github.com/f-secure-foundry/tamago@v0.0.0-20220307101044-d73fcdd7f11b/soc/bcm2835/videocore.go (about) 1 // BCM2835 SoC VideoCore support 2 // https://github.com/f-secure-foundry/tamago 3 // 4 // Copyright (c) the bcm2835 package authors 5 // 6 // Use of this source code is governed by the license 7 // that can be found in the LICENSE file. 8 9 package bcm2835 10 11 import "encoding/binary" 12 13 const ( 14 GPU_MEMORY_FLAG_DISCARDABLE = 1 << 0 15 GPU_MEMORY_FLAG_NORMAL = 0 << 2 16 GPU_MEMORY_FLAG_DIRECT = 1 << 2 17 GPU_MEMORY_FLAG_COHERENT = 2 << 2 18 GPU_MEMORY_FLAG_L1_NONALLOCATING = 3 << 2 19 GPU_MEMORY_FLAG_ZERO = 1 << 4 20 GPU_MEMORY_FLAG_NO_INIT = 1 << 5 21 GPU_MEMORY_FLAG_HINT_PERMALOCK = 1 << 6 22 ) 23 24 // FirmwareRevision gets the firmware rev of the VideoCore GPU 25 func FirmwareRevision() uint32 { 26 buf := exchangeSingleTagMessage(VC_BOARD_GET_REV, make([]byte, VC_BOARD_GET_REV_LEN)) 27 28 if len(buf) < 4 { 29 return 0 30 } 31 32 return binary.LittleEndian.Uint32(buf) 33 } 34 35 // BoardModel gets the board model 36 func BoardModel() uint32 { 37 buf := exchangeSingleTagMessage(VC_BOARD_GET_MODEL, make([]byte, VC_BOARD_GET_MODEL_LEN)) 38 39 if len(buf) < 4 { 40 return 0 41 } 42 43 return binary.LittleEndian.Uint32(buf) 44 } 45 46 // MACAddress gets the board's MAC address 47 func MACAddress() []byte { 48 return exchangeSingleTagMessage(VC_BOARD_GET_MAC, make([]byte, VC_BOARD_GET_MAC_LEN)) 49 } 50 51 // Serial gets the board's serial number 52 func Serial() uint32 { 53 buf := exchangeSingleTagMessage(VC_BOARD_GET_SERIAL, make([]byte, VC_BOARD_GET_SERIAL_LEN)) 54 55 if len(buf) < 4 { 56 return 0 57 } 58 59 return binary.LittleEndian.Uint32(buf) 60 } 61 62 // CPUMemory gets the memory ranges allocated to the ARM core(s) 63 func CPUMemory() (start uint32, size uint32) { 64 buf := exchangeSingleTagMessage(VC_BOARD_GET_ARM_MEMORY, make([]byte, VC_BOARD_GET_ARM_MEMORY_LEN)) 65 66 if len(buf) < 8 { 67 return 0, 0 68 } 69 70 return binary.LittleEndian.Uint32(buf[0:]), binary.LittleEndian.Uint32(buf[4:]) 71 } 72 73 // GPUMemory gets the memory ranges allocated to VideoCore 74 func GPUMemory() (start uint32, size uint32) { 75 buf := exchangeSingleTagMessage(VC_BOARD_GET_VC_MEMORY, make([]byte, VC_BOARD_GET_VC_MEMORY_LEN)) 76 77 if len(buf) < 8 { 78 return 0, 0 79 } 80 81 return binary.LittleEndian.Uint32(buf[0:]), binary.LittleEndian.Uint32(buf[4:]) 82 } 83 84 // CPUAvailableDMAChannels gets the DMA channels available to the ARM core(s) 85 func CPUAvailableDMAChannels() (bitmask uint32) { 86 buf := exchangeSingleTagMessage(VC_RES_GET_DMACHANNELS, make([]byte, VC_RES_GET_DMACHANNELS_LEN)) 87 88 if len(buf) < 4 { 89 return 0 90 } 91 92 return binary.LittleEndian.Uint32(buf) 93 } 94 95 // AllocateGPUMemory allocates space from the GPU address space 96 // 97 // The returned value is a handle, use LockMemory to convert 98 // to an address. 99 func AllocateGPUMemory(size uint32, alignment uint32, flags uint32) (handle uint32) { 100 buf := make([]byte, VC_MEM_ALLOCATE_LEN) 101 binary.LittleEndian.PutUint32(buf[0:], size) 102 binary.LittleEndian.PutUint32(buf[4:], alignment) 103 binary.LittleEndian.PutUint32(buf[8:], uint32(flags)) 104 105 buf = exchangeSingleTagMessage(VC_MEM_ALLOCATE, buf) 106 107 if len(buf) < 4 { 108 return 0 109 } 110 111 return binary.LittleEndian.Uint32(buf) 112 } 113 114 // LockGPUMemory provides the address of previously allocated memory 115 func LockGPUMemory(handle uint32) (addr uint32) { 116 buf := make([]byte, VC_MEM_LOCK_LEN) 117 binary.LittleEndian.PutUint32(buf[0:], handle) 118 119 buf = exchangeSingleTagMessage(VC_MEM_LOCK, buf) 120 121 if len(buf) < 4 { 122 return 0 123 } 124 125 return binary.LittleEndian.Uint32(buf) 126 } 127 128 func exchangeSingleTagMessage(code uint32, buf []byte) []byte { 129 msg := &MailboxMessage{ 130 Tags: []MailboxTag{ 131 { 132 ID: code, 133 Buffer: buf, 134 }, 135 }, 136 } 137 138 Mailbox.Call(VC_CH_PROPERTYTAGS_A_TO_VC, msg) 139 140 tag := msg.Tag(code) 141 142 if tag == nil { 143 return nil 144 } 145 146 return tag.Buffer 147 }