mirror of
https://github.com/mudita/MuditaOS.git
synced 2026-07-21 13:35:04 -04:00
Split module-utils into smaller components for better dependency management. Fix many dependencies throughout the project. Signed-off-by: Marcin Smoczyński <smoczynski.marcin@gmail.com>
251 lines
8.0 KiB
C++
251 lines
8.0 KiB
C++
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
|
|
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
|
|
|
|
#include <log/log.hpp>
|
|
|
|
#include "consoledump.hpp"
|
|
#include "MIMXRT1051.h"
|
|
|
|
/// Hard Fault Fault Status Register
|
|
struct __attribute__((packed)) hfsr_t
|
|
{
|
|
union
|
|
{
|
|
uint32_t all;
|
|
struct
|
|
{
|
|
uint32_t rsrvd0 : 1;
|
|
uint32_t vecttbl : 1;
|
|
uint32_t rsrvd1 : 28;
|
|
uint32_t forced : 1;
|
|
uint32_t debugevt : 1;
|
|
};
|
|
};
|
|
};
|
|
|
|
/// MemManage Fault Status Register
|
|
struct __attribute__((packed)) mmfsr_t
|
|
{
|
|
union
|
|
{
|
|
uint8_t all;
|
|
struct
|
|
{
|
|
uint8_t iaccviol : 1;
|
|
uint8_t daccviol : 1;
|
|
uint8_t rsrvd2 : 1;
|
|
uint8_t munstkerr : 1;
|
|
uint8_t mstkerr : 1;
|
|
uint8_t mlsperr : 1;
|
|
uint8_t rsrvd6 : 1;
|
|
uint8_t mmarvalid : 1;
|
|
};
|
|
};
|
|
};
|
|
|
|
/// BusFault Status Register
|
|
struct __attribute__((packed)) bfsr_t
|
|
{
|
|
union
|
|
{
|
|
uint8_t all;
|
|
struct
|
|
{
|
|
uint8_t ibuserr : 1;
|
|
uint8_t preciserr : 1;
|
|
uint8_t impreciserr : 1;
|
|
uint8_t unstkerr : 1;
|
|
uint8_t stkerr : 1;
|
|
uint8_t lsperr : 1;
|
|
uint8_t rsrvd6 : 1;
|
|
uint8_t bfarvalid : 1;
|
|
};
|
|
};
|
|
};
|
|
|
|
/// UsageFault Status Register
|
|
struct __attribute__((packed)) ufsr_t
|
|
{
|
|
union
|
|
{
|
|
uint16_t all;
|
|
struct
|
|
{
|
|
uint8_t undefinstr : 1;
|
|
uint8_t invstate : 1;
|
|
uint8_t invpc : 1;
|
|
uint8_t nocp : 1;
|
|
uint8_t rsrvd4_7 : 3;
|
|
uint8_t unaligned : 1;
|
|
uint8_t divbyzero : 1;
|
|
uint8_t rsrvd10_15 : 6;
|
|
};
|
|
};
|
|
};
|
|
|
|
/// Configurable Fault Status Register
|
|
struct __attribute__((packed)) cfsr_t
|
|
{
|
|
union
|
|
{
|
|
uint32_t all;
|
|
struct
|
|
{
|
|
mmfsr_t mmfsr;
|
|
bfsr_t bfsr;
|
|
ufsr_t ufsr;
|
|
};
|
|
};
|
|
};
|
|
|
|
/// Auxiliary Bus Fault Status register
|
|
struct __attribute__((packed)) abfsr_t
|
|
{
|
|
union
|
|
{
|
|
uint32_t all;
|
|
struct
|
|
{
|
|
uint32_t itcm : 1;
|
|
uint32_t dtcm : 1;
|
|
uint32_t ahbp : 1;
|
|
uint32_t axim : 1;
|
|
uint32_t eppb : 1;
|
|
uint32_t rsrvd5_7 : 3;
|
|
uint32_t aximtype : 2;
|
|
uint32_t rsrvd10_31 : 1;
|
|
};
|
|
};
|
|
};
|
|
|
|
struct __attribute__((packed)) syslog_t
|
|
{
|
|
CrashCatcherStackedRegisters stackFrame;
|
|
struct
|
|
{
|
|
hfsr_t hfsr; /// Hard Fault Fault Status Register
|
|
cfsr_t cfsr; /// Configurable Fault Status Register
|
|
uint32_t mmfar; /// MemManage Fault Address Register
|
|
uint32_t bfar; /// BusFault Address Register
|
|
abfsr_t abfsr; /// Auxiliary Bus Fault Status register
|
|
uint32_t exc_return; /// EXC_RETURN value for the exception being serviced
|
|
} registers;
|
|
};
|
|
|
|
namespace
|
|
{
|
|
void printCrashInfo(const syslog_t &syslog)
|
|
{
|
|
LOG_FATAL("!!! Crash Occured !!!");
|
|
LOG_FATAL("* Stack Frame:");
|
|
LOG_FATAL("R0 = 0x%0" PRIX32, syslog.stackFrame.r0);
|
|
LOG_FATAL("R1 = 0x%0" PRIX32, syslog.stackFrame.r1);
|
|
LOG_FATAL("R2 = 0x%0" PRIX32, syslog.stackFrame.r2);
|
|
LOG_FATAL("R3 = 0x%0" PRIX32, syslog.stackFrame.r3);
|
|
LOG_FATAL("R12 = 0x%0" PRIX32, syslog.stackFrame.r12);
|
|
LOG_FATAL("LR = 0x%0" PRIX32, syslog.stackFrame.lr);
|
|
LOG_FATAL("PC = 0x%0" PRIX32, syslog.stackFrame.pc);
|
|
LOG_FATAL("PSR = 0x%0" PRIX32, syslog.stackFrame.psr);
|
|
|
|
LOG_FATAL("* Fault Status Registers:");
|
|
LOG_FATAL("SCB->HFSR = 0x%0" PRIX32, syslog.registers.hfsr.all);
|
|
LOG_FATAL("SCB->CFSR = 0x%0" PRIX32, syslog.registers.cfsr.all);
|
|
LOG_FATAL("SCB->MMAR = 0x%0" PRIX32, syslog.registers.mmfar);
|
|
LOG_FATAL("SCB->BFAR = 0x%0" PRIX32, syslog.registers.bfar);
|
|
LOG_FATAL("SCB->ABFSR = 0x%0" PRIX32, syslog.registers.abfsr.all);
|
|
LOG_FATAL("EXC_RETURN = 0x%0" PRIX32, syslog.registers.exc_return);
|
|
|
|
LOG_FATAL("* Details of Fault Status Registers:");
|
|
hfsr_t hfsr = syslog.registers.hfsr;
|
|
LOG_FATAL("SCB->HFSR = 0x%0" PRIX32 " - HardFault Status Register", hfsr.all);
|
|
if (hfsr.debugevt)
|
|
LOG_FATAL(" - DEBUGEVT: Hard fault caused by debug event");
|
|
if (hfsr.forced)
|
|
LOG_FATAL(" - FORCED: Hard fault caused by bus/memory management/usage fault");
|
|
if (hfsr.vecttbl)
|
|
LOG_FATAL(" - VECTBL: BusFault on vector table read");
|
|
|
|
cfsr_t cfsr = syslog.registers.cfsr;
|
|
LOG_FATAL("SCB->CFSR = 0x%0" PRIX32 " - Configurable Fault Status Register", cfsr.all);
|
|
mmfsr_t mmfsr = cfsr.mmfsr;
|
|
LOG_FATAL("> SCB->MMFSR = 0x%0" PRIX8 " Memory Management Fault Status Register", mmfsr.all);
|
|
if (mmfsr.mmarvalid)
|
|
LOG_FATAL(" - MMARVALID: MMAR is valid");
|
|
if (mmfsr.mlsperr)
|
|
LOG_FATAL(" - MLSPERR: A MemManage fault occurred during floating-point lazy state preservation");
|
|
if (mmfsr.mstkerr)
|
|
LOG_FATAL(" - MSTKERR: MemManage fault on stacking for exception entry");
|
|
if (mmfsr.munstkerr)
|
|
LOG_FATAL(" - MUNSTKERR: MemManage fault on unstacking for a return from exception:");
|
|
if (mmfsr.daccviol)
|
|
LOG_FATAL(" - DACCVIOL: Data access violation");
|
|
if (mmfsr.iaccviol)
|
|
LOG_FATAL(" - IACCVIOL: Instruction access violation");
|
|
|
|
bfsr_t bfsr = cfsr.bfsr;
|
|
LOG_FATAL("> SCB->BFSR = 0x%0" PRIX8 " - Bus Fault Status Register ", bfsr.all);
|
|
if (bfsr.bfarvalid)
|
|
LOG_FATAL(" - BFARVALID: BFAR is valid ");
|
|
if (bfsr.lsperr)
|
|
LOG_FATAL(" - LSPERR: A bus fault occurred during floating-point lazy state preservation");
|
|
if (bfsr.stkerr)
|
|
LOG_FATAL(" - STKERR: Stacking error");
|
|
if (bfsr.unstkerr)
|
|
LOG_FATAL(" - UNSTKERR: Unstacking error");
|
|
if (bfsr.impreciserr)
|
|
LOG_FATAL(" - IMPREISERR: Imprecise data bus error");
|
|
if (bfsr.preciserr)
|
|
LOG_FATAL(" - PRECISERR: Precise data bus error");
|
|
if (bfsr.ibuserr)
|
|
LOG_FATAL(" - IBUSERR: Instruction bus error");
|
|
|
|
ufsr_t ufsr = cfsr.ufsr;
|
|
LOG_FATAL("> SCB->UFSR = 0x%0" PRIX16 " - Usage Fault Status Register", ufsr.all);
|
|
if (ufsr.divbyzero)
|
|
LOG_FATAL(" - DIVBYZERO: Divide by zero UsageFault");
|
|
if (ufsr.unaligned)
|
|
LOG_FATAL(" - UNALIGNED: Unaligned access UsageFault");
|
|
if (ufsr.nocp)
|
|
LOG_FATAL(" - NOCP: Attempt to execute a coprocessor instruction");
|
|
if (ufsr.invpc)
|
|
LOG_FATAL(" - INVPC: Invalid PC load UsageFault");
|
|
if (ufsr.invstate)
|
|
LOG_FATAL(" - INVSTATE: Invalid state UsageFault");
|
|
if (ufsr.undefinstr)
|
|
LOG_FATAL(" - UNDEFINSTR: Undefined instruction UsageFault");
|
|
|
|
abfsr_t abfsr = syslog.registers.abfsr;
|
|
LOG_FATAL("SCB->ABFSR = 0x%0" PRIX32 " - Auxiliary Bus Fault Status register", abfsr.all);
|
|
if (abfsr.itcm)
|
|
LOG_FATAL(" - ITCM: Asynchronous fault on ITCM interface");
|
|
if (abfsr.dtcm)
|
|
LOG_FATAL(" - DTCM: Asynchronous fault on DTCM interface.");
|
|
if (abfsr.ahbp)
|
|
LOG_FATAL(" - AHBP: Asynchronous fault on AHBP interface");
|
|
if (abfsr.eppb)
|
|
LOG_FATAL(" - EPPB: Asynchronous fault on EPPB interface");
|
|
}
|
|
|
|
syslog_t syslogFrom(const CrashCatcherInfo *info)
|
|
{
|
|
syslog_t syslog;
|
|
|
|
syslog.stackFrame = *info->pSP;
|
|
syslog.registers.hfsr.all = SCB->HFSR;
|
|
syslog.registers.cfsr.all = SCB->CFSR;
|
|
syslog.registers.mmfar = SCB->MMFAR;
|
|
syslog.registers.bfar = SCB->BFAR;
|
|
syslog.registers.abfsr.all = SCB->ABFSR;
|
|
|
|
return syslog;
|
|
}
|
|
} // namespace
|
|
|
|
namespace crashdump
|
|
{
|
|
void printCrashInfo(const CrashCatcherInfo *info)
|
|
{
|
|
::printCrashInfo(syslogFrom(info));
|
|
}
|
|
} // namespace crashdump
|