2012-06-18 11:30:31

by Michal Simek

[permalink] [raw]
Subject: ARM SMP/GIC/LDS patches for Xilinx Zynq remoteproc

Hi,

I am sending bunch of patches which I have made for a Xilinx Zynq remoteproc AMP solution +
some patches around.

Xilinx Zynq is dual core ARM Cortex A9. Remoteproc in new interface for controlling other cpus
is the system. I have created solution where on one ARM runs Linux and the second ARM
runs RTOS or any other standalone firmware. It is AMP between two ARM cores.

Communication is done via shared memory with kicking via IPI interrupts.
Based on that I had to do some changes in the kernel which I am sending.

Thanks for your review,
Michal


2012-06-18 11:30:41

by Michal Simek

[permalink] [raw]
Subject: [RFC PATCH 1/8] ARM: gic: Support forcing cpumask for possible cpus in the system

gic_set_affinity doesn't support force option. Force option
should work with all possible cpus in the system not only with
online cpus.

Signed-off-by: Michal Simek <[email protected]>
---
arch/arm/common/gic.c | 7 ++++++-
1 files changed, 6 insertions(+), 1 deletions(-)

diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c
index aa52699..4003cc2 100644
--- a/arch/arm/common/gic.c
+++ b/arch/arm/common/gic.c
@@ -235,9 +235,14 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val,
{
void __iomem *reg = gic_dist_base(d) + GIC_DIST_TARGET + (gic_irq(d) & ~3);
unsigned int shift = (gic_irq(d) % 4) * 8;
- unsigned int cpu = cpumask_any_and(mask_val, cpu_online_mask);
+ unsigned int cpu;
u32 val, mask, bit;

+ if (force)
+ cpu = cpumask_any_and(mask_val, cpu_possible_mask);
+ else
+ cpu = cpumask_any_and(mask_val, cpu_online_mask);
+
if (cpu >= 8 || cpu >= nr_cpu_ids)
return -EINVAL;

--
1.7.0.4

2012-06-18 11:30:47

by Michal Simek

[permalink] [raw]
Subject: [RFC PATCH 3/8] ARM: gic: Introduce new gic_set_cpu

gic_set_cpu enable option to forward specific IRQ to choosen
ARM core.

Signed-off-by: Michal Simek <[email protected]>
---
arch/arm/common/gic.c | 11 +++++++++++
arch/arm/include/asm/hardware/gic.h | 2 ++
2 files changed, 13 insertions(+), 0 deletions(-)

diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c
index b8e7202..2998d9e 100644
--- a/arch/arm/common/gic.c
+++ b/arch/arm/common/gic.c
@@ -257,6 +257,17 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val,

return IRQ_SET_MASK_OK;
}
+
+void gic_set_cpu(unsigned int cpu, unsigned int irq)
+{
+ struct irq_data *d = irq_get_irq_data(irq);
+ struct cpumask mask;
+
+ cpumask_clear(&mask);
+ cpumask_set_cpu(cpu, &mask);
+ gic_set_affinity(d, &mask, true);
+}
+EXPORT_SYMBOL(gic_set_cpu);
#endif

#ifdef CONFIG_PM
diff --git a/arch/arm/include/asm/hardware/gic.h b/arch/arm/include/asm/hardware/gic.h
index 4b1ce6c..8aa9631 100644
--- a/arch/arm/include/asm/hardware/gic.h
+++ b/arch/arm/include/asm/hardware/gic.h
@@ -46,6 +46,8 @@ void gic_handle_irq(struct pt_regs *regs);
void gic_cascade_irq(unsigned int gic_nr, unsigned int irq);
void gic_raise_softirq(const struct cpumask *mask, unsigned int irq);

