-
Notifications
You must be signed in to change notification settings - Fork 55
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add tamago/amd64 support, microvm target (#45)
* WiP tamago/amd64 support * add CPU initialization functions * tidying * add amd64 memory initialization * tidying * tidying * initial amd64 cpuinit (LM with 2MB map) * working amd64 long mode * enable SSE * add basic COM1 support * increase RAM size * tidying * halt and catch fire * package rename riscv -> riscv64 for consistency with GOARCH * working 16550A UART driver * triple-fault on microvm exit * map page entries to cover ramStart+ramSize * set stack offset * add IsSet function * amd64 TSC support * microvm kvmclock support * microvm MC146818A RTC driver * tidying * tidying * typo fix * typo fix * URL update * documentation update * tidying * tidying * tidying * fix and simplify amd64 TLBs, reserve I/O area * tidying * initial import of WiP VirtIO driver * tidying * move VirtIO device driver outside tamago * update qemu settings * tidying * add IsSet64 function * improve VirtIO driver * improve VirtIO driver * improve VirtIO driver * improve VirtIO driver * improve VirtIO driver * improve VirtIO driver * improve VirtIO driver * improve VirtIO driver * tidying * bump release * tidying
- Loading branch information
Showing
89 changed files
with
1,800 additions
and
128 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
// x86-64 processor support | ||
// https://github.com/usbarmory/tamago | ||
// | ||
// Copyright (c) WithSecure Corporation | ||
// https://foundry.withsecure.com | ||
// | ||
// Use of this source code is governed by the license | ||
// that can be found in the LICENSE file. | ||
|
||
// Package amd64 provides support for AMD64 architecture specific operations. | ||
// | ||
// The following architectures/cores are supported/tested: | ||
// - AMD64 (single-core) | ||
// | ||
// This package is only meant to be used with `GOOS=tamago GOARCH=amd64` as | ||
// supported by the TamaGo framework for bare metal Go, see | ||
// https://github.com/usbarmory/tamago. | ||
package amd64 | ||
|
||
import ( | ||
"runtime" | ||
_ "unsafe" | ||
) | ||
|
||
//go:linkname ramStackOffset runtime.ramStackOffset | ||
var ramStackOffset uint64 = 0x100000 // 1 MB | ||
|
||
// CPU instance | ||
type CPU struct { | ||
// features | ||
invariant bool | ||
kvm bool | ||
kvmclock uint32 | ||
|
||
// Timer multiplier | ||
TimerMultiplier float64 | ||
// Timer offset in nanoseconds | ||
TimerOffset int64 | ||
// Timer function | ||
TimerFn func() uint64 | ||
} | ||
|
||
// defined in amd64.s | ||
func halt(int32) | ||
|
||
// Fault generates a triple fault. | ||
func Fault() | ||
|
||
// Init performs initialization of an AMD64 core instance. | ||
func (cpu *CPU) Init() { | ||
runtime.Exit = halt | ||
|
||
cpu.initFeatures() | ||
cpu.initTimers() | ||
} | ||
|
||
// Name returns the CPU identifier. | ||
func (cpu *CPU) Name() string { | ||
return runtime.CPU() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
// x86-64 processor support | ||
// https://github.com/usbarmory/tamago | ||
// | ||
// Copyright (c) WithSecure Corporation | ||
// https://foundry.withsecure.com | ||
// | ||
// Use of this source code is governed by the license | ||
// that can be found in the LICENSE file. | ||
|
||
// func Fault() | ||
TEXT ·Fault(SB),$0 | ||
CLI | ||
XORL AX, AX | ||
LGDT (AX) | ||
HLT | ||
|
||
// func halt(int32) | ||
TEXT ·halt(SB),$0-8 | ||
CLI | ||
halt: | ||
HLT | ||
JMP halt |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
// x86-64 processor support | ||
// https://github.com/usbarmory/tamago | ||
// | ||
// Copyright (c) WithSecure Corporation | ||
// https://foundry.withsecure.com | ||
// | ||
// Use of this source code is governed by the license | ||
// that can be found in the LICENSE file. | ||
|
||
package amd64 | ||
|
||
import ( | ||
"github.com/usbarmory/tamago/bits" | ||
) | ||
|
||
// CPUID function numbers | ||
// | ||
// (Intel® Architecture Instruction Set Extensions | ||
// and Future Features Programming Reference | ||
// 1.5 CPUID INSTRUCTION). | ||
const ( | ||
CPUID_TSC_CCC = 0x15 | ||
|
||
CPUID_APM = 0x80000007 | ||
APM_TSC_INVARIANT = 8 | ||
) | ||
|
||
// KVM CPUID function numbers | ||
// | ||
// (https://docs.kernel.org/virt/kvm/x86/cpuid.html) | ||
const ( | ||
KVM_CPUID_SIGNATURE = 0x40000000 | ||
KVM_SIGNATURE = 0x4b4d564b // "KVMK" | ||
|
||
KVM_CPUID_FEATURES = 0x40000001 | ||
FEATURES_CLOCKSOURCE = 0 | ||
FEATURES_CLOCKSOURCE2 = 3 | ||
|
||
KVM_CPUID_TSC_KHZ = 0x40000010 | ||
) | ||
|
||
// kvmclock MSRs | ||
const ( | ||
MSR_KVM_SYSTEM_TIME = 0x12 | ||
MSR_KVM_SYSTEM_TIME_NEW = 0x4b564d01 | ||
) | ||
|
||
// defined in features.s | ||
func cpuid(eaxArg, ecxArg uint32) (eax, ebx, ecx, edx uint32) | ||
|
||
func (cpu *CPU) initFeatures() { | ||
_, _, _, apmFeatures := cpuid(CPUID_APM, 0x00) | ||
cpu.invariant = bits.IsSet(&apmFeatures, APM_TSC_INVARIANT) | ||
|
||
_, kvmk, _, _ := cpuid(KVM_CPUID_SIGNATURE, 0x00) | ||
cpu.kvm = kvmk == KVM_SIGNATURE | ||
|
||
if !cpu.kvm { | ||
return | ||
} | ||
|
||
kvmFeatures, _, _, _ := cpuid(KVM_CPUID_FEATURES, 0x00) | ||
|
||
if bits.IsSet(&kvmFeatures, FEATURES_CLOCKSOURCE) { | ||
cpu.kvmclock = 0x12 | ||
} | ||
|
||
if bits.IsSet(&kvmFeatures, FEATURES_CLOCKSOURCE2) { | ||
cpu.kvmclock = 0x4b564d01 | ||
} | ||
} | ||
|
||
// Features represents the processor capabilities detected through the CPUID | ||
// instruction. | ||
type Features struct { | ||
// InvariantTSC indicates whether the Time Stamp Counter is guaranteed | ||
// to be at constant rate. | ||
InvariantTSC bool | ||
// KVM indicates whether a Kernel-base Virtual Machine is detected. | ||
KVM bool | ||
// KVMClockMSR returns the kvmclock Model Specific Register. | ||
KVMClockMSR uint32 | ||
} | ||
|
||
// Features returns the processor capabilities. | ||
func (cpu *CPU) Features() *Features { | ||
return &Features{ | ||
InvariantTSC: cpu.invariant, | ||
KVM: cpu.kvm, | ||
KVMClockMSR: cpu.kvmclock, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
// x86-64 processor support | ||
// https://github.com/usbarmory/tamago | ||
// | ||
// Copyright (c) WithSecure Corporation | ||
// https://foundry.withsecure.com | ||
// | ||
// Use of this source code is governed by the license | ||
// that can be found in the LICENSE file. | ||
|
||
#include "textflag.h" | ||
|
||
// func cpuid(eaxArg, ecxArg uint32) (eax, ebx, ecx, edx uint32) | ||
TEXT ·cpuid(SB),NOSPLIT,$0-24 | ||
MOVL eaxArg+0(FP), AX | ||
MOVL ecxArg+4(FP), CX | ||
CPUID | ||
MOVL AX, eax+8(FP) | ||
MOVL BX, ebx+12(FP) | ||
MOVL CX, ecx+16(FP) | ||
MOVL DX, edx+20(FP) | ||
RET |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
// x86-64 processor support | ||
// https://github.com/usbarmory/tamago | ||
// | ||
// Copyright (c) WithSecure Corporation | ||
// https://foundry.withsecure.com | ||
// | ||
// Use of this source code is governed by the license | ||
// that can be found in the LICENSE file. | ||
|
||
#include "textflag.h" | ||
|
||
#define MSR_EFER 0xc0000080 | ||
|
||
#define PML4T 0x1000 // Page Map Level 4 Table (512GB entries) | ||
#define PDPT 0x2000 // Page Directory Pointer Table (1GB entries) | ||
#define PDT 0x3000 // Page Directory Table (2MB entries) | ||
#define PT 0x4000 // Page Table (4kB entries) | ||
|
||
// Global Descriptor Table | ||
DATA gdt<>+0x00(SB)/8, $0x0000000000000000 // null descriptor | ||
DATA gdt<>+0x08(SB)/8, $0x00209a0000000000 // code descriptor (x/r) | ||
DATA gdt<>+0x10(SB)/8, $0x0000920000000000 // data descriptor (r/w) | ||
GLOBL gdt<>(SB),8,$24 | ||
|
||
DATA gdtptr<>+0x00(SB)/2, $0x1800 // GDT Limit | ||
DATA gdtptr<>+0x02(SB)/8, $gdt<>(SB) // GDT Base Address | ||
GLOBL gdtptr<>(SB),8,$10 | ||
|
||
TEXT cpuinit(SB),NOSPLIT|NOFRAME,$0 | ||
// Disable interrupts | ||
CLI | ||
|
||
// Set up paging | ||
// | ||
// AMD64 Architecture Programmer’s Manual | ||
// Volume 2 - 5.3 Long-Mode Page Translation | ||
// | ||
// Intel® 64 and IA-32 Architectures Software Developer’s Manual | ||
// Volume 3A - 4.5 IA-32E PAGING | ||
|
||
// Clear tables | ||
XORL AX, AX // value | ||
MOVL $PML4T, DI // to | ||
MOVL $0x5000, CX // n | ||
MOVL DI, CR3 | ||
REP; STOSB | ||
|
||
// PML4T[0] = PDPT | ||
MOVL $PML4T, DI | ||
MOVL $(PDPT | 1<<1 | 1<<0), (DI) // set R/W, P | ||
|
||
// Configure Long-Mode Page Translation as follows: | ||
// 0x00000000 - 0x3ffffffff (1GB) cacheable physical page | ||
// 0x40000000 - 0x7ffffffff (1GB) cacheable physical page | ||
// 0x80000000 - 0xbffffffff (1GB) cacheable physical page | ||
// 0xc0000000 - 0xfffffffff (1GB) uncacheable physical page | ||
MOVL $PDPT, DI | ||
MOVQ $(0 << 30 | 1<<7 | 1<<1 | 1<<0), (DI) // set PS, R/W, P | ||
ADDL $8, DI | ||
MOVQ $(1 << 30 | 1<<7 | 1<<1 | 1<<0), (DI) // set PS, R/W, P | ||
ADDL $8, DI | ||
MOVQ $(2 << 30 | 1<<7 | 1<<1 | 1<<0), (DI) // set PS, R/W, P | ||
ADDL $8, DI | ||
MOVQ $(3 << 30 | 1<<7 | 1<<4 | 1<<1 | 1<<0), (DI) // set PS, PCD, R/W, P | ||
|
||
// Enter long mode | ||
|
||
MOVL $(1<<7 | 1<<5), AX // set CR4.(PGE|PAE) | ||
MOVL AX, CR4 | ||
|
||
MOVL $MSR_EFER, CX | ||
RDMSR | ||
ORL $(1<<8), AX // set MSR_EFER.LME | ||
WRMSR | ||
|
||
MOVL CR0, AX | ||
ORL $(1<<31 | 1<<0), AX // set CR0.(PG|PE) | ||
MOVL AX, CR0 | ||
|
||
// Set Global Descriptor Table | ||
|
||
CALL ·getPC<>(SB) | ||
MOVL $gdtptr<>(SB), BX // 32-bit mode: only PC offset is copied | ||
ADDL $6, AX | ||
ADDL BX, AX | ||
LGDT (AX) | ||
|
||
CALL ·getPC<>(SB) | ||
MOVL $·start<>(SB), BX // 32-bit mode: only PC offset is copied | ||
ADDL $6, AX | ||
ADDL BX, AX | ||
|
||
PUSHQ $0x08 | ||
PUSHQ AX | ||
RETFQ | ||
|
||
TEXT ·start<>(SB),NOSPLIT|NOFRAME,$0 | ||
MOVL CR0, AX | ||
MOVL CR4, BX | ||
|
||
// Enable SSE | ||
ANDL $~(1<<2), AX // clear CR0.EM | ||
ORL $(1<<1), AX // set CR0.MP | ||
ORL $(1<<10 | 1<<9), BX // set CR4.(OSXMMEXCPT|OSFXSR) | ||
|
||
MOVL AX, CR0 | ||
MOVL BX, CR4 | ||
|
||
JMP _rt0_tamago_start(SB) | ||
|
||
TEXT ·getPC<>(SB),NOSPLIT|NOFRAME,$0 | ||
POPQ AX | ||
CALL AX |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
// x86-64 processor support | ||
// https://github.com/usbarmory/tamago | ||
// | ||
// Copyright (c) WithSecure Corporation | ||
// https://foundry.withsecure.com | ||
// | ||
// Use of this source code is governed by the license | ||
// that can be found in the LICENSE file. | ||
|
||
//go:build !linkramstart | ||
|
||
package amd64 | ||
|
||
import ( | ||
_ "unsafe" | ||
) | ||
|
||
//go:linkname ramStart runtime.ramStart | ||
var ramStart uint64 = 0x10000000 |
Oops, something went wrong.