Revision fd872598 vl.c
b/vl.c | ||
---|---|---|
43 | 43 |
#include <sys/socket.h> |
44 | 44 |
#include <linux/if.h> |
45 | 45 |
#include <linux/if_tun.h> |
46 |
#include <linux/rtc.h> |
|
46 | 47 |
#endif |
47 | 48 |
|
48 | 49 |
#if defined(CONFIG_SLIRP) |
... | ... | |
77 | 78 |
#define DEFAULT_NETWORK_SCRIPT "/etc/qemu-ifup" |
78 | 79 |
|
79 | 80 |
//#define DEBUG_UNUSED_IOPORT |
81 |
//#define DEBUG_IOPORT |
|
80 | 82 |
|
81 | 83 |
#if !defined(CONFIG_SOFTMMU) |
82 | 84 |
#define PHYS_RAM_MAX_SIZE (256 * 1024 * 1024) |
... | ... | |
274 | 276 |
void cpu_outb(CPUState *env, int addr, int val) |
275 | 277 |
{ |
276 | 278 |
addr &= (MAX_IOPORTS - 1); |
279 |
#ifdef DEBUG_IOPORT |
|
280 |
if (loglevel & CPU_LOG_IOPORT) |
|
281 |
fprintf(logfile, "outb: %04x %02x\n", addr, val); |
|
282 |
#endif |
|
277 | 283 |
ioport_write_table[0][addr](ioport_opaque[addr], addr, val); |
278 | 284 |
} |
279 | 285 |
|
280 | 286 |
void cpu_outw(CPUState *env, int addr, int val) |
281 | 287 |
{ |
282 | 288 |
addr &= (MAX_IOPORTS - 1); |
289 |
#ifdef DEBUG_IOPORT |
|
290 |
if (loglevel & CPU_LOG_IOPORT) |
|
291 |
fprintf(logfile, "outw: %04x %04x\n", addr, val); |
|
292 |
#endif |
|
283 | 293 |
ioport_write_table[1][addr](ioport_opaque[addr], addr, val); |
284 | 294 |
} |
285 | 295 |
|
286 | 296 |
void cpu_outl(CPUState *env, int addr, int val) |
287 | 297 |
{ |
288 | 298 |
addr &= (MAX_IOPORTS - 1); |
299 |
#ifdef DEBUG_IOPORT |
|
300 |
if (loglevel & CPU_LOG_IOPORT) |
|
301 |
fprintf(logfile, "outl: %04x %08x\n", addr, val); |
|
302 |
#endif |
|
289 | 303 |
ioport_write_table[2][addr](ioport_opaque[addr], addr, val); |
290 | 304 |
} |
291 | 305 |
|
292 | 306 |
int cpu_inb(CPUState *env, int addr) |
293 | 307 |
{ |
308 |
int val; |
|
294 | 309 |
addr &= (MAX_IOPORTS - 1); |
295 |
return ioport_read_table[0][addr](ioport_opaque[addr], addr); |
|
310 |
val = ioport_read_table[0][addr](ioport_opaque[addr], addr); |
|
311 |
#ifdef DEBUG_IOPORT |
|
312 |
if (loglevel & CPU_LOG_IOPORT) |
|
313 |
fprintf(logfile, "inb : %04x %02x\n", addr, val); |
|
314 |
#endif |
|
315 |
return val; |
|
296 | 316 |
} |
297 | 317 |
|
298 | 318 |
int cpu_inw(CPUState *env, int addr) |
299 | 319 |
{ |
320 |
int val; |
|
300 | 321 |
addr &= (MAX_IOPORTS - 1); |
301 |
return ioport_read_table[1][addr](ioport_opaque[addr], addr); |
|
322 |
val = ioport_read_table[1][addr](ioport_opaque[addr], addr); |
|
323 |
#ifdef DEBUG_IOPORT |
|
324 |
if (loglevel & CPU_LOG_IOPORT) |
|
325 |
fprintf(logfile, "inw : %04x %04x\n", addr, val); |
|
326 |
#endif |
|
327 |
return val; |
|
302 | 328 |
} |
303 | 329 |
|
304 | 330 |
int cpu_inl(CPUState *env, int addr) |
305 | 331 |
{ |
332 |
int val; |
|
306 | 333 |
addr &= (MAX_IOPORTS - 1); |
307 |
return ioport_read_table[2][addr](ioport_opaque[addr], addr); |
|
334 |
val = ioport_read_table[2][addr](ioport_opaque[addr], addr); |
|
335 |
#ifdef DEBUG_IOPORT |
|
336 |
if (loglevel & CPU_LOG_IOPORT) |
|
337 |
fprintf(logfile, "inl : %04x %08x\n", addr, val); |
|
338 |
#endif |
|
339 |
return val; |
|
308 | 340 |
} |
309 | 341 |
|
310 | 342 |
/***********************************************************/ |
... | ... | |
680 | 712 |
} |
681 | 713 |
} |
682 | 714 |
|
715 |
#ifndef _WIN32 |
|
716 |
|
|
717 |
#define RTC_FREQ 1024 |
|
718 |
|
|
719 |
static int rtc_fd; |
|
720 |
|
|
721 |
static int start_rtc_timer(void) |
|
722 |
{ |
|
723 |
rtc_fd = open("/dev/rtc", O_RDONLY); |
|
724 |
if (rtc_fd < 0) |
|
725 |
return -1; |
|
726 |
if (ioctl(rtc_fd, RTC_IRQP_SET, RTC_FREQ) < 0) { |
|
727 |
fprintf(stderr, "Could not configure '/dev/rtc' to have a 1024 Hz timer. This is not a fatal\n" |
|
728 |
"error, but for better emulation accuracy either use a 2.6 host Linux kernel or\n" |
|
729 |
"type 'echo 1024 > /proc/sys/dev/rtc/max-user-freq' as root.\n"); |
|
730 |
goto fail; |
|
731 |
} |
|
732 |
if (ioctl(rtc_fd, RTC_PIE_ON, 0) < 0) { |
|
733 |
fail: |
|
734 |
close(rtc_fd); |
|
735 |
return -1; |
|
736 |
} |
|
737 |
pit_min_timer_count = PIT_FREQ / RTC_FREQ; |
|
738 |
return 0; |
|
739 |
} |
|
740 |
|
|
741 |
#endif |
|
742 |
|
|
683 | 743 |
static void init_timers(void) |
684 | 744 |
{ |
685 | 745 |
rt_clock = qemu_new_clock(QEMU_TIMER_REALTIME); |
... | ... | |
715 | 775 |
#endif |
716 | 776 |
act.sa_handler = host_alarm_handler; |
717 | 777 |
sigaction(SIGALRM, &act, NULL); |
718 |
|
|
778 |
|
|
719 | 779 |
itv.it_interval.tv_sec = 0; |
720 | 780 |
itv.it_interval.tv_usec = 1000; |
721 | 781 |
itv.it_value.tv_sec = 0; |
... | ... | |
724 | 784 |
/* we probe the tick duration of the kernel to inform the user if |
725 | 785 |
the emulated kernel requested a too high timer frequency */ |
726 | 786 |
getitimer(ITIMER_REAL, &itv); |
727 |
pit_min_timer_count = ((uint64_t)itv.it_interval.tv_usec * PIT_FREQ) / |
|
728 |
1000000; |
|
787 |
|
|
788 |
if (itv.it_interval.tv_usec > 1000) { |
|
789 |
/* try to use /dev/rtc to have a faster timer */ |
|
790 |
if (start_rtc_timer() < 0) |
|
791 |
goto use_itimer; |
|
792 |
/* disable itimer */ |
|
793 |
itv.it_interval.tv_sec = 0; |
|
794 |
itv.it_interval.tv_usec = 0; |
|
795 |
itv.it_value.tv_sec = 0; |
|
796 |
itv.it_value.tv_usec = 0; |
|
797 |
setitimer(ITIMER_REAL, &itv, NULL); |
|
798 |
|
|
799 |
/* use the RTC */ |
|
800 |
sigaction(SIGIO, &act, NULL); |
|
801 |
fcntl(rtc_fd, F_SETFL, O_ASYNC); |
|
802 |
fcntl(rtc_fd, F_SETOWN, getpid()); |
|
803 |
} else { |
|
804 |
use_itimer: |
|
805 |
pit_min_timer_count = ((uint64_t)itv.it_interval.tv_usec * |
|
806 |
PIT_FREQ) / 1000000; |
|
807 |
} |
|
729 | 808 |
} |
730 | 809 |
#endif |
731 | 810 |
} |
Also available in: Unified diff