forked from mosa/MOSA-Project
/
MultibootV1Stage.cs
53 lines (42 loc) · 2.17 KB
/
MultibootV1Stage.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
// Copyright (c) MOSA Project. Licensed under the New BSD License.
using Mosa.Compiler.Framework;
using Mosa.Compiler.MosaTypeSystem;
using Mosa.Platform.Intel;
namespace Mosa.Platform.x64.CompilerStages
{
public sealed class MultibootV1Stage : Intel.CompilerStages.MultibootV1Stage
{
protected override void CreateMultibootMethod()
{
var eax = Operand.CreateCPURegister(TypeSystem.BuiltIn.I8, GeneralPurposeRegister.EAX);
var ebx = Operand.CreateCPURegister(TypeSystem.BuiltIn.I8, GeneralPurposeRegister.EBX);
var ebp = Operand.CreateCPURegister(TypeSystem.BuiltIn.I8, GeneralPurposeRegister.EBP);
var esp = Operand.CreateCPURegister(TypeSystem.BuiltIn.I8, GeneralPurposeRegister.ESP);
var multibootEAX = Operand.CreateUnmanagedSymbolPointer(MultibootEAX, TypeSystem);
var multibootEBX = Operand.CreateUnmanagedSymbolPointer(MultibootEBX, TypeSystem);
var stackTop = CreateConstant(STACK_ADDRESS);
var zero = CreateConstant(0);
var offset = CreateConstant(8);
var basicBlocks = new BasicBlocks();
var block = basicBlocks.CreateBlock(BasicBlock.PrologueLabel);
basicBlocks.AddHeadBlock(block);
var ctx = new Context(block);
// Setup the stack and place the sentinel on the stack to indicate the start of the stack
ctx.AppendInstruction(X64.Mov64, esp, stackTop);
ctx.AppendInstruction(X64.Mov64, ebp, stackTop);
ctx.AppendInstruction(X64.MovStore64, null, esp, zero, zero);
ctx.AppendInstruction(X64.MovStore64, null, esp, offset, zero);
// Place the multiboot address into a static field
ctx.AppendInstruction(X64.MovStore64, null, multibootEAX, zero, eax);
ctx.AppendInstruction(X64.MovStore64, null, multibootEBX, zero, ebx);
var startUpType = TypeSystem.GetTypeByName("Mosa.Runtime", "StartUp");
var initializeMethod = startUpType.FindMethodByName("Initialize");
var entryPoint = Operand.CreateSymbolFromMethod(initializeMethod, TypeSystem);
ctx.AppendInstruction(X64.Call, null, entryPoint);
ctx.AppendInstruction(X64.Ret);
Compiler.CompileMethod(multibootMethod, basicBlocks);
MethodScanner.MethodInvoked(initializeMethod, multibootMethod);
MethodScanner.MethodInvoked(multibootMethod, multibootMethod);
}
}
}