Skip to content

Commit d0dd3f1

Browse files
authored
Add wake handler support for go1.23 and go1.24. (#317)
1 parent 926862a commit d0dd3f1

File tree

2 files changed

+166
-28
lines changed

2 files changed

+166
-28
lines changed

trusted_os/handler.go

+18-10
Original file line numberDiff line numberDiff line change
@@ -36,25 +36,33 @@ var (
3636
var irqHandler = make(map[int]func())
3737

3838
// defined in handler.s
39-
func wakeHandler(g uint32, p uint32)
4039
func wakeHandlerPreGo123(g uint32, p uint32)
40+
func wakeHandlerGo123(g uint32, p uint32)
41+
func wakeHandlerGo124(g uint32, p uint32)
4142

42-
// handlerCutover is the semver representation of the cut over between wakeHandler implementations above.
43+
// handler123Cutover is the semver representation of the cut over between wakeHandler implementations above.
4344
// Anything less that this should use the legacy PreGo123 version.
44-
const handlerCutover = "1.23.0"
45+
const handler123Cutover = "1.23.0"
46+
const handler124Cutover = "1.24.0"
4547

4648
var (
47-
// wHandler is the wakeHandler implementation to be used, 1.23+ by default.
48-
wHandler = wakeHandler
49-
wHandlerCutover = *semver.New(handlerCutover)
49+
// wHandler is the wakeHandler implementation to be used, 1.24+ by default.
50+
wHandler func(g uint32, p uint32)
51+
wHandler123Cutover = *semver.New(handler123Cutover)
52+
wHandler124Cutover = *semver.New(handler124Cutover)
5053
)
5154

5255
func configureWakeHandler(rtVersion semver.Version) {
53-
if rtVersion.LessThan(wHandlerCutover) {
56+
switch {
57+
case rtVersion.LessThan(wHandler123Cutover):
58+
log.Printf("SM Using legacy pre-%s wakeHandler", wHandler123Cutover.String())
5459
wHandler = wakeHandlerPreGo123
55-
log.Printf("SM Using legacy pre-%s wakeHandler", wHandlerCutover.String())
56-
} else {
57-
wHandler = wakeHandler
60+
case rtVersion.LessThan(wHandler124Cutover):
61+
log.Printf("SM Using legacy %s wakeHandler", wHandler123Cutover.String())
62+
wHandler = wakeHandlerGo123
63+
default:
64+
log.Printf("SM Using OS runtime %s wakeHandler", wHandler124Cutover.String())
65+
wHandler = wakeHandlerGo124
5866
}
5967
}
6068

trusted_os/handler.s

+148-18
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,8 @@
1515
#include "go_asm.h"
1616
#include "textflag.h"
1717

18-
// These defines are only used to aid applet runtime backward compatiblity,
19-
// within wakeHandlerPreGo123, and represent timer structs offsets fo Go <
20-
// 1.23.
21-
#define g_timer 208
22-
#define timer_nextwhen 36
23-
#define timer_status 44
24-
#define const_timerModifiedEarlier 7
25-
#define p_timerModifiedEarliest 2384
26-
27-
// Supports tamago >= 1.23 applet runtime.
28-
TEXT ·wakeHandler(SB),$0-8
18+
// Supports tamago >= 1.24 applet runtime.
19+
TEXT ·wakeHandlerGo124(SB),$0-8
2920
MOVW handlerG+0(FP), R0
3021
MOVW handlerP+4(FP), R1
3122

@@ -35,10 +26,149 @@ TEXT ·wakeHandler(SB),$0-8
3526
CMP $0, R1
3627
B.EQ done
3728

29+
// Call the current runtime's version of WakeG
3830
B runtime·WakeG(SB)
3931
done:
4032
RET
4133

34+
// These values are only used to aid applet runtime backward compatibility
35+
// within wakeHandlerGo123, and represent timer struct offsets in the Go runtime
36+
// for Go version 1.23.x
37+
//
38+
// To determine these values, the following rough process can be used:
39+
// 1. clone https://github.com/usbarmory/tamago-go@tamago-1.23.1
40+
// 2. cd tamago-go/src
41+
// 3. run ./all.bash to build the binaries
42+
// 4. within the cloned repo, create a file src/runtime/test.go with the following contents:
43+
// package runtime
44+
//
45+
// import "unsafe"
46+
//
47+
// type Info struct {
48+
// GTimer uintptr
49+
// }
50+
//
51+
// func GetInfo() Info {
52+
// gp, _ := GetG()
53+
// myG := (*g)(unsafe.Pointer(uintptr(gp)))
54+
// r := Info{}
55+
// r.GTimer = unsafe.Offsetof(myG.timer)
56+
// return r
57+
// }
58+
// 5. within the cloned repo, create a file test.go at the root with the following contents:
59+
// package main
60+
//
61+
// func main() {
62+
// i := runtime.GetInfo()
63+
// fmt.Printf("%#v", i)
64+
// }
65+
// 6. From the root of the repo, run: GOOS=tamago GOARCH=arm ./bin/go run --work ./test.go
66+
// This will fail with some "undefined: ..." errors, but importantly will print out a line line this:
67+
// WORK=/tmp/go-build3974774761
68+
// 7. Find #define values of interest in /tmp/go-build3974774761/b002/go_asm.h
69+
70+
#define go123_g_timer 212
71+
#define go123_timer_when 12
72+
#define go123_timerWhen__size 12
73+
#define go123_timerWhen_timer 0
74+
#define go123_timerWhen_when 4
75+
#define go123_timer_astate 4
76+
#define go123_timer_ts 44
77+
#define go123_timers_minWhenModified 40
78+
#define go123_timers_heap 4
79+
#define go123_const_timerModified 2
80+
81+
// Supports tamago version >= 1.23.0 && < 1.24.
82+
TEXT ·wakeHandlerGo123(SB),$0-8
83+
MOVW handlerG+0(FP), R0
84+
MOVW handlerP+4(FP), R1
85+
86+
CMP $0, R0
87+
B.EQ done
88+
89+
CMP $0, R1
90+
B.EQ done
91+
92+
// Code below taken from tamago-go@1.23.1/src/runtime/sys_tamago_arm.s
93+
MOVW (go123_g_timer)(R0), R3
94+
CMP $0, R3
95+
B.EQ done
96+
97+
// g->timer.when = 1
98+
MOVW $1, R1
99+
MOVW R1, (go123_timer_when+0)(R3)
100+
MOVW $0, R1
101+
MOVW R1, (go123_timer_when+4)(R3)
102+
103+
// g->timer.astate &= timerModified
104+
// g->timer.state &= timerModified
105+
MOVW (go123_timer_astate)(R3), R2
106+
ORR $go123_const_timerModified<<8|go123_const_timerModified, R2, R2
107+
MOVW R2, (go123_timer_astate)(R3)
108+
109+
MOVW (go123_timer_ts)(R3), R0
110+
CMP $0, R0
111+
B.EQ done
112+
113+
// g->timer.ts.minWhenModified = 1
114+
MOVW $1, R1
115+
MOVW R1, (go123_timers_minWhenModified+0)(R0)
116+
MOVW $0, R1
117+
MOVW R1, (go123_timers_minWhenModified+4)(R0)
118+
119+
// len(g->timer.ts.heap)
120+
MOVW (go123_timers_heap+4)(R0), R2
121+
CMP $0, R2
122+
B.EQ done
123+
124+
// offset to last element
125+
SUB $1, R2, R2
126+
MOVW $(go123_timerWhen__size), R1
127+
MUL R1, R2, R2
128+
129+
MOVW (go123_timers_heap)(R0), R0
130+
CMP $0, R0
131+
B.EQ done
132+
133+
// g->timer.ts.heap[len-1]
134+
ADD R2, R0, R0
135+
B check
136+
137+
prev:
138+
SUB $(go123_timerWhen__size), R0
139+
CMP $0, R0
140+
B.EQ done
141+
142+
check:
143+
// find longest timer as *timers.adjust() might be pending
144+
MOVW (go123_timerWhen_when+0)(R0), R1
145+
CMP $0xffffffff, R1 // LS word of math.MaxInt64
146+
B.NE prev
147+
148+
MOVW (go123_timerWhen_when+4)(R0), R1
149+
CMP $0x7fffffff, R1 // MS word of math.MaxInt64
150+
B.NE prev
151+
152+
// g->timer.ts.heap[off] = 1
153+
MOVW $1, R1
154+
MOVW R1, (go123_timerWhen_when+0)(R0)
155+
MOVW $0, R1
156+
MOVW R1, (go123_timerWhen_when+4)(R0)
157+
158+
done:
159+
RET
160+
161+
162+
// These defines are only used to aid applet runtime backward compatiblity,
163+
// within wakeHandlerPreGo123, and represent timer structs offsets fo Go <
164+
// 1.23.
165+
#define go122_g_timer 208
166+
#define go122_timer_nextwhen 36
167+
#define go122_timer_status 44
168+
#define go122_const_timerModifiedEarlier 7
169+
#define go122_p_timerModifiedEarliest 2384
170+
171+
42172
// Supports tamago < 1.23 applet runtime.
43173
TEXT ·wakeHandlerPreGo123(SB),$0-8
44174
MOVW handlerG+0(FP), R0
@@ -50,24 +180,24 @@ TEXT ·wakeHandlerPreGo123(SB),$0-8
50180
CMP $0, R1
51181
B.EQ done
52182

53-
MOVW (g_timer)(R0), R0
183+
MOVW (go122_g_timer)(R0), R0
54184
CMP $0, R0
55185
B.EQ done
56186

57187
// g->timer.nextwhen = 1
58188
MOVW $1, R2
59-
MOVW R2, (timer_nextwhen+0)(R0)
189+
MOVW R2, (go122_timer_nextwhen+0)(R0)
60190
MOVW $0, R2
61-
MOVW R2, (timer_nextwhen+4)(R0)
191+
MOVW R2, (go122_timer_nextwhen+4)(R0)
62192

63193
// g->timer.status = timerModifiedEarlier
64-
MOVW $const_timerModifiedEarlier, R2
65-
MOVW R2, (timer_status+0)(R0)
194+
MOVW $go122_const_timerModifiedEarlier, R2
195+
MOVW R2, (go122_timer_status+0)(R0)
66196

67197
// g->m->p.timerModifiedEarliest = 1
68198
MOVW $1, R2
69-
MOVW R2, (p_timerModifiedEarliest)(R1)
199+
MOVW R2, (go122_p_timerModifiedEarliest)(R1)
70200
MOVW $0, R2
71-
MOVW R2, (p_timerModifiedEarliest+4)(R1)
201+
MOVW R2, (go122_p_timerModifiedEarliest+4)(R1)
72202
done:
73203
RET

0 commit comments

Comments
 (0)