thermosphere: introduce "ENSURE"

This commit is contained in:
TuxSH 2020-01-25 17:20:43 +00:00
parent 310048a32c
commit 5b545f89f5
6 changed files with 47 additions and 51 deletions

View file

@ -56,11 +56,13 @@ INCLUDES := include ../common/include
#---------------------------------------------------------------------------------
# options for code generation
#---------------------------------------------------------------------------------
ARCH := -march=armv8-a -mtune=cortex-a57 -mgeneral-regs-only -ffixed-x18 #<- important
# Note: -ffixed-x18 and -mgeneral-regs-only are very important and must be enabled
ARCH := -march=armv8-a -mtune=cortex-a57 -mgeneral-regs-only -ffixed-x18
DEFINES := -D__CCPLEX__ -DATMOSPHERE_GIT_BRANCH=\"$(AMSBRANCH)\" -DATMOSPHERE_GIT_REV=\"$(AMSREV)\"\
-DATMOSPHERE_RELEASE_VERSION_HASH="0x$(AMSHASH)" $(PLATFORM_DEFINES)
CFLAGS := \
-g \
-fmacro-prefix-map=$(TOPDIR)/src/= \
-Os \
-ffunction-sections \
-fdata-sections \

View file

@ -38,13 +38,10 @@ static void loadKernelViaSemihosting(void)
DEBUG("Loading kernel via semihosted file I/O... ");
handle = semihosting_file_open("test_kernel.bin", FOPEN_MODE_RB);
if (handle < 0) {
PANIC("failed to open file (%ld)!\n", handle);
}
ENSURE2(handle >= 0, "failed to open file (%ld)!\n", handle);
if ((ret = semihosting_file_read(handle, &len, buf)) < 0) {
PANIC("failed to read file (%ld)!\n", ret);
}
ret = semihosting_file_read(handle, &len, buf);
ENSURE2(ret >= 0, "failed to read file (%ld)!\n", ret);
DEBUG("OK!\n");
semihosting_file_close(handle);
@ -115,11 +112,8 @@ void thermosphereMain(ExceptionStackFrame *frame, u64 pct)
if (currentCoreCtx->isBootCore) {
if (currentCoreCtx->kernelEntrypoint == 0) {
if (semihosting_connection_supported()) {
loadKernelViaSemihosting();
} else {
PANIC("Kernel not loaded!\n");
}
ENSURE2(semihosting_connection_supported(), "Kernel not loaded!\n");
loadKernelViaSemihosting();
}
}
else {

View file

@ -178,11 +178,13 @@ void handleMcrMrcCP15Trap(ExceptionStackFrame *frame, ExceptionSyndromeRegister
bool isRead = (iss & 1) != 0;
u32 instructionLength = esr.il == 0 ? 2 : 4;
if (LIKELY(opc1 == 0 && CRn == 14 && CRm == 2 && opc2 <= 1)) {
iss = opc2 == 0 ? ENCODE_SYSREG_ISS(CNTP_TVAL_EL0) : ENCODE_SYSREG_ISS(CNTP_CTL_EL0);
} else {
PANIC("handleMcrMrcTrap: unexpected cp15 register, instruction: %s p15, #%u, r%u, c%u, c%u, #%u\n", isRead ? "mrc" : "mcr", opc1, Rt, CRn, CRm, opc2);
}
ENSURE2(
opc1 == 0 && CRn == 14 && CRm == 2 && opc2 <= 1,
"unexpected cp15 register, instruction: %s p15, #%u, r%u, c%u, c%u, #%u\n",
isRead ? "mrc" : "mcr", opc1, Rt, CRn, CRm, opc2
);
iss = opc2 == 0 ? ENCODE_SYSREG_ISS(CNTP_TVAL_EL0) : ENCODE_SYSREG_ISS(CNTP_CTL_EL0);
if (isRead) {
doMrc(frame, iss, instructionLength, Rt);
@ -209,11 +211,13 @@ void handleMcrrMrrcCP15Trap(ExceptionStackFrame *frame, ExceptionSyndromeRegiste
bool isRead = (iss & 1) != 0;
u32 instructionLength = esr.il == 0 ? 2 : 4;
if (LIKELY(CRm == 14 && (opc1 == 0 || opc1 == 2))) {
iss = opc1 == 0 ? ENCODE_SYSREG_ISS(CNTPCT_EL0) : ENCODE_SYSREG_ISS(CNTP_CVAL_EL0);
} else {
PANIC("handleMcrrMrrcTrap: unexpected cp15 register, instruction: %s p15, #%u, r%u, r%u, c%u\n", isRead ? "mrrc" : "mcrr", opc1, Rt, Rt, CRm);
}
ENSURE2(
CRm == 14 && (opc1 == 0 || opc1 == 2),
"handleMcrrMrrcTrap: unexpected cp15 register, instruction: %s p15, #%u, r%u, r%u, c%u\n",
isRead ? "mrrc" : "mcrr", opc1, Rt, Rt, CRm
);
iss = opc1 == 0 ? ENCODE_SYSREG_ISS(CNTPCT_EL0) : ENCODE_SYSREG_ISS(CNTP_CVAL_EL0);
if (isRead) {
doMrrc(frame, iss, instructionLength, Rt, Rt2);

View file

@ -122,17 +122,13 @@ TransportInterface *transportInterfaceCreate(
)
{
u64 irqFlags = recursiveSpinlockLockMaskIrq(&g_transportInterfaceLayerLock);
if (transportInterfaceListIsEmpty(&g_transportInterfaceFreeList)) {
PANIC("transportInterfaceCreateAndInit: resource exhaustion\n");
}
ENSURE(!transportInterfaceListIsEmpty(&g_transportInterfaceFreeList));
TransportInterface *iface;
FOREACH_LINK (link, &g_transportInterfaceList) {
iface = transportInterfaceGetLinkParent(link);
if (iface->type == type && iface->id == id) {
PANIC("transportInterfaceCreateAndInit: device already registered\n");
}
ENSURE(iface->type != type || iface->id != id);
}
iface = transportInterfaceGetLinkParent(transportInterfaceListGetFirstLink(&g_transportInterfaceFreeList));
@ -228,9 +224,7 @@ void transportInterfaceSetInterruptAffinity(TransportInterface *iface, u8 affini
TransportInterface *transportInterfaceIrqHandlerTopHalf(u16 irqId)
{
TransportInterface *iface = transportInterfaceFindByIrqId(irqId);
if (iface == NULL) {
PANIC("transportInterfaceLayerIrqHandlerTop: irq id %x not found!\n", irqId);
}
ENSURE(iface != NULL);
transportInterfaceAcquire(iface);

View file

@ -30,16 +30,26 @@
#define MAKE_REG32(a) (*(volatile u32 *)(uintptr_t)(a))
#define ALIGN(m) __attribute__((aligned(m)))
#define PACKED __attribute__((packed))
#define LIKELY(expr) __builtin_expect((expr), 1)
#define UNLIKELY(expr) __builtin_expect((expr), 0)
#define ALIGN(m) __attribute__((aligned(m)))
#define PACKED __attribute__((packed))
#define LIKELY(expr) __builtin_expect((expr), 1)
#define UNLIKELY(expr) __builtin_expect((expr), 0)
#define ALINLINE __attribute__((always_inline))
#define ALINLINE __attribute__((always_inline))
#define TEMPORARY __attribute__((section(".tempbss")))
#define TEMPORARY __attribute__((section(".tempbss")))
#define PANIC(...) do { DEBUG(__VA_ARGS__); panic(); } while (false)
#define PANIC(...) do { DEBUG(__VA_ARGS__); panic(); } while (false)
// Note: ##__VA_ARGS__ removing the comma if __VA_ARGS__ is empty is a GCC extension; __FUNCTION__ too
#define ENSURE2(expr, msg, ...)\
do {\
if (UNLIKELY(!(expr))) {\
PANIC("EL2 [core %u]: " __FILE__ ":" STRINGIZE(__LINE__) ": " msg, currentCoreCtx->coreId, ##__VA_ARGS__);\
}\
} while (false)
#define ENSURE(expr) ENSURE2(expr, #expr"\n")
#define FOREACH_BIT(tmpmsk, var, word) for (u64 tmpmsk = (word), var = __builtin_ctzll(word); tmpmsk != 0; tmpmsk &= ~BITL(var), var = __builtin_ctzll(tmpmsk))

View file

@ -237,9 +237,7 @@ static void vgicEnqueueVirqState(VirqStateList *list, VirqState *elem)
{
VirqState *pos;
if (vgicIsStateQueued(elem)) {
PANIC("vgicEnqueueVirqState: unsanitized argument idx=%u previd=%u nextid=%u\n", (u32)vgicGetVirqStateIndex(elem), elem->listPrev, elem->listNext);
}
ENSURE(!vgicIsStateQueued(elem));
for (pos = list->first; pos != vgicGetQueueEnd(); pos = vgicGetNextQueuedVirqState(pos)) {
// Sort predicate should be stable
@ -256,9 +254,7 @@ static void vgicDequeueVirqState(VirqStateList *list, VirqState *elem)
VirqState *prev = vgicGetPrevQueuedVirqState(elem);
VirqState *next = vgicGetNextQueuedVirqState(elem);
if (!vgicIsStateQueued(elem)) {
PANIC("vgicDequeueVirqState: invalid id %x\n", vgicGetVirqStateIndex(elem));
}
ENSURE(vgicIsStateQueued(elem));
--list->size;
if (prev != vgicGetQueueEnd()) {
@ -873,9 +869,7 @@ static bool vgicUpdateListRegister(volatile ArmGicV2ListRegister *lr)
u32 srcCoreId = state->coreId;
u32 coreId = currentCoreCtx->coreId;
if (!state->handled) {
PANIC("vgicUpdateListRegister: improper previous state for now pending irq idx %u, active=%d\n", vgicGetVirqStateIndex(state), (int)state->active);
}
ENSURE(state->handled);
state->active = lrCopy.active;
@ -995,10 +989,6 @@ void vgicMaintenanceInterruptHandler(void)
DEBUG("EL2 [core %d]: Group 1 disabled maintenance interrupt\n", (int)currentCoreCtx->coreId);
}
if (misr.lrenp) {
PANIC("EL2 [core %d]: List Register Entry Not Present maintenance interrupt!\n", currentCoreCtx->coreId);
}
if (misr.eoi) {
//DEBUG("EL2 [core %d]: SGI EOI maintenance interrupt\n", currentCoreCtx->coreId);
}
@ -1007,6 +997,8 @@ void vgicMaintenanceInterruptHandler(void)
//DEBUG("EL2 [core %d]: Underflow maintenance interrupt\n", currentCoreCtx->coreId);
}
ENSURE2(!misr.lrenp, "List Register Entry Not Present maintenance interrupt!\n");
// The rest should be handled by the main loop...
}