github.com/linuxboot/fiano@v1.2.0/pkg/intel/me/me.go (about) 1 // Copyright 2021 the LinuxBoot Authors. All rights reserved 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package me 6 7 import ( 8 "bytes" 9 "encoding/binary" 10 "io" 11 ) 12 13 var ( 14 Signature = [4]byte{0x24, 0x46, 0x50, 0x54} 15 ) 16 17 func parseLegacyFlashPartitionTableHeader(r io.Reader) (*LegacyFlashPartitionTableHeader, error) { 18 var header LegacyFlashPartitionTableHeader 19 var scrap [12]byte 20 if err := binary.Read(r, binary.LittleEndian, &scrap); err != nil { 21 return nil, err 22 } 23 if err := binary.Read(r, binary.LittleEndian, &header.Marker); err != nil { 24 return nil, err 25 } 26 if err := binary.Read(r, binary.LittleEndian, &header.NumFptEntries); err != nil { 27 return nil, err 28 } 29 if err := binary.Read(r, binary.LittleEndian, &header.HeaderVersion); err != nil { 30 return nil, err 31 } 32 if err := binary.Read(r, binary.LittleEndian, &header.EntryVersion); err != nil { 33 return nil, err 34 } 35 if err := binary.Read(r, binary.LittleEndian, &header.HeaderLength); err != nil { 36 return nil, err 37 } 38 if err := binary.Read(r, binary.LittleEndian, &header.HeaderChecksum); err != nil { 39 return nil, err 40 } 41 if err := binary.Read(r, binary.LittleEndian, &header.TicksToAdd); err != nil { 42 return nil, err 43 } 44 if err := binary.Read(r, binary.LittleEndian, &header.TokensToAdd); err != nil { 45 return nil, err 46 } 47 if err := binary.Read(r, binary.LittleEndian, &header.UMASize); err != nil { 48 return nil, err 49 } 50 if err := binary.Read(r, binary.LittleEndian, &header.Flags); err != nil { 51 return nil, err 52 } 53 return &header, nil 54 55 } 56 57 func parseFlashPartitionTableHeader(r io.Reader) (*FlashPartitionTableHeader, error) { 58 var header FlashPartitionTableHeader 59 // Set Signature 60 header.Marker = Signature 61 62 if err := binary.Read(r, binary.LittleEndian, &header.NumFptEntries); err != nil { 63 return nil, err 64 } 65 if err := binary.Read(r, binary.LittleEndian, &header.HeaderVersion); err != nil { 66 return nil, err 67 } 68 if err := binary.Read(r, binary.LittleEndian, &header.EntryVersion); err != nil { 69 return nil, err 70 } 71 if err := binary.Read(r, binary.LittleEndian, &header.HeaderLength); err != nil { 72 return nil, err 73 } 74 if err := binary.Read(r, binary.LittleEndian, &header.HeaderChecksum); err != nil { 75 return nil, err 76 } 77 if err := binary.Read(r, binary.LittleEndian, &header.TicksToAdd); err != nil { 78 return nil, err 79 } 80 if err := binary.Read(r, binary.LittleEndian, &header.TokensToAdd); err != nil { 81 return nil, err 82 } 83 if err := binary.Read(r, binary.LittleEndian, &header.UMASizeOrReserved); err != nil { 84 return nil, err 85 } 86 if err := binary.Read(r, binary.LittleEndian, &header.FlashLayoutOrFlags); err != nil { 87 return nil, err 88 } 89 if err := binary.Read(r, binary.LittleEndian, &header.FitcMajor); err != nil { 90 return nil, err 91 } 92 if err := binary.Read(r, binary.LittleEndian, &header.FitcMinor); err != nil { 93 return nil, err 94 } 95 if err := binary.Read(r, binary.LittleEndian, &header.FitcHotfix); err != nil { 96 return nil, err 97 } 98 if err := binary.Read(r, binary.LittleEndian, &header.FitcBuild); err != nil { 99 return nil, err 100 } 101 102 return &header, nil 103 } 104 105 func parseEntry(r io.Reader) (*FlashPartitionTableEntry, error) { 106 var entry FlashPartitionTableEntry 107 if err := binary.Read(r, binary.LittleEndian, &entry); err != nil { 108 return nil, err 109 } 110 return &entry, nil 111 } 112 113 // ParseIntelFirmware parses the Intel firmware image by uefi.Firmware interface` 114 func ParseIntelME(r io.Reader) (*IntelME, error) { 115 var me IntelME 116 me.legacy = false 117 var numEntries uint32 118 119 // Read first 4 byte, we catch the marker as prefix or suffix 120 var markerarea [4]byte 121 if err := binary.Read(r, binary.LittleEndian, &markerarea); err != nil { 122 return nil, err 123 } 124 125 // Check on new header 126 if bytes.HasPrefix(markerarea[:], Signature[:]) { 127 hdr, err := parseFlashPartitionTableHeader(r) 128 if err != nil { 129 return nil, err 130 } 131 me.hdr = hdr 132 numEntries = hdr.NumFptEntries 133 } else { 134 me.legacy = true 135 hdr, err := parseLegacyFlashPartitionTableHeader(r) 136 if err != nil { 137 return nil, err 138 } 139 me.legacyhdr = hdr 140 numEntries = hdr.NumFptEntries 141 } 142 143 partitions := make([]FlashPartitionTableEntry, 0) 144 for i := uint32(0); i < numEntries; i++ { 145 entry, err := parseEntry(r) 146 if err != nil { 147 return nil, err 148 } 149 partitions = append(partitions, *entry) 150 } 151 me.partitions = partitions 152 return &me, nil 153 }