From abd0c6bda0c89f36528e1a7efac99277607a5280 Mon Sep 17 00:00:00 2001 From: Paul Brook Date: Fri, 20 Nov 2009 00:03:47 +0000 Subject: [PATCH] BCD cleanup Combine multiple BCD implementations. Signed-off-by: Paul Brook --- hw/m48t59.c | 50 ++++++++++++++++------------------------ hw/mc146818rtc.c | 36 ++++++++++++++--------------- hw/omap1.c | 70 ++++++++++++++++++++++++-------------------------------- hw/twl92230.c | 10 -------- qemu-common.h | 11 +++++++++ 5 files changed, 79 insertions(+), 98 deletions(-) diff --git a/hw/m48t59.c b/hw/m48t59.c index bb58419d2a..ce38f8b6ec 100644 --- a/hw/m48t59.c +++ b/hw/m48t59.c @@ -80,16 +80,6 @@ typedef struct M48t59SysBusState { } M48t59SysBusState; /* Fake timer functions */ -/* Generic helpers for BCD */ -static inline uint8_t toBCD (uint8_t value) -{ - return (((value / 10) % 10) << 4) | (value % 10); -} - -static inline uint8_t fromBCD (uint8_t BCD) -{ - return ((BCD >> 4) * 10) + (BCD & 0x0F); -} /* Alarm management */ static void alarm_cb (void *opaque) @@ -219,7 +209,7 @@ void m48t59_write (void *opaque, uint32_t addr, uint32_t val) break; case 0x1FF2: /* alarm seconds */ - tmp = fromBCD(val & 0x7F); + tmp = from_bcd(val & 0x7F); if (tmp >= 0 && tmp <= 59) { NVRAM->alarm.tm_sec = tmp; NVRAM->buffer[0x1FF2] = val; @@ -228,7 +218,7 @@ void m48t59_write (void *opaque, uint32_t addr, uint32_t val) break; case 0x1FF3: /* alarm minutes */ - tmp = fromBCD(val & 0x7F); + tmp = from_bcd(val & 0x7F); if (tmp >= 0 && tmp <= 59) { NVRAM->alarm.tm_min = tmp; NVRAM->buffer[0x1FF3] = val; @@ -237,7 +227,7 @@ void m48t59_write (void *opaque, uint32_t addr, uint32_t val) break; case 0x1FF4: /* alarm hours */ - tmp = fromBCD(val & 0x3F); + tmp = from_bcd(val & 0x3F); if (tmp >= 0 && tmp <= 23) { NVRAM->alarm.tm_hour = tmp; NVRAM->buffer[0x1FF4] = val; @@ -246,7 +236,7 @@ void m48t59_write (void *opaque, uint32_t addr, uint32_t val) break; case 0x1FF5: /* alarm date */ - tmp = fromBCD(val & 0x1F); + tmp = from_bcd(val & 0x1F); if (tmp != 0) { NVRAM->alarm.tm_mday = tmp; NVRAM->buffer[0x1FF5] = val; @@ -270,7 +260,7 @@ void m48t59_write (void *opaque, uint32_t addr, uint32_t val) case 0x1FF9: case 0x07F9: /* seconds (BCD) */ - tmp = fromBCD(val & 0x7F); + tmp = from_bcd(val & 0x7F); if (tmp >= 0 && tmp <= 59) { get_time(NVRAM, &tm); tm.tm_sec = tmp; @@ -289,7 +279,7 @@ void m48t59_write (void *opaque, uint32_t addr, uint32_t val) case 0x1FFA: case 0x07FA: /* minutes (BCD) */ - tmp = fromBCD(val & 0x7F); + tmp = from_bcd(val & 0x7F); if (tmp >= 0 && tmp <= 59) { get_time(NVRAM, &tm); tm.tm_min = tmp; @@ -299,7 +289,7 @@ void m48t59_write (void *opaque, uint32_t addr, uint32_t val) case 0x1FFB: case 0x07FB: /* hours (BCD) */ - tmp = fromBCD(val & 0x3F); + tmp = from_bcd(val & 0x3F); if (tmp >= 0 && tmp <= 23) { get_time(NVRAM, &tm); tm.tm_hour = tmp; @@ -309,7 +299,7 @@ void m48t59_write (void *opaque, uint32_t addr, uint32_t val) case 0x1FFC: case 0x07FC: /* day of the week / century */ - tmp = fromBCD(val & 0x07); + tmp = from_bcd(val & 0x07); get_time(NVRAM, &tm); tm.tm_wday = tmp; set_time(NVRAM, &tm); @@ -318,7 +308,7 @@ void m48t59_write (void *opaque, uint32_t addr, uint32_t val) case 0x1FFD: case 0x07FD: /* date */ - tmp = fromBCD(val & 0x1F); + tmp = from_bcd(val & 0x1F); if (tmp != 0) { get_time(NVRAM, &tm); tm.tm_mday = tmp; @@ -328,7 +318,7 @@ void m48t59_write (void *opaque, uint32_t addr, uint32_t val) case 0x1FFE: case 0x07FE: /* month */ - tmp = fromBCD(val & 0x1F); + tmp = from_bcd(val & 0x1F); if (tmp >= 1 && tmp <= 12) { get_time(NVRAM, &tm); tm.tm_mon = tmp - 1; @@ -338,13 +328,13 @@ void m48t59_write (void *opaque, uint32_t addr, uint32_t val) case 0x1FFF: case 0x07FF: /* year */ - tmp = fromBCD(val); + tmp = from_bcd(val); if (tmp >= 0 && tmp <= 99) { get_time(NVRAM, &tm); if (NVRAM->type == 8) - tm.tm_year = fromBCD(val) + 68; // Base year is 1968 + tm.tm_year = from_bcd(val) + 68; // Base year is 1968 else - tm.tm_year = fromBCD(val); + tm.tm_year = from_bcd(val); set_time(NVRAM, &tm); } break; @@ -410,19 +400,19 @@ uint32_t m48t59_read (void *opaque, uint32_t addr) case 0x07F9: /* seconds (BCD) */ get_time(NVRAM, &tm); - retval = (NVRAM->buffer[addr] & 0x80) | toBCD(tm.tm_sec); + retval = (NVRAM->buffer[addr] & 0x80) | to_bcd(tm.tm_sec); break; case 0x1FFA: case 0x07FA: /* minutes (BCD) */ get_time(NVRAM, &tm); - retval = toBCD(tm.tm_min); + retval = to_bcd(tm.tm_min); break; case 0x1FFB: case 0x07FB: /* hours (BCD) */ get_time(NVRAM, &tm); - retval = toBCD(tm.tm_hour); + retval = to_bcd(tm.tm_hour); break; case 0x1FFC: case 0x07FC: @@ -434,22 +424,22 @@ uint32_t m48t59_read (void *opaque, uint32_t addr) case 0x07FD: /* date */ get_time(NVRAM, &tm); - retval = toBCD(tm.tm_mday); + retval = to_bcd(tm.tm_mday); break; case 0x1FFE: case 0x07FE: /* month */ get_time(NVRAM, &tm); - retval = toBCD(tm.tm_mon + 1); + retval = to_bcd(tm.tm_mon + 1); break; case 0x1FFF: case 0x07FF: /* year */ get_time(NVRAM, &tm); if (NVRAM->type == 8) - retval = toBCD(tm.tm_year - 68); // Base year is 1968 + retval = to_bcd(tm.tm_year - 68); // Base year is 1968 else - retval = toBCD(tm.tm_year); + retval = to_bcd(tm.tm_year); break; default: /* Check lock registers state */ diff --git a/hw/mc146818rtc.c b/hw/mc146818rtc.c index 61ddf0b35d..b8c7b0c1b8 100644 --- a/hw/mc146818rtc.c +++ b/hw/mc146818rtc.c @@ -259,7 +259,7 @@ static void cmos_ioport_write(void *opaque, uint32_t addr, uint32_t data) } } -static inline int to_bcd(RTCState *s, int a) +static inline int rtc_to_bcd(RTCState *s, int a) { if (s->cmos_data[RTC_REG_B] & REG_B_DM) { return a; @@ -268,7 +268,7 @@ static inline int to_bcd(RTCState *s, int a) } } -static inline int from_bcd(RTCState *s, int a) +static inline int rtc_from_bcd(RTCState *s, int a) { if (s->cmos_data[RTC_REG_B] & REG_B_DM) { return a; @@ -281,17 +281,17 @@ static void rtc_set_time(RTCState *s) { struct tm *tm = &s->current_tm; - tm->tm_sec = from_bcd(s, s->cmos_data[RTC_SECONDS]); - tm->tm_min = from_bcd(s, s->cmos_data[RTC_MINUTES]); - tm->tm_hour = from_bcd(s, s->cmos_data[RTC_HOURS] & 0x7f); + tm->tm_sec = rtc_from_bcd(s, s->cmos_data[RTC_SECONDS]); + tm->tm_min = rtc_from_bcd(s, s->cmos_data[RTC_MINUTES]); + tm->tm_hour = rtc_from_bcd(s, s->cmos_data[RTC_HOURS] & 0x7f); if (!(s->cmos_data[RTC_REG_B] & 0x02) && (s->cmos_data[RTC_HOURS] & 0x80)) { tm->tm_hour += 12; } - tm->tm_wday = from_bcd(s, s->cmos_data[RTC_DAY_OF_WEEK]) - 1; - tm->tm_mday = from_bcd(s, s->cmos_data[RTC_DAY_OF_MONTH]); - tm->tm_mon = from_bcd(s, s->cmos_data[RTC_MONTH]) - 1; - tm->tm_year = from_bcd(s, s->cmos_data[RTC_YEAR]) + s->base_year - 1900; + tm->tm_wday = rtc_from_bcd(s, s->cmos_data[RTC_DAY_OF_WEEK]) - 1; + tm->tm_mday = rtc_from_bcd(s, s->cmos_data[RTC_DAY_OF_MONTH]); + tm->tm_mon = rtc_from_bcd(s, s->cmos_data[RTC_MONTH]) - 1; + tm->tm_year = rtc_from_bcd(s, s->cmos_data[RTC_YEAR]) + s->base_year - 1900; } static void rtc_copy_date(RTCState *s) @@ -299,24 +299,24 @@ static void rtc_copy_date(RTCState *s) const struct tm *tm = &s->current_tm; int year; - s->cmos_data[RTC_SECONDS] = to_bcd(s, tm->tm_sec); - s->cmos_data[RTC_MINUTES] = to_bcd(s, tm->tm_min); + s->cmos_data[RTC_SECONDS] = rtc_to_bcd(s, tm->tm_sec); + s->cmos_data[RTC_MINUTES] = rtc_to_bcd(s, tm->tm_min); if (s->cmos_data[RTC_REG_B] & 0x02) { /* 24 hour format */ - s->cmos_data[RTC_HOURS] = to_bcd(s, tm->tm_hour); + s->cmos_data[RTC_HOURS] = rtc_to_bcd(s, tm->tm_hour); } else { /* 12 hour format */ - s->cmos_data[RTC_HOURS] = to_bcd(s, tm->tm_hour % 12); + s->cmos_data[RTC_HOURS] = rtc_to_bcd(s, tm->tm_hour % 12); if (tm->tm_hour >= 12) s->cmos_data[RTC_HOURS] |= 0x80; } - s->cmos_data[RTC_DAY_OF_WEEK] = to_bcd(s, tm->tm_wday + 1); - s->cmos_data[RTC_DAY_OF_MONTH] = to_bcd(s, tm->tm_mday); - s->cmos_data[RTC_MONTH] = to_bcd(s, tm->tm_mon + 1); + s->cmos_data[RTC_DAY_OF_WEEK] = rtc_to_bcd(s, tm->tm_wday + 1); + s->cmos_data[RTC_DAY_OF_MONTH] = rtc_to_bcd(s, tm->tm_mday); + s->cmos_data[RTC_MONTH] = rtc_to_bcd(s, tm->tm_mon + 1); year = (tm->tm_year - s->base_year) % 100; if (year < 0) year += 100; - s->cmos_data[RTC_YEAR] = to_bcd(s, year); + s->cmos_data[RTC_YEAR] = rtc_to_bcd(s, year); } /* month is between 0 and 11. */ @@ -497,7 +497,7 @@ static void rtc_set_date_from_host(RTCState *s) qemu_get_timedate(&tm, 0); rtc_set_date(s, &tm); - val = to_bcd(s, (tm.tm_year / 100) + 19); + val = rtc_to_bcd(s, (tm.tm_year / 100) + 19); rtc_set_memory(s, REG_IBM_CENTURY_BYTE, val); rtc_set_memory(s, REG_IBM_PS2_CENTURY_BYTE, val); } diff --git a/hw/omap1.c b/hw/omap1.c index e9676ecc88..b5d78cd917 100644 --- a/hw/omap1.c +++ b/hw/omap1.c @@ -3358,16 +3358,6 @@ static void omap_rtc_alarm_update(struct omap_rtc_s *s) printf("%s: conversion failed\n", __FUNCTION__); } -static inline uint8_t omap_rtc_bcd(int num) -{ - return ((num / 10) << 4) | (num % 10); -} - -static inline int omap_rtc_bin(uint8_t num) -{ - return (num & 15) + 10 * (num >> 4); -} - static uint32_t omap_rtc_read(void *opaque, target_phys_addr_t addr) { struct omap_rtc_s *s = (struct omap_rtc_s *) opaque; @@ -3376,51 +3366,51 @@ static uint32_t omap_rtc_read(void *opaque, target_phys_addr_t addr) switch (offset) { case 0x00: /* SECONDS_REG */ - return omap_rtc_bcd(s->current_tm.tm_sec); + return to_bcd(s->current_tm.tm_sec); case 0x04: /* MINUTES_REG */ - return omap_rtc_bcd(s->current_tm.tm_min); + return to_bcd(s->current_tm.tm_min); case 0x08: /* HOURS_REG */ if (s->pm_am) return ((s->current_tm.tm_hour > 11) << 7) | - omap_rtc_bcd(((s->current_tm.tm_hour - 1) % 12) + 1); + to_bcd(((s->current_tm.tm_hour - 1) % 12) + 1); else - return omap_rtc_bcd(s->current_tm.tm_hour); + return to_bcd(s->current_tm.tm_hour); case 0x0c: /* DAYS_REG */ - return omap_rtc_bcd(s->current_tm.tm_mday); + return to_bcd(s->current_tm.tm_mday); case 0x10: /* MONTHS_REG */ - return omap_rtc_bcd(s->current_tm.tm_mon + 1); + return to_bcd(s->current_tm.tm_mon + 1); case 0x14: /* YEARS_REG */ - return omap_rtc_bcd(s->current_tm.tm_year % 100); + return to_bcd(s->current_tm.tm_year % 100); case 0x18: /* WEEK_REG */ return s->current_tm.tm_wday; case 0x20: /* ALARM_SECONDS_REG */ - return omap_rtc_bcd(s->alarm_tm.tm_sec); + return to_bcd(s->alarm_tm.tm_sec); case 0x24: /* ALARM_MINUTES_REG */ - return omap_rtc_bcd(s->alarm_tm.tm_min); + return to_bcd(s->alarm_tm.tm_min); case 0x28: /* ALARM_HOURS_REG */ if (s->pm_am) return ((s->alarm_tm.tm_hour > 11) << 7) | - omap_rtc_bcd(((s->alarm_tm.tm_hour - 1) % 12) + 1); + to_bcd(((s->alarm_tm.tm_hour - 1) % 12) + 1); else - return omap_rtc_bcd(s->alarm_tm.tm_hour); + return to_bcd(s->alarm_tm.tm_hour); case 0x2c: /* ALARM_DAYS_REG */ - return omap_rtc_bcd(s->alarm_tm.tm_mday); + return to_bcd(s->alarm_tm.tm_mday); case 0x30: /* ALARM_MONTHS_REG */ - return omap_rtc_bcd(s->alarm_tm.tm_mon + 1); + return to_bcd(s->alarm_tm.tm_mon + 1); case 0x34: /* ALARM_YEARS_REG */ - return omap_rtc_bcd(s->alarm_tm.tm_year % 100); + return to_bcd(s->alarm_tm.tm_year % 100); case 0x40: /* RTC_CTRL_REG */ return (s->pm_am << 3) | (s->auto_comp << 2) | @@ -3459,7 +3449,7 @@ static void omap_rtc_write(void *opaque, target_phys_addr_t addr, printf("RTC SEC_REG <-- %02x\n", value); #endif s->ti -= s->current_tm.tm_sec; - s->ti += omap_rtc_bin(value); + s->ti += from_bcd(value); return; case 0x04: /* MINUTES_REG */ @@ -3467,7 +3457,7 @@ static void omap_rtc_write(void *opaque, target_phys_addr_t addr, printf("RTC MIN_REG <-- %02x\n", value); #endif s->ti -= s->current_tm.tm_min * 60; - s->ti += omap_rtc_bin(value) * 60; + s->ti += from_bcd(value) * 60; return; case 0x08: /* HOURS_REG */ @@ -3476,10 +3466,10 @@ static void omap_rtc_write(void *opaque, target_phys_addr_t addr, #endif s->ti -= s->current_tm.tm_hour * 3600; if (s->pm_am) { - s->ti += (omap_rtc_bin(value & 0x3f) & 12) * 3600; + s->ti += (from_bcd(value & 0x3f) & 12) * 3600; s->ti += ((value >> 7) & 1) * 43200; } else - s->ti += omap_rtc_bin(value & 0x3f) * 3600; + s->ti += from_bcd(value & 0x3f) * 3600; return; case 0x0c: /* DAYS_REG */ @@ -3487,7 +3477,7 @@ static void omap_rtc_write(void *opaque, target_phys_addr_t addr, printf("RTC DAY_REG <-- %02x\n", value); #endif s->ti -= s->current_tm.tm_mday * 86400; - s->ti += omap_rtc_bin(value) * 86400; + s->ti += from_bcd(value) * 86400; return; case 0x10: /* MONTHS_REG */ @@ -3495,7 +3485,7 @@ static void omap_rtc_write(void *opaque, target_phys_addr_t addr, printf("RTC MTH_REG <-- %02x\n", value); #endif memcpy(&new_tm, &s->current_tm, sizeof(new_tm)); - new_tm.tm_mon = omap_rtc_bin(value); + new_tm.tm_mon = from_bcd(value); ti[0] = mktimegm(&s->current_tm); ti[1] = mktimegm(&new_tm); @@ -3505,7 +3495,7 @@ static void omap_rtc_write(void *opaque, target_phys_addr_t addr, } else { /* A less accurate version */ s->ti -= s->current_tm.tm_mon * 2592000; - s->ti += omap_rtc_bin(value) * 2592000; + s->ti += from_bcd(value) * 2592000; } return; @@ -3514,7 +3504,7 @@ static void omap_rtc_write(void *opaque, target_phys_addr_t addr, printf("RTC YRS_REG <-- %02x\n", value); #endif memcpy(&new_tm, &s->current_tm, sizeof(new_tm)); - new_tm.tm_year += omap_rtc_bin(value) - (new_tm.tm_year % 100); + new_tm.tm_year += from_bcd(value) - (new_tm.tm_year % 100); ti[0] = mktimegm(&s->current_tm); ti[1] = mktimegm(&new_tm); @@ -3524,7 +3514,7 @@ static void omap_rtc_write(void *opaque, target_phys_addr_t addr, } else { /* A less accurate version */ s->ti -= (s->current_tm.tm_year % 100) * 31536000; - s->ti += omap_rtc_bin(value) * 31536000; + s->ti += from_bcd(value) * 31536000; } return; @@ -3535,7 +3525,7 @@ static void omap_rtc_write(void *opaque, target_phys_addr_t addr, #ifdef ALMDEBUG printf("ALM SEC_REG <-- %02x\n", value); #endif - s->alarm_tm.tm_sec = omap_rtc_bin(value); + s->alarm_tm.tm_sec = from_bcd(value); omap_rtc_alarm_update(s); return; @@ -3543,7 +3533,7 @@ static void omap_rtc_write(void *opaque, target_phys_addr_t addr, #ifdef ALMDEBUG printf("ALM MIN_REG <-- %02x\n", value); #endif - s->alarm_tm.tm_min = omap_rtc_bin(value); + s->alarm_tm.tm_min = from_bcd(value); omap_rtc_alarm_update(s); return; @@ -3553,10 +3543,10 @@ static void omap_rtc_write(void *opaque, target_phys_addr_t addr, #endif if (s->pm_am) s->alarm_tm.tm_hour = - ((omap_rtc_bin(value & 0x3f)) % 12) + + ((from_bcd(value & 0x3f)) % 12) + ((value >> 7) & 1) * 12; else - s->alarm_tm.tm_hour = omap_rtc_bin(value); + s->alarm_tm.tm_hour = from_bcd(value); omap_rtc_alarm_update(s); return; @@ -3564,7 +3554,7 @@ static void omap_rtc_write(void *opaque, target_phys_addr_t addr, #ifdef ALMDEBUG printf("ALM DAY_REG <-- %02x\n", value); #endif - s->alarm_tm.tm_mday = omap_rtc_bin(value); + s->alarm_tm.tm_mday = from_bcd(value); omap_rtc_alarm_update(s); return; @@ -3572,7 +3562,7 @@ static void omap_rtc_write(void *opaque, target_phys_addr_t addr, #ifdef ALMDEBUG printf("ALM MON_REG <-- %02x\n", value); #endif - s->alarm_tm.tm_mon = omap_rtc_bin(value); + s->alarm_tm.tm_mon = from_bcd(value); omap_rtc_alarm_update(s); return; @@ -3580,7 +3570,7 @@ static void omap_rtc_write(void *opaque, target_phys_addr_t addr, #ifdef ALMDEBUG printf("ALM YRS_REG <-- %02x\n", value); #endif - s->alarm_tm.tm_year = omap_rtc_bin(value); + s->alarm_tm.tm_year = from_bcd(value); omap_rtc_alarm_update(s); return; diff --git a/hw/twl92230.c b/hw/twl92230.c index a6c60ba2b8..93232da2d5 100644 --- a/hw/twl92230.c +++ b/hw/twl92230.c @@ -183,16 +183,6 @@ static void menelaus_reset(i2c_slave *i2c) menelaus_update(s); } -static inline uint8_t to_bcd(int val) -{ - return ((val / 10) << 4) | (val % 10); -} - -static inline int from_bcd(uint8_t val) -{ - return ((val >> 4) * 10) + (val & 0x0f); -} - static void menelaus_gpio_set(void *opaque, int line, int level) { MenelausState *s = (MenelausState *) opaque; diff --git a/qemu-common.h b/qemu-common.h index b779cfe69d..b1e038bd00 100644 --- a/qemu-common.h +++ b/qemu-common.h @@ -248,6 +248,17 @@ void qemu_iovec_from_buffer(QEMUIOVector *qiov, const void *buf, size_t count); struct Monitor; typedef struct Monitor Monitor; +/* Convert a byte between binary and BCD. */ +static inline uint8_t to_bcd(uint8_t val) +{ + return ((val / 10) << 4) | (val % 10); +} + +static inline uint8_t from_bcd(uint8_t val) +{ + return ((val >> 4) * 10) + (val & 0x0f); +} + #include "module.h" #endif /* dyngen-exec.h hack */ -- 2.11.0