github.com/platinasystems/nvram@v1.0.1-0.20190709235807-51a23abd5aec/cmos_mem.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  	"github.com/platinasystems/nvram/debug"
    10  	"os"
    11  	"syscall"
    12  )
    13  
    14  type CMOSMem struct {
    15  	mem_file *os.File
    16  	mem      []byte
    17  }
    18  
    19  func (c *CMOSMem) Open(filename string) (err error) {
    20  	// Close in case it is already opened
    21  	c.Close()
    22  
    23  	// Close on any error
    24  	defer func() {
    25  		if err != nil {
    26  			c.Close()
    27  		}
    28  	}()
    29  
    30  	debug.Trace(debug.LevelMSG1, "Opening CMOS Mem file %s\n", filename)
    31  
    32  	// Open CMOS data file
    33  	c.mem_file, err = os.OpenFile(filename, os.O_RDWR|os.O_SYNC, 0)
    34  	if err != nil {
    35  		return
    36  	}
    37  
    38  	fi, err := c.mem_file.Stat()
    39  	if err != nil {
    40  		return
    41  	}
    42  	size := fi.Size()
    43  
    44  	if size < 0 {
    45  		err = fmt.Errorf("nvram: File %s has negative size.", filename)
    46  		return
    47  	}
    48  
    49  	// Memory map file for access.
    50  	c.mem, err = syscall.Mmap(int(c.mem_file.Fd()), 0, int(size),
    51  		syscall.PROT_READ|syscall.PROT_WRITE, syscall.MAP_SHARED)
    52  	if err != nil {
    53  		return
    54  	}
    55  
    56  	debug.Trace(debug.LevelMSG3, "c.mem len = %d\n", len(c.mem))
    57  
    58  	return
    59  }
    60  
    61  func (c *CMOSMem) Close() (err error) {
    62  
    63  	debug.Trace(debug.LevelMSG1, "Closing CMOS Mem\n")
    64  
    65  	// Unmap file if it has been mapped
    66  	if len(c.mem) > 0 {
    67  		syscall.Munmap(c.mem)
    68  		c.mem = nil
    69  	}
    70  
    71  	// Close file
    72  	if c.mem_file != nil {
    73  		c.mem_file.Close()
    74  		c.mem_file = nil
    75  	}
    76  
    77  	return
    78  }
    79  
    80  func (c *CMOSMem) ReadByte(off uint) (byte, error) {
    81  	if len(c.mem) == 0 {
    82  		return 0, ErrCMOSNotOpen
    83  	}
    84  	if !verifyCMOSByteIndex(off) {
    85  		return 0, ErrInvalidCMOSIndex
    86  	}
    87  	return c.mem[off], nil
    88  }
    89  
    90  func (c *CMOSMem) WriteByte(off uint, b byte) error {
    91  	if len(c.mem) == 0 {
    92  		return ErrCMOSNotOpen
    93  	}
    94  	if !verifyCMOSByteIndex(off) {
    95  		return ErrInvalidCMOSIndex
    96  	}
    97  	c.mem[off] = b
    98  	return nil
    99  }