github.com/transparency-dev/armored-witness-os@v0.1.3-0.20240514084412-27eef7325168/trusted_os/load.go (about) 1 // Copyright 2022 The Armored Witness OS authors. All Rights Reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package main 16 17 import ( 18 "fmt" 19 "log" 20 21 "github.com/usbarmory/tamago/arm" 22 "github.com/usbarmory/tamago/bits" 23 "github.com/usbarmory/tamago/soc/nxp/imx6ul" 24 25 "github.com/usbarmory/armory-boot/exec" 26 27 "github.com/usbarmory/GoTEE/monitor" 28 ) 29 30 const ( 31 // Watchdog interval (in ms) to force context switching (User -> System mode) 32 // to prevent Trusted Applet starvation of Trusted OS resources. 33 watchdogTimeout = 60 * 1000 34 35 // watchdogWarningInterval (in ms) controls how long before the watchdog triggers 36 // the service request interrupt will be raised. 37 watchdogWarningInterval = 5 * 1000 38 ) 39 40 // loadApplet loads a TamaGo unikernel as trusted applet. 41 func loadApplet(elf []byte, ctl *controlInterface) (ta *monitor.ExecCtx, err error) { 42 image := &exec.ELFImage{ 43 Region: appletRegion, 44 ELF: elf, 45 } 46 47 // BEE requires caching to be activated before image loading 48 imx6ul.ARM.ConfigureMMU(uint32(image.Region.Start()), uint32(image.Region.End()), 0, arm.MemoryRegion) 49 50 if err = image.Load(); err != nil { 51 return 52 } 53 54 if ta, err = monitor.Load(image.Entry(), image.Region, true); err != nil { 55 return nil, fmt.Errorf("SM could not load applet: %v", err) 56 } 57 58 log.Printf("SM applet loaded addr:%#x entry:%#x size:%d", ta.Memory.Start(), ta.R15, len(elf)) 59 60 // register RPC receiver 61 ta.Server.Register(ctl.RPC) 62 ctl.RPC.Ctx = ta 63 64 // set stack pointer to end of available memory 65 ta.R13 = uint32(ta.Memory.End()) 66 67 // override default handler 68 ta.Handler = handler 69 ta.Debug = true 70 71 // enable FIQs 72 bits.Clear(&ta.SPSR, CPSR_FIQ) 73 74 return ta, run(ta) 75 } 76 77 func run(ctx *monitor.ExecCtx) (err error) { 78 mode := arm.ModeName(int(ctx.SPSR) & 0x1f) 79 ns := ctx.NonSecure() 80 81 log.Printf("SM applet started mode:%s sp:%#.8x pc:%#.8x ns:%v", mode, ctx.R13, ctx.R15, ns) 82 83 irqHandler[imx6ul.WDOG2.IRQ] = func() { 84 imx6ul.WDOG2.Service(watchdogTimeout) 85 } 86 87 // activate watchdog to prevent resource starvation 88 imx6ul.GIC.EnableInterrupt(imx6ul.WDOG2.IRQ, true) 89 imx6ul.WDOG2.EnableInterrupt(watchdogWarningInterval) 90 imx6ul.WDOG2.EnableTimeout(watchdogTimeout) 91 92 // route IRQs as FIQs to serve them through applet handler 93 imx6ul.GIC.FIQEn(true) 94 95 err = ctx.Run() 96 97 // restore routing to IRQ handler 98 imx6ul.GIC.FIQEn(false) 99 100 // Re-enable interrupts as the monitor exception handler disables them 101 // when switching back to System Mode. 102 imx6ul.ARM.EnableInterrupts(false) 103 104 log.Printf("SM applet stopped mode:%s sp:%#.8x lr:%#.8x pc:%#.8x ns:%v err:%v", mode, ctx.R13, ctx.R14, ctx.R15, ns, err) 105 106 if err != nil && debug { 107 err = inspect(taELF, ctx) 108 } 109 110 return 111 }