Skip to content

cpu/cortex-m: turn MPU support into a feature#13391

Merged
aabadie merged 4 commits intoRIOT-OS:masterfrom
kaspar030:mpu_feature
Mar 4, 2020
Merged

cpu/cortex-m: turn MPU support into a feature#13391
aabadie merged 4 commits intoRIOT-OS:masterfrom
kaspar030:mpu_feature

Conversation

@kaspar030
Copy link
Contributor

Contribution description

This turns the MPU of Cortex-M into a feature.

Testing procedure

Issues/PRs references

@kaspar030 kaspar030 added Platform: ARM Platform: This PR/issue effects ARM-based platforms Area: build system Area: Build system CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR Area: security Area: Security-related libraries and subsystems labels Feb 17, 2020
@kaspar030 kaspar030 changed the title cpu/corrtex-m: turn MPU support into a feature [WIP] cpu/cortex-m: turn MPU support into a feature [WIP] Feb 17, 2020
Comment on lines +9 to +11
ifneq ($(CPU_ARCH),cortex-m0)
FEATURES_PROVIDED += cortexm_mpu
endif
Copy link
Contributor

@benpicco benpicco Feb 17, 2020

Choose a reason for hiding this comment

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

According to Wikipedia, the MPU is always optional. It's up to the chip vendor whether to include it or not.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hmok. Do all our non-cm0 CPUs have an MCU?
I'll add a check to the mpu test application.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've added a check. Seems like all our non-Cortex-M0 boards have an MPU, or at leastm __MPU_PRESENT set.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Either __MPU_PRESENT is not undefined, or all our Cortex-M boards do have the optional MPU, even the CM0. @aabadie Could you verify the test succeeds e.g., on a stm32f031k6?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@aabadie could you take a look at this? I don't have a M0 board...

Copy link
Contributor

Choose a reason for hiding this comment

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

I tried on nucleo-f072rb, which is an M0, and the tests/mpu_stack_guard is correctly skipped by the build system.

