Skip to content

Initial support for ARM Cortex-R #9316

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Aug 9, 2019
Merged

Conversation

bbolen
Copy link
Collaborator

@bbolen bbolen commented Aug 6, 2018

There have been a couple of requests for the addition of ARM Cortex-R support, e.g. #6545 and #5540.

I have started work for Cortex-R4 support for a project my company is doing. This PR represents work that gets the "shell" sample working on an R4. Basic context switching and interrupts using an R4 connected to a GIC400 are working.

The work and testing were done on a custom SoC so the PR does not include the SoC code since it won't be very useful to anyone.

Closes #6545
Closes #5540

Signed-off-by: Bradley Bolen [email protected]

@carlescufi carlescufi added DNM This PR should not be merged (Do Not Merge) area: ARM ARM (32-bit) Architecture RFC Request For Comments: want input from the community area: Architectures and removed DNM This PR should not be merged (Do Not Merge) labels Aug 6, 2018
@carlescufi carlescufi requested a review from pizi-nordic August 6, 2018 20:59
@codecov-io
Copy link

codecov-io commented Aug 6, 2018

Codecov Report

❗ No coverage uploaded for pull request base (master@be2c937). Click here to learn what that means.
The diff coverage is n/a.

Impacted file tree graph

@@            Coverage Diff            @@
##             master    #9316   +/-   ##
=========================================
  Coverage          ?   52.92%           
=========================================
  Files             ?      309           
  Lines             ?    45268           
  Branches          ?    10451           
=========================================
  Hits              ?    23956           
  Misses            ?    16544           
  Partials          ?     4768

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update be2c937...5396c68. Read the comment docs.

Copy link
Collaborator

@ulfalizer ulfalizer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just some Kconfig nits.

config ISA_THUMB2
bool
# Omit prompt to signify "hidden" option
default n
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Redundant default n.

@galak
Copy link
Collaborator

galak commented Aug 6, 2018

@bbolen have you tried to see if you can port qemu and the xlnx-zynqmp platform?

@bbolen
Copy link
Collaborator Author

bbolen commented Aug 7, 2018

@ulfalizer Thanks for the comments. Those should all be fixed now.

@bbolen
Copy link
Collaborator Author

bbolen commented Aug 7, 2018

@galak I saw that yesterday trying to find a way for others to replicate my work. I will keep looking at it, but I can't guarantee when I may have something useful with respect to qemu.

Copy link
Collaborator

@ulfalizer ulfalizer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kconfig parts look good to me.

#define GIC_INT_WD 30
#define GIC_INT_IRQ 31

#define IRQ_TYPE_NONE 0x00000000
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that IRQ type should be set by DTS. This means that:

  • IRQ type definitions have to be exposed as DTS bindings.
  • YAML files should be updated accordingly.
  • Driver should set GICD_ICFGn basing on the flags specified in interrupt property.

#define NO_GIC_INT_PENDING 1023

/* CPU Interrupt numbers */
#define GIC_INT_GTMR 27
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Could we use here names which will be self-descriptive or easy to find in docs? (like GIC_INT_LEGACY_FIQ)
  • According to the CoreLink™ GIC-400 Generic Interrupt Controller Technical Reference Manual there is no watchdog interrupt at ID 30 (GIC_INT_WD suggests watchdog). Is watchdog on this line specific to your SoC?
  • IMHO these defines should be exposed to the DTS or some platform code which will use it (like timer driver).

* Set priority on PPI and SGI interrupts
*/
for (i = 0; i < 32; i += 4)
sys_write32(0xa0a0a0a0, GICD_IPRIORITYRn + i);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMHO priority should be taken from DTS.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see two possible paths to get the flags and priority from gic.c. 1) add an intr_set_priority() callback to the irq_next_level_api struct and call it from arch/arm/core/irq_manage.c:_irq_priority_set() OR 2) redefine _ARCH_IRQ_CONNECT for Cortex-R to pass flags_p instead of 0 to _ISR_DECLARE and get to the flags through the isr_sw_table.

Do you have a preference between these two, or another option?

arch/Kconfig Outdated
@@ -19,7 +19,6 @@ config ARC

config ARM
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMHO subject of the commit does not reflect actual change.
What about "arch: arm: Move thread_abort.c to cortex_m specific directory"?

@@ -4,7 +4,6 @@ zephyr_library_sources(
exc_exit.S
swap.c
swap_helper.S
fault.c
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here also you are moving file specific to cortex-m, but subject of the commit suggests cortex-r.

* Cortex-R only has one IRQ line so the main handler will be at
* offset 0 of the table.
*/
mov r0, #0
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you going to dispatch FIQ and IRQ using the same IRQ table?

@@ -140,7 +151,11 @@ SECTION_FUNC(TEXT, __pendsv)
str r3, [r4]
#else
ldr r0, [r2, #_thread_offset_to_basepri]
#ifdef CONFIG_CPU_CORTEX_M
movs.n r3, #0
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMHO we just could use "movs r3, #0" on both Cortex-M and Cortex-R

mov r4, lr

cps #MODE_SYS
stmdb sp!, {r0-r4}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about R12?

@@ -0,0 +1,158 @@
/* ARM Cortex-M GCC specific public inline assembler functions and macros */
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMHO with some modifications in _arch_irq_lock()/_arch_irq_unlock() this file could be common for Cortex-M and R.

Copy link
Member

@ioannisg ioannisg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Went through most of the /arch code; added a few comments about re-using code and about Kconfig options.

config CPU_CORTEX_R4
bool
select CPU_CORTEX_R
select ARMV7_R_ARMV8_R_MAINLINE
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this the right thing to do?
I mean: for Cortex-M, ARMv8-M_Mainline is a "super-set" of and backwards-compatible with ARMv7-M.
Is this true for ARMv7-R? Do ARMv7-R, ARMv8-R have the Baseline, Mainline versions?

If not, I would say, it is better to name the architecture as ARMV7_R


if CPU_CORTEX_R

config ISA_THUMB2
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree. There are several options that might be not-specific to ARM-R (instead, shared with ARM-M).
Could we move those options to arm/core/Kconfig, instead?

select ATOMIC_OPERATIONS_BUILTIN
select ISA_ARM
help
This option signifies the use of an ARMv7-R processor
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Coming back to this one: is this accurate for ARMv8-R? Are there Baseline and Mainline variations?

@@ -0,0 +1,37 @@
/*
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this file just copy-pasted from the cortex-m version of it?

@@ -0,0 +1,71 @@
/*
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had a quick look, and it seems to me that the only difference from Cortex-M is that we do not have the code block for the case of CONFIG_CPU_CORTEX_M_HAS_VTOR=y.

SYS_Stack:
.skip 1024 * 4

#define STACK_MARGIN 4
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

...And use them, directly in the linker script, perhaps, @pizi-nordic ?

*
* SPDX-License-Identifier: Apache-2.0
*/

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we re-use the Cortex-M scb.c file, instead?
And add this dummy implementation, if ARMv7_R is defined (instead of ARMv-M). Note, that this would move the scb.c one level up.

#include <arch/arm/cortex_m/cmsis.h>
#else
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps, it is better to have CONFIG_CPU_CORTEX_3 explicitly given, here.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same applies to more cases, below.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm sorry, I think I'm missing something here. I was assuming that this code applied to all Cortex-M's. Are you saying that it should only apply to the M3?

/* set pending bit to make sure we will take a PendSV exception */
SCB->ICSR |= SCB_ICSR_PENDSVSET_Msk;
#endif

/* clear mask or enable all irqs to take a pendsv */
irq_unlock(0);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this needed for Cortex-R?

@nashif nashif closed this Aug 11, 2018
@nashif nashif reopened this Aug 11, 2018
@bbolen bbolen force-pushed the cortex_r branch 2 times, most recently from a97a908 to 85a8ecf Compare August 14, 2018 18:08
@bbolen
Copy link
Collaborator Author

bbolen commented Aug 14, 2018

@pizi-nordic @ioannisg I've updated this PR with changes to address your comments.

@SebastianBoe SebastianBoe removed their request for review August 16, 2018 07:39
Copy link
Member

@ioannisg ioannisg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some more suggestions and issues/questions.

One general thing: Please, use #if defined (), instead of #ifdef in the arm/core and include/ sub-trees

help
This option signifies the use of an ARMv7-R processor
implementation, or the use of an ARMv8-R processor
implementation supporting the Main Extension.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please, clarify: does the -R- architecture have Base and Mainline versions for v8? If not, the help text needs update

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Btw, I searched a bit and I didn't see clear indication of Baseline, Mainline terminology outside the -M- architecture...

referred to as a Mainline Implementation.
- ARMv7-R compatibility requires the Main Extension.

From https://developer.arm.com/products/architecture/m-profile:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Link points to -M- documentation

depends on ARMV7_R
help
This option signifies the use of an ARMv7-R processor
implementation, or the use of an ARMv8-R processor
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ARMv8 is not reflected in the symbol name.

bool
select CPU_CORTEX_R
select ARMV7_R
select ARMV7_M_ARMV8_M_FP if CPU_HAS_FPU
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ARMV7_M_ARMV8_M_FP is for Cortex-M CPUs

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm sorry. Most of this is just copy-paste crud that I'll get rid of.

@@ -120,7 +124,8 @@ SECTION_FUNC(TEXT, k_cpu_idle)
mov lr, r0
#endif

#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE)
#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) \
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This, here (and right below on line 180/185) look a bit weird; ARMV7_R is "grouped" together with ARMV6_M, instead of ARMV7_M.

If this is indeed correct, and needs to be as is, it will confuse the reader.
Any suggestion how to address this, @galak ?


#ifdef CONFIG_PREEMPT_ENABLED
ldr r0, =_kernel

ldr r1, [r0, #_kernel_offset_to_current]

ldr r0, [r0, _kernel_offset_to_ready_q_cache]
ldr r0, [r0, #_kernel_offset_to_ready_q_cache]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What was the reason for this?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using the zephyr-sdk, I get a compile error
src/zephyr/arch/arm/core/exc_exit.S: Assembler messages:
src/zephyr/arch/arm/core/exc_exit.S:82: Error: immediate expression requires a # prefix -- `ldr r0,[r0,(0x1c+0x0)]' since _kernel_offset_to_ready_q_cache is an immediate value. I can't really say why the M boards do not see this.

@@ -140,7 +151,7 @@ SECTION_FUNC(TEXT, __pendsv)
str r3, [r4]
#else
ldr r0, [r2, #_thread_offset_to_basepri]
movs.n r3, #0
movs r3, #0
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is the reason for this change?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, compile error when using the SDK for Cortex-R
src/zephyr/arch/arm/core/swap_helper.S: Assembler messages:
src/zephyr/arch/arm/core/swap_helper.S:158: Error: unexpected character n' in type specifier src/zephyr/arch/arm/core/swap_helper.S:158: Error: bad instruction movs.n r3,#0'

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@galak ^^

flash: 256
testing:
default: false
ignore_tags:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure why these tags are all ignored

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently, the cortex R5 on the xlnx-zynmp qemu machine is not hooked up to an interrupt controller, so only the "hello world" test case will run right now.

Copy link
Member

@ioannisg ioannisg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Went through the PR, looks OK to me. I still left several comments to address, but, just to try to push this for 2.0, I give a +1

@ioannisg
Copy link
Member

ioannisg commented Aug 9, 2019

@bbolen I suppose if you rebase once more you can run CI with the new SDK, Qemu.

@galak galak mentioned this pull request Aug 9, 2019
48 tasks
@ioannisg
Copy link
Member

ioannisg commented Aug 9, 2019

@andrewboie @galak could you have another look?
@bbolen could you rebase to latest master?

Bradley Bolen and others added 12 commits August 9, 2019 10:56
Provide a path for irq controller drivers to change properties of an
individual irq using priority and flags fields that come from the device
tree.

Signed-off-by: Bradley Bolen <[email protected]>
The GIC400 is a common interrupt controller that can be used with the
Cortex A and R series processors.  This patch adds basic interrupt
handling for the GIC, but does not handle multiple routing or
priorities.

Signed-off-by: Bradley Bolen <[email protected]>
This reverts commit e20fd5f.

This is needed for Cortex-R support.

Signed-off-by: Bradley Bolen <[email protected]>
This adds initial Cortex-R support for interrupts and context switching.

Signed-off-by: Bradley Bolen <[email protected]>
Cortex R has a write buffer that can cause reordering problems when
accessing memory mapped registers.  Use memory barries to make sure that
these accesses are performed in the desired order.

Signed-off-by: Bradley Bolen <[email protected]>
Pass the correct -march and -mcpu flags to the compiler when building
for the Cortex-R4.

Signed-off-by: Bradley Bolen <[email protected]>
Pass the correct -mcpu flags to the compiler when building for the
Cortex-R5.

Signed-off-by: Bradley Bolen <[email protected]>
Add ZynqMP PS uart driver for Xilinx ZynqMP platform

Signed-off-by: Wendy Liang <[email protected]>
Add Xilinx PS ttc timer for Xilinx ZynqMP platform.

Signed-off-by: Wendy Liang <[email protected]>
This commit adds support for the Zynq UltraScale+ MPSoC as a qemu based
platform for Cortex-R based testing.  This SoC only supports an
interrupt controller and serial port for limited testing.

Signed-off-by: Bradley Bolen <[email protected]>
This adds a qemu test board using the Xilinx ZynqMP SoC.

Signed-off-by: Bradley Bolen <[email protected]>
The xlnx-zcu102 qemu machine is the only one that supports a Cortex-R
processor.  However, its main CPUs are Cortex A53s which requires the
aarch64 qemu binary to run.

Signed-off-by: Bradley Bolen <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: API Changes to public APIs area: Architectures area: ARM ARM (32-bit) Architecture area: Boards area: Build System area: Devicetree area: Kernel area: Test Framework Issues related not to a particular test, but to the framework instead area: Tests Issues related to a particular existing or missing test area: Timer Timer Feature A planned feature with a milestone RFC Request For Comments: want input from the community
Projects
None yet
Development

Successfully merging this pull request may close these issues.

ARM Cortex R Architecture support Any plans to support on Cortex-R5 CPU such as those in Xilinx MPSoC