1 // Copyright 2021 The Pigweed Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not 4 // use this file except in compliance with the License. You may obtain a copy of 5 // the License at 6 // 7 // https://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 // License for the specific language governing permissions and limitations under 13 // the License. 14 15 #pragma once 16 17 #include <cstdint> 18 19 #include "pw_preprocessor/arch.h" 20 21 namespace pw::cpu_exception::cortex_m { 22 23 // CMSIS/Cortex-M/ARMv7 related constants. 24 // These values are from the ARMv7-M Architecture Reference Manual DDI 0403E.b. 25 // https://static.docs.arm.com/ddi0403/e/DDI0403E_B_armv7m_arm.pdf 26 27 constexpr uint32_t kThreadModeIsrNum = 0x0; 28 constexpr uint32_t kNmiIsrNum = 0x2; 29 constexpr uint32_t kHardFaultIsrNum = 0x3; 30 constexpr uint32_t kMemFaultIsrNum = 0x4; 31 constexpr uint32_t kBusFaultIsrNum = 0x5; 32 constexpr uint32_t kUsageFaultIsrNum = 0x6; 33 34 // Masks for Interrupt Control and State Register ICSR (ARMv7-M Section B3.2.4) 35 constexpr uint32_t kIcsrVectactiveMask = (1 << 9) - 1; 36 37 // Masks for individual bits of HFSR. (ARMv7-M Section B3.2.16) 38 constexpr uint32_t kHfsrForcedMask = (0x1 << 30); 39 40 // Masks for different sections of CFSR. (ARMv7-M Section B3.2.15) 41 constexpr uint32_t kCfsrMemFaultMask = 0x000000ff; 42 constexpr uint32_t kCfsrBusFaultMask = 0x0000ff00; 43 constexpr uint32_t kCfsrUsageFaultMask = 0xffff0000; 44 45 // Masks for individual bits of CFSR. (ARMv7-M Section B3.2.15) 46 // Memory faults (MemManage Status Register) 47 constexpr uint32_t kCfsrMemFaultStart = (0x1); 48 constexpr uint32_t kCfsrIaccviolMask = (kCfsrMemFaultStart << 0); 49 constexpr uint32_t kCfsrDaccviolMask = (kCfsrMemFaultStart << 1); 50 constexpr uint32_t kCfsrMunstkerrMask = (kCfsrMemFaultStart << 3); 51 constexpr uint32_t kCfsrMstkerrMask = (kCfsrMemFaultStart << 4); 52 constexpr uint32_t kCfsrMlsperrMask = (kCfsrMemFaultStart << 5); 53 constexpr uint32_t kCfsrMmarvalidMask = (kCfsrMemFaultStart << 7); 54 // Mask for all supported memory error flags i.e. bits that indicate a specific 55 // error. 56 constexpr uint32_t kCfsrMemAllErrorsMask = 57 kCfsrIaccviolMask | kCfsrDaccviolMask | kCfsrMunstkerrMask | 58 kCfsrMstkerrMask | kCfsrMlsperrMask; 59 // Bus faults (BusFault Status Register) 60 constexpr uint32_t kCfsrBusFaultStart = (0x1 << 8); 61 constexpr uint32_t kCfsrIbuserrMask = (kCfsrBusFaultStart << 0); 62 constexpr uint32_t kCfsrPreciserrMask = (kCfsrBusFaultStart << 1); 63 constexpr uint32_t kCfsrImpreciserrMask = (kCfsrBusFaultStart << 2); 64 constexpr uint32_t kCfsrUnstkerrMask = (kCfsrBusFaultStart << 3); 65 constexpr uint32_t kCfsrStkerrMask = (kCfsrBusFaultStart << 4); 66 constexpr uint32_t kCfsrLsperrMask = (kCfsrBusFaultStart << 5); 67 constexpr uint32_t kCfsrBfarvalidMask = (kCfsrBusFaultStart << 7); 68 // Mask for all supported bus error flags i.e. bits that indicate a specific 69 // error. 70 constexpr uint32_t kCfsrBusAllErrorsMask = 71 kCfsrIbuserrMask | kCfsrPreciserrMask | kCfsrImpreciserrMask | 72 kCfsrUnstkerrMask | kCfsrStkerrMask | kCfsrLsperrMask; 73 // Usage faults (UsageFault Status Register) 74 constexpr uint32_t kCfsrUsageFaultStart = (0x1 << 16); 75 constexpr uint32_t kCfsrUndefinstrMask = (kCfsrUsageFaultStart << 0); 76 constexpr uint32_t kCfsrInvstateMask = (kCfsrUsageFaultStart << 1); 77 constexpr uint32_t kCfsrInvpcMask = (kCfsrUsageFaultStart << 2); 78 constexpr uint32_t kCfsrNocpMask = (kCfsrUsageFaultStart << 3); 79 #if _PW_ARCH_ARM_V8M_MAINLINE || _PW_ARCH_ARM_V8_1M_MAINLINE 80 constexpr uint32_t kCfsrStkofMask = (kCfsrUsageFaultStart << 4); 81 #endif // _PW_ARCH_ARM_V8M_MAINLINE || _PW_ARCH_ARM_V8_1M_MAINLINE 82 constexpr uint32_t kCfsrUnalignedMask = (kCfsrUsageFaultStart << 8); 83 constexpr uint32_t kCfsrDivbyzeroMask = (kCfsrUsageFaultStart << 9); 84 // Mask for all supported usage error flags i.e. bits that indicate a specific 85 // error. 86 constexpr uint32_t kCfsrUsageAllErrorsMask = 87 kCfsrUndefinstrMask | kCfsrInvstateMask | kCfsrInvpcMask | kCfsrNocpMask | 88 #if _PW_ARCH_ARM_V8M_MAINLINE || _PW_ARCH_ARM_V8_1M_MAINLINE 89 kCfsrStkofMask | 90 #endif // _PW_ARCH_ARM_V8M_MAINLINE || _PW_ARCH_ARM_V8_1M_MAINLINE 91 kCfsrUnalignedMask | kCfsrDivbyzeroMask; 92 93 // Bit masks for an exception return value. (ARMv7-M Section B1.5.8) 94 constexpr uint32_t kExcReturnStackMask = 0x1u << 2; // 0=MSP, 1=PSP 95 constexpr uint32_t kExcReturnModeMask = 0x1u << 3; // 0=Handler, 1=Thread 96 constexpr uint32_t kExcReturnBasicFrameMask = 0x1u << 4; 97 98 // Mask for the IPSR, bits 8:0, of the xPSR register. 99 constexpr uint32_t kXpsrIpsrMask = 0b1'1111'1111; 100 101 // Bit masks for the control register. (ARMv7-M Section B1.4.4) 102 // The SPSEL bit is only valid while in Thread Mode: 103 constexpr uint32_t kControlThreadModeStackMask = 0x1u << 1; // 0=MSP, 1=PSP 104 105 // Memory mapped registers. (ARMv7-M Section B3.2.2, Table B3-4) 106 // Note: Only some of these are supported on ARMv6-M. 107 inline volatile uint32_t& cortex_m_cfsr = 108 *reinterpret_cast<volatile uint32_t*>(0xE000ED28u); 109 inline volatile uint32_t& cortex_m_mmfar = 110 *reinterpret_cast<volatile uint32_t*>(0xE000ED34u); 111 inline volatile uint32_t& cortex_m_bfar = 112 *reinterpret_cast<volatile uint32_t*>(0xE000ED38u); 113 inline volatile uint32_t& cortex_m_icsr = 114 *reinterpret_cast<volatile uint32_t*>(0xE000ED04u); 115 inline volatile uint32_t& cortex_m_hfsr = 116 *reinterpret_cast<volatile uint32_t*>(0xE000ED2Cu); 117 inline volatile uint32_t& cortex_m_shcsr = 118 *reinterpret_cast<volatile uint32_t*>(0xE000ED24u); 119 120 } // namespace pw::cpu_exception::cortex_m 121