Porting to Cortex-M0+


Nashif, Anas
 

See https://gerrit.zephyrproject.org/r/4160 for the maintainers.

Anas

On 18/08/2016, 11:00, "Jon Medhurst (Tixy)" <tixy(a)linaro.org> wrote:

On Wed, 2016-08-17 at 14:13 -0400, Benjamin Walsh wrote:
> > > I also want to add an ARCH_ARMV6, V7 etc to handle architecture
> > > specific code. We still need the more specific CPU_CORTEX_M0PLUS,
> 3,
> > > 4, etc because each cpu has different features.
>
> > Sounds reasonable to me. (I'm new around here though, so don't count
> > that as anything other than a random opinion ;-)
>
> Sounds reasonable to me as well. I'd like to hear from the ARM
> maintainers to get their opinion too.

Which reminds me to ask... who _are_ the ARM maintainers and how do we
find out such things given that the MAINTAINERS file in the source tree
is somewhat deficient in coverage?

--
Tixy


Jon Medhurst (Tixy) <tixy@...>
 

On Wed, 2016-08-17 at 14:13 -0400, Benjamin Walsh wrote:
I also want to add an ARCH_ARMV6, V7 etc to handle architecture
specific code. We still need the more specific CPU_CORTEX_M0PLUS,
3,
4, etc because each cpu has different features.
Sounds reasonable to me. (I'm new around here though, so don't count
that as anything other than a random opinion ;-)
Sounds reasonable to me as well. I'd like to hear from the ARM
maintainers to get their opinion too.
Which reminds me to ask... who _are_ the ARM maintainers and how do we
find out such things given that the MAINTAINERS file in the source tree
is somewhat deficient in coverage?

--
Tixy


Benjamin Walsh <benjamin.walsh@...>
 

On Wed, Aug 17, 2016 at 02:36:07PM +0100, Jon Medhurst (Tixy) wrote:
On Wed, 2016-08-17 at 09:40 +0000, Euan Mutch wrote:
I am thinking either, CPU_HAS_BASEPRI or ARCH_HAS_BASEPRI.
No objection from me.

I also want to add an ARCH_ARMV6, V7 etc to handle architecture
specific code. We still need the more specific CPU_CORTEX_M0PLUS, 3,
4, etc because each cpu has different features.
Sounds reasonable to me. (I'm new around here though, so don't count
that as anything other than a random opinion ;-)
Sounds reasonable to me as well. I'd like to hear from the ARM
maintainers to get their opinion too.

My main thought was that boards/SoCs select a CPU type which then
selects the individual feature that CPU supports. That way, core kernel
changes are decoupled better from people's board/SoC definitions which
don't have to break when kernel changes are made.
Cheers,
Ben


Jon Medhurst (Tixy) <tixy@...>
 

On Wed, 2016-08-17 at 09:40 +0000, Euan Mutch wrote:
I am thinking either, CPU_HAS_BASEPRI or ARCH_HAS_BASEPRI.

I also want to add an ARCH_ARMV6, V7 etc to handle architecture
specific code. We still need the more specific CPU_CORTEX_M0PLUS, 3,
4, etc because each cpu has different features.
Sounds reasonable to me. (I'm new around here though, so don't count
that as anything other than a random opinion ;-)

My main thought was that boards/SoCs select a CPU type which then
selects the individual feature that CPU supports. That way, core kernel
changes are decoupled better from people's board/SoC definitions which
don't have to break when kernel changes are made.

--
Tixy


Euan Mutch <euan.mutch@...>
 

TIxy,
I am thinking either, CPU_HAS_BASEPRI or ARCH_HAS_BASEPRI.

I also want to add an ARCH_ARMV6, V7 etc to handle architecture specific code. We still need the more specific CPU_CORTEX_M0PLUS, 3, 4, etc because each cpu has different features.

Ricardo,
I am hoping to push the finished port back to the community. Although it might not be finished for a litle while yet!

I now have my M0+ board (SAMD20 Xplained Pro) and have managed to program it with zephyr using Atmel Studio. So far it gets to main and can run C code, but not much else.


Ricardo Salveti <ricardo.salveti@...>
 

Hi Euan,

