Adeos for Linux 2.6.19 PowerPC kernels.
Subsystems (9)
PATCH 1/1 Adeos for Linux 2.6.19 PowerPC kernels.
Hello,
A few time ago, I've sent a first draft of a patch that aimed at porting Adeos Ipipe from PPC to PowerPC kernel architecture. While being ported, the patch had problems running on due to some incompabilities with the IRQ handling.
I recently reworked on it and have it fixed.
Please see attached patch that adds PowerPC support on Linux 2.6.19(.2) kernel. It is based on current ppc patch (v1.5) for 2.6.19.
For the record, the previous draft was in fact blocking as soon as an h/w IRQ comes in. Adeos was unable to acknowledge the interruption and so, it was triggered thousands of times a second, hanging on the board.
Judging by arch/powerpc/sysdev/ipic.c, I've replaced all ack() calls in ipipe-root.c by a mask_ack() call and added an end() implementation, that basically unmask() the IRQ after being treated.
This may not be the best way to solve the issue but at least it works for now, allowing more dev to be done on PowerPC platform. The best way would probably to adapt the ipipe-root to a new Adeos version (like x86 arch does, defining multiple acknowledging functions, whether the IRQ is level or edge based, but it's out of my scope right now).
If the patch is accepted (and I hope it will), I may extend it later on (for more recent kernels like 2.6.21) or upgrading to a newest Adeos version (but each version being pretty undocumented in terms of ChangeLog, it's pretty hard to do) if you can provide me advices, unless somebody else beats me on that.
PS: if applied, please keep the README.adeos file unchanged as it was mandatory for me to have the patch pushed upstream ;-)
Thanks for reviewal,
Ben
arch/powerpc/Kconfig +2 -0
@@ -613,6 +613,8 @@ menu "Kernel options" +source "kernel/ipipe/Kconfig" + config HIGHMEM bool "High memory support" depends on PPC32
arch/powerpc/kernel/entry_32.S +92 -0
140 lines not on this page · raw message
arch/powerpc/kernel/head_32.S +15 -1
@@ -329,6 +329,12 @@ EXC_XFER_TEMPLATE(n, hdlr, n, NOCOPY, transfer_to_handler_full, \ ret_from_except_full) +#ifdef CONFIG_IPIPE +#define EXC_XFER_IPIPE(n, hdlr) \ + EXC_XFER_TEMPLATE(n, hdlr, n+1, NOCOPY, transfer_to_handler, \ + __ipipe_ret_from_except) +#endif /* CONFIG_IPIPE */ + #define EXC_XFER_LITE(n, hdlr) \ EXC_XFER_TEMPLATE(n, hdlr, n+1, NOCOPY, transfer_to_handler, \ ret_from_except)
@@ -418,8 +424,12 @@ EXC_XFER_EE_LITE(0x400, handle_page_fault) /* External interrupt */ +#ifdef CONFIG_IPIPE + EXCEPTION(0x500, HardwareInterrupt, __ipipe_grab_irq, EXC_XFER_IPIPE) +#else /* !CONFIG_IPIPE */ EXCEPTION(0x500, HardwareInterrupt, do_IRQ, EXC_XFER_LITE) - +#endif /* CONFIG_IPIPE */ + /* Alignment exception */ . = 0x600 Alignment:
@@ -443,7 +453,11 @@ EXC_XFER_EE_LITE(0x800, kernel_fp_unavailable_exception) /* Decrementer */ +#ifdef CONFIG_IPIPE + EXCEPTION(0x900, Decrementer, __ipipe_grab_timer, EXC_XFER_IPIPE) +#else /* !CONFIG_IPIPE */ EXCEPTION(0x900, Decrementer, timer_interrupt, EXC_XFER_LITE) +#endif /* CONFIG_IPIPE */ EXCEPTION(0xa00, Trap_0a, unknown_exception, EXC_XFER_EE) EXCEPTION(0xb00, Trap_0b, unknown_exception, EXC_XFER_EE)
arch/powerpc/kernel/head_44x.S +5 -1
@@ -427,8 +427,12 @@ INSTRUCTION_STORAGE_EXCEPTION /* External Input Interrupt */ +#ifdef CONFIG_IPIPE + EXCEPTION(0x0500, ExternalInput, __ipipe_grab_irq, EXC_XFER_IPIPE) +#else /* !CONFIG_IPIPE */ EXCEPTION(0x0500, ExternalInput, do_IRQ, EXC_XFER_LITE) - +#endif /* CONFIG_IPIPE */ + /* Alignment Interrupt */ ALIGNMENT_EXCEPTION
arch/powerpc/kernel/head_4xx.S +16 -2
@@ -228,6 +228,12 @@ EXC_XFER_TEMPLATE(hdlr, n, MSR_KERNEL, NOCOPY, transfer_to_handler_full, \ ret_from_except_full) +#ifdef CONFIG_IPIPE +#define EXC_XFER_IPIPE(n, hdlr) \ + EXC_XFER_TEMPLATE(hdlr, n+1, MSR_KERNEL, NOCOPY, transfer_to_handler, \ + __ipipe_ret_from_except) +#endif /* CONFIG_IPIPE */ + #define EXC_XFER_LITE(n, hdlr) \ EXC_XFER_TEMPLATE(hdlr, n+1, MSR_KERNEL, NOCOPY, transfer_to_handler, \ ret_from_except)
@@ -396,8 +402,12 @@ EXC_XFER_EE_LITE(0x400, handle_page_fault) /* 0x0500 - External Interrupt Exception */ +#ifdef CONFIG_IPIPE + EXCEPTION(0x0500, HardwareInterrupt, __ipipe_grab_irq, EXC_XFER_IPIPE) +#else /* !CONFIG_IPIPE */ EXCEPTION(0x0500, HardwareInterrupt, do_IRQ, EXC_XFER_LITE) - +#endif /* CONFIG_IPIPE */ + /* 0x0600 - Alignment Exception */ START_EXCEPTION(0x0600, Alignment) NORMAL_EXCEPTION_PROLOG
@@ -434,8 +444,12 @@ lis r0,TSR_PIS@h mtspr SPRN_TSR,r0 /* Clear the PIT exception */ addi r3,r1,STACK_FRAME_OVERHEAD +#ifdef CONFIG_IPIPE + EXC_XFER_IPIPE(0x1000, __ipipe_grab_timer) +#else /* !CONFIG_IPIPE */ EXC_XFER_LITE(0x1000, timer_interrupt) - +#endif /* CONFIG_IPIPE */ + #if 0 /* NOTE: * FIT and WDT handlers are not implemented yet.
arch/powerpc/kernel/head_8xx.S +16 -2
@@ -187,6 +187,12 @@ EXC_XFER_TEMPLATE(n, hdlr, n, NOCOPY, transfer_to_handler_full, \ ret_from_except_full) +#ifdef CONFIG_IPIPE +#define EXC_XFER_IPIPE(n, hdlr) \ + EXC_XFER_TEMPLATE(n, hdlr, n+1, NOCOPY, transfer_to_handler, \ + __ipipe_ret_from_except) +#endif /* CONFIG_IPIPE */ + #define EXC_XFER_LITE(n, hdlr) \ EXC_XFER_TEMPLATE(n, hdlr, n+1, NOCOPY, transfer_to_handler, \ ret_from_except)
@@ -238,8 +244,12 @@ EXC_XFER_EE_LITE(0x400, handle_page_fault) /* External interrupt */ +#ifdef CONFIG_IPIPE + EXCEPTION(0x500, HardwareInterrupt, __ipipe_grab_irq, EXC_XFER_IPIPE) +#else /* !CONFIG_IPIPE */ EXCEPTION(0x500, HardwareInterrupt, do_IRQ, EXC_XFER_LITE) - +#endif /* CONFIG_IPIPE */ + /* Alignment exception */ . = 0x600 Alignment:
@@ -259,8 +269,12 @@ EXCEPTION(0x800, FPUnavailable, unknown_exception, EXC_XFER_STD) /* Decrementer */ +#ifdef CONFIG_IPIPE + EXCEPTION(0x900, Decrementer, __ipipe_grab_timer, EXC_XFER_IPIPE) +#else /* !CONFIG_IPIPE */ EXCEPTION(0x900, Decrementer, timer_interrupt, EXC_XFER_LITE) - +#endif /* CONFIG_IPIPE */ + EXCEPTION(0xa00, Trap_0a, unknown_exception, EXC_XFER_EE) EXCEPTION(0xb00, Trap_0b, unknown_exception, EXC_XFER_EE)
arch/powerpc/kernel/head_booke.h +16 -0
@@ -187,6 +187,12 @@EXC_XFER_TEMPLATE (hdlr, n,MSR_KERNEL ,NOCOPY , transfer_to_handler_full, \ ret_from_except_full) +#ifdef CONFIG_IPIPE +#define EXC_XFER_IPIPE (n, hdlr) \ + EXC_XFER_TEMPLATE(hdlr, n+1, MSR_KERNEL, NOCOPY, transfer_to_handler, \ + __ipipe_ret_from_except) +#endif /* CONFIG_IPIPE */ +#define EXC_XFER_LITE (n, hdlr) \ EXC_XFER_TEMPLATE(hdlr, n+1, MSR_KERNEL, NOCOPY, transfer_to_handler, \ ret_from_except)
@@ -345,6 +351,15 @@addi r3,r1,STACK_FRAME_OVERHEAD ; \ EXC_XFER_STD(0x0700, program_check_exception) +#ifdef CONFIG_IPIPE +#define DECREMENTER_EXCEPTION \ + START_EXCEPTION(Decrementer) \ + NORMAL_EXCEPTION_PROLOG; \ + lis r0,TSR_DIS@h;/* Setup the DEC interrupt mask */ \ +mtspr SPRN_TSR ,r0;/* Clear the DEC interrupt */ \ +addi r3,r1,STACK_FRAME_OVERHEAD ; \ + EXC_XFER_IPIPE(0x0900, __ipipe_grab_timer) +#else /* !CONFIG_IPIPE */ #define DECREMENTER_EXCEPTION \ START_EXCEPTION(Decrementer) \ NORMAL_EXCEPTION_PROLOG; \
@@ -352,6 +367,7 @@mtspr SPRN_TSR ,r0;/* Clear the DEC interrupt */ \addi r3,r1,STACK_FRAME_OVERHEAD ; \ EXC_XFER_LITE(0x0900, timer_interrupt) +#endif /* CONFIG_IPIPE */ #define FP_UNAVAILABLE_EXCEPTION \ START_EXCEPTION(FloatingPointUnavailable) \
arch/powerpc/kernel/head_fsl_booke.S +5 -1
@@ -526,8 +526,12 @@ INSTRUCTION_STORAGE_EXCEPTION /* External Input Interrupt */ +#ifdef CONFIG_IPIPE + EXCEPTION(0x0500, ExternalInput, __ipipe_grab_irq, EXC_XFER_IPIPE) +#else /* !CONFIG_IPIPE */ EXCEPTION(0x0500, ExternalInput, do_IRQ, EXC_XFER_LITE) - +#endif /* CONFIG_IPIPE */ + /* Alignment Interrupt */ ALIGNMENT_EXCEPTION
arch/powerpc/kernel/idle.c +9 -0
@@ -51,6 +51,7 @@while (1 ) {while (!need_resched () && !cpu_should_die ()) {ppc64_runlatch_off (); +ipipe_suspend_domain ();if (ppc_md.power_save) {clear_thread_flag (TIF_POLLING_NRFLAG );
@@ -59,13 +60,21 @@* is ordered w.r.t. need_resched() test. */ smp_mb (); +#ifdef CONFIG_IPIPE +local_irq_disable_hw (); +#else /* !CONFIG_IPIPE */ local_irq_disable (); +#endif /* CONFIG_IPIPE */ /* check again after disabling irqs */ if (!need_resched () && !cpu_should_die ()) ppc_md.power_save (); +#ifdef CONFIG_IPIPE +local_irq_enable_hw (); +#else /* !CONFIG_IPIPE */ local_irq_enable (); +#endif /* CONFIG_IPIPE */ set_thread_flag (TIF_POLLING_NRFLAG ); }else {
arch/powerpc/kernel/ipipe-core.c +264 -0
264 lines not on this page · raw message
arch/powerpc/kernel/ipipe-mcount.S +76 -0
76 lines not on this page · raw message
arch/powerpc/kernel/ipipe-root.c +491 -0
491 lines not on this page · raw message
arch/powerpc/kernel/irq.c +4 -0
@@ -69,7 +69,11 @@#endif int __irq_offset_value; +#ifdef CONFIG_IPIPE +int ppc_spurious_interrupts; +#else /* !CONFIG_IPIPE */ static int ppc_spurious_interrupts; +#endif /* CONFIG_IPIPE */ #ifdef CONFIG_PPC32 EXPORT_SYMBOL (__irq_offset_value);
arch/powerpc/kernel/Makefile +2 -0
@@ -57,6 +57,8 @@ obj-$(CONFIG_MODULES) += ppc_ksyms.o obj-$(CONFIG_BOOTX_TEXT) += btext.o obj-$(CONFIG_SMP) += smp.o +obj-$(CONFIG_IPIPE) += ipipe-core.o ipipe-root.o +obj-$(CONFIG_IPIPE_TRACE_MCOUNT) += ipipe-mcount.o obj-$(CONFIG_KPROBES) += kprobes.o obj-$(CONFIG_PPC_UDBG_16550) += legacy_serial.o udbg_16550.o module-$(CONFIG_PPC64) += module_64.o
arch/powerpc/kernel/setup_32.c +1 -1
@@ -88,7 +88,7 @@* from the address that it was linked at, so we must use RELOC/PTRRELOC * to access static data (including strings). -- paulus */ -unsigned long __init early_init (unsigned long dt_ptr) +notrace unsigned long __init early_init (unsigned long dt_ptr) {unsigned long offset =reloc_offset ();struct cpu_spec *spec;
arch/powerpc/kernel/time.c +13 -2
@@ -296,7 +296,11 @@#else /* ! CONFIG_VIRT_CPU_ACCOUNTING */ #define calc_cputime_factors () +#ifdef CONFIG_IPIPE +#define account_process_time (regs) update_process_times(user_mode(__ipipe_tick_regs + smp_processor_id())) +#else #define account_process_time (regs) update_process_times(user_mode(regs)) +#endif /* CONFIG_IPIPE */ #define calculate_steal_time () do { } while (0)#endif
@@ -669,10 +673,17 @@ }write_sequnlock (&xtime_lock); } - + +#ifdef CONFIG_IPIPE +if (__ipipe_decr_ticks == tb_ticks_per_jiffy) { + next_dec = tb_ticks_per_jiffy - ticks; +set_dec (next_dec); + } +#else /* !CONFIG_IPIPE */ next_dec = tb_ticks_per_jiffy - ticks;set_dec (next_dec); - +#endif /* CONFIG_IPIPE */ +#ifdef CONFIG_PPC_ISERIES if (hvlpevent_is_pending ())process_hvlpevents ();
arch/powerpc/kernel/traps.c +38 -2
@@ -324,6 +324,9 @@int recover =0 ;unsigned long reason =get_mc_reason (regs); +if (ipipe_trap_notify (IPIPE_TRAP_MCE ,regs)) +return ; +/* See if any machine dependent calls */ if (ppc_md.machine_check_exception) recover = ppc_md.machine_check_exception (regs);
@@ -490,6 +493,10 @@void unknown_exception (struct pt_regs *regs) { +if (ipipe_trap_notify (IPIPE_TRAP_IABR ,regs)) +return ; +if (ipipe_trap_notify (IPIPE_TRAP_UNKNOWN ,regs)) +return ;printk ("Bad trap at PC: %lx, SR: %lx, vector=%lx\n" , regs->nip, regs->msr, regs->trap);
@@ -508,13 +515,17 @@void RunModeException (struct pt_regs *regs) { +if (ipipe_trap_notify (IPIPE_TRAP_RM ,regs)) +return ;_exception (SIGTRAP , regs,0 ,0 ); }void __kprobes single_step_exception (struct pt_regs *regs) { regs->msr &= ~(MSR_SE |MSR_BE );/* Turn off 'trace' bits */ - +if (ipipe_trap_notify (IPIPE_TRAP_SSTEP ,regs)) +return ; +if (notify_die (DIE_SSTEP ,"single_step" , regs,5 ,5 ,SIGTRAP ) ==NOTIFY_STOP )return ;
@@ -534,7 +545,9 @@ {if (single_stepping (regs)) {clear_single_step (regs); -_exception (SIGTRAP , regs,TRAP_TRACE ,0 ); +if (ipipe_trap_notify (IPIPE_TRAP_SSTEP ,regs)) +return ; +_exception (SIGTRAP , regs,TRAP_TRACE ,0 ); } }
@@ -786,6 +799,9 @@unsigned int reason =get_reason (regs);extern int do_mathemu (struct pt_regs *regs); +if (ipipe_trap_notify (IPIPE_TRAP_PCE ,regs)) +return ; +#ifdef CONFIG_MATH_EMULATION /* (reason & REASON_ILLEGAL) would be the obvious thing here, * but there seems to be a hardware bug on the 405GP (RevD)
@@ -855,6 +871,9 @@return ; } +if (ipipe_trap_notify (IPIPE_TRAP_ALIGNMENT ,regs)) +return ; +/* Operand address was bad */ if (fixed == -EFAULT ) { sig =SIGSEGV ;
@@ -880,6 +899,8 @@void nonrecoverable_exception (struct pt_regs *regs) { +if (ipipe_trap_notify (IPIPE_TRAP_NREC ,regs)) +return ;printk (KERN_ERR "Non-recoverable exception at PC=%lx MSR=%lx\n" , regs->nip, regs->msr);debugger (regs);
@@ -902,6 +923,9 @@void altivec_unavailable_exception (struct pt_regs *regs) { +if (ipipe_trap_notify (IPIPE_TRAP_ALTUNAVAIL ,regs)) +return ; +if (user_mode (regs)) {/* A user program has executed an altivec instruction, but this kernel doesn't support altivec. */
@@ -926,6 +950,9 @@extern int Soft_emulate_8xx (struct pt_regs *);int errcode; +if (ipipe_trap_notify (IPIPE_TRAP_SOFTEMU ,regs)) +return ; +CHECK_FULL_REGS (regs);if (!user_mode (regs)) {
@@ -954,6 +981,9 @@void DebugException (struct pt_regs *regs,unsigned long debug_status) { +if (ipipe_trap_notify (IPIPE_TRAP_DEBUG ,regs)) +return ; +if (debug_status &DBSR_IC ) {/* instruction completion */ regs->msr &= ~MSR_DE ;if (user_mode (regs)) {
@@ -984,6 +1014,9 @@ {int err; +if (ipipe_trap_notify (IPIPE_TRAP_ALTASSIST ,regs)) +return ; +if (!user_mode (regs)) {printk (KERN_EMERG "VMX/Altivec assist exception in kernel mode" " at %lx\n" , regs->nip);
@@ -1034,6 +1067,9 @@int fpexc_mode;int code =0 ; +if (ipipe_trap_notify (IPIPE_TRAP_SPE ,regs)) +return ; + spefscr = current->thread.spefscr; fpexc_mode = current->thread.fpexc_mode;
arch/powerpc/mm/fault.c +3 -0
@@ -175,6 +175,9 @@ is_write = error_code &ESR_DST ;#endif /* CONFIG_4xx || CONFIG_BOOKE */ +if (ipipe_trap_notify (IPIPE_TRAP_ACCESS ,regs)) +return 0 ; +if (notify_page_fault (DIE_PAGE_FAULT ,"page_fault" , regs, error_code,11 ,SIGSEGV ) ==NOTIFY_STOP )return 0 ;
arch/powerpc/sysdev/ipic.c +12 -0
@@ -4,6 +4,7 @@* IPIC routines implementations. * * Copyright 2005 Freescale Semiconductor, Inc. +* Copyright (C) 2007 Benjamin Zores, Alain Grimmer (Adeos/powerpc 2.6 port). * * 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
@@ -500,6 +501,14 @@return 0 ; } +#ifdef CONFIG_IPIPE +static void ipic_end_irq (unsigned int irq) +{ +if (!(irq_desc[irq].status & (IRQ_DISABLED |IRQ_INPROGRESS ))) +ipic_unmask_irq (irq); +} +#endif /* CONFIG_IPIPE */ +static struct irq_chip ipic_irq_chip = { .typename =" IPIC " , .unmask = ipic_unmask_irq,
@@ -507,6 +516,9 @@ .mask_ack = ipic_mask_irq_and_ack, .ack = ipic_ack_irq, .set_type = ipic_set_irq_type, +#ifdef CONFIG_IPIPE + .end = ipic_end_irq, +#endif /* CONFIG_IPIPE */ };static int ipic_host_match (struct irq_host *h,struct device_node *node)
include/asm-powerpc/hw_irq.h +162 -0
174 lines not on this page · raw message
include/asm-powerpc/ipipe.h +216 -0
216 lines not on this page · raw message
include/asm-powerpc/irq.h +2 -0
@@ -11,7 +11,9 @@#include <linux/threads.h> #include <linux/list.h> +#ifdef CONFIG_PPC_MERGE #include <linux/radix-tree.h> +#endif #include <asm/types.h> #include <asm/atomic.h>
include/asm-ppc/pgalloc.h +5 -0
@@ -39,5 +39,10 @@#define check_pgt_cache () do { } while (0) +static inline void set_pgdir (unsigned long address,pgd_t entry) +{ +/* nop */ +} +#endif /* _PPC_PGALLOC_H */ #endif /* __KERNEL__ */
include/linux/hardirq.h +13 -0
@@ -128,7 +128,20 @@*/ extern void irq_exit (void ); +#ifdef CONFIG_IPIPE +#define nmi_enter () \ +do { \ + if (ipipe_current_domain == ipipe_root_domain) \ + { lockdep_off(); irq_enter(); } \ +} while(0) +#define nmi_exit () \ +do { \ + if (ipipe_current_domain == ipipe_root_domain) \ + { __irq_exit(); lockdep_on(); } \ +} while(0) +#else /* !CONFIG_IPIPE */ #define nmi_enter () do { lockdep_off(); irq_enter(); } while (0)#define nmi_exit () do { __irq_exit(); lockdep_on(); } while (0) +#endif /* CONFIG_IPIPE */ #endif /* LINUX_HARDIRQ_H */
include/linux/ipipe.h +769 -0
769 lines not on this page · raw message
include/linux/ipipe_trace.h +40 -0
@@ -0,0 +1,40 @@ +/* -*- linux-c -*- +* include/linux/ipipe_trace.h +* +* Copyright (C) 2005 Luotao Fu. +* 2005, 2006 Jan Kiszka. +* +* 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, Inc., 675 Mass Ave, Cambridge MA 02139, +* USA; either version 2 of the License, or (at your option) any later +* version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#ifndef _LINUX_IPIPE_TRACE_H +#define _LINUX_IPIPE_TRACE_H + +#include <linux/types.h> + +void ipipe_trace_begin (unsigned long v); +void ipipe_trace_end (unsigned long v); +void ipipe_trace_freeze (unsigned long v); +void ipipe_trace_special (unsigned char special_id,unsigned long v); +void ipipe_trace_pid (pid_t pid,short prio); + +int ipipe_trace_max_reset (void ); +int ipipe_trace_frozen_reset (void ); + +void ipipe_trace_panic_freeze (void ); +void ipipe_trace_panic_dump (void ); + +#endif /* !__LINUX_IPIPE_H */
include/linux/linkage.h +4 -0
@@ -64,4 +64,8 @@#define fastcall#endif +#ifndef notrace +#define notrace __attribute__((no_instrument_function)) +#endif +#endif
include/linux/preempt.h +21 -6
@@ -26,22 +26,37 @@ asmlinkage void preempt_schedule(void); +#ifdef CONFIG_IPIPE +#include <asm/ipipe.h> +DECLARE_PER_CPU(struct ipipe_domain *, ipipe_percpu_domain); +extern struct ipipe_domain ipipe_root; +#define ipipe_preempt_guard () (per_cpu(ipipe_percpu_domain, ipipe_processor_id()) == &ipipe_root) +#else /* !CONFIG_IPIPE */ +#define ipipe_preempt_guard () 1 +#endif /* CONFIG_IPIPE */ +#define preempt_disable () \ do { \ - inc_preempt_count(); \ - barrier(); \ + if (ipipe_preempt_guard()) { \ + inc_preempt_count(); \ + barrier(); \ + } \ } while (0)#define preempt_enable_no_resched () \ do { \ - barrier(); \ - dec_preempt_count(); \ + if (ipipe_preempt_guard()) { \ + barrier(); \ + dec_preempt_count(); \ + } \ } while (0)#define preempt_check_resched () \ do { \ - if (unlikely(test_thread_flag(TIF_NEED_RESCHED))) \ - preempt_schedule(); \ + if (ipipe_preempt_guard()) { \ + if (unlikely(test_thread_flag(TIF_NEED_RESCHED))) \ + preempt_schedule(); \ + } \ } while (0)#define preempt_enable () \
include/linux/radix-tree.h +2 -0
@@ -19,7 +19,9 @@#ifndef _LINUX_RADIX_TREE_H#define _LINUX_RADIX_TREE_H +#ifndef CONFIG_PPC_MERGE #include <linux/sched.h> +#endif /* CONFIG_PPC_MERGE */ #include <linux/preempt.h> #include <linux/types.h>
include/linux/sched.h +17 -0
@@ -43,6 +43,7 @@#include <asm/param.h> /* for HZ */ +#include <linux/ipipe.h> #include <linux/capability.h> #include <linux/threads.h> #include <linux/kernel.h>
@@ -150,6 +151,14 @@/* in tsk->state again */ #define TASK_NONINTERACTIVE 64#define TASK_DEAD 128 +#ifdef CONFIG_IPIPE +#define TASK_ATOMICSWITCH 512 +#define TASK_NOWAKEUP 1024 +#else /* !CONFIG_IPIPE */ +#define TASK_ATOMICSWITCH 0 +#define TASK_NOWAKEUP 0 +#endif /* CONFIG_IPIPE */ +#define __set_task_state (tsk, state_value) \ do { (tsk)->state = (state_value); } while (0)
@@ -1023,6 +1032,9 @@#ifdef CONFIG_TASK_DELAY_ACCT struct task_delay_info *delays;#endif +#ifdef CONFIG_IPIPE +void *ptd[IPIPE_ROOT_NPTDKEYS ]; +#endif };static inline pid_t process_group (struct task_struct *tsk)
@@ -1115,6 +1127,11 @@#define PF_SPREAD_SLAB 0x02000000/* Spread some slab caches over cpuset */ #define PF_MEMPOLICY 0x10000000/* Non-default NUMA mempolicy */ #define PF_MUTEX_TESTER 0x20000000/* Thread belongs to the rt mutex tester */ +#ifdef CONFIG_IPIPE +#define PF_EVNOTIFY 0x40000000/* Notify other domains about internal events */ +#else +#define PF_EVNOTIFY 0 +#endif /* CONFIG_IPIPE */ /* * Only the _current_ task can read/write to tsk->flags, but other
init/Kconfig +2 -0
@@ -67,6 +67,7 @@ config LOCALVERSION string "Local version - append to kernel release" + default "-ipipe" help Append an extra string to the end of your kernel version. This will show up when you type uname, for example.
@@ -543,3 +544,4 @@ menu "Block layer" source "block/Kconfig" endmenu +
init/main.c +6 -0
@@ -535,6 +535,11 @@softirq_init ();timekeeping_init ();time_init (); +/* +* We need to wait for the interrupt and time subsystems to be +* initialized before enabling the pipeline. +*/ +ipipe_init ();profile_init ();if (!irqs_disabled ())printk ("start_kernel(): bug: interrupts were enabled early\n" );
@@ -683,6 +688,7 @@#ifdef CONFIG_SYSCTL sysctl_init ();#endif +ipipe_init_proc ();do_initcalls (); }
kernel/exit.c +1 -0
@@ -914,6 +914,7 @@taskstats_exit_send (tsk, tidstats, group_dead, mycpu);taskstats_exit_free (tidstats); +ipipe_exit_notify (tsk);exit_mm (tsk);if (group_dead)
kernel/fork.c +11 -1
@@ -384,6 +384,7 @@might_sleep ();if (atomic_dec_and_test (&mm->mm_users)) { +ipipe_cleanup_notify (mm);exit_aio (mm);exit_mmap (mm);if (!list_empty (&mm->mmlist)) {
@@ -914,7 +915,7 @@ {unsigned long new_flags = p->flags; - new_flags &= ~(PF_SUPERPRIV |PF_NOFREEZE ); + new_flags &= ~(PF_SUPERPRIV |PF_NOFREEZE |PF_EVNOTIFY ); new_flags |=PF_FORKNOEXEC ;if (!(clone_flags &CLONE_PTRACE )) p->ptrace =0 ;
@@ -1258,6 +1259,15 @@spin_unlock (¤t->sighand->siglock);write_unlock_irq (&tasklist_lock);proc_fork_connector (p); +#ifdef CONFIG_IPIPE + { +int k; + +for (k =0 ; k <IPIPE_ROOT_NPTDKEYS ; k++) + p->ptd[k] =NULL ; + } +#endif /* CONFIG_IPIPE */ +return p; bad_fork_cleanup_namespaces:
kernel/ipipe/core.c +1049 -0
202 lines not on this page · raw message
kernel/ipipe/generic.c +424 -0
424 lines not on this page · raw message
kernel/ipipe/Kconfig.debug +69 -0
69 lines not on this page · raw message
kernel/ipipe/tracer.c +1245 -0
1,245 lines not on this page · raw message
kernel/printk.c +73 -0
73 lines not on this page · raw message
kernel/sched.c +69 -3
72 lines not on this page · raw message
The rest of this diff is not shown. View the raw message.
Part of the diff is not shown here. View the raw message.
Quoted 19 lines · Benjamin Zores
Hello,
A few time ago, I've sent a first draft of a patch that aimed at porting Adeos Ipipe from PPC to PowerPC kernel architecture.
While being ported, the patch had problems running on due to some incompabilities with the IRQ handling.I recently reworked on it and have it fixed.
Please see attached patch that adds PowerPC support on Linux 2.6.19(.2) kernel. It is based on current ppc patch (v1.5) for 2.6.19.For the record, the previous draft was in fact blocking as soon as an h/w IRQ comes in. Adeos was unable to acknowledge the interruption and so, it was triggered thousands of times a second, hanging on the board.
Judging by
arch/powerpc/sysdev/ipic.c, I've replaced allack()calls inipipe-root.cby amask_ack()call and added anend()implementation, that basicallyunmask()the IRQ after being treated.
Quoted 5 lines
This may not be the best way to solve the issue but at least it works for now, allowing more dev to be done on PowerPC platform. The best way would probably to adapt the ipipe-root to a new Adeos version (like x86 arch does, defining multiple acknowledging functions, whether the IRQ is level or edge based, but it's out of my scope right now).
FWIW, I've almost finished an I-pipe port over 2.6.21 also using the arch/powerpc tree. It relies on the genirq layer which makes things way more comfortable, and which does not require to redefine particular ack routines but rather keep the original irqchip handlers.
Quoted 7 lines
If the patch is accepted (and I hope it will), I may extend it later on (for more recent kernels like 2.6.21) or upgrading to a newest Adeos version (but each version being pretty undocumented in terms of ChangeLog, it's pretty hard to do) if you can provide me advices, unless somebody else beats me on that.
This should get better when the I-pipe/powerpc development is merged into the main git repo here, which should happen in a reasonable future:
http://www.denx.de/cgi-bin/gitweb.cgi?p=ipipe-2.6.git;a=summary
Quoted 2 lines
PS: if applied, please keep the README.adeos file unchanged as it was mandatory for me to have the patch pushed upstream ;-)
Note: you are mixing my [and Karim's words] from the orginal Abstract with your words from the new Disclaimer, making the "we" clauses rather confusing. It should be more of a README.alcatel-lucent file than a README.adeos one.
Quoted 3 lines
Thanks for reviewal,
I had a look at this patch, and I see two issues, one of which can't be solved easily unless you make your code use the genirq layer (see x86-1.7 series and beyond), the other one is simple to fix.
Calling mask_ack in __ipipe_ack works for edge/level IRQs, but would not be applicable to transparent controllers only requiring the software to send eoi, or per-cpu IRQ flows involving mask+eoi for instance. Basically, this code works because it assumes that all IRQs are somehow managed in level mode thus preventing the interrupt flood, but this may not be always the case. Working with the vanilla genirq layer solves this.
The other issue is an old bug of mine for this port, specifically we need to call irq_enter()/irq_exit() for virtual interrupts too; otherwise, softirqs triggered by virtual ones might be delayed until the next hw interrupt comes in. Something like this would do:
include/asm/ipipe.h renamed from include/asm/ipipe.h~ +8 -2
@@ -198,8 +198,14 @@ do { \ local_irq_enable_nohead(ipd); \ if (ipd == ipipe_root_domain) { \ - ((void (*)(unsigned, struct pt_regs *)) \ - ipd->irqs[irq].handler) (irq, __ipipe_tick_regs + cpuid); \ + if (likely(!ipipe_virtual_irq_p(irq))) \ + ((void (*)(unsigned, struct pt_regs *)) \ + ipd->irqs[irq].handler) (irq, __ipipe_tick_regs + cpuid); \ + else { \ + irq_enter(); \ + ipd->irqs[irq].handler(irq, ipd->irqs[irq].cookie);\ + irq_exit(); \ + } \ } else { \ __clear_bit(IPIPE_SYNC_FLAG, &cpudata->status); \ ipd->irqs[irq].handler(irq,ipd->irqs[irq].cookie); \
In the same move, you would also need to prevent irq_enter() to be called twice for the decrementer trap which is bound to a virtual interrupt in our case (otherwise, this would wreck the tasklets triggering, and cause RCU to misbehave for instance):
arch/powerpc/kernel/time.c renamed from arch/powerpc/kernel/time.c~ +4 -0
@@ -625,7 +625,9 @@#endif old_regs =set_irq_regs (regs); +#ifndef CONFIG_IPIPE irq_enter (); +#endif profile_tick (CPU_PROFILING );calculate_steal_time ();
@@ -686,7 +688,9 @@ }#endif +#ifndef CONFIG_IPIPE irq_exit (); +#endif set_irq_regs (old_regs); }
Signature · 1 line
Philippe.
Quoted 5 lines · Philippe Gerum
FWIW, I've almost finished an I-pipe port over 2.6.21 also using the
arch/powerpctree. It relies on the genirq layer which makes things way more comfortable, and which does not require to redefine particular ack routines but rather keep the original irqchip handlers.
That's pretty cool !
Well, using the genirq layer is definitely the way to go but, as stated, my patch was a port based adeos-1.5 which was kinda old.
Quoted 4 lines
This should get better when the I-pipe/powerpc development is merged into the main git repo here, which should happen in a reasonable future:
http://www.denx.de/cgi-bin/gitweb.cgi?p=ipipe-2.6.git;a=summary
Well, I'm waiting for that too.
Most of embedded devels still relies on ppc arch instead of powerpc and I hope this situation will change soon.
Quoted 5 lines
Note: you are mixing my [and Karim's words] from the orginal Abstract with your words from the new Disclaimer, making the "we" clauses rather confusing. It should be more of a README.alcatel-lucent file than a README.adeos one.
I can do so.
Quoted 4 lines
I had a look at this patch, and I see two issues, one of which can't be solved easily unless you make your code use the genirq layer (see x86-1.7 series and beyond), the other one is simple to fix.
I know.
That's why I said my patch is working but the implementation isn't as nice as I'd like it to be.
Quoted 8 lines
Calling
mask_ackin__ipipe_ackworks for edge/level IRQs, but would not be applicable to transparent controllers only requiring the software to send eoi, or per-cpu IRQ flows involving mask+eoi for instance. Basically, this code works because it assumes that all IRQs are somehow managed in level mode thus preventing the interrupt flood, but this may not be always the case. Working with the vanilla genirq layer solves this.
I however won't have more time allowed
to update the patch to use genirq layer.
Quoted 6 lines
The other issue is an old bug of mine for this port, specifically we need to call irq_enter()/irq_exit() for virtual interrupts too; otherwise, softirqs triggered by virtual ones might be delayed until the next hw interrupt comes in. Something like this would do:
[...]
Is this patch tested ?
It seems not to work, segfaulting kernel.
[...]
I-pipe 1.5-01: pipeline enabled.
Unable to handle kernel paging request for data at address 0x00000084 Faulting instruction address: 0xc001c874 Oops: Kernel access of bad area, sig: 11 [#1]
[...]
I can update the patch but I won't be able to switch to genirq layer. So it's up to you to decide whether this patch gets commited or just lay down on mailing lists archives.
Hoping to see your 2.6.21 patch soon ;-)
Ben
A message that is not in the archive (sent off-list or not yet received): [email protected]
Quoted 43 lines · Benjamin Zores
Quoted 5 lines · Philippe Gerum
FWIW, I've almost finished an I-pipe port over 2.6.21 also using the
arch/powerpctree. It relies on the genirq layer which makes things way more comfortable, and which does not require to redefine particular ack routines but rather keep the original irqchip handlers.That's pretty cool !
Well, using the genirq layer is definitely the way to go but, as stated, my patch was a port based adeos-1.5 which was kinda old.Quoted 4 lines
This should get better when the I-pipe/powerpc development is merged into the main git repo here, which should happen in a reasonable future:
http://www.denx.de/cgi-bin/gitweb.cgi?p=ipipe-2.6.git;a=summaryWell, I'm waiting for that too.
Most of embedded devels still relies on ppc arch instead of powerpc and I hope this situation will change soon.Quoted 5 lines
Note: you are mixing my [and Karim's words] from the orginal Abstract with your words from the new Disclaimer, making the "we" clauses rather confusing. It should be more of a README.alcatel-lucent file than a README.adeos one.
I can do so.
Quoted 4 lines
I had a look at this patch, and I see two issues, one of which can't be solved easily unless you make your code use the genirq layer (see x86-1.7 series and beyond), the other one is simple to fix.
I know.
That's why I said my patch is working but the implementation isn't as nice as I'd like it to be.Quoted 8 lines
Calling
mask_ackin__ipipe_ackworks for edge/level IRQs, but would not be applicable to transparent controllers only requiring the software to send eoi, or per-cpu IRQ flows involving mask+eoi for instance. Basically, this code works because it assumes that all IRQs are somehow managed in level mode thus preventing the interrupt flood, but this may not be always the case. Working with the vanilla genirq layer solves this.I however won't have more time allowed
to update the patch to use genirq layer.
Quoted 7 lines
Quoted 6 lines
The other issue is an old bug of mine for this port, specifically we need to call irq_enter()/irq_exit() for virtual interrupts too; otherwise, softirqs triggered by virtual ones might be delayed until the next hw interrupt comes in. Something like this would do:
[...]Is this patch tested ?
Yes, in my patchset though. Your IRQ handler may still require a valid cookie value, typically a pointer to some register frame (__ipipe_tick_regs + cpuid); you could try to replace the NULL value passed to virq handlers from my patch by the same value passed to root domain handlers.
Quoted 8 lines
It seems not to work, segfaulting kernel.
[...]
I-pipe 1.5-01: pipeline enabled.Unable to handle kernel paging request for data at address 0x00000084Faulting instruction address:
0xc001c874
If the suggestion above does not work, I guess that objdump on the kernel image is your friend then, at least to locate the offending routine.
Oops: Kernel access of bad area, sig: 11 [#1]
Quoted 10 lines
[...]
I can update the patch but I won't be able to switch to genirq layer. So it's up to you to decide whether this patch gets commited or just lay down on mailing lists archives.
Hoping to see your 2.6.21 patch soon ;-)
Ben
Signature · 1 line
Philippe.
Quoted 6 lines · Philippe Gerum
FWIW, I've almost finished an I-pipe port over 2.6.21 also using the
arch/powerpctree. It relies on the genirq layer which makes things way more comfortable, and which does not require to redefine particular ack routines but rather keep the original irqchip handlers.
Hello Philippe,
Do you have any news about the 2.6.21 port ?
Is there something that can be tested ?
Quoted 5 lines
This should get better when the I-pipe/powerpc development is merged into the main git repo here, which should happen in a reasonable future:
http://www.denx.de/cgi-bin/gitweb.cgi?p=ipipe-2.6.git;a=summary
There's not much about PowerPC arch changes right there. Is the development stuck ? :-(
Thanks for any news.
Ben
Quoted 16 lines · Benjamin ZORES
Quoted 6 lines · Philippe Gerum
FWIW, I've almost finished an I-pipe port over 2.6.21 also using the
arch/powerpctree. It relies on the genirq layer which makes things way more comfortable, and which does not require to redefine particular ack routines but rather keep the original irqchip handlers.Hello Philippe,
Do you have any news about the 2.6.21 port ?
Is there something that can be tested ?Quoted 5 lines
This should get better when the I-pipe/powerpc development is merged into the main git repo here, which should happen in a reasonable future:
http://www.denx.de/cgi-bin/gitweb.cgi?p=ipipe-2.6.git;a=summary
Quoted 4 lines
There's not much about PowerPC arch changes right there. Is the development stuck ? :-(
Thanks for any news.
Highest priority goes to closing the merge window before 2.4-rc1 which mostly consists of integrating all generic core changes, and we are already late on this.
2.6.21/powerpc will be there for 2.4 final; but since we do have a decent 2.6.19/ppc support available already, the former will have to wait because it is not on the critical path - AFAIC, that is.
Signature · 1 line
Philippe.