thermosphere: propagate some changes

This commit is contained in:
TuxSH 2020-02-23 01:30:35 +00:00
parent 5b56d05e11
commit 036883c30f
16 changed files with 114 additions and 99 deletions

View file

@ -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)\

View file

@ -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));
} }

View file

@ -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 {

View file

@ -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();

View file

@ -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: {

View file

@ -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)

View file

@ -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)
{ {

View file

@ -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;
} }

View file

@ -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();
} }

View file

@ -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;
} }

View file

@ -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);

View file

@ -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;

View file

@ -18,7 +18,6 @@
#include "defines.hpp" #include "defines.hpp"
namespace ams::hvisor { namespace ams::hvisor {
class Spinlock final { class Spinlock final {

View file

@ -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));

View file

@ -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];
} }
} }

View file

@ -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)