On Thu, Aug 4, 2016 at 6:00 AM, Euan Mutch <euan.mutch(a)gmail.com> wrote:
Hi Ben,

That seems to be working properly now with the interrupts being disabled.

We might be able to merge the M0 and
M3/M4 implementations as well.
I have been trying to make sure that anything I change still works on M3/M4
and will add config options where a common approach would not work.
I was looking at what would take to get Zephyr to support Cortex-M0
today (wanted to port Zephyr to nRF51), and found your thread :-)

Are you expecting to open source/upstream your Cortex M0+ based port?
Wanted to avoid duplicating this effort, as the M0 port would be quite
similar with M0+. Happy to test/review your implementation as well.

Thanks,
--
Ricardo Salveti


Jon Medhurst (Tixy) <tixy@...>
 

Top posting made this conversation difficult to follow and quote, so
I'll heavily edit and paraphrase...

Euan said:
Got some problems with _Swap() when porting to Cortex M0+

Ben said:
You have to use PRIMASK instead of BASEPRI as well for the
interrupt locking, since there is no BASEPRI on M0 (IIRC)
We might be able to merge the M0 and M3/M4 implementations as well.

Euan said:
I created a new board and soc for the M0+ I will be using... then
replaced all occurrences of BASEPRI with PRIMASK.

I have been trying to make sure that anything I change still works
on M3/M4 and will add config options where a common approach would
not work.
One thing that may be relevant here is that with the advent of ARMv8-M,
differences like presence of BASEPRI etc are predicated on whether the
CPU implements the 'Main Extension'. The ARM ARM [1] also refers to
Mainline and Baseline implementation.

So, I just wanted to suggest that if any work is going on to support M0+
then if the temptation is to have something like

#ifndef CONFIG_CORTEX_M0PLUS
use BASEPRI
#else
do something different
#endif

Probably best to instead have the test above check
CONFIG_CORTEXM_HAVE_BASEPRI and get Cortex M3 etc to select that.
(Or have a negative config DONT_HAVE_BASEPRI and/or or have some clever
kconfig defaults, whatever seems best). If we do that the we can more
easily add support for v8-M devices.

I hit the lack of BASEPRI issue booting Zephyr on a v8-M emulator [2]
which defaulted to Baseline implementation. Fortunately it had a
commandline option to select Mainline so I could ignore the problem for
the time being :-)

[1] https://silver.arm.com/download/download.tm?pv=3394548&p=1610307
(Free registration required)

[2] https://developer.arm.com/products/system-design/fixed-virtual-platforms#AllFVPS
(Licence required to run emulators).

--
Tixy


Euan Mutch <euan.mutch@...>
 

Hi Ben,

That seems to be working properly now with the interrupts being disabled.

We might be able to merge the M0 and
M3/M4 implementations as well.
I have been trying to make sure that anything I change still works on M3/M4
and will add config options where a common approach would not work.

Thanks,
Euan


On Tue, Aug 2, 2016 at 10:05 PM, Euan Mutch <euan.mutch(a)gmail.com> wrote:

Hi Ben,

I created a new board and soc for the M0+ I will be using, then just fixed
all the compiler errors with the M3/M4 assembler.
Then replaced all occurrences of BASEPRI with PRIMASK.

I don't have the M0+ yet so I have been testing on a Arduino Due in the
mean time and after changing all that it still seems to work fine (although
its not an M0+ so we will see)
Will try pending the PendSV exception tomorrow and see if that works!

Thanks,
Euan

On Tue, Aug 2, 2016 at 8:38 PM, Benjamin Walsh <
benjamin.walsh(a)windriver.com> wrote:

Hi Euan,

I am in the process of porting Zephyr to Cortex-M0+, the problem is
that for the M0+ if you use a Supervisor Call (SVC) with interrupts
disabled, since there is no interrupt masking either, then the
Supervisor Call will generate a hard fault.

Which means that every time _Swap() is called it hard faults.

Currently I have managed to get round this by just commenting out the
disabling of interrupts before _Swap() is called. However I don't
think this is a viable long term solution!
Indeed, it is not. :)

Do I have to rewrite _Swap() to not use SVC or is there another way to
do it that I have missed?
You have to take another approach in this case. I _think_ you can simply
pend the PendSV exception instead, and then unlock interrupts.

