From david at gibson.dropbear.id.au Mon Aug 1 15:48:10 2005 From: david at gibson.dropbear.id.au (David Gibson) Date: Mon, 1 Aug 2005 15:48:10 +1000 Subject: [PATCH 0/8] Assorted cleanups to head.S Message-ID: <20050801054810.GA10853@localhost.localdomain> Hi Paul, Please forward upstream, if acceptable. This stack of 8 patches makes a number of cleanups to head.S, in the process removing several pages from the kernel runtime image, and a couple more from the vmlinux. [PATCH 1/8] Remove NACA fixed address constraint [PATCH 2/8] Move iSeries and common vectors into unused space in head.S [PATCH 3/8] Change address of ppc64 initial segment table [PATCH 4/8] Remove general use functions from head.S [PATCH 5/8] Fix apparent code overlap in ppc64 head.S [PATCH 6/8] Remove unneeded #defines in head.S [PATCH 7/8] Tweak comments in ppc64 head.S [PATCH 8/8] Move variables in ppc64 head.S from .data to .bss -- David Gibson | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/people/dgibson From david at gibson.dropbear.id.au Mon Aug 1 15:53:51 2005 From: david at gibson.dropbear.id.au (David Gibson) Date: Mon, 1 Aug 2005 15:53:51 +1000 (EST) Subject: [PATCH 1/8] Remove NACA fixed address constraint In-Reply-To: <20050801054810.GA10853@localhost.localdomain> Message-ID: <20050801055351.E164D67E06@ozlabs.org> Comments in head.S suggest that the iSeries naca has a fixed address, because tools expect to find it there. The only tool which appears to access the naca is addRamDisk, but both the in-kernel version and the version used in RHEL and SuSE in fact locate the NACA the same way as the hypervisor does, by following the pointer in the hvReleaseData structure. Since the requirement for a fixed address seems to be obsolete, this patch removes the naca from head.S and replaces it with a normal C initializer. For good measure, it removes an old version of addRamDisk.c which was sitting, unused, in the ppc32 tree. Signed-off-by: David Gibson arch/ppc/boot/utils/addRamDisk.c | 203 --------------------------------------- arch/ppc64/kernel/LparData.c | 11 ++ arch/ppc64/kernel/head.S | 17 --- include/asm-ppc64/naca.h | 7 - 4 files changed, 12 insertions(+), 226 deletions(-) Index: working-2.6/arch/ppc/boot/utils/addRamDisk.c =================================================================== --- working-2.6.orig/arch/ppc/boot/utils/addRamDisk.c 2005-05-24 14:12:22.000000000 +1000 +++ /dev/null 1970-01-01 00:00:00.000000000 +0000 @@ -1,203 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -#define ElfHeaderSize (64 * 1024) -#define ElfPages (ElfHeaderSize / 4096) -#define KERNELBASE (0xc0000000) - -void get4k(FILE *file, char *buf ) -{ - unsigned j; - unsigned num = fread(buf, 1, 4096, file); - for ( j=num; j<4096; ++j ) - buf[j] = 0; -} - -void put4k(FILE *file, char *buf ) -{ - fwrite(buf, 1, 4096, file); -} - -void death(const char *msg, FILE *fdesc, const char *fname) -{ - printf(msg); - fclose(fdesc); - unlink(fname); - exit(1); -} - -int main(int argc, char **argv) -{ - char inbuf[4096]; - FILE *ramDisk = NULL; - FILE *inputVmlinux = NULL; - FILE *outputVmlinux = NULL; - unsigned i = 0; - u_int32_t ramFileLen = 0; - u_int32_t ramLen = 0; - u_int32_t roundR = 0; - u_int32_t kernelLen = 0; - u_int32_t actualKernelLen = 0; - u_int32_t round = 0; - u_int32_t roundedKernelLen = 0; - u_int32_t ramStartOffs = 0; - u_int32_t ramPages = 0; - u_int32_t roundedKernelPages = 0; - u_int32_t hvReleaseData = 0; - u_int32_t eyeCatcher = 0xc8a5d9c4; - u_int32_t naca = 0; - u_int32_t xRamDisk = 0; - u_int32_t xRamDiskSize = 0; - if ( argc < 2 ) { - printf("Name of RAM disk file missing.\n"); - exit(1); - } - - if ( argc < 3 ) { - printf("Name of vmlinux file missing.\n"); - exit(1); - } - - if ( argc < 4 ) { - printf("Name of vmlinux output file missing.\n"); - exit(1); - } - - ramDisk = fopen(argv[1], "r"); - if ( ! ramDisk ) { - printf("RAM disk file \"%s\" failed to open.\n", argv[1]); - exit(1); - } - inputVmlinux = fopen(argv[2], "r"); - if ( ! inputVmlinux ) { - printf("vmlinux file \"%s\" failed to open.\n", argv[2]); - exit(1); - } - outputVmlinux = fopen(argv[3], "w+"); - if ( ! outputVmlinux ) { - printf("output vmlinux file \"%s\" failed to open.\n", argv[3]); - exit(1); - } - fseek(ramDisk, 0, SEEK_END); - ramFileLen = ftell(ramDisk); - fseek(ramDisk, 0, SEEK_SET); - printf("%s file size = %d\n", argv[1], ramFileLen); - - ramLen = ramFileLen; - - roundR = 4096 - (ramLen % 4096); - if ( roundR ) { - printf("Rounding RAM disk file up to a multiple of 4096, adding %d\n", roundR); - ramLen += roundR; - } - - printf("Rounded RAM disk size is %d\n", ramLen); - fseek(inputVmlinux, 0, SEEK_END); - kernelLen = ftell(inputVmlinux); - fseek(inputVmlinux, 0, SEEK_SET); - printf("kernel file size = %d\n", kernelLen); - if ( kernelLen == 0 ) { - printf("You must have a linux kernel specified as argv[2]\n"); - exit(1); - } - - actualKernelLen = kernelLen - ElfHeaderSize; - - printf("actual kernel length (minus ELF header) = %d\n", actualKernelLen); - - round = actualKernelLen % 4096; - roundedKernelLen = actualKernelLen; - if ( round ) - roundedKernelLen += (4096 - round); - - printf("actual kernel length rounded up to a 4k multiple = %d\n", roundedKernelLen); - - ramStartOffs = roundedKernelLen; - ramPages = ramLen / 4096; - - printf("RAM disk pages to copy = %d\n", ramPages); - - // Copy 64K ELF header - for (i=0; i<(ElfPages); ++i) { - get4k( inputVmlinux, inbuf ); - put4k( outputVmlinux, inbuf ); - } - - roundedKernelPages = roundedKernelLen / 4096; - - fseek(inputVmlinux, ElfHeaderSize, SEEK_SET); - - for ( i=0; i #include #include -#include #include #include #include @@ -510,24 +509,10 @@ mfspr r12,SPRG2 EXCEPTION_PROLOG_PSERIES(PACA_EXSLB, .do_stab_bolted) - - /* Space for the naca. Architected to be located at real address - * NACA_PHYS_ADDR. Various tools rely on this location being fixed. - * The first dword of the naca is required by iSeries LPAR to - * point to itVpdAreas. On pSeries native, this value is not used. - */ - . = NACA_PHYS_ADDR - .globl __end_interrupts -__end_interrupts: -#ifdef CONFIG_PPC_ISERIES - .globl naca -naca: - .llong itVpdAreas - .llong 0 /* xRamDisk */ - .llong 0 /* xRamDiskSize */ . = 0x6100 +#ifdef CONFIG_PPC_ISERIES /*** ISeries-LPAR interrupt handlers ***/ STD_EXCEPTION_ISERIES(0x200, machine_check, PACA_EXMC) arch/ppc/boot/utils/addRamDisk.c | 203 --------------------------------------- arch/ppc64/kernel/LparData.c | 11 ++ arch/ppc64/kernel/head.S | 17 --- include/asm-ppc64/naca.h | 7 - 4 files changed, 12 insertions(+), 226 deletions(-) Index: working-2.6/include/asm-ppc64/naca.h =================================================================== --- working-2.6.orig/include/asm-ppc64/naca.h 2005-05-24 14:12:25.000000000 +1000 +++ working-2.6/include/asm-ppc64/naca.h 2005-08-01 11:26:38.000000000 +1000 @@ -12,8 +12,6 @@ #include -#ifndef __ASSEMBLY__ - struct naca_struct { /* Kernel only data - undefined for user space */ void *xItVpdAreas; /* VPD Data 0x00 */ @@ -23,9 +21,4 @@ extern struct naca_struct naca; -#endif /* __ASSEMBLY__ */ - -#define NACA_PAGE 0x4 -#define NACA_PHYS_ADDR (NACA_PAGE< Message-ID: <20050801055351.23C3967E1A@ozlabs.org> In the ppc64 kernel head.S there is currently quite a lot of unused space between the naca (at fixed address 0x4000) and the fwnmi data area (at fixed address 0x7000). This patch moves various exception vectors and support code into this region to use the wasted space. The functions load_up_fpu and load_up_altivec are moved down as well, since they are essentially continuations of the fp_unavailable_common and altivec_unavailable_common vectors, respectively. Likewise, the fwnmi vectors themselves are moved down into this area, because while the location of the fwnmi data area is fixed by the RPA, the vectors themselves can be anywhere sufficiently low. Signed-off-by: David Gibson arch/ppc64/kernel/head.S | 350 +++++++++++++++++++++++------------------------ 1 files changed, 175 insertions(+), 175 deletions(-) Index: working-2.6/arch/ppc64/kernel/head.S =================================================================== --- working-2.6.orig/arch/ppc64/kernel/head.S 2005-08-01 15:19:04.000000000 +1000 +++ working-2.6/arch/ppc64/kernel/head.S 2005-08-01 15:20:17.000000000 +1000 @@ -51,9 +51,8 @@ * We layout physical memory as follows: * 0x0000 - 0x00ff : Secondary processor spin code * 0x0100 - 0x2fff : pSeries Interrupt prologs - * 0x3000 - 0x3fff : Interrupt support - * 0x4000 - 0x4fff : NACA - * 0x6000 : iSeries and common interrupt prologs + * 0x3000 - 0x6fff : interrupt support, iSeries and common interrupt prologs + * 0x7000 - 0x7fff : FWNMI data area * 0x9000 - 0x9fff : Initial segment table */ @@ -500,17 +499,35 @@ STD_EXCEPTION_PSERIES(0x1300, instruction_breakpoint) STD_EXCEPTION_PSERIES(0x1700, altivec_assist) + . = 0x3000 + +/*** pSeries interrupt support ***/ + /* moved from 0xf00 */ - STD_EXCEPTION_PSERIES(0x3000, performance_monitor) + STD_EXCEPTION_PSERIES(., performance_monitor) - . = 0x3100 + .align 7 _GLOBAL(do_stab_bolted_pSeries) mtcrf 0x80,r12 mfspr r12,SPRG2 EXCEPTION_PROLOG_PSERIES(PACA_EXSLB, .do_stab_bolted) +/* + * Vectors for the FWNMI option. Share common code. + */ + .globl system_reset_fwnmi +system_reset_fwnmi: + HMT_MEDIUM + mtspr SPRG1,r13 /* save r13 */ + RUNLATCH_ON(r13) + EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common) - . = 0x6100 + .globl machine_check_fwnmi +machine_check_fwnmi: + HMT_MEDIUM + mtspr SPRG1,r13 /* save r13 */ + RUNLATCH_ON(r13) + EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common) #ifdef CONFIG_PPC_ISERIES /*** ISeries-LPAR interrupt handlers ***/ @@ -655,45 +672,7 @@ ld r13,PACA_EXGEN+EX_R13(r13) rfid b . /* prevent speculative execution */ -#endif - -/* - * Data area reserved for FWNMI option. - */ - .= 0x7000 - .globl fwnmi_data_area -fwnmi_data_area: - -/* - * Vectors for the FWNMI option. Share common code. - */ - . = 0x8000 - .globl system_reset_fwnmi -system_reset_fwnmi: - HMT_MEDIUM - mtspr SPRG1,r13 /* save r13 */ - RUNLATCH_ON(r13) - EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common) - .globl machine_check_fwnmi -machine_check_fwnmi: - HMT_MEDIUM - mtspr SPRG1,r13 /* save r13 */ - RUNLATCH_ON(r13) - EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common) - - /* - * Space for the initial segment table - * For LPAR, the hypervisor must fill in at least one entry - * before we get control (with relocate on) - */ - . = STAB0_PHYS_ADDR - .globl __start_stab -__start_stab: - - . = (STAB0_PHYS_ADDR + PAGE_SIZE) - .globl __end_stab -__end_stab: - +#endif /* CONFIG_PPC_ISERIES */ /*** Common interrupt handlers ***/ @@ -885,6 +864,62 @@ bl .kernel_fp_unavailable_exception BUG_OPCODE +/* + * load_up_fpu(unused, unused, tsk) + * Disable FP for the task which had the FPU previously, + * and save its floating-point registers in its thread_struct. + * Enables the FPU for use in the kernel on return. + * On SMP we know the fpu is free, since we give it up every + * switch (ie, no lazy save of the FP registers). + * On entry: r13 == 'current' && last_task_used_math != 'current' + */ +_STATIC(load_up_fpu) + mfmsr r5 /* grab the current MSR */ + ori r5,r5,MSR_FP + mtmsrd r5 /* enable use of fpu now */ + isync +/* + * For SMP, we don't do lazy FPU switching because it just gets too + * horrendously complex, especially when a task switches from one CPU + * to another. Instead we call giveup_fpu in switch_to. + * + */ +#ifndef CONFIG_SMP + ld r3,last_task_used_math at got(r2) + ld r4,0(r3) + cmpdi 0,r4,0 + beq 1f + /* Save FP state to last_task_used_math's THREAD struct */ + addi r4,r4,THREAD + SAVE_32FPRS(0, r4) + mffs fr0 + stfd fr0,THREAD_FPSCR(r4) + /* Disable FP for last_task_used_math */ + ld r5,PT_REGS(r4) + ld r4,_MSR-STACK_FRAME_OVERHEAD(r5) + li r6,MSR_FP|MSR_FE0|MSR_FE1 + andc r4,r4,r6 + std r4,_MSR-STACK_FRAME_OVERHEAD(r5) +1: +#endif /* CONFIG_SMP */ + /* enable use of FP after return */ + ld r4,PACACURRENT(r13) + addi r5,r4,THREAD /* Get THREAD */ + ld r4,THREAD_FPEXC_MODE(r5) + ori r12,r12,MSR_FP + or r12,r12,r4 + std r12,_MSR(r1) + lfd fr0,THREAD_FPSCR(r5) + mtfsf 0xff,fr0 + REST_32FPRS(0, r5) +#ifndef CONFIG_SMP + /* Update last_task_used_math to 'current' */ + subi r4,r5,THREAD /* Back to 'current' */ + std r4,0(r3) +#endif /* CONFIG_SMP */ + /* restore registers and return */ + b fast_exception_return + .align 7 .globl altivec_unavailable_common altivec_unavailable_common: @@ -900,6 +935,80 @@ bl .altivec_unavailable_exception b .ret_from_except +#ifdef CONFIG_ALTIVEC +/* + * load_up_altivec(unused, unused, tsk) + * Disable VMX for the task which had it previously, + * and save its vector registers in its thread_struct. + * Enables the VMX for use in the kernel on return. + * On SMP we know the VMX is free, since we give it up every + * switch (ie, no lazy save of the vector registers). + * On entry: r13 == 'current' && last_task_used_altivec != 'current' + */ +_STATIC(load_up_altivec) + mfmsr r5 /* grab the current MSR */ + oris r5,r5,MSR_VEC at h + mtmsrd r5 /* enable use of VMX now */ + isync + +/* + * For SMP, we don't do lazy VMX switching because it just gets too + * horrendously complex, especially when a task switches from one CPU + * to another. Instead we call giveup_altvec in switch_to. + * VRSAVE isn't dealt with here, that is done in the normal context + * switch code. Note that we could rely on vrsave value to eventually + * avoid saving all of the VREGs here... + */ +#ifndef CONFIG_SMP + ld r3,last_task_used_altivec at got(r2) + ld r4,0(r3) + cmpdi 0,r4,0 + beq 1f + /* Save VMX state to last_task_used_altivec's THREAD struct */ + addi r4,r4,THREAD + SAVE_32VRS(0,r5,r4) + mfvscr vr0 + li r10,THREAD_VSCR + stvx vr0,r10,r4 + /* Disable VMX for last_task_used_altivec */ + ld r5,PT_REGS(r4) + ld r4,_MSR-STACK_FRAME_OVERHEAD(r5) + lis r6,MSR_VEC at h + andc r4,r4,r6 + std r4,_MSR-STACK_FRAME_OVERHEAD(r5) +1: +#endif /* CONFIG_SMP */ + /* Hack: if we get an altivec unavailable trap with VRSAVE + * set to all zeros, we assume this is a broken application + * that fails to set it properly, and thus we switch it to + * all 1's + */ + mfspr r4,SPRN_VRSAVE + cmpdi 0,r4,0 + bne+ 1f + li r4,-1 + mtspr SPRN_VRSAVE,r4 +1: + /* enable use of VMX after return */ + ld r4,PACACURRENT(r13) + addi r5,r4,THREAD /* Get THREAD */ + oris r12,r12,MSR_VEC at h + std r12,_MSR(r1) + li r4,1 + li r10,THREAD_VSCR + stw r4,THREAD_USED_VR(r5) + lvx vr0,r10,r5 + mtvscr vr0 + REST_32VRS(0,r4,r5) +#ifndef CONFIG_SMP + /* Update last_task_used_math to 'current' */ + subi r4,r5,THREAD /* Back to 'current' */ + std r4,0(r3) +#endif /* CONFIG_SMP */ + /* restore registers and return */ + b fast_exception_return +#endif /* CONFIG_ALTIVEC */ + /* * Hash table stuff */ @@ -1146,6 +1255,27 @@ bl .unrecoverable_exception b 1b +/* + * Data area reserved for FWNMI option. + * This address (0x7000) is fixed by the RPA. + */ + .= 0x7000 + .globl fwnmi_data_area +fwnmi_data_area: + .space PAGE_SIZE + + /* + * Space for the initial segment table + * For LPAR, the hypervisor must fill in at least one entry + * before we get control (with relocate on) + */ + . = STAB0_PHYS_ADDR + .globl __start_stab +__start_stab: + + . = (STAB0_PHYS_ADDR + PAGE_SIZE) + .globl __end_stab +__end_stab: /* * On pSeries, secondary processors spin in the following code. @@ -1410,62 +1540,6 @@ copy_to_here: /* - * load_up_fpu(unused, unused, tsk) - * Disable FP for the task which had the FPU previously, - * and save its floating-point registers in its thread_struct. - * Enables the FPU for use in the kernel on return. - * On SMP we know the fpu is free, since we give it up every - * switch (ie, no lazy save of the FP registers). - * On entry: r13 == 'current' && last_task_used_math != 'current' - */ -_STATIC(load_up_fpu) - mfmsr r5 /* grab the current MSR */ - ori r5,r5,MSR_FP - mtmsrd r5 /* enable use of fpu now */ - isync -/* - * For SMP, we don't do lazy FPU switching because it just gets too - * horrendously complex, especially when a task switches from one CPU - * to another. Instead we call giveup_fpu in switch_to. - * - */ -#ifndef CONFIG_SMP - ld r3,last_task_used_math at got(r2) - ld r4,0(r3) - cmpdi 0,r4,0 - beq 1f - /* Save FP state to last_task_used_math's THREAD struct */ - addi r4,r4,THREAD - SAVE_32FPRS(0, r4) - mffs fr0 - stfd fr0,THREAD_FPSCR(r4) - /* Disable FP for last_task_used_math */ - ld r5,PT_REGS(r4) - ld r4,_MSR-STACK_FRAME_OVERHEAD(r5) - li r6,MSR_FP|MSR_FE0|MSR_FE1 - andc r4,r4,r6 - std r4,_MSR-STACK_FRAME_OVERHEAD(r5) -1: -#endif /* CONFIG_SMP */ - /* enable use of FP after return */ - ld r4,PACACURRENT(r13) - addi r5,r4,THREAD /* Get THREAD */ - ld r4,THREAD_FPEXC_MODE(r5) - ori r12,r12,MSR_FP - or r12,r12,r4 - std r12,_MSR(r1) - lfd fr0,THREAD_FPSCR(r5) - mtfsf 0xff,fr0 - REST_32FPRS(0, r5) -#ifndef CONFIG_SMP - /* Update last_task_used_math to 'current' */ - subi r4,r5,THREAD /* Back to 'current' */ - std r4,0(r3) -#endif /* CONFIG_SMP */ - /* restore registers and return */ - b fast_exception_return - -/* * disable_kernel_fp() * Disable the FPU. */ @@ -1509,81 +1583,7 @@ #endif /* CONFIG_SMP */ blr - #ifdef CONFIG_ALTIVEC - -/* - * load_up_altivec(unused, unused, tsk) - * Disable VMX for the task which had it previously, - * and save its vector registers in its thread_struct. - * Enables the VMX for use in the kernel on return. - * On SMP we know the VMX is free, since we give it up every - * switch (ie, no lazy save of the vector registers). - * On entry: r13 == 'current' && last_task_used_altivec != 'current' - */ -_STATIC(load_up_altivec) - mfmsr r5 /* grab the current MSR */ - oris r5,r5,MSR_VEC at h - mtmsrd r5 /* enable use of VMX now */ - isync - -/* - * For SMP, we don't do lazy VMX switching because it just gets too - * horrendously complex, especially when a task switches from one CPU - * to another. Instead we call giveup_altvec in switch_to. - * VRSAVE isn't dealt with here, that is done in the normal context - * switch code. Note that we could rely on vrsave value to eventually - * avoid saving all of the VREGs here... - */ -#ifndef CONFIG_SMP - ld r3,last_task_used_altivec at got(r2) - ld r4,0(r3) - cmpdi 0,r4,0 - beq 1f - /* Save VMX state to last_task_used_altivec's THREAD struct */ - addi r4,r4,THREAD - SAVE_32VRS(0,r5,r4) - mfvscr vr0 - li r10,THREAD_VSCR - stvx vr0,r10,r4 - /* Disable VMX for last_task_used_altivec */ - ld r5,PT_REGS(r4) - ld r4,_MSR-STACK_FRAME_OVERHEAD(r5) - lis r6,MSR_VEC at h - andc r4,r4,r6 - std r4,_MSR-STACK_FRAME_OVERHEAD(r5) -1: -#endif /* CONFIG_SMP */ - /* Hack: if we get an altivec unavailable trap with VRSAVE - * set to all zeros, we assume this is a broken application - * that fails to set it properly, and thus we switch it to - * all 1's - */ - mfspr r4,SPRN_VRSAVE - cmpdi 0,r4,0 - bne+ 1f - li r4,-1 - mtspr SPRN_VRSAVE,r4 -1: - /* enable use of VMX after return */ - ld r4,PACACURRENT(r13) - addi r5,r4,THREAD /* Get THREAD */ - oris r12,r12,MSR_VEC at h - std r12,_MSR(r1) - li r4,1 - li r10,THREAD_VSCR - stw r4,THREAD_USED_VR(r5) - lvx vr0,r10,r5 - mtvscr vr0 - REST_32VRS(0,r4,r5) -#ifndef CONFIG_SMP - /* Update last_task_used_math to 'current' */ - subi r4,r5,THREAD /* Back to 'current' */ - std r4,0(r3) -#endif /* CONFIG_SMP */ - /* restore registers and return */ - b fast_exception_return - /* * disable_kernel_altivec() * Disable the VMX. From david at gibson.dropbear.id.au Mon Aug 1 15:53:52 2005 From: david at gibson.dropbear.id.au (David Gibson) Date: Mon, 1 Aug 2005 15:53:52 +1000 (EST) Subject: [PATCH 3/8] Change address of ppc64 initial segment table In-Reply-To: <20050801054810.GA10853@localhost.localdomain> Message-ID: <20050801055352.460EA67E22@ozlabs.org> On ppc64 machines with segment tables, CPU0's segment table is at a fixed address, currently 0x9000. This patch moves it to the free space at 0x6000, just below the fwnmi data area. This saves 8k of space in vmlinux and the runtime kernel image. Signed-off-by: David Gibson arch/ppc64/kernel/head.S | 32 +++++++++++++++++--------------- arch/ppc64/kernel/pacaData.c | 4 ++-- include/asm-ppc64/mmu.h | 7 +++++-- 3 files changed, 24 insertions(+), 19 deletions(-) Index: working-2.6/arch/ppc64/kernel/head.S =================================================================== --- working-2.6.orig/arch/ppc64/kernel/head.S 2005-07-28 14:23:09.000000000 +1000 +++ working-2.6/arch/ppc64/kernel/head.S 2005-07-28 14:23:15.000000000 +1000 @@ -51,9 +51,10 @@ * We layout physical memory as follows: * 0x0000 - 0x00ff : Secondary processor spin code * 0x0100 - 0x2fff : pSeries Interrupt prologs - * 0x3000 - 0x6fff : interrupt support, iSeries and common interrupt prologs + * 0x3000 - 0x5fff : interrupt support, iSeries and common interrupt prologs + * 0x6000 - 0x6fff : Initial (CPU0) segment table * 0x7000 - 0x7fff : FWNMI data area - * 0x9000 - 0x9fff : Initial segment table + * 0x8000 - : Early init and support code */ /* @@ -1256,6 +1257,20 @@ b 1b /* + * Space for CPU0's segment table. + * + * On iSeries, the hypervisor must fill in at least one entry before + * we get control (with relocate on). The address is give to the hv + * as a page number (see xLparMap in LparData.c), so this must be at a + * fixed address (the linker can't compute (u64)&initial_stab >> + * PAGE_SHIFT). + */ + . = STAB0_PHYS_ADDR /* 0x6000 */ + .globl initial_stab +initial_stab: + .space 4096 + +/* * Data area reserved for FWNMI option. * This address (0x7000) is fixed by the RPA. */ @@ -1264,19 +1279,6 @@ fwnmi_data_area: .space PAGE_SIZE - /* - * Space for the initial segment table - * For LPAR, the hypervisor must fill in at least one entry - * before we get control (with relocate on) - */ - . = STAB0_PHYS_ADDR - .globl __start_stab -__start_stab: - - . = (STAB0_PHYS_ADDR + PAGE_SIZE) - .globl __end_stab -__end_stab: - /* * On pSeries, secondary processors spin in the following code. * At entry, r3 = this processor's number (physical cpu id) arch/ppc64/kernel/head.S | 32 +++++++++++++++++--------------- arch/ppc64/kernel/pacaData.c | 4 ++-- include/asm-ppc64/mmu.h | 7 +++++-- 3 files changed, 24 insertions(+), 19 deletions(-) Index: working-2.6/arch/ppc64/kernel/pacaData.c =================================================================== --- working-2.6.orig/arch/ppc64/kernel/pacaData.c 2005-07-28 14:23:03.000000000 +1000 +++ working-2.6/arch/ppc64/kernel/pacaData.c 2005-07-28 14:23:15.000000000 +1000 @@ -78,7 +78,7 @@ #define BOOTCPU_PACA_INIT(number) \ { \ - PACA_INIT_COMMON(number, 1, 0, STAB0_VIRT_ADDR) \ + PACA_INIT_COMMON(number, 1, 0, (u64)&initial_stab) \ PACA_INIT_ISERIES(number) \ } @@ -90,7 +90,7 @@ #define BOOTCPU_PACA_INIT(number) \ { \ - PACA_INIT_COMMON(number, 1, STAB0_PHYS_ADDR, STAB0_VIRT_ADDR) \ + PACA_INIT_COMMON(number, 1, STAB0_PHYS_ADDR, (u64)&initial_stab) \ } #endif arch/ppc64/kernel/head.S | 32 +++++++++++++++++--------------- arch/ppc64/kernel/pacaData.c | 4 ++-- include/asm-ppc64/mmu.h | 7 +++++-- 3 files changed, 24 insertions(+), 19 deletions(-) Index: working-2.6/include/asm-ppc64/mmu.h =================================================================== --- working-2.6.orig/include/asm-ppc64/mmu.h 2005-07-28 14:23:03.000000000 +1000 +++ working-2.6/include/asm-ppc64/mmu.h 2005-07-28 14:23:15.000000000 +1000 @@ -28,9 +28,12 @@ #define STE_VSID_SHIFT 12 /* Location of cpu0's segment table */ -#define STAB0_PAGE 0x9 +#define STAB0_PAGE 0x6 #define STAB0_PHYS_ADDR (STAB0_PAGE< Message-ID: <20050801055352.7D2A367E23@ozlabs.org> As well as the interrupt vectors and initialization code, head.S contains several asm functions which are used during runtime. This patch moves these to misc.S, a more sensible location for random asm support code. A couple The functions moved are: disable_kernel_fp giveup_fpu disable_kernel_altivec giveup_altivec __setup_cpu_power3 (empty function) Signed-off-by: David Gibson arch/ppc64/kernel/head.S | 95 --------------------------------------------- arch/ppc64/kernel/misc.S | 98 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 98 insertions(+), 95 deletions(-) Index: working-2.6/arch/ppc64/kernel/head.S =================================================================== --- working-2.6.orig/arch/ppc64/kernel/head.S 2005-07-28 14:23:16.000000000 +1000 +++ working-2.6/arch/ppc64/kernel/head.S 2005-07-28 14:23:18.000000000 +1000 @@ -1541,98 +1541,6 @@ .align 8 copy_to_here: -/* - * disable_kernel_fp() - * Disable the FPU. - */ -_GLOBAL(disable_kernel_fp) - mfmsr r3 - rldicl r0,r3,(63-MSR_FP_LG),1 - rldicl r3,r0,(MSR_FP_LG+1),0 - mtmsrd r3 /* disable use of fpu now */ - isync - blr - -/* - * giveup_fpu(tsk) - * Disable FP for the task given as the argument, - * and save the floating-point registers in its thread_struct. - * Enables the FPU for use in the kernel on return. - */ -_GLOBAL(giveup_fpu) - mfmsr r5 - ori r5,r5,MSR_FP - mtmsrd r5 /* enable use of fpu now */ - isync - cmpdi 0,r3,0 - beqlr- /* if no previous owner, done */ - addi r3,r3,THREAD /* want THREAD of task */ - ld r5,PT_REGS(r3) - cmpdi 0,r5,0 - SAVE_32FPRS(0, r3) - mffs fr0 - stfd fr0,THREAD_FPSCR(r3) - beq 1f - ld r4,_MSR-STACK_FRAME_OVERHEAD(r5) - li r3,MSR_FP|MSR_FE0|MSR_FE1 - andc r4,r4,r3 /* disable FP for previous task */ - std r4,_MSR-STACK_FRAME_OVERHEAD(r5) -1: -#ifndef CONFIG_SMP - li r5,0 - ld r4,last_task_used_math at got(r2) - std r5,0(r4) -#endif /* CONFIG_SMP */ - blr - -#ifdef CONFIG_ALTIVEC -/* - * disable_kernel_altivec() - * Disable the VMX. - */ -_GLOBAL(disable_kernel_altivec) - mfmsr r3 - rldicl r0,r3,(63-MSR_VEC_LG),1 - rldicl r3,r0,(MSR_VEC_LG+1),0 - mtmsrd r3 /* disable use of VMX now */ - isync - blr - -/* - * giveup_altivec(tsk) - * Disable VMX for the task given as the argument, - * and save the vector registers in its thread_struct. - * Enables the VMX for use in the kernel on return. - */ -_GLOBAL(giveup_altivec) - mfmsr r5 - oris r5,r5,MSR_VEC at h - mtmsrd r5 /* enable use of VMX now */ - isync - cmpdi 0,r3,0 - beqlr- /* if no previous owner, done */ - addi r3,r3,THREAD /* want THREAD of task */ - ld r5,PT_REGS(r3) - cmpdi 0,r5,0 - SAVE_32VRS(0,r4,r3) - mfvscr vr0 - li r4,THREAD_VSCR - stvx vr0,r4,r3 - beq 1f - ld r4,_MSR-STACK_FRAME_OVERHEAD(r5) - lis r3,MSR_VEC at h - andc r4,r4,r3 /* disable FP for previous task */ - std r4,_MSR-STACK_FRAME_OVERHEAD(r5) -1: -#ifndef CONFIG_SMP - li r5,0 - ld r4,last_task_used_altivec at got(r2) - std r5,0(r4) -#endif /* CONFIG_SMP */ - blr - -#endif /* CONFIG_ALTIVEC */ - #ifdef CONFIG_SMP #ifdef CONFIG_PPC_PMAC /* @@ -1983,9 +1891,6 @@ bl .start_kernel -_GLOBAL(__setup_cpu_power3) - blr - _GLOBAL(hmt_init) #ifdef CONFIG_HMT LOADADDR(r5, hmt_thread_data) arch/ppc64/kernel/head.S | 95 --------------------------------------------- arch/ppc64/kernel/misc.S | 98 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 98 insertions(+), 95 deletions(-) Index: working-2.6/arch/ppc64/kernel/misc.S =================================================================== --- working-2.6.orig/arch/ppc64/kernel/misc.S 2005-07-28 14:23:03.000000000 +1000 +++ working-2.6/arch/ppc64/kernel/misc.S 2005-07-28 14:23:18.000000000 +1000 @@ -680,6 +680,104 @@ ld r30,-16(r1) blr +/* + * disable_kernel_fp() + * Disable the FPU. + */ +_GLOBAL(disable_kernel_fp) + mfmsr r3 + rldicl r0,r3,(63-MSR_FP_LG),1 + rldicl r3,r0,(MSR_FP_LG+1),0 + mtmsrd r3 /* disable use of fpu now */ + isync + blr + +/* + * giveup_fpu(tsk) + * Disable FP for the task given as the argument, + * and save the floating-point registers in its thread_struct. + * Enables the FPU for use in the kernel on return. + */ +_GLOBAL(giveup_fpu) + mfmsr r5 + ori r5,r5,MSR_FP + mtmsrd r5 /* enable use of fpu now */ + isync + cmpdi 0,r3,0 + beqlr- /* if no previous owner, done */ + addi r3,r3,THREAD /* want THREAD of task */ + ld r5,PT_REGS(r3) + cmpdi 0,r5,0 + SAVE_32FPRS(0, r3) + mffs fr0 + stfd fr0,THREAD_FPSCR(r3) + beq 1f + ld r4,_MSR-STACK_FRAME_OVERHEAD(r5) + li r3,MSR_FP|MSR_FE0|MSR_FE1 + andc r4,r4,r3 /* disable FP for previous task */ + std r4,_MSR-STACK_FRAME_OVERHEAD(r5) +1: +#ifndef CONFIG_SMP + li r5,0 + ld r4,last_task_used_math at got(r2) + std r5,0(r4) +#endif /* CONFIG_SMP */ + blr + +#ifdef CONFIG_ALTIVEC + +#if 0 /* this has no callers for now */ +/* + * disable_kernel_altivec() + * Disable the VMX. + */ +_GLOBAL(disable_kernel_altivec) + mfmsr r3 + rldicl r0,r3,(63-MSR_VEC_LG),1 + rldicl r3,r0,(MSR_VEC_LG+1),0 + mtmsrd r3 /* disable use of VMX now */ + isync + blr +#endif /* 0 */ + +/* + * giveup_altivec(tsk) + * Disable VMX for the task given as the argument, + * and save the vector registers in its thread_struct. + * Enables the VMX for use in the kernel on return. + */ +_GLOBAL(giveup_altivec) + mfmsr r5 + oris r5,r5,MSR_VEC at h + mtmsrd r5 /* enable use of VMX now */ + isync + cmpdi 0,r3,0 + beqlr- /* if no previous owner, done */ + addi r3,r3,THREAD /* want THREAD of task */ + ld r5,PT_REGS(r3) + cmpdi 0,r5,0 + SAVE_32VRS(0,r4,r3) + mfvscr vr0 + li r4,THREAD_VSCR + stvx vr0,r4,r3 + beq 1f + ld r4,_MSR-STACK_FRAME_OVERHEAD(r5) + lis r3,MSR_VEC at h + andc r4,r4,r3 /* disable FP for previous task */ + std r4,_MSR-STACK_FRAME_OVERHEAD(r5) +1: +#ifndef CONFIG_SMP + li r5,0 + ld r4,last_task_used_altivec at got(r2) + std r5,0(r4) +#endif /* CONFIG_SMP */ + blr + +#endif /* CONFIG_ALTIVEC */ + +_GLOBAL(__setup_cpu_power3) + blr + /* kexec_wait(phys_cpu) * * wait for the flag to change, indicating this kernel is going away but From david at gibson.dropbear.id.au Mon Aug 1 15:53:52 2005 From: david at gibson.dropbear.id.au (David Gibson) Date: Mon, 1 Aug 2005 15:53:52 +1000 (EST) Subject: [PATCH 5/8] Fix apparent code overlap in ppc64 head.S In-Reply-To: <20050801054810.GA10853@localhost.localdomain> Message-ID: <20050801055352.B0DD267E24@ozlabs.org> An #if/#else construct near the top of ppc64's head.S appears to create overlapping sections of code for iSeries and pSeries (i.e. one thing on iSeries and something different in the same place on pSeries). In fact, checking the various absolute offsets, it doesn't. This patch unravels the #ifdefs to make it more obvious what's going on. This accomplishes another microstep towards a single kernel image which can boot both iSeries and pSeries. Signed-off-by: David Gibson arch/ppc64/kernel/head.S | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: working-2.6/arch/ppc64/kernel/head.S =================================================================== --- working-2.6.orig/arch/ppc64/kernel/head.S 2005-07-28 14:23:18.000000000 +1000 +++ working-2.6/arch/ppc64/kernel/head.S 2005-07-28 14:23:20.000000000 +1000 @@ -92,6 +92,7 @@ /* Catch branch to 0 in real mode */ trap + #ifdef CONFIG_PPC_ISERIES /* * At offset 0x20, there is a pointer to iSeries LPAR data. @@ -118,7 +119,7 @@ embedded_sysmap_end: .llong 0 -#else /* CONFIG_PPC_ISERIES */ +#endif /* CONFIG_PPC_ISERIES */ /* Secondary processors spin on this value until it goes to 1. */ .globl __secondary_hold_spinloop @@ -168,7 +169,6 @@ BUG_OPCODE #endif #endif -#endif /* This value is used to mark exception frames on the stack. */ .section ".toc","aw" From david at gibson.dropbear.id.au Mon Aug 1 15:53:57 2005 From: david at gibson.dropbear.id.au (David Gibson) Date: Mon, 1 Aug 2005 15:53:57 +1000 (EST) Subject: [PATCH 6/8] Remove unneeded #defines in head.S In-Reply-To: <20050801054810.GA10853@localhost.localdomain> Message-ID: <20050801055357.94EE367E39@ozlabs.org> arch/ppc64/kernel/head.S #defines SECONDARY_PROCESSORS then has some #ifdefs based on it. Whatever purpose this had is long lost, this patch removes it. Likewise, head.S defines H_SET_ASR, which is now defined, along with other hypervisor call numbers in hvcall.h. This patch deletes it, as well, from head.S. Signed-off-by: David Gibson arch/ppc64/kernel/head.S | 11 ----------- 1 files changed, 11 deletions(-) Index: working-2.6/arch/ppc64/kernel/head.S =================================================================== --- working-2.6.orig/arch/ppc64/kernel/head.S 2005-07-28 14:23:20.000000000 +1000 +++ working-2.6/arch/ppc64/kernel/head.S 2005-07-28 14:23:22.000000000 +1000 @@ -23,8 +23,6 @@ * 2 of the License, or (at your option) any later version. */ -#define SECONDARY_PROCESSORS - #include #include #include @@ -43,11 +41,6 @@ #endif /* - * hcall interface to pSeries LPAR - */ -#define H_SET_ASR 0x30 - -/* * We layout physical memory as follows: * 0x0000 - 0x00ff : Secondary processor spin code * 0x0100 - 0x2fff : pSeries Interrupt prologs @@ -628,9 +621,7 @@ cmpwi 0,r23,0 beq iSeries_secondary_smp_loop /* Loop until told to go */ -#ifdef SECONDARY_PROCESSORS bne .__secondary_start /* Loop until told to go */ -#endif iSeries_secondary_smp_loop: /* Let the Hypervisor know we are alive */ /* 8002 is a call to HvCallCfg::getLps, a harmless Hypervisor function */ @@ -1324,10 +1315,8 @@ cmpwi 0,r23,0 #ifdef CONFIG_SMP -#ifdef SECONDARY_PROCESSORS bne .__secondary_start #endif -#endif b 3b /* Loop until told to go */ #ifdef CONFIG_PPC_ISERIES From david at gibson.dropbear.id.au Mon Aug 1 15:53:58 2005 From: david at gibson.dropbear.id.au (David Gibson) Date: Mon, 1 Aug 2005 15:53:58 +1000 (EST) Subject: [PATCH 7/8] Tweak comments in ppc64 head.S In-Reply-To: <20050801054810.GA10853@localhost.localdomain> Message-ID: <20050801055358.E366367E40@ozlabs.org> This patch adjust some comments in head.S for accuracy, clarity, and spelling. Signed-off-by: David Gibson arch/ppc64/kernel/head.S | 8 ++++---- 1 files changed, 4 insertions(+), 4 deletions(-) Index: working-2.6/arch/ppc64/kernel/head.S =================================================================== --- working-2.6.orig/arch/ppc64/kernel/head.S 2005-07-28 14:23:22.000000000 +1000 +++ working-2.6/arch/ppc64/kernel/head.S 2005-07-28 14:23:24.000000000 +1000 @@ -147,7 +147,7 @@ std r24,__secondary_hold_acknowledge at l(0) sync - /* All secondary cpu's wait here until told to start. */ + /* All secondary cpus wait here until told to start. */ 100: ld r4,__secondary_hold_spinloop at l(0) cmpdi 0,r4,1 bne 100b @@ -702,8 +702,8 @@ * R9 contains the saved CR, r13 points to the paca, * r10 contains the (bad) kernel stack pointer, * r11 and r12 contain the saved SRR0 and SRR1. - * We switch to using the paca guard page as an emergency stack, - * save the registers there, and call kernel_bad_stack(), which panics. + * We switch to using an emergency stack, save the registers there, + * and call kernel_bad_stack(), which panics. */ bad_stack: ld r1,PACAEMERGSP(r13) @@ -1302,7 +1302,7 @@ b .kexec_wait /* next kernel might do better */ 2: mtspr SPRG3,r13 /* Save vaddr of paca in SPRG3 */ - /* From now on, r24 is expected to be logica cpuid */ + /* From now on, r24 is expected to be logical cpuid */ mr r24,r5 3: HMT_LOW lbz r23,PACAPROCSTART(r13) /* Test if this processor should */ From david at gibson.dropbear.id.au Mon Aug 1 15:53:59 2005 From: david at gibson.dropbear.id.au (David Gibson) Date: Mon, 1 Aug 2005 15:53:59 +1000 (EST) Subject: [PATCH 8/8] Move variables in ppc64 head.S from .data to .bss In-Reply-To: <20050801054810.GA10853@localhost.localdomain> Message-ID: <20050801055359.9FFE567E46@ozlabs.org> The ppc64 head.S defines several zero-initialized structures, such as the empty_zero_page and the kernel top-level pagetable. Currently they are defined to be in the data section. However, they're not used until after the bss is cleared, so this patch moves them to the bss, saving two and a half pages from the vmlinux. Signed-off-by: David Gibson arch/ppc64/kernel/head.S | 13 ++++++------- 1 files changed, 6 insertions(+), 7 deletions(-) Index: working-2.6/arch/ppc64/kernel/head.S =================================================================== --- working-2.6.orig/arch/ppc64/kernel/head.S 2005-07-28 15:07:47.000000000 +1000 +++ working-2.6/arch/ppc64/kernel/head.S 2005-07-28 15:52:43.000000000 +1000 @@ -1970,20 +1970,19 @@ /* * We put a few things here that have to be page-aligned. - * This stuff goes at the beginning of the data segment, - * which is page-aligned. + * This stuff goes at the beginning of the bss, which is page-aligned. */ - .data + .section ".bss" + .align 12 - .globl sdata -sdata: + .globl empty_zero_page empty_zero_page: - .space 4096 + .space PAGE_SIZE .globl swapper_pg_dir swapper_pg_dir: - .space 4096 + .space PAGE_SIZE /* * This space gets a copy of optional info passed to us by the bootstrap From olh at suse.de Mon Aug 1 16:19:04 2005 From: olh at suse.de (Olaf Hering) Date: Mon, 1 Aug 2005 08:19:04 +0200 Subject: RFC: Kill off addRamDisk In-Reply-To: <20050728033118.GC4543@localhost.localdomain> References: <20050728033118.GC4543@localhost.localdomain> Message-ID: <20050801061904.GA21952@suse.de> On Thu, Jul 28, David Gibson wrote: > Can anyone think of any problems with abolishing addRamDisk - the icky > iSeries-specific method of loading an initial ramdisk. If not, I'll > push this to Andrew. > > iSeries has a home-built method of attaching an initial ramdisk, which > relies on an addRamDisk helper program poking the data, location and > offset into the vmlinux after build. Both SLES and RHEL now use the > normal initramfs mechanisms instead of the iSeries specific initrd on > 2.6 kernels, so let's get rid of this obsolete mechanism. How is the initramfs vs. loop mounted file related? Maybe I miss the point, how is the initrd content passed to the kernel during boot after your change? pseries has its own section in zImage.initrd, and yaboot passes just the initrd memrange in r3+r4. Can the $O/usr/initramfs_data.cpio.gz file linked later into the vmlinux file? I see an '.init.ramfs' section there, perhaps you want to replace the addRamdisk binary with an addRamdisk shell script which calls objcopy. But this way we lose the overlay feature. A simple 'find . | cpio -H newc --create | gzip -9 > tmp_initrd.gz' would not work anymore as unprivileged user because mknod cant be done that way. From olh at suse.de Mon Aug 1 16:29:29 2005 From: olh at suse.de (Olaf Hering) Date: Mon, 1 Aug 2005 08:29:29 +0200 Subject: [PPC64] Remove another fixed address constraint In-Reply-To: <20050725061635.GD19817@localhost.localdomain> References: <20050725061635.GD19817@localhost.localdomain> Message-ID: <20050801062929.GA22102@suse.de> On Mon, Jul 25, David Gibson wrote: > Presently the LparMap, one of the structures the kernel shares with > the legacy iSeries hypervisor has a fixed offset address in head.S. > This patch changes this so the LparMap is a normally initialized > structure, without fixed address. This allows us to use macros to > compute some of the values in the structure, which wasn't previously > possible because the assembler always uses signed-% which gets the > wrong answers for the computations in question. > > Unfortunately, a gcc bug means that doing this requires another > structure (hvReleaseData) to be initialized in asm instead of C, but > on the whole the result is cleaner than before. I think this change caused this compile error in rc4: {standard input}: Assembler messages: {standard input}:254: Error: value of 4000000000002080 too large for field of 4 bytes at 0000000000002108 make[1]: *** [arch/ppc64/kernel/LparData.o] Error 1 binutils-2.16.91.0.2 gcc-4.0.2_20050727 From david at gibson.dropbear.id.au Mon Aug 1 16:31:07 2005 From: david at gibson.dropbear.id.au (David Gibson) Date: Mon, 1 Aug 2005 16:31:07 +1000 Subject: RFC: Kill off addRamDisk In-Reply-To: <20050801061904.GA21952@suse.de> References: <20050728033118.GC4543@localhost.localdomain> <20050801061904.GA21952@suse.de> Message-ID: <20050801063107.GB13052@localhost.localdomain> On Mon, Aug 01, 2005 at 08:19:04AM +0200, Olaf Hering wrote: > On Thu, Jul 28, David Gibson wrote: > > > Can anyone think of any problems with abolishing addRamDisk - the icky > > iSeries-specific method of loading an initial ramdisk. If not, I'll > > push this to Andrew. > > > > iSeries has a home-built method of attaching an initial ramdisk, which > > relies on an addRamDisk helper program poking the data, location and > > offset into the vmlinux after build. Both SLES and RHEL now use the > > normal initramfs mechanisms instead of the iSeries specific initrd on > > 2.6 kernels, so let's get rid of this obsolete mechanism. > > How is the initramfs vs. loop mounted file related? > Maybe I miss the point, how is the initrd content passed to the kernel > during boot after your change? pseries has its own section in zImage.initrd, > and yaboot passes just the initrd memrange in r3+r4. Yeah, check the rest of the thread - I realized I was mistaken and that the initramfs, too, needed addRamDisk. I've sent a new patch which removes the fixed address from the NACA without eliminating addRamDisk. Changing addRamDisk to use objcopy instead of direct poking might be something to look at later. > Can the $O/usr/initramfs_data.cpio.gz file linked later into the vmlinux > file? I see an '.init.ramfs' section there, perhaps you want to replace > the addRamdisk binary with an addRamdisk shell script which calls > objcopy. But this way we lose the overlay feature. I'm not sure what you mean by "the overlay feature". > A simple 'find . | cpio -H newc --create | gzip -9 > tmp_initrd.gz' > would not work anymore as unprivileged user because mknod cant be done > that way. How does the method used to combine the vmlinux and initrd have any bearing on what we can do when generating the initrd? -- David Gibson | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/people/dgibson From david at gibson.dropbear.id.au Mon Aug 1 16:35:54 2005 From: david at gibson.dropbear.id.au (David Gibson) Date: Mon, 1 Aug 2005 16:35:54 +1000 Subject: [PPC64] Remove another fixed address constraint In-Reply-To: <20050801062929.GA22102@suse.de> References: <20050725061635.GD19817@localhost.localdomain> <20050801062929.GA22102@suse.de> Message-ID: <20050801063554.GC13052@localhost.localdomain> On Mon, Aug 01, 2005 at 08:29:29AM +0200, Olaf Hering wrote: > On Mon, Jul 25, David Gibson wrote: > > > Presently the LparMap, one of the structures the kernel shares with > > the legacy iSeries hypervisor has a fixed offset address in head.S. > > This patch changes this so the LparMap is a normally initialized > > structure, without fixed address. This allows us to use macros to > > compute some of the values in the structure, which wasn't previously > > possible because the assembler always uses signed-% which gets the > > wrong answers for the computations in question. > > > > Unfortunately, a gcc bug means that doing this requires another > > structure (hvReleaseData) to be initialized in asm instead of C, but > > on the whole the result is cleaner than before. > > I think this change caused this compile error in rc4: > > {standard input}: Assembler messages: > {standard input}:254: Error: value of 4000000000002080 too large for field of 4 bytes at 0000000000002108 > make[1]: *** [arch/ppc64/kernel/LparData.o] Error 1 > > binutils-2.16.91.0.2 > gcc-4.0.2_20050727 Hrm.. definitely works here. Is this with any other patches? Can you send the .s file? That might help be debug it. -- David Gibson | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/people/dgibson From olh at suse.de Mon Aug 1 16:44:05 2005 From: olh at suse.de (Olaf Hering) Date: Mon, 1 Aug 2005 08:44:05 +0200 Subject: RFC: Kill off addRamDisk In-Reply-To: <20050801063107.GB13052@localhost.localdomain> References: <20050728033118.GC4543@localhost.localdomain> <20050801061904.GA21952@suse.de> <20050801063107.GB13052@localhost.localdomain> Message-ID: <20050801064405.GA22175@suse.de> On Mon, Aug 01, David Gibson wrote: > > Can the $O/usr/initramfs_data.cpio.gz file linked later into the vmlinux > > file? I see an '.init.ramfs' section there, perhaps you want to replace > > the addRamdisk binary with an addRamdisk shell script which calls > > objcopy. But this way we lose the overlay feature. > > I'm not sure what you mean by "the overlay feature". The initrd content passed via the bootloader is extracted over the in-kernel cpio image. initramfs_data.cpio.gz contains per default /dev, /dev/console and /root. Thats enough to run udevstart to fill /dev with other required /sys/class/{mem,tty}/ device nodes. Maybe it will work also with an empty rootfs, if nothing fails when the stdin/stdout device node is missing. > > A simple 'find . | cpio -H newc --create | gzip -9 > tmp_initrd.gz' > > would not work anymore as unprivileged user because mknod cant be done > > that way. > > How does the method used to combine the vmlinux and initrd have any > bearing on what we can do when generating the initrd? an user process cant run 'mknod ./dev/console'. I see a panic() in init/main.c if /dev/console is missing. From olh at suse.de Mon Aug 1 16:45:02 2005 From: olh at suse.de (Olaf Hering) Date: Mon, 1 Aug 2005 08:45:02 +0200 Subject: [PPC64] Remove another fixed address constraint In-Reply-To: <20050801063554.GC13052@localhost.localdomain> References: <20050725061635.GD19817@localhost.localdomain> <20050801062929.GA22102@suse.de> <20050801063554.GC13052@localhost.localdomain> Message-ID: <20050801064502.GB22175@suse.de> On Mon, Aug 01, David Gibson wrote: > Hrm.. definitely works here. Is this with any other patches? Can you > send the .s file? That might help be debug it. It works with SLES9 gcc3, only gcc4 (or recent binutils) do not like it. From david at gibson.dropbear.id.au Mon Aug 1 17:09:35 2005 From: david at gibson.dropbear.id.au (David Gibson) Date: Mon, 1 Aug 2005 17:09:35 +1000 Subject: RFC: Kill off addRamDisk In-Reply-To: <20050801064405.GA22175@suse.de> References: <20050728033118.GC4543@localhost.localdomain> <20050801061904.GA21952@suse.de> <20050801063107.GB13052@localhost.localdomain> <20050801064405.GA22175@suse.de> Message-ID: <20050801070935.GD13052@localhost.localdomain> On Mon, Aug 01, 2005 at 08:44:05AM +0200, Olaf Hering wrote: > On Mon, Aug 01, David Gibson wrote: > > > > Can the $O/usr/initramfs_data.cpio.gz file linked later into the vmlinux > > > file? I see an '.init.ramfs' section there, perhaps you want to replace > > > the addRamdisk binary with an addRamdisk shell script which calls > > > objcopy. But this way we lose the overlay feature. > > > > I'm not sure what you mean by "the overlay feature". > > The initrd content passed via the bootloader is extracted over the > in-kernel cpio image. I assume you mean the fact the ramfs added by addRamDisk is overlayed on top of the one built into the vmlinux section? iSeries has no bootloader.. Hrm.. to address that in an objcopy solution we would need to either a) allow multiple initramfs sections, b) allow multiple, concatenated cpios within the ramfs section or c) have the user program extract the preexisting ramfs section, combine it with the new cpio, and replace the combined image into the ramfs. Still, doesn't matter for now, addRamDisk can stay for now. -- David Gibson | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/people/dgibson From david at gibson.dropbear.id.au Mon Aug 1 17:10:50 2005 From: david at gibson.dropbear.id.au (David Gibson) Date: Mon, 1 Aug 2005 17:10:50 +1000 Subject: [PPC64] Remove another fixed address constraint In-Reply-To: <20050801064502.GB22175@suse.de> References: <20050725061635.GD19817@localhost.localdomain> <20050801062929.GA22102@suse.de> <20050801063554.GC13052@localhost.localdomain> <20050801064502.GB22175@suse.de> Message-ID: <20050801071050.GE13052@localhost.localdomain> On Mon, Aug 01, 2005 at 08:45:02AM +0200, Olaf Hering wrote: > On Mon, Aug 01, David Gibson wrote: > > > Hrm.. definitely works here. Is this with any other patches? Can you > > send the .s file? That might help be debug it. > > It works with SLES9 gcc3, only gcc4 (or recent binutils) do not like > it. gcc4 can't be the problem; that's an assembler error. I am using: sneetch:~/kernel$ powerpc64-linux-as --version GNU assembler 2.15.94 20041116 Copyright 2002 Free Software Foundation, Inc. This program is free software; you may redistribute it under the terms of the GNU General Public License. This program has absolutely no warranty. This assembler was configured for a target of `powerpc-linux'. -- David Gibson | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/people/dgibson From benh at kernel.crashing.org Mon Aug 1 18:37:57 2005 From: benh at kernel.crashing.org (Benjamin Herrenschmidt) Date: Mon, 01 Aug 2005 10:37:57 +0200 Subject: [PATCH 0/8] Assorted cleanups to head.S In-Reply-To: <20050801054810.GA10853@localhost.localdomain> References: <20050801054810.GA10853@localhost.localdomain> Message-ID: <1122885477.18835.103.camel@gaston> On Mon, 2005-08-01 at 15:48 +1000, David Gibson wrote: > Hi Paul, > > Please forward upstream, if acceptable. This stack of 8 patches makes > a number of cleanups to head.S, in the process removing several pages > from the kernel runtime image, and a couple more from the vmlinux. All looks good after a quick look... if it boots, I'd say submit it :) Ben. From amodra at bigpond.net.au Tue Aug 2 13:13:45 2005 From: amodra at bigpond.net.au (Alan Modra) Date: Tue, 2 Aug 2005 12:43:45 +0930 Subject: Error: value of 4000000000002080 too large for field of 4 bytes In-Reply-To: <20050801071050.GE13052@localhost.localdomain> References: <20050725061635.GD19817@localhost.localdomain> <20050801062929.GA22102@suse.de> <20050801063554.GC13052@localhost.localdomain> <20050801064502.GB22175@suse.de> <20050801071050.GE13052@localhost.localdomain> Message-ID: <20050802031345.GA2874@bubble.grove.modra.org> On Mon, Aug 01, 2005 at 05:10:50PM +1000, David Gibson wrote: > gcc4 can't be the problem; that's an assembler error. I am using: Yes, it is an assembler bug, present in current sources and all older versions I checked. PowerPC gas prior to 2005-03-02 didn't tickle the bug because it didn't reduce "lparMapPhys" to "xLparMap+0x400...00000" and from there to ".data+0x4000...02080". So with older gas, you had a reloc against lparMapPhys with offset 0, and an entry in the symbol table, section .data, value 0x4000...02080. With newer gas, you (try to) have a reloc against .data with offset 0x4000...02080. It's this offset that gas is complaining about, because ppc gas writes the value into the section contents. Of course, since ppc uses RELA type relocs (addend stored separately from the section contents), the section contents are immaterial; ld will overwrite them with the relocated value. * config/tc-ppc.c (md_apply_fix ): Don't warn on overflow if emitting a reloc. Index: gas/config/tc-ppc.c =================================================================== RCS file: /cvs/src/src/gas/config/tc-ppc.c,v retrieving revision 1.101 diff -u -p -r1.101 tc-ppc.c --- gas/config/tc-ppc.c 5 Jul 2005 13:25:52 -0000 1.101 +++ gas/config/tc-ppc.c 2 Aug 2005 03:06:18 -0000 @@ -6014,6 +6014,13 @@ md_apply_fix (fixP, valP, seg) #ifdef OBJ_ELF fixP->fx_addnumber = value; + + /* PowerPC uses RELA relocs, ie. the reloc addend is stored separately + from the section contents. If we are going to be emitting a reloc + then the section contents are immaterial, so don't warn if they + happen to overflow. Leave such warnings to ld. */ + if (!fixP->fx_done) + fixP->fx_no_overflow = 1; #else if (fixP->fx_r_type != BFD_RELOC_PPC_TOC16) fixP->fx_addnumber = 0; -- Alan Modra IBM OzLabs - Linux Technology Centre From dgibson at ozlabs.org Tue Aug 2 13:58:54 2005 From: dgibson at ozlabs.org (David Gibson) Date: Tue, 2 Aug 2005 13:58:54 +1000 Subject: Error: value of 4000000000002080 too large for field of 4 bytes In-Reply-To: <20050802031345.GA2874@bubble.grove.modra.org> References: <20050725061635.GD19817@localhost.localdomain> <20050801062929.GA22102@suse.de> <20050801063554.GC13052@localhost.localdomain> <20050801064502.GB22175@suse.de> <20050801071050.GE13052@localhost.localdomain> <20050802031345.GA2874@bubble.grove.modra.org> Message-ID: <20050802035854.GA3113@localhost.localdomain> On Tue, Aug 02, 2005 at 12:43:45PM +0930, Alan Modra wrote: > On Mon, Aug 01, 2005 at 05:10:50PM +1000, David Gibson wrote: > > gcc4 can't be the problem; that's an assembler error. I am using: > > Yes, it is an assembler bug, present in current sources and all older > versions I checked. PowerPC gas prior to 2005-03-02 didn't tickle the > bug because it didn't reduce "lparMapPhys" to "xLparMap+0x400...00000" > and from there to ".data+0x4000...02080". So with older gas, you > had a reloc against lparMapPhys with offset 0, and an entry in the > symbol table, section .data, value 0x4000...02080. With newer gas, > you (try to) have a reloc against .data with offset 0x4000...02080. > It's this offset that gas is complaining about, because ppc gas writes > the value into the section contents. Of course, since ppc uses RELA > type relocs (addend stored separately from the section contents), the > section contents are immaterial; ld will overwrite them with the > relocated value. > > * config/tc-ppc.c (md_apply_fix ): Don't warn on overflow > if emitting a reloc. Ah! Does this mean with the fix below, I shouldn't need the indirection of defining lparMapPhys, and could simply do: .long xLparMap - KERNELBASE Thanks Alan, have you pushed this fix upstream yet? > Index: gas/config/tc-ppc.c > =================================================================== > RCS file: /cvs/src/src/gas/config/tc-ppc.c,v > retrieving revision 1.101 > diff -u -p -r1.101 tc-ppc.c > --- gas/config/tc-ppc.c 5 Jul 2005 13:25:52 -0000 1.101 > +++ gas/config/tc-ppc.c 2 Aug 2005 03:06:18 -0000 > @@ -6014,6 +6014,13 @@ md_apply_fix (fixP, valP, seg) > > #ifdef OBJ_ELF > fixP->fx_addnumber = value; > + > + /* PowerPC uses RELA relocs, ie. the reloc addend is stored separately > + from the section contents. If we are going to be emitting a reloc > + then the section contents are immaterial, so don't warn if they > + happen to overflow. Leave such warnings to ld. */ > + if (!fixP->fx_done) > + fixP->fx_no_overflow = 1; > #else > if (fixP->fx_r_type != BFD_RELOC_PPC_TOC16) > fixP->fx_addnumber = 0; > -- David Gibson | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/people/dgibson From bdc at carlstrom.com Tue Aug 2 15:18:04 2005 From: bdc at carlstrom.com (Brian D. Carlstrom) Date: 2 Aug 2005 05:18:04 -0000 Subject: Fan control for new PowerMac G5 2.7GHz machines? Message-ID: <20050802051804.29854.qmail@electricrain.com> I'm trying to get linuxppc64 fan control working on a 2.7GHz G5 machine. I started with YDL 4.0.1's 2.6.10 kernel and already have applied the fixup_device_tree code from: [PATCH] ppc64: Fix booting on latest G5 models http://ozlabs.org/pipermail/linuxppc64-dev/2005-May/004140.html Its nice to be up and running but the fans are running at full speed, similar to what I remember with YDL 4.0 and the therm_pm72 patch. /var/log/dmesg shows the following: PowerMac G5 Thermal control driver 1.1 adb: starting probe task... adb: finished probe task... Detected fan controls: 0: PWM fan, id 1, location: BACKSIDE,SYS CTRLR FAN 1: RPM fan, id 2, location: DRIVE BAY 2: PWM fan, id 2, location: SLOT,PCI FAN 3: RPM fan, id 3, location: CPU A INTAKE 4: RPM fan, id 4, location: CPU A EXHAUST 5: RPM fan, id 5, location: CPU B INTAKE 6: RPM fan, id 6, location: CPU B EXHAUST 7: RPM fan, id 1, location: CPU A PUMP 8: RPM fan, id 0, location: CPU B PUMP I noticed that YDL seems to have applied the main part of this patch to their 2.6.10 tree, as you can see from the "SYS CTRLR FAN" string, although they left the version as "1.1": Patch: Thermal control for Xserve http://patchwork.ozlabs.org/linuxppc64/patch?id=697 Beyond the fixup_device_tree patch, I haven't seen much talk about the status of linuxppc64 on the 2.7 GHz G5. There was this once post on yellowdog-devel: g5 2.7 works with 4.0.91 beta. http://lists.terrasoftsolutions.com/pipermail/yellowdog-devel/2005-June/000433.html but it's kind of sparse on the details. Can anyone shed some light on the fan support for these new machines? Am I just doing something simple wrong or missing something obvious? Thanks, -bri From jdl at freescale.com Wed Aug 3 08:59:35 2005 From: jdl at freescale.com (Jon Loeliger) Date: Tue, 02 Aug 2005 17:59:35 -0500 Subject: Beginning Merger Patch Message-ID: <1123023575.2614.25.camel@cashmere.sps.mot.com> Folks, I have grabbed my asbestos suit. Here is a patch to begin the process of merging the PPC32 and PPC64 include directories into a new common "powerpc" arch. This patch introduces the include/asm-powerpc directory. It then places into it, all of the files in asm-ppc and asm-ppc64 that are essentially identical. A stub is left in asm-ppc and asm-ppc64 pointing to the unified files. No real thought went into this set of files; these are the dead-simple identical files for starters! This patch can be rsync'ed from here: rsync www.jdl.com::pub/software/patches/linux-20050802-01.patch 20050802-01.patch It may be cg-pull'ed from this tree: cg-clone http://www.jdl.com/pub/software/linux-2.6-jdl.git or cg-clone rsync://www.jdl.com/pub/software/linux-2.6-jdl.git Oh yeah. jdl Signed-off-by: Jon Loeliger --- commit 2c6a0ac49cb3ec2b73fc48b015aa3550e2df27c7 tree f12b4db25885fb67cacf1597daf2a789140c974d parent 9a351e30d72d409ec62c83f380e330e0baa584b4 author Jon Loeliger Tue, 02 Aug 2005 14:27:26 -0500 committer Jon Loeliger Tue, 02 Aug 2005 14:27:26 -0500 include/asm-powerpc/8253pit.h | 10 +++++++++ include/asm-powerpc/agp.h | 23 +++++++++++++++++++++ include/asm-powerpc/cputime.h | 1 + include/asm-powerpc/emergency-restart.h | 1 + include/asm-powerpc/errno.h | 18 ++++++++++++++++ include/asm-powerpc/hdreg.h | 1 + include/asm-powerpc/ipc.h | 1 + include/asm-powerpc/linkage.h | 6 +++++ include/asm-powerpc/local.h | 1 + include/asm-powerpc/parport.h | 18 ++++++++++++++++ include/asm-powerpc/percpu.h | 1 + include/asm-powerpc/poll.h | 32 +++++++++++++++++++++++++++++ include/asm-powerpc/resource.h | 1 + include/asm-powerpc/shmparam.h | 13 ++++++++++++ include/asm-powerpc/xor.h | 1 + include/asm-ppc/8253pit.h | 12 ++--------- include/asm-ppc/agp.h | 25 ++--------------------- include/asm-ppc/cputime.h | 5 ----- include/asm-ppc/emergency-restart.h | 5 ----- include/asm-ppc/errno.h | 13 ++---------- include/asm-ppc/linkage.h | 8 ++----- include/asm-ppc/local.h | 5 ----- include/asm-ppc/parport.h | 19 +---------------- include/asm-ppc/percpu.h | 5 ----- include/asm-ppc/poll.h | 25 ++--------------------- include/asm-ppc/resource.h | 5 ----- include/asm-ppc/shmparam.h | 7 ++---- include/asm-ppc64/8253pit.h | 12 ++--------- include/asm-ppc64/agp.h | 25 ++--------------------- include/asm-ppc64/cputime.h | 5 ----- include/asm-ppc64/emergency-restart.h | 5 ----- include/asm-ppc64/errno.h | 20 ++---------------- include/asm-ppc64/linkage.h | 8 ++----- include/asm-ppc64/parport.h | 19 +---------------- include/asm-ppc64/percpu.h | 5 ----- include/asm-ppc64/poll.h | 34 ++----------------------------- include/asm-ppc64/resource.h | 5 ----- include/asm-ppc64/shmparam.h | 15 ++------------ 38 files changed, 154 insertions(+), 261 deletions(-) diff --git a/include/asm-powerpc/8253pit.h b/include/asm-powerpc/8253pit.h new file mode 100644 --- /dev/null +++ b/include/asm-powerpc/8253pit.h @@ -0,0 +1,10 @@ +/* + * 8253/8254 Programmable Interval Timer + */ + +#ifndef _ASM_POWERPC_8253PIT_H +#define _ASM_POWERPC_8253PIT_H + +#define PIT_TICK_RATE 1193182UL + +#endif /* _ASM_POWERPC_8253PIT_H */ diff --git a/include/asm-powerpc/agp.h b/include/asm-powerpc/agp.h new file mode 100644 --- /dev/null +++ b/include/asm-powerpc/agp.h @@ -0,0 +1,23 @@ +#ifndef _ASM_POWERPC_AGP_H +#define _ASM_POWERPC_AGP_H + +#include + +/* nothing much needed here */ + +#define map_page_into_agp(page) +#define unmap_page_from_agp(page) +#define flush_agp_mappings() +#define flush_agp_cache() mb() + +/* Convert a physical address to an address suitable for the GART. */ +#define phys_to_gart(x) (x) +#define gart_to_phys(x) (x) + +/* GATT allocation. Returns/accepts GATT kernel virtual address. */ +#define alloc_gatt_pages(order) \ + ((char *)__get_free_pages(GFP_KERNEL, (order))) +#define free_gatt_pages(table, order) \ + free_pages((unsigned long)(table), (order)) + +#endif /* _ASM_POWERPC_AGP_H */ diff --git a/include/asm-powerpc/cputime.h b/include/asm-powerpc/cputime.h new file mode 100644 --- /dev/null +++ b/include/asm-powerpc/cputime.h @@ -0,0 +1 @@ +#include diff --git a/include/asm-powerpc/emergency-restart.h b/include/asm-powerpc/emergency-restart.h new file mode 100644 --- /dev/null +++ b/include/asm-powerpc/emergency-restart.h @@ -0,0 +1 @@ +#include diff --git a/include/asm-powerpc/errno.h b/include/asm-powerpc/errno.h new file mode 100644 --- /dev/null +++ b/include/asm-powerpc/errno.h @@ -0,0 +1,18 @@ +/* + * 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. + */ + +#ifndef _ASM_POWERPC_ERRNO_H +#define _ASM_POWERPC_ERRNO_H + +#include + +#undef EDEADLOCK +#define EDEADLOCK 58 /* File locking deadlock error */ + +#define _LAST_ERRNO 516 + +#endif /* _ASM_POWERPC_ERRNO_H */ diff --git a/include/asm-powerpc/hdreg.h b/include/asm-powerpc/hdreg.h new file mode 100644 --- /dev/null +++ b/include/asm-powerpc/hdreg.h @@ -0,0 +1 @@ +#include diff --git a/include/asm-powerpc/ipc.h b/include/asm-powerpc/ipc.h new file mode 100644 --- /dev/null +++ b/include/asm-powerpc/ipc.h @@ -0,0 +1 @@ +#include diff --git a/include/asm-powerpc/linkage.h b/include/asm-powerpc/linkage.h new file mode 100644 --- /dev/null +++ b/include/asm-powerpc/linkage.h @@ -0,0 +1,6 @@ +#ifndef _ASM_POWERPC_LINKAGE_H +#define _ASM_POWERPC_LINKAGE_H + +/* Nothing to see here... */ + +#endif /* _ASM_POWERPC_LINKAGE_H */ diff --git a/include/asm-powerpc/local.h b/include/asm-powerpc/local.h new file mode 100644 --- /dev/null +++ b/include/asm-powerpc/local.h @@ -0,0 +1 @@ +#include diff --git a/include/asm-powerpc/parport.h b/include/asm-powerpc/parport.h new file mode 100644 --- /dev/null +++ b/include/asm-powerpc/parport.h @@ -0,0 +1,18 @@ +/* + * parport.h: platform-specific PC-style parport initialisation + * + * Copyright (C) 1999, 2000 Tim Waugh + * + * This file should only be included by drivers/parport/parport_pc.c. + */ + +#ifndef _ASM_POWERPC_PARPORT_H +#define _ASM_POWERPC_PARPORT_H + +static int __devinit parport_pc_find_isa_ports (int autoirq, int autodma); +static int __devinit parport_pc_find_nonpci_ports (int autoirq, int autodma) +{ + return parport_pc_find_isa_ports (autoirq, autodma); +} + +#endif /* _ASM_POWERPC_PARPORT_H */ diff --git a/include/asm-powerpc/percpu.h b/include/asm-powerpc/percpu.h new file mode 100644 --- /dev/null +++ b/include/asm-powerpc/percpu.h @@ -0,0 +1 @@ +#include diff --git a/include/asm-powerpc/poll.h b/include/asm-powerpc/poll.h new file mode 100644 --- /dev/null +++ b/include/asm-powerpc/poll.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2001 PPC64 Team, IBM Corp + * + * 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. + */ + +#ifndef _ASM_POWERPC_POLL_H +#define _ASM_POWERPC_POLL_H + +#define POLLIN 0x0001 +#define POLLPRI 0x0002 +#define POLLOUT 0x0004 +#define POLLERR 0x0008 +#define POLLHUP 0x0010 +#define POLLNVAL 0x0020 +#define POLLRDNORM 0x0040 +#define POLLRDBAND 0x0080 +#define POLLWRNORM 0x0100 +#define POLLWRBAND 0x0200 +#define POLLMSG 0x0400 +#define POLLREMOVE 0x1000 + +struct pollfd { + int fd; + short events; + short revents; +}; + +#endif /* _ASM_POWERPC_POLL_H */ diff --git a/include/asm-powerpc/resource.h b/include/asm-powerpc/resource.h new file mode 100644 --- /dev/null +++ b/include/asm-powerpc/resource.h @@ -0,0 +1 @@ +#include diff --git a/include/asm-powerpc/shmparam.h b/include/asm-powerpc/shmparam.h new file mode 100644 --- /dev/null +++ b/include/asm-powerpc/shmparam.h @@ -0,0 +1,13 @@ +/* + * 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. + */ + +#ifndef _ASM_POWERPC_SHMPARAM_H +#define _ASM_POWERPC_SHMPARAM_H + +#define SHMLBA PAGE_SIZE /* attach addr a multiple of this */ + +#endif /* _ASM_POWERPC_SHMPARAM_H */ diff --git a/include/asm-powerpc/xor.h b/include/asm-powerpc/xor.h new file mode 100644 --- /dev/null +++ b/include/asm-powerpc/xor.h @@ -0,0 +1 @@ +#include diff --git a/include/asm-ppc/8253pit.h b/include/asm-ppc/8253pit.h --- a/include/asm-ppc/8253pit.h +++ b/include/asm-ppc/8253pit.h @@ -1,10 +1,2 @@ -/* - * 8253/8254 Programmable Interval Timer - */ - -#ifndef _8253PIT_H -#define _8253PIT_H - -#define PIT_TICK_RATE 1193182UL - -#endif +/* ppc and ppc64 are being merged into powerpc */ +#include diff --git a/include/asm-ppc/agp.h b/include/asm-ppc/agp.h --- a/include/asm-ppc/agp.h +++ b/include/asm-ppc/agp.h @@ -1,23 +1,2 @@ -#ifndef AGP_H -#define AGP_H 1 - -#include - -/* nothing much needed here */ - -#define map_page_into_agp(page) -#define unmap_page_from_agp(page) -#define flush_agp_mappings() -#define flush_agp_cache() mb() - -/* Convert a physical address to an address suitable for the GART. */ -#define phys_to_gart(x) (x) -#define gart_to_phys(x) (x) - -/* GATT allocation. Returns/accepts GATT kernel virtual address. */ -#define alloc_gatt_pages(order) \ - ((char *)__get_free_pages(GFP_KERNEL, (order))) -#define free_gatt_pages(table, order) \ - free_pages((unsigned long)(table), (order)) - -#endif +/* ppc and ppc64 are being merged into powerpc */ +#include diff --git a/include/asm-ppc/cputime.h b/include/asm-ppc/cputime.h --- a/include/asm-ppc/cputime.h +++ b/include/asm-ppc/cputime.h @@ -1,6 +1 @@ -#ifndef __PPC_CPUTIME_H -#define __PPC_CPUTIME_H - #include - -#endif /* __PPC_CPUTIME_H */ diff --git a/include/asm-ppc/emergency-restart.h b/include/asm-ppc/emergency-restart.h --- a/include/asm-ppc/emergency-restart.h +++ b/include/asm-ppc/emergency-restart.h @@ -1,6 +1 @@ -#ifndef _ASM_EMERGENCY_RESTART_H -#define _ASM_EMERGENCY_RESTART_H - #include - -#endif /* _ASM_EMERGENCY_RESTART_H */ diff --git a/include/asm-ppc/errno.h b/include/asm-ppc/errno.h --- a/include/asm-ppc/errno.h +++ b/include/asm-ppc/errno.h @@ -1,11 +1,2 @@ -#ifndef _PPC_ERRNO_H -#define _PPC_ERRNO_H - -#include - -#undef EDEADLOCK -#define EDEADLOCK 58 /* File locking deadlock error */ - -#define _LAST_ERRNO 516 - -#endif +/* ppc and ppc64 are being merged into powerpc */ +#include diff --git a/include/asm-ppc/linkage.h b/include/asm-ppc/linkage.h --- a/include/asm-ppc/linkage.h +++ b/include/asm-ppc/linkage.h @@ -1,6 +1,2 @@ -#ifndef __ASM_LINKAGE_H -#define __ASM_LINKAGE_H - -/* Nothing to see here... */ - -#endif +/* ppc and ppc64 are being merged into powerpc */ +#include diff --git a/include/asm-ppc/local.h b/include/asm-ppc/local.h --- a/include/asm-ppc/local.h +++ b/include/asm-ppc/local.h @@ -1,6 +1 @@ -#ifndef __PPC_LOCAL_H -#define __PPC_LOCAL_H - #include - -#endif /* __PPC_LOCAL_H */ diff --git a/include/asm-ppc/parport.h b/include/asm-ppc/parport.h --- a/include/asm-ppc/parport.h +++ b/include/asm-ppc/parport.h @@ -1,18 +1 @@ -/* - * parport.h: platform-specific PC-style parport initialisation - * - * Copyright (C) 1999, 2000 Tim Waugh - * - * This file should only be included by drivers/parport/parport_pc.c. - */ - -#ifndef _ASM_PPC_PARPORT_H -#define _ASM_PPC_PARPORT_H - -static int __devinit parport_pc_find_isa_ports (int autoirq, int autodma); -static int __devinit parport_pc_find_nonpci_ports (int autoirq, int autodma) -{ - return parport_pc_find_isa_ports (autoirq, autodma); -} - -#endif /* !(_ASM_PPC_PARPORT_H) */ +#include diff --git a/include/asm-ppc/percpu.h b/include/asm-ppc/percpu.h --- a/include/asm-ppc/percpu.h +++ b/include/asm-ppc/percpu.h @@ -1,6 +1 @@ -#ifndef __ARCH_PPC_PERCPU__ -#define __ARCH_PPC_PERCPU__ - #include - -#endif /* __ARCH_PPC_PERCPU__ */ diff --git a/include/asm-ppc/poll.h b/include/asm-ppc/poll.h --- a/include/asm-ppc/poll.h +++ b/include/asm-ppc/poll.h @@ -1,23 +1,2 @@ -#ifndef __PPC_POLL_H -#define __PPC_POLL_H - -#define POLLIN 0x0001 -#define POLLPRI 0x0002 -#define POLLOUT 0x0004 -#define POLLERR 0x0008 -#define POLLHUP 0x0010 -#define POLLNVAL 0x0020 -#define POLLRDNORM 0x0040 -#define POLLRDBAND 0x0080 -#define POLLWRNORM 0x0100 -#define POLLWRBAND 0x0200 -#define POLLMSG 0x0400 -#define POLLREMOVE 0x1000 - -struct pollfd { - int fd; - short events; - short revents; -}; - -#endif +/* ppc and ppc64 are being merged into powerpc */ +#include diff --git a/include/asm-ppc/resource.h b/include/asm-ppc/resource.h --- a/include/asm-ppc/resource.h +++ b/include/asm-ppc/resource.h @@ -1,6 +1 @@ -#ifndef _PPC_RESOURCE_H -#define _PPC_RESOURCE_H - #include - -#endif diff --git a/include/asm-ppc/shmparam.h b/include/asm-ppc/shmparam.h --- a/include/asm-ppc/shmparam.h +++ b/include/asm-ppc/shmparam.h @@ -1,6 +1,3 @@ -#ifndef _PPC_SHMPARAM_H -#define _PPC_SHMPARAM_H +/* ppc and ppc64 are being merged into powerpc */ +#include -#define SHMLBA PAGE_SIZE /* attach addr a multiple of this */ - -#endif /* _PPC_SHMPARAM_H */ diff --git a/include/asm-ppc64/8253pit.h b/include/asm-ppc64/8253pit.h --- a/include/asm-ppc64/8253pit.h +++ b/include/asm-ppc64/8253pit.h @@ -1,10 +1,2 @@ -/* - * 8253/8254 Programmable Interval Timer - */ - -#ifndef _8253PIT_H -#define _8253PIT_H - -#define PIT_TICK_RATE 1193182UL - -#endif +/* ppc and ppc64 are being merged into powerpc */ +#include diff --git a/include/asm-ppc64/agp.h b/include/asm-ppc64/agp.h --- a/include/asm-ppc64/agp.h +++ b/include/asm-ppc64/agp.h @@ -1,23 +1,2 @@ -#ifndef AGP_H -#define AGP_H 1 - -#include - -/* nothing much needed here */ - -#define map_page_into_agp(page) -#define unmap_page_from_agp(page) -#define flush_agp_mappings() -#define flush_agp_cache() mb() - -/* Convert a physical address to an address suitable for the GART. */ -#define phys_to_gart(x) (x) -#define gart_to_phys(x) (x) - -/* GATT allocation. Returns/accepts GATT kernel virtual address. */ -#define alloc_gatt_pages(order) \ - ((char *)__get_free_pages(GFP_KERNEL, (order))) -#define free_gatt_pages(table, order) \ - free_pages((unsigned long)(table), (order)) - -#endif +/* ppc and ppc64 are being merged into powerpc */ +#include diff --git a/include/asm-ppc64/cputime.h b/include/asm-ppc64/cputime.h --- a/include/asm-ppc64/cputime.h +++ b/include/asm-ppc64/cputime.h @@ -1,6 +1 @@ -#ifndef __PPC_CPUTIME_H -#define __PPC_CPUTIME_H - #include - -#endif /* __PPC_CPUTIME_H */ diff --git a/include/asm-ppc64/emergency-restart.h b/include/asm-ppc64/emergency-restart.h --- a/include/asm-ppc64/emergency-restart.h +++ b/include/asm-ppc64/emergency-restart.h @@ -1,6 +1 @@ -#ifndef _ASM_EMERGENCY_RESTART_H -#define _ASM_EMERGENCY_RESTART_H - #include - -#endif /* _ASM_EMERGENCY_RESTART_H */ diff --git a/include/asm-ppc64/errno.h b/include/asm-ppc64/errno.h --- a/include/asm-ppc64/errno.h +++ b/include/asm-ppc64/errno.h @@ -1,18 +1,2 @@ -#ifndef _PPC64_ERRNO_H -#define _PPC64_ERRNO_H - -/* - * 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 - -#undef EDEADLOCK -#define EDEADLOCK 58 /* File locking deadlock error */ - -#define _LAST_ERRNO 516 - -#endif +/* ppc and ppc64 are being merged into powerpc */ +#include diff --git a/include/asm-ppc64/linkage.h b/include/asm-ppc64/linkage.h --- a/include/asm-ppc64/linkage.h +++ b/include/asm-ppc64/linkage.h @@ -1,6 +1,2 @@ -#ifndef __ASM_LINKAGE_H -#define __ASM_LINKAGE_H - -/* Nothing to see here... */ - -#endif +/* ppc and ppc64 are being merged into powerpc */ +#include diff --git a/include/asm-ppc64/parport.h b/include/asm-ppc64/parport.h --- a/include/asm-ppc64/parport.h +++ b/include/asm-ppc64/parport.h @@ -1,18 +1 @@ -/* - * parport.h: platform-specific PC-style parport initialisation - * - * Copyright (C) 1999, 2000 Tim Waugh - * - * This file should only be included by drivers/parport/parport_pc.c. - */ - -#ifndef _ASM_PPC64_PARPORT_H -#define _ASM_PPC64_PARPORT_H - -static int __devinit parport_pc_find_isa_ports (int autoirq, int autodma); -static int __devinit parport_pc_find_nonpci_ports (int autoirq, int autodma) -{ - return parport_pc_find_isa_ports (autoirq, autodma); -} - -#endif /* !(_ASM_PPC_PARPORT_H) */ +#include diff --git a/include/asm-ppc64/percpu.h b/include/asm-ppc64/percpu.h --- a/include/asm-ppc64/percpu.h +++ b/include/asm-ppc64/percpu.h @@ -1,6 +1 @@ -#ifndef __ARCH_PPC64_PERCPU__ -#define __ARCH_PPC64_PERCPU__ - #include - -#endif /* __ARCH_PPC64_PERCPU__ */ diff --git a/include/asm-ppc64/poll.h b/include/asm-ppc64/poll.h --- a/include/asm-ppc64/poll.h +++ b/include/asm-ppc64/poll.h @@ -1,32 +1,2 @@ -#ifndef __PPC64_POLL_H -#define __PPC64_POLL_H - -/* - * Copyright (C) 2001 PPC64 Team, IBM Corp - * - * 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. - */ - -#define POLLIN 0x0001 -#define POLLPRI 0x0002 -#define POLLOUT 0x0004 -#define POLLERR 0x0008 -#define POLLHUP 0x0010 -#define POLLNVAL 0x0020 -#define POLLRDNORM 0x0040 -#define POLLRDBAND 0x0080 -#define POLLWRNORM 0x0100 -#define POLLWRBAND 0x0200 -#define POLLMSG 0x0400 -#define POLLREMOVE 0x1000 - -struct pollfd { - int fd; - short events; - short revents; -}; - -#endif /* __PPC64_POLL_H */ +/* ppc and ppc64 are being merged into powerpc */ +#include diff --git a/include/asm-ppc64/resource.h b/include/asm-ppc64/resource.h --- a/include/asm-ppc64/resource.h +++ b/include/asm-ppc64/resource.h @@ -1,6 +1 @@ -#ifndef _PPC64_RESOURCE_H -#define _PPC64_RESOURCE_H - #include - -#endif /* _PPC64_RESOURCE_H */ diff --git a/include/asm-ppc64/shmparam.h b/include/asm-ppc64/shmparam.h --- a/include/asm-ppc64/shmparam.h +++ b/include/asm-ppc64/shmparam.h @@ -1,13 +1,2 @@ -#ifndef _PPC64_SHMPARAM_H -#define _PPC64_SHMPARAM_H - -/* - * 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. - */ - -#define SHMLBA PAGE_SIZE /* attach addr a multiple of this */ - -#endif /* _PPC64_SHMPARAM_H */ +/* ppc and ppc64 are being merged into powerpc */ +#include From ebs at ebshome.net Wed Aug 3 09:05:37 2005 From: ebs at ebshome.net (Eugene Surovegin) Date: Tue, 2 Aug 2005 16:05:37 -0700 Subject: Beginning Merger Patch In-Reply-To: <1123023575.2614.25.camel@cashmere.sps.mot.com> References: <1123023575.2614.25.camel@cashmere.sps.mot.com> Message-ID: <20050802230537.GA9125@gate.ebshome.net> On Tue, Aug 02, 2005 at 05:59:35PM -0500, Jon Loeliger wrote: > Here is a patch to begin the process of merging > the PPC32 and PPC64 include directories into a > new common "powerpc" arch. > > This patch introduces the include/asm-powerpc directory. > It then places into it, all of the files in asm-ppc and > asm-ppc64 that are essentially identical. A stub is left > in asm-ppc and asm-ppc64 pointing to the unified files. > No real thought went into this set of files; these are > the dead-simple identical files for starters! Hmm, I got an impression that we wouldn't touch ppc and ppc64 for now and just _copy_ or create clean stuff into powerpc. I think this will be much safer, at least at the beginning. -- Eugene From ebs at ebshome.net Wed Aug 3 09:17:09 2005 From: ebs at ebshome.net (Eugene Surovegin) Date: Tue, 2 Aug 2005 16:17:09 -0700 Subject: Beginning Merger Patch In-Reply-To: References: <1123023575.2614.25.camel@cashmere.sps.mot.com> <20050802230537.GA9125@gate.ebshome.net> Message-ID: <20050802231709.GB9125@gate.ebshome.net> On Tue, Aug 02, 2005 at 07:12:05PM -0400, Dan Malek wrote: > > On Aug 2, 2005, at 7:05 PM, Eugene Surovegin wrote: > > >Hmm, I got an impression that we wouldn't touch ppc and ppc64 for > >now and just _copy_ or create clean stuff into powerpc. I think this > >will be much safer, at least at the beginning. > > Shouldn't this be a 2.7 project? Maybe, I'm still waiting for official announcement from the maintainer :) -- Eugene From dan at embeddededge.com Wed Aug 3 09:10:56 2005 From: dan at embeddededge.com (Dan Malek) Date: Tue, 2 Aug 2005 19:10:56 -0400 Subject: Beginning Merger Patch In-Reply-To: <1123023575.2614.25.camel@cashmere.sps.mot.com> References: <1123023575.2614.25.camel@cashmere.sps.mot.com> Message-ID: <688ba2276de281a9473b030a16a514c0@embeddededge.com> On Aug 2, 2005, at 6:59 PM, Jon Loeliger wrote: > ..... A stub is left > in asm-ppc and asm-ppc64 pointing to the unified files. Why bother? You may as well change all of the source files, too, or else that will never get done :-) Thanks. -- Dan From dan at embeddededge.com Wed Aug 3 09:12:05 2005 From: dan at embeddededge.com (Dan Malek) Date: Tue, 2 Aug 2005 19:12:05 -0400 Subject: Beginning Merger Patch In-Reply-To: <20050802230537.GA9125@gate.ebshome.net> References: <1123023575.2614.25.camel@cashmere.sps.mot.com> <20050802230537.GA9125@gate.ebshome.net> Message-ID: On Aug 2, 2005, at 7:05 PM, Eugene Surovegin wrote: > Hmm, I got an impression that we wouldn't touch ppc and ppc64 for > now and just _copy_ or create clean stuff into powerpc. I think this > will be much safer, at least at the beginning. Shouldn't this be a 2.7 project? -- Dan From ntl at pobox.com Wed Aug 3 12:17:42 2005 From: ntl at pobox.com (Nathan Lynch) Date: Tue, 2 Aug 2005 21:17:42 -0500 Subject: Beginning Merger Patch In-Reply-To: <1123023575.2614.25.camel@cashmere.sps.mot.com> References: <1123023575.2614.25.camel@cashmere.sps.mot.com> Message-ID: <20050803021742.GB3985@otto> Jon Loeliger wrote: > Folks, > > I have grabbed my asbestos suit. > > Here is a patch to begin the process of merging > the PPC32 and PPC64 include directories into a > new common "powerpc" arch. Perhaps you could briefly explain the motivation for this? I think I've heard/read that something like this was in the works, but I'd like to know what the problem is, and why it should be solved this way instead of e.g. x86_64's method of including headers directly from asm-i386. Nathan From ebs at ebshome.net Wed Aug 3 12:58:06 2005 From: ebs at ebshome.net (Eugene Surovegin) Date: Tue, 2 Aug 2005 19:58:06 -0700 Subject: Beginning Merger Patch In-Reply-To: <20050803021742.GB3985@otto> References: <1123023575.2614.25.camel@cashmere.sps.mot.com> <20050803021742.GB3985@otto> Message-ID: <20050803025806.GC9125@gate.ebshome.net> On Tue, Aug 02, 2005 at 09:17:42PM -0500, Nathan Lynch wrote: > Jon Loeliger wrote: > > Folks, > > > > I have grabbed my asbestos suit. > > > > Here is a patch to begin the process of merging > > the PPC32 and PPC64 include directories into a > > new common "powerpc" arch. > > Perhaps you could briefly explain the motivation for this? > > I think I've heard/read that something like this was in the works, but > I'd like to know what the problem is, and why it should be solved this > way instead of e.g. x86_64's method of including headers directly from > asm-i386. I think the reason for such approach is that there will be no asm-ppc and asm-ppc64 in the end of this transition. This differs significantly from i386/x86_64 situation. -- Eugene From paulus at samba.org Wed Aug 3 13:08:57 2005 From: paulus at samba.org (Paul Mackerras) Date: Wed, 3 Aug 2005 13:08:57 +1000 Subject: Beginning Merger Patch In-Reply-To: References: <1123023575.2614.25.camel@cashmere.sps.mot.com> <20050802230537.GA9125@gate.ebshome.net> Message-ID: <17136.13641.777687.620155@cargo.ozlabs.ibm.com> Dan Malek writes: > Shouldn't this be a 2.7 project? I don't think so; I don't think it's going to be as dramatically invasive as to need to wait for a 2.7, and in any case, there is no sign of 2.7 on the horizon. Paul. From paulus at samba.org Wed Aug 3 13:07:34 2005 From: paulus at samba.org (Paul Mackerras) Date: Wed, 3 Aug 2005 13:07:34 +1000 Subject: Merging ppc32 and ppc64 Message-ID: <17136.13558.773102.465379@cargo.ozlabs.ibm.com> At OLS I discussed the idea of merging the ppc32 and ppc64 architectures in the Linux kernel with various ppc32 and ppc64 kernel hackers and users. There was broad agreement that this would be a good thing to do, so we are going to go ahead and do it. The plan is to create include/asm-powerpc and arch/powerpc directories for the merged architecture and move stuff in there as it gets merged. The existing ppc32 and ppc64 directories will stay around until they are no longer useful. The intention is not to break anything that currently works; however, we do not plan to move unused and unmaintained platforms into the merged architecture. The advantage of merging is that it will reduce the maintenance effort and reduce the instances where a common bug gets fixed in one architecture but not the other. It will also make it easier to support 64-bit embedded systems as they become more common. I don't see the merge as changing the actual code that gets executed on any given platform very much, except in one respect: we are going to standardize on a flattened device tree as the way that information about the platform gets passed from the boot loader to the kernel. Comments? Flames? :) Paul. From jwboyer at jdub.homelinux.org Wed Aug 3 12:38:15 2005 From: jwboyer at jdub.homelinux.org (Josh Boyer) Date: Tue, 02 Aug 2005 21:38:15 -0500 Subject: Beginning Merger Patch In-Reply-To: <20050802230537.GA9125@gate.ebshome.net> References: <1123023575.2614.25.camel@cashmere.sps.mot.com> <20050802230537.GA9125@gate.ebshome.net> Message-ID: <1123036695.4755.36.camel@yoda.jdub.homelinux.org> On Tue, 2005-08-02 at 16:05 -0700, Eugene Surovegin wrote: > On Tue, Aug 02, 2005 at 05:59:35PM -0500, Jon Loeliger wrote: > > Here is a patch to begin the process of merging > > the PPC32 and PPC64 include directories into a > > new common "powerpc" arch. > > > > This patch introduces the include/asm-powerpc directory. > > It then places into it, all of the files in asm-ppc and > > asm-ppc64 that are essentially identical. A stub is left > > in asm-ppc and asm-ppc64 pointing to the unified files. > > No real thought went into this set of files; these are > > the dead-simple identical files for starters! > > Hmm, I got an impression that we wouldn't touch ppc and ppc64 for > now and just _copy_ or create clean stuff into powerpc. I think this > will be much safer, at least at the beginning. Safer, maybe. But then you have triple maintenance, since all the files in question were just duplicates. Patches like this don't need to be applied right away. They take time and lots of vetting. They can live as separate entities until they are really ready to be committed. That being said, I say go whole-hog and do it as Jon has done. Especially considering that he has a git tree that can be worked from. josh From sfr at canb.auug.org.au Wed Aug 3 14:26:39 2005 From: sfr at canb.auug.org.au (Stephen Rothwell) Date: Wed, 3 Aug 2005 14:26:39 +1000 Subject: [PATCH] 0/4 abstract firmware feature checks Message-ID: <20050803142639.2bc38771.sfr@canb.auug.org.au> Hi all, This series of patches are intended to abstract the current firmware feature checks in such a way that they may be (sometimes) evaluated at compile time. This should hopefully, reduce the checks on CONFIG_PPC_[IP]SERIES. They also introduce a feature bit to identify the iSeries hypervisor. Thanks to Arnd Bergmann for the method I have taken from his CPU_HAS_FEATURE patch. arch/ppc64/kernel/Makefile | 2 arch/ppc64/kernel/cputable.c | 40 --------------- arch/ppc64/kernel/firmware.c | 47 +++++++++++++++++ arch/ppc64/kernel/iSeries_setup.c | 3 + arch/ppc64/kernel/lparcfg.c | 6 +- arch/ppc64/kernel/pSeries_iommu.c | 3 - arch/ppc64/kernel/pSeries_lpar.c | 1 arch/ppc64/kernel/pSeries_setup.c | 18 +++--- arch/ppc64/kernel/pSeries_smp.c | 3 - arch/ppc64/kernel/process.c | 12 +--- arch/ppc64/kernel/sysfs.c | 5 - arch/ppc64/kernel/time.c | 7 +- include/asm-ppc64/cputable.h | 47 +---------------- include/asm-ppc64/firmware.h | 101 ++++++++++++++++++++++++++++++++++++++ 14 files changed, 181 insertions(+), 114 deletions(-) -- Cheers, Stephen Rothwell sfr at canb.auug.org.au http://www.canb.auug.org.au/~sfr/ From sfr at canb.auug.org.au Wed Aug 3 14:32:30 2005 From: sfr at canb.auug.org.au (Stephen Rothwell) Date: Wed, 3 Aug 2005 14:32:30 +1000 Subject: [PATCH] 1/4 remove firmware features from cpu_spec In-Reply-To: <20050803142639.2bc38771.sfr@canb.auug.org.au> References: <20050803142639.2bc38771.sfr@canb.auug.org.au> Message-ID: <20050803143230.0500e9b3.sfr@canb.auug.org.au> The firmware_features field of struct cpu_spec should really be a separate variable as the firmware features do not depend on the chip and the bitmask is constructed independently. By removing it, we save 112 bytes from the cpu_specs array and we access the bitmask directly instead of via the cur_cpu_spec pointer. Signed-off-by: Stephen Rothwell -- Cheers, Stephen Rothwell sfr at canb.auug.org.au http://www.canb.auug.org.au/~sfr/ diff -ruNp linus/arch/ppc64/kernel/cputable.c linus-firmware.1/arch/ppc64/kernel/cputable.c --- linus/arch/ppc64/kernel/cputable.c 2005-07-15 14:37:43.000000000 +1000 +++ linus-firmware.1/arch/ppc64/kernel/cputable.c 2005-07-22 16:48:41.000000000 +1000 @@ -23,6 +23,7 @@ struct cpu_spec* cur_cpu_spec = NULL; EXPORT_SYMBOL(cur_cpu_spec); +unsigned long ppc64_firmware_features; /* NOTE: * Unlike ppc32, ppc64 will only call this once for the boot CPU, it's @@ -60,7 +61,6 @@ struct cpu_spec cpu_specs[] = { .icache_bsize = 128, .dcache_bsize = 128, .cpu_setup = __setup_cpu_power3, - .firmware_features = COMMON_PPC64_FW, }, { /* Power3+ */ .pvr_mask = 0xffff0000, @@ -73,7 +73,6 @@ struct cpu_spec cpu_specs[] = { .icache_bsize = 128, .dcache_bsize = 128, .cpu_setup = __setup_cpu_power3, - .firmware_features = COMMON_PPC64_FW, }, { /* Northstar */ .pvr_mask = 0xffff0000, @@ -86,7 +85,6 @@ struct cpu_spec cpu_specs[] = { .icache_bsize = 128, .dcache_bsize = 128, .cpu_setup = __setup_cpu_power3, - .firmware_features = COMMON_PPC64_FW, }, { /* Pulsar */ .pvr_mask = 0xffff0000, @@ -99,7 +97,6 @@ struct cpu_spec cpu_specs[] = { .icache_bsize = 128, .dcache_bsize = 128, .cpu_setup = __setup_cpu_power3, - .firmware_features = COMMON_PPC64_FW, }, { /* I-star */ .pvr_mask = 0xffff0000, @@ -112,7 +109,6 @@ struct cpu_spec cpu_specs[] = { .icache_bsize = 128, .dcache_bsize = 128, .cpu_setup = __setup_cpu_power3, - .firmware_features = COMMON_PPC64_FW, }, { /* S-star */ .pvr_mask = 0xffff0000, @@ -125,7 +121,6 @@ struct cpu_spec cpu_specs[] = { .icache_bsize = 128, .dcache_bsize = 128, .cpu_setup = __setup_cpu_power3, - .firmware_features = COMMON_PPC64_FW, }, { /* Power4 */ .pvr_mask = 0xffff0000, @@ -138,7 +133,6 @@ struct cpu_spec cpu_specs[] = { .icache_bsize = 128, .dcache_bsize = 128, .cpu_setup = __setup_cpu_power4, - .firmware_features = COMMON_PPC64_FW, }, { /* Power4+ */ .pvr_mask = 0xffff0000, @@ -151,7 +145,6 @@ struct cpu_spec cpu_specs[] = { .icache_bsize = 128, .dcache_bsize = 128, .cpu_setup = __setup_cpu_power4, - .firmware_features = COMMON_PPC64_FW, }, { /* PPC970 */ .pvr_mask = 0xffff0000, @@ -166,7 +159,6 @@ struct cpu_spec cpu_specs[] = { .icache_bsize = 128, .dcache_bsize = 128, .cpu_setup = __setup_cpu_ppc970, - .firmware_features = COMMON_PPC64_FW, }, { /* PPC970FX */ .pvr_mask = 0xffff0000, @@ -181,7 +173,6 @@ struct cpu_spec cpu_specs[] = { .icache_bsize = 128, .dcache_bsize = 128, .cpu_setup = __setup_cpu_ppc970, - .firmware_features = COMMON_PPC64_FW, }, { /* PPC970MP */ .pvr_mask = 0xffff0000, @@ -196,7 +187,6 @@ struct cpu_spec cpu_specs[] = { .icache_bsize = 128, .dcache_bsize = 128, .cpu_setup = __setup_cpu_ppc970, - .firmware_features = COMMON_PPC64_FW, }, { /* Power5 */ .pvr_mask = 0xffff0000, @@ -211,7 +201,6 @@ struct cpu_spec cpu_specs[] = { .icache_bsize = 128, .dcache_bsize = 128, .cpu_setup = __setup_cpu_power4, - .firmware_features = COMMON_PPC64_FW, }, { /* Power5 */ .pvr_mask = 0xffff0000, @@ -226,7 +215,6 @@ struct cpu_spec cpu_specs[] = { .icache_bsize = 128, .dcache_bsize = 128, .cpu_setup = __setup_cpu_power4, - .firmware_features = COMMON_PPC64_FW, }, { /* BE DD1.x */ .pvr_mask = 0xffff0000, @@ -241,7 +229,6 @@ struct cpu_spec cpu_specs[] = { .icache_bsize = 128, .dcache_bsize = 128, .cpu_setup = __setup_cpu_be, - .firmware_features = COMMON_PPC64_FW, }, { /* default match */ .pvr_mask = 0x00000000, @@ -254,7 +241,6 @@ struct cpu_spec cpu_specs[] = { .icache_bsize = 128, .dcache_bsize = 128, .cpu_setup = __setup_cpu_power4, - .firmware_features = COMMON_PPC64_FW, } }; diff -ruNp linus/arch/ppc64/kernel/lparcfg.c linus-firmware.1/arch/ppc64/kernel/lparcfg.c --- linus/arch/ppc64/kernel/lparcfg.c 2005-06-27 16:08:00.000000000 +1000 +++ linus-firmware.1/arch/ppc64/kernel/lparcfg.c 2005-07-22 16:38:40.000000000 +1000 @@ -377,7 +377,7 @@ static int lparcfg_data(struct seq_file partition_active_processors = lparcfg_count_active_processors(); - if (cur_cpu_spec->firmware_features & FW_FEATURE_SPLPAR) { + if (ppc64_firmware_features & FW_FEATURE_SPLPAR) { unsigned long h_entitled, h_unallocated; unsigned long h_aggregation, h_resource; unsigned long pool_idle_time, pool_procs; @@ -571,7 +571,7 @@ int __init lparcfg_init(void) mode_t mode = S_IRUSR; /* Allow writing if we have FW_FEATURE_SPLPAR */ - if (cur_cpu_spec->firmware_features & FW_FEATURE_SPLPAR) { + if (ppc64_firmware_features & FW_FEATURE_SPLPAR) { lparcfg_fops.write = lparcfg_write; mode |= S_IWUSR; } diff -ruNp linus/arch/ppc64/kernel/pSeries_iommu.c linus-firmware.1/arch/ppc64/kernel/pSeries_iommu.c --- linus/arch/ppc64/kernel/pSeries_iommu.c 2005-06-27 16:08:00.000000000 +1000 +++ linus-firmware.1/arch/ppc64/kernel/pSeries_iommu.c 2005-07-22 16:38:57.000000000 +1000 @@ -546,7 +546,7 @@ void iommu_init_early_pSeries(void) } if (systemcfg->platform & PLATFORM_LPAR) { - if (cur_cpu_spec->firmware_features & FW_FEATURE_MULTITCE) { + if (ppc64_firmware_features & FW_FEATURE_MULTITCE) { ppc_md.tce_build = tce_buildmulti_pSeriesLP; ppc_md.tce_free = tce_freemulti_pSeriesLP; } else { diff -ruNp linus/arch/ppc64/kernel/pSeries_setup.c linus-firmware.1/arch/ppc64/kernel/pSeries_setup.c --- linus/arch/ppc64/kernel/pSeries_setup.c 2005-07-08 15:18:27.000000000 +1000 +++ linus-firmware.1/arch/ppc64/kernel/pSeries_setup.c 2005-07-22 16:40:08.000000000 +1000 @@ -231,11 +231,11 @@ static void __init pSeries_setup_arch(vo pSeries_nvram_init(); - if (cur_cpu_spec->firmware_features & FW_FEATURE_SPLPAR) + if (ppc64_firmware_features & FW_FEATURE_SPLPAR) vpa_init(boot_cpuid); /* Choose an idle loop */ - if (cur_cpu_spec->firmware_features & FW_FEATURE_SPLPAR) { + if (ppc64_firmware_features & FW_FEATURE_SPLPAR) { if (get_paca()->lppaca.shared_proc) { printk(KERN_INFO "Using shared processor idle loop\n"); ppc_md.idle_loop = pseries_shared_idle; @@ -260,7 +260,7 @@ static int __init pSeries_init_panel(voi arch_initcall(pSeries_init_panel); -/* Build up the firmware_features bitmask field +/* Build up the ppc64_firmware_features bitmask field * using contents of device-tree/ibm,hypertas-functions. * Ultimately this functionality may be moved into prom.c prom_init(). */ @@ -272,7 +272,7 @@ void __init fw_feature_init(void) DBG(" -> fw_feature_init()\n"); - cur_cpu_spec->firmware_features = 0; + ppc64_firmware_features = 0; dn = of_find_node_by_path("/rtas"); if (dn == NULL) { printk(KERN_ERR "WARNING ! Cannot find RTAS in device-tree !\n"); @@ -288,7 +288,7 @@ void __init fw_feature_init(void) if ((firmware_features_table[i].name) && (strcmp(firmware_features_table[i].name,hypertas))==0) { /* we have a match */ - cur_cpu_spec->firmware_features |= + ppc64_firmware_features |= (firmware_features_table[i].val); break; } @@ -302,7 +302,7 @@ void __init fw_feature_init(void) of_node_put(dn); no_rtas: printk(KERN_INFO "firmware_features = 0x%lx\n", - cur_cpu_spec->firmware_features); + ppc64_firmware_features); DBG(" <- fw_feature_init()\n"); } diff -ruNp linus/arch/ppc64/kernel/pSeries_smp.c linus-firmware.1/arch/ppc64/kernel/pSeries_smp.c --- linus/arch/ppc64/kernel/pSeries_smp.c 2005-06-27 16:08:00.000000000 +1000 +++ linus-firmware.1/arch/ppc64/kernel/pSeries_smp.c 2005-07-22 16:40:18.000000000 +1000 @@ -326,7 +326,7 @@ static void __devinit smp_xics_setup_cpu if (cpu != boot_cpuid) xics_setup_cpu(); - if (cur_cpu_spec->firmware_features & FW_FEATURE_SPLPAR) + if (ppc64_firmware_features & FW_FEATURE_SPLPAR) vpa_init(cpu); cpu_clear(cpu, of_spin_map); diff -ruNp linus/arch/ppc64/kernel/process.c linus-firmware.1/arch/ppc64/kernel/process.c --- linus/arch/ppc64/kernel/process.c 2005-06-28 10:05:26.000000000 +1000 +++ linus-firmware.1/arch/ppc64/kernel/process.c 2005-07-22 16:40:26.000000000 +1000 @@ -206,7 +206,7 @@ struct task_struct *__switch_to(struct t /* purr is nothing but processor time base */ #if defined(CONFIG_PPC_PSERIES) - if (cur_cpu_spec->firmware_features & FW_FEATURE_SPLPAR) { + if (ppc64_firmware_features & FW_FEATURE_SPLPAR) { struct cpu_usage *cu = &__get_cpu_var(cpu_usage_array); long unsigned start_tb, current_tb; start_tb = old_thread->start_tb; diff -ruNp linus/arch/ppc64/kernel/sysfs.c linus-firmware.1/arch/ppc64/kernel/sysfs.c --- linus/arch/ppc64/kernel/sysfs.c 2005-07-08 15:18:27.000000000 +1000 +++ linus-firmware.1/arch/ppc64/kernel/sysfs.c 2005-07-22 16:40:34.000000000 +1000 @@ -154,7 +154,7 @@ void ppc64_enable_pmcs(void) #ifdef CONFIG_PPC_PSERIES /* instruct hypervisor to maintain PMCs */ - if (cur_cpu_spec->firmware_features & FW_FEATURE_SPLPAR) + if (ppc64_firmware_features & FW_FEATURE_SPLPAR) get_paca()->lppaca.pmcregs_in_use = 1; #endif /* CONFIG_PPC_PSERIES */ } diff -ruNp linus/arch/ppc64/kernel/time.c linus-firmware.1/arch/ppc64/kernel/time.c --- linus/arch/ppc64/kernel/time.c 2005-07-01 09:58:50.000000000 +1000 +++ linus-firmware.1/arch/ppc64/kernel/time.c 2005-07-22 16:40:43.000000000 +1000 @@ -372,7 +372,7 @@ int timer_interrupt(struct pt_regs * reg /* collect purr register values often, for accurate calculations */ #if defined(CONFIG_PPC_PSERIES) - if (cur_cpu_spec->firmware_features & FW_FEATURE_SPLPAR) { + if (ppc64_firmware_features & FW_FEATURE_SPLPAR) { struct cpu_usage *cu = &__get_cpu_var(cpu_usage_array); cu->current_tb = mfspr(SPRN_PURR); } diff -ruNp linus/include/asm-ppc64/cputable.h linus-firmware.1/include/asm-ppc64/cputable.h --- linus/include/asm-ppc64/cputable.h 2005-07-08 15:18:28.000000000 +1000 +++ linus-firmware.1/include/asm-ppc64/cputable.h 2005-07-22 16:42:23.000000000 +1000 @@ -56,11 +56,6 @@ struct cpu_spec { * BHT, SPD, etc... from head.S before branching to identify_machine */ cpu_setup_t cpu_setup; - - /* This is used to identify firmware features which are available - * to the kernel. - */ - unsigned long firmware_features; }; extern struct cpu_spec cpu_specs[]; @@ -72,6 +67,11 @@ static inline unsigned long cpu_has_feat } +/* This is used to identify firmware features which are available + * to the kernel. + */ +extern unsigned long ppc64_firmware_features; + /* firmware feature bitmask values */ #define FIRMWARE_MAX_FEATURES 63 From sfr at canb.auug.org.au Wed Aug 3 14:35:25 2005 From: sfr at canb.auug.org.au (Stephen Rothwell) Date: Wed, 3 Aug 2005 14:35:25 +1000 Subject: [PATCH] 2/4 create firmware_has_feature() In-Reply-To: <20050803142639.2bc38771.sfr@canb.auug.org.au> References: <20050803142639.2bc38771.sfr@canb.auug.org.au> Message-ID: <20050803143525.30f5582a.sfr@canb.auug.org.au> Create the firmware_has_feature() inline and move the firmware feature stuff into its own header file. Signed-off-by: Stephen Rothwell -- Cheers, Stephen Rothwell sfr at canb.auug.org.au http://www.canb.auug.org.au/~sfr/ diff -ruNp linus-firmware.1/arch/ppc64/kernel/cputable.c linus-firmware.2/arch/ppc64/kernel/cputable.c --- linus-firmware.1/arch/ppc64/kernel/cputable.c 2005-07-22 16:48:41.000000000 +1000 +++ linus-firmware.2/arch/ppc64/kernel/cputable.c 2005-07-22 17:09:21.000000000 +1000 @@ -20,6 +20,7 @@ #include #include +#include struct cpu_spec* cur_cpu_spec = NULL; EXPORT_SYMBOL(cur_cpu_spec); diff -ruNp linus-firmware.1/arch/ppc64/kernel/lparcfg.c linus-firmware.2/arch/ppc64/kernel/lparcfg.c --- linus-firmware.1/arch/ppc64/kernel/lparcfg.c 2005-07-22 16:38:40.000000000 +1000 +++ linus-firmware.2/arch/ppc64/kernel/lparcfg.c 2005-07-22 17:11:46.000000000 +1000 @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include #include #include @@ -377,7 +377,7 @@ static int lparcfg_data(struct seq_file partition_active_processors = lparcfg_count_active_processors(); - if (ppc64_firmware_features & FW_FEATURE_SPLPAR) { + if (firmware_has_feature(FW_FEATURE_SPLPAR)) { unsigned long h_entitled, h_unallocated; unsigned long h_aggregation, h_resource; unsigned long pool_idle_time, pool_procs; @@ -571,7 +571,7 @@ int __init lparcfg_init(void) mode_t mode = S_IRUSR; /* Allow writing if we have FW_FEATURE_SPLPAR */ - if (ppc64_firmware_features & FW_FEATURE_SPLPAR) { + if (firmware_has_feature(FW_FEATURE_SPLPAR)) { lparcfg_fops.write = lparcfg_write; mode |= S_IWUSR; } diff -ruNp linus-firmware.1/arch/ppc64/kernel/pSeries_iommu.c linus-firmware.2/arch/ppc64/kernel/pSeries_iommu.c --- linus-firmware.1/arch/ppc64/kernel/pSeries_iommu.c 2005-07-22 16:38:57.000000000 +1000 +++ linus-firmware.2/arch/ppc64/kernel/pSeries_iommu.c 2005-07-22 17:12:33.000000000 +1000 @@ -45,6 +45,7 @@ #include #include #include +#include #include "pci.h" #define DBG(fmt...) @@ -546,7 +547,7 @@ void iommu_init_early_pSeries(void) } if (systemcfg->platform & PLATFORM_LPAR) { - if (ppc64_firmware_features & FW_FEATURE_MULTITCE) { + if (firmware_has_feature(FW_FEATURE_MULTITCE)) { ppc_md.tce_build = tce_buildmulti_pSeriesLP; ppc_md.tce_free = tce_freemulti_pSeriesLP; } else { diff -ruNp linus-firmware.1/arch/ppc64/kernel/pSeries_setup.c linus-firmware.2/arch/ppc64/kernel/pSeries_setup.c --- linus-firmware.1/arch/ppc64/kernel/pSeries_setup.c 2005-07-22 16:40:08.000000000 +1000 +++ linus-firmware.2/arch/ppc64/kernel/pSeries_setup.c 2005-07-22 17:14:01.000000000 +1000 @@ -60,7 +60,7 @@ #include #include #include -#include +#include #include "i8259.h" #include "mpic.h" @@ -231,11 +231,11 @@ static void __init pSeries_setup_arch(vo pSeries_nvram_init(); - if (ppc64_firmware_features & FW_FEATURE_SPLPAR) + if (firmware_has_feature(FW_FEATURE_SPLPAR)) vpa_init(boot_cpuid); /* Choose an idle loop */ - if (ppc64_firmware_features & FW_FEATURE_SPLPAR) { + if (firmware_has_feature(FW_FEATURE_SPLPAR)) { if (get_paca()->lppaca.shared_proc) { printk(KERN_INFO "Using shared processor idle loop\n"); ppc_md.idle_loop = pseries_shared_idle; diff -ruNp linus-firmware.1/arch/ppc64/kernel/pSeries_smp.c linus-firmware.2/arch/ppc64/kernel/pSeries_smp.c --- linus-firmware.1/arch/ppc64/kernel/pSeries_smp.c 2005-07-22 16:40:18.000000000 +1000 +++ linus-firmware.2/arch/ppc64/kernel/pSeries_smp.c 2005-07-22 17:15:01.000000000 +1000 @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -326,7 +327,7 @@ static void __devinit smp_xics_setup_cpu if (cpu != boot_cpuid) xics_setup_cpu(); - if (ppc64_firmware_features & FW_FEATURE_SPLPAR) + if (firmware_has_feature(FW_FEATURE_SPLPAR)) vpa_init(cpu); cpu_clear(cpu, of_spin_map); diff -ruNp linus-firmware.1/arch/ppc64/kernel/process.c linus-firmware.2/arch/ppc64/kernel/process.c --- linus-firmware.1/arch/ppc64/kernel/process.c 2005-07-22 16:40:26.000000000 +1000 +++ linus-firmware.2/arch/ppc64/kernel/process.c 2005-07-22 17:15:35.000000000 +1000 @@ -50,6 +50,7 @@ #include #include #include +#include #include #include #include @@ -206,7 +207,7 @@ struct task_struct *__switch_to(struct t /* purr is nothing but processor time base */ #if defined(CONFIG_PPC_PSERIES) - if (ppc64_firmware_features & FW_FEATURE_SPLPAR) { + if (firmware_has_feature(FW_FEATURE_SPLPAR)) { struct cpu_usage *cu = &__get_cpu_var(cpu_usage_array); long unsigned start_tb, current_tb; start_tb = old_thread->start_tb; diff -ruNp linus-firmware.1/arch/ppc64/kernel/sysfs.c linus-firmware.2/arch/ppc64/kernel/sysfs.c --- linus-firmware.1/arch/ppc64/kernel/sysfs.c 2005-07-22 16:40:34.000000000 +1000 +++ linus-firmware.2/arch/ppc64/kernel/sysfs.c 2005-07-22 17:15:57.000000000 +1000 @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -154,7 +155,7 @@ void ppc64_enable_pmcs(void) #ifdef CONFIG_PPC_PSERIES /* instruct hypervisor to maintain PMCs */ - if (ppc64_firmware_features & FW_FEATURE_SPLPAR) + if (firmware_has_feature(FW_FEATURE_SPLPAR)) get_paca()->lppaca.pmcregs_in_use = 1; #endif /* CONFIG_PPC_PSERIES */ } diff -ruNp linus-firmware.1/arch/ppc64/kernel/time.c linus-firmware.2/arch/ppc64/kernel/time.c --- linus-firmware.1/arch/ppc64/kernel/time.c 2005-07-22 16:40:43.000000000 +1000 +++ linus-firmware.2/arch/ppc64/kernel/time.c 2005-07-22 17:16:40.000000000 +1000 @@ -67,6 +67,7 @@ #include #include #include +#include u64 jiffies_64 __cacheline_aligned_in_smp = INITIAL_JIFFIES; @@ -372,7 +373,7 @@ int timer_interrupt(struct pt_regs * reg /* collect purr register values often, for accurate calculations */ #if defined(CONFIG_PPC_PSERIES) - if (ppc64_firmware_features & FW_FEATURE_SPLPAR) { + if (firmware_has_feature(FW_FEATURE_SPLPAR)) { struct cpu_usage *cu = &__get_cpu_var(cpu_usage_array); cu->current_tb = mfspr(SPRN_PURR); } diff -ruNp linus-firmware.1/include/asm-ppc64/cputable.h linus-firmware.2/include/asm-ppc64/cputable.h --- linus-firmware.1/include/asm-ppc64/cputable.h 2005-07-22 16:42:23.000000000 +1000 +++ linus-firmware.2/include/asm-ppc64/cputable.h 2005-07-22 17:06:42.000000000 +1000 @@ -66,44 +66,6 @@ static inline unsigned long cpu_has_feat return cur_cpu_spec->cpu_features & feature; } - -/* This is used to identify firmware features which are available - * to the kernel. - */ -extern unsigned long ppc64_firmware_features; - -/* firmware feature bitmask values */ -#define FIRMWARE_MAX_FEATURES 63 - -#define FW_FEATURE_PFT (1UL<<0) -#define FW_FEATURE_TCE (1UL<<1) -#define FW_FEATURE_SPRG0 (1UL<<2) -#define FW_FEATURE_DABR (1UL<<3) -#define FW_FEATURE_COPY (1UL<<4) -#define FW_FEATURE_ASR (1UL<<5) -#define FW_FEATURE_DEBUG (1UL<<6) -#define FW_FEATURE_TERM (1UL<<7) -#define FW_FEATURE_PERF (1UL<<8) -#define FW_FEATURE_DUMP (1UL<<9) -#define FW_FEATURE_INTERRUPT (1UL<<10) -#define FW_FEATURE_MIGRATE (1UL<<11) -#define FW_FEATURE_PERFMON (1UL<<12) -#define FW_FEATURE_CRQ (1UL<<13) -#define FW_FEATURE_VIO (1UL<<14) -#define FW_FEATURE_RDMA (1UL<<15) -#define FW_FEATURE_LLAN (1UL<<16) -#define FW_FEATURE_BULK (1UL<<17) -#define FW_FEATURE_XDABR (1UL<<18) -#define FW_FEATURE_MULTITCE (1UL<<19) -#define FW_FEATURE_SPLPAR (1UL<<20) - -typedef struct { - unsigned long val; - char * name; -} firmware_feature_t; - -extern firmware_feature_t firmware_features_table[]; - #endif /* __ASSEMBLY__ */ /* CPU kernel features */ @@ -140,10 +102,8 @@ extern firmware_feature_t firmware_featu #define CPU_FTR_MMCRA_SIHV ASM_CONST(0x0000080000000000) #define CPU_FTR_CTRL ASM_CONST(0x0000100000000000) -/* Platform firmware features */ -#define FW_FTR_ ASM_CONST(0x0000000000000001) - #ifndef __ASSEMBLY__ + #define COMMON_USER_PPC64 (PPC_FEATURE_32 | PPC_FEATURE_64 | \ PPC_FEATURE_HAS_FPU | PPC_FEATURE_HAS_MMU) @@ -156,10 +116,9 @@ extern firmware_feature_t firmware_featu #define CPU_FTR_PPCAS_ARCH_V2 (CPU_FTR_PPCAS_ARCH_V2_BASE) #else #define CPU_FTR_PPCAS_ARCH_V2 (CPU_FTR_PPCAS_ARCH_V2_BASE | CPU_FTR_16M_PAGE) -#endif +#endif /* CONFIG_PPC_ISERIES */ -#define COMMON_PPC64_FW (0) -#endif +#endif /* __ASSEMBLY */ #ifdef __ASSEMBLY__ diff -ruNp linus-firmware.1/include/asm-ppc64/firmware.h linus-firmware.2/include/asm-ppc64/firmware.h --- linus-firmware.1/include/asm-ppc64/firmware.h 1970-01-01 10:00:00.000000000 +1000 +++ linus-firmware.2/include/asm-ppc64/firmware.h 2005-07-22 17:18:19.000000000 +1000 @@ -0,0 +1,67 @@ +/* + * include/asm-ppc64/firmware.h + * + * Extracted from include/asm-ppc64/cputable.h + * + * Copyright (C) 2001 Ben. Herrenschmidt (benh at kernel.crashing.org) + * + * Modifications for ppc64: + * Copyright (C) 2003 Dave Engebretsen + * + * 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. + */ +#ifndef __ASM_PPC_FIRMWARE_H +#define __ASM_PPC_FIRMWARE_H + +#ifdef __KERNEL__ + +#ifndef __ASSEMBLY__ + +/* firmware feature bitmask values */ +#define FIRMWARE_MAX_FEATURES 63 + +#define FW_FEATURE_PFT (1UL<<0) +#define FW_FEATURE_TCE (1UL<<1) +#define FW_FEATURE_SPRG0 (1UL<<2) +#define FW_FEATURE_DABR (1UL<<3) +#define FW_FEATURE_COPY (1UL<<4) +#define FW_FEATURE_ASR (1UL<<5) +#define FW_FEATURE_DEBUG (1UL<<6) +#define FW_FEATURE_TERM (1UL<<7) +#define FW_FEATURE_PERF (1UL<<8) +#define FW_FEATURE_DUMP (1UL<<9) +#define FW_FEATURE_INTERRUPT (1UL<<10) +#define FW_FEATURE_MIGRATE (1UL<<11) +#define FW_FEATURE_PERFMON (1UL<<12) +#define FW_FEATURE_CRQ (1UL<<13) +#define FW_FEATURE_VIO (1UL<<14) +#define FW_FEATURE_RDMA (1UL<<15) +#define FW_FEATURE_LLAN (1UL<<16) +#define FW_FEATURE_BULK (1UL<<17) +#define FW_FEATURE_XDABR (1UL<<18) +#define FW_FEATURE_MULTITCE (1UL<<19) +#define FW_FEATURE_SPLPAR (1UL<<20) + +/* This is used to identify firmware features which are available + * to the kernel. + */ +extern unsigned long ppc64_firmware_features; + +static inline unsigned long firmware_has_feature(unsigned long feature) +{ + return ppc64_firmware_features & feature; +} + +typedef struct { + unsigned long val; + char * name; +} firmware_feature_t; + +extern firmware_feature_t firmware_features_table[]; + +#endif /* __ASSEMBLY__ */ +#endif /* __KERNEL__ */ +#endif /* __ASM_PPC_FIRMWARE_H */ From sfr at canb.auug.org.au Wed Aug 3 14:40:16 2005 From: sfr at canb.auug.org.au (Stephen Rothwell) Date: Wed, 3 Aug 2005 14:40:16 +1000 Subject: [PATCH] 3/4 make firmware_has_feature() stronger In-Reply-To: <20050803142639.2bc38771.sfr@canb.auug.org.au> References: <20050803142639.2bc38771.sfr@canb.auug.org.au> Message-ID: <20050803144016.14f7964c.sfr@canb.auug.org.au> Make firmware_has_feature() evaluate at compile time for the non pSeries case and tidy up code where possible. Signed-off-by: Stephen Rothwell -- Cheers, Stephen Rothwell sfr at canb.auug.org.au http://www.canb.auug.org.au/~sfr/ diff -ruNp linus-firmware.2/arch/ppc64/kernel/Makefile linus-firmware.3/arch/ppc64/kernel/Makefile --- linus-firmware.2/arch/ppc64/kernel/Makefile 2005-06-27 16:08:00.000000000 +1000 +++ linus-firmware.3/arch/ppc64/kernel/Makefile 2005-07-22 17:42:16.000000000 +1000 @@ -11,7 +11,7 @@ obj-y := setup.o entry.o t udbg.o binfmt_elf32.o sys_ppc32.o ioctl32.o \ ptrace32.o signal32.o rtc.o init_task.o \ lmb.o cputable.o cpu_setup_power4.o idle_power4.o \ - iommu.o sysfs.o vdso.o pmc.o + iommu.o sysfs.o vdso.o pmc.o firmware.o obj-y += vdso32/ vdso64/ obj-$(CONFIG_PPC_OF) += of_device.o diff -ruNp linus-firmware.2/arch/ppc64/kernel/cputable.c linus-firmware.3/arch/ppc64/kernel/cputable.c --- linus-firmware.2/arch/ppc64/kernel/cputable.c 2005-07-22 17:09:21.000000000 +1000 +++ linus-firmware.3/arch/ppc64/kernel/cputable.c 2005-07-22 17:40:16.000000000 +1000 @@ -5,7 +5,7 @@ * * Modifications for ppc64: * Copyright (C) 2003 Dave Engebretsen - * + * * 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 @@ -20,11 +20,9 @@ #include #include -#include struct cpu_spec* cur_cpu_spec = NULL; EXPORT_SYMBOL(cur_cpu_spec); -unsigned long ppc64_firmware_features; /* NOTE: * Unlike ppc32, ppc64 will only call this once for the boot CPU, it's @@ -244,26 +242,3 @@ struct cpu_spec cpu_specs[] = { .cpu_setup = __setup_cpu_power4, } }; - -firmware_feature_t firmware_features_table[FIRMWARE_MAX_FEATURES] = { - {FW_FEATURE_PFT, "hcall-pft"}, - {FW_FEATURE_TCE, "hcall-tce"}, - {FW_FEATURE_SPRG0, "hcall-sprg0"}, - {FW_FEATURE_DABR, "hcall-dabr"}, - {FW_FEATURE_COPY, "hcall-copy"}, - {FW_FEATURE_ASR, "hcall-asr"}, - {FW_FEATURE_DEBUG, "hcall-debug"}, - {FW_FEATURE_PERF, "hcall-perf"}, - {FW_FEATURE_DUMP, "hcall-dump"}, - {FW_FEATURE_INTERRUPT, "hcall-interrupt"}, - {FW_FEATURE_MIGRATE, "hcall-migrate"}, - {FW_FEATURE_PERFMON, "hcall-perfmon"}, - {FW_FEATURE_CRQ, "hcall-crq"}, - {FW_FEATURE_VIO, "hcall-vio"}, - {FW_FEATURE_RDMA, "hcall-rdma"}, - {FW_FEATURE_LLAN, "hcall-lLAN"}, - {FW_FEATURE_BULK, "hcall-bulk"}, - {FW_FEATURE_XDABR, "hcall-xdabr"}, - {FW_FEATURE_MULTITCE, "hcall-multi-tce"}, - {FW_FEATURE_SPLPAR, "hcall-splpar"}, -}; diff -ruNp linus-firmware.2/arch/ppc64/kernel/firmware.c linus-firmware.3/arch/ppc64/kernel/firmware.c --- linus-firmware.2/arch/ppc64/kernel/firmware.c 1970-01-01 10:00:00.000000000 +1000 +++ linus-firmware.3/arch/ppc64/kernel/firmware.c 2005-07-22 17:42:01.000000000 +1000 @@ -0,0 +1,47 @@ +/* + * arch/ppc64/kernel/firmware.c + * + * Extracted from cputable.c + * + * Copyright (C) 2001 Ben. Herrenschmidt (benh at kernel.crashing.org) + * + * Modifications for ppc64: + * Copyright (C) 2003 Dave Engebretsen + * Copyright (C) 2005 Stephen Rothwell, IBM Corporation + * + * 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 + +#include + +unsigned long ppc64_firmware_features; + +#ifdef CONFIG_PPC_PSERIES +firmware_feature_t firmware_features_table[FIRMWARE_MAX_FEATURES] = { + {FW_FEATURE_PFT, "hcall-pft"}, + {FW_FEATURE_TCE, "hcall-tce"}, + {FW_FEATURE_SPRG0, "hcall-sprg0"}, + {FW_FEATURE_DABR, "hcall-dabr"}, + {FW_FEATURE_COPY, "hcall-copy"}, + {FW_FEATURE_ASR, "hcall-asr"}, + {FW_FEATURE_DEBUG, "hcall-debug"}, + {FW_FEATURE_PERF, "hcall-perf"}, + {FW_FEATURE_DUMP, "hcall-dump"}, + {FW_FEATURE_INTERRUPT, "hcall-interrupt"}, + {FW_FEATURE_MIGRATE, "hcall-migrate"}, + {FW_FEATURE_PERFMON, "hcall-perfmon"}, + {FW_FEATURE_CRQ, "hcall-crq"}, + {FW_FEATURE_VIO, "hcall-vio"}, + {FW_FEATURE_RDMA, "hcall-rdma"}, + {FW_FEATURE_LLAN, "hcall-lLAN"}, + {FW_FEATURE_BULK, "hcall-bulk"}, + {FW_FEATURE_XDABR, "hcall-xdabr"}, + {FW_FEATURE_MULTITCE, "hcall-multi-tce"}, + {FW_FEATURE_SPLPAR, "hcall-splpar"}, +}; +#endif diff -ruNp linus-firmware.2/arch/ppc64/kernel/pSeries_setup.c linus-firmware.3/arch/ppc64/kernel/pSeries_setup.c --- linus-firmware.2/arch/ppc64/kernel/pSeries_setup.c 2005-07-22 17:14:01.000000000 +1000 +++ linus-firmware.3/arch/ppc64/kernel/pSeries_setup.c 2005-07-22 17:23:23.000000000 +1000 @@ -231,11 +231,9 @@ static void __init pSeries_setup_arch(vo pSeries_nvram_init(); - if (firmware_has_feature(FW_FEATURE_SPLPAR)) - vpa_init(boot_cpuid); - /* Choose an idle loop */ if (firmware_has_feature(FW_FEATURE_SPLPAR)) { + vpa_init(boot_cpuid); if (get_paca()->lppaca.shared_proc) { printk(KERN_INFO "Using shared processor idle loop\n"); ppc_md.idle_loop = pseries_shared_idle; diff -ruNp linus-firmware.2/arch/ppc64/kernel/process.c linus-firmware.3/arch/ppc64/kernel/process.c --- linus-firmware.2/arch/ppc64/kernel/process.c 2005-07-22 17:15:35.000000000 +1000 +++ linus-firmware.3/arch/ppc64/kernel/process.c 2005-07-22 17:24:53.000000000 +1000 @@ -203,10 +203,9 @@ struct task_struct *__switch_to(struct t new_thread = &new->thread; old_thread = ¤t->thread; -/* Collect purr utilization data per process and per processor wise */ -/* purr is nothing but processor time base */ - -#if defined(CONFIG_PPC_PSERIES) + /* Collect purr utilization data per process and per processor + * wise purr is nothing but processor time base + */ if (firmware_has_feature(FW_FEATURE_SPLPAR)) { struct cpu_usage *cu = &__get_cpu_var(cpu_usage_array); long unsigned start_tb, current_tb; @@ -215,8 +214,6 @@ struct task_struct *__switch_to(struct t old_thread->accum_tb += (current_tb - start_tb); new_thread->start_tb = current_tb; } -#endif - local_irq_save(flags); last = _switch(old_thread, new_thread); diff -ruNp linus-firmware.2/arch/ppc64/kernel/sysfs.c linus-firmware.3/arch/ppc64/kernel/sysfs.c --- linus-firmware.2/arch/ppc64/kernel/sysfs.c 2005-07-22 17:15:57.000000000 +1000 +++ linus-firmware.3/arch/ppc64/kernel/sysfs.c 2005-07-22 17:25:24.000000000 +1000 @@ -153,11 +153,9 @@ void ppc64_enable_pmcs(void) break; } -#ifdef CONFIG_PPC_PSERIES /* instruct hypervisor to maintain PMCs */ if (firmware_has_feature(FW_FEATURE_SPLPAR)) get_paca()->lppaca.pmcregs_in_use = 1; -#endif /* CONFIG_PPC_PSERIES */ } #else diff -ruNp linus-firmware.2/arch/ppc64/kernel/time.c linus-firmware.3/arch/ppc64/kernel/time.c --- linus-firmware.2/arch/ppc64/kernel/time.c 2005-07-22 17:16:40.000000000 +1000 +++ linus-firmware.3/arch/ppc64/kernel/time.c 2005-07-22 17:25:50.000000000 +1000 @@ -371,13 +371,11 @@ int timer_interrupt(struct pt_regs * reg process_hvlpevents(regs); #endif -/* collect purr register values often, for accurate calculations */ -#if defined(CONFIG_PPC_PSERIES) + /* collect purr register values often, for accurate calculations */ if (firmware_has_feature(FW_FEATURE_SPLPAR)) { struct cpu_usage *cu = &__get_cpu_var(cpu_usage_array); cu->current_tb = mfspr(SPRN_PURR); } -#endif irq_exit(); diff -ruNp linus-firmware.2/include/asm-ppc64/firmware.h linus-firmware.3/include/asm-ppc64/firmware.h --- linus-firmware.2/include/asm-ppc64/firmware.h 2005-07-22 17:18:19.000000000 +1000 +++ linus-firmware.3/include/asm-ppc64/firmware.h 2005-07-22 17:31:12.000000000 +1000 @@ -45,6 +45,22 @@ #define FW_FEATURE_MULTITCE (1UL<<19) #define FW_FEATURE_SPLPAR (1UL<<20) +enum { + FW_FEATURE_PSERIES = FW_FEATURE_PFT | FW_FEATURE_TCE | + FW_FEATURE_SPRG0 | FW_FEATURE_DABR | FW_FEATURE_COPY | + FW_FEATURE_ASR | FW_FEATURE_DEBUG | FW_FEATURE_TERM | + FW_FEATURE_PERF | FW_FEATURE_DUMP | FW_FEATURE_INTERRUPT | + FW_FEATURE_MIGRATE | FW_FEATURE_PERFMON | FW_FEATURE_CRQ | + FW_FEATURE_VIO | FW_FEATURE_RDMA | FW_FEATURE_LLAN | + FW_FEATURE_BULK | FW_FEATURE_XDABR | FW_FEATURE_MULTITCE | + FW_FEATURE_SPLPAR, + FW_FEATURE_POSSIBLE = +#ifdef CONFIG_PPC_PSERIES + FW_FEATURE_PSERIES | +#endif + 0, +}; + /* This is used to identify firmware features which are available * to the kernel. */ @@ -52,15 +68,17 @@ extern unsigned long ppc64_firmware_feat static inline unsigned long firmware_has_feature(unsigned long feature) { - return ppc64_firmware_features & feature; + return ppc64_firmware_features & feature & FW_FEATURE_POSSIBLE; } +#ifdef CONFIG_PPC_PSERIES typedef struct { unsigned long val; char * name; } firmware_feature_t; extern firmware_feature_t firmware_features_table[]; +#endif #endif /* __ASSEMBLY__ */ #endif /* __KERNEL__ */ From sfr at canb.auug.org.au Wed Aug 3 14:43:21 2005 From: sfr at canb.auug.org.au (Stephen Rothwell) Date: Wed, 3 Aug 2005 14:43:21 +1000 Subject: [PATCH] 4/4 introduce FW_FEATURE_ISERIES In-Reply-To: <20050803142639.2bc38771.sfr@canb.auug.org.au> References: <20050803142639.2bc38771.sfr@canb.auug.org.au> Message-ID: <20050803144321.59b9f8d2.sfr@canb.auug.org.au> Signed-off-by: Stephen Rothwell -- Cheers, Stephen Rothwell sfr at canb.auug.org.au http://www.canb.auug.org.au/~sfr/ diff -ruNp linus-firmware.3/arch/ppc64/kernel/iSeries_setup.c linus-firmware.4/arch/ppc64/kernel/iSeries_setup.c --- linus-firmware.3/arch/ppc64/kernel/iSeries_setup.c 2005-07-15 14:37:43.000000000 +1000 +++ linus-firmware.4/arch/ppc64/kernel/iSeries_setup.c 2005-07-22 18:34:11.000000000 +1000 @@ -39,6 +39,7 @@ #include #include #include +#include #include #include "iSeries_setup.h" @@ -314,6 +315,8 @@ static void __init iSeries_init_early(vo DBG(" -> iSeries_init_early()\n"); + ppc64_firmware_features = FW_FEATURE_ISERIES; + ppcdbg_initialize(); #if defined(CONFIG_BLK_DEV_INITRD) diff -ruNp linus-firmware.3/arch/ppc64/kernel/pSeries_lpar.c linus-firmware.4/arch/ppc64/kernel/pSeries_lpar.c --- linus-firmware.3/arch/ppc64/kernel/pSeries_lpar.c 2005-07-15 14:37:43.000000000 +1000 +++ linus-firmware.4/arch/ppc64/kernel/pSeries_lpar.c 2005-07-22 18:17:24.000000000 +1000 @@ -52,7 +52,6 @@ EXPORT_SYMBOL(plpar_hcall_4out); EXPORT_SYMBOL(plpar_hcall_norets); EXPORT_SYMBOL(plpar_hcall_8arg_2ret); -extern void fw_feature_init(void); extern void pSeries_find_serial_port(void); diff -ruNp linus-firmware.3/arch/ppc64/kernel/pSeries_setup.c linus-firmware.4/arch/ppc64/kernel/pSeries_setup.c --- linus-firmware.3/arch/ppc64/kernel/pSeries_setup.c 2005-07-22 17:23:23.000000000 +1000 +++ linus-firmware.4/arch/ppc64/kernel/pSeries_setup.c 2005-07-22 18:20:38.000000000 +1000 @@ -262,7 +262,7 @@ arch_initcall(pSeries_init_panel); * using contents of device-tree/ibm,hypertas-functions. * Ultimately this functionality may be moved into prom.c prom_init(). */ -void __init fw_feature_init(void) +static void __init fw_feature_init(void) { struct device_node * dn; char * hypertas; diff -ruNp linus-firmware.3/include/asm-ppc64/firmware.h linus-firmware.4/include/asm-ppc64/firmware.h --- linus-firmware.3/include/asm-ppc64/firmware.h 2005-07-22 17:31:12.000000000 +1000 +++ linus-firmware.4/include/asm-ppc64/firmware.h 2005-07-22 18:35:35.000000000 +1000 @@ -44,9 +44,10 @@ #define FW_FEATURE_XDABR (1UL<<18) #define FW_FEATURE_MULTITCE (1UL<<19) #define FW_FEATURE_SPLPAR (1UL<<20) +#define FW_FEATURE_ISERIES (1UL<<21) enum { - FW_FEATURE_PSERIES = FW_FEATURE_PFT | FW_FEATURE_TCE | + FW_FEATURE_PSERIES_POSSIBLE = FW_FEATURE_PFT | FW_FEATURE_TCE | FW_FEATURE_SPRG0 | FW_FEATURE_DABR | FW_FEATURE_COPY | FW_FEATURE_ASR | FW_FEATURE_DEBUG | FW_FEATURE_TERM | FW_FEATURE_PERF | FW_FEATURE_DUMP | FW_FEATURE_INTERRUPT | @@ -54,11 +55,25 @@ enum { FW_FEATURE_VIO | FW_FEATURE_RDMA | FW_FEATURE_LLAN | FW_FEATURE_BULK | FW_FEATURE_XDABR | FW_FEATURE_MULTITCE | FW_FEATURE_SPLPAR, + FW_FEATURE_PSERIES_ALWAYS = 0, + FW_FEATURE_ISERIES_POSSIBLE = FW_FEATURE_ISERIES, + FW_FEATURE_ISERIES_ALWAYS = FW_FEATURE_ISERIES, FW_FEATURE_POSSIBLE = #ifdef CONFIG_PPC_PSERIES - FW_FEATURE_PSERIES | + FW_FEATURE_PSERIES_POSSIBLE | +#endif +#ifdef CONFIG_PPC_ISERIES + FW_FEATURE_ISERIES_POSSIBLE | #endif 0, + FW_FEATURE_ALWAYS = +#ifdef CONFIG_PPC_PSERIES + FW_FEATURE_PSERIES_ALWAYS & +#endif +#ifdef CONFIG_PPC_ISERIES + FW_FEATURE_ISERIES_ALWAYS & +#endif + FW_FEATURE_POSSIBLE, }; /* This is used to identify firmware features which are available @@ -68,7 +83,8 @@ extern unsigned long ppc64_firmware_feat static inline unsigned long firmware_has_feature(unsigned long feature) { - return ppc64_firmware_features & feature & FW_FEATURE_POSSIBLE; + return (FW_FEATURE_ALWAYS & feature) || + (FW_FEATURE_POSSIBLE & ppc64_firmware_features & feature); } #ifdef CONFIG_PPC_PSERIES From michael at ellerman.id.au Wed Aug 3 20:21:22 2005 From: michael at ellerman.id.au (Michael Ellerman) Date: Wed, 3 Aug 2005 20:21:22 +1000 (EST) Subject: [PATCH 0/10] Cleanup iSeries msChunks handling, and lmb code. Message-ID: <1123064479.417492.649639846705.qpatch@concordia> This series of patches cleans up the iSeries msChunks structure, and associated macros and functions. It also removes CONFIG_MSCHUNKS from the lmb code, and eventually removes CONFIG_MSCHUNKS entirely. The final patch rely's on Stephen's FW_FEATURE_ISERIES patches. Booted on Power3, G5, Power5 LPAR and iSeries. From michael at ellerman.id.au Wed Aug 3 20:21:23 2005 From: michael at ellerman.id.au (Michael Ellerman) Date: Wed, 3 Aug 2005 20:21:23 +1000 (EST) Subject: [PATCH 1/10] ppc64: Remove PTRRELOC() from msChunks code In-Reply-To: <1123064479.417492.649639846705.qpatch@concordia> Message-ID: <20050803102123.56F3467E87@ozlabs.org> The msChunks code was written to work on pSeries, but now it's only used on iSeries. This means there's no need to do PTRRELOC anymore, so remove it all. A few places were getting "extern reloc_offset()" from abs_addr.h, move it into system.h instead. Signed-off-by: Michael Ellerman arch/ppc64/kernel/LparData.c | 10 +--------- include/asm-ppc64/abs_addr.h | 36 ++++++++++-------------------------- include/asm-ppc64/system.h | 2 ++ 3 files changed, 13 insertions(+), 35 deletions(-) Index: work/include/asm-ppc64/abs_addr.h =================================================================== --- work.orig/include/asm-ppc64/abs_addr.h +++ work/include/asm-ppc64/abs_addr.h @@ -29,46 +29,30 @@ struct msChunks { extern struct msChunks msChunks; extern unsigned long msChunks_alloc(unsigned long, unsigned long, unsigned long); -extern unsigned long reloc_offset(void); #ifdef CONFIG_MSCHUNKS -static inline unsigned long -chunk_to_addr(unsigned long chunk) +static inline unsigned long chunk_to_addr(unsigned long chunk) { - unsigned long offset = reloc_offset(); - struct msChunks *_msChunks = PTRRELOC(&msChunks); - - return chunk << _msChunks->chunk_shift; + return chunk << msChunks.chunk_shift; } -static inline unsigned long -addr_to_chunk(unsigned long addr) +static inline unsigned long addr_to_chunk(unsigned long addr) { - unsigned long offset = reloc_offset(); - struct msChunks *_msChunks = PTRRELOC(&msChunks); - - return addr >> _msChunks->chunk_shift; + return addr >> msChunks.chunk_shift; } -static inline unsigned long -chunk_offset(unsigned long addr) +static inline unsigned long chunk_offset(unsigned long addr) { - unsigned long offset = reloc_offset(); - struct msChunks *_msChunks = PTRRELOC(&msChunks); - - return addr & _msChunks->chunk_mask; + return addr & msChunks.chunk_mask; } -static inline unsigned long -abs_chunk(unsigned long pchunk) +static inline unsigned long abs_chunk(unsigned long pchunk) { - unsigned long offset = reloc_offset(); - struct msChunks *_msChunks = PTRRELOC(&msChunks); - if ( pchunk >= _msChunks->num_chunks ) { + if (pchunk >= msChunks.num_chunks) return pchunk; - } - return PTRRELOC(_msChunks->abs)[pchunk]; + + return msChunks.abs[pchunk]; } /* A macro so it can take pointers or unsigned long. */ Index: work/arch/ppc64/kernel/LparData.c =================================================================== --- work.orig/arch/ppc64/kernel/LparData.c +++ work/arch/ppc64/kernel/LparData.c @@ -295,24 +295,16 @@ struct ItVpdAreas itVpdAreas = { struct msChunks msChunks; EXPORT_SYMBOL(msChunks); -/* Depending on whether this is called from iSeries or pSeries setup - * code, the location of the msChunks struct may or may not have - * to be reloc'd, so we force the caller to do that for us by passing - * in a pointer to the structure. - */ unsigned long msChunks_alloc(unsigned long mem, unsigned long num_chunks, unsigned long chunk_size) { - unsigned long offset = reloc_offset(); - struct msChunks *_msChunks = PTRRELOC(&msChunks); - _msChunks->num_chunks = num_chunks; _msChunks->chunk_size = chunk_size; _msChunks->chunk_shift = __ilog2(chunk_size); _msChunks->chunk_mask = (1UL<<_msChunks->chunk_shift)-1; mem = _ALIGN(mem, sizeof(msChunks_entry)); - _msChunks->abs = (msChunks_entry *)(mem + offset); + _msChunks->abs = (msChunks_entry *)mem; mem += num_chunks * sizeof(msChunks_entry); return mem; Index: work/include/asm-ppc64/system.h =================================================================== --- work.orig/include/asm-ppc64/system.h +++ work/include/asm-ppc64/system.h @@ -302,5 +302,7 @@ __cmpxchg(volatile void *ptr, unsigned l #define arch_align_stack(x) (x) +extern unsigned long reloc_offset(void); + #endif /* __KERNEL__ */ #endif From michael at ellerman.id.au Wed Aug 3 20:21:23 2005 From: michael at ellerman.id.au (Michael Ellerman) Date: Wed, 3 Aug 2005 20:21:23 +1000 (EST) Subject: [PATCH 2/10] ppc64: msChunks cleanups In-Reply-To: <1123064479.417492.649639846705.qpatch@concordia> Message-ID: <20050803102123.81CB367E87@ozlabs.org> Chunks are 256KB, so use constants for the size/shift/mask, rather than getting them from the msChunks struct. The iSeries debugger (??) might still need access to the values in the msChunks struct, so we keep them around for now, but set them from the constant values. Replace msChunks_entry typedef with regular u32. Simplify msChunks_alloc() to manipulate klimit directly, rather than via a parameter. Move msChunks_alloc() and msChunks into iSeries_setup.c, as that's where they're used. Signed-off-by: Michael Ellerman arch/ppc64/kernel/LparData.c | 18 ------------------ arch/ppc64/kernel/iSeries_setup.c | 20 ++++++++++++++++++-- include/asm-ppc64/abs_addr.h | 15 +++++++++------ 3 files changed, 27 insertions(+), 26 deletions(-) Index: work/include/asm-ppc64/abs_addr.h =================================================================== --- work.orig/include/asm-ppc64/abs_addr.h +++ work/include/asm-ppc64/abs_addr.h @@ -17,34 +17,37 @@ #include #include -typedef u32 msChunks_entry; struct msChunks { unsigned long num_chunks; unsigned long chunk_size; unsigned long chunk_shift; unsigned long chunk_mask; - msChunks_entry *abs; + u32 *abs; }; extern struct msChunks msChunks; -extern unsigned long msChunks_alloc(unsigned long, unsigned long, unsigned long); #ifdef CONFIG_MSCHUNKS +/* Chunks are 256 KB */ +#define MSCHUNKS_CHUNK_SHIFT (18) +#define MSCHUNKS_CHUNK_SIZE (1UL << MSCHUNKS_CHUNK_SHIFT) +#define MSCHUNKS_OFFSET_MASK (MSCHUNKS_CHUNK_SIZE - 1) + static inline unsigned long chunk_to_addr(unsigned long chunk) { - return chunk << msChunks.chunk_shift; + return chunk << MSCHUNKS_CHUNK_SHIFT; } static inline unsigned long addr_to_chunk(unsigned long addr) { - return addr >> msChunks.chunk_shift; + return addr >> MSCHUNKS_CHUNK_SHIFT; } static inline unsigned long chunk_offset(unsigned long addr) { - return addr & msChunks.chunk_mask; + return addr & MSCHUNKS_OFFSET_MASK; } static inline unsigned long abs_chunk(unsigned long pchunk) Index: work/arch/ppc64/kernel/iSeries_setup.c =================================================================== --- work.orig/arch/ppc64/kernel/iSeries_setup.c +++ work/arch/ppc64/kernel/iSeries_setup.c @@ -412,6 +412,22 @@ static void __init iSeries_init_early(vo DBG(" <- iSeries_init_early()\n"); } +struct msChunks msChunks = { + /* XXX We don't use these, but Piranha might need them. */ + .chunk_size = MSCHUNKS_CHUNK_SIZE, + .chunk_shift = MSCHUNKS_CHUNK_SHIFT, + .chunk_mask = MSCHUNKS_OFFSET_MASK, +}; +EXPORT_SYMBOL(msChunks); + +void msChunks_alloc(unsigned long num_chunks) +{ + klimit = _ALIGN(klimit, sizeof(u32)); + msChunks.abs = (u32 *)klimit; + klimit += num_chunks * sizeof(u32); + msChunks.num_chunks = num_chunks; +} + /* * The iSeries may have very large memories ( > 128 GB ) and a partition * may get memory in "chunks" that may be anywhere in the 2**52 real @@ -449,7 +465,7 @@ static void __init build_iSeries_Memory_ /* Chunk size on iSeries is 256K bytes */ totalChunks = (u32)HvLpConfig_getMsChunks(); - klimit = msChunks_alloc(klimit, totalChunks, 1UL << 18); + msChunks_alloc(totalChunks); /* * Get absolute address of our load area @@ -495,7 +511,7 @@ static void __init build_iSeries_Memory_ */ hptFirstChunk = (u32)addr_to_chunk(HvCallHpt_getHptAddress()); hptSizePages = (u32)HvCallHpt_getHptPages(); - hptSizeChunks = hptSizePages >> (msChunks.chunk_shift - PAGE_SHIFT); + hptSizeChunks = hptSizePages >> (MSCHUNKS_CHUNK_SHIFT - PAGE_SHIFT); hptLastChunk = hptFirstChunk + hptSizeChunks - 1; printk("HPT absolute addr = %016lx, size = %dK\n", Index: work/arch/ppc64/kernel/LparData.c =================================================================== --- work.orig/arch/ppc64/kernel/LparData.c +++ work/arch/ppc64/kernel/LparData.c @@ -291,21 +291,3 @@ struct ItVpdAreas itVpdAreas = { 0,0 } }; - -struct msChunks msChunks; -EXPORT_SYMBOL(msChunks); - -unsigned long -msChunks_alloc(unsigned long mem, unsigned long num_chunks, unsigned long chunk_size) -{ - _msChunks->num_chunks = num_chunks; - _msChunks->chunk_size = chunk_size; - _msChunks->chunk_shift = __ilog2(chunk_size); - _msChunks->chunk_mask = (1UL<<_msChunks->chunk_shift)-1; - - mem = _ALIGN(mem, sizeof(msChunks_entry)); - _msChunks->abs = (msChunks_entry *)mem; - mem += num_chunks * sizeof(msChunks_entry); - - return mem; -} From michael at ellerman.id.au Wed Aug 3 20:21:23 2005 From: michael at ellerman.id.au (Michael Ellerman) Date: Wed, 3 Aug 2005 20:21:23 +1000 (EST) Subject: [PATCH 3/10] ppc64: Rename msChunks structure In-Reply-To: <1123064479.417492.649639846705.qpatch@concordia> Message-ID: <20050803102123.B23FD67E87@ozlabs.org> Rename the msChunks struct to get rid of the StUdlY caps and make it a bit clearer what it's for. Signed-off-by: Michael Ellerman arch/ppc64/kernel/head.S | 4 ++-- arch/ppc64/kernel/iSeries_setup.c | 17 +++++++++-------- include/asm-ppc64/abs_addr.h | 15 +++++++-------- 3 files changed, 18 insertions(+), 18 deletions(-) Index: work/arch/ppc64/kernel/iSeries_setup.c =================================================================== --- work.orig/arch/ppc64/kernel/iSeries_setup.c +++ work/arch/ppc64/kernel/iSeries_setup.c @@ -412,20 +412,20 @@ static void __init iSeries_init_early(vo DBG(" <- iSeries_init_early()\n"); } -struct msChunks msChunks = { +struct mschunks_map mschunks_map = { /* XXX We don't use these, but Piranha might need them. */ .chunk_size = MSCHUNKS_CHUNK_SIZE, .chunk_shift = MSCHUNKS_CHUNK_SHIFT, .chunk_mask = MSCHUNKS_OFFSET_MASK, }; -EXPORT_SYMBOL(msChunks); +EXPORT_SYMBOL(mschunks_map); -void msChunks_alloc(unsigned long num_chunks) +void mschunks_alloc(unsigned long num_chunks) { klimit = _ALIGN(klimit, sizeof(u32)); - msChunks.abs = (u32 *)klimit; + mschunks_map.mapping = (u32 *)klimit; klimit += num_chunks * sizeof(u32); - msChunks.num_chunks = num_chunks; + mschunks_map.num_chunks = num_chunks; } /* @@ -465,7 +465,7 @@ static void __init build_iSeries_Memory_ /* Chunk size on iSeries is 256K bytes */ totalChunks = (u32)HvLpConfig_getMsChunks(); - msChunks_alloc(totalChunks); + mschunks_alloc(totalChunks); /* * Get absolute address of our load area @@ -502,7 +502,7 @@ static void __init build_iSeries_Memory_ printk("Load area size %dK\n", loadAreaSize * 256); for (nextPhysChunk = 0; nextPhysChunk < loadAreaSize; ++nextPhysChunk) - msChunks.abs[nextPhysChunk] = + mschunks_map.mapping[nextPhysChunk] = loadAreaFirstChunk + nextPhysChunk; /* @@ -568,7 +568,8 @@ static void __init build_iSeries_Memory_ (absChunk > hptLastChunk)) && ((absChunk < loadAreaFirstChunk) || (absChunk > loadAreaLastChunk))) { - msChunks.abs[nextPhysChunk] = absChunk; + mschunks_map.mapping[nextPhysChunk] = + absChunk; ++nextPhysChunk; } } Index: work/include/asm-ppc64/abs_addr.h =================================================================== --- work.orig/include/asm-ppc64/abs_addr.h +++ work/include/asm-ppc64/abs_addr.h @@ -17,18 +17,17 @@ #include #include -struct msChunks { +#ifdef CONFIG_MSCHUNKS + +struct mschunks_map { unsigned long num_chunks; unsigned long chunk_size; unsigned long chunk_shift; unsigned long chunk_mask; - u32 *abs; + u32 *mapping; }; -extern struct msChunks msChunks; - - -#ifdef CONFIG_MSCHUNKS +extern struct mschunks_map mschunks_map; /* Chunks are 256 KB */ #define MSCHUNKS_CHUNK_SHIFT (18) @@ -52,10 +51,10 @@ static inline unsigned long chunk_offset static inline unsigned long abs_chunk(unsigned long pchunk) { - if (pchunk >= msChunks.num_chunks) + if (pchunk >= mschunks_map.num_chunks) return pchunk; - return msChunks.abs[pchunk]; + return mschunks_map.mapping[pchunk]; } /* A macro so it can take pointers or unsigned long. */ Index: work/arch/ppc64/kernel/head.S =================================================================== --- work.orig/arch/ppc64/kernel/head.S +++ work/arch/ppc64/kernel/head.S @@ -102,12 +102,12 @@ END_FTR_SECTION(0, 1) .llong hvReleaseData-KERNELBASE /* - * At offset 0x28 and 0x30 are offsets to the msChunks + * At offset 0x28 and 0x30 are offsets to the mschunks_map * array (used by the iSeries LPAR debugger to do translation * between physical addresses and absolute addresses) and * to the pidhash table (also used by the debugger) */ - .llong msChunks-KERNELBASE + .llong mschunks_map-KERNELBASE .llong 0 /* pidhash-KERNELBASE SFRXXX */ /* Offset 0x38 - Pointer to start of embedded System.map */ From michael at ellerman.id.au Wed Aug 3 20:21:23 2005 From: michael at ellerman.id.au (Michael Ellerman) Date: Wed, 3 Aug 2005 20:21:23 +1000 (EST) Subject: [PATCH 4/10] ppc64: Consolidate some macros In-Reply-To: <1123064479.417492.649639846705.qpatch@concordia> Message-ID: <20050803102123.42BAA67E87@ozlabs.org> The only caller of chunk_offset() and abs_chunk() is phys_to_abs(), so fold the former two into the latter. Signed-off-by: Michael Ellerman include/asm-ppc64/abs_addr.h | 21 +++++++-------------- 1 files changed, 7 insertions(+), 14 deletions(-) Index: work/include/asm-ppc64/abs_addr.h =================================================================== --- work.orig/include/asm-ppc64/abs_addr.h +++ work/include/asm-ppc64/abs_addr.h @@ -44,24 +44,17 @@ static inline unsigned long addr_to_chun return addr >> MSCHUNKS_CHUNK_SHIFT; } -static inline unsigned long chunk_offset(unsigned long addr) +static inline unsigned long phys_to_abs(unsigned long pa) { - return addr & MSCHUNKS_OFFSET_MASK; -} + unsigned long chunk; -static inline unsigned long abs_chunk(unsigned long pchunk) -{ - if (pchunk >= mschunks_map.num_chunks) - return pchunk; + chunk = addr_to_chunk(pa); - return mschunks_map.mapping[pchunk]; -} + if (chunk < mschunks_map.num_chunks) + chunk = mschunks_map.mapping[chunk]; -/* A macro so it can take pointers or unsigned long. */ -#define phys_to_abs(pa) \ - ({ unsigned long _pa = (unsigned long)(pa); \ - chunk_to_addr(abs_chunk(addr_to_chunk(_pa))) + chunk_offset(_pa); \ - }) + return chunk_to_addr(chunk) + (pa & MSCHUNKS_OFFSET_MASK); +} static inline unsigned long physRpn_to_absRpn(unsigned long rpn) From michael at ellerman.id.au Wed Aug 3 20:21:24 2005 From: michael at ellerman.id.au (Michael Ellerman) Date: Wed, 3 Aug 2005 20:21:24 +1000 (EST) Subject: [PATCH 5/10] ppc64: Remove redundant uses of physRpn_to_absRpn In-Reply-To: <1123064479.417492.649639846705.qpatch@concordia> Message-ID: <20050803102124.9D5D467E91@ozlabs.org> physRpn_to_absRpn is a no-op on non-iSeries platforms, remove the two redundant calls. There's only one caller on iSeries so fold the logic in there so we can get rid of it completely. Signed-off-by: Michael Ellerman arch/ppc64/kernel/iSeries_htab.c | 5 ++++- arch/ppc64/kernel/pSeries_lpar.c | 3 +-- arch/ppc64/mm/hash_native.c | 3 +-- include/asm-ppc64/abs_addr.h | 8 -------- 4 files changed, 6 insertions(+), 13 deletions(-) Index: work/arch/ppc64/kernel/pSeries_lpar.c =================================================================== --- work.orig/arch/ppc64/kernel/pSeries_lpar.c +++ work/arch/ppc64/kernel/pSeries_lpar.c @@ -279,7 +279,6 @@ long pSeries_lpar_hpte_insert(unsigned l unsigned long va, unsigned long prpn, unsigned long vflags, unsigned long rflags) { - unsigned long arpn = physRpn_to_absRpn(prpn); unsigned long lpar_rc; unsigned long flags; unsigned long slot; @@ -290,7 +289,7 @@ long pSeries_lpar_hpte_insert(unsigned l if (vflags & HPTE_V_LARGE) hpte_v &= ~(1UL << HPTE_V_AVPN_SHIFT); - hpte_r = (arpn << HPTE_R_RPN_SHIFT) | rflags; + hpte_r = (prpn << HPTE_R_RPN_SHIFT) | rflags; /* Now fill in the actual HPTE */ /* Set CEC cookie to 0 */ Index: work/arch/ppc64/mm/hash_native.c =================================================================== --- work.orig/arch/ppc64/mm/hash_native.c +++ work/arch/ppc64/mm/hash_native.c @@ -51,7 +51,6 @@ long native_hpte_insert(unsigned long hp unsigned long prpn, unsigned long vflags, unsigned long rflags) { - unsigned long arpn = physRpn_to_absRpn(prpn); hpte_t *hptep = htab_address + hpte_group; unsigned long hpte_v, hpte_r; int i; @@ -74,7 +73,7 @@ long native_hpte_insert(unsigned long hp hpte_v = (va >> 23) << HPTE_V_AVPN_SHIFT | vflags | HPTE_V_VALID; if (vflags & HPTE_V_LARGE) va &= ~(1UL << HPTE_V_AVPN_SHIFT); - hpte_r = (arpn << HPTE_R_RPN_SHIFT) | rflags; + hpte_r = (prpn << HPTE_R_RPN_SHIFT) | rflags; hptep->r = hpte_r; /* Guarantee the second dword is visible before the valid bit */ Index: work/arch/ppc64/kernel/iSeries_htab.c =================================================================== --- work.orig/arch/ppc64/kernel/iSeries_htab.c +++ work/arch/ppc64/kernel/iSeries_htab.c @@ -41,6 +41,7 @@ static long iSeries_hpte_insert(unsigned unsigned long prpn, unsigned long vflags, unsigned long rflags) { + unsigned long arpn; long slot; hpte_t lhpte; int secondary = 0; @@ -70,8 +71,10 @@ static long iSeries_hpte_insert(unsigned slot &= 0x7fffffffffffffff; } + arpn = phys_to_abs(prpn << PAGE_SHIFT) >> PAGE_SHIFT; + lhpte.v = (va >> 23) << HPTE_V_AVPN_SHIFT | vflags | HPTE_V_VALID; - lhpte.r = (physRpn_to_absRpn(prpn) << HPTE_R_RPN_SHIFT) | rflags; + lhpte.r = (arpn << HPTE_R_RPN_SHIFT) | rflags; /* Now fill in the actual HPTE */ HvCallHpt_addValidate(slot, secondary, &lhpte); Index: work/include/asm-ppc64/abs_addr.h =================================================================== --- work.orig/include/asm-ppc64/abs_addr.h +++ work/include/asm-ppc64/abs_addr.h @@ -56,14 +56,6 @@ static inline unsigned long phys_to_abs( return chunk_to_addr(chunk) + (pa & MSCHUNKS_OFFSET_MASK); } -static inline unsigned long -physRpn_to_absRpn(unsigned long rpn) -{ - unsigned long pa = rpn << PAGE_SHIFT; - unsigned long aa = phys_to_abs(pa); - return (aa >> PAGE_SHIFT); -} - /* A macro so it can take pointers or unsigned long. */ #define abs_to_phys(aa) lmb_abs_to_phys((unsigned long)(aa)) From michael at ellerman.id.au Wed Aug 3 20:21:24 2005 From: michael at ellerman.id.au (Michael Ellerman) Date: Wed, 3 Aug 2005 20:21:24 +1000 (EST) Subject: [PATCH 6/10] ppc64: Remove redundant use of pointers in lmb code In-Reply-To: <1123064479.417492.649639846705.qpatch@concordia> Message-ID: <20050803102124.DA57167E87@ozlabs.org> The lmb code is all written to use a pointer to an lmb struct. But it's always the same lmb struct, called "lmb". So we take the address of lmb, call it _lmb and then start using _lmb->foo everywhere, which is silly. This patch removes the _lmb pointers and replaces them with direct references to the one "lmb" struct. We do the same for some _mem and _rsv pointers which point to lmb.memory and lmb.reserved respectively. This patch looks quite busy, but it's basically just: s/_lmb->/lmb./g s/_mem->/lmb.memory./g s/_rsv->/lmb.reserved./g s/_rsv/&lmb.reserved/g s/mem->/lmb.memory./g Signed-off-by: Michael Ellerman arch/ppc64/kernel/lmb.c | 100 ++++++++++++++++++++---------------------------- 1 files changed, 43 insertions(+), 57 deletions(-) Index: work/arch/ppc64/kernel/lmb.c =================================================================== --- work.orig/arch/ppc64/kernel/lmb.c +++ work/arch/ppc64/kernel/lmb.c @@ -28,33 +28,32 @@ void lmb_dump_all(void) { #ifdef DEBUG unsigned long i; - struct lmb *_lmb = &lmb; udbg_printf("lmb_dump_all:\n"); udbg_printf(" memory.cnt = 0x%lx\n", - _lmb->memory.cnt); + lmb.memory.cnt); udbg_printf(" memory.size = 0x%lx\n", - _lmb->memory.size); - for (i=0; i < _lmb->memory.cnt ;i++) { + lmb.memory.size); + for (i=0; i < lmb.memory.cnt ;i++) { udbg_printf(" memory.region[0x%x].base = 0x%lx\n", - i, _lmb->memory.region[i].base); + i, lmb.memory.region[i].base); udbg_printf(" .physbase = 0x%lx\n", - _lmb->memory.region[i].physbase); + lmb.memory.region[i].physbase); udbg_printf(" .size = 0x%lx\n", - _lmb->memory.region[i].size); + lmb.memory.region[i].size); } udbg_printf("\n reserved.cnt = 0x%lx\n", - _lmb->reserved.cnt); + lmb.reserved.cnt); udbg_printf(" reserved.size = 0x%lx\n", - _lmb->reserved.size); - for (i=0; i < _lmb->reserved.cnt ;i++) { + lmb.reserved.size); + for (i=0; i < lmb.reserved.cnt ;i++) { udbg_printf(" reserved.region[0x%x].base = 0x%lx\n", - i, _lmb->reserved.region[i].base); + i, lmb.reserved.region[i].base); udbg_printf(" .physbase = 0x%lx\n", - _lmb->reserved.region[i].physbase); + lmb.reserved.region[i].physbase); udbg_printf(" .size = 0x%lx\n", - _lmb->reserved.region[i].size); + lmb.reserved.region[i].size); } #endif /* DEBUG */ } @@ -108,19 +107,17 @@ lmb_coalesce_regions(struct lmb_region * void __init lmb_init(void) { - struct lmb *_lmb = &lmb; - /* Create a dummy zero size LMB which will get coalesced away later. * This simplifies the lmb_add() code below... */ - _lmb->memory.region[0].base = 0; - _lmb->memory.region[0].size = 0; - _lmb->memory.cnt = 1; + lmb.memory.region[0].base = 0; + lmb.memory.region[0].size = 0; + lmb.memory.cnt = 1; /* Ditto. */ - _lmb->reserved.region[0].base = 0; - _lmb->reserved.region[0].size = 0; - _lmb->reserved.cnt = 1; + lmb.reserved.region[0].base = 0; + lmb.reserved.region[0].size = 0; + lmb.reserved.cnt = 1; } /* This routine called with relocation disabled. */ @@ -130,27 +127,26 @@ lmb_analyze(void) unsigned long i; unsigned long mem_size = 0; unsigned long size_mask = 0; - struct lmb *_lmb = &lmb; #ifdef CONFIG_MSCHUNKS unsigned long physbase = 0; #endif - for (i=0; i < _lmb->memory.cnt; i++) { + for (i=0; i < lmb.memory.cnt; i++) { unsigned long lmb_size; - lmb_size = _lmb->memory.region[i].size; + lmb_size = lmb.memory.region[i].size; #ifdef CONFIG_MSCHUNKS - _lmb->memory.region[i].physbase = physbase; + lmb.memory.region[i].physbase = physbase; physbase += lmb_size; #else - _lmb->memory.region[i].physbase = _lmb->memory.region[i].base; + lmb.memory.region[i].physbase = lmb.memory.region[i].base; #endif mem_size += lmb_size; size_mask |= lmb_size; } - _lmb->memory.size = mem_size; + lmb.memory.size = mem_size; } /* This routine called with relocation disabled. */ @@ -213,12 +209,11 @@ lmb_add_region(struct lmb_region *rgn, u long __init lmb_add(unsigned long base, unsigned long size) { - struct lmb *_lmb = &lmb; - struct lmb_region *_rgn = &(_lmb->memory); + struct lmb_region *_rgn = &(lmb.memory); /* On pSeries LPAR systems, the first LMB is our RMO region. */ if ( base == 0 ) - _lmb->rmo_size = size; + lmb.rmo_size = size; return lmb_add_region(_rgn, base, size); @@ -227,8 +222,7 @@ lmb_add(unsigned long base, unsigned lon long __init lmb_reserve(unsigned long base, unsigned long size) { - struct lmb *_lmb = &lmb; - struct lmb_region *_rgn = &(_lmb->reserved); + struct lmb_region *_rgn = &(lmb.reserved); return lmb_add_region(_rgn, base, size); } @@ -260,13 +254,10 @@ lmb_alloc_base(unsigned long size, unsig { long i, j; unsigned long base = 0; - struct lmb *_lmb = &lmb; - struct lmb_region *_mem = &(_lmb->memory); - struct lmb_region *_rsv = &(_lmb->reserved); - for (i=_mem->cnt-1; i >= 0; i--) { - unsigned long lmbbase = _mem->region[i].base; - unsigned long lmbsize = _mem->region[i].size; + for (i=lmb.memory.cnt-1; i >= 0; i--) { + unsigned long lmbbase = lmb.memory.region[i].base; + unsigned long lmbsize = lmb.memory.region[i].size; if ( max_addr == LMB_ALLOC_ANYWHERE ) base = _ALIGN_DOWN(lmbbase+lmbsize-size, align); @@ -276,8 +267,8 @@ lmb_alloc_base(unsigned long size, unsig continue; while ( (lmbbase <= base) && - ((j = lmb_overlaps_region(_rsv,base,size)) >= 0) ) { - base = _ALIGN_DOWN(_rsv->region[j].base-size, align); + ((j = lmb_overlaps_region(&lmb.reserved,base,size)) >= 0) ) { + base = _ALIGN_DOWN(lmb.reserved.region[j].base-size, align); } if ( (base != 0) && (lmbbase <= base) ) @@ -287,7 +278,7 @@ lmb_alloc_base(unsigned long size, unsig if ( i < 0 ) return 0; - lmb_add_region(_rsv, base, size); + lmb_add_region(&lmb.reserved, base, size); return base; } @@ -295,17 +286,15 @@ lmb_alloc_base(unsigned long size, unsig unsigned long __init lmb_phys_mem_size(void) { - struct lmb *_lmb = &lmb; #ifdef CONFIG_MSCHUNKS - return _lmb->memory.size; + return lmb.memory.size; #else - struct lmb_region *_mem = &(_lmb->memory); unsigned long total = 0; int i; /* add all physical memory to the bootmem map */ - for (i=0; i < _mem->cnt; i++) - total += _mem->region[i].size; + for (i=0; i < lmb.memory.cnt; i++) + total += lmb.memory.region[i].size; return total; #endif /* CONFIG_MSCHUNKS */ } @@ -313,14 +302,12 @@ lmb_phys_mem_size(void) unsigned long __init lmb_end_of_DRAM(void) { - struct lmb *_lmb = &lmb; - struct lmb_region *_mem = &(_lmb->memory); - int idx = _mem->cnt - 1; + int idx = lmb.memory.cnt - 1; #ifdef CONFIG_MSCHUNKS - return (_mem->region[idx].physbase + _mem->region[idx].size); + return (lmb.memory.region[idx].physbase + lmb.memory.region[idx].size); #else - return (_mem->region[idx].base + _mem->region[idx].size); + return (lmb.memory.region[idx].base + lmb.memory.region[idx].size); #endif /* CONFIG_MSCHUNKS */ return 0; @@ -353,20 +340,19 @@ void __init lmb_enforce_memory_limit(voi { extern unsigned long memory_limit; unsigned long i, limit; - struct lmb_region *mem = &(lmb.memory); if (! memory_limit) return; limit = memory_limit; - for (i = 0; i < mem->cnt; i++) { - if (limit > mem->region[i].size) { - limit -= mem->region[i].size; + for (i = 0; i < lmb.memory.cnt; i++) { + if (limit > lmb.memory.region[i].size) { + limit -= lmb.memory.region[i].size; continue; } - mem->region[i].size = limit; - mem->cnt = i + 1; + lmb.memory.region[i].size = limit; + lmb.memory.cnt = i + 1; break; } } From michael at ellerman.id.au Wed Aug 3 20:21:25 2005 From: michael at ellerman.id.au (Michael Ellerman) Date: Wed, 3 Aug 2005 20:21:25 +1000 (EST) Subject: [PATCH 7/10] ppc64: Remove redundant abs_to_phys() macro In-Reply-To: <1123064479.417492.649639846705.qpatch@concordia> Message-ID: <20050803102125.6A5A767E91@ozlabs.org> abs_to_phys() is a macro that turns out to do nothing, and also has the unfortunate property that it's not the inverse of phys_to_abs() on iSeries. The following is for my benefit as much as everyone else. With CONFIG_MSCHUNKS enabled, the lmb code is changed such that it keeps a physbase variable for each lmb region. This is used to take the possibly discontiguous lmb regions and present them as a contiguous address space beginning from zero. In this context each lmb region's base address is its "absolute" base address, and its physbase is it's "physical" address (from Linux's point of view). The abs_to_phys() macro does the mapping from "absolute" to "physical". Note: This is not related to the iSeries mapping of physical to absolute (ie. Hypervisor) addresses which is maintained with the msChunks structure. And the msChunks structure is not controlled via CONFIG_MSCHUNKS. Once upon a time you could compile for non-iSeries with CONFIG_MSCHUNKS enabled. But these days CONFIG_MSCHUNKS depends on CONFIG_PPC_ISERIES, so for non-iSeries code abs_to_phys() is a no-op. On iSeries we always have one lmb region which spans from 0 to systemcfg->physicalMemorySize (arch/ppc64/kernel/iSeries_setup.c line 383). This region has a base (ie. absolute) address of 0, and a physbase address of 0 (as calculated in lmb_analyze() (arch/ppc64/kernel/lmb.c line 144)). On iSeries, abs_to_phys(aa) is defined as lmb_abs_to_phys(aa), which finds the lmb region containing aa (and there's only one, ie. 0), and then does: return lmb.memory.region[0].physbase + (aa - lmb.memory.region[0].base) physbase == base == 0, so you're left with "return aa". So remove abs_to_phys(), and lmb_abs_to_phys() which is the implementation of abs_to_phys() for iSeries. Signed-off-by: Michael Ellerman arch/ppc64/kernel/lmb.c | 19 ------------------- arch/ppc64/mm/init.c | 4 +--- include/asm-ppc64/abs_addr.h | 6 +----- include/asm-ppc64/lmb.h | 1 - 4 files changed, 2 insertions(+), 28 deletions(-) Index: work/arch/ppc64/mm/init.c =================================================================== --- work.orig/arch/ppc64/mm/init.c +++ work/arch/ppc64/mm/init.c @@ -42,7 +42,6 @@ #include #include -#include #include #include #include @@ -159,7 +158,6 @@ static int map_io_page(unsigned long ea, ptep = pte_alloc_kernel(&init_mm, pmdp, ea); if (!ptep) return -ENOMEM; - pa = abs_to_phys(pa); set_pte_at(&init_mm, ea, ptep, pfn_pte(pa >> PAGE_SHIFT, __pgprot(flags))); spin_unlock(&init_mm.page_table_lock); @@ -547,7 +545,7 @@ void __init do_init_bootmem(void) */ bootmap_pages = bootmem_bootmap_pages(total_pages); - start = abs_to_phys(lmb_alloc(bootmap_pages<> PAGE_SHIFT, total_pages); Index: work/include/asm-ppc64/abs_addr.h =================================================================== --- work.orig/include/asm-ppc64/abs_addr.h +++ work/include/asm-ppc64/abs_addr.h @@ -56,9 +56,6 @@ static inline unsigned long phys_to_abs( return chunk_to_addr(chunk) + (pa & MSCHUNKS_OFFSET_MASK); } -/* A macro so it can take pointers or unsigned long. */ -#define abs_to_phys(aa) lmb_abs_to_phys((unsigned long)(aa)) - #else /* !CONFIG_MSCHUNKS */ #define chunk_to_addr(chunk) ((unsigned long)(chunk)) @@ -68,12 +65,11 @@ static inline unsigned long phys_to_abs( #define phys_to_abs(pa) (pa) #define physRpn_to_absRpn(rpn) (rpn) -#define abs_to_phys(aa) (aa) #endif /* !CONFIG_MSCHUNKS */ /* Convenience macros */ #define virt_to_abs(va) phys_to_abs(__pa(va)) -#define abs_to_virt(aa) __va(abs_to_phys(aa)) +#define abs_to_virt(aa) __va(aa) #endif /* _ABS_ADDR_H */ Index: work/arch/ppc64/kernel/lmb.c =================================================================== --- work.orig/arch/ppc64/kernel/lmb.c +++ work/arch/ppc64/kernel/lmb.c @@ -313,25 +313,6 @@ lmb_end_of_DRAM(void) return 0; } -unsigned long __init -lmb_abs_to_phys(unsigned long aa) -{ - unsigned long i, pa = aa; - struct lmb *_lmb = &lmb; - struct lmb_region *_mem = &(_lmb->memory); - - for (i=0; i < _mem->cnt; i++) { - unsigned long lmbbase = _mem->region[i].base; - unsigned long lmbsize = _mem->region[i].size; - if ( lmb_addrs_overlap(aa,1,lmbbase,lmbsize) ) { - pa = _mem->region[i].physbase + (aa - lmbbase); - break; - } - } - - return pa; -} - /* * Truncate the lmb list to memory_limit if it's set * You must call lmb_analyze() after this. Index: work/include/asm-ppc64/lmb.h =================================================================== --- work.orig/include/asm-ppc64/lmb.h +++ work/include/asm-ppc64/lmb.h @@ -50,7 +50,6 @@ extern unsigned long __init lmb_alloc_ba unsigned long); extern unsigned long __init lmb_phys_mem_size(void); extern unsigned long __init lmb_end_of_DRAM(void); -extern unsigned long __init lmb_abs_to_phys(unsigned long); extern void __init lmb_enforce_memory_limit(void); extern void lmb_dump_all(void); From michael at ellerman.id.au Wed Aug 3 20:21:26 2005 From: michael at ellerman.id.au (Michael Ellerman) Date: Wed, 3 Aug 2005 20:21:26 +1000 (EST) Subject: [PATCH 9/10] ppc64: Simplify some lmb functions In-Reply-To: <1123064479.417492.649639846705.qpatch@concordia> Message-ID: <20050803102126.9938767E9B@ozlabs.org> lmb_phys_mem_size() can always return lmb.memory.size, as long as it's called after lmb_analyze(), which it is. There's no need to recalculate the size on every call. lmb_analyze() was calculating a few things we then threw away, so just don't calculate them to start with. Signed-off-by: Michael Ellerman arch/ppc64/kernel/lmb.c | 27 +++++---------------------- 1 files changed, 5 insertions(+), 22 deletions(-) Index: work/arch/ppc64/kernel/lmb.c =================================================================== --- work.orig/arch/ppc64/kernel/lmb.c +++ work/arch/ppc64/kernel/lmb.c @@ -119,20 +119,12 @@ lmb_init(void) void __init lmb_analyze(void) { - unsigned long i; - unsigned long mem_size = 0; - unsigned long size_mask = 0; - - for (i=0; i < lmb.memory.cnt; i++) { - unsigned long lmb_size; + int i; - lmb_size = lmb.memory.region[i].size; + lmb.memory.size = 0; - mem_size += lmb_size; - size_mask |= lmb_size; - } - - lmb.memory.size = mem_size; + for (i = 0; i < lmb.memory.cnt; i++) + lmb.memory.size += lmb.memory.region[i].size; } /* This routine called with relocation disabled. */ @@ -266,20 +258,11 @@ lmb_alloc_base(unsigned long size, unsig return base; } +/* You must call lmb_analyze() before this. */ unsigned long __init lmb_phys_mem_size(void) { -#ifdef CONFIG_MSCHUNKS return lmb.memory.size; -#else - unsigned long total = 0; - int i; - - /* add all physical memory to the bootmem map */ - for (i=0; i < lmb.memory.cnt; i++) - total += lmb.memory.region[i].size; - return total; -#endif /* CONFIG_MSCHUNKS */ } unsigned long __init From michael at ellerman.id.au Wed Aug 3 20:21:26 2005 From: michael at ellerman.id.au (Michael Ellerman) Date: Wed, 3 Aug 2005 20:21:26 +1000 (EST) Subject: [PATCH 8/10] ppc64: Remove physbase from the lmb_property struct In-Reply-To: <1123064479.417492.649639846705.qpatch@concordia> Message-ID: <20050803102126.30DA467E97@ozlabs.org> We no longer need the lmb code to know about abs and phys addresses, so remove the physbase variable from the lmb_property struct. Signed-off-by: Michael Ellerman arch/ppc64/kernel/lmb.c | 23 ----------------------- arch/ppc64/mm/hash_utils.c | 2 +- arch/ppc64/mm/init.c | 27 ++++++++++++--------------- arch/ppc64/mm/numa.c | 2 +- include/asm-ppc64/lmb.h | 1 - 5 files changed, 14 insertions(+), 41 deletions(-) Index: work/include/asm-ppc64/lmb.h =================================================================== --- work.orig/include/asm-ppc64/lmb.h +++ work/include/asm-ppc64/lmb.h @@ -22,7 +22,6 @@ struct lmb_property { unsigned long base; - unsigned long physbase; unsigned long size; }; Index: work/arch/ppc64/kernel/lmb.c =================================================================== --- work.orig/arch/ppc64/kernel/lmb.c +++ work/arch/ppc64/kernel/lmb.c @@ -37,8 +37,6 @@ void lmb_dump_all(void) for (i=0; i < lmb.memory.cnt ;i++) { udbg_printf(" memory.region[0x%x].base = 0x%lx\n", i, lmb.memory.region[i].base); - udbg_printf(" .physbase = 0x%lx\n", - lmb.memory.region[i].physbase); udbg_printf(" .size = 0x%lx\n", lmb.memory.region[i].size); } @@ -50,8 +48,6 @@ void lmb_dump_all(void) for (i=0; i < lmb.reserved.cnt ;i++) { udbg_printf(" reserved.region[0x%x].base = 0x%lx\n", i, lmb.reserved.region[i].base); - udbg_printf(" .physbase = 0x%lx\n", - lmb.reserved.region[i].physbase); udbg_printf(" .size = 0x%lx\n", lmb.reserved.region[i].size); } @@ -97,7 +93,6 @@ lmb_coalesce_regions(struct lmb_region * rgn->region[r1].size += rgn->region[r2].size; for (i=r2; i < rgn->cnt-1; i++) { rgn->region[i].base = rgn->region[i+1].base; - rgn->region[i].physbase = rgn->region[i+1].physbase; rgn->region[i].size = rgn->region[i+1].size; } rgn->cnt--; @@ -127,21 +122,12 @@ lmb_analyze(void) unsigned long i; unsigned long mem_size = 0; unsigned long size_mask = 0; -#ifdef CONFIG_MSCHUNKS - unsigned long physbase = 0; -#endif for (i=0; i < lmb.memory.cnt; i++) { unsigned long lmb_size; lmb_size = lmb.memory.region[i].size; -#ifdef CONFIG_MSCHUNKS - lmb.memory.region[i].physbase = physbase; - physbase += lmb_size; -#else - lmb.memory.region[i].physbase = lmb.memory.region[i].base; -#endif mem_size += lmb_size; size_mask |= lmb_size; } @@ -164,7 +150,6 @@ lmb_add_region(struct lmb_region *rgn, u adjacent = lmb_addrs_adjacent(base,size,rgnbase,rgnsize); if ( adjacent > 0 ) { rgn->region[i].base -= size; - rgn->region[i].physbase -= size; rgn->region[i].size += size; coalesced++; break; @@ -191,11 +176,9 @@ lmb_add_region(struct lmb_region *rgn, u for (i=rgn->cnt-1; i >= 0; i--) { if (base < rgn->region[i].base) { rgn->region[i+1].base = rgn->region[i].base; - rgn->region[i+1].physbase = rgn->region[i].physbase; rgn->region[i+1].size = rgn->region[i].size; } else { rgn->region[i+1].base = base; - rgn->region[i+1].physbase = lmb_abs_to_phys(base); rgn->region[i+1].size = size; break; } @@ -304,13 +287,7 @@ lmb_end_of_DRAM(void) { int idx = lmb.memory.cnt - 1; -#ifdef CONFIG_MSCHUNKS - return (lmb.memory.region[idx].physbase + lmb.memory.region[idx].size); -#else return (lmb.memory.region[idx].base + lmb.memory.region[idx].size); -#endif /* CONFIG_MSCHUNKS */ - - return 0; } /* Index: work/arch/ppc64/mm/init.c =================================================================== --- work.orig/arch/ppc64/mm/init.c +++ work/arch/ppc64/mm/init.c @@ -482,9 +482,9 @@ void __init mm_init_ppc64(void) for (i = 1; i < lmb.memory.cnt; i++) { unsigned long base, prevbase, prevsize; - prevbase = lmb.memory.region[i-1].physbase; + prevbase = lmb.memory.region[i-1].base; prevsize = lmb.memory.region[i-1].size; - base = lmb.memory.region[i].physbase; + base = lmb.memory.region[i].base; if (base > (prevbase + prevsize)) { io_hole_start = prevbase + prevsize; io_hole_size = base - (prevbase + prevsize); @@ -511,11 +511,8 @@ int page_is_ram(unsigned long pfn) for (i=0; i < lmb.memory.cnt; i++) { unsigned long base; -#ifdef CONFIG_MSCHUNKS - base = lmb.memory.region[i].physbase; -#else base = lmb.memory.region[i].base; -#endif + if ((paddr >= base) && (paddr < (base + lmb.memory.region[i].size))) { return 1; @@ -556,25 +553,25 @@ void __init do_init_bootmem(void) * present. */ for (i=0; i < lmb.memory.cnt; i++) { - unsigned long physbase, size; + unsigned long base, size; unsigned long start_pfn, end_pfn; - physbase = lmb.memory.region[i].physbase; + base = lmb.memory.region[i].base; size = lmb.memory.region[i].size; - start_pfn = physbase >> PAGE_SHIFT; + start_pfn = base >> PAGE_SHIFT; end_pfn = start_pfn + (size >> PAGE_SHIFT); memory_present(0, start_pfn, end_pfn); - free_bootmem(physbase, size); + free_bootmem(base, size); } /* reserve the sections we're already using */ for (i=0; i < lmb.reserved.cnt; i++) { - unsigned long physbase = lmb.reserved.region[i].physbase; + unsigned long base = lmb.reserved.region[i].base; unsigned long size = lmb.reserved.region[i].size; - reserve_bootmem(physbase, size); + reserve_bootmem(base, size); } } @@ -613,10 +610,10 @@ static int __init setup_kcore(void) int i; for (i=0; i < lmb.memory.cnt; i++) { - unsigned long physbase, size; + unsigned long base, size; struct kcore_list *kcore_mem; - physbase = lmb.memory.region[i].physbase; + base = lmb.memory.region[i].base; size = lmb.memory.region[i].size; /* GFP_ATOMIC to avoid might_sleep warnings during boot */ @@ -624,7 +621,7 @@ static int __init setup_kcore(void) if (!kcore_mem) panic("mem_init: kmalloc failed\n"); - kclist_add(kcore_mem, __va(physbase), size); + kclist_add(kcore_mem, __va(base), size); } kclist_add(&kcore_vmem, (void *)VMALLOC_START, VMALLOC_END-VMALLOC_START); Index: work/arch/ppc64/mm/hash_utils.c =================================================================== --- work.orig/arch/ppc64/mm/hash_utils.c +++ work/arch/ppc64/mm/hash_utils.c @@ -210,7 +210,7 @@ void __init htab_initialize(void) /* create bolted the linear mapping in the hash table */ for (i=0; i < lmb.memory.cnt; i++) { - base = lmb.memory.region[i].physbase + KERNELBASE; + base = lmb.memory.region[i].base + KERNELBASE; size = lmb.memory.region[i].size; DBG("creating mapping for region: %lx : %lx\n", base, size); Index: work/arch/ppc64/mm/numa.c =================================================================== --- work.orig/arch/ppc64/mm/numa.c +++ work/arch/ppc64/mm/numa.c @@ -671,7 +671,7 @@ new_range: * Mark reserved regions on this node */ for (i = 0; i < lmb.reserved.cnt; i++) { - unsigned long physbase = lmb.reserved.region[i].physbase; + unsigned long physbase = lmb.reserved.region[i].base; unsigned long size = lmb.reserved.region[i].size; if (pa_to_nid(physbase) != nid && From michael at ellerman.id.au Wed Aug 3 20:21:26 2005 From: michael at ellerman.id.au (Michael Ellerman) Date: Wed, 3 Aug 2005 20:21:26 +1000 (EST) Subject: [PATCH 10/10] ppc64: Remove CONFIG_MSCHUNKS In-Reply-To: <1123064479.417492.649639846705.qpatch@concordia> Message-ID: <20050803102126.0729967E9E@ozlabs.org> We can now remove CONFIG_MSCHUNKS as it doesn't do anything interesting anymore. The only macro in abs_addr.h which is called by non-iSeries code is phys_to_abs(), so remove the other dummy implementations, and we add a firmware feature check to phys_to_abs(). Signed-off-by: Michael Ellerman arch/ppc64/Kconfig | 6 ------ arch/ppc64/configs/iSeries_defconfig | 1 - include/asm-ppc64/abs_addr.h | 19 +++++-------------- 3 files changed, 5 insertions(+), 21 deletions(-) Index: work/arch/ppc64/Kconfig =================================================================== --- work.orig/arch/ppc64/Kconfig +++ work/arch/ppc64/Kconfig @@ -302,12 +302,6 @@ config GENERIC_HARDIRQS bool default y -config MSCHUNKS - bool - depends on PPC_ISERIES - default y - - config PPC_RTAS bool depends on PPC_PSERIES || PPC_BPA Index: work/include/asm-ppc64/abs_addr.h =================================================================== --- work.orig/include/asm-ppc64/abs_addr.h +++ work/include/asm-ppc64/abs_addr.h @@ -16,8 +16,7 @@ #include #include #include - -#ifdef CONFIG_MSCHUNKS +#include struct mschunks_map { unsigned long num_chunks; @@ -48,6 +47,10 @@ static inline unsigned long phys_to_abs( { unsigned long chunk; + /* This is a no-op on non-iSeries */ + if (!firmware_has_feature(FW_FEATURE_ISERIES)) + return pa; + chunk = addr_to_chunk(pa); if (chunk < mschunks_map.num_chunks) @@ -56,18 +59,6 @@ static inline unsigned long phys_to_abs( return chunk_to_addr(chunk) + (pa & MSCHUNKS_OFFSET_MASK); } -#else /* !CONFIG_MSCHUNKS */ - -#define chunk_to_addr(chunk) ((unsigned long)(chunk)) -#define addr_to_chunk(addr) (addr) -#define chunk_offset(addr) (0) -#define abs_chunk(pchunk) (pchunk) - -#define phys_to_abs(pa) (pa) -#define physRpn_to_absRpn(rpn) (rpn) - -#endif /* !CONFIG_MSCHUNKS */ - /* Convenience macros */ #define virt_to_abs(va) phys_to_abs(__pa(va)) #define abs_to_virt(aa) __va(aa) Index: work/arch/ppc64/configs/iSeries_defconfig =================================================================== --- work.orig/arch/ppc64/configs/iSeries_defconfig +++ work/arch/ppc64/configs/iSeries_defconfig @@ -99,7 +99,6 @@ CONFIG_HZ_100=y # CONFIG_HZ_1000 is not set CONFIG_HZ=100 CONFIG_GENERIC_HARDIRQS=y -CONFIG_MSCHUNKS=y CONFIG_LPARCFG=y CONFIG_SECCOMP=y CONFIG_ISA_DMA_API=y From benh at kernel.crashing.org Wed Aug 3 21:51:33 2005 From: benh at kernel.crashing.org (Benjamin Herrenschmidt) Date: Wed, 03 Aug 2005 13:51:33 +0200 Subject: Fan control for new PowerMac G5 2.7GHz machines? In-Reply-To: <20050802051804.29854.qmail@electricrain.com> References: <20050802051804.29854.qmail@electricrain.com> Message-ID: <1123069894.30257.39.camel@gaston> > > Can anyone shed some light on the fan support for these new machines? > Am I just doing something simple wrong or missing something obvious? I though it was "just working" but maybe I'm wrong ... Have you tried a 2.6.12 upstream kernel ? Ben. From geoffrey.levand at am.sony.com Thu Aug 4 02:09:59 2005 From: geoffrey.levand at am.sony.com (Geoff Levand) Date: Wed, 03 Aug 2005 09:09:59 -0700 Subject: Fan control for new PowerMac G5 2.7GHz machines? In-Reply-To: <1123069894.30257.39.camel@gaston> References: <1123069894.30257.39.camel@gaston> Message-ID: <42F0EC57.9010503@am.sony.com> Benjamin Herrenschmidt wrote: >>Can anyone shed some light on the fan support for these new machines? >>Am I just doing something simple wrong or missing something obvious? > > > I though it was "just working" but maybe I'm wrong ... Have you tried a > 2.6.12 upstream kernel ? > > Ben. It doesn't work for me with 2.6.12.3. Any clue as to what's wrong? -Geoff From jdl at freescale.com Thu Aug 4 05:01:45 2005 From: jdl at freescale.com (Jon Loeliger) Date: Wed, 03 Aug 2005 14:01:45 -0500 Subject: [PATCH 0/10] Cleanup iSeries msChunks handling, and lmb code. In-Reply-To: <1123064479.417492.649639846705.qpatch@concordia> References: <1123064479.417492.649639846705.qpatch@concordia> Message-ID: <1123095705.8638.14.camel@cashmere.sps.mot.com> On Wed, 2005-08-03 at 05:21, Michael Ellerman wrote: > This series of patches cleans up the iSeries msChunks structure, and > associated macros and functions. > > It also removes CONFIG_MSCHUNKS from the lmb code, and eventually removes > CONFIG_MSCHUNKS entirely. > > The final patch rely's on Stephen's FW_FEATURE_ISERIES patches. > > Booted on Power3, G5, Power5 LPAR and iSeries. Excellent. This patch, especially the LMB simplification and removal of the physbase bits, greatly simplifies the notion of merging LMB form 64 land and the mem_pieces. I have previously submitted patches against the ppc32 code that enhance the mem_pieces towards the LMB structure as well. Given an eventual merger of the two bodies of code, I'd like to make the merger of these two structures more complete. I'll work towards that goal if that's a Good Idea. Advice here? Thanks, jdl From benh at kernel.crashing.org Thu Aug 4 05:58:00 2005 From: benh at kernel.crashing.org (Benjamin Herrenschmidt) Date: Wed, 03 Aug 2005 21:58:00 +0200 Subject: Fan control for new PowerMac G5 2.7GHz machines? In-Reply-To: <42F0EC57.9010503@am.sony.com> References: <1123069894.30257.39.camel@gaston> <42F0EC57.9010503@am.sony.com> Message-ID: <1123099081.30257.41.camel@gaston> On Wed, 2005-08-03 at 09:09 -0700, Geoff Levand wrote: > Benjamin Herrenschmidt wrote: > >>Can anyone shed some light on the fan support for these new machines? > >>Am I just doing something simple wrong or missing something obvious? > > > > > > I though it was "just working" but maybe I'm wrong ... Have you tried a > > 2.6.12 upstream kernel ? > > > > Ben. > > It doesn't work for me with 2.6.12.3. Any clue as to what's wrong? Not really. It's a PowerMac7,2 model ? (in /proc/cpuinfo) ? Can you maybe add some printk's around in the driver to see what's wrong ? Ben. From bdc at carlstrom.com Thu Aug 4 08:01:38 2005 From: bdc at carlstrom.com (Brian D. Carlstrom) Date: Wed, 3 Aug 2005 15:01:38 -0700 Subject: Fan control for new PowerMac G5 2.7GHz machines? In-Reply-To: <1123099081.30257.41.camel@gaston> References: <1123069894.30257.39.camel@gaston> <42F0EC57.9010503@am.sony.com> <1123099081.30257.41.camel@gaston> Message-ID: <17137.16066.91475.699906@zot.electricrain.com> Benjamin Herrenschmidt writes: > Not really. It's a PowerMac7,2 model ? (in /proc/cpuinfo) ? Can you > maybe add some printk's around in the driver to see what's wrong ? It reports PowerMac7,3: $ cat /proc/cpuinfo processor : 0 cpu : PPC970FX, altivec supported clock : 2700.000000MHz revision : 3.1 processor : 1 cpu : PPC970FX, altivec supported clock : 2700.000000MHz revision : 3.1 timebase : 33333333 machine : PowerMac7,3 motherboard : PowerMac7,3 MacRISC4 Power Macintosh detected as : 336 (PowerMac G5) pmac flags : 00000000 pmac-generation : NewWorld At the moment several people are working on the machine setting up services so I haven't been able to reboot to try the 2.6.12.3 linux-stable kernel yet. -bri From cfriesen at nortel.com Thu Aug 4 08:06:46 2005 From: cfriesen at nortel.com (Christopher Friesen) Date: Wed, 03 Aug 2005 16:06:46 -0600 Subject: Fan control for new PowerMac G5 2.7GHz machines? In-Reply-To: <17137.16066.91475.699906@zot.electricrain.com> References: <1123069894.30257.39.camel@gaston> <42F0EC57.9010503@am.sony.com> <1123099081.30257.41.camel@gaston> <17137.16066.91475.699906@zot.electricrain.com> Message-ID: <42F13FF6.8010701@nortel.com> Brian D. Carlstrom wrote: > Benjamin Herrenschmidt writes: > > Not really. It's a PowerMac7,2 model ? (in /proc/cpuinfo) ? Can you > > maybe add some printk's around in the driver to see what's wrong ? > > It reports PowerMac7,3: I think Ben must have made a mistake. My G5 that I've had for some time now also reports as 7,3, but it doesn't have the FX cpu revisions. processor : 0 cpu : PPC970, altivec supported clock : 2000.000000MHz revision : 2.2 processor : 1 cpu : PPC970, altivec supported clock : 2000.000000MHz revision : 2.2 timebase : 33333333 machine : PowerMac7,3 motherboard : PowerMac7,3 MacRISC4 Power Macintosh detected as : 336 (PowerMac G5) pmac flags : 00000000 pmac-generation : NewWorld Chris From geoffrey.levand at am.sony.com Thu Aug 4 08:19:47 2005 From: geoffrey.levand at am.sony.com (Geoff Levand) Date: Wed, 03 Aug 2005 15:19:47 -0700 Subject: Fan control for new PowerMac G5 2.7GHz machines? In-Reply-To: <1123099081.30257.41.camel@gaston> References: <1123099081.30257.41.camel@gaston> Message-ID: <42F14303.2000304@am.sony.com> Benjamin Herrenschmidt wrote: > On Wed, 2005-08-03 at 09:09 -0700, Geoff Levand wrote: > >>Benjamin Herrenschmidt wrote: >> >>>>Can anyone shed some light on the fan support for these new > > machines? > >>>>Am I just doing something simple wrong or missing something obvious? >>> >>> >>>I though it was "just working" but maybe I'm wrong ... Have you > > tried a > >>>2.6.12 upstream kernel ? >>> >>>Ben. >> >>It doesn't work for me with 2.6.12.3. Any clue as to what's wrong? > > > Not really. It's a PowerMac7,2 model ? (in /proc/cpuinfo) ? Can you > maybe add some printk's around in the driver to see what's wrong ? > Here's what it says... [geoff at g5 ~]$ cat /proc/cpuinfo processor : 0 cpu : PPC970FX, altivec supported clock : 2000.000000MHz revision : 3.0 processor : 1 cpu : PPC970FX, altivec supported clock : 2000.000000MHz revision : 3.0 timebase : 33333333 machine : PowerMac7,3 motherboard : PowerMac7,3 MacRISC4 Power Macintosh detected as : 336 (PowerMac G5) pmac flags : 00000000 pmac-generation : NewWorld This might be the problem, not sure how to fix though: i2c /dev entries driver /u3 at 0,f8000000/i2c at f8001000: Missing interrupt or address ! In therm_pm72_attach() it hits 'Found K2', but u3_0 and u3_1 are never set, so start_control_loops() is never called. I'll look at it more when I have some time. -Geoff From michael at ellerman.id.au Thu Aug 4 10:17:50 2005 From: michael at ellerman.id.au (Michael Ellerman) Date: Thu, 4 Aug 2005 10:17:50 +1000 Subject: [PATCH 0/10] Cleanup iSeries msChunks handling, and lmb code. In-Reply-To: <1123095705.8638.14.camel@cashmere.sps.mot.com> References: <1123064479.417492.649639846705.qpatch@concordia> <1123095705.8638.14.camel@cashmere.sps.mot.com> Message-ID: <200508041017.54208.michael@ellerman.id.au> On Thu, 4 Aug 2005 05:01, Jon Loeliger wrote: > On Wed, 2005-08-03 at 05:21, Michael Ellerman wrote: > > This series of patches cleans up the iSeries msChunks structure, and > > associated macros and functions. > > > > It also removes CONFIG_MSCHUNKS from the lmb code, and eventually removes > > CONFIG_MSCHUNKS entirely. > > > > The final patch rely's on Stephen's FW_FEATURE_ISERIES patches. > > > > Booted on Power3, G5, Power5 LPAR and iSeries. > > Excellent. This patch, especially the LMB simplification > and removal of the physbase bits, greatly simplifies the > notion of merging LMB form 64 land and the mem_pieces. Cool. I wasn't really thinking of 32 <-> 64 merging when I did the patches, but it's good to be heading in the right direction. > I have previously submitted patches against the ppc32 code > that enhance the mem_pieces towards the LMB structure as well. > > Given an eventual merger of the two bodies of code, I'd > like to make the merger of these two structures more complete. > I'll work towards that goal if that's a Good Idea. I don't know the ppc32 code (guess I'll need to soon), so I can't comment on specifics, but it sounds like a "Good Idea" to me. cheers -- Michael Ellerman IBM OzLabs email: michael:ellerman.id.au inmsg: mpe:jabber.org wwweb: http://michael.ellerman.id.au phone: +61 2 6212 1183 (tie line 70 21183) We do not inherit the earth from our ancestors, we borrow it from our children. - S.M.A.R.T Person -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: not available Url : http://ozlabs.org/pipermail/linuxppc64-dev/attachments/20050804/635ba5e6/attachment.pgp From olof at lixom.net Thu Aug 4 11:30:10 2005 From: olof at lixom.net (Olof Johansson) Date: Wed, 3 Aug 2005 20:30:10 -0500 Subject: [PATCH] PPC64: Fix UP kernel build Message-ID: <20050804013010.GA10556@austin.ibm.com> Hi, CONFIG_KEXEC breaks UP builds because of a misspelled smp_release_cpus(). Also, the function isn't defined unless built with CONFIG_SMP but it is needed if we are to go from a UP to SMP kernel. Enable it and document it. Thanks to Steven Winiecki for reporting this and to Milton for remembering how it's supposed to work and why. -Olof Signed-off-by: Olof Johansson Index: 2.6/arch/ppc64/kernel/machine_kexec.c =================================================================== --- 2.6.orig/arch/ppc64/kernel/machine_kexec.c 2005-08-03 19:53:16.000000000 -0500 +++ 2.6/arch/ppc64/kernel/machine_kexec.c 2005-08-03 20:39:49.000000000 -0500 @@ -243,13 +243,17 @@ static void kexec_prepare_cpus(void) static void kexec_prepare_cpus(void) { + extern void smp_release_cpus(void); /* * move the secondarys to us so that we can copy * the new kernel 0-0x100 safely * * do this if kexec in setup.c ? + * + * We need to release the cpus if we are ever going from an + * UP to an SMP kernel. */ - smp_relase_cpus(); + smp_release_cpus(); if (ppc_md.cpu_irq_down) ppc_md.cpu_irq_down(); local_irq_disable(); Index: 2.6/arch/ppc64/kernel/head.S =================================================================== --- 2.6.orig/arch/ppc64/kernel/head.S 2005-08-03 19:53:16.000000000 -0500 +++ 2.6/arch/ppc64/kernel/head.S 2005-08-03 20:37:22.000000000 -0500 @@ -2071,7 +2071,7 @@ _GLOBAL(hmt_start_secondary) blr #endif -#if defined(CONFIG_SMP) && !defined(CONFIG_PPC_ISERIES) +#if defined(CONFIG_KEXEC) || (defined(CONFIG_SMP) && !defined(CONFIG_PPC_ISERIES)) _GLOBAL(smp_release_cpus) /* All secondary cpus are spinning on a common * spinloop, release them all now so they can start From david at gibson.dropbear.id.au Thu Aug 4 15:13:07 2005 From: david at gibson.dropbear.id.au (David Gibson) Date: Thu, 4 Aug 2005 15:13:07 +1000 Subject: [PATCH] Four level pagetables for ppc64 Message-ID: <20050804051307.GA27961@localhost.localdomain> Paul, Please forward upstream for -mm, and, after 2.6.13, mainline also. Implement 4-level pagetables for ppc64 This patch implements full four-level page tables for ppc64, thereby extending the usable user address range to 44 bits (16T). The patch uses a full page for the tables at the bottom and top level, and a quarter page for the intermediate levels. It uses full 64-bit pointers at every level, thus also increasing the addressable range of physical memory. This patch also tweaks the VSID allocation to allow matching range for user addresses (this halves the number of available contexts) and adds some #if and BUILD_BUG sanity checks. Signed-off-by: David Gibson arch/ppc64/mm/hash_utils.c | 2 arch/ppc64/mm/hugetlbpage.c | 187 +++++++++++++----------------------------- arch/ppc64/mm/imalloc.c | 2 arch/ppc64/mm/init.c | 62 +++++++++---- arch/ppc64/mm/slb_low.S | 2 arch/ppc64/mm/tlb.c | 95 ++++++++++++--------- include/asm-ppc64/imalloc.h | 2 include/asm-ppc64/mmu.h | 7 - include/asm-ppc64/page.h | 26 +++-- include/asm-ppc64/pgalloc.h | 90 +++++++++++++------- include/asm-ppc64/pgtable.h | 81 +++++++++++------- include/asm-ppc64/processor.h | 4 12 files changed, 291 insertions(+), 269 deletions(-) Index: working-2.6/include/asm-ppc64/pgtable.h =================================================================== --- working-2.6.orig/include/asm-ppc64/pgtable.h 2005-08-04 13:22:21.000000000 +1000 +++ working-2.6/include/asm-ppc64/pgtable.h 2005-08-04 13:22:22.000000000 +1000 @@ -15,19 +15,24 @@ #include #endif /* __ASSEMBLY__ */ -#include - /* * Entries per page directory level. The PTE level must use a 64b record * for each page table entry. The PMD and PGD level use a 32b record for * each entry by assuming that each entry is page aligned. */ #define PTE_INDEX_SIZE 9 -#define PMD_INDEX_SIZE 10 -#define PGD_INDEX_SIZE 10 +#define PMD_INDEX_SIZE 7 +#define PUD_INDEX_SIZE 7 +#define PGD_INDEX_SIZE 9 + +#define PTE_TABLE_SIZE (sizeof(pte_t) << PTE_INDEX_SIZE) +#define PMD_TABLE_SIZE (sizeof(pmd_t) << PMD_INDEX_SIZE) +#define PUD_TABLE_SIZE (sizeof(pud_t) << PUD_INDEX_SIZE) +#define PGD_TABLE_SIZE (sizeof(pgd_t) << PGD_INDEX_SIZE) #define PTRS_PER_PTE (1 << PTE_INDEX_SIZE) #define PTRS_PER_PMD (1 << PMD_INDEX_SIZE) +#define PTRS_PER_PUD (1 << PMD_INDEX_SIZE) #define PTRS_PER_PGD (1 << PGD_INDEX_SIZE) /* PMD_SHIFT determines what a second-level page table entry can map */ @@ -35,8 +40,13 @@ #define PMD_SIZE (1UL << PMD_SHIFT) #define PMD_MASK (~(PMD_SIZE-1)) -/* PGDIR_SHIFT determines what a third-level page table entry can map */ -#define PGDIR_SHIFT (PMD_SHIFT + PMD_INDEX_SIZE) +/* PUD_SHIFT determines what a third-level page table entry can map */ +#define PUD_SHIFT (PMD_SHIFT + PMD_INDEX_SIZE) +#define PUD_SIZE (1UL << PUD_SHIFT) +#define PUD_MASK (~(PUD_SIZE-1)) + +/* PGDIR_SHIFT determines what a fourth-level page table entry can map */ +#define PGDIR_SHIFT (PUD_SHIFT + PUD_INDEX_SIZE) #define PGDIR_SIZE (1UL << PGDIR_SHIFT) #define PGDIR_MASK (~(PGDIR_SIZE-1)) @@ -45,15 +55,23 @@ /* * Size of EA range mapped by our pagetables. */ -#define EADDR_SIZE (PTE_INDEX_SIZE + PMD_INDEX_SIZE + \ - PGD_INDEX_SIZE + PAGE_SHIFT) -#define EADDR_MASK ((1UL << EADDR_SIZE) - 1) +#define PGTABLE_EADDR_SIZE (PTE_INDEX_SIZE + PMD_INDEX_SIZE + \ + PUD_INDEX_SIZE + PGD_INDEX_SIZE + PAGE_SHIFT) +#define PGTABLE_RANGE (1UL << PGTABLE_EADDR_SIZE) + +#if TASK_SIZE_USER64 > PGTABLE_RANGE +#error TASK_SIZE_USER64 exceeds pagetable range +#endif + +#if TASK_SIZE_USER64 > (1UL << (USER_ESID_BITS + SID_SHIFT)) +#error TASK_SIZE_USER64 exceeds user VSID range +#endif /* * Define the address range of the vmalloc VM area. */ #define VMALLOC_START (0xD000000000000000ul) -#define VMALLOC_SIZE (0x10000000000UL) +#define VMALLOC_SIZE (0x80000000000UL) #define VMALLOC_END (VMALLOC_START + VMALLOC_SIZE) /* @@ -154,8 +172,6 @@ #ifndef __ASSEMBLY__ int hash_huge_page(struct mm_struct *mm, unsigned long access, unsigned long ea, unsigned long vsid, int local); - -void hugetlb_mm_free_pgd(struct mm_struct *mm); #endif /* __ASSEMBLY__ */ #define HAVE_ARCH_UNMAPPED_AREA @@ -163,7 +179,6 @@ #else #define hash_huge_page(mm,a,ea,vsid,local) -1 -#define hugetlb_mm_free_pgd(mm) do {} while (0) #endif @@ -197,39 +212,45 @@ #define pte_pfn(x) ((unsigned long)((pte_val(x) >> PTE_SHIFT))) #define pte_page(x) pfn_to_page(pte_pfn(x)) -#define pmd_set(pmdp, ptep) \ - (pmd_val(*(pmdp)) = __ba_to_bpn(ptep)) +#define pmd_set(pmdp, ptep) (pmd_val(*(pmdp)) = (unsigned long)(ptep)) #define pmd_none(pmd) (!pmd_val(pmd)) #define pmd_bad(pmd) (pmd_val(pmd) == 0) #define pmd_present(pmd) (pmd_val(pmd) != 0) #define pmd_clear(pmdp) (pmd_val(*(pmdp)) = 0) -#define pmd_page_kernel(pmd) (__bpn_to_ba(pmd_val(pmd))) +#define pmd_page_kernel(pmd) (pmd_val(pmd)) #define pmd_page(pmd) virt_to_page(pmd_page_kernel(pmd)) -#define pud_set(pudp, pmdp) (pud_val(*(pudp)) = (__ba_to_bpn(pmdp))) +#define pud_set(pudp, pmdp) (pud_val(*(pudp)) = (unsigned long)(pmdp)) #define pud_none(pud) (!pud_val(pud)) -#define pud_bad(pud) ((pud_val(pud)) == 0UL) -#define pud_present(pud) (pud_val(pud) != 0UL) -#define pud_clear(pudp) (pud_val(*(pudp)) = 0UL) -#define pud_page(pud) (__bpn_to_ba(pud_val(pud))) +#define pud_bad(pud) ((pud_val(pud)) == 0) +#define pud_present(pud) (pud_val(pud) != 0) +#define pud_clear(pudp) (pud_val(*(pudp)) = 0) +#define pud_page(pud) (pud_val(pud)) + +#define pgd_set(pgdp, pudp) ({pgd_val(*(pgdp)) = (unsigned long)(pudp);}) +#define pgd_none(pgd) (!pgd_val(pgd)) +#define pgd_bad(pgd) (pgd_val(pgd) == 0) +#define pgd_present(pgd) (pgd_val(pgd) != 0) +#define pgd_clear(pgdp) (pgd_val(*(pgdp)) = 0) +#define pgd_page(pgd) (pgd_val(pgd)) /* * Find an entry in a page-table-directory. We combine the address region * (the high order N bits) and the pgd portion of the address. */ /* to avoid overflow in free_pgtables we don't use PTRS_PER_PGD here */ -#define pgd_index(address) (((address) >> (PGDIR_SHIFT)) & 0x7ff) +#define pgd_index(address) (((address) >> (PGDIR_SHIFT)) & 0x1ff) #define pgd_offset(mm, address) ((mm)->pgd + pgd_index(address)) -/* Find an entry in the second-level page table.. */ +#define pud_offset(pgdp, addr) \ + (((pud_t *) pgd_page(*(pgdp))) + (((addr) >> PUD_SHIFT) & (PTRS_PER_PUD - 1))) + #define pmd_offset(pudp,addr) \ - ((pmd_t *) pud_page(*(pudp)) + (((addr) >> PMD_SHIFT) & (PTRS_PER_PMD - 1))) + (((pmd_t *) pud_page(*(pudp))) + (((addr) >> PMD_SHIFT) & (PTRS_PER_PMD - 1))) -/* Find an entry in the third-level page table.. */ #define pte_offset_kernel(dir,addr) \ - ((pte_t *) pmd_page_kernel(*(dir)) \ - + (((addr) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))) + (((pte_t *) pmd_page_kernel(*(dir))) + (((addr) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))) #define pte_offset_map(dir,addr) pte_offset_kernel((dir), (addr)) #define pte_offset_map_nested(dir,addr) pte_offset_kernel((dir), (addr)) @@ -458,9 +479,11 @@ #define pte_same(A,B) (((pte_val(A) ^ pte_val(B)) & ~_PAGE_HPTEFLAGS) == 0) #define pmd_ERROR(e) \ - printk("%s:%d: bad pmd %08x.\n", __FILE__, __LINE__, pmd_val(e)) + printk("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, pmd_val(e)) +#define pud_ERROR(e) \ + printk("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, pud_val(e)) #define pgd_ERROR(e) \ - printk("%s:%d: bad pgd %08x.\n", __FILE__, __LINE__, pgd_val(e)) + printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e)) extern pgd_t swapper_pg_dir[]; Index: working-2.6/include/asm-ppc64/page.h =================================================================== --- working-2.6.orig/include/asm-ppc64/page.h 2005-08-04 13:22:21.000000000 +1000 +++ working-2.6/include/asm-ppc64/page.h 2005-08-04 13:22:22.000000000 +1000 @@ -46,6 +46,7 @@ #define ARCH_HAS_HUGEPAGE_ONLY_RANGE #define ARCH_HAS_PREPARE_HUGEPAGE_RANGE +#define ARCH_HAS_SETCLEAR_HUGE_PTE #define touches_hugepage_low_range(mm, addr, len) \ (LOW_ESID_MASK((addr), (len)) & mm->context.htlb_segs) @@ -125,36 +126,42 @@ * Entries in the pte table are 64b, while entries in the pgd & pmd are 32b. */ typedef struct { unsigned long pte; } pte_t; -typedef struct { unsigned int pmd; } pmd_t; -typedef struct { unsigned int pgd; } pgd_t; +typedef struct { unsigned long pmd; } pmd_t; +typedef struct { unsigned long pud; } pud_t; +typedef struct { unsigned long pgd; } pgd_t; typedef struct { unsigned long pgprot; } pgprot_t; #define pte_val(x) ((x).pte) #define pmd_val(x) ((x).pmd) +#define pud_val(x) ((x).pud) #define pgd_val(x) ((x).pgd) #define pgprot_val(x) ((x).pgprot) -#define __pte(x) ((pte_t) { (x) } ) -#define __pmd(x) ((pmd_t) { (x) } ) -#define __pgd(x) ((pgd_t) { (x) } ) -#define __pgprot(x) ((pgprot_t) { (x) } ) +#define __pte(x) ((pte_t) { (x) }) +#define __pmd(x) ((pmd_t) { (x) }) +#define __pud(x) ((pud_t) { (x) }) +#define __pgd(x) ((pgd_t) { (x) }) +#define __pgprot(x) ((pgprot_t) { (x) }) #else /* * .. while these make it easier on the compiler */ typedef unsigned long pte_t; -typedef unsigned int pmd_t; -typedef unsigned int pgd_t; +typedef unsigned long pmd_t; +typedef unsigned long pud_t; +typedef unsigned long pgd_t; typedef unsigned long pgprot_t; #define pte_val(x) (x) #define pmd_val(x) (x) +#define pud_val(x) (x) #define pgd_val(x) (x) #define pgprot_val(x) (x) #define __pte(x) (x) #define __pmd(x) (x) +#define __pud(x) (x) #define __pgd(x) (x) #define __pgprot(x) (x) @@ -208,9 +215,6 @@ #define USER_REGION_ID (0UL) #define REGION_ID(ea) (((unsigned long)(ea)) >> REGION_SHIFT) -#define __bpn_to_ba(x) ((((unsigned long)(x)) << PAGE_SHIFT) + KERNELBASE) -#define __ba_to_bpn(x) ((((unsigned long)(x)) & ~REGION_MASK) >> PAGE_SHIFT) - #define __va(x) ((void *)((unsigned long)(x) + KERNELBASE)) #ifdef CONFIG_DISCONTIGMEM Index: working-2.6/include/asm-ppc64/pgalloc.h =================================================================== --- working-2.6.orig/include/asm-ppc64/pgalloc.h 2005-08-04 13:22:21.000000000 +1000 +++ working-2.6/include/asm-ppc64/pgalloc.h 2005-08-04 13:22:36.000000000 +1000 @@ -6,7 +6,12 @@ #include #include -extern kmem_cache_t *zero_cache; +extern kmem_cache_t *pgtable_cache[]; + +#define PTE_CACHE_NUM 0 +#define PMD_CACHE_NUM 1 +#define PUD_CACHE_NUM 1 +#define PGD_CACHE_NUM 0 /* * This program is free software; you can redistribute it and/or @@ -15,30 +20,40 @@ * 2 of the License, or (at your option) any later version. */ -static inline pgd_t * -pgd_alloc(struct mm_struct *mm) +static inline pgd_t *pgd_alloc(struct mm_struct *mm) { - return kmem_cache_alloc(zero_cache, GFP_KERNEL); + return kmem_cache_alloc(pgtable_cache[PGD_CACHE_NUM], GFP_KERNEL); } -static inline void -pgd_free(pgd_t *pgd) +static inline void pgd_free(pgd_t *pgd) { - kmem_cache_free(zero_cache, pgd); + kmem_cache_free(pgtable_cache[PGD_CACHE_NUM], pgd); +} + +#define pgd_populate(MM, PGD, PUD) pgd_set(PGD, PUD) + +static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long addr) +{ + return kmem_cache_alloc(pgtable_cache[PUD_CACHE_NUM], + GFP_KERNEL|__GFP_REPEAT); +} + +static inline void pud_free(pud_t *pud) +{ + kmem_cache_free(pgtable_cache[PUD_CACHE_NUM], pud); } #define pud_populate(MM, PUD, PMD) pud_set(PUD, PMD) -static inline pmd_t * -pmd_alloc_one(struct mm_struct *mm, unsigned long addr) +static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr) { - return kmem_cache_alloc(zero_cache, GFP_KERNEL|__GFP_REPEAT); + return kmem_cache_alloc(pgtable_cache[PMD_CACHE_NUM], + GFP_KERNEL|__GFP_REPEAT); } -static inline void -pmd_free(pmd_t *pmd) +static inline void pmd_free(pmd_t *pmd) { - kmem_cache_free(zero_cache, pmd); + kmem_cache_free(pgtable_cache[PMD_CACHE_NUM], pmd); } #define pmd_populate_kernel(mm, pmd, pte) pmd_set(pmd, pte) @@ -47,44 +62,55 @@ static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) { - return kmem_cache_alloc(zero_cache, GFP_KERNEL|__GFP_REPEAT); + return kmem_cache_alloc(pgtable_cache[PTE_CACHE_NUM], + GFP_KERNEL|__GFP_REPEAT); } static inline struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address) { - pte_t *pte = kmem_cache_alloc(zero_cache, GFP_KERNEL|__GFP_REPEAT); - if (pte) - return virt_to_page(pte); - return NULL; + return virt_to_page(pte_alloc_one_kernel(mm, address)); } static inline void pte_free_kernel(pte_t *pte) { - kmem_cache_free(zero_cache, pte); + kmem_cache_free(pgtable_cache[PTE_CACHE_NUM], pte); } static inline void pte_free(struct page *ptepage) { - kmem_cache_free(zero_cache, page_address(ptepage)); + pte_free_kernel(page_address(ptepage)); } -struct pte_freelist_batch +#define PGF_CACHENUM_MASK 0xf + +typedef struct pgtable_free { + unsigned long val; +} pgtable_free_t; + +static inline pgtable_free_t pgtable_free_cache(void *p, int cachenum) { - struct rcu_head rcu; - unsigned int index; - struct page * pages[0]; -}; + BUG_ON((unsigned long)p & PGF_CACHENUM_MASK); + BUG_ON(cachenum & ~PGF_CACHENUM_MASK); + return (pgtable_free_t){.val = ((unsigned long) p) | cachenum}; +} -#define PTE_FREELIST_SIZE ((PAGE_SIZE - sizeof(struct pte_freelist_batch)) / \ - sizeof(struct page *)) +static inline void pgtable_free(pgtable_free_t pgf) +{ + void *p = (void *)(pgf.val & ~PGF_CACHENUM_MASK); + int cachenum = pgf.val & PGF_CACHENUM_MASK; -extern void pte_free_now(struct page *ptepage); -extern void pte_free_submit(struct pte_freelist_batch *batch); + kmem_cache_free(pgtable_cache[cachenum], p); +} -DECLARE_PER_CPU(struct pte_freelist_batch *, pte_freelist_cur); +void pgtable_free_tlb(struct mmu_gather *tlb, pgtable_free_t pgf); -void __pte_free_tlb(struct mmu_gather *tlb, struct page *ptepage); -#define __pmd_free_tlb(tlb, pmd) __pte_free_tlb(tlb, virt_to_page(pmd)) +#define __pte_free_tlb(tlb, ptepage) \ + pgtable_free_tlb(tlb, pgtable_free_cache(page_address(ptepage), \ + PTE_CACHE_NUM)) +#define __pmd_free_tlb(tlb, pmd) \ + pgtable_free_tlb(tlb, pgtable_free_cache(pmd, PMD_CACHE_NUM)) +#define __pud_free_tlb(tlb, pmd) \ + pgtable_free_tlb(tlb, pgtable_free_cache(pud, PUD_CACHE_NUM )) #define check_pgt_cache() do { } while (0) Index: working-2.6/arch/ppc64/mm/init.c =================================================================== --- working-2.6.orig/arch/ppc64/mm/init.c 2005-08-04 13:22:21.000000000 +1000 +++ working-2.6/arch/ppc64/mm/init.c 2005-08-04 13:22:36.000000000 +1000 @@ -66,6 +66,14 @@ #include #include +#if PGTABLE_RANGE > USER_VSID_RANGE +#warning Limited user VSID range means pagetable space is wasted +#endif + +#if (TASK_SIZE_USER64 < PGTABLE_RANGE) && (TASK_SIZE_USER64 < USER_VSID_RANGE) +#warning TASK_SIZE is smaller than it needs to be. +#endif + int mem_init_done; unsigned long ioremap_bot = IMALLOC_BASE; static unsigned long phbs_io_bot = PHBS_IO_BASE; @@ -226,7 +234,7 @@ * Before that, we map using addresses going * up from ioremap_bot. imalloc will use * the addresses from ioremap_bot through - * IMALLOC_END (0xE000001fffffffff) + * IMALLOC_END * */ pa = addr & PAGE_MASK; @@ -417,12 +425,6 @@ int index; int err; -#ifdef CONFIG_HUGETLB_PAGE - /* We leave htlb_segs as it was, but for a fork, we need to - * clear the huge_pgdir. */ - mm->context.huge_pgdir = NULL; -#endif - again: if (!idr_pre_get(&mmu_context_idr, GFP_KERNEL)) return -ENOMEM; @@ -453,8 +455,6 @@ spin_unlock(&mmu_context_lock); mm->context.id = NO_CONTEXT; - - hugetlb_mm_free_pgd(mm); } /* @@ -833,23 +833,43 @@ return virt_addr; } -kmem_cache_t *zero_cache; - -static void zero_ctor(void *pte, kmem_cache_t *cache, unsigned long flags) +static void zero_ctor(void *addr, kmem_cache_t *cache, unsigned long flags) { - memset(pte, 0, PAGE_SIZE); + memset(addr, 0, kmem_cache_size(cache)); } +static const int pgtable_cache_size[2] = { + PTE_TABLE_SIZE, PMD_TABLE_SIZE +}; +static const char *pgtable_cache_name[ARRAY_SIZE(pgtable_cache_size)] = { + "pgd_pte_cache", "pud_pmd_cache", +}; + +kmem_cache_t *pgtable_cache[ARRAY_SIZE(pgtable_cache_size)]; + void pgtable_cache_init(void) { - zero_cache = kmem_cache_create("zero", - PAGE_SIZE, - 0, - SLAB_HWCACHE_ALIGN | SLAB_MUST_HWCACHE_ALIGN, - zero_ctor, - NULL); - if (!zero_cache) - panic("pgtable_cache_init(): could not create zero_cache!\n"); + int i; + + BUILD_BUG_ON(PTE_TABLE_SIZE != pgtable_cache_size[PTE_CACHE_NUM]); + BUILD_BUG_ON(PMD_TABLE_SIZE != pgtable_cache_size[PMD_CACHE_NUM]); + BUILD_BUG_ON(PUD_TABLE_SIZE != pgtable_cache_size[PUD_CACHE_NUM]); + BUILD_BUG_ON(PGD_TABLE_SIZE != pgtable_cache_size[PGD_CACHE_NUM]); + + for (i = 0; i < ARRAY_SIZE(pgtable_cache_size); i++) { + int size = pgtable_cache_size[i]; + const char *name = pgtable_cache_name[i]; + + pgtable_cache[i] = kmem_cache_create(name, + size, size, + SLAB_HWCACHE_ALIGN + | SLAB_MUST_HWCACHE_ALIGN, + zero_ctor, + NULL); + if (! pgtable_cache[i]) + panic("pgtable_cache_init(): could not create %s!\n", + name); + } } pgprot_t phys_mem_access_prot(struct file *file, unsigned long addr, Index: working-2.6/include/asm-ppc64/processor.h =================================================================== --- working-2.6.orig/include/asm-ppc64/processor.h 2005-08-04 13:22:21.000000000 +1000 +++ working-2.6/include/asm-ppc64/processor.h 2005-08-04 13:22:22.000000000 +1000 @@ -382,8 +382,8 @@ extern struct task_struct *last_task_used_math; extern struct task_struct *last_task_used_altivec; -/* 64-bit user address space is 41-bits (2TBs user VM) */ -#define TASK_SIZE_USER64 (0x0000020000000000UL) +/* 64-bit user address space is 44-bits (16TB user VM) */ +#define TASK_SIZE_USER64 (0x0000100000000000UL) /* * 32-bit user address space is 4GB - 1 page Index: working-2.6/arch/ppc64/mm/imalloc.c =================================================================== --- working-2.6.orig/arch/ppc64/mm/imalloc.c 2005-08-04 13:22:21.000000000 +1000 +++ working-2.6/arch/ppc64/mm/imalloc.c 2005-08-04 13:22:22.000000000 +1000 @@ -31,7 +31,7 @@ break; if ((unsigned long)tmp->addr >= ioremap_bot) addr = tmp->size + (unsigned long) tmp->addr; - if (addr > IMALLOC_END-size) + if (addr >= IMALLOC_END-size) return 1; } *im_addr = addr; Index: working-2.6/arch/ppc64/mm/hash_utils.c =================================================================== --- working-2.6.orig/arch/ppc64/mm/hash_utils.c 2005-08-04 13:22:21.000000000 +1000 +++ working-2.6/arch/ppc64/mm/hash_utils.c 2005-08-04 13:22:22.000000000 +1000 @@ -302,7 +302,7 @@ int local = 0; cpumask_t tmp; - if ((ea & ~REGION_MASK) > EADDR_MASK) + if ((ea & ~REGION_MASK) >= PGTABLE_RANGE) return 1; switch (REGION_ID(ea)) { Index: working-2.6/include/asm-ppc64/mmu.h =================================================================== --- working-2.6.orig/include/asm-ppc64/mmu.h 2005-08-04 13:22:21.000000000 +1000 +++ working-2.6/include/asm-ppc64/mmu.h 2005-08-04 13:22:22.000000000 +1000 @@ -259,8 +259,10 @@ #define VSID_BITS 36 #define VSID_MODULUS ((1UL<index; i++) + pgtable_free(batch->tables[i]); + + free_page((unsigned long)batch); +} + +static void pte_free_submit(struct pte_freelist_batch *batch) +{ + INIT_RCU_HEAD(&batch->rcu); + call_rcu(&batch->rcu, pte_free_rcu_callback); +} + +void pgtable_free_tlb(struct mmu_gather *tlb, pgtable_free_t pgf) { /* This is safe as we are holding page_table_lock */ cpumask_t local_cpumask = cpumask_of_cpu(smp_processor_id()); @@ -49,19 +100,19 @@ if (atomic_read(&tlb->mm->mm_users) < 2 || cpus_equal(tlb->mm->cpu_vm_mask, local_cpumask)) { - pte_free(ptepage); + pgtable_free(pgf); return; } if (*batchp == NULL) { *batchp = (struct pte_freelist_batch *)__get_free_page(GFP_ATOMIC); if (*batchp == NULL) { - pte_free_now(ptepage); + pgtable_free_now(pgf); return; } (*batchp)->index = 0; } - (*batchp)->pages[(*batchp)->index++] = ptepage; + (*batchp)->tables[(*batchp)->index++] = pgf; if ((*batchp)->index == PTE_FREELIST_SIZE) { pte_free_submit(*batchp); *batchp = NULL; @@ -132,42 +183,6 @@ put_cpu(); } -#ifdef CONFIG_SMP -static void pte_free_smp_sync(void *arg) -{ - /* Do nothing, just ensure we sync with all CPUs */ -} -#endif - -/* This is only called when we are critically out of memory - * (and fail to get a page in pte_free_tlb). - */ -void pte_free_now(struct page *ptepage) -{ - pte_freelist_forced_free++; - - smp_call_function(pte_free_smp_sync, NULL, 0, 1); - - pte_free(ptepage); -} - -static void pte_free_rcu_callback(struct rcu_head *head) -{ - struct pte_freelist_batch *batch = - container_of(head, struct pte_freelist_batch, rcu); - unsigned int i; - - for (i = 0; i < batch->index; i++) - pte_free(batch->pages[i]); - free_page((unsigned long)batch); -} - -void pte_free_submit(struct pte_freelist_batch *batch) -{ - INIT_RCU_HEAD(&batch->rcu); - call_rcu(&batch->rcu, pte_free_rcu_callback); -} - void pte_free_finish(void) { /* This is safe as we are holding page_table_lock */ Index: working-2.6/arch/ppc64/mm/hugetlbpage.c =================================================================== --- working-2.6.orig/arch/ppc64/mm/hugetlbpage.c 2005-08-04 13:22:21.000000000 +1000 +++ working-2.6/arch/ppc64/mm/hugetlbpage.c 2005-08-04 13:22:22.000000000 +1000 @@ -27,124 +27,93 @@ #include -#define HUGEPGDIR_SHIFT (HPAGE_SHIFT + PAGE_SHIFT - 3) -#define HUGEPGDIR_SIZE (1UL << HUGEPGDIR_SHIFT) -#define HUGEPGDIR_MASK (~(HUGEPGDIR_SIZE-1)) - -#define HUGEPTE_INDEX_SIZE 9 -#define HUGEPGD_INDEX_SIZE 10 - -#define PTRS_PER_HUGEPTE (1 << HUGEPTE_INDEX_SIZE) -#define PTRS_PER_HUGEPGD (1 << HUGEPGD_INDEX_SIZE) - -static inline int hugepgd_index(unsigned long addr) +/* Modelled after find_linux_pte() */ +pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr) { - return (addr & ~REGION_MASK) >> HUGEPGDIR_SHIFT; -} + pgd_t *pg; + pud_t *pu; + pmd_t *pm; + pte_t *pt; -static pud_t *hugepgd_offset(struct mm_struct *mm, unsigned long addr) -{ - int index; + BUG_ON(! in_hugepage_area(mm->context, addr)); - if (! mm->context.huge_pgdir) - return NULL; + addr &= HPAGE_MASK; + pg = pgd_offset(mm, addr); + if (!pgd_none(*pg)) { + pu = pud_offset(pg, addr); + if (!pud_none(*pu)) { + pm = pmd_offset(pu, addr); + pt = (pte_t *)pm; + BUG_ON(!pmd_none(*pm) + && !(pte_present(*pt) && pte_huge(*pt))); + return pt; + } + } - index = hugepgd_index(addr); - BUG_ON(index >= PTRS_PER_HUGEPGD); - return (pud_t *)(mm->context.huge_pgdir + index); + return NULL; } -static inline pte_t *hugepte_offset(pud_t *dir, unsigned long addr) +pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr) { - int index; - - if (pud_none(*dir)) - return NULL; - - index = (addr >> HPAGE_SHIFT) % PTRS_PER_HUGEPTE; - return (pte_t *)pud_page(*dir) + index; -} + pgd_t *pg; + pud_t *pu; + pmd_t *pm; + pte_t *pt; -static pud_t *hugepgd_alloc(struct mm_struct *mm, unsigned long addr) -{ BUG_ON(! in_hugepage_area(mm->context, addr)); - if (! mm->context.huge_pgdir) { - pgd_t *new; - spin_unlock(&mm->page_table_lock); - /* Don't use pgd_alloc(), because we want __GFP_REPEAT */ - new = kmem_cache_alloc(zero_cache, GFP_KERNEL | __GFP_REPEAT); - BUG_ON(memcmp(new, empty_zero_page, PAGE_SIZE)); - spin_lock(&mm->page_table_lock); - - /* - * Because we dropped the lock, we should re-check the - * entry, as somebody else could have populated it.. - */ - if (mm->context.huge_pgdir) - pgd_free(new); - else - mm->context.huge_pgdir = new; - } - return hugepgd_offset(mm, addr); -} - -static pte_t *hugepte_alloc(struct mm_struct *mm, pud_t *dir, unsigned long addr) -{ - if (! pud_present(*dir)) { - pte_t *new; + addr &= HPAGE_MASK; - spin_unlock(&mm->page_table_lock); - new = kmem_cache_alloc(zero_cache, GFP_KERNEL | __GFP_REPEAT); - BUG_ON(memcmp(new, empty_zero_page, PAGE_SIZE)); - spin_lock(&mm->page_table_lock); - /* - * Because we dropped the lock, we should re-check the - * entry, as somebody else could have populated it.. - */ - if (pud_present(*dir)) { - if (new) - kmem_cache_free(zero_cache, new); - } else { - struct page *ptepage; + pg = pgd_offset(mm, addr); + pu = pud_alloc(mm, pg, addr); - if (! new) - return NULL; - ptepage = virt_to_page(new); - ptepage->mapping = (void *) mm; - ptepage->index = addr & HUGEPGDIR_MASK; - pud_populate(mm, dir, new); + if (pu) { + pm = pmd_alloc(mm, pu, addr); + if (pm) { + pt = (pte_t *)pm; + BUG_ON(!pmd_none(*pm) + && !(pte_present(*pt) && pte_huge(*pt))); + return pt; } } - return hugepte_offset(dir, addr); + return NULL; } -pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr) -{ - pud_t *pud; +#define HUGEPTE_BATCH_SIZE (HPAGE_SIZE / PMD_SIZE) - BUG_ON(! in_hugepage_area(mm->context, addr)); +void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, + pte_t *ptep, pte_t pte) +{ + int i; - pud = hugepgd_offset(mm, addr); - if (! pud) - return NULL; + if (pte_present(*ptep)) { + pte_clear(mm, addr, ptep); + flush_tlb_pending(); + } - return hugepte_offset(pud, addr); + for (i = 0; i < HUGEPTE_BATCH_SIZE; i++) { + *ptep = __pte(pte_val(pte) & ~_PAGE_HPTEFLAGS); + ptep++; + } } -pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr) +pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, + pte_t *ptep) { - pud_t *pud; + unsigned long old = pte_update(ptep, ~0UL); + int i; - BUG_ON(! in_hugepage_area(mm->context, addr)); + if (old & _PAGE_HASHPTE) + hpte_update(mm, addr, old, 0); - pud = hugepgd_alloc(mm, addr); - if (! pud) - return NULL; + for (i = 1; i < HUGEPTE_BATCH_SIZE; i++) { + *ptep = __pte(0); + ptep++; + } - return hugepte_alloc(mm, pud, addr); + return __pte(old); } /* @@ -541,42 +510,6 @@ } } -void hugetlb_mm_free_pgd(struct mm_struct *mm) -{ - int i; - pgd_t *pgdir; - - spin_lock(&mm->page_table_lock); - - pgdir = mm->context.huge_pgdir; - if (! pgdir) - goto out; - - mm->context.huge_pgdir = NULL; - - /* cleanup any hugepte pages leftover */ - for (i = 0; i < PTRS_PER_HUGEPGD; i++) { - pud_t *pud = (pud_t *)(pgdir + i); - - if (! pud_none(*pud)) { - pte_t *pte = (pte_t *)pud_page(*pud); - struct page *ptepage = virt_to_page(pte); - - ptepage->mapping = NULL; - - BUG_ON(memcmp(pte, empty_zero_page, PAGE_SIZE)); - kmem_cache_free(zero_cache, pte); - } - pud_clear(pud); - } - - BUG_ON(memcmp(pgdir, empty_zero_page, PAGE_SIZE)); - kmem_cache_free(zero_cache, pgdir); - - out: - spin_unlock(&mm->page_table_lock); -} - int hash_huge_page(struct mm_struct *mm, unsigned long access, unsigned long ea, unsigned long vsid, int local) { Index: working-2.6/arch/ppc64/mm/slb_low.S =================================================================== --- working-2.6.orig/arch/ppc64/mm/slb_low.S 2005-08-04 13:22:21.000000000 +1000 +++ working-2.6/arch/ppc64/mm/slb_low.S 2005-08-04 13:22:22.000000000 +1000 @@ -91,7 +91,7 @@ 0: /* user address: proto-VSID = context<<15 | ESID */ li r11,SLB_VSID_USER - srdi. r9,r3,13 + srdi. r9,r3,USER_ESID_BITS bne- 8f /* invalid ea bits set */ #ifdef CONFIG_HUGETLB_PAGE -- David Gibson | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/people/dgibson From michael at ellerman.id.au Thu Aug 4 17:14:56 2005 From: michael at ellerman.id.au (Michael Ellerman) Date: Thu, 4 Aug 2005 17:14:56 +1000 (EST) Subject: [PATCH 0/3] Make kexec work with ibmvscsi/ibmveth Message-ID: <1123139692.552248.494888583145.qpatch@concordia> On our Power5 we have vscsi and veth installed. When trying to kexec a new kernel the vscsi and veth initialisation fails because the previous kernel didn't clean up properly and as far as the Hypervisor is concerned is still connected. The fix is, perhaps, to add a shutdown() function to the vio_driver struct so that vscsi and veth have a chance to disconnect from the Hypervisor at reboot. The veth seems to work fine just by calling its remove method. Just calling remove didn't work for vscsi, so I trialed-and-errored and came up with something that works. With these patches I can kexec happily on our Power5 LPAR. cheers From michael at ellerman.id.au Thu Aug 4 17:14:58 2005 From: michael at ellerman.id.au (Michael Ellerman) Date: Thu, 4 Aug 2005 17:14:58 +1000 (EST) Subject: [PATCH 2/3] ibmvscsi: Add a shutdown() function to ibmvscsi In-Reply-To: <1123139692.552248.494888583145.qpatch@concordia> Message-ID: <20050804071458.F3AC067EB5@ozlabs.org> Add a shutdown() function to the ibmvscsi driver. I originally just used ibmvscsi_remove() for shutdown, but this was causing errors as something was trying to do I/O to the disk when we removed it. The following works for me on our Power5 box, in that it doesn't many errors on shutdown and it allows the ibmvscsi to come up again after kexec. It may not be the "Right Thing" to do though. Signed-off-by: Michael Ellerman drivers/scsi/ibmvscsi/ibmvscsi.c | 12 +++++++++++- 1 files changed, 11 insertions(+), 1 deletion(-) Index: kexec/drivers/scsi/ibmvscsi/ibmvscsi.c =================================================================== --- kexec.orig/drivers/scsi/ibmvscsi/ibmvscsi.c +++ kexec/drivers/scsi/ibmvscsi/ibmvscsi.c @@ -1436,6 +1436,15 @@ static int ibmvscsi_remove(struct vio_de return 0; } +static void ibmvscsi_shutdown(struct vio_dev *vdev) +{ + struct ibmvscsi_host_data *hostdata = vdev->dev.driver_data; + + atomic_set(&hostdata->request_limit, -1); + release_event_pool(&hostdata->pool, hostdata); + ibmvscsi_release_crq_queue(&hostdata->queue, hostdata, max_requests); +} + /** * ibmvscsi_device_table: Used by vio.c to match devices in the device tree we * support. @@ -1450,7 +1459,8 @@ static struct vio_driver ibmvscsi_driver .name = "ibmvscsi", .id_table = ibmvscsi_device_table, .probe = ibmvscsi_probe, - .remove = ibmvscsi_remove + .remove = ibmvscsi_remove, + .shutdown = ibmvscsi_shutdown }; int __init ibmvscsi_module_init(void) From michael at ellerman.id.au Thu Aug 4 17:14:58 2005 From: michael at ellerman.id.au (Michael Ellerman) Date: Thu, 4 Aug 2005 17:14:58 +1000 (EST) Subject: [PATCH 1/3] ppc64: Add a shutdown member to vio_driver In-Reply-To: <1123139692.552248.494888583145.qpatch@concordia> Message-ID: <20050804071458.1868D67EB2@ozlabs.org> Add a shutdown member to struct vio_driver. We also need vio_bus_shutdown() which converts from struct device to struct vio_dev and knows how to extract the struct vio_driver. Cleanup the vio_driver definition to fit 80 columns while we're there. Signed-off-by: Michael Ellerman arch/ppc64/kernel/vio.c | 13 +++++++++++++ include/asm-ppc64/vio.h | 16 +++++++++++++--- 2 files changed, 26 insertions(+), 3 deletions(-) Index: kexec/arch/ppc64/kernel/vio.c =================================================================== --- kexec.orig/arch/ppc64/kernel/vio.c +++ kexec/arch/ppc64/kernel/vio.c @@ -105,6 +105,18 @@ static int vio_bus_remove(struct device return 1; } +/* convert from struct device to struct vio_dev and pass to driver. */ +static void vio_bus_shutdown(struct device *dev) +{ + struct vio_dev *viodev = to_vio_dev(dev); + struct vio_driver *viodrv = to_vio_driver(dev->driver); + + DBGENTER(); + + if (viodrv->shutdown) + viodrv->shutdown(viodev); +} + /** * vio_register_driver: - Register a new vio driver * @drv: The vio_driver structure to be registered. @@ -119,6 +131,7 @@ int vio_register_driver(struct vio_drive viodrv->driver.bus = &vio_bus_type; viodrv->driver.probe = vio_bus_probe; viodrv->driver.remove = vio_bus_remove; + viodrv->driver.shutdown = vio_bus_shutdown; return driver_register(&viodrv->driver); } Index: kexec/include/asm-ppc64/vio.h =================================================================== --- kexec.orig/include/asm-ppc64/vio.h +++ kexec/include/asm-ppc64/vio.h @@ -69,9 +69,19 @@ struct vio_device_id { struct vio_driver { struct list_head node; char *name; - const struct vio_device_id *id_table; /* NULL if wants all devices */ - int (*probe) (struct vio_dev *dev, const struct vio_device_id *id); /* New device inserted */ - int (*remove) (struct vio_dev *dev); /* Device removed (NULL if not a hot-plug capable driver) */ + + /* NULL if wants all devices */ + const struct vio_device_id *id_table; + + /* New device inserted */ + int (*probe)(struct vio_dev *dev, const struct vio_device_id *id); + + /* Device removed (NULL if not a hot-plug capable driver) */ + int (*remove) (struct vio_dev *dev); + + /* Shutdown the device (NULL if no action required) */ + void (*shutdown) (struct vio_dev *dev); + unsigned long driver_data; struct device_driver driver; From michael at ellerman.id.au Thu Aug 4 17:15:00 2005 From: michael at ellerman.id.au (Michael Ellerman) Date: Thu, 4 Aug 2005 17:15:00 +1000 (EST) Subject: [PATCH 3/3] ibmveth: Add a shutdown() function to ibmveth In-Reply-To: <1123139692.552248.494888583145.qpatch@concordia> Message-ID: <20050804071500.783BC67EAB@ozlabs.org> Add a shutdown() function to the ibmveth driver. Simply calling ibmveth_remove() appears to be sufficient. I think I need to remove __devexit from ibmveth_remove(), because it will be called even when the driver's built in. Signed-off-by: Michael Ellerman drivers/net/ibmveth.c | 5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) Index: kexec/drivers/net/ibmveth.c =================================================================== --- kexec.orig/drivers/net/ibmveth.c +++ kexec/drivers/net/ibmveth.c @@ -994,7 +994,7 @@ static int __devinit ibmveth_probe(struc return 0; } -static int __devexit ibmveth_remove(struct vio_dev *dev) +static int ibmveth_remove(struct vio_dev *dev) { struct net_device *netdev = dev->dev.driver_data; struct ibmveth_adapter *adapter = netdev->priv; @@ -1153,7 +1153,8 @@ static struct vio_driver ibmveth_driver .name = (char *)ibmveth_driver_name, .id_table = ibmveth_device_table, .probe = ibmveth_probe, - .remove = ibmveth_remove + .remove = ibmveth_remove, + .shutdown = ibmveth_remove }; static int __init ibmveth_module_init(void) From benh at kernel.crashing.org Thu Aug 4 19:20:00 2005 From: benh at kernel.crashing.org (Benjamin Herrenschmidt) Date: Thu, 04 Aug 2005 11:20:00 +0200 Subject: Fan control for new PowerMac G5 2.7GHz machines? In-Reply-To: <42F14303.2000304@am.sony.com> References: <1123099081.30257.41.camel@gaston> <42F14303.2000304@am.sony.com> Message-ID: <1123147202.30257.50.camel@gaston> > > i2c /dev entries driver > /u3 at 0,f8000000/i2c at f8001000: Missing interrupt or address ! > > In therm_pm72_attach() it hits 'Found K2', but u3_0 and u3_1 > are never set, so start_control_loops() is never called. > > I'll look at it more when I have some time. Ah yes, this is indeed the problem ! There is a bug in Apple device tree on these machines that is breaking Linux. I should have a workaround upstream, but for some reason, it seems it's not working for you. Can you look at arch/ppc64/kernel/prom_init.c, more specifically, the function static void __init fixup_device_tree(void) And see if it's going all the way to the fixup code at the end or not ? If not, then one of the tests isn't triggering the right way on your machine, possibly the U3 revision. Ben. From schwab at suse.de Thu Aug 4 22:08:43 2005 From: schwab at suse.de (Andreas Schwab) Date: Thu, 04 Aug 2005 14:08:43 +0200 Subject: [PATCH] PPC64: Fix UP kernel build In-Reply-To: <20050804013010.GA10556@austin.ibm.com> (Olof Johansson's message of "Wed, 3 Aug 2005 20:30:10 -0500") References: <20050804013010.GA10556@austin.ibm.com> Message-ID: Olof Johansson writes: > Index: 2.6/arch/ppc64/kernel/machine_kexec.c > =================================================================== > --- 2.6.orig/arch/ppc64/kernel/machine_kexec.c 2005-08-03 19:53:16.000000000 -0500 > +++ 2.6/arch/ppc64/kernel/machine_kexec.c 2005-08-03 20:39:49.000000000 -0500 > @@ -243,13 +243,17 @@ static void kexec_prepare_cpus(void) > > static void kexec_prepare_cpus(void) > { > + extern void smp_release_cpus(void); Please put this in a header. Andreas. -- Andreas Schwab, SuSE Labs, schwab at suse.de SuSE Linux Products GmbH, Maxfeldstra?e 5, 90409 N?rnberg, Germany Key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5 "And now for something completely different." From boutcher at us.ibm.com Fri Aug 5 00:31:37 2005 From: boutcher at us.ibm.com (David Boutcher) Date: Thu, 4 Aug 2005 09:31:37 -0500 Subject: [PATCH 0/3] Make kexec work with ibmvscsi/ibmveth In-Reply-To: <1123139692.552248.494888583145.qpatch@concordia> Message-ID: Michael Ellerman wrote on 08/04/2005 02:14:56 AM: > On our Power5 we have vscsi and veth installed. When trying to kexec a new > kernel the vscsi and veth initialisation fails because the previous kernel > didn't clean up properly and as far as the Hypervisor is concerned is still > connected. > > The fix is, perhaps, to add a shutdown() function to the vio_driver struct so > that vscsi and veth have a chance to disconnect from the Hypervisor at reboot. > > The veth seems to work fine just by calling its remove method. > > Just calling remove didn't work for vscsi, so I trialed-and-errored and came > up with something that works. > > With these patches I can kexec happily on our Power5 LPAR. Hmmm....before we commit this I would prefer to figure out why vscsi remove doesn't work. I'll dig into that. Dave Boutcher IBM Linux Technology Center From olh at suse.de Fri Aug 5 03:26:42 2005 From: olh at suse.de (Olaf Hering) Date: Thu, 4 Aug 2005 19:26:42 +0200 Subject: [PATCH] allow xmon=off on ppc64 Message-ID: <20050804172642.GA23306@suse.de> If both CONFIG_XMON and CONFIG_XMON_DEFAULT is enabled in the .config, there is no way to disable xmon again. setup_system calls first xmon_init, later parse_early_param. So a new 'xmon=off' cmdline option will do the right thing. Signed-off-by: Olaf Hering arch/ppc64/kernel/setup.c | 8 +++++--- arch/ppc64/xmon/start.c | 2 +- arch/ppc64/xmon/xmon.c | 26 ++++++++++++++++++-------- include/asm-ppc64/system.h | 2 +- 4 files changed, 25 insertions(+), 13 deletions(-) Index: linux-2.6.12/arch/ppc64/kernel/setup.c =================================================================== --- linux-2.6.12.orig/arch/ppc64/kernel/setup.c +++ linux-2.6.12/arch/ppc64/kernel/setup.c @@ -627,7 +627,7 @@ void __init setup_system(void) * Initialize xmon */ #ifdef CONFIG_XMON_DEFAULT - xmon_init(); + xmon_init(1); #endif /* * Register early console @@ -1350,11 +1350,13 @@ static int __init early_xmon(char *p) /* ensure xmon is enabled */ if (p) { if (strncmp(p, "on", 2) == 0) - xmon_init(); + xmon_init(1); + if (strncmp(p, "off", 3) == 0) + xmon_init(0); if (strncmp(p, "early", 5) != 0) return 0; } - xmon_init(); + xmon_init(1); debugger(NULL); return 0; Index: linux-2.6.12/arch/ppc64/xmon/start.c =================================================================== --- linux-2.6.12.orig/arch/ppc64/xmon/start.c +++ linux-2.6.12/arch/ppc64/xmon/start.c @@ -27,7 +27,7 @@ static void sysrq_handle_xmon(int key, s struct tty_struct *tty) { /* ensure xmon is enabled */ - xmon_init(); + xmon_init(1); debugger(pt_regs); } Index: linux-2.6.12/arch/ppc64/xmon/xmon.c =================================================================== --- linux-2.6.12.orig/arch/ppc64/xmon/xmon.c +++ linux-2.6.12/arch/ppc64/xmon/xmon.c @@ -2496,15 +2496,25 @@ static void dump_stab(void) } } -void xmon_init(void) +void xmon_init(int enable) { - __debugger = xmon; - __debugger_ipi = xmon_ipi; - __debugger_bpt = xmon_bpt; - __debugger_sstep = xmon_sstep; - __debugger_iabr_match = xmon_iabr_match; - __debugger_dabr_match = xmon_dabr_match; - __debugger_fault_handler = xmon_fault_handler; + if (enable) { + __debugger = xmon; + __debugger_ipi = xmon_ipi; + __debugger_bpt = xmon_bpt; + __debugger_sstep = xmon_sstep; + __debugger_iabr_match = xmon_iabr_match; + __debugger_dabr_match = xmon_dabr_match; + __debugger_fault_handler = xmon_fault_handler; + } else { + __debugger = NULL; + __debugger_ipi = NULL; + __debugger_bpt = NULL; + __debugger_sstep = NULL; + __debugger_iabr_match = NULL; + __debugger_dabr_match = NULL; + __debugger_fault_handler = NULL; + } } void dump_segments(void) Index: linux-2.6.12/include/asm-ppc64/system.h =================================================================== --- linux-2.6.12.orig/include/asm-ppc64/system.h +++ linux-2.6.12/include/asm-ppc64/system.h @@ -88,7 +88,7 @@ DEBUGGER_BOILERPLATE(debugger_dabr_match DEBUGGER_BOILERPLATE(debugger_fault_handler) #ifdef CONFIG_XMON -extern void xmon_init(void); +extern void xmon_init(int enable); #endif #else From olh at suse.de Fri Aug 5 03:28:09 2005 From: olh at suse.de (Olaf Hering) Date: Thu, 4 Aug 2005 19:28:09 +0200 Subject: [PATCH] update xmon helptext In-Reply-To: <20050804172642.GA23306@suse.de> References: <20050804172642.GA23306@suse.de> Message-ID: <20050804172809.GB23306@suse.de> xmon will do nothing but noise on a G5 if BOOTX_TEXT is not enabled. mention the recognized kernel cmdline options for xmon. Signed-off-by: Olaf Hering arch/ppc64/Kconfig.debug | 9 +++++++++ 1 files changed, 9 insertions(+) Index: linux-2.6.12/arch/ppc64/Kconfig.debug =================================================================== --- linux-2.6.12.orig/arch/ppc64/Kconfig.debug +++ linux-2.6.12/arch/ppc64/Kconfig.debug @@ -41,10 +41,19 @@ config XMON help Include in-kernel hooks for the xmon kernel monitor/debugger. Unless you are intending to debug the kernel, say N here. + Make sure to enable also CONFIG_BOOTX_TEXT on Macs. Otherwise + nothing will appear on the screen (xmon writes directly to the + framebuffer memory). + The cmdline option 'xmon' or 'xmon=early' will drop into xmon very + early during boot. 'xmon=on' will just enable the xmon debugger hooks. + 'xmon=off' will disable the debugger hooks if CONFIG_XMON_DEFAULT is set. config XMON_DEFAULT bool "Enable xmon by default" depends on XMON + help + xmon is normally disabled unless booted with 'xmon=on'. + Use 'xmon=off' to disable xmon init during runtime. config PPCDBG bool "Include PPCDBG realtime debugging" From paulus at samba.org Fri Aug 5 08:39:01 2005 From: paulus at samba.org (Paul Mackerras) Date: Fri, 5 Aug 2005 08:39:01 +1000 Subject: [PATCH 0/3] Make kexec work with ibmvscsi/ibmveth In-Reply-To: <1123139692.552248.494888583145.qpatch@concordia> References: <1123139692.552248.494888583145.qpatch@concordia> Message-ID: <17138.39173.312034.227658@cargo.ozlabs.ibm.com> Michael Ellerman writes: > On our Power5 we have vscsi and veth installed. When trying to kexec a new > kernel the vscsi and veth initialisation fails because the previous kernel > didn't clean up properly and as far as the Hypervisor is concerned is still > connected. > > The fix is, perhaps, to add a shutdown() function to the vio_driver struct so > that vscsi and veth have a chance to disconnect from the Hypervisor at reboot. But if we are using kexec to do kdump, and the kernel panics, the driver's shutdown method won't get called. We should instead harden the driver so that it can cope with the error from the hypervisor and recover, I think. Paul. From haren at us.ibm.com Fri Aug 5 10:44:33 2005 From: haren at us.ibm.com (Haren Myneni) Date: Thu, 04 Aug 2005 17:44:33 -0700 Subject: [PATCH 0/3] Make kexec work with ibmvscsi/ibmveth In-Reply-To: References: Message-ID: <42F2B671.2030207@us.ibm.com> > > Michael Ellerman writes: > > > On our Power5 we have vscsi and veth installed. When trying to kexec > a new > > kernel the vscsi and veth initialisation fails because the previous > kernel > > didn't clean up properly and as far as the Hypervisor is concerned > is still > > connected. > > > > The fix is, perhaps, to add a shutdown() function to the vio_driver > struct so > > that vscsi and veth have a chance to disconnect from the Hypervisor > at reboot. > > But if we are using kexec to do kdump, and the kernel panics, the > driver's shutdown method won't get called. We should instead harden > the driver so that it can cope with the error from the hypervisor and > recover, I think. > > Paul. > BTW, When I tested kexec boot without calling device_shutdown(), had the device initialization issue for IPR. However, the system was booted with some EEH traces after I applied Linas's EEH Error recovery patches (reset the PCI slot). I need to do some more testing. Thanks Haren But, in the normal kexec boot, > _______________________________________________ > Linuxppc64-dev mailing list > Linuxppc64-dev at ozlabs.org > https://ozlabs.org/mailman/listinfo/linuxppc64-dev > From michael at ellerman.id.au Fri Aug 5 11:21:54 2005 From: michael at ellerman.id.au (Michael Ellerman) Date: Fri, 5 Aug 2005 11:21:54 +1000 Subject: [PATCH 0/3] Make kexec work with ibmvscsi/ibmveth In-Reply-To: <17138.39173.312034.227658@cargo.ozlabs.ibm.com> References: <1123139692.552248.494888583145.qpatch@concordia> <17138.39173.312034.227658@cargo.ozlabs.ibm.com> Message-ID: <200508051121.54574.michael@ellerman.id.au> On Fri, 5 Aug 2005 08:39, Paul Mackerras wrote: > Michael Ellerman writes: > > On our Power5 we have vscsi and veth installed. When trying to kexec a > > new kernel the vscsi and veth initialisation fails because the previous > > kernel didn't clean up properly and as far as the Hypervisor is concerned > > is still connected. > > > > The fix is, perhaps, to add a shutdown() function to the vio_driver > > struct so that vscsi and veth have a chance to disconnect from the > > Hypervisor at reboot. > > But if we are using kexec to do kdump, and the kernel panics, the > driver's shutdown method won't get called. We should instead harden > the driver so that it can cope with the error from the hypervisor and > recover, I think. You're right, that's a much better idea. cheers -- Michael Ellerman IBM OzLabs email: michael:ellerman.id.au inmsg: mpe:jabber.org wwweb: http://michael.ellerman.id.au phone: +61 2 6212 1183 (tie line 70 21183) We do not inherit the earth from our ancestors, we borrow it from our children. - S.M.A.R.T Person -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: not available Url : http://ozlabs.org/pipermail/linuxppc64-dev/attachments/20050805/145b12ad/attachment.pgp From olof at lixom.net Fri Aug 5 14:02:26 2005 From: olof at lixom.net (Olof Johansson) Date: Thu, 4 Aug 2005 23:02:26 -0500 Subject: [PATCH] PPC64: Add VMX save flag to VPA Message-ID: <20050805040225.GA13865@austin.ibm.com> Hi, We need to indicate to the hypervisor that it needs to save our VMX registers when switching partitions on a shared-processor system, just as it needs to for FP and PMC registers. This could be made to be on-demand when VMX is used, but we don't do that for FP nor PMC right now either so let's not overcomplicate things. Signed-off-by: Olof Johansson Index: 2.6/arch/ppc64/kernel/pacaData.c =================================================================== --- 2.6.orig/arch/ppc64/kernel/pacaData.c 2005-08-03 19:53:16.000000000 -0500 +++ 2.6/arch/ppc64/kernel/pacaData.c 2005-08-04 19:26:26.000000000 -0500 @@ -59,6 +59,7 @@ extern unsigned long __toc_start; .fpregs_in_use = 1, \ .end_of_quantum = 0xfffffffffffffffful, \ .slb_count = 64, \ + .vmxregs_in_use = 0, \ }, \ #ifdef CONFIG_PPC_ISERIES Index: 2.6/include/asm-ppc64/lppaca.h =================================================================== --- 2.6.orig/include/asm-ppc64/lppaca.h 2005-08-04 19:25:54.000000000 -0500 +++ 2.6/include/asm-ppc64/lppaca.h 2005-08-04 19:26:15.000000000 -0500 @@ -108,7 +108,7 @@ struct lppaca volatile u32 virtual_decr; // Virtual DECR for shared procsx78-x7B u16 slb_count; // # of SLBs to maintain x7C-x7D u8 idle; // Indicate OS is idle x7E - u8 reserved5; // Reserved x7F + u8 vmxregs_in_use; // VMX registers in use x7F //============================================================================= Index: 2.6/arch/ppc64/kernel/pSeries_lpar.c =================================================================== --- 2.6.orig/arch/ppc64/kernel/pSeries_lpar.c 2005-08-03 19:53:16.000000000 -0500 +++ 2.6/arch/ppc64/kernel/pSeries_lpar.c 2005-08-04 19:35:41.000000000 -0500 @@ -267,6 +267,10 @@ void vpa_init(int cpu) /* Register the Virtual Processor Area (VPA) */ flags = 1UL << (63 - 18); + + if (cpu_has_feature(CPU_FTR_ALTIVEC)) + paca[cpu].lppaca.vmxregs_in_use = 1; + ret = register_vpa(flags, hwcpu, __pa(vpa)); if (ret) From sfr at canb.auug.org.au Fri Aug 5 17:47:05 2005 From: sfr at canb.auug.org.au (Stephen Rothwell) Date: Fri, 5 Aug 2005 17:47:05 +1000 Subject: [PATCH] 1/2 Start header file merger (Was: Re: Beginning Merger Patch) In-Reply-To: <688ba2276de281a9473b030a16a514c0@embeddededge.com> References: <1123023575.2614.25.camel@cashmere.sps.mot.com> <688ba2276de281a9473b030a16a514c0@embeddededge.com> Message-ID: <20050805174705.731ffa05.sfr@canb.auug.org.au> On Tue, 2 Aug 2005 19:10:56 -0400 Dan Malek wrote: > > On Aug 2, 2005, at 6:59 PM, Jon Loeliger wrote: > > > ..... A stub is left > > in asm-ppc and asm-ppc64 pointing to the unified files. > > Why bother? You may as well change all of the source > files, too, or else that will never get done :-) You actually don't need to modify (m)any source files. Here is an alternative approach. These patches depend on Olaf's boot code cleanup for ppc64 (or similar). Do the following: cd linux/include mkdir asm-powerpc cd asm-ppc for i in * do [ -e ../asm-ppc64/$i ] || mv $i ../asm-powerpc/$i done cd ../asm-ppc64 for i in * do [ -e ../asm-ppc/$i ] || mv $i ../asm-powerpc/$i done for i in * do [ -f ../asm-ppc64/$i ] && cmp -s $i ../asm-ppc64/$i && mv $i ../asm-powerpc/$i && rm ../asm-ppc64/$i done Then apply the patch below and the patch in the following email. I have built this kernel for ppc (defconfig), ppc64 (iSeries, pSeries and pmac). -- Cheers, Stephen Rothwell sfr at canb.auug.org.au http://www.canb.auug.org.au/~sfr/ diff -ruNp linus-powerpc.xx/arch/ppc/Makefile linus-powerpc.1/arch/ppc/Makefile --- linus-powerpc.xx/arch/ppc/Makefile 2005-06-27 16:08:00.000000000 +1000 +++ linus-powerpc.1/arch/ppc/Makefile 2005-08-05 11:19:25.000000000 +1000 @@ -21,11 +21,13 @@ CC := $(CC) -m32 endif LDFLAGS_vmlinux := -Ttext $(KERNELLOAD) -Bstatic -CPPFLAGS += -Iarch/$(ARCH) +CPPFLAGS += -Iarch/$(ARCH) -Iinclude3 AFLAGS += -Iarch/$(ARCH) CFLAGS += -Iarch/$(ARCH) -msoft-float -pipe \ -ffixed-r2 -mmultiple CPP = $(CC) -E $(CFLAGS) +# Temporary hack until we have migrated to asm-powerpc +LINUXINCLUDE += -Iinclude3 CHECKFLAGS += -D__powerpc__ @@ -101,6 +103,7 @@ endef archclean: $(Q)$(MAKE) $(clean)=arch/ppc/boot + $(Q)rm -rf include3 prepare: include/asm-$(ARCH)/offsets.h checkbin @@ -110,6 +113,12 @@ arch/$(ARCH)/kernel/asm-offsets.s: inclu include/asm-$(ARCH)/offsets.h: arch/$(ARCH)/kernel/asm-offsets.s $(call filechk,gen-asm-offsets) +# Temporary hack until we have migrated to asm-powerpc +include/asm: include3/asm +include3/asm: + $(Q)if [ ! -d include3 ]; then mkdir -p include3; fi; + $(Q)ln -fsn $(srctree)/include/asm-powerpc include3/asm + # Use the file '.tmp_gas_check' for binutils tests, as gas won't output # to stdout and these checks are run even on install targets. TOUT := .tmp_gas_check diff -ruNp linus-powerpc.xx/arch/ppc64/Makefile linus-powerpc.1/arch/ppc64/Makefile --- linus-powerpc.xx/arch/ppc64/Makefile 2005-06-27 16:08:00.000000000 +1000 +++ linus-powerpc.1/arch/ppc64/Makefile 2005-08-05 11:19:50.000000000 +1000 @@ -55,6 +55,8 @@ LDFLAGS := -m elf64ppc LDFLAGS_vmlinux := -Bstatic -e $(KERNELLOAD) -Ttext $(KERNELLOAD) CFLAGS += -msoft-float -pipe -mminimal-toc -mtraceback=none \ -mcall-aixdesc +# Temporary hack until we have migrated to asm-powerpc +CPPFLAGS += -Iinclude3 GCC_VERSION := $(call cc-version) GCC_BROKEN_VEC := $(shell if [ $(GCC_VERSION) -lt 0400 ] ; then echo "y"; fi ;) @@ -112,6 +114,7 @@ all: $(KBUILD_IMAGE) archclean: $(Q)$(MAKE) $(clean)=$(boot) + $(Q)rm -rf include3 prepare: include/asm-ppc64/offsets.h @@ -121,6 +124,12 @@ arch/ppc64/kernel/asm-offsets.s: include include/asm-ppc64/offsets.h: arch/ppc64/kernel/asm-offsets.s $(call filechk,gen-asm-offsets) +# Temporary hack until we have migrated to asm-powerpc +include/asm: include3/asm +include3/asm: + $(Q)if [ ! -d include3 ]; then mkdir -p include3; fi; + $(Q)ln -fsn $(srctree)/include/asm-powerpc include3/asm + define archhelp echo '* zImage - Compressed kernel image (arch/$(ARCH)/boot/zImage)' echo ' zImage.initrd- Compressed kernel image with initrd attached,' From sfr at canb.auug.org.au Fri Aug 5 17:50:09 2005 From: sfr at canb.auug.org.au (Stephen Rothwell) Date: Fri, 5 Aug 2005 17:50:09 +1000 Subject: [PATCH] 2/2 merge the easy ones In-Reply-To: <20050805174705.731ffa05.sfr@canb.auug.org.au> References: <1123023575.2614.25.camel@cashmere.sps.mot.com> <688ba2276de281a9473b030a16a514c0@embeddededge.com> <20050805174705.731ffa05.sfr@canb.auug.org.au> Message-ID: <20050805175009.48761e9e.sfr@canb.auug.org.au> Here is the rest of the easy headers to merge. -- Cheers, Stephen Rothwell sfr at canb.auug.org.au http://www.canb.auug.org.au/~sfr/ diff -ruNp linus-powerpc.1a/include/asm-powerpc/cputime.h linus-powerpc.2/include/asm-powerpc/cputime.h --- linus-powerpc.1a/include/asm-powerpc/cputime.h 2005-06-27 16:08:08.000000000 +1000 +++ linus-powerpc.2/include/asm-powerpc/cputime.h 2005-08-05 15:04:55.000000000 +1000 @@ -1,6 +1 @@ -#ifndef __PPC_CPUTIME_H -#define __PPC_CPUTIME_H - #include - -#endif /* __PPC_CPUTIME_H */ diff -ruNp linus-powerpc.1a/include/asm-powerpc/div64.h linus-powerpc.2/include/asm-powerpc/div64.h --- linus-powerpc.1a/include/asm-powerpc/div64.h 2005-06-27 16:08:08.000000000 +1000 +++ linus-powerpc.2/include/asm-powerpc/div64.h 1970-01-01 10:00:00.000000000 +1000 @@ -1 +0,0 @@ -#include diff -ruNp linus-powerpc.1a/include/asm-powerpc/emergency-restart.h linus-powerpc.2/include/asm-powerpc/emergency-restart.h --- linus-powerpc.1a/include/asm-powerpc/emergency-restart.h 2005-07-27 10:17:26.000000000 +1000 +++ linus-powerpc.2/include/asm-powerpc/emergency-restart.h 2005-08-05 15:04:55.000000000 +1000 @@ -1,6 +1 @@ -#ifndef _ASM_EMERGENCY_RESTART_H -#define _ASM_EMERGENCY_RESTART_H - #include - -#endif /* _ASM_EMERGENCY_RESTART_H */ diff -ruNp linus-powerpc.1a/include/asm-powerpc/errno.h linus-powerpc.2/include/asm-powerpc/errno.h --- linus-powerpc.1a/include/asm-powerpc/errno.h 1970-01-01 10:00:00.000000000 +1000 +++ linus-powerpc.2/include/asm-powerpc/errno.h 2005-08-05 15:04:55.000000000 +1000 @@ -0,0 +1,11 @@ +#ifndef _ASM_ERRNO_H +#define _ASM_ERRNO_H + +#include + +#undef EDEADLOCK +#define EDEADLOCK 58 /* File locking deadlock error */ + +#define _LAST_ERRNO 516 + +#endif /* _ASM_ERRNO_H */ diff -ruNp linus-powerpc.1a/include/asm-powerpc/ioctl.h linus-powerpc.2/include/asm-powerpc/ioctl.h --- linus-powerpc.1a/include/asm-powerpc/ioctl.h 1970-01-01 10:00:00.000000000 +1000 +++ linus-powerpc.2/include/asm-powerpc/ioctl.h 2005-08-05 15:04:55.000000000 +1000 @@ -0,0 +1,69 @@ +#ifndef _ASM_IOCTL_H +#define _ASM_IOCTL_H + + +/* + * This was copied from the alpha as it's a bit cleaner there. + * -- Cort + */ + +#define _IOC_NRBITS 8 +#define _IOC_TYPEBITS 8 +#define _IOC_SIZEBITS 13 +#define _IOC_DIRBITS 3 + +#define _IOC_NRMASK ((1 << _IOC_NRBITS)-1) +#define _IOC_TYPEMASK ((1 << _IOC_TYPEBITS)-1) +#define _IOC_SIZEMASK ((1 << _IOC_SIZEBITS)-1) +#define _IOC_DIRMASK ((1 << _IOC_DIRBITS)-1) + +#define _IOC_NRSHIFT 0 +#define _IOC_TYPESHIFT (_IOC_NRSHIFT+_IOC_NRBITS) +#define _IOC_SIZESHIFT (_IOC_TYPESHIFT+_IOC_TYPEBITS) +#define _IOC_DIRSHIFT (_IOC_SIZESHIFT+_IOC_SIZEBITS) + +/* + * Direction bits _IOC_NONE could be 0, but OSF/1 gives it a bit. + * And this turns out useful to catch old ioctl numbers in header + * files for us. + */ +#define _IOC_NONE 1U +#define _IOC_READ 2U +#define _IOC_WRITE 4U + +#define _IOC(dir,type,nr,size) \ + (((dir) << _IOC_DIRSHIFT) | \ + ((type) << _IOC_TYPESHIFT) | \ + ((nr) << _IOC_NRSHIFT) | \ + ((size) << _IOC_SIZESHIFT)) + +/* provoke compile error for invalid uses of size argument */ +extern unsigned int __invalid_size_argument_for_IOC; +#define _IOC_TYPECHECK(t) \ + ((sizeof(t) == sizeof(t[1]) && \ + sizeof(t) < (1 << _IOC_SIZEBITS)) ? \ + sizeof(t) : __invalid_size_argument_for_IOC) + +/* used to create numbers */ +#define _IO(type,nr) _IOC(_IOC_NONE,(type),(nr),0) +#define _IOR(type,nr,size) _IOC(_IOC_READ,(type),(nr),(_IOC_TYPECHECK(size))) +#define _IOW(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size))) +#define _IOWR(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size))) +#define _IOR_BAD(type,nr,size) _IOC(_IOC_READ,(type),(nr),sizeof(size)) +#define _IOW_BAD(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),sizeof(size)) +#define _IOWR_BAD(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size)) + +/* used to decode them.. */ +#define _IOC_DIR(nr) (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK) +#define _IOC_TYPE(nr) (((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK) +#define _IOC_NR(nr) (((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK) +#define _IOC_SIZE(nr) (((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK) + +/* various drivers, such as the pcmcia stuff, need these... */ +#define IOC_IN (_IOC_WRITE << _IOC_DIRSHIFT) +#define IOC_OUT (_IOC_READ << _IOC_DIRSHIFT) +#define IOC_INOUT ((_IOC_WRITE|_IOC_READ) << _IOC_DIRSHIFT) +#define IOCSIZE_MASK (_IOC_SIZEMASK << _IOC_SIZESHIFT) +#define IOCSIZE_SHIFT (_IOC_SIZESHIFT) + +#endif /* _ASM_IOCTL_H */ diff -ruNp linus-powerpc.1a/include/asm-powerpc/ioctls.h linus-powerpc.2/include/asm-powerpc/ioctls.h --- linus-powerpc.1a/include/asm-powerpc/ioctls.h 1970-01-01 10:00:00.000000000 +1000 +++ linus-powerpc.2/include/asm-powerpc/ioctls.h 2005-08-05 15:04:55.000000000 +1000 @@ -0,0 +1,107 @@ +#ifndef _ASM_IOCTLS_H +#define _ASM_IOCTLS_H + +#include + +#define FIOCLEX _IO('f', 1) +#define FIONCLEX _IO('f', 2) +#define FIOASYNC _IOW('f', 125, int) +#define FIONBIO _IOW('f', 126, int) +#define FIONREAD _IOR('f', 127, int) +#define TIOCINQ FIONREAD +#define FIOQSIZE _IOR('f', 128, loff_t) + +#define TIOCGETP _IOR('t', 8, struct sgttyb) +#define TIOCSETP _IOW('t', 9, struct sgttyb) +#define TIOCSETN _IOW('t', 10, struct sgttyb) /* TIOCSETP wo flush */ + +#define TIOCSETC _IOW('t', 17, struct tchars) +#define TIOCGETC _IOR('t', 18, struct tchars) +#define TCGETS _IOR('t', 19, struct termios) +#define TCSETS _IOW('t', 20, struct termios) +#define TCSETSW _IOW('t', 21, struct termios) +#define TCSETSF _IOW('t', 22, struct termios) + +#define TCGETA _IOR('t', 23, struct termio) +#define TCSETA _IOW('t', 24, struct termio) +#define TCSETAW _IOW('t', 25, struct termio) +#define TCSETAF _IOW('t', 28, struct termio) + +#define TCSBRK _IO('t', 29) +#define TCXONC _IO('t', 30) +#define TCFLSH _IO('t', 31) + +#define TIOCSWINSZ _IOW('t', 103, struct winsize) +#define TIOCGWINSZ _IOR('t', 104, struct winsize) +#define TIOCSTART _IO('t', 110) /* start output, like ^Q */ +#define TIOCSTOP _IO('t', 111) /* stop output, like ^S */ +#define TIOCOUTQ _IOR('t', 115, int) /* output queue size */ + +#define TIOCGLTC _IOR('t', 116, struct ltchars) +#define TIOCSLTC _IOW('t', 117, struct ltchars) +#define TIOCSPGRP _IOW('t', 118, int) +#define TIOCGPGRP _IOR('t', 119, int) + +#define TIOCEXCL 0x540C +#define TIOCNXCL 0x540D +#define TIOCSCTTY 0x540E + +#define TIOCSTI 0x5412 +#define TIOCMGET 0x5415 +#define TIOCMBIS 0x5416 +#define TIOCMBIC 0x5417 +#define TIOCMSET 0x5418 +# define TIOCM_LE 0x001 +# define TIOCM_DTR 0x002 +# define TIOCM_RTS 0x004 +# define TIOCM_ST 0x008 +# define TIOCM_SR 0x010 +# define TIOCM_CTS 0x020 +# define TIOCM_CAR 0x040 +# define TIOCM_RNG 0x080 +# define TIOCM_DSR 0x100 +# define TIOCM_CD TIOCM_CAR +# define TIOCM_RI TIOCM_RNG + +#define TIOCGSOFTCAR 0x5419 +#define TIOCSSOFTCAR 0x541A +#define TIOCLINUX 0x541C +#define TIOCCONS 0x541D +#define TIOCGSERIAL 0x541E +#define TIOCSSERIAL 0x541F +#define TIOCPKT 0x5420 +# define TIOCPKT_DATA 0 +# define TIOCPKT_FLUSHREAD 1 +# define TIOCPKT_FLUSHWRITE 2 +# define TIOCPKT_STOP 4 +# define TIOCPKT_START 8 +# define TIOCPKT_NOSTOP 16 +# define TIOCPKT_DOSTOP 32 + + +#define TIOCNOTTY 0x5422 +#define TIOCSETD 0x5423 +#define TIOCGETD 0x5424 +#define TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */ +#define TIOCSBRK 0x5427 /* BSD compatibility */ +#define TIOCCBRK 0x5428 /* BSD compatibility */ +#define TIOCGSID 0x5429 /* Return the session ID of FD */ +#define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */ +#define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */ + +#define TIOCSERCONFIG 0x5453 +#define TIOCSERGWILD 0x5454 +#define TIOCSERSWILD 0x5455 +#define TIOCGLCKTRMIOS 0x5456 +#define TIOCSLCKTRMIOS 0x5457 +#define TIOCSERGSTRUCT 0x5458 /* For debugging only */ +#define TIOCSERGETLSR 0x5459 /* Get line status register */ + /* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */ +# define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ +#define TIOCSERGETMULTI 0x545A /* Get multiport config */ +#define TIOCSERSETMULTI 0x545B /* Set multiport config */ + +#define TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */ +#define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */ + +#endif /* _ASM_IOCTLS_H */ diff -ruNp linus-powerpc.1a/include/asm-powerpc/linkage.h linus-powerpc.2/include/asm-powerpc/linkage.h --- linus-powerpc.1a/include/asm-powerpc/linkage.h 2005-06-27 16:08:08.000000000 +1000 +++ linus-powerpc.2/include/asm-powerpc/linkage.h 2005-08-05 15:04:55.000000000 +1000 @@ -1,6 +1 @@ -#ifndef __ASM_LINKAGE_H -#define __ASM_LINKAGE_H - /* Nothing to see here... */ - -#endif diff -ruNp linus-powerpc.1a/include/asm-powerpc/local.h linus-powerpc.2/include/asm-powerpc/local.h --- linus-powerpc.1a/include/asm-powerpc/local.h 1970-01-01 10:00:00.000000000 +1000 +++ linus-powerpc.2/include/asm-powerpc/local.h 2005-08-05 15:04:55.000000000 +1000 @@ -0,0 +1 @@ +#include diff -ruNp linus-powerpc.1a/include/asm-powerpc/mman.h linus-powerpc.2/include/asm-powerpc/mman.h --- linus-powerpc.1a/include/asm-powerpc/mman.h 1970-01-01 10:00:00.000000000 +1000 +++ linus-powerpc.2/include/asm-powerpc/mman.h 2005-08-05 15:04:55.000000000 +1000 @@ -0,0 +1,44 @@ +#ifndef _ASM_MMAN_H +#define _ASM_MMAN_H + +#define PROT_READ 0x1 /* page can be read */ +#define PROT_WRITE 0x2 /* page can be written */ +#define PROT_EXEC 0x4 /* page can be executed */ +#define PROT_SEM 0x8 /* page may be used for atomic ops */ +#define PROT_NONE 0x0 /* page can not be accessed */ +#define PROT_GROWSDOWN 0x01000000 /* mprotect flag: extend change to start of growsdown vma */ +#define PROT_GROWSUP 0x02000000 /* mprotect flag: extend change to end of growsup vma */ + +#define MAP_SHARED 0x01 /* Share changes */ +#define MAP_PRIVATE 0x02 /* Changes are private */ +#define MAP_TYPE 0x0f /* Mask for type of mapping */ +#define MAP_FIXED 0x10 /* Interpret addr exactly */ +#define MAP_ANONYMOUS 0x20 /* don't use a file */ +#define MAP_RENAME MAP_ANONYMOUS /* In SunOS terminology */ +#define MAP_NORESERVE 0x40 /* don't reserve swap pages */ +#define MAP_LOCKED 0x80 + +#define MAP_GROWSDOWN 0x0100 /* stack-like segment */ +#define MAP_DENYWRITE 0x0800 /* ETXTBSY */ +#define MAP_EXECUTABLE 0x1000 /* mark it as an executable */ +#define MAP_POPULATE 0x8000 /* populate (prefault) pagetables */ +#define MAP_NONBLOCK 0x10000 /* do not block on IO */ + +#define MS_ASYNC 1 /* sync memory asynchronously */ +#define MS_INVALIDATE 2 /* invalidate the caches */ +#define MS_SYNC 4 /* synchronous memory sync */ + +#define MCL_CURRENT 0x2000 /* lock all currently mapped pages */ +#define MCL_FUTURE 0x4000 /* lock all additions to address space */ + +#define MADV_NORMAL 0x0 /* default page-in behavior */ +#define MADV_RANDOM 0x1 /* page-in minimum required */ +#define MADV_SEQUENTIAL 0x2 /* read-ahead aggressively */ +#define MADV_WILLNEED 0x3 /* pre-fault pages */ +#define MADV_DONTNEED 0x4 /* discard these pages */ + +/* compatibility flags */ +#define MAP_ANON MAP_ANONYMOUS +#define MAP_FILE 0 + +#endif /* _ASM_MMAN_H */ diff -ruNp linus-powerpc.1a/include/asm-powerpc/param.h linus-powerpc.2/include/asm-powerpc/param.h --- linus-powerpc.1a/include/asm-powerpc/param.h 1970-01-01 10:00:00.000000000 +1000 +++ linus-powerpc.2/include/asm-powerpc/param.h 2005-08-05 15:04:55.000000000 +1000 @@ -0,0 +1,29 @@ +#ifndef _ASM_PARAM_H +#define _ASM_PARAM_H + +/* + * 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. + */ + +#ifdef __KERNEL__ +# define HZ 1000 /* Internal kernel timer frequency */ +# define USER_HZ 100 /* .. some user interfaces are in "ticks" */ +# define CLOCKS_PER_SEC (USER_HZ) /* like times() */ +#endif + +#ifndef HZ +#define HZ 100 +#endif + +#define EXEC_PAGESIZE 4096 + +#ifndef NOGROUP +#define NOGROUP (-1) +#endif + +#define MAXHOSTNAMELEN 64 /* max length of hostname */ + +#endif /* _ASM_PARAM_H */ diff -ruNp linus-powerpc.1a/include/asm-powerpc/parport.h linus-powerpc.2/include/asm-powerpc/parport.h --- linus-powerpc.1a/include/asm-powerpc/parport.h 1970-01-01 10:00:00.000000000 +1000 +++ linus-powerpc.2/include/asm-powerpc/parport.h 2005-08-05 15:04:55.000000000 +1000 @@ -0,0 +1,18 @@ +/* + * parport.h: platform-specific PC-style parport initialisation + * + * Copyright (C) 1999, 2000 Tim Waugh + * + * This file should only be included by drivers/parport/parport_pc.c. + */ + +#ifndef _ASM_PARPORT_H +#define _ASM_PARPORT_H + +static int __devinit parport_pc_find_isa_ports (int autoirq, int autodma); +static int __devinit parport_pc_find_nonpci_ports (int autoirq, int autodma) +{ + return parport_pc_find_isa_ports (autoirq, autodma); +} + +#endif /* !(_ASM_PARPORT_H) */ diff -ruNp linus-powerpc.1a/include/asm-powerpc/percpu.h linus-powerpc.2/include/asm-powerpc/percpu.h --- linus-powerpc.1a/include/asm-powerpc/percpu.h 1970-01-01 10:00:00.000000000 +1000 +++ linus-powerpc.2/include/asm-powerpc/percpu.h 2005-08-05 15:04:55.000000000 +1000 @@ -0,0 +1 @@ +#include diff -ruNp linus-powerpc.1a/include/asm-powerpc/poll.h linus-powerpc.2/include/asm-powerpc/poll.h --- linus-powerpc.1a/include/asm-powerpc/poll.h 1970-01-01 10:00:00.000000000 +1000 +++ linus-powerpc.2/include/asm-powerpc/poll.h 2005-08-05 15:04:55.000000000 +1000 @@ -0,0 +1,32 @@ +#ifndef _ASM_POLL_H +#define _ASM_POLL_H + +/* + * Copyright (C) 2001 PPC64 Team, IBM Corp + * + * 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. + */ + +#define POLLIN 0x0001 +#define POLLPRI 0x0002 +#define POLLOUT 0x0004 +#define POLLERR 0x0008 +#define POLLHUP 0x0010 +#define POLLNVAL 0x0020 +#define POLLRDNORM 0x0040 +#define POLLRDBAND 0x0080 +#define POLLWRNORM 0x0100 +#define POLLWRBAND 0x0200 +#define POLLMSG 0x0400 +#define POLLREMOVE 0x1000 + +struct pollfd { + int fd; + short events; + short revents; +}; + +#endif /* _ASM_POLL_H */ diff -ruNp linus-powerpc.1a/include/asm-powerpc/resource.h linus-powerpc.2/include/asm-powerpc/resource.h --- linus-powerpc.1a/include/asm-powerpc/resource.h 1970-01-01 10:00:00.000000000 +1000 +++ linus-powerpc.2/include/asm-powerpc/resource.h 2005-08-05 15:04:55.000000000 +1000 @@ -0,0 +1 @@ +#include diff -ruNp linus-powerpc.1a/include/asm-powerpc/shmparam.h linus-powerpc.2/include/asm-powerpc/shmparam.h --- linus-powerpc.1a/include/asm-powerpc/shmparam.h 1970-01-01 10:00:00.000000000 +1000 +++ linus-powerpc.2/include/asm-powerpc/shmparam.h 2005-08-05 15:04:55.000000000 +1000 @@ -0,0 +1,6 @@ +#ifndef _ASM_SHMPARAM_H +#define _ASM_SHMPARAM_H + +#define SHMLBA PAGE_SIZE /* attach addr a multiple of this */ + +#endif /* _ASM_SHMPARAM_H */ diff -ruNp linus-powerpc.1a/include/asm-powerpc/string.h linus-powerpc.2/include/asm-powerpc/string.h --- linus-powerpc.1a/include/asm-powerpc/string.h 1970-01-01 10:00:00.000000000 +1000 +++ linus-powerpc.2/include/asm-powerpc/string.h 2005-08-05 15:04:55.000000000 +1000 @@ -0,0 +1,32 @@ +#ifndef _ASM_STRING_H +#define _ASM_STRING_H + +#ifdef __KERNEL__ + +#define __HAVE_ARCH_STRCPY +#define __HAVE_ARCH_STRNCPY +#define __HAVE_ARCH_STRLEN +#define __HAVE_ARCH_STRCMP +#define __HAVE_ARCH_STRCAT +#define __HAVE_ARCH_MEMSET +#define __HAVE_ARCH_MEMCPY +#define __HAVE_ARCH_MEMMOVE +#define __HAVE_ARCH_MEMCMP +#define __HAVE_ARCH_MEMCHR + +extern int strcasecmp(const char *, const char *); +extern int strncasecmp(const char *, const char *, int); +extern char * strcpy(char *,const char *); +extern char * strncpy(char *,const char *, __kernel_size_t); +extern __kernel_size_t strlen(const char *); +extern int strcmp(const char *,const char *); +extern char * strcat(char *, const char *); +extern void * memset(void *,int,__kernel_size_t); +extern void * memcpy(void *,const void *,__kernel_size_t); +extern void * memmove(void *,const void *,__kernel_size_t); +extern int memcmp(const void *,const void *,__kernel_size_t); +extern void * memchr(const void *,int,__kernel_size_t); + +#endif /* __KERNEL__ */ + +#endif /* _ASM_STRING_H */ diff -ruNp linus-powerpc.1a/include/asm-powerpc/termbits.h linus-powerpc.2/include/asm-powerpc/termbits.h --- linus-powerpc.1a/include/asm-powerpc/termbits.h 1970-01-01 10:00:00.000000000 +1000 +++ linus-powerpc.2/include/asm-powerpc/termbits.h 2005-08-05 15:04:55.000000000 +1000 @@ -0,0 +1,184 @@ +#ifndef _ASM_TERMBITS_H +#define _ASM_TERMBITS_H + +typedef unsigned char cc_t; +typedef unsigned int speed_t; +typedef unsigned int tcflag_t; + +/* + * termios type and macro definitions. Be careful about adding stuff + * to this file since it's used in GNU libc and there are strict rules + * concerning namespace pollution. + */ + +#define NCCS 19 +struct termios { + tcflag_t c_iflag; /* input mode flags */ + tcflag_t c_oflag; /* output mode flags */ + tcflag_t c_cflag; /* control mode flags */ + tcflag_t c_lflag; /* local mode flags */ + cc_t c_cc[NCCS]; /* control characters */ + cc_t c_line; /* line discipline (== c_cc[19]) */ + speed_t c_ispeed; /* input speed */ + speed_t c_ospeed; /* output speed */ +}; + +/* c_cc characters */ +#define VINTR 0 +#define VQUIT 1 +#define VERASE 2 +#define VKILL 3 +#define VEOF 4 +#define VMIN 5 +#define VEOL 6 +#define VTIME 7 +#define VEOL2 8 +#define VSWTC 9 +#define VWERASE 10 +#define VREPRINT 11 +#define VSUSP 12 +#define VSTART 13 +#define VSTOP 14 +#define VLNEXT 15 +#define VDISCARD 16 + +/* c_iflag bits */ +#define IGNBRK 0000001 +#define BRKINT 0000002 +#define IGNPAR 0000004 +#define PARMRK 0000010 +#define INPCK 0000020 +#define ISTRIP 0000040 +#define INLCR 0000100 +#define IGNCR 0000200 +#define ICRNL 0000400 +#define IXON 0001000 +#define IXOFF 0002000 +#define IXANY 0004000 +#define IUCLC 0010000 +#define IMAXBEL 0020000 +#define IUTF8 0040000 + +/* c_oflag bits */ +#define OPOST 0000001 +#define ONLCR 0000002 +#define OLCUC 0000004 + +#define OCRNL 0000010 +#define ONOCR 0000020 +#define ONLRET 0000040 + +#define OFILL 00000100 +#define OFDEL 00000200 +#define NLDLY 00001400 +#define NL0 00000000 +#define NL1 00000400 +#define NL2 00001000 +#define NL3 00001400 +#define TABDLY 00006000 +#define TAB0 00000000 +#define TAB1 00002000 +#define TAB2 00004000 +#define TAB3 00006000 +#define XTABS 00006000 /* required by POSIX to == TAB3 */ +#define CRDLY 00030000 +#define CR0 00000000 +#define CR1 00010000 +#define CR2 00020000 +#define CR3 00030000 +#define FFDLY 00040000 +#define FF0 00000000 +#define FF1 00040000 +#define BSDLY 00100000 +#define BS0 00000000 +#define BS1 00100000 +#define VTDLY 00200000 +#define VT0 00000000 +#define VT1 00200000 + +/* c_cflag bit meaning */ +#define CBAUD 0000377 +#define B0 0000000 /* hang up */ +#define B50 0000001 +#define B75 0000002 +#define B110 0000003 +#define B134 0000004 +#define B150 0000005 +#define B200 0000006 +#define B300 0000007 +#define B600 0000010 +#define B1200 0000011 +#define B1800 0000012 +#define B2400 0000013 +#define B4800 0000014 +#define B9600 0000015 +#define B19200 0000016 +#define B38400 0000017 +#define EXTA B19200 +#define EXTB B38400 +#define CBAUDEX 0000000 +#define B57600 00020 +#define B115200 00021 +#define B230400 00022 +#define B460800 00023 +#define B500000 00024 +#define B576000 00025 +#define B921600 00026 +#define B1000000 00027 +#define B1152000 00030 +#define B1500000 00031 +#define B2000000 00032 +#define B2500000 00033 +#define B3000000 00034 +#define B3500000 00035 +#define B4000000 00036 + +#define CSIZE 00001400 +#define CS5 00000000 +#define CS6 00000400 +#define CS7 00001000 +#define CS8 00001400 + +#define CSTOPB 00002000 +#define CREAD 00004000 +#define PARENB 00010000 +#define PARODD 00020000 +#define HUPCL 00040000 + +#define CLOCAL 00100000 +#define CRTSCTS 020000000000 /* flow control */ + +/* c_lflag bits */ +#define ISIG 0x00000080 +#define ICANON 0x00000100 +#define XCASE 0x00004000 +#define ECHO 0x00000008 +#define ECHOE 0x00000002 +#define ECHOK 0x00000004 +#define ECHONL 0x00000010 +#define NOFLSH 0x80000000 +#define TOSTOP 0x00400000 +#define ECHOCTL 0x00000040 +#define ECHOPRT 0x00000020 +#define ECHOKE 0x00000001 +#define FLUSHO 0x00800000 +#define PENDIN 0x20000000 +#define IEXTEN 0x00000400 + +/* Values for the ACTION argument to `tcflow'. */ +#define TCOOFF 0 +#define TCOON 1 +#define TCIOFF 2 +#define TCION 3 + +/* Values for the QUEUE_SELECTOR argument to `tcflush'. */ +#define TCIFLUSH 0 +#define TCOFLUSH 1 +#define TCIOFLUSH 2 + +/* Values for the OPTIONAL_ACTIONS argument to `tcsetattr'. */ +#define TCSANOW 0 +#define TCSADRAIN 1 +#define TCSAFLUSH 2 + +#endif /* _ASM_TERMBITS_H */ diff -ruNp linus-powerpc.1a/include/asm-powerpc/termios.h linus-powerpc.2/include/asm-powerpc/termios.h --- linus-powerpc.1a/include/asm-powerpc/termios.h 1970-01-01 10:00:00.000000000 +1000 +++ linus-powerpc.2/include/asm-powerpc/termios.h 2005-08-05 15:04:55.000000000 +1000 @@ -0,0 +1,231 @@ +#ifndef _ASM_TERMIOS_H +#define _ASM_TERMIOS_H + +/* + * Liberally adapted from alpha/termios.h. In particular, the c_cc[] + * fields have been reordered so that termio & termios share the + * common subset in the same order (for brain dead programs that don't + * know or care about the differences). + */ + +#include +#include + +struct sgttyb { + char sg_ispeed; + char sg_ospeed; + char sg_erase; + char sg_kill; + short sg_flags; +}; + +struct tchars { + char t_intrc; + char t_quitc; + char t_startc; + char t_stopc; + char t_eofc; + char t_brkc; +}; + +struct ltchars { + char t_suspc; + char t_dsuspc; + char t_rprntc; + char t_flushc; + char t_werasc; + char t_lnextc; +}; + +struct winsize { + unsigned short ws_row; + unsigned short ws_col; + unsigned short ws_xpixel; + unsigned short ws_ypixel; +}; + +#define NCC 10 +struct termio { + unsigned short c_iflag; /* input mode flags */ + unsigned short c_oflag; /* output mode flags */ + unsigned short c_cflag; /* control mode flags */ + unsigned short c_lflag; /* local mode flags */ + unsigned char c_line; /* line discipline */ + unsigned char c_cc[NCC]; /* control characters */ +}; + +/* c_cc characters */ +#define _VINTR 0 +#define _VQUIT 1 +#define _VERASE 2 +#define _VKILL 3 +#define _VEOF 4 +#define _VMIN 5 +#define _VEOL 6 +#define _VTIME 7 +#define _VEOL2 8 +#define _VSWTC 9 + +/* line disciplines */ +#define N_TTY 0 +#define N_SLIP 1 +#define N_MOUSE 2 +#define N_PPP 3 +#define N_STRIP 4 +#define N_AX25 5 +#define N_X25 6 /* X.25 async */ +#define N_6PACK 7 +#define N_MASC 8 /* Reserved for Mobitex module */ +#define N_R3964 9 /* Reserved for Simatic R3964 module */ +#define N_PROFIBUS_FDL 10 /* Reserved for Profibus */ +#define N_IRDA 11 /* Linux IrDa - http://irda.sourceforge.net/ */ +#define N_SMSBLOCK 12 /* SMS block mode - for talking to GSM data cards about SMS messages */ +#define N_HDLC 13 /* synchronous HDLC */ +#define N_SYNC_PPP 14 +#define N_HCI 15 /* Bluetooth HCI UART */ + +#ifdef __KERNEL__ +/* ^C ^\ del ^U ^D 1 0 0 0 0 ^W ^R ^Z ^Q ^S ^V ^U */ +#define INIT_C_CC "\003\034\177\025\004\001\000\000\000\000\027\022\032\021\023\026\025" +#endif /* __KERNEL__ */ + +#define FIOCLEX _IO('f', 1) +#define FIONCLEX _IO('f', 2) +#define FIOASYNC _IOW('f', 125, int) +#define FIONBIO _IOW('f', 126, int) +#define FIONREAD _IOR('f', 127, int) +#define TIOCINQ FIONREAD + +#define TIOCGETP _IOR('t', 8, struct sgttyb) +#define TIOCSETP _IOW('t', 9, struct sgttyb) +#define TIOCSETN _IOW('t', 10, struct sgttyb) /* TIOCSETP wo flush */ + +#define TIOCSETC _IOW('t', 17, struct tchars) +#define TIOCGETC _IOR('t', 18, struct tchars) +#define TCGETS _IOR('t', 19, struct termios) +#define TCSETS _IOW('t', 20, struct termios) +#define TCSETSW _IOW('t', 21, struct termios) +#define TCSETSF _IOW('t', 22, struct termios) + +#define TCGETA _IOR('t', 23, struct termio) +#define TCSETA _IOW('t', 24, struct termio) +#define TCSETAW _IOW('t', 25, struct termio) +#define TCSETAF _IOW('t', 28, struct termio) + +#define TCSBRK _IO('t', 29) +#define TCXONC _IO('t', 30) +#define TCFLSH _IO('t', 31) + +#define TIOCSWINSZ _IOW('t', 103, struct winsize) +#define TIOCGWINSZ _IOR('t', 104, struct winsize) +#define TIOCSTART _IO('t', 110) /* start output, like ^Q */ +#define TIOCSTOP _IO('t', 111) /* stop output, like ^S */ +#define TIOCOUTQ _IOR('t', 115, int) /* output queue size */ + +#define TIOCGLTC _IOR('t', 116, struct ltchars) +#define TIOCSLTC _IOW('t', 117, struct ltchars) +#define TIOCSPGRP _IOW('t', 118, int) +#define TIOCGPGRP _IOR('t', 119, int) + +#define TIOCEXCL 0x540C +#define TIOCNXCL 0x540D +#define TIOCSCTTY 0x540E + +#define TIOCSTI 0x5412 +#define TIOCMGET 0x5415 +#define TIOCMBIS 0x5416 +#define TIOCMBIC 0x5417 +#define TIOCMSET 0x5418 +#define TIOCGSOFTCAR 0x5419 +#define TIOCSSOFTCAR 0x541A +#define TIOCLINUX 0x541C +#define TIOCCONS 0x541D +#define TIOCGSERIAL 0x541E +#define TIOCSSERIAL 0x541F +#define TIOCPKT 0x5420 + +#define TIOCNOTTY 0x5422 +#define TIOCSETD 0x5423 +#define TIOCGETD 0x5424 +#define TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */ + +#define TIOCSERCONFIG 0x5453 +#define TIOCSERGWILD 0x5454 +#define TIOCSERSWILD 0x5455 +#define TIOCGLCKTRMIOS 0x5456 +#define TIOCSLCKTRMIOS 0x5457 +#define TIOCSERGSTRUCT 0x5458 /* For debugging only */ +#define TIOCSERGETLSR 0x5459 /* Get line status register */ +#define TIOCSERGETMULTI 0x545A /* Get multiport config */ +#define TIOCSERSETMULTI 0x545B /* Set multiport config */ + +#define TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */ +#define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */ + +/* Used for packet mode */ +#define TIOCPKT_DATA 0 +#define TIOCPKT_FLUSHREAD 1 +#define TIOCPKT_FLUSHWRITE 2 +#define TIOCPKT_STOP 4 +#define TIOCPKT_START 8 +#define TIOCPKT_NOSTOP 16 +#define TIOCPKT_DOSTOP 32 + +/* modem lines */ +#define TIOCM_LE 0x001 +#define TIOCM_DTR 0x002 +#define TIOCM_RTS 0x004 +#define TIOCM_ST 0x008 +#define TIOCM_SR 0x010 +#define TIOCM_CTS 0x020 +#define TIOCM_CAR 0x040 +#define TIOCM_RNG 0x080 +#define TIOCM_DSR 0x100 +#define TIOCM_CD TIOCM_CAR +#define TIOCM_RI TIOCM_RNG +#define TIOCM_OUT1 0x2000 +#define TIOCM_OUT2 0x4000 +#define TIOCM_LOOP 0x8000 + +/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */ +#define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ + +#ifdef __KERNEL__ + +/* + * Translate a "termio" structure into a "termios". Ugh. + */ +#define SET_LOW_TERMIOS_BITS(termios, termio, x) { \ + unsigned short __tmp; \ + get_user(__tmp,&(termio)->x); \ + (termios)->x = (0xffff0000 & (termios)->x) | __tmp; \ +} + +#define user_termio_to_kernel_termios(termios, termio) \ +({ \ + SET_LOW_TERMIOS_BITS(termios, termio, c_iflag); \ + SET_LOW_TERMIOS_BITS(termios, termio, c_oflag); \ + SET_LOW_TERMIOS_BITS(termios, termio, c_cflag); \ + SET_LOW_TERMIOS_BITS(termios, termio, c_lflag); \ + copy_from_user((termios)->c_cc, (termio)->c_cc, NCC); \ +}) + +/* + * Translate a "termios" structure into a "termio". Ugh. + */ +#define kernel_termios_to_user_termio(termio, termios) \ +({ \ + put_user((termios)->c_iflag, &(termio)->c_iflag); \ + put_user((termios)->c_oflag, &(termio)->c_oflag); \ + put_user((termios)->c_cflag, &(termio)->c_cflag); \ + put_user((termios)->c_lflag, &(termio)->c_lflag); \ + put_user((termios)->c_line, &(termio)->c_line); \ + copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \ +}) + +#define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios)) +#define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios)) + +#endif /* __KERNEL__ */ + +#endif /* _ASM_TERMIOS_H */ diff -ruNp linus-powerpc.1a/include/asm-powerpc/unaligned.h linus-powerpc.2/include/asm-powerpc/unaligned.h --- linus-powerpc.1a/include/asm-powerpc/unaligned.h 1970-01-01 10:00:00.000000000 +1000 +++ linus-powerpc.2/include/asm-powerpc/unaligned.h 2005-08-05 15:04:55.000000000 +1000 @@ -0,0 +1,18 @@ +#ifdef __KERNEL__ +#ifndef _ASM_UNALIGNED_H +#define _ASM_UNALIGNED_H + +/* + * The PowerPC can do unaligned accesses itself in big endian mode. + * + * The strange macros are there to make sure these can't + * be misused in a way that makes them not work on other + * architectures where unaligned accesses aren't as simple. + */ + +#define get_unaligned(ptr) (*(ptr)) + +#define put_unaligned(val, ptr) ((void)( *(ptr) = (val) )) + +#endif /* _ASM_UNALIGNED_H */ +#endif /* __KERNEL__ */ diff -ruNp linus-powerpc.1a/include/asm-ppc/div64.h linus-powerpc.2/include/asm-ppc/div64.h --- linus-powerpc.1a/include/asm-ppc/div64.h 1970-01-01 10:00:00.000000000 +1000 +++ linus-powerpc.2/include/asm-ppc/div64.h 2005-06-27 16:08:08.000000000 +1000 @@ -0,0 +1 @@ +#include diff -ruNp linus-powerpc.1a/include/asm-ppc/errno.h linus-powerpc.2/include/asm-ppc/errno.h --- linus-powerpc.1a/include/asm-ppc/errno.h 2005-06-27 16:08:08.000000000 +1000 +++ linus-powerpc.2/include/asm-ppc/errno.h 1970-01-01 10:00:00.000000000 +1000 @@ -1,11 +0,0 @@ -#ifndef _PPC_ERRNO_H -#define _PPC_ERRNO_H - -#include - -#undef EDEADLOCK -#define EDEADLOCK 58 /* File locking deadlock error */ - -#define _LAST_ERRNO 516 - -#endif diff -ruNp linus-powerpc.1a/include/asm-ppc/ioctl.h linus-powerpc.2/include/asm-ppc/ioctl.h --- linus-powerpc.1a/include/asm-ppc/ioctl.h 2005-06-27 16:08:08.000000000 +1000 +++ linus-powerpc.2/include/asm-ppc/ioctl.h 1970-01-01 10:00:00.000000000 +1000 @@ -1,69 +0,0 @@ -#ifndef _PPC_IOCTL_H -#define _PPC_IOCTL_H - - -/* - * this was copied from the alpha as it's a bit cleaner there. - * -- Cort - */ - -#define _IOC_NRBITS 8 -#define _IOC_TYPEBITS 8 -#define _IOC_SIZEBITS 13 -#define _IOC_DIRBITS 3 - -#define _IOC_NRMASK ((1 << _IOC_NRBITS)-1) -#define _IOC_TYPEMASK ((1 << _IOC_TYPEBITS)-1) -#define _IOC_SIZEMASK ((1 << _IOC_SIZEBITS)-1) -#define _IOC_DIRMASK ((1 << _IOC_DIRBITS)-1) - -#define _IOC_NRSHIFT 0 -#define _IOC_TYPESHIFT (_IOC_NRSHIFT+_IOC_NRBITS) -#define _IOC_SIZESHIFT (_IOC_TYPESHIFT+_IOC_TYPEBITS) -#define _IOC_DIRSHIFT (_IOC_SIZESHIFT+_IOC_SIZEBITS) - -/* - * Direction bits _IOC_NONE could be 0, but OSF/1 gives it a bit. - * And this turns out useful to catch old ioctl numbers in header - * files for us. - */ -#define _IOC_NONE 1U -#define _IOC_READ 2U -#define _IOC_WRITE 4U - -#define _IOC(dir,type,nr,size) \ - (((dir) << _IOC_DIRSHIFT) | \ - ((type) << _IOC_TYPESHIFT) | \ - ((nr) << _IOC_NRSHIFT) | \ - ((size) << _IOC_SIZESHIFT)) - -/* provoke compile error for invalid uses of size argument */ -extern unsigned int __invalid_size_argument_for_IOC; -#define _IOC_TYPECHECK(t) \ - ((sizeof(t) == sizeof(t[1]) && \ - sizeof(t) < (1 << _IOC_SIZEBITS)) ? \ - sizeof(t) : __invalid_size_argument_for_IOC) - -/* used to create numbers */ -#define _IO(type,nr) _IOC(_IOC_NONE,(type),(nr),0) -#define _IOR(type,nr,size) _IOC(_IOC_READ,(type),(nr),(_IOC_TYPECHECK(size))) -#define _IOW(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size))) -#define _IOWR(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size))) -#define _IOR_BAD(type,nr,size) _IOC(_IOC_READ,(type),(nr),sizeof(size)) -#define _IOW_BAD(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),sizeof(size)) -#define _IOWR_BAD(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size)) - -/* used to decode them.. */ -#define _IOC_DIR(nr) (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK) -#define _IOC_TYPE(nr) (((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK) -#define _IOC_NR(nr) (((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK) -#define _IOC_SIZE(nr) (((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK) - -/* various drivers, such as the pcmcia stuff, need these... */ -#define IOC_IN (_IOC_WRITE << _IOC_DIRSHIFT) -#define IOC_OUT (_IOC_READ << _IOC_DIRSHIFT) -#define IOC_INOUT ((_IOC_WRITE|_IOC_READ) << _IOC_DIRSHIFT) -#define IOCSIZE_MASK (_IOC_SIZEMASK << _IOC_SIZESHIFT) -#define IOCSIZE_SHIFT (_IOC_SIZESHIFT) - -#endif diff -ruNp linus-powerpc.1a/include/asm-ppc/ioctls.h linus-powerpc.2/include/asm-ppc/ioctls.h --- linus-powerpc.1a/include/asm-ppc/ioctls.h 2005-06-27 16:08:08.000000000 +1000 +++ linus-powerpc.2/include/asm-ppc/ioctls.h 1970-01-01 10:00:00.000000000 +1000 @@ -1,107 +0,0 @@ -#ifndef _ASM_PPC_IOCTLS_H -#define _ASM_PPC_IOCTLS_H - -#include - -#define FIOCLEX _IO('f', 1) -#define FIONCLEX _IO('f', 2) -#define FIOASYNC _IOW('f', 125, int) -#define FIONBIO _IOW('f', 126, int) -#define FIONREAD _IOR('f', 127, int) -#define TIOCINQ FIONREAD -#define FIOQSIZE _IOR('f', 128, loff_t) - -#define TIOCGETP _IOR('t', 8, struct sgttyb) -#define TIOCSETP _IOW('t', 9, struct sgttyb) -#define TIOCSETN _IOW('t', 10, struct sgttyb) /* TIOCSETP wo flush */ - -#define TIOCSETC _IOW('t', 17, struct tchars) -#define TIOCGETC _IOR('t', 18, struct tchars) -#define TCGETS _IOR('t', 19, struct termios) -#define TCSETS _IOW('t', 20, struct termios) -#define TCSETSW _IOW('t', 21, struct termios) -#define TCSETSF _IOW('t', 22, struct termios) - -#define TCGETA _IOR('t', 23, struct termio) -#define TCSETA _IOW('t', 24, struct termio) -#define TCSETAW _IOW('t', 25, struct termio) -#define TCSETAF _IOW('t', 28, struct termio) - -#define TCSBRK _IO('t', 29) -#define TCXONC _IO('t', 30) -#define TCFLSH _IO('t', 31) - -#define TIOCSWINSZ _IOW('t', 103, struct winsize) -#define TIOCGWINSZ _IOR('t', 104, struct winsize) -#define TIOCSTART _IO('t', 110) /* start output, like ^Q */ -#define TIOCSTOP _IO('t', 111) /* stop output, like ^S */ -#define TIOCOUTQ _IOR('t', 115, int) /* output queue size */ - -#define TIOCGLTC _IOR('t', 116, struct ltchars) -#define TIOCSLTC _IOW('t', 117, struct ltchars) -#define TIOCSPGRP _IOW('t', 118, int) -#define TIOCGPGRP _IOR('t', 119, int) - -#define TIOCEXCL 0x540C -#define TIOCNXCL 0x540D -#define TIOCSCTTY 0x540E - -#define TIOCSTI 0x5412 -#define TIOCMGET 0x5415 -#define TIOCMBIS 0x5416 -#define TIOCMBIC 0x5417 -#define TIOCMSET 0x5418 -# define TIOCM_LE 0x001 -# define TIOCM_DTR 0x002 -# define TIOCM_RTS 0x004 -# define TIOCM_ST 0x008 -# define TIOCM_SR 0x010 -# define TIOCM_CTS 0x020 -# define TIOCM_CAR 0x040 -# define TIOCM_RNG 0x080 -# define TIOCM_DSR 0x100 -# define TIOCM_CD TIOCM_CAR -# define TIOCM_RI TIOCM_RNG - -#define TIOCGSOFTCAR 0x5419 -#define TIOCSSOFTCAR 0x541A -#define TIOCLINUX 0x541C -#define TIOCCONS 0x541D -#define TIOCGSERIAL 0x541E -#define TIOCSSERIAL 0x541F -#define TIOCPKT 0x5420 -# define TIOCPKT_DATA 0 -# define TIOCPKT_FLUSHREAD 1 -# define TIOCPKT_FLUSHWRITE 2 -# define TIOCPKT_STOP 4 -# define TIOCPKT_START 8 -# define TIOCPKT_NOSTOP 16 -# define TIOCPKT_DOSTOP 32 - - -#define TIOCNOTTY 0x5422 -#define TIOCSETD 0x5423 -#define TIOCGETD 0x5424 -#define TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */ -#define TIOCSBRK 0x5427 /* BSD compatibility */ -#define TIOCCBRK 0x5428 /* BSD compatibility */ -#define TIOCGSID 0x5429 /* Return the session ID of FD */ -#define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */ -#define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */ - -#define TIOCSERCONFIG 0x5453 -#define TIOCSERGWILD 0x5454 -#define TIOCSERSWILD 0x5455 -#define TIOCGLCKTRMIOS 0x5456 -#define TIOCSLCKTRMIOS 0x5457 -#define TIOCSERGSTRUCT 0x5458 /* For debugging only */ -#define TIOCSERGETLSR 0x5459 /* Get line status register */ - /* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */ -# define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ -#define TIOCSERGETMULTI 0x545A /* Get multiport config */ -#define TIOCSERSETMULTI 0x545B /* Set multiport config */ - -#define TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */ -#define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */ - -#endif /* _ASM_PPC_IOCTLS_H */ diff -ruNp linus-powerpc.1a/include/asm-ppc/local.h linus-powerpc.2/include/asm-ppc/local.h --- linus-powerpc.1a/include/asm-ppc/local.h 2005-06-27 16:08:08.000000000 +1000 +++ linus-powerpc.2/include/asm-ppc/local.h 1970-01-01 10:00:00.000000000 +1000 @@ -1,6 +0,0 @@ -#ifndef __PPC_LOCAL_H -#define __PPC_LOCAL_H - -#include - -#endif /* __PPC_LOCAL_H */ diff -ruNp linus-powerpc.1a/include/asm-ppc/mman.h linus-powerpc.2/include/asm-ppc/mman.h --- linus-powerpc.1a/include/asm-ppc/mman.h 2005-06-27 16:08:08.000000000 +1000 +++ linus-powerpc.2/include/asm-ppc/mman.h 1970-01-01 10:00:00.000000000 +1000 @@ -1,44 +0,0 @@ -#ifndef __PPC_MMAN_H__ -#define __PPC_MMAN_H__ - -#define PROT_READ 0x1 /* page can be read */ -#define PROT_WRITE 0x2 /* page can be written */ -#define PROT_EXEC 0x4 /* page can be executed */ -#define PROT_SEM 0x8 /* page may be used for atomic ops */ -#define PROT_NONE 0x0 /* page can not be accessed */ -#define PROT_GROWSDOWN 0x01000000 /* mprotect flag: extend change to start of growsdown vma */ -#define PROT_GROWSUP 0x02000000 /* mprotect flag: extend change to end of growsup vma */ - -#define MAP_SHARED 0x01 /* Share changes */ -#define MAP_PRIVATE 0x02 /* Changes are private */ -#define MAP_TYPE 0x0f /* Mask for type of mapping */ -#define MAP_FIXED 0x10 /* Interpret addr exactly */ -#define MAP_ANONYMOUS 0x20 /* don't use a file */ -#define MAP_RENAME MAP_ANONYMOUS /* In SunOS terminology */ -#define MAP_NORESERVE 0x40 /* don't reserve swap pages */ -#define MAP_LOCKED 0x80 - -#define MAP_GROWSDOWN 0x0100 /* stack-like segment */ -#define MAP_DENYWRITE 0x0800 /* ETXTBSY */ -#define MAP_EXECUTABLE 0x1000 /* mark it as an executable */ -#define MAP_POPULATE 0x8000 /* populate (prefault) pagetables */ -#define MAP_NONBLOCK 0x10000 /* do not block on IO */ - -#define MS_ASYNC 1 /* sync memory asynchronously */ -#define MS_INVALIDATE 2 /* invalidate the caches */ -#define MS_SYNC 4 /* synchronous memory sync */ - -#define MCL_CURRENT 0x2000 /* lock all currently mapped pages */ -#define MCL_FUTURE 0x4000 /* lock all additions to address space */ - -#define MADV_NORMAL 0x0 /* default page-in behavior */ -#define MADV_RANDOM 0x1 /* page-in minimum required */ -#define MADV_SEQUENTIAL 0x2 /* read-ahead aggressively */ -#define MADV_WILLNEED 0x3 /* pre-fault pages */ -#define MADV_DONTNEED 0x4 /* discard these pages */ - -/* compatibility flags */ -#define MAP_ANON MAP_ANONYMOUS -#define MAP_FILE 0 - -#endif /* __PPC_MMAN_H__ */ diff -ruNp linus-powerpc.1a/include/asm-ppc/param.h linus-powerpc.2/include/asm-ppc/param.h --- linus-powerpc.1a/include/asm-ppc/param.h 2005-06-27 16:08:08.000000000 +1000 +++ linus-powerpc.2/include/asm-ppc/param.h 1970-01-01 10:00:00.000000000 +1000 @@ -1,22 +0,0 @@ -#ifndef _ASM_PPC_PARAM_H -#define _ASM_PPC_PARAM_H - -#ifdef __KERNEL__ -#define HZ 1000 /* internal timer frequency */ -#define USER_HZ 100 /* for user interfaces in "ticks" */ -#define CLOCKS_PER_SEC (USER_HZ) /* frequency at which times() counts */ -#endif /* __KERNEL__ */ - -#ifndef HZ -#define HZ 100 -#endif - -#define EXEC_PAGESIZE 4096 - -#ifndef NOGROUP -#define NOGROUP (-1) -#endif - -#define MAXHOSTNAMELEN 64 /* max length of hostname */ - -#endif diff -ruNp linus-powerpc.1a/include/asm-ppc/parport.h linus-powerpc.2/include/asm-ppc/parport.h --- linus-powerpc.1a/include/asm-ppc/parport.h 2005-06-27 16:08:08.000000000 +1000 +++ linus-powerpc.2/include/asm-ppc/parport.h 1970-01-01 10:00:00.000000000 +1000 @@ -1,18 +0,0 @@ -/* - * parport.h: platform-specific PC-style parport initialisation - * - * Copyright (C) 1999, 2000 Tim Waugh - * - * This file should only be included by drivers/parport/parport_pc.c. - */ - -#ifndef _ASM_PPC_PARPORT_H -#define _ASM_PPC_PARPORT_H - -static int __devinit parport_pc_find_isa_ports (int autoirq, int autodma); -static int __devinit parport_pc_find_nonpci_ports (int autoirq, int autodma) -{ - return parport_pc_find_isa_ports (autoirq, autodma); -} - -#endif /* !(_ASM_PPC_PARPORT_H) */ diff -ruNp linus-powerpc.1a/include/asm-ppc/percpu.h linus-powerpc.2/include/asm-ppc/percpu.h --- linus-powerpc.1a/include/asm-ppc/percpu.h 2005-06-27 16:08:08.000000000 +1000 +++ linus-powerpc.2/include/asm-ppc/percpu.h 1970-01-01 10:00:00.000000000 +1000 @@ -1,6 +0,0 @@ -#ifndef __ARCH_PPC_PERCPU__ -#define __ARCH_PPC_PERCPU__ - -#include - -#endif /* __ARCH_PPC_PERCPU__ */ diff -ruNp linus-powerpc.1a/include/asm-ppc/poll.h linus-powerpc.2/include/asm-ppc/poll.h --- linus-powerpc.1a/include/asm-ppc/poll.h 2005-06-27 16:08:08.000000000 +1000 +++ linus-powerpc.2/include/asm-ppc/poll.h 1970-01-01 10:00:00.000000000 +1000 @@ -1,23 +0,0 @@ -#ifndef __PPC_POLL_H -#define __PPC_POLL_H - -#define POLLIN 0x0001 -#define POLLPRI 0x0002 -#define POLLOUT 0x0004 -#define POLLERR 0x0008 -#define POLLHUP 0x0010 -#define POLLNVAL 0x0020 -#define POLLRDNORM 0x0040 -#define POLLRDBAND 0x0080 -#define POLLWRNORM 0x0100 -#define POLLWRBAND 0x0200 -#define POLLMSG 0x0400 -#define POLLREMOVE 0x1000 - -struct pollfd { - int fd; - short events; - short revents; -}; - -#endif diff -ruNp linus-powerpc.1a/include/asm-ppc/resource.h linus-powerpc.2/include/asm-ppc/resource.h --- linus-powerpc.1a/include/asm-ppc/resource.h 2005-06-27 16:08:08.000000000 +1000 +++ linus-powerpc.2/include/asm-ppc/resource.h 1970-01-01 10:00:00.000000000 +1000 @@ -1,6 +0,0 @@ -#ifndef _PPC_RESOURCE_H -#define _PPC_RESOURCE_H - -#include - -#endif diff -ruNp linus-powerpc.1a/include/asm-ppc/shmparam.h linus-powerpc.2/include/asm-ppc/shmparam.h --- linus-powerpc.1a/include/asm-ppc/shmparam.h 2005-06-27 16:08:08.000000000 +1000 +++ linus-powerpc.2/include/asm-ppc/shmparam.h 1970-01-01 10:00:00.000000000 +1000 @@ -1,6 +0,0 @@ -#ifndef _PPC_SHMPARAM_H -#define _PPC_SHMPARAM_H - -#define SHMLBA PAGE_SIZE /* attach addr a multiple of this */ - -#endif /* _PPC_SHMPARAM_H */ diff -ruNp linus-powerpc.1a/include/asm-ppc/string.h linus-powerpc.2/include/asm-ppc/string.h --- linus-powerpc.1a/include/asm-ppc/string.h 2005-06-27 16:08:08.000000000 +1000 +++ linus-powerpc.2/include/asm-ppc/string.h 1970-01-01 10:00:00.000000000 +1000 @@ -1,32 +0,0 @@ -#ifndef _PPC_STRING_H_ -#define _PPC_STRING_H_ - -#ifdef __KERNEL__ - -#define __HAVE_ARCH_STRCPY -#define __HAVE_ARCH_STRNCPY -#define __HAVE_ARCH_STRLEN -#define __HAVE_ARCH_STRCMP -#define __HAVE_ARCH_STRCAT -#define __HAVE_ARCH_MEMSET -#define __HAVE_ARCH_MEMCPY -#define __HAVE_ARCH_MEMMOVE -#define __HAVE_ARCH_MEMCMP -#define __HAVE_ARCH_MEMCHR - -extern int strcasecmp(const char *, const char *); -extern int strncasecmp(const char *, const char *, int); -extern char * strcpy(char *,const char *); -extern char * strncpy(char *,const char *, __kernel_size_t); -extern __kernel_size_t strlen(const char *); -extern int strcmp(const char *,const char *); -extern char * strcat(char *, const char *); -extern void * memset(void *,int,__kernel_size_t); -extern void * memcpy(void *,const void *,__kernel_size_t); -extern void * memmove(void *,const void *,__kernel_size_t); -extern int memcmp(const void *,const void *,__kernel_size_t); -extern void * memchr(const void *,int,__kernel_size_t); - -#endif /* __KERNEL__ */ - -#endif diff -ruNp linus-powerpc.1a/include/asm-ppc/termbits.h linus-powerpc.2/include/asm-ppc/termbits.h --- linus-powerpc.1a/include/asm-ppc/termbits.h 2005-06-27 16:08:08.000000000 +1000 +++ linus-powerpc.2/include/asm-ppc/termbits.h 1970-01-01 10:00:00.000000000 +1000 @@ -1,185 +0,0 @@ -#ifndef _PPC_TERMBITS_H -#define _PPC_TERMBITS_H - -typedef unsigned char cc_t; -typedef unsigned int speed_t; -typedef unsigned int tcflag_t; - -/* - * termios type and macro definitions. Be careful about adding stuff - * to this file since it's used in GNU libc and there are strict rules - * concerning namespace pollution. - */ - -#define NCCS 19 -struct termios { - tcflag_t c_iflag; /* input mode flags */ - tcflag_t c_oflag; /* output mode flags */ - tcflag_t c_cflag; /* control mode flags */ - tcflag_t c_lflag; /* local mode flags */ - cc_t c_cc[NCCS]; /* control characters */ - cc_t c_line; /* line discipline (== c_cc[19]) */ - speed_t c_ispeed; /* input speed */ - speed_t c_ospeed; /* output speed */ -}; - -/* c_cc characters */ -#define VINTR 0 -#define VQUIT 1 -#define VERASE 2 -#define VKILL 3 -#define VEOF 4 -#define VMIN 5 -#define VEOL 6 -#define VTIME 7 -#define VEOL2 8 -#define VSWTC 9 - -#define VWERASE 10 -#define VREPRINT 11 -#define VSUSP 12 -#define VSTART 13 -#define VSTOP 14 -#define VLNEXT 15 -#define VDISCARD 16 - -/* c_iflag bits */ -#define IGNBRK 0000001 -#define BRKINT 0000002 -#define IGNPAR 0000004 -#define PARMRK 0000010 -#define INPCK 0000020 -#define ISTRIP 0000040 -#define INLCR 0000100 -#define IGNCR 0000200 -#define ICRNL 0000400 -#define IXON 0001000 -#define IXOFF 0002000 -#define IXANY 0004000 -#define IUCLC 0010000 -#define IMAXBEL 0020000 -#define IUTF8 0040000 - -/* c_oflag bits */ -#define OPOST 0000001 -#define ONLCR 0000002 -#define OLCUC 0000004 - -#define OCRNL 0000010 -#define ONOCR 0000020 -#define ONLRET 0000040 - -#define OFILL 00000100 -#define OFDEL 00000200 -#define NLDLY 00001400 -#define NL0 00000000 -#define NL1 00000400 -#define NL2 00001000 -#define NL3 00001400 -#define TABDLY 00006000 -#define TAB0 00000000 -#define TAB1 00002000 -#define TAB2 00004000 -#define TAB3 00006000 -#define XTABS 00006000 /* required by POSIX to == TAB3 */ -#define CRDLY 00030000 -#define CR0 00000000 -#define CR1 00010000 -#define CR2 00020000 -#define CR3 00030000 -#define FFDLY 00040000 -#define FF0 00000000 -#define FF1 00040000 -#define BSDLY 00100000 -#define BS0 00000000 -#define BS1 00100000 -#define VTDLY 00200000 -#define VT0 00000000 -#define VT1 00200000 - -/* c_cflag bit meaning */ -#define CBAUD 0000377 -#define B0 0000000 /* hang up */ -#define B50 0000001 -#define B75 0000002 -#define B110 0000003 -#define B134 0000004 -#define B150 0000005 -#define B200 0000006 -#define B300 0000007 -#define B600 0000010 -#define B1200 0000011 -#define B1800 0000012 -#define B2400 0000013 -#define B4800 0000014 -#define B9600 0000015 -#define B19200 0000016 -#define B38400 0000017 -#define EXTA B19200 -#define EXTB B38400 -#define CBAUDEX 0000000 -#define B57600 00020 -#define B115200 00021 -#define B230400 00022 -#define B460800 00023 -#define B500000 00024 -#define B576000 00025 -#define B921600 00026 -#define B1000000 00027 -#define B1152000 00030 -#define B1500000 00031 -#define B2000000 00032 -#define B2500000 00033 -#define B3000000 00034 -#define B3500000 00035 -#define B4000000 00036 - -#define CSIZE 00001400 -#define CS5 00000000 -#define CS6 00000400 -#define CS7 00001000 -#define CS8 00001400 - -#define CSTOPB 00002000 -#define CREAD 00004000 -#define PARENB 00010000 -#define PARODD 00020000 -#define HUPCL 00040000 - -#define CLOCAL 00100000 -#define CRTSCTS 020000000000 /* flow control */ - -/* c_lflag bits */ -#define ISIG 0x00000080 -#define ICANON 0x00000100 -#define XCASE 0x00004000 -#define ECHO 0x00000008 -#define ECHOE 0x00000002 -#define ECHOK 0x00000004 -#define ECHONL 0x00000010 -#define NOFLSH 0x80000000 -#define TOSTOP 0x00400000 -#define ECHOCTL 0x00000040 -#define ECHOPRT 0x00000020 -#define ECHOKE 0x00000001 -#define FLUSHO 0x00800000 -#define PENDIN 0x20000000 -#define IEXTEN 0x00000400 - -/* Values for the ACTION argument to `tcflow'. */ -#define TCOOFF 0 -#define TCOON 1 -#define TCIOFF 2 -#define TCION 3 - -/* Values for the QUEUE_SELECTOR argument to `tcflush'. */ -#define TCIFLUSH 0 -#define TCOFLUSH 1 -#define TCIOFLUSH 2 - -/* Values for the OPTIONAL_ACTIONS argument to `tcsetattr'. */ -#define TCSANOW 0 -#define TCSADRAIN 1 -#define TCSAFLUSH 2 - -#endif /* _PPC_TERMBITS_H */ diff -ruNp linus-powerpc.1a/include/asm-ppc/termios.h linus-powerpc.2/include/asm-ppc/termios.h --- linus-powerpc.1a/include/asm-ppc/termios.h 2005-06-27 16:08:08.000000000 +1000 +++ linus-powerpc.2/include/asm-ppc/termios.h 1970-01-01 10:00:00.000000000 +1000 @@ -1,232 +0,0 @@ -#ifndef _PPC_TERMIOS_H -#define _PPC_TERMIOS_H - -/* - * Liberally adapted from alpha/termios.h. In particular, the c_cc[] - * fields have been reordered so that termio & termios share the - * common subset in the same order (for brain dead programs that don't - * know or care about the differences). - */ - -#include -#include - -struct sgttyb { - char sg_ispeed; - char sg_ospeed; - char sg_erase; - char sg_kill; - short sg_flags; -}; - -struct tchars { - char t_intrc; - char t_quitc; - char t_startc; - char t_stopc; - char t_eofc; - char t_brkc; -}; - -struct ltchars { - char t_suspc; - char t_dsuspc; - char t_rprntc; - char t_flushc; - char t_werasc; - char t_lnextc; -}; - -#define FIOCLEX _IO('f', 1) -#define FIONCLEX _IO('f', 2) -#define FIOASYNC _IOW('f', 125, int) -#define FIONBIO _IOW('f', 126, int) -#define FIONREAD _IOR('f', 127, int) -#define TIOCINQ FIONREAD -#define FIOQSIZE _IOR('f', 128, loff_t) - -#define TIOCGETP _IOR('t', 8, struct sgttyb) -#define TIOCSETP _IOW('t', 9, struct sgttyb) -#define TIOCSETN _IOW('t', 10, struct sgttyb) /* TIOCSETP wo flush */ - -#define TIOCSETC _IOW('t', 17, struct tchars) -#define TIOCGETC _IOR('t', 18, struct tchars) -#define TCGETS _IOR('t', 19, struct termios) -#define TCSETS _IOW('t', 20, struct termios) -#define TCSETSW _IOW('t', 21, struct termios) -#define TCSETSF _IOW('t', 22, struct termios) - -#define TCGETA _IOR('t', 23, struct termio) -#define TCSETA _IOW('t', 24, struct termio) -#define TCSETAW _IOW('t', 25, struct termio) -#define TCSETAF _IOW('t', 28, struct termio) - -#define TCSBRK _IO('t', 29) -#define TCXONC _IO('t', 30) -#define TCFLSH _IO('t', 31) - -#define TIOCSWINSZ _IOW('t', 103, struct winsize) -#define TIOCGWINSZ _IOR('t', 104, struct winsize) -#define TIOCSTART _IO('t', 110) /* start output, like ^Q */ -#define TIOCSTOP _IO('t', 111) /* stop output, like ^S */ -#define TIOCOUTQ _IOR('t', 115, int) /* output queue size */ - -#define TIOCGLTC _IOR('t', 116, struct ltchars) -#define TIOCSLTC _IOW('t', 117, struct ltchars) -#define TIOCSPGRP _IOW('t', 118, int) -#define TIOCGPGRP _IOR('t', 119, int) - -#define TIOCEXCL 0x540C -#define TIOCNXCL 0x540D -#define TIOCSCTTY 0x540E - -#define TIOCSTI 0x5412 -#define TIOCMGET 0x5415 -#define TIOCMBIS 0x5416 -#define TIOCMBIC 0x5417 -#define TIOCMSET 0x5418 -#define TIOCGSOFTCAR 0x5419 -#define TIOCSSOFTCAR 0x541A -#define TIOCLINUX 0x541C -#define TIOCCONS 0x541D -#define TIOCGSERIAL 0x541E -#define TIOCSSERIAL 0x541F -#define TIOCPKT 0x5420 - -#define TIOCNOTTY 0x5422 -#define TIOCSETD 0x5423 -#define TIOCGETD 0x5424 -#define TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */ - -#define TIOCSERCONFIG 0x5453 -#define TIOCSERGWILD 0x5454 -#define TIOCSERSWILD 0x5455 -#define TIOCGLCKTRMIOS 0x5456 -#define TIOCSLCKTRMIOS 0x5457 -#define TIOCSERGSTRUCT 0x5458 /* For debugging only */ -#define TIOCSERGETLSR 0x5459 /* Get line status register */ -#define TIOCSERGETMULTI 0x545A /* Get multiport config */ -#define TIOCSERSETMULTI 0x545B /* Set multiport config */ - -#define TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */ -#define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */ - -/* Used for packet mode */ -#define TIOCPKT_DATA 0 -#define TIOCPKT_FLUSHREAD 1 -#define TIOCPKT_FLUSHWRITE 2 -#define TIOCPKT_STOP 4 -#define TIOCPKT_START 8 -#define TIOCPKT_NOSTOP 16 -#define TIOCPKT_DOSTOP 32 - -struct winsize { - unsigned short ws_row; - unsigned short ws_col; - unsigned short ws_xpixel; - unsigned short ws_ypixel; -}; - -#define NCC 10 -struct termio { - unsigned short c_iflag; /* input mode flags */ - unsigned short c_oflag; /* output mode flags */ - unsigned short c_cflag; /* control mode flags */ - unsigned short c_lflag; /* local mode flags */ - unsigned char c_line; /* line discipline */ - unsigned char c_cc[NCC]; /* control characters */ -}; - -/* c_cc characters */ -#define _VINTR 0 -#define _VQUIT 1 -#define _VERASE 2 -#define _VKILL 3 -#define _VEOF 4 -#define _VMIN 5 -#define _VEOL 6 -#define _VTIME 7 -#define _VEOL2 8 -#define _VSWTC 9 - -#ifdef __KERNEL__ -/* ^C ^\ del ^U ^D 1 0 0 0 0 ^W ^R ^Z ^Q ^S ^V ^U */ -#define INIT_C_CC "\003\034\177\025\004\001\000\000\000\000\027\022\032\021\023\026\025" -#endif /* __KERNEL__ */ - -/* modem lines */ -#define TIOCM_LE 0x001 -#define TIOCM_DTR 0x002 -#define TIOCM_RTS 0x004 -#define TIOCM_ST 0x008 -#define TIOCM_SR 0x010 -#define TIOCM_CTS 0x020 -#define TIOCM_CAR 0x040 -#define TIOCM_RNG 0x080 -#define TIOCM_DSR 0x100 -#define TIOCM_CD TIOCM_CAR -#define TIOCM_RI TIOCM_RNG -#define TIOCM_OUT1 0x2000 -#define TIOCM_OUT2 0x4000 -#define TIOCM_LOOP 0x8000 - -/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */ -#define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ - -/* line disciplines */ -#define N_TTY 0 -#define N_SLIP 1 -#define N_MOUSE 2 -#define N_PPP 3 -#define N_STRIP 4 -#define N_AX25 5 -#define N_X25 6 /* X.25 async */ -#define N_6PACK 7 -#define N_MASC 8 /* Reserved for Mobitex module */ -#define N_R3964 9 /* Reserved for Simatic R3964 module */ -#define N_PROFIBUS_FDL 10 /* Reserved for Profibus */ -#define N_IRDA 11 /* Linux IrDa - http://irda.sourceforge.net/ */ -#define N_SMSBLOCK 12 /* SMS block mode - for talking to GSM data cards about SMS messages */ -#define N_HDLC 13 /* synchronous HDLC */ -#define N_SYNC_PPP 14 -#define N_HCI 15 /* Bluetooth HCI UART */ - -#ifdef __KERNEL__ - -/* - * Translate a "termio" structure into a "termios". Ugh. - */ -#define SET_LOW_TERMIOS_BITS(termios, termio, x) { \ - unsigned short __tmp; \ - get_user(__tmp,&(termio)->x); \ - (termios)->x = (0xffff0000 & (termios)->x) | __tmp; \ -} - -#define user_termio_to_kernel_termios(termios, termio) \ -({ \ - SET_LOW_TERMIOS_BITS(termios, termio, c_iflag); \ - SET_LOW_TERMIOS_BITS(termios, termio, c_oflag); \ - SET_LOW_TERMIOS_BITS(termios, termio, c_cflag); \ - SET_LOW_TERMIOS_BITS(termios, termio, c_lflag); \ - copy_from_user((termios)->c_cc, (termio)->c_cc, NCC); \ -}) - -/* - * Translate a "termios" structure into a "termio". Ugh. - */ -#define kernel_termios_to_user_termio(termio, termios) \ -({ \ - put_user((termios)->c_iflag, &(termio)->c_iflag); \ - put_user((termios)->c_oflag, &(termio)->c_oflag); \ - put_user((termios)->c_cflag, &(termio)->c_cflag); \ - put_user((termios)->c_lflag, &(termio)->c_lflag); \ - put_user((termios)->c_line, &(termio)->c_line); \ - copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \ -}) - -#define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios)) -#define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios)) - -#endif /* __KERNEL__ */ - -#endif /* _PPC_TERMIOS_H */ diff -ruNp linus-powerpc.1a/include/asm-ppc/unaligned.h linus-powerpc.2/include/asm-ppc/unaligned.h --- linus-powerpc.1a/include/asm-ppc/unaligned.h 2005-06-27 16:08:08.000000000 +1000 +++ linus-powerpc.2/include/asm-ppc/unaligned.h 1970-01-01 10:00:00.000000000 +1000 @@ -1,18 +0,0 @@ -#ifdef __KERNEL__ -#ifndef __PPC_UNALIGNED_H -#define __PPC_UNALIGNED_H - -/* - * The PowerPC can do unaligned accesses itself in big endian mode. - * - * The strange macros are there to make sure these can't - * be misused in a way that makes them not work on other - * architectures where unaligned accesses aren't as simple. - */ - -#define get_unaligned(ptr) (*(ptr)) - -#define put_unaligned(val, ptr) ((void)( *(ptr) = (val) )) - -#endif -#endif /* __KERNEL__ */ diff -ruNp linus-powerpc.1a/include/asm-ppc64/div64.h linus-powerpc.2/include/asm-ppc64/div64.h --- linus-powerpc.1a/include/asm-ppc64/div64.h 1970-01-01 10:00:00.000000000 +1000 +++ linus-powerpc.2/include/asm-ppc64/div64.h 2005-06-27 16:08:08.000000000 +1000 @@ -0,0 +1 @@ +#include diff -ruNp linus-powerpc.1a/include/asm-ppc64/errno.h linus-powerpc.2/include/asm-ppc64/errno.h --- linus-powerpc.1a/include/asm-ppc64/errno.h 2005-06-27 17:55:59.000000000 +1000 +++ linus-powerpc.2/include/asm-ppc64/errno.h 1970-01-01 10:00:00.000000000 +1000 @@ -1,18 +0,0 @@ -#ifndef _PPC64_ERRNO_H -#define _PPC64_ERRNO_H - -/* - * 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 - -#undef EDEADLOCK -#define EDEADLOCK 58 /* File locking deadlock error */ - -#define _LAST_ERRNO 516 - -#endif diff -ruNp linus-powerpc.1a/include/asm-ppc64/ioctl.h linus-powerpc.2/include/asm-ppc64/ioctl.h --- linus-powerpc.1a/include/asm-ppc64/ioctl.h 2005-06-27 17:55:59.000000000 +1000 +++ linus-powerpc.2/include/asm-ppc64/ioctl.h 1970-01-01 10:00:00.000000000 +1000 @@ -1,74 +0,0 @@ -#ifndef _PPC64_IOCTL_H -#define _PPC64_IOCTL_H - - -/* - * This was copied from the alpha as it's a bit cleaner there. - * -- Cort - * - * 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. - */ - -#define _IOC_NRBITS 8 -#define _IOC_TYPEBITS 8 -#define _IOC_SIZEBITS 13 -#define _IOC_DIRBITS 3 - -#define _IOC_NRMASK ((1 << _IOC_NRBITS)-1) -#define _IOC_TYPEMASK ((1 << _IOC_TYPEBITS)-1) -#define _IOC_SIZEMASK ((1 << _IOC_SIZEBITS)-1) -#define _IOC_DIRMASK ((1 << _IOC_DIRBITS)-1) - -#define _IOC_NRSHIFT 0 -#define _IOC_TYPESHIFT (_IOC_NRSHIFT+_IOC_NRBITS) -#define _IOC_SIZESHIFT (_IOC_TYPESHIFT+_IOC_TYPEBITS) -#define _IOC_DIRSHIFT (_IOC_SIZESHIFT+_IOC_SIZEBITS) - -/* - * Direction bits _IOC_NONE could be 0, but OSF/1 gives it a bit. - * And this turns out useful to catch old ioctl numbers in header - * files for us. - */ -#define _IOC_NONE 1U -#define _IOC_READ 2U -#define _IOC_WRITE 4U - -#define _IOC(dir,type,nr,size) \ - (((dir) << _IOC_DIRSHIFT) | \ - ((type) << _IOC_TYPESHIFT) | \ - ((nr) << _IOC_NRSHIFT) | \ - ((size) << _IOC_SIZESHIFT)) - -/* provoke compile error for invalid uses of size argument */ -extern unsigned int __invalid_size_argument_for_IOC; -#define _IOC_TYPECHECK(t) \ - ((sizeof(t) == sizeof(t[1]) && \ - sizeof(t) < (1 << _IOC_SIZEBITS)) ? \ - sizeof(t) : __invalid_size_argument_for_IOC) - -/* used to create numbers */ -#define _IO(type,nr) _IOC(_IOC_NONE,(type),(nr),0) -#define _IOR(type,nr,size) _IOC(_IOC_READ,(type),(nr),(_IOC_TYPECHECK(size))) -#define _IOW(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size))) -#define _IOWR(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size))) -#define _IOR_BAD(type,nr,size) _IOC(_IOC_READ,(type),(nr),sizeof(size)) -#define _IOW_BAD(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),sizeof(size)) -#define _IOWR_BAD(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size)) - -/* used to decode them.. */ -#define _IOC_DIR(nr) (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK) -#define _IOC_TYPE(nr) (((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK) -#define _IOC_NR(nr) (((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK) -#define _IOC_SIZE(nr) (((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK) - -/* various drivers, such as the pcmcia stuff, need these... */ -#define IOC_IN (_IOC_WRITE << _IOC_DIRSHIFT) -#define IOC_OUT (_IOC_READ << _IOC_DIRSHIFT) -#define IOC_INOUT ((_IOC_WRITE|_IOC_READ) << _IOC_DIRSHIFT) -#define IOCSIZE_MASK (_IOC_SIZEMASK << _IOC_SIZESHIFT) -#define IOCSIZE_SHIFT (_IOC_SIZESHIFT) - -#endif /* _PPC64_IOCTL_H */ diff -ruNp linus-powerpc.1a/include/asm-ppc64/ioctls.h linus-powerpc.2/include/asm-ppc64/ioctls.h --- linus-powerpc.1a/include/asm-ppc64/ioctls.h 2005-06-27 17:55:59.000000000 +1000 +++ linus-powerpc.2/include/asm-ppc64/ioctls.h 1970-01-01 10:00:00.000000000 +1000 @@ -1,114 +0,0 @@ -#ifndef _ASM_PPC64_IOCTLS_H -#define _ASM_PPC64_IOCTLS_H - -/* - * 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 - -#define FIOCLEX _IO('f', 1) -#define FIONCLEX _IO('f', 2) -#define FIOASYNC _IOW('f', 125, int) -#define FIONBIO _IOW('f', 126, int) -#define FIONREAD _IOR('f', 127, int) -#define TIOCINQ FIONREAD -#define FIOQSIZE _IOR('f', 128, loff_t) - -#define TIOCGETP _IOR('t', 8, struct sgttyb) -#define TIOCSETP _IOW('t', 9, struct sgttyb) -#define TIOCSETN _IOW('t', 10, struct sgttyb) /* TIOCSETP wo flush */ - -#define TIOCSETC _IOW('t', 17, struct tchars) -#define TIOCGETC _IOR('t', 18, struct tchars) -#define TCGETS _IOR('t', 19, struct termios) -#define TCSETS _IOW('t', 20, struct termios) -#define TCSETSW _IOW('t', 21, struct termios) -#define TCSETSF _IOW('t', 22, struct termios) - -#define TCGETA _IOR('t', 23, struct termio) -#define TCSETA _IOW('t', 24, struct termio) -#define TCSETAW _IOW('t', 25, struct termio) -#define TCSETAF _IOW('t', 28, struct termio) - -#define TCSBRK _IO('t', 29) -#define TCXONC _IO('t', 30) -#define TCFLSH _IO('t', 31) - -#define TIOCSWINSZ _IOW('t', 103, struct winsize) -#define TIOCGWINSZ _IOR('t', 104, struct winsize) -#define TIOCSTART _IO('t', 110) /* start output, like ^Q */ -#define TIOCSTOP _IO('t', 111) /* stop output, like ^S */ -#define TIOCOUTQ _IOR('t', 115, int) /* output queue size */ - -#define TIOCGLTC _IOR('t', 116, struct ltchars) -#define TIOCSLTC _IOW('t', 117, struct ltchars) -#define TIOCSPGRP _IOW('t', 118, int) -#define TIOCGPGRP _IOR('t', 119, int) - -#define TIOCEXCL 0x540C -#define TIOCNXCL 0x540D -#define TIOCSCTTY 0x540E - -#define TIOCSTI 0x5412 -#define TIOCMGET 0x5415 -#define TIOCMBIS 0x5416 -#define TIOCMBIC 0x5417 -#define TIOCMSET 0x5418 -# define TIOCM_LE 0x001 -# define TIOCM_DTR 0x002 -# define TIOCM_RTS 0x004 -# define TIOCM_ST 0x008 -# define TIOCM_SR 0x010 -# define TIOCM_CTS 0x020 -# define TIOCM_CAR 0x040 -# define TIOCM_RNG 0x080 -# define TIOCM_DSR 0x100 -# define TIOCM_CD TIOCM_CAR -# define TIOCM_RI TIOCM_RNG - -#define TIOCGSOFTCAR 0x5419 -#define TIOCSSOFTCAR 0x541A -#define TIOCLINUX 0x541C -#define TIOCCONS 0x541D -#define TIOCGSERIAL 0x541E -#define TIOCSSERIAL 0x541F -#define TIOCPKT 0x5420 -# define TIOCPKT_DATA 0 -# define TIOCPKT_FLUSHREAD 1 -# define TIOCPKT_FLUSHWRITE 2 -# define TIOCPKT_STOP 4 -# define TIOCPKT_START 8 -# define TIOCPKT_NOSTOP 16 -# define TIOCPKT_DOSTOP 32 - - -#define TIOCNOTTY 0x5422 -#define TIOCSETD 0x5423 -#define TIOCGETD 0x5424 -#define TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */ -#define TIOCSBRK 0x5427 /* BSD compatibility */ -#define TIOCCBRK 0x5428 /* BSD compatibility */ -#define TIOCGSID 0x5429 /* Return the session ID of FD */ -#define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */ -#define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */ - -#define TIOCSERCONFIG 0x5453 -#define TIOCSERGWILD 0x5454 -#define TIOCSERSWILD 0x5455 -#define TIOCGLCKTRMIOS 0x5456 -#define TIOCSLCKTRMIOS 0x5457 -#define TIOCSERGSTRUCT 0x5458 /* For debugging only */ -#define TIOCSERGETLSR 0x5459 /* Get line status register */ - /* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */ -# define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ -#define TIOCSERGETMULTI 0x545A /* Get multiport config */ -#define TIOCSERSETMULTI 0x545B /* Set multiport config */ - -#define TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */ -#define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */ - -#endif /* _ASM_PPC64_IOCTLS_H */ diff -ruNp linus-powerpc.1a/include/asm-ppc64/local.h linus-powerpc.2/include/asm-ppc64/local.h --- linus-powerpc.1a/include/asm-ppc64/local.h 2005-06-27 16:08:08.000000000 +1000 +++ linus-powerpc.2/include/asm-ppc64/local.h 1970-01-01 10:00:00.000000000 +1000 @@ -1 +0,0 @@ -#include diff -ruNp linus-powerpc.1a/include/asm-ppc64/mman.h linus-powerpc.2/include/asm-ppc64/mman.h --- linus-powerpc.1a/include/asm-ppc64/mman.h 2005-06-27 17:55:59.000000000 +1000 +++ linus-powerpc.2/include/asm-ppc64/mman.h 1970-01-01 10:00:00.000000000 +1000 @@ -1,52 +0,0 @@ -#ifndef __PPC64_MMAN_H__ -#define __PPC64_MMAN_H__ - -/* - * 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. - */ - -#define PROT_READ 0x1 /* page can be read */ -#define PROT_WRITE 0x2 /* page can be written */ -#define PROT_EXEC 0x4 /* page can be executed */ -#define PROT_SEM 0x8 /* page may be used for atomic ops */ -#define PROT_NONE 0x0 /* page can not be accessed */ -#define PROT_GROWSDOWN 0x01000000 /* mprotect flag: extend change to start of growsdown vma */ -#define PROT_GROWSUP 0x02000000 /* mprotect flag: extend change to end of growsup vma */ - -#define MAP_SHARED 0x01 /* Share changes */ -#define MAP_PRIVATE 0x02 /* Changes are private */ -#define MAP_TYPE 0x0f /* Mask for type of mapping */ -#define MAP_FIXED 0x10 /* Interpret addr exactly */ -#define MAP_ANONYMOUS 0x20 /* don't use a file */ -#define MAP_RENAME MAP_ANONYMOUS /* In SunOS terminology */ -#define MAP_NORESERVE 0x40 /* don't reserve swap pages */ -#define MAP_LOCKED 0x80 - -#define MAP_GROWSDOWN 0x0100 /* stack-like segment */ -#define MAP_DENYWRITE 0x0800 /* ETXTBSY */ -#define MAP_EXECUTABLE 0x1000 /* mark it as an executable */ - -#define MS_ASYNC 1 /* sync memory asynchronously */ -#define MS_INVALIDATE 2 /* invalidate the caches */ -#define MS_SYNC 4 /* synchronous memory sync */ - -#define MCL_CURRENT 0x2000 /* lock all currently mapped pages */ -#define MCL_FUTURE 0x4000 /* lock all additions to address space */ - -#define MAP_POPULATE 0x8000 /* populate (prefault) pagetables */ -#define MAP_NONBLOCK 0x10000 /* do not block on IO */ - -#define MADV_NORMAL 0x0 /* default page-in behavior */ -#define MADV_RANDOM 0x1 /* page-in minimum required */ -#define MADV_SEQUENTIAL 0x2 /* read-ahead aggressively */ -#define MADV_WILLNEED 0x3 /* pre-fault pages */ -#define MADV_DONTNEED 0x4 /* discard these pages */ - -/* compatibility flags */ -#define MAP_ANON MAP_ANONYMOUS -#define MAP_FILE 0 - -#endif /* __PPC64_MMAN_H__ */ diff -ruNp linus-powerpc.1a/include/asm-ppc64/param.h linus-powerpc.2/include/asm-ppc64/param.h --- linus-powerpc.1a/include/asm-ppc64/param.h 2005-06-27 17:55:59.000000000 +1000 +++ linus-powerpc.2/include/asm-ppc64/param.h 1970-01-01 10:00:00.000000000 +1000 @@ -1,29 +0,0 @@ -#ifndef _ASM_PPC64_PARAM_H -#define _ASM_PPC64_PARAM_H - -/* - * 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. - */ - -#ifdef __KERNEL__ -# define HZ 1000 /* Internal kernel timer frequency */ -# define USER_HZ 100 /* .. some user interfaces are in "ticks" */ -# define CLOCKS_PER_SEC (USER_HZ) /* like times() */ -#endif - -#ifndef HZ -#define HZ 100 -#endif - -#define EXEC_PAGESIZE 4096 - -#ifndef NOGROUP -#define NOGROUP (-1) -#endif - -#define MAXHOSTNAMELEN 64 /* max length of hostname */ - -#endif /* _ASM_PPC64_PARAM_H */ diff -ruNp linus-powerpc.1a/include/asm-ppc64/parport.h linus-powerpc.2/include/asm-ppc64/parport.h --- linus-powerpc.1a/include/asm-ppc64/parport.h 2005-06-27 17:55:59.000000000 +1000 +++ linus-powerpc.2/include/asm-ppc64/parport.h 1970-01-01 10:00:00.000000000 +1000 @@ -1,18 +0,0 @@ -/* - * parport.h: platform-specific PC-style parport initialisation - * - * Copyright (C) 1999, 2000 Tim Waugh - * - * This file should only be included by drivers/parport/parport_pc.c. - */ - -#ifndef _ASM_PPC64_PARPORT_H -#define _ASM_PPC64_PARPORT_H - -static int __devinit parport_pc_find_isa_ports (int autoirq, int autodma); -static int __devinit parport_pc_find_nonpci_ports (int autoirq, int autodma) -{ - return parport_pc_find_isa_ports (autoirq, autodma); -} - -#endif /* !(_ASM_PPC_PARPORT_H) */ diff -ruNp linus-powerpc.1a/include/asm-ppc64/percpu.h linus-powerpc.2/include/asm-ppc64/percpu.h --- linus-powerpc.1a/include/asm-ppc64/percpu.h 2005-06-27 16:08:08.000000000 +1000 +++ linus-powerpc.2/include/asm-ppc64/percpu.h 1970-01-01 10:00:00.000000000 +1000 @@ -1,6 +0,0 @@ -#ifndef __ARCH_PPC64_PERCPU__ -#define __ARCH_PPC64_PERCPU__ - -#include - -#endif /* __ARCH_PPC64_PERCPU__ */ diff -ruNp linus-powerpc.1a/include/asm-ppc64/poll.h linus-powerpc.2/include/asm-ppc64/poll.h --- linus-powerpc.1a/include/asm-ppc64/poll.h 2005-06-27 17:55:59.000000000 +1000 +++ linus-powerpc.2/include/asm-ppc64/poll.h 1970-01-01 10:00:00.000000000 +1000 @@ -1,32 +0,0 @@ -#ifndef __PPC64_POLL_H -#define __PPC64_POLL_H - -/* - * Copyright (C) 2001 PPC64 Team, IBM Corp - * - * 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. - */ - -#define POLLIN 0x0001 -#define POLLPRI 0x0002 -#define POLLOUT 0x0004 -#define POLLERR 0x0008 -#define POLLHUP 0x0010 -#define POLLNVAL 0x0020 -#define POLLRDNORM 0x0040 -#define POLLRDBAND 0x0080 -#define POLLWRNORM 0x0100 -#define POLLWRBAND 0x0200 -#define POLLMSG 0x0400 -#define POLLREMOVE 0x1000 - -struct pollfd { - int fd; - short events; - short revents; -}; - -#endif /* __PPC64_POLL_H */ diff -ruNp linus-powerpc.1a/include/asm-ppc64/resource.h linus-powerpc.2/include/asm-ppc64/resource.h --- linus-powerpc.1a/include/asm-ppc64/resource.h 2005-06-27 16:08:08.000000000 +1000 +++ linus-powerpc.2/include/asm-ppc64/resource.h 1970-01-01 10:00:00.000000000 +1000 @@ -1,6 +0,0 @@ -#ifndef _PPC64_RESOURCE_H -#define _PPC64_RESOURCE_H - -#include - -#endif /* _PPC64_RESOURCE_H */ diff -ruNp linus-powerpc.1a/include/asm-ppc64/shmparam.h linus-powerpc.2/include/asm-ppc64/shmparam.h --- linus-powerpc.1a/include/asm-ppc64/shmparam.h 2005-06-27 17:55:59.000000000 +1000 +++ linus-powerpc.2/include/asm-ppc64/shmparam.h 1970-01-01 10:00:00.000000000 +1000 @@ -1,13 +0,0 @@ -#ifndef _PPC64_SHMPARAM_H -#define _PPC64_SHMPARAM_H - -/* - * 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. - */ - -#define SHMLBA PAGE_SIZE /* attach addr a multiple of this */ - -#endif /* _PPC64_SHMPARAM_H */ diff -ruNp linus-powerpc.1a/include/asm-ppc64/string.h linus-powerpc.2/include/asm-ppc64/string.h --- linus-powerpc.1a/include/asm-ppc64/string.h 2005-06-27 17:55:59.000000000 +1000 +++ linus-powerpc.2/include/asm-ppc64/string.h 1970-01-01 10:00:00.000000000 +1000 @@ -1,35 +0,0 @@ -#ifndef _PPC64_STRING_H_ -#define _PPC64_STRING_H_ - -/* - * 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. - */ - -#define __HAVE_ARCH_STRCPY -#define __HAVE_ARCH_STRNCPY -#define __HAVE_ARCH_STRLEN -#define __HAVE_ARCH_STRCMP -#define __HAVE_ARCH_STRCAT -#define __HAVE_ARCH_MEMSET -#define __HAVE_ARCH_MEMCPY -#define __HAVE_ARCH_MEMMOVE -#define __HAVE_ARCH_MEMCMP -#define __HAVE_ARCH_MEMCHR - -extern int strcasecmp(const char *, const char *); -extern int strncasecmp(const char *, const char *, int); -extern char * strcpy(char *,const char *); -extern char * strncpy(char *,const char *, __kernel_size_t); -extern __kernel_size_t strlen(const char *); -extern int strcmp(const char *,const char *); -extern char * strcat(char *, const char *); -extern void * memset(void *,int,__kernel_size_t); -extern void * memcpy(void *,const void *,__kernel_size_t); -extern void * memmove(void *,const void *,__kernel_size_t); -extern int memcmp(const void *,const void *,__kernel_size_t); -extern void * memchr(const void *,int,__kernel_size_t); - -#endif /* _PPC64_STRING_H_ */ diff -ruNp linus-powerpc.1a/include/asm-ppc64/termbits.h linus-powerpc.2/include/asm-ppc64/termbits.h --- linus-powerpc.1a/include/asm-ppc64/termbits.h 2005-06-27 17:55:59.000000000 +1000 +++ linus-powerpc.2/include/asm-ppc64/termbits.h 1970-01-01 10:00:00.000000000 +1000 @@ -1,193 +0,0 @@ -#ifndef _PPC64_TERMBITS_H -#define _PPC64_TERMBITS_H - -/* - * 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 - -typedef unsigned char cc_t; -typedef unsigned int speed_t; -typedef unsigned int tcflag_t; - -/* - * termios type and macro definitions. Be careful about adding stuff - * to this file since it's used in GNU libc and there are strict rules - * concerning namespace pollution. - */ - -#define NCCS 19 -struct termios { - tcflag_t c_iflag; /* input mode flags */ - tcflag_t c_oflag; /* output mode flags */ - tcflag_t c_cflag; /* control mode flags */ - tcflag_t c_lflag; /* local mode flags */ - cc_t c_cc[NCCS]; /* control characters */ - cc_t c_line; /* line discipline (== c_cc[19]) */ - speed_t c_ispeed; /* input speed */ - speed_t c_ospeed; /* output speed */ -}; - -/* c_cc characters */ -#define VINTR 0 -#define VQUIT 1 -#define VERASE 2 -#define VKILL 3 -#define VEOF 4 -#define VMIN 5 -#define VEOL 6 -#define VTIME 7 -#define VEOL2 8 -#define VSWTC 9 -#define VWERASE 10 -#define VREPRINT 11 -#define VSUSP 12 -#define VSTART 13 -#define VSTOP 14 -#define VLNEXT 15 -#define VDISCARD 16 - -/* c_iflag bits */ -#define IGNBRK 0000001 -#define BRKINT 0000002 -#define IGNPAR 0000004 -#define PARMRK 0000010 -#define INPCK 0000020 -#define ISTRIP 0000040 -#define INLCR 0000100 -#define IGNCR 0000200 -#define ICRNL 0000400 -#define IXON 0001000 -#define IXOFF 0002000 -#define IXANY 0004000 -#define IUCLC 0010000 -#define IMAXBEL 0020000 -#define IUTF8 0040000 - -/* c_oflag bits */ -#define OPOST 0000001 -#define ONLCR 0000002 -#define OLCUC 0000004 - -#define OCRNL 0000010 -#define ONOCR 0000020 -#define ONLRET 0000040 - -#define OFILL 00000100 -#define OFDEL 00000200 -#define NLDLY 00001400 -#define NL0 00000000 -#define NL1 00000400 -#define NL2 00001000 -#define NL3 00001400 -#define TABDLY 00006000 -#define TAB0 00000000 -#define TAB1 00002000 -#define TAB2 00004000 -#define TAB3 00006000 -#define XTABS 00006000 /* required by POSIX to == TAB3 */ -#define CRDLY 00030000 -#define CR0 00000000 -#define CR1 00010000 -#define CR2 00020000 -#define CR3 00030000 -#define FFDLY 00040000 -#define FF0 00000000 -#define FF1 00040000 -#define BSDLY 00100000 -#define BS0 00000000 -#define BS1 00100000 -#define VTDLY 00200000 -#define VT0 00000000 -#define VT1 00200000 - -/* c_cflag bit meaning */ -#define CBAUD 0000377 -#define B0 0000000 /* hang up */ -#define B50 0000001 -#define B75 0000002 -#define B110 0000003 -#define B134 0000004 -#define B150 0000005 -#define B200 0000006 -#define B300 0000007 -#define B600 0000010 -#define B1200 0000011 -#define B1800 0000012 -#define B2400 0000013 -#define B4800 0000014 -#define B9600 0000015 -#define B19200 0000016 -#define B38400 0000017 -#define EXTA B19200 -#define EXTB B38400 -#define CBAUDEX 0000000 -#define B57600 00020 -#define B115200 00021 -#define B230400 00022 -#define B460800 00023 -#define B500000 00024 -#define B576000 00025 -#define B921600 00026 -#define B1000000 00027 -#define B1152000 00030 -#define B1500000 00031 -#define B2000000 00032 -#define B2500000 00033 -#define B3000000 00034 -#define B3500000 00035 -#define B4000000 00036 - -#define CSIZE 00001400 -#define CS5 00000000 -#define CS6 00000400 -#define CS7 00001000 -#define CS8 00001400 - -#define CSTOPB 00002000 -#define CREAD 00004000 -#define PARENB 00010000 -#define PARODD 00020000 -#define HUPCL 00040000 - -#define CLOCAL 00100000 -#define CRTSCTS 020000000000 /* flow control */ - -/* c_lflag bits */ -#define ISIG 0x00000080 -#define ICANON 0x00000100 -#define XCASE 0x00004000 -#define ECHO 0x00000008 -#define ECHOE 0x00000002 -#define ECHOK 0x00000004 -#define ECHONL 0x00000010 -#define NOFLSH 0x80000000 -#define TOSTOP 0x00400000 -#define ECHOCTL 0x00000040 -#define ECHOPRT 0x00000020 -#define ECHOKE 0x00000001 -#define FLUSHO 0x00800000 -#define PENDIN 0x20000000 -#define IEXTEN 0x00000400 - -/* Values for the ACTION argument to `tcflow'. */ -#define TCOOFF 0 -#define TCOON 1 -#define TCIOFF 2 -#define TCION 3 - -/* Values for the QUEUE_SELECTOR argument to `tcflush'. */ -#define TCIFLUSH 0 -#define TCOFLUSH 1 -#define TCIOFLUSH 2 - -/* Values for the OPTIONAL_ACTIONS argument to `tcsetattr'. */ -#define TCSANOW 0 -#define TCSADRAIN 1 -#define TCSAFLUSH 2 - -#endif /* _PPC64_TERMBITS_H */ diff -ruNp linus-powerpc.1a/include/asm-ppc64/termios.h linus-powerpc.2/include/asm-ppc64/termios.h --- linus-powerpc.1a/include/asm-ppc64/termios.h 2005-06-27 17:55:59.000000000 +1000 +++ linus-powerpc.2/include/asm-ppc64/termios.h 1970-01-01 10:00:00.000000000 +1000 @@ -1,235 +0,0 @@ -#ifndef _PPC64_TERMIOS_H -#define _PPC64_TERMIOS_H - -/* - * Liberally adapted from alpha/termios.h. In particular, the c_cc[] - * fields have been reordered so that termio & termios share the - * common subset in the same order (for brain dead programs that don't - * know or care about the differences). - * - * 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 -#include - -struct sgttyb { - char sg_ispeed; - char sg_ospeed; - char sg_erase; - char sg_kill; - short sg_flags; -}; - -struct tchars { - char t_intrc; - char t_quitc; - char t_startc; - char t_stopc; - char t_eofc; - char t_brkc; -}; - -struct ltchars { - char t_suspc; - char t_dsuspc; - char t_rprntc; - char t_flushc; - char t_werasc; - char t_lnextc; -}; - -struct winsize { - unsigned short ws_row; - unsigned short ws_col; - unsigned short ws_xpixel; - unsigned short ws_ypixel; -}; - -#define NCC 10 -struct termio { - unsigned short c_iflag; /* input mode flags */ - unsigned short c_oflag; /* output mode flags */ - unsigned short c_cflag; /* control mode flags */ - unsigned short c_lflag; /* local mode flags */ - unsigned char c_line; /* line discipline */ - unsigned char c_cc[NCC]; /* control characters */ -}; - -/* c_cc characters */ -#define _VINTR 0 -#define _VQUIT 1 -#define _VERASE 2 -#define _VKILL 3 -#define _VEOF 4 -#define _VMIN 5 -#define _VEOL 6 -#define _VTIME 7 -#define _VEOL2 8 -#define _VSWTC 9 - -/* line disciplines */ -#define N_TTY 0 -#define N_SLIP 1 -#define N_MOUSE 2 -#define N_PPP 3 -#define N_STRIP 4 -#define N_AX25 5 -#define N_X25 6 /* X.25 async */ -#define N_6PACK 7 -#define N_MASC 8 /* Reserved for Mobitex module */ -#define N_R3964 9 /* Reserved for Simatic R3964 module */ -#define N_PROFIBUS_FDL 10 /* Reserved for Profibus */ -#define N_IRDA 11 /* Linux IrDa - http://www.cs.uit.no/~dagb/irda/irda.html */ -#define N_SMSBLOCK 12 /* SMS block mode - for talking to GSM data cards about SMS messages */ -#define N_HDLC 13 /* synchronous HDLC */ -#define N_SYNC_PPP 14 - -#ifdef __KERNEL__ -/* ^C ^\ del ^U ^D 1 0 0 0 0 ^W ^R ^Z ^Q ^S ^V ^U */ -#define INIT_C_CC "\003\034\177\025\004\001\000\000\000\000\027\022\032\021\023\026\025" -#endif - -#define FIOCLEX _IO('f', 1) -#define FIONCLEX _IO('f', 2) -#define FIOASYNC _IOW('f', 125, int) -#define FIONBIO _IOW('f', 126, int) -#define FIONREAD _IOR('f', 127, int) -#define TIOCINQ FIONREAD - -#define TIOCGETP _IOR('t', 8, struct sgttyb) -#define TIOCSETP _IOW('t', 9, struct sgttyb) -#define TIOCSETN _IOW('t', 10, struct sgttyb) /* TIOCSETP wo flush */ - -#define TIOCSETC _IOW('t', 17, struct tchars) -#define TIOCGETC _IOR('t', 18, struct tchars) -#define TCGETS _IOR('t', 19, struct termios) -#define TCSETS _IOW('t', 20, struct termios) -#define TCSETSW _IOW('t', 21, struct termios) -#define TCSETSF _IOW('t', 22, struct termios) - -#define TCGETA _IOR('t', 23, struct termio) -#define TCSETA _IOW('t', 24, struct termio) -#define TCSETAW _IOW('t', 25, struct termio) -#define TCSETAF _IOW('t', 28, struct termio) - -#define TCSBRK _IO('t', 29) -#define TCXONC _IO('t', 30) -#define TCFLSH _IO('t', 31) - -#define TIOCSWINSZ _IOW('t', 103, struct winsize) -#define TIOCGWINSZ _IOR('t', 104, struct winsize) -#define TIOCSTART _IO('t', 110) /* start output, like ^Q */ -#define TIOCSTOP _IO('t', 111) /* stop output, like ^S */ -#define TIOCOUTQ _IOR('t', 115, int) /* output queue size */ - -#define TIOCGLTC _IOR('t', 116, struct ltchars) -#define TIOCSLTC _IOW('t', 117, struct ltchars) -#define TIOCSPGRP _IOW('t', 118, int) -#define TIOCGPGRP _IOR('t', 119, int) - -#define TIOCEXCL 0x540C -#define TIOCNXCL 0x540D -#define TIOCSCTTY 0x540E - -#define TIOCSTI 0x5412 -#define TIOCMGET 0x5415 -#define TIOCMBIS 0x5416 -#define TIOCMBIC 0x5417 -#define TIOCMSET 0x5418 -#define TIOCGSOFTCAR 0x5419 -#define TIOCSSOFTCAR 0x541A -#define TIOCLINUX 0x541C -#define TIOCCONS 0x541D -#define TIOCGSERIAL 0x541E -#define TIOCSSERIAL 0x541F -#define TIOCPKT 0x5420 - -#define TIOCNOTTY 0x5422 -#define TIOCSETD 0x5423 -#define TIOCGETD 0x5424 -#define TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */ - -#define TIOCSERCONFIG 0x5453 -#define TIOCSERGWILD 0x5454 -#define TIOCSERSWILD 0x5455 -#define TIOCGLCKTRMIOS 0x5456 -#define TIOCSLCKTRMIOS 0x5457 -#define TIOCSERGSTRUCT 0x5458 /* For debugging only */ -#define TIOCSERGETLSR 0x5459 /* Get line status register */ -#define TIOCSERGETMULTI 0x545A /* Get multiport config */ -#define TIOCSERSETMULTI 0x545B /* Set multiport config */ - -#define TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */ -#define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */ - -/* Used for packet mode */ -#define TIOCPKT_DATA 0 -#define TIOCPKT_FLUSHREAD 1 -#define TIOCPKT_FLUSHWRITE 2 -#define TIOCPKT_STOP 4 -#define TIOCPKT_START 8 -#define TIOCPKT_NOSTOP 16 -#define TIOCPKT_DOSTOP 32 - -/* modem lines */ -#define TIOCM_LE 0x001 -#define TIOCM_DTR 0x002 -#define TIOCM_RTS 0x004 -#define TIOCM_ST 0x008 -#define TIOCM_SR 0x010 -#define TIOCM_CTS 0x020 -#define TIOCM_CAR 0x040 -#define TIOCM_RNG 0x080 -#define TIOCM_DSR 0x100 -#define TIOCM_CD TIOCM_CAR -#define TIOCM_RI TIOCM_RNG -#define TIOCM_OUT1 0x2000 -#define TIOCM_OUT2 0x4000 -#define TIOCM_LOOP 0x8000 - -/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */ -#define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ - -#ifdef __KERNEL__ - -/* - * Translate a "termio" structure into a "termios". Ugh. - */ -#define SET_LOW_TERMIOS_BITS(termios, termio, x) { \ - unsigned short __tmp; \ - get_user(__tmp,&(termio)->x); \ - (termios)->x = (0xffff0000 & (termios)->x) | __tmp; \ -} - -#define user_termio_to_kernel_termios(termios, termio) \ -({ \ - SET_LOW_TERMIOS_BITS(termios, termio, c_iflag); \ - SET_LOW_TERMIOS_BITS(termios, termio, c_oflag); \ - SET_LOW_TERMIOS_BITS(termios, termio, c_cflag); \ - SET_LOW_TERMIOS_BITS(termios, termio, c_lflag); \ - copy_from_user((termios)->c_cc, (termio)->c_cc, NCC); \ -}) - -/* - * Translate a "termios" structure into a "termio". Ugh. - */ -#define kernel_termios_to_user_termio(termio, termios) \ -({ \ - put_user((termios)->c_iflag, &(termio)->c_iflag); \ - put_user((termios)->c_oflag, &(termio)->c_oflag); \ - put_user((termios)->c_cflag, &(termio)->c_cflag); \ - put_user((termios)->c_lflag, &(termio)->c_lflag); \ - put_user((termios)->c_line, &(termio)->c_line); \ - copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \ -}) - -#define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios)) -#define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios)) - -#endif /* __KERNEL__ */ - -#endif /* _PPC64_TERMIOS_H */ diff -ruNp linus-powerpc.1a/include/asm-ppc64/unaligned.h linus-powerpc.2/include/asm-ppc64/unaligned.h --- linus-powerpc.1a/include/asm-ppc64/unaligned.h 2005-06-27 17:55:59.000000000 +1000 +++ linus-powerpc.2/include/asm-ppc64/unaligned.h 1970-01-01 10:00:00.000000000 +1000 @@ -1,21 +0,0 @@ -#ifndef __PPC64_UNALIGNED_H -#define __PPC64_UNALIGNED_H - -/* - * The PowerPC can do unaligned accesses itself in big endian mode. - * - * The strange macros are there to make sure these can't - * be misused in a way that makes them not work on other - * architectures where unaligned accesses aren't as simple. - * - * 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. - */ - -#define get_unaligned(ptr) (*(ptr)) - -#define put_unaligned(val, ptr) ((void)( *(ptr) = (val) )) - -#endif /* __PPC64_UNALIGNED_H */ From sfr at canb.auug.org.au Fri Aug 5 18:37:56 2005 From: sfr at canb.auug.org.au (Stephen Rothwell) Date: Fri, 5 Aug 2005 18:37:56 +1000 Subject: [PATCH] 1/2 Start header file merger (Was: Re: Beginning Merger Patch) In-Reply-To: <20050805174705.731ffa05.sfr@canb.auug.org.au> References: <1123023575.2614.25.camel@cashmere.sps.mot.com> <688ba2276de281a9473b030a16a514c0@embeddededge.com> <20050805174705.731ffa05.sfr@canb.auug.org.au> Message-ID: <20050805183756.25c65e08.sfr@canb.auug.org.au> On Fri, 5 Aug 2005 17:47:05 +1000 Stephen Rothwell wrote: > > for i in * > do > [ -f ../asm-ppc64/$i ] && cmp -s $i ../asm-ppc64/$i && > mv $i ../asm-powerpc/$i && rm ../asm-ppc64/$i > done note to self: Never modify stuff in an email :-( that should be [While in .../asm-ppc64 ] for i in * do [ -f ../asm-ppc/$i ] && cmp -s $i ../asm-ppc/$i && mv $i ../asm-powerpc/$i && rm ../asm-ppc/$i done Sorry about that! -- Cheers, Stephen Rothwell sfr at canb.auug.org.au http://www.canb.auug.org.au/~sfr/ From michael at ellerman.id.au Fri Aug 5 19:08:20 2005 From: michael at ellerman.id.au (Michael Ellerman) Date: Fri, 5 Aug 2005 19:08:20 +1000 Subject: [PATCH] 1/2 Start header file merger (Was: Re: Beginning Merger Patch) In-Reply-To: <20050805174705.731ffa05.sfr@canb.auug.org.au> References: <1123023575.2614.25.camel@cashmere.sps.mot.com> <688ba2276de281a9473b030a16a514c0@embeddededge.com> <20050805174705.731ffa05.sfr@canb.auug.org.au> Message-ID: <200508051908.24019.michael@ellerman.id.au> And for the faint of heart there's a patch at: http://michael.ellerman.id.au/files/misc/header-merge.patch cheers On Fri, 5 Aug 2005 17:47, Stephen Rothwell wrote: > On Tue, 2 Aug 2005 19:10:56 -0400 Dan Malek wrote: > > On Aug 2, 2005, at 6:59 PM, Jon Loeliger wrote: > > > ..... A stub is left > > > in asm-ppc and asm-ppc64 pointing to the unified files. > > > > Why bother? You may as well change all of the source > > files, too, or else that will never get done :-) > > You actually don't need to modify (m)any source files. > > Here is an alternative approach. These patches depend on Olaf's > boot code cleanup for ppc64 (or similar). Do the following: > > cd linux/include > mkdir asm-powerpc > cd asm-ppc > for i in * > do > [ -e ../asm-ppc64/$i ] || mv $i ../asm-powerpc/$i > done > cd ../asm-ppc64 > for i in * > do > [ -e ../asm-ppc/$i ] || mv $i ../asm-powerpc/$i > done > for i in * > do > [ -f ../asm-ppc64/$i ] && cmp -s $i ../asm-ppc64/$i && > mv $i ../asm-powerpc/$i && rm ../asm-ppc64/$i > done > > Then apply the patch below and the patch in the following email. > > I have built this kernel for ppc (defconfig), ppc64 (iSeries, pSeries and > pmac). -- Michael Ellerman IBM OzLabs email: michael:ellerman.id.au inmsg: mpe:jabber.org wwweb: http://michael.ellerman.id.au phone: +61 2 6212 1183 (tie line 70 21183) We do not inherit the earth from our ancestors, we borrow it from our children. - S.M.A.R.T Person -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: not available Url : http://ozlabs.org/pipermail/linuxppc64-dev/attachments/20050805/aafd2187/attachment.pgp From david at gibson.dropbear.id.au Fri Aug 5 19:39:06 2005 From: david at gibson.dropbear.id.au (David Gibson) Date: Fri, 5 Aug 2005 19:39:06 +1000 Subject: [PATCH] Four level pagetables for ppc64 In-Reply-To: <20050804051307.GA27961@localhost.localdomain> References: <20050804051307.GA27961@localhost.localdomain> Message-ID: <20050805093906.GA3780@localhost.localdomain> On Thu, Aug 04, 2005 at 03:13:07PM +1000, David Gibson wrote: > Paul, > > Please forward upstream for -mm, and, after 2.6.13, mainline also. > > Implement 4-level pagetables for ppc64 Oops, just discovered that that version had some bugs in the hugepage handling. Corrected version below Implement 4-level pagetables for ppc64 This patch implements full four-level page tables for ppc64, thereby extending the usable user address range to 44 bits (16T). The patch uses a full page for the tables at the bottom and top level, and a quarter page for the intermediate levels. It uses full 64-bit pointers at every level, thus also increasing the addressable range of physical memory. This patch also tweaks the VSID allocation to allow matching range for user addresses (this halves the number of available contexts) and adds some #if and BUILD_BUG sanity checks. Signed-off-by: David Gibson arch/ppc64/mm/hash_utils.c | 2 arch/ppc64/mm/hugetlbpage.c | 185 +++++++++++++----------------------------- arch/ppc64/mm/imalloc.c | 2 arch/ppc64/mm/init.c | 62 +++++++++----- arch/ppc64/mm/slb_low.S | 2 arch/ppc64/mm/tlb.c | 95 ++++++++++++--------- include/asm-ppc64/imalloc.h | 2 include/asm-ppc64/mmu.h | 7 - include/asm-ppc64/page.h | 26 +++-- include/asm-ppc64/pgalloc.h | 93 +++++++++++++-------- include/asm-ppc64/pgtable.h | 90 ++++++++++++-------- include/asm-ppc64/processor.h | 4 12 files changed, 293 insertions(+), 277 deletions(-) Index: working-2.6/include/asm-ppc64/pgtable.h =================================================================== --- working-2.6.orig/include/asm-ppc64/pgtable.h 2005-07-28 16:44:21.000000000 +1000 +++ working-2.6/include/asm-ppc64/pgtable.h 2005-08-05 18:10:07.000000000 +1000 @@ -15,19 +15,24 @@ #include #endif /* __ASSEMBLY__ */ -#include - /* * Entries per page directory level. The PTE level must use a 64b record * for each page table entry. The PMD and PGD level use a 32b record for * each entry by assuming that each entry is page aligned. */ #define PTE_INDEX_SIZE 9 -#define PMD_INDEX_SIZE 10 -#define PGD_INDEX_SIZE 10 +#define PMD_INDEX_SIZE 7 +#define PUD_INDEX_SIZE 7 +#define PGD_INDEX_SIZE 9 + +#define PTE_TABLE_SIZE (sizeof(pte_t) << PTE_INDEX_SIZE) +#define PMD_TABLE_SIZE (sizeof(pmd_t) << PMD_INDEX_SIZE) +#define PUD_TABLE_SIZE (sizeof(pud_t) << PUD_INDEX_SIZE) +#define PGD_TABLE_SIZE (sizeof(pgd_t) << PGD_INDEX_SIZE) #define PTRS_PER_PTE (1 << PTE_INDEX_SIZE) #define PTRS_PER_PMD (1 << PMD_INDEX_SIZE) +#define PTRS_PER_PUD (1 << PMD_INDEX_SIZE) #define PTRS_PER_PGD (1 << PGD_INDEX_SIZE) /* PMD_SHIFT determines what a second-level page table entry can map */ @@ -35,8 +40,13 @@ #define PMD_SIZE (1UL << PMD_SHIFT) #define PMD_MASK (~(PMD_SIZE-1)) -/* PGDIR_SHIFT determines what a third-level page table entry can map */ -#define PGDIR_SHIFT (PMD_SHIFT + PMD_INDEX_SIZE) +/* PUD_SHIFT determines what a third-level page table entry can map */ +#define PUD_SHIFT (PMD_SHIFT + PMD_INDEX_SIZE) +#define PUD_SIZE (1UL << PUD_SHIFT) +#define PUD_MASK (~(PUD_SIZE-1)) + +/* PGDIR_SHIFT determines what a fourth-level page table entry can map */ +#define PGDIR_SHIFT (PUD_SHIFT + PUD_INDEX_SIZE) #define PGDIR_SIZE (1UL << PGDIR_SHIFT) #define PGDIR_MASK (~(PGDIR_SIZE-1)) @@ -45,15 +55,23 @@ /* * Size of EA range mapped by our pagetables. */ -#define EADDR_SIZE (PTE_INDEX_SIZE + PMD_INDEX_SIZE + \ - PGD_INDEX_SIZE + PAGE_SHIFT) -#define EADDR_MASK ((1UL << EADDR_SIZE) - 1) +#define PGTABLE_EADDR_SIZE (PTE_INDEX_SIZE + PMD_INDEX_SIZE + \ + PUD_INDEX_SIZE + PGD_INDEX_SIZE + PAGE_SHIFT) +#define PGTABLE_RANGE (1UL << PGTABLE_EADDR_SIZE) + +#if TASK_SIZE_USER64 > PGTABLE_RANGE +#error TASK_SIZE_USER64 exceeds pagetable range +#endif + +#if TASK_SIZE_USER64 > (1UL << (USER_ESID_BITS + SID_SHIFT)) +#error TASK_SIZE_USER64 exceeds user VSID range +#endif /* * Define the address range of the vmalloc VM area. */ #define VMALLOC_START (0xD000000000000000ul) -#define VMALLOC_SIZE (0x10000000000UL) +#define VMALLOC_SIZE (0x80000000000UL) #define VMALLOC_END (VMALLOC_START + VMALLOC_SIZE) /* @@ -154,8 +172,6 @@ #ifndef __ASSEMBLY__ int hash_huge_page(struct mm_struct *mm, unsigned long access, unsigned long ea, unsigned long vsid, int local); - -void hugetlb_mm_free_pgd(struct mm_struct *mm); #endif /* __ASSEMBLY__ */ #define HAVE_ARCH_UNMAPPED_AREA @@ -163,7 +179,6 @@ #else #define hash_huge_page(mm,a,ea,vsid,local) -1 -#define hugetlb_mm_free_pgd(mm) do {} while (0) #endif @@ -197,39 +212,45 @@ #define pte_pfn(x) ((unsigned long)((pte_val(x) >> PTE_SHIFT))) #define pte_page(x) pfn_to_page(pte_pfn(x)) -#define pmd_set(pmdp, ptep) \ - (pmd_val(*(pmdp)) = __ba_to_bpn(ptep)) +#define pmd_set(pmdp, ptep) ({BUG_ON((u64)ptep < KERNELBASE); pmd_val(*(pmdp)) = (unsigned long)(ptep);}) #define pmd_none(pmd) (!pmd_val(pmd)) #define pmd_bad(pmd) (pmd_val(pmd) == 0) #define pmd_present(pmd) (pmd_val(pmd) != 0) #define pmd_clear(pmdp) (pmd_val(*(pmdp)) = 0) -#define pmd_page_kernel(pmd) (__bpn_to_ba(pmd_val(pmd))) +#define pmd_page_kernel(pmd) (pmd_val(pmd)) #define pmd_page(pmd) virt_to_page(pmd_page_kernel(pmd)) -#define pud_set(pudp, pmdp) (pud_val(*(pudp)) = (__ba_to_bpn(pmdp))) +#define pud_set(pudp, pmdp) (pud_val(*(pudp)) = (unsigned long)(pmdp)) #define pud_none(pud) (!pud_val(pud)) -#define pud_bad(pud) ((pud_val(pud)) == 0UL) -#define pud_present(pud) (pud_val(pud) != 0UL) -#define pud_clear(pudp) (pud_val(*(pudp)) = 0UL) -#define pud_page(pud) (__bpn_to_ba(pud_val(pud))) +#define pud_bad(pud) ((pud_val(pud)) == 0) +#define pud_present(pud) (pud_val(pud) != 0) +#define pud_clear(pudp) (pud_val(*(pudp)) = 0) +#define pud_page(pud) (pud_val(pud)) + +#define pgd_set(pgdp, pudp) ({pgd_val(*(pgdp)) = (unsigned long)(pudp);}) +#define pgd_none(pgd) (!pgd_val(pgd)) +#define pgd_bad(pgd) (pgd_val(pgd) == 0) +#define pgd_present(pgd) (pgd_val(pgd) != 0) +#define pgd_clear(pgdp) (pgd_val(*(pgdp)) = 0) +#define pgd_page(pgd) (pgd_val(pgd)) /* * Find an entry in a page-table-directory. We combine the address region * (the high order N bits) and the pgd portion of the address. */ /* to avoid overflow in free_pgtables we don't use PTRS_PER_PGD here */ -#define pgd_index(address) (((address) >> (PGDIR_SHIFT)) & 0x7ff) +#define pgd_index(address) (((address) >> (PGDIR_SHIFT)) & 0x1ff) #define pgd_offset(mm, address) ((mm)->pgd + pgd_index(address)) -/* Find an entry in the second-level page table.. */ +#define pud_offset(pgdp, addr) \ + (((pud_t *) pgd_page(*(pgdp))) + (((addr) >> PUD_SHIFT) & (PTRS_PER_PUD - 1))) + #define pmd_offset(pudp,addr) \ - ((pmd_t *) pud_page(*(pudp)) + (((addr) >> PMD_SHIFT) & (PTRS_PER_PMD - 1))) + (((pmd_t *) pud_page(*(pudp))) + (((addr) >> PMD_SHIFT) & (PTRS_PER_PMD - 1))) -/* Find an entry in the third-level page table.. */ #define pte_offset_kernel(dir,addr) \ - ((pte_t *) pmd_page_kernel(*(dir)) \ - + (((addr) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))) + (((pte_t *) pmd_page_kernel(*(dir))) + (((addr) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))) #define pte_offset_map(dir,addr) pte_offset_kernel((dir), (addr)) #define pte_offset_map_nested(dir,addr) pte_offset_kernel((dir), (addr)) @@ -458,23 +479,18 @@ #define pte_same(A,B) (((pte_val(A) ^ pte_val(B)) & ~_PAGE_HPTEFLAGS) == 0) #define pmd_ERROR(e) \ - printk("%s:%d: bad pmd %08x.\n", __FILE__, __LINE__, pmd_val(e)) + printk("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, pmd_val(e)) +#define pud_ERROR(e) \ + printk("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, pud_val(e)) #define pgd_ERROR(e) \ - printk("%s:%d: bad pgd %08x.\n", __FILE__, __LINE__, pgd_val(e)) + printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e)) extern pgd_t swapper_pg_dir[]; extern void paging_init(void); -/* - * Because the huge pgtables are only 2 level, they can take - * at most around 4M, much less than one hugepage which the - * process is presumably entitled to use. So we don't bother - * freeing up the pagetables on unmap, and wait until - * destroy_context() to clean up the lot. - */ #define hugetlb_free_pgd_range(tlb, addr, end, floor, ceiling) \ - do { } while (0) + free_pgd_range(tlb, addr, end, floor, ceiling) /* * This gets called at the end of handling a page fault, when Index: working-2.6/include/asm-ppc64/page.h =================================================================== --- working-2.6.orig/include/asm-ppc64/page.h 2005-07-28 16:44:21.000000000 +1000 +++ working-2.6/include/asm-ppc64/page.h 2005-08-05 18:10:07.000000000 +1000 @@ -46,6 +46,7 @@ #define ARCH_HAS_HUGEPAGE_ONLY_RANGE #define ARCH_HAS_PREPARE_HUGEPAGE_RANGE +#define ARCH_HAS_SETCLEAR_HUGE_PTE #define touches_hugepage_low_range(mm, addr, len) \ (LOW_ESID_MASK((addr), (len)) & mm->context.htlb_segs) @@ -125,36 +126,42 @@ * Entries in the pte table are 64b, while entries in the pgd & pmd are 32b. */ typedef struct { unsigned long pte; } pte_t; -typedef struct { unsigned int pmd; } pmd_t; -typedef struct { unsigned int pgd; } pgd_t; +typedef struct { unsigned long pmd; } pmd_t; +typedef struct { unsigned long pud; } pud_t; +typedef struct { unsigned long pgd; } pgd_t; typedef struct { unsigned long pgprot; } pgprot_t; #define pte_val(x) ((x).pte) #define pmd_val(x) ((x).pmd) +#define pud_val(x) ((x).pud) #define pgd_val(x) ((x).pgd) #define pgprot_val(x) ((x).pgprot) -#define __pte(x) ((pte_t) { (x) } ) -#define __pmd(x) ((pmd_t) { (x) } ) -#define __pgd(x) ((pgd_t) { (x) } ) -#define __pgprot(x) ((pgprot_t) { (x) } ) +#define __pte(x) ((pte_t) { (x) }) +#define __pmd(x) ((pmd_t) { (x) }) +#define __pud(x) ((pud_t) { (x) }) +#define __pgd(x) ((pgd_t) { (x) }) +#define __pgprot(x) ((pgprot_t) { (x) }) #else /* * .. while these make it easier on the compiler */ typedef unsigned long pte_t; -typedef unsigned int pmd_t; -typedef unsigned int pgd_t; +typedef unsigned long pmd_t; +typedef unsigned long pud_t; +typedef unsigned long pgd_t; typedef unsigned long pgprot_t; #define pte_val(x) (x) #define pmd_val(x) (x) +#define pud_val(x) (x) #define pgd_val(x) (x) #define pgprot_val(x) (x) #define __pte(x) (x) #define __pmd(x) (x) +#define __pud(x) (x) #define __pgd(x) (x) #define __pgprot(x) (x) @@ -208,9 +215,6 @@ #define USER_REGION_ID (0UL) #define REGION_ID(ea) (((unsigned long)(ea)) >> REGION_SHIFT) -#define __bpn_to_ba(x) ((((unsigned long)(x)) << PAGE_SHIFT) + KERNELBASE) -#define __ba_to_bpn(x) ((((unsigned long)(x)) & ~REGION_MASK) >> PAGE_SHIFT) - #define __va(x) ((void *)((unsigned long)(x) + KERNELBASE)) #ifdef CONFIG_DISCONTIGMEM Index: working-2.6/include/asm-ppc64/pgalloc.h =================================================================== --- working-2.6.orig/include/asm-ppc64/pgalloc.h 2005-06-08 15:46:24.000000000 +1000 +++ working-2.6/include/asm-ppc64/pgalloc.h 2005-08-05 18:10:07.000000000 +1000 @@ -6,7 +6,12 @@ #include #include -extern kmem_cache_t *zero_cache; +extern kmem_cache_t *pgtable_cache[]; + +#define PTE_CACHE_NUM 0 +#define PMD_CACHE_NUM 1 +#define PUD_CACHE_NUM 1 +#define PGD_CACHE_NUM 0 /* * This program is free software; you can redistribute it and/or @@ -15,30 +20,40 @@ * 2 of the License, or (at your option) any later version. */ -static inline pgd_t * -pgd_alloc(struct mm_struct *mm) +static inline pgd_t *pgd_alloc(struct mm_struct *mm) +{ + return kmem_cache_alloc(pgtable_cache[PGD_CACHE_NUM], GFP_KERNEL); +} + +static inline void pgd_free(pgd_t *pgd) +{ + kmem_cache_free(pgtable_cache[PGD_CACHE_NUM], pgd); +} + +#define pgd_populate(MM, PGD, PUD) pgd_set(PGD, PUD) + +static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long addr) { - return kmem_cache_alloc(zero_cache, GFP_KERNEL); + return kmem_cache_alloc(pgtable_cache[PUD_CACHE_NUM], + GFP_KERNEL|__GFP_REPEAT); } -static inline void -pgd_free(pgd_t *pgd) +static inline void pud_free(pud_t *pud) { - kmem_cache_free(zero_cache, pgd); + kmem_cache_free(pgtable_cache[PUD_CACHE_NUM], pud); } #define pud_populate(MM, PUD, PMD) pud_set(PUD, PMD) -static inline pmd_t * -pmd_alloc_one(struct mm_struct *mm, unsigned long addr) +static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr) { - return kmem_cache_alloc(zero_cache, GFP_KERNEL|__GFP_REPEAT); + return kmem_cache_alloc(pgtable_cache[PMD_CACHE_NUM], + GFP_KERNEL|__GFP_REPEAT); } -static inline void -pmd_free(pmd_t *pmd) +static inline void pmd_free(pmd_t *pmd) { - kmem_cache_free(zero_cache, pmd); + kmem_cache_free(pgtable_cache[PMD_CACHE_NUM], pmd); } #define pmd_populate_kernel(mm, pmd, pte) pmd_set(pmd, pte) @@ -47,44 +62,58 @@ static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) { - return kmem_cache_alloc(zero_cache, GFP_KERNEL|__GFP_REPEAT); + return kmem_cache_alloc(pgtable_cache[PTE_CACHE_NUM], + GFP_KERNEL|__GFP_REPEAT); } static inline struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address) { - pte_t *pte = kmem_cache_alloc(zero_cache, GFP_KERNEL|__GFP_REPEAT); - if (pte) - return virt_to_page(pte); - return NULL; + return virt_to_page(pte_alloc_one_kernel(mm, address)); } static inline void pte_free_kernel(pte_t *pte) { - kmem_cache_free(zero_cache, pte); + kmem_cache_free(pgtable_cache[PTE_CACHE_NUM], pte); } static inline void pte_free(struct page *ptepage) { - kmem_cache_free(zero_cache, page_address(ptepage)); + pte_free_kernel(page_address(ptepage)); } -struct pte_freelist_batch +#define PGF_CACHENUM_MASK 0xf + +typedef struct pgtable_free { + unsigned long val; +} pgtable_free_t; + +static inline pgtable_free_t pgtable_free_cache(void *p, int cachenum, + unsigned long mask) { - struct rcu_head rcu; - unsigned int index; - struct page * pages[0]; -}; + BUG_ON(cachenum > PGF_CACHENUM_MASK); -#define PTE_FREELIST_SIZE ((PAGE_SIZE - sizeof(struct pte_freelist_batch)) / \ - sizeof(struct page *)) + return (pgtable_free_t){.val = ((unsigned long) p & ~mask) | cachenum}; +} -extern void pte_free_now(struct page *ptepage); -extern void pte_free_submit(struct pte_freelist_batch *batch); +static inline void pgtable_free(pgtable_free_t pgf) +{ + void *p = (void *)(pgf.val & ~PGF_CACHENUM_MASK); + int cachenum = pgf.val & PGF_CACHENUM_MASK; + + kmem_cache_free(pgtable_cache[cachenum], p); +} -DECLARE_PER_CPU(struct pte_freelist_batch *, pte_freelist_cur); +void pgtable_free_tlb(struct mmu_gather *tlb, pgtable_free_t pgf); -void __pte_free_tlb(struct mmu_gather *tlb, struct page *ptepage); -#define __pmd_free_tlb(tlb, pmd) __pte_free_tlb(tlb, virt_to_page(pmd)) +#define __pte_free_tlb(tlb, ptepage) \ + pgtable_free_tlb(tlb, pgtable_free_cache(page_address(ptepage), \ + PTE_CACHE_NUM, PTE_TABLE_SIZE-1)) +#define __pmd_free_tlb(tlb, pmd) \ + pgtable_free_tlb(tlb, pgtable_free_cache(pmd, \ + PMD_CACHE_NUM, PMD_TABLE_SIZE-1)) +#define __pud_free_tlb(tlb, pmd) \ + pgtable_free_tlb(tlb, pgtable_free_cache(pud, \ + PUD_CACHE_NUM, PUD_TABLE_SIZE-1)) #define check_pgt_cache() do { } while (0) Index: working-2.6/arch/ppc64/mm/init.c =================================================================== --- working-2.6.orig/arch/ppc64/mm/init.c 2005-08-01 10:50:44.000000000 +1000 +++ working-2.6/arch/ppc64/mm/init.c 2005-08-05 18:10:07.000000000 +1000 @@ -66,6 +66,14 @@ #include #include +#if PGTABLE_RANGE > USER_VSID_RANGE +#warning Limited user VSID range means pagetable space is wasted +#endif + +#if (TASK_SIZE_USER64 < PGTABLE_RANGE) && (TASK_SIZE_USER64 < USER_VSID_RANGE) +#warning TASK_SIZE is smaller than it needs to be. +#endif + int mem_init_done; unsigned long ioremap_bot = IMALLOC_BASE; static unsigned long phbs_io_bot = PHBS_IO_BASE; @@ -226,7 +234,7 @@ * Before that, we map using addresses going * up from ioremap_bot. imalloc will use * the addresses from ioremap_bot through - * IMALLOC_END (0xE000001fffffffff) + * IMALLOC_END * */ pa = addr & PAGE_MASK; @@ -417,12 +425,6 @@ int index; int err; -#ifdef CONFIG_HUGETLB_PAGE - /* We leave htlb_segs as it was, but for a fork, we need to - * clear the huge_pgdir. */ - mm->context.huge_pgdir = NULL; -#endif - again: if (!idr_pre_get(&mmu_context_idr, GFP_KERNEL)) return -ENOMEM; @@ -453,8 +455,6 @@ spin_unlock(&mmu_context_lock); mm->context.id = NO_CONTEXT; - - hugetlb_mm_free_pgd(mm); } /* @@ -833,23 +833,43 @@ return virt_addr; } -kmem_cache_t *zero_cache; - -static void zero_ctor(void *pte, kmem_cache_t *cache, unsigned long flags) +static void zero_ctor(void *addr, kmem_cache_t *cache, unsigned long flags) { - memset(pte, 0, PAGE_SIZE); + memset(addr, 0, kmem_cache_size(cache)); } +static const int pgtable_cache_size[2] = { + PTE_TABLE_SIZE, PMD_TABLE_SIZE +}; +static const char *pgtable_cache_name[ARRAY_SIZE(pgtable_cache_size)] = { + "pgd_pte_cache", "pud_pmd_cache", +}; + +kmem_cache_t *pgtable_cache[ARRAY_SIZE(pgtable_cache_size)]; + void pgtable_cache_init(void) { - zero_cache = kmem_cache_create("zero", - PAGE_SIZE, - 0, - SLAB_HWCACHE_ALIGN | SLAB_MUST_HWCACHE_ALIGN, - zero_ctor, - NULL); - if (!zero_cache) - panic("pgtable_cache_init(): could not create zero_cache!\n"); + int i; + + BUILD_BUG_ON(PTE_TABLE_SIZE != pgtable_cache_size[PTE_CACHE_NUM]); + BUILD_BUG_ON(PMD_TABLE_SIZE != pgtable_cache_size[PMD_CACHE_NUM]); + BUILD_BUG_ON(PUD_TABLE_SIZE != pgtable_cache_size[PUD_CACHE_NUM]); + BUILD_BUG_ON(PGD_TABLE_SIZE != pgtable_cache_size[PGD_CACHE_NUM]); + + for (i = 0; i < ARRAY_SIZE(pgtable_cache_size); i++) { + int size = pgtable_cache_size[i]; + const char *name = pgtable_cache_name[i]; + + pgtable_cache[i] = kmem_cache_create(name, + size, size, + SLAB_HWCACHE_ALIGN + | SLAB_MUST_HWCACHE_ALIGN, + zero_ctor, + NULL); + if (! pgtable_cache[i]) + panic("pgtable_cache_init(): could not create %s!\n", + name); + } } pgprot_t phys_mem_access_prot(struct file *file, unsigned long addr, Index: working-2.6/include/asm-ppc64/processor.h =================================================================== --- working-2.6.orig/include/asm-ppc64/processor.h 2005-07-28 16:44:21.000000000 +1000 +++ working-2.6/include/asm-ppc64/processor.h 2005-08-05 18:10:07.000000000 +1000 @@ -382,8 +382,8 @@ extern struct task_struct *last_task_used_math; extern struct task_struct *last_task_used_altivec; -/* 64-bit user address space is 41-bits (2TBs user VM) */ -#define TASK_SIZE_USER64 (0x0000020000000000UL) +/* 64-bit user address space is 44-bits (16TB user VM) */ +#define TASK_SIZE_USER64 (0x0000100000000000UL) /* * 32-bit user address space is 4GB - 1 page Index: working-2.6/arch/ppc64/mm/imalloc.c =================================================================== --- working-2.6.orig/arch/ppc64/mm/imalloc.c 2005-07-28 16:43:47.000000000 +1000 +++ working-2.6/arch/ppc64/mm/imalloc.c 2005-08-05 18:10:07.000000000 +1000 @@ -31,7 +31,7 @@ break; if ((unsigned long)tmp->addr >= ioremap_bot) addr = tmp->size + (unsigned long) tmp->addr; - if (addr > IMALLOC_END-size) + if (addr >= IMALLOC_END-size) return 1; } *im_addr = addr; Index: working-2.6/arch/ppc64/mm/hash_utils.c =================================================================== --- working-2.6.orig/arch/ppc64/mm/hash_utils.c 2005-08-01 10:50:44.000000000 +1000 +++ working-2.6/arch/ppc64/mm/hash_utils.c 2005-08-05 18:10:07.000000000 +1000 @@ -302,7 +302,7 @@ int local = 0; cpumask_t tmp; - if ((ea & ~REGION_MASK) > EADDR_MASK) + if ((ea & ~REGION_MASK) >= PGTABLE_RANGE) return 1; switch (REGION_ID(ea)) { Index: working-2.6/include/asm-ppc64/mmu.h =================================================================== --- working-2.6.orig/include/asm-ppc64/mmu.h 2005-08-01 10:50:46.000000000 +1000 +++ working-2.6/include/asm-ppc64/mmu.h 2005-08-05 18:10:07.000000000 +1000 @@ -259,8 +259,10 @@ #define VSID_BITS 36 #define VSID_MODULUS ((1UL<index; i++) + pgtable_free(batch->tables[i]); + + free_page((unsigned long)batch); +} + +static void pte_free_submit(struct pte_freelist_batch *batch) +{ + INIT_RCU_HEAD(&batch->rcu); + call_rcu(&batch->rcu, pte_free_rcu_callback); +} + +void pgtable_free_tlb(struct mmu_gather *tlb, pgtable_free_t pgf) { /* This is safe as we are holding page_table_lock */ cpumask_t local_cpumask = cpumask_of_cpu(smp_processor_id()); @@ -49,19 +100,19 @@ if (atomic_read(&tlb->mm->mm_users) < 2 || cpus_equal(tlb->mm->cpu_vm_mask, local_cpumask)) { - pte_free(ptepage); + pgtable_free(pgf); return; } if (*batchp == NULL) { *batchp = (struct pte_freelist_batch *)__get_free_page(GFP_ATOMIC); if (*batchp == NULL) { - pte_free_now(ptepage); + pgtable_free_now(pgf); return; } (*batchp)->index = 0; } - (*batchp)->pages[(*batchp)->index++] = ptepage; + (*batchp)->tables[(*batchp)->index++] = pgf; if ((*batchp)->index == PTE_FREELIST_SIZE) { pte_free_submit(*batchp); *batchp = NULL; @@ -132,42 +183,6 @@ put_cpu(); } -#ifdef CONFIG_SMP -static void pte_free_smp_sync(void *arg) -{ - /* Do nothing, just ensure we sync with all CPUs */ -} -#endif - -/* This is only called when we are critically out of memory - * (and fail to get a page in pte_free_tlb). - */ -void pte_free_now(struct page *ptepage) -{ - pte_freelist_forced_free++; - - smp_call_function(pte_free_smp_sync, NULL, 0, 1); - - pte_free(ptepage); -} - -static void pte_free_rcu_callback(struct rcu_head *head) -{ - struct pte_freelist_batch *batch = - container_of(head, struct pte_freelist_batch, rcu); - unsigned int i; - - for (i = 0; i < batch->index; i++) - pte_free(batch->pages[i]); - free_page((unsigned long)batch); -} - -void pte_free_submit(struct pte_freelist_batch *batch) -{ - INIT_RCU_HEAD(&batch->rcu); - call_rcu(&batch->rcu, pte_free_rcu_callback); -} - void pte_free_finish(void) { /* This is safe as we are holding page_table_lock */ Index: working-2.6/arch/ppc64/mm/hugetlbpage.c =================================================================== --- working-2.6.orig/arch/ppc64/mm/hugetlbpage.c 2005-08-01 10:50:44.000000000 +1000 +++ working-2.6/arch/ppc64/mm/hugetlbpage.c 2005-08-05 18:10:07.000000000 +1000 @@ -27,124 +27,91 @@ #include -#define HUGEPGDIR_SHIFT (HPAGE_SHIFT + PAGE_SHIFT - 3) -#define HUGEPGDIR_SIZE (1UL << HUGEPGDIR_SHIFT) -#define HUGEPGDIR_MASK (~(HUGEPGDIR_SIZE-1)) - -#define HUGEPTE_INDEX_SIZE 9 -#define HUGEPGD_INDEX_SIZE 10 - -#define PTRS_PER_HUGEPTE (1 << HUGEPTE_INDEX_SIZE) -#define PTRS_PER_HUGEPGD (1 << HUGEPGD_INDEX_SIZE) - -static inline int hugepgd_index(unsigned long addr) +/* Modelled after find_linux_pte() */ +pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr) { - return (addr & ~REGION_MASK) >> HUGEPGDIR_SHIFT; -} + pgd_t *pg; + pud_t *pu; + pmd_t *pm; + pte_t *pt; -static pud_t *hugepgd_offset(struct mm_struct *mm, unsigned long addr) -{ - int index; + BUG_ON(! in_hugepage_area(mm->context, addr)); - if (! mm->context.huge_pgdir) - return NULL; + addr &= HPAGE_MASK; + pg = pgd_offset(mm, addr); + if (!pgd_none(*pg)) { + pu = pud_offset(pg, addr); + if (!pud_none(*pu)) { + pm = pmd_offset(pu, addr); + pt = (pte_t *)pm; + BUG_ON(!pmd_none(*pm) + && !(pte_present(*pt) && pte_huge(*pt))); + return pt; + } + } - index = hugepgd_index(addr); - BUG_ON(index >= PTRS_PER_HUGEPGD); - return (pud_t *)(mm->context.huge_pgdir + index); + return NULL; } -static inline pte_t *hugepte_offset(pud_t *dir, unsigned long addr) +pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr) { - int index; - - if (pud_none(*dir)) - return NULL; - - index = (addr >> HPAGE_SHIFT) % PTRS_PER_HUGEPTE; - return (pte_t *)pud_page(*dir) + index; -} + pgd_t *pg; + pud_t *pu; + pmd_t *pm; + pte_t *pt; -static pud_t *hugepgd_alloc(struct mm_struct *mm, unsigned long addr) -{ BUG_ON(! in_hugepage_area(mm->context, addr)); - if (! mm->context.huge_pgdir) { - pgd_t *new; - spin_unlock(&mm->page_table_lock); - /* Don't use pgd_alloc(), because we want __GFP_REPEAT */ - new = kmem_cache_alloc(zero_cache, GFP_KERNEL | __GFP_REPEAT); - BUG_ON(memcmp(new, empty_zero_page, PAGE_SIZE)); - spin_lock(&mm->page_table_lock); - - /* - * Because we dropped the lock, we should re-check the - * entry, as somebody else could have populated it.. - */ - if (mm->context.huge_pgdir) - pgd_free(new); - else - mm->context.huge_pgdir = new; - } - return hugepgd_offset(mm, addr); -} - -static pte_t *hugepte_alloc(struct mm_struct *mm, pud_t *dir, unsigned long addr) -{ - if (! pud_present(*dir)) { - pte_t *new; + addr &= HPAGE_MASK; - spin_unlock(&mm->page_table_lock); - new = kmem_cache_alloc(zero_cache, GFP_KERNEL | __GFP_REPEAT); - BUG_ON(memcmp(new, empty_zero_page, PAGE_SIZE)); - spin_lock(&mm->page_table_lock); - /* - * Because we dropped the lock, we should re-check the - * entry, as somebody else could have populated it.. - */ - if (pud_present(*dir)) { - if (new) - kmem_cache_free(zero_cache, new); - } else { - struct page *ptepage; + pg = pgd_offset(mm, addr); + pu = pud_alloc(mm, pg, addr); - if (! new) - return NULL; - ptepage = virt_to_page(new); - ptepage->mapping = (void *) mm; - ptepage->index = addr & HUGEPGDIR_MASK; - pud_populate(mm, dir, new); + if (pu) { + pm = pmd_alloc(mm, pu, addr); + if (pm) { + pt = (pte_t *)pm; + BUG_ON(!pmd_none(*pm) + && !(pte_present(*pt) && pte_huge(*pt))); + return pt; } } - return hugepte_offset(dir, addr); + return NULL; } -pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr) -{ - pud_t *pud; +#define HUGEPTE_BATCH_SIZE (HPAGE_SIZE / PMD_SIZE) - BUG_ON(! in_hugepage_area(mm->context, addr)); +void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, + pte_t *ptep, pte_t pte) +{ + int i; - pud = hugepgd_offset(mm, addr); - if (! pud) - return NULL; + if (pte_present(*ptep)) { + pte_clear(mm, addr, ptep); + flush_tlb_pending(); + } - return hugepte_offset(pud, addr); + for (i = 0; i < HUGEPTE_BATCH_SIZE; i++) { + *ptep = __pte(pte_val(pte) & ~_PAGE_HPTEFLAGS); + ptep++; + } } -pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr) +pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, + pte_t *ptep) { - pud_t *pud; + unsigned long old = pte_update(ptep, ~0UL); + int i; - BUG_ON(! in_hugepage_area(mm->context, addr)); + if (old & _PAGE_HASHPTE) + hpte_update(mm, addr, old, 0); - pud = hugepgd_alloc(mm, addr); - if (! pud) - return NULL; + for (i = 1; i < HUGEPTE_BATCH_SIZE; i++) + ptep[i] = __pte(0); - return hugepte_alloc(mm, pud, addr); + return __pte(old); } /* @@ -541,42 +508,6 @@ } } -void hugetlb_mm_free_pgd(struct mm_struct *mm) -{ - int i; - pgd_t *pgdir; - - spin_lock(&mm->page_table_lock); - - pgdir = mm->context.huge_pgdir; - if (! pgdir) - goto out; - - mm->context.huge_pgdir = NULL; - - /* cleanup any hugepte pages leftover */ - for (i = 0; i < PTRS_PER_HUGEPGD; i++) { - pud_t *pud = (pud_t *)(pgdir + i); - - if (! pud_none(*pud)) { - pte_t *pte = (pte_t *)pud_page(*pud); - struct page *ptepage = virt_to_page(pte); - - ptepage->mapping = NULL; - - BUG_ON(memcmp(pte, empty_zero_page, PAGE_SIZE)); - kmem_cache_free(zero_cache, pte); - } - pud_clear(pud); - } - - BUG_ON(memcmp(pgdir, empty_zero_page, PAGE_SIZE)); - kmem_cache_free(zero_cache, pgdir); - - out: - spin_unlock(&mm->page_table_lock); -} - int hash_huge_page(struct mm_struct *mm, unsigned long access, unsigned long ea, unsigned long vsid, int local) { Index: working-2.6/arch/ppc64/mm/slb_low.S =================================================================== --- working-2.6.orig/arch/ppc64/mm/slb_low.S 2005-05-24 14:12:22.000000000 +1000 +++ working-2.6/arch/ppc64/mm/slb_low.S 2005-08-05 18:10:07.000000000 +1000 @@ -91,7 +91,7 @@ 0: /* user address: proto-VSID = context<<15 | ESID */ li r11,SLB_VSID_USER - srdi. r9,r3,13 + srdi. r9,r3,USER_ESID_BITS bne- 8f /* invalid ea bits set */ #ifdef CONFIG_HUGETLB_PAGE -- David Gibson | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/people/dgibson From arnd at arndb.de Fri Aug 5 21:53:22 2005 From: arnd at arndb.de (Arnd Bergmann) Date: Fri, 5 Aug 2005 13:53:22 +0200 Subject: [PATCH] 1/2 Start header file merger (Was: Re: Beginning Merger Patch) In-Reply-To: <20050805174705.731ffa05.sfr@canb.auug.org.au> References: <1123023575.2614.25.camel@cashmere.sps.mot.com> <688ba2276de281a9473b030a16a514c0@embeddededge.com> <20050805174705.731ffa05.sfr@canb.auug.org.au> Message-ID: <200508051353.23750.arnd@arndb.de> On Freedag 05 August 2005 09:47, Stephen Rothwell wrote: > cd linux/include > mkdir asm-powerpc > cd asm-ppc > for i in * > do > ????????[ -e ../asm-ppc64/$i ] || mv $i ../asm-powerpc/$i > done > cd ../asm-ppc64 > for i in * > do > ????????[ -e ../asm-ppc/$i ] || mv $i ../asm-powerpc/$i > done While I really like your approach in general (I've done it the same way when merging asm-s390{,x]), I think we should take a little care to move only the files that we really want in asm/powerpc. E.g, most of the files that are in asm-ppc but not in asm-ppc64 seem so be board-specific or cpu-specific, so I'd not move them around before (unless) moving the platform code for those as well. Also, for everything below include/asm-ppc64/iSeries, it would make sense to rename the files to lowercase in the same step and change all their users. > for i in * > do > ????????[ -f ../asm-ppc64/$i ] && cmp -s $i ../asm-ppc64/$i && > ????????????????mv $i ../asm-powerpc/$i && rm ../asm-ppc64/$i > done Another help for merging further is to do for i in `ls include/asm-ppc` ; do if [ -e include/asm-ppc64/$i ] ; then diff --ifdef __powerpc64__ include/asm-{ppc,ppc64}/$i > \ include/asm-generic/$i ; fi done Note that you need to hand-edit practically every file that you get from this, but many of them become trivial to merge. Another interesting point about it is which define to use. For s390, we decided to '#ifdef __s390x__' rather than '#ifdef CONFIG_ARCH_S390X' or 'ifdef CONFIG_64BIT', because CONFIG_* does not work when including the headers from user space. Using CONFIG_64BIT instead of __powerpc64__ only within #ifdef __KERNEL__ would be correct but less consistant. Arnd <>< From sfr at canb.auug.org.au Sat Aug 6 00:59:41 2005 From: sfr at canb.auug.org.au (Stephen Rothwell) Date: Sat, 6 Aug 2005 00:59:41 +1000 Subject: [PATCH] 1/2 Start header file merger (Was: Re: Beginning Merger Patch) In-Reply-To: <200508051353.23750.arnd@arndb.de> References: <1123023575.2614.25.camel@cashmere.sps.mot.com> <688ba2276de281a9473b030a16a514c0@embeddededge.com> <20050805174705.731ffa05.sfr@canb.auug.org.au> <200508051353.23750.arnd@arndb.de> Message-ID: <20050806005941.5d1fe432.sfr@canb.auug.org.au> Hi Arnd, On Fri, 5 Aug 2005 13:53:22 +0200 Arnd Bergmann wrote: > > While I really like your approach in general (I've done it the > same way when merging asm-s390{,x]), I think we should take > a little care to move only the files that we really want in > asm/powerpc. Sure, this was just a first pass - really to demonstrate that we can remove header files from their original directories as we go. > E.g, most of the files that are in asm-ppc but not in asm-ppc64 > seem so be board-specific or cpu-specific, so I'd not move them > around before (unless) moving the platform code for those as well. Indeed. > Also, for everything below include/asm-ppc64/iSeries, it would > make sense to rename the files to lowercase in the same > step and change all their users. That would definitely be a separate set of patches (those include files are referenced in 47 different files). > Another help for merging further is to do > > for i in `ls include/asm-ppc` ; do > if [ -e include/asm-ppc64/$i ] ; then > diff --ifdef __powerpc64__ include/asm-{ppc,ppc64}/$i > \ > include/asm-generic/$i ; ^^^^^^^ (I assume you meant powerpc as we are not the generic architecture, yet :-)) > fi > done > > Note that you need to hand-edit practically every file that you get from > this, but many of them become trivial to merge. I'll have a go and see what happens. > Another interesting point about it is which define to use. For s390, we > decided to '#ifdef __s390x__' rather than '#ifdef CONFIG_ARCH_S390X' or > 'ifdef CONFIG_64BIT', because CONFIG_* does not work when including the > headers from user space. Well noone should even include kernel headers from user space :-) and my understanding is that glibc "sanitizes" its version of the kernel headers anyway. > Using CONFIG_64BIT instead of __powerpc64__ only within #ifdef __KERNEL__ > would be correct but less consistant. The advantage of using CONFIG_64BIT as much as possible is that it shows us places that can be consolidated across the various architectures (which is a bit of a passion of mine :-)). And more consolidation should make life easier for the glibc folks in the long run. -- Cheers, Stephen Rothwell sfr at canb.auug.org.au http://www.canb.auug.org.au/~sfr/ From arnd at arndb.de Sat Aug 6 02:24:16 2005 From: arnd at arndb.de (Arnd Bergmann) Date: Fri, 5 Aug 2005 18:24:16 +0200 Subject: [PATCH] 1/2 Start header file merger (Was: Re: Beginning Merger Patch) In-Reply-To: <20050806005941.5d1fe432.sfr@canb.auug.org.au> References: <1123023575.2614.25.camel@cashmere.sps.mot.com> <200508051353.23750.arnd@arndb.de> <20050806005941.5d1fe432.sfr@canb.auug.org.au> Message-ID: <200508051824.17947.arnd@arndb.de> On Freedag 05 August 2005 16:59, Stephen Rothwell wrote: > Well noone should even include kernel headers from user space :-) and my > understanding is that glibc "sanitizes" its version of the kernel headers > anyway. Glibc doesn't change the header files too much, most of that is done in the linux-libc-headers package, which is maintained separately from the kernel and from glibc. There is some effort being put into keeping the difference between that package and the kernel headers small. Also, while using kernel headers directly from user space should be considered a bug, Linus has stated before that he wants source code that is broken in that way to keep working instead of breaking it even more. There is also klibc, which heavily relies on kernel headers by design. > > Using CONFIG_64BIT instead of __powerpc64__ only within #ifdef __KERNEL__ > > would be correct but less consistant. > > The advantage of using CONFIG_64BIT as much as possible is that it shows > us places that can be consolidated across the various architectures > (which is a bit of a passion of mine :-)). ?And more consolidation should > make life easier for the glibc folks in the long run. AFAIK, in linux-libc-headers every usage of CONFIG_* outside of __KERNEL__ is a bug that needs to be fixed by the maintainer, so we really should not do that. I think it might be ok to use CONFIG_64BIT for files that are completely inside #ifdef __KERNEL__, but I'd like to avoid stuff like: #ifndef __powerpc64__ #define __NR_sendfile64?? 226 /* only for 32 bit */ #endif /* __powerpc64__ */ ... #ifdef __KERNEL__ #ifndef CONFIG_64BIT #define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall") #else /* CONFIG_64BIT */ #define cond_syscall(x) asm(".weak\t." #x "\n\t.set\t." #x ",.sys_ni_syscall") #endif /* CONFIG_64BIT */ #endif /* __KERNEL__ */ in a single file. Using __powerpc64__ consistantly has the advantage that the casual reader can easily find all places that rely on 32/64 bit definitions without having to understand why there are two different ways to do the same thing. Perhaps it works out better if this is combined with the split into include/asm-powerpc/ and include/asm-powerpc/user, as mentioned in the thread around http://www.ussg.iu.edu/hypermail/linux/kernel/0411.3/1663.html. Then we could have CONFIG_64BIT everywhere in the real kernel headers and __powerpc64__ in the user interface headers. Arnd <>< From kumar.gala at freescale.com Sat Aug 6 03:38:50 2005 From: kumar.gala at freescale.com (Kumar Gala) Date: Fri, 5 Aug 2005 12:38:50 -0500 Subject: [PATCH] PPC64: Add VMX save flag to VPA In-Reply-To: <20050805040225.GA13865@austin.ibm.com> References: <20050805040225.GA13865@austin.ibm.com> Message-ID: Olaf, Out of interest, I'm assuming this extension to pacaData is part of some software spec? Or is this specific to Linux. I ask because one of the issues we are going to run into when merging ppc32/ppc64 is the lack of public information about hypervisor interfaces. - kumar On Aug 4, 2005, at 11:02 PM, Olof Johansson wrote: > Hi, > > We need to indicate to the hypervisor that it needs to save our VMX > registers when switching partitions on a shared-processor system, just > as it needs to for FP and PMC registers. > > This could be made to be on-demand when VMX is used, but we don't do > that for FP nor PMC right now either so let's not overcomplicate > things. > > > Signed-off-by: Olof Johansson > > > Index: 2.6/arch/ppc64/kernel/pacaData.c > =================================================================== > --- 2.6.orig/arch/ppc64/kernel/pacaData.c 2005-08-03 > 19:53:16.000000000 -0500 > +++ 2.6/arch/ppc64/kernel/pacaData.c 2005-08-04 19:26:26.000000000 > -0500 > @@ -59,6 +59,7 @@ extern unsigned long __toc_start; > .fpregs_in_use = 1, > \ > .end_of_quantum = 0xfffffffffffffffful, > \ > .slb_count = 64, > \ > + .vmxregs_in_use = 0, > \ > }, > \ > > #ifdef CONFIG_PPC_ISERIES > Index: 2.6/include/asm-ppc64/lppaca.h > =================================================================== > --- 2.6.orig/include/asm-ppc64/lppaca.h 2005-08-04 > 19:25:54.000000000 > -0500 > +++ 2.6/include/asm-ppc64/lppaca.h 2005-08-04 19:26:15.000000000 > -0500 > @@ -108,7 +108,7 @@ struct lppaca > volatile u32 virtual_decr; // Virtual DECR for shared > procsx78-x7B > u16 slb_count; // # of SLBs to maintain > x7C-x7D > u8 idle; // Indicate OS is idle > x7E > - u8 reserved5; // Reserved > x7F > + u8 vmxregs_in_use; // VMX registers in use > x7F > > > > // > ====================================================================== > ======= > Index: 2.6/arch/ppc64/kernel/pSeries_lpar.c > =================================================================== > --- 2.6.orig/arch/ppc64/kernel/pSeries_lpar.c 2005-08-03 > 19:53:16.000000000 -0500 > +++ 2.6/arch/ppc64/kernel/pSeries_lpar.c 2005-08-04 > 19:35:41.000000000 -0500 > @@ -267,6 +267,10 @@ void vpa_init(int cpu) > > /* Register the Virtual Processor Area (VPA) */ > flags = 1UL << (63 - 18); > + > + if (cpu_has_feature(CPU_FTR_ALTIVEC)) > + paca[cpu].lppaca.vmxregs_in_use = 1; > + > ret = register_vpa(flags, hwcpu, __pa(vpa)); > > if (ret) > _______________________________________________ > Linuxppc64-dev mailing list > Linuxppc64-dev at ozlabs.org > https://ozlabs.org/mailman/listinfo/linuxppc64-dev > From olof at lixom.net Sat Aug 6 04:02:33 2005 From: olof at lixom.net (Olof Johansson) Date: Fri, 5 Aug 2005 13:02:33 -0500 Subject: [PATCH] PPC64: Add VMX save flag to VPA In-Reply-To: References: <20050805040225.GA13865@austin.ibm.com> Message-ID: <20050805180233.GB13865@austin.ibm.com> On Fri, Aug 05, 2005 at 12:38:50PM -0500, Kumar Gala wrote: > Out of interest, I'm assuming this extension to pacaData is part of > some software spec? Or is this specific to Linux. > > I ask because one of the issues we are going to run into when merging > ppc32/ppc64 is the lack of public information about hypervisor > interfaces. Yes, this is architected in a document called PAPR (Power Architecture Platform Requirements). It used to be called RPA (Risc Platform Archiecture). At this time there is no publically available version of this document. -Olof From bdc at carlstrom.com Sat Aug 6 09:52:18 2005 From: bdc at carlstrom.com (Brian D. Carlstrom) Date: Fri, 5 Aug 2005 16:52:18 -0700 Subject: Fan control for new PowerMac G5 2.7GHz machines? In-Reply-To: <1123147202.30257.50.camel@gaston> References: <1123099081.30257.41.camel@gaston> <42F14303.2000304@am.sony.com> <1123147202.30257.50.camel@gaston> Message-ID: <17139.64434.831070.403355@zot.electricrain.com> Benjamin Herrenschmidt writes: > > i2c /dev entries driver > > /u3 at 0,f8000000/i2c at f8001000: Missing interrupt or address ! > > > > In therm_pm72_attach() it hits 'Found K2', but u3_0 and u3_1 > > are never set, so start_control_loops() is never called. > > > > I'll look at it more when I have some time. > > Ah yes, this is indeed the problem ! There is a bug in Apple device tree > on these machines that is breaking Linux. I should have a workaround > upstream, but for some reason, it seems it's not working for you. Well, I have good news and bad news. I switched from the patched YDL 2.6.10-1 to linux-stable 2.6.12.3 to debug the fan issue. The good news is that my fans control now works. Since Geoff is having problems, I'll include my DBG output from therm_pm72 below. For me it is reporting "found U3-1, attaching FCU" and not "Found K2". The bad news is that ybin is having trouble: # ybin ofpath: /proc/device-tree is broken. Do not use BootX to boot, use yaboot. ofpath: The yaboot HOWTO can be found here: http://www.alaska.net/~erbenson/doc ybin: Unable to find OpenFirmware path for boot=/dev/sda2 ybin: Please add ofboot= where is the OpenFirmware path to /dev/sda2 to /etc/yaboot.conf I've heard a newer yaboot might fix this but for now I just booted to my old kernel to update yaboot.conf. -bri found U3-0 counted 2 CPUs in the device-tree Liquid cooling pumps detected, using new algorithm ! CPU 0 Using 6 power history entries CPU 1 Using 6 power history entries all control loops up ! found U3-1, attaching FCU FCU attached everything up, starting control loops main_control_loop started Found KeyWest i2c on "u3", 2 channels, stepping: 4 bits ADC config reg: 00 ADC config reg: 00 cpu 0, exhaust RPM: 1000 cpu 0, temp raw: 01f2, m_diode: 9fc5, b_diode: fffff67d temp: 39.653 cpu 0, current: 17.333, voltage: 1.413, power: 24.502 W cpu 1, exhaust RPM: 1000 cpu 1, temp raw: 01e9, m_diode: 9dbb, b_diode: fffff674 temp: 37.134 cpu 1, current: 19.409, voltage: 1.408, power: 27.341 W power target: 85.000, error: 57.658 integral: 0159f366 integ_p: 29 adj_in_target: 53.594, ttarget: 81 deriv_p: 0 prop_p: -140 sum: -140 ** CPU 1 RPM: 860 Ex, 834, Pump: 1250, In, overtemp: 0 backside: current pwm: 26 temp: 49.000, target: 75.000 integral: fefc0000 integ_p: 0 deriv_p: 0 prop_p: -130 sum: -130 ** BACKSIDE PWM: 20 drives: current rpm: 1000 temp: 21.500, target: 40.000 integral: ff470000 integ_p: 0 deriv_p: 0 prop_p: -93 sum: -93 ** DRIVES RPM: 907 From benh at kernel.crashing.org Sun Aug 7 17:41:54 2005 From: benh at kernel.crashing.org (Benjamin Herrenschmidt) Date: Sun, 07 Aug 2005 09:41:54 +0200 Subject: Fan control for new PowerMac G5 2.7GHz machines? In-Reply-To: <17139.64434.831070.403355@zot.electricrain.com> References: <1123099081.30257.41.camel@gaston> <42F14303.2000304@am.sony.com> <1123147202.30257.50.camel@gaston> <17139.64434.831070.403355@zot.electricrain.com> Message-ID: <1123400515.30257.100.camel@gaston> On Fri, 2005-08-05 at 16:52 -0700, Brian D. Carlstrom wrote: > Benjamin Herrenschmidt writes: > > > i2c /dev entries driver > > > /u3 at 0,f8000000/i2c at f8001000: Missing interrupt or address ! > > > > > > In therm_pm72_attach() it hits 'Found K2', but u3_0 and u3_1 > > > are never set, so start_control_loops() is never called. > > > > > > I'll look at it more when I have some time. > > > > Ah yes, this is indeed the problem ! There is a bug in Apple device tree > > on these machines that is breaking Linux. I should have a workaround > > upstream, but for some reason, it seems it's not working for you. > > Well, I have good news and bad news. I switched from the patched YDL > 2.6.10-1 to linux-stable 2.6.12.3 to debug the fan issue. The problem is realted to the device-tree fixup code as I posted. > The good news is that my fans control now works. Since Geoff is having > problems, I'll include my DBG output from therm_pm72 below. For me it > is reporting "found U3-1, attaching FCU" and not "Found K2". > > The bad news is that ybin is having trouble: > > # ybin > ofpath: /proc/device-tree is broken. Do not use BootX to boot, use yaboot. > ofpath: The yaboot HOWTO can be found here: http://www.alaska.net/~erbenson/doc > ybin: Unable to find OpenFirmware path for boot=/dev/sda2 > ybin: Please add ofboot= where is the OpenFirmware path to /dev/sda2 to /etc/yaboot.conf > > I've heard a newer yaboot might fix this but for now I just booted to my > old kernel to update yaboot.conf. Just edit "ofpath" (it's a shell script) and simply remove the test that trigger this error, it's bogus. Ben. From paulus at samba.org Mon Aug 8 13:24:38 2005 From: paulus at samba.org (Paul Mackerras) Date: Mon, 8 Aug 2005 13:24:38 +1000 Subject: [PATCH] make arch/ppc64/boot standalone In-Reply-To: <20050507215801.GC26918@suse.de> References: <20050507215801.GC26918@suse.de> Message-ID: <17142.53366.96808.266798@cargo.ozlabs.ibm.com> Olaf Hering writes: > make the bootheader for ppc64 independent from kernel and libc headers > add -nostdinc -isystem $gccincludes to not include libc headers > declare all functions in header files, also the stuff from string.S > declare some functions static > use stddef.h to get size_t (hopefully ok) > remove ppc32-types.h, only elf.h used the __NN types Here is a new version, munged somewhat by Stephen Rothwell and me. I'll send this upstream after 2.6.13 is out. Paul. diff -ruN linus/arch/ppc64/boot/Makefile linus-boot.2/arch/ppc64/boot/Makefile --- linus/arch/ppc64/boot/Makefile 2005-07-01 09:58:50.000000000 +1000 +++ linus-boot.2/arch/ppc64/boot/Makefile 2005-08-05 11:50:15.000000000 +1000 @@ -22,8 +22,8 @@ HOSTCC := gcc -BOOTCFLAGS := $(HOSTCFLAGS) $(LINUXINCLUDE) -fno-builtin -BOOTAFLAGS := -D__ASSEMBLY__ $(BOOTCFLAGS) -traditional +BOOTCFLAGS := $(HOSTCFLAGS) -fno-builtin -nostdinc -isystem $(shell $(CROSS32CC) -print-file-name=include) +BOOTAFLAGS := -D__ASSEMBLY__ $(BOOTCFLAGS) -traditional -nostdinc BOOTLFLAGS := -Ttext 0x00400000 -e _start -T $(srctree)/$(src)/zImage.lds OBJCOPYFLAGS := contents,alloc,load,readonly,data diff -ruN linus/arch/ppc64/boot/addnote.c linus-boot.2/arch/ppc64/boot/addnote.c --- linus/arch/ppc64/boot/addnote.c 2005-06-27 16:08:00.000000000 +1000 +++ linus-boot.2/arch/ppc64/boot/addnote.c 2005-08-05 11:28:36.000000000 +1000 @@ -157,7 +157,7 @@ PUT_32BE(ns, strlen(arch) + 1); PUT_32BE(ns + 4, N_DESCR * 4); PUT_32BE(ns + 8, 0x1275); - strcpy(&buf[ns + 12], arch); + strcpy((char *) &buf[ns + 12], arch); ns += 12 + strlen(arch) + 1; for (i = 0; i < N_DESCR; ++i, ns += 4) PUT_32BE(ns, descr[i]); @@ -172,7 +172,7 @@ PUT_32BE(ns, strlen(rpaname) + 1); PUT_32BE(ns + 4, sizeof(rpanote)); PUT_32BE(ns + 8, 0x12759999); - strcpy(&buf[ns + 12], rpaname); + strcpy((char *) &buf[ns + 12], rpaname); ns += 12 + ROUNDUP(strlen(rpaname) + 1); for (i = 0; i < N_RPA_DESCR; ++i, ns += 4) PUT_32BE(ns, rpanote[i]); diff -ruN linus/arch/ppc64/boot/crt0.S linus-boot.2/arch/ppc64/boot/crt0.S --- linus/arch/ppc64/boot/crt0.S 2005-06-27 16:08:00.000000000 +1000 +++ linus-boot.2/arch/ppc64/boot/crt0.S 2005-08-05 11:46:30.000000000 +1000 @@ -9,7 +9,7 @@ * NOTE: this code runs in 32 bit mode and is packaged as ELF32. */ -#include +#include "ppc_asm.h" .text .globl _start diff -ruN linus/arch/ppc64/boot/div64.S linus-boot.2/arch/ppc64/boot/div64.S --- linus/arch/ppc64/boot/div64.S 2005-06-27 16:08:00.000000000 +1000 +++ linus-boot.2/arch/ppc64/boot/div64.S 2005-08-05 11:48:25.000000000 +1000 @@ -13,7 +13,7 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */ -#include +#include "ppc_asm.h" .globl __div64_32 __div64_32: diff -ruN linus/arch/ppc64/boot/elf.h linus-boot.2/arch/ppc64/boot/elf.h --- linus/arch/ppc64/boot/elf.h 1970-01-01 10:00:00.000000000 +1000 +++ linus-boot.2/arch/ppc64/boot/elf.h 2005-08-05 11:28:36.000000000 +1000 @@ -0,0 +1,149 @@ +#ifndef _PPC_BOOT_ELF_H_ +#define _PPC_BOOT_ELF_H_ + +/* 32-bit ELF base types. */ +typedef unsigned int Elf32_Addr; +typedef unsigned short Elf32_Half; +typedef unsigned int Elf32_Off; +typedef signed int Elf32_Sword; +typedef unsigned int Elf32_Word; + +/* 64-bit ELF base types. */ +typedef unsigned long long Elf64_Addr; +typedef unsigned short Elf64_Half; +typedef signed short Elf64_SHalf; +typedef unsigned long long Elf64_Off; +typedef signed int Elf64_Sword; +typedef unsigned int Elf64_Word; +typedef unsigned long long Elf64_Xword; +typedef signed long long Elf64_Sxword; + +/* These constants are for the segment types stored in the image headers */ +#define PT_NULL 0 +#define PT_LOAD 1 +#define PT_DYNAMIC 2 +#define PT_INTERP 3 +#define PT_NOTE 4 +#define PT_SHLIB 5 +#define PT_PHDR 6 +#define PT_TLS 7 /* Thread local storage segment */ +#define PT_LOOS 0x60000000 /* OS-specific */ +#define PT_HIOS 0x6fffffff /* OS-specific */ +#define PT_LOPROC 0x70000000 +#define PT_HIPROC 0x7fffffff +#define PT_GNU_EH_FRAME 0x6474e550 + +#define PT_GNU_STACK (PT_LOOS + 0x474e551) + +/* These constants define the different elf file types */ +#define ET_NONE 0 +#define ET_REL 1 +#define ET_EXEC 2 +#define ET_DYN 3 +#define ET_CORE 4 +#define ET_LOPROC 0xff00 +#define ET_HIPROC 0xffff + +/* These constants define the various ELF target machines */ +#define EM_NONE 0 +#define EM_PPC 20 /* PowerPC */ +#define EM_PPC64 21 /* PowerPC64 */ + +#define EI_NIDENT 16 + +typedef struct elf32_hdr { + unsigned char e_ident[EI_NIDENT]; + Elf32_Half e_type; + Elf32_Half e_machine; + Elf32_Word e_version; + Elf32_Addr e_entry; /* Entry point */ + Elf32_Off e_phoff; + Elf32_Off e_shoff; + Elf32_Word e_flags; + Elf32_Half e_ehsize; + Elf32_Half e_phentsize; + Elf32_Half e_phnum; + Elf32_Half e_shentsize; + Elf32_Half e_shnum; + Elf32_Half e_shstrndx; +} Elf32_Ehdr; + +typedef struct elf64_hdr { + unsigned char e_ident[16]; /* ELF "magic number" */ + Elf64_Half e_type; + Elf64_Half e_machine; + Elf64_Word e_version; + Elf64_Addr e_entry; /* Entry point virtual address */ + Elf64_Off e_phoff; /* Program header table file offset */ + Elf64_Off e_shoff; /* Section header table file offset */ + Elf64_Word e_flags; + Elf64_Half e_ehsize; + Elf64_Half e_phentsize; + Elf64_Half e_phnum; + Elf64_Half e_shentsize; + Elf64_Half e_shnum; + Elf64_Half e_shstrndx; +} Elf64_Ehdr; + +/* These constants define the permissions on sections in the program + header, p_flags. */ +#define PF_R 0x4 +#define PF_W 0x2 +#define PF_X 0x1 + +typedef struct elf32_phdr { + Elf32_Word p_type; + Elf32_Off p_offset; + Elf32_Addr p_vaddr; + Elf32_Addr p_paddr; + Elf32_Word p_filesz; + Elf32_Word p_memsz; + Elf32_Word p_flags; + Elf32_Word p_align; +} Elf32_Phdr; + +typedef struct elf64_phdr { + Elf64_Word p_type; + Elf64_Word p_flags; + Elf64_Off p_offset; /* Segment file offset */ + Elf64_Addr p_vaddr; /* Segment virtual address */ + Elf64_Addr p_paddr; /* Segment physical address */ + Elf64_Xword p_filesz; /* Segment size in file */ + Elf64_Xword p_memsz; /* Segment size in memory */ + Elf64_Xword p_align; /* Segment alignment, file & memory */ +} Elf64_Phdr; + +#define EI_MAG0 0 /* e_ident[] indexes */ +#define EI_MAG1 1 +#define EI_MAG2 2 +#define EI_MAG3 3 +#define EI_CLASS 4 +#define EI_DATA 5 +#define EI_VERSION 6 +#define EI_OSABI 7 +#define EI_PAD 8 + +#define ELFMAG0 0x7f /* EI_MAG */ +#define ELFMAG1 'E' +#define ELFMAG2 'L' +#define ELFMAG3 'F' +#define ELFMAG "\177ELF" +#define SELFMAG 4 + +#define ELFCLASSNONE 0 /* EI_CLASS */ +#define ELFCLASS32 1 +#define ELFCLASS64 2 +#define ELFCLASSNUM 3 + +#define ELFDATANONE 0 /* e_ident[EI_DATA] */ +#define ELFDATA2LSB 1 +#define ELFDATA2MSB 2 + +#define EV_NONE 0 /* e_version, EI_VERSION */ +#define EV_CURRENT 1 +#define EV_NUM 2 + +#define ELFOSABI_NONE 0 +#define ELFOSABI_LINUX 3 + +#endif /* _PPC_BOOT_ELF_H_ */ diff -ruN linus/arch/ppc64/boot/main.c linus-boot.2/arch/ppc64/boot/main.c --- linus/arch/ppc64/boot/main.c 2005-07-01 09:58:50.000000000 +1000 +++ linus-boot.2/arch/ppc64/boot/main.c 2005-08-05 11:47:53.000000000 +1000 @@ -8,36 +8,28 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */ -#include "ppc32-types.h" +#include +#include +#include "elf.h" +#include "page.h" +#include "string.h" +#include "stdio.h" +#include "prom.h" #include "zlib.h" -#include -#include -#include -#include - -extern void *finddevice(const char *); -extern int getprop(void *, const char *, void *, int); -extern void printf(const char *fmt, ...); -extern int sprintf(char *buf, const char *fmt, ...); -void gunzip(void *, int, unsigned char *, int *); -void *claim(unsigned int, unsigned int, unsigned int); -void flush_cache(void *, unsigned long); -void pause(void); -extern void exit(void); - -unsigned long strlen(const char *s); -void *memmove(void *dest, const void *src, unsigned long n); -void *memcpy(void *dest, const void *src, unsigned long n); + +static void gunzip(void *, int, unsigned char *, int *); +extern void flush_cache(void *, unsigned long); + /* Value picked to match that used by yaboot */ #define PROG_START 0x01400000 #define RAM_END (256<<20) // Fixme: use OF */ -char *avail_ram; -char *begin_avail, *end_avail; -char *avail_high; -unsigned int heap_use; -unsigned int heap_max; +static char *avail_ram; +static char *begin_avail, *end_avail; +static char *avail_high; +static unsigned int heap_use; +static unsigned int heap_max; extern char _start[]; extern char _vmlinux_start[]; @@ -52,9 +44,9 @@ unsigned long size; unsigned long memsize; }; -struct addr_range vmlinux = {0, 0, 0}; -struct addr_range vmlinuz = {0, 0, 0}; -struct addr_range initrd = {0, 0, 0}; +static struct addr_range vmlinux = {0, 0, 0}; +static struct addr_range vmlinuz = {0, 0, 0}; +static struct addr_range initrd = {0, 0, 0}; static char scratch[128<<10]; /* 128kB of scratch space for gunzip */ @@ -64,13 +56,6 @@ void *); -int (*prom)(void *); - -void *chosen_handle; -void *stdin; -void *stdout; -void *stderr; - #undef DEBUG static unsigned long claim_base = PROG_START; @@ -277,7 +262,7 @@ #define DEFLATED 8 -void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp) +static void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp) { z_stream s; int r, i, flags; diff -ruN linus/arch/ppc64/boot/page.h linus-boot.2/arch/ppc64/boot/page.h --- linus/arch/ppc64/boot/page.h 1970-01-01 10:00:00.000000000 +1000 +++ linus-boot.2/arch/ppc64/boot/page.h 2005-08-05 11:28:36.000000000 +1000 @@ -0,0 +1,34 @@ +#ifndef _PPC_BOOT_PAGE_H +#define _PPC_BOOT_PAGE_H +/* + * Copyright (C) 2001 PPC64 Team, IBM Corp + * + * 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. + */ + +#ifdef __ASSEMBLY__ +#define ASM_CONST(x) x +#else +#define __ASM_CONST(x) x##UL +#define ASM_CONST(x) __ASM_CONST(x) +#endif + +/* PAGE_SHIFT determines the page size */ +#define PAGE_SHIFT 12 +#define PAGE_SIZE (ASM_CONST(1) << PAGE_SHIFT) +#define PAGE_MASK (~(PAGE_SIZE-1)) + +/* align addr on a size boundary - adjust address up/down if needed */ +#define _ALIGN_UP(addr,size) (((addr)+((size)-1))&(~((size)-1))) +#define _ALIGN_DOWN(addr,size) ((addr)&(~((size)-1))) + +/* align addr on a size boundary - adjust address up if needed */ +#define _ALIGN(addr,size) _ALIGN_UP(addr,size) + +/* to align the pointer to the (next) page boundary */ +#define PAGE_ALIGN(addr) _ALIGN(addr, PAGE_SIZE) + +#endif /* _PPC_BOOT_PAGE_H */ diff -ruN linus/arch/ppc64/boot/ppc32-types.h linus-boot.2/arch/ppc64/boot/ppc32-types.h --- linus/arch/ppc64/boot/ppc32-types.h 2005-06-27 16:08:00.000000000 +1000 +++ linus-boot.2/arch/ppc64/boot/ppc32-types.h 1970-01-01 10:00:00.000000000 +1000 @@ -1,36 +0,0 @@ -#ifndef _PPC64_TYPES_H -#define _PPC64_TYPES_H - -typedef __signed__ char __s8; -typedef unsigned char __u8; - -typedef __signed__ short __s16; -typedef unsigned short __u16; - -typedef __signed__ int __s32; -typedef unsigned int __u32; - -typedef __signed__ long long __s64; -typedef unsigned long long __u64; - -typedef signed char s8; -typedef unsigned char u8; - -typedef signed short s16; -typedef unsigned short u16; - -typedef signed int s32; -typedef unsigned int u32; - -typedef signed long long s64; -typedef unsigned long long u64; - -typedef struct { - __u32 u[4]; -} __attribute((aligned(16))) __vector128; - -#define BITS_PER_LONG 32 - -typedef __vector128 vector128; - -#endif /* _PPC64_TYPES_H */ diff -ruN linus/arch/ppc64/boot/ppc_asm.h linus-boot.2/arch/ppc64/boot/ppc_asm.h --- linus/arch/ppc64/boot/ppc_asm.h 1970-01-01 10:00:00.000000000 +1000 +++ linus-boot.2/arch/ppc64/boot/ppc_asm.h 2005-08-05 11:28:36.000000000 +1000 @@ -0,0 +1,62 @@ +#ifndef _PPC64_PPC_ASM_H +#define _PPC64_PPC_ASM_H +/* + * + * Definitions used by various bits of low-level assembly code on PowerPC. + * + * Copyright (C) 1995-1999 Gary Thomas, Paul Mackerras, 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. + */ + +/* Condition Register Bit Fields */ + +#define cr0 0 +#define cr1 1 +#define cr2 2 +#define cr3 3 +#define cr4 4 +#define cr5 5 +#define cr6 6 +#define cr7 7 + + +/* General Purpose Registers (GPRs) */ + +#define r0 0 +#define r1 1 +#define r2 2 +#define r3 3 +#define r4 4 +#define r5 5 +#define r6 6 +#define r7 7 +#define r8 8 +#define r9 9 +#define r10 10 +#define r11 11 +#define r12 12 +#define r13 13 +#define r14 14 +#define r15 15 +#define r16 16 +#define r17 17 +#define r18 18 +#define r19 19 +#define r20 20 +#define r21 21 +#define r22 22 +#define r23 23 +#define r24 24 +#define r25 25 +#define r26 26 +#define r27 27 +#define r28 28 +#define r29 29 +#define r30 30 +#define r31 31 + +#endif /* _PPC64_PPC_ASM_H */ diff -ruN linus/arch/ppc64/boot/prom.c linus-boot.2/arch/ppc64/boot/prom.c --- linus/arch/ppc64/boot/prom.c 2005-07-01 09:58:50.000000000 +1000 +++ linus-boot.2/arch/ppc64/boot/prom.c 2005-08-05 11:47:19.000000000 +1000 @@ -7,43 +7,19 @@ * 2 of the License, or (at your option) any later version. */ #include -#include -#include -#include - -extern __u32 __div64_32(unsigned long long *dividend, __u32 divisor); - -/* The unnecessary pointer compare is there - * to check for type safety (n must be 64bit) - */ -# define do_div(n,base) ({ \ - __u32 __base = (base); \ - __u32 __rem; \ - (void)(((typeof((n)) *)0) == ((unsigned long long *)0)); \ - if (((n) >> 32) == 0) { \ - __rem = (__u32)(n) % __base; \ - (n) = (__u32)(n) / __base; \ - } else \ - __rem = __div64_32(&(n), __base); \ - __rem; \ - }) +#include +#include "string.h" +#include "stdio.h" +#include "prom.h" int (*prom)(void *); void *chosen_handle; + void *stdin; void *stdout; void *stderr; -void exit(void); -void *finddevice(const char *name); -int getprop(void *phandle, const char *name, void *buf, int buflen); -void chrpboot(int a1, int a2, void *prom); /* in main.c */ - -int printf(char *fmt, ...); - -/* there is no convenient header to get this from... -- paulus */ -extern unsigned long strlen(const char *); int write(void *handle, void *ptr, int nb) @@ -210,107 +186,6 @@ return write(f, str, n) == n? 0: -1; } -int -readchar(void) -{ - char ch; - - for (;;) { - switch (read(stdin, &ch, 1)) { - case 1: - return ch; - case -1: - printf("read(stdin) returned -1\r\n"); - return -1; - } - } -} - -static char line[256]; -static char *lineptr; -static int lineleft; - -int -getchar(void) -{ - int c; - - if (lineleft == 0) { - lineptr = line; - for (;;) { - c = readchar(); - if (c == -1 || c == 4) - break; - if (c == '\r' || c == '\n') { - *lineptr++ = '\n'; - putchar('\n'); - break; - } - switch (c) { - case 0177: - case '\b': - if (lineptr > line) { - putchar('\b'); - putchar(' '); - putchar('\b'); - --lineptr; - } - break; - case 'U' & 0x1F: - while (lineptr > line) { - putchar('\b'); - putchar(' '); - putchar('\b'); - --lineptr; - } - break; - default: - if (lineptr >= &line[sizeof(line) - 1]) - putchar('\a'); - else { - putchar(c); - *lineptr++ = c; - } - } - } - lineleft = lineptr - line; - lineptr = line; - } - if (lineleft == 0) - return -1; - --lineleft; - return *lineptr++; -} - - - -/* String functions lifted from lib/vsprintf.c and lib/ctype.c */ -unsigned char _ctype[] = { -_C,_C,_C,_C,_C,_C,_C,_C, /* 0-7 */ -_C,_C|_S,_C|_S,_C|_S,_C|_S,_C|_S,_C,_C, /* 8-15 */ -_C,_C,_C,_C,_C,_C,_C,_C, /* 16-23 */ -_C,_C,_C,_C,_C,_C,_C,_C, /* 24-31 */ -_S|_SP,_P,_P,_P,_P,_P,_P,_P, /* 32-39 */ -_P,_P,_P,_P,_P,_P,_P,_P, /* 40-47 */ -_D,_D,_D,_D,_D,_D,_D,_D, /* 48-55 */ -_D,_D,_P,_P,_P,_P,_P,_P, /* 56-63 */ -_P,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U, /* 64-71 */ -_U,_U,_U,_U,_U,_U,_U,_U, /* 72-79 */ -_U,_U,_U,_U,_U,_U,_U,_U, /* 80-87 */ -_U,_U,_U,_P,_P,_P,_P,_P, /* 88-95 */ -_P,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L, /* 96-103 */ -_L,_L,_L,_L,_L,_L,_L,_L, /* 104-111 */ -_L,_L,_L,_L,_L,_L,_L,_L, /* 112-119 */ -_L,_L,_L,_P,_P,_P,_P,_C, /* 120-127 */ -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 128-143 */ -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 144-159 */ -_S|_SP,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P, /* 160-175 */ -_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P, /* 176-191 */ -_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U, /* 192-207 */ -_U,_U,_U,_U,_U,_U,_U,_P,_U,_U,_U,_U,_U,_U,_U,_L, /* 208-223 */ -_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L, /* 224-239 */ -_L,_L,_L,_L,_L,_L,_L,_P,_L,_L,_L,_L,_L,_L,_L,_L}; /* 240-255 */ - size_t strnlen(const char * s, size_t count) { const char *sc; @@ -320,44 +195,30 @@ return sc - s; } -unsigned long simple_strtoul(const char *cp,char **endp,unsigned int base) -{ - unsigned long result = 0,value; +extern unsigned int __div64_32(unsigned long long *dividend, + unsigned int divisor); - if (!base) { - base = 10; - if (*cp == '0') { - base = 8; - cp++; - if ((*cp == 'x') && isxdigit(cp[1])) { - cp++; - base = 16; - } - } - } - while (isxdigit(*cp) && - (value = isdigit(*cp) ? *cp-'0' : toupper(*cp)-'A'+10) < base) { - result = result*base + value; - cp++; - } - if (endp) - *endp = (char *)cp; - return result; -} - -long simple_strtol(const char *cp,char **endp,unsigned int base) -{ - if(*cp=='-') - return -simple_strtoul(cp+1,endp,base); - return simple_strtoul(cp,endp,base); -} +/* The unnecessary pointer compare is there + * to check for type safety (n must be 64bit) + */ +# define do_div(n,base) ({ \ + unsigned int __base = (base); \ + unsigned int __rem; \ + (void)(((typeof((n)) *)0) == ((unsigned long long *)0)); \ + if (((n) >> 32) == 0) { \ + __rem = (unsigned int)(n) % __base; \ + (n) = (unsigned int)(n) / __base; \ + } else \ + __rem = __div64_32(&(n), __base); \ + __rem; \ + }) static int skip_atoi(const char **s) { - int i=0; + int i, c; - while (isdigit(**s)) - i = i*10 + *((*s)++) - '0'; + for (i = 0; '0' <= (c = **s) && c <= '9'; ++*s) + i = i*10 + c - '0'; return i; } @@ -436,9 +297,6 @@ return str; } -/* Forward decl. needed for IP address printing stuff... */ -int sprintf(char * buf, const char *fmt, ...); - int vsprintf(char *buf, const char *fmt, va_list args) { int len; @@ -477,7 +335,7 @@ /* get field width */ field_width = -1; - if (isdigit(*fmt)) + if ('0' <= *fmt && *fmt <= '9') field_width = skip_atoi(&fmt); else if (*fmt == '*') { ++fmt; @@ -493,7 +351,7 @@ precision = -1; if (*fmt == '.') { ++fmt; - if (isdigit(*fmt)) + if ('0' <= *fmt && *fmt <= '9') precision = skip_atoi(&fmt); else if (*fmt == '*') { ++fmt; @@ -628,7 +486,7 @@ static char sprint_buf[1024]; int -printf(char *fmt, ...) +printf(const char *fmt, ...) { va_list args; int n; diff -ruN linus/arch/ppc64/boot/prom.h linus-boot.2/arch/ppc64/boot/prom.h --- linus/arch/ppc64/boot/prom.h 1970-01-01 10:00:00.000000000 +1000 +++ linus-boot.2/arch/ppc64/boot/prom.h 2005-08-05 11:28:36.000000000 +1000 @@ -0,0 +1,18 @@ +#ifndef _PPC_BOOT_PROM_H_ +#define _PPC_BOOT_PROM_H_ + +extern int (*prom) (void *); +extern void *chosen_handle; + +extern void *stdin; +extern void *stdout; +extern void *stderr; + +extern int write(void *handle, void *ptr, int nb); +extern int read(void *handle, void *ptr, int nb); +extern void exit(void); +extern void pause(void); +extern void *finddevice(const char *); +extern void *claim(unsigned long virt, unsigned long size, unsigned long align); +extern int getprop(void *phandle, const char *name, void *buf, int buflen); +#endif /* _PPC_BOOT_PROM_H_ */ diff -ruN linus/arch/ppc64/boot/stdio.h linus-boot.2/arch/ppc64/boot/stdio.h --- linus/arch/ppc64/boot/stdio.h 1970-01-01 10:00:00.000000000 +1000 +++ linus-boot.2/arch/ppc64/boot/stdio.h 2005-08-05 11:28:36.000000000 +1000 @@ -0,0 +1,16 @@ +#ifndef _PPC_BOOT_STDIO_H_ +#define _PPC_BOOT_STDIO_H_ + +extern int printf(const char *fmt, ...); + +extern int sprintf(char *buf, const char *fmt, ...); + +extern int vsprintf(char *buf, const char *fmt, va_list args); + +extern int putc(int c, void *f); +extern int putchar(int c); +extern int getchar(void); + +extern int fputs(char *str, void *f); + +#endif /* _PPC_BOOT_STDIO_H_ */ diff -ruN linus/arch/ppc64/boot/string.S linus-boot.2/arch/ppc64/boot/string.S --- linus/arch/ppc64/boot/string.S 2005-06-27 16:08:00.000000000 +1000 +++ linus-boot.2/arch/ppc64/boot/string.S 2005-08-05 11:46:40.000000000 +1000 @@ -9,7 +9,7 @@ * NOTE: this code runs in 32 bit mode and is packaged as ELF32. */ -#include +#include "ppc_asm.h" .text .globl strcpy diff -ruN linus/arch/ppc64/boot/string.h linus-boot.2/arch/ppc64/boot/string.h --- linus/arch/ppc64/boot/string.h 1970-01-01 10:00:00.000000000 +1000 +++ linus-boot.2/arch/ppc64/boot/string.h 2005-08-05 11:28:36.000000000 +1000 @@ -0,0 +1,16 @@ +#ifndef _PPC_BOOT_STRING_H_ +#define _PPC_BOOT_STRING_H_ + +extern char *strcpy(char *dest, const char *src); +extern char *strncpy(char *dest, const char *src, size_t n); +extern char *strcat(char *dest, const char *src); +extern int strcmp(const char *s1, const char *s2); +extern size_t strlen(const char *s); +extern size_t strnlen(const char *s, size_t count); + +extern void *memset(void *s, int c, size_t n); +extern void *memmove(void *dest, const void *src, unsigned long n); +extern void *memcpy(void *dest, const void *src, unsigned long n); +extern int memcmp(const void *s1, const void *s2, size_t n); + +#endif /* _PPC_BOOT_STRING_H_ */ diff -ruN linus/arch/ppc64/boot/zlib.c linus-boot.2/arch/ppc64/boot/zlib.c --- linus/arch/ppc64/boot/zlib.c 2005-06-27 16:08:00.000000000 +1000 +++ linus-boot.2/arch/ppc64/boot/zlib.c 2005-08-05 11:48:13.000000000 +1000 @@ -107,7 +107,7 @@ /* Diagnostic functions */ #ifdef DEBUG_ZLIB -# include +# include "stdio.h" # ifndef verbose # define verbose 0 # endif From michael at ellerman.id.au Mon Aug 8 13:55:33 2005 From: michael at ellerman.id.au (Michael Ellerman) Date: Mon, 8 Aug 2005 13:55:33 +1000 (EST) Subject: [PATCH 0/2] Make kexec work with ibmvscsi/ibmveth Message-ID: <1123473326.905217.26508543874.qpatch@concordia> On our Power5 we have vscsi and veth installed. When trying to kexec a new kernel the vscsi and veth initialisation fails because the previous kernel didn't clean up properly and as far as the Hypervisor is concerned is still connected. The fix is to harden the driver initialisation routines to cope with this condition and free the resource and retry. With these patches I can kexec happily on our Power5 LPAR. cheers From michael at ellerman.id.au Mon Aug 8 13:55:37 2005 From: michael at ellerman.id.au (Michael Ellerman) Date: Mon, 8 Aug 2005 13:55:37 +1000 (EST) Subject: [PATCH 1/2] ppc64: ibmvscsi: Harden driver initilisation for kexec In-Reply-To: <1123473326.905217.26508543874.qpatch@concordia> Message-ID: <20050808035537.D65FF67F3F@ozlabs.org> After a kexec the vscsi driver will fail when trying to register with the Hypervisor because the previous kernel has not unregistered. So if the registration fails, we unregister and then try again. Signed-off-by: Michael Ellerman drivers/scsi/ibmvscsi/rpa_vscsi.c | 27 ++++++++++++++++++++++++--- 1 files changed, 24 insertions(+), 3 deletions(-) Index: kexec/drivers/scsi/ibmvscsi/rpa_vscsi.c =================================================================== --- kexec.orig/drivers/scsi/ibmvscsi/rpa_vscsi.c +++ kexec/drivers/scsi/ibmvscsi/rpa_vscsi.c @@ -194,6 +194,28 @@ static void set_adapter_info(struct ibmv hostdata->madapter_info.os_type = 2; } +static int ibmvscsi_reg_crq_queue(uint32_t unit_addr, dma_addr_t token) +{ + int rc, try_again = 1; + + /* After a kexec the crq will still be open, so our attempt to + * open it will fail. So if we get a failure we free the crq and + * try again, but only once. */ +retry: + rc = plpar_hcall_norets(H_REG_CRQ, unit_addr, token, PAGE_SIZE); + + if (rc != H_Success && rc != 2 && try_again) { + do { + rc = plpar_hcall_norets(H_FREE_CRQ, unit_addr); + } while ((rc == H_Busy) || (H_isLongBusy(rc))); + + try_again = 0; + goto retry; + } + + return rc; +} + /** * initialize_crq_queue: - Initializes and registers CRQ with hypervisor * @queue: crq_queue to initialize and register @@ -226,9 +248,8 @@ int ibmvscsi_init_crq_queue(struct crq_q gather_partition_info(); set_adapter_info(hostdata); - rc = plpar_hcall_norets(H_REG_CRQ, - vdev->unit_address, - queue->msg_token, PAGE_SIZE); + rc = ibmvscsi_reg_crq_queue(vdev->unit_address, queue->msg_token); + if (rc == 2) { /* Adapter is good, but other end is not ready */ printk(KERN_WARNING "ibmvscsi: Partner adapter not ready\n"); From michael at ellerman.id.au Mon Aug 8 13:55:44 2005 From: michael at ellerman.id.au (Michael Ellerman) Date: Mon, 8 Aug 2005 13:55:44 +1000 (EST) Subject: [PATCH 2/2] ppc64: ibmveth: Harden driver initilisation for kexec In-Reply-To: <1123473326.905217.26508543874.qpatch@concordia> Message-ID: <20050808035544.9649567F46@ozlabs.org> After a kexec the veth driver will fail when trying to register with the Hypervisor because the previous kernel has not unregistered. So if the registration fails, we unregister and then try again. Signed-off-by: Michael Ellerman drivers/net/ibmveth.c | 32 ++++++++++++++++++++++++++------ 1 files changed, 26 insertions(+), 6 deletions(-) Index: kexec/drivers/net/ibmveth.c =================================================================== --- kexec.orig/drivers/net/ibmveth.c +++ kexec/drivers/net/ibmveth.c @@ -448,6 +448,31 @@ static void ibmveth_cleanup(struct ibmve ibmveth_free_buffer_pool(adapter, &adapter->rx_buff_pool[2]); } +static int ibmveth_register_logical_lan(struct ibmveth_adapter *adapter, + union ibmveth_buf_desc rxq_desc, u64 mac_address) +{ + int rc, try_again = 1; + + /* After a kexec the adapter will still be open, so our attempt to + * open it will fail. So if we get a failure we free the adapter and + * try again, but only once. */ +retry: + rc = h_register_logical_lan(adapter->vdev->unit_address, + adapter->buffer_list_dma, rxq_desc.desc, + adapter->filter_list_dma, mac_address); + + if (rc != H_Success && try_again) { + do { + rc = h_free_logical_lan(adapter->vdev->unit_address); + } while (H_isLongBusy(rc) || (rc == H_Busy)); + + try_again = 0; + goto retry; + } + + return rc; +} + static int ibmveth_open(struct net_device *netdev) { struct ibmveth_adapter *adapter = netdev->priv; @@ -523,12 +548,7 @@ static int ibmveth_open(struct net_devic ibmveth_debug_printk("filter list @ 0x%p\n", adapter->filter_list_addr); ibmveth_debug_printk("receive q @ 0x%p\n", adapter->rx_queue.queue_addr); - - lpar_rc = h_register_logical_lan(adapter->vdev->unit_address, - adapter->buffer_list_dma, - rxq_desc.desc, - adapter->filter_list_dma, - mac_address); + lpar_rc = ibmveth_register_logical_lan(adapter, rxq_desc, mac_address); if(lpar_rc != H_Success) { ibmveth_error_printk("h_register_logical_lan failed with %ld\n", lpar_rc); From paulus at samba.org Mon Aug 8 15:32:32 2005 From: paulus at samba.org (Paul Mackerras) Date: Mon, 8 Aug 2005 15:32:32 +1000 Subject: [PATCH] Externally visible buffer for CONFIG_CMDLINE In-Reply-To: <20050704193652.23980d26@brick.watson.ibm.com> References: <20050704193652.23980d26@brick.watson.ibm.com> Message-ID: <17142.61040.804303.329948@cargo.ozlabs.ibm.com> Michal Ostrowski writes: > Define a fixed buffer to store the CONFIG_CMDLINE string and the buffer > in it's own section. This allows for one to easily locate this buffer > in the vmlinux file (using objdump) and then use dd to change the > command line. (Allows one to avoid re-building everything to change the > command line when using hardware where the only command line is the > built-in one.) > +#ifdef CONFIG_CMDLINE > +const char builtin_cmdline[COMMAND_LINE_SIZE] > + __attribute__((section("__builtin_cmdline"))) = CONFIG_CMDLINE; > +#endif Where does the __builtin_cmdline section get linked, given that it isn't mentioned explicitly in the vmlinux.lds? > #ifdef CONFIG_CMDLINE > - if (l == 0 || (l == 1 && (*p) == 0)) > - strlcpy(cmd_line, CONFIG_CMDLINE, COMMAND_LINE_SIZE); > -#endif /* CONFIG_CMDLINE */ > + if (l == 0 || (l == 1 && (*p) == 0)) { > + strlcpy(cmd_line, builtin_cmdline, sizeof(builtin_cmdline)); > + } > +#endif We seem to have gained an extra unnecessary pair of braces and lost the comment on the #endif. Paul. From paulus at samba.org Mon Aug 8 15:39:11 2005 From: paulus at samba.org (Paul Mackerras) Date: Mon, 8 Aug 2005 15:39:11 +1000 Subject: [RFC/PATCH] ppc64: Move ppc64_enable_pmcs() logic into a ppc_md function In-Reply-To: <200507121707.31061.michael@ellerman.id.au> References: <200507121707.31061.michael@ellerman.id.au> Message-ID: <17142.61439.561755.747453@cargo.ozlabs.ibm.com> Michael Ellerman writes: > This patch adds an enable_pmc entry to the ppc_md structure, and moves code > from arch/ppc64/kerne/sysfs.c into the various platform files. There should be > no functional changes. Not a bad idea, but why don't you make separate functions for bare-metal and hypervisor versions of pSeries_enable_pmcs, and set ppc_md.enable_pmcs to one or the other as appropriate? Paul. From michael at ellerman.id.au Mon Aug 8 18:45:39 2005 From: michael at ellerman.id.au (Michael Ellerman) Date: Mon, 8 Aug 2005 18:45:39 +1000 (EST) Subject: [PATCH] ppc64: Move ppc64_enable_pmcs() logic into a ppc_md function In-Reply-To: <17142.61439.561755.747453@cargo.ozlabs.ibm.com> Message-ID: <20050808084539.26A1B67F4A@ozlabs.org> Ok, here's an updated version. I've tested it on P5 LPAR and P4. It does what it used to. It still doesn't seem to actually work on P5, with or without this patch, ie. the counters never increment. I take it that's normal. Signed-off-by: Michael Ellerman arch/ppc64/kernel/iSeries_setup.c | 2 + arch/ppc64/kernel/pSeries_setup.c | 20 ++++++++++++ arch/ppc64/kernel/pmac_setup.c | 1 arch/ppc64/kernel/sysfs.c | 54 ++-------------------------------- arch/ppc64/oprofile/op_model_power4.c | 21 +++++++++++++ include/asm-ppc64/machdep.h | 5 +++ 6 files changed, 53 insertions(+), 50 deletions(-) Index: work/arch/ppc64/kernel/iSeries_setup.c =================================================================== --- work.orig/arch/ppc64/kernel/iSeries_setup.c +++ work/arch/ppc64/kernel/iSeries_setup.c @@ -947,6 +947,8 @@ void __init iSeries_early_setup(void) ppc_md.calibrate_decr = iSeries_calibrate_decr; ppc_md.progress = iSeries_progress; + /* XXX Implement enable_pmcs for iSeries */ + if (get_paca()->lppaca.shared_proc) { ppc_md.idle_loop = iseries_shared_idle; printk(KERN_INFO "Using shared processor idle loop\n"); Index: work/arch/ppc64/kernel/pSeries_setup.c =================================================================== --- work.orig/arch/ppc64/kernel/pSeries_setup.c +++ work/arch/ppc64/kernel/pSeries_setup.c @@ -187,6 +187,21 @@ static void __init pSeries_setup_mpic(vo " MPIC "); } +static void pseries_lpar_enable_pmcs(void) +{ + unsigned long set, reset; + + power4_enable_pmcs(); + + set = 1UL << 63; + reset = 0; + plpar_hcall_norets(H_PERFMON, set, reset); + + /* instruct hypervisor to maintain PMCs */ + if (firmware_has_feature(FW_FEATURE_SPLPAR)) + get_paca()->lppaca.pmcregs_in_use = 1; +} + static void __init pSeries_setup_arch(void) { /* Fixup ppc_md depending on the type of interrupt controller */ @@ -245,6 +260,11 @@ static void __init pSeries_setup_arch(vo printk(KERN_INFO "Using default idle loop\n"); ppc_md.idle_loop = default_idle; } + + if (systemcfg->platform & PLATFORM_LPAR) + ppc_md.enable_pmcs = pseries_lpar_enable_pmcs; + else + ppc_md.enable_pmcs = power4_enable_pmcs; } static int __init pSeries_init_panel(void) Index: work/arch/ppc64/kernel/pmac_setup.c =================================================================== --- work.orig/arch/ppc64/kernel/pmac_setup.c +++ work/arch/ppc64/kernel/pmac_setup.c @@ -511,4 +511,5 @@ struct machdep_calls __initdata pmac_md .progress = pmac_progress, .check_legacy_ioport = pmac_check_legacy_ioport, .idle_loop = native_idle, + .enable_pmcs = power4_enable_cpus, }; Index: work/arch/ppc64/kernel/sysfs.c =================================================================== --- work.orig/arch/ppc64/kernel/sysfs.c +++ work/arch/ppc64/kernel/sysfs.c @@ -101,6 +101,8 @@ static int __init setup_smt_snooze_delay } __setup("smt-snooze-delay=", setup_smt_snooze_delay); +#endif /* CONFIG_PPC_MULTIPLATFORM */ + /* * Enabling PMCs will slow partition context switch times so we only do * it the first time we write to the PMCs. @@ -110,63 +112,15 @@ static DEFINE_PER_CPU(char, pmcs_enabled void ppc64_enable_pmcs(void) { - unsigned long hid0; -#ifdef CONFIG_PPC_PSERIES - unsigned long set, reset; -#endif /* CONFIG_PPC_PSERIES */ - /* Only need to enable them once */ if (__get_cpu_var(pmcs_enabled)) return; __get_cpu_var(pmcs_enabled) = 1; - switch (systemcfg->platform) { - case PLATFORM_PSERIES: - case PLATFORM_POWERMAC: - hid0 = mfspr(HID0); - hid0 |= 1UL << (63 - 20); - - /* POWER4 requires the following sequence */ - asm volatile( - "sync\n" - "mtspr %1, %0\n" - "mfspr %0, %1\n" - "mfspr %0, %1\n" - "mfspr %0, %1\n" - "mfspr %0, %1\n" - "mfspr %0, %1\n" - "mfspr %0, %1\n" - "isync" : "=&r" (hid0) : "i" (HID0), "0" (hid0): - "memory"); - break; - -#ifdef CONFIG_PPC_PSERIES - case PLATFORM_PSERIES_LPAR: - set = 1UL << 63; - reset = 0; - plpar_hcall_norets(H_PERFMON, set, reset); - break; -#endif /* CONFIG_PPC_PSERIES */ - - default: - break; - } - - /* instruct hypervisor to maintain PMCs */ - if (firmware_has_feature(FW_FEATURE_SPLPAR)) - get_paca()->lppaca.pmcregs_in_use = 1; + if (ppc_md.enable_pmcs) + ppc_md.enable_pmcs(); } - -#else - -/* PMC stuff */ -void ppc64_enable_pmcs(void) -{ - /* XXX Implement for iseries */ -} -#endif /* CONFIG_PPC_MULTIPLATFORM */ - EXPORT_SYMBOL(ppc64_enable_pmcs); /* XXX convert to rusty's on_one_cpu */ Index: work/arch/ppc64/oprofile/op_model_power4.c =================================================================== --- work.orig/arch/ppc64/oprofile/op_model_power4.c +++ work/arch/ppc64/oprofile/op_model_power4.c @@ -83,6 +83,27 @@ static void power4_reg_setup(struct op_c mmcr0_val |= MMCR0_PROBLEM_DISABLE; } +void power4_enable_pmcs(void) +{ + unsigned long hid0; + + hid0 = mfspr(HID0); + hid0 |= 1UL << (63 - 20); + + /* POWER4 requires the following sequence */ + asm volatile( + "sync\n" + "mtspr %1, %0\n" + "mfspr %0, %1\n" + "mfspr %0, %1\n" + "mfspr %0, %1\n" + "mfspr %0, %1\n" + "mfspr %0, %1\n" + "mfspr %0, %1\n" + "isync" : "=&r" (hid0) : "i" (HID0), "0" (hid0): + "memory"); +} + extern void ppc64_enable_pmcs(void); static void power4_cpu_setup(void *unused) Index: work/include/asm-ppc64/machdep.h =================================================================== --- work.orig/include/asm-ppc64/machdep.h +++ work/include/asm-ppc64/machdep.h @@ -140,11 +140,16 @@ struct machdep_calls { /* Idle loop for this platform, leave empty for default idle loop */ int (*idle_loop)(void); + + /* Function to enable pmcs for this platform, called once per cpu. */ + void (*enable_pmcs)(void); }; extern int default_idle(void); extern int native_idle(void); +extern void power4_enable_pmcs(void); + extern struct machdep_calls ppc_md; extern char cmd_line[COMMAND_LINE_SIZE]; From michael at ellerman.id.au Mon Aug 8 18:47:08 2005 From: michael at ellerman.id.au (Michael Ellerman) Date: Mon, 8 Aug 2005 18:47:08 +1000 Subject: [PATCH] ppc64: Move ppc64_enable_pmcs() logic into a ppc_md function In-Reply-To: <20050808084539.26A1B67F4A@ozlabs.org> References: <20050808084539.26A1B67F4A@ozlabs.org> Message-ID: <200508081847.11327.michael@ellerman.id.au> Sorry, I should add this depends on Stephen's firmware feature patches. On Mon, 8 Aug 2005 18:45, Michael Ellerman wrote: > Ok, here's an updated version. > > I've tested it on P5 LPAR and P4. It does what it used to. > > It still doesn't seem to actually work on P5, with or without this patch, > ie. the counters never increment. I take it that's normal. > > Signed-off-by: Michael Ellerman > > arch/ppc64/kernel/iSeries_setup.c | 2 + > arch/ppc64/kernel/pSeries_setup.c | 20 ++++++++++++ > arch/ppc64/kernel/pmac_setup.c | 1 > arch/ppc64/kernel/sysfs.c | 54 > ++-------------------------------- arch/ppc64/oprofile/op_model_power4.c | > 21 +++++++++++++ > include/asm-ppc64/machdep.h | 5 +++ > 6 files changed, 53 insertions(+), 50 deletions(-) > > Index: work/arch/ppc64/kernel/iSeries_setup.c > =================================================================== > --- work.orig/arch/ppc64/kernel/iSeries_setup.c > +++ work/arch/ppc64/kernel/iSeries_setup.c > @@ -947,6 +947,8 @@ void __init iSeries_early_setup(void) > ppc_md.calibrate_decr = iSeries_calibrate_decr; > ppc_md.progress = iSeries_progress; > > + /* XXX Implement enable_pmcs for iSeries */ > + > if (get_paca()->lppaca.shared_proc) { > ppc_md.idle_loop = iseries_shared_idle; > printk(KERN_INFO "Using shared processor idle loop\n"); > Index: work/arch/ppc64/kernel/pSeries_setup.c > =================================================================== > --- work.orig/arch/ppc64/kernel/pSeries_setup.c > +++ work/arch/ppc64/kernel/pSeries_setup.c > @@ -187,6 +187,21 @@ static void __init pSeries_setup_mpic(vo > " MPIC "); > } > > +static void pseries_lpar_enable_pmcs(void) > +{ > + unsigned long set, reset; > + > + power4_enable_pmcs(); > + > + set = 1UL << 63; > + reset = 0; > + plpar_hcall_norets(H_PERFMON, set, reset); > + > + /* instruct hypervisor to maintain PMCs */ > + if (firmware_has_feature(FW_FEATURE_SPLPAR)) > + get_paca()->lppaca.pmcregs_in_use = 1; > +} > + > static void __init pSeries_setup_arch(void) > { > /* Fixup ppc_md depending on the type of interrupt controller */ > @@ -245,6 +260,11 @@ static void __init pSeries_setup_arch(vo > printk(KERN_INFO "Using default idle loop\n"); > ppc_md.idle_loop = default_idle; > } > + > + if (systemcfg->platform & PLATFORM_LPAR) > + ppc_md.enable_pmcs = pseries_lpar_enable_pmcs; > + else > + ppc_md.enable_pmcs = power4_enable_pmcs; > } > > static int __init pSeries_init_panel(void) > Index: work/arch/ppc64/kernel/pmac_setup.c > =================================================================== > --- work.orig/arch/ppc64/kernel/pmac_setup.c > +++ work/arch/ppc64/kernel/pmac_setup.c > @@ -511,4 +511,5 @@ struct machdep_calls __initdata pmac_md > .progress = pmac_progress, > .check_legacy_ioport = pmac_check_legacy_ioport, > .idle_loop = native_idle, > + .enable_pmcs = power4_enable_cpus, > }; > Index: work/arch/ppc64/kernel/sysfs.c > =================================================================== > --- work.orig/arch/ppc64/kernel/sysfs.c > +++ work/arch/ppc64/kernel/sysfs.c > @@ -101,6 +101,8 @@ static int __init setup_smt_snooze_delay > } > __setup("smt-snooze-delay=", setup_smt_snooze_delay); > > +#endif /* CONFIG_PPC_MULTIPLATFORM */ > + > /* > * Enabling PMCs will slow partition context switch times so we only do > * it the first time we write to the PMCs. > @@ -110,63 +112,15 @@ static DEFINE_PER_CPU(char, pmcs_enabled > > void ppc64_enable_pmcs(void) > { > - unsigned long hid0; > -#ifdef CONFIG_PPC_PSERIES > - unsigned long set, reset; > -#endif /* CONFIG_PPC_PSERIES */ > - > /* Only need to enable them once */ > if (__get_cpu_var(pmcs_enabled)) > return; > > __get_cpu_var(pmcs_enabled) = 1; > > - switch (systemcfg->platform) { > - case PLATFORM_PSERIES: > - case PLATFORM_POWERMAC: > - hid0 = mfspr(HID0); > - hid0 |= 1UL << (63 - 20); > - > - /* POWER4 requires the following sequence */ > - asm volatile( > - "sync\n" > - "mtspr %1, %0\n" > - "mfspr %0, %1\n" > - "mfspr %0, %1\n" > - "mfspr %0, %1\n" > - "mfspr %0, %1\n" > - "mfspr %0, %1\n" > - "mfspr %0, %1\n" > - "isync" : "=&r" (hid0) : "i" (HID0), "0" (hid0): > - "memory"); > - break; > - > -#ifdef CONFIG_PPC_PSERIES > - case PLATFORM_PSERIES_LPAR: > - set = 1UL << 63; > - reset = 0; > - plpar_hcall_norets(H_PERFMON, set, reset); > - break; > -#endif /* CONFIG_PPC_PSERIES */ > - > - default: > - break; > - } > - > - /* instruct hypervisor to maintain PMCs */ > - if (firmware_has_feature(FW_FEATURE_SPLPAR)) > - get_paca()->lppaca.pmcregs_in_use = 1; > + if (ppc_md.enable_pmcs) > + ppc_md.enable_pmcs(); > } > - > -#else > - > -/* PMC stuff */ > -void ppc64_enable_pmcs(void) > -{ > - /* XXX Implement for iseries */ > -} > -#endif /* CONFIG_PPC_MULTIPLATFORM */ > - > EXPORT_SYMBOL(ppc64_enable_pmcs); > > /* XXX convert to rusty's on_one_cpu */ > Index: work/arch/ppc64/oprofile/op_model_power4.c > =================================================================== > --- work.orig/arch/ppc64/oprofile/op_model_power4.c > +++ work/arch/ppc64/oprofile/op_model_power4.c > @@ -83,6 +83,27 @@ static void power4_reg_setup(struct op_c > mmcr0_val |= MMCR0_PROBLEM_DISABLE; > } > > +void power4_enable_pmcs(void) > +{ > + unsigned long hid0; > + > + hid0 = mfspr(HID0); > + hid0 |= 1UL << (63 - 20); > + > + /* POWER4 requires the following sequence */ > + asm volatile( > + "sync\n" > + "mtspr %1, %0\n" > + "mfspr %0, %1\n" > + "mfspr %0, %1\n" > + "mfspr %0, %1\n" > + "mfspr %0, %1\n" > + "mfspr %0, %1\n" > + "mfspr %0, %1\n" > + "isync" : "=&r" (hid0) : "i" (HID0), "0" (hid0): > + "memory"); > +} > + > extern void ppc64_enable_pmcs(void); > > static void power4_cpu_setup(void *unused) > Index: work/include/asm-ppc64/machdep.h > =================================================================== > --- work.orig/include/asm-ppc64/machdep.h > +++ work/include/asm-ppc64/machdep.h > @@ -140,11 +140,16 @@ struct machdep_calls { > > /* Idle loop for this platform, leave empty for default idle loop */ > int (*idle_loop)(void); > + > + /* Function to enable pmcs for this platform, called once per cpu. */ > + void (*enable_pmcs)(void); > }; > > extern int default_idle(void); > extern int native_idle(void); > > +extern void power4_enable_pmcs(void); > + > extern struct machdep_calls ppc_md; > extern char cmd_line[COMMAND_LINE_SIZE]; > > _______________________________________________ > Linuxppc64-dev mailing list > Linuxppc64-dev at ozlabs.org > https://ozlabs.org/mailman/listinfo/linuxppc64-dev -- Michael Ellerman IBM OzLabs email: michael:ellerman.id.au inmsg: mpe:jabber.org wwweb: http://michael.ellerman.id.au phone: +61 2 6212 1183 (tie line 70 21183) We do not inherit the earth from our ancestors, we borrow it from our children. - S.M.A.R.T Person -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: not available Url : http://ozlabs.org/pipermail/linuxppc64-dev/attachments/20050808/85ff0d73/attachment.pgp From mostrows at watson.ibm.com Mon Aug 8 23:32:16 2005 From: mostrows at watson.ibm.com (Michal Ostrowski) Date: Mon, 8 Aug 2005 09:32:16 -0400 Subject: [PATCH] Externally visible buffer for CONFIG_CMDLINE In-Reply-To: <17142.61040.804303.329948@cargo.ozlabs.ibm.com> References: <20050704193652.23980d26@brick.watson.ibm.com> <17142.61040.804303.329948@cargo.ozlabs.ibm.com> Message-ID: <20050808093216.4027bd6f@brick.watson.ibm.com> I've included a better patch which does similar things to the bzImage wrapper code as we discussed at OLS. On Mon, 8 Aug 2005 15:32:32 +1000 Paul Mackerras wrote: > Michal Ostrowski writes: > > > +#ifdef CONFIG_CMDLINE > > +const char builtin_cmdline[COMMAND_LINE_SIZE] > > + __attribute__((section("__builtin_cmdline"))) = CONFIG_CMDLINE; > > +#endif > > Where does the __builtin_cmdline section get linked, given that it > isn't mentioned explicitly in the vmlinux.lds? There is no need to actually specify it in vmlinux.lds. The linker will simply create that section. The linker will also create symbols which let me reference the boundaries of this section (e.g. __start___builtin_cmdline). In my builds it ends up after .rodata and before .pci_fixup. -- Michal Ostrowski # HG changeset patch # User mostrows at heater.watson.ibm.com # Node ID 8b371ee4b3b31923857f540a28fdcd3d2a42233c # Parent 9f5416993abdaa44f3ecc9095372eeb5e9816704 Allow for built-in command line to be edited in binary images. Define buffers for the built-in command-line strings in the bzImage wrapper and in the early boot program. The buffers reside in sections called "__builtin_cmdline" and so can be easily accessed and modified by tools. This avoid the need to reconfigure and re-build in order to change a built-in command line. Precedence is always given to an existing /chosen/bootargs property (but if one is not present bzImage wrapper will create one with the contents of it's built-in command-line buffer). Signed-off-by: Michal Ostrowski diff -r 9f5416993abd -r 8b371ee4b3b3 arch/ppc64/boot/main.c --- a/arch/ppc64/boot/main.c Mon Aug 8 03:00:07 2005 +++ b/arch/ppc64/boot/main.c Mon Aug 8 13:28:34 2005 @@ -14,9 +14,11 @@ #include #include #include +#include extern void *finddevice(const char *); extern int getprop(void *, const char *, void *, int); +extern int setprop(void *, const char *, void *, int); extern void printf(const char *fmt, ...); extern int sprintf(char *buf, const char *fmt, ...); void gunzip(void *, int, unsigned char *, int *); @@ -73,6 +75,11 @@ #undef DEBUG +#ifdef CONFIG_CMDLINE +char builtin_cmdline[COMMAND_LINE_SIZE] + __attribute__((section("__builtin_cmdline"))) = CONFIG_CMDLINE; +#endif + static unsigned long claim_base = PROG_START; static unsigned long try_claim(unsigned long size) @@ -97,6 +104,7 @@ { unsigned long i; kernel_entry_t kernel_entry; + char cmdline[COMMAND_LINE_SIZE]; Elf64_Ehdr *elf64; Elf64_Phdr *elf64ph; @@ -109,6 +117,15 @@ stderr = stdout; if (getprop(chosen_handle, "stdin", &stdin, sizeof(stdin)) != 4) exit(); + +#ifdef CONFIG_CMDLINE + i = getprop(chosen_handle, "bootargs", cmdline, sizeof(cmdline)); + if (i <= 0 || cmdline[0] == 0) { + setprop(chosen_handle, "bootargs", builtin_cmdline, + strlen(builtin_cmdline)); + } + +#endif /* CONFIG_CMDLINE */ printf("\n\rzImage starting: loaded at 0x%x\n\r", (unsigned)_start); diff -r 9f5416993abd -r 8b371ee4b3b3 arch/ppc64/boot/prom.c --- a/arch/ppc64/boot/prom.c Mon Aug 8 03:00:07 2005 +++ b/arch/ppc64/boot/prom.c Mon Aug 8 13:28:34 2005 @@ -38,6 +38,7 @@ void exit(void); void *finddevice(const char *name); int getprop(void *phandle, const char *name, void *buf, int buflen); +int setprop(void *phandle, const char *name, void *buf, int buflen); void chrpboot(int a1, int a2, void *prom); /* in main.c */ int printf(char *fmt, ...); @@ -175,6 +176,32 @@ } args; args.service = "getprop"; + args.nargs = 4; + args.nret = 1; + args.phandle = phandle; + args.name = name; + args.buf = buf; + args.buflen = buflen; + args.size = -1; + (*prom)(&args); + return args.size; +} + +int +setprop(void *phandle, const char *name, void *buf, int buflen) +{ + struct prom_args { + char *service; + int nargs; + int nret; + void *phandle; + const char *name; + void *buf; + int buflen; + int size; + } args; + + args.service = "setprop"; args.nargs = 4; args.nret = 1; args.phandle = phandle; diff -r 9f5416993abd -r 8b371ee4b3b3 arch/ppc64/kernel/prom.c --- a/arch/ppc64/kernel/prom.c Mon Aug 8 03:00:07 2005 +++ b/arch/ppc64/kernel/prom.c Mon Aug 8 13:28:34 2005 @@ -72,6 +72,10 @@ u32 size; }; +#ifdef CONFIG_CMDLINE +const char builtin_cmdline[COMMAND_LINE_SIZE] + __attribute__((section("__builtin_cmdline"))) = CONFIG_CMDLINE; +#endif typedef int interpret_func(struct device_node *, unsigned long *, int, int, int); @@ -870,7 +874,7 @@ } #ifdef CONFIG_CMDLINE if (l == 0 || (l == 1 && (*p) == 0)) - strlcpy(cmd_line, CONFIG_CMDLINE, COMMAND_LINE_SIZE); + strlcpy(cmd_line, builtin_cmdline, sizeof(builtin_cmdline)); #endif /* CONFIG_CMDLINE */ DBG("Command line is: %s\n", cmd_line); diff -r 9f5416993abd -r 8b371ee4b3b3 arch/ppc64/kernel/prom_init.c --- a/arch/ppc64/kernel/prom_init.c Mon Aug 8 03:00:07 2005 +++ b/arch/ppc64/kernel/prom_init.c Mon Aug 8 13:28:34 2005 @@ -56,6 +56,10 @@ extern const struct linux_logo logo_linux_clut224; #endif +#ifdef CONFIG_CMDLINE +extern const char builtin_cmdline[COMMAND_LINE_SIZE]; +#endif + /* * Properties whose value is longer than this get excluded from our * copy of the device tree. This value does need to be big enough to @@ -477,7 +481,7 @@ #ifdef CONFIG_CMDLINE if (l == 0) /* dbl check */ strlcpy(RELOC(prom_cmd_line), - RELOC(CONFIG_CMDLINE), sizeof(prom_cmd_line)); + RELOC(builtin_cmdline), sizeof(prom_cmd_line)); #endif /* CONFIG_CMDLINE */ prom_printf("command line: %s\n", RELOC(prom_cmd_line)); -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: not available Url : http://ozlabs.org/pipermail/linuxppc64-dev/attachments/20050808/0b5c1514/attachment.pgp From sharada at in.ibm.com Tue Aug 9 01:23:48 2005 From: sharada at in.ibm.com (R Sharada) Date: Mon, 8 Aug 2005 20:53:48 +0530 Subject: kexec-tools for ppc64 - RFC Message-ID: <20050808152348.GA4898@in.ibm.com> Hello, Finally, here is a first draft of the kexec-tools support for ppc64. This has been tested on Power4 p630 machine, in both lpar and non-lpar environments, with kexec-tools-1.101 and linux kernel version 2.6.13-rc5. Current Status --------------- kexec-tools can now be used to kexec load and reboot into a second kernel. This integration uses the old tools primarily written by Milton Miller and enables the old tools to work from within the kexec-tools package. - fs2dt which is the device-tree flattening code is still retained as a separate source file, but converted into a function call, which is called from within kexec-tools code. - v2wrap is still retained as a separate assembly stub and is being compiled and built from within the kexec/arch/ppc64 directory. - v2wrap + flat device-tree is still loaded as a single segment. - default compilation is 64-bit. Current Limitations -------------------- - User has to supply the load addresses (or range in which the load address is to start at) for 2 segments that are currently supported - vmlinux, and v2wrap. This is because of a limitation in the amount of data currently available from get_memory_ranges on ppc64. get_memory_ranges currently reads the memory range from /proc/device-tree which does not provide information about the memory ranges occupied by the hash page tables (in non-lpar case), as well as the rmo boundary for both lpar and non-lpar. - Hackish way to find the device-tree load address (by calling locate_hole in advance) to fill up the reserve_mem address for device-tree. - initrd loading is currently not supported. Work in Progress ----------------- - Clean up build to put v2wrap binary into objdir - Fix and clean up the get_memory_range support in ppc64 so that we do not have to have the user to supply load addresses for the segments. - Adding support to load initrd image. ToDo ----- - Integrate v2wrap to be built from within purgatory Example Usage -------------- A sample load call would be: kexec -l vmlinux --v2wrap=v2wrap --append="v2wrap-base=0x5000000 vmlinux-base=0x6000000" To kexec reboot: kexec -e ps: I still seem to have to do an occasional ifdown on the network interface prior to a kexec -e This however still needs lots of testing and cleanups some of which will be posted shortly. Kindly review / test and provide comments. Thanks and Regards, Sharada --- kexec-tools-1.101-sharada/Makefile | 4 kexec-tools-1.101-sharada/configure | 7 kexec-tools-1.101-sharada/kexec/arch/ppc64/Makefile | 5 kexec-tools-1.101-sharada/kexec/arch/ppc64/fs2dt.c | 314 ++++++++++ kexec-tools-1.101-sharada/kexec/arch/ppc64/kexec-elf-ppc64.c | 201 +++++- kexec-tools-1.101-sharada/kexec/arch/ppc64/kexec-elf-rel-ppc64.c | 2 kexec-tools-1.101-sharada/kexec/arch/ppc64/kexec-ppc64.c | 168 +++++ kexec-tools-1.101-sharada/kexec/arch/ppc64/kexec-ppc64.h | 6 kexec-tools-1.101-sharada/kexec/arch/ppc64/make_v2wrap | 13 kexec-tools-1.101-sharada/kexec/arch/ppc64/v2wrap.S | 114 +++ kexec-tools-1.101-sharada/purgatory/Makefile | 5 11 files changed, 799 insertions(+), 40 deletions(-) diff -puN configure~kexec-tools-ppc64 configure --- kexec-tools-1.101/configure~kexec-tools-ppc64 2005-08-08 20:26:12.000000000 +0530 +++ kexec-tools-1.101-sharada/configure 2005-08-08 20:27:19.000000000 +0530 @@ -1384,6 +1384,9 @@ case $host_cpu in powerpc ) host_cpu="ppc" ;; + powerpc64 ) + host_cpu="ppc64" + ;; * ) host_cpu="$host_cpu" ;; @@ -1421,6 +1424,10 @@ if test "${with_gamecube+set}" = set; th EXTRA_CFLAGS="$EXTRA_CFLAGS -DCONFIG_GAMECUBE=1" fi; +# Check whether ppc64. Add -m64 for building 64-bit binary +if test "$ARCH"=ppc64; then + EXTRA_CFLAGS="$EXTRA_CFLAGS -m64" +fi; # Check whether --with-zlib or --without-zlib was given. if test "${with_zlib+set}" = set; then diff -puN Makefile~kexec-tools-ppc64 Makefile --- kexec-tools-1.101/Makefile~kexec-tools-ppc64 2005-08-08 20:26:12.000000000 +0530 +++ kexec-tools-1.101-sharada/Makefile 2005-08-08 20:35:13.000000000 +0530 @@ -89,6 +89,10 @@ endif ifeq ($(ARCH),x86_64) include kexec_test/Makefile endif +ifeq ($(ARCH),ppc64) +include kexec/arch/ppc64/make_v2wrap +endif + GENERATED_SRCS:= ./configure SPEC=$(OBJDIR)/$(PACKAGE)-$(VERSION).spec diff -puN /dev/null kexec/arch/ppc64/fs2dt.c --- /dev/null 2005-08-08 20:42:13.772546000 +0530 +++ kexec-tools-1.101-sharada/kexec/arch/ppc64/fs2dt.c 2005-08-08 20:39:26.000000000 +0530 @@ -0,0 +1,314 @@ +/* + * fs2dt: creates a flattened device-tree + * + * Copyright (C) 2004,2005 Milton D Miller II, IBM Corporation + * Copyright (C) 2005 R Sharada (sharada at in.ibm.com), IBM Corporation + * + * 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 (version 2 of the License). + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include "kexec-ppc64.h" + +#define MAXPATH 1024 /* max path name length */ +#define NAMESPACE 16384 /* max bytes for property names */ +#define TREEWORDS 65536 /* max 32 bit words for property values */ +#define MEMRESERVE 256 /* max number of reserved memory blocks */ + +enum { + ERR_NONE, + ERR_USAGE, + ERR_OPENDIR, + ERR_READDIR, + ERR_STAT, + ERR_OPEN, + ERR_READ, + ERR_RESERVE, +}; + +void err(const char *str, int rc) +{ + if (errno) + perror(str); + else + fprintf(stderr, "%s: unrecoverable error\n", str); + exit(rc); +} + +typedef unsigned dvt; +struct stat statbuf[1]; +char pathname[MAXPATH], *pathstart; +char propnames[NAMESPACE]; +dvt dtstruct[TREEWORDS], *dt; +unsigned long long mem_rsrv[2*MEMRESERVE]; + +extern unsigned long initrd_base; +extern unsigned long initrd_size; + +void reserve(unsigned long long where, unsigned long long length) +{ + unsigned long long *mr; + + mr = mem_rsrv; + + while(mr[1]) + mr += 2; + + mr[0] = where; + mr[1] = length; +} + +/* look for properties we need to reserve memory space for */ +void checkprop(char *name, dvt *data) +{ + static unsigned long long base, size, end; + + if ((data == NULL) && (base || size || end)) + err((void *)data, ERR_RESERVE); + else if (!strcmp(name, "linux,rtas-base")) + base = *data; + else if (!strcmp(name, "linux,initrd-start")) { + if (initrd_base) + base = initrd_base; + else + base = *(unsigned long long *) data; + } + else if (!strcmp(name, "linux,tce-base")) + base = *(unsigned long long *) data; + else if (!strcmp(name, "rtas-size") || + !strcmp(name, "linux,tce-size")) + size = *data; + else if (!strcmp(name, "linux,initrd-end")) { + if (initrd_size) + size = initrd_size; + else + end = *(unsigned long long *) data; + } + if (size && end) + err(name, ERR_RESERVE); + if (base && size) { + reserve(base, size); + base = size = 0; + } + if (base && end) { + reserve(base, end-base); + base = end = 0; + } +} + +/* + * return the property index for a property name, creating a new one + * if needed. + */ +dvt propnum(const char *name) +{ + dvt offset = 0; + + while(propnames[offset]) + if (strcmp(name, propnames+offset)) + offset += strlen(propnames+offset)+1; + else + return offset; + + strcpy(propnames+offset, name); + + return offset; +} + +/* put all properties (files) in the property structure */ +void putprops(char *fn, DIR *dir) +{ + struct dirent *dp; + + while ((dp = readdir(dir)) != NULL) { + strcpy(fn, dp->d_name); + + if (lstat(pathname, statbuf)) + err(pathname, ERR_STAT); + + if (S_ISREG(statbuf[0].st_mode)) { + int fd, len = statbuf[0].st_size; + + *dt++ = 3; + *dt++ = len; + *dt++ = propnum(fn); + + if ((len >= 8) && ((unsigned long)dt & 0x4)) + dt++; + + fd = open(pathname, O_RDONLY); + if (fd == -1) + err(pathname, ERR_OPEN); + if (read(fd, dt, len) != len) + err(pathname, ERR_READ); + close(fd); + + checkprop(fn, dt); + + dt += (len + 3)/4; + } + } + fn[0] = '\0'; + if(errno == ENOSYS) + errno = 0; + if (errno) + err(pathname, ERR_READDIR); + checkprop(pathname, NULL); +} + +/* + * put a node (directory) in the property structure. first properties + * then children. + */ +void putnode(void) +{ + DIR *dir; + char *dn; + struct dirent *dp; + + *dt++ = 1; + strcpy((void *)dt, *pathstart ? pathstart : "/"); + while(*dt) + dt++; + if (dt[-1] & 0xff) + dt++; + + dir = opendir(pathname); + + if (!dir) + err(pathname, ERR_OPENDIR); + + strcat(pathname, "/"); + dn = pathname + strlen(pathname); + + putprops(dn, dir); + + rewinddir(dir); + + while ((dp = readdir(dir)) != NULL) { + strcpy(dn, dp->d_name); + + if (!strcmp(dn, ".") || !strcmp(dn, "..")) + continue; + + if (lstat(pathname, statbuf)) + err(pathname, ERR_STAT); + + if (S_ISDIR(statbuf[0].st_mode)) + putnode(); + } + if (errno) + err(pathname, ERR_READDIR); + + *dt++ = 2; + closedir(dir); + dn[-1] = '\0'; +} + +/* boot block version 2 as defined by the linux kernel */ +struct bootblock { + unsigned magic, + totalsize, + off_dt_struct, + off_dt_strings, + off_mem_rsvmap, + version, + last_comp_version, + boot_physid; +} bb[1]; + +struct devtree_data { + unsigned long load_addr; + unsigned long initrd_start; + unsigned long initrd_size; +}; + +int create_flatten_tree(struct kexec_info *info, unsigned char **bufp, unsigned long *sizep) +{ + unsigned long len; + unsigned long tlen; + unsigned char *buf; + unsigned long me; + unsigned long base_addr; + unsigned long size; + + me = 0; + base_addr = 0; + + strcpy(pathname, "/proc/device-tree/"); + + pathstart = pathname + strlen(pathname); + dt = dtstruct; + + putnode(); + *dt++ = 9; + + len = sizeof(bb[0]); + len += 7; len &= ~7; + + bb->off_mem_rsvmap = len; + + for (len = 1; mem_rsrv[len]; len += 2) + ; + len+= 3; + len *= sizeof(mem_rsrv[0]); + + bb->off_dt_struct = bb->off_mem_rsvmap + len; + + len = dt - dtstruct; + len *= sizeof(dvt); + bb->off_dt_strings = bb->off_dt_struct + len; + + len = propnum(""); + len += 3; len &= ~3; + bb->totalsize = bb->off_dt_strings + len; + + bb->magic = 0xd00dfeed; + bb->version = 2; + bb->last_comp_version = 2; + + size = bb->totalsize + 0x100; + /* Hacks - should clean this up so that we can set a logical and valid + * min and max addr to pass into locate_hole + */ + unsigned long max_addr = v2wrap_base + 0x1000000; + base_addr = (unsigned long)locate_hole(info, size, 0, v2wrap_base, max_addr, -1); + if (base_addr) { + me = base_addr + 0x100; + } + + reserve(me, bb->totalsize); + + buf = (unsigned char *) realloc(*bufp, *sizep + bb->totalsize); + *bufp = buf; + memcpy(buf+(*sizep), bb, bb->off_mem_rsvmap); + tlen = *sizep + bb->off_mem_rsvmap; + memcpy(buf+tlen, mem_rsrv, bb->off_dt_struct - bb->off_mem_rsvmap); + tlen = tlen + (bb->off_dt_struct - bb->off_mem_rsvmap); + memcpy(buf+tlen, dtstruct, bb->off_dt_strings - bb->off_dt_struct); + tlen = tlen + (bb->off_dt_strings - bb->off_dt_struct); + memcpy(buf+tlen, propnames, bb->totalsize - bb->off_dt_strings); + tlen = tlen + bb->totalsize - bb->off_dt_strings; + *sizep = tlen; + return 0; +} diff -puN kexec/arch/ppc64/kexec-elf-ppc64.c~kexec-tools-ppc64 kexec/arch/ppc64/kexec-elf-ppc64.c --- kexec-tools-1.101/kexec/arch/ppc64/kexec-elf-ppc64.c~kexec-tools-ppc64 2005-08-08 20:26:13.000000000 +0530 +++ kexec-tools-1.101-sharada/kexec/arch/ppc64/kexec-elf-ppc64.c 2005-08-08 20:39:50.000000000 +0530 @@ -3,6 +3,7 @@ * * Copyright (C) 2004 Adam Litke (agl at us.ibm.com) * Copyright (C) 2004 IBM Corp. + * Copyright (C) 2005 R Sharada (sharada at in.ibm.com) * * 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 @@ -33,45 +34,14 @@ #include "../../kexec.h" #include "../../kexec-elf.h" #include "kexec-ppc64.h" +#include #define BOOTLOADER "kexec" #define BOOTLOADER_VERSION VERSION #define MAX_COMMAND_LINE 256 -#define UPSZ(X) ((sizeof(X) + 3) & ~3) -static struct boot_notes { - Elf_Bhdr hdr; - Elf_Nhdr bl_hdr; - unsigned char bl_desc[UPSZ(BOOTLOADER)]; - Elf_Nhdr blv_hdr; - unsigned char blv_desc[UPSZ(BOOTLOADER_VERSION)]; - Elf_Nhdr cmd_hdr; - unsigned char command_line[0]; -} elf_boot_notes = { - .hdr = { - .b_signature = 0x0E1FB007, - .b_size = sizeof(elf_boot_notes), - .b_checksum = 0, - .b_records = 3, - }, - .bl_hdr = { - .n_namesz = 0, - .n_descsz = sizeof(BOOTLOADER), - .n_type = EBN_BOOTLOADER_NAME, - }, - .bl_desc = BOOTLOADER, - .blv_hdr = { - .n_namesz = 0, - .n_descsz = sizeof(BOOTLOADER_VERSION), - .n_type = EBN_BOOTLOADER_VERSION, - }, - .blv_desc = BOOTLOADER_VERSION, - .cmd_hdr = { - .n_namesz = 0, - .n_descsz = 0, - .n_type = EBN_COMMAND_LINE, - }, -}; +int create_flatten_tree(struct kexec_info *, unsigned char*, unsigned long *); +int parse_options(char *); int elf_ppc64_probe(const char *buf, off_t len) { @@ -98,8 +68,67 @@ int elf_ppc64_load(int argc, char **argv struct kexec_info *info) { struct mem_ehdr ehdr; + const char *command_line; + const char *input_options; + int command_line_len; + const char *ramdisk; + const char *v2wrap; + unsigned long *lp; + int result; + int opt; +#define OPT_APPEND (OPT_ARCH_MAX+0) +#define OPT_V2WRAP (OPT_ARCH_MAX+1) +#define OPT_RAMDISK (OPT_ARCH_MAX+2) + + static const struct option options[] = { + KEXEC_ARCH_OPTIONS + { "append", 1, NULL, OPT_APPEND }, + { "v2wrap", 1, NULL, OPT_V2WRAP }, + { "ramdisk", 1, NULL, OPT_RAMDISK }, + { 0, 0, NULL, 0 }, + }; + + static const char short_options[] = KEXEC_OPT_STR ""; + + initrd_base = 0; + initrd_size = 0; + v2wrap_base = 0; + vmlinux_base = 0; /* Parse command line arguments */ + command_line = 0; + input_options = 0; + ramdisk = 0; + v2wrap = 0; + + while ((opt = getopt_long(argc, argv, short_options, options, 0)) != -1) { + switch (opt) { + default: + /* Ignore core options */ + if (opt < OPT_ARCH_MAX) { + break; + } + case '?': + usage(); + return -1; + case OPT_APPEND: + input_options = optarg; + break; + case OPT_V2WRAP: + v2wrap = optarg; + break; + case OPT_RAMDISK: + ramdisk = optarg; + break; + } + } + + command_line_len = 0; + if (command_line) { + command_line_len = strlen(command_line) + 1; + } + + parse_options(input_options); /* Parse the Elf file */ result = build_elf_exec_info(buf, len, &ehdr); @@ -108,16 +137,116 @@ int elf_ppc64_load(int argc, char **argv return result; } - /* Load the Elf data */ + /* Load the Elf data. Physical load addresses in elf64 header do not + * show up correctly. Use user supplied address for now to patch the + * elf header + */ + ehdr.e_phdr[0].p_paddr=vmlinux_base; result = elf_exec_load(&ehdr, info); if (result < 0) { free_elf_info(&ehdr); return result; } - return 1; + + /* Add v2wrap to the current image */ + if (v2wrap) { + unsigned char *v2wrap_buf = NULL; + off_t v2wrap_size = 0; + unsigned long hole_base = 0; + unsigned long max_addr; + + v2wrap_buf = slurp_file(v2wrap, &v2wrap_size); + create_flatten_tree(info, &v2wrap_buf, &v2wrap_size); + max_addr = v2wrap_base + 0x1000000; + add_buffer(info, v2wrap_buf, v2wrap_size, v2wrap_size, 0, v2wrap_base, max_addr, -1); + } + + lp = info->segment[1].buf + 0x100; + lp--; + *lp = info->segment[0].mem; + info->entry = info->segment[1].mem; + printf("segment[0].mem:%lx, segment[1].mem:" + "%lx\n", info->segment[0].mem, info->segment[1].mem); + + /* Add a ram-disk to the current image */ + if (ramdisk) { + /* Not supported at the moment - coming soon */ + } + + return 0; } void elf_ppc64_usage(void) { fprintf(stderr, "elf support is still broken\n"); } + +struct param_struct { + const char *name; + void *val; +}; +struct param_struct params; + +static char *next_arg(char *args, char **param, char **val) +{ + unsigned int i, equals = 0; + char *next; + + /* Chew any extra spaces */ + while (*args == ' ') args++; + + for (i = 0; args[i]; i++) { + if (args[i] == ' ') + break; + if (equals == 0) { + if (args[i] == '=') + equals = i; + } + } + + *param = args; + if (!equals) + *val = NULL; + else { + args[equals] = '\0'; + *val = args + equals + 1; + } + + if (args[i]) { + args[i] = '\0'; + next = args + i + 1; + } else + next = args + i; + return next; +} + +static int add_arg(char *param, char*val) +{ + int ret = 0; + if (strcmp(param, "initrd-base")==0) + initrd_base=strtoul(val, NULL, 0); + else if (strcmp(param, "initrd-size")==0) + initrd_size=strtoul(val, NULL, 0); + else if (strcmp(param, "v2wrap-base")==0) + v2wrap_base=strtoul(val, NULL, 0); + else if (strcmp(param, "vmlinux-base")==0) + vmlinux_base=strtoul(val, NULL, 0); + else { + printf("invalid option\n"); + ret = 1; + } + return ret; +} + +int parse_options(char *options) +{ + char *param, *val; + /* initrd-addr , initrd-size, v2wrap-addr, vmlinux-addr */ + while (*options) { + int ret; + options = next_arg(options, ¶m, &val); + ret = add_arg(param, val); + } + /* All parsed OK */ + return 0; +} diff -puN kexec/arch/ppc64/kexec-elf-rel-ppc64.c~kexec-tools-ppc64 kexec/arch/ppc64/kexec-elf-rel-ppc64.c --- kexec-tools-1.101/kexec/arch/ppc64/kexec-elf-rel-ppc64.c~kexec-tools-ppc64 2005-08-08 20:26:13.000000000 +0530 +++ kexec-tools-1.101-sharada/kexec/arch/ppc64/kexec-elf-rel-ppc64.c 2005-08-08 20:38:37.000000000 +0530 @@ -22,7 +22,7 @@ static struct mem_shdr *toc_section(cons struct mem_shdr *shdr, *shdr_end; unsigned char *strtab; strtab = ehdr->e_shdr[ehdr->e_shstrndx].sh_data; - shdr_end = &ehdr->e_shdr[ehdr->shnum]; + shdr_end = &ehdr->e_shdr[ehdr->e_shnum]; for(shdr = ehdr->e_shdr; shdr != shdr_end; shdr++) { if (strcmp(shdr->sh_name, ".toc") == 0) { return shdr; diff -puN /dev/null kexec/arch/ppc64/kexec-ppc64.c --- /dev/null 2005-08-08 20:42:13.772546000 +0530 +++ kexec-tools-1.101-sharada/kexec/arch/ppc64/kexec-ppc64.c 2005-08-08 20:40:13.000000000 +0530 @@ -0,0 +1,168 @@ +/* + * kexec: Linux boots Linux + * + * Copyright (C) 2005 R Sharada (sharada at in.ibm.com), IBM Corporation + * + * 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 (version 2 of the License). + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../../kexec.h" +#include "../../kexec-syscall.h" +#include "kexec-ppc64.h" +#include + +#define MAX_MEMORY_RANGES 64 +#define MAX_LINE 160 +#define MAXBYTES 128 + +static struct memory_range memory_range[MAX_MEMORY_RANGES]; + +/* Return a sorted list of memory ranges. */ +int get_memory_ranges(struct memory_range **range, int *ranges) +{ + int memory_ranges = 0; + char device_tree[256] = "/proc/device-tree/"; + char fname[256]; + char buf[MAXBYTES-1]; + DIR *dir, *dmem; + FILE *file; + struct dirent *dentry, *mentry; + int n; + + if ((dir = opendir(device_tree)) == NULL) { + perror(device_tree); + return -1; + } + while ((dentry = readdir(dir)) != NULL) { + if (strncmp(dentry->d_name, "memory@", 7)) + continue; + strcpy(fname, device_tree); + strcat(fname, dentry->d_name); + if ((dmem = opendir(fname)) == NULL) { + perror(fname); + closedir(dir); + return -1; + } + while ((mentry = readdir(dmem)) != NULL) { + if (strcmp(mentry->d_name, "reg")) + continue; + strcat(fname, "/reg"); + if ((file = fopen(fname, "r")) == NULL) { + perror(fname); + closedir(dmem); + closedir(dir); + return -1; + } + if ((n = fread(buf, 1, MAXBYTES, file)) < 0) { + perror(fname); + fclose(file); + closedir(dmem); + closedir(dir); + return -1; + } + if (memory_ranges >= MAX_MEMORY_RANGES) + break; + memory_range[memory_ranges].start = + ((unsigned long long *)buf)[0]; + memory_range[memory_ranges].end = + memory_range[memory_ranges].start + + ((unsigned long long *)buf)[1]; + memory_range[memory_ranges].type = RANGE_RAM; + printf("%016Lx-%016Lx : %x\n", memory_range[memory_ranges].start, memory_range[memory_ranges].end, memory_range[memory_ranges].type); + memory_ranges++; + fclose(file); + } + closedir(dmem); + } + closedir(dir); + + *range = memory_range; + *ranges = memory_ranges; + return 0; +} + +struct file_type file_type[] = { + { "elf-ppc64", elf_ppc64_probe, elf_ppc64_load, elf_ppc64_usage }, +}; +int file_types = sizeof(file_type) / sizeof(file_type[0]); + +void arch_usage(void) +{ +} + +static struct { +} arch_options = { +}; + +int arch_process_options(int argc, char **argv) +{ + static const struct option options[] = { + KEXEC_ARCH_OPTIONS + { 0, 0, NULL, 0 }, + }; + static const char short_options[] = KEXEC_ARCH_OPT_STR; + int opt; + + opterr = 0; /* Don't complain about unrecognized options here */ + while((opt = getopt_long(argc, argv, short_options, options, 0)) != -1) { + switch(opt) { + default: + break; + } + } + /* Reset getopt for the next pass; called in other source modules */ + opterr = 1; + optind = 1; + return 0; +} + +int arch_compat_trampoline(struct kexec_info *info, unsigned long *flags) +{ + int result; + struct utsname utsname; + result = uname(&utsname); + if (result < 0) { + fprintf(stderr, "uname failed: %s\n", + strerror(errno)); + return -1; + } + if (strcmp(utsname.machine, "ppc64") == 0) + { + /* We are running a 32-bit kexec-tools on 64-bit ppc64. + * So pass KEXEC_ARCH_PPC64 here + */ + *flags |= KEXEC_ARCH_PPC64; + } + else { + fprintf(stderr, "Unsupported machine type: %s\n", + utsname.machine); + return -1; + } + return 0; +} + +void arch_update_purgatory(struct kexec_info *info) +{ +} + diff -puN kexec/arch/ppc64/kexec-ppc64.h~kexec-tools-ppc64 kexec/arch/ppc64/kexec-ppc64.h --- kexec-tools-1.101/kexec/arch/ppc64/kexec-ppc64.h~kexec-tools-ppc64 2005-08-08 20:26:13.000000000 +0530 +++ kexec-tools-1.101-sharada/kexec/arch/ppc64/kexec-ppc64.h 2005-08-08 20:30:33.000000000 +0530 @@ -6,4 +6,8 @@ int elf_ppc64_load(int argc, char **argv struct kexec_info *info); void elf_ppc64_usage(void); -#endif /* KEXEC_PPC_H */ +unsigned long initrd_base; +unsigned long initrd_size; +unsigned long v2wrap_base; +unsigned long vmlinux_base; +#endif /* KEXEC_PPC64_H */ diff -puN kexec/arch/ppc64/Makefile~kexec-tools-ppc64 kexec/arch/ppc64/Makefile --- kexec-tools-1.101/kexec/arch/ppc64/Makefile~kexec-tools-ppc64 2005-08-08 20:26:13.000000000 +0530 +++ kexec-tools-1.101-sharada/kexec/arch/ppc64/Makefile 2005-08-08 20:41:34.000000000 +0530 @@ -1,7 +1,8 @@ # # kexec ppc64 (linux booting linux) # +KEXEC_C_SRCS+= kexec/arch/ppc64/kexec-ppc64.c +KEXEC_C_SRCS+= kexec/arch/ppc64/kexec-elf-ppc64.c KEXEC_C_SRCS+= kexec/arch/ppc64/kexec-elf-rel-ppc64.c KEXEC_C_SRCS+= kexec/arch/ppc64/kexec-zImage-ppc64.c - -KEXEC_S_SRCS+= +KEXEC_C_SRCS+= kexec/arch/ppc64/fs2dt.c diff -puN /dev/null kexec/arch/ppc64/v2wrap.S --- /dev/null 2005-08-08 20:42:13.772546000 +0530 +++ kexec-tools-1.101-sharada/kexec/arch/ppc64/v2wrap.S 2005-08-08 20:28:08.000000000 +0530 @@ -0,0 +1,114 @@ +# +# kexec: Linux boots Linux +# +# Copyright (C) 2004 - 2005, Milton D Miller II, IBM Corporation +# +# 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 (version 2 of the License). +# +# 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., 675 Mass Ave, Cambridge, MA 02139, USA. +# + +# v2wrap.S +# a wrapper to place in front of a v2 device tree +# to call a ppc64 kernel with the expected arguments +# of kernel(device-tree, phys-offset, 0) +# +# calling convention: +# r3 = physical number of this cpu (all cpus) +# r4 = address of this chunk (master only) +# master enters at start (aka first byte of this chunk) +# slaves (additional cpus), if any, enter a copy of the +# first 0x100 bytes of this code relocated to 0x0 +# +# in other words, +# a copy of the first 0x100 bytes of this code is copied to 0 +# and the slaves are sent to address 0x60 +# with r3 = their physical cpu number. + + +# look a bit like a Linux kernel here ... + .machine ppc64 + .org 0 +start: b master + tweq 0,0 +secondary_hold: + .llong 0 + + .org 0x20 # need a bit more space than after slave, +master: + std 4,secondary_hold at l(0) # bring slaves up here to this copy + sync # try to get the slaves to see this + or 1,1,1 # low priority to let other thread catchup + isync + mr 5,3 # save cpu id to r5 + addi 3,4,0x100 # r3 = boot param block + lwz 6,20(3) # fetch version number + cmpwi 0,6,2 # v2 ? + blt 80f + stw 5,28(3) # save my cpu number as boot_cpu_phys +80: b 81f + + .org 0x60 # ABI: slaves start at 60 with r3=phys +slave: ld 4,secondary_hold at l(0); + cmpdi 0,4,0 + beq slave + + # ahh, master told us where he is running from + # jump into our copy of the code up there so this code can change + addi 5,4,1f-start + mtctr 5 + bctr + + # ok, now wait for the master to tell is to go back to the new block +1: ld 5,copied at l(4) + cmpdi 0,5,0 + beq 1b + ba 0x60 + + + + .long 0 # just an eye-catcher, delete if space needed + .long 0 # just an eye-catcher, delete if space needed + +81: # master continues here + or 3,3,3 # ok back to high, lets boot + lis 6,0x1 + mtctr 6 # delay a bit for slaves to catch up +83: bdnz 83b # before we overwrite 0-100 again + + ld 4,-8(3) # kernel pointer is at -8(bb) by loader + addi 5,4,-8 # prepare copy with update form instructions + li 6,0x100/8 + mtctr 6 + li 6,-8 +85: ldu 7,8(5) + stdu 7,8(6) + bdnz 85b + + li 5,0 # r5 will be 0 for kernel + dcbst 0,5 # store dcache, flush icache + dcbst 0,6 # 0 and 0xf8 covers us with 128 byte lines + mtctr 4 # prepare branch too + sync + icbi 0,5 + icbi 0,6 + sync + isync + std 6,-16(3) # send slaves back down + bctr # start kernel + + .org 0xf0 +copied: .llong 0 +kernel: .llong 0 + .org 0x100 +__end_stub: + .equ boot_block, . - start diff -puN purgatory/Makefile~kexec-tools-ppc64 purgatory/Makefile --- kexec-tools-1.101/purgatory/Makefile~kexec-tools-ppc64 2005-08-08 20:26:13.000000000 +0530 +++ kexec-tools-1.101-sharada/purgatory/Makefile 2005-08-08 20:31:16.000000000 +0530 @@ -6,6 +6,11 @@ # There is probably a cleaner way to do this but for now this # should keep us from accidentially include unsafe library functions # or headers. + +ifeq ($(ARCH),ppc64) +LDFLAGS = -melf64ppc +endif + PCFLAGS:=-Wall -Os \ -I$(shell $(CC) -print-file-name=include) \ -Ipurgatory/include -Ipurgatory/arch/$(ARCH)/include \ diff -puN /dev/null kexec/arch/ppc64/make_v2wrap --- /dev/null 2005-08-08 20:42:13.772546000 +0530 +++ kexec-tools-1.101-sharada/kexec/arch/ppc64/make_v2wrap 2005-08-08 20:42:12.000000000 +0530 @@ -0,0 +1,13 @@ +# kexec ppc64 (linux booting linux) +# Build v2wrap from here for now + +KEXEC_S_OBJ_PATH:=kexec/arch/ppc64 +KEXEC_S_SRCS:=kexec/arch/ppc64/v2wrap.S +KEXEC_S_OBJS:=kexec/arch/ppc64/v2wrap + +all: $(KEXEC_S_OBJS) +$(KEXEC_S_OBJS): $(KEXEC_S_SRCS) + gcc -c -o $(KEXEC_S_OBJ_PATH)/v2wrap.o $(KEXEC_S_OBJ_PATH)/v2wrap.S + ld -Ttext=0 -e 0 -o $(KEXEC_S_OBJ_PATH)/v2wrap.elf $(KEXEC_S_OBJ_PATH)/v2wrap.o + objcopy -O binary $(KEXEC_S_OBJ_PATH)/v2wrap.elf $(KEXEC_S_OBJ_PATH)/v2wrap + _ From mbellon at mvista.com Tue Aug 9 04:33:17 2005 From: mbellon at mvista.com (Mark Bellon) Date: Mon, 08 Aug 2005 11:33:17 -0700 Subject: [Fwd: [PATCH] PPC64: large INITRD causes kernel not to boot] Message-ID: <42F7A56D.7090809@mvista.com> > Please send patches like these to linuxppc64-dev at ozlabs.org, which is > the architecture list for ppc64. You might want to coordinate your work > with some of the other people working on initrd/yaboot updates at the > moment, Olaf Hering and others. In PPC64 there are number of problems in arch/ppc64/boot/main.c that prevent a kernel from making use of a large (greater than ~16MB) INITRD. This is 64 bit architecture and really large INITRD images should be possible. Simply put the existing code has a fixed reservation (claim) address and once the kernel plus initrd image are large enough to pass this address all sorts of bad things occur. The fix is the dynamically establish the first claim address above the loaded kernel plus initrd (plus some "padding" and rounding) mark Signed-off-by: Mark Bellon -------------- next part -------------- A non-text attachment was scrubbed... Name: common_initrd.patch Type: text/x-patch Size: 2451 bytes Desc: not available Url : http://ozlabs.org/pipermail/linuxppc64-dev/attachments/20050808/6f9796ed/attachment.bin From geoffrey.levand at am.sony.com Tue Aug 9 04:27:36 2005 From: geoffrey.levand at am.sony.com (Geoff Levand) Date: Mon, 08 Aug 2005 11:27:36 -0700 Subject: [RFC] addnote and pmac Message-ID: <42F7A418.2050601@am.sony.com> I found that my Mac G5 wouldn't boot with a zImage modified by addnote. It worked OK when the image wasn't run through addnote though. I took just a brief look at addnote.c, and it seems this step is specific to the OF implementation, or could it be needed by older tool chains? At any rate, by default it is run for all zImage builds, which we'll need to change to support at least some machines. Below is what I got working, but someone more familiar with the boot makefile and the needs of other machines could certainly do better. -Geoff Index: dev-2-6-12/arch/ppc64/boot/Makefile =================================================================== --- dev-2-6-12.orig/arch/ppc64/boot/Makefile 2005-08-08 10:43:43.000000000 -0700 +++ dev-2-6-12/arch/ppc64/boot/Makefile 2005-08-08 10:45:51.000000000 -0700 @@ -75,8 +75,12 @@ --add-section=.kernel:$(strip $(patsubst $(obj)/kernel-%.o,%, $(1)))=$(patsubst %.o,%.gz, $(1)) \ --set-section-flags=.kernel:$(strip $(patsubst $(obj)/kernel-%.o,%, $(1)))=$(OBJCOPYFLAGS) -quiet_cmd_addnote = ADDNOTE $@ - cmd_addnote = $(CROSS32LD) $(BOOTLFLAGS) -o $@ $(obj-boot) && $(obj)/addnote $@ +ifeq ($(CONFIG_PPC_ISERIES),y) + addnote_cmd := $(call if_changed,addnote) +endif + +quiet_cmd_addnote = ADDNOTE $@ + cmd_addnote = $(obj)/addnote $@ quiet_cmd_piggy = PIGGY $@ cmd_piggy = $(obj)/piggyback $(@:.o=) < $< | $(CROSS32AS) -o $@ @@ -96,11 +100,12 @@ $(obj)/zImage: obj-boot += $(call obj-sec, $(required)) $(obj)/zImage: $(call obj-sec, $(required)) $(obj-boot) $(obj)/addnote FORCE - $(call if_changed,addnote) + $(CROSS32LD) $(BOOTLFLAGS) -o $@ $(obj-boot) + $(addnote_cmd) $(obj)/zImage.initrd: obj-boot += $(call obj-sec, $(required) $(initrd)) $(obj)/zImage.initrd: $(call obj-sec, $(required) $(initrd)) $(obj-boot) $(obj)/addnote FORCE - $(call if_changed,addnote) + $(addnote_cmd) $(obj)/imagesize.c: vmlinux.strip @echo Generating $@ -EOF From olh at suse.de Tue Aug 9 04:54:35 2005 From: olh at suse.de (Olaf Hering) Date: Mon, 8 Aug 2005 20:54:35 +0200 Subject: [Fwd: [PATCH] PPC64: large INITRD causes kernel not to boot] In-Reply-To: <42F7A56D.7090809@mvista.com> References: <42F7A56D.7090809@mvista.com> Message-ID: <20050808185435.GA13206@suse.de> On Mon, Aug 08, Mark Bellon wrote: > + /* > + * The first available claim_base must be "out of the way" - > + * well above _start + kernel_size + initrd + overhead. > + */ > + > + claim_base = ((unsigned long) _start) + > + ((unsigned long) vmlinux_filesize) + > + (unsigned long)(_initrd_end - _initrd_start) + > + ONE_MB; Why do you have to make the initial claim_base non-zero? Did you try to start from zero? Appears to work ok for me. From olh at suse.de Tue Aug 9 04:56:54 2005 From: olh at suse.de (Olaf Hering) Date: Mon, 8 Aug 2005 20:56:54 +0200 Subject: [RFC] addnote and pmac In-Reply-To: <42F7A418.2050601@am.sony.com> References: <42F7A418.2050601@am.sony.com> Message-ID: <20050808185654.GB13206@suse.de> On Mon, Aug 08, Geoff Levand wrote: > At any rate, by default it is run for all zImage builds, which > we'll need to change to support at least some machines. Below is > what I got working, but someone more familiar with the boot > makefile and the needs of other machines could certainly do > better. Better split the build process to build a vmlinux.elf-pmac and a zImage.rs6k. From mbellon at mvista.com Tue Aug 9 05:02:58 2005 From: mbellon at mvista.com (Mark Bellon) Date: Mon, 08 Aug 2005 12:02:58 -0700 Subject: [Fwd: [PATCH] PPC64: large INITRD causes kernel not to boot] In-Reply-To: <20050808185435.GA13206@suse.de> References: <42F7A56D.7090809@mvista.com> <20050808185435.GA13206@suse.de> Message-ID: <42F7AC62.3070601@mvista.com> Olaf Hering wrote: > On Mon, Aug 08, Mark Bellon wrote: > > > >>+ /* >>+ * The first available claim_base must be "out of the way" - >>+ * well above _start + kernel_size + initrd + overhead. >>+ */ >>+ >>+ claim_base = ((unsigned long) _start) + >>+ ((unsigned long) vmlinux_filesize) + >>+ (unsigned long)(_initrd_end - _initrd_start) + >>+ ONE_MB; >> >> > >Why do you have to make the initial claim_base non-zero? Did you try to >start from zero? Appears to work ok for me. > > The original code started non-zero too [don't know why]. Yes, if everything was correct and the claims where proper one could always start at zero. I've got several platforms where the claim will (incorrectly) succeed below the computed location. This coding insures that no matter what the firmware thinks is right (or wrong) the claiming starts at a safe place. Insurance? On top of that it's just a waste of time. In really huge INITRD handling this adds unnecessary boot latency. mark From olh at suse.de Tue Aug 9 05:11:23 2005 From: olh at suse.de (Olaf Hering) Date: Mon, 8 Aug 2005 21:11:23 +0200 Subject: [Fwd: [PATCH] PPC64: large INITRD causes kernel not to boot] In-Reply-To: <42F7AC62.3070601@mvista.com> References: <42F7A56D.7090809@mvista.com> <20050808185435.GA13206@suse.de> <42F7AC62.3070601@mvista.com> Message-ID: <20050808191123.GA14047@suse.de> On Mon, Aug 08, Mark Bellon wrote: > The original code started non-zero too [don't know why]. Yes, if > everything was correct and the claims where proper one could always > start at zero. make sure to also claim the range from _start to _end. The firmware on my B50 doesnt claim the client memrange. > I've got several platforms where the claim will (incorrectly) succeed > below the computed location. This coding insures that no matter what the > firmware thinks is right (or wrong) the claiming starts at a safe place. > Insurance? What is wrong with allocations on low addresses? > On top of that it's just a waste of time. In really huge INITRD handling > this adds unnecessary boot latency. I could not load a 10Mb file via network on a POWER4 LPAR. Maybe your case is a huge ELF memsize. On what system do you see the failure? From mbellon at mvista.com Tue Aug 9 05:31:13 2005 From: mbellon at mvista.com (Mark Bellon) Date: Mon, 08 Aug 2005 12:31:13 -0700 Subject: [Fwd: [PATCH] PPC64: large INITRD causes kernel not to boot] In-Reply-To: <20050808191123.GA14047@suse.de> References: <42F7A56D.7090809@mvista.com> <20050808185435.GA13206@suse.de> <42F7AC62.3070601@mvista.com> <20050808191123.GA14047@suse.de> Message-ID: <42F7B301.5060008@mvista.com> Olaf Hering wrote: > On Mon, Aug 08, Mark Bellon wrote: > > > >>The original code started non-zero too [don't know why]. Yes, if >>everything was correct and the claims where proper one could always >>start at zero. >> >> > >make sure to also claim the range from _start to _end. The firmware on >my B50 doesnt claim the client memrange. > > Doesn't the "_start + ((unsigned long) vmlinux_filesize)" in the calculation already do that by never allowing an allocation in that address range? Yes, it's unclaimed but it's also not going to be around for very long... [pragmatic approach?] The kernel is copied to a claimed area, as is the initrd and then things are "lit". Whatever seems best we can do and I'll work up the patch. Comments? > > >>I've got several platforms where the claim will (incorrectly) succeed >>below the computed location. This coding insures that no matter what the >>firmware thinks is right (or wrong) the claiming starts at a safe place. >>Insurance? >> >> > >What is wrong with allocations on low addresses? > > The firmware only protects itself - the first MB or, on some firmwares, up to the first 48 MB. Regardless, the wrapper doesn't know how much is enough so the patch starts it in a known safe place - past its end. The old, hard coded 0x1400000 could lead to a claim in the middle of the image once the load image size was larger than 16 MB (4MB standard load point). > > >>On top of that it's just a waste of time. In really huge INITRD handling >>this adds unnecessary boot latency. >> >> > >I could not load a 10Mb file via network on a POWER4 LPAR. Maybe your >case is a huge ELF memsize. On what system do you see the failure? > > Motorola 6101 with 2 GB of RAM amongst others. I've got to support a 260 MB INITRD (and entire environment). I've seen firmware problems on platforms with huge ELF files. Never gets to execute code. I've got a kernel of approximately 2.5 MB plus the initrd. The initrd varies in size. A 50 MB INITRD, even compressed down, took me over the older 16 MB limit and one could see the problem and it works now. mark From olh at suse.de Tue Aug 9 05:42:35 2005 From: olh at suse.de (Olaf Hering) Date: Mon, 8 Aug 2005 21:42:35 +0200 Subject: [Fwd: [PATCH] PPC64: large INITRD causes kernel not to boot] In-Reply-To: <42F7B301.5060008@mvista.com> References: <42F7A56D.7090809@mvista.com> <20050808185435.GA13206@suse.de> <42F7AC62.3070601@mvista.com> <20050808191123.GA14047@suse.de> <42F7B301.5060008@mvista.com> Message-ID: <20050808194235.GA14744@suse.de> On Mon, Aug 08, Mark Bellon wrote: > Olaf Hering wrote: > >make sure to also claim the range from _start to _end. The firmware on > >my B50 doesnt claim the client memrange. > > > > > Doesn't the "_start + ((unsigned long) vmlinux_filesize)" in the > calculation already do that by never allowing an allocation in that > address range? Yes, it's unclaimed but it's also not going to be around > for very long... [pragmatic approach?] If the zimage elf range is claimed, nothing else will get this area, and claim_base could remain zero. something like this after of1275_prominit() is done in my zimage. of1275_claim((unsigned int)_start, (unsigned int)(_end - _start), 0); From mbellon at mvista.com Tue Aug 9 05:55:12 2005 From: mbellon at mvista.com (Mark Bellon) Date: Mon, 08 Aug 2005 12:55:12 -0700 Subject: [Fwd: [PATCH] PPC64: large INITRD causes kernel not to boot] In-Reply-To: <20050808194235.GA14744@suse.de> References: <42F7A56D.7090809@mvista.com> <20050808185435.GA13206@suse.de> <42F7AC62.3070601@mvista.com> <20050808191123.GA14047@suse.de> <42F7B301.5060008@mvista.com> <20050808194235.GA14744@suse.de> Message-ID: <42F7B8A0.3000901@mvista.com> Olaf Hering wrote: > On Mon, Aug 08, Mark Bellon wrote: > > > >>Olaf Hering wrote: >> >> >>>make sure to also claim the range from _start to _end. The firmware on >>>my B50 doesnt claim the client memrange. >>> >>> >>> >>> >>Doesn't the "_start + ((unsigned long) vmlinux_filesize)" in the >>calculation already do that by never allowing an allocation in that >>address range? Yes, it's unclaimed but it's also not going to be around >>for very long... [pragmatic approach?] >> >> > >If the zimage elf range is claimed, nothing else will get this area, and >claim_base could remain zero. > >something like this after of1275_prominit() is done in my zimage. >of1275_claim((unsigned int)_start, (unsigned int)(_end - _start), 0) > > I see your point. but I've got practical issues that I want to avoid: I've got platforms that claim only part of the space south of 4MB and _start is usually 4MB (a hole); starting at zero would not do nice things in some cases. I felt my coding prevents any possibility of problems by simply removing the chance of a collision. That initrd image is not claimed in your approach and it sits immediately about _end. It would need to be claimed as well. How about this? Claim everything in the loaded ELF file from _start explicitly with claim_start initialized at _start? However I still like my approach saving time especially with a huge INITRD. Listening and thinking, mark From mbellon at mvista.com Tue Aug 9 06:05:58 2005 From: mbellon at mvista.com (Mark Bellon) Date: Mon, 08 Aug 2005 13:05:58 -0700 Subject: [Fwd: [PATCH] PPC64: large INITRD causes kernel not to boot] In-Reply-To: <42F7B8A0.3000901@mvista.com> References: <42F7A56D.7090809@mvista.com> <20050808185435.GA13206@suse.de> <42F7AC62.3070601@mvista.com> <20050808191123.GA14047@suse.de> <42F7B301.5060008@mvista.com> <20050808194235.GA14744@suse.de> <42F7B8A0.3000901@mvista.com> Message-ID: <42F7BB26.9090500@mvista.com> Mark Bellon wrote: > Olaf Hering wrote: > >> On Mon, Aug 08, Mark Bellon wrote: >> >> >> >>> Olaf Hering wrote: >>> >>> >>>> make sure to also claim the range from _start to _end. The firmware on >>>> my B50 doesnt claim the client memrange. >>>> >>>> >>>> >>> >>> Doesn't the "_start + ((unsigned long) vmlinux_filesize)" in the >>> calculation already do that by never allowing an allocation in that >>> address range? Yes, it's unclaimed but it's also not going to be >>> around for very long... [pragmatic approach?] >>> >> >> >> If the zimage elf range is claimed, nothing else will get this area, and >> claim_base could remain zero. >> >> something like this after of1275_prominit() is done in my zimage. >> of1275_claim((unsigned int)_start, (unsigned int)(_end - _start), 0) >> >> > I see your point. but I've got practical issues that I want to avoid: > I've got platforms that claim only part of the space south of 4MB and > _start is usually 4MB (a hole); starting at zero would not do nice > things in some cases. I felt my coding prevents any possibility of > problems by simply removing the chance of a collision. > > That initrd image is not claimed in your approach and it sits > immediately about _end. It would need to be claimed as well. > > How about this? Claim everything in the loaded ELF file from _start > explicitly with claim_start initialized at _start? > > However I still like my approach saving time especially with a huge > INITRD. > > Listening and thinking, How about something like this? (haven't tried it yet). mark -------------- next part -------------- A non-text attachment was scrubbed... Name: common_initrd.patch Type: text/x-patch Size: 2992 bytes Desc: not available Url : http://ozlabs.org/pipermail/linuxppc64-dev/attachments/20050808/e09e0fba/attachment.bin From olh at suse.de Tue Aug 9 06:10:01 2005 From: olh at suse.de (Olaf Hering) Date: Mon, 8 Aug 2005 22:10:01 +0200 Subject: [Fwd: [PATCH] PPC64: large INITRD causes kernel not to boot] In-Reply-To: <42F7B8A0.3000901@mvista.com> References: <42F7A56D.7090809@mvista.com> <20050808185435.GA13206@suse.de> <42F7AC62.3070601@mvista.com> <20050808191123.GA14047@suse.de> <42F7B301.5060008@mvista.com> <20050808194235.GA14744@suse.de> <42F7B8A0.3000901@mvista.com> Message-ID: <20050808201001.GA15425@suse.de> On Mon, Aug 08, Mark Bellon wrote: > I see your point. but I've got practical issues that I want to avoid: > I've got platforms that claim only part of the space south of 4MB and > _start is usually 4MB (a hole); starting at zero would not do nice > things in some cases. I felt my coding prevents any possibility of > problems by simply removing the chance of a collision. Yes, try_claim could return an address below _start if size is small enough. > That initrd image is not claimed in your approach and it sits > immediately about _end. It would need to be claimed as well. No, initrd is moved to initrd.addr. > How about this? Claim everything in the loaded ELF file from _start > explicitly with claim_start initialized at _start? This is really only required for brokenfirmware implementations. I have seen it on IBM B50. Maybe older 64bit systems like 170 or 260 are broken as well. So you claim once from _start to _end, and set claim_base to _end. > However I still like my approach saving time especially with a huge INITRD. Does a claim take so much time? Maybe I misunderstood this part. From mbellon at mvista.com Tue Aug 9 06:19:37 2005 From: mbellon at mvista.com (Mark Bellon) Date: Mon, 08 Aug 2005 13:19:37 -0700 Subject: [Fwd: [PATCH] PPC64: large INITRD causes kernel not to boot] In-Reply-To: <20050808201001.GA15425@suse.de> References: <42F7A56D.7090809@mvista.com> <20050808185435.GA13206@suse.de> <42F7AC62.3070601@mvista.com> <20050808191123.GA14047@suse.de> <42F7B301.5060008@mvista.com> <20050808194235.GA14744@suse.de> <42F7B8A0.3000901@mvista.com> <20050808201001.GA15425@suse.de> Message-ID: <42F7BE59.4010700@mvista.com> Olaf Hering wrote: > On Mon, Aug 08, Mark Bellon wrote: > > > >>I see your point. but I've got practical issues that I want to avoid: >>I've got platforms that claim only part of the space south of 4MB and >>_start is usually 4MB (a hole); starting at zero would not do nice >>things in some cases. I felt my coding prevents any possibility of >>problems by simply removing the chance of a collision. >> >> > >Yes, try_claim could return an address below _start if size is small enough. > > > >>That initrd image is not claimed in your approach and it sits >>immediately about _end. It would need to be claimed as well. >> >> > >No, initrd is moved to initrd.addr. > > But the claim could come back right in the middle of the initrd image inside the ELF file (which is what happens in my case). The _end is the end of the (compressed) kernel code, not the end of file contain the vmlinuz with the initrd in it. Claiming part of the ELF image is no insurance that claims will not come back in the middle of the entire image. Only explicit claims covering everything or starting the claim_base about the entire image insure all data. >>How about this? Claim everything in the loaded ELF file from _start >>explicitly with claim_start initialized at _start? >> >> > >This is really only required for brokenfirmware implementations. I have >seen it on IBM B50. Maybe older 64bit systems like 170 or 260 are broken >as well. So you claim once from _start to _end, and set claim_base to >_end. > > As I pointed out this is not enough when the firmware is broken. The claim that succeeds can be in the middle of things. My change works on all platform regardless of the firmware (trust nobody). I've got a firmware that cannot claim below 48 MB. I can't protect the loaded image with a claim. try_claim would land up being very high up and useless. >>However I still like my approach saving time especially with a huge INITRD. >> >> > >Does a claim take so much time? Maybe I misunderstood this part? > > If the code used claim to grab the kernel ELF pieces, leaving claim_base at zero then using try_claim to grab memory will be very inefficient when the ELF imiage is huge - many retries that are wasted to get to the good zone. mark From olh at suse.de Tue Aug 9 08:30:10 2005 From: olh at suse.de (Olaf Hering) Date: Tue, 9 Aug 2005 00:30:10 +0200 Subject: [Fwd: [PATCH] PPC64: large INITRD causes kernel not to boot] In-Reply-To: <42F7B301.5060008@mvista.com> References: <42F7A56D.7090809@mvista.com> <20050808185435.GA13206@suse.de> <42F7AC62.3070601@mvista.com> <20050808191123.GA14047@suse.de> <42F7B301.5060008@mvista.com> Message-ID: <20050808223010.GA18775@suse.de> On Mon, Aug 08, Mark Bellon wrote: > >I could not load a 10Mb file via network on a POWER4 LPAR. Maybe your > >case is a huge ELF memsize. On what system do you see the failure? > > > > > Motorola 6101 with 2 GB of RAM amongst others. I've got to support a 260 > MB INITRD (and entire environment). > > I've seen firmware problems on platforms with huge ELF files. Never gets > to execute code. Where is the firmware located on your board, and where is the stack? stack is at 42MB on pseries, maybe some real huge kernel + initrd can overwrite parts of the stack. That would be 22MB, can probably only happen when loaded from yaboot. From mbellon at mvista.com Tue Aug 9 08:40:18 2005 From: mbellon at mvista.com (Mark Bellon) Date: Mon, 08 Aug 2005 15:40:18 -0700 Subject: [Fwd: [PATCH] PPC64: large INITRD causes kernel not to boot] In-Reply-To: <20050808223010.GA18775@suse.de> References: <42F7A56D.7090809@mvista.com> <20050808185435.GA13206@suse.de> <42F7AC62.3070601@mvista.com> <20050808191123.GA14047@suse.de> <42F7B301.5060008@mvista.com> <20050808223010.GA18775@suse.de> Message-ID: <42F7DF52.4090905@mvista.com> Olaf Hering wrote: > On Mon, Aug 08, Mark Bellon wrote: > > > >>>I could not load a 10Mb file via network on a POWER4 LPAR. Maybe your >>>case is a huge ELF memsize. On what system do you see the failure? >>> >>> >>> >>> >>Motorola 6101 with 2 GB of RAM amongst others. I've got to support a 260 >>MB INITRD (and entire environment). >> >>I've seen firmware problems on platforms with huge ELF files. Never gets >>to execute code. >> >> > >Where is the firmware located on your board, and where is the stack? >stack is at 42MB on pseries, maybe some real huge kernel + initrd can >overwrite parts of the stack. That would be 22MB, can probably only >happen when loaded from yaboot. > > Yes, the stack getting trashed is what is often looks like. The 22 MB seems about right for some of the firmware. Other firmwares seem to work to a much larger size. Regardless of the firmware issues I want to make sure the kernel/wrapper are clean for any size kernel+initrd. I'm testing a simplified patch that makes use of _end as you suggested. All the math is replaced by a "round up" of _end to set the initial claim_base. I hope to post the patch soon. mark From jschopp at austin.ibm.com Tue Aug 9 03:59:37 2005 From: jschopp at austin.ibm.com (Joel Schopp) Date: Mon, 08 Aug 2005 12:59:37 -0500 Subject: Merging ppc32 and ppc64 In-Reply-To: <17136.13558.773102.465379@cargo.ozlabs.ibm.com> References: <17136.13558.773102.465379@cargo.ozlabs.ibm.com> Message-ID: <42F79D89.3040709@austin.ibm.com> > I don't see the merge as changing the actual code that gets executed > on any given platform very much, except in one respect: we are going > to standardize on a flattened device tree as the way that information > about the platform gets passed from the boot loader to the kernel. > > Comments? Flames? :) There are several userspace applications that parse the non-flat device tree in /proc/device-tree on pSeries. While I like the idea of the flattened device tree I think we need to consider how many apps we are going to break with it. From kamitch at cisco.com Tue Aug 9 08:48:09 2005 From: kamitch at cisco.com (Keith Mitchell) Date: Mon, 08 Aug 2005 18:48:09 -0400 Subject: server_mode on Newer Powermac 1.8 (single) Message-ID: <42F7E129.6010105@cisco.com> I have about a dozen of the newer Powermac G5 1.8ghz (single) that has the SMU (not the PMU) and I was wondering if it is currently possible to get these things to automatically turn back on in the powerfail scenario. We also have some Dual 2ghz machines that we can set 'server_mode' to 1 in the /proc/pmu/options file but nothing similar seems to exist for these machines. If I put OSX on this thing and set it via that GUI will the setting stick? I thought I had done that initially but I now have some of the machines that will power back up and some that will not... but I don't remember if I powered down after doing that setting before installing linux or not. The output from /proc/cpuinfo for these machines is: processor : 0 cpu : PPC970FX, altivec supported clock : 1800.000000MHz revision : 3.0 timebase : 33333333 machine : PowerMac9,1 motherboard : PowerMac9,1 MacRISC4 Power Macintosh detected as : 415 (Unknown K2-based) pmac flags : 00000000 pmac-generation : NewWorld Right now I have YDL 4.0.1 (kernel 2.6.10) on the machines. Thanks. -- Keith Mitchell | | | kamitch at cisco.com | :|: :|: 7025 Kit Creek Road, P.O. Box 14987 | :|||||: :|||||: Research Triangle Park, NC 27709 | .:|||||||:.:|||||||:. 919-392-9607 | c i s c o S y s t e m s From paulus at samba.org Tue Aug 9 09:48:52 2005 From: paulus at samba.org (Paul Mackerras) Date: Tue, 9 Aug 2005 09:48:52 +1000 Subject: Merging ppc32 and ppc64 In-Reply-To: <42F79D89.3040709@austin.ibm.com> References: <17136.13558.773102.465379@cargo.ozlabs.ibm.com> <42F79D89.3040709@austin.ibm.com> Message-ID: <17143.61284.499588.465260@cargo.ozlabs.ibm.com> Joel Schopp writes: > There are several userspace applications that parse the non-flat device > tree in /proc/device-tree on pSeries. While I like the idea of the > flattened device tree I think we need to consider how many apps we are > going to break with it. ... and standardizing on the flattened device tree will mean that every ppc and ppc64 platform has stuff in /proc/device-tree, not just those that have OF. :) Paul. From mbellon at mvista.com Tue Aug 9 11:04:54 2005 From: mbellon at mvista.com (Mark Bellon) Date: Mon, 08 Aug 2005 18:04:54 -0700 Subject: [Fwd: [PATCH] PPC64: large INITRD causes kernel not to boot] In-Reply-To: <42F7DF52.4090905@mvista.com> References: <42F7A56D.7090809@mvista.com> <20050808185435.GA13206@suse.de> <42F7AC62.3070601@mvista.com> <20050808191123.GA14047@suse.de> <42F7B301.5060008@mvista.com> <20050808223010.GA18775@suse.de> <42F7DF52.4090905@mvista.com> Message-ID: <42F80136.9050500@mvista.com> Please find attached my revised patch. Olaf's suggestion of using _end removes the calculation making things smaller, neater and less complex. We could add an explicit claim of _start through _end. Given all of the broken firmware I'm seeing the claim_base cannot be set less than _end - and I prefer to round it up to MB boundary. Comments? mark Signed-off-by: Mark Bellon -------------- next part -------------- A non-text attachment was scrubbed... Name: common_initrd.patch Type: text/x-patch Size: 2462 bytes Desc: not available Url : http://ozlabs.org/pipermail/linuxppc64-dev/attachments/20050808/facc27ec/attachment.bin From michael at ellerman.id.au Tue Aug 9 11:13:36 2005 From: michael at ellerman.id.au (Michael Ellerman) Date: Tue, 9 Aug 2005 11:13:36 +1000 (EST) Subject: [PATCH] ppc64: Move ppc64_enable_pmcs() logic into a ppc_md function In-Reply-To: <20050808084539.26A1B67F4A@ozlabs.org> Message-ID: <20050809011336.EAF0B67F8D@ozlabs.org> David asked me to put power4_enable_pmcs() in arch/ppc64/kernel/pmc.c, so here's an updated (again) version. I've tested it on P5 LPAR and P4. It does what it used to. Signed-off-by: Michael Ellerman arch/ppc64/kernel/iSeries_setup.c | 2 + arch/ppc64/kernel/pSeries_setup.c | 21 ++++++++++++++ arch/ppc64/kernel/pmac_setup.c | 2 + arch/ppc64/kernel/pmc.c | 21 ++++++++++++++ arch/ppc64/kernel/sysfs.c | 54 ++------------------------------------ include/asm-ppc64/machdep.h | 3 ++ include/asm-ppc64/pmc.h | 2 + 7 files changed, 55 insertions(+), 50 deletions(-) Index: work/arch/ppc64/kernel/iSeries_setup.c =================================================================== --- work.orig/arch/ppc64/kernel/iSeries_setup.c +++ work/arch/ppc64/kernel/iSeries_setup.c @@ -947,6 +947,8 @@ void __init iSeries_early_setup(void) ppc_md.calibrate_decr = iSeries_calibrate_decr; ppc_md.progress = iSeries_progress; + /* XXX Implement enable_pmcs for iSeries */ + if (get_paca()->lppaca.shared_proc) { ppc_md.idle_loop = iseries_shared_idle; printk(KERN_INFO "Using shared processor idle loop\n"); Index: work/arch/ppc64/kernel/pSeries_setup.c =================================================================== --- work.orig/arch/ppc64/kernel/pSeries_setup.c +++ work/arch/ppc64/kernel/pSeries_setup.c @@ -61,6 +61,7 @@ #include #include #include +#include #include "i8259.h" #include "mpic.h" @@ -187,6 +188,21 @@ static void __init pSeries_setup_mpic(vo " MPIC "); } +static void pseries_lpar_enable_pmcs(void) +{ + unsigned long set, reset; + + power4_enable_pmcs(); + + set = 1UL << 63; + reset = 0; + plpar_hcall_norets(H_PERFMON, set, reset); + + /* instruct hypervisor to maintain PMCs */ + if (firmware_has_feature(FW_FEATURE_SPLPAR)) + get_paca()->lppaca.pmcregs_in_use = 1; +} + static void __init pSeries_setup_arch(void) { /* Fixup ppc_md depending on the type of interrupt controller */ @@ -245,6 +261,11 @@ static void __init pSeries_setup_arch(vo printk(KERN_INFO "Using default idle loop\n"); ppc_md.idle_loop = default_idle; } + + if (systemcfg->platform & PLATFORM_LPAR) + ppc_md.enable_pmcs = pseries_lpar_enable_pmcs; + else + ppc_md.enable_pmcs = power4_enable_pmcs; } static int __init pSeries_init_panel(void) Index: work/arch/ppc64/kernel/pmac_setup.c =================================================================== --- work.orig/arch/ppc64/kernel/pmac_setup.c +++ work/arch/ppc64/kernel/pmac_setup.c @@ -71,6 +71,7 @@ #include #include #include +#include #include "pmac.h" #include "mpic.h" @@ -511,4 +512,5 @@ struct machdep_calls __initdata pmac_md .progress = pmac_progress, .check_legacy_ioport = pmac_check_legacy_ioport, .idle_loop = native_idle, + .enable_pmcs = power4_enable_cpus, }; Index: work/arch/ppc64/kernel/sysfs.c =================================================================== --- work.orig/arch/ppc64/kernel/sysfs.c +++ work/arch/ppc64/kernel/sysfs.c @@ -101,6 +101,8 @@ static int __init setup_smt_snooze_delay } __setup("smt-snooze-delay=", setup_smt_snooze_delay); +#endif /* CONFIG_PPC_MULTIPLATFORM */ + /* * Enabling PMCs will slow partition context switch times so we only do * it the first time we write to the PMCs. @@ -110,63 +112,15 @@ static DEFINE_PER_CPU(char, pmcs_enabled void ppc64_enable_pmcs(void) { - unsigned long hid0; -#ifdef CONFIG_PPC_PSERIES - unsigned long set, reset; -#endif /* CONFIG_PPC_PSERIES */ - /* Only need to enable them once */ if (__get_cpu_var(pmcs_enabled)) return; __get_cpu_var(pmcs_enabled) = 1; - switch (systemcfg->platform) { - case PLATFORM_PSERIES: - case PLATFORM_POWERMAC: - hid0 = mfspr(HID0); - hid0 |= 1UL << (63 - 20); - - /* POWER4 requires the following sequence */ - asm volatile( - "sync\n" - "mtspr %1, %0\n" - "mfspr %0, %1\n" - "mfspr %0, %1\n" - "mfspr %0, %1\n" - "mfspr %0, %1\n" - "mfspr %0, %1\n" - "mfspr %0, %1\n" - "isync" : "=&r" (hid0) : "i" (HID0), "0" (hid0): - "memory"); - break; - -#ifdef CONFIG_PPC_PSERIES - case PLATFORM_PSERIES_LPAR: - set = 1UL << 63; - reset = 0; - plpar_hcall_norets(H_PERFMON, set, reset); - break; -#endif /* CONFIG_PPC_PSERIES */ - - default: - break; - } - - /* instruct hypervisor to maintain PMCs */ - if (firmware_has_feature(FW_FEATURE_SPLPAR)) - get_paca()->lppaca.pmcregs_in_use = 1; + if (ppc_md.enable_pmcs) + ppc_md.enable_pmcs(); } - -#else - -/* PMC stuff */ -void ppc64_enable_pmcs(void) -{ - /* XXX Implement for iseries */ -} -#endif /* CONFIG_PPC_MULTIPLATFORM */ - EXPORT_SYMBOL(ppc64_enable_pmcs); /* XXX convert to rusty's on_one_cpu */ Index: work/include/asm-ppc64/machdep.h =================================================================== --- work.orig/include/asm-ppc64/machdep.h +++ work/include/asm-ppc64/machdep.h @@ -140,6 +140,9 @@ struct machdep_calls { /* Idle loop for this platform, leave empty for default idle loop */ int (*idle_loop)(void); + + /* Function to enable pmcs for this platform, called once per cpu. */ + void (*enable_pmcs)(void); }; extern int default_idle(void); Index: work/arch/ppc64/kernel/pmc.c =================================================================== --- work.orig/arch/ppc64/kernel/pmc.c +++ work/arch/ppc64/kernel/pmc.c @@ -65,3 +65,24 @@ void release_pmc_hardware(void) spin_unlock(&pmc_owner_lock); } EXPORT_SYMBOL_GPL(release_pmc_hardware); + +void power4_enable_pmcs(void) +{ + unsigned long hid0; + + hid0 = mfspr(HID0); + hid0 |= 1UL << (63 - 20); + + /* POWER4 requires the following sequence */ + asm volatile( + "sync\n" + "mtspr %1, %0\n" + "mfspr %0, %1\n" + "mfspr %0, %1\n" + "mfspr %0, %1\n" + "mfspr %0, %1\n" + "mfspr %0, %1\n" + "mfspr %0, %1\n" + "isync" : "=&r" (hid0) : "i" (HID0), "0" (hid0): + "memory"); +} Index: work/include/asm-ppc64/pmc.h =================================================================== --- work.orig/include/asm-ppc64/pmc.h +++ work/include/asm-ppc64/pmc.h @@ -26,4 +26,6 @@ typedef void (*perf_irq_t)(struct pt_reg int reserve_pmc_hardware(perf_irq_t new_perf_irq); void release_pmc_hardware(void); +void power4_enable_pmcs(void); + #endif /* _PPC64_PMC_H */ From michael at ellerman.id.au Tue Aug 9 15:20:15 2005 From: michael at ellerman.id.au (Michael Ellerman) Date: Tue, 9 Aug 2005 15:20:15 +1000 (EST) Subject: [PATCH 0/3] A few fixes for the new device tree code Message-ID: <1123564809.127864.246065361642.qpatch@concordia> Here are three minor fixes for Benh's new device tree code. From michael at ellerman.id.au Tue Aug 9 15:20:18 2005 From: michael at ellerman.id.au (Michael Ellerman) Date: Tue, 9 Aug 2005 15:20:18 +1000 (EST) Subject: [PATCH 1/3] ppc64: Fix a misleading printk in unflatten_dt_node() In-Reply-To: <1123564809.127864.246065361642.qpatch@concordia> Message-ID: <20050809052018.88D9767EEF@ozlabs.org> When unflatten_dt_node() fails to find an OF_DT_END_NODE tag it prints "Weird tag at start of node", this should be "Weird tag at end of node". Signed-off-by: Michael Ellerman arch/ppc64/kernel/prom.c | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: work/arch/ppc64/kernel/prom.c =================================================================== --- work.orig/arch/ppc64/kernel/prom.c +++ work/arch/ppc64/kernel/prom.c @@ -918,7 +918,7 @@ static unsigned long __init unflatten_dt tag = *((u32 *)(*p)); } if (tag != OF_DT_END_NODE) { - printk("Weird tag at start of node: %x\n", tag); + printk("Weird tag at end of node: %x\n", tag); return mem; } *p += 4; From michael at ellerman.id.au Tue Aug 9 15:20:19 2005 From: michael at ellerman.id.au (Michael Ellerman) Date: Tue, 9 Aug 2005 15:20:19 +1000 (EST) Subject: [PATCH 2/3] ppc64: unflatten_device_tree() should check if lmb_alloc() fails In-Reply-To: <1123564809.127864.246065361642.qpatch@concordia> Message-ID: <20050809052019.6A26B67EF3@ozlabs.org> unflatten_device_tree() doesn't check if lmb_alloc() succeeds or not, it should. All it can do is panic, but at least there's an error message (assuming you have some sort of console at that point). Signed-off-by: Michael Ellerman arch/ppc64/kernel/prom.c | 9 +++++++-- 1 files changed, 7 insertions(+), 2 deletions(-) Index: work/arch/ppc64/kernel/prom.c =================================================================== --- work.orig/arch/ppc64/kernel/prom.c +++ work/arch/ppc64/kernel/prom.c @@ -950,8 +950,13 @@ void __init unflatten_device_tree(void) DBG(" size is %lx, allocating...\n", size); /* Allocate memory for the expanded device tree */ - mem = (unsigned long)abs_to_virt(lmb_alloc(size + 4, - __alignof__(struct device_node))); + mem = lmb_alloc(size + 4, __alignof__(struct device_node)); + if (!mem) { + DBG("Couldn't allocate memory with lmb_alloc()!\n"); + panic("Couldn't allocate memory with lmb_alloc()!\n"); + } + mem = (unsigned long)abs_to_virt(mem); + ((u32 *)mem)[size / 4] = 0xdeadbeef; DBG(" unflattening...\n", mem); From michael at ellerman.id.au Tue Aug 9 15:20:20 2005 From: michael at ellerman.id.au (Michael Ellerman) Date: Tue, 9 Aug 2005 15:20:20 +1000 (EST) Subject: [PATCH 3/3] ppc64: Check of_chosen in check_for_initrd() In-Reply-To: <1123564809.127864.246065361642.qpatch@concordia> Message-ID: <20050809052020.CF0B967EFC@ozlabs.org> You can't call get_property() on a NULL node, so check if of_chosen is set in check_for_initrd(). Signed-off-by: Michael Ellerman arch/ppc64/kernel/setup.c | 20 ++++++++++++-------- 1 files changed, 12 insertions(+), 8 deletions(-) Index: work/arch/ppc64/kernel/setup.c =================================================================== --- work.orig/arch/ppc64/kernel/setup.c +++ work/arch/ppc64/kernel/setup.c @@ -536,15 +536,19 @@ static void __init check_for_initrd(void DBG(" -> check_for_initrd()\n"); - prop = (u64 *)get_property(of_chosen, "linux,initrd-start", NULL); - if (prop != NULL) { - initrd_start = (unsigned long)__va(*prop); - prop = (u64 *)get_property(of_chosen, "linux,initrd-end", NULL); + if (of_chosen) { + prop = (u64 *)get_property(of_chosen, + "linux,initrd-start", NULL); if (prop != NULL) { - initrd_end = (unsigned long)__va(*prop); - initrd_below_start_ok = 1; - } else - initrd_start = 0; + initrd_start = (unsigned long)__va(*prop); + prop = (u64 *)get_property(of_chosen, + "linux,initrd-end", NULL); + if (prop != NULL) { + initrd_end = (unsigned long)__va(*prop); + initrd_below_start_ok = 1; + } else + initrd_start = 0; + } } /* If we were passed an initrd, set the ROOT_DEV properly if the values From paulus at samba.org Tue Aug 9 16:48:29 2005 From: paulus at samba.org (Paul Mackerras) Date: Tue, 9 Aug 2005 16:48:29 +1000 Subject: [PATCH] ppc64: Move ppc64_enable_pmcs() logic into a ppc_md function In-Reply-To: <20050809011336.EAF0B67F8D@ozlabs.org> References: <20050808084539.26A1B67F4A@ozlabs.org> <20050809011336.EAF0B67F8D@ozlabs.org> Message-ID: <17144.20925.218140.776125@cargo.ozlabs.ibm.com> Michael Ellerman writes: > David asked me to put power4_enable_pmcs() in arch/ppc64/kernel/pmc.c, so > here's an updated (again) version. > Index: work/arch/ppc64/kernel/pmac_setup.c > =================================================================== > --- work.orig/arch/ppc64/kernel/pmac_setup.c > +++ work/arch/ppc64/kernel/pmac_setup.c > @@ -71,6 +71,7 @@ > #include > #include > #include > +#include > > #include "pmac.h" > #include "mpic.h" > @@ -511,4 +512,5 @@ struct machdep_calls __initdata pmac_md > .progress = pmac_progress, > .check_legacy_ioport = pmac_check_legacy_ioport, > .idle_loop = native_idle, > + .enable_pmcs = power4_enable_cpus, That should be power4_enable_pmcs... Regards, Paul. From benh at kernel.crashing.org Tue Aug 9 18:31:13 2005 From: benh at kernel.crashing.org (Benjamin Herrenschmidt) Date: Tue, 09 Aug 2005 10:31:13 +0200 Subject: [RFC] addnote and pmac In-Reply-To: <42F7A418.2050601@am.sony.com> References: <42F7A418.2050601@am.sony.com> Message-ID: <1123576274.30257.152.camel@gaston> On Mon, 2005-08-08 at 11:27 -0700, Geoff Levand wrote: > I found that my Mac G5 wouldn't boot with a zImage modified by > addnote. It worked OK when the image wasn't run through addnote > though. I took just a brief look at addnote.c, and it seems this > step is specific to the OF implementation, or could it be needed > by older tool chains? > > At any rate, by default it is run for all zImage builds, which > we'll need to change to support at least some machines. Below is > what I got working, but someone more familiar with the boot > makefile and the needs of other machines could certainly do > better. The problem is that your G5 does understand the added Note header but doesn't like it's content. IBM Open Firmware only works properly in real mode, while Apple's only works properly in virtual mode. The Note header is set to real mode, thus causing Apple's OF to do a double-reboot into a mode where it craps itself. There is no way unfortunately to "fix" that other than generating two zImages, or better, having the distro add the Note section for IBM machines at zImage install time. Note that your patch is wrong, as this has nothing to do with iSeries, but it's a pSeries issue. But since you can built kernels images that can be booted on both a G5 and a pSeries, using a CONFIG_ option for that isn't a good solution anyway. Ben. From paulus at samba.org Tue Aug 9 21:48:59 2005 From: paulus at samba.org (Paul Mackerras) Date: Tue, 9 Aug 2005 21:48:59 +1000 Subject: queue of patches to go upstream post 2.6.13 Message-ID: <17144.38955.181595.734665@cargo.ozlabs.ibm.com> I have queued up 35 patches to go to Linus once 2.6.13 is out and checked them into a git repository. If you are interested to see what is pending, you can pull from rsync://ozlabs.org/kernel/ppc64-2.6.git Note that that repository only contains the objects that don't appear in Linus' linux-2.6 tree. If you make a clone of a linux-2.6 git repository and then do a git pull like this: git pull rsync://ozlabs.org/kernel/ppc64-2.6.git you should get everything. If anyone has any other ppc64 patches which they would like to go upstream post 2.6.13, let me know. Paul. From boutcher at us.ibm.com Tue Aug 9 22:04:19 2005 From: boutcher at us.ibm.com (David Boutcher) Date: Tue, 9 Aug 2005 07:04:19 -0500 Subject: [PATCH 1/8] Remove NACA fixed address constraint In-Reply-To: <1123569762.4000.14.camel@localhost.localdomain> Message-ID: Jeff Scheel wrote on 08/09/2005 01:42:42 AM: > On Mon, 2005-08-01 at 05:53, David Gibson wrote: > > Comments in head.S suggest that the iSeries naca has a fixed address, > > because tools expect to find it there. The only tool which appears to > > access the naca is addRamDisk, but both the in-kernel version and the > > version used in RHEL and SuSE in fact locate the NACA the same way as > > the hypervisor does, by following the pointer in the hvReleaseData > > structure. > > > > Since the requirement for a fixed address seems to be obsolete, this > > patch removes the naca from head.S and replaces it with a normal C > > initializer. > There are IBM internal debug tools built into the iSeries which depend > on this address. Removing it will break them. > > You should really get input from Mike Ranweiler as to the impact of this > change. Dave Boutcher might also have insight. > -Jeff I was asked before this patch was sent.. No one that I am aware of has used these tools in a couple of years. Dave Boutcher IBM Linux Technology Center -------------- next part -------------- An HTML attachment was scrubbed... URL: http://ozlabs.org/pipermail/linuxppc64-dev/attachments/20050809/fbcac632/attachment.htm From scheel at vnet.ibm.com Tue Aug 9 16:42:42 2005 From: scheel at vnet.ibm.com (Jeff Scheel) Date: Tue, 09 Aug 2005 06:42:42 +0000 Subject: [PATCH 1/8] Remove NACA fixed address constraint In-Reply-To: <20050801055351.E164D67E06@ozlabs.org> References: <20050801055351.E164D67E06@ozlabs.org> Message-ID: <1123569762.4000.14.camel@localhost.localdomain> On Mon, 2005-08-01 at 05:53, David Gibson wrote: > Comments in head.S suggest that the iSeries naca has a fixed address, > because tools expect to find it there. The only tool which appears to > access the naca is addRamDisk, but both the in-kernel version and the > version used in RHEL and SuSE in fact locate the NACA the same way as > the hypervisor does, by following the pointer in the hvReleaseData > structure. > > Since the requirement for a fixed address seems to be obsolete, this > patch removes the naca from head.S and replaces it with a normal C > initializer. There are IBM internal debug tools built into the iSeries which depend on this address. Removing it will break them. You should really get input from Mike Ranweiler as to the impact of this change. Dave Boutcher might also have insight. -Jeff From hch at lst.de Tue Aug 9 22:33:47 2005 From: hch at lst.de (Christoph Hellwig) Date: Tue, 9 Aug 2005 14:33:47 +0200 Subject: [PATCH 1/8] Remove NACA fixed address constraint In-Reply-To: <1123569762.4000.14.camel@localhost.localdomain> References: <20050801055351.E164D67E06@ozlabs.org> <1123569762.4000.14.camel@localhost.localdomain> Message-ID: <20050809123347.GA20902@lst.de> On Tue, Aug 09, 2005 at 06:42:42AM +0000, Jeff Scheel wrote: > On Mon, 2005-08-01 at 05:53, David Gibson wrote: > > Comments in head.S suggest that the iSeries naca has a fixed address, > > because tools expect to find it there. The only tool which appears to > > access the naca is addRamDisk, but both the in-kernel version and the > > version used in RHEL and SuSE in fact locate the NACA the same way as > > the hypervisor does, by following the pointer in the hvReleaseData > > structure. > > > > Since the requirement for a fixed address seems to be obsolete, this > > patch removes the naca from head.S and replaces it with a normal C > > initializer. > There are IBM internal debug tools built into the iSeries which depend > on this address. Removing it will break them. Bad luch. opensource the tools and they can be fixed. Reliance on binry only internal to some company tools must not hold kernel development back. From segher at kernel.crashing.org Tue Aug 9 23:07:00 2005 From: segher at kernel.crashing.org (Segher Boessenkool) Date: Tue, 9 Aug 2005 15:07:00 +0200 Subject: server_mode on Newer Powermac 1.8 (single) In-Reply-To: <42F7E129.6010105@cisco.com> References: <42F7E129.6010105@cisco.com> Message-ID: > If I put OSX on this thing and set it via that GUI will the setting > stick? Yes. If all is right, of course, like, Linux doesn't turn it off for you or something similar ;-) Segher From segher at kernel.crashing.org Tue Aug 9 23:09:02 2005 From: segher at kernel.crashing.org (Segher Boessenkool) Date: Tue, 9 Aug 2005 15:09:02 +0200 Subject: Merging ppc32 and ppc64 In-Reply-To: <42F79D89.3040709@austin.ibm.com> References: <17136.13558.773102.465379@cargo.ozlabs.ibm.com> <42F79D89.3040709@austin.ibm.com> Message-ID: >> I don't see the merge as changing the actual code that gets executed >> on any given platform very much, except in one respect: we are going >> to standardize on a flattened device tree as the way that information >> about the platform gets passed from the boot loader to the kernel. >> Comments? Flames? :) > > There are several userspace applications that parse the non-flat > device tree in /proc/device-tree on pSeries. While I like the idea of > the flattened device tree I think we need to consider how many apps we > are going to break with it. _Please_ don't throw the real device tree away; I'm happy with the flattened device tree if and only if it is a _minimum_ requirement, and having a _real_ device tree (or even real Open Firmware support) is still an option. Segher From segher at kernel.crashing.org Tue Aug 9 23:30:42 2005 From: segher at kernel.crashing.org (Segher Boessenkool) Date: Tue, 9 Aug 2005 15:30:42 +0200 Subject: Merging ppc32 and ppc64 In-Reply-To: References: <17136.13558.773102.465379@cargo.ozlabs.ibm.com> <42F79D89.3040709@austin.ibm.com> Message-ID: >>>> I don't see the merge as changing the actual code that gets executed >>>> on any given platform very much, except in one respect: we are going >>>> to standardize on a flattened device tree as the way that >>>> information >>>> about the platform gets passed from the boot loader to the kernel. > > ^^^^^^^^^^^^^^^^^^^^^***********^^^^^^^^******^ Yes, and that is exactly what I do not want. We are not going to require OF implementations that do not need yaboot or similar to pass a flattened device tree to the kernel, eh? Also, there is no reason why something like yaboot (with an OF still running underneath) should have to care about anything device-tree related at all; the OS can just as easily ask the OF itself. Segher From geert at linux-m68k.org Tue Aug 9 23:11:09 2005 From: geert at linux-m68k.org (Geert Uytterhoeven) Date: Tue, 9 Aug 2005 15:11:09 +0200 (CEST) Subject: Merging ppc32 and ppc64 In-Reply-To: References: <17136.13558.773102.465379@cargo.ozlabs.ibm.com> <42F79D89.3040709@austin.ibm.com> Message-ID: On Tue, 9 Aug 2005, Segher Boessenkool wrote: > > > I don't see the merge as changing the actual code that gets executed > > > on any given platform very much, except in one respect: we are going > > > to standardize on a flattened device tree as the way that information > > > about the platform gets passed from the boot loader to the kernel. ^^^^^^^^^^^^^^^^^^^^^***********^^^^^^^^******^ > > > Comments? Flames? :) > > > > There are several userspace applications that parse the non-flat device tree > > in /proc/device-tree on pSeries. While I like the idea of the flattened > > device tree I think we need to consider how many apps we are going to break > > with it. > > _Please_ don't throw the real device tree away; I'm happy with > the flattened device tree if and only if it is a _minimum_ > requirement, and having a _real_ device tree (or even real > Open Firmware support) is still an option. Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds From kumar.gala at freescale.com Wed Aug 10 00:12:20 2005 From: kumar.gala at freescale.com (Kumar Gala) Date: Tue, 9 Aug 2005 09:12:20 -0500 Subject: Merging ppc32 and ppc64 In-Reply-To: References: Message-ID: <3F1564F6-3732-403B-BA6B-BFAB28568AEE@freescale.com> On Aug 9, 2005, at 8:30 AM, Segher Boessenkool wrote: >>>>> I don't see the merge as changing the actual code that gets >>>>> > executed > >>>>> on any given platform very much, except in one respect: we are >>>>> > going > >>>>> to standardize on a flattened device tree as the way that >>>>> information >>>>> about the platform gets passed from the boot loader to the kernel. >>>>> >> >> ^^^^^^^^^^^^^^^^^^^^^***********^^^^^^^^******^ >> > > Yes, and that is exactly what I do not want. We are not going > to require OF implementations that do not need yaboot or similar > to pass a flattened device tree to the kernel, eh? Also, there > is no reason why something like yaboot (with an OF still running > underneath) should have to care about anything device-tree related > at all; the OS can just as easily ask the OF itself. I was under the impression that ALL platforms regardless if the had a OF firmware or not would be using a flattened device tree. Any conversion between an OF tree to a flatten tree would end up happening in boot wrapper code going forward. - kumar From benh at kernel.crashing.org Wed Aug 10 00:38:42 2005 From: benh at kernel.crashing.org (Benjamin Herrenschmidt) Date: Tue, 09 Aug 2005 16:38:42 +0200 Subject: queue of patches to go upstream post 2.6.13 In-Reply-To: <17144.38955.181595.734665@cargo.ozlabs.ibm.com> References: <17144.38955.181595.734665@cargo.ozlabs.ibm.com> Message-ID: <1123598323.30257.206.camel@gaston> On Tue, 2005-08-09 at 21:48 +1000, Paul Mackerras wrote: > I have queued up 35 patches to go to Linus once 2.6.13 is out and > checked them into a git repository. If you are interested to see what > is pending, you can pull from > > rsync://ozlabs.org/kernel/ppc64-2.6.git Could we setup gitweb there too ? :) Ben. From benh at kernel.crashing.org Wed Aug 10 00:40:16 2005 From: benh at kernel.crashing.org (Benjamin Herrenschmidt) Date: Tue, 09 Aug 2005 16:40:16 +0200 Subject: server_mode on Newer Powermac 1.8 (single) In-Reply-To: <42F7E129.6010105@cisco.com> References: <42F7E129.6010105@cisco.com> Message-ID: <1123598417.30257.208.camel@gaston> On Mon, 2005-08-08 at 18:48 -0400, Keith Mitchell wrote: > I have about a dozen of the newer Powermac G5 1.8ghz (single) that has > the SMU (not the PMU) and I was wondering if it is currently possible to > get these things to automatically turn back on in the powerfail > scenario. We also have some Dual 2ghz machines that we can set > 'server_mode' to 1 in the /proc/pmu/options file but nothing similar > seems to exist for these machines. > > If I put OSX on this thing and set it via that GUI will the setting > stick? I thought I had done that initially but I now have some of the > machines that will power back up and some that will not... but I don't > remember if I powered down after doing that setting before installing > linux or not. I haven't yet done something for that. When I find some time, I'll finish my new SMU driver and see if I can figure out how to control the server mode ... Ben. From olof at lixom.net Wed Aug 10 00:52:59 2005 From: olof at lixom.net (Olof Johansson) Date: Tue, 9 Aug 2005 09:52:59 -0500 Subject: Merging ppc32 and ppc64 In-Reply-To: References: <17136.13558.773102.465379@cargo.ozlabs.ibm.com> <42F79D89.3040709@austin.ibm.com> Message-ID: <20050809145259.GH7163@austin.ibm.com> On Tue, Aug 09, 2005 at 03:09:02PM +0200, Segher Boessenkool wrote: > _Please_ don't throw the real device tree away; I'm happy with > the flattened device tree if and only if it is a _minimum_ > requirement, and having a _real_ device tree (or even real > Open Firmware support) is still an option. We already do that. prom_init.c will walk the OF device tree and build a flattened one before booting the kernel. -Olof From arnd at arndb.de Wed Aug 10 00:47:32 2005 From: arnd at arndb.de (Arnd Bergmann) Date: Tue, 9 Aug 2005 16:47:32 +0200 Subject: Merging ppc32 and ppc64 In-Reply-To: <3F1564F6-3732-403B-BA6B-BFAB28568AEE@freescale.com> References: <3F1564F6-3732-403B-BA6B-BFAB28568AEE@freescale.com> Message-ID: <200508091647.32925.arnd@arndb.de> On Dinsdag 09 August 2005 16:12, Kumar Gala wrote: > > Yes, and that is exactly what I do not want. ?We are not going > > to require OF implementations that do not need yaboot or similar > > to pass a flattened device tree to the kernel, eh? ?Also, there > > is no reason why something like yaboot (with an OF still running > > underneath) should have to care about anything device-tree related > > at all; the OS can just as easily ask the OF itself. > > I was under the impression that ALL platforms regardless if the had a ? > OF firmware or not would be using a flattened device tree. ?Any ? > conversion between an OF tree to a flatten tree would end up ? > happening in boot wrapper code going forward. I think you are both right, just using different terminology. The running kernel uses its own representation of the device tree, which is neither the flattened stuff nor using the OF interfaces. The conversion from OF to the flattened tree is done by the kernel itself. Apple OF \ SLOF \ pSeries |-1- prom_init------, PIBS / \ ... / \ \ other -----------------------------2--unflatten_device_tree--3-- boot loader / / iSeries ----------- early_setup---` All "regular" machines enter in the traditional prom_init path (1) from Open Firmware. The embedded machines that are too memory constraint to use SLOF have a flattened device tree in their boot loader and the legacy iSeries boxes can fake the device tree in their iSeries_early_setup function. The main entry point (2) is entered by all machines when the flattened device tree is there and the kernel builds its tree representation for run time (3). Arnd <>< From kumar.gala at freescale.com Wed Aug 10 01:01:05 2005 From: kumar.gala at freescale.com (Kumar Gala) Date: Tue, 9 Aug 2005 10:01:05 -0500 Subject: Merging ppc32 and ppc64 In-Reply-To: <200508091647.32925.arnd@arndb.de> References: <200508091647.32925.arnd@arndb.de> Message-ID: <80BD2461-35F1-4B9D-983E-E2BCFFC08C77@freescale.com> > I think you are both right, just using different terminology. The > running kernel uses its own representation of the device tree, which > is neither the flattened stuff nor using the OF interfaces. The > conversion from OF to the flattened tree is done by the kernel itself. > > Apple OF \ > SLOF \ > pSeries |-1- prom_init------, > PIBS / \ > ... / \ > \ > other -----------------------------2-- > unflatten_device_tree--3-- > boot loader / > / > iSeries ----------- early_setup---` > > All "regular" machines enter in the traditional prom_init path (1) > from Open Firmware. The embedded machines that are too memory > constraint > to use SLOF have a flattened device tree in their boot loader and the > legacy iSeries boxes can fake the device tree in their > iSeries_early_setup > function. The main entry point (2) is entered by all machines when the > flattened device tree is there and the kernel builds its tree > representation > for run time (3). I guess my point is that in the "new" powerpc arch doing steps 1 & 3 should no longer be part of the kernel proper. The should be handled by boot wrappers of some form. I know Ben tool care to ensure that prom_init was isolated from kernel proper and I'm suggesting we move it into a boot wrapper going forward. - kumar From segher at kernel.crashing.org Wed Aug 10 01:16:05 2005 From: segher at kernel.crashing.org (Segher Boessenkool) Date: Tue, 9 Aug 2005 17:16:05 +0200 Subject: Merging ppc32 and ppc64 In-Reply-To: <3F1564F6-3732-403B-BA6B-BFAB28568AEE@freescale.com> References: <3F1564F6-3732-403B-BA6B-BFAB28568AEE@freescale.com> Message-ID: <265a318e3c20a3ba217e374d12a8f9f6@kernel.crashing.org> > I was under the impression that ALL platforms regardless if the had a > OF firmware or not would be using a flattened device tree. Any > conversion between an OF tree to a flatten tree would end up happening > in boot wrapper code going forward. Ah OK -- so part of the problem is indeed terminology confusion. I view the "boot wrapper code" (prom_init.c) as being part of the kernel. Another thing is that I do not want prom_init to kill OF at all, which means you cannot have a static device tree. But that is another fight ;-) Segher From will_schmidt at vnet.ibm.com Wed Aug 10 02:33:35 2005 From: will_schmidt at vnet.ibm.com (will schmidt) Date: Tue, 09 Aug 2005 11:33:35 -0500 Subject: [PATCH 1/8] Remove NACA fixed address constraint In-Reply-To: <200508091204.j79C4ZSg020113@d01av01.pok.ibm.com> References: <200508091204.j79C4ZSg020113@d01av01.pok.ibm.com> Message-ID: <42F8DADF.7080908@vnet.ibm.com> David Boutcher wrote: > Jeff Scheel wrote on 08/09/2005 01:42:42 AM: > >>On Mon, 2005-08-01 at 05:53, David Gibson wrote: >> >>>Comments in head.S suggest that the iSeries naca has a fixed address, >>>because tools expect to find it there. The only tool which appears to >>>access the naca is addRamDisk, but both the in-kernel version and the >>>version used in RHEL and SuSE in fact locate the NACA the same way as >>>the hypervisor does, by following the pointer in the hvReleaseData >>>structure. >>> >>>Since the requirement for a fixed address seems to be obsolete, this >>>patch removes the naca from head.S and replaces it with a normal C >>>initializer. >> >>There are IBM internal debug tools built into the iSeries which depend >>on this address. Removing it will break them. >> >>You should really get input from Mike Ranweiler as to the impact of this >>change. Dave Boutcher might also have insight. >>-Jeff > > > I was asked before this patch was sent.. No one that I am aware of > has used these tools in a couple of years. > A few of us folks down the hall from you have been using these tools a fair amount recently. Not clear to me how significant the breakage is,.. but being an internal tool, that discussion belongs elsewhere. Christoph Hellwig wrote: > Bad luch. opensource the tools and they can be fixed. Reliance on > binry only internal to some company tools must not hold kernel > development back. Yes, you are right. I cant argue against this point. -Will From trini at kernel.crashing.org Wed Aug 10 02:21:33 2005 From: trini at kernel.crashing.org (Tom Rini) Date: Tue, 9 Aug 2005 09:21:33 -0700 Subject: Merging ppc32 and ppc64 In-Reply-To: <80BD2461-35F1-4B9D-983E-E2BCFFC08C77@freescale.com> References: <200508091647.32925.arnd@arndb.de> <80BD2461-35F1-4B9D-983E-E2BCFFC08C77@freescale.com> Message-ID: <20050809162133.GL3187@smtp.west.cox.net> On Tue, Aug 09, 2005 at 10:01:05AM -0500, Kumar Gala wrote: > >I think you are both right, just using different terminology. The > >running kernel uses its own representation of the device tree, which > >is neither the flattened stuff nor using the OF interfaces. The > >conversion from OF to the flattened tree is done by the kernel itself. > > > > Apple OF \ > > SLOF \ > > pSeries |-1- prom_init------, > > PIBS / \ > > ... / \ > > \ > > other -----------------------------2-- > >unflatten_device_tree--3-- > > boot loader / > > / > > iSeries ----------- early_setup---` > > > >All "regular" machines enter in the traditional prom_init path (1) > >from Open Firmware. The embedded machines that are too memory > >constraint > >to use SLOF have a flattened device tree in their boot loader and the > >legacy iSeries boxes can fake the device tree in their > >iSeries_early_setup > >function. The main entry point (2) is entered by all machines when the > >flattened device tree is there and the kernel builds its tree > >representation > >for run time (3). > > I guess my point is that in the "new" powerpc arch doing steps 1 & 3 > should no longer be part of the kernel proper. The should be handled > by boot wrappers of some form. I know Ben tool care to ensure that > prom_init was isolated from kernel proper and I'm suggesting we move > it into a boot wrapper going forward. That's not 100% true because as Segher said, prom_init.c is part of the kernel (tree, image), but is what does the translation. -- Tom Rini http://gate.crashing.org/~trini/ From kumar.gala at freescale.com Wed Aug 10 03:41:54 2005 From: kumar.gala at freescale.com (Kumar Gala) Date: Tue, 9 Aug 2005 12:41:54 -0500 Subject: Merging ppc32 and ppc64 In-Reply-To: <20050809162133.GL3187@smtp.west.cox.net> References: <20050809162133.GL3187@smtp.west.cox.net> Message-ID: On Aug 9, 2005, at 11:21 AM, Tom Rini wrote: > On Tue, Aug 09, 2005 at 10:01:05AM -0500, Kumar Gala wrote: > >>> I think you are both right, just using different terminology. The >>> running kernel uses its own representation of the device tree, which >>> is neither the flattened stuff nor using the OF interfaces. The >>> conversion from OF to the flattened tree is done by the kernel >>> > itself. > >>> >>> Apple OF \ >>> SLOF \ >>> pSeries |-1- prom_init------, >>> PIBS / \ >>> ... / \ >>> \ >>> other -----------------------------2-- >>> unflatten_device_tree--3-- >>> boot loader / >>> / >>> iSeries ----------- early_setup---` >>> >>> All "regular" machines enter in the traditional prom_init path (1) >>> from Open Firmware. The embedded machines that are too memory >>> constraint >>> to use SLOF have a flattened device tree in their boot loader and >>> the >>> legacy iSeries boxes can fake the device tree in their >>> iSeries_early_setup >>> function. The main entry point (2) is entered by all machines when >>> > the > >>> flattened device tree is there and the kernel builds its tree >>> representation >>> for run time (3). >>> >> >> I guess my point is that in the "new" powerpc arch doing steps 1 & 3 >> should no longer be part of the kernel proper. The should be handled >> > > >> by boot wrappers of some form. I know Ben tool care to ensure that >> prom_init was isolated from kernel proper and I'm suggesting we move >> it into a boot wrapper going forward. >> > > That's not 100% true because as Segher said, prom_init.c is part of > the > kernel (tree, image), but is what does the translation. I'm not sure I follow. I understand that prom_init.c is part of the kernel in ppc64. I'm saying that such things should NOT be part of the arch/powerpc kernel going forward. They should be handled via bootwrappers. - kumar From trini at kernel.crashing.org Wed Aug 10 03:47:17 2005 From: trini at kernel.crashing.org (Tom Rini) Date: Tue, 9 Aug 2005 10:47:17 -0700 Subject: Merging ppc32 and ppc64 In-Reply-To: References: <20050809162133.GL3187@smtp.west.cox.net> Message-ID: <20050809174717.GO3187@smtp.west.cox.net> On Tue, Aug 09, 2005 at 12:41:54PM -0500, Kumar Gala wrote: > > On Aug 9, 2005, at 11:21 AM, Tom Rini wrote: [snip] > >That's not 100% true because as Segher said, prom_init.c is part of > >the > >kernel (tree, image), but is what does the translation. > > I'm not sure I follow. I understand that prom_init.c is part of the > kernel in ppc64. I'm saying that such things should NOT be part of > the arch/powerpc kernel going forward. They should be handled via > bootwrappers. That's a "cleanup" we can argue about later, but I expect some resistance :) -- Tom Rini http://gate.crashing.org/~trini/ From kumar.gala at freescale.com Wed Aug 10 04:49:41 2005 From: kumar.gala at freescale.com (Kumar Gala) Date: Tue, 9 Aug 2005 13:49:41 -0500 Subject: Merging ppc32 and ppc64 In-Reply-To: <20050809174717.GO3187@smtp.west.cox.net> References: <20050809174717.GO3187@smtp.west.cox.net> Message-ID: <4D608D36-754B-46EA-9546-304AEFFB3F3A@freescale.com> On Aug 9, 2005, at 12:47 PM, Tom Rini wrote: > On Tue, Aug 09, 2005 at 12:41:54PM -0500, Kumar Gala wrote: > >> >> On Aug 9, 2005, at 11:21 AM, Tom Rini wrote: >> > [snip] > >>> That's not 100% true because as Segher said, prom_init.c is part of >>> the >>> kernel (tree, image), but is what does the translation. >>> >> >> I'm not sure I follow. I understand that prom_init.c is part of the >> kernel in ppc64. I'm saying that such things should NOT be part of >> the arch/powerpc kernel going forward. They should be handled via >> bootwrappers. >> > > That's a "cleanup" we can argue about later, but I expect some > resistance :) Why argue later? Isn't part of the point of the merge to do cleanup between ppc32 & ppc64. When would be the point to discuss this? - kumar From olof at lixom.net Wed Aug 10 06:22:45 2005 From: olof at lixom.net (Olof Johansson) Date: Tue, 9 Aug 2005 15:22:45 -0500 Subject: [PATCH] [2/4] PPC64: Remove TCE/DART dependency on 4K PAGE_SIZE In-Reply-To: <20050809202007.GA30589@austin.ibm.com> References: <20050809202007.GA30589@austin.ibm.com> Message-ID: <20050809202245.GC30589@austin.ibm.com> There are potential cases in the future where the IOMMU might be mapping smaller pages than the regular MMU is using. Keep the allocator working on MMU pagesizes, but the low-level mapping functions need to map more than one TCE entry per page to deal with this. Signed-off-by: Olof Johansson Index: gr_work/arch/ppc64/kernel/pSeries_iommu.c =================================================================== --- gr_work.orig/arch/ppc64/kernel/pSeries_iommu.c 2005-08-08 11:09:02.977599596 -0500 +++ gr_work/arch/ppc64/kernel/pSeries_iommu.c 2005-08-08 11:09:21.485465685 -0500 @@ -59,6 +59,9 @@ static void tce_build_pSeries(struct iom union tce_entry t; union tce_entry *tp; + index <<= TCE_PAGE_FACTOR; + npages <<= TCE_PAGE_FACTOR; + t.te_word = 0; t.te_rdwr = 1; // Read allowed @@ -69,11 +72,11 @@ static void tce_build_pSeries(struct iom while (npages--) { /* can't move this out since we might cross LMB boundary */ - t.te_rpn = (virt_to_abs(uaddr)) >> PAGE_SHIFT; + t.te_rpn = (virt_to_abs(uaddr)) >> TCE_SHIFT; tp->te_word = t.te_word; - uaddr += PAGE_SIZE; + uaddr += TCE_PAGE_SIZE; tp++; } } @@ -84,6 +87,9 @@ static void tce_free_pSeries(struct iomm union tce_entry t; union tce_entry *tp; + npages <<= TCE_PAGE_FACTOR; + index <<= TCE_PAGE_FACTOR; + t.te_word = 0; tp = ((union tce_entry *)tbl->it_base) + index; @@ -103,7 +109,7 @@ static void tce_build_pSeriesLP(struct i union tce_entry tce; tce.te_word = 0; - tce.te_rpn = (virt_to_abs(uaddr)) >> PAGE_SHIFT; + tce.te_rpn = (virt_to_abs(uaddr)) >> TCE_SHIFT; tce.te_rdwr = 1; if (direction != DMA_TO_DEVICE) tce.te_pciwr = 1; @@ -136,6 +142,9 @@ static void tce_buildmulti_pSeriesLP(str union tce_entry tce, *tcep; long l, limit; + tcenum <<= TCE_PAGE_FACTOR; + npages <<= TCE_PAGE_FACTOR; + if (npages == 1) return tce_build_pSeriesLP(tbl, tcenum, npages, uaddr, direction); @@ -155,7 +164,7 @@ static void tce_buildmulti_pSeriesLP(str } tce.te_word = 0; - tce.te_rpn = (virt_to_abs(uaddr)) >> PAGE_SHIFT; + tce.te_rpn = (virt_to_abs(uaddr)) >> TCE_SHIFT; tce.te_rdwr = 1; if (direction != DMA_TO_DEVICE) tce.te_pciwr = 1; @@ -166,7 +175,7 @@ static void tce_buildmulti_pSeriesLP(str * Set up the page with TCE data, looping through and setting * the values. */ - limit = min_t(long, npages, PAGE_SIZE/sizeof(union tce_entry)); + limit = min_t(long, npages, 4096/sizeof(union tce_entry)); for (l = 0; l < limit; l++) { tcep[l] = tce; @@ -196,6 +205,9 @@ static void tce_free_pSeriesLP(struct io u64 rc; union tce_entry tce; + tcenum <<= TCE_PAGE_FACTOR; + npages <<= TCE_PAGE_FACTOR; + tce.te_word = 0; while (npages--) { @@ -221,6 +233,9 @@ static void tce_freemulti_pSeriesLP(stru u64 rc; union tce_entry tce; + tcenum <<= TCE_PAGE_FACTOR; + npages <<= TCE_PAGE_FACTOR; + tce.te_word = 0; rc = plpar_tce_stuff((u64)tbl->it_index, Index: gr_work/include/asm-ppc64/tce.h =================================================================== --- gr_work.orig/include/asm-ppc64/tce.h 2005-08-08 11:09:02.978599438 -0500 +++ gr_work/include/asm-ppc64/tce.h 2005-08-08 11:09:21.486465527 -0500 @@ -29,6 +29,13 @@ #define TCE_VB 0 #define TCE_PCI 1 +/* TCE page size is 4096 bytes (1 << 12) */ + +#define TCE_SHIFT 12 +#define TCE_PAGE_SIZE (1 << TCE_SHIFT) +#define TCE_PAGE_FACTOR (PAGE_SHIFT - TCE_SHIFT) + + /* tce_entry * Used by pSeries (SMP) and iSeries/pSeries LPAR, but there it's * abstracted so layout is irrelevant. Index: gr_work/arch/ppc64/kernel/u3_iommu.c =================================================================== --- gr_work.orig/arch/ppc64/kernel/u3_iommu.c 2005-08-08 11:09:02.977599596 -0500 +++ gr_work/arch/ppc64/kernel/u3_iommu.c 2005-08-08 11:09:21.488465210 -0500 @@ -125,18 +125,21 @@ static void dart_build(struct iommu_tabl DBG("dart: build at: %lx, %lx, addr: %x\n", index, npages, uaddr); + index <<= DART_PAGE_FACTOR; + npages <<= DART_PAGE_FACTOR; + dp = ((unsigned int*)tbl->it_base) + index; /* On U3, all memory is contigous, so we can move this * out of the loop. */ while (npages--) { - rpn = virt_to_abs(uaddr) >> PAGE_SHIFT; + rpn = virt_to_abs(uaddr) >> DART_PAGE_SHIFT; *(dp++) = DARTMAP_VALID | (rpn & DARTMAP_RPNMASK); rpn++; - uaddr += PAGE_SIZE; + uaddr += DART_PAGE_SIZE; } dart_dirty = 1; @@ -154,6 +157,9 @@ static void dart_free(struct iommu_table DBG("dart: free at: %lx, %lx\n", index, npages); + index <<= DART_PAGE_FACTOR; + npages <<= DART_PAGE_FACTOR; + dp = ((unsigned int *)tbl->it_base) + index; while (npages--) @@ -182,10 +188,10 @@ static int dart_init(struct device_node * that to work around what looks like a problem with the HT bridge * prefetching into invalid pages and corrupting data */ - tmp = lmb_alloc(PAGE_SIZE, PAGE_SIZE); + tmp = lmb_alloc(DART_PAGE_SIZE, DART_PAGE_SIZE); if (!tmp) panic("U3-DART: Cannot allocate spare page!"); - dart_emptyval = DARTMAP_VALID | ((tmp >> PAGE_SHIFT) & DARTMAP_RPNMASK); + dart_emptyval = DARTMAP_VALID | ((tmp >> DART_PAGE_SHIFT) & DARTMAP_RPNMASK); /* Map in DART registers. FIXME: Use device node to get base address */ dart = ioremap(DART_BASE, 0x7000); @@ -196,8 +202,8 @@ static int dart_init(struct device_node * table size and enable bit */ regword = DARTCNTL_ENABLE | - ((dart_tablebase >> PAGE_SHIFT) << DARTCNTL_BASE_SHIFT) | - (((dart_tablesize >> PAGE_SHIFT) & DARTCNTL_SIZE_MASK) + ((dart_tablebase >> DART_PAGE_SHIFT) << DARTCNTL_BASE_SHIFT) | + (((dart_tablesize >> DART_PAGE_SHIFT) & DARTCNTL_SIZE_MASK) << DARTCNTL_SIZE_SHIFT); dart_vbase = ioremap(virt_to_abs(dart_tablebase), dart_tablesize); Index: gr_work/include/asm-ppc64/dart.h =================================================================== --- gr_work.orig/include/asm-ppc64/dart.h 2005-08-08 11:09:02.978599438 -0500 +++ gr_work/include/asm-ppc64/dart.h 2005-08-08 11:09:21.489465051 -0500 @@ -52,5 +52,9 @@ #define DARTMAP_RPNMASK 0x00ffffff +#define DART_SHIFT 12 +#define DART_PAGE_SIZE (1 << DART_SHIFT) +#define DART_PAGE_FACTOR (PAGE_SHIFT - DART_SHIFT) + #endif From olof at lixom.net Wed Aug 10 06:23:30 2005 From: olof at lixom.net (Olof Johansson) Date: Tue, 9 Aug 2005 15:23:30 -0500 Subject: [PATCH] [3/4] PPC64: PAGE_SIZE constants in copyuser.S and copypage.S In-Reply-To: <20050809202007.GA30589@austin.ibm.com> References: <20050809202007.GA30589@austin.ibm.com> Message-ID: <20050809202329.GD30589@austin.ibm.com> Replace some of the hardcoded constants in copypage and copyuser to be based on PAGE_SIZE. Also change the assembly where needed to deal with larger values of PAGE_SIZE. Signed-off-by: Olof Johansson Index: gr_work/arch/ppc64/lib/copypage.S =================================================================== --- gr_work.orig/arch/ppc64/lib/copypage.S 2005-08-08 13:58:53.876635495 -0500 +++ gr_work/arch/ppc64/lib/copypage.S 2005-08-08 14:01:35.414604998 -0500 @@ -24,7 +24,7 @@ _GLOBAL(copy_page) std r22,-80(1) std r21,-88(1) std r20,-96(1) - li r5,4096/32 - 1 + li r5,PAGE_SIZE/32 - 1 addi r3,r3,-8 li r12,5 0: addi r5,r5,-24 Index: gr_work/arch/ppc64/lib/copyuser.S =================================================================== --- gr_work.orig/arch/ppc64/lib/copyuser.S 2005-08-08 13:58:53.877635336 -0500 +++ gr_work/arch/ppc64/lib/copyuser.S 2005-08-08 14:18:19.126545435 -0500 @@ -15,10 +15,16 @@ _GLOBAL(__copy_tofrom_user) /* first check for a whole page copy on a page boundary */ cmpldi cr1,r5,16 - cmpdi cr6,r5,4096 +#if PAGE_SIZE > 0x8000 + li r6,PAGE_SIZE at l + oris r6,r6,PAGE_SIZE at h + cmpd cr6,r5,r6 +#else + cmpdi cr6,r5,PAGE_SIZE +#endif or r0,r3,r4 neg r6,r3 /* LS 3 bits = # bytes to 8-byte dest bdry */ - andi. r0,r0,4095 + andi. r0,r0,PAGE_SIZE-1 std r3,-24(r1) crand cr0*4+2,cr0*4+2,cr6*4+2 std r4,-16(r1) @@ -379,7 +385,7 @@ _GLOBAL(__copy_tofrom_user) std r22,-104(1) std r21,-112(1) std r20,-120(1) - li r5,4096/32 - 1 + li r5,PAGE_SIZE/32 - 1 addi r3,r3,-8 li r0,5 0: addi r5,r5,-24 @@ -497,7 +503,10 @@ _GLOBAL(__copy_tofrom_user) ld r31,-32(1) ld r3,-24(r1) ld r4,-16(r1) - li r5,4096 + li r5,PAGE_SIZE at l +#if PAGE_SIZE > 0x8000 + oris r5,r5,PAGE_SIZE at h +#endif b .Ldst_aligned .section __ex_table,"a" From olof at lixom.net Wed Aug 10 06:20:07 2005 From: olof at lixom.net (Olof Johansson) Date: Tue, 9 Aug 2005 15:20:07 -0500 Subject: [PATCH] [0/4] PPC64: Cleanups to prepare for new page sizes Message-ID: <20050809202007.GA30589@austin.ibm.com> Hi, This is a short series of 4 patches to clean up and prepare PPC64 for a new base page size, for when the 2.6.14 tree opens: 1/4: Split off platform-specific contents from iommu.h. Creates tce.h and dart.h 2/4: Make TCE/DART code independent of system PAGE_SIZE. Depends on 1/4. 3/4: Fix loading of constants in copypage.S and copyuser.S. 4/4: Various conversations of hardcoded page-size related constants to use the defines instead. None of the patches should change any behaviour for the standard PAGE_SIZE. -Olof From olof at lixom.net Wed Aug 10 06:24:24 2005 From: olof at lixom.net (Olof Johansson) Date: Tue, 9 Aug 2005 15:24:24 -0500 Subject: [PATCH] [4/4] PPC64: Fix some page-size related hardcoded constants In-Reply-To: <20050809202007.GA30589@austin.ibm.com> References: <20050809202007.GA30589@austin.ibm.com> Message-ID: <20050809202424.GE30589@austin.ibm.com> Replace some of the hard-coded constants with PAGE_SIZE/SHIFT/ORDER where appropriate. Likewise, in a couple of places it doesn't make sense to base some allocations on page size when all that's required is a constant 4K, etc. Signed-off-by: Olof Johansson Index: gr_work/arch/ppc64/kernel/head.S =================================================================== --- gr_work.orig/arch/ppc64/kernel/head.S 2005-08-08 14:38:41.023520151 -0500 +++ gr_work/arch/ppc64/kernel/head.S 2005-08-08 14:52:21.688435819 -0500 @@ -714,7 +714,7 @@ machine_check_fwnmi: .globl __start_stab __start_stab: - . = (STAB0_PHYS_ADDR + PAGE_SIZE) + . = (STAB0_PHYS_ADDR + 4096) .globl __end_stab __end_stab: @@ -2102,16 +2102,16 @@ _GLOBAL(smp_release_cpus) * which is page-aligned. */ .data - .align 12 + .align PAGE_SHIFT .globl sdata sdata: .globl empty_zero_page empty_zero_page: - .space 4096 + .space PAGE_SIZE .globl swapper_pg_dir swapper_pg_dir: - .space 4096 + .space PAGE_SIZE /* * This space gets a copy of optional info passed to us by the bootstrap Index: gr_work/arch/ppc64/kernel/misc.S =================================================================== --- gr_work.orig/arch/ppc64/kernel/misc.S 2005-08-08 14:38:41.023520151 -0500 +++ gr_work/arch/ppc64/kernel/misc.S 2005-08-08 14:49:49.783114926 -0500 @@ -329,7 +329,7 @@ _GLOBAL(__flush_dcache_icache) /* Flush the dcache */ ld r7,PPC64_CACHES at toc(r2) - clrrdi r3,r3,12 /* Page align */ + clrrdi r3,r3,PAGE_SHIFT /* Page align */ lwz r4,DCACHEL1LINESPERPAGE(r7) /* Get # dcache lines per page */ lwz r5,DCACHEL1LINESIZE(r7) /* Get dcache line size */ mr r6,r3 Index: gr_work/arch/ppc64/kernel/vmlinux.lds.S =================================================================== --- gr_work.orig/arch/ppc64/kernel/vmlinux.lds.S 2005-08-08 14:38:41.024519995 -0500 +++ gr_work/arch/ppc64/kernel/vmlinux.lds.S 2005-08-08 14:49:49.784114770 -0500 @@ -1,3 +1,4 @@ +#include #include OUTPUT_ARCH(powerpc:common64) @@ -16,7 +17,7 @@ SECTIONS SCHED_TEXT LOCK_TEXT *(.fixup) - . = ALIGN(4096); + . = ALIGN(PAGE_SIZE); _etext = .; } @@ -42,7 +43,7 @@ SECTIONS /* will be freed after init */ - . = ALIGN(4096); + . = ALIGN(PAGE_SIZE); __init_begin = .; .init.text : { @@ -82,7 +83,7 @@ SECTIONS SECURITY_INIT - . = ALIGN(4096); + . = ALIGN(PAGE_SIZE); .init.ramfs : { __initramfs_start = .; *(.init.ramfs) @@ -95,13 +96,13 @@ SECTIONS __per_cpu_end = .; } - . = ALIGN(16384); + . = ALIGN(PAGE_SIZE); __init_end = .; /* freed after init ends here */ /* Read/write sections */ - . = ALIGN(16384); + . = ALIGN(PAGE_SIZE); /* The initial task and kernel stack */ .data.init_task : { *(.data.init_task) @@ -128,18 +129,18 @@ SECTIONS __toc_start = .; *(.got) *(.toc) - . = ALIGN(4096); + . = ALIGN(PAGE_SIZE); _edata = .; } - . = ALIGN(4096); + . = ALIGN(PAGE_SIZE); .bss : { __bss_start = .; *(.bss) __bss_stop = .; } - . = ALIGN(4096); + . = ALIGN(PAGE_SIZE); _end = . ; } Index: gr_work/include/asm-ppc64/elf.h =================================================================== --- gr_work.orig/include/asm-ppc64/elf.h 2005-08-08 14:38:41.030519059 -0500 +++ gr_work/include/asm-ppc64/elf.h 2005-08-08 14:49:49.786114457 -0500 @@ -4,6 +4,7 @@ #include #include #include +#include /* PowerPC relocations defined by the ABIs */ #define R_PPC_NONE 0 @@ -145,7 +146,7 @@ typedef elf_vrreg_t elf_vrregset_t32[ELF #define elf_check_arch(x) ((x)->e_machine == ELF_ARCH) #define USE_ELF_CORE_DUMP -#define ELF_EXEC_PAGESIZE 4096 +#define ELF_EXEC_PAGESIZE PAGE_SIZE /* This is the location that an ET_DYN program is loaded if exec'ed. Typical use of this is to invoke "./ld.so someprog" to test out a new version of Index: gr_work/include/asm-ppc64/thread_info.h =================================================================== --- gr_work.orig/include/asm-ppc64/thread_info.h 2005-08-08 14:38:41.031518903 -0500 +++ gr_work/include/asm-ppc64/thread_info.h 2005-08-08 14:51:38.917765995 -0500 @@ -54,9 +54,9 @@ struct thread_info { /* thread information allocation */ -#define THREAD_ORDER 2 -#define THREAD_SIZE (PAGE_SIZE << THREAD_ORDER) -#define THREAD_SHIFT (PAGE_SHIFT + THREAD_ORDER) +#define THREAD_SHIFT 14 +#define THREAD_ORDER (THREAD_SHIFT - PAGE_SHIFT) +#define THREAD_SIZE (1 << THREAD_SHIFT) #ifdef CONFIG_DEBUG_STACK_USAGE #define alloc_thread_info(tsk) \ ({ \ Index: gr_work/include/asm-ppc64/naca.h =================================================================== --- gr_work.orig/include/asm-ppc64/naca.h 2005-03-17 19:20:24.000000000 -0600 +++ gr_work/include/asm-ppc64/naca.h 2005-08-08 14:52:00.166650722 -0500 @@ -26,6 +26,6 @@ extern struct naca_struct naca; #endif /* __ASSEMBLY__ */ #define NACA_PAGE 0x4 -#define NACA_PHYS_ADDR (NACA_PAGE< References: <20050809202007.GA30589@austin.ibm.com> Message-ID: <20050809202118.GB30589@austin.ibm.com> Split out the implementation-specific parts of include/asm-ppc64/iommu.h to separate include files (tce.h and dart.h respectively). The generic iommu code really doesn't care about the underlying implementation, and the TCE and DART stuff is completely different. Signed-off-by: Olof Johansson Index: gr_work/include/asm-ppc64/dart.h =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ gr_work/include/asm-ppc64/dart.h 2005-08-08 10:54:26.517166287 -0500 @@ -0,0 +1,56 @@ +/* + * dart.h + * Copyright (C) 2004 Olof Johansson , IBM Corporation + * + * 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 + */ + +#ifndef _ASM_DART_H +#define _ASM_DART_H + + +/* physical base of DART registers */ +#define DART_BASE 0xf8033000UL + +/* Offset from base to control register */ +#define DARTCNTL 0 +/* Offset from base to exception register */ +#define DARTEXCP 0x10 +/* Offset from base to TLB tag registers */ +#define DARTTAG 0x1000 + + +/* Control Register fields */ + +/* base address of table (pfn) */ +#define DARTCNTL_BASE_MASK 0xfffff +#define DARTCNTL_BASE_SHIFT 12 + +#define DARTCNTL_FLUSHTLB 0x400 +#define DARTCNTL_ENABLE 0x200 + +/* size of table in pages */ +#define DARTCNTL_SIZE_MASK 0x1ff +#define DARTCNTL_SIZE_SHIFT 0 + + +/* DART table fields */ + +#define DARTMAP_VALID 0x80000000 +#define DARTMAP_RPNMASK 0x00ffffff + + + +#endif Index: gr_work/include/asm-ppc64/iommu.h =================================================================== --- gr_work.orig/include/asm-ppc64/iommu.h 2005-08-08 10:38:46.067231185 -0500 +++ gr_work/include/asm-ppc64/iommu.h 2005-08-08 10:54:26.516166446 -0500 @@ -29,44 +29,11 @@ /* * IOMAP_MAX_ORDER defines the largest contiguous block - * of dma (tce) space we can get. IOMAP_MAX_ORDER = 13 + * of dma space we can get. IOMAP_MAX_ORDER = 13 * allows up to 2**12 pages (4096 * 4096) = 16 MB */ #define IOMAP_MAX_ORDER 13 -/* - * Tces come in two formats, one for the virtual bus and a different - * format for PCI - */ -#define TCE_VB 0 -#define TCE_PCI 1 - -/* tce_entry - * Used by pSeries (SMP) and iSeries/pSeries LPAR, but there it's - * abstracted so layout is irrelevant. - */ -union tce_entry { - unsigned long te_word; - struct { - unsigned int tb_cacheBits :6; /* Cache hash bits - not used */ - unsigned int tb_rsvd :6; - unsigned long tb_rpn :40; /* Real page number */ - unsigned int tb_valid :1; /* Tce is valid (vb only) */ - unsigned int tb_allio :1; /* Tce is valid for all lps (vb only) */ - unsigned int tb_lpindex :8; /* LpIndex for user of TCE (vb only) */ - unsigned int tb_pciwr :1; /* Write allowed (pci only) */ - unsigned int tb_rdwr :1; /* Read allowed (pci), Write allowed (vb) */ - } te_bits; -#define te_cacheBits te_bits.tb_cacheBits -#define te_rpn te_bits.tb_rpn -#define te_valid te_bits.tb_valid -#define te_allio te_bits.tb_allio -#define te_lpindex te_bits.tb_lpindex -#define te_pciwr te_bits.tb_pciwr -#define te_rdwr te_bits.tb_rdwr -}; - - struct iommu_table { unsigned long it_busno; /* Bus number this table belongs to */ unsigned long it_size; /* Size of iommu table in entries */ Index: gr_work/include/asm-ppc64/tce.h =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ gr_work/include/asm-ppc64/tce.h 2005-08-08 10:54:26.517166287 -0500 @@ -0,0 +1,58 @@ +/* + * tce.h + * Copyright (C) 2001 Mike Corrigan & Dave Engebretsen, IBM Corporation + * Rewrite, cleanup: + * Copyright (C) 2004 Olof Johansson , IBM Corporation + * + * 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 + */ + +#ifndef _ASM_TCE_H +#define _ASM_TCE_H + +/* + * Tces come in two formats, one for the virtual bus and a different + * format for PCI + */ +#define TCE_VB 0 +#define TCE_PCI 1 + +/* tce_entry + * Used by pSeries (SMP) and iSeries/pSeries LPAR, but there it's + * abstracted so layout is irrelevant. + */ +union tce_entry { + unsigned long te_word; + struct { + unsigned int tb_cacheBits :6; /* Cache hash bits - not used */ + unsigned int tb_rsvd :6; + unsigned long tb_rpn :40; /* Real page number */ + unsigned int tb_valid :1; /* Tce is valid (vb only) */ + unsigned int tb_allio :1; /* Tce is valid for all lps (vb only) */ + unsigned int tb_lpindex :8; /* LpIndex for user of TCE (vb only) */ + unsigned int tb_pciwr :1; /* Write allowed (pci only) */ + unsigned int tb_rdwr :1; /* Read allowed (pci), Write allowed (vb) */ + } te_bits; +#define te_cacheBits te_bits.tb_cacheBits +#define te_rpn te_bits.tb_rpn +#define te_valid te_bits.tb_valid +#define te_allio te_bits.tb_allio +#define te_lpindex te_bits.tb_lpindex +#define te_pciwr te_bits.tb_pciwr +#define te_rdwr te_bits.tb_rdwr +}; + + +#endif Index: gr_work/arch/ppc64/kernel/u3_iommu.c =================================================================== --- gr_work.orig/arch/ppc64/kernel/u3_iommu.c 2005-08-08 10:45:38.886569179 -0500 +++ gr_work/arch/ppc64/kernel/u3_iommu.c 2005-08-08 10:55:48.682666607 -0500 @@ -44,39 +44,12 @@ #include #include #include +#include #include "pci.h" extern int iommu_force_on; -/* physical base of DART registers */ -#define DART_BASE 0xf8033000UL - -/* Offset from base to control register */ -#define DARTCNTL 0 -/* Offset from base to exception register */ -#define DARTEXCP 0x10 -/* Offset from base to TLB tag registers */ -#define DARTTAG 0x1000 - - -/* Control Register fields */ - -/* base address of table (pfn) */ -#define DARTCNTL_BASE_MASK 0xfffff -#define DARTCNTL_BASE_SHIFT 12 - -#define DARTCNTL_FLUSHTLB 0x400 -#define DARTCNTL_ENABLE 0x200 - -/* size of table in pages */ -#define DARTCNTL_SIZE_MASK 0x1ff -#define DARTCNTL_SIZE_SHIFT 0 - -/* DART table fields */ -#define DARTMAP_VALID 0x80000000 -#define DARTMAP_RPNMASK 0x00ffffff - /* Physical base address and size of the DART table */ unsigned long dart_tablebase; /* exported to htab_initialize */ static unsigned long dart_tablesize; Index: gr_work/arch/ppc64/kernel/pSeries_iommu.c =================================================================== --- gr_work.orig/arch/ppc64/kernel/pSeries_iommu.c 2005-08-08 10:54:26.514166763 -0500 +++ gr_work/arch/ppc64/kernel/pSeries_iommu.c 2005-08-08 10:55:59.069619425 -0500 @@ -45,6 +45,7 @@ #include #include #include +#include #include "pci.h" #define DBG(fmt...) Index: gr_work/arch/ppc64/kernel/vio.c =================================================================== --- gr_work.orig/arch/ppc64/kernel/vio.c 2005-08-05 17:55:40.000000000 -0500 +++ gr_work/arch/ppc64/kernel/vio.c 2005-08-08 10:56:36.197329571 -0500 @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include From kamitch at cisco.com Wed Aug 10 06:40:23 2005 From: kamitch at cisco.com (Keith Mitchell) Date: Tue, 09 Aug 2005 16:40:23 -0400 Subject: New Dual 2ghz Powermac G5 Message-ID: <42F914B7.8010208@cisco.com> I just got in a bunch of new Dual 2.0ghz Powermacs and one out of the bunch so far has a noisy fan problem. I have been loading YDL 4.0.91 which has kernel 2.6.12 plus some patches and I did go back and verify that it had the last patch I saw related to this (http://patchwork.ozlabs.org/linuxppc64/patch?id=846). All of the machines all identify themselves as running OpenFirmware 5.2.4f1 and all came in at once with the same config. The machine with the problem so far issues the following messages: kernel: /u3 at 0,f8000000/i2c at f8001000: Missing interrupt or address ! kernel: /u3 at 0,f8000000/i2c at f8001000: Missing interrupt or address ! kernel: /u3 at 0,f8000000/i2c at f8001000: Missing interrupt or address ! kernel: /u3 at 0,f8000000/i2c at f8001000: Missing interrupt or address ! Is this a known issue? Thanks. From geoffrey.levand at am.sony.com Wed Aug 10 07:05:58 2005 From: geoffrey.levand at am.sony.com (Geoff Levand) Date: Tue, 09 Aug 2005 14:05:58 -0700 Subject: [RFC] addnote and pmac In-Reply-To: <1123576274.30257.152.camel@gaston> References: <1123576274.30257.152.camel@gaston> Message-ID: <42F91AB6.8050309@am.sony.com> Benjamin Herrenschmidt wrote: > On Mon, 2005-08-08 at 11:27 -0700, Geoff Levand wrote: > >>I found that my Mac G5 wouldn't boot with a zImage modified by >>addnote. It worked OK when the image wasn't run through addnote >>though. I took just a brief look at addnote.c, and it seems this >>step is specific to the OF implementation, or could it be needed >>by older tool chains? >> >>At any rate, by default it is run for all zImage builds, which >>we'll need to change to support at least some machines. Below is >>what I got working, but someone more familiar with the boot >>makefile and the needs of other machines could certainly do >>better. > > The problem is that your G5 does understand the added Note header but > doesn't like it's content. > > IBM Open Firmware only works properly in real mode, while Apple's only > works properly in virtual mode. The Note header is set to real mode, > thus causing Apple's OF to do a double-reboot into a mode where it craps > itself. OK, I understand. > There is no way unfortunately to "fix" that other than > generating two zImages, or better, having the distro add the Note > section for IBM machines at zImage install time. It seems like an inconvenience to need to add something later... > Note that your patch is wrong, as this has nothing to do with iSeries, > but it's a pSeries issue. But since you can built kernels images that > can be booted on both a G5 and a pSeries, using a CONFIG_ option for > that isn't a good solution anyway. If I understand it correctly, we need it so you can build a kernel image (vmlinux) that could be binary compatible with both G5 and pSeries machines, and maybe others, but that the OF compatible wrapper program, if built, needs to have a note header added for pSeries machines. It seems both you and Olaf suggested to make two build targets, so I set them up as zImage and zImage.rs6k. I wonder if we could use zImage.real, since I imagine any OF machine would need one or the other, or are there other machine specific things needed by others? -Geoff Index: alp-linux--dev-2-6-12--1.7/arch/ppc64/Makefile =================================================================== --- alp-linux--dev-2-6-12--1.7.orig/arch/ppc64/Makefile 2005-08-09 13:24:43.000000000 -0700 +++ alp-linux--dev-2-6-12--1.7/arch/ppc64/Makefile 2005-08-09 13:28:14.000000000 -0700 @@ -87,14 +87,15 @@ boot := arch/ppc64/boot -boottarget-$(CONFIG_PPC_PSERIES) := zImage zImage.initrd -boottarget-$(CONFIG_PPC_MAPLE) := zImage zImage.initrd -boottarget-$(CONFIG_PPC_ISERIES) := vmlinux.sminitrd vmlinux.initrd vmlinux.sm -boottarget-$(CONFIG_PPC_BPA) := zImage zImage.initrd -$(boottarget-y): vmlinux +boottargets-$(CONFIG_PPC_PSERIES) += zImage.rs6k zImage.initrd.rs6k +boottargets-$(CONFIG_PPC_PMAC) += zImage zImage.initrd +boottargets-$(CONFIG_PPC_MAPLE) += zImage zImage.initrd +boottargets-$(CONFIG_PPC_ISERIES) += vmlinux.sminitrd vmlinux.initrd vmlinux.sm +boottargets-$(CONFIG_PPC_BPA) += zImage zImage.initrd +$(boottargets-y): vmlinux $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ -bootimage-$(CONFIG_PPC_PSERIES) := $(boot)/zImage +bootimage-$(CONFIG_PPC_PSERIES) := $(boot)/zImage.rs6k bootimage-$(CONFIG_PPC_PMAC) := vmlinux bootimage-$(CONFIG_PPC_MAPLE) := $(boot)/zImage bootimage-$(CONFIG_PPC_BPA) := zImage @@ -122,10 +123,12 @@ $(call filechk,gen-asm-offsets) define archhelp - echo '* zImage - Compressed kernel image (arch/$(ARCH)/boot/zImage)' - echo ' zImage.initrd- Compressed kernel image with initrd attached,' - echo ' sourced from arch/$(ARCH)/boot/ramdisk.image.gz' - echo ' (arch/$(ARCH)/boot/zImage.initrd)' + echo ' zImage - Compressed kernel image (arch/$(ARCH)/boot/zImage)' + echo ' zImage.initrd - Compressed kernel image with initrd attached,' + echo ' sourced from arch/$(ARCH)/boot/ramdisk.image.gz' + echo ' (arch/$(ARCH)/boot/zImage.initrd)' + echo ' zImage.rs6k - zImage for pSeries machines' + echo ' zImage.initrd.rs6k- zImage with initrd for pSeries machines' endef CLEAN_FILES += include/asm-ppc64/offsets.h Index: alp-linux--dev-2-6-12--1.7/arch/ppc64/boot/Makefile =================================================================== --- alp-linux--dev-2-6-12--1.7.orig/arch/ppc64/boot/Makefile 2005-08-09 13:27:38.000000000 -0700 +++ alp-linux--dev-2-6-12--1.7/arch/ppc64/boot/Makefile 2005-08-09 13:32:59.000000000 -0700 @@ -37,6 +37,9 @@ quiet_cmd_bootas = BOOTAS $@ cmd_bootas = $(CROSS32CC) -Wp,-MD,$(depfile) $(BOOTAFLAGS) -c -o $@ $< +quiet_cmd_bootld = BOOTLD $@ + cmd_bootld = $(CROSS32LD) $(BOOTLFLAGS) -o $@ $(2) + $(patsubst %.c,%.o, $(filter %.c, $(src-boot))): %.o: %.c $(call if_changed_dep,bootcc) $(patsubst %.S,%.o, $(filter %.S, $(src-boot))): %.o: %.S @@ -95,11 +98,19 @@ $(call addsection, $@) $(obj)/zImage: obj-boot += $(call obj-sec, $(required)) -$(obj)/zImage: $(call obj-sec, $(required)) $(obj-boot) $(obj)/addnote FORCE - $(call if_changed,addnote) +$(obj)/zImage: $(call obj-sec, $(required)) $(obj-boot) FORCE + $(call cmd,bootld,$(obj-boot)) $(obj)/zImage.initrd: obj-boot += $(call obj-sec, $(required) $(initrd)) -$(obj)/zImage.initrd: $(call obj-sec, $(required) $(initrd)) $(obj-boot) $(obj)/addnote FORCE +$(obj)/zImage.initrd: $(call obj-sec, $(required) $(initrd)) $(obj-boot) FORCE + $(call cmd,bootld,$(obj-boot)) + +$(obj)/zImage.rs6k: $(obj)/zImage $(obj)/addnote FORCE + @cp -f $< $@ + $(call if_changed,addnote) + +$(obj)/zImage.initrd.rs6k: $(obj)/zImage.initrd $(obj)/addnote FORCE + @cp -f $< $@ $(call if_changed,addnote) $(obj)/imagesize.c: vmlinux.strip -EOF From hch at lst.de Wed Aug 10 07:26:03 2005 From: hch at lst.de (Christoph Hellwig) Date: Tue, 9 Aug 2005 23:26:03 +0200 Subject: [PATCH] [1/4] PPC64: Split off platform stuff from iommu.h In-Reply-To: <20050809202118.GB30589@austin.ibm.com> References: <20050809202007.GA30589@austin.ibm.com> <20050809202118.GB30589@austin.ibm.com> Message-ID: <20050809212603.GA29629@lst.de> On Tue, Aug 09, 2005 at 03:21:18PM -0500, Olof Johansson wrote: > +/* > + * dart.h totally useless comment. The file name is defined by the directory it's contained in, and duplicating it in the file is unessecary redudant infortmation. > +/* > + * tce.h dito From olof at lixom.net Wed Aug 10 07:37:06 2005 From: olof at lixom.net (Olof Johansson) Date: Tue, 9 Aug 2005 16:37:06 -0500 Subject: [PATCH] [1/4] PPC64: Split off platform stuff from iommu.h In-Reply-To: <20050809212603.GA29629@lst.de> References: <20050809202007.GA30589@austin.ibm.com> <20050809202118.GB30589@austin.ibm.com> <20050809212603.GA29629@lst.de> Message-ID: <20050809213706.GA6300@austin.ibm.com> On Tue, Aug 09, 2005 at 11:26:03PM +0200, Christoph Hellwig wrote: > On Tue, Aug 09, 2005 at 03:21:18PM -0500, Olof Johansson wrote: > > +/* > > + * dart.h > > totally useless comment. The file name is defined by the directory > it's contained in, and duplicating it in the file is unessecary redudant > infortmation. Sure. I just followed the existing praxis on the file I copied/split from. Some files seem to have it, some don't. New patch below. -Olof Split out the implementation-specific parts of include/asm-ppc64/iommu.h to separate include files (tce.h and dart.h respectively). The generic iommu code really doesn't care about the underlying implementation, and the TCE and DART stuff is completely different. Signed-off-by: Olof Johansson Index: gr_work/include/asm-ppc64/dart.h =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ gr_work/include/asm-ppc64/dart.h 2005-08-09 16:36:57.117937111 -0500 @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2004 Olof Johansson , IBM Corporation + * + * 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 + */ + +#ifndef _ASM_DART_H +#define _ASM_DART_H + + +/* physical base of DART registers */ +#define DART_BASE 0xf8033000UL + +/* Offset from base to control register */ +#define DARTCNTL 0 +/* Offset from base to exception register */ +#define DARTEXCP 0x10 +/* Offset from base to TLB tag registers */ +#define DARTTAG 0x1000 + + +/* Control Register fields */ + +/* base address of table (pfn) */ +#define DARTCNTL_BASE_MASK 0xfffff +#define DARTCNTL_BASE_SHIFT 12 + +#define DARTCNTL_FLUSHTLB 0x400 +#define DARTCNTL_ENABLE 0x200 + +/* size of table in pages */ +#define DARTCNTL_SIZE_MASK 0x1ff +#define DARTCNTL_SIZE_SHIFT 0 + + +/* DART table fields */ + +#define DARTMAP_VALID 0x80000000 +#define DARTMAP_RPNMASK 0x00ffffff + + + +#endif Index: gr_work/include/asm-ppc64/iommu.h =================================================================== --- gr_work.orig/include/asm-ppc64/iommu.h 2005-08-09 16:34:49.934787069 -0500 +++ gr_work/include/asm-ppc64/iommu.h 2005-08-09 16:36:09.579280381 -0500 @@ -1,5 +1,4 @@ /* - * iommu.h * Copyright (C) 2001 Mike Corrigan & Dave Engebretsen, IBM Corporation * Rewrite, cleanup: * Copyright (C) 2004 Olof Johansson , IBM Corporation @@ -29,44 +28,11 @@ /* * IOMAP_MAX_ORDER defines the largest contiguous block - * of dma (tce) space we can get. IOMAP_MAX_ORDER = 13 + * of dma space we can get. IOMAP_MAX_ORDER = 13 * allows up to 2**12 pages (4096 * 4096) = 16 MB */ #define IOMAP_MAX_ORDER 13 -/* - * Tces come in two formats, one for the virtual bus and a different - * format for PCI - */ -#define TCE_VB 0 -#define TCE_PCI 1 - -/* tce_entry - * Used by pSeries (SMP) and iSeries/pSeries LPAR, but there it's - * abstracted so layout is irrelevant. - */ -union tce_entry { - unsigned long te_word; - struct { - unsigned int tb_cacheBits :6; /* Cache hash bits - not used */ - unsigned int tb_rsvd :6; - unsigned long tb_rpn :40; /* Real page number */ - unsigned int tb_valid :1; /* Tce is valid (vb only) */ - unsigned int tb_allio :1; /* Tce is valid for all lps (vb only) */ - unsigned int tb_lpindex :8; /* LpIndex for user of TCE (vb only) */ - unsigned int tb_pciwr :1; /* Write allowed (pci only) */ - unsigned int tb_rdwr :1; /* Read allowed (pci), Write allowed (vb) */ - } te_bits; -#define te_cacheBits te_bits.tb_cacheBits -#define te_rpn te_bits.tb_rpn -#define te_valid te_bits.tb_valid -#define te_allio te_bits.tb_allio -#define te_lpindex te_bits.tb_lpindex -#define te_pciwr te_bits.tb_pciwr -#define te_rdwr te_bits.tb_rdwr -}; - - struct iommu_table { unsigned long it_busno; /* Bus number this table belongs to */ unsigned long it_size; /* Size of iommu table in entries */ Index: gr_work/include/asm-ppc64/tce.h =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ gr_work/include/asm-ppc64/tce.h 2005-08-09 16:36:57.116937270 -0500 @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2001 Mike Corrigan & Dave Engebretsen, IBM Corporation + * Rewrite, cleanup: + * Copyright (C) 2004 Olof Johansson , IBM Corporation + * + * 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 + */ + +#ifndef _ASM_TCE_H +#define _ASM_TCE_H + +/* + * Tces come in two formats, one for the virtual bus and a different + * format for PCI + */ +#define TCE_VB 0 +#define TCE_PCI 1 + +/* tce_entry + * Used by pSeries (SMP) and iSeries/pSeries LPAR, but there it's + * abstracted so layout is irrelevant. + */ +union tce_entry { + unsigned long te_word; + struct { + unsigned int tb_cacheBits :6; /* Cache hash bits - not used */ + unsigned int tb_rsvd :6; + unsigned long tb_rpn :40; /* Real page number */ + unsigned int tb_valid :1; /* Tce is valid (vb only) */ + unsigned int tb_allio :1; /* Tce is valid for all lps (vb only) */ + unsigned int tb_lpindex :8; /* LpIndex for user of TCE (vb only) */ + unsigned int tb_pciwr :1; /* Write allowed (pci only) */ + unsigned int tb_rdwr :1; /* Read allowed (pci), Write allowed (vb) */ + } te_bits; +#define te_cacheBits te_bits.tb_cacheBits +#define te_rpn te_bits.tb_rpn +#define te_valid te_bits.tb_valid +#define te_allio te_bits.tb_allio +#define te_lpindex te_bits.tb_lpindex +#define te_pciwr te_bits.tb_pciwr +#define te_rdwr te_bits.tb_rdwr +}; + + +#endif Index: gr_work/arch/ppc64/kernel/u3_iommu.c =================================================================== --- gr_work.orig/arch/ppc64/kernel/u3_iommu.c 2005-08-09 16:34:49.936786752 -0500 +++ gr_work/arch/ppc64/kernel/u3_iommu.c 2005-08-09 16:36:57.115937429 -0500 @@ -44,39 +44,12 @@ #include #include #include +#include #include "pci.h" extern int iommu_force_on; -/* physical base of DART registers */ -#define DART_BASE 0xf8033000UL - -/* Offset from base to control register */ -#define DARTCNTL 0 -/* Offset from base to exception register */ -#define DARTEXCP 0x10 -/* Offset from base to TLB tag registers */ -#define DARTTAG 0x1000 - - -/* Control Register fields */ - -/* base address of table (pfn) */ -#define DARTCNTL_BASE_MASK 0xfffff -#define DARTCNTL_BASE_SHIFT 12 - -#define DARTCNTL_FLUSHTLB 0x400 -#define DARTCNTL_ENABLE 0x200 - -/* size of table in pages */ -#define DARTCNTL_SIZE_MASK 0x1ff -#define DARTCNTL_SIZE_SHIFT 0 - -/* DART table fields */ -#define DARTMAP_VALID 0x80000000 -#define DARTMAP_RPNMASK 0x00ffffff - /* Physical base address and size of the DART table */ unsigned long dart_tablebase; /* exported to htab_initialize */ static unsigned long dart_tablesize; Index: gr_work/arch/ppc64/kernel/pSeries_iommu.c =================================================================== --- gr_work.orig/arch/ppc64/kernel/pSeries_iommu.c 2005-08-09 16:34:49.937786593 -0500 +++ gr_work/arch/ppc64/kernel/pSeries_iommu.c 2005-08-09 16:36:57.112937904 -0500 @@ -45,6 +45,7 @@ #include #include #include +#include #include "pci.h" #define DBG(fmt...) Index: gr_work/arch/ppc64/kernel/vio.c =================================================================== --- gr_work.orig/arch/ppc64/kernel/vio.c 2005-08-09 16:34:49.937786593 -0500 +++ gr_work/arch/ppc64/kernel/vio.c 2005-08-09 16:34:51.994862000 -0500 @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include From paulus at samba.org Wed Aug 10 08:48:33 2005 From: paulus at samba.org (Paul Mackerras) Date: Wed, 10 Aug 2005 08:48:33 +1000 Subject: Merging ppc32 and ppc64 In-Reply-To: References: <17136.13558.773102.465379@cargo.ozlabs.ibm.com> <42F79D89.3040709@austin.ibm.com> Message-ID: <17145.12993.672427.466466@cargo.ozlabs.ibm.com> Segher Boessenkool writes: > _Please_ don't throw the real device tree away; I'm happy with > the flattened device tree if and only if it is a _minimum_ > requirement, and having a _real_ device tree (or even real > Open Firmware support) is still an option. Aarrgh! There seems to be a lot of misunderstanding about the flattened device tree concept. The flattened device tree is simply a representation of a device tree (i.e., the full, or "real" (whatever that means) device tree) that does not contain any pointers and is in a single contiguous block of memory. On systems with open firmware, the boot is separated into two phases. In the first phase, OF is still active. The kernel is not based at physical address 0, and can do OF client calls. In the second phase, the kernel is based at physical address 0 and OF's memory has been reclaimed by the kernel. The flattened device tree is the main data structure that is passed from the first phase to the second. One of the first things that the second phase does is to expand the flattened device tree into the normal in-kernel device tree representation (a tree of struct device_node). Having the flattened device tree doesn't mean that we will be using the device tree less, it means we will be using it _more_. Paul. From paulus at samba.org Wed Aug 10 08:55:34 2005 From: paulus at samba.org (Paul Mackerras) Date: Wed, 10 Aug 2005 08:55:34 +1000 Subject: Merging ppc32 and ppc64 In-Reply-To: References: <17136.13558.773102.465379@cargo.ozlabs.ibm.com> <42F79D89.3040709@austin.ibm.com> Message-ID: <17145.13414.996858.522127@cargo.ozlabs.ibm.com> Segher Boessenkool writes: > Yes, and that is exactly what I do not want. We are not going > to require OF implementations that do not need yaboot or similar > to pass a flattened device tree to the kernel, eh? Also, there > is no reason why something like yaboot (with an OF still running > underneath) should have to care about anything device-tree related > at all; the OS can just as easily ask the OF itself. For now the kernel will cope with either having an OF client interface entry point or a flattened device tree passed to it. In the future we intend to move all the OF client calls into the zImage wrapper and have the zImage wrapper pass the flattened device tree to the kernel proper. That will be much cleaner because we will be able to get rid of all of the dodgy RELOC stuff in prom_init.c. It is already the case (and has always been the case) that you can't boot a vmlinux image directly from OF - there is always either or both of yaboot or a zImage wrapper in between anyway. Paul. From kumar.gala at freescale.com Wed Aug 10 09:00:21 2005 From: kumar.gala at freescale.com (Kumar Gala) Date: Tue, 9 Aug 2005 18:00:21 -0500 Subject: Merging ppc32 and ppc64 In-Reply-To: <17145.13414.996858.522127@cargo.ozlabs.ibm.com> References: <17145.13414.996858.522127@cargo.ozlabs.ibm.com> Message-ID: On Aug 9, 2005, at 5:55 PM, Paul Mackerras wrote: > Segher Boessenkool writes: > > >> Yes, and that is exactly what I do not want. We are not going >> to require OF implementations that do not need yaboot or similar >> to pass a flattened device tree to the kernel, eh? Also, there >> is no reason why something like yaboot (with an OF still running >> underneath) should have to care about anything device-tree related >> at all; the OS can just as easily ask the OF itself. >> > > For now the kernel will cope with either having an OF client interface > entry point or a flattened device tree passed to it. In the future we > intend to move all the OF client calls into the zImage wrapper and > have the zImage wrapper pass the flattened device tree to the kernel > proper. That will be much cleaner because we will be able to get rid > of all of the dodgy RELOC stuff in prom_init.c. Can you clarify when the "future" is. I'd like to see this change happen as part of the arch/powerpc work. - kumar From nacc at us.ibm.com Wed Aug 10 09:29:43 2005 From: nacc at us.ibm.com (Nishanth Aravamudan) Date: Tue, 9 Aug 2005 16:29:43 -0700 Subject: [PATCH] add {request,free}_virt_irq() helper functions Message-ID: <20050809232943.GD7826@us.ibm.com> Hi, Description: For drivers which do not actually have access to interrupts, it is useful to be able to request a virtual IRQ on PPC. Provide wrapper functions for the request and free paths. One user of this interface is the IBM eHCA Driver (Infiniband Host Channel Adapter) which has been submitted to the OpenIB tree. Signed-off-by: Nishanth Aravamudan --- arch/ppc64/kernel/irq.c | 33 +++++++++++++++++++++++++++++++++ include/asm-ppc64/virq.h | 30 ++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+) diff -urpN 2.6.13-rc6/arch/ppc64/kernel/irq.c 2.6.13-rc6-dev/arch/ppc64/kernel/irq.c --- 2.6.13-rc6/arch/ppc64/kernel/irq.c 2005-08-09 15:22:54.000000000 -0700 +++ 2.6.13-rc6-dev/arch/ppc64/kernel/irq.c 2005-08-09 16:28:27.000000000 -0700 @@ -49,6 +49,7 @@ #include #include #include +#include #include #include #include @@ -462,6 +463,38 @@ unsigned int real_irq_to_virt_slowpath(u } +/* + * Wrapper around request_irq to allow registering handler for + * a specific Interrupt Source Token ist + */ +int request_virt_irq(__u32 ist, + irqreturn_t (*handler)(int, void*, struct pt_regs *), + unsigned long irq_flags, const char * devname, + void *dev_id) +{ + unsigned int irq = virt_irq_create_mapping(ist); + if (irq == NO_IRQ) + return -EINVAL; + + irq = irq_offset_up(irq); + return request_irq(irq, handler, + irq_flags, devname, dev_id); +} +EXPORT_SYMBOL_GPL(request_virt_irq); + +/* + * Wrapper around free_irq to allow deregistering handler for + * a specific Interrupt Source Token ist + */ +void free_virt_irq(__u32 ist, void *dev_id) +{ + unsigned int irq = virt_irq_create_mapping(ist); + + irq = irq_offset_up(irq); + free_irq(irq, dev_id); + return; +} +EXPORT_SYMBOL_GPL(free_virt_irq); #endif /* CONFIG_PPC_ISERIES */ #ifdef CONFIG_IRQSTACKS diff -urpN 2.6.13-rc6/include/asm-ppc64/virq.h 2.6.13-rc6-dev/include/asm-ppc64/virq.h --- 2.6.13-rc6/include/asm-ppc64/virq.h 1969-12-31 16:00:00.000000000 -0800 +++ 2.6.13-rc6-dev/include/asm-ppc64/virq.h 2005-08-09 15:23:17.000000000 -0700 @@ -0,0 +1,30 @@ +#ifdef __KERNEL__ +#ifndef _ASM_VIRQ_H +#define _ASM_VIRQ_H + +/* + * 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 +#include + +/* + * Wrapper around request_irq to allow registering handler for + * a specific Interrupt Source Token ist + */ +int request_virt_irq(__u32 ist, + irqreturn_t (*handler)(int, void*, struct pt_regs *), + unsigned long irq_flags, const char * devname, + void *dev_id); +/* + * Wrapper around free_irq to allow deregistering handler for + * a specific Interrupt Source Token ist + */ +void free_virt_irq(__u32 ist, void *dev_id); + +#endif /* _ASM_VIRQ_H */ +#endif /* __KERNEL__ */ From paulus at samba.org Wed Aug 10 09:32:45 2005 From: paulus at samba.org (Paul Mackerras) Date: Wed, 10 Aug 2005 09:32:45 +1000 Subject: [PATCH] add {request,free}_virt_irq() helper functions In-Reply-To: <20050809232943.GD7826@us.ibm.com> References: <20050809232943.GD7826@us.ibm.com> Message-ID: <17145.15645.667784.78585@cargo.ozlabs.ibm.com> Nishanth Aravamudan writes: > +int request_virt_irq(__u32 ist, > + irqreturn_t (*handler)(int, void*, struct pt_regs *), > + unsigned long irq_flags, const char * devname, > + void *dev_id) Baaaad name. This isn't at all about requesting a virtual IRQ, in fact request_irq already does that. This interface needs to be rethought. Paul. From geoffrey.levand at am.sony.com Wed Aug 10 09:21:51 2005 From: geoffrey.levand at am.sony.com (Geoff Levand) Date: Tue, 09 Aug 2005 16:21:51 -0700 Subject: Fan control for new PowerMac G5 2.7GHz machines? In-Reply-To: <1123147202.30257.50.camel@gaston> References: <1123147202.30257.50.camel@gaston> Message-ID: <42F93A8F.7040605@am.sony.com> Benjamin Herrenschmidt wrote: >>i2c /dev entries driver >>/u3 at 0,f8000000/i2c at f8001000: Missing interrupt or address ! >> >>In therm_pm72_attach() it hits 'Found K2', but u3_0 and u3_1 >>are never set, so start_control_loops() is never called. >> >>I'll look at it more when I have some time. > > > Ah yes, this is indeed the problem ! There is a bug in Apple device tree > on these machines that is breaking Linux. I should have a workaround > upstream, but for some reason, it seems it's not working for you. > > Can you look at arch/ppc64/kernel/prom_init.c, more specifically, the > function > > static void __init fixup_device_tree(void) > > And see if it's going all the way to the fixup code at the end or not ? > If not, then one of the tests isn't triggering the right way on your > machine, possibly the U3 revision. > Seems like this makes it work, at least I get '** CPU ...' like debug messages coming out. -Geoff --- a/arch/ppc64/kernel/prom_init.c 2005-07-27 18:34:40.000000000 -0700 +++ b/arch/ppc64/kernel/prom_init.c 2005-08-09 16:18:04.000000000 -0700 @@ -1803,7 +1803,7 @@ if (prom_getprop(u3, "device-rev", &u3_rev, sizeof(u3_rev)) == PROM_ERROR) return; - if (u3_rev != 0x35) + if (u3_rev != 0x35 && u3_rev != 0x37) return; /* does it need fixup ? */ if (prom_getproplen(i2c, "interrupts") > 0) -EOF From bdc at carlstrom.com Wed Aug 10 10:34:35 2005 From: bdc at carlstrom.com (Brian D. Carlstrom) Date: Tue, 9 Aug 2005 17:34:35 -0700 Subject: Fan control for new PowerMac G5 2.7GHz machines? In-Reply-To: <42F93A8F.7040605@am.sony.com> References: <1123147202.30257.50.camel@gaston> <42F93A8F.7040605@am.sony.com> Message-ID: <17145.19355.41846.690596@zot.electricrain.com> Geoff Levand writes: > Seems like this makes it work, at least I get '** CPU ...' like debug > messages coming out. Since I started this thread, I wanted to mention that with Fedora Core 4 (versus YDL 4.0.1) things worked fine. The fans run loud during the installation but after reboot the installed kernel has no problems. The 2.6.12-1.1398_FC4 kernel installed by "yum update" is also fine. We have 2 more 2.7 GHz on backorder. Apparently they are holding them up to resolve some issue. Hopefully they aren't just creating more special cases to test for. -bri From olof at lixom.net Wed Aug 10 13:20:01 2005 From: olof at lixom.net (Olof Johansson) Date: Tue, 9 Aug 2005 22:20:01 -0500 Subject: [PATCH] PPC64: Don't try to claim memory from OF at 1GB mark Message-ID: <20050810032001.GB6300@austin.ibm.com> Hi, Some RS64-based machines (p620, F80, others) have problems with firmware returning 0xdeadbeef instead of failure to allocations that end at the 1GB mark. We have two options: 1. Detect the undocumented 0xdeadbeef return value and interpret it as a failure. 2. Avoid allocating that high. (2) is really the cleaner solution here. 768MB is plenty of room so use that as the max alloc_top instead of 1GB. Signed-off-by: Olof Johansson Index: 2.6/arch/ppc64/kernel/prom_init.c =================================================================== --- 2.6.orig/arch/ppc64/kernel/prom_init.c 2005-08-09 03:16:09.000000000 -0500 +++ 2.6/arch/ppc64/kernel/prom_init.c 2005-08-09 18:16:18.000000000 -0500 @@ -892,7 +892,10 @@ static void __init prom_init_mem(void) if ( RELOC(of_platform) == PLATFORM_PSERIES_LPAR ) RELOC(alloc_top) = RELOC(rmo_top); else - RELOC(alloc_top) = RELOC(rmo_top) = min(0x40000000ul, RELOC(ram_top)); + /* Some RS64 machines have buggy firmware where claims up at 1GB + * fails. Cap at 768MB as a workaround. Still plenty of room. + */ + RELOC(alloc_top) = RELOC(rmo_top) = min(0x30000000ul, RELOC(ram_top)); prom_printf("memory layout at init:\n"); prom_printf(" memory_limit : %x (16 MB aligned)\n", RELOC(prom_memory_limit)); From olof at lixom.net Wed Aug 10 13:24:37 2005 From: olof at lixom.net (Olof Johansson) Date: Tue, 9 Aug 2005 22:24:37 -0500 Subject: [PATCH] PPC64: Fix non-LPAR IOMMU table allocation on pSeries Message-ID: <20050810032437.GC6300@austin.ibm.com> Hi, This is for the 2.6.14 feed. I wouldn't recommend pushing it into 2.6.13 due to risk of regressing some box that I don't have access to for testing. I'd appreciate it if people with pre-POWER5, non-LPAR machines would give this a go on their boxes and let me know if something falls apart. It's been tested on an F80 and a p650 (SMP mode) here. p615 and p630 have been sore spots in the past. --- Some RS64 systems (such as F80) have non-python host bridges with EADS. However, they have two EADS with 4 buses each under them, so the logic that assumed no more than 7 busses per PHB failed miserably. Try to be a bit smarter at detecting the need for a PHB-level IOMMU table by checking for the presence of an ISA bus. Only PHBs with ISA bridges should need the PHB-level table. Signed-off-by: Olof Johansson Index: 2.6/arch/ppc64/kernel/pSeries_iommu.c =================================================================== --- 2.6.orig/arch/ppc64/kernel/pSeries_iommu.c 2005-08-09 03:20:04.000000000 -0500 +++ 2.6/arch/ppc64/kernel/pSeries_iommu.c 2005-08-09 03:25:54.000000000 -0500 @@ -311,6 +311,7 @@ static void iommu_bus_setup_pSeries(stru { struct device_node *dn, *pdn; struct iommu_table *tbl; + struct device_node *isa_dn; DBG("iommu_bus_setup_pSeries, bus %p, bus->self %p\n", bus, bus->self); @@ -328,18 +329,22 @@ static void iommu_bus_setup_pSeries(stru if (!bus->self) { /* Root bus */ if (is_python(dn)) { - unsigned int *iohole; - DBG("Python root bus %s\n", bus->name); - iohole = (unsigned int *)get_property(dn, "io-hole", 0); + /* Check if the ISA bus on the system is under + * this PHB. + */ + isa_dn = of_find_node_by_type(NULL, "isa"); + + while (isa_dn && isa_dn != dn) + isa_dn = isa_dn->parent; - if (iohole) { + if (isa_dn) { /* On first bus we need to leave room for the * ISA address space. Just skip the first 256MB * alltogether. This leaves 768MB for the window. */ - DBG("PHB has io-hole, reserving 256MB\n"); + DBG("PHB has isa bus, reserving 256MB\n"); dn->phb->dma_window_size = 3 << 28; dn->phb->dma_window_base_cur = 1 << 28; } else { @@ -353,15 +358,36 @@ static void iommu_bus_setup_pSeries(stru iommu_table_setparms(dn->phb, dn, tbl); dn->iommu_table = iommu_init_table(tbl); } else { - /* Do a 128MB table at root. This is used for the IDE - * controller on some SMP-mode POWER4 machines. It - * doesn't hurt to allocate it on other machines - * -- it'll just be unused since new tables are - * allocated on the EADS level. + /* Do a 128MB table at root if there is an ISA bus + * under our PHB. This is used for the IDE + * controller on some SMP-mode POWER4 machines. * * Allocate at offset 128MB to avoid having to deal * with ISA holes; 128MB table for IDE is plenty. */ + /* Check if the ISA bus on the system is under + * this PHB. + */ + isa_dn = of_find_node_by_type(NULL, "isa"); + + while (isa_dn && isa_dn != dn) + isa_dn = isa_dn->parent; + + if (!isa_dn) { + /* No ISA/IDE, no table needed. All I/O is under + * EADS bridges. All we need to do is set + * base values. + */ + dn->phb->dma_window_size = 1 << 28; + dn->phb->dma_window_base_cur = 0; + return; + } + + /* If we have ISA, then we probably have an IDE + * controller too. Allocate a 128MB table but + * skip the first 128MB to avoid stepping on ISA + * space. + */ dn->phb->dma_window_size = 1 << 27; dn->phb->dma_window_base_cur = 1 << 27; From miltonm at bga.com Wed Aug 10 13:43:17 2005 From: miltonm at bga.com (Milton Miller) Date: Tue, 9 Aug 2005 22:43:17 -0500 Subject: [PATCH 3/8] Change address of ppc64 initial segment table Message-ID: <68f3f183084d1212e65adeb4839a478c@bga.com> > =================================================================== > --- working-2.6.orig/arch/ppc64/kernel/head.S 2005-07-28 > 14:23:09.000000000 +1000 > +++ working-2.6/arch/ppc64/kernel/head.S 2005-07-28 > 14:23:15.000000000 +1000 > @@ -51,9 +51,10 @@ > * We layout physical memory as follows: > * 0x0000 - 0x00ff : Secondary processor spin code > * 0x0100 - 0x2fff : pSeries Interrupt prologs > - * 0x3000 - 0x6fff : interrupt support, iSeries and common interrupt > prologs > + * 0x3000 - 0x5fff : interrupt support, iSeries and common interrupt > prologs > + * 0x6000 - 0x6fff : Initial (CPU0) segment table > * 0x7000 - 0x7fff : FWNMI data area > - * 0x9000 - 0x9fff : Initial segment table > + * 0x8000 - : Early init and support code > */ > Before moving the segment table, lets move the syscall entry code from entry.S below 0x8000 so that we can save a dependent add (or?) instruction every syscall. milton From miltonm at bga.com Wed Aug 10 13:43:25 2005 From: miltonm at bga.com (Milton Miller) Date: Tue, 9 Aug 2005 22:43:25 -0500 Subject: [PATCH] [3/4] PPC64: PAGE_SIZE constants in copyuser.S and copypage.S Message-ID: > - cmpdi cr6,r5,4096 > +#if PAGE_SIZE > 0x8000 > + li r6,PAGE_SIZE at l > + oris r6,r6,PAGE_SIZE at h > + cmpd cr6,r5,r6 > +#else > + cmpdi cr6,r5,PAGE_SIZE > +#endif That is actually broken for 32K as li is signed. Hence the normal idiom lis @h / li @l. Yes, lis is also signed, which matters for 64 bits. Alternatively use the @ha modifier which takes this into account and use addis: addis r6,r6,PAGE_SIZE at ha > - li r5,4096 > + li r5,PAGE_SIZE at l > +#if PAGE_SIZE > 0x8000 > + oris r5,r5,PAGE_SIZE at h > +#endif Change this to: addis r5,r5, at PAGE_SIZE@ha milton From sfr at canb.auug.org.au Wed Aug 10 13:59:15 2005 From: sfr at canb.auug.org.au (Stephen Rothwell) Date: Wed, 10 Aug 2005 13:59:15 +1000 Subject: queue of patches to go upstream post 2.6.13 In-Reply-To: <1123598323.30257.206.camel@gaston> References: <17144.38955.181595.734665@cargo.ozlabs.ibm.com> <1123598323.30257.206.camel@gaston> Message-ID: <20050810135915.352d23a3.sfr@canb.auug.org.au> On Tue, 09 Aug 2005 16:38:42 +0200 Benjamin Herrenschmidt wrote: > > On Tue, 2005-08-09 at 21:48 +1000, Paul Mackerras wrote: > > I have queued up 35 patches to go to Linus once 2.6.13 is out and > > checked them into a git repository. If you are interested to see what > > is pending, you can pull from > > > > rsync://ozlabs.org/kernel/ppc64-2.6.git > > Could we setup gitweb there too ? :) Please try http://ozlabs.org/git N.B. Some of the diffs and large parts of the tree will generate 403 errors because we only export the changed subset of the full kernel tree ... -- Cheers, Stephen Rothwell sfr at canb.auug.org.au http://www.canb.auug.org.au/~sfr/ From michael at ellerman.id.au Wed Aug 10 14:18:29 2005 From: michael at ellerman.id.au (Michael Ellerman) Date: Wed, 10 Aug 2005 14:18:29 +1000 (EST) Subject: [PATCH 0/10] Add flattened device tree for iSeries Message-ID: <1123647505.420467.500210448555.qpatch@concordia> Hi, This series of patches adds a flattened device tree for iSeries, and makes other changes which allow us to call the common initialisation code on iSeries. Most of these are reasonably low risk, they're just moving logic from iSeries specific routines into the device tree. Although I'm less confident about "ppc64: Update create_pte_mapping to replace iSeries_bolt_kernel()", it'd be good if someone with more MMU knowledge could look at that one. This series depends on Benh's new device tree code, Stephen's FW_FEATURE patches and David's head.S cleanups. Booted on iSeries, P5 LPAR, P3 and G5. cheers From michael at ellerman.id.au Wed Aug 10 14:18:31 2005 From: michael at ellerman.id.au (Michael Ellerman) Date: Wed, 10 Aug 2005 14:18:31 +1000 (EST) Subject: [PATCH 1/10] ppc64: Move iSeries ppc_md functions into a machdep_calls struct In-Reply-To: <1123647505.420467.500210448555.qpatch@concordia> Message-ID: <20050810041831.ED92067FB0@ozlabs.org> Move the iSeries machine specific calls into a machdep_calls struct like other platforms, rather than setting members of ppc_md explicitly. Signed-off-by: Michael Ellerman --- arch/ppc64/kernel/iSeries_setup.c | 57 ++++++++++++++++++-------------------- 1 files changed, 28 insertions(+), 29 deletions(-) Index: work/arch/ppc64/kernel/iSeries_setup.c =================================================================== --- work.orig/arch/ppc64/kernel/iSeries_setup.c +++ work/arch/ppc64/kernel/iSeries_setup.c @@ -76,6 +76,8 @@ extern void ppcdbg_initialize(void); static void build_iSeries_Memory_Map(void); static void setup_iSeries_cache_sizes(void); static void iSeries_bolt_kernel(unsigned long saddr, unsigned long eaddr); +static int iseries_shared_idle(void); +static int iseries_dedicated_idle(void); #ifdef CONFIG_PCI extern void iSeries_pci_final_fixup(void); #else @@ -695,6 +697,14 @@ static void __init iSeries_setup_arch(vo { unsigned procIx = get_paca()->lppaca.dyn_hv_phys_proc_index; + if (get_paca()->lppaca.shared_proc) { + ppc_md.idle_loop = iseries_shared_idle; + printk(KERN_INFO "Using shared processor idle loop\n"); + } else { + ppc_md.idle_loop = iseries_dedicated_idle; + printk(KERN_INFO "Using dedicated idle loop\n"); + } + /* Add an eye catcher and the systemcfg layout version number */ strcpy(systemcfg->eye_catcher, "SYSTEMCFG:PPC64"); systemcfg->version.major = SYSTEMCFG_MAJOR; @@ -942,36 +952,25 @@ static int iseries_dedicated_idle(void) void __init iSeries_init_IRQ(void) { } #endif +struct machdep_calls __initdata iseries_md = { + .setup_arch = iSeries_setup_arch, + .get_cpuinfo = iSeries_get_cpuinfo, + .init_IRQ = iSeries_init_IRQ, + .get_irq = iSeries_get_irq, + .init_early = iSeries_init_early, + .pcibios_fixup = iSeries_pci_final_fixup, + .restart = iSeries_restart, + .power_off = iSeries_power_off, + .halt = iSeries_halt, + .get_boot_time = iSeries_get_boot_time, + .set_rtc_time = iSeries_set_rtc_time, + .get_rtc_time = iSeries_get_rtc_time, + .calibrate_decr = iSeries_calibrate_decr, + .progress = iSeries_progress, + /* XXX Implement enable_pmcs for iSeries */ +}; + void __init iSeries_early_setup(void) { iSeries_fixup_klimit(); - - ppc_md.setup_arch = iSeries_setup_arch; - ppc_md.get_cpuinfo = iSeries_get_cpuinfo; - ppc_md.init_IRQ = iSeries_init_IRQ; - ppc_md.get_irq = iSeries_get_irq; - ppc_md.init_early = iSeries_init_early, - - ppc_md.pcibios_fixup = iSeries_pci_final_fixup; - - ppc_md.restart = iSeries_restart; - ppc_md.power_off = iSeries_power_off; - ppc_md.halt = iSeries_halt; - - ppc_md.get_boot_time = iSeries_get_boot_time; - ppc_md.set_rtc_time = iSeries_set_rtc_time; - ppc_md.get_rtc_time = iSeries_get_rtc_time; - ppc_md.calibrate_decr = iSeries_calibrate_decr; - ppc_md.progress = iSeries_progress; - - /* XXX Implement enable_pmcs for iSeries */ - - if (get_paca()->lppaca.shared_proc) { - ppc_md.idle_loop = iseries_shared_idle; - printk(KERN_INFO "Using shared processor idle loop\n"); - } else { - ppc_md.idle_loop = iseries_dedicated_idle; - printk(KERN_INFO "Using dedicated idle loop\n"); - } } - From michael at ellerman.id.au Wed Aug 10 14:18:32 2005 From: michael at ellerman.id.au (Michael Ellerman) Date: Wed, 10 Aug 2005 14:18:32 +1000 (EST) Subject: [PATCH 2/10] ppc64: Make some generic irq code compile for iSeries In-Reply-To: <1123647505.420467.500210448555.qpatch@concordia> Message-ID: <20050810041832.C861267FB5@ozlabs.org> In order to call finish_device_tree() on iSeries we need to define virt_irq_create_mapping(). We also need to set ppc64_interrupt_controller to something other than zero. If we want to do interrupt setup via the device tree on iSeries this code will need some serious work, but it's harmless to have it there as long as the nodes in the iSeries device tree don't cause it to be invoked. Signed-off-by: Michael Ellerman --- arch/ppc64/kernel/iSeries_irq.c | 13 +++++++++++++ arch/ppc64/kernel/iSeries_setup.c | 2 ++ include/asm-ppc64/processor.h | 1 + 3 files changed, 16 insertions(+) Index: work/arch/ppc64/kernel/iSeries_irq.c =================================================================== --- work.orig/arch/ppc64/kernel/iSeries_irq.c +++ work/arch/ppc64/kernel/iSeries_irq.c @@ -351,3 +351,16 @@ int __init iSeries_allocate_IRQ(HvBusNum irq_desc[virtirq].handler = &iSeries_IRQ_handler; return virtirq; } + +int virt_irq_create_mapping(unsigned int real_irq) +{ + BUG(); /* Don't call this on iSeries, yet */ + + return 0; +} + +void virt_irq_init(void) +{ + return; +} + Index: work/arch/ppc64/kernel/iSeries_setup.c =================================================================== --- work.orig/arch/ppc64/kernel/iSeries_setup.c +++ work/arch/ppc64/kernel/iSeries_setup.c @@ -321,6 +321,8 @@ static void __init iSeries_init_early(vo ppcdbg_initialize(); + ppc64_interrupt_controller = IC_ISERIES; + #if defined(CONFIG_BLK_DEV_INITRD) /* * If the init RAM disk has been configured and there is Index: work/include/asm-ppc64/processor.h =================================================================== --- work.orig/include/asm-ppc64/processor.h +++ work/include/asm-ppc64/processor.h @@ -290,6 +290,7 @@ #define IC_OPEN_PIC 1 #define IC_PPC_XIC 2 #define IC_BPA_IIC 3 +#define IC_ISERIES 4 #define XGLUE(a,b) a##b #define GLUE(a,b) XGLUE(a,b) From michael at ellerman.id.au Wed Aug 10 14:18:34 2005 From: michael at ellerman.id.au (Michael Ellerman) Date: Wed, 10 Aug 2005 14:18:34 +1000 (EST) Subject: [PATCH 3/10] ppc64: Update create_pte_mapping to replace iSeries_bolt_kernel() In-Reply-To: <1123647505.420467.500210448555.qpatch@concordia> Message-ID: <20050810041834.8B59867FC4@ozlabs.org> early_setup() calls htab_initialize() which is similar, but not identical to iSeries_bolt_kernel(). On iSeries the Hypervisor has already inserted some ptes for us, and we simply have to detect that and bolt them. iSeries_hpte_bolt_or_insert() implements that logic. For the case of a non-existing pte we just call iSeries_hpte_insert(). This appears to work, although it's not entirely equivalent to the old code in iSeries_make_pte() which panicked if we got a secondary slot. Not sure if that's important. Finally we call iSeries_hpte_bolt_or_insert() from create_pte_mapping(), which is called from htab_initialize() for each lmb region. Signed-off-by: Michael Ellerman --- arch/ppc64/kernel/iSeries_htab.c | 19 ++++++++++++ arch/ppc64/kernel/iSeries_setup.c | 60 -------------------------------------- arch/ppc64/mm/hash_utils.c | 15 ++++++--- include/asm-ppc64/mmu.h | 4 ++ 4 files changed, 34 insertions(+), 64 deletions(-) Index: work/arch/ppc64/kernel/iSeries_htab.c =================================================================== --- work.orig/arch/ppc64/kernel/iSeries_htab.c +++ work/arch/ppc64/kernel/iSeries_htab.c @@ -84,6 +84,25 @@ static long iSeries_hpte_insert(unsigned return (secondary << 3) | (slot & 7); } +long iSeries_hpte_bolt_or_insert(unsigned long hpte_group, + unsigned long va, unsigned long prpn, unsigned long vflags, + unsigned long rflags) +{ + long slot; + hpte_t lhpte; + + slot = HvCallHpt_findValid(&lhpte, va >> PAGE_SHIFT); + + if (lhpte.v & HPTE_V_VALID) { + /* Bolt the existing HPTE */ + HvCallHpt_setSwBits(slot, 0x10, 0); + HvCallHpt_setPp(slot, PP_RWXX); + return 0; + } + + return iSeries_hpte_insert(hpte_group, va, prpn, vflags, rflags); +} + static unsigned long iSeries_hpte_getword0(unsigned long slot) { hpte_t hpte; Index: work/arch/ppc64/kernel/iSeries_setup.c =================================================================== --- work.orig/arch/ppc64/kernel/iSeries_setup.c +++ work/arch/ppc64/kernel/iSeries_setup.c @@ -75,7 +75,6 @@ extern void ppcdbg_initialize(void); static void build_iSeries_Memory_Map(void); static void setup_iSeries_cache_sizes(void); -static void iSeries_bolt_kernel(unsigned long saddr, unsigned long eaddr); static int iseries_shared_idle(void); static int iseries_dedicated_idle(void); #ifdef CONFIG_PCI @@ -383,9 +382,6 @@ static void __init iSeries_init_early(vo } } - /* Bolt kernel mappings for all of memory (or just a bit if we've got a limit) */ - iSeries_bolt_kernel(0, systemcfg->physicalMemorySize); - lmb_init(); lmb_add(0, systemcfg->physicalMemorySize); lmb_analyze(); @@ -637,62 +633,6 @@ static void __init setup_iSeries_cache_s } /* - * Create a pte. Used during initialization only. - */ -static void iSeries_make_pte(unsigned long va, unsigned long pa, - int mode) -{ - hpte_t local_hpte, rhpte; - unsigned long hash, vpn; - long slot; - - vpn = va >> PAGE_SHIFT; - hash = hpt_hash(vpn, 0); - - local_hpte.r = pa | mode; - local_hpte.v = ((va >> 23) << HPTE_V_AVPN_SHIFT) - | HPTE_V_BOLTED | HPTE_V_VALID; - - slot = HvCallHpt_findValid(&rhpte, vpn); - if (slot < 0) { - /* Must find space in primary group */ - panic("hash_page: hpte already exists\n"); - } - HvCallHpt_addValidate(slot, 0, &local_hpte); -} - -/* - * Bolt the kernel addr space into the HPT - */ -static void __init iSeries_bolt_kernel(unsigned long saddr, unsigned long eaddr) -{ - unsigned long pa; - unsigned long mode_rw = _PAGE_ACCESSED | _PAGE_COHERENT | PP_RWXX; - hpte_t hpte; - - for (pa = saddr; pa < eaddr ;pa += PAGE_SIZE) { - unsigned long ea = (unsigned long)__va(pa); - unsigned long vsid = get_kernel_vsid(ea); - unsigned long va = (vsid << 28) | (pa & 0xfffffff); - unsigned long vpn = va >> PAGE_SHIFT; - unsigned long slot = HvCallHpt_findValid(&hpte, vpn); - - /* Make non-kernel text non-executable */ - if (!in_kernel_text(ea)) - mode_rw |= HW_NO_EXEC; - - if (hpte.v & HPTE_V_VALID) { - /* HPTE exists, so just bolt it */ - HvCallHpt_setSwBits(slot, 0x10, 0); - /* And make sure the pp bits are correct */ - HvCallHpt_setPp(slot, PP_RWXX); - } else - /* No HPTE exists, so create a new bolted one */ - iSeries_make_pte(va, phys_to_abs(pa), mode_rw); - } -} - -/* * Document me. */ static void __init iSeries_setup_arch(void) Index: work/arch/ppc64/mm/hash_utils.c =================================================================== --- work.orig/arch/ppc64/mm/hash_utils.c +++ work/arch/ppc64/mm/hash_utils.c @@ -90,7 +90,6 @@ static inline void loop_forever(void) ; } -#ifdef CONFIG_PPC_MULTIPLATFORM static inline void create_pte_mapping(unsigned long start, unsigned long end, unsigned long mode, int large) { @@ -111,7 +110,7 @@ static inline void create_pte_mapping(un unsigned long vpn, hash, hpteg; unsigned long vsid = get_kernel_vsid(addr); unsigned long va = (vsid << 28) | (addr & 0xfffffff); - int ret; + int ret = -1; if (large) vpn = va >> HPAGE_SHIFT; @@ -129,16 +128,25 @@ static inline void create_pte_mapping(un hpteg = ((hash & htab_hash_mask) * HPTES_PER_GROUP); +#ifdef CONFIG_PPC_ISERIES + if (systemcfg->platform & PLATFORM_ISERIES_LPAR) + ret = iSeries_hpte_bolt_or_insert(hpteg, va, + virt_to_abs(addr) >> PAGE_SHIFT, + vflags, tmp_mode); + else +#endif #ifdef CONFIG_PPC_PSERIES if (systemcfg->platform & PLATFORM_LPAR) ret = pSeries_lpar_hpte_insert(hpteg, va, virt_to_abs(addr) >> PAGE_SHIFT, vflags, tmp_mode); else -#endif /* CONFIG_PPC_PSERIES */ +#endif +#ifdef CONFIG_PPC_MULTIPLATFORM ret = native_hpte_insert(hpteg, va, virt_to_abs(addr) >> PAGE_SHIFT, vflags, tmp_mode); +#endif if (ret == -1) { ppc64_terminate_msg(0x20, "create_pte_mapping"); @@ -261,7 +269,6 @@ void __init htab_initialize(void) } #undef KB #undef MB -#endif /* CONFIG_PPC_MULTIPLATFORM */ /* * Called by asm hashtable.S for doing lazy icache flush Index: work/include/asm-ppc64/mmu.h =================================================================== --- work.orig/include/asm-ppc64/mmu.h +++ work/include/asm-ppc64/mmu.h @@ -203,6 +203,10 @@ extern long native_hpte_insert(unsigned unsigned long prpn, unsigned long vflags, unsigned long rflags); +extern long iSeries_hpte_bolt_or_insert(unsigned long hpte_group, + unsigned long va, unsigned long prpn, + unsigned long vflags, unsigned long rflags); + extern void stabs_alloc(void); #endif /* __ASSEMBLY__ */ From michael at ellerman.id.au Wed Aug 10 14:18:36 2005 From: michael at ellerman.id.au (Michael Ellerman) Date: Wed, 10 Aug 2005 14:18:36 +1000 (EST) Subject: [PATCH 4/10] ppc64: Make stab_initialize() work on iSeries In-Reply-To: <1123647505.420467.500210448555.qpatch@concordia> Message-ID: <20050810041836.234EF67FC1@ozlabs.org> We don't need to call stab_initialize() for the boot cpu on iSeries, so we hack around it so that early_setup() can be called on iSeries. Signed-off-by: Michael Ellerman --- arch/ppc64/kernel/setup.c | 4 ++-- arch/ppc64/mm/stab.c | 10 ++++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) Index: work/arch/ppc64/mm/stab.c =================================================================== --- work.orig/arch/ppc64/mm/stab.c +++ work/arch/ppc64/mm/stab.c @@ -20,6 +20,7 @@ #include #include #include +#include struct stab_entry { unsigned long esid_data; @@ -277,3 +278,12 @@ void stab_initialize(unsigned long stab) asm volatile("sync":::"memory"); } } + +void stab_initialize_boot(unsigned long stab) +{ + /* stab is initialized by the HV for the boot cpu on iSeries */ + if (firmware_has_feature(FW_FEATURE_ISERIES)) + return; + + stab_initialize(stab); +} Index: work/arch/ppc64/kernel/setup.c =================================================================== --- work.orig/arch/ppc64/kernel/setup.c +++ work/arch/ppc64/kernel/setup.c @@ -96,7 +96,7 @@ extern void udbg_init_maple_realmode(voi extern unsigned long klimit; extern void mm_init_ppc64(void); -extern void stab_initialize(unsigned long stab); +extern void stab_initialize_boot(unsigned long stab); extern void htab_initialize(void); extern void early_init_devtree(void *flat_dt); extern void unflatten_device_tree(void); @@ -436,7 +436,7 @@ void __init early_setup(unsigned long dt /* * Initialize stab / SLB management */ - stab_initialize(lpaca->stab_real); + stab_initialize_boot(lpaca->stab_real); /* * Initialize the MMU Hash table and create the linear mapping From michael at ellerman.id.au Wed Aug 10 14:18:38 2005 From: michael at ellerman.id.au (Michael Ellerman) Date: Wed, 10 Aug 2005 14:18:38 +1000 (EST) Subject: [PATCH 5/10] ppc64: Make smp_release_cpus() callable on iSeries In-Reply-To: <1123647505.420467.500210448555.qpatch@concordia> Message-ID: <20050810041838.F2A7167FC8@ozlabs.org> We don't need to call smp_release_cpus() on iSeries but it's harmless if we do and it removes another #ifdef ISERIES. Signed-off-by: Michael Ellerman --- arch/ppc64/kernel/head.S | 6 ++++-- arch/ppc64/kernel/setup.c | 8 ++++---- 2 files changed, 8 insertions(+), 6 deletions(-) Index: work/arch/ppc64/kernel/head.S =================================================================== --- work.orig/arch/ppc64/kernel/head.S +++ work/arch/ppc64/kernel/head.S @@ -1952,20 +1952,22 @@ _GLOBAL(hmt_start_secondary) blr #endif -#if defined(CONFIG_KEXEC) || (defined(CONFIG_SMP) && !defined(CONFIG_PPC_ISERIES)) +#if defined(CONFIG_KEXEC) || defined(CONFIG_SMP) _GLOBAL(smp_release_cpus) /* All secondary cpus are spinning on a common * spinloop, release them all now so they can start * to spin on their individual paca spinloops. * For non SMP kernels, the secondary cpus never * get out of the common spinloop. + * XXX This does nothing useful on iSeries, secondaries are + * already waiting on their paca. */ li r3,1 LOADADDR(r5,__secondary_hold_spinloop) std r3,0(r5) sync blr -#endif /* CONFIG_SMP && !CONFIG_PPC_ISERIES */ +#endif /* CONFIG_SMP */ /* Index: work/arch/ppc64/kernel/setup.c =================================================================== --- work.orig/arch/ppc64/kernel/setup.c +++ work/arch/ppc64/kernel/setup.c @@ -182,7 +182,7 @@ void __init disable_early_printk(void) early_console_initialized = 0; } -#if defined(CONFIG_PPC_MULTIPLATFORM) && defined(CONFIG_SMP) +#ifdef CONFIG_SMP static int smt_enabled_cmdline; @@ -335,7 +335,7 @@ static void __init setup_cpu_maps(void) systemcfg->processorCount = num_present_cpus(); } -#endif /* defined(CONFIG_PPC_MULTIPLATFORM) && defined(CONFIG_SMP) */ +#endif /* CONFIG_SMP */ #ifdef CONFIG_PPC_MULTIPLATFORM @@ -645,7 +645,7 @@ void __init setup_system(void) parse_early_param(); #endif /* !CONFIG_PPC_ISERIES */ -#if defined(CONFIG_SMP) && !defined(CONFIG_PPC_ISERIES) +#ifdef CONFIG_SMP /* * iSeries has already initialized the cpu maps at this point. */ @@ -655,7 +655,7 @@ void __init setup_system(void) * we can map physical -> logical CPU ids */ smp_release_cpus(); -#endif /* defined(CONFIG_SMP) && !defined(CONFIG_PPC_ISERIES) */ +#endif printk("Starting Linux PPC64 %s\n", UTS_RELEASE); From michael at ellerman.id.au Wed Aug 10 14:18:41 2005 From: michael at ellerman.id.au (Michael Ellerman) Date: Wed, 10 Aug 2005 14:18:41 +1000 (EST) Subject: [PATCH 6/10] ppc64: Create a fake flat device tree on iSeries In-Reply-To: <1123647505.420467.500210448555.qpatch@concordia> Message-ID: <20050810041841.E487367FF8@ozlabs.org> This patch adds infrastructure for creating a fake flattened device tree on iSeries. We also need to build prom.o for iSeries which means we'll always need it. Signed-off-by: Michael Ellerman --- arch/ppc64/kernel/iSeries_setup.c | 137 ++++++++++++++++++++++++++++++++++++++ 1 files changed, 137 insertions(+) Index: work/arch/ppc64/kernel/iSeries_setup.c =================================================================== --- work.orig/arch/ppc64/kernel/iSeries_setup.c +++ work/arch/ppc64/kernel/iSeries_setup.c @@ -912,7 +912,144 @@ struct machdep_calls __initdata iseries_ /* XXX Implement enable_pmcs for iSeries */ }; +struct blob { + unsigned char data[PAGE_SIZE]; + unsigned long next; +}; + +struct iseries_flat_dt { + struct boot_param_header header; + u64 reserve_map[2]; + struct blob dt; + struct blob strings; +}; + +struct iseries_flat_dt iseries_dt; + +void dt_init(struct iseries_flat_dt *dt) +{ + dt->header.off_mem_rsvmap = + offsetof(struct iseries_flat_dt, reserve_map); + dt->header.off_dt_struct = offsetof(struct iseries_flat_dt, dt); + dt->header.off_dt_strings = offsetof(struct iseries_flat_dt, strings); + dt->header.totalsize = sizeof(struct iseries_flat_dt); + dt->header.dt_strings_size = sizeof(struct blob); + + /* There is no notion of hardware cpu id on iSeries */ + dt->header.boot_cpuid_phys = smp_processor_id(); + + dt->dt.next = (unsigned long)&dt->dt.data; + dt->strings.next = (unsigned long)&dt->strings.data; + + dt->header.magic = OF_DT_HEADER; + dt->header.version = 0x10; + dt->header.last_comp_version = 0x10; + + dt->reserve_map[0] = 0; + dt->reserve_map[1] = 0; +} + +void dt_check_blob(struct blob *b) +{ + if (b->next >= (unsigned long)&b->next) { + DBG("Ran out of space in flat device tree blob!\n"); + BUG(); + } +} + +void dt_push_u32(struct iseries_flat_dt *dt, u32 value) +{ + *((u32*)dt->dt.next) = value; + dt->dt.next += sizeof(u32); + + dt_check_blob(&dt->dt); +} + +void dt_push_u64(struct iseries_flat_dt *dt, u64 value) +{ + *((u64*)dt->dt.next) = value; + dt->dt.next += sizeof(u64); + + dt_check_blob(&dt->dt); +} + +unsigned long dt_push_bytes(struct blob *blob, char *data, int len) +{ + unsigned long start = blob->next - (unsigned long)blob->data; + + memcpy((char *)blob->next, data, len); + blob->next = _ALIGN(blob->next + len, 4); + + dt_check_blob(blob); + + return start; +} + +void dt_start_node(struct iseries_flat_dt *dt, char *name) +{ + dt_push_u32(dt, OF_DT_BEGIN_NODE); + dt_push_bytes(&dt->dt, name, strlen(name) + 1); +} + +#define dt_end_node(dt) dt_push_u32(dt, OF_DT_END_NODE) + +void dt_prop(struct iseries_flat_dt *dt, char *name, char *data, int len) +{ + unsigned long offset; + + dt_push_u32(dt, OF_DT_PROP); + + /* Length of the data */ + dt_push_u32(dt, len); + + /* Put the property name in the string blob. */ + offset = dt_push_bytes(&dt->strings, name, strlen(name) + 1); + + /* The offset of the properties name in the string blob. */ + dt_push_u32(dt, (u32)offset); + + /* The actual data. */ + dt_push_bytes(&dt->dt, data, len); +} + +void dt_prop_str(struct iseries_flat_dt *dt, char *name, char *data) +{ + dt_prop(dt, name, data, strlen(data) + 1); /* + 1 for NULL */ +} + +void dt_prop_u32(struct iseries_flat_dt *dt, char *name, u32 data) +{ + dt_prop(dt, name, (char *)&data, sizeof(u32)); +} + +void dt_prop_u64(struct iseries_flat_dt *dt, char *name, u64 data) +{ + dt_prop(dt, name, (char *)&data, sizeof(u64)); +} + +void dt_prop_u64_list(struct iseries_flat_dt *dt, char *name, u64 *data, int n) +{ + dt_prop(dt, name, (char *)data, sizeof(u64) * n); +} + +void dt_prop_empty(struct iseries_flat_dt *dt, char *name) +{ + dt_prop(dt, name, NULL, 0); +} + +void build_flat_dt(struct iseries_flat_dt *dt) +{ + dt_init(dt); + + dt_start_node(dt, ""); + dt_end_node(dt); + + dt_push_u32(dt, OF_DT_END); +} + void __init iSeries_early_setup(void) { iSeries_fixup_klimit(); + + build_flat_dt(&iseries_dt); } From michael at ellerman.id.au Wed Aug 10 14:18:43 2005 From: michael at ellerman.id.au (Michael Ellerman) Date: Wed, 10 Aug 2005 14:18:43 +1000 (EST) Subject: [PATCH 7/10] ppc64: Call early_setup() on iSeries In-Reply-To: <1123647505.420467.500210448555.qpatch@concordia> Message-ID: <20050810041843.1C7FB67FFA@ozlabs.org> Misc steps to incorporate the flat device tree on iSeries. - define iseries_probe() - call build_iSeries_Memory_Map() earlier - return __pa() of the flat device tree from iSeries_early_setup() - actually call early_setup() for iSeries - add iseries_md to machdep_calls - build prom.o for iSeries - enable /proc/device-tree for iSeries Signed-off-by: Michael Ellerman --- arch/ppc64/Kconfig | 1 - arch/ppc64/kernel/Makefile | 4 ++-- arch/ppc64/kernel/head.S | 1 + arch/ppc64/kernel/iSeries_setup.c | 22 +++++++++++++++------- arch/ppc64/kernel/setup.c | 9 ++++----- 5 files changed, 22 insertions(+), 15 deletions(-) Index: work/arch/ppc64/kernel/iSeries_setup.c =================================================================== --- work.orig/arch/ppc64/kernel/iSeries_setup.c +++ work/arch/ppc64/kernel/iSeries_setup.c @@ -359,12 +359,6 @@ static void __init iSeries_init_early(vo */ iommu_init_early_iSeries(); - /* - * Initialize the table which translate Linux physical addresses to - * AS/400 absolute addresses - */ - build_iSeries_Memory_Map(); - iSeries_get_cmdline(); /* Save unparsed command line copy for /proc/cmdline */ @@ -894,6 +888,11 @@ static int iseries_dedicated_idle(void) void __init iSeries_init_IRQ(void) { } #endif +static int __init iseries_probe(int platform) +{ + return PLATFORM_ISERIES_LPAR == platform; +} + struct machdep_calls __initdata iseries_md = { .setup_arch = iSeries_setup_arch, .get_cpuinfo = iSeries_get_cpuinfo, @@ -909,6 +908,7 @@ struct machdep_calls __initdata iseries_ .get_rtc_time = iSeries_get_rtc_time, .calibrate_decr = iSeries_calibrate_decr, .progress = iSeries_progress, + .probe = iseries_probe, /* XXX Implement enable_pmcs for iSeries */ }; @@ -1047,9 +1047,17 @@ void build_flat_dt(struct iseries_flat_d dt_push_u32(dt, OF_DT_END); } -void __init iSeries_early_setup(void) +void * __init iSeries_early_setup(void) { iSeries_fixup_klimit(); + /* + * Initialize the table which translate Linux physical addresses to + * AS/400 absolute addresses + */ + build_iSeries_Memory_Map(); + build_flat_dt(&iseries_dt); + + return (void *) __pa(&iseries_dt); } Index: work/arch/ppc64/kernel/setup.c =================================================================== --- work.orig/arch/ppc64/kernel/setup.c +++ work/arch/ppc64/kernel/setup.c @@ -337,13 +337,11 @@ static void __init setup_cpu_maps(void) } #endif /* CONFIG_SMP */ - -#ifdef CONFIG_PPC_MULTIPLATFORM - extern struct machdep_calls pSeries_md; extern struct machdep_calls pmac_md; extern struct machdep_calls maple_md; extern struct machdep_calls bpa_md; +extern struct machdep_calls iseries_md; /* Ultimately, stuff them in an elf section like initcalls... */ static struct machdep_calls __initdata *machines[] = { @@ -359,6 +357,9 @@ static struct machdep_calls __initdata * #ifdef CONFIG_PPC_BPA &bpa_md, #endif +#ifdef CONFIG_PPC_ISERIES + &iseries_md, +#endif NULL }; @@ -567,8 +568,6 @@ static void __init check_for_initrd(void #endif /* CONFIG_BLK_DEV_INITRD */ } -#endif /* CONFIG_PPC_MULTIPLATFORM */ - /* * Do some initial setup of the system. The parameters are those which * were passed in from the bootloader. Index: work/arch/ppc64/kernel/head.S =================================================================== --- work.orig/arch/ppc64/kernel/head.S +++ work/arch/ppc64/kernel/head.S @@ -1349,6 +1349,7 @@ _STATIC(__start_initialization_iSeries) addi r2,r2,0x4000 bl .iSeries_early_setup + bl .early_setup /* relocation is on at this point */ Index: work/arch/ppc64/Kconfig =================================================================== --- work.orig/arch/ppc64/Kconfig +++ work/arch/ppc64/Kconfig @@ -357,7 +357,6 @@ config HOTPLUG_CPU config PROC_DEVICETREE bool "Support for Open Firmware device tree in /proc" - depends on !PPC_ISERIES help This option adds a device-tree directory under /proc which contains an image of the device tree that the kernel copies from Open Index: work/arch/ppc64/kernel/Makefile =================================================================== --- work.orig/arch/ppc64/kernel/Makefile +++ work/arch/ppc64/kernel/Makefile @@ -11,7 +11,7 @@ obj-y := setup.o entry.o t udbg.o binfmt_elf32.o sys_ppc32.o ioctl32.o \ ptrace32.o signal32.o rtc.o init_task.o \ lmb.o cputable.o cpu_setup_power4.o idle_power4.o \ - iommu.o sysfs.o vdso.o pmc.o firmware.o + iommu.o sysfs.o vdso.o pmc.o firmware.o prom.o obj-y += vdso32/ vdso64/ obj-$(CONFIG_PPC_OF) += of_device.o @@ -27,7 +27,7 @@ obj-$(CONFIG_PPC_ISERIES) += HvCall.o Hv mf.o HvLpEvent.o iSeries_proc.o iSeries_htab.o \ iSeries_iommu.o -obj-$(CONFIG_PPC_MULTIPLATFORM) += nvram.o i8259.o prom_init.o prom.o +obj-$(CONFIG_PPC_MULTIPLATFORM) += nvram.o i8259.o prom_init.o obj-$(CONFIG_PPC_PSERIES) += pSeries_pci.o pSeries_lpar.o pSeries_hvCall.o \ pSeries_nvram.o rtasd.o ras.o pSeries_reconfig.o \ From michael at ellerman.id.au Wed Aug 10 14:18:44 2005 From: michael at ellerman.id.au (Michael Ellerman) Date: Wed, 10 Aug 2005 14:18:44 +1000 (EST) Subject: [PATCH 8/10] ppc64: Move memory setup into iSeries device tree In-Reply-To: <1123647505.420467.500210448555.qpatch@concordia> Message-ID: <20050810041844.45E7D67FF8@ozlabs.org> This patch adds the required nodes to the iSeries device tree to allow early_init_devtree() to do the lmb setup for us. Signed-off-by: Michael Ellerman --- arch/ppc64/kernel/iSeries_setup.c | 20 +++++++++++++++----- 1 files changed, 15 insertions(+), 5 deletions(-) Index: work/arch/ppc64/kernel/iSeries_setup.c =================================================================== --- work.orig/arch/ppc64/kernel/iSeries_setup.c +++ work/arch/ppc64/kernel/iSeries_setup.c @@ -376,11 +376,6 @@ static void __init iSeries_init_early(vo } } - lmb_init(); - lmb_add(0, systemcfg->physicalMemorySize); - lmb_analyze(); - lmb_reserve(0, __pa(klimit)); - /* Initialize machine-dependency vectors */ #ifdef CONFIG_SMP smp_init_iSeries(); @@ -1039,9 +1034,24 @@ void dt_prop_empty(struct iseries_flat_d void build_flat_dt(struct iseries_flat_dt *dt) { + u64 tmp[2]; + dt_init(dt); dt_start_node(dt, ""); + + dt_prop_u32(dt, "#address-cells", 2); + dt_prop_u32(dt, "#size-cells", 2); + + /* /memory */ + dt_start_node(dt, "memory at 0"); + dt_prop_str(dt, "name", "memory"); + dt_prop_str(dt, "device_type", "memory"); + tmp[0] = 0; + tmp[1] = systemcfg->physicalMemorySize; + dt_prop_u64_list(dt, "reg", tmp, 2); + dt_end_node(dt); + dt_end_node(dt); dt_push_u32(dt, OF_DT_END); From michael at ellerman.id.au Wed Aug 10 14:18:45 2005 From: michael at ellerman.id.au (Michael Ellerman) Date: Wed, 10 Aug 2005 14:18:45 +1000 (EST) Subject: [PATCH 9/10] ppc64: Move setup of systemcfg->platform into iSeries device tree In-Reply-To: <1123647505.420467.500210448555.qpatch@concordia> Message-ID: <20050810041845.2310467FF8@ozlabs.org> Add /chosen/linux,platform to the device tree so we can remove iSeries specific code in setup_system() to set systemcfg->platform. Signed-off-by: Michael Ellerman --- arch/ppc64/kernel/iSeries_setup.c | 5 +++++ arch/ppc64/kernel/setup.c | 9 --------- 2 files changed, 5 insertions(+), 9 deletions(-) Index: work/arch/ppc64/kernel/iSeries_setup.c =================================================================== --- work.orig/arch/ppc64/kernel/iSeries_setup.c +++ work/arch/ppc64/kernel/iSeries_setup.c @@ -1052,6 +1052,11 @@ void build_flat_dt(struct iseries_flat_d dt_prop_u64_list(dt, "reg", tmp, 2); dt_end_node(dt); + /* /chosen */ + dt_start_node(dt, "chosen"); + dt_prop_u32(dt, "linux,platform", PLATFORM_ISERIES_LPAR); + dt_end_node(dt); + dt_end_node(dt); dt_push_u32(dt, OF_DT_END); Index: work/arch/ppc64/kernel/setup.c =================================================================== --- work.orig/arch/ppc64/kernel/setup.c +++ work/arch/ppc64/kernel/setup.c @@ -576,14 +576,6 @@ void __init setup_system(void) { DBG(" -> setup_system()\n"); -#ifdef CONFIG_PPC_ISERIES - /* pSeries systems are identified in prom.c via OF. */ - if (itLpNaca.xLparInstalled == 1) - systemcfg->platform = PLATFORM_ISERIES_LPAR; - - ppc_md.init_early(); -#else /* CONFIG_PPC_ISERIES */ - /* * Unflatten the device-tree passed by prom_init or kexec */ @@ -642,7 +634,6 @@ void __init setup_system(void) strlcpy(saved_command_line, cmd_line, COMMAND_LINE_SIZE); parse_early_param(); -#endif /* !CONFIG_PPC_ISERIES */ #ifdef CONFIG_SMP /* From michael at ellerman.id.au Wed Aug 10 14:18:48 2005 From: michael at ellerman.id.au (Michael Ellerman) Date: Wed, 10 Aug 2005 14:18:48 +1000 (EST) Subject: [PATCH 10/10] ppc64: Define /cpus in iSeries device tree In-Reply-To: <1123647505.420467.500210448555.qpatch@concordia> Message-ID: <20050810041848.F16BE68014@ozlabs.org> Add the /cpus node and nodes for each cpu, as well as cache size properties, reg propery, "linux,boot-cpu", and timebase/clock frequency. With those properties in place we can remove: - setup_iSeries_cache_sizes() - code in iSeries_setup_arch() to calculate timebase etc. - iSeries_calibrate_decr() - smp_iSeries_numProcs() and simplify smp_iSeries_probe() Signed-off-by: Michael Ellerman --- arch/ppc64/kernel/iSeries_setup.c | 178 +++++++++++--------------------------- arch/ppc64/kernel/iSeries_smp.c | 30 ------ arch/ppc64/kernel/time.c | 2 3 files changed, 57 insertions(+), 153 deletions(-) Index: work/arch/ppc64/kernel/iSeries_setup.c =================================================================== --- work.orig/arch/ppc64/kernel/iSeries_setup.c +++ work/arch/ppc64/kernel/iSeries_setup.c @@ -74,7 +74,6 @@ extern void hvlog(char *fmt, ...); extern void ppcdbg_initialize(void); static void build_iSeries_Memory_Map(void); -static void setup_iSeries_cache_sizes(void); static int iseries_shared_idle(void); static int iseries_dedicated_idle(void); #ifdef CONFIG_PCI @@ -84,14 +83,6 @@ static void iSeries_pci_final_fixup(void #endif /* Global Variables */ -static unsigned long procFreqHz; -static unsigned long procFreqMhz; -static unsigned long procFreqMhzHundreths; - -static unsigned long tbFreqHz; -static unsigned long tbFreqMhz; -static unsigned long tbFreqMhzHundreths; - int piranha_simulator; extern int rd_size; /* Defined in drivers/block/rd.c */ @@ -344,12 +335,6 @@ static void __init iSeries_init_early(vo iSeries_recal_titan = HvCallXm_loadTod(); /* - * Cache sizes must be initialized before hpte_init_iSeries is called - * as the later need them for flush_icache_range() - */ - setup_iSeries_cache_sizes(); - - /* * Initialize the hash table management pointers */ hpte_init_iSeries(); @@ -581,47 +566,6 @@ static void __init build_iSeries_Memory_ } /* - * Set up the variables that describe the cache line sizes - * for this machine. - */ -static void __init setup_iSeries_cache_sizes(void) -{ - unsigned int i, n; - unsigned int procIx = get_paca()->lppaca.dyn_hv_phys_proc_index; - - systemcfg->icache_size = - ppc64_caches.isize = xIoHriProcessorVpd[procIx].xInstCacheSize * 1024; - systemcfg->icache_line_size = - ppc64_caches.iline_size = - xIoHriProcessorVpd[procIx].xInstCacheOperandSize; - systemcfg->dcache_size = - ppc64_caches.dsize = - xIoHriProcessorVpd[procIx].xDataL1CacheSizeKB * 1024; - systemcfg->dcache_line_size = - ppc64_caches.dline_size = - xIoHriProcessorVpd[procIx].xDataCacheOperandSize; - ppc64_caches.ilines_per_page = PAGE_SIZE / ppc64_caches.iline_size; - ppc64_caches.dlines_per_page = PAGE_SIZE / ppc64_caches.dline_size; - - i = ppc64_caches.iline_size; - n = 0; - while ((i = (i / 2))) - ++n; - ppc64_caches.log_iline_size = n; - - i = ppc64_caches.dline_size; - n = 0; - while ((i = (i / 2))) - ++n; - ppc64_caches.log_dline_size = n; - - printk("D-cache line size = %d\n", - (unsigned int)ppc64_caches.dline_size); - printk("I-cache line size = %d\n", - (unsigned int)ppc64_caches.iline_size); -} - -/* * Document me. */ static void __init iSeries_setup_arch(void) @@ -636,36 +580,14 @@ static void __init iSeries_setup_arch(vo printk(KERN_INFO "Using dedicated idle loop\n"); } - /* Add an eye catcher and the systemcfg layout version number */ - strcpy(systemcfg->eye_catcher, "SYSTEMCFG:PPC64"); - systemcfg->version.major = SYSTEMCFG_MAJOR; - systemcfg->version.minor = SYSTEMCFG_MINOR; - /* Setup the Lp Event Queue */ setup_hvlpevent_queue(); - /* Compute processor frequency */ - procFreqHz = ((1UL << 34) * 1000000) / - xIoHriProcessorVpd[procIx].xProcFreq; - procFreqMhz = procFreqHz / 1000000; - procFreqMhzHundreths = (procFreqHz / 10000) - (procFreqMhz * 100); - ppc_proc_freq = procFreqHz; - - /* Compute time base frequency */ - tbFreqHz = ((1UL << 32) * 1000000) / - xIoHriProcessorVpd[procIx].xTimeBaseFreq; - tbFreqMhz = tbFreqHz / 1000000; - tbFreqMhzHundreths = (tbFreqHz / 10000) - (tbFreqMhz * 100); - ppc_tb_freq = tbFreqHz; - printk("Max logical processors = %d\n", itVpdAreas.xSlicMaxLogicalProcs); printk("Max physical processors = %d\n", itVpdAreas.xSlicMaxPhysicalProcs); - printk("Processor frequency = %lu.%02lu\n", procFreqMhz, - procFreqMhzHundreths); - printk("Time base frequency = %lu.%02lu\n", tbFreqMhz, - tbFreqMhzHundreths); + systemcfg->processor = xIoHriProcessorVpd[procIx].xPVR; printk("Processor version = %x\n", systemcfg->processor); } @@ -709,49 +631,6 @@ static void iSeries_halt(void) mf_power_off(); } -/* - * void __init iSeries_calibrate_decr() - * - * Description: - * This routine retrieves the internal processor frequency from the VPD, - * and sets up the kernel timer decrementer based on that value. - * - */ -static void __init iSeries_calibrate_decr(void) -{ - unsigned long cyclesPerUsec; - struct div_result divres; - - /* Compute decrementer (and TB) frequency in cycles/sec */ - cyclesPerUsec = ppc_tb_freq / 1000000; - - /* - * Set the amount to refresh the decrementer by. This - * is the number of decrementer ticks it takes for - * 1/HZ seconds. - */ - tb_ticks_per_jiffy = ppc_tb_freq / HZ; - -#if 0 - /* TEST CODE FOR ADJTIME */ - tb_ticks_per_jiffy += tb_ticks_per_jiffy / 5000; - /* END OF TEST CODE */ -#endif - - /* - * tb_ticks_per_sec = freq; would give better accuracy - * but tb_ticks_per_sec = tb_ticks_per_jiffy*HZ; assures - * that jiffies (and xtime) will match the time returned - * by do_gettimeofday. - */ - tb_ticks_per_sec = tb_ticks_per_jiffy * HZ; - tb_ticks_per_usec = cyclesPerUsec; - tb_to_us = mulhwu_scale_factor(ppc_tb_freq, 1000000); - div128_by_32(1024 * 1024, 0, tb_ticks_per_sec, &divres); - tb_to_xs = divres.result_low; - setup_default_decr(); -} - static void __init iSeries_progress(char * st, unsigned short code) { printk("Progress: [%04x] - %s\n", (unsigned)code, st); @@ -901,7 +780,7 @@ struct machdep_calls __initdata iseries_ .get_boot_time = iSeries_get_boot_time, .set_rtc_time = iSeries_set_rtc_time, .get_rtc_time = iSeries_get_rtc_time, - .calibrate_decr = iSeries_calibrate_decr, + .calibrate_decr = generic_calibrate_decr, .progress = iSeries_progress, .probe = iseries_probe, /* XXX Implement enable_pmcs for iSeries */ @@ -1032,6 +911,57 @@ void dt_prop_empty(struct iseries_flat_d dt_prop(dt, name, NULL, 0); } +void dt_cpus(struct iseries_flat_dt *dt) +{ + unsigned char buf[32]; + unsigned char *p; + unsigned int i, index; + struct IoHriProcessorVpd *d; + + /* yuck */ + snprintf(buf, 32, "PowerPC,%s", cur_cpu_spec->cpu_name); + p = strchr(buf, ' '); + if (!p) p = buf + strlen(buf); + + dt_start_node(dt, "cpus"); + dt_prop_u32(dt, "#address-cells", 1); + dt_prop_u32(dt, "#size-cells", 0); + + for (i = 0; i < NR_CPUS; i++) { + if (paca[i].lppaca.dyn_proc_status >= 2) + continue; + + snprintf(p, 32 - (p - buf), "@%d", i); + dt_start_node(dt, buf); + + dt_prop_str(dt, "device_type", "cpu"); + + index = paca[i].lppaca.dyn_hv_phys_proc_index; + d = &xIoHriProcessorVpd[index]; + + dt_prop_u32(dt, "i-cache-size", d->xInstCacheSize * 1024); + dt_prop_u32(dt, "i-cache-line-size", d->xInstCacheOperandSize); + + dt_prop_u32(dt, "d-cache-size", d->xDataL1CacheSizeKB * 1024); + dt_prop_u32(dt, "d-cache-line-size", d->xDataCacheOperandSize); + + /* magic conversions to Hz copied from old code */ + dt_prop_u32(dt, "clock-frequency", + ((1UL << 34) * 1000000) / d->xProcFreq); + dt_prop_u32(dt, "timebase-frequency", + ((1UL << 32) * 1000000) / d->xTimeBaseFreq); + + dt_prop_u32(dt, "reg", i); + + if (dt->header.boot_cpuid_phys == i) + dt_prop_empty(dt, "linux,boot-cpu"); + + dt_end_node(dt); + } + + dt_end_node(dt); +} + void build_flat_dt(struct iseries_flat_dt *dt) { u64 tmp[2]; @@ -1057,6 +987,8 @@ void build_flat_dt(struct iseries_flat_d dt_prop_u32(dt, "linux,platform", PLATFORM_ISERIES_LPAR); dt_end_node(dt); + dt_cpus(dt); + dt_end_node(dt); dt_push_u32(dt, OF_DT_END); Index: work/arch/ppc64/kernel/iSeries_smp.c =================================================================== --- work.orig/arch/ppc64/kernel/iSeries_smp.c +++ work/arch/ppc64/kernel/iSeries_smp.c @@ -82,35 +82,9 @@ static void smp_iSeries_message_pass(int } } -static int smp_iSeries_numProcs(void) -{ - unsigned np, i; - - np = 0; - for (i=0; i < NR_CPUS; ++i) { - if (paca[i].lppaca.dyn_proc_status < 2) { - cpu_set(i, cpu_possible_map); - cpu_set(i, cpu_present_map); - cpu_set(i, cpu_sibling_map[i]); - ++np; - } - } - return np; -} - static int smp_iSeries_probe(void) { - unsigned i; - unsigned np = 0; - - for (i=0; i < NR_CPUS; ++i) { - if (paca[i].lppaca.dyn_proc_status < 2) { - /*paca[i].active = 1;*/ - ++np; - } - } - - return np; + return cpus_weight(cpu_possible_map); } static void smp_iSeries_kick_cpu(int nr) @@ -144,6 +118,4 @@ static struct smp_ops_t iSeries_smp_ops void __init smp_init_iSeries(void) { smp_ops = &iSeries_smp_ops; - systemcfg->processorCount = smp_iSeries_numProcs(); } - Index: work/arch/ppc64/kernel/time.c =================================================================== --- work.orig/arch/ppc64/kernel/time.c +++ work/arch/ppc64/kernel/time.c @@ -471,7 +471,7 @@ int do_settimeofday(struct timespec *tv) EXPORT_SYMBOL(do_settimeofday); -#if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_MAPLE) || defined(CONFIG_PPC_BPA) +#if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_MAPLE) || defined(CONFIG_PPC_BPA) || defined(CONFIG_PPC_ISERIES) void __init generic_calibrate_decr(void) { struct device_node *cpu; From david at gibson.dropbear.id.au Wed Aug 10 14:33:48 2005 From: david at gibson.dropbear.id.au (David Gibson) Date: Wed, 10 Aug 2005 14:33:48 +1000 Subject: [PATCH 4/10] ppc64: Make stab_initialize() work on iSeries In-Reply-To: <20050810041836.234EF67FC1@ozlabs.org> References: <1123647505.420467.500210448555.qpatch@concordia> <20050810041836.234EF67FC1@ozlabs.org> Message-ID: <20050810043348.GD22335@localhost.localdomain> On Wed, Aug 10, 2005 at 02:18:36PM +1000, Michael Ellerman wrote: > We don't need to call stab_initialize() for the boot cpu on iSeries, so > we hack around it so that early_setup() can be called on iSeries. I'd suggest just folding the firmware_has_feature() logic into early_setup, rather than having the trivial function. -- David Gibson | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/people/dgibson From miltonm at bga.com Wed Aug 10 14:51:24 2005 From: miltonm at bga.com (Milton Miller) Date: Tue, 9 Aug 2005 23:51:24 -0500 Subject: [Fwd: [PATCH] PPC64: large INITRD causes kernel not to boot] Message-ID: <1b082f286ff07d6348211697ef38a608@bga.com> > > - printf("\n\rzImage starting: loaded at 0x%x\n\r", (unsigned)_start); > + printf("\n\rzImage starting: loaded at 0x%lx\n\r", (unsigned long) > _start); > + > + /* > + * The first available claim_base must be above the end of the > + * the loaded kernel file (_start to _end) and rounded up to a > + * nice 1 MB boundary. > + */ > + > + claim_base = ((((unsigned long) _end) + ONE_MB - 1) / ONE_MB) * > ONE_MB; > > _start and _end here are the linked runtime range of the zImage program not the kernel image contained therein. This also contains the initrd. Milton From michael at ellerman.id.au Wed Aug 10 15:40:12 2005 From: michael at ellerman.id.au (Michael Ellerman) Date: Wed, 10 Aug 2005 15:40:12 +1000 Subject: [PATCH 4/10] ppc64: Make stab_initialize() work on iSeries In-Reply-To: <20050810043348.GD22335@localhost.localdomain> References: <1123647505.420467.500210448555.qpatch@concordia> <20050810041836.234EF67FC1@ozlabs.org> <20050810043348.GD22335@localhost.localdomain> Message-ID: <200508101540.13220.michael@ellerman.id.au> On Wed, 10 Aug 2005 14:33, David Gibson wrote: > On Wed, Aug 10, 2005 at 02:18:36PM +1000, Michael Ellerman wrote: > > We don't need to call stab_initialize() for the boot cpu on iSeries, so > > we hack around it so that early_setup() can be called on iSeries. > > I'd suggest just folding the firmware_has_feature() logic into > early_setup, rather than having the trivial function. Yeah, duh. That evolved from a different hack which is why it's the way it was, but I should have cleaned it up. --- We don't need to call stab_initialize() for the boot cpu on iSeries, so we hack around it so that early_setup() can be called on iSeries. Signed-off-by: Michael Ellerman --- We don't need to call stab_initialize() for the boot cpu on iSeries, so we hack around it so that early_setup() can be called on iSeries. arch/ppc64/kernel/setup.c | 4 +++- 1 files changed, 3 insertions(+), 1 deletion(-) Index: work/arch/ppc64/kernel/setup.c =================================================================== --- work.orig/arch/ppc64/kernel/setup.c +++ work/arch/ppc64/kernel/setup.c @@ -58,6 +58,7 @@ #include #include #include +#include #ifdef DEBUG #define DBG(fmt...) udbg_printf(fmt) @@ -436,7 +437,8 @@ void __init early_setup(unsigned long dt /* * Initialize stab / SLB management */ - stab_initialize(lpaca->stab_real); + if (!firmware_has_feature(FW_FEATURE_ISERIES)) + stab_initialize(lpaca->stab_real); /* * Initialize the MMU Hash table and create the linear mapping From miltonm at bga.com Wed Aug 10 17:16:15 2005 From: miltonm at bga.com (Milton Miller) Date: Wed, 10 Aug 2005 02:16:15 -0500 Subject: [PATCH 6/10] ppc64: Create a fake flat device tree on iSeries Message-ID: <6b57499e431cefc69e65db59b4210b38@bga.com> 1) These funtions would seem to be infrastucture, do they belong in iSeries_setup? I note that they are not declared static. 2) checking the blob afterwards is likely buggy because if we add more than 4 bytes, we will overwrite the next pointer and inc the data therein before we realize that we overwrote the pointer. a) move pointer before blob data b) move check before set, and pass size to check c) see #6 3) dt_prop is not checking if the property name already exists, wasting string space. While this may not be an issue in small usage so far, there are obviously replacated strings (cpu propertys, but also things like "name"). 4) While the blob size is arbitaray, a structure PAGE_SIZE + u64 is a bit odd. In fact if we swtich to only saving the string table it makes it take 2 pages instead of one. 5) If you are going to statically allocate this for iSeries (as opossed to say a klimit bump), then the only thing in dynamic is setting the boot cpuid. May as well use a static initializer. Today this would add over 2 pages of bss for a "combined" kernel. 6) I suggest using propnum from fs2dt.c for #3 and open coding the checks for overflow against the device tree fields. Putting the device data at klimit would allow the checks for overflow to be deferred until after its created (look for 2 nuls in string table -- the size is propnum(""), and placing data at after the reserve map and string table and either compare to total size or set totalsize according to what is used). From miltonm at bga.com Wed Aug 10 17:28:39 2005 From: miltonm at bga.com (Milton Miller) Date: Wed, 10 Aug 2005 02:28:39 -0500 Subject: [PATCH 10/10] ppc64: Define /cpus in iSeries device tree Message-ID: <70d7f1742008670680e112aee39d2db9@bga.com> > > +void dt_cpus(struct iseries_flat_dt *dt)+{ > + unsigned char buf[32]; ... > + > + /* yuck */ > + snprintf(buf, 32, "PowerPC,%s", cur_cpu_spec->cpu_name); > + p = strchr(buf, ' '); > + if (!p) p = buf + strlen(buf); ... > + for (i = 0; i < NR_CPUS; i++) { ... > + snprintf(p, 32 - (p - buf), "@%d", i); > + dt_start_node(dt, buf); The magic number number 32 occurs at least 3 times in this context, but later a different magic 32 occurs in this function. The math for second one takes thought to verify. How about just calculating the length of the desired part of the cpu name and then doing a single snprintf with a %*s counted length string? Alternatively, a private copy of the desired portion might be clearer code. We might also want to warn if we get 32 chars and/or limit the length so that we are sure to have room for the instance address. Something like (totally untested): snprintf(buf, sizeof(buf), "PowerPC,%*s@%d", cpunamelen, cur_cpu_spec->cpu_name, i); milton From paulus at samba.org Wed Aug 10 18:24:09 2005 From: paulus at samba.org (Paul Mackerras) Date: Wed, 10 Aug 2005 18:24:09 +1000 Subject: [PATCH] [3/4] PPC64: PAGE_SIZE constants in copyuser.S and copypage.S In-Reply-To: <20050809202329.GD30589@austin.ibm.com> References: <20050809202007.GA30589@austin.ibm.com> <20050809202329.GD30589@austin.ibm.com> Message-ID: <17145.47529.108458.602653@cargo.ozlabs.ibm.com> Olof Johansson writes: > Replace some of the hardcoded constants in copypage and copyuser to > be based on PAGE_SIZE. Also change the assembly where needed to deal > with larger values of PAGE_SIZE. The bulk copy routine in __copy_tofrom_user was designed for doing 4096 bytes at a time on cacheline-aligned sources and destinations. We should extend it to do any multiple of 4096 bytes, I think. Regards, Paul. From david at gibson.dropbear.id.au Wed Aug 10 18:32:28 2005 From: david at gibson.dropbear.id.au (David Gibson) Date: Wed, 10 Aug 2005 18:32:28 +1000 Subject: [PATCH 6/10] ppc64: Create a fake flat device tree on iSeries In-Reply-To: <6b57499e431cefc69e65db59b4210b38@bga.com> References: <6b57499e431cefc69e65db59b4210b38@bga.com> Message-ID: <20050810083228.GE22335@localhost.localdomain> On Wed, Aug 10, 2005 at 02:16:15AM -0500, Milton Miller wrote: > 1) These funtions would seem to be infrastucture, do they belong in > iSeries_setup? I note that they are not declared static. > > 2) checking the blob afterwards is likely buggy because if we add > more than 4 bytes, we will overwrite the next pointer and inc the > data therein before we realize that we overwrote the pointer. > a) move pointer before blob data > b) move check before set, and pass size to check > c) see #6 > > 3) dt_prop is not checking if the property name already exists, > wasting string space. While this may not be an issue in small usage > so far, there are obviously replacated strings (cpu propertys, but > also things like "name"). We need to weight the space-wastage of duplicated strings against either the extra complexity of a lookup table, or the time expenditure of scanning the whole string table on every dt_prop(). > 4) While the blob size is arbitaray, a structure PAGE_SIZE + u64 > is a bit odd. In fact if we swtich to only saving the string table > it makes it take 2 pages instead of one. > > 5) If you are going to statically allocate this for iSeries (as > opossed to say a klimit bump), then the only thing in dynamic is > setting the boot cpuid. May as well use a static initializer. > > Today this would add over 2 pages of bss for a "combined" kernel. I think you'll find there are patches coming making more stuff dynamic. Virtual devices, in particular. > 6) I suggest using propnum from fs2dt.c for #3 and open coding the > checks for overflow against the device tree fields. Better yet, use the string insert function from libdt included in the dtc sources (which probably amounts to almos the same thing). > Putting the > device data at klimit would allow the checks for overflow to be > deferred until after its created (look for 2 nuls in string table > -- the size is propnum(""), and placing data at after the reserve > map and string table and either compare to total size or set > totalsize according to what is used). Hrm.. actually.. this may be too irritatingly inflexible, but since the iseries device tree is pretty limited in what it contains, it would potentially be possible to statically initialize a string table containing every property name iSeries might ever use. In fact, doing it that way you could generate the skeleton of the device tree with dtc (asm output mode), leaving some space in the structure section, then add in the dynamic structure at runtime. (I'd need to add something to dtc to allow you to force a string into the string section even if it's not used in the tree, of course, but that should be easy) -- David Gibson | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/people/dgibson From benh at kernel.crashing.org Wed Aug 10 19:12:09 2005 From: benh at kernel.crashing.org (Benjamin Herrenschmidt) Date: Wed, 10 Aug 2005 11:12:09 +0200 Subject: [PATCH] ppc64: Fix Fan control for new PowerMac G5 2.7GHz machines Message-ID: <1123665129.30257.219.camel@gaston> Hi ! It would be nice if that bug fix could still sneak into 2.6.13 ... The workaround for broken device-tree that prevents fan control from working on recent G5 models need to be "enabled" for machines with revision 0x37 of the bridge in addition to machines with revision 0x35. Signed-off-by: Geoff Levand Signed-off-by: Benjamin Herrenschmidt --- a/arch/ppc64/kernel/prom_init.c 2005-07-27 18:34:40.000000000 -0700 +++ b/arch/ppc64/kernel/prom_init.c 2005-08-09 16:18:04.000000000 -0700 @@ -1803,7 +1803,7 @@ if (prom_getprop(u3, "device-rev", &u3_rev, sizeof(u3_rev)) == PROM_ERROR) return; - if (u3_rev != 0x35) + if (u3_rev != 0x35 && u3_rev != 0x37) return; /* does it need fixup ? */ if (prom_getproplen(i2c, "interrupts") > 0) From benh at kernel.crashing.org Wed Aug 10 19:15:03 2005 From: benh at kernel.crashing.org (Benjamin Herrenschmidt) Date: Wed, 10 Aug 2005 11:15:03 +0200 Subject: [RFC] addnote and pmac In-Reply-To: <42F91AB6.8050309@am.sony.com> References: <1123576274.30257.152.camel@gaston> <42F91AB6.8050309@am.sony.com> Message-ID: <1123665304.30257.221.camel@gaston> On Tue, 2005-08-09 at 14:05 -0700, Geoff Levand wrote: > > It seems both you and Olaf suggested to make two build targets, so I set > them up as zImage and zImage.rs6k. > > I wonder if we could use zImage.real, since I imagine any OF machine > would need one or the other, or are there other machine specific things > needed by others? I'm not fan of "zImage.real" as a name though :) Ben. From segher at kernel.crashing.org Wed Aug 10 20:15:09 2005 From: segher at kernel.crashing.org (Segher Boessenkool) Date: Wed, 10 Aug 2005 12:15:09 +0200 Subject: Merging ppc32 and ppc64 In-Reply-To: <17145.13414.996858.522127@cargo.ozlabs.ibm.com> References: <17136.13558.773102.465379@cargo.ozlabs.ibm.com> <42F79D89.3040709@austin.ibm.com> <17145.13414.996858.522127@cargo.ozlabs.ibm.com> Message-ID: > It is already the case (and has always been the case) that you can't > boot a vmlinux image directly from OF - there is always either or both > of yaboot or a zImage wrapper in between anyway. If you fix the ELF headers, you can boot a vmlinux directly from OF just fine. I agree getting rid of all that RELOC() stuff is a worthy goal; I just hope there's a better way to do it... Anyway, I'm not going to stand in you guys way -- please just don't make it harder for me without reason, though. Segher From benh at kernel.crashing.org Wed Aug 10 20:30:21 2005 From: benh at kernel.crashing.org (Benjamin Herrenschmidt) Date: Wed, 10 Aug 2005 12:30:21 +0200 Subject: New Dual 2ghz Powermac G5 In-Reply-To: <42F914B7.8010208@cisco.com> References: <42F914B7.8010208@cisco.com> Message-ID: <1123669822.30257.228.camel@gaston> On Tue, 2005-08-09 at 16:40 -0400, Keith Mitchell wrote: > I just got in a bunch of new Dual 2.0ghz Powermacs and one out of the > bunch so far has a noisy fan problem. I have been loading YDL 4.0.91 > which has kernel 2.6.12 plus some patches and I did go back and verify > that it had the last patch I saw related to this > (http://patchwork.ozlabs.org/linuxppc64/patch?id=846). All of the > machines all identify themselves as running OpenFirmware 5.2.4f1 and all > came in at once with the same config. > > The machine with the problem so far issues the following messages: > > kernel: /u3 at 0,f8000000/i2c at f8001000: Missing interrupt or address ! > kernel: /u3 at 0,f8000000/i2c at f8001000: Missing interrupt or address ! > kernel: /u3 at 0,f8000000/i2c at f8001000: Missing interrupt or address ! > kernel: /u3 at 0,f8000000/i2c at f8001000: Missing interrupt or address ! > > > Is this a known issue? Yes, here is the fix: The workaround for broken device-tree that prevents fan control from working on recent G5 models need to be "enabled" for machines with revision 0x37 of the bridge in addition to machines with revision 0x35. Signed-off-by: Geoff Levand Signed-off-by: Benjamin Herrenschmidt --- a/arch/ppc64/kernel/prom_init.c 2005-07-27 18:34:40.000000000 -0700 +++ b/arch/ppc64/kernel/prom_init.c 2005-08-09 16:18:04.000000000 -0700 @@ -1803,7 +1803,7 @@ if (prom_getprop(u3, "device-rev", &u3_rev, sizeof(u3_rev)) == PROM_ERROR) return; - if (u3_rev != 0x35) + if (u3_rev != 0x35 && u3_rev != 0x37) return; /* does it need fixup ? */ if (prom_getproplen(i2c, "interrupts") > 0) From benh at kernel.crashing.org Wed Aug 10 20:51:25 2005 From: benh at kernel.crashing.org (Benjamin Herrenschmidt) Date: Wed, 10 Aug 2005 12:51:25 +0200 Subject: Merging ppc32 and ppc64 In-Reply-To: <17145.12993.672427.466466@cargo.ozlabs.ibm.com> References: <17136.13558.773102.465379@cargo.ozlabs.ibm.com> <42F79D89.3040709@austin.ibm.com> <17145.12993.672427.466466@cargo.ozlabs.ibm.com> Message-ID: <1123671086.30257.231.camel@gaston> > Having the flattened device tree doesn't mean that we will be using > the device tree less, it means we will be using it _more_. The reason Segher is freaking out is because he wants to keep OF alive in the future while the kernel is running.... (at least with SLOF) I think that would require a different entry point with no flattened tree, and changing of all the OF accessors to call OF instead of walking an in-kernel tree. That is far from our current target though. Ben. From olh at suse.de Wed Aug 10 21:02:24 2005 From: olh at suse.de (Olaf Hering) Date: Wed, 10 Aug 2005 13:02:24 +0200 Subject: [PATCH] PPC64: Fix non-LPAR IOMMU table allocation on pSeries In-Reply-To: <20050810032437.GC6300@austin.ibm.com> References: <20050810032437.GC6300@austin.ibm.com> Message-ID: <20050810110224.GA15674@suse.de> On Tue, Aug 09, Olof Johansson wrote: > Hi, > > This is for the 2.6.14 feed. I wouldn't recommend pushing it into > 2.6.13 due to risk of regressing some box that I don't have access to > for testing. > > I'd appreciate it if people with pre-POWER5, non-LPAR machines would give > this a go on their boxes and let me know if something falls apart. It's > been tested on an F80 and a p650 (SMP mode) here. p615 and p630 have > been sore spots in the past. This does not help a p660. [boot]0100 MM Init [boot]0100 MM Init Done Linux version 2.6.13-rc6 (olaf at pomegranate) (gcc version 3.3.3 (SuSE Linux)) #2 SMP Wed Aug 10 09:57:26 CEST 2005 [boot]0012 Setup Arch Top of RAM: 0x180000000, Total RAM: 0x180000000 Memory hole size: 0MB Syscall map setup, 242 32 bits and 218 64 bits syscalls EEH: No capable adapters found PPC64 nvram contains 262144 bytes Using default idle loop [boot]0015 Setup Done Built 1 zonelists Kernel command line: root=/dev/sda3 ro init=/bin/bash --login [boot]0020 XICS Init [boot]0021 XICS Done PID hash table entries: 4096 (order: 12, 131072 bytes) time_init: decrementer frequency = 668.945632 MHz time_init: processor frequency = 668.980000 MHz this is arch/ppc64/defconfig From miltonm at bga.com Wed Aug 10 23:59:51 2005 From: miltonm at bga.com (Milton Miller) Date: Wed, 10 Aug 2005 08:59:51 -0500 Subject: [PATCH 6/10] ppc64: Create a fake flat device tree on iSeries In-Reply-To: <20050810083228.GE22335@localhost.localdomain> References: <6b57499e431cefc69e65db59b4210b38@bga.com> <20050810083228.GE22335@localhost.localdomain> Message-ID: On Aug 10, 2005, at 3:32 AM, David Gibson wrote: > On Wed, Aug 10, 2005 at 02:16:15AM -0500, Milton Miller wrote: >> >> 5) If you are going to statically allocate this for iSeries (as >> opossed to say a klimit bump), then the only thing in dynamic is >> setting the boot cpuid. May as well use a static initializer. >> >> Today this would add over 2 pages of bss for a "combined" kernel. > > I think you'll find there are patches coming making more stuff > dynamic. Virtual devices, in particular. Sorry, wasn't trying to imply making the whole tree static, just the header. But I would rather see it allocated at klimit ... > >> Putting the >> device data at klimit would allow the checks for overflow to be >> deferred until after its created (look for 2 nuls in string table >> -- the size is propnum(""), and placing data at after the reserve >> map and string table and either compare to total size or set >> totalsize according to what is used). > > Hrm.. actually.. this may be too irritatingly inflexible, but since > the iseries device tree is pretty limited in what it contains, it > would potentially be possible to statically initialize a string table > containing every property name iSeries might ever use. In fact, doing > it that way you could generate the skeleton of the device tree with > dtc (asm output mode), leaving some space in the structure section, > then add in the dynamic structure at runtime. (I'd need to add > something to dtc to allow you to force a string into the string > section even if it's not used in the tree, of course, but that should > be easy) My other generator does this very thing. The strings are allocated statically. While discussing embedded with panto on #mklinux, another approach is to say "here's the max", put the strings at the end, and allocate new strings down moving the start as we add strings. Makes sense for fw where there is a fixed allocation. End of blob processing can then memmove the string table and cut total size down. Even without the knowing the max size realloc could move strings down if a space check is added before extending the dt blob. > > -- > David Gibson | I'll have my music baroque, and my code > david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ > _other_ > | _way_ _around_! > http://www.ozlabs.org/people/dgibson > From mbellon at mvista.com Thu Aug 11 01:49:32 2005 From: mbellon at mvista.com (Mark Bellon) Date: Wed, 10 Aug 2005 08:49:32 -0700 Subject: [Fwd: [PATCH] PPC64: large INITRD causes kernel not to boot] In-Reply-To: <1b082f286ff07d6348211697ef38a608@bga.com> References: <1b082f286ff07d6348211697ef38a608@bga.com> Message-ID: <42FA220C.1090109@mvista.com> Milton Miller wrote: >> >> - printf("\n\rzImage starting: loaded at 0x%x\n\r", >> (unsigned)_start); >> + printf("\n\rzImage starting: loaded at 0x%lx\n\r", (unsigned >> long) _start); >> + >> + /* >> + * The first available claim_base must be above the end of the >> + * the loaded kernel file (_start to _end) and rounded up to a >> + * nice 1 MB boundary. >> + */ >> + >> + claim_base = ((((unsigned long) _end) + ONE_MB - 1) / ONE_MB) * >> ONE_MB; >> >> > > _start and _end here are the linked runtime range of the zImage program > not the kernel image contained therein. This also contains the > initrd. > > Milton > Exactly. The claim_base needs to start after the kernel and initrd. Since _end is above the "top" of the initrd it's perfect to use as the base for the round up calculation for the starting claim_base. mark From becky.bruce at freescale.com Thu Aug 11 02:45:10 2005 From: becky.bruce at freescale.com (Becky Bruce) Date: Wed, 10 Aug 2005 11:45:10 -0500 Subject: RFC: proposed arch/powerpc directory structure Message-ID: All, In the name of moving the much-anticipated 32/64 ppc merge along, Kumar Gala, Jon Loeliger, and myself have worked out an initial proposal for the directory structure of the new merged arch/powerpc. Listed below are the proposed directories, along with a description of the logical contents, as well as a description of which existing files will be moved into these directories. There was some discussion on the list recently about whether or not it might be better to change things around to be laid out more along the lines of functionality with, say, all pci-related code in one place. We've stuck with a more traditional model in this proposal, although the topic is certainly still up for discussion. This is just a first pass at a structure - we're really looking for input from this list on the best way to proceed, and that discussion needs to start somewhere. BTW, this proposal preempts the previous 64-bit directory structure reorg proposal that I sent to this list a couple of months ago. So here it is: include/powerpc/ arch/powerpc/ configs/ - Kconfig defaults per buildable board. boot/ - Pre-kernel execution shims and pre-passes. - Convert firmware reprensentations (bi_recs, OF Dev-Trees, bootx,bd_t) to flat-dev-trees. - Includes merged files from arch/ppc*/boot/ trees, plus prom_init.c from arch/ppc64/kernel. kernel/ - CPU-centric core code and generic PPC-specific kernel - Main entry point supports r5=0, r3 = flat-dev-tree, etc. - Includes all cpu core-specific code, kernel initialization code, and other generic kernel foo like smp, ptrace, syscalls, etc from arch/ppc*/kernel. Files not belonging to one of these categories will be moved to other directories. platforms/ - platform-specific code laid out in the following directories: pSeries/ iSeries/ pmac/ (both 32 and 64-bit) classic32/ (platforms containing 6xx/7xx/74xx/8240/8241/8245) classic64/ (Maple?) 83xx/ (may collapse into classic 32 at some point) 86xx/ (may collapse into classic 32 at some point) pq2/ (may collapse into classic 32 at some point) 52xx/ (may collapse into classic 32 at some point) 85xx/ 4xx/ 8xx/ - Includes all code from arch/ppc/platforms, all code from arch/ppc64/kernel that is specific to a given platform (where a platform is a whole computer system or board) NOTE: there would be no .[chS] files directly under platforms - all live in subdirs. mm/ - Memory management, slabs, tlbs, etc. - Unify LMB and mem_pieces for early boot memory. - Includes all code from arch/ppc*/mm sysdev/ - System Device support and Kitchen Sink - Includes all code currently in arch/ppc/syslib, irq and pci code that currently lives in arch/ppc/kernel, and all code from arch/ppc64/kernel that is generic system code, including pci, irq, interrupt control, bridges, rtas(?) lib/ - Library code - Includes all code from arch/ppc*/lib math-emu/ - Math Emulation for FPU-less ppc32s. - this is 32-bit only, so this directory would just move from arch/ppc to arch/powerpc oprofile/ - Support for oprofile. - Includes all code from arch/ppc*/oprofile xmon/ - Support for xmon. - Includes all code from arch/ppc*xmon Cheers, -Becky From dan at embeddededge.com Thu Aug 11 03:01:34 2005 From: dan at embeddededge.com (Dan Malek) Date: Wed, 10 Aug 2005 13:01:34 -0400 Subject: RFC: proposed arch/powerpc directory structure In-Reply-To: References: Message-ID: <22fac6c20e1ee142606e4295722c2d1d@embeddededge.com> On Aug 10, 2005, at 12:45 PM, Becky Bruce wrote: > .... Listed below are the proposed directories, along with a > description of the logical contents, as well as a description of which > existing files will be moved into these directories. I think this is fine, but I'd like to make a suggestion about the file names themselves. Since we have platform directories for a specific processor type or core, can we change the file names a little? For example, if I'm in the platforms/82xx directory, I don't need to prepend every file with mpc82xx_ or ppc82xx- or whatever. We know that's what it is, let's try to use the file names to be more descriptive of what's inside of them. Regardless of the build or management tools we use, I still find it nice to keep a concise file name that is still descriptive, and take advantage of the directory structure names to assist with this. Thanks. -- Dan From kamitch at cisco.com Thu Aug 11 06:30:54 2005 From: kamitch at cisco.com (Keith Mitchell) Date: Wed, 10 Aug 2005 16:30:54 -0400 Subject: New Dual 2ghz Powermac G5 In-Reply-To: <1123669822.30257.228.camel@gaston> References: <42F914B7.8010208@cisco.com> <1123669822.30257.228.camel@gaston> Message-ID: <42FA63FE.8000405@cisco.com> Yep.. that fixed it. Benjamin Herrenschmidt wrote: >On Tue, 2005-08-09 at 16:40 -0400, Keith Mitchell wrote: > > >>I just got in a bunch of new Dual 2.0ghz Powermacs and one out of the >>bunch so far has a noisy fan problem. I have been loading YDL 4.0.91 >>which has kernel 2.6.12 plus some patches and I did go back and verify >>that it had the last patch I saw related to this >>(http://patchwork.ozlabs.org/linuxppc64/patch?id=846). All of the >>machines all identify themselves as running OpenFirmware 5.2.4f1 and all >>came in at once with the same config. >> >>The machine with the problem so far issues the following messages: >> >>kernel: /u3 at 0,f8000000/i2c at f8001000: Missing interrupt or address ! >>kernel: /u3 at 0,f8000000/i2c at f8001000: Missing interrupt or address ! >>kernel: /u3 at 0,f8000000/i2c at f8001000: Missing interrupt or address ! >>kernel: /u3 at 0,f8000000/i2c at f8001000: Missing interrupt or address ! >> >> >>Is this a known issue? >> >> > >Yes, here is the fix: > >The workaround for broken device-tree that prevents fan control from >working on recent G5 models need to be "enabled" for machines with >revision 0x37 of the bridge in addition to machines with revision 0x35. > >Signed-off-by: Geoff Levand >Signed-off-by: Benjamin Herrenschmidt > >--- a/arch/ppc64/kernel/prom_init.c 2005-07-27 18:34:40.000000000 -0700 >+++ b/arch/ppc64/kernel/prom_init.c 2005-08-09 16:18:04.000000000 -0700 >@@ -1803,7 +1803,7 @@ > if (prom_getprop(u3, "device-rev", &u3_rev, sizeof(u3_rev)) > == PROM_ERROR) > return; >- if (u3_rev != 0x35) >+ if (u3_rev != 0x35 && u3_rev != 0x37) > return; > /* does it need fixup ? */ > if (prom_getproplen(i2c, "interrupts") > 0) > > > > -- Keith Mitchell | | | kamitch at cisco.com | :|: :|: 7025 Kit Creek Road, P.O. Box 14987 | :|||||: :|||||: Research Triangle Park, NC 27709 | .:|||||||:.:|||||||:. 919-392-9607 | c i s c o S y s t e m s -------------- next part -------------- An HTML attachment was scrubbed... URL: http://ozlabs.org/pipermail/linuxppc64-dev/attachments/20050810/7ffe1d70/attachment.htm From linville at tuxdriver.com Thu Aug 11 07:35:34 2005 From: linville at tuxdriver.com (John W. Linville) Date: Wed, 10 Aug 2005 17:35:34 -0400 Subject: RFC: proposed arch/powerpc directory structure In-Reply-To: <22fac6c20e1ee142606e4295722c2d1d@embeddededge.com> References: <22fac6c20e1ee142606e4295722c2d1d@embeddededge.com> Message-ID: <20050810213533.GA2353@tuxdriver.com> On Wed, Aug 10, 2005 at 01:01:34PM -0400, Dan Malek wrote: > inside of them. Regardless of the build or management tools we use, I > still find it > nice to keep a concise file name that is still descriptive, and take > advantage of > the directory structure names to assist with this. I'll second that, fwiw... John -- John W. Linville linville at tuxdriver.com From aw-confirm at ebay.com Thu Aug 11 09:35:21 2005 From: aw-confirm at ebay.com (aw-confirm at ebay.com) Date: Wed, 10 Aug 2005 19:35:21 -0400 (EDT) Subject: Action Required -- Credit/Debit Card Expiration Reminder Message-ID: <20050810233521.14C1E3B9DF3@aes.mes.org> An HTML attachment was scrubbed... URL: http://ozlabs.org/pipermail/linuxppc64-dev/attachments/20050810/1348f4bf/attachment.htm From sfr at canb.auug.org.au Thu Aug 11 10:09:11 2005 From: sfr at canb.auug.org.au (Stephen Rothwell) Date: Thu, 11 Aug 2005 10:09:11 +1000 Subject: RFC: proposed arch/powerpc directory structure In-Reply-To: References: Message-ID: <20050811100911.7b3ac089.sfr@canb.auug.org.au> On Wed, 10 Aug 2005 11:45:10 -0500 Becky Bruce wrote: > > platforms/ > - platform-specific code laid out in the following > directories: pSeries/ > iSeries/ Please, lets get rid of the StudLy CaPs :-) -- Cheers, Stephen Rothwell sfr at canb.auug.org.au http://www.canb.auug.org.au/~sfr/ From mbellon at mvista.com Thu Aug 11 10:57:22 2005 From: mbellon at mvista.com (Mark Bellon) Date: Wed, 10 Aug 2005 17:57:22 -0700 Subject: [Fwd: [PATCH] PPC64: large INITRD causes kernel not to boot] In-Reply-To: <42F80136.9050500@mvista.com> References: <42F7A56D.7090809@mvista.com> <20050808185435.GA13206@suse.de> <42F7AC62.3070601@mvista.com> <20050808191123.GA14047@suse.de> <42F7B301.5060008@mvista.com> <20050808223010.GA18775@suse.de> <42F7DF52.4090905@mvista.com> <42F80136.9050500@mvista.com> Message-ID: <42FAA272.6010601@mvista.com> Please find attached my revised patch. This includes the following change over my original patch: 1) Olaf's suggestion of using _end removes the calculation making things smaller, neater and less complex. 2) The comment about where to start has been improved. 3) In extended testing I found a platform with ancient firmware (different than the platform that started all of this) that has a similar problem with claim. The fix was to enforce the PROG_START value as the absolute minimum. mark -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: ppc64-initrd-patch Url: http://ozlabs.org/pipermail/linuxppc64-dev/attachments/20050810/7b88c26f/attachment.txt From michael at ellerman.id.au Thu Aug 11 11:01:04 2005 From: michael at ellerman.id.au (Michael Ellerman) Date: Thu, 11 Aug 2005 11:01:04 +1000 Subject: [PATCH] PPC64: Fix non-LPAR IOMMU table allocation on pSeries In-Reply-To: <20050810032437.GC6300@austin.ibm.com> References: <20050810032437.GC6300@austin.ibm.com> Message-ID: <200508111101.08562.michael@ellerman.id.au> On Wed, 10 Aug 2005 13:24, Olof Johansson wrote: > Hi, > > This is for the 2.6.14 feed. I wouldn't recommend pushing it into > 2.6.13 due to risk of regressing some box that I don't have access to > for testing. > > I'd appreciate it if people with pre-POWER5, non-LPAR machines would give > this a go on their boxes and let me know if something falls apart. It's > been tested on an F80 and a p650 (SMP mode) here. p615 and p630 have > been sore spots in the past. > Boots fine on my 44P (7044-170), it's triggering the Python with ISA case: zImage starting: loaded at 0x400000 Allocating 0x98c000 bytes for kernel ... gunzipping (0x1400000 <- 0x407000:0x6e4bbf)...done 0x7fb8e0 bytes 0xe3dc bytes of heap consumed, max in use 0xa234 OF stdout device is: /pci at fef00000/isa at b/serial at i3f8 command line: devfs=nomount root=/dev/sdb2 memory layout at init: memory_limit : 0000000000000000 (16 MB aligned) alloc_bottom : 0000000001ca0000 alloc_top : 0000000020000000 alloc_top_hi : 0000000020000000 rmo_top : 0000000020000000 ram_top : 0000000020000000 Looking for displays found display : /pci at fef00000/display at 11, opening ... done opening PHB /pci at fef00000... done opening PHB /pci at fee00000... done instantiating rtas at 0x000000001efb5000 ... done 0000000000000000 : boot cpu 0000000000000000 copying OF device tree ... Building dt strings... Building dt structure... Device tree strings 0x0000000001da1000 -> 0x0000000001da2039 Device tree struct 0x0000000001da3000 -> 0x0000000001da9000 Calling quiesce ... returning from prom_init firmware_features = 0x0 Starting Linux PPC64 2.6.13-rc6-kexec ----------------------------------------------------- ppc64_pft_size = 0x17 ppc64_debug_switch = 0x0 ppc64_interrupt_controller = 0x1 systemcfg = 0xc000000000570000 systemcfg->platform = 0x100 systemcfg->processorCount = 0x1 systemcfg->physicalMemorySize = 0x20000000 ppc64_caches.dcache_line_size = 0x80 ppc64_caches.icache_line_size = 0x80 htab_address = 0xc00000001e000000 htab_hash_mask = 0xffff ----------------------------------------------------- [boot]0100 MM Init [boot]0100 MM Init Done Linux version 2.6.13-rc6-kexec (michael at concordia) (gcc version 3.4.2) #4 SMP T5 [boot]0012 Setup Arch Top of RAM: 0x20000000, Total RAM: 0x20000000 Memory hole size: 0MB Syscall map setup, 245 32 bits and 221 64 bits syscalls mpic: Setting up MPIC " MPIC " version 1.2 at ffc00000, max 8 CPUs mpic: ISU size: 16, shift: 4, mask: f No ramdisk, default root is /dev/sda2 Python workaround: reg0: 18e3388 Python workaround: reg0: 18eb788 PPC64 nvram contains 110592 bytes Using default idle loop [boot]0015 Setup Done Built 1 zonelists Kernel command line: devfs=nomount root=/dev/sdb2 mpic: Initializing for 32 sources mpic: Detected reversed IPI registers PID hash table entries: 4096 (order: 12, 131072 bytes) time_init: decrementer frequency = 95.140136 MHz time_init: processor frequency = 333.000000 MHz firmware_features = 0x0 Starting Linux PPC64 2.6.13-rc6-kexec ----------------------------------------------------- ppc64_pft_size = 0x17 ppc64_debug_switch = 0x0 ppc64_interrupt_controller = 0x1 systemcfg = 0xc000000000570000 systemcfg->platform = 0x100 systemcfg->processorCount = 0x1 systemcfg->physicalMemorySize = 0x20000000 ppc64_caches.dcache_line_size = 0x80 ppc64_caches.icache_line_size = 0x80 htab_address = 0xc00000001e000000 htab_hash_mask = 0xffff ----------------------------------------------------- [boot]0100 MM Init [boot]0100 MM Init Done Linux version 2.6.13-rc6-kexec (michael at concordia) (gcc version 3.4.2) #4 SMP T5 [boot]0012 Setup Arch Top of RAM: 0x20000000, Total RAM: 0x20000000 Memory hole size: 0MB Syscall map setup, 245 32 bits and 221 64 bits syscalls mpic: Setting up MPIC " MPIC " version 1.2 at ffc00000, max 8 CPUs mpic: ISU size: 16, shift: 4, mask: f No ramdisk, default root is /dev/sda2 Python workaround: reg0: 18e3388 Python workaround: reg0: 18eb788 PPC64 nvram contains 110592 bytes Using default idle loop [boot]0015 Setup Done Built 1 zonelists Kernel command line: devfs=nomount root=/dev/sdb2 mpic: Initializing for 32 sources mpic: Detected reversed IPI registers PID hash table entries: 4096 (order: 12, 131072 bytes) time_init: decrementer frequency = 95.140136 MHz time_init: processor frequency = 333.000000 MHz Console: colour dummy device 80x25 Dentry cache hash table entries: 131072 (order: 8, 1048576 bytes) Inode-cache hash table entries: 65536 (order: 7, 524288 bytes) freeing bootmem node 0 Memory: 477528k/524288k available (4540k kernel code, 46760k reserved, 2552k da) Mount-cache hash table entries: 256 device-tree: property "l2-cache" name conflicts with node in /cpus/PowerPC,POWE0 Brought up 1 CPUs NET: Registered protocol family 16 PCI: Probing PCI hardware iommu_bus_setup_pSeries, bus c00000000ffe5c00, bus->self 0000000000000000 Python root bus PHB has isa bus, reserving 256MB IOMMU table initialized, virtual merging enabled iommu_dev_setup_pSeries, dev c00000000ff92800 (Symphony Labs W83C553) iommu_dev_setup_pSeries, dev c00000000ff92000 (LSI Logic / Symbios Logic 53C896) iommu_dev_setup_pSeries, dev c00000000ff98800 (LSI Logic / Symbios Logic 53C896) iommu_dev_setup_pSeries, dev c00000000ff98000 (Advanced Micro Devices [AMD] 79c) iommu_dev_setup_pSeries, dev c00000000ff99800 (Matrox Graphics, Inc. MGA G200) iommu_bus_setup_pSeries, bus c00000000ffe5800, bus->self 0000000000000000 Python root bus mapping IO f8000000 -> d000010000000000, size: 1000000 mapping IO f9000000 -> d000010001000000, size: 1000000 ISA bridge at 0000:00:0b.0 PCI: Probing PCI hardware done SCSI subsystem initialized usbcore: registered new driver usbfs usbcore: registered new driver hub i/pSeries Real Time Clock Driver v1.1 RTAS daemon started audit: initializing netlink socket (disabled) audit(1123721342.074:1): initialized Total HugeTLB memory allocated, 0 Installing knfsd (copyright (C) 1996 okir at monad.swb.de). Initializing Cryptographic API matroxfb: Matrox MGA-G200 (PCI) detected matroxfb: BIOS on your Matrox device does not contain powerup info matroxfb: 640x480x8bpp (virtual: 640x3276) matroxfb: framebuffer at 0xC0000000, mapped to 0xd000010080211000, size 2097152 Console: switching to colour frame buffer device 80x30 fb0: MATROX frame buffer device HVSI: registered 0 devices serio: i8042 AUX port at 0x60,0x64 irq 12 serio: i8042 KBD port at 0x60,0x64 irq 1 Serial: 8250/16550 driver $Revision: 1.90 $ 4 ports, IRQ sharing disabled ttyS0 at I/O 0x3f8 (irq = 4) is a 16550A ttyS1 at I/O 0x2f8 (irq = 3) is a 16550A ttyS2 at I/O 0x898 (irq = 15) is a 16550A io scheduler noop registered io scheduler anticipatory registered io scheduler deadline registered io scheduler cfq registered RAMDISK driver initialized: 16 RAM disks of 65536K size 1024 blocksize loop: loaded (max 8 devices) Intel(R) PRO/1000 Network Driver - version 6.0.60-k2 Copyright (c) 1999-2005 Intel Corporation. pcnet32.c:v1.30j 29.04.2005 tsbogend at alpha.franken.de pcnet32: PCnet/FAST 79C971 at 0xfff400, 00 09 6b de 34 6b tx_start_pt(0x0c00):~220 bytes, BCR18(68e2):BurstWrEn BurstRdEn DWordIO NoU SRAMSIZE=0x7f00, SRAM_BND=0x4000, assigned IRQ 18. eth0: registered as PCnet/FAST 79C971 pcnet32: 1 cards_found. e100: Intel(R) PRO/100 Network Driver, 3.4.8-k2-NAPI e100: Copyright(c) 1999-2005 Intel Corporation /home/michael/src/kernel/work/drivers/net/ibmveth.c: ibmveth: IBM i/pSeries Vir3 netconsole: not configured, aborting Uniform Multi-Platform E-IDE driver Revision: 7.00alpha2 ide: Assuming 33MHz system bus speed for PIO modes; override with idebus=xx sym0: <896> rev 0x7 at pci 0000:00:0c.0 irq 20 sym0: No NVRAM, ID 7, Fast-40, SE, parity checking sym0: SCSI BUS has been reset. scsi0 : sym-2.2.1 Vendor: IBM Model: CDRM00203 !K Rev: 1_05 Type: CD-ROM ANSI SCSI revision: 02 target0:0:1: Beginning Domain Validation target0:0:1: asynchronous. target0:0:1: wide asynchronous. target0:0:1: Domain Validation skipping write tests target0:0:1: FAST-20 WIDE SCSI 40.0 MB/s ST (50 ns, offset 15) target0:0:1: Ending Domain Validation target0:0:4: FAST-20 WIDE SCSI 40.0 MB/s ST (50 ns, offset 31) Vendor: IBM Model: DDYS-T09170N Rev: S96F Type: Direct-Access ANSI SCSI revision: 03 target0:0:4: tagged command queuing enabled, command queue depth 16. etc. -- Michael Ellerman IBM OzLabs email: michael:ellerman.id.au inmsg: mpe:jabber.org wwweb: http://michael.ellerman.id.au phone: +61 2 6212 1183 (tie line 70 21183) We do not inherit the earth from our ancestors, we borrow it from our children. - S.M.A.R.T Person -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: not available Url : http://ozlabs.org/pipermail/linuxppc64-dev/attachments/20050811/b0b621b9/attachment.pgp From olof at lixom.net Thu Aug 11 11:10:29 2005 From: olof at lixom.net (Olof Johansson) Date: Wed, 10 Aug 2005 20:10:29 -0500 Subject: RFC: proposed arch/powerpc directory structure In-Reply-To: <20050811100911.7b3ac089.sfr@canb.auug.org.au> References: <20050811100911.7b3ac089.sfr@canb.auug.org.au> Message-ID: <20050811011029.GA6746@austin.ibm.com> On Thu, Aug 11, 2005 at 10:09:11AM +1000, Stephen Rothwell wrote: > On Wed, 10 Aug 2005 11:45:10 -0500 Becky Bruce > wrote: > > > > platforms/ > > - platform-specific code laid out in the following > > directories: pSeries/ > > iSeries/ > > Please, lets get rid of the StudLy CaPs :-) Actually, might be a good time to start calling pSeries something else too, since it's no longer just pSeries that uses the platform. papr? rpa? -Olof From geoffrey.levand at am.sony.com Thu Aug 11 10:57:42 2005 From: geoffrey.levand at am.sony.com (Geoff Levand) Date: Wed, 10 Aug 2005 17:57:42 -0700 Subject: [PATCH 2/2] ppc64: makefile cleanup Message-ID: <42FAA286.6000301@am.sony.com> Please consider for inclusion in the post 2.6.13 patches. -Geoff This patch cleans up the output generated by ppc64 builds. Signed-off-by: Geoff Levand Index: linux-2.6.13-rc6.ppc64-makefile/arch/ppc64/boot/Makefile =================================================================== --- linux-2.6.13-rc6.ppc64-makefile.orig/arch/ppc64/boot/Makefile 2005-08-10 17:34:01.000000000 -0700 +++ linux-2.6.13-rc6.ppc64-makefile/arch/ppc64/boot/Makefile 2005-08-10 17:34:09.000000000 -0700 @@ -66,7 +66,7 @@ quiet_cmd_ramdisk = RAMDISK $@ cmd_ramdisk = $(obj)/addRamDisk $(obj)/ramdisk.image.gz $< $@ -quiet_cmd_stripvm = STRIP $@ +quiet_cmd_stripvm = STRIP $@ cmd_stripvm = $(STRIP) -s $< -o $@ vmlinux.strip: vmlinux FORCE @@ -74,9 +74,17 @@ $(obj)/vmlinux.initrd: vmlinux.strip $(obj)/addRamDisk $(obj)/ramdisk.image.gz FORCE $(call if_changed,ramdisk) -addsection = $(CROSS32OBJCOPY) $(1) \ - --add-section=.kernel:$(strip $(patsubst $(obj)/kernel-%.o,%, $(1)))=$(patsubst %.o,%.gz, $(1)) \ - --set-section-flags=.kernel:$(strip $(patsubst $(obj)/kernel-%.o,%, $(1)))=$(OBJCOPYFLAGS) +quiet_cmd_addsection = ADDSEC $@ + cmd_addsection = $(CROSS32OBJCOPY) $@ \ + --add-section=.kernel:$(strip $(patsubst $(obj)/kernel-%.o,%, $@))=$(patsubst %.o,%.gz, $@) \ + --set-section-flags=.kernel:$(strip $(patsubst $(obj)/kernel-%.o,%, $@))=$(OBJCOPYFLAGS) + +quiet_cmd_imagesize = GENSIZE $@ + cmd_imagesize = ls -l vmlinux.strip | \ + awk '{printf "/* generated -- do not edit! */\n" "unsigned long vmlinux_filesize = %d;\n", $$5}' \ + > $(obj)/imagesize.c && \ + $(CROSS_COMPILE)nm -n vmlinux | tail -n 1 | \ + awk '{printf "unsigned long vmlinux_memsize = 0x%s;\n", substr($$1,8)}' >> $(obj)/imagesize.c quiet_cmd_addnote = ADDNOTE $@ cmd_addnote = $(obj)/addnote $@ @@ -88,11 +96,11 @@ cp -f $(obj)/ramdisk.image.gz $@ $(call src-sec, $(required) $(initrd)): $(obj)/kernel-%.c: $(obj)/kernel-%.gz FORCE - touch $@ + @touch $@ $(call obj-sec, $(required) $(initrd)): $(obj)/kernel-%.o: $(obj)/kernel-%.c FORCE $(call if_changed_dep,bootcc) - $(call addsection, $@) + $(call cmd,addsection) $(obj)/zImage: obj-boot += $(call obj-sec, $(required)) $(obj)/zImage: $(call obj-sec, $(required)) $(obj-boot) FORCE @@ -111,13 +119,7 @@ $(call if_changed,addnote) $(obj)/imagesize.c: vmlinux.strip - @echo Generating $@ - ls -l vmlinux.strip | \ - awk '{printf "/* generated -- do not edit! */\n" \ - "unsigned long vmlinux_filesize = %d;\n", $$5}' > $(obj)/imagesize.c - $(CROSS_COMPILE)nm -n vmlinux | tail -n 1 | \ - awk '{printf "unsigned long vmlinux_memsize = 0x%s;\n", substr($$1,8)}' \ - >> $(obj)/imagesize.c + $(call cmd,imagesize) install: $(CONFIGURE) $(BOOTIMAGE) sh -x $(srctree)/$(src)/install.sh "$(KERNELRELEASE)" vmlinux System.map "$(INSTALL_PATH)" "$(BOOTIMAGE)" From geoffrey.levand at am.sony.com Thu Aug 11 10:57:38 2005 From: geoffrey.levand at am.sony.com (Geoff Levand) Date: Wed, 10 Aug 2005 17:57:38 -0700 Subject: [PATCH 1/2] ppc64: zimage build fix Message-ID: <42FAA282.9040701@am.sony.com> Please consider for inclusion in the post 2.6.13 patches. -Geoff This patch makes it possible to build ppc64 kernel image files for all targeted machines when several CONFIG_PPC_XXX machine type options are enabled simultaneously. To accomplish this it introduces two new build targets, zImage.rs6k and zImage.initrd.rs6, which will make the proper ELF note header needed by pSeries machines. It falls out from these changes that compressed zImages for the Powermac G5 can now be built. Previously only vmlinux images could be for that machine. One remaining problem not addressed by this patch is how to specify the 'make install' target when several CONFIG_PPC_XXX machine type options are enabled simultaneously. Signed-off-by: Geoff Levand Index: linux-2.6.13-rc6.ppc64-makefile/arch/ppc64/Makefile =================================================================== --- linux-2.6.13-rc6.ppc64-makefile.orig/arch/ppc64/Makefile 2005-08-10 17:30:56.000000000 -0700 +++ linux-2.6.13-rc6.ppc64-makefile/arch/ppc64/Makefile 2005-08-10 17:34:01.000000000 -0700 @@ -87,14 +87,15 @@ boot := arch/ppc64/boot -boottarget-$(CONFIG_PPC_PSERIES) := zImage zImage.initrd -boottarget-$(CONFIG_PPC_MAPLE) := zImage zImage.initrd -boottarget-$(CONFIG_PPC_ISERIES) := vmlinux.sminitrd vmlinux.initrd vmlinux.sm -boottarget-$(CONFIG_PPC_BPA) := zImage zImage.initrd -$(boottarget-y): vmlinux +boottargets-$(CONFIG_PPC_PSERIES) += zImage.rs6k zImage.initrd.rs6k +boottargets-$(CONFIG_PPC_PMAC) += zImage zImage.initrd +boottargets-$(CONFIG_PPC_MAPLE) += zImage zImage.initrd +boottargets-$(CONFIG_PPC_ISERIES) += vmlinux.sminitrd vmlinux.initrd vmlinux.sm +boottargets-$(CONFIG_PPC_BPA) += zImage zImage.initrd +$(boottargets-y): vmlinux $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ -bootimage-$(CONFIG_PPC_PSERIES) := $(boot)/zImage +bootimage-$(CONFIG_PPC_PSERIES) := $(boot)/zImage.rs6k bootimage-$(CONFIG_PPC_PMAC) := vmlinux bootimage-$(CONFIG_PPC_MAPLE) := $(boot)/zImage bootimage-$(CONFIG_PPC_BPA) := zImage @@ -103,7 +104,7 @@ install: vmlinux $(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(BOOTIMAGE) $@ -defaultimage-$(CONFIG_PPC_PSERIES) := zImage +defaultimage-$(CONFIG_PPC_PSERIES) := zImage.rs6k defaultimage-$(CONFIG_PPC_PMAC) := vmlinux defaultimage-$(CONFIG_PPC_MAPLE) := zImage defaultimage-$(CONFIG_PPC_ISERIES) := vmlinux @@ -122,10 +123,12 @@ $(call filechk,gen-asm-offsets) define archhelp - echo '* zImage - Compressed kernel image (arch/$(ARCH)/boot/zImage)' - echo ' zImage.initrd- Compressed kernel image with initrd attached,' - echo ' sourced from arch/$(ARCH)/boot/ramdisk.image.gz' - echo ' (arch/$(ARCH)/boot/zImage.initrd)' + echo ' zImage - Compressed kernel image (arch/$(ARCH)/boot/zImage)' + echo ' zImage.initrd - Compressed kernel image with initrd attached,' + echo ' sourced from arch/$(ARCH)/boot/ramdisk.image.gz' + echo ' (arch/$(ARCH)/boot/zImage.initrd)' + echo ' zImage.rs6k - zImage for pSeries machines' + echo ' zImage.initrd.rs6k- zImage with initrd for pSeries machines' endef CLEAN_FILES += include/asm-ppc64/offsets.h Index: linux-2.6.13-rc6.ppc64-makefile/arch/ppc64/boot/Makefile =================================================================== --- linux-2.6.13-rc6.ppc64-makefile.orig/arch/ppc64/boot/Makefile 2005-08-10 17:30:56.000000000 -0700 +++ linux-2.6.13-rc6.ppc64-makefile/arch/ppc64/boot/Makefile 2005-08-10 17:34:01.000000000 -0700 @@ -37,6 +37,9 @@ quiet_cmd_bootas = BOOTAS $@ cmd_bootas = $(CROSS32CC) -Wp,-MD,$(depfile) $(BOOTAFLAGS) -c -o $@ $< +quiet_cmd_bootld = BOOTLD $@ + cmd_bootld = $(CROSS32LD) $(BOOTLFLAGS) -o $@ $(2) + $(patsubst %.c,%.o, $(filter %.c, $(src-boot))): %.o: %.c $(call if_changed_dep,bootcc) $(patsubst %.S,%.o, $(filter %.S, $(src-boot))): %.o: %.S @@ -75,8 +78,8 @@ --add-section=.kernel:$(strip $(patsubst $(obj)/kernel-%.o,%, $(1)))=$(patsubst %.o,%.gz, $(1)) \ --set-section-flags=.kernel:$(strip $(patsubst $(obj)/kernel-%.o,%, $(1)))=$(OBJCOPYFLAGS) -quiet_cmd_addnote = ADDNOTE $@ - cmd_addnote = $(CROSS32LD) $(BOOTLFLAGS) -o $@ $(obj-boot) && $(obj)/addnote $@ +quiet_cmd_addnote = ADDNOTE $@ + cmd_addnote = $(obj)/addnote $@ $(call gz-sec, $(required)): $(obj)/kernel-%.gz: % FORCE $(call if_changed,gzip) @@ -92,11 +95,19 @@ $(call addsection, $@) $(obj)/zImage: obj-boot += $(call obj-sec, $(required)) -$(obj)/zImage: $(call obj-sec, $(required)) $(obj-boot) $(obj)/addnote FORCE - $(call if_changed,addnote) +$(obj)/zImage: $(call obj-sec, $(required)) $(obj-boot) FORCE + $(call cmd,bootld,$(obj-boot)) $(obj)/zImage.initrd: obj-boot += $(call obj-sec, $(required) $(initrd)) -$(obj)/zImage.initrd: $(call obj-sec, $(required) $(initrd)) $(obj-boot) $(obj)/addnote FORCE +$(obj)/zImage.initrd: $(call obj-sec, $(required) $(initrd)) $(obj-boot) FORCE + $(call cmd,bootld,$(obj-boot)) + +$(obj)/zImage.rs6k: $(obj)/zImage $(obj)/addnote FORCE + @cp -f $< $@ + $(call if_changed,addnote) + +$(obj)/zImage.initrd.rs6k: $(obj)/zImage.initrd $(obj)/addnote FORCE + @cp -f $< $@ $(call if_changed,addnote) $(obj)/imagesize.c: vmlinux.strip From miltonm at bga.com Thu Aug 11 12:11:02 2005 From: miltonm at bga.com (Milton Miller) Date: Wed, 10 Aug 2005 21:11:02 -0500 Subject: [Fwd: [PATCH] PPC64: large INITRD causes kernel not to boot] In-Reply-To: <42FA220C.1090109@mvista.com> References: <1b082f286ff07d6348211697ef38a608@bga.com> <42FA220C.1090109@mvista.com> Message-ID: On Aug 10, 2005, at 10:49 AM, Mark Bellon wrote: > Milton Miller wrote: > >>> >>> - printf("\n\rzImage starting: loaded at 0x%x\n\r", >>> (unsigned)_start); >>> + printf("\n\rzImage starting: loaded at 0x%lx\n\r", (unsigned >>> long) _start); >>> + >>> + /* >>> + * The first available claim_base must be above the end of the >>> + * the loaded kernel file (_start to _end) and rounded up to a >>> + * nice 1 MB boundary. >>> + */ >>> + >>> + claim_base = ((((unsigned long) _end) + ONE_MB - 1) / ONE_MB) * >>> ONE_MB; >>> >>> >> >> _start and _end here are the linked runtime range of the zImage >> program >> not the kernel image contained therein. This also contains the >> initrd. >> >> Milton >> > Exactly. The claim_base needs to start after the kernel and initrd. > Since _end is above the "top" of the initrd it's perfect to use as the > base for the round up calculation for the starting claim_base. > > mark > My unstated request was to fix the misleading comment. Change "loaded kernel file" to something like "this running program" or "image" or something. Something to be aware of: the program gets loaded at load-base and then the sections get moved to their linked area. It is explicitly stated that while the fw has to maintain the elf header, it does *NOT* need to worry about overlaping source and desitination. In other words, there is an implied copy from elf file loaded into ram at ram-base to the _start,_end range that doesn't look for overlap. milton From michael at ellerman.id.au Thu Aug 11 12:15:06 2005 From: michael at ellerman.id.au (Michael Ellerman) Date: Thu, 11 Aug 2005 12:15:06 +1000 Subject: [PATCH 1/2] ppc64: zimage build fix In-Reply-To: <42FAA282.9040701@am.sony.com> References: <42FAA282.9040701@am.sony.com> Message-ID: <200508111215.09284.michael@ellerman.id.au> Sorry I didn't comment on this earlier. I don't know about others, but I have a bunch of scripts and so on that expect a pSeries build to produce a "zImage" - all of which would have to be changed to cope with this patch. On the other hand I don't have any scripts that expect a G5 build to produce a zImage. So it would seem more logical to me leave zImage as is, and create a new zImage.g5 or zImage.realmode or whatever you want to call it. cheers On Thu, 11 Aug 2005 10:57, Geoff Levand wrote: > Please consider for inclusion in the post 2.6.13 patches. > > -Geoff > > > > This patch makes it possible to build ppc64 kernel image files for all > targeted machines when several CONFIG_PPC_XXX machine type options are > enabled simultaneously. To accomplish this it introduces two new build > targets, zImage.rs6k and zImage.initrd.rs6, which will make the proper > ELF note header needed by pSeries machines. It falls out from these > changes that compressed zImages for the Powermac G5 can now be built. > Previously only vmlinux images could be for that machine. > > One remaining problem not addressed by this patch is how to specify the > 'make install' target when several CONFIG_PPC_XXX machine type options are > enabled simultaneously. > > Signed-off-by: Geoff Levand > > > Index: linux-2.6.13-rc6.ppc64-makefile/arch/ppc64/Makefile > =================================================================== > --- linux-2.6.13-rc6.ppc64-makefile.orig/arch/ppc64/Makefile 2005-08-10 > 17:30:56.000000000 -0700 +++ > linux-2.6.13-rc6.ppc64-makefile/arch/ppc64/Makefile 2005-08-10 > 17:34:01.000000000 -0700 @@ -87,14 +87,15 @@ > > boot := arch/ppc64/boot > > -boottarget-$(CONFIG_PPC_PSERIES) := zImage zImage.initrd > -boottarget-$(CONFIG_PPC_MAPLE) := zImage zImage.initrd > -boottarget-$(CONFIG_PPC_ISERIES) := vmlinux.sminitrd vmlinux.initrd > vmlinux.sm -boottarget-$(CONFIG_PPC_BPA) := zImage zImage.initrd > -$(boottarget-y): vmlinux > +boottargets-$(CONFIG_PPC_PSERIES) += zImage.rs6k zImage.initrd.rs6k > +boottargets-$(CONFIG_PPC_PMAC) += zImage zImage.initrd > +boottargets-$(CONFIG_PPC_MAPLE) += zImage zImage.initrd > +boottargets-$(CONFIG_PPC_ISERIES) += vmlinux.sminitrd vmlinux.initrd > vmlinux.sm +boottargets-$(CONFIG_PPC_BPA) += zImage zImage.initrd > +$(boottargets-y): vmlinux > $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ > > -bootimage-$(CONFIG_PPC_PSERIES) := $(boot)/zImage > +bootimage-$(CONFIG_PPC_PSERIES) := $(boot)/zImage.rs6k > bootimage-$(CONFIG_PPC_PMAC) := vmlinux > bootimage-$(CONFIG_PPC_MAPLE) := $(boot)/zImage > bootimage-$(CONFIG_PPC_BPA) := zImage > @@ -103,7 +104,7 @@ > install: vmlinux > $(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(BOOTIMAGE) $@ > > -defaultimage-$(CONFIG_PPC_PSERIES) := zImage > +defaultimage-$(CONFIG_PPC_PSERIES) := zImage.rs6k > defaultimage-$(CONFIG_PPC_PMAC) := vmlinux > defaultimage-$(CONFIG_PPC_MAPLE) := zImage > defaultimage-$(CONFIG_PPC_ISERIES) := vmlinux > @@ -122,10 +123,12 @@ > $(call filechk,gen-asm-offsets) > > define archhelp > - echo '* zImage - Compressed kernel image > (arch/$(ARCH)/boot/zImage)' - echo ' zImage.initrd- Compressed kernel > image with initrd attached,' - echo ' sourced from > arch/$(ARCH)/boot/ramdisk.image.gz' > - echo ' (arch/$(ARCH)/boot/zImage.initrd)' > + echo ' zImage - Compressed kernel image > (arch/$(ARCH)/boot/zImage)' + echo ' zImage.initrd - Compressed > kernel image with initrd attached,' + echo ' sourced from > arch/$(ARCH)/boot/ramdisk.image.gz' + echo ' > (arch/$(ARCH)/boot/zImage.initrd)' > + echo ' zImage.rs6k - zImage for pSeries machines' > + echo ' zImage.initrd.rs6k- zImage with initrd for pSeries machines' > endef > > CLEAN_FILES += include/asm-ppc64/offsets.h > Index: linux-2.6.13-rc6.ppc64-makefile/arch/ppc64/boot/Makefile > =================================================================== > --- > linux-2.6.13-rc6.ppc64-makefile.orig/arch/ppc64/boot/Makefile 2005-08-10 > 17:30:56.000000000 -0700 +++ > linux-2.6.13-rc6.ppc64-makefile/arch/ppc64/boot/Makefile 2005-08-10 > 17:34:01.000000000 -0700 @@ -37,6 +37,9 @@ > quiet_cmd_bootas = BOOTAS $@ > cmd_bootas = $(CROSS32CC) -Wp,-MD,$(depfile) $(BOOTAFLAGS) -c -o $@ > $< > > +quiet_cmd_bootld = BOOTLD $@ > + cmd_bootld = $(CROSS32LD) $(BOOTLFLAGS) -o $@ $(2) > + > $(patsubst %.c,%.o, $(filter %.c, $(src-boot))): %.o: %.c > $(call if_changed_dep,bootcc) > $(patsubst %.S,%.o, $(filter %.S, $(src-boot))): %.o: %.S > @@ -75,8 +78,8 @@ > --add-section=.kernel:$(strip $(patsubst $(obj)/kernel-%.o,%, > $(1)))=$(patsubst %.o,%.gz, $(1)) \ --set-section-flags=.kernel:$(strip > $(patsubst $(obj)/kernel-%.o,%, $(1)))=$(OBJCOPYFLAGS) > > -quiet_cmd_addnote = ADDNOTE $@ > - cmd_addnote = $(CROSS32LD) $(BOOTLFLAGS) -o $@ $(obj-boot) && > $(obj)/addnote $@ +quiet_cmd_addnote = ADDNOTE $@ > + cmd_addnote = $(obj)/addnote $@ > > $(call gz-sec, $(required)): $(obj)/kernel-%.gz: % FORCE > $(call if_changed,gzip) > @@ -92,11 +95,19 @@ > $(call addsection, $@) > > $(obj)/zImage: obj-boot += $(call obj-sec, $(required)) > -$(obj)/zImage: $(call obj-sec, $(required)) $(obj-boot) $(obj)/addnote > FORCE - $(call if_changed,addnote) > +$(obj)/zImage: $(call obj-sec, $(required)) $(obj-boot) FORCE > + $(call cmd,bootld,$(obj-boot)) > > $(obj)/zImage.initrd: obj-boot += $(call obj-sec, $(required) $(initrd)) > -$(obj)/zImage.initrd: $(call obj-sec, $(required) $(initrd)) $(obj-boot) > $(obj)/addnote FORCE +$(obj)/zImage.initrd: $(call obj-sec, $(required) > $(initrd)) $(obj-boot) FORCE + $(call cmd,bootld,$(obj-boot)) > + > +$(obj)/zImage.rs6k: $(obj)/zImage $(obj)/addnote FORCE > + @cp -f $< $@ > + $(call if_changed,addnote) > + > +$(obj)/zImage.initrd.rs6k: $(obj)/zImage.initrd $(obj)/addnote FORCE > + @cp -f $< $@ > $(call if_changed,addnote) > > $(obj)/imagesize.c: vmlinux.strip > > _______________________________________________ > Linuxppc64-dev mailing list > Linuxppc64-dev at ozlabs.org > https://ozlabs.org/mailman/listinfo/linuxppc64-dev -- Michael Ellerman IBM OzLabs email: michael:ellerman.id.au inmsg: mpe:jabber.org wwweb: http://michael.ellerman.id.au phone: +61 2 6212 1183 (tie line 70 21183) We do not inherit the earth from our ancestors, we borrow it from our children. - S.M.A.R.T Person -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: not available Url : http://ozlabs.org/pipermail/linuxppc64-dev/attachments/20050811/b2ffa2fe/attachment.pgp From david at gibson.dropbear.id.au Thu Aug 11 13:14:25 2005 From: david at gibson.dropbear.id.au (David Gibson) Date: Thu, 11 Aug 2005 13:14:25 +1000 Subject: [PATCH 6/10] ppc64: Create a fake flat device tree on iSeries In-Reply-To: References: <6b57499e431cefc69e65db59b4210b38@bga.com> <20050810083228.GE22335@localhost.localdomain> Message-ID: <20050811031425.GA5975@localhost.localdomain> On Wed, Aug 10, 2005 at 08:59:51AM -0500, Milton Miller wrote: > > On Aug 10, 2005, at 3:32 AM, David Gibson wrote: > > >On Wed, Aug 10, 2005 at 02:16:15AM -0500, Milton Miller wrote: > >> > >>5) If you are going to statically allocate this for iSeries (as > >>opossed to say a klimit bump), then the only thing in dynamic is > >>setting the boot cpuid. May as well use a static initializer. > >> > >>Today this would add over 2 pages of bss for a "combined" kernel. > > > >I think you'll find there are patches coming making more stuff > >dynamic. Virtual devices, in particular. > > Sorry, wasn't trying to imply making the whole tree static, just > the header. But I would rather see it allocated at klimit ... > > > > > >>Putting the > >>device data at klimit would allow the checks for overflow to be > >>deferred until after its created (look for 2 nuls in string table > >>-- the size is propnum(""), and placing data at after the reserve > >>map and string table and either compare to total size or set > >>totalsize according to what is used). > > > >Hrm.. actually.. this may be too irritatingly inflexible, but since > >the iseries device tree is pretty limited in what it contains, it > >would potentially be possible to statically initialize a string table > >containing every property name iSeries might ever use. In fact, doing > >it that way you could generate the skeleton of the device tree with > >dtc (asm output mode), leaving some space in the structure section, > >then add in the dynamic structure at runtime. (I'd need to add > >something to dtc to allow you to force a string into the string > >section even if it's not used in the tree, of course, but that should > >be easy) > > My other generator does this very thing. The strings are allocated > statically. > > While discussing embedded with panto on #mklinux, another approach > is to say "here's the max", put the strings at the end, and allocate > new strings down moving the start as we add strings. An memmove() on every string insertion? That's kinda horrible.. > Makes sense for > fw where there is a fixed allocation. End of blob processing can > then memmove the string table and cut total size down. > > Even without the knowing the max size realloc could move strings down > if a space check is added before extending the dt blob. -- David Gibson | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/people/dgibson From olh at suse.de Thu Aug 11 16:40:41 2005 From: olh at suse.de (Olaf Hering) Date: Thu, 11 Aug 2005 08:40:41 +0200 Subject: [RFC] addnote and pmac In-Reply-To: <42F91AB6.8050309@am.sony.com> References: <1123576274.30257.152.camel@gaston> <42F91AB6.8050309@am.sony.com> Message-ID: <20050811064041.GA6291@suse.de> On Tue, Aug 09, Geoff Levand wrote: > It seems both you and Olaf suggested to make two build targets, so I set > them up as zImage and zImage.rs6k. No, the target has to be zImage, the result is arch/ppc64/boot/zImage and arch/ppc64/boot/vmlinux.elf-pmac Just copying it away before doing addnote on zImage should be enough. From david at gibson.dropbear.id.au Thu Aug 11 16:55:21 2005 From: david at gibson.dropbear.id.au (David Gibson) Date: Thu, 11 Aug 2005 16:55:21 +1000 Subject: Dynamic hugepage addresses for ppc64 Message-ID: <20050811065521.GF5975@localhost.localdomain> Paulus, I think this is now a reasonable candidate for the post-2.6.13 queue. Relax address restrictions for hugepages on ppc64 Presently, 64-bit applications on ppc64 may only use hugepages in the address region from 1-1.5T. Furthermore, if hugepages are enabled in the kernel config, they may only use hugepages and never normal pages in this area. This patch relaxes this restriction, allowing any address to be used with hugepages, but with a 1TB granularity. That is if you map a hugepage anywhere in the region 1TB-2TB, that entire area will be reserved exclusively for hugepages for the remainder of the process's lifetime. This works analagously to hugepages in 32-bit applications, where hugepages can be mapped anywhere, but with 256MB (mmu segment) granularity. This patch applies on top of the four level pagetable patch (http://patchwork.ozlabs.org/linuxppc64/patch?id=1936). Signed-off-by: David Gibson Index: working-2.6/arch/ppc64/kernel/asm-offsets.c =================================================================== --- working-2.6.orig/arch/ppc64/kernel/asm-offsets.c 2005-07-28 16:43:46.000000000 +1000 +++ working-2.6/arch/ppc64/kernel/asm-offsets.c 2005-08-11 16:07:29.000000000 +1000 @@ -94,7 +94,8 @@ DEFINE(PACASLBCACHEPTR, offsetof(struct paca_struct, slb_cache_ptr)); DEFINE(PACACONTEXTID, offsetof(struct paca_struct, context.id)); #ifdef CONFIG_HUGETLB_PAGE - DEFINE(PACAHTLBSEGS, offsetof(struct paca_struct, context.htlb_segs)); + DEFINE(PACALOWHTLBAREAS, offsetof(struct paca_struct, context.low_htlb_areas)); + DEFINE(PACAHIGHHTLBAREAS, offsetof(struct paca_struct, context.high_htlb_areas)); #endif /* CONFIG_HUGETLB_PAGE */ DEFINE(PACADEFAULTDECR, offsetof(struct paca_struct, default_decr)); DEFINE(PACA_EXGEN, offsetof(struct paca_struct, exgen)); Index: working-2.6/arch/ppc64/mm/hugetlbpage.c =================================================================== --- working-2.6.orig/arch/ppc64/mm/hugetlbpage.c 2005-08-11 16:07:28.000000000 +1000 +++ working-2.6/arch/ppc64/mm/hugetlbpage.c 2005-08-11 16:15:55.000000000 +1000 @@ -27,6 +27,9 @@ #include +#define NUM_LOW_AREAS (0x100000000UL >> SID_SHIFT) +#define NUM_HIGH_AREAS (PGTABLE_RANGE >> HTLB_AREA_SHIFT) + /* Modelled after find_linux_pte() */ pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr) { @@ -129,15 +132,17 @@ return 0; } -static void flush_segments(void *parm) +static void flush_low_segments(void *parm) { - u16 segs = (unsigned long) parm; + u16 areas = (unsigned long) parm; unsigned long i; asm volatile("isync" : : : "memory"); - for (i = 0; i < 16; i++) { - if (! (segs & (1U << i))) + BUILD_BUG_ON((sizeof(areas)*8) != NUM_LOW_AREAS); + + for (i = 0; i < NUM_LOW_AREAS; i++) { + if (! (areas & (1U << i))) continue; asm volatile("slbie %0" : : "r" (i << SID_SHIFT)); } @@ -145,13 +150,49 @@ asm volatile("isync" : : : "memory"); } -static int prepare_low_seg_for_htlb(struct mm_struct *mm, unsigned long seg) +static void flush_high_segments(void *parm) +{ + u16 areas = (unsigned long) parm; + unsigned long i, j; + + asm volatile("isync" : : : "memory"); + + BUILD_BUG_ON((sizeof(areas)*8) != NUM_HIGH_AREAS); + + for (i = 0; i < NUM_HIGH_AREAS; i++) { + if (! (areas & (1U << i))) + continue; + for (j = 0; j < (1UL << (HTLB_AREA_SHIFT-SID_SHIFT)); j++) + asm volatile("slbie %0" + :: "r" ((i << HTLB_AREA_SHIFT) + (j << SID_SHIFT))); + } + + asm volatile("isync" : : : "memory"); +} + +static int prepare_low_area_for_htlb(struct mm_struct *mm, unsigned long area) +{ + unsigned long start = area << SID_SHIFT; + unsigned long end = (area+1) << SID_SHIFT; + struct vm_area_struct *vma; + + BUG_ON(area >= NUM_LOW_AREAS); + + /* Check no VMAs are in the region */ + vma = find_vma(mm, start); + if (vma && (vma->vm_start < end)) + return -EBUSY; + + return 0; +} + +static int prepare_high_area_for_htlb(struct mm_struct *mm, unsigned long area) { - unsigned long start = seg << SID_SHIFT; - unsigned long end = (seg+1) << SID_SHIFT; + unsigned long start = area << HTLB_AREA_SHIFT; + unsigned long end = (area+1) << HTLB_AREA_SHIFT; struct vm_area_struct *vma; - BUG_ON(seg >= 16); + BUG_ON(area >= NUM_HIGH_AREAS); /* Check no VMAs are in the region */ vma = find_vma(mm, start); @@ -161,20 +202,53 @@ return 0; } -static int open_low_hpage_segs(struct mm_struct *mm, u16 newsegs) +static int open_low_hpage_areas(struct mm_struct *mm, u16 newareas) { unsigned long i; - newsegs &= ~(mm->context.htlb_segs); - if (! newsegs) + BUILD_BUG_ON((sizeof(newareas)*8) != NUM_LOW_AREAS); + BUILD_BUG_ON((sizeof(mm->context.low_htlb_areas)*8) != NUM_LOW_AREAS); + + newareas &= ~(mm->context.low_htlb_areas); + if (! newareas) return 0; /* The segments we want are already open */ - for (i = 0; i < 16; i++) - if ((1 << i) & newsegs) - if (prepare_low_seg_for_htlb(mm, i) != 0) + for (i = 0; i < NUM_LOW_AREAS; i++) + if ((1 << i) & newareas) + if (prepare_low_area_for_htlb(mm, i) != 0) + return -EBUSY; + + mm->context.low_htlb_areas |= newareas; + + /* update the paca copy of the context struct */ + get_paca()->context = mm->context; + + /* the context change must make it to memory before the flush, + * so that further SLB misses do the right thing. */ + mb(); + on_each_cpu(flush_low_segments, (void *)(unsigned long)newareas, 0, 1); + + return 0; +} + +static int open_high_hpage_areas(struct mm_struct *mm, u16 newareas) +{ + unsigned long i; + + BUILD_BUG_ON((sizeof(newareas)*8) != NUM_HIGH_AREAS); + BUILD_BUG_ON((sizeof(mm->context.high_htlb_areas)*8) + != NUM_HIGH_AREAS); + + newareas &= ~(mm->context.high_htlb_areas); + if (! newareas) + return 0; /* The areas we want are already open */ + + for (i = 0; i < NUM_HIGH_AREAS; i++) + if ((1 << i) & newareas) + if (prepare_high_area_for_htlb(mm, i) != 0) return -EBUSY; - mm->context.htlb_segs |= newsegs; + mm->context.high_htlb_areas |= newareas; /* update the paca copy of the context struct */ get_paca()->context = mm->context; @@ -182,29 +256,33 @@ /* the context change must make it to memory before the flush, * so that further SLB misses do the right thing. */ mb(); - on_each_cpu(flush_segments, (void *)(unsigned long)newsegs, 0, 1); + on_each_cpu(flush_high_segments, (void *)(unsigned long)newareas, 0, 1); return 0; } int prepare_hugepage_range(unsigned long addr, unsigned long len) { - if (within_hugepage_high_range(addr, len)) - return 0; - else if ((addr < 0x100000000UL) && ((addr+len) < 0x100000000UL)) { - int err; - /* Yes, we need both tests, in case addr+len overflows - * 64-bit arithmetic */ - err = open_low_hpage_segs(current->mm, + int err; + + if ( (addr+len) < addr ) + return -EINVAL; + + if ((addr + len) < 0x100000000UL) + err = open_low_hpage_areas(current->mm, LOW_ESID_MASK(addr, len)); - if (err) - printk(KERN_DEBUG "prepare_hugepage_range(%lx, %lx)" - " failed (segs: 0x%04hx)\n", addr, len, - LOW_ESID_MASK(addr, len)); + else + err = open_high_hpage_areas(current->mm, + HTLB_AREA_MASK(addr, len)); + if (err) { + printk(KERN_DEBUG "prepare_hugepage_range(%lx, %lx)" + " failed (lowmask: 0x%04hx, highmask: 0x%04hx)\n", + addr, len, + LOW_ESID_MASK(addr, len), HTLB_AREA_MASK(addr, len)); return err; } - return -EINVAL; + return 0; } struct page * @@ -276,8 +354,8 @@ vma = find_vma(mm, addr); continue; } - if (touches_hugepage_high_range(addr, len)) { - addr = TASK_HPAGE_END; + if (touches_hugepage_high_range(mm, addr, len)) { + addr = ALIGN(addr+1, 1UL<mm, addr); - for (vma = find_vma(current->mm, addr); - addr + len <= TASK_HPAGE_END; - vma = vma->vm_next) { + while (addr + len <= TASK_SIZE_USER64) { BUG_ON(vma && (addr >= vma->vm_end)); /* invariant */ - BUG_ON(! within_hugepage_high_range(addr, len)); + + if (! __within_hugepage_high_range(addr, len, areamask)) { + addr = ALIGN(addr+1, 1UL<mm, addr); + continue; + } if (!vma || (addr + len) <= vma->vm_start) return addr; addr = ALIGN(vma->vm_end, HPAGE_SIZE); - /* Because we're in a hugepage region, this alignment - * should not skip us over any VMAs */ + /* Depending on segmask this might not be a confirmed + * hugepage region, so the ALIGN could have skipped + * some VMAs */ + vma = find_vma(current->mm, addr); } return -ENOMEM; @@ -474,6 +558,9 @@ unsigned long len, unsigned long pgoff, unsigned long flags) { + int lastshift; + u16 areamask, curareas; + if (len & ~HPAGE_MASK) return -EINVAL; @@ -481,31 +568,49 @@ return -EINVAL; if (test_thread_flag(TIF_32BIT)) { - int lastshift = 0; - u16 segmask, cursegs = current->mm->context.htlb_segs; + curareas = current->mm->context.low_htlb_areas; /* First see if we can do the mapping in the existing - * low hpage segments */ - addr = htlb_get_low_area(len, cursegs); + * low areas */ + addr = htlb_get_low_area(len, curareas); if (addr != -ENOMEM) return addr; - for (segmask = LOW_ESID_MASK(0x100000000UL-len, len); - ! lastshift; segmask >>=1) { - if (segmask & 1) + lastshift = 0; + for (areamask = LOW_ESID_MASK(0x100000000UL-len, len); + ! lastshift; areamask >>=1) { + if (areamask & 1) lastshift = 1; - addr = htlb_get_low_area(len, cursegs | segmask); + addr = htlb_get_low_area(len, curareas | areamask); if ((addr != -ENOMEM) - && open_low_hpage_segs(current->mm, segmask) == 0) + && open_low_hpage_areas(current->mm, areamask) == 0) return addr; } - printk(KERN_DEBUG "hugetlb_get_unmapped_area() unable to open" - " enough segments\n"); - return -ENOMEM; } else { - return htlb_get_high_area(len); + curareas = current->mm->context.high_htlb_areas; + + /* First see if we can do the mapping in the existing + * high areas */ + addr = htlb_get_high_area(len, curareas); + if (addr != -ENOMEM) + return addr; + + lastshift = 0; + for (areamask = HTLB_AREA_MASK(TASK_SIZE_USER64-len, len); + ! lastshift; areamask >>=1) { + if (areamask & 1) + lastshift = 1; + + addr = htlb_get_high_area(len, curareas | areamask); + if ((addr != -ENOMEM) + && open_high_hpage_areas(current->mm, areamask) == 0) + return addr; + } } + printk(KERN_DEBUG "hugetlb_get_unmapped_area() unable to open" + " enough areas\n"); + return -ENOMEM; } int hash_huge_page(struct mm_struct *mm, unsigned long access, Index: working-2.6/include/asm-ppc64/mmu.h =================================================================== --- working-2.6.orig/include/asm-ppc64/mmu.h 2005-08-11 16:07:28.000000000 +1000 +++ working-2.6/include/asm-ppc64/mmu.h 2005-08-11 16:07:29.000000000 +1000 @@ -304,7 +304,7 @@ typedef struct { mm_context_id_t id; #ifdef CONFIG_HUGETLB_PAGE - u16 htlb_segs; /* bitmask */ + u16 low_htlb_areas, high_htlb_areas; #endif } mm_context_t; Index: working-2.6/include/asm-ppc64/page.h =================================================================== --- working-2.6.orig/include/asm-ppc64/page.h 2005-08-11 16:07:28.000000000 +1000 +++ working-2.6/include/asm-ppc64/page.h 2005-08-11 16:07:29.000000000 +1000 @@ -37,40 +37,45 @@ #define HUGETLB_PAGE_ORDER (HPAGE_SHIFT - PAGE_SHIFT) -/* For 64-bit processes the hugepage range is 1T-1.5T */ -#define TASK_HPAGE_BASE ASM_CONST(0x0000010000000000) -#define TASK_HPAGE_END ASM_CONST(0x0000018000000000) +#define HTLB_AREA_SHIFT 40 +#define HTLB_AREA_SIZE (1UL << HTLB_AREA_SHIFT) +#define GET_HTLB_AREA(x) ((x) >> HTLB_AREA_SHIFT) #define LOW_ESID_MASK(addr, len) (((1U << (GET_ESID(addr+len-1)+1)) \ - (1U << GET_ESID(addr))) & 0xffff) +#define HTLB_AREA_MASK(addr, len) (((1U << (GET_HTLB_AREA(addr+len-1)+1)) \ + - (1U << GET_HTLB_AREA(addr))) & 0xffff) #define ARCH_HAS_HUGEPAGE_ONLY_RANGE #define ARCH_HAS_PREPARE_HUGEPAGE_RANGE #define ARCH_HAS_SETCLEAR_HUGE_PTE #define touches_hugepage_low_range(mm, addr, len) \ - (LOW_ESID_MASK((addr), (len)) & mm->context.htlb_segs) -#define touches_hugepage_high_range(addr, len) \ - (((addr) > (TASK_HPAGE_BASE-(len))) && ((addr) < TASK_HPAGE_END)) + (LOW_ESID_MASK((addr), (len)) & (mm)->context.low_htlb_areas) +#define touches_hugepage_high_range(mm, addr, len) \ + (HTLB_AREA_MASK((addr), (len)) & (mm)->context.high_htlb_areas) #define __within_hugepage_low_range(addr, len, segmask) \ ((LOW_ESID_MASK((addr), (len)) | (segmask)) == (segmask)) #define within_hugepage_low_range(addr, len) \ __within_hugepage_low_range((addr), (len), \ - current->mm->context.htlb_segs) -#define within_hugepage_high_range(addr, len) (((addr) >= TASK_HPAGE_BASE) \ - && ((addr)+(len) <= TASK_HPAGE_END) && ((addr)+(len) >= (addr))) + current->mm->context.low_htlb_areas) +#define __within_hugepage_high_range(addr, len, zonemask) \ + ((HTLB_AREA_MASK((addr), (len)) | (zonemask)) == (zonemask)) +#define within_hugepage_high_range(addr, len) \ + __within_hugepage_high_range((addr), (len), \ + current->mm->context.high_htlb_areas) #define is_hugepage_only_range(mm, addr, len) \ - (touches_hugepage_high_range((addr), (len)) || \ + (touches_hugepage_high_range((mm), (addr), (len)) || \ touches_hugepage_low_range((mm), (addr), (len))) #define HAVE_ARCH_HUGETLB_UNMAPPED_AREA #define in_hugepage_area(context, addr) \ (cpu_has_feature(CPU_FTR_16M_PAGE) && \ - ( (((addr) >= TASK_HPAGE_BASE) && ((addr) < TASK_HPAGE_END)) || \ + ( ((1 << GET_HTLB_AREA(addr)) & (context).high_htlb_areas) || \ ( ((addr) < 0x100000000L) && \ - ((1 << GET_ESID(addr)) & (context).htlb_segs) ) ) ) + ((1 << GET_ESID(addr)) & (context).low_htlb_areas) ) ) ) #else /* !CONFIG_HUGETLB_PAGE */ Index: working-2.6/arch/ppc64/mm/slb_low.S =================================================================== --- working-2.6.orig/arch/ppc64/mm/slb_low.S 2005-08-11 16:07:28.000000000 +1000 +++ working-2.6/arch/ppc64/mm/slb_low.S 2005-08-11 16:07:29.000000000 +1000 @@ -89,28 +89,29 @@ b 9f 0: /* user address: proto-VSID = context<<15 | ESID */ - li r11,SLB_VSID_USER - srdi. r9,r3,USER_ESID_BITS bne- 8f /* invalid ea bits set */ #ifdef CONFIG_HUGETLB_PAGE BEGIN_FTR_SECTION - /* check against the hugepage ranges */ - cmpldi r3,(TASK_HPAGE_END>>SID_SHIFT) - bge 6f /* >= TASK_HPAGE_END */ - cmpldi r3,(TASK_HPAGE_BASE>>SID_SHIFT) - bge 5f /* TASK_HPAGE_BASE..TASK_HPAGE_END */ + lhz r9,PACAHIGHHTLBAREAS(r13) + srdi r11,r3,(HTLB_AREA_SHIFT-SID_SHIFT) + srd r9,r9,r11 + andi. r9,r9,1 + bne 5f + + li r11,SLB_VSID_USER + cmpldi r3,16 - bge 6f /* 4GB..TASK_HPAGE_BASE */ + bge 6f - lhz r9,PACAHTLBSEGS(r13) + lhz r9,PACALOWHTLBAREAS(r13) srd r9,r9,r3 andi. r9,r9,1 + beq 6f -5: /* this is a hugepage user address */ - li r11,(SLB_VSID_USER|SLB_VSID_L) +5: li r11,SLB_VSID_USER|SLB_VSID_L END_FTR_SECTION_IFSET(CPU_FTR_16M_PAGE) #endif /* CONFIG_HUGETLB_PAGE */ -- David Gibson | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/people/dgibson From olh at suse.de Fri Aug 12 00:56:48 2005 From: olh at suse.de (Olaf Hering) Date: Thu, 11 Aug 2005 16:56:48 +0200 Subject: [PATCH] PPC64: Fix non-LPAR IOMMU table allocation on pSeries In-Reply-To: <20050810110224.GA15674@suse.de> References: <20050810032437.GC6300@austin.ibm.com> <20050810110224.GA15674@suse.de> Message-ID: <20050811145648.GA24483@suse.de> On Wed, Aug 10, Olaf Hering wrote: > On Tue, Aug 09, Olof Johansson wrote: > > > Hi, > > > > This is for the 2.6.14 feed. I wouldn't recommend pushing it into > > 2.6.13 due to risk of regressing some box that I don't have access to > > for testing. > > > > I'd appreciate it if people with pre-POWER5, non-LPAR machines would give > > this a go on their boxes and let me know if something falls apart. It's > > been tested on an F80 and a p650 (SMP mode) here. p615 and p630 have > > been sore spots in the past. > > This does not help a p660. But it works on the p620. From hollisb at us.ibm.com Fri Aug 12 01:54:37 2005 From: hollisb at us.ibm.com (Hollis Blanchard) Date: Thu, 11 Aug 2005 10:54:37 -0500 Subject: GDB backtrace and signal trampolines Message-ID: GDB 6.3 contains this code in ppc-linux-tdep.c: static const struct frame_unwind * ppc_linux_sigtramp_sniffer (struct frame_info *next_frame) { struct gdbarch_tdep *tdep = gdbarch_tdep (get_frame_arch (next_frame)); if (frame_pc_unwind (next_frame) > frame_unwind_register_unsigned (next_frame, SP_REGNUM)) /* Assume anything that is vaguely on the stack is a signal trampoline. */ return &ppc_linux_sigtramp_unwind; else return NULL; } Essentially it says that any time the program counter is above the stack pointer, we must be in a signal trampoline, and so GDB proceeds to grope about for a struct rt_sigframe on the stack. This is not a good assumption. I'm using a GDB stub to debug Xen, and as it so happens, the Xen stack is below the Xen text. That means that the above test always triggers, but of course there is no rt_sigframe on the stack, and my backtrace runs away. Would it make sense to limit the test to within a few hundred bytes of the stack pointer? Or some better way to detect that the PC is in a signal trampoline? (Also, how can I test backtraces within a signal trampoline? I've single-stepped my way into and out of a signal hander, and never saw the PC inside the stack.) -- Hollis Blanchard IBM Linux Technology Center From mbellon at mvista.com Fri Aug 12 03:26:14 2005 From: mbellon at mvista.com (Mark Bellon) Date: Thu, 11 Aug 2005 10:26:14 -0700 Subject: [Fwd: [PATCH] PPC64: large INITRD causes kernel not to boot] In-Reply-To: References: <1b082f286ff07d6348211697ef38a608@bga.com> <42FA220C.1090109@mvista.com> Message-ID: <42FB8A36.3020009@mvista.com> Milton Miller wrote: > > On Aug 10, 2005, at 10:49 AM, Mark Bellon wrote: > >> Milton Miller wrote: >> >>>> >>>> - printf("\n\rzImage starting: loaded at 0x%x\n\r", >>>> (unsigned)_start); >>>> + printf("\n\rzImage starting: loaded at 0x%lx\n\r", (unsigned >>>> long) _start); >>>> + >>>> + /* >>>> + * The first available claim_base must be above the end of the >>>> + * the loaded kernel file (_start to _end) and rounded up to a >>>> + * nice 1 MB boundary. >>>> + */ >>>> + >>>> + claim_base = ((((unsigned long) _end) + ONE_MB - 1) / ONE_MB) >>>> * ONE_MB; >>>> >>>> >>> >>> _start and _end here are the linked runtime range of the zImage program >>> not the kernel image contained therein. This also contains the >>> initrd. >>> >>> Milton >>> >> Exactly. The claim_base needs to start after the kernel and initrd. >> Since _end is above the "top" of the initrd it's perfect to use as >> the base for the round up calculation for the starting claim_base. >> >> mark >> > > My unstated request was to fix the misleading comment. Change > "loaded kernel file" to something like "this running program" or > "image" or something. I posted an update yesterday with improved comments and a tweak. Thanks for the comment. I was a bit unclear in my response. > Something to be aware of: the program gets loaded at load-base and > then the sections get moved to their linked area. It is explicitly > stated that while the fw has to maintain the elf header, it does > *NOT* need to worry about overlaping source and desitination. True, as long as the address returned from claim is not in the middle of the image of the loaded kernel wrapper file (which is what was happening). > In other words, there is an implied copy from elf file loaded into > ram at ram-base to the _start,_end range that doesn't look for > overlap. OK. > > milton > From geoffrey.levand at am.sony.com Fri Aug 12 04:19:09 2005 From: geoffrey.levand at am.sony.com (Geoff Levand) Date: Thu, 11 Aug 2005 11:19:09 -0700 Subject: [PATCH 1/2] ppc64: zimage build fix In-Reply-To: <200508111215.09284.michael@ellerman.id.au> References: <200508111215.09284.michael@ellerman.id.au> Message-ID: <42FB969D.8030708@am.sony.com> Michael Ellerman wrote: > Sorry I didn't comment on this earlier. > > I don't know about others, but I have a bunch of scripts and so on that > expect > a pSeries build to produce a "zImage" - all of which would have to be > changed > to cope with this patch. > > On the other hand I don't have any scripts that expect a G5 build to > produce a > zImage. > > So it would seem more logical to me leave zImage as is, and create a new > zImage.g5 or zImage.realmode or whatever you want to call it. > Yes, I was concerned about this, but no one spoke up... It's not specific to the G5, that's just a common platform that it would work on, so I don't want to tie it to that. Also, from what I understand, it is the pSeries OF that is running in real mode. So, what about zImage.elf-vmode or zImage.vmode? Anyone have a request or suggestion? -Geoff > > On Thu, 11 Aug 2005 10:57, Geoff Levand wrote: > >>Please consider for inclusion in the post 2.6.13 patches. >> >>-Geoff >> >> >> >>This patch makes it possible to build ppc64 kernel image files for all >>targeted machines when several CONFIG_PPC_XXX machine type options are >>enabled simultaneously. To accomplish this it introduces two new >> build >>targets, zImage.rs6k and zImage.initrd.rs6, which will make the proper >>ELF note header needed by pSeries machines. It falls out from these >>changes that compressed zImages for the Powermac G5 can now be built. >>Previously only vmlinux images could be for that machine. >> From trini at kernel.crashing.org Fri Aug 12 05:59:27 2005 From: trini at kernel.crashing.org (Tom Rini) Date: Thu, 11 Aug 2005 12:59:27 -0700 Subject: RFC: proposed arch/powerpc directory structure In-Reply-To: References: Message-ID: <20050811195927.GX3187@smtp.west.cox.net> On Wed, Aug 10, 2005 at 11:45:10AM -0500, Becky Bruce wrote: [snip] > platforms/ > - platform-specific code laid out in the following > directories: > pSeries/ > iSeries/ > pmac/ (both 32 and 64-bit) > classic32/ (platforms containing > 6xx/7xx/74xx/8240/8241/8245) > classic64/ (Maple?) I'm a bit ppc64-ignorant, but isn't 'pSeries' just a regular OpenFirmware-containing ppc64 box (like Maple) ? How about just 9xx/ for all of the ppc64's that have a 9xx in them (Maple), that aren't pmac (which is a class of its own). > 83xx/ (may collapse into classic 32 at some point) > 86xx/ (may collapse into classic 32 at some point) > pq2/ (may collapse into classic 32 at some point) PQ2 is the marketing name for 82xx, lets just call it 82xx. I don't like the idea of sticking subdirs in classic32/ either, but also can't think of a better name for the catchall of 7xx and 74xx boards. -- Tom Rini http://gate.crashing.org/~trini/ From kumar.gala at freescale.com Fri Aug 12 06:13:30 2005 From: kumar.gala at freescale.com (Kumar Gala) Date: Thu, 11 Aug 2005 15:13:30 -0500 Subject: RFC: proposed arch/powerpc directory structure In-Reply-To: <20050811195927.GX3187@smtp.west.cox.net> References: <20050811195927.GX3187@smtp.west.cox.net> Message-ID: On Aug 11, 2005, at 2:59 PM, Tom Rini wrote: > On Wed, Aug 10, 2005 at 11:45:10AM -0500, Becky Bruce wrote: > > [snip] > >> platforms/ >> - platform-specific code laid out in the following >> directories: >> pSeries/ >> iSeries/ >> pmac/ (both 32 and 64-bit) >> classic32/ (platforms containing >> 6xx/7xx/74xx/8240/8241/8245) >> classic64/ (Maple?) >> > > I'm a bit ppc64-ignorant, but isn't 'pSeries' just a regular > OpenFirmware-containing ppc64 box (like Maple) ? How about just 9xx/ > for all of the ppc64's that have a 9xx in them (Maple), that aren't > pmac > (which is a class of its own). > > >> 83xx/ (may collapse into classic 32 at some point) >> 86xx/ (may collapse into classic 32 at some point) >> pq2/ (may collapse into classic 32 at some point) >> > > PQ2 is the marketing name for 82xx, lets just call it 82xx. The problem is that PQ2 describes a subset of 82xx (it nots 8240/8241/8245). > I don't like the idea of sticking subdirs in classic32/ either, but > also > can't think of a better name for the catchall of 7xx and 74xx boards. I dont think we where planning on subdirs in classic32. - kumar From trini at kernel.crashing.org Fri Aug 12 06:18:21 2005 From: trini at kernel.crashing.org (Tom Rini) Date: Thu, 11 Aug 2005 13:18:21 -0700 Subject: RFC: proposed arch/powerpc directory structure In-Reply-To: References: <20050811195927.GX3187@smtp.west.cox.net> Message-ID: <20050811201821.GY3187@smtp.west.cox.net> On Thu, Aug 11, 2005 at 03:13:30PM -0500, Kumar Gala wrote: > > On Aug 11, 2005, at 2:59 PM, Tom Rini wrote: > > >On Wed, Aug 10, 2005 at 11:45:10AM -0500, Becky Bruce wrote: > > > >[snip] [snip] > >> 83xx/ (may collapse into classic 32 at some point) > >> 86xx/ (may collapse into classic 32 at some point) > >> pq2/ (may collapse into classic 32 at some point) > >> > > > >PQ2 is the marketing name for 82xx, lets just call it 82xx. > > The problem is that PQ2 describes a subset of 82xx (it nots > 8240/8241/8245). All the more reason imho to stick all 82xx stuff under '82xx', rather than classic32 or 'pq2'. > >I don't like the idea of sticking subdirs in classic32/ either, but > >also > >can't think of a better name for the catchall of 7xx and 74xx boards. > > I dont think we where planning on subdirs in classic32. I took "may collapse into classic 32 at some point" to mean "move into classic32/ at some point", for some reason. collapsing the content into classic32/ will bring us back to the bad-old-days of everything in platforms/ (or kernel/). -- Tom Rini http://gate.crashing.org/~trini/ From olh at suse.de Fri Aug 12 06:25:36 2005 From: olh at suse.de (Olaf Hering) Date: Thu, 11 Aug 2005 22:25:36 +0200 Subject: RFC: proposed arch/powerpc directory structure In-Reply-To: References: Message-ID: <20050811202536.GA4220@suse.de> On Wed, Aug 10, Becky Bruce wrote: > boot/ > - Pre-kernel execution shims and pre-passes. > - Convert firmware reprensentations (bi_recs, OF Dev-Trees, > bootx,bd_t) to flat-dev-trees. > - Includes merged files from arch/ppc*/boot/ trees, plus > prom_init.c from arch/ppc64/kernel. This should live outside the kernel source, in a $mkzimage project. From jschopp at austin.ibm.com Fri Aug 12 08:33:04 2005 From: jschopp at austin.ibm.com (Joel Schopp) Date: Thu, 11 Aug 2005 17:33:04 -0500 Subject: Coverity found bugs Message-ID: <42FBD220.9020109@austin.ibm.com> I recently got Coverity Prevent ( http://coverity.com/ ) for x86 Linux. Through the modern miracle of cross compiling I got it to spit out what it thinks are errors in the ppc64 kernel. Hundreds of them. I plan on fixing as many of these as I have time for, starting with the arch specific ones, which I will post as replies to this message. I will leave individual fixes in individual patches for now, but if it starts to get excessive I will group batches of them into single patches. From jschopp at austin.ibm.com Fri Aug 12 08:37:31 2005 From: jschopp at austin.ibm.com (Joel Schopp) Date: Thu, 11 Aug 2005 17:37:31 -0500 Subject: [PATCH 1/?] hugetlbpage.c useless code In-Reply-To: <42FBD220.9020109@austin.ibm.com> References: <42FBD220.9020109@austin.ibm.com> Message-ID: <42FBD32B.3010908@austin.ibm.com> Remove useless code. Signed-off-by: Joel Schopp -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: 2845.patch Url: http://ozlabs.org/pipermail/linuxppc64-dev/attachments/20050811/3c22537b/attachment.txt From jschopp at austin.ibm.com Fri Aug 12 08:39:28 2005 From: jschopp at austin.ibm.com (Joel Schopp) Date: Thu, 11 Aug 2005 17:39:28 -0500 Subject: [PATCH 2/?] of_device.c remove useless code In-Reply-To: <42FBD220.9020109@austin.ibm.com> References: <42FBD220.9020109@austin.ibm.com> Message-ID: <42FBD3A0.10503@austin.ibm.com> Coverity found more unused code. Signed-off-by: Joel Schopp -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: 2848.patch Url: http://ozlabs.org/pipermail/linuxppc64-dev/attachments/20050811/e824f20b/attachment.txt From becky.bruce at freescale.com Fri Aug 12 08:41:36 2005 From: becky.bruce at freescale.com (Becky Bruce) Date: Thu, 11 Aug 2005 17:41:36 -0500 Subject: RFC: proposed arch/powerpc directory structure In-Reply-To: <20050811201821.GY3187@smtp.west.cox.net> References: <20050811195927.GX3187@smtp.west.cox.net> <20050811201821.GY3187@smtp.west.cox.net> Message-ID: > >>> I don't like the idea of sticking subdirs in classic32/ either, but >>> also >>> can't think of a better name for the catchall of 7xx and 74xx boards. >> >> I dont think we where planning on subdirs in classic32. > > I took "may collapse into classic 32 at some point" to mean "move into > classic32/ at some point", for some reason. collapsing the content > into > classic32/ will bring us back to the bad-old-days of everything in > platforms/ (or kernel/). My apologies - this wasn't at all clear in the proposal. The plan at present is to not have subdirs under classic32. By "collapsing into classic32", I meant a move to a more common code base, not a wholescale copy of the existing files into classic32. Cheers, -B From kumar.gala at freescale.com Fri Aug 12 09:07:03 2005 From: kumar.gala at freescale.com (Kumar Gala) Date: Thu, 11 Aug 2005 18:07:03 -0500 Subject: RFC: proposed arch/powerpc directory structure In-Reply-To: <20050811201821.GY3187@smtp.west.cox.net> References: <20050811201821.GY3187@smtp.west.cox.net> Message-ID: On Aug 11, 2005, at 3:18 PM, Tom Rini wrote: > On Thu, Aug 11, 2005 at 03:13:30PM -0500, Kumar Gala wrote: > >> >> On Aug 11, 2005, at 2:59 PM, Tom Rini wrote: >> >> >>> On Wed, Aug 10, 2005 at 11:45:10AM -0500, Becky Bruce wrote: >>> >>> [snip] >>> > [snip] > >>>> 83xx/ (may collapse into classic 32 at some point) >>>> 86xx/ (may collapse into classic 32 at some point) >>>> pq2/ (may collapse into classic 32 at some point) >>>> >>>> >>> >>> PQ2 is the marketing name for 82xx, lets just call it 82xx. >>> >> >> The problem is that PQ2 describes a subset of 82xx (it nots >> 8240/8241/8245). >> > > All the more reason imho to stick all 82xx stuff under '82xx', rather > than classic32 or 'pq2'. I think this causes confusion. the reason we suggested pq2 and classic32 was to handle things like sandpoint. Sandpoint would live in classic32. The confusion partial comes from the fact that we can run 8240/1/5 on a Sandpoint. The thinking was everything that was 6xx/7xx/74xx + things like 8240/1/5 which can be thought of as 603 + 10x bridge would be classic32. If it was 82xx w/o a CPM it went into classic32. If it was a 82xx w/ CPM it went into pq2. The idea being that we might be able to build kernels in either directory that supported a large number of boards with one image. Anyways, that was the thought process to try and keep things sane. (Which it may not ;) - kumar From trini at kernel.crashing.org Fri Aug 12 09:19:48 2005 From: trini at kernel.crashing.org (Tom Rini) Date: Thu, 11 Aug 2005 16:19:48 -0700 Subject: RFC: proposed arch/powerpc directory structure In-Reply-To: References: <20050811201821.GY3187@smtp.west.cox.net> Message-ID: <20050811231948.GA3187@smtp.west.cox.net> On Thu, Aug 11, 2005 at 06:07:03PM -0500, Kumar Gala wrote: [snip] > I think this causes confusion. the reason we suggested pq2 and > classic32 was to handle things like sandpoint. Sandpoint would live > in classic32. The confusion partial comes from the fact that we can > run 8240/1/5 on a Sandpoint. The thinking was everything that was > 6xx/7xx/74xx + things like 8240/1/5 which can be thought of as 603 + > 10x bridge would be classic32. Thanks for the explanation. But I think this is overkill for the sandpoint or true like a sandpoint (Zynx something, Willow, neither of which are in the kernel tree). I think we can field the "I wanna hack on my Sandpoint/8240, but don't see the code under 82xx/!" question. :) > If it was 82xx w/o a CPM it went into classic32. If it was a 82xx w/ > CPM it went into pq2. The idea being that we might be able to build > kernels in either directory that supported a large number of boards > with one image. We can certainly investigate just how many distinct boards can be supported with one image when infos are passed dynamically. If we can simplify things enough, maybe we can break the rule of no .[ch] files in arch/powerpc/platforms since it'll just be 82xx.[ch], 83xx.[ch] and so on, execept for that damn pmac. ;) -- Tom Rini http://gate.crashing.org/~trini/ From dan at embeddededge.com Fri Aug 12 09:29:57 2005 From: dan at embeddededge.com (Dan Malek) Date: Thu, 11 Aug 2005 19:29:57 -0400 Subject: RFC: proposed arch/powerpc directory structure In-Reply-To: References: <20050811201821.GY3187@smtp.west.cox.net> Message-ID: On Aug 11, 2005, at 7:07 PM, Kumar Gala wrote: > ...... The idea being that we might be able to build kernels in > either directory that supported a large number of boards with one > image. Please don't go there :-) I'm having enough trouble meeting reasonable performance goals in 2.6 on embedded systems that I don't need the overhead of code bloat or extra cycles to determine what board I'm on. Contrary to the belief of developers, products don't have the resource wealth we see on these evaluation and ODM boards. Embedded products still require we build kernels (and everything else) as concisely and efficient as possible. Thanks. -- Dan From kumar.gala at freescale.com Fri Aug 12 12:34:57 2005 From: kumar.gala at freescale.com (Kumar Gala) Date: Thu, 11 Aug 2005 21:34:57 -0500 Subject: RFC: proposed arch/powerpc directory structure In-Reply-To: <20050811231948.GA3187@smtp.west.cox.net> References: <20050811231948.GA3187@smtp.west.cox.net> Message-ID: <9C2E830E-288C-4373-BDE3-49C5FE47A01C@freescale.com> On Aug 11, 2005, at 6:19 PM, Tom Rini wrote: > On Thu, Aug 11, 2005 at 06:07:03PM -0500, Kumar Gala wrote: > [snip] > >> I think this causes confusion. the reason we suggested pq2 and >> classic32 was to handle things like sandpoint. Sandpoint would live >> in classic32. The confusion partial comes from the fact that we can >> run 8240/1/5 on a Sandpoint. The thinking was everything that was >> 6xx/7xx/74xx + things like 8240/1/5 which can be thought of as 603 + >> 10x bridge would be classic32. >> > > Thanks for the explanation. But I think this is overkill for the > sandpoint or true like a sandpoint (Zynx something, Willow, neither of > which are in the kernel tree). I think we can field the "I wanna hack > on my Sandpoint/8240, but don't see the code under 82xx/!" > question. :) So where do you suggest Sandpoint goes in this directory structure? - kumar From jwboyer at jdub.homelinux.org Fri Aug 12 12:09:44 2005 From: jwboyer at jdub.homelinux.org (Josh Boyer) Date: Thu, 11 Aug 2005 21:09:44 -0500 Subject: RFC: proposed arch/powerpc directory structure In-Reply-To: <20050811195927.GX3187@smtp.west.cox.net> References: <20050811195927.GX3187@smtp.west.cox.net> Message-ID: <1123812584.3299.18.camel@yoda.jdub.homelinux.org> On Thu, 2005-08-11 at 12:59 -0700, Tom Rini wrote: > On Wed, Aug 10, 2005 at 11:45:10AM -0500, Becky Bruce wrote: > > [snip] > > platforms/ > > - platform-specific code laid out in the following > > directories: > > pSeries/ > > iSeries/ > > pmac/ (both 32 and 64-bit) > > classic32/ (platforms containing > > 6xx/7xx/74xx/8240/8241/8245) > > classic64/ (Maple?) > > I'm a bit ppc64-ignorant, but isn't 'pSeries' just a regular > OpenFirmware-containing ppc64 box (like Maple) ? How about just 9xx/ > for all of the ppc64's that have a 9xx in them (Maple), that aren't pmac > (which is a class of its own). I myself am also pretty ppc64 ignorant, but I do know that not all pSeries are 9xx based. There are POWER 4 and POWER 5 pSeries boxes too. josh From trini at kernel.crashing.org Fri Aug 12 13:38:50 2005 From: trini at kernel.crashing.org (Tom Rini) Date: Thu, 11 Aug 2005 20:38:50 -0700 Subject: RFC: proposed arch/powerpc directory structure In-Reply-To: <9C2E830E-288C-4373-BDE3-49C5FE47A01C@freescale.com> References: <20050811231948.GA3187@smtp.west.cox.net> <9C2E830E-288C-4373-BDE3-49C5FE47A01C@freescale.com> Message-ID: <20050812033850.GB3187@smtp.west.cox.net> On Thu, Aug 11, 2005 at 09:34:57PM -0500, Kumar Gala wrote: > > On Aug 11, 2005, at 6:19 PM, Tom Rini wrote: > > >On Thu, Aug 11, 2005 at 06:07:03PM -0500, Kumar Gala wrote: > >[snip] > > > >>I think this causes confusion. the reason we suggested pq2 and > >>classic32 was to handle things like sandpoint. Sandpoint would live > >>in classic32. The confusion partial comes from the fact that we can > >>run 8240/1/5 on a Sandpoint. The thinking was everything that was > >>6xx/7xx/74xx + things like 8240/1/5 which can be thought of as 603 + > >>10x bridge would be classic32. > >> > > > >Thanks for the explanation. But I think this is overkill for the > >sandpoint or true like a sandpoint (Zynx something, Willow, neither of > >which are in the kernel tree). I think we can field the "I wanna hack > >on my Sandpoint/8240, but don't see the code under 82xx/!" > >question. :) > > So where do you suggest Sandpoint goes in this directory structure? classic32/ -- Tom Rini http://gate.crashing.org/~trini/ From paulus at samba.org Fri Aug 12 13:49:22 2005 From: paulus at samba.org (Paul Mackerras) Date: Fri, 12 Aug 2005 13:49:22 +1000 Subject: RFC: proposed arch/powerpc directory structure In-Reply-To: <20050811195927.GX3187@smtp.west.cox.net> References: <20050811195927.GX3187@smtp.west.cox.net> Message-ID: <17148.7234.193140.997481@cargo.ozlabs.ibm.com> Tom Rini writes: > I'm a bit ppc64-ignorant, but isn't 'pSeries' just a regular > OpenFirmware-containing ppc64 box (like Maple) ? How about just 9xx/ Ummm, no, not exactly. The distinctive thing about pSeries is the hypervisor interfaces. And in fact most pSeries boxes aren't 970-based, rather POWER4/4+/5. If you want to generalize, we could call the directory "papr" (for Power Architecture Platform Requirements, the name of the document that describes the pSeries platforms) rather than pSeries, but I suspect that would just confuse people. :) Paul. From trini at kernel.crashing.org Fri Aug 12 14:14:43 2005 From: trini at kernel.crashing.org (Tom Rini) Date: Thu, 11 Aug 2005 21:14:43 -0700 Subject: RFC: proposed arch/powerpc directory structure In-Reply-To: <17148.7234.193140.997481@cargo.ozlabs.ibm.com> References: <20050811195927.GX3187@smtp.west.cox.net> <17148.7234.193140.997481@cargo.ozlabs.ibm.com> Message-ID: <20050812041443.GC3187@smtp.west.cox.net> On Fri, Aug 12, 2005 at 01:49:22PM +1000, Paul Mackerras wrote: > Tom Rini writes: > > > I'm a bit ppc64-ignorant, but isn't 'pSeries' just a regular > > OpenFirmware-containing ppc64 box (like Maple) ? How about just 9xx/ > > Ummm, no, not exactly. The distinctive thing about pSeries is the > hypervisor interfaces. And in fact most pSeries boxes aren't > 970-based, rather POWER4/4+/5. If you want to generalize, we could > call the directory "papr" (for Power Architecture Platform > Requirements, the name of the document that describes the pSeries > platforms) rather than pSeries, but I suspect that would just confuse > people. :) Ok. How about 9xx/ instead of classic64 ? -- Tom Rini http://gate.crashing.org/~trini/ From anton at samba.org Fri Aug 12 15:06:09 2005 From: anton at samba.org (Anton Blanchard) Date: Fri, 12 Aug 2005 15:06:09 +1000 Subject: GDB backtrace and signal trampolines In-Reply-To: References: Message-ID: <20050812050609.GA7355@krispykreme> Hi, > Would it make sense to limit the test to within a few hundred bytes of > the stack pointer? Or some better way to detect that the PC is in a > signal trampoline? With recent kernels we should be able to use the dwarf2 unwind information in the vdso I think. Anton From security at BankOfTheWest.com Fri Aug 12 23:16:20 2005 From: security at BankOfTheWest.com (BankOfTheWest) Date: Fri, 12 Aug 2005 16:16:20 +0300 Subject: BankOfTheWest Inc: Please Confirm Your Banking Details [Fri, 12 Aug 2005 12:38:14 -0100] Message-ID: <20050812131653.85282331E8@ns.coninsalt.ro> An HTML attachment was scrubbed... URL: http://ozlabs.org/pipermail/linuxppc64-dev/attachments/20050812/bf3d015c/attachment.htm From hollisb at us.ibm.com Fri Aug 12 23:58:32 2005 From: hollisb at us.ibm.com (Hollis Blanchard) Date: Fri, 12 Aug 2005 08:58:32 -0500 Subject: GDB backtrace and signal trampolines In-Reply-To: <20050812050609.GA7355@krispykreme> References: <20050812050609.GA7355@krispykreme> Message-ID: <3b9a91d3eebf79c9cc8a2b67cc5e3f84@us.ibm.com> On Aug 12, 2005, at 12:06 AM, Anton Blanchard wrote: > >> Would it make sense to limit the test to within a few hundred bytes of >> the stack pointer? Or some better way to detect that the PC is in a >> signal trampoline? > > With recent kernels we should be able to use the dwarf2 unwind > information in the vdso I think. I guess compatibility with older kernels will still need to be maintained, though. I see this note in arch/ppc64/mm/fault.c: /* * N.B. The POWER/Open ABI allows programs to access up to * 288 bytes below the stack pointer. * The kernel signal delivery code writes up to about 1.5kB * below the stack pointer (r1) before decrementing it. * The exec code can write slightly over 640kB to the stack * before setting the user r1. Thus we allow the stack to * expand to 1MB without further checks. */ So would 2KB be a reasonable limit to the signal frame check, as I described before? -- Hollis Blanchard IBM Linux Technology Center From jschopp at austin.ibm.com Sat Aug 13 05:13:36 2005 From: jschopp at austin.ibm.com (Joel Schopp) Date: Fri, 12 Aug 2005 14:13:36 -0500 Subject: [PATCH 3/?] lparconfig.c memory leak In-Reply-To: <42FBD220.9020109@austin.ibm.com> References: <42FBD220.9020109@austin.ibm.com> Message-ID: <42FCF4E0.8070002@austin.ibm.com> This patch fixes a rare memory leak found by Coverity. -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: 2954.patch Url: http://ozlabs.org/pipermail/linuxppc64-dev/attachments/20050812/807d5e48/attachment.txt From olof at lixom.net Sat Aug 13 05:27:41 2005 From: olof at lixom.net (Olof Johansson) Date: Fri, 12 Aug 2005 14:27:41 -0500 Subject: [PATCH 3/?] lparconfig.c memory leak In-Reply-To: <42FCF4E0.8070002@austin.ibm.com> References: <42FBD220.9020109@austin.ibm.com> <42FCF4E0.8070002@austin.ibm.com> Message-ID: <20050812192741.GA7409@austin.ibm.com> On Fri, Aug 12, 2005 at 02:13:36PM -0500, Joel Schopp wrote: > This patch fixes a rare memory leak found by Coverity. Signed-off-by? -Olof From jschopp at austin.ibm.com Sat Aug 13 05:34:58 2005 From: jschopp at austin.ibm.com (Joel Schopp) Date: Fri, 12 Aug 2005 14:34:58 -0500 Subject: [PATCH 3/?] lparconfig.c memory leak In-Reply-To: <42FCF4E0.8070002@austin.ibm.com> References: <42FBD220.9020109@austin.ibm.com> <42FCF4E0.8070002@austin.ibm.com> Message-ID: <42FCF9E2.3010304@austin.ibm.com> This patch fixes a rare memory leak found by Coverity. Signed-off-by: Joel Schopp -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: 2954.patch Url: http://ozlabs.org/pipermail/linuxppc64-dev/attachments/20050812/acc701ba/attachment.txt From miltonm at bga.com Sun Aug 14 06:44:50 2005 From: miltonm at bga.com (Milton Miller) Date: Sat, 13 Aug 2005 15:44:50 -0500 Subject: [PATCH 6/10] ppc64: Create a fake flat device tree on iSeries In-Reply-To: <20050811031425.GA5975@localhost.localdomain> References: <6b57499e431cefc69e65db59b4210b38@bga.com> <20050810083228.GE22335@localhost.localdomain> <20050811031425.GA5975@localhost.localdomain> Message-ID: <132f13582efb822fe7fd9b278c667c49@bga.com> On Aug 10, 2005, at 10:14 PM, David Gibson wrote: > > On Wed, Aug 10, 2005 at 08:59:51AM -0500, Milton Miller wrote: >> >> On Aug 10, 2005, at 3:32 AM, David Gibson wrote: >> >>> On Wed, Aug 10, 2005 at 02:16:15AM -0500, Milton Miller wrote: >>>> Putting the >>>> device data at klimit would allow the checks for overflow to be >>>> deferred until after its created (look for 2 nuls in string table >>>> -- the size is propnum(""), and placing data at after the reserve >>>> map and string table and either compare to total size or set >>>> totalsize according to what is used). >>> >> >> My other generator does this very thing. The strings are allocated >> statically. >> >> While discussing embedded with panto on #mklinux, another approach >> is to say "here's the max", put the strings at the end, and allocate >> new strings down moving the start as we add strings. > > An memmove() on every string insertion? That's kinda horrible.. NO! I agree, that would be. I was saying 1 memmove on "oops we didn't alocate enough, allocate a bigger area" and and optional one after everything else to say "well, we allocated a 16k chunk and used 8 bytes, lets save a 3 pages". By inserting strings by growing down towards the blob we just have to update the start of the string table. I just realized why that doesn't work --- the offset would keep changing. ... this still doesn't keep us from makeing an optimistic guess how much string table and device tree we need an doing a memmove when we were wrong. > >> Makes sense for >> fw where there is a fixed allocation. End of blob processing can >> then memmove the string table and cut total size down. >> >> Even without the knowing the max size realloc could move strings down >> if a space check is added before extending the dt blob. milton From sfr at canb.auug.org.au Mon Aug 15 17:51:15 2005 From: sfr at canb.auug.org.au (Stephen Rothwell) Date: Mon, 15 Aug 2005 17:51:15 +1000 Subject: [PATCH] iSeries build with newer assemblers and compilers Message-ID: <20050815175115.4b789a1c.sfr@canb.auug.org.au> Hi all, This patch makes iSeries build with the newer assemblers and compilers. We had a hack to allow us to move xLparMap out of head.S but that required a horrible bit of inline assembler in LparData.c. When I upgraded Debian unstable in order to use their biarch compiler, even that hack broke. This patch works around the whole compiler/assembler mess by patching the address we care about into the vmlinux after it is built. This should really go in before 2.6.13 if at all possible as we have problematic build systems out there already. Signed-off-by: Stephen Rothwell --- arch/ppc64/Makefile | 8 ++++ arch/ppc64/kernel/LparData.c | 65 ++++--------------------------------- scripts/Makefile | 1 scripts/fix_lparmap.c | 74 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 90 insertions(+), 58 deletions(-) -- Cheers, Stephen Rothwell sfr at canb.auug.org.au http://www.canb.auug.org.au/~sfr/ diff -ruN linus/arch/ppc64/Makefile linus-lparmap/arch/ppc64/Makefile --- linus/arch/ppc64/Makefile 2005-06-27 16:08:00.000000000 +1000 +++ linus-lparmap/arch/ppc64/Makefile 2005-08-15 17:33:09.000000000 +1000 @@ -129,3 +129,11 @@ endef CLEAN_FILES += include/asm-ppc64/offsets.h + +ifeq ($(CONFIG_PPC_ISERIES),y) +cmd_vmlinux__ ?= $(LD) $(LDFLAGS) $(LDFLAGS_vmlinux) -o $@ \ + -T $(vmlinux-lds) $(vmlinux-init) \ + --start-group $(vmlinux-main) --end-group \ + $(filter-out $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) FORCE ,$^); \ + scripts/fix_lparmap `$(OBJDUMP) -t $@ | grep ' xLparMap' | cut -d' ' -f1` $@ +endif diff -ruN linus/arch/ppc64/kernel/LparData.c linus-lparmap/arch/ppc64/kernel/LparData.c --- linus/arch/ppc64/kernel/LparData.c 2005-07-28 11:23:11.000000000 +1000 +++ linus-lparmap/arch/ppc64/kernel/LparData.c 2005-08-15 15:17:00.000000000 +1000 @@ -32,32 +32,18 @@ /* The HvReleaseData is the root of the information shared between * the hypervisor and Linux. */ - -/* - * WARNING - magic here - * - * Ok, this is a horrid hack below, but marginally better than the - * alternatives. What we really want is just to initialize - * hvReleaseData in C as in the #if 0 section here. However, gcc - * refuses to believe that (u32)&x is a constant expression, so will - * not allow the xMsNucDataOffset field to be properly initialized. - * So, we declare hvReleaseData in inline asm instead. We use inline - * asm, rather than a .S file, because the assembler won't generate - * the necessary relocation for the LparMap either, unless that symbol - * is declared in the same source file. Finally, we put the asm in a - * dummy, attribute-used function, instead of at file scope, because - * file scope asms don't allow contraints. We want to use the "i" - * constraints to put sizeof() and offsetof() expressions in there, - * because including asm/offsets.h in C code then stringifying causes - * all manner of warnings. - */ -#if 0 struct HvReleaseData hvReleaseData = { .xDesc = 0xc8a5d9c4, /* "HvRD" ebcdic */ .xSize = sizeof(struct HvReleaseData), .xVpdAreasPtrOffset = offsetof(struct naca_struct, xItVpdAreas), .xSlicNacaAddr = &naca, /* 64-bit Naca address */ - .xMsNucDataOffset = (u32)((unsigned long)&xLparMap - KERNELBASE), + /* + * This next field should be initialiased to + * (u32)((unsigned long)&xLparMap - KERNELBASE) but the compiler + * does not believe that that is a constant expression. We + * will fix this up using by post processing the vmlinux. + */ + .xMsNucDataOffset = 0, .xFlags = HVREL_TAGSINACTIVE /* tags inactive */ /* 64 bit */ /* shared processors */ @@ -70,43 +56,6 @@ 0xa7, 0x40, 0xf2, 0x4b, 0xf4, 0x4b, 0xf6, 0xf4 }, }; -#endif - - -extern struct HvReleaseData hvReleaseData; - -static void __attribute_used__ hvReleaseData_wrapper(void) -{ - /* This doesn't appear to need any alignment (even 4 byte) */ - asm volatile ( - " lparMapPhys = xLparMap - %3\n" - " .data\n" - " .globl hvReleaseData\n" - "hvReleaseData:\n" - " .long 0xc8a5d9c4\n" /* xDesc */ - /* "HvRD" in ebcdic */ - " .short %0\n" /* xSize */ - " .short %1\n" /* xVpdAreasPtrOffset */ - " .llong naca\n" /* xSlicNacaAddr */ - " .long lparMapPhys\n" /* xMsNucDataOffset */ - " .long 0\n" /* xRsvd1 */ - " .short %2\n" /* xFlags */ - " .short 4\n" /* xVrmIndex - v5r2m0 */ - " .short 3\n" /* xMinSupportedPlicVrmIndex - v5r1m0 */ - " .short 3\n" /* xMinCompatablePlicVrmIndex - v5r1m0 */ - " .long 0xd38995a4\n" /* xVrmName */ - " .long 0xa740f24b\n" /* "Linux 2.4.64" ebcdic */ - " .long 0xf44bf6f4\n" - " . = hvReleaseData + %0\n" - " .previous\n" - : : "i"(sizeof(hvReleaseData)), - "i"(offsetof(struct naca_struct, xItVpdAreas)), - "i"(HVREL_TAGSINACTIVE /* tags inactive, 64 bit, */ - /* shared processors, HMT allowed */ - | 6), /* TEMP: This allows non-GA drivers */ - "i"(KERNELBASE) - ); -} struct LparMap __attribute__((aligned (16))) xLparMap = { .xNumberEsids = HvEsidsToMap, diff -ruN linus/scripts/Makefile linus-lparmap/scripts/Makefile --- linus/scripts/Makefile 2005-06-27 16:08:15.000000000 +1000 +++ linus-lparmap/scripts/Makefile 2005-08-15 16:47:44.000000000 +1000 @@ -12,6 +12,7 @@ hostprogs-$(CONFIG_VT) += conmakehash hostprogs-$(CONFIG_PROM_CONSOLE) += conmakehash hostprogs-$(CONFIG_IKCONFIG) += bin2c +hostprogs-$(CONFIG_PPC_ISERIES) += fix_lparmap always := $(hostprogs-y) diff -ruN linus/scripts/fix_lparmap.c linus-lparmap/scripts/fix_lparmap.c --- linus/scripts/fix_lparmap.c 1970-01-01 10:00:00.000000000 +1000 +++ linus-lparmap/scripts/fix_lparmap.c 2005-08-15 17:28:09.000000000 +1000 @@ -0,0 +1,74 @@ +/* + * This program is just here to work around the fact that the + * compiler cannot emit (u32)(&xLparMap - KERNElBASE) as a constant. + * + * Copyright (C) 2005 Stephen Rothwell IBM Corporation + * + * 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 +#include +#include +#include + +#define ElfHeaderSize (64 * 1024) +#define KERNELBASE (0xc000000000000000ULL) + +int main(int argc, char *argv[]) +{ + FILE *vmlinux = NULL; + unsigned long long xLparMap_addr; + unsigned int hvReleaseData_addr; + unsigned int xDesc; + unsigned int short_lpar_map; + + if ((argc < 2) || (sscanf(argv[1], "%Lx", &xLparMap_addr) != 1)) { + fprintf(stderr, "Address of xLparMap is missing.\n"); + return 1; + } + + if (argc < 3) { + fprintf(stderr, "Name of vmlinux file is missing.\n"); + return 1; + } + + vmlinux = fopen(argv[2], "r+"); + if (vmlinux == NULL) { + fprintf(stderr, "Cannot open vmlinux file \"%s\".\n", argv[2]); + return 1; + } + + /* fseek to the hvReleaseData pointer */ + fseek(vmlinux, ElfHeaderSize + 0x24, SEEK_SET); + if (fread(&hvReleaseData_addr, 4, 1, vmlinux) != 1) { + fprintf(stderr, "Could not read hvReleaseData pointer\n"); + return 1; + } + hvReleaseData_addr = ntohl(hvReleaseData_addr); + + /* fseek to the hvReleaseData */ + fseek(vmlinux, ElfHeaderSize + hvReleaseData_addr, SEEK_SET); + if (fread(&xDesc, sizeof(xDesc), 1, vmlinux) != 1) { + fprintf(stderr, "Could not read hvReleaseData.xDesc\n"); + return 1; + } + /* Check hvReleaseData sanity */ + if (xDesc != 0xc8a5d9c4) { + fprintf(stderr, "hvReleaseData is invalid\n"); + return 1; + } + + short_lpar_map = htonl((unsigned int)(xLparMap_addr - KERNELBASE)); + fseek(vmlinux, ElfHeaderSize + hvReleaseData_addr + 16, SEEK_SET); + if (fwrite(&short_lpar_map, 4, 1, vmlinux) != 1) { + fprintf(stderr, "Could not write xLparMap address\n"); + return 1; + } + + fclose(vmlinux); + + return 0; +} From hch at lst.de Mon Aug 15 18:00:35 2005 From: hch at lst.de (Christoph Hellwig) Date: Mon, 15 Aug 2005 10:00:35 +0200 Subject: [PATCH] iSeries build with newer assemblers and compilers In-Reply-To: <20050815175115.4b789a1c.sfr@canb.auug.org.au> References: <20050815175115.4b789a1c.sfr@canb.auug.org.au> Message-ID: <20050815080035.GA13490@lst.de> On Mon, Aug 15, 2005 at 05:51:15PM +1000, Stephen Rothwell wrote: > Hi all, > > This patch makes iSeries build with the newer assemblers and compilers. > We had a hack to allow us to move xLparMap out of head.S but that > required a horrible bit of inline assembler in LparData.c. When I > upgraded Debian unstable in order to use their biarch compiler, even that > hack broke. This patch works around the whole compiler/assembler mess by > patching the address we care about into the vmlinux after it is built. Why don't you move it back to head.S? Sure it was ugly, but the previous and new workaround are even worse. From david at gibson.dropbear.id.au Mon Aug 15 18:07:50 2005 From: david at gibson.dropbear.id.au (David Gibson) Date: Mon, 15 Aug 2005 18:07:50 +1000 Subject: [PATCH] iSeries build with newer assemblers and compilers In-Reply-To: <20050815080035.GA13490@lst.de> References: <20050815175115.4b789a1c.sfr@canb.auug.org.au> <20050815080035.GA13490@lst.de> Message-ID: <20050815080750.GC6224@localhost.localdomain> On Mon, Aug 15, 2005 at 10:00:35AM +0200, Christoph Hellwig wrote: > On Mon, Aug 15, 2005 at 05:51:15PM +1000, Stephen Rothwell wrote: > > Hi all, > > > > This patch makes iSeries build with the newer assemblers and compilers. > > We had a hack to allow us to move xLparMap out of head.S but that > > required a horrible bit of inline assembler in LparData.c. When I > > upgraded Debian unstable in order to use their biarch compiler, even that > > hack broke. This patch works around the whole compiler/assembler mess by > > patching the address we care about into the vmlinux after it is built. > > Why don't you move it back to head.S? Sure it was ugly, but the > previous and new workaround are even worse. I disagree. Apart from the nasty fixed address, having it in head.S means the VSID constants have to be hard coded. In C, those can be computed using macros, which means it's much less likely to break if we change the VSID scrambling functions again. Having the LparMap sitting there also blocks a bunch of rearrangements and cleanups I want to do in head.S (currently in paulus' queue). -- David Gibson | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/people/dgibson From segher at kernel.crashing.org Tue Aug 16 04:25:18 2005 From: segher at kernel.crashing.org (Segher Boessenkool) Date: Mon, 15 Aug 2005 20:25:18 +0200 Subject: RFC: proposed arch/powerpc directory structure In-Reply-To: <20050812041443.GC3187@smtp.west.cox.net> References: <20050811195927.GX3187@smtp.west.cox.net> <17148.7234.193140.997481@cargo.ozlabs.ibm.com> <20050812041443.GC3187@smtp.west.cox.net> Message-ID: > Ok. How about 9xx/ instead of classic64 ? That would be tons better, as there doesn't exist anything called "classic64"... Segher From kumar.gala at freescale.com Tue Aug 16 04:25:24 2005 From: kumar.gala at freescale.com (Kumar Gala) Date: Mon, 15 Aug 2005 13:25:24 -0500 Subject: CONFIG_FRAME_POINTER on ppc/ppc64? Message-ID: <3E78617E-D2D4-44DB-A3F1-9C5D8814E37F@freescale.com> Is there any reason we dont allow building with frame pointers on ppc/ ppc64? - kumar From tim.bird at am.sony.com Tue Aug 16 04:24:55 2005 From: tim.bird at am.sony.com (Tim Bird) Date: Mon, 15 Aug 2005 11:24:55 -0700 Subject: question about symbols and function locations Message-ID: <4300DDF7.4060403@am.sony.com> Hi all, Sorry if this is a remedial question. I'm porting some kernel tracing software to ppc64, and I'm confused about the information I'm getting for function locations. In System.map I see most functions have two addresses - a weak (text) address and a data address: c00000000000d0a0 W .calibrate_delay c0000000005c8e80 D calibrate_delay The latter looks like some kind of jumb table?, with the real function text located in the lower addresses? Can someone shed some light on what's going on here? Thanks in advance, -- Tim Some background: I generate my trace data by using gcc's -finstrument-functions option when I compile the kernel and by logging data from my own __cyg_profile_func_enter/exit functions. However, I get somewhat jumbled information. The __cyg_profile* functions receive the function address and call site for the called function. On ppc64 the function address matches the data address for the call, but the call site is in the range of the weak symbols. I can work around this in my program which resolves the symbols for the trace log, but I wanted to understand what was going on. ============================= Tim Bird Architecture Group Chair, CE Linux Forum Senior Staff Engineer, Sony Electronics ============================= From nacc at us.ibm.com Tue Aug 16 04:15:41 2005 From: nacc at us.ibm.com (Nishanth Aravamudan) Date: Mon, 15 Aug 2005 11:15:41 -0700 Subject: [-mm PATCH 13/32] ppc64: fix-up schedule_timeout() usage In-Reply-To: <20050815180514.GC2854@us.ibm.com> References: <20050815180514.GC2854@us.ibm.com> Message-ID: <20050815181541.GP2854@us.ibm.com> Description: Use schedule_timeout_interruptible() instead of set_current_state()/schedule_timeout() to reduce kernel size. Signed-off-by: Nishanth Aravamudan --- arch/ppc64/kernel/rtasd.c | 3 +-- arch/ppc64/kernel/rtc.c | 6 ++---- arch/ppc64/kernel/scanlog.c | 3 +-- 3 files changed, 4 insertions(+), 8 deletions(-) diff -urpN 2.6.13-rc5-mm1/arch/ppc64/kernel/rtasd.c 2.6.13-rc5-mm1-dev/arch/ppc64/kernel/rtasd.c --- 2.6.13-rc5-mm1/arch/ppc64/kernel/rtasd.c 2005-08-07 09:57:45.000000000 -0700 +++ 2.6.13-rc5-mm1-dev/arch/ppc64/kernel/rtasd.c 2005-08-08 13:54:49.000000000 -0700 @@ -412,8 +412,7 @@ static void do_event_scan_all_cpus(long /* Drop hotplug lock, and sleep for the specified delay */ unlock_cpu_hotplug(); - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(delay); + schedule_timeout_interruptible(delay); lock_cpu_hotplug(); cpu = next_cpu(cpu, cpu_online_map); diff -urpN 2.6.13-rc5-mm1/arch/ppc64/kernel/rtc.c 2.6.13-rc5-mm1-dev/arch/ppc64/kernel/rtc.c --- 2.6.13-rc5-mm1/arch/ppc64/kernel/rtc.c 2005-08-07 09:57:45.000000000 -0700 +++ 2.6.13-rc5-mm1-dev/arch/ppc64/kernel/rtc.c 2005-08-08 13:55:03.000000000 -0700 @@ -351,8 +351,7 @@ void rtas_get_rtc_time(struct rtc_time * return; /* delay not allowed */ } wait_time = rtas_extended_busy_delay_time(error); - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(wait_time); + schedule_timeout_interruptible(wait_time); error = RTAS_CLOCK_BUSY; } } while (error == RTAS_CLOCK_BUSY && (__get_tb() < max_wait_tb)); @@ -386,8 +385,7 @@ int rtas_set_rtc_time(struct rtc_time *t if (in_interrupt()) return 1; /* probably decrementer */ wait_time = rtas_extended_busy_delay_time(error); - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(wait_time); + schedule_timeout_interruptible(wait_time); error = RTAS_CLOCK_BUSY; } } while (error == RTAS_CLOCK_BUSY && (__get_tb() < max_wait_tb)); diff -urpN 2.6.13-rc5-mm1/arch/ppc64/kernel/scanlog.c 2.6.13-rc5-mm1-dev/arch/ppc64/kernel/scanlog.c --- 2.6.13-rc5-mm1/arch/ppc64/kernel/scanlog.c 2005-08-07 09:57:22.000000000 -0700 +++ 2.6.13-rc5-mm1-dev/arch/ppc64/kernel/scanlog.c 2005-08-08 13:55:13.000000000 -0700 @@ -123,8 +123,7 @@ static ssize_t scanlog_read(struct file } } /* Apparently no data yet. Wait and try again. */ - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(wait_time); + schedule_timeout_interruptible(wait_time); } /*NOTREACHED*/ } From security at eBay.com Tue Aug 16 05:18:32 2005 From: security at eBay.com (eBay) Date: Mon, 15 Aug 2005 22:18:32 +0300 Subject: eBay Inc: Please Confirm Your Banking Details [Mon, 15 Aug 2005 22:38:14 -0100] Message-ID: <20050815191901.8725D2D68A@ns.coninsalt.ro> An HTML attachment was scrubbed... URL: http://ozlabs.org/pipermail/linuxppc64-dev/attachments/20050815/c34c9572/attachment.htm From geoffrey.levand at am.sony.com Tue Aug 16 06:59:13 2005 From: geoffrey.levand at am.sony.com (Geoff Levand) Date: Mon, 15 Aug 2005 13:59:13 -0700 Subject: [PATCH 1/2] ppc64: zimage build fix In-Reply-To: <200508111215.09284.michael@ellerman.id.au> References: <200508111215.09284.michael@ellerman.id.au> Message-ID: <43010221.7050008@am.sony.com> Here is an updated version. I changed the build target names as was recommended: zImage = real mode elf, suitable for pSeries. zImage.vmode = virtual mode elf, suitable for powermac, and others. I also fix a problem with 'make clean' leaving stale zImage files. -Geoff ppc64-zimage-build-fix.patch: This patch makes it possible to build ppc64 kernel image files for all targeted machines when several CONFIG_PPC_XXX machine type options are enabled simultaneously. To accomplish this it introduces two new build targets, zImage.vmode and zImage.initrd.vmode, which will make the proper image needed by machines with virtual mode Open Firmware. Signed-off-by: Geoff Levand Index: linux-2.6.13-rc6/arch/ppc64/Makefile =================================================================== --- linux-2.6.13-rc6.orig/arch/ppc64/Makefile 2005-08-15 12:10:57.000000000 -0700 +++ linux-2.6.13-rc6/arch/ppc64/Makefile 2005-08-15 12:41:08.000000000 -0700 @@ -87,11 +87,12 @@ boot := arch/ppc64/boot -boottarget-$(CONFIG_PPC_PSERIES) := zImage zImage.initrd -boottarget-$(CONFIG_PPC_MAPLE) := zImage zImage.initrd -boottarget-$(CONFIG_PPC_ISERIES) := vmlinux.sminitrd vmlinux.initrd vmlinux.sm -boottarget-$(CONFIG_PPC_BPA) := zImage zImage.initrd -$(boottarget-y): vmlinux +boottargets-$(CONFIG_PPC_PSERIES) += zImage zImage.initrd +boottargets-$(CONFIG_PPC_PMAC) += zImage.vmode zImage.initrd.vmode +boottargets-$(CONFIG_PPC_MAPLE) += zImage zImage.initrd +boottargets-$(CONFIG_PPC_ISERIES) += vmlinux.sminitrd vmlinux.initrd vmlinux.sm +boottargets-$(CONFIG_PPC_BPA) += zImage zImage.initrd +$(boottargets-y): vmlinux $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ bootimage-$(CONFIG_PPC_PSERIES) := $(boot)/zImage @@ -122,10 +123,12 @@ $(call filechk,gen-asm-offsets) define archhelp - echo '* zImage - Compressed kernel image (arch/$(ARCH)/boot/zImage)' - echo ' zImage.initrd- Compressed kernel image with initrd attached,' - echo ' sourced from arch/$(ARCH)/boot/ramdisk.image.gz' - echo ' (arch/$(ARCH)/boot/zImage.initrd)' + echo ' zImage.vmode - Compressed kernel image (arch/$(ARCH)/boot/zImage.vmode)' + echo ' zImage.initrd.vmode - Compressed kernel image with initrd attached,' + echo ' sourced from arch/$(ARCH)/boot/ramdisk.image.gz' + echo ' (arch/$(ARCH)/boot/zImage.initrd.vmode)' + echo ' zImage - zImage for pSeries machines' + echo ' zImage.initrd - zImage with initrd for pSeries machines' endef CLEAN_FILES += include/asm-ppc64/offsets.h Index: linux-2.6.13-rc6/arch/ppc64/boot/Makefile =================================================================== --- linux-2.6.13-rc6.orig/arch/ppc64/boot/Makefile 2005-08-15 12:10:57.000000000 -0700 +++ linux-2.6.13-rc6/arch/ppc64/boot/Makefile 2005-08-15 12:47:49.000000000 -0700 @@ -37,6 +37,9 @@ quiet_cmd_bootas = BOOTAS $@ cmd_bootas = $(CROSS32CC) -Wp,-MD,$(depfile) $(BOOTAFLAGS) -c -o $@ $< +quiet_cmd_bootld = BOOTLD $@ + cmd_bootld = $(CROSS32LD) $(BOOTLFLAGS) -o $@ $(2) + $(patsubst %.c,%.o, $(filter %.c, $(src-boot))): %.o: %.c $(call if_changed_dep,bootcc) $(patsubst %.S,%.o, $(filter %.S, $(src-boot))): %.o: %.S @@ -53,7 +56,7 @@ gz-sec = $(foreach section, $(1), $(patsubst %,$(obj)/kernel-%.gz, $(section))) hostprogs-y := addnote addRamDisk -targets += zImage zImage.initrd imagesize.c \ +targets += zImage.vmode zImage.initrd.vmode zImage zImage.initrd imagesize.c \ $(patsubst $(obj)/%,%, $(call obj-sec, $(required) $(initrd))) \ $(patsubst $(obj)/%,%, $(call src-sec, $(required) $(initrd))) \ $(patsubst $(obj)/%,%, $(call gz-sec, $(required) $(initrd))) \ @@ -75,8 +78,8 @@ --add-section=.kernel:$(strip $(patsubst $(obj)/kernel-%.o,%, $(1)))=$(patsubst %.o,%.gz, $(1)) \ --set-section-flags=.kernel:$(strip $(patsubst $(obj)/kernel-%.o,%, $(1)))=$(OBJCOPYFLAGS) -quiet_cmd_addnote = ADDNOTE $@ - cmd_addnote = $(CROSS32LD) $(BOOTLFLAGS) -o $@ $(obj-boot) && $(obj)/addnote $@ +quiet_cmd_addnote = ADDNOTE $@ + cmd_addnote = $(obj)/addnote $@ $(call gz-sec, $(required)): $(obj)/kernel-%.gz: % FORCE $(call if_changed,gzip) @@ -91,12 +94,20 @@ $(call if_changed_dep,bootcc) $(call addsection, $@) -$(obj)/zImage: obj-boot += $(call obj-sec, $(required)) -$(obj)/zImage: $(call obj-sec, $(required)) $(obj-boot) $(obj)/addnote FORCE +$(obj)/zImage.vmode: obj-boot += $(call obj-sec, $(required)) +$(obj)/zImage.vmode: $(call obj-sec, $(required)) $(obj-boot) FORCE + $(call cmd,bootld,$(obj-boot)) + +$(obj)/zImage.initrd.vmode: obj-boot += $(call obj-sec, $(required) $(initrd)) +$(obj)/zImage.initrd.vmode: $(call obj-sec, $(required) $(initrd)) $(obj-boot) FORCE + $(call cmd,bootld,$(obj-boot)) + +$(obj)/zImage: $(obj)/zImage.vmode $(obj)/addnote FORCE + @cp -f $< $@ $(call if_changed,addnote) -$(obj)/zImage.initrd: obj-boot += $(call obj-sec, $(required) $(initrd)) -$(obj)/zImage.initrd: $(call obj-sec, $(required) $(initrd)) $(obj-boot) $(obj)/addnote FORCE +$(obj)/zImage.initrd: $(obj)/zImage.initrd.vmode $(obj)/addnote FORCE + @cp -f $< $@ $(call if_changed,addnote) $(obj)/imagesize.c: vmlinux.strip From paulus at samba.org Tue Aug 16 09:08:12 2005 From: paulus at samba.org (Paul Mackerras) Date: Tue, 16 Aug 2005 09:08:12 +1000 Subject: CONFIG_FRAME_POINTER on ppc/ppc64? In-Reply-To: <3E78617E-D2D4-44DB-A3F1-9C5D8814E37F@freescale.com> References: <3E78617E-D2D4-44DB-A3F1-9C5D8814E37F@freescale.com> Message-ID: <17153.8284.3721.188488@cargo.ozlabs.ibm.com> > Is there any reason we dont allow building with frame pointers on ppc/ > ppc64? Because -fomit-frame-pointer and -fno-omit-frame-pointer have no effect on ppc or ppc64, I assume. :) Paul. From kumar.gala at freescale.com Tue Aug 16 13:41:03 2005 From: kumar.gala at freescale.com (Kumar Gala) Date: Mon, 15 Aug 2005 22:41:03 -0500 Subject: CONFIG_FRAME_POINTER on ppc/ppc64? In-Reply-To: <17153.8284.3721.188488@cargo.ozlabs.ibm.com> References: <17153.8284.3721.188488@cargo.ozlabs.ibm.com> Message-ID: <473FD762-FB04-4B63-93E9-11931492AC60@freescale.com> On Aug 15, 2005, at 6:08 PM, Paul Mackerras wrote: >> Is there any reason we dont allow building with frame pointers on >> ppc/ >> > > >> ppc64? >> > > Because -fomit-frame-pointer and -fno-omit-frame-pointer have no > effect on ppc or ppc64, I assume. :) I'm assuming that's a guess. The reason I ask that is my memory serves correctly r31 is used as the frame pointer if compiled that way. Maybe some GCC expert can chime in. I'll copy David Edelsohn and see if I get a response :) - kumar From dje at watson.ibm.com Tue Aug 16 14:03:16 2005 From: dje at watson.ibm.com (David Edelsohn) Date: Tue, 16 Aug 2005 00:03:16 -0400 Subject: CONFIG_FRAME_POINTER on ppc/ppc64? In-Reply-To: Message from Kumar Gala of "Mon, 15 Aug 2005 22:41:03 CDT." <473FD762-FB04-4B63-93E9-11931492AC60@freescale.com> References: <17153.8284.3721.188488@cargo.ozlabs.ibm.com> <473FD762-FB04-4B63-93E9-11931492AC60@freescale.com> Message-ID: <200508160403.j7G43Hd29692@makai.watson.ibm.com> >>>>> Kumar Gala writes: >> Because -fomit-frame-pointer and -fno-omit-frame-pointer have no >> effect on ppc or ppc64, I assume. :) Kumar> I'm assuming that's a guess. The reason I ask that is my memory Kumar> serves correctly r31 is used as the frame pointer if compiled that Kumar> way. Maybe some GCC expert can chime in. I'll copy David Edelsohn Kumar> and see if I get a response :) I am missing some context here. On both 32-bit PowerPC Linux (PowerPC SVR4) and 64-bit PowerPC Linux, GPR r31 is used as the frame pointer. PowerPC does not have a dedicated frame pointer and the PowerPC ABI does not require an independent frame pointer in a function at all times, so it can be omitted by default. If the frame pointer is not referenced for any unique needs, uses of the frame pointer are adjusted to reference the stack pointer. GCC only retains the PowerPC frame pointer when dynamic stack allocation (alloca) is used within a function. -fomit-frame-pointer has no effect on PowerPC because it is enabled by default. David From paulus at samba.org Tue Aug 16 15:23:50 2005 From: paulus at samba.org (Paul Mackerras) Date: Tue, 16 Aug 2005 15:23:50 +1000 Subject: CONFIG_FRAME_POINTER on ppc/ppc64? In-Reply-To: <200508160403.j7G43Hd29692@makai.watson.ibm.com> References: <17153.8284.3721.188488@cargo.ozlabs.ibm.com> <473FD762-FB04-4B63-93E9-11931492AC60@freescale.com> <200508160403.j7G43Hd29692@makai.watson.ibm.com> Message-ID: <17153.30822.529374.24144@cargo.ozlabs.ibm.com> David Edelsohn writes: > Kumar> I'm assuming that's a guess. The reason I ask that is my memory > Kumar> serves correctly r31 is used as the frame pointer if compiled that > Kumar> way. Maybe some GCC expert can chime in. I'll copy David Edelsohn > Kumar> and see if I get a response :) > > I am missing some context here. On both 32-bit PowerPC Linux > (PowerPC SVR4) and 64-bit PowerPC Linux, GPR r31 is used as the frame > pointer. PowerPC does not have a dedicated frame pointer and the PowerPC > ABI does not require an independent frame pointer in a function at all > times, so it can be omitted by default. If the frame pointer is not > referenced for any unique needs, uses of the frame pointer are adjusted to > reference the stack pointer. GCC only retains the PowerPC frame pointer > when dynamic stack allocation (alloca) is used within a function. > -fomit-frame-pointer has no effect on PowerPC because it is enabled by > default. OK, my memory was at fault then. The reason for having the kernel config option is that it is impossible to get reliable stack traces on x86 without frame pointers. On PPC, because the stack frames are always linked together, even if you don't use a frame pointer, the frame pointer doesn't help in getting stack traces. Thus there is no point in having the kernel config option. Paul. From sfr at canb.auug.org.au Tue Aug 16 15:50:02 2005 From: sfr at canb.auug.org.au (Stephen Rothwell) Date: Tue, 16 Aug 2005 15:50:02 +1000 Subject: [PATCH] iSeries build with newer assemblers and compilers In-Reply-To: <20050815080750.GC6224@localhost.localdomain> References: <20050815175115.4b789a1c.sfr@canb.auug.org.au> <20050815080035.GA13490@lst.de> <20050815080750.GC6224@localhost.localdomain> Message-ID: <20050816155002.3640d079.sfr@canb.auug.org.au> Hi all, Paulus suggested that we put xLparMap in its own .c file so that we can generate a .s file to be included into head.S. This doesn't get around the problem of having it at a fixed address, but it makes it more palatable. It would be good if this could be included in 2.6.13 as it solves our build problems with various versions of binutils and gcc. In particular, it allows us to build an iSeries kernel on Debian unstable using their biarch compiler. There are a couple of small cleanups/rearrangements in head.S that will allow David's later cleanups to apply more easily. This has been built and booted on iSeries and built for pSeries and g5. Signed-off-by: Stephen Rothwell --- arch/ppc64/kernel/LparData.c | 79 ------------------------------------ arch/ppc64/kernel/Makefile | 5 ++ arch/ppc64/kernel/head.S | 39 ++++++++++------- arch/ppc64/kernel/lparmap.c | 31 ++++++++++++++ include/asm-ppc64/iSeries/LparMap.h | 9 +++- 5 files changed, 68 insertions(+), 95 deletions(-) -- Cheers, Stephen Rothwell sfr at canb.auug.org.au diff -ruN linus/arch/ppc64/kernel/LparData.c linus-lparmap.1/arch/ppc64/kernel/LparData.c --- linus/arch/ppc64/kernel/LparData.c 2005-07-28 11:23:11.000000000 +1000 +++ linus-lparmap.1/arch/ppc64/kernel/LparData.c 2005-08-16 15:10:56.000000000 +1000 @@ -32,32 +32,12 @@ /* The HvReleaseData is the root of the information shared between * the hypervisor and Linux. */ - -/* - * WARNING - magic here - * - * Ok, this is a horrid hack below, but marginally better than the - * alternatives. What we really want is just to initialize - * hvReleaseData in C as in the #if 0 section here. However, gcc - * refuses to believe that (u32)&x is a constant expression, so will - * not allow the xMsNucDataOffset field to be properly initialized. - * So, we declare hvReleaseData in inline asm instead. We use inline - * asm, rather than a .S file, because the assembler won't generate - * the necessary relocation for the LparMap either, unless that symbol - * is declared in the same source file. Finally, we put the asm in a - * dummy, attribute-used function, instead of at file scope, because - * file scope asms don't allow contraints. We want to use the "i" - * constraints to put sizeof() and offsetof() expressions in there, - * because including asm/offsets.h in C code then stringifying causes - * all manner of warnings. - */ -#if 0 struct HvReleaseData hvReleaseData = { .xDesc = 0xc8a5d9c4, /* "HvRD" ebcdic */ .xSize = sizeof(struct HvReleaseData), .xVpdAreasPtrOffset = offsetof(struct naca_struct, xItVpdAreas), .xSlicNacaAddr = &naca, /* 64-bit Naca address */ - .xMsNucDataOffset = (u32)((unsigned long)&xLparMap - KERNELBASE), + .xMsNucDataOffset = LPARMAP_PHYS, .xFlags = HVREL_TAGSINACTIVE /* tags inactive */ /* 64 bit */ /* shared processors */ @@ -70,63 +50,6 @@ 0xa7, 0x40, 0xf2, 0x4b, 0xf4, 0x4b, 0xf6, 0xf4 }, }; -#endif - - -extern struct HvReleaseData hvReleaseData; - -static void __attribute_used__ hvReleaseData_wrapper(void) -{ - /* This doesn't appear to need any alignment (even 4 byte) */ - asm volatile ( - " lparMapPhys = xLparMap - %3\n" - " .data\n" - " .globl hvReleaseData\n" - "hvReleaseData:\n" - " .long 0xc8a5d9c4\n" /* xDesc */ - /* "HvRD" in ebcdic */ - " .short %0\n" /* xSize */ - " .short %1\n" /* xVpdAreasPtrOffset */ - " .llong naca\n" /* xSlicNacaAddr */ - " .long lparMapPhys\n" /* xMsNucDataOffset */ - " .long 0\n" /* xRsvd1 */ - " .short %2\n" /* xFlags */ - " .short 4\n" /* xVrmIndex - v5r2m0 */ - " .short 3\n" /* xMinSupportedPlicVrmIndex - v5r1m0 */ - " .short 3\n" /* xMinCompatablePlicVrmIndex - v5r1m0 */ - " .long 0xd38995a4\n" /* xVrmName */ - " .long 0xa740f24b\n" /* "Linux 2.4.64" ebcdic */ - " .long 0xf44bf6f4\n" - " . = hvReleaseData + %0\n" - " .previous\n" - : : "i"(sizeof(hvReleaseData)), - "i"(offsetof(struct naca_struct, xItVpdAreas)), - "i"(HVREL_TAGSINACTIVE /* tags inactive, 64 bit, */ - /* shared processors, HMT allowed */ - | 6), /* TEMP: This allows non-GA drivers */ - "i"(KERNELBASE) - ); -} - -struct LparMap __attribute__((aligned (16))) xLparMap = { - .xNumberEsids = HvEsidsToMap, - .xNumberRanges = HvRangesToMap, - .xSegmentTableOffs = STAB0_PAGE, - - .xEsids = { - { .xKernelEsid = GET_ESID(KERNELBASE), - .xKernelVsid = KERNEL_VSID(KERNELBASE), }, - { .xKernelEsid = GET_ESID(VMALLOCBASE), - .xKernelVsid = KERNEL_VSID(VMALLOCBASE), }, - }, - - .xRanges = { - { .xPages = HvPagesToMap, - .xOffset = 0, - .xVPN = KERNEL_VSID(KERNELBASE) << (SID_SHIFT - PAGE_SHIFT), - }, - }, -}; extern void system_reset_iSeries(void); extern void machine_check_iSeries(void); diff -ruN linus/arch/ppc64/kernel/Makefile linus-lparmap.1/arch/ppc64/kernel/Makefile --- linus/arch/ppc64/kernel/Makefile 2005-06-27 16:08:00.000000000 +1000 +++ linus-lparmap.1/arch/ppc64/kernel/Makefile 2005-08-16 15:19:34.000000000 +1000 @@ -73,3 +73,8 @@ obj-$(CONFIG_KPROBES) += kprobes.o CFLAGS_ioctl32.o += -Ifs/ + +ifeq ($(CONFIG_PPC_ISERIES),y) +arch/ppc64/kernel/head.o: arch/ppc64/kernel/lparmap.s +AFLAGS_head.o += -Iarch/ppc64/kernel +endif diff -ruN linus/arch/ppc64/kernel/head.S linus-lparmap.1/arch/ppc64/kernel/head.S --- linus/arch/ppc64/kernel/head.S 2005-08-05 09:12:57.000000000 +1000 +++ linus-lparmap.1/arch/ppc64/kernel/head.S 2005-08-16 15:29:10.000000000 +1000 @@ -38,6 +38,7 @@ #include #include #include +#include #ifdef CONFIG_PPC_ISERIES #define DO_SOFT_DISABLE @@ -93,6 +94,18 @@ /* Catch branch to 0 in real mode */ trap + + /* Secondary processors spin on this value until it goes to 1. */ + .globl __secondary_hold_spinloop +__secondary_hold_spinloop: + .llong 0x0 + + /* Secondary processors write this value with their cpu # */ + /* after they enter the spin loop immediately below. */ + .globl __secondary_hold_acknowledge +__secondary_hold_acknowledge: + .llong 0x0 + #ifdef CONFIG_PPC_ISERIES /* * At offset 0x20, there is a pointer to iSeries LPAR data. @@ -119,20 +132,9 @@ embedded_sysmap_end: .llong 0 -#else /* CONFIG_PPC_ISERIES */ - - /* Secondary processors spin on this value until it goes to 1. */ - .globl __secondary_hold_spinloop -__secondary_hold_spinloop: - .llong 0x0 - - /* Secondary processors write this value with their cpu # */ - /* after they enter the spin loop immediately below. */ - .globl __secondary_hold_acknowledge -__secondary_hold_acknowledge: - .llong 0x0 +#endif /* CONFIG_PPC_ISERIES */ - . = 0x60 +#ifdef CONFIG_PPC_MULTIPLATFORM /* * The following code is used on pSeries to hold secondary processors * in a spin loop after they have been freed from OpenFirmware, but @@ -167,9 +169,14 @@ b .pSeries_secondary_smp_init #else BUG_OPCODE -#endif -#endif -#endif +#endif /* CONFIG_SMP */ +#endif /* CONFIG_HMT */ +#endif /* CONFIG_PPC_MULTIPLATFORM */ + +#ifdef CONFIG_PPC_ISERIES + . = LPARMAP_PHYS +#include "lparmap.s" +#endif /* CONFIG_PPC_ISERIES */ /* This value is used to mark exception frames on the stack. */ .section ".toc","aw" diff -ruN linus/arch/ppc64/kernel/lparmap.c linus-lparmap.1/arch/ppc64/kernel/lparmap.c --- linus/arch/ppc64/kernel/lparmap.c 1970-01-01 10:00:00.000000000 +1000 +++ linus-lparmap.1/arch/ppc64/kernel/lparmap.c 2005-08-16 14:59:36.000000000 +1000 @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2005 Stephen Rothwell IBM Corp. + * + * 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 +#include +#include + +const struct LparMap __attribute__((__section__(".text"))) xLparMap = { + .xNumberEsids = HvEsidsToMap, + .xNumberRanges = HvRangesToMap, + .xSegmentTableOffs = STAB0_PAGE, + + .xEsids = { + { .xKernelEsid = GET_ESID(KERNELBASE), + .xKernelVsid = KERNEL_VSID(KERNELBASE), }, + { .xKernelEsid = GET_ESID(VMALLOCBASE), + .xKernelVsid = KERNEL_VSID(VMALLOCBASE), }, + }, + + .xRanges = { + { .xPages = HvPagesToMap, + .xOffset = 0, + .xVPN = KERNEL_VSID(KERNELBASE) << (SID_SHIFT - PAGE_SHIFT), + }, + }, +}; diff -ruN linus/include/asm-ppc64/iSeries/LparMap.h linus-lparmap.1/include/asm-ppc64/iSeries/LparMap.h --- linus/include/asm-ppc64/iSeries/LparMap.h 2005-07-28 11:23:11.000000000 +1000 +++ linus-lparmap.1/include/asm-ppc64/iSeries/LparMap.h 2005-08-16 15:17:16.000000000 +1000 @@ -19,6 +19,8 @@ #ifndef _LPARMAP_H #define _LPARMAP_H +#ifndef __ASSEMBLY__ + #include /* @@ -71,6 +73,11 @@ } xRanges[HvRangesToMap]; }; -extern struct LparMap xLparMap; +extern const struct LparMap xLparMap; + +#endif /* __ASSEMBLY__ */ + +/* the fixed address where the LparMap exists */ +#define LPARMAP_PHYS 0x80 #endif /* _LPARMAP_H */ From david at gibson.dropbear.id.au Tue Aug 16 17:14:25 2005 From: david at gibson.dropbear.id.au (David Gibson) Date: Tue, 16 Aug 2005 17:14:25 +1000 Subject: [PATCH 6/10] ppc64: Create a fake flat device tree on iSeries In-Reply-To: <132f13582efb822fe7fd9b278c667c49@bga.com> References: <6b57499e431cefc69e65db59b4210b38@bga.com> <20050810083228.GE22335@localhost.localdomain> <20050811031425.GA5975@localhost.localdomain> <132f13582efb822fe7fd9b278c667c49@bga.com> Message-ID: <20050816071425.GD4983@localhost.localdomain> On Sat, Aug 13, 2005 at 03:44:50PM -0500, Milton Miller wrote: > > On Aug 10, 2005, at 10:14 PM, David Gibson wrote: > > > > >On Wed, Aug 10, 2005 at 08:59:51AM -0500, Milton Miller wrote: > >> > >>On Aug 10, 2005, at 3:32 AM, David Gibson wrote: > >> > >>>On Wed, Aug 10, 2005 at 02:16:15AM -0500, Milton Miller wrote: > >>>>Putting the > >>>>device data at klimit would allow the checks for overflow to be > >>>>deferred until after its created (look for 2 nuls in string table > >>>>-- the size is propnum(""), and placing data at after the reserve > >>>>map and string table and either compare to total size or set > >>>>totalsize according to what is used). > >>> > >> > > >>My other generator does this very thing. The strings are allocated > >>statically. > >> > >>While discussing embedded with panto on #mklinux, another approach > >>is to say "here's the max", put the strings at the end, and allocate > >>new strings down moving the start as we add strings. > > > >An memmove() on every string insertion? That's kinda horrible.. > > NO! I agree, that would be. > > I was saying 1 memmove on "oops we didn't alocate enough, allocate > a bigger area" and and optional one after everything else to say > "well, we allocated a 16k chunk and used 8 bytes, lets save a 3 pages". > > By inserting strings by growing down towards the blob we just have > to update the start of the string table. > > I just realized why that doesn't work --- the offset would keep > changing. That's what I was getting at. Sorry, I should have been clearer. paulus did point out that we could do it this way if we allowed negative string offsets. But that gets potentially ghastly if we ever needed to copy the device blob around as a unit. > ... this still doesn't keep us from makeing an optimistic guess > how much string table and device tree we need an doing a memmove when > we were wrong. Hrm, I guess. I don't really seeing the advantage over just growing upwards, though. However, from talking with Michael the other day, I think he came up with a reasonable way of statically allocating the strings table which is probably a better option. > >>Makes sense for > >>fw where there is a fixed allocation. End of blob processing can > >>then memmove the string table and cut total size down. > >> > >>Even without the knowing the max size realloc could move strings down > >>if a space check is added before extending the dt blob. > > milton > -- David Gibson | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/people/dgibson From sfr at canb.auug.org.au Tue Aug 16 17:38:38 2005 From: sfr at canb.auug.org.au (Stephen Rothwell) Date: Tue, 16 Aug 2005 17:38:38 +1000 Subject: [PATCH] iSeries build with newer assemblers and compilers In-Reply-To: <20050816155002.3640d079.sfr@canb.auug.org.au> References: <20050815175115.4b789a1c.sfr@canb.auug.org.au> <20050815080035.GA13490@lst.de> <20050815080750.GC6224@localhost.localdomain> <20050816155002.3640d079.sfr@canb.auug.org.au> Message-ID: <20050816173838.6bbed45f.sfr@canb.auug.org.au> [Paulus wants a smaller patch ...] Hi all, Paulus suggested that we put xLparMap in its own .c file so that we can generate a .s file to be included into head.S. This doesn't get around the problem of having it at a fixed address, but it makes it more palatable. It would be good if this could be included in 2.6.13 as it solves our build problems with various versions of binutils and gcc. In particular, it allows us to build an iSeries kernel on Debian unstable using their biarch compiler. This has been built and booted on iSeries and built for pSeries and g5. Signed-off-by: Stephen Rothwell --- arch/ppc64/kernel/LparData.c | 79 ------------------------------------ arch/ppc64/kernel/Makefile | 5 ++ arch/ppc64/kernel/head.S | 6 ++ arch/ppc64/kernel/lparmap.c | 31 ++++++++++++++ include/asm-ppc64/iSeries/LparMap.h | 9 +++- 5 files changed, 51 insertions(+), 79 deletions(-) -- Cheers, Stephen Rothwell sfr at canb.auug.org.au http://www.canb.auug.org.au/~sfr/ diff -ruN linus/arch/ppc64/kernel/LparData.c linus-lparmap.2/arch/ppc64/kernel/LparData.c --- linus/arch/ppc64/kernel/LparData.c 2005-07-28 11:23:11.000000000 +1000 +++ linus-lparmap.2/arch/ppc64/kernel/LparData.c 2005-08-16 17:13:16.000000000 +1000 @@ -32,32 +32,12 @@ /* The HvReleaseData is the root of the information shared between * the hypervisor and Linux. */ - -/* - * WARNING - magic here - * - * Ok, this is a horrid hack below, but marginally better than the - * alternatives. What we really want is just to initialize - * hvReleaseData in C as in the #if 0 section here. However, gcc - * refuses to believe that (u32)&x is a constant expression, so will - * not allow the xMsNucDataOffset field to be properly initialized. - * So, we declare hvReleaseData in inline asm instead. We use inline - * asm, rather than a .S file, because the assembler won't generate - * the necessary relocation for the LparMap either, unless that symbol - * is declared in the same source file. Finally, we put the asm in a - * dummy, attribute-used function, instead of at file scope, because - * file scope asms don't allow contraints. We want to use the "i" - * constraints to put sizeof() and offsetof() expressions in there, - * because including asm/offsets.h in C code then stringifying causes - * all manner of warnings. - */ -#if 0 struct HvReleaseData hvReleaseData = { .xDesc = 0xc8a5d9c4, /* "HvRD" ebcdic */ .xSize = sizeof(struct HvReleaseData), .xVpdAreasPtrOffset = offsetof(struct naca_struct, xItVpdAreas), .xSlicNacaAddr = &naca, /* 64-bit Naca address */ - .xMsNucDataOffset = (u32)((unsigned long)&xLparMap - KERNELBASE), + .xMsNucDataOffset = LPARMAP_PHYS, .xFlags = HVREL_TAGSINACTIVE /* tags inactive */ /* 64 bit */ /* shared processors */ @@ -70,63 +50,6 @@ 0xa7, 0x40, 0xf2, 0x4b, 0xf4, 0x4b, 0xf6, 0xf4 }, }; -#endif - - -extern struct HvReleaseData hvReleaseData; - -static void __attribute_used__ hvReleaseData_wrapper(void) -{ - /* This doesn't appear to need any alignment (even 4 byte) */ - asm volatile ( - " lparMapPhys = xLparMap - %3\n" - " .data\n" - " .globl hvReleaseData\n" - "hvReleaseData:\n" - " .long 0xc8a5d9c4\n" /* xDesc */ - /* "HvRD" in ebcdic */ - " .short %0\n" /* xSize */ - " .short %1\n" /* xVpdAreasPtrOffset */ - " .llong naca\n" /* xSlicNacaAddr */ - " .long lparMapPhys\n" /* xMsNucDataOffset */ - " .long 0\n" /* xRsvd1 */ - " .short %2\n" /* xFlags */ - " .short 4\n" /* xVrmIndex - v5r2m0 */ - " .short 3\n" /* xMinSupportedPlicVrmIndex - v5r1m0 */ - " .short 3\n" /* xMinCompatablePlicVrmIndex - v5r1m0 */ - " .long 0xd38995a4\n" /* xVrmName */ - " .long 0xa740f24b\n" /* "Linux 2.4.64" ebcdic */ - " .long 0xf44bf6f4\n" - " . = hvReleaseData + %0\n" - " .previous\n" - : : "i"(sizeof(hvReleaseData)), - "i"(offsetof(struct naca_struct, xItVpdAreas)), - "i"(HVREL_TAGSINACTIVE /* tags inactive, 64 bit, */ - /* shared processors, HMT allowed */ - | 6), /* TEMP: This allows non-GA drivers */ - "i"(KERNELBASE) - ); -} - -struct LparMap __attribute__((aligned (16))) xLparMap = { - .xNumberEsids = HvEsidsToMap, - .xNumberRanges = HvRangesToMap, - .xSegmentTableOffs = STAB0_PAGE, - - .xEsids = { - { .xKernelEsid = GET_ESID(KERNELBASE), - .xKernelVsid = KERNEL_VSID(KERNELBASE), }, - { .xKernelEsid = GET_ESID(VMALLOCBASE), - .xKernelVsid = KERNEL_VSID(VMALLOCBASE), }, - }, - - .xRanges = { - { .xPages = HvPagesToMap, - .xOffset = 0, - .xVPN = KERNEL_VSID(KERNELBASE) << (SID_SHIFT - PAGE_SHIFT), - }, - }, -}; extern void system_reset_iSeries(void); extern void machine_check_iSeries(void); diff -ruN linus/arch/ppc64/kernel/Makefile linus-lparmap.2/arch/ppc64/kernel/Makefile --- linus/arch/ppc64/kernel/Makefile 2005-06-27 16:08:00.000000000 +1000 +++ linus-lparmap.2/arch/ppc64/kernel/Makefile 2005-08-16 17:13:16.000000000 +1000 @@ -73,3 +73,8 @@ obj-$(CONFIG_KPROBES) += kprobes.o CFLAGS_ioctl32.o += -Ifs/ + +ifeq ($(CONFIG_PPC_ISERIES),y) +arch/ppc64/kernel/head.o: arch/ppc64/kernel/lparmap.s +AFLAGS_head.o += -Iarch/ppc64/kernel +endif diff -ruN linus/arch/ppc64/kernel/head.S linus-lparmap.2/arch/ppc64/kernel/head.S --- linus/arch/ppc64/kernel/head.S 2005-08-05 09:12:57.000000000 +1000 +++ linus-lparmap.2/arch/ppc64/kernel/head.S 2005-08-16 17:24:59.000000000 +1000 @@ -38,6 +38,7 @@ #include #include #include +#include #ifdef CONFIG_PPC_ISERIES #define DO_SOFT_DISABLE @@ -679,6 +680,11 @@ .globl fwnmi_data_area fwnmi_data_area: +#ifdef CONFIG_PPC_ISERIES + . = LPARMAP_PHYS +#include "lparmap.s" +#endif /* CONFIG_PPC_ISERIES */ + /* * Vectors for the FWNMI option. Share common code. */ diff -ruN linus/arch/ppc64/kernel/lparmap.c linus-lparmap.2/arch/ppc64/kernel/lparmap.c --- linus/arch/ppc64/kernel/lparmap.c 1970-01-01 10:00:00.000000000 +1000 +++ linus-lparmap.2/arch/ppc64/kernel/lparmap.c 2005-08-16 17:13:16.000000000 +1000 @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2005 Stephen Rothwell IBM Corp. + * + * 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 +#include +#include + +const struct LparMap __attribute__((__section__(".text"))) xLparMap = { + .xNumberEsids = HvEsidsToMap, + .xNumberRanges = HvRangesToMap, + .xSegmentTableOffs = STAB0_PAGE, + + .xEsids = { + { .xKernelEsid = GET_ESID(KERNELBASE), + .xKernelVsid = KERNEL_VSID(KERNELBASE), }, + { .xKernelEsid = GET_ESID(VMALLOCBASE), + .xKernelVsid = KERNEL_VSID(VMALLOCBASE), }, + }, + + .xRanges = { + { .xPages = HvPagesToMap, + .xOffset = 0, + .xVPN = KERNEL_VSID(KERNELBASE) << (SID_SHIFT - PAGE_SHIFT), + }, + }, +}; diff -ruN linus/include/asm-ppc64/iSeries/LparMap.h linus-lparmap.2/include/asm-ppc64/iSeries/LparMap.h --- linus/include/asm-ppc64/iSeries/LparMap.h 2005-07-28 11:23:11.000000000 +1000 +++ linus-lparmap.2/include/asm-ppc64/iSeries/LparMap.h 2005-08-16 17:14:33.000000000 +1000 @@ -19,6 +19,8 @@ #ifndef _LPARMAP_H #define _LPARMAP_H +#ifndef __ASSEMBLY__ + #include /* @@ -71,6 +73,11 @@ } xRanges[HvRangesToMap]; }; -extern struct LparMap xLparMap; +extern const struct LparMap xLparMap; + +#endif /* __ASSEMBLY__ */ + +/* the fixed address where the LparMap exists */ +#define LPARMAP_PHYS 0x7000 #endif /* _LPARMAP_H */ From michael at ellerman.id.au Tue Aug 16 17:44:03 2005 From: michael at ellerman.id.au (Michael Ellerman) Date: Tue, 16 Aug 2005 17:44:03 +1000 Subject: [RFC] Flat Device Tree Spec Message-ID: <200508161744.06365.michael@ellerman.id.au> Hi guys, The latest device tree spec (1) says that the header, reserve map, flat tree and strings should be contiguous in memory (2), although it does mention that the order is not important. From looking at the unflattening code though, the requirements are actually not so strict. AFAICT there's no reason the pieces (3) need to be contiguous at all, as long as the header is first and the offsets to the pieces fit in a u32. Is there any reason why the spec needs to be so strict? If we added a size_reserve_map and size_dt_struct, to match size_dt_strings, we'd have enough information to not care whether the pieces were contiguous or not. The reason I'm interested is that I've changed the iSeries code to put all property strings in a special linker section. We then simply copy that section into the flat device tree. If the pieces didn't have to be contiguous then we could just point the off_dt_strings at the actual linker section, and not need to do a copy at all. cheers 1: http://ozlabs.org/pipermail/linuxppc64-dev/2005-June/004221.html 2: See ASCII art at end of section # 1. 3: ie. the reserve map, flat tree and strings blob. -- Michael Ellerman IBM OzLabs email: michael:ellerman.id.au inmsg: mpe:jabber.org wwweb: http://michael.ellerman.id.au phone: +61 2 6212 1183 (tie line 70 21183) We do not inherit the earth from our ancestors, we borrow it from our children. - S.M.A.R.T Person -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: not available Url : http://ozlabs.org/pipermail/linuxppc64-dev/attachments/20050816/05284b32/attachment.pgp From benh at kernel.crashing.org Tue Aug 16 17:49:00 2005 From: benh at kernel.crashing.org (Benjamin Herrenschmidt) Date: Tue, 16 Aug 2005 17:49:00 +1000 Subject: [RFC] Flat Device Tree Spec In-Reply-To: <200508161744.06365.michael@ellerman.id.au> References: <200508161744.06365.michael@ellerman.id.au> Message-ID: <1124178543.6804.56.camel@gaston> On Tue, 2005-08-16 at 17:44 +1000, Michael Ellerman wrote: > Hi guys, > > The latest device tree spec (1) says that the header, reserve map, flat tree > and strings should be contiguous in memory (2), although it does mention that > the order is not important. > > From looking at the unflattening code though, the requirements are actually > not so strict. AFAICT there's no reason the pieces (3) need to be contiguous > at all, as long as the header is first and the offsets to the pieces fit in a > u32. > > Is there any reason why the spec needs to be so strict? I wanted to be able to move the entire blob around... though I don't have a strict real life case of needing to do that, it made sense to keep the whole thing nicely self contained. > If we added a size_reserve_map and size_dt_struct, to match size_dt_strings, > we'd have enough information to not care whether the pieces were contiguous > or not. > > The reason I'm interested is that I've changed the iSeries code to put all > property strings in a special linker section. We then simply copy that > section into the flat device tree. If the pieces didn't have to be contiguous > then we could just point the off_dt_strings at the actual linker section, and > not need to do a copy at all. Well, the offset is 32 bits, so how do you manage if you strings block is below your blob or too far away ? Ben. From michael at ellerman.id.au Tue Aug 16 18:13:56 2005 From: michael at ellerman.id.au (Michael Ellerman) Date: Tue, 16 Aug 2005 18:13:56 +1000 Subject: [PATCH] Dump flat device tree before scanning Message-ID: <200508161813.56331.michael@ellerman.id.au> Hi, This patch is just for people debugging flat device tree code. It dumps the content of the device tree before scanning it, giving you a chance to look over things before it all blows up. I also have a python script that will turn this into something dtc can read, if anyone wants it. You need some sort of early debugging enabled to see anything BTW. See setup.c cheers # Bazaar-NG changeset v0.0.5 # # committer: Michael Ellerman # date: Tue 2005-08-16 17:54:46.513325930 +1000 # message: # Add dumping of flat DT in prom.c # --- orig/arch/ppc64/kernel/prom.c +++ mod/arch/ppc64/kernel/prom.c @@ -1218,6 +1218,31 @@ #endif } +#ifdef DEBUG +static void dump_flat_dt(char *p) +{ + struct boot_param_header *hdr = (struct boot_param_header*)p; + unsigned char buf[64]; + int i, j; + + DBG("Dumping flat dt ...\n"); + + for (i = j = 0; i < hdr->totalsize; i += 2) { + if (i % 4 == 0) + j += snprintf(buf + j, sizeof(buf) - j, " "); + + if (i % 16 == 0) { + DBG("%s\n", buf); + j = 0; + } + + j += snprintf(buf + j, sizeof(buf) - j, + "%.2x%.2x ", p[i], p[i + 1]); + } + DBG("%s\n", buf); +} +#endif + void __init early_init_devtree(void *params) { DBG(" -> early_init_devtree()\n"); @@ -1227,6 +1252,10 @@ /* By default, hash size is not set */ ppc64_pft_size = 0; + +#ifdef DEBUG + dump_flat_dt((char *)params); +#endif /* Retreive various informations from the /chosen node of the * device-tree, including the platform type, initrd location and -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: not available Url : http://ozlabs.org/pipermail/linuxppc64-dev/attachments/20050816/8fc61768/attachment.pgp From segher at kernel.crashing.org Tue Aug 16 19:44:33 2005 From: segher at kernel.crashing.org (Segher Boessenkool) Date: Tue, 16 Aug 2005 11:44:33 +0200 Subject: CONFIG_FRAME_POINTER on ppc/ppc64? In-Reply-To: <473FD762-FB04-4B63-93E9-11931492AC60@freescale.com> References: <17153.8284.3721.188488@cargo.ozlabs.ibm.com> <473FD762-FB04-4B63-93E9-11931492AC60@freescale.com> Message-ID: <62a65a7989df38a7e4b1400150dcb2e5@kernel.crashing.org> >> Because -fomit-frame-pointer and -fno-omit-frame-pointer have no >> effect on ppc or ppc64, I assume. :) > > I'm assuming that's a guess. The reason I ask that is my memory > serves correctly r31 is used as the frame pointer if compiled that > way. Maybe some GCC expert can chime in. I'll copy David Edelsohn > and see if I get a response :) Yes, GPR31 is used as frame pointer. All optimization levels other than -O0 enable -fomit-frame-pointer. But -fno-omit-frame-pointer certainly works. Segher From david at gibson.dropbear.id.au Tue Aug 16 21:01:00 2005 From: david at gibson.dropbear.id.au (David Gibson) Date: Tue, 16 Aug 2005 21:01:00 +1000 Subject: [PATCH] iSeries build with newer assemblers and compilers In-Reply-To: <20050816173838.6bbed45f.sfr@canb.auug.org.au> References: <20050815175115.4b789a1c.sfr@canb.auug.org.au> <20050815080035.GA13490@lst.de> <20050815080750.GC6224@localhost.localdomain> <20050816155002.3640d079.sfr@canb.auug.org.au> <20050816173838.6bbed45f.sfr@canb.auug.org.au> Message-ID: <20050816110100.GA6238@localhost.localdomain> On Tue, Aug 16, 2005 at 05:38:38PM +1000, Stephen Rothwell wrote: > [Paulus wants a smaller patch ...] > > Hi all, > > Paulus suggested that we put xLparMap in its own .c file so that we can > generate a .s file to be included into head.S. This doesn't get around > the problem of having it at a fixed address, but it makes it more > palatable. > > It would be good if this could be included in 2.6.13 as it solves our > build problems with various versions of binutils and gcc. In > particular, it allows us to build an iSeries kernel on Debian unstable > using their biarch compiler. > > This has been built and booted on iSeries and built for pSeries and g5. > > Signed-off-by: Stephen Rothwell Acked-by: David Gibson -- David Gibson | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/people/dgibson From arnd at arndb.de Tue Aug 16 21:30:01 2005 From: arnd at arndb.de (Arnd Bergmann) Date: Tue, 16 Aug 2005 13:30:01 +0200 Subject: [-mm PATCH 13/32] ppc64: fix-up schedule_timeout() usage In-Reply-To: <20050815181541.GP2854@us.ibm.com> References: <20050815180514.GC2854@us.ibm.com> <20050815181541.GP2854@us.ibm.com> Message-ID: <200508161330.02682.arnd@arndb.de> On Maandag 15 August 2005 20:15, Nishanth Aravamudan wrote: > Description: Use schedule_timeout_interruptible() instead of > set_current_state()/schedule_timeout() to reduce kernel size. Shouldn't these use msleep_interruptible() instead? Arnd <>< From linas at austin.ibm.com Wed Aug 17 01:44:22 2005 From: linas at austin.ibm.com (Linas Vepstas) Date: Tue, 16 Aug 2005 10:44:22 -0500 Subject: question about symbols and function locations In-Reply-To: <4300DDF7.4060403@am.sony.com> References: <4300DDF7.4060403@am.sony.com> Message-ID: <20050816154422.GM5553@austin.ibm.com> On Mon, Aug 15, 2005 at 11:24:55AM -0700, Tim Bird was heard to remark: > On ppc64 the function address matches > the data address for the call, but the call site is in the > range of the weak symbols. Caution: My answer below may be only partly correct ... I beleive the ppc ABI makes use of a struct with three pointers in it to identify a called subroutine. One pointer is to the executable code, one pointer is to the "TOC" (table of contents) which holds pointers to all of the global variables that the subroutine references. The TOC is 65K in size, so that immediate (16-bit offset) instructions can be used to do the addressing. The third pointer is the "environment" pointer; its not used by the C language, but is used by other languages, e.g. Pascal, I beleive. The "address of a subroutine" is actually the address of this 3-pointer struct. The subroutine call glue loads the TOC pointer into r2 before calling the subroutine. You'll notice that global vars are always addrssed relative to r2. (The TOC also contains addresses of called subroutines, as well as global vars. Also, note that some static "global" vars are inlined into the TOC, rather than being pointed at. ). I think the call glue is named .gl-something or other. --linas From hollis at penguinppc.org Wed Aug 17 02:00:04 2005 From: hollis at penguinppc.org (Hollis Blanchard) Date: Tue, 16 Aug 2005 11:00:04 -0500 Subject: question about symbols and function locations In-Reply-To: <20050816154422.GM5553@austin.ibm.com> References: <4300DDF7.4060403@am.sony.com> <20050816154422.GM5553@austin.ibm.com> Message-ID: On Aug 16, 2005, at 10:44 AM, Linas Vepstas wrote: > On Mon, Aug 15, 2005 at 11:24:55AM -0700, Tim Bird was heard to remark: >> On ppc64 the function address matches >> the data address for the call, but the call site is in the >> range of the weak symbols. > > I beleive the ppc ABI makes use of a struct with three pointers > in it to identify a called subroutine. See http://penguinppc.org/dev/#library for the ppc64 ABI and related docs. -Hollis From galak at freescale.com Wed Aug 17 07:20:39 2005 From: galak at freescale.com (Kumar Gala) Date: Tue, 16 Aug 2005 16:20:39 -0500 (CDT) Subject: [PATCH] ppc64: removed include of Message-ID: segment.h in ppc64 is a dummy file so no need to include it in arch code Signed-off-by: Kumar Gala --- commit d88b795bc4c4b59c29a98e2a551c2ad4d65901c5 tree 1f9262f12a79869f4265bc057317f25bcbfa4960 parent 3068d1994b48bbf977af7a939e30eeeef6702e96 author Kumar K. Gala Tue, 16 Aug 2005 15:58:43 -0500 committer Kumar K. Gala Tue, 16 Aug 2005 15:58:43 -0500 arch/ppc64/kernel/time.c | 1 - 1 files changed, 0 insertions(+), 1 deletions(-) diff --git a/arch/ppc64/kernel/time.c b/arch/ppc64/kernel/time.c --- a/arch/ppc64/kernel/time.c +++ b/arch/ppc64/kernel/time.c @@ -51,7 +51,6 @@ #include #include -#include #include #include #include From akpm at osdl.org Wed Aug 17 10:30:42 2005 From: akpm at osdl.org (Andrew Morton) Date: Tue, 16 Aug 2005 17:30:42 -0700 Subject: [-mm UPDATE PATCH 13/32] ppc64: replace schedule_timeout() with msleep_interruptible() In-Reply-To: <20050816225608.GC2806@us.ibm.com> References: <20050815180514.GC2854@us.ibm.com> <20050815181541.GP2854@us.ibm.com> <200508161330.02682.arnd@arndb.de> <20050816225608.GC2806@us.ibm.com> Message-ID: <20050816173042.2cf6edb3.akpm@osdl.org> Nishanth Aravamudan wrote: > > On 16.08.2005 [13:30:01 +0200], Arnd Bergmann wrote: > > On Maandag 15 August 2005 20:15, Nishanth Aravamudan wrote: > > > Description: Use schedule_timeout_interruptible() instead of > > > set_current_state()/schedule_timeout() to reduce kernel size. > > > > Shouldn't these use msleep_interruptible() instead? > > Yes, you are right. I had forgotten to get on that after my -KJ patches > which affected these files. Does the following patch look ok/better? > This should avoid the load average increase issues the ppc64 maintainers > (rightly) had with my older -KJ patches. > > Thanks, > Nish > > > > Description: Use msleep_interruptible() instead of schedule_timeout() in > ppc64-specific code to cleanup/simplify the sleeping logic. Really I'd prefer not to include this patch at this time. It's a separate thing from the simple mechanistic convert-to-schedule_timeout_interruptible patches. This patch requires more thought and review. So hm. I'll just drop 13/32 and handle this patch as a separate thing. From nacc at us.ibm.com Wed Aug 17 08:56:08 2005 From: nacc at us.ibm.com (Nishanth Aravamudan) Date: Tue, 16 Aug 2005 15:56:08 -0700 Subject: [-mm UPDATE PATCH 13/32] ppc64: replace schedule_timeout() with msleep_interruptible() In-Reply-To: <200508161330.02682.arnd@arndb.de> References: <20050815180514.GC2854@us.ibm.com> <20050815181541.GP2854@us.ibm.com> <200508161330.02682.arnd@arndb.de> Message-ID: <20050816225608.GC2806@us.ibm.com> On 16.08.2005 [13:30:01 +0200], Arnd Bergmann wrote: > On Maandag 15 August 2005 20:15, Nishanth Aravamudan wrote: > > Description: Use schedule_timeout_interruptible() instead of > > set_current_state()/schedule_timeout() to reduce kernel size. > > Shouldn't these use msleep_interruptible() instead? Yes, you are right. I had forgotten to get on that after my -KJ patches which affected these files. Does the following patch look ok/better? This should avoid the load average increase issues the ppc64 maintainers (rightly) had with my older -KJ patches. Thanks, Nish Description: Use msleep_interruptible() instead of schedule_timeout() in ppc64-specific code to cleanup/simplify the sleeping logic. Change the units of the parameter of do_event_scan_all_cpus() to milliseconds from jiffies. The return value of rtas_extended_busy_delay_time() was incorrectly being used as a jiffies value (it is actually milliseconds), which is fixed by using the value as a parameter to msleep_interruptible(). Also, use rtas_extended_busy_delay_time() in another case where similar logic is duplicated. Signed-off-by: Nishanth Aravamudan --- arch/ppc64/kernel/rtasd.c | 10 +++++----- arch/ppc64/kernel/rtc.c | 7 +++---- arch/ppc64/kernel/scanlog.c | 17 ++++------------- 3 files changed, 12 insertions(+), 22 deletions(-) diff -urpN 2.6.13-rc5-mm1/arch/ppc64/kernel/rtasd.c 2.6.13-rc5-mm1-dev/arch/ppc64/kernel/rtasd.c --- 2.6.13-rc5-mm1/arch/ppc64/kernel/rtasd.c 2005-08-07 09:57:45.000000000 -0700 +++ 2.6.13-rc5-mm1-dev/arch/ppc64/kernel/rtasd.c 2005-08-16 15:50:10.000000000 -0700 @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -412,8 +413,7 @@ static void do_event_scan_all_cpus(long /* Drop hotplug lock, and sleep for the specified delay */ unlock_cpu_hotplug(); - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(delay); + msleep_interruptible(delay); lock_cpu_hotplug(); cpu = next_cpu(cpu, cpu_online_map); @@ -442,7 +442,7 @@ static int rtasd(void *unused) printk(KERN_INFO "RTAS daemon started\n"); - DEBUG("will sleep for %d jiffies\n", (HZ*60/rtas_event_scan_rate) / 2); + DEBUG("will sleep for %d milliseconds\n", (30000/rtas_event_scan_rate)); /* See if we have any error stored in NVRAM */ memset(logdata, 0, rtas_error_log_max); @@ -459,7 +459,7 @@ static int rtasd(void *unused) } /* First pass. */ - do_event_scan_all_cpus(HZ); + do_event_scan_all_cpus(1000); if (surveillance_timeout != -1) { DEBUG("enabling surveillance\n"); @@ -471,7 +471,7 @@ static int rtasd(void *unused) * machines have problems if we call event-scan too * quickly. */ for (;;) - do_event_scan_all_cpus((HZ*60/rtas_event_scan_rate) / 2); + do_event_scan_all_cpus(30000/rtas_event_scan_rate); error: /* Should delete proc entries */ diff -urpN 2.6.13-rc5-mm1/arch/ppc64/kernel/rtc.c 2.6.13-rc5-mm1-dev/arch/ppc64/kernel/rtc.c --- 2.6.13-rc5-mm1/arch/ppc64/kernel/rtc.c 2005-08-07 09:57:45.000000000 -0700 +++ 2.6.13-rc5-mm1-dev/arch/ppc64/kernel/rtc.c 2005-08-16 15:49:53.000000000 -0700 @@ -35,6 +35,7 @@ #include #include #include +#include #include #include @@ -351,8 +352,7 @@ void rtas_get_rtc_time(struct rtc_time * return; /* delay not allowed */ } wait_time = rtas_extended_busy_delay_time(error); - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(wait_time); + msleep_interruptible(wait_time); error = RTAS_CLOCK_BUSY; } } while (error == RTAS_CLOCK_BUSY && (__get_tb() < max_wait_tb)); @@ -386,8 +386,7 @@ int rtas_set_rtc_time(struct rtc_time *t if (in_interrupt()) return 1; /* probably decrementer */ wait_time = rtas_extended_busy_delay_time(error); - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(wait_time); + msleep_interruptible(wait_time); error = RTAS_CLOCK_BUSY; } } while (error == RTAS_CLOCK_BUSY && (__get_tb() < max_wait_tb)); diff -urpN 2.6.13-rc5-mm1/arch/ppc64/kernel/scanlog.c 2.6.13-rc5-mm1-dev/arch/ppc64/kernel/scanlog.c --- 2.6.13-rc5-mm1/arch/ppc64/kernel/scanlog.c 2005-08-07 09:57:22.000000000 -0700 +++ 2.6.13-rc5-mm1-dev/arch/ppc64/kernel/scanlog.c 2005-08-16 15:49:39.000000000 -0700 @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -77,7 +78,7 @@ static ssize_t scanlog_read(struct file return -EFAULT; for (;;) { - wait_time = HZ/2; /* default wait if no data */ + wait_time = 500; /* default wait if no data */ spin_lock(&rtas_data_buf_lock); memcpy(rtas_data_buf, data, RTAS_DATA_BUF_SIZE); status = rtas_call(ibm_scan_log_dump, 2, 1, NULL, @@ -107,24 +108,14 @@ static ssize_t scanlog_read(struct file break; default: if (status > 9900 && status <= 9905) { - /* No data. RTAS is hinting at a delay required - * between 1-100000 milliseconds - */ - int ms = 1; - for (; status > 9900; status--) - ms = ms * 10; - /* Use microseconds for reasonable accuracy */ - ms *= 1000; - wait_time = ms / (1000000/HZ); /* round down is fine */ - /* Fall through to sleep */ + wait_time = rtas_extended_busy_delay_time(status); } else { printk(KERN_ERR "scanlog: unknown error from rtas: %d\n", status); return -EIO; } } /* Apparently no data yet. Wait and try again. */ - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(wait_time); + msleep_interruptible(wait_time); } /*NOTREACHED*/ } From kumar.gala at freescale.com Wed Aug 17 15:39:27 2005 From: kumar.gala at freescale.com (Kumar Gala) Date: Wed, 17 Aug 2005 00:39:27 -0500 Subject: [PATCH] 1/2 Start header file merger (Was: Re: Beginning Merger Patch) In-Reply-To: <20050805174705.731ffa05.sfr@canb.auug.org.au> References: <20050805174705.731ffa05.sfr@canb.auug.org.au> Message-ID: <8DC89F16-0704-484A-9216-D94F3EE90CA4@freescale.com> On Aug 5, 2005, at 2:47 AM, Stephen Rothwell wrote: > On Tue, 2 Aug 2005 19:10:56 -0400 Dan Malek > wrote: > >> >> On Aug 2, 2005, at 6:59 PM, Jon Loeliger wrote: >> >> >>> ..... A stub is left >>> in asm-ppc and asm-ppc64 pointing to the unified files. >>> >> >> Why bother? You may as well change all of the source >> files, too, or else that will never get done :-) >> > > You actually don't need to modify (m)any source files. > > Here is an alternative approach. These patches depend on Olaf's > boot code cleanup for ppc64 (or similar). Do the following: > > cd linux/include > mkdir asm-powerpc > cd asm-ppc > for i in * > do > [ -e ../asm-ppc64/$i ] || mv $i ../asm-powerpc/$i > done > cd ../asm-ppc64 > for i in * > do > [ -e ../asm-ppc/$i ] || mv $i ../asm-powerpc/$i > done > for i in * > do > [ -f ../asm-ppc64/$i ] && cmp -s $i ../asm-ppc64/$i && > mv $i ../asm-powerpc/$i && rm ../asm-ppc64/$i > done > > Then apply the patch below and the patch in the following email. > > I have built this kernel for ppc (defconfig), ppc64 (iSeries, pSeries > and > pmac). I think conceptual this is ok, just now how we should go about it. There is a fair amount of cruft in asm-ppc and I think we should be more selective and iterative about what we move into arch-powerpc. For example, there is a fair amount of headers that are specific to platform support code. It's probably the case that alot of that should move into the proper platform directory. If we just copy those files into arch-powerpc I think we will never get around to moving them to the proper location in the future. We've been doing some analysis (well, Jon and Becky have) and I think there is some low hanging fruit that we can start with: 1. files that are identical are almost identical 2. files that are not overly ppc specific and seem straight forward to merge 3. low hanging ppc specific files 4. identify files that we clearly want to wait on (for example anything platform related) This will hopefully leave us with the painful list of things that we can start identifying and discussion how we want to go about solving things (like what should "current" by defined as :) Now your makefile hackery seems perfectly reasonable if we want to go that way instead of explicitly including files like Jon's original patch does. I dont have any strong feelings one way or the other. The makefile hackery seems less intrusive since we dont have to duplicate files in both places. I'd like to see if we can come to some consensus on this since it directly impacts future patches that we are working on to merge more files and move them into include/asm- powerpc/ - kumar From nacc at us.ibm.com Wed Aug 17 15:51:36 2005 From: nacc at us.ibm.com (Nishanth Aravamudan) Date: Tue, 16 Aug 2005 22:51:36 -0700 Subject: [-mm UPDATE PATCH 13/32] ppc64: replace schedule_timeout() with msleep_interruptible() In-Reply-To: <20050816173042.2cf6edb3.akpm@osdl.org> References: <20050815180514.GC2854@us.ibm.com> <20050815181541.GP2854@us.ibm.com> <200508161330.02682.arnd@arndb.de> <20050816225608.GC2806@us.ibm.com> <20050816173042.2cf6edb3.akpm@osdl.org> Message-ID: <20050817055134.GA4143@us.ibm.com> On 16.08.2005 [17:30:42 -0700], Andrew Morton wrote: > Nishanth Aravamudan wrote: > > > > On 16.08.2005 [13:30:01 +0200], Arnd Bergmann wrote: > > > On Maandag 15 August 2005 20:15, Nishanth Aravamudan wrote: > > > > Description: Use schedule_timeout_interruptible() instead of > > > > set_current_state()/schedule_timeout() to reduce kernel size. > > > > > > Shouldn't these use msleep_interruptible() instead? > > > > Yes, you are right. I had forgotten to get on that after my -KJ patches > > which affected these files. Does the following patch look ok/better? > > This should avoid the load average increase issues the ppc64 maintainers > > (rightly) had with my older -KJ patches. > > > > Thanks, > > Nish > > > > > > > > Description: Use msleep_interruptible() instead of schedule_timeout() in > > ppc64-specific code to cleanup/simplify the sleeping logic. > > Really I'd prefer not to include this patch at this time. It's a separate > thing from the simple mechanistic convert-to-schedule_timeout_interruptible > patches. This patch requires more thought and review. > > So hm. I'll just drop 13/32 and handle this patch as a separate thing. Eep, sorry about that Andrew. I just replied-to-all. I didn't intend for you to pull this in with the other 31 patches, as you are correct, it should be reviewed. I think it should go in via the ppc64 maintainers. Thanks, Nish From sfr at canb.auug.org.au Wed Aug 17 16:35:31 2005 From: sfr at canb.auug.org.au (Stephen Rothwell) Date: Wed, 17 Aug 2005 16:35:31 +1000 Subject: [PATCH 0/4] More vio changes In-Reply-To: <20050712175026.1652e11a.sfr@canb.auug.org.au> References: <20050712173655.387d5110.sfr@canb.auug.org.au> <20050712175026.1652e11a.sfr@canb.auug.org.au> Message-ID: <20050817163531.6368f9ec.sfr@canb.auug.org.au> Hi all, The following four patches do more splitting/cleanup of the vio code. These are relative to Paulus's queued patches for post 2.6.13. -- Cheers, Stephen Rothwell sfr at canb.auug.org.au http://www.canb.auug.org.au/~sfr/ From sfr at canb.auug.org.au Wed Aug 17 16:37:35 2005 From: sfr at canb.auug.org.au (Stephen Rothwell) Date: Wed, 17 Aug 2005 16:37:35 +1000 Subject: [PATCH 1/4] Formatting changes to vio.c In-Reply-To: <20050817163531.6368f9ec.sfr@canb.auug.org.au> References: <20050712173655.387d5110.sfr@canb.auug.org.au> <20050712175026.1652e11a.sfr@canb.auug.org.au> <20050817163531.6368f9ec.sfr@canb.auug.org.au> Message-ID: <20050817163735.1a8d701e.sfr@canb.auug.org.au> Formatting changes to vio.c to bring it closer to the kernel coding standard. Signed-off-by: Stephen Rothwell --- arch/ppc64/kernel/vio.c | 39 +++++++++++++++++---------------------- 1 files changed, 17 insertions(+), 22 deletions(-) -- Cheers, Stephen Rothwell sfr at canb.auug.org.au http://www.canb.auug.org.au/~sfr/ 55138fa2f876b2f92ea1412a097600c94c2b055a diff --git a/arch/ppc64/kernel/vio.c b/arch/ppc64/kernel/vio.c --- a/arch/ppc64/kernel/vio.c +++ b/arch/ppc64/kernel/vio.c @@ -37,9 +37,11 @@ static int (*is_match)(const struct vio_ static void (*unregister_device_callback)(struct vio_dev *dev); static void (*release_device_callback)(struct device *dev); -/* convert from struct device to struct vio_dev and pass to driver. +/* + * Convert from struct device to struct vio_dev and pass to driver. * dev->driver has already been set by generic code because vio_bus_match - * succeeded. */ + * succeeded. + */ static int vio_bus_probe(struct device *dev) { struct vio_dev *viodev = to_vio_dev(dev); @@ -51,9 +53,8 @@ static int vio_bus_probe(struct device * return error; id = vio_match_device(viodrv->id_table, viodev); - if (id) { + if (id) error = viodrv->probe(viodev, id); - } return error; } @@ -64,9 +65,8 @@ static int vio_bus_remove(struct device struct vio_dev *viodev = to_vio_dev(dev); struct vio_driver *viodrv = to_vio_driver(dev->driver); - if (viodrv->remove) { + if (viodrv->remove) return viodrv->remove(viodev); - } /* driver can't remove */ return 1; @@ -102,16 +102,17 @@ void vio_unregister_driver(struct vio_dr EXPORT_SYMBOL(vio_unregister_driver); /** - * vio_match_device: - Tell if a VIO device has a matching VIO device id structure. - * @ids: array of VIO device id structures to search in - * @dev: the VIO device structure to match against + * vio_match_device: - Tell if a VIO device has a matching + * VIO device id structure. + * @ids: array of VIO device id structures to search in + * @dev: the VIO device structure to match against * * Used by a driver to check whether a VIO device present in the * system is in its list of supported devices. Returns the matching * vio_device_id structure or NULL if there is no match. */ -static const struct vio_device_id * vio_match_device(const struct vio_device_id *ids, - const struct vio_dev *dev) +static const struct vio_device_id *vio_match_device( + const struct vio_device_id *ids, const struct vio_dev *dev) { while (ids->type) { if (is_match(ids, dev)) @@ -141,7 +142,8 @@ int __init vio_bus_init(int (*match_func return err; } - /* the fake parent of all vio devices, just to give us + /* + * The fake parent of all vio devices, just to give us * a nice directory */ err = device_register(&vio_bus_device.dev); @@ -162,7 +164,8 @@ static void __devinit vio_dev_release(st kfree(to_vio_dev(dev)); } -static ssize_t viodev_show_name(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t viodev_show_name(struct device *dev, + struct device_attribute *attr, char *buf) { return sprintf(buf, "%s\n", to_vio_dev(dev)->name); } @@ -262,16 +265,8 @@ static int vio_bus_match(struct device * const struct vio_dev *vio_dev = to_vio_dev(dev); struct vio_driver *vio_drv = to_vio_driver(drv); const struct vio_device_id *ids = vio_drv->id_table; - const struct vio_device_id *found_id; - if (!ids) - return 0; - - found_id = vio_match_device(ids, vio_dev); - if (found_id) - return 1; - - return 0; + return (ids != NULL) && (vio_match_device(ids, vio_dev) != NULL); } struct bus_type vio_bus_type = { From sfr at canb.auug.org.au Wed Aug 17 16:41:44 2005 From: sfr at canb.auug.org.au (Stephen Rothwell) Date: Wed, 17 Aug 2005 16:41:44 +1000 Subject: [PATCH 3/4] Create vio_bus_ops In-Reply-To: <20050817163531.6368f9ec.sfr@canb.auug.org.au> References: <20050712173655.387d5110.sfr@canb.auug.org.au> <20050712175026.1652e11a.sfr@canb.auug.org.au> <20050817163531.6368f9ec.sfr@canb.auug.org.au> Message-ID: <20050817164144.19f9e2de.sfr@canb.auug.org.au> Create vio_bus_ops so that we just pass a structure to vio_bus_init instead of three separate function pointers. Rearrange vio.h to avoid forward references. vio.h only needs struct device_node from prom.h so remove the include and just declare it. Signed-off-by: Stephen Rothwell --- arch/ppc64/kernel/iSeries_vio.c | 6 ++ arch/ppc64/kernel/pSeries_vio.c | 10 +++- arch/ppc64/kernel/vio.c | 24 +++------ drivers/scsi/ibmvscsi/rpa_vscsi.c | 1 include/asm-ppc64/vio.h | 97 ++++++++++++++++++------------------- 5 files changed, 69 insertions(+), 69 deletions(-) -- Cheers, Stephen Rothwell sfr at canb.auug.org.au http://www.canb.auug.org.au/~sfr/ a4f1f328f03f481ee9a9446cd038a3370995ea0d diff --git a/arch/ppc64/kernel/iSeries_vio.c b/arch/ppc64/kernel/iSeries_vio.c --- a/arch/ppc64/kernel/iSeries_vio.c +++ b/arch/ppc64/kernel/iSeries_vio.c @@ -131,6 +131,10 @@ static int vio_match_device_iseries(cons return strncmp(dev->type, id->type, strlen(id->type)) == 0; } +static struct vio_bus_ops vio_bus_ops_iseries = { + .match = vio_match_device_iseries, +}; + /** * vio_bus_init_iseries: - Initialize the iSeries virtual IO bus */ @@ -138,7 +142,7 @@ static int __init vio_bus_init_iseries(v { int err; - err = vio_bus_init(vio_match_device_iseries, NULL, NULL); + err = vio_bus_init(&vio_bus_ops_iseries); if (err == 0) { iommu_vio_init(); vio_bus_device.iommu_table = &vio_iommu_table; diff --git a/arch/ppc64/kernel/pSeries_vio.c b/arch/ppc64/kernel/pSeries_vio.c --- a/arch/ppc64/kernel/pSeries_vio.c +++ b/arch/ppc64/kernel/pSeries_vio.c @@ -76,6 +76,12 @@ static void vio_unregister_device_pserie device_remove_file(&viodev->dev, &dev_attr_devspec); } +static struct vio_bus_ops vio_bus_ops_pseries = { + .match = vio_match_device_pseries, + .unregister_device = vio_unregister_device_pseries, + .release_device = vio_release_device_pseries, +}; + /** * vio_bus_init_pseries: - Initialize the pSeries virtual IO bus */ @@ -83,9 +89,7 @@ static int __init vio_bus_init_pseries(v { int err; - err = vio_bus_init(vio_match_device_pseries, - vio_unregister_device_pseries, - vio_release_device_pseries); + err = vio_bus_init(&vio_bus_ops_pseries); if (err == 0) probe_bus_pseries(); return err; diff --git a/arch/ppc64/kernel/vio.c b/arch/ppc64/kernel/vio.c --- a/arch/ppc64/kernel/vio.c +++ b/arch/ppc64/kernel/vio.c @@ -32,10 +32,7 @@ struct vio_dev vio_bus_device = { /* fa .dev.bus = &vio_bus_type, }; -static int (*is_match)(const struct vio_device_id *id, - const struct vio_dev *dev); -static void (*unregister_device_callback)(struct vio_dev *dev); -static void (*release_device_callback)(struct device *dev); +static struct vio_bus_ops vio_bus_ops; /* * Convert from struct device to struct vio_dev and pass to driver. @@ -115,7 +112,7 @@ static const struct vio_device_id *vio_m const struct vio_device_id *ids, const struct vio_dev *dev) { while (ids->type) { - if (is_match(ids, dev)) + if (vio_bus_ops.match(ids, dev)) return ids; ids++; } @@ -125,16 +122,11 @@ static const struct vio_device_id *vio_m /** * vio_bus_init: - Initialize the virtual IO bus */ -int __init vio_bus_init(int (*match_func)(const struct vio_device_id *id, - const struct vio_dev *dev), - void (*unregister_dev)(struct vio_dev *), - void (*release_dev)(struct device *)) +int __init vio_bus_init(struct vio_bus_ops *ops) { int err; - is_match = match_func; - unregister_device_callback = unregister_dev; - release_device_callback = release_dev; + vio_bus_ops = *ops; err = bus_register(&vio_bus_type); if (err) { @@ -159,8 +151,8 @@ int __init vio_bus_init(int (*match_func /* vio_dev refcount hit 0 */ static void __devinit vio_dev_release(struct device *dev) { - if (release_device_callback) - release_device_callback(dev); + if (vio_bus_ops.release_device) + vio_bus_ops.release_device(dev); kfree(to_vio_dev(dev)); } @@ -191,8 +183,8 @@ struct vio_dev * __devinit vio_register_ void __devinit vio_unregister_device(struct vio_dev *viodev) { - if (unregister_device_callback) - unregister_device_callback(viodev); + if (vio_bus_ops.unregister_device) + vio_bus_ops.unregister_device(viodev); device_remove_file(&viodev->dev, &dev_attr_name); device_unregister(&viodev->dev); } diff --git a/drivers/scsi/ibmvscsi/rpa_vscsi.c b/drivers/scsi/ibmvscsi/rpa_vscsi.c --- a/drivers/scsi/ibmvscsi/rpa_vscsi.c +++ b/drivers/scsi/ibmvscsi/rpa_vscsi.c @@ -28,6 +28,7 @@ */ #include +#include #include #include #include diff --git a/include/asm-ppc64/vio.h b/include/asm-ppc64/vio.h --- a/include/asm-ppc64/vio.h +++ b/include/asm-ppc64/vio.h @@ -19,13 +19,14 @@ #include #include #include + #include -#include #include -/* + +/* * Architecture-specific constants for drivers to * extract attributes of the device using vio_get_attribute() -*/ + */ #define VETH_MAC_ADDR "local-mac-address" #define VETH_MCAST_FILTER_SIZE "ibm,mac-address-filters" @@ -37,30 +38,19 @@ #define VIO_IRQ_DISABLE 0UL #define VIO_IRQ_ENABLE 1UL -struct vio_dev; -struct vio_driver; -struct vio_device_id; struct iommu_table; -int vio_register_driver(struct vio_driver *drv); -void vio_unregister_driver(struct vio_driver *drv); - -#ifdef CONFIG_PPC_PSERIES -struct vio_dev * __devinit vio_register_device_node( - struct device_node *node_vdev); -#endif -void __devinit vio_unregister_device(struct vio_dev *dev); -struct vio_dev *vio_find_node(struct device_node *vnode); - -const void * vio_get_attribute(struct vio_dev *vdev, void* which, int* length); -int vio_get_irq(struct vio_dev *dev); -int vio_enable_interrupts(struct vio_dev *dev); -int vio_disable_interrupts(struct vio_dev *dev); -extern struct vio_dev * __devinit vio_register_device(struct vio_dev *viodev); - -extern struct dma_mapping_ops vio_dma_ops; - -extern struct bus_type vio_bus_type; +/* + * The vio_dev structure is used to describe virtual I/O devices. + */ +struct vio_dev { + struct iommu_table *iommu_table; /* vio_map_* uses this */ + char *name; + char *type; + uint32_t unit_address; + unsigned int irq; + struct device dev; +}; struct vio_device_id { char *type; @@ -70,42 +60,51 @@ struct vio_device_id { struct vio_driver { struct list_head node; char *name; - const struct vio_device_id *id_table; /* NULL if wants all devices */ - int (*probe) (struct vio_dev *dev, const struct vio_device_id *id); /* New device inserted */ - int (*remove) (struct vio_dev *dev); /* Device removed (NULL if not a hot-plug capable driver) */ + const struct vio_device_id *id_table; + int (*probe)(struct vio_dev *dev, const struct vio_device_id *id); + int (*remove)(struct vio_dev *dev); unsigned long driver_data; - struct device_driver driver; }; +struct vio_bus_ops { + int (*match)(const struct vio_device_id *id, const struct vio_dev *dev); + void (*unregister_device)(struct vio_dev *); + void (*release_device)(struct device *); +}; + +extern struct dma_mapping_ops vio_dma_ops; +extern struct bus_type vio_bus_type; +extern struct vio_dev vio_bus_device; + +extern int vio_register_driver(struct vio_driver *drv); +extern void vio_unregister_driver(struct vio_driver *drv); + +extern struct vio_dev * __devinit vio_register_device(struct vio_dev *viodev); +extern void __devinit vio_unregister_device(struct vio_dev *dev); + +extern int vio_bus_init(struct vio_bus_ops *); + +#ifdef CONFIG_PPC_PSERIES +struct device_node; + +extern struct vio_dev * __devinit vio_register_device_node( + struct device_node *node_vdev); +extern struct vio_dev *vio_find_node(struct device_node *vnode); +extern const void *vio_get_attribute(struct vio_dev *vdev, void *which, + int *length); +extern int vio_enable_interrupts(struct vio_dev *dev); +extern int vio_disable_interrupts(struct vio_dev *dev); +#endif + static inline struct vio_driver *to_vio_driver(struct device_driver *drv) { return container_of(drv, struct vio_driver, driver); } -/* - * The vio_dev structure is used to describe virtual I/O devices. - */ -struct vio_dev { - struct iommu_table *iommu_table; /* vio_map_* uses this */ - char *name; - char *type; - uint32_t unit_address; - unsigned int irq; - - struct device dev; -}; - -extern struct vio_dev vio_bus_device; - static inline struct vio_dev *to_vio_dev(struct device *dev) { return container_of(dev, struct vio_dev, dev); } -extern int vio_bus_init(int (*is_match)(const struct vio_device_id *id, - const struct vio_dev *dev), - void (*)(struct vio_dev *), - void (*)(struct device *)); - #endif /* _ASM_VIO_H */ From sfr at canb.auug.org.au Wed Aug 17 16:40:12 2005 From: sfr at canb.auug.org.au (Stephen Rothwell) Date: Wed, 17 Aug 2005 16:40:12 +1000 Subject: [PATCH 2/4] Create vio_register_device In-Reply-To: <20050817163531.6368f9ec.sfr@canb.auug.org.au> References: <20050712173655.387d5110.sfr@canb.auug.org.au> <20050712175026.1652e11a.sfr@canb.auug.org.au> <20050817163531.6368f9ec.sfr@canb.auug.org.au> Message-ID: <20050817164012.46dd77d0.sfr@canb.auug.org.au> Take some assignments out of vio_register_device_common and rename it to vio_register_device. Signed-off-by: Stephen Rothwell --- arch/ppc64/kernel/iSeries_vio.c | 15 +++++++++++---- arch/ppc64/kernel/pSeries_vio.c | 9 ++++++--- arch/ppc64/kernel/vio.c | 10 ++-------- include/asm-ppc64/vio.h | 4 +--- 4 files changed, 20 insertions(+), 18 deletions(-) -- Cheers, Stephen Rothwell sfr at canb.auug.org.au http://www.canb.auug.org.au/~sfr/ aa9434fa10c8644eca4652021448e62463bfbc3c diff --git a/arch/ppc64/kernel/iSeries_vio.c b/arch/ppc64/kernel/iSeries_vio.c --- a/arch/ppc64/kernel/iSeries_vio.c +++ b/arch/ppc64/kernel/iSeries_vio.c @@ -68,7 +68,7 @@ static void __init iommu_vio_init(void) } /** - * vio_register_device: - Register a new vio device. + * vio_register_device_iseries: - Register a new iSeries vio device. * @voidev: The device to register. */ static struct vio_dev *__init vio_register_device_iseries(char *type, @@ -76,7 +76,7 @@ static struct vio_dev *__init vio_regist { struct vio_dev *viodev; - /* allocate a vio_dev for this node */ + /* allocate a vio_dev for this device */ viodev = kmalloc(sizeof(struct vio_dev), GFP_KERNEL); if (!viodev) return NULL; @@ -84,8 +84,15 @@ static struct vio_dev *__init vio_regist snprintf(viodev->dev.bus_id, BUS_ID_SIZE, "%s%d", type, unit_num); - return vio_register_device_common(viodev, viodev->dev.bus_id, type, - unit_num, &vio_iommu_table); + viodev->name = viodev->dev.bus_id; + viodev->type = type; + viodev->unit_address = unit_num; + viodev->iommu_table = &vio_iommu_table; + if (vio_register_device(viodev) == NULL) { + kfree(viodev); + return NULL; + } + return viodev; } void __init probe_bus_iseries(void) diff --git a/arch/ppc64/kernel/pSeries_vio.c b/arch/ppc64/kernel/pSeries_vio.c --- a/arch/ppc64/kernel/pSeries_vio.c +++ b/arch/ppc64/kernel/pSeries_vio.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -181,11 +182,13 @@ struct vio_dev * __devinit vio_register_ } snprintf(viodev->dev.bus_id, BUS_ID_SIZE, "%x", *unit_address); + viodev->name = of_node->name; + viodev->type = of_node->type; + viodev->unit_address = *unit_address; + viodev->iommu_table = vio_build_iommu_table(viodev); /* register with generic device framework */ - if (vio_register_device_common(viodev, of_node->name, of_node->type, - *unit_address, vio_build_iommu_table(viodev)) - == NULL) { + if (vio_register_device(viodev) == NULL) { /* XXX free TCE table */ kfree(viodev); return NULL; diff --git a/arch/ppc64/kernel/vio.c b/arch/ppc64/kernel/vio.c --- a/arch/ppc64/kernel/vio.c +++ b/arch/ppc64/kernel/vio.c @@ -171,14 +171,8 @@ static ssize_t viodev_show_name(struct d } DEVICE_ATTR(name, S_IRUSR | S_IRGRP | S_IROTH, viodev_show_name, NULL); -struct vio_dev * __devinit vio_register_device_common( - struct vio_dev *viodev, char *name, char *type, - uint32_t unit_address, struct iommu_table *iommu_table) -{ - viodev->name = name; - viodev->type = type; - viodev->unit_address = unit_address; - viodev->iommu_table = iommu_table; +struct vio_dev * __devinit vio_register_device(struct vio_dev *viodev) +{ /* init generic 'struct device' fields: */ viodev->dev.parent = &vio_bus_device.dev; viodev->dev.bus = &vio_bus_type; diff --git a/include/asm-ppc64/vio.h b/include/asm-ppc64/vio.h --- a/include/asm-ppc64/vio.h +++ b/include/asm-ppc64/vio.h @@ -56,9 +56,7 @@ const void * vio_get_attribute(struct vi int vio_get_irq(struct vio_dev *dev); int vio_enable_interrupts(struct vio_dev *dev); int vio_disable_interrupts(struct vio_dev *dev); -extern struct vio_dev * __devinit vio_register_device_common( - struct vio_dev *viodev, char *name, char *type, - uint32_t unit_address, struct iommu_table *iommu_table); +extern struct vio_dev * __devinit vio_register_device(struct vio_dev *viodev); extern struct dma_mapping_ops vio_dma_ops; From sfr at canb.auug.org.au Wed Aug 17 16:42:59 2005 From: sfr at canb.auug.org.au (Stephen Rothwell) Date: Wed, 17 Aug 2005 16:42:59 +1000 Subject: [PATCH 4/4] Make MODULE_DEVICE_TABLE work for vio devices In-Reply-To: <20050817163531.6368f9ec.sfr@canb.auug.org.au> References: <20050712173655.387d5110.sfr@canb.auug.org.au> <20050712175026.1652e11a.sfr@canb.auug.org.au> <20050817163531.6368f9ec.sfr@canb.auug.org.au> Message-ID: <20050817164259.64b97478.sfr@canb.auug.org.au> Make MODULE_DEVICE_TABLE work for vio devices. Signed-off-by: Stephen Rothwell --- arch/ppc64/kernel/vio.c | 2 +- drivers/block/viodasd.c | 2 +- drivers/cdrom/viocd.c | 2 +- drivers/char/hvc_vio.c | 2 +- drivers/char/hvcs.c | 2 +- drivers/char/viotape.c | 2 +- drivers/net/ibmveth.c | 2 +- drivers/net/iseries_veth.c | 2 +- drivers/scsi/ibmvscsi/ibmvscsi.c | 2 +- include/asm-ppc64/vio.h | 6 +----- include/linux/mod_devicetable.h | 7 ++++++- scripts/mod/file2alias.c | 19 +++++++++++++++++++ 12 files changed, 35 insertions(+), 15 deletions(-) -- Cheers, Stephen Rothwell sfr at canb.auug.org.au http://www.canb.auug.org.au/~sfr/ 040e6a85b831f516593e7ce70c805eb7393a22b4 diff --git a/arch/ppc64/kernel/vio.c b/arch/ppc64/kernel/vio.c --- a/arch/ppc64/kernel/vio.c +++ b/arch/ppc64/kernel/vio.c @@ -111,7 +111,7 @@ EXPORT_SYMBOL(vio_unregister_driver); static const struct vio_device_id *vio_match_device( const struct vio_device_id *ids, const struct vio_dev *dev) { - while (ids->type) { + while (ids->type[0] != '\0') { if (vio_bus_ops.match(ids, dev)) return ids; ids++; diff --git a/drivers/block/viodasd.c b/drivers/block/viodasd.c --- a/drivers/block/viodasd.c +++ b/drivers/block/viodasd.c @@ -776,7 +776,7 @@ static int viodasd_remove(struct vio_dev */ static struct vio_device_id viodasd_device_table[] __devinitdata = { { "viodasd", "" }, - { 0, } + { "", "" } }; MODULE_DEVICE_TABLE(vio, viodasd_device_table); diff --git a/drivers/cdrom/viocd.c b/drivers/cdrom/viocd.c --- a/drivers/cdrom/viocd.c +++ b/drivers/cdrom/viocd.c @@ -734,7 +734,7 @@ static int viocd_remove(struct vio_dev * */ static struct vio_device_id viocd_device_table[] __devinitdata = { { "viocd", "" }, - { 0, } + { "", "" } }; MODULE_DEVICE_TABLE(vio, viocd_device_table); diff --git a/drivers/char/hvc_vio.c b/drivers/char/hvc_vio.c --- a/drivers/char/hvc_vio.c +++ b/drivers/char/hvc_vio.c @@ -39,7 +39,7 @@ char hvc_driver_name[] = "hvc_console"; static struct vio_device_id hvc_driver_table[] __devinitdata = { {"serial", "hvterm1"}, - { NULL, } + { "", "" } }; MODULE_DEVICE_TABLE(vio, hvc_driver_table); diff --git a/drivers/char/hvcs.c b/drivers/char/hvcs.c --- a/drivers/char/hvcs.c +++ b/drivers/char/hvcs.c @@ -527,7 +527,7 @@ static int khvcsd(void *unused) static struct vio_device_id hvcs_driver_table[] __devinitdata= { {"serial-server", "hvterm2"}, - { NULL, } + { "", "" } }; MODULE_DEVICE_TABLE(vio, hvcs_driver_table); diff --git a/drivers/char/viotape.c b/drivers/char/viotape.c --- a/drivers/char/viotape.c +++ b/drivers/char/viotape.c @@ -991,7 +991,7 @@ static int viotape_remove(struct vio_dev */ static struct vio_device_id viotape_device_table[] __devinitdata = { { "viotape", "" }, - { 0, } + { "", "" } }; MODULE_DEVICE_TABLE(vio, viotape_device_table); diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c --- a/drivers/net/ibmveth.c +++ b/drivers/net/ibmveth.c @@ -1144,7 +1144,7 @@ static void ibmveth_proc_unregister_driv static struct vio_device_id ibmveth_device_table[] __devinitdata= { { "network", "IBM,l-lan"}, - { 0,} + { "", "" } }; MODULE_DEVICE_TABLE(vio, ibmveth_device_table); diff --git a/drivers/net/iseries_veth.c b/drivers/net/iseries_veth.c --- a/drivers/net/iseries_veth.c +++ b/drivers/net/iseries_veth.c @@ -1370,7 +1370,7 @@ static int veth_probe(struct vio_dev *vd */ static struct vio_device_id veth_device_table[] __devinitdata = { { "vlan", "" }, - { NULL, NULL } + { "", "" } }; MODULE_DEVICE_TABLE(vio, veth_device_table); diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c --- a/drivers/scsi/ibmvscsi/ibmvscsi.c +++ b/drivers/scsi/ibmvscsi/ibmvscsi.c @@ -1442,7 +1442,7 @@ static int ibmvscsi_remove(struct vio_de */ static struct vio_device_id ibmvscsi_device_table[] __devinitdata = { {"vscsi", "IBM,v-scsi"}, - {0,} + { "", "" } }; MODULE_DEVICE_TABLE(vio, ibmvscsi_device_table); diff --git a/include/asm-ppc64/vio.h b/include/asm-ppc64/vio.h --- a/include/asm-ppc64/vio.h +++ b/include/asm-ppc64/vio.h @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -52,11 +53,6 @@ struct vio_dev { struct device dev; }; -struct vio_device_id { - char *type; - char *compat; -}; - struct vio_driver { struct list_head node; char *name; diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h --- a/include/linux/mod_devicetable.h +++ b/include/linux/mod_devicetable.h @@ -1,6 +1,6 @@ /* * Device tables which are exported to userspace via - * scripts/table2alias.c. You must keep that file in sync with this + * scripts/mod/file2alias.c. You must keep that file in sync with this * header. */ @@ -185,6 +185,11 @@ struct of_device_id void *data; }; +/* VIO */ +struct vio_device_id { + char type[32]; + char compat[32]; +}; /* PCMCIA */ diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -341,6 +341,22 @@ static int do_of_entry (const char *file return 1; } +static int do_vio_entry(const char *filename, struct vio_device_id *vio, + char *alias) +{ + char *tmp; + + sprintf(alias, "vio:T%sS%s", vio->type[0] ? vio->type : "*", + vio->compat[0] ? vio->compat : "*"); + + /* Replace all whitespace with underscores */ + for (tmp = alias; tmp && *tmp; tmp++) + if (isspace (*tmp)) + *tmp = '_'; + + return 1; +} + /* Ignore any prefix, eg. v850 prepends _ */ static inline int sym_is(const char *symbol, const char *name) { @@ -422,6 +438,9 @@ void handle_moddevtable(struct module *m else if (sym_is(symname, "__mod_of_device_table")) do_table(symval, sym->st_size, sizeof(struct of_device_id), do_of_entry, mod); + else if (sym_is(symname, "__mod_vio_device_table")) + do_table(symval, sym->st_size, sizeof(struct vio_device_id), + do_vio_entry, mod); } From michael at ellerman.id.au Wed Aug 17 17:08:10 2005 From: michael at ellerman.id.au (Michael Ellerman) Date: Wed, 17 Aug 2005 17:08:10 +1000 (EST) Subject: [RFC/PATCH 1/2] ppc64: Rename VMALLOCBASE to VMALLOC_OFFSET Message-ID: <20050817070810.5D0A867FAF@ozlabs.org> VMALLOCBASE would seem to be similar to KERNELBASE, but in fact it's not, it's more like PAGE_OFFSET, so rename it to avoid confusion. Signed-off-by: Michael Ellerman --- arch/ppc64/kernel/lparmap.c | 4 ++-- arch/ppc64/mm/slb.c | 6 +++--- include/asm-ppc64/page.h | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) Index: work/arch/ppc64/mm/slb.c =================================================================== --- work.orig/arch/ppc64/mm/slb.c +++ work/arch/ppc64/mm/slb.c @@ -67,8 +67,8 @@ static void slb_flush_and_rebolt(void) /* Slot 2 - kernel stack */ "slbmte %2,%3\n" "isync" - :: "r"(mk_vsid_data(VMALLOCBASE, SLB_VSID_KERNEL)), - "r"(mk_esid_data(VMALLOCBASE, 1)), + :: "r"(mk_vsid_data(VMALLOC_OFFSET, SLB_VSID_KERNEL)), + "r"(mk_esid_data(VMALLOC_OFFSET, 1)), "r"(mk_vsid_data(ksp_esid_data, ksp_flags)), "r"(ksp_esid_data) : "memory"); @@ -146,7 +146,7 @@ void slb_initialize(void) asm volatile("slbmte %0,%0"::"r" (0) : "memory"); asm volatile("isync; slbia; isync":::"memory"); create_slbe(KERNELBASE, flags, 0); - create_slbe(VMALLOCBASE, SLB_VSID_KERNEL, 1); + create_slbe(VMALLOC_OFFSET, SLB_VSID_KERNEL, 1); /* We don't bolt the stack for the time being - we're in boot, * so the stack is in the bolted segment. By the time it goes * elsewhere, we'll call _switch() which will bolt in the new Index: work/include/asm-ppc64/page.h =================================================================== --- work.orig/include/asm-ppc64/page.h +++ work/include/asm-ppc64/page.h @@ -201,9 +201,9 @@ extern u64 ppc64_pft_size; /* Log 2 of /* to change! */ #define PAGE_OFFSET ASM_CONST(0xC000000000000000) #define KERNELBASE PAGE_OFFSET -#define VMALLOCBASE ASM_CONST(0xD000000000000000) +#define VMALLOC_OFFSET ASM_CONST(0xD000000000000000) -#define VMALLOC_REGION_ID (VMALLOCBASE >> REGION_SHIFT) +#define VMALLOC_REGION_ID (VMALLOC_OFFSET >> REGION_SHIFT) #define KERNEL_REGION_ID (KERNELBASE >> REGION_SHIFT) #define USER_REGION_ID (0UL) #define REGION_ID(ea) (((unsigned long)(ea)) >> REGION_SHIFT) Index: work/arch/ppc64/kernel/lparmap.c =================================================================== --- work.orig/arch/ppc64/kernel/lparmap.c +++ work/arch/ppc64/kernel/lparmap.c @@ -18,8 +18,8 @@ const struct LparMap __attribute__((__se .xEsids = { { .xKernelEsid = GET_ESID(KERNELBASE), .xKernelVsid = KERNEL_VSID(KERNELBASE), }, - { .xKernelEsid = GET_ESID(VMALLOCBASE), - .xKernelVsid = KERNEL_VSID(VMALLOCBASE), }, + { .xKernelEsid = GET_ESID(VMALLOC_OFFSET), + .xKernelVsid = KERNEL_VSID(VMALLOC_OFFSET), }, }, .xRanges = { From michael at ellerman.id.au Wed Aug 17 17:08:13 2005 From: michael at ellerman.id.au (Michael Ellerman) Date: Wed, 17 Aug 2005 17:08:13 +1000 (EST) Subject: [RFC/PATCH 2/2] ppc64: Seperate usage of KERNELBASE and PAGE_OFFSET Message-ID: <20050817070813.4859067FB6@ozlabs.org> This patch *tries* to seperate usage of KERNELBASE and PAGE_OFFSET. PAGE_OFFSET == 0xC00..00 and always will. It's the quantity you subtract from a virtual kernel address to get a physical one. KERNELBASE == 0xC00..00 *currently*, but might one day be something else, hold onto your hats. It points to the start of the kernel text + data in virtual memory. I'd really appreciate it if people can cast an eye over this, as I'm sure I've got some wrong. There's still a few more users of KERNELBASE that could be converted to __pa() or __va() but I'll get to those later. This actually boots on my P5 LPAR, but there might be some subtleties. Signed-off-by: Michael Ellerman --- arch/ppc64/kernel/head.S | 12 ++++++------ arch/ppc64/kernel/machine_kexec.c | 5 ++--- arch/ppc64/kernel/pmac_smp.c | 8 ++++---- arch/ppc64/kernel/prom_init.c | 4 ++-- arch/ppc64/kernel/setup.c | 2 +- arch/ppc64/mm/hash_native.c | 2 +- arch/ppc64/mm/hash_utils.c | 8 ++++---- arch/ppc64/mm/slb.c | 10 +++++----- arch/ppc64/mm/stab.c | 22 ++++++++++------------ arch/ppc64/oprofile/op_model_power4.c | 4 ++-- arch/ppc64/oprofile/op_model_rs64.c | 2 +- arch/ppc64/xmon/xmon.c | 4 ++-- include/asm-ppc64/mmu.h | 4 ++-- include/asm-ppc64/page.h | 6 +++--- include/asm-ppc64/ppc_asm.h | 13 ------------- 15 files changed, 45 insertions(+), 61 deletions(-) Index: work/arch/ppc64/mm/stab.c =================================================================== --- work.orig/arch/ppc64/mm/stab.c +++ work/arch/ppc64/mm/stab.c @@ -40,7 +40,7 @@ static int make_ste(unsigned long stab, unsigned long entry, group, old_esid, castout_entry, i; unsigned int global_entry; struct stab_entry *ste, *castout_ste; - unsigned long kernel_segment = (esid << SID_SHIFT) >= KERNELBASE; + unsigned long kernel_segment = (esid << SID_SHIFT) >= PAGE_OFFSET; vsid_data = vsid << STE_VSID_SHIFT; esid_data = esid << SID_SHIFT | STE_ESID_KP | STE_ESID_V; @@ -83,7 +83,7 @@ static int make_ste(unsigned long stab, } /* Dont cast out the first kernel segment */ - if ((castout_ste->esid_data & ESID_MASK) != KERNELBASE) + if ((castout_ste->esid_data & ESID_MASK) != PAGE_OFFSET) break; castout_entry = (castout_entry + 1) & 0xf; @@ -122,7 +122,7 @@ static int __ste_allocate(unsigned long unsigned long offset; /* Kernel or user address? */ - if (ea >= KERNELBASE) { + if (ea >= PAGE_OFFSET) { vsid = get_kernel_vsid(ea); } else { if ((ea >= TASK_SIZE_USER64) || (! mm)) @@ -133,7 +133,7 @@ static int __ste_allocate(unsigned long stab_entry = make_ste(get_paca()->stab_addr, GET_ESID(ea), vsid); - if (ea < KERNELBASE) { + if (ea < PAGE_OFFSET) { offset = __get_cpu_var(stab_cache_ptr); if (offset < NR_STAB_CACHE_ENTRIES) __get_cpu_var(stab_cache[offset++]) = stab_entry; @@ -190,7 +190,7 @@ void switch_stab(struct task_struct *tsk entry++, ste++) { unsigned long ea; ea = ste->esid_data & ESID_MASK; - if (ea < KERNELBASE) { + if (ea < PAGE_OFFSET) { ste->esid_data = 0; } } @@ -248,12 +248,10 @@ void stabs_alloc(void) panic("Unable to allocate segment table for CPU %d.\n", cpu); - newstab += KERNELBASE; + memset(__va(newstab), 0, PAGE_SIZE); - memset((void *)newstab, 0, PAGE_SIZE); - - paca[cpu].stab_addr = newstab; - paca[cpu].stab_real = virt_to_abs(newstab); + paca[cpu].stab_addr = (u64)__va(newstab); + paca[cpu].stab_real = newstab; printk(KERN_DEBUG "Segment table for CPU %d at 0x%lx virtual, 0x%lx absolute\n", cpu, paca[cpu].stab_addr, paca[cpu].stab_real); } } @@ -265,13 +263,13 @@ void stabs_alloc(void) */ void stab_initialize(unsigned long stab) { - unsigned long vsid = get_kernel_vsid(KERNELBASE); + unsigned long vsid = get_kernel_vsid(PAGE_OFFSET); if (cpu_has_feature(CPU_FTR_SLB)) { slb_initialize(); } else { asm volatile("isync; slbia; isync":::"memory"); - make_ste(stab, GET_ESID(KERNELBASE), vsid); + make_ste(stab, GET_ESID(PAGE_OFFSET), vsid); /* Order update */ asm volatile("sync":::"memory"); Index: work/include/asm-ppc64/ppc_asm.h =================================================================== --- work.orig/include/asm-ppc64/ppc_asm.h +++ work/include/asm-ppc64/ppc_asm.h @@ -110,19 +110,6 @@ ori reg,reg,(label)@l; -/* PPPBBB - DRENG If KERNELBASE is always 0xC0..., - * Then we can easily do this with one asm insn. -Peter - */ -#define tophys(rd,rs) \ - lis rd,((KERNELBASE>>48)&0xFFFF); \ - rldicr rd,rd,32,31; \ - sub rd,rs,rd - -#define tovirt(rd,rs) \ - lis rd,((KERNELBASE>>48)&0xFFFF); \ - rldicr rd,rd,32,31; \ - add rd,rs,rd - /* Condition Register Bit Fields */ #define cr0 0 Index: work/arch/ppc64/kernel/head.S =================================================================== --- work.orig/arch/ppc64/kernel/head.S +++ work/arch/ppc64/kernel/head.S @@ -100,7 +100,7 @@ END_FTR_SECTION(0, 1) * This is required by the hypervisor */ . = 0x20 - .llong hvReleaseData-KERNELBASE + .llong hvReleaseData-PAGE_OFFSET /* * At offset 0x28 and 0x30 are offsets to the msChunks @@ -108,8 +108,8 @@ END_FTR_SECTION(0, 1) * between physical addresses and absolute addresses) and * to the pidhash table (also used by the debugger) */ - .llong msChunks-KERNELBASE - .llong 0 /* pidhash-KERNELBASE SFRXXX */ + .llong msChunks-PAGE_OFFSET + .llong 0 /* pidhash-PAGE_OFFSET SFRXXX */ /* Offset 0x38 - Pointer to start of embedded System.map */ .globl embedded_sysmap_start @@ -1301,7 +1301,7 @@ _GLOBAL(__start_initialization_multiplat li r24,0 /* Switch off MMU if not already */ - LOADADDR(r4, .__after_prom_start - KERNELBASE) + LOADADDR(r4, .__after_prom_start - PAGE_OFFSET) add r4,r4,r30 bl .__mmu_off b .__after_prom_start @@ -1355,11 +1355,11 @@ _STATIC(__after_prom_start) * * Note: This process overwrites the OF exception vectors. * r26 == relocation offset - * r27 == KERNELBASE + * r27 == PAGE_OFFSET */ bl .reloc_offset mr r26,r3 - SET_REG_TO_CONST(r27,KERNELBASE) + SET_REG_TO_CONST(r27,PAGE_OFFSET) li r3,0 /* target addr */ Index: work/arch/ppc64/kernel/machine_kexec.c =================================================================== --- work.orig/arch/ppc64/kernel/machine_kexec.c +++ work/arch/ppc64/kernel/machine_kexec.c @@ -184,9 +184,8 @@ void kexec_copy_flush(struct kimage *ima * including ones that were in place on the original copy */ for (i = 0; i < nr_segments; i++) - flush_icache_range(ranges[i].mem + KERNELBASE, - ranges[i].mem + KERNELBASE + - ranges[i].memsz); + flush_icache_range((unsigned long)__va(ranges[i].mem), + (unsigned long)__va(ranges[i].mem + ranges[i].memsz)); } #ifdef CONFIG_SMP Index: work/arch/ppc64/kernel/pmac_smp.c =================================================================== --- work.orig/arch/ppc64/kernel/pmac_smp.c +++ work/arch/ppc64/kernel/pmac_smp.c @@ -241,7 +241,7 @@ static void __init smp_core99_kick_cpu(i unsigned long new_vector; unsigned long flags; volatile unsigned int *vector - = ((volatile unsigned int *)(KERNELBASE+0x100)); + = ((volatile unsigned int *)(PAGE_OFFSET + 0x100)); if (nr < 1 || nr > 3) return; @@ -253,8 +253,8 @@ static void __init smp_core99_kick_cpu(i /* Save reset vector */ save_vector = *vector; - /* Setup fake reset vector that does - * b .pmac_secondary_start - KERNELBASE + /* Setup fake reset vector that does + * b .pmac_secondary_start - PAGE_OFFSET */ switch(nr) { case 1: @@ -268,7 +268,7 @@ static void __init smp_core99_kick_cpu(i new_vector = (unsigned long)pmac_secondary_start_3; break; } - *vector = 0x48000002 + (new_vector - KERNELBASE); + *vector = 0x48000002 + (new_vector - PAGE_OFFSET); /* flush data cache and inval instruction cache */ flush_icache_range((unsigned long) vector, (unsigned long) vector + 4); Index: work/arch/ppc64/kernel/prom_init.c =================================================================== --- work.orig/arch/ppc64/kernel/prom_init.c +++ work/arch/ppc64/kernel/prom_init.c @@ -1846,7 +1846,7 @@ static void __init prom_check_initrd(uns if ( r3 && r4 && r4 != 0xdeadbeef) { u64 val; - RELOC(prom_initrd_start) = (r3 >= KERNELBASE) ? __pa(r3) : r3; + RELOC(prom_initrd_start) = (r3 >= PAGE_OFFSET) ? __pa(r3) : r3; RELOC(prom_initrd_end) = RELOC(prom_initrd_start) + r4; val = (u64)RELOC(prom_initrd_start); @@ -1918,7 +1918,7 @@ unsigned long __init prom_init(unsigned * On pSeries and BPA, copy the CPU hold code */ if (RELOC(of_platform) & (PLATFORM_PSERIES | PLATFORM_BPA)) - copy_and_flush(0, KERNELBASE - offset, 0x100, 0); + copy_and_flush(__pa(KERNELBASE), KERNELBASE - offset, 0x100, 0); /* * Get memory cells format Index: work/arch/ppc64/kernel/setup.c =================================================================== --- work.orig/arch/ppc64/kernel/setup.c +++ work/arch/ppc64/kernel/setup.c @@ -550,7 +550,7 @@ static void __init check_for_initrd(void /* If we were passed an initrd, set the ROOT_DEV properly if the values * look sensible. If not, clear initrd reference. */ - if (initrd_start >= KERNELBASE && initrd_end >= KERNELBASE && + if (initrd_start >= PAGE_OFFSET && initrd_end >= PAGE_OFFSET && initrd_end > initrd_start) ROOT_DEV = Root_RAM0; else Index: work/arch/ppc64/mm/hash_native.c =================================================================== --- work.orig/arch/ppc64/mm/hash_native.c +++ work/arch/ppc64/mm/hash_native.c @@ -352,7 +352,7 @@ static void native_flush_hash_range(unsi j = 0; for (i = 0; i < number; i++) { - if (batch->addr[i] < KERNELBASE) + if (batch->addr[i] < PAGE_OFFSET) vsid = get_vsid(context, batch->addr[i]); else vsid = get_kernel_vsid(batch->addr[i]); Index: work/arch/ppc64/mm/hash_utils.c =================================================================== --- work.orig/arch/ppc64/mm/hash_utils.c +++ work/arch/ppc64/mm/hash_utils.c @@ -210,7 +210,7 @@ void __init htab_initialize(void) /* create bolted the linear mapping in the hash table */ for (i=0; i < lmb.memory.cnt; i++) { - base = lmb.memory.region[i].physbase + KERNELBASE; + base = (unsigned long)__va(lmb.memory.region[i].physbase); size = lmb.memory.region[i].size; DBG("creating mapping for region: %lx : %lx\n", base, size); @@ -247,8 +247,8 @@ void __init htab_initialize(void) * for either 4K or 16MB pages. */ if (tce_alloc_start) { - tce_alloc_start += KERNELBASE; - tce_alloc_end += KERNELBASE; + tce_alloc_start = (unsigned long)__va(tce_alloc_start); + tce_alloc_end = (unsigned long)__va(tce_alloc_end); if (base + size >= tce_alloc_start) tce_alloc_start = base + size + 1; @@ -361,7 +361,7 @@ void flush_hash_page(unsigned long conte unsigned long vsid, vpn, va, hash, secondary, slot; unsigned long huge = pte_huge(pte); - if (ea < KERNELBASE) + if (ea < PAGE_OFFSET) vsid = get_vsid(context, ea); else vsid = get_kernel_vsid(ea); Index: work/arch/ppc64/mm/slb.c =================================================================== --- work.orig/arch/ppc64/mm/slb.c +++ work/arch/ppc64/mm/slb.c @@ -55,7 +55,7 @@ static void slb_flush_and_rebolt(void) ksp_flags |= SLB_VSID_L; ksp_esid_data = mk_esid_data(get_paca()->kstack, 2); - if ((ksp_esid_data & ESID_MASK) == KERNELBASE) + if ((ksp_esid_data & ESID_MASK) == PAGE_OFFSET) ksp_esid_data &= ~SLB_ESID_V; /* We need to do this all in asm, so we're sure we don't touch @@ -111,14 +111,14 @@ void switch_slb(struct task_struct *tsk, else unmapped_base = TASK_UNMAPPED_BASE_USER64; - if (pc >= KERNELBASE) + if (pc >= PAGE_OFFSET) return; slb_allocate(pc); if (GET_ESID(pc) == GET_ESID(stack)) return; - if (stack >= KERNELBASE) + if (stack >= PAGE_OFFSET) return; slb_allocate(stack); @@ -126,7 +126,7 @@ void switch_slb(struct task_struct *tsk, || (GET_ESID(stack) == GET_ESID(unmapped_base))) return; - if (unmapped_base >= KERNELBASE) + if (unmapped_base >= PAGE_OFFSET) return; slb_allocate(unmapped_base); } @@ -145,7 +145,7 @@ void slb_initialize(void) asm volatile("isync":::"memory"); asm volatile("slbmte %0,%0"::"r" (0) : "memory"); asm volatile("isync; slbia; isync":::"memory"); - create_slbe(KERNELBASE, flags, 0); + create_slbe(PAGE_OFFSET, flags, 0); create_slbe(VMALLOC_OFFSET, SLB_VSID_KERNEL, 1); /* We don't bolt the stack for the time being - we're in boot, * so the stack is in the bolted segment. By the time it goes Index: work/arch/ppc64/oprofile/op_model_power4.c =================================================================== --- work.orig/arch/ppc64/oprofile/op_model_power4.c +++ work/arch/ppc64/oprofile/op_model_power4.c @@ -236,7 +236,7 @@ static unsigned long get_pc(struct pt_re return (unsigned long)__va(pc); /* Not sure where we were */ - if (pc < KERNELBASE) + if (pc < PAGE_OFFSET) /* function descriptor madness */ return *((unsigned long *)kernel_unknown_bucket); @@ -248,7 +248,7 @@ static int get_kernel(unsigned long pc) int is_kernel; if (!mmcra_has_sihv) { - is_kernel = (pc >= KERNELBASE); + is_kernel = (pc >= PAGE_OFFSET); } else { unsigned long mmcra = mfspr(SPRN_MMCRA); is_kernel = ((mmcra & MMCRA_SIPR) == 0); Index: work/arch/ppc64/oprofile/op_model_rs64.c =================================================================== --- work.orig/arch/ppc64/oprofile/op_model_rs64.c +++ work/arch/ppc64/oprofile/op_model_rs64.c @@ -179,7 +179,7 @@ static void rs64_handle_interrupt(struct int val; int i; unsigned long pc = mfspr(SPRN_SIAR); - int is_kernel = (pc >= KERNELBASE); + int is_kernel = (pc >= PAGE_OFFSET); /* set the PMM bit (see comment below) */ mtmsrd(mfmsr() | MSR_PMM); Index: work/arch/ppc64/xmon/xmon.c =================================================================== --- work.orig/arch/ppc64/xmon/xmon.c +++ work/arch/ppc64/xmon/xmon.c @@ -1044,7 +1044,7 @@ static long check_bp_loc(unsigned long a unsigned int instr; addr &= ~3; - if (addr < KERNELBASE) { + if (addr < PAGE_OFFSET) { printf("Breakpoints may only be placed at kernel addresses\n"); return 0; } @@ -1094,7 +1094,7 @@ bpt_cmds(void) dabr.address = 0; dabr.enabled = 0; if (scanhex(&dabr.address)) { - if (dabr.address < KERNELBASE) { + if (dabr.address < PAGE_OFFSET) { printf(badaddr); break; } Index: work/include/asm-ppc64/mmu.h =================================================================== --- work.orig/include/asm-ppc64/mmu.h +++ work/include/asm-ppc64/mmu.h @@ -29,8 +29,8 @@ /* Location of cpu0's segment table */ #define STAB0_PAGE 0x9 -#define STAB0_PHYS_ADDR (STAB0_PAGE<> REGION_SHIFT) -#define KERNEL_REGION_ID (KERNELBASE >> REGION_SHIFT) +#define KERNEL_REGION_ID (PAGE_OFFSET >> REGION_SHIFT) #define USER_REGION_ID (0UL) #define REGION_ID(ea) (((unsigned long)(ea)) >> REGION_SHIFT) -#define __bpn_to_ba(x) ((((unsigned long)(x)) << PAGE_SHIFT) + KERNELBASE) +#define __bpn_to_ba(x) ((((unsigned long)(x)) << PAGE_SHIFT) + PAGE_OFFSET) #define __ba_to_bpn(x) ((((unsigned long)(x)) & ~REGION_MASK) >> PAGE_SHIFT) -#define __va(x) ((void *)((unsigned long)(x) + KERNELBASE)) +#define __va(x) ((void *)((unsigned long)(x) + PAGE_OFFSET)) #ifdef CONFIG_DISCONTIGMEM #define page_to_pfn(page) discontigmem_page_to_pfn(page) From cartoes at uol.com.br Wed Aug 17 16:26:20 2005 From: cartoes at uol.com.br (cartoes at uol.com.br) Date: Wed, 17 Aug 2005 06:26:20 +0000 Subject: =?iso-8859-1?q?Cart=F5es_UOL?= Message-ID: An HTML attachment was scrubbed... URL: http://ozlabs.org/pipermail/linuxppc64-dev/attachments/20050817/afe7b1f5/attachment.htm From arnd at arndb.de Wed Aug 17 21:05:29 2005 From: arnd at arndb.de (Arnd Bergmann) Date: Wed, 17 Aug 2005 13:05:29 +0200 Subject: [PATCH] 1/2 Start header file merger (Was: Re: Beginning Merger Patch) In-Reply-To: <8DC89F16-0704-484A-9216-D94F3EE90CA4@freescale.com> References: <20050805174705.731ffa05.sfr@canb.auug.org.au> <8DC89F16-0704-484A-9216-D94F3EE90CA4@freescale.com> Message-ID: <200508171305.30833.arnd@arndb.de> On Middeweken 17 August 2005 07:39, Kumar Gala wrote: > > For example, there is a fair amount of headers that are specific to > platform support code. It's probably the case that alot of that > should move into the proper platform directory. I have identified a list of files that are included only from files in a single directory (after the platform merge) or not included at all. See the end of this mail. > Now your makefile hackery seems perfectly reasonable if we want to go > that way instead of explicitly including files like Jon's original > patch does. I dont have any strong feelings one way or the other. > The makefile hackery seems less intrusive since we dont have to > duplicate files in both places. I'd like to see if we can come to > some consensus on this since it directly impacts future patches that > we are working on to merge more files and move them into include/asm- > powerpc/ I vote for doing it with the Makefile hacks. The advantage I see in this is that it is obvious from the file in each of the directories which files are already merged and which ones still need to be worked on. Arnd <>< +++ ./bseip.h 0 +++ +++ ./gt64260.h 0 +++ +++ ./hdreg.h 0 +++ +++ ./md.h 0 +++ +++ ./ans-lcd.h 1 +++ ./drivers/macintosh/ans-lcd.c:#include +++ ./gt64260_defs.h 1 +++ ./include/asm-ppc/gt64260.h:#include +++ ./hawk_defs.h 1 +++ ./include/asm-ppc/hawk.h:#include +++ ./iSeries/HvCallSm.h 1 +++ ./arch/ppc64/kernel/iSeries_setup.c:#include +++ ./iSeries/HvReleaseData.h 1 +++ ./arch/ppc64/kernel/LparData.c:#include +++ ./iSeries/ItIplParmsReal.h 1 +++ ./arch/ppc64/kernel/LparData.c:#include +++ ./iSeries/ItSpCommArea.h 1 +++ ./arch/ppc64/kernel/LparData.c:#include +++ ./iSeries/iSeries_io.h 1 +++ ./include/asm-ppc64/io.h:#include +++ ./ibm403.h 1 +++ ./arch/ppc/platforms/4xx/oak.h:#include +++ ./m8260_pci.h 1 +++ ./arch/ppc/syslib/m82xx_pci.h:#include +++ ./mk48t59.h 1 +++ ./arch/ppc/platforms/prep_setup.c:#include +++ ./ppc32.h 1 +++ ./arch/ppc64/kernel/signal32.c:#include +++ ./raven.h 1 +++ ./arch/ppc/platforms/prep_setup.c:#include +++ ./gg2.h 2 +++ ./arch/ppc/platforms/chrp_pci.c:#include ./arch/ppc/platforms/chrp_setup.c:#include +++ ./harrier.h 2 +++ ./arch/ppc/platforms/prpmc800.c:#include ./arch/ppc/syslib/harrier.c:#include +++ ./iSeries/IoHriMainStore.h 2 +++ ./arch/ppc64/kernel/iSeries_proc.c:#include ./arch/ppc64/kernel/iSeries_setup.c:#include +++ ./iSeries/ItVpdAreas.h 2 +++ ./arch/ppc64/kernel/LparData.c:#include ./arch/ppc64/kernel/iSeries_setup.c:#include +++ ./iSeries/LparMap.h 2 +++ ./arch/ppc64/kernel/LparData.c:#include ./arch/ppc64/kernel/iSeries_setup.c:#include +++ ./imalloc.h 2 +++ ./arch/ppc64/mm/imalloc.c:#include ./arch/ppc64/mm/init.c:#include +++ ./ppc4xx_dma.h 2 +++ ./arch/ppc/syslib/ppc4xx_dma.c:#include ./arch/ppc/syslib/ppc4xx_sgdma.c:#include +++ ./xparameters.h 2 +++ ./arch/ppc/platforms/4xx/virtex-ii_pro.h:#include ./arch/ppc/syslib/xilinx_pic.c:#include +++ ./iSeries/HvCallHpt.h 3 +++ ./arch/ppc64/kernel/iSeries_htab.c:#include ./arch/ppc64/kernel/iSeries_setup.c:#include ./arch/ppc64/kernel/process.c:#include +++ ./iSeries/IoHriProcessorVpd.h 3 +++ ./arch/ppc64/kernel/LparData.c:#include ./arch/ppc64/kernel/iSeries_proc.c:#include ./arch/ppc64/kernel/iSeries_setup.c:#include +++ ./iSeries/ItExtVpdPanel.h 3 +++ ./arch/ppc64/kernel/LparData.c:#include ./arch/ppc64/kernel/lparcfg.c:#include ./arch/ppc64/kernel/viopath.c:#include +++ ./iSeries/iSeries_irq.h 3 +++ ./arch/ppc64/kernel/iSeries_irq.c:#include ./arch/ppc64/kernel/iSeries_pci.c:#include ./arch/ppc64/kernel/iSeries_setup.c:#include +++ ./ipic.h 3 +++ ./arch/ppc/platforms/83xx/mpc834x_sys.c:#include ./arch/ppc/syslib/ipic.c:#include ./arch/ppc/syslib/ipic.h:#include +++ ./xics.h 3 +++ ./arch/ppc64/kernel/pSeries_setup.c:#include ./arch/ppc64/kernel/pSeries_smp.c:#include ./arch/ppc64/kernel/xics.c:#include +++ ./plpar_wrappers.h 4 +++ ./arch/ppc64/kernel/pSeries_iommu.c:#include ./arch/ppc64/kernel/pSeries_lpar.c:#include ./arch/ppc64/kernel/pSeries_setup.c:#include ./arch/ppc64/kernel/pSeries_smp.c:#include +++ ./prep_nvram.h 4 +++ ./arch/ppc/platforms/lopec.c:#include ./arch/ppc/platforms/pplus.c:#include ./arch/ppc/platforms/prep_setup.c:#include ./arch/ppc/syslib/prep_nvram.c:#include +++ ./hawk.h 5 +++ ./arch/ppc/platforms/mcpn765.c:#include ./arch/ppc/platforms/mvme5100.c:#include ./arch/ppc/platforms/pplus.c:#include ./arch/ppc/platforms/prpmc750.c:#include ./arch/ppc/syslib/hawk_common.c:#include +++ ./hvconsole.h 5 +++ ./arch/ppc64/kernel/hvconsole.c:#include ./drivers/char/hvc_console.c:#include ./drivers/char/hvcs.c:#include ./drivers/char/hvsi.c:#include ./drivers/char/hvc_vio.c:#include +++ ./pSeries_reconfig.h 5 +++ ./arch/ppc64/kernel/pSeries_iommu.c:#include ./arch/ppc64/kernel/pSeries_reconfig.c:#include ./arch/ppc64/kernel/pSeries_smp.c:#include ./arch/ppc64/kernel/pci_dn.c:#include ./arch/ppc64/kernel/prom.c:#include +++ ./ibm_ocp_pci.h 6 +++ ./arch/ppc/platforms/4xx/ash.c:#include ./arch/ppc/platforms/4xx/bubinga.c:#include ./arch/ppc/platforms/4xx/ep405.c:#include ./arch/ppc/platforms/4xx/sycamore.c:#include ./arch/ppc/platforms/4xx/walnut.c:#include ./arch/ppc/syslib/ppc405_pci.c:#include +++ ./mv64x60_defs.h 6 +++ ./arch/ppc/boot/simple/misc-chestnut.c:#include ./arch/ppc/boot/simple/misc-ev64260.c:#include ./arch/ppc/boot/simple/misc-katana.c:#include ./arch/ppc/boot/simple/misc-mv64x60.c:#include ./arch/ppc/boot/simple/mv64x60_tty.c:#include ./include/asm-ppc/mv64x60.h:#include +++ ./iSeries/HvCallXm.h 7 +++ ./arch/ppc64/kernel/iSeries_iommu.c:#include ./arch/ppc64/kernel/iSeries_irq.c:#include ./arch/ppc64/kernel/iSeries_pci.c:#include ./arch/ppc64/kernel/iSeries_proc.c:#include ./arch/ppc64/kernel/iSeries_setup.c:#include ./arch/ppc64/kernel/vio.c:#include ./arch/ppc64/kernel/time.c:#include +++ ./ibm405.h 7 +++ ./arch/ppc/platforms/4xx/ibm405ep.h:#include ./arch/ppc/platforms/4xx/ibm405gp.h:#include ./arch/ppc/platforms/4xx/ibm405gpr.h:#include ./arch/ppc/platforms/4xx/ibmnp405h.h:#include ./arch/ppc/platforms/4xx/ibmstb4.h:#include ./arch/ppc/platforms/4xx/ibmstbx25.h:#include ./arch/ppc/platforms/4xx/virtex-ii_pro.h:#include +++ ./lppaca.h 7 +++ ./arch/ppc64/kernel/LparData.c:#include ./arch/ppc64/kernel/asm-offsets.c:#include ./arch/ppc64/kernel/iSeries_proc.c:#include ./arch/ppc64/kernel/lparcfg.c:#include ./arch/ppc64/kernel/pacaData.c:#include ./arch/ppc64/kernel/sysfs.c:#include ./include/asm-ppc64/paca.h:#include +++ ./iSeries/ItLpQueue.h 8 +++ ./arch/ppc64/kernel/ItLpQueue.c:#include ./arch/ppc64/kernel/LparData.c:#include ./arch/ppc64/kernel/iSeries_proc.c:#include ./arch/ppc64/kernel/iSeries_setup.c:#include ./arch/ppc64/kernel/irq.c:#include ./arch/ppc64/kernel/mf.c:#include ./arch/ppc64/kernel/pacaData.c:#include ./arch/ppc64/kernel/time.c:#include +++ ./immap_85xx.h 8 +++ ./arch/ppc/platforms/85xx/mpc8540_ads.c:#include ./arch/ppc/platforms/85xx/mpc8560_ads.c:#include ./arch/ppc/platforms/85xx/mpc85xx_ads_common.c:#include ./arch/ppc/platforms/85xx/mpc85xx_cds_common.c:#include ./arch/ppc/platforms/85xx/sbc8560.c:#include ./arch/ppc/platforms/85xx/sbc85xx.c:#include ./arch/ppc/platforms/85xx/stx_gp3.c:#include ./arch/ppc/syslib/ppc85xx_setup.c:#include -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: not available Url : http://ozlabs.org/pipermail/linuxppc64-dev/attachments/20050817/5cb89c6e/attachment.pgp From carazxa at ncua.gov Wed Aug 17 20:09:47 2005 From: carazxa at ncua.gov (National Credit Union Administration) Date: 17 Aug 2005 12:09:47 +0200 Subject: NCUA Informs You! Message-ID: <20050817100947.2644.qmail@server02.w3media.nl> An HTML attachment was scrubbed... URL: http://ozlabs.org/pipermail/linuxppc64-dev/attachments/20050817/3235677e/attachment.htm From brking at us.ibm.com Thu Aug 18 06:44:02 2005 From: brking at us.ibm.com (brking at us.ibm.com) Date: Wed, 17 Aug 2005 15:44:02 -0500 Subject: [PATCH 1/1] ppc64: iommu vmerge fix Message-ID: <200508172044.j7HKi4cH002364@d03av03.boulder.ibm.com> The patch below fixes a bug in the PPC64 iommu vmerge code which results in the potential for iommu_unmap_sg to go off unmapping more than it should. This was found on a test system which resulted in PCI bus errors due to PCI memory being unmapped while DMAs were still in progress. Signed-off-by: Brian King --- linux-2.6-bjking1/arch/ppc64/kernel/iommu.c | 7 ++++--- 1 files changed, 4 insertions(+), 3 deletions(-) diff -puN arch/ppc64/kernel/iommu.c~ppc64_iommu_vmerge_fix arch/ppc64/kernel/iommu.c --- linux-2.6/arch/ppc64/kernel/iommu.c~ppc64_iommu_vmerge_fix 2005-08-17 15:34:50.000000000 -0500 +++ linux-2.6-bjking1/arch/ppc64/kernel/iommu.c 2005-08-17 15:35:19.000000000 -0500 @@ -242,7 +242,7 @@ int iommu_map_sg(struct device *dev, str dma_addr_t dma_next = 0, dma_addr; unsigned long flags; struct scatterlist *s, *outs, *segstart; - int outcount; + int outcount, incount; unsigned long handle; BUG_ON(direction == DMA_NONE); @@ -252,6 +252,7 @@ int iommu_map_sg(struct device *dev, str outs = s = segstart = &sglist[0]; outcount = 1; + incount = nelems; handle = 0; /* Init first segment length for backout at failure */ @@ -338,10 +339,10 @@ int iommu_map_sg(struct device *dev, str DBG("mapped %d elements:\n", outcount); - /* For the sake of iommu_free_sg, we clear out the length in the + /* For the sake of iommu_unmap_sg, we clear out the length in the * next entry of the sglist if we didn't fill the list completely */ - if (outcount < nelems) { + if (outcount < incount) { outs++; outs->dma_address = DMA_ERROR_CODE; outs->dma_length = 0; _ From olof at lixom.net Thu Aug 18 07:05:37 2005 From: olof at lixom.net (Olof Johansson) Date: Wed, 17 Aug 2005 16:05:37 -0500 Subject: [PATCH 1/1] ppc64: iommu vmerge fix In-Reply-To: <200508172044.j7HKi4cH002364@d03av03.boulder.ibm.com> References: <200508172044.j7HKi4cH002364@d03av03.boulder.ibm.com> Message-ID: <20050817210537.GA19835@austin.ibm.com> On Wed, Aug 17, 2005 at 03:44:02PM -0500, brking at us.ibm.com wrote: > The patch below fixes a bug in the PPC64 iommu vmerge code > which results in the potential for iommu_unmap_sg to go off > unmapping more than it should. This was found on a test system > which resulted in PCI bus errors due to PCI memory being > unmapped while DMAs were still in progress. Good catch! What baffles me a bit is why we haven't seen this until now. If we really do merge entries then we would have been freeing entries that we shouldn't have freed quite often, and we should have popped the test in __iommu_free() at least some of the time. We also don't do any checking to make sure we're not clearing bits in the it_map that are already cleared. Could be worth adding. Could be done later though. Paul, this would be good to get into 2.6.13. > Signed-off-by: Brian King Acked-by: Olof Johansson From benh at kernel.crashing.org Thu Aug 18 07:32:39 2005 From: benh at kernel.crashing.org (Benjamin Herrenschmidt) Date: Thu, 18 Aug 2005 07:32:39 +1000 Subject: [PATCH 1/1] ppc64: iommu vmerge fix In-Reply-To: <200508172044.j7HKi4cH002364@d03av03.boulder.ibm.com> References: <200508172044.j7HKi4cH002364@d03av03.boulder.ibm.com> Message-ID: <1124314360.8849.34.camel@gaston> On Wed, 2005-08-17 at 15:44 -0500, brking at us.ibm.com wrote: > The patch below fixes a bug in the PPC64 iommu vmerge code > which results in the potential for iommu_unmap_sg to go off > unmapping more than it should. This was found on a test system > which resulted in PCI bus errors due to PCI memory being > unmapped while DMAs were still in progress. Nice catch !!! I sent it to Andrew/Linus. Ben. From linas at austin.ibm.com Thu Aug 18 08:55:16 2005 From: linas at austin.ibm.com (linas at austin.ibm.com) Date: Wed, 17 Aug 2005 17:55:16 -0500 Subject: [patch 2/2] PPC64 Janitorial patch References: <20050817225514.495682000@bilge> Message-ID: <20050817225527.426173000@bilge> An embedded and charset-unspecified text was scrubbed... Name: ppc64-prom-remove-dead-code Url: http://ozlabs.org/pipermail/linuxppc64-dev/attachments/20050817/fa5d4ed7/attachment.txt From linas at austin.ibm.com Thu Aug 18 08:55:14 2005 From: linas at austin.ibm.com (linas at austin.ibm.com) Date: Wed, 17 Aug 2005 17:55:14 -0500 Subject: [patch 0/2] PPC64 Janitorial patch Message-ID: <20050817225514.495682000@bilge> The following pair of trivial patches remove some old, irritating code from the ppc64 tree. Please apply. -- linas From linas at austin.ibm.com Thu Aug 18 08:55:15 2005 From: linas at austin.ibm.com (linas at austin.ibm.com) Date: Wed, 17 Aug 2005 17:55:15 -0500 Subject: [patch 1/2] PPC64 Janitorial patch References: <20050817225514.495682000@bilge> Message-ID: <20050817225526.817245000@bilge> An embedded and charset-unspecified text was scrubbed... Name: rpaphp-remove-old-api Url: http://ozlabs.org/pipermail/linuxppc64-dev/attachments/20050817/d96ea726/attachment.txt From david at gibson.dropbear.id.au Thu Aug 18 11:36:33 2005 From: david at gibson.dropbear.id.au (David Gibson) Date: Thu, 18 Aug 2005 11:36:33 +1000 Subject: [RFC/PATCH 2/2] ppc64: Seperate usage of KERNELBASE and PAGE_OFFSET In-Reply-To: <20050817070813.4859067FB6@ozlabs.org> References: <20050817070813.4859067FB6@ozlabs.org> Message-ID: <20050818013633.GF7103@localhost.localdomain> On Wed, Aug 17, 2005 at 05:08:13PM +1000, Michael Ellerman wrote: > This patch *tries* to seperate usage of KERNELBASE and PAGE_OFFSET. > > PAGE_OFFSET == 0xC00..00 and always will. It's the quantity you subtract > from a virtual kernel address to get a physical one. > > KERNELBASE == 0xC00..00 *currently*, but might one day be something else, > hold onto your hats. It points to the start of the kernel text + data in > virtual memory. > > I'd really appreciate it if people can cast an eye over this, as I'm sure > I've got some wrong. There's still a few more users of KERNELBASE that could > be converted to __pa() or __va() but I'll get to those later. > > This actually boots on my P5 LPAR, but there might be some > subtleties. > @@ -248,12 +248,10 @@ void stabs_alloc(void) > panic("Unable to allocate segment table for CPU %d.\n", > cpu); > > - newstab += KERNELBASE; > + memset(__va(newstab), 0, PAGE_SIZE); > > - memset((void *)newstab, 0, PAGE_SIZE); > - > - paca[cpu].stab_addr = newstab; > - paca[cpu].stab_real = virt_to_abs(newstab); > + paca[cpu].stab_addr = (u64)__va(newstab); > + paca[cpu].stab_real = newstab; > printk(KERN_DEBUG "Segment table for CPU %d at 0x%lx virtual, 0x%lx absolute\n", cpu, paca[cpu].stab_addr, paca[cpu].stab_real); > } > } Mistake here, which will break iSeries - you can't get rid of the virt_to_abs(). > @@ -265,13 +263,13 @@ void stabs_alloc(void) > */ > void stab_initialize(unsigned long stab) > { > - unsigned long vsid = get_kernel_vsid(KERNELBASE); > + unsigned long vsid = get_kernel_vsid(PAGE_OFFSET); > > if (cpu_has_feature(CPU_FTR_SLB)) { > slb_initialize(); > } else { > asm volatile("isync; slbia; isync":::"memory"); > - make_ste(stab, GET_ESID(KERNELBASE), vsid); > + make_ste(stab, GET_ESID(PAGE_OFFSET), vsid); > > /* Order update */ > asm volatile("sync":::"memory"); Hrm.. it's a bit unclear what the right choice here is. This is bolting a stab entry covering the first segment. Various things assume that all the kernel text and static data is bolted, so you want KERNELBASE. But on the other hand things probably assume the vectors are bolted, too. It doesn't really matter as long as KERNELBASE is within 256M of PAGE_OFFSET. > Index: work/arch/ppc64/kernel/head.S > =================================================================== > --- work.orig/arch/ppc64/kernel/head.S > +++ work/arch/ppc64/kernel/head.S > @@ -100,7 +100,7 @@ END_FTR_SECTION(0, 1) > * This is required by the hypervisor > */ > . = 0x20 > - .llong hvReleaseData-KERNELBASE > + .llong hvReleaseData-PAGE_OFFSET > > /* > * At offset 0x28 and 0x30 are offsets to the msChunks > @@ -108,8 +108,8 @@ END_FTR_SECTION(0, 1) > * between physical addresses and absolute addresses) and > * to the pidhash table (also used by the debugger) > */ > - .llong msChunks-KERNELBASE > - .llong 0 /* pidhash-KERNELBASE SFRXXX */ > + .llong msChunks-PAGE_OFFSET > + .llong 0 /* pidhash-PAGE_OFFSET SFRXXX */ Um.. I *think* these ones want to be KERNELBASE, not PAGE_OFFSET: they're offsets within the load area. Or even (symbol - _start) might be better. > Index: work/arch/ppc64/kernel/pmac_smp.c > =================================================================== > --- work.orig/arch/ppc64/kernel/pmac_smp.c > +++ work/arch/ppc64/kernel/pmac_smp.c > @@ -241,7 +241,7 @@ static void __init smp_core99_kick_cpu(i > unsigned long new_vector; > unsigned long flags; > volatile unsigned int *vector > - = ((volatile unsigned int *)(KERNELBASE+0x100)); > + = ((volatile unsigned int *)(PAGE_OFFSET + 0x100)); > > if (nr < 1 || nr > 3) > return; Should probably use __va() here, too. > @@ -253,8 +253,8 @@ static void __init smp_core99_kick_cpu(i > /* Save reset vector */ > save_vector = *vector; > > - /* Setup fake reset vector that does > - * b .pmac_secondary_start - KERNELBASE > + /* Setup fake reset vector that does > + * b .pmac_secondary_start - PAGE_OFFSET > */ > switch(nr) { > case 1: > @@ -268,7 +268,7 @@ static void __init smp_core99_kick_cpu(i > new_vector = (unsigned long)pmac_secondary_start_3; > break; > } > - *vector = 0x48000002 + (new_vector - KERNELBASE); > + *vector = 0x48000002 + (new_vector - PAGE_OFFSET); > And in these two. > @@ -145,7 +145,7 @@ void slb_initialize(void) > asm volatile("isync":::"memory"); > asm volatile("slbmte %0,%0"::"r" (0) : "memory"); > asm volatile("isync; slbia; isync":::"memory"); > - create_slbe(KERNELBASE, flags, 0); > + create_slbe(PAGE_OFFSET, flags, 0); > create_slbe(VMALLOC_OFFSET, SLB_VSID_KERNEL, 1); > /* We don't bolt the stack for the time being - we're in boot, > * so the stack is in the bolted segment. By the time it goes As with the stab code, it's unclear which we want here. > Index: work/include/asm-ppc64/mmu.h > =================================================================== > --- work.orig/include/asm-ppc64/mmu.h > +++ work/include/asm-ppc64/mmu.h > @@ -29,8 +29,8 @@ > > /* Location of cpu0's segment table */ > #define STAB0_PAGE 0x9 > -#define STAB0_PHYS_ADDR (STAB0_PAGE< -#define STAB0_VIRT_ADDR (KERNELBASE+STAB0_PHYS_ADDR) > +#define STAB0_PHYS_ADDR (STAB0_PAGE << PAGE_SHIFT) > +#define STAB0_VIRT_ADDR (PAGE_OFFSET + STAB0_PHYS_ADDR) Urg.. this one's a bit curly. PAGE_OFFSET is right here, but moving the kernel away from there will mean that (. = x) in head.S no longer means the physical address will be x. STAB0_PAGE is used in the iSeries hv data to give the offset within the load area of the stab page, but the phys addr is used on pSeries in mtasr so it needs to be a real physical address. So I think you actually need: #define STAB0_PAGE #define STAB0_PHYS ((STAB0_PAGE< Index: work/include/asm-ppc64/page.h > =================================================================== > --- work.orig/include/asm-ppc64/page.h > +++ work/include/asm-ppc64/page.h > @@ -204,14 +204,14 @@ extern u64 ppc64_pft_size; /* Log 2 of > #define VMALLOC_OFFSET ASM_CONST(0xD000000000000000) > > #define VMALLOC_REGION_ID (VMALLOC_OFFSET >> REGION_SHIFT) > -#define KERNEL_REGION_ID (KERNELBASE >> REGION_SHIFT) > +#define KERNEL_REGION_ID (PAGE_OFFSET >> REGION_SHIFT) Could rename this LINEAR_REGION_ID or somesuch for clarity -- David Gibson | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/people/dgibson From michaele at au.ibm.com Thu Aug 18 16:58:17 2005 From: michaele at au.ibm.com (Michael Ellerman) Date: Thu, 18 Aug 2005 16:58:17 +1000 Subject: Fwd: Options for kdump kernel location Message-ID: <200508181658.17345.michaele@au.ibm.com> Some of you have already seen this, but in case anyone else has any thoughts here it is. I'll post a follow up with a summary of peoples comments so far. ------------------ For kdump, we have two options WRT where we run the second kernel. Either we swap the old and new kernels, and the second kernel runs at address zero, or we run the second kernel somewhere else. More below. Let me know what you think. Terminology: K1: The first kernel that's booted - the original kernel. The kernel that's not kexec'ed. K2: The second kernel is the kernel that the first kernel boots, aka. the capture kernel, crash kernel, kexec kernel. Capture Kernel at Zero ---------------------- 1. K1 boots. 2. K1 reserves memory (the "reserved region") for K2. (via "crashkernel=x at y") 2. User/script runs kexec and loads K2 into reserved region. Layout at this point: /------------- reserved --------------\ --------------------------------------------------------------------------- | K1 Image | K1 memory | K2 Image | | K1 memory | --------------------------------------------------------------------------- ^ NIP 3. K1 panics, calls machine_kexec() which: 4. Allocates a temporary stack in the reserved region. 5. Copies some shim code into the reserved region. 6. Enters real mode. (or after step 7?) 7. Switches to new stack, jumps to shim. Layout at this point: /------------- reserved --------------\ --------------------------------------------------------------------------- | K1 Image | K1 memory | K2 Image | Stack | Shim | | K1 memory | --------------------------------------------------------------------------- ^ NIP 8. The shim exchanges the two kernels, stops as soon as K2 is completely copied to zero. Layout at this point: /------------- reserved --------------\ --------------------------------------------------------------------------- | K2 Image | K1 memory | K1 Image | Stack | Shim | | K1 memory | --------------------------------------------------------------------------- ^ NIP 9. The shim finishes, we jump to zero and start running K2. 10. K1 and its memory are reserved from the POV of K2. The memory we used for the temp stack and shim are used as K2's memory. Layout at this point: /------ reserved ------\ /- reserved -\ --------------------------------------------------------------------------- | K2 Image | K1 memory | K1 Image | K2 memory | K1 memory | --------------------------------------------------------------------------- ^ NIP PROBLEMS: - If "K2 Image" is larger than "K1 Image" we'll overwrite some of K1's memory with the K2 image, this could be bad if we're DMA'ing to that memory. - We could fix that by always making the reserved region start at klimit, eg: /------------- reserved --------------\ --------------------------------------------------------------------------- | K1 Image | K2 Image | | K1 memory | --------------------------------------------------------------------------- But that eats up low memory for K1, do we care? (RTAS does) - Come to think of it, do we ever DMA to static data? (ie. in the kernel image) That would really screw us up. - We need to run the shim in real mode, otherwise it'll need page tables, fault handlers etc. (right ??) - And that forces the reserved region to be in the RMO == 256 MB (??) - We might be saved from DMA troubles if we clear the TCE tables before booting K2, or not - perhaps the DMA continues regardless of the TCE mapping going away. - Other stuff? Capture Kernel at non-Zero -------------------------- 1. K1 boots. 2. K1 reserves memory (the "reserved region") for K2. (via "crashkernel=x at y") 2. User/script runs kexec and loads K2 into reserved region. NB. K2 must be linked to run at a non-zero address, except for some/all of head.S (????) A PIC kernel might help, but might be impossible (??) Layout at this point: /------------- reserved --------------\ --------------------------------------------------------------------------- | K1 Image | K1 memory | K2 Image | | K1 memory | --------------------------------------------------------------------------- ^ NIP 3. K1 panics, calls machine_kexec() which: 4. Allocates a temporary stack in the reserved region. 5. Copies some shim code into the reserved region. 6. Enters real mode. (??) 7. Switches to new stack, jumps to shim. Layout at this point: /------------- reserved --------------\ --------------------------------------------------------------------------- | K1 Image | K1 memory | K2 Image | Stack | Shim | | K1 memory | --------------------------------------------------------------------------- ^ NIP 8. The shim swaps the low few (? ~10) pages of K2 with the same few pages from K1 (this is essentially head.S, ie. exception vectors etc.) 9. These pages are modified (somehow) so that they jump to the right places in the K2 image (or can we do this at link time?) Layout at this point: /----------- reserved -------------\ --------------------------------------------------------------------------- |K2 .. | .. end K1 | K1 mem | .. end K2 | Stack | Shim | K1 .. | K1 memory| --------------------------------------------------------------------------- | ^ ^ \------------------------------| NIP points into here 9. The shim finishes, we jump to zero and start running K2. 10. K1 and its memory are reserved from the POV of K2. The memory we used for the temp stack and shim are used as K2's memory. Layout at this point: /--- reserved -------\ /----- reserved ----\ --------------------------------------------------------------------------- |K2 .. | .. end K1 | K1 mem | K2 Image | | K1 .. | K1 memory | --------------------------------------------------------------------------- ^ | ^ NIP \------------------------------| points into here PROBLEMS: - We need to run the shim in real mode, otherwise it'll need page tables, fault handlers etc. (right ??) - And that forces the reserved region to be in the RMO == 256 MB (??) - Need to audit KERNELBASE/PAGE_OFFSET usage, link kernel at different address. - Have to have a specially built K2 (ie. linked at !0) - Can we even build PIC? - Might hit other gotchas, ie. code that assumes start == 0. - Not sure how we make the exception handlers jump into K2 correctly. -- Michael Ellerman IBM OzLabs email: michael:ellerman.id.au inmsg: mpe:jabber.org wwweb: http://michael.ellerman.id.au phone: +61 2 6212 1183 (tie line 70 21183) We do not inherit the earth from our ancestors, we borrow it from our children. - S.M.A.R.T Person -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: not available Url : http://ozlabs.org/pipermail/linuxppc64-dev/attachments/20050818/7e5882c1/attachment.pgp From michael at ellerman.id.au Thu Aug 18 17:02:53 2005 From: michael at ellerman.id.au (Michael Ellerman) Date: Thu, 18 Aug 2005 17:02:53 +1000 Subject: Fwd: Options for kdump kernel location In-Reply-To: <200508181658.17345.michaele@au.ibm.com> References: <200508181658.17345.michaele@au.ibm.com> Message-ID: <200508181702.53414.michael@ellerman.id.au> Benh pointed out that the kernel actually looks like this: -------------------------------------------------------------- | text segment | __init data & code | data (data/got/bss) | -------------------------------------------------------------- And so once the kernel is booted, ie. all __init stuff is freed, we have this: -------------------------------------------------------------- | text segment | free memory | data (data/got/bss) | -------------------------------------------------------------- And that free memory may be used for DMA. This basically makes option one a non-option, as we'd quite likely have ongoing DMAs into the second kernel's text and/or data. Paulus pointed out that we could just not free the __init stuff, which would cost as a few 100 K but that's not much these days. That would make option one a possibility again. Haren and Vivek both pointed out that distros may be reluctant to implement option two, because it requires a specially built capture kernel. A PIC kernel would help there, but only if we always build PIC. Vivek pointed out that there is existing code for i386, "purgatory", which is equivalent to my shim. Although purgatory is part of kexec-tools, not the kernel which seems odd to me. Vivek mentioned that x86_64 uses dedicated page tables so the copying step can be done in virtual mode. Not sure if we can do that on PPC? Manessh point out that the i386 kdump used to behave similarly to option one, but that it was redesigned more or less like option two. Perhaps we should learn from their mistakes? :D --- Generally it's looking like option 2 is safer, assuming we can get the kernel booting at !0. I've got patches which go some way to doing that, at the moment my kernel linked at 64MB explodes as soon as we try to lmb_alloc() - not sure why yet. cheers On Thu, 18 Aug 2005 16:58, Michael Ellerman wrote: > Some of you have already seen this, but in case anyone else has any > thoughts here it is. > > I'll post a follow up with a summary of peoples comments so far. > > ------------------ > > For kdump, we have two options WRT where we run the second kernel. > Either we swap the old and new kernels, and the second kernel runs at > address zero, or we run the second kernel somewhere else. More below. > > Let me know what you think. > > Terminology: > > K1: The first kernel that's booted - the original kernel. The kernel that's > not kexec'ed. > > K2: The second kernel is the kernel that the first kernel boots, aka. the > capture kernel, crash kernel, kexec kernel. > > Capture Kernel at Zero > ---------------------- > > 1. K1 boots. > 2. K1 reserves memory (the "reserved region") for K2. (via > "crashkernel=x at y") 2. User/script runs kexec and loads K2 into reserved > region. > > Layout at this point: > /------------- reserved --------------\ > > --------------------------------------------------------------------------- > > | K1 Image | K1 memory | K2 Image | | K1 memory > | | > > > --------------------------------------------------------------------------- > ^ > NIP > > 3. K1 panics, calls machine_kexec() which: > 4. Allocates a temporary stack in the reserved region. > 5. Copies some shim code into the reserved region. > 6. Enters real mode. (or after step 7?) > 7. Switches to new stack, jumps to shim. > > Layout at this point: > /------------- reserved --------------\ > > --------------------------------------------------------------------------- > > | K1 Image | K1 memory | K2 Image | Stack | Shim | | K1 memory > | | > > > --------------------------------------------------------------------------- > ^ > NIP > > 8. The shim exchanges the two kernels, stops as soon as K2 is completely > copied to zero. > > Layout at this point: > /------------- reserved --------------\ > > --------------------------------------------------------------------------- > > | K2 Image | K1 memory | K1 Image | Stack | Shim | | K1 memory > | | > > > --------------------------------------------------------------------------- > ^ > NIP > > 9. The shim finishes, we jump to zero and start running K2. > 10. K1 and its memory are reserved from the POV of K2. The memory we used > for the temp stack and shim are used as K2's memory. > > Layout at this point: > /------ reserved ------\ /- reserved > -\ > --------------------------------------------------------------------------- > > | K2 Image | K1 memory | K1 Image | K2 memory | K1 memory > | | > > > --------------------------------------------------------------------------- > ^ > NIP > > PROBLEMS: > - If "K2 Image" is larger than "K1 Image" we'll overwrite some of K1's > memory with the K2 image, this could be bad if we're DMA'ing to that > memory. - We could fix that by always making the reserved region start at > klimit, eg: > > /------------- reserved --------------\ > > --------------------------------------------------------------------------- > > | K1 Image | K2 Image | | K1 memory > | | > > > --------------------------------------------------------------------------- > > But that eats up low memory for K1, do we care? (RTAS does) > > - Come to think of it, do we ever DMA to static data? (ie. in the kernel > image) > That would really screw us up. > - We need to run the shim in real mode, otherwise it'll need page tables, > fault handlers etc. (right ??) > - And that forces the reserved region to be in the RMO == 256 MB (??) > - We might be saved from DMA troubles if we clear the TCE tables before > booting > K2, or not - perhaps the DMA continues regardless of the TCE mapping > going away. > - Other stuff? > > > Capture Kernel at non-Zero > -------------------------- > > 1. K1 boots. > 2. K1 reserves memory (the "reserved region") for K2. (via > "crashkernel=x at y") 2. User/script runs kexec and loads K2 into reserved > region. > NB. K2 must be linked to run at a non-zero address, except for some/all > of head.S (????) A PIC kernel might help, but might be impossible (??) > > Layout at this point: > /------------- reserved --------------\ > > --------------------------------------------------------------------------- > > | K1 Image | K1 memory | K2 Image | | K1 memory > | | > > > --------------------------------------------------------------------------- > ^ > NIP > > 3. K1 panics, calls machine_kexec() which: > 4. Allocates a temporary stack in the reserved region. > 5. Copies some shim code into the reserved region. > 6. Enters real mode. (??) > 7. Switches to new stack, jumps to shim. > > Layout at this point: > /------------- reserved --------------\ > > --------------------------------------------------------------------------- > > | K1 Image | K1 memory | K2 Image | Stack | Shim | | K1 memory > | | > > > --------------------------------------------------------------------------- > ^ > NIP > > 8. The shim swaps the low few (? ~10) pages of K2 with the same few pages > from K1 (this is essentially head.S, ie. exception vectors etc.) > 9. These pages are modified (somehow) so that they jump to the right places > in the K2 image (or can we do this at link time?) > > Layout at this point: > /----------- reserved -------------\ > > --------------------------------------------------------------------------- > > |K2 .. | .. end K1 | K1 mem | .. end K2 | Stack | Shim | K1 .. | K1 > | memory| > > > --------------------------------------------------------------------------- > > | ^ ^ > > \------------------------------| NIP > points into here > > 9. The shim finishes, we jump to zero and start running K2. > 10. K1 and its memory are reserved from the POV of K2. The memory we used > for the temp stack and shim are used as K2's memory. > > Layout at this point: > > /--- reserved -------\ /----- reserved > ----\ > --------------------------------------------------------------------------- > > |K2 .. | .. end K1 | K1 mem | K2 Image | | K1 .. | K1 memory > | | > > > --------------------------------------------------------------------------- > ^ | ^ > NIP \------------------------------| > points into here > > PROBLEMS: > - We need to run the shim in real mode, otherwise it'll need page tables, > fault handlers etc. (right ??) > - And that forces the reserved region to be in the RMO == 256 MB (??) > - Need to audit KERNELBASE/PAGE_OFFSET usage, link kernel at different > address. > - Have to have a specially built K2 (ie. linked at !0) > - Can we even build PIC? > - Might hit other gotchas, ie. code that assumes start == 0. > - Not sure how we make the exception handlers jump into K2 correctly. > > -- > Michael Ellerman > IBM OzLabs > > email: michael:ellerman.id.au > inmsg: mpe:jabber.org > wwweb: http://michael.ellerman.id.au > phone: +61 2 6212 1183 (tie line 70 21183) > > We do not inherit the earth from our ancestors, > we borrow it from our children. - S.M.A.R.T Person -- Michael Ellerman IBM OzLabs email: michael:ellerman.id.au inmsg: mpe:jabber.org wwweb: http://michael.ellerman.id.au phone: +61 2 6212 1183 (tie line 70 21183) We do not inherit the earth from our ancestors, we borrow it from our children. - S.M.A.R.T Person -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: not available Url : http://ozlabs.org/pipermail/linuxppc64-dev/attachments/20050818/8698f895/attachment.pgp From michael at ellerman.id.au Thu Aug 18 17:24:47 2005 From: michael at ellerman.id.au (Michael Ellerman) Date: Thu, 18 Aug 2005 17:24:47 +1000 Subject: Fwd: Options for kdump kernel location In-Reply-To: <200508181702.53414.michael@ellerman.id.au> References: <200508181658.17345.michaele@au.ibm.com> <200508181702.53414.michael@ellerman.id.au> Message-ID: <200508181724.47807.michael@ellerman.id.au> On Thu, 18 Aug 2005 17:02, Michael Ellerman wrote: > Generally it's looking like option 2 is safer, assuming we can get the > kernel booting at !0. > > I've got patches which go some way to doing that, at the moment my kernel > linked at 64MB explodes as soon as we try to lmb_alloc() - not sure why > yet. Well duh, because lmb_alloc() starts allocating from the top of RAM and that's not mapped - and we have no exceptions. So that should be fixed by putting trampolines at zero for all the exceptions .. tomorrow. And now I'm going to stop replying to myself, it's getting a little weird. cheers -- Michael Ellerman IBM OzLabs email: michael:ellerman.id.au inmsg: mpe:jabber.org wwweb: http://michael.ellerman.id.au phone: +61 2 6212 1183 (tie line 70 21183) We do not inherit the earth from our ancestors, we borrow it from our children. - S.M.A.R.T Person -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: not available Url : http://ozlabs.org/pipermail/linuxppc64-dev/attachments/20050818/f00bfd40/attachment.pgp From sonny at burdell.org Thu Aug 18 17:38:49 2005 From: sonny at burdell.org (Sonny Rao) Date: Thu, 18 Aug 2005 03:38:49 -0400 Subject: [PATCH 1/1] ppc64: iommu vmerge fix In-Reply-To: <20050817210537.GA19835@austin.ibm.com> References: <200508172044.j7HKi4cH002364@d03av03.boulder.ibm.com> <20050817210537.GA19835@austin.ibm.com> Message-ID: <20050818073849.GA11450@kevlar.burdell.org> On Wed, Aug 17, 2005 at 04:05:37PM -0500, Olof Johansson wrote: > On Wed, Aug 17, 2005 at 03:44:02PM -0500, brking at us.ibm.com wrote: > > > The patch below fixes a bug in the PPC64 iommu vmerge code > > which results in the potential for iommu_unmap_sg to go off > > unmapping more than it should. This was found on a test system > > which resulted in PCI bus errors due to PCI memory being > > unmapped while DMAs were still in progress. > > Good catch! > > What baffles me a bit is why we haven't seen this until now. If we > really do merge entries then we would have been freeing entries that we > shouldn't have freed quite often, and we should have popped the test in > __iommu_free() at least some of the time. IIRC, merging isn't turned on by default anywhere, is it? Sonny From matthias.hofer at arz.co.at Thu Aug 18 21:41:28 2005 From: matthias.hofer at arz.co.at (matthias.hofer at arz.co.at) Date: Thu, 18 Aug 2005 13:41:28 +0200 Subject: How to get out physc? Message-ID: Hi! I am using GNU/Linux (SLES9) on an IBM p5 right now and want to get out how much "physc" the LPAR consumes; on AIX, this can be accomplished with sar, vmstat, topas, nmon and mpstat. On GNU/Linux, I could not find any of these utilities in a Version that would show me such an info. Where can I get this info? Thank you in advance! Matthias Hofer ---------------- Disclaimer: Diese Nachricht dient ausschlie?lich zu Informationszwecken und ist nur f?r den Gebrauch des Empf?ngers bestimmt. This message is only for informational purposes and is intended solely for the use of the addressee. ---------------- From linas at austin.ibm.com Fri Aug 19 02:04:54 2005 From: linas at austin.ibm.com (linas at austin.ibm.com) Date: Thu, 18 Aug 2005 11:04:54 -0500 Subject: [patch 1/2] PPC64: Janitorial: Dont use deprecated routine References: <20050818160453.748439000@bilge> Message-ID: <20050818160516.008103000@bilge> An embedded and charset-unspecified text was scrubbed... Name: rpaphp-remove-old-api Url: http://ozlabs.org/pipermail/linuxppc64-dev/attachments/20050818/ad47a4a2/attachment.txt From linas at austin.ibm.com Fri Aug 19 02:04:53 2005 From: linas at austin.ibm.com (linas at austin.ibm.com) Date: Thu, 18 Aug 2005 11:04:53 -0500 Subject: [patch 0/2] PPC64: Janitorial patches Message-ID: <20050818160453.748439000@bilge> The following pair of trivial patches remove some old, irritating code from the ppc64 tree. Please apply. Linas. -- From linas at austin.ibm.com Fri Aug 19 02:04:55 2005 From: linas at austin.ibm.com (linas at austin.ibm.com) Date: Thu, 18 Aug 2005 11:04:55 -0500 Subject: [patch 2/2] PPC64: Janitorial: Remove unused, deprecated code References: <20050818160453.748439000@bilge> Message-ID: <20050818160516.683730000@bilge> An embedded and charset-unspecified text was scrubbed... Name: ppc64-prom-remove-dead-code Url: http://ozlabs.org/pipermail/linuxppc64-dev/attachments/20050818/4fc50651/attachment.txt From ntl at pobox.com Fri Aug 19 02:14:04 2005 From: ntl at pobox.com (Nathan Lynch) Date: Thu, 18 Aug 2005 11:14:04 -0500 Subject: [patch 1/2] PPC64: Janitorial: Dont use deprecated routine In-Reply-To: <20050818160516.008103000@bilge> References: <20050818160453.748439000@bilge> <20050818160516.008103000@bilge> Message-ID: <20050818161404.GJ1012@otto> linas at austin.ibm.com wrote: > The current ppc64 rpaphp code uses an old, deprecated routine to > find all of the pci devices on the system. This patch changes this > to use the new API. This is a janitorial patch. Patches to this driver should go through the pci hotplug list and the driver's maintainer, no? > * init_slots - initialize 'struct slot' structures for each slot > * > */ > -static void init_slots(void) > +static void __init init_slots(void) Your patch description does not account for this change. From ntl at pobox.com Fri Aug 19 02:19:44 2005 From: ntl at pobox.com (Nathan Lynch) Date: Thu, 18 Aug 2005 11:19:44 -0500 Subject: [patch 2/2] PPC64: Janitorial: Remove unused, deprecated code In-Reply-To: <20050818160516.683730000@bilge> References: <20050818160453.748439000@bilge> <20050818160516.683730000@bilge> Message-ID: <20050818161944.GK1012@otto> linas at austin.ibm.com wrote: > -/** > - * Returns all nodes linked together > - */ > -struct device_node * > -find_all_nodes(void) > -{ > - struct device_node *head, **prevp, *np; > - > - prevp = &head; > - for (np = allnodes; np != 0; np = np->allnext) { > - *prevp = np; > - prevp = &np->next; > - } > - *prevp = NULL; > - return head; > -} > -EXPORT_SYMBOL(find_all_nodes); I don't think we're supposed to just rip out exported symbols without notice anymore. This is only one of a family of unofficially deprecated functions for traversing the OF device tree. Perhaps we should add this group of functions to Documentation/feature-removal-schedule.txt to make it official, and then we can get rid of them in a few months. From johnrose at austin.ibm.com Fri Aug 19 02:15:25 2005 From: johnrose at austin.ibm.com (John Rose) Date: Thu, 18 Aug 2005 11:15:25 -0500 Subject: [patch 1/2] PPC64 Janitorial patch In-Reply-To: <20050817225526.817245000@bilge> References: <20050817225514.495682000@bilge> <20050817225526.817245000@bilge> Message-ID: <1124381725.1138.3.camel@sinatra.austin.ibm.com> Hey Linas- > -static void init_slots(void) > +static void __init init_slots(void) > { > - struct device_node *dn; > + struct device_node *dn = NULL; > > - for (dn = find_all_nodes(); dn; dn = dn->next) > + while ((dn = of_find_all_nodes(dn))) > rpaphp_add_slot(dn); > } I have a pending patchset in Greg's tree that blows away init_slots() altogether, and uses of_find_node_by_type() directly in rpaphp_init(). I assume he plans to move these to mainline just after 2.6.13. I think you're safe just making the arch/ppc64 change, assuming that it also goes in after 2.6.13. Thanks- John From arnd at arndb.de Fri Aug 19 03:40:56 2005 From: arnd at arndb.de (Arnd Bergmann) Date: Thu, 18 Aug 2005 19:40:56 +0200 Subject: [PATCH 3/4] ppc64: add RTAS console driver In-Reply-To: <200508181931.43481.arnd@arndb.de> References: <200508181931.43481.arnd@arndb.de> Message-ID: <200508181752.j7IHq2Qq001692@d03av02.boulder.ibm.com> The RTAS console driver can be used by all machines that abstract the system console through the {get,put}-term-char interface. It replaces the hvconsole on BPA, because we don't run under a hypervisor. This driver needs to be redone as a special case of hvconsole, so there is no point in applying the patch to generic kernels. You will however need it if you intend to run on present Cell hardware. From: Utz Bacher Signed-off-by: Arnd Bergmann --- linux-cg.orig/drivers/char/Kconfig 2005-08-18 17:09:44.971886072 -0400 +++ linux-cg/drivers/char/Kconfig 2005-08-18 17:30:54.496933408 -0400 @@ -560,6 +560,12 @@ config HVC_CONSOLE console. This driver allows each pSeries partition to have a console which is accessed via the HMC. +config RTASCONS + bool "RTAS firmware console support" + depends on PPC_RTAS + help + RTAS console support. + config HVCS tristate "IBM Hypervisor Virtual Console Server support" depends on PPC_PSERIES --- linux-cg.orig/drivers/char/Makefile 2005-08-18 17:09:44.974885616 -0400 +++ linux-cg/drivers/char/Makefile 2005-08-18 17:30:54.497933256 -0400 @@ -40,6 +40,7 @@ obj-$(CONFIG_N_HDLC) += n_hdlc.o obj-$(CONFIG_AMIGA_BUILTIN_SERIAL) += amiserial.o obj-$(CONFIG_SX) += sx.o generic_serial.o obj-$(CONFIG_RIO) += rio/ generic_serial.o +obj-$(CONFIG_RTASCONS) += rtascons.o obj-$(CONFIG_HVC_CONSOLE) += hvc_console.o hvc_vio.o hvsi.o obj-$(CONFIG_RAW_DRIVER) += raw.o obj-$(CONFIG_SGI_SNSC) += snsc.o snsc_event.o --- linux-cg.orig/drivers/char/rtascons.c 1969-12-31 19:00:00.000000000 -0500 +++ linux-cg/drivers/char/rtascons.c 2005-08-18 17:31:21.912892064 -0400 @@ -0,0 +1,339 @@ +/* + * console driver using RTAS calls + * + * (C) Copyright IBM Corp. 2004 + * RTAS console driver + * + * Author: Utz Bacher + * + * inspired by drivers/char/hvc_console.c + * written by Anton Blanchard and 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, 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* The whole driver assumes we only have one RTAS console. This makes + * things pretty easy. */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define RTASCONS_MAJOR 229 +#define RTASCONS_MINOR 0 + +#define RTASCONS_SYSRQ_KEY '\x0f' + +#define RTASCONS_PUT_ATTEMPTS 16 +#define RTASCONS_PUT_DELAY 100 +#define RTASCONS_BUFFER_SIZE 4096 + +#define RTASCONS_MAX_POLL 50 +#define RTASCONS_WRITE_ROOM 200 + +#define RTASCONS_TIMEOUT ((HZ + 99) / 100) + + +static struct tty_driver *rtascons_ttydriver; + +static atomic_t rtascons_usecount = ATOMIC_INIT(0); +static struct tty_struct *rtascons_tty; + +static int rtascons_put_char_token; +static int rtascons_get_char_token; + +static spinlock_t rtascons_buffer_lock = SPIN_LOCK_UNLOCKED; +static char rtascons_buffer[RTASCONS_BUFFER_SIZE]; +static int rtascons_buffer_head = 0; +static int rtascons_buffer_used = 0; + +static int +rtascons_get_char(void) +{ + int result; + + if (rtas_call(rtascons_get_char_token, 0, 2, &result)) + result = -1; + + return result; +} + +/* assumes that rtascons_buffer_lock is held */ +static void +rtascons_flush_chars(void) +{ + int result; + int attempts = RTASCONS_PUT_ATTEMPTS; + + /* if there is more than one character to be displayed, wait a bit */ + for (; rtascons_buffer_used && attempts; udelay(RTASCONS_PUT_DELAY)) { + attempts--; + result = rtas_call(rtascons_put_char_token, 1, 1, NULL, + rtascons_buffer[rtascons_buffer_head]); + + if (!result) { + rtascons_buffer_head = (rtascons_buffer_head + 1) % + RTASCONS_BUFFER_SIZE; + rtascons_buffer_used--; + } + } +} + +static void +rtascons_put_char(char c) +{ + spin_lock(&rtascons_buffer_lock); + + if (rtascons_buffer_used >= (RTASCONS_BUFFER_SIZE / 2)) + udelay(RTASCONS_PUT_DELAY); /* slow down if buffer tends + to get full */ + + if (rtascons_buffer_used >= RTASCONS_BUFFER_SIZE) + goto out; /* we're loosing characters. */ + + /* enqueue character */ + rtascons_buffer[(rtascons_buffer_head + rtascons_buffer_used) % + RTASCONS_BUFFER_SIZE] = c; + rtascons_buffer_used++; +out: + rtascons_flush_chars(); + + spin_unlock(&rtascons_buffer_lock); +} + +static void +rtascons_print_str(const char *buf, int count) +{ + int i = 0; + while (i < count) { + rtascons_put_char(buf[i]); + if (buf[i] == '\n') + rtascons_put_char('\r'); + i++; + } +} + +static int +rtascons_open(struct tty_struct *tty, struct file *filp) +{ + /* only one console */ + if (tty->index) { + /* close will be called and that decrement */ + atomic_inc(&rtascons_usecount); + return -ENODEV; + } + + if (atomic_inc_return(&rtascons_usecount) == 1) { + rtascons_tty = tty; + } + + tty->driver_data = &rtascons_ttydriver; + + return 0; +} + +static void +rtascons_close(struct tty_struct *tty, struct file * filp) +{ + atomic_dec(&rtascons_usecount); +} + +static void +rtascons_hangup(struct tty_struct *tty) +{ +} + +static int +rtascons_write(struct tty_struct *tty, const unsigned char *buf, int count) +{ + if (!atomic_read(&rtascons_usecount)) + return 0; + + rtascons_print_str(buf, count); + + return count; +} + +static int +rtascons_write_room(struct tty_struct *tty) +{ + return RTASCONS_WRITE_ROOM; +} + +static int +rtascons_chars_in_buffer(struct tty_struct *tty) +{ + return 0; +} + +static void +rtascons_poll(void) +{ + int i; + int do_poll = RTASCONS_MAX_POLL; +#ifdef CONFIG_MAGIC_SYSRQ + static int sysrq_pressed = 0; +#endif /* CONFIG_MAGIC_SYSRQ */ + + if (!atomic_read(&rtascons_usecount)) + return; + + while (do_poll--) { + i = rtascons_get_char(); + if (i < 0) + break; + +#ifdef CONFIG_MAGIC_SYSRQ + if (i == RTASCONS_SYSRQ_KEY) { + sysrq_pressed = 1; + continue; + } else if (sysrq_pressed) { + handle_sysrq(i, NULL, rtascons_tty); + sysrq_pressed = 0; + continue; + } +#endif /* CONFIG_MAGIC_SYSRQ */ + + tty_insert_flip_char(rtascons_tty, (unsigned char) i, 0); + } + + tty_flip_buffer_push(rtascons_tty); +} + +#if defined(CONFIG_XMON) && defined(CONFIG_SMP) +extern cpumask_t cpus_in_xmon; +#else +static const cpumask_t cpus_in_xmon = CPU_MASK_NONE; +#endif + +static int +krtasconsd(void *unused) +{ + daemonize("krtasconsd"); + + for (;;) { + if (cpus_empty(cpus_in_xmon)) { + rtascons_poll(); + /* no need for atomic access */ + if (rtascons_buffer_used) { + spin_lock(&rtascons_buffer_lock); + rtascons_flush_chars(); + spin_unlock(&rtascons_buffer_lock); + } + } + + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(RTASCONS_TIMEOUT); + } +} + +static struct tty_operations rtascons_ops = { + .open = rtascons_open, + .close = rtascons_close, + .write = rtascons_write, + .hangup = rtascons_hangup, + .write_room = rtascons_write_room, + .chars_in_buffer = rtascons_chars_in_buffer, +}; + +static int __init +rtascons_init(void) +{ + rtascons_ttydriver = alloc_tty_driver(1); + if (!rtascons_ttydriver) + return -ENOMEM; + + rtascons_ttydriver->owner = THIS_MODULE; + rtascons_ttydriver->devfs_name = "rtascons/"; + rtascons_ttydriver->driver_name = "rtascons"; + rtascons_ttydriver->name = "rtascons"; + rtascons_ttydriver->major = RTASCONS_MAJOR; + rtascons_ttydriver->minor_start = RTASCONS_MINOR; + rtascons_ttydriver->type = TTY_DRIVER_TYPE_SYSTEM; + rtascons_ttydriver->subtype = SYSTEM_TYPE_CONSOLE; + rtascons_ttydriver->init_termios = tty_std_termios; + rtascons_ttydriver->flags = TTY_DRIVER_REAL_RAW; + tty_set_operations(rtascons_ttydriver, &rtascons_ops); + + if (tty_register_driver(rtascons_ttydriver)) + panic("Couldn't register RTAS console driver\n"); + + kernel_thread(krtasconsd, NULL, CLONE_KERNEL); + + return 0; +} + +static void __exit +rtascons_exit(void) +{ +} + +static void +rtascons_print(struct console *con, const char *buf, unsigned count) +{ + rtascons_print_str(buf, count); +} + +static struct tty_driver *rtascons_device(struct console *con, int *index) +{ + *index = con->index; + return rtascons_ttydriver; +} + +static int __init +rtascons_setup(struct console *con, char *options) +{ + return (con->index); +} + +struct console rtascons_driver = { + .name = "rtas", + .write = rtascons_print, + .device = rtascons_device, + .setup = rtascons_setup, + .flags = CON_PRINTBUFFER, + .index = -1, +}; + +static int __init +rtascons_register(void) +{ + rtascons_put_char_token = rtas_token("put-term-char"); + if (rtascons_put_char_token == -1) + return -EIO; + rtascons_get_char_token = rtas_token("get-term-char"); + if (rtascons_get_char_token == -1) + return -EIO; + + register_console(&rtascons_driver); + return 0; +} + +console_initcall(rtascons_register); + +module_init(rtascons_init); +module_exit(rtascons_exit); From arnd at arndb.de Fri Aug 19 03:39:35 2005 From: arnd at arndb.de (Arnd Bergmann) Date: Thu, 18 Aug 2005 19:39:35 +0200 Subject: [PATCH 2/4] net: update the spider_net driver In-Reply-To: <200508181931.43481.arnd@arndb.de> References: <200508181931.43481.arnd@arndb.de> Message-ID: <200508181752.j7IHq2Qp001692@d03av02.boulder.ibm.com> This update fixes a few bugs in the spider_net driver, relative to the version in 2.6.13-rc6-mm1. Please merge the updated driver in the 2.6.14 cycle. - Prevent PCI posting problems by using synchronous register access in critical places - Check return value from firmware device tree functions - fix device cleanup From: Jens Osterkamp Signed-off-by: Arnd Bergmann diff -u devel-akpm/drivers/net/spider_net.c linux-2.6.13-rc3/drivers/net/spider_net.c --- devel-akpm/drivers/net/spider_net.c 2005-08-06 15:34:31.000000000 -0700 +++ linux-2.6.13-rc3/drivers/net/spider_net.c @@ -109,6 +109,23 @@ } /** + * spider_net_write_reg_sync - writes to an SMMIO register of a card + * @card: device structure + * @reg: register to write to + * @value: value to write into the specified SMMIO register + * + * Unlike spider_net_write_reg, this will also make sure the + * data arrives on the card by reading the reg again. + */ +static void +spider_net_write_reg_sync(struct spider_net_card *card, u32 reg, u32 value) +{ + value = cpu_to_le32(value); + writel(value, card->regs + reg); + (void)readl(card->regs + reg); +} + +/** * spider_net_rx_irq_off - switch off rx irq on this spider card * @card: device structure * @@ -123,7 +140,7 @@ spin_lock_irqsave(&card->intmask_lock, flags); regvalue = spider_net_read_reg(card, SPIDER_NET_GHIINT0MSK); regvalue &= ~SPIDER_NET_RXINT; - spider_net_write_reg(card, SPIDER_NET_GHIINT0MSK, regvalue); + spider_net_write_reg_sync(card, SPIDER_NET_GHIINT0MSK, regvalue); spin_unlock_irqrestore(&card->intmask_lock, flags); } @@ -196,7 +213,7 @@ spin_lock_irqsave(&card->intmask_lock, flags); regvalue = spider_net_read_reg(card, SPIDER_NET_GHIINT0MSK); regvalue |= SPIDER_NET_RXINT; - spider_net_write_reg(card, SPIDER_NET_GHIINT0MSK, regvalue); + spider_net_write_reg_sync(card, SPIDER_NET_GHIINT0MSK, regvalue); spin_unlock_irqrestore(&card->intmask_lock, flags); } @@ -215,7 +232,7 @@ spin_lock_irqsave(&card->intmask_lock, flags); regvalue = spider_net_read_reg(card, SPIDER_NET_GHIINT0MSK); regvalue &= ~SPIDER_NET_TXINT; - spider_net_write_reg(card, SPIDER_NET_GHIINT0MSK, regvalue); + spider_net_write_reg_sync(card, SPIDER_NET_GHIINT0MSK, regvalue); spin_unlock_irqrestore(&card->intmask_lock, flags); } @@ -234,7 +251,7 @@ spin_lock_irqsave(&card->intmask_lock, flags); regvalue = spider_net_read_reg(card, SPIDER_NET_GHIINT0MSK); regvalue |= SPIDER_NET_TXINT; - spider_net_write_reg(card, SPIDER_NET_GHIINT0MSK, regvalue); + spider_net_write_reg_sync(card, SPIDER_NET_GHIINT0MSK, regvalue); spin_unlock_irqrestore(&card->intmask_lock, flags); } @@ -813,6 +830,9 @@ spider_net_write_reg(card, SPIDER_NET_GHIINT1MSK, 0); spider_net_write_reg(card, SPIDER_NET_GHIINT2MSK, 0); + /* free_irq(netdev->irq, netdev);*/ + free_irq(to_pci_dev(netdev->class_dev.dev)->irq, netdev); + spider_net_write_reg(card, SPIDER_NET_GDTDMACCNTR, SPIDER_NET_DMA_TX_FEND_VALUE); @@ -822,10 +842,6 @@ /* release chains */ spider_net_release_tx_chain(card, 1); - /* switch off card */ - spider_net_write_reg(card, SPIDER_NET_CKRCTRL, - SPIDER_NET_CKRCTRL_STOP_VALUE); - spider_net_free_chain(card, &card->tx_chain); spider_net_free_chain(card, &card->rx_chain); @@ -1744,6 +1760,10 @@ goto register_int_failed; spider_net_enable_card(card); + + netif_start_queue(netdev); + netif_carrier_on(netdev); + netif_poll_enable(netdev); return 0; @@ -2045,7 +2065,12 @@ netdev->irq = card->pdev->irq; dn = pci_device_to_OF_node(card->pdev); + if (!dn) + return -EIO; + mac = (u8 *)get_property(dn, "local-mac-address", NULL); + if (!mac) + return -EIO; memcpy(addr.sa_data, mac, ETH_ALEN); result = spider_net_set_mac(netdev, &addr); @@ -2241,12 +2266,17 @@ wait_event(card->waitq, atomic_read(&card->tx_timeout_task_counter) == 0); - + unregister_netdev(netdev); + + /* switch off card */ + spider_net_write_reg(card, SPIDER_NET_CKRCTRL, + SPIDER_NET_CKRCTRL_STOP_VALUE); + spider_net_write_reg(card, SPIDER_NET_CKRCTRL, + SPIDER_NET_CKRCTRL_RUN_VALUE); + spider_net_undo_pci_setup(card); free_netdev(netdev); - - free_irq(to_pci_dev(netdev->class_dev.dev)->irq, netdev); } static struct pci_driver spider_net_driver = { From arnd at arndb.de Fri Aug 19 03:42:13 2005 From: arnd at arndb.de (Arnd Bergmann) Date: Thu, 18 Aug 2005 19:42:13 +0200 Subject: [PATCH 4/4] ppc64: small hacks for running on BPA hardware In-Reply-To: <200508181931.43481.arnd@arndb.de> References: <200508181931.43481.arnd@arndb.de> Message-ID: <200508181752.j7IHq2Qr001692@d03av02.boulder.ibm.com> This patch is not meant for inclusion in a generic kernel, but is currently needed to support the available HW. Most of the things done in here are workarounds for deficiencies in the present hardware or firmware that will be solved there in later releases. Signed-off-by: Arnd Bergmann --- linux-cg.orig/arch/ppc64/Kconfig 2005-08-18 17:23:29.789907568 -0400 +++ linux-cg/arch/ppc64/Kconfig 2005-08-18 17:23:52.529911976 -0400 @@ -221,6 +221,12 @@ config SMP If you don't know what to do here, say Y. +config BE_DD2 + bool "BE DD2.x Errata Workaround Support" + depends on PPC_BPA + ---help--- + This support enables BE DD2.x errata workarounds. + config NR_CPUS int "Maximum number of CPUs (2-128)" range 2 128 --- linux-cg.orig/arch/ppc64/kernel/Makefile 2005-08-18 17:22:05.500940704 -0400 +++ linux-cg/arch/ppc64/kernel/Makefile 2005-08-18 17:23:52.668890848 -0400 @@ -33,7 +33,7 @@ obj-$(CONFIG_PPC_PSERIES) += pSeries_pci pSeries_nvram.o rtasd.o ras.o pSeries_reconfig.o \ pSeries_setup.o pSeries_iommu.o -obj-$(CONFIG_PPC_BPA) += bpa_setup.o bpa_iommu.o bpa_nvram.o \ +obj-$(CONFIG_PPC_BPA) += bpa_setup.o bpa_iommu.o bpa_nvram.o bpa_pci.o \ bpa_iic.o spider-pic.o obj-$(CONFIG_KEXEC) += machine_kexec.o --- linux-cg.orig/arch/ppc64/kernel/bpa_iommu.c 2005-08-18 17:23:29.778909240 -0400 +++ linux-cg/arch/ppc64/kernel/bpa_iommu.c 2005-08-18 17:23:52.472920640 -0400 @@ -245,8 +245,6 @@ set_iocmd_config(void __iomem *base) } /* FIXME: get these from the device tree */ -#define ioc_base 0x20000511000ull -#define ioc_mmio_base 0x20000510000ull #define ioid 0x48a #define iopt_phys_offset (- 0x20000000) /* We have a 512MB offset from the SB */ #define io_page_size 0x1000000 @@ -278,12 +276,22 @@ static void bpa_map_iommu(void) void __iomem *base; ioste ioste; unsigned long index; - + struct device_node *node; + unsigned long *handle, ioc_mmio_base, ioc_base; + int nodelen; + + for(node = of_find_node_by_type(NULL, "cpu"); + node; + node = of_find_node_by_type(node, "cpu")) { + handle = (unsigned long *) get_property(node, "ioc-translation", &nodelen); + ioc_base = *handle + 0x1000; + base = __ioremap(ioc_base, 0x1000, _PAGE_NO_CACHE); pr_debug("%lx mapped to %p\n", ioc_base, base); set_iocmd_config(base); iounmap(base); + ioc_mmio_base = *handle; base = __ioremap(ioc_mmio_base, 0x1000, _PAGE_NO_CACHE); pr_debug("%lx mapped to %p\n", ioc_mmio_base, base); @@ -302,6 +310,7 @@ static void bpa_map_iommu(void) map_iopt_entry(address)); } iounmap(base); + } } --- linux-cg.orig/arch/ppc64/kernel/bpa_pci.c 1969-12-31 19:00:00.000000000 -0500 +++ linux-cg/arch/ppc64/kernel/bpa_pci.c 2005-08-18 17:28:39.211996792 -0400 @@ -0,0 +1,83 @@ +/* + * BPA specific PCI code + * + * Copyright (C) 2005 IBM Corporation, + Arnd Bergmann + * + * 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 + */ + +#include +#include +#include + +#include +#include +#include + +#include "pci.h" +#include "bpa_iic.h" + +void __init bpa_final_fixup(void) +{ + struct pci_dev *dev = NULL; + + phbs_remap_io(); + + for_each_pci_dev(dev) { + // FIXME: fix IRQ numbers for devices on second south bridge + } +} + +static void fixup_spider_ipci_irq(struct pci_dev* dev) +{ + int irq_node_offset; + pr_debug("fixup for %04x:%04x at %02x.%1x: ", dev->vendor, dev->device, + PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); + switch (dev->devfn) { + case PCI_DEVFN(3,0): + /* ethernet */ + dev->irq = 8; + break; + case PCI_DEVFN(5,0): + /* OHCI 0 */ + dev->irq = 10; + break; + case PCI_DEVFN(6,0): + /* OHCI 1 */ + dev->irq = 11; + break; + case PCI_DEVFN(5,1): + /* EHCI 0 */ + dev->irq = 10; + break; + case PCI_DEVFN(6,1): + /* EHCI 1 */ + dev->irq = 11; + break; + } + + irq_node_offset = IIC_NODE_STRIDE * (pci_domain_nr(dev->bus)-1); + dev->irq += irq_node_offset; + + pr_debug("irq %0x\n", dev->irq); +} + +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TOSHIBA_2, + PCI_DEVICE_ID_TOSHIBA_SPIDER_NET, fixup_spider_ipci_irq); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TOSHIBA_2, + PCI_DEVICE_ID_TOSHIBA_SPIDER_OHCI, fixup_spider_ipci_irq); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TOSHIBA_2, + PCI_DEVICE_ID_TOSHIBA_SPIDER_EHCI, fixup_spider_ipci_irq); --- linux-cg.orig/arch/ppc64/kernel/bpa_setup.c 2005-08-18 17:22:05.507939640 -0400 +++ linux-cg/arch/ppc64/kernel/bpa_setup.c 2005-08-18 17:23:52.669890696 -0400 @@ -54,6 +54,8 @@ #define DBG(fmt...) #endif +extern void bpa_final_fixup(void); + void bpa_get_cpuinfo(struct seq_file *m) { struct device_node *root; @@ -129,6 +131,7 @@ struct machdep_calls __initdata bpa_md = .setup_arch = bpa_setup_arch, .init_early = bpa_init_early, .get_cpuinfo = bpa_get_cpuinfo, + .pcibios_fixup = bpa_final_fixup, .restart = rtas_restart, .power_off = rtas_power_off, .halt = rtas_halt, --- linux-cg.orig/arch/ppc64/kernel/head.S 2005-08-18 17:23:29.782908632 -0400 +++ linux-cg/arch/ppc64/kernel/head.S 2005-08-18 17:23:52.626897232 -0400 @@ -312,6 +312,38 @@ label##_pSeries: \ RUNLATCH_ON(r13); \ EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common) +#define WORKAROUND_EXCEPTION_PSERIES(n, label) \ + . = n; \ + .globl label##_pSeries; \ +label##_pSeries: \ + mtspr SPRG1,r21; /* save r21 */ \ + mfspr r21, SPRN_CTRLF; \ + oris r21, r21, 0x00C0; \ + mtspr SPRN_CTRLT, r21; \ + mfspr r21,SPRG1; /* restore r21 */ \ + mtspr SPRG1,r13; /* save r13 */ \ + EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common) + +#define RES_EXCEPTION_PSERIES(n, label) \ + . = n; \ + .globl label##_pSeries; \ +label##_pSeries: \ + mtspr SPRG2,r20; /* use SPRG2 as scratch reg */ \ + mtspr SPRG1,r21; /* use SPRG1 as scratch reg */ \ + mfspr r20,SPRG3; /* get paca virtual address */ \ + cmpdi r20,0x0; /* if SPRG3 zero,thread */ \ + bne 20f; /* shouldn't run */ \ +18: /* Stop current Thread */ \ + andi. r21,0,0; \ + mtspr SPRN_CTRLT,r21; \ +19: \ + b 19b; /* Thread should be stopped */ \ +20: \ + HMT_MEDIUM; \ + mtspr SPRG1,r13; /* save r13 */ \ + RUNLATCH_ON(r13); \ + EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common) + #define STD_EXCEPTION_ISERIES(n, label, area) \ .globl label##_iSeries; \ label##_iSeries: \ @@ -391,7 +423,11 @@ label##_common: \ .globl __start_interrupts __start_interrupts: +#ifdef CONFIG_BE_DD2 + RES_EXCEPTION_PSERIES(0x100, system_reset) +#else STD_EXCEPTION_PSERIES(0x100, system_reset) +#endif . = 0x200 _machine_check_pSeries: @@ -459,11 +495,15 @@ instruction_access_slb_pSeries: mfspr r3,SRR0 /* SRR0 is faulting address */ b .do_slb_miss /* Rel. branch works in real mode */ - STD_EXCEPTION_PSERIES(0x500, hardware_interrupt) +#ifdef CONFIG_BE_DD2 + WORKAROUND_EXCEPTION_PSERIES(0x500, hardware_interrupt) +#endif STD_EXCEPTION_PSERIES(0x600, alignment) STD_EXCEPTION_PSERIES(0x700, program_check) STD_EXCEPTION_PSERIES(0x800, fp_unavailable) - STD_EXCEPTION_PSERIES(0x900, decrementer) +#ifdef CONFIG_BE_DD2 + WORKAROUND_EXCEPTION_PSERIES(0x900, decrementer) +#endif STD_EXCEPTION_PSERIES(0xa00, trap_0a) STD_EXCEPTION_PSERIES(0xb00, trap_0b) --- linux-cg.orig/arch/ppc64/kernel/prom_init.c 2005-08-18 17:23:29.787907872 -0400 +++ linux-cg/arch/ppc64/kernel/prom_init.c 2005-08-18 17:23:52.776874432 -0400 @@ -1365,6 +1365,8 @@ static int __init prom_find_machine_type return PLATFORM_POWERMAC; if (strstr(p, RELOC("Momentum,Maple"))) return PLATFORM_MAPLE; + if (strstr(p, RELOC("IBM,CPB"))) + return PLATFORM_BPA; i += sl + 1; } } --- linux-cg.orig/arch/ppc64/kernel/spider-pic.c 2005-08-18 17:23:29.780908936 -0400 +++ linux-cg/arch/ppc64/kernel/spider-pic.c 2005-08-18 17:23:52.473920488 -0400 @@ -84,10 +84,11 @@ static void __iomem *spider_get_irq_conf static void spider_enable_irq(unsigned int irq) { + int nodeid = (irq / IIC_NODE_STRIDE) * 0x10; void __iomem *cfg = spider_get_irq_config(irq); irq = spider_get_nr(irq); - out_be32(cfg, in_be32(cfg) | 0x3107000eu); + out_be32(cfg, in_be32(cfg) | 0x3107000eu | nodeid); out_be32(cfg + 4, in_be32(cfg + 4) | 0x00020000u | irq); } @@ -150,13 +151,17 @@ int spider_get_irq(unsigned long int_pen void spider_init_IRQ(void) { int node; +#if 0 struct device_node *dn; unsigned int *property; +#endif long spiderpic; + long pics[] = { 0x24000008000, 0x34000008000 }; int n; /* FIXME: detect multiple PICs as soon as the device tree has them */ - for (node = 0; node < 1; node++) { + for (node = 0; node <= 1; node++) { +#if 0 dn = of_find_node_by_path("/"); n = prom_n_addr_cells(dn); property = (unsigned int *) get_property(dn, @@ -166,6 +171,8 @@ void spider_init_IRQ(void) continue; for (spiderpic = 0; n > 0; --n) spiderpic = (spiderpic << 32) + *property++; +#endif + spiderpic = pics[node]; printk(KERN_DEBUG "SPIDER addr: %lx\n", spiderpic); spider_pics[node] = __ioremap(spiderpic, 0x800, _PAGE_NO_CACHE); for (n = 0; n < IIC_NUM_EXT; n++) { --- linux-cg.orig/include/asm-ppc64/processor.h 2005-08-18 17:23:29.773910000 -0400 +++ linux-cg/include/asm-ppc64/processor.h 2005-08-18 17:23:52.423928088 -0400 @@ -438,7 +438,7 @@ struct thread_struct { .fs = KERNEL_DS, \ .fpr = {0}, \ .fpscr = 0, \ - .fpexc_mode = MSR_FE0|MSR_FE1, \ + .fpexc_mode = 0, \ } /* --- linux-cg.orig/include/linux/pci_ids.h 2005-08-18 17:23:29.775909696 -0400 +++ linux-cg/include/linux/pci_ids.h 2005-08-18 17:23:52.827004832 -0400 @@ -1611,6 +1611,8 @@ #define PCI_DEVICE_ID_TOSHIBA_TX4927 0x0180 #define PCI_DEVICE_ID_TOSHIBA_TC86C001_MISC 0x0108 #define PCI_DEVICE_ID_TOSHIBA_SPIDER_NET 0x01b3 +#define PCI_DEVICE_ID_TOSHIBA_SPIDER_OHCI 0x01b6 +#define PCI_DEVICE_ID_TOSHIBA_SPIDER_EHCI 0x01b5 #define PCI_VENDOR_ID_RICOH 0x1180 #define PCI_DEVICE_ID_RICOH_RL5C465 0x0465 From arnd at arndb.de Fri Aug 19 03:33:56 2005 From: arnd at arndb.de (Arnd Bergmann) Date: Thu, 18 Aug 2005 19:33:56 +0200 Subject: [PATCH 0/4] ppc64: updates for BPA platform Message-ID: <200508181931.43481.arnd@arndb.de> These are a few updates for the BPA platform of ppc64. Only the first two patches are meant for inclusion, the others are provided here for people who are running on Cell already and cannot wait for clean versions of the patches ;-) I also have lots of updates pending for spufs, but will send them separately. Arnd <>< From arnd at arndb.de Fri Aug 19 03:35:21 2005 From: arnd at arndb.de (Arnd Bergmann) Date: Thu, 18 Aug 2005 19:35:21 +0200 Subject: [PATCH 1/4] ppc64: fix IPI on bpa_iic In-Reply-To: <200508181931.43481.arnd@arndb.de> References: <200508181931.43481.arnd@arndb.de> Message-ID: <200508181752.j7IHq2Qt001692@d03av02.boulder.ibm.com> This fixes a severe bug in the bpa_iic driver that caused all sorts of problems. We had been using incorrect priority values for inter processor interrupts, which resulted in always doing CALL_FUNCTION instead of RESCHEDULE or DEBUGGER_BREAK. The symptoms cured by this patch include bad performance on SMP systems spurious kernel panics in the IPI code. Signed-off-by: Arnd Bergmann --- linux-2.6.13-rc6.orig/arch/ppc64/kernel/bpa_iic.c +++ linux-2.6.13-rc6/arch/ppc64/kernel/bpa_iic.c @@ -205,6 +205,18 @@ static struct iic_regs __iomem *find_iic } #ifdef CONFIG_SMP + +/* Use the highest interrupt priorities for IPI */ +static inline int iic_ipi_to_irq(int ipi) +{ + return IIC_IPI_OFFSET + IIC_NUM_IPIS - 1 - ipi; +} + +static inline int iic_irq_to_ipi(int irq) +{ + return IIC_NUM_IPIS - 1 - (irq - IIC_IPI_OFFSET); +} + void iic_setup_cpu(void) { out_be64(&__get_cpu_var(iic).regs->prio, 0xff); @@ -212,18 +224,20 @@ void iic_setup_cpu(void) void iic_cause_IPI(int cpu, int mesg) { - out_be64(&per_cpu(iic, cpu).regs->generate, mesg); + out_be64(&per_cpu(iic, cpu).regs->generate, (IIC_NUM_IPIS - 1 - mesg) << 4); } static irqreturn_t iic_ipi_action(int irq, void *dev_id, struct pt_regs *regs) { - - smp_message_recv(irq - IIC_IPI_OFFSET, regs); + smp_message_recv(iic_irq_to_ipi(irq), regs); return IRQ_HANDLED; } -static void iic_request_ipi(int irq, const char *name) +static void iic_request_ipi(int ipi, const char *name) { + int irq; + + irq = iic_ipi_to_irq(ipi); /* IPIs are marked SA_INTERRUPT as they must run with irqs * disabled */ get_irq_desc(irq)->handler = &iic_pic; @@ -233,10 +247,10 @@ static void iic_request_ipi(int irq, con void iic_request_IPIs(void) { - iic_request_ipi(IIC_IPI_OFFSET + PPC_MSG_CALL_FUNCTION, "IPI-call"); - iic_request_ipi(IIC_IPI_OFFSET + PPC_MSG_RESCHEDULE, "IPI-resched"); + iic_request_ipi(PPC_MSG_CALL_FUNCTION, "IPI-call"); + iic_request_ipi(PPC_MSG_RESCHEDULE, "IPI-resched"); #ifdef CONFIG_DEBUGGER - iic_request_ipi(IIC_IPI_OFFSET + PPC_MSG_DEBUGGER_BREAK, "IPI-debug"); + iic_request_ipi(PPC_MSG_DEBUGGER_BREAK, "IPI-debug"); #endif /* CONFIG_DEBUGGER */ } #endif /* CONFIG_SMP */ From nish.aravamudan at gmail.com Fri Aug 19 04:07:56 2005 From: nish.aravamudan at gmail.com (Nish Aravamudan) Date: Thu, 18 Aug 2005 11:07:56 -0700 Subject: [PATCH 3/4] ppc64: add RTAS console driver In-Reply-To: <200508181752.j7IHq2Qq001692@d03av02.boulder.ibm.com> References: <200508181931.43481.arnd@arndb.de> <200508181752.j7IHq2Qq001692@d03av02.boulder.ibm.com> Message-ID: <29495f1d050818110763d0b658@mail.gmail.com> On 8/18/05, Arnd Bergmann wrote: > The RTAS console driver can be used by all machines that abstract > the system console through the {get,put}-term-char interface. > It replaces the hvconsole on BPA, because we don't run under > a hypervisor. > > This driver needs to be redone as a special case of hvconsole, > so there is no point in applying the patch to generic kernels. > You will however need it if you intend to run on present Cell > hardware. > > From: Utz Bacher > Signed-off-by: Arnd Bergmann > --- linux-cg.orig/drivers/char/rtascons.c 1969-12-31 19:00:00.000000000 -0500 > +++ linux-cg/drivers/char/rtascons.c 2005-08-18 17:31:21.912892064 > +#define RTASCONS_TIMEOUT ((HZ + 99) / 100) msecs_to_jiffies(10)? Or perhaps leave it in milliseconds with a comment as such (see below)? > +static int > +krtasconsd(void *unused) > +{ > + daemonize("krtasconsd"); > + > + for (;;) { > + if (cpus_empty(cpus_in_xmon)) { > + rtascons_poll(); > + /* no need for atomic access */ > + if (rtascons_buffer_used) { > + spin_lock(&rtascons_buffer_lock); > + rtascons_flush_chars(); > + spin_unlock(&rtascons_buffer_lock); > + } > + } > + > + set_current_state(TASK_INTERRUPTIBLE); > + schedule_timeout(RTASCONS_TIMEOUT); Couldn't this be msleep_interruptible(RTASCONS_TIMEOUT) [if you make RTASCONS_TIMEOUT in milliseconds]? Thanks, Nish From linas at austin.ibm.com Fri Aug 19 05:44:45 2005 From: linas at austin.ibm.com (Linas Vepstas) Date: Thu, 18 Aug 2005 14:44:45 -0500 Subject: [patch 1/2] PPC64: Janitorial: Dont use deprecated routine In-Reply-To: <20050818161404.GJ1012@otto> References: <20050818160453.748439000@bilge> <20050818160516.008103000@bilge> <20050818161404.GJ1012@otto> Message-ID: <20050818194445.GU5553@austin.ibm.com> On Thu, Aug 18, 2005 at 11:14:04AM -0500, Nathan Lynch was heard to remark: > linas at austin.ibm.com wrote: > > The current ppc64 rpaphp code uses an old, deprecated routine to > > find all of the pci devices on the system. This patch changes this > > to use the new API. This is a janitorial patch. > > Patches to this driver should go through the pci hotplug list and the > driver's maintainer, no? It did, didn't it? My understanding is the aintainer is John Rose ... Sorry I didn't cc the pci list, I figured the ppc64 list would be enough, since this only affects the ppc community. --linas From linas at austin.ibm.com Fri Aug 19 05:54:49 2005 From: linas at austin.ibm.com (Linas Vepstas) Date: Thu, 18 Aug 2005 14:54:49 -0500 Subject: [patch 2/2] PPC64: Janitorial: Remove unused, deprecated code In-Reply-To: <20050818161944.GK1012@otto> References: <20050818160453.748439000@bilge> <20050818160516.683730000@bilge> <20050818161944.GK1012@otto> Message-ID: <20050818195449.GV5553@austin.ibm.com> On Thu, Aug 18, 2005 at 11:19:44AM -0500, Nathan Lynch was heard to remark: > linas at austin.ibm.com wrote: > > -/** > > - * Returns all nodes linked together > > - */ > > -struct device_node * > > -find_all_nodes(void) > > -{ > > - struct device_node *head, **prevp, *np; > > - > > - prevp = &head; > > - for (np = allnodes; np != 0; np = np->allnext) { > > - *prevp = np; > > - prevp = &np->next; > > - } > > - *prevp = NULL; > > - return head; > > -} > > -EXPORT_SYMBOL(find_all_nodes); > > I don't think we're supposed to just rip out exported symbols without > notice anymore. Oh, why not? I grepped, I can't find any users of this code anywhere. Surely, there aren't any proprietary drivers calling this. > This is only one of a family of unofficially deprecated functions for > traversing the OF device tree. I was thinking of asking if I should get rid of the other uses of the other deprecated functions as well. So.. Should I? > Perhaps we should add this group of > functions to Documentation/feature-removal-schedule.txt to make it > official, and then we can get rid of them in a few months. Hmm, just looked at that file. Surely, the intent of that file is to document big things that affect many other people. By contrast, I would have thought that this patch affected just about no one. I found it somewhat bizarre to see dates in that file, and not version numbers. Wouldn't one want to have the removal of big chunks coincide with releases of new major versions? e.g. 2.6.14 or 2.6.15? --linas From mensagem at voxcard.com.br Thu Aug 18 18:38:02 2005 From: mensagem at voxcard.com.br (mensagem at voxcard.com.br) Date: Thu, 18 Aug 2005 03:38:02 -0500 Subject: Voce Acaba De Receber Um Cartao VoxCard Message-ID: <200508180838.j7I8c1v10225@ftsweb2.aijalon.net> An HTML attachment was scrubbed... URL: http://ozlabs.org/pipermail/linuxppc64-dev/attachments/20050818/f713b59b/attachment.htm From benh at kernel.crashing.org Fri Aug 19 07:59:23 2005 From: benh at kernel.crashing.org (Benjamin Herrenschmidt) Date: Fri, 19 Aug 2005 07:59:23 +1000 Subject: [patch 1/2] PPC64: Janitorial: Dont use deprecated routine In-Reply-To: <20050818194445.GU5553@austin.ibm.com> References: <20050818160453.748439000@bilge> <20050818160516.008103000@bilge> <20050818161404.GJ1012@otto> <20050818194445.GU5553@austin.ibm.com> Message-ID: <1124402363.5197.16.camel@gaston> On Thu, 2005-08-18 at 14:44 -0500, Linas Vepstas wrote: > On Thu, Aug 18, 2005 at 11:14:04AM -0500, Nathan Lynch was heard to remark: > > linas at austin.ibm.com wrote: > > > The current ppc64 rpaphp code uses an old, deprecated routine to > > > find all of the pci devices on the system. This patch changes this > > > to use the new API. This is a janitorial patch. > > > > Patches to this driver should go through the pci hotplug list and the > > driver's maintainer, no? > > It did, didn't it? My understanding is the aintainer is John Rose ... Neither the PCI hotplug list nor John are in your CC list ... > Sorry I didn't cc the pci list, I figured the ppc64 list would be > enough, since this only affects the ppc community. Well, John isn't on the list neither :) Ben. From johnrose at austin.ibm.com Fri Aug 19 09:48:08 2005 From: johnrose at austin.ibm.com (John Rose) Date: Thu, 18 Aug 2005 18:48:08 -0500 Subject: [patch 1/2] PPC64: Janitorial: Dont use deprecated routine In-Reply-To: <20050818194445.GU5553@austin.ibm.com> References: <20050818160453.748439000@bilge> <20050818160516.008103000@bilge> <20050818161404.GJ1012@otto> <20050818194445.GU5553@austin.ibm.com> Message-ID: <1124408888.1138.13.camel@sinatra.austin.ibm.com> > > Patches to this driver should go through the pci hotplug list and the > > driver's maintainer, no? > > It did, didn't it? My understanding is the aintainer is John Rose ... > > Sorry I didn't cc the pci list, I figured the ppc64 list would be > enough, since this only affects the ppc community. GregKH is considered the PCI Hotplug maintainer for all arches, and he tends to see hotplug stuff on the pcihpd-discuss list. Thanks- John From hollis at penguinppc.org Fri Aug 19 12:35:21 2005 From: hollis at penguinppc.org (Hollis Blanchard) Date: Thu, 18 Aug 2005 21:35:21 -0500 Subject: How to get out physc? In-Reply-To: References: Message-ID: On Aug 18, 2005, at 6:41 AM, matthias.hofer at arz.co.at wrote: > > I am using GNU/Linux (SLES9) on an IBM p5 right now and want to get out > how much "physc" the LPAR consumes; on AIX, this can be accomplished > with > sar, vmstat, topas, nmon and mpstat. > On GNU/Linux, I could not find any of these utilities in a Version that > would show me such an info. So what is "physc"? -Hollis From david at gibson.dropbear.id.au Fri Aug 19 14:49:00 2005 From: david at gibson.dropbear.id.au (David Gibson) Date: Fri, 19 Aug 2005 14:49:00 +1000 Subject: [PATCH 0/8] ppc64 head.S cleanups (rebased) Message-ID: <20050819044900.GC17814@localhost.localdomain> Paulus, this is a new version of my head.S cleanups stack, rebased for the current Linus git tree. In particular it resolves the conflicts the old version had with the new buggy-assembler-friendly way of doing the iSeries lparmap. Please merge into your post-2.6.13 queue (replacing the old versions, obviously. -- David Gibson | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/people/dgibson From david at gibson.dropbear.id.au Fri Aug 19 14:52:31 2005 From: david at gibson.dropbear.id.au (David Gibson) Date: Fri, 19 Aug 2005 14:52:31 +1000 (EST) Subject: [PATCH 1/8] Remove NACA fixed address constraint In-Reply-To: <20050819044900.GC17814@localhost.localdomain> Message-ID: <20050819045231.BC387680A7@ozlabs.org> Comments in head.S suggest that the iSeries naca has a fixed address, because tools expect to find it there. The only tool which appears to access the naca is addRamDisk, but both the in-kernel version and the version used in RHEL and SuSE in fact locate the NACA the same way as the hypervisor does, by following the pointer in the hvReleaseData structure. Since the requirement for a fixed address seems to be obsolete, this patch removes the naca from head.S and replaces it with a normal C initializer. For good measure, it removes an old version of addRamDisk.c which was sitting, unused, in the ppc32 tree. Signed-off-by: David Gibson --- arch/ppc/boot/utils/addRamDisk.c | 203 --------------------------------------- arch/ppc64/kernel/LparData.c | 11 ++ arch/ppc64/kernel/head.S | 17 --- include/asm-ppc64/naca.h | 7 - 4 files changed, 12 insertions(+), 226 deletions(-) Index: working-2.6/arch/ppc/boot/utils/addRamDisk.c =================================================================== --- working-2.6.orig/arch/ppc/boot/utils/addRamDisk.c 2005-08-19 14:34:30.000000000 +1000 +++ /dev/null 1970-01-01 00:00:00.000000000 +0000 @@ -1,203 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -#define ElfHeaderSize (64 * 1024) -#define ElfPages (ElfHeaderSize / 4096) -#define KERNELBASE (0xc0000000) - -void get4k(FILE *file, char *buf ) -{ - unsigned j; - unsigned num = fread(buf, 1, 4096, file); - for ( j=num; j<4096; ++j ) - buf[j] = 0; -} - -void put4k(FILE *file, char *buf ) -{ - fwrite(buf, 1, 4096, file); -} - -void death(const char *msg, FILE *fdesc, const char *fname) -{ - printf(msg); - fclose(fdesc); - unlink(fname); - exit(1); -} - -int main(int argc, char **argv) -{ - char inbuf[4096]; - FILE *ramDisk = NULL; - FILE *inputVmlinux = NULL; - FILE *outputVmlinux = NULL; - unsigned i = 0; - u_int32_t ramFileLen = 0; - u_int32_t ramLen = 0; - u_int32_t roundR = 0; - u_int32_t kernelLen = 0; - u_int32_t actualKernelLen = 0; - u_int32_t round = 0; - u_int32_t roundedKernelLen = 0; - u_int32_t ramStartOffs = 0; - u_int32_t ramPages = 0; - u_int32_t roundedKernelPages = 0; - u_int32_t hvReleaseData = 0; - u_int32_t eyeCatcher = 0xc8a5d9c4; - u_int32_t naca = 0; - u_int32_t xRamDisk = 0; - u_int32_t xRamDiskSize = 0; - if ( argc < 2 ) { - printf("Name of RAM disk file missing.\n"); - exit(1); - } - - if ( argc < 3 ) { - printf("Name of vmlinux file missing.\n"); - exit(1); - } - - if ( argc < 4 ) { - printf("Name of vmlinux output file missing.\n"); - exit(1); - } - - ramDisk = fopen(argv[1], "r"); - if ( ! ramDisk ) { - printf("RAM disk file \"%s\" failed to open.\n", argv[1]); - exit(1); - } - inputVmlinux = fopen(argv[2], "r"); - if ( ! inputVmlinux ) { - printf("vmlinux file \"%s\" failed to open.\n", argv[2]); - exit(1); - } - outputVmlinux = fopen(argv[3], "w+"); - if ( ! outputVmlinux ) { - printf("output vmlinux file \"%s\" failed to open.\n", argv[3]); - exit(1); - } - fseek(ramDisk, 0, SEEK_END); - ramFileLen = ftell(ramDisk); - fseek(ramDisk, 0, SEEK_SET); - printf("%s file size = %d\n", argv[1], ramFileLen); - - ramLen = ramFileLen; - - roundR = 4096 - (ramLen % 4096); - if ( roundR ) { - printf("Rounding RAM disk file up to a multiple of 4096, adding %d\n", roundR); - ramLen += roundR; - } - - printf("Rounded RAM disk size is %d\n", ramLen); - fseek(inputVmlinux, 0, SEEK_END); - kernelLen = ftell(inputVmlinux); - fseek(inputVmlinux, 0, SEEK_SET); - printf("kernel file size = %d\n", kernelLen); - if ( kernelLen == 0 ) { - printf("You must have a linux kernel specified as argv[2]\n"); - exit(1); - } - - actualKernelLen = kernelLen - ElfHeaderSize; - - printf("actual kernel length (minus ELF header) = %d\n", actualKernelLen); - - round = actualKernelLen % 4096; - roundedKernelLen = actualKernelLen; - if ( round ) - roundedKernelLen += (4096 - round); - - printf("actual kernel length rounded up to a 4k multiple = %d\n", roundedKernelLen); - - ramStartOffs = roundedKernelLen; - ramPages = ramLen / 4096; - - printf("RAM disk pages to copy = %d\n", ramPages); - - // Copy 64K ELF header - for (i=0; i<(ElfPages); ++i) { - get4k( inputVmlinux, inbuf ); - put4k( outputVmlinux, inbuf ); - } - - roundedKernelPages = roundedKernelLen / 4096; - - fseek(inputVmlinux, ElfHeaderSize, SEEK_SET); - - for ( i=0; i #include #include -#include #include #include #include @@ -511,24 +510,10 @@ mfspr r12,SPRG2 EXCEPTION_PROLOG_PSERIES(PACA_EXSLB, .do_stab_bolted) - - /* Space for the naca. Architected to be located at real address - * NACA_PHYS_ADDR. Various tools rely on this location being fixed. - * The first dword of the naca is required by iSeries LPAR to - * point to itVpdAreas. On pSeries native, this value is not used. - */ - . = NACA_PHYS_ADDR - .globl __end_interrupts -__end_interrupts: -#ifdef CONFIG_PPC_ISERIES - .globl naca -naca: - .llong itVpdAreas - .llong 0 /* xRamDisk */ - .llong 0 /* xRamDiskSize */ . = 0x6100 +#ifdef CONFIG_PPC_ISERIES /*** ISeries-LPAR interrupt handlers ***/ STD_EXCEPTION_ISERIES(0x200, machine_check, PACA_EXMC) Index: working-2.6/include/asm-ppc64/naca.h =================================================================== --- working-2.6.orig/include/asm-ppc64/naca.h 2005-08-19 14:34:30.000000000 +1000 +++ working-2.6/include/asm-ppc64/naca.h 2005-08-19 14:34:45.000000000 +1000 @@ -12,8 +12,6 @@ #include -#ifndef __ASSEMBLY__ - struct naca_struct { /* Kernel only data - undefined for user space */ void *xItVpdAreas; /* VPD Data 0x00 */ @@ -23,9 +21,4 @@ extern struct naca_struct naca; -#endif /* __ASSEMBLY__ */ - -#define NACA_PAGE 0x4 -#define NACA_PHYS_ADDR (NACA_PAGE< Message-ID: <20050819045231.C2BF5680A8@ozlabs.org> In the ppc64 kernel head.S there is currently quite a lot of unused space between the naca (at fixed address 0x4000) and the fwnmi data area (at fixed address 0x7000). This patch moves various exception vectors and support code into this region to use the wasted space. The functions load_up_fpu and load_up_altivec are moved down as well, since they are essentially continuations of the fp_unavailable_common and altivec_unavailable_common vectors, respectively. Likewise, the fwnmi vectors themselves are moved down into this area, because while the location of the fwnmi data area is fixed by the RPA, the vectors themselves can be anywhere sufficiently low. Signed-off-by: David Gibson --- arch/ppc64/kernel/head.S | 353 +++++++++++++++++++++++------------------------ 1 files changed, 174 insertions(+), 179 deletions(-) Index: working-2.6/arch/ppc64/kernel/head.S =================================================================== --- working-2.6.orig/arch/ppc64/kernel/head.S 2005-08-19 14:34:45.000000000 +1000 +++ working-2.6/arch/ppc64/kernel/head.S 2005-08-19 14:37:04.000000000 +1000 @@ -52,9 +52,8 @@ * We layout physical memory as follows: * 0x0000 - 0x00ff : Secondary processor spin code * 0x0100 - 0x2fff : pSeries Interrupt prologs - * 0x3000 - 0x3fff : Interrupt support - * 0x4000 - 0x4fff : NACA - * 0x6000 : iSeries and common interrupt prologs + * 0x3000 - 0x6fff : interrupt support, iSeries and common interrupt prologs + * 0x7000 - 0x7fff : FWNMI data area * 0x9000 - 0x9fff : Initial segment table */ @@ -501,17 +500,35 @@ STD_EXCEPTION_PSERIES(0x1300, instruction_breakpoint) STD_EXCEPTION_PSERIES(0x1700, altivec_assist) + . = 0x3000 + +/*** pSeries interrupt support ***/ + /* moved from 0xf00 */ - STD_EXCEPTION_PSERIES(0x3000, performance_monitor) + STD_EXCEPTION_PSERIES(., performance_monitor) - . = 0x3100 + .align 7 _GLOBAL(do_stab_bolted_pSeries) mtcrf 0x80,r12 mfspr r12,SPRG2 EXCEPTION_PROLOG_PSERIES(PACA_EXSLB, .do_stab_bolted) +/* + * Vectors for the FWNMI option. Share common code. + */ + .globl system_reset_fwnmi +system_reset_fwnmi: + HMT_MEDIUM + mtspr SPRG1,r13 /* save r13 */ + RUNLATCH_ON(r13) + EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common) - . = 0x6100 + .globl machine_check_fwnmi +machine_check_fwnmi: + HMT_MEDIUM + mtspr SPRG1,r13 /* save r13 */ + RUNLATCH_ON(r13) + EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common) #ifdef CONFIG_PPC_ISERIES /*** ISeries-LPAR interrupt handlers ***/ @@ -656,51 +673,8 @@ ld r13,PACA_EXGEN+EX_R13(r13) rfid b . /* prevent speculative execution */ -#endif - -/* - * Data area reserved for FWNMI option. - */ - .= 0x7000 - .globl fwnmi_data_area -fwnmi_data_area: - -#ifdef CONFIG_PPC_ISERIES - . = LPARMAP_PHYS -#include "lparmap.s" #endif /* CONFIG_PPC_ISERIES */ -/* - * Vectors for the FWNMI option. Share common code. - */ - . = 0x8000 - .globl system_reset_fwnmi -system_reset_fwnmi: - HMT_MEDIUM - mtspr SPRG1,r13 /* save r13 */ - RUNLATCH_ON(r13) - EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common) - .globl machine_check_fwnmi -machine_check_fwnmi: - HMT_MEDIUM - mtspr SPRG1,r13 /* save r13 */ - RUNLATCH_ON(r13) - EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common) - - /* - * Space for the initial segment table - * For LPAR, the hypervisor must fill in at least one entry - * before we get control (with relocate on) - */ - . = STAB0_PHYS_ADDR - .globl __start_stab -__start_stab: - - . = (STAB0_PHYS_ADDR + PAGE_SIZE) - .globl __end_stab -__end_stab: - - /*** Common interrupt handlers ***/ STD_EXCEPTION_COMMON(0x100, system_reset, .system_reset_exception) @@ -891,6 +865,62 @@ bl .kernel_fp_unavailable_exception BUG_OPCODE +/* + * load_up_fpu(unused, unused, tsk) + * Disable FP for the task which had the FPU previously, + * and save its floating-point registers in its thread_struct. + * Enables the FPU for use in the kernel on return. + * On SMP we know the fpu is free, since we give it up every + * switch (ie, no lazy save of the FP registers). + * On entry: r13 == 'current' && last_task_used_math != 'current' + */ +_STATIC(load_up_fpu) + mfmsr r5 /* grab the current MSR */ + ori r5,r5,MSR_FP + mtmsrd r5 /* enable use of fpu now */ + isync +/* + * For SMP, we don't do lazy FPU switching because it just gets too + * horrendously complex, especially when a task switches from one CPU + * to another. Instead we call giveup_fpu in switch_to. + * + */ +#ifndef CONFIG_SMP + ld r3,last_task_used_math at got(r2) + ld r4,0(r3) + cmpdi 0,r4,0 + beq 1f + /* Save FP state to last_task_used_math's THREAD struct */ + addi r4,r4,THREAD + SAVE_32FPRS(0, r4) + mffs fr0 + stfd fr0,THREAD_FPSCR(r4) + /* Disable FP for last_task_used_math */ + ld r5,PT_REGS(r4) + ld r4,_MSR-STACK_FRAME_OVERHEAD(r5) + li r6,MSR_FP|MSR_FE0|MSR_FE1 + andc r4,r4,r6 + std r4,_MSR-STACK_FRAME_OVERHEAD(r5) +1: +#endif /* CONFIG_SMP */ + /* enable use of FP after return */ + ld r4,PACACURRENT(r13) + addi r5,r4,THREAD /* Get THREAD */ + ld r4,THREAD_FPEXC_MODE(r5) + ori r12,r12,MSR_FP + or r12,r12,r4 + std r12,_MSR(r1) + lfd fr0,THREAD_FPSCR(r5) + mtfsf 0xff,fr0 + REST_32FPRS(0, r5) +#ifndef CONFIG_SMP + /* Update last_task_used_math to 'current' */ + subi r4,r5,THREAD /* Back to 'current' */ + std r4,0(r3) +#endif /* CONFIG_SMP */ + /* restore registers and return */ + b fast_exception_return + .align 7 .globl altivec_unavailable_common altivec_unavailable_common: @@ -906,6 +936,80 @@ bl .altivec_unavailable_exception b .ret_from_except +#ifdef CONFIG_ALTIVEC +/* + * load_up_altivec(unused, unused, tsk) + * Disable VMX for the task which had it previously, + * and save its vector registers in its thread_struct. + * Enables the VMX for use in the kernel on return. + * On SMP we know the VMX is free, since we give it up every + * switch (ie, no lazy save of the vector registers). + * On entry: r13 == 'current' && last_task_used_altivec != 'current' + */ +_STATIC(load_up_altivec) + mfmsr r5 /* grab the current MSR */ + oris r5,r5,MSR_VEC at h + mtmsrd r5 /* enable use of VMX now */ + isync + +/* + * For SMP, we don't do lazy VMX switching because it just gets too + * horrendously complex, especially when a task switches from one CPU + * to another. Instead we call giveup_altvec in switch_to. + * VRSAVE isn't dealt with here, that is done in the normal context + * switch code. Note that we could rely on vrsave value to eventually + * avoid saving all of the VREGs here... + */ +#ifndef CONFIG_SMP + ld r3,last_task_used_altivec at got(r2) + ld r4,0(r3) + cmpdi 0,r4,0 + beq 1f + /* Save VMX state to last_task_used_altivec's THREAD struct */ + addi r4,r4,THREAD + SAVE_32VRS(0,r5,r4) + mfvscr vr0 + li r10,THREAD_VSCR + stvx vr0,r10,r4 + /* Disable VMX for last_task_used_altivec */ + ld r5,PT_REGS(r4) + ld r4,_MSR-STACK_FRAME_OVERHEAD(r5) + lis r6,MSR_VEC at h + andc r4,r4,r6 + std r4,_MSR-STACK_FRAME_OVERHEAD(r5) +1: +#endif /* CONFIG_SMP */ + /* Hack: if we get an altivec unavailable trap with VRSAVE + * set to all zeros, we assume this is a broken application + * that fails to set it properly, and thus we switch it to + * all 1's + */ + mfspr r4,SPRN_VRSAVE + cmpdi 0,r4,0 + bne+ 1f + li r4,-1 + mtspr SPRN_VRSAVE,r4 +1: + /* enable use of VMX after return */ + ld r4,PACACURRENT(r13) + addi r5,r4,THREAD /* Get THREAD */ + oris r12,r12,MSR_VEC at h + std r12,_MSR(r1) + li r4,1 + li r10,THREAD_VSCR + stw r4,THREAD_USED_VR(r5) + lvx vr0,r10,r5 + mtvscr vr0 + REST_32VRS(0,r4,r5) +#ifndef CONFIG_SMP + /* Update last_task_used_math to 'current' */ + subi r4,r5,THREAD /* Back to 'current' */ + std r4,0(r3) +#endif /* CONFIG_SMP */ + /* restore registers and return */ + b fast_exception_return +#endif /* CONFIG_ALTIVEC */ + /* * Hash table stuff */ @@ -1152,6 +1256,27 @@ bl .unrecoverable_exception b 1b +/* + * Data area reserved for FWNMI option. + * This address (0x7000) is fixed by the RPA. + */ + .= 0x7000 + .globl fwnmi_data_area +fwnmi_data_area: + .space PAGE_SIZE + + /* + * Space for the initial segment table + * For LPAR, the hypervisor must fill in at least one entry + * before we get control (with relocate on) + */ + . = STAB0_PHYS_ADDR + .globl __start_stab +__start_stab: + + . = (STAB0_PHYS_ADDR + PAGE_SIZE) + .globl __end_stab +__end_stab: /* * On pSeries, secondary processors spin in the following code. @@ -1416,62 +1541,6 @@ copy_to_here: /* - * load_up_fpu(unused, unused, tsk) - * Disable FP for the task which had the FPU previously, - * and save its floating-point registers in its thread_struct. - * Enables the FPU for use in the kernel on return. - * On SMP we know the fpu is free, since we give it up every - * switch (ie, no lazy save of the FP registers). - * On entry: r13 == 'current' && last_task_used_math != 'current' - */ -_STATIC(load_up_fpu) - mfmsr r5 /* grab the current MSR */ - ori r5,r5,MSR_FP - mtmsrd r5 /* enable use of fpu now */ - isync -/* - * For SMP, we don't do lazy FPU switching because it just gets too - * horrendously complex, especially when a task switches from one CPU - * to another. Instead we call giveup_fpu in switch_to. - * - */ -#ifndef CONFIG_SMP - ld r3,last_task_used_math at got(r2) - ld r4,0(r3) - cmpdi 0,r4,0 - beq 1f - /* Save FP state to last_task_used_math's THREAD struct */ - addi r4,r4,THREAD - SAVE_32FPRS(0, r4) - mffs fr0 - stfd fr0,THREAD_FPSCR(r4) - /* Disable FP for last_task_used_math */ - ld r5,PT_REGS(r4) - ld r4,_MSR-STACK_FRAME_OVERHEAD(r5) - li r6,MSR_FP|MSR_FE0|MSR_FE1 - andc r4,r4,r6 - std r4,_MSR-STACK_FRAME_OVERHEAD(r5) -1: -#endif /* CONFIG_SMP */ - /* enable use of FP after return */ - ld r4,PACACURRENT(r13) - addi r5,r4,THREAD /* Get THREAD */ - ld r4,THREAD_FPEXC_MODE(r5) - ori r12,r12,MSR_FP - or r12,r12,r4 - std r12,_MSR(r1) - lfd fr0,THREAD_FPSCR(r5) - mtfsf 0xff,fr0 - REST_32FPRS(0, r5) -#ifndef CONFIG_SMP - /* Update last_task_used_math to 'current' */ - subi r4,r5,THREAD /* Back to 'current' */ - std r4,0(r3) -#endif /* CONFIG_SMP */ - /* restore registers and return */ - b fast_exception_return - -/* * disable_kernel_fp() * Disable the FPU. */ @@ -1515,81 +1584,7 @@ #endif /* CONFIG_SMP */ blr - #ifdef CONFIG_ALTIVEC - -/* - * load_up_altivec(unused, unused, tsk) - * Disable VMX for the task which had it previously, - * and save its vector registers in its thread_struct. - * Enables the VMX for use in the kernel on return. - * On SMP we know the VMX is free, since we give it up every - * switch (ie, no lazy save of the vector registers). - * On entry: r13 == 'current' && last_task_used_altivec != 'current' - */ -_STATIC(load_up_altivec) - mfmsr r5 /* grab the current MSR */ - oris r5,r5,MSR_VEC at h - mtmsrd r5 /* enable use of VMX now */ - isync - -/* - * For SMP, we don't do lazy VMX switching because it just gets too - * horrendously complex, especially when a task switches from one CPU - * to another. Instead we call giveup_altvec in switch_to. - * VRSAVE isn't dealt with here, that is done in the normal context - * switch code. Note that we could rely on vrsave value to eventually - * avoid saving all of the VREGs here... - */ -#ifndef CONFIG_SMP - ld r3,last_task_used_altivec at got(r2) - ld r4,0(r3) - cmpdi 0,r4,0 - beq 1f - /* Save VMX state to last_task_used_altivec's THREAD struct */ - addi r4,r4,THREAD - SAVE_32VRS(0,r5,r4) - mfvscr vr0 - li r10,THREAD_VSCR - stvx vr0,r10,r4 - /* Disable VMX for last_task_used_altivec */ - ld r5,PT_REGS(r4) - ld r4,_MSR-STACK_FRAME_OVERHEAD(r5) - lis r6,MSR_VEC at h - andc r4,r4,r6 - std r4,_MSR-STACK_FRAME_OVERHEAD(r5) -1: -#endif /* CONFIG_SMP */ - /* Hack: if we get an altivec unavailable trap with VRSAVE - * set to all zeros, we assume this is a broken application - * that fails to set it properly, and thus we switch it to - * all 1's - */ - mfspr r4,SPRN_VRSAVE - cmpdi 0,r4,0 - bne+ 1f - li r4,-1 - mtspr SPRN_VRSAVE,r4 -1: - /* enable use of VMX after return */ - ld r4,PACACURRENT(r13) - addi r5,r4,THREAD /* Get THREAD */ - oris r12,r12,MSR_VEC at h - std r12,_MSR(r1) - li r4,1 - li r10,THREAD_VSCR - stw r4,THREAD_USED_VR(r5) - lvx vr0,r10,r5 - mtvscr vr0 - REST_32VRS(0,r4,r5) -#ifndef CONFIG_SMP - /* Update last_task_used_math to 'current' */ - subi r4,r5,THREAD /* Back to 'current' */ - std r4,0(r3) -#endif /* CONFIG_SMP */ - /* restore registers and return */ - b fast_exception_return - /* * disable_kernel_altivec() * Disable the VMX. From david at gibson.dropbear.id.au Fri Aug 19 14:52:31 2005 From: david at gibson.dropbear.id.au (David Gibson) Date: Fri, 19 Aug 2005 14:52:31 +1000 (EST) Subject: [PATCH 3/8] Change address of ppc64 initial segment table In-Reply-To: <20050819044900.GC17814@localhost.localdomain> Message-ID: <20050819045231.EAC41680AB@ozlabs.org> On ppc64 machines with segment tables, CPU0's segment table is at a fixed address, currently 0x9000. This patch moves it to the free space at 0x6000, just below the fwnmi data area. This saves 8k of space in vmlinux and the runtime kernel image. Signed-off-by: David Gibson --- arch/ppc64/kernel/head.S | 32 +++++++++++++++++--------------- arch/ppc64/kernel/pacaData.c | 4 ++-- include/asm-ppc64/mmu.h | 7 +++++-- 3 files changed, 24 insertions(+), 19 deletions(-) Index: working-2.6/arch/ppc64/kernel/head.S =================================================================== --- working-2.6.orig/arch/ppc64/kernel/head.S 2005-08-19 14:37:04.000000000 +1000 +++ working-2.6/arch/ppc64/kernel/head.S 2005-08-19 14:37:38.000000000 +1000 @@ -52,9 +52,10 @@ * We layout physical memory as follows: * 0x0000 - 0x00ff : Secondary processor spin code * 0x0100 - 0x2fff : pSeries Interrupt prologs - * 0x3000 - 0x6fff : interrupt support, iSeries and common interrupt prologs + * 0x3000 - 0x5fff : interrupt support, iSeries and common interrupt prologs + * 0x6000 - 0x6fff : Initial (CPU0) segment table * 0x7000 - 0x7fff : FWNMI data area - * 0x9000 - 0x9fff : Initial segment table + * 0x8000 - : Early init and support code */ /* @@ -1257,6 +1258,20 @@ b 1b /* + * Space for CPU0's segment table. + * + * On iSeries, the hypervisor must fill in at least one entry before + * we get control (with relocate on). The address is give to the hv + * as a page number (see xLparMap in LparData.c), so this must be at a + * fixed address (the linker can't compute (u64)&initial_stab >> + * PAGE_SHIFT). + */ + . = STAB0_PHYS_ADDR /* 0x6000 */ + .globl initial_stab +initial_stab: + .space 4096 + +/* * Data area reserved for FWNMI option. * This address (0x7000) is fixed by the RPA. */ @@ -1265,19 +1280,6 @@ fwnmi_data_area: .space PAGE_SIZE - /* - * Space for the initial segment table - * For LPAR, the hypervisor must fill in at least one entry - * before we get control (with relocate on) - */ - . = STAB0_PHYS_ADDR - .globl __start_stab -__start_stab: - - . = (STAB0_PHYS_ADDR + PAGE_SIZE) - .globl __end_stab -__end_stab: - /* * On pSeries, secondary processors spin in the following code. * At entry, r3 = this processor's number (physical cpu id) Index: working-2.6/arch/ppc64/kernel/pacaData.c =================================================================== --- working-2.6.orig/arch/ppc64/kernel/pacaData.c 2005-07-28 16:43:46.000000000 +1000 +++ working-2.6/arch/ppc64/kernel/pacaData.c 2005-08-19 14:37:38.000000000 +1000 @@ -78,7 +78,7 @@ #define BOOTCPU_PACA_INIT(number) \ { \ - PACA_INIT_COMMON(number, 1, 0, STAB0_VIRT_ADDR) \ + PACA_INIT_COMMON(number, 1, 0, (u64)&initial_stab) \ PACA_INIT_ISERIES(number) \ } @@ -90,7 +90,7 @@ #define BOOTCPU_PACA_INIT(number) \ { \ - PACA_INIT_COMMON(number, 1, STAB0_PHYS_ADDR, STAB0_VIRT_ADDR) \ + PACA_INIT_COMMON(number, 1, STAB0_PHYS_ADDR, (u64)&initial_stab) \ } #endif Index: working-2.6/include/asm-ppc64/mmu.h =================================================================== --- working-2.6.orig/include/asm-ppc64/mmu.h 2005-08-01 10:50:46.000000000 +1000 +++ working-2.6/include/asm-ppc64/mmu.h 2005-08-19 14:37:38.000000000 +1000 @@ -28,9 +28,12 @@ #define STE_VSID_SHIFT 12 /* Location of cpu0's segment table */ -#define STAB0_PAGE 0x9 +#define STAB0_PAGE 0x6 #define STAB0_PHYS_ADDR (STAB0_PAGE< Message-ID: <20050819045231.020AB680A5@ozlabs.org> As well as the interrupt vectors and initialization code, head.S contains several asm functions which are used during runtime. This patch moves these to misc.S, a more sensible location for random asm support code. A couple The functions moved are: disable_kernel_fp giveup_fpu disable_kernel_altivec giveup_altivec __setup_cpu_power3 (empty function) Signed-off-by: David Gibson --- arch/ppc64/kernel/head.S | 95 --------------------------------------------- arch/ppc64/kernel/misc.S | 98 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 98 insertions(+), 95 deletions(-) Index: working-2.6/arch/ppc64/kernel/head.S =================================================================== --- working-2.6.orig/arch/ppc64/kernel/head.S 2005-08-19 14:37:38.000000000 +1000 +++ working-2.6/arch/ppc64/kernel/head.S 2005-08-19 14:37:40.000000000 +1000 @@ -1542,98 +1542,6 @@ .align 8 copy_to_here: -/* - * disable_kernel_fp() - * Disable the FPU. - */ -_GLOBAL(disable_kernel_fp) - mfmsr r3 - rldicl r0,r3,(63-MSR_FP_LG),1 - rldicl r3,r0,(MSR_FP_LG+1),0 - mtmsrd r3 /* disable use of fpu now */ - isync - blr - -/* - * giveup_fpu(tsk) - * Disable FP for the task given as the argument, - * and save the floating-point registers in its thread_struct. - * Enables the FPU for use in the kernel on return. - */ -_GLOBAL(giveup_fpu) - mfmsr r5 - ori r5,r5,MSR_FP - mtmsrd r5 /* enable use of fpu now */ - isync - cmpdi 0,r3,0 - beqlr- /* if no previous owner, done */ - addi r3,r3,THREAD /* want THREAD of task */ - ld r5,PT_REGS(r3) - cmpdi 0,r5,0 - SAVE_32FPRS(0, r3) - mffs fr0 - stfd fr0,THREAD_FPSCR(r3) - beq 1f - ld r4,_MSR-STACK_FRAME_OVERHEAD(r5) - li r3,MSR_FP|MSR_FE0|MSR_FE1 - andc r4,r4,r3 /* disable FP for previous task */ - std r4,_MSR-STACK_FRAME_OVERHEAD(r5) -1: -#ifndef CONFIG_SMP - li r5,0 - ld r4,last_task_used_math at got(r2) - std r5,0(r4) -#endif /* CONFIG_SMP */ - blr - -#ifdef CONFIG_ALTIVEC -/* - * disable_kernel_altivec() - * Disable the VMX. - */ -_GLOBAL(disable_kernel_altivec) - mfmsr r3 - rldicl r0,r3,(63-MSR_VEC_LG),1 - rldicl r3,r0,(MSR_VEC_LG+1),0 - mtmsrd r3 /* disable use of VMX now */ - isync - blr - -/* - * giveup_altivec(tsk) - * Disable VMX for the task given as the argument, - * and save the vector registers in its thread_struct. - * Enables the VMX for use in the kernel on return. - */ -_GLOBAL(giveup_altivec) - mfmsr r5 - oris r5,r5,MSR_VEC at h - mtmsrd r5 /* enable use of VMX now */ - isync - cmpdi 0,r3,0 - beqlr- /* if no previous owner, done */ - addi r3,r3,THREAD /* want THREAD of task */ - ld r5,PT_REGS(r3) - cmpdi 0,r5,0 - SAVE_32VRS(0,r4,r3) - mfvscr vr0 - li r4,THREAD_VSCR - stvx vr0,r4,r3 - beq 1f - ld r4,_MSR-STACK_FRAME_OVERHEAD(r5) - lis r3,MSR_VEC at h - andc r4,r4,r3 /* disable FP for previous task */ - std r4,_MSR-STACK_FRAME_OVERHEAD(r5) -1: -#ifndef CONFIG_SMP - li r5,0 - ld r4,last_task_used_altivec at got(r2) - std r5,0(r4) -#endif /* CONFIG_SMP */ - blr - -#endif /* CONFIG_ALTIVEC */ - #ifdef CONFIG_SMP #ifdef CONFIG_PPC_PMAC /* @@ -1984,9 +1892,6 @@ bl .start_kernel -_GLOBAL(__setup_cpu_power3) - blr - _GLOBAL(hmt_init) #ifdef CONFIG_HMT LOADADDR(r5, hmt_thread_data) Index: working-2.6/arch/ppc64/kernel/misc.S =================================================================== --- working-2.6.orig/arch/ppc64/kernel/misc.S 2005-08-19 14:34:21.000000000 +1000 +++ working-2.6/arch/ppc64/kernel/misc.S 2005-08-19 14:37:40.000000000 +1000 @@ -680,6 +680,104 @@ ld r30,-16(r1) blr +/* + * disable_kernel_fp() + * Disable the FPU. + */ +_GLOBAL(disable_kernel_fp) + mfmsr r3 + rldicl r0,r3,(63-MSR_FP_LG),1 + rldicl r3,r0,(MSR_FP_LG+1),0 + mtmsrd r3 /* disable use of fpu now */ + isync + blr + +/* + * giveup_fpu(tsk) + * Disable FP for the task given as the argument, + * and save the floating-point registers in its thread_struct. + * Enables the FPU for use in the kernel on return. + */ +_GLOBAL(giveup_fpu) + mfmsr r5 + ori r5,r5,MSR_FP + mtmsrd r5 /* enable use of fpu now */ + isync + cmpdi 0,r3,0 + beqlr- /* if no previous owner, done */ + addi r3,r3,THREAD /* want THREAD of task */ + ld r5,PT_REGS(r3) + cmpdi 0,r5,0 + SAVE_32FPRS(0, r3) + mffs fr0 + stfd fr0,THREAD_FPSCR(r3) + beq 1f + ld r4,_MSR-STACK_FRAME_OVERHEAD(r5) + li r3,MSR_FP|MSR_FE0|MSR_FE1 + andc r4,r4,r3 /* disable FP for previous task */ + std r4,_MSR-STACK_FRAME_OVERHEAD(r5) +1: +#ifndef CONFIG_SMP + li r5,0 + ld r4,last_task_used_math at got(r2) + std r5,0(r4) +#endif /* CONFIG_SMP */ + blr + +#ifdef CONFIG_ALTIVEC + +#if 0 /* this has no callers for now */ +/* + * disable_kernel_altivec() + * Disable the VMX. + */ +_GLOBAL(disable_kernel_altivec) + mfmsr r3 + rldicl r0,r3,(63-MSR_VEC_LG),1 + rldicl r3,r0,(MSR_VEC_LG+1),0 + mtmsrd r3 /* disable use of VMX now */ + isync + blr +#endif /* 0 */ + +/* + * giveup_altivec(tsk) + * Disable VMX for the task given as the argument, + * and save the vector registers in its thread_struct. + * Enables the VMX for use in the kernel on return. + */ +_GLOBAL(giveup_altivec) + mfmsr r5 + oris r5,r5,MSR_VEC at h + mtmsrd r5 /* enable use of VMX now */ + isync + cmpdi 0,r3,0 + beqlr- /* if no previous owner, done */ + addi r3,r3,THREAD /* want THREAD of task */ + ld r5,PT_REGS(r3) + cmpdi 0,r5,0 + SAVE_32VRS(0,r4,r3) + mfvscr vr0 + li r4,THREAD_VSCR + stvx vr0,r4,r3 + beq 1f + ld r4,_MSR-STACK_FRAME_OVERHEAD(r5) + lis r3,MSR_VEC at h + andc r4,r4,r3 /* disable FP for previous task */ + std r4,_MSR-STACK_FRAME_OVERHEAD(r5) +1: +#ifndef CONFIG_SMP + li r5,0 + ld r4,last_task_used_altivec at got(r2) + std r5,0(r4) +#endif /* CONFIG_SMP */ + blr + +#endif /* CONFIG_ALTIVEC */ + +_GLOBAL(__setup_cpu_power3) + blr + /* kexec_wait(phys_cpu) * * wait for the flag to change, indicating this kernel is going away but From david at gibson.dropbear.id.au Fri Aug 19 14:52:32 2005 From: david at gibson.dropbear.id.au (David Gibson) Date: Fri, 19 Aug 2005 14:52:32 +1000 (EST) Subject: [PATCH 5/8] Fix apparent code overlap in ppc64 head.S In-Reply-To: <20050819044900.GC17814@localhost.localdomain> Message-ID: <20050819045232.2AA40680AD@ozlabs.org> An #if/#else construct near the top of ppc64's head.S appears to create overlapping sections of code for iSeries and pSeries (i.e. one thing on iSeries and something different in the same place on pSeries). In fact, checking the various absolute offsets, it doesn't. This patch unravels the #ifdefs to make it more obvious what's going on. This accomplishes another microstep towards a single kernel image which can boot both iSeries and pSeries. Signed-off-by: David Gibson --- arch/ppc64/kernel/head.S | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: working-2.6/arch/ppc64/kernel/head.S =================================================================== --- working-2.6.orig/arch/ppc64/kernel/head.S 2005-08-19 14:37:40.000000000 +1000 +++ working-2.6/arch/ppc64/kernel/head.S 2005-08-19 14:37:42.000000000 +1000 @@ -93,6 +93,7 @@ /* Catch branch to 0 in real mode */ trap + #ifdef CONFIG_PPC_ISERIES /* * At offset 0x20, there is a pointer to iSeries LPAR data. @@ -119,7 +120,7 @@ embedded_sysmap_end: .llong 0 -#else /* CONFIG_PPC_ISERIES */ +#endif /* CONFIG_PPC_ISERIES */ /* Secondary processors spin on this value until it goes to 1. */ .globl __secondary_hold_spinloop @@ -169,7 +170,6 @@ BUG_OPCODE #endif #endif -#endif /* This value is used to mark exception frames on the stack. */ .section ".toc","aw" From david at gibson.dropbear.id.au Fri Aug 19 14:52:32 2005 From: david at gibson.dropbear.id.au (David Gibson) Date: Fri, 19 Aug 2005 14:52:32 +1000 (EST) Subject: [PATCH 6/8] Remove unneeded #defines in head.S In-Reply-To: <20050819044900.GC17814@localhost.localdomain> Message-ID: <20050819045232.3796A680AE@ozlabs.org> arch/ppc64/kernel/head.S #defines SECONDARY_PROCESSORS then has some #ifdefs based on it. Whatever purpose this had is long lost, this patch removes it. Likewise, head.S defines H_SET_ASR, which is now defined, along with other hypervisor call numbers in hvcall.h. This patch deletes it, as well, from head.S. Signed-off-by: David Gibson --- arch/ppc64/kernel/head.S | 11 ----------- 1 files changed, 11 deletions(-) Index: working-2.6/arch/ppc64/kernel/head.S =================================================================== --- working-2.6.orig/arch/ppc64/kernel/head.S 2005-08-19 14:37:42.000000000 +1000 +++ working-2.6/arch/ppc64/kernel/head.S 2005-08-19 14:37:45.000000000 +1000 @@ -23,8 +23,6 @@ * 2 of the License, or (at your option) any later version. */ -#define SECONDARY_PROCESSORS - #include #include #include @@ -44,11 +42,6 @@ #endif /* - * hcall interface to pSeries LPAR - */ -#define H_SET_ASR 0x30 - -/* * We layout physical memory as follows: * 0x0000 - 0x00ff : Secondary processor spin code * 0x0100 - 0x2fff : pSeries Interrupt prologs @@ -629,9 +622,7 @@ cmpwi 0,r23,0 beq iSeries_secondary_smp_loop /* Loop until told to go */ -#ifdef SECONDARY_PROCESSORS bne .__secondary_start /* Loop until told to go */ -#endif iSeries_secondary_smp_loop: /* Let the Hypervisor know we are alive */ /* 8002 is a call to HvCallCfg::getLps, a harmless Hypervisor function */ @@ -1325,10 +1316,8 @@ cmpwi 0,r23,0 #ifdef CONFIG_SMP -#ifdef SECONDARY_PROCESSORS bne .__secondary_start #endif -#endif b 3b /* Loop until told to go */ #ifdef CONFIG_PPC_ISERIES From david at gibson.dropbear.id.au Fri Aug 19 14:52:32 2005 From: david at gibson.dropbear.id.au (David Gibson) Date: Fri, 19 Aug 2005 14:52:32 +1000 (EST) Subject: [PATCH 7/8] Tweak comments in ppc64 head.S In-Reply-To: <20050819044900.GC17814@localhost.localdomain> Message-ID: <20050819045232.5A3E2680B3@ozlabs.org> This patch adjust some comments in head.S for accuracy, clarity, and spelling. Signed-off-by: David Gibson --- arch/ppc64/kernel/head.S | 8 ++++---- 1 files changed, 4 insertions(+), 4 deletions(-) Index: working-2.6/arch/ppc64/kernel/head.S =================================================================== --- working-2.6.orig/arch/ppc64/kernel/head.S 2005-08-19 14:37:45.000000000 +1000 +++ working-2.6/arch/ppc64/kernel/head.S 2005-08-19 14:37:47.000000000 +1000 @@ -148,7 +148,7 @@ std r24,__secondary_hold_acknowledge at l(0) sync - /* All secondary cpu's wait here until told to start. */ + /* All secondary cpus wait here until told to start. */ 100: ld r4,__secondary_hold_spinloop at l(0) cmpdi 0,r4,1 bne 100b @@ -703,8 +703,8 @@ * R9 contains the saved CR, r13 points to the paca, * r10 contains the (bad) kernel stack pointer, * r11 and r12 contain the saved SRR0 and SRR1. - * We switch to using the paca guard page as an emergency stack, - * save the registers there, and call kernel_bad_stack(), which panics. + * We switch to using an emergency stack, save the registers there, + * and call kernel_bad_stack(), which panics. */ bad_stack: ld r1,PACAEMERGSP(r13) @@ -1303,7 +1303,7 @@ b .kexec_wait /* next kernel might do better */ 2: mtspr SPRG3,r13 /* Save vaddr of paca in SPRG3 */ - /* From now on, r24 is expected to be logica cpuid */ + /* From now on, r24 is expected to be logical cpuid */ mr r24,r5 3: HMT_LOW lbz r23,PACAPROCSTART(r13) /* Test if this processor should */ From david at gibson.dropbear.id.au Fri Aug 19 14:52:32 2005 From: david at gibson.dropbear.id.au (David Gibson) Date: Fri, 19 Aug 2005 14:52:32 +1000 (EST) Subject: [PATCH 8/8] Move variables in ppc64 head.S from .data to .bss In-Reply-To: <20050819044900.GC17814@localhost.localdomain> Message-ID: <20050819045232.8D4F5680B5@ozlabs.org> The ppc64 head.S defines several zero-initialized structures, such as the empty_zero_page and the kernel top-level pagetable. Currently they are defined to be in the data section. However, they're not used until after the bss is cleared, so this patch moves them to the bss, saving two and a half pages from the vmlinux. Signed-off-by: David Gibson --- arch/ppc64/kernel/head.S | 13 ++++++------- 1 files changed, 6 insertions(+), 7 deletions(-) Index: working-2.6/arch/ppc64/kernel/head.S =================================================================== --- working-2.6.orig/arch/ppc64/kernel/head.S 2005-08-19 14:37:47.000000000 +1000 +++ working-2.6/arch/ppc64/kernel/head.S 2005-08-19 14:37:49.000000000 +1000 @@ -1971,20 +1971,19 @@ /* * We put a few things here that have to be page-aligned. - * This stuff goes at the beginning of the data segment, - * which is page-aligned. + * This stuff goes at the beginning of the bss, which is page-aligned. */ - .data + .section ".bss" + .align 12 - .globl sdata -sdata: + .globl empty_zero_page empty_zero_page: - .space 4096 + .space PAGE_SIZE .globl swapper_pg_dir swapper_pg_dir: - .space 4096 + .space PAGE_SIZE /* * This space gets a copy of optional info passed to us by the bootstrap From matthias.hofer at arz.co.at Fri Aug 19 16:50:04 2005 From: matthias.hofer at arz.co.at (matthias.hofer at arz.co.at) Date: Fri, 19 Aug 2005 08:50:04 +0200 Subject: How to get out physc? In-Reply-To: Message-ID: Hi! > > I am using GNU/Linux (SLES9) on an IBM p5 right now and want to get out > > how much "physc" the LPAR consumes; on AIX, this can be accomplished > > with > > sar, vmstat, topas, nmon and mpstat. > > On GNU/Linux, I could not find any of these utilities in a Version that > > would show me such an info. > > So what is "physc"? On IBM Power5-Systems Logical Partitions use up the amount of CPU-time, that they really need. "physc" is the value that represents the amount of Physical CPUs that the LPAR consumes. On AIX, sar shows: $ sar AIX aix0003a 3 5 00C1D7DF4C00 08/19/05 System configuration: lcpu=4 ent=0.40 02:00:00 %usr %sys %wio %idle physc %entc 02:05:00 77 10 6 7 0.86 215.6 02:10:01 44 24 11 22 0.35 87.3 02:15:00 39 22 12 27 0.32 80.3 02:20:00 45 18 12 25 0.32 79.3 02:25:00 35 19 10 35 0.28 70.3 02:30:00 41 19 7 33 0.30 76.1 02:35:00 23 11 6 60 0.17 43.5 02:40:00 78 10 1 11 0.50 125.8 02:45:00 90 2 0 7 1.04 260.6 02:50:01 90 2 0 7 1.06 264.5 02:55:00 90 2 0 7 1.07 266.3 03:00:00 91 2 0 7 1.05 263.5 03:05:00 88 4 2 7 1.13 283.4 03:10:00 87 4 1 7 1.17 293.6 03:15:00 90 3 1 7 1.11 277.1 03:20:00 90 3 0 7 1.06 265.8 03:25:00 91 2 0 7 1.04 261.2 03:30:01 90 2 0 7 1.05 263.0 03:35:00 91 2 0 7 1.04 260.1 03:40:00 90 2 0 7 1.05 263.6 03:45:00 91 2 0 7 1.04 259.8 So, this LPAR used between 0.17 and 1.17 Physical CPUs at a given time. vmstat, for example, shows: $ vmstat 2 3 System configuration: lcpu=4 mem=5120MB ent=0.40 kthr memory page faults cpu ----- ----------- ------------------------ ------------ ----------------------- r b avm fre re pi po fr sr cy in sy cs us sy id wa pc ec 1 0 697996 457310 0 0 0 0 0 0 505 783 1276 88 3 8 1 1.07 266.4 2 0 697996 457310 0 0 0 0 0 0 731 2291 1680 88 4 7 2 1.12 280.7 2 0 697996 457310 0 0 0 0 0 0 1096 8121 2482 85 6 7 3 1.17 292.5 The next-to-last value is "physc" (pc). I found out that "nmon" is able to measure and show this value for the LPAR on GNU/Linux, but I hoped for something like sar, for historical data. Anybody confident with GNU/Linux on IBM-Power5 with Advanced Virtualization? Thank you! Matthias Hofer ---------------- Disclaimer: Diese Nachricht dient ausschlie?lich zu Informationszwecken und ist nur f?r den Gebrauch des Empf?ngers bestimmt. This message is only for informational purposes and is intended solely for the use of the addressee. ---------------- From jimix at watson.ibm.com Sun Aug 21 02:15:38 2005 From: jimix at watson.ibm.com (Jimi Xenidis) Date: Sat, 20 Aug 2005 12:15:38 -0400 Subject: systemcfg is now a pointer Message-ID: <17159.22314.387569.374706@kitch0.watson.ibm.com> The following patch "fixes" 2 issues: 1) systemcfg is now a pointer that needs to be deref'd 2) use PLATFORM_LPAR bit to test if running in LPAR mode let me know if you'd like separate diffs. Signed-off-by: Jimi Xenidis diff -r e783ced09546 arch/ppc64/kernel/head.S --- a/arch/ppc64/kernel/head.S Thu Aug 18 22:16:12 2005 +++ b/arch/ppc64/kernel/head.S Sat Aug 20 12:10:24 2005 @@ -1753,8 +1753,9 @@ #else /* set the ASR */ ld r3,systemcfg at got(r2) /* r3 = ptr to systemcfg */ + ld r3,0(r3) lwz r3,PLATFORM(r3) /* r3 = platform flags */ - cmpldi r3,PLATFORM_PSERIES_LPAR + andi. r3,r3,PLATFORM_LPAR /* Test if bit 0 is set (LPAR bit) */ bne 98f mfspr r3,PVR srwi r3,r3,16 @@ -1916,8 +1917,9 @@ ld r3,PACASTABREAL(r13) ori r4,r3,1 /* turn on valid bit */ ld r3,systemcfg at got(r2) /* r3 = ptr to systemcfg */ + ld r3,0(r3) lwz r3,PLATFORM(r3) /* r3 = platform flags */ - cmpldi r3,PLATFORM_PSERIES_LPAR + andi. r3,r3,PLATFORM_LPAR /* Test if bit 0 is set (LPAR bit) */ bne 98f mfspr r3,PVR srwi r3,r3,16 @@ -1935,9 +1937,10 @@ 99: /* Set SDR1 (hash table pointer) */ ld r3,systemcfg at 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,0x1 + andi. r3,r3,PLATFORM_LPAR bne 98f LOADADDR(r6,_SDR1) /* Only if NOT LPAR */ sub r6,r6,r26 From a.othieno at bluewin.ch Sun Aug 21 11:48:47 2005 From: a.othieno at bluewin.ch (Arthur Othieno) Date: Sat, 20 Aug 2005 21:48:47 -0400 Subject: [PATCH] ppc64: Big-endian I/O memory accessors. Message-ID: <20050821014847.GA31956@mars> I/O memory accessors. Big-endian version. For those busses/devices that do export big-endian I/O memory. Of notable relevance/reference: http://lwn.net/Articles/132804/ http://ozlabs.org/pipermail/linuxppc-embedded/2005-August/019798.html http://ozlabs.org/pipermail/linuxppc-embedded/2005-August/019752.html Signed-Off-By: Arthur Othieno iomap.c | 20 ++++++++++++++++++++ 1 files changed, 20 insertions(+) --- a/arch/ppc64/kernel/iomap.c 2005-08-20 19:23:12.000000000 -0400 +++ b/arch/ppc64/kernel/iomap.c 2005-08-20 21:35:42.000000000 -0400 @@ -22,13 +22,23 @@ unsigned int fastcall ioread16(void __io { return readw(addr); } +unsigned int fastcall ioread16be(void __iomem *addr) +{ + return __raw_readw(addr); +} unsigned int fastcall ioread32(void __iomem *addr) { return readl(addr); } +unsigned int fastcall ioread32be(void __iomem *addr) +{ + return __raw_readl(addr); +} EXPORT_SYMBOL(ioread8); EXPORT_SYMBOL(ioread16); +EXPORT_SYMBOL(ioread16be); EXPORT_SYMBOL(ioread32); +EXPORT_SYMBOL(ioread32be); void fastcall iowrite8(u8 val, void __iomem *addr) { @@ -38,13 +48,23 @@ void fastcall iowrite16(u16 val, void __ { writew(val, addr); } +void fastcall iowrite16be(u16 val, void __iomem *addr) +{ + __raw_writew(val, addr); +} void fastcall iowrite32(u32 val, void __iomem *addr) { writel(val, addr); } +void fastcall iowrite32be(u32 val, void __iomem *addr) +{ + __raw_writel(val, addr); +} EXPORT_SYMBOL(iowrite8); EXPORT_SYMBOL(iowrite16); +EXPORT_SYMBOL(iowrite16be); EXPORT_SYMBOL(iowrite32); +EXPORT_SYMBOL(iowrite32be); /* * These are the "repeat read/write" functions. Note the From benh at kernel.crashing.org Mon Aug 22 09:16:18 2005 From: benh at kernel.crashing.org (Benjamin Herrenschmidt) Date: Mon, 22 Aug 2005 09:16:18 +1000 Subject: [PATCH] ppc64: Big-endian I/O memory accessors. In-Reply-To: <20050821014847.GA31956@mars> References: <20050821014847.GA31956@mars> Message-ID: <1124666178.5198.123.camel@gaston> On Sat, 2005-08-20 at 21:48 -0400, Arthur Othieno wrote: > I/O memory accessors. Big-endian version. For those busses/devices > that do export big-endian I/O memory. > > Of notable re Same comment as the ppc32 ones. You need appropriate memory barriers among others. Use in/out_bexx() (look how readl/writel are implemented). Ben. From ntl at pobox.com Mon Aug 22 14:33:10 2005 From: ntl at pobox.com (Nathan Lynch) Date: Sun, 21 Aug 2005 23:33:10 -0500 Subject: [patch 2/2] PPC64: Janitorial: Remove unused, deprecated code In-Reply-To: <20050818195449.GV5553@austin.ibm.com> References: <20050818160453.748439000@bilge> <20050818160516.683730000@bilge> <20050818161944.GK1012@otto> <20050818195449.GV5553@austin.ibm.com> Message-ID: <20050822043310.GM1012@otto> Linas Vepstas wrote: > > > -EXPORT_SYMBOL(find_all_nodes); > > > > I don't think we're supposed to just rip out exported symbols without > > notice anymore. > > Oh, why not? I grepped, I can't find any users of this code anywhere. > Surely, there aren't any proprietary drivers calling this. It's not necessarily an issue of proprietary drivers but out-of-tree code in general which may be using the symbol. > > This is only one of a family of unofficially deprecated functions for > > traversing the OF device tree. > > I was thinking of asking if I should get rid of the other uses of the > other deprecated functions as well. So.. Should I? Yes, I think so. The old device tree API isn't safe to use on systems which support dynamic reconfiguration (which encompasses DLPAR and pci hotplug). However, the planned merge of ppc and ppc64 should be taken into account. ppc has its own copy of the old API, but it does have the new one... however, a brief grep through arch/ppc/kernel shows that it hasn't been converted to the new of_* functions. Paulus, does it seem reasonable to convert arch/ppc to the new of_* API and then omit the old device tree API from asm-powerpc/prom.h? From sfr at canb.auug.org.au Mon Aug 22 16:02:54 2005 From: sfr at canb.auug.org.au (Stephen Rothwell) Date: Mon, 22 Aug 2005 16:02:54 +1000 Subject: [PATCH 1/3] Create include/asm-powerpc Message-ID: <20050822160254.2dc59b25.sfr@canb.auug.org.au> Hopefully, we can gree to start like this ... Create include/asm-powerpc (and move linkage.h into it since we don't like empty directories). Modify the Makefiles to cope. Signed-off-by: Stephen Rothwell --- arch/ppc/Makefile | 11 ++++++++++- arch/ppc64/Makefile | 9 +++++++++ include/asm-powerpc/linkage.h | 6 ++++++ include/asm-ppc/linkage.h | 6 ------ include/asm-ppc64/linkage.h | 6 ------ 5 files changed, 25 insertions(+), 13 deletions(-) create mode 100644 include/asm-powerpc/linkage.h delete mode 100644 include/asm-ppc/linkage.h delete mode 100644 include/asm-ppc64/linkage.h -- Cheers, Stephen Rothwell sfr at canb.auug.org.au http://www.canb.auug.org.au/~sfr/ diff --git a/arch/ppc/Makefile b/arch/ppc/Makefile --- a/arch/ppc/Makefile +++ b/arch/ppc/Makefile @@ -21,11 +21,13 @@ CC := $(CC) -m32 endif LDFLAGS_vmlinux := -Ttext $(KERNELLOAD) -Bstatic -CPPFLAGS += -Iarch/$(ARCH) +CPPFLAGS += -Iarch/$(ARCH) -Iinclude3 AFLAGS += -Iarch/$(ARCH) CFLAGS += -Iarch/$(ARCH) -msoft-float -pipe \ -ffixed-r2 -mmultiple CPP = $(CC) -E $(CFLAGS) +# Temporary hack until we have migrated to asm-powerpc +LINUXINCLUDE += -Iinclude3 CHECKFLAGS += -D__powerpc__ @@ -101,6 +103,7 @@ endef archclean: $(Q)$(MAKE) $(clean)=arch/ppc/boot + $(Q)rm -rf include3 prepare: include/asm-$(ARCH)/offsets.h checkbin @@ -110,6 +113,12 @@ arch/$(ARCH)/kernel/asm-offsets.s: inclu include/asm-$(ARCH)/offsets.h: arch/$(ARCH)/kernel/asm-offsets.s $(call filechk,gen-asm-offsets) +# Temporary hack until we have migrated to asm-powerpc +include/asm: include3/asm +include3/asm: + $(Q)if [ ! -d include3 ]; then mkdir -p include3; fi + $(Q)ln -fsn $(srctree)/include/asm-powerpc include3/asm + # Use the file '.tmp_gas_check' for binutils tests, as gas won't output # to stdout and these checks are run even on install targets. TOUT := .tmp_gas_check diff --git a/arch/ppc64/Makefile b/arch/ppc64/Makefile --- a/arch/ppc64/Makefile +++ b/arch/ppc64/Makefile @@ -55,6 +55,8 @@ LDFLAGS := -m elf64ppc LDFLAGS_vmlinux := -Bstatic -e $(KERNELLOAD) -Ttext $(KERNELLOAD) CFLAGS += -msoft-float -pipe -mminimal-toc -mtraceback=none \ -mcall-aixdesc +# Temporary hack until we have migrated to asm-powerpc +CPPFLAGS += -Iinclude3 GCC_VERSION := $(call cc-version) GCC_BROKEN_VEC := $(shell if [ $(GCC_VERSION) -lt 0400 ] ; then echo "y"; fi ;) @@ -112,6 +114,7 @@ all: $(KBUILD_IMAGE) archclean: $(Q)$(MAKE) $(clean)=$(boot) + $(Q)rm -rf include3 prepare: include/asm-ppc64/offsets.h @@ -121,6 +124,12 @@ arch/ppc64/kernel/asm-offsets.s: include include/asm-ppc64/offsets.h: arch/ppc64/kernel/asm-offsets.s $(call filechk,gen-asm-offsets) +# Temporary hack until we have migrated to asm-powerpc +include/asm: include3/asm +include3/asm: + $(Q)if [ ! -d include3 ]; then mkdir -p include3; fi; + $(Q)ln -fsn $(srctree)/include/asm-powerpc include3/asm + define archhelp echo '* zImage - Compressed kernel image (arch/$(ARCH)/boot/zImage)' echo ' zImage.initrd- Compressed kernel image with initrd attached,' diff --git a/include/asm-powerpc/linkage.h b/include/asm-powerpc/linkage.h new file mode 100644 --- /dev/null +++ b/include/asm-powerpc/linkage.h @@ -0,0 +1,6 @@ +#ifndef __ASM_LINKAGE_H +#define __ASM_LINKAGE_H + +/* Nothing to see here... */ + +#endif diff --git a/include/asm-ppc/linkage.h b/include/asm-ppc/linkage.h deleted file mode 100644 --- a/include/asm-ppc/linkage.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __ASM_LINKAGE_H -#define __ASM_LINKAGE_H - -/* Nothing to see here... */ - -#endif diff --git a/include/asm-ppc64/linkage.h b/include/asm-ppc64/linkage.h deleted file mode 100644 --- a/include/asm-ppc64/linkage.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __ASM_LINKAGE_H -#define __ASM_LINKAGE_H - -/* Nothing to see here... */ - -#endif From sfr at canb.auug.org.au Mon Aug 22 16:05:19 2005 From: sfr at canb.auug.org.au (Stephen Rothwell) Date: Mon, 22 Aug 2005 16:05:19 +1000 Subject: [PATCH 2/3] Move the identical files from include/asm-ppc{,64} In-Reply-To: <20050822160254.2dc59b25.sfr@canb.auug.org.au> References: <20050822160254.2dc59b25.sfr@canb.auug.org.au> Message-ID: <20050822160519.51d065fe.sfr@canb.auug.org.au> Move the identical files from include/asm-ppc{,64}/ to include/asm-powerpc/. Remove hdreg.h completely as it is unused in the tree. Signed-off-by: Stephen Rothwell --- include/asm-powerpc/8253pit.h | 10 ++++++++++ include/asm-powerpc/agp.h | 23 +++++++++++++++++++++++ include/asm-powerpc/cputime.h | 1 + include/asm-powerpc/div64.h | 1 + include/asm-powerpc/emergency-restart.h | 1 + include/asm-powerpc/ipc.h | 1 + include/asm-powerpc/xor.h | 1 + include/asm-ppc/8253pit.h | 10 ---------- include/asm-ppc/agp.h | 23 ----------------------- include/asm-ppc/cputime.h | 6 ------ include/asm-ppc/div64.h | 1 - include/asm-ppc/emergency-restart.h | 6 ------ include/asm-ppc/hdreg.h | 1 - include/asm-ppc/ipc.h | 1 - include/asm-ppc/xor.h | 1 - include/asm-ppc64/8253pit.h | 10 ---------- include/asm-ppc64/agp.h | 23 ----------------------- include/asm-ppc64/cputime.h | 6 ------ include/asm-ppc64/div64.h | 1 - include/asm-ppc64/emergency-restart.h | 6 ------ include/asm-ppc64/hdreg.h | 1 - include/asm-ppc64/ipc.h | 1 - include/asm-ppc64/xor.h | 1 - 23 files changed, 38 insertions(+), 98 deletions(-) -- Cheers, Stephen Rothwell sfr at canb.auug.org.au http://www.canb.auug.org.au/~sfr/ diff --git a/include/asm-powerpc/8253pit.h b/include/asm-powerpc/8253pit.h new file mode 100644 --- /dev/null +++ b/include/asm-powerpc/8253pit.h @@ -0,0 +1,10 @@ +/* + * 8253/8254 Programmable Interval Timer + */ + +#ifndef _8253PIT_H +#define _8253PIT_H + +#define PIT_TICK_RATE 1193182UL + +#endif diff --git a/include/asm-powerpc/agp.h b/include/asm-powerpc/agp.h new file mode 100644 --- /dev/null +++ b/include/asm-powerpc/agp.h @@ -0,0 +1,23 @@ +#ifndef AGP_H +#define AGP_H 1 + +#include + +/* nothing much needed here */ + +#define map_page_into_agp(page) +#define unmap_page_from_agp(page) +#define flush_agp_mappings() +#define flush_agp_cache() mb() + +/* Convert a physical address to an address suitable for the GART. */ +#define phys_to_gart(x) (x) +#define gart_to_phys(x) (x) + +/* GATT allocation. Returns/accepts GATT kernel virtual address. */ +#define alloc_gatt_pages(order) \ + ((char *)__get_free_pages(GFP_KERNEL, (order))) +#define free_gatt_pages(table, order) \ + free_pages((unsigned long)(table), (order)) + +#endif diff --git a/include/asm-powerpc/cputime.h b/include/asm-powerpc/cputime.h new file mode 100644 --- /dev/null +++ b/include/asm-powerpc/cputime.h @@ -0,0 +1 @@ +#include diff --git a/include/asm-powerpc/div64.h b/include/asm-powerpc/div64.h new file mode 100644 --- /dev/null +++ b/include/asm-powerpc/div64.h @@ -0,0 +1 @@ +#include diff --git a/include/asm-powerpc/emergency-restart.h b/include/asm-powerpc/emergency-restart.h new file mode 100644 --- /dev/null +++ b/include/asm-powerpc/emergency-restart.h @@ -0,0 +1 @@ +#include diff --git a/include/asm-powerpc/ipc.h b/include/asm-powerpc/ipc.h new file mode 100644 --- /dev/null +++ b/include/asm-powerpc/ipc.h @@ -0,0 +1 @@ +#include diff --git a/include/asm-powerpc/xor.h b/include/asm-powerpc/xor.h new file mode 100644 --- /dev/null +++ b/include/asm-powerpc/xor.h @@ -0,0 +1 @@ +#include diff --git a/include/asm-ppc/8253pit.h b/include/asm-ppc/8253pit.h deleted file mode 100644 --- a/include/asm-ppc/8253pit.h +++ /dev/null @@ -1,10 +0,0 @@ -/* - * 8253/8254 Programmable Interval Timer - */ - -#ifndef _8253PIT_H -#define _8253PIT_H - -#define PIT_TICK_RATE 1193182UL - -#endif diff --git a/include/asm-ppc/agp.h b/include/asm-ppc/agp.h deleted file mode 100644 --- a/include/asm-ppc/agp.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef AGP_H -#define AGP_H 1 - -#include - -/* nothing much needed here */ - -#define map_page_into_agp(page) -#define unmap_page_from_agp(page) -#define flush_agp_mappings() -#define flush_agp_cache() mb() - -/* Convert a physical address to an address suitable for the GART. */ -#define phys_to_gart(x) (x) -#define gart_to_phys(x) (x) - -/* GATT allocation. Returns/accepts GATT kernel virtual address. */ -#define alloc_gatt_pages(order) \ - ((char *)__get_free_pages(GFP_KERNEL, (order))) -#define free_gatt_pages(table, order) \ - free_pages((unsigned long)(table), (order)) - -#endif diff --git a/include/asm-ppc/cputime.h b/include/asm-ppc/cputime.h deleted file mode 100644 --- a/include/asm-ppc/cputime.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __PPC_CPUTIME_H -#define __PPC_CPUTIME_H - -#include - -#endif /* __PPC_CPUTIME_H */ diff --git a/include/asm-ppc/div64.h b/include/asm-ppc/div64.h deleted file mode 100644 --- a/include/asm-ppc/div64.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/include/asm-ppc/emergency-restart.h b/include/asm-ppc/emergency-restart.h deleted file mode 100644 --- a/include/asm-ppc/emergency-restart.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _ASM_EMERGENCY_RESTART_H -#define _ASM_EMERGENCY_RESTART_H - -#include - -#endif /* _ASM_EMERGENCY_RESTART_H */ diff --git a/include/asm-ppc/hdreg.h b/include/asm-ppc/hdreg.h deleted file mode 100644 --- a/include/asm-ppc/hdreg.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/include/asm-ppc/ipc.h b/include/asm-ppc/ipc.h deleted file mode 100644 --- a/include/asm-ppc/ipc.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/include/asm-ppc/xor.h b/include/asm-ppc/xor.h deleted file mode 100644 --- a/include/asm-ppc/xor.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/include/asm-ppc64/8253pit.h b/include/asm-ppc64/8253pit.h deleted file mode 100644 --- a/include/asm-ppc64/8253pit.h +++ /dev/null @@ -1,10 +0,0 @@ -/* - * 8253/8254 Programmable Interval Timer - */ - -#ifndef _8253PIT_H -#define _8253PIT_H - -#define PIT_TICK_RATE 1193182UL - -#endif diff --git a/include/asm-ppc64/agp.h b/include/asm-ppc64/agp.h deleted file mode 100644 --- a/include/asm-ppc64/agp.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef AGP_H -#define AGP_H 1 - -#include - -/* nothing much needed here */ - -#define map_page_into_agp(page) -#define unmap_page_from_agp(page) -#define flush_agp_mappings() -#define flush_agp_cache() mb() - -/* Convert a physical address to an address suitable for the GART. */ -#define phys_to_gart(x) (x) -#define gart_to_phys(x) (x) - -/* GATT allocation. Returns/accepts GATT kernel virtual address. */ -#define alloc_gatt_pages(order) \ - ((char *)__get_free_pages(GFP_KERNEL, (order))) -#define free_gatt_pages(table, order) \ - free_pages((unsigned long)(table), (order)) - -#endif diff --git a/include/asm-ppc64/cputime.h b/include/asm-ppc64/cputime.h deleted file mode 100644 --- a/include/asm-ppc64/cputime.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __PPC_CPUTIME_H -#define __PPC_CPUTIME_H - -#include - -#endif /* __PPC_CPUTIME_H */ diff --git a/include/asm-ppc64/div64.h b/include/asm-ppc64/div64.h deleted file mode 100644 --- a/include/asm-ppc64/div64.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/include/asm-ppc64/emergency-restart.h b/include/asm-ppc64/emergency-restart.h deleted file mode 100644 --- a/include/asm-ppc64/emergency-restart.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _ASM_EMERGENCY_RESTART_H -#define _ASM_EMERGENCY_RESTART_H - -#include - -#endif /* _ASM_EMERGENCY_RESTART_H */ diff --git a/include/asm-ppc64/hdreg.h b/include/asm-ppc64/hdreg.h deleted file mode 100644 --- a/include/asm-ppc64/hdreg.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/include/asm-ppc64/ipc.h b/include/asm-ppc64/ipc.h deleted file mode 100644 --- a/include/asm-ppc64/ipc.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/include/asm-ppc64/xor.h b/include/asm-ppc64/xor.h deleted file mode 100644 --- a/include/asm-ppc64/xor.h +++ /dev/null @@ -1 +0,0 @@ -#include From sfr at canb.auug.org.au Mon Aug 22 16:10:30 2005 From: sfr at canb.auug.org.au (Stephen Rothwell) Date: Mon, 22 Aug 2005 16:10:30 +1000 Subject: [PATCH 3/3] Move all the very similar files In-Reply-To: <20050822160519.51d065fe.sfr@canb.auug.org.au> References: <20050822160254.2dc59b25.sfr@canb.auug.org.au> <20050822160519.51d065fe.sfr@canb.auug.org.au> Message-ID: <20050822161030.4082716d.sfr@canb.auug.org.au> This moves all the very similar files - either the ppc64 file included the ppc file or they differed in simple comments. Signed-off-by: Stephen Rothwell --- This patch is too large for the list, so it is available at http://ozlabs.org/~sfr/0003-This-moves-all-the-very-similar-files-either-the-ppc64-file-included.txt include/asm-powerpc/dbdma.h | 102 ++++++++++ include/asm-powerpc/errno.h | 11 + include/asm-powerpc/ioctl.h | 69 +++++++ include/asm-powerpc/ioctls.h | 107 ++++++++++ include/asm-powerpc/keylargo.h | 248 ++++++++++++++++++++++++ include/asm-powerpc/local.h | 1 include/asm-powerpc/macio.h | 141 +++++++++++++ include/asm-powerpc/namei.h | 20 ++ include/asm-powerpc/of_device.h | 62 ++++++ include/asm-powerpc/parport.h | 18 ++ include/asm-powerpc/percpu.h | 1 include/asm-powerpc/pmac_feature.h | 379 ++++++++++++++++++++++++++++++++++++ include/asm-powerpc/pmac_low_i2c.h | 43 ++++ include/asm-powerpc/poll.h | 23 ++ include/asm-powerpc/resource.h | 1 include/asm-powerpc/shmparam.h | 6 + include/asm-powerpc/string.h | 32 +++ include/asm-powerpc/unaligned.h | 18 ++ include/asm-powerpc/uninorth.h | 229 ++++++++++++++++++++++ include/asm-ppc/dbdma.h | 102 ---------- include/asm-ppc/errno.h | 11 - include/asm-ppc/ioctl.h | 69 ------- include/asm-ppc/ioctls.h | 107 ---------- include/asm-ppc/keylargo.h | 248 ------------------------ include/asm-ppc/local.h | 6 - include/asm-ppc/macio.h | 141 ------------- include/asm-ppc/namei.h | 20 -- include/asm-ppc/of_device.h | 62 ------ include/asm-ppc/parport.h | 18 -- include/asm-ppc/percpu.h | 6 - include/asm-ppc/pmac_feature.h | 379 ------------------------------------ include/asm-ppc/pmac_low_i2c.h | 43 ---- include/asm-ppc/poll.h | 23 -- include/asm-ppc/resource.h | 6 - include/asm-ppc/shmparam.h | 6 - include/asm-ppc/string.h | 32 --- include/asm-ppc/unaligned.h | 18 -- include/asm-ppc/uninorth.h | 229 ---------------------- include/asm-ppc64/dbdma.h | 2 include/asm-ppc64/errno.h | 18 -- include/asm-ppc64/ioctl.h | 74 ------- include/asm-ppc64/ioctls.h | 114 ----------- include/asm-ppc64/keylargo.h | 2 include/asm-ppc64/local.h | 1 include/asm-ppc64/macio.h | 2 include/asm-ppc64/namei.h | 23 -- include/asm-ppc64/of_device.h | 2 include/asm-ppc64/parport.h | 18 -- include/asm-ppc64/percpu.h | 6 - include/asm-ppc64/pmac_feature.h | 2 include/asm-ppc64/pmac_low_i2c.h | 2 include/asm-ppc64/poll.h | 32 --- include/asm-ppc64/resource.h | 6 - include/asm-ppc64/shmparam.h | 13 - include/asm-ppc64/string.h | 35 --- include/asm-ppc64/unaligned.h | 21 -- include/asm-ppc64/uninorth.h | 2 57 files changed, 1511 insertions(+), 1901 deletions(-) -- Cheers, Stephen Rothwell sfr at canb.auug.org.au http://www.canb.auug.org.au/~sfr/ From hch at lst.de Mon Aug 22 18:16:33 2005 From: hch at lst.de (Christoph Hellwig) Date: Mon, 22 Aug 2005 10:16:33 +0200 Subject: [patch 2/2] PPC64: Janitorial: Remove unused, deprecated code In-Reply-To: <20050818161944.GK1012@otto> References: <20050818160453.748439000@bilge> <20050818160516.683730000@bilge> <20050818161944.GK1012@otto> Message-ID: <20050822081633.GA31892@lst.de> On Thu, Aug 18, 2005 at 11:19:44AM -0500, Nathan Lynch wrote: > I don't think we're supposed to just rip out exported symbols without > notice anymore. For obscure arch code that's totally fine. From qyjlso_07_i0dfvb at hotmail.com Mon Aug 22 19:05:59 2005 From: qyjlso_07_i0dfvb at hotmail.com (Unnur Dixon) Date: Mon, 22 Aug 2005 02:05:59 -0700 Subject: =?iso-8859-1?q?V=EDagrra_Really_Works_Wonder?= Message-ID: An HTML attachment was scrubbed... URL: http://ozlabs.org/pipermail/linuxppc64-dev/attachments/20050822/2cd120cf/attachment.htm From a.othieno at bluewin.ch Mon Aug 22 22:57:23 2005 From: a.othieno at bluewin.ch (Arthur Othieno) Date: Mon, 22 Aug 2005 08:57:23 -0400 Subject: [PATCH] ppc64: Big-endian I/O memory accessors. In-Reply-To: <1124666178.5198.123.camel@gaston> References: <20050821014847.GA31956@mars> <1124666178.5198.123.camel@gaston> Message-ID: <20050822125723.GB811@mars> On Mon, Aug 22, 2005 at 09:16:18AM +1000, Benjamin Herrenschmidt wrote: > On Sat, 2005-08-20 at 21:48 -0400, Arthur Othieno wrote: > > I/O memory accessors. Big-endian version. For those busses/devices > > that do export big-endian I/O memory. > > Same comment as the ppc32 ones. You need appropriate memory barriers > among others. Use in/out_bexx() (look how readl/writel are implemented). > > Ben. Updated patch inline. Signed-Off-By: Arthur Othieno iomap.c | 20 ++++++++++++++++++++ 1 files changed, 20 insertions(+) diff -uprN a/arch/ppc64/kernel/iomap.c b/arch/ppc64/kernel/iomap.c --- a/arch/ppc64/kernel/iomap.c 2005-08-21 17:48:54.000000000 -0400 +++ b/arch/ppc64/kernel/iomap.c 2005-08-21 20:34:12.000000000 -0400 @@ -22,13 +22,23 @@ unsigned int fastcall ioread16(void __io { return readw(addr); } +unsigned int fastcall ioread16be(void __iomem *addr) +{ + return in_be16(addr); +} unsigned int fastcall ioread32(void __iomem *addr) { return readl(addr); } +unsigned int fastcall ioread32be(void __iomem *addr) +{ + return in_be32(addr); +} EXPORT_SYMBOL(ioread8); EXPORT_SYMBOL(ioread16); +EXPORT_SYMBOL(ioread16be); EXPORT_SYMBOL(ioread32); +EXPORT_SYMBOL(ioread32be); void fastcall iowrite8(u8 val, void __iomem *addr) { @@ -38,13 +48,23 @@ void fastcall iowrite16(u16 val, void __ { writew(val, addr); } +void fastcall iowrite16be(u16 val, void __iomem *addr) +{ + out_be16(addr, val); +} void fastcall iowrite32(u32 val, void __iomem *addr) { writel(val, addr); } +void fastcall iowrite32be(u32 val, void __iomem *addr) +{ + out_be32(addr, val); +} EXPORT_SYMBOL(iowrite8); EXPORT_SYMBOL(iowrite16); +EXPORT_SYMBOL(iowrite16be); EXPORT_SYMBOL(iowrite32); +EXPORT_SYMBOL(iowrite32be); /* * These are the "repeat read/write" functions. Note the From olof at lixom.net Tue Aug 23 00:12:35 2005 From: olof at lixom.net (Olof Johansson) Date: Mon, 22 Aug 2005 09:12:35 -0500 Subject: [PATCH 3/3] Move all the very similar files In-Reply-To: <20050822161030.4082716d.sfr@canb.auug.org.au> References: <20050822160254.2dc59b25.sfr@canb.auug.org.au> <20050822160519.51d065fe.sfr@canb.auug.org.au> <20050822161030.4082716d.sfr@canb.auug.org.au> Message-ID: <20050822141235.GA7110@austin.ibm.com> On Mon, Aug 22, 2005 at 04:10:30PM +1000, Stephen Rothwell wrote: > This moves all the very similar files - either the ppc64 file included > the ppc file or they differed in simple comments. [...] > include/asm-powerpc/pmac_feature.h | 379 ++++++++++++++++++++++++++++++++++++ > include/asm-powerpc/pmac_low_i2c.h | 43 ++++ Since the need is considered big enough to create a hierarchy for the code under arch/powerpc/, wouldn't something corresponding be a good idea for the include files? Or do we want to clutter them with all platform-specific files in one directory? -Olof From kumar.gala at freescale.com Tue Aug 23 00:20:10 2005 From: kumar.gala at freescale.com (Kumar Gala) Date: Mon, 22 Aug 2005 09:20:10 -0500 Subject: [PATCH 3/3] Move all the very similar files In-Reply-To: <20050822141235.GA7110@austin.ibm.com> References: <20050822141235.GA7110@austin.ibm.com> Message-ID: <0F51EC83-8969-4083-B0D7-9343D075B635@freescale.com> On Aug 22, 2005, at 9:12 AM, Olof Johansson wrote: > On Mon, Aug 22, 2005 at 04:10:30PM +1000, Stephen Rothwell wrote: > >> This moves all the very similar files - either the ppc64 file >> included >> the ppc file or they differed in simple comments. >> > > [...] > >> include/asm-powerpc/pmac_feature.h | 379 >> > ++++++++++++++++++++++++++++++++++++ > >> include/asm-powerpc/pmac_low_i2c.h | 43 ++++ >> > > Since the need is considered big enough to create a hierarchy for > the code under arch/powerpc/, wouldn't something corresponding be a > good idea for the include files? Or do we want to clutter them with > all platform-specific files in one directory? I'm in agreement, but am wondering how many of the pmac specific headers could end up in arch/powerpc/platforms/pmac in the future. - kumar From olh at suse.de Tue Aug 23 00:20:28 2005 From: olh at suse.de (Olaf Hering) Date: Mon, 22 Aug 2005 16:20:28 +0200 Subject: [Fwd: [PATCH] PPC64: large INITRD causes kernel not to boot] In-Reply-To: <42FAA272.6010601@mvista.com> References: <42F7A56D.7090809@mvista.com> <20050808185435.GA13206@suse.de> <42F7AC62.3070601@mvista.com> <20050808191123.GA14047@suse.de> <42F7B301.5060008@mvista.com> <20050808223010.GA18775@suse.de> <42F7DF52.4090905@mvista.com> <42F80136.9050500@mvista.com> <42FAA272.6010601@mvista.com> Message-ID: <20050822142028.GA8605@suse.de> On Wed, Aug 10, Mark Bellon wrote: > + > + /* > + * The first available claim_base must be above the end of the > + * the loaded kernel wrapper file (_start to _end includes the > + * initrd image if it is present) and rounded up to a nice > + * 1 MB boundary for good measure. > + */ > + > + claim_base = ((((unsigned long) _end) + ONE_MB - 1) / ONE_MB) * ONE_MB; I guess that doesnt help the maple board with their PIBS 1.05 firmware. I got 0x00aa7688 bytes for uncompressed kernel @ 0x00b00000, which was used for the nvram msg_area (NVRAM_MAGIC did not match anymore). It seems SLOF isnt any better... Maybe the claim_base should be at least 20mb. From olof at lixom.net Tue Aug 23 01:01:38 2005 From: olof at lixom.net (Olof Johansson) Date: Mon, 22 Aug 2005 10:01:38 -0500 Subject: [PATCH 3/3] Move all the very similar files In-Reply-To: <0F51EC83-8969-4083-B0D7-9343D075B635@freescale.com> References: <20050822141235.GA7110@austin.ibm.com> <0F51EC83-8969-4083-B0D7-9343D075B635@freescale.com> Message-ID: <20050822150138.GA14735@austin.ibm.com> On Mon, Aug 22, 2005 at 09:20:10AM -0500, Kumar Gala wrote: > >Since the need is considered big enough to create a hierarchy for > >the code under arch/powerpc/, wouldn't something corresponding be a > >good idea for the include files? Or do we want to clutter them with > >all platform-specific files in one directory? > > I'm in agreement, but am wondering how many of the pmac specific > headers could end up in arch/powerpc/platforms/pmac in the future. Yeah, not sure -- I was thinking the same while I wrote that reply. There are some pSeries and iSeries files that could maybe be moved there too. -Olof From trini at kernel.crashing.org Tue Aug 23 01:37:22 2005 From: trini at kernel.crashing.org (Tom Rini) Date: Mon, 22 Aug 2005 08:37:22 -0700 Subject: [PATCH 1/3] Create include/asm-powerpc In-Reply-To: <20050822160254.2dc59b25.sfr@canb.auug.org.au> References: <20050822160254.2dc59b25.sfr@canb.auug.org.au> Message-ID: <20050822153722.GA22161@smtp.west.cox.net> On Mon, Aug 22, 2005 at 04:02:54PM +1000, Stephen Rothwell wrote: > Hopefully, we can gree to start like this ... > > Create include/asm-powerpc (and move linkage.h into it since we don't > like empty directories). Modify the Makefiles to cope. > > Signed-off-by: Stephen Rothwell Sounds like a good start to me. -- Tom Rini http://gate.crashing.org/~trini/ From kumar.gala at freescale.com Tue Aug 23 01:47:53 2005 From: kumar.gala at freescale.com (Kumar Gala) Date: Mon, 22 Aug 2005 10:47:53 -0500 Subject: [PATCH 1/3] Create include/asm-powerpc In-Reply-To: <20050822153722.GA22161@smtp.west.cox.net> References: <20050822153722.GA22161@smtp.west.cox.net> Message-ID: <6304CEE6-FC35-4847-B619-D6B33C6BBBC6@freescale.com> On Aug 22, 2005, at 10:37 AM, Tom Rini wrote: > On Mon, Aug 22, 2005 at 04:02:54PM +1000, Stephen Rothwell wrote: > > >> Hopefully, we can gree to start like this ... >> >> Create include/asm-powerpc (and move linkage.h into it since we don't >> like empty directories). Modify the Makefiles to cope. >> >> Signed-off-by: Stephen Rothwell >> > > Sounds like a good start to me. If it was not clear, I'm good with patch 1/3 and 2/3. - kumar From jschopp at austin.ibm.com Tue Aug 23 04:11:36 2005 From: jschopp at austin.ibm.com (Joel Schopp) Date: Mon, 22 Aug 2005 13:11:36 -0500 Subject: ibmvscsi.c broken in 2.6.13-rc6-mm1 Message-ID: <430A1558.4010108@austin.ibm.com> Got a compile error in the latest -mm on line 597 of ibmvscsi.c, function ibmvscsi_queuecommand, structure has no member named timeout. You might want to fix this. From segher at kernel.crashing.org Tue Aug 23 05:01:35 2005 From: segher at kernel.crashing.org (Segher Boessenkool) Date: Mon, 22 Aug 2005 21:01:35 +0200 Subject: [Fwd: [PATCH] PPC64: large INITRD causes kernel not to boot] In-Reply-To: <20050822142028.GA8605@suse.de> References: <42F7A56D.7090809@mvista.com> <20050808185435.GA13206@suse.de> <42F7AC62.3070601@mvista.com> <20050808191123.GA14047@suse.de> <42F7B301.5060008@mvista.com> <20050808223010.GA18775@suse.de> <42F7DF52.4090905@mvista.com> <42F80136.9050500@mvista.com> <42FAA272.6010601@mvista.com> <20050822142028.GA8605@suse.de> Message-ID: <19a8c3db28d17b53e582be6d8dd698a7@kernel.crashing.org> > I guess that doesnt help the maple board with their PIBS 1.05 firmware. > I got 0x00aa7688 bytes for uncompressed kernel @ 0x00b00000, > which was used for the nvram msg_area (NVRAM_MAGIC did not match > anymore). > It seems SLOF isnt any better... Hey, I told you that in private, no need to spout it on the mailing list. Also, our memory map (esp. the new memory map) leaves almost all "low" memory to whoever wants to use it, so much less chance of collisions, even with broken clients (like Linux seems to be). Segher From sonny at burdell.org Tue Aug 23 05:26:16 2005 From: sonny at burdell.org (Sonny Rao) Date: Mon, 22 Aug 2005 15:26:16 -0400 Subject: How to get out physc? In-Reply-To: References: Message-ID: <20050822192616.GA27480@kevlar.burdell.org> On Fri, Aug 19, 2005 at 08:50:04AM +0200, matthias.hofer at arz.co.at wrote: > On IBM Power5-Systems Logical Partitions use up the amount of CPU-time, > that they really need. "physc" is the value that represents the amount of > Physical CPUs that the LPAR consumes. > On AIX, sar shows: > > $ sar > > AIX aix0003a 3 5 00C1D7DF4C00 08/19/05 > > System configuration: lcpu=4 ent=0.40 > > 02:00:00 %usr %sys %wio %idle physc %entc > 02:05:00 77 10 6 7 0.86 215.6 > 02:10:01 44 24 11 22 0.35 87.3 > 02:15:00 39 22 12 27 0.32 80.3 > 02:20:00 45 18 12 25 0.32 79.3 > 02:25:00 35 19 10 35 0.28 70.3 > 02:30:00 41 19 7 33 0.30 76.1 > 02:35:00 23 11 6 60 0.17 43.5 > 02:40:00 78 10 1 11 0.50 125.8 > 02:45:00 90 2 0 7 1.04 260.6 > 02:50:01 90 2 0 7 1.06 264.5 > 02:55:00 90 2 0 7 1.07 266.3 > 03:00:00 91 2 0 7 1.05 263.5 > 03:05:00 88 4 2 7 1.13 283.4 > 03:10:00 87 4 1 7 1.17 293.6 > 03:15:00 90 3 1 7 1.11 277.1 > 03:20:00 90 3 0 7 1.06 265.8 > 03:25:00 91 2 0 7 1.04 261.2 > 03:30:01 90 2 0 7 1.05 263.0 > 03:35:00 91 2 0 7 1.04 260.1 > 03:40:00 90 2 0 7 1.05 263.6 > 03:45:00 91 2 0 7 1.04 259.8 > > So, this LPAR used between 0.17 and 1.17 Physical CPUs at a given time. > vmstat, for example, shows: > > $ vmstat 2 3 > > System configuration: lcpu=4 mem=5120MB ent=0.40 > > kthr memory page faults cpu > ----- ----------- ------------------------ ------------ > ----------------------- > r b avm fre re pi po fr sr cy in sy cs us sy id wa pc > ec > 1 0 697996 457310 0 0 0 0 0 0 505 783 1276 88 3 8 1 > 1.07 266.4 > 2 0 697996 457310 0 0 0 0 0 0 731 2291 1680 88 4 7 2 > 1.12 280.7 > 2 0 697996 457310 0 0 0 0 0 0 1096 8121 2482 85 6 7 3 > 1.17 292.5 > > The next-to-last value is "physc" (pc). > > I found out that "nmon" is able to measure and show this value for the > LPAR on GNU/Linux, but I hoped for something like sar, for historical > data. > Anybody confident with GNU/Linux on IBM-Power5 with Advanced > Virtualization? Currently, there is no good way to do this in Linux, the tools are currently being worked on and will be released at some point later but I'm not sure when. Sonny LTC Performance From olh at suse.de Tue Aug 23 05:29:08 2005 From: olh at suse.de (Olaf Hering) Date: Mon, 22 Aug 2005 21:29:08 +0200 Subject: [Fwd: [PATCH] PPC64: large INITRD causes kernel not to boot] In-Reply-To: <19a8c3db28d17b53e582be6d8dd698a7@kernel.crashing.org> References: <20050808185435.GA13206@suse.de> <42F7AC62.3070601@mvista.com> <20050808191123.GA14047@suse.de> <42F7B301.5060008@mvista.com> <20050808223010.GA18775@suse.de> <42F7DF52.4090905@mvista.com> <42F80136.9050500@mvista.com> <42FAA272.6010601@mvista.com> <20050822142028.GA8605@suse.de> <19a8c3db28d17b53e582be6d8dd698a7@kernel.crashing.org> Message-ID: <20050822192908.GA26542@suse.de> On Mon, Aug 22, Segher Boessenkool wrote: > >I guess that doesnt help the maple board with their PIBS 1.05 firmware. > >I got 0x00aa7688 bytes for uncompressed kernel @ 0x00b00000, > >which was used for the nvram msg_area (NVRAM_MAGIC did not match > >anymore). > >It seems SLOF isnt any better... > > Hey, I told you that in private, no need to spout it on the > mailing list. Such bugs have to be fixed, obviously. No? > Also, our memory map (esp. the new memory map) leaves almost > all "low" memory to whoever wants to use it, so much less > chance of collisions, even with broken clients (like Linux > seems to be). If I claim(0x0,123456,0) and OF says OK than I have to expect that its really OK to use the mem at 0x0. In this case maple rejected everything up to 11MB. But it has appearently some runtime data above 11MB, havent debugged it further. At least claim(11MB,10MB,0) and claim(64MB,10MB,0) and copying the memory from 11MB to 64MB and comparing it right away showed differences. Pretty bad for an client owned area, no? From jdl at freescale.com Tue Aug 23 05:39:03 2005 From: jdl at freescale.com (Jon Loeliger) Date: Mon, 22 Aug 2005 14:39:03 -0500 Subject: [PATCH 1/3] Create include/asm-powerpc In-Reply-To: <20050822160254.2dc59b25.sfr@canb.auug.org.au> References: <20050822160254.2dc59b25.sfr@canb.auug.org.au> Message-ID: <1124739542.14957.13.camel@cashmere.sps.mot.com> On Mon, 2005-08-22 at 01:02, Stephen Rothwell wrote: > Hopefully, we can gree to start like this ... Say, I'd be happy to _a_gree on this start. :-) So, this is the third or so variant of this, and I know that Becky has an essentially identical patch queued up here to go out as well, and all. Paul, any chance that we can set up a "merge tree" that contains a good working basis for these patches so that we can make some forward progress while waiting for some upstream commits to take place? Thanks, jdl From jschopp at austin.ibm.com Tue Aug 23 05:53:23 2005 From: jschopp at austin.ibm.com (Joel Schopp) Date: Mon, 22 Aug 2005 14:53:23 -0500 Subject: [patch] ibmvscsi timeout fix In-Reply-To: <20050822193826.GA2455@cs.umn.edu> References: <20050822193826.GA2455@cs.umn.edu> Message-ID: <430A2D33.2000308@austin.ibm.com> > This patch fixes a long term borkenness in > ibmvscsi where we were using the wrong timeout > field from the scsi command (and using the > wrong units.) Now broken by the fact that the > scsi_cmnd timeout field is gone entirely. > This only worked before because all the SCSI > targets assumed that 0 was default. That was fast. I report the error to you and get a patch next time I look at my mail. This does fix the build break I saw in a 2.6.13-rc6-mm1 defconfig on ppc64. Adding Andrew Morton to the distribution list since somebody else is bound to notice that ppc64 -mm doesn't compile anymore. Acked-by: Joel Schopp > > Signed-off-by: Dave Boutcher > > --- linux-2.6.13-rc6-mm1-orig/drivers/scsi/ibmvscsi/ibmvscsi.c 2005-08-22 13:54:20.111955197 -0500 > +++ linux-2.6.13-rc6-mm1/drivers/scsi/ibmvscsi/ibmvscsi.c 2005-08-22 14:22:56.265042174 -0500 > @@ -594,7 +594,7 @@ > init_event_struct(evt_struct, > handle_cmd_rsp, > VIOSRP_SRP_FORMAT, > - cmnd->timeout); > + cmnd->timeout_per_command/HZ); > > evt_struct->cmnd = cmnd; > evt_struct->cmnd_done = done; > > From sleddog at us.ibm.com Tue Aug 23 05:38:26 2005 From: sleddog at us.ibm.com (Dave C Boutcher) Date: Mon, 22 Aug 2005 14:38:26 -0500 Subject: [patch] ibmvscsi timeout fix Message-ID: <20050822193826.GA2455@cs.umn.edu> This patch fixes a long term borkenness in ibmvscsi where we were using the wrong timeout field from the scsi command (and using the wrong units.) Now broken by the fact that the scsi_cmnd timeout field is gone entirely. This only worked before because all the SCSI targets assumed that 0 was default. Signed-off-by: Dave Boutcher --- linux-2.6.13-rc6-mm1-orig/drivers/scsi/ibmvscsi/ibmvscsi.c 2005-08-22 13:54:20.111955197 -0500 +++ linux-2.6.13-rc6-mm1/drivers/scsi/ibmvscsi/ibmvscsi.c 2005-08-22 14:22:56.265042174 -0500 @@ -594,7 +594,7 @@ init_event_struct(evt_struct, handle_cmd_rsp, VIOSRP_SRP_FORMAT, - cmnd->timeout); + cmnd->timeout_per_command/HZ); evt_struct->cmnd = cmnd; evt_struct->cmnd_done = done; -- Dave Boutcher From anton at samba.org Tue Aug 23 15:34:43 2005 From: anton at samba.org (Anton Blanchard) Date: Tue, 23 Aug 2005 15:34:43 +1000 Subject: [PATCH] ppc64: Fix issue with gcc 4.0 compiled kernels Message-ID: <20050823053443.GB31949@krispykreme> Hi, I recently had a BUG_ON() go off spuriously on a gcc 4.0 compiled kernel. It turns out gcc-4.0 was removing a sign extension while earlier gcc versions would not. Thinking this to be a compiler bug, I submitted a report: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=23422 It turns out we need to cast the input in order to tell gcc to sign extend it. Thanks to Andrew Pinski for his help on this bug. Signed-off-by: Anton Blanchard Index: gr_work/include/asm-ppc64/bug.h =================================================================== --- gr_work.orig/include/asm-ppc64/bug.h 2005-07-08 22:34:03.000000000 -0500 +++ gr_work/include/asm-ppc64/bug.h 2005-08-16 09:26:23.940170149 -0500 @@ -43,8 +43,8 @@ ".section __bug_table,\"a\"\n\t" \ " .llong 1b,%1,%2,%3\n" \ ".previous" \ - : : "r" (x), "i" (__LINE__), "i" (__FILE__), \ - "i" (__FUNCTION__)); \ + : : "r" ((long long)(x)), "i" (__LINE__), \ + "i" (__FILE__), "i" (__FUNCTION__)); \ } while (0) #define WARN_ON(x) do { \ @@ -53,7 +53,8 @@ ".section __bug_table,\"a\"\n\t" \ " .llong 1b,%1,%2,%3\n" \ ".previous" \ - : : "r" (x), "i" (__LINE__ + BUG_WARNING_TRAP), \ + : : "r" ((long long)(x)), \ + "i" (__LINE__ + BUG_WARNING_TRAP), \ "i" (__FILE__), "i" (__FUNCTION__)); \ } while (0) From benh at kernel.crashing.org Tue Aug 23 15:41:47 2005 From: benh at kernel.crashing.org (Benjamin Herrenschmidt) Date: Tue, 23 Aug 2005 15:41:47 +1000 Subject: [PATCH 3/3] Move all the very similar files In-Reply-To: <0F51EC83-8969-4083-B0D7-9343D075B635@freescale.com> References: <20050822141235.GA7110@austin.ibm.com> <0F51EC83-8969-4083-B0D7-9343D075B635@freescale.com> Message-ID: <1124775707.5159.92.camel@gaston> On Mon, 2005-08-22 at 09:20 -0500, Kumar Gala wrote: > On Aug 22, 2005, at 9:12 AM, Olof Johansson wrote: > > > On Mon, Aug 22, 2005 at 04:10:30PM +1000, Stephen Rothwell wrote: > > > >> This moves all the very similar files - either the ppc64 file > >> included > >> the ppc file or they differed in simple comments. > >> > > > > [...] > > > >> include/asm-powerpc/pmac_feature.h | 379 > >> > > ++++++++++++++++++++++++++++++++++++ > > > >> include/asm-powerpc/pmac_low_i2c.h | 43 ++++ > >> > > > > Since the need is considered big enough to create a hierarchy for > > the code under arch/powerpc/, wouldn't something corresponding be a > > good idea for the include files? Or do we want to clutter them with > > all platform-specific files in one directory? > > I'm in agreement, but am wondering how many of the pmac specific > headers could end up in arch/powerpc/platforms/pmac in the future. Most of the ones that are in include/asm* are there because drivers outside of arch/* use them. Ben. From paulus at samba.org Tue Aug 23 16:11:05 2005 From: paulus at samba.org (Paul Mackerras) Date: Tue, 23 Aug 2005 16:11:05 +1000 Subject: [PATCH] ppc64: Fix issue with gcc 4.0 compiled kernels In-Reply-To: <20050823053443.GB31949@krispykreme> References: <20050823053443.GB31949@krispykreme> Message-ID: <17162.48633.667720.881115@cargo.ozlabs.ibm.com> Anton Blanchard writes: > I recently had a BUG_ON() go off spuriously on a gcc 4.0 compiled > kernel. It turns out gcc-4.0 was removing a sign extension while earlier > gcc versions would not. Thinking this to be a compiler bug, I submitted > a report: ... > - "i" (__FUNCTION__)); \ > + : : "r" ((long long)(x)), "i" (__LINE__), \ Could we have a (long) cast instead? That way we can use the same definition on 32-bit as well. Paul. From amodra at bigpond.net.au Tue Aug 23 16:22:24 2005 From: amodra at bigpond.net.au (Alan Modra) Date: Tue, 23 Aug 2005 15:52:24 +0930 Subject: [PATCH] ppc64: Fix issue with gcc 4.0 compiled kernels In-Reply-To: <17162.48633.667720.881115@cargo.ozlabs.ibm.com> References: <20050823053443.GB31949@krispykreme> <17162.48633.667720.881115@cargo.ozlabs.ibm.com> Message-ID: <20050823062224.GE30583@bubble.grove.modra.org> On Tue, Aug 23, 2005 at 04:11:05PM +1000, Paul Mackerras wrote: > Anton Blanchard writes: > > - "i" (__FUNCTION__)); \ > > + : : "r" ((long long)(x)), "i" (__LINE__), \ > > Could we have a (long) cast instead? That way we can use the same > definition on 32-bit as well. Yes, that will work fine. -- Alan Modra IBM OzLabs - Linux Technology Centre From sfr at canb.auug.org.au Tue Aug 23 17:31:42 2005 From: sfr at canb.auug.org.au (Stephen Rothwell) Date: Tue, 23 Aug 2005 17:31:42 +1000 Subject: [PATCH 3/3] Move all the very similar files In-Reply-To: <1124775707.5159.92.camel@gaston> References: <20050822141235.GA7110@austin.ibm.com> <0F51EC83-8969-4083-B0D7-9343D075B635@freescale.com> <1124775707.5159.92.camel@gaston> Message-ID: <20050823173142.4f620d75.sfr@canb.auug.org.au> On Tue, 23 Aug 2005 15:41:47 +1000 Benjamin Herrenschmidt wrote: > > Most of the ones that are in include/asm* are there because drivers > outside of arch/* use them. Indeed. Here is the result of grepping for all of the .h files in patch 3 (minus the obvious noncontentious ones like errno.h ...): asm/dbdma.h ----------------------------------------------------------- arch/ppc/platforms/pmac_feature.c:#include arch/ppc64/kernel/pmac_feature.c:#include drivers/block/swim3.c:#include drivers/ide/ppc/pmac.c:#include drivers/media/video/planb.c:#include drivers/media/video/planb.h:#include drivers/net/bmac.c:#include drivers/net/mace.c:#include drivers/scsi/mac53c94.c:#include drivers/scsi/mesh.c:#include drivers/serial/pmac_zilog.c:#include sound/oss/dmasound/dmasound_awacs.c:#include sound/ppc/pmac.h:#include ----------------------------------------------------------- asm/keylargo.h ----------------------------------------------------------- arch/ppc/platforms/pmac_cpufreq.c:#include arch/ppc/platforms/pmac_feature.c:#include arch/ppc/platforms/pmac_low_i2c.c:#include arch/ppc/platforms/pmac_smp.c:#include arch/ppc64/kernel/pmac_feature.c:#include arch/ppc64/kernel/pmac_low_i2c.c:#include arch/ppc64/kernel/pmac_smp.c:#include drivers/macintosh/mediabay.c:#include ----------------------------------------------------------- asm/macio.h ----------------------------------------------------------- drivers/macintosh/macio_asic.c:#include drivers/macintosh/macio_sysfs.c:#include drivers/macintosh/therm_pm72.c:#include drivers/macintosh/therm_windtunnel.c:#include drivers/net/bmac.c:#include drivers/net/mace.c:#include drivers/scsi/mac53c94.c:#include drivers/scsi/mesh.c:#include drivers/serial/pmac_zilog.c:#include include/asm-powerpc/pmac_feature.h:#include ----------------------------------------------------------- asm/of_device.h ----------------------------------------------------------- arch/ppc/platforms/pmac_setup.c:#include arch/ppc/syslib/of_device.c:#include arch/ppc64/kernel/maple_setup.c:#include arch/ppc64/kernel/of_device.c:#include arch/ppc64/kernel/pmac_setup.c:#include drivers/macintosh/therm_adt746x.c:#include drivers/macintosh/therm_pm72.c:#include drivers/macintosh/therm_windtunnel.c:#include drivers/video/platinumfb.c:#include include/asm-powerpc/macio.h:#include ----------------------------------------------------------- asm/parport.h ----------------------------------------------------------- drivers/parport/ChangeLog: * parport_pc.c (parport_pc_init): Moved from asm/parport.h. drivers/parport/parport_pc.c:#include drivers/parport/parport_pc.c:/* This is called by parport_pc_find_nonpci_ports (in asm/parport.h) */ drivers/parport/parport_pc.c: /* ISA ports and whatever (see asm/parport.h). */ ----------------------------------------------------------- asm/pmac_feature.h ----------------------------------------------------------- arch/ppc/kernel/ppc_ksyms.c:#include arch/ppc/kernel/setup.c:#include arch/ppc/platforms/pmac_cpufreq.c:#include arch/ppc/platforms/pmac_feature.c:#include arch/ppc/platforms/pmac_pci.c:#include arch/ppc/platforms/pmac_pic.c:#include arch/ppc/platforms/pmac_setup.c:#include arch/ppc/platforms/pmac_smp.c:#include arch/ppc/xmon/start.c:#include arch/ppc64/kernel/bpa_iommu.c:#include arch/ppc64/kernel/pci_direct_iommu.c:#include arch/ppc64/kernel/pmac_feature.c:#include arch/ppc64/kernel/pmac_pci.c:#include arch/ppc64/kernel/pmac_setup.c:#include arch/ppc64/kernel/pmac_smp.c:#include arch/ppc64/kernel/udbg.c:#include drivers/block/swim3.c:#include drivers/char/agp/uninorth-agp.c:#include drivers/i2c/busses/i2c-keywest.c:#include drivers/ide/ppc/pmac.c:#include drivers/ieee1394/ohci1394.c:#include drivers/macintosh/adbhid.c:#include drivers/macintosh/macio_asic.c:#include drivers/macintosh/mediabay.c:#include drivers/macintosh/smu.c:#include drivers/macintosh/via-pmu.c:#include drivers/net/bmac.c:#include drivers/net/sungem.c:#include drivers/net/wireless/airport.c:#include drivers/scsi/mesh.c:#include drivers/serial/pmac_zilog.c:#include drivers/usb/host/ohci-pci.c:#include drivers/video/aty/aty128fb.c:#include drivers/video/aty/radeon_pm.c:#include sound/oss/dmasound/dmasound_awacs.c:#include sound/ppc/pmac.c:#include sound/ppc/toonie.c:#include sound/ppc/tumbler.c:#include ----------------------------------------------------------- asm/pmac_low_i2c.h ----------------------------------------------------------- arch/ppc/platforms/pmac_feature.c:#include arch/ppc/platforms/pmac_low_i2c.c:#include arch/ppc64/kernel/pmac_feature.c:#include arch/ppc64/kernel/pmac_low_i2c.c:#include arch/ppc64/kernel/pmac_smp.c:#include drivers/i2c/busses/i2c-keywest.c:#include ----------------------------------------------------------- asm/uninorth.h ----------------------------------------------------------- arch/ppc/platforms/pmac_feature.c:#include arch/ppc/platforms/pmac_low_i2c.c:#include arch/ppc64/kernel/pmac_feature.c:#include arch/ppc64/kernel/pmac_low_i2c.c:#include drivers/char/agp/uninorth-agp.c:#include ----------------------------------------------------------- -- Cheers, Stephen Rothwell sfr at canb.auug.org.au http://www.canb.auug.org.au/~sfr/ -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: not available Url : http://ozlabs.org/pipermail/linuxppc64-dev/attachments/20050823/9db49c5a/attachment.pgp From matthias.hofer at arz.co.at Tue Aug 23 17:32:06 2005 From: matthias.hofer at arz.co.at (matthias.hofer at arz.co.at) Date: Tue, 23 Aug 2005 09:32:06 +0200 Subject: Antwort: Re: How to get out physc? In-Reply-To: <20050822192616.GA27480@kevlar.burdell.org> Message-ID: Hi! > > I found out that "nmon" is able to measure and show this value for the > > LPAR on GNU/Linux, but I hoped for something like sar, for historical > > data. > > Anybody confident with GNU/Linux on IBM-Power5 with Advanced > > Virtualization? > > Currently, there is no good way to do this in Linux, the tools are > currently being worked on and will be released at some point later > but I'm not sure when. > > Sonny > LTC Performance Thank you for your info, Sonny! Where did you get this info from? Is there any resource on the web? Thank you. Matthias ---------------- Disclaimer: Diese Nachricht dient ausschlie?lich zu Informationszwecken und ist nur f?r den Gebrauch des Empf?ngers bestimmt. This message is only for informational purposes and is intended solely for the use of the addressee. ---------------- From sonny at burdell.org Tue Aug 23 17:53:32 2005 From: sonny at burdell.org (Sonny Rao) Date: Tue, 23 Aug 2005 03:53:32 -0400 Subject: Antwort: Re: How to get out physc? In-Reply-To: References: <20050822192616.GA27480@kevlar.burdell.org> Message-ID: <20050823075332.GA16332@kevlar.burdell.org> On Tue, Aug 23, 2005 at 09:32:06AM +0200, matthias.hofer at arz.co.at wrote: > Hi! > > > > I found out that "nmon" is able to measure and show this value for the > > > > LPAR on GNU/Linux, but I hoped for something like sar, for historical > > > data. > > > Anybody confident with GNU/Linux on IBM-Power5 with Advanced > > > Virtualization? > > > > Currently, there is no good way to do this in Linux, the tools are > > currently being worked on and will be released at some point later > > but I'm not sure when. > > > > Sonny > > LTC Performance > > Thank you for your info, Sonny! > > Where did you get this info from? > > Is there any resource on the web? No sorry, I work at IBM Linux Technology Center, we have a performance tools group who is working on this, there's not really anything public just yet. Sonny From sharada at in.ibm.com Tue Aug 23 18:04:24 2005 From: sharada at in.ibm.com (R Sharada) Date: Tue, 23 Aug 2005 13:34:24 +0530 Subject: [PATCH] export htab value for kexec on non-lpar Message-ID: <20050823080423.GA2380@in.ibm.com> Hello, kexec on ppc64 requires that we be able to identify and avoid having valid segment destination addresses in the htab area, on non-lpar machines, as kexec uses the page tables (copy_page) for copying into the final destination addresses. On non-lpar power4 machines, this means that the kexec-tools needs to have a way to know where the htab addresses lie. Here is a patch to export the htab details into /proc/device-tree under /chosen node. Created and tested against 2.6.13-rc6. Kindly review and let me know if there are any issues in getting this accepted. Thanks and Regards, Sharada --- diff -puN ./arch/ppc64/kernel/setup.c~kexec-export-htab-value ./arch/ppc64/kernel/setup.c --- linux-2.6.13-rc6/./arch/ppc64/kernel/setup.c~kexec-export-htab-value 2005-08-23 18:27:14.000000000 +0530 +++ linux-2.6.13-rc6-sharada/./arch/ppc64/kernel/setup.c 2005-08-23 18:34:11.000000000 +0530 @@ -59,12 +59,19 @@ #include #include +#include + #ifdef DEBUG #define DBG(fmt...) udbg_printf(fmt) #else #define DBG(fmt...) #endif +#ifdef CONFIG_KEXEC +#define HASH_GROUP_SIZE 0x80 /* size of each hash group, asm/mmu.h */ +void export_htab_value(void); +#endif + /* * Here are some early debugging facilities. You can enable one * but your kernel will not boot on anything else if you do so @@ -1086,6 +1093,9 @@ void __init setup_arch(char **cmdline_p) } paging_init(); +#ifdef CONFIG_KEXEC + export_htab_value(); +#endif ppc64_boot_msg(0x15, "Setup Done"); } @@ -1358,3 +1368,39 @@ void cpu_die(void) if (ppc_md.cpu_die) ppc_md.cpu_die(); } + +#ifdef CONFIG_KEXEC +void export_htab_value() +{ + struct device_node *node; + struct property *newprop1, *newprop2; + unsigned long low, high; + + if (systemcfg->platform != PLATFORM_PSERIES_LPAR) { + node = of_find_node_by_path("/chosen"); + if (!node) + return; + newprop1 = alloc_bootmem(sizeof(struct property) + sizeof(unsigned long)); + if (newprop1 == NULL) + return; + newprop2 = alloc_bootmem(sizeof(struct property) + sizeof(unsigned long)); + if (newprop1 == NULL) + return; + memset(newprop1, 0, sizeof(struct property)); + memset(newprop2, 0, sizeof(struct property)); + newprop1->name = "htab_address"; + newprop1->length = sizeof(unsigned long); + newprop1->value = (unsigned char *)&newprop1[1]; + low = __pa(htab_address); + memcpy(newprop1->value, &low, sizeof(low)); + prom_add_property(node, newprop1); + newprop2->name = "htab_size"; + newprop2->length = sizeof(unsigned long); + newprop2->value = (unsigned char *)&newprop2[1]; + high = low + (htab_hash_mask + 1) * HASH_GROUP_SIZE; + memcpy(newprop2->value, &high, sizeof(high)); + prom_add_property(node, newprop2); + of_node_put(node); + } +} +#endif _ From kumar.gala at freescale.com Wed Aug 24 03:05:36 2005 From: kumar.gala at freescale.com (Kumar Gala) Date: Tue, 23 Aug 2005 12:05:36 -0500 Subject: [PATCH 3/3] Move all the very similar files In-Reply-To: <20050823173142.4f620d75.sfr@canb.auug.org.au> References: <20050822141235.GA7110@austin.ibm.com> <0F51EC83-8969-4083-B0D7-9343D075B635@freescale.com> <1124775707.5159.92.camel@gaston> <20050823173142.4f620d75.sfr@canb.auug.org.au> Message-ID: On Aug 23, 2005, at 2:31 AM, Stephen Rothwell wrote: > On Tue, 23 Aug 2005 15:41:47 +1000 Benjamin Herrenschmidt > wrote: > >> >> Most of the ones that are in include/asm* are there because drivers >> outside of arch/* use them. >> > > Indeed. Here is the result of grepping for all of the .h files in > patch 3 (minus the > obvious noncontentious ones like errno.h ...): This seems reasonable then to have them in include/asm-powerpc. I feel that there are a few files in include/asm-ppc that were only used by code in arch/ppc/platforms but I'm probably just crazy. - kumar From arnd at arndb.de Wed Aug 24 03:47:48 2005 From: arnd at arndb.de (Arnd Bergmann) Date: Tue, 23 Aug 2005 19:47:48 +0200 Subject: [PATCH] export htab value for kexec on non-lpar In-Reply-To: <20050823080423.GA2380@in.ibm.com> References: <20050823080423.GA2380@in.ibm.com> Message-ID: <200508231947.49881.arnd@arndb.de> On Dinsdag 23 August 2005 10:04, R Sharada wrote: > > diff -puN ./arch/ppc64/kernel/setup.c~kexec-export-htab-value ./arch/ppc64/kernel/setup.c > --- linux-2.6.13-rc6/./arch/ppc64/kernel/setup.c~kexec-export-htab-value 2005-08-23 18:27:14.000000000 +0530 > +++ linux-2.6.13-rc6-sharada/./arch/ppc64/kernel/setup.c 2005-08-23 18:34:11.000000000 +0530 > @@ -59,12 +59,19 @@ > #include > #include > > +#include > + > #ifdef DEBUG > #define DBG(fmt...) udbg_printf(fmt) > #else > #define DBG(fmt...) > #endif > > +#ifdef CONFIG_KEXEC > +#define HASH_GROUP_SIZE 0x80 /* size of each hash group, asm/mmu.h */ This should not be inside of #ifdef. From the comment, I'd also expect that this would better fit into asm/mmu.h ;-) > +void export_htab_value(void); The function should be static when it is only used in a single file. Also, forward declarations of functions within .c files are often a bad idea. Just put your own function more to the top to avoid this. > +#endif > + > /* > * Here are some early debugging facilities. You can enable one > * but your kernel will not boot on anything else if you do so > @@ -1086,6 +1093,9 @@ void __init setup_arch(char **cmdline_p) > } > > paging_init(); > +#ifdef CONFIG_KEXEC > + export_htab_value(); > +#endif Instead of doing the #ifdef here, you can simply have an #else path at the definition that provides an empty inline function. That is, if it makes sense to have this conditional in the first place. > ppc64_boot_msg(0x15, "Setup Done"); > } > > @@ -1358,3 +1368,39 @@ void cpu_die(void) > if (ppc_md.cpu_die) > ppc_md.cpu_die(); > } > + > +#ifdef CONFIG_KEXEC > +void export_htab_value() > +{ > + struct device_node *node; > + struct property *newprop1, *newprop2; > + unsigned long low, high; > + > + if (systemcfg->platform != PLATFORM_PSERIES_LPAR) { > + node = of_find_node_by_path("/chosen"); > + if (!node) > + return; > + newprop1 = alloc_bootmem(sizeof(struct property) + sizeof(unsigned long)); > + if (newprop1 == NULL) > + return; > + newprop2 = alloc_bootmem(sizeof(struct property) + sizeof(unsigned long)); > + if (newprop1 == NULL) > + return; Your memory layout is a bit obscure here. I'd either do a single allocation of a structure for this purpose or simply have the properties statically allocated. A static allocation would actually decrease the memory requirements because you would not need the code to initialize it. > + memset(newprop1, 0, sizeof(struct property)); > + memset(newprop2, 0, sizeof(struct property)); > + newprop1->name = "htab_address"; > + newprop1->length = sizeof(unsigned long); > + newprop1->value = (unsigned char *)&newprop1[1]; > + low = __pa(htab_address); > + memcpy(newprop1->value, &low, sizeof(low)); Just to an assignment of the variably instead of memcpy. It's only a single integer. > + prom_add_property(node, newprop1); > + newprop2->name = "htab_size"; > + newprop2->length = sizeof(unsigned long); > + newprop2->value = (unsigned char *)&newprop2[1]; > + high = low + (htab_hash_mask + 1) * HASH_GROUP_SIZE; > + memcpy(newprop2->value, &high, sizeof(high)); > + prom_add_property(node, newprop2); > + of_node_put(node); > + } Arnd <>< From anton at samba.org Wed Aug 24 07:15:11 2005 From: anton at samba.org (Anton Blanchard) Date: Wed, 24 Aug 2005 07:15:11 +1000 Subject: [PATCH] ppc64: Fix issue with gcc 4.0 compiled kernels In-Reply-To: <20050823062224.GE30583@bubble.grove.modra.org> References: <20050823053443.GB31949@krispykreme> <17162.48633.667720.881115@cargo.ozlabs.ibm.com> <20050823062224.GE30583@bubble.grove.modra.org> Message-ID: <20050823211511.GD31949@krispykreme> > > Could we have a (long) cast instead? That way we can use the same > > definition on 32-bit as well. > > Yes, that will work fine. Except that the instruction itself is tdnei which would be dangerous to use in 32bit mode wouldnt it? Anton From anton at samba.org Wed Aug 24 08:53:03 2005 From: anton at samba.org (Anton Blanchard) Date: Wed, 24 Aug 2005 08:53:03 +1000 Subject: [PATCH] ppc64: Add CONFIG_HZ Message-ID: <20050823225303.GF31949@krispykreme> Hi, While ppc64 has the CONFIG_HZ Kconfig option, it wasnt actually being used. Connect it up and set all platforms to 250Hz. Signed-off-by: Anton Blanchard Index: build/include/asm-ppc64/param.h =================================================================== --- build.orig/include/asm-ppc64/param.h 2005-08-15 23:42:07.000000000 +1000 +++ build/include/asm-ppc64/param.h 2005-08-24 08:02:29.000000000 +1000 @@ -1,6 +1,8 @@ #ifndef _ASM_PPC64_PARAM_H #define _ASM_PPC64_PARAM_H +#include + /* * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -9,7 +11,7 @@ */ #ifdef __KERNEL__ -# define HZ 1000 /* Internal kernel timer frequency */ +# define HZ CONFIG_HZ /* Internal kernel timer frequency */ # define USER_HZ 100 /* .. some user interfaces are in "ticks" */ # define CLOCKS_PER_SEC (USER_HZ) /* like times() */ #endif Index: build/arch/ppc64/configs/g5_defconfig =================================================================== --- build.orig/arch/ppc64/configs/g5_defconfig 2005-08-15 23:42:04.000000000 +1000 +++ build/arch/ppc64/configs/g5_defconfig 2005-08-24 07:55:50.000000000 +1000 @@ -103,10 +103,10 @@ # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set # CONFIG_PREEMPT_BKL is not set -CONFIG_HZ_100=y -# CONFIG_HZ_250 is not set +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y # CONFIG_HZ_1000 is not set -CONFIG_HZ=100 +CONFIG_HZ=250 CONFIG_GENERIC_HARDIRQS=y CONFIG_SECCOMP=y CONFIG_ISA_DMA_API=y Index: build/arch/ppc64/configs/iSeries_defconfig =================================================================== --- build.orig/arch/ppc64/configs/iSeries_defconfig 2005-08-15 23:42:04.000000000 +1000 +++ build/arch/ppc64/configs/iSeries_defconfig 2005-08-24 07:56:46.000000000 +1000 @@ -94,10 +94,10 @@ # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set # CONFIG_PREEMPT_BKL is not set -CONFIG_HZ_100=y -# CONFIG_HZ_250 is not set +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y # CONFIG_HZ_1000 is not set -CONFIG_HZ=100 +CONFIG_HZ=250 CONFIG_GENERIC_HARDIRQS=y CONFIG_MSCHUNKS=y CONFIG_LPARCFG=y Index: build/arch/ppc64/configs/maple_defconfig =================================================================== --- build.orig/arch/ppc64/configs/maple_defconfig 2005-08-15 23:42:04.000000000 +1000 +++ build/arch/ppc64/configs/maple_defconfig 2005-08-24 08:46:58.000000000 +1000 @@ -103,10 +103,10 @@ # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set # CONFIG_PREEMPT_BKL is not set -CONFIG_HZ_100=y -# CONFIG_HZ_250 is not set +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y # CONFIG_HZ_1000 is not set -CONFIG_HZ=100 +CONFIG_HZ=250 CONFIG_GENERIC_HARDIRQS=y CONFIG_SECCOMP=y CONFIG_ISA_DMA_API=y Index: build/arch/ppc64/configs/pSeries_defconfig =================================================================== --- build.orig/arch/ppc64/configs/pSeries_defconfig 2005-08-15 23:42:04.000000000 +1000 +++ build/arch/ppc64/configs/pSeries_defconfig 2005-08-24 07:58:38.000000000 +1000 @@ -112,10 +112,10 @@ # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set # CONFIG_PREEMPT_BKL is not set -CONFIG_HZ_100=y -# CONFIG_HZ_250 is not set +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y # CONFIG_HZ_1000 is not set -CONFIG_HZ=100 +CONFIG_HZ=250 CONFIG_EEH=y CONFIG_GENERIC_HARDIRQS=y CONFIG_PPC_RTAS=y Index: build/arch/ppc64/defconfig =================================================================== --- build.orig/arch/ppc64/defconfig 2005-08-15 23:42:04.000000000 +1000 +++ build/arch/ppc64/defconfig 2005-08-24 07:55:27.000000000 +1000 @@ -114,10 +114,10 @@ # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set # CONFIG_PREEMPT_BKL is not set -CONFIG_HZ_100=y -# CONFIG_HZ_250 is not set +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y # CONFIG_HZ_1000 is not set -CONFIG_HZ=100 +CONFIG_HZ=250 CONFIG_EEH=y CONFIG_GENERIC_HARDIRQS=y CONFIG_PPC_RTAS=y From linas at austin.ibm.com Wed Aug 24 09:35:46 2005 From: linas at austin.ibm.com (Linas Vepstas) Date: Tue, 23 Aug 2005 18:35:46 -0500 Subject: [patch 0/8] PCI Error Recovery patchset In-Reply-To: <20050823231817.829359000@bilge> References: <20050823231817.829359000@bilge> Message-ID: <20050823233545.GA18113@austin.ibm.com> What follows is a set of patches to implement a PCI error recovery system. Some (newer) PCI controllers are able to detect and report PCI errors, these patches enable this hardware function. -- the first patch adds documentation, explaining what this is and how it works. -- the next patch adds core infrastructure to include/linux/pci.h -- the next several patches add recovery support to three ethernet and two scsi drivers. -- the last patch is a big monster that implements the recovery driver for the ppc64-specific pci controllers. The first seven patches should apply cleanly to just about any recent kernel tree; the last patch requires GregKH's pci patchset, since some ppc64 functions changed recently. --linas -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: Digital signature Url : http://ozlabs.org/pipermail/linuxppc64-dev/attachments/20050823/8cc54006/attachment.pgp From linas at austin.ibm.com Wed Aug 24 09:39:27 2005 From: linas at austin.ibm.com (Linas Vepstas) Date: Tue, 23 Aug 2005 18:39:27 -0500 Subject: [patch 2/8] PCI Error Recovery: header file patch In-Reply-To: <20050823232140.337320000@bilge> References: <20050823231817.829359000@bilge> <20050823232140.337320000@bilge> Message-ID: <20050823233927.GC18113@austin.ibm.com> Various PCI bus errors can be signaled by newer PCI controllers. Recovering from those errors requires an infrastructure to notify affected device drivers of the error, and a way of walking through a reset sequence. This patch adds a set of callbacks to be used by error recovery routines to notify device drivers of the various stages of recovery. Signed-off-by: Linas Vepstas -- include/linux/pci.h | 39 +++++++++++++++++++++++++++++++++++++++ 1 files changed, 39 insertions(+) Index: linux-2.6.13-rc6-git9/include/linux/pci.h =================================================================== --- linux-2.6.13-rc6-git9.orig/include/linux/pci.h 2005-08-19 13:03:27.000000000 -0500 +++ linux-2.6.13-rc6-git9/include/linux/pci.h 2005-08-19 13:03:32.000000000 -0500 @@ -78,6 +78,16 @@ #define PCI_UNKNOWN ((pci_power_t __force) 5) #define PCI_POWER_ERROR ((pci_power_t __force) -1) +/** The pci_channel state describes connectivity between the CPU and + * the pci device. If some PCI bus between here and the pci device + * has crashed or locked up, this info is reflected here. + */ +enum pci_channel_state { + pci_channel_io_normal = 0, /* I/O channel is in normal state */ + pci_channel_io_frozen = 1, /* I/O to channel is blocked */ + pci_channel_io_perm_failure, /* PCI card is dead */ +}; + /* * The pci_dev structure is used to describe PCI devices. */ @@ -110,6 +120,7 @@ this is D0-D3, D0 being fully functional, and D3 being off. */ + enum pci_channel_state error_state; /* current connectivity state */ struct device dev; /* Generic device interface */ /* device is compatible with these IDs */ @@ -231,6 +242,33 @@ unsigned int use_driver_data:1; /* pci_driver->driver_data is used */ }; +/* ---------------------------------------------------------------- */ +/** PCI error recovery infrastructure. If a PCI device driver provides + * a set fof callbacks in struct pci_error_handlers, then that device driver + * will be notified of PCI bus errors, and will be driven to recovery + * when an error occurs. + */ + +enum pcierr_result { + PCIERR_RESULT_NONE=0, /* no result/none/not supported in device driver */ + PCIERR_RESULT_CAN_RECOVER=1, /* Device driver can recover without slot reset */ + PCIERR_RESULT_NEED_RESET, /* Device driver wants slot to be reset. */ + PCIERR_RESULT_DISCONNECT, /* Device has completely failed, is unrecoverable */ + PCIERR_RESULT_RECOVERED, /* Device driver is fully recovered and operational */ +}; + +/* PCI bus error event callbacks */ +struct pci_error_handlers +{ + int (*error_detected)(struct pci_dev *dev, enum pci_channel_state error); + int (*mmio_enabled)(struct pci_dev *dev); /* MMIO has been reanbled, but not DMA */ + int (*link_reset)(struct pci_dev *dev); /* PCI Express link has been reset */ + int (*slot_reset)(struct pci_dev *dev); /* PCI slot has been reset */ + void (*resume)(struct pci_dev *dev); /* Device driver may resume normal operations */ +}; + +/* ---------------------------------------------------------------- */ + struct module; struct pci_driver { struct list_head node; @@ -244,6 +282,7 @@ int (*enable_wake) (struct pci_dev *dev, pci_power_t state, int enable); /* Enable wake event */ void (*shutdown) (struct pci_dev *dev); + struct pci_error_handlers *err_handler; struct device_driver driver; struct pci_dynids dynids; }; -- -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: Digital signature Url : http://ozlabs.org/pipermail/linuxppc64-dev/attachments/20050823/5c9da39a/attachment.pgp From linas at austin.ibm.com Wed Aug 24 09:41:50 2005 From: linas at austin.ibm.com (Linas Vepstas) Date: Tue, 23 Aug 2005 18:41:50 -0500 Subject: [patch 3/8] PCI Error Recovery: IPR SCSI device driver In-Reply-To: <20050823232140.520090000@bilge> References: <20050823231817.829359000@bilge> <20050823232140.520090000@bilge> Message-ID: <20050823234150.GD18113@austin.ibm.com> Various PCI bus errors can be signaled by newer PCI controllers. This patch adds the PCI error recovery callbacks to the IPR SCSI device driver. The patch has been tested, and appears to work well. Signed-off-by: Linas Vepstas -- arch/ppc64/configs/pSeries_defconfig | 1 drivers/scsi/Kconfig | 8 +++ drivers/scsi/ipr.c | 93 +++++++++++++++++++++++++++++++++++ 3 files changed, 102 insertions(+) Index: linux-2.6.13-rc6-git9/drivers/scsi/Kconfig =================================================================== --- linux-2.6.13-rc6-git9.orig/drivers/scsi/Kconfig 2005-08-19 13:39:32.000000000 -0500 +++ linux-2.6.13-rc6-git9/drivers/scsi/Kconfig 2005-08-19 13:40:10.000000000 -0500 @@ -1065,6 +1065,14 @@ If you enable this support, the iprdump daemon can be used to capture adapter failure analysis information. +config SCSI_IPR_EEH_RECOVERY + bool "Enable PCI bus error recovery" + depends on SCSI_IPR && PPC_PSERIES + help + If you say Y here, the driver will be able to recover from + PCI bus errors on many PowerPC platforms. IBM pSeries users + should answer Y. + config SCSI_ZALON tristate "Zalon SCSI support" depends on GSC && SCSI Index: linux-2.6.13-rc6-git9/drivers/scsi/ipr.c =================================================================== --- linux-2.6.13-rc6-git9.orig/drivers/scsi/ipr.c 2005-08-19 13:39:31.000000000 -0500 +++ linux-2.6.13-rc6-git9/drivers/scsi/ipr.c 2005-08-19 13:40:09.000000000 -0500 @@ -5326,6 +5326,88 @@ shutdown_type); } +#ifdef CONFIG_SCSI_IPR_EEH_RECOVERY + +/** If the PCI slot is frozen, hold off all i/o + * activity; then, as soon as the slot is available again, + * initiate an adapter reset. + */ +static int ipr_reset_freeze(struct ipr_cmnd *ipr_cmd) +{ + list_add_tail(&ipr_cmd->queue, &ipr_cmd->ioa_cfg->pending_q); + ipr_cmd->done = ipr_reset_ioa_job; + return IPR_RC_JOB_RETURN; +} + +/** ipr_eeh_frozen -- called when slot has experience PCI bus error. + * This routine is called to tell us that the PCI bus is down. + * Can't do anything here, except put the device driver into a + * holding pattern, waiting for the PCI bus to come back. + */ +static void ipr_eeh_frozen (struct pci_dev *pdev) +{ + unsigned long flags = 0; + struct ipr_ioa_cfg *ioa_cfg = pci_get_drvdata(pdev); + + spin_lock_irqsave(ioa_cfg->host->host_lock, flags); + _ipr_initiate_ioa_reset(ioa_cfg, ipr_reset_freeze, IPR_SHUTDOWN_NONE); + spin_unlock_irqrestore(ioa_cfg->host->host_lock, flags); +} + +/** ipr_eeh_slot_reset - called when pci slot has been reset. + * + * This routine is called by the pci error recovery recovery + * code after the PCI slot has been reset, just before we + * should resume normal operations. + */ +static int ipr_eeh_slot_reset (struct pci_dev *pdev) +{ + unsigned long flags = 0; + struct ipr_ioa_cfg *ioa_cfg = pci_get_drvdata(pdev); + + pci_enable_device(pdev); + pci_set_master(pdev); + enable_irq (pdev->irq); + spin_lock_irqsave(ioa_cfg->host->host_lock, flags); + _ipr_initiate_ioa_reset(ioa_cfg, ipr_reset_restore_cfg_space, + IPR_SHUTDOWN_NONE); + spin_unlock_irqrestore(ioa_cfg->host->host_lock, flags); + + return PCIERR_RESULT_RECOVERED; +} + +/** This routine is called when the PCI bus has permanently + * failed. This routine should purge all pending I/O and + * shut down the device driver (close and unload). + * XXX Needs to be implemented. + */ +static void ipr_eeh_perm_failure (struct pci_dev *pdev) +{ +#if 0 // XXXXXXXXXXXXXXXXXXXXXXX + ipr_cmd->job_step = ipr_reset_shutdown_ioa; + rc = IPR_RC_JOB_CONTINUE; +#endif +} + +static int ipr_eeh_error_detected (struct pci_dev *pdev, + enum pci_channel_state state) +{ + switch (state) { + case pci_channel_io_frozen: + ipr_eeh_frozen (pdev); + return PCIERR_RESULT_NEED_RESET; + + case pci_channel_io_perm_failure: + ipr_eeh_perm_failure (pdev); + return PCIERR_RESULT_DISCONNECT; + break; + default: + break; + } + return PCIERR_RESULT_NEED_RESET; +} +#endif + /** * ipr_probe_ioa_part2 - Initializes IOAs found in ipr_probe_ioa(..) * @ioa_cfg: ioa cfg struct @@ -6063,12 +6145,23 @@ }; MODULE_DEVICE_TABLE(pci, ipr_pci_table); + +#ifdef CONFIG_SCSI_IPR_EEH_RECOVERY +static struct pci_error_handlers ipr_err_handler = { + .error_detected = ipr_eeh_error_detected, + .slot_reset = ipr_eeh_slot_reset, +}; +#endif /* CONFIG_SCSI_IPR_EEH_RECOVERY */ + static struct pci_driver ipr_driver = { .name = IPR_NAME, .id_table = ipr_pci_table, .probe = ipr_probe, .remove = ipr_remove, .shutdown = ipr_shutdown, +#ifdef CONFIG_SCSI_IPR_EEH_RECOVERY + .err_handler = &ipr_err_handler, +#endif /* CONFIG_SCSI_IPR_EEH_RECOVERY */ }; /** Index: linux-2.6.13-rc6-git9/arch/ppc64/configs/pSeries_defconfig =================================================================== --- linux-2.6.13-rc6-git9.orig/arch/ppc64/configs/pSeries_defconfig 2005-08-19 13:39:32.000000000 -0500 +++ linux-2.6.13-rc6-git9/arch/ppc64/configs/pSeries_defconfig 2005-08-19 13:40:44.000000000 -0500 @@ -476,6 +476,7 @@ CONFIG_SCSI_IPR=y CONFIG_SCSI_IPR_TRACE=y CONFIG_SCSI_IPR_DUMP=y +CONFIG_SCSI_IPR_EEH_RECOVERY=y # CONFIG_SCSI_QLOGIC_FC is not set # CONFIG_SCSI_QLOGIC_1280 is not set CONFIG_SCSI_QLA2XXX=y -- -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: Digital signature Url : http://ozlabs.org/pipermail/linuxppc64-dev/attachments/20050823/15a11c1c/attachment.pgp From linas at austin.ibm.com Wed Aug 24 09:43:15 2005 From: linas at austin.ibm.com (Linas Vepstas) Date: Tue, 23 Aug 2005 18:43:15 -0500 Subject: [patch 4/8] PCI Error Recovery: Symbios SCSI device driver In-Reply-To: <20050823232140.903067000@bilge> References: <20050823231817.829359000@bilge> <20050823232140.903067000@bilge> Message-ID: <20050823234315.GE18113@austin.ibm.com> Various PCI bus errors can be signaled by newer PCI controllers. This patch adds the PCI error recovery callbacks to the Symbios SCSI device driver. The patch has been tested, and appears to work well. Signed-off-by: Linas Vepstas -- arch/ppc64/configs/pSeries_defconfig | 1 drivers/scsi/Kconfig | 8 ++ drivers/scsi/sym53c8xx_2/sym_glue.c | 124 +++++++++++++++++++++++++++++++++++ drivers/scsi/sym53c8xx_2/sym_glue.h | 4 + drivers/scsi/sym53c8xx_2/sym_hipd.c | 16 ++++ 5 files changed, 153 insertions(+) Index: linux-2.6.13-rc6-git9/arch/ppc64/configs/pSeries_defconfig =================================================================== --- linux-2.6.13-rc6-git9.orig/arch/ppc64/configs/pSeries_defconfig 2005-08-19 13:40:44.000000000 -0500 +++ linux-2.6.13-rc6-git9/arch/ppc64/configs/pSeries_defconfig 2005-08-19 14:18:39.000000000 -0500 @@ -473,6 +473,7 @@ CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 # CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set +CONFIG_SCSI_SYM53C8XX_EEH_RECOVERY=y CONFIG_SCSI_IPR=y CONFIG_SCSI_IPR_TRACE=y CONFIG_SCSI_IPR_DUMP=y Index: linux-2.6.13-rc6-git9/drivers/scsi/Kconfig =================================================================== --- linux-2.6.13-rc6-git9.orig/drivers/scsi/Kconfig 2005-08-19 13:40:10.000000000 -0500 +++ linux-2.6.13-rc6-git9/drivers/scsi/Kconfig 2005-08-19 14:18:09.000000000 -0500 @@ -1040,6 +1040,14 @@ the card. This is significantly slower then using memory mapped IO. Most people should answer N. +config SCSI_SYM53C8XX_EEH_RECOVERY + bool "Enable PCI bus error recovery" + depends on SCSI_SYM53C8XX_2 && PPC_PSERIES + help + If you say Y here, the driver will be able to recover from + PCI bus errors on many PowerPC platforms. IBM pSeries users + should answer Y. + config SCSI_IPR tristate "IBM Power Linux RAID adapter support" depends on PCI && SCSI Index: linux-2.6.13-rc6-git9/drivers/scsi/sym53c8xx_2/sym_glue.c =================================================================== --- linux-2.6.13-rc6-git9.orig/drivers/scsi/sym53c8xx_2/sym_glue.c 2005-08-17 15:14:15.000000000 -0500 +++ linux-2.6.13-rc6-git9/drivers/scsi/sym53c8xx_2/sym_glue.c 2005-08-19 14:23:02.000000000 -0500 @@ -685,6 +685,10 @@ struct sym_hcb *np = (struct sym_hcb *)dev_id; if (DEBUG_FLAGS & DEBUG_TINY) printf_debug ("["); +#ifdef CONFIG_SCSI_SYM53C8XX_EEH_RECOVERY + if (np->s.io_state != pci_channel_io_normal) + return IRQ_HANDLED; +#endif /* CONFIG_SCSI_SYM53C8XX_EEH_RECOVERY */ spin_lock_irqsave(np->s.host->host_lock, flags); sym_interrupt(np); @@ -759,6 +763,27 @@ */ static void sym_eh_timeout(u_long p) { __sym_eh_done((struct scsi_cmnd *)p, 1); } +#ifdef CONFIG_SCSI_SYM53C8XX_EEH_RECOVERY +static void sym_eeh_timeout(u_long p) +{ + struct sym_eh_wait *ep = (struct sym_eh_wait *) p; + if (!ep) + return; + complete(&ep->done); +} + +static void sym_eeh_done(struct sym_eh_wait *ep) +{ + if (!ep) + return; + ep->timed_out = 0; + if (!del_timer(&ep->timer)) + return; + + complete(&ep->done); +} +#endif /* CONFIG_SCSI_SYM53C8XX_EEH_RECOVERY */ + /* * Generic method for our eh processing. * The 'op' argument tells what we have to do. @@ -799,6 +824,37 @@ /* Try to proceed the operation we have been asked for */ sts = -1; +#ifdef CONFIG_SCSI_SYM53C8XX_EEH_RECOVERY + + /* We may be in an error condition because the PCI bus + * went down. In this case, we need to wait until the + * PCI bus is reset, the card is reset, and only then + * proceed with the scsi error recovery. We'll wait + * for 15 seconds for this to happen. + */ +#define WAIT_FOR_PCI_RECOVERY 15 + if (np->s.io_state != pci_channel_io_normal) { + struct sym_eh_wait eeh, *eep = &eeh; + np->s.io_reset_wait = eep; + init_completion(&eep->done); + init_timer(&eep->timer); + eep->to_do = SYM_EH_DO_WAIT; + eep->timer.expires = jiffies + (WAIT_FOR_PCI_RECOVERY*HZ); + eep->timer.function = sym_eeh_timeout; + eep->timer.data = (u_long)eep; + eep->timed_out = 1; /* Be pessimistic for once :) */ + add_timer(&eep->timer); + spin_unlock_irq(np->s.host->host_lock); + wait_for_completion(&eep->done); + spin_lock_irq(np->s.host->host_lock); + if (eep->timed_out) { + printk (KERN_ERR "%s: Timed out waiting for PCI reset\n", + sym_name(np)); + } + np->s.io_reset_wait = NULL; + } +#endif /* CONFIG_SCSI_SYM53C8XX_EEH_RECOVERY */ + switch(op) { case SYM_EH_ABORT: sts = sym_abort_scsiio(np, cmd, 1); @@ -1584,6 +1640,10 @@ np->maxoffs = dev->chip.offset_max; np->maxburst = dev->chip.burst_max; np->myaddr = dev->host_id; +#ifdef CONFIG_SCSI_SYM53C8XX_EEH_RECOVERY + np->s.io_state = pci_channel_io_normal; + np->s.io_reset_wait = NULL; +#endif /* CONFIG_SCSI_SYM53C8XX_EEH_RECOVERY */ /* * Edit its name. @@ -1916,6 +1976,59 @@ return 1; } +#ifdef CONFIG_SCSI_SYM53C8XX_EEH_RECOVERY +/** sym2_io_error_detected() is called when PCI error is detected */ +static int sym2_io_error_detected (struct pci_dev *pdev, enum pci_channel_state state) +{ + struct sym_hcb *np = pci_get_drvdata(pdev); + + np->s.io_state = state; + // XXX If slot is permanently frozen, then what? + // Should we scsi_remove_host() maybe ?? + + /* Request a slot slot reset. */ + return PCIERR_RESULT_NEED_RESET; +} + +/** sym2_io_slot_reset is called when the pci bus has been reset. + * Restart the card from scratch. */ +static int sym2_io_slot_reset (struct pci_dev *pdev) +{ + struct sym_hcb *np = pci_get_drvdata(pdev); + + printk (KERN_INFO "%s: recovering from a PCI slot reset\n", + sym_name(np)); + + if (pci_enable_device(pdev)) + printk (KERN_ERR "%s: device setup failed most egregiously\n", + sym_name(np)); + + pci_set_master(pdev); + enable_irq (pdev->irq); + + /* Perform host reset only on one instance of the card */ + if (0 == PCI_FUNC (pdev->devfn)) + sym_reset_scsi_bus(np, 0); + + return PCIERR_RESULT_RECOVERED; +} + +/** sym2_io_resume is called when the error recovery driver + * tells us that its OK to resume normal operation. + */ +static void sym2_io_resume (struct pci_dev *pdev) +{ + struct sym_hcb *np = pci_get_drvdata(pdev); + + /* Perform device startup only once for this card. */ + if (0 == PCI_FUNC (pdev->devfn)) + sym_start_up (np, 1); + + np->s.io_state = pci_channel_io_normal; + sym_eeh_done (np->s.io_reset_wait); +} +#endif /* CONFIG_SCSI_SYM53C8XX_EEH_RECOVERY */ + /* * Driver host template. */ @@ -2169,11 +2282,22 @@ MODULE_DEVICE_TABLE(pci, sym2_id_table); +#ifdef CONFIG_SCSI_SYM53C8XX_EEH_RECOVERY +static struct pci_error_handlers sym2_err_handler = { + .error_detected = sym2_io_error_detected, + .slot_reset = sym2_io_slot_reset, + .resume = sym2_io_resume, +}; +#endif /* CONFIG_SCSI_SYM53C8XX_EEH_RECOVERY */ + static struct pci_driver sym2_driver = { .name = NAME53C8XX, .id_table = sym2_id_table, .probe = sym2_probe, .remove = __devexit_p(sym2_remove), +#ifdef CONFIG_SCSI_SYM53C8XX_EEH_RECOVERY + .err_handler = &sym2_err_handler, +#endif /* CONFIG_SCSI_SYM53C8XX_EEH_RECOVERY */ }; static int __init sym2_init(void) Index: linux-2.6.13-rc6-git9/drivers/scsi/sym53c8xx_2/sym_glue.h =================================================================== --- linux-2.6.13-rc6-git9.orig/drivers/scsi/sym53c8xx_2/sym_glue.h 2005-08-17 15:14:15.000000000 -0500 +++ linux-2.6.13-rc6-git9/drivers/scsi/sym53c8xx_2/sym_glue.h 2005-08-19 14:18:09.000000000 -0500 @@ -181,6 +181,10 @@ char chip_name[8]; struct pci_dev *device; + /* pci bus i/o state; waiter for clearing of i/o state */ + enum pci_channel_state io_state; + struct sym_eh_wait *io_reset_wait; + struct Scsi_Host *host; void __iomem * ioaddr; /* MMIO kernel io address */ Index: linux-2.6.13-rc6-git9/drivers/scsi/sym53c8xx_2/sym_hipd.c =================================================================== --- linux-2.6.13-rc6-git9.orig/drivers/scsi/sym53c8xx_2/sym_hipd.c 2005-08-17 15:14:15.000000000 -0500 +++ linux-2.6.13-rc6-git9/drivers/scsi/sym53c8xx_2/sym_hipd.c 2005-08-19 14:20:44.000000000 -0500 @@ -2806,6 +2806,7 @@ u_char istat, istatc; u_char dstat; u_short sist; + u_int icnt; /* * interrupt on the fly ? @@ -2847,6 +2848,7 @@ sist = 0; dstat = 0; istatc = istat; + icnt = 0; do { if (istatc & SIP) sist |= INW(np, nc_sist); @@ -2854,6 +2856,20 @@ dstat |= INB(np, nc_dstat); istatc = INB(np, nc_istat); istat |= istatc; +#ifdef CONFIG_SCSI_SYM53C8XX_EEH_RECOVERY + /* Prevent deadlock waiting on a condition that may never clear. */ + /* XXX this is a temporary kludge; the correct to detect + * a PCI bus error would be to use the io_check interfaces + * proposed by Hidetoshi Seto + * Problem with polling like that is the state flag might not + * be set. + */ + icnt ++; + if (100 < icnt) { + if (np->s.device->error_state != pci_channel_io_normal) + return; + } +#endif /* CONFIG_SCSI_SYM53C8XX_EEH_RECOVERY */ } while (istatc & (SIP|DIP)); if (DEBUG_FLAGS & DEBUG_TINY) -- -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: Digital signature Url : http://ozlabs.org/pipermail/linuxppc64-dev/attachments/20050823/37d25385/attachment.pgp From linas at austin.ibm.com Wed Aug 24 09:45:23 2005 From: linas at austin.ibm.com (Linas Vepstas) Date: Tue, 23 Aug 2005 18:45:23 -0500 Subject: [patch 5/8] PCI Error Recovery: e100 network device driver In-Reply-To: <20050823232141.286102000@bilge> References: <20050823231817.829359000@bilge> <20050823232141.286102000@bilge> Message-ID: <20050823234523.GF18113@austin.ibm.com> Various PCI bus errors can be signaled by newer PCI controllers. This patch adds the PCI error recovery callbacks to the intel ethernet e100 device driver. The patch has been tested, and appears to work well. Signed-off-by: Linas Vepstas -- arch/ppc64/configs/pSeries_defconfig | 1 drivers/net/Kconfig | 8 +++ drivers/net/e100.c | 73 +++++++++++++++++++++++++++++++++++ 3 files changed, 82 insertions(+) Index: linux-2.6.13-rc6-git9/arch/ppc64/configs/pSeries_defconfig =================================================================== --- linux-2.6.13-rc6-git9.orig/arch/ppc64/configs/pSeries_defconfig 2005-08-19 14:18:39.000000000 -0500 +++ linux-2.6.13-rc6-git9/arch/ppc64/configs/pSeries_defconfig 2005-08-19 14:31:26.000000000 -0500 @@ -574,6 +574,7 @@ # CONFIG_DGRS is not set # CONFIG_EEPRO100 is not set CONFIG_E100=y +CONFIG_E100_EEH_RECOVERY=y # CONFIG_FEALNX is not set # CONFIG_NATSEMI is not set # CONFIG_NE2K_PCI is not set Index: linux-2.6.13-rc6-git9/drivers/net/Kconfig =================================================================== --- linux-2.6.13-rc6-git9.orig/drivers/net/Kconfig 2005-08-17 15:13:33.000000000 -0500 +++ linux-2.6.13-rc6-git9/drivers/net/Kconfig 2005-08-19 14:31:26.000000000 -0500 @@ -1392,6 +1392,14 @@ . The module will be called e100. +config E100_EEH_RECOVERY + bool "Enable PCI bus error recovery" + depends on E100 && PPC_PSERIES + help + If you say Y here, the driver will be able to recover from + PCI bus errors on many PowerPC platforms. IBM pSeries users + should answer Y. + config LNE390 tristate "Mylex EISA LNE390A/B support (EXPERIMENTAL)" depends on NET_PCI && EISA && EXPERIMENTAL Index: linux-2.6.13-rc6-git9/drivers/net/e100.c =================================================================== --- linux-2.6.13-rc6-git9.orig/drivers/net/e100.c 2005-08-17 15:13:36.000000000 -0500 +++ linux-2.6.13-rc6-git9/drivers/net/e100.c 2005-08-19 14:34:11.000000000 -0500 @@ -2459,6 +2459,76 @@ #endif } +#ifdef CONFIG_E100_EEH_RECOVERY + +/** e100_io_error_detected() is called when PCI error is detected */ +static int e100_io_error_detected (struct pci_dev *pdev, enum pci_channel_state state) +{ + struct net_device *netdev = pci_get_drvdata(pdev); + + /* Same as calling e100_down(netdev_priv(netdev)), but generic */ + netdev->stop(netdev); + + /* Is a detach needed ?? */ + // netif_device_detach(netdev); + + /* Request a slot reset. */ + return PCIERR_RESULT_NEED_RESET; +} + +/** e100_io_slot_reset is called after the pci bus has been reset. + * Restart the card from scratch. */ +static int e100_io_slot_reset (struct pci_dev *pdev) +{ + struct net_device *netdev = pci_get_drvdata(pdev); + struct nic *nic = netdev_priv(netdev); + + if(pci_enable_device(pdev)) { + printk(KERN_ERR "e100: Cannot re-enable PCI device after reset.\n"); + return PCIERR_RESULT_DISCONNECT; + } + pci_set_master(pdev); + + /* Only one device per card can do a reset */ + if (0 != PCI_FUNC (pdev->devfn)) + return PCIERR_RESULT_RECOVERED; + + e100_hw_reset(nic); + e100_phy_init(nic); + + if(e100_hw_init(nic)) { + DPRINTK(HW, ERR, "e100_hw_init failed\n"); + return PCIERR_RESULT_DISCONNECT; + } + + return PCIERR_RESULT_RECOVERED; +} + +/** e100_io_resume is called when the error recovery driver + * tells us that its OK to resume normal operation. + */ +static void e100_io_resume (struct pci_dev *pdev) +{ + struct net_device *netdev = pci_get_drvdata(pdev); + struct nic *nic = netdev_priv(netdev); + + /* ack any pending wake events, disable PME */ + pci_enable_wake(pdev, 0, 0); + + netif_device_attach(netdev); + if(netif_running(netdev)) + e100_open (netdev); + + mod_timer(&nic->watchdog, jiffies); +} + +static struct pci_error_handlers e100_err_handler = { + .error_detected = e100_io_error_detected, + .slot_reset = e100_io_slot_reset, + .resume = e100_io_resume, +}; + +#endif /* CONFIG_E100_EEH_RECOVERY */ static struct pci_driver e100_driver = { .name = DRV_NAME, @@ -2470,6 +2540,9 @@ .resume = e100_resume, #endif .shutdown = e100_shutdown, +#ifdef CONFIG_E100_EEH_RECOVERY + .err_handler = &e100_err_handler, +#endif /* CONFIG_E100_EEH_RECOVERY */ }; static int __init e100_init_module(void) -- -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: Digital signature Url : http://ozlabs.org/pipermail/linuxppc64-dev/attachments/20050823/03e4ed0f/attachment.pgp From linas at austin.ibm.com Wed Aug 24 09:46:08 2005 From: linas at austin.ibm.com (Linas Vepstas) Date: Tue, 23 Aug 2005 18:46:08 -0500 Subject: [patch 6/8] PCI Error Recovery: e1000 network device driver In-Reply-To: <20050823232141.925586000@bilge> References: <20050823231817.829359000@bilge> <20050823232141.925586000@bilge> Message-ID: <20050823234608.GG18113@austin.ibm.com> Various PCI bus errors can be signaled by newer PCI controllers. This patch adds the PCI error recovery callbacks to the intel gigabit ethernet e1000 device driver. The patch has been tested, and appears to work well. Signed-off-by: Linas Vepstas -- arch/ppc64/configs/pSeries_defconfig | 1 drivers/net/Kconfig | 8 ++ drivers/net/e1000/e1000_main.c | 103 ++++++++++++++++++++++++++++++++++- 3 files changed, 111 insertions(+), 1 deletion(-) Index: linux-2.6.13-rc6-git9/arch/ppc64/configs/pSeries_defconfig =================================================================== --- linux-2.6.13-rc6-git9.orig/arch/ppc64/configs/pSeries_defconfig 2005-08-19 14:47:01.000000000 -0500 +++ linux-2.6.13-rc6-git9/arch/ppc64/configs/pSeries_defconfig 2005-08-19 14:47:18.000000000 -0500 @@ -593,6 +593,7 @@ # CONFIG_DL2K is not set CONFIG_E1000=y # CONFIG_E1000_NAPI is not set +CONFIG_E1000_EEH_RECOVERY=y # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set Index: linux-2.6.13-rc6-git9/drivers/net/Kconfig =================================================================== --- linux-2.6.13-rc6-git9.orig/drivers/net/Kconfig 2005-08-19 14:47:01.000000000 -0500 +++ linux-2.6.13-rc6-git9/drivers/net/Kconfig 2005-08-19 14:47:18.000000000 -0500 @@ -1847,6 +1847,14 @@ If in doubt, say N. +config E1000_EEH_RECOVERY + bool "Enable PCI bus error recovery" + depends on E1000 && PPC_PSERIES + help + If you say Y here, the driver will be able to recover from + PCI bus errors on many PowerPC platforms. IBM pSeries users + should answer Y. + config MYRI_SBUS tristate "MyriCOM Gigabit Ethernet support" depends on SBUS Index: linux-2.6.13-rc6-git9/drivers/net/e1000/e1000_main.c =================================================================== --- linux-2.6.13-rc6-git9.orig/drivers/net/e1000/e1000_main.c 2005-08-19 14:47:01.000000000 -0500 +++ linux-2.6.13-rc6-git9/drivers/net/e1000/e1000_main.c 2005-08-19 14:51:12.000000000 -0500 @@ -172,6 +172,18 @@ static void e1000_netpoll (struct net_device *netdev); #endif +#ifdef CONFIG_E1000_EEH_RECOVERY +static int e1000_io_error_detected (struct pci_dev *pdev, enum pci_channel_state state); +static int e1000_io_slot_reset (struct pci_dev *pdev); +static void e1000_io_resume (struct pci_dev *pdev); + +static struct pci_error_handlers e1000_err_handler = { + .error_detected = e1000_io_error_detected, + .slot_reset = e1000_io_slot_reset, + .resume = e1000_io_resume, +}; +#endif /* CONFIG_E1000_EEH_RECOVERY */ + /* Exported from other modules */ extern void e1000_check_options(struct e1000_adapter *adapter); @@ -184,8 +196,11 @@ /* Power Managment Hooks */ #ifdef CONFIG_PM .suspend = e1000_suspend, - .resume = e1000_resume + .resume = e1000_resume, #endif +#ifdef CONFIG_E1000_EEH_RECOVERY + .err_handler = &e1000_err_handler, +#endif /* CONFIG_E1000_EEH_RECOVERY */ }; @@ -3796,4 +3811,90 @@ } #endif +#ifdef CONFIG_E1000_EEH_RECOVERY + +/** e1000_io_error_detected() is called when PCI error is detected */ +static int e1000_io_error_detected (struct pci_dev *pdev, enum pci_channel_state state) +{ + struct net_device *netdev = pci_get_drvdata(pdev); + struct e1000_adapter *adapter = netdev->priv; + + if(netif_running(netdev)) + e1000_down(adapter); + + /* Request a slot slot reset. */ + return PCIERR_RESULT_NEED_RESET; +} + +/** e1000_io_slot_reset is called after the pci bus has been reset. + * Restart the card from scratch. + * Implementation resembles the first-half of the + * e1000_resume routine. + */ +static int e1000_io_slot_reset (struct pci_dev *pdev) +{ + struct net_device *netdev = pci_get_drvdata(pdev); + struct e1000_adapter *adapter = netdev->priv; + + if(pci_enable_device(pdev)) { + printk(KERN_ERR "e1000: Cannot re-enable PCI device after reset.\n"); + return PCIERR_RESULT_DISCONNECT; + } + pci_set_master(pdev); + + pci_enable_wake(pdev, 3, 0); + pci_enable_wake(pdev, 4, 0); /* 4 == D3 cold */ + + /* Perform card reset only on one instance of the card */ + if (0 != PCI_FUNC (pdev->devfn)) + return PCIERR_RESULT_RECOVERED; + + e1000_reset(adapter); + E1000_WRITE_REG(&adapter->hw, WUS, ~0); + + return PCIERR_RESULT_RECOVERED; +} + +/** e1000_io_resume is called when the error recovery driver + * tells us that its OK to resume normal operation. + * Implementation resembles the second-half of the + * e1000_resume routine. + */ +static void e1000_io_resume (struct pci_dev *pdev) +{ + struct net_device *netdev = pci_get_drvdata(pdev); + struct e1000_adapter *adapter = netdev->priv; + uint32_t manc, swsm; + + if(netif_running(netdev)) { + if(e1000_up(adapter)) { + printk ("e1000: can't bring device back up after reset\n"); + return; + } + } + + netif_device_attach(netdev); + + if(adapter->hw.mac_type >= e1000_82540 && + adapter->hw.media_type == e1000_media_type_copper) { + manc = E1000_READ_REG(&adapter->hw, MANC); + manc &= ~(E1000_MANC_ARP_EN); + E1000_WRITE_REG(&adapter->hw, MANC, manc); + } + + switch(adapter->hw.mac_type) { + case e1000_82573: + swsm = E1000_READ_REG(&adapter->hw, SWSM); + E1000_WRITE_REG(&adapter->hw, SWSM, + swsm | E1000_SWSM_DRV_LOAD); + break; + default: + break; + } + + mod_timer(&adapter->watchdog_timer, jiffies); +} + +#endif /* CONFIG_E1000_EEH_RECOVERY */ + /* e1000_main.c */ -- -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: Digital signature Url : http://ozlabs.org/pipermail/linuxppc64-dev/attachments/20050823/24d15eb6/attachment.pgp From linas at austin.ibm.com Wed Aug 24 09:47:02 2005 From: linas at austin.ibm.com (Linas Vepstas) Date: Tue, 23 Aug 2005 18:47:02 -0500 Subject: [patch 7/8] PCI Error Recovery: ixgb network device driver In-Reply-To: <20050823232142.651390000@bilge> References: <20050823231817.829359000@bilge> <20050823232142.651390000@bilge> Message-ID: <20050823234702.GH18113@austin.ibm.com> Various PCI bus errors can be signaled by newer PCI controllers. This patch adds the PCI error recovery callbacks to the intel ten-gigabit ethernet ixgb device driver. The patch has been tested, and appears to work well. Signed-off-by: Linas Vepstas -- arch/ppc64/configs/pSeries_defconfig | 1 drivers/net/Kconfig | 8 +++ drivers/net/ixgb/ixgb_main.c | 78 +++++++++++++++++++++++++++++++++++ 3 files changed, 87 insertions(+) Index: linux-2.6.13-rc6-git9/arch/ppc64/configs/pSeries_defconfig =================================================================== --- linux-2.6.13-rc6-git9.orig/arch/ppc64/configs/pSeries_defconfig 2005-08-19 14:47:18.000000000 -0500 +++ linux-2.6.13-rc6-git9/arch/ppc64/configs/pSeries_defconfig 2005-08-19 14:57:35.000000000 -0500 @@ -610,6 +610,7 @@ # CONFIG_IXGB=m # CONFIG_IXGB_NAPI is not set +CONFIG_IXGB_EEH_RECOVERY=y CONFIG_S2IO=m # CONFIG_S2IO_NAPI is not set # CONFIG_2BUFF_MODE is not set Index: linux-2.6.13-rc6-git9/drivers/net/Kconfig =================================================================== --- linux-2.6.13-rc6-git9.orig/drivers/net/Kconfig 2005-08-19 14:47:18.000000000 -0500 +++ linux-2.6.13-rc6-git9/drivers/net/Kconfig 2005-08-19 14:57:35.000000000 -0500 @@ -2146,6 +2146,14 @@ If in doubt, say N. +config IXGB_EEH_RECOVERY + bool "Enable PCI bus error recovery" + depends on IXGB && PPC_PSERIES + help + If you say Y here, the driver will be able to recover from + PCI bus errors on many PowerPC platforms. IBM pSeries users + should answer Y. + config S2IO tristate "S2IO 10Gbe XFrame NIC" depends on PCI Index: linux-2.6.13-rc6-git9/drivers/net/ixgb/ixgb_main.c =================================================================== --- linux-2.6.13-rc6-git9.orig/drivers/net/ixgb/ixgb_main.c 2005-08-17 15:13:45.000000000 -0500 +++ linux-2.6.13-rc6-git9/drivers/net/ixgb/ixgb_main.c 2005-08-19 14:57:35.000000000 -0500 @@ -128,6 +128,18 @@ static void ixgb_netpoll(struct net_device *dev); #endif +#ifdef CONFIG_IXGB_EEH_RECOVERY +static int ixgb_io_error_detected (struct pci_dev *pdev, enum pci_channel_state state); +static int ixgb_io_slot_reset (struct pci_dev *pdev); +static void ixgb_io_resume (struct pci_dev *pdev); + +static struct pci_error_handlers ixgb_err_handler = { + .error_detected = ixgb_io_error_detected, + .slot_reset = ixgb_io_slot_reset, + .resume = ixgb_io_resume, +}; +#endif /* CONFIG_IXGB_EEH_RECOVERY */ + /* Exported from other modules */ extern void ixgb_check_options(struct ixgb_adapter *adapter); @@ -137,6 +149,10 @@ .id_table = ixgb_pci_tbl, .probe = ixgb_probe, .remove = __devexit_p(ixgb_remove), +#ifdef CONFIG_IXGB_EEH_RECOVERY + .err_handler = &ixgb_err_handler, +#endif /* CONFIG_IXGB_EEH_RECOVERY */ + }; MODULE_AUTHOR("Intel Corporation, "); @@ -2119,4 +2135,66 @@ } #endif +#ifdef CONFIG_IXGB_EEH_RECOVERY + +/** ixgb_io_error_detected() is called when PCI error is detected */ +static int ixgb_io_error_detected (struct pci_dev *pdev, enum pci_channel_state state) +{ + struct net_device *netdev = pci_get_drvdata(pdev); + struct ixgb_adapter *adapter = netdev->priv; + + if(netif_running(netdev)) + ixgb_down(adapter, TRUE); + + /* Request a slot reset. */ + return PCIERR_RESULT_NEED_RESET; +} + +/** ixgb_io_slot_reset is called after the pci bus has been reset. + * Restart the card from scratch. + * Implementation resembles the first-half of the + * ixgb_resume routine. + */ +static int ixgb_io_slot_reset (struct pci_dev *pdev) +{ + struct net_device *netdev = pci_get_drvdata(pdev); + struct ixgb_adapter *adapter = netdev->priv; + + if(pci_enable_device(pdev)) { + printk(KERN_ERR "ixgb: Cannot re-enable PCI device after reset.\n"); + return PCIERR_RESULT_DISCONNECT; + } + pci_set_master(pdev); + + /* Perform card reset only on one instance of the card */ + if (0 != PCI_FUNC (pdev->devfn)) + return PCIERR_RESULT_RECOVERED; + + ixgb_reset(adapter); + + return PCIERR_RESULT_RECOVERED; +} + +/** ixgb_io_resume is called when the error recovery driver + * tells us that its OK to resume normal operation. + * Implementation resembles the second-half of the + * ixgb_resume routine. + */ +static void ixgb_io_resume (struct pci_dev *pdev) +{ + struct net_device *netdev = pci_get_drvdata(pdev); + struct ixgb_adapter *adapter = netdev->priv; + + if(netif_running(netdev)) { + if(ixgb_up(adapter)) { + printk ("ixgb: can't bring device back up after reset\n"); + return; + } + } + + netif_device_attach(netdev); + mod_timer(&adapter->watchdog_timer, jiffies); +} +#endif /* CONFIG_IXGB_EEH_RECOVERY */ + /* ixgb_main.c */ -- -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: Digital signature Url : http://ozlabs.org/pipermail/linuxppc64-dev/attachments/20050823/13689fc8/attachment.pgp From linas at austin.ibm.com Wed Aug 24 09:47:47 2005 From: linas at austin.ibm.com (Linas Vepstas) Date: Tue, 23 Aug 2005 18:47:47 -0500 Subject: [patch 8/8] PCI Error Recovery: PPC64 core recovery routines In-Reply-To: <20050823232143.003048000@bilge> References: <20050823231817.829359000@bilge> <20050823232143.003048000@bilge> Message-ID: <20050823234747.GI18113@austin.ibm.com> Various PCI bus errors can be signaled by newer PCI controllers. The core error recovery routines are architecture dependent. This patch adds a recovery infrastructure for the PPC64 pSeries systems. Signed-off-by: Linas Vepstas -- arch/ppc64/kernel/Makefile | 2 arch/ppc64/kernel/eeh.c | 543 +++++++++++++++++++++++++++++------------ arch/ppc64/kernel/eeh_driver.c | 361 +++++++++++++++++++++++++++ arch/ppc64/kernel/eeh_event.c | 116 ++++++++ arch/ppc64/kernel/eeh_event.h | 52 +++ arch/ppc64/kernel/rtas_pci.c | 5 include/asm-ppc64/eeh.h | 105 +++++-- include/asm-ppc64/prom.h | 10 include/asm-ppc64/rtas.h | 2 9 files changed, 1001 insertions(+), 195 deletions(-) Index: linux-2.6.13-rc6-git9/arch/ppc64/kernel/eeh.c =================================================================== --- linux-2.6.13-rc6-git9.orig/arch/ppc64/kernel/eeh.c 2005-08-19 12:52:31.000000000 -0500 +++ linux-2.6.13-rc6-git9/arch/ppc64/kernel/eeh.c 2005-08-23 16:53:05.000000000 -0500 @@ -1,32 +1,33 @@ /* + * * eeh.c * Copyright (C) 2001 Dave Engebretsen & Todd Inglett IBM Corporation - * + * * 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 */ -#include +#include #include +#include #include -#include -#include #include #include #include #include #include +#include #include #include #include @@ -34,6 +35,7 @@ #include #include #include "pci.h" +#include "eeh_event.h" #undef DEBUG @@ -49,8 +51,8 @@ * were "empty": all reads return 0xff's and all writes are silently * ignored. EEH slot isolation events can be triggered by parity * errors on the address or data busses (e.g. during posted writes), - * which in turn might be caused by dust, vibration, humidity, - * radioactivity or plain-old failed hardware. + * which in turn might be caused by low voltage on the bus, dust, + * vibration, humidity, radioactivity or plain-old failed hardware. * * Note, however, that one of the leading causes of EEH slot * freeze events are buggy device drivers, buggy device microcode, @@ -75,22 +77,13 @@ #define BUID_HI(buid) ((buid) >> 32) #define BUID_LO(buid) ((buid) & 0xffffffff) -/* EEH event workqueue setup. */ -static DEFINE_SPINLOCK(eeh_eventlist_lock); -LIST_HEAD(eeh_eventlist); -static void eeh_event_handler(void *); -DECLARE_WORK(eeh_event_wq, eeh_event_handler, NULL); - -static struct notifier_block *eeh_notifier_chain; - /* * If a device driver keeps reading an MMIO register in an interrupt * handler after a slot isolation event has occurred, we assume it * is broken and panic. This sets the threshold for how many read * attempts we allow before panicking. */ -#define EEH_MAX_FAILS 1000 -static atomic_t eeh_fail_count; +#define EEH_MAX_FAILS 100000 /* RTAS tokens */ static int ibm_set_eeh_option; @@ -107,6 +100,10 @@ static int eeh_error_buf_size; /* System monitoring statistics */ +static DEFINE_PER_CPU(unsigned long, no_device); +static DEFINE_PER_CPU(unsigned long, no_dn); +static DEFINE_PER_CPU(unsigned long, no_cfg_addr); +static DEFINE_PER_CPU(unsigned long, ignored_check); static DEFINE_PER_CPU(unsigned long, total_mmio_ffs); static DEFINE_PER_CPU(unsigned long, false_positives); static DEFINE_PER_CPU(unsigned long, ignored_failures); @@ -224,9 +221,9 @@ while (*p) { parent = *p; piar = rb_entry(parent, struct pci_io_addr_range, rb_node); - if (alo < piar->addr_lo) { + if (ahi < piar->addr_lo) { p = &parent->rb_left; - } else if (ahi > piar->addr_hi) { + } else if (alo > piar->addr_hi) { p = &parent->rb_right; } else { if (dev != piar->pcidev || @@ -245,6 +242,11 @@ piar->pcidev = dev; piar->flags = flags; +#ifdef DEBUG + printk (KERN_DEBUG "PIAR: insert range=[%lx:%lx] dev=%s\n", + alo, ahi, pci_name (dev)); +#endif + rb_link_node(&piar->rb_node, parent, p); rb_insert_color(&piar->rb_node, &pci_io_addr_cache_root.rb_root); @@ -268,8 +270,8 @@ if (!(dn->eeh_mode & EEH_MODE_SUPPORTED) || dn->eeh_mode & EEH_MODE_NOCHECK) { #ifdef DEBUG - printk(KERN_INFO "PCI: skip building address cache for=%s\n", - pci_name(dev)); + printk(KERN_INFO "PCI: skip building address cache for=%s %s\n", + pci_name(dev), dn->type); #endif return; } @@ -368,8 +370,12 @@ */ void __init pci_addr_cache_build(void) { + struct device_node *dn; struct pci_dev *dev = NULL; + if (!eeh_subsystem_enabled) + return; + spin_lock_init(&pci_io_addr_cache_root.piar_lock); while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { @@ -378,6 +384,17 @@ continue; } pci_addr_cache_insert_device(dev); + + /* Save the BAR's; firmware doesn't restore these after EEH reset */ + dn = pci_device_to_OF_node(dev); + if (dn) { + int i; + for (i = 0; i < 16; i++) + pci_read_config_dword(dev, i * 4, &dn->config_space[i]); + + if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) + dn->eeh_is_bridge = 1; + } } #ifdef DEBUG @@ -389,24 +406,32 @@ /* --------------------------------------------------------------- */ /* Above lies the PCI Address Cache. Below lies the EEH event infrastructure */ -/** - * eeh_register_notifier - Register to find out about EEH events. - * @nb: notifier block to callback on events - */ -int eeh_register_notifier(struct notifier_block *nb) +void eeh_slot_error_detail (struct device_node *dn, int severity) { - return notifier_chain_register(&eeh_notifier_chain, nb); -} + unsigned long flags; + int rc; -/** - * eeh_unregister_notifier - Unregister to an EEH event notifier. - * @nb: notifier block to callback on events - */ -int eeh_unregister_notifier(struct notifier_block *nb) -{ - return notifier_chain_unregister(&eeh_notifier_chain, nb); + if (!dn) return; + + /* Log the error with the rtas logger */ + spin_lock_irqsave(&slot_errbuf_lock, flags); + memset(slot_errbuf, 0, eeh_error_buf_size); + + rc = rtas_call(ibm_slot_error_detail, + 8, 1, NULL, dn->eeh_config_addr, + BUID_HI(dn->phb->buid), + BUID_LO(dn->phb->buid), NULL, 0, + virt_to_phys(slot_errbuf), + eeh_error_buf_size, + severity); + + if (rc == 0) + log_error(slot_errbuf, ERR_TYPE_RTAS_LOG, 0); + spin_unlock_irqrestore(&slot_errbuf_lock, flags); } +EXPORT_SYMBOL(eeh_slot_error_detail); + /** * read_slot_reset_state - Read the reset state of a device node's slot * @dn: device node to read @@ -421,6 +446,7 @@ outputs = 4; } else { token = ibm_read_slot_reset_state; + rets[2] = 0; /* fake PE Unavailable info */ outputs = 3; } @@ -429,75 +455,8 @@ } /** - * 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) -{ - /* - * XXX We should create a separate sysctl for this. - * - * 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 { - __get_cpu_var(ignored_failures)++; - 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 void eeh_event_handler(void *dummy) -{ - unsigned long flags; - struct eeh_event *event; - - while (1) { - 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: MMIO failure (%d), notifiying device " - "%s\n", event->reset_state, - pci_name(event->dev)); - - atomic_set(&eeh_fail_count, 0); - notifier_call_chain (&eeh_notifier_chain, - EEH_NOTIFY_FREEZE, event); - - __get_cpu_var(slot_resets)++; - - pci_dev_put(event->dev); - kfree(event); - } -} - -/** - * eeh_token_to_phys - convert EEH address token to phys address - * @token i/o token, should be address in the form 0xE.... + * eeh_token_to_phys - convert I/O address to phys address + * @token i/o token, should be address in the form 0xA.... */ static inline unsigned long eeh_token_to_phys(unsigned long token) { @@ -512,6 +471,39 @@ return pa | (token & (PAGE_SIZE-1)); } +/** Mark all devices that are peers of this device as failed. + * Mark the device driver too, so that it can see the failure + * immediately; this is critical, since some drivers poll + * status registers in interrupts ... If a driver is polling, + * and the slot is frozen, then the driver can deadlock in + * an interrupt context, which is bad. + */ +static inline void eeh_mark_slot (struct device_node *dn) +{ + while (dn) { + dn->eeh_mode |= EEH_MODE_ISOLATED; + + /* Mark the pci device driver too */ + struct pci_dev *dev = dn->pcidev; + if (dev && dev->driver) { + dev->error_state = pci_channel_io_frozen; + } + if (dn->child) + eeh_mark_slot (dn->child); + dn = dn->sibling; + } +} + +static inline void eeh_clear_slot (struct device_node *dn) +{ + while (dn) { + dn->eeh_mode &= ~(EEH_MODE_RECOVERING|EEH_MODE_ISOLATED); + if (dn->child) + eeh_clear_slot (dn->child); + dn = dn->sibling; + } +} + /** * eeh_dn_check_failure - check if all 1's data is due to EEH slot freeze * @dn device node @@ -527,29 +519,37 @@ * * It is safe to call this routine in an interrupt context. */ +extern void disable_irq_nosync(unsigned int); + int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev) { int ret; int rets[3]; - unsigned long flags; - int rc, reset_state; - struct eeh_event *event; + enum pci_channel_state state; __get_cpu_var(total_mmio_ffs)++; if (!eeh_subsystem_enabled) return 0; - if (!dn) + if (!dn) { + __get_cpu_var(no_dn)++; return 0; + } /* Access to IO BARs might get this far and still not want checking. */ if (!(dn->eeh_mode & EEH_MODE_SUPPORTED) || dn->eeh_mode & EEH_MODE_NOCHECK) { + __get_cpu_var(ignored_check)++; +#ifdef DEBUG + printk ("EEH:ignored check for %s %s\n", + pci_name (dev), dn->full_name); +#endif return 0; } if (!dn->eeh_config_addr) { + __get_cpu_var(no_cfg_addr)++; return 0; } @@ -558,12 +558,18 @@ * slot, we know it's bad already, we don't need to check... */ if (dn->eeh_mode & EEH_MODE_ISOLATED) { - atomic_inc(&eeh_fail_count); - if (atomic_read(&eeh_fail_count) >= EEH_MAX_FAILS) { + dn->eeh_check_count ++; + if (dn->eeh_check_count >= EEH_MAX_FAILS) { + printk (KERN_ERR "EEH: Device driver ignored %d bad reads, panicing\n", + dn->eeh_check_count); + dump_stack(); /* re-read the slot reset state */ if (read_slot_reset_state(dn, rets) != 0) rets[0] = -1; /* reset state unknown */ - eeh_panic(dev, rets[0]); + + /* If we are here, then we hit an infinite loop. Stop. */ + panic("EEH: MMIO halt (%d) on device:%s\n", rets[0], + pci_name(dev)); } return 0; } @@ -576,53 +582,36 @@ * In any case they must share a common PHB. */ ret = read_slot_reset_state(dn, rets); - if (!(ret == 0 && rets[1] == 1 && (rets[0] == 2 || rets[0] == 4))) { + if (!(ret == 0 && ((rets[1] == 1 && (rets[0] == 2 || rets[0] >= 4)) + || (rets[0] == 5)))) { __get_cpu_var(false_positives)++; return 0; } - /* prevent repeated reports of this failure */ - dn->eeh_mode |= EEH_MODE_ISOLATED; - - reset_state = rets[0]; - - spin_lock_irqsave(&slot_errbuf_lock, flags); - memset(slot_errbuf, 0, eeh_error_buf_size); - - rc = rtas_call(ibm_slot_error_detail, - 8, 1, NULL, dn->eeh_config_addr, - BUID_HI(dn->phb->buid), - BUID_LO(dn->phb->buid), NULL, 0, - virt_to_phys(slot_errbuf), - eeh_error_buf_size, - 1 /* Temporary Error */); + /* Note that empty slots will fail; empty slots don't have children... */ + if ((rets[0] == 5) && (dn->child == NULL)) { + __get_cpu_var(false_positives)++; + return 0; + } - if (rc == 0) - log_error(slot_errbuf, ERR_TYPE_RTAS_LOG, 0); - spin_unlock_irqrestore(&slot_errbuf_lock, flags); + /* Avoid repeated reports of this failure, including problems + * with other functions on this device, and functions under + * bridges. */ + eeh_mark_slot (dn->parent->child); + __get_cpu_var(slot_resets)++; + + state = pci_channel_io_normal; + if ((rets[0] == 2) || (rets[0] == 4)) + state = pci_channel_io_frozen; + if (rets[0] == 5) + state = pci_channel_io_perm_failure; - printk(KERN_INFO "EEH: MMIO failure (%d) on device: %s %s\n", - rets[0], dn->name, dn->full_name); - event = kmalloc(sizeof(*event), GFP_ATOMIC); - if (event == NULL) { - eeh_panic(dev, reset_state); - return 1; - } - - event->dev = dev; - event->dn = dn; - event->reset_state = reset_state; - - /* 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); + eeh_send_failure_event (dn, dev, state, rets[2]); /* Most EEH events are due to device driver bugs. Having * a stack trace will help the device-driver authors figure * out what happened. So print that out. */ - dump_stack(); - schedule_work(&eeh_event_wq); + if (rets[0] != 5) dump_stack(); return 0; } @@ -634,7 +623,6 @@ * @token i/o token, should be address in the form 0xA.... * @val value, should be all 1's (XXX why do we need this arg??) * - * Check for an eeh failure at the given token address. * Check for an EEH failure at the given token address. Call this * routine if the result of a read was all 0xff's and you want to * find out if this is due to an EEH slot freeze event. This routine @@ -651,8 +639,10 @@ /* Finding the phys addr + pci device; this is pretty quick. */ addr = eeh_token_to_phys((unsigned long __force) token); dev = pci_get_device_by_addr(addr); - if (!dev) + if (!dev) { + __get_cpu_var(no_device)++; return val; + } dn = pci_device_to_OF_node(dev); eeh_dn_check_failure (dn, dev); @@ -663,6 +653,209 @@ EXPORT_SYMBOL(eeh_check_failure); +/* ------------------------------------------------------------- */ +/* The code below deals with error recovery */ + +/** eeh_pci_slot_reset -- raises/lowers the pci #RST line + * state: 1/0 to raise/lower the #RST + */ +void +eeh_pci_slot_reset(struct pci_dev *dev, int state) +{ + struct device_node *dn = pci_device_to_OF_node(dev); + rtas_pci_slot_reset (dn, state); +} + +/** Return negative value if a permanent error, else return + * a number of milliseconds to wait until the PCI slot is + * ready to be used. + */ +static int +eeh_slot_availability(struct device_node *dn) +{ + int rc; + int rets[3]; + + rc = read_slot_reset_state(dn, rets); + + if (rc) return rc; + + if (rets[1] == 0) return -1; /* EEH is not supported */ + if (rets[0] == 0) return 0; /* Oll Korrect */ + if (rets[0] == 5) { + if (rets[2] == 0) return -1; /* permanently unavailable */ + return rets[2]; /* number of millisecs to wait */ + } + return -1; +} + +int +eeh_pci_slot_availability(struct pci_dev *dev) +{ + struct device_node *dn = pci_device_to_OF_node(dev); + if (!dn) return -1; + + BUG_ON (dn->phb==NULL); + if (dn->phb==NULL) { + printk (KERN_ERR "EEH, checking on slot with no phb dn=%s dev=%s\n", + dn->full_name, pci_name(dev)); + return -1; + } + return eeh_slot_availability (dn); +} + +void +rtas_pci_slot_reset(struct device_node *dn, int state) +{ + int rc; + + if (!dn) + return; + if (!dn->phb) { + printk (KERN_WARNING "EEH: in slot reset, device node %s has no phb\n", dn->full_name); + return; + } + + dn->eeh_mode |= EEH_MODE_RECOVERING; + rc = rtas_call(ibm_set_slot_reset,4,1, NULL, + dn->eeh_config_addr, + BUID_HI(dn->phb->buid), + BUID_LO(dn->phb->buid), + state); + if (rc) { + printk (KERN_WARNING "EEH: Unable to reset the failed slot, (%d) #RST=%d\n", rc, state); + return; + } + + if (state == 0) + eeh_clear_slot (dn->parent->child); +} + +/** rtas_set_slot_reset -- assert the pci #RST line for 1/4 second + * dn -- device node to be reset. + */ + +void +rtas_set_slot_reset(struct device_node *dn) +{ + int i, rc; + + rtas_pci_slot_reset (dn, 1); + + /* The PCI bus requires that the reset be held high for at least + * a 100 milliseconds. We wait a bit longer 'just in case'. */ + +#define PCI_BUS_RST_HOLD_TIME_MSEC 250 + msleep (PCI_BUS_RST_HOLD_TIME_MSEC); + rtas_pci_slot_reset (dn, 0); + + /* After a PCI slot has been reset, the PCI Express spec requires + * a 1.5 second idle time for the bus to stabilize, before starting + * up traffic. */ +#define PCI_BUS_SETTLE_TIME_MSEC 1800 + msleep (PCI_BUS_SETTLE_TIME_MSEC); + + /* Now double check with the firmware to make sure the device is + * ready to be used; if not, wait for recovery. */ + for (i=0; i<10; i++) { + rc = eeh_slot_availability (dn); + if (rc <= 0) break; + + msleep (rc+100); + } +} + +EXPORT_SYMBOL(rtas_set_slot_reset); + +void +rtas_configure_bridge(struct device_node *dn) +{ + int token = rtas_token ("ibm,configure-bridge"); + int rc; + + if (token == RTAS_UNKNOWN_SERVICE) + return; + rc = rtas_call(token,3,1, NULL, + dn->eeh_config_addr, + BUID_HI(dn->phb->buid), + BUID_LO(dn->phb->buid)); + if (rc) { + printk (KERN_WARNING "EEH: Unable to configure device bridge (%d) for %s\n", + rc, dn->full_name); + } +} + +EXPORT_SYMBOL(rtas_configure_bridge); + +/* ------------------------------------------------------- */ +/** Save and restore of PCI BARs + * + * Although firmware will set up BARs during boot, it doesn't + * set up device BAR's after a device reset, although it will, + * if requested, set up bridge configuration. Thus, we need to + * configure the PCI devices ourselves. Config-space setup is + * stored in the PCI structures which are normally deleted during + * device removal. Thus, the "save" routine references the + * structures so that they aren't deleted. + */ + +/** + * __restore_bars - Restore the Base Address Registers + * Loads the PCI configuration space base address registers, + * the expansion ROM base address, the latency timer, and etc. + * from the saved values in the device node. + */ +static inline void __restore_bars (struct device_node *dn) +{ + int i; + + if (NULL==dn->phb) return; + for (i=4; i<10; i++) { + rtas_write_config(dn, i*4, 4, dn->config_space[i]); + } + + /* 12 == Expansion ROM Address */ + rtas_write_config(dn, 12*4, 4, dn->config_space[12]); + +#define BYTE_SWAP(OFF) (8*((OFF)/4)+3-(OFF)) +#define SAVED_BYTE(OFF) (((u8 *)(dn->config_space))[BYTE_SWAP(OFF)]) + + rtas_write_config (dn, PCI_CACHE_LINE_SIZE, 1, + SAVED_BYTE(PCI_CACHE_LINE_SIZE)); + + rtas_write_config (dn, PCI_LATENCY_TIMER, 1, + SAVED_BYTE(PCI_LATENCY_TIMER)); + + /* max latency, min grant, interrupt pin and line */ + rtas_write_config(dn, 15*4, 4, dn->config_space[15]); +} + +/** + * eeh_restore_bars - restore the PCI config space info + */ +void eeh_restore_bars(struct device_node *dn) +{ + if (! dn->eeh_is_bridge) + __restore_bars (dn); + + if (dn->child) + eeh_restore_bars (dn->child); +} + +void eeh_pci_restore_bars(struct pci_dev *dev) +{ + struct device_node *dn = pci_device_to_OF_node(dev); + eeh_restore_bars (dn); +} + +/* ------------------------------------------------------------- */ +/* The code below deals with enabling EEH for devices during the + * early boot sequence. EEH must be enabled before any PCI probing + * can be done. + */ + +#define EEH_ENABLE 1 + struct eeh_early_enable_info { unsigned int buid_hi; unsigned int buid_lo; @@ -681,6 +874,8 @@ int enable; dn->eeh_mode = 0; + dn->eeh_check_count = 0; + dn->eeh_freeze_count = 0; if (status && strcmp(status, "ok") != 0) return NULL; /* ignore devices with bad status */ @@ -704,8 +899,10 @@ * But there are a few cases like display devices that make sense. */ enable = 1; /* i.e. we will do checking */ +#if 0 if ((*class_code >> 16) == PCI_BASE_CLASS_DISPLAY) enable = 0; +#endif if (!enable) dn->eeh_mode |= EEH_MODE_NOCHECK; @@ -742,7 +939,7 @@ dn->full_name); } - return NULL; + return NULL; } /* @@ -827,7 +1024,9 @@ return; phb = dn->phb; if (NULL == phb || 0 == phb->buid) { - printk(KERN_WARNING "EEH: Expected buid but found none\n"); + printk(KERN_WARNING "EEH: Expected buid but found none for %s\n", + dn->full_name); + dump_stack(); return; } @@ -846,6 +1045,9 @@ */ void eeh_add_device_late(struct pci_dev *dev) { + int i; + struct device_node *dn; + if (!dev || !eeh_subsystem_enabled) return; @@ -854,6 +1056,17 @@ #endif pci_addr_cache_insert_device (dev); + + /* Save the BAR's; firmware doesn't restore these after EEH reset */ + dn = pci_device_to_OF_node(dev); + for (i = 0; i < 16; i++) + pci_read_config_dword(dev, i * 4, &dn->config_space[i]); + + if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) + dn->eeh_is_bridge = 1; + + pci_dev_get (dev); + dn->pcidev = dev; } EXPORT_SYMBOL(eeh_add_device_late); @@ -866,6 +1079,7 @@ */ void eeh_remove_device(struct pci_dev *dev) { + struct device_node *dn; if (!dev || !eeh_subsystem_enabled) return; @@ -874,6 +1088,10 @@ printk(KERN_DEBUG "EEH: remove device %s\n", pci_name(dev)); #endif pci_addr_cache_remove_device(dev); + + dn = pci_device_to_OF_node(dev); + dn->pcidev = NULL; + pci_dev_put (dev); } EXPORT_SYMBOL(eeh_remove_device); @@ -882,12 +1100,17 @@ unsigned int cpu; unsigned long ffs = 0, positives = 0, failures = 0; unsigned long resets = 0; + unsigned long no_dev = 0, no_dn = 0, no_cfg = 0, no_check = 0; for_each_cpu(cpu) { ffs += per_cpu(total_mmio_ffs, cpu); positives += per_cpu(false_positives, cpu); failures += per_cpu(ignored_failures, cpu); resets += per_cpu(slot_resets, cpu); + no_dev += per_cpu(no_device, cpu); + no_dn += per_cpu(no_dn, cpu); + no_cfg += per_cpu(no_cfg_addr, cpu); + no_check += per_cpu(ignored_check, cpu); } if (0 == eeh_subsystem_enabled) { @@ -895,13 +1118,17 @@ seq_printf(m, "eeh_total_mmio_ffs=%ld\n", ffs); } else { seq_printf(m, "EEH Subsystem is enabled\n"); - seq_printf(m, "eeh_total_mmio_ffs=%ld\n" + seq_printf(m, + "no device=%ld\n" + "no device node=%ld\n" + "no config address=%ld\n" + "check not wanted=%ld\n" + "eeh_total_mmio_ffs=%ld\n" "eeh_false_positives=%ld\n" "eeh_ignored_failures=%ld\n" - "eeh_slot_resets=%ld\n" - "eeh_fail_count=%d\n", - ffs, positives, failures, resets, - eeh_fail_count.counter); + "eeh_slot_resets=%ld\n", + no_dev, no_dn, no_cfg, no_check, + ffs, positives, failures, resets); } return 0; Index: linux-2.6.13-rc6-git9/arch/ppc64/kernel/eeh_driver.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ linux-2.6.13-rc6-git9/arch/ppc64/kernel/eeh_driver.c 2005-08-23 14:34:44.000000000 -0500 @@ -0,0 +1,361 @@ +/* + * PCI Hot Plug Controller Driver for RPA-compliant PPC64 platform. + * Copyright (C) 2004, 2005 Linas Vepstas + * + * All rights reserved. + * + * 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, GOOD TITLE or + * NON INFRINGEMENT. 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., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Send feedback to + * + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "eeh_event.h" +#include "../../../drivers/pci/pci.h" +#include "../../../drivers/pci/hotplug/rpaphp.h" + +/** + * pci_search_bus_for_dev - return 1 if device is under this bus, else 0 + * @bus: the bus to search for this device. + * @dev: the pci device we are looking for. + * + * XXX should this be moved to drivers/pci/search.c ? + */ +static int pci_search_bus_for_dev (struct pci_bus *bus, struct pci_dev *dev) +{ + struct list_head *ln; + + if (!bus) return 0; + + for (ln = bus->devices.next; ln != &bus->devices; ln = ln->next) { + struct pci_dev *pdev = pci_dev_b(ln); + if (pdev == dev) + return 1; + if (pdev->subordinate) { + int rc; + rc = pci_search_bus_for_dev (pdev->subordinate, dev); + if (rc) + return 1; + } + } + return 0; +} + +/** + * rpaphp_find_slot - find and return the slot holding the device + * @dev: pci device for which we want the slot structure. + */ +static struct slot *rpaphp_find_slot(struct pci_dev *dev) +{ + struct list_head *tmp, *n; + struct slot *slot; + + list_for_each_safe(tmp, n, &rpaphp_slot_head) { + struct pci_bus *bus; + + slot = list_entry(tmp, struct slot, rpaphp_slot_list); + + /* PHB's don't have bridges. */ + bus = slot->bus; + if (bus == NULL) + continue; + + /* The PCI device could be the slot itself. */ + if (bus->self == dev) + return slot; + + if (pci_search_bus_for_dev (bus, dev)) + return slot; + } + return NULL; +} + +struct hotplug_slot *pci_hp_find_slot(struct pci_dev *dev) +{ + struct slot *slot = rpaphp_find_slot(dev); + if (slot) + return slot->hotplug_slot; + return NULL; +} + +/* ------------------------------------------------------- */ +/** eeh_report_error - report an EEH error to each device, + * collect up and merge the device responses. + */ + +static void eeh_report_error(struct pci_dev *dev, void *userdata) +{ + enum pcierr_result rc, *res = userdata; + struct pci_driver *driver = dev->driver; + + dev->error_state = pci_channel_io_frozen; + + if (!driver) + return; + if (!driver->err_handler) + return; + if (!driver->err_handler->error_detected) + return; + + rc = driver->err_handler->error_detected (dev, pci_channel_io_frozen); + if (*res == PCIERR_RESULT_NONE) *res = rc; + if (*res == PCIERR_RESULT_NEED_RESET) return; + if (*res == PCIERR_RESULT_DISCONNECT && + rc == PCIERR_RESULT_NEED_RESET) *res = rc; +} + +/** eeh_report_reset -- tell this device that the pci slot + * has been reset. + */ + +static void eeh_report_reset(struct pci_dev *dev, void *userdata) +{ + struct pci_driver *driver = dev->driver; + + if (!driver) + return; + if (!driver->err_handler) + return; + if (!driver->err_handler->slot_reset) + return; + + driver->err_handler->slot_reset (dev); +} + +static void eeh_report_resume(struct pci_dev *dev, void *userdata) +{ + struct pci_driver *driver = dev->driver; + + dev->error_state = pci_channel_io_normal; + + if (!driver) + return; + if (!driver->err_handler) + return; + if (!driver->err_handler->resume) + return; + + driver->err_handler->resume (dev); +} + +static void eeh_report_failure(struct pci_dev *dev, void *userdata) +{ + struct pci_driver *driver = dev->driver; + + dev->error_state = pci_channel_io_perm_failure; + + if (!driver) + return; + if (!driver->err_handler) + return; + if (!driver->err_handler->error_detected) + return; + driver->err_handler->error_detected (dev, pci_channel_io_perm_failure); +} + +/* ------------------------------------------------------- */ +/** + * handle_eeh_events -- reset a PCI device after hard lockup. + * + * pSeries systems will isolate a PCI slot if the PCI-Host + * bridge detects address or data parity errors, DMA's + * occuring to wild addresses (which usually happen due to + * bugs in device drivers or in PCI adapter firmware). + * Slot isolations also occur if #SERR, #PERR or other misc + * PCI-related errors are detected. + * + * Recovery process consists of unplugging the device driver + * (which generated hotplug events to userspace), then issuing + * a PCI #RST to the device, then reconfiguring the PCI config + * space for all bridges & devices under this slot, and then + * finally restarting the device drivers (which cause a second + * set of hotplug events to go out to userspace). + */ + +int eeh_reset_device (struct pci_dev *dev, struct device_node *dn, int reconfig) +{ + struct hotplug_slot *frozen_slot= NULL; + struct hotplug_slot_ops *frozen_ops= NULL; + + if (!dev) + return 1; + + if (reconfig) { + frozen_slot = pci_hp_find_slot(dev); + if (frozen_slot) + frozen_ops = frozen_slot->ops; + } + + if (frozen_ops) frozen_ops->disable_slot (frozen_slot); + + /* Reset the pci controller. (Asserts RST#; resets config space). + * Reconfigure bridges and devices */ + rtas_set_slot_reset (dn->child); + + /* Walk over all functions on this device */ + struct device_node *peer = dn->child; + while (peer) { + rtas_configure_bridge(peer); + eeh_restore_bars(peer); + peer = peer->sibling; + } + + /* Give the system 5 seconds to finish running the user-space + * hotplug scripts, e.g. ifdown for ethernet. Yes, this is a hack, + * but if we don't do this, weird things happen. + */ + if (frozen_ops) { + ssleep (5); + frozen_ops->enable_slot (frozen_slot); + } + return 0; +} + +/* The longest amount of time to wait for a pci device + * to come back on line, in seconds. + */ +#define MAX_WAIT_FOR_RECOVERY 15 + +int handle_eeh_events (struct eeh_event *event) +{ + int freeze_count=0; + struct device_node *frozen_device; + struct pci_dev *dev = event->dev; + int perm_failure = 0; + + /* We might not have a pci device, if it was a config space read + * that failed. Find the pci device now. */ + if (!dev) + dev = event->dn->pcidev; + if (!dev) + { + printk ("EEH: EEH error caught, but no PCI device found!\n"); + return 1; + } + + /* Some devices go crazy if irq's are not ack'ed; disable irq now */ + disable_irq_nosync (dev->irq); + + frozen_device = pci_bus_to_OF_node(dev->bus); + if (!frozen_device) + { + printk (KERN_ERR "EEH: Cannot find PCI controller for %s\n", + pci_name(dev)); + + return 1; + } + BUG_ON (frozen_device->phb==NULL); + + /* We get "permanent failure" messages on empty slots. + * These are false alarms. Empty slots have no child dn. */ + if ((event->state == pci_channel_io_perm_failure) && (frozen_device == NULL)) + return 0; + + if (frozen_device) + freeze_count = frozen_device->eeh_freeze_count; + freeze_count ++; + if (freeze_count > EEH_MAX_ALLOWED_FREEZES) + perm_failure = 1; + + /* If the reset state is a '5' and the time to reset is 0 (infinity) + * or is more then 15 seconds, then mark this as a permanent failure. + */ + if ((event->state == pci_channel_io_perm_failure) && + ((event->time_unavail <= 0) || + (event->time_unavail > MAX_WAIT_FOR_RECOVERY*1000))) + { + perm_failure = 1; + } + + /* Log the error with the rtas logger. */ + if (perm_failure) { + /* + * About 90% of all real-life EEH failures in the field + * are due to poorly seated PCI cards. Only 10% or so are + * due to actual, failed cards. + */ + printk (KERN_ERR + "EEH: PCI device %s has failed %d times \n" + "and has been permanently disabled. Please try reseating\n" + "this device or replacing it.\n", + pci_name (dev), + freeze_count); + + eeh_slot_error_detail (frozen_device, 2 /* Permanent Error */); + + /* Notify all devices that they're about to go down. */ + pci_walk_bus (dev->bus, eeh_report_failure, 0); + + /* If there's a hotplug slot, unconfigure it */ + // XXX we need alternate way to deconfigure non-hotplug slots. + struct hotplug_slot * frozen_slot = pci_hp_find_slot(dev); + if (frozen_slot && frozen_slot->ops) + frozen_slot->ops->disable_slot (frozen_slot); + return 1; + } else { + eeh_slot_error_detail (frozen_device, 1 /* Temporary Error */); + } + + printk (KERN_WARNING + "EEH: This PCI device has failed %d times since last reboot: %s\n", + freeze_count, + pci_name (dev)); + + /* Walk the various device drivers attached to this slot, + * letting each know about the EEH bug. + */ + enum pcierr_result result = PCIERR_RESULT_NONE; + pci_walk_bus (dev->bus, eeh_report_error, &result); + + /* If all device drivers were EEH-unaware, then pci hotplug + * the device, and hope that clears the error. */ + if (result == PCIERR_RESULT_NONE) { + eeh_reset_device (dev, frozen_device, 1); + } + + /* If any device called out for a reset, then reset the slot */ + if (result == PCIERR_RESULT_NEED_RESET) { + eeh_reset_device (dev, frozen_device, 0); + pci_walk_bus (dev->bus, eeh_report_reset, 0); + } + + /* If all devices reported they can proceed, the re-enable PIO */ + if (result == PCIERR_RESULT_CAN_RECOVER) { + /* XXX Not supported; we brute-force reset the device */ + eeh_reset_device (dev, frozen_device, 0); + pci_walk_bus (dev->bus, eeh_report_reset, 0); + } + + /* Tell all device drivers that they can resume operations */ + pci_walk_bus (dev->bus, eeh_report_resume, 0); + + /* Store the freeze count with the pci adapter, and not the slot. + * This way, if the device is replaced, the count is cleared. + */ + frozen_device->eeh_freeze_count = freeze_count; + + return 1; +} + +/* ---------- end of file ---------- */ Index: linux-2.6.13-rc6-git9/arch/ppc64/kernel/eeh_event.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ linux-2.6.13-rc6-git9/arch/ppc64/kernel/eeh_event.c 2005-08-23 10:33:40.000000000 -0500 @@ -0,0 +1,116 @@ +/* + * 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 + */ + +#include +#include +#include "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_event_handler(void *); +DECLARE_WORK(eeh_event_wq, eeh_event_handler, NULL); + +int handle_eeh_events (struct eeh_event *event); + +/** + * 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 void eeh_event_handler(void *dummy) +{ + unsigned long flags; + struct eeh_event *event; + + while (1) { + 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)); + + handle_eeh_events(event); + + pci_dev_put(event->dev); + kfree(event); + } +} + +/** + * 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, + enum pci_channel_state 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 ******************************/ Index: linux-2.6.13-rc6-git9/arch/ppc64/kernel/eeh_event.h =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ linux-2.6.13-rc6-git9/arch/ppc64/kernel/eeh_event.h 2005-08-19 15:52:59.000000000 -0500 @@ -0,0 +1,52 @@ +/* + * eeh_event.h + * + * 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 + */ + +#ifndef ASM_PPC64_EEH_EVENT_H +#define ASM_PPC64_EEH_EVENT_H + +/** EEH event -- structure holding pci controller data that describes + * a change in the isolation status of a PCI slot. A pointer + * to this struct is passed as the data pointer in a notify callback. + */ +struct eeh_event { + struct list_head list; + struct device_node *dn; /* struct device node */ + struct pci_dev *dev; /* affected device */ + enum pci_channel_state state; /* PCI bus state for the affected device */ + int time_unavail; /* milliseconds until device might be available */ +}; + +/** + * eeh_send_failure_event - generate a PCI error event + * @dev pci device + * + * This routine builds a PCI error event which will be delivered + * to all listeners on the peh_notifier_chain. + * + * 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, + enum pci_channel_state state, + int time_unavail); + +#endif /* ASM_PPC64_EEH_EVENT_H */ Index: linux-2.6.13-rc6-git9/arch/ppc64/kernel/rtas_pci.c =================================================================== --- linux-2.6.13-rc6-git9.orig/arch/ppc64/kernel/rtas_pci.c 2005-08-19 12:01:00.000000000 -0500 +++ linux-2.6.13-rc6-git9/arch/ppc64/kernel/rtas_pci.c 2005-08-23 14:37:20.000000000 -0500 @@ -58,7 +58,7 @@ return 0; } -static int rtas_read_config(struct device_node *dn, int where, int size, u32 *val) +int rtas_read_config(struct device_node *dn, int where, int size, u32 *val) { int returnval = -1; unsigned long buid, addr; @@ -105,10 +105,11 @@ for (dn = busdn->child; dn; dn = dn->sibling) if (dn->devfn == devfn) return rtas_read_config(dn, where, size, val); + return PCIBIOS_DEVICE_NOT_FOUND; } -static int rtas_write_config(struct device_node *dn, int where, int size, u32 val) +int rtas_write_config(struct device_node *dn, int where, int size, u32 val) { unsigned long buid, addr; int ret; Index: linux-2.6.13-rc6-git9/include/asm-ppc64/eeh.h =================================================================== --- linux-2.6.13-rc6-git9.orig/include/asm-ppc64/eeh.h 2005-07-15 16:18:57.000000000 -0500 +++ linux-2.6.13-rc6-git9/include/asm-ppc64/eeh.h 2005-08-19 15:02:28.000000000 -0500 @@ -1,4 +1,4 @@ -/* +/* * eeh.h * Copyright (C) 2001 Dave Engebretsen & Todd Inglett IBM Corporation. * @@ -6,12 +6,12 @@ * 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 @@ -36,6 +36,11 @@ #define EEH_MODE_SUPPORTED (1<<0) #define EEH_MODE_NOCHECK (1<<1) #define EEH_MODE_ISOLATED (1<<2) +#define EEH_MODE_RECOVERING (1<<3) + +/* Max number of EEH freezes allowed before we consider the device + * to be permanently disabled. */ +#define EEH_MAX_ALLOWED_FREEZES 5 void __init eeh_init(void); unsigned long eeh_check_failure(const volatile void __iomem *token, @@ -59,35 +64,71 @@ * eeh_remove_device - undo EEH setup for the indicated pci device * @dev: pci device to be removed * - * This routine should be when a device is removed from a running - * system (e.g. by hotplug or dlpar). + * This routine should be called when a device is removed from + * a running system (e.g. by hotplug or dlpar). It unregisters + * the PCI device from the EEH subsystem. I/O errors affecting + * this device will no longer be detected after this call; thus, + * i/o errors affecting this slot may leave this device unusable. */ void eeh_remove_device(struct pci_dev *); -#define EEH_DISABLE 0 -#define EEH_ENABLE 1 -#define EEH_RELEASE_LOADSTORE 2 -#define EEH_RELEASE_DMA 3 +/** + * eeh_slot_error_detail -- record and EEH error condition to the log + * @severity: 1 if temporary, 2 if permanent failure. + * + * Obtains the the EEH error details from the RTAS subsystem, + * and then logs these details with the RTAS error log system. + */ +void eeh_slot_error_detail (struct device_node *dn, int severity); /** - * Notifier event flags. + * rtas_set_slot_reset -- unfreeze a frozen slot + * + * Clear the EEH-frozen condition on a slot. This routine + * does this by asserting the PCI #RST line for 1/8th of + * a second; this routine will sleep while the adapter is + * being reset. */ -#define EEH_NOTIFY_FREEZE 1 +void rtas_set_slot_reset (struct device_node *dn); -/** EEH event -- structure holding pci slot data that describes - * a change in the isolation status of a PCI slot. A pointer - * to this struct is passed as the data pointer in a notify callback. - */ -struct eeh_event { - struct list_head list; - struct pci_dev *dev; - struct device_node *dn; - int reset_state; -}; - -/** Register to find out about EEH events. */ -int eeh_register_notifier(struct notifier_block *nb); -int eeh_unregister_notifier(struct notifier_block *nb); +/** rtas_pci_slot_reset raises/lowers the pci #RST line + * state: 1/0 to raise/lower the #RST + * + * Clear the EEH-frozen condition on a slot. This routine + * asserts the PCI #RST line if the 'state' argument is '1', + * and drops the #RST line if 'state is '0'. This routine is + * safe to call in an interrupt context. + * + */ +void rtas_pci_slot_reset(struct device_node *dn, int state); +void eeh_pci_slot_reset(struct pci_dev *dev, int state); + +/** eeh_pci_slot_availability -- Indicates whether a PCI + * slot is ready to be used. After a PCI reset, it may take a while + * for the PCI fabric to fully reset the comminucations path to the + * given PCI card. This routine can be used to determine how long + * to wait before a PCI slot might become usable. + * + * This routine returns how long to wait (in milliseconds) before + * the slot is expected to be usable. A value of zero means the + * slot is immediately usable. A negavitve value means that the + * slot is permanently disabled. + */ +int eeh_pci_slot_availability(struct pci_dev *dev); + +/** Restore device configuration info across device resets. + */ +void eeh_restore_bars(struct device_node *); +void eeh_pci_restore_bars(struct pci_dev *dev); + +/** + * rtas_configure_bridge -- firmware initialization of pci bridge + * + * Ask the firmware to configure any PCI bridge devices + * located behind the indicated node. Required after a + * pci device reset. + */ +void rtas_configure_bridge(struct device_node *dn); /** * EEH_POSSIBLE_ERROR() -- test for possible MMIO failure. @@ -129,7 +170,7 @@ #define EEH_IO_ERROR_VALUE(size) (-1UL) #endif /* CONFIG_EEH */ -/* +/* * MMIO read/write operations with EEH support. */ static inline u8 eeh_readb(const volatile void __iomem *addr) @@ -251,21 +292,21 @@ *((u8 *)dest) = *((volatile u8 *)vsrc); __asm__ __volatile__ ("eieio" : : : "memory"); vsrc = (void *)((unsigned long)vsrc + 1); - dest = (void *)((unsigned long)dest + 1); + dest = (void *)((unsigned long)dest + 1); n--; } while(n > 4) { *((u32 *)dest) = *((volatile u32 *)vsrc); __asm__ __volatile__ ("eieio" : : : "memory"); vsrc = (void *)((unsigned long)vsrc + 4); - dest = (void *)((unsigned long)dest + 4); + dest = (void *)((unsigned long)dest + 4); n -= 4; } while(n) { *((u8 *)dest) = *((volatile u8 *)vsrc); __asm__ __volatile__ ("eieio" : : : "memory"); vsrc = (void *)((unsigned long)vsrc + 1); - dest = (void *)((unsigned long)dest + 1); + dest = (void *)((unsigned long)dest + 1); n--; } __asm__ __volatile__ ("sync" : : : "memory"); @@ -287,19 +328,19 @@ while(n && (!EEH_CHECK_ALIGN(vdest, 4) || !EEH_CHECK_ALIGN(src, 4))) { *((volatile u8 *)vdest) = *((u8 *)src); src = (void *)((unsigned long)src + 1); - vdest = (void *)((unsigned long)vdest + 1); + vdest = (void *)((unsigned long)vdest + 1); n--; } while(n > 4) { *((volatile u32 *)vdest) = *((volatile u32 *)src); src = (void *)((unsigned long)src + 4); - vdest = (void *)((unsigned long)vdest + 4); + vdest = (void *)((unsigned long)vdest + 4); n-=4; } while(n) { *((volatile u8 *)vdest) = *((u8 *)src); src = (void *)((unsigned long)src + 1); - vdest = (void *)((unsigned long)vdest + 1); + vdest = (void *)((unsigned long)vdest + 1); n--; } __asm__ __volatile__ ("sync" : : : "memory"); Index: linux-2.6.13-rc6-git9/include/asm-ppc64/rtas.h =================================================================== --- linux-2.6.13-rc6-git9.orig/include/asm-ppc64/rtas.h 2005-08-17 15:17:44.000000000 -0500 +++ linux-2.6.13-rc6-git9/include/asm-ppc64/rtas.h 2005-08-19 15:02:28.000000000 -0500 @@ -246,4 +246,6 @@ #define GLOBAL_INTERRUPT_QUEUE 9005 +extern int rtas_write_config(struct device_node *dn, int where, int size, u32 val); + #endif /* _PPC64_RTAS_H */ Index: linux-2.6.13-rc6-git9/include/asm-ppc64/prom.h =================================================================== --- linux-2.6.13-rc6-git9.orig/include/asm-ppc64/prom.h 2005-08-19 15:11:39.000000000 -0500 +++ linux-2.6.13-rc6-git9/include/asm-ppc64/prom.h 2005-08-23 13:31:52.000000000 -0500 @@ -135,11 +135,17 @@ int busno; /* for pci devices */ int bussubno; /* for pci devices */ int devfn; /* for pci devices */ - int eeh_mode; /* See eeh.h for possible EEH_MODEs */ - int eeh_config_addr; + int eeh_mode; /* See eeh.h for possible EEH_MODEs */ + int eeh_config_addr; + int eeh_check_count; /* number of times device driver ignored error */ + int eeh_freeze_count; /* number of times this device froze up. */ + int eeh_is_bridge; /* device is pci-to-pci bridge */ + int pci_ext_config_space; /* for pci devices */ struct pci_controller *phb; /* for pci devices */ struct iommu_table *iommu_table; /* for phb's or bridges */ + struct pci_dev *pcidev; /* back-pointer to the pci device */ + u32 config_space[16]; /* saved PCI config space */ struct property *properties; struct device_node *parent; Index: linux-2.6.13-rc6-git9/arch/ppc64/kernel/Makefile =================================================================== --- linux-2.6.13-rc6-git9.orig/arch/ppc64/kernel/Makefile 2005-08-17 15:40:18.000000000 -0500 +++ linux-2.6.13-rc6-git9/arch/ppc64/kernel/Makefile 2005-08-19 15:54:26.000000000 -0500 @@ -37,7 +37,7 @@ bpa_iic.o spider-pic.o obj-$(CONFIG_KEXEC) += machine_kexec.o -obj-$(CONFIG_EEH) += eeh.o +obj-$(CONFIG_EEH) += eeh.o eeh_driver.o eeh_event.o obj-$(CONFIG_PROC_FS) += proc_ppc64.o obj-$(CONFIG_RTAS_FLASH) += rtas_flash.o obj-$(CONFIG_SMP) += smp.o -- -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: Digital signature Url : http://ozlabs.org/pipermail/linuxppc64-dev/attachments/20050823/e9fe30b8/attachment.pgp From paulus at samba.org Wed Aug 24 10:43:02 2005 From: paulus at samba.org (Paul Mackerras) Date: Wed, 24 Aug 2005 10:43:02 +1000 Subject: [patch 8/8] PCI Error Recovery: PPC64 core recovery routines In-Reply-To: <20050823234747.GI18113@austin.ibm.com> References: <20050823231817.829359000@bilge> <20050823232143.003048000@bilge> <20050823234747.GI18113@austin.ibm.com> Message-ID: <17163.49814.166545.946491@cargo.ozlabs.ibm.com> Linas Vepstas writes: In this patch at least, your mailer seems to have blanked out lines that match ^[-+]$. Could you send them to me again with a different mailer or put them on a web or ftp site somewhere? Thanks, Paul. From sfr at canb.auug.org.au Wed Aug 24 14:36:55 2005 From: sfr at canb.auug.org.au (Stephen Rothwell) Date: Wed, 24 Aug 2005 14:36:55 +1000 Subject: [PATCH] ppc64: Add CONFIG_HZ In-Reply-To: <20050823225303.GF31949@krispykreme> References: <20050823225303.GF31949@krispykreme> Message-ID: <20050824143655.47a2dcae.sfr@canb.auug.org.au> On Wed, 24 Aug 2005 08:53:03 +1000 Anton Blanchard wrote: > > While ppc64 has the CONFIG_HZ Kconfig option, it wasnt actually being > used. Connect it up and set all platforms to 250Hz. Do we really want HZ above 100 on LPAR platforms? -- Cheers, Stephen Rothwell sfr at canb.auug.org.au http://www.canb.auug.org.au/~sfr/ -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: not available Url : http://ozlabs.org/pipermail/linuxppc64-dev/attachments/20050824/3ed98de1/attachment.pgp From anton at samba.org Wed Aug 24 15:15:51 2005 From: anton at samba.org (Anton Blanchard) Date: Wed, 24 Aug 2005 15:15:51 +1000 Subject: [PATCH] ppc64: Add CONFIG_HZ In-Reply-To: <20050824143655.47a2dcae.sfr@canb.auug.org.au> References: <20050823225303.GF31949@krispykreme> <20050824143655.47a2dcae.sfr@canb.auug.org.au> Message-ID: <20050824051551.GH31949@krispykreme> > Do we really want HZ above 100 on LPAR platforms? Probably not, but I thought going down to 100HZ might enrage some of the interactive zealots. Anton From paulus at samba.org Wed Aug 24 14:49:30 2005 From: paulus at samba.org (Paul Mackerras) Date: Wed, 24 Aug 2005 14:49:30 +1000 Subject: [patch 8/8] PCI Error Recovery: PPC64 core recovery routines In-Reply-To: <17163.49814.166545.946491@cargo.ozlabs.ibm.com> References: <20050823231817.829359000@bilge> <20050823232143.003048000@bilge> <20050823234747.GI18113@austin.ibm.com> <17163.49814.166545.946491@cargo.ozlabs.ibm.com> Message-ID: <17163.64602.634390.104042@cargo.ozlabs.ibm.com> I wrote: > Linas Vepstas writes: > > In this patch at least, your mailer seems to have blanked out lines > that match ^[-+]$. Could you send them to me again with a different > mailer or put them on a web or ftp site somewhere? I got 3 copies of each of these mails, one directly, one through linuxppc64-dev and one through linux-kernel. It looks like the copies that came through the mailing lists are OK but the copy that came directly to me is corrupted. Weird. Regards, Paul. From segher at kernel.crashing.org Wed Aug 24 18:24:06 2005 From: segher at kernel.crashing.org (Segher Boessenkool) Date: Wed, 24 Aug 2005 10:24:06 +0200 Subject: [Fwd: [PATCH] PPC64: large INITRD causes kernel not to boot] In-Reply-To: <20050822192908.GA26542@suse.de> References: <20050808185435.GA13206@suse.de> <42F7AC62.3070601@mvista.com> <20050808191123.GA14047@suse.de> <42F7B301.5060008@mvista.com> <20050808223010.GA18775@suse.de> <42F7DF52.4090905@mvista.com> <42F80136.9050500@mvista.com> <42FAA272.6010601@mvista.com> <20050822142028.GA8605@suse.de> <19a8c3db28d17b53e582be6d8dd698a7@kernel.crashing.org> <20050822192908.GA26542@suse.de> Message-ID: <420bb7a5009e644df7c709fd151c92ea@kernel.crashing.org> > Such bugs have to be fixed, obviously. No? It's not a bug, just a missing feature ;-) > If I claim(0x0,123456,0) and OF says OK than I have to expect that its > really OK to use the mem at 0x0. Yes. > In this case maple rejected everything > up to 11MB. But it has appearently some runtime data above 11MB, havent > debugged it further. At least claim(11MB,10MB,0) and claim(64MB,10MB,0) > and copying the memory from 11MB to 64MB and comparing it right away > showed differences. Pretty bad for an client owned area, no? You could of course just ask for "any address", i.e., claim(0, size, 4kB) or something. And pray that your OF does implement this (cough missing feature cough). Or else, if you absolutely must decide what address to put stuff at yourself, at a minimum have a look at the "available" property, don't just guess. Segher From ntl at pobox.com Wed Aug 24 23:34:23 2005 From: ntl at pobox.com (Nathan Lynch) Date: Wed, 24 Aug 2005 08:34:23 -0500 Subject: [PATCH] export htab value for kexec on non-lpar In-Reply-To: <20050823080423.GA2380@in.ibm.com> References: <20050823080423.GA2380@in.ibm.com> Message-ID: <20050824133423.GN1012@otto> > @@ -1086,6 +1093,9 @@ void __init setup_arch(char **cmdline_p) > } > > paging_init(); > +#ifdef CONFIG_KEXEC > + export_htab_value(); > +#endif > ppc64_boot_msg(0x15, "Setup Done"); > } > > @@ -1358,3 +1368,39 @@ void cpu_die(void) > if (ppc_md.cpu_die) > ppc_md.cpu_die(); > } > + > +#ifdef CONFIG_KEXEC > +void export_htab_value() > +{ Can export_htab_value not be marked __init since it is called only from setup_arch? From hollis at penguinppc.org Wed Aug 24 23:52:36 2005 From: hollis at penguinppc.org (Hollis Blanchard) Date: Wed, 24 Aug 2005 08:52:36 -0500 Subject: GDB backtrace and signal trampolines In-Reply-To: References: Message-ID: <0dac9cb23e9a6db6a80d8d15c4fc5e99@penguinppc.org> On Aug 11, 2005, at 10:54 AM, Hollis Blanchard wrote: > GDB 6.3 contains this code in ppc-linux-tdep.c: > > static const struct frame_unwind * > ppc_linux_sigtramp_sniffer (struct frame_info *next_frame) > { > struct gdbarch_tdep *tdep = gdbarch_tdep (get_frame_arch > (next_frame)); > > if (frame_pc_unwind (next_frame) > > frame_unwind_register_unsigned (next_frame, SP_REGNUM)) > /* Assume anything that is vaguely on the stack is a signal > trampoline. */ > return &ppc_linux_sigtramp_unwind; > else > return NULL; > } > > Essentially it says that any time the program counter is above the > stack pointer, we must be in a signal trampoline, and so GDB proceeds > to grope about for a struct rt_sigframe on the stack. > > This is not a good assumption. I'm using a GDB stub to debug Xen, and > as it so happens, the Xen stack is below the Xen text. That means that > the above test always triggers, but of course there is no rt_sigframe > on the stack, and my backtrace runs away. FYI: I looked at a GDB snapshot (gdb-6.3.50.20050818) and the problem had been resolved. -Hollis From johnrose at austin.ibm.com Thu Aug 25 01:45:31 2005 From: johnrose at austin.ibm.com (John Rose) Date: Wed, 24 Aug 2005 10:45:31 -0500 Subject: [patch 8/8] PCI Error Recovery: PPC64 core recovery routines In-Reply-To: <20050823234747.GI18113@austin.ibm.com> References: <20050823231817.829359000@bilge> <20050823232143.003048000@bilge> <20050823234747.GI18113@austin.ibm.com> Message-ID: <1124898331.24668.33.camel@sinatra.austin.ibm.com> Hi Linas- I like the idea of splitting the recovery stuff into its own driver. A few comments on the last reorg patch: > Index: linux-2.6.13-rc6-git9/arch/ppc64/kernel/eeh.c ... > +static int > +eeh_slot_availability(struct device_node *dn) ... > +void eeh_restore_bars(struct device_node *dn) Inconsistent spacing in new code... > --- /dev/null 1970-01-01 00:00:00.000000000 +0000 > +++ linux-2.6.13-rc6-git9/arch/ppc64/kernel/eeh_driver.c 2005-08-23 14:34:44.000000000 -0500 > @@ -0,0 +1,361 @@ > +/* > + * PCI Hot Plug Controller Driver for RPA-compliant PPC64 platform. This probably isn't the right header description for this file :) > + > +/** > + * rpaphp_find_slot - find and return the slot holding the device > + * @dev: pci device for which we want the slot structure. > + */ > +static struct slot *rpaphp_find_slot(struct pci_dev *dev) > +{ > + struct list_head *tmp, *n; > + struct slot *slot; > + > + list_for_each_safe(tmp, n, &rpaphp_slot_head) { > + struct pci_bus *bus; > + > + slot = list_entry(tmp, struct slot, rpaphp_slot_list); > + > + /* PHB's don't have bridges. */ > + bus = slot->bus; > + if (bus == NULL) > + continue; > + > + /* The PCI device could be the slot itself. */ > + if (bus->self == dev) > + return slot; > + > + if (pci_search_bus_for_dev (bus, dev)) > + return slot; > + } > + return NULL; > +} This function breaks if rpaphp is compiled as a module. It's probably bad for kernel code to depend on symbols exported from modules. This raises two larger questions: Where should this new driver sit, and should it be possible to compile it as a module as well? > +/* ------------------------------------------------------- */ > +/** > + * handle_eeh_events -- reset a PCI device after hard lockup. > + * ... > +int eeh_reset_device (struct pci_dev *dev, struct device_node *dn, int reconfig) Header doesn't match the function :) > +{ > + struct hotplug_slot *frozen_slot= NULL; > + struct hotplug_slot_ops *frozen_ops= NULL; > + > + if (!dev) > + return 1; > + > + if (reconfig) { > + frozen_slot = pci_hp_find_slot(dev); > + if (frozen_slot) > + frozen_ops = frozen_slot->ops; > + } > + > + if (frozen_ops) frozen_ops->disable_slot (frozen_slot); > + > + /* Reset the pci controller. (Asserts RST#; resets config space). > + * Reconfigure bridges and devices */ > + rtas_set_slot_reset (dn->child); > + > + /* Walk over all functions on this device */ > + struct device_node *peer = dn->child; > + while (peer) { > + rtas_configure_bridge(peer); > + eeh_restore_bars(peer); > + peer = peer->sibling; > + } > + > + /* Give the system 5 seconds to finish running the user-space > + * hotplug scripts, e.g. ifdown for ethernet. Yes, this is a hack, > + * but if we don't do this, weird things happen. > + */ > + if (frozen_ops) { > + ssleep (5); > + frozen_ops->enable_slot (frozen_slot); > + } > + return 0; > +} This dependence on struct hotplug_slot might be problematic as we restrict the registration of "PCI hotplug" slots to exclude PHBs, VIO, and embedded slots. Noticed your comment to this effect. I can work with you offline on this. > + > +/* The longest amount of time to wait for a pci device > + * to come back on line, in seconds. > + */ > +#define MAX_WAIT_FOR_RECOVERY 15 > + > +int handle_eeh_events (struct eeh_event *event) > +{ > + ... > + frozen_device = pci_bus_to_OF_node(dev->bus); > + if (!frozen_device) > + { > + printk (KERN_ERR "EEH: Cannot find PCI controller for %s\n", > + pci_name(dev)); > + > + return 1; > + } > + BUG_ON (frozen_device->phb==NULL); > + > + /* We get "permanent failure" messages on empty slots. > + * These are false alarms. Empty slots have no child dn. */ > + if ((event->state == pci_channel_io_perm_failure) && (frozen_device == NULL)) The second part of this conditional will never be true, as this has just been checked above. > + if (frozen_device) > + freeze_count = frozen_device->eeh_freeze_count; This conditional will always be true, as this has also ben checked above. > Index: linux-2.6.13-rc6-git9/include/asm-ppc64/prom.h > =================================================================== > --- linux-2.6.13-rc6-git9.orig/include/asm-ppc64/prom.h 2005-08-19 15:11:39.000000000 -0500 > +++ linux-2.6.13-rc6-git9/include/asm-ppc64/prom.h 2005-08-23 13:31:52.000000000 -0500 > @@ -135,11 +135,17 @@ > int busno; /* for pci devices */ > int bussubno; /* for pci devices */ > int devfn; /* for pci devices */ > - int eeh_mode; /* See eeh.h for possible EEH_MODEs */ > - int eeh_config_addr; > + int eeh_mode; /* See eeh.h for possible EEH_MODEs */ > + int eeh_config_addr; > + int eeh_check_count; /* number of times device driver ignored error */ > + int eeh_freeze_count; /* number of times this device froze up. */ > + int eeh_is_bridge; /* device is pci-to-pci bridge */ > + > int pci_ext_config_space; /* for pci devices */ > struct pci_controller *phb; /* for pci devices */ > struct iommu_table *iommu_table; /* for phb's or bridges */ > + struct pci_dev *pcidev; /* back-pointer to the pci device */ > + u32 config_space[16]; /* saved PCI config space */ > > struct property *properties; > struct device_node *parent; How about a pointer to a struct of EEH fields? Folks are touchy about adding anything PCI-specific to device nodes, especially since most DNs aren't PCI at all. Thanks- John From linas at austin.ibm.com Thu Aug 25 02:29:59 2005 From: linas at austin.ibm.com (Linas Vepstas) Date: Wed, 24 Aug 2005 11:29:59 -0500 Subject: [patch 8/8] PCI Error Recovery: PPC64 core recovery routines In-Reply-To: <1124898331.24668.33.camel@sinatra.austin.ibm.com> References: <20050823231817.829359000@bilge> <20050823232143.003048000@bilge> <20050823234747.GI18113@austin.ibm.com> <1124898331.24668.33.camel@sinatra.austin.ibm.com> Message-ID: <20050824162959.GC25174@austin.ibm.com> On Wed, Aug 24, 2005 at 10:45:31AM -0500, John Rose was heard to remark: > > +++ linux-2.6.13-rc6-git9/arch/ppc64/kernel/eeh_driver.c 2005-08-23 14:34:44.000000000 -0500 > > +/* > > + * PCI Hot Plug Controller Driver for RPA-compliant PPC64 platform. > > This probably isn't the right header description for this file :) Yes, this file is a little ball of ugliness that resulted from moving things out of the rpaphp directory; and, yes, it's rather un-reconstructed. I released it under the "release early" program. The meta-issue that I'd like to reach consensus on first is whether there should be any hot-plug recovery attempted at all. Removing hot-plug-recovery support will make many of the issues you raise to be moot. > > +++ linux-2.6.13-rc6-git9/include/asm-ppc64/prom.h 2005-08-23 13:31:52.000000000 -0500 > > int busno; /* for pci devices */ > > int bussubno; /* for pci devices */ > > int devfn; /* for pci devices */ > > How about a pointer to a struct of EEH fields? Folks are touchy about > adding anything PCI-specific to device nodes, especially since most DNs > aren't PCI at all. I attempted to remove all of the pci-related stuff from this struct, and got a crash in very very early boot (before the transition from real to virtual addressing). Not sure why, I was surprised. It seems related to the flattening of the device ndode tree. I'll try again soon. --linas From galak at freescale.com Thu Aug 25 02:56:56 2005 From: galak at freescale.com (Kumar Gala) Date: Wed, 24 Aug 2005 11:56:56 -0500 (CDT) Subject: [PATCH 09/15] ppc64: remove use of asm/segment.h In-Reply-To: References: Message-ID: Removed PPC64 architecture specific users of asm/segment.h and asm-ppc64/segment.h itself Signed-off-by: Kumar Gala --- commit 21a31cb366a764793dc532b525b95bfc3e1723a2 tree 2c40ec80e781b61fef42e5914d8f336dc72f2200 parent 53cbc8f4b0d47965e2d673bcc9dc5e6a8388350b author Kumar K. Gala Wed, 24 Aug 2005 10:55:55 -0500 committer Kumar K. Gala Wed, 24 Aug 2005 10:55:55 -0500 arch/ppc64/kernel/time.c | 1 - include/asm-ppc64/segment.h | 6 ------ 2 files changed, 0 insertions(+), 7 deletions(-) diff --git a/arch/ppc64/kernel/time.c b/arch/ppc64/kernel/time.c --- a/arch/ppc64/kernel/time.c +++ b/arch/ppc64/kernel/time.c @@ -51,7 +51,6 @@ #include #include -#include #include #include #include diff --git a/include/asm-ppc64/segment.h b/include/asm-ppc64/segment.h deleted file mode 100644 --- a/include/asm-ppc64/segment.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __PPC64_SEGMENT_H -#define __PPC64_SEGMENT_H - -/* Only here because we have some old header files that expect it.. */ - -#endif /* __PPC64_SEGMENT_H */ From trini at kernel.crashing.org Thu Aug 25 04:20:20 2005 From: trini at kernel.crashing.org (Tom Rini) Date: Wed, 24 Aug 2005 11:20:20 -0700 Subject: [PATCH 3/3] Move all the very similar files In-Reply-To: References: <20050822141235.GA7110@austin.ibm.com> <0F51EC83-8969-4083-B0D7-9343D075B635@freescale.com> <1124775707.5159.92.camel@gaston> <20050823173142.4f620d75.sfr@canb.auug.org.au> Message-ID: <20050824182020.GB15735@smtp.west.cox.net> On Tue, Aug 23, 2005 at 12:05:36PM -0500, Kumar Gala wrote: > > On Aug 23, 2005, at 2:31 AM, Stephen Rothwell wrote: > > >On Tue, 23 Aug 2005 15:41:47 +1000 Benjamin Herrenschmidt > > wrote: > > > >> > >>Most of the ones that are in include/asm* are there because drivers > >>outside of arch/* use them. > >> > > > >Indeed. Here is the result of grepping for all of the .h files in > >patch 3 (minus the > >obvious noncontentious ones like errno.h ...): > > This seems reasonable then to have them in include/asm-powerpc. I No it doesn't. You can easily make the drivers get the includes from , arch/$(ARCH) is already always in the search path, I believe (if not, it's easy to add Makefile things to get it). -- Tom Rini http://gate.crashing.org/~trini/ From sharada at in.ibm.com Thu Aug 25 04:39:44 2005 From: sharada at in.ibm.com (R Sharada) Date: Thu, 25 Aug 2005 00:09:44 +0530 Subject: [PATCH] export htab value for kexec on non-lpar - cleaned up patch In-Reply-To: <20050824133423.GN1012@otto> References: <20050823080423.GA2380@in.ibm.com> <20050824133423.GN1012@otto> Message-ID: <20050824183944.GA1869@in.ibm.com> Hello, Thanks for the comments. Here is the revised patch, cleaned up as per the review comments. Please review and consider for acceptance Signed-off-by: R Sharada --- diff -puN include/asm-ppc64/mmu.h~kexec-export-htab-value include/asm-ppc64/mmu.h --- linux-2.6.13-rc6-org/include/asm-ppc64/mmu.h~kexec-export-htab-value 2005-08-25 05:27:35.000000000 +0530 +++ linux-2.6.13-rc6-org-sharada/include/asm-ppc64/mmu.h 2005-08-25 05:28:12.000000000 +0530 @@ -57,7 +57,7 @@ /* * Hash table */ - +#define HASH_GROUP_SIZE 0x80 /* size of each hash group */ #define HPTES_PER_GROUP 8 #define HPTE_V_AVPN_SHIFT 7 diff -puN ./arch/ppc64/kernel/setup.c~kexec-export-htab-value ./arch/ppc64/kernel/setup.c --- linux-2.6.13-rc6-org/./arch/ppc64/kernel/setup.c~kexec-export-htab-value 2005-08-25 05:27:35.000000000 +0530 +++ linux-2.6.13-rc6-org-sharada/./arch/ppc64/kernel/setup.c 2005-08-25 05:36:41.000000000 +0530 @@ -103,6 +103,10 @@ extern void unflatten_device_tree(void); extern void smp_release_cpus(void); +/* required for kexec on non-lpar - htab_export_value */ +unsigned long htab_base, htab_size; +struct property newprop1, newprop2; + int have_of = 1; int boot_cpuid = 0; int boot_cpuid_phys = 0; @@ -1033,6 +1037,29 @@ void __init setup_syscall_map(void) count32, count64); } +static void __init export_htab_value(void) +{ + struct device_node *node; + + if (systemcfg->platform == PLATFORM_PSERIES_LPAR) + return; + + node = of_find_node_by_path("/chosen"); + if (!node) + return; + newprop1.name = "htab_base"; + newprop1.length = sizeof(unsigned long); + htab_base = __pa(htab_address); + newprop1.value = &htab_base; + prom_add_property(node, &newprop1); + newprop2.name = "htab_size"; + newprop2.length = sizeof(unsigned long); + htab_size = (htab_hash_mask + 1) * HASH_GROUP_SIZE; + newprop2.value = &htab_size; + prom_add_property(node, &newprop2); + of_node_put(node); +} + /* * Called into from start_kernel, after lock_kernel has been called. * Initializes bootmem, which is unsed to manage page allocation until @@ -1086,6 +1113,8 @@ void __init setup_arch(char **cmdline_p) } paging_init(); + /* export htab value into /proc/device-tree/chosen for kexec */ + export_htab_value(); ppc64_boot_msg(0x15, "Setup Done"); } Thanks and Regards, Sharada _ On Wed, Aug 24, 2005 at 08:34:23AM -0500, Nathan Lynch wrote: > > @@ -1086,6 +1093,9 @@ void __init setup_arch(char **cmdline_p) > > } > > > > paging_init(); > > +#ifdef CONFIG_KEXEC > > + export_htab_value(); > > +#endif > > ppc64_boot_msg(0x15, "Setup Done"); > > } > > > > @@ -1358,3 +1368,39 @@ void cpu_die(void) > > if (ppc_md.cpu_die) > > ppc_md.cpu_die(); > > } > > + > > +#ifdef CONFIG_KEXEC > > +void export_htab_value() > > +{ > > Can export_htab_value not be marked __init since it is called only > from setup_arch? From ntl at pobox.com Thu Aug 25 05:06:52 2005 From: ntl at pobox.com (Nathan Lynch) Date: Wed, 24 Aug 2005 14:06:52 -0500 Subject: [PATCH] export htab value for kexec on non-lpar - cleaned up patch In-Reply-To: <20050824183944.GA1869@in.ibm.com> References: <20050823080423.GA2380@in.ibm.com> <20050824133423.GN1012@otto> <20050824183944.GA1869@in.ibm.com> Message-ID: <20050824190652.GO1012@otto> R Sharada wrote: > +/* required for kexec on non-lpar - htab_export_value */ > +unsigned long htab_base, htab_size; > +struct property newprop1, newprop2; All of these could be static, right? I also suggest that the struct property variables need better names so that their intended use is more clear. Perhaps htab_base_prop and htab_size_prop. From arnd at arndb.de Thu Aug 25 06:03:26 2005 From: arnd at arndb.de (Arnd Bergmann) Date: Wed, 24 Aug 2005 22:03:26 +0200 Subject: [PATCH 3/3] Move all the very similar files In-Reply-To: <20050824182020.GB15735@smtp.west.cox.net> References: <20050822141235.GA7110@austin.ibm.com> <20050824182020.GB15735@smtp.west.cox.net> Message-ID: <200508242203.27210.arnd@arndb.de> On Middeweken 24 August 2005 20:20, Tom Rini wrote: > On Tue, Aug 23, 2005 at 12:05:36PM -0500, Kumar Gala wrote: > > > > This seems reasonable then to have them in include/asm-powerpc. I > > No it doesn't. You can easily make the drivers get the includes from > , arch/$(ARCH) is already always in the search > path, I believe (if not, it's easy to add Makefile things to get it). I don't think any architecture except ppc32 has traditionally had arch/$ARCH in its include path, and it would probably come as a surprise to many kernel developers if this were used more. Currently, there seem to be hardly any users of this "feature" in ppc32 that can't be trivially converted to including local files, so I'd rather not see this moved over to arch/powerpc. Arnd <>< From trini at kernel.crashing.org Thu Aug 25 06:13:32 2005 From: trini at kernel.crashing.org (Tom Rini) Date: Wed, 24 Aug 2005 13:13:32 -0700 Subject: [PATCH 3/3] Move all the very similar files In-Reply-To: <200508242203.27210.arnd@arndb.de> References: <20050822141235.GA7110@austin.ibm.com> <20050824182020.GB15735@smtp.west.cox.net> <200508242203.27210.arnd@arndb.de> Message-ID: <20050824201332.GD15735@smtp.west.cox.net> On Wed, Aug 24, 2005 at 10:03:26PM +0200, Arnd Bergmann wrote: > On Middeweken 24 August 2005 20:20, Tom Rini wrote: > > On Tue, Aug 23, 2005 at 12:05:36PM -0500, Kumar Gala wrote: > > > > > > This seems reasonable then to have them in include/asm-powerpc. I > > > > No it doesn't. You can easily make the drivers get the includes from > > , arch/$(ARCH) is already always in the search > > path, I believe (if not, it's easy to add Makefile things to get it). > > I don't think any architecture except ppc32 has traditionally had > arch/$ARCH in its include path, and it would probably come as a surprise > to many kernel developers if this were used more. True, but it's possible that the pmac drivers could also be converted to use something else to pass around infos, register IO and such so the headers can still live in arch/powerpc/platforms/pmac/ -- Tom Rini http://gate.crashing.org/~trini/ From moilanen at austin.ibm.com Thu Aug 25 06:22:12 2005 From: moilanen at austin.ibm.com (Jake Moilanen) Date: Wed, 24 Aug 2005 15:22:12 -0500 Subject: [PATCH] oprofile PVR 970MP Message-ID: <20050824152212.54303585.moilanen@austin.ibm.com> Here's the 970MP's PVR entry for oprofile. Signed-off-by: Jake Moilanen Index: 2.6-git/arch/ppc64/oprofile/common.c =================================================================== --- 2.6-git.orig/arch/ppc64/oprofile/common.c 2005-08-22 12:25:17.000000000 -0500 +++ 2.6-git/arch/ppc64/oprofile/common.c 2005-08-24 14:58:03.000000000 -0500 @@ -153,6 +153,7 @@ case PV_970: case PV_970FX: + case PV_970MP: model = &op_model_power4; model->num_counters = 8; ops->cpu_type = "ppc64/970"; Index: 2.6-git/include/asm-ppc64/processor.h =================================================================== --- 2.6-git.orig/include/asm-ppc64/processor.h 2005-08-22 12:25:22.000000000 -0500 +++ 2.6-git/include/asm-ppc64/processor.h 2005-08-24 14:59:25.000000000 -0500 @@ -268,6 +268,7 @@ #define PV_970FX 0x003C #define PV_630 0x0040 #define PV_630p 0x0041 +#define PV_970MP 0x0044 #define PV_BE 0x0070 /* Platforms supported by PPC64 */ From flar at allandria.com Thu Aug 25 06:44:33 2005 From: flar at allandria.com (Brad Boyer) Date: Wed, 24 Aug 2005 13:44:33 -0700 Subject: [PATCH 3/3] Move all the very similar files In-Reply-To: <20050824201332.GD15735@smtp.west.cox.net> References: <20050822141235.GA7110@austin.ibm.com> <20050824182020.GB15735@smtp.west.cox.net> <200508242203.27210.arnd@arndb.de> <20050824201332.GD15735@smtp.west.cox.net> Message-ID: <20050824204433.GB23118@pants.nu> On Wed, Aug 24, 2005 at 01:13:32PM -0700, Tom Rini wrote: > On Wed, Aug 24, 2005 at 10:03:26PM +0200, Arnd Bergmann wrote: > > On Middeweken 24 August 2005 20:20, Tom Rini wrote: > > > No it doesn't. You can easily make the drivers get the includes from > > > , arch/$(ARCH) is already always in the search > > > path, I believe (if not, it's easy to add Makefile things to get it). > > > > I don't think any architecture except ppc32 has traditionally had > > arch/$ARCH in its include path, and it would probably come as a surprise > > to many kernel developers if this were used more. > > True, but it's possible that the pmac drivers could also be converted to > use something else to pass around infos, register IO and such so the > headers can still live in arch/powerpc/platforms/pmac/ These days, the macio bus is a real device-model bus. The code still lives in drivers/macintosh, but it will be used by more than just pmac machines whenever I get the 68k mac support finished. It seems like we really should have an include/linux/macio.h, and make the whole thing act more like a normal bus. I would like to abstract out more of it anyway, particularly the DMA support. That way we wouldn't have several different drivers for the same chip due to bus interface differences (see mace.c and macmace.c for an example of current practice). This would eliminate at least macio.h and dbdma.h. Hopefully it would get most of the mac specific code organized in a more logical fashion. Any comments/requirements/suggestions? Brad Boyer flar at allandria.com From dwmw2 at infradead.org Thu Aug 25 09:02:25 2005 From: dwmw2 at infradead.org (David Woodhouse) Date: Thu, 25 Aug 2005 00:02:25 +0100 Subject: [PATCH] missing audit_syscall_exit() on sigsuspend exit to signal handler Message-ID: <1124924545.7316.85.camel@baythorne.infradead.org> When we leave sigsuspend() directly into a signal handler, we don't want to go via the normal syscall exit path -- it'll corrupt r4 and r5 which are supposed to be giving information to the signal handler, and it'll give us one more single-step SIGTRAP than we need if single-stepping is in operation. However, we _should_ be calling audit_syscall_exit(), which would normally get invoked in that patch. It's not wonderfully pretty, but I suspect the best answer is just to call it directly... Signed-off-by: David Woodhouse --- linux-2.6.12/arch/ppc64/kernel/asm-offsets.c.audit 2005-08-24 23:21:51.000000000 +0100 +++ linux-2.6.12/arch/ppc64/kernel/asm-offsets.c 2005-08-24 23:34:26.000000000 +0100 @@ -68,6 +68,7 @@ int main(void) DEFINE(THREAD_USED_VR, offsetof(struct thread_struct, used_vr)); #endif /* CONFIG_ALTIVEC */ DEFINE(MM, offsetof(struct task_struct, mm)); + DEFINE(AUDITCONTEXT, offsetof(struct task_struct, audit_context)); DEFINE(DCACHEL1LINESIZE, offsetof(struct ppc64_caches, dline_size)); DEFINE(DCACHEL1LOGLINESIZE, offsetof(struct ppc64_caches, log_dline_size)); --- linux-2.6.12/arch/ppc64/kernel/entry.S.audit 2005-08-24 23:20:57.000000000 +0100 +++ linux-2.6.12/arch/ppc64/kernel/entry.S 2005-08-24 23:33:18.000000000 +0100 @@ -276,12 +276,20 @@ _GLOBAL(ppc64_rt_sigsuspend) _GLOBAL(ppc32_rt_sigsuspend) bl .save_nvgprs bl .sys32_rt_sigsuspend - /* If sigsuspend() returns zero, we are going into a signal handler */ 70: cmpdi 0,r3,0 - beq .ret_from_except - /* If it returned -EINTR, we need to return via syscall_exit to set + /* If it returned an error, we need to return via syscall_exit to set the SO bit in cr0 and potentially stop for ptrace. */ - b syscall_exit + bne syscall_exit + /* If sigsuspend() returns zero, we are going into a signal handler. We + may need to call audit_syscall_exit() to mark the exit from sigsuspend() */ + ld r3,PACACURRENT(r13) + ld r4,AUDITCONTEXT(r3) + cmpdi 0,r4,0 + beq .ret_from_except /* No audit_context: Leave immediately. */ + li r4, 2 /* AUDITSC_FAILURE */ + li r5,-4 /* It's always -EINTR */ + bl .audit_syscall_exit + b .ret_from_except _GLOBAL(ppc_fork) bl .save_nvgprs -- dwmw2 From paulus at samba.org Thu Aug 25 09:30:40 2005 From: paulus at samba.org (Paul Mackerras) Date: Thu, 25 Aug 2005 09:30:40 +1000 Subject: [RFC/PATCH] Set up PCI tree from OF on ppc64 Message-ID: <17165.800.617053.891578@cargo.ozlabs.ibm.com> This patch adds code which gives us the option on ppc64 of instantiating the PCI tree (the tree of pci_bus and pci_dev structs) from the Open Firmware device tree rather than by probing PCI configuration space. The OF device tree has a node for each PCI device and bridge in the system, with properties that tell us what addresses the firmware has configured for them and other details. There are a couple of reasons why this is needed. First, on systems with a hypervisor, there is a PCI-PCI bridge per slot under the PCI host bridges. These PCI-PCI bridges have special isolation features for virtualization. We can't write to their config space, and we are not supposed to be reading their config space either. The firmware tells us about the address ranges that they pass in the OF device tree. Secondly, on powermacs, the interrupt controller is in a PCI device that may be behind a PCI-PCI bridge. If we happened to take an interrupt just at the point when the device or a bridge on the path to it was disabled for probing, we would crash when we try to access the interrupt controller. I have implemented a platform-specific function which is called for each PCI bridge (host or PCI-PCI) to say whether the code should look in the device tree or use normal PCI probing for the devices under that bridge. On pSeries machines we use the device tree if we're running under a hypervisor, otherwise we use normal probing. On powermacs we use normal probing for the AGP bridge, since the device for the AGP bridge itself isn't shown in the device tree (at least on my G5), and the device tree for everything else. The patch does some minor rearrangement of the generic PCI probing code so that we can reuse as much code from drivers/pci as makes sense. This has been tested on a dual G5 powermac and a partition on a POWER5 machine (running under the hypervisor). Any comments? Paul. diff -urN linux-2.6/arch/ppc64/kernel/pSeries_setup.c g5-ofpci/arch/ppc64/kernel/pSeries_setup.c --- linux-2.6/arch/ppc64/kernel/pSeries_setup.c 2005-07-14 20:07:04.000000000 +1000 +++ g5-ofpci/arch/ppc64/kernel/pSeries_setup.c 2005-08-24 14:09:07.000000000 +1000 @@ -574,6 +574,13 @@ return 0; } +static int pSeries_pci_probe_mode(struct pci_bus *bus) +{ + if (systemcfg->platform & PLATFORM_LPAR) + return PCI_PROBE_DEVTREE; + return PCI_PROBE_NORMAL; +} + struct machdep_calls __initdata pSeries_md = { .probe = pSeries_probe, .setup_arch = pSeries_setup_arch, @@ -581,6 +588,7 @@ .get_cpuinfo = pSeries_get_cpuinfo, .log_error = pSeries_log_error, .pcibios_fixup = pSeries_final_fixup, + .pci_probe_mode = pSeries_pci_probe_mode, .irq_bus_setup = pSeries_irq_bus_setup, .restart = rtas_restart, .power_off = rtas_power_off, diff -urN linux-2.6/arch/ppc64/kernel/pci.c g5-ofpci/arch/ppc64/kernel/pci.c --- linux-2.6/arch/ppc64/kernel/pci.c 2005-08-05 19:00:43.000000000 +1000 +++ g5-ofpci/arch/ppc64/kernel/pci.c 2005-08-24 21:01:16.000000000 +1000 @@ -50,6 +50,8 @@ EXPORT_SYMBOL(io_page_mask); +static void fixup_resource(struct resource *res, struct pci_dev *dev); +static void do_bus_setup(struct pci_bus *bus); unsigned int pcibios_assign_all_busses(void) { @@ -225,10 +227,283 @@ } #endif +static u32 get_int_prop(struct device_node *np, const char *name, u32 def) +{ + u32 *prop; + int len; + + prop = (u32 *) get_property(np, name, &len); + if (prop && len >= 4) + return *prop; + return def; +} + +static unsigned int pci_parse_of_flags(u32 addr0) +{ + unsigned int flags = 0; + + if (addr0 & 0x02000000) { + flags |= IORESOURCE_MEM; + if (addr0 & 0x40000000) + flags |= IORESOURCE_PREFETCH; + } else if (addr0 & 0x01000000) + flags |= IORESOURCE_IO; + return flags; +} + +#define GET_64BIT(prop, i) ((((u64) (prop)[(i)]) << 32) | (prop)[(i)+1]) + +static void pci_parse_of_addrs(struct device_node *node, struct pci_dev *dev) +{ + u64 base, size; + unsigned int flags; + struct resource *res; + u32 *addrs, i; + int proplen; + + addrs = (u32 *) get_property(node, "assigned-addresses", &proplen); + if (!addrs) + return; + for (; proplen >= 20; proplen -= 20, addrs += 5) { + flags = pci_parse_of_flags(addrs[0]); + if (!flags) + continue; + base = GET_64BIT(addrs, 1); + size = GET_64BIT(addrs, 3); + if (!size) + continue; + i = addrs[0] & 0xff; + if (PCI_BASE_ADDRESS_0 <= i && i <= PCI_BASE_ADDRESS_5) { + res = &dev->resource[(i - PCI_BASE_ADDRESS_0) >> 2]; + } else if (i == dev->rom_base_reg) { + res = &dev->resource[PCI_ROM_RESOURCE]; + flags |= IORESOURCE_READONLY | IORESOURCE_CACHEABLE; + } else { + printk(KERN_ERR "PCI: bad cfg reg num 0x%x\n", i); + continue; + } + res->start = base; + res->end = base + size - 1; + res->flags = flags; + res->name = pci_name(dev); + fixup_resource(res, dev); + } +} + +static struct pci_dev *of_create_pci_dev(struct device_node *node, + struct pci_bus *bus, int devfn) +{ + struct pci_dev *dev; + const char *type; + + dev = kmalloc(sizeof(struct pci_dev), GFP_KERNEL); + if (!dev) + return NULL; + type = get_property(node, "device_type", NULL); + if (type == NULL) + type = ""; + + memset(dev, 0, sizeof(struct pci_dev)); + dev->bus = bus; + dev->sysdata = node; + dev->dev.parent = bus->bridge; + dev->dev.bus = &pci_bus_type; + dev->devfn = devfn; + dev->multifunction = 0; /* maybe a lie? */ + + dev->vendor = get_int_prop(node, "vendor-id", 0xffff); + dev->device = get_int_prop(node, "device-id", 0xffff); + dev->subsystem_vendor = get_int_prop(node, "subsystem-vendor-id", 0); + dev->subsystem_device = get_int_prop(node, "subsystem-id", 0); + + dev->cfg_size = 256; /*pci_cfg_space_size(dev);*/ + + sprintf(pci_name(dev), "%04x:%02x:%02x.%d", pci_domain_nr(bus), + dev->bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn)); + dev->class = get_int_prop(node, "class-code", 0); + + dev->current_state = 4; /* unknown power state */ + + if (!strcmp(type, "pci")) { + /* a PCI-PCI bridge */ + dev->hdr_type = PCI_HEADER_TYPE_BRIDGE; + dev->rom_base_reg = PCI_ROM_ADDRESS1; + } else if (!strcmp(type, "cardbus")) { + dev->hdr_type = PCI_HEADER_TYPE_CARDBUS; + } else { + dev->hdr_type = PCI_HEADER_TYPE_NORMAL; + dev->rom_base_reg = PCI_ROM_ADDRESS; + dev->irq = NO_IRQ; + if (node->n_intrs > 0) { + dev->irq = node->intrs[0].line; + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, + dev->irq); + } + } + + pci_parse_of_addrs(node, dev); + + pci_device_add(dev, bus); + + /* XXX pci_scan_msi_device(dev); ? */ + + return dev; +} + +static void of_scan_pci_bridge(struct device_node *node, struct pci_dev *dev); + +static void __devinit of_scan_bus(struct device_node *node, + struct pci_bus *bus) +{ + struct device_node *child = NULL; + u32 *reg; + int reglen, devfn; + struct pci_dev *dev; + + while ((child = of_get_next_child(node, child)) != NULL) { + reg = (u32 *) get_property(child, "reg", ®len); + if (reg == NULL || reglen < 20) + continue; + devfn = (reg[0] >> 8) & 0xff; + /* create a new pci_dev for this device */ + dev = of_create_pci_dev(child, bus, devfn); + if (!dev) + continue; + if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE || + dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) + of_scan_pci_bridge(child, dev); + } + + do_bus_setup(bus); +} + +static void __devinit of_scan_pci_bridge(struct device_node *node, + struct pci_dev *dev) +{ + struct pci_bus *bus; + u32 *busrange, *ranges; + int len, i, mode; + struct resource *res; + unsigned int flags; + u64 size; + + /* parse bus-range property */ + busrange = (u32 *) get_property(node, "bus-range", &len); + if (busrange == NULL || len != 8) { + printk(KERN_ERR "Can't get bus-range for PCI-PCI bridge %s\n", + node->full_name); + return; + } + ranges = (u32 *) get_property(node, "ranges", &len); + if (ranges == NULL) { + printk(KERN_ERR "Can't get ranges for PCI-PCI bridge %s\n", + node->full_name); + return; + } + + bus = pci_add_new_bus(dev->bus, dev, busrange[0]); + if (!bus) { + printk(KERN_ERR "Failed to create pci bus for %s\n", + node->full_name); + return; + } + + bus->primary = dev->bus->number; + bus->subordinate = busrange[1]; + bus->bridge_ctl = 0; + bus->sysdata = node; + + /* parse ranges property */ + /* PCI #address-cells == 3 and #size-cells == 2 always */ + res = &dev->resource[PCI_BRIDGE_RESOURCES]; + for (i = 0; i < PCI_NUM_RESOURCES - PCI_BRIDGE_RESOURCES; ++i) { + res->flags = 0; + bus->resource[i] = res; + ++res; + } + i = 1; + for (; len >= 32; len -= 32, ranges += 8) { + flags = pci_parse_of_flags(ranges[0]); + size = GET_64BIT(ranges, 6); + if (flags == 0 || size == 0) + continue; + if (flags & IORESOURCE_IO) { + res = bus->resource[0]; + if (res->flags) { + printk(KERN_ERR "PCI: ignoring extra I/O range" + " for bridge %s\n", node->full_name); + continue; + } + } else { + if (i >= PCI_NUM_RESOURCES - PCI_BRIDGE_RESOURCES) { + printk(KERN_ERR "PCI: too many memory ranges" + " for bridge %s\n", node->full_name); + continue; + } + res = bus->resource[i]; + ++i; + } + res->start = GET_64BIT(ranges, 1); + res->end = res->start + size - 1; + res->flags = flags; + fixup_resource(res, dev); + } + sprintf(bus->name, "PCI Bus %04x:%02x", pci_domain_nr(bus), + bus->number); + + mode = PCI_PROBE_NORMAL; + if (ppc_md.pci_probe_mode) + mode = ppc_md.pci_probe_mode(bus); + if (mode == PCI_PROBE_DEVTREE) + of_scan_bus(node, bus); + else if (mode == PCI_PROBE_NORMAL) + pci_scan_child_bus(bus); +} + +static void __devinit scan_phb(struct pci_controller *hose) +{ + struct pci_bus *bus; + struct device_node *node = hose->arch_data; + int i, mode; + struct resource *res; + + bus = pci_create_bus(NULL, hose->first_busno, hose->ops, node); + if (bus == NULL) { + printk(KERN_ERR "Failed to create bus for PCI domain %04x\n", + hose->global_number); + return; + } + bus->secondary = hose->first_busno; + hose->bus = bus; + + bus->resource[0] = res = &hose->io_resource; + if (res->flags && request_resource(&ioport_resource, res)) + printk(KERN_ERR "Failed to request PCI IO region " + "on PCI domain %04x\n", hose->global_number); + + for (i = 0; i < 3; ++i) { + res = &hose->mem_resources[i]; + bus->resource[i+1] = res; + if (res->flags && request_resource(&iomem_resource, res)) + printk(KERN_ERR "Failed to request PCI memory region " + "on PCI domain %04x\n", hose->global_number); + } + + mode = PCI_PROBE_NORMAL; + if (ppc_md.pci_probe_mode) + mode = ppc_md.pci_probe_mode(bus); + if (mode == PCI_PROBE_DEVTREE) { + bus->subordinate = hose->last_busno; + of_scan_bus(node, bus); + } else if (mode == PCI_PROBE_NORMAL) { + hose->last_busno = bus->subordinate = pci_scan_child_bus(bus); + } + pci_bus_add_devices(bus); +} + static int __init pcibios_init(void) { struct pci_controller *hose, *tmp; - struct pci_bus *bus; /* For now, override phys_mem_access_prot. If we need it, * later, we may move that initialization to each ppc_md @@ -242,13 +517,8 @@ printk("PCI: Probing PCI hardware\n"); /* Scan all of the recorded PCI controllers. */ - list_for_each_entry_safe(hose, tmp, &hose_list, list_node) { - hose->last_busno = 0xff; - bus = pci_scan_bus(hose->first_busno, hose->ops, - hose->arch_data); - hose->bus = bus; - hose->last_busno = bus->subordinate; - } + list_for_each_entry_safe(hose, tmp, &hose_list, list_node) + scan_phb(hose); #ifndef CONFIG_PPC_ISERIES if (pci_probe_only) @@ -820,6 +1090,8 @@ /* * ppc64 can have multifunction devices that do not respond to function 0. * In this case we must scan all functions. + * XXX this can go now, we use the OF device tree in all the + * cases that caused problems. -- paulus */ int pcibios_scan_all_fns(struct pci_bus *bus, int devfn) { @@ -845,93 +1117,81 @@ return 0; } +static void __devinit fixup_resource(struct resource *res, struct pci_dev *dev) +{ + struct pci_controller *hose = pci_bus_to_host(dev->bus); + unsigned long start, end, mask, offset; + + if (res->flags & IORESOURCE_IO) { + offset = (unsigned long)hose->io_base_virt - pci_io_base; + + start = res->start += offset; + end = res->end += offset; + + /* Need to allow IO access to pages that are in the + ISA range */ + if (start < MAX_ISA_PORT) { + if (end > MAX_ISA_PORT) + end = MAX_ISA_PORT; + + start >>= PAGE_SHIFT; + end >>= PAGE_SHIFT; + + /* get the range of pages for the map */ + mask = ((1 << (end+1)) - 1) ^ ((1 << start) - 1); + io_page_mask |= mask; + } + } else if (res->flags & IORESOURCE_MEM) { + res->start += hose->pci_mem_offset; + res->end += hose->pci_mem_offset; + } +} void __devinit pcibios_fixup_device_resources(struct pci_dev *dev, - struct pci_bus *bus) + struct pci_bus *bus) { /* Update device resources. */ - struct pci_controller *hose = pci_bus_to_host(bus); int i; - for (i = 0; i < PCI_NUM_RESOURCES; i++) { - if (dev->resource[i].flags & IORESOURCE_IO) { - unsigned long offset = (unsigned long)hose->io_base_virt - - pci_io_base; - unsigned long start, end, mask; - - start = dev->resource[i].start += offset; - end = dev->resource[i].end += offset; - - /* Need to allow IO access to pages that are in the - ISA range */ - if (start < MAX_ISA_PORT) { - if (end > MAX_ISA_PORT) - end = MAX_ISA_PORT; - - start >>= PAGE_SHIFT; - end >>= PAGE_SHIFT; - - /* get the range of pages for the map */ - mask = ((1 << (end+1))-1) ^ ((1 << start)-1); - io_page_mask |= mask; - } - } - else if (dev->resource[i].flags & IORESOURCE_MEM) { - dev->resource[i].start += hose->pci_mem_offset; - dev->resource[i].end += hose->pci_mem_offset; - } - } + for (i = 0; i < PCI_NUM_RESOURCES; i++) + if (dev->resource[i].flags) + fixup_resource(&dev->resource[i], dev); } EXPORT_SYMBOL(pcibios_fixup_device_resources); -void __devinit pcibios_fixup_bus(struct pci_bus *bus) +static void __devinit do_bus_setup(struct pci_bus *bus) { - struct pci_controller *hose = pci_bus_to_host(bus); - struct pci_dev *dev = bus->self; - struct resource *res; - int i; + struct pci_dev *dev; - if (!dev) { - /* Root bus. */ + ppc_md.iommu_bus_setup(bus); - hose->bus = bus; - bus->resource[0] = res = &hose->io_resource; + list_for_each_entry(dev, &bus->devices, bus_list) + ppc_md.iommu_dev_setup(dev); - if (res->flags && request_resource(&ioport_resource, res)) - printk(KERN_ERR "Failed to request IO on " - "PCI domain %d\n", pci_domain_nr(bus)); - - for (i = 0; i < 3; ++i) { - res = &hose->mem_resources[i]; - bus->resource[i+1] = res; - if (res->flags && request_resource(&iomem_resource, res)) - printk(KERN_ERR "Failed to request MEM on " - "PCI domain %d\n", - pci_domain_nr(bus)); - } - } else if (pci_probe_only && - (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) { + if (ppc_md.irq_bus_setup) + ppc_md.irq_bus_setup(bus); +} + +void __devinit pcibios_fixup_bus(struct pci_bus *bus) +{ + struct pci_dev *dev = bus->self; + + if (dev && pci_probe_only && + (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) { /* This is a subordinate bridge */ pci_read_bridge_bases(bus); pcibios_fixup_device_resources(dev, bus); } - ppc_md.iommu_bus_setup(bus); - - list_for_each_entry(dev, &bus->devices, bus_list) - ppc_md.iommu_dev_setup(dev); - - if (ppc_md.irq_bus_setup) - ppc_md.irq_bus_setup(bus); + do_bus_setup(bus); if (!pci_probe_only) return; - list_for_each_entry(dev, &bus->devices, bus_list) { + list_for_each_entry(dev, &bus->devices, bus_list) if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI) pcibios_fixup_device_resources(dev, bus); - } } EXPORT_SYMBOL(pcibios_fixup_bus); diff -urN linux-2.6/arch/ppc64/kernel/pmac_setup.c g5-ofpci/arch/ppc64/kernel/pmac_setup.c --- linux-2.6/arch/ppc64/kernel/pmac_setup.c 2005-07-28 12:51:10.000000000 +1000 +++ g5-ofpci/arch/ppc64/kernel/pmac_setup.c 2005-08-24 22:00:52.000000000 +1000 @@ -489,6 +489,18 @@ return 1; } +static int pmac_probe_mode(struct pci_bus *bus) +{ + struct device_node *node = bus->sysdata; + + /* We need to use normal PCI probing for the AGP bus, + since the device for the AGP bridge isn't in the tree. */ + if (bus->self == NULL && device_is_compatible(node, "u3-agp")) + return PCI_PROBE_NORMAL; + + return PCI_PROBE_DEVTREE; +} + struct machdep_calls __initdata pmac_md = { #ifdef CONFIG_HOTPLUG_CPU .cpu_die = generic_mach_cpu_die, @@ -500,6 +512,7 @@ .init_IRQ = pmac_init_IRQ, .get_irq = mpic_get_irq, .pcibios_fixup = pmac_pcibios_fixup, + .pci_probe_mode = pmac_probe_mode, .restart = pmac_restart, .power_off = pmac_power_off, .halt = pmac_halt, diff -urN linux-2.6/drivers/pci/pci.h g5-ofpci/drivers/pci/pci.h --- linux-2.6/drivers/pci/pci.h 2005-08-17 17:51:11.000000000 +1000 +++ g5-ofpci/drivers/pci/pci.h 2005-08-22 16:25:43.000000000 +1000 @@ -29,7 +29,6 @@ #endif /* Functions for PCI Hotplug drivers to use */ -extern struct pci_bus * pci_add_new_bus(struct pci_bus *parent, struct pci_dev *dev, int busnr); extern unsigned int pci_do_scan_bus(struct pci_bus *bus); extern int pci_remove_device_safe(struct pci_dev *dev); extern unsigned char pci_max_busnr(void); diff -urN linux-2.6/drivers/pci/probe.c g5-ofpci/drivers/pci/probe.c --- linux-2.6/drivers/pci/probe.c 2005-07-31 17:38:35.000000000 +1000 +++ g5-ofpci/drivers/pci/probe.c 2005-08-22 15:03:30.000000000 +1000 @@ -753,6 +753,12 @@ kfree(dev); return NULL; } + + return dev; +} + +void __devinit pci_device_add(struct pci_dev *dev, struct pci_bus *bus) +{ device_initialize(&dev->dev); dev->dev.release = pci_release_dev; pci_dev_get(dev); @@ -762,20 +768,6 @@ dev->dev.dma_mask = &dev->dma_mask; dev->dev.coherent_dma_mask = 0xffffffffull; - return dev; -} - -struct pci_dev * __devinit -pci_scan_single_device(struct pci_bus *bus, int devfn) -{ - struct pci_dev *dev; - - dev = pci_scan_device(bus, devfn); - pci_scan_msi_device(dev); - - if (!dev) - return NULL; - /* Fix up broken headers */ pci_fixup_device(pci_fixup_header, dev); @@ -787,6 +779,19 @@ spin_lock(&pci_bus_lock); list_add_tail(&dev->bus_list, &bus->devices); spin_unlock(&pci_bus_lock); +} + +struct pci_dev * __devinit +pci_scan_single_device(struct pci_bus *bus, int devfn) +{ + struct pci_dev *dev; + + dev = pci_scan_device(bus, devfn); + if (!dev) + return NULL; + + pci_device_add(dev, bus); + pci_scan_msi_device(dev); return dev; } @@ -883,7 +888,8 @@ return max; } -struct pci_bus * __devinit pci_scan_bus_parented(struct device *parent, int bus, struct pci_ops *ops, void *sysdata) +struct pci_bus * __devinit pci_create_bus(struct device *parent, + int bus, struct pci_ops *ops, void *sysdata) { int error; struct pci_bus *b; @@ -940,8 +946,6 @@ b->resource[0] = &ioport_resource; b->resource[1] = &iomem_resource; - b->subordinate = pci_scan_child_bus(b); - return b; sys_create_link_err: @@ -959,6 +963,18 @@ kfree(b); return NULL; } +EXPORT_SYMBOL_GPL(pci_create_bus); + +struct pci_bus * __devinit pci_scan_bus_parented(struct device *parent, + int bus, struct pci_ops *ops, void *sysdata) +{ + struct pci_bus *b; + + b = pci_create_bus(parent, bus, ops, sysdata); + if (b) + b->subordinate = pci_scan_child_bus(b); + return b; +} EXPORT_SYMBOL(pci_scan_bus_parented); #ifdef CONFIG_HOTPLUG diff -urN linux-2.6/include/asm-ppc64/machdep.h g5-ofpci/include/asm-ppc64/machdep.h --- linux-2.6/include/asm-ppc64/machdep.h 2005-08-05 08:51:40.000000000 +1000 +++ g5-ofpci/include/asm-ppc64/machdep.h 2005-08-24 11:30:53.000000000 +1000 @@ -88,6 +88,7 @@ /* PCI stuff */ void (*pcibios_fixup)(void); + int (*pci_probe_mode)(struct pci_bus *); void (*restart)(char *cmd); void (*power_off)(void); diff -urN linux-2.6/include/asm-ppc64/pci-bridge.h g5-ofpci/include/asm-ppc64/pci-bridge.h --- linux-2.6/include/asm-ppc64/pci-bridge.h 2005-04-26 15:38:02.000000000 +1000 +++ g5-ofpci/include/asm-ppc64/pci-bridge.h 2005-08-24 11:34:23.000000000 +1000 @@ -86,5 +86,10 @@ return busdn->phb; } +/* Return values for ppc_md.pci_probe_mode function */ +#define PCI_PROBE_NONE -1 /* Don't look at this bus at all */ +#define PCI_PROBE_NORMAL 0 /* Do normal PCI probing */ +#define PCI_PROBE_DEVTREE 1 /* Instantiate from device tree */ + #endif #endif /* __KERNEL__ */ diff -urN linux-2.6/include/linux/pci.h g5-ofpci/include/linux/pci.h --- linux-2.6/include/linux/pci.h 2005-08-17 17:51:11.000000000 +1000 +++ g5-ofpci/include/linux/pci.h 2005-08-24 21:06:14.000000000 +1000 @@ -745,8 +745,11 @@ pci_bus_add_devices(root_bus); return root_bus; } +struct pci_bus *pci_create_bus(struct device *parent, int bus, struct pci_ops *ops, void *sysdata); +struct pci_bus * pci_add_new_bus(struct pci_bus *parent, struct pci_dev *dev, int busnr); int pci_scan_slot(struct pci_bus *bus, int devfn); struct pci_dev * pci_scan_single_device(struct pci_bus *bus, int devfn); +void pci_device_add(struct pci_dev *dev, struct pci_bus *bus); unsigned int pci_scan_child_bus(struct pci_bus *bus); void pci_bus_add_device(struct pci_dev *dev); void pci_name_device(struct pci_dev *dev); From paulus at samba.org Thu Aug 25 10:10:45 2005 From: paulus at samba.org (Paul Mackerras) Date: Thu, 25 Aug 2005 10:10:45 +1000 Subject: [patch 8/8] PCI Error Recovery: PPC64 core recovery routines In-Reply-To: <20050824162959.GC25174@austin.ibm.com> References: <20050823231817.829359000@bilge> <20050823232143.003048000@bilge> <20050823234747.GI18113@austin.ibm.com> <1124898331.24668.33.camel@sinatra.austin.ibm.com> <20050824162959.GC25174@austin.ibm.com> Message-ID: <17165.3205.505386.187453@cargo.ozlabs.ibm.com> Linas Vepstas writes: > The meta-issue that I'd like to reach consensus on first is whether > there should be any hot-plug recovery attempted at all. Removing > hot-plug-recovery support will make many of the issues you raise > to be moot. Yes, this probably the thorniest issue we have. My feeling is that the unplug half of it is probably fairly uncontroversial, but the replug half is a can of worms. Would you agree with that? Is it udev that handles the hotplug notifications on the userspace side in all cases (do both RHEL and SLES use udev, for instance)? How hard is it to add a new sort of notification, on the kernel side and in udev? I think what I'd like to see is that when a slot gets isolated and the driver doesn't have recovery code, the kernel calls the driver's unplug function and generates a hotplug event to udev. Ideally this would be a variant of the remove event which would say "and by the way, please try replugging this slot when you've finished handling the remove event" or something along those lines. Thoughts? Paul. From becky.bruce at freescale.com Thu Aug 25 10:23:15 2005 From: becky.bruce at freescale.com (Becky Bruce) Date: Wed, 24 Aug 2005 19:23:15 -0500 Subject: termbits.h question Message-ID: So, Can anyone explain why termbits.h in include/asm-ppc64 #includes linux/posix_types.h? It doesn't seem to be needed by termbits.h itself, and I've successfully built all the 64-bit ppc configs without the #include. I'm wondering if this is historical, or if there's some other reason I'm missing. I'd like to merge this with the very similar 32-bit version, but I need to understand why this #include is there. It's missing in the 32-bit version, which is essentially the same file, ordered slightly differently. Cheers, B From benh at kernel.crashing.org Thu Aug 25 10:49:03 2005 From: benh at kernel.crashing.org (Benjamin Herrenschmidt) Date: Thu, 25 Aug 2005 10:49:03 +1000 Subject: [patch 8/8] PCI Error Recovery: PPC64 core recovery routines In-Reply-To: <17165.3205.505386.187453@cargo.ozlabs.ibm.com> References: <20050823231817.829359000@bilge> <20050823232143.003048000@bilge> <20050823234747.GI18113@austin.ibm.com> <1124898331.24668.33.camel@sinatra.austin.ibm.com> <20050824162959.GC25174@austin.ibm.com> <17165.3205.505386.187453@cargo.ozlabs.ibm.com> Message-ID: <1124930943.5159.168.camel@gaston> > I think what I'd like to see is that when a slot gets isolated and the > driver doesn't have recovery code, the kernel calls the driver's > unplug function and generates a hotplug event to udev. Ideally this > would be a variant of the remove event which would say "and by the > way, please try replugging this slot when you've finished handling the > remove event" or something along those lines. I'm still trying to understand why we care. What prevents us from just uplugging the previous device and re-plugging right away ? After all, the driver->remove() function is supposed to guarantee that no HW access will happen after it returns and that everything was unmapped. Of course, we'll possibly end up with a different ethX or whatever, but I don't see the problem with that ... It's hopeless to think we might manage to keep that identical anyway, unless the driver implements proper error recovery. Ben. From paulus at samba.org Thu Aug 25 12:10:02 2005 From: paulus at samba.org (Paul Mackerras) Date: Thu, 25 Aug 2005 12:10:02 +1000 Subject: termbits.h question In-Reply-To: References: Message-ID: <17165.10362.492949.726155@cargo.ozlabs.ibm.com> Becky Bruce writes: > Can anyone explain why termbits.h in include/asm-ppc64 #includes > linux/posix_types.h? At this stage, I doubt it. :) The include was present when the ppc64 support was added to the 2.5 tree. > It doesn't seem to be needed by termbits.h itself, and I've > successfully built all the 64-bit ppc configs without the #include. > I'm wondering if this is historical, or if there's some other reason > I'm missing. I can't see any reason why we need it. > I'd like to merge this with the very similar 32-bit version, but I need Go ahead... :) Paul. From sharada at in.ibm.com Thu Aug 25 14:42:06 2005 From: sharada at in.ibm.com (R Sharada) Date: Thu, 25 Aug 2005 10:12:06 +0530 Subject: [PATCH] export htab value for kexec on non-lpar - cleaned up patch In-Reply-To: <20050824190652.GO1012@otto> References: <20050823080423.GA2380@in.ibm.com> <20050824133423.GN1012@otto> <20050824183944.GA1869@in.ibm.com> <20050824190652.GO1012@otto> Message-ID: <20050825044206.GA2079@in.ibm.com> Nathan, Thanks for the comments. It makes sense to make then static and more appropriately named. Have done the same and re-posting the patch with those minor changes Thanks and Regards, Sharada Signed-off-by: R Sharada --- diff -puN include/asm-ppc64/mmu.h~kexec-export-htab-value include/asm-ppc64/mmu.h --- linux-2.6.13-rc6-org/include/asm-ppc64/mmu.h~kexec-export-htab-value 2005-08-25 05:27:35.000000000 +0530 +++ linux-2.6.13-rc6-org-sharada/include/asm-ppc64/mmu.h 2005-08-25 05:28:12.000000000 +0530 @@ -57,7 +57,7 @@ /* * Hash table */ - +#define HASH_GROUP_SIZE 0x80 /* size of each hash group */ #define HPTES_PER_GROUP 8 #define HPTE_V_AVPN_SHIFT 7 diff -puN ./arch/ppc64/kernel/setup.c~kexec-export-htab-value ./arch/ppc64/kernel/setup.c --- linux-2.6.13-rc6-org/./arch/ppc64/kernel/setup.c~kexec-export-htab-value 2005-08-25 05:27:35.000000000 +0530 +++ linux-2.6.13-rc6-org-sharada/./arch/ppc64/kernel/setup.c 2005-08-25 15:40:38.000000000 +0530 @@ -103,6 +103,10 @@ extern void unflatten_device_tree(void); extern void smp_release_cpus(void); +/* required for kexec on non-lpar - htab_export_value */ +static unsigned long htab_base, htab_size; +static struct property htab_base_prop, htab_size_prop; + int have_of = 1; int boot_cpuid = 0; int boot_cpuid_phys = 0; @@ -1033,6 +1037,29 @@ void __init setup_syscall_map(void) count32, count64); } +static void __init export_htab_value(void) +{ + struct device_node *node; + + if (systemcfg->platform == PLATFORM_PSERIES_LPAR) + return; + + node = of_find_node_by_path("/chosen"); + if (!node) + return; + htab_base_prop.name = "htab_base"; + htab_base_prop.length = sizeof(unsigned long); + htab_base = __pa(htab_address); + htab_base_prop.value = &htab_base; + prom_add_property(node, &htab_base_prop); + htab_size_prop.name = "htab_size"; + htab_size_prop.length = sizeof(unsigned long); + htab_size = (htab_hash_mask + 1) * HASH_GROUP_SIZE; + htab_size_prop.value = &htab_size; + prom_add_property(node, &htab_size_prop); + of_node_put(node); +} + /* * Called into from start_kernel, after lock_kernel has been called. * Initializes bootmem, which is unsed to manage page allocation until @@ -1086,6 +1113,8 @@ void __init setup_arch(char **cmdline_p) } paging_init(); + /* export htab value into /proc/device-tree/chosen for kexec */ + export_htab_value(); ppc64_boot_msg(0x15, "Setup Done"); } - On Wed, Aug 24, 2005 at 02:06:52PM -0500, Nathan Lynch wrote: > R Sharada wrote: > > +/* required for kexec on non-lpar - htab_export_value */ > > +unsigned long htab_base, htab_size; > > +struct property newprop1, newprop2; > > All of these could be static, right? > > I also suggest that the struct property variables need better names so > that their intended use is more clear. Perhaps htab_base_prop and > htab_size_prop. From bgill at freescale.com Thu Aug 25 12:40:27 2005 From: bgill at freescale.com (Becky Bruce) Date: Wed, 24 Aug 2005 21:40:27 -0500 (CDT) Subject: [PATCH] ppc: Move 3 more headers to asm-powerpc Message-ID: Merged several nearly-identical header files from asm-ppc and asm-ppc64 into asm-powerpc. This patch requires Stephen Rothwell's recent [PATCH 1/3] Create include/asm-powerpc. Signed-off-by: Kumar Gala Signed-off-by: Becky Bruce --- commit 630b4d31338fdf66ff6d3e8f793b4dc2782e09b5 tree d0e785d79a1bca0f09558d181e2cb3cb4105eb0e parent a9fa7aff4d2ef08fef0d393d1853b65f861e61bb author Becky Bruce Wed, 24 Aug 2005 11:40:41 -0500 committer Becky Bruce Wed, 24 Aug 2005 11:40:41 -0500 include/asm-powerpc/mman.h | 52 +++++++++ include/asm-powerpc/termbits.h | 191 ++++++++++++++++++++++++++++++++ include/asm-powerpc/termios.h | 236 ++++++++++++++++++++++++++++++++++++++++ include/asm-ppc/mman.h | 44 ------- include/asm-ppc/termbits.h | 185 ------------------------------- include/asm-ppc/termios.h | 232 --------------------------------------- include/asm-ppc64/mman.h | 52 --------- include/asm-ppc64/termbits.h | 193 --------------------------------- include/asm-ppc64/termios.h | 235 ---------------------------------------- 9 files changed, 479 insertions(+), 941 deletions(-) diff --git a/include/asm-powerpc/mman.h b/include/asm-powerpc/mman.h new file mode 100644 --- /dev/null +++ b/include/asm-powerpc/mman.h @@ -0,0 +1,52 @@ +#ifndef __PPC_MMAN_H__ +#define __PPC_MMAN_H__ + +/* + * 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. + */ + +#define PROT_READ 0x1 /* page can be read */ +#define PROT_WRITE 0x2 /* page can be written */ +#define PROT_EXEC 0x4 /* page can be executed */ +#define PROT_SEM 0x8 /* page may be used for atomic ops */ +#define PROT_NONE 0x0 /* page can not be accessed */ +#define PROT_GROWSDOWN 0x01000000 /* mprotect flag: extend change to start of growsdown vma */ +#define PROT_GROWSUP 0x02000000 /* mprotect flag: extend change to end of growsup vma */ + +#define MAP_SHARED 0x01 /* Share changes */ +#define MAP_PRIVATE 0x02 /* Changes are private */ +#define MAP_TYPE 0x0f /* Mask for type of mapping */ +#define MAP_FIXED 0x10 /* Interpret addr exactly */ +#define MAP_ANONYMOUS 0x20 /* don't use a file */ +#define MAP_RENAME MAP_ANONYMOUS /* In SunOS terminology */ +#define MAP_NORESERVE 0x40 /* don't reserve swap pages */ +#define MAP_LOCKED 0x80 + +#define MAP_GROWSDOWN 0x0100 /* stack-like segment */ +#define MAP_DENYWRITE 0x0800 /* ETXTBSY */ +#define MAP_EXECUTABLE 0x1000 /* mark it as an executable */ + +#define MS_ASYNC 1 /* sync memory asynchronously */ +#define MS_INVALIDATE 2 /* invalidate the caches */ +#define MS_SYNC 4 /* synchronous memory sync */ + +#define MCL_CURRENT 0x2000 /* lock all currently mapped pages */ +#define MCL_FUTURE 0x4000 /* lock all additions to address space */ + +#define MAP_POPULATE 0x8000 /* populate (prefault) pagetables */ +#define MAP_NONBLOCK 0x10000 /* do not block on IO */ + +#define MADV_NORMAL 0x0 /* default page-in behavior */ +#define MADV_RANDOM 0x1 /* page-in minimum required */ +#define MADV_SEQUENTIAL 0x2 /* read-ahead aggressively */ +#define MADV_WILLNEED 0x3 /* pre-fault pages */ +#define MADV_DONTNEED 0x4 /* discard these pages */ + +/* compatibility flags */ +#define MAP_ANON MAP_ANONYMOUS +#define MAP_FILE 0 + +#endif /* __PPC_MMAN_H__ */ diff --git a/include/asm-powerpc/termbits.h b/include/asm-powerpc/termbits.h new file mode 100644 --- /dev/null +++ b/include/asm-powerpc/termbits.h @@ -0,0 +1,191 @@ +#ifndef _PPC_TERMBITS_H +#define _PPC_TERMBITS_H + +/* + * 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. + */ + +typedef unsigned char cc_t; +typedef unsigned int speed_t; +typedef unsigned int tcflag_t; + +/* + * termios type and macro definitions. Be careful about adding stuff + * to this file since it's used in GNU libc and there are strict rules + * concerning namespace pollution. + */ + +#define NCCS 19 +struct termios { + tcflag_t c_iflag; /* input mode flags */ + tcflag_t c_oflag; /* output mode flags */ + tcflag_t c_cflag; /* control mode flags */ + tcflag_t c_lflag; /* local mode flags */ + cc_t c_cc[NCCS]; /* control characters */ + cc_t c_line; /* line discipline (== c_cc[19]) */ + speed_t c_ispeed; /* input speed */ + speed_t c_ospeed; /* output speed */ +}; + +/* c_cc characters */ +#define VINTR 0 +#define VQUIT 1 +#define VERASE 2 +#define VKILL 3 +#define VEOF 4 +#define VMIN 5 +#define VEOL 6 +#define VTIME 7 +#define VEOL2 8 +#define VSWTC 9 +#define VWERASE 10 +#define VREPRINT 11 +#define VSUSP 12 +#define VSTART 13 +#define VSTOP 14 +#define VLNEXT 15 +#define VDISCARD 16 + +/* c_iflag bits */ +#define IGNBRK 0000001 +#define BRKINT 0000002 +#define IGNPAR 0000004 +#define PARMRK 0000010 +#define INPCK 0000020 +#define ISTRIP 0000040 +#define INLCR 0000100 +#define IGNCR 0000200 +#define ICRNL 0000400 +#define IXON 0001000 +#define IXOFF 0002000 +#define IXANY 0004000 +#define IUCLC 0010000 +#define IMAXBEL 0020000 +#define IUTF8 0040000 + +/* c_oflag bits */ +#define OPOST 0000001 +#define ONLCR 0000002 +#define OLCUC 0000004 + +#define OCRNL 0000010 +#define ONOCR 0000020 +#define ONLRET 0000040 + +#define OFILL 00000100 +#define OFDEL 00000200 +#define NLDLY 00001400 +#define NL0 00000000 +#define NL1 00000400 +#define NL2 00001000 +#define NL3 00001400 +#define TABDLY 00006000 +#define TAB0 00000000 +#define TAB1 00002000 +#define TAB2 00004000 +#define TAB3 00006000 +#define XTABS 00006000 /* required by POSIX to == TAB3 */ +#define CRDLY 00030000 +#define CR0 00000000 +#define CR1 00010000 +#define CR2 00020000 +#define CR3 00030000 +#define FFDLY 00040000 +#define FF0 00000000 +#define FF1 00040000 +#define BSDLY 00100000 +#define BS0 00000000 +#define BS1 00100000 +#define VTDLY 00200000 +#define VT0 00000000 +#define VT1 00200000 + +/* c_cflag bit meaning */ +#define CBAUD 0000377 +#define B0 0000000 /* hang up */ +#define B50 0000001 +#define B75 0000002 +#define B110 0000003 +#define B134 0000004 +#define B150 0000005 +#define B200 0000006 +#define B300 0000007 +#define B600 0000010 +#define B1200 0000011 +#define B1800 0000012 +#define B2400 0000013 +#define B4800 0000014 +#define B9600 0000015 +#define B19200 0000016 +#define B38400 0000017 +#define EXTA B19200 +#define EXTB B38400 +#define CBAUDEX 0000000 +#define B57600 00020 +#define B115200 00021 +#define B230400 00022 +#define B460800 00023 +#define B500000 00024 +#define B576000 00025 +#define B921600 00026 +#define B1000000 00027 +#define B1152000 00030 +#define B1500000 00031 +#define B2000000 00032 +#define B2500000 00033 +#define B3000000 00034 +#define B3500000 00035 +#define B4000000 00036 + +#define CSIZE 00001400 +#define CS5 00000000 +#define CS6 00000400 +#define CS7 00001000 +#define CS8 00001400 + +#define CSTOPB 00002000 +#define CREAD 00004000 +#define PARENB 00010000 +#define PARODD 00020000 +#define HUPCL 00040000 + +#define CLOCAL 00100000 +#define CRTSCTS 020000000000 /* flow control */ + +/* c_lflag bits */ +#define ISIG 0x00000080 +#define ICANON 0x00000100 +#define XCASE 0x00004000 +#define ECHO 0x00000008 +#define ECHOE 0x00000002 +#define ECHOK 0x00000004 +#define ECHONL 0x00000010 +#define NOFLSH 0x80000000 +#define TOSTOP 0x00400000 +#define ECHOCTL 0x00000040 +#define ECHOPRT 0x00000020 +#define ECHOKE 0x00000001 +#define FLUSHO 0x00800000 +#define PENDIN 0x20000000 +#define IEXTEN 0x00000400 + +/* Values for the ACTION argument to `tcflow'. */ +#define TCOOFF 0 +#define TCOON 1 +#define TCIOFF 2 +#define TCION 3 + +/* Values for the QUEUE_SELECTOR argument to `tcflush'. */ +#define TCIFLUSH 0 +#define TCOFLUSH 1 +#define TCIOFLUSH 2 + +/* Values for the OPTIONAL_ACTIONS argument to `tcsetattr'. */ +#define TCSANOW 0 +#define TCSADRAIN 1 +#define TCSAFLUSH 2 + +#endif /* _PPC_TERMBITS_H */ diff --git a/include/asm-powerpc/termios.h b/include/asm-powerpc/termios.h new file mode 100644 --- /dev/null +++ b/include/asm-powerpc/termios.h @@ -0,0 +1,236 @@ +#ifndef _PPC_TERMIOS_H +#define _PPC_TERMIOS_H + +/* + * Liberally adapted from alpha/termios.h. In particular, the c_cc[] + * fields have been reordered so that termio & termios share the + * common subset in the same order (for brain dead programs that don't + * know or care about the differences). + * + * 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 +#include + +struct sgttyb { + char sg_ispeed; + char sg_ospeed; + char sg_erase; + char sg_kill; + short sg_flags; +}; + +struct tchars { + char t_intrc; + char t_quitc; + char t_startc; + char t_stopc; + char t_eofc; + char t_brkc; +}; + +struct ltchars { + char t_suspc; + char t_dsuspc; + char t_rprntc; + char t_flushc; + char t_werasc; + char t_lnextc; +}; + +struct winsize { + unsigned short ws_row; + unsigned short ws_col; + unsigned short ws_xpixel; + unsigned short ws_ypixel; +}; + +#define NCC 10 +struct termio { + unsigned short c_iflag; /* input mode flags */ + unsigned short c_oflag; /* output mode flags */ + unsigned short c_cflag; /* control mode flags */ + unsigned short c_lflag; /* local mode flags */ + unsigned char c_line; /* line discipline */ + unsigned char c_cc[NCC]; /* control characters */ +}; + +/* c_cc characters */ +#define _VINTR 0 +#define _VQUIT 1 +#define _VERASE 2 +#define _VKILL 3 +#define _VEOF 4 +#define _VMIN 5 +#define _VEOL 6 +#define _VTIME 7 +#define _VEOL2 8 +#define _VSWTC 9 + +/* line disciplines */ +#define N_TTY 0 +#define N_SLIP 1 +#define N_MOUSE 2 +#define N_PPP 3 +#define N_STRIP 4 +#define N_AX25 5 +#define N_X25 6 /* X.25 async */ +#define N_6PACK 7 +#define N_MASC 8 /* Reserved for Mobitex module */ +#define N_R3964 9 /* Reserved for Simatic R3964 module */ +#define N_PROFIBUS_FDL 10 /* Reserved for Profibus */ +#define N_IRDA 11 /* Linux IrDa - http://www.cs.uit.no/~dagb/irda/irda.html */ +#define N_SMSBLOCK 12 /* SMS block mode - for talking to GSM data cards about SMS messages */ +#define N_HDLC 13 /* synchronous HDLC */ +#define N_SYNC_PPP 14 +#define N_HCI 15 /* Bluetooth HCI UART */ + +#ifdef __KERNEL__ +/* ^C ^\ del ^U ^D 1 0 0 0 0 ^W ^R ^Z ^Q ^S ^V ^U */ +#define INIT_C_CC "\003\034\177\025\004\001\000\000\000\000\027\022\032\021\023\026\025" +#endif + +#define FIOCLEX _IO('f', 1) +#define FIONCLEX _IO('f', 2) +#define FIOASYNC _IOW('f', 125, int) +#define FIONBIO _IOW('f', 126, int) +#define FIONREAD _IOR('f', 127, int) +#define TIOCINQ FIONREAD + +#define TIOCGETP _IOR('t', 8, struct sgttyb) +#define TIOCSETP _IOW('t', 9, struct sgttyb) +#define TIOCSETN _IOW('t', 10, struct sgttyb) /* TIOCSETP wo flush */ + +#define TIOCSETC _IOW('t', 17, struct tchars) +#define TIOCGETC _IOR('t', 18, struct tchars) +#define TCGETS _IOR('t', 19, struct termios) +#define TCSETS _IOW('t', 20, struct termios) +#define TCSETSW _IOW('t', 21, struct termios) +#define TCSETSF _IOW('t', 22, struct termios) + +#define TCGETA _IOR('t', 23, struct termio) +#define TCSETA _IOW('t', 24, struct termio) +#define TCSETAW _IOW('t', 25, struct termio) +#define TCSETAF _IOW('t', 28, struct termio) + +#define TCSBRK _IO('t', 29) +#define TCXONC _IO('t', 30) +#define TCFLSH _IO('t', 31) + +#define TIOCSWINSZ _IOW('t', 103, struct winsize) +#define TIOCGWINSZ _IOR('t', 104, struct winsize) +#define TIOCSTART _IO('t', 110) /* start output, like ^Q */ +#define TIOCSTOP _IO('t', 111) /* stop output, like ^S */ +#define TIOCOUTQ _IOR('t', 115, int) /* output queue size */ + +#define TIOCGLTC _IOR('t', 116, struct ltchars) +#define TIOCSLTC _IOW('t', 117, struct ltchars) +#define TIOCSPGRP _IOW('t', 118, int) +#define TIOCGPGRP _IOR('t', 119, int) + +#define TIOCEXCL 0x540C +#define TIOCNXCL 0x540D +#define TIOCSCTTY 0x540E + +#define TIOCSTI 0x5412 +#define TIOCMGET 0x5415 +#define TIOCMBIS 0x5416 +#define TIOCMBIC 0x5417 +#define TIOCMSET 0x5418 +#define TIOCGSOFTCAR 0x5419 +#define TIOCSSOFTCAR 0x541A +#define TIOCLINUX 0x541C +#define TIOCCONS 0x541D +#define TIOCGSERIAL 0x541E +#define TIOCSSERIAL 0x541F +#define TIOCPKT 0x5420 + +#define TIOCNOTTY 0x5422 +#define TIOCSETD 0x5423 +#define TIOCGETD 0x5424 +#define TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */ + +#define TIOCSERCONFIG 0x5453 +#define TIOCSERGWILD 0x5454 +#define TIOCSERSWILD 0x5455 +#define TIOCGLCKTRMIOS 0x5456 +#define TIOCSLCKTRMIOS 0x5457 +#define TIOCSERGSTRUCT 0x5458 /* For debugging only */ +#define TIOCSERGETLSR 0x5459 /* Get line status register */ +#define TIOCSERGETMULTI 0x545A /* Get multiport config */ +#define TIOCSERSETMULTI 0x545B /* Set multiport config */ + +#define TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */ +#define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */ + +/* Used for packet mode */ +#define TIOCPKT_DATA 0 +#define TIOCPKT_FLUSHREAD 1 +#define TIOCPKT_FLUSHWRITE 2 +#define TIOCPKT_STOP 4 +#define TIOCPKT_START 8 +#define TIOCPKT_NOSTOP 16 +#define TIOCPKT_DOSTOP 32 + +/* modem lines */ +#define TIOCM_LE 0x001 +#define TIOCM_DTR 0x002 +#define TIOCM_RTS 0x004 +#define TIOCM_ST 0x008 +#define TIOCM_SR 0x010 +#define TIOCM_CTS 0x020 +#define TIOCM_CAR 0x040 +#define TIOCM_RNG 0x080 +#define TIOCM_DSR 0x100 +#define TIOCM_CD TIOCM_CAR +#define TIOCM_RI TIOCM_RNG +#define TIOCM_OUT1 0x2000 +#define TIOCM_OUT2 0x4000 +#define TIOCM_LOOP 0x8000 + +/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */ +#define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ + +#ifdef __KERNEL__ + +/* + * Translate a "termio" structure into a "termios". Ugh. + */ +#define SET_LOW_TERMIOS_BITS(termios, termio, x) { \ + unsigned short __tmp; \ + get_user(__tmp,&(termio)->x); \ + (termios)->x = (0xffff0000 & (termios)->x) | __tmp; \ +} + +#define user_termio_to_kernel_termios(termios, termio) \ +({ \ + SET_LOW_TERMIOS_BITS(termios, termio, c_iflag); \ + SET_LOW_TERMIOS_BITS(termios, termio, c_oflag); \ + SET_LOW_TERMIOS_BITS(termios, termio, c_cflag); \ + SET_LOW_TERMIOS_BITS(termios, termio, c_lflag); \ + copy_from_user((termios)->c_cc, (termio)->c_cc, NCC); \ +}) + +/* + * Translate a "termios" structure into a "termio". Ugh. + */ +#define kernel_termios_to_user_termio(termio, termios) \ +({ \ + put_user((termios)->c_iflag, &(termio)->c_iflag); \ + put_user((termios)->c_oflag, &(termio)->c_oflag); \ + put_user((termios)->c_cflag, &(termio)->c_cflag); \ + put_user((termios)->c_lflag, &(termio)->c_lflag); \ + put_user((termios)->c_line, &(termio)->c_line); \ + copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \ +}) + +#define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios)) +#define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios)) + +#endif /* __KERNEL__ */ + +#endif /* _PPC_TERMIOS_H */ diff --git a/include/asm-ppc/mman.h b/include/asm-ppc/mman.h deleted file mode 100644 --- a/include/asm-ppc/mman.h +++ /dev/null @@ -1,44 +0,0 @@ -#ifndef __PPC_MMAN_H__ -#define __PPC_MMAN_H__ - -#define PROT_READ 0x1 /* page can be read */ -#define PROT_WRITE 0x2 /* page can be written */ -#define PROT_EXEC 0x4 /* page can be executed */ -#define PROT_SEM 0x8 /* page may be used for atomic ops */ -#define PROT_NONE 0x0 /* page can not be accessed */ -#define PROT_GROWSDOWN 0x01000000 /* mprotect flag: extend change to start of growsdown vma */ -#define PROT_GROWSUP 0x02000000 /* mprotect flag: extend change to end of growsup vma */ - -#define MAP_SHARED 0x01 /* Share changes */ -#define MAP_PRIVATE 0x02 /* Changes are private */ -#define MAP_TYPE 0x0f /* Mask for type of mapping */ -#define MAP_FIXED 0x10 /* Interpret addr exactly */ -#define MAP_ANONYMOUS 0x20 /* don't use a file */ -#define MAP_RENAME MAP_ANONYMOUS /* In SunOS terminology */ -#define MAP_NORESERVE 0x40 /* don't reserve swap pages */ -#define MAP_LOCKED 0x80 - -#define MAP_GROWSDOWN 0x0100 /* stack-like segment */ -#define MAP_DENYWRITE 0x0800 /* ETXTBSY */ -#define MAP_EXECUTABLE 0x1000 /* mark it as an executable */ -#define MAP_POPULATE 0x8000 /* populate (prefault) pagetables */ -#define MAP_NONBLOCK 0x10000 /* do not block on IO */ - -#define MS_ASYNC 1 /* sync memory asynchronously */ -#define MS_INVALIDATE 2 /* invalidate the caches */ -#define MS_SYNC 4 /* synchronous memory sync */ - -#define MCL_CURRENT 0x2000 /* lock all currently mapped pages */ -#define MCL_FUTURE 0x4000 /* lock all additions to address space */ - -#define MADV_NORMAL 0x0 /* default page-in behavior */ -#define MADV_RANDOM 0x1 /* page-in minimum required */ -#define MADV_SEQUENTIAL 0x2 /* read-ahead aggressively */ -#define MADV_WILLNEED 0x3 /* pre-fault pages */ -#define MADV_DONTNEED 0x4 /* discard these pages */ - -/* compatibility flags */ -#define MAP_ANON MAP_ANONYMOUS -#define MAP_FILE 0 - -#endif /* __PPC_MMAN_H__ */ diff --git a/include/asm-ppc/termbits.h b/include/asm-ppc/termbits.h deleted file mode 100644 --- a/include/asm-ppc/termbits.h +++ /dev/null @@ -1,185 +0,0 @@ -#ifndef _PPC_TERMBITS_H -#define _PPC_TERMBITS_H - -typedef unsigned char cc_t; -typedef unsigned int speed_t; -typedef unsigned int tcflag_t; - -/* - * termios type and macro definitions. Be careful about adding stuff - * to this file since it's used in GNU libc and there are strict rules - * concerning namespace pollution. - */ - -#define NCCS 19 -struct termios { - tcflag_t c_iflag; /* input mode flags */ - tcflag_t c_oflag; /* output mode flags */ - tcflag_t c_cflag; /* control mode flags */ - tcflag_t c_lflag; /* local mode flags */ - cc_t c_cc[NCCS]; /* control characters */ - cc_t c_line; /* line discipline (== c_cc[19]) */ - speed_t c_ispeed; /* input speed */ - speed_t c_ospeed; /* output speed */ -}; - -/* c_cc characters */ -#define VINTR 0 -#define VQUIT 1 -#define VERASE 2 -#define VKILL 3 -#define VEOF 4 -#define VMIN 5 -#define VEOL 6 -#define VTIME 7 -#define VEOL2 8 -#define VSWTC 9 - -#define VWERASE 10 -#define VREPRINT 11 -#define VSUSP 12 -#define VSTART 13 -#define VSTOP 14 -#define VLNEXT 15 -#define VDISCARD 16 - -/* c_iflag bits */ -#define IGNBRK 0000001 -#define BRKINT 0000002 -#define IGNPAR 0000004 -#define PARMRK 0000010 -#define INPCK 0000020 -#define ISTRIP 0000040 -#define INLCR 0000100 -#define IGNCR 0000200 -#define ICRNL 0000400 -#define IXON 0001000 -#define IXOFF 0002000 -#define IXANY 0004000 -#define IUCLC 0010000 -#define IMAXBEL 0020000 -#define IUTF8 0040000 - -/* c_oflag bits */ -#define OPOST 0000001 -#define ONLCR 0000002 -#define OLCUC 0000004 - -#define OCRNL 0000010 -#define ONOCR 0000020 -#define ONLRET 0000040 - -#define OFILL 00000100 -#define OFDEL 00000200 -#define NLDLY 00001400 -#define NL0 00000000 -#define NL1 00000400 -#define NL2 00001000 -#define NL3 00001400 -#define TABDLY 00006000 -#define TAB0 00000000 -#define TAB1 00002000 -#define TAB2 00004000 -#define TAB3 00006000 -#define XTABS 00006000 /* required by POSIX to == TAB3 */ -#define CRDLY 00030000 -#define CR0 00000000 -#define CR1 00010000 -#define CR2 00020000 -#define CR3 00030000 -#define FFDLY 00040000 -#define FF0 00000000 -#define FF1 00040000 -#define BSDLY 00100000 -#define BS0 00000000 -#define BS1 00100000 -#define VTDLY 00200000 -#define VT0 00000000 -#define VT1 00200000 - -/* c_cflag bit meaning */ -#define CBAUD 0000377 -#define B0 0000000 /* hang up */ -#define B50 0000001 -#define B75 0000002 -#define B110 0000003 -#define B134 0000004 -#define B150 0000005 -#define B200 0000006 -#define B300 0000007 -#define B600 0000010 -#define B1200 0000011 -#define B1800 0000012 -#define B2400 0000013 -#define B4800 0000014 -#define B9600 0000015 -#define B19200 0000016 -#define B38400 0000017 -#define EXTA B19200 -#define EXTB B38400 -#define CBAUDEX 0000000 -#define B57600 00020 -#define B115200 00021 -#define B230400 00022 -#define B460800 00023 -#define B500000 00024 -#define B576000 00025 -#define B921600 00026 -#define B1000000 00027 -#define B1152000 00030 -#define B1500000 00031 -#define B2000000 00032 -#define B2500000 00033 -#define B3000000 00034 -#define B3500000 00035 -#define B4000000 00036 - -#define CSIZE 00001400 -#define CS5 00000000 -#define CS6 00000400 -#define CS7 00001000 -#define CS8 00001400 - -#define CSTOPB 00002000 -#define CREAD 00004000 -#define PARENB 00010000 -#define PARODD 00020000 -#define HUPCL 00040000 - -#define CLOCAL 00100000 -#define CRTSCTS 020000000000 /* flow control */ - -/* c_lflag bits */ -#define ISIG 0x00000080 -#define ICANON 0x00000100 -#define XCASE 0x00004000 -#define ECHO 0x00000008 -#define ECHOE 0x00000002 -#define ECHOK 0x00000004 -#define ECHONL 0x00000010 -#define NOFLSH 0x80000000 -#define TOSTOP 0x00400000 -#define ECHOCTL 0x00000040 -#define ECHOPRT 0x00000020 -#define ECHOKE 0x00000001 -#define FLUSHO 0x00800000 -#define PENDIN 0x20000000 -#define IEXTEN 0x00000400 - -/* Values for the ACTION argument to `tcflow'. */ -#define TCOOFF 0 -#define TCOON 1 -#define TCIOFF 2 -#define TCION 3 - -/* Values for the QUEUE_SELECTOR argument to `tcflush'. */ -#define TCIFLUSH 0 -#define TCOFLUSH 1 -#define TCIOFLUSH 2 - -/* Values for the OPTIONAL_ACTIONS argument to `tcsetattr'. */ -#define TCSANOW 0 -#define TCSADRAIN 1 -#define TCSAFLUSH 2 - -#endif /* _PPC_TERMBITS_H */ diff --git a/include/asm-ppc/termios.h b/include/asm-ppc/termios.h deleted file mode 100644 --- a/include/asm-ppc/termios.h +++ /dev/null @@ -1,232 +0,0 @@ -#ifndef _PPC_TERMIOS_H -#define _PPC_TERMIOS_H - -/* - * Liberally adapted from alpha/termios.h. In particular, the c_cc[] - * fields have been reordered so that termio & termios share the - * common subset in the same order (for brain dead programs that don't - * know or care about the differences). - */ - -#include -#include - -struct sgttyb { - char sg_ispeed; - char sg_ospeed; - char sg_erase; - char sg_kill; - short sg_flags; -}; - -struct tchars { - char t_intrc; - char t_quitc; - char t_startc; - char t_stopc; - char t_eofc; - char t_brkc; -}; - -struct ltchars { - char t_suspc; - char t_dsuspc; - char t_rprntc; - char t_flushc; - char t_werasc; - char t_lnextc; -}; - -#define FIOCLEX _IO('f', 1) -#define FIONCLEX _IO('f', 2) -#define FIOASYNC _IOW('f', 125, int) -#define FIONBIO _IOW('f', 126, int) -#define FIONREAD _IOR('f', 127, int) -#define TIOCINQ FIONREAD -#define FIOQSIZE _IOR('f', 128, loff_t) - -#define TIOCGETP _IOR('t', 8, struct sgttyb) -#define TIOCSETP _IOW('t', 9, struct sgttyb) -#define TIOCSETN _IOW('t', 10, struct sgttyb) /* TIOCSETP wo flush */ - -#define TIOCSETC _IOW('t', 17, struct tchars) -#define TIOCGETC _IOR('t', 18, struct tchars) -#define TCGETS _IOR('t', 19, struct termios) -#define TCSETS _IOW('t', 20, struct termios) -#define TCSETSW _IOW('t', 21, struct termios) -#define TCSETSF _IOW('t', 22, struct termios) - -#define TCGETA _IOR('t', 23, struct termio) -#define TCSETA _IOW('t', 24, struct termio) -#define TCSETAW _IOW('t', 25, struct termio) -#define TCSETAF _IOW('t', 28, struct termio) - -#define TCSBRK _IO('t', 29) -#define TCXONC _IO('t', 30) -#define TCFLSH _IO('t', 31) - -#define TIOCSWINSZ _IOW('t', 103, struct winsize) -#define TIOCGWINSZ _IOR('t', 104, struct winsize) -#define TIOCSTART _IO('t', 110) /* start output, like ^Q */ -#define TIOCSTOP _IO('t', 111) /* stop output, like ^S */ -#define TIOCOUTQ _IOR('t', 115, int) /* output queue size */ - -#define TIOCGLTC _IOR('t', 116, struct ltchars) -#define TIOCSLTC _IOW('t', 117, struct ltchars) -#define TIOCSPGRP _IOW('t', 118, int) -#define TIOCGPGRP _IOR('t', 119, int) - -#define TIOCEXCL 0x540C -#define TIOCNXCL 0x540D -#define TIOCSCTTY 0x540E - -#define TIOCSTI 0x5412 -#define TIOCMGET 0x5415 -#define TIOCMBIS 0x5416 -#define TIOCMBIC 0x5417 -#define TIOCMSET 0x5418 -#define TIOCGSOFTCAR 0x5419 -#define TIOCSSOFTCAR 0x541A -#define TIOCLINUX 0x541C -#define TIOCCONS 0x541D -#define TIOCGSERIAL 0x541E -#define TIOCSSERIAL 0x541F -#define TIOCPKT 0x5420 - -#define TIOCNOTTY 0x5422 -#define TIOCSETD 0x5423 -#define TIOCGETD 0x5424 -#define TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */ - -#define TIOCSERCONFIG 0x5453 -#define TIOCSERGWILD 0x5454 -#define TIOCSERSWILD 0x5455 -#define TIOCGLCKTRMIOS 0x5456 -#define TIOCSLCKTRMIOS 0x5457 -#define TIOCSERGSTRUCT 0x5458 /* For debugging only */ -#define TIOCSERGETLSR 0x5459 /* Get line status register */ -#define TIOCSERGETMULTI 0x545A /* Get multiport config */ -#define TIOCSERSETMULTI 0x545B /* Set multiport config */ - -#define TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */ -#define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */ - -/* Used for packet mode */ -#define TIOCPKT_DATA 0 -#define TIOCPKT_FLUSHREAD 1 -#define TIOCPKT_FLUSHWRITE 2 -#define TIOCPKT_STOP 4 -#define TIOCPKT_START 8 -#define TIOCPKT_NOSTOP 16 -#define TIOCPKT_DOSTOP 32 - -struct winsize { - unsigned short ws_row; - unsigned short ws_col; - unsigned short ws_xpixel; - unsigned short ws_ypixel; -}; - -#define NCC 10 -struct termio { - unsigned short c_iflag; /* input mode flags */ - unsigned short c_oflag; /* output mode flags */ - unsigned short c_cflag; /* control mode flags */ - unsigned short c_lflag; /* local mode flags */ - unsigned char c_line; /* line discipline */ - unsigned char c_cc[NCC]; /* control characters */ -}; - -/* c_cc characters */ -#define _VINTR 0 -#define _VQUIT 1 -#define _VERASE 2 -#define _VKILL 3 -#define _VEOF 4 -#define _VMIN 5 -#define _VEOL 6 -#define _VTIME 7 -#define _VEOL2 8 -#define _VSWTC 9 - -#ifdef __KERNEL__ -/* ^C ^\ del ^U ^D 1 0 0 0 0 ^W ^R ^Z ^Q ^S ^V ^U */ -#define INIT_C_CC "\003\034\177\025\004\001\000\000\000\000\027\022\032\021\023\026\025" -#endif /* __KERNEL__ */ - -/* modem lines */ -#define TIOCM_LE 0x001 -#define TIOCM_DTR 0x002 -#define TIOCM_RTS 0x004 -#define TIOCM_ST 0x008 -#define TIOCM_SR 0x010 -#define TIOCM_CTS 0x020 -#define TIOCM_CAR 0x040 -#define TIOCM_RNG 0x080 -#define TIOCM_DSR 0x100 -#define TIOCM_CD TIOCM_CAR -#define TIOCM_RI TIOCM_RNG -#define TIOCM_OUT1 0x2000 -#define TIOCM_OUT2 0x4000 -#define TIOCM_LOOP 0x8000 - -/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */ -#define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ - -/* line disciplines */ -#define N_TTY 0 -#define N_SLIP 1 -#define N_MOUSE 2 -#define N_PPP 3 -#define N_STRIP 4 -#define N_AX25 5 -#define N_X25 6 /* X.25 async */ -#define N_6PACK 7 -#define N_MASC 8 /* Reserved for Mobitex module */ -#define N_R3964 9 /* Reserved for Simatic R3964 module */ -#define N_PROFIBUS_FDL 10 /* Reserved for Profibus */ -#define N_IRDA 11 /* Linux IrDa - http://irda.sourceforge.net/ */ -#define N_SMSBLOCK 12 /* SMS block mode - for talking to GSM data cards about SMS messages */ -#define N_HDLC 13 /* synchronous HDLC */ -#define N_SYNC_PPP 14 -#define N_HCI 15 /* Bluetooth HCI UART */ - -#ifdef __KERNEL__ - -/* - * Translate a "termio" structure into a "termios". Ugh. - */ -#define SET_LOW_TERMIOS_BITS(termios, termio, x) { \ - unsigned short __tmp; \ - get_user(__tmp,&(termio)->x); \ - (termios)->x = (0xffff0000 & (termios)->x) | __tmp; \ -} - -#define user_termio_to_kernel_termios(termios, termio) \ -({ \ - SET_LOW_TERMIOS_BITS(termios, termio, c_iflag); \ - SET_LOW_TERMIOS_BITS(termios, termio, c_oflag); \ - SET_LOW_TERMIOS_BITS(termios, termio, c_cflag); \ - SET_LOW_TERMIOS_BITS(termios, termio, c_lflag); \ - copy_from_user((termios)->c_cc, (termio)->c_cc, NCC); \ -}) - -/* - * Translate a "termios" structure into a "termio". Ugh. - */ -#define kernel_termios_to_user_termio(termio, termios) \ -({ \ - put_user((termios)->c_iflag, &(termio)->c_iflag); \ - put_user((termios)->c_oflag, &(termio)->c_oflag); \ - put_user((termios)->c_cflag, &(termio)->c_cflag); \ - put_user((termios)->c_lflag, &(termio)->c_lflag); \ - put_user((termios)->c_line, &(termio)->c_line); \ - copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \ -}) - -#define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios)) -#define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios)) - -#endif /* __KERNEL__ */ - -#endif /* _PPC_TERMIOS_H */ diff --git a/include/asm-ppc64/mman.h b/include/asm-ppc64/mman.h deleted file mode 100644 --- a/include/asm-ppc64/mman.h +++ /dev/null @@ -1,52 +0,0 @@ -#ifndef __PPC64_MMAN_H__ -#define __PPC64_MMAN_H__ - -/* - * 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. - */ - -#define PROT_READ 0x1 /* page can be read */ -#define PROT_WRITE 0x2 /* page can be written */ -#define PROT_EXEC 0x4 /* page can be executed */ -#define PROT_SEM 0x8 /* page may be used for atomic ops */ -#define PROT_NONE 0x0 /* page can not be accessed */ -#define PROT_GROWSDOWN 0x01000000 /* mprotect flag: extend change to start of growsdown vma */ -#define PROT_GROWSUP 0x02000000 /* mprotect flag: extend change to end of growsup vma */ - -#define MAP_SHARED 0x01 /* Share changes */ -#define MAP_PRIVATE 0x02 /* Changes are private */ -#define MAP_TYPE 0x0f /* Mask for type of mapping */ -#define MAP_FIXED 0x10 /* Interpret addr exactly */ -#define MAP_ANONYMOUS 0x20 /* don't use a file */ -#define MAP_RENAME MAP_ANONYMOUS /* In SunOS terminology */ -#define MAP_NORESERVE 0x40 /* don't reserve swap pages */ -#define MAP_LOCKED 0x80 - -#define MAP_GROWSDOWN 0x0100 /* stack-like segment */ -#define MAP_DENYWRITE 0x0800 /* ETXTBSY */ -#define MAP_EXECUTABLE 0x1000 /* mark it as an executable */ - -#define MS_ASYNC 1 /* sync memory asynchronously */ -#define MS_INVALIDATE 2 /* invalidate the caches */ -#define MS_SYNC 4 /* synchronous memory sync */ - -#define MCL_CURRENT 0x2000 /* lock all currently mapped pages */ -#define MCL_FUTURE 0x4000 /* lock all additions to address space */ - -#define MAP_POPULATE 0x8000 /* populate (prefault) pagetables */ -#define MAP_NONBLOCK 0x10000 /* do not block on IO */ - -#define MADV_NORMAL 0x0 /* default page-in behavior */ -#define MADV_RANDOM 0x1 /* page-in minimum required */ -#define MADV_SEQUENTIAL 0x2 /* read-ahead aggressively */ -#define MADV_WILLNEED 0x3 /* pre-fault pages */ -#define MADV_DONTNEED 0x4 /* discard these pages */ - -/* compatibility flags */ -#define MAP_ANON MAP_ANONYMOUS -#define MAP_FILE 0 - -#endif /* __PPC64_MMAN_H__ */ diff --git a/include/asm-ppc64/termbits.h b/include/asm-ppc64/termbits.h deleted file mode 100644 --- a/include/asm-ppc64/termbits.h +++ /dev/null @@ -1,193 +0,0 @@ -#ifndef _PPC64_TERMBITS_H -#define _PPC64_TERMBITS_H - -/* - * 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 - -typedef unsigned char cc_t; -typedef unsigned int speed_t; -typedef unsigned int tcflag_t; - -/* - * termios type and macro definitions. Be careful about adding stuff - * to this file since it's used in GNU libc and there are strict rules - * concerning namespace pollution. - */ - -#define NCCS 19 -struct termios { - tcflag_t c_iflag; /* input mode flags */ - tcflag_t c_oflag; /* output mode flags */ - tcflag_t c_cflag; /* control mode flags */ - tcflag_t c_lflag; /* local mode flags */ - cc_t c_cc[NCCS]; /* control characters */ - cc_t c_line; /* line discipline (== c_cc[19]) */ - speed_t c_ispeed; /* input speed */ - speed_t c_ospeed; /* output speed */ -}; - -/* c_cc characters */ -#define VINTR 0 -#define VQUIT 1 -#define VERASE 2 -#define VKILL 3 -#define VEOF 4 -#define VMIN 5 -#define VEOL 6 -#define VTIME 7 -#define VEOL2 8 -#define VSWTC 9 -#define VWERASE 10 -#define VREPRINT 11 -#define VSUSP 12 -#define VSTART 13 -#define VSTOP 14 -#define VLNEXT 15 -#define VDISCARD 16 - -/* c_iflag bits */ -#define IGNBRK 0000001 -#define BRKINT 0000002 -#define IGNPAR 0000004 -#define PARMRK 0000010 -#define INPCK 0000020 -#define ISTRIP 0000040 -#define INLCR 0000100 -#define IGNCR 0000200 -#define ICRNL 0000400 -#define IXON 0001000 -#define IXOFF 0002000 -#define IXANY 0004000 -#define IUCLC 0010000 -#define IMAXBEL 0020000 -#define IUTF8 0040000 - -/* c_oflag bits */ -#define OPOST 0000001 -#define ONLCR 0000002 -#define OLCUC 0000004 - -#define OCRNL 0000010 -#define ONOCR 0000020 -#define ONLRET 0000040 - -#define OFILL 00000100 -#define OFDEL 00000200 -#define NLDLY 00001400 -#define NL0 00000000 -#define NL1 00000400 -#define NL2 00001000 -#define NL3 00001400 -#define TABDLY 00006000 -#define TAB0 00000000 -#define TAB1 00002000 -#define TAB2 00004000 -#define TAB3 00006000 -#define XTABS 00006000 /* required by POSIX to == TAB3 */ -#define CRDLY 00030000 -#define CR0 00000000 -#define CR1 00010000 -#define CR2 00020000 -#define CR3 00030000 -#define FFDLY 00040000 -#define FF0 00000000 -#define FF1 00040000 -#define BSDLY 00100000 -#define BS0 00000000 -#define BS1 00100000 -#define VTDLY 00200000 -#define VT0 00000000 -#define VT1 00200000 - -/* c_cflag bit meaning */ -#define CBAUD 0000377 -#define B0 0000000 /* hang up */ -#define B50 0000001 -#define B75 0000002 -#define B110 0000003 -#define B134 0000004 -#define B150 0000005 -#define B200 0000006 -#define B300 0000007 -#define B600 0000010 -#define B1200 0000011 -#define B1800 0000012 -#define B2400 0000013 -#define B4800 0000014 -#define B9600 0000015 -#define B19200 0000016 -#define B38400 0000017 -#define EXTA B19200 -#define EXTB B38400 -#define CBAUDEX 0000000 -#define B57600 00020 -#define B115200 00021 -#define B230400 00022 -#define B460800 00023 -#define B500000 00024 -#define B576000 00025 -#define B921600 00026 -#define B1000000 00027 -#define B1152000 00030 -#define B1500000 00031 -#define B2000000 00032 -#define B2500000 00033 -#define B3000000 00034 -#define B3500000 00035 -#define B4000000 00036 - -#define CSIZE 00001400 -#define CS5 00000000 -#define CS6 00000400 -#define CS7 00001000 -#define CS8 00001400 - -#define CSTOPB 00002000 -#define CREAD 00004000 -#define PARENB 00010000 -#define PARODD 00020000 -#define HUPCL 00040000 - -#define CLOCAL 00100000 -#define CRTSCTS 020000000000 /* flow control */ - -/* c_lflag bits */ -#define ISIG 0x00000080 -#define ICANON 0x00000100 -#define XCASE 0x00004000 -#define ECHO 0x00000008 -#define ECHOE 0x00000002 -#define ECHOK 0x00000004 -#define ECHONL 0x00000010 -#define NOFLSH 0x80000000 -#define TOSTOP 0x00400000 -#define ECHOCTL 0x00000040 -#define ECHOPRT 0x00000020 -#define ECHOKE 0x00000001 -#define FLUSHO 0x00800000 -#define PENDIN 0x20000000 -#define IEXTEN 0x00000400 - -/* Values for the ACTION argument to `tcflow'. */ -#define TCOOFF 0 -#define TCOON 1 -#define TCIOFF 2 -#define TCION 3 - -/* Values for the QUEUE_SELECTOR argument to `tcflush'. */ -#define TCIFLUSH 0 -#define TCOFLUSH 1 -#define TCIOFLUSH 2 - -/* Values for the OPTIONAL_ACTIONS argument to `tcsetattr'. */ -#define TCSANOW 0 -#define TCSADRAIN 1 -#define TCSAFLUSH 2 - -#endif /* _PPC64_TERMBITS_H */ diff --git a/include/asm-ppc64/termios.h b/include/asm-ppc64/termios.h deleted file mode 100644 --- a/include/asm-ppc64/termios.h +++ /dev/null @@ -1,235 +0,0 @@ -#ifndef _PPC64_TERMIOS_H -#define _PPC64_TERMIOS_H - -/* - * Liberally adapted from alpha/termios.h. In particular, the c_cc[] - * fields have been reordered so that termio & termios share the - * common subset in the same order (for brain dead programs that don't - * know or care about the differences). - * - * 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 -#include - -struct sgttyb { - char sg_ispeed; - char sg_ospeed; - char sg_erase; - char sg_kill; - short sg_flags; -}; - -struct tchars { - char t_intrc; - char t_quitc; - char t_startc; - char t_stopc; - char t_eofc; - char t_brkc; -}; - -struct ltchars { - char t_suspc; - char t_dsuspc; - char t_rprntc; - char t_flushc; - char t_werasc; - char t_lnextc; -}; - -struct winsize { - unsigned short ws_row; - unsigned short ws_col; - unsigned short ws_xpixel; - unsigned short ws_ypixel; -}; - -#define NCC 10 -struct termio { - unsigned short c_iflag; /* input mode flags */ - unsigned short c_oflag; /* output mode flags */ - unsigned short c_cflag; /* control mode flags */ - unsigned short c_lflag; /* local mode flags */ - unsigned char c_line; /* line discipline */ - unsigned char c_cc[NCC]; /* control characters */ -}; - -/* c_cc characters */ -#define _VINTR 0 -#define _VQUIT 1 -#define _VERASE 2 -#define _VKILL 3 -#define _VEOF 4 -#define _VMIN 5 -#define _VEOL 6 -#define _VTIME 7 -#define _VEOL2 8 -#define _VSWTC 9 - -/* line disciplines */ -#define N_TTY 0 -#define N_SLIP 1 -#define N_MOUSE 2 -#define N_PPP 3 -#define N_STRIP 4 -#define N_AX25 5 -#define N_X25 6 /* X.25 async */ -#define N_6PACK 7 -#define N_MASC 8 /* Reserved for Mobitex module */ -#define N_R3964 9 /* Reserved for Simatic R3964 module */ -#define N_PROFIBUS_FDL 10 /* Reserved for Profibus */ -#define N_IRDA 11 /* Linux IrDa - http://www.cs.uit.no/~dagb/irda/irda.html */ -#define N_SMSBLOCK 12 /* SMS block mode - for talking to GSM data cards about SMS messages */ -#define N_HDLC 13 /* synchronous HDLC */ -#define N_SYNC_PPP 14 - -#ifdef __KERNEL__ -/* ^C ^\ del ^U ^D 1 0 0 0 0 ^W ^R ^Z ^Q ^S ^V ^U */ -#define INIT_C_CC "\003\034\177\025\004\001\000\000\000\000\027\022\032\021\023\026\025" -#endif - -#define FIOCLEX _IO('f', 1) -#define FIONCLEX _IO('f', 2) -#define FIOASYNC _IOW('f', 125, int) -#define FIONBIO _IOW('f', 126, int) -#define FIONREAD _IOR('f', 127, int) -#define TIOCINQ FIONREAD - -#define TIOCGETP _IOR('t', 8, struct sgttyb) -#define TIOCSETP _IOW('t', 9, struct sgttyb) -#define TIOCSETN _IOW('t', 10, struct sgttyb) /* TIOCSETP wo flush */ - -#define TIOCSETC _IOW('t', 17, struct tchars) -#define TIOCGETC _IOR('t', 18, struct tchars) -#define TCGETS _IOR('t', 19, struct termios) -#define TCSETS _IOW('t', 20, struct termios) -#define TCSETSW _IOW('t', 21, struct termios) -#define TCSETSF _IOW('t', 22, struct termios) - -#define TCGETA _IOR('t', 23, struct termio) -#define TCSETA _IOW('t', 24, struct termio) -#define TCSETAW _IOW('t', 25, struct termio) -#define TCSETAF _IOW('t', 28, struct termio) - -#define TCSBRK _IO('t', 29) -#define TCXONC _IO('t', 30) -#define TCFLSH _IO('t', 31) - -#define TIOCSWINSZ _IOW('t', 103, struct winsize) -#define TIOCGWINSZ _IOR('t', 104, struct winsize) -#define TIOCSTART _IO('t', 110) /* start output, like ^Q */ -#define TIOCSTOP _IO('t', 111) /* stop output, like ^S */ -#define TIOCOUTQ _IOR('t', 115, int) /* output queue size */ - -#define TIOCGLTC _IOR('t', 116, struct ltchars) -#define TIOCSLTC _IOW('t', 117, struct ltchars) -#define TIOCSPGRP _IOW('t', 118, int) -#define TIOCGPGRP _IOR('t', 119, int) - -#define TIOCEXCL 0x540C -#define TIOCNXCL 0x540D -#define TIOCSCTTY 0x540E - -#define TIOCSTI 0x5412 -#define TIOCMGET 0x5415 -#define TIOCMBIS 0x5416 -#define TIOCMBIC 0x5417 -#define TIOCMSET 0x5418 -#define TIOCGSOFTCAR 0x5419 -#define TIOCSSOFTCAR 0x541A -#define TIOCLINUX 0x541C -#define TIOCCONS 0x541D -#define TIOCGSERIAL 0x541E -#define TIOCSSERIAL 0x541F -#define TIOCPKT 0x5420 - -#define TIOCNOTTY 0x5422 -#define TIOCSETD 0x5423 -#define TIOCGETD 0x5424 -#define TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */ - -#define TIOCSERCONFIG 0x5453 -#define TIOCSERGWILD 0x5454 -#define TIOCSERSWILD 0x5455 -#define TIOCGLCKTRMIOS 0x5456 -#define TIOCSLCKTRMIOS 0x5457 -#define TIOCSERGSTRUCT 0x5458 /* For debugging only */ -#define TIOCSERGETLSR 0x5459 /* Get line status register */ -#define TIOCSERGETMULTI 0x545A /* Get multiport config */ -#define TIOCSERSETMULTI 0x545B /* Set multiport config */ - -#define TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */ -#define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */ - -/* Used for packet mode */ -#define TIOCPKT_DATA 0 -#define TIOCPKT_FLUSHREAD 1 -#define TIOCPKT_FLUSHWRITE 2 -#define TIOCPKT_STOP 4 -#define TIOCPKT_START 8 -#define TIOCPKT_NOSTOP 16 -#define TIOCPKT_DOSTOP 32 - -/* modem lines */ -#define TIOCM_LE 0x001 -#define TIOCM_DTR 0x002 -#define TIOCM_RTS 0x004 -#define TIOCM_ST 0x008 -#define TIOCM_SR 0x010 -#define TIOCM_CTS 0x020 -#define TIOCM_CAR 0x040 -#define TIOCM_RNG 0x080 -#define TIOCM_DSR 0x100 -#define TIOCM_CD TIOCM_CAR -#define TIOCM_RI TIOCM_RNG -#define TIOCM_OUT1 0x2000 -#define TIOCM_OUT2 0x4000 -#define TIOCM_LOOP 0x8000 - -/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */ -#define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ - -#ifdef __KERNEL__ - -/* - * Translate a "termio" structure into a "termios". Ugh. - */ -#define SET_LOW_TERMIOS_BITS(termios, termio, x) { \ - unsigned short __tmp; \ - get_user(__tmp,&(termio)->x); \ - (termios)->x = (0xffff0000 & (termios)->x) | __tmp; \ -} - -#define user_termio_to_kernel_termios(termios, termio) \ -({ \ - SET_LOW_TERMIOS_BITS(termios, termio, c_iflag); \ - SET_LOW_TERMIOS_BITS(termios, termio, c_oflag); \ - SET_LOW_TERMIOS_BITS(termios, termio, c_cflag); \ - SET_LOW_TERMIOS_BITS(termios, termio, c_lflag); \ - copy_from_user((termios)->c_cc, (termio)->c_cc, NCC); \ -}) - -/* - * Translate a "termios" structure into a "termio". Ugh. - */ -#define kernel_termios_to_user_termio(termio, termios) \ -({ \ - put_user((termios)->c_iflag, &(termio)->c_iflag); \ - put_user((termios)->c_oflag, &(termio)->c_oflag); \ - put_user((termios)->c_cflag, &(termio)->c_cflag); \ - put_user((termios)->c_lflag, &(termio)->c_lflag); \ - put_user((termios)->c_line, &(termio)->c_line); \ - copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \ -}) - -#define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios)) -#define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios)) - -#endif /* __KERNEL__ */ - -#endif /* _PPC64_TERMIOS_H */ From jimix at watson.ibm.com Thu Aug 25 22:56:12 2005 From: jimix at watson.ibm.com (Jimi Xenidis) Date: Thu, 25 Aug 2005 08:56:12 -0400 Subject: [News] Cell documents _now_ available on the web Message-ID: <17165.49132.487161.174641@kitch0.watson.ibm.com> ya know, thats the thing sony is putting in playstation 3s http://www-128.ibm.com/developerworks/power/cell/ -JX -- "I got an idea, an idea so smart my head would explode if I even began to know what I was talking about." -- Peter Griffin (Family Guy) From arnd at arndb.de Fri Aug 26 00:49:32 2005 From: arnd at arndb.de (Arnd Bergmann) Date: Thu, 25 Aug 2005 16:49:32 +0200 Subject: [News] Cell documents _now_ available on the web In-Reply-To: <17165.49132.487161.174641@kitch0.watson.ibm.com> References: <17165.49132.487161.174641@kitch0.watson.ibm.com> Message-ID: <200508251649.32956.arnd@arndb.de> On Dunnersdag 25 August 2005 14:56, Jimi Xenidis wrote: > > ya know, thats the thing sony is putting in playstation 3s > > http://www-128.ibm.com/developerworks/power/cell/ There is also a site to get them without the registration at http://cell.scei.co.jp/e_download.html . Now that the official name for the architecture has become CBEA (Cell Broadband Engine Architecture), I wonder if we should rename the stuff in the kernel from BPA (which it has been called so far) to either "CBEA" or simply "cell". Arnd <>< From arnd at arndb.de Fri Aug 26 00:49:24 2005 From: arnd at arndb.de (Arnd Bergmann) Date: Thu, 25 Aug 2005 16:49:24 +0200 Subject: [PATCH] export htab value for kexec on non-lpar - cleaned up patch In-Reply-To: <20050825044206.GA2079@in.ibm.com> References: <20050823080423.GA2380@in.ibm.com> <20050824190652.GO1012@otto> <20050825044206.GA2079@in.ibm.com> Message-ID: <200508251649.26156.arnd@arndb.de> On Dunnersdag 25 August 2005 06:42, R Sharada wrote: > Nathan, > Thanks for the comments. It makes sense to make then static and more > appropriately named. > Have done the same and re-posting the patch with those minor changes > > +static void __init export_htab_value(void) > +{ > + struct device_node *node; > + > + if (systemcfg->platform == PLATFORM_PSERIES_LPAR) > + return; > + > + node = of_find_node_by_path("/chosen"); > + if (!node) > + return; > + htab_base_prop.name = "htab_base"; > + htab_base_prop.length = sizeof(unsigned long); > + htab_base = __pa(htab_address); > + htab_base_prop.value = &htab_base; > + prom_add_property(node, &htab_base_prop); > + htab_size_prop.name = "htab_size"; > + htab_size_prop.length = sizeof(unsigned long); > + htab_size = (htab_hash_mask + 1) * HASH_GROUP_SIZE; > + htab_size_prop.value = &htab_size; > + prom_add_property(node, &htab_size_prop); > + of_node_put(node); > +} Actually I had been thinking of something more along the lines of static void __init export_htab_value(void) +{ + static unsigned long htab_base; + static struct property htab_base_prop = { + .name = "htab_base", + .length = sizeof(unsigned long), + .value = &htab_base, + }; + + static unsigned long htab_size; + static struct property htab_size_prop = { + .name = "htab_size", + .length = sizeof(unsigned long), + .value = &htab_size, + }; + + struct device_node *node; + if (systemcfg->platform == PLATFORM_PSERIES_LPAR) + return; + + node = of_find_node_by_path("/chosen"); + if (!node) + return; + + htab_base = __pa(htab_address); + prom_add_property(node, &htab_base_prop); + htab_size = (htab_hash_mask + 1) * HASH_GROUP_SIZE; + prom_add_property(node, &htab_size_prop); + + of_node_put(node); +} I find this easier to read and it should also result in smaller code. Arnd <>< From kumar.gala at freescale.com Fri Aug 26 01:27:32 2005 From: kumar.gala at freescale.com (Kumar Gala) Date: Thu, 25 Aug 2005 10:27:32 -0500 Subject: [News] Cell documents _now_ available on the web In-Reply-To: <200508251649.32956.arnd@arndb.de> References: <200508251649.32956.arnd@arndb.de> Message-ID: On Aug 25, 2005, at 9:49 AM, Arnd Bergmann wrote: > On Dunnersdag 25 August 2005 14:56, Jimi Xenidis wrote: > >> >> ya know, thats the thing sony is putting in playstation 3s >> >> http://www-128.ibm.com/developerworks/power/cell/ >> > > There is also a site to get them without the registration > at http://cell.scei.co.jp/e_download.html . > > Now that the official name for the architecture has become > CBEA (Cell Broadband Engine Architecture), I wonder if we > should rename the stuff in the kernel from BPA (which it > has been called so far) to either "CBEA" or simply "cell". I would vote for simply "cell" since that seems less likely to change due to marketers :) - kumar From segher at kernel.crashing.org Fri Aug 26 01:42:07 2005 From: segher at kernel.crashing.org (Segher Boessenkool) Date: Thu, 25 Aug 2005 17:42:07 +0200 Subject: [RFC/PATCH] Set up PCI tree from OF on ppc64 In-Reply-To: <17165.800.617053.891578@cargo.ozlabs.ibm.com> References: <17165.800.617053.891578@cargo.ozlabs.ibm.com> Message-ID: <640514b313694c6083cacd9863058a32@kernel.crashing.org> > There are a couple of reasons why this is needed. First, on systems > with a hypervisor, there is a PCI-PCI bridge per slot under the PCI > host bridges. These PCI-PCI bridges have special isolation features > for virtualization. We can't write to their config space, and we are > not supposed to be reading their config space either. Then the hypervisor should just hide these bridges from us (or fake all accesses to it). > Secondly, on powermacs, the interrupt controller is in a PCI device > that may be behind a PCI-PCI bridge. If we happened to take an > interrupt just at the point when the device or a bridge on the path to > it was disabled for probing, we would crash when we try to access the > interrupt controller. Why does it have to be disabled for probing? The kernel really shouldn't change bus numbers and address ranges and BARs if the firmware already has done this. If the firmware has disabled a device (or bridge, or just some BARs), it probably has a good reason to do so. On the other hand, there might be a lot of broken firmwares out there, of course -- but not nearly as much as on x86, so we don't need all those fixups they use. So, in short, I'm fine with your patch, as it will solve some problems, but I don't think it is the best way to go. I didn't review or try your actual patch yet; will try to do that soon, though. Segher p.s. Here is a patch fragment I use to work around / fix PCI probing brokenness: @@ -233,11 +233,11 @@ static int __init pcibios_init(void) #ifndef CONFIG_PPC_ISERIES if (pci_probe_only) pcibios_claim_of_setup(); - else - /* FIXME: `else' will be removed when - pci_assign_unassigned_resources() is able to work - correctly with [partially] allocated PCI tree. */ - pci_assign_unassigned_resources(); #endif /* !CONFIG_PPC_ISERIES */ /* Call machine dependent final fixup */ From matthew at wil.cx Fri Aug 26 02:09:51 2005 From: matthew at wil.cx (Matthew Wilcox) Date: Thu, 25 Aug 2005 17:09:51 +0100 Subject: [RFC/PATCH] Set up PCI tree from OF on ppc64 In-Reply-To: <640514b313694c6083cacd9863058a32@kernel.crashing.org> References: <17165.800.617053.891578@cargo.ozlabs.ibm.com> <640514b313694c6083cacd9863058a32@kernel.crashing.org> Message-ID: <20050825160951.GA26314@parcelfarce.linux.theplanet.co.uk> On Thu, Aug 25, 2005 at 05:42:07PM +0200, Segher Boessenkool wrote: > Why does it have to be disabled for probing? The kernel really > shouldn't change bus numbers and address ranges and BARs if the > firmware already has done this. If the firmware has disabled a > device (or bridge, or just some BARs), it probably has a good > reason to do so. On the other hand, there might be a lot of > broken firmwares out there, of course -- but not nearly as much > as on x86, so we don't need all those fixups they use. In order to size a BAR, you read its current value, write 0xffffffff to it, read it back, see how many bits are 0, then write the original value back. It's a fundamentally destructive process [1] during the window between writing 0xffffffff and restoring the original value. [1] Which is why cpqphp_pci, ibmphp_pci, pciehp_pci and shpchp_pci are broken. They're loadable as a module, and will probe the BARs of devices with currently running drivers. If an interrupt comes in at the wrong time, splat. I fixed acpiphp and I guess I'll have to fix pciehp soon ;-( They're such ugly drivers ... and so much copy-and-pasted code between them. -- "Next the statesmen will invent cheap lies, putting the blame upon the nation that is attacked, and every man will be glad of those conscience-soothing falsities, and will diligently study them, and refuse to examine any refutations of them; and thus he will by and by convince himself that the war is just, and will thank God for the better sleep he enjoys after this process of grotesque self-deception." -- Mark Twain From linas at austin.ibm.com Fri Aug 26 02:13:25 2005 From: linas at austin.ibm.com (Linas Vepstas) Date: Thu, 25 Aug 2005 11:13:25 -0500 Subject: [patch 8/8] PCI Error Recovery: PPC64 core recovery routines In-Reply-To: <17165.3205.505386.187453@cargo.ozlabs.ibm.com> References: <20050823231817.829359000@bilge> <20050823232143.003048000@bilge> <20050823234747.GI18113@austin.ibm.com> <1124898331.24668.33.camel@sinatra.austin.ibm.com> <20050824162959.GC25174@austin.ibm.com> <17165.3205.505386.187453@cargo.ozlabs.ibm.com> Message-ID: <20050825161325.GG25174@austin.ibm.com> On Thu, Aug 25, 2005 at 10:10:45AM +1000, Paul Mackerras was heard to remark: > Linas Vepstas writes: > > > The meta-issue that I'd like to reach consensus on first is whether > > there should be any hot-plug recovery attempted at all. Removing > > hot-plug-recovery support will make many of the issues you raise > > to be moot. > > Yes, this probably the thorniest issue we have. > > My feeling is that the unplug half of it is probably fairly > uncontroversial, but the replug half is a can of worms. Would you > agree with that? Actually, no. There are three issues: 1) hotplug routines are called from within kernel. GregKH has stated on multiple occasions that doing this is wrong/bad/evil. This includes calling hot-unplug. 2) As a result, the code to call hot-unplug is a bit messy. In particular, there's a bit of hoop-jumping when hotplug is built as as a module (and said hoops were wrecked recently when I moved the code around, out of the rpaphp directory). 3) Hot-unplug causes scripts to run in user-space. There is no way to know when these scripts are done, so its not clear if we've waited long enough before calling hot-add (or if waiting is even necessary). > Is it udev that handles the hotplug notifications on the userspace > side in all cases (do both RHEL and SLES use udev, for instance)? Yes, and it seems to work fine despite the fact that the current sles9/rhel4 use rather oooooold versions of udev, which is criminal, according to Kay Seivers. I have not tested new versions of udev; I assume new versions will work "even better". > How hard is it to add a new sort of notification, on the kernel side > and in udev? Why? To acheive what goal? (Keep in mind that user-space eeh solutions seem to fail when the affected device is storage, since block devices and filesystems don't like the underlying storage to wink out.) > I think what I'd like to see is that when a slot gets isolated and the > driver doesn't have recovery code, the kernel calls the driver's > unplug function and generates a hotplug event to udev. Ideally this > would be a variant of the remove event which would say "and by the > way, please try replugging this slot when you've finished handling the > remove event" or something along those lines. Ahh, yes, this addresses the timing issue raised in point 3). However, I'm thinking that the timing issue is not really an issue, depending on how udev is designed. For example, consider a 100% cpu loaded, heavy i/o loaded PC, and now we rapidly unplug and replug some USB key. Presumably, udev will handle this gracefully. The kernel error recovery essentially looks the same to udev: the burp on the bus looks like a rapid-fire unplug-replug. BTW, zSeries has similar concerns, where channels can come and go, causing thousands of unplug/replug udev events in rapid succession. (This was discussed on the udev mailing lists in the past). It might be interesting to have the zSeries folks discuss the current EEH design, as this is something they have far more experience with than any of the pc or unix crowd. I personally have not discussed with any zSeries people. --linas From geoffrey.levand at am.sony.com Fri Aug 26 01:55:37 2005 From: geoffrey.levand at am.sony.com (Geoff Levand) Date: Thu, 25 Aug 2005 08:55:37 -0700 Subject: [News] Cell documents _now_ available on the web In-Reply-To: <200508251649.32956.arnd@arndb.de> References: <17165.49132.487161.174641@kitch0.watson.ibm.com> <200508251649.32956.arnd@arndb.de> Message-ID: <430DE9F9.40200@am.sony.com> Arnd Bergmann wrote: > Now that the official name for the architecture has become > CBEA (Cell Broadband Engine Architecture), I wonder if we > should rename the stuff in the kernel from BPA (which it > has been called so far) to either "CBEA" or simply "cell". I think 'cell' is certainly the more identifiable name, and its easier to remember how to spell... -Geoff From linas at austin.ibm.com Fri Aug 26 02:21:18 2005 From: linas at austin.ibm.com (Linas Vepstas) Date: Thu, 25 Aug 2005 11:21:18 -0500 Subject: [patch 8/8] PCI Error Recovery: PPC64 core recovery routines In-Reply-To: <1124930943.5159.168.camel@gaston> References: <20050823231817.829359000@bilge> <20050823232143.003048000@bilge> <20050823234747.GI18113@austin.ibm.com> <1124898331.24668.33.camel@sinatra.austin.ibm.com> <20050824162959.GC25174@austin.ibm.com> <17165.3205.505386.187453@cargo.ozlabs.ibm.com> <1124930943.5159.168.camel@gaston> Message-ID: <20050825162118.GH25174@austin.ibm.com> On Thu, Aug 25, 2005 at 10:49:03AM +1000, Benjamin Herrenschmidt was heard to remark: > > Of course, we'll possibly end up with a different ethX or whatever, but Yep, but that's not an issue, since all the various device-naming schemes are supposed to be fixing this. Its a distinct problem; it needs to be solved even across cold-boots. (Didn't I ever tell you about the day I added a new disk controller to my system, and /dev/hda became /dev/hde and thus /home was mounted on /usr and /var as /etc and all hell broke loose? Owww, device naming is a serious issue for home users and even more so for enterprise-class users). --linas From segher at kernel.crashing.org Fri Aug 26 03:13:39 2005 From: segher at kernel.crashing.org (Segher Boessenkool) Date: Thu, 25 Aug 2005 19:13:39 +0200 Subject: [RFC/PATCH] Set up PCI tree from OF on ppc64 In-Reply-To: <20050825160951.GA26314@parcelfarce.linux.theplanet.co.uk> References: <17165.800.617053.891578@cargo.ozlabs.ibm.com> <640514b313694c6083cacd9863058a32@kernel.crashing.org> <20050825160951.GA26314@parcelfarce.linux.theplanet.co.uk> Message-ID: <1f4234743e9399c7b8b81c512d111bf7@kernel.crashing.org> > In order to size a BAR, Ah indeed, I didn't think about this part. Of course this can be solved with a lightweight lock or something, but it's probably just not worth it (might slow down the interrupt path too much). Segher From glikely at gmail.com Fri Aug 26 03:12:22 2005 From: glikely at gmail.com (Grant Likely) Date: Thu, 25 Aug 2005 11:12:22 -0600 Subject: [News] Cell documents _now_ available on the web In-Reply-To: References: <200508251649.32956.arnd@arndb.de> Message-ID: <20050825171222.GA6221@siegfried.thelikelysolution.ca> On Thu, Aug 25, 2005 at 10:27:32AM -0500, Kumar Gala wrote: > > On Aug 25, 2005, at 9:49 AM, Arnd Bergmann wrote: > >Now that the official name for the architecture has become > >CBEA (Cell Broadband Engine Architecture), I wonder if we > >should rename the stuff in the kernel from BPA (which it > >has been called so far) to either "CBEA" or simply "cell". > > I would vote for simply "cell" since that seems less likely to change > due to marketers :) Personally, I vote for more, not fewer, incomprehensible acronyms. How else do we keep the barriers of entry, and our salaries, high? :) g. From johnrose at austin.ibm.com Fri Aug 26 05:36:53 2005 From: johnrose at austin.ibm.com (John Rose) Date: Thu, 25 Aug 2005 14:36:53 -0500 Subject: [RFC/PATCH] Set up PCI tree from OF on ppc64 In-Reply-To: <17165.800.617053.891578@cargo.ozlabs.ibm.com> References: <17165.800.617053.891578@cargo.ozlabs.ibm.com> Message-ID: <1124998613.15265.7.camel@sinatra.austin.ibm.com> Hi Paul- (Sorry for the resend, forgot cc's) Looks nice. A few comments: +static int pSeries_pci_probe_mode(struct pci_bus *bus) +{ + if (systemcfg->platform & PLATFORM_LPAR) + return PCI_PROBE_DEVTREE; + return PCI_PROBE_NORMAL; +} + Would we not want to use PROBE_DEVTREE for non-partitioned and legacy pSeries? +static void __devinit of_scan_bus(struct device_node *node, + struct pci_bus *bus) ... +static void __devinit of_scan_pci_bridge(struct device_node *node, + struct pci_dev *dev) We should probably expose these for use by the PCI Hotplug/DLPAR drivers, along w/ scan_phb(). + /* parse ranges property */ + /* PCI #address-cells == 3 and #size-cells == 2 always */ + res = &dev->resource[PCI_BRIDGE_RESOURCES]; + for (i = 0; i < PCI_NUM_RESOURCES - PCI_BRIDGE_RESOURCES; ++i) { + res->flags = 0; + bus->resource[i] = res; + ++res; + } + i = 1; + for (; len >= 32; len -= 32, ranges += 8) { + flags = pci_parse_of_flags(ranges[0]); + size = GET_64BIT(ranges, 6); + if (flags == 0 || size == 0) + continue; + if (flags & IORESOURCE_IO) { + res = bus->resource[0]; + if (res->flags) { + printk(KERN_ERR "PCI: ignoring extra I/O range" + " for bridge %s\n", node->full_name); + continue; + } + } else { + if (i >= PCI_NUM_RESOURCES - PCI_BRIDGE_RESOURCES) { + printk(KERN_ERR "PCI: too many memory ranges" + " for bridge %s\n", node->full_name); + continue; + } + res = bus->resource[i]; + ++i; + } + res->start = GET_64BIT(ranges, 1); + res->end = res->start + size - 1; + res->flags = flags; + fixup_resource(res, dev); + } Could pci_process_bridge_OF_ranges() and of_scan_pci_bridge() use common "ranges" parsing logic? We're parsing the same property in two different ways in the same file. This could be a "todo" I guess. Thanks- John From benh at kernel.crashing.org Fri Aug 26 07:43:57 2005 From: benh at kernel.crashing.org (Benjamin Herrenschmidt) Date: Fri, 26 Aug 2005 07:43:57 +1000 Subject: [patch 8/8] PCI Error Recovery: PPC64 core recovery routines In-Reply-To: <20050825162118.GH25174@austin.ibm.com> References: <20050823231817.829359000@bilge> <20050823232143.003048000@bilge> <20050823234747.GI18113@austin.ibm.com> <1124898331.24668.33.camel@sinatra.austin.ibm.com> <20050824162959.GC25174@austin.ibm.com> <17165.3205.505386.187453@cargo.ozlabs.ibm.com> <1124930943.5159.168.camel@gaston> <20050825162118.GH25174@austin.ibm.com> Message-ID: <1125006237.12539.23.camel@gaston> On Thu, 2005-08-25 at 11:21 -0500, Linas Vepstas wrote: > On Thu, Aug 25, 2005 at 10:49:03AM +1000, Benjamin Herrenschmidt was heard to remark: > > > > Of course, we'll possibly end up with a different ethX or whatever, but > > Yep, but that's not an issue, since all the various device-naming > schemes are supposed to be fixing this. Its a distinct problem; > it needs to be solved even across cold-boots. Ok, so what is the problem then ? Why do we have to wait at all ? Why not just unplug/replug right away ? > (Didn't I ever tell you about the day I added a new disk controller to > my system, and /dev/hda became /dev/hde and thus /home was mounted on > /usr and /var as /etc and all hell broke loose? Owww, device naming > is a serious issue for home users and even more so for enterprise-class > users). > > --linas > From arnd at arndb.de Fri Aug 26 07:53:10 2005 From: arnd at arndb.de (Arnd Bergmann) Date: Thu, 25 Aug 2005 23:53:10 +0200 Subject: [PATCH 0/7] Cell SPU file system, snapshot 4 Message-ID: <200508252353.10740.arnd@arndb.de> Thankfully, there is now documentation available to the world about the Cell architecture (http://cell.scei.co.jp/e_download.html), so I am now able to disclose more of our work on the SPU file system. This is a rather big update compared to the previous version, as it contains work from Mark Nutter and Ulrich Weigand to support context save and restore of SPUs. This release should still be fully compatible to the previous ones, but we intend to do incompatible changes for in the future. Arnd <>< From arnd at arndb.de Fri Aug 26 08:04:11 2005 From: arnd at arndb.de (Arnd Bergmann) Date: Fri, 26 Aug 2005 00:04:11 +0200 Subject: [PATCH 2/7] spufs: switchable spu contexts Message-ID: <200508260004.11814.arnd@arndb.de> Add some infrastructure for saving and restoring the context of an SPE. This patch creates a new structure that can hold the whole state of a physical SPE in memory. It also contains code that avoids races during the context switch and the binary code that is loaded to the SPU in order to access its registers. The actual PPE- and SPE-side context switch code are two separate patches. From: Mark Nutter Signed-off-by: Arnd Bergmann -- arch/ppc64/kernel/spu_base.c | 27 ++ fs/spufs/Makefile | 4 fs/spufs/context.c | 18 + fs/spufs/spu_restore_dump.h_shipped | 342 ++++++++++++++++++++++++++++++++++++ fs/spufs/spu_save_dump.h_shipped | 290 ++++++++++++++++++++++++++++++ fs/spufs/spufs.h | 2 fs/spufs/switch.c | 174 ++++++++++++++++++ include/asm-ppc64/spu.h | 76 ++++++++ include/asm-ppc64/spu_csa.h | 256 ++++++++++++++++++++++++++ 9 files changed, 1185 insertions(+), 4 deletions(-) diff -urN linux-2.6.13-rc6.fix/arch/ppc64/kernel/spu_base.c linux-2.6.13-rc6/arch/ppc64/kernel/spu_base.c --- linux-2.6.13-rc6.fix/arch/ppc64/kernel/spu_base.c 2005-08-23 00:25:53.201118036 +0200 +++ linux-2.6.13-rc6/arch/ppc64/kernel/spu_base.c 2005-08-23 00:21:50.242294578 +0200 @@ -62,7 +62,9 @@ static void spu_restart_dma(struct spu *spu) { struct spu_priv2 __iomem *priv2 = spu->priv2; - out_be64(&priv2->mfc_control_RW, MFC_CNTL_RESTART_DMA_COMMAND); + + if (!test_bit(SPU_CONTEXT_SWITCH_PENDING_nr, &spu->flags)) + out_be64(&priv2->mfc_control_RW, MFC_CNTL_RESTART_DMA_COMMAND); } static int __spu_trap_data_seg(struct spu *spu, unsigned long ea) @@ -72,6 +74,11 @@ pr_debug("%s\n", __FUNCTION__); + if (test_bit(SPU_CONTEXT_SWITCH_ACTIVE_nr, &spu->flags)) { + printk("%s: invalid access during switch!\n", __func__); + return 1; + } + if (REGION_ID(ea) != USER_REGION_ID) { pr_debug("invalid region access at %016lx\n", ea); return 1; @@ -98,6 +105,7 @@ return 0; } +extern int hash_page(unsigned long ea, unsigned long access, unsigned long trap); //XXX static int __spu_trap_data_map(struct spu *spu, unsigned long ea) { unsigned long dsisr; @@ -107,8 +115,21 @@ priv1 = spu->priv1; dsisr = in_be64(&priv1->mfc_dsisr_RW); - wake_up(&spu->stop_wq); + /* Handle kernel space hash faults immediately. + User hash faults need to be deferred to process context. */ + if ((dsisr & MFC_DSISR_PTE_NOT_FOUND) + && REGION_ID(ea) != USER_REGION_ID + && hash_page(ea, _PAGE_PRESENT, 0x300) == 0) { + spu_restart_dma(spu); + return 0; + } + + if (test_bit(SPU_CONTEXT_SWITCH_ACTIVE_nr, &spu->flags)) { + printk("%s: invalid access during switch!\n", __func__); + return 1; + } + wake_up(&spu->stop_wq); return 0; } @@ -378,7 +399,6 @@ } EXPORT_SYMBOL(spu_free); -extern int hash_page(unsigned long ea, unsigned long access, unsigned long trap); //XXX static int spu_handle_mm_fault(struct spu *spu) { struct spu_priv1 __iomem *priv1; @@ -646,6 +666,7 @@ spu->slb_replace = 0; spu->mm = NULL; spu->class_0_pending = 0; + spu->flags = 0UL; spin_lock_init(&spu->register_lock); out_be64(&spu->priv1->mfc_sdr_RW, mfspr(SPRN_SDR1)); diff -urN linux-2.6.13-rc6.fix/fs/spufs/Makefile linux-2.6.13-rc6/fs/spufs/Makefile --- linux-2.6.13-rc6.fix/fs/spufs/Makefile 2005-08-22 23:47:52.087135000 +0200 +++ linux-2.6.13-rc6/fs/spufs/Makefile 2005-08-22 23:50:30.742186383 +0200 @@ -1,3 +1,5 @@ obj-$(CONFIG_SPU_FS) += spufs.o -spufs-y += inode.o file.o context.o +spufs-y += inode.o file.o context.o switch.o + +$(obj)/switch.o: $(obj)/spu_save_dump.h $(obj)/spu_restore_dump.h diff -urN linux-2.6.13-rc6.fix/fs/spufs/context.c linux-2.6.13-rc6/fs/spufs/context.c --- linux-2.6.13-rc6.fix/fs/spufs/context.c 2005-08-22 23:47:52.088135000 +0200 +++ linux-2.6.13-rc6/fs/spufs/context.c 2005-08-22 23:50:30.743186743 +0200 @@ -22,6 +22,7 @@ #include #include +#include #include "spufs.h" struct spu_context *alloc_spu_context(void) @@ -30,9 +31,25 @@ ctx = kmalloc(sizeof *ctx, GFP_KERNEL); if (!ctx) goto out; + /* Future enhancement: do not call spu_alloc() + * here. This step should be deferred until + * spu_run()!! + * + * More work needs to be done to read(), + * write(), mmap(), etc., so that operations + * are performed on CSA when the context is + * not currently being run. In this way we + * can support arbitrarily large number of + * entries in /spu, allow state queries, etc. + */ ctx->spu = spu_alloc(); if (!ctx->spu) goto out_free; + spu_init_csa(&ctx->csa); + if (!ctx->csa.lscsa) { + spu_free(ctx->spu); + goto out_free; + } init_rwsem(&ctx->backing_sema); spin_lock_init(&ctx->mmio_lock); kref_init(&ctx->kref); @@ -50,6 +67,7 @@ ctx = container_of(kref, struct spu_context, kref); if (ctx->spu) spu_free(ctx->spu); + spu_fini_csa(&ctx->csa); kfree(ctx); } diff -urN linux-2.6.13-rc6.fix/fs/spufs/spu_restore_dump.h_shipped linux-2.6.13-rc6/fs/spufs/spu_restore_dump.h_shipped --- linux-2.6.13-rc6.fix/fs/spufs/spu_restore_dump.h_shipped 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.13-rc6/fs/spufs/spu_restore_dump.h_shipped 2005-08-22 23:50:30.750189261 +0200 @@ -0,0 +1,342 @@ +/* spu_restore_dump.h: Copyright (C) 2005 IBM. + * Hex-dump auto generated from spu_restore.c. + * Do not edit! + */ +static unsigned int spu_restore_code[] __page_aligned = { +0x40800000, 0x409ff801, 0x24000080, 0x24fd8081, +0x1cd80081, 0x33009d80, 0x42054003, 0x33800284, +0x1c010204, 0x40200000, 0x40200000, 0x40200000, +0x34000190, 0x34004191, 0x34008192, 0x3400c193, +0x141fc205, 0x23fffd84, 0x1c100183, 0x217ffa85, +0x30813000, 0x30813201, 0x30813402, 0x30813603, +0x30813804, 0x30813a05, 0x30813c06, 0x30813e07, +0x30814008, 0x30814209, 0x3081440a, 0x3081460b, +0x3081480c, 0x30814a0d, 0x30814c0e, 0x30814e0f, +0x00003ffc, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x420a4002, 0x3f8101b8, 0x40a00003, 0x00200000, +0x1c010104, 0x34000107, 0x40800018, 0x3ec00108, +0x40a48005, 0x3ec00212, 0x40800436, 0x3ec20122, +0x18015c13, 0x3ec20232, 0x42448006, 0x3ec6010b, +0x40800805, 0xb141c188, 0x18019c31, 0x3ec40106, +0x42648009, 0x3ec40208, 0x40800c07, 0x3ec6020d, +0x18025c09, 0x2886010a, 0x4284800c, 0x34000215, +0x4080100a, 0x3ec8010e, 0x18031c0c, 0x3ec80210, +0x42a48011, 0x3ecc0116, 0x4080140f, 0x3ece011b, +0x18045c11, 0x3ece021d, 0x42c48014, 0xb3454992, +0x40801812, 0x3eca0113, 0x18051c14, 0x3eca0215, +0x42e48019, 0x00200000, 0x40801c17, 0x2886021a, +0x18065c18, 0x388d8123, 0x4304801c, 0x3ecc0219, +0x4080201a, 0x18071c1c, 0x43248021, 0x3ac6811e, +0x4080241f, 0x3ac68220, 0x18085c21, 0xb4c8c1a2, +0x43448025, 0x3ac7c122, 0x40802823, 0x3ac7c224, +0x18095c25, 0x00200000, 0x43648027, 0x288d8126, +0x40802c26, 0x388d8233, 0x1809dc27, 0x3ac8c128, +0x4384802c, 0x3ac8c229, 0x4080302a, 0x3ac9812b, +0x180b1c2c, 0x3ac9822d, 0x43a48030, 0x3aca812e, +0x4080342f, 0xb6ecd8b2, 0x180c1c30, 0x3aca8231, +0x43c48035, 0x3acbc132, 0x40803833, 0x3acbc234, +0x180d5c35, 0x288d8237, 0x43e48037, 0x34004136, +0x40200001, 0x3accc139, 0x180ddc37, 0x3accc238, +0xb0cd8186, 0x28814106, 0x34004206, 0xb0c18488, +0x28814206, 0x3881c105, 0xb0a1418b, 0x2881c105, +0x3881c205, 0xb0a1460d, 0x2881c205, 0x34008105, +0xb0a1418e, 0x28828105, 0x34008205, 0xb0a14890, +0x28828205, 0x3883c105, 0xb0a14193, 0x2883c105, +0x3883c205, 0xb0a14a15, 0x2883c205, 0x3400c105, +0xb0a14196, 0x28848105, 0x3400c205, 0xb0a14c19, +0x28848205, 0x3885c105, 0xb0a1419b, 0x2885c105, +0x3885c205, 0xb0a14e1d, 0x2885c205, 0x34010105, +0xb0a1419e, 0x28868105, 0x34010205, 0xb0a150a0, +0x28868205, 0x3887c105, 0xb0a141a2, 0x2887c105, +0x3887c205, 0xb0a152a4, 0x2887c205, 0x34014105, +0xb0a141a8, 0x2888c105, 0x34014205, 0x3580001c, +0xb0a153a9, 0x2888c205, 0x38898105, 0xb0a141ab, +0x28898105, 0x38898205, 0xb0a1562d, 0x28898205, +0x34018105, 0xb0a141ae, 0x288a8105, 0x34018205, +0xb0a15831, 0x288a8205, 0x388bc105, 0xb0a141b2, +0x288bc105, 0x388bc205, 0xb0a15ab4, 0x288bc205, +0x3401c105, 0xb06141b9, 0x288cc103, 0x3401c202, +0xb0409bb8, 0x288cc202, 0x4020003a, 0x35000000, +0x40800002, 0x40804004, 0x40805a05, 0x21a00802, +0x21a00883, 0x3f810183, 0x21a00903, 0x21a00984, +0x21a00a02, 0x21a00a85, 0x40200001, 0x3580000a, +0x40200006, 0x00200000, 0x40200007, 0x00200000, +0x40200008, 0x00200000, 0x40200009, 0x00200000, +0x4020000a, 0x35000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x4204c002, 0x40848004, 0x40800005, 0x00200000, +0x40802006, 0x21a00802, 0x21a00883, 0x3f810182, +0x21a00902, 0x21a00984, 0x21a00a05, 0x21a00a86, +0x40200001, 0x3580000a, 0x40200007, 0x00200000, +0x40200008, 0x00200000, 0x40200009, 0x00200000, +0x4020000a, 0x00200000, 0x4020000b, 0x35000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x40a00002, 0x420a4004, 0x40803c05, 0x40800006, +0x40802207, 0x21a00802, 0x21a00883, 0x21a00904, +0x21a00985, 0x21a00a06, 0x21a00a87, 0x3580000a, +0x40200001, 0x00200000, 0x40200008, 0x00200000, +0x40200009, 0x00200000, 0x4020000a, 0x00200000, +0x4020000b, 0x35000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x24004080, 0x24fd0081, 0x1cd00081, 0x01a00182, +0x34028083, 0x3ec00084, 0xb040c104, 0x01a00203, +0x4020000f, 0x127fdb89, 0x40200010, 0x3ec10084, +0x40200011, 0x00200000, 0x40200012, 0x00200000, +0xb7408184, 0x082e9d03, 0x337fd700, 0x40800002, +0x408000bb, 0x21a00082, 0x21a00b3b, 0x127f6c8a, +0x40200013, 0x00200000, 0x40200014, 0x00200000, +0x40200015, 0x00200000, 0x40200016, 0x00200000, +0x40200017, 0x337f6780, 0x082e9d03, 0x127fde8a, +0x40200018, 0x00200000, 0x40200019, 0x00200000, +0x4020001a, 0x00200000, 0x4020001b, 0x00200000, +0x4020001c, 0x337fd980, 0x4204c006, 0x30823402, +0x3b818102, 0x20000202, 0x30823202, 0x3b818102, +0x21a00382, 0x127fb589, 0x4020001d, 0x00200000, +0x4020001e, 0x00200000, 0x4020001f, 0x00200000, +0x40200020, 0x00200000, 0x337fb100, 0x21a00bbb, +0x01a00c02, 0x01a00d82, 0x30823602, 0x3b818102, +0x21a00e02, 0x30823802, 0x3b818102, 0x21a00f02, +0x30823e02, 0x30823003, 0x3b818102, 0x774001a1, +0x21a00702, 0x30823c02, 0x3b818102, 0x21a00082, +0x30823a02, 0x3b818103, 0x40844002, 0x00200000, +0x18008302, 0x21a00b03, 0x40844203, 0x00200000, +0x4200480e, 0x34000104, 0x1800c303, 0x34000185, +0x3b808204, 0x3b80c282, 0x1cffc203, 0x5c020184, +0x21005504, 0x0f610183, 0x42094004, 0x3880c203, +0x3b810183, 0x3580018a, 0x40200022, 0x00200000, +0x40200023, 0x00200000, 0x40200024, 0x00200000, +0x40200025, 0x00200000, 0x40200026, 0x35000180, +0x409ffe03, 0x34000704, 0x1c010705, 0x3ec00706, +0x41004007, 0x3ec10708, 0x1c020709, 0x1200498a, +0x3ec2070a, 0xb0610186, 0x24000703, 0x34000283, +0xb060c388, 0x24000283, 0x34000483, 0xb040c10a, +0x24000482, 0x32004480, 0x409ffe03, 0x34000704, +0x1c010705, 0x3ec00706, 0x413d8007, 0x3ec10708, +0x1c020709, 0x1200408a, 0x3ec2070a, 0xb0610186, +0x24000703, 0x34000283, 0xb060c388, 0x24000283, +0x34000483, 0xb040c10a, 0x24000482, 0x32003b80, +0x409ffe03, 0x34000704, 0x1c010705, 0x3ec00706, +0x1c020707, 0x3ec10708, 0x41201009, 0x3ec2070a, +0x1c03070b, 0x12003690, 0x41193f8d, 0x3ec3070c, +0xb0610186, 0x60ffc00d, 0x24000703, 0x34000283, +0xb040c108, 0x24000282, 0x34000382, 0xb040848a, +0x24000382, 0x34000582, 0xb040868c, 0x24000582, +0x40200027, 0x32002e80, 0x409ffe02, 0x34000703, +0x1c010704, 0x3ec00705, 0x41004006, 0x3ec10707, +0x1c020708, 0x3ec20709, 0x4120100a, 0x12002990, +0x1c03070c, 0x3ec3070b, 0x41193f8d, 0xb040c105, +0x60ffc00d, 0x24000702, 0x34000202, 0xb0408307, +0x24000202, 0x34000402, 0xb0408509, 0x24000402, +0x34000602, 0xb040868b, 0x24000602, 0x32002180, +0x409ffe02, 0x34000703, 0x1c010704, 0x3ec00705, +0x413d8006, 0x3ec10707, 0x1c020708, 0x3ec20709, +0x4120100a, 0x12001c90, 0x1c03070c, 0x3ec3070b, +0x41193f8d, 0xb040c105, 0x60ffc00d, 0x24000702, +0x34000202, 0xb0408307, 0x24000202, 0x34000402, +0xb0408509, 0x24000402, 0x34000602, 0xb040868b, +0x24000602, 0x32001480, 0x409ffe03, 0x30801204, +0x1c010705, 0x3ec00706, 0x40200028, 0x1200118a, +0x40200029, 0x3ec10707, 0x4020002a, 0xb0610186, +0x20801203, 0x34000283, 0xb040c107, 0x24000282, +0x4020002b, 0x32000c80, 0x409ffe02, 0x34000703, +0x1c010704, 0x3ec00705, 0x41201006, 0x3ec10707, +0x1c020708, 0x3ec20709, 0x1c03070a, 0x3ec3070b, +0x41193f8c, 0xb040c105, 0x60ffc00c, 0x24000702, +0x34000202, 0xb0408307, 0x24000202, 0x34000402, +0xb0408309, 0x24000402, 0x34000502, 0xb040860b, +0x4020002c, 0x24000502, 0x40800003, 0x00400000, +0x1c300081, 0x34004080, 0x4020002d, 0x3580000a, +0x4020002e, 0x00200000, 0x4020002f, 0x00200000, +0x40200030, 0x00200000, 0x40200031, 0x00200000, +0x40200032, 0x35000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000888, 0x00000000, 0x00000000, 0x00000000, +0x000007b8, 0x00000000, 0x00000000, 0x00000000, +0x00000820, 0x00000000, 0x00000000, 0x00000000, +0x000008c8, 0x00000000, 0x00000000, 0x00000000, +0x000007b8, 0x00000000, 0x00000000, 0x00000000, +0x00000750, 0x00000000, 0x00000000, 0x00000000, +0x00000708, 0x00000000, 0x00000000, 0x00000000, +0x000006c0, 0x00000000, 0x00000000, 0x00000000, +0x000008c8, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x72657475, 0x726e2063, 0x6f64653a, 0x2025640a, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +}; diff -urN linux-2.6.13-rc6.fix/fs/spufs/spu_save_dump.h_shipped linux-2.6.13-rc6/fs/spufs/spu_save_dump.h_shipped --- linux-2.6.13-rc6.fix/fs/spufs/spu_save_dump.h_shipped 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.13-rc6/fs/spufs/spu_save_dump.h_shipped 2005-08-22 23:50:30.753190340 +0200 @@ -0,0 +1,290 @@ +/* spu_save_dump.h: Copyright (C) 2005 IBM. + * Hex-dump auto generated from spu_save.c. + * Do not edit! + */ +static unsigned int spu_save_code[] __page_aligned = { +0x2080f000, 0x2080f201, 0x2080f402, 0x2080f603, +0x2080f804, 0x2080fa05, 0x2080fc06, 0x2080fe07, +0x20810008, 0x20810209, 0x2081040a, 0x2081060b, +0x2081080c, 0x20810a0d, 0x20810c0e, 0x20810e0f, +0x42044003, 0x33800184, 0x1c010204, 0x40200000, +0x24000190, 0x24004191, 0x24008192, 0x2400c193, +0x141fc205, 0x23fffd84, 0x1c100183, 0x217ffb85, +0x40800000, 0x409ff801, 0x24000080, 0x24fd8081, +0x1cd80081, 0x33009780, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x4208c002, 0x3f8101b8, 0x40a00003, 0x00200000, +0x1c010104, 0x34000107, 0x40800018, 0x3ec00108, +0x40a48005, 0x3ec00212, 0x40800436, 0x3ec20122, +0x18015c13, 0x3ec20232, 0x42448006, 0x3ec6010b, +0x40800805, 0xb141c188, 0x18019c31, 0x3ec40106, +0x42648009, 0x3ec40208, 0x40800c07, 0x3ec6020d, +0x18025c09, 0x2886010a, 0x4284800c, 0x34000215, +0x4080100a, 0x3ec8010e, 0x18031c0c, 0x3ec80210, +0x42a48011, 0x3ecc0116, 0x4080140f, 0x3ece011b, +0x18045c11, 0x3ece021d, 0x42c48014, 0xb3454992, +0x40801812, 0x3eca0113, 0x18051c14, 0x3eca0215, +0x42e48019, 0x00200000, 0x40801c17, 0x2886021a, +0x18065c18, 0x388d8123, 0x4304801c, 0x3ecc0219, +0x4080201a, 0x18071c1c, 0x43248021, 0x3ac6811e, +0x4080241f, 0x3ac68220, 0x18085c21, 0xb4c8c1a2, +0x43448025, 0x3ac7c122, 0x40802823, 0x3ac7c224, +0x18095c25, 0x00200000, 0x43648027, 0x288d8126, +0x40802c26, 0x388d8233, 0x1809dc27, 0x3ac8c128, +0x4384802c, 0x3ac8c229, 0x4080302a, 0x3ac9812b, +0x180b1c2c, 0x3ac9822d, 0x43a48030, 0x3aca812e, +0x4080342f, 0xb6ecd8b2, 0x180c1c30, 0x3aca8231, +0x43c48035, 0x3acbc132, 0x40803833, 0x3acbc234, +0x180d5c35, 0x288d8237, 0x43e48037, 0x34004136, +0x40200001, 0x3accc139, 0x180ddc37, 0x3accc238, +0xb0cd8186, 0x28814106, 0x34004206, 0xb0c18488, +0x28814206, 0x3881c105, 0xb0a1418b, 0x2881c105, +0x3881c205, 0xb0a1460d, 0x2881c205, 0x34008105, +0xb0a1418e, 0x28828105, 0x34008205, 0xb0a14890, +0x28828205, 0x3883c105, 0xb0a14193, 0x2883c105, +0x3883c205, 0xb0a14a15, 0x2883c205, 0x3400c105, +0xb0a14196, 0x28848105, 0x3400c205, 0xb0a14c19, +0x28848205, 0x3885c105, 0xb0a1419b, 0x2885c105, +0x3885c205, 0xb0a14e1d, 0x2885c205, 0x34010105, +0xb0a1419e, 0x28868105, 0x34010205, 0xb0a150a0, +0x28868205, 0x3887c105, 0xb0a141a2, 0x2887c105, +0x3887c205, 0xb0a152a4, 0x2887c205, 0x34014105, +0xb0a141a8, 0x2888c105, 0x34014205, 0x3580001c, +0xb0a153a9, 0x2888c205, 0x38898105, 0xb0a141ab, +0x28898105, 0x38898205, 0xb0a1562d, 0x28898205, +0x34018105, 0xb0a141ae, 0x288a8105, 0x34018205, +0xb0a15831, 0x288a8205, 0x388bc105, 0xb0a141b2, +0x288bc105, 0x388bc205, 0xb0a15ab4, 0x288bc205, +0x3401c105, 0xb06141b9, 0x288cc103, 0x3401c202, +0xb0409bb8, 0x288cc202, 0x4020003a, 0x35000000, +0x40800002, 0x40804004, 0x40805a05, 0x21a00802, +0x21a00883, 0x3f810183, 0x21a00903, 0x21a00984, +0x21a00a02, 0x21a00a85, 0x40200001, 0x3580000a, +0x40200006, 0x00200000, 0x40200007, 0x00200000, +0x40200008, 0x00200000, 0x40200009, 0x00200000, +0x4020000a, 0x35000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x40a00002, 0x4208c004, 0x40803c05, 0x40800006, +0x40801207, 0x21a00802, 0x21a00883, 0x21a00904, +0x21a00985, 0x21a00a06, 0x21a00a87, 0x3580000a, +0x40200001, 0x00200000, 0x40200008, 0x00200000, +0x40200009, 0x00200000, 0x4020000a, 0x00200000, +0x4020000b, 0x35000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x4203c002, 0x40848004, 0x40800005, 0x00200000, +0x40801006, 0x21a00802, 0x21a00883, 0x3f810182, +0x21a00902, 0x21a00984, 0x21a00a05, 0x21a00a86, +0x40200001, 0x3580000a, 0x40200007, 0x00200000, +0x40200008, 0x00200000, 0x40200009, 0x00200000, +0x4020000a, 0x00200000, 0x4020000b, 0x35000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x40800002, 0x40806603, 0x21a00a02, 0x21a00a83, +0x40200001, 0x3580000a, 0x40200004, 0x00200000, +0x40200005, 0x00200000, 0x40200006, 0x00200000, +0x40200007, 0x00200000, 0x40200008, 0x35000000, +0x24004080, 0x24fd0081, 0x1cd00081, 0x01a00182, +0x34028083, 0x3ec00084, 0xb040c104, 0x01a00203, +0x40843005, 0x3ec10084, 0xb7408184, 0x01a00582, +0x4203c03b, 0x40842806, 0x34219d83, 0x3ac15d84, +0xb040c104, 0x28815d82, 0x40200007, 0x01a00603, +0x40800002, 0x34215d84, 0x408000bc, 0x3ac19d85, +0xb0610185, 0x28819d83, 0x082e9d03, 0x21a00082, +0x21a00b3c, 0x127f618a, 0x40200008, 0x00200000, +0x40200009, 0x00200000, 0x4020000a, 0x00200000, +0x4020000b, 0x00200000, 0x4020000c, 0x337f5c80, +0x082e9d03, 0x127fc389, 0x4020000d, 0x00200000, +0x4020000e, 0x00200000, 0x4020000f, 0x00200000, +0x40200010, 0x00200000, 0x337fbf00, 0x73000002, +0x40840003, 0x40840805, 0x2880dd82, 0x01a00402, +0x40843806, 0x34205d83, 0x3ac15d84, 0xb040c104, +0x28815d82, 0x01a00782, 0x082e9d03, 0x3421dd84, +0x3ac19d85, 0xb0410105, 0x28819d82, 0x127fa68a, +0x40200011, 0x00200000, 0x40200012, 0x00200000, +0x40200013, 0x00200000, 0x40200014, 0x00200000, +0x40200015, 0x337fa180, 0x082e9d03, 0x127fc089, +0x40200016, 0x00200000, 0x40200017, 0x00200000, +0x40200018, 0x00200000, 0x40200019, 0x00200000, +0x337fbc00, 0x127fcb89, 0x4020001a, 0x00200000, +0x4020001b, 0x00200000, 0x4020001c, 0x00200000, +0x4020001d, 0x00200000, 0x337fc700, 0x21a00bbc, +0x01a00c02, 0x01a00d82, 0x40800003, 0x00003ffb, +0x1c300081, 0x34004080, 0x4020001e, 0x3580000a, +0x4020001f, 0x00200000, 0x40200020, 0x00200000, +0x40200021, 0x00200000, 0x40200022, 0x00200000, +0x40200023, 0x35000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x72657475, 0x726e2063, 0x6f64653a, 0x2025640a, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +}; diff -urN linux-2.6.13-rc6.fix/fs/spufs/spufs.h linux-2.6.13-rc6/fs/spufs/spufs.h --- linux-2.6.13-rc6.fix/fs/spufs/spufs.h 2005-08-22 23:47:52.095138000 +0200 +++ linux-2.6.13-rc6/fs/spufs/spufs.h 2005-08-22 23:50:30.754190699 +0200 @@ -28,6 +28,7 @@ #include #include +#include /* The magic number for our file system */ enum { @@ -36,6 +37,7 @@ struct spu_context { struct spu *spu; /* pointer to a physical SPU */ + struct spu_state csa; /* SPU context save area. */ struct rw_semaphore backing_sema; /* protects the above */ spinlock_t mmio_lock; /* protects mmio access */ diff -urN linux-2.6.13-rc6.fix/fs/spufs/switch.c linux-2.6.13-rc6/fs/spufs/switch.c --- linux-2.6.13-rc6.fix/fs/spufs/switch.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.13-rc6/fs/spufs/switch.c 2005-08-22 23:50:40.591265801 +0200 @@ -0,0 +1,174 @@ +/* + * spu_switch.c + * + * (C) Copyright IBM Corp. 2005 + * + * Author: Mark Nutter + * + * Host-side part of SPU context switch sequence outlined in + * Synergistic Processor Element, Book IV. + * + * A fully premptive switch of an SPE is very expensive in terms + * of time and system resources. SPE Book IV indicates that SPE + * allocation should follow a "serially reusable device" model, + * in which the SPE is assigned a task until it completes. When + * this is not possible, this sequence may be used to premptively + * save, and then later (optionally) restore the context of a + * program executing on an SPE. + * + * + * 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, 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "spu_save_dump.h" +#include "spu_restore_dump.h" + +/** + * spu_save - SPU context save, with locking. + * @prev: pointer to SPU context save area, to be saved. + * @spu: pointer to SPU iomem structure. + * + * Acquire locks, perform the save operation then return. + */ +int spu_save(struct spu_state *prev, struct spu *spu) +{ + /* XXX missing */ + + return 0; +} + +/** + * spu_restore - SPU context restore, with harvest and locking. + * @new: pointer to SPU context save area, to be restored. + * @spu: pointer to SPU iomem structure. + * + * Perform harvest + restore, as we may not be coming + * from a previous succesful save operation, and the + * hardware state is unknown. + */ +int spu_restore(struct spu_state *new, struct spu *spu) +{ + /* XXX missing */ + + return 0; +} + +/** + * spu_switch - SPU context switch (save + restore). + * @prev: pointer to SPU context save area, to be saved. + * @new: pointer to SPU context save area, to be restored. + * @spu: pointer to SPU iomem structure. + * + * Perform save, then restore. Only harvest if the + * save fails, as cleanup is otherwise not needed. + */ +int spu_switch(struct spu_state *prev, struct spu_state *new, struct spu *spu) +{ + /* XXX missing */ + + return 0; +} + +static void init_prob(struct spu_state *csa) +{ + csa->spu_chnlcnt_RW[9] = 1; + csa->spu_chnlcnt_RW[21] = 16; + csa->spu_chnlcnt_RW[23] = 1; + csa->spu_chnlcnt_RW[28] = 1; + csa->spu_chnlcnt_RW[30] = 1; + csa->prob.spu_runcntl_RW = SPU_RUNCNTL_STOP; +} + +static void init_priv1(struct spu_state *csa) +{ + /* Enable decode, relocate, tlbie response, master runcntl. */ + csa->priv1.mfc_sr1_RW = MFC_STATE1_LOCAL_STORAGE_DECODE_MASK | + MFC_STATE1_MASTER_RUN_CONTROL_MASK | + MFC_STATE1_PROBLEM_STATE_MASK | + MFC_STATE1_RELOCATE_MASK | MFC_STATE1_BUS_TLBIE_MASK; + + /* Set storage description. */ + csa->priv1.mfc_sdr_RW = mfspr(SPRN_SDR1); + + /* Enable OS-specific set of interrupts. */ + csa->priv1.int_mask_class0_RW = CLASS0_ENABLE_DMA_ALIGNMENT_INTR | + CLASS0_ENABLE_INVALID_DMA_COMMAND_INTR | + CLASS0_ENABLE_SPU_ERROR_INTR; + csa->priv1.int_mask_class1_RW = CLASS1_ENABLE_SEGMENT_FAULT_INTR | + CLASS1_ENABLE_STORAGE_FAULT_INTR; + csa->priv1.int_mask_class2_RW = CLASS2_ENABLE_MAILBOX_INTR | + CLASS2_ENABLE_SPU_STOP_INTR | CLASS2_ENABLE_SPU_HALT_INTR; +} + +static void init_priv2(struct spu_state *csa) +{ + csa->priv2.spu_lslr_RW = LS_ADDR_MASK; + csa->priv2.mfc_control_RW = MFC_CNTL_RESUME_DMA_QUEUE | + MFC_CNTL_NORMAL_DMA_QUEUE_OPERATION | + MFC_CNTL_DMA_QUEUES_EMPTY_MASK; +} + +/** + * spu_alloc_csa - allocate and initialize an SPU context save area. + * + * Allocate and initialize the contents of an SPU context save area. + * This includes enabling address translation, interrupt masks, etc., + * as appropriate for the given OS environment. + * + * Note that storage for the 'lscsa' is allocated separately, + * as it is by far the largest of the context save regions, + * and may need to be pinned or otherwise specially aligned. + */ +void spu_init_csa(struct spu_state *csa) +{ + struct spu_lscsa *lscsa; + + if (!csa) + return; + memset(csa, 0, sizeof(struct spu_state)); + + lscsa = vmalloc(sizeof(struct spu_lscsa)); + if (!lscsa) + return; + + memset(lscsa, 0, sizeof(struct spu_lscsa)); + csa->lscsa = lscsa; + + init_prob(csa); + init_priv1(csa); + init_priv2(csa); +} + +void spu_fini_csa(struct spu_state *csa) +{ + vfree(csa->lscsa); +} diff -urN linux-2.6.13-rc6.fix/include/asm-ppc64/spu.h linux-2.6.13-rc6/include/asm-ppc64/spu.h --- linux-2.6.13-rc6.fix/include/asm-ppc64/spu.h 2005-08-22 23:47:52.098139000 +0200 +++ linux-2.6.13-rc6/include/asm-ppc64/spu.h 2005-08-23 00:26:27.970341701 +0200 @@ -28,6 +28,81 @@ #define LS_ORDER (6) /* 256 kb */ #define LS_SIZE (PAGE_SIZE << LS_ORDER) +#define LS_ADDR_MASK (LS_SIZE - 1) + +#define MFC_PUT_CMD 0x20 +#define MFC_PUTS_CMD 0x28 +#define MFC_PUTR_CMD 0x30 +#define MFC_PUTF_CMD 0x22 +#define MFC_PUTB_CMD 0x21 +#define MFC_PUTFS_CMD 0x2A +#define MFC_PUTBS_CMD 0x29 +#define MFC_PUTRF_CMD 0x32 +#define MFC_PUTRB_CMD 0x31 +#define MFC_PUTL_CMD 0x24 +#define MFC_PUTRL_CMD 0x34 +#define MFC_PUTLF_CMD 0x26 +#define MFC_PUTLB_CMD 0x25 +#define MFC_PUTRLF_CMD 0x36 +#define MFC_PUTRLB_CMD 0x35 + +#define MFC_GET_CMD 0x40 +#define MFC_GETS_CMD 0x48 +#define MFC_GETF_CMD 0x42 +#define MFC_GETB_CMD 0x41 +#define MFC_GETFS_CMD 0x4A +#define MFC_GETBS_CMD 0x49 +#define MFC_GETL_CMD 0x44 +#define MFC_GETLF_CMD 0x46 +#define MFC_GETLB_CMD 0x45 + +#define MFC_SDCRT_CMD 0x80 +#define MFC_SDCRTST_CMD 0x81 +#define MFC_SDCRZ_CMD 0x89 +#define MFC_SDCRS_CMD 0x8D +#define MFC_SDCRF_CMD 0x8F + +#define MFC_GETLLAR_CMD 0xD0 +#define MFC_PUTLLC_CMD 0xB4 +#define MFC_PUTLLUC_CMD 0xB0 +#define MFC_PUTQLLUC_CMD 0xB8 +#define MFC_SNDSIG_CMD 0xA0 +#define MFC_SNDSIGB_CMD 0xA1 +#define MFC_SNDSIGF_CMD 0xA2 +#define MFC_BARRIER_CMD 0xC0 +#define MFC_EIEIO_CMD 0xC8 +#define MFC_SYNC_CMD 0xCC + +#define MFC_MIN_DMA_SIZE_SHIFT 4 /* 16 bytes */ +#define MFC_MAX_DMA_SIZE_SHIFT 14 /* 16384 bytes */ +#define MFC_MIN_DMA_SIZE (1 << MFC_MIN_DMA_SIZE_SHIFT) +#define MFC_MAX_DMA_SIZE (1 << MFC_MAX_DMA_SIZE_SHIFT) +#define MFC_MIN_DMA_SIZE_MASK (MFC_MIN_DMA_SIZE - 1) +#define MFC_MAX_DMA_SIZE_MASK (MFC_MAX_DMA_SIZE - 1) +#define MFC_MIN_DMA_LIST_SIZE 0x0008 /* 8 bytes */ +#define MFC_MAX_DMA_LIST_SIZE 0x4000 /* 16K bytes */ + +#define MFC_TAGID_TO_TAGMASK(tag_id) (1 << (tag_id & 0x1F)) + +/* Events for Channels 0-2 */ +#define MFC_DMA_TAG_STATUS_UPDATE_EVENT 0x00000001 +#define MFC_DMA_TAG_CMD_STALL_NOTIFY_EVENT 0x00000002 +#define MFC_DMA_QUEUE_AVAILABLE_EVENT 0x00000008 +#define MFC_SPU_MAILBOX_WRITTEN_EVENT 0x00000010 +#define MFC_DECREMENTER_EVENT 0x00000020 +#define MFC_PU_INT_MAILBOX_AVAILABLE_EVENT 0x00000040 +#define MFC_PU_MAILBOX_AVAILABLE_EVENT 0x00000080 +#define MFC_SIGNAL_2_EVENT 0x00000100 +#define MFC_SIGNAL_1_EVENT 0x00000200 +#define MFC_LLR_LOST_EVENT 0x00000400 +#define MFC_PRIV_ATTN_EVENT 0x00000800 +#define MFC_MULTI_SRC_EVENT 0x00001000 + +/* Flags indicating progress during context switch. */ +#define SPU_CONTEXT_SWITCH_PENDING_nr 0UL +#define SPU_CONTEXT_SWITCH_ACTIVE_nr 1UL +#define SPU_CONTEXT_SWITCH_PENDING (1UL << SPU_CONTEXT_SWITCH_PENDING_nr) +#define SPU_CONTEXT_SWITCH_ACTIVE (1UL << SPU_CONTEXT_SWITCH_ACTIVE_nr) struct spu { char *name; @@ -40,6 +115,7 @@ int number; u32 isrc; u32 node; + u64 flags; struct kref kref; size_t ls_size; unsigned int slb_replace; diff -urN linux-2.6.13-rc6.fix/include/asm-ppc64/spu_csa.h linux-2.6.13-rc6/include/asm-ppc64/spu_csa.h --- linux-2.6.13-rc6.fix/include/asm-ppc64/spu_csa.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.13-rc6/include/asm-ppc64/spu_csa.h 2005-08-22 23:50:30.760192858 +0200 @@ -0,0 +1,256 @@ +/* + * spu_csa.h: Definitions for SPU context save area (CSA). + * + * (C) Copyright IBM 2005 + * + * Author: Mark Nutter + * + * 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, 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef _SPU_CSA_H_ +#define _SPU_CSA_H_ + +/* + * Total number of 128-bit registers. + */ +#define NR_SPU_GPRS 128 +#define NR_SPU_SPRS 9 +#define NR_SPU_REGS_PAD 7 +#define NR_SPU_SPILL_REGS 144 /* GPRS + SPRS + PAD */ +#define SIZEOF_SPU_SPILL_REGS NR_SPU_SPILL_REGS * 16 + +#define SPU_SAVE_COMPLETE 0x3FFB +#define SPU_RESTORE_COMPLETE 0x3FFC + +/* + * Definitions for various 'stopped' status conditions, + * to be recreated during context restore. + */ +#define SPU_STOPPED_STATUS_P 1 +#define SPU_STOPPED_STATUS_I 2 +#define SPU_STOPPED_STATUS_H 3 +#define SPU_STOPPED_STATUS_S 4 +#define SPU_STOPPED_STATUS_S_I 5 +#define SPU_STOPPED_STATUS_S_P 6 +#define SPU_STOPPED_STATUS_P_H 7 +#define SPU_STOPPED_STATUS_P_I 8 +#define SPU_STOPPED_STATUS_R 9 + +#ifndef __ASSEMBLY__ +/** + * spu_reg128 - generic 128-bit register definition. + */ +struct spu_reg128 { + u32 slot[4]; +}; + +/** + * struct spu_lscsa - Local Store Context Save Area. + * @gprs: Array of saved registers. + * @fpcr: Saved floating point status control register. + * @decr: Saved decrementer value. + * @decr_status: Indicates decrementer run status. + * @ppu_mb: Saved PPU mailbox data. + * @ppuint_mb: Saved PPU interrupting mailbox data. + * @tag_mask: Saved tag group mask. + * @event_mask: Saved event mask. + * @srr0: Saved SRR0. + * @stopped_status: Conditions to be recreated by restore. + * @ls: Saved contents of Local Storage Area. + * + * The LSCSA represents state that is primarily saved and + * restored by SPU-side code. + */ +struct spu_lscsa { + struct spu_reg128 gprs[128]; + struct spu_reg128 fpcr; + struct spu_reg128 decr; + struct spu_reg128 decr_status; + struct spu_reg128 ppu_mb; + struct spu_reg128 ppuint_mb; + struct spu_reg128 tag_mask; + struct spu_reg128 event_mask; + struct spu_reg128 srr0; + struct spu_reg128 stopped_status; + struct spu_reg128 pad[7]; /* 'ls' must be 128-byte aligned. */ + unsigned char ls[LS_SIZE]; +}; + +#ifdef __KERNEL__ + +/* + * struct spu_problem_collapsed - condensed problem state area, w/o pads. + */ +struct spu_problem_collapsed { + u64 spc_mssync_RW; + u32 mfc_lsa_W; + u32 unused_pad0; + u64 mfc_ea_W; + union mfc_tag_size_class_cmd mfc_union_W; + u32 dma_qstatus_R; + u32 dma_querytype_RW; + u32 dma_querymask_RW; + u32 dma_tagstatus_R; + u32 pu_mb_R; + u32 spu_mb_W; + u32 mb_stat_R; + u32 spu_runcntl_RW; + u32 spu_status_R; + u32 spu_spc_R; + u32 spu_npc_RW; + u32 signal_notify1; + u32 signal_notify2; + u32 unused_pad1; +}; + +/* + * struct spu_priv1_collapsed - condensed privileged 1 area, w/o pads. + */ +struct spu_priv1_collapsed { + u64 mfc_sr1_RW; + u64 mfc_lpid_RW; + u64 spu_idr_RW; + u64 mfc_vr_RO; + u64 spu_vr_RO; + u64 int_mask_class0_RW; + u64 int_mask_class1_RW; + u64 int_mask_class2_RW; + u64 int_stat_class0_RW; + u64 int_stat_class1_RW; + u64 int_stat_class2_RW; + u64 int_route_RW; + u64 mfc_atomic_flush_RW; + u64 resource_allocation_groupID_RW; + u64 resource_allocation_enable_RW; + u64 mfc_fir_R; + u64 mfc_fir_status_or_W; + u64 mfc_fir_status_and_W; + u64 mfc_fir_mask_R; + u64 mfc_fir_mask_or_W; + u64 mfc_fir_mask_and_W; + u64 mfc_fir_chkstp_enable_RW; + u64 smf_sbi_signal_sel; + u64 smf_ato_signal_sel; + u64 mfc_sdr_RW; + u64 tlb_index_hint_RO; + u64 tlb_index_W; + u64 tlb_vpn_RW; + u64 tlb_rpn_RW; + u64 tlb_invalidate_entry_W; + u64 tlb_invalidate_all_W; + u64 smm_hid; + u64 mfc_accr_RW; + u64 mfc_dsisr_RW; + u64 mfc_dar_RW; + u64 rmt_index_RW; + u64 rmt_data1_RW; + u64 mfc_dsir_R; + u64 mfc_lsacr_RW; + u64 mfc_lscrr_R; + u64 mfc_tclass_id_RW; + u64 mfc_rm_boundary; + u64 smf_dma_signal_sel; + u64 smm_signal_sel; + u64 mfc_cer_R; + u64 pu_ecc_cntl_RW; + u64 pu_ecc_stat_RW; + u64 spu_ecc_addr_RW; + u64 spu_err_mask_RW; + u64 spu_trig0_sel; + u64 spu_trig1_sel; + u64 spu_trig2_sel; + u64 spu_trig3_sel; + u64 spu_trace_sel; + u64 spu_event0_sel; + u64 spu_event1_sel; + u64 spu_event2_sel; + u64 spu_event3_sel; + u64 spu_trace_cntl; +}; + +/* + * struct spu_priv2_collapsed - condensed priviliged 2 area, w/o pads. + */ +struct spu_priv2_collapsed { + u64 slb_index_W; + u64 slb_esid_RW; + u64 slb_vsid_RW; + u64 slb_invalidate_entry_W; + u64 slb_invalidate_all_W; + struct mfc_cq_sr spuq[16]; + struct mfc_cq_sr puq[8]; + u64 mfc_control_RW; + u64 puint_mb_R; + u64 spu_privcntl_RW; + u64 spu_lslr_RW; + u64 spu_chnlcntptr_RW; + u64 spu_chnlcnt_RW; + u64 spu_chnldata_RW; + u64 spu_cfg_RW; + u64 spu_pm_trace_tag_status_RW; + u64 spu_tag_status_query_RW; + u64 spu_cmd_buf1_RW; + u64 spu_cmd_buf2_RW; + u64 spu_atomic_status_RW; +}; + +/** + * struct spu_state + * @lscsa: Local Store Context Save Area. + * @prob: Collapsed Problem State Area, w/o pads. + * @priv1: Collapsed Privileged 1 Area, w/o pads. + * @priv2: Collapsed Privileged 2 Area, w/o pads. + * @spu_chnlcnt_RW: Array of saved channel counts. + * @spu_chnldata_RW: Array of saved channel data. + * @suspend_time: Time stamp when decrementer disabled. + * @slb_esid_RW: Array of saved SLB esid entries. + * @slb_vsid_RW: Array of saved SLB vsid entries. + * + * Structure representing the whole of the SPU + * context save area (CSA). This struct contains + * all of the state necessary to suspend and then + * later optionally resume execution of an SPU + * context. + * + * The @lscsa region is by far the largest, and is + * allocated separately so that it may either be + * pinned or mapped to/from application memory, as + * appropriate for the OS environment. + */ +struct spu_state { + struct spu_lscsa *lscsa; + struct spu_problem_collapsed prob; + struct spu_priv1_collapsed priv1; + struct spu_priv2_collapsed priv2; + u64 spu_chnlcnt_RW[32]; + u64 spu_chnldata_RW[32]; + u32 spu_mailbox_data[4]; + u32 pu_mailbox_data[1]; + unsigned long suspend_time; + u64 slb_esid_RW[8]; + u64 slb_vsid_RW[8]; +}; + +extern void spu_init_csa(struct spu_state *csa); +extern void spu_fini_csa(struct spu_state *csa); +extern int spu_save(struct spu_state *prev, struct spu *spu); +extern int spu_restore(struct spu_state *new, struct spu *spu); +extern int spu_switch(struct spu_state *prev, struct spu_state *new, + struct spu *spu); + +#endif /* __KERNEL__ */ +#endif /* !__ASSEMBLY__ */ +#endif /* _SPU_CSA_H_ */ From arnd at arndb.de Fri Aug 26 08:03:39 2005 From: arnd at arndb.de (Arnd Bergmann) Date: Fri, 26 Aug 2005 00:03:39 +0200 Subject: [PATCH 1/7] spufs: The SPU file system Message-ID: <200508260003.40865.arnd@arndb.de> This is a work-in-progress version of the SPU file system. Since the previous version, a lot of features have been added and a number of bugs has been fixed. We now support doing read() on the /run file to start executing code on an SPU. Some files have been added to give access to more hardware features, especially the signal notification channels. Most importantly, we now have a working context save and restore functionality for SPEs, which is written by Mark Nutter and will eventually lead to having a scheduler for SPUs in the kernel. Since this has grown the file system a lot, I now split it up into a few smaller patches. Within the next weeks, we will do some larger reworks on the code base, so this version is probably the last one that is binary compatible to the earlier releases. If you have specific requirements that are not met by spufs in its present incarnation, now would be a good time to tell us. Signed-off-by: Arnd Bergmann -- Documentation/filesystems/spufs.txt | 107 +++++ arch/ppc/kernel/ppc_ksyms.c | 1 arch/ppc64/kernel/Makefile | 1 arch/ppc64/kernel/spu_base.c | 733 ++++++++++++++++++++++++++++++++++++ arch/ppc64/mm/hash_utils.c | 1 fs/Kconfig | 10 fs/Makefile | 1 fs/spufs/Makefile | 3 fs/spufs/context.c | 67 +++ fs/spufs/file.c | 716 +++++++++++++++++++++++++++++++++++ fs/spufs/inode.c | 435 +++++++++++++++++++++ fs/spufs/spufs.h | 65 +++ include/asm-ppc64/spu.h | 473 +++++++++++++++++++++++ mm/memory.c | 2 14 files changed, 2614 insertions(+), 1 deletion(-) --- linux-cg.orig/Documentation/filesystems/spufs.txt 1969-12-31 19:00:00.000000000 -0500 +++ linux-cg/Documentation/filesystems/spufs.txt 2005-08-25 22:15:10.902980544 -0400 @@ -0,0 +1,107 @@ + *** The SPU file system *** + +Spufs is used to run code on the Synergistic Processing Units +of the Cell Processor (a.k.a Broadband Engine). + +The file system provides a name space similar to posix shared +memory or message queues. Users that have write permissions +on the file system can create directories in the spufs root. + +Every directory represents an SPU context, which is currently +mapped to a physical SPU, but that is going to change to a +virtualization scheme in future updates. + +An SPU context directory contains a predefined set of files +used for manipulating the state of the logical SPU. Users +can change permissions on those files, but not actually +add or remove files without removing the complete directory. + +The current set of files is: + +/mem the contents of the local store memory of the SPU. + This can be accessed like a regular shared memory + file and contains both code and data in the address + space of the SPU. + The implemented file operations currently are read(), + write() and mmap(). We will need our own address + space operations as soon as we allow the SPU context + to be scheduled away from the physical SPU into + page cache. + +/run A stub file that lets us do the spu_run() call. + spu_run suspends the current thread from the host + CPU and transfers the flow of execution to the SPU. + The spu_run call returns to the calling thread when a + state is entered that can not be handled by the kernel, + e.g. an error in the SPU code or an exit() from it. + When a signal is pending for the host CPU thread, the + ioctl is interrupted and the SPU stopped in order to + call the signal handler. + Currently, there are three different methods how + spu_run can be entered with the /run file: + - The spu_run() syscall (see other patch) + - ioctl(), as used in previous versions + - read(), to return only the status, while the npc + is updated in kernel or through the /npc file. + Very likely, the concept of the /run file will change + in the near future and it will be replaced with + something completely different. + +/mbox The first SPU to CPU communication mailbox. This file + is read-only and can be read in units of 32 bits. + The file can only be used in non-blocking mode and + it even poll() will not block on it. + When no data is available in the mailbox, read() returns + EAGAIN. + +/ibox The second SPU to CPU communication mailbox. This file + is similar to the first mailbox file, but can be read + in blocking I/O mode, and the poll familiy of system + calls can be used to wait for it. + +/wbox The CPU to SPU communation mailbox. It is write-only + can can be written in units of 32 bits. If the mailbox + is full, write() will block and poll can be used to + wait for it becoming empty again. + +/mbox_stat +/ibox_stat +/wbox_stat + Read-only files that contain the length of the current + queue, i.e. how many words can be read from mbox or + ibox or how many words can be written to wbox without + blocking. + The files can be read only in 4-byte units and return + a big-endian binary integer number. + +/npc The next program counter of the SPU. The representation + is an ASCII string with the numeric value of the + next instruction to be executed. It can be used in + read/write mode. + +/signal1 +/signal2 + The two signal notification channels of an SPU. These + are read-write files that operate on a 32 bit word, + similar to the npc file. + Writing to one of these files triggers an interrupt on + the SPU. The value writting to the signal files can + be read from the SPU through a channel read or from + host user space through the file. + After the value has been read by the SPU, it is reset + to zero. + +/signal1_type +/signal2_type + These two files change the behavior of the signal1 and + signal2 notification files. The contain a numerical + ASCII string which is read as either "1" or "0". + In mode 0 (overwrite), the hardware replaces the contents + of the signal channel with the data that is written to it. + in mode 1 (logical OR), the hardware accumulates the bits + that are subsequently written to it. + +There are also a number of files that are only there for +debugging purposes and give low-level access to hardware +registers of an SPE. These will certainly go away and +should not be considered official interfaces. --- linux-cg.orig/arch/ppc64/kernel/Makefile 2005-08-25 22:08:05.354980224 -0400 +++ linux-cg/arch/ppc64/kernel/Makefile 2005-08-25 22:20:30.523977744 -0400 @@ -53,6 +53,7 @@ obj-$(CONFIG_HVCS) += hvcserver.o obj-$(CONFIG_IBMVIO) += vio.o obj-$(CONFIG_XICS) += xics.o obj-$(CONFIG_MPIC) += mpic.o +obj-$(CONFIG_SPU_FS) += spu_base.o obj-$(CONFIG_PPC_PMAC) += pmac_setup.o pmac_feature.o pmac_pci.o \ pmac_time.o pmac_nvram.o pmac_low_i2c.o --- linux-cg.orig/arch/ppc64/kernel/spu_base.c 1969-12-31 19:00:00.000000000 -0500 +++ linux-cg/arch/ppc64/kernel/spu_base.c 2005-08-25 22:27:19.502976744 -0400 @@ -0,0 +1,733 @@ +/* + * Low-level SPU handling + * + * (C) Copyright IBM Deutschland Entwicklung GmbH 2005 + * + * Author: Arnd Bergmann + * + * 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, 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#define DEBUG 1 + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "bpa_iic.h" + +static int __spu_trap_invalid_dma(struct spu *spu) +{ + pr_debug("%s\n", __FUNCTION__); + force_sig(SIGBUS, /* info, */ current); + return 0; +} + +static int __spu_trap_dma_align(struct spu *spu) +{ + pr_debug("%s\n", __FUNCTION__); + force_sig(SIGBUS, /* info, */ current); + return 0; +} + +static int __spu_trap_error(struct spu *spu) +{ + pr_debug("%s\n", __FUNCTION__); + force_sig(SIGILL, /* info, */ current); + return 0; +} + +static void spu_restart_dma(struct spu *spu) +{ + struct spu_priv2 __iomem *priv2 = spu->priv2; + out_be64(&priv2->mfc_control_RW, MFC_CNTL_RESTART_DMA_COMMAND); +} + +static int __spu_trap_data_seg(struct spu *spu, unsigned long ea) +{ + struct spu_priv2 __iomem *priv2; + struct mm_struct *mm; + + pr_debug("%s\n", __FUNCTION__); + + if (REGION_ID(ea) != USER_REGION_ID) { + pr_debug("invalid region access at %016lx\n", ea); + return 1; + } + + priv2 = spu->priv2; + mm = spu->mm; + + if (spu->slb_replace >= 8) + spu->slb_replace = 0; + + out_be64(&priv2->slb_index_W, spu->slb_replace); + out_be64(&priv2->slb_vsid_RW, + (get_vsid(mm->context.id, ea) << SLB_VSID_SHIFT) + | SLB_VSID_USER); + out_be64(&priv2->slb_esid_RW, (ea & ESID_MASK) | SLB_ESID_V); + + spu_restart_dma(spu); + + pr_debug("set slb %d context %lx, ea %016lx, vsid %016lx, esid %016lx\n", + spu->slb_replace, mm->context.id, ea, + (get_vsid(mm->context.id, ea) << SLB_VSID_SHIFT)| SLB_VSID_USER, + (ea & ESID_MASK) | SLB_ESID_V); + return 0; +} + +static int __spu_trap_data_map(struct spu *spu, unsigned long ea) +{ + unsigned long dsisr; + struct spu_priv1 __iomem *priv1; + + pr_debug("%s\n", __FUNCTION__); + priv1 = spu->priv1; + dsisr = in_be64(&priv1->mfc_dsisr_RW); + + wake_up(&spu->stop_wq); + + return 0; +} + +static int __spu_trap_mailbox(struct spu *spu) +{ + wake_up_all(&spu->ibox_wq); + + /* atomically disable SPU mailbox interrupts */ + spin_lock(&spu->register_lock); + out_be64(&spu->priv1->int_mask_class2_RW, + in_be64(&spu->priv1->int_mask_class2_RW) & ~0x1); + spin_unlock(&spu->register_lock); + return 0; +} + +static int __spu_trap_stop(struct spu *spu) +{ + pr_debug("%s\n", __FUNCTION__); + spu->stop_code = in_be32(&spu->problem->spu_status_R); + wake_up(&spu->stop_wq); + return 0; +} + +static int __spu_trap_halt(struct spu *spu) +{ + pr_debug("%s\n", __FUNCTION__); + spu->stop_code = in_be32(&spu->problem->spu_status_R); + wake_up(&spu->stop_wq); + return 0; +} + +static int __spu_trap_tag_group(struct spu *spu) +{ + pr_debug("%s\n", __FUNCTION__); + /* wake_up(&spu->dma_wq); */ + return 0; +} + +static int __spu_trap_spubox(struct spu *spu) +{ + wake_up_all(&spu->wbox_wq); + + /* atomically disable SPU mailbox interrupts */ + spin_lock(&spu->register_lock); + out_be64(&spu->priv1->int_mask_class2_RW, + in_be64(&spu->priv1->int_mask_class2_RW) & ~0x10); + spin_unlock(&spu->register_lock); + return 0; +} + +static irqreturn_t +spu_irq_class_0(int irq, void *data, struct pt_regs *regs) +{ + struct spu *spu; + + spu = data; + spu->class_0_pending = 1; + wake_up(&spu->stop_wq); + + return IRQ_HANDLED; +} + +static int +spu_irq_class_0_bottom(struct spu *spu) +{ + unsigned long stat; + + spu->class_0_pending = 0; + + stat = in_be64(&spu->priv1->int_stat_class0_RW); + + if (stat & 1) /* invalid MFC DMA */ + __spu_trap_invalid_dma(spu); + + if (stat & 2) /* invalid DMA alignment */ + __spu_trap_dma_align(spu); + + if (stat & 4) /* error on SPU */ + __spu_trap_error(spu); + + out_be64(&spu->priv1->int_stat_class0_RW, stat); + return 0; +} + +static irqreturn_t +spu_irq_class_1(int irq, void *data, struct pt_regs *regs) +{ + struct spu *spu; + unsigned long stat, dar; + + spu = data; + stat = in_be64(&spu->priv1->int_stat_class1_RW); + dar = in_be64(&spu->priv1->mfc_dar_RW); + + if (stat & 1) /* segment fault */ + __spu_trap_data_seg(spu, dar); + + if (stat & 2) { /* mapping fault */ + __spu_trap_data_map(spu, dar); + } + + if (stat & 4) /* ls compare & suspend on get */ + ; + + if (stat & 8) /* ls compare & suspend on put */ + ; + + out_be64(&spu->priv1->int_stat_class1_RW, stat); + return stat ? IRQ_HANDLED : IRQ_NONE; +} + +static irqreturn_t +spu_irq_class_2(int irq, void *data, struct pt_regs *regs) +{ + struct spu *spu; + unsigned long stat; + + spu = data; + stat = in_be64(&spu->priv1->int_stat_class2_RW); + + pr_debug("class 2 interrupt %d, %lx, %lx\n", irq, stat, + in_be64(&spu->priv1->int_mask_class2_RW)); + + + if (stat & 1) /* PPC core mailbox */ + __spu_trap_mailbox(spu); + + if (stat & 2) /* SPU stop-and-signal */ + __spu_trap_stop(spu); + + if (stat & 4) /* SPU halted */ + __spu_trap_halt(spu); + + if (stat & 8) /* DMA tag group complete */ + __spu_trap_tag_group(spu); + + if (stat & 0x10) /* SPU mailbox threshold */ + __spu_trap_spubox(spu); + + out_be64(&spu->priv1->int_stat_class2_RW, stat); + return stat ? IRQ_HANDLED : IRQ_NONE; +} + +static int +spu_request_irqs(struct spu *spu) +{ + int ret; + int irq_base; + + irq_base = IIC_NODE_STRIDE * spu->node + IIC_SPE_OFFSET; + + snprintf(spu->irq_c0, sizeof (spu->irq_c0), "spe%02d.0", spu->number); + ret = request_irq(irq_base + spu->isrc, + spu_irq_class_0, 0, spu->irq_c0, spu); + if (ret) + goto out; + out_be64(&spu->priv1->int_mask_class0_RW, 0x7); + + snprintf(spu->irq_c1, sizeof (spu->irq_c1), "spe%02d.1", spu->number); + ret = request_irq(irq_base + IIC_CLASS_STRIDE + spu->isrc, + spu_irq_class_1, 0, spu->irq_c1, spu); + if (ret) + goto out1; + out_be64(&spu->priv1->int_mask_class1_RW, 0x3); + + snprintf(spu->irq_c2, sizeof (spu->irq_c2), "spe%02d.2", spu->number); + ret = request_irq(irq_base + 2*IIC_CLASS_STRIDE + spu->isrc, + spu_irq_class_2, 0, spu->irq_c2, spu); + if (ret) + goto out2; + out_be64(&spu->priv1->int_mask_class2_RW, 0xe); + goto out; + +out2: + free_irq(irq_base + IIC_CLASS_STRIDE + spu->isrc, spu); +out1: + free_irq(irq_base + spu->isrc, spu); +out: + return ret; +} + +static void +spu_free_irqs(struct spu *spu) +{ + int irq_base; + + irq_base = IIC_NODE_STRIDE * spu->node + IIC_SPE_OFFSET; + + free_irq(irq_base + spu->isrc, spu); + free_irq(irq_base + IIC_CLASS_STRIDE + spu->isrc, spu); + free_irq(irq_base + 2*IIC_CLASS_STRIDE + spu->isrc, spu); +} + +static LIST_HEAD(spu_list); +static DECLARE_MUTEX(spu_mutex); + +static void spu_init_channels(struct spu *spu) +{ + static const struct { + unsigned channel; + unsigned count; + } zero_list[] = { + { 0x00, 1, }, { 0x01, 1, }, { 0x03, 1, }, { 0x04, 1, }, + { 0x18, 1, }, { 0x19, 1, }, { 0x1b, 1, }, { 0x1d, 1, }, + }, count_list[] = { + { 0x00, 0, }, { 0x03, 0, }, { 0x04, 0, }, { 0x15, 16, }, + { 0x17, 1, }, { 0x18, 0, }, { 0x19, 0, }, { 0x1b, 0, }, + { 0x1c, 1, }, { 0x1d, 0, }, { 0x1e, 1, }, + }; + struct spu_priv2 *priv2; + int i; + + priv2 = spu->priv2; + + /* initialize all channel data to zero */ + for (i = 0; i < ARRAY_SIZE(zero_list); i++) { + int count; + + out_be64(&priv2->spu_chnlcntptr_RW, zero_list[i].channel); + for (count = 0; count < zero_list[i].count; count++) + out_be64(&priv2->spu_chnldata_RW, 0); + } + + /* initialize channel counts to meaningful values */ + for (i = 0; i < ARRAY_SIZE(count_list); i++) { + out_be64(&priv2->spu_chnlcntptr_RW, count_list[i].channel); + out_be64(&priv2->spu_chnlcnt_RW, count_list[i].count); + } +} + +static void spu_init_regs(struct spu *spu) +{ + out_be64(&spu->priv1->int_mask_class0_RW, 0x7); + out_be64(&spu->priv1->int_mask_class1_RW, 0x3); + out_be64(&spu->priv1->int_mask_class2_RW, 0xe); +} + +struct spu *spu_alloc(void) +{ + struct spu *spu; + + down(&spu_mutex); + if (!list_empty(&spu_list)) { + spu = list_entry(spu_list.next, struct spu, list); + list_del_init(&spu->list); + pr_debug("Got SPU %x %d\n", spu->isrc, spu->number); + } else { + pr_debug("No SPU left\n"); + spu = NULL; + } + up(&spu_mutex); + + if (spu) { + spu_init_channels(spu); + spu_init_regs(spu); + } + + return spu; +} +EXPORT_SYMBOL(spu_alloc); + +void spu_free(struct spu *spu) +{ + down(&spu_mutex); + list_add_tail(&spu->list, &spu_list); + up(&spu_mutex); +} +EXPORT_SYMBOL(spu_free); + +extern int hash_page(unsigned long ea, unsigned long access, unsigned long trap); //XXX +static int spu_handle_mm_fault(struct spu *spu) +{ + struct spu_priv1 __iomem *priv1; + struct mm_struct *mm = spu->mm; + struct vm_area_struct *vma; + u64 ea, dsisr, is_write; + int ret; + + priv1 = spu->priv1; + ea = in_be64(&priv1->mfc_dar_RW); + dsisr = in_be64(&priv1->mfc_dsisr_RW); +#if 0 + if (!IS_VALID_EA(ea)) { + return -EFAULT; + } +#endif /* XXX */ + if (mm == NULL) { + return -EFAULT; + } + if (mm->pgd == NULL) { + return -EFAULT; + } + + down_read(&mm->mmap_sem); + vma = find_vma(mm, ea); + if (!vma) + goto bad_area; + if (vma->vm_start <= ea) + goto good_area; + if (!(vma->vm_flags & VM_GROWSDOWN)) + goto bad_area; +#if 0 + if (expand_stack(vma, ea)) + goto bad_area; +#endif /* XXX */ +good_area: + is_write = dsisr & MFC_DSISR_ACCESS_PUT; + if (is_write) { + if (!(vma->vm_flags & VM_WRITE)) + goto bad_area; + } else { + if (dsisr & MFC_DSISR_ACCESS_DENIED) + goto bad_area; + if (!(vma->vm_flags & (VM_READ | VM_EXEC))) + goto bad_area; + } + ret = 0; + switch (handle_mm_fault(mm, vma, ea, is_write)) { + case VM_FAULT_MINOR: + current->min_flt++; + break; + case VM_FAULT_MAJOR: + current->maj_flt++; + break; + case VM_FAULT_SIGBUS: + ret = -EFAULT; + goto bad_area; + case VM_FAULT_OOM: + ret = -ENOMEM; + goto bad_area; + default: + BUG(); + } + up_read(&mm->mmap_sem); + return ret; + +bad_area: + up_read(&mm->mmap_sem); + return -EFAULT; +} + +static int spu_handle_pte_fault(struct spu *spu) +{ + struct spu_priv1 __iomem *priv1; + u64 ea, dsisr, access, error = 0UL; + int ret = 0; + + priv1 = spu->priv1; + ea = in_be64(&priv1->mfc_dar_RW); + dsisr = in_be64(&priv1->mfc_dsisr_RW); + access = (_PAGE_PRESENT | _PAGE_USER); + if (dsisr & MFC_DSISR_PTE_NOT_FOUND) { + if (hash_page(ea, access, 0x300) != 0) + error |= CLASS1_ENABLE_STORAGE_FAULT_INTR; + } + if ((error & CLASS1_ENABLE_STORAGE_FAULT_INTR) || + (dsisr & MFC_DSISR_ACCESS_DENIED)) { + if ((ret = spu_handle_mm_fault(spu)) != 0) + error |= CLASS1_ENABLE_STORAGE_FAULT_INTR; + else + error &= ~CLASS1_ENABLE_STORAGE_FAULT_INTR; + } + if (!error) + spu_restart_dma(spu); + + return ret; +} + +int spu_run(struct spu *spu) +{ + struct spu_problem __iomem *prob; + struct spu_priv1 __iomem *priv1; + struct spu_priv2 __iomem *priv2; + unsigned long status; + int ret; + + prob = spu->problem; + priv1 = spu->priv1; + priv2 = spu->priv2; + + /* Let SPU run. */ + spu->mm = current->mm; + eieio(); + out_be32(&prob->spu_runcntl_RW, SPU_RUNCNTL_RUNNABLE); + + do { + ret = wait_event_interruptible(spu->stop_wq, + (!((status = in_be32(&prob->spu_status_R)) & 0x1)) + || (in_be64(&priv1->mfc_dsisr_RW) & MFC_DSISR_PTE_NOT_FOUND) + || spu->class_0_pending); + + if (status & SPU_STATUS_STOPPED_BY_STOP) + ret = -EAGAIN; + else if (status & SPU_STATUS_STOPPED_BY_HALT) + ret = -EIO; + else if (in_be64(&priv1->mfc_dsisr_RW) & MFC_DSISR_PTE_NOT_FOUND) + ret = spu_handle_pte_fault(spu); + + if (spu->class_0_pending) + spu_irq_class_0_bottom(spu); + + if (!ret && signal_pending(current)) + ret = -ERESTARTSYS; + + } while (!ret); + + /* Ensure SPU is stopped. */ + out_be32(&prob->spu_runcntl_RW, SPU_RUNCNTL_STOP); + eieio(); + while (in_be32(&prob->spu_status_R) & SPU_STATUS_RUNNING) + cpu_relax(); + + out_be64(&priv2->slb_invalidate_all_W, 0); + out_be64(&priv1->tlb_invalidate_entry_W, 0UL); + eieio(); + + spu->mm = NULL; + + /* Check for SPU breakpoint. */ + if (unlikely(current->ptrace & PT_PTRACED)) { + status = in_be32(&prob->spu_status_R); + + if ((status & SPU_STATUS_STOPPED_BY_STOP) + && status >> SPU_STOP_STATUS_SHIFT == 0x3fff) { + force_sig(SIGTRAP, current); + ret = -ERESTARTSYS; + } + } + + return ret; +} +EXPORT_SYMBOL(spu_run); + +static void __iomem * __init map_spe_prop(struct device_node *n, + const char *name) +{ + struct address_prop { + unsigned long address; + unsigned int len; + } __attribute__((packed)) *prop; + + void *p; + int proplen; + + p = get_property(n, name, &proplen); + if (proplen != sizeof (struct address_prop)) + return NULL; + + prop = p; + + return ioremap(prop->address, prop->len); +} + +static void spu_unmap(struct spu *spu) +{ + iounmap(spu->priv2); + iounmap(spu->priv1); + iounmap(spu->problem); + iounmap((u8 __iomem *)spu->local_store); +} + +static int __init spu_map_device(struct spu *spu, struct device_node *spe) +{ + char *prop; + int ret; + + ret = -ENODEV; + prop = get_property(spe, "isrc", NULL); + if (!prop) + goto out; + spu->isrc = *(unsigned int *)prop; + + spu->name = get_property(spe, "name", NULL); + if (!spu->name) + goto out; + + prop = get_property(spe, "local-store", NULL); + if (!prop) + goto out; + spu->local_store_phys = *(unsigned long *)prop; + + /* we use local store as ram, not io memory */ + spu->local_store = (void __force *)map_spe_prop(spe, "local-store"); + if (!spu->local_store) + goto out; + + spu->problem= map_spe_prop(spe, "problem"); + if (!spu->problem) + goto out_unmap; + + spu->priv1= map_spe_prop(spe, "priv1"); + if (!spu->priv1) + goto out_unmap; + + spu->priv2= map_spe_prop(spe, "priv2"); + if (!spu->priv2) + goto out_unmap; + ret = 0; + goto out; + +out_unmap: + spu_unmap(spu); +out: + return ret; +} + +static int __init find_spu_node_id(struct device_node *spe) +{ + unsigned int *id; + struct device_node *cpu; + + cpu = spe->parent->parent; + id = (unsigned int *)get_property(cpu, "node-id", NULL); + + return id ? *id : 0; +} + +static int __init create_spu(struct device_node *spe) +{ + struct spu *spu; + int ret; + static int number; + + ret = -ENOMEM; + spu = kmalloc(sizeof (*spu), GFP_KERNEL); + if (!spu) + goto out; + + ret = spu_map_device(spu, spe); + if (ret) + goto out_free; + + spu->node = find_spu_node_id(spe); + spu->stop_code = 0; + spu->slb_replace = 0; + spu->mm = NULL; + spu->class_0_pending = 0; + spin_lock_init(&spu->register_lock); + + out_be64(&spu->priv1->mfc_sdr_RW, mfspr(SPRN_SDR1)); + out_be64(&spu->priv1->mfc_sr1_RW, 0x33); + + init_waitqueue_head(&spu->stop_wq); + init_waitqueue_head(&spu->wbox_wq); + init_waitqueue_head(&spu->ibox_wq); + + down(&spu_mutex); + spu->number = number++; + ret = spu_request_irqs(spu); + if (ret) + goto out_unmap; + + list_add(&spu->list, &spu_list); + up(&spu_mutex); + + pr_debug(KERN_DEBUG "Using SPE %s %02x %p %p %p %p %d\n", + spu->name, spu->isrc, spu->local_store, + spu->problem, spu->priv1, spu->priv2, spu->number); + goto out; + +out_unmap: + up(&spu_mutex); + spu_unmap(spu); +out_free: + kfree(spu); +out: + return ret; +} + +static void destroy_spu(struct spu *spu) +{ + list_del_init(&spu->list); + + spu_free_irqs(spu); + spu_unmap(spu); + kfree(spu); +} + +static void cleanup_spu_base(void) +{ + struct spu *spu, *tmp; + down(&spu_mutex); + list_for_each_entry_safe(spu, tmp, &spu_list, list) + destroy_spu(spu); + up(&spu_mutex); +} +module_exit(cleanup_spu_base); + +static int __init init_spu_base(void) +{ + struct device_node *node; + int ret; + + ret = -ENODEV; + for (node = of_find_node_by_type(NULL, "spe"); + node; node = of_find_node_by_type(node, "spe")) { + ret = create_spu(node); + if (ret) { + printk(KERN_WARNING "%s: Error initializing %s\n", + __FUNCTION__, node->name); + cleanup_spu_base(); + break; + } + } + /* in some old firmware versions, the spe is called 'spc', so we + look for that as well */ + for (node = of_find_node_by_type(NULL, "spc"); + node; node = of_find_node_by_type(node, "spc")) { + ret = create_spu(node); + if (ret) { + printk(KERN_WARNING "%s: Error initializing %s\n", + __FUNCTION__, node->name); + cleanup_spu_base(); + break; + } + } + return ret; +} +module_init(init_spu_base); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Arnd Bergmann "); --- linux-cg.orig/arch/ppc64/mm/hash_utils.c 2005-08-25 22:08:05.359979464 -0400 +++ linux-cg/arch/ppc64/mm/hash_utils.c 2005-08-25 22:15:10.906979936 -0400 @@ -354,6 +354,7 @@ int hash_page(unsigned long ea, unsigned return ret; } +EXPORT_SYMBOL_GPL(hash_page); void flush_hash_page(unsigned long context, unsigned long ea, pte_t pte, int local) --- linux-cg.orig/fs/Kconfig 2005-08-25 22:08:05.361979160 -0400 +++ linux-cg/fs/Kconfig 2005-08-25 22:15:10.908979632 -0400 @@ -845,6 +845,16 @@ config HUGETLBFS config HUGETLB_PAGE def_bool HUGETLBFS +config SPU_FS + tristate "SPU file system" + default m + depends on PPC_BPA + help + The SPU file system is used to access Synergistic Processing + Units on machines implementing the Broadband Processor + Architecture. + + config RAMFS bool default y --- linux-cg.orig/fs/Makefile 2005-08-25 22:08:05.363978856 -0400 +++ linux-cg/fs/Makefile 2005-08-25 22:15:10.908979632 -0400 @@ -98,3 +98,4 @@ obj-$(CONFIG_BEFS_FS) += befs/ obj-$(CONFIG_HOSTFS) += hostfs/ obj-$(CONFIG_HPPFS) += hppfs/ obj-$(CONFIG_DEBUG_FS) += debugfs/ +obj-$(CONFIG_SPU_FS) += spufs/ --- linux-cg.orig/fs/spufs/Makefile 1969-12-31 19:00:00.000000000 -0500 +++ linux-cg/fs/spufs/Makefile 2005-08-25 22:20:31.628941784 -0400 @@ -0,0 +1,3 @@ +obj-$(CONFIG_SPU_FS) += spufs.o + +spufs-y += inode.o file.o context.o --- linux-cg.orig/fs/spufs/context.c 1969-12-31 19:00:00.000000000 -0500 +++ linux-cg/fs/spufs/context.c 2005-08-25 22:20:31.631941328 -0400 @@ -0,0 +1,67 @@ +/* + * SPU file system -- SPU context management + * + * (C) Copyright IBM Deutschland Entwicklung GmbH 2005 + * + * Author: Arnd Bergmann + * + * 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, 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include "spufs.h" + +struct spu_context *alloc_spu_context(void) +{ + struct spu_context *ctx; + ctx = kmalloc(sizeof *ctx, GFP_KERNEL); + if (!ctx) + goto out; + ctx->spu = spu_alloc(); + if (!ctx->spu) + goto out_free; + init_rwsem(&ctx->backing_sema); + spin_lock_init(&ctx->mmio_lock); + kref_init(&ctx->kref); + goto out; +out_free: + kfree(ctx); + ctx = NULL; +out: + return ctx; +} + +void destroy_spu_context(struct kref *kref) +{ + struct spu_context *ctx; + ctx = container_of(kref, struct spu_context, kref); + if (ctx->spu) + spu_free(ctx->spu); + kfree(ctx); +} + +struct spu_context * get_spu_context(struct spu_context *ctx) +{ + kref_get(&ctx->kref); + return ctx; +} + +void put_spu_context(struct spu_context *ctx) +{ + kref_put(&ctx->kref, &destroy_spu_context); +} + + --- linux-cg.orig/fs/spufs/file.c 1969-12-31 19:00:00.000000000 -0500 +++ linux-cg/fs/spufs/file.c 2005-08-25 22:27:19.503976592 -0400 @@ -0,0 +1,716 @@ +/* + * SPU file system -- file contents + * + * (C) Copyright IBM Deutschland Entwicklung GmbH 2005 + * + * Author: Arnd Bergmann + * + * 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, 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "spufs.h" + +static int +spufs_mem_open(struct inode *inode, struct file *file) +{ + struct spufs_inode_info *i = SPUFS_I(inode); + file->private_data = i->i_ctx; + return 0; +} + +static ssize_t +spufs_mem_read(struct file *file, char __user *buffer, + size_t size, loff_t *pos) +{ + struct spu *spu; + struct spu_context *ctx; + int ret; + + ctx = file->private_data; + spu = ctx->spu; + + down_read(&ctx->backing_sema); + if (spu->number & 0/*1*/) { + ret = generic_file_read(file, buffer, size, pos); + goto out; + } + + ret = simple_read_from_buffer(buffer, size, pos, + spu->local_store, LS_SIZE); +out: + up_read(&ctx->backing_sema); + return ret; +} + +static ssize_t +spufs_mem_write(struct file *file, const char __user *buffer, + size_t size, loff_t *pos) +{ + struct spu_context *ctx = file->private_data; + struct spu *spu = ctx->spu; + + if (spu->number & 0) //1) + return generic_file_write(file, buffer, size, pos); + + size = min_t(ssize_t, LS_SIZE - *pos, size); + if (size <= 0) + return -EFBIG; + *pos += size; + return copy_from_user(spu->local_store + *pos - size, + buffer, size) ? -EFAULT : size; +} + +static int +spufs_mem_mmap(struct file *file, struct vm_area_struct *vma) +{ + struct spu_context *ctx = file->private_data; + struct spu *spu = ctx->spu; + unsigned long pfn; + + if (spu->number & 0) //1) + return generic_file_mmap(file, vma); + + vma->vm_flags |= VM_RESERVED; + vma->vm_page_prot = __pgprot(pgprot_val (vma->vm_page_prot) + | _PAGE_NO_CACHE); + pfn = spu->local_store_phys >> PAGE_SHIFT; + /* + * This will work for actual SPUs, but not for vmalloc memory: + */ + if (remap_pfn_range(vma, vma->vm_start, pfn, + vma->vm_end-vma->vm_start, vma->vm_page_prot)) + return -EAGAIN; + return 0; +} + +static struct file_operations spufs_mem_fops = { + .open = spufs_mem_open, + .read = spufs_mem_read, + .write = spufs_mem_write, + .mmap = spufs_mem_mmap, + .llseek = generic_file_llseek, +}; + +/* generic open function for all pipe-like files */ +static int spufs_pipe_open(struct inode *inode, struct file *file) +{ + struct spufs_inode_info *i = SPUFS_I(inode); + file->private_data = i->i_ctx; + + return nonseekable_open(inode, file); +} + +static ssize_t spufs_mbox_read(struct file *file, char __user *buf, + size_t len, loff_t *pos) +{ + struct spu_context *ctx; + struct spu_problem __iomem *prob; + u32 mbox_stat; + u32 mbox_data; + + if (len < 4) + return -EINVAL; + + ctx = file->private_data; + prob = ctx->spu->problem; + mbox_stat = in_be32(&prob->mb_stat_R); + if (!(mbox_stat & 0x0000ff)) + return -EAGAIN; + + mbox_data = in_be32(&prob->pu_mb_R); + + if (copy_to_user(buf, &mbox_data, sizeof mbox_data)) + return -EFAULT; + + return 4; +} + +static struct file_operations spufs_mbox_fops = { + .open = spufs_pipe_open, + .read = spufs_mbox_read, +}; + +static ssize_t spufs_mbox_stat_read(struct file *file, char __user *buf, + size_t len, loff_t *pos) +{ + struct spu_context *ctx; + u32 mbox_stat; + + if (len < 4) + return -EINVAL; + + ctx = file->private_data; + mbox_stat = in_be32(&ctx->spu->problem->mb_stat_R) & 0xff; + + if (copy_to_user(buf, &mbox_stat, sizeof mbox_stat)) + return -EFAULT; + + return 4; +} + +static struct file_operations spufs_mbox_stat_fops = { + .open = spufs_pipe_open, + .read = spufs_mbox_stat_read, +}; + +/* low-level ibox access function */ +size_t spu_ibox_read(struct spu *spu, u32 *data) +{ + int ret; + + spin_lock_irq(&spu->register_lock); + + if (in_be32(&spu->problem->mb_stat_R) & 0xff0000) { + /* read the first available word */ + *data = in_be64(&spu->priv2->puint_mb_R); + ret = 4; + } else { + /* make sure we get woken up by the interrupt */ + out_be64(&spu->priv1->int_mask_class2_RW, + in_be64(&spu->priv1->int_mask_class2_RW) | 0x1); + ret = 0; + } + + spin_unlock_irq(&spu->register_lock); + return ret; +} +EXPORT_SYMBOL(spu_ibox_read); + +static ssize_t spufs_ibox_read(struct file *file, char __user *buf, + size_t len, loff_t *pos) +{ + struct spu_context *ctx; + u32 ibox_data; + ssize_t ret; + + if (len < 4) + return -EINVAL; + + ctx = file->private_data; + + ret = 0; + if (file->f_flags & O_NONBLOCK) { + if (!spu_ibox_read(ctx->spu, &ibox_data)) + ret = -EAGAIN; + } else { + ret = wait_event_interruptible(ctx->spu->ibox_wq, + spu_ibox_read(ctx->spu, &ibox_data)); + } + + if (ret) + return ret; + + ret = 4; + if (copy_to_user(buf, &ibox_data, sizeof ibox_data)) + ret = -EFAULT; + + return ret; +} + +static unsigned int spufs_ibox_poll(struct file *file, poll_table *wait) +{ + struct spu_context *ctx; + struct spu_problem __iomem *prob; + u32 mbox_stat; + unsigned int mask; + + ctx = file->private_data; + prob = ctx->spu->problem; + mbox_stat = in_be32(&prob->mb_stat_R); + + poll_wait(file, &ctx->spu->ibox_wq, wait); + + mask = 0; + if (mbox_stat & 0xff0000) + mask |= POLLIN | POLLRDNORM; + + return mask; +} + +static struct file_operations spufs_ibox_fops = { + .open = spufs_pipe_open, + .read = spufs_ibox_read, + .poll = spufs_ibox_poll, +}; + +static ssize_t spufs_ibox_stat_read(struct file *file, char __user *buf, + size_t len, loff_t *pos) +{ + struct spu_context *ctx; + u32 ibox_stat; + + if (len < 4) + return -EINVAL; + + ctx = file->private_data; + ibox_stat = (in_be32(&ctx->spu->problem->mb_stat_R) >> 16) & 0xff; + + if (copy_to_user(buf, &ibox_stat, sizeof ibox_stat)) + return -EFAULT; + + return 4; +} + +static struct file_operations spufs_ibox_stat_fops = { + .open = spufs_pipe_open, + .read = spufs_ibox_stat_read, +}; + +/* low-level mailbox write */ +size_t spu_wbox_write(struct spu *spu, u32 data) +{ + int ret; + + spin_lock_irq(&spu->register_lock); + + if (in_be32(&spu->problem->mb_stat_R) & 0x00ff00) { + /* we have space to write wbox_data to */ + out_be32(&spu->problem->spu_mb_W, data); + ret = 4; + } else { + /* make sure we get woken up by the interrupt when space + becomes available */ + out_be64(&spu->priv1->int_mask_class2_RW, + in_be64(&spu->priv1->int_mask_class2_RW) | 0x10); + ret = 0; + } + + spin_unlock_irq(&spu->register_lock); + return ret; +} +EXPORT_SYMBOL(spu_wbox_write); + +static ssize_t spufs_wbox_write(struct file *file, const char __user *buf, + size_t len, loff_t *pos) +{ + struct spu_context *ctx; + u32 wbox_data; + int ret; + + if (len < 4) + return -EINVAL; + + ctx = file->private_data; + + if (copy_from_user(&wbox_data, buf, sizeof wbox_data)) + return -EFAULT; + + ret = 0; + if (file->f_flags & O_NONBLOCK) { + if (!spu_wbox_write(ctx->spu, wbox_data)) + ret = -EAGAIN; + } else { + ret = wait_event_interruptible(ctx->spu->wbox_wq, + spu_wbox_write(ctx->spu, wbox_data)); + } + + return ret ? ret : sizeof wbox_data; +} + +static unsigned int spufs_wbox_poll(struct file *file, poll_table *wait) +{ + struct spu_context *ctx; + struct spu_problem __iomem *prob; + u32 mbox_stat; + unsigned int mask; + + ctx = file->private_data; + prob = ctx->spu->problem; + mbox_stat = in_be32(&prob->mb_stat_R); + + poll_wait(file, &ctx->spu->wbox_wq, wait); + + mask = 0; + if (mbox_stat & 0x00ff00) + mask = POLLOUT | POLLWRNORM; + + return mask; +} + +static struct file_operations spufs_wbox_fops = { + .open = spufs_pipe_open, + .write = spufs_wbox_write, + .poll = spufs_wbox_poll, +}; + +static ssize_t spufs_wbox_stat_read(struct file *file, char __user *buf, + size_t len, loff_t *pos) +{ + struct spu_context *ctx; + u32 wbox_stat; + + if (len < 4) + return -EINVAL; + + ctx = file->private_data; + wbox_stat = (in_be32(&ctx->spu->problem->mb_stat_R) >> 8) & 0xff; + + if (copy_to_user(buf, &wbox_stat, sizeof wbox_stat)) + return -EFAULT; + + return 4; +} + +static struct file_operations spufs_wbox_stat_fops = { + .open = spufs_pipe_open, + .read = spufs_wbox_stat_read, +}; + +static long spufs_run_spu(struct file *file, struct spu_context *ctx, + u32 *npc, u32 *status) +{ + struct spu_problem __iomem *prob; + int ret; + + if (file->f_flags & O_NONBLOCK) { + ret = -EAGAIN; + if (!down_write_trylock(&ctx->backing_sema)) + goto out; + } else { + down_write(&ctx->backing_sema); + } + + prob = ctx->spu->problem; + out_be32(&prob->spu_npc_RW, *npc); + + ret = spu_run(ctx->spu); + + *status = in_be32(&prob->spu_status_R); + *npc = in_be32(&prob->spu_npc_RW); + + up_write(&ctx->backing_sema); + +out: + return ret; +} + +struct spufs_run_arg { + u32 npc; /* inout: Next Program Counter */ + u32 status; /* out: SPU status */ +}; + +static ssize_t spufs_run_read(struct file *file, char __user *buf, + size_t len, loff_t *pos) +{ + struct spu_context *ctx; + struct spufs_run_arg arg; + int ret; + + ctx = file->private_data; + + ret = -EINVAL; + if (len < 8) + goto out; + + arg.npc = in_be32(&ctx->spu->problem->spu_npc_RW); + + ret = spufs_run_spu(file, file->private_data, &arg.npc, &arg.status); + if (ret == -EAGAIN) + ret = 0; + + if ((arg.status & 0xffff0002) == 0x21000002) { + /* library callout */ + u32 npc = arg.npc; + arg.npc = *(u32*) (ctx->spu->local_store + npc); + npc += 4; + out_be32(&ctx->spu->problem->spu_npc_RW, npc); + } + + if (ret) + goto out; + + ret = 8; + if (copy_to_user(buf, &arg, 8)) + ret = -EFAULT; + +out: + return ret; +} + +/* either this ioctl function or the system call needs to die! */ +static long spufs_run_ioctl(struct file *file, unsigned int num, + unsigned long arg) +{ + struct spufs_run_arg data; + int ret; + + if (num != _IOWR('s', 0, struct spufs_run_arg)) + return -EINVAL; + + if (copy_from_user(&data, (void __user *)arg, sizeof data)) + return -EFAULT; + + ret = spufs_run_spu(file, file->private_data, + &data.npc, &data.status); + + if (copy_to_user((void __user *)arg, &data, sizeof data)) + ret = -EFAULT; + + return ret; +} + +static struct file_operations spufs_run_fops = { + .open = spufs_pipe_open, + .unlocked_ioctl = spufs_run_ioctl, + .compat_ioctl = spufs_run_ioctl, + .read = spufs_run_read, +}; + +static ssize_t spufs_signal1_read(struct file *file, char __user *buf, + size_t len, loff_t *pos) +{ + struct spu_context *ctx; + struct spu_problem *prob; + u32 data; + + ctx = file->private_data; + prob = ctx->spu->problem; + + if (len < 4) + return -EINVAL; + + data = in_be32(&prob->signal_notify1); + if (copy_to_user(buf, &data, 4)) + return -EFAULT; + + return 4; +} + +static ssize_t spufs_signal1_write(struct file *file, const char __user *buf, + size_t len, loff_t *pos) +{ + struct spu_context *ctx; + struct spu_problem *prob; + u32 data; + + ctx = file->private_data; + prob = ctx->spu->problem; + + if (len < 4) + return -EINVAL; + + if (copy_from_user(&data, buf, 4)) + return -EFAULT; + + out_be32(&prob->signal_notify1, data); + + return 4; +} + +static struct file_operations spufs_signal1_fops = { + .open = spufs_pipe_open, + .read = spufs_signal1_read, + .write = spufs_signal1_write, +}; + +static ssize_t spufs_signal2_read(struct file *file, char __user *buf, + size_t len, loff_t *pos) +{ + struct spu_context *ctx; + struct spu_problem *prob; + u32 data; + + ctx = file->private_data; + prob = ctx->spu->problem; + + if (len < 4) + return -EINVAL; + + data = in_be32(&prob->signal_notify2); + if (copy_to_user(buf, &data, 4)) + return -EFAULT; + + return 4; +} + +static ssize_t spufs_signal2_write(struct file *file, const char __user *buf, + size_t len, loff_t *pos) +{ + struct spu_context *ctx; + struct spu_problem *prob; + u32 data; + + ctx = file->private_data; + prob = ctx->spu->problem; + + if (len < 4) + return -EINVAL; + + if (copy_from_user(&data, buf, 4)) + return -EFAULT; + + out_be32(&prob->signal_notify2, data); + + return 4; +} + +static struct file_operations spufs_signal2_fops = { + .open = spufs_pipe_open, + .read = spufs_signal2_read, + .write = spufs_signal2_write, +}; + +static void spufs_signal1_type_set(void *data, u64 val) +{ + struct spu_context *ctx = data; + struct spu_priv2 *priv2 = ctx->spu->priv2; + u64 tmp; + + spin_lock_irq(&ctx->spu->register_lock); + tmp = in_be64(&priv2->spu_cfg_RW); + if (val) + tmp |= 1; + else + tmp &= ~1; + out_be64(&priv2->spu_cfg_RW, tmp); + spin_unlock_irq(&ctx->spu->register_lock); +} + +static u64 spufs_signal1_type_get(void *data) +{ + struct spu_context *ctx = data; + return (in_be64(&ctx->spu->priv2->spu_cfg_RW) & 1) != 0; +} +DEFINE_SIMPLE_ATTRIBUTE(spufs_signal1_type, spufs_signal1_type_get, + spufs_signal1_type_set, "%llu"); + +static void spufs_signal2_type_set(void *data, u64 val) +{ + struct spu_context *ctx = data; + struct spu_priv2 *priv2 = ctx->spu->priv2; + u64 tmp; + + spin_lock_irq(&ctx->spu->register_lock); + tmp = in_be64(&priv2->spu_cfg_RW); + if (val) + tmp |= 2; + else + tmp &= ~2; + out_be64(&priv2->spu_cfg_RW, tmp); + spin_unlock_irq(&ctx->spu->register_lock); +} + +static u64 spufs_signal2_type_get(void *data) +{ + struct spu_context *ctx = data; + return (in_be64(&ctx->spu->priv2->spu_cfg_RW) & 2) != 0; +} +DEFINE_SIMPLE_ATTRIBUTE(spufs_signal2_type, spufs_signal2_type_get, + spufs_signal2_type_set, "%llu"); + +#define prob_attr(name) \ +static void spufs_ ## name ## _set(void *data, u64 val) \ +{ \ + struct spu_context *ctx = data; \ + out_be32(&ctx->spu->problem->name, val); \ +} \ +static u64 spufs_ ## name ## _get(void *data) \ +{ \ + struct spu_context *ctx = data; \ + return in_be32(&ctx->spu->problem->name); \ +} \ +DEFINE_SIMPLE_ATTRIBUTE(spufs_ ## name, \ + spufs_ ## name ## _get, \ + spufs_ ## name ## _set, "%llx\n") + +#define priv1_attr(name) \ +static void spufs_ ## name ## _set(void *data, u64 val) \ +{ \ + struct spu_context *ctx = data; \ + out_be64(&ctx->spu->priv1->name, val); \ +} \ +static u64 spufs_ ## name ## _get(void *data) \ +{ \ + struct spu_context *ctx = data; \ + return in_be64(&ctx->spu->priv1->name); \ +} \ +DEFINE_SIMPLE_ATTRIBUTE(spufs_ ## name, \ + spufs_ ## name ## _get, \ + spufs_ ## name ## _set, "%llx\n") + +#define priv2_attr(name) \ +static void spufs_ ## name ## _set(void *data, u64 val) \ +{ \ + struct spu_context *ctx = data; \ + out_be64(&ctx->spu->priv2->name, val); \ +} \ +static u64 spufs_ ## name ## _get(void *data) \ +{ \ + struct spu_context *ctx = data; \ + return in_be64(&ctx->spu->priv2->name); \ +} \ +DEFINE_SIMPLE_ATTRIBUTE(spufs_ ## name, \ + spufs_ ## name ## _get, \ + spufs_ ## name ## _set, "%llx\n") + +prob_attr(mb_stat_R); +prob_attr(spu_npc_RW); + +priv1_attr(int_stat_class0_RW); +priv1_attr(int_stat_class1_RW); +priv1_attr(int_stat_class2_RW); + +priv1_attr(int_mask_class0_RW); +priv1_attr(int_mask_class1_RW); +priv1_attr(int_mask_class2_RW); + +priv1_attr(mfc_sr1_RW); +priv1_attr(mfc_cer_R); +priv1_attr(mfc_dsisr_RW); +priv1_attr(mfc_dsir_R); +priv1_attr(mfc_sdr_RW); +priv2_attr(mfc_control_RW); + +struct tree_descr spufs_dir_contents[] = { + { "mem", &spufs_mem_fops, 0666, }, + { "run", &spufs_run_fops, 0444, }, + { "mbox", &spufs_mbox_fops, 0444, }, + { "ibox", &spufs_ibox_fops, 0444, }, + { "wbox", &spufs_wbox_fops, 0222, }, + { "mbox_stat", &spufs_mbox_stat_fops, 0444, }, + { "ibox_stat", &spufs_ibox_stat_fops, 0444, }, + { "wbox_stat", &spufs_wbox_stat_fops, 0444, }, + { "signal1", &spufs_signal1_fops, 0666, }, + { "signal2", &spufs_signal2_fops, 0666, }, + { "signal1_type", &spufs_signal1_type, 0666, }, + { "signal2_type", &spufs_signal2_type, 0666, }, + { "npc", &spufs_spu_npc_RW, 0666, }, +#if 1 /* debugging only */ + { "mb_stat", &spufs_mb_stat_R, 0444, }, + { "class0_mask", &spufs_int_mask_class0_RW, 0666, }, + { "class1_mask", &spufs_int_mask_class1_RW, 0666, }, + { "class2_mask", &spufs_int_mask_class2_RW, 0666, }, + { "class0_stat", &spufs_int_stat_class0_RW, 0666, }, + { "class1_stat", &spufs_int_stat_class1_RW, 0666, }, + { "class2_stat", &spufs_int_stat_class2_RW, 0666, }, + { "sr1", &spufs_mfc_sr1_RW, 0666, }, + { "cer", &spufs_mfc_cer_R, 0444, }, + { "dsisr", &spufs_mfc_dsisr_RW, 0666, }, + { "dsir", &spufs_mfc_dsir_R, 0222, }, + { "cntl", &spufs_mfc_control_RW, 0666, }, + { "sdr", &spufs_mfc_sdr_RW, 0666, }, +#endif + {}, +}; --- linux-cg.orig/fs/spufs/inode.c 1969-12-31 19:00:00.000000000 -0500 +++ linux-cg/fs/spufs/inode.c 2005-08-25 22:15:10.914978720 -0400 @@ -0,0 +1,435 @@ +/* + * SPU file system + * + * (C) Copyright IBM Deutschland Entwicklung GmbH 2005 + * + * Author: Arnd Bergmann + * + * 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, 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "spufs.h" + +static kmem_cache_t *spufs_inode_cache; + +/* Information about the backing dev, same as ramfs */ +#if 0 +static struct backing_dev_info spufs_backing_dev_info = { + .ra_pages = 0, /* No readahead */ + .capabilities = BDI_CAP_NO_ACCT_DIRTY | BDI_CAP_NO_WRITEBACK | + BDI_CAP_MAP_DIRECT | BDI_CAP_MAP_COPY | BDI_CAP_READ_MAP | + BDI_CAP_WRITE_MAP, +}; + +static struct address_space_operations spufs_aops = { + .readpage = simple_readpage, + .prepare_write = simple_prepare_write, + .commit_write = simple_commit_write, +}; +#endif + +/* Inode operations */ + +static struct inode * +spufs_alloc_inode(struct super_block *sb) +{ + struct spufs_inode_info *ei; + + ei = kmem_cache_alloc(spufs_inode_cache, SLAB_KERNEL); + if (!ei) + return NULL; + return &ei->vfs_inode; +} + +static void +spufs_destroy_inode(struct inode *inode) +{ + kmem_cache_free(spufs_inode_cache, SPUFS_I(inode)); +} + +static void +spufs_init_once(void *p, kmem_cache_t * cachep, unsigned long flags) +{ + struct spufs_inode_info *ei = p; + + if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == + SLAB_CTOR_CONSTRUCTOR) { + inode_init_once(&ei->vfs_inode); + } +} + +static struct inode * +spufs_new_inode(struct super_block *sb, int mode) +{ + struct inode *inode; + + inode = new_inode(sb); + if (!inode) + goto out; + + inode->i_mode = mode; + inode->i_uid = current->fsuid; + inode->i_gid = current->fsgid; + inode->i_blksize = PAGE_CACHE_SIZE; + inode->i_blocks = 0; + inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; +out: + return inode; +} + +static int +spufs_setattr(struct dentry *dentry, struct iattr *attr) +{ + struct inode *inode = dentry->d_inode; + +/* dump_stack(); + pr_debug("ia_size %lld, i_size:%lld\n", attr->ia_size, inode->i_size); +*/ + if ((attr->ia_valid & ATTR_SIZE) && + (attr->ia_size != inode->i_size)) + return -EINVAL; + return inode_setattr(inode, attr); +} + + +static int +spufs_new_file(struct super_block *sb, struct dentry *dentry, + struct file_operations *fops, int mode, + struct spu_context *ctx) +{ + static struct inode_operations spufs_file_iops = { + .getattr = simple_getattr, + .setattr = spufs_setattr, + .unlink = simple_unlink, + }; + struct inode *inode; + int ret; + + ret = -ENOSPC; + inode = spufs_new_inode(sb, S_IFREG | mode); + if (!inode) + goto out; + + ret = 0; + inode->i_op = &spufs_file_iops; + inode->i_fop = fops; +// inode->i_mapping->a_ops = &spufs_aops; +// inode->i_mapping->backing_dev_info = &spufs_backing_dev_info; + inode->u.generic_ip = SPUFS_I(inode)->i_ctx = get_spu_context(ctx); + d_add(dentry, inode); +out: + return ret; +} + +static int +spufs_create(struct inode *dir, struct dentry *dentry, + int mode, struct nameidata *nd) +{ + struct tree_descr *descr; + struct spu_context *ctx; + int ret; + + descr = spufs_dir_contents; + + /* search spufs_dir_contents for a file with the name we are + trying to create */ + ret = -EINVAL; + while (strcmp(descr->name, dentry->d_name.name) != 0) { + descr++; + if (!descr->name || !descr->name[0]) + goto out; + } + + ctx = SPUFS_I(dir)->i_ctx; + mode &= descr->mode; + + ret = spufs_new_file(dir->i_sb, dentry, descr->ops, mode, ctx); + /* get an extra reference to pin the dentry */ + dget(dentry); +out: + return ret; +} + +static void +spufs_delete_inode(struct inode *inode) +{ + if (SPUFS_I(inode)->i_ctx) + put_spu_context(SPUFS_I(inode)->i_ctx); + clear_inode(inode); +} + +static int +spufs_fill_dir(struct dentry *dir, struct tree_descr *files, + int mode, struct spu_context *ctx) +{ + struct dentry *dentry; + int ret; + + while (files->name && files->name[0]) { + ret = -ENOMEM; + dentry = d_alloc_name(dir, files->name); + if (!dentry) + goto out; + ret = spufs_new_file(dir->d_sb, dentry, files->ops, + files->mode & mode, ctx); + if (ret) + goto out; + files++; + } + return 0; +out: + // FIXME: remove all files that are left + + return ret; +} + +struct inode_operations spufs_dir_inode_operations = { + .lookup = simple_lookup, + .unlink = simple_unlink, + .create = spufs_create, +}; + +static int +spufs_mkdir(struct inode *dir, struct dentry *dentry, int mode) +{ + int ret; + struct inode *inode; + struct spu_context *ctx; + + ret = -ENOSPC; + inode = spufs_new_inode(dir->i_sb, mode | S_IFDIR); + if (!inode) + goto out; + + if (dir->i_mode & S_ISGID) { + inode->i_gid = dir->i_gid; + inode->i_mode &= S_ISGID; + } + ctx = alloc_spu_context(); + SPUFS_I(inode)->i_ctx = ctx; + if (!ctx) + goto out_iput; + + inode->i_op = &spufs_dir_inode_operations; + inode->i_fop = &simple_dir_operations; + ret = spufs_fill_dir(dentry, spufs_dir_contents, mode, ctx); + if (ret) + goto out_free_ctx; + + d_instantiate(dentry, inode); + dget(dentry); + dir->i_nlink++; + goto out; + +out_free_ctx: + put_spu_context(ctx); +out_iput: + iput(inode); +out: + return ret; +} + +/* This looks really wrong! */ +static int spufs_rmdir(struct inode *root, struct dentry *dir_dentry) +{ + struct dentry *dentry; + int err; + + spin_lock(&dcache_lock); +#if 0 + /* check if any entry is used */ + err = -EBUSY; + list_for_each_entry(dentry, &dir_dentry->d_subdirs, d_child) { + if (d_unhashed(dentry) || !dentry->d_inode) + continue; + if (atomic_read(&dentry->d_count) != 1) + goto out; + } +#endif + /* remove all entries */ + err = 0; + list_for_each_entry(dentry, &dir_dentry->d_subdirs, d_child) { + if (d_unhashed(dentry) || !dentry->d_inode) + continue; + atomic_dec(&dentry->d_count); + __d_drop(dentry); + } +#if 0 +out: +#endif + spin_unlock(&dcache_lock); + if (!err) { + shrink_dcache_parent(dir_dentry); + err = simple_rmdir(root, dir_dentry); + } + return err; +} + +/* File system initialization */ +enum { + Opt_uid, Opt_gid, Opt_err, +}; + +static match_table_t spufs_tokens = { + { Opt_uid, "uid=%d" }, + { Opt_gid, "gid=%d" }, + { Opt_err, NULL }, +}; + +static int +spufs_parse_options(char *options, struct inode *root) +{ + char *p; + substring_t args[MAX_OPT_ARGS]; + + while ((p = strsep(&options, ",")) != NULL) { + int token, option; + + if (!*p) + continue; + + token = match_token(p, spufs_tokens, args); + switch (token) { + case Opt_uid: + if (match_int(&args[0], &option)) + return 0; + root->i_uid = option; + break; + case Opt_gid: + if (match_int(&args[0], &option)) + return 0; + root->i_gid = option; + break; + default: + return 0; + } + } + return 1; +} + +static int +spufs_create_root(struct super_block *sb, void *data) { + static struct inode_operations spufs_root_inode_operations = { + .lookup = simple_lookup, + .mkdir = spufs_mkdir, + .rmdir = spufs_rmdir, +// .rename = simple_rename, // XXX maybe + }; + + struct inode *inode; + int ret; + + ret = -ENOMEM; + inode = spufs_new_inode(sb, S_IFDIR | 0775); + if (!inode) + goto out; + + inode->i_op = &spufs_root_inode_operations; + inode->i_fop = &simple_dir_operations; + SPUFS_I(inode)->i_ctx = NULL; + + ret = -EINVAL; + if (!spufs_parse_options(data, inode)) + goto out_iput; + + ret = -ENOMEM; + sb->s_root = d_alloc_root(inode); + if (!sb->s_root) + goto out_iput; + + return 0; +out_iput: + iput(inode); +out: + return ret; +} + +static int +spufs_fill_super(struct super_block *sb, void *data, int silent) +{ + static struct super_operations s_ops = { + .alloc_inode = spufs_alloc_inode, + .destroy_inode = spufs_destroy_inode, + .statfs = simple_statfs, + .delete_inode = spufs_delete_inode, + .drop_inode = generic_delete_inode, + }; + + sb->s_maxbytes = MAX_LFS_FILESIZE; + sb->s_blocksize = PAGE_CACHE_SIZE; + sb->s_blocksize_bits = PAGE_CACHE_SHIFT; + sb->s_magic = SPUFS_MAGIC; + sb->s_op = &s_ops; + + return spufs_create_root(sb, data); +} + +static struct super_block * +spufs_get_sb(struct file_system_type *fstype, int flags, + const char *name, void *data) +{ + return get_sb_single(fstype, flags, data, spufs_fill_super); +} + +static struct file_system_type spufs_type = { + .owner = THIS_MODULE, + .name = "spufs", + .get_sb = spufs_get_sb, + .kill_sb = kill_litter_super, +}; + +static int spufs_init(void) +{ + int ret; + ret = -ENOMEM; + spufs_inode_cache = kmem_cache_create("spufs_inode_cache", + sizeof(struct spufs_inode_info), 0, + SLAB_HWCACHE_ALIGN, spufs_init_once, NULL); + + if (!spufs_inode_cache) + goto out; + ret = register_filesystem(&spufs_type); + if (ret) + kmem_cache_destroy(spufs_inode_cache); +out: + return ret; +} +module_init(spufs_init); + +static void spufs_exit(void) +{ + unregister_filesystem(&spufs_type); + kmem_cache_destroy(spufs_inode_cache); +} +module_exit(spufs_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Arnd Bergmann "); + --- linux-cg.orig/fs/spufs/spufs.h 1969-12-31 19:00:00.000000000 -0500 +++ linux-cg/fs/spufs/spufs.h 2005-08-25 22:20:31.638940264 -0400 @@ -0,0 +1,65 @@ +/* + * SPU file system + * + * (C) Copyright IBM Deutschland Entwicklung GmbH 2005 + * + * Author: Arnd Bergmann + * + * 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, 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#ifndef SPUFS_H +#define SPUFS_H + +#include +#include +#include +#include + +#include + +/* The magic number for our file system */ +enum { + SPUFS_MAGIC = 0x23c9b64e, +}; + +struct spu_context { + struct spu *spu; /* pointer to a physical SPU */ + struct rw_semaphore backing_sema; /* protects the above */ + spinlock_t mmio_lock; /* protects mmio access */ + + struct kref kref; +}; + +struct spufs_inode_info { + struct spu_context *i_ctx; + struct inode vfs_inode; +}; +#define SPUFS_I(inode) \ + container_of(inode, struct spufs_inode_info, vfs_inode) + +extern struct tree_descr spufs_dir_contents[]; + +/* context management */ +struct spu_context * alloc_spu_context(void); +void destroy_spu_context(struct kref *kref); +struct spu_context * get_spu_context(struct spu_context *ctx); +void put_spu_context(struct spu_context *ctx); + +void spu_acquire(struct spu_context *ctx); +void spu_release(struct spu_context *ctx); +void spu_acquire_runnable(struct spu_context *ctx); +void spu_acquire_saved(struct spu_context *ctx); + +#endif --- linux-cg.orig/include/asm-ppc64/spu.h 1969-12-31 19:00:00.000000000 -0500 +++ linux-cg/include/asm-ppc64/spu.h 2005-08-25 22:20:31.642939656 -0400 @@ -0,0 +1,473 @@ +/* + * SPU core / file system interface and HW structures + * + * (C) Copyright IBM Deutschland Entwicklung GmbH 2005 + * + * Author: Arnd Bergmann + * + * 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, 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef _SPU_H +#define _SPU_H +#include +#include + +#define LS_ORDER (6) /* 256 kb */ + +#define LS_SIZE (PAGE_SIZE << LS_ORDER) + +struct spu { + char *name; + unsigned long local_store_phys; + u8 *local_store; + struct spu_problem __iomem *problem; + struct spu_priv1 __iomem *priv1; + struct spu_priv2 __iomem *priv2; + struct list_head list; + int number; + u32 isrc; + u32 node; + struct kref kref; + size_t ls_size; + unsigned int slb_replace; + struct mm_struct *mm; + int class_0_pending; + spinlock_t register_lock; + + u32 stop_code; + wait_queue_head_t stop_wq; + wait_queue_head_t ibox_wq; + wait_queue_head_t wbox_wq; + + char irq_c0[8]; + char irq_c1[8]; + char irq_c2[8]; +}; + +struct spu *spu_alloc(void); +void spu_free(struct spu *spu); +int spu_run(struct spu *spu); + +size_t spu_wbox_write(struct spu *spu, u32 data); +size_t spu_ibox_read(struct spu *spu, u32 *data); + +/* + * This defines the Local Store, Problem Area and Privlege Area of an SPU. + */ + +union mfc_tag_size_class_cmd { + struct { + u16 mfc_size; + u16 mfc_tag; + u8 pad; + u8 mfc_rclassid; + u16 mfc_cmd; + } u; + struct { + u32 mfc_size_tag32; + u32 mfc_class_cmd32; + } by32; + u64 all64; +}; + +struct mfc_cq_sr { + u64 mfc_cq_data0_RW; + u64 mfc_cq_data1_RW; + u64 mfc_cq_data2_RW; + u64 mfc_cq_data3_RW; +}; + +struct spu_problem { +#define MS_SYNC_PENDING 1L + u64 spc_mssync_RW; /* 0x0000 */ + u8 pad_0x0008_0x3000[0x3000 - 0x0008]; + + /* DMA Area */ + u8 pad_0x3000_0x3004[0x4]; /* 0x3000 */ + u32 mfc_lsa_W; /* 0x3004 */ + u64 mfc_ea_W; /* 0x3008 */ + union mfc_tag_size_class_cmd mfc_union_W; /* 0x3010 */ + u8 pad_0x3018_0x3104[0xec]; /* 0x3018 */ + u32 dma_qstatus_R; /* 0x3104 */ + u8 pad_0x3108_0x3204[0xfc]; /* 0x3108 */ + u32 dma_querytype_RW; /* 0x3204 */ + u8 pad_0x3208_0x321c[0x14]; /* 0x3208 */ + u32 dma_querymask_RW; /* 0x321c */ + u8 pad_0x3220_0x322c[0xc]; /* 0x3220 */ + u32 dma_tagstatus_R; /* 0x322c */ +#define DMA_TAGSTATUS_INTR_ANY 1u +#define DMA_TAGSTATUS_INTR_ALL 2u + u8 pad_0x3230_0x4000[0x4000 - 0x3230]; /* 0x3230 */ + + /* SPU Control Area */ + u8 pad_0x4000_0x4004[0x4]; /* 0x4000 */ + u32 pu_mb_R; /* 0x4004 */ + u8 pad_0x4008_0x400c[0x4]; /* 0x4008 */ + u32 spu_mb_W; /* 0x400c */ + u8 pad_0x4010_0x4014[0x4]; /* 0x4010 */ + u32 mb_stat_R; /* 0x4014 */ + u8 pad_0x4018_0x401c[0x4]; /* 0x4018 */ + u32 spu_runcntl_RW; /* 0x401c */ +#define SPU_RUNCNTL_STOP 0L +#define SPU_RUNCNTL_RUNNABLE 1L + u8 pad_0x4020_0x4024[0x4]; /* 0x4020 */ + u32 spu_status_R; /* 0x4024 */ +#define SPU_STOP_STATUS_SHIFT 16 +#define SPU_STATUS_STOPPED 0x0 +#define SPU_STATUS_RUNNING 0x1 +#define SPU_STATUS_STOPPED_BY_STOP 0x2 +#define SPU_STATUS_STOPPED_BY_HALT 0x4 +#define SPU_STATUS_WAITING_FOR_CHANNEL 0x8 +#define SPU_STATUS_SINGLE_STEP 0x10 +#define SPU_STATUS_INVALID_INSTR 0x20 +#define SPU_STATUS_INVALID_CH 0x40 +#define SPU_STATUS_ISOLATED_STATE 0x80 +#define SPU_STATUS_ISOLATED_LOAD_STAUTUS 0x200 +#define SPU_STATUS_ISOLATED_EXIT_STAUTUS 0x400 + u8 pad_0x4028_0x402c[0x4]; /* 0x4028 */ + u32 spu_spe_R; /* 0x402c */ + u8 pad_0x4030_0x4034[0x4]; /* 0x4030 */ + u32 spu_npc_RW; /* 0x4034 */ + u8 pad_0x4038_0x14000[0x14000 - 0x4038]; /* 0x4038 */ + + /* Signal Notification Area */ + u8 pad_0x14000_0x1400c[0xc]; /* 0x14000 */ + u32 signal_notify1; /* 0x1400c */ + u8 pad_0x14010_0x1c00c[0x7ffc]; /* 0x14010 */ + u32 signal_notify2; /* 0x1c00c */ +} __attribute__ ((aligned(0x20000))); + +/* SPU Privilege 2 State Area */ +struct spu_priv2 { + /* MFC Registers */ + u8 pad_0x0000_0x1100[0x1100 - 0x0000]; /* 0x0000 */ + + /* SLB Management Registers */ + u8 pad_0x1100_0x1108[0x8]; /* 0x1100 */ + u64 slb_index_W; /* 0x1108 */ +#define SLB_INDEX_MASK 0x7L + u64 slb_esid_RW; /* 0x1110 */ + u64 slb_vsid_RW; /* 0x1118 */ +#define SLB_VSID_SUPERVISOR_STATE (0x1ull << 11) +#define SLB_VSID_SUPERVISOR_STATE_MASK (0x1ull << 11) +#define SLB_VSID_PROBLEM_STATE (0x1ull << 10) +#define SLB_VSID_PROBLEM_STATE_MASK (0x1ull << 10) +#define SLB_VSID_EXECUTE_SEGMENT (0x1ull << 9) +#define SLB_VSID_NO_EXECUTE_SEGMENT (0x1ull << 9) +#define SLB_VSID_EXECUTE_SEGMENT_MASK (0x1ull << 9) +#define SLB_VSID_4K_PAGE (0x0 << 8) +#define SLB_VSID_LARGE_PAGE (0x1ull << 8) +#define SLB_VSID_PAGE_SIZE_MASK (0x1ull << 8) +#define SLB_VSID_CLASS_MASK (0x1ull << 7) +#define SLB_VSID_VIRTUAL_PAGE_SIZE_MASK (0x1ull << 6) + u64 slb_invalidate_entry_W; /* 0x1120 */ + u64 slb_invalidate_all_W; /* 0x1128 */ + u8 pad_0x1130_0x2000[0x2000 - 0x1130]; /* 0x1130 */ + + /* Context Save / Restore Area */ + struct mfc_cq_sr spuq[16]; /* 0x2000 */ + struct mfc_cq_sr puq[8]; /* 0x2200 */ + u8 pad_0x2300_0x3000[0x3000 - 0x2300]; /* 0x2300 */ + + /* MFC Control */ + u64 mfc_control_RW; /* 0x3000 */ +#define MFC_CNTL_RESUME_DMA_QUEUE (0ull << 0) +#define MFC_CNTL_SUSPEND_DMA_QUEUE (1ull << 0) +#define MFC_CNTL_SUSPEND_DMA_QUEUE_MASK (1ull << 0) +#define MFC_CNTL_NORMAL_DMA_QUEUE_OPERATION (0ull << 8) +#define MFC_CNTL_SUSPEND_IN_PROGRESS (1ull << 8) +#define MFC_CNTL_SUSPEND_COMPLETE (3ull << 8) +#define MFC_CNTL_SUSPEND_DMA_STATUS_MASK (3ull << 8) +#define MFC_CNTL_DMA_QUEUES_EMPTY (1ull << 14) +#define MFC_CNTL_DMA_QUEUES_EMPTY_MASK (1ull << 14) +#define MFC_CNTL_PURGE_DMA_REQUEST (1ull << 15) +#define MFC_CNTL_PURGE_DMA_IN_PROGRESS (1ull << 24) +#define MFC_CNTL_PURGE_DMA_COMPLETE (3ull << 24) +#define MFC_CNTL_PURGE_DMA_STATUS_MASK (3ull << 24) +#define MFC_CNTL_RESTART_DMA_COMMAND (1ull << 32) +#define MFC_CNTL_DMA_COMMAND_REISSUE_PENDING (1ull << 32) +#define MFC_CNTL_DMA_COMMAND_REISSUE_STATUS_MASK (1ull << 32) +#define MFC_CNTL_MFC_PRIVILEGE_STATE (2ull << 33) +#define MFC_CNTL_MFC_PROBLEM_STATE (3ull << 33) +#define MFC_CNTL_MFC_KEY_PROTECTION_STATE_MASK (3ull << 33) +#define MFC_CNTL_DECREMENTER_HALTED (1ull << 35) +#define MFC_CNTL_DECREMENTER_RUNNING (1ull << 40) +#define MFC_CNTL_DECREMENTER_STATUS_MASK (1ull << 40) + u8 pad_0x3008_0x4000[0x4000 - 0x3008]; /* 0x3008 */ + + /* Interrupt Mailbox */ + u64 puint_mb_R; /* 0x4000 */ + u8 pad_0x4008_0x4040[0x4040 - 0x4008]; /* 0x4008 */ + + /* SPU Control */ + u64 spu_privcntl_RW; /* 0x4040 */ +#define SPU_PRIVCNTL_MODE_NORMAL (0x0ull << 0) +#define SPU_PRIVCNTL_MODE_SINGLE_STEP (0x1ull << 0) +#define SPU_PRIVCNTL_MODE_MASK (0x1ull << 0) +#define SPU_PRIVCNTL_NO_ATTENTION_EVENT (0x0ull << 1) +#define SPU_PRIVCNTL_ATTENTION_EVENT (0x1ull << 1) +#define SPU_PRIVCNTL_ATTENTION_EVENT_MASK (0x1ull << 1) +#define SPU_PRIVCNT_LOAD_REQUEST_NORMAL (0x0ull << 2) +#define SPU_PRIVCNT_LOAD_REQUEST_ENABLE_MASK (0x1ull << 2) + u8 pad_0x4048_0x4058[0x10]; /* 0x4048 */ + u64 spu_lslr_RW; /* 0x4058 */ + u64 spu_chnlcntptr_RW; /* 0x4060 */ + u64 spu_chnlcnt_RW; /* 0x4068 */ + u64 spu_chnldata_RW; /* 0x4070 */ + u64 spu_cfg_RW; /* 0x4078 */ + u8 pad_0x4080_0x5000[0x5000 - 0x4080]; /* 0x4080 */ + + /* PV2_ImplRegs: Implementation-specific privileged-state 2 regs */ + u64 spu_pm_trace_tag_status_RW; /* 0x5000 */ + u64 spu_tag_status_query_RW; /* 0x5008 */ +#define TAG_STATUS_QUERY_CONDITION_BITS (0x3ull << 32) +#define TAG_STATUS_QUERY_MASK_BITS (0xffffffffull) + u64 spu_cmd_buf1_RW; /* 0x5010 */ +#define SPU_COMMAND_BUFFER_1_LSA_BITS (0x7ffffull << 32) +#define SPU_COMMAND_BUFFER_1_EAH_BITS (0xffffffffull) + u64 spu_cmd_buf2_RW; /* 0x5018 */ +#define SPU_COMMAND_BUFFER_2_EAL_BITS ((0xffffffffull) << 32) +#define SPU_COMMAND_BUFFER_2_TS_BITS (0xffffull << 16) +#define SPU_COMMAND_BUFFER_2_TAG_BITS (0x3full) + u64 spu_atomic_status_RW; /* 0x5020 */ +} __attribute__ ((aligned(0x20000))); + +/* SPU Privilege 1 State Area */ +struct spu_priv1 { + /* Control and Configuration Area */ + u64 mfc_sr1_RW; /* 0x000 */ +#define MFC_STATE1_LOCAL_STORAGE_DECODE_MASK 0x01ull +#define MFC_STATE1_BUS_TLBIE_MASK 0x02ull +#define MFC_STATE1_REAL_MODE_OFFSET_ENABLE_MASK 0x04ull +#define MFC_STATE1_PROBLEM_STATE_MASK 0x08ull +#define MFC_STATE1_RELOCATE_MASK 0x10ull +#define MFC_STATE1_MASTER_RUN_CONTROL_MASK 0x20ull + u64 mfc_lpid_RW; /* 0x008 */ + u64 spu_idr_RW; /* 0x010 */ + u64 mfc_vr_RO; /* 0x018 */ +#define MFC_VERSION_BITS (0xffff << 16) +#define MFC_REVISION_BITS (0xffff) +#define MFC_GET_VERSION_BITS(vr) (((vr) & MFC_VERSION_BITS) >> 16) +#define MFC_GET_REVISION_BITS(vr) ((vr) & MFC_REVISION_BITS) + u64 spu_vr_RO; /* 0x020 */ +#define SPU_VERSION_BITS (0xffff << 16) +#define SPU_REVISION_BITS (0xffff) +#define SPU_GET_VERSION_BITS(vr) (vr & SPU_VERSION_BITS) >> 16 +#define SPU_GET_REVISION_BITS(vr) (vr & SPU_REVISION_BITS) + u8 pad_0x28_0x100[0x100 - 0x28]; /* 0x28 */ + + + /* Interrupt Area */ + u64 int_mask_class0_RW; /* 0x100 */ +#define CLASS0_ENABLE_DMA_ALIGNMENT_INTR 0x1L +#define CLASS0_ENABLE_INVALID_DMA_COMMAND_INTR 0x2L +#define CLASS0_ENABLE_SPU_ERROR_INTR 0x4L +#define CLASS0_ENABLE_MFC_FIR_INTR 0x8L + u64 int_mask_class1_RW; /* 0x108 */ +#define CLASS1_ENABLE_SEGMENT_FAULT_INTR 0x1L +#define CLASS1_ENABLE_STORAGE_FAULT_INTR 0x2L +#define CLASS1_ENABLE_LS_COMPARE_SUSPEND_ON_GET_INTR 0x4L +#define CLASS1_ENABLE_LS_COMPARE_SUSPEND_ON_PUT_INTR 0x8L + u64 int_mask_class2_RW; /* 0x110 */ +#define CLASS2_ENABLE_MAILBOX_INTR 0x1L +#define CLASS2_ENABLE_SPU_STOP_INTR 0x2L +#define CLASS2_ENABLE_SPU_HALT_INTR 0x4L +#define CLASS2_ENABLE_SPU_DMA_TAG_GROUP_COMPLETE_INTR 0x8L + u8 pad_0x118_0x140[0x28]; /* 0x118 */ + u64 int_stat_class0_RW; /* 0x140 */ + u64 int_stat_class1_RW; /* 0x148 */ + u64 int_stat_class2_RW; /* 0x150 */ + u8 pad_0x158_0x180[0x28]; /* 0x158 */ + u64 int_route_RW; /* 0x180 */ + + /* Interrupt Routing */ + u8 pad_0x188_0x200[0x200 - 0x188]; /* 0x188 */ + + /* Atomic Unit Control Area */ + u64 mfc_atomic_flush_RW; /* 0x200 */ +#define mfc_atomic_flush_enable 0x1L + u8 pad_0x208_0x280[0x78]; /* 0x208 */ + u64 resource_allocation_groupID_RW; /* 0x280 */ + u64 resource_allocation_enable_RW; /* 0x288 */ + u8 pad_0x290_0x3c8[0x3c8 - 0x290]; /* 0x290 */ + + /* SPU_Cache_ImplRegs: Implementation-dependent cache registers */ + + u64 smf_sbi_signal_sel; /* 0x3c8 */ +#define smf_sbi_mask_lsb 56 +#define smf_sbi_shift (63 - smf_sbi_mask_lsb) +#define smf_sbi_mask (0x301LL << smf_sbi_shift) +#define smf_sbi_bus0_bits (0x001LL << smf_sbi_shift) +#define smf_sbi_bus2_bits (0x100LL << smf_sbi_shift) +#define smf_sbi2_bus0_bits (0x201LL << smf_sbi_shift) +#define smf_sbi2_bus2_bits (0x300LL << smf_sbi_shift) + u64 smf_ato_signal_sel; /* 0x3d0 */ +#define smf_ato_mask_lsb 35 +#define smf_ato_shift (63 - smf_ato_mask_lsb) +#define smf_ato_mask (0x3LL << smf_ato_shift) +#define smf_ato_bus0_bits (0x2LL << smf_ato_shift) +#define smf_ato_bus2_bits (0x1LL << smf_ato_shift) + u8 pad_0x3d8_0x400[0x400 - 0x3d8]; /* 0x3d8 */ + + /* TLB Management Registers */ + u64 mfc_sdr_RW; /* 0x400 */ + u8 pad_0x408_0x500[0xf8]; /* 0x408 */ + u64 tlb_index_hint_RO; /* 0x500 */ + u64 tlb_index_W; /* 0x508 */ + u64 tlb_vpn_RW; /* 0x510 */ + u64 tlb_rpn_RW; /* 0x518 */ + u8 pad_0x520_0x540[0x20]; /* 0x520 */ + u64 tlb_invalidate_entry_W; /* 0x540 */ + u64 tlb_invalidate_all_W; /* 0x548 */ + u8 pad_0x550_0x580[0x580 - 0x550]; /* 0x550 */ + + /* SPU_MMU_ImplRegs: Implementation-dependent MMU registers */ + u64 smm_hid; /* 0x580 */ +#define PAGE_SIZE_MASK 0xf000000000000000ull +#define PAGE_SIZE_16MB_64KB 0x2000000000000000ull + u8 pad_0x588_0x600[0x600 - 0x588]; /* 0x588 */ + + /* MFC Status/Control Area */ + u64 mfc_accr_RW; /* 0x600 */ +#define MFC_ACCR_EA_ACCESS_GET (1 << 0) +#define MFC_ACCR_EA_ACCESS_PUT (1 << 1) +#define MFC_ACCR_LS_ACCESS_GET (1 << 3) +#define MFC_ACCR_LS_ACCESS_PUT (1 << 4) + u8 pad_0x608_0x610[0x8]; /* 0x608 */ + u64 mfc_dsisr_RW; /* 0x610 */ +#define MFC_DSISR_PTE_NOT_FOUND (1 << 30) +#define MFC_DSISR_ACCESS_DENIED (1 << 27) +#define MFC_DSISR_ATOMIC (1 << 26) +#define MFC_DSISR_ACCESS_PUT (1 << 25) +#define MFC_DSISR_ADDR_MATCH (1 << 22) +#define MFC_DSISR_LS (1 << 17) +#define MFC_DSISR_L (1 << 16) +#define MFC_DSISR_ADDRESS_OVERFLOW (1 << 0) + u8 pad_0x618_0x620[0x8]; /* 0x618 */ + u64 mfc_dar_RW; /* 0x620 */ + u8 pad_0x628_0x700[0x700 - 0x628]; /* 0x628 */ + + /* Replacement Management Table (RMT) Area */ + u64 rmt_index_RW; /* 0x700 */ + u8 pad_0x708_0x710[0x8]; /* 0x708 */ + u64 rmt_data1_RW; /* 0x710 */ + u8 pad_0x718_0x800[0x800 - 0x718]; /* 0x718 */ + + /* Control/Configuration Registers */ + u64 mfc_dsir_R; /* 0x800 */ +#define MFC_DSIR_Q (1 << 31) +#define MFC_DSIR_SPU_QUEUE MFC_DSIR_Q + u64 mfc_lsacr_RW; /* 0x808 */ +#define MFC_LSACR_COMPARE_MASK ((~0ull) << 32) +#define MFC_LSACR_COMPARE_ADDR ((~0ull) >> 32) + u64 mfc_lscrr_R; /* 0x810 */ +#define MFC_LSCRR_Q (1 << 31) +#define MFC_LSCRR_SPU_QUEUE MFC_LSCRR_Q +#define MFC_LSCRR_QI_SHIFT 32 +#define MFC_LSCRR_QI_MASK ((~0ull) << MFC_LSCRR_QI_SHIFT) + u8 pad_0x818_0x820[0x8]; /* 0x818 */ + u64 mfc_tclass_id_RW; /* 0x820 */ +#define MFC_TCLASS_ID_ENABLE (1L << 0L) +#define MFC_TCLASS_SLOT2_ENABLE (1L << 5L) +#define MFC_TCLASS_SLOT1_ENABLE (1L << 6L) +#define MFC_TCLASS_SLOT0_ENABLE (1L << 7L) +#define MFC_TCLASS_QUOTA_2_SHIFT 8L +#define MFC_TCLASS_QUOTA_1_SHIFT 16L +#define MFC_TCLASS_QUOTA_0_SHIFT 24L +#define MFC_TCLASS_QUOTA_2_MASK (0x1FL << MFC_TCLASS_QUOTA_2_SHIFT) +#define MFC_TCLASS_QUOTA_1_MASK (0x1FL << MFC_TCLASS_QUOTA_1_SHIFT) +#define MFC_TCLASS_QUOTA_0_MASK (0x1FL << MFC_TCLASS_QUOTA_0_SHIFT) + u8 pad_0x828_0x900[0x900 - 0x828]; /* 0x828 */ + + /* Real Mode Support Registers */ + u64 mfc_rm_boundary; /* 0x900 */ + u8 pad_0x908_0x938[0x30]; /* 0x908 */ + u64 smf_dma_signal_sel; /* 0x938 */ +#define mfc_dma1_mask_lsb 41 +#define mfc_dma1_shift (63 - mfc_dma1_mask_lsb) +#define mfc_dma1_mask (0x3LL << mfc_dma1_shift) +#define mfc_dma1_bits (0x1LL << mfc_dma1_shift) +#define mfc_dma2_mask_lsb 43 +#define mfc_dma2_shift (63 - mfc_dma2_mask_lsb) +#define mfc_dma2_mask (0x3LL << mfc_dma2_shift) +#define mfc_dma2_bits (0x1LL << mfc_dma2_shift) + u8 pad_0x940_0xa38[0xf8]; /* 0x940 */ + u64 smm_signal_sel; /* 0xa38 */ +#define smm_sig_mask_lsb 12 +#define smm_sig_shift (63 - smm_sig_mask_lsb) +#define smm_sig_mask (0x3LL << smm_sig_shift) +#define smm_sig_bus0_bits (0x2LL << smm_sig_shift) +#define smm_sig_bus2_bits (0x1LL << smm_sig_shift) + u8 pad_0xa40_0xc00[0xc00 - 0xa40]; /* 0xa40 */ + + /* DMA Command Error Area */ + u64 mfc_cer_R; /* 0xc00 */ +#define MFC_CER_Q (1 << 31) +#define MFC_CER_SPU_QUEUE MFC_CER_Q + u8 pad_0xc08_0x1000[0x1000 - 0xc08]; /* 0xc08 */ + + /* PV1_ImplRegs: Implementation-dependent privileged-state 1 regs */ + /* DMA Command Error Area */ + u64 spu_ecc_cntl_RW; /* 0x1000 */ +#define SPU_ECC_CNTL_E (1ull << 0ull) +#define SPU_ECC_CNTL_ENABLE SPU_ECC_CNTL_E +#define SPU_ECC_CNTL_DISABLE (~SPU_ECC_CNTL_E & 1L) +#define SPU_ECC_CNTL_S (1ull << 1ull) +#define SPU_ECC_STOP_AFTER_ERROR SPU_ECC_CNTL_S +#define SPU_ECC_CONTINUE_AFTER_ERROR (~SPU_ECC_CNTL_S & 2L) +#define SPU_ECC_CNTL_B (1ull << 2ull) +#define SPU_ECC_BACKGROUND_ENABLE SPU_ECC_CNTL_B +#define SPU_ECC_BACKGROUND_DISABLE (~SPU_ECC_CNTL_B & 4L) +#define SPU_ECC_CNTL_I_SHIFT 3ull +#define SPU_ECC_CNTL_I_MASK (3ull << SPU_ECC_CNTL_I_SHIFT) +#define SPU_ECC_WRITE_ALWAYS (~SPU_ECC_CNTL_I & 12L) +#define SPU_ECC_WRITE_CORRECTABLE (1ull << SPU_ECC_CNTL_I_SHIFT) +#define SPU_ECC_WRITE_UNCORRECTABLE (3ull << SPU_ECC_CNTL_I_SHIFT) +#define SPU_ECC_CNTL_D (1ull << 5ull) +#define SPU_ECC_DETECTION_ENABLE SPU_ECC_CNTL_D +#define SPU_ECC_DETECTION_DISABLE (~SPU_ECC_CNTL_D & 32L) + u64 spu_ecc_stat_RW; /* 0x1008 */ +#define SPU_ECC_CORRECTED_ERROR (1ull << 0ul) +#define SPU_ECC_UNCORRECTED_ERROR (1ull << 1ul) +#define SPU_ECC_SCRUB_COMPLETE (1ull << 2ul) +#define SPU_ECC_SCRUB_IN_PROGRESS (1ull << 3ul) +#define SPU_ECC_INSTRUCTION_ERROR (1ull << 4ul) +#define SPU_ECC_DATA_ERROR (1ull << 5ul) +#define SPU_ECC_DMA_ERROR (1ull << 6ul) +#define SPU_ECC_STATUS_CNT_MASK (256ull << 8) + u64 spu_ecc_addr_RW; /* 0x1010 */ + u64 spu_err_mask_RW; /* 0x1018 */ +#define SPU_ERR_ILLEGAL_INSTR (1ull << 0ul) +#define SPU_ERR_ILLEGAL_CHANNEL (1ull << 1ul) + u8 pad_0x1020_0x1028[0x1028 - 0x1020]; /* 0x1020 */ + + /* SPU Debug-Trace Bus (DTB) Selection Registers */ + u64 spu_trig0_sel; /* 0x1028 */ + u64 spu_trig1_sel; /* 0x1030 */ + u64 spu_trig2_sel; /* 0x1038 */ + u64 spu_trig3_sel; /* 0x1040 */ + u64 spu_trace_sel; /* 0x1048 */ +#define spu_trace_sel_mask 0x1f1fLL +#define spu_trace_sel_bus0_bits 0x1000LL +#define spu_trace_sel_bus2_bits 0x0010LL + u64 spu_event0_sel; /* 0x1050 */ + u64 spu_event1_sel; /* 0x1058 */ + u64 spu_event2_sel; /* 0x1060 */ + u64 spu_event3_sel; /* 0x1068 */ + u64 spu_trace_cntl; /* 0x1070 */ +} __attribute__ ((aligned(0x2000))); + +#endif --- linux-cg.orig/mm/memory.c 2005-08-25 22:08:05.379976424 -0400 +++ linux-cg/mm/memory.c 2005-08-25 22:15:10.920977808 -0400 @@ -2062,6 +2062,8 @@ int __handle_mm_fault(struct mm_struct * return VM_FAULT_OOM; } +EXPORT_SYMBOL_GPL(__handle_mm_fault); + #ifndef __PAGETABLE_PUD_FOLDED /* * Allocate page upper directory. --- linux-cg.orig/arch/ppc/kernel/ppc_ksyms.c 2005-08-08 13:44:49.000000000 -0400 +++ linux-cg/arch/ppc/kernel/ppc_ksyms.c 2005-08-25 22:50:27.453998112 -0400 @@ -324,7 +324,6 @@ EXPORT_SYMBOL(__res); EXPORT_SYMBOL(next_mmu_context); EXPORT_SYMBOL(set_context); -EXPORT_SYMBOL_GPL(__handle_mm_fault); /* For MOL */ EXPORT_SYMBOL(disarm_decr); #ifdef CONFIG_PPC_STD_MMU extern long mol_trampoline; From arnd at arndb.de Fri Aug 26 08:04:23 2005 From: arnd at arndb.de (Arnd Bergmann) Date: Fri, 26 Aug 2005 00:04:23 +0200 Subject: [PATCH 5/7] spufs: Use a system call instead of ioctl Message-ID: <200508260004.23926.arnd@arndb.de> This patch makes it possible to use a system call instead of an ioctl to run spu code on spufs. This is only provided for reference, the current patch is unlikely to be used in future versions. We planning to move to a model where creation/destruction of SPU threads as well as entering the execution is done with new system calls instead of mkdir, rmdir and this call. This will make an SPU thread a property of a Linux user space thread instead of the global object that can be used by any process. Signed-off-by: Arnd Bergmann -- arch/ppc64/kernel/misc.S | 2 fs/spufs/Makefile | 2 fs/spufs/file.c | 12 +++++ fs/spufs/spufs.h | 2 fs/spufs/spurun.c | 96 +++++++++++++++++++++++++++++++++++++++++++++ include/asm-ppc/unistd.h | 3 - include/asm-ppc64/unistd.h | 3 - include/linux/syscalls.h | 3 + kernel/sys_ni.c | 1 9 files changed, 121 insertions(+), 3 deletions(-) --- linux-cg.orig/arch/ppc64/kernel/misc.S 2005-08-25 23:12:31.254917248 -0400 +++ linux-cg/arch/ppc64/kernel/misc.S 2005-08-25 23:12:36.582906000 -0400 @@ -1132,6 +1132,7 @@ _GLOBAL(sys_call_table32) .llong .sys_inotify_init /* 275 */ .llong .sys_inotify_add_watch .llong .sys_inotify_rm_watch + .llong .sys_spu_run .balign 8 _GLOBAL(sys_call_table) @@ -1413,3 +1414,4 @@ _GLOBAL(sys_call_table) .llong .sys_inotify_init /* 275 */ .llong .sys_inotify_add_watch .llong .sys_inotify_rm_watch + .llong .sys_spu_run --- linux-cg.orig/fs/spufs/Makefile 2005-08-25 23:12:34.935890192 -0400 +++ linux-cg/fs/spufs/Makefile 2005-08-25 23:12:36.582906000 -0400 @@ -1,5 +1,7 @@ obj-$(CONFIG_SPU_FS) += spufs.o +syscall-$(CONFIG_SPU_FS) += spurun.o +obj-y += $(syscall-y) $(syscall-m) spufs-y += inode.o file.o context.o switch.o # Rules to build switch.o with the help of SPU tool chain --- linux-cg.orig/fs/spufs/file.c 2005-08-25 23:12:31.259916488 -0400 +++ linux-cg/fs/spufs/file.c 2005-08-25 23:12:36.584905696 -0400 @@ -406,6 +406,16 @@ out: return ret; } +static int spufs_run_open(struct inode *inode, struct file *file) +{ + struct spufs_inode_info *i = SPUFS_I(inode); + file->private_data = i->i_ctx; + + i->i_spu_run = spufs_run_spu; + + return nonseekable_open(inode, file); +} + struct spufs_run_arg { u32 npc; /* inout: Next Program Counter */ u32 status; /* out: SPU status */ @@ -472,7 +482,7 @@ static long spufs_run_ioctl(struct file } static struct file_operations spufs_run_fops = { - .open = spufs_pipe_open, + .open = spufs_run_open, .unlocked_ioctl = spufs_run_ioctl, .compat_ioctl = spufs_run_ioctl, .read = spufs_run_read, --- linux-cg.orig/fs/spufs/spufs.h 2005-08-25 23:12:31.261916184 -0400 +++ linux-cg/fs/spufs/spufs.h 2005-08-25 23:12:36.584905696 -0400 @@ -46,6 +46,8 @@ struct spu_context { struct spufs_inode_info { struct spu_context *i_ctx; + long (*i_spu_run)(struct file *filp, struct spu_context *ctx, + u32 *npc, u32 *result); struct inode vfs_inode; }; #define SPUFS_I(inode) \ --- linux-cg.orig/fs/spufs/spurun.c 1969-12-31 19:00:00.000000000 -0500 +++ linux-cg/fs/spufs/spurun.c 2005-08-25 23:12:36.585905544 -0400 @@ -0,0 +1,96 @@ +/* + * SPU file system -- run system call + * + * (C) Copyright IBM Deutschland Entwicklung GmbH 2005 + * + * Author: Arnd Bergmann + * + * 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, 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include + +#include + +#include "spufs.h" + +/** + * sys_spu_run - run code loaded into an SPU + * + * @unpc: next program counter for the SPU + * @ustatus: status of the SPU + * + * This system call transfers the control of execution of a + * user space thread to an SPU. It will return when the + * SPU has finished executing or when it hits an error + * condition and it will be interrupted if a signal needs + * to be delivered to a handler in user space. + * + * The next program counter is set to the passed value + * before the SPU starts fetching code and the user space + * pointer gets updated with the new value when returning + * from kernel space. + * + * The status value returned from spu_run reflects the + * value of the spu_status register after the SPU has stopped. + * + * The function must get linked into the kernel, even if spufs + * itself is built as a module, so we can use the pointer in the + * system call table. + */ +long sys_spu_run(int fd, __u32 __user *unpc, __u32 __user *ustatus) +{ + struct file *filp; + struct spufs_inode_info *i; + long ret; + u32 npc, status; + int fput_needed; + + ret = -EBADF; + filp = fget_light(fd, &fput_needed); + if (!filp) + goto out; + + ret = -EFAULT; + if (get_user(npc, unpc) || get_user(status, ustatus)) + goto out; + + ret = -EINVAL; + if (filp->f_vfsmnt->mnt_sb->s_magic != SPUFS_MAGIC) + goto out_fput; + + i = SPUFS_I(filp->f_dentry->d_inode); + /* + * In order to call the underlying spu_run operation, we have the + * function pointer as part of our inode info. This is anything but + * nice, but it helps to avoid registering a global function pointer + * at module load time, which would be even worse imho. + */ + if (!i->i_spu_run) + goto out_fput; + ret = i->i_spu_run(filp, i->i_ctx, &npc, &status); + + if (put_user(npc, unpc)) + ret = -EFAULT; + +out_fput: + fput_light(filp, fput_needed); +out: + return ret; +} --- linux-cg.orig/include/asm-ppc/unistd.h 2005-08-25 23:12:31.265915576 -0400 +++ linux-cg/include/asm-ppc/unistd.h 2005-08-25 23:12:36.586905392 -0400 @@ -282,8 +282,9 @@ #define __NR_inotify_init 275 #define __NR_inotify_add_watch 276 #define __NR_inotify_rm_watch 277 +#define __NR_spu_run 278 -#define __NR_syscalls 278 +#define __NR_syscalls 279 #define __NR(n) #n --- linux-cg.orig/include/asm-ppc64/unistd.h 2005-08-25 23:12:31.268915120 -0400 +++ linux-cg/include/asm-ppc64/unistd.h 2005-08-25 23:12:36.586905392 -0400 @@ -288,8 +288,9 @@ #define __NR_inotify_init 275 #define __NR_inotify_add_watch 276 #define __NR_inotify_rm_watch 277 +#define __NR_spu_run 278 +#define __NR_syscalls 279 -#define __NR_syscalls 278 #ifdef __KERNEL__ #define NR_syscalls __NR_syscalls #endif --- linux-cg.orig/include/linux/syscalls.h 2005-08-25 23:12:31.270914816 -0400 +++ linux-cg/include/linux/syscalls.h 2005-08-25 23:12:36.587905240 -0400 @@ -509,4 +509,7 @@ asmlinkage long sys_keyctl(int cmd, unsi asmlinkage long sys_ioprio_set(int which, int who, int ioprio); asmlinkage long sys_ioprio_get(int which, int who); +asmlinkage long sys_spu_run(int fd, __u32 __user *unpc, + __u32 __user *ustatus); + #endif --- linux-cg.orig/kernel/sys_ni.c 2005-08-25 23:12:31.272914512 -0400 +++ linux-cg/kernel/sys_ni.c 2005-08-25 23:12:36.588905088 -0400 @@ -90,3 +90,4 @@ cond_syscall(sys_pciconfig_iobase); cond_syscall(sys32_ipc); cond_syscall(sys32_sysctl); cond_syscall(ppc_rtas); +cond_syscall(sys_spu_run); From arnd at arndb.de Fri Aug 26 08:04:17 2005 From: arnd at arndb.de (Arnd Bergmann) Date: Fri, 26 Aug 2005 00:04:17 +0200 Subject: [PATCH 3/7] spufs: kernel-side context switch code Message-ID: <200508260004.17825.arnd@arndb.de> This adds the code needed to perform a context switch from spufs, following the recommended 76-step sequence. From: Mark Nutter Signed-off-by: Arnd Bergmann -- switch.c | 2052 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 2046 insertions(+), 6 deletions(-) --- linux-cg.orig/fs/spufs/switch.c 2005-08-17 19:15:27.324893240 -0400 +++ linux-cg/fs/spufs/switch.c 2005-08-17 19:22:16.112922576 -0400 @@ -52,6 +52,2029 @@ #include "spu_save_dump.h" #include "spu_restore_dump.h" +#if 0 +#define POLL_WHILE_TRUE(_c) { \ + do { \ + } while (_c); \ + } +#else +#define RELAX_SPIN_COUNT 1000 +#define POLL_WHILE_TRUE(_c) { \ + do { \ + int _i; \ + for (_i=0; _iproblem; + u32 isolate_state; + + /* Save, Step 2: + * Save, Step 6: + * If SPU_Status[E,L,IS] any field is '1', this + * SPU is in isolate state and cannot be context + * saved at this time. + */ + isolate_state = SPU_STATUS_ISOLATED_STATE | + SPU_STATUS_ISOLATED_LOAD_STAUTUS | SPU_STATUS_ISOLATED_EXIT_STAUTUS; + return (in_be32(&prob->spu_status_R) & isolate_state) ? 1 : 0; +} + +static inline void disable_interrupts(struct spu_state *csa, struct spu *spu) +{ + struct spu_priv1 __iomem *priv1 = spu->priv1; + unsigned long flags; + + /* Save, Step 3: + * Restore, Step 2: + * Save INT_Mask_class0 in CSA. + * Write INT_MASK_class0 with value of 0. + * Save INT_Mask_class1 in CSA. + * Write INT_MASK_class1 with value of 0. + * Save INT_Mask_class2 in CSA. + * Write INT_MASK_class2 with value of 0. + */ + local_irq_save(flags); + if (csa) { + csa->priv1.int_mask_class0_RW = + in_be64(&priv1->int_mask_class0_RW); + csa->priv1.int_mask_class1_RW = + in_be64(&priv1->int_mask_class1_RW); + csa->priv1.int_mask_class2_RW = + in_be64(&priv1->int_mask_class2_RW); + } + out_be64(&priv1->int_mask_class0_RW, 0UL); + out_be64(&priv1->int_mask_class1_RW, 0UL); + out_be64(&priv1->int_mask_class2_RW, 0UL); + eieio(); + local_irq_restore(flags); +} + +static inline void set_watchdog_timer(struct spu_state *csa, struct spu *spu) +{ + /* Save, Step 4: + * Restore, Step 25. + * Set a software watchdog timer, which specifies the + * maximum allowable time for a context save sequence. + * + * For present, this implementation will not set a global + * watchdog timer, as virtualization & variable system load + * may cause unpredictable execution times. + */ +} + +static inline void inhibit_user_access(struct spu_state *csa, struct spu *spu) +{ + /* Save, Step 5: + * Restore, Step 3: + * Inhibit user-space access (if provided) to this + * SPU by unmapping the virtual pages assigned to + * the SPU memory-mapped I/O (MMIO) for problem + * state. TBD. + */ +} + +static inline void set_switch_pending(struct spu_state *csa, struct spu *spu) +{ + /* Save, Step 7: + * Restore, Step 5: + * Set a software context switch pending flag. + */ + set_bit(SPU_CONTEXT_SWITCH_PENDING_nr, &spu->flags); + mb(); +} + +static inline void save_mfc_cntl(struct spu_state *csa, struct spu *spu) +{ + struct spu_priv2 __iomem *priv2 = spu->priv2; + + /* Save, Step 8: + * Read and save MFC_CNTL[Ss]. + */ + if (csa) { + csa->priv2.mfc_control_RW = in_be64(&priv2->mfc_control_RW) & + MFC_CNTL_SUSPEND_DMA_STATUS_MASK; + } +} + +static inline void save_spu_runcntl(struct spu_state *csa, struct spu *spu) +{ + struct spu_problem __iomem *prob = spu->problem; + + /* Save, Step 9: + * Save SPU_Runcntl in the CSA. This value contains + * the "Application Desired State". + */ + csa->prob.spu_runcntl_RW = in_be32(&prob->spu_runcntl_RW); +} + +static inline void save_mfc_sr1(struct spu_state *csa, struct spu *spu) +{ + struct spu_priv1 __iomem *priv1 = spu->priv1; + + /* Save, Step 10: + * Save MFC_SR1 in the CSA. + */ + csa->priv1.mfc_sr1_RW = in_be64(&priv1->mfc_sr1_RW); +} + +static inline void save_spu_status(struct spu_state *csa, struct spu *spu) +{ + struct spu_problem __iomem *prob = spu->problem; + + /* Save, Step 11: + * Read SPU_Status[R], and save to CSA. + */ + if ((in_be32(&prob->spu_status_R) & SPU_STATUS_RUNNING) == 0) { + csa->prob.spu_status_R = in_be32(&prob->spu_status_R); + } else { + u32 stopped; + + out_be32(&prob->spu_runcntl_RW, SPU_RUNCNTL_STOP); + eieio(); + POLL_WHILE_TRUE(in_be32(&prob->spu_status_R) & + SPU_STATUS_RUNNING); + stopped = + SPU_STATUS_INVALID_INSTR | SPU_STATUS_SINGLE_STEP | + SPU_STATUS_STOPPED_BY_HALT | SPU_STATUS_STOPPED_BY_STOP; + if ((in_be32(&prob->spu_status_R) & stopped) == 0) + csa->prob.spu_status_R = SPU_STATUS_RUNNING; + else + csa->prob.spu_status_R = in_be32(&prob->spu_status_R); + } +} + +static inline void save_mfc_decr(struct spu_state *csa, struct spu *spu) +{ + struct spu_priv2 __iomem *priv2 = spu->priv2; + + /* Save, Step 12: + * Read MFC_CNTL[Ds]. Update saved copy of + * CSA.MFC_CNTL[Ds]. + */ + if (in_be64(&priv2->mfc_control_RW) & MFC_CNTL_DECREMENTER_RUNNING) { + csa->priv2.mfc_control_RW |= MFC_CNTL_DECREMENTER_RUNNING; + csa->suspend_time = get_cycles(); + out_be64(&priv2->spu_chnlcntptr_RW, 7ULL); + eieio(); + csa->spu_chnldata_RW[7] = in_be64(&priv2->spu_chnldata_RW); + eieio(); + } +} + +static inline void halt_mfc_decr(struct spu_state *csa, struct spu *spu) +{ + struct spu_priv2 __iomem *priv2 = spu->priv2; + + /* Save, Step 13: + * Write MFC_CNTL[Dh] set to a '1' to halt + * the decrementer. + */ + out_be64(&priv2->mfc_control_RW, MFC_CNTL_DECREMENTER_HALTED); + eieio(); +} + +static inline void save_timebase(struct spu_state *csa, struct spu *spu) +{ + /* Save, Step 14: + * Read PPE Timebase High and Timebase low registers + * and save in CSA. TBD. + */ + csa->suspend_time = get_cycles(); +} + +static inline void remove_other_spu_access(struct spu_state *csa, + struct spu *spu) +{ + /* Save, Step 15: + * Remove other SPU access to this SPU by unmapping + * this SPU's pages from their address space. TBD. + */ +} + +static inline void do_mfc_mssync(struct spu_state *csa, struct spu *spu) +{ + struct spu_problem __iomem *prob = spu->problem; + + /* Save, Step 16: + * Restore, Step 11. + * Write SPU_MSSync register. Poll SPU_MSSync[P] + * for a value of 0. + */ + out_be64(&prob->spc_mssync_RW, 1UL); + POLL_WHILE_TRUE(in_be64(&prob->spc_mssync_RW) & MS_SYNC_PENDING); +} + +static inline void issue_mfc_tlbie(struct spu_state *csa, struct spu *spu) +{ + struct spu_priv1 __iomem *priv1 = spu->priv1; + + /* Save, Step 17: + * Restore, Step 12. + * Restore, Step 48. + * Write TLB_Invalidate_Entry[IS,VPN,L,Lp]=0 register. + * Then issue a PPE sync instruction. + */ + out_be64(&priv1->tlb_invalidate_entry_W, 0UL); + mb(); +} + +static inline void handle_pending_interrupts(struct spu_state *csa, + struct spu *spu) +{ + /* Save, Step 18: + * Handle any pending interrupts from this SPU + * here. This is OS or hypervisor specific. One + * option is to re-enable interrupts to handle any + * pending interrupts, with the interrupt handlers + * recognizing the software Context Switch Pending + * flag, to ensure the SPU execution or MFC command + * queue is not restarted. TBD. + */ +} + +static inline void save_mfc_queues(struct spu_state *csa, struct spu *spu) +{ + struct spu_priv2 __iomem *priv2 = spu->priv2; + int i; + + /* Save, Step 19: + * If MFC_Cntl[Se]=0 then save + * MFC command queues. + */ + if ((in_be64(&priv2->mfc_control_RW) & MFC_CNTL_DMA_QUEUES_EMPTY) == 0) { + for (i = 0; i < 8; i++) { + csa->priv2.puq[i].mfc_cq_data0_RW = + in_be64(&priv2->puq[i].mfc_cq_data0_RW); + csa->priv2.puq[i].mfc_cq_data1_RW = + in_be64(&priv2->puq[i].mfc_cq_data1_RW); + csa->priv2.puq[i].mfc_cq_data2_RW = + in_be64(&priv2->puq[i].mfc_cq_data2_RW); + csa->priv2.puq[i].mfc_cq_data3_RW = + in_be64(&priv2->puq[i].mfc_cq_data3_RW); + } + for (i = 0; i < 16; i++) { + csa->priv2.spuq[i].mfc_cq_data0_RW = + in_be64(&priv2->spuq[i].mfc_cq_data0_RW); + csa->priv2.spuq[i].mfc_cq_data1_RW = + in_be64(&priv2->spuq[i].mfc_cq_data1_RW); + csa->priv2.spuq[i].mfc_cq_data2_RW = + in_be64(&priv2->spuq[i].mfc_cq_data2_RW); + csa->priv2.spuq[i].mfc_cq_data3_RW = + in_be64(&priv2->spuq[i].mfc_cq_data3_RW); + } + } +} + +static inline void save_ppu_querymask(struct spu_state *csa, struct spu *spu) +{ + struct spu_problem __iomem *prob = spu->problem; + + /* Save, Step 20: + * Save the PPU_QueryMask register + * in the CSA. + */ + csa->prob.dma_querymask_RW = in_be32(&prob->dma_querymask_RW); +} + +static inline void save_ppu_querytype(struct spu_state *csa, struct spu *spu) +{ + struct spu_problem __iomem *prob = spu->problem; + + /* Save, Step 21: + * Save the PPU_QueryType register + * in the CSA. + */ + csa->prob.dma_querytype_RW = in_be32(&prob->dma_querytype_RW); +} + +static inline void save_mfc_csr_tsq(struct spu_state *csa, struct spu *spu) +{ + struct spu_priv2 __iomem *priv2 = spu->priv2; + + /* Save, Step 22: + * Save the MFC_CSR_TSQ register + * in the LSCSA. + */ + csa->priv2.spu_tag_status_query_RW = + in_be64(&priv2->spu_tag_status_query_RW); +} + +static inline void save_mfc_csr_cmd(struct spu_state *csa, struct spu *spu) +{ + struct spu_priv2 __iomem *priv2 = spu->priv2; + + /* Save, Step 23: + * Save the MFC_CSR_CMD1 and MFC_CSR_CMD2 + * registers in the CSA. + */ + csa->priv2.spu_cmd_buf1_RW = in_be64(&priv2->spu_cmd_buf1_RW); + csa->priv2.spu_cmd_buf2_RW = in_be64(&priv2->spu_cmd_buf2_RW); +} + +static inline void save_mfc_csr_ato(struct spu_state *csa, struct spu *spu) +{ + struct spu_priv2 __iomem *priv2 = spu->priv2; + + /* Save, Step 24: + * Save the MFC_CSR_ATO register in + * the CSA. + */ + csa->priv2.spu_atomic_status_RW = in_be64(&priv2->spu_atomic_status_RW); +} + +static inline void save_mfc_tclass_id(struct spu_state *csa, struct spu *spu) +{ + struct spu_priv1 __iomem *priv1 = spu->priv1; + + /* Save, Step 25: + * Save the MFC_TCLASS_ID register in + * the CSA. + */ + csa->priv1.mfc_tclass_id_RW = in_be64(&priv1->mfc_tclass_id_RW); +} + +static inline void set_mfc_tclass_id(struct spu_state *csa, struct spu *spu) +{ + struct spu_priv1 __iomem *priv1 = spu->priv1; + + /* Save, Step 26: + * Restore, Step 23. + * Write the MFC_TCLASS_ID register with + * the value 0x10000000. + */ + out_be64(&priv1->mfc_tclass_id_RW, 0x10000000); + eieio(); +} + +static inline void purge_mfc_queue(struct spu_state *csa, struct spu *spu) +{ + struct spu_priv2 __iomem *priv2 = spu->priv2; + + /* Save, Step 27: + * Restore, Step 14. + * Write MFC_CNTL[Pc]=1 (purge queue). + */ + out_be64(&priv2->mfc_control_RW, MFC_CNTL_PURGE_DMA_REQUEST); + eieio(); +} + +static inline void wait_purge_complete(struct spu_state *csa, struct spu *spu) +{ + struct spu_priv2 __iomem *priv2 = spu->priv2; + + /* Save, Step 28: + * Poll MFC_CNTL[Ps] until value '11' is read + * (purge complete). + */ + POLL_WHILE_FALSE(in_be64(&priv2->mfc_control_RW) & + MFC_CNTL_PURGE_DMA_COMPLETE); +} + +static inline void save_mfc_slbs(struct spu_state *csa, struct spu *spu) +{ + struct spu_priv1 __iomem *priv1 = spu->priv1; + struct spu_priv2 __iomem *priv2 = spu->priv2; + int i; + + /* Save, Step 29: + * If MFC_SR1[R]='1', save SLBs in CSA. + */ + if (in_be64(&priv1->mfc_sr1_RW) & MFC_STATE1_RELOCATE_MASK) { + csa->priv2.slb_index_W = in_be64(&priv2->slb_index_W); + for (i = 0; i < 8; i++) { + out_be64(&priv2->slb_index_W, i); + eieio(); + csa->slb_esid_RW[i] = in_be64(&priv2->slb_esid_RW); + csa->slb_vsid_RW[i] = in_be64(&priv2->slb_vsid_RW); + eieio(); + } + } +} + +static inline void setup_mfc_sr1(struct spu_state *csa, struct spu *spu) +{ + struct spu_priv1 __iomem *priv1 = spu->priv1; + + /* Save, Step 30: + * Restore, Step 18: + * Write MFC_SR1 with MFC_SR1[D=0,S=1] and + * MFC_SR1[TL,R,Pr,T] set correctly for the + * OS specific environment. + * + * Implementation note: The SPU-side code + * for save/restore is privileged, so the + * MFC_SR1[Pr] bit is not set. + * + */ + out_be64(&priv1->mfc_sr1_RW, (MFC_STATE1_MASTER_RUN_CONTROL_MASK | + MFC_STATE1_RELOCATE_MASK | + MFC_STATE1_BUS_TLBIE_MASK)); +} + +static inline void save_spu_npc(struct spu_state *csa, struct spu *spu) +{ + struct spu_problem __iomem *prob = spu->problem; + + /* Save, Step 31: + * Save SPU_NPC in the CSA. + */ + csa->prob.spu_npc_RW = in_be32(&prob->spu_npc_RW); +} + +static inline void save_spu_privcntl(struct spu_state *csa, struct spu *spu) +{ + struct spu_priv2 __iomem *priv2 = spu->priv2; + + /* Save, Step 32: + * Save SPU_PrivCntl in the CSA. + */ + csa->priv2.spu_privcntl_RW = in_be64(&priv2->spu_privcntl_RW); +} + +static inline void reset_spu_privcntl(struct spu_state *csa, struct spu *spu) +{ + struct spu_priv2 __iomem *priv2 = spu->priv2; + + /* Save, Step 33: + * Restore, Step 16: + * Write SPU_PrivCntl[S,Le,A] fields reset to 0. + */ + out_be64(&priv2->spu_privcntl_RW, 0UL); + eieio(); +} + +static inline void save_spu_lslr(struct spu_state *csa, struct spu *spu) +{ + struct spu_priv2 __iomem *priv2 = spu->priv2; + + /* Save, Step 34: + * Save SPU_LSLR in the CSA. + */ + csa->priv2.spu_lslr_RW = in_be64(&priv2->spu_lslr_RW); +} + +static inline void reset_spu_lslr(struct spu_state *csa, struct spu *spu) +{ + struct spu_priv2 __iomem *priv2 = spu->priv2; + + /* Save, Step 35: + * Restore, Step 17. + * Reset SPU_LSLR. + */ + out_be64(&priv2->spu_lslr_RW, LS_ADDR_MASK); + eieio(); +} + +static inline void save_spu_cfg(struct spu_state *csa, struct spu *spu) +{ + struct spu_priv2 __iomem *priv2 = spu->priv2; + + /* Save, Step 36: + * Save SPU_Cfg in the CSA. + */ + csa->priv2.spu_cfg_RW = in_be64(&priv2->spu_cfg_RW); +} + +static inline void save_pm_trace(struct spu_state *csa, struct spu *spu) +{ + struct spu_priv2 __iomem *priv2 = spu->priv2; + + /* Save, Step 37: + * Save PM_Trace_Tag_Wait_Mask in the CSA. + */ + csa->priv2.spu_pm_trace_tag_status_RW = + in_be64(&priv2->spu_pm_trace_tag_status_RW); +} + +static inline void save_mfc_rag(struct spu_state *csa, struct spu *spu) +{ + struct spu_priv1 __iomem *priv1 = spu->priv1; + + /* Save, Step 38: + * Save RA_GROUP_ID register and the + * RA_ENABLE reigster in the CSA. + */ + csa->priv1.resource_allocation_groupID_RW = + in_be64(&priv1->resource_allocation_groupID_RW); + csa->priv1.resource_allocation_enable_RW = + in_be64(&priv1->resource_allocation_enable_RW); +} + +static inline void save_ppu_mb_stat(struct spu_state *csa, struct spu *spu) +{ + struct spu_problem __iomem *prob = spu->problem; + + /* Save, Step 39: + * Save MB_Stat register in the CSA. + */ + csa->prob.mb_stat_R = in_be32(&prob->mb_stat_R); +} + +static inline void save_ppu_mb(struct spu_state *csa, struct spu *spu) +{ + struct spu_problem __iomem *prob = spu->problem; + + /* Save, Step 40: + * Save the PPU_MB register in the CSA. + */ + csa->prob.pu_mb_R = in_be32(&prob->pu_mb_R); +} + +static inline void save_ppuint_mb(struct spu_state *csa, struct spu *spu) +{ + struct spu_priv2 __iomem *priv2 = spu->priv2; + + /* Save, Step 41: + * Save the PPUINT_MB register in the CSA. + */ + csa->priv2.puint_mb_R = in_be64(&priv2->puint_mb_R); +} + +static inline void save_ch_part1(struct spu_state *csa, struct spu *spu) +{ + struct spu_priv2 __iomem *priv2 = spu->priv2; + u64 idx, ch_indices[7] = { 0UL, 1UL, 3UL, 4UL, 24UL, 25UL, 27UL }; + int i; + + /* Save, Step 42: + * Save the following CH: [0,1,3,4,24,25,27] + */ + for (i = 0; i < 7; i++) { + idx = ch_indices[i]; + out_be64(&priv2->spu_chnlcntptr_RW, idx); + eieio(); + csa->spu_chnldata_RW[idx] = in_be64(&priv2->spu_chnldata_RW); + csa->spu_chnlcnt_RW[idx] = in_be64(&priv2->spu_chnlcnt_RW); + out_be64(&priv2->spu_chnldata_RW, 0UL); + out_be64(&priv2->spu_chnlcnt_RW, 0UL); + eieio(); + } +} + +static inline void save_spu_mb(struct spu_state *csa, struct spu *spu) +{ + struct spu_priv2 __iomem *priv2 = spu->priv2; + int i; + + /* Save, Step 43: + * Save SPU Read Mailbox Channel. + */ + out_be64(&priv2->spu_chnlcntptr_RW, 29UL); + eieio(); + csa->spu_chnlcnt_RW[29] = in_be64(&priv2->spu_chnlcnt_RW); + for (i = 0; i < 4; i++) { + csa->pu_mailbox_data[i] = in_be64(&priv2->spu_chnldata_RW); + } + out_be64(&priv2->spu_chnlcnt_RW, 0UL); + eieio(); +} + +static inline void save_mfc_cmd(struct spu_state *csa, struct spu *spu) +{ + struct spu_priv2 __iomem *priv2 = spu->priv2; + + /* Save, Step 44: + * Save MFC_CMD Channel. + */ + out_be64(&priv2->spu_chnlcntptr_RW, 21UL); + eieio(); + csa->spu_chnlcnt_RW[21] = in_be64(&priv2->spu_chnlcnt_RW); + eieio(); +} + +static inline void reset_ch(struct spu_state *csa, struct spu *spu) +{ + struct spu_priv2 __iomem *priv2 = spu->priv2; + u64 ch_indices[4] = { 21UL, 23UL, 28UL, 30UL }; + u64 ch_counts[4] = { 16UL, 1UL, 1UL, 1UL }; + u64 idx; + int i; + + /* Save, Step 45: + * Reset the following CH: [21, 23, 28, 30] + */ + for (i = 0; i < 4; i++) { + idx = ch_indices[i]; + out_be64(&priv2->spu_chnlcntptr_RW, idx); + eieio(); + out_be64(&priv2->spu_chnlcnt_RW, ch_counts[i]); + eieio(); + } +} + +static inline void resume_mfc_queue(struct spu_state *csa, struct spu *spu) +{ + struct spu_priv2 __iomem *priv2 = spu->priv2; + + /* Save, Step 46: + * Restore, Step 25. + * Write MFC_CNTL[Sc]=0 (resume queue processing). + */ + out_be64(&priv2->mfc_control_RW, MFC_CNTL_RESUME_DMA_QUEUE); +} + +static inline void invalidate_slbs(struct spu_state *csa, struct spu *spu) +{ + struct spu_priv1 __iomem *priv1 = spu->priv1; + struct spu_priv2 __iomem *priv2 = spu->priv2; + + /* Save, Step 45: + * Restore, Step 19: + * If MFC_SR1[R]=1, write 0 to SLB_Invalidate_All. + */ + if (in_be64(&priv1->mfc_sr1_RW) & MFC_STATE1_RELOCATE_MASK) { + out_be64(&priv2->slb_invalidate_all_W, 0UL); + eieio(); + } +} + +static inline void get_kernel_slb(u64 ea, u64 slb[2]) +{ + slb[0] = (get_kernel_vsid(ea) << SLB_VSID_SHIFT) | SLB_VSID_KERNEL; + slb[1] = (ea & ESID_MASK) | SLB_ESID_V; + + /* Large pages are used for kernel text/data, but not vmalloc. */ + if (cpu_has_feature(CPU_FTR_16M_PAGE) + && REGION_ID(ea) == KERNEL_REGION_ID) + slb[0] |= SLB_VSID_L; +} + +static inline void load_mfc_slb(struct spu *spu, u64 slb[2], int slbe) +{ + struct spu_priv2 __iomem *priv2 = spu->priv2; + + out_be64(&priv2->slb_index_W, slbe); + eieio(); + out_be64(&priv2->slb_vsid_RW, slb[0]); + out_be64(&priv2->slb_esid_RW, slb[1]); + eieio(); +} + +static inline void setup_mfc_slbs(struct spu_state *csa, struct spu *spu) +{ + u64 code_slb[2]; + u64 lscsa_slb[2]; + + /* Save, Step 47: + * Restore, Step 30. + * If MFC_SR1[R]=1, write 0 to SLB_Invalidate_All + * register, then initialize SLB_VSID and SLB_ESID + * to provide access to SPU context save code and + * LSCSA. + * + * This implementation places both the context + * switch code and LSCSA in kernel address space. + * + * Further this implementation assumes that the + * MFC_SR1[R]=1 (in other words, assume that + * translation is desired by OS environment). + */ + invalidate_slbs(csa, spu); + get_kernel_slb((unsigned long)&spu_save_code[0], code_slb); + get_kernel_slb((unsigned long)csa->lscsa, lscsa_slb); + load_mfc_slb(spu, code_slb, 0); + if ((lscsa_slb[0] != code_slb[0]) || (lscsa_slb[1] != code_slb[1])) + load_mfc_slb(spu, lscsa_slb, 1); +} + +static inline void set_switch_active(struct spu_state *csa, struct spu *spu) +{ + /* Save, Step 48: + * Restore, Step 23. + * Change the software context switch pending flag + * to context switch active. + */ + set_bit(SPU_CONTEXT_SWITCH_ACTIVE_nr, &spu->flags); + clear_bit(SPU_CONTEXT_SWITCH_PENDING_nr, &spu->flags); + mb(); +} + +static inline void enable_interrupts(struct spu_state *csa, struct spu *spu) +{ + struct spu_priv1 __iomem *priv1 = spu->priv1; + unsigned long flags, class1_mask = CLASS1_ENABLE_SEGMENT_FAULT_INTR | + CLASS1_ENABLE_STORAGE_FAULT_INTR; + + /* Save, Step 49: + * Restore, Step 22: + * Reset and then enable interrupts, as + * needed by OS. + * + * This implementation enables only class1 + * (translation) interrupts. + */ + local_irq_save(flags); + out_be64(&priv1->int_stat_class0_RW, ~(0UL)); + out_be64(&priv1->int_stat_class1_RW, ~(0UL)); + out_be64(&priv1->int_stat_class2_RW, ~(0UL)); + out_be64(&priv1->int_mask_class0_RW, 0UL); + out_be64(&priv1->int_mask_class1_RW, class1_mask); + out_be64(&priv1->int_mask_class2_RW, 0UL); + local_irq_restore(flags); +} + +static inline int send_mfc_dma(struct spu *spu, unsigned long ea, + unsigned int ls_offset, unsigned int size, + unsigned int tag, unsigned int rclass, + unsigned int cmd) +{ + struct spu_problem __iomem *prob = spu->problem; + union mfc_tag_size_class_cmd command; + unsigned int transfer_size; + volatile unsigned int status = 0x0; + + while (size > 0) { + transfer_size = + (size > MFC_MAX_DMA_SIZE) ? MFC_MAX_DMA_SIZE : size; + command.u.mfc_size = transfer_size; + command.u.mfc_tag = tag; + command.u.mfc_rclassid = rclass; + command.u.mfc_cmd = cmd; + do { + out_be32(&prob->mfc_lsa_W, ls_offset); + out_be64(&prob->mfc_ea_W, ea); + out_be64(&prob->mfc_union_W.all64, command.all64); + status = + in_be32(&prob->mfc_union_W.by32.mfc_class_cmd32); + if (unlikely(status & 0x2)) { + cpu_relax(); + } + } while (status & 0x3); + size -= transfer_size; + ea += transfer_size; + ls_offset += transfer_size; + } + return 0; +} + +static inline void save_ls_16kb(struct spu_state *csa, struct spu *spu) +{ + unsigned long addr = (unsigned long)&csa->lscsa->ls[0]; + unsigned int ls_offset = 0x0; + unsigned int size = 16384; + unsigned int tag = 0; + unsigned int rclass = 0; + unsigned int cmd = MFC_PUT_CMD; + + /* Save, Step 50: + * Issue a DMA command to copy the first 16K bytes + * of local storage to the CSA. + */ + send_mfc_dma(spu, addr, ls_offset, size, tag, rclass, cmd); +} + +static inline void set_spu_npc(struct spu_state *csa, struct spu *spu) +{ + struct spu_problem __iomem *prob = spu->problem; + + /* Save, Step 51: + * Restore, Step 31. + * Write SPU_NPC[IE]=0 and SPU_NPC[LSA] to entry + * point address of context save code in local + * storage. + * + * This implementation uses SPU-side save/restore + * programs with entry points at LSA of 0. + */ + out_be32(&prob->spu_npc_RW, 0); + eieio(); +} + +static inline void set_signot1(struct spu_state *csa, struct spu *spu) +{ + struct spu_problem __iomem *prob = spu->problem; + union { + u64 ull; + u32 ui[2]; + } addr64; + + /* Save, Step 52: + * Restore, Step 32: + * Write SPU_Sig_Notify_1 register with upper 32-bits + * of the CSA.LSCSA effective address. + */ + addr64.ull = (u64) csa->lscsa; + out_be32(&prob->signal_notify1, addr64.ui[0]); + eieio(); +} + +static inline void set_signot2(struct spu_state *csa, struct spu *spu) +{ + struct spu_problem __iomem *prob = spu->problem; + union { + u64 ull; + u32 ui[2]; + } addr64; + + /* Save, Step 53: + * Restore, Step 33: + * Write SPU_Sig_Notify_2 register with lower 32-bits + * of the CSA.LSCSA effective address. + */ + addr64.ull = (u64) csa->lscsa; + out_be32(&prob->signal_notify2, addr64.ui[1]); + eieio(); +} + +static inline void send_save_code(struct spu_state *csa, struct spu *spu) +{ + unsigned long addr = (unsigned long)&spu_save_code[0]; + unsigned int ls_offset = 0x0; + unsigned int size = sizeof(spu_save_code); + unsigned int tag = 0; + unsigned int rclass = 0; + unsigned int cmd = MFC_GETFS_CMD; + + /* Save, Step 54: + * Issue a DMA command to copy context save code + * to local storage and start SPU. + */ + send_mfc_dma(spu, addr, ls_offset, size, tag, rclass, cmd); +} + +static inline void set_ppu_querymask(struct spu_state *csa, struct spu *spu) +{ + struct spu_problem __iomem *prob = spu->problem; + + /* Save, Step 55: + * Restore, Step 38. + * Write PPU_QueryMask=1 (enable Tag Group 0) + * and issue eieio instruction. + */ + out_be32(&prob->dma_querymask_RW, MFC_TAGID_TO_TAGMASK(0)); + eieio(); +} + +static inline void wait_tag_complete(struct spu_state *csa, struct spu *spu) +{ + struct spu_priv1 __iomem *priv1 = spu->priv1; + struct spu_problem __iomem *prob = spu->problem; + u32 mask = MFC_TAGID_TO_TAGMASK(0); + unsigned long flags; + + /* Save, Step 56: + * Restore, Step 39. + * Restore, Step 39. + * Restore, Step 46. + * Poll PPU_TagStatus[gn] until 01 (Tag group 0 complete) + * or write PPU_QueryType[TS]=01 and wait for Tag Group + * Complete Interrupt. Write INT_Stat_Class0 or + * INT_Stat_Class2 with value of 'handled'. + */ + POLL_WHILE_FALSE(in_be32(&prob->dma_tagstatus_R) & mask); + + local_irq_save(flags); + out_be64(&priv1->int_stat_class0_RW, ~(0UL)); + out_be64(&priv1->int_stat_class2_RW, ~(0UL)); + local_irq_restore(flags); +} + +static inline void wait_spu_stopped(struct spu_state *csa, struct spu *spu) +{ + struct spu_priv1 __iomem *priv1 = spu->priv1; + struct spu_problem __iomem *prob = spu->problem; + unsigned long flags; + + /* Save, Step 57: + * Restore, Step 40. + * Poll until SPU_Status[R]=0 or wait for SPU Class 0 + * or SPU Class 2 interrupt. Write INT_Stat_class0 + * or INT_Stat_class2 with value of handled. + */ + POLL_WHILE_TRUE(in_be32(&prob->spu_status_R) & SPU_STATUS_RUNNING); + + local_irq_save(flags); + out_be64(&priv1->int_stat_class0_RW, ~(0UL)); + out_be64(&priv1->int_stat_class2_RW, ~(0UL)); + local_irq_restore(flags); +} + +static inline int check_save_status(struct spu_state *csa, struct spu *spu) +{ + struct spu_problem __iomem *prob = spu->problem; + u32 complete; + + /* Save, Step 54: + * If SPU_Status[P]=1 and SPU_Status[SC] = "success", + * context save succeeded, otherwise context save + * failed. + */ + complete = ((SPU_SAVE_COMPLETE << SPU_STOP_STATUS_SHIFT) | + SPU_STATUS_STOPPED_BY_STOP); + return (in_be32(&prob->spu_status_R) != complete) ? 1 : 0; +} + +static inline void terminate_spu_app(struct spu_state *csa, struct spu *spu) +{ + /* Restore, Step 4: + * If required, notify the "using application" that + * the SPU task has been terminated. TBD. + */ +} + +static inline void suspend_mfc(struct spu_state *csa, struct spu *spu) +{ + struct spu_priv2 __iomem *priv2 = spu->priv2; + + /* Restore, Step 7: + * Restore, Step 47. + * Write MFC_Cntl[Dh,Sc]='1','1' to suspend + * the queue and halt the decrementer. + */ + out_be64(&priv2->mfc_control_RW, MFC_CNTL_SUSPEND_DMA_QUEUE | + MFC_CNTL_DECREMENTER_HALTED); + eieio(); +} + +static inline void wait_suspend_mfc_complete(struct spu_state *csa, + struct spu *spu) +{ + struct spu_priv2 __iomem *priv2 = spu->priv2; + + /* Restore, Step 8: + * Restore, Step 47. + * Poll MFC_CNTL[Ss] until 11 is returned. + */ + POLL_WHILE_FALSE(in_be64(&priv2->mfc_control_RW) & + MFC_CNTL_SUSPEND_COMPLETE); +} + +static inline int suspend_spe(struct spu_state *csa, struct spu *spu) +{ + struct spu_problem __iomem *prob = spu->problem; + + /* Restore, Step 9: + * If SPU_Status[R]=1, stop SPU execution + * and wait for stop to complete. + * + * Returns 1 if SPU_Status[R]=1 on entry. + * 0 otherwise + */ + if (in_be32(&prob->spu_status_R) & SPU_STATUS_RUNNING) { + if (in_be32(&prob->spu_status_R) & + SPU_STATUS_ISOLATED_EXIT_STAUTUS) { + POLL_WHILE_TRUE(in_be32(&prob->spu_status_R) & + SPU_STATUS_RUNNING); + } + if ((in_be32(&prob->spu_status_R) & + SPU_STATUS_ISOLATED_LOAD_STAUTUS) + || (in_be32(&prob->spu_status_R) & + SPU_STATUS_ISOLATED_STATE)) { + out_be32(&prob->spu_runcntl_RW, SPU_RUNCNTL_STOP); + eieio(); + POLL_WHILE_TRUE(in_be32(&prob->spu_status_R) & + SPU_STATUS_RUNNING); + out_be32(&prob->spu_runcntl_RW, 0x2); + eieio(); + POLL_WHILE_TRUE(in_be32(&prob->spu_status_R) & + SPU_STATUS_RUNNING); + } + if (in_be32(&prob->spu_status_R) & + SPU_STATUS_WAITING_FOR_CHANNEL) { + out_be32(&prob->spu_runcntl_RW, SPU_RUNCNTL_STOP); + eieio(); + POLL_WHILE_TRUE(in_be32(&prob->spu_status_R) & + SPU_STATUS_RUNNING); + } + return 1; + } + return 0; +} + +static inline void clear_spu_status(struct spu_state *csa, struct spu *spu) +{ + struct spu_problem __iomem *prob = spu->problem; + struct spu_priv1 __iomem *priv1 = spu->priv1; + + /* Restore, Step 10: + * If SPU_Status[R]=0 and SPU_Status[E,L,IS]=1, + * release SPU from isolate state. + */ + if (!(in_be32(&prob->spu_status_R) & SPU_STATUS_RUNNING)) { + if (in_be32(&prob->spu_status_R) & + SPU_STATUS_ISOLATED_EXIT_STAUTUS) { + out_be64(&priv1->mfc_sr1_RW, + MFC_STATE1_MASTER_RUN_CONTROL_MASK); + eieio(); + out_be32(&prob->spu_runcntl_RW, SPU_RUNCNTL_RUNNABLE); + eieio(); + POLL_WHILE_TRUE(in_be32(&prob->spu_status_R) & + SPU_STATUS_RUNNING); + } + if ((in_be32(&prob->spu_status_R) & + SPU_STATUS_ISOLATED_LOAD_STAUTUS) + || (in_be32(&prob->spu_status_R) & + SPU_STATUS_ISOLATED_STATE)) { + out_be64(&priv1->mfc_sr1_RW, + MFC_STATE1_MASTER_RUN_CONTROL_MASK); + eieio(); + out_be32(&prob->spu_runcntl_RW, 0x2); + eieio(); + POLL_WHILE_TRUE(in_be32(&prob->spu_status_R) & + SPU_STATUS_RUNNING); + } + } +} + +static inline void reset_ch_part1(struct spu_state *csa, struct spu *spu) +{ + struct spu_priv2 __iomem *priv2 = spu->priv2; + u64 ch_indices[7] = { 0UL, 1UL, 3UL, 4UL, 24UL, 25UL, 27UL }; + u64 idx; + int i; + + /* Restore, Step 20: + * Reset the following CH: [0,1,3,4,24,25,27] + */ + for (i = 0; i < 7; i++) { + idx = ch_indices[i]; + out_be64(&priv2->spu_chnlcntptr_RW, idx); + eieio(); + out_be64(&priv2->spu_chnldata_RW, 0UL); + out_be64(&priv2->spu_chnlcnt_RW, 0UL); + eieio(); + } +} + +static inline void reset_ch_part2(struct spu_state *csa, struct spu *spu) +{ + struct spu_priv2 __iomem *priv2 = spu->priv2; + u64 ch_indices[5] = { 21UL, 23UL, 28UL, 29UL, 30UL }; + u64 ch_counts[5] = { 16UL, 1UL, 1UL, 0UL, 1UL }; + u64 idx; + int i; + + /* Restore, Step 21: + * Reset the following CH: [21, 23, 28, 29, 30] + */ + for (i = 0; i < 5; i++) { + idx = ch_indices[i]; + out_be64(&priv2->spu_chnlcntptr_RW, idx); + eieio(); + out_be64(&priv2->spu_chnlcnt_RW, ch_counts[i]); + eieio(); + } +} + +static inline void setup_spu_status_part1(struct spu_state *csa, + struct spu *spu) +{ + u32 status_P = SPU_STATUS_STOPPED_BY_STOP; + u32 status_I = SPU_STATUS_INVALID_INSTR; + u32 status_H = SPU_STATUS_STOPPED_BY_HALT; + u32 status_S = SPU_STATUS_SINGLE_STEP; + u32 status_S_I = SPU_STATUS_SINGLE_STEP | SPU_STATUS_INVALID_INSTR; + u32 status_S_P = SPU_STATUS_SINGLE_STEP | SPU_STATUS_STOPPED_BY_STOP; + u32 status_P_H = SPU_STATUS_STOPPED_BY_HALT |SPU_STATUS_STOPPED_BY_STOP; + u32 status_P_I = SPU_STATUS_STOPPED_BY_STOP |SPU_STATUS_INVALID_INSTR; + u32 status_code; + + /* Restore, Step 27: + * If the CSA.SPU_Status[I,S,H,P]=1 then add the correct + * instruction sequence to the end of the SPU based restore + * code (after the "context restored" stop and signal) to + * restore the correct SPU status. + * + * NOTE: Rather than modifying the SPU executable, we + * instead add a new 'stopped_status' field to the + * LSCSA. The SPU-side restore reads this field and + * takes the appropriate action when exiting. + */ + + status_code = + (csa->prob.spu_status_R >> SPU_STOP_STATUS_SHIFT) & 0xFFFF; + if (csa->prob.spu_status_R & status_P_I) { + + /* SPU_Status[P,I]=1 - Illegal Instruction followed + * by Stop and Signal instruction, followed by 'br -4'. + * + */ + csa->lscsa->stopped_status.slot[0] = SPU_STOPPED_STATUS_P_I; + csa->lscsa->stopped_status.slot[1] = status_code; + + } else if (csa->prob.spu_status_R & status_P_H) { + + /* SPU_Status[P,H]=1 - Halt Conditional, followed + * by Stop and Signal instruction, followed by + * 'br -4'. + */ + csa->lscsa->stopped_status.slot[0] = SPU_STOPPED_STATUS_P_H; + csa->lscsa->stopped_status.slot[1] = status_code; + + } else if (csa->prob.spu_status_R & status_S_P) { + + /* SPU_Status[S,P]=1 - Stop and Signal instruction + * followed by 'br -4'. + */ + csa->lscsa->stopped_status.slot[0] = SPU_STOPPED_STATUS_S_P; + csa->lscsa->stopped_status.slot[1] = status_code; + + } else if (csa->prob.spu_status_R & status_S_I) { + + /* SPU_Status[S,I]=1 - Illegal instruction followed + * by 'br -4'. + */ + csa->lscsa->stopped_status.slot[0] = SPU_STOPPED_STATUS_S_I; + csa->lscsa->stopped_status.slot[1] = status_code; + + } else if (csa->prob.spu_status_R & status_P) { + + /* SPU_Status[P]=1 - Stop and Signal instruction + * followed by 'br -4'. + */ + csa->lscsa->stopped_status.slot[0] = SPU_STOPPED_STATUS_P; + csa->lscsa->stopped_status.slot[1] = status_code; + + } else if (csa->prob.spu_status_R & status_H) { + + /* SPU_Status[H]=1 - Halt Conditional, followed + * by 'br -4'. + */ + csa->lscsa->stopped_status.slot[0] = SPU_STOPPED_STATUS_H; + + } else if (csa->prob.spu_status_R & status_S) { + + /* SPU_Status[S]=1 - Two nop instructions. + */ + csa->lscsa->stopped_status.slot[0] = SPU_STOPPED_STATUS_S; + + } else if (csa->prob.spu_status_R & status_I) { + + /* SPU_Status[I]=1 - Illegal instruction followed + * by 'br -4'. + */ + csa->lscsa->stopped_status.slot[0] = SPU_STOPPED_STATUS_I; + + } +} + +static inline void setup_spu_status_part2(struct spu_state *csa, + struct spu *spu) +{ + u32 mask; + + /* Restore, Step 28: + * If the CSA.SPU_Status[I,S,H,P,R]=0 then + * add a 'br *' instruction to the end of + * the SPU based restore code. + * + * NOTE: Rather than modifying the SPU executable, we + * instead add a new 'stopped_status' field to the + * LSCSA. The SPU-side restore reads this field and + * takes the appropriate action when exiting. + */ + mask = SPU_STATUS_INVALID_INSTR | + SPU_STATUS_SINGLE_STEP | + SPU_STATUS_STOPPED_BY_HALT | + SPU_STATUS_STOPPED_BY_STOP | SPU_STATUS_RUNNING; + if (!(csa->prob.spu_status_R & mask)) { + csa->lscsa->stopped_status.slot[0] = SPU_STOPPED_STATUS_R; + } +} + +static inline void restore_mfc_rag(struct spu_state *csa, struct spu *spu) +{ + struct spu_priv1 __iomem *priv1 = spu->priv1; + + /* Restore, Step 29: + * Restore RA_GROUP_ID register and the + * RA_ENABLE reigster from the CSA. + */ + out_be64(&priv1->resource_allocation_groupID_RW, + csa->priv1.resource_allocation_groupID_RW); + out_be64(&priv1->resource_allocation_enable_RW, + csa->priv1.resource_allocation_enable_RW); +} + +static inline void send_restore_code(struct spu_state *csa, struct spu *spu) +{ + unsigned long addr = (unsigned long)&spu_restore_code[0]; + unsigned int ls_offset = 0x0; + unsigned int size = sizeof(spu_restore_code); + unsigned int tag = 0; + unsigned int rclass = 0; + unsigned int cmd = MFC_GETFS_CMD; + + /* Restore, Step 37: + * Issue MFC DMA command to copy context + * restore code to local storage. + */ + send_mfc_dma(spu, addr, ls_offset, size, tag, rclass, cmd); +} + +static inline void setup_decr(struct spu_state *csa, struct spu *spu) +{ + /* Restore, Step 34: + * If CSA.MFC_CNTL[Ds]=1 (decrementer was + * running) then adjust decrementer, set + * decrementer running status in LSCSA, + * and set decrementer "wrapped" status + * in LSCSA. + */ + if (csa->priv2.mfc_control_RW & MFC_CNTL_DECREMENTER_RUNNING) { + cycles_t resume_time = get_cycles(); + cycles_t delta_time = resume_time - csa->suspend_time; + + csa->lscsa->decr.slot[0] = delta_time; + } +} + +static inline void setup_ppu_mb(struct spu_state *csa, struct spu *spu) +{ + /* Restore, Step 35: + * Copy the CSA.PU_MB data into the LSCSA. + */ + csa->lscsa->ppu_mb.slot[0] = csa->prob.pu_mb_R; +} + +static inline void setup_ppuint_mb(struct spu_state *csa, struct spu *spu) +{ + /* Restore, Step 36: + * Copy the CSA.PUINT_MB data into the LSCSA. + */ + csa->lscsa->ppuint_mb.slot[0] = csa->priv2.puint_mb_R; +} + +static inline int check_restore_status(struct spu_state *csa, struct spu *spu) +{ + struct spu_problem __iomem *prob = spu->problem; + u32 complete; + + /* Restore, Step 40: + * If SPU_Status[P]=1 and SPU_Status[SC] = "success", + * context restore succeeded, otherwise context restore + * failed. + */ + complete = ((SPU_RESTORE_COMPLETE << SPU_STOP_STATUS_SHIFT) | + SPU_STATUS_STOPPED_BY_STOP); + return (in_be32(&prob->spu_status_R) != complete) ? 1 : 0; +} + +static inline void restore_spu_privcntl(struct spu_state *csa, struct spu *spu) +{ + struct spu_priv2 __iomem *priv2 = spu->priv2; + + /* Restore, Step 41: + * Restore SPU_PrivCntl from the CSA. + */ + out_be64(&priv2->spu_privcntl_RW, csa->priv2.spu_privcntl_RW); + eieio(); +} + +static inline void restore_status_part1(struct spu_state *csa, struct spu *spu) +{ + struct spu_problem __iomem *prob = spu->problem; + u32 mask; + + /* Restore, Step 42: + * If any CSA.SPU_Status[I,S,H,P]=1, then + * restore the error or single step state. + */ + mask = SPU_STATUS_INVALID_INSTR | + SPU_STATUS_SINGLE_STEP | + SPU_STATUS_STOPPED_BY_HALT | SPU_STATUS_STOPPED_BY_STOP; + if (csa->prob.spu_status_R & mask) { + out_be32(&prob->spu_runcntl_RW, SPU_RUNCNTL_RUNNABLE); + eieio(); + POLL_WHILE_TRUE(in_be32(&prob->spu_status_R) & + SPU_STATUS_RUNNING); + } +} + +static inline void restore_status_part2(struct spu_state *csa, struct spu *spu) +{ + struct spu_problem __iomem *prob = spu->problem; + u32 mask; + + /* Restore, Step 43: + * If all CSA.SPU_Status[I,S,H,P,R]=0 then write + * SPU_RunCntl[R0R1]='01', wait for SPU_Status[R]=1, + * then write '00' to SPU_RunCntl[R0R1] and wait + * for SPU_Status[R]=0. + */ + mask = SPU_STATUS_INVALID_INSTR | + SPU_STATUS_SINGLE_STEP | + SPU_STATUS_STOPPED_BY_HALT | + SPU_STATUS_STOPPED_BY_STOP | SPU_STATUS_RUNNING; + if (!(csa->prob.spu_status_R & mask)) { + out_be32(&prob->spu_runcntl_RW, SPU_RUNCNTL_RUNNABLE); + eieio(); + POLL_WHILE_FALSE(in_be32(&prob->spu_status_R) & + SPU_STATUS_RUNNING); + out_be32(&prob->spu_runcntl_RW, SPU_RUNCNTL_STOP); + eieio(); + POLL_WHILE_TRUE(in_be32(&prob->spu_status_R) & + SPU_STATUS_RUNNING); + } +} + +static inline void restore_ls_16kb(struct spu_state *csa, struct spu *spu) +{ + unsigned long addr = (unsigned long)&csa->lscsa->ls[0]; + unsigned int ls_offset = 0x0; + unsigned int size = 16384; + unsigned int tag = 0; + unsigned int rclass = 0; + unsigned int cmd = MFC_GET_CMD; + + /* Restore, Step 44: + * Issue a DMA command to restore the first + * 16kb of local storage from CSA. + */ + send_mfc_dma(spu, addr, ls_offset, size, tag, rclass, cmd); +} + +static inline void clear_interrupts(struct spu_state *csa, struct spu *spu) +{ + struct spu_priv1 __iomem *priv1 = spu->priv1; + unsigned long flags; + + /* Restore, Step 49: + * Write INT_MASK_class0 with value of 0. + * Write INT_MASK_class1 with value of 0. + * Write INT_MASK_class2 with value of 0. + * Write INT_STAT_class0 with value of -1. + * Write INT_STAT_class1 with value of -1. + * Write INT_STAT_class2 with value of -1. + */ + local_irq_save(flags); + out_be64(&priv1->int_mask_class0_RW, 0UL); + out_be64(&priv1->int_mask_class1_RW, 0UL); + out_be64(&priv1->int_mask_class2_RW, 0UL); + out_be64(&priv1->int_stat_class0_RW, ~(0UL)); + out_be64(&priv1->int_stat_class1_RW, ~(0UL)); + out_be64(&priv1->int_stat_class2_RW, ~(0UL)); + local_irq_restore(flags); +} + +static inline void restore_mfc_queues(struct spu_state *csa, struct spu *spu) +{ + struct spu_priv2 __iomem *priv2 = spu->priv2; + int i; + + /* Restore, Step 50: + * If MFC_Cntl[Se]!=0 then restore + * MFC command queues. + */ + if ((csa->priv2.mfc_control_RW & MFC_CNTL_DMA_QUEUES_EMPTY_MASK) == 0) { + for (i = 0; i < 8; i++) { + out_be64(&priv2->puq[i].mfc_cq_data0_RW, + csa->priv2.puq[i].mfc_cq_data0_RW); + out_be64(&priv2->puq[i].mfc_cq_data1_RW, + csa->priv2.puq[i].mfc_cq_data1_RW); + out_be64(&priv2->puq[i].mfc_cq_data2_RW, + csa->priv2.puq[i].mfc_cq_data2_RW); + out_be64(&priv2->puq[i].mfc_cq_data3_RW, + csa->priv2.puq[i].mfc_cq_data3_RW); + } + for (i = 0; i < 16; i++) { + out_be64(&priv2->spuq[i].mfc_cq_data0_RW, + csa->priv2.spuq[i].mfc_cq_data0_RW); + out_be64(&priv2->spuq[i].mfc_cq_data1_RW, + csa->priv2.spuq[i].mfc_cq_data1_RW); + out_be64(&priv2->spuq[i].mfc_cq_data2_RW, + csa->priv2.spuq[i].mfc_cq_data2_RW); + out_be64(&priv2->spuq[i].mfc_cq_data3_RW, + csa->priv2.spuq[i].mfc_cq_data3_RW); + } + } + eieio(); +} + +static inline void restore_ppu_querymask(struct spu_state *csa, struct spu *spu) +{ + struct spu_problem __iomem *prob = spu->problem; + + /* Restore, Step 51: + * Restore the PPU_QueryMask register from CSA. + */ + out_be32(&prob->dma_querymask_RW, csa->prob.dma_querymask_RW); + eieio(); +} + +static inline void restore_ppu_querytype(struct spu_state *csa, struct spu *spu) +{ + struct spu_problem __iomem *prob = spu->problem; + + /* Restore, Step 52: + * Restore the PPU_QueryType register from CSA. + */ + out_be32(&prob->dma_querytype_RW, csa->prob.dma_querytype_RW); + eieio(); +} + +static inline void restore_mfc_csr_tsq(struct spu_state *csa, struct spu *spu) +{ + struct spu_priv2 __iomem *priv2 = spu->priv2; + + /* Restore, Step 53: + * Restore the MFC_CSR_TSQ register from CSA. + */ + out_be64(&priv2->spu_tag_status_query_RW, + csa->priv2.spu_tag_status_query_RW); + eieio(); +} + +static inline void restore_mfc_csr_cmd(struct spu_state *csa, struct spu *spu) +{ + struct spu_priv2 __iomem *priv2 = spu->priv2; + + /* Restore, Step 54: + * Restore the MFC_CSR_CMD1 and MFC_CSR_CMD2 + * registers from CSA. + */ + out_be64(&priv2->spu_cmd_buf1_RW, csa->priv2.spu_cmd_buf1_RW); + out_be64(&priv2->spu_cmd_buf2_RW, csa->priv2.spu_cmd_buf2_RW); + eieio(); +} + +static inline void restore_mfc_csr_ato(struct spu_state *csa, struct spu *spu) +{ + struct spu_priv2 __iomem *priv2 = spu->priv2; + + /* Restore, Step 55: + * Restore the MFC_CSR_ATO register from CSA. + */ + out_be64(&priv2->spu_atomic_status_RW, csa->priv2.spu_atomic_status_RW); +} + +static inline void restore_mfc_tclass_id(struct spu_state *csa, struct spu *spu) +{ + struct spu_priv1 __iomem *priv1 = spu->priv1; + + /* Restore, Step 56: + * Restore the MFC_TCLASS_ID register from CSA. + */ + out_be64(&priv1->mfc_tclass_id_RW, csa->priv1.mfc_tclass_id_RW); + eieio(); +} + +static inline void set_llr_event(struct spu_state *csa, struct spu *spu) +{ + u64 ch0_cnt, ch0_data; + u64 ch1_data; + + /* Restore, Step 57: + * Set the Lock Line Reservation Lost Event by: + * 1. OR CSA.SPU_Event_Status with bit 21 (Lr) set to 1. + * 2. If CSA.SPU_Channel_0_Count=0 and + * CSA.SPU_Wr_Event_Mask[Lr]=1 and + * CSA.SPU_Event_Status[Lr]=0 then set + * CSA.SPU_Event_Status_Count=1. + */ + ch0_cnt = csa->spu_chnlcnt_RW[0]; + ch0_data = csa->spu_chnldata_RW[0]; + ch1_data = csa->spu_chnldata_RW[1]; + csa->spu_chnldata_RW[0] |= MFC_LLR_LOST_EVENT; + if ((ch0_cnt == 0) && !(ch0_data & MFC_LLR_LOST_EVENT) && + (ch1_data & MFC_LLR_LOST_EVENT)) { + csa->spu_chnlcnt_RW[0] = 1; + } +} + +static inline void restore_decr_wrapped(struct spu_state *csa, struct spu *spu) +{ + /* Restore, Step 58: + * If the status of the CSA software decrementer + * "wrapped" flag is set, OR in a '1' to + * CSA.SPU_Event_Status[Tm]. + */ + if (csa->lscsa->decr_status.slot[0] == 1) { + csa->spu_chnldata_RW[0] |= 0x20; + } + if ((csa->lscsa->decr_status.slot[0] == 1) && + (csa->spu_chnlcnt_RW[0] == 0 && + ((csa->spu_chnldata_RW[2] & 0x20) == 0x0) && + ((csa->spu_chnldata_RW[0] & 0x20) != 0x1))) { + csa->spu_chnlcnt_RW[0] = 1; + } +} + +static inline void restore_ch_part1(struct spu_state *csa, struct spu *spu) +{ + struct spu_priv2 __iomem *priv2 = spu->priv2; + u64 idx, ch_indices[7] = { 0UL, 1UL, 3UL, 4UL, 24UL, 25UL, 27UL }; + int i; + + /* Restore, Step 59: + * Restore the following CH: [0,1,3,4,24,25,27] + */ + for (i = 0; i < 7; i++) { + idx = ch_indices[i]; + out_be64(&priv2->spu_chnlcntptr_RW, idx); + eieio(); + out_be64(&priv2->spu_chnldata_RW, csa->spu_chnldata_RW[idx]); + out_be64(&priv2->spu_chnlcnt_RW, csa->spu_chnlcnt_RW[idx]); + eieio(); + } +} + +static inline void restore_ch_part2(struct spu_state *csa, struct spu *spu) +{ + struct spu_priv2 __iomem *priv2 = spu->priv2; + u64 ch_indices[3] = { 9UL, 21UL, 23UL }; + u64 ch_counts[3] = { 1UL, 16UL, 1UL }; + u64 idx; + int i; + + /* Restore, Step 60: + * Restore the following CH: [9,21,23]. + */ + ch_counts[0] = 1UL; + ch_counts[1] = csa->spu_chnlcnt_RW[21]; + ch_counts[2] = 1UL; + for (i = 0; i < 3; i++) { + idx = ch_indices[i]; + out_be64(&priv2->spu_chnlcntptr_RW, idx); + eieio(); + out_be64(&priv2->spu_chnlcnt_RW, ch_counts[i]); + eieio(); + } +} + +static inline void restore_spu_lslr(struct spu_state *csa, struct spu *spu) +{ + struct spu_priv2 __iomem *priv2 = spu->priv2; + + /* Restore, Step 61: + * Restore the SPU_LSLR register from CSA. + */ + out_be64(&priv2->spu_lslr_RW, csa->priv2.spu_lslr_RW); + eieio(); +} + +static inline void restore_spu_cfg(struct spu_state *csa, struct spu *spu) +{ + struct spu_priv2 __iomem *priv2 = spu->priv2; + + /* Restore, Step 62: + * Restore the SPU_Cfg register from CSA. + */ + out_be64(&priv2->spu_cfg_RW, csa->priv2.spu_cfg_RW); + eieio(); +} + +static inline void restore_pm_trace(struct spu_state *csa, struct spu *spu) +{ + struct spu_priv2 __iomem *priv2 = spu->priv2; + + /* Restore, Step 63: + * Restore PM_Trace_Tag_Wait_Mask from CSA. + */ + out_be64(&priv2->spu_pm_trace_tag_status_RW, + csa->priv2.spu_pm_trace_tag_status_RW); + eieio(); +} + +static inline void restore_spu_npc(struct spu_state *csa, struct spu *spu) +{ + struct spu_problem __iomem *prob = spu->problem; + + /* Restore, Step 64: + * Restore SPU_NPC from CSA. + */ + out_be32(&prob->spu_npc_RW, csa->prob.spu_npc_RW); + eieio(); +} + +static inline void restore_spu_mb(struct spu_state *csa, struct spu *spu) +{ + struct spu_priv2 __iomem *priv2 = spu->priv2; + int i; + + /* Restore, Step 65: + * Restore MFC_RdSPU_MB from CSA. + */ + out_be64(&priv2->spu_chnlcntptr_RW, 29UL); + eieio(); + out_be64(&priv2->spu_chnlcnt_RW, csa->spu_chnlcnt_RW[29]); + for (i = 0; i < 4; i++) { + out_be64(&priv2->spu_chnldata_RW, csa->pu_mailbox_data[i]); + } + eieio(); +} + +static inline void check_ppu_mb_stat(struct spu_state *csa, struct spu *spu) +{ + struct spu_problem __iomem *prob = spu->problem; + u32 dummy = 0; + + /* Restore, Step 66: + * If CSA.MB_Stat[P]=0 (mailbox empty) then + * read from the PPU_MB register. + */ + if ((csa->prob.mb_stat_R & 0xFF) == 0) { + dummy = in_be32(&prob->pu_mb_R); + eieio(); + } +} + +static inline void check_ppuint_mb_stat(struct spu_state *csa, struct spu *spu) +{ + struct spu_priv1 __iomem *priv1 = spu->priv1; + struct spu_priv2 __iomem *priv2 = spu->priv2; + u64 dummy = 0UL; + + /* Restore, Step 66: + * If CSA.MB_Stat[I]=0 (mailbox empty) then + * read from the PPUINT_MB register. + */ + if ((csa->prob.mb_stat_R & 0xFF0000) == 0) { + dummy = in_be64(&priv2->puint_mb_R); + eieio(); + out_be64(&priv1->int_stat_class2_RW, + CLASS2_ENABLE_MAILBOX_INTR); + eieio(); + } +} + +static inline void restore_mfc_slbs(struct spu_state *csa, struct spu *spu) +{ + struct spu_priv2 __iomem *priv2 = spu->priv2; + int i; + + /* Restore, Step 68: + * If MFC_SR1[R]='1', restore SLBs from CSA. + */ + if (csa->priv1.mfc_sr1_RW & MFC_STATE1_RELOCATE_MASK) { + for (i = 0; i < 8; i++) { + out_be64(&priv2->slb_index_W, i); + eieio(); + out_be64(&priv2->slb_esid_RW, csa->slb_esid_RW[i]); + out_be64(&priv2->slb_vsid_RW, csa->slb_vsid_RW[i]); + eieio(); + } + out_be64(&priv2->slb_index_W, csa->priv2.slb_index_W); + eieio(); + } +} + +static inline void restore_mfc_sr1(struct spu_state *csa, struct spu *spu) +{ + struct spu_priv1 __iomem *priv1 = spu->priv1; + + /* Restore, Step 69: + * Restore the MFC_SR1 register from CSA. + */ + out_be64(&priv1->mfc_sr1_RW, csa->priv1.mfc_sr1_RW); + eieio(); +} + +static inline void restore_other_spu_access(struct spu_state *csa, + struct spu *spu) +{ + /* Restore, Step 70: + * Restore other SPU mappings to this SPU. TBD. + */ +} + +static inline void restore_spu_runcntl(struct spu_state *csa, struct spu *spu) +{ + struct spu_problem __iomem *prob = spu->problem; + + /* Restore, Step 71: + * If CSA.SPU_Status[R]=1 then write + * SPU_RunCntl[R0R1]='01'. + */ + if (csa->prob.spu_status_R & SPU_STATUS_RUNNING) { + out_be32(&prob->spu_runcntl_RW, SPU_RUNCNTL_RUNNABLE); + eieio(); + } +} + +static inline void restore_mfc_cntl(struct spu_state *csa, struct spu *spu) +{ + struct spu_priv2 __iomem *priv2 = spu->priv2; + + /* Restore, Step 72: + * Restore the MFC_CNTL register for the CSA. + */ + out_be64(&priv2->mfc_control_RW, csa->priv2.mfc_control_RW); + eieio(); +} + +static inline void enable_user_access(struct spu_state *csa, struct spu *spu) +{ + /* Restore, Step 73: + * Enable user-space access (if provided) to this + * SPU by mapping the virtual pages assigned to + * the SPU memory-mapped I/O (MMIO) for problem + * state. TBD. + */ +} + +static inline void reset_switch_active(struct spu_state *csa, struct spu *spu) +{ + /* Restore, Step 74: + * Reset the "context switch active" flag. + */ + clear_bit(SPU_CONTEXT_SWITCH_ACTIVE_nr, &spu->flags); + mb(); +} + +static inline void reenable_interrupts(struct spu_state *csa, struct spu *spu) +{ + struct spu_priv1 __iomem *priv1 = spu->priv1; + unsigned long flags; + + /* Restore, Step 75: + * Re-enable SPU interrupts. + */ + local_irq_save(flags); + out_be64(&priv1->int_mask_class0_RW, csa->priv1.int_mask_class0_RW); + out_be64(&priv1->int_mask_class1_RW, csa->priv1.int_mask_class1_RW); + out_be64(&priv1->int_mask_class2_RW, csa->priv1.int_mask_class2_RW); + local_irq_restore(flags); +} + +static int quiece_spu(struct spu_state *prev, struct spu *spu) +{ + /* + * Combined steps 2-18 of SPU context save sequence, which + * quiesce the SPU state (disable SPU execution, MFC command + * queues, decrementer, SPU interrupts, etc.). + * + * Returns 0 on success. + * 2 if failed step 2. + * 6 if failed step 6. + */ + + if (check_spu_isolate(prev, spu)) { /* Step 2. */ + return 2; + } + disable_interrupts(prev, spu); /* Step 3. */ + set_watchdog_timer(prev, spu); /* Step 4. */ + inhibit_user_access(prev, spu); /* Step 5. */ + if (check_spu_isolate(prev, spu)) { /* Step 6. */ + return 6; + } + set_switch_pending(prev, spu); /* Step 7. */ + save_mfc_cntl(prev, spu); /* Step 8. */ + save_spu_runcntl(prev, spu); /* Step 9. */ + save_mfc_sr1(prev, spu); /* Step 10. */ + save_spu_status(prev, spu); /* Step 11. */ + save_mfc_decr(prev, spu); /* Step 12. */ + halt_mfc_decr(prev, spu); /* Step 13. */ + save_timebase(prev, spu); /* Step 14. */ + remove_other_spu_access(prev, spu); /* Step 15. */ + do_mfc_mssync(prev, spu); /* Step 16. */ + issue_mfc_tlbie(prev, spu); /* Step 17. */ + handle_pending_interrupts(prev, spu); /* Step 18. */ + + return 0; +} + +static void save_csa(struct spu_state *prev, struct spu *spu) +{ + /* + * Combine steps 19-44 of SPU context save sequence, which + * save regions of the privileged & problem state areas. + */ + + save_mfc_queues(prev, spu); /* Step 19. */ + save_ppu_querymask(prev, spu); /* Step 20. */ + save_ppu_querytype(prev, spu); /* Step 21. */ + save_mfc_csr_tsq(prev, spu); /* Step 22. */ + save_mfc_csr_cmd(prev, spu); /* Step 23. */ + save_mfc_csr_ato(prev, spu); /* Step 24. */ + save_mfc_tclass_id(prev, spu); /* Step 25. */ + set_mfc_tclass_id(prev, spu); /* Step 26. */ + purge_mfc_queue(prev, spu); /* Step 27. */ + wait_purge_complete(prev, spu); /* Step 28. */ + save_mfc_slbs(prev, spu); /* Step 29. */ + setup_mfc_sr1(prev, spu); /* Step 30. */ + save_spu_npc(prev, spu); /* Step 31. */ + save_spu_privcntl(prev, spu); /* Step 32. */ + reset_spu_privcntl(prev, spu); /* Step 33. */ + save_spu_lslr(prev, spu); /* Step 34. */ + reset_spu_lslr(prev, spu); /* Step 35. */ + save_spu_cfg(prev, spu); /* Step 36. */ + save_pm_trace(prev, spu); /* Step 37. */ + save_mfc_rag(prev, spu); /* Step 38. */ + save_ppu_mb_stat(prev, spu); /* Step 39. */ + save_ppu_mb(prev, spu); /* Step 40. */ + save_ppuint_mb(prev, spu); /* Step 41. */ + save_ch_part1(prev, spu); /* Step 42. */ + save_spu_mb(prev, spu); /* Step 43. */ + save_mfc_cmd(prev, spu); /* Step 44. */ + reset_ch(prev, spu); /* Step 45. */ +} + +static void save_lscsa(struct spu_state *prev, struct spu *spu) +{ + /* + * Perform steps 46-57 of SPU context save sequence, + * which save regions of the local store and register + * file. + */ + + resume_mfc_queue(prev, spu); /* Step 46. */ + setup_mfc_slbs(prev, spu); /* Step 47. */ + set_switch_active(prev, spu); /* Step 48. */ + enable_interrupts(prev, spu); /* Step 49. */ + save_ls_16kb(prev, spu); /* Step 50. */ + set_spu_npc(prev, spu); /* Step 51. */ + set_signot1(prev, spu); /* Step 52. */ + set_signot2(prev, spu); /* Step 53. */ + send_save_code(prev, spu); /* Step 54. */ + set_ppu_querymask(prev, spu); /* Step 55. */ + wait_tag_complete(prev, spu); /* Step 56. */ + wait_spu_stopped(prev, spu); /* Step 57. */ +} + +static void harvest(struct spu_state *prev, struct spu *spu) +{ + /* + * Perform steps 2-25 of SPU context restore sequence, + * which resets an SPU either after a failed save, or + * when using SPU for first time. + */ + + disable_interrupts(prev, spu); /* Step 2. */ + inhibit_user_access(prev, spu); /* Step 3. */ + terminate_spu_app(prev, spu); /* Step 4. */ + set_switch_pending(prev, spu); /* Step 5. */ + remove_other_spu_access(prev, spu); /* Step 6. */ + suspend_mfc(prev, spu); /* Step 7. */ + wait_suspend_mfc_complete(prev, spu); /* Step 8. */ + if (!suspend_spe(prev, spu)) /* Step 9. */ + clear_spu_status(prev, spu); /* Step 10. */ + do_mfc_mssync(prev, spu); /* Step 11. */ + issue_mfc_tlbie(prev, spu); /* Step 12. */ + handle_pending_interrupts(prev, spu); /* Step 13. */ + purge_mfc_queue(prev, spu); /* Step 14. */ + wait_purge_complete(prev, spu); /* Step 15. */ + reset_spu_privcntl(prev, spu); /* Step 16. */ + reset_spu_lslr(prev, spu); /* Step 17. */ + setup_mfc_sr1(prev, spu); /* Step 18. */ + invalidate_slbs(prev, spu); /* Step 19. */ + reset_ch_part1(prev, spu); /* Step 20. */ + reset_ch_part2(prev, spu); /* Step 21. */ + enable_interrupts(prev, spu); /* Step 22. */ + set_switch_active(prev, spu); /* Step 23. */ + set_mfc_tclass_id(prev, spu); /* Step 24. */ + resume_mfc_queue(prev, spu); /* Step 25. */ +} + +static void restore_lscsa(struct spu_state *next, struct spu *spu) +{ + /* + * Perform steps 26-40 of SPU context restore sequence, + * which restores regions of the local store and register + * file. + */ + + set_watchdog_timer(next, spu); /* Step 26. */ + setup_spu_status_part1(next, spu); /* Step 27. */ + setup_spu_status_part2(next, spu); /* Step 28. */ + restore_mfc_rag(next, spu); /* Step 29. */ + setup_mfc_slbs(next, spu); /* Step 30. */ + set_spu_npc(next, spu); /* Step 31. */ + set_signot1(next, spu); /* Step 32. */ + set_signot2(next, spu); /* Step 33. */ + setup_decr(next, spu); /* Step 34. */ + setup_ppu_mb(next, spu); /* Step 35. */ + setup_ppuint_mb(next, spu); /* Step 36. */ + send_restore_code(next, spu); /* Step 37. */ + set_ppu_querymask(next, spu); /* Step 38. */ + wait_tag_complete(next, spu); /* Step 39. */ + wait_spu_stopped(next, spu); /* Step 40. */ +} + +static void restore_csa(struct spu_state *next, struct spu *spu) +{ + /* + * Combine steps 41-76 of SPU context restore sequence, which + * restore regions of the privileged & problem state areas. + */ + + restore_spu_privcntl(next, spu); /* Step 41. */ + restore_status_part1(next, spu); /* Step 42. */ + restore_status_part2(next, spu); /* Step 43. */ + restore_ls_16kb(next, spu); /* Step 44. */ + wait_tag_complete(next, spu); /* Step 45. */ + suspend_mfc(next, spu); /* Step 46. */ + wait_suspend_mfc_complete(next, spu); /* Step 47. */ + issue_mfc_tlbie(next, spu); /* Step 48. */ + clear_interrupts(next, spu); /* Step 49. */ + restore_mfc_queues(next, spu); /* Step 50. */ + restore_ppu_querymask(next, spu); /* Step 51. */ + restore_ppu_querytype(next, spu); /* Step 52. */ + restore_mfc_csr_tsq(next, spu); /* Step 53. */ + restore_mfc_csr_cmd(next, spu); /* Step 54. */ + restore_mfc_csr_ato(next, spu); /* Step 55. */ + restore_mfc_tclass_id(next, spu); /* Step 56. */ + set_llr_event(next, spu); /* Step 57. */ + restore_decr_wrapped(next, spu); /* Step 58. */ + restore_ch_part1(next, spu); /* Step 59. */ + restore_ch_part2(next, spu); /* Step 60. */ + restore_spu_lslr(next, spu); /* Step 61. */ + restore_spu_cfg(next, spu); /* Step 62. */ + restore_pm_trace(next, spu); /* Step 63. */ + restore_spu_npc(next, spu); /* Step 64. */ + restore_spu_mb(next, spu); /* Step 65. */ + check_ppu_mb_stat(next, spu); /* Step 66. */ + check_ppuint_mb_stat(next, spu); /* Step 67. */ + restore_mfc_slbs(next, spu); /* Step 68. */ + restore_mfc_sr1(next, spu); /* Step 69. */ + restore_other_spu_access(next, spu); /* Step 70. */ + restore_spu_runcntl(next, spu); /* Step 71. */ + restore_mfc_cntl(next, spu); /* Step 72. */ + enable_user_access(next, spu); /* Step 73. */ + reset_switch_active(next, spu); /* Step 74. */ + reenable_interrupts(next, spu); /* Step 75. */ +} + +static int __do_spu_save(struct spu_state *prev, struct spu *spu) +{ + int rc; + + /* + * SPU context save can be broken into three phases: + * + * (a) quiesce [steps 2-16]. + * (b) save of CSA, performed by PPE [steps 17-42] + * (c) save of LSCSA, mostly performed by SPU [steps 43-52]. + * + * Returns 0 on success. + * 2,6 if failed to quiece SPU + * 53 if SPU-side of save failed. + */ + + rc = quiece_spu(prev, spu); /* Steps 2-16. */ + switch (rc) { + default: + case 2: + case 6: + harvest(prev, spu); + return rc; + break; + case 0: + break; + } + save_csa(prev, spu); /* Steps 17-43. */ + save_lscsa(prev, spu); /* Steps 44-53. */ + return check_save_status(prev, spu); /* Step 54. */ +} + +static int __do_spu_restore(struct spu_state *next, struct spu *spu) +{ + int rc; + + /* + * SPU context restore can be broken into three phases: + * + * (a) harvest (or reset) SPU [steps 2-24]. + * (b) restore LSCSA [steps 25-40], mostly performed by SPU. + * (c) restore CSA [steps 41-76], performed by PPE. + * + * The 'harvest' step is not performed here, but rather + * as needed below. + */ + + restore_lscsa(next, spu); /* Steps 24-39. */ + rc = check_restore_status(next, spu); /* Step 40. */ + switch (rc) { + default: + /* Failed. Return now. */ + return rc; + break; + case 0: + /* Fall through to next step. */ + break; + } + restore_csa(next, spu); + + return 0; +} + /** * spu_save - SPU context save, with locking. * @prev: pointer to SPU context save area, to be saved. @@ -61,9 +2084,13 @@ */ int spu_save(struct spu_state *prev, struct spu *spu) { - /* XXX missing */ + int rc; - return 0; + acquire_spu_lock(spu); /* Step 1. */ + rc = __do_spu_save(prev, spu); /* Steps 2-53. */ + release_spu_lock(spu); + + return rc; } /** @@ -77,9 +2104,14 @@ int spu_save(struct spu_state *prev, str */ int spu_restore(struct spu_state *new, struct spu *spu) { - /* XXX missing */ + int rc; - return 0; + acquire_spu_lock(spu); + harvest(NULL, spu); + rc = __do_spu_restore(new, spu); + release_spu_lock(spu); + + return rc; } /** @@ -93,9 +2125,17 @@ int spu_restore(struct spu_state *new, s */ int spu_switch(struct spu_state *prev, struct spu_state *new, struct spu *spu) { - /* XXX missing */ + int rc; - return 0; + acquire_spu_lock(spu); /* Save, Step 1. */ + rc = __do_spu_save(prev, spu); /* Save, Steps 2-53. */ + if (rc != 0) { + harvest(prev, spu); + } + rc = __do_spu_restore(new, spu); + release_spu_lock(spu); + + return rc; } static void init_prob(struct spu_state *csa) From arnd at arndb.de Fri Aug 26 08:04:38 2005 From: arnd at arndb.de (Arnd Bergmann) Date: Fri, 26 Aug 2005 00:04:38 +0200 Subject: [PATCH 7/7] spufs: Add a register file for the debugger Message-ID: <200508260004.39492.arnd@arndb.de> In order to debug spu threads, we need access to the registers of the running SPU. Unfortunately, this is only possible when the SPU context is saved to memory. This patch adds operations that enable accessing an SPU in either runnable or saved state. We use an RW semaphore to protect the state of the SPU from changing underneath us, while we are holding it readable. In order to change the state, it is acquired writeable and a context save or restore is executed before downgrading the semaphore to read-only. Future schedulers will likely be built on top of this. From: Ulrich Weigand Signed-off-by: Arnd Bergmann -- context.c | 48 ++++++++++++ file.c | 239 ++++++++++++++++++++++++++++++++++++++++++++++++------------ spufs.h | 3 4 files changed, 243 insertions(+), 47 deletions(-) --- linux-cg.orig/fs/spufs/context.c 2005-08-25 23:12:20.725920136 -0400 +++ linux-cg/fs/spufs/context.c 2005-08-25 23:12:52.415895512 -0400 @@ -53,6 +53,8 @@ struct spu_context *alloc_spu_context(vo init_rwsem(&ctx->backing_sema); spin_lock_init(&ctx->mmio_lock); kref_init(&ctx->kref); + init_rwsem(&ctx->state_sema); + ctx->state = SPU_STATE_SAVED; goto out; out_free: kfree(ctx); @@ -82,4 +84,50 @@ void put_spu_context(struct spu_context kref_put(&ctx->kref, &destroy_spu_context); } +void spu_acquire(struct spu_context *ctx) +{ + down_read(&ctx->state_sema); +} + +void spu_release(struct spu_context *ctx) +{ + up_read(&ctx->state_sema); +} + +void spu_acquire_runnable(struct spu_context *ctx) +{ + down_read(&ctx->state_sema); + + if (ctx->state == SPU_STATE_RUNNABLE + || ctx->state == SPU_STATE_LOCKED) + return; + + up_read(&ctx->state_sema); + down_write(&ctx->state_sema); + if (ctx->state == SPU_STATE_SAVED) { + spu_restore(&ctx->csa, ctx->spu); + ctx->state = SPU_STATE_RUNNABLE; + } + + downgrade_write(&ctx->state_sema); +} + +void spu_acquire_saved(struct spu_context *ctx) +{ + down_read(&ctx->state_sema); + + if (ctx->state == SPU_STATE_SAVED + || ctx->state == SPU_STATE_LOCKED) + return; + + up_read(&ctx->state_sema); + down_write(&ctx->state_sema); + + if (ctx->state == SPU_STATE_RUNNABLE) { + spu_save(&ctx->csa, ctx->spu); + ctx->state = SPU_STATE_SAVED; + } + + downgrade_write(&ctx->state_sema); +} --- linux-cg.orig/fs/spufs/file.c 2005-08-25 23:12:46.858941568 -0400 +++ linux-cg/fs/spufs/file.c 2005-08-25 23:12:52.418895056 -0400 @@ -32,6 +32,7 @@ #include "spufs.h" + static int spufs_mem_open(struct inode *inode, struct file *file) { @@ -44,23 +45,22 @@ static ssize_t spufs_mem_read(struct file *file, char __user *buffer, size_t size, loff_t *pos) { - struct spu *spu; - struct spu_context *ctx; + struct spu_context *ctx = file->private_data; + char *local_store; int ret; - ctx = file->private_data; - spu = ctx->spu; - + spu_acquire(ctx); down_read(&ctx->backing_sema); - if (spu->number & 0/*1*/) { - ret = generic_file_read(file, buffer, size, pos); - goto out; - } - ret = simple_read_from_buffer(buffer, size, pos, - spu->local_store, LS_SIZE); -out: + if (ctx->state == SPU_STATE_SAVED) + local_store = ctx->csa.lscsa->ls; + else + local_store = ctx->spu->local_store; + + ret = simple_read_from_buffer(buffer, size, pos, local_store, LS_SIZE); + up_read(&ctx->backing_sema); + spu_release(ctx); return ret; } @@ -69,17 +69,28 @@ spufs_mem_write(struct file *file, const size_t size, loff_t *pos) { struct spu_context *ctx = file->private_data; - struct spu *spu = ctx->spu; - - if (spu->number & 0) //1) - return generic_file_write(file, buffer, size, pos); + char *local_store; + int ret; size = min_t(ssize_t, LS_SIZE - *pos, size); if (size <= 0) return -EFBIG; *pos += size; - return copy_from_user(spu->local_store + *pos - size, - buffer, size) ? -EFAULT : size; + + spu_acquire(ctx); + down_read(&ctx->backing_sema); + + if (ctx->state == SPU_STATE_SAVED) + local_store = ctx->csa.lscsa->ls; + else + local_store = ctx->spu->local_store; + + ret = copy_from_user(local_store + *pos - size, + buffer, size) ? -EFAULT : size; + + up_read(&ctx->backing_sema); + spu_release(ctx); + return ret; } static int @@ -88,9 +99,9 @@ spufs_mem_mmap(struct file *file, struct struct spu_context *ctx = file->private_data; struct spu *spu = ctx->spu; unsigned long pfn; + int ret = 0; - if (spu->number & 0) //1) - return generic_file_mmap(file, vma); + spu_acquire_runnable(ctx); vma->vm_flags |= VM_RESERVED; vma->vm_page_prot = __pgprot(pgprot_val (vma->vm_page_prot) @@ -101,8 +112,13 @@ spufs_mem_mmap(struct file *file, struct */ if (remap_pfn_range(vma, vma->vm_start, pfn, vma->vm_end-vma->vm_start, vma->vm_page_prot)) - return -EAGAIN; - return 0; + ret = -EAGAIN; + + if (!ret) + ctx->state = SPU_STATE_LOCKED; + + spu_release(ctx); + return ret; } static struct file_operations spufs_mem_fops = { @@ -113,6 +129,68 @@ static struct file_operations spufs_mem_ .llseek = generic_file_llseek, }; +static int +spufs_regs_open(struct inode *inode, struct file *file) +{ + struct spufs_inode_info *i = SPUFS_I(inode); + file->private_data = i->i_ctx; + return 0; +} + +static ssize_t +spufs_regs_read(struct file *file, char __user *buffer, + size_t size, loff_t *pos) +{ + struct spu_context *ctx = file->private_data; + struct spu_lscsa *lscsa = ctx->csa.lscsa; + int ret; + + spu_acquire_saved(ctx); + if (ctx->state == SPU_STATE_LOCKED) { + spu_release(ctx); + return -EAGAIN; + } + + ret = simple_read_from_buffer(buffer, size, pos, + lscsa->gprs, sizeof lscsa->gprs); + + spu_release(ctx); + return ret; +} + +static ssize_t +spufs_regs_write(struct file *file, const char __user *buffer, + size_t size, loff_t *pos) +{ + struct spu_context *ctx = file->private_data; + struct spu_lscsa *lscsa = ctx->csa.lscsa; + int ret; + + size = min_t(ssize_t, sizeof lscsa->gprs - *pos, size); + if (size <= 0) + return -EFBIG; + *pos += size; + + spu_acquire_saved(ctx); + if (ctx->state == SPU_STATE_LOCKED) { + spu_release(ctx); + return -EAGAIN; + } + + ret = copy_from_user(lscsa->gprs + *pos - size, + buffer, size) ? -EFAULT : size; + + spu_release(ctx); + return ret; +} + +static struct file_operations spufs_regs_fops = { + .open = spufs_regs_open, + .read = spufs_regs_read, + .write = spufs_regs_write, + .llseek = generic_file_llseek, +}; + /* generic open function for all pipe-like files */ static int spufs_pipe_open(struct inode *inode, struct file *file) { @@ -125,7 +203,7 @@ static int spufs_pipe_open(struct inode static ssize_t spufs_mbox_read(struct file *file, char __user *buf, size_t len, loff_t *pos) { - struct spu_context *ctx; + struct spu_context *ctx = file->private_data; struct spu_problem __iomem *prob; u32 mbox_stat; u32 mbox_data; @@ -133,14 +211,19 @@ static ssize_t spufs_mbox_read(struct fi if (len < 4) return -EINVAL; - ctx = file->private_data; + spu_acquire_runnable(ctx); + prob = ctx->spu->problem; mbox_stat = in_be32(&prob->mb_stat_R); - if (!(mbox_stat & 0x0000ff)) + if (!(mbox_stat & 0x0000ff)) { + spu_release(ctx); return -EAGAIN; + } mbox_data = in_be32(&prob->pu_mb_R); + spu_release(ctx); + if (copy_to_user(buf, &mbox_data, sizeof mbox_data)) return -EFAULT; @@ -155,14 +238,15 @@ static struct file_operations spufs_mbox static ssize_t spufs_mbox_stat_read(struct file *file, char __user *buf, size_t len, loff_t *pos) { - struct spu_context *ctx; + struct spu_context *ctx = file->private_data; u32 mbox_stat; if (len < 4) return -EINVAL; - ctx = file->private_data; + spu_acquire_runnable(ctx); mbox_stat = in_be32(&ctx->spu->problem->mb_stat_R) & 0xff; + spu_release(ctx); if (copy_to_user(buf, &mbox_stat, sizeof mbox_stat)) return -EFAULT; @@ -208,14 +292,14 @@ static int spufs_ibox_fasync(int fd, str static ssize_t spufs_ibox_read(struct file *file, char __user *buf, size_t len, loff_t *pos) { - struct spu_context *ctx; + struct spu_context *ctx = file->private_data; u32 ibox_data; ssize_t ret; if (len < 4) return -EINVAL; - ctx = file->private_data; + spu_acquire_runnable(ctx); ret = 0; if (file->f_flags & O_NONBLOCK) { @@ -226,6 +310,8 @@ static ssize_t spufs_ibox_read(struct fi spu_ibox_read(ctx->spu, &ibox_data)); } + spu_release(ctx); + if (ret) return ret; @@ -238,17 +324,20 @@ static ssize_t spufs_ibox_read(struct fi static unsigned int spufs_ibox_poll(struct file *file, poll_table *wait) { - struct spu_context *ctx; + struct spu_context *ctx = file->private_data; struct spu_problem __iomem *prob; u32 mbox_stat; unsigned int mask; - ctx = file->private_data; + spu_acquire_runnable(ctx); + prob = ctx->spu->problem; mbox_stat = in_be32(&prob->mb_stat_R); poll_wait(file, &ctx->spu->ibox_wq, wait); + spu_release(ctx); + mask = 0; if (mbox_stat & 0xff0000) mask |= POLLIN | POLLRDNORM; @@ -266,14 +355,15 @@ static struct file_operations spufs_ibox static ssize_t spufs_ibox_stat_read(struct file *file, char __user *buf, size_t len, loff_t *pos) { - struct spu_context *ctx; + struct spu_context *ctx = file->private_data; u32 ibox_stat; if (len < 4) return -EINVAL; - ctx = file->private_data; + spu_acquire_runnable(ctx); ibox_stat = (in_be32(&ctx->spu->problem->mb_stat_R) >> 16) & 0xff; + spu_release(ctx); if (copy_to_user(buf, &ibox_stat, sizeof ibox_stat)) return -EFAULT; @@ -320,18 +410,18 @@ static int spufs_wbox_fasync(int fd, str static ssize_t spufs_wbox_write(struct file *file, const char __user *buf, size_t len, loff_t *pos) { - struct spu_context *ctx; + struct spu_context *ctx = file->private_data; u32 wbox_data; int ret; if (len < 4) return -EINVAL; - ctx = file->private_data; - if (copy_from_user(&wbox_data, buf, sizeof wbox_data)) return -EFAULT; + spu_acquire_runnable(ctx); + ret = 0; if (file->f_flags & O_NONBLOCK) { if (!spu_wbox_write(ctx->spu, wbox_data)) @@ -341,22 +431,27 @@ static ssize_t spufs_wbox_write(struct f spu_wbox_write(ctx->spu, wbox_data)); } + spu_release(ctx); + return ret ? ret : sizeof wbox_data; } static unsigned int spufs_wbox_poll(struct file *file, poll_table *wait) { - struct spu_context *ctx; + struct spu_context *ctx = file->private_data; struct spu_problem __iomem *prob; u32 mbox_stat; unsigned int mask; - ctx = file->private_data; + spu_acquire_runnable(ctx); + prob = ctx->spu->problem; mbox_stat = in_be32(&prob->mb_stat_R); poll_wait(file, &ctx->spu->wbox_wq, wait); + spu_release(ctx); + mask = 0; if (mbox_stat & 0x00ff00) mask = POLLOUT | POLLWRNORM; @@ -374,14 +469,15 @@ static struct file_operations spufs_wbox static ssize_t spufs_wbox_stat_read(struct file *file, char __user *buf, size_t len, loff_t *pos) { - struct spu_context *ctx; + struct spu_context *ctx = file->private_data; u32 wbox_stat; if (len < 4) return -EINVAL; - ctx = file->private_data; + spu_acquire_runnable(ctx); wbox_stat = (in_be32(&ctx->spu->problem->mb_stat_R) >> 8) & 0xff; + spu_release(ctx); if (copy_to_user(buf, &wbox_stat, sizeof wbox_stat)) return -EFAULT; @@ -400,6 +496,8 @@ static long spufs_run_spu(struct file *f struct spu_problem __iomem *prob; int ret; + ctx = file->private_data; + if (file->f_flags & O_NONBLOCK) { ret = -EAGAIN; if (!down_write_trylock(&ctx->backing_sema)) @@ -408,6 +506,8 @@ static long spufs_run_spu(struct file *f down_write(&ctx->backing_sema); } + spu_acquire_runnable(ctx); + prob = ctx->spu->problem; out_be32(&prob->spu_npc_RW, *npc); @@ -416,6 +516,7 @@ static long spufs_run_spu(struct file *f *status = in_be32(&prob->spu_status_R); *npc = in_be32(&prob->spu_npc_RW); + spu_release(ctx); up_write(&ctx->backing_sema); out: @@ -507,17 +608,19 @@ static struct file_operations spufs_run_ static ssize_t spufs_signal1_read(struct file *file, char __user *buf, size_t len, loff_t *pos) { - struct spu_context *ctx; + struct spu_context *ctx = file->private_data; struct spu_problem *prob; u32 data; - ctx = file->private_data; prob = ctx->spu->problem; if (len < 4) return -EINVAL; + spu_acquire_runnable(ctx); data = in_be32(&prob->signal_notify1); + spu_release(ctx); + if (copy_to_user(buf, &data, 4)) return -EFAULT; @@ -540,7 +643,9 @@ static ssize_t spufs_signal1_write(struc if (copy_from_user(&data, buf, 4)) return -EFAULT; + spu_acquire_runnable(ctx); out_be32(&prob->signal_notify1, data); + spu_release(ctx); return 4; } @@ -564,7 +669,10 @@ static ssize_t spufs_signal2_read(struct if (len < 4) return -EINVAL; + spu_acquire_runnable(ctx); data = in_be32(&prob->signal_notify2); + spu_release(ctx); + if (copy_to_user(buf, &data, 4)) return -EFAULT; @@ -587,7 +695,9 @@ static ssize_t spufs_signal2_write(struc if (copy_from_user(&data, buf, 4)) return -EFAULT; + spu_acquire_runnable(ctx); out_be32(&prob->signal_notify2, data); + spu_release(ctx); return 4; } @@ -604,6 +714,7 @@ static void spufs_signal1_type_set(void struct spu_priv2 *priv2 = ctx->spu->priv2; u64 tmp; + spu_acquire_runnable(ctx); spin_lock_irq(&ctx->spu->register_lock); tmp = in_be64(&priv2->spu_cfg_RW); if (val) @@ -612,12 +723,19 @@ static void spufs_signal1_type_set(void tmp &= ~1; out_be64(&priv2->spu_cfg_RW, tmp); spin_unlock_irq(&ctx->spu->register_lock); + spu_release(ctx); } static u64 spufs_signal1_type_get(void *data) { struct spu_context *ctx = data; - return (in_be64(&ctx->spu->priv2->spu_cfg_RW) & 1) != 0; + u64 ret; + + spu_acquire_runnable(ctx); + ret = ((in_be64(&ctx->spu->priv2->spu_cfg_RW) & 1) != 0); + spu_release(ctx); + + return ret; } DEFINE_SIMPLE_ATTRIBUTE(spufs_signal1_type, spufs_signal1_type_get, spufs_signal1_type_set, "%llu"); @@ -628,6 +746,7 @@ static void spufs_signal2_type_set(void struct spu_priv2 *priv2 = ctx->spu->priv2; u64 tmp; + spu_acquire_runnable(ctx); spin_lock_irq(&ctx->spu->register_lock); tmp = in_be64(&priv2->spu_cfg_RW); if (val) @@ -636,12 +755,19 @@ static void spufs_signal2_type_set(void tmp &= ~2; out_be64(&priv2->spu_cfg_RW, tmp); spin_unlock_irq(&ctx->spu->register_lock); + spu_release(ctx); } static u64 spufs_signal2_type_get(void *data) { struct spu_context *ctx = data; - return (in_be64(&ctx->spu->priv2->spu_cfg_RW) & 2) != 0; + u64 ret; + + spu_acquire_runnable(ctx); + ret = ((in_be64(&ctx->spu->priv2->spu_cfg_RW) & 2) != 0); + spu_release(ctx); + + return ret; } DEFINE_SIMPLE_ATTRIBUTE(spufs_signal2_type, spufs_signal2_type_get, spufs_signal2_type_set, "%llu"); @@ -650,12 +776,18 @@ DEFINE_SIMPLE_ATTRIBUTE(spufs_signal2_ty static void spufs_ ## name ## _set(void *data, u64 val) \ { \ struct spu_context *ctx = data; \ + spu_acquire_runnable(ctx); \ out_be32(&ctx->spu->problem->name, val); \ + spu_release(ctx); \ } \ static u64 spufs_ ## name ## _get(void *data) \ { \ struct spu_context *ctx = data; \ - return in_be32(&ctx->spu->problem->name); \ + u64 ret; \ + spu_acquire_runnable(ctx); \ + ret = in_be32(&ctx->spu->problem->name); \ + spu_release(ctx); \ + return ret; \ } \ DEFINE_SIMPLE_ATTRIBUTE(spufs_ ## name, \ spufs_ ## name ## _get, \ @@ -665,12 +797,18 @@ DEFINE_SIMPLE_ATTRIBUTE(spufs_ ## name, static void spufs_ ## name ## _set(void *data, u64 val) \ { \ struct spu_context *ctx = data; \ + spu_acquire_runnable(ctx); \ out_be64(&ctx->spu->priv1->name, val); \ + spu_release(ctx); \ } \ static u64 spufs_ ## name ## _get(void *data) \ { \ struct spu_context *ctx = data; \ - return in_be64(&ctx->spu->priv1->name); \ + u64 ret; \ + spu_acquire_runnable(ctx); \ + ret = in_be64(&ctx->spu->priv1->name); \ + spu_release(ctx); \ + return ret; \ } \ DEFINE_SIMPLE_ATTRIBUTE(spufs_ ## name, \ spufs_ ## name ## _get, \ @@ -680,12 +818,18 @@ DEFINE_SIMPLE_ATTRIBUTE(spufs_ ## name, static void spufs_ ## name ## _set(void *data, u64 val) \ { \ struct spu_context *ctx = data; \ + spu_acquire_runnable(ctx); \ out_be64(&ctx->spu->priv2->name, val); \ + spu_release(ctx); \ } \ static u64 spufs_ ## name ## _get(void *data) \ { \ struct spu_context *ctx = data; \ - return in_be64(&ctx->spu->priv2->name); \ + u64 ret; \ + spu_acquire_runnable(ctx); \ + ret = in_be64(&ctx->spu->priv2->name); \ + spu_release(ctx); \ + return ret; \ } \ DEFINE_SIMPLE_ATTRIBUTE(spufs_ ## name, \ spufs_ ## name ## _get, \ @@ -711,6 +855,7 @@ priv2_attr(mfc_control_RW); struct tree_descr spufs_dir_contents[] = { { "mem", &spufs_mem_fops, 0666, }, + { "regs", &spufs_regs_fops, 0666, }, { "run", &spufs_run_fops, 0444, }, { "mbox", &spufs_mbox_fops, 0444, }, { "ibox", &spufs_ibox_fops, 0444, }, --- linux-cg.orig/fs/spufs/spufs.h 2005-08-25 23:12:36.584905696 -0400 +++ linux-cg/fs/spufs/spufs.h 2005-08-25 23:12:52.418895056 -0400 @@ -41,6 +41,9 @@ struct spu_context { struct rw_semaphore backing_sema; /* protects the above */ spinlock_t mmio_lock; /* protects mmio access */ + enum { SPU_STATE_RUNNABLE, SPU_STATE_SAVED, SPU_STATE_LOCKED } state; + struct rw_semaphore state_sema; + struct kref kref; }; From arnd at arndb.de Fri Aug 26 08:04:28 2005 From: arnd at arndb.de (Arnd Bergmann) Date: Fri, 26 Aug 2005 00:04:28 +0200 Subject: [PATCH 4/7] spufs: spu-side context switch code Message-ID: <200508260004.29161.arnd@arndb.de> Add the source code that is used to generate spu_save_dump.h and spu_restore_dump.h. Since a full spu tool chain is needed to generate these files, the default remains to use the shipped versions in order to keep the number of tools for building the kernel down. From: Mark Nutter: Signed-off-by: Arnd Bergmann -- Makefile | 46 +++++++ spu_restore.c | 336 +++++++++++++++++++++++++++++++++++++++++++++++++++++ spu_restore_crt0.S | 116 ++++++++++++++++++ spu_save.c | 203 ++++++++++++++++++++++++++++++++ spu_save_crt0.S | 102 ++++++++++++++++ spu_utils.h | 160 +++++++++++++++++++++++++ 6 files changed, 963 insertions(+) --- linux-cg.orig/fs/spufs/Makefile 2005-08-16 20:11:10.396001984 -0400 +++ linux-cg/fs/spufs/Makefile 2005-08-16 20:11:43.730998928 -0400 @@ -2,4 +2,50 @@ obj-$(CONFIG_SPU_FS) += spufs.o spufs-y += inode.o file.o context.o switch.o +# Rules to build switch.o with the help of SPU tool chain +SPU_CROSS := spu- +SPU_CC := $(SPU_CROSS)gcc +SPU_AS := $(SPU_CROSS)gcc +SPU_LD := $(SPU_CROSS)ld +SPU_READELF := $(SPU_CROSS)readelf +SPU_CFLAGS := -O2 -Wall -I$(srctree)/include -I$(objtree)/include2 +SPU_AFLAGS := -c -D__ASSEMBLY__ -I$(srctree)/include -I$(objtree)/include2 +SPU_LDFLAGS := -N -Ttext=0x0 + $(obj)/switch.o: $(obj)/spu_save_dump.h $(obj)/spu_restore_dump.h + +# Compile SPU files + cmd_spu_cc = $(SPU_CC) $(SPU_CFLAGS) -c -o $@ $< +quiet_cmd_spu_cc = SPU_CC $@ +$(obj)/spu_%.o: $(src)/spu_%.c + $(call if_changed,spu_cc) + +# Assemble SPU files + cmd_spu_as = $(SPU_AS) $(SPU_AFLAGS) -o $@ $< +quiet_cmd_spu_as = SPU_AS $@ +$(obj)/spu_%.o: $(src)/spu_%.S + $(call if_changed,spu_as) + +# Link SPU Executables + cmd_spu_ld = $(SPU_LD) $(SPU_LDFLAGS) -o $@ $^ +quiet_cmd_spu_ld = SPU_LD $@ +$(obj)/spu_%: $(obj)/spu_%.o $(obj)/spu_%_crt0.o + $(call if_changed,spu_ld) + +# create C code from ELF executable +cmd_hexdump = ( \ + echo "/*" ; \ + echo " * $@: Copyright (C) 2005 IBM." ; \ + echo " * Hex-dump auto generated from $<.c." ; \ + echo " * Do not edit!" ; \ + echo " */" ; \ + echo "static unsigned int $*_code[] __page_aligned = {" ; \ + $(SPU_READELF) -x1 -x2 $< | \ + grep -v "Hex dump of section" | \ + grep -v "^$$" | \ + $(AWK) -- '{ print "0x"$$2", 0x"$$3", 0x"$$4", 0x"$$5", " }' ; \ + echo "};" ; \ + ) > $@ +quiet_cmd_hexdump = HEXDUMP $@ +$(obj)/%_dump.h: $(obj)/% + $(call if_changed,hexdump) --- linux-cg.orig/fs/spufs/spu_restore.c 1969-12-31 19:00:00.000000000 -0500 +++ linux-cg/fs/spufs/spu_restore.c 2005-08-16 20:11:43.737997864 -0400 @@ -0,0 +1,336 @@ +/* + * spu_restore.c + * + * (C) Copyright IBM Corp. 2005 + * + * SPU-side context restore sequence outlined in + * Synergistic Processor Element Book IV + * + * Author: Mark Nutter + * + * 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, 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., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + + +#ifndef LS_SIZE +#define LS_SIZE 0x40000 /* 256K (in bytes) */ +#endif + +typedef unsigned int u32; +typedef unsigned long long u64; + +#include +#include +#include "spu_utils.h" + +#define BR_INSTR 0x327fff80 /* br -4 */ +#define NOP_INSTR 0x40200000 /* nop */ +#define HEQ_INSTR 0x7b000000 /* heq $0, $0 */ +#define STOP_INSTR 0x00000000 /* stop 0x0 */ +#define ILLEGAL_INSTR 0x00800000 /* illegal instr */ +#define RESTORE_COMPLETE 0x00003ffc /* stop 0x3ffc */ + +static inline void fetch_regs_from_mem(addr64 lscsa_ea) +{ + unsigned int ls = (unsigned int)®s_spill[0]; + unsigned int size = sizeof(regs_spill); + unsigned int tag_id = 0; + unsigned int cmd = 0x40; /* GET */ + + spu_writech(mfc_ls_addr, ls); + spu_writech(mfc_ea_hi, lscsa_ea.ui[0]); + spu_writech(mfc_ea_low, lscsa_ea.ui[1]); + spu_writech(mfc_dma_size, size); + spu_writech(mfc_tag_id, tag_id); + spu_writech(mfc_cmd_queue, cmd); +} + +static inline void restore_upper_240kb(addr64 lscsa_ea) +{ + unsigned int ls = 16384; + unsigned int list = (unsigned int)&dma_list[0]; + unsigned int size = sizeof(dma_list); + unsigned int tag_id = 0; + unsigned int cmd = 0x44; /* GETL */ + + /* Restore, Step 4: + * Enqueue the GETL command (tag 0) to the MFC SPU command + * queue to transfer the upper 240 kb of LS from CSA. + */ + spu_writech(mfc_ls_addr, ls); + spu_writech(mfc_ea_hi, lscsa_ea.ui[0]); + spu_writech(mfc_ea_low, list); + spu_writech(mfc_dma_size, size); + spu_writech(mfc_tag_id, tag_id); + spu_writech(mfc_cmd_queue, cmd); +} + +static inline void restore_decr(void) +{ + unsigned int offset; + unsigned int decr_running; + unsigned int decr; + + /* Restore, Step 6: + * If the LSCSA "decrementer running" flag is set + * then write the SPU_WrDec channel with the + * decrementer value from LSCSA. + */ + offset = LSCSA_QW_OFFSET(decr_status); + decr_running = regs_spill[offset].slot[0]; + if (decr_running) { + offset = LSCSA_QW_OFFSET(decr); + decr = regs_spill[offset].slot[0]; + spu_writech(spu_wr_decr_count, decr); + } +} + +static inline void write_ppu_mb(void) +{ + unsigned int offset; + unsigned int data; + + /* Restore, Step 11: + * Write the MFC_WrOut_MB channel with the PPU_MB + * data from LSCSA. + */ + offset = LSCSA_QW_OFFSET(ppu_mb); + data = regs_spill[offset].slot[0]; + spu_writech(mfc_wr_mailbox, data); +} + +static inline void write_ppuint_mb(void) +{ + unsigned int offset; + unsigned int data; + + /* Restore, Step 12: + * Write the MFC_WrInt_MB channel with the PPUINT_MB + * data from LSCSA. + */ + offset = LSCSA_QW_OFFSET(ppuint_mb); + data = regs_spill[offset].slot[0]; + spu_writech(mfc_wr_intr_mailbox, data); +} + +static inline void restore_fpcr(void) +{ + unsigned int offset; + vector unsigned int fpcr; + + /* Restore, Step 13: + * Restore the floating-point status and control + * register from the LSCSA. + */ + offset = LSCSA_QW_OFFSET(fpcr); + fpcr = regs_spill[offset].v; + spu_mtfpscr(fpcr); +} + +static inline void restore_srr0(void) +{ + unsigned int offset; + unsigned int srr0; + + /* Restore, Step 14: + * Restore the SPU SRR0 data from the LSCSA. + */ + offset = LSCSA_QW_OFFSET(srr0); + srr0 = regs_spill[offset].slot[0]; + spu_writech(spu_wr_srr0, srr0); +} + +static inline void restore_event_mask(void) +{ + unsigned int offset; + unsigned int event_mask; + + /* Restore, Step 15: + * Restore the SPU_RdEventMsk data from the LSCSA. + */ + offset = LSCSA_QW_OFFSET(event_mask); + event_mask = regs_spill[offset].slot[0]; + spu_writech(spu_wr_event_mask, event_mask); +} + +static inline void restore_tag_mask(void) +{ + unsigned int offset; + unsigned int tag_mask; + + /* Restore, Step 16: + * Restore the SPU_RdTagMsk data from the LSCSA. + */ + offset = LSCSA_QW_OFFSET(tag_mask); + tag_mask = regs_spill[offset].slot[0]; + spu_writech(mfc_wr_tag_mask, tag_mask); +} + +static inline void restore_complete(void) +{ + extern void exit_fini(void); + unsigned int *exit_instrs = (unsigned int *)exit_fini; + unsigned int offset; + unsigned int stopped_status; + unsigned int stopped_code; + + /* Restore, Step 18: + * Issue a stop-and-signal instruction with + * "good context restore" signal value. + * + * Restore, Step 19: + * There may be additional instructions placed + * here by the PPE Sequence for SPU Context + * Restore in order to restore the correct + * "stopped state". + * + * This step is handled here by analyzing the + * LSCSA.stopped_status and then modifying the + * exit() function to behave appropriately. + */ + + offset = LSCSA_QW_OFFSET(stopped_status); + stopped_status = regs_spill[offset].slot[0]; + stopped_code = regs_spill[offset].slot[1]; + + switch (stopped_status) { + case SPU_STOPPED_STATUS_P_I: + /* SPU_Status[P,I]=1. Add illegal instruction + * followed by stop-and-signal instruction after + * end of restore code. + */ + exit_instrs[0] = RESTORE_COMPLETE; + exit_instrs[1] = ILLEGAL_INSTR; + exit_instrs[2] = STOP_INSTR | stopped_code; + break; + case SPU_STOPPED_STATUS_P_H: + /* SPU_Status[P,H]=1. Add 'heq $0, $0' followed + * by stop-and-signal instruction after end of + * restore code. + */ + exit_instrs[0] = RESTORE_COMPLETE; + exit_instrs[1] = HEQ_INSTR; + exit_instrs[2] = STOP_INSTR | stopped_code; + break; + case SPU_STOPPED_STATUS_S_P: + /* SPU_Status[S,P]=1. Add nop instruction + * followed by 'br -4' after end of restore + * code. + */ + exit_instrs[0] = RESTORE_COMPLETE; + exit_instrs[1] = STOP_INSTR | stopped_code; + exit_instrs[2] = NOP_INSTR; + exit_instrs[3] = BR_INSTR; + break; + case SPU_STOPPED_STATUS_S_I: + /* SPU_Status[S,I]=1. Add illegal instruction + * followed by 'br -4' after end of restore code. + */ + exit_instrs[0] = RESTORE_COMPLETE; + exit_instrs[1] = ILLEGAL_INSTR; + exit_instrs[2] = NOP_INSTR; + exit_instrs[3] = BR_INSTR; + break; + case SPU_STOPPED_STATUS_I: + /* SPU_Status[I]=1. Add illegal instruction followed + * by infinite loop after end of restore sequence. + */ + exit_instrs[0] = RESTORE_COMPLETE; + exit_instrs[1] = ILLEGAL_INSTR; + exit_instrs[2] = NOP_INSTR; + exit_instrs[3] = BR_INSTR; + break; + case SPU_STOPPED_STATUS_S: + /* SPU_Status[S]=1. Add two 'nop' instructions. */ + exit_instrs[0] = RESTORE_COMPLETE; + exit_instrs[1] = NOP_INSTR; + exit_instrs[2] = NOP_INSTR; + exit_instrs[3] = BR_INSTR; + break; + case SPU_STOPPED_STATUS_H: + /* SPU_Status[H]=1. Add 'heq $0, $0' instruction + * after end of restore code. + */ + exit_instrs[0] = RESTORE_COMPLETE; + exit_instrs[1] = HEQ_INSTR; + exit_instrs[2] = NOP_INSTR; + exit_instrs[3] = BR_INSTR; + break; + case SPU_STOPPED_STATUS_P: + /* SPU_Status[P]=1. Add stop-and-signal instruction + * after end of restore code. + */ + exit_instrs[0] = RESTORE_COMPLETE; + exit_instrs[1] = STOP_INSTR | stopped_code; + break; + case SPU_STOPPED_STATUS_R: + /* SPU_Status[I,S,H,P,R]=0. Add infinite loop. */ + exit_instrs[0] = RESTORE_COMPLETE; + exit_instrs[1] = NOP_INSTR; + exit_instrs[2] = NOP_INSTR; + exit_instrs[3] = BR_INSTR; + break; + default: + /* SPU_Status[R]=1. No additonal instructions. */ + break; + } + spu_sync(); +} + +/** + * main - entry point for SPU-side context restore. + * + * This code deviates from the documented sequence in the + * following aspects: + * + * 1. The EA for LSCSA is passed from PPE in the + * signal notification channels. + * 2. The register spill area is pulled by SPU + * into LS, rather than pushed by PPE. + * 3. All 128 registers are restored by exit(). + * 4. The exit() function is modified at run + * time in order to properly restore the + * SPU_Status register. + */ +int main() +{ + addr64 lscsa_ea; + + lscsa_ea.ui[0] = spu_readch(mfc_rd_signal_1); + lscsa_ea.ui[1] = spu_readch(mfc_rd_signal_2); + fetch_regs_from_mem(lscsa_ea); + + set_event_mask(); /* Step 1. */ + set_tag_mask(); /* Step 2. */ + build_dma_list(lscsa_ea); /* Step 3. */ + restore_upper_240kb(lscsa_ea); /* Step 4. */ + /* Step 5: done by 'exit'. */ + restore_decr(); /* Step 6. */ + enqueue_putllc(lscsa_ea); /* Step 7. */ + set_tag_update(); /* Step 8. */ + read_tag_status(); /* Step 9. */ + read_llar_status(); /* Step 10. */ + write_ppu_mb(); /* Step 11. */ + write_ppuint_mb(); /* Step 12. */ + restore_fpcr(); /* Step 13. */ + restore_srr0(); /* Step 14. */ + restore_event_mask(); /* Step 15. */ + restore_tag_mask(); /* Step 16. */ + /* Step 17. done by 'exit'. */ + restore_complete(); /* Step 18. */ + + return 0; +} --- linux-cg.orig/fs/spufs/spu_restore_crt0.S 1969-12-31 19:00:00.000000000 -0500 +++ linux-cg/fs/spufs/spu_restore_crt0.S 2005-08-16 20:11:43.737997864 -0400 @@ -0,0 +1,116 @@ +/* + * crt0_r.S: Entry function for SPU-side context restore. + * + * Copyright (C) 2005 IBM + * + * Entry and exit function for SPU-side of the context restore + * sequence. Sets up an initial stack frame, then branches to + * 'main'. On return, restores all 128 registers from the LSCSA + * and exits. + * + * + * 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, 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include + +.data +.align 7 +.globl regs_spill +regs_spill: +.space SIZEOF_SPU_SPILL_REGS, 0x0 + +.text +.global _start +_start: + /* Initialize the stack pointer to point to 16368 + * (16kb-16). The back chain pointer is initialized + * to NULL. + */ + il $0, 0 + il $SP, 16368 + stqd $0, 0($SP) + + /* Allocate a minimum stack frame for the called main. + * This is needed so that main has a place to save the + * link register when it calls another function. + */ + stqd $SP, -160($SP) + ai $SP, $SP, -160 + + /* Call the program's main function. */ + brsl $0, main + +.global exit +.global _exit +exit: +_exit: + /* SPU Context Restore, Step 5: Restore the remaining 112 GPRs. */ + ila $3, regs_spill + 256 +restore_regs: + lqr $4, restore_reg_insts +restore_reg_loop: + ai $4, $4, 4 + .balignl 16, 0x40200000 +restore_reg_insts: /* must be quad-word aligned. */ + lqd $16, 0($3) + lqd $17, 16($3) + lqd $18, 32($3) + lqd $19, 48($3) + andi $5, $4, 0x7F + stqr $4, restore_reg_insts + ai $3, $3, 64 + brnz $5, restore_reg_loop + + /* SPU Context Restore Step 17: Restore the first 16 GPRs. */ + lqa $0, regs_spill + 0 + lqa $1, regs_spill + 16 + lqa $2, regs_spill + 32 + lqa $3, regs_spill + 48 + lqa $4, regs_spill + 64 + lqa $5, regs_spill + 80 + lqa $6, regs_spill + 96 + lqa $7, regs_spill + 112 + lqa $8, regs_spill + 128 + lqa $9, regs_spill + 144 + lqa $10, regs_spill + 160 + lqa $11, regs_spill + 176 + lqa $12, regs_spill + 192 + lqa $13, regs_spill + 208 + lqa $14, regs_spill + 224 + lqa $15, regs_spill + 240 + + /* Under normal circumstances, the 'exit' function + * terminates with 'stop SPU_RESTORE_COMPLETE', + * indicating that the SPU-side restore code has + * completed. + * + * However it is possible that instructions immediately + * following the 'stop 0x3ffc' have been modified at run + * time so as to recreate the exact SPU_Status settings + * from the application, e.g. illegal instruciton, halt, + * etc. + */ +.global exit_fini +.global _exit_fini +exit_fini: +_exit_fini: + stop SPU_RESTORE_COMPLETE + stop 0 + stop 0 + stop 0 + + /* Pad the size of this crt0.o to be multiple of 16 bytes. */ +.balignl 16, 0x0 --- linux-cg.orig/fs/spufs/spu_save.c 1969-12-31 19:00:00.000000000 -0500 +++ linux-cg/fs/spufs/spu_save.c 2005-08-16 20:11:43.741997256 -0400 @@ -0,0 +1,203 @@ +/* + * spu_save.c + * + * (C) Copyright IBM Corp. 2005 + * + * SPU-side context save sequence outlined in + * Synergistic Processor Element Book IV + * + * Author: Mark Nutter + * + * 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, 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., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + + +#ifndef LS_SIZE +#define LS_SIZE 0x40000 /* 256K (in bytes) */ +#endif + +typedef unsigned int u32; +typedef unsigned long long u64; + +#include +#include +#include "spu_utils.h" + +/* Hack! These two are not present in old DD1 spu_intrinsics.h! */ +#ifndef spu_rd_event_mask +#define spu_rd_event_mask 11 +#endif +#ifndef mfc_rd_tag_mask +#define mfc_rd_tag_mask 12 +#endif + +static inline void save_event_mask(void) +{ + unsigned int offset; + + /* Save, Step 2: + * Read the SPU_RdEventMsk channel and save to the LSCSA. + */ + offset = LSCSA_QW_OFFSET(event_mask); + regs_spill[offset].slot[0] = spu_readch(spu_rd_event_mask); +} + +static inline void save_tag_mask(void) +{ + unsigned int offset; + + /* Save, Step 3: + * Read the SPU_RdTagMsk channel and save to the LSCSA. + */ + offset = LSCSA_QW_OFFSET(tag_mask); + regs_spill[offset].slot[0] = spu_readch(mfc_rd_tag_mask); +} + +static inline void save_upper_240kb(addr64 lscsa_ea) +{ + unsigned int ls = 16384; + unsigned int list = (unsigned int)&dma_list[0]; + unsigned int size = sizeof(dma_list); + unsigned int tag_id = 0; + unsigned int cmd = 0x24; /* PUTL */ + + /* Save, Step 7: + * Enqueue the PUTL command (tag 0) to the MFC SPU command + * queue to transfer the remaining 240 kb of LS to CSA. + */ + spu_writech(mfc_ls_addr, ls); + spu_writech(mfc_ea_hi, lscsa_ea.ui[0]); + spu_writech(mfc_ea_low, list); + spu_writech(mfc_dma_size, size); + spu_writech(mfc_tag_id, tag_id); + spu_writech(mfc_cmd_queue, cmd); +} + +static inline void save_fpcr(void) +{ + // vector unsigned int fpcr; + unsigned int offset; + + /* Save, Step 9: + * Issue the floating-point status and control register + * read instruction, and save to the LSCSA. + */ + offset = LSCSA_QW_OFFSET(fpcr); + regs_spill[offset].v = spu_mffpscr(); +} + +static inline void save_decr(void) +{ + unsigned int offset; + + /* Save, Step 10: + * Read and save the SPU_RdDec channel data to + * the LSCSA. + */ + offset = LSCSA_QW_OFFSET(decr); + regs_spill[offset].slot[0] = spu_readch(spu_rd_decr_count); +} + +static inline void save_srr0(void) +{ + unsigned int offset; + + /* Save, Step 11: + * Read and save the SPU_WSRR0 channel data to + * the LSCSA. + */ + offset = LSCSA_QW_OFFSET(srr0); + regs_spill[offset].slot[0] = spu_readch(spu_rd_srr0); +} + +static inline void spill_regs_to_mem(addr64 lscsa_ea) +{ + unsigned int ls = (unsigned int)®s_spill[0]; + unsigned int size = sizeof(regs_spill); + unsigned int tag_id = 0; + unsigned int cmd = 0x20; /* PUT */ + + /* Save, Step 13: + * Enqueue a PUT command (tag 0) to send the LSCSA + * to the CSA. + */ + spu_writech(mfc_ls_addr, ls); + spu_writech(mfc_ea_hi, lscsa_ea.ui[0]); + spu_writech(mfc_ea_low, lscsa_ea.ui[1]); + spu_writech(mfc_dma_size, size); + spu_writech(mfc_tag_id, tag_id); + spu_writech(mfc_cmd_queue, cmd); +} + +static inline void enqueue_sync(addr64 lscsa_ea) +{ + unsigned int tag_id = 0; + unsigned int cmd = 0xCC; + + /* Save, Step 14: + * Enqueue an MFC_SYNC command (tag 0). + */ + spu_writech(mfc_tag_id, tag_id); + spu_writech(mfc_cmd_queue, cmd); +} + +static inline void save_complete(void) +{ + /* Save, Step 18: + * Issue a stop-and-signal instruction indicating + * "save complete". Note: This function will not + * return!! + */ + spu_stop(SPU_SAVE_COMPLETE); +} + +/** + * main - entry point for SPU-side context save. + * + * This code deviates from the documented sequence as follows: + * + * 1. The EA for LSCSA is passed from PPE in the + * signal notification channels. + * 2. All 128 registers are saved by crt0.o. + */ +int main() +{ + addr64 lscsa_ea; + + lscsa_ea.ui[0] = spu_readch(mfc_rd_signal_1); + lscsa_ea.ui[1] = spu_readch(mfc_rd_signal_2); + + /* Step 1: done by exit(). */ + save_event_mask(); /* Step 2. */ + save_tag_mask(); /* Step 3. */ + set_event_mask(); /* Step 4. */ + set_tag_mask(); /* Step 5. */ + build_dma_list(lscsa_ea); /* Step 6. */ + save_upper_240kb(lscsa_ea); /* Step 7. */ + /* Step 8: done by exit(). */ + save_fpcr(); /* Step 9. */ + save_decr(); /* Step 10. */ + save_srr0(); /* Step 11. */ + enqueue_putllc(lscsa_ea); /* Step 12. */ + spill_regs_to_mem(lscsa_ea); /* Step 13. */ + enqueue_sync(lscsa_ea); /* Step 14. */ + set_tag_update(); /* Step 15. */ + read_tag_status(); /* Step 16. */ + read_llar_status(); /* Step 17. */ + save_complete(); /* Step 18. */ + + return 0; +} --- linux-cg.orig/fs/spufs/spu_save_crt0.S 1969-12-31 19:00:00.000000000 -0500 +++ linux-cg/fs/spufs/spu_save_crt0.S 2005-08-16 20:11:43.742997104 -0400 @@ -0,0 +1,102 @@ +/* + * crt0_s.S: Entry function for SPU-side context save. + * + * Copyright (C) 2005 IBM + * + * Entry function for SPU-side of the context save sequence. + * Saves all 128 GPRs, sets up an initial stack frame, then + * branches to 'main'. + * + * + * 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, 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include + +.data +.align 7 +.globl regs_spill +regs_spill: +.space SIZEOF_SPU_SPILL_REGS, 0x0 + +.text +.global _start +_start: + /* SPU Context Save Step 1: Save the first 16 GPRs. */ + stqa $0, regs_spill + 0 + stqa $1, regs_spill + 16 + stqa $2, regs_spill + 32 + stqa $3, regs_spill + 48 + stqa $4, regs_spill + 64 + stqa $5, regs_spill + 80 + stqa $6, regs_spill + 96 + stqa $7, regs_spill + 112 + stqa $8, regs_spill + 128 + stqa $9, regs_spill + 144 + stqa $10, regs_spill + 160 + stqa $11, regs_spill + 176 + stqa $12, regs_spill + 192 + stqa $13, regs_spill + 208 + stqa $14, regs_spill + 224 + stqa $15, regs_spill + 240 + + /* SPU Context Save, Step 8: Save the remaining 112 GPRs. */ + ila $3, regs_spill + 256 +save_regs: + lqr $4, save_reg_insts +save_reg_loop: + ai $4, $4, 4 + .balignl 16, 0x40200000 +save_reg_insts: /* must be quad-word aligned. */ + stqd $16, 0($3) + stqd $17, 16($3) + stqd $18, 32($3) + stqd $19, 48($3) + andi $5, $4, 0x7F + stqr $4, save_reg_insts + ai $3, $3, 64 + brnz $5, save_reg_loop + + /* Initialize the stack pointer to point to 16368 + * (16kb-16). The back chain pointer is initialized + * to NULL. + */ + il $0, 0 + il $SP, 16368 + stqd $0, 0($SP) + + /* Allocate a minimum stack frame for the called main. + * This is needed so that main has a place to save the + * link register when it calls another function. + */ + stqd $SP, -160($SP) + ai $SP, $SP, -160 + + /* Call the program's main function. */ + brsl $0, main + + /* In this case main should not return; if it does + * there has been an error in the sequence. Execute + * stop-and-signal with code=0. + */ +.global exit +.global _exit +exit: +_exit: + stop 0x0 + + /* Pad the size of this crt0.o to be multiple of 16 bytes. */ +.balignl 16, 0x0 + --- linux-cg.orig/fs/spufs/spu_utils.h 1969-12-31 19:00:00.000000000 -0500 +++ linux-cg/fs/spufs/spu_utils.h 2005-08-16 20:11:43.745996648 -0400 @@ -0,0 +1,160 @@ +/* + * utils.h: Utilities for SPU-side of the context switch operation. + * + * (C) Copyright IBM 2005 + * + * 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, 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef _SPU_CONTEXT_UTILS_H_ +#define _SPU_CONTEXT_UTILS_H_ + +/* + * 64-bit safe EA. + */ +typedef union { + unsigned long long ull; + unsigned int ui[2]; +} addr64; + +/* + * 128-bit register template. + */ +typedef union { + unsigned int slot[4]; + vector unsigned int v; +} spu_reg128v; + +/* + * DMA list structure. + */ +struct dma_list_elem { + unsigned int size; + unsigned int ea_low; +}; + +/* + * Declare storage for 8-byte aligned DMA list. + */ +struct dma_list_elem dma_list[15] __attribute__ ((aligned(8))); + +/* + * External definition for storage + * declared in crt0. + */ +extern spu_reg128v regs_spill[NR_SPU_SPILL_REGS]; + +/* + * Compute LSCSA byte offset for a given field. + */ +static struct spu_lscsa *dummy = (struct spu_lscsa *)0; +#define LSCSA_BYTE_OFFSET(_field) \ + ((char *)(&(dummy->_field)) - (char *)(&(dummy->gprs[0].slot[0]))) +#define LSCSA_QW_OFFSET(_field) (LSCSA_BYTE_OFFSET(_field) >> 4) + +static inline void set_event_mask(void) +{ + unsigned int event_mask = 0; + + /* Save, Step 4: + * Restore, Step 1: + * Set the SPU_RdEventMsk channel to zero to mask + * all events. + */ + spu_writech(spu_wr_event_mask, event_mask); +} + +static inline void set_tag_mask(void) +{ + unsigned int tag_mask = 1; + + /* Save, Step 5: + * Restore, Step 2: + * Set the SPU_WrTagMsk channel to '01' to unmask + * only tag group 0. + */ + spu_writech(mfc_wr_tag_mask, tag_mask); +} + +static inline void build_dma_list(addr64 lscsa_ea) +{ + unsigned int ea_low; + int i; + + /* Save, Step 6: + * Restore, Step 3: + * Update the effective address for the CSA in the + * pre-canned DMA-list in local storage. + */ + ea_low = lscsa_ea.ui[1]; + ea_low += LSCSA_BYTE_OFFSET(ls[16384]); + + for (i = 0; i < 15; i++, ea_low += 16384) { + dma_list[i].size = 16384; + dma_list[i].ea_low = ea_low; + } +} + +static inline void enqueue_putllc(addr64 lscsa_ea) +{ + unsigned int ls = 0; + unsigned int size = 128; + unsigned int tag_id = 0; + unsigned int cmd = 0xB4; /* PUTLLC */ + + /* Save, Step 12: + * Restore, Step 7: + * Send a PUTLLC (tag 0) command to the MFC using + * an effective address in the CSA in order to + * remove any possible lock-line reservation. + */ + spu_writech(mfc_ls_addr, ls); + spu_writech(mfc_ea_hi, lscsa_ea.ui[0]); + spu_writech(mfc_ea_low, lscsa_ea.ui[1]); + spu_writech(mfc_dma_size, size); + spu_writech(mfc_tag_id, tag_id); + spu_writech(mfc_cmd_queue, cmd); +} + +static inline void set_tag_update(void) +{ + unsigned int update_any = 1; + + /* Save, Step 15: + * Restore, Step 8: + * Write the MFC_TagUpdate channel with '01'. + */ + spu_writech(mfc_wr_tag_update, update_any); +} + +static inline void read_tag_status(void) +{ + /* Save, Step 16: + * Restore, Step 9: + * Read the MFC_TagStat channel data. + */ + spu_readch(mfc_rd_tag_status); +} + +static inline void read_llar_status(void) +{ + /* Save, Step 17: + * Restore, Step 10: + * Read the MFC_AtomicStat channel data. + */ + spu_readch(mfc_rd_llar_status); +} + +#endif /* _SPU_CONTEXT_UTILS_H_ */ From arnd at arndb.de Fri Aug 26 08:04:33 2005 From: arnd at arndb.de (Arnd Bergmann) Date: Fri, 26 Aug 2005 00:04:33 +0200 Subject: [PATCH 6/7] spufs: allow O_ASYNC on mailbox files Message-ID: <200508260004.34216.arnd@arndb.de> This patch makes it possible to receive user-defined signals when the spufs ibox and wbox files are accessed from an SPE, so data can be read/written from/to them again. Unfortunately, this kind of messes with the layering of the high- and low-level parts of the code, so I'm currently thinking about dropping the functionality again. If anyone has strong opinions on how useful or harmful this patch is, please tell me. Signed-off-by: Arnd Bergmann -- arch/ppc64/kernel/spu_base.c | 7 +++++++ fs/spufs/file.c | 16 ++++++++++++++++ include/asm-ppc64/spu.h | 2 ++ 3 files changed, 25 insertions(+) --- linux-cg.orig/arch/ppc64/kernel/spu_base.c 2005-08-25 23:12:30.395914664 -0400 +++ linux-cg/arch/ppc64/kernel/spu_base.c 2005-08-25 23:12:46.857941720 -0400 @@ -136,6 +136,7 @@ static int __spu_trap_data_map(struct sp static int __spu_trap_mailbox(struct spu *spu) { wake_up_all(&spu->ibox_wq); + kill_fasync(&spu->ibox_fasync, SIGIO, POLLIN); /* atomically disable SPU mailbox interrupts */ spin_lock(&spu->register_lock); @@ -171,6 +172,7 @@ static int __spu_trap_tag_group(struct s static int __spu_trap_spubox(struct spu *spu) { wake_up_all(&spu->wbox_wq); + kill_fasync(&spu->wbox_fasync, SIGIO, POLLOUT); /* atomically disable SPU mailbox interrupts */ spin_lock(&spu->register_lock); @@ -394,6 +396,8 @@ EXPORT_SYMBOL(spu_alloc); void spu_free(struct spu *spu) { down(&spu_mutex); + spu->ibox_fasync = NULL; + spu->wbox_fasync = NULL; list_add_tail(&spu->list, &spu_list); up(&spu_mutex); } @@ -676,6 +680,9 @@ static int __init create_spu(struct devi init_waitqueue_head(&spu->wbox_wq); init_waitqueue_head(&spu->ibox_wq); + spu->ibox_fasync = NULL; + spu->wbox_fasync = NULL; + down(&spu_mutex); spu->number = number++; ret = spu_request_irqs(spu); --- linux-cg.orig/fs/spufs/file.c 2005-08-25 23:12:36.584905696 -0400 +++ linux-cg/fs/spufs/file.c 2005-08-25 23:12:46.858941568 -0400 @@ -198,6 +198,13 @@ size_t spu_ibox_read(struct spu *spu, u3 } EXPORT_SYMBOL(spu_ibox_read); +static int spufs_ibox_fasync(int fd, struct file *file, int on) +{ + struct spu_context *ctx; + ctx = file->private_data; + return fasync_helper(fd, file, on, &ctx->spu->ibox_fasync); +} + static ssize_t spufs_ibox_read(struct file *file, char __user *buf, size_t len, loff_t *pos) { @@ -253,6 +260,7 @@ static struct file_operations spufs_ibox .open = spufs_pipe_open, .read = spufs_ibox_read, .poll = spufs_ibox_poll, + .fasync = spufs_ibox_fasync, }; static ssize_t spufs_ibox_stat_read(struct file *file, char __user *buf, @@ -302,6 +310,13 @@ size_t spu_wbox_write(struct spu *spu, u } EXPORT_SYMBOL(spu_wbox_write); +static int spufs_wbox_fasync(int fd, struct file *file, int on) +{ + struct spu_context *ctx; + ctx = file->private_data; + return fasync_helper(fd, file, on, &ctx->spu->wbox_fasync); +} + static ssize_t spufs_wbox_write(struct file *file, const char __user *buf, size_t len, loff_t *pos) { @@ -353,6 +368,7 @@ static struct file_operations spufs_wbox .open = spufs_pipe_open, .write = spufs_wbox_write, .poll = spufs_wbox_poll, + .fasync = spufs_wbox_fasync, }; static ssize_t spufs_wbox_stat_read(struct file *file, char __user *buf, --- linux-cg.orig/include/asm-ppc64/spu.h 2005-08-25 23:12:30.400913904 -0400 +++ linux-cg/include/asm-ppc64/spu.h 2005-08-25 23:12:46.860941264 -0400 @@ -127,6 +127,8 @@ struct spu { wait_queue_head_t stop_wq; wait_queue_head_t ibox_wq; wait_queue_head_t wbox_wq; + struct fasync_struct *ibox_fasync; + struct fasync_struct *wbox_fasync; char irq_c0[8]; char irq_c1[8]; From paulus at samba.org Fri Aug 26 09:14:39 2005 From: paulus at samba.org (Paul Mackerras) Date: Fri, 26 Aug 2005 09:14:39 +1000 Subject: [RFC/PATCH] Set up PCI tree from OF on ppc64 In-Reply-To: <1124998613.15265.7.camel@sinatra.austin.ibm.com> References: <17165.800.617053.891578@cargo.ozlabs.ibm.com> <1124998613.15265.7.camel@sinatra.austin.ibm.com> Message-ID: <17166.20703.93373.580025@cargo.ozlabs.ibm.com> John Rose writes: > Would we not want to use PROBE_DEVTREE for non-partitioned and legacy > pSeries? We could, once we've tested that it all works as expected on POWER3 and RS64 systems. I was just being a bit conservative. > +static void __devinit of_scan_bus(struct device_node *node, > + struct pci_bus *bus) > ... > +static void __devinit of_scan_pci_bridge(struct device_node *node, > + struct pci_dev *dev) > > We should probably expose these for use by the PCI Hotplug/DLPAR > drivers, along w/ scan_phb(). Sure. I was thinking as I was writing this code that we should use it for hotplug as well. > Could pci_process_bridge_OF_ranges() and of_scan_pci_bridge() use > common "ranges" parsing logic? We're parsing the same property > in two different ways in the same file. This could be a "todo" I > guess. Yes, probably. The size of each entry in the ranges property depends on #address-cells for the parent, #address-cells for the child, and #size-cells for the child. Currently we have those values hard-coded to 3, 3, and 2 for of_scan_pci_bridge (which is OK because those values are mandated by the PCI binding to OF), and 2, 3, 2 in pci_process_bridge_OF_ranges. That's the main difference between them. Paul. From paulus at samba.org Fri Aug 26 09:18:00 2005 From: paulus at samba.org (Paul Mackerras) Date: Fri, 26 Aug 2005 09:18:00 +1000 Subject: [patch 8/8] PCI Error Recovery: PPC64 core recovery routines In-Reply-To: <1125006237.12539.23.camel@gaston> References: <20050823231817.829359000@bilge> <20050823232143.003048000@bilge> <20050823234747.GI18113@austin.ibm.com> <1124898331.24668.33.camel@sinatra.austin.ibm.com> <20050824162959.GC25174@austin.ibm.com> <17165.3205.505386.187453@cargo.ozlabs.ibm.com> <1124930943.5159.168.camel@gaston> <20050825162118.GH25174@austin.ibm.com> <1125006237.12539.23.camel@gaston> Message-ID: <17166.20904.543484.435446@cargo.ozlabs.ibm.com> Benjamin Herrenschmidt writes: > Ok, so what is the problem then ? Why do we have to wait at all ? Why > not just unplug/replug right away ? We'd have to be absolutely certain that the driver could not possibly take another interrupt or try to access the device on behalf of the old instance of the device by the time it returned from the remove function. I'm not sure I'd trust most drivers that far... Paul. From paulus at samba.org Fri Aug 26 08:57:37 2005 From: paulus at samba.org (Paul Mackerras) Date: Fri, 26 Aug 2005 08:57:37 +1000 Subject: [RFC/PATCH] Set up PCI tree from OF on ppc64 In-Reply-To: <640514b313694c6083cacd9863058a32@kernel.crashing.org> References: <17165.800.617053.891578@cargo.ozlabs.ibm.com> <640514b313694c6083cacd9863058a32@kernel.crashing.org> Message-ID: <17166.19681.434577.137224@cargo.ozlabs.ibm.com> Segher Boessenkool writes: > Then the hypervisor should just hide these bridges from us (or fake > all accesses to it). What the hypervisor "should" do is pretty close to irrelevant in this situation. I basically had the choice of either presenting each of these special PCI-PCI bridges as a host bridge to the PCI-PCI code, or constructing the PCI tree from the OF device tree, and the latter seemed better to me. Paul. From benh at kernel.crashing.org Fri Aug 26 09:37:36 2005 From: benh at kernel.crashing.org (Benjamin Herrenschmidt) Date: Fri, 26 Aug 2005 09:37:36 +1000 Subject: [patch 8/8] PCI Error Recovery: PPC64 core recovery routines In-Reply-To: <17166.20904.543484.435446@cargo.ozlabs.ibm.com> References: <20050823231817.829359000@bilge> <20050823232143.003048000@bilge> <20050823234747.GI18113@austin.ibm.com> <1124898331.24668.33.camel@sinatra.austin.ibm.com> <20050824162959.GC25174@austin.ibm.com> <17165.3205.505386.187453@cargo.ozlabs.ibm.com> <1124930943.5159.168.camel@gaston> <20050825162118.GH25174@austin.ibm.com> <1125006237.12539.23.camel@gaston> <17166.20904.543484.435446@cargo.ozlabs.ibm.com> Message-ID: <1125013056.14185.0.camel@gaston> On Fri, 2005-08-26 at 09:18 +1000, Paul Mackerras wrote: > Benjamin Herrenschmidt writes: > > > Ok, so what is the problem then ? Why do we have to wait at all ? Why > > not just unplug/replug right away ? > > We'd have to be absolutely certain that the driver could not possibly > take another interrupt or try to access the device on behalf of the > old instance of the device by the time it returned from the remove > function. I'm not sure I'd trust most drivers that far... Hrm... If a driver gets that wrong, then it will also blow up when unloaded as a module. All drivers should be fully shut down by the time they return from remove(). free_irq() is synchronous as is iounmap() and both of those are usually called as part of remove(). I wouldn't be too worried here. Ben. From michael at ellerman.id.au Fri Aug 26 12:53:19 2005 From: michael at ellerman.id.au (Michael Ellerman) Date: Fri, 26 Aug 2005 12:53:19 +1000 (EST) Subject: [PATCH 0/12] Enable non-zero KERNELBASE Message-ID: <1125024799.128302.675577398916.qpatch@concordia> For kdump we need to boot the kernel at somewhere other than zero, because the first kernel is already running (or crashed) at zero. This series of patches makes changes to allow us to boot a kernel at 32 MB. The first six patches, up to "Add a is_kernel_addr() macro", are preparatory changes and are good to merge if no one objects. (on top of the current for-2.6.14 branch) The remaining six patches are still experimental. Feedback requested! There's still a few KERNELBASE references lying around that I haven't checked out yet, I'll get to them soonish. Booted at zero and 32MB on P5 LPAR, Power3 and G5. From michael at ellerman.id.au Fri Aug 26 12:53:20 2005 From: michael at ellerman.id.au (Michael Ellerman) Date: Fri, 26 Aug 2005 12:53:20 +1000 (EST) Subject: [PATCH 1/12] ppc64: Set entry point and text address in linker script In-Reply-To: <1125024799.128302.675577398916.qpatch@concordia> Message-ID: <20050826025320.764BC68051@ozlabs.org> Currently we set the kernel entry point and the address of the text section in the Makefile, using a hard-coded 0xc000000000000000. Instead we can #include in the linker script and use KERNELBASE directly. Which means if we ever change KERNELBASE there's one less place to change it. There are zero differences from readelf of vmlinux before and after this patch. Signed-off-by: Michael Ellerman --- arch/ppc64/Makefile | 4 +--- arch/ppc64/kernel/vmlinux.lds.S | 3 +++ 2 files changed, 4 insertions(+), 3 deletions(-) Index: work/arch/ppc64/Makefile =================================================================== --- work.orig/arch/ppc64/Makefile +++ work/arch/ppc64/Makefile @@ -13,8 +13,6 @@ # Adjusted for PPC64 by Tom Gall # -KERNELLOAD := 0xc000000000000000 - # Set default 32 bits cross compilers for vdso and boot wrapper CROSS32_COMPILE ?= @@ -52,7 +50,7 @@ endif CHECKFLAGS += -m64 -D__powerpc__ LDFLAGS := -m elf64ppc -LDFLAGS_vmlinux := -Bstatic -e $(KERNELLOAD) -Ttext $(KERNELLOAD) +LDFLAGS_vmlinux := -Bstatic CFLAGS += -msoft-float -pipe -mminimal-toc -mtraceback=none \ -mcall-aixdesc Index: work/arch/ppc64/kernel/vmlinux.lds.S =================================================================== --- work.orig/arch/ppc64/kernel/vmlinux.lds.S +++ work/arch/ppc64/kernel/vmlinux.lds.S @@ -1,5 +1,7 @@ #include +#include +ENTRY(_stext) OUTPUT_ARCH(powerpc:common64) jiffies = jiffies_64; SECTIONS @@ -9,6 +11,7 @@ SECTIONS *(.exitcall.exit) } + . = KERNELBASE; /* Read-only sections, merged into text segment: */ .text : { From michael at ellerman.id.au Fri Aug 26 12:53:21 2005 From: michael at ellerman.id.au (Michael Ellerman) Date: Fri, 26 Aug 2005 12:53:21 +1000 (EST) Subject: [PATCH 2/12] ppc64: Fixup __after_prom_start to use phys address returned from prom_init() In-Reply-To: <1125024799.128302.675577398916.qpatch@concordia> Message-ID: <20050826025321.0E6F368051@ozlabs.org> This patch removes a FIXME in head.S. prom_init() calculates the physical address of __start and passes it to the kernel, however currently the code ignores this value and recalculates. So instead just use the value provided by prom_init(). Signed-off-by: Michael Ellerman --- arch/ppc64/kernel/head.S | 15 +++++---------- 1 files changed, 5 insertions(+), 10 deletions(-) Index: work/arch/ppc64/kernel/head.S =================================================================== --- work.orig/arch/ppc64/kernel/head.S +++ work/arch/ppc64/kernel/head.S @@ -1441,8 +1441,8 @@ _STATIC(__boot_from_prom) trap /* - * At this point, r3 contains the physical address we are running at, - * returned by prom_init() + * At this point, r30 contains the physical address of __start, returned + * by prom_init() */ _STATIC(__after_prom_start) @@ -1458,17 +1458,11 @@ _STATIC(__after_prom_start) * r26 == relocation offset * r27 == KERNELBASE */ - bl .reloc_offset - mr r26,r3 SET_REG_TO_CONST(r27,KERNELBASE) li r3,0 /* target addr */ - // XXX FIXME: Use phys returned by OF (r30) - sub r4,r27,r26 /* source addr */ - /* current address of _start */ - /* i.e. where we are running */ - /* the source addr */ + mr r4,r30 /* source, current addr of __start */ LOADADDR(r5,copy_to_here) /* # bytes of memory to copy */ sub r5,r5,r27 @@ -1485,7 +1479,8 @@ _STATIC(__after_prom_start) bctr 4: LOADADDR(r5,klimit) - sub r5,r5,r26 + sub r5,r5,r27 /* subtract KERNELBASE */ + add r5,r5,r30 /* add physical offset to __start */ ld r5,0(r5) /* get the value of klimit */ sub r5,r5,r27 bl .copy_and_flush /* copy the rest */ From michael at ellerman.id.au Fri Aug 26 12:53:21 2005 From: michael at ellerman.id.au (Michael Ellerman) Date: Fri, 26 Aug 2005 12:53:21 +1000 (EST) Subject: [PATCH 3/12] ppc64: Remove unused reloc_offset code In-Reply-To: <1125024799.128302.675577398916.qpatch@concordia> Message-ID: <20050826025321.AC23068051@ozlabs.org> In head.S there are several routines that are written to use reloc_offset, so they can run at a different address to their link address. However, some of these routines are only ever called after the kernel's moved to it's linked address, and so the reloc_offset business is redundant. This patch changes the calling convention for cpu_setup routines, but currently none of them actually consult their arguments so no further changes are needed. Signed-off-by: Michael Ellerman --- arch/ppc64/kernel/head.S | 13 ------------- arch/ppc64/kernel/misc.S | 10 ++-------- 2 files changed, 2 insertions(+), 21 deletions(-) Index: work/arch/ppc64/kernel/head.S =================================================================== --- work.orig/arch/ppc64/kernel/head.S +++ work/arch/ppc64/kernel/head.S @@ -1342,7 +1342,6 @@ _STATIC(__start_initialization_iSeries) LOADADDR(r3,cpu_specs) LOADADDR(r4,cur_cpu_spec) - li r5,0 bl .identify_cpu LOADADDR(r2,__toc_start) @@ -1689,10 +1688,6 @@ _GLOBAL(enable_64b_mode) * This is where the main kernel code starts. */ _STATIC(start_here_multiplatform) - /* get a new offset, now that the kernel has moved. */ - bl .reloc_offset - mr r26,r3 - /* Clear out the BSS. It may have been done in prom_init, * already but that's irrelevant since prom_init will soon * be detached from the kernel completely. Besides, we need @@ -1738,7 +1733,6 @@ _STATIC(start_here_multiplatform) /* kernel but are still running in real mode. */ LOADADDR(r3,init_thread_union) - sub r3,r3,r26 /* set up a stack pointer (physical address) */ addi r1,r3,THREAD_SIZE @@ -1749,13 +1743,9 @@ _STATIC(start_here_multiplatform) LOADADDR(r2,__toc_start) addi r2,r2,0x4000 addi r2,r2,0x4000 - sub r2,r2,r26 LOADADDR(r3,cpu_specs) - sub r3,r3,r26 LOADADDR(r4,cur_cpu_spec) - sub r4,r4,r26 - mr r5,r26 bl .identify_cpu /* Save some low level config HIDs of CPU0 to be copied to @@ -1770,13 +1760,11 @@ _STATIC(start_here_multiplatform) * code */ LOADADDR(r27, boot_cpuid) - sub r27,r27,r26 lwz r27,0(r27) LOADADDR(r24, paca) /* Get base vaddr of paca array */ mulli r13,r27,PACA_SIZE /* Calculate vaddr of right paca */ add r13,r13,r24 /* for this processor. */ - sub r13,r13,r26 /* convert to physical addr */ mtspr SPRG3,r13 /* PPPBBB: Temp... -Peter */ /* Do very early kernel initializations, including initial hash table, @@ -1814,7 +1802,6 @@ _STATIC(start_here_multiplatform) andi. r3,r3,0x1 bne 98f LOADADDR(r6,_SDR1) /* Only if NOT LPAR */ - sub r6,r6,r26 ld r6,0(r6) /* get the value of _SDR1 */ mtspr SDR1,r6 /* set the htab location */ 98: Index: work/arch/ppc64/kernel/misc.S =================================================================== --- work.orig/arch/ppc64/kernel/misc.S +++ work/arch/ppc64/kernel/misc.S @@ -511,7 +511,6 @@ _GLOBAL(cvt_df) * identify_cpu and calls setup_cpu * In: r3 = base of the cpu_specs array * r4 = address of cur_cpu_spec - * r5 = relocation offset */ _GLOBAL(identify_cpu) mfpvr r7 @@ -524,16 +523,11 @@ _GLOBAL(identify_cpu) addi r3,r3,CPU_SPEC_ENTRY_SIZE b 1b 1: - add r0,r3,r5 - std r0,0(r4) + std r3,0(r4) ld r4,CPU_SPEC_SETUP(r3) - sub r4,r4,r5 ld r4,0(r4) - sub r4,r4,r5 mtctr r4 - /* Calling convention for cpu setup is r3=offset, r4=cur_cpu_spec */ - mr r4,r3 - mr r3,r5 + /* Calling convention for cpu setup is r3 = cur_cpu_spec */ bctr /* From michael at ellerman.id.au Fri Aug 26 12:53:22 2005 From: michael at ellerman.id.au (Michael Ellerman) Date: Fri, 26 Aug 2005 12:53:22 +1000 (EST) Subject: [PATCH 4/12] ppc64: Rename VMALLOCBASE to VMALLOC_OFFSET In-Reply-To: <1125024799.128302.675577398916.qpatch@concordia> Message-ID: <20050826025322.5296D68093@ozlabs.org> VMALLOCBASE would seem to be similar to KERNELBASE, but in fact it's not, it's more like PAGE_OFFSET, so rename it to avoid confusion. Signed-off-by: Michael Ellerman --- arch/ppc64/kernel/lparmap.c | 4 ++-- arch/ppc64/mm/slb.c | 6 +++--- include/asm-ppc64/page.h | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) Index: work/arch/ppc64/mm/slb.c =================================================================== --- work.orig/arch/ppc64/mm/slb.c +++ work/arch/ppc64/mm/slb.c @@ -67,8 +67,8 @@ static void slb_flush_and_rebolt(void) /* Slot 2 - kernel stack */ "slbmte %2,%3\n" "isync" - :: "r"(mk_vsid_data(VMALLOCBASE, SLB_VSID_KERNEL)), - "r"(mk_esid_data(VMALLOCBASE, 1)), + :: "r"(mk_vsid_data(VMALLOC_OFFSET, SLB_VSID_KERNEL)), + "r"(mk_esid_data(VMALLOC_OFFSET, 1)), "r"(mk_vsid_data(ksp_esid_data, ksp_flags)), "r"(ksp_esid_data) : "memory"); @@ -146,7 +146,7 @@ void slb_initialize(void) asm volatile("slbmte %0,%0"::"r" (0) : "memory"); asm volatile("isync; slbia; isync":::"memory"); create_slbe(KERNELBASE, flags, 0); - create_slbe(VMALLOCBASE, SLB_VSID_KERNEL, 1); + create_slbe(VMALLOC_OFFSET, SLB_VSID_KERNEL, 1); /* We don't bolt the stack for the time being - we're in boot, * so the stack is in the bolted segment. By the time it goes * elsewhere, we'll call _switch() which will bolt in the new Index: work/include/asm-ppc64/page.h =================================================================== --- work.orig/include/asm-ppc64/page.h +++ work/include/asm-ppc64/page.h @@ -213,9 +213,9 @@ extern u64 ppc64_pft_size; /* Log 2 of /* to change! */ #define PAGE_OFFSET ASM_CONST(0xC000000000000000) #define KERNELBASE PAGE_OFFSET -#define VMALLOCBASE ASM_CONST(0xD000000000000000) +#define VMALLOC_OFFSET ASM_CONST(0xD000000000000000) -#define VMALLOC_REGION_ID (VMALLOCBASE >> REGION_SHIFT) +#define VMALLOC_REGION_ID (VMALLOC_OFFSET >> REGION_SHIFT) #define KERNEL_REGION_ID (KERNELBASE >> REGION_SHIFT) #define USER_REGION_ID (0UL) #define REGION_ID(ea) (((unsigned long)(ea)) >> REGION_SHIFT) Index: work/arch/ppc64/kernel/lparmap.c =================================================================== --- work.orig/arch/ppc64/kernel/lparmap.c +++ work/arch/ppc64/kernel/lparmap.c @@ -18,8 +18,8 @@ const struct LparMap __attribute__((__se .xEsids = { { .xKernelEsid = GET_ESID(KERNELBASE), .xKernelVsid = KERNEL_VSID(KERNELBASE), }, - { .xKernelEsid = GET_ESID(VMALLOCBASE), - .xKernelVsid = KERNEL_VSID(VMALLOCBASE), }, + { .xKernelEsid = GET_ESID(VMALLOC_OFFSET), + .xKernelVsid = KERNEL_VSID(VMALLOC_OFFSET), }, }, .xRanges = { From michael at ellerman.id.au Fri Aug 26 12:53:24 2005 From: michael at ellerman.id.au (Michael Ellerman) Date: Fri, 26 Aug 2005 12:53:24 +1000 (EST) Subject: [PATCH 5/12] ppc64: Add __va_ul() which does __va() but returns unsigned long In-Reply-To: <1125024799.128302.675577398916.qpatch@concordia> Message-ID: <20050826025324.CF7866809A@ozlabs.org> Currently __va() returns void *, however about half of the callers of __va() actually want an unsigned long as the return value. So we add a __va_ul() macro that does this for us. Purely cosmetic. Signed-off-by: Michael Ellerman --- arch/ppc64/kernel/iSeries_setup.c | 4 ++-- arch/ppc64/kernel/pSeries_iommu.c | 2 +- arch/ppc64/kernel/setup.c | 4 ++-- arch/ppc64/oprofile/op_model_power4.c | 2 +- include/asm-ppc64/page.h | 3 ++- 5 files changed, 8 insertions(+), 7 deletions(-) Index: work/include/asm-ppc64/page.h =================================================================== --- work.orig/include/asm-ppc64/page.h +++ work/include/asm-ppc64/page.h @@ -220,7 +220,8 @@ extern u64 ppc64_pft_size; /* Log 2 of #define USER_REGION_ID (0UL) #define REGION_ID(ea) (((unsigned long)(ea)) >> REGION_SHIFT) -#define __va(x) ((void *)((unsigned long)(x) + KERNELBASE)) +#define __va_ul(x) (((unsigned long)(x) + KERNELBASE)) +#define __va(x) ((void *)__va_ul(x)) #ifdef CONFIG_DISCONTIGMEM #define page_to_pfn(page) discontigmem_page_to_pfn(page) Index: work/arch/ppc64/kernel/iSeries_setup.c =================================================================== --- work.orig/arch/ppc64/kernel/iSeries_setup.c +++ work/arch/ppc64/kernel/iSeries_setup.c @@ -325,7 +325,7 @@ static void __init iSeries_init_early(vo * a non-zero starting address for it, set it up */ if (naca.xRamDisk) { - initrd_start = (unsigned long)__va(naca.xRamDisk); + initrd_start = __va_ul(naca.xRamDisk); initrd_end = initrd_start + naca.xRamDiskSize * PAGE_SIZE; initrd_below_start_ok = 1; // ramdisk in kernel space ROOT_DEV = Root_RAM0; @@ -667,7 +667,7 @@ static void __init iSeries_bolt_kernel(u hpte_t hpte; for (pa = saddr; pa < eaddr ;pa += PAGE_SIZE) { - unsigned long ea = (unsigned long)__va(pa); + unsigned long ea = __va_ul(pa); unsigned long vsid = get_kernel_vsid(ea); unsigned long va = (vsid << 28) | (pa & 0xfffffff); unsigned long vpn = va >> PAGE_SHIFT; Index: work/arch/ppc64/kernel/pSeries_iommu.c =================================================================== --- work.orig/arch/ppc64/kernel/pSeries_iommu.c +++ work/arch/ppc64/kernel/pSeries_iommu.c @@ -256,7 +256,7 @@ static void iommu_table_setparms(struct return; } - tbl->it_base = (unsigned long)__va(*basep); + tbl->it_base = __va_ul(*basep); memset((void *)tbl->it_base, 0, *sizep); tbl->it_busno = phb->bus->number; Index: work/arch/ppc64/kernel/setup.c =================================================================== --- work.orig/arch/ppc64/kernel/setup.c +++ work/arch/ppc64/kernel/setup.c @@ -540,11 +540,11 @@ static void __init check_for_initrd(void prop = (u64 *)get_property(of_chosen, "linux,initrd-start", NULL); if (prop != NULL) { - initrd_start = (unsigned long)__va(*prop); + initrd_start = __va_ul(*prop); prop = (u64 *)get_property(of_chosen, "linux,initrd-end", NULL); if (prop != NULL) { - initrd_end = (unsigned long)__va(*prop); + initrd_end = __va_ul(*prop); initrd_below_start_ok = 1; } else initrd_start = 0; Index: work/arch/ppc64/oprofile/op_model_power4.c =================================================================== --- work.orig/arch/ppc64/oprofile/op_model_power4.c +++ work/arch/ppc64/oprofile/op_model_power4.c @@ -233,7 +233,7 @@ static unsigned long get_pc(struct pt_re /* Were we in our exception vectors or SLB real mode miss handler? */ if (pc < 0x1000000UL) - return (unsigned long)__va(pc); + return __va_ul(pc); /* Not sure where we were */ if (pc < KERNELBASE) From michael at ellerman.id.au Fri Aug 26 12:53:26 2005 From: michael at ellerman.id.au (Michael Ellerman) Date: Fri, 26 Aug 2005 12:53:26 +1000 (EST) Subject: [PATCH 6/12] ppc64: Add a is_kernel_addr() macro In-Reply-To: <1125024799.128302.675577398916.qpatch@concordia> Message-ID: <20050826025326.D1851680E9@ozlabs.org> There's a bunch of code that compares an address with KERNELBASE to see if it's a "kernel address", ie. >= KERNELBASE. Replace all of them with an is_kernel_addr() macro that does the same thing. This will save us some pain when we change KERNELBASE, and also makes the code more readable IMHO. Signed-off-by: Michael Ellerman --- arch/ppc64/kernel/prom_init.c | 2 +- arch/ppc64/kernel/setup.c | 2 +- arch/ppc64/mm/hash_native.c | 2 +- arch/ppc64/mm/hash_utils.c | 2 +- arch/ppc64/mm/slb.c | 6 +++--- arch/ppc64/mm/stab.c | 6 +++--- arch/ppc64/oprofile/op_model_power4.c | 4 ++-- arch/ppc64/oprofile/op_model_rs64.c | 3 +-- arch/ppc64/xmon/xmon.c | 4 ++-- include/asm-ppc64/page.h | 2 ++ include/asm-ppc64/pgtable.h | 2 +- 11 files changed, 18 insertions(+), 17 deletions(-) Index: work/arch/ppc64/mm/stab.c =================================================================== --- work.orig/arch/ppc64/mm/stab.c +++ work/arch/ppc64/mm/stab.c @@ -122,7 +122,7 @@ static int __ste_allocate(unsigned long unsigned long offset; /* Kernel or user address? */ - if (ea >= KERNELBASE) { + if (is_kernel_addr(ea)) { vsid = get_kernel_vsid(ea); } else { if ((ea >= TASK_SIZE_USER64) || (! mm)) @@ -133,7 +133,7 @@ static int __ste_allocate(unsigned long stab_entry = make_ste(get_paca()->stab_addr, GET_ESID(ea), vsid); - if (ea < KERNELBASE) { + if (!is_kernel_addr(ea)) { offset = __get_cpu_var(stab_cache_ptr); if (offset < NR_STAB_CACHE_ENTRIES) __get_cpu_var(stab_cache[offset++]) = stab_entry; @@ -190,7 +190,7 @@ void switch_stab(struct task_struct *tsk entry++, ste++) { unsigned long ea; ea = ste->esid_data & ESID_MASK; - if (ea < KERNELBASE) { + if (!is_kernel_addr(ea)) { ste->esid_data = 0; } } Index: work/arch/ppc64/kernel/prom_init.c =================================================================== --- work.orig/arch/ppc64/kernel/prom_init.c +++ work/arch/ppc64/kernel/prom_init.c @@ -1868,7 +1868,7 @@ static void __init prom_check_initrd(uns if ( r3 && r4 && r4 != 0xdeadbeef) { u64 val; - RELOC(prom_initrd_start) = (r3 >= KERNELBASE) ? __pa(r3) : r3; + RELOC(prom_initrd_start) = is_kernel_addr(r3) ? __pa(r3) : r3; RELOC(prom_initrd_end) = RELOC(prom_initrd_start) + r4; val = (u64)RELOC(prom_initrd_start); Index: work/arch/ppc64/kernel/setup.c =================================================================== --- work.orig/arch/ppc64/kernel/setup.c +++ work/arch/ppc64/kernel/setup.c @@ -554,7 +554,7 @@ static void __init check_for_initrd(void /* If we were passed an initrd, set the ROOT_DEV properly if the values * look sensible. If not, clear initrd reference. */ - if (initrd_start >= KERNELBASE && initrd_end >= KERNELBASE && + if (is_kernel_addr(initrd_start) && is_kernel_addr(initrd_end) && initrd_end > initrd_start) ROOT_DEV = Root_RAM0; else Index: work/arch/ppc64/mm/hash_native.c =================================================================== --- work.orig/arch/ppc64/mm/hash_native.c +++ work/arch/ppc64/mm/hash_native.c @@ -351,7 +351,7 @@ static void native_flush_hash_range(unsi j = 0; for (i = 0; i < number; i++) { - if (batch->addr[i] < KERNELBASE) + if (!is_kernel_addr(batch->addr[i])) vsid = get_vsid(context, batch->addr[i]); else vsid = get_kernel_vsid(batch->addr[i]); Index: work/arch/ppc64/mm/hash_utils.c =================================================================== --- work.orig/arch/ppc64/mm/hash_utils.c +++ work/arch/ppc64/mm/hash_utils.c @@ -361,7 +361,7 @@ void flush_hash_page(unsigned long conte unsigned long vsid, vpn, va, hash, secondary, slot; unsigned long huge = pte_huge(pte); - if (ea < KERNELBASE) + if (!is_kernel_addr(ea)) vsid = get_vsid(context, ea); else vsid = get_kernel_vsid(ea); Index: work/arch/ppc64/mm/slb.c =================================================================== --- work.orig/arch/ppc64/mm/slb.c +++ work/arch/ppc64/mm/slb.c @@ -111,14 +111,14 @@ void switch_slb(struct task_struct *tsk, else unmapped_base = TASK_UNMAPPED_BASE_USER64; - if (pc >= KERNELBASE) + if (is_kernel_addr(pc)) return; slb_allocate(pc); if (GET_ESID(pc) == GET_ESID(stack)) return; - if (stack >= KERNELBASE) + if (is_kernel_addr(stack)) return; slb_allocate(stack); @@ -126,7 +126,7 @@ void switch_slb(struct task_struct *tsk, || (GET_ESID(stack) == GET_ESID(unmapped_base))) return; - if (unmapped_base >= KERNELBASE) + if (is_kernel_addr(unmapped_base)) return; slb_allocate(unmapped_base); } Index: work/arch/ppc64/oprofile/op_model_power4.c =================================================================== --- work.orig/arch/ppc64/oprofile/op_model_power4.c +++ work/arch/ppc64/oprofile/op_model_power4.c @@ -236,7 +236,7 @@ static unsigned long get_pc(struct pt_re return __va_ul(pc); /* Not sure where we were */ - if (pc < KERNELBASE) + if (!is_kernel_addr(pc)) /* function descriptor madness */ return *((unsigned long *)kernel_unknown_bucket); @@ -248,7 +248,7 @@ static int get_kernel(unsigned long pc) int is_kernel; if (!mmcra_has_sihv) { - is_kernel = (pc >= KERNELBASE); + is_kernel = is_kernel_addr(pc); } else { unsigned long mmcra = mfspr(SPRN_MMCRA); is_kernel = ((mmcra & MMCRA_SIPR) == 0); Index: work/arch/ppc64/xmon/xmon.c =================================================================== --- work.orig/arch/ppc64/xmon/xmon.c +++ work/arch/ppc64/xmon/xmon.c @@ -1044,7 +1044,7 @@ static long check_bp_loc(unsigned long a unsigned int instr; addr &= ~3; - if (addr < KERNELBASE) { + if (!is_kernel_addr(addr)) { printf("Breakpoints may only be placed at kernel addresses\n"); return 0; } @@ -1094,7 +1094,7 @@ bpt_cmds(void) dabr.address = 0; dabr.enabled = 0; if (scanhex(&dabr.address)) { - if (dabr.address < KERNELBASE) { + if (!is_kernel_addr(dabr.address)) { printf(badaddr); break; } Index: work/include/asm-ppc64/page.h =================================================================== --- work.orig/include/asm-ppc64/page.h +++ work/include/asm-ppc64/page.h @@ -223,6 +223,8 @@ extern u64 ppc64_pft_size; /* Log 2 of #define __va_ul(x) (((unsigned long)(x) + KERNELBASE)) #define __va(x) ((void *)__va_ul(x)) +#define is_kernel_addr(x) ((x) >= KERNELBASE) + #ifdef CONFIG_DISCONTIGMEM #define page_to_pfn(page) discontigmem_page_to_pfn(page) #define pfn_to_page(pfn) discontigmem_pfn_to_page(pfn) Index: work/include/asm-ppc64/pgtable.h =================================================================== --- work.orig/include/asm-ppc64/pgtable.h +++ work/include/asm-ppc64/pgtable.h @@ -212,7 +212,7 @@ static inline pte_t pfn_pte(unsigned lon #define pte_pfn(x) ((unsigned long)((pte_val(x) >> PTE_SHIFT))) #define pte_page(x) pfn_to_page(pte_pfn(x)) -#define pmd_set(pmdp, ptep) ({BUG_ON((u64)ptep < KERNELBASE); pmd_val(*(pmdp)) = (unsigned long)(ptep);}) +#define pmd_set(pmdp, ptep) ({BUG_ON(!is_kernel_addr((u64)ptep)); pmd_val(*(pmdp)) = (unsigned long)(ptep);}) #define pmd_none(pmd) (!pmd_val(pmd)) #define pmd_bad(pmd) (pmd_val(pmd) == 0) #define pmd_present(pmd) (pmd_val(pmd) != 0) Index: work/arch/ppc64/oprofile/op_model_rs64.c =================================================================== --- work.orig/arch/ppc64/oprofile/op_model_rs64.c +++ work/arch/ppc64/oprofile/op_model_rs64.c @@ -179,7 +179,6 @@ static void rs64_handle_interrupt(struct int val; int i; unsigned long pc = mfspr(SPRN_SIAR); - int is_kernel = (pc >= KERNELBASE); /* set the PMM bit (see comment below) */ mtmsrd(mfmsr() | MSR_PMM); @@ -188,7 +187,7 @@ static void rs64_handle_interrupt(struct val = ctr_read(i); if (val < 0) { if (ctr[i].enabled) { - oprofile_add_pc(pc, is_kernel, i); + oprofile_add_pc(pc, is_kernel_addr(pc), i); ctr_write(i, reset_value[i]); } else { ctr_write(i, 0); From michael at ellerman.id.au Fri Aug 26 12:53:27 2005 From: michael at ellerman.id.au (Michael Ellerman) Date: Fri, 26 Aug 2005 12:53:27 +1000 (EST) Subject: [PATCH 7/12] ppc64: Add CONFIG_KDUMP_CAPTURE_KERNEL In-Reply-To: <1125024799.128302.675577398916.qpatch@concordia> Message-ID: <20050826025327.E0BD5680F7@ozlabs.org> This patch adds a Kconfig variable, CONFIG_KDUMP_CAPTURE_KERNEL, which configures the built kernel for use as a Kdump capture kernel. Currently "all" this involves is changing the value of KERNELBASE to 32 MB. Signed-off-by: Michael Ellerman --- arch/ppc64/Kconfig | 10 ++++++++++ include/asm-ppc64/page.h | 17 ++++++++++------- 2 files changed, 20 insertions(+), 7 deletions(-) Index: work/include/asm-ppc64/page.h =================================================================== --- work.orig/include/asm-ppc64/page.h +++ work/include/asm-ppc64/page.h @@ -206,15 +206,18 @@ extern u64 ppc64_pft_size; /* Log 2 of #endif -/* This must match the -Ttext linker address */ -/* Note: tophys & tovirt make assumptions about how */ -/* KERNELBASE is defined for performance reasons. */ -/* When KERNELBASE moves, those macros may have */ -/* to change! */ -#define PAGE_OFFSET ASM_CONST(0xC000000000000000) -#define KERNELBASE PAGE_OFFSET +#define PAGE_OFFSET ASM_CONST(0xC000000000000000) #define VMALLOC_OFFSET ASM_CONST(0xD000000000000000) +#ifdef CONFIG_KDUMP_CAPTURE_KERNEL +/* Kdump kernel runs at 32 MB, change at your peril. */ +#define PHYSICAL_START ASM_CONST(0x2000000) +#else +#define PHYSICAL_START ASM_CONST(0x0) +#endif + +#define KERNELBASE (PAGE_OFFSET + PHYSICAL_START) + #define VMALLOC_REGION_ID (VMALLOC_OFFSET >> REGION_SHIFT) #define KERNEL_REGION_ID (KERNELBASE >> REGION_SHIFT) #define USER_REGION_ID (0UL) Index: work/arch/ppc64/Kconfig =================================================================== --- work.orig/arch/ppc64/Kconfig +++ work/arch/ppc64/Kconfig @@ -142,6 +142,16 @@ config PPC_SPLPAR processors, that is, which share physical processors between two or more partitions. +config KDUMP_CAPTURE_KERNEL + bool "kdump capture kernel" + depends on PPC_MULTIPLATFORM && EXPERIMENTAL + help + Build a kernel suitable for use as a kdump capture kernel. + The kernel will be linked at a different address than normal, and + so can only be used for Kdump. + + Don't change this unless you know what you are doing. + config KEXEC bool "kexec system call (EXPERIMENTAL)" depends on PPC_MULTIPLATFORM && EXPERIMENTAL From michael at ellerman.id.au Fri Aug 26 12:53:29 2005 From: michael at ellerman.id.au (Michael Ellerman) Date: Fri, 26 Aug 2005 12:53:29 +1000 (EST) Subject: [PATCH 8/12] ppc64: Seperate usage of KERNELBASE and PAGE_OFFSET In-Reply-To: <1125024799.128302.675577398916.qpatch@concordia> Message-ID: <20050826025329.0D5C9680F7@ozlabs.org> This patch tries to seperate usage of KERNELBASE and PAGE_OFFSET. PAGE_OFFSET == 0xC00..00 and always will. It's the quantity you subtract from a virtual kernel address to get a physical one. KERNELBASE == 0xC00..00 + SOMETHING, where SOMETHING tends to be 0, but might not be. It points to the start of the kernel text + data in virtual memory. Signed-off-by: Michael Ellerman --- arch/ppc64/kernel/entry.S | 4 ++-- arch/ppc64/kernel/head.S | 2 +- arch/ppc64/kernel/machine_kexec.c | 5 ++--- arch/ppc64/kernel/pmac_smp.c | 7 +++---- arch/ppc64/kernel/prom_init.c | 2 +- arch/ppc64/mm/hash_utils.c | 6 +++--- arch/ppc64/mm/slb.c | 4 ++-- arch/ppc64/mm/stab.c | 10 +++++----- include/asm-ppc64/mmu.h | 2 +- include/asm-ppc64/page.h | 6 +++--- include/asm-ppc64/ppc_asm.h | 13 ------------- 11 files changed, 23 insertions(+), 38 deletions(-) Index: work/arch/ppc64/mm/stab.c =================================================================== --- work.orig/arch/ppc64/mm/stab.c +++ work/arch/ppc64/mm/stab.c @@ -40,7 +40,7 @@ static int make_ste(unsigned long stab, unsigned long entry, group, old_esid, castout_entry, i; unsigned int global_entry; struct stab_entry *ste, *castout_ste; - unsigned long kernel_segment = (esid << SID_SHIFT) >= KERNELBASE; + unsigned long kernel_segment = (esid << SID_SHIFT) >= PAGE_OFFSET; vsid_data = vsid << STE_VSID_SHIFT; esid_data = esid << SID_SHIFT | STE_ESID_KP | STE_ESID_V; @@ -83,7 +83,7 @@ static int make_ste(unsigned long stab, } /* Dont cast out the first kernel segment */ - if ((castout_ste->esid_data & ESID_MASK) != KERNELBASE) + if ((castout_ste->esid_data & ESID_MASK) != PAGE_OFFSET) break; castout_entry = (castout_entry + 1) & 0xf; @@ -248,7 +248,7 @@ void stabs_alloc(void) panic("Unable to allocate segment table for CPU %d.\n", cpu); - newstab += KERNELBASE; + newstab = __va_ul(newstab); memset((void *)newstab, 0, PAGE_SIZE); @@ -265,13 +265,13 @@ void stabs_alloc(void) */ void stab_initialize(unsigned long stab) { - unsigned long vsid = get_kernel_vsid(KERNELBASE); + unsigned long vsid = get_kernel_vsid(PAGE_OFFSET); if (cpu_has_feature(CPU_FTR_SLB)) { slb_initialize(); } else { asm volatile("isync; slbia; isync":::"memory"); - make_ste(stab, GET_ESID(KERNELBASE), vsid); + make_ste(stab, GET_ESID(PAGE_OFFSET), vsid); /* Order update */ asm volatile("sync":::"memory"); Index: work/include/asm-ppc64/ppc_asm.h =================================================================== --- work.orig/include/asm-ppc64/ppc_asm.h +++ work/include/asm-ppc64/ppc_asm.h @@ -110,19 +110,6 @@ ori reg,reg,(label)@l; -/* PPPBBB - DRENG If KERNELBASE is always 0xC0..., - * Then we can easily do this with one asm insn. -Peter - */ -#define tophys(rd,rs) \ - lis rd,((KERNELBASE>>48)&0xFFFF); \ - rldicr rd,rd,32,31; \ - sub rd,rs,rd - -#define tovirt(rd,rs) \ - lis rd,((KERNELBASE>>48)&0xFFFF); \ - rldicr rd,rd,32,31; \ - add rd,rs,rd - /* Condition Register Bit Fields */ #define cr0 0 Index: work/arch/ppc64/kernel/machine_kexec.c =================================================================== --- work.orig/arch/ppc64/kernel/machine_kexec.c +++ work/arch/ppc64/kernel/machine_kexec.c @@ -171,9 +171,8 @@ void kexec_copy_flush(struct kimage *ima * including ones that were in place on the original copy */ for (i = 0; i < nr_segments; i++) - flush_icache_range(ranges[i].mem + KERNELBASE, - ranges[i].mem + KERNELBASE + - ranges[i].memsz); + flush_icache_range(__va_ul(ranges[i].mem), + __va_ul(ranges[i].mem + ranges[i].memsz)); } #ifdef CONFIG_SMP Index: work/arch/ppc64/kernel/pmac_smp.c =================================================================== --- work.orig/arch/ppc64/kernel/pmac_smp.c +++ work/arch/ppc64/kernel/pmac_smp.c @@ -240,8 +240,7 @@ static void __init smp_core99_kick_cpu(i int save_vector, j; unsigned long new_vector; unsigned long flags; - volatile unsigned int *vector - = ((volatile unsigned int *)(KERNELBASE+0x100)); + volatile unsigned int *vector = (volatile unsigned int *)__va(0x100); if (nr < 1 || nr > 3) return; @@ -254,7 +253,7 @@ static void __init smp_core99_kick_cpu(i save_vector = *vector; /* Setup fake reset vector that does - * b .pmac_secondary_start - KERNELBASE + * b .pmac_secondary_start_(1|2|3) */ switch(nr) { case 1: @@ -268,7 +267,7 @@ static void __init smp_core99_kick_cpu(i new_vector = (unsigned long)pmac_secondary_start_3; break; } - *vector = 0x48000002 + (new_vector - KERNELBASE); + *vector = 0x48000001 + (new_vector - (unsigned long)vector); /* flush data cache and inval instruction cache */ flush_icache_range((unsigned long) vector, (unsigned long) vector + 4); Index: work/arch/ppc64/kernel/prom_init.c =================================================================== --- work.orig/arch/ppc64/kernel/prom_init.c +++ work/arch/ppc64/kernel/prom_init.c @@ -1940,7 +1940,7 @@ unsigned long __init prom_init(unsigned * On pSeries and BPA, copy the CPU hold code */ if (RELOC(of_platform) & (PLATFORM_PSERIES | PLATFORM_BPA)) - copy_and_flush(0, KERNELBASE - offset, 0x100, 0); + copy_and_flush(__pa(KERNELBASE), KERNELBASE - offset, 0x100, 0); /* * Get memory cells format Index: work/arch/ppc64/mm/hash_utils.c =================================================================== --- work.orig/arch/ppc64/mm/hash_utils.c +++ work/arch/ppc64/mm/hash_utils.c @@ -210,7 +210,7 @@ void __init htab_initialize(void) /* create bolted the linear mapping in the hash table */ for (i=0; i < lmb.memory.cnt; i++) { - base = lmb.memory.region[i].base + KERNELBASE; + base = __va_ul(lmb.memory.region[i].base); size = lmb.memory.region[i].size; DBG("creating mapping for region: %lx : %lx\n", base, size); @@ -247,8 +247,8 @@ void __init htab_initialize(void) * for either 4K or 16MB pages. */ if (tce_alloc_start) { - tce_alloc_start += KERNELBASE; - tce_alloc_end += KERNELBASE; + tce_alloc_start = __va_ul(tce_alloc_start); + tce_alloc_end = __va_ul(tce_alloc_end); if (base + size >= tce_alloc_start) tce_alloc_start = base + size + 1; Index: work/arch/ppc64/mm/slb.c =================================================================== --- work.orig/arch/ppc64/mm/slb.c +++ work/arch/ppc64/mm/slb.c @@ -55,7 +55,7 @@ static void slb_flush_and_rebolt(void) ksp_flags |= SLB_VSID_L; ksp_esid_data = mk_esid_data(get_paca()->kstack, 2); - if ((ksp_esid_data & ESID_MASK) == KERNELBASE) + if ((ksp_esid_data & ESID_MASK) == PAGE_OFFSET) ksp_esid_data &= ~SLB_ESID_V; /* We need to do this all in asm, so we're sure we don't touch @@ -145,7 +145,7 @@ void slb_initialize(void) asm volatile("isync":::"memory"); asm volatile("slbmte %0,%0"::"r" (0) : "memory"); asm volatile("isync; slbia; isync":::"memory"); - create_slbe(KERNELBASE, flags, 0); + create_slbe(PAGE_OFFSET, flags, 0); create_slbe(VMALLOC_OFFSET, SLB_VSID_KERNEL, 1); /* We don't bolt the stack for the time being - we're in boot, * so the stack is in the bolted segment. By the time it goes Index: work/include/asm-ppc64/mmu.h =================================================================== --- work.orig/include/asm-ppc64/mmu.h +++ work/include/asm-ppc64/mmu.h @@ -29,7 +29,7 @@ /* Location of cpu0's segment table */ #define STAB0_PAGE 0x6 -#define STAB0_PHYS_ADDR (STAB0_PAGE<> REGION_SHIFT) -#define KERNEL_REGION_ID (KERNELBASE >> REGION_SHIFT) +#define KERNEL_REGION_ID (PAGE_OFFSET >> REGION_SHIFT) #define USER_REGION_ID (0UL) #define REGION_ID(ea) (((unsigned long)(ea)) >> REGION_SHIFT) -#define __va_ul(x) (((unsigned long)(x) + KERNELBASE)) +#define __va_ul(x) (((unsigned long)(x) + PAGE_OFFSET)) #define __va(x) ((void *)__va_ul(x)) -#define is_kernel_addr(x) ((x) >= KERNELBASE) +#define is_kernel_addr(x) ((x) >= PAGE_OFFSET) #ifdef CONFIG_DISCONTIGMEM #define page_to_pfn(page) discontigmem_page_to_pfn(page) Index: work/arch/ppc64/kernel/head.S =================================================================== --- work.orig/arch/ppc64/kernel/head.S +++ work/arch/ppc64/kernel/head.S @@ -1257,7 +1257,7 @@ unrecov_slb: * fixed address (the linker can't compute (u64)&initial_stab >> * PAGE_SHIFT). */ - . = STAB0_PHYS_ADDR /* 0x6000 */ + . = (STAB0_PAGE << PAGE_SHIFT) /* 0x6000 */ .globl initial_stab initial_stab: .space 4096 Index: work/arch/ppc64/kernel/entry.S =================================================================== --- work.orig/arch/ppc64/kernel/entry.S +++ work/arch/ppc64/kernel/entry.S @@ -668,7 +668,7 @@ _GLOBAL(enter_rtas) /* Setup our real return addr */ SET_REG_TO_LABEL(r4,.rtas_return_loc) - SET_REG_TO_CONST(r9,KERNELBASE) + SET_REG_TO_CONST(r9,PAGE_OFFSET) sub r4,r4,r9 mtlr r4 @@ -696,7 +696,7 @@ _GLOBAL(enter_rtas) _STATIC(rtas_return_loc) /* relocation is off at this point */ mfspr r4,SPRG3 /* Get PACA */ - SET_REG_TO_CONST(r5, KERNELBASE) + SET_REG_TO_CONST(r5, PAGE_OFFSET) sub r4,r4,r5 /* RELOC the PACA base pointer */ mfmsr r6 From michael at ellerman.id.au Fri Aug 26 12:53:29 2005 From: michael at ellerman.id.au (Michael Ellerman) Date: Fri, 26 Aug 2005 12:53:29 +1000 (EST) Subject: [PATCH 9/12] ppc64: Misc fixups for non-zero KERNELBASE In-Reply-To: <1125024799.128302.675577398916.qpatch@concordia> Message-ID: <20050826025329.2883F680F7@ozlabs.org> The code to do startup of secondary cpus assumes it only needs to load the low halfword of the __secondary_hold_* symbols. This won't work if we build the kernel at 32 MB. The interrupt prolog code for pSeries assumes it can get the address of the interrupt handler by just loading the top and bottom halfwords of the address. This doesn't work if the kernel's linked too far above zero. We'd like to use SET_REG_TO_LABEL(), but we're short on space, so we simply augment the existing hack. Signed-off-by: Michael Ellerman --- arch/ppc64/kernel/head.S | 14 +++++++------- 1 files changed, 7 insertions(+), 7 deletions(-) Index: work/arch/ppc64/kernel/head.S =================================================================== --- work.orig/arch/ppc64/kernel/head.S +++ work/arch/ppc64/kernel/head.S @@ -143,13 +143,12 @@ _GLOBAL(__secondary_hold) mr r24,r3 /* Tell the master cpu we're here */ - /* Relocation is off & we are located at an address less */ - /* than 0x100, so only need to grab low order offset. */ - std r24,__secondary_hold_acknowledge at l(0) + LOADADDR(r4, __secondary_hold_acknowledge) + std r24,0(r4) sync /* All secondary cpus wait here until told to start. */ -100: ld r4,__secondary_hold_spinloop at l(0) +100: LOADADDR(r4, __secondary_hold_spinloop) cmpdi 0,r4,1 bne 100b @@ -210,9 +209,10 @@ exception_marker: std r9,area+EX_R13(r13); \ mfcr r9; \ clrrdi r12,r13,32; /* get high part of &label */ \ + oris r12,r12,(label)@h; /* virt addr of handler ... */ \ + ori r12,r12,(label)@l; /* .. and the rest */ \ mfmsr r10; \ mfspr r11,SRR0; /* save SRR0 */ \ - ori r12,r12,(label)@l; /* virt addr of handler */ \ ori r10,r10,MSR_IR|MSR_DR|MSR_RI; \ mtspr SRR0,r12; \ mfspr r12,SRR1; /* and SRR1 */ \ @@ -1446,7 +1446,7 @@ _STATIC(__boot_from_prom) _STATIC(__after_prom_start) /* - * We need to run with __start at physical address 0. + * We need to run with __start at physical address KERNELBASE. * This will leave some code in the first 256B of * real memory, which are reserved for software use. * The remainder of the first page is loaded with the fixed @@ -1459,7 +1459,7 @@ _STATIC(__after_prom_start) */ SET_REG_TO_CONST(r27,KERNELBASE) - li r3,0 /* target addr */ + LOADADDR(r3, PHYSICAL_START) /* target addr */ mr r4,r30 /* source, current addr of __start */ From michael at ellerman.id.au Fri Aug 26 12:53:31 2005 From: michael at ellerman.id.au (Michael Ellerman) Date: Fri, 26 Aug 2005 12:53:31 +1000 (EST) Subject: [PATCH 10/12] ppc64: Reroute interrupts from zero + offset to KERNELBASE + offset In-Reply-To: <1125024799.128302.675577398916.qpatch@concordia> Message-ID: <20050826025331.84994680F7@ozlabs.org> Regardless of where the kernel's linked we always get interrupts at low addresses. This patch creates a trampoline in the first 3 pages of memory, where interrupts land, and patches those addresses to jump into the real kernel code at KERNELBASE. We also need to reserve the low pages of memory in prom.c, as well as __pa(KERNELBASE) to __pa(klimit). FIXME, 0x8000 should be a #define. Signed-off-by: Michael Ellerman --- arch/ppc64/kernel/prom.c | 5 ++++- arch/ppc64/kernel/setup.c | 22 ++++++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) Index: work/arch/ppc64/kernel/setup.c =================================================================== --- work.orig/arch/ppc64/kernel/setup.c +++ work/arch/ppc64/kernel/setup.c @@ -362,6 +362,26 @@ static struct machdep_calls __initdata * NULL }; +#ifdef CONFIG_KDUMP_CAPTURE_KERNEL +static void setup_kdump_trampoline(void) +{ + unsigned long i; + unsigned int *addr; + + /* XXX this only works if PHYSICAL_START <= 32 MB */ + + for (i = 0x100; i < 0x3000; i += 8) { + addr = (unsigned int *)i; + *addr++ = 0x60000000; /* nop */ + *addr = 0x48000000 | ((PHYSICAL_START - 1) & 0x03fffffc); + + asm ("dcbst 0,%0; sync; icbi 0,%0; isync" : : "r" (addr)); + } +} +#else +static inline void setup_kdump_trampoline(void) { } +#endif + /* * Early initialization entry point. This is called by head.S * with MMU translation disabled. We rely on the "feature" of @@ -394,6 +414,8 @@ void __init early_setup(unsigned long dt DBG(" -> early_setup()\n"); + setup_kdump_trampoline(); + /* * Fill the default DBG level (do we want to keep * that old mecanism around forever ?) Index: work/arch/ppc64/kernel/prom.c =================================================================== --- work.orig/arch/ppc64/kernel/prom.c +++ work/arch/ppc64/kernel/prom.c @@ -1241,7 +1241,10 @@ void __init early_init_devtree(void *par lmb_enforce_memory_limit(); lmb_analyze(); systemcfg->physicalMemorySize = lmb_phys_mem_size(); - lmb_reserve(0, __pa(klimit)); + lmb_reserve(__pa(KERNELBASE), __pa(klimit)); +#ifdef CONFIG_KDUMP_CAPTURE_KERNEL + lmb_reserve(0, 0x8000); /* Reserve the trampoline */ +#endif DBG("Phys. mem: %lx\n", systemcfg->physicalMemorySize); From michael at ellerman.id.au Fri Aug 26 12:53:32 2005 From: michael at ellerman.id.au (Michael Ellerman) Date: Fri, 26 Aug 2005 12:53:32 +1000 (EST) Subject: [PATCH 11/12] ppc64: Move fwnmi vectors into trampoline area In-Reply-To: <1125024799.128302.675577398916.qpatch@concordia> Message-ID: <20050826025332.0952F680E9@ozlabs.org> The fwnmi vectors can be anywhere < 32 MB, so we need to use a trampoline for them too. We've got plenty of room below 0x3000, so just plonk them in there and the existing trampoline code will do what we want. If we ever run out of space below 0x3000 we can change the code to patch the fwnmi vectors explictly. Signed-off-by: Michael Ellerman --- arch/ppc64/kernel/head.S | 37 ++++++++++++++++++++----------------- arch/ppc64/kernel/pSeries_setup.c | 14 +++++++++----- 2 files changed, 29 insertions(+), 22 deletions(-) Index: work/arch/ppc64/kernel/head.S =================================================================== --- work.orig/arch/ppc64/kernel/head.S +++ work/arch/ppc64/kernel/head.S @@ -494,6 +494,26 @@ system_call_pSeries: STD_EXCEPTION_PSERIES(0x1300, instruction_breakpoint) STD_EXCEPTION_PSERIES(0x1700, altivec_assist) + /* + * Vectors for the FWNMI option. Share common code. + * For kdump's sake these must be < 0x3000 and 8-byte aligned. + */ + .align 7 + .globl system_reset_fwnmi +system_reset_fwnmi: + HMT_MEDIUM + mtspr SPRG1,r13 /* save r13 */ + RUNLATCH_ON(r13) + EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common) + + .align 7 + .globl machine_check_fwnmi +machine_check_fwnmi: + HMT_MEDIUM + mtspr SPRG1,r13 /* save r13 */ + RUNLATCH_ON(r13) + EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common) + . = 0x3000 /*** pSeries interrupt support ***/ @@ -507,23 +527,6 @@ _GLOBAL(do_stab_bolted_pSeries) mfspr r12,SPRG2 EXCEPTION_PROLOG_PSERIES(PACA_EXSLB, .do_stab_bolted) -/* - * Vectors for the FWNMI option. Share common code. - */ - .globl system_reset_fwnmi -system_reset_fwnmi: - HMT_MEDIUM - mtspr SPRG1,r13 /* save r13 */ - RUNLATCH_ON(r13) - EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common) - - .globl machine_check_fwnmi -machine_check_fwnmi: - HMT_MEDIUM - mtspr SPRG1,r13 /* save r13 */ - RUNLATCH_ON(r13) - EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common) - #ifdef CONFIG_PPC_ISERIES /*** ISeries-LPAR interrupt handlers ***/ Index: work/arch/ppc64/kernel/pSeries_setup.c =================================================================== --- work.orig/arch/ppc64/kernel/pSeries_setup.c +++ work/arch/ppc64/kernel/pSeries_setup.c @@ -108,14 +108,18 @@ void pSeries_get_cpuinfo(struct seq_file */ static void __init fwnmi_init(void) { - int ret; + unsigned long v1, v2; + int ibm_nmi_register = rtas_token("ibm,nmi-register"); if (ibm_nmi_register == RTAS_UNKNOWN_SERVICE) return; - ret = rtas_call(ibm_nmi_register, 2, 1, NULL, - __pa((unsigned long)system_reset_fwnmi), - __pa((unsigned long)machine_check_fwnmi)); - if (ret == 0) + + /* We point the firmware at low addresses, and use a trampoline to + * get up to the real code at KERNELBASE. */ + v1 = (unsigned long)system_reset_fwnmi - KERNELBASE; + v2 = (unsigned long)machine_check_fwnmi - KERNELBASE; + + if (0 == rtas_call(ibm_nmi_register, 2, 1, NULL, v1, v2)) fwnmi_active = 1; } From michael at ellerman.id.au Fri Aug 26 12:53:34 2005 From: michael at ellerman.id.au (Michael Ellerman) Date: Fri, 26 Aug 2005 12:53:34 +1000 (EST) Subject: [PATCH 12/12] ppc64: Hack, make sure zImage wrapper doesn't load kernel at KERNELBASE In-Reply-To: <1125024799.128302.675577398916.qpatch@concordia> Message-ID: <20050826025334.6121D680FF@ozlabs.org> For testing the kernel linked at 32 MB it's handy to be able to netboot it. However the zImage wrapper doesn't have any idea where KERNELBASE is, it just assumes it's 0. This can lead to the zImage wrapper loading the kernel in an area that overlaps KERNELBASE to klimit, which breaks badly. We could do this properly but for the moment just start allocating at 48 MB, which gives us space for an average sized kernel at 32 MB. Signed-off-by: Michael Ellerman --- arch/ppc64/boot/main.c | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: work/arch/ppc64/boot/main.c =================================================================== --- work.orig/arch/ppc64/boot/main.c +++ work/arch/ppc64/boot/main.c @@ -22,7 +22,7 @@ extern void flush_cache(void *, unsigned /* Value picked to match that used by yaboot */ -#define PROG_START 0x01400000 +#define PROG_START 0x03000000 #define RAM_END (256<<20) // Fixme: use OF */ static char *avail_ram; From sfr at canb.auug.org.au Fri Aug 26 17:30:02 2005 From: sfr at canb.auug.org.au (Stephen Rothwell) Date: Fri, 26 Aug 2005 17:30:02 +1000 Subject: [patch 2/2] delete unused file In-Reply-To: <20041225174524.4CDDA1EA0F@trashy.coderock.org> References: <20041225174524.4CDDA1EA0F@trashy.coderock.org> Message-ID: <20050826173002.3f587f55.sfr@canb.auug.org.au> On Sat, 25 Dec 2004 18:45:34 +0100 domen at coderock.org wrote: > > > Remove nowhere referenced file. (egrep "filename\." didn't find anything) > > Signed-off-by: Domen Puncer Ack-by: Stephen Rothwell -- Cheers, Stephen Rothwell sfr at canb.auug.org.au http://www.canb.auug.org.au/~sfr/ -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: not available Url : http://ozlabs.org/pipermail/linuxppc64-dev/attachments/20050826/6a2604c5/attachment.pgp From sfr at canb.auug.org.au Fri Aug 26 17:31:42 2005 From: sfr at canb.auug.org.au (Stephen Rothwell) Date: Fri, 26 Aug 2005 17:31:42 +1000 Subject: [patch 2/2] delete unused file In-Reply-To: <20050826173002.3f587f55.sfr@canb.auug.org.au> References: <20041225174524.4CDDA1EA0F@trashy.coderock.org> <20050826173002.3f587f55.sfr@canb.auug.org.au> Message-ID: <20050826173142.2c59cb09.sfr@canb.auug.org.au> On Fri, 26 Aug 2005 17:30:02 +1000 Stephen Rothwell wrote: Ignore this, MTA strangeness .... :-( -- Cheers, Stephen Rothwell sfr at canb.auug.org.au http://www.canb.auug.org.au/~sfr/ -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: not available Url : http://ozlabs.org/pipermail/linuxppc64-dev/attachments/20050826/fcce545f/attachment.pgp From penberg at cs.helsinki.fi Fri Aug 26 18:17:19 2005 From: penberg at cs.helsinki.fi (Pekka Enberg) Date: Fri, 26 Aug 2005 11:17:19 +0300 Subject: [PATCH 1/7] spufs: The SPU file system In-Reply-To: <200508260003.40865.arnd@arndb.de> References: <200508260003.40865.arnd@arndb.de> Message-ID: <84144f02050826011778e1142@mail.gmail.com> Hi Arnd, > This is a work-in-progress version of the SPU file system. > --- linux-cg.orig/fs/spufs/file.c 1969-12-31 19:00:00.000000000 -0500 > +++ linux-cg/fs/spufs/file.c 2005-08-25 22:27:19.503976592 -0400 > @@ -0,0 +1,716 @@ > +/* > + * SPU file system -- file contents > +/* low-level mailbox write */ > +size_t spu_wbox_write(struct spu *spu, u32 data) > +{ > + int ret; > + > + spin_lock_irq(&spu->register_lock); > + > + if (in_be32(&spu->problem->mb_stat_R) & 0x00ff00) { > + /* we have space to write wbox_data to */ > + out_be32(&spu->problem->spu_mb_W, data); > + ret = 4; > + } else { > + /* make sure we get woken up by the interrupt when space > + becomes available */ > + out_be64(&spu->priv1->int_mask_class2_RW, > + in_be64(&spu->priv1->int_mask_class2_RW) | 0x10); I am confused. The code is architecture specific and does device I/O. Why do you want to put this in fs/ and not drivers/? Pekka From segher at kernel.crashing.org Fri Aug 26 19:23:13 2005 From: segher at kernel.crashing.org (Segher Boessenkool) Date: Fri, 26 Aug 2005 11:23:13 +0200 Subject: [RFC/PATCH] Set up PCI tree from OF on ppc64 In-Reply-To: <17166.19681.434577.137224@cargo.ozlabs.ibm.com> References: <17165.800.617053.891578@cargo.ozlabs.ibm.com> <640514b313694c6083cacd9863058a32@kernel.crashing.org> <17166.19681.434577.137224@cargo.ozlabs.ibm.com> Message-ID: <16dd0b73c06e6278ba5767bdc41d7e26@kernel.crashing.org> > What the hypervisor "should" do is pretty close to irrelevant in this > situation. I basically had the choice of either presenting each of > these special PCI-PCI bridges as a host bridge to the PCI-PCI code, or > constructing the PCI tree from the OF device tree, and the latter > seemed better to me. Yes, I understand. I'm quite happy with just taking whatever Open Firmware tells us (and hope you don't need to put all that many workarounds in _that_ code, heh). The more I think about it the happier I am about it. I guess I got a bit scared by the motivation, that's all. Are you planning to in the future take _all_ configuration space settings from OF properties? That would be a logical next step, have the kernel not try to redo any of the PCI configuration... Segher From sfr at canb.auug.org.au Fri Aug 26 21:40:15 2005 From: sfr at canb.auug.org.au (Stephen Rothwell) Date: Fri, 26 Aug 2005 21:40:15 +1000 Subject: [PATCH 3/12] ppc64: Remove unused reloc_offset code In-Reply-To: <20050826025321.AC23068051@ozlabs.org> References: <1125024799.128302.675577398916.qpatch@concordia> <20050826025321.AC23068051@ozlabs.org> Message-ID: <20050826214015.3c96f10e.sfr@canb.auug.org.au> On Fri, 26 Aug 2005 12:53:21 +1000 (EST) Michael Ellerman wrote: > > This patch changes the calling convention for cpu_setup routines, but currently > none of them actually consult their arguments so no further changes are > needed. except for the prototypes in cputable.c ... -- Cheers, Stephen Rothwell sfr at canb.auug.org.au http://www.canb.auug.org.au/~sfr/ -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: not available Url : http://ozlabs.org/pipermail/linuxppc64-dev/attachments/20050826/a70b287b/attachment.pgp From sfr at canb.auug.org.au Fri Aug 26 21:59:00 2005 From: sfr at canb.auug.org.au (Stephen Rothwell) Date: Fri, 26 Aug 2005 21:59:00 +1000 Subject: [PATCH 3/12] ppc64: Remove unused reloc_offset code In-Reply-To: <20050826214015.3c96f10e.sfr@canb.auug.org.au> References: <1125024799.128302.675577398916.qpatch@concordia> <20050826025321.AC23068051@ozlabs.org> <20050826214015.3c96f10e.sfr@canb.auug.org.au> Message-ID: <20050826215900.4e9a7177.sfr@canb.auug.org.au> On Fri, 26 Aug 2005 21:40:15 +1000 Stephen Rothwell wrote: > > On Fri, 26 Aug 2005 12:53:21 +1000 (EST) Michael Ellerman wrote: > > > > This patch changes the calling convention for cpu_setup routines, but currently > > none of them actually consult their arguments so no further changes are > > needed. > > except for the prototypes in cputable.c ... And, of course, the definition of cpu_set_t in cputable.h -- Cheers, Stephen Rothwell sfr at canb.auug.org.au http://www.canb.auug.org.au/~sfr/ -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: not available Url : http://ozlabs.org/pipermail/linuxppc64-dev/attachments/20050826/dd93bb35/attachment.pgp From sfr at canb.auug.org.au Fri Aug 26 23:39:48 2005 From: sfr at canb.auug.org.au (Stephen Rothwell) Date: Fri, 26 Aug 2005 23:39:48 +1000 Subject: [PATCH 10/12] ppc64: Reroute interrupts from zero + offset to KERNELBASE + offset In-Reply-To: <20050826025331.84994680F7@ozlabs.org> References: <1125024799.128302.675577398916.qpatch@concordia> <20050826025331.84994680F7@ozlabs.org> Message-ID: <20050826233948.00669e3f.sfr@canb.auug.org.au> On Fri, 26 Aug 2005 12:53:31 +1000 (EST) Michael Ellerman wrote: > > +static void setup_kdump_trampoline(void) > +{ > + unsigned long i; > + unsigned int *addr; > + > + /* XXX this only works if PHYSICAL_START <= 32 MB */ > + > + for (i = 0x100; i < 0x3000; i += 8) { > + addr = (unsigned int *)i; > + *addr++ = 0x60000000; /* nop */ This next should really have a comment ... > + *addr = 0x48000000 | ((PHYSICAL_START - 1) & 0x03fffffc); > + > + asm ("dcbst 0,%0; sync; icbi 0,%0; isync" : : "r" (addr)); -- Cheers, Stephen Rothwell sfr at canb.auug.org.au http://www.canb.auug.org.au/~sfr/ -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: not available Url : http://ozlabs.org/pipermail/linuxppc64-dev/attachments/20050826/fa3d9ea3/attachment.pgp From will_schmidt at vnet.ibm.com Fri Aug 26 23:53:59 2005 From: will_schmidt at vnet.ibm.com (will schmidt) Date: Fri, 26 Aug 2005 08:53:59 -0500 Subject: [PATCH 10/12] ppc64: Reroute interrupts from zero + offset to KERNELBASE + offset In-Reply-To: <20050826025331.84994680F7@ozlabs.org> References: <20050826025331.84994680F7@ozlabs.org> Message-ID: <430F1EF7.8080903@vnet.ibm.com> Hi Michael, first question is inline, the other question.. when the KDUMP_CAPTURE_KERNEL is configured, is it only mapped into memory ahead of time, or would functions like this one (setup_kdump_trampoline) be run during normal system start? Michael Ellerman wrote: > Regardless of where the kernel's linked we always get interrupts at low > addresses. This patch creates a trampoline in the first 3 pages of memory, > where interrupts land, and patches those addresses to jump into the real > kernel code at KERNELBASE. > > We also need to reserve the low pages of memory in prom.c, as well as > __pa(KERNELBASE) to __pa(klimit). > > FIXME, 0x8000 should be a #define. > > Signed-off-by: Michael Ellerman > --- > > arch/ppc64/kernel/prom.c | 5 ++++- > arch/ppc64/kernel/setup.c | 22 ++++++++++++++++++++++ > 2 files changed, 26 insertions(+), 1 deletion(-) > > Index: work/arch/ppc64/kernel/setup.c > =================================================================== > --- work.orig/arch/ppc64/kernel/setup.c > +++ work/arch/ppc64/kernel/setup.c > @@ -362,6 +362,26 @@ static struct machdep_calls __initdata * > NULL > }; > > +#ifdef CONFIG_KDUMP_CAPTURE_KERNEL > +static void setup_kdump_trampoline(void) > +{ > + unsigned long i; > + unsigned int *addr; > + > + /* XXX this only works if PHYSICAL_START <= 32 MB */ > + > + for (i = 0x100; i < 0x3000; i += 8) { > + addr = (unsigned int *)i; > + *addr++ = 0x60000000; /* nop */ > + *addr = 0x48000000 | ((PHYSICAL_START - 1) & 0x03fffffc); > + > + asm ("dcbst 0,%0; sync; icbi 0,%0; isync" : : "r" (addr)); > + } So here we're replacing the exception code in the first kernel, with pointers to the exception code in the second, right? once this runs we end up with code something like... c0000000 00000100: 60 00 00 00 nop c0000000 00000108: 48 00 xx xx b (PHYSICAL_START -1) c0000000 00000110: 60 00 00 00 nop c0000000 00000118: 48 00 xx xx b (PHYSICAL_START -1) c0000000 00000120: 60 00 00 00 nop c0000000 00000128: 48 00 xx xx b (PHYSICAL_START -1) ... Is this the intent, or should there be a +i somewhere in the branch instruction too? > +} > +#else > +static inline void setup_kdump_trampoline(void) { } > +#endif > + > /* > * Early initialization entry point. This is called by head.S > * with MMU translation disabled. We rely on the "feature" of > @@ -394,6 +414,8 @@ void __init early_setup(unsigned long dt > > DBG(" -> early_setup()\n"); > > + setup_kdump_trampoline(); > + > /* > * Fill the default DBG level (do we want to keep > * that old mecanism around forever ?) > Index: work/arch/ppc64/kernel/prom.c > =================================================================== > --- work.orig/arch/ppc64/kernel/prom.c > +++ work/arch/ppc64/kernel/prom.c > @@ -1241,7 +1241,10 @@ void __init early_init_devtree(void *par > lmb_enforce_memory_limit(); > lmb_analyze(); > systemcfg->physicalMemorySize = lmb_phys_mem_size(); > - lmb_reserve(0, __pa(klimit)); > + lmb_reserve(__pa(KERNELBASE), __pa(klimit)); > +#ifdef CONFIG_KDUMP_CAPTURE_KERNEL > + lmb_reserve(0, 0x8000); /* Reserve the trampoline */ > +#endif > > DBG("Phys. mem: %lx\n", systemcfg->physicalMemorySize); > > _______________________________________________ > Linuxppc64-dev mailing list > Linuxppc64-dev at ozlabs.org > https://ozlabs.org/mailman/listinfo/linuxppc64-dev From haveblue at us.ibm.com Sat Aug 27 00:23:40 2005 From: haveblue at us.ibm.com (Dave Hansen) Date: Fri, 26 Aug 2005 07:23:40 -0700 Subject: [PATCH] fix SPARSEMEM extreme for ppc64 Message-ID: <20050826142340.1AC9BFE5@kernel.beaverton.ibm.com> From: Joel Schopp From: Arnd Bergmann SPARSEMEM EXTREME uses bootmem allocator, so the memory_present() calls need to happen later. The extra loop in the NUMA code probably needs to go, but that's a cleanup for another day. Applies to 2.6.13-rc6-mm2. Signed-off-by: Dave Hansen --- Re_Lhms-devel_2.6.13-rc3-git7-mhp1-1.patch | 0 memhotplug-dave/arch/ppc64/mm/init.c | 29 ++++++------------- memhotplug-dave/arch/ppc64/mm/numa.c | 43 ++++++++++++++++++++++++++--- memhotplug-dave/include/asm-ppc64/lmb.h | 22 ++++++++++++++ 4 files changed, 72 insertions(+), 22 deletions(-) diff -puN arch/ppc64/mm/init.c~B-sparse-183-ppc64-later-sparse-init arch/ppc64/mm/init.c --- memhotplug/arch/ppc64/mm/init.c~B-sparse-183-ppc64-later-sparse-init 2005-08-24 10:35:40.000000000 -0700 +++ memhotplug-dave/arch/ppc64/mm/init.c 2005-08-24 10:35:40.000000000 -0700 @@ -557,27 +557,18 @@ void __init do_init_bootmem(void) /* Add all physical memory to the bootmem map, mark each area * present. */ - for (i=0; i < lmb.memory.cnt; i++) { - unsigned long physbase, size; - unsigned long start_pfn, end_pfn; - - physbase = lmb.memory.region[i].physbase; - size = lmb.memory.region[i].size; - - start_pfn = physbase >> PAGE_SHIFT; - end_pfn = start_pfn + (size >> PAGE_SHIFT); - memory_present(0, start_pfn, end_pfn); - - free_bootmem(physbase, size); - } + for (i=0; i < lmb.memory.cnt; i++) + free_bootmem(lmb_start_pfn(&lmb.memory, i), + lmb_size_bytes(&lmb.memory, i)); /* reserve the sections we're already using */ - for (i=0; i < lmb.reserved.cnt; i++) { - unsigned long physbase = lmb.reserved.region[i].physbase; - unsigned long size = lmb.reserved.region[i].size; - - reserve_bootmem(physbase, size); - } + for (i=0; i < lmb.reserved.cnt; i++) + reserve_bootmem(lmb_start_pfn(&lmb.reserved, i), + lmb_size_bytes(&lmb.reserved, i)); + + for (i=0; i < lmb.memory.cnt; i++) + memory_present(0, lmb_start_pfn(&lmb.memory, i), + lmb_end_pfn(&lmb.memory, i)); } /* diff -puN include/asm-ppc64/lmb.h~B-sparse-183-ppc64-later-sparse-init include/asm-ppc64/lmb.h --- memhotplug/include/asm-ppc64/lmb.h~B-sparse-183-ppc64-later-sparse-init 2005-08-24 10:35:40.000000000 -0700 +++ memhotplug-dave/include/asm-ppc64/lmb.h 2005-08-24 10:35:40.000000000 -0700 @@ -57,4 +57,26 @@ extern void lmb_dump_all(void); extern unsigned long io_hole_start; +static inline unsigned long +lmb_size_bytes(struct lmb_region *type, unsigned long region_nr) +{ + return type->region[region_nr].size; +} +static inline unsigned long +lmb_size_pages(struct lmb_region *type, unsigned long region_nr) +{ + return lmb_size_bytes(type, region_nr) >> PAGE_SHIFT; +} +static inline unsigned long +lmb_start_pfn(struct lmb_region *type, unsigned long region_nr) +{ + return type->region[region_nr].physbase >> PAGE_SHIFT; +} +static inline unsigned long +lmb_end_pfn(struct lmb_region *type, unsigned long region_nr) +{ + return lmb_start_pfn(type, region_nr) + + lmb_size_pages(type, region_nr); +} + #endif /* _PPC64_LMB_H */ diff -puN arch/ppc64/mm/numa.c~B-sparse-183-ppc64-later-sparse-init arch/ppc64/mm/numa.c --- memhotplug/arch/ppc64/mm/numa.c~B-sparse-183-ppc64-later-sparse-init 2005-08-24 10:35:40.000000000 -0700 +++ memhotplug-dave/arch/ppc64/mm/numa.c 2005-08-24 10:35:40.000000000 -0700 @@ -440,8 +440,6 @@ new_range: for (i = start ; i < (start+size); i += MEMORY_INCREMENT) numa_memory_lookup_table[i >> MEMORY_INCREMENT_SHIFT] = numa_domain; - memory_present(numa_domain, start >> PAGE_SHIFT, - (start + size) >> PAGE_SHIFT); if (--ranges) goto new_range; @@ -483,7 +481,6 @@ static void __init setup_nonnuma(void) for (i = 0 ; i < top_of_ram; i += MEMORY_INCREMENT) numa_memory_lookup_table[i >> MEMORY_INCREMENT_SHIFT] = 0; - memory_present(0, 0, init_node_data[0].node_end_pfn); } static void __init dump_numa_topology(void) @@ -695,6 +692,46 @@ new_range: size); } } + /* + * This loop may look famaliar, but we have to do it again + * after marking our reserved memory to mark memory present + * for sparsemem. + */ + addr_cells = get_mem_addr_cells(); + size_cells = get_mem_size_cells(); + memory = NULL; + while ((memory = of_find_node_by_type(memory, "memory")) != NULL) { + unsigned long mem_start, mem_size; + int numa_domain, ranges; + unsigned int *memcell_buf; + unsigned int len; + + memcell_buf = (unsigned int *)get_property(memory, "reg", &len); + if (!memcell_buf || len <= 0) + continue; + + ranges = memory->n_addrs; /* ranges in cell */ +new_range2: + mem_start = read_n_cells(addr_cells, &memcell_buf); + mem_size = read_n_cells(size_cells, &memcell_buf); + if (numa_enabled) { + numa_domain = of_node_numa_domain(memory); + if (numa_domain >= MAX_NUMNODES) + numa_domain = 0; + } else + numa_domain = 0; + + if (numa_domain != nid) + continue; + + mem_size = numa_enforce_memory_limit(mem_start, mem_size); + memory_present(numa_domain, mem_start >> PAGE_SHIFT, + (mem_start + mem_size) >> PAGE_SHIFT); + + if (--ranges) /* process all ranges in cell */ + goto new_range2; + } + } } diff -puN arch/ppc64/kernel/setup.c~B-sparse-183-ppc64-later-sparse-init arch/ppc64/kernel/setup.c diff -puN Re_Lhms-devel_2.6.13-rc3-git7-mhp1-1.patch~B-sparse-183-ppc64-later-sparse-init Re_Lhms-devel_2.6.13-rc3-git7-mhp1-1.patch _ From kumar.gala at freescale.com Sat Aug 27 05:00:43 2005 From: kumar.gala at freescale.com (Kumar Gala) Date: Fri, 26 Aug 2005 14:00:43 -0500 Subject: [PATCH] ppc64: Add CONFIG_HZ In-Reply-To: <20050823225303.GF31949@krispykreme> References: <20050823225303.GF31949@krispykreme> Message-ID: <0192F2FD-0132-4B51-9524-590084E3FB0B@freescale.com> Any reason we shouldn't do the same thing on ppc32? - kumar On Aug 23, 2005, at 5:53 PM, Anton Blanchard wrote: > > Hi, > > While ppc64 has the CONFIG_HZ Kconfig option, it wasnt actually being > used. Connect it up and set all platforms to 250Hz. > > Signed-off-by: Anton Blanchard > > Index: build/include/asm-ppc64/param.h > =================================================================== > --- build.orig/include/asm-ppc64/param.h 2005-08-15 > 23:42:07.000000000 +1000 > +++ build/include/asm-ppc64/param.h 2005-08-24 08:02:29.000000000 > +1000 > @@ -1,6 +1,8 @@ > #ifndef _ASM_PPC64_PARAM_H > #define _ASM_PPC64_PARAM_H > > +#include > + > /* > * This program is free software; you can redistribute it and/or > * modify it under the terms of the GNU General Public License > @@ -9,7 +11,7 @@ > */ > > #ifdef __KERNEL__ > -# define HZ 1000 /* Internal kernel timer > frequency */ > +# define HZ CONFIG_HZ /* Internal kernel timer > frequency */ > # define USER_HZ 100 /* .. some user interfaces are > in "ticks" */ > # define CLOCKS_PER_SEC (USER_HZ) /* like times() */ > #endif > Index: build/arch/ppc64/configs/g5_defconfig > =================================================================== > --- build.orig/arch/ppc64/configs/g5_defconfig 2005-08-15 > 23:42:04.000000000 +1000 > +++ build/arch/ppc64/configs/g5_defconfig 2005-08-24 > 07:55:50.000000000 +1000 > @@ -103,10 +103,10 @@ > # CONFIG_PREEMPT_VOLUNTARY is not set > # CONFIG_PREEMPT is not set > # CONFIG_PREEMPT_BKL is not set > -CONFIG_HZ_100=y > -# CONFIG_HZ_250 is not set > +# CONFIG_HZ_100 is not set > +CONFIG_HZ_250=y > # CONFIG_HZ_1000 is not set > -CONFIG_HZ=100 > +CONFIG_HZ=250 > CONFIG_GENERIC_HARDIRQS=y > CONFIG_SECCOMP=y > CONFIG_ISA_DMA_API=y > Index: build/arch/ppc64/configs/iSeries_defconfig > =================================================================== > --- build.orig/arch/ppc64/configs/iSeries_defconfig 2005-08-15 > 23:42:04.000000000 +1000 > +++ build/arch/ppc64/configs/iSeries_defconfig 2005-08-24 > 07:56:46.000000000 +1000 > @@ -94,10 +94,10 @@ > # CONFIG_PREEMPT_VOLUNTARY is not set > # CONFIG_PREEMPT is not set > # CONFIG_PREEMPT_BKL is not set > -CONFIG_HZ_100=y > -# CONFIG_HZ_250 is not set > +# CONFIG_HZ_100 is not set > +CONFIG_HZ_250=y > # CONFIG_HZ_1000 is not set > -CONFIG_HZ=100 > +CONFIG_HZ=250 > CONFIG_GENERIC_HARDIRQS=y > CONFIG_MSCHUNKS=y > CONFIG_LPARCFG=y > Index: build/arch/ppc64/configs/maple_defconfig > =================================================================== > --- build.orig/arch/ppc64/configs/maple_defconfig 2005-08-15 > 23:42:04.000000000 +1000 > +++ build/arch/ppc64/configs/maple_defconfig 2005-08-24 > 08:46:58.000000000 +1000 > @@ -103,10 +103,10 @@ > # CONFIG_PREEMPT_VOLUNTARY is not set > # CONFIG_PREEMPT is not set > # CONFIG_PREEMPT_BKL is not set > -CONFIG_HZ_100=y > -# CONFIG_HZ_250 is not set > +# CONFIG_HZ_100 is not set > +CONFIG_HZ_250=y > # CONFIG_HZ_1000 is not set > -CONFIG_HZ=100 > +CONFIG_HZ=250 > CONFIG_GENERIC_HARDIRQS=y > CONFIG_SECCOMP=y > CONFIG_ISA_DMA_API=y > Index: build/arch/ppc64/configs/pSeries_defconfig > =================================================================== > --- build.orig/arch/ppc64/configs/pSeries_defconfig 2005-08-15 > 23:42:04.000000000 +1000 > +++ build/arch/ppc64/configs/pSeries_defconfig 2005-08-24 > 07:58:38.000000000 +1000 > @@ -112,10 +112,10 @@ > # CONFIG_PREEMPT_VOLUNTARY is not set > # CONFIG_PREEMPT is not set > # CONFIG_PREEMPT_BKL is not set > -CONFIG_HZ_100=y > -# CONFIG_HZ_250 is not set > +# CONFIG_HZ_100 is not set > +CONFIG_HZ_250=y > # CONFIG_HZ_1000 is not set > -CONFIG_HZ=100 > +CONFIG_HZ=250 > CONFIG_EEH=y > CONFIG_GENERIC_HARDIRQS=y > CONFIG_PPC_RTAS=y > Index: build/arch/ppc64/defconfig > =================================================================== > --- build.orig/arch/ppc64/defconfig 2005-08-15 23:42:04.000000000 > +1000 > +++ build/arch/ppc64/defconfig 2005-08-24 07:55:27.000000000 +1000 > @@ -114,10 +114,10 @@ > # CONFIG_PREEMPT_VOLUNTARY is not set > # CONFIG_PREEMPT is not set > # CONFIG_PREEMPT_BKL is not set > -CONFIG_HZ_100=y > -# CONFIG_HZ_250 is not set > +# CONFIG_HZ_100 is not set > +CONFIG_HZ_250=y > # CONFIG_HZ_1000 is not set > -CONFIG_HZ=100 > +CONFIG_HZ=250 > CONFIG_EEH=y > CONFIG_GENERIC_HARDIRQS=y > CONFIG_PPC_RTAS=y > _______________________________________________ > Linuxppc64-dev mailing list > Linuxppc64-dev at ozlabs.org > https://ozlabs.org/mailman/listinfo/linuxppc64-dev > From olof at lixom.net Sat Aug 27 05:04:03 2005 From: olof at lixom.net (Olof Johansson) Date: Fri, 26 Aug 2005 14:04:03 -0500 Subject: [PATCH] ppc64: Add CONFIG_HZ In-Reply-To: <0192F2FD-0132-4B51-9524-590084E3FB0B@freescale.com> References: <20050823225303.GF31949@krispykreme> <0192F2FD-0132-4B51-9524-590084E3FB0B@freescale.com> Message-ID: <20050826190403.GA6265@austin.ibm.com> On Fri, Aug 26, 2005 at 02:00:43PM -0500, Kumar Gala wrote: > Any reason we shouldn't do the same thing on ppc32? When I built a 2.6.13-rc7 I got the question about what HZ I wanted, so I guess we're already doing it. Maybe the default needs changing though, can't remember what it was. -Olof From kumar.gala at freescale.com Sat Aug 27 05:07:37 2005 From: kumar.gala at freescale.com (Kumar Gala) Date: Fri, 26 Aug 2005 14:07:37 -0500 Subject: [PATCH] ppc64: Add CONFIG_HZ In-Reply-To: <20050826190403.GA6265@austin.ibm.com> References: <20050826190403.GA6265@austin.ibm.com> Message-ID: <28F4C8E9-FF41-4954-977D-546732D561B8@freescale.com> What were you building for? I'm wondering if the same issue exists that you are asked, but its not wired to actually do anything. - kumar On Aug 26, 2005, at 2:04 PM, Olof Johansson wrote: > On Fri, Aug 26, 2005 at 02:00:43PM -0500, Kumar Gala wrote: > >> Any reason we shouldn't do the same thing on ppc32? >> > > When I built a 2.6.13-rc7 I got the question about what HZ I wanted, > so I guess we're already doing it. Maybe the default needs changing > though, can't remember what it was. > > > -Olof > From olof at lixom.net Sat Aug 27 05:14:50 2005 From: olof at lixom.net (Olof Johansson) Date: Fri, 26 Aug 2005 14:14:50 -0500 Subject: [PATCH] ppc64: Add CONFIG_HZ In-Reply-To: <28F4C8E9-FF41-4954-977D-546732D561B8@freescale.com> References: <20050826190403.GA6265@austin.ibm.com> <28F4C8E9-FF41-4954-977D-546732D561B8@freescale.com> Message-ID: <20050826191450.GB6265@austin.ibm.com> On Fri, Aug 26, 2005 at 02:07:37PM -0500, Kumar Gala wrote: > What were you building for? I'm wondering if the same issue exists > that you are asked, but its not wired to actually do anything. Doh, you're right. No, it's not wired up. I was building for pmac. -Olof From kumar.gala at freescale.com Sat Aug 27 05:23:43 2005 From: kumar.gala at freescale.com (Kumar Gala) Date: Fri, 26 Aug 2005 14:23:43 -0500 Subject: [PATCH] ppc64: Add CONFIG_HZ In-Reply-To: <20050826191450.GB6265@austin.ibm.com> References: <20050826191450.GB6265@austin.ibm.com> Message-ID: <31AB6D4D-58E8-4BB6-9191-2C0710397D69@freescale.com> On Aug 26, 2005, at 2:14 PM, Olof Johansson wrote: > On Fri, Aug 26, 2005 at 02:07:37PM -0500, Kumar Gala wrote: > >> What were you building for? I'm wondering if the same issue exists >> that you are asked, but its not wired to actually do anything. >> > > Doh, you're right. No, it's not wired up. I was building for pmac. Ok, sent a patch to linuxppc-dev for ppc32 which mimic's Anton's patch. Once we get an include/asm-powerpc going we can merge these into on file that lives there. - kumar From jdl at freescale.com Sat Aug 27 06:55:11 2005 From: jdl at freescale.com (Jon Loeliger) Date: Fri, 26 Aug 2005 15:55:11 -0500 Subject: [PATCH] 1/2 Start header file merger (Was: Re: Beginning Merger Patch) In-Reply-To: <20050806005941.5d1fe432.sfr@canb.auug.org.au> References: <1123023575.2614.25.camel@cashmere.sps.mot.com> <688ba2276de281a9473b030a16a514c0@embeddededge.com> <20050805174705.731ffa05.sfr@canb.auug.org.au> <200508051353.23750.arnd@arndb.de> <20050806005941.5d1fe432.sfr@canb.auug.org.au> Message-ID: <1125089709.32488.35.camel@cashmere.sps.mot.com> On Fri, 2005-08-05 at 09:59, Stephen Rothwell wrote: > > Another interesting point about it is which define to use. For s390, we > > decided to '#ifdef __s390x__' rather than '#ifdef CONFIG_ARCH_S390X' or > > 'ifdef CONFIG_64BIT', because CONFIG_* does not work when including the > > headers from user space. > > Well noone should even include kernel headers from user space :-) and my > understanding is that glibc "sanitizes" its version of the kernel headers > anyway. > > > Using CONFIG_64BIT instead of __powerpc64__ only within #ifdef __KERNEL__ > > would be correct but less consistant. > > The advantage of using CONFIG_64BIT as much as possible is that it shows > us places that can be consolidated across the various architectures > (which is a bit of a passion of mine :-)). And more consolidation should > make life easier for the glibc folks in the long run. Hi guys, Well, the time has come when I need an answer to this question in order to make more progress on merging some include files. Anyone care to take a semi-authoritative stand on what symbol to use to distinguish 32/64-bit-ness in the include files? Thanks, jdl From miltonm at bga.com Sun Aug 28 14:55:08 2005 From: miltonm at bga.com (Milton Miller) Date: Sat, 27 Aug 2005 23:55:08 -0500 (CDT) Subject: CONFIG_FRAME_POINTER on ppc/ppc64? In-Reply-To: <200508160403.j7G43Hd29692@makai.watson.ibm.com> Message-ID: <200508280455.j7S4t8Vt023949@sullivan.realtime.net> Paulus wrote: > The reason for having the kernel config option is that it is > impossible to get reliable stack traces on x86 without frame pointers. > On PPC, because the stack frames are always linked together, even if > you don't use a frame pointer, the frame pointer doesn't help in > getting stack traces. Thus there is no point in having the kernel > config option. In addition, it forces stack frames on leaf functions, which results in more code for no gain. milton From arnd at arndb.de Mon Aug 29 02:44:17 2005 From: arnd at arndb.de (Arnd Bergmann) Date: Sun, 28 Aug 2005 18:44:17 +0200 Subject: [PATCH 1/7] spufs: The SPU file system In-Reply-To: <84144f02050826011778e1142@mail.gmail.com> References: <200508260003.40865.arnd@arndb.de> <84144f02050826011778e1142@mail.gmail.com> Message-ID: <200508281844.18187.arnd@arndb.de> On Freedag 26 August 2005 10:17, Pekka Enberg wrote: > I am confused. The code is architecture specific and does device I/O. Why do > you want to put this in fs/ and not drivers/? I never really thought of it as a device driver but rather an architecture extension, so it started out in arch/ppc64/kernel. Since most of the code is interacting with VFS, it is now in fs/spufs. I don't really care about the location, but I among the possible places to put the code (with the unified arch/powerpc tree), I'd suggest (best first) 1) arch/powerpc/platforms/cell 2) arch/powerpc/spe 3) fs/spufs 4) drivers/spe 1) would be the place where I want to have the low-level code (currently arch/ppc64/kernel/spu_base.c) anyway, so it makes sense to have everything in there that I maintain. 2) might work better if we at a later point have multiple platform types in arch/powerpc that use SPEs, e.g if we want to keep Playstation code separate from generic Cell. Arnd <>< From penberg at cs.helsinki.fi Mon Aug 29 06:05:27 2005 From: penberg at cs.helsinki.fi (Pekka Enberg) Date: Sun, 28 Aug 2005 23:05:27 +0300 Subject: [PATCH 1/7] spufs: The SPU file system In-Reply-To: <200508281844.18187.arnd@arndb.de> References: <200508260003.40865.arnd@arndb.de> <84144f02050826011778e1142@mail.gmail.com> <200508281844.18187.arnd@arndb.de> Message-ID: <1125259528.3007.4.camel@localhost> On Sun, 2005-08-28 at 18:44 +0200, Arnd Bergmann wrote: > I never really thought of it as a device driver but rather an architecture > extension, so it started out in arch/ppc64/kernel. Since most of the code > is interacting with VFS, it is now in fs/spufs. I don't really care about > the location, but I among the possible places to put the code (with the > unified arch/powerpc tree), I'd suggest (best first) > > 1) arch/powerpc/platforms/cell > 2) arch/powerpc/spe > 3) fs/spufs > 4) drivers/spe > > 1) would be the place where I want to have the low-level code > (currently arch/ppc64/kernel/spu_base.c) anyway, so it makes > sense to have everything in there that I maintain. I am happy with 1, 2, and 4. You could, of course, abstract away the general purpose parts of spufs (for example, if we had other similar architecture extensions that could share the code) and put them in 3 but that would probably just introduce unnecessary complexity. Pekka From paulus at samba.org Mon Aug 29 11:28:43 2005 From: paulus at samba.org (Paul Mackerras) Date: Mon, 29 Aug 2005 11:28:43 +1000 Subject: please pull ppc64-2.6.git Message-ID: <17170.25803.413408.44080@cargo.ozlabs.ibm.com> Linus, Please do a pull from: rsync://rsync.kernel.org/pub/scm/linux/kernel/git/paulus/ppc64-2.6.git to get a bunch of ppc64 updates. Diffstat and log follow. Paul. arch/ppc/boot/utils/addRamDisk.c | 203 ------------- arch/ppc64/Kconfig | 74 ++--- arch/ppc64/boot/Makefile | 4 arch/ppc64/boot/addnote.c | 4 arch/ppc64/boot/crt0.S | 2 arch/ppc64/boot/div64.S | 2 arch/ppc64/boot/elf.h | 149 ++++++++++ arch/ppc64/boot/main.c | 55 +-- arch/ppc64/boot/page.h | 34 ++ arch/ppc64/boot/ppc32-types.h | 36 -- arch/ppc64/boot/ppc_asm.h | 62 ++++ arch/ppc64/boot/prom.c | 196 +------------ arch/ppc64/boot/prom.h | 18 + arch/ppc64/boot/stdio.h | 16 + arch/ppc64/boot/string.S | 2 arch/ppc64/boot/string.h | 16 + arch/ppc64/boot/zlib.c | 2 arch/ppc64/configs/iSeries_defconfig | 1 arch/ppc64/kernel/LparData.c | 37 -- arch/ppc64/kernel/Makefile | 7 arch/ppc64/kernel/asm-offsets.c | 3 arch/ppc64/kernel/cputable.c | 40 -- arch/ppc64/kernel/firmware.c | 47 +++ arch/ppc64/kernel/head.S | 509 +++++++++++++---------------------- arch/ppc64/kernel/iSeries_htab.c | 5 arch/ppc64/kernel/iSeries_setup.c | 30 +- arch/ppc64/kernel/iSeries_vio.c | 144 +++++++++ arch/ppc64/kernel/lmb.c | 153 ++-------- arch/ppc64/kernel/lparcfg.c | 6 arch/ppc64/kernel/misc.S | 98 ++++++ arch/ppc64/kernel/pSeries_iommu.c | 3 arch/ppc64/kernel/pSeries_lpar.c | 4 arch/ppc64/kernel/pSeries_setup.c | 39 +- arch/ppc64/kernel/pSeries_smp.c | 3 arch/ppc64/kernel/pSeries_vio.c | 266 ++++++++++++++++++ arch/ppc64/kernel/pacaData.c | 4 arch/ppc64/kernel/pmac_setup.c | 2 arch/ppc64/kernel/pmc.c | 21 + arch/ppc64/kernel/process.c | 12 arch/ppc64/kernel/prom.c | 184 ++++++++++-- arch/ppc64/kernel/prom_init.c | 88 +++--- arch/ppc64/kernel/rtas_pci.c | 19 + arch/ppc64/kernel/setup.c | 28 + arch/ppc64/kernel/sysfs.c | 57 --- arch/ppc64/kernel/time.c | 7 arch/ppc64/kernel/vio.c | 407 +-------------------------- arch/ppc64/mm/hash_native.c | 3 arch/ppc64/mm/hash_utils.c | 4 arch/ppc64/mm/hugetlbpage.c | 386 ++++++++++++++------------ arch/ppc64/mm/imalloc.c | 2 arch/ppc64/mm/init.c | 96 +++--- arch/ppc64/mm/numa.c | 2 arch/ppc64/mm/slb_low.S | 25 - arch/ppc64/mm/tlb.c | 95 +++--- arch/ppc64/xmon/start.c | 2 arch/ppc64/xmon/xmon.c | 26 + include/asm-ppc64/abs_addr.h | 86 +---- include/asm-ppc64/cputable.h | 47 --- include/asm-ppc64/firmware.h | 101 ++++++ include/asm-ppc64/imalloc.h | 2 include/asm-ppc64/iommu.h | 3 include/asm-ppc64/lmb.h | 1 include/asm-ppc64/machdep.h | 3 include/asm-ppc64/mmu.h | 16 - include/asm-ppc64/naca.h | 7 include/asm-ppc64/page.h | 55 ++- include/asm-ppc64/pgalloc.h | 93 ++++-- include/asm-ppc64/pgtable.h | 90 +++--- include/asm-ppc64/pmc.h | 2 include/asm-ppc64/processor.h | 4 include/asm-ppc64/prom.h | 14 include/asm-ppc64/system.h | 4 include/asm-ppc64/vio.h | 10 73 files changed, 2231 insertions(+), 2047 deletions(-) commit c594adad5653491813959277fb87a2fef54c4e05 Author: David Gibson Date: Thu Aug 11 16:55:21 2005 +1000 [PATCH] Dynamic hugepage addresses for ppc64 Paulus, I think this is now a reasonable candidate for the post-2.6.13 queue. Relax address restrictions for hugepages on ppc64 Presently, 64-bit applications on ppc64 may only use hugepages in the address region from 1-1.5T. Furthermore, if hugepages are enabled in the kernel config, they may only use hugepages and never normal pages in this area. This patch relaxes this restriction, allowing any address to be used with hugepages, but with a 1TB granularity. That is if you map a hugepage anywhere in the region 1TB-2TB, that entire area will be reserved exclusively for hugepages for the remainder of the process's lifetime. This works analagously to hugepages in 32-bit applications, where hugepages can be mapped anywhere, but with 256MB (mmu segment) granularity. This patch applies on top of the four level pagetable patch (http://patchwork.ozlabs.org/linuxppc64/patch?id=1936). Signed-off-by: David Gibson Signed-off-by: Paul Mackerras commit 9a5573e378c5c8976c6000a7643b52e2a0481688 Author: Michael Ellerman Date: Tue Aug 9 15:20:20 2005 +1000 [PATCH] ppc64: Check of_chosen in check_for_initrd() You can't call get_property() on a NULL node, so check if of_chosen is set in check_for_initrd(). Signed-off-by: Michael Ellerman arch/ppc64/kernel/setup.c | 20 ++++++++++++-------- 1 files changed, 12 insertions(+), 8 deletions(-) Signed-off-by: Paul Mackerras commit 95920324f51b3a12603cf6d9bacbd831f34c5b60 Author: Michael Ellerman Date: Tue Aug 9 15:20:19 2005 +1000 [PATCH] ppc64: unflatten_device_tree() should check if lmb_alloc() fails unflatten_device_tree() doesn't check if lmb_alloc() succeeds or not, it should. All it can do is panic, but at least there's an error message (assuming you have some sort of console at that point). Signed-off-by: Michael Ellerman arch/ppc64/kernel/prom.c | 9 +++++++-- 1 files changed, 7 insertions(+), 2 deletions(-) Signed-off-by: Paul Mackerras commit 145ec7d51ae507c7cc8889ad05e24af05bbd9147 Author: Michael Ellerman Date: Tue Aug 9 15:20:18 2005 +1000 [PATCH] ppc64: Fix a misleading printk in unflatten_dt_node() When unflatten_dt_node() fails to find an OF_DT_END_NODE tag it prints "Weird tag at start of node", this should be "Weird tag at end of node". Signed-off-by: Michael Ellerman arch/ppc64/kernel/prom.c | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Signed-off-by: Paul Mackerras commit 180a33627d958d5d9d3602dde6ac74b315e136f0 Author: Michael Ellerman Date: Tue Aug 9 11:13:36 2005 +1000 [PATCH] ppc64: Move ppc64_enable_pmcs() logic into a ppc_md function This patch moves power4_enable_pmcs() to arch/ppc64/kernel/pmc.c. I've tested it on P5 LPAR and P4. It does what it used to. Signed-off-by: Michael Ellerman Signed-off-by: Paul Mackerras commit b13cfd173f73c3f6f9a307b7b6e64d45fbd756b2 Author: Olaf Hering Date: Thu Aug 4 19:26:42 2005 +0200 [PATCH] ppc64: allow xmon=off If both CONFIG_XMON and CONFIG_XMON_DEFAULT is enabled in the .config, there is no way to disable xmon again. setup_system calls first xmon_init, later parse_early_param. So a new 'xmon=off' cmdline option will do the right thing. Signed-off-by: Olaf Hering Signed-off-by: Paul Mackerras commit bef5686229810709091fb6e505071f4aa41e3760 Author: Michael Ellerman Date: Wed Aug 3 20:21:26 2005 +1000 [PATCH] ppc64: Remove CONFIG_MSCHUNKS We can now remove CONFIG_MSCHUNKS as it doesn't do anything interesting anymore. The only macro in abs_addr.h which is called by non-iSeries code is phys_to_abs(), so remove the other dummy implementations, and we add a firmware feature check to phys_to_abs(). Signed-off-by: Michael Ellerman Signed-off-by: Paul Mackerras commit 71e1f55ad4bc4c8bcfe696400a950a34263a750e Author: Michael Ellerman Date: Wed Aug 3 20:21:26 2005 +1000 [PATCH] ppc64: Simplify some lmb functions lmb_phys_mem_size() can always return lmb.memory.size, as long as it's called after lmb_analyze(), which it is. There's no need to recalculate the size on every call. lmb_analyze() was calculating a few things we then threw away, so just don't calculate them to start with. Signed-off-by: Michael Ellerman Signed-off-by: Paul Mackerras commit 180379dcefb39e8bd05d562b0685e9084dffcc0a Author: Michael Ellerman Date: Wed Aug 3 20:21:26 2005 +1000 [PATCH] ppc64: Remove physbase from the lmb_property struct We no longer need the lmb code to know about abs and phys addresses, so remove the physbase variable from the lmb_property struct. Signed-off-by: Michael Ellerman Signed-off-by: Paul Mackerras commit e88bcd1b29f63738b702e57d831758706162347e Author: Michael Ellerman Date: Wed Aug 3 20:21:25 2005 +1000 [PATCH] ppc64: Remove redundant abs_to_phys() macro abs_to_phys() is a macro that turns out to do nothing, and also has the unfortunate property that it's not the inverse of phys_to_abs() on iSeries. The following is for my benefit as much as everyone else. With CONFIG_MSCHUNKS enabled, the lmb code is changed such that it keeps a physbase variable for each lmb region. This is used to take the possibly discontiguous lmb regions and present them as a contiguous address space beginning from zero. In this context each lmb region's base address is its "absolute" base address, and its physbase is it's "physical" address (from Linux's point of view). The abs_to_phys() macro does the mapping from "absolute" to "physical". Note: This is not related to the iSeries mapping of physical to absolute (ie. Hypervisor) addresses which is maintained with the msChunks structure. And the msChunks structure is not controlled via CONFIG_MSCHUNKS. Once upon a time you could compile for non-iSeries with CONFIG_MSCHUNKS enabled. But these days CONFIG_MSCHUNKS depends on CONFIG_PPC_ISERIES, so for non-iSeries code abs_to_phys() is a no-op. On iSeries we always have one lmb region which spans from 0 to systemcfg->physicalMemorySize (arch/ppc64/kernel/iSeries_setup.c line 383). This region has a base (ie. absolute) address of 0, and a physbase address of 0 (as calculated in lmb_analyze() (arch/ppc64/kernel/lmb.c line 144)). On iSeries, abs_to_phys(aa) is defined as lmb_abs_to_phys(aa), which finds the lmb region containing aa (and there's only one, ie. 0), and then does: return lmb.memory.region[0].physbase + (aa - lmb.memory.region[0].base) physbase == base == 0, so you're left with "return aa". So remove abs_to_phys(), and lmb_abs_to_phys() which is the implementation of abs_to_phys() for iSeries. Signed-off-by: Michael Ellerman Signed-off-by: Paul Mackerras commit a4a0f97020444f83bf22bb9c8c20d8af2b4e6317 Author: Michael Ellerman Date: Wed Aug 3 20:21:24 2005 +1000 [PATCH] ppc64: Remove redundant use of pointers in lmb code The lmb code is all written to use a pointer to an lmb struct. But it's always the same lmb struct, called "lmb". So we take the address of lmb, call it _lmb and then start using _lmb->foo everywhere, which is silly. This patch removes the _lmb pointers and replaces them with direct references to the one "lmb" struct. We do the same for some _mem and _rsv pointers which point to lmb.memory and lmb.reserved respectively. This patch looks quite busy, but it's basically just: s/_lmb->/lmb./g s/_mem->/lmb.memory./g s/_rsv->/lmb.reserved./g s/_rsv/&lmb.reserved/g s/mem->/lmb.memory./g Signed-off-by: Michael Ellerman Signed-off-by: Paul Mackerras commit aefd16b0c5a594b5feaba23954ad74061f45c8a5 Author: Michael Ellerman Date: Wed Aug 3 20:21:24 2005 +1000 [PATCH] ppc64: Remove redundant uses of physRpn_to_absRpn physRpn_to_absRpn is a no-op on non-iSeries platforms, remove the two redundant calls. There's only one caller on iSeries so fold the logic in there so we can get rid of it completely. Signed-off-by: Michael Ellerman Signed-off-by: Paul Mackerras commit ce21795275ab469b97384faa36462350af17eca0 Author: Michael Ellerman Date: Wed Aug 3 20:21:23 2005 +1000 [PATCH] ppc64: Consolidate some macros The only caller of chunk_offset() and abs_chunk() is phys_to_abs(), so fold the former two into the latter. Signed-off-by: Michael Ellerman Signed-off-by: Paul Mackerras commit 56e97b71bf55edb69dc8e9715553972ce50b1564 Author: Michael Ellerman Date: Wed Aug 3 20:21:23 2005 +1000 [PATCH] ppc64: Rename msChunks structure Rename the msChunks struct to get rid of the StUdlY caps and make it a bit clearer what it's for. Signed-off-by: Michael Ellerman Signed-off-by: Paul Mackerras commit 34c8f6961fc601294a38c5bd5ca12131b2e52674 Author: Michael Ellerman Date: Wed Aug 3 20:21:23 2005 +1000 [PATCH] ppc64: msChunks cleanups Chunks are 256KB, so use constants for the size/shift/mask, rather than getting them from the msChunks struct. The iSeries debugger (??) might still need access to the values in the msChunks struct, so we keep them around for now, but set them from the constant values. Replace msChunks_entry typedef with regular u32. Simplify msChunks_alloc() to manipulate klimit directly, rather than via a parameter. Move msChunks_alloc() and msChunks into iSeries_setup.c, as that's where they're used. Signed-off-by: Michael Ellerman Signed-off-by: Paul Mackerras commit 38e85dc18036804ada8698951cfad4e6114fec1b Author: Michael Ellerman Date: Wed Aug 3 20:21:23 2005 +1000 [PATCH] ppc64: Remove PTRRELOC() from msChunks code The msChunks code was written to work on pSeries, but now it's only used on iSeries. This means there's no need to do PTRRELOC anymore, so remove it all. A few places were getting "extern reloc_offset()" from abs_addr.h, move it into system.h instead. Signed-off-by: Michael Ellerman Signed-off-by: Paul Mackerras commit aed31351941aa990fb0865c186565a589c56d3fe Author: Stephen Rothwell Date: Wed Aug 3 14:43:21 2005 +1000 [PATCH] ppc64: introduce FW_FEATURE_ISERIES Signed-off-by: Stephen Rothwell Signed-off-by: Paul Mackerras commit 8d15a3e55f49678b0900dcf5c1cddb322a129325 Author: Stephen Rothwell Date: Wed Aug 3 14:40:16 2005 +1000 [PATCH] ppc64: make firmware_has_feature() stronger Make firmware_has_feature() evaluate at compile time for the non pSeries case and tidy up code where possible. Signed-off-by: Stephen Rothwell Signed-off-by: Paul Mackerras commit 1ababe11480d59d75be806804c71fa55d203a5a6 Author: Stephen Rothwell Date: Wed Aug 3 14:35:25 2005 +1000 [PATCH] ppc64: create firmware_has_feature() Create the firmware_has_feature() inline and move the firmware feature stuff into its own header file. Signed-off-by: Stephen Rothwell Signed-off-by: Paul Mackerras commit 7a6af5e38054d8e658a4b1b703902331a845de1a Author: Stephen Rothwell Date: Wed Aug 3 14:32:30 2005 +1000 [PATCH] ppc64: remove firmware features from cpu_spec The firmware_features field of struct cpu_spec should really be a separate variable as the firmware features do not depend on the chip and the bitmask is constructed independently. By removing it, we save 112 bytes from the cpu_specs array and we access the bitmask directly instead of via the cur_cpu_spec pointer. Signed-off-by: Stephen Rothwell Signed-off-by: Paul Mackerras commit 6fbb49d56d228b666cb4534bbc3c2dfe833c8053 Author: David Gibson Date: Fri Aug 19 14:52:32 2005 +1000 [PATCH] Move variables in ppc64 head.S from .data to .bss The ppc64 head.S defines several zero-initialized structures, such as the empty_zero_page and the kernel top-level pagetable. Currently they are defined to be in the data section. However, they're not used until after the bss is cleared, so this patch moves them to the bss, saving two and a half pages from the vmlinux. Signed-off-by: David Gibson Signed-off-by: Paul Mackerras commit 91a57fc6723d778e12686b5106a38583072fd767 Author: David Gibson Date: Fri Aug 19 14:52:32 2005 +1000 [PATCH] Tweak comments in ppc64 head.S This patch adjust some comments in head.S for accuracy, clarity, and spelling. Signed-off-by: David Gibson Signed-off-by: Paul Mackerras commit 1d086e6bd605ac44154e019fe96ae3568e8b2ba2 Author: David Gibson Date: Fri Aug 19 14:52:32 2005 +1000 [PATCH] Remove unneeded #defines in head.S arch/ppc64/kernel/head.S #defines SECONDARY_PROCESSORS then has some #ifdefs based on it. Whatever purpose this had is long lost, this patch removes it. Likewise, head.S defines H_SET_ASR, which is now defined, along with other hypervisor call numbers in hvcall.h. This patch deletes it, as well, from head.S. Signed-off-by: David Gibson Signed-off-by: Paul Mackerras commit 60ba44945714d9b7dae8b85ab0926f6f13809c73 Author: David Gibson Date: Fri Aug 19 14:52:32 2005 +1000 [PATCH] Fix apparent code overlap in ppc64 head.S An #if/#else construct near the top of ppc64's head.S appears to create overlapping sections of code for iSeries and pSeries (i.e. one thing on iSeries and something different in the same place on pSeries). In fact, checking the various absolute offsets, it doesn't. This patch unravels the #ifdefs to make it more obvious what's going on. This accomplishes another microstep towards a single kernel image which can boot both iSeries and pSeries. Signed-off-by: David Gibson Signed-off-by: Paul Mackerras commit 0ab20002f4b41f4b1799bad5948389da1c4c8444 Author: David Gibson Date: Fri Aug 19 14:52:31 2005 +1000 [PATCH] Remove general use functions from head.S As well as the interrupt vectors and initialization code, head.S contains several asm functions which are used during runtime. This patch moves these to misc.S, a more sensible location for random asm support code. A couple The functions moved are: disable_kernel_fp giveup_fpu disable_kernel_altivec giveup_altivec __setup_cpu_power3 (empty function) Signed-off-by: David Gibson Signed-off-by: Paul Mackerras commit c59c464a3e29830bcfae5eea1777cad9e00087f3 Author: David Gibson Date: Fri Aug 19 14:52:31 2005 +1000 [PATCH] Change address of ppc64 initial segment table On ppc64 machines with segment tables, CPU0's segment table is at a fixed address, currently 0x9000. This patch moves it to the free space at 0x6000, just below the fwnmi data area. This saves 8k of space in vmlinux and the runtime kernel image. Signed-off-by: David Gibson Signed-off-by: Paul Mackerras commit ec465515eeb662f66725c8c483a46b6bdd9bdd48 Author: David Gibson Date: Fri Aug 19 14:52:31 2005 +1000 [PATCH] Move iSeries and common vectors into unused space in head.S In the ppc64 kernel head.S there is currently quite a lot of unused space between the naca (at fixed address 0x4000) and the fwnmi data area (at fixed address 0x7000). This patch moves various exception vectors and support code into this region to use the wasted space. The functions load_up_fpu and load_up_altivec are moved down as well, since they are essentially continuations of the fp_unavailable_common and altivec_unavailable_common vectors, respectively. Likewise, the fwnmi vectors themselves are moved down into this area, because while the location of the fwnmi data area is fixed by the RPA, the vectors themselves can be anywhere sufficiently low. Signed-off-by: David Gibson Signed-off-by: Paul Mackerras commit 2e2446ea0758cd57dd065962d9544e3f4d44ea2b Author: David Gibson Date: Fri Aug 19 14:52:31 2005 +1000 [PATCH] Remove NACA fixed address constraint Comments in head.S suggest that the iSeries naca has a fixed address, because tools expect to find it there. The only tool which appears to access the naca is addRamDisk, but both the in-kernel version and the version used in RHEL and SuSE in fact locate the NACA the same way as the hypervisor does, by following the pointer in the hvReleaseData structure. Since the requirement for a fixed address seems to be obsolete, this patch removes the naca from head.S and replaces it with a normal C initializer. For good measure, it removes an old version of addRamDisk.c which was sitting, unused, in the ppc32 tree. Signed-off-by: David Gibson Signed-off-by: Paul Mackerras commit 19dbd0f6a74f7529d6d49dd50ad6b31adbe0598d Author: Stephen Rothwell Date: Tue Jul 12 17:50:26 2005 +1000 [PATCH] ppc64: split pSeries specific parts out of vio.c This patch just splits out the pSeries specific parts of vio.c. Signed-off-by: Stephen Rothwell Signed-off-by: Paul Mackerras commit 6312236fe82bbd3b0e1dee60b3eb3b270a2f6aeb Author: Stephen Rothwell Date: Tue Jul 12 17:45:27 2005 +1000 [PATCH] ppc64: make the bus matching function platform specific This patch allows us to have a different bus if matching function for each platform. Signed-off-by: Stephen Rothwell Signed-off-by: Paul Mackerras commit 8c65b5c955b8598d9c63b4e97392377269873a54 Author: Stephen Rothwell Date: Tue Jul 12 17:42:49 2005 +1000 [PATCH] ppc64: move iSeries vio iommu init Since the iSeries vio iommu tables cannot be used until after the vio bus has been initialised, move the initialisation of the tables to there. Signed-off-by: Stephen Rothwell Signed-off-by: Paul Mackerras commit 3e494c80481653bbc810b4e67651097595ea0294 Author: Stephen Rothwell Date: Tue Jul 12 17:40:17 2005 +1000 [PATCH] ppc64: split iSeries specific parts out of vio.c This patch splits the iSeries specific parts out of vio.c. Signed-off-by: Stephen Rothwell Signed-off-by: Paul Mackerras commit 6020164499ff3a61cd8bebceb9e294a155079f71 Author: Frank Rowand Date: Tue Jun 28 16:48:04 2005 -0700 [PATCH] ppc64: change duplicate Kconfig menu "General setup" to "Bus Options" arch/ppc64/Kconfig defines a "General setup" menu, but also sources init/Kconfig which also defines a "General setup" menu. Both of these menus appear at the top level of make menuconfig. Having two menus with the same name is confusing. This patch renames the ppc64/Kconfig menu to be "Bus Options" and moves options in this menu which are not bus related to the end of the "Platform support" menu. There are many variations among architectures on the exact naming of the "Bus Options" menu. I chose to use the simplest one, which is also used in arch/ppc/Kconfig. Signed-off-by: Frank Rowand Signed-off-by: Paul Mackerras commit 293da76b3d4c2f362f906bce8c5d2e053bdf8d44 Author: Jake Moilanen Date: Thu Jun 9 09:31:12 2005 -0500 [PATCH] ppc64: PCI device-node failure detection OpenFirmware marks devices as failed in the device-tree when a hardware problem is detected. The kernel needs to fail config reads/writes to prevent a kernel crash when incorrect data is read. This patch validates that the device-node is not marked "fail" when config space reads/writes are attempted. Signed-off-by: Jake Moilanen Signed-off-by: Paul Mackerras commit 34153fa3af45d84f3221d9b67ba2ab7e8a220d28 Author: Benjamin Herrenschmidt Date: Tue Aug 9 10:36:34 2005 +0200 [PATCH] flattened device tree changes This patch updates the format of the flattened device-tree passed between the boot trampoline and the kernel to support a more compact representation, for use by embedded systems mostly. Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Paul Mackerras commit e28f7faf05159f1cfd564596f5e6178edba6bd49 Author: David Gibson Date: Fri Aug 5 19:39:06 2005 +1000 [PATCH] Four level pagetables for ppc64 Implement 4-level pagetables for ppc64 This patch implements full four-level page tables for ppc64, thereby extending the usable user address range to 44 bits (16T). The patch uses a full page for the tables at the bottom and top level, and a quarter page for the intermediate levels. It uses full 64-bit pointers at every level, thus also increasing the addressable range of physical memory. This patch also tweaks the VSID allocation to allow matching range for user addresses (this halves the number of available contexts) and adds some #if and BUILD_BUG sanity checks. Signed-off-by: David Gibson Signed-off-by: Paul Mackerras commit decd300b30e499fe6be1bbfc5650fc971de8c1fa Author: Olaf Hering Date: Mon Aug 8 13:24:38 2005 +1000 [PATCH] ppc64: make arch/ppc64/boot standalone Make the bootheader for ppc64 independent from kernel and libc headers. * add -nostdinc -isystem $gccincludes to not include libc headers * declare all functions in header files, also the stuff from string.S * declare some functions static * use stddef.h to get size_t (hopefully ok) * remove ppc32-types.h, only elf.h used the __NN types With further modifications by Paul Mackerras and Stephen Rothwell. Signed-off-by: Olaf Hering Signed-off-by: Paul Mackerras From michael at ellerman.id.au Mon Aug 29 11:56:31 2005 From: michael at ellerman.id.au (Michael Ellerman) Date: Mon, 29 Aug 2005 11:56:31 +1000 Subject: [PATCH 10/12] ppc64: Reroute interrupts from zero + offset to KERNELBASE + offset In-Reply-To: <430F1EF7.8080903@vnet.ibm.com> References: <20050826025331.84994680F7@ozlabs.org> <430F1EF7.8080903@vnet.ibm.com> Message-ID: <200508291156.34262.michael@ellerman.id.au> Hi Will, On Fri, 26 Aug 2005 23:53, will schmidt wrote: > Hi Michael, > first question is inline, the other question.. when the > KDUMP_CAPTURE_KERNEL is configured, is it only mapped into memory ahead > of time, or would functions like this one (setup_kdump_trampoline) be > run during normal system start? I'm not sure what you mean there. The idea is that the first kernel will load the second kernel into memory at 32 MB, then when the first kernel crashes it passes control to the second kernel which begins running. In the process of starting up, the second kernel will backup the first 0x8000 bytes of the first kernel, and then call setup_kdump_trampoline(). > > + /* XXX this only works if PHYSICAL_START <= 32 MB */ > > + > > + for (i = 0x100; i < 0x3000; i += 8) { > > + addr = (unsigned int *)i; > > + *addr++ = 0x60000000; /* nop */ > > + *addr = 0x48000000 | ((PHYSICAL_START - 1) & 0x03fffffc); > > + > > + asm ("dcbst 0,%0; sync; icbi 0,%0; isync" : : "r" (addr)); > > + } Stephen is right, this code definitely needs a comment, I just hadn't got around to it yet. > So here we're replacing the exception code in the first kernel, with > pointers to the exception code in the second, right? once this runs we > end up with code something like... > > c0000000 00000100: 60 00 00 00 nop > c0000000 00000108: 48 00 xx xx b (PHYSICAL_START -1) > c0000000 00000110: 60 00 00 00 nop > c0000000 00000118: 48 00 xx xx b (PHYSICAL_START -1) > c0000000 00000120: 60 00 00 00 nop > c0000000 00000128: 48 00 xx xx b (PHYSICAL_START -1) > ... > > Is this the intent, or should there be a +i somewhere in the branch > instruction too? Almost. 0x48000000 is a "b" instruction, not "ba". So the disassembly looks like this: c000000000000100 60000000 nop c000000000000104 49fffffc b c000000002000100 c000000000000108 60000000 nop c00000000000010c 49fffffc b c000000002000108 c000000000000110 60000000 nop c000000000000114 49fffffc b c000000002000110 c000000000000118 60000000 nop c00000000000011c 49fffffc b c000000002000118 That is we're branching to (32 MB - 4) + current address. [it's - 4 because of the mask (0x03ffffffc)] We'd like to just branch to current address + 32 MB, but we don't have enough bits in the branch instruction for that, hence we need a nop at 0x100, then at 0x104 we jump to 0x104 + 32 MB - 4 = 0x100 + 32 MB. Hope that makes sense. cheers -- Michael Ellerman IBM OzLabs email: michael:ellerman.id.au inmsg: mpe:jabber.org wwweb: http://michael.ellerman.id.au phone: +61 2 6212 1183 (tie line 70 21183) We do not inherit the earth from our ancestors, we borrow it from our children. - S.M.A.R.T Person -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: not available Url : http://ozlabs.org/pipermail/linuxppc64-dev/attachments/20050829/1ac705a3/attachment.pgp From olof at lixom.net Mon Aug 29 12:42:10 2005 From: olof at lixom.net (Olof Johansson) Date: Sun, 28 Aug 2005 21:42:10 -0500 Subject: [PATCH][RESEND] PPC64: Don't try to claim memory from OF at 1GB mark Message-ID: <20050829024210.GA14044@austin.ibm.com> Hi, Some RS64-based machines (p620, F80, others) have problems with firmware returning 0xdeadbeef instead of failure to allocations that end at the 1GB mark. We have two options: 1. Detect the undocumented 0xdeadbeef return value and interpret it as a failure. 2. Avoid allocating that high. (2) is really the cleaner solution here. 768MB is plenty of room so use that as the max alloc_top instead of 1GB. Signed-off-by: Olof Johansson Index: 2.6/arch/ppc64/kernel/prom_init.c =================================================================== --- 2.6.orig/arch/ppc64/kernel/prom_init.c 2005-08-09 03:16:09.000000000 -0500 +++ 2.6/arch/ppc64/kernel/prom_init.c 2005-08-09 18:16:18.000000000 -0500 @@ -892,7 +892,10 @@ static void __init prom_init_mem(void) if ( RELOC(of_platform) == PLATFORM_PSERIES_LPAR ) RELOC(alloc_top) = RELOC(rmo_top); else - RELOC(alloc_top) = RELOC(rmo_top) = min(0x40000000ul, RELOC(ram_top)); + /* Some RS64 machines have buggy firmware where claims up at 1GB + * fails. Cap at 768MB as a workaround. Still plenty of room. + */ + RELOC(alloc_top) = RELOC(rmo_top) = min(0x30000000ul, RELOC(ram_top)); prom_printf("memory layout at init:\n"); prom_printf(" memory_limit : %x (16 MB aligned)\n", RELOC(prom_memory_limit)); _______________________________________________ Linuxppc64-dev mailing list Linuxppc64-dev at ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc64-dev From michael at ellerman.id.au Mon Aug 29 13:00:20 2005 From: michael at ellerman.id.au (Michael Ellerman) Date: Mon, 29 Aug 2005 13:00:20 +1000 Subject: [PATCH 3/12] ppc64: Remove unused reloc_offset code In-Reply-To: <20050826215900.4e9a7177.sfr@canb.auug.org.au> References: <1125024799.128302.675577398916.qpatch@concordia> <20050826214015.3c96f10e.sfr@canb.auug.org.au> <20050826215900.4e9a7177.sfr@canb.auug.org.au> Message-ID: <200508291300.20578.michael@ellerman.id.au> On Fri, 26 Aug 2005 21:59, Stephen Rothwell wrote: > On Fri, 26 Aug 2005 21:40:15 +1000 Stephen Rothwell wrote: > > On Fri, 26 Aug 2005 12:53:21 +1000 (EST) Michael Ellerman wrote: > > > This patch changes the calling convention for cpu_setup routines, but > > > currently none of them actually consult their arguments so no further > > > changes are needed. > > > > except for the prototypes in cputable.c ... > > And, of course, the definition of cpu_set_t in cputable.h Oops, glad the compiler caught those for me :/ Updated patch: ppc64: Remove unused reloc_offset code In head.S there are several routines that are written to use reloc_offset, so they can run at a different address to their link address. However, some of these routines are only ever called after the kernel's moved to it's linked address, and so the reloc_offset business is redundant. As a side-effect, this patch changes the calling convention for cpu_setup routines (cpu_setup_t). Index: work/arch/ppc64/kernel/head.S =================================================================== --- work.orig/arch/ppc64/kernel/head.S +++ work/arch/ppc64/kernel/head.S @@ -1342,7 +1342,6 @@ _STATIC(__start_initialization_iSeries) LOADADDR(r3,cpu_specs) LOADADDR(r4,cur_cpu_spec) - li r5,0 bl .identify_cpu LOADADDR(r2,__toc_start) @@ -1689,10 +1688,6 @@ _GLOBAL(enable_64b_mode) * This is where the main kernel code starts. */ _STATIC(start_here_multiplatform) - /* get a new offset, now that the kernel has moved. */ - bl .reloc_offset - mr r26,r3 - /* Clear out the BSS. It may have been done in prom_init, * already but that's irrelevant since prom_init will soon * be detached from the kernel completely. Besides, we need @@ -1738,7 +1733,6 @@ _STATIC(start_here_multiplatform) /* kernel but are still running in real mode. */ LOADADDR(r3,init_thread_union) - sub r3,r3,r26 /* set up a stack pointer (physical address) */ addi r1,r3,THREAD_SIZE @@ -1749,13 +1743,9 @@ _STATIC(start_here_multiplatform) LOADADDR(r2,__toc_start) addi r2,r2,0x4000 addi r2,r2,0x4000 - sub r2,r2,r26 LOADADDR(r3,cpu_specs) - sub r3,r3,r26 LOADADDR(r4,cur_cpu_spec) - sub r4,r4,r26 - mr r5,r26 bl .identify_cpu /* Save some low level config HIDs of CPU0 to be copied to @@ -1770,13 +1760,11 @@ _STATIC(start_here_multiplatform) * code */ LOADADDR(r27, boot_cpuid) - sub r27,r27,r26 lwz r27,0(r27) LOADADDR(r24, paca) /* Get base vaddr of paca array */ mulli r13,r27,PACA_SIZE /* Calculate vaddr of right paca */ add r13,r13,r24 /* for this processor. */ - sub r13,r13,r26 /* convert to physical addr */ mtspr SPRG3,r13 /* PPPBBB: Temp... -Peter */ /* Do very early kernel initializations, including initial hash table, @@ -1814,7 +1802,6 @@ _STATIC(start_here_multiplatform) andi. r3,r3,0x1 bne 98f LOADADDR(r6,_SDR1) /* Only if NOT LPAR */ - sub r6,r6,r26 ld r6,0(r6) /* get the value of _SDR1 */ mtspr SDR1,r6 /* set the htab location */ 98: Index: work/arch/ppc64/kernel/misc.S =================================================================== --- work.orig/arch/ppc64/kernel/misc.S +++ work/arch/ppc64/kernel/misc.S @@ -511,7 +511,6 @@ _GLOBAL(cvt_df) * identify_cpu and calls setup_cpu * In: r3 = base of the cpu_specs array * r4 = address of cur_cpu_spec - * r5 = relocation offset */ _GLOBAL(identify_cpu) mfpvr r7 @@ -524,16 +523,11 @@ _GLOBAL(identify_cpu) addi r3,r3,CPU_SPEC_ENTRY_SIZE b 1b 1: - add r0,r3,r5 - std r0,0(r4) + std r3,0(r4) ld r4,CPU_SPEC_SETUP(r3) - sub r4,r4,r5 ld r4,0(r4) - sub r4,r4,r5 mtctr r4 - /* Calling convention for cpu setup is r3=offset, r4=cur_cpu_spec */ - mr r4,r3 - mr r3,r5 + /* Calling convention for cpu setup is r3 = cur_cpu_spec */ bctr /* Index: work/include/asm-ppc64/cputable.h =================================================================== --- work.orig/include/asm-ppc64/cputable.h +++ work/include/asm-ppc64/cputable.h @@ -37,7 +37,7 @@ */ struct cpu_spec; -typedef void (*cpu_setup_t)(unsigned long offset, struct cpu_spec* spec); +typedef void (*cpu_setup_t)(struct cpu_spec* spec); struct cpu_spec { /* CPU is matched via (PVR & pvr_mask) == pvr_value */ Index: work/arch/ppc64/kernel/cputable.c =================================================================== --- work.orig/arch/ppc64/kernel/cputable.c +++ work/arch/ppc64/kernel/cputable.c @@ -31,10 +31,10 @@ EXPORT_SYMBOL(cur_cpu_spec); * part of the cputable though. That has to be fixed for both ppc32 * and ppc64 */ -extern void __setup_cpu_power3(unsigned long offset, struct cpu_spec* spec); -extern void __setup_cpu_power4(unsigned long offset, struct cpu_spec* spec); -extern void __setup_cpu_ppc970(unsigned long offset, struct cpu_spec* spec); -extern void __setup_cpu_be(unsigned long offset, struct cpu_spec* spec); +extern void __setup_cpu_power3(struct cpu_spec* spec); +extern void __setup_cpu_power4(struct cpu_spec* spec); +extern void __setup_cpu_ppc970(struct cpu_spec* spec); +extern void __setup_cpu_be(struct cpu_spec* spec); /* We only set the altivec features if the kernel was compiled with altivec From sfr at canb.auug.org.au Mon Aug 29 13:01:33 2005 From: sfr at canb.auug.org.au (Stephen Rothwell) Date: Mon, 29 Aug 2005 13:01:33 +1000 Subject: [PATCH 0/3] Start the merge Message-ID: <20050829130133.519391c6.sfr@canb.auug.org.au> Hi Paulus, I think the following 3 patches are no longer contentious - I have removed some of the files from the third that people expressed concersn over. Please send at least the first upstream. The other two can also probably be sent. -- Cheers, Stephen Rothwell sfr at canb.auug.org.au http://www.canb.auug.org.au/~sfr/ -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: not available Url : http://ozlabs.org/pipermail/linuxppc64-dev/attachments/20050829/adcecf3e/attachment.pgp From sfr at canb.auug.org.au Mon Aug 29 13:15:50 2005 From: sfr at canb.auug.org.au (Stephen Rothwell) Date: Mon, 29 Aug 2005 13:15:50 +1000 Subject: [PATCH 1/3] Create include/asm-powerpc In-Reply-To: <20050829130133.519391c6.sfr@canb.auug.org.au> References: <20050829130133.519391c6.sfr@canb.auug.org.au> Message-ID: <20050829131550.39e97cf3.sfr@canb.auug.org.au> The ppc and ppc64 trees are hopefully going to merge over time, so this patch begins the process by creating a place for the merging of the header files. Create include/asm-powerpc (and move linkage.h into it from asm-{ppc,ppc64} since we don't like empty directories). Modify the ppc and ppc64 Makefiles to cope. Signed-off-by: Stephen Rothwell --- arch/ppc/Makefile | 11 ++++++++++- arch/ppc64/Makefile | 9 +++++++++ include/asm-powerpc/linkage.h | 6 ++++++ include/asm-ppc/linkage.h | 6 ------ include/asm-ppc64/linkage.h | 6 ------ 5 files changed, 25 insertions(+), 13 deletions(-) create mode 100644 include/asm-powerpc/linkage.h delete mode 100644 include/asm-ppc/linkage.h delete mode 100644 include/asm-ppc64/linkage.h -- Cheers, Stephen Rothwell sfr at canb.auug.org.au http://www.canb.auug.org.au/~sfr/ c12b44d5844f3c8a48fb30bb880db49029d0d8cb diff --git a/arch/ppc/Makefile b/arch/ppc/Makefile --- a/arch/ppc/Makefile +++ b/arch/ppc/Makefile @@ -21,11 +21,13 @@ CC := $(CC) -m32 endif LDFLAGS_vmlinux := -Ttext $(KERNELLOAD) -Bstatic -CPPFLAGS += -Iarch/$(ARCH) +CPPFLAGS += -Iarch/$(ARCH) -Iinclude3 AFLAGS += -Iarch/$(ARCH) CFLAGS += -Iarch/$(ARCH) -msoft-float -pipe \ -ffixed-r2 -mmultiple CPP = $(CC) -E $(CFLAGS) +# Temporary hack until we have migrated to asm-powerpc +LINUXINCLUDE += -Iinclude3 CHECKFLAGS += -D__powerpc__ @@ -101,6 +103,7 @@ endef archclean: $(Q)$(MAKE) $(clean)=arch/ppc/boot + $(Q)rm -rf include3 prepare: include/asm-$(ARCH)/offsets.h checkbin @@ -110,6 +113,12 @@ arch/$(ARCH)/kernel/asm-offsets.s: inclu include/asm-$(ARCH)/offsets.h: arch/$(ARCH)/kernel/asm-offsets.s $(call filechk,gen-asm-offsets) +# Temporary hack until we have migrated to asm-powerpc +include/asm: include3/asm +include3/asm: + $(Q)if [ ! -d include3 ]; then mkdir -p include3; fi + $(Q)ln -fsn $(srctree)/include/asm-powerpc include3/asm + # Use the file '.tmp_gas_check' for binutils tests, as gas won't output # to stdout and these checks are run even on install targets. TOUT := .tmp_gas_check diff --git a/arch/ppc64/Makefile b/arch/ppc64/Makefile --- a/arch/ppc64/Makefile +++ b/arch/ppc64/Makefile @@ -55,6 +55,8 @@ LDFLAGS := -m elf64ppc LDFLAGS_vmlinux := -Bstatic -e $(KERNELLOAD) -Ttext $(KERNELLOAD) CFLAGS += -msoft-float -pipe -mminimal-toc -mtraceback=none \ -mcall-aixdesc +# Temporary hack until we have migrated to asm-powerpc +CPPFLAGS += -Iinclude3 GCC_VERSION := $(call cc-version) GCC_BROKEN_VEC := $(shell if [ $(GCC_VERSION) -lt 0400 ] ; then echo "y"; fi ;) @@ -112,6 +114,7 @@ all: $(KBUILD_IMAGE) archclean: $(Q)$(MAKE) $(clean)=$(boot) + $(Q)rm -rf include3 prepare: include/asm-ppc64/offsets.h @@ -121,6 +124,12 @@ arch/ppc64/kernel/asm-offsets.s: include include/asm-ppc64/offsets.h: arch/ppc64/kernel/asm-offsets.s $(call filechk,gen-asm-offsets) +# Temporary hack until we have migrated to asm-powerpc +include/asm: include3/asm +include3/asm: + $(Q)if [ ! -d include3 ]; then mkdir -p include3; fi; + $(Q)ln -fsn $(srctree)/include/asm-powerpc include3/asm + define archhelp echo '* zImage - Compressed kernel image (arch/$(ARCH)/boot/zImage)' echo ' zImage.initrd- Compressed kernel image with initrd attached,' diff --git a/include/asm-powerpc/linkage.h b/include/asm-powerpc/linkage.h new file mode 100644 --- /dev/null +++ b/include/asm-powerpc/linkage.h @@ -0,0 +1,6 @@ +#ifndef __ASM_LINKAGE_H +#define __ASM_LINKAGE_H + +/* Nothing to see here... */ + +#endif diff --git a/include/asm-ppc/linkage.h b/include/asm-ppc/linkage.h deleted file mode 100644 --- a/include/asm-ppc/linkage.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __ASM_LINKAGE_H -#define __ASM_LINKAGE_H - -/* Nothing to see here... */ - -#endif diff --git a/include/asm-ppc64/linkage.h b/include/asm-ppc64/linkage.h deleted file mode 100644 --- a/include/asm-ppc64/linkage.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __ASM_LINKAGE_H -#define __ASM_LINKAGE_H - -/* Nothing to see here... */ - -#endif From sfr at canb.auug.org.au Mon Aug 29 14:06:56 2005 From: sfr at canb.auug.org.au (Stephen Rothwell) Date: Mon, 29 Aug 2005 14:06:56 +1000 Subject: [PATCH 2/3] Move the identical files from include/asm-ppc{,64} In-Reply-To: <20050829131550.39e97cf3.sfr@canb.auug.org.au> References: <20050829130133.519391c6.sfr@canb.auug.org.au> <20050829131550.39e97cf3.sfr@canb.auug.org.au> Message-ID: <20050829140656.5b9e751f.sfr@canb.auug.org.au> Move the identical files from include/asm-ppc{,64}/ to include/asm-powerpc/. Remove hdreg.h completely as it is unused in the tree. Signed-off-by: Stephen Rothwell --- include/asm-powerpc/8253pit.h | 10 ++++++++++ include/asm-powerpc/agp.h | 23 +++++++++++++++++++++++ include/asm-powerpc/cputime.h | 1 + include/asm-powerpc/div64.h | 1 + include/asm-powerpc/emergency-restart.h | 1 + include/asm-powerpc/ipc.h | 1 + include/asm-powerpc/xor.h | 1 + include/asm-ppc/8253pit.h | 10 ---------- include/asm-ppc/agp.h | 23 ----------------------- include/asm-ppc/cputime.h | 6 ------ include/asm-ppc/div64.h | 1 - include/asm-ppc/emergency-restart.h | 6 ------ include/asm-ppc/hdreg.h | 1 - include/asm-ppc/ipc.h | 1 - include/asm-ppc/xor.h | 1 - include/asm-ppc64/8253pit.h | 10 ---------- include/asm-ppc64/agp.h | 23 ----------------------- include/asm-ppc64/cputime.h | 6 ------ include/asm-ppc64/div64.h | 1 - include/asm-ppc64/emergency-restart.h | 6 ------ include/asm-ppc64/hdreg.h | 1 - include/asm-ppc64/ipc.h | 1 - include/asm-ppc64/xor.h | 1 - 23 files changed, 38 insertions(+), 98 deletions(-) create mode 100644 include/asm-powerpc/8253pit.h create mode 100644 include/asm-powerpc/agp.h create mode 100644 include/asm-powerpc/cputime.h create mode 100644 include/asm-powerpc/div64.h create mode 100644 include/asm-powerpc/emergency-restart.h create mode 100644 include/asm-powerpc/ipc.h create mode 100644 include/asm-powerpc/xor.h delete mode 100644 include/asm-ppc/8253pit.h delete mode 100644 include/asm-ppc/agp.h delete mode 100644 include/asm-ppc/cputime.h delete mode 100644 include/asm-ppc/div64.h delete mode 100644 include/asm-ppc/emergency-restart.h delete mode 100644 include/asm-ppc/hdreg.h delete mode 100644 include/asm-ppc/ipc.h delete mode 100644 include/asm-ppc/xor.h delete mode 100644 include/asm-ppc64/8253pit.h delete mode 100644 include/asm-ppc64/agp.h delete mode 100644 include/asm-ppc64/cputime.h delete mode 100644 include/asm-ppc64/div64.h delete mode 100644 include/asm-ppc64/emergency-restart.h delete mode 100644 include/asm-ppc64/hdreg.h delete mode 100644 include/asm-ppc64/ipc.h delete mode 100644 include/asm-ppc64/xor.h -- Cheers, Stephen Rothwell sfr at canb.auug.org.au http://www.canb.auug.org.au/~sfr/ 9ead132760dbd38ffa1bf132703d5fbb77e1081d diff --git a/include/asm-powerpc/8253pit.h b/include/asm-powerpc/8253pit.h new file mode 100644 --- /dev/null +++ b/include/asm-powerpc/8253pit.h @@ -0,0 +1,10 @@ +/* + * 8253/8254 Programmable Interval Timer + */ + +#ifndef _8253PIT_H +#define _8253PIT_H + +#define PIT_TICK_RATE 1193182UL + +#endif diff --git a/include/asm-powerpc/agp.h b/include/asm-powerpc/agp.h new file mode 100644 --- /dev/null +++ b/include/asm-powerpc/agp.h @@ -0,0 +1,23 @@ +#ifndef AGP_H +#define AGP_H 1 + +#include + +/* nothing much needed here */ + +#define map_page_into_agp(page) +#define unmap_page_from_agp(page) +#define flush_agp_mappings() +#define flush_agp_cache() mb() + +/* Convert a physical address to an address suitable for the GART. */ +#define phys_to_gart(x) (x) +#define gart_to_phys(x) (x) + +/* GATT allocation. Returns/accepts GATT kernel virtual address. */ +#define alloc_gatt_pages(order) \ + ((char *)__get_free_pages(GFP_KERNEL, (order))) +#define free_gatt_pages(table, order) \ + free_pages((unsigned long)(table), (order)) + +#endif diff --git a/include/asm-powerpc/cputime.h b/include/asm-powerpc/cputime.h new file mode 100644 --- /dev/null +++ b/include/asm-powerpc/cputime.h @@ -0,0 +1 @@ +#include diff --git a/include/asm-powerpc/div64.h b/include/asm-powerpc/div64.h new file mode 100644 --- /dev/null +++ b/include/asm-powerpc/div64.h @@ -0,0 +1 @@ +#include diff --git a/include/asm-powerpc/emergency-restart.h b/include/asm-powerpc/emergency-restart.h new file mode 100644 --- /dev/null +++ b/include/asm-powerpc/emergency-restart.h @@ -0,0 +1 @@ +#include diff --git a/include/asm-powerpc/ipc.h b/include/asm-powerpc/ipc.h new file mode 100644 --- /dev/null +++ b/include/asm-powerpc/ipc.h @@ -0,0 +1 @@ +#include diff --git a/include/asm-powerpc/xor.h b/include/asm-powerpc/xor.h new file mode 100644 --- /dev/null +++ b/include/asm-powerpc/xor.h @@ -0,0 +1 @@ +#include diff --git a/include/asm-ppc/8253pit.h b/include/asm-ppc/8253pit.h deleted file mode 100644 --- a/include/asm-ppc/8253pit.h +++ /dev/null @@ -1,10 +0,0 @@ -/* - * 8253/8254 Programmable Interval Timer - */ - -#ifndef _8253PIT_H -#define _8253PIT_H - -#define PIT_TICK_RATE 1193182UL - -#endif diff --git a/include/asm-ppc/agp.h b/include/asm-ppc/agp.h deleted file mode 100644 --- a/include/asm-ppc/agp.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef AGP_H -#define AGP_H 1 - -#include - -/* nothing much needed here */ - -#define map_page_into_agp(page) -#define unmap_page_from_agp(page) -#define flush_agp_mappings() -#define flush_agp_cache() mb() - -/* Convert a physical address to an address suitable for the GART. */ -#define phys_to_gart(x) (x) -#define gart_to_phys(x) (x) - -/* GATT allocation. Returns/accepts GATT kernel virtual address. */ -#define alloc_gatt_pages(order) \ - ((char *)__get_free_pages(GFP_KERNEL, (order))) -#define free_gatt_pages(table, order) \ - free_pages((unsigned long)(table), (order)) - -#endif diff --git a/include/asm-ppc/cputime.h b/include/asm-ppc/cputime.h deleted file mode 100644 --- a/include/asm-ppc/cputime.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __PPC_CPUTIME_H -#define __PPC_CPUTIME_H - -#include - -#endif /* __PPC_CPUTIME_H */ diff --git a/include/asm-ppc/div64.h b/include/asm-ppc/div64.h deleted file mode 100644 --- a/include/asm-ppc/div64.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/include/asm-ppc/emergency-restart.h b/include/asm-ppc/emergency-restart.h deleted file mode 100644 --- a/include/asm-ppc/emergency-restart.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _ASM_EMERGENCY_RESTART_H -#define _ASM_EMERGENCY_RESTART_H - -#include - -#endif /* _ASM_EMERGENCY_RESTART_H */ diff --git a/include/asm-ppc/hdreg.h b/include/asm-ppc/hdreg.h deleted file mode 100644 --- a/include/asm-ppc/hdreg.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/include/asm-ppc/ipc.h b/include/asm-ppc/ipc.h deleted file mode 100644 --- a/include/asm-ppc/ipc.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/include/asm-ppc/xor.h b/include/asm-ppc/xor.h deleted file mode 100644 --- a/include/asm-ppc/xor.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/include/asm-ppc64/8253pit.h b/include/asm-ppc64/8253pit.h deleted file mode 100644 --- a/include/asm-ppc64/8253pit.h +++ /dev/null @@ -1,10 +0,0 @@ -/* - * 8253/8254 Programmable Interval Timer - */ - -#ifndef _8253PIT_H -#define _8253PIT_H - -#define PIT_TICK_RATE 1193182UL - -#endif diff --git a/include/asm-ppc64/agp.h b/include/asm-ppc64/agp.h deleted file mode 100644 --- a/include/asm-ppc64/agp.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef AGP_H -#define AGP_H 1 - -#include - -/* nothing much needed here */ - -#define map_page_into_agp(page) -#define unmap_page_from_agp(page) -#define flush_agp_mappings() -#define flush_agp_cache() mb() - -/* Convert a physical address to an address suitable for the GART. */ -#define phys_to_gart(x) (x) -#define gart_to_phys(x) (x) - -/* GATT allocation. Returns/accepts GATT kernel virtual address. */ -#define alloc_gatt_pages(order) \ - ((char *)__get_free_pages(GFP_KERNEL, (order))) -#define free_gatt_pages(table, order) \ - free_pages((unsigned long)(table), (order)) - -#endif diff --git a/include/asm-ppc64/cputime.h b/include/asm-ppc64/cputime.h deleted file mode 100644 --- a/include/asm-ppc64/cputime.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __PPC_CPUTIME_H -#define __PPC_CPUTIME_H - -#include - -#endif /* __PPC_CPUTIME_H */ diff --git a/include/asm-ppc64/div64.h b/include/asm-ppc64/div64.h deleted file mode 100644 --- a/include/asm-ppc64/div64.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/include/asm-ppc64/emergency-restart.h b/include/asm-ppc64/emergency-restart.h deleted file mode 100644 --- a/include/asm-ppc64/emergency-restart.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _ASM_EMERGENCY_RESTART_H -#define _ASM_EMERGENCY_RESTART_H - -#include - -#endif /* _ASM_EMERGENCY_RESTART_H */ diff --git a/include/asm-ppc64/hdreg.h b/include/asm-ppc64/hdreg.h deleted file mode 100644 --- a/include/asm-ppc64/hdreg.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/include/asm-ppc64/ipc.h b/include/asm-ppc64/ipc.h deleted file mode 100644 --- a/include/asm-ppc64/ipc.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/include/asm-ppc64/xor.h b/include/asm-ppc64/xor.h deleted file mode 100644 --- a/include/asm-ppc64/xor.h +++ /dev/null @@ -1 +0,0 @@ -#include From sfr at canb.auug.org.au Mon Aug 29 14:08:11 2005 From: sfr at canb.auug.org.au (Stephen Rothwell) Date: Mon, 29 Aug 2005 14:08:11 +1000 Subject: [PATCH 3/3] Move all the very similar files to asm-powerpc In-Reply-To: <20050829140656.5b9e751f.sfr@canb.auug.org.au> References: <20050829130133.519391c6.sfr@canb.auug.org.au> <20050829131550.39e97cf3.sfr@canb.auug.org.au> <20050829140656.5b9e751f.sfr@canb.auug.org.au> Message-ID: <20050829140811.793e9fe6.sfr@canb.auug.org.au> They differed in either simple comments or in the protecting ifdefs. Signed-off-by: Stephen Rothwell --- include/asm-powerpc/errno.h | 11 ++++ include/asm-powerpc/ioctl.h | 69 ++++++++++++++++++++++++ include/asm-powerpc/ioctls.h | 107 +++++++++++++++++++++++++++++++++++++ include/asm-powerpc/local.h | 1 include/asm-powerpc/namei.h | 20 +++++++ include/asm-powerpc/percpu.h | 1 include/asm-powerpc/poll.h | 23 ++++++++ include/asm-powerpc/resource.h | 1 include/asm-powerpc/shmparam.h | 6 ++ include/asm-powerpc/string.h | 32 +++++++++++ include/asm-powerpc/unaligned.h | 18 ++++++ include/asm-ppc/errno.h | 11 ---- include/asm-ppc/ioctl.h | 69 ------------------------ include/asm-ppc/ioctls.h | 107 ------------------------------------- include/asm-ppc/local.h | 6 -- include/asm-ppc/namei.h | 20 ------- include/asm-ppc/percpu.h | 6 -- include/asm-ppc/poll.h | 23 -------- include/asm-ppc/resource.h | 6 -- include/asm-ppc/shmparam.h | 6 -- include/asm-ppc/string.h | 32 ----------- include/asm-ppc/unaligned.h | 18 ------ include/asm-ppc64/errno.h | 18 ------ include/asm-ppc64/ioctl.h | 74 ------------------------- include/asm-ppc64/ioctls.h | 114 --------------------------------------- include/asm-ppc64/local.h | 1 include/asm-ppc64/namei.h | 23 -------- include/asm-ppc64/percpu.h | 6 -- include/asm-ppc64/poll.h | 32 ----------- include/asm-ppc64/resource.h | 6 -- include/asm-ppc64/shmparam.h | 13 ---- include/asm-ppc64/string.h | 35 ------------ include/asm-ppc64/unaligned.h | 21 ------- 33 files changed, 289 insertions(+), 647 deletions(-) create mode 100644 include/asm-powerpc/errno.h create mode 100644 include/asm-powerpc/ioctl.h create mode 100644 include/asm-powerpc/ioctls.h create mode 100644 include/asm-powerpc/local.h create mode 100644 include/asm-powerpc/namei.h create mode 100644 include/asm-powerpc/percpu.h create mode 100644 include/asm-powerpc/poll.h create mode 100644 include/asm-powerpc/resource.h create mode 100644 include/asm-powerpc/shmparam.h create mode 100644 include/asm-powerpc/string.h create mode 100644 include/asm-powerpc/unaligned.h delete mode 100644 include/asm-ppc/errno.h delete mode 100644 include/asm-ppc/ioctl.h delete mode 100644 include/asm-ppc/ioctls.h delete mode 100644 include/asm-ppc/local.h delete mode 100644 include/asm-ppc/namei.h delete mode 100644 include/asm-ppc/percpu.h delete mode 100644 include/asm-ppc/poll.h delete mode 100644 include/asm-ppc/resource.h delete mode 100644 include/asm-ppc/shmparam.h delete mode 100644 include/asm-ppc/string.h delete mode 100644 include/asm-ppc/unaligned.h delete mode 100644 include/asm-ppc64/errno.h delete mode 100644 include/asm-ppc64/ioctl.h delete mode 100644 include/asm-ppc64/ioctls.h delete mode 100644 include/asm-ppc64/local.h delete mode 100644 include/asm-ppc64/namei.h delete mode 100644 include/asm-ppc64/percpu.h delete mode 100644 include/asm-ppc64/poll.h delete mode 100644 include/asm-ppc64/resource.h delete mode 100644 include/asm-ppc64/shmparam.h delete mode 100644 include/asm-ppc64/string.h delete mode 100644 include/asm-ppc64/unaligned.h -- Cheers, Stephen Rothwell sfr at canb.auug.org.au http://www.canb.auug.org.au/~sfr/ bd136b653c5aac766e14dc5c655ab6ae3053d76d diff --git a/include/asm-powerpc/errno.h b/include/asm-powerpc/errno.h new file mode 100644 --- /dev/null +++ b/include/asm-powerpc/errno.h @@ -0,0 +1,11 @@ +#ifndef _PPC_ERRNO_H +#define _PPC_ERRNO_H + +#include + +#undef EDEADLOCK +#define EDEADLOCK 58 /* File locking deadlock error */ + +#define _LAST_ERRNO 516 + +#endif diff --git a/include/asm-powerpc/ioctl.h b/include/asm-powerpc/ioctl.h new file mode 100644 --- /dev/null +++ b/include/asm-powerpc/ioctl.h @@ -0,0 +1,69 @@ +#ifndef _PPC_IOCTL_H +#define _PPC_IOCTL_H + + +/* + * this was copied from the alpha as it's a bit cleaner there. + * -- Cort + */ + +#define _IOC_NRBITS 8 +#define _IOC_TYPEBITS 8 +#define _IOC_SIZEBITS 13 +#define _IOC_DIRBITS 3 + +#define _IOC_NRMASK ((1 << _IOC_NRBITS)-1) +#define _IOC_TYPEMASK ((1 << _IOC_TYPEBITS)-1) +#define _IOC_SIZEMASK ((1 << _IOC_SIZEBITS)-1) +#define _IOC_DIRMASK ((1 << _IOC_DIRBITS)-1) + +#define _IOC_NRSHIFT 0 +#define _IOC_TYPESHIFT (_IOC_NRSHIFT+_IOC_NRBITS) +#define _IOC_SIZESHIFT (_IOC_TYPESHIFT+_IOC_TYPEBITS) +#define _IOC_DIRSHIFT (_IOC_SIZESHIFT+_IOC_SIZEBITS) + +/* + * Direction bits _IOC_NONE could be 0, but OSF/1 gives it a bit. + * And this turns out useful to catch old ioctl numbers in header + * files for us. + */ +#define _IOC_NONE 1U +#define _IOC_READ 2U +#define _IOC_WRITE 4U + +#define _IOC(dir,type,nr,size) \ + (((dir) << _IOC_DIRSHIFT) | \ + ((type) << _IOC_TYPESHIFT) | \ + ((nr) << _IOC_NRSHIFT) | \ + ((size) << _IOC_SIZESHIFT)) + +/* provoke compile error for invalid uses of size argument */ +extern unsigned int __invalid_size_argument_for_IOC; +#define _IOC_TYPECHECK(t) \ + ((sizeof(t) == sizeof(t[1]) && \ + sizeof(t) < (1 << _IOC_SIZEBITS)) ? \ + sizeof(t) : __invalid_size_argument_for_IOC) + +/* used to create numbers */ +#define _IO(type,nr) _IOC(_IOC_NONE,(type),(nr),0) +#define _IOR(type,nr,size) _IOC(_IOC_READ,(type),(nr),(_IOC_TYPECHECK(size))) +#define _IOW(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size))) +#define _IOWR(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size))) +#define _IOR_BAD(type,nr,size) _IOC(_IOC_READ,(type),(nr),sizeof(size)) +#define _IOW_BAD(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),sizeof(size)) +#define _IOWR_BAD(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size)) + +/* used to decode them.. */ +#define _IOC_DIR(nr) (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK) +#define _IOC_TYPE(nr) (((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK) +#define _IOC_NR(nr) (((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK) +#define _IOC_SIZE(nr) (((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK) + +/* various drivers, such as the pcmcia stuff, need these... */ +#define IOC_IN (_IOC_WRITE << _IOC_DIRSHIFT) +#define IOC_OUT (_IOC_READ << _IOC_DIRSHIFT) +#define IOC_INOUT ((_IOC_WRITE|_IOC_READ) << _IOC_DIRSHIFT) +#define IOCSIZE_MASK (_IOC_SIZEMASK << _IOC_SIZESHIFT) +#define IOCSIZE_SHIFT (_IOC_SIZESHIFT) + +#endif diff --git a/include/asm-powerpc/ioctls.h b/include/asm-powerpc/ioctls.h new file mode 100644 --- /dev/null +++ b/include/asm-powerpc/ioctls.h @@ -0,0 +1,107 @@ +#ifndef _ASM_PPC_IOCTLS_H +#define _ASM_PPC_IOCTLS_H + +#include + +#define FIOCLEX _IO('f', 1) +#define FIONCLEX _IO('f', 2) +#define FIOASYNC _IOW('f', 125, int) +#define FIONBIO _IOW('f', 126, int) +#define FIONREAD _IOR('f', 127, int) +#define TIOCINQ FIONREAD +#define FIOQSIZE _IOR('f', 128, loff_t) + +#define TIOCGETP _IOR('t', 8, struct sgttyb) +#define TIOCSETP _IOW('t', 9, struct sgttyb) +#define TIOCSETN _IOW('t', 10, struct sgttyb) /* TIOCSETP wo flush */ + +#define TIOCSETC _IOW('t', 17, struct tchars) +#define TIOCGETC _IOR('t', 18, struct tchars) +#define TCGETS _IOR('t', 19, struct termios) +#define TCSETS _IOW('t', 20, struct termios) +#define TCSETSW _IOW('t', 21, struct termios) +#define TCSETSF _IOW('t', 22, struct termios) + +#define TCGETA _IOR('t', 23, struct termio) +#define TCSETA _IOW('t', 24, struct termio) +#define TCSETAW _IOW('t', 25, struct termio) +#define TCSETAF _IOW('t', 28, struct termio) + +#define TCSBRK _IO('t', 29) +#define TCXONC _IO('t', 30) +#define TCFLSH _IO('t', 31) + +#define TIOCSWINSZ _IOW('t', 103, struct winsize) +#define TIOCGWINSZ _IOR('t', 104, struct winsize) +#define TIOCSTART _IO('t', 110) /* start output, like ^Q */ +#define TIOCSTOP _IO('t', 111) /* stop output, like ^S */ +#define TIOCOUTQ _IOR('t', 115, int) /* output queue size */ + +#define TIOCGLTC _IOR('t', 116, struct ltchars) +#define TIOCSLTC _IOW('t', 117, struct ltchars) +#define TIOCSPGRP _IOW('t', 118, int) +#define TIOCGPGRP _IOR('t', 119, int) + +#define TIOCEXCL 0x540C +#define TIOCNXCL 0x540D +#define TIOCSCTTY 0x540E + +#define TIOCSTI 0x5412 +#define TIOCMGET 0x5415 +#define TIOCMBIS 0x5416 +#define TIOCMBIC 0x5417 +#define TIOCMSET 0x5418 +# define TIOCM_LE 0x001 +# define TIOCM_DTR 0x002 +# define TIOCM_RTS 0x004 +# define TIOCM_ST 0x008 +# define TIOCM_SR 0x010 +# define TIOCM_CTS 0x020 +# define TIOCM_CAR 0x040 +# define TIOCM_RNG 0x080 +# define TIOCM_DSR 0x100 +# define TIOCM_CD TIOCM_CAR +# define TIOCM_RI TIOCM_RNG + +#define TIOCGSOFTCAR 0x5419 +#define TIOCSSOFTCAR 0x541A +#define TIOCLINUX 0x541C +#define TIOCCONS 0x541D +#define TIOCGSERIAL 0x541E +#define TIOCSSERIAL 0x541F +#define TIOCPKT 0x5420 +# define TIOCPKT_DATA 0 +# define TIOCPKT_FLUSHREAD 1 +# define TIOCPKT_FLUSHWRITE 2 +# define TIOCPKT_STOP 4 +# define TIOCPKT_START 8 +# define TIOCPKT_NOSTOP 16 +# define TIOCPKT_DOSTOP 32 + + +#define TIOCNOTTY 0x5422 +#define TIOCSETD 0x5423 +#define TIOCGETD 0x5424 +#define TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */ +#define TIOCSBRK 0x5427 /* BSD compatibility */ +#define TIOCCBRK 0x5428 /* BSD compatibility */ +#define TIOCGSID 0x5429 /* Return the session ID of FD */ +#define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */ +#define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */ + +#define TIOCSERCONFIG 0x5453 +#define TIOCSERGWILD 0x5454 +#define TIOCSERSWILD 0x5455 +#define TIOCGLCKTRMIOS 0x5456 +#define TIOCSLCKTRMIOS 0x5457 +#define TIOCSERGSTRUCT 0x5458 /* For debugging only */ +#define TIOCSERGETLSR 0x5459 /* Get line status register */ + /* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */ +# define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ +#define TIOCSERGETMULTI 0x545A /* Get multiport config */ +#define TIOCSERSETMULTI 0x545B /* Set multiport config */ + +#define TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */ +#define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */ + +#endif /* _ASM_PPC_IOCTLS_H */ diff --git a/include/asm-powerpc/local.h b/include/asm-powerpc/local.h new file mode 100644 --- /dev/null +++ b/include/asm-powerpc/local.h @@ -0,0 +1 @@ +#include diff --git a/include/asm-powerpc/namei.h b/include/asm-powerpc/namei.h new file mode 100644 --- /dev/null +++ b/include/asm-powerpc/namei.h @@ -0,0 +1,20 @@ +/* + * include/asm-ppc/namei.h + * Adapted from include/asm-alpha/namei.h + * + * Included from fs/namei.c + */ + +#ifdef __KERNEL__ +#ifndef __PPC_NAMEI_H +#define __PPC_NAMEI_H + +/* This dummy routine maybe changed to something useful + * for /usr/gnemul/ emulation stuff. + * Look at asm-sparc/namei.h for details. + */ + +#define __emul_prefix() NULL + +#endif /* __PPC_NAMEI_H */ +#endif /* __KERNEL__ */ diff --git a/include/asm-powerpc/percpu.h b/include/asm-powerpc/percpu.h new file mode 100644 --- /dev/null +++ b/include/asm-powerpc/percpu.h @@ -0,0 +1 @@ +#include diff --git a/include/asm-powerpc/poll.h b/include/asm-powerpc/poll.h new file mode 100644 --- /dev/null +++ b/include/asm-powerpc/poll.h @@ -0,0 +1,23 @@ +#ifndef __PPC_POLL_H +#define __PPC_POLL_H + +#define POLLIN 0x0001 +#define POLLPRI 0x0002 +#define POLLOUT 0x0004 +#define POLLERR 0x0008 +#define POLLHUP 0x0010 +#define POLLNVAL 0x0020 +#define POLLRDNORM 0x0040 +#define POLLRDBAND 0x0080 +#define POLLWRNORM 0x0100 +#define POLLWRBAND 0x0200 +#define POLLMSG 0x0400 +#define POLLREMOVE 0x1000 + +struct pollfd { + int fd; + short events; + short revents; +}; + +#endif diff --git a/include/asm-powerpc/resource.h b/include/asm-powerpc/resource.h new file mode 100644 --- /dev/null +++ b/include/asm-powerpc/resource.h @@ -0,0 +1 @@ +#include diff --git a/include/asm-powerpc/shmparam.h b/include/asm-powerpc/shmparam.h new file mode 100644 --- /dev/null +++ b/include/asm-powerpc/shmparam.h @@ -0,0 +1,6 @@ +#ifndef _PPC_SHMPARAM_H +#define _PPC_SHMPARAM_H + +#define SHMLBA PAGE_SIZE /* attach addr a multiple of this */ + +#endif /* _PPC_SHMPARAM_H */ diff --git a/include/asm-powerpc/string.h b/include/asm-powerpc/string.h new file mode 100644 --- /dev/null +++ b/include/asm-powerpc/string.h @@ -0,0 +1,32 @@ +#ifndef _PPC_STRING_H_ +#define _PPC_STRING_H_ + +#ifdef __KERNEL__ + +#define __HAVE_ARCH_STRCPY +#define __HAVE_ARCH_STRNCPY +#define __HAVE_ARCH_STRLEN +#define __HAVE_ARCH_STRCMP +#define __HAVE_ARCH_STRCAT +#define __HAVE_ARCH_MEMSET +#define __HAVE_ARCH_MEMCPY +#define __HAVE_ARCH_MEMMOVE +#define __HAVE_ARCH_MEMCMP +#define __HAVE_ARCH_MEMCHR + +extern int strcasecmp(const char *, const char *); +extern int strncasecmp(const char *, const char *, int); +extern char * strcpy(char *,const char *); +extern char * strncpy(char *,const char *, __kernel_size_t); +extern __kernel_size_t strlen(const char *); +extern int strcmp(const char *,const char *); +extern char * strcat(char *, const char *); +extern void * memset(void *,int,__kernel_size_t); +extern void * memcpy(void *,const void *,__kernel_size_t); +extern void * memmove(void *,const void *,__kernel_size_t); +extern int memcmp(const void *,const void *,__kernel_size_t); +extern void * memchr(const void *,int,__kernel_size_t); + +#endif /* __KERNEL__ */ + +#endif diff --git a/include/asm-powerpc/unaligned.h b/include/asm-powerpc/unaligned.h new file mode 100644 --- /dev/null +++ b/include/asm-powerpc/unaligned.h @@ -0,0 +1,18 @@ +#ifdef __KERNEL__ +#ifndef __PPC_UNALIGNED_H +#define __PPC_UNALIGNED_H + +/* + * The PowerPC can do unaligned accesses itself in big endian mode. + * + * The strange macros are there to make sure these can't + * be misused in a way that makes them not work on other + * architectures where unaligned accesses aren't as simple. + */ + +#define get_unaligned(ptr) (*(ptr)) + +#define put_unaligned(val, ptr) ((void)( *(ptr) = (val) )) + +#endif +#endif /* __KERNEL__ */ diff --git a/include/asm-ppc/errno.h b/include/asm-ppc/errno.h deleted file mode 100644 --- a/include/asm-ppc/errno.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef _PPC_ERRNO_H -#define _PPC_ERRNO_H - -#include - -#undef EDEADLOCK -#define EDEADLOCK 58 /* File locking deadlock error */ - -#define _LAST_ERRNO 516 - -#endif diff --git a/include/asm-ppc/ioctl.h b/include/asm-ppc/ioctl.h deleted file mode 100644 --- a/include/asm-ppc/ioctl.h +++ /dev/null @@ -1,69 +0,0 @@ -#ifndef _PPC_IOCTL_H -#define _PPC_IOCTL_H - - -/* - * this was copied from the alpha as it's a bit cleaner there. - * -- Cort - */ - -#define _IOC_NRBITS 8 -#define _IOC_TYPEBITS 8 -#define _IOC_SIZEBITS 13 -#define _IOC_DIRBITS 3 - -#define _IOC_NRMASK ((1 << _IOC_NRBITS)-1) -#define _IOC_TYPEMASK ((1 << _IOC_TYPEBITS)-1) -#define _IOC_SIZEMASK ((1 << _IOC_SIZEBITS)-1) -#define _IOC_DIRMASK ((1 << _IOC_DIRBITS)-1) - -#define _IOC_NRSHIFT 0 -#define _IOC_TYPESHIFT (_IOC_NRSHIFT+_IOC_NRBITS) -#define _IOC_SIZESHIFT (_IOC_TYPESHIFT+_IOC_TYPEBITS) -#define _IOC_DIRSHIFT (_IOC_SIZESHIFT+_IOC_SIZEBITS) - -/* - * Direction bits _IOC_NONE could be 0, but OSF/1 gives it a bit. - * And this turns out useful to catch old ioctl numbers in header - * files for us. - */ -#define _IOC_NONE 1U -#define _IOC_READ 2U -#define _IOC_WRITE 4U - -#define _IOC(dir,type,nr,size) \ - (((dir) << _IOC_DIRSHIFT) | \ - ((type) << _IOC_TYPESHIFT) | \ - ((nr) << _IOC_NRSHIFT) | \ - ((size) << _IOC_SIZESHIFT)) - -/* provoke compile error for invalid uses of size argument */ -extern unsigned int __invalid_size_argument_for_IOC; -#define _IOC_TYPECHECK(t) \ - ((sizeof(t) == sizeof(t[1]) && \ - sizeof(t) < (1 << _IOC_SIZEBITS)) ? \ - sizeof(t) : __invalid_size_argument_for_IOC) - -/* used to create numbers */ -#define _IO(type,nr) _IOC(_IOC_NONE,(type),(nr),0) -#define _IOR(type,nr,size) _IOC(_IOC_READ,(type),(nr),(_IOC_TYPECHECK(size))) -#define _IOW(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size))) -#define _IOWR(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size))) -#define _IOR_BAD(type,nr,size) _IOC(_IOC_READ,(type),(nr),sizeof(size)) -#define _IOW_BAD(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),sizeof(size)) -#define _IOWR_BAD(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size)) - -/* used to decode them.. */ -#define _IOC_DIR(nr) (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK) -#define _IOC_TYPE(nr) (((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK) -#define _IOC_NR(nr) (((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK) -#define _IOC_SIZE(nr) (((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK) - -/* various drivers, such as the pcmcia stuff, need these... */ -#define IOC_IN (_IOC_WRITE << _IOC_DIRSHIFT) -#define IOC_OUT (_IOC_READ << _IOC_DIRSHIFT) -#define IOC_INOUT ((_IOC_WRITE|_IOC_READ) << _IOC_DIRSHIFT) -#define IOCSIZE_MASK (_IOC_SIZEMASK << _IOC_SIZESHIFT) -#define IOCSIZE_SHIFT (_IOC_SIZESHIFT) - -#endif diff --git a/include/asm-ppc/ioctls.h b/include/asm-ppc/ioctls.h deleted file mode 100644 --- a/include/asm-ppc/ioctls.h +++ /dev/null @@ -1,107 +0,0 @@ -#ifndef _ASM_PPC_IOCTLS_H -#define _ASM_PPC_IOCTLS_H - -#include - -#define FIOCLEX _IO('f', 1) -#define FIONCLEX _IO('f', 2) -#define FIOASYNC _IOW('f', 125, int) -#define FIONBIO _IOW('f', 126, int) -#define FIONREAD _IOR('f', 127, int) -#define TIOCINQ FIONREAD -#define FIOQSIZE _IOR('f', 128, loff_t) - -#define TIOCGETP _IOR('t', 8, struct sgttyb) -#define TIOCSETP _IOW('t', 9, struct sgttyb) -#define TIOCSETN _IOW('t', 10, struct sgttyb) /* TIOCSETP wo flush */ - -#define TIOCSETC _IOW('t', 17, struct tchars) -#define TIOCGETC _IOR('t', 18, struct tchars) -#define TCGETS _IOR('t', 19, struct termios) -#define TCSETS _IOW('t', 20, struct termios) -#define TCSETSW _IOW('t', 21, struct termios) -#define TCSETSF _IOW('t', 22, struct termios) - -#define TCGETA _IOR('t', 23, struct termio) -#define TCSETA _IOW('t', 24, struct termio) -#define TCSETAW _IOW('t', 25, struct termio) -#define TCSETAF _IOW('t', 28, struct termio) - -#define TCSBRK _IO('t', 29) -#define TCXONC _IO('t', 30) -#define TCFLSH _IO('t', 31) - -#define TIOCSWINSZ _IOW('t', 103, struct winsize) -#define TIOCGWINSZ _IOR('t', 104, struct winsize) -#define TIOCSTART _IO('t', 110) /* start output, like ^Q */ -#define TIOCSTOP _IO('t', 111) /* stop output, like ^S */ -#define TIOCOUTQ _IOR('t', 115, int) /* output queue size */ - -#define TIOCGLTC _IOR('t', 116, struct ltchars) -#define TIOCSLTC _IOW('t', 117, struct ltchars) -#define TIOCSPGRP _IOW('t', 118, int) -#define TIOCGPGRP _IOR('t', 119, int) - -#define TIOCEXCL 0x540C -#define TIOCNXCL 0x540D -#define TIOCSCTTY 0x540E - -#define TIOCSTI 0x5412 -#define TIOCMGET 0x5415 -#define TIOCMBIS 0x5416 -#define TIOCMBIC 0x5417 -#define TIOCMSET 0x5418 -# define TIOCM_LE 0x001 -# define TIOCM_DTR 0x002 -# define TIOCM_RTS 0x004 -# define TIOCM_ST 0x008 -# define TIOCM_SR 0x010 -# define TIOCM_CTS 0x020 -# define TIOCM_CAR 0x040 -# define TIOCM_RNG 0x080 -# define TIOCM_DSR 0x100 -# define TIOCM_CD TIOCM_CAR -# define TIOCM_RI TIOCM_RNG - -#define TIOCGSOFTCAR 0x5419 -#define TIOCSSOFTCAR 0x541A -#define TIOCLINUX 0x541C -#define TIOCCONS 0x541D -#define TIOCGSERIAL 0x541E -#define TIOCSSERIAL 0x541F -#define TIOCPKT 0x5420 -# define TIOCPKT_DATA 0 -# define TIOCPKT_FLUSHREAD 1 -# define TIOCPKT_FLUSHWRITE 2 -# define TIOCPKT_STOP 4 -# define TIOCPKT_START 8 -# define TIOCPKT_NOSTOP 16 -# define TIOCPKT_DOSTOP 32 - - -#define TIOCNOTTY 0x5422 -#define TIOCSETD 0x5423 -#define TIOCGETD 0x5424 -#define TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */ -#define TIOCSBRK 0x5427 /* BSD compatibility */ -#define TIOCCBRK 0x5428 /* BSD compatibility */ -#define TIOCGSID 0x5429 /* Return the session ID of FD */ -#define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */ -#define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */ - -#define TIOCSERCONFIG 0x5453 -#define TIOCSERGWILD 0x5454 -#define TIOCSERSWILD 0x5455 -#define TIOCGLCKTRMIOS 0x5456 -#define TIOCSLCKTRMIOS 0x5457 -#define TIOCSERGSTRUCT 0x5458 /* For debugging only */ -#define TIOCSERGETLSR 0x5459 /* Get line status register */ - /* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */ -# define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ -#define TIOCSERGETMULTI 0x545A /* Get multiport config */ -#define TIOCSERSETMULTI 0x545B /* Set multiport config */ - -#define TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */ -#define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */ - -#endif /* _ASM_PPC_IOCTLS_H */ diff --git a/include/asm-ppc/local.h b/include/asm-ppc/local.h deleted file mode 100644 --- a/include/asm-ppc/local.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __PPC_LOCAL_H -#define __PPC_LOCAL_H - -#include - -#endif /* __PPC_LOCAL_H */ diff --git a/include/asm-ppc/namei.h b/include/asm-ppc/namei.h deleted file mode 100644 --- a/include/asm-ppc/namei.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * include/asm-ppc/namei.h - * Adapted from include/asm-alpha/namei.h - * - * Included from fs/namei.c - */ - -#ifdef __KERNEL__ -#ifndef __PPC_NAMEI_H -#define __PPC_NAMEI_H - -/* This dummy routine maybe changed to something useful - * for /usr/gnemul/ emulation stuff. - * Look at asm-sparc/namei.h for details. - */ - -#define __emul_prefix() NULL - -#endif /* __PPC_NAMEI_H */ -#endif /* __KERNEL__ */ diff --git a/include/asm-ppc/percpu.h b/include/asm-ppc/percpu.h deleted file mode 100644 --- a/include/asm-ppc/percpu.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __ARCH_PPC_PERCPU__ -#define __ARCH_PPC_PERCPU__ - -#include - -#endif /* __ARCH_PPC_PERCPU__ */ diff --git a/include/asm-ppc/poll.h b/include/asm-ppc/poll.h deleted file mode 100644 --- a/include/asm-ppc/poll.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef __PPC_POLL_H -#define __PPC_POLL_H - -#define POLLIN 0x0001 -#define POLLPRI 0x0002 -#define POLLOUT 0x0004 -#define POLLERR 0x0008 -#define POLLHUP 0x0010 -#define POLLNVAL 0x0020 -#define POLLRDNORM 0x0040 -#define POLLRDBAND 0x0080 -#define POLLWRNORM 0x0100 -#define POLLWRBAND 0x0200 -#define POLLMSG 0x0400 -#define POLLREMOVE 0x1000 - -struct pollfd { - int fd; - short events; - short revents; -}; - -#endif diff --git a/include/asm-ppc/resource.h b/include/asm-ppc/resource.h deleted file mode 100644 --- a/include/asm-ppc/resource.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _PPC_RESOURCE_H -#define _PPC_RESOURCE_H - -#include - -#endif diff --git a/include/asm-ppc/shmparam.h b/include/asm-ppc/shmparam.h deleted file mode 100644 --- a/include/asm-ppc/shmparam.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _PPC_SHMPARAM_H -#define _PPC_SHMPARAM_H - -#define SHMLBA PAGE_SIZE /* attach addr a multiple of this */ - -#endif /* _PPC_SHMPARAM_H */ diff --git a/include/asm-ppc/string.h b/include/asm-ppc/string.h deleted file mode 100644 --- a/include/asm-ppc/string.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef _PPC_STRING_H_ -#define _PPC_STRING_H_ - -#ifdef __KERNEL__ - -#define __HAVE_ARCH_STRCPY -#define __HAVE_ARCH_STRNCPY -#define __HAVE_ARCH_STRLEN -#define __HAVE_ARCH_STRCMP -#define __HAVE_ARCH_STRCAT -#define __HAVE_ARCH_MEMSET -#define __HAVE_ARCH_MEMCPY -#define __HAVE_ARCH_MEMMOVE -#define __HAVE_ARCH_MEMCMP -#define __HAVE_ARCH_MEMCHR - -extern int strcasecmp(const char *, const char *); -extern int strncasecmp(const char *, const char *, int); -extern char * strcpy(char *,const char *); -extern char * strncpy(char *,const char *, __kernel_size_t); -extern __kernel_size_t strlen(const char *); -extern int strcmp(const char *,const char *); -extern char * strcat(char *, const char *); -extern void * memset(void *,int,__kernel_size_t); -extern void * memcpy(void *,const void *,__kernel_size_t); -extern void * memmove(void *,const void *,__kernel_size_t); -extern int memcmp(const void *,const void *,__kernel_size_t); -extern void * memchr(const void *,int,__kernel_size_t); - -#endif /* __KERNEL__ */ - -#endif diff --git a/include/asm-ppc/unaligned.h b/include/asm-ppc/unaligned.h deleted file mode 100644 --- a/include/asm-ppc/unaligned.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifdef __KERNEL__ -#ifndef __PPC_UNALIGNED_H -#define __PPC_UNALIGNED_H - -/* - * The PowerPC can do unaligned accesses itself in big endian mode. - * - * The strange macros are there to make sure these can't - * be misused in a way that makes them not work on other - * architectures where unaligned accesses aren't as simple. - */ - -#define get_unaligned(ptr) (*(ptr)) - -#define put_unaligned(val, ptr) ((void)( *(ptr) = (val) )) - -#endif -#endif /* __KERNEL__ */ diff --git a/include/asm-ppc64/errno.h b/include/asm-ppc64/errno.h deleted file mode 100644 --- a/include/asm-ppc64/errno.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef _PPC64_ERRNO_H -#define _PPC64_ERRNO_H - -/* - * 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 - -#undef EDEADLOCK -#define EDEADLOCK 58 /* File locking deadlock error */ - -#define _LAST_ERRNO 516 - -#endif diff --git a/include/asm-ppc64/ioctl.h b/include/asm-ppc64/ioctl.h deleted file mode 100644 --- a/include/asm-ppc64/ioctl.h +++ /dev/null @@ -1,74 +0,0 @@ -#ifndef _PPC64_IOCTL_H -#define _PPC64_IOCTL_H - - -/* - * This was copied from the alpha as it's a bit cleaner there. - * -- Cort - * - * 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. - */ - -#define _IOC_NRBITS 8 -#define _IOC_TYPEBITS 8 -#define _IOC_SIZEBITS 13 -#define _IOC_DIRBITS 3 - -#define _IOC_NRMASK ((1 << _IOC_NRBITS)-1) -#define _IOC_TYPEMASK ((1 << _IOC_TYPEBITS)-1) -#define _IOC_SIZEMASK ((1 << _IOC_SIZEBITS)-1) -#define _IOC_DIRMASK ((1 << _IOC_DIRBITS)-1) - -#define _IOC_NRSHIFT 0 -#define _IOC_TYPESHIFT (_IOC_NRSHIFT+_IOC_NRBITS) -#define _IOC_SIZESHIFT (_IOC_TYPESHIFT+_IOC_TYPEBITS) -#define _IOC_DIRSHIFT (_IOC_SIZESHIFT+_IOC_SIZEBITS) - -/* - * Direction bits _IOC_NONE could be 0, but OSF/1 gives it a bit. - * And this turns out useful to catch old ioctl numbers in header - * files for us. - */ -#define _IOC_NONE 1U -#define _IOC_READ 2U -#define _IOC_WRITE 4U - -#define _IOC(dir,type,nr,size) \ - (((dir) << _IOC_DIRSHIFT) | \ - ((type) << _IOC_TYPESHIFT) | \ - ((nr) << _IOC_NRSHIFT) | \ - ((size) << _IOC_SIZESHIFT)) - -/* provoke compile error for invalid uses of size argument */ -extern unsigned int __invalid_size_argument_for_IOC; -#define _IOC_TYPECHECK(t) \ - ((sizeof(t) == sizeof(t[1]) && \ - sizeof(t) < (1 << _IOC_SIZEBITS)) ? \ - sizeof(t) : __invalid_size_argument_for_IOC) - -/* used to create numbers */ -#define _IO(type,nr) _IOC(_IOC_NONE,(type),(nr),0) -#define _IOR(type,nr,size) _IOC(_IOC_READ,(type),(nr),(_IOC_TYPECHECK(size))) -#define _IOW(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size))) -#define _IOWR(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size))) -#define _IOR_BAD(type,nr,size) _IOC(_IOC_READ,(type),(nr),sizeof(size)) -#define _IOW_BAD(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),sizeof(size)) -#define _IOWR_BAD(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size)) - -/* used to decode them.. */ -#define _IOC_DIR(nr) (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK) -#define _IOC_TYPE(nr) (((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK) -#define _IOC_NR(nr) (((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK) -#define _IOC_SIZE(nr) (((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK) - -/* various drivers, such as the pcmcia stuff, need these... */ -#define IOC_IN (_IOC_WRITE << _IOC_DIRSHIFT) -#define IOC_OUT (_IOC_READ << _IOC_DIRSHIFT) -#define IOC_INOUT ((_IOC_WRITE|_IOC_READ) << _IOC_DIRSHIFT) -#define IOCSIZE_MASK (_IOC_SIZEMASK << _IOC_SIZESHIFT) -#define IOCSIZE_SHIFT (_IOC_SIZESHIFT) - -#endif /* _PPC64_IOCTL_H */ diff --git a/include/asm-ppc64/ioctls.h b/include/asm-ppc64/ioctls.h deleted file mode 100644 --- a/include/asm-ppc64/ioctls.h +++ /dev/null @@ -1,114 +0,0 @@ -#ifndef _ASM_PPC64_IOCTLS_H -#define _ASM_PPC64_IOCTLS_H - -/* - * 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 - -#define FIOCLEX _IO('f', 1) -#define FIONCLEX _IO('f', 2) -#define FIOASYNC _IOW('f', 125, int) -#define FIONBIO _IOW('f', 126, int) -#define FIONREAD _IOR('f', 127, int) -#define TIOCINQ FIONREAD -#define FIOQSIZE _IOR('f', 128, loff_t) - -#define TIOCGETP _IOR('t', 8, struct sgttyb) -#define TIOCSETP _IOW('t', 9, struct sgttyb) -#define TIOCSETN _IOW('t', 10, struct sgttyb) /* TIOCSETP wo flush */ - -#define TIOCSETC _IOW('t', 17, struct tchars) -#define TIOCGETC _IOR('t', 18, struct tchars) -#define TCGETS _IOR('t', 19, struct termios) -#define TCSETS _IOW('t', 20, struct termios) -#define TCSETSW _IOW('t', 21, struct termios) -#define TCSETSF _IOW('t', 22, struct termios) - -#define TCGETA _IOR('t', 23, struct termio) -#define TCSETA _IOW('t', 24, struct termio) -#define TCSETAW _IOW('t', 25, struct termio) -#define TCSETAF _IOW('t', 28, struct termio) - -#define TCSBRK _IO('t', 29) -#define TCXONC _IO('t', 30) -#define TCFLSH _IO('t', 31) - -#define TIOCSWINSZ _IOW('t', 103, struct winsize) -#define TIOCGWINSZ _IOR('t', 104, struct winsize) -#define TIOCSTART _IO('t', 110) /* start output, like ^Q */ -#define TIOCSTOP _IO('t', 111) /* stop output, like ^S */ -#define TIOCOUTQ _IOR('t', 115, int) /* output queue size */ - -#define TIOCGLTC _IOR('t', 116, struct ltchars) -#define TIOCSLTC _IOW('t', 117, struct ltchars) -#define TIOCSPGRP _IOW('t', 118, int) -#define TIOCGPGRP _IOR('t', 119, int) - -#define TIOCEXCL 0x540C -#define TIOCNXCL 0x540D -#define TIOCSCTTY 0x540E - -#define TIOCSTI 0x5412 -#define TIOCMGET 0x5415 -#define TIOCMBIS 0x5416 -#define TIOCMBIC 0x5417 -#define TIOCMSET 0x5418 -# define TIOCM_LE 0x001 -# define TIOCM_DTR 0x002 -# define TIOCM_RTS 0x004 -# define TIOCM_ST 0x008 -# define TIOCM_SR 0x010 -# define TIOCM_CTS 0x020 -# define TIOCM_CAR 0x040 -# define TIOCM_RNG 0x080 -# define TIOCM_DSR 0x100 -# define TIOCM_CD TIOCM_CAR -# define TIOCM_RI TIOCM_RNG - -#define TIOCGSOFTCAR 0x5419 -#define TIOCSSOFTCAR 0x541A -#define TIOCLINUX 0x541C -#define TIOCCONS 0x541D -#define TIOCGSERIAL 0x541E -#define TIOCSSERIAL 0x541F -#define TIOCPKT 0x5420 -# define TIOCPKT_DATA 0 -# define TIOCPKT_FLUSHREAD 1 -# define TIOCPKT_FLUSHWRITE 2 -# define TIOCPKT_STOP 4 -# define TIOCPKT_START 8 -# define TIOCPKT_NOSTOP 16 -# define TIOCPKT_DOSTOP 32 - - -#define TIOCNOTTY 0x5422 -#define TIOCSETD 0x5423 -#define TIOCGETD 0x5424 -#define TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */ -#define TIOCSBRK 0x5427 /* BSD compatibility */ -#define TIOCCBRK 0x5428 /* BSD compatibility */ -#define TIOCGSID 0x5429 /* Return the session ID of FD */ -#define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */ -#define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */ - -#define TIOCSERCONFIG 0x5453 -#define TIOCSERGWILD 0x5454 -#define TIOCSERSWILD 0x5455 -#define TIOCGLCKTRMIOS 0x5456 -#define TIOCSLCKTRMIOS 0x5457 -#define TIOCSERGSTRUCT 0x5458 /* For debugging only */ -#define TIOCSERGETLSR 0x5459 /* Get line status register */ - /* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */ -# define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ -#define TIOCSERGETMULTI 0x545A /* Get multiport config */ -#define TIOCSERSETMULTI 0x545B /* Set multiport config */ - -#define TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */ -#define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */ - -#endif /* _ASM_PPC64_IOCTLS_H */ diff --git a/include/asm-ppc64/local.h b/include/asm-ppc64/local.h deleted file mode 100644 --- a/include/asm-ppc64/local.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/include/asm-ppc64/namei.h b/include/asm-ppc64/namei.h deleted file mode 100644 --- a/include/asm-ppc64/namei.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * linux/include/asm-ppc/namei.h - * Adapted from linux/include/asm-alpha/namei.h - * - * Included from linux/fs/namei.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. - */ - -#ifndef __PPC64_NAMEI_H -#define __PPC64_NAMEI_H - -/* This dummy routine maybe changed to something useful - * for /usr/gnemul/ emulation stuff. - * Look at asm-sparc/namei.h for details. - */ - -#define __emul_prefix() NULL - -#endif /* __PPC64_NAMEI_H */ diff --git a/include/asm-ppc64/percpu.h b/include/asm-ppc64/percpu.h deleted file mode 100644 --- a/include/asm-ppc64/percpu.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __ARCH_PPC64_PERCPU__ -#define __ARCH_PPC64_PERCPU__ - -#include - -#endif /* __ARCH_PPC64_PERCPU__ */ diff --git a/include/asm-ppc64/poll.h b/include/asm-ppc64/poll.h deleted file mode 100644 --- a/include/asm-ppc64/poll.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef __PPC64_POLL_H -#define __PPC64_POLL_H - -/* - * Copyright (C) 2001 PPC64 Team, IBM Corp - * - * 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. - */ - -#define POLLIN 0x0001 -#define POLLPRI 0x0002 -#define POLLOUT 0x0004 -#define POLLERR 0x0008 -#define POLLHUP 0x0010 -#define POLLNVAL 0x0020 -#define POLLRDNORM 0x0040 -#define POLLRDBAND 0x0080 -#define POLLWRNORM 0x0100 -#define POLLWRBAND 0x0200 -#define POLLMSG 0x0400 -#define POLLREMOVE 0x1000 - -struct pollfd { - int fd; - short events; - short revents; -}; - -#endif /* __PPC64_POLL_H */ diff --git a/include/asm-ppc64/resource.h b/include/asm-ppc64/resource.h deleted file mode 100644 --- a/include/asm-ppc64/resource.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _PPC64_RESOURCE_H -#define _PPC64_RESOURCE_H - -#include - -#endif /* _PPC64_RESOURCE_H */ diff --git a/include/asm-ppc64/shmparam.h b/include/asm-ppc64/shmparam.h deleted file mode 100644 --- a/include/asm-ppc64/shmparam.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef _PPC64_SHMPARAM_H -#define _PPC64_SHMPARAM_H - -/* - * 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. - */ - -#define SHMLBA PAGE_SIZE /* attach addr a multiple of this */ - -#endif /* _PPC64_SHMPARAM_H */ diff --git a/include/asm-ppc64/string.h b/include/asm-ppc64/string.h deleted file mode 100644 --- a/include/asm-ppc64/string.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef _PPC64_STRING_H_ -#define _PPC64_STRING_H_ - -/* - * 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. - */ - -#define __HAVE_ARCH_STRCPY -#define __HAVE_ARCH_STRNCPY -#define __HAVE_ARCH_STRLEN -#define __HAVE_ARCH_STRCMP -#define __HAVE_ARCH_STRCAT -#define __HAVE_ARCH_MEMSET -#define __HAVE_ARCH_MEMCPY -#define __HAVE_ARCH_MEMMOVE -#define __HAVE_ARCH_MEMCMP -#define __HAVE_ARCH_MEMCHR - -extern int strcasecmp(const char *, const char *); -extern int strncasecmp(const char *, const char *, int); -extern char * strcpy(char *,const char *); -extern char * strncpy(char *,const char *, __kernel_size_t); -extern __kernel_size_t strlen(const char *); -extern int strcmp(const char *,const char *); -extern char * strcat(char *, const char *); -extern void * memset(void *,int,__kernel_size_t); -extern void * memcpy(void *,const void *,__kernel_size_t); -extern void * memmove(void *,const void *,__kernel_size_t); -extern int memcmp(const void *,const void *,__kernel_size_t); -extern void * memchr(const void *,int,__kernel_size_t); - -#endif /* _PPC64_STRING_H_ */ diff --git a/include/asm-ppc64/unaligned.h b/include/asm-ppc64/unaligned.h deleted file mode 100644 --- a/include/asm-ppc64/unaligned.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef __PPC64_UNALIGNED_H -#define __PPC64_UNALIGNED_H - -/* - * The PowerPC can do unaligned accesses itself in big endian mode. - * - * The strange macros are there to make sure these can't - * be misused in a way that makes them not work on other - * architectures where unaligned accesses aren't as simple. - * - * 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. - */ - -#define get_unaligned(ptr) (*(ptr)) - -#define put_unaligned(val, ptr) ((void)( *(ptr) = (val) )) - -#endif /* __PPC64_UNALIGNED_H */ From paulus at samba.org Mon Aug 29 16:40:20 2005 From: paulus at samba.org (Paul Mackerras) Date: Mon, 29 Aug 2005 16:40:20 +1000 Subject: [patch 8/8] PCI Error Recovery: PPC64 core recovery routines In-Reply-To: <20050825161325.GG25174@austin.ibm.com> References: <20050823231817.829359000@bilge> <20050823232143.003048000@bilge> <20050823234747.GI18113@austin.ibm.com> <1124898331.24668.33.camel@sinatra.austin.ibm.com> <20050824162959.GC25174@austin.ibm.com> <17165.3205.505386.187453@cargo.ozlabs.ibm.com> <20050825161325.GG25174@austin.ibm.com> Message-ID: <17170.44500.848623.139474@cargo.ozlabs.ibm.com> Linas Vepstas writes: > Actually, no. There are three issues: > 1) hotplug routines are called from within kernel. GregKH has stated on > multiple occasions that doing this is wrong/bad/evil. This includes > calling hot-unplug. > > 2) As a result, the code to call hot-unplug is a bit messy. In > particular, there's a bit of hoop-jumping when hotplug is built as > as a module (and said hoops were wrecked recently when I moved the > code around, out of the rpaphp directory). One way to clean this up would be to make rpaphp the driver for the EADS bridges (from the pci code's point of view). Then it would automatically get included in the error recovery process and could do whatever it should. > 3) Hot-unplug causes scripts to run in user-space. There is no way to > know when these scripts are done, so its not clear if we've waited > long enough before calling hot-add (or if waiting is even necessary). OK, so let's just add a new hotplug event called KOBJ_ERROR or something, which tells userspace that an error has occurred which has made the device inaccessible. Greg, would that be OK? The only trouble with that is that if we don't have a hotplug bridge driver loaded for the slot, we can't tell the driver that its device has gone away. I guess that's not a big problem in practice. Paul. From arnd at arndb.de Mon Aug 29 16:45:33 2005 From: arnd at arndb.de (Arnd Bergmann) Date: Mon, 29 Aug 2005 08:45:33 +0200 Subject: [PATCH 0/3] Start the merge In-Reply-To: <20050829130133.519391c6.sfr@canb.auug.org.au> References: <20050829130133.519391c6.sfr@canb.auug.org.au> Message-ID: <200508290845.34544.arnd@arndb.de> On Maandag 29 August 2005 05:01, Stephen Rothwell wrote: > Please send at least the first upstream. The other two can also probably > be sent. These certainly look good to me. This is another patch to merge the atomic.h file. It is not completely trivial and changes the semantics for 32 bit SMP systems, which previously did not do EIEIO_ON_SMP within the atomic operations. AFAICT, that was a bug in the 32 bit version, which is now fixed as a side-effect of the merge. The combined version of this file also prevents building user space applications using atomic.h on ppc64. That was already impossible on 32 bit ppc, but probably also created broken output on ppc64. Signed-off-by: Arnd Bergmann -- include/asm-ppc/atomic.h | 214 ------------------------------ include/asm-ppc64/atomic.h | 197 --------------------------- include/asm-ppc64/memory.h | 59 -------- linux-2.6.12/include/asm-powerpc/atomic.h | 209 +++++++++++++++++++++++++++++ linux-2.6.12/include/asm-powerpc/memory.h | 59 ++++++++ linux-2.6.12/include/asm-ppc/io.h | 11 - 6 files changed, 269 insertions(+), 480 deletions(-) Index: linux-2.6.12/include/asm-ppc/atomic.h =================================================================== --- linux-2.6.12.orig/include/asm-ppc/atomic.h 2005-08-29 08:04:06.000000000 +0200 +++ /dev/null 1970-01-01 00:00:00.000000000 +0000 @@ -1,214 +0,0 @@ -/* - * PowerPC atomic operations - */ - -#ifndef _ASM_PPC_ATOMIC_H_ -#define _ASM_PPC_ATOMIC_H_ - -typedef struct { volatile int counter; } atomic_t; - -#ifdef __KERNEL__ - -#define ATOMIC_INIT(i) { (i) } - -#define atomic_read(v) ((v)->counter) -#define atomic_set(v,i) (((v)->counter) = (i)) - -extern void atomic_clear_mask(unsigned long mask, unsigned long *addr); - -#ifdef CONFIG_SMP -#define SMP_SYNC "sync" -#define SMP_ISYNC "\n\tisync" -#else -#define SMP_SYNC "" -#define SMP_ISYNC -#endif - -/* Erratum #77 on the 405 means we need a sync or dcbt before every stwcx. - * The old ATOMIC_SYNC_FIX covered some but not all of this. - */ -#ifdef CONFIG_IBM405_ERR77 -#define PPC405_ERR77(ra,rb) "dcbt " #ra "," #rb ";" -#else -#define PPC405_ERR77(ra,rb) -#endif - -static __inline__ void atomic_add(int a, atomic_t *v) -{ - int t; - - __asm__ __volatile__( -"1: lwarx %0,0,%3 # atomic_add\n\ - add %0,%2,%0\n" - PPC405_ERR77(0,%3) -" stwcx. %0,0,%3 \n\ - bne- 1b" - : "=&r" (t), "=m" (v->counter) - : "r" (a), "r" (&v->counter), "m" (v->counter) - : "cc"); -} - -static __inline__ int atomic_add_return(int a, atomic_t *v) -{ - int t; - - __asm__ __volatile__( -"1: lwarx %0,0,%2 # atomic_add_return\n\ - add %0,%1,%0\n" - PPC405_ERR77(0,%2) -" stwcx. %0,0,%2 \n\ - bne- 1b" - SMP_ISYNC - : "=&r" (t) - : "r" (a), "r" (&v->counter) - : "cc", "memory"); - - return t; -} - -#define atomic_add_negative(a, v) (atomic_add_return((a), (v)) < 0) - -static __inline__ void atomic_sub(int a, atomic_t *v) -{ - int t; - - __asm__ __volatile__( -"1: lwarx %0,0,%3 # atomic_sub\n\ - subf %0,%2,%0\n" - PPC405_ERR77(0,%3) -" stwcx. %0,0,%3 \n\ - bne- 1b" - : "=&r" (t), "=m" (v->counter) - : "r" (a), "r" (&v->counter), "m" (v->counter) - : "cc"); -} - -static __inline__ int atomic_sub_return(int a, atomic_t *v) -{ - int t; - - __asm__ __volatile__( -"1: lwarx %0,0,%2 # atomic_sub_return\n\ - subf %0,%1,%0\n" - PPC405_ERR77(0,%2) -" stwcx. %0,0,%2 \n\ - bne- 1b" - SMP_ISYNC - : "=&r" (t) - : "r" (a), "r" (&v->counter) - : "cc", "memory"); - - return t; -} - -static __inline__ void atomic_inc(atomic_t *v) -{ - int t; - - __asm__ __volatile__( -"1: lwarx %0,0,%2 # atomic_inc\n\ - addic %0,%0,1\n" - PPC405_ERR77(0,%2) -" stwcx. %0,0,%2 \n\ - bne- 1b" - : "=&r" (t), "=m" (v->counter) - : "r" (&v->counter), "m" (v->counter) - : "cc"); -} - -static __inline__ int atomic_inc_return(atomic_t *v) -{ - int t; - - __asm__ __volatile__( -"1: lwarx %0,0,%1 # atomic_inc_return\n\ - addic %0,%0,1\n" - PPC405_ERR77(0,%1) -" stwcx. %0,0,%1 \n\ - bne- 1b" - SMP_ISYNC - : "=&r" (t) - : "r" (&v->counter) - : "cc", "memory"); - - return t; -} - -/* - * atomic_inc_and_test - increment and test - * @v: pointer of type atomic_t - * - * Atomically increments @v by 1 - * and returns true if the result is zero, or false for all - * other cases. - */ -#define atomic_inc_and_test(v) (atomic_inc_return(v) == 0) - -static __inline__ void atomic_dec(atomic_t *v) -{ - int t; - - __asm__ __volatile__( -"1: lwarx %0,0,%2 # atomic_dec\n\ - addic %0,%0,-1\n" - PPC405_ERR77(0,%2)\ -" stwcx. %0,0,%2\n\ - bne- 1b" - : "=&r" (t), "=m" (v->counter) - : "r" (&v->counter), "m" (v->counter) - : "cc"); -} - -static __inline__ int atomic_dec_return(atomic_t *v) -{ - int t; - - __asm__ __volatile__( -"1: lwarx %0,0,%1 # atomic_dec_return\n\ - addic %0,%0,-1\n" - PPC405_ERR77(0,%1) -" stwcx. %0,0,%1\n\ - bne- 1b" - SMP_ISYNC - : "=&r" (t) - : "r" (&v->counter) - : "cc", "memory"); - - return t; -} - -#define atomic_sub_and_test(a, v) (atomic_sub_return((a), (v)) == 0) -#define atomic_dec_and_test(v) (atomic_dec_return((v)) == 0) - -/* - * Atomically test *v and decrement if it is greater than 0. - * The function returns the old value of *v minus 1. - */ -static __inline__ int atomic_dec_if_positive(atomic_t *v) -{ - int t; - - __asm__ __volatile__( -"1: lwarx %0,0,%1 # atomic_dec_if_positive\n\ - addic. %0,%0,-1\n\ - blt- 2f\n" - PPC405_ERR77(0,%1) -" stwcx. %0,0,%1\n\ - bne- 1b" - SMP_ISYNC - "\n\ -2:" : "=&r" (t) - : "r" (&v->counter) - : "cc", "memory"); - - return t; -} - -#define __MB __asm__ __volatile__ (SMP_SYNC : : : "memory") -#define smp_mb__before_atomic_dec() __MB -#define smp_mb__after_atomic_dec() __MB -#define smp_mb__before_atomic_inc() __MB -#define smp_mb__after_atomic_inc() __MB - -#endif /* __KERNEL__ */ -#endif /* _ASM_PPC_ATOMIC_H_ */ Index: linux-2.6.12/include/asm-ppc64/memory.h =================================================================== --- linux-2.6.12.orig/include/asm-ppc64/memory.h 2005-08-29 08:04:06.000000000 +0200 +++ /dev/null 1970-01-01 00:00:00.000000000 +0000 @@ -1,59 +0,0 @@ -#ifndef _ASM_POWERPC_MEMORY_H_ -#define _ASM_POWERPC_MEMORY_H_ - -/* - * 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 - -/* - * Arguably the bitops and *xchg operations don't imply any memory barrier - * or SMP ordering, but in fact a lot of drivers expect them to imply - * both, since they do on x86 cpus. - */ -#ifdef CONFIG_SMP -#define EIEIO_ON_SMP "eieio\n" -#define ISYNC_ON_SMP "\n\tisync" -#else -#define EIEIO_ON_SMP -#define ISYNC_ON_SMP -#endif - -static inline void eieio(void) -{ - __asm__ __volatile__ ("eieio" : : : "memory"); -} - -static inline void isync(void) -{ - __asm__ __volatile__ ("isync" : : : "memory"); -} - -#ifdef CONFIG_SMP -#define eieio_on_smp() eieio() -#define isync_on_smp() isync() -#else -#define eieio_on_smp() __asm__ __volatile__("": : :"memory") -#define isync_on_smp() __asm__ __volatile__("": : :"memory") -#endif - -/* Macros for adjusting thread priority (hardware multi-threading) */ -#define HMT_very_low() asm volatile("or 31,31,31 # very low priority") -#define HMT_low() asm volatile("or 1,1,1 # low priority") -#define HMT_medium_low() asm volatile("or 6,6,6 # medium low priority") -#define HMT_medium() asm volatile("or 2,2,2 # medium priority") -#define HMT_medium_high() asm volatile("or 5,5,5 # medium high priority") -#define HMT_high() asm volatile("or 3,3,3 # high priority") - -#define HMT_VERY_LOW "\tor 31,31,31 # very low priority\n" -#define HMT_LOW "\tor 1,1,1 # low priority\n" -#define HMT_MEDIUM_LOW "\tor 6,6,6 # medium low priority\n" -#define HMT_MEDIUM "\tor 2,2,2 # medium priority\n" -#define HMT_MEDIUM_HIGH "\tor 5,5,5 # medium high priority\n" -#define HMT_HIGH "\tor 3,3,3 # high priority\n" - -#endif Index: linux-2.6.12/include/asm-ppc/io.h =================================================================== --- linux-2.6.12.orig/include/asm-ppc/io.h 2005-08-29 08:04:06.000000000 +0200 +++ linux-2.6.12/include/asm-ppc/io.h 2005-08-29 08:04:26.000000000 +0200 @@ -8,6 +8,7 @@ #include #include +#include #include #define SIO_CONFIG_RA 0x398 @@ -440,16 +441,6 @@ #define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT) #define page_to_bus(page) (page_to_phys(page) + PCI_DRAM_OFFSET) -/* - * Enforce In-order Execution of I/O: - * Acts as a barrier to ensure all previous I/O accesses have - * completed before any further ones are issued. - */ -extern inline void eieio(void) -{ - __asm__ __volatile__ ("eieio" : : : "memory"); -} - /* Enforce in-order execution of data I/O. * No distinction between read/write on PPC; use eieio for all three. */ Index: linux-2.6.12/include/asm-ppc64/atomic.h =================================================================== --- linux-2.6.12.orig/include/asm-ppc64/atomic.h 2005-08-29 08:04:06.000000000 +0200 +++ /dev/null 1970-01-01 00:00:00.000000000 +0000 @@ -1,197 +0,0 @@ -/* - * PowerPC64 atomic operations - * - * Copyright (C) 2001 Paul Mackerras , IBM - * Copyright (C) 2001 Anton Blanchard , IBM - * - * 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. - */ - -#ifndef _ASM_PPC64_ATOMIC_H_ -#define _ASM_PPC64_ATOMIC_H_ - -#include - -typedef struct { volatile int counter; } atomic_t; - -#define ATOMIC_INIT(i) { (i) } - -#define atomic_read(v) ((v)->counter) -#define atomic_set(v,i) (((v)->counter) = (i)) - -static __inline__ void atomic_add(int a, atomic_t *v) -{ - int t; - - __asm__ __volatile__( -"1: lwarx %0,0,%3 # atomic_add\n\ - add %0,%2,%0\n\ - stwcx. %0,0,%3\n\ - bne- 1b" - : "=&r" (t), "=m" (v->counter) - : "r" (a), "r" (&v->counter), "m" (v->counter) - : "cc"); -} - -static __inline__ int atomic_add_return(int a, atomic_t *v) -{ - int t; - - __asm__ __volatile__( - EIEIO_ON_SMP -"1: lwarx %0,0,%2 # atomic_add_return\n\ - add %0,%1,%0\n\ - stwcx. %0,0,%2\n\ - bne- 1b" - ISYNC_ON_SMP - : "=&r" (t) - : "r" (a), "r" (&v->counter) - : "cc", "memory"); - - return t; -} - -#define atomic_add_negative(a, v) (atomic_add_return((a), (v)) < 0) - -static __inline__ void atomic_sub(int a, atomic_t *v) -{ - int t; - - __asm__ __volatile__( -"1: lwarx %0,0,%3 # atomic_sub\n\ - subf %0,%2,%0\n\ - stwcx. %0,0,%3\n\ - bne- 1b" - : "=&r" (t), "=m" (v->counter) - : "r" (a), "r" (&v->counter), "m" (v->counter) - : "cc"); -} - -static __inline__ int atomic_sub_return(int a, atomic_t *v) -{ - int t; - - __asm__ __volatile__( - EIEIO_ON_SMP -"1: lwarx %0,0,%2 # atomic_sub_return\n\ - subf %0,%1,%0\n\ - stwcx. %0,0,%2\n\ - bne- 1b" - ISYNC_ON_SMP - : "=&r" (t) - : "r" (a), "r" (&v->counter) - : "cc", "memory"); - - return t; -} - -static __inline__ void atomic_inc(atomic_t *v) -{ - int t; - - __asm__ __volatile__( -"1: lwarx %0,0,%2 # atomic_inc\n\ - addic %0,%0,1\n\ - stwcx. %0,0,%2\n\ - bne- 1b" - : "=&r" (t), "=m" (v->counter) - : "r" (&v->counter), "m" (v->counter) - : "cc"); -} - -static __inline__ int atomic_inc_return(atomic_t *v) -{ - int t; - - __asm__ __volatile__( - EIEIO_ON_SMP -"1: lwarx %0,0,%1 # atomic_inc_return\n\ - addic %0,%0,1\n\ - stwcx. %0,0,%1\n\ - bne- 1b" - ISYNC_ON_SMP - : "=&r" (t) - : "r" (&v->counter) - : "cc", "memory"); - - return t; -} - -/* - * atomic_inc_and_test - increment and test - * @v: pointer of type atomic_t - * - * Atomically increments @v by 1 - * and returns true if the result is zero, or false for all - * other cases. - */ -#define atomic_inc_and_test(v) (atomic_inc_return(v) == 0) - -static __inline__ void atomic_dec(atomic_t *v) -{ - int t; - - __asm__ __volatile__( -"1: lwarx %0,0,%2 # atomic_dec\n\ - addic %0,%0,-1\n\ - stwcx. %0,0,%2\n\ - bne- 1b" - : "=&r" (t), "=m" (v->counter) - : "r" (&v->counter), "m" (v->counter) - : "cc"); -} - -static __inline__ int atomic_dec_return(atomic_t *v) -{ - int t; - - __asm__ __volatile__( - EIEIO_ON_SMP -"1: lwarx %0,0,%1 # atomic_dec_return\n\ - addic %0,%0,-1\n\ - stwcx. %0,0,%1\n\ - bne- 1b" - ISYNC_ON_SMP - : "=&r" (t) - : "r" (&v->counter) - : "cc", "memory"); - - return t; -} - -#define atomic_sub_and_test(a, v) (atomic_sub_return((a), (v)) == 0) -#define atomic_dec_and_test(v) (atomic_dec_return((v)) == 0) - -/* - * Atomically test *v and decrement if it is greater than 0. - * The function returns the old value of *v minus 1. - */ -static __inline__ int atomic_dec_if_positive(atomic_t *v) -{ - int t; - - __asm__ __volatile__( - EIEIO_ON_SMP -"1: lwarx %0,0,%1 # atomic_dec_if_positive\n\ - addic. %0,%0,-1\n\ - blt- 2f\n\ - stwcx. %0,0,%1\n\ - bne- 1b" - ISYNC_ON_SMP - "\n\ -2:" : "=&r" (t) - : "r" (&v->counter) - : "cc", "memory"); - - return t; -} - -#define smp_mb__before_atomic_dec() smp_mb() -#define smp_mb__after_atomic_dec() smp_mb() -#define smp_mb__before_atomic_inc() smp_mb() -#define smp_mb__after_atomic_inc() smp_mb() - -#endif /* _ASM_PPC64_ATOMIC_H_ */ Index: linux-2.6.12/include/asm-powerpc/memory.h =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ linux-2.6.12/include/asm-powerpc/memory.h 2005-08-29 08:04:26.000000000 +0200 @@ -0,0 +1,59 @@ +#ifndef _ASM_PPC64_MEMORY_H_ +#define _ASM_PPC64_MEMORY_H_ + +/* + * 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 + +/* + * Arguably the bitops and *xchg operations don't imply any memory barrier + * or SMP ordering, but in fact a lot of drivers expect them to imply + * both, since they do on x86 cpus. + */ +#ifdef CONFIG_SMP +#define EIEIO_ON_SMP "eieio\n" +#define ISYNC_ON_SMP "\n\tisync" +#else +#define EIEIO_ON_SMP +#define ISYNC_ON_SMP +#endif + +static inline void eieio(void) +{ + __asm__ __volatile__ ("eieio" : : : "memory"); +} + +static inline void isync(void) +{ + __asm__ __volatile__ ("isync" : : : "memory"); +} + +#ifdef CONFIG_SMP +#define eieio_on_smp() eieio() +#define isync_on_smp() isync() +#else +#define eieio_on_smp() __asm__ __volatile__("": : :"memory") +#define isync_on_smp() __asm__ __volatile__("": : :"memory") +#endif + +/* Macros for adjusting thread priority (hardware multi-threading) */ +#define HMT_very_low() asm volatile("or 31,31,31 # very low priority") +#define HMT_low() asm volatile("or 1,1,1 # low priority") +#define HMT_medium_low() asm volatile("or 6,6,6 # medium low priority") +#define HMT_medium() asm volatile("or 2,2,2 # medium priority") +#define HMT_medium_high() asm volatile("or 5,5,5 # medium high priority") +#define HMT_high() asm volatile("or 3,3,3 # high priority") + +#define HMT_VERY_LOW "\tor 31,31,31 # very low priority\n" +#define HMT_LOW "\tor 1,1,1 # low priority\n" +#define HMT_MEDIUM_LOW "\tor 6,6,6 # medium low priority\n" +#define HMT_MEDIUM "\tor 2,2,2 # medium priority\n" +#define HMT_MEDIUM_HIGH "\tor 5,5,5 # medium high priority\n" +#define HMT_HIGH "\tor 3,3,3 # high priority\n" + +#endif Index: linux-2.6.12/include/asm-powerpc/atomic.h =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ linux-2.6.12/include/asm-powerpc/atomic.h 2005-08-29 08:04:26.000000000 +0200 @@ -0,0 +1,209 @@ +/* + * PowerPC atomic operations + */ + +#ifndef _ASM_POWERPC_ATOMIC_H_ +#define _ASM_POWERPC_ATOMIC_H_ + +typedef struct { volatile int counter; } atomic_t; + +#ifdef __KERNEL__ +#include + +#define ATOMIC_INIT(i) { (i) } + +#define atomic_read(v) ((v)->counter) +#define atomic_set(v,i) (((v)->counter) = (i)) + +/* Erratum #77 on the 405 means we need a sync or dcbt before every stwcx. + * The old ATOMIC_SYNC_FIX covered some but not all of this. + */ +#ifdef CONFIG_IBM405_ERR77 +#define PPC405_ERR77(ra,rb) "dcbt " #ra "," #rb ";" +#else +#define PPC405_ERR77(ra,rb) +#endif + +static __inline__ void atomic_add(int a, atomic_t *v) +{ + int t; + + __asm__ __volatile__( +"1: lwarx %0,0,%3 # atomic_add\n\ + add %0,%2,%0\n" + PPC405_ERR77(0,%3) +" stwcx. %0,0,%3 \n\ + bne- 1b" + : "=&r" (t), "=m" (v->counter) + : "r" (a), "r" (&v->counter), "m" (v->counter) + : "cc"); +} + +static __inline__ int atomic_add_return(int a, atomic_t *v) +{ + int t; + + __asm__ __volatile__( + EIEIO_ON_SMP +"1: lwarx %0,0,%2 # atomic_add_return\n\ + add %0,%1,%0\n" + PPC405_ERR77(0,%2) +" stwcx. %0,0,%2 \n\ + bne- 1b" + ISYNC_ON_SMP + : "=&r" (t) + : "r" (a), "r" (&v->counter) + : "cc", "memory"); + + return t; +} + +#define atomic_add_negative(a, v) (atomic_add_return((a), (v)) < 0) + +static __inline__ void atomic_sub(int a, atomic_t *v) +{ + int t; + + __asm__ __volatile__( +"1: lwarx %0,0,%3 # atomic_sub\n\ + subf %0,%2,%0\n" + PPC405_ERR77(0,%3) +" stwcx. %0,0,%3 \n\ + bne- 1b" + : "=&r" (t), "=m" (v->counter) + : "r" (a), "r" (&v->counter), "m" (v->counter) + : "cc"); +} + +static __inline__ int atomic_sub_return(int a, atomic_t *v) +{ + int t; + + __asm__ __volatile__( + EIEIO_ON_SMP +"1: lwarx %0,0,%2 # atomic_sub_return\n\ + subf %0,%1,%0\n" + PPC405_ERR77(0,%2) +" stwcx. %0,0,%2 \n\ + bne- 1b" + ISYNC_ON_SMP + : "=&r" (t) + : "r" (a), "r" (&v->counter) + : "cc", "memory"); + + return t; +} + +static __inline__ void atomic_inc(atomic_t *v) +{ + int t; + + __asm__ __volatile__( +"1: lwarx %0,0,%2 # atomic_inc\n\ + addic %0,%0,1\n" + PPC405_ERR77(0,%2) +" stwcx. %0,0,%2 \n\ + bne- 1b" + : "=&r" (t), "=m" (v->counter) + : "r" (&v->counter), "m" (v->counter) + : "cc"); +} + +static __inline__ int atomic_inc_return(atomic_t *v) +{ + int t; + + __asm__ __volatile__( + EIEIO_ON_SMP +"1: lwarx %0,0,%1 # atomic_inc_return\n\ + addic %0,%0,1\n" + PPC405_ERR77(0,%1) +" stwcx. %0,0,%1 \n\ + bne- 1b" + ISYNC_ON_SMP + : "=&r" (t) + : "r" (&v->counter) + : "cc", "memory"); + + return t; +} + +/* + * atomic_inc_and_test - increment and test + * @v: pointer of type atomic_t + * + * Atomically increments @v by 1 + * and returns true if the result is zero, or false for all + * other cases. + */ +#define atomic_inc_and_test(v) (atomic_inc_return(v) == 0) + +static __inline__ void atomic_dec(atomic_t *v) +{ + int t; + + __asm__ __volatile__( +"1: lwarx %0,0,%2 # atomic_dec\n\ + addic %0,%0,-1\n" + PPC405_ERR77(0,%2)\ +" stwcx. %0,0,%2\n\ + bne- 1b" + : "=&r" (t), "=m" (v->counter) + : "r" (&v->counter), "m" (v->counter) + : "cc"); +} + +static __inline__ int atomic_dec_return(atomic_t *v) +{ + int t; + + __asm__ __volatile__( + EIEIO_ON_SMP +"1: lwarx %0,0,%1 # atomic_dec_return\n\ + addic %0,%0,-1\n" + PPC405_ERR77(0,%1) +" stwcx. %0,0,%1\n\ + bne- 1b" + ISYNC_ON_SMP + : "=&r" (t) + : "r" (&v->counter) + : "cc", "memory"); + + return t; +} + +#define atomic_sub_and_test(a, v) (atomic_sub_return((a), (v)) == 0) +#define atomic_dec_and_test(v) (atomic_dec_return((v)) == 0) + +/* + * Atomically test *v and decrement if it is greater than 0. + * The function returns the old value of *v minus 1. + */ +static __inline__ int atomic_dec_if_positive(atomic_t *v) +{ + int t; + + __asm__ __volatile__( + EIEIO_ON_SMP +"1: lwarx %0,0,%1 # atomic_dec_if_positive\n\ + addic. %0,%0,-1\n\ + blt- 2f\n" + PPC405_ERR77(0,%1) +" stwcx. %0,0,%1\n\ + bne- 1b" + ISYNC_ON_SMP + "\n\ +2:" : "=&r" (t) + : "r" (&v->counter) + : "cc", "memory"); + + return t; +} + +#define smp_mb__before_atomic_dec() smp_mb() +#define smp_mb__after_atomic_dec() smp_mb() +#define smp_mb__before_atomic_inc() smp_mb() +#define smp_mb__after_atomic_inc() smp_mb() + +#endif /* __KERNEL__ */ +#endif /* _ASM_POWERPC_ATOMIC_H_ */ From sfr at canb.auug.org.au Mon Aug 29 18:26:01 2005 From: sfr at canb.auug.org.au (Stephen Rothwell) Date: Mon, 29 Aug 2005 18:26:01 +1000 Subject: [PATCH] fix iSeries build for gcc-3.4 Message-ID: <20050829182601.7f15cae6.sfr@canb.auug.org.au> gcc 3.4 (at least the build we are using) puts the gcc generated .ident string into a .note section at the end of the files it compiles (gcc 3.3.3-hammer and gcc 4.0.2 Debian puts it in the .text section). This means that the lparmap.s file we produce in the iSeries build may end with a .note section. When we include it into head.S, the assembler can no longer resolve some of the conditional branches since the target label ends up too far away. This patch just forces us back to the .text section after including lparmap.s. The breakage was caused by my patch "iSeries build with newer assemblers and compilers" (sha1-id: 2ad56496627630ebc99f06af5f81ca23e17e014e). Signed-off-by: Stephen Rothwell --- head.S | 5 +++++ 1 file changed, 5 insertions(+) Built with gcc 3.3.3-hammer, gcc 3.4.4 20041116 and 4.0.2 20050816. -- Cheers, Stephen Rothwell sfr at canb.auug.org.au http://www.canb.auug.org.au/~sfr/ diff --git a/arch/ppc64/kernel/head.S b/arch/ppc64/kernel/head.S --- a/arch/ppc64/kernel/head.S +++ b/arch/ppc64/kernel/head.S @@ -683,6 +683,11 @@ fwnmi_data_area: #ifdef CONFIG_PPC_ISERIES . = LPARMAP_PHYS #include "lparmap.s" +/* + * This ".text" is here for old compilers that generate a trailing + * .note section when compiling .c files to .s + */ + .text #endif /* CONFIG_PPC_ISERIES */ /* From sharada at in.ibm.com Mon Aug 29 21:52:07 2005 From: sharada at in.ibm.com (R Sharada) Date: Mon, 29 Aug 2005 17:22:07 +0530 Subject: [PATCH] export htab value for kexec on non-lpar - cleaned up patch In-Reply-To: <200508251649.26156.arnd@arndb.de> References: <20050823080423.GA2380@in.ibm.com> <20050824190652.GO1012@otto> <20050825044206.GA2079@in.ibm.com> <200508251649.26156.arnd@arndb.de> Message-ID: <20050829115207.GA2858@in.ibm.com> Hello, Based on Arnd's comments, it made sense to statically allocate the data structures for htab_base and htab_size as well as assign the values therein. Hence modified the patch to reflect the changes suggested by Arnd and Nathan. Hopefully, the patch is now in shape to be considered for inclusion. Sending it herewith for acceptance Thanks and Regards, Sharada Signed-off-by: R Sharada --- diff -puN include/asm-ppc64/mmu.h~kexec-export-htab-value include/asm-ppc64/mmu.h --- linux-2.6.13-rc6-org/include/asm-ppc64/mmu.h~kexec-export-htab-value 2005-08-25 05:27:35.000000000 +0530 +++ linux-2.6.13-rc6-org-sharada/include/asm-ppc64/mmu.h 2005-08-29 22:09:04.000000000 +0530 @@ -58,6 +58,7 @@ * Hash table */ +#define HASH_GROUP_SIZE 0x80 /* size of each hash group */ #define HPTES_PER_GROUP 8 #define HPTE_V_AVPN_SHIFT 7 diff -puN ./arch/ppc64/kernel/setup.c~kexec-export-htab-value ./arch/ppc64/kernel/setup.c --- linux-2.6.13-rc6-org/./arch/ppc64/kernel/setup.c~kexec-export-htab-value 2005-08-25 05:27:35.000000000 +0530 +++ linux-2.6.13-rc6-org-sharada/./arch/ppc64/kernel/setup.c 2005-08-29 22:11:06.000000000 +0530 @@ -1033,6 +1033,39 @@ void __init setup_syscall_map(void) count32, count64); } +static void __init export_htab_value(void) +{ + static unsigned long htab_base; + static struct property htab_base_prop = { + .name = "htab_base", + .length = sizeof(unsigned long), + .value = &htab_base, + }; + + static unsigned long htab_size; + static struct property htab_base_size = { + .name = "htab_size", + .length = sizeof(unsigned long), + .value = &htab_size, + }; + + struct device_node *node; + + if (systemcfg->platform == PLATFORM_PSERIES_LPAR) + return; + + node = of_find_node_by_path("/chosen"); + if (!node) + return; + + htab_base = __pa(htab_address); + prom_add_property(node, &htab_base_prop); + htab_size = (htab_hash_mask + 1) * HASH_GROUP_SIZE; + prom_add_property(node, &htab_size_prop); + + of_node_put(node); +} + /* * Called into from start_kernel, after lock_kernel has been called. * Initializes bootmem, which is unsed to manage page allocation until @@ -1086,6 +1119,8 @@ void __init setup_arch(char **cmdline_p) } paging_init(); + /* export htab value into /proc/device-tree/chosen for kexec */ + export_htab_value(); ppc64_boot_msg(0x15, "Setup Done"); } _ From will_schmidt at vnet.ibm.com Tue Aug 30 00:11:22 2005 From: will_schmidt at vnet.ibm.com (will schmidt) Date: Mon, 29 Aug 2005 09:11:22 -0500 Subject: [PATCH 10/12] ppc64: Reroute interrupts from zero + offset to KERNELBASE + offset In-Reply-To: <200508291156.34262.michael@ellerman.id.au> References: <20050826025331.84994680F7@ozlabs.org> <430F1EF7.8080903@vnet.ibm.com> <200508291156.34262.michael@ellerman.id.au> Message-ID: <4313178A.9010203@vnet.ibm.com> Michael Ellerman wrote: > Hi Will, > > On Fri, 26 Aug 2005 23:53, will schmidt wrote: > >>Hi Michael, >> first question is inline, the other question.. when the >>KDUMP_CAPTURE_KERNEL is configured, is it only mapped into memory ahead >>of time, or would functions like this one (setup_kdump_trampoline) be >>run during normal system start? > > > I'm not sure what you mean there. The idea is that the first kernel will load > the second kernel into memory at 32 MB, then when the first kernel crashes it > passes control to the second kernel which begins running. In the process of > starting up, the second kernel will backup the first 0x8000 bytes of the > first kernel, and then call setup_kdump_trampoline(). > Ultimately, the question was _when_ does this code get invoked. My concern was that we would always be running with the trampoline. You've clarified this for me, so now I know. :-) > >>>+ /* XXX this only works if PHYSICAL_START <= 32 MB */ >>>+ >>>+ for (i = 0x100; i < 0x3000; i += 8) { >>>+ addr = (unsigned int *)i; >>>+ *addr++ = 0x60000000; /* nop */ >>>+ *addr = 0x48000000 | ((PHYSICAL_START - 1) & 0x03fffffc); >>>+ >>>+ asm ("dcbst 0,%0; sync; icbi 0,%0; isync" : : "r" (addr)); >>>+ } > > > Stephen is right, this code definitely needs a comment, I just hadn't got > around to it yet. > > >>So here we're replacing the exception code in the first kernel, with >>pointers to the exception code in the second, right? once this runs we >>end up with code something like... >> >>c0000000 00000100: 60 00 00 00 nop >>c0000000 00000108: 48 00 xx xx b (PHYSICAL_START -1) >>c0000000 00000110: 60 00 00 00 nop >>c0000000 00000118: 48 00 xx xx b (PHYSICAL_START -1) >>c0000000 00000120: 60 00 00 00 nop >>c0000000 00000128: 48 00 xx xx b (PHYSICAL_START -1) >>... >> >>Is this the intent, or should there be a +i somewhere in the branch >>instruction too? > > > Almost. 0x48000000 is a "b" instruction, not "ba". So the disassembly looks > like this: > > c000000000000100 60000000 nop > c000000000000104 49fffffc b c000000002000100 > c000000000000108 60000000 nop > c00000000000010c 49fffffc b c000000002000108 > c000000000000110 60000000 nop > c000000000000114 49fffffc b c000000002000110 > c000000000000118 60000000 nop > c00000000000011c 49fffffc b c000000002000118 > > That is we're branching to (32 MB - 4) + current address. [it's - 4 because of > the mask (0x03ffffffc)] > > We'd like to just branch to current address + 32 MB, but we don't have enough > bits in the branch instruction for that, hence we need a nop at 0x100, then > at 0x104 we jump to 0x104 + 32 MB - 4 = 0x100 + 32 MB. > > Hope that makes sense. Yes, it does. Thanks. > > cheers > -Will From segher at kernel.crashing.org Tue Aug 30 01:44:34 2005 From: segher at kernel.crashing.org (Segher Boessenkool) Date: Mon, 29 Aug 2005 17:44:34 +0200 Subject: [PATCH] 1/2 Start header file merger (Was: Re: Beginning Merger Patch) In-Reply-To: <1125089709.32488.35.camel@cashmere.sps.mot.com> References: <1123023575.2614.25.camel@cashmere.sps.mot.com> <688ba2276de281a9473b030a16a514c0@embeddededge.com> <20050805174705.731ffa05.sfr@canb.auug.org.au> <200508051353.23750.arnd@arndb.de> <20050806005941.5d1fe432.sfr@canb.auug.org.au> <1125089709.32488.35.camel@cashmere.sps.mot.com> Message-ID: <7d30f9ea7e93320d569a60c90f179ba5@kernel.crashing.org> > Anyone care to take a semi-authoritative stand on what > symbol to use to distinguish 32/64-bit-ness in the > include files? It depends on what you are testing for. Sometimes __LP64__ would be best (when you want to know the size of pointers etc.), sometimes __powerpc64__ (when you need to know the available instruction set), and I'm sure there are cases where you should use a different symbol altogether, because you are testing something else. Segher From linas at austin.ibm.com Tue Aug 30 01:57:50 2005 From: linas at austin.ibm.com (Linas Vepstas) Date: Mon, 29 Aug 2005 10:57:50 -0500 Subject: [patch 8/8] PCI Error Recovery: PPC64 core recovery routines In-Reply-To: <1125006237.12539.23.camel@gaston> References: <20050823231817.829359000@bilge> <20050823232143.003048000@bilge> <20050823234747.GI18113@austin.ibm.com> <1124898331.24668.33.camel@sinatra.austin.ibm.com> <20050824162959.GC25174@austin.ibm.com> <17165.3205.505386.187453@cargo.ozlabs.ibm.com> <1124930943.5159.168.camel@gaston> <20050825162118.GH25174@austin.ibm.com> <1125006237.12539.23.camel@gaston> Message-ID: <20050829155750.GB12618@austin.ibm.com> On Fri, Aug 26, 2005 at 07:43:57AM +1000, Benjamin Herrenschmidt was heard to remark: > On Thu, 2005-08-25 at 11:21 -0500, Linas Vepstas wrote: > > On Thu, Aug 25, 2005 at 10:49:03AM +1000, Benjamin Herrenschmidt was heard to remark: > > > > > > Of course, we'll possibly end up with a different ethX or whatever, but > > > > Yep, but that's not an issue, since all the various device-naming > > schemes are supposed to be fixing this. Its a distinct problem; > > it needs to be solved even across cold-boots. > > Ok, so what is the problem then ? Why do we have to wait at all ? Why > not just unplug/replug right away ? Paranoia + old versions of udev. I beleive that older versions of udev (such as the ones currently shipping with Red Hat RHEL4 and SuSE SLES9) failed to serialize events properly. I beleive that the newer versions do serialize, but have not verified/tested. --linas From linas at austin.ibm.com Tue Aug 30 02:00:14 2005 From: linas at austin.ibm.com (Linas Vepstas) Date: Mon, 29 Aug 2005 11:00:14 -0500 Subject: [patch 8/8] PCI Error Recovery: PPC64 core recovery routines In-Reply-To: <1125013056.14185.0.camel@gaston> References: <20050823232143.003048000@bilge> <20050823234747.GI18113@austin.ibm.com> <1124898331.24668.33.camel@sinatra.austin.ibm.com> <20050824162959.GC25174@austin.ibm.com> <17165.3205.505386.187453@cargo.ozlabs.ibm.com> <1124930943.5159.168.camel@gaston> <20050825162118.GH25174@austin.ibm.com> <1125006237.12539.23.camel@gaston> <17166.20904.543484.435446@cargo.ozlabs.ibm.com> <1125013056.14185.0.camel@gaston> Message-ID: <20050829160014.GC12618@austin.ibm.com> On Fri, Aug 26, 2005 at 09:37:36AM +1000, Benjamin Herrenschmidt was heard to remark: > On Fri, 2005-08-26 at 09:18 +1000, Paul Mackerras wrote: > > Benjamin Herrenschmidt writes: > > > > > Ok, so what is the problem then ? Why do we have to wait at all ? Why > > > not just unplug/replug right away ? > > > > We'd have to be absolutely certain that the driver could not possibly > > take another interrupt or try to access the device on behalf of the > > old instance of the device by the time it returned from the remove > > function. I'm not sure I'd trust most drivers that far... > > Hrm... If a driver gets that wrong, then it will also blow up when > unloaded as a module. :) We've discovered two, so far, that blow up when unloaded: lpfc and e1000. I beleive these are now fixed in mainline. --linas From linas at austin.ibm.com Tue Aug 30 02:09:15 2005 From: linas at austin.ibm.com (Linas Vepstas) Date: Mon, 29 Aug 2005 11:09:15 -0500 Subject: [patch 8/8] PCI Error Recovery: PPC64 core recovery routines In-Reply-To: <17170.44500.848623.139474@cargo.ozlabs.ibm.com> References: <20050823231817.829359000@bilge> <20050823232143.003048000@bilge> <20050823234747.GI18113@austin.ibm.com> <1124898331.24668.33.camel@sinatra.austin.ibm.com> <20050824162959.GC25174@austin.ibm.com> <17165.3205.505386.187453@cargo.ozlabs.ibm.com> <20050825161325.GG25174@austin.ibm.com> <17170.44500.848623.139474@cargo.ozlabs.ibm.com> Message-ID: <20050829160915.GD12618@austin.ibm.com> On Mon, Aug 29, 2005 at 04:40:20PM +1000, Paul Mackerras was heard to remark: > Linas Vepstas writes: > > > Actually, no. There are three issues: > > 1) hotplug routines are called from within kernel. GregKH has stated on > > multiple occasions that doing this is wrong/bad/evil. This includes > > calling hot-unplug. > > > > 2) As a result, the code to call hot-unplug is a bit messy. In > > particular, there's a bit of hoop-jumping when hotplug is built as > > as a module (and said hoops were wrecked recently when I moved the > > code around, out of the rpaphp directory). > > One way to clean this up would be to make rpaphp the driver for the > EADS bridges (from the pci code's point of view). I guess I don't understand what that means. Are you suggesting moving pSeries_pci.c into the rpaphp code directory? > Then it would > automatically get included in the error recovery process and could do > whatever it should. John Rose, the current maintainer of the rpaphp code, is pretty militant about removing things from, not adding things to, the rpaphp code. Which is a good idea, as chunks of that code are spaghetti, and do need simplification and cleanup. > > 3) Hot-unplug causes scripts to run in user-space. There is no way to > > know when these scripts are done, so its not clear if we've waited > > long enough before calling hot-add (or if waiting is even necessary). > > OK, so let's just add a new hotplug event called KOBJ_ERROR or > something, which tells userspace that an error has occurred which has > made the device inaccessible. Greg, would that be OK? Why do we need such an event? I would prefer to deprecate the hot-plug based recovery scheme. This is for many reasons, including the fact that some devices that can get pci errors are soldered onto the planar, and are not hot-pluggable. --linas From torvalds at osdl.org Tue Aug 30 03:32:09 2005 From: torvalds at osdl.org (Linus Torvalds) Date: Mon, 29 Aug 2005 10:32:09 -0700 (PDT) Subject: please pull ppc64-2.6.git In-Reply-To: <17170.25803.413408.44080@cargo.ozlabs.ibm.com> References: <17170.25803.413408.44080@cargo.ozlabs.ibm.com> Message-ID: On Mon, 29 Aug 2005, Paul Mackerras wrote: > > Please do a pull from: > > rsync://rsync.kernel.org/pub/scm/linux/kernel/git/paulus/ppc64-2.6.git Gaah. This is not a valid git repository. Guys, if you do partially populated repositories, _please_ make sure that you still make it a valid git repository. These days you can trivially do so by doing a echo /pub/scm/linux/kernel/git/torvalds/linux-2.6/objects > objects/info/alternates or similar. That also makes gitweb able to show diffs etc, something it can't do for a broken partial repository. Not pulled, Linus From rmk at arm.linux.org.uk Tue Aug 30 03:45:10 2005 From: rmk at arm.linux.org.uk (Russell King) Date: Mon, 29 Aug 2005 18:45:10 +0100 Subject: please pull ppc64-2.6.git In-Reply-To: ; from torvalds@osdl.org on Mon, Aug 29, 2005 at 10:32:09AM -0700 References: <17170.25803.413408.44080@cargo.ozlabs.ibm.com> Message-ID: <20050829184510.A20605@flint.arm.linux.org.uk> On Mon, Aug 29, 2005 at 10:32:09AM -0700, Linus Torvalds wrote: > On Mon, 29 Aug 2005, Paul Mackerras wrote: > > Please do a pull from: > > > > rsync://rsync.kernel.org/pub/scm/linux/kernel/git/paulus/ppc64-2.6.git > > Gaah. > > This is not a valid git repository. > > Guys, if you do partially populated repositories, _please_ make sure that > you still make it a valid git repository. These days you can trivially do > so by doing a > > echo /pub/scm/linux/kernel/git/torvalds/linux-2.6/objects > objects/info/alternates > > or similar. That also makes gitweb able to show diffs etc, something it > can't do for a broken partial repository. Is the expected filesystem layout documented somewhere online (_external_ to the source code) ? The reason I stress external to the code is that some of us do not track git developments. (Except via the ctrl-d method in our mail readers.) Alternatively, when changes occur to the repostory format, please can they be marked with some obvious subject so that folk know when things are going to break? -- Russell King From torvalds at osdl.org Tue Aug 30 04:02:38 2005 From: torvalds at osdl.org (Linus Torvalds) Date: Mon, 29 Aug 2005 11:02:38 -0700 (PDT) Subject: please pull ppc64-2.6.git In-Reply-To: <20050829184510.A20605@flint.arm.linux.org.uk> References: <17170.25803.413408.44080@cargo.ozlabs.ibm.com> <20050829184510.A20605@flint.arm.linux.org.uk> Message-ID: On Mon, 29 Aug 2005, Russell King wrote: > > Is the expected filesystem layout documented somewhere online (_external_ > to the source code) ? Nope, I don't think so. > Alternatively, when changes occur to the repostory format, please can > they be marked with some obvious subject so that folk know when things > are going to break? The only actual filesystem _breakage_ has been the introduction of pack-files (and the old, old _old_ thing where I changed the actual object compression/hashing order). The "objects/info/alternates" thing is an extension, which allows you to have a partial object store, and point to the "rest of it", and still have all the tools understand it and be able to parse the totality of it. So it doesn't break or change old formats, it only allows a new one. (Partial repos have always worked with the rsync protocol, and with the client-side pulling. But that was more of an accident than anything else, and they fundamentally were broken for any real work - gitweb can't show anything really sane, server-side serving - whether anonymous or ssh - doesn't work, etc etc). Linus From rmk at arm.linux.org.uk Tue Aug 30 04:20:13 2005 From: rmk at arm.linux.org.uk (Russell King) Date: Mon, 29 Aug 2005 19:20:13 +0100 Subject: please pull ppc64-2.6.git In-Reply-To: ; from torvalds@osdl.org on Mon, Aug 29, 2005 at 11:02:38AM -0700 References: <17170.25803.413408.44080@cargo.ozlabs.ibm.com> <20050829184510.A20605@flint.arm.linux.org.uk> Message-ID: <20050829192013.B20605@flint.arm.linux.org.uk> On Mon, Aug 29, 2005 at 11:02:38AM -0700, Linus Torvalds wrote: > The "objects/info/alternates" thing is an extension, which allows you to > have a partial object store, and point to the "rest of it", and still have > all the tools understand it and be able to parse the totality of it. So it > doesn't break or change old formats, it only allows a new one. Ah, ok. I thought it was a new requirement, and I had visions of similar complaints about my repositories. Thanks for explaining the situation. -- Russell King From geoffrey.levand at am.sony.com Tue Aug 30 04:09:49 2005 From: geoffrey.levand at am.sony.com (Geoff Levand) Date: Mon, 29 Aug 2005 11:09:49 -0700 Subject: [PATCH 1/7] spufs: The SPU file system In-Reply-To: <200508281844.18187.arnd@arndb.de> References: <200508260003.40865.arnd@arndb.de> <84144f02050826011778e1142@mail.gmail.com> <200508281844.18187.arnd@arndb.de> Message-ID: <43134F6D.1080602@am.sony.com> Arnd Bergmann wrote: > On Freedag 26 August 2005 10:17, Pekka Enberg wrote: > >>I am confused. The code is architecture specific and does device I/O. Why do >>you want to put this in fs/ and not drivers/? > > > I never really thought of it as a device driver but rather an architecture > extension, so it started out in arch/ppc64/kernel. Since most of the code > is interacting with VFS, it is now in fs/spufs. I don't really care about > the location, but I among the possible places to put the code (with the > unified arch/powerpc tree), I'd suggest (best first) > > 1) arch/powerpc/platforms/cell > 2) arch/powerpc/spe > 3) fs/spufs > 4) drivers/spe > > 1) would be the place where I want to have the low-level code > (currently arch/ppc64/kernel/spu_base.c) anyway, so it makes > sense to have everything in there that I maintain. > 2) might work better if we at a later point have multiple platform > types in arch/powerpc that use SPEs, e.g if we want to keep > Playstation code separate from generic Cell. > I think putting it in 'arch/powerpc/platforms/cell' is fine for now. We'll be better able to judge if we need to and how to split off platform specifics when we have code for more cell platforms. -Geoff From cfriesen at nortel.com Tue Aug 30 04:41:10 2005 From: cfriesen at nortel.com (Christopher Friesen) Date: Mon, 29 Aug 2005 12:41:10 -0600 Subject: [PATCH] 1/2 Start header file merger (Was: Re: Beginning Merger Patch) In-Reply-To: <1125089709.32488.35.camel@cashmere.sps.mot.com> References: <1123023575.2614.25.camel@cashmere.sps.mot.com> <688ba2276de281a9473b030a16a514c0@embeddededge.com> <20050805174705.731ffa05.sfr@canb.auug.org.au> <200508051353.23750.arnd@arndb.de> <20050806005941.5d1fe432.sfr@canb.auug.org.au> <1125089709.32488.35.camel@cashmere.sps.mot.com> Message-ID: <431356C6.3070301@nortel.com> Jon Loeliger wrote: > Anyone care to take a semi-authoritative stand on what > symbol to use to distinguish 32/64-bit-ness in the > include files? I vote for __powerpc64__, if only to make it easier for the people who have to sanitize the kernel headers for use in userspace. Chris From johnrose at austin.ibm.com Tue Aug 30 06:26:25 2005 From: johnrose at austin.ibm.com (John Rose) Date: Mon, 29 Aug 2005 15:26:25 -0500 Subject: [patch 8/8] PCI Error Recovery: PPC64 core recovery routines In-Reply-To: <17170.44500.848623.139474@cargo.ozlabs.ibm.com> References: <20050823231817.829359000@bilge> <20050823232143.003048000@bilge> <20050823234747.GI18113@austin.ibm.com> <1124898331.24668.33.camel@sinatra.austin.ibm.com> <20050824162959.GC25174@austin.ibm.com> <17165.3205.505386.187453@cargo.ozlabs.ibm.com> <20050825161325.GG25174@austin.ibm.com> <17170.44500.848623.139474@cargo.ozlabs.ibm.com> Message-ID: <1125347185.19449.54.camel@sinatra.austin.ibm.com> Hi Paul- > > 2) As a result, the code to call hot-unplug is a bit messy. In > > particular, there's a bit of hoop-jumping when hotplug is built as > > as a module (and said hoops were wrecked recently when I moved the > > code around, out of the rpaphp directory). > > One way to clean this up would be to make rpaphp the driver for the > EADS bridges (from the pci code's point of view). Then it would > automatically get included in the error recovery process and could do > whatever it should. Not sure that I agree with this. Not all PCI hotplug slots have EADS devices as parents. This sort of topography dependency is something we're trying to break in rpaphp. Rpaphp could set this up for devices that do have EADS parents, but then we've only covered a subset of EEH-capable devices. Anyway, isn't the OS forbidden from performing most of the expected function of such a driver for EADS devices: Enable the device Access device configuration space Discover resources (addresses and IRQ numbers) provided by the device Allocate these resources Communicate with the device Disable the device Thanks- John From johnrose at austin.ibm.com Tue Aug 30 06:31:08 2005 From: johnrose at austin.ibm.com (John Rose) Date: Mon, 29 Aug 2005 15:31:08 -0500 Subject: [patch 8/8] PCI Error Recovery: PPC64 core recovery routines In-Reply-To: <1125347185.19449.54.camel@sinatra.austin.ibm.com> References: <20050823231817.829359000@bilge> <20050823232143.003048000@bilge> <20050823234747.GI18113@austin.ibm.com> <1124898331.24668.33.camel@sinatra.austin.ibm.com> <20050824162959.GC25174@austin.ibm.com> <17165.3205.505386.187453@cargo.ozlabs.ibm.com> <20050825161325.GG25174@austin.ibm.com> <17170.44500.848623.139474@cargo.ozlabs.ibm.com> <1125347185.19449.54.camel@sinatra.austin.ibm.com> Message-ID: <1125347468.19449.56.camel@sinatra.austin.ibm.com> > Not sure that I agree with this. Not all PCI hotplug slots have EADS > devices as parents. Ahem, "PCI hotplug" above should read "EEH-enabled". Sorry :) John From paulus at samba.org Tue Aug 30 09:31:48 2005 From: paulus at samba.org (Paul Mackerras) Date: Tue, 30 Aug 2005 09:31:48 +1000 Subject: please pull ppc64-2.6.git In-Reply-To: References: <17170.25803.413408.44080@cargo.ozlabs.ibm.com> Message-ID: <17171.39652.237263.484079@cargo.ozlabs.ibm.com> Linus Torvalds writes: > echo /pub/scm/linux/kernel/git/torvalds/linux-2.6/objects > objects/info/alternates Did that (s/linux-2.6/linux-2.6.git/ actually...) What can one put in the alternates file? Just an absolute path, or does a relative path or a URL work too? > or similar. That also makes gitweb able to show diffs etc, something it > can't do for a broken partial repository. Gitweb still doesn't work; I think someone needs to update the git on *.kernel.org. Paul. From torvalds at osdl.org Tue Aug 30 10:20:21 2005 From: torvalds at osdl.org (Linus Torvalds) Date: Mon, 29 Aug 2005 17:20:21 -0700 (PDT) Subject: please pull ppc64-2.6.git In-Reply-To: <17171.39652.237263.484079@cargo.ozlabs.ibm.com> References: <17170.25803.413408.44080@cargo.ozlabs.ibm.com> <17171.39652.237263.484079@cargo.ozlabs.ibm.com> Message-ID: On Tue, 30 Aug 2005, Paul Mackerras wrote: > > What can one put in the alternates file? Just an absolute path, or > does a relative path or a URL work too? Only an absolute path. URL's fundamentally do not work, and relative paths end up being parsed as relative to where-ever the user happens to be (and some commands will "chdir()" into the .git directory, while others will not). For a raw git directory like the ones on master.kernel.org, with a relative pathname (relative to the main git directory itself) the _pulling_ should actually happen to work, since that will be happening in the xxx.git directory using "GIT_DIR=.". But anything who uses GIT_DIR= from another directory wouldn't be able to use it. That probably includes gitweb, btw. So only do the absolute ones. Maybe we should define some well-specified meaning for relative ones, but it definitely isn't there now. > > or similar. That also makes gitweb able to show diffs etc, something it > > can't do for a broken partial repository. > > Gitweb still doesn't work; I think someone needs to update the git on > *.kernel.org. Hmm, yes. kernel.org is at 0.99.4, and the objects/info/alternates thing was done after that. It's in 0.99.5, though, so next time kernel.org updates its git version, it will automagically start working. (And I use my own git installation, so it works fine for me, and I just pulled the thing without problems). Linus From torvalds at osdl.org Tue Aug 30 11:17:26 2005 From: torvalds at osdl.org (Linus Torvalds) Date: Mon, 29 Aug 2005 18:17:26 -0700 (PDT) Subject: please pull ppc64-2.6.git In-Reply-To: <17171.39652.237263.484079@cargo.ozlabs.ibm.com> References: <17170.25803.413408.44080@cargo.ozlabs.ibm.com> <17171.39652.237263.484079@cargo.ozlabs.ibm.com> Message-ID: Paul, I get tons of warnings like include/linux/hugetlb.h:104:1: warning: "hugetlb_free_pgd_range" redefined In file included from include/linux/mm.h:36, from drivers/base/node.c:8: include/asm/pgtable.h:492:1: warning: this is the location of the previous definition after merging this. The generic code expects ARCH_HAS_HUGEPAGE_ONLY_RANGE to go hand-in-hand with hugetlb_free_pgd_range(). You do have that #define, but only when CONFIG_HUGETLB_PAGE is defined. But you define the "hugetlb_free_pgd_range()" thing unconditionally. Pls fix, Linus From david at gibson.dropbear.id.au Tue Aug 30 12:54:07 2005 From: david at gibson.dropbear.id.au (David Gibson) Date: Tue, 30 Aug 2005 12:54:07 +1000 (EST) Subject: [PATCH] Restore lparmap.s include for iSeries Message-ID: <20050830025407.D6B2368166@ozlabs.org> A mistake rebasing the series of ppc64 head.S cleanup patches meant the #include of lparmap.s, needed for iSeries was lost. This patch puts it back again. Signed-off-by: David Gibson --- arch/ppc64/kernel/head.S | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) Index: working-2.6/arch/ppc64/kernel/head.S =================================================================== --- working-2.6.orig/arch/ppc64/kernel/head.S 2005-08-30 12:41:28.000000000 +1000 +++ working-2.6/arch/ppc64/kernel/head.S 2005-08-30 12:48:16.000000000 +1000 @@ -1269,7 +1269,16 @@ .= 0x7000 .globl fwnmi_data_area fwnmi_data_area: - .space PAGE_SIZE + + /* iSeries does not use the FWNMI stuff, so it is safe to put + * this here, even if we later allow kernels that will boot on + * both pSeries and iSeries */ +#ifdef CONFIG_PPC_ISERIES + . = LPARMAP_PHYS +#include "lparmap.s" +#endif /* CONFIG_PPC_ISERIES */ + + . = 0x8000 /* * On pSeries, secondary processors spin in the following code. From david at gibson.dropbear.id.au Tue Aug 30 12:54:07 2005 From: david at gibson.dropbear.id.au (David Gibson) Date: Tue, 30 Aug 2005 12:54:07 +1000 (EST) Subject: [PATCH] PPC64: Abolish broken nested feature sections Message-ID: <20050830025407.E0D7268167@ozlabs.org> The {BEGIN,END}_FTR_SECTION asm macros used in ppc64 to nop out sections of code at runtime cannot be nested. However, we do nest them in hash_low.S. We get away with it there, because there is nothing between the BEGIN markers for each section. However, that's confusing to someone reading the code. This patch removes the nested ifset and ifclr feature sections, replacing them with a single feature section in the full mask/value form. Signed-off-by: David Gibson --- arch/ppc64/mm/hash_low.S | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) Index: working-2.6/arch/ppc64/mm/hash_low.S =================================================================== --- working-2.6.orig/arch/ppc64/mm/hash_low.S 2005-07-26 10:36:48.000000000 +1000 +++ working-2.6/arch/ppc64/mm/hash_low.S 2005-07-26 17:35:49.000000000 +1000 @@ -129,12 +129,10 @@ * code rather than call a C function...) */ BEGIN_FTR_SECTION -BEGIN_FTR_SECTION mr r4,r30 mr r5,r7 bl .hash_page_do_lazy_icache -END_FTR_SECTION_IFSET(CPU_FTR_NOEXECUTE) -END_FTR_SECTION_IFCLR(CPU_FTR_COHERENT_ICACHE) +END_FTR_SECTION(CPU_FTR_NOEXECUTE|CPU_FTR_COHERENT_ICACHE, CPU_FTR_NOEXECUTE) /* At this point, r3 contains new PP bits, save them in * place of "access" in the param area (sic) From paulus at samba.org Tue Aug 30 14:33:13 2005 From: paulus at samba.org (Paul Mackerras) Date: Tue, 30 Aug 2005 14:33:13 +1000 Subject: please pull ppc64-2.6.git In-Reply-To: References: <17170.25803.413408.44080@cargo.ozlabs.ibm.com> <17171.39652.237263.484079@cargo.ozlabs.ibm.com> Message-ID: <17171.57737.757041.432631@cargo.ozlabs.ibm.com> Linus Torvalds writes: > I get tons of warnings like > > include/linux/hugetlb.h:104:1: warning: "hugetlb_free_pgd_range" redefined > In file included from include/linux/mm.h:36, > from drivers/base/node.c:8: > include/asm/pgtable.h:492:1: warning: this is the location of the previous definition > > after merging this. The generic code expects ARCH_HAS_HUGEPAGE_ONLY_RANGE > to go hand-in-hand with hugetlb_free_pgd_range(). Fixed, plus some more patches checked in. Please do another pull from rsync://rsync.kernel.org/pub/scm/linux/kernel/git/paulus/ppc64-2.6.git Notably, this starts the merge process between ppc32 and ppc64 by creating an include/asm-powerpc directory and starting to move common header files into there. We plan to create an arch/powerpc for the common architecture and remove arch/ppc and arch/ppc64 (and include/asm-ppc and include/asm-ppc64) once the merge is done. Diffstat and log follow. (I don't know why diffstat does the b/ thing some times and not other times; I guess it's to do with the moved files. Is there a git command to get the diffstat other than doing git-diff-tree -p OLD_HEAD HEAD | diffstat ?) Paul. b/arch/ppc/Makefile | 11 ++ b/arch/ppc64/Makefile | 9 ++ b/arch/ppc64/configs/g5_defconfig | 6 - b/arch/ppc64/configs/iSeries_defconfig | 6 - b/arch/ppc64/configs/maple_defconfig | 6 - b/arch/ppc64/configs/pSeries_defconfig | 6 - b/arch/ppc64/defconfig | 6 - b/arch/ppc64/kernel/head.S | 16 +++- b/arch/ppc64/kernel/iSeries_vio.c | 21 ++++- b/arch/ppc64/kernel/lparcfg.c | 1 b/arch/ppc64/kernel/of_device.c | 2 b/arch/ppc64/kernel/pSeries_vio.c | 19 +++-- b/arch/ppc64/kernel/prom_init.c | 5 + b/arch/ppc64/kernel/vio.c | 75 +++++++------------ b/arch/ppc64/mm/hash_low.S | 4 - b/arch/ppc64/oprofile/common.c | 1 b/drivers/block/viodasd.c | 2 b/drivers/cdrom/viocd.c | 2 b/drivers/char/hvc_vio.c | 2 b/drivers/char/hvcs.c | 2 b/drivers/char/viotape.c | 2 b/drivers/net/ibmveth.c | 2 b/drivers/net/iseries_veth.c | 2 b/drivers/scsi/ibmvscsi/ibmvscsi.c | 2 b/drivers/scsi/ibmvscsi/rpa_vscsi.c | 1 b/include/asm-powerpc/8253pit.h | 10 ++ b/include/asm-powerpc/agp.h | 23 ++++++ b/include/asm-powerpc/cputime.h | 1 b/include/asm-powerpc/div64.h | 1 b/include/asm-powerpc/emergency-restart.h | 1 b/include/asm-powerpc/errno.h | 11 ++ b/include/asm-powerpc/ioctl.h | 69 ++++++++++++++++++ b/include/asm-powerpc/ioctls.h | 107 ++++++++++++++++++++++++++++ b/include/asm-powerpc/ipc.h | 1 b/include/asm-powerpc/linkage.h | 6 + b/include/asm-powerpc/local.h | 1 b/include/asm-powerpc/namei.h | 20 +++++ b/include/asm-powerpc/percpu.h | 1 b/include/asm-powerpc/poll.h | 23 ++++++ b/include/asm-powerpc/resource.h | 1 b/include/asm-powerpc/shmparam.h | 6 + b/include/asm-powerpc/string.h | 32 ++++++++ b/include/asm-powerpc/unaligned.h | 18 ++++ b/include/asm-powerpc/xor.h | 1 b/include/asm-ppc64/param.h | 4 - b/include/asm-ppc64/pgtable.h | 2 b/include/asm-ppc64/processor.h | 1 b/include/asm-ppc64/vio.h | 101 ++++++++++++-------------- b/include/linux/mod_devicetable.h | 7 + b/scripts/mod/file2alias.c | 19 +++++ include/asm-ppc/8253pit.h | 10 -- include/asm-ppc/agp.h | 23 ------ include/asm-ppc/cputime.h | 6 - include/asm-ppc/div64.h | 1 include/asm-ppc/emergency-restart.h | 6 - include/asm-ppc/errno.h | 11 -- include/asm-ppc/hdreg.h | 1 include/asm-ppc/ioctl.h | 69 ------------------ include/asm-ppc/ioctls.h | 107 ---------------------------- include/asm-ppc/ipc.h | 1 include/asm-ppc/linkage.h | 6 - include/asm-ppc/local.h | 6 - include/asm-ppc/namei.h | 20 ----- include/asm-ppc/percpu.h | 6 - include/asm-ppc/poll.h | 23 ------ include/asm-ppc/resource.h | 6 - include/asm-ppc/shmparam.h | 6 - include/asm-ppc/string.h | 32 -------- include/asm-ppc/unaligned.h | 18 ---- include/asm-ppc/xor.h | 1 include/asm-ppc64/8253pit.h | 10 -- include/asm-ppc64/agp.h | 23 ------ include/asm-ppc64/cputime.h | 6 - include/asm-ppc64/div64.h | 1 include/asm-ppc64/emergency-restart.h | 6 - include/asm-ppc64/errno.h | 18 ---- include/asm-ppc64/hdreg.h | 1 include/asm-ppc64/ioctl.h | 74 ------------------- include/asm-ppc64/ioctls.h | 114 ------------------------------ include/asm-ppc64/ipc.h | 1 include/asm-ppc64/linkage.h | 6 - include/asm-ppc64/local.h | 1 include/asm-ppc64/namei.h | 23 ------ include/asm-ppc64/percpu.h | 6 - include/asm-ppc64/poll.h | 32 -------- include/asm-ppc64/resource.h | 6 - include/asm-ppc64/shmparam.h | 13 --- include/asm-ppc64/string.h | 35 --------- include/asm-ppc64/unaligned.h | 21 ----- include/asm-ppc64/xor.h | 1 90 files changed, 533 insertions(+), 902 deletions(-) commit 8913ca1c9ccb5eb6471afd419159729eef6e2730 Author: David Gibson Date: Wed Jul 27 15:47:23 2005 +1000 [PATCH] Remove nested feature sections The {BEGIN,END}_FTR_SECTION asm macros used in ppc64 to nop out sections of code at runtime cannot be nested. However, we do nest them in hash_low.S. We get away with it there, because there is nothing between the BEGIN markers for each section. However, that's confusing to someone reading the code. This patch removes the nested ifset and ifclr feature sections, replacing them with a single feature section in the full mask/value form. Signed-off-by: David Gibson Signed-off-by: Paul Mackerras commit 597f95e2bfbe9b83ed8b0761ebf4e7d55fd4df17 Author: Joel Schopp Date: Fri Aug 12 14:34:58 2005 -0500 [PATCH] ppc64: lparconfig.c memory leak This patch fixes a rare memory leak found by Coverity. Signed-off-by: Joel Schopp Signed-off-by: Paul Mackerras commit 5ff98ae18bec792d77bfea801aa4b3385b98b355 Author: Joel Schopp Date: Thu Aug 11 17:39:28 2005 -0500 [PATCH] ppc64: of_device.c remove useless code Coverity found more unused code. Signed-off-by: Joel Schopp Signed-off-by: Paul Mackerras commit 717522ff44f1fbee5ea09e83d7cd4b5c956e30f9 Author: Anton Blanchard Date: Wed Aug 24 08:53:03 2005 +1000 [PATCH] ppc64: Add CONFIG_HZ While ppc64 has the CONFIG_HZ Kconfig option, it wasnt actually being used. Connect it up and set all platforms to 250Hz. Signed-off-by: Anton Blanchard Signed-off-by: Paul Mackerras commit 04ed65190a5d1562220dd3a7fc9eac2402c7104c Author: Jake Moilanen Date: Wed Aug 24 15:22:12 2005 -0500 [PATCH] oprofile PVR 970MP Here's the 970MP's PVR (processor version register) entry for oprofile. Signed-off-by: Jake Moilanen Signed-off-by: Paul Mackerras commit 7fea82ab1a74030f79a2adfac1af3d93b8638fc3 Author: Olof Johansson Date: Sun Aug 28 21:42:10 2005 -0500 [PATCH] PPC64: Don't try to claim memory from OF at 1GB mark Some RS64-based machines (p620, F80, others) have problems with firmware returning 0xdeadbeef instead of failure to allocations that end at the 1GB mark. We have two options: 1. Detect the undocumented 0xdeadbeef return value and interpret it as a failure. 2. Avoid allocating that high. (2) is really the cleaner solution here. 768MB is plenty of room so use that as the max alloc_top instead of 1GB. Signed-off-by: Olof Johansson Signed-off-by: Paul Mackerras commit 6f9aa727433fe7647869c9b64ce2f7b5feac0052 Author: Stephen Rothwell Date: Mon Aug 29 14:08:11 2005 +1000 [PATCH] Move all the very similar files to asm-powerpc They differed in either simple comments or in the protecting ifdefs. Signed-off-by: Stephen Rothwell Signed-off-by: Paul Mackerras commit 88999ceb55bf959e63df0c911915166b005977fc Author: Stephen Rothwell Date: Mon Aug 29 14:06:56 2005 +1000 [PATCH] Move the identical files from include/asm-ppc{,64} Move the identical files from include/asm-ppc{,64}/ to include/asm-powerpc/. Remove hdreg.h completely as it is unused in the tree. Signed-off-by: Stephen Rothwell Signed-off-by: Paul Mackerras commit 45e2a6e4e5e22acd4321f69e84b726c2a568dacf Author: Stephen Rothwell Date: Mon Aug 29 13:15:50 2005 +1000 [PATCH] Create include/asm-powerpc The ppc and ppc64 trees are hopefully going to merge over time, so this patch begins the process by creating a place for the merging of the header files. Create include/asm-powerpc (and move linkage.h into it from asm-{ppc,ppc64} since we don't like empty directories). Modify the ppc and ppc64 Makefiles to cope. Signed-off-by: Stephen Rothwell Signed-off-by: Paul Mackerras commit fb120da678c517f72d4b39932062c2191827b331 Author: Stephen Rothwell Date: Wed Aug 17 16:42:59 2005 +1000 [PATCH] Make MODULE_DEVICE_TABLE work for vio devices Make MODULE_DEVICE_TABLE work for vio devices. Signed-off-by: Stephen Rothwell Signed-off-by: Paul Mackerras commit 71d276d751ff5ddba28312aecefb174b20a5b970 Author: Stephen Rothwell Date: Wed Aug 17 16:41:44 2005 +1000 [PATCH] Create vio_bus_ops Create vio_bus_ops so that we just pass a structure to vio_bus_init instead of three separate function pointers. Rearrange vio.h to avoid forward references. vio.h only needs struct device_node from prom.h so remove the include and just declare it. Signed-off-by: Stephen Rothwell Signed-off-by: Paul Mackerras commit b877b90f227fb9698d99fb70492d432362584082 Author: Stephen Rothwell Date: Wed Aug 17 16:40:12 2005 +1000 [PATCH] Create vio_register_device Take some assignments out of vio_register_device_common and rename it to vio_register_device. Signed-off-by: Stephen Rothwell Signed-off-by: Paul Mackerras commit 5c0b4b8759f78c31172088a91e10733fc014ccee Author: Stephen Rothwell Date: Wed Aug 17 16:37:35 2005 +1000 [PATCH] Formatting changes to vio.c Formatting changes to vio.c to bring it closer to the kernel coding standard. Signed-off-by: Stephen Rothwell Signed-off-by: Paul Mackerras commit 1e4a79e0458beca871c662028610ae3a88e3f1bf Author: Stephen Rothwell Date: Mon Aug 29 18:26:01 2005 +1000 [PATCH] fix iSeries build for gcc-3.4 gcc 3.4 (at least the build we are using) puts the gcc generated .ident string into a .note section at the end of the files it compiles (gcc 3.3.3-hammer and gcc 4.0.2 Debian puts it in the .text section). This means that the lparmap.s file we produce in the iSeries build may end with a .note section. When we include it into head.S, the assembler can no longer resolve some of the conditional branches since the target label ends up too far away. This patch just forces us back to the .text section after including lparmap.s. The breakage was caused by my patch "iSeries build with newer assemblers and compilers" (sha1-id: 2ad56496627630ebc99f06af5f81ca23e17e014e). Signed-off-by: Stephen Rothwell Signed-off-by: Paul Mackerras commit 2739e8cf113ce6e931608986a28bab5a42c0acd9 Author: David Gibson Date: Tue Aug 30 12:54:07 2005 +1000 [PATCH] Restore lparmap.s include for iSeries A mistake rebasing the series of ppc64 head.S cleanup patches meant the #include of lparmap.s, needed for iSeries was lost. This patch puts it back again. Signed-off-by: David Gibson Signed-off-by: Paul Mackerras commit b74d0bd53406c23636707565d87ddaa55d315b26 Author: Andrew Morton Date: Wed Aug 10 13:53:41 2005 +1000 [PATCH] ppc64: four level pagetables fix With CONFIG_HUGETLB_PAGE=n: In file included from kernel/sysctl.c:37: include/linux/hugetlb.h:104:1: warning: "hugetlb_free_pgd_range" redefined In file included from include/linux/mm.h:36, from kernel/sysctl.c:23: include/asm/pgtable.h:492:1: warning: this is the location of the previous definition Signed-off-by: Andrew Morton Signed-off-by: David Gibson Signed-off-by: Paul Mackerras From paulus at samba.org Tue Aug 30 14:46:00 2005 From: paulus at samba.org (Paul Mackerras) Date: Tue, 30 Aug 2005 14:46:00 +1000 Subject: [PATCH] export htab value for kexec on non-lpar - cleaned up patch In-Reply-To: <20050829115207.GA2858@in.ibm.com> References: <20050823080423.GA2380@in.ibm.com> <20050824190652.GO1012@otto> <20050825044206.GA2079@in.ibm.com> <200508251649.26156.arnd@arndb.de> <20050829115207.GA2858@in.ibm.com> Message-ID: <17171.58504.946616.395669@cargo.ozlabs.ibm.com> R Sharada writes: > Hence modified the patch to reflect the changes suggested by Arnd and Nathan. > Hopefully, the patch is now in shape to be considered for inclusion. > Sending it herewith for acceptance I get: arch/ppc64/kernel/setup.c: In function 'export_htab_value': arch/ppc64/kernel/setup.c:1048: warning: initialization from incompatible pointer type arch/ppc64/kernel/setup.c:1055: warning: initialization from incompatible pointer type arch/ppc64/kernel/setup.c:1070: error: 'htab_size_prop' undeclared (first use in this function) arch/ppc64/kernel/setup.c:1070: error: (Each undeclared identifier is reported only once arch/ppc64/kernel/setup.c:1070: error: for each function it appears in.) arch/ppc64/kernel/setup.c:1052: warning: unused variable 'htab_base_size' make[1]: *** [arch/ppc64/kernel/setup.o] Error 1 make: *** [arch/ppc64/kernel] Error 2 Please fix and re-send. Paul. From paulus at samba.org Tue Aug 30 14:44:19 2005 From: paulus at samba.org (Paul Mackerras) Date: Tue, 30 Aug 2005 14:44:19 +1000 Subject: [patch 8/8] PCI Error Recovery: PPC64 core recovery routines In-Reply-To: <20050829160915.GD12618@austin.ibm.com> References: <20050823231817.829359000@bilge> <20050823232143.003048000@bilge> <20050823234747.GI18113@austin.ibm.com> <1124898331.24668.33.camel@sinatra.austin.ibm.com> <20050824162959.GC25174@austin.ibm.com> <17165.3205.505386.187453@cargo.ozlabs.ibm.com> <20050825161325.GG25174@austin.ibm.com> <17170.44500.848623.139474@cargo.ozlabs.ibm.com> <20050829160915.GD12618@austin.ibm.com> Message-ID: <17171.58403.920889.62559@cargo.ozlabs.ibm.com> Linas Vepstas writes: > > One way to clean this up would be to make rpaphp the driver for the > > EADS bridges (from the pci code's point of view). > > I guess I don't understand what that means. Are you suggesting moving > pSeries_pci.c into the rpaphp code directory? No, not at all. :) I'm suggesting that the rpaphp code has a struct pci_driver whose id_table and probe function are such that it will claim the EADS bridges. (It would probably be best to match on vendor=IBM and class=PCI-PCI bridge and let the probe function figure out which of the bridges it gets asked about are actually EADS bridges.) > I would prefer to deprecate the hot-plug based recovery scheme. This > is for many reasons, including the fact that some devices that can get > pci errors are soldered onto the planar, and are not hot-pluggable. Those devices can still be isolated and reset, can they not? And they still have an EADS bridge above them, don't they? Are there any that can't be dynamically reassigned from one partition to another? I.e., they may not be physically hotpluggable but they are still virtually hotpluggable as far as the partition is concerned, IIUC. Paul. From torvalds at osdl.org Tue Aug 30 14:48:17 2005 From: torvalds at osdl.org (Linus Torvalds) Date: Mon, 29 Aug 2005 21:48:17 -0700 (PDT) Subject: please pull ppc64-2.6.git In-Reply-To: <17171.57737.757041.432631@cargo.ozlabs.ibm.com> References: <17170.25803.413408.44080@cargo.ozlabs.ibm.com> <17171.39652.237263.484079@cargo.ozlabs.ibm.com> <17171.57737.757041.432631@cargo.ozlabs.ibm.com> Message-ID: On Tue, 30 Aug 2005, Paul Mackerras wrote: > > Diffstat and log follow. (I don't know why diffstat does the b/ thing > some times and not other times; I guess it's to do with the moved > files. Is there a git command to get the diffstat other than doing > git-diff-tree -p OLD_HEAD HEAD | diffstat ?) Use "diffstat -p1". Actually, preferably, use "git-apply --stat". The latter can also be used with the "--summary" flag, which knows about renames etc. So you can do git diff -M -p src..dst | git-apply --stat --summary and you'll see lines like rename include/{asm-ppc/8253pit.h => asm-powerpc/8253pit.h} (96%) rename include/{asm-ppc/agp.h => asm-powerpc/agp.h} (100%) create mode 100644 include/asm-powerpc/cputime.h rename include/{asm-ppc/div64.h => asm-powerpc/div64.h} (100%) create mode 100644 include/asm-powerpc/emergency-restart.h rename include/{asm-ppc/errno.h => asm-powerpc/errno.h} (100%) rename include/{asm-ppc/ioctl.h => asm-powerpc/ioctl.h} (100%) rename include/{asm-ppc/ioctls.h => asm-powerpc/ioctls.h} (100%) rename include/{asm-ppc/ipc.h => asm-powerpc/ipc.h} (100%) rename include/{asm-ppc/linkage.h => asm-powerpc/linkage.h} (100%) rename include/{asm-ppc64/local.h => asm-powerpc/local.h} (100%) rename include/{asm-ppc/namei.h => asm-powerpc/namei.h} (100%) create mode 100644 include/asm-powerpc/percpu.h rename include/{asm-ppc/poll.h => asm-powerpc/poll.h} (100%) create mode 100644 include/asm-powerpc/resource.h rename include/{asm-ppc/shmparam.h => asm-powerpc/shmparam.h} (100%) rename include/{asm-ppc/string.h => asm-powerpc/string.h} (100%) rename include/{asm-ppc/unaligned.h => asm-powerpc/unaligned.h} (100%) rename include/{asm-ppc/xor.h => asm-powerpc/xor.h} (100%) delete mode 100644 include/asm-ppc/cputime.h delete mode 100644 include/asm-ppc/emergency-restart.h delete mode 100644 include/asm-ppc/hdreg.h delete mode 100644 include/asm-ppc/local.h delete mode 100644 include/asm-ppc/percpu.h delete mode 100644 include/asm-ppc/resource.h delete mode 100644 include/asm-ppc64/8253pit.h delete mode 100644 include/asm-ppc64/agp.h delete mode 100644 include/asm-ppc64/cputime.h delete mode 100644 include/asm-ppc64/div64.h delete mode 100644 include/asm-ppc64/emergency-restart.h delete mode 100644 include/asm-ppc64/errno.h delete mode 100644 include/asm-ppc64/hdreg.h delete mode 100644 include/asm-ppc64/ioctl.h delete mode 100644 include/asm-ppc64/ioctls.h delete mode 100644 include/asm-ppc64/ipc.h delete mode 100644 include/asm-ppc64/linkage.h delete mode 100644 include/asm-ppc64/namei.h delete mode 100644 include/asm-ppc64/percpu.h delete mode 100644 include/asm-ppc64/poll.h delete mode 100644 include/asm-ppc64/resource.h delete mode 100644 include/asm-ppc64/shmparam.h delete mode 100644 include/asm-ppc64/string.h delete mode 100644 include/asm-ppc64/unaligned.h delete mode 100644 include/asm-ppc64/xor.h which in this case is a bit overwhelming, but it's nice when there's just a couple or renames etc. Linus From sharada at in.ibm.com Tue Aug 30 15:36:18 2005 From: sharada at in.ibm.com (R Sharada) Date: Tue, 30 Aug 2005 11:06:18 +0530 Subject: [PATCH] export htab value for kexec on non-lpar - cleaned up patch In-Reply-To: <17171.58504.946616.395669@cargo.ozlabs.ibm.com> References: <20050823080423.GA2380@in.ibm.com> <20050824190652.GO1012@otto> <20050825044206.GA2079@in.ibm.com> <200508251649.26156.arnd@arndb.de> <20050829115207.GA2858@in.ibm.com> <17171.58504.946616.395669@cargo.ozlabs.ibm.com> Message-ID: <20050830053618.GA1273@in.ibm.com> Hello Paulus, Hmm.. I did clean that warning and error messages up. Must have switched to the older patch while sending it out. My apologies. Here is the patch with the warning and errors cleaned up Thanks and Regards, Sharada Signed-off-by: R Sharada --- diff -puN include/asm-ppc64/mmu.h~kexec-export-htab-value include/asm-ppc64/mmu.h --- linux-2.6.13-rc6-org/include/asm-ppc64/mmu.h~kexec-export-htab-value 2005-08-25 05:27:35.000000000 +0530 +++ linux-2.6.13-rc6-org-sharada/include/asm-ppc64/mmu.h 2005-08-29 22:09:04.000000000 +0530 @@ -58,6 +58,7 @@ * Hash table */ +#define HASH_GROUP_SIZE 0x80 /* size of each hash group */ #define HPTES_PER_GROUP 8 #define HPTE_V_AVPN_SHIFT 7 diff -puN ./arch/ppc64/kernel/setup.c~kexec-export-htab-value ./arch/ppc64/kernel/setup.c --- linux-2.6.13-rc6-org/./arch/ppc64/kernel/setup.c~kexec-export-htab-value 2005-08-25 05:27:35.000000000 +0530 +++ linux-2.6.13-rc6-org-sharada/./arch/ppc64/kernel/setup.c 2005-08-30 16:37:30.000000000 +0530 @@ -1033,6 +1033,39 @@ void __init setup_syscall_map(void) count32, count64); } +static void __init export_htab_value(void) +{ + static unsigned long htab_base; + static struct property htab_base_prop = { + .name = "htab_base", + .length = sizeof(unsigned long), + .value = (unsigned char *)&htab_base, + }; + + static unsigned long htab_size; + static struct property htab_size_prop = { + .name = "htab_size", + .length = sizeof(unsigned long), + .value = (unsigned char *)&htab_size, + }; + + struct device_node *node; + + if (systemcfg->platform == PLATFORM_PSERIES_LPAR) + return; + + node = of_find_node_by_path("/chosen"); + if (!node) + return; + + htab_base = __pa(htab_address); + prom_add_property(node, &htab_base_prop); + htab_size = (htab_hash_mask + 1) * HASH_GROUP_SIZE; + prom_add_property(node, &htab_size_prop); + + of_node_put(node); +} + /* * Called into from start_kernel, after lock_kernel has been called. * Initializes bootmem, which is unsed to manage page allocation until @@ -1086,6 +1119,8 @@ void __init setup_arch(char **cmdline_p) } paging_init(); + /* export htab value into /proc/device-tree/chosen for kexec */ + export_htab_value(); ppc64_boot_msg(0x15, "Setup Done"); } _ From miltonm at realtime.net Tue Aug 30 15:47:53 2005 From: miltonm at realtime.net (Milton D. Miller II) Date: Tue, 30 Aug 2005 00:47:53 -0500 (CDT) Subject: [PATCH 2/12] ppc64: Fixup __after_prom_start to use phys address returned from prom_init() In-Reply-To: <20050826025321.0E6F368051@ozlabs.org> Message-ID: <200508300547.j7U5lr6l033948@sullivan.realtime.net> Michael Ellerman wrote: > > This patch removes a FIXME in head.S. prom_init() calculates the physical > address of __start and passes it to the kernel, however currently the code > ignores this value and recalculates. > > So instead just use the value provided by prom_init(). > > Signed-off-by: Michael Ellerman > --- > > arch/ppc64/kernel/head.S | 15 +++++---------- > 1 files changed, 5 insertions(+), 10 deletions(-) > > Index: work/arch/ppc64/kernel/head.S > =================================================================== > --- work.orig/arch/ppc64/kernel/head.S > +++ work/arch/ppc64/kernel/head.S > @@ -1441,8 +1441,8 @@ _STATIC(__boot_from_prom) > trap > > /* > - * At this point, r3 contains the physical address we are running at, > - * returned by prom_init() > + * At this point, r30 contains the physical address of __start, returned > + * by prom_init() > */ 1) its not necessarly from prom_init 2) its not returned, its a parameter on the new call. I think this code would be clearer if we moved the call to prom_init to be the straight path (reversed the sense of the initial compare to r5) and have a "we skip to after the trap branch" for the kexec/other non-prom callback bootloader case. Somewhere I have a patch to do that, buried in a tree mixed with something else most likely. milton > _STATIC(__after_prom_start) > > @@ -1458,17 +1458,11 @@ _STATIC(__after_prom_start) > * r26 == relocation offset > * r27 == KERNELBASE > */ > - bl .reloc_offset > - mr r26,r3 > SET_REG_TO_CONST(r27,KERNELBASE) > > li r3,0 /* target addr */ > > - // XXX FIXME: Use phys returned by OF (r30) > - sub r4,r27,r26 /* source addr */ > - /* current address of _start */ > - /* i.e. where we are running */ > - /* the source addr */ > + mr r4,r30 /* source, current addr of __start */ > > LOADADDR(r5,copy_to_here) /* # bytes of memory to copy */ > sub r5,r5,r27 > @@ -1485,7 +1479,8 @@ _STATIC(__after_prom_start) > bctr > > 4: LOADADDR(r5,klimit) > - sub r5,r5,r26 > + sub r5,r5,r27 /* subtract KERNELBASE */ > + add r5,r5,r30 /* add physical offset to __start */ > ld r5,0(r5) /* get the value of klimit */ > sub r5,r5,r27 > bl .copy_and_flush /* copy the rest */ > From miltonm at realtime.net Tue Aug 30 15:41:20 2005 From: miltonm at realtime.net (Milton D. Miller II) Date: Tue, 30 Aug 2005 00:41:20 -0500 (CDT) Subject: [PATCH 10/12] ppc64: Reroute interrupts from zero + offset to KERNELBASE + offset In-Reply-To: <20050826025331.84994680F7@ozlabs.org> Message-ID: <200508300541.j7U5fK9G033936@sullivan.realtime.net> > From michael at ellerman.id.au Fri Aug 26 12:53:31 2005 > From: michael at ellerman.id.au (Michael Ellerman) > Date: Fri Aug 26 12:53:42 2005 > Subject: [PATCH 10/12] ppc64: Reroute interrupts from zero + offset to > KERNELBASE + offset > In-Reply-To: <1125024799.128302.675577398916.qpatch at concordia> > > Regardless of where the kernel's linked we always get interrupts at low > addresses. This patch creates a trampoline in the first 3 pages of memory, > where interrupts land, and patches those addresses to jump into the real > kernel code at KERNELBASE. > > We also need to reserve the low pages of memory in prom.c, as well as > __pa(KERNELBASE) to __pa(klimit). > > FIXME, 0x8000 should be a #define. Actually we should reserve 0 to __pa(KERNELBASE) for testing kdump environment... Do we work if the reserve of low memory is not part of the mem= ? In kdump, this memory will not be part of the "mem=" line passed to the capture kernel. Why is it 0x8000 for the reserve and 0x3000 for the trampoline? Do we know what we expect the trampoline will save? page 9 is the initial stab (for RS64 and POWER3), or are you using the new rearranged low memory patch? > > Signed-off-by: Michael Ellerman > --- > > arch/ppc64/kernel/prom.c | 5 ++++- > arch/ppc64/kernel/setup.c | 22 ++++++++++++++++++++++ > 2 files changed, 26 insertions(+), 1 deletion(-) > > Index: work/arch/ppc64/kernel/setup.c > =================================================================== > --- work.orig/arch/ppc64/kernel/setup.c > +++ work/arch/ppc64/kernel/setup.c > @@ -362,6 +362,26 @@ static struct machdep_calls __initdata * > NULL > }; > > +#ifdef CONFIG_KDUMP_CAPTURE_KERNEL > +static void setup_kdump_trampoline(void) > +{ > + unsigned long i; > + unsigned int *addr; > + > + /* XXX this only works if PHYSICAL_START <= 32 MB */ how about an #error ? > + > + for (i = 0x100; i < 0x3000; i += 8) { > + addr = (unsigned int *)i; > + *addr++ = 0x60000000; /* nop */ > + *addr = 0x48000000 | ((PHYSICAL_START - 1) & 0x03fffffc); > + > + asm ("dcbst 0,%0; sync; icbi 0,%0; isync" : : "r" (addr)); every 8 bytes is a bit overkill, but ok. The -1 should be -4, its the instruction target.. Others have commented on the comments for the patching. The trick of doing a nop to extend the range to 32k should be explicitly stated. Another approach is to copy pages 0-3 down to pages 0-3 and execute the copy there. It does mean that we can't use relative branchs from there to the "main" kernel. > + } > +} > +#else > +static inline void setup_kdump_trampoline(void) { } > +#endif > + > /* > * Early initialization entry point. This is called by head.S > * with MMU translation disabled. We rely on the "feature" of > @@ -394,6 +414,8 @@ void __init early_setup(unsigned long dt > > DBG(" -> early_setup()\n"); > > + setup_kdump_trampoline(); > + > /* > * Fill the default DBG level (do we want to keep > * that old mecanism around forever ?) > Index: work/arch/ppc64/kernel/prom.c > =================================================================== > --- work.orig/arch/ppc64/kernel/prom.c > +++ work/arch/ppc64/kernel/prom.c > @@ -1241,7 +1241,10 @@ void __init early_init_devtree(void *par > lmb_enforce_memory_limit(); > lmb_analyze(); > systemcfg->physicalMemorySize = lmb_phys_mem_size(); > - lmb_reserve(0, __pa(klimit)); > + lmb_reserve(__pa(KERNELBASE), __pa(klimit)); > +#ifdef CONFIG_KDUMP_CAPTURE_KERNEL > + lmb_reserve(0, 0x8000); /* Reserve the trampoline */ > +#endif > > DBG("Phys. mem: %lx\n", systemcfg->physicalMemorySize); > > milton From miltonm at realtime.net Tue Aug 30 16:02:19 2005 From: miltonm at realtime.net (Milton D. Miller II) Date: Tue, 30 Aug 2005 01:02:19 -0500 (CDT) Subject: [PATCH 9/12] ppc64: Misc fixups for non-zero KERNELBASE In-Reply-To: <20050826025329.2883F680F7@ozlabs.org> Message-ID: <200508300602.j7U62J4A033998@sullivan.realtime.net> Michael Ellerman wrote: > The code to do startup of secondary cpus assumes it only needs to load the low > halfword of the __secondary_hold_* symbols. This won't work if we build the > kernel at 32 MB. > No, the cpus are spinning on a copy of the code running below address 100 (or they should be). The secondary_hold symbols sholuld be the ones in this copy. Doing this (and the 0x60 offset)is part of the kexec calling interface. Using LOAD_ADDR makes the code less common with ppc(32) becasue it must do the relocate. > The interrupt prolog code for pSeries assumes it can get the address of the > interrupt handler by just loading the top and bottom halfwords of the address. > This doesn't work if the kernel's linked too far above zero. We'd like to use > SET_REG_TO_LABEL(), but we're short on space, so we simply augment the > existing hack. > This is a dependent op on back-to-back operations. We only need this for PHYSICAL_START > 0x4000 or so. Lets code that explictly into the macro with a test for PHYSICAL_START > 0. You took out the scheduling of putting independent ops between the clear and the ori of the lower half. This just cost the main kernel several wasted cycles. (No, I didn't sim this to count). The third segment (moving the dest) is probably ok although does have 3 unnecessary instructions. milton > Signed-off-by: Michael Ellerman > --- > > arch/ppc64/kernel/head.S | 14 +++++++------- > 1 files changed, 7 insertions(+), 7 deletions(-) > > Index: work/arch/ppc64/kernel/head.S > =================================================================== > --- work.orig/arch/ppc64/kernel/head.S > +++ work/arch/ppc64/kernel/head.S > @@ -143,13 +143,12 @@ _GLOBAL(__secondary_hold) > mr r24,r3 > > /* Tell the master cpu we're here */ > - /* Relocation is off & we are located at an address less */ > - /* than 0x100, so only need to grab low order offset. */ > - std r24,__secondary_hold_acknowledge at l(0) > + LOADADDR(r4, __secondary_hold_acknowledge) > + std r24,0(r4) > sync > > /* All secondary cpus wait here until told to start. */ > -100: ld r4,__secondary_hold_spinloop at l(0) > +100: LOADADDR(r4, __secondary_hold_spinloop) > cmpdi 0,r4,1 > bne 100b > > @@ -210,9 +209,10 @@ exception_marker: > std r9,area+EX_R13(r13); \ > mfcr r9; \ > clrrdi r12,r13,32; /* get high part of &label */ \ > + oris r12,r12,(label)@h; /* virt addr of handler ... */ \ > + ori r12,r12,(label)@l; /* .. and the rest */ \ > mfmsr r10; \ > mfspr r11,SRR0; /* save SRR0 */ \ > - ori r12,r12,(label)@l; /* virt addr of handler */ \ > ori r10,r10,MSR_IR|MSR_DR|MSR_RI; \ > mtspr SRR0,r12; \ > mfspr r12,SRR1; /* and SRR1 */ \ > @@ -1446,7 +1446,7 @@ _STATIC(__boot_from_prom) > _STATIC(__after_prom_start) > > /* > - * We need to run with __start at physical address 0. > + * We need to run with __start at physical address KERNELBASE. > * This will leave some code in the first 256B of > * real memory, which are reserved for software use. > * The remainder of the first page is loaded with the fixed > @@ -1459,7 +1459,7 @@ _STATIC(__after_prom_start) > */ > SET_REG_TO_CONST(r27,KERNELBASE) > > - li r3,0 /* target addr */ > + LOADADDR(r3, PHYSICAL_START) /* target addr */ > > mr r4,r30 /* source, current addr of __start */ > > From miltonm at realtime.net Tue Aug 30 16:09:03 2005 From: miltonm at realtime.net (Milton D. Miller II) Date: Tue, 30 Aug 2005 01:09:03 -0500 (CDT) Subject: [PATCH 11/12] ppc64: Move fwnmi vectors into trampoline area In-Reply-To: <20050826025332.0952F680E9@ozlabs.org> Message-ID: <200508300609.j7U693rL034018@sullivan.realtime.net> Michael Ellerman wrote: > The fwnmi vectors can be anywhere < 32 MB, so we need to use a trampoline > for them too. We've got plenty of room below 0x3000, so just plonk them in > there and the existing trampoline code will do what we want. If we ever > run out of space below 0x3000 we can change the code to patch the fwnmi > vectors explictly. 1) Addresses below 0x3000 are reserved by the (processor?) architecture to add interrupt vectors. This patch might collide with them. 2) Without making sure the old and new vecotors are at the same place, the call may not succeed. 3) We are going to call rtas to register these vectors again. I would much prefer we test that rtas handles us calling register again with a different address to move the vector addresses. (We need to test Power4 SMP, LPAR, and Power5. I don't expect problems). milton > > Signed-off-by: Michael Ellerman > --- > > arch/ppc64/kernel/head.S | 37 ++++++++++++++++++++----------------- > arch/ppc64/kernel/pSeries_setup.c | 14 +++++++++----- > 2 files changed, 29 insertions(+), 22 deletions(-) > > Index: work/arch/ppc64/kernel/head.S > =================================================================== > --- work.orig/arch/ppc64/kernel/head.S > +++ work/arch/ppc64/kernel/head.S > @@ -494,6 +494,26 @@ system_call_pSeries: > STD_EXCEPTION_PSERIES(0x1300, instruction_breakpoint) > STD_EXCEPTION_PSERIES(0x1700, altivec_assist) > > + /* > + * Vectors for the FWNMI option. Share common code. > + * For kdump's sake these must be < 0x3000 and 8-byte aligned. > + */ > + .align 7 > + .globl system_reset_fwnmi > +system_reset_fwnmi: > + HMT_MEDIUM > + mtspr SPRG1,r13 /* save r13 */ > + RUNLATCH_ON(r13) > + EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common) > + > + .align 7 > + .globl machine_check_fwnmi > +machine_check_fwnmi: > + HMT_MEDIUM > + mtspr SPRG1,r13 /* save r13 */ > + RUNLATCH_ON(r13) > + EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common) > + > . = 0x3000 > > /*** pSeries interrupt support ***/ > @@ -507,23 +527,6 @@ _GLOBAL(do_stab_bolted_pSeries) > mfspr r12,SPRG2 > EXCEPTION_PROLOG_PSERIES(PACA_EXSLB, .do_stab_bolted) > > -/* > - * Vectors for the FWNMI option. Share common code. > - */ > - .globl system_reset_fwnmi > -system_reset_fwnmi: > - HMT_MEDIUM > - mtspr SPRG1,r13 /* save r13 */ > - RUNLATCH_ON(r13) > - EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common) > - > - .globl machine_check_fwnmi > -machine_check_fwnmi: > - HMT_MEDIUM > - mtspr SPRG1,r13 /* save r13 */ > - RUNLATCH_ON(r13) > - EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common) > - > #ifdef CONFIG_PPC_ISERIES > /*** ISeries-LPAR interrupt handlers ***/ > > Index: work/arch/ppc64/kernel/pSeries_setup.c > =================================================================== > --- work.orig/arch/ppc64/kernel/pSeries_setup.c > +++ work/arch/ppc64/kernel/pSeries_setup.c > @@ -108,14 +108,18 @@ void pSeries_get_cpuinfo(struct seq_file > */ > static void __init fwnmi_init(void) > { > - int ret; > + unsigned long v1, v2; > + > int ibm_nmi_register = rtas_token("ibm,nmi-register"); > if (ibm_nmi_register == RTAS_UNKNOWN_SERVICE) > return; > - ret = rtas_call(ibm_nmi_register, 2, 1, NULL, > - __pa((unsigned long)system_reset_fwnmi), > - __pa((unsigned long)machine_check_fwnmi)); > - if (ret == 0) > + > + /* We point the firmware at low addresses, and use a trampoline to > + * get up to the real code at KERNELBASE. */ > + v1 = (unsigned long)system_reset_fwnmi - KERNELBASE; > + v2 = (unsigned long)machine_check_fwnmi - KERNELBASE; > + > + if (0 == rtas_call(ibm_nmi_register, 2, 1, NULL, v1, v2)) > fwnmi_active = 1; > } > > From michael at ellerman.id.au Tue Aug 30 16:50:47 2005 From: michael at ellerman.id.au (Michael Ellerman) Date: Tue, 30 Aug 2005 16:50:47 +1000 Subject: [PATCH 2/12] ppc64: Fixup __after_prom_start to use phys address returned from prom_init() In-Reply-To: <200508300547.j7U5lr6l033948@sullivan.realtime.net> References: <200508300547.j7U5lr6l033948@sullivan.realtime.net> Message-ID: <200508301650.50164.michael@ellerman.id.au> On Tue, 30 Aug 2005 15:47, Milton D. Miller II wrote: > Michael Ellerman wrote: > > /* > > - * At this point, r3 contains the physical address we are running at, > > - * returned by prom_init() > > + * At this point, r30 contains the physical address of __start, returned > > + * by prom_init() > > */ > > 1) its not necessarly from prom_init > > 2) its not returned, its a parameter on the new call. You're right, I was just updating the comment per my changes, I didn't check if it was *actually correct* :D > I think this code would be clearer if we moved the call to prom_init > to be the straight path (reversed the sense of the initial compare to > r5) and have a "we skip to after the trap branch" for the kexec/other > non-prom callback bootloader case. > > Somewhere I have a patch to do that, buried in a tree mixed with > something else most likely. Yeah you're right that probably would be cleaner. If you can't find that patch anytime soon I'll do it myself when I get to it next. cheers -- Michael Ellerman IBM OzLabs email: michael:ellerman.id.au inmsg: mpe:jabber.org wwweb: http://michael.ellerman.id.au phone: +61 2 6212 1183 (tie line 70 21183) We do not inherit the earth from our ancestors, we borrow it from our children. - S.M.A.R.T Person -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: not available Url : http://ozlabs.org/pipermail/linuxppc64-dev/attachments/20050830/73bbe062/attachment.pgp From michael at ellerman.id.au Tue Aug 30 17:04:48 2005 From: michael at ellerman.id.au (Michael Ellerman) Date: Tue, 30 Aug 2005 17:04:48 +1000 Subject: [PATCH 11/12] ppc64: Move fwnmi vectors into trampoline area In-Reply-To: <200508300609.j7U693rL034018@sullivan.realtime.net> References: <200508300609.j7U693rL034018@sullivan.realtime.net> Message-ID: <200508301704.48872.michael@ellerman.id.au> On Tue, 30 Aug 2005 16:09, Milton D. Miller II wrote: > Michael Ellerman wrote: > > The fwnmi vectors can be anywhere < 32 MB, so we need to use a trampoline > > for them too. We've got plenty of room below 0x3000, so just plonk them > > in there and the existing trampoline code will do what we want. If we > > ever run out of space below 0x3000 we can change the code to patch the > > fwnmi vectors explictly. > > 1) Addresses below 0x3000 are reserved by the (processor?) architecture > to add interrupt vectors. This patch might collide with them. Yeah it's reserved up to 0x3000 in the green book. My reasoning was that when a chip comes out that uses those addresses we'll know about it and we can move the fwmni vectors some where else, in the meantime it's just empty space. > 2) Without making sure the old and new vecotors are at the same place, > the call may not succeed. > > 3) We are going to call rtas to register these vectors again. > > I would much prefer we test that rtas handles us calling register again > with a different address to move the vector addresses. Do you mean the old and new vectors should be in the same place, or different places? If they're in the same place then perhaps we don't even need to re-register them? cheers -- Michael Ellerman IBM OzLabs email: michael:ellerman.id.au inmsg: mpe:jabber.org wwweb: http://michael.ellerman.id.au phone: +61 2 6212 1183 (tie line 70 21183) We do not inherit the earth from our ancestors, we borrow it from our children. - S.M.A.R.T Person -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: not available Url : http://ozlabs.org/pipermail/linuxppc64-dev/attachments/20050830/c96a7b45/attachment.pgp From miltonm at bga.com Tue Aug 30 17:07:04 2005 From: miltonm at bga.com (Milton Miller) Date: Tue, 30 Aug 2005 02:07:04 -0500 Subject: Fwd: [PATCH 10/12] ppc64: Reroute interrupts from zero + offset to KERNELBASE + offset Message-ID: <0ef6622eec9f4aedf06259a4c86c7dd0@bga.com> Oops put the wrong address on this one for the list. I also see that the sending address is wrong, please reply to miltonm at bga.com. The disadvantages of a multi-domain ISP. milton Begin forwarded message: > From: "Milton D. Miller II" > Date: August 30, 2005 12:41:20 AM CDT > To: michael at ellerman.id.au > Cc: linuxppc64-dev at ozlabs.com > Subject: Re: [PATCH 10/12] ppc64: Reroute interrupts from zero + > offset to KERNELBASE + offset > >> From michael at ellerman.id.au Fri Aug 26 12:53:31 2005 >> From: michael at ellerman.id.au (Michael Ellerman) >> Date: Fri Aug 26 12:53:42 2005 >> Subject: [PATCH 10/12] ppc64: Reroute interrupts from zero + offset to >> KERNELBASE + offset >> In-Reply-To: <1125024799.128302.675577398916.qpatch at concordia> >> >> Regardless of where the kernel's linked we always get interrupts at >> low >> addresses. This patch creates a trampoline in the first 3 pages of >> memory, >> where interrupts land, and patches those addresses to jump into the >> real >> kernel code at KERNELBASE. >> >> We also need to reserve the low pages of memory in prom.c, as well as >> __pa(KERNELBASE) to __pa(klimit). >> >> FIXME, 0x8000 should be a #define. > > > Actually we should reserve 0 to __pa(KERNELBASE) for testing kdump > environment... > > Do we work if the reserve of low memory is not part of the mem= ? > In kdump, this memory will not be part of the "mem=" line passed to > the capture kernel. > > Why is it 0x8000 for the reserve and 0x3000 for the trampoline? > Do we know what we expect the trampoline will save? > > page 9 is the initial stab (for RS64 and POWER3), or are you using > the new rearranged low memory patch? > > > >> >> Signed-off-by: Michael Ellerman >> --- >> >> arch/ppc64/kernel/prom.c | 5 ++++- >> arch/ppc64/kernel/setup.c | 22 ++++++++++++++++++++++ >> 2 files changed, 26 insertions(+), 1 deletion(-) >> >> Index: work/arch/ppc64/kernel/setup.c >> =================================================================== >> --- work.orig/arch/ppc64/kernel/setup.c >> +++ work/arch/ppc64/kernel/setup.c >> @@ -362,6 +362,26 @@ static struct machdep_calls __initdata * >> NULL >> }; >> >> +#ifdef CONFIG_KDUMP_CAPTURE_KERNEL >> +static void setup_kdump_trampoline(void) >> +{ >> + unsigned long i; >> + unsigned int *addr; >> + >> + /* XXX this only works if PHYSICAL_START <= 32 MB */ > > how about an #error ? > >> + >> + for (i = 0x100; i < 0x3000; i += 8) { >> + addr = (unsigned int *)i; >> + *addr++ = 0x60000000; /* nop */ >> + *addr = 0x48000000 | ((PHYSICAL_START - 1) & 0x03fffffc); >> + >> + asm ("dcbst 0,%0; sync; icbi 0,%0; isync" : : "r" (addr)); > > every 8 bytes is a bit overkill, but ok. The -1 should be -4, its the > instruction target.. > > Others have commented on the comments for the patching. The > trick of doing a nop to extend the range to 32k should be > explicitly stated. > > > Another approach is to copy pages 0-3 down to pages 0-3 and execute the > copy there. It does mean that we can't use relative branchs from there > to the "main" kernel. > >> + } >> +} >> +#else >> +static inline void setup_kdump_trampoline(void) { } >> +#endif >> + >> /* >> * Early initialization entry point. This is called by head.S >> * with MMU translation disabled. We rely on the "feature" of >> @@ -394,6 +414,8 @@ void __init early_setup(unsigned long dt >> >> DBG(" -> early_setup()\n"); >> >> + setup_kdump_trampoline(); >> + >> /* >> * Fill the default DBG level (do we want to keep >> * that old mecanism around forever ?) >> Index: work/arch/ppc64/kernel/prom.c >> =================================================================== >> --- work.orig/arch/ppc64/kernel/prom.c >> +++ work/arch/ppc64/kernel/prom.c >> @@ -1241,7 +1241,10 @@ void __init early_init_devtree(void *par >> lmb_enforce_memory_limit(); >> lmb_analyze(); >> systemcfg->physicalMemorySize = lmb_phys_mem_size(); >> - lmb_reserve(0, __pa(klimit)); >> + lmb_reserve(__pa(KERNELBASE), __pa(klimit)); >> +#ifdef CONFIG_KDUMP_CAPTURE_KERNEL >> + lmb_reserve(0, 0x8000); /* Reserve the trampoline */ >> +#endif >> >> DBG("Phys. mem: %lx\n", systemcfg->physicalMemorySize); >> >> > > milton > From miltonm at bga.com Tue Aug 30 17:22:53 2005 From: miltonm at bga.com (Milton Miller) Date: Tue, 30 Aug 2005 02:22:53 -0500 Subject: [PATCH 11/12] ppc64: Move fwnmi vectors into trampoline area In-Reply-To: <200508300609.j7U693rL034018@sullivan.realtime.net> References: <200508300609.j7U693rL034018@sullivan.realtime.net> Message-ID: Sorry for the broken threading, I only saw Michael's reply via the web. key: > > Milton Miller quotes > Michael Ellerman quotes > > > > 1) Addresses below 0x3000 are reserved by the (processor?) > architecture > > to add interrupt vectors. This patch might collide with them. > > Yeah it's reserved up to 0x3000 in the green book. My reasoning was > that when > a chip comes out that uses those addresses we'll know about it and we > can > move the fwmni vectors some where else, in the meantime it's just empty > space. By following the architecture, we have a chance of booting on CPUs that we don't know about yet. We also find out with a more deterministic crash when we are slow to add support for a new feature. Following the architecture will save us in the long run. [success story censored] > > > 2) Without making sure the old and new vecotors are at the same > place, > > the call may not succeed. > > > > 3) We are going to call rtas to register these vectors again. > > > > I would much prefer we test that rtas handles us calling register > again > > with a different address to move the vector addresses. > > Do you mean the old and new vectors should be in the same place, or > different > places? If they're in the same place then perhaps we don't even need to > re-register them? I'm saying if rtas and the hypervisor accept the new address then we don't have to worry. If they don't accept an address, then we must reserve a fixed address in page 3 and only support dump of a base kernel of some minimum level. So let us test now if the address is accepted, and if so not worry about a "low" vector or trampoline for these entry points. On Aug 30, 2005, at 1:09 AM, Milton D. Miller II wrote: From michael at ellerman.id.au Tue Aug 30 17:22:05 2005 From: michael at ellerman.id.au (Michael Ellerman) Date: Tue, 30 Aug 2005 17:22:05 +1000 Subject: [PATCH 10/12] ppc64: Reroute interrupts from zero + offset to KERNELBASE + offset In-Reply-To: <200508300541.j7U5fK9G033936@sullivan.realtime.net> References: <200508300541.j7U5fK9G033936@sullivan.realtime.net> Message-ID: <200508301722.05643.michael@ellerman.id.au> On Tue, 30 Aug 2005 15:41, Milton D. Miller II wrote: > > From michael at ellerman.id.au Fri Aug 26 12:53:31 2005 > > We also need to reserve the low pages of memory in prom.c, as well as > > __pa(KERNELBASE) to __pa(klimit). > > > > FIXME, 0x8000 should be a #define. > > Actually we should reserve 0 to __pa(KERNELBASE) for testing kdump > environment... Why's that? > Do we work if the reserve of low memory is not part of the mem= ? > In kdump, this memory will not be part of the "mem=" line passed to > the capture kernel. Not quite sure what you mean here? I was thinking the second kernel would detect it's memory constraints via the device tree (crashk_start etc). rather than by using mem=. Although I guess either could work, and perhaps mem= is better - less custom KDUMP code. > Why is it 0x8000 for the reserve and 0x3000 for the trampoline? > Do we know what we expect the trampoline will save? The trampoline is only for vectors, so up to 0x3000. The reserve includes the fwnmi data area and basically everything in head.S > page 9 is the initial stab (for RS64 and POWER3), or are you using > the new rearranged low memory patch? Yeah I'm using David's patches, so 0x8000 is the top of the important bits in head.S > > +#ifdef CONFIG_KDUMP_CAPTURE_KERNEL > > +static void setup_kdump_trampoline(void) > > +{ > > + unsigned long i; > > + unsigned int *addr; > > + > > + /* XXX this only works if PHYSICAL_START <= 32 MB */ > > how about an #error ? Yep, just hadn't got to it yet. I think I saw some "BUILD_BUG" macro somewhere, or am I mad. > > + > > + for (i = 0x100; i < 0x3000; i += 8) { > > + addr = (unsigned int *)i; > > + *addr++ = 0x60000000; /* nop */ > > + *addr = 0x48000000 | ((PHYSICAL_START - 1) & 0x03fffffc); > > + > > + asm ("dcbst 0,%0; sync; icbi 0,%0; isync" : : "r" (addr)); > > every 8 bytes is a bit overkill, but ok. The -1 should be -4, its the > instruction target.. Well yeah, it could probably be 0x100, but this way any new vectors that get added at weird places will also be caught. It is - 4 because of the mask, but I guess actually having "- 4" would be clearer. > Others have commented on the comments for the patching. The > trick of doing a nop to extend the range to 32k should be > explicitly stated. Yep it's ugly. I think I'll make a macro for it, we synthesise branches in a few places. > Another approach is to copy pages 0-3 down to pages 0-3 and execute the > copy there. It does mean that we can't use relative branchs from there > to the "main" kernel. Yeah I thought about that. But we'd have to link head.S differently, somehow, and given that most of the code in head.S is happy to be at 32 MB I decided the trampoline was an easier option. cheers -- Michael Ellerman IBM OzLabs email: michael:ellerman.id.au inmsg: mpe:jabber.org wwweb: http://michael.ellerman.id.au phone: +61 2 6212 1183 (tie line 70 21183) We do not inherit the earth from our ancestors, we borrow it from our children. - S.M.A.R.T Person -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: not available Url : http://ozlabs.org/pipermail/linuxppc64-dev/attachments/20050830/24f7572a/attachment.pgp From michael at ellerman.id.au Tue Aug 30 17:28:34 2005 From: michael at ellerman.id.au (Michael Ellerman) Date: Tue, 30 Aug 2005 17:28:34 +1000 Subject: [PATCH 11/12] ppc64: Move fwnmi vectors into trampoline area In-Reply-To: References: <200508300609.j7U693rL034018@sullivan.realtime.net> Message-ID: <200508301728.35097.michael@ellerman.id.au> On Tue, 30 Aug 2005 17:22, Milton Miller wrote: > > Yeah it's reserved up to 0x3000 in the green book. My reasoning was > > that when > > a chip comes out that uses those addresses we'll know about it and we > > can > > move the fwmni vectors some where else, in the meantime it's just empty > > space. > > By following the architecture, we have a chance of booting on CPUs that > we don't know about yet. We also find out with a more deterministic > crash when we are slow to add support for a new feature. > > Following the architecture will save us in the long run. > [success story censored] Ok, I'll fix it. > > Do you mean the old and new vectors should be in the same place, or > > different > > places? If they're in the same place then perhaps we don't even need to > > re-register them? > > I'm saying if rtas and the hypervisor accept the new address then > we don't have to worry. If they don't accept an address, then we > must reserve a fixed address in page 3 and only support dump of a > base kernel of some minimum level. Right. > So let us test now if the address is accepted, and if so not worry > about a "low" vector or trampoline for these entry points. Anton said they had to be < 32 MB, so we'll still need a trampoline, although perhaps not at a fixed address. As an aside, if we do reuse the same address for the second kernel, is there any chance we can be broken by fwmni vectors firing before the second kernel is ready for them? cheers -- Michael Ellerman IBM OzLabs email: michael:ellerman.id.au inmsg: mpe:jabber.org wwweb: http://michael.ellerman.id.au phone: +61 2 6212 1183 (tie line 70 21183) We do not inherit the earth from our ancestors, we borrow it from our children. - S.M.A.R.T Person -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: not available Url : http://ozlabs.org/pipermail/linuxppc64-dev/attachments/20050830/58bb064c/attachment.pgp From miltonm at bga.com Tue Aug 30 17:39:15 2005 From: miltonm at bga.com (Milton Miller) Date: Tue, 30 Aug 2005 02:39:15 -0500 Subject: [PATCH 11/12] ppc64: Move fwnmi vectors into trampoline area In-Reply-To: <200508301728.35097.michael@ellerman.id.au> References: <200508300609.j7U693rL034018@sullivan.realtime.net> <200508301728.35097.michael@ellerman.id.au> Message-ID: <1e4ccf8fde47c50a4775bca339ed2d22@bga.com> On Aug 30, 2005, at 2:28 AM, Michael Ellerman wrote: > On Tue, 30 Aug 2005 17:22, Milton Miller wrote: > As an aside, if we do reuse the same address for the second kernel, is > there > any chance we can be broken by fwmni vectors firing before the second > kernel > is ready for them? > Probably, and by not using them there is probably a non-zero chance that during this window the old kernel's routines would be broken. milton From miltonm at bga.com Tue Aug 30 18:00:49 2005 From: miltonm at bga.com (Milton Miller) Date: Tue, 30 Aug 2005 03:00:49 -0500 Subject: [PATCH 10/12] ppc64: Reroute interrupts from zero + offset to KERNELBASE + offset In-Reply-To: <200508300541.j7U5fK9G033936@sullivan.realtime.net> References: <200508300541.j7U5fK9G033936@sullivan.realtime.net> Message-ID: [Again, sorry for broken threading] Michael Ellerman wrote: > On Tue, 30 Aug 2005 15:41, Milton D. Miller II wrote: > > > From michael at ellerman.id.au Fri Aug 26 12:53:31 2005 > > > We also need to reserve the low pages of memory in prom.c, as well > as > > > __pa(KERNELBASE) to __pa(klimit). > > > > > > FIXME, 0x8000 should be a #define. > > > > Actually we should reserve 0 to __pa(KERNELBASE) for testing kdump > > environment... > > Why's that? because kdump won't let us use those pages? (I did say kdump, not just !0 KERNELBASE). And it hides the problem of 0x8000 :) > > > Do we work if the reserve of low memory is not part of the mem= ? > > In kdump, this memory will not be part of the "mem=" line passed to > > the capture kernel. > > Not quite sure what you mean here? I was thinking the second kernel > would > detect it's memory constraints via the device tree (crashk_start etc). > rather > than by using mem=. Although I guess either could work, and perhaps > mem= is > better - less custom KDUMP code. Actually I like this idea, although I'm not quite sure of the best approach to do this. Some of the things to watch for: 1) We probably want to create the linear mapping in the hash table for all physically present memory, so that a read() on /dev/mem works. 2) However, we want the total low memory etc in the node to reflect the memory that the kdump kernel is allowed to manage so we get various dynamically sized structures right (inode hash, tcp hashes, etc). I think this will be key in getting a working dump of a large memory machine. > > > Why is it 0x8000 for the reserve and 0x3000 for the trampoline? > > Do we know what we expect the trampoline will save? > > The trampoline is only for vectors, so up to 0x3000. The reserve > includes the > fwnmi data area and basically everything in head.S Yes, but this needs to be less magic. > > > page 9 is the initial stab (for RS64 and POWER3), or are you using > > the new rearranged low memory patch? > > Yeah I'm using David's patches, so 0x8000 is the top of the important > bits in > head.S I didn't see that listed as a prereq :) > > > > +#ifdef CONFIG_KDUMP_CAPTURE_KERNEL > > > +static void setup_kdump_trampoline(void) > > > +{ > > > + unsigned long i; > > > + unsigned int *addr; > > > + > > > + /* XXX this only works if PHYSICAL_START <= 32 MB */ > > > > how about an #error ? > > Yep, just hadn't got to it yet. I think I saw some "BUILD_BUG" macro > somewhere, or am I mad. I thought so too but couldn't locate it quickly, so wasn't sure if it was still just proposed or actually merged. > > > > + > > > + for (i = 0x100; i < 0x3000; i += 8) { > > > + addr = (unsigned int *)i; > > > + *addr++ = 0x60000000; /* nop */ > > > + *addr = 0x48000000 | ((PHYSICAL_START - 1) & 0x03fffffc); > > > + > > > + asm ("dcbst 0,%0; sync; icbi 0,%0; isync" : : "r" (addr)); > > > > every 8 bytes is a bit overkill, but ok. The -1 should be -4, its > the > > instruction target.. > > Well yeah, it could probably be 0x100, but this way any new vectors > that get > added at weird places will also be caught. It is - 4 because of the > mask, but > I guess actually having "- 4" would be clearer. Yea, well, it used to be 0x100, then 0x80, and altivec has 0x20, and another has one at 0x50 so every 10 vs every 8 ... The other option is zero fill and put in the ones we actually support. That way anything else will go to 0x700. > > > Others have commented on the comments for the patching. The > > trick of doing a nop to extend the range to 32k should be > > explicitly stated. > > Yep it's ugly. I think I'll make a macro for it, we synthesise > branches in a > few places. > > > Another approach is to copy pages 0-3 down to pages 0-3 and execute > the > > copy there. It does mean that we can't use relative branchs from > there > > to the "main" kernel. > > Yeah I thought about that. But we'd have to link head.S differently, > somehow, > and given that most of the code in head.S is happy to be at 32 MB I > decided > the trampoline was an easier option. Since head.S is assembly, we couuld just be careful about what we put in there, making sure it is relocatable code. ... Maybe a comment that this is an option, maybe just this discussion. I was still debating which way to go when you took over. Any reason you are choosing 32M instead of 16M ? Other than it is the limit, of course. I don't know what size others have, my kernel with its drivers is somewhere around 9M. I guess 16 could be tight for some. milton From hollis at penguinppc.org Wed Aug 31 00:38:50 2005 From: hollis at penguinppc.org (Hollis Blanchard) Date: Tue, 30 Aug 2005 09:38:50 -0500 Subject: [PATCH 9/12] ppc64: Misc fixups for non-zero KERNELBASE In-Reply-To: <200508300602.j7U62J4A033998@sullivan.realtime.net> References: <200508300602.j7U62J4A033998@sullivan.realtime.net> Message-ID: <1328367f8594db7bb7555770868641b2@penguinppc.org> On Aug 30, 2005, at 1:02 AM, Milton D. Miller II wrote: > > You took out the scheduling of putting independent ops between the > clear and the ori of the lower half. > > This just cost the main kernel several wasted cycles. (No, I didn't > sim this to count). Is that really true? I did an unofficial test (on 604 because it was handy) with this sequence: lis 3, 0x55 lis 4, 0x55 ori 3, 3, 0xaa55 vs lis 3, 0x55 ori 3, 3, 0xaa55 lis 4, 0x55 ... run 100000000 iterations, a few times to allow for cache warming. I saw no difference in the run times. Was this just a non-representative test case, or would it matter more on other processors? -Hollis From segher at kernel.crashing.org Wed Aug 31 00:53:28 2005 From: segher at kernel.crashing.org (Segher Boessenkool) Date: Tue, 30 Aug 2005 16:53:28 +0200 Subject: [PATCH 11/12] ppc64: Move fwnmi vectors into trampoline area In-Reply-To: <200508300609.j7U693rL034018@sullivan.realtime.net> References: <200508300609.j7U693rL034018@sullivan.realtime.net> Message-ID: <0b2bea3bcaff846f02aa7f3159d5a8d6@kernel.crashing.org> > 1) Addresses below 0x3000 are reserved by the (processor?) architecture > to add interrupt vectors. This patch might collide with them. Just nitpicking: 0x100..0xfff are reserved for interrupt vectors; 0x1000..0x2fff are reserved for (processor) implementation specific purposes (all CPUs I know of that use these addresses, use them for more interrupt vectors, of course ;-) ) Segher From rcjenn at austin.ibm.com Wed Aug 31 02:48:12 2005 From: rcjenn at austin.ibm.com (Robert C. Jennings) Date: Tue, 30 Aug 2005 11:48:12 -0500 (CDT) Subject: [PATCH] Add PTRACE_{GET|SET}VRREGS Message-ID: The ptrace get and set methods for VMX/Altivec registers present in the ppc tree were missing for ppc64. This patch adds the 32-bit and 64-bit methods. Signed-off-by: Robert C Jennings --- ptrace.c | 18 ++++++++++++++++++ ptrace32.c | 18 ++++++++++++++++++ 2 files changed, 36 insertions(+) diff -uprN -X linux-2.6.13/Documentation/dontdiff linux-2.6.13.orig/arch/ppc64/kernel/ptrace32.c linux-2.6.13/arch/ppc64/kernel/ptrace32.c --- linux-2.6.13.orig/arch/ppc64/kernel/ptrace32.c 2005-08-28 18:41:01.000000000 -0500 +++ linux-2.6.13/arch/ppc64/kernel/ptrace32.c 2005-08-30 11:12:18.000000000 -0500 @@ -408,6 +408,24 @@ int sys32_ptrace(long request, long pid, case PTRACE_GETEVENTMSG: ret = put_user(child->ptrace_message, (unsigned int __user *) data); break; + +#ifdef CONFIG_ALTIVEC + case PTRACE_GETVRREGS: + /* Get the child altivec register state. */ + if (copy_to_user((void *)data, &child->thread.vr[0], + offsetof(struct thread_struct, used_vr) - + offsetof(struct thread_struct, vr[0]))) + ret = -EFAULT; + break; + + case PTRACE_SETVRREGS: + /* Set the child altivec register state. */ + if (copy_from_user(&child->thread.vr[0], (void *)data, + offsetof(struct thread_struct, used_vr) - + offsetof(struct thread_struct, vr[0]))) + ret = -EFAULT; + break; +#endif default: ret = ptrace_request(child, request, addr, data); diff -uprN -X linux-2.6.13/Documentation/dontdiff linux-2.6.13.orig/arch/ppc64/kernel/ptrace.c linux-2.6.13/arch/ppc64/kernel/ptrace.c --- linux-2.6.13.orig/arch/ppc64/kernel/ptrace.c 2005-08-28 18:41:01.000000000 -0500 +++ linux-2.6.13/arch/ppc64/kernel/ptrace.c 2005-08-30 11:11:59.000000000 -0500 @@ -274,6 +274,24 @@ int sys_ptrace(long request, long pid, l break; } +#ifdef CONFIG_ALTIVEC + case PTRACE_GETVRREGS: + /* Get the child altivec register state. */ + if (copy_to_user((void *)data, &child->thread.vr[0], + offsetof(struct thread_struct, used_vr) - + offsetof(struct thread_struct, vr[0]))) + ret = -EFAULT; + break; + + case PTRACE_SETVRREGS: + /* Set the child altivec register state. */ + if (copy_from_user(&child->thread.vr[0], (void *)data, + offsetof(struct thread_struct, used_vr) - + offsetof(struct thread_struct, vr[0]))) + ret = -EFAULT; + break; +#endif + default: ret = ptrace_request(child, request, addr, data); break; From torvalds at osdl.org Wed Aug 31 04:11:00 2005 From: torvalds at osdl.org (Linus Torvalds) Date: Tue, 30 Aug 2005 11:11:00 -0700 (PDT) Subject: Non-booting G5 In-Reply-To: <17171.57737.757041.432631@cargo.ozlabs.ibm.com> References: <17170.25803.413408.44080@cargo.ozlabs.ibm.com> <17171.39652.237263.484079@cargo.ozlabs.ibm.com> <17171.57737.757041.432631@cargo.ozlabs.ibm.com> Message-ID: This commit causes my G5 to not boot at all. It just hangs very early on in the boot sequence. The good news is that I used this bug to verify (and fix an off-by-one error) the git bisection thing. The previous commit works fine ("ppc64: Check of_chosen..") I won't have time to test anything else, since my flight to Italy leaves in a couple of hours, but hopefully this is enough for people to start on. I don't have anything strange in my config, but I'm appending that as a gzipped attachment in case people care. Linus --- c594adad5653491813959277fb87a2fef54c4e05 is first bad commit diff-tree c594adad5653491813959277fb87a2fef54c4e05 (from 9a5573e378c5c8976c6000a7643b52e2a0481688) Author: David Gibson Date: Thu Aug 11 16:55:21 2005 +1000 [PATCH] Dynamic hugepage addresses for ppc64 Paulus, I think this is now a reasonable candidate for the post-2.6.13 queue. Relax address restrictions for hugepages on ppc64 Presently, 64-bit applications on ppc64 may only use hugepages in the address region from 1-1.5T. Furthermore, if hugepages are enabled in the kernel config, they may only use hugepages and never normal pages in this area. This patch relaxes this restriction, allowing any address to be used with hugepages, but with a 1TB granularity. That is if you map a hugepage anywhere in the region 1TB-2TB, that entire area will be reserved exclusively for hugepages for the remainder of the process's lifetime. This works analagously to hugepages in 32-bit applications, where hugepages can be mapped anywhere, but with 256MB (mmu segment) granularity. This patch applies on top of the four level pagetable patch (http://patchwork.ozlabs.org/linuxppc64/patch?id=1936). Signed-off-by: David Gibson Signed-off-by: Paul Mackerras -------------- next part -------------- A non-text attachment was scrubbed... Name: g5-config.gz Type: application/x-gzip Size: 7949 bytes Desc: Url : http://ozlabs.org/pipermail/linuxppc64-dev/attachments/20050830/7e0e6b20/attachment.bin From haren at us.ibm.com Wed Aug 31 04:18:08 2005 From: haren at us.ibm.com (Haren Myneni) Date: Tue, 30 Aug 2005 11:18:08 -0700 Subject: [PATCH 10/12] ppc64: Reroute interrupts from zero + offset to KERNELBASE + offset In-Reply-To: <200508301722.05643.michael@ellerman.id.au> References: <200508300541.j7U5fK9G033936@sullivan.realtime.net> <200508301722.05643.michael@ellerman.id.au> Message-ID: <4314A2E0.1060407@us.ibm.com> Michael Ellerman wrote: >On Tue, 30 Aug 2005 15:41, Milton D. Miller II wrote: > > >>>From michael at ellerman.id.au Fri Aug 26 12:53:31 2005 >>>We also need to reserve the low pages of memory in prom.c, as well as >>>__pa(KERNELBASE) to __pa(klimit). >>> >>>FIXME, 0x8000 should be a #define. >>> >>> >>Actually we should reserve 0 to __pa(KERNELBASE) for testing kdump >>environment... >> >> > >Why's that? > > > >>Do we work if the reserve of low memory is not part of the mem= ? >>In kdump, this memory will not be part of the "mem=" line passed to >>the capture kernel. >> >> > >Not quite sure what you mean here? I was thinking the second kernel would >detect it's memory constraints via the device tree (crashk_start etc). rather >than by using mem=. Although I guess either could work, and perhaps mem= is >better - less custom KDUMP code. > > > Milton, At present, the capture kernel base will be fixed at 32MB. Hence, 'mem=' option can be used. However, once we have fully relocatable kernel (PIC) support later, new options 'memmap=X at Y/exactmap' are needed or able to detect memory values from the device tree (crash_kernel_start and crash_kernel_end) as Michael pointed out. Now, kexec-tools passes 'memmap=' option to the second kernel since already supported on i386. I think, it will be better to have same interfaces even though only kdump is using them now. Thanks Haren >>Why is it 0x8000 for the reserve and 0x3000 for the trampoline? >>Do we know what we expect the trampoline will save? >> >> > >The trampoline is only for vectors, so up to 0x3000. The reserve includes the >fwnmi data area and basically everything in head.S > > > >>page 9 is the initial stab (for RS64 and POWER3), or are you using >>the new rearranged low memory patch? >> >> > >Yeah I'm using David's patches, so 0x8000 is the top of the important bits in >head.S > > > >>>+#ifdef CONFIG_KDUMP_CAPTURE_KERNEL >>>+static void setup_kdump_trampoline(void) >>>+{ >>>+ unsigned long i; >>>+ unsigned int *addr; >>>+ >>>+ /* XXX this only works if PHYSICAL_START <= 32 MB */ >>> >>> >>how about an #error ? >> >> > >Yep, just hadn't got to it yet. I think I saw some "BUILD_BUG" macro >somewhere, or am I mad. > > > >>>+ >>>+ for (i = 0x100; i < 0x3000; i += 8) { >>>+ addr = (unsigned int *)i; >>>+ *addr++ = 0x60000000; /* nop */ >>>+ *addr = 0x48000000 | ((PHYSICAL_START - 1) & 0x03fffffc); >>>+ >>>+ asm ("dcbst 0,%0; sync; icbi 0,%0; isync" : : "r" (addr)); >>> >>> >>every 8 bytes is a bit overkill, but ok. The -1 should be -4, its the >>instruction target.. >> >> > >Well yeah, it could probably be 0x100, but this way any new vectors that get >added at weird places will also be caught. It is - 4 because of the mask, but >I guess actually having "- 4" would be clearer. > > > >>Others have commented on the comments for the patching. The >>trick of doing a nop to extend the range to 32k should be >>explicitly stated. >> >> > >Yep it's ugly. I think I'll make a macro for it, we synthesise branches in a >few places. > > > >>Another approach is to copy pages 0-3 down to pages 0-3 and execute the >>copy there. It does mean that we can't use relative branchs from there >>to the "main" kernel. >> >> > >Yeah I thought about that. But we'd have to link head.S differently, somehow, >and given that most of the code in head.S is happy to be at 32 MB I decided >the trampoline was an easier option. > >cheers > > > >------------------------------------------------------------------------ > >_______________________________________________ >Linuxppc64-dev mailing list >Linuxppc64-dev at ozlabs.org >https://ozlabs.org/mailman/listinfo/linuxppc64-dev > > From johnrose at austin.ibm.com Wed Aug 31 08:33:10 2005 From: johnrose at austin.ibm.com (John Rose) Date: Tue, 30 Aug 2005 17:33:10 -0500 Subject: [patch 8/8] PCI Error Recovery: PPC64 core recovery routines In-Reply-To: <17171.58403.920889.62559@cargo.ozlabs.ibm.com> References: <20050823231817.829359000@bilge> <20050823232143.003048000@bilge> <20050823234747.GI18113@austin.ibm.com> <1124898331.24668.33.camel@sinatra.austin.ibm.com> <20050824162959.GC25174@austin.ibm.com> <17165.3205.505386.187453@cargo.ozlabs.ibm.com> <20050825161325.GG25174@austin.ibm.com> <17170.44500.848623.139474@cargo.ozlabs.ibm.com> <20050829160915.GD12618@austin.ibm.com> <17171.58403.920889.62559@cargo.ozlabs.ibm.com> Message-ID: <1125441190.27140.13.camel@sinatra.austin.ibm.com> Hi Paul- > I'm suggesting that the rpaphp code has a struct pci_driver whose > id_table and probe function are such that it will claim the EADS > bridges. (It would probably be best to match on vendor=IBM and > class=PCI-PCI bridge and let the probe function figure out which of > the bridges it gets asked about are actually EADS bridges.) Wouldn't this leave out hotplug-capable adapters who have direct PHB parents, since these parent PHBs don't have pci_devs? Thoughts? Thanks- John From dwg at au1.ibm.com Wed Aug 31 14:34:05 2005 From: dwg at au1.ibm.com (David Gibson) Date: Wed, 31 Aug 2005 14:34:05 +1000 Subject: Non-booting G5 In-Reply-To: References: <17170.25803.413408.44080@cargo.ozlabs.ibm.com> <17171.39652.237263.484079@cargo.ozlabs.ibm.com> <17171.57737.757041.432631@cargo.ozlabs.ibm.com> Message-ID: <20050831043404.GA30843@localhost.localdomain> On Tue, Aug 30, 2005 at 11:11:00AM -0700, Linus Torvalds wrote: > > This commit causes my G5 to not boot at all. It just hangs very early on > in the boot sequence. > > The good news is that I used this bug to verify (and fix an off-by-one > error) the git bisection thing. The previous commit works fine ("ppc64: > Check of_chosen..") > > I won't have time to test anything else, since my flight to Italy leaves > in a couple of hours, but hopefully this is enough for people to start on. > > I don't have anything strange in my config, but I'm appending that as a > gzipped attachment in case people care. Fix bug in ppc64 dynamic hugepage support I'm an idiot. In adjusting the logic for SLB miss for the dynamic hugepage stuff, I messed up the !CONFIG_HUGETLB_PAGE case, failing to set the SLB flags properly. This patch fixes it. It also streamlines the logic for the CONFIG_HUGETLB_PAGE case (removing a couple of branches) while we're at it. Booted, and roughly tested on POWER5 (with and without CONFIG_HUGETLB_PAGE), iSeries/RS64 (no hugepage available), and G5 (with and without CONFIG_HUGETLB_PAGE). Signed-off-by: David Gibson Index: working-2.6/arch/ppc64/mm/slb_low.S =================================================================== --- working-2.6.orig/arch/ppc64/mm/slb_low.S 2005-08-31 13:46:45.000000000 +1000 +++ working-2.6/arch/ppc64/mm/slb_low.S 2005-08-31 13:46:45.000000000 +1000 @@ -97,25 +97,21 @@ lhz r9,PACAHIGHHTLBAREAS(r13) srdi r11,r3,(HTLB_AREA_SHIFT-SID_SHIFT) srd r9,r9,r11 - andi. r9,r9,1 - bne 5f + lhz r11,PACALOWHTLBAREAS(r13) + srd r11,r11,r3 + or r9,r9,r11 +END_FTR_SECTION_IFSET(CPU_FTR_16M_PAGE) +#endif /* CONFIG_HUGETLB_PAGE */ li r11,SLB_VSID_USER - cmpldi r3,16 - bge 6f - - lhz r9,PACALOWHTLBAREAS(r13) - srd r9,r9,r3 - andi. r9,r9,1 - - beq 6f - -5: li r11,SLB_VSID_USER|SLB_VSID_L +#ifdef CONFIG_HUGETLB_PAGE +BEGIN_FTR_SECTION + rldimi r11,r9,8,55 /* shift masked bit into SLB_VSID_L */ END_FTR_SECTION_IFSET(CPU_FTR_16M_PAGE) #endif /* CONFIG_HUGETLB_PAGE */ -6: ld r9,PACACONTEXTID(r13) + ld r9,PACACONTEXTID(r13) rldimi r3,r9,USER_ESID_BITS,0 9: /* r3 = protovsid, r11 = flags, r10 = esid_data, cr7 = <>KERNELBASE */ -- David Gibson | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/people/dgibson