github.com/tinygo-org/tinygo@v0.31.3-0.20240404173401-90b0bf646c27/src/internal/task/task_stack_avr.go (about) 1 //go:build scheduler.tasks && avr 2 3 package task 4 5 import "unsafe" 6 7 //go:extern tinygo_systemStack 8 var systemStack uintptr 9 10 // calleeSavedRegs is the list of registers that must be saved and restored when 11 // switching between tasks. Also see task_stack_avr.S that relies on the exact 12 // layout of this struct. 13 // 14 // https://gcc.gnu.org/wiki/avr-gcc#Call-Saved_Registers 15 type calleeSavedRegs struct { 16 r2r3 uintptr 17 r4r5 uintptr 18 r6r7 uintptr 19 r8r9 uintptr 20 r10r11 uintptr 21 r12r13 uintptr 22 r14r15 uintptr 23 r16r17 uintptr 24 r28r29 uintptr // Y register 25 26 pc uintptr 27 } 28 29 // archInit runs architecture-specific setup for the goroutine startup. 30 // Note: adding //go:noinline to work around an AVR backend bug. 31 // 32 //go:noinline 33 func (s *state) archInit(r *calleeSavedRegs, fn uintptr, args unsafe.Pointer) { 34 // Store the initial sp for the startTask function (implemented in assembly). 35 s.sp = uintptr(unsafe.Pointer(r)) - 1 36 37 // Initialize the registers. 38 // These will be popped off of the stack on the first resume of the goroutine. 39 40 // Start the function at tinygo_startTask. 41 startTask := uintptr(unsafe.Pointer(&startTask)) 42 r.pc = startTask/2>>8 | startTask/2<<8 43 44 // Pass the function to call in r2:r3. 45 // This function is a compiler-generated wrapper which loads arguments out 46 // of a struct pointer. See createGoroutineStartWrapper (defined in 47 // compiler/goroutine.go) for more information. 48 r.r2r3 = fn 49 50 // Pass the pointer to the arguments struct in r4:45. 51 r.r4r5 = uintptr(args) 52 } 53 54 func (s *state) resume() { 55 swapTask(s.sp, &systemStack) 56 } 57 58 func (s *state) pause() { 59 newStack := systemStack 60 systemStack = 0 61 swapTask(newStack, &s.sp) 62 } 63 64 // SystemStack returns the system stack pointer when called from a task stack. 65 // When called from the system stack, it returns 0. 66 func SystemStack() uintptr { 67 return systemStack 68 }