[34] | 1 | Index: ioemu/hw/mc146818rtc.c |
---|
| 2 | =================================================================== |
---|
| 3 | --- ioemu.orig/hw/mc146818rtc.c 2007-05-03 15:38:35.000000000 +0100 |
---|
| 4 | +++ ioemu/hw/mc146818rtc.c 2007-05-03 15:38:45.000000000 +0100 |
---|
| 5 | @@ -178,10 +178,27 @@ |
---|
| 6 | } |
---|
| 7 | } |
---|
| 8 | |
---|
| 9 | +static void send_timeoffset_msg(time_t delta) |
---|
| 10 | +{ |
---|
| 11 | + |
---|
| 12 | +/* This routine is used to inform another entity that the |
---|
| 13 | + base time offset has changed. For instance, if you |
---|
| 14 | + were using xenstore, you might want to write to the store |
---|
| 15 | + at this point. Or, you might use some other method. |
---|
| 16 | + Whatever you might choose, here's a hook point to implement it. |
---|
| 17 | + |
---|
| 18 | + One item of note is that this delta is in addition to |
---|
| 19 | + any existing offset you might be already using. */ |
---|
| 20 | + |
---|
| 21 | + return; |
---|
| 22 | +} |
---|
| 23 | + |
---|
| 24 | static void rtc_set_time(RTCState *s) |
---|
| 25 | { |
---|
| 26 | struct tm *tm = &s->current_tm; |
---|
| 27 | - |
---|
| 28 | + time_t before, after; |
---|
| 29 | + |
---|
| 30 | + before = mktime(tm); |
---|
| 31 | tm->tm_sec = from_bcd(s, s->cmos_data[RTC_SECONDS]); |
---|
| 32 | tm->tm_min = from_bcd(s, s->cmos_data[RTC_MINUTES]); |
---|
| 33 | tm->tm_hour = from_bcd(s, s->cmos_data[RTC_HOURS] & 0x7f); |
---|
| 34 | @@ -193,6 +210,12 @@ |
---|
| 35 | tm->tm_mday = from_bcd(s, s->cmos_data[RTC_DAY_OF_MONTH]); |
---|
| 36 | tm->tm_mon = from_bcd(s, s->cmos_data[RTC_MONTH]) - 1; |
---|
| 37 | tm->tm_year = from_bcd(s, s->cmos_data[RTC_YEAR]) + 100; |
---|
| 38 | + |
---|
| 39 | + /* Compute, and send, the additional time delta |
---|
| 40 | + We could compute the total time delta, but this is |
---|
| 41 | + sufficient, and simple. */ |
---|
| 42 | + after = mktime(tm); |
---|
| 43 | + send_timeoffset_msg(after-before); |
---|
| 44 | } |
---|
| 45 | |
---|
| 46 | static void rtc_copy_date(RTCState *s) |
---|
| 47 | Index: ioemu/hw/pc.c |
---|
| 48 | =================================================================== |
---|
| 49 | --- ioemu.orig/hw/pc.c 2007-05-03 15:38:44.000000000 +0100 |
---|
| 50 | +++ ioemu/hw/pc.c 2007-05-03 15:38:45.000000000 +0100 |
---|
| 51 | @@ -159,7 +159,7 @@ |
---|
| 52 | } |
---|
| 53 | |
---|
| 54 | /* hd_table must contain 4 block drivers */ |
---|
| 55 | -static void cmos_init(uint64_t ram_size, int boot_device, BlockDriverState **hd_table) |
---|
| 56 | +static void cmos_init(uint64_t ram_size, int boot_device, BlockDriverState **hd_table, time_t timeoffset) |
---|
| 57 | { |
---|
| 58 | RTCState *s = rtc_state; |
---|
| 59 | int val; |
---|
| 60 | @@ -170,6 +170,7 @@ |
---|
| 61 | |
---|
| 62 | /* set the CMOS date */ |
---|
| 63 | time(&ti); |
---|
| 64 | + ti += timeoffset; |
---|
| 65 | if (rtc_utc) |
---|
| 66 | tm = gmtime(&ti); |
---|
| 67 | else |
---|
| 68 | @@ -619,7 +620,7 @@ |
---|
| 69 | static void pc_init1(uint64_t ram_size, int vga_ram_size, int boot_device, |
---|
| 70 | DisplayState *ds, const char **fd_filename, int snapshot, |
---|
| 71 | const char *kernel_filename, const char *kernel_cmdline, |
---|
| 72 | - const char *initrd_filename, |
---|
| 73 | + const char *initrd_filename, time_t timeoffset, |
---|
| 74 | int pci_enabled) |
---|
| 75 | { |
---|
| 76 | #ifndef NOBIOS |
---|
| 77 | @@ -871,7 +872,7 @@ |
---|
| 78 | |
---|
| 79 | floppy_controller = fdctrl_init(6, 2, 0, 0x3f0, fd_table); |
---|
| 80 | |
---|
| 81 | - cmos_init(ram_size, boot_device, bs_table); |
---|
| 82 | + cmos_init(ram_size, boot_device, bs_table, timeoffset); |
---|
| 83 | |
---|
| 84 | /* using PIIX4 acpi model */ |
---|
| 85 | if (pci_enabled && acpi_enabled) |
---|
| 86 | @@ -920,12 +921,13 @@ |
---|
| 87 | int snapshot, |
---|
| 88 | const char *kernel_filename, |
---|
| 89 | const char *kernel_cmdline, |
---|
| 90 | - const char *initrd_filename) |
---|
| 91 | + const char *initrd_filename, |
---|
| 92 | + time_t timeoffset) |
---|
| 93 | { |
---|
| 94 | pc_init1(ram_size, vga_ram_size, boot_device, |
---|
| 95 | ds, fd_filename, snapshot, |
---|
| 96 | kernel_filename, kernel_cmdline, |
---|
| 97 | - initrd_filename, 1); |
---|
| 98 | + initrd_filename, timeoffset, 1); |
---|
| 99 | } |
---|
| 100 | |
---|
| 101 | static void pc_init_isa(uint64_t ram_size, int vga_ram_size, int boot_device, |
---|
| 102 | @@ -933,12 +935,13 @@ |
---|
| 103 | int snapshot, |
---|
| 104 | const char *kernel_filename, |
---|
| 105 | const char *kernel_cmdline, |
---|
| 106 | - const char *initrd_filename) |
---|
| 107 | + const char *initrd_filename, |
---|
| 108 | + time_t timeoffset) |
---|
| 109 | { |
---|
| 110 | pc_init1(ram_size, vga_ram_size, boot_device, |
---|
| 111 | ds, fd_filename, snapshot, |
---|
| 112 | kernel_filename, kernel_cmdline, |
---|
| 113 | - initrd_filename, 0); |
---|
| 114 | + initrd_filename, timeoffset, 0); |
---|
| 115 | } |
---|
| 116 | |
---|
| 117 | QEMUMachine pc_machine = { |
---|
| 118 | Index: ioemu/vl.c |
---|
| 119 | =================================================================== |
---|
| 120 | --- ioemu.orig/vl.c 2007-05-03 15:38:45.000000000 +0100 |
---|
| 121 | +++ ioemu/vl.c 2007-05-03 15:38:45.000000000 +0100 |
---|
| 122 | @@ -167,6 +167,8 @@ |
---|
| 123 | |
---|
| 124 | int xc_handle; |
---|
| 125 | |
---|
| 126 | +time_t timeoffset = 0; |
---|
| 127 | + |
---|
| 128 | char domain_name[1024] = { 'H','V', 'M', 'X', 'E', 'N', '-'}; |
---|
| 129 | extern int domid; |
---|
| 130 | |
---|
| 131 | @@ -5435,6 +5437,7 @@ |
---|
| 132 | "-vncviewer start a vncviewer process for this domain\n" |
---|
| 133 | "-vncunused bind the VNC server to an unused port\n" |
---|
| 134 | "-vnclisten bind the VNC server to this address\n" |
---|
| 135 | + "-timeoffset time offset (in seconds) from local time\n" |
---|
| 136 | "-acpi disable or enable ACPI of HVM domain \n" |
---|
| 137 | "\n" |
---|
| 138 | "During emulation, the following keys are useful:\n" |
---|
| 139 | @@ -5522,6 +5525,7 @@ |
---|
| 140 | |
---|
| 141 | QEMU_OPTION_d, |
---|
| 142 | QEMU_OPTION_vcpus, |
---|
| 143 | + QEMU_OPTION_timeoffset, |
---|
| 144 | QEMU_OPTION_acpi, |
---|
| 145 | QEMU_OPTION_vncviewer, |
---|
| 146 | QEMU_OPTION_vncunused, |
---|
| 147 | @@ -5613,6 +5617,7 @@ |
---|
| 148 | |
---|
| 149 | { "d", HAS_ARG, QEMU_OPTION_d }, |
---|
| 150 | { "vcpus", 1, QEMU_OPTION_vcpus }, |
---|
| 151 | + { "timeoffset", HAS_ARG, QEMU_OPTION_timeoffset }, |
---|
| 152 | { "acpi", 0, QEMU_OPTION_acpi }, |
---|
| 153 | { NULL }, |
---|
| 154 | }; |
---|
| 155 | @@ -6377,6 +6382,9 @@ |
---|
| 156 | vcpus = atoi(optarg); |
---|
| 157 | fprintf(logfile, "qemu: the number of cpus is %d\n", vcpus); |
---|
| 158 | break; |
---|
| 159 | + case QEMU_OPTION_timeoffset: |
---|
| 160 | + timeoffset = strtol(optarg, NULL, 0); |
---|
| 161 | + break; |
---|
| 162 | case QEMU_OPTION_acpi: |
---|
| 163 | acpi_enabled = 1; |
---|
| 164 | break; |
---|
| 165 | @@ -6531,6 +6539,9 @@ |
---|
| 166 | } |
---|
| 167 | free(page_array); |
---|
| 168 | #endif |
---|
| 169 | + |
---|
| 170 | + timeoffset_get(); |
---|
| 171 | + |
---|
| 172 | #else /* !CONFIG_DM */ |
---|
| 173 | |
---|
| 174 | phys_ram_base = qemu_vmalloc(phys_ram_size); |
---|
| 175 | @@ -6662,7 +6673,8 @@ |
---|
| 176 | |
---|
| 177 | machine->init(ram_size, vga_ram_size, boot_device, |
---|
| 178 | ds, fd_filename, snapshot, |
---|
| 179 | - kernel_filename, kernel_cmdline, initrd_filename); |
---|
| 180 | + kernel_filename, kernel_cmdline, initrd_filename, |
---|
| 181 | + timeoffset); |
---|
| 182 | |
---|
| 183 | /* init USB devices */ |
---|
| 184 | if (usb_enabled) { |
---|
| 185 | Index: ioemu/vl.h |
---|
| 186 | =================================================================== |
---|
| 187 | --- ioemu.orig/vl.h 2007-05-03 15:38:45.000000000 +0100 |
---|
| 188 | +++ ioemu/vl.h 2007-05-03 15:38:45.000000000 +0100 |
---|
| 189 | @@ -581,7 +581,7 @@ |
---|
| 190 | int boot_device, |
---|
| 191 | DisplayState *ds, const char **fd_filename, int snapshot, |
---|
| 192 | const char *kernel_filename, const char *kernel_cmdline, |
---|
| 193 | - const char *initrd_filename); |
---|
| 194 | + const char *initrd_filename, time_t timeoffset); |
---|
| 195 | |
---|
| 196 | typedef struct QEMUMachine { |
---|
| 197 | const char *name; |
---|
| 198 | @@ -1216,6 +1216,10 @@ |
---|
| 199 | int xenstore_vm_write(int domid, char *key, char *val); |
---|
| 200 | char *xenstore_vm_read(int domid, char *key, int *len); |
---|
| 201 | |
---|
| 202 | +/* helper2.c */ |
---|
| 203 | +extern long time_offset; |
---|
| 204 | +void timeoffset_get(void); |
---|
| 205 | + |
---|
| 206 | void kqemu_record_dump(void); |
---|
| 207 | |
---|
| 208 | extern char domain_name[]; |
---|
| 209 | Index: ioemu/target-i386-dm/helper2.c |
---|
| 210 | =================================================================== |
---|
| 211 | --- ioemu.orig/target-i386-dm/helper2.c 2007-05-03 15:38:44.000000000 +0100 |
---|
| 212 | +++ ioemu/target-i386-dm/helper2.c 2007-05-03 15:38:45.000000000 +0100 |
---|
| 213 | @@ -74,6 +74,8 @@ |
---|
| 214 | |
---|
| 215 | int xc_handle; |
---|
| 216 | |
---|
| 217 | +long time_offset = 0; |
---|
| 218 | + |
---|
| 219 | shared_iopage_t *shared_page = NULL; |
---|
| 220 | |
---|
| 221 | /* the evtchn fd for polling */ |
---|
| 222 | @@ -447,6 +449,34 @@ |
---|
| 223 | req->data = tmp1; |
---|
| 224 | } |
---|
| 225 | |
---|
| 226 | +void timeoffset_get() |
---|
| 227 | +{ |
---|
| 228 | + char *p; |
---|
| 229 | + |
---|
| 230 | + p = xenstore_vm_read(domid, "rtc/timeoffset", NULL); |
---|
| 231 | + if (!p) |
---|
| 232 | + return; |
---|
| 233 | + |
---|
| 234 | + if (sscanf(p, "%ld", &time_offset) == 1) |
---|
| 235 | + fprintf(logfile, "Time offset set %ld\n", time_offset); |
---|
| 236 | + else |
---|
| 237 | + time_offset = 0; |
---|
| 238 | + |
---|
| 239 | + xc_domain_set_time_offset(xc_handle, domid, time_offset); |
---|
| 240 | + |
---|
| 241 | + free(p); |
---|
| 242 | +} |
---|
| 243 | + |
---|
| 244 | +void cpu_ioreq_timeoffset(CPUState *env, ioreq_t *req) |
---|
| 245 | +{ |
---|
| 246 | + char b[64]; |
---|
| 247 | + |
---|
| 248 | + time_offset += (ulong)req->data; |
---|
| 249 | + |
---|
| 250 | + sprintf(b, "%ld", time_offset); |
---|
| 251 | + xenstore_vm_write(domid, "rtc/timeoffset", b); |
---|
| 252 | +} |
---|
| 253 | + |
---|
| 254 | void cpu_ioreq_xchg(CPUState *env, ioreq_t *req) |
---|
| 255 | { |
---|
| 256 | unsigned long tmp1; |
---|
| 257 | @@ -497,6 +527,9 @@ |
---|
| 258 | case IOREQ_TYPE_XCHG: |
---|
| 259 | cpu_ioreq_xchg(env, req); |
---|
| 260 | break; |
---|
| 261 | + case IOREQ_TYPE_TIMEOFFSET: |
---|
| 262 | + cpu_ioreq_timeoffset(env, req); |
---|
| 263 | + break; |
---|
| 264 | default: |
---|
| 265 | hw_error("Invalid ioreq type 0x%x\n", req->type); |
---|
| 266 | } |
---|