You have to use PRIMASK instead of BASEPRI as well for the interrupt
locking, since there is no BASEPRI on M0 (IIRC). Some of the ARM arch
code has to be adapted to that as well.

The SVC handler for M3/M4 does not do much more work than that anyway
(apart from the IRQ offload). We might be able to merge the M0 and
M3/M4 implementations as well.

HTH,
Ben


Euan Mutch <euan.mutch@...>
 

Hi Ben,

I created a new board and soc for the M0+ I will be using, then just fixed
all the compiler errors with the M3/M4 assembler.
Then replaced all occurrences of BASEPRI with PRIMASK.

I don't have the M0+ yet so I have been testing on a Arduino Due in the
mean time and after changing all that it still seems to work fine (although
its not an M0+ so we will see)
Will try pending the PendSV exception tomorrow and see if that works!

Thanks,
Euan

On Tue, Aug 2, 2016 at 8:38 PM, Benjamin Walsh <benjamin.walsh(a)windriver.com
wrote:
Hi Euan,

I am in the process of porting Zephyr to Cortex-M0+, the problem is
that for the M0+ if you use a Supervisor Call (SVC) with interrupts
disabled, since there is no interrupt masking either, then the
Supervisor Call will generate a hard fault.

Which means that every time _Swap() is called it hard faults.

Currently I have managed to get round this by just commenting out the
disabling of interrupts before _Swap() is called. However I don't
think this is a viable long term solution!
Indeed, it is not. :)

Do I have to rewrite _Swap() to not use SVC or is there another way to
do it that I have missed?
You have to take another approach in this case. I _think_ you can simply
pend the PendSV exception instead, and then unlock interrupts.

You have to use PRIMASK instead of BASEPRI as well for the interrupt
locking, since there is no BASEPRI on M0 (IIRC). Some of the ARM arch
code has to be adapted to that as well.

The SVC handler for M3/M4 does not do much more work than that anyway
(apart from the IRQ offload). We might be able to merge the M0 and
M3/M4 implementations as well.

HTH,
Ben


Benjamin Walsh <benjamin.walsh@...>
 

Hi Euan,

I am in the process of porting Zephyr to Cortex-M0+, the problem is
that for the M0+ if you use a Supervisor Call (SVC) with interrupts
disabled, since there is no interrupt masking either, then the
Supervisor Call will generate a hard fault.

Which means that every time _Swap() is called it hard faults.

Currently I have managed to get round this by just commenting out the
disabling of interrupts before _Swap() is called. However I don't
think this is a viable long term solution!
Indeed, it is not. :)

Do I have to rewrite _Swap() to not use SVC or is there another way to
do it that I have missed?
You have to take another approach in this case. I _think_ you can simply
pend the PendSV exception instead, and then unlock interrupts.

You have to use PRIMASK instead of BASEPRI as well for the interrupt
locking, since there is no BASEPRI on M0 (IIRC). Some of the ARM arch
code has to be adapted to that as well.

The SVC handler for M3/M4 does not do much more work than that anyway
(apart from the IRQ offload). We might be able to merge the M0 and
M3/M4 implementations as well.

HTH,
Ben


Boie, Andrew P
 

On Mon, 2016-08-01 at 13:34 +0000, Euan Mutch wrote:
Do I have to rewrite _Swap() to not use SVC or is there another way 
to do it that I have missed?
I am not too deeply familiar with ARM arch code. Ben Walsh would be the
person to talk to. I believe he gets back from sabbatical today
although it may take him some time to get through all his email.

Andrew


Euan Mutch <euan.mutch@...>
 

Hi,

I am in the process of porting Zephyr to Cortex-M0+, the problem is that for the M0+ if you use a Supervisor Call (SVC) with interrupts disabled, since there is no interrupt masking either, then the Supervisor Call will generate a hard fault.

Which means that every time _Swap() is called it hard faults.

Currently I have managed to get round this by just commenting out the disabling of interrupts before _Swap() is called. However I don't think this is a viable long term solution!

Do I have to rewrite _Swap() to not use SVC or is there another way to do it that I have missed?

Thanks,
Euan