github.com/icexin/eggos@v0.4.2-0.20220216025428-78b167e4f349/drivers/clock/cmos.go (about) 1 package clock 2 3 import ( 4 "time" 5 6 "github.com/icexin/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 }