github.com/f-secure-foundry/tamago@v0.0.0-20220307101044-d73fcdd7f11b/soc/imx6/imx6.go (about) 1 // NXP i.MX6 UL/ULL/ULZ support 2 // https://github.com/f-secure-foundry/tamago 3 // 4 // Copyright (c) F-Secure Corporation 5 // https://foundry.f-secure.com 6 // 7 // Use of this source code is governed by the license 8 // that can be found in the LICENSE file. 9 10 // Package imx6 provides support to Go bare metal unikernels written using the 11 // TamaGo framework. 12 // 13 // The package implements initialization and drivers for specific NXP i.MX6 14 // System-on-Chip (SoC) peripherals, adopting, where indicated, the following 15 // reference specifications: 16 // * IMX6ULLRM - i.MX 6ULL Applications Processor Reference Manual - Rev 1 2017/11 17 // * IMX6FG - i.MX 6 Series Firmware Guide - Rev 0 2012/11 18 // * IMX6ULLCEC - i.MX6ULL Data Sheet - Rev 1.2 2017/11 19 // * MCIMX28RM - i.MX28 Applications Processor Reference Manual - Rev 2 2013/08 20 // * SD-PL-7.10 - SD Specifications Part 1 Physical Layer Simplified Specification - 7.10 2020/03/25 21 // * JESD84-B51 - Embedded Multi-Media Card (e•MMC) Electrical Standard (5.1) - JESD84-B51 2015/02 22 // * USB2.0 - USB Specification Revision 2.0 - 2.0 2000/04/27 23 // 24 // This package is only meant to be used with `GOOS=tamago GOARCH=arm` as 25 // supported by the TamaGo framework for bare metal Go on ARM SoCs, see 26 // https://github.com/f-secure-foundry/tamago. 27 package imx6 28 29 import ( 30 "encoding/binary" 31 _ "unsafe" 32 33 "github.com/f-secure-foundry/tamago/arm" 34 "github.com/f-secure-foundry/tamago/internal/reg" 35 ) 36 37 // Identification registers 38 const ( 39 OCOTP_CFG0 = 0x021bc410 40 OCOTP_CFG1 = 0x021bc420 41 USB_ANALOG_DIGPROG = 0x020c8260 42 ) 43 44 const ( 45 // GIC base address (p176, Table 2-1, IMX6ULLRM) 46 GIC_BASE = 0x00a00000 47 48 // Timer registers (p178, Table 2-3, IMX6ULLRM) 49 SYS_CNT_BASE = 0x021dc000 50 ) 51 52 // i.MX processor families 53 const ( 54 IMX6UL = 0x64 55 IMX6ULL = 0x65 56 ) 57 58 // Processor family 59 var Family uint32 60 61 // Flag for native or emulated processor 62 var Native bool 63 64 // ARM processor instance 65 var ARM = &arm.CPU{} 66 67 //go:linkname nanotime1 runtime.nanotime1 68 func nanotime1() int64 { 69 return int64(ARM.TimerFn()*ARM.TimerMultiplier + ARM.TimerOffset) 70 } 71 72 // Init takes care of the lower level SoC initialization triggered early in 73 // runtime setup. 74 func Init() { 75 if ARM.Mode() != arm.SYS_MODE { 76 // initialization required only when in PL1 77 return 78 } 79 80 ARM.Init() 81 ARM.EnableVFP() 82 83 // required when booting in SDP mode 84 ARM.EnableSMP() 85 86 // MMU initialization is required to take advantage of data cache 87 ARM.InitMMU() 88 ARM.EnableCache() 89 90 _, fam, revMajor, revMinor := SiliconVersion() 91 Family = fam 92 93 if revMajor != 0 || revMinor != 0 { 94 Native = true 95 } 96 97 switch Family { 98 case IMX6UL, IMX6ULL: 99 if !Native { 100 // use QEMU fixed CNTFRQ value (62.5MHz) 101 ARM.InitGenericTimers(SYS_CNT_BASE, 62500000) 102 } else { 103 // U-Boot value for i.MX6 family (8.0MHz) 104 ARM.InitGenericTimers(SYS_CNT_BASE, 8000000) 105 } 106 default: 107 ARM.InitGlobalTimers() 108 } 109 } 110 111 // SiliconVersion returns the SoC silicon version information 112 // (p3945, 57.4.11 Chip Silicon Version (USB_ANALOG_DIGPROG), IMX6ULLRM). 113 func SiliconVersion() (sv, family, revMajor, revMinor uint32) { 114 sv = reg.Read(USB_ANALOG_DIGPROG) 115 116 family = (sv >> 16) & 0xff 117 revMajor = (sv >> 8) & 0xff 118 revMinor = sv & 0xff 119 120 return 121 } 122 123 // UniqueID returns the NXP SoC Device Unique 64-bit ID. 124 func UniqueID() (uid [8]byte) { 125 cfg0 := reg.Read(OCOTP_CFG0) 126 cfg1 := reg.Read(OCOTP_CFG1) 127 128 binary.LittleEndian.PutUint32(uid[0:4], cfg0) 129 binary.LittleEndian.PutUint32(uid[4:8], cfg1) 130 131 return 132 } 133 134 // Model returns the SoC model name. 135 func Model() (model string) { 136 switch Family { 137 case IMX6UL: 138 model = "i.MX6UL" 139 case IMX6ULL: 140 model = "i.MX6ULL" 141 default: 142 model = "unknown" 143 } 144 145 return 146 }