2008-03-05 09:52:00 -05:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
//
|
|
|
|
// Microsoft Research Singularity
|
|
|
|
//
|
|
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
|
|
//
|
|
|
|
// File: Hal.cpp
|
|
|
|
//
|
2008-11-17 18:29:00 -05:00
|
|
|
// Note: Kernel Only
|
2008-03-05 09:52:00 -05:00
|
|
|
//
|
|
|
|
|
|
|
|
#include "hal.h"
|
|
|
|
#include "halkd.h"
|
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
#include "strformat.cpp"
|
2008-03-05 09:52:00 -05:00
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
int __cdecl _cinit(void);
|
2008-03-05 09:52:00 -05:00
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
#if ISA_ARM
|
|
|
|
void SerialInit(UINT32 * uartBase);
|
|
|
|
void SerialOutHex(uint32 value);
|
|
|
|
void SerialOut(const char * str);
|
|
|
|
#define ArmSerialInit(x) SerialInit(x)
|
|
|
|
#define ArmSerialOut(x) SerialOut(x)
|
|
|
|
#define ArmSerialOutHex(x) SerialOutHex(x)
|
|
|
|
#else // ISA_ARM
|
|
|
|
#define ArmSerialInit(x)
|
|
|
|
#define ArmSerialOut(x)
|
|
|
|
#define ArmSerialOutHex(x)
|
|
|
|
#endif // ISA_ARM
|
2008-03-05 09:52:00 -05:00
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Kernel methods
|
|
|
|
//
|
|
|
|
extern wchar_t _LinkDate[];
|
2008-03-05 09:52:00 -05:00
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
bartok_char *
|
|
|
|
Class_Microsoft_Singularity_Kernel::g_HalGetLinkDate()
|
2008-03-05 09:52:00 -05:00
|
|
|
{
|
2008-11-17 18:29:00 -05:00
|
|
|
return (bartok_char *)_LinkDate;
|
2008-03-05 09:52:00 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
void fail_assert(const char *expr)
|
|
|
|
{
|
2008-11-17 18:29:00 -05:00
|
|
|
// TODO: wire up something useful here.
|
|
|
|
__debugbreak();
|
2008-03-05 09:52:00 -05:00
|
|
|
}
|
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////
|
2008-03-05 09:52:00 -05:00
|
|
|
//
|
2008-11-17 18:29:00 -05:00
|
|
|
Class_System_RuntimeType *CpuRuntimeType = &Class_Microsoft_Singularity_Hal_Cpu::_type;
|
|
|
|
Class_System_RuntimeType *PlatformRuntimeType = &Class_Microsoft_Singularity_Hal_Platform::_type;
|
2008-03-05 09:52:00 -05:00
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
Class_Microsoft_Singularity_Hal_Cpu *Class_Microsoft_Singularity_Hal_Platform::g_GetCurrentCpu()
|
2008-03-05 09:52:00 -05:00
|
|
|
{
|
2008-11-17 18:29:00 -05:00
|
|
|
return (Class_Microsoft_Singularity_Hal_Cpu *)
|
|
|
|
Class_Microsoft_Singularity_Processor::g_GetCurrentProcessorContext()->halCpu;
|
2008-03-05 09:52:00 -05:00
|
|
|
}
|
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
void Struct_Microsoft_Singularity_MpBootInfo::g_HalReleaseMpStartupLock()
|
2008-03-05 09:52:00 -05:00
|
|
|
{
|
2008-11-17 18:29:00 -05:00
|
|
|
uint32 lockAddr =
|
|
|
|
(uint32)Class_Microsoft_Singularity_Hal_Platform::c_thePlatform->MpStartupLock32;
|
|
|
|
if (lockAddr != 0) {
|
|
|
|
*((uint16*) lockAddr) = 0;
|
2008-03-05 09:52:00 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
void InitCpu(Class_Microsoft_Singularity_Hal_Cpu *pi)
|
2008-03-05 09:52:00 -05:00
|
|
|
{
|
2008-11-17 18:29:00 -05:00
|
|
|
ArmSerialOut("InitCpu0\n");
|
|
|
|
ArmSerialOutHex(pi->Id);
|
|
|
|
ArmSerialOut("\n");
|
2008-03-05 09:52:00 -05:00
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
Class_Microsoft_Singularity_Hal_Cpu *hpi = (Class_Microsoft_Singularity_Hal_Cpu*) pi;
|
2008-03-05 09:52:00 -05:00
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
hpi->postHeader.vtableObject = CpuRuntimeType->classVtable;
|
2008-03-05 09:52:00 -05:00
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
ArmSerialOut("InitCpu1\n");
|
2008-03-05 09:52:00 -05:00
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
Class_Microsoft_Singularity_Hal_Cpu::m_Initialize(hpi);
|
2008-03-05 09:52:00 -05:00
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
ArmSerialOut("InitCpu2\n");
|
2008-03-05 09:52:00 -05:00
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
Class_Microsoft_Singularity_Isal_Isa::g_InitializeCpuDispatchTable();
|
2008-03-05 09:52:00 -05:00
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
ArmSerialOut("InitCpu3\n");
|
2008-03-05 09:52:00 -05:00
|
|
|
}
|
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
void ShutdownCpu(Class_Microsoft_Singularity_Hal_Cpu *pi)
|
2008-03-05 09:52:00 -05:00
|
|
|
{
|
2008-11-17 18:29:00 -05:00
|
|
|
#if ISA_IX86 || ISA_IX64
|
|
|
|
// Disable Interrupts and then spin a screen icon waiting to be reset.
|
2008-03-05 09:52:00 -05:00
|
|
|
Class_Microsoft_Singularity_Processor::g_DisableInterrupts();
|
2008-11-17 18:29:00 -05:00
|
|
|
|
|
|
|
int cpu = pi->Id;
|
2008-03-05 09:52:00 -05:00
|
|
|
for (int i = 0; i != i + 1; i++) {
|
|
|
|
uint16* p = (uint16*)(0xb8000 + (cpu - 1) * 2 * 8);
|
|
|
|
for (int r = 0; r < 8; r++) {
|
|
|
|
uint16 t = (uint16)(i >> (28 - r * 4));
|
|
|
|
t &= 0xf;
|
|
|
|
if (t > 9) {
|
|
|
|
t += 0x1f00 + 'a' - 10;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
t += 0x1f00 + '0';
|
|
|
|
}
|
|
|
|
*p++ = t;
|
|
|
|
if (Class_Microsoft_Singularity_DebugStub::g_PollForBreak() == true) {
|
2008-11-17 18:29:00 -05:00
|
|
|
__debugbreak();
|
2008-03-05 09:52:00 -05:00
|
|
|
}
|
|
|
|
for (int i = 0; i < 50000; i++) {
|
2008-11-17 18:29:00 -05:00
|
|
|
__nop();
|
2008-03-05 09:52:00 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2008-11-17 18:29:00 -05:00
|
|
|
#endif
|
2008-03-05 09:52:00 -05:00
|
|
|
}
|
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
void InitPlatform(Class_Microsoft_Singularity_Hal_Platform *bi,
|
|
|
|
Class_Microsoft_Singularity_Hal_Cpu *pi)
|
2008-03-05 09:52:00 -05:00
|
|
|
{
|
2008-11-17 18:29:00 -05:00
|
|
|
ArmSerialOut("InitPlatform0");
|
2008-03-05 09:52:00 -05:00
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
#ifndef ISA_ARM
|
|
|
|
Class_Microsoft_Singularity_Isal_Isa::g_InitializeDispatchTable();
|
|
|
|
#endif
|
2008-03-05 09:52:00 -05:00
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
InitCpu(pi);
|
2008-03-05 09:52:00 -05:00
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
ArmSerialOut("InitPlatform2");
|
2008-03-05 09:52:00 -05:00
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
Class_Microsoft_Singularity_Hal_Platform *nbi = (Class_Microsoft_Singularity_Hal_Platform *) bi;
|
|
|
|
nbi->postHeader.vtableObject = PlatformRuntimeType->classVtable;
|
2008-03-05 09:52:00 -05:00
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
// Call early init routines
|
2008-03-05 09:52:00 -05:00
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
Class_Microsoft_Singularity_Hal_Platform::m_Initialize(nbi,
|
|
|
|
(Class_Microsoft_Singularity_Hal_Cpu *) pi);
|
2008-03-05 09:52:00 -05:00
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
ArmSerialOut("InitPlatform3");
|
2008-03-05 09:52:00 -05:00
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
kdprintf("DebugPort: %04x\n", nbi->DebugBasePort);
|
2008-03-05 09:52:00 -05:00
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
ArmSerialOut("InitPlatform4");
|
2008-03-05 09:52:00 -05:00
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
// Initialize the debugger hardware
|
2008-03-05 09:52:00 -05:00
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
if (KdpSerialInit(nbi)) {
|
|
|
|
nbi->DebuggerType = Class_Microsoft_Singularity_Hal_Platform_DEBUGGER_SERIAL;
|
2008-03-05 09:52:00 -05:00
|
|
|
}
|
|
|
|
else {
|
2008-11-17 18:29:00 -05:00
|
|
|
nbi->DebuggerType = Class_Microsoft_Singularity_Hal_Platform_DEBUGGER_NONE;
|
2008-03-05 09:52:00 -05:00
|
|
|
}
|
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
ArmSerialOut("Calling Kernel.Main:\n");
|
2008-03-05 09:52:00 -05:00
|
|
|
}
|
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
void ShutdownPlatform(Class_Microsoft_Singularity_Hal_Platform *bi)
|
|
|
|
{
|
|
|
|
}
|
2008-03-05 09:52:00 -05:00
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
//
|
2008-11-17 18:29:00 -05:00
|
|
|
// These are the first instruction executed in the kernel.
|
2008-03-05 09:52:00 -05:00
|
|
|
//
|
2008-11-17 18:29:00 -05:00
|
|
|
extern "C" int __fastcall HalEntryPoint(
|
|
|
|
Class_Microsoft_Singularity_Hal_Platform *bi,
|
|
|
|
Class_Microsoft_Singularity_Hal_Cpu *pi)
|
|
|
|
{
|
|
|
|
ArmSerialInit((UINT32 *) 0xffd82300);
|
|
|
|
ArmSerialOut("HalEntry 1\n");
|
|
|
|
|
|
|
|
if (bi->Size != sizeof(Class_Microsoft_Singularity_Hal_Platform)) {
|
|
|
|
__debugbreak();
|
|
|
|
return Class_Microsoft_Singularity_Hal_Platform_ERROR_BAD_SIZE;
|
|
|
|
}
|
2008-03-05 09:52:00 -05:00
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
if (pi->Id == 0) {
|
2008-03-05 09:52:00 -05:00
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
// Static C++ constructors. Ideally, there would be none.
|
|
|
|
_cinit();
|
2008-03-05 09:52:00 -05:00
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
ArmSerialOut("HalEntry 2\n");
|
2008-03-05 09:52:00 -05:00
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
// Initialize the target.
|
|
|
|
Class_Microsoft_Singularity_Isal_Isa::g_Initialize(bi->CpuRecordPointerOffset,
|
|
|
|
bi->ThreadRecordPointerOffset);
|
2008-03-05 09:52:00 -05:00
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
Class_Microsoft_Singularity_Isal_Isa::g_InitializeCpu(
|
|
|
|
(Struct_Microsoft_Singularity_Isal_CpuRecord *)pi->CpuRecordPage,
|
|
|
|
pi->Id,
|
|
|
|
(UIntPtr) pi->KernelStackLimit);
|
2008-03-05 09:52:00 -05:00
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
ArmSerialOut("HalEntry 3\n");
|
2008-03-05 09:52:00 -05:00
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
// Initialize processor context
|
|
|
|
ProcessorInitialize(pi);
|
2008-03-05 09:52:00 -05:00
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
ArmSerialOut("HalEntry 4\n");
|
2008-03-05 09:52:00 -05:00
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
// Assert that processor local store is working correctly
|
|
|
|
if (Class_Microsoft_Singularity_Hal_Platform::g_GetCurrentCpu() != pi) {
|
|
|
|
__debugbreak();
|
|
|
|
}
|
2008-03-05 09:52:00 -05:00
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
ArmSerialOut("HalEntry 6\n");
|
2008-03-05 09:52:00 -05:00
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
// Set up native-only constants
|
|
|
|
// Initialize platform (in a platform-specific way)
|
|
|
|
InitPlatform(bi, pi);
|
|
|
|
ArmSerialOut("HalEntry 7\n");
|
2008-03-05 09:52:00 -05:00
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
// Initialize tracing
|
|
|
|
Class_Microsoft_Singularity_Tracing::g_Initialize();
|
|
|
|
|
|
|
|
ArmSerialOut("HalEntry 8\n");
|
|
|
|
|
|
|
|
// Initialize debugger
|
|
|
|
KdInitialize(bi);
|
|
|
|
|
|
|
|
ArmSerialOut("HalEntry 9\n");
|
|
|
|
|
|
|
|
// Initial breakpoint - uncomment me to do early debugging
|
|
|
|
//if (bi->DebuggerType != Class_Microsoft_Singularity_Hal_Platform_DEBUGGER_NONE) {
|
|
|
|
// __debugbreak();
|
|
|
|
//}
|
|
|
|
|
|
|
|
Class_Microsoft_Singularity_Kernel::g_Main();
|
|
|
|
|
|
|
|
ShutdownPlatform(bi);
|
|
|
|
// Native exits by returning back to the undump/bootloader
|
|
|
|
return 0;
|
2008-03-05 09:52:00 -05:00
|
|
|
}
|
2008-11-17 18:29:00 -05:00
|
|
|
else {
|
|
|
|
// Initialize the target cpu.
|
|
|
|
Class_Microsoft_Singularity_Isal_Isa::g_InitializeCpu(
|
|
|
|
(Struct_Microsoft_Singularity_Isal_CpuRecord *)pi->CpuRecordPage,
|
|
|
|
pi->Id,
|
|
|
|
(UIntPtr) pi->KernelStackLimit);
|
2008-03-05 09:52:00 -05:00
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
// Initialize processor context
|
|
|
|
ProcessorInitialize(pi);
|
2008-03-05 09:52:00 -05:00
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
// Initialize platform processor
|
|
|
|
InitCpu(pi);
|
2008-03-05 09:52:00 -05:00
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
// Assert that processor local store is working correctly
|
|
|
|
if (Class_Microsoft_Singularity_Hal_Platform::g_GetCurrentCpu() != pi) {
|
|
|
|
__debugbreak();
|
|
|
|
}
|
|
|
|
|
|
|
|
int result = Class_Microsoft_Singularity_Kernel::g_MpMain(pi->Id);
|
2008-03-05 09:52:00 -05:00
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
ShutdownCpu(pi);
|
|
|
|
|
|
|
|
return Class_Microsoft_Singularity_Hal_Platform_SUCCESS;
|
|
|
|
}
|
2008-03-05 09:52:00 -05:00
|
|
|
}
|