github.com/linuxboot/fiano@v1.2.0/pkg/amd/manifest/embedded_firmware_structure.go (about)

     1  // Copyright 2019 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 manifest
     6  
     7  import (
     8  	"bytes"
     9  	"encoding/binary"
    10  	"fmt"
    11  	"io"
    12  
    13  	bytes2 "github.com/linuxboot/fiano/pkg/bytes"
    14  )
    15  
    16  // Refer to: AMD Platform Security Processor BIOS Architecture Design Guide for AMD Family 17h and Family 19h
    17  // Processors (NDA), Publication # 55758 Revision: 1.11 Issue Date: August 2020 (1)
    18  
    19  // EmbeddedFirmwareStructureSignature is a special identifier of Firmware Embedded Structure
    20  const EmbeddedFirmwareStructureSignature = 0x55aa55aa
    21  
    22  // EmbeddedFirmwareStructure represents Embedded Firmware Structure defined in Table 2 in (1)
    23  type EmbeddedFirmwareStructure struct {
    24  	Signature                uint32
    25  	Reserved1                [16]byte
    26  	PSPDirectoryTablePointer uint32
    27  
    28  	BIOSDirectoryTableFamily17hModels00h0FhPointer uint32
    29  	BIOSDirectoryTableFamily17hModels10h1FhPointer uint32
    30  	BIOSDirectoryTableFamily17hModels30h3FhPointer uint32
    31  	Reserved2                                      uint32
    32  	BIOSDirectoryTableFamily17hModels60h3FhPointer uint32
    33  
    34  	Reserved3 [30]byte
    35  }
    36  
    37  // FindEmbeddedFirmwareStructure locates and parses Embedded Firmware Structure
    38  func FindEmbeddedFirmwareStructure(firmware Firmware) (*EmbeddedFirmwareStructure, bytes2.Range, error) {
    39  	var addresses = []uint64{
    40  		0xfffa0000,
    41  		0xfff20000,
    42  		0xffe20000,
    43  		0xffc20000,
    44  		0xff820000,
    45  		0xff020000,
    46  	}
    47  
    48  	image := firmware.ImageBytes()
    49  
    50  	for _, addr := range addresses {
    51  		offset := firmware.PhysAddrToOffset(addr)
    52  		if offset+4 > uint64(len(image)) {
    53  			continue
    54  		}
    55  
    56  		actualSignature := binary.LittleEndian.Uint32(image[offset:])
    57  		if actualSignature == EmbeddedFirmwareStructureSignature {
    58  			result, length, err := ParseEmbeddedFirmwareStructure(bytes.NewBuffer(image[offset:]))
    59  			return result, bytes2.Range{Offset: offset, Length: length}, err
    60  		}
    61  	}
    62  	return nil, bytes2.Range{}, fmt.Errorf("EmbeddedFirmwareStructure is not found")
    63  }
    64  
    65  // ParseEmbeddedFirmwareStructure converts input bytes into EmbeddedFirmwareStructure
    66  func ParseEmbeddedFirmwareStructure(r io.Reader) (*EmbeddedFirmwareStructure, uint64, error) {
    67  	var result EmbeddedFirmwareStructure
    68  	if err := binary.Read(r, binary.LittleEndian, &result); err != nil {
    69  		return nil, 0, err
    70  	}
    71  
    72  	if result.Signature != EmbeddedFirmwareStructureSignature {
    73  		return nil, 0, fmt.Errorf("incorrect signature: %d", result.Signature)
    74  	}
    75  	return &result, uint64(binary.Size(result)), nil
    76  }