Commit fd872598d8d8cf78c1f12ed9661baf9ac0943c04

Authored by bellard
1 parent 8cd0ac2f

primitive ioport debug - /dev/rtc fast timer support (needed for better simulati…

…on accuracy with Linux 2.4)


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@799 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 3 changed files with 88 additions and 6 deletions
cpu-all.h
... ... @@ -636,6 +636,7 @@ target_ulong cpu_get_phys_page_debug(CPUState *env, target_ulong addr);
636 636 #define CPU_LOG_INT (1 << 4)
637 637 #define CPU_LOG_EXEC (1 << 5)
638 638 #define CPU_LOG_PCALL (1 << 6)
  639 +#define CPU_LOG_IOPORT (1 << 7)
639 640  
640 641 /* define log items */
641 642 typedef struct CPULogItem {
... ...
... ... @@ -1131,6 +1131,8 @@ CPULogItem cpu_log_items[] = {
1131 1131 { CPU_LOG_PCALL, "pcall",
1132 1132 "show protected mode far calls/returns/exceptions" },
1133 1133 #endif
  1134 + { CPU_LOG_IOPORT, "ioport",
  1135 + "show all i/o ports accesses" },
1134 1136 { 0, NULL, NULL },
1135 1137 };
1136 1138  
... ...
... ... @@ -43,6 +43,7 @@
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,6 +78,7 @@ extern void __sigaction();
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,37 +276,67 @@ int load_image(const char *filename, uint8_t *addr)
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,6 +712,34 @@ static void host_alarm_handler(int host_signum)
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,7 +775,7 @@ static void init_timers(void)
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,8 +784,27 @@ static void init_timers(void)
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 }
... ...