Module: xenomai-2.6 Branch: master Commit: 85b5eee23ab41a1a420d3efd056c91fbf999a4ca URL: http://git.xenomai.org/?p=xenomai-2.6.git;a=commit;h=85b5eee23ab41a1a420d3efd056c91fbf999a4ca
Author: Gilles Chanteperdrix <gilles.chanteperd...@xenomai.org> Date: Tue May 1 16:58:19 2012 +0200 arm: upgrade I-pipe support to 3.0.13-arm-1.18-08 --- ....patch => adeos-ipipe-3.0.13-arm-1.18-08.patch} | 392 ++++++++++++-------- 1 files changed, 234 insertions(+), 158 deletions(-) diff --git a/ksrc/arch/arm/patches/adeos-ipipe-3.0.13-arm-1.18-06.patch b/ksrc/arch/arm/patches/adeos-ipipe-3.0.13-arm-1.18-08.patch similarity index 98% rename from ksrc/arch/arm/patches/adeos-ipipe-3.0.13-arm-1.18-06.patch rename to ksrc/arch/arm/patches/adeos-ipipe-3.0.13-arm-1.18-08.patch index d460e5e..361079d 100644 --- a/ksrc/arch/arm/patches/adeos-ipipe-3.0.13-arm-1.18-06.patch +++ b/ksrc/arch/arm/patches/adeos-ipipe-3.0.13-arm-1.18-08.patch @@ -995,10 +995,10 @@ index 4384d81..f4efd23 100644 void sp804_clockevents_init(void __iomem *, unsigned int, const char *); diff --git a/arch/arm/include/asm/ipipe.h b/arch/arm/include/asm/ipipe.h new file mode 100644 -index 0000000..6a91c49 +index 0000000..6e12980 --- /dev/null +++ b/arch/arm/include/asm/ipipe.h -@@ -0,0 +1,340 @@ +@@ -0,0 +1,341 @@ +/* -*- linux-c -*- + * arch/arm/include/asm/ipipe.h + * @@ -1031,10 +1031,10 @@ index 0000000..6a91c49 +#include <linux/ipipe_percpu.h> +#include <linux/ipipe_trace.h> + -+#define IPIPE_ARCH_STRING "1.18-06" ++#define IPIPE_ARCH_STRING "1.18-08" +#define IPIPE_MAJOR_NUMBER 1 +#define IPIPE_MINOR_NUMBER 18 -+#define IPIPE_PATCH_NUMBER 6 ++#define IPIPE_PATCH_NUMBER 8 + +#ifdef CONFIG_SMP +#define ipipe_processor_id() hard_smp_processor_id() @@ -1286,14 +1286,15 @@ index 0000000..6a91c49 + +void __ipipe_exit_irq(struct pt_regs *regs); + -+void __ipipe_handle_irq(int irq, struct pt_regs *regs); ++#define IPIPE_IRQF_NOACK 0x1 ++#define IPIPE_IRQF_NOSYNC 0x2 ++ ++void __ipipe_handle_irq(int irq, int flags); + +static inline void ipipe_handle_chained_irq(unsigned int irq) +{ -+ struct pt_regs regs; /* dummy */ -+ + ipipe_trace_irq_entry(irq); -+ __ipipe_handle_irq(irq, ®s); ++ __ipipe_handle_irq(irq, IPIPE_IRQF_NOSYNC); + ipipe_trace_irq_exit(irq); +} + @@ -2279,7 +2280,7 @@ index 734b581..6579eec 100644 #endif diff --git a/arch/arm/include/asm/smp_twd.h b/arch/arm/include/asm/smp_twd.h -index fed9981..b49c8ac 100644 +index fed9981..f655b27 100644 --- a/arch/arm/include/asm/smp_twd.h +++ b/arch/arm/include/asm/smp_twd.h @@ -22,7 +22,61 @@ struct clock_event_device; @@ -2319,7 +2320,7 @@ index fed9981..b49c8ac 100644 +#define __ipipe_mach_relay_ipi(ipi, thiscpu) \ + ({ \ + (void)(thiscpu); \ -+ __ipipe_handle_irq(ipi, NULL); \ ++ __ipipe_handle_irq(ipi, IPIPE_IRQF_NOACK); \ + }) + +struct irq_desc; @@ -2963,10 +2964,10 @@ index 051166c..043ca62 100644 * have in theory up to 7 arguments to a function - r0 to r6. diff --git a/arch/arm/kernel/ipipe.c b/arch/arm/kernel/ipipe.c new file mode 100644 -index 0000000..92c0592 +index 0000000..6cb7401 --- /dev/null +++ b/arch/arm/kernel/ipipe.c -@@ -0,0 +1,675 @@ +@@ -0,0 +1,676 @@ +/* -*- linux-c -*- + * linux/arch/arm/kernel/ipipe.c + * @@ -3221,7 +3222,7 @@ index 0000000..92c0592 + return -EINVAL; +#endif + local_irq_save_hw(flags); -+ __ipipe_handle_irq(irq, NULL); ++ __ipipe_handle_irq(irq, IPIPE_IRQF_NOACK); + local_irq_restore_hw(flags); + + return 1; @@ -3429,7 +3430,7 @@ index 0000000..92c0592 + * interrupt protection log is maintained here for each domain. Hw + * interrupts are off on entry. + */ -+void __ipipe_handle_irq(int irq, struct pt_regs *regs) ++void __ipipe_handle_irq(int irq, int flags) +{ + struct ipipe_domain *this_domain, *next_domain; + struct list_head *head, *pos; @@ -3437,7 +3438,7 @@ index 0000000..92c0592 + int m_ack; + + /* Software-triggered IRQs do not need any ack. */ -+ m_ack = (regs == NULL); ++ m_ack = (flags & IPIPE_IRQF_NOACK) != 0; + +#ifdef CONFIG_IPIPE_DEBUG + if (unlikely(irq >= IPIPE_NR_IRQS) || @@ -3452,7 +3453,8 @@ index 0000000..92c0592 + else { + head = __ipipe_pipeline.next; + next_domain = list_entry(head, struct ipipe_domain, p_link); -+ if (likely(test_bit(IPIPE_WIRED_FLAG, &next_domain->irqs[irq].control))) { ++ if (!(flags & IPIPE_IRQF_NOSYNC) ++ && likely(test_bit(IPIPE_WIRED_FLAG, &next_domain->irqs[irq].control))) { + if (!m_ack && next_domain->irqs[irq].acknowledge) { + desc = ipipe_virtual_irq_p(irq) ? NULL : irq_to_desc(irq); + next_domain->irqs[irq].acknowledge(irq, desc); @@ -3571,7 +3573,7 @@ index 0000000..92c0592 + ipipe_trace_begin(regs->ARM_ORIG_r0); +#endif + -+ __ipipe_handle_irq(irq, regs); ++ __ipipe_handle_irq(irq, 0); + +#ifdef CONFIG_IPIPE_TRACE_IRQSOFF + ipipe_trace_end(regs->ARM_ORIG_r0); @@ -3786,7 +3788,7 @@ index 0000000..ba0765a +} diff --git a/arch/arm/kernel/ipipe_tsc_asm.S b/arch/arm/kernel/ipipe_tsc_asm.S new file mode 100644 -index 0000000..ae7ea7d +index 0000000..a9fb0bc --- /dev/null +++ b/arch/arm/kernel/ipipe_tsc_asm.S @@ -0,0 +1,205 @@ @@ -3929,7 +3931,7 @@ index 0000000..ae7ea7d + ldr r0, .LCfr16_cntr_addr +/* User-space entry-point: r0 is the hardware counter virtual address */ +1: myldrd r2, r3, r1, .LCfr16_last_tsc -+ ldr ip, [r0] ++ ldrh ip, [r0] +#ifndef CONFIG_CPU_BIG_ENDIAN +/* Little endian */ + ldr r1, .LCfr16_last_tsc @@ -3972,7 +3974,7 @@ index 0000000..ae7ea7d +#ifndef CONFIG_CPU_BIG_ENDIAN +/* Little endian */ +1: ldr r1, .LCdec16_last_tsc -+ ldr ip, [r0] ++ ldrh ip, [r0] + ldr r2, .LCdec16_last_cnt + subs ip, r2, ip + addcc ip, ip, #0x10000 @@ -3984,7 +3986,7 @@ index 0000000..ae7ea7d +#else /* Big endian */ +/* Little endian */ +1: ldr r1, .LCdec16_last_tsc + 4 -+ ldr ip, [r0] ++ ldrh ip, [r0] + ldr r2, .LCdec16_last_cnt + subs ip, r2, ip + addcc ip, ip, #0x10000 @@ -4074,7 +4076,7 @@ index 9726006..d016461 100644 return 0; } diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c -index e7f92a4..6cd477d 100644 +index e7f92a4..3b968bf 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c @@ -53,6 +53,25 @@ enum ipi_msg_type { @@ -4166,7 +4168,7 @@ index e7f92a4..6cd477d 100644 + __ipipe_do_vnmi(IPIPE_SERVICE_VNMI, NULL); + else if ((1 << svc) & IPI_IPIPE_ALL) { + virq = svc - IPI_IPIPE_CRITICAL + IPIPE_FIRST_IPI; -+ __ipipe_handle_irq(virq, NULL); ++ __ipipe_handle_irq(virq, IPIPE_IRQF_NOACK); + } else + __ipipe_mach_relay_ipi(svc, cpu); + @@ -4468,10 +4470,10 @@ index 2248467..46b0e3d 100644 config MTD_AT91_DATAFLASH_CARD diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile -index 9696623..9d28024 100644 +index 9696623..ad1c822 100644 --- a/arch/arm/mach-at91/Makefile +++ b/arch/arm/mach-at91/Makefile -@@ -91,3 +91,14 @@ obj-$(CONFIG_CPU_IDLE) += cpuidle.o +@@ -91,3 +91,15 @@ obj-$(CONFIG_CPU_IDLE) += cpuidle.o ifeq ($(CONFIG_PM_DEBUG),y) CFLAGS_pm.o += -DDEBUG endif @@ -4485,13 +4487,14 @@ index 9696623..9d28024 100644 +obj-$(CONFIG_ARCH_AT91SAM9RL) += at91_ipipe_time.o +obj-$(CONFIG_ARCH_AT91SAM9G20) += at91_ipipe_time.o +obj-$(CONFIG_ARCH_AT91X40) += at91_ipipe_time.o ++obj-$(CONFIG_ARCH_AT91SAM9G45) += at91_ipipe_time.o +endif diff --git a/arch/arm/mach-at91/at91_ipipe_time.c b/arch/arm/mach-at91/at91_ipipe_time.c new file mode 100644 -index 0000000..b0aa6a4 +index 0000000..2e97a28 --- /dev/null +++ b/arch/arm/mach-at91/at91_ipipe_time.c -@@ -0,0 +1,316 @@ +@@ -0,0 +1,325 @@ +/* + * linux/arch/arm/mach-at91/at91_ipipe_time.c + * @@ -4500,6 +4503,9 @@ index 0000000..b0aa6a4 + * Adaptation to AT91SAM926x: + * Copyright (C) 2007 Gregory CLEMENT, Adeneo + * ++ * Adaptation to AT91SAM9G45: ++ * Copyright (C) 2011 Gregory CLEMENT, Free Electrons ++ * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. @@ -4549,6 +4555,10 @@ index 0000000..b0aa6a4 +#define AT91_ID_TC0 AT91X40_ID_TC0 +#define AT91_ID_TC1 AT91X40_ID_TC1 +#define AT91_ID_TC2 AT91X40_ID_TC2 ++#elif defined(CONFIG_ARCH_AT91SAM9G45) ++#define AT91_ID_TC0 AT91SAM9G45_ID_TCB ++#define AT91_ID_TC1 AT91SAM9G45_ID_TCB ++#define AT91_ID_TC2 AT91SAM9G45_ID_TCB +#else +#error "AT91 processor unsupported by Adeos" +#endif @@ -4640,12 +4650,14 @@ index 0000000..b0aa6a4 + if (mode == CLOCK_EVT_MODE_PERIODIC) { + unsigned long v; + -+#ifndef CONFIG_ARCH_AT91SAM9263 -+ clk_enable(clk_get(NULL, "tc" -+ __stringify(CONFIG_IPIPE_AT91_TC) "_clk")); -+#else /* AT91SAM9263 */ ++#ifdef CONFIG_ARCH_AT91SAM9263 + clk_enable(clk_get(NULL, "tcb_clk")); -+#endif /* AT91SAM9263 */ ++#elif CONFIG_ARCH_AT91SAM9G45 ++ clk_enable(clk_get(NULL, "tcb0_clk")); ++#else /* AT91SAM9263 and AT91SAM9G45*/ ++ clk_enable(clk_get(NULL, "tc" ++ __stringify(CONFIG_IPIPE_AT91_TC) "_clk")); ++#endif + + /* No Sync. */ + at91_tc_write(AT91_TC_BCR, 0); @@ -4740,7 +4752,7 @@ index 0000000..b0aa6a4 + (void) at91_sys_read(AT91_ST_SR); /* Clear any pending interrupts */ +#elif defined(CONFIG_ARCH_AT91SAM9260) || defined(CONFIG_ARCH_AT91SAM9261) \ + || defined(CONFIG_ARCH_AT91SAM9263) || defined(CONFIG_ARCH_AT91SAM9RL) \ -+ || defined(CONFIG_ARCH_AT91SAM9G20) ++ || defined(CONFIG_ARCH_AT91SAM9G20) || defined(CONFIG_ARCH_AT91SAM9G45) + at91_sys_write(AT91_PIT_MR, 0); + + /* Clear any pending interrupts */ @@ -4797,7 +4809,7 @@ index 0000000..b0aa6a4 +struct sys_timer at91rm9200_timer = { +#elif defined(CONFIG_ARCH_AT91SAM9260) || defined(CONFIG_ARCH_AT91SAM9261) \ + || defined(CONFIG_ARCH_AT91SAM9263) || defined(CONFIG_ARCH_AT91SAM9RL) \ -+ || defined(CONFIG_ARCH_AT91SAM9G20) ++ || defined(CONFIG_ARCH_AT91SAM9G20) || defined(CONFIG_ARCH_AT91SAM9G45) +struct sys_timer at91sam926x_timer = { +#elif defined(CONFIG_ARCH_AT91X40) +struct sys_timer at91x40_timer = { @@ -5084,6 +5096,77 @@ index dc28477..2b9144b 100644 }; void __init at91sam9263_init_interrupts(unsigned int priority[NR_AIC_IRQS]) +diff --git a/arch/arm/mach-at91/at91sam9g45.c b/arch/arm/mach-at91/at91sam9g45.c +index 11e2141..208b26b 100644 +--- a/arch/arm/mach-at91/at91sam9g45.c ++++ b/arch/arm/mach-at91/at91sam9g45.c +@@ -296,6 +296,13 @@ static struct at91_gpio_bank at91sam9g45_gpio[] = { + .offset = AT91_PIOA, + .clock = &pioA_clk, + }, { ++#ifdef CONFIG_IPIPE ++ .virtual = AT91_VA_BASE_TCB0, ++ .pfn = __phys_to_pfn(AT91_BASE_TCB0), ++ .length = SZ_16K, ++ .type = MT_DEVICE, ++ }, { ++#endif /* CONFIG_IPIPE */ + .id = AT91SAM9G45_ID_PIOB, + .offset = AT91_PIOB, + .clock = &pioB_clk, +@@ -358,6 +365,7 @@ void __init at91sam9g45_initialize(unsigned long main_clock) + /* + * The default interrupt priority levels (0 = lowest, 7 = highest). + */ ++#ifndef CONFIG_IPIPE + static unsigned int at91sam9g45_default_irq_priority[NR_AIC_IRQS] __initdata = { + 7, /* Advanced Interrupt Controller (FIQ) */ + 7, /* System Peripherals */ +@@ -392,6 +400,44 @@ static unsigned int at91sam9g45_default_irq_priority[NR_AIC_IRQS] __initdata = { + 0, + 0, /* Advanced Interrupt Controller (IRQ0) */ + }; ++#else ++static unsigned int at91sam9g45_default_irq_priority[NR_AIC_IRQS] __initdata = { ++/* Give the highest priority to TC, since they are used as timer interrupt by ++ I-pipe. */ ++ 7, /* Advanced Interrupt Controller (FIQ) */ ++ 6, /* System Peripherals */ ++ 0, /* Parallel IO Controller A */ ++ 0, /* Parallel IO Controller B */ ++ 0, /* Parallel IO Controller C */ ++ 0, /* Parallel IO Controller D and E */ ++ 0, ++ 5, /* USART 0 */ ++ 5, /* USART 1 */ ++ 5, /* USART 2 */ ++ 5, /* USART 3 */ ++ 0, /* Multimedia Card Interface 0 */ ++ 6, /* Two-Wire Interface 0 */ ++ 6, /* Two-Wire Interface 1 */ ++ 5, /* Serial Peripheral Interface 0 */ ++ 5, /* Serial Peripheral Interface 1 */ ++ 4, /* Serial Synchronous Controller 0 */ ++ 4, /* Serial Synchronous Controller 1 */ ++ 7, /* Timer Counter 0, 1, 2, 3, 4 and 5 */ ++ 0, /* Pulse Width Modulation Controller */ ++ 0, /* Touch Screen Controller */ ++ 0, /* DMA Controller */ ++ 2, /* USB Host High Speed port */ ++ 3, /* LDC Controller */ ++ 5, /* AC97 Controller */ ++ 2, /* Ethernet */ ++ 0, /* Image Sensor Interface */ ++ 2, /* USB Device High speed port */ ++ 0, ++ 0, /* Multimedia Card Interface 1 */ ++ 0, ++ 0, /* Advanced Interrupt Controller (IRQ0) */ ++}; ++#endif + + void __init at91sam9g45_init_interrupts(unsigned int priority[NR_AIC_IRQS]) + { diff --git a/arch/arm/mach-at91/at91sam9rl.c b/arch/arm/mach-at91/at91sam9rl.c index 29dff18..11d868e 100644 --- a/arch/arm/mach-at91/at91sam9rl.c @@ -5340,10 +5423,10 @@ index 4615528..620b6c1 100644 gpiochip_add(&at91_gpio->chip); diff --git a/arch/arm/mach-at91/include/mach/hardware.h b/arch/arm/mach-at91/include/mach/hardware.h -index 1008b9f..9ec4b50 100644 +index 1008b9f..498a205 100644 --- a/arch/arm/mach-at91/include/mach/hardware.h +++ b/arch/arm/mach-at91/include/mach/hardware.h -@@ -69,6 +69,25 @@ +@@ -69,6 +69,27 @@ #define AT91_VA_BASE_SYS AT91_IO_P2V(AT91_BASE_SYS) #define AT91_VA_BASE_EMAC AT91_IO_P2V(AT91RM9200_BASE_EMAC) @@ -5358,6 +5441,8 @@ index 1008b9f..9ec4b50 100644 +#define AT91_BASE_TCB0 AT91SAM9263_BASE_TCB0 +#elif defined(CONFIG_ARCH_AT91SAM9RL) +#define AT91_BASE_TCB0 AT91SAM9RL_BASE_TCB0 ++#elif defined(CONFIG_ARCH_AT91SAM9G45) ++#define AT91_BASE_TCB0 AT91SAM9G45_BASE_TCB0 +#elif defined(CONFIG_ARCH_AT91X40) +#define AT91_BASE_TCB0 (AT91_BASE_SYS + AT91_TC) +#else @@ -8463,6 +8548,18 @@ index 42af976..2e713d1 100644 mcr p15, 0, r0, c2, c0, 0 @ load page table pointer mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs cpwait_ret lr, ip +diff --git a/arch/arm/plat-mxc/Kconfig b/arch/arm/plat-mxc/Kconfig +index a5353fc..ab894a0 100644 +--- a/arch/arm/plat-mxc/Kconfig ++++ b/arch/arm/plat-mxc/Kconfig +@@ -57,6 +57,7 @@ endmenu + + config MXC_IRQ_PRIOR + bool "Use IRQ priority" ++ depends on !IPIPE + help + Select this if you want to use prioritized IRQ handling. + This feature prevents higher priority ISR to be interrupted diff --git a/arch/arm/plat-mxc/avic.c b/arch/arm/plat-mxc/avic.c index 09e2bd0..5b9b15b 100644 --- a/arch/arm/plat-mxc/avic.c @@ -8568,7 +8665,7 @@ index eee1b60..253b711 100644 + +postcore_initcall(post_cpu_init); diff --git a/arch/arm/plat-mxc/gpio.c b/arch/arm/plat-mxc/gpio.c -index 6cd6d7f..d103f09 100644 +index 6cd6d7f..bfde13f 100644 --- a/arch/arm/plat-mxc/gpio.c +++ b/arch/arm/plat-mxc/gpio.c @@ -24,6 +24,7 @@ @@ -8601,35 +8698,7 @@ index 6cd6d7f..d103f09 100644 return 0; } -@@ -159,13 +163,35 @@ static void mxc_gpio_irq_handler(struct mxc_gpio_port *port, u32 irq_stat) - { - u32 gpio_irq_no_base = port->virtual_irq_start; - -+#ifdef CONFIG_IPIPE -+ /* Handle high priority domains interrupts first */ -+ u32 nonroot_gpios = irq_stat & port->nonroot_gpios; -+ -+ irq_stat &= ~nonroot_gpios; -+ while (nonroot_gpios != 0) { -+ int irqoffset = fls(nonroot_gpios) - 1; -+ -+ if (port->both_edges & (1 << irqoffset)) -+ mxc_flip_edge(port, irqoffset); -+ -+ ipipe_handle_chained_irq(gpio_irq_no_base + irqoffset); -+ -+ nonroot_gpios &= ~(1 << irqoffset); -+ } -+#endif -+ - while (irq_stat != 0) { - int irqoffset = fls(irq_stat) - 1; - -+#ifdef CONFIG_IPIPE -+ local_irq_enable_hw(); -+ local_irq_disable_hw(); -+#endif /* CONFIG_IPIPE */ -+ +@@ -165,7 +169,7 @@ static void mxc_gpio_irq_handler(struct mxc_gpio_port *port, u32 irq_stat) if (port->both_edges & (1 << irqoffset)) mxc_flip_edge(port, irqoffset); @@ -8638,48 +8707,7 @@ index 6cd6d7f..d103f09 100644 irq_stat &= ~(1 << irqoffset); } -@@ -177,10 +203,18 @@ static void mx3_gpio_irq_handler(u32 irq, struct irq_desc *desc) - u32 irq_stat; - struct mxc_gpio_port *port = irq_get_handler_data(irq); - -+#ifdef CONFIG_IPIPE -+ desc->irq_data.chip->irq_mask_ack(&desc->irq_data); -+#endif /* CONFIG_IPIPE */ -+ - irq_stat = __raw_readl(port->base + GPIO_ISR) & - __raw_readl(port->base + GPIO_IMR); - - mxc_gpio_irq_handler(port, irq_stat); -+ -+#ifdef CONFIG_IPIPE -+ desc->irq_data.chip->irq_unmask(&desc->irq_data); -+#endif /* CONFIG_IPIPE */ - } - - /* MX2 has one interrupt *for all* gpio ports */ -@@ -190,6 +224,10 @@ static void mx2_gpio_irq_handler(u32 irq, struct irq_desc *desc) - u32 irq_msk, irq_stat; - struct mxc_gpio_port *port = irq_get_handler_data(irq); - -+#ifdef CONFIG_IPIPE -+ desc->irq_data.chip->irq_mask_ack(&desc->irq_data); -+#endif /* CONFIG_IPIPE */ -+ - /* walk through all interrupt status registers */ - for (i = 0; i < gpio_table_size; i++) { - irq_msk = __raw_readl(port[i].base + GPIO_IMR); -@@ -200,6 +238,10 @@ static void mx2_gpio_irq_handler(u32 irq, struct irq_desc *desc) - if (irq_stat) - mxc_gpio_irq_handler(&port[i], irq_stat); - } -+ -+#ifdef CONFIG_IPIPE -+ desc->irq_data.chip->irq_unmask(&desc->irq_data); -+#endif /* CONFIG_IPIPE */ - } - - /* -@@ -359,3 +401,53 @@ int __init mxc_gpio_init(struct mxc_gpio_port *port, int cnt) +@@ -359,3 +363,53 @@ int __init mxc_gpio_init(struct mxc_gpio_port *port, int cnt) return 0; } @@ -8786,7 +8814,7 @@ index 35c89bc..826ec98 100644 + #endif /* __ASM_ARCH_MXC_IRQS_H__ */ diff --git a/arch/arm/plat-mxc/time.c b/arch/arm/plat-mxc/time.c -index 4b0fe28..aae2717 100644 +index 4b0fe28..da27606 100644 --- a/arch/arm/plat-mxc/time.c +++ b/arch/arm/plat-mxc/time.c @@ -25,6 +25,7 @@ @@ -8801,7 +8829,7 @@ index 4b0fe28..aae2717 100644 #define timer_is_v1() (cpu_is_mx1() || cpu_is_mx21() || cpu_is_mx27()) #define timer_is_v2() (!timer_is_v1()) -+#ifdef CONFIG_IPIPE ++#if defined(CONFIG_IPIPE) && !defined(CONFIG_SMP) +int __ipipe_mach_timerint; +EXPORT_SYMBOL(__ipipe_mach_timerint); + @@ -8812,29 +8840,35 @@ index 4b0fe28..aae2717 100644 +EXPORT_SYMBOL(__ipipe_mach_ticks_per_jiffy); + +static unsigned mxc_min_delay; -+#endif /* CONFIG_IPIPE */ ++#endif /* CONFIG_IPIPE && !CONFIG_SMP */ + static struct clock_event_device clockevent_mxc; static enum clock_event_mode clockevent_mode = CLOCK_EVT_MODE_UNUSED; -@@ -245,7 +259,11 @@ static irqreturn_t mxc_timer_interrupt(int irq, void *dev_id) - else +@@ -238,6 +252,7 @@ static void mxc_set_mode(enum clock_event_mode mode, + static irqreturn_t mxc_timer_interrupt(int irq, void *dev_id) + { + struct clock_event_device *evt = &clockevent_mxc; ++#if !defined(CONFIG_IPIPE) || defined(CONFIG_SMP) + uint32_t tstat; + + if (timer_is_v2()) +@@ -246,6 +261,9 @@ static irqreturn_t mxc_timer_interrupt(int irq, void *dev_id) tstat = __raw_readl(timer_base + MX1_2_TSTAT); -+#ifndef CONFIG_IPIPE gpt_irq_acknowledge(); -+#else /* !CONFIG_IPIPE */ ++#else /* CONFIG_IPIPE && !CONFIG_SMP */ + __ipipe_tsc_update(); -+#endif /* !CONFIG_IPIPE */ ++#endif /* CONFIG_IPIPE && !CONFIG_SMP */ evt->event_handler(evt); -@@ -288,7 +306,68 @@ static int __init mxc_clockevent_init(struct clk *timer_clk) +@@ -288,7 +306,67 @@ static int __init mxc_clockevent_init(struct clk *timer_clk) return 0; } -void __init mxc_timer_init(struct clk *timer_clk, void __iomem *base, int irq) -+#ifdef CONFIG_IPIPE ++#if defined(CONFIG_IPIPE) && !defined(CONFIG_SMP) +static struct __ipipe_tscinfo tsc_info = { + .type = IPIPE_TSC_TYPE_FREERUNNING, + .u = { @@ -8851,6 +8885,13 @@ index 4b0fe28..aae2717 100644 + +void __ipipe_mach_acktimer(void) +{ ++ uint32_t tstat; ++ ++ if (timer_is_v2()) ++ tstat = __raw_readl(timer_base + V2_TSTAT); ++ else ++ tstat = __raw_readl(timer_base + MX1_2_TSTAT); ++ + gpt_irq_acknowledge(); +} +/* @@ -8859,17 +8900,9 @@ index 4b0fe28..aae2717 100644 + +void __ipipe_mach_set_dec(unsigned long delay) +{ -+ if (delay > mxc_min_delay) { -+ unsigned long tcmp; -+ -+ if (!timer_is_v2()) { -+ tcmp = __raw_readl(timer_base + MX1_2_TCN) + delay; -+ __raw_writel(tcmp, timer_base + MX1_2_TCMP); -+ } else { -+ tcmp = __raw_readl(timer_base + V2_TCN) + delay; -+ __raw_writel(tcmp, timer_base + V2_TCMP); -+ } -+ } else ++ if (delay <= mxc_min_delay ++ || (!timer_is_v2() && mx1_2_set_next_event(delay, NULL) < 0) ++ || (timer_is_v2() && v2_set_next_event(delay, NULL) < 0)) + ipipe_trigger_irq(__ipipe_mach_timerint); +} +EXPORT_SYMBOL(__ipipe_mach_set_dec); @@ -8891,7 +8924,7 @@ index 4b0fe28..aae2717 100644 + return __raw_readl(timer_base + V2_TCMP) + - __raw_readl(timer_base + V2_TCN); +} -+#endif /* CONFIG_IPIPE */ ++#endif /* CONFIG_IPIPE && !CONFIG_SMP */ + +void __init +mxc_timer_init(struct clk *timer_clk, @@ -8899,26 +8932,26 @@ index 4b0fe28..aae2717 100644 { uint32_t tctl_val; -@@ -316,4 +395,20 @@ void __init mxc_timer_init(struct clk *timer_clk, void __iomem *base, int irq) +@@ -316,4 +394,20 @@ void __init mxc_timer_init(struct clk *timer_clk, void __iomem *base, int irq) /* Make irqs happen */ setup_irq(irq, &mxc_timer_irq); + -+#ifdef CONFIG_IPIPE ++#if defined(CONFIG_IPIPE) && !defined(CONFIG_SMP) + __ipipe_mach_timerint = irq; -+ __ipipe_mach_ticks_per_jiffy = (clk_get_rate(timer_clk) + HZ/2) / HZ; ++ __ipipe_mach_ticks_per_jiffy = (clk_get_rate(timer_clk) + HZ / 2) / HZ; + tsc_info.freq = clk_get_rate(timer_clk); -+ mxc_min_delay = ((__ipipe_cpu_freq + 500000) / 1000000) ?: 1; ++ mxc_min_delay = 2 * ((__ipipe_cpu_freq + 500000) / 1000000) ?: 1; + + if (timer_is_v1()) { + tsc_info.u.counter_paddr = phys + MX1_2_TCN; -+ tsc_info.counter_vaddr =(unsigned long)(phys + MX1_2_TCN); ++ tsc_info.counter_vaddr =(unsigned long)(timer_base + MX1_2_TCN); + } else { + tsc_info.u.counter_paddr = phys + V2_TCN; + tsc_info.counter_vaddr = (unsigned long)(timer_base + V2_TCN); + } + __ipipe_tsc_register(&tsc_info); -+#endif /* CONFIG_IPIPE */ ++#endif /* CONFIG_IPIPE && !CONFIG_SMP */ } diff --git a/arch/arm/plat-mxc/tzic.c b/arch/arm/plat-mxc/tzic.c index 57f9395..1b23e63 100644 @@ -10868,10 +10901,10 @@ index ba36217..a710065 100644 #endif /* LINUX_HARDIRQ_H */ diff --git a/include/linux/ipipe.h b/include/linux/ipipe.h new file mode 100644 -index 0000000..253dcdf +index 0000000..88c0920 --- /dev/null +++ b/include/linux/ipipe.h -@@ -0,0 +1,744 @@ +@@ -0,0 +1,745 @@ +/* -*- linux-c -*- + * include/linux/ipipe.h + * @@ -11516,6 +11549,7 @@ index 0000000..253dcdf +void *ipipe_get_ptd(int key); + +int ipipe_disable_ondemand_mappings(struct task_struct *tsk); ++int __ipipe_pin_vma(struct mm_struct *mm, struct vm_area_struct *vma); + +static inline void ipipe_nmi_enter(void) +{ @@ -17656,7 +17690,7 @@ index 4689cb0..3d12764 100644 /* diff --git a/mm/memory.c b/mm/memory.c -index 95a7799..3c50fcd 100644 +index 95a7799..b578617 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -845,6 +845,32 @@ out: @@ -17733,7 +17767,7 @@ index 95a7799..3c50fcd 100644 + struct page *uncow_page = NULL; +#ifdef CONFIG_IPIPE + int do_cow_break = 0; -+again: + again: + if (do_cow_break) { + uncow_page = alloc_page_vma(GFP_HIGHUSER, vma, addr); + if (uncow_page == NULL) @@ -17741,7 +17775,7 @@ index 95a7799..3c50fcd 100644 + do_cow_break = 0; + } +#else - again: ++again: +#endif init_rss_vec(rss); @@ -17782,6 +17816,15 @@ index 95a7799..3c50fcd 100644 if (entry.val) break; progress += 8; +@@ -1645,7 +1717,7 @@ int __get_user_pages(struct task_struct *tsk, struct mm_struct *mm, + + VM_BUG_ON(!!pages != !!(gup_flags & FOLL_GET)); + +- /* ++ /* + * Require read or write permissions. + * If FOLL_FORCE is set, we only require the "MAY" flags. + */ @@ -2430,32 +2502,6 @@ static inline int pte_unmap_same(struct mm_struct *mm, pmd_t *pmd, return same; } @@ -17815,7 +17858,7 @@ index 95a7799..3c50fcd 100644 /* * This routine handles present pages, when users try to write * to a shared page. It is done by copying the page to a new address -@@ -3983,3 +4029,111 @@ void copy_user_huge_page(struct page *dst, struct page *src, +@@ -3983,3 +4029,119 @@ void copy_user_huge_page(struct page *dst, struct page *src, } } #endif /* CONFIG_TRANSPARENT_HUGEPAGE || CONFIG_HUGETLBFS */ @@ -17881,13 +17924,31 @@ index 95a7799..3c50fcd 100644 + return 0; +} + -+int ipipe_disable_ondemand_mappings(struct task_struct *tsk) ++int __ipipe_pin_vma(struct mm_struct *mm, struct vm_area_struct *vma) +{ + unsigned long addr, next, end; ++ pgd_t *pgd; ++ ++ addr = vma->vm_start; ++ end = vma->vm_end; ++ ++ pgd = pgd_offset(mm, addr); ++ do { ++ next = pgd_addr_end(addr, end); ++ if (pgd_none_or_clear_bad(pgd)) ++ continue; ++ if (ipipe_pin_pud_range(mm, pgd, vma, addr, next)) ++ return -ENOMEM; ++ } while (pgd++, addr = next, addr != end); ++ ++ return 0; ++} ++ ++int ipipe_disable_ondemand_mappings(struct task_struct *tsk) ++{ + struct vm_area_struct *vma; + struct mm_struct *mm; + int result = 0; -+ pgd_t *pgd; + + mm = get_task_mm(tsk); + if (!mm) @@ -17902,19 +17963,9 @@ index 95a7799..3c50fcd 100644 + || !(vma->vm_flags & VM_WRITE)) + continue; + -+ addr = vma->vm_start; -+ end = vma->vm_end; -+ -+ pgd = pgd_offset(mm, addr); -+ do { -+ next = pgd_addr_end(addr, end); -+ if (pgd_none_or_clear_bad(pgd)) -+ continue; -+ if (ipipe_pin_pud_range(mm, pgd, vma, addr, next)) { -+ result = -ENOMEM; -+ goto done_mm; -+ } -+ } while (pgd++, addr = next, addr != end); ++ result = __ipipe_pin_vma(mm, vma); ++ if (result < 0) ++ goto done_mm; + } + set_bit(MMF_VM_PINNED, &mm->flags); + @@ -17952,7 +18003,7 @@ index 9e82e93..a4bd34d 100644 if (active_mm != mm) diff --git a/mm/mprotect.c b/mm/mprotect.c -index 5a688a2..3f234b3 100644 +index 5a688a2..9981d19 100644 --- a/mm/mprotect.c +++ b/mm/mprotect.c @@ -147,6 +147,7 @@ mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev, @@ -17982,6 +18033,31 @@ index 5a688a2..3f234b3 100644 if (vma_wants_writenotify(vma)) { vma->vm_page_prot = vm_get_page_prot(newflags & ~VM_SHARED); +@@ -214,6 +224,24 @@ success: + } + + mmu_notifier_invalidate_range_start(mm, start, end); ++#ifdef CONFIG_IPIPE ++ /* ++ * Privatize potential COW pages ++ */ ++ if (test_bit(MMF_VM_PINNED, &mm->flags) && ++ (((vma->vm_flags | mm->def_flags) & (VM_LOCKED | VM_WRITE)) == ++ (VM_LOCKED | VM_WRITE))) { ++ error = __ipipe_pin_vma(mm, vma); ++ if (error) ++ /* ++ * OOM. Just revert the fake VM_SHARED so that the ++ * zero page cannot be overwritten. ++ */ ++ vma->vm_page_prot = ++ pgprot_modify(vma->vm_page_prot, ++ vm_get_page_prot(newflags)); ++ } ++#endif + if (is_vm_hugetlb_page(vma)) + hugetlb_change_protection(vma, start, end, vma->vm_page_prot); + else diff --git a/mm/vmalloc.c b/mm/vmalloc.c index 65d5fd2..e4cd778 100644 --- a/mm/vmalloc.c _______________________________________________ Xenomai-git mailing list Xenomai-git@gna.org https://mail.gna.org/listinfo/xenomai-git