Add HPET emulation to qemu (v5)
PATCH 1/2 Add HPET emulation to qemu (v5)
Very minor changes. I discovered I'd created a static function and a global variable with the same name.
Signature · 4 lines
Elizabeth Kon (Beth) IBM Linux Technology Center Open Hypervisor Team email: [email protected]
Makefile.target +1 -1
@@ -662,7 +662,7 @@ ifeq ($(TARGET_BASE_ARCH), i386) OBJS+= ide.o pckbd.o ps2.o vga.o $(SOUND_HW) dma.o OBJS+= fdc.o mc146818rtc.o serial.o i8259.o i8254.o pcspk.o pc.o OBJS+= cirrus_vga.o apic.o parallel.o acpi.o piix_pci.o -OBJS+= usb-uhci.o vmmouse.o vmport.o vmware_vga.o +OBJS+= usb-uhci.o vmmouse.o vmport.o vmware_vga.o hpet.o CPPFLAGS += -DHAS_AUDIO -DHAS_AUDIO_CHOICE endif ifeq ($(TARGET_BASE_ARCH), ppc)
hw/apic.c +7 -0
@@ -945,6 +945,13 @@ void ioapic_set_irq(void *opaque, int vector, int level) {IOAPICState *s = opaque; +/* ISA IRQs map to GSI 1-1 except for IRQ0 which maps +* to GSI 2. GSI maps to ioapic 1-1. This is not +* the cleanest way of doing it but it should work. */ + +if (vector ==0 ) + vector =2 ; +if (vector >=0 && vector <IOAPIC_NUM_PINS ) {uint32_t mask =1 << vector;uint64_t entry = s->ioredtbl[vector];
hw/hpet.c new file +588 -0
588 lines not on this page · raw message
hw/hpet_emul.h new file +85 -0
85 lines not on this page · raw message
hw/i8254.c +21 -0
@@ -463,6 +463,27 @@ static void pit_reset(void *opaque) } } +/* When HPET is operating in legacy mode, i8254 timer0 is disabled */ +void hpet_pit_disable (void ) { +PITChannelState *s; + s = &pit_state.channels[0 ]; +qemu_del_timer (s->irq_timer); +} + +/* When HPET is reset or leaving legacy mode, it must reenable i8254 +* timer 0 +*/ + +void hpet_pit_enable (void ) +{ +PITState *pit = &pit_state; +PITChannelState *s; + s = &pit->channels[0 ]; + s->mode =3 ; + s->gate =1 ; +pit_load_count (s,0 ); +} +PITState *pit_init (int base,qemu_irq irq) {PITState *pit = &pit_state;
hw/mc146818rtc.c +24 -5
@@ -26,6 +26,7 @@#include "sysemu.h" #include "pc.h" #include "isa.h" +#include "hpet_emul.h" //#define DEBUG_CMOS
@@ -70,6 +71,18 @@ struct RTCState {QEMUTimer *second_timer2; }; +static void rtc_irq_raise (qemu_irq irq) { +/* When HPET is operating in legacy mode, RTC interrupts are disabled +* We block qemu_irq_raise, but not qemu_irq_lower, in case legacy +* mode is established while interrupt is raised. We want it to +* be lowered in any case +*/ +#if definedTARGET_I386 || definedTARGET_X86_64 + if (!hpet_in_legacy_mode()) +#endif +qemu_irq_raise (irq); +} +static void rtc_set_time (RTCState *s);static void rtc_copy_date (RTCState *s);
@@ -79,8 +92,14 @@ static void rtc_timer_update(RTCState *s, int64_t current_time)int64_t cur_clock, next_irq_clock; period_code = s->cmos_data[RTC_REG_A ] &0x0f ; -if (period_code !=0 && - (s->cmos_data[RTC_REG_B ] ®_B_PIE )) { +#if definedTARGET_I386 || definedTARGET_X86_64 +/* disable periodic timer if hpet is in legacy mode, since interrupts are +* disabled anyway. +*/ +if (period_code !=0 && (s->cmos_data[RTC_REG_B ] ®_B_PIE ) && !hpet_in_legacy_mode ()) { +#else +if (period_code !=0 && (s->cmos_data[RTC_REG_B ] ®_B_PIE )) { +#endif if (period_code <=2 ) period_code +=7 ;/* period in 32 Khz cycles */
@@ -101,7 +120,7 @@ static void rtc_periodic_timer(void *opaque)rtc_timer_update (s, s->next_periodic_time); s->cmos_data[RTC_REG_C ] |=0xc0 ; -qemu_irq_raise (s->irq); +rtc_irq_raise (s->irq); }static void cmos_ioport_write (void *opaque,uint32_t addr,uint32_t data)
@@ -320,14 +339,14 @@ static void rtc_update_second2(void *opaque) s->cmos_data[RTC_HOURS_ALARM] == s->current_tm.tm_hour)) { s->cmos_data[RTC_REG_C ] |=0xa0 ; -qemu_irq_raise (s->irq); +rtc_irq_raise (s->irq); } }/* update ended interrupt */ if (s->cmos_data[RTC_REG_B ] ®_B_UIE ) { s->cmos_data[RTC_REG_C ] |=0x90 ; -qemu_irq_raise (s->irq); +rtc_irq_raise (s->irq); }/* clear update in progress bit */
hw/pc.c +4 -0
@@ -33,6 +33,7 @@#include "boards.h" #include "console.h" #include "fw_cfg.h" +#include "hpet_emul.h" /* output Bochs bios info messages */ //#define DEBUG_BIOS
@@ -975,6 +976,9 @@ static void pc_init1(ram_addr_t ram_size, int vga_ram_size, } pit =pit_init (0x40 , i8259[0 ]);pcspk_init (pit); +if (!no_hpet) { +hpet_init (i8259); + }if (pci_enabled) {pic_set_alt_irq_func (isa_pic, ioapic_set_irq, ioapic); }
hw/pc.h +3 -0
@@ -95,6 +95,9 @@ i2c_bus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,void piix4_smbus_register_device (SMBusDevice *dev,uint8_t addr);void acpi_bios_init (void ); +/* hpet.c */ +extern int no_hpet; +/* pcspk.c */ void pcspk_init (PITState *);int pcspk_audio_init (AudioState *,qemu_irq *pic);
monitor.c +7 -0
@@ -251,6 +251,11 @@ static void do_info_name(void)term_printf ("%s\n" , qemu_name); } +static void do_info_hpet (void ) +{ +term_printf ("HPET is %s by QEMU\n" , (no_hpet) ?"disabled" :"enabled" ); +} +static void do_info_uuid (void ) { term_printf(UUID_FMT "\n", qemu_uuid[0], qemu_uuid[1], qemu_uuid[2],
@@ -1506,6 +1511,8 @@ static const term_cmd_t info_cmds[] = { "", "show virtual to physical memory mappings", }, { "mem", "", mem_info, "", "show the active virtual memory mappings", }, + { "hpet", "", do_info_hpet, + "", "show state of HPET", }, #endif { "jit", "", do_info_jit, "", "show dynamic compiler info", },
vl.c +7 -0
@@ -222,6 +222,7 @@ int usb_enabled = 0;int smp_cpus =1 ;const char *vnc_display;int acpi_enabled =1 ; +int no_hpet =0 ;int fd_bootchk =1 ;int no_reboot =0 ;int no_shutdown =0 ;
@@ -3922,6 +3923,7 @@ static void help(int exitcode)#endif #ifdef TARGET_I386 "-no-acpi disable ACPI\n" + "-no-hpet disable HPET\n"#endif #ifdef CONFIG_CURSES "-curses use a curses/ncurses interface instead of SDL\n"
@@ -4033,6 +4035,7 @@ enum { QEMU_OPTION_smp, QEMU_OPTION_vnc, QEMU_OPTION_no_acpi, + QEMU_OPTION_no_hpet, QEMU_OPTION_curses, QEMU_OPTION_no_reboot, QEMU_OPTION_no_shutdown,
@@ -4146,6 +4149,7 @@ static const QEMUOption qemu_options[] = {/* temporary options */ { "usb", 0, QEMU_OPTION_usb }, { "no-acpi", 0, QEMU_OPTION_no_acpi }, + { "no-hpet", 0, QEMU_OPTION_no_hpet }, { "no-reboot", 0, QEMU_OPTION_no_reboot }, { "no-shutdown", 0, QEMU_OPTION_no_shutdown }, { "show-cursor", 0, QEMU_OPTION_show_cursor },
@@ -4981,6 +4985,9 @@ int main(int argc, char **argv)case QEMU_OPTION_no_acpi: acpi_enabled =0 ;break ; +case QEMU_OPTION_no_hpet: + no_hpet =1 ; +break ;case QEMU_OPTION_no_reboot: no_reboot =1 ;break ;
Quoted 4 lines · Beth Kon
Very minor changes. I discovered I'd created a static function and a global variable with the same name.
Thanks. Applied both.
Regards,
Anthony Liguori