The problem here is that, according to the __MPU_PRESENT macro in vendor files, stm32f1 and also some stm32f3 (so not all) CPUs doesn't provide an MPU. It's also unclear if stm32l0 provides an MPU or not (I'm wondering if the vendor files were manually altered for this family).

So, as suggested by @benpicco, I think this feature should be provided by default less widely. Maybe just for M4/M7 by default, and enable on a case-by-case basis for other CPU families (M0/M0plus,M3).

Copy link
Contributor

Choose a reason for hiding this comment

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

I just checked the data sheets, neither samd2x nor saml2x (cm0p) implement an MPU.

@@ -1,3 +1,4 @@
BOARD_INSUFFICIENT_MEMORY := \
nucleo-f031k6 \
Copy link
Contributor

@aabadie aabadie Feb 17, 2020

Choose a reason for hiding this comment

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

This board (and stm32f030f4-demo) is already excluded by the FEATURES_REQUIRED += cortexm_mpu and should already be marked as unsupported by the CI. Why do you add it here ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hm, seems like the feature guard doesn't work:

[kaspar@ng riot.tmp/tests/mpu_stack_guard (mpu_feature)]$ make info-boards-supported | grep -o nucleo-f031k6
nucleo-f031k6
[kaspar@ng riot.tmp/tests/mpu_stack_guard (mpu_feature)]$ 
[kaspar@ng riot.tmp/tests/mpu_stack_guard (mpu_feature)]$ BOARD=nucleo-f031k6 make info-debug-variable-CPU_ARCH
cortex-m0
[kaspar@ng riot.tmp/tests/mpu_stack_guard (mpu_feature)]$

Seems like CPU_ARCH is not available in Makefile.features.

Copy link
Contributor

@aabadie aabadie Feb 17, 2020

Choose a reason for hiding this comment

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

It seems that this PR requires some changes from #13236 where CPU_ARCH is moved to Makefile.features. I can cut this part out of #13236 if it also helps here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I can cut this part out of #13236 if it also helps here.

That would be awesome.

Copy link
Contributor

Choose a reason for hiding this comment

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

Here it is: #13392 :)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks a bunch.

[kaspar@ng riot.tmp/tests/mpu_stack_guard (mpu_feature)]$ make info-boards-supported | grep -o nucleo-f031k6
[kaspar@ng riot.tmp/tests/mpu_stack_guard (mpu_feature)]$

@benpicco
Copy link
Contributor

So this needs a rebase now.

@kaspar030 kaspar030 changed the title cpu/cortex-m: turn MPU support into a feature [WIP] cpu/cortex-m: turn MPU support into a feature Feb 18, 2020
@kaspar030
Copy link
Contributor Author

So this needs a rebase now.

Done. Removed an unrelated ssp change, and renamed the WIP commit.

@kaspar030
Copy link
Contributor Author

  • fixed long commit msg

@benpicco benpicco added CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR and removed CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR labels Feb 20, 2020
@kaspar030 kaspar030 added CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR and removed CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR labels Feb 24, 2020
@aabadie aabadie self-assigned this Feb 25, 2020
Copy link
Contributor

@aabadie aabadie left a comment

Choose a reason for hiding this comment

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

I think this PR cannot be merged in the current state: we should check more precisely which CPUs (family or even specific CPUs) provide an MPU or not. It seems some families doesn't provide an MPU (M0) or even not all CPUs of a given family (M3). For M4/M7, all CPUs seems to provide an MPU.

I also don't think the check on __MPU_PRESENT macro is needed as it seems to be defined to 0 if not already defined (can be verified with git grep __MPU_PRESENT).

Comment on lines +9 to +11
ifneq ($(CPU_ARCH),cortex-m0)
FEATURES_PROVIDED += cortexm_mpu
endif
Copy link
Contributor

Choose a reason for hiding this comment

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

I tried on nucleo-f072rb, which is an M0, and the tests/mpu_stack_guard is correctly skipped by the build system.

The problem here is that, according to the __MPU_PRESENT macro in vendor files, stm32f1 and also some stm32f3 (so not all) CPUs doesn't provide an MPU. It's also unclear if stm32l0 provides an MPU or not (I'm wondering if the vendor files were manually altered for this family).

So, as suggested by @benpicco, I think this feature should be provided by default less widely. Maybe just for M4/M7 by default, and enable on a case-by-case basis for other CPU families (M0/M0plus,M3).

@kaspar030
Copy link
Contributor Author

So, as suggested by @benpicco, I think this feature should be provided by default less widely. Maybe just for M4/M7 by default, and enable on a case-by-case basis for other CPU families (M0/M0plus,M3).

Even for M4 this seems to not not always be available (e.g., stm32f302r8 is an M4, but doesn't set __MPU_PRESENT). Seaveing through all CPU's is quite a hassle.

I'm inclined to define this per-board, as that can be done quickly (by, e.g., use the buildtest output of all cortex-m, then add the feature to all board Makefile.features where it succeeded).
We can then move it to more common places later on.

@aabadie what do you think?

@aabadie
Copy link
Contributor

aabadie commented Feb 25, 2020

what do you think?

I agree that the feature should be provided more finely. Maybe provide the feature in whitelisted board as a first step ? (and no need to wait for buildtest ;))

@benpicco
Copy link
Contributor

Seaveing through all CPU's is quite a hassle.

We can just add it to known-good CPU families for now, it's easy to fix omissions later.
E.g. I think it's save to assume no stm32f3 has a MPU.

I'm inclined to define this per-board

But this is not a board feature. We should get rid of MCU features in boards, not add more of those.

@kaspar030
Copy link
Contributor Author

E.g. I think it's save to assume no stm32f3 has a MPU.

Hmm,

(e.g., stm32f302r8 is an M4, but doesn't set __MPU_PRESENT).

@kaspar030
Copy link
Contributor Author

But this is not a board feature. We should get rid of MCU features in boards, not add more of those.

Agreed, but the way our build configuration is modeled, there's no way to print the tree of dependencies (board -> cpu -> cpu_fam -> cpu_arch), and there are many layers of includes with non-standard names.

I can do the manual equivalent of make buildtest | grep succeeded | cut -d" " -f3 to get a list of boards that work, and with that I can do for board in $BOARDS; do echo "FEATURES_PROVIDED += cortexm_mpu" >> boards/$BOARD/Makefile.features, then cleanup the result.

Doing it "the right way" will take maybe a day? We'd have to go through all ~180 board Makefiles, figure out which CPU family they're in, try to find commonalities, build, refine.

@benpicco
Copy link
Contributor

E.g. I think it's save to assume no stm32f3 has a MPU.

Hmm,

(e.g., stm32f302r8 is an M4, but doesn't set __MPU_PRESENT).

I see no contradiction 😉

Doing it "the right way" will take maybe a day? We'd have to go through all ~180 board Makefiles, figure out which CPU family they're in, try to find commonalities, build, refine.

I'm not advocating for a complete list, just adding FEATURES_PROVIDED += cortexm_mpu to the hand full of families where we know it's present.
Sure we'll miss some, but if people want to use the MPU on these boards they can add the FEATURES_PROVIDED += cortexm_mpu.

@kaspar030
Copy link
Contributor Author

I'm not advocating for a complete list, just adding FEATURES_PROVIDED += cortexm_mpu to the hand full of families where we know it's present.

Makes sense. Which ones are those?

@benpicco
Copy link
Contributor

benpicco commented Feb 25, 2020

Which ones are those?

stm32f4 (checked the smallest member of the family), stm32l4 (dito), nrf51, nrf52, samd5x, cc26x2_cc13x2, lm4f120, sam3, saml1x, cc2538

@kaspar030
Copy link
Contributor Author

stm32f4 (checked the smallest member of the family), stm32l4 (dito), nrf51, nrf52, samd5x, cc26x2_cc13x2, lm4f120, sam3, saml1x, cc2538

Done. Removed nrf51, they don't have an MPU.

@benpicco
Copy link
Contributor

benpicco commented Mar 2, 2020

Removed nrf51, they don't have an MPU.

The Data Sheet has a chapter about an MPU though.

@kaspar030
Copy link
Contributor Author

The Data Sheet has a chapter about an MPU though.

Hm, maybe it is non-standard. The CMSIS headers define __MPU_PRESENT to 0, and if forced to 1, compilation fails, e.g.,:

/home/kaspar/src/riot/cpu/cortexm_common/mpu.c: In function 'mpu_disable':
/home/kaspar/src/riot/cpu/cortexm_common/mpu.c:28:5: error: 'MPU' undeclared (first use in this function); did you mean 'MPU_H'?
   28 |     MPU->CTRL &= ~MPU_CTRL_ENABLE_Msk;
      |     ^~~                                                                                                                  
      |     MPU_H                                               

Seems like "MPU" is what Nordic calls flash protection:

The memory protection unit can be configured to protect all flash memory on the device from readback, or to protect blocks of flash from over-write or erase.

Copy link
Contributor

@aabadie aabadie left a comment

Choose a reason for hiding this comment

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

Could FEATURES_PROVIDED += cortexm_mpu be also added to stm32f1, stm32f2 and stm32l1 ?
(initially iotlab-*, nucleo-l152re and nucleo-207zg were whitelisted in the test).

@kaspar030
Copy link
Contributor Author

Could FEATURES_PROVIDED += cortexm_mpu be also added to stm32f1, stm32f2 and stm32l1 ?
(initially iotlab-*, nucleo-l152re and nucleo-207zg were whitelisted in the test).

Added the stm32f2 and l1. The others don't define __MPU_PRESENT.

@aabadie
Copy link
Contributor

aabadie commented Mar 3, 2020

Added the stm32f2 and l1

Did you forget to push ?

@kaspar030
Copy link
Contributor Author

Did you forget to push ?

yup :)

@kaspar030
Copy link
Contributor Author

There are some missing that where whitelisted before and actually work. Will add them.

@kaspar030
Copy link
Contributor Author

Now I got them all. Special cases were: some stm32f303 and some stm32l052 have an MPU.
The PR now covers all CPU's in master.
It was not so bad, thanks for pushing @benpicco @aabadie.

Copy link
Contributor

@aabadie aabadie left a comment

Choose a reason for hiding this comment

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

ACK and go!

@aabadie aabadie merged commit 68ec8b2 into RIOT-OS:master Mar 4, 2020
@leandrolanzieri leandrolanzieri added the Type: enhancement The issue suggests enhanceable parts / The PR enhances parts of the codebase / documentation label Mar 13, 2020
@leandrolanzieri leandrolanzieri added this to the Release 2020.04 milestone Mar 13, 2020
@kaspar030 kaspar030 deleted the mpu_feature branch March 30, 2020 19:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area: build system Area: Build system Area: security Area: Security-related libraries and subsystems CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR Platform: ARM Platform: This PR/issue effects ARM-based platforms Type: enhancement The issue suggests enhanceable parts / The PR enhances parts of the codebase / documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants