-
Notifications
You must be signed in to change notification settings - Fork 2
/
main.go
160 lines (135 loc) · 3.58 KB
/
main.go
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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
//-----------------------------------------------------------------------------
/*
RISC-V RV32/RV64 Emulator
*/
//-----------------------------------------------------------------------------
package main
import (
"debug/elf"
"flag"
"fmt"
"os"
cli "github.com/deadsy/go-cli"
"github.com/deadsy/riscv/csr"
"github.com/deadsy/riscv/host"
"github.com/deadsy/riscv/mem"
"github.com/deadsy/riscv/rv"
"github.com/deadsy/riscv/util"
)
//-----------------------------------------------------------------------------
const historyPath = ".rvemu_history"
const heapSize = 1 << 20
//-----------------------------------------------------------------------------
// emuApp is state associated with the emulator application.
type emuApp struct {
mem *mem.Memory
cpu *rv.RV
elfClass elf.Class
host *host.Host
prompt string
}
// newEmu32 returns a 32-bit emulator.
func newEmu32() (*emuApp, error) {
// 32-bit ISA
isa := rv.NewISA(csr.IsaExtS | csr.IsaExtU)
err := isa.Add(rv.ISArv32gc)
if err != nil {
return nil, err
}
// 32-bit CSR and memory
csr := csr.NewState(32, isa.GetExtensions())
m := mem.NewMem32(csr, 0)
return &emuApp{
mem: m,
cpu: rv.NewRV32(isa, m, csr),
elfClass: elf.ELFCLASS32,
prompt: "rv32> ",
}, nil
}
// newEmu64 returns a 64-bit emulator.
func newEmu64() (*emuApp, error) {
// 64-bit ISA
isa := rv.NewISA(csr.IsaExtS | csr.IsaExtU)
err := isa.Add(rv.ISArv64gc)
if err != nil {
return nil, err
}
// 64-bit CSR and memory
csr := csr.NewState(64, isa.GetExtensions())
m := mem.NewMem64(csr, 0)
return &emuApp{
mem: m,
cpu: rv.NewRV64(isa, m, csr),
elfClass: elf.ELFCLASS64,
prompt: "rv64> ",
}, nil
}
//-----------------------------------------------------------------------------
// Put outputs a string to the user application.
func (u *emuApp) Put(s string) {
os.Stdout.WriteString(s)
}
//-----------------------------------------------------------------------------
func main() {
// command line flags
fname := flag.String("f", "out.bin", "file to load (ELF)")
flag.Parse()
elfClass, err := util.GetELFClass(*fname)
if err != nil {
fmt.Fprintf(os.Stderr, "%s\n", err)
os.Exit(1)
}
// create the application
var app *emuApp
switch elfClass {
case elf.ELFCLASS32:
app, err = newEmu32()
case elf.ELFCLASS64:
app, err = newEmu64()
default:
fmt.Fprintf(os.Stderr, "ELF class %d is not supported\n", elfClass)
os.Exit(1)
}
if err != nil {
fmt.Fprintf(os.Stderr, "%s\n", err)
os.Exit(1)
}
// load the file
status, err := app.mem.LoadELF(*fname, app.elfClass)
if err != nil {
fmt.Fprintf(os.Stderr, "%s\n", err)
os.Exit(1)
}
fmt.Fprintf(os.Stderr, "%s\n", status)
// add a heap
app.mem.Add(mem.NewSection("heap", 0x80000000, heapSize, mem.AttrRW))
// Callback on the "tohost" write (compliance tests).
sym := app.mem.SymbolByName("tohost")
if sym != nil {
app.host = host.NewHost(app.mem, sym.Addr)
if sym.Size == 8 {
// trap on a write to the most significant word
fn := func(bp *mem.BreakPoint) bool { return app.host.To64(bp) }
app.mem.AddBreakPoint(sym.Name, sym.Addr+4, mem.AttrW, fn)
} else {
// 32-bit variable
fn := func(bp *mem.BreakPoint) bool { return app.host.To32(bp) }
app.mem.AddBreakPoint(sym.Name, sym.Addr, mem.AttrW, fn)
}
}
// create the cli
c := cli.NewCLI(app)
c.HistoryLoad(historyPath)
c.SetRoot(menuRoot)
c.SetPrompt(app.prompt)
// reset the cpu
app.cpu.Reset()
// run the cli
for c.Running() {
c.Run()
}
// exit
c.HistorySave(historyPath)
os.Exit(0)
}
//-----------------------------------------------------------------------------