-
Notifications
You must be signed in to change notification settings - Fork 1
/
main.go
135 lines (109 loc) · 2.6 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
package main
import (
"flag"
"os"
"strconv"
"strings"
"time"
log "github.com/sirupsen/logrus"
"github.com/sokoide/rv32i-go/pkg/rv32i"
)
func chkerr(err error) {
if err != nil {
panic(err)
}
}
type options struct {
logLevel string
demo bool
sourcePath string
end string
}
var opts options = options{
demo: false,
}
func parseArgs() {
flag.BoolVar(&opts.demo, "demo", false, "Run demo")
flag.StringVar(&opts.logLevel, "logLevel", opts.logLevel, "Log level (trace, debug, info, warn, error, fatal, panic)")
flag.StringVar(&opts.sourcePath, "sourcePath", opts.sourcePath, "Source path")
flag.StringVar(&opts.end, "end", opts.end, "End address")
flag.Parse()
}
func runDemo() {
var err error
emu := rv32i.NewEmulator()
emu.Reset()
// test binary in sample-binary-001.txt
// 80000000 <boot>:
// 80000000: 93 00 00 00 li ra, 0
// # x1 == ra == 0
// 80000004: 13 04 00 00 li s0, 0
// # x8 == s0/fp == 0
// 80000008: 37 45 00 00 lui a0, 4
// # x10 == a0 == 4<<12 == 16384
err = emu.Load("./data/sample-binary-001.txt")
chkerr(err)
emu.Step()
emu.Step()
emu.Step()
emu.Dump()
log.Info("* Converting txt to bin")
l := rv32i.NewLoader()
l.TextToBinary("./data/sample-binary-003.txt", "./data/sample-binary-003.bin")
log.Info("* Running the bin")
emu.Reset()
err = emu.Load("./data/sample-binary-003.bin")
chkerr(err)
log.Info("*** code ***")
for i := 0; i < 0x108; i += 4 {
log.Infof("0x%08x: 0x%02x%02x%02x%02x,", i, emu.Memory[i+3], emu.Memory[i+2], emu.Memory[i+1], emu.Memory[i])
}
log.Info("*** code end ***")
emu.StepUntil(0x18)
emu.Dump()
emu.StepUntil(0x1c)
}
func run(sourcePath string, end string) {
var err error
emu := rv32i.NewEmulator()
emu.Reset()
err = emu.Load(sourcePath)
chkerr(err)
if len(end) > 0 {
var uintEnd uint32
var uintEnd64 uint64
if strings.HasPrefix(end, "0x") {
uintEnd64, err = strconv.ParseUint(end[2:], 16, 32)
uintEnd = uint32(uintEnd64)
} else {
uintEnd64, err = strconv.ParseUint(end, 10, 32)
uintEnd = uint32(uintEnd64)
}
chkerr(err)
startTime := time.Now()
err = emu.StepUntil(uintEnd)
endTime := time.Now()
log.Infof("elapsed time: %v\n", endTime.Sub(startTime))
} else {
panic("please specify the end address")
}
}
func main() {
var err error
parseArgs()
log.SetOutput(os.Stdout)
ll := log.InfoLevel
if len(opts.logLevel) > 0 {
ll, err = log.ParseLevel(opts.logLevel)
chkerr(err)
}
log.SetLevel(ll)
log.Info("* Started")
log.Info("* Running a small program")
if opts.demo {
runDemo()
} else {
run(opts.sourcePath, opts.end)
}
log.Info("* Completed")
}