+void gic_set_cpu(unsigned int cpu, unsigned int irq);
+
static inline void gic_init(unsigned int nr, int start,
void __iomem *dist , void __iomem *cpu)
{
--
1.7.0.4

2012-06-18 11:30:55

by Michal Simek

[permalink] [raw]
Subject: [RFC PATCH 5/8] AMP: smp: Extend number of IPIs

GIC supports up to 16 IPIs.

Signed-off-by: Michal Simek <[email protected]>

---
Please correct me if this code is also designed for different
interrupt controller which doesn't support 16 IPIs.
---
arch/arm/include/asm/hardirq.h | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/arch/arm/include/asm/hardirq.h b/arch/arm/include/asm/hardirq.h
index 436e60b..3e9ded5 100644
--- a/arch/arm/include/asm/hardirq.h
+++ b/arch/arm/include/asm/hardirq.h
@@ -5,7 +5,7 @@
#include <linux/threads.h>
#include <asm/irq.h>

-#define NR_IPI 5
+#define NR_IPI 16

typedef struct {
unsigned int __softirq_pending;
--
1.7.0.4

2012-06-18 11:30:50

by Michal Simek

[permalink] [raw]
Subject: [RFC PATCH 4/8] ARM: smp: Move cpu initialization directly to ipi_cpu_stop

This is just preparation patch for dynamic IPI allocation.

Signed-off-by: Michal Simek <[email protected]>
---
arch/arm/kernel/smp.c | 6 ++++--
1 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index 2c7217d..47406ee 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -468,8 +468,10 @@ static DEFINE_RAW_SPINLOCK(stop_lock);
/*
* ipi_cpu_stop - handle IPI from smp_send_stop()
*/
-static void ipi_cpu_stop(unsigned int cpu)
+static void ipi_cpu_stop(void)
{
+ unsigned int cpu = smp_processor_id();
+
if (system_state == SYSTEM_BOOTING ||
system_state == SYSTEM_RUNNING) {
raw_spin_lock(&stop_lock);
@@ -528,7 +530,7 @@ void handle_IPI(int ipinr, struct pt_regs *regs)

case IPI_CPU_STOP:
irq_enter();
- ipi_cpu_stop(cpu);
+ ipi_cpu_stop();
irq_exit();
break;

--
1.7.0.4

2012-06-18 11:31:00

by Michal Simek

[permalink] [raw]
Subject: [RFC PATCH 6/8] ARM: smp: Use generic API for ipi

Support dynamic IPI allocation. It supports cases
where user wants to use IPI for communication among cpus
and setup own handler for it.

New functions set_ipi_handler/clear_ipi_handler are used
for dynamic allocation.

Signed-off-by: Michal Simek <[email protected]>
---
arch/arm/include/asm/smp.h | 3 +
arch/arm/kernel/smp.c | 104 +++++++++++++++++++++++++------------------
2 files changed, 63 insertions(+), 44 deletions(-)

diff --git a/arch/arm/include/asm/smp.h b/arch/arm/include/asm/smp.h
index ae29293..308cca9 100644
--- a/arch/arm/include/asm/smp.h
+++ b/arch/arm/include/asm/smp.h
@@ -93,4 +93,7 @@ extern void platform_cpu_enable(unsigned int cpu);
extern void arch_send_call_function_single_ipi(int cpu);
extern void arch_send_call_function_ipi_mask(const struct cpumask *mask);

+extern int set_ipi_handler(int ipinr, void *handler, char *desc);
+extern void clear_ipi_handler(int ipinr);
+
#endif /* ifndef __ASM_ARM_SMP_H */
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index 47406ee..4af1679 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -51,7 +51,7 @@
struct secondary_data secondary_data;

enum ipi_msg_type {
- IPI_TIMER = 2,
+ IPI_TIMER,
IPI_RESCHEDULE,
IPI_CALL_FUNC,
IPI_CALL_FUNC_SINGLE,
@@ -346,13 +346,23 @@ void arch_send_call_function_single_ipi(int cpu)
smp_cross_call(cpumask_of(cpu), IPI_CALL_FUNC_SINGLE);
}

-static const char *ipi_types[NR_IPI] = {
-#define S(x,s) [x - IPI_TIMER] = s
- S(IPI_TIMER, "Timer broadcast interrupts"),
- S(IPI_RESCHEDULE, "Rescheduling interrupts"),
- S(IPI_CALL_FUNC, "Function call interrupts"),
- S(IPI_CALL_FUNC_SINGLE, "Single function call interrupts"),
- S(IPI_CPU_STOP, "CPU stop interrupts"),
+struct ipi {
+ const char *desc;
+ void (*handler)(void);
+};
+
+static void ipi_timer(void);
+static void ipi_cpu_stop(void);
+
+static struct ipi ipi_types[NR_IPI] = {
+#define S(x, s, f) [x].desc = s, [x].handler = f
+ S(IPI_TIMER, "Timer broadcast interrupts", ipi_timer),
+ S(IPI_RESCHEDULE, "Rescheduling interrupts", scheduler_ipi),
+ S(IPI_CALL_FUNC, "Function call interrupts",
+ generic_smp_call_function_interrupt),
+ S(IPI_CALL_FUNC_SINGLE, "Single function call interrupts",
+ generic_smp_call_function_single_interrupt),
+ S(IPI_CPU_STOP, "CPU stop interrupts", ipi_cpu_stop),
};

void show_ipi_list(struct seq_file *p, int prec)
@@ -360,13 +370,15 @@ void show_ipi_list(struct seq_file *p, int prec)
unsigned int cpu, i;

for (i = 0; i < NR_IPI; i++) {
- seq_printf(p, "%*s%u: ", prec - 1, "IPI", i);
+ if (ipi_types[i].handler) {
+ seq_printf(p, "%*s%u: ", prec - 1, "IPI", i);

- for_each_present_cpu(cpu)
- seq_printf(p, "%10u ",
- __get_irq_stat(cpu, ipi_irqs[i]));
+ for_each_present_cpu(cpu)
+ seq_printf(p, "%10u ",
+ __get_irq_stat(cpu, ipi_irqs[i]));

- seq_printf(p, " %s\n", ipi_types[i]);
+ seq_printf(p, " %s\n", ipi_types[i].desc);
+ }
}
}

@@ -502,45 +514,49 @@ void handle_IPI(int ipinr, struct pt_regs *regs)
unsigned int cpu = smp_processor_id();
struct pt_regs *old_regs = set_irq_regs(regs);

- if (ipinr >= IPI_TIMER && ipinr < IPI_TIMER + NR_IPI)
- __inc_irq_stat(cpu, ipi_irqs[ipinr - IPI_TIMER]);
-
- switch (ipinr) {
- case IPI_TIMER:
+ if (ipi_types[ipinr].handler) {
+ __inc_irq_stat(cpu, ipi_irqs[ipinr]);
irq_enter();
- ipi_timer();
+ (*ipi_types[ipinr].handler)();
irq_exit();
- break;
+ } else
+ pr_crit("CPU%u: Unknown IPI message 0x%x\n",
+ cpu, ipinr);

- case IPI_RESCHEDULE:
- scheduler_ipi();
- break;
+ set_irq_regs(old_regs);
+}

- case IPI_CALL_FUNC:
- irq_enter();
- generic_smp_call_function_interrupt();
- irq_exit();
- break;
+/*
+ * set_ipi_handler:
+ * Interface provided for a kernel module to specify an IPI handler function.
+ */
+int set_ipi_handler(int ipinr, void *handler, char *desc)
+{
+ unsigned int cpu = smp_processor_id();

- case IPI_CALL_FUNC_SINGLE:
- irq_enter();
- generic_smp_call_function_single_interrupt();
- irq_exit();
- break;
+ if (ipi_types[ipinr].handler) {
+ pr_crit("CPU%u: IPI handler 0x%x already registered to %pf\n",
+ cpu, ipinr, ipi_types[ipinr].handler);
+ return -1;
+ }

- case IPI_CPU_STOP:
- irq_enter();
- ipi_cpu_stop();
- irq_exit();
- break;
+ ipi_types[ipinr].handler = handler;
+ ipi_types[ipinr].desc = desc;

- default:
- printk(KERN_CRIT "CPU%u: Unknown IPI message 0x%x\n",
- cpu, ipinr);
- break;
- }
- set_irq_regs(old_regs);
+ return 0;
+}
+EXPORT_SYMBOL(set_ipi_handler);
+
+/*
+ * clear_ipi_handler:
+ * Interface provided for a kernel module to clear an IPI handler function.
+ */
+void clear_ipi_handler(int ipinr)
+{
+ ipi_types[ipinr].handler = NULL;
+ ipi_types[ipinr].desc = NULL;
}
+EXPORT_SYMBOL(clear_ipi_handler);

void smp_send_reschedule(int cpu)
{
--
1.7.0.4

2012-06-18 11:31:10

by Michal Simek

[permalink] [raw]
Subject: [RFC PATCH 7/8] ARM: vmlinux.lds: Setup physical load address not virtual

Setup correct virtual and physical address in ELF LOAD section.

Signed-off-by: Michal Simek <[email protected]>
---
arch/arm/include/asm/page.h | 2 ++
arch/arm/kernel/vmlinux.lds.S | 28 ++++++++++++++--------------
2 files changed, 16 insertions(+), 14 deletions(-)

diff --git a/arch/arm/include/asm/page.h b/arch/arm/include/asm/page.h
index ecf9019..4070209 100644
--- a/arch/arm/include/asm/page.h
+++ b/arch/arm/include/asm/page.h
@@ -15,6 +15,8 @@
#define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT)
#define PAGE_MASK (~(PAGE_SIZE-1))

+#define LOAD_OFFSET (CONFIG_PAGE_OFFSET - CONFIG_PHYS_OFFSET)
+
#ifndef __ASSEMBLY__

#ifndef CONFIG_MMU
diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
index c887be0..b996bc0 100644
--- a/arch/arm/kernel/vmlinux.lds.S
+++ b/arch/arm/kernel/vmlinux.lds.S
@@ -3,11 +3,11 @@
* Written by Martin Mares <[email protected]>
*/

+#include <asm/page.h>
#include <asm-generic/vmlinux.lds.h>
#include <asm/cache.h>
#include <asm/thread_info.h>
#include <asm/memory.h>
-#include <asm/page.h>

#define PROC_INFO \
. = ALIGN(4); \
@@ -86,11 +86,11 @@ SECTIONS
#else
. = PAGE_OFFSET + TEXT_OFFSET;
#endif
- .head.text : {
+ .head.text : AT(ADDR(.head.text) - LOAD_OFFSET) {
_text = .;
HEAD_TEXT
}
- .text : { /* Real text segment */
+ .text : AT(ADDR(.text) - LOAD_OFFSET){ /* Real text segment */
_stext = .; /* Text and read-only data */
__exception_text_start = .;
*(.exception.text)
@@ -132,12 +132,12 @@ SECTIONS
* Stack unwinding tables
*/
. = ALIGN(8);
- .ARM.unwind_idx : {
+ .ARM.unwind_idx : AT(ADDR(.ARM.unwind_idx) - LOAD_OFFSET) {
__start_unwind_idx = .;
*(.ARM.exidx*)
__stop_unwind_idx = .;
}
- .ARM.unwind_tab : {
+ .ARM.unwind_tab : AT(ADDR(.ARM.unwind_tab) - LOAD_OFFSET) {
__start_unwind_tab = .;
*(.ARM.extab*)
__stop_unwind_tab = .;
@@ -152,35 +152,35 @@ SECTIONS
#endif

INIT_TEXT_SECTION(8)
- .exit.text : {
+ .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) {
ARM_EXIT_KEEP(EXIT_TEXT)
}
- .init.proc.info : {
+ .init.proc.info : AT(ADDR(.init.proc.info) - LOAD_OFFSET) {
ARM_CPU_DISCARD(PROC_INFO)
}
- .init.arch.info : {
+ .init.arch.info : AT(ADDR(.init.arch.info) - LOAD_OFFSET) {
__arch_info_begin = .;
*(.arch.info.init)
__arch_info_end = .;
}
- .init.tagtable : {
+ .init.tagtable : AT(ADDR(.init.tagtable) - LOAD_OFFSET) {
__tagtable_begin = .;
*(.taglist.init)
__tagtable_end = .;
}
#ifdef CONFIG_SMP_ON_UP
- .init.smpalt : {
+ .init.smpalt : AT(ADDR(.init.smpalt) - LOAD_OFFSET) {
__smpalt_begin = .;
*(.alt.smp.init)
__smpalt_end = .;
}
#endif
- .init.pv_table : {
+ .init.pv_table : AT(ADDR(.init.pv_table) - LOAD_OFFSET) {
__pv_table_begin = .;
*(.pv_table)
__pv_table_end = .;
}
- .init.data : {
+ .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) {
#ifndef CONFIG_XIP_KERNEL
INIT_DATA
#endif
@@ -191,7 +191,7 @@ SECTIONS
INIT_RAM_FS
}
#ifndef CONFIG_XIP_KERNEL
- .exit.data : {
+ .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) {
ARM_EXIT_KEEP(EXIT_DATA)
}
#endif
@@ -207,7 +207,7 @@ SECTIONS
__data_loc = .;
#endif

- .data : AT(__data_loc) {
+ .data : AT(ADDR(.data) - LOAD_OFFSET) {
_data = .; /* address in memory */
_sdata = .;

--
1.7.0.4

2012-06-18 11:31:13

by Michal Simek

[permalink] [raw]
Subject: [RFC PATCH 8/8] ARM: vmlinux.lds: Setup correct entry point to physical address

linker script setups entry point to virtual address.

Signed-off-by: Michal Simek <[email protected]>

---
Not sure what is the reason to setup entry point to virtual address.
---
arch/arm/kernel/vmlinux.lds.S | 4 +++-
1 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
index b996bc0..de43b01 100644
--- a/arch/arm/kernel/vmlinux.lds.S
+++ b/arch/arm/kernel/vmlinux.lds.S
@@ -39,7 +39,7 @@
#endif

OUTPUT_ARCH(arm)
-ENTRY(stext)
+ENTRY(arm_start)

#ifndef __ARMEB__
jiffies = jiffies_64;
@@ -83,8 +83,10 @@ SECTIONS

#ifdef CONFIG_XIP_KERNEL
. = XIP_VIRT_ADDR(CONFIG_XIP_PHYS_ADDR);
+ arm_start = . ;
#else
. = PAGE_OFFSET + TEXT_OFFSET;
+ arm_start = CONFIG_PHYS_OFFSET + TEXT_OFFSET;
#endif
.head.text : AT(ADDR(.head.text) - LOAD_OFFSET) {
_text = .;
--
1.7.0.4

2012-06-18 11:32:12

by Michal Simek

[permalink] [raw]
Subject: [RFC PATCH 2/8] ARM: gic: Export gic_raise_softirq function for kernel modules

This function can be used by device driver for raising
software irqs. For example AMP(remoteproc) on Zynq.

Signed-off-by: Michal Simek <[email protected]>
---
arch/arm/common/gic.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c
index 4003cc2..b8e7202 100644
--- a/arch/arm/common/gic.c
+++ b/arch/arm/common/gic.c
@@ -22,6 +22,7 @@
* As such, the enable set/clear, pending set/clear and active bit
* registers are banked per-cpu for these sources.
*/
+#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/err.h>
@@ -753,6 +754,7 @@ void gic_raise_softirq(const struct cpumask *mask, unsigned int irq)
/* this always happens on GIC0 */
writel_relaxed(map << 16 | irq, gic_data_dist_base(&gic_data[0]) + GIC_DIST_SOFTINT);
}
+EXPORT_SYMBOL(gic_raise_softirq);
#endif

#ifdef CONFIG_OF
--
1.7.0.4

2012-06-18 11:33:50

by Russell King - ARM Linux

[permalink] [raw]
Subject: Re: [RFC PATCH 1/8] ARM: gic: Support forcing cpumask for possible cpus in the system

On Mon, Jun 18, 2012 at 01:30:04PM +0200, Michal Simek wrote:
> gic_set_affinity doesn't support force option. Force option
> should work with all possible cpus in the system not only with
> online cpus.

Neither does x86. Why do you want this? Offline CPUs are unable to
receive the interrupt in any case (and must not receive interrupts in
the bringup path until they are online.)

2012-06-18 11:34:29

by Russell King - ARM Linux

[permalink] [raw]
Subject: Re: [RFC PATCH 4/8] ARM: smp: Move cpu initialization directly to ipi_cpu_stop

On Mon, Jun 18, 2012 at 01:30:07PM +0200, Michal Simek wrote:
> This is just preparation patch for dynamic IPI allocation.

Why?

2012-06-18 11:35:55

by Russell King - ARM Linux

[permalink] [raw]
Subject: Re: [RFC PATCH 5/8] AMP: smp: Extend number of IPIs

On Mon, Jun 18, 2012 at 01:30:08PM +0200, Michal Simek wrote:
> GIC supports up to 16 IPIs.
>
> Signed-off-by: Michal Simek <[email protected]>
>
> ---
> Please correct me if this code is also designed for different
> interrupt controller which doesn't support 16 IPIs.

This code is not specific to the GIC. We use NR_IPI to indicate the
number of IPIs that the kernel actually uses, not the number which the
hardware provides.

2012-06-18 11:36:25

by Russell King - ARM Linux

[permalink] [raw]
Subject: Re: [RFC PATCH 6/8] ARM: smp: Use generic API for ipi

On Mon, Jun 18, 2012 at 01:30:09PM +0200, Michal Simek wrote:
> Support dynamic IPI allocation. It supports cases
> where user wants to use IPI for communication among cpus
> and setup own handler for it.
>
> New functions set_ipi_handler/clear_ipi_handler are used
> for dynamic allocation.

For what purpose?

2012-06-18 11:37:23

by Russell King - ARM Linux

[permalink] [raw]
Subject: Re: [RFC PATCH 8/8] ARM: vmlinux.lds: Setup correct entry point to physical address

On Mon, Jun 18, 2012 at 01:30:11PM +0200, Michal Simek wrote:
> linker script setups entry point to virtual address.
>
> Signed-off-by: Michal Simek <[email protected]>
>
> ---
> Not sure what is the reason to setup entry point to virtual address.
> ---
> arch/arm/kernel/vmlinux.lds.S | 4 +++-
> 1 files changed, 3 insertions(+), 1 deletions(-)
>
> diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
> index b996bc0..de43b01 100644
> --- a/arch/arm/kernel/vmlinux.lds.S
> +++ b/arch/arm/kernel/vmlinux.lds.S
> @@ -39,7 +39,7 @@
> #endif
>
> OUTPUT_ARCH(arm)
> -ENTRY(stext)
> +ENTRY(arm_start)

stext etc better stay as the virtual address through this change. The
kernel makes use of all stext/etext etc symbols as virtual addresses.

2012-06-18 11:41:59

by Michal Simek

[permalink] [raw]
Subject: Re: [RFC PATCH 1/8] ARM: gic: Support forcing cpumask for possible cpus in the system

On 06/18/2012 01:33 PM, Russell King - ARM Linux wrote:
> On Mon, Jun 18, 2012 at 01:30:04PM +0200, Michal Simek wrote:
>> gic_set_affinity doesn't support force option. Force option
>> should work with all possible cpus in the system not only with
>> online cpus.
>
> Neither does x86. Why do you want this? Offline CPUs are unable to
> receive the interrupt in any case (and must not receive interrupts in
> the bringup path until they are online.)

The whole reason for all these changes in AMP on dual core Cortex A9 where
on one cpu runs Linux and on the second RTOS/standlone.

It means that the second cpu is from Linux point of view offline all the time.
But GIC has to be (and can be) setup to forward IRQ directly to the second cpu.
GIC should be controlled by Linux.

Thanks,
Michal




--
Michal Simek, Ing. (M.Eng)
w: http://www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel 2.6 Microblaze Linux - http://www.monstr.eu/fdt/
Microblaze U-BOOT custodian

2012-06-18 11:45:48

by Michal Simek

[permalink] [raw]
Subject: Re: [RFC PATCH 8/8] ARM: vmlinux.lds: Setup correct entry point to physical address

On 06/18/2012 01:37 PM, Russell King - ARM Linux wrote:
> On Mon, Jun 18, 2012 at 01:30:11PM +0200, Michal Simek wrote:
>> linker script setups entry point to virtual address.
>>
>> Signed-off-by: Michal Simek<[email protected]>
>>
>> ---
>> Not sure what is the reason to setup entry point to virtual address.
>> ---
>> arch/arm/kernel/vmlinux.lds.S | 4 +++-
>> 1 files changed, 3 insertions(+), 1 deletions(-)
>>
>> diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
>> index b996bc0..de43b01 100644
>> --- a/arch/arm/kernel/vmlinux.lds.S
>> +++ b/arch/arm/kernel/vmlinux.lds.S
>> @@ -39,7 +39,7 @@
>> #endif
>>
>> OUTPUT_ARCH(arm)
>> -ENTRY(stext)
>> +ENTRY(arm_start)
>
> stext etc better stay as the virtual address through this change. The
> kernel makes use of all stext/etext etc symbols as virtual addresses.

I am not changing stext to physical address. Just elf entry point.
What's it reason to have entry point in virtual address space?

Thanks,
Michal


--
Michal Simek, Ing. (M.Eng)
w: http://www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel 2.6 Microblaze Linux - http://www.monstr.eu/fdt/
Microblaze U-BOOT custodian

2012-06-18 11:53:48

by Michal Simek

[permalink] [raw]
Subject: Re: [RFC PATCH 4/8] ARM: smp: Move cpu initialization directly to ipi_cpu_stop

On 06/18/2012 01:34 PM, Russell King - ARM Linux wrote:
> On Mon, Jun 18, 2012 at 01:30:07PM +0200, Michal Simek wrote:
>> This is just preparation patch for dynamic IPI allocation.
>
> Why?

Let's start with this one first.

The reason for dynamic IPI allocation is that IPI interrupts can be used (and I am using them)
for sending IRQ to the second cpu and the second cpu doesn't run Linux.
But still I need functionality for sending interrupts to the second core for Linux. A also need
to have any hook to be able to receive irq from the second core.
Based on that I have looked at this code where only static allocation is used and it is not possible
to use it in this model because no driver can allocate IPI handler.
Based on that I have changed it to model where dynamic IPIs can be allocated dynamically.
As you see from the code. Origin static IPI allocation is still there.

Maybe what it is not visible is that NR_IPI value. As you commented in 5/8 NR_IPI stores number of
IPI used by Linux and I am using is as maximum IPIs in the system.
I am completely fine with not changing NR_IPI value and introduce new one like MAX_NR_IPI value which
will be for Xilinx Zynq GIC setup to 16.

Hope I have clarify it a little bit.

Thanks,
Michal

--
Michal Simek, Ing. (M.Eng)
w: http://www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel 2.6 Microblaze Linux - http://www.monstr.eu/fdt/
Microblaze U-BOOT custodian

2012-06-18 11:54:42

by Michal Simek

[permalink] [raw]
Subject: Re: [RFC PATCH 6/8] ARM: smp: Use generic API for ipi

On 06/18/2012 01:36 PM, Russell King - ARM Linux wrote:
> On Mon, Jun 18, 2012 at 01:30:09PM +0200, Michal Simek wrote:
>> Support dynamic IPI allocation. It supports cases
>> where user wants to use IPI for communication among cpus
>> and setup own handler for it.
>>
>> New functions set_ipi_handler/clear_ipi_handler are used
>> for dynamic allocation.
>
> For what purpose?

Please look at my reaction in 4/8. It is the part of dynamic IPI allocation.

Thanks,
Michal


--
Michal Simek, Ing. (M.Eng)
w: http://www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel 2.6 Microblaze Linux - http://www.monstr.eu/fdt/
Microblaze U-BOOT custodian

2012-06-18 11:55:00

by Michal Simek

[permalink] [raw]
Subject: Re: [RFC PATCH 5/8] AMP: smp: Extend number of IPIs

On 06/18/2012 01:35 PM, Russell King - ARM Linux wrote:
> On Mon, Jun 18, 2012 at 01:30:08PM +0200, Michal Simek wrote:
>> GIC supports up to 16 IPIs.
>>
>> Signed-off-by: Michal Simek<[email protected]>
>>
>> ---
>> Please correct me if this code is also designed for different
>> interrupt controller which doesn't support 16 IPIs.
>
> This code is not specific to the GIC. We use NR_IPI to indicate the
> number of IPIs that the kernel actually uses, not the number which the
> hardware provides.

ok.

Thanks,
Michal


--
Michal Simek, Ing. (M.Eng)
w: http://www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel 2.6 Microblaze Linux - http://www.monstr.eu/fdt/
Microblaze U-BOOT custodian

2012-06-18 14:13:25

by Nicolas Pitre

[permalink] [raw]
Subject: Re: [RFC PATCH 7/8] ARM: vmlinux.lds: Setup physical load address not virtual

On Mon, 18 Jun 2012, Michal Simek wrote:

> Setup correct virtual and physical address in ELF LOAD section.

We are moving to a single kernel binary for multiple targets, including
targets with different physical load addresses. The kernel code figures
out at run time what the actual physical address is when
CONFIG_ARM_PATCH_PHYS_VIRT is set which is the default these days. In
other words, we don't know the physical offset at build time in that
case and CONFIG_PHYS_OFFSET is simply not defined.

Why do you need this change? Your patch comments are lacking
justification for them.


> Signed-off-by: Michal Simek <[email protected]>
> ---
> arch/arm/include/asm/page.h | 2 ++
> arch/arm/kernel/vmlinux.lds.S | 28 ++++++++++++++--------------
> 2 files changed, 16 insertions(+), 14 deletions(-)
>
> diff --git a/arch/arm/include/asm/page.h b/arch/arm/include/asm/page.h
> index ecf9019..4070209 100644
> --- a/arch/arm/include/asm/page.h
> +++ b/arch/arm/include/asm/page.h
> @@ -15,6 +15,8 @@
> #define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT)
> #define PAGE_MASK (~(PAGE_SIZE-1))
>
> +#define LOAD_OFFSET (CONFIG_PAGE_OFFSET - CONFIG_PHYS_OFFSET)
> +
> #ifndef __ASSEMBLY__
>
> #ifndef CONFIG_MMU
> diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
> index c887be0..b996bc0 100644
> --- a/arch/arm/kernel/vmlinux.lds.S
> +++ b/arch/arm/kernel/vmlinux.lds.S
> @@ -3,11 +3,11 @@
> * Written by Martin Mares <[email protected]>
> */
>
> +#include <asm/page.h>
> #include <asm-generic/vmlinux.lds.h>
> #include <asm/cache.h>
> #include <asm/thread_info.h>
> #include <asm/memory.h>
> -#include <asm/page.h>
>
> #define PROC_INFO \
> . = ALIGN(4); \
> @@ -86,11 +86,11 @@ SECTIONS
> #else
> . = PAGE_OFFSET + TEXT_OFFSET;
> #endif
> - .head.text : {
> + .head.text : AT(ADDR(.head.text) - LOAD_OFFSET) {
> _text = .;
> HEAD_TEXT
> }
> - .text : { /* Real text segment */
> + .text : AT(ADDR(.text) - LOAD_OFFSET){ /* Real text segment */
> _stext = .; /* Text and read-only data */
> __exception_text_start = .;
> *(.exception.text)
> @@ -132,12 +132,12 @@ SECTIONS
> * Stack unwinding tables
> */
> . = ALIGN(8);
> - .ARM.unwind_idx : {
> + .ARM.unwind_idx : AT(ADDR(.ARM.unwind_idx) - LOAD_OFFSET) {
> __start_unwind_idx = .;
> *(.ARM.exidx*)
> __stop_unwind_idx = .;
> }
> - .ARM.unwind_tab : {
> + .ARM.unwind_tab : AT(ADDR(.ARM.unwind_tab) - LOAD_OFFSET) {
> __start_unwind_tab = .;
> *(.ARM.extab*)
> __stop_unwind_tab = .;
> @@ -152,35 +152,35 @@ SECTIONS
> #endif
>
> INIT_TEXT_SECTION(8)
> - .exit.text : {
> + .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) {
> ARM_EXIT_KEEP(EXIT_TEXT)
> }
> - .init.proc.info : {
> + .init.proc.info : AT(ADDR(.init.proc.info) - LOAD_OFFSET) {
> ARM_CPU_DISCARD(PROC_INFO)
> }
> - .init.arch.info : {
> + .init.arch.info : AT(ADDR(.init.arch.info) - LOAD_OFFSET) {
> __arch_info_begin = .;
> *(.arch.info.init)
> __arch_info_end = .;
> }
> - .init.tagtable : {
> + .init.tagtable : AT(ADDR(.init.tagtable) - LOAD_OFFSET) {
> __tagtable_begin = .;
> *(.taglist.init)
> __tagtable_end = .;
> }
> #ifdef CONFIG_SMP_ON_UP
> - .init.smpalt : {
> + .init.smpalt : AT(ADDR(.init.smpalt) - LOAD_OFFSET) {
> __smpalt_begin = .;
> *(.alt.smp.init)
> __smpalt_end = .;
> }
> #endif
> - .init.pv_table : {
> + .init.pv_table : AT(ADDR(.init.pv_table) - LOAD_OFFSET) {
> __pv_table_begin = .;
> *(.pv_table)
> __pv_table_end = .;
> }
> - .init.data : {
> + .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) {
> #ifndef CONFIG_XIP_KERNEL
> INIT_DATA
> #endif
> @@ -191,7 +191,7 @@ SECTIONS
> INIT_RAM_FS
> }
> #ifndef CONFIG_XIP_KERNEL
> - .exit.data : {
> + .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) {
> ARM_EXIT_KEEP(EXIT_DATA)
> }
> #endif
> @@ -207,7 +207,7 @@ SECTIONS
> __data_loc = .;
> #endif
>
> - .data : AT(__data_loc) {
> + .data : AT(ADDR(.data) - LOAD_OFFSET) {
> _data = .; /* address in memory */
> _sdata = .;
>
> --
> 1.7.0.4
>