github.com/mvdan/u-root-coreutils@v0.0.0-20230122170626-c2eef2898555/pkg/vpd/flashromvpd.go (about)

     1  // Copyright 2021 the u-root 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 vpd
     6  
     7  import (
     8  	"log"
     9  	"os"
    10  	"os/exec"
    11  	"os/signal"
    12  	"syscall"
    13  )
    14  
    15  func handler(c <-chan os.Signal) {
    16  	for range c {
    17  		log.Printf("ignoring SIGINT during flash write to prevent corruption")
    18  	}
    19  }
    20  
    21  // Set RW_VPD key-value via flashrom and vpd executables, delete set to false would set or add the key,
    22  // delete set to true would delete an existing key.
    23  func FlashromRWVpdSet(key string, value []byte, delete bool) error {
    24  	file, err := os.CreateTemp("/tmp", "rwvpd*.bin")
    25  	if err != nil {
    26  		return err
    27  	}
    28  	defer os.Remove(file.Name())
    29  
    30  	c := make(chan os.Signal, 1)
    31  	go handler(c)
    32  	defer close(c)
    33  
    34  	cmd := exec.Command("flashrom", "-p", "internal:ich_spi_mode=hwseq", "-c", "Opaque flash chip", "--fmap", "-i", "RW_VPD", "-r", file.Name())
    35  	cmd.Stdin, cmd.Stdout = os.Stdin, os.Stdout
    36  	if err = cmd.Run(); err != nil {
    37  		log.Printf("flashrom failed to read RW_VPD: %v", err)
    38  		return err
    39  	}
    40  
    41  	if delete {
    42  		cmd = exec.Command("vpd", "-f", file.Name(), "-d", key)
    43  		if err = cmd.Run(); err != nil {
    44  			log.Printf("vpd failed to delete key: %v, err: %v", key, err)
    45  			return err
    46  		}
    47  	} else {
    48  		cmd = exec.Command("vpd", "-f", file.Name(), "-s", key+"="+string(value[:]))
    49  		if err = cmd.Run(); err != nil {
    50  			log.Printf("vpd failed to set key: %v value: %v, err: %v", key, string(value[:]), err)
    51  			return err
    52  		}
    53  	}
    54  
    55  	cmd = exec.Command("flashrom", "-p", "internal:ich_spi_mode=hwseq", "-c", "Opaque flash chip", "--fmap", "-i", "RW_VPD", "--noverify-all", "-w", file.Name())
    56  	cmd.SysProcAttr = &syscall.SysProcAttr{
    57  		Setpgid: true,
    58  	}
    59  	signal.Notify(c, syscall.SIGINT)
    60  	defer signal.Reset(syscall.SIGINT)
    61  	if err = cmd.Run(); err != nil {
    62  		log.Printf("flashrom failed to write RW_VPD: %v", err)
    63  		return err
    64  	}
    65  	return nil
    66  }
    67  
    68  // ClearRwVpd re-format RW_VPD via flashrom and vpd executables
    69  func ClearRwVpd() error {
    70  	file, err := os.CreateTemp("/tmp", "rwvpd*.bin")
    71  	if err != nil {
    72  		return err
    73  	}
    74  	defer os.Remove(file.Name())
    75  
    76  	c := make(chan os.Signal, 1)
    77  	go handler(c)
    78  	defer close(c)
    79  
    80  	log.Printf("Reading RW_VPD...")
    81  	cmd := exec.Command("flashrom", "-p", "internal:ich_spi_mode=hwseq", "-c", "Opaque flash chip", "--fmap", "-i", "RW_VPD", "-r", file.Name())
    82  	cmd.Stdin, cmd.Stdout = os.Stdin, os.Stdout
    83  	if err = cmd.Run(); err != nil {
    84  		log.Printf("flashrom failed to read RW_VPD: %v", err)
    85  		return err
    86  	}
    87  	cmd = exec.Command("vpd", "-f", file.Name(), "-O")
    88  	if err = cmd.Run(); err != nil {
    89  		log.Printf("vpd failed to re-format RW_VPD: %v", err)
    90  		return err
    91  	}
    92  	cmd = exec.Command("flashrom", "-p", "internal:ich_spi_mode=hwseq", "-c", "Opaque flash chip", "--fmap", "-i", "RW_VPD", "--noverify-all", "-w", file.Name())
    93  	cmd.SysProcAttr = &syscall.SysProcAttr{
    94  		Setpgid: true,
    95  	}
    96  	signal.Notify(c, syscall.SIGINT)
    97  	defer signal.Reset(syscall.SIGINT)
    98  	if err = cmd.Run(); err != nil {
    99  		log.Printf("flashrom failed to write RW_VPD: %v", err)
   100  		return err
   101  	}
   102  	return nil
   103  }
   104  
   105  // FlashromVpdDump read and dump all VPD values from RO and RW VPD flash regions directly
   106  func FlashromVpdDump() error {
   107  	file, err := os.CreateTemp("/tmp", "rovpd*.bin")
   108  	if err != nil {
   109  		return err
   110  	}
   111  	defer os.Remove(file.Name())
   112  
   113  	log.Printf("RO_VPD values:")
   114  	cmd := exec.Command("flashrom", "-p", "internal:ich_spi_mode=hwseq", "-c", "Opaque flash chip", "--fmap", "-i", "RO_VPD", "-r", file.Name())
   115  	if err = cmd.Run(); err != nil {
   116  		log.Printf("flashrom failed to read RO_VPD: %v", err)
   117  		return err
   118  	}
   119  	cmd = exec.Command("vpd", "-f", file.Name(), "-l")
   120  	cmd.Stdin, cmd.Stdout = os.Stdin, os.Stdout
   121  	if err = cmd.Run(); err != nil {
   122  		log.Printf("vpd failed to print RO_VPD: %v", err)
   123  		return err
   124  	}
   125  
   126  	os.Remove(file.Name())
   127  	file, err = os.CreateTemp("/tmp", "rwvpd*.bin")
   128  	if err != nil {
   129  		return err
   130  	}
   131  	defer os.Remove(file.Name())
   132  
   133  	log.Printf("RW_VPD values:")
   134  	cmd = exec.Command("flashrom", "-p", "internal:ich_spi_mode=hwseq", "-c", "Opaque flash chip", "--fmap", "-i", "RW_VPD", "-r", file.Name())
   135  	if err = cmd.Run(); err != nil {
   136  		log.Printf("flashrom failed to read RW_VPD: %v", err)
   137  		return err
   138  	}
   139  	cmd = exec.Command("vpd", "-f", file.Name(), "-l")
   140  	cmd.Stdin, cmd.Stdout = os.Stdin, os.Stdout
   141  	if err = cmd.Run(); err != nil {
   142  		log.Printf("vpd failed to print RW_VPD: %v", err)
   143  		return err
   144  	}
   145  
   146  	return nil
   147  }