Re: [PATCH 14/27] Add book3s_64 specific opcode emulation
On Tuesday 03 November 2009, Benjamin Herrenschmidt wrote: (Though glibc can be nasty, afaik it might load up optimized variants of some routines with hard wired cache line sizes based on the CPU type) You can also get application with hand-coded cache optimizations that are even harder, if not impossible, to fix. Arnd ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 14/27] Add book3s_64 specific opcode emulation
On Wed, 2009-11-04 at 09:43 +0100, Arnd Bergmann wrote: On Tuesday 03 November 2009, Benjamin Herrenschmidt wrote: (Though glibc can be nasty, afaik it might load up optimized variants of some routines with hard wired cache line sizes based on the CPU type) You can also get application with hand-coded cache optimizations that are even harder, if not impossible, to fix. Right. But those are already broken across CPU variants anyways. Cheers, Ben ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH] spi/mpc52xx: replace printk with dev_err
To easily identify which device has problems. Signed-off-by: Wolfram Sang w.s...@pengutronix.de Cc: Grant Likely grant.lik...@secretlab.ca --- drivers/spi/mpc52xx_psc_spi.c |5 ++--- 1 files changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/spi/mpc52xx_psc_spi.c b/drivers/spi/mpc52xx_psc_spi.c index e268437..6fb6b3b 100644 --- a/drivers/spi/mpc52xx_psc_spi.c +++ b/drivers/spi/mpc52xx_psc_spi.c @@ -471,7 +471,7 @@ static int __init mpc52xx_psc_spi_of_probe(struct of_device *op, regaddr_p = of_get_address(op-node, 0, size64, NULL); if (!regaddr_p) { - printk(KERN_ERR Invalid PSC address\n); + dev_err(op-dev, Invalid PSC address\n); return -EINVAL; } regaddr64 = of_translate_address(op-node, regaddr_p); @@ -482,8 +482,7 @@ static int __init mpc52xx_psc_spi_of_probe(struct of_device *op, psc_nump = of_get_property(op-node, cell-index, NULL); if (!psc_nump || *psc_nump 5) { - printk(KERN_ERR mpc52xx_psc_spi: Device node %s has invalid - cell-index property\n, op-node-full_name); + dev_err(op-dev, Invalid cell-index property\n); return -EINVAL; } id = *psc_nump + 1; -- 1.6.3.3 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 14/27] Add book3s_64 specific opcode emulation
On 04.11.2009, at 09:47, Benjamin Herrenschmidt wrote: On Wed, 2009-11-04 at 09:43 +0100, Arnd Bergmann wrote: On Tuesday 03 November 2009, Benjamin Herrenschmidt wrote: (Though glibc can be nasty, afaik it might load up optimized variants of some routines with hard wired cache line sizes based on the CPU type) You can also get application with hand-coded cache optimizations that are even harder, if not impossible, to fix. Right. But those are already broken across CPU variants anyways. ... which might be the reason you're using KVM in the first place. Alex ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [powerpc] Next tree Nov 2 : kernel BUG at mm/mmap.c:2135!
Sachin Sant wrote: Today's next tree failed to boot on a POWER 6 box with : [ cut here ] kernel BUG at mm/mmap.c:2135! Oops: Exception in kernel mode, sig: 5 [#2] SMP NR_CPUS=1024 NUMA pSeries Problem exists with today's next as well. Likely cause for this problem seems to the following commit. If i revert this patch the machine boots fine. commit a0668cdc154e54bf0c85182e0535eea237d53146 powerpc/mm: Cleanup management of kmem_caches for pagetables Thanks -Sachin Modules linked in: ibmvscsic scsi_transport_srp scsi_tgt scsi_mod NIP: c014e30c LR: c014e2f8 CTR: c014db88 REGS: c000db703620 TRAP: 0700 Tainted: G D (2.6.32-rc5-autotest-next-20091102) MSR: 80029032 EE,ME,CE,IR,DR CR: 24022442 XER: 200c TASK = c000db7f6fe0[76] 'init' THREAD: c000db70 CPU: 1 GPR00: 0001 c000db7038a0 c0b19900 GPR04: c000db406a40 000c c000fe10c370 c0bb2800 GPR08: db40 c000dfdc0e00 000c GPR12: 44022442 c0bb2800 GPR16: 0843 003c c000db703ea0 c000db569108 GPR20: c000db568908 c000db703d60 GPR24: 0001 00040100 c000fe503580 c000db1ac180 GPR28: c0f812d0 c0a84f00 NIP [c014e30c] .exit_mmap+0x190/0x1b8 LR [c014e2f8] .exit_mmap+0x17c/0x1b8 Call Trace: [c000db7038a0] [c014e2f8] .exit_mmap+0x17c/0x1b8 (unreliable) [c000db703950] [c00916cc] .mmput+0x54/0x164 [c000db7039e0] [c00968d8] .exit_mm+0x17c/0x1a0 [c000db703a90] [c0098cb8] .do_exit+0x248/0x784 [c000db703b70] [c00992a8] .do_group_exit+0xb4/0xe8 [c000db703c00] [c00aca2c] .get_signal_to_deliver+0x3ec/0x478 [c000db703cf0] [c00134ac] .do_signal+0x6c/0x31c [c000db703e30] [c0008b7c] do_work+0x24/0x28 Instruction dump: 7c8407b4 387d0018 4800ab11 6000 939d0008 7fe3fb78 4bfffdbd 7c7f1b79 4082fff4 e81b00e8 3120 7c090110 0b00 382100b0 e8010010 eb61ffd8 ---[ end trace ec052ac77a8e7cb4 ]--- Fixing recursive fault but reboot is needed! mm/mmap.c:2135 corresponds to : BUG_ON(mm-nr_ptes (FIRST_USER_ADDRESS+PMD_SIZE-1)PMD_SHIFT); -- - Sachin Sant IBM Linux Technology Center India Systems and Technology Labs Bangalore, India - ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: Regarding FPGA based cascaded PIC
- Original Message - From: Benjamin Herrenschmidt b...@kernel.crashing.org To: Thirumalai thirumala...@datapatterns.co.in Cc: scottw...@freescale.com Sent: Wednesday, November 04, 2009 11:55 AM Subject: Re: Regarding FPGA based cascaded PIC On Wed, 2009-11-04 at 10:48 +0530, Thirumalai wrote: Hi Ben, I am a having MPC8640D based board on which i am in the process of writing cascaded interrupt handler for my FPGA based PIC. I need some clarification on writing customized cascaded interrupt handler. As for as my understanding we need to use irq_alloc_host() function for allocating the irq_host for my FPGA pic and we should use irq_of_parse_and_map() function for parsing and assignment of virtual IRQ from my device tree. In my case my FPGA based PIC is giving interrupts to 3 external interrupt of MPC8640D i.e 1,2,3 . So i have written my fpga-pic node as follows on my device tree. Please post to the mailing list linuxppc-dev@lists.ozlabs.org for such questions. fpga-...@dc00 { compatible = dp,fpga-pic; reg = 0xdc00 0x7fff; interrupt-controller; #interrupt-cells = 3; interrupts = 1 1 2 1 3 1; interrupt-parent = mpic; }; 3 cells per interrupt ? that's a lot :-) What do you put in there ? mpic: p...@4 { clock-frequency = 0; interrupt-controller; #address-cells = 0; #interrupt-cells = 2; reg = 0x4 0x4; compatible = chrp,open-pic; device_type = open-pic; big-endian; }; So far it looks reasonable... The function irq_of_parse_and_map is returning VIRQ as 16,17,18 successfully. i hooked my chained interrupt handler for this VIRQ using set_irq_chained_handler function. On my user defined interrupt handler when i am searching the vector need to be returned i am getting 0 as vector. ie using the function irq_linear_revmap. So here my doubt: Even irq_alloc_host has returned a irq_host for my pic, Why my custom map funtion is not called during irq_of_parse_and_map function. Instead of my map/xlate function it is calling mpic's map/xlate function? That's where I don't follow you... So interrupts 1,2,3 in your example are outputs of the FPGA PIC connected to inputs 1,2,3 of the MPIC. Those get mapped to virq 16.17 and 18. Those are really MPIC interrupts. At some stage some interrupts -below- your FPGA PIC (whatever devices you have on the FPGA) are going to fire. it's -those- interrupts that will use map/xlate from the FPGA host when irq_of_parse_and_map() is called for them you understood correctly. Here the problem lies.Correct me if i am wrong. So you are telling that irq_of_parse_and_map() will invoke the map/xlate of my FPGA pic. Right. But this is what not happening. Instead of calling my map/xlate functions the irq_of_parse_and_map() function is invoking mpic's map/xlate function. Here is the piece of code that we are using. fpga_pic_irq_host = irq_alloc_host(pic, IRQ_HOST_MAP_LINEAR, DPVPX0659_FPGA_NUM_IRQS,fpga_pic_host_ops, NO_IRQ); if (fpga_pic_irq_host == NULL) { printk(FPGA PIC: Unable to allocate host\n); return; } for (i = 0; i 3; i++) { fpga_irqs[i] = irq_of_parse_and_map(pic, i); if (fpga_irqs[i] == NO_IRQ) { printk(FPGA PIC: can't get irq %d.\n, i); continue; } printk(interrupt from device tree : %d \n,fpga_irqs[i]); set_irq_chained_handler(dpvpx0659_fpga_irqs[i],dpvpx0659_fpga_pic_cascade); } IE. When -those- fire, the FPGA emits one of the 3 interrupts, and your cascade handler gets called. It will then fetch off the FPGA PIC what interrupts happened and revmap that. Cheers, Ben. Kindly reply me soon. Regards Thirumalai Thank you Thirumalai CAUTION - Disclaimer *This email may contain confidential and privileged material for the sole use of the intended recipient(s). Any review, use, retention, distribution or disclosure by others is strictly prohibited. If you are not the intended recipient (or authorized to receive for the recipient), please contact the sender by reply email and delete all copies of this message. Also, email is susceptible to data corruption, interception, tampering, unauthorized amendment and viruses. We only send and receive emails on the basis that we are not liable for any such corruption, interception, tampering, amendment or viruses or any consequence thereof. *** End of Disclaimer ***DataPatterns ITS Group**
[PATCH 5/8] 8xx: Add missing Guarded setting in DTLB Error.
only DTLB Miss did set this bit, DTLB Error needs too otherwise the setting is lost when the page becomes dirty. Signed-off-by: Joakim Tjernlund joakim.tjernl...@transmode.se --- arch/powerpc/kernel/head_8xx.S | 13 ++--- 1 files changed, 10 insertions(+), 3 deletions(-) diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S index 1d8e4e3..18e9901 100644 --- a/arch/powerpc/kernel/head_8xx.S +++ b/arch/powerpc/kernel/head_8xx.S @@ -552,9 +552,16 @@ DARFixed:/* Return from dcbx instruction bug workaround, r10 holds value of DAR */ ori r11, r11, 1 /* Set valid bit in physical L2 page */ DO_8xx_CPU6(0x3b80, r3) - mtspr SPRN_MD_TWC, r11/* Load pte table base address */ - mfspr r11, SPRN_MD_TWC/* and get the pte address */ - lwz r10, 0(r11) /* Get the pte */ + mtspr SPRN_MD_TWC, r11/* Load pte table base address */ + mfspr r10, SPRN_MD_TWC/* and get the pte address */ + lwz r10, 0(r10) /* Get the pte */ + /* Insert the Guarded flag into the TWC from the Linux PTE. +* It is bit 27 of both the Linux PTE and the TWC +*/ + rlwimi r11, r10, 0, 27, 27 + DO_8xx_CPU6(0x3b80, r3) + mtspr SPRN_MD_TWC, r11 + mfspr r11, SPRN_MD_TWC/* get the pte address again */ ori r10, r10, _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_HWWRITE stw r10, 0(r11) /* and update pte in table */ -- 1.6.4.4 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 0/8] 8xx: Misc fixes for buggy insn
Here is the latest(last?) round of this series. I hope I got everything right now. Scott and Rex, please test and send ACK/NACK. Jocke Joakim Tjernlund (8): 8xx: invalidate non present TLBs 8xx: Update TLB asm so it behaves as linux mm expects. 8xx: Tag DAR with 0x00f0 to catch buggy instructions. 8xx: Fixup DAR from buggy dcbX instructions. 8xx: Add missing Guarded setting in DTLB Error. 8xx: Restore _PAGE_WRITETHRU 8xx: start using dcbX instructions in various copy routines 8xx: Remove DIRTY pte handling in DTLB Error. arch/powerpc/include/asm/pte-8xx.h | 14 +- arch/powerpc/kernel/head_8xx.S | 308 ++-- arch/powerpc/kernel/misc_32.S | 18 -- arch/powerpc/lib/copy_32.S | 24 --- arch/powerpc/mm/fault.c|8 +- 5 files changed, 205 insertions(+), 167 deletions(-) ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 1/8] 8xx: invalidate non present TLBs
8xx sometimes need to load a invalid/non-present TLBs in it DTLB asm handler. These must be invalidated separaly as linux mm don't. Signed-off-by: Joakim Tjernlund joakim.tjernl...@transmode.se --- arch/powerpc/mm/fault.c |8 +++- 1 files changed, 7 insertions(+), 1 deletions(-) diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c index e7dae82..26fb6b9 100644 --- a/arch/powerpc/mm/fault.c +++ b/arch/powerpc/mm/fault.c @@ -40,7 +40,7 @@ #include asm/uaccess.h #include asm/tlbflush.h #include asm/siginfo.h - +#include mm/mmu_decl.h #ifdef CONFIG_KPROBES static inline int notify_page_fault(struct pt_regs *regs) @@ -246,6 +246,12 @@ good_area: goto bad_area; #endif /* CONFIG_6xx */ #if defined(CONFIG_8xx) + /* 8xx sometimes need to load a invalid/non-present TLBs. +* These must be invalidated separately as linux mm don't. +*/ + if (error_code 0x4000) /* no translation? */ + _tlbil_va(address, 0, 0, 0); + /* The MPC8xx seems to always set 0x8000, which is * undefined. Of those that can be set, this is the only * one which seems bad. -- 1.6.4.4 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 2/8] 8xx: Update TLB asm so it behaves as linux mm expects.
Update the TLB asm to make proper use of _PAGE_DIRY and _PAGE_ACCESSED. Get rid of _PAGE_HWWRITE too. Pros: - I/D TLB Miss never needs to write to the linux pte. - _PAGE_ACCESSED is only set on TLB Error fixing accounting - _PAGE_DIRTY is mapped to 0x100, the changed bit, and is set directly when a page has been made dirty. - Proper RO/RW mapping of user space. - Free up 2 SW TLB bits in the linux pte(add back _PAGE_WRITETHRU ?) - kernel RO/user NA support. Cons: - A few more instructions in the TLB Miss routines. Signed-off-by: Joakim Tjernlund joakim.tjernl...@transmode.se --- arch/powerpc/include/asm/pte-8xx.h | 13 ++--- arch/powerpc/kernel/head_8xx.S | 99 ++- 2 files changed, 57 insertions(+), 55 deletions(-) diff --git a/arch/powerpc/include/asm/pte-8xx.h b/arch/powerpc/include/asm/pte-8xx.h index dd5ea95..68ba861 100644 --- a/arch/powerpc/include/asm/pte-8xx.h +++ b/arch/powerpc/include/asm/pte-8xx.h @@ -33,21 +33,20 @@ #define _PAGE_NO_CACHE 0x0002 /* I: cache inhibit */ #define _PAGE_SHARED 0x0004 /* No ASID (context) compare */ #define _PAGE_SPECIAL 0x0008 /* SW entry, forced to 0 by the TLB miss */ +#define _PAGE_DIRTY0x0100 /* C: page changed */ -/* These five software bits must be masked out when the entry is loaded - * into the TLB. +/* These 3 software bits must be masked out when the entry is loaded + * into the TLB, 2 SW bits left. */ #define _PAGE_GUARDED 0x0010 /* software: guarded access */ -#define _PAGE_DIRTY0x0020 /* software: page changed */ -#define _PAGE_RW 0x0040 /* software: user write access allowed */ -#define _PAGE_ACCESSED 0x0080 /* software: page referenced */ +#define _PAGE_ACCESSED 0x0020 /* software: page referenced */ /* Setting any bits in the nibble with the follow two controls will * require a TLB exception handler change. It is assumed unused bits * are always zero. */ -#define _PAGE_HWWRITE 0x0100 /* h/w write enable: never set in Linux PTE */ -#define _PAGE_USER 0x0800 /* One of the PP bits, the other is USER~RW */ +#define _PAGE_RW 0x0400 /* lsb PP bits, inverted in HW */ +#define _PAGE_USER 0x0800 /* msb PP bits */ #define _PMD_PRESENT 0x0001 #define _PMD_BAD 0x0ff0 diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S index 6ded19d..97bd523 100644 --- a/arch/powerpc/kernel/head_8xx.S +++ b/arch/powerpc/kernel/head_8xx.S @@ -333,26 +333,20 @@ InstructionTLBMiss: mfspr r11, SPRN_MD_TWC/* and get the pte address */ lwz r10, 0(r11) /* Get the pte */ -#ifdef CONFIG_SWAP - /* do not set the _PAGE_ACCESSED bit of a non-present page */ - andi. r11, r10, _PAGE_PRESENT - beq 4f - ori r10, r10, _PAGE_ACCESSED - mfspr r11, SPRN_MD_TWC/* get the pte address again */ - stw r10, 0(r11) -4: -#else - ori r10, r10, _PAGE_ACCESSED - stw r10, 0(r11) -#endif + andi. r11, r10, _PAGE_ACCESSED | _PAGE_PRESENT + cmpwi cr0, r11, _PAGE_ACCESSED | _PAGE_PRESENT + bne-cr0, 2f + + /* Clear PP lsb, 0x400 */ + rlwinm r10, r10, 0, 22, 20 /* The Linux PTE won't go exactly into the MMU TLB. -* Software indicator bits 21, 22 and 28 must be clear. +* Software indicator bits 22 and 28 must be clear. * Software indicator bits 24, 25, 26, and 27 must be * set. All other Linux PTE bits control the behavior * of the MMU. */ -2: li r11, 0x00f0 + li r11, 0x00f0 rlwimi r10, r11, 0, 24, 28 /* Set 24-27, clear 28 */ DO_8xx_CPU6(0x2d80, r3) mtspr SPRN_MI_RPN, r10/* Update TLB entry */ @@ -365,6 +359,22 @@ InstructionTLBMiss: lwz r3, 8(r0) #endif rfi +2: + mfspr r11, SPRN_SRR1 + /* clear all error bits as TLB Miss +* sets a few unconditionally + */ + rlwinm r11, r11, 0, 0x + mtspr SPRN_SRR1, r11 + + mfspr r10, SPRN_M_TW /* Restore registers */ + lwz r11, 0(r0) + mtcrr11 + lwz r11, 4(r0) +#ifdef CONFIG_8xx_CPU6 + lwz r3, 8(r0) +#endif + b InstructionAccess . = 0x1200 DataStoreTLBMiss: @@ -409,21 +419,27 @@ DataStoreTLBMiss: DO_8xx_CPU6(0x3b80, r3) mtspr SPRN_MD_TWC, r11 -#ifdef CONFIG_SWAP - /* do not set the _PAGE_ACCESSED bit of a non-present page */ - andi. r11, r10, _PAGE_PRESENT - beq 4f - ori r10, r10, _PAGE_ACCESSED -4: - /* and update pte in table */ -#else - ori r10, r10, _PAGE_ACCESSED -#endif - mfspr r11, SPRN_MD_TWC/* get the pte address again */ - stw r10, 0(r11) + /* Both _PAGE_ACCESSED and _PAGE_PRESENT has to be set. +* We also need to know if the insn is a load/store, so: +* Clear _PAGE_PRESENT and load that
[PATCH 4/8] 8xx: Fixup DAR from buggy dcbX instructions.
This is an assembler version to fixup DAR not being set by dcbX, icbi instructions. There are two versions, one uses selfmodifing code, the other uses a jump table but is much bigger(default). Signed-off-by: Joakim Tjernlund joakim.tjernl...@transmode.se --- arch/powerpc/kernel/head_8xx.S | 147 ++- 1 files changed, 143 insertions(+), 4 deletions(-) diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S index a9f1ace..1d8e4e3 100644 --- a/arch/powerpc/kernel/head_8xx.S +++ b/arch/powerpc/kernel/head_8xx.S @@ -494,11 +494,16 @@ DataTLBError: mfspr r10, SPRN_DAR cmpwi cr0, r10, 0x00f0 - beq-2f /* must be a buggy dcbX, icbi insn. */ - + beq-FixupDAR/* must be a buggy dcbX, icbi insn. */ +DARFixed:/* Return from dcbx instruction bug workaround, r10 holds value of DAR */ mfspr r11, SPRN_DSISR - andis. r11, r11, 0x4800/* !translation or protection */ - bne 2f /* branch if either is set */ + /* As the DAR fixup may clear store we may have all 3 states zero. +* Make sure only 0x0200(store) falls down into DIRTY handling +*/ + andis. r11, r11, 0x4a00/* !translation, protection or store */ + srwir11, r11, 16 + cmpwi cr0, r11, 0x0200/* just store ? */ + bne 2f /* Only Change bit left now, do it here as it is faster * than trapping to the C fault handler. */ @@ -604,6 +609,140 @@ DataTLBError: . = 0x2000 +/* This is the procedure to calculate the data EA for buggy dcbx,dcbi instructions + * by decoding the registers used by the dcbx instruction and adding them. + * DAR is set to the calculated address and r10 also holds the EA on exit. + */ + /* define if you don't want to use self modifying code */ +#define NO_SELF_MODIFYING_CODE +FixupDAR:/* Entry point for dcbx workaround. */ + /* fetch instruction from memory. */ + mfspr r10, SPRN_SRR0 + DO_8xx_CPU6(0x3780, r3) + mtspr SPRN_MD_EPN, r10 + mfspr r11, SPRN_M_TWB /* Get level 1 table entry address */ + cmplwi cr0, r11, 0x0800 + blt-3f /* Branch if user space */ + lis r11, (swapper_pg_dir-PAGE_OFFSET)@h + ori r11, r11, (swapper_pg_dir-PAGE_OFFSET)@l + rlwimi r11, r10, 22, 0xffc +3: lwz r11, 0(r11) /* Get the level 1 entry */ + DO_8xx_CPU6(0x3b80, r3) + mtspr SPRN_MD_TWC, r11/* Load pte table base address */ + mfspr r11, SPRN_MD_TWC/* and get the pte address */ + lwz r11, 0(r11) /* Get the pte */ + /* concat physical page address(r11) and page offset(r10) */ + rlwimi r11, r10, 0, 20, 31 + lwz r11,0(r11) +/* Check if it really is a dcbx instruction. */ +/* dcbt and dcbtst does not generate DTLB Misses/Errors, + * no need to include them here */ + srwir10, r11, 26/* check if major OP code is 31 */ + cmpwi cr0, r10, 31 + bne-141f + rlwinm r10, r11, 0, 21, 30 + cmpwi cr0, r10, 2028 /* Is dcbz? */ + beq+142f + cmpwi cr0, r10, 940 /* Is dcbi? */ + beq+142f + cmpwi cr0, r10, 108 /* Is dcbst? */ + beq+144f/* Fix up store bit! */ + cmpwi cr0, r10, 172 /* Is dcbf? */ + beq+142f + cmpwi cr0, r10, 1964 /* Is icbi? */ + beq+142f +141: mfspr r10, SPRN_DAR /* r10 must hold DAR at exit */ + b DARFixed/* Nope, go back to normal TLB processing */ + +144: mfspr r10, SPRN_DSISR + rlwinm r10, r10,0,7,5 /* Clear store bit for buggy dcbst insn */ + mtspr SPRN_DSISR, r10 +142: /* continue, it was a dcbx, dcbi instruction. */ +#ifdef CONFIG_8xx_CPU6 + lwz r3, 8(r0) /* restore r3 from memory */ +#endif +#ifndef NO_SELF_MODIFYING_CODE + andis. r10,r11,0x1f/* test if reg RA is r0 */ + li r10,modified_in...@l + dcbtst r0,r10 /* touch for store */ + rlwinm r11,r11,0,0,20 /* Zero lower 10 bits */ + orisr11,r11,640 /* Transform instr. to a add r10,RA,RB */ + ori r11,r11,532 + stw r11,0(r10) /* store add/and instruction */ + dcbf0,r10 /* flush new instr. to memory. */ + icbi0,r10 /* invalidate instr. cache line */ + lwz r11, 4(r0) /* restore r11 from memory */ + mfspr r10, SPRN_M_TW /* restore r10 from M_TW */ + isync /* Wait until new instr is loaded from memory */ +modified_instr: + .space 4 /* this is where the add/and instr. is stored */ + bne+143f + subfr10,r0,r10 /* r10=r10-r0, only if reg RA is r0 */ +143: mtdar r10 /* store faulting EA in DAR */ + b DARFixed/* Go back to normal TLB handling
[PATCH 3/8] 8xx: Tag DAR with 0x00f0 to catch buggy instructions.
dcbz, dcbf, dcbi, dcbst and icbi do not set DAR when they cause a DTLB Error. Dectect this by tagging DAR with 0x00f0 at every exception exit that modifies DAR. Test for DAR=0x00f0 in DataTLBError and bail to handle_page_fault(). Signed-off-by: Joakim Tjernlund joakim.tjernl...@transmode.se --- arch/powerpc/kernel/head_8xx.S | 15 ++- 1 files changed, 14 insertions(+), 1 deletions(-) diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S index 97bd523..a9f1ace 100644 --- a/arch/powerpc/kernel/head_8xx.S +++ b/arch/powerpc/kernel/head_8xx.S @@ -206,6 +206,8 @@ MachineCheck: EXCEPTION_PROLOG mfspr r4,SPRN_DAR stw r4,_DAR(r11) + li r5,0x00f0 + mtspr SPRN_DAR,r5 /* Tag DAR, to be used in DTLB Error */ mfspr r5,SPRN_DSISR stw r5,_DSISR(r11) addi r3,r1,STACK_FRAME_OVERHEAD @@ -222,6 +224,8 @@ DataAccess: stw r10,_DSISR(r11) mr r5,r10 mfspr r4,SPRN_DAR + li r10,0x00f0 + mtspr SPRN_DAR,r10/* Tag DAR, to be used in DTLB Error */ EXC_XFER_EE_LITE(0x300, handle_page_fault) /* Instruction access exception. @@ -244,6 +248,8 @@ Alignment: EXCEPTION_PROLOG mfspr r4,SPRN_DAR stw r4,_DAR(r11) + li r5,0x00f0 + mtspr SPRN_DAR,r5 /* Tag DAR, to be used in DTLB Error */ mfspr r5,SPRN_DSISR stw r5,_DSISR(r11) addir3,r1,STACK_FRAME_OVERHEAD @@ -445,6 +451,7 @@ DataStoreTLBMiss: * of the MMU. */ 2: li r11, 0x00f0 + mtspr SPRN_DAR,r11/* Tag DAR */ rlwimi r10, r11, 0, 24, 28 /* Set 24-27, clear 28 */ DO_8xx_CPU6(0x3d80, r3) mtspr SPRN_MD_RPN, r10/* Update TLB entry */ @@ -485,6 +492,10 @@ DataTLBError: stw r10, 0(r0) stw r11, 4(r0) + mfspr r10, SPRN_DAR + cmpwi cr0, r10, 0x00f0 + beq-2f /* must be a buggy dcbX, icbi insn. */ + mfspr r11, SPRN_DSISR andis. r11, r11, 0x4800/* !translation or protection */ bne 2f /* branch if either is set */ @@ -508,7 +519,8 @@ DataTLBError: * are initialized in mapin_ram(). This will avoid the problem, * assuming we only use the dcbi instruction on kernel addresses. */ - mfspr r10, SPRN_DAR + + /* DAR is in r10 already */ rlwinm r11, r10, 0, 0, 19 ori r11, r11, MD_EVALID mfspr r10, SPRN_M_CASID @@ -550,6 +562,7 @@ DataTLBError: * of the MMU. */ li r11, 0x00f0 + mtspr SPRN_DAR,r11/* Tag DAR */ rlwimi r10, r11, 0, 24, 28 /* Set 24-27, clear 28 */ DO_8xx_CPU6(0x3d80, r3) mtspr SPRN_MD_RPN, r10/* Update TLB entry */ -- 1.6.4.4 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 7/8] 8xx: start using dcbX instructions in various copy routines
Now that 8xx can fixup dcbX instructions, start using them where possible like every other PowerPc arch do. Signed-off-by: Joakim Tjernlund joakim.tjernl...@transmode.se --- arch/powerpc/kernel/misc_32.S | 18 -- arch/powerpc/lib/copy_32.S| 24 2 files changed, 0 insertions(+), 42 deletions(-) diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S index da9c0c4..8649f53 100644 --- a/arch/powerpc/kernel/misc_32.S +++ b/arch/powerpc/kernel/misc_32.S @@ -502,15 +502,7 @@ _GLOBAL(clear_pages) li r0,PAGE_SIZE/L1_CACHE_BYTES slw r0,r0,r4 mtctr r0 -#ifdef CONFIG_8xx - li r4, 0 -1: stw r4, 0(r3) - stw r4, 4(r3) - stw r4, 8(r3) - stw r4, 12(r3) -#else 1: dcbz0,r3 -#endif addir3,r3,L1_CACHE_BYTES bdnz1b blr @@ -535,15 +527,6 @@ _GLOBAL(copy_page) addir3,r3,-4 addir4,r4,-4 -#ifdef CONFIG_8xx - /* don't use prefetch on 8xx */ - li r0,4096/L1_CACHE_BYTES - mtctr r0 -1: COPY_16_BYTES - bdnz1b - blr - -#else /* not 8xx, we can prefetch */ li r5,4 #if MAX_COPY_PREFETCH 1 @@ -584,7 +567,6 @@ _GLOBAL(copy_page) li r0,MAX_COPY_PREFETCH li r11,4 b 2b -#endif /* CONFIG_8xx */ /* * void atomic_clear_mask(atomic_t mask, atomic_t *addr) diff --git a/arch/powerpc/lib/copy_32.S b/arch/powerpc/lib/copy_32.S index c657de5..74a7f41 100644 --- a/arch/powerpc/lib/copy_32.S +++ b/arch/powerpc/lib/copy_32.S @@ -98,20 +98,7 @@ _GLOBAL(cacheable_memzero) bdnz4b 3: mtctr r9 li r7,4 -#if !defined(CONFIG_8xx) 10:dcbzr7,r6 -#else -10:stw r4, 4(r6) - stw r4, 8(r6) - stw r4, 12(r6) - stw r4, 16(r6) -#if CACHE_LINE_SIZE = 32 - stw r4, 20(r6) - stw r4, 24(r6) - stw r4, 28(r6) - stw r4, 32(r6) -#endif /* CACHE_LINE_SIZE */ -#endif addir6,r6,CACHELINE_BYTES bdnz10b clrlwi r5,r8,32-LG_CACHELINE_BYTES @@ -200,9 +187,7 @@ _GLOBAL(cacheable_memcpy) mtctr r0 beq 63f 53: -#if !defined(CONFIG_8xx) dcbzr11,r6 -#endif COPY_16_BYTES #if L1_CACHE_BYTES = 32 COPY_16_BYTES @@ -356,14 +341,6 @@ _GLOBAL(__copy_tofrom_user) li r11,4 beq 63f -#ifdef CONFIG_8xx - /* Don't use prefetch on 8xx */ - mtctr r0 - li r0,0 -53:COPY_16_BYTES_WITHEX(0) - bdnz53b - -#else /* not CONFIG_8xx */ /* Here we decide how far ahead to prefetch the source */ li r3,4 cmpwi r0,1 @@ -416,7 +393,6 @@ _GLOBAL(__copy_tofrom_user) li r3,4 li r7,0 bne 114b -#endif /* CONFIG_8xx */ 63:srwi. r0,r5,2 mtctr r0 -- 1.6.4.4 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 8/8] 8xx: Remove DIRTY pte handling in DTLB Error.
There is no need to do set the DIRTY bit directly in DTLB Error. Trap to do_page_fault() and let the generic MM code do the work. Signed-off-by: Joakim Tjernlund joakim.tjernl...@transmode.se --- arch/powerpc/kernel/head_8xx.S | 96 1 files changed, 0 insertions(+), 96 deletions(-) diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S index 65e0526..d6d70f2 100644 --- a/arch/powerpc/kernel/head_8xx.S +++ b/arch/powerpc/kernel/head_8xx.S @@ -500,102 +500,6 @@ DataTLBError: cmpwi cr0, r10, 0x00f0 beq-FixupDAR/* must be a buggy dcbX, icbi insn. */ DARFixed:/* Return from dcbx instruction bug workaround, r10 holds value of DAR */ - mfspr r11, SPRN_DSISR - /* As the DAR fixup may clear store we may have all 3 states zero. -* Make sure only 0x0200(store) falls down into DIRTY handling -*/ - andis. r11, r11, 0x4a00/* !translation, protection or store */ - srwir11, r11, 16 - cmpwi cr0, r11, 0x0200/* just store ? */ - bne 2f - /* Only Change bit left now, do it here as it is faster -* than trapping to the C fault handler. - */ - - /* The EA of a data TLB miss is automatically stored in the MD_EPN -* register. The EA of a data TLB error is automatically stored in -* the DAR, but not the MD_EPN register. We must copy the 20 most -* significant bits of the EA from the DAR to MD_EPN before we -* start walking the page tables. We also need to copy the CASID -* value from the M_CASID register. -* Addendum: The EA of a data TLB error is _supposed_ to be stored -* in DAR, but it seems that this doesn't happen in some cases, such -* as when the error is due to a dcbi instruction to a page with a -* TLB that doesn't have the changed bit set. In such cases, there -* does not appear to be any way to recover the EA of the error -* since it is neither in DAR nor MD_EPN. As a workaround, the -* _PAGE_HWWRITE bit is set for all kernel data pages when the PTEs -* are initialized in mapin_ram(). This will avoid the problem, -* assuming we only use the dcbi instruction on kernel addresses. -*/ - - /* DAR is in r10 already */ - rlwinm r11, r10, 0, 0, 19 - ori r11, r11, MD_EVALID - mfspr r10, SPRN_M_CASID - rlwimi r11, r10, 0, 28, 31 - DO_8xx_CPU6(0x3780, r3) - mtspr SPRN_MD_EPN, r11 - - mfspr r10, SPRN_M_TWB /* Get level 1 table entry address */ - - /* If we are faulting a kernel address, we have to use the -* kernel page tables. -*/ - andi. r11, r10, 0x0800 - beq 3f - lis r11, swapper_pg_...@h - ori r11, r11, swapper_pg_...@l - rlwimi r10, r11, 0, 2, 19 -3: - lwz r11, 0(r10) /* Get the level 1 entry */ - rlwinm. r10, r11,0,0,19 /* Extract page descriptor page address */ - beq 2f /* If zero, bail */ - - /* We have a pte table, so fetch the pte from the table. -*/ - ori r11, r11, 1 /* Set valid bit in physical L2 page */ - DO_8xx_CPU6(0x3b80, r3) - mtspr SPRN_MD_TWC, r11/* Load pte table base address */ - mfspr r10, SPRN_MD_TWC/* and get the pte address */ - lwz r10, 0(r10) /* Get the pte */ - /* Insert the Guarded flag into the TWC from the Linux PTE. -* It is bit 27 of both the Linux PTE and the TWC -*/ - rlwimi r11, r10, 0, 27, 27 - /* Insert the WriteThru flag into the TWC from the Linux PTE. -* It is bit 25 in the Linux PTE and bit 30 in the TWC -*/ - rlwimi r11, r10, 32-5, 30, 30 - DO_8xx_CPU6(0x3b80, r3) - mtspr SPRN_MD_TWC, r11 - mfspr r11, SPRN_MD_TWC/* get the pte address again */ - - ori r10, r10, _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_HWWRITE - stw r10, 0(r11) /* and update pte in table */ - xorir10, r10, _PAGE_RW /* RW bit is inverted */ - - /* The Linux PTE won't go exactly into the MMU TLB. -* Software indicator bits 22 and 28 must be clear. -* Software indicator bits 24, 25, 26, and 27 must be -* set. All other Linux PTE bits control the behavior -* of the MMU. -*/ - li r11, 0x00f0 - mtspr SPRN_DAR,r11/* Tag DAR */ - rlwimi r10, r11, 0, 24, 28 /* Set 24-27, clear 28 */ - DO_8xx_CPU6(0x3d80, r3) - mtspr SPRN_MD_RPN, r10/* Update TLB entry */ - - mfspr r10, SPRN_M_TW /* Restore registers */ - lwz r11, 0(r0) - mtcrr11 - lwz r11, 4(r0) -#ifdef CONFIG_8xx_CPU6 - lwz r3, 8(r0) -#endif - rfi -2: mfspr r10, SPRN_M_TW /* Restore
[PATCH] PCI: Fix regression in powerpc MSI-X
Patch f598282f5145036312d90875d0ed5c14b49fd8a7 exposed a problem in powerpc MSI-X functionality, making network interfaces such as ixgbe and cxgb3 stop to work when MSI-X is enabled. RX interrupts were not being generated. The problem was caused because MSI irq was not being effectively unmasked after device initialization. Signed-off-by: Andre Detsch adet...@br.ibm.com Signed-off-by: Michael Ellerman mich...@ellerman.id.au Index: linux-2.6/arch/powerpc/platforms/pseries/msi.c === --- linux-2.6.orig/arch/powerpc/platforms/pseries/msi.c 2009-11-04 06:35:39.0 -0700 +++ linux-2.6/arch/powerpc/platforms/pseries/msi.c 2009-11-04 07:23:27.0 -0700 @@ -432,8 +432,6 @@ static int rtas_setup_msi_irqs(struct pc /* Read config space back so we can restore after reset */ read_msi_msg(virq, msg); entry-msg = msg; - - unmask_msi_irq(virq); } return 0; Index: linux-2.6/arch/powerpc/platforms/pseries/xics.c === --- linux-2.6.orig/arch/powerpc/platforms/pseries/xics.c2009-11-04 06:35:39.0 -0700 +++ linux-2.6/arch/powerpc/platforms/pseries/xics.c 2009-11-04 07:23:27.0 -0700 @@ -18,6 +18,7 @@ #include linux/init.h #include linux/radix-tree.h #include linux/cpu.h +#include linux/msi.h #include linux/of.h #include asm/firmware.h @@ -219,6 +220,14 @@ static void xics_unmask_irq(unsigned int static unsigned int xics_startup(unsigned int virq) { + /* +* The generic MSI code returns with the interrupt disabled on the +* card, using the MSI mask bits. Firmware doesn't appear to unmask +* at that level, so we do it here by hand. +*/ + if (irq_to_desc(virq)-msi_desc) + unmask_msi_irq(virq); + /* unmask it */ xics_unmask_irq(virq); return 0; ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
RE: DMA to User-Space
Jonathan Haws wrote: All, I have what may be an unconventional question: Our application consists of data being captured by an FPGA, processed, and transferred to SDRAM. I simply give the FPGA an address of where I want it stored in SDRAM and it simply DMAs the data over and interrupts me when finished. I then take that data and store it to disk. I have code in user space that handles all of the writing to disk nicely and fast enough for my application (I am capturing data at about 35-40 Mbytes/sec). My question is this: is it possible to give a user-space pointer to the FPGA to DMA to? It seems like I would have problems with alignment, address manipulation, and a whole slew of other issues. What would be the best way to accomplish something like that? I want to handle all the disk access in user-space, but I do not want to have to copy 40 MB/s from kernel space to user-space either. You can maintain a DMA buffer in kernel, then mmap to user space. And maybe you need some handshake between FPGA and the apps to balance input datas with datas to disk. I can maintain an allocated, DMA-safe buffer in kernel space if needed. Can I simply get a user-space pointer to that buffer? What calls are needed to translate addresses? Use remap_pfn_range() in your kernel DMA buffer manipulation driver .mmap() handler to export DMA buffer address to user space. Can you provide an example for how to do that? I have an mmap routine to map BARs that the FPGA maintains and I can access those, however when I try to map the DMA buffer and access what is in it, the system crashes. Here is the mmap function I have right now: /* fpga_mmap() * * Description: * The purpose of this function is to serve as a 'file_operation' * which maps different PCI resources into the calling processes * memory space. * * NOTE: The file offset are in page size; i.e.: * offset 0 in process's mmap syscall - BAR0 * offset 4096 in process's mmap syscall - BAR1 * offset 8192 in process's mmap syscall - BAR2 * offset 12288 - Streaming DMA buffer * * Arguments: * struct file *filp -- struct representing an open file * struct vm_area_struct *vma -- struct representing memory 'segment' * * Returns: * int -- indication of success or failure * */ int fpga_mmap(struct file *filp, struct vm_area_struct *vma) { struct pci_dev *dev; unsigned long addressToMap; uint8_t mapType = 0; /* 0 = IO, 1 = memory */ /* Get the PCI device */ dev = (struct pci_dev*)(filp-private_data); /* Map in the appropriate BAR based on page offset */ if (vma-vm_pgoff == FPGA_CONFIG_SPACE) { /* Map BAR1 (the CONFIG area) */ printk(KERN_ALERT FPGA: Mapping BAR1 (CONFIG BAR).\n); addressToMap = pci_resource_start(dev, FPGA_CONFIG_SPACE); printk(KERN_ALERT FPGA: PCI BAR1 (CONFIG BAR) Size - %#08x.\n, pci_resource_len(dev, FPGA_CONFIG_SPACE)); mapType = 0; } else if(vma-vm_pgoff == FPGA_TEST_SPACE) { /* Map BAR2 (the TEST area) */ printk(KERN_ALERT FPGA: Mapping BAR2 (TEST BAR).\n); addressToMap = (pci_resource_start(dev, FPGA_TEST_SPACE) + pci_resource_len(dev, FPGA_TEST_SPACE)) - FPGA_TEST_LENGTH; printk(KERN_ALERT FPGA: PCI BAR2 (TEST BAR) Size - %#08x.\n, pci_resource_len(dev, FPGA_TEST_SPACE)); mapType = 0; } else if(vma-vm_pgoff == 3) { addressToMap = (unsigned long)fpga_drv.strmData[0]; mapType = 1; } else { printk(KERN_ALERT FPGA: Invalid BAR mapping specified.\n); return ERROR; } /* Execute the mapping */ vma-vm_flags |= VM_IO; vma-vm_flags |= VM_RESERVED; vma-vm_page_prot = pgprot_noncached(vma-vm_page_prot); printk(KERN_ALERT FPGA: vmSize - 0x%x.\n, (unsigned int)(vma-vm_end - vma-vm_start)); if( mapType == 0 ) { if(io_remap_pfn_range(vma, vma-vm_start, addressToMap PAGE_SHIFT, vma-vm_end - vma-vm_start, vma-vm_page_prot) != 0) { printk(KERN_ALERT FPGA: Failed to map BAR PCI space to user space.\n); return ERROR; } } else { printk(KERN_NOTICE FPGA: Mapping stream ptr (%#08x) to user space\n,(uint32_t)fpga_drv.strmData[0]); printk(KERN_NOTICE FPGA: Setting strmData[0][0] to 0x37\n); fpga_drv.strmData[0][0] = 0x37; if(remap_pfn_range(vma, vma-vm_start, addressToMap PAGE_SHIFT,
RE: DMA to User-Space
1. I open /dev/mem and get a file descriptor 2. I use mmap to reserve some physical addresses for my buffers in user space. 3. I give that address to the FPGA for DMA use. 4. When I get the FPGA interrupt, I invalidate the data cache and write the data to disk Does that sound like it would work? Would the address I receive from mmap() and pass to the FPGA be the actual physical address, or would I need to send the physical address to the FPGA and use the mmap() address to access and write to disk? One more question about this approach: does the mmap() call prevent the kernel from using this memory for other purposes? Will the kernel be able to move this memory elsewhere? I guess what I am asking is if this memory is locked for all other purposes? ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: Fwd: [PATCH] arch/powerpc: Improve _memcpy
See http://lists.ozlabs.org/pipermail/linuxppc-dev/2009-May/072582.html. Any chance to get this one into the tree? Grant? Cheers, Albrecht. Am 03.11.09 20:30 schrieb(en) Chris Friesen: Forwarding to the ppc mailing list. Chris Original Message Subject: [PATCH] arch/powerpc: Improve _memcpy Date: Tue, 3 Nov 2009 15:20:56 +0100 From: Dirk Eibach eib...@gdsys.de To: linux-ker...@vger.kernel.org CC: Dirk Eibach eib...@gdsys.de The implementation of _memcpy_fromio and _memcpy_toio seems to be suboptimal for size 4. Signed-off-by: Dirk Eibach eib...@gdsys.de --- arch/powerpc/kernel/io.c |4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/kernel/io.c b/arch/powerpc/kernel/io.c index 1882bf4..8dc7547 100644 --- a/arch/powerpc/kernel/io.c +++ b/arch/powerpc/kernel/io.c @@ -161,7 +161,7 @@ void _memcpy_fromio(void *dest, const volatile void __iomem *src, dest++; n--; } - while(n 4) { + while(n = 4) { *((u32 *)dest) = *((volatile u32 *)vsrc); eieio(); vsrc += 4; @@ -190,7 +190,7 @@ void _memcpy_toio(volatile void __iomem *dest, const void *src, unsigned long n) vdest++; n--; } - while(n 4) { + while(n = 4) { *((volatile u32 *)vdest) = *((volatile u32 *)src); src += 4; vdest += 4; -- 1.5.6.5 -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/ ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev pgp1gpEWeEASu.pgp Description: PGP signature ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Please pull 'next' branch of 4xx tree
Hi Ben, Please pull the next branch of the 4xx tree to get the following commits. I have some other things in the middle of being worked that may or may not make it in time for the next release, so I wanted to get these commits into your tree now rather than wait. josh The following changes since commit 588e050887c5f00a39b056848ea58c8b496beab0: Benjamin Herrenschmidt (1): powerpc/8xx: Fix build breakage with sparse irq changes are available in the git repository at: ssh://master.kernel.org/pub/scm/linux/kernel/git/jwboyer/powerpc-4xx.git next Dave Mitchell (1): powerpc/4xx: Add 16K FIFO size DTS entries on supported platforms Stefan Roese (1): powerpc/44x: Enable 64bit (= 4GB) memory size in Katmai dts arch/powerpc/boot/dts/canyonlands.dts |2 ++ arch/powerpc/boot/dts/eiger.dts |6 ++ arch/powerpc/boot/dts/glacier.dts |6 ++ arch/powerpc/boot/dts/haleakala.dts |2 ++ arch/powerpc/boot/dts/katmai.dts | 14 +++--- arch/powerpc/boot/dts/kilauea.dts |4 arch/powerpc/boot/dts/makalu.dts |4 arch/powerpc/boot/dts/redwood.dts |1 + 8 files changed, 36 insertions(+), 3 deletions(-) ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
RE: DMA to User-Space
Jonathan, what kind of memory is fpga_drv.strmdata? memory from the kernel stack, something you allocated? You'll notice you were trying to access location 0. To use dma streaming memory you must call dma_map_single() to get the physical address of fpga_drv.strmdata. That memory must be contiguous. Then you may call remap_pfn_range with the page offset of the physical address returned from the dma_map_single() call. Then when the cpu accesses that region you must sync the region for with dma direction for cpu or when the device needs to access it, for the device. LDD3 seems a bit dated on this topic it says to use nopage instead of remap_pfn_range(), in my experiments remap_pfn_range seemed ok. I would ask others on the list for their experience on the topic. Ultimately I went with mapping user space provided address and implementing dma with scatter-gather. -Original Message- From: linuxppc-dev-bounces+john.p.price=l-3com@lists.ozlabs.org [mailto:linuxppc-dev-bounces+john.p.price=l-3com@lists.ozlabs.org] On Behalf Of Jonathan Haws Sent: Wednesday, November 04, 2009 12:40 PM To: bo@windriver.com Cc: linuxppc-dev@lists.ozlabs.org Subject: RE: DMA to User-Space Jonathan Haws wrote: All, I have what may be an unconventional question: Our application consists of data being captured by an FPGA, processed, and transferred to SDRAM. I simply give the FPGA an address of where I want it stored in SDRAM and it simply DMAs the data over and interrupts me when finished. I then take that data and store it to disk. I have code in user space that handles all of the writing to disk nicely and fast enough for my application (I am capturing data at about 35-40 Mbytes/sec). My question is this: is it possible to give a user-space pointer to the FPGA to DMA to? It seems like I would have problems with alignment, address manipulation, and a whole slew of other issues. What would be the best way to accomplish something like that? I want to handle all the disk access in user-space, but I do not want to have to copy 40 MB/s from kernel space to user-space either. You can maintain a DMA buffer in kernel, then mmap to user space. And maybe you need some handshake between FPGA and the apps to balance input datas with datas to disk. I can maintain an allocated, DMA-safe buffer in kernel space if needed. Can I simply get a user-space pointer to that buffer? What calls are needed to translate addresses? Use remap_pfn_range() in your kernel DMA buffer manipulation driver .mmap() handler to export DMA buffer address to user space. Can you provide an example for how to do that? I have an mmap routine to map BARs that the FPGA maintains and I can access those, however when I try to map the DMA buffer and access what is in it, the system crashes. Here is the mmap function I have right now: /* fpga_mmap() * * Description: * The purpose of this function is to serve as a 'file_operation' * which maps different PCI resources into the calling processes * memory space. * * NOTE: The file offset are in page size; i.e.: * offset 0 in process's mmap syscall - BAR0 * offset 4096 in process's mmap syscall - BAR1 * offset 8192 in process's mmap syscall - BAR2 * offset 12288 - Streaming DMA buffer * * Arguments: * struct file *filp -- struct representing an open file * struct vm_area_struct *vma -- struct representing memory 'segment' * * Returns: * int -- indication of success or failure * */ int fpga_mmap(struct file *filp, struct vm_area_struct *vma) { struct pci_dev *dev; unsigned long addressToMap; uint8_t mapType = 0; /* 0 = IO, 1 = memory */ /* Get the PCI device */ dev = (struct pci_dev*)(filp-private_data); /* Map in the appropriate BAR based on page offset */ if (vma-vm_pgoff == FPGA_CONFIG_SPACE) { /* Map BAR1 (the CONFIG area) */ printk(KERN_ALERT FPGA: Mapping BAR1 (CONFIG BAR).\n); addressToMap = pci_resource_start(dev, FPGA_CONFIG_SPACE); printk(KERN_ALERT FPGA: PCI BAR1 (CONFIG BAR) Size - %#08x.\n, pci_resource_len(dev, FPGA_CONFIG_SPACE)); mapType = 0; } else if(vma-vm_pgoff == FPGA_TEST_SPACE) { /* Map BAR2 (the TEST area) */ printk(KERN_ALERT FPGA: Mapping BAR2 (TEST BAR).\n); addressToMap = (pci_resource_start(dev, FPGA_TEST_SPACE) + pci_resource_len(dev, FPGA_TEST_SPACE)) - FPGA_TEST_LENGTH; printk(KERN_ALERT FPGA: PCI BAR2 (TEST BAR) Size - %#08x.\n, pci_resource_len(dev, FPGA_TEST_SPACE)); mapType = 0; } else if(vma-vm_pgoff == 3) { addressToMap = (unsigned
Re: Regarding FPGA based cascaded PIC
On Wed, 2009-11-04 at 18:09 +0530, Thirumalai wrote: you understood correctly. Here the problem lies.Correct me if i am wrong. So you are telling that irq_of_parse_and_map() will invoke the map/xlate of my FPGA pic. Right. But this is what not happening. Instead of calling my map/xlate functions the irq_of_parse_and_map() function is invoking mpic's map/xlate function. irq_of_parse_and_map() will call the map/xlate function of the parent PIC for the given interrupt. In your case, the interrupts you are calling it for are defined as being interrupts wiring the FPGA to the MPIC, hence are MPIC inputs, and thus will be parsed/mapped by the MPIC. From the MPIC standpoint, the FPGA is just a device. So the code is doing what you tell it to do :-) I don't understand what you are actually trying to acheive. If those 3 interrupts aren't outputs from the FPGA to the MPIC but input to the FPGA then they shouldn't be there, they should be device interrupts connected to the FPGA. Those will end up with map/xlate called in the FPGA host. Ben. Here is the piece of code that we are using. fpga_pic_irq_host = irq_alloc_host(pic, IRQ_HOST_MAP_LINEAR, DPVPX0659_FPGA_NUM_IRQS,fpga_pic_host_ops, NO_IRQ); if (fpga_pic_irq_host == NULL) { printk(FPGA PIC: Unable to allocate host\n); return; } for (i = 0; i 3; i++) { fpga_irqs[i] = irq_of_parse_and_map(pic, i); if (fpga_irqs[i] == NO_IRQ) { printk(FPGA PIC: can't get irq %d.\n, i); continue; } printk(interrupt from device tree : %d \n,fpga_irqs[i]); set_irq_chained_handler(dpvpx0659_fpga_irqs[i],dpvpx0659_fpga_pic_cascade); } ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[RFC PATCH 0/5] Merge common dynamic OF device tree code
This is a follow on to Grant Likely's patches, attempting to merge the common pieces of dynamic OF device tree updating. These patches move the common code for adding and removing nodes and properties from the device tree to drivers/of/of_dynamic.c and wraps them under the new OF_DYNAMIC config option. Additionally this makes the necessary updates to powerpc and microblaze arch's for this move. Nathan Fontenot (5) - Move the declaration of devtree_lock and allnodes to linux/of.h - Create drivers/of/of_dynamic.c from common code. - powerpc and pseries updates - microblaze updates - powerpc/iseries updates ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[RFC PATCH 1/5] Move devtree_lock and allnodes declaration to of.h
Move the declaration of devtree_lock and allnodes from powerpc/microblaze asm/prom.h to linux/of.h Signed-off-by: Nathan Fontenot nf...@austin.ibm.com --- Index: linux-next/include/linux/of.h === --- linux-next.orig/include/linux/of.h 2009-11-02 13:39:46.0 -0600 +++ linux-next/include/linux/of.h 2009-11-02 14:17:29.0 -0600 @@ -19,6 +19,7 @@ #include linux/bitops.h #include linux/kref.h #include linux/mod_devicetable.h +#include linux/spinlock.h typedef u32 phandle; typedef u32 ihandle; @@ -63,6 +64,9 @@ #endif }; +extern rwlock_t devtree_lock; +extern struct device_node *allnodes; + static inline int of_node_check_flag(struct device_node *n, unsigned long flag) { return test_bit(flag, n-_flags); Index: linux-next/arch/powerpc/kernel/prom.c === --- linux-next.orig/arch/powerpc/kernel/prom.c 2009-11-02 13:39:40.0 -0600 +++ linux-next/arch/powerpc/kernel/prom.c 2009-11-02 14:07:43.0 -0600 @@ -32,6 +32,7 @@ #include linux/debugfs.h #include linux/irq.h #include linux/lmb.h +#include linux/of.h #include asm/prom.h #include asm/rtas.h @@ -79,10 +80,6 @@ struct boot_param_header *initial_boot_params; #endif -extern struct device_node *allnodes; /* temporary while merging */ - -extern rwlock_t devtree_lock; /* temporary while merging */ - /* export that to outside world */ struct device_node *of_chosen; Index: linux-next/arch/microblaze/include/asm/prom.h === --- linux-next.orig/arch/microblaze/include/asm/prom.h 2009-11-02 13:39:39.0 -0600 +++ linux-next/arch/microblaze/include/asm/prom.h 2009-11-02 14:10:13.0 -0600 @@ -23,6 +23,7 @@ #include linux/of_fdt.h #include linux/proc_fs.h #include linux/platform_device.h +#include linux/of.h #include asm/irq.h #include asm/atomic.h @@ -37,9 +38,6 @@ #define HAVE_ARCH_DEVTREE_FIXUPS -extern struct device_node *allnodes; /* temporary while merging */ -extern rwlock_t devtree_lock; /* temporary while merging */ - /* For updating the device tree at runtime */ extern void of_attach_node(struct device_node *); extern void of_detach_node(struct device_node *); Index: linux-next/arch/sparc/kernel/prom.h === --- linux-next.orig/arch/sparc/kernel/prom.h2009-11-02 13:39:40.0 -0600 +++ linux-next/arch/sparc/kernel/prom.h 2009-11-02 14:12:46.0 -0600 @@ -2,11 +2,9 @@ #define __PROM_H #include linux/spinlock.h +#include linux/of.h #include asm/prom.h -extern struct device_node *allnodes; /* temporary while merging */ -extern rwlock_t devtree_lock; /* temporary while merging */ - extern void * prom_early_alloc(unsigned long size); extern void irq_trans_init(struct device_node *dp); ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[RFC PATCH 2/5] Merge dynamic OF code to of_dynamic.c
Creation of the OF dynamic device tree update code in drivers/of. This merges the common device tree updating routines to add/remove nodes and properties from powerpc and microblaze. All of the new code is conditional based on a new OF_DYNAMIC config option. There are two updates to the code. First, the routines to update properties are re-named from prom_* to of_*. This seems correct as the routines no longer reside in prom.c files. Second, the addition of a notifier chain for when nodes are added removed from the device tree. This is a feature that currently exists in powerpc. Signed-off-by: Nathan Fontenot nf...@austin.ibm.com --- Index: linux-next/drivers/of/of_dynamic.c === --- /dev/null 1970-01-01 00:00:00.0 + +++ linux-next/drivers/of/of_dynamic.c 2009-11-04 14:45:11.0 -0600 @@ -0,0 +1,387 @@ +/* + * Definitions for talking to the Open Firmware PROM on + * Power Macintosh and other computers. + * + * Copyright (C) 1996-2005 Paul Mackerras. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include linux/of.h + +BLOCKING_NOTIFIER_HEAD(of_update_chain); + +/** + * of_node_get - Increment refcount of a node + * @node: Node to inc refcount, NULL is supported to + * simplify writing of callers + * + * Returns node. + */ +struct device_node *of_node_get(struct device_node *node) +{ + if (node) + kref_get(node-kref); + return node; +} +EXPORT_SYMBOL(of_node_get); + +static inline struct device_node *kref_to_device_node(struct kref *kref) +{ + return container_of(kref, struct device_node, kref); +} + +/** + * of_node_release - release a dynamically allocated node + * @kref: kref element of the node to be released + * + * In of_node_put() this function is passed to kref_put() + * as the destructor. + */ +static void of_node_release(struct kref *kref) +{ + struct device_node *node = kref_to_device_node(kref); + struct property *prop = node-properties; + + /* We should never be releasing nodes that haven't been detached. */ + if (!of_node_check_flag(node, OF_DETACHED)) { + printk(KERN_WARNING Bad of_node_put() on %s\n, + node-full_name); + dump_stack(); + kref_init(node-kref); + return; + } + + if (!of_node_check_flag(node, OF_DYNAMIC)) + return; + + while (prop) { + struct property *next = prop-next; + kfree(prop-name); + kfree(prop-value); + kfree(prop); + prop = next; + + if (!prop) { + prop = node-deadprops; + node-deadprops = NULL; + } + } + kfree(node-full_name); + kfree(node-data); + kfree(node); +} + +/** + * of_node_put - Decrement refcount of a node + * @node: Node to dec refcount, NULL is supported to + * simplify writing of callers + * + */ +void of_node_put(struct device_node *node) +{ + if (node) + kref_put(node-kref, of_node_release); +} +EXPORT_SYMBOL(of_node_put); + +static struct device_node *of_derive_parent(char *path) +{ + struct device_node *parent = NULL; + char *parent_path = /; + size_t parent_path_len = strrchr(path, '/') - path + 1; + + /* reject if path is / */ + if (!strcmp(path, /)) + return ERR_PTR(-EINVAL); + + if (strrchr(path, '/') != path) { + parent_path = kmalloc(parent_path_len, GFP_KERNEL); + if (!parent_path) + return ERR_PTR(-ENOMEM); + strlcpy(parent_path, path, parent_path_len); + } + + parent = of_find_node_by_path(parent_path); + if (!parent) + return ERR_PTR(-EINVAL); + + if (strcmp(parent_path, /)) + kfree(parent_path); + return parent; +} + +static int of_attach_one_node(struct device_node *np) +{ + struct proc_dir_entry *ent; + unsigned long flags; + int rc; + + of_node_set_flag(np, OF_DYNAMIC); + kref_init(np-kref); + + np-parent = of_derive_parent(np-full_name); + if (IS_ERR(np-parent)) + return PTR_ERR(np-parent); + + rc = of_update_notifier_call(OF_ATTACH_NODE, np); + if (rc == NOTIFY_BAD) { + printk(KERN_ERR Failed to add device node %s\n, + np-full_name); + return -ENOMEM; /* For now, safe to assume kmalloc failure */ + } + + write_lock_irqsave(devtree_lock, flags); + np-sibling = np-parent-child; + np-allnext = allnodes; +
[RFC PATCH 3/5] powerpc and pseries updates for new OF dynamic code
Updates to powerpc generic and powerpc/pseries. This patch removes the dynamic device tree updating code from prom.c and deletes the no longer neccessary pSeries_reconfig.h file, all of the functionality is now in the generic OF code. The remaining changes deal with updating code for name changes with using the OF code. Signed-off-by: Nathan Fonteot nf...@austin.ibm.com --- Index: linux-next/arch/powerpc/include/asm/pSeries_reconfig.h === --- linux-next.orig/arch/powerpc/include/asm/pSeries_reconfig.h 2009-11-04 14:42:17.0 -0600 +++ /dev/null 1970-01-01 00:00:00.0 + @@ -1,29 +0,0 @@ -#ifndef _PPC64_PSERIES_RECONFIG_H -#define _PPC64_PSERIES_RECONFIG_H -#ifdef __KERNEL__ - -#include linux/notifier.h - -/* - * Use this API if your code needs to know about OF device nodes being - * added or removed on pSeries systems. - */ - -#define PSERIES_RECONFIG_ADD 0x0001 -#define PSERIES_RECONFIG_REMOVE0x0002 -#define PSERIES_DRCONF_MEM_ADD 0x0003 -#define PSERIES_DRCONF_MEM_REMOVE 0x0004 - -#ifdef CONFIG_PPC_PSERIES -extern int pSeries_reconfig_notifier_register(struct notifier_block *); -extern void pSeries_reconfig_notifier_unregister(struct notifier_block *); -#else /* !CONFIG_PPC_PSERIES */ -static inline int pSeries_reconfig_notifier_register(struct notifier_block *nb) -{ - return 0; -} -static inline void pSeries_reconfig_notifier_unregister(struct notifier_block *nb) { } -#endif /* CONFIG_PPC_PSERIES */ - -#endif /* __KERNEL__ */ -#endif /* _PPC64_PSERIES_RECONFIG_H */ Index: linux-next/arch/powerpc/kernel/prom.c === --- linux-next.orig/arch/powerpc/kernel/prom.c 2009-11-04 14:42:17.0 -0600 +++ linux-next/arch/powerpc/kernel/prom.c 2009-11-04 14:45:43.0 -0600 @@ -50,7 +50,6 @@ #include asm/btext.h #include asm/sections.h #include asm/machdep.h -#include asm/pSeries_reconfig.h #include asm/pci-bridge.h #include asm/phyp_dump.h #include asm/kexec.h @@ -1313,138 +1312,6 @@ return NULL; } -/** - * of_node_get - Increment refcount of a node - * @node: Node to inc refcount, NULL is supported to - * simplify writing of callers - * - * Returns node. - */ -struct device_node *of_node_get(struct device_node *node) -{ - if (node) - kref_get(node-kref); - return node; -} -EXPORT_SYMBOL(of_node_get); - -static inline struct device_node * kref_to_device_node(struct kref *kref) -{ - return container_of(kref, struct device_node, kref); -} - -/** - * of_node_release - release a dynamically allocated node - * @kref: kref element of the node to be released - * - * In of_node_put() this function is passed to kref_put() - * as the destructor. - */ -static void of_node_release(struct kref *kref) -{ - struct device_node *node = kref_to_device_node(kref); - struct property *prop = node-properties; - - /* We should never be releasing nodes that haven't been detached. */ - if (!of_node_check_flag(node, OF_DETACHED)) { - printk(WARNING: Bad of_node_put() on %s\n, node-full_name); - dump_stack(); - kref_init(node-kref); - return; - } - - if (!of_node_check_flag(node, OF_DYNAMIC)) - return; - - while (prop) { - struct property *next = prop-next; - kfree(prop-name); - kfree(prop-value); - kfree(prop); - prop = next; - - if (!prop) { - prop = node-deadprops; - node-deadprops = NULL; - } - } - kfree(node-full_name); - kfree(node-data); - kfree(node); -} - -/** - * of_node_put - Decrement refcount of a node - * @node: Node to dec refcount, NULL is supported to - * simplify writing of callers - * - */ -void of_node_put(struct device_node *node) -{ - if (node) - kref_put(node-kref, of_node_release); -} -EXPORT_SYMBOL(of_node_put); - -/* - * Plug a device node into the tree and global list. - */ -void of_attach_node(struct device_node *np) -{ - unsigned long flags; - - write_lock_irqsave(devtree_lock, flags); - np-sibling = np-parent-child; - np-allnext = allnodes; - np-parent-child = np; - allnodes = np; - write_unlock_irqrestore(devtree_lock, flags); -} - -/* - * Unplug a node from the device tree. The caller must hold - * a reference to the node. The memory associated with the node - * is not freed until its refcount goes to zero. - */ -void of_detach_node(struct device_node *np) -{ - struct device_node *parent; - unsigned long flags; - - write_lock_irqsave(devtree_lock, flags); - - parent = np-parent; - if (!parent) - goto out_unlock; -
[RFC PATCH 4/5] Microblaze updates for OF dynamic code
This patch removes the common OF dynamic device tree updating from the microblaze prom.c file to now use the generic OF code. NOTE: I have no means of building and testing for the microblaze architecture. I'll sign off on this with the understanding that it has not even passed the compile test yet. Signed-off-by: Nathan Fontenot nf...@austin.ibm.com --- Index: linux-next/arch/microblaze/kernel/prom.c === --- linux-next.orig/arch/microblaze/kernel/prom.c 2009-11-03 13:20:25.0 -0600 +++ linux-next/arch/microblaze/kernel/prom.c2009-11-03 14:01:34.0 -0600 @@ -30,6 +30,7 @@ #include linux/debugfs.h #include linux/irq.h #include linux/lmb.h +#include linux/of.h #include asm/prom.h #include asm/page.h @@ -859,252 +860,6 @@ } EXPORT_SYMBOL(of_find_node_by_phandle); -/** - * of_node_get - Increment refcount of a node - * @node: Node to inc refcount, NULL is supported to - * simplify writing of callers - * - * Returns node. - */ -struct device_node *of_node_get(struct device_node *node) -{ - if (node) - kref_get(node-kref); - return node; -} -EXPORT_SYMBOL(of_node_get); - -static inline struct device_node *kref_to_device_node(struct kref *kref) -{ - return container_of(kref, struct device_node, kref); -} - -/** - * of_node_release - release a dynamically allocated node - * @kref: kref element of the node to be released - * - * In of_node_put() this function is passed to kref_put() - * as the destructor. - */ -static void of_node_release(struct kref *kref) -{ - struct device_node *node = kref_to_device_node(kref); - struct property *prop = node-properties; - - /* We should never be releasing nodes that haven't been detached. */ - if (!of_node_check_flag(node, OF_DETACHED)) { - printk(KERN_INFO WARNING: Bad of_node_put() on %s\n, - node-full_name); - dump_stack(); - kref_init(node-kref); - return; - } - - if (!of_node_check_flag(node, OF_DYNAMIC)) - return; - - while (prop) { - struct property *next = prop-next; - kfree(prop-name); - kfree(prop-value); - kfree(prop); - prop = next; - - if (!prop) { - prop = node-deadprops; - node-deadprops = NULL; - } - } - kfree(node-full_name); - kfree(node-data); - kfree(node); -} - -/** - * of_node_put - Decrement refcount of a node - * @node: Node to dec refcount, NULL is supported to - * simplify writing of callers - * - */ -void of_node_put(struct device_node *node) -{ - if (node) - kref_put(node-kref, of_node_release); -} -EXPORT_SYMBOL(of_node_put); - -/* - * Plug a device node into the tree and global list. - */ -void of_attach_node(struct device_node *np) -{ - unsigned long flags; - - write_lock_irqsave(devtree_lock, flags); - np-sibling = np-parent-child; - np-allnext = allnodes; - np-parent-child = np; - allnodes = np; - write_unlock_irqrestore(devtree_lock, flags); -} - -/* - * Unplug a node from the device tree. The caller must hold - * a reference to the node. The memory associated with the node - * is not freed until its refcount goes to zero. - */ -void of_detach_node(struct device_node *np) -{ - struct device_node *parent; - unsigned long flags; - - write_lock_irqsave(devtree_lock, flags); - - parent = np-parent; - if (!parent) - goto out_unlock; - - if (allnodes == np) - allnodes = np-allnext; - else { - struct device_node *prev; - for (prev = allnodes; -prev-allnext != np; -prev = prev-allnext) - ; - prev-allnext = np-allnext; - } - - if (parent-child == np) - parent-child = np-sibling; - else { - struct device_node *prevsib; - for (prevsib = np-parent-child; -prevsib-sibling != np; -prevsib = prevsib-sibling) - ; - prevsib-sibling = np-sibling; - } - - of_node_set_flag(np, OF_DETACHED); - -out_unlock: - write_unlock_irqrestore(devtree_lock, flags); -} - -/* - * Add a property to a node - */ -int prom_add_property(struct device_node *np, struct property *prop) -{ - struct property **next; - unsigned long flags; - - prop-next = NULL; - write_lock_irqsave(devtree_lock, flags); - next = np-properties; - while (*next) { - if (strcmp(prop-name, (*next)-name) == 0) { - /* duplicate ! don't insert it */ -
[RFC PATCH 5/5] powerpc/iseries updates for new OF dynamic code
Update the powerpc/iseries vio code to use the new generic OF dynamic code. NOTE: I have no means of testing iseries kernels, this does at least pass the compile test for me. Signed-off-by: Nathan Fontenot nf...@austin.ibm.com --- Index: linux-next/arch/powerpc/platforms/iseries/vio.c === --- linux-next.orig/arch/powerpc/platforms/iseries/vio.c2009-11-02 13:39:40.0 -0600 +++ linux-next/arch/powerpc/platforms/iseries/vio.c 2009-11-03 12:34:19.0 -0600 @@ -80,8 +80,7 @@ kfree(np); } -static struct device_node *new_node(const char *path, - struct device_node *parent) +static struct device_node *new_node(const char *path) { struct device_node *np = kzalloc(sizeof(*np), GFP_KERNEL); @@ -93,9 +92,6 @@ return NULL; } strcpy(np-full_name, path); - of_node_set_flag(np, OF_DYNAMIC); - kref_init(np-kref); - np-parent = of_node_get(parent); return np; } @@ -122,7 +118,7 @@ if (!nprop) return 0; - prom_add_property(np, nprop); + of_property_attach(np, nprop); return 1; } @@ -133,19 +129,19 @@ if (!nprop) return 0; - prom_add_property(np, nprop); + of_property_attach(np, nprop); return 1; } -static struct device_node *do_device_node(struct device_node *parent, - const char *name, u32 reg, u32 unit, const char *type, - const char *compat, struct vio_resource *res) +static struct device_node *do_device_node(const char *name, u32 reg, + u32 unit, const char *type, const char *compat, + struct vio_resource *res) { struct device_node *np; char path[32]; snprintf(path, sizeof(path), /vdevice/%...@%08x, name, reg); - np = new_node(path, parent); + np = new_node(path); if (!np) return NULL; if (!add_string_property(np, name, name) || @@ -168,15 +164,6 @@ np-name = of_get_property(np, name, NULL); np-type = of_get_property(np, device_type, NULL); of_attach_node(np); -#ifdef CONFIG_PROC_DEVICETREE - if (parent-pde) { - struct proc_dir_entry *ent; - - ent = proc_mkdir(strrchr(np-full_name, '/') + 1, parent-pde); - if (ent) - proc_device_tree_add_node(np, ent); - } -#endif return np; node_free: @@ -190,16 +177,11 @@ */ struct vio_dev *vio_create_viodasd(u32 unit) { - struct device_node *vio_root; struct device_node *np; struct vio_dev *vdev = NULL; - vio_root = of_find_node_by_path(/vdevice); - if (!vio_root) - return NULL; - np = do_device_node(vio_root, viodasd, FIRST_VIODASD + unit, unit, + np = do_device_node(viodasd, FIRST_VIODASD + unit, unit, block, IBM,iSeries-viodasd, NULL); - of_node_put(vio_root); if (np) { vdev = vio_register_device_node(np); if (!vdev) @@ -254,7 +236,7 @@ } } -static void __init probe_disk(struct device_node *vio_root, u32 unit) +static void __init probe_disk(u32 unit) { HvLpEvent_Rc hvrc; struct vio_waitevent we; @@ -305,11 +287,11 @@ return; } - do_device_node(vio_root, viodasd, FIRST_VIODASD + unit, unit, + do_device_node(viodasd, FIRST_VIODASD + unit, unit, block, IBM,iSeries-viodasd, NULL); } -static void __init get_viodasd_info(struct device_node *vio_root) +static void __init get_viodasd_info(void) { int rc; u32 unit; @@ -326,7 +308,7 @@ vio_setHandler(viomajorsubtype_blockio, handle_block_event); for (unit = 0; unit HVMAXARCHITECTEDVIRTUALDISKS; unit++) - probe_disk(vio_root, unit); + probe_disk(unit); vio_clearHandler(viomajorsubtype_blockio); viopath_close(viopath_hostLp, viomajorsubtype_blockio, 2); @@ -372,7 +354,7 @@ } } -static void __init get_viocd_info(struct device_node *vio_root) +static void __init get_viocd_info(void) { HvLpEvent_Rc hvrc; u32 unit; @@ -430,7 +412,7 @@ for (unit = 0; (unit HVMAXARCHITECTEDVIRTUALCDROMS) unitinfo[unit].rsrcname[0]; unit++) { - if (!do_device_node(vio_root, viocd, FIRST_VIOCD + unit, unit, + if (!do_device_node(viocd, FIRST_VIOCD + unit, unit, block, IBM,iSeries-viocd, unitinfo[unit])) break; } @@ -464,7 +446,7 @@ } } -static void __init get_viotape_info(struct device_node *vio_root) +static void __init get_viotape_info(void) { HvLpEvent_Rc hvrc; u32 unit; @@ -507,7 +489,7 @@ for (unit = 0; (unit HVMAXARCHITECTEDVIRTUALTAPES)
[PATCH 1/3] fsl_pq_mdio: Fix compiler/sparse warnings (part 1)
commit 1d2397d742b7a2b39b2f09dd9da3b9d1463f55e9 (fsl_pq_mdio: Add Suport for etsec2.0 devices) introduced the following warnings: CHECK fsl_pq_mdio.c fsl_pq_mdio.c:287:22: warning: incorrect type in initializer (different base types) fsl_pq_mdio.c:287:22:expected unknown type 11 const *__mptr fsl_pq_mdio.c:287:22:got unsigned long long [unsigned] [assigned] [usertype] addr fsl_pq_mdio.c:287:19: warning: incorrect type in assignment (different base types) fsl_pq_mdio.c:287:19:expected unsigned long long [unsigned] [usertype] ioremap_miimcfg fsl_pq_mdio.c:287:19:got struct fsl_pq_mdio *noident CC fsl_pq_mdio.o fsl_pq_mdio.c: In function 'fsl_pq_mdio_probe': fsl_pq_mdio.c:287: warning: initialization makes pointer from integer without a cast fsl_pq_mdio.c:287: warning: assignment makes integer from pointer without a cast These warnings are not easy to fix without ugly __force casts. So, instead of introducing the casts, rework the code to substitute an offset from an already mapped area. This makes the code a lot simpler and less duplicated. Plus, from now on we don't actually map reserved registers on non-etsec2.0 devices, so we have more chances to catch programming errors. Signed-off-by: Anton Vorontsov avoront...@ru.mvista.com --- drivers/net/fsl_pq_mdio.c | 31 --- 1 files changed, 12 insertions(+), 19 deletions(-) diff --git a/drivers/net/fsl_pq_mdio.c b/drivers/net/fsl_pq_mdio.c index 4065b7c..fb8c8d9 100644 --- a/drivers/net/fsl_pq_mdio.c +++ b/drivers/net/fsl_pq_mdio.c @@ -262,10 +262,11 @@ static int fsl_pq_mdio_probe(struct of_device *ofdev, struct device_node *np = ofdev-node; struct device_node *tbi; struct fsl_pq_mdio __iomem *regs = NULL; + void __iomem *map; u32 __iomem *tbipa; struct mii_bus *new_bus; int tbiaddr = -1; - u64 addr = 0, size = 0, ioremap_miimcfg = 0; + u64 addr = 0, size = 0; int err = 0; new_bus = mdiobus_alloc(); @@ -279,28 +280,20 @@ static int fsl_pq_mdio_probe(struct of_device *ofdev, fsl_pq_mdio_bus_name(new_bus-id, np); /* Set the PHY base address */ - if (of_device_is_compatible(np,fsl,gianfar-mdio) || - of_device_is_compatible(np, fsl,gianfar-tbi) || - of_device_is_compatible(np, fsl,ucc-mdio) || - of_device_is_compatible(np,ucc_geth_phy )) { - addr = of_translate_address(np, of_get_address(np, 0, size, NULL)); - ioremap_miimcfg = container_of(addr, struct fsl_pq_mdio, miimcfg); - regs = ioremap(ioremap_miimcfg, size + - offsetof(struct fsl_pq_mdio, miimcfg)); - } else if (of_device_is_compatible(np,fsl,etsec2-mdio) || - of_device_is_compatible(np, fsl,etsec2-tbi)) { - addr = of_translate_address(np, of_get_address(np, 0, size, NULL)); - regs = ioremap(addr, size); - } else { - err = -EINVAL; - goto err_free_bus; - } - - if (NULL == regs) { + addr = of_translate_address(np, of_get_address(np, 0, size, NULL)); + map = ioremap(addr, size); + if (!map) { err = -ENOMEM; goto err_free_bus; } + if (of_device_is_compatible(np, fsl,gianfar-mdio) || + of_device_is_compatible(np, fsl,gianfar-tbi) || + of_device_is_compatible(np, fsl,ucc-mdio) || + of_device_is_compatible(np, ucc_geth_phy)) + map -= offsetof(struct fsl_pq_mdio, miimcfg); + regs = map; + new_bus-priv = (void __force *)regs; new_bus-irq = kcalloc(PHY_MAX_ADDR, sizeof(int), GFP_KERNEL); -- 1.6.3.3 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 2/3] fsl_pq_mdio: Fix compiler/sparse warnings (part 2)
This patch fixes following warnings: fsl_pq_mdio.c:112:38: warning: cast adds address space to expression (asn:2) fsl_pq_mdio.c:124:38: warning: cast adds address space to expression (asn:2) fsl_pq_mdio.c:133:38: warning: cast adds address space to expression (asn:2) fsl_pq_mdio.c:414:11: warning: cast adds address space to expression (asn:2) Instead of adding __force all over the place, introduce convenient fsl_pq_mdio_get_regs() call that does the ugly casting just once. Signed-off-by: Anton Vorontsov avoront...@ru.mvista.com --- drivers/net/fsl_pq_mdio.c | 13 + 1 files changed, 9 insertions(+), 4 deletions(-) diff --git a/drivers/net/fsl_pq_mdio.c b/drivers/net/fsl_pq_mdio.c index fb8c8d9..b2ca596 100644 --- a/drivers/net/fsl_pq_mdio.c +++ b/drivers/net/fsl_pq_mdio.c @@ -103,13 +103,18 @@ int fsl_pq_local_mdio_read(struct fsl_pq_mdio __iomem *regs, return value; } +static struct fsl_pq_mdio __iomem *fsl_pq_mdio_get_regs(struct mii_bus *bus) +{ + return (void __iomem __force *)bus-priv; +} + /* * Write value to the PHY at mii_id at register regnum, * on the bus, waiting until the write is done before returning. */ int fsl_pq_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value) { - struct fsl_pq_mdio __iomem *regs = (void __iomem *)bus-priv; + struct fsl_pq_mdio __iomem *regs = fsl_pq_mdio_get_regs(bus); /* Write to the local MII regs */ return(fsl_pq_local_mdio_write(regs, mii_id, regnum, value)); @@ -121,7 +126,7 @@ int fsl_pq_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value) */ int fsl_pq_mdio_read(struct mii_bus *bus, int mii_id, int regnum) { - struct fsl_pq_mdio __iomem *regs = (void __iomem *)bus-priv; + struct fsl_pq_mdio __iomem *regs = fsl_pq_mdio_get_regs(bus); /* Read the local MII regs */ return(fsl_pq_local_mdio_read(regs, mii_id, regnum)); @@ -130,7 +135,7 @@ int fsl_pq_mdio_read(struct mii_bus *bus, int mii_id, int regnum) /* Reset the MIIM registers, and wait for the bus to free */ static int fsl_pq_mdio_reset(struct mii_bus *bus) { - struct fsl_pq_mdio __iomem *regs = (void __iomem *)bus-priv; + struct fsl_pq_mdio __iomem *regs = fsl_pq_mdio_get_regs(bus); int timeout = PHY_INIT_TIMEOUT; mutex_lock(bus-mdio_lock); @@ -404,7 +409,7 @@ static int fsl_pq_mdio_remove(struct of_device *ofdev) dev_set_drvdata(device, NULL); - iounmap((void __iomem *)bus-priv); + iounmap(fsl_pq_mdio_get_regs(bus)); bus-priv = NULL; mdiobus_free(bus); -- 1.6.3.3 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 3/3] gianfar: Fix compiler and sparse warnings
commit fba4ed030cfae7efdb6b79a57b0c5a9d72c9de83 (gianfar: Add Multiple Queue Support) introduced the following warnings: CHECK gianfar.c gianfar.c:333:8: warning: incorrect type in assignment (different address spaces) gianfar.c:333:8:expected unsigned int [usertype] *baddr gianfar.c:333:8:got unsigned int [noderef] asn:2*noident [... 67 lines skipped ...] gianfar.c:2565:3: warning: incorrect type in argument 1 (different type sizes) gianfar.c:2565:3:expected unsigned long const *addr gianfar.c:2565:3:got unsigned int *noident CC gianfar.o gianfar.c: In function 'gfar_probe': gianfar.c:985: warning: passing argument 1 of 'find_next_bit' from incompatible pointer type gianfar.c:985: warning: passing argument 1 of 'find_next_bit' from incompatible pointer type gianfar.c:993: warning: passing argument 1 of 'find_next_bit' from incompatible pointer type gianfar.c:993: warning: passing argument 1 of 'find_next_bit' from incompatible pointer type gianfar.c: In function 'gfar_configure_coalescing': gianfar.c:1680: warning: passing argument 1 of 'find_next_bit' from incompatible pointer type gianfar.c:1680: warning: passing argument 1 of 'find_next_bit' from incompatible pointer type gianfar.c:1688: warning: passing argument 1 of 'find_next_bit' from incompatible pointer type gianfar.c:1688: warning: passing argument 1 of 'find_next_bit' from incompatible pointer type gianfar.c: In function 'gfar_poll': gianfar.c:2565: warning: passing argument 1 of 'find_next_bit' from incompatible pointer type gianfar.c:2565: warning: passing argument 1 of 'find_next_bit' from incompatible pointer type gianfar.c:2566: warning: passing argument 2 of 'test_bit' from incompatible pointer type gianfar.c:2585: warning: passing argument 2 of 'set_bit' from incompatible pointer type Following warnings left unfixed (looks like sparse doesn't like locks in loops, so __acquires/__releases() doesn't help): gianfar.c:441:40: warning: context imbalance in 'lock_rx_qs': wrong count at exit gianfar.c:441:40:context 'noident': wanted 0, got 1 gianfar.c:449:40: warning: context imbalance in 'lock_tx_qs': wrong count at exit gianfar.c:449:40:context 'noident': wanted 0, got 1 gianfar.c:458:3: warning: context imbalance in 'unlock_rx_qs': __context__ statement expected different context gianfar.c:458:3:context 'noident': wanted = 0, got -1 gianfar.c:466:3: warning: context imbalance in 'unlock_tx_qs': __context__ statement expected different context gianfar.c:466:3:context 'noident': wanted = 0, got -1 Signed-off-by: Anton Vorontsov avoront...@ru.mvista.com --- drivers/net/gianfar.c | 14 -- drivers/net/gianfar.h | 10 +- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index 086d40d..197b358 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c @@ -327,7 +327,7 @@ cleanup: static void gfar_init_tx_rx_base(struct gfar_private *priv) { struct gfar __iomem *regs = priv-gfargrp[0].regs; - u32 *baddr; + u32 __iomem *baddr; int i; baddr = regs-tbase0; @@ -770,7 +770,8 @@ static unsigned int reverse_bitmap(unsigned int bit_map, unsigned int max_qs) return new_bit_map; } -u32 cluster_entry_per_class(struct gfar_private *priv, u32 rqfar, u32 class) +static u32 cluster_entry_per_class(struct gfar_private *priv, u32 rqfar, + u32 class) { u32 rqfpr = FPR_FILER_MASK; u32 rqfcr = 0x0; @@ -849,7 +850,7 @@ static int gfar_probe(struct of_device *ofdev, int len_devname; u32 rstat = 0, tstat = 0, rqueue = 0, tqueue = 0; u32 isrg = 0; - u32 *baddr; + u32 __iomem *baddr; err = gfar_of_init(ofdev, dev); @@ -1658,10 +1659,10 @@ void gfar_start(struct net_device *dev) } void gfar_configure_coalescing(struct gfar_private *priv, - unsigned int tx_mask, unsigned int rx_mask) + unsigned long tx_mask, unsigned long rx_mask) { struct gfar __iomem *regs = priv-gfargrp[0].regs; - u32 *baddr; + u32 __iomem *baddr; int i = 0; /* Backward compatible case even if we enable @@ -2546,7 +2547,8 @@ static int gfar_poll(struct napi_struct *napi, int budget) struct gfar_priv_tx_q *tx_queue = NULL; struct gfar_priv_rx_q *rx_queue = NULL; int rx_cleaned = 0, budget_per_queue = 0, rx_cleaned_per_queue = 0; - int tx_cleaned = 0, i, left_over_budget = budget, serviced_queues = 0; + int tx_cleaned = 0, i, left_over_budget = budget; + unsigned long serviced_queues = 0; int num_queues = 0; unsigned long flags; diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h index 44b63da..cbb4510 100644 --- a/drivers/net/gianfar.h +++ b/drivers/net/gianfar.h @@ -986,10 +986,10 @@ struct gfar_priv_grp { struct gfar_private *priv; struct gfar __iomem *regs;
[PATCH RFC] gianfar: Make polling safe with IRQs disabled
When using KGDBoE, gianfar driver spits 'Interrupt problem' messages, which appears to be a legitimate warning, i.e. we may end up calling netif_receive_skb() or vlan_hwaccel_receive_skb() with IRQs disabled. This patch reworks the RX path so that if netpoll is enabled (the only case when the driver don't know from what context the polling may be called), we check whether IRQs are disabled, and if so we fall back to safe variants of skb receiving functions. Signed-off-by: Anton Vorontsov avoront...@ru.mvista.com --- I'm not sure if this is suitable for mainline since it doesn't have KGDBoE support. Jason, if the patch is OK, would you like to merge it into KGDB tree? drivers/net/gianfar.c | 17 + 1 files changed, 13 insertions(+), 4 deletions(-) diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index 197b358..024ca4a 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c @@ -2412,9 +2412,17 @@ static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb, { struct gfar_private *priv = netdev_priv(dev); struct rxfcb *fcb = NULL; - + int irqs_dis = 0; int ret; + /* +* With netpoll we don't know from what context we're called (e.g +* KGDBoE may call us from an exception handler), otherwise we're +* pretty sure that IRQs are enabled. +*/ +#ifdef CONFIG_NETPOLL + irqs_dis = irqs_disabled(); +#endif /* fcb is at the beginning if exists */ fcb = (struct rxfcb *)skb-data; @@ -2432,7 +2440,10 @@ static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb, /* Send the packet up the stack */ if (unlikely(priv-vlgrp (fcb-flags RXFCB_VLN))) - ret = vlan_hwaccel_receive_skb(skb, priv-vlgrp, fcb-vlctl); + ret = __vlan_hwaccel_rx(skb, priv-vlgrp, fcb-vlctl, + !irqs_dis); + else if (irqs_dis) + ret = netif_rx(skb); else ret = netif_receive_skb(skb); @@ -2504,8 +2515,6 @@ int gfar_clean_rx_ring(struct gfar_priv_rx_q *rx_queue, int rx_work_limit) skb_put(skb, pkt_len); dev-stats.rx_bytes += pkt_len; - if (in_irq() || irqs_disabled()) - printk(Interrupt problem!\n); gfar_process_frame(dev, skb, amount_pull); } else { -- 1.6.3.3 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH] powerpc/mm: Remove debug context clamping from nohash code
I inadvertently left that debug code enabled, causing the number of contexts to be clamped to 31 which is going to slow things down on 4xx and just plain breaks 8xx Signed-off-by: Benjamin Herrenschmidt b...@kernel.crashing.org --- arch/powerpc/mm/mmu_context_nohash.c |4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/mm/mmu_context_nohash.c b/arch/powerpc/mm/mmu_context_nohash.c index c2f93dc..be4f34c 100644 --- a/arch/powerpc/mm/mmu_context_nohash.c +++ b/arch/powerpc/mm/mmu_context_nohash.c @@ -25,8 +25,8 @@ * also clear mm-cpu_vm_mask bits when processes are migrated */ -#define DEBUG_MAP_CONSISTENCY -#define DEBUG_CLAMP_LAST_CONTEXT 31 +//#define DEBUG_MAP_CONSISTENCY +//#define DEBUG_CLAMP_LAST_CONTEXT 31 //#define DEBUG_HARDER /* We don't use DEBUG because it tends to be compiled in always nowadays ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [powerpc] Next tree Nov 2 : kernel BUG at mm/mmap.c:2135!
On Wed, Nov 04, 2009 at 06:08:44PM +0530, Sachin Sant wrote: Sachin Sant wrote: Today's next tree failed to boot on a POWER 6 box with : [ cut here ] kernel BUG at mm/mmap.c:2135! Oops: Exception in kernel mode, sig: 5 [#2] SMP NR_CPUS=1024 NUMA pSeries Problem exists with today's next as well. Likely cause for this problem seems to the following commit. If i revert this patch the machine boots fine. commit a0668cdc154e54bf0c85182e0535eea237d53146 powerpc/mm: Cleanup management of kmem_caches for pagetables Ugh. Ok, it's not at all obvious how my patch could cause this bug. Can you send your .config? Modules linked in: ibmvscsic scsi_transport_srp scsi_tgt scsi_mod NIP: c014e30c LR: c014e2f8 CTR: c014db88 REGS: c000db703620 TRAP: 0700 Tainted: G D (2.6.32-rc5-autotest-next-20091102) MSR: 80029032 EE,ME,CE,IR,DR CR: 24022442 XER: 200c TASK = c000db7f6fe0[76] 'init' THREAD: c000db70 CPU: 1 GPR00: 0001 c000db7038a0 c0b19900 GPR04: c000db406a40 000c c000fe10c370 c0bb2800 GPR08: db40 c000dfdc0e00 000c GPR12: 44022442 c0bb2800 GPR16: 0843 003c c000db703ea0 c000db569108 GPR20: c000db568908 c000db703d60 GPR24: 0001 00040100 c000fe503580 c000db1ac180 GPR28: c0f812d0 c0a84f00 NIP [c014e30c] .exit_mmap+0x190/0x1b8 LR [c014e2f8] .exit_mmap+0x17c/0x1b8 Call Trace: [c000db7038a0] [c014e2f8] .exit_mmap+0x17c/0x1b8 (unreliable) [c000db703950] [c00916cc] .mmput+0x54/0x164 [c000db7039e0] [c00968d8] .exit_mm+0x17c/0x1a0 [c000db703a90] [c0098cb8] .do_exit+0x248/0x784 [c000db703b70] [c00992a8] .do_group_exit+0xb4/0xe8 [c000db703c00] [c00aca2c] .get_signal_to_deliver+0x3ec/0x478 [c000db703cf0] [c00134ac] .do_signal+0x6c/0x31c [c000db703e30] [c0008b7c] do_work+0x24/0x28 Instruction dump: 7c8407b4 387d0018 4800ab11 6000 939d0008 7fe3fb78 4bfffdbd 7c7f1b79 4082fff4 e81b00e8 3120 7c090110 0b00 382100b0 e8010010 eb61ffd8 ---[ end trace ec052ac77a8e7cb4 ]--- Fixing recursive fault but reboot is needed! mm/mmap.c:2135 corresponds to : BUG_ON(mm-nr_ptes (FIRST_USER_ADDRESS+PMD_SIZE-1)PMD_SHIFT); -- 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/~dgibson ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH] BUILD_BUG_ON: make it handle more cases
Hi Rusty, On Tue, 20 Oct 2009 14:15:33 +1030 Rusty Russell ru...@rustcorp.com.au wrote: +#ifndef __OPTIMIZE__ +#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)])) +#else +extern int __build_bug_on_failed; +#define BUILD_BUG_ON(condition) \ + do {\ + ((void)sizeof(char[1 - 2*!!(condition)])); \ + if (condition) __build_bug_on_failed = 1; \ + } while(0) +#endif +#define MAYBE_BUILD_BUG_ON(condition) BUILD_BUG_ON(condition) + I decided to try this in linux-next, but an x86_64 allmodconfig build gave this (gcc 4.4.0): ERROR: __build_bug_on_failed [drivers/net/virtio_net.ko] undefined! ERROR: __build_bug_on_failed [drivers/block/virtio_blk.ko] undefined! I assume that this is caused by the MAYBE_BUILD_BUG_ON(fbit = 32) in virtio_has_feature() (in include/linux/virtio_config.h) which is called all over the place. Unfortunately, virtio_has_feature() gets uninlined in those two files ... I have taken the patch back out again for today. -- Cheers, Stephen Rothwells...@canb.auug.org.au http://www.canb.auug.org.au/~sfr/ pgpepvBMY373a.pgp Description: PGP signature ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 14/27] Add book3s_64 specific opcode emulation
+ case OP_31_XOP_EIOIO: + break; Have you always executed an eieio or sync when you get here, or do you just not allow direct access to I/O devices? Other context synchronising insns are not enough, they do not broadcast on the bus. There is no device passthrough yet :-). It's theoretically possible, but nothing for it is implemented so far. You could just always do an eieio here, it's not expensive at all compared to the emulation trap itself. However -- eieio is a Book II insn, it will never trap anyway! + case OP_31_XOP_DCBZ: + { + ulong rb = vcpu-arch.gpr[get_rb(inst)]; + ulong ra = 0; + ulong addr; + u32 zeros[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; + + if (get_ra(inst)) + ra = vcpu-arch.gpr[get_ra(inst)]; + + addr = (ra + rb) ~31ULL; + if (!(vcpu-arch.msr MSR_SF)) + addr = 0x; + + if (kvmppc_st(vcpu, addr, 32, zeros)) { DCBZ zeroes out a cache line, not 32 bytes; except on 970, where there are HID bits to make it work on 32 bytes only, and an extra DCBZL insn that always clears a full cache line (128 bytes). Yes. We only come here when we patched the dcbz opcodes to invalid instructions Ah yes, I forgot. Could you rename it to OP_31_XOP_FAKE_32BIT_DCBZ or such? because cache line size of target == 32. On 970 with MSR_HV = 0 we actually use the dcbz 32-bytes mode. Admittedly though, this could be a lot more clever. + /* guest HID5 set can change is_dcbz32 */ + if (vcpu-arch.mmu.is_dcbz32(vcpu) + (mfmsr() MSR_HV)) + vcpu-arch.hflags |= BOOK3S_HFLAG_DCBZ32; + break; Wait, does this mean you allow other HID writes when MSR[HV] isn't set? All HIDs (and many other SPRs) cannot be read or written in supervisor mode. When we're running in MSR_HV=0 mode on a 970 we can use the 32 byte dcbz HID flag. So all we need to do is tell our entry/exit code to set this bit. Which patch contains that entry/exit code? If we're on 970 on a hypervisor or on a non-970 though we can't use the HID5 bit, so we need to binary patch the opcodes. So in order to emulate real 970 behavior, we need to be able to emulate that HID5 bit too! That's what this chunk of code does - it basically sets us in dcbz32 mode when allowed on 970 guests. But when MSR[HV]=0 and MSR[PR]=0, mtspr to a hypervisor resource will not trap but be silently ignored. Sorry for not being more clear. ...Oh. You run your guest as MSR[PR]=1 anyway! Tricky. Segher ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH] PCI: Fix regression in powerpc MSI-X
On Wed, 2009-11-04 at 13:03 -0200, Andre Detsch wrote: Patch f598282f5145036312d90875d0ed5c14b49fd8a7 exposed a problem in powerpc MSI-X functionality, making network interfaces such as ixgbe and cxgb3 stop to work when MSI-X is enabled. RX interrupts were not being generated. Which means we'd like it in 32 please Ben. Also Andre, once Ben has merged this you should forward it to sta...@kernel.org for the 31 stable series. cheers signature.asc Description: This is a digitally signed message part ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: Regarding FPGA based cascaded PIC
On Thu, 05 Nov 2009 07:51:22 +1100, Benjamin Herrenschmidt b...@kernel.crashing.org wrote: On Wed, 2009-11-04 at 18:09 +0530, Thirumalai wrote: you understood correctly. Here the problem lies.Correct me if i am wrong. So you are telling that irq_of_parse_and_map() will invoke the map/xlate of my FPGA pic. Right. But this is what not happening. Instead of calling my map/xlate functions the irq_of_parse_and_map() function is invoking mpic's map/xlate function. irq_of_parse_and_map() will call the map/xlate function of the parent PIC for the given interrupt. In your case, the interrupts you are calling it for are defined as being interrupts wiring the FPGA to the MPIC, hence are MPIC inputs, and thus will be parsed/mapped by the MPIC. From the MPIC standpoint, the FPGA is just a device. So the code is doing what you tell it to do :-) I don't understand what you are actually trying to acheive. If those 3 interrupts aren't outputs from the FPGA to the MPIC but input to the FPGA then they shouldn't be there, they should be device interrupts connected to the FPGA. Those will end up with map/xlate called in the FPGA host. I Understood the thing. Thank you very much. So you mean to say that my map/xlate functions will get invoked only for the devices which is connected the FPGA PIC. So for example suppose if i have an WDT connected to my FPGA then the interrupt-parent tag should point to FPGA-PIC. So at that time the irq_of_parse_and_map() will invoke my map/xlate functions right. So i need to define the nodes on my device tree for the devices which are all going to generate interrupts for FPGA and keeping the interrupt-parent property as fpga-pic. So my device node for WDT is something like the following w...@4,2000 { #interrupt-cells = 2; device_type = watchdog; compatible = gef,fpga-wdt; reg = 0x4 0x2000 0x8; interrupts = 0x1a 0x4; interrupt-parent = fpga_pic; }; Correct me if i am wrong. Ben. Here is the piece of code that we are using. fpga_pic_irq_host = irq_alloc_host(pic, IRQ_HOST_MAP_LINEAR, DPVPX0659_FPGA_NUM_IRQS,fpga_pic_host_ops, NO_IRQ); if (fpga_pic_irq_host == NULL) { printk(FPGA PIC: Unable to allocate host\n); return; } for (i = 0; i 3; i++) { fpga_irqs[i] = irq_of_parse_and_map(pic, i); if (fpga_irqs[i] == NO_IRQ) { printk(FPGA PIC: can't get irq %d.\n, i); continue; } printk(interrupt from device tree : %d \n,fpga_irqs[i]); set_irq_chained_handler(dpvpx0659_fpga_irqs[i],dpvpx0659_fpga_pic_cascade); } Thank you Thirumalai CAUTION - Disclaimer *This email may contain confidential and privileged material for the sole use of the intended recipient(s). Any review, use, retention, distribution or disclosure by others is strictly prohibited. If you are not the intended recipient (or authorized to receive for the recipient), please contact the sender by reply email and delete all copies of this message. Also, email is susceptible to data corruption, interception, tampering, unauthorized amendment and viruses. We only send and receive emails on the basis that we are not liable for any such corruption, interception, tampering, amendment or viruses or any consequence thereof. *** End of Disclaimer ***DataPatterns ITS Group** ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: Regarding FPGA based cascaded PIC
On Thu, 2009-11-05 at 08:16 +0530, thirumalai.p wrote: I Understood the thing. Thank you very much. So you mean to say that my map/xlate functions will get invoked only for the devices which is connected the FPGA PIC. Right, and I fail to see how it would make any sense the other way around :-) Seriously, the map and xlate functions are used to hook up interrupt to the PIC inputs. So logically, the 3 cascade interrupts are -inputs- to the parent controller and as such get mapped by that controller. IE. The parent is the only one to understand the format of the interrupts properties for those and the interrupt numbers for those are HW numbers in the parent space. It wouldn't make -any- sense to call map/xlate of the child. In fact, for the code in question, the child PIC is just a device, the fact that that device is itself a PIC is irrelevant. So for example suppose if i have an WDT connected to my FPGA then the interrupt-parent tag should point to FPGA-PIC. So at that time the irq_of_parse_and_map() will invoke my map/xlate functions right. Yes. So i need to define the nodes on my device tree for the devices which are all going to generate interrupts for FPGA and keeping the interrupt-parent property as fpga-pic. Or you can just keep track of the irq_host * of the FPGA and manually call irq_create_mapping() passing it a HW number in the FPGA irq space if you don't want to create device nodes for those children but the device-node approach is preferred. So my device node for WDT is something like the following w...@4,2000 { #interrupt-cells = 2; device_type = watchdog; compatible = gef,fpga-wdt; reg = 0x4 0x2000 0x8; interrupts = 0x1a 0x4; interrupt-parent = fpga_pic; }; Correct me if i am wrong. It looks ok except that if I remember correctly, your FPGA PIC has a #interrupt-cells value of '3' which means that it expects 3 numbers in the interrupts property to define an interrupt (which your xlate function is then going to translate into the appropriate HW number and sense/polarity flags for linux). So if you use only 2 numbers, you need to fix your #interrupt-cells property value. Cheers, Ben. Ben. Here is the piece of code that we are using. fpga_pic_irq_host = irq_alloc_host(pic, IRQ_HOST_MAP_LINEAR, DPVPX0659_FPGA_NUM_IRQS,fpga_pic_host_ops, NO_IRQ); if (fpga_pic_irq_host == NULL) { printk(FPGA PIC: Unable to allocate host\n); return; } for (i = 0; i 3; i++) { fpga_irqs[i] = irq_of_parse_and_map(pic, i); if (fpga_irqs[i] == NO_IRQ) { printk(FPGA PIC: can't get irq %d.\n, i); continue; } printk(interrupt from device tree : %d \n,fpga_irqs[i]); set_irq_chained_handler(dpvpx0659_fpga_irqs[i],dpvpx0659_fpga_pic_cascade); } Thank you Thirumalai ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev