singrdk/base/Kernel/Native/arm/halkdarm.cpp

321 lines
11 KiB
C++
Raw Permalink Normal View History

2008-11-17 18:29:00 -05:00
///////////////////////////////////////////////////////////////////////////////
//
// Microsoft Research Singularity
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// File: halkdarm.cpp - Processor-specific support routines for halkd.cpp.
//
#include "hal.h"
#include "halkd.h"
#define KDDBG if (0) kdprintf
extern "C" void * __cdecl memcpy(void *, const void *, size_t);
void KdpArmSetControlReport(IN OUT PDBGKD_CONTROL_REPORT report);
//////////////////////////////////////////////// User visible progress beacon.
//
void KdpSpin()
{
#if 0
extern uint16 * videoBuffer;
static uint16 values[] = { 0x0000, 0xffff, 0xfc00, 0x03f0, 0x000f };
if (videoBuffer != 0) {
static UINT8 state = 0;
videoBuffer[0] = values[state];
videoBuffer[1] = values[state];
videoBuffer[2] = values[state];
videoBuffer[3] = values[state];
videoBuffer[4] = values[state];
videoBuffer[5] = values[state];
videoBuffer[6] = values[state];
videoBuffer[7] = values[state];
state++;
if (state >= arrayof(values)) {
state = 0;
}
}
#endif
}
//////////////////////////////////////////////////////////////////////////////
void KdpToKdContext(IN CONST Struct_Microsoft_Singularity_Isal_SpillContext *singularity,
OUT CONTEXT *windbg)
{
windbg->ContextFlags = (CONTEXT_CONTROL |
CONTEXT_INTEGER);
windbg->Sp = singularity->sp;
windbg->Lr = singularity->lr;
windbg->Pc = singularity->pc;
windbg->R0 = singularity->r0;
windbg->R1 = singularity->r1;
windbg->R2 = singularity->r2;
windbg->R3 = singularity->r3;
windbg->R4 = singularity->r4;
windbg->R5 = singularity->r5;
windbg->R6 = singularity->r6;
windbg->R7 = singularity->r7;
windbg->R8 = singularity->r8;
windbg->R9 = singularity->r9;
windbg->R10 = singularity->r10;
windbg->R11 = singularity->r11;
windbg->R12 = singularity->r12;
windbg->Cpsr = singularity->cpsr;
}
void KdpFromKdContext(IN CONST CONTEXT *windbg,
OUT Struct_Microsoft_Singularity_Isal_SpillContext *singularity)
{
singularity->sp = windbg->Sp;
singularity->lr = windbg->Lr;
singularity->pc = windbg->Pc;
singularity->r0 = windbg->R0;
singularity->r1 = windbg->R1;
singularity->r2 = windbg->R2;
singularity->r3 = windbg->R3;
singularity->r4 = windbg->R4;
singularity->r5 = windbg->R5;
singularity->r6 = windbg->R6;
singularity->r7 = windbg->R7;
singularity->r8 = windbg->R8;
singularity->r9 = windbg->R9;
singularity->r10 = windbg->R10;
singularity->r11 = windbg->R11;
singularity->r12 = windbg->R12;
singularity->cpsr = windbg->Cpsr;
}
void KdpSetControlReport(IN OUT PDBGKD_CONTROL_REPORT report,
IN CONST Struct_Microsoft_Singularity_Isal_SpillContext *singularity)
{
KdpArmSetControlReport(report);
report->Cpsr = singularity->cpsr;
}
void KdpSetControlSet(IN CONST DBGKD_CONTROL_SET * control,
IN OUT Struct_Microsoft_Singularity_Isal_SpillContext *singularity)
{
// TODO: This needs to be filled in.
}
//////////////////////////////////////////////////////////////////////////////
void KdpReadSpecialRegisters(KSPECIAL_REGISTERS *pksp,
IN CONST Struct_Microsoft_Singularity_Isal_SpillContext *singularity)
{
#if 0
internal struct ArmKSpecialRegisters {
internal uint Cp15Cr0Id;
internal uint Cp15Cr0Cachetype;
internal uint Cp15Cr1Control;
internal uint Cp15Cr2Ttb;
internal uint Cp15Cr3Dacr;
internal uint Cp15Cr5FaultStatus;
internal uint Cp15Cr5FaultAddress;
internal uint Cp15Cr13ProcessId;
};
#endif
#if 0
pksp->Cp15Cr0Id = _MoveFromCoprocessor(0, 15, 0, 7, 5, 0);
#endif
}
void KdpWriteSpecialRegisters(CONST KSPECIAL_REGISTERS *pksp)
{
#if 0
#endif
}
void KdpFlushInstCache(void)
{
_MoveToCoprocessor(0, 15, 0, 7, 5, 0); // ICIALLU: Invalidate all instruction caches.
}
bool KdpReadMsr(UINT32 msr, UINT32 *plo, UINT32 *phi)
{
*phi = 0;
switch (msr) {
#undef VALID_COPROC_REGISTER
#define VALID_COPROC_REGISTER(_Coproc, _OpCode1, _CoReg1, _CoReg2, _OpCode2) \
case (_Coproc << 16) | (_OpCode1 << 12) | (_CoReg1 << 8) | (_CoReg2 << 4) | _OpCode2 : \
*plo = _MoveFromCoprocessor(_Coproc, _OpCode1, _CoReg1, _CoReg2, _OpCode2); \
break;
#include "halkdmsr.h"
default:
return false;
}
return true;
}
bool KdpWriteMsr(UINT32 msr, UINT32 lo, UINT32 hi)
{
switch (msr) {
#undef VALID_COPROC_REGISTER
#define VALID_COPROC_REGISTER(_Coproc, _OpCode1, _CoReg1, _CoReg2, _OpCode2) \
case (_Coproc << 16) | (_OpCode1 << 12) | (_CoReg1 << 8) | (_CoReg2 << 4) | _OpCode2 : \
_MoveToCoprocessor(lo, _Coproc, _OpCode1, _CoReg1, _CoReg2, _OpCode2); \
break;
#include "halkdmsr.h"
default:
return false;
}
return true;
}
//////////////////////////////////////////////////////////////////////////////
KdDebugTrapData * KdpIsDebugTrap(IN CONST Struct_Microsoft_Singularity_Isal_SpillContext *context,
int id)
{
if ((id == Struct_Microsoft_Singularity_Isal_Arm_ExceptionVector_SoftwareInterrupt) &&
(context->instruction == 0xefffff2e)) {
KDDBG("IsDebugTrap(%x) tag=%p\n", id, ((KdDebugTrapData *)(context->r0))->tag);
return (KdDebugTrapData *)(context->r0);
}
KDDBG("IsDebugTrap(%x) NULL\n", id);
return NULL;
}
// Convert a trap into a exception record.
void KdpConvertTrapToException(IN OUT EXCEPTION_RECORD64 *per,
IN OUT Struct_Microsoft_Singularity_Isal_SpillContext *context,
int id)
{
KDDBG("ConvertTrapToExc(%d)\n", id);
KDDBG(" pc=%p [%p]\n", context->pc, *((uint32*)context->pc));
KDDBG(" lr=%p r0=%p\n", context->lr, context->r0);
// Breakpoints:
switch (id) {
case Struct_Microsoft_Singularity_Isal_Arm_ExceptionVector_UndefinedInstruction: {
KDDBG("Illegal Instruction %08x\n", context->instruction);
per->ExceptionCode = STATUS_ILLEGAL_INSTRUCTION;
per->ExceptionAddress = SIGN_EXTEND(context->pc - 4);
per->NumberParameters = 0;
return;
}
case Struct_Microsoft_Singularity_Isal_Arm_ExceptionVector_PrefetchAbort: {
KDDBG("KD: Prefetch Exception %d\n", id);
per->ExceptionCode = STATUS_ACCESS_VIOLATION;
per->ExceptionAddress = SIGN_EXTEND(context->pc);
per->NumberParameters = 0;
return;
}
case Struct_Microsoft_Singularity_Isal_Arm_ExceptionVector_DataAbort: {
KDDBG("KD: Data Exception %d\n", id);
per->ExceptionCode = STATUS_ACCESS_VIOLATION;
// Should probably decode instruction to figure out the real faulty address.
per->ExceptionAddress = SIGN_EXTEND(context->pc);
per->NumberParameters = 0;
return;
}
case Struct_Microsoft_Singularity_Isal_Arm_ExceptionVector_Reset:
case Struct_Microsoft_Singularity_Isal_Arm_ExceptionVector_Irq:
case Struct_Microsoft_Singularity_Isal_Arm_ExceptionVector_Fiq: {
KDDBG("KD: Unexpected IRQ %d\n", id);
per->ExceptionCode = STATUS_UNHANDLED_EXCEPTION;
per->ExceptionAddress = SIGN_EXTEND(context->pc);
per->NumberParameters = 1;
per->ExceptionInformation0 = id;
return;
}
case Struct_Microsoft_Singularity_Isal_Arm_ExceptionVector_SoftwareInterrupt: {
switch (context->instruction) {
case 0xefffff01: { // aka KDP_BREAKPOINT_VALUE (swi 0xffff01)
KDDBG("KD Single or Bkpt\n");
per->ExceptionCode = STATUS_SINGLE_STEP;
per->ExceptionAddress = SIGN_EXTEND(context->pc);
return;
}
case 0xefffff03: { // Hard-coded break (swi 0xffff03)
KDDBG("Breakpoint\n");
per->ExceptionCode = STATUS_BREAKPOINT;
per->NumberParameters = 1;
per->ExceptionInformation0 = BREAKPOINT_BREAK;
per->ExceptionAddress = SIGN_EXTEND(context->pc - 4);
return;
}
case 0xefffff2e: { // Debug notify (swi 0xffff2e)
KdDebugTrapData *trapData = (KdDebugTrapData *) (context->r0);
switch (trapData->tag) {
case KdDebugTrapData::FIRST_CHANCE_EXCEPTION:
context->r0 = trapData->firstChanceException.throwAddr;
KDDBG("KD: First chance C# exception\n");
// per->ExceptionCode = STATUS_CPP_EH_EXCEPTION; //0xe06d7363;
per->ExceptionCode = STATUS_VCPP_EXCEPTION; //0x8000ff1f;
per->ExceptionAddress = SIGN_EXTEND(context->pc - 4);
per->NumberParameters = 1;
per->ExceptionInformation0 = BREAKPOINT_BREAK;
return;
default:
KDDBG("KD: Bad trap 0x%x\n", id);
per->ExceptionCode = STATUS_UNHANDLED_EXCEPTION;
per->ExceptionAddress = SIGN_EXTEND(context->pc - 4);
per->NumberParameters = 1;
per->ExceptionInformation0 = id;
return;
}
}
default: {
KDDBG("KD: Unexpected SWI %08x\n", context->instruction);
per->ExceptionCode = STATUS_ILLEGAL_INSTRUCTION;
per->ExceptionAddress = SIGN_EXTEND(context->pc - 4);
return;
}
}
}
default:
KDDBG("KD: Unexpected interrupt %d\n", id);
per->ExceptionCode = 0x80000000 + id;
per->ExceptionAddress = SIGN_EXTEND(context->pc);
return;
}
}
//
// Read or Write I/O Space.
//
// Return: Silently does nothing on ARM. Could be implemented
// in the future to read/write from a simulated I/O space
// if an ARM platform has such a mapping.
//
// iowrite == 0: value read from port
//
// iowrite !=0: zero
//
int KdpReadWriteIoSpace(
int size, // 1, 2, 4
int iowrite, // true if write, false if read
unsigned short addr,
unsigned int value
)
{
return 0;
}