コード例 #1
0
ファイル: mc146818rtc.c プロジェクト: junbo-hu/xen-4.5.0
static void rtc_update_timer(void *opaque)
{
    RTCState *s = opaque;
    int32_t irqs = REG_C_UF;
    int32_t new_irqs;

    assert((s->cmos_data[RTC_REG_A] & 0x60) != 0x60);

    /* UIP might have been latched, update time and clear it.  */
    rtc_update_time(s);
    s->cmos_data[RTC_REG_A] &= ~REG_A_UIP;

    if (qemu_clock_get_ns(rtc_clock) >= s->next_alarm_time) {
        irqs |= REG_C_AF;
        if (s->cmos_data[RTC_REG_B] & REG_B_AIE) {
            qemu_system_wakeup_request(QEMU_WAKEUP_REASON_RTC);
        }
    }

    new_irqs = irqs & ~s->cmos_data[RTC_REG_C];
    s->cmos_data[RTC_REG_C] |= irqs;
    if ((new_irqs & s->cmos_data[RTC_REG_B]) != 0) {
        s->cmos_data[RTC_REG_C] |= REG_C_IRQF;
        qemu_irq_raise(s->irq);
    }
    check_update_timer(s);
}
コード例 #2
0
ファイル: mc146818rtc.c プロジェクト: 01org/KVMGT-qemu
static void rtc_get_date(Object *obj, Visitor *v, void *opaque,
                         const char *name, Error **errp)
{
    RTCState *s = MC146818_RTC(obj);
    struct tm current_tm;

    rtc_update_time(s);
    rtc_get_time(s, &current_tm);
    visit_start_struct(v, NULL, "struct tm", name, 0, errp);
    visit_type_int32(v, &current_tm.tm_year, "tm_year", errp);
    visit_type_int32(v, &current_tm.tm_mon, "tm_mon", errp);
    visit_type_int32(v, &current_tm.tm_mday, "tm_mday", errp);
    visit_type_int32(v, &current_tm.tm_hour, "tm_hour", errp);
    visit_type_int32(v, &current_tm.tm_min, "tm_min", errp);
    visit_type_int32(v, &current_tm.tm_sec, "tm_sec", errp);
    visit_end_struct(v, errp);
}
コード例 #3
0
ファイル: mc146818rtc.c プロジェクト: CrazyXen/XEN_CODE
static void rtc_get_date(Object *obj, Visitor *v, void *opaque,
                         const char *name, Error **errp)
{
    ISADevice *isa = ISA_DEVICE(obj);
    RTCState *s = DO_UPCAST(RTCState, dev, isa);
    struct tm current_tm;

    rtc_update_time(s);
    rtc_get_time(s, &current_tm);
    visit_start_struct(v, NULL, "struct tm", name, 0, errp);
    visit_type_int32(v, &current_tm.tm_year, "tm_year", errp);
    visit_type_int32(v, &current_tm.tm_mon, "tm_mon", errp);
    visit_type_int32(v, &current_tm.tm_mday, "tm_mday", errp);
    visit_type_int32(v, &current_tm.tm_hour, "tm_hour", errp);
    visit_type_int32(v, &current_tm.tm_min, "tm_min", errp);
    visit_type_int32(v, &current_tm.tm_sec, "tm_sec", errp);
    visit_end_struct(v, errp);
}
コード例 #4
0
ファイル: mc146818rtc.c プロジェクト: dmarion/qemu
static void rtc_get_date(Object *obj, Visitor *v, void *opaque,
                         const char *name, Error **errp)
{
    Error *err = NULL;
    RTCState *s = MC146818_RTC(obj);
    struct tm current_tm;

    rtc_update_time(s);
    rtc_get_time(s, &current_tm);
    visit_start_struct(v, NULL, "struct tm", name, 0, &err);
    if (err) {
        goto out;
    }
    visit_type_int32(v, &current_tm.tm_year, "tm_year", &err);
    if (err) {
        goto out_end;
    }
    visit_type_int32(v, &current_tm.tm_mon, "tm_mon", &err);
    if (err) {
        goto out_end;
    }
    visit_type_int32(v, &current_tm.tm_mday, "tm_mday", &err);
    if (err) {
        goto out_end;
    }
    visit_type_int32(v, &current_tm.tm_hour, "tm_hour", &err);
    if (err) {
        goto out_end;
    }
    visit_type_int32(v, &current_tm.tm_min, "tm_min", &err);
    if (err) {
        goto out_end;
    }
    visit_type_int32(v, &current_tm.tm_sec, "tm_sec", &err);
    if (err) {
        goto out_end;
    }
out_end:
    error_propagate(errp, err);
    err = NULL;
    visit_end_struct(v, errp);
out:
    error_propagate(errp, err);
}
コード例 #5
0
ファイル: sms.c プロジェクト: sergioamr/vaccinemonitoring
// Send back data after an SMS request
void sms_send_data_request(char *number) {
	uint32_t iOffset;
	char *data = getSMSBufferHelper();

	if (number == NULL || strlen(number) == 0)
		return;

	//get temperature values
	rtc_update_time();
	strcat(data, get_simplified_date_string(&g_tmCurrTime));
	strcat(data, " ");
	for (iOffset = 0; iOffset < SYSTEM_NUM_SENSORS; iOffset++) {
		strcat(data, SensorName[iOffset]);
		strcat(data, ":");
		strcat(data, temperature_getString(iOffset));
		strcat(data, "C, ");
	}

	// added for show msg//
	strcat(data, "BATTERY:");
	strcat(data, itoa_nopadding(batt_getlevel()));
	strcat(data, "%, ");
	if (P4IN & BIT4)	//power not plugged
	{
		strcat(data, "POWER OUT");
	} else if (((P4IN & BIT6)) && (batt_getlevel() == 100)) {
		strcat(data, "FULL CHARGE");
	} else {
		strcat(data, "CHARGING");
	}

#ifdef _DEBUG
	strcat(data, ",UPTIME:");
	strcat(data, itoa_nopadding(iMinuteTick));
	strcat(data, ",STACK:");
	strcat(data, itoa_nopadding(g_pSysCfg->stackLeft));
#endif

	iOffset = strlen(data);
	sms_send_message_number(number, data);
}
コード例 #6
0
ファイル: mc146818rtc.c プロジェクト: 01org/KVMGT-qemu
static uint64_t cmos_ioport_read(void *opaque, hwaddr addr,
                                 unsigned size)
{
    RTCState *s = opaque;
    int ret;
    if ((addr & 1) == 0) {
        return 0xff;
    } else {
        switch(s->cmos_index) {
	case RTC_IBM_PS2_CENTURY_BYTE:
            s->cmos_index = RTC_CENTURY;
            /* fall through */
        case RTC_CENTURY:
        case RTC_SECONDS:
        case RTC_MINUTES:
        case RTC_HOURS:
        case RTC_DAY_OF_WEEK:
        case RTC_DAY_OF_MONTH:
        case RTC_MONTH:
        case RTC_YEAR:
            /* if not in set mode, calibrate cmos before
             * reading*/
            if (rtc_running(s)) {
                rtc_update_time(s);
            }
            ret = s->cmos_data[s->cmos_index];
            break;
        case RTC_REG_A:
            if (update_in_progress(s)) {
                s->cmos_data[s->cmos_index] |= REG_A_UIP;
            } else {
                s->cmos_data[s->cmos_index] &= ~REG_A_UIP;
            }
            ret = s->cmos_data[s->cmos_index];
            break;
        case RTC_REG_C:
            ret = s->cmos_data[s->cmos_index];
            qemu_irq_lower(s->irq);
            s->cmos_data[RTC_REG_C] = 0x00;
            if (ret & (REG_C_UF | REG_C_AF)) {
                check_update_timer(s);
            }
#ifdef TARGET_I386
            if(s->irq_coalesced &&
                    (s->cmos_data[RTC_REG_B] & REG_B_PIE) &&
                    s->irq_reinject_on_ack_count < RTC_REINJECT_ON_ACK_COUNT) {
                s->irq_reinject_on_ack_count++;
                s->cmos_data[RTC_REG_C] |= REG_C_IRQF | REG_C_PF;
                apic_reset_irq_delivered();
                DPRINTF_C("cmos: injecting on ack\n");
                qemu_irq_raise(s->irq);
                if (apic_get_irq_delivered()) {
                    s->irq_coalesced--;
                    DPRINTF_C("cmos: coalesced irqs decreased to %d\n",
                              s->irq_coalesced);
                }
            }
#endif
            break;
        default:
            ret = s->cmos_data[s->cmos_index];
            break;
        }
        CMOS_DPRINTF("cmos: read index=0x%02x val=0x%02x\n",
                     s->cmos_index, ret);
        return ret;
    }
}
コード例 #7
0
ファイル: mc146818rtc.c プロジェクト: 01org/KVMGT-qemu
static void cmos_ioport_write(void *opaque, hwaddr addr,
                              uint64_t data, unsigned size)
{
    RTCState *s = opaque;

    if ((addr & 1) == 0) {
        s->cmos_index = data & 0x7f;
    } else {
        CMOS_DPRINTF("cmos: write index=0x%02x val=0x%02x\n",
                     s->cmos_index, data);
        switch(s->cmos_index) {
        case RTC_SECONDS_ALARM:
        case RTC_MINUTES_ALARM:
        case RTC_HOURS_ALARM:
            s->cmos_data[s->cmos_index] = data;
            check_update_timer(s);
            break;
	case RTC_IBM_PS2_CENTURY_BYTE:
            s->cmos_index = RTC_CENTURY;
            /* fall through */
        case RTC_CENTURY:
        case RTC_SECONDS:
        case RTC_MINUTES:
        case RTC_HOURS:
        case RTC_DAY_OF_WEEK:
        case RTC_DAY_OF_MONTH:
        case RTC_MONTH:
        case RTC_YEAR:
            s->cmos_data[s->cmos_index] = data;
            /* if in set mode, do not update the time */
            if (rtc_running(s)) {
                rtc_set_time(s);
                check_update_timer(s);
            }
            break;
        case RTC_REG_A:
            if ((data & 0x60) == 0x60) {
                if (rtc_running(s)) {
                    rtc_update_time(s);
                }
                /* What happens to UIP when divider reset is enabled is
                 * unclear from the datasheet.  Shouldn't matter much
                 * though.
                 */
                s->cmos_data[RTC_REG_A] &= ~REG_A_UIP;
            } else if (((s->cmos_data[RTC_REG_A] & 0x60) == 0x60) &&
                    (data & 0x70)  <= 0x20) {
                /* when the divider reset is removed, the first update cycle
                 * begins one-half second later*/
                if (!(s->cmos_data[RTC_REG_B] & REG_B_SET)) {
                    s->offset = 500000000;
                    rtc_set_time(s);
                }
                s->cmos_data[RTC_REG_A] &= ~REG_A_UIP;
            }
            /* UIP bit is read only */
            s->cmos_data[RTC_REG_A] = (data & ~REG_A_UIP) |
                (s->cmos_data[RTC_REG_A] & REG_A_UIP);
            periodic_timer_update(s, qemu_get_clock_ns(rtc_clock));
            check_update_timer(s);
            break;
        case RTC_REG_B:
            if (data & REG_B_SET) {
                /* update cmos to when the rtc was stopping */
                if (rtc_running(s)) {
                    rtc_update_time(s);
                }
                /* set mode: reset UIP mode */
                s->cmos_data[RTC_REG_A] &= ~REG_A_UIP;
                data &= ~REG_B_UIE;
            } else {
                /* if disabling set mode, update the time */
                if ((s->cmos_data[RTC_REG_B] & REG_B_SET) &&
                    (s->cmos_data[RTC_REG_A] & 0x70) <= 0x20) {
                    s->offset = get_guest_rtc_ns(s) % NSEC_PER_SEC;
                    rtc_set_time(s);
                }
            }
            /* if an interrupt flag is already set when the interrupt
             * becomes enabled, raise an interrupt immediately.  */
            if (data & s->cmos_data[RTC_REG_C] & REG_C_MASK) {
                s->cmos_data[RTC_REG_C] |= REG_C_IRQF;
                qemu_irq_raise(s->irq);
            } else {
                s->cmos_data[RTC_REG_C] &= ~REG_C_IRQF;
                qemu_irq_lower(s->irq);
            }
            s->cmos_data[RTC_REG_B] = data;
            periodic_timer_update(s, qemu_get_clock_ns(rtc_clock));
            check_update_timer(s);
            break;
        case RTC_REG_C:
        case RTC_REG_D:
            /* cannot write to them */
            break;
        default:
            s->cmos_data[s->cmos_index] = data;
            break;
        }
    }
}
コード例 #8
0
ファイル: mc146818rtc.c プロジェクト: 01org/KVMGT-qemu
static uint64_t get_next_alarm(RTCState *s)
{
    int32_t alarm_sec, alarm_min, alarm_hour, cur_hour, cur_min, cur_sec;
    int32_t hour, min, sec;

    rtc_update_time(s);

    alarm_sec = rtc_from_bcd(s, s->cmos_data[RTC_SECONDS_ALARM]);
    alarm_min = rtc_from_bcd(s, s->cmos_data[RTC_MINUTES_ALARM]);
    alarm_hour = rtc_from_bcd(s, s->cmos_data[RTC_HOURS_ALARM]);
    alarm_hour = alarm_hour == -1 ? -1 : convert_hour(s, alarm_hour);

    cur_sec = rtc_from_bcd(s, s->cmos_data[RTC_SECONDS]);
    cur_min = rtc_from_bcd(s, s->cmos_data[RTC_MINUTES]);
    cur_hour = rtc_from_bcd(s, s->cmos_data[RTC_HOURS]);
    cur_hour = convert_hour(s, cur_hour);

    if (alarm_hour == -1) {
        alarm_hour = cur_hour;
        if (alarm_min == -1) {
            alarm_min = cur_min;
            if (alarm_sec == -1) {
                alarm_sec = cur_sec + 1;
            } else if (cur_sec > alarm_sec) {
                alarm_min++;
            }
        } else if (cur_min == alarm_min) {
            if (alarm_sec == -1) {
                alarm_sec = cur_sec + 1;
            } else {
                if (cur_sec > alarm_sec) {
                    alarm_hour++;
                }
            }
            if (alarm_sec == SEC_PER_MIN) {
                /* wrap to next hour, minutes is not in don't care mode */
                alarm_sec = 0;
                alarm_hour++;
            }
        } else if (cur_min > alarm_min) {
            alarm_hour++;
        }
    } else if (cur_hour == alarm_hour) {
        if (alarm_min == -1) {
            alarm_min = cur_min;
            if (alarm_sec == -1) {
                alarm_sec = cur_sec + 1;
            } else if (cur_sec > alarm_sec) {
                alarm_min++;
            }

            if (alarm_sec == SEC_PER_MIN) {
                alarm_sec = 0;
                alarm_min++;
            }
            /* wrap to next day, hour is not in don't care mode */
            alarm_min %= MIN_PER_HOUR;
        } else if (cur_min == alarm_min) {
            if (alarm_sec == -1) {
                alarm_sec = cur_sec + 1;
            }
            /* wrap to next day, hours+minutes not in don't care mode */
            alarm_sec %= SEC_PER_MIN;
        }
    }

    /* values that are still don't care fire at the next min/sec */
    if (alarm_min == -1) {
        alarm_min = 0;
    }
    if (alarm_sec == -1) {
        alarm_sec = 0;
    }

    /* keep values in range */
    if (alarm_sec == SEC_PER_MIN) {
        alarm_sec = 0;
        alarm_min++;
    }
    if (alarm_min == MIN_PER_HOUR) {
        alarm_min = 0;
        alarm_hour++;
    }
    alarm_hour %= HOUR_PER_DAY;

    hour = alarm_hour - cur_hour;
    min = hour * MIN_PER_HOUR + alarm_min - cur_min;
    sec = min * SEC_PER_MIN + alarm_sec - cur_sec;
    return sec <= 0 ? sec + SEC_PER_DAY : sec;
}