Changeset View
Changeset View
Standalone View
Standalone View
sys/amd64/vmm/io/vrtc.c
Show First 20 Lines • Show All 838 Lines • ▼ Show 20 Lines | vrtc_nvram_read(struct vm *vm, int offset, uint8_t *retval) | ||||
ptr = (uint8_t *)(&vrtc->rtcdev); | ptr = (uint8_t *)(&vrtc->rtcdev); | ||||
*retval = ptr[offset]; | *retval = ptr[offset]; | ||||
VRTC_UNLOCK(vrtc); | VRTC_UNLOCK(vrtc); | ||||
return (0); | return (0); | ||||
} | } | ||||
int | int | ||||
vrtc_addr_handler(struct vm *vm, int vcpuid, bool in, int port, int bytes, | vrtc_addr_handler(struct vm *vm, bool in, int port, int bytes, uint32_t *val) | ||||
uint32_t *val) | |||||
{ | { | ||||
struct vrtc *vrtc; | struct vrtc *vrtc; | ||||
vrtc = vm_rtc(vm); | vrtc = vm_rtc(vm); | ||||
if (bytes != 1) | if (bytes != 1) | ||||
return (-1); | return (-1); | ||||
if (in) { | if (in) { | ||||
*val = 0xff; | *val = 0xff; | ||||
return (0); | return (0); | ||||
} | } | ||||
VRTC_LOCK(vrtc); | VRTC_LOCK(vrtc); | ||||
vrtc->addr = *val & 0x7f; | vrtc->addr = *val & 0x7f; | ||||
VRTC_UNLOCK(vrtc); | VRTC_UNLOCK(vrtc); | ||||
return (0); | return (0); | ||||
} | } | ||||
int | int | ||||
vrtc_data_handler(struct vm *vm, int vcpuid, bool in, int port, int bytes, | vrtc_data_handler(struct vm *vm, bool in, int port, int bytes, uint32_t *val) | ||||
uint32_t *val) | |||||
{ | { | ||||
struct vrtc *vrtc; | struct vrtc *vrtc; | ||||
struct rtcdev *rtc; | struct rtcdev *rtc; | ||||
sbintime_t basetime; | sbintime_t basetime; | ||||
time_t curtime; | time_t curtime; | ||||
int error, offset; | int error, offset; | ||||
vrtc = vm_rtc(vm); | vrtc = vm_rtc(vm); | ||||
Show All 30 Lines | if (offset == 12) { | ||||
* reg_c interrupt flags are updated only if the | * reg_c interrupt flags are updated only if the | ||||
* corresponding interrupt enable bit in reg_b is set. | * corresponding interrupt enable bit in reg_b is set. | ||||
*/ | */ | ||||
*val = vrtc->rtcdev.reg_c; | *val = vrtc->rtcdev.reg_c; | ||||
vrtc_set_reg_c(vrtc, 0); | vrtc_set_reg_c(vrtc, 0); | ||||
} else { | } else { | ||||
*val = *((uint8_t *)rtc + offset); | *val = *((uint8_t *)rtc + offset); | ||||
} | } | ||||
VCPU_CTR2(vm, vcpuid, "Read value %#x from RTC offset %#x", | VM_CTR2(vm, "Read value %#x from RTC offset %#x", | ||||
*val, offset); | *val, offset); | ||||
} else { | } else { | ||||
switch (offset) { | switch (offset) { | ||||
case 10: | case 10: | ||||
VCPU_CTR1(vm, vcpuid, "RTC reg_a set to %#x", *val); | VM_CTR1(vm, "RTC reg_a set to %#x", *val); | ||||
vrtc_set_reg_a(vrtc, *val); | vrtc_set_reg_a(vrtc, *val); | ||||
break; | break; | ||||
case 11: | case 11: | ||||
VCPU_CTR1(vm, vcpuid, "RTC reg_b set to %#x", *val); | VM_CTR1(vm, "RTC reg_b set to %#x", *val); | ||||
error = vrtc_set_reg_b(vrtc, *val); | error = vrtc_set_reg_b(vrtc, *val); | ||||
break; | break; | ||||
case 12: | case 12: | ||||
VCPU_CTR1(vm, vcpuid, "RTC reg_c set to %#x (ignored)", | VM_CTR1(vm, "RTC reg_c set to %#x (ignored)", | ||||
*val); | *val); | ||||
break; | break; | ||||
case 13: | case 13: | ||||
VCPU_CTR1(vm, vcpuid, "RTC reg_d set to %#x (ignored)", | VM_CTR1(vm, "RTC reg_d set to %#x (ignored)", | ||||
*val); | *val); | ||||
break; | break; | ||||
case 0: | case 0: | ||||
/* | /* | ||||
* High order bit of 'seconds' is readonly. | * High order bit of 'seconds' is readonly. | ||||
*/ | */ | ||||
*val &= 0x7f; | *val &= 0x7f; | ||||
/* FALLTHRU */ | /* FALLTHRU */ | ||||
default: | default: | ||||
VCPU_CTR2(vm, vcpuid, "RTC offset %#x set to %#x", | VM_CTR2(vm, "RTC offset %#x set to %#x", | ||||
offset, *val); | offset, *val); | ||||
*((uint8_t *)rtc + offset) = *val; | *((uint8_t *)rtc + offset) = *val; | ||||
break; | break; | ||||
} | } | ||||
/* | /* | ||||
* XXX some guests (e.g. OpenBSD) write the century byte | * XXX some guests (e.g. OpenBSD) write the century byte | ||||
* outside of RTCSB_HALT so re-calculate the RTC date/time. | * outside of RTCSB_HALT so re-calculate the RTC date/time. | ||||
▲ Show 20 Lines • Show All 113 Lines • Show Last 20 Lines |