github.com/jspc/eggos@v0.5.1-0.20221028160421-556c75c878a5/drivers/clock/cmos.go (about)

     1  package clock
     2  
     3  import (
     4  	"time"
     5  
     6  	"github.com/jspc/eggos/kernel/sys"
     7  )
     8  
     9  type CmosTime struct {
    10  	Second int
    11  	Minute int
    12  	Hour   int
    13  	Day    int
    14  	Month  int
    15  	Year   int
    16  }
    17  
    18  func ReadCmosTime() CmosTime {
    19  	var t CmosTime
    20  	for {
    21  		readCmosTime(&t)
    22  		if bcdDecode(readCmosSecond()) == t.Second {
    23  			break
    24  		}
    25  	}
    26  	return t
    27  }
    28  
    29  func (c *CmosTime) Time() time.Time {
    30  	return time.Date(c.Year, time.Month(c.Month), c.Day, c.Hour, c.Minute, c.Second, 0, time.UTC)
    31  }
    32  
    33  // https://wiki.osdev.org/CMOS
    34  func readCmosTime(t *CmosTime) {
    35  	t.Year = bcdDecode(readCmosReg(0x09)) + bcdDecode(readCmosReg(0x32))*100
    36  	t.Month = bcdDecode(readCmosReg(0x08))
    37  	t.Day = bcdDecode(readCmosReg(0x07))
    38  	t.Hour = bcdDecode(readCmosReg(0x04))
    39  	t.Minute = bcdDecode(readCmosReg(0x02))
    40  	t.Second = bcdDecode(readCmosReg(0x00))
    41  }
    42  
    43  func readCmosSecond() int {
    44  	return readCmosReg(0x00)
    45  }
    46  
    47  // decode bcd format
    48  func bcdDecode(v int) int {
    49  	return v&0x0F + v/16*10
    50  }
    51  
    52  //go:nosplit
    53  func readCmosReg(reg uint16) int {
    54  	sys.Outb(0x70, 0x80|byte(reg))
    55  	return int(sys.Inb(0x71))
    56  }