mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-11-15 09:36:35 +00:00
thermosphere: propagate some changes
This commit is contained in:
parent
5b56d05e11
commit
036883c30f
16 changed files with 114 additions and 99 deletions
|
@ -15,7 +15,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "hvisor_cpu_caches.hpp"
|
#include "hvisor_cpu_caches.hpp"
|
||||||
#include "../core_ctx.h"
|
|
||||||
|
|
||||||
#define DEFINE_CACHE_RANGE_FUNC(isn, name, cache, post)\
|
#define DEFINE_CACHE_RANGE_FUNC(isn, name, cache, post)\
|
||||||
void name(const void *addr, size_t size)\
|
void name(const void *addr, size_t size)\
|
||||||
|
|
|
@ -25,10 +25,12 @@
|
||||||
#include "hvisor_gdb_defines_internal.hpp"
|
#include "hvisor_gdb_defines_internal.hpp"
|
||||||
#include "hvisor_gdb_packet_data.hpp"
|
#include "hvisor_gdb_packet_data.hpp"
|
||||||
|
|
||||||
#include "../breakpoints.h"
|
#include "../hvisor_hw_breakpoint_manager.hpp"
|
||||||
#include "../software_breakpoints.h"
|
#include "../hvisor_sw_breakpoint_manager.hpp"
|
||||||
#include "../watchpoints.h"
|
#include "../hvisor_watchpoint_manager.hpp"
|
||||||
#include "../fpu.h"
|
|
||||||
|
#include "../hvisor_fpu_register_cache.hpp"
|
||||||
|
|
||||||
#include "../debug_manager.h"
|
#include "../debug_manager.h"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
@ -67,7 +69,7 @@ namespace ams::hvisor::gdb {
|
||||||
{
|
{
|
||||||
// TODO: move the debug traps enable here?
|
// TODO: move the debug traps enable here?
|
||||||
|
|
||||||
m_attachedCoreList = getActiveCoreMask();
|
m_attachedCoreList = CoreContext::GetActiveCoreMask();
|
||||||
|
|
||||||
// We're in full-stop mode at this point
|
// We're in full-stop mode at this point
|
||||||
// Break cores, but don't send the debug event (it will be fetched with '?')
|
// Break cores, but don't send the debug event (it will be fetched with '?')
|
||||||
|
@ -78,7 +80,7 @@ namespace ams::hvisor::gdb {
|
||||||
|
|
||||||
BreakAllCores();
|
BreakAllCores();
|
||||||
|
|
||||||
DebugEventInfo *info = debugManagerGetDebugEvent(currentCoreCtx->coreId);
|
DebugEventInfo *info = debugManagerGetDebugEvent(currentCoreCtx->GetCoreId());
|
||||||
info->preprocessed = true;
|
info->preprocessed = true;
|
||||||
info->handled = true;
|
info->handled = true;
|
||||||
m_lastDebugEvent = info;
|
m_lastDebugEvent = info;
|
||||||
|
@ -90,9 +92,9 @@ namespace ams::hvisor::gdb {
|
||||||
|
|
||||||
void Context::Detach()
|
void Context::Detach()
|
||||||
{
|
{
|
||||||
removeAllWatchpoints();
|
WatchpointManager::GetInstance().RemoveAll();
|
||||||
removeAllBreakpoints();
|
HwBreakpointManager::GetInstance().RemoveAll();
|
||||||
removeAllSoftwareBreakpoints(true);
|
SwBreakpointManager::GetInstance().RemoveAll(true);
|
||||||
|
|
||||||
// Reports to gdb are prevented because of "detaching" state?
|
// Reports to gdb are prevented because of "detaching" state?
|
||||||
|
|
||||||
|
@ -102,12 +104,12 @@ namespace ams::hvisor::gdb {
|
||||||
memset(&m_currentHioRequest, 0, sizeof(PackedGdbHioRequest));
|
memset(&m_currentHioRequest, 0, sizeof(PackedGdbHioRequest));
|
||||||
|
|
||||||
debugManagerSetReportingEnabled(false);
|
debugManagerSetReportingEnabled(false);
|
||||||
debugManagerContinueCores(getActiveCoreMask());
|
debugManagerContinueCores(CoreContext::GetActiveCoreMask());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Context::MigrateRxIrq(u32 coreId) const
|
void Context::MigrateRxIrq(u32 coreId) const
|
||||||
{
|
{
|
||||||
fpuCleanInvalidateRegisterCache();
|
FpuRegisterCache::GetInstance().CleanInvalidate();
|
||||||
//transportInterfaceSetInterruptAffinity(ctx->transportInterface, BIT(coreId));
|
//transportInterfaceSetInterruptAffinity(ctx->transportInterface, BIT(coreId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,6 @@
|
||||||
#include "hvisor_gdb_defines_internal.hpp"
|
#include "hvisor_gdb_defines_internal.hpp"
|
||||||
#include "hvisor_gdb_packet_data.hpp"
|
#include "hvisor_gdb_packet_data.hpp"
|
||||||
|
|
||||||
#include "../core_ctx.h"
|
|
||||||
#include "../guest_memory.h"
|
#include "../guest_memory.h"
|
||||||
|
|
||||||
namespace ams::hvisor::gdb {
|
namespace ams::hvisor::gdb {
|
||||||
|
|
|
@ -24,12 +24,12 @@
|
||||||
#include "hvisor_gdb_defines_internal.hpp"
|
#include "hvisor_gdb_defines_internal.hpp"
|
||||||
#include "hvisor_gdb_packet_data.hpp"
|
#include "hvisor_gdb_packet_data.hpp"
|
||||||
|
|
||||||
#include "../exceptions.h"
|
#include "../hvisor_exception_stack_frame.hpp"
|
||||||
#include "../fpu.h"
|
#include "../hvisor_fpu_register_cache.hpp"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
auto GetRegisterPointerAndSize(unsigned long id, ExceptionStackFrame *frame, FpuRegisterCache *fpuRegCache)
|
auto GetRegisterPointerAndSize(unsigned long id, ams::hvisor::ExceptionStackFrame *frame, ams::hvisor::FpuRegisterCache::Storage &fpuRegStorage)
|
||||||
{
|
{
|
||||||
void *outPtr = nullptr;
|
void *outPtr = nullptr;
|
||||||
size_t outSz = 0;
|
size_t outSz = 0;
|
||||||
|
@ -40,7 +40,7 @@ namespace {
|
||||||
outSz = 8;
|
outSz = 8;
|
||||||
break;
|
break;
|
||||||
case 31:
|
case 31:
|
||||||
outPtr = exceptionGetSpPtr(frame);
|
outPtr = &frame->GetSpRef();
|
||||||
outSz = 8;
|
outSz = 8;
|
||||||
break;
|
break;
|
||||||
case 32:
|
case 32:
|
||||||
|
@ -48,15 +48,15 @@ namespace {
|
||||||
outSz = 4;
|
outSz = 4;
|
||||||
break;
|
break;
|
||||||
case 33 ... 64:
|
case 33 ... 64:
|
||||||
outPtr = &fpuRegCache->q[id - 33];
|
outPtr = &fpuRegStorage.q[id - 33];
|
||||||
outSz = 16;
|
outSz = 16;
|
||||||
break;
|
break;
|
||||||
case 65:
|
case 65:
|
||||||
outPtr = &fpuRegCache->fpsr;
|
outPtr = &fpuRegStorage.fpsr;
|
||||||
outSz = 4;
|
outSz = 4;
|
||||||
break;
|
break;
|
||||||
case 66:
|
case 66:
|
||||||
outPtr = &fpuRegCache->fpcr;
|
outPtr = &fpuRegStorage.fpcr;
|
||||||
outSz = 4;
|
outSz = 4;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -74,11 +74,11 @@ namespace ams::hvisor::gdb {
|
||||||
// Note: GDB treats cpsr, fpsr, fpcr as 32-bit integers...
|
// Note: GDB treats cpsr, fpsr, fpcr as 32-bit integers...
|
||||||
GDB_DEFINE_HANDLER(ReadRegisters)
|
GDB_DEFINE_HANDLER(ReadRegisters)
|
||||||
{
|
{
|
||||||
ENSURE(m_selectedCoreId == currentCoreCtx->coreId);
|
ENSURE(m_selectedCoreId == currentCoreCtx->GetCoreId());
|
||||||
GDB_CHECK_NO_CMD_DATA();
|
GDB_CHECK_NO_CMD_DATA();
|
||||||
|
|
||||||
ExceptionStackFrame *frame = currentCoreCtx->guestFrame;
|
ExceptionStackFrame *frame = currentCoreCtx->GetGuestFrame();
|
||||||
FpuRegisterCache *fpuRegCache = fpuReadRegisters();
|
auto &fpuRegStorage = FpuRegisterCache::GetInstance().ReadRegisters();
|
||||||
|
|
||||||
char *buf = GetInPlaceOutputBuffer();
|
char *buf = GetInPlaceOutputBuffer();
|
||||||
|
|
||||||
|
@ -89,19 +89,19 @@ namespace ams::hvisor::gdb {
|
||||||
u64 pc;
|
u64 pc;
|
||||||
u32 cpsr;
|
u32 cpsr;
|
||||||
} cpuSprs = {
|
} cpuSprs = {
|
||||||
.sp = *exceptionGetSpPtr(frame),
|
.sp = frame->GetSpRef(),
|
||||||
.pc = frame->elr_el2,
|
.pc = frame->elr_el2,
|
||||||
.cpsr = static_cast<u32>(frame->spsr_el2),
|
.cpsr = static_cast<u32>(frame->spsr_el2),
|
||||||
};
|
};
|
||||||
|
|
||||||
u32 fpuSprs[2] = {
|
u32 fpuSprs[2] = {
|
||||||
static_cast<u32>(fpuRegCache->fpsr),
|
static_cast<u32>(fpuRegStorage.fpsr),
|
||||||
static_cast<u32>(fpuRegCache->fpcr),
|
static_cast<u32>(fpuRegStorage.fpcr),
|
||||||
};
|
};
|
||||||
|
|
||||||
n += EncodeHex(buf + n, frame->x, sizeof(frame->x));
|
n += EncodeHex(buf + n, frame->x, sizeof(frame->x));
|
||||||
n += EncodeHex(buf + n, &cpuSprs, 8+8+4);
|
n += EncodeHex(buf + n, &cpuSprs, 8+8+4);
|
||||||
n += EncodeHex(buf + n, fpuRegCache->q, sizeof(fpuRegCache->q));
|
n += EncodeHex(buf + n, fpuRegStorage.q, sizeof(fpuRegStorage.q));
|
||||||
n += EncodeHex(buf + n, fpuSprs, sizeof(fpuSprs));
|
n += EncodeHex(buf + n, fpuSprs, sizeof(fpuSprs));
|
||||||
|
|
||||||
return SendPacket(std::string_view{buf, n});
|
return SendPacket(std::string_view{buf, n});
|
||||||
|
@ -109,10 +109,10 @@ namespace ams::hvisor::gdb {
|
||||||
|
|
||||||
GDB_DEFINE_HANDLER(WriteRegisters)
|
GDB_DEFINE_HANDLER(WriteRegisters)
|
||||||
{
|
{
|
||||||
ENSURE(m_selectedCoreId == currentCoreCtx->coreId);
|
ENSURE(m_selectedCoreId == currentCoreCtx->GetCoreId());
|
||||||
|
|
||||||
ExceptionStackFrame *frame = currentCoreCtx->guestFrame;
|
ExceptionStackFrame *frame = currentCoreCtx->GetGuestFrame();
|
||||||
FpuRegisterCache *fpuRegCache = fpuGetRegisterCache();
|
auto &fpuRegStorage = FpuRegisterCache::GetInstance().ReadRegisters();
|
||||||
|
|
||||||
char *tmp = GetWorkBuffer();
|
char *tmp = GetWorkBuffer();
|
||||||
|
|
||||||
|
@ -132,7 +132,7 @@ namespace ams::hvisor::gdb {
|
||||||
} infos[4] = {
|
} infos[4] = {
|
||||||
{ frame->x, sizeof(frame->x) },
|
{ frame->x, sizeof(frame->x) },
|
||||||
{ &cpuSprs, 8+8+4 },
|
{ &cpuSprs, 8+8+4 },
|
||||||
{ fpuRegCache->q, sizeof(fpuRegCache->q) },
|
{ fpuRegStorage.q, sizeof(fpuRegStorage.q) },
|
||||||
{ fpuSprs, sizeof(fpuSprs) },
|
{ fpuSprs, sizeof(fpuSprs) },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -153,22 +153,22 @@ namespace ams::hvisor::gdb {
|
||||||
n += info.sz;
|
n += info.sz;
|
||||||
}
|
}
|
||||||
|
|
||||||
*exceptionGetSpPtr(frame) = cpuSprs.sp;
|
frame->GetSpRef() = cpuSprs.sp;
|
||||||
frame->elr_el2 = cpuSprs.pc;
|
frame->elr_el2 = cpuSprs.pc;
|
||||||
frame->spsr_el2 = cpuSprs.cpsr;
|
frame->spsr_el2 = cpuSprs.cpsr;
|
||||||
fpuRegCache->fpsr = fpuSprs[0];
|
fpuRegStorage.fpsr = fpuSprs[0];
|
||||||
fpuRegCache->fpcr = fpuSprs[1];
|
fpuRegStorage.fpcr = fpuSprs[1];
|
||||||
fpuCommitRegisters();
|
FpuRegisterCache::GetInstance().CommitRegisters();
|
||||||
|
|
||||||
return ReplyOk();
|
return ReplyOk();
|
||||||
}
|
}
|
||||||
|
|
||||||
GDB_DEFINE_HANDLER(ReadRegister)
|
GDB_DEFINE_HANDLER(ReadRegister)
|
||||||
{
|
{
|
||||||
ENSURE(m_selectedCoreId == currentCoreCtx->coreId);
|
ENSURE(m_selectedCoreId == currentCoreCtx->GetCoreId());
|
||||||
|
|
||||||
ExceptionStackFrame *frame = currentCoreCtx->guestFrame;
|
ExceptionStackFrame *frame = currentCoreCtx->GetGuestFrame();
|
||||||
FpuRegisterCache *fpuRegCache = nullptr;
|
FpuRegisterCache::Storage *fpuRegStorage = nullptr;
|
||||||
|
|
||||||
auto [nread, gdbRegNum] = ParseHexIntegerList<1>(m_commandData);
|
auto [nread, gdbRegNum] = ParseHexIntegerList<1>(m_commandData);
|
||||||
if (nread == 0) {
|
if (nread == 0) {
|
||||||
|
@ -182,19 +182,19 @@ namespace ams::hvisor::gdb {
|
||||||
|
|
||||||
if (gdbRegNum > 31 + 3) {
|
if (gdbRegNum > 31 + 3) {
|
||||||
// FPU register -- must read the FPU registers first
|
// FPU register -- must read the FPU registers first
|
||||||
fpuRegCache = fpuReadRegisters();
|
fpuRegStorage = &FpuRegisterCache::GetInstance().ReadRegisters();
|
||||||
}
|
}
|
||||||
|
|
||||||
return std::apply(SendHexPacket, GetRegisterPointerAndSize(gdbRegNum, frame, fpuRegCache));
|
return std::apply(SendHexPacket, GetRegisterPointerAndSize(gdbRegNum, frame, *fpuRegStorage));
|
||||||
}
|
}
|
||||||
|
|
||||||
GDB_DEFINE_HANDLER(WriteRegister)
|
GDB_DEFINE_HANDLER(WriteRegister)
|
||||||
{
|
{
|
||||||
ENSURE(m_selectedCoreId == currentCoreCtx->coreId);
|
ENSURE(m_selectedCoreId == currentCoreCtx->GetCoreId());
|
||||||
|
|
||||||
char *tmp = GetWorkBuffer();
|
char *tmp = GetWorkBuffer();
|
||||||
ExceptionStackFrame *frame = currentCoreCtx->guestFrame;
|
ExceptionStackFrame *frame = currentCoreCtx->GetGuestFrame();
|
||||||
FpuRegisterCache *fpuRegCache = fpuGetRegisterCache();
|
auto &fpuRegStorage = FpuRegisterCache::GetInstance().GetStorageRef();
|
||||||
|
|
||||||
auto [nread, gdbRegNum] = ParseHexIntegerList<1>(m_commandData, '=');
|
auto [nread, gdbRegNum] = ParseHexIntegerList<1>(m_commandData, '=');
|
||||||
if (nread == 0) {
|
if (nread == 0) {
|
||||||
|
@ -207,7 +207,7 @@ namespace ams::hvisor::gdb {
|
||||||
return ReplyErrno(EINVAL);
|
return ReplyErrno(EINVAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto [regPtr, sz] = GetRegisterPointerAndSize(gdbRegNum, frame, fpuRegCache);
|
auto [regPtr, sz] = GetRegisterPointerAndSize(gdbRegNum, frame, fpuRegStorage);
|
||||||
|
|
||||||
// Decode, check for errors
|
// Decode, check for errors
|
||||||
if (m_commandData.size() != 2 * sz || DecodeHex(tmp, m_commandData) != sz) {
|
if (m_commandData.size() != 2 * sz || DecodeHex(tmp, m_commandData) != sz) {
|
||||||
|
@ -218,7 +218,7 @@ namespace ams::hvisor::gdb {
|
||||||
|
|
||||||
if (gdbRegNum > 31 + 3) {
|
if (gdbRegNum > 31 + 3) {
|
||||||
// FPU register -- must commit the FPU registers
|
// FPU register -- must commit the FPU registers
|
||||||
fpuCommitRegisters();
|
FpuRegisterCache::GetInstance().CommitRegisters();
|
||||||
}
|
}
|
||||||
|
|
||||||
return ReplyOk();
|
return ReplyOk();
|
||||||
|
|
|
@ -24,9 +24,10 @@
|
||||||
#include "hvisor_gdb_defines_internal.hpp"
|
#include "hvisor_gdb_defines_internal.hpp"
|
||||||
#include "hvisor_gdb_packet_data.hpp"
|
#include "hvisor_gdb_packet_data.hpp"
|
||||||
|
|
||||||
#include "../breakpoints.h"
|
#include "../hvisor_hw_breakpoint_manager.hpp"
|
||||||
#include "../software_breakpoints.h"
|
#include "../hvisor_sw_breakpoint_manager.hpp"
|
||||||
#include "../watchpoints.h"
|
#include "../hvisor_watchpoint_manager.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace ams::hvisor::gdb {
|
namespace ams::hvisor::gdb {
|
||||||
|
|
||||||
|
@ -46,19 +47,23 @@ namespace ams::hvisor::gdb {
|
||||||
// In theory we should reject leading zeroes in "kind". Oh well...
|
// In theory we should reject leading zeroes in "kind". Oh well...
|
||||||
|
|
||||||
int res;
|
int res;
|
||||||
static const WatchpointLoadStoreControl kinds[3] = {
|
static const cpu::DebugRegisterPair::LoadStoreControl kinds[3] = {
|
||||||
WatchpointLoadStoreControl_Store,
|
cpu::DebugRegisterPair::Store,
|
||||||
WatchpointLoadStoreControl_Load,
|
cpu::DebugRegisterPair::Load,
|
||||||
WatchpointLoadStoreControl_LoadStore,
|
cpu::DebugRegisterPair::LoadStore,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
auto &hwBpMgr = HwBreakpointManager::GetInstance();
|
||||||
|
auto &swBpMgr = SwBreakpointManager::GetInstance();
|
||||||
|
auto &wpMgr = WatchpointManager::GetInstance();
|
||||||
|
|
||||||
switch(kind) {
|
switch(kind) {
|
||||||
// Software breakpoint
|
// Software breakpoint
|
||||||
case 0: {
|
case 0: {
|
||||||
if(size != 4) {
|
if(size != 4) {
|
||||||
return ReplyErrno(EINVAL);
|
return ReplyErrno(EINVAL);
|
||||||
}
|
}
|
||||||
res = add ? addSoftwareBreakpoint(addr, persist) : removeSoftwareBreakpoint(addr, false);
|
res = add ? swBpMgr.Add(addr, persist) : swBpMgr.Remove(addr, false);
|
||||||
return res == 0 ? ReplyOk() : ReplyErrno(-res);
|
return res == 0 ? ReplyOk() : ReplyErrno(-res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,7 +72,7 @@ namespace ams::hvisor::gdb {
|
||||||
if(size != 4) {
|
if(size != 4) {
|
||||||
return ReplyErrno(EINVAL);
|
return ReplyErrno(EINVAL);
|
||||||
}
|
}
|
||||||
res = add ? addBreakpoint(addr) : removeBreakpoint(addr);
|
res = add ? hwBpMgr.Add(addr) : hwBpMgr.Remove(addr);
|
||||||
return res == 0 ? ReplyOk() : ReplyErrno(-res);
|
return res == 0 ? ReplyOk() : ReplyErrno(-res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,7 +80,7 @@ namespace ams::hvisor::gdb {
|
||||||
case 2:
|
case 2:
|
||||||
case 3:
|
case 3:
|
||||||
case 4: {
|
case 4: {
|
||||||
res = add ? addWatchpoint(addr, size, kinds[kind - 2]) : removeWatchpoint(addr, size, kinds[kind - 2]);
|
res = add ? wpMgr.Add(addr, size, kinds[kind - 2]) : wpMgr.Remove(addr, size, kinds[kind - 2]);
|
||||||
return res == 0 ? ReplyOk() : ReplyErrno(-res);
|
return res == 0 ? ReplyOk() : ReplyErrno(-res);
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
#include "hvisor_gdb_defines_internal.hpp"
|
#include "hvisor_gdb_defines_internal.hpp"
|
||||||
#include "hvisor_gdb_packet_data.hpp"
|
#include "hvisor_gdb_packet_data.hpp"
|
||||||
|
|
||||||
#include "../core_ctx.h"
|
#include "../hvisor_core_context.hpp"
|
||||||
|
|
||||||
namespace ams::hvisor::gdb {
|
namespace ams::hvisor::gdb {
|
||||||
|
|
||||||
|
@ -30,9 +30,9 @@ namespace ams::hvisor::gdb {
|
||||||
case ULONG_MAX:
|
case ULONG_MAX:
|
||||||
return -1;
|
return -1;
|
||||||
case 0:
|
case 0:
|
||||||
return currentCoreCtx->coreId;
|
return currentCoreCtx->GetCoreId();
|
||||||
default:
|
default:
|
||||||
return currentCoreCtx->coreId - 1;
|
return currentCoreCtx->GetCoreId() - 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,7 +97,7 @@ namespace ams::hvisor::gdb {
|
||||||
GDB_DEFINE_QUERY_HANDLER(CurrentThreadId)
|
GDB_DEFINE_QUERY_HANDLER(CurrentThreadId)
|
||||||
{
|
{
|
||||||
GDB_CHECK_NO_CMD_DATA();
|
GDB_CHECK_NO_CMD_DATA();
|
||||||
return SendFormattedPacket("QC%x", 1 + currentCoreCtx->coreId);
|
return SendFormattedPacket("QC%x", 1 + currentCoreCtx->GetCoreId());
|
||||||
}
|
}
|
||||||
|
|
||||||
GDB_DEFINE_QUERY_HANDLER(fThreadInfo)
|
GDB_DEFINE_QUERY_HANDLER(fThreadInfo)
|
||||||
|
|
|
@ -77,6 +77,7 @@ namespace ams::hvisor {
|
||||||
constexpr u64 GetKernelEntrypoint() const { return m_kernelEntrypoint; }
|
constexpr u64 GetKernelEntrypoint() const { return m_kernelEntrypoint; }
|
||||||
|
|
||||||
constexpr u32 GetCoreId() const { return m_coreId; }
|
constexpr u32 GetCoreId() const { return m_coreId; }
|
||||||
|
constexpr bool IsBootCore() const { return m_bootCore; }
|
||||||
|
|
||||||
constexpr u64 SetWarmboot(uintptr_t ep)
|
constexpr u64 SetWarmboot(uintptr_t ep)
|
||||||
{
|
{
|
||||||
|
|
|
@ -17,13 +17,13 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "defines.hpp"
|
#include "defines.hpp"
|
||||||
#include "core_ctx.h"
|
#include "hvisor_core_context.hpp"
|
||||||
|
|
||||||
namespace ams::hvisor {
|
namespace ams::hvisor {
|
||||||
|
|
||||||
class FpuRegisterCache final {
|
class FpuRegisterCache final {
|
||||||
SINGLETON_WITH_ATTRS(FpuRegisterCache, TEMPORARY);
|
SINGLETON_WITH_ATTRS(FpuRegisterCache, TEMPORARY);
|
||||||
private:
|
public:
|
||||||
struct Storage {
|
struct Storage {
|
||||||
u128 q[32];
|
u128 q[32];
|
||||||
u64 fpsr;
|
u64 fpsr;
|
||||||
|
@ -44,19 +44,25 @@ namespace ams::hvisor {
|
||||||
public:
|
public:
|
||||||
constexpr void TakeOwnership()
|
constexpr void TakeOwnership()
|
||||||
{
|
{
|
||||||
if (m_coreId != currentCoreCtx->coreId) {
|
if (m_coreId != currentCoreCtx->GetCoreId()) {
|
||||||
m_valid = false;
|
m_valid = false;
|
||||||
m_dirty = false;
|
m_dirty = false;
|
||||||
}
|
}
|
||||||
m_coreId = currentCoreCtx->coreId;
|
m_coreId = currentCoreCtx->GetCoreId();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReadRegisters()
|
Storage &GetStorageRef()
|
||||||
|
{
|
||||||
|
return m_storage;
|
||||||
|
}
|
||||||
|
|
||||||
|
Storage &ReadRegisters()
|
||||||
{
|
{
|
||||||
if (!m_valid) {
|
if (!m_valid) {
|
||||||
DumpRegisters(&m_storage);
|
DumpRegisters(&m_storage);
|
||||||
m_valid = true;
|
m_valid = true;
|
||||||
}
|
}
|
||||||
|
return m_storage;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr void CommitRegisters()
|
constexpr void CommitRegisters()
|
||||||
|
@ -68,7 +74,7 @@ namespace ams::hvisor {
|
||||||
|
|
||||||
void CleanInvalidate()
|
void CleanInvalidate()
|
||||||
{
|
{
|
||||||
if (m_dirty && m_coreId == currentCoreCtx->coreId) {
|
if (m_dirty && m_coreId == currentCoreCtx->GetCoreId()) {
|
||||||
ReloadRegisters(&m_storage);
|
ReloadRegisters(&m_storage);
|
||||||
m_dirty = false;
|
m_dirty = false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,9 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "hvisor_hw_stop_point_manager.hpp"
|
#include "hvisor_hw_stop_point_manager.hpp"
|
||||||
|
#include "hvisor_core_context.hpp"
|
||||||
#include "cpu/hvisor_cpu_instructions.hpp"
|
#include "cpu/hvisor_cpu_instructions.hpp"
|
||||||
#include "cpu/hvisor_cpu_interrupt_mask_guard.hpp"
|
#include "cpu/hvisor_cpu_interrupt_mask_guard.hpp"
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
@ -29,7 +31,7 @@ namespace ams::hvisor {
|
||||||
cpu::InterruptMaskGuard mg{};
|
cpu::InterruptMaskGuard mg{};
|
||||||
cpu::dmb();
|
cpu::dmb();
|
||||||
Reload();
|
Reload();
|
||||||
m_reloadBarrier.Reset(getActiveCoreMask());
|
m_reloadBarrier.Reset(CoreContext::GetActiveCoreMask());
|
||||||
IrqManager::GenerateSgiForAllOthers(m_irqId);
|
IrqManager::GenerateSgiForAllOthers(m_irqId);
|
||||||
m_reloadBarrier.Join();
|
m_reloadBarrier.Join();
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,10 +18,10 @@
|
||||||
|
|
||||||
#include "hvisor_irq_manager.hpp"
|
#include "hvisor_irq_manager.hpp"
|
||||||
#include "hvisor_virtual_gic.hpp"
|
#include "hvisor_virtual_gic.hpp"
|
||||||
|
#include "hvisor_core_context.hpp"
|
||||||
|
|
||||||
#include "cpu/hvisor_cpu_interrupt_mask_guard.hpp"
|
#include "cpu/hvisor_cpu_interrupt_mask_guard.hpp"
|
||||||
#include "platform/interrupt_config.h"
|
#include "platform/interrupt_config.h"
|
||||||
#include "core_ctx.h"
|
|
||||||
#include "guest_timers.h"
|
#include "guest_timers.h"
|
||||||
#include "transport_interface.h"
|
#include "transport_interface.h"
|
||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
|
@ -79,7 +79,7 @@ namespace ams::hvisor {
|
||||||
void IrqManager::InitializeGic()
|
void IrqManager::InitializeGic()
|
||||||
{
|
{
|
||||||
// Reinits the GICD and GICC (for non-secure mode, obviously)
|
// Reinits the GICD and GICC (for non-secure mode, obviously)
|
||||||
if (currentCoreCtx->isBootCore && !currentCoreCtx->warmboot) {
|
if (currentCoreCtx->IsBootCore() && currentCoreCtx->IsColdboot()) {
|
||||||
// Disable interrupt handling & global interrupt distribution
|
// Disable interrupt handling & global interrupt distribution
|
||||||
gicd->ctlr = 0;
|
gicd->ctlr = 0;
|
||||||
|
|
||||||
|
@ -97,7 +97,7 @@ namespace ams::hvisor {
|
||||||
// Only one core will reset the GIC state for the shared peripheral interrupts
|
// Only one core will reset the GIC state for the shared peripheral interrupts
|
||||||
|
|
||||||
u32 numInterrupts = 32;
|
u32 numInterrupts = 32;
|
||||||
if (currentCoreCtx->isBootCore) {
|
if (currentCoreCtx->IsBootCore()) {
|
||||||
numInterrupts += m_numSharedInterrupts;
|
numInterrupts += m_numSharedInterrupts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,7 +133,7 @@ namespace ams::hvisor {
|
||||||
// Now, reenable interrupts
|
// Now, reenable interrupts
|
||||||
|
|
||||||
// Enable the distributor
|
// Enable the distributor
|
||||||
if (currentCoreCtx->isBootCore) {
|
if (currentCoreCtx->IsBootCore()) {
|
||||||
gicd->ctlr = 1;
|
gicd->ctlr = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "hvisor_sw_breakpoint_manager.hpp"
|
#include "hvisor_sw_breakpoint_manager.hpp"
|
||||||
|
#include "hvisor_core_context.hpp"
|
||||||
#include "cpu/hvisor_cpu_instructions.hpp"
|
#include "cpu/hvisor_cpu_instructions.hpp"
|
||||||
#include "cpu/hvisor_cpu_interrupt_mask_guard.hpp"
|
#include "cpu/hvisor_cpu_interrupt_mask_guard.hpp"
|
||||||
|
|
||||||
|
@ -84,7 +85,7 @@ namespace ams::hvisor {
|
||||||
bool SwBreakpointManager::ApplyOrRevert(size_t id, bool apply)
|
bool SwBreakpointManager::ApplyOrRevert(size_t id, bool apply)
|
||||||
{
|
{
|
||||||
cpu::InterruptMaskGuard mg{};
|
cpu::InterruptMaskGuard mg{};
|
||||||
m_applyBarrier.Reset(getActiveCoreMask());
|
m_applyBarrier.Reset(CoreContext::GetActiveCoreMask());
|
||||||
IrqManager::GenerateSgiForAllOthers(IrqManager::ApplyRevertSwBreakpointSgi);
|
IrqManager::GenerateSgiForAllOthers(IrqManager::ApplyRevertSwBreakpointSgi);
|
||||||
if (apply) {
|
if (apply) {
|
||||||
DoApply(id);
|
DoApply(id);
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "hvisor_synchronization.hpp"
|
#include "hvisor_synchronization.hpp"
|
||||||
#include "core_ctx.h"
|
#include "hvisor_core_context.hpp"
|
||||||
|
|
||||||
namespace ams::hvisor {
|
namespace ams::hvisor {
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ namespace ams::hvisor {
|
||||||
|
|
||||||
void Barrier::Join()
|
void Barrier::Join()
|
||||||
{
|
{
|
||||||
const u32 mask = BIT(currentCoreCtx->coreId);
|
const u32 mask = BIT(currentCoreCtx->GetCoreId());
|
||||||
u32 newval, tmp;
|
u32 newval, tmp;
|
||||||
__asm__ __volatile__(
|
__asm__ __volatile__(
|
||||||
"prfm pstl1keep, %[val] \n"
|
"prfm pstl1keep, %[val] \n"
|
||||||
|
@ -75,7 +75,7 @@ namespace ams::hvisor {
|
||||||
|
|
||||||
void RecursiveSpinlock::lock()
|
void RecursiveSpinlock::lock()
|
||||||
{
|
{
|
||||||
u32 tag = currentCoreCtx->coreId + 1;
|
u32 tag = currentCoreCtx->GetCoreId() + 1;
|
||||||
if (AMS_LIKELY(tag != m_tag)) {
|
if (AMS_LIKELY(tag != m_tag)) {
|
||||||
m_spinlock.lock();
|
m_spinlock.lock();
|
||||||
m_tag = tag;
|
m_tag = tag;
|
||||||
|
|
|
@ -18,7 +18,6 @@
|
||||||
|
|
||||||
#include "defines.hpp"
|
#include "defines.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace ams::hvisor {
|
namespace ams::hvisor {
|
||||||
|
|
||||||
class Spinlock final {
|
class Spinlock final {
|
||||||
|
|
|
@ -161,7 +161,7 @@ namespace ams::hvisor {
|
||||||
VirqState &state = GetVirqState(id);
|
VirqState &state = GetVirqState(id);
|
||||||
if (state.IsPending()) {
|
if (state.IsPending()) {
|
||||||
u8 oldList = state.targetList;
|
u8 oldList = state.targetList;
|
||||||
u8 diffList = (oldList ^ coreList) & getActiveCoreMask();
|
u8 diffList = (oldList ^ coreList) & CoreContext::GetActiveCoreMask();
|
||||||
if (diffList != 0) {
|
if (diffList != 0) {
|
||||||
NotifyOtherCoreList(diffList);
|
NotifyOtherCoreList(diffList);
|
||||||
}
|
}
|
||||||
|
@ -211,20 +211,20 @@ namespace ams::hvisor {
|
||||||
break;
|
break;
|
||||||
case GicV2Distributor::ForwardToAllOthers:
|
case GicV2Distributor::ForwardToAllOthers:
|
||||||
// Forward to all but current core
|
// Forward to all but current core
|
||||||
coreList = ~BIT(currentCoreCtx->coreId);
|
coreList = ~BIT(currentCoreCtx->GetCoreId());
|
||||||
break;
|
break;
|
||||||
case GicV2Distributor::ForwardToSelf:
|
case GicV2Distributor::ForwardToSelf:
|
||||||
// Forward to current core only
|
// Forward to current core only
|
||||||
coreList = BIT(currentCoreCtx->coreId);
|
coreList = BIT(currentCoreCtx->GetCoreId());
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
DEBUG("Emulated GCID_SGIR: invalid TargetListFilter value!\n");
|
DEBUG("Emulated GCID_SGIR: invalid TargetListFilter value!\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
coreList &= getActiveCoreMask();
|
coreList &= CoreContext::GetActiveCoreMask();
|
||||||
for (u32 dstCore: util::BitsOf{coreList}) {
|
for (u32 dstCore: util::BitsOf{coreList}) {
|
||||||
SetSgiPendingState(id, dstCore, currentCoreCtx->coreId);
|
SetSgiPendingState(id, dstCore, currentCoreCtx->GetCoreId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -466,12 +466,12 @@ namespace ams::hvisor {
|
||||||
{
|
{
|
||||||
size_t numChosen = 0;
|
size_t numChosen = 0;
|
||||||
auto pred = [](const VirqState &state) {
|
auto pred = [](const VirqState &state) {
|
||||||
if (state.irqId < 32 && state.coreId != currentCoreCtx->coreId) {
|
if (state.irqId < 32 && state.coreId != currentCoreCtx->GetCoreId()) {
|
||||||
// We can't handle SGIs/PPIs of other cores.
|
// We can't handle SGIs/PPIs of other cores.
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return state.enabled && (state.irqId < 32 || (state.targetList & BIT(currentCoreCtx->coreId)) != 0);
|
return state.enabled && (state.irqId < 32 || (state.targetList & BIT(currentCoreCtx->GetCoreId())) != 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
for (VirqState &state: m_virqPendingQueue) {
|
for (VirqState &state: m_virqPendingQueue) {
|
||||||
|
@ -482,7 +482,7 @@ namespace ams::hvisor {
|
||||||
|
|
||||||
for (size_t i = 0; i < numChosen; i++) {
|
for (size_t i = 0; i < numChosen; i++) {
|
||||||
chosen[i]->handled = true;
|
chosen[i]->handled = true;
|
||||||
chosen[i]->coreId = currentCoreCtx->coreId;
|
chosen[i]->coreId = currentCoreCtx->GetCoreId();
|
||||||
m_virqPendingQueue.erase(*chosen[i]);
|
m_virqPendingQueue.erase(*chosen[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -536,7 +536,7 @@ namespace ams::hvisor {
|
||||||
ENSURE(state.handled);
|
ENSURE(state.handled);
|
||||||
|
|
||||||
u32 srcCoreId = state.coreId;
|
u32 srcCoreId = state.coreId;
|
||||||
u32 coreId = currentCoreCtx->coreId;
|
u32 coreId = currentCoreCtx->GetCoreId();
|
||||||
|
|
||||||
state.active = lrCopy.active;
|
state.active = lrCopy.active;
|
||||||
|
|
||||||
|
@ -598,7 +598,7 @@ namespace ams::hvisor {
|
||||||
void VirtualGic::UpdateState()
|
void VirtualGic::UpdateState()
|
||||||
{
|
{
|
||||||
GicV2VirtualInterfaceController::HypervisorControlRegister hcr = { .raw = gich->hcr.raw };
|
GicV2VirtualInterfaceController::HypervisorControlRegister hcr = { .raw = gich->hcr.raw };
|
||||||
u32 coreId = currentCoreCtx->coreId;
|
u32 coreId = currentCoreCtx->GetCoreId();
|
||||||
|
|
||||||
// First, put back inactive interrupts into the queue, handle some SGI stuff
|
// First, put back inactive interrupts into the queue, handle some SGI stuff
|
||||||
// Need to handle the LRs in reverse order to keep list stability
|
// Need to handle the LRs in reverse order to keep list stability
|
||||||
|
@ -651,29 +651,29 @@ namespace ams::hvisor {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (misr.vgrp0e) {
|
if (misr.vgrp0e) {
|
||||||
DEBUG("EL2 [core %d]: Group 0 enabled maintenance interrupt\n", (int)currentCoreCtx->coreId);
|
DEBUG("EL2 [core %d]: Group 0 enabled maintenance interrupt\n", (int)currentCoreCtx->GetCoreId());
|
||||||
gich->hcr.vgrp0eie = false;
|
gich->hcr.vgrp0eie = false;
|
||||||
gich->hcr.vgrp0die = true;
|
gich->hcr.vgrp0die = true;
|
||||||
} else if (misr.vgrp0d) {
|
} else if (misr.vgrp0d) {
|
||||||
DEBUG("EL2 [core %d]: Group 0 disabled maintenance interrupt\n", (int)currentCoreCtx->coreId);
|
DEBUG("EL2 [core %d]: Group 0 disabled maintenance interrupt\n", (int)currentCoreCtx->GetCoreId());
|
||||||
gich->hcr.vgrp0eie = true;
|
gich->hcr.vgrp0eie = true;
|
||||||
gich->hcr.vgrp0die = false;
|
gich->hcr.vgrp0die = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Already handled the following 2 above:
|
// Already handled the following 2 above:
|
||||||
if (misr.vgrp1e) {
|
if (misr.vgrp1e) {
|
||||||
DEBUG("EL2 [core %d]: Group 1 enabled maintenance interrupt\n", (int)currentCoreCtx->coreId);
|
DEBUG("EL2 [core %d]: Group 1 enabled maintenance interrupt\n", (int)currentCoreCtx->GetCoreId());
|
||||||
}
|
}
|
||||||
if (misr.vgrp1d) {
|
if (misr.vgrp1d) {
|
||||||
DEBUG("EL2 [core %d]: Group 1 disabled maintenance interrupt\n", (int)currentCoreCtx->coreId);
|
DEBUG("EL2 [core %d]: Group 1 disabled maintenance interrupt\n", (int)currentCoreCtx->GetCoreId());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (misr.eoi) {
|
if (misr.eoi) {
|
||||||
//DEBUG("EL2 [core %d]: SGI EOI maintenance interrupt\n", currentCoreCtx->coreId);
|
//DEBUG("EL2 [core %d]: SGI EOI maintenance interrupt\n", currentCoreCtx->GetCoreId());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (misr.u) {
|
if (misr.u) {
|
||||||
//DEBUG("EL2 [core %d]: Underflow maintenance interrupt\n", currentCoreCtx->coreId);
|
//DEBUG("EL2 [core %d]: Underflow maintenance interrupt\n", currentCoreCtx->GetCoreId());
|
||||||
}
|
}
|
||||||
|
|
||||||
ENSURE2(!misr.lrenp, "List Register Entry Not Present maintenance interrupt!\n");
|
ENSURE2(!misr.lrenp, "List Register Entry Not Present maintenance interrupt!\n");
|
||||||
|
@ -691,7 +691,7 @@ namespace ams::hvisor {
|
||||||
|
|
||||||
void VirtualGic::Initialize()
|
void VirtualGic::Initialize()
|
||||||
{
|
{
|
||||||
if (currentCoreCtx->isBootCore) {
|
if (currentCoreCtx->IsBootCore()) {
|
||||||
m_virqPendingQueue.Initialize(m_virqStates.data());
|
m_virqPendingQueue.Initialize(m_virqStates.data());
|
||||||
m_numListRegisters = static_cast<u8>(1 + (gich->vtr & 0x3F));
|
m_numListRegisters = static_cast<u8>(1 + (gich->vtr & 0x3F));
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "defines.hpp"
|
#include "defines.hpp"
|
||||||
|
#include "hvisor_core_context.hpp"
|
||||||
#include "cpu/hvisor_cpu_exception_sysregs.hpp"
|
#include "cpu/hvisor_cpu_exception_sysregs.hpp"
|
||||||
#include "hvisor_irq_manager.hpp"
|
#include "hvisor_irq_manager.hpp"
|
||||||
#include "memory_map.h"
|
#include "memory_map.h"
|
||||||
|
@ -233,7 +234,7 @@ namespace ams::hvisor {
|
||||||
private:
|
private:
|
||||||
static void NotifyOtherCoreList(u32 coreList)
|
static void NotifyOtherCoreList(u32 coreList)
|
||||||
{
|
{
|
||||||
coreList &= ~BIT(currentCoreCtx->coreId);
|
coreList &= ~BIT(currentCoreCtx->GetCoreId());
|
||||||
if (coreList != 0) {
|
if (coreList != 0) {
|
||||||
IrqManager::GenerateSgiForList(IrqManager::VgicUpdateSgi, coreList);
|
IrqManager::GenerateSgiForList(IrqManager::VgicUpdateSgi, coreList);
|
||||||
}
|
}
|
||||||
|
@ -273,7 +274,7 @@ namespace ams::hvisor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
VirqState &GetVirqState(u32 id) { return GetVirqState(currentCoreCtx->coreId, id); }
|
VirqState &GetVirqState(u32 id) { return GetVirqState(currentCoreCtx->GetCoreId(), id); }
|
||||||
|
|
||||||
void SetDistributorControlRegister(u32 value)
|
void SetDistributorControlRegister(u32 value)
|
||||||
{
|
{
|
||||||
|
@ -315,17 +316,17 @@ namespace ams::hvisor {
|
||||||
bool GetInterruptEnabledState(u32 id)
|
bool GetInterruptEnabledState(u32 id)
|
||||||
{
|
{
|
||||||
// SGIs are always enabled
|
// SGIs are always enabled
|
||||||
return id < 16 || (IrqManager::IsGuestInterrupt(id) && GetVirqState(currentCoreCtx->coreId, id).enabled);
|
return id < 16 || (IrqManager::IsGuestInterrupt(id) && GetVirqState(currentCoreCtx->GetCoreId(), id).enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 GetInterruptPriorityByte(u32 id)
|
u8 GetInterruptPriorityByte(u32 id)
|
||||||
{
|
{
|
||||||
return IrqManager::IsGuestInterrupt(id) ? GetVirqState(currentCoreCtx->coreId, id).priority << priorityShift : 0;
|
return IrqManager::IsGuestInterrupt(id) ? GetVirqState(currentCoreCtx->GetCoreId(), id).priority << priorityShift : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 GetInterruptTargets(u16 id)
|
u8 GetInterruptTargets(u16 id)
|
||||||
{
|
{
|
||||||
return id < 32 || (IrqManager::IsGuestInterrupt(id) && GetVirqState(currentCoreCtx->coreId, id).targetList);
|
return id < 32 || (IrqManager::IsGuestInterrupt(id) && GetVirqState(currentCoreCtx->GetCoreId(), id).targetList);
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 GetInterruptConfigBits(u16 id)
|
u32 GetInterruptConfigBits(u16 id)
|
||||||
|
@ -357,7 +358,7 @@ namespace ams::hvisor {
|
||||||
if (ff == 0) {
|
if (ff == 0) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
} else {
|
} else {
|
||||||
m_usedLrMap[currentCoreCtx->coreId] |= BITL(ff - 1);
|
m_usedLrMap[currentCoreCtx->GetCoreId()] |= BITL(ff - 1);
|
||||||
return &gich->lr[ff - 1];
|
return &gich->lr[ff - 1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
#define ENSURE2(expr, msg, ...)\
|
#define ENSURE2(expr, msg, ...)\
|
||||||
do {\
|
do {\
|
||||||
if (UNLIKELY(!(expr))) {\
|
if (UNLIKELY(!(expr))) {\
|
||||||
PANIC("EL2 [core %u]: " __FILE__ ":" STRINGIZE(__LINE__) ": " msg, currentCoreCtx->coreId, ##__VA_ARGS__);\
|
PANIC("EL2 [core %u]: " __FILE__ ":" STRINGIZE(__LINE__) ": " msg, currentCoreCtx->GetCoreId(), ##__VA_ARGS__);\
|
||||||
}\
|
}\
|
||||||
} while (false)
|
} while (false)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue