github.com/platinasystems/nvram@v1.0.1-0.20190709235807-51a23abd5aec/cmos_entry.go (about)

     1  // Copyright © 2019 Platina Systems, Inc. All rights reserved.
     2  // Use of this source code is governed by the GPL-2 license described in the
     3  // LICENSE file.
     4  
     5  package nvram
     6  
     7  import (
     8  	"fmt"
     9  )
    10  
    11  type CMOSEntryConfig byte
    12  
    13  const (
    14  	CMOSEntryEnum     CMOSEntryConfig = 'e'
    15  	CMOSEntryHex      CMOSEntryConfig = 'h'
    16  	CMOSEntryString   CMOSEntryConfig = 's'
    17  	CMOSEntryReserved CMOSEntryConfig = 'r'
    18  )
    19  
    20  type CMOSEntry struct {
    21  	bit       uint
    22  	length    uint
    23  	config    CMOSEntryConfig
    24  	config_id uint
    25  	name      string
    26  }
    27  
    28  func (e CMOSEntry) String() string {
    29  	return fmt.Sprintf("%d %d %c %d %s", e.bit, e.length, e.config, e.config_id, e.name)
    30  }
    31  
    32  func (e CMOSEntry) Bit() uint {
    33  	return e.bit
    34  }
    35  
    36  func (e CMOSEntry) Length() uint {
    37  	return e.length
    38  }
    39  
    40  func (e CMOSEntry) Config() CMOSEntryConfig {
    41  	return e.config
    42  }
    43  
    44  func (e CMOSEntry) ConfigId() uint {
    45  	return e.config_id
    46  }
    47  
    48  func (e CMOSEntry) Name() string {
    49  	return e.name
    50  }
    51  
    52  func verifyCMOSEntry(e *CMOSEntry) error {
    53  	// Check if entry is out of range.
    54  	if (e.bit >= (8 * cmosSize)) || ((e.bit + e.length) > (8 * cmosSize)) {
    55  		return fmt.Errorf("CMOS entry %s out of range.", e.name)
    56  	}
    57  
    58  	// Check if entry is unaligned and spanning multiple bytes.
    59  	if ((e.bit % 8) > 0) && ((e.bit / 8) != ((e.bit + e.length - 1) / 8)) {
    60  		return fmt.Errorf("CMOS entry %s unaligned spanning multiple bytes.", e.name)
    61  	}
    62  
    63  	// Check for a valid config type
    64  	switch e.config {
    65  	case CMOSEntryString:
    66  	case CMOSEntryEnum:
    67  	case CMOSEntryHex:
    68  	case CMOSEntryReserved:
    69  	default:
    70  		return fmt.Errorf("CMOS entry %s has invalid config type.", e.name)
    71  	}
    72  
    73  	return nil
    74  }
    75  
    76  func verifyCMOSOp(e *CMOSEntry) error {
    77  	// Check if entry is reserved
    78  	if e.config == CMOSEntryReserved {
    79  		return fmt.Errorf("CMOS entry %s is reserved.", e.name)
    80  	}
    81  
    82  	// Check if entry is in the RTC area
    83  	if e.bit < (8 * cmosRTCAreaSize) {
    84  		return fmt.Errorf("CMOS entry %s overlaps RTC.", e.name)
    85  	}
    86  
    87  	// Check if entry is more than 64 bits and not a string
    88  	if e.length > 64 && e.config != CMOSEntryString {
    89  		return fmt.Errorf("CMOS entry %s too wide.", e.name)
    90  	}
    91  
    92  	// Verify the rest of the entry
    93  	return verifyCMOSEntry(e)
    94  }
    95  
    96  func (e *CMOSEntry) IsOverlap(e1 *CMOSEntry) bool {
    97  	// Check if this entry overlaps another entry
    98  	return checkAreaOverLap(e.bit, e.length, e1.bit, e1.length)
    99  }
   100  
   101  func checkAreaOverLap(s0, l0, s1, l1 uint) bool {
   102  	e0 := s0 + l0 - 1
   103  	e1 := s1 + l1 - 1
   104  	return ((s1 <= e0) && (s0 <= e1))
   105  }