-
Notifications
You must be signed in to change notification settings - Fork 8
/
os_tamago_arm.go
204 lines (168 loc) · 4.66 KB
/
os_tamago_arm.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
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build tamago,arm
package runtime
import (
"unsafe"
)
const _PAGESIZE uintptr = 0x1000
// the following variables must be provided externally
var ramStart uint32
var ramStackOffset uint32
// the following variables must be provided externally
// (but are already stubbed somewhere else in the runtime)
// var ramSize uint32
// the following functions must be provided externally
func hwinit()
func printk(byte)
func getRandomData([]byte)
func initRNG()
// the following functions must be provided externally
// (but are already stubbed somewhere else in the runtime)
//func nanotime1() int64
// GetRandomData generates len(r) random bytes from the random source provided
// externally by the linked application.
func GetRandomData(r []byte) {
getRandomData(r)
}
// CallOnG0 calls a function (func(off int)) on g0 stack.
//
// The function arguments must be passed through the following registers
// (rather than on the frame pointer):
//
// * R0: fn argument (vector table offset)
// * R1: fn pointer
// * R2: size of stack area reserved for caller registers
// * R3: caller program counter
func CallOnG0()
// MemRegion returns the start and end addresses of the physical RAM assigned
// to the Go runtime.
func MemRegion() (start uint32, end uint32) {
return ramStart, ramStart + ramSize
}
// stubs for unused/unimplemented functionality
type mOS struct{}
type sigset struct{}
type gsignalStack struct{}
func goenvs() {}
func sigsave(p *sigset) {}
func msigrestore(sigmask sigset) {}
func clearSignalHandlers() {}
func sigblock(exiting bool) {}
func minit() {}
func unminit() {}
func mdestroy(mp *m) {}
func setProcessCPUProfiler(hz int32) {}
func setThreadCPUProfiler(hz int32) {}
func initsig(preinit bool) {}
func osyield() {}
// May run with m.p==nil, so write barriers are not allowed.
//go:nowritebarrier
func newosproc(mp *m) {
panic("newosproc: not implemented")
}
// Called to do synchronous initialization of Go code built with
// -buildmode=c-archive or -buildmode=c-shared.
// None of the Go runtime is initialized.
//go:nosplit
//go:nowritebarrierrec
func libpreinit() {
initsig(true)
}
// Called to initialize a new m (including the bootstrap m).
// Called on the parent thread (main thread in case of bootstrap), can allocate memory.
func mpreinit(mp *m) {
mp.gsignal = malg(32 * 1024)
mp.gsignal.m = mp
}
func osinit() {
ncpu = 1
physPageSize = 4096
initBloc()
}
func signame(sig uint32) string {
return ""
}
func checkgoarm() {
if goarm < 5 || goarm > 7 {
print("runtime: tamago requires ARMv5 through ARMv7. Recompile using GOARM=5, GOARM=6 or GOARM=7.\n")
exit(1)
}
}
//go:nosplit
func cputicks() int64 {
// Currently cputicks() is used in blocking profiler and to seed runtime·fastrand().
// runtime·nanotime() is a poor approximation of CPU ticks that is enough for the profiler.
return nanotime()
}
//go:nosplit
func roundup(val, upto uint32) uint32 {
return ((val + (upto - 1)) & ^(upto - 1))
}
//go:linkname os_sigpipe os.sigpipe
func os_sigpipe() {
throw("too many writes on closed pipe")
}
//go:nosplit
func crash() {
*(*int32)(nil) = 0
}
//go:linkname syscall
func syscall(number, a1, a2, a3 uintptr) (r1, r2, err uintptr) {
switch number {
// SYS_WRITE
case 1:
r1 := write(a1, unsafe.Pointer(a2), int32(a3))
return uintptr(r1), 0, 0
default:
throw("unexpected syscall")
}
return
}
//go:nosplit
func write1(fd uintptr, buf unsafe.Pointer, count int32) int32 {
if fd != 1 && fd != 2 {
throw("unexpected fd, only stdout/stderr are supported")
}
c := uintptr(count)
for i := uintptr(0); i < c; i++ {
p := (*byte)(unsafe.Pointer(uintptr(buf) + i))
printk(*p)
}
return int32(c)
}
//go:linkname syscall_now syscall.now
func syscall_now() (sec int64, nsec int32) {
sec, nsec, _ = time_now()
return
}
//go:nosplit
func walltime1() (sec int64, nsec int32) {
// TODO: probably better implement this in sys_tamago_arm.s for better
// performance
nano := nanotime()
sec = nano / 1000000000
nsec = int32(nano % 1000000000)
return
}
//go:nosplit
func usleep(us uint32) {
wake := nanotime() + int64(us)*1000
for nanotime() < wake {
}
}
func exit(code int32) {
print("exit with code ", code, " halting\n")
for {
// hang forever
}
}
func exitThread(wait *uint32) {
// We should never reach exitThread
throw("exitThread: not implemented")
}
const preemptMSupported = false
func preemptM(mp *m) {
// No threads, so nothing to do.
}