static int read_seed_from_cmos(struct pei_data *pei_data) { u16 c1, c2, checksum, seed_checksum; struct udevice *dev; int ret = 0; ret = uclass_get_device(UCLASS_RTC, 0, &dev); if (ret) { debug("Cannot find RTC: err=%d\n", ret); return -ENODEV; } /* * Read scrambler seeds from CMOS RAM. We don't want to store them in * SPI flash since they change on every boot and that would wear down * the flash too much. So we store these in CMOS and the large MRC * data in SPI flash. */ ret = rtc_read32(dev, CMOS_OFFSET_MRC_SEED, &pei_data->scrambler_seed); if (!ret) { ret = rtc_read32(dev, CMOS_OFFSET_MRC_SEED_S3, &pei_data->scrambler_seed_s3); } if (ret) { debug("Failed to read from RTC %s\n", dev->name); return ret; } debug("Read scrambler seed 0x%08x from CMOS 0x%02x\n", pei_data->scrambler_seed, CMOS_OFFSET_MRC_SEED); debug("Read S3 scrambler seed 0x%08x from CMOS 0x%02x\n", pei_data->scrambler_seed_s3, CMOS_OFFSET_MRC_SEED_S3); /* Compute seed checksum and compare */ c1 = compute_ip_checksum((u8 *)&pei_data->scrambler_seed, sizeof(u32)); c2 = compute_ip_checksum((u8 *)&pei_data->scrambler_seed_s3, sizeof(u32)); checksum = add_ip_checksums(sizeof(u32), c1, c2); seed_checksum = rtc_read8(dev, CMOS_OFFSET_MRC_SEED_CHK); seed_checksum |= rtc_read8(dev, CMOS_OFFSET_MRC_SEED_CHK + 1) << 8; if (checksum != seed_checksum) { debug("%s: invalid seed checksum\n", __func__); pei_data->scrambler_seed = 0; pei_data->scrambler_seed_s3 = 0; return -EINVAL; } return 0; }
u32 rtc_read32(int reg) { u32 value = 0; int i; for (i = 0; i < sizeof(value); i++) value |= rtc_read8(reg + i) << (i << 3); return value; }
/* Treat all 32-bit operations as two 16-bit operations */ uint8 loadB(uint32 address) { address &= 0xFFFFFF; if(FastReadMap[address >> 16]) return(FastReadMap[address >> 16][address]); uint8* ptr = (uint8*)translate_address_read(address); if (ptr) return *ptr; if(address >= 0x8000 && address <= 0xbfff) return(NGPGfx->read8(address)); if(address >= 0x4000 && address <= 0x7fff) { return(*(uint8 *)(CPUExRAM + address - 0x4000)); } if(address >= 0x70 && address <= 0x7F) { return(int_read8(address)); } if(address >= 0x90 && address <= 0x97) { return(rtc_read8(address)); } if(address >= 0x20 && address <= 0x29) { return(timer_read8(address)); } if(address == 0x50) return(SC0BUF); if(address == 0xBC) return Z80_ReadComm(); //printf("UNK B R: %08x\n", address); return(0); }
void rtc_init(void) { #if CLEAR_CMOS int i; rtc_write8(RTC_SECONDS_ALARM, 0); rtc_write8(RTC_MINUTES_ALARM, 0); rtc_write8(RTC_HOURS_ALARM, 0); for (i = RTC_CONFIG_A; i < RTC_REG_SIZE; i++) rtc_write8(i, 0); printf("RTC: zeroing CMOS RAM\n"); #endif /* Setup the real time clock */ rtc_write8(RTC_CONFIG_B, RTC_CONFIG_B_24H); /* Setup the frequency it operates at */ rtc_write8(RTC_CONFIG_A, RTC_CONFIG_A_REF_CLCK_32KHZ | RTC_CONFIG_A_RATE_1024HZ); /* Ensure all reserved bits are 0 in register D */ rtc_write8(RTC_CONFIG_D, RTC_CONFIG_D_VALID_RAM_AND_TIME); /* Clear any pending interrupts */ rtc_read8(RTC_CONFIG_C); }
uint16 loadW(uint32 address) { address &= 0xFFFFFF; if(address & 1) { uint16 ret; ret = loadB(address); ret |= loadB(address + 1) << 8; return(ret); } if(FastReadMap[address >> 16]) return(MDFN_de16lsb<true>(&FastReadMap[address >> 16][address])); uint16* ptr = (uint16*)translate_address_read(address); if(ptr) return MDFN_de16lsb<true>(ptr); if(address >= 0x8000 && address <= 0xbfff) return(NGPGfx->read16(address)); if(address >= 0x4000 && address <= 0x7fff) { return(MDFN_de16lsb<true>(CPUExRAM + address - 0x4000)); } if(address == 0x50) return(SC0BUF); if(address >= 0x70 && address <= 0x7F) { uint16 ret; ret = int_read8(address); ret |= int_read8(address + 1) << 8; return(ret); } if(address >= 0x90 && address <= 0x97) { uint16 ret; ret = rtc_read8(address); ret |= rtc_read8(address + 1) << 8; return(ret); } if(address >= 0x20 && address <= 0x29) { uint16 ret; ret = timer_read8(address); ret |= timer_read8(address + 1) << 8; return(ret); } if(address == 0xBC) return Z80_ReadComm(); //printf("UNK W R: %08x\n", address); return(0); }
int rtc_get (struct rtc_time *tmp) { uchar sec, min, hour, mday, wday, mon, year; /* here check if rtc can be accessed */ while ((rtc_read8(RTC_CONFIG_A) & 0x80) == 0x80); sec = rtc_read8(RTC_SECONDS); min = rtc_read8(RTC_MINUTES); hour = rtc_read8(RTC_HOURS); mday = rtc_read8(RTC_DATE_OF_MONTH); wday = rtc_read8(RTC_DAY_OF_WEEK); mon = rtc_read8(RTC_MONTH); year = rtc_read8(RTC_YEAR); #ifdef RTC_DEBUG printf ( "Get RTC year: %02x mon/cent: %02x mday: %02x wday: %02x " "hr: %02x min: %02x sec: %02x\n", year, mon, mday, wday, hour, min, sec ); printf ( "Alarms: month: %02x hour: %02x min: %02x sec: %02x\n", rtc_read8(RTC_CONFIG_D) & 0x3F, rtc_read8(RTC_HOURS_ALARM), rtc_read8(RTC_MINUTES_ALARM), rtc_read8(RTC_SECONDS_ALARM)); #endif tmp->tm_sec = bcd2bin (sec & 0x7F); tmp->tm_min = bcd2bin (min & 0x7F); tmp->tm_hour = bcd2bin (hour & 0x3F); tmp->tm_mday = bcd2bin (mday & 0x3F); tmp->tm_mon = bcd2bin (mon & 0x1F); tmp->tm_year = bcd2bin (year); tmp->tm_wday = bcd2bin (wday & 0x07); if(tmp->tm_year<70) tmp->tm_year+=2000; else tmp->tm_year+=1900; tmp->tm_yday = 0; tmp->tm_isdst= 0; #ifdef RTC_DEBUG printf ( "Get DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n", tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday, tmp->tm_hour, tmp->tm_min, tmp->tm_sec); #endif return 0; }