Select one of the symbols to view example projects that use it.
 
Outline
#include "pico/runtime.h"
#include "hardware/structs/mpu.h"
#include "hardware/riscv.h"
runtime_init_per_core_install_stack_guard(void *)
Files
loading...
SourceVuRaspberry Pi Pico SDK and ExamplesPicoSDKsrc/rp2_common/pico_runtime_init/runtime_init_stack_guard.c
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
#include "pico/runtime.h" #if !PICO_RUNTIME_NO_INIT_PER_CORE_INSTALL_STACK_GUARD #if PICO_RP2040 #include "hardware/structs/mpu.h" #elif defined(__riscv) #include "hardware/riscv.h" #endif // this is called for each thread since they have their own MPU void runtime_init_per_core_install_stack_guard(void *stack_bottom) { // this is called b4 runtime_init is complete, so beware printf or assert uintptr_t addr = (uintptr_t) stack_bottom; // the minimum we can protect is 32 bytes on a 32 byte boundary, so round up which will // just shorten the valid stack range a tad addr = (addr + 31u) & ~31u; #if PICO_RP2040 // Armv6-M MPU // make sure no one is using the MPU yet if (mpu_hw->ctrl) { // Note that it would be tempting to change this to a panic, but it happens so early, printing is not a good idea __breakpoint(); }if (mpu_hw->ctrl) { ... } // mask is 1 bit per 32 bytes of the 256 byte range... clear the bit for the segment we want uint32_t subregion_select = 0xffu ^ (1u << ((addr >> 5u) & 7u)); mpu_hw->ctrl = 5; // enable mpu with background default map mpu_hw->rbar = (addr & (uint)~0xff) | M0PLUS_MPU_RBAR_VALID_BITS | 0; mpu_hw->rasr = 1 // enable region | (0x7 << 1) // size 2^(7 + 1) = 256 | (subregion_select << 8) | 0x10000000; // XN = disable instruction fetch; no other bits means no permissions /* ... */ #elif defined(__riscv) #if !PICO_RP2350 #error "Check PMP configuration for new platform" #endif // RISC-V PMP, RP2350 configuration of Hazard3: 8 non-hardwired regions, // NAPOT only, 32-byte granule, with nonstandard PMPCFGM0 register to // apply regions to M-mode without locking them. // Make sure no one is using the PMP yet bool dirty_pmp = riscv_read_csr(pmpcfg0) != 0 || riscv_read_csr(pmpcfg1) != 0 || riscv_read_csr(RVCSR_PMPCFGM0_OFFSET) != 0; if (dirty_pmp) { __breakpoint(); }if (dirty_pmp) { ... } // Note pmpaddr is in units of 4 bytes, so right-shift 2. riscv_write_csr(pmpaddr0, (addr | 0x0fu) >> 2); // Make this region inaccessible in both M-mode and U-mode (but don't lock it) riscv_write_csr(RVCSR_PMPCFGM0_OFFSET, 0x1u); riscv_write_csr(pmpcfg0, RVCSR_PMPCFG0_R0_A_VALUE_NAPOT << RVCSR_PMPCFG0_R0_A_LSB); /* ... */ #else // // Armv8-M MPU // // make sure no one is using the MPU yet // if (mpu_hw->ctrl) { // __breakpoint(); // } // mpu_hw->rnr = 0; // // Read-only, privileged-only, nonexecutable. (Good enough because stack // // is usually written first, on a stack push) // mpu_hw->rbar = addr | (2u << M33_MPU_RBAR_AP_LSB) | (M33_MPU_RBAR_XN_BITS); // mpu_hw->rlar = addr | M33_MPU_RLAR_EN_BITS; // // Enable MPU (and leave default attributes applied even for privileged software) // mpu_hw->ctrl = M33_MPU_CTRL_PRIVDEFENA_BITS | M33_MPU_CTRL_ENABLE_BITS; pico_default_asm_volatile( "msr msplim, %0" : : "r" (stack_bottom));/* ... */ #endif }{ ... } /* ... */#endif
Details
Show:
from
Types: Columns:
This file uses the notable symbols shown below. Click anywhere in the file to view more details.