mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
Add HPET emulation to qemu (Beth Kon)
This patch adds HPET emulation. It can be disabled with -disable-hpet. An hpet provides a more finely granular clocksource than otherwise available on PC. This means that latency-dependent applications (e.g. multimedia) will generally be smoother when using the HPET. Signed-off-by: Beth Kon <eak@us.ibm.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6081 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
+1
-1
@@ -635,7 +635,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
|
||||
# virtio support
|
||||
OBJS+= virtio.o virtio-blk.o virtio-balloon.o virtio-net.o
|
||||
CPPFLAGS += -DHAS_AUDIO -DHAS_AUDIO_CHOICE
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* QEMU Emulated HPET support
|
||||
*
|
||||
* Copyright IBM, Corp. 2008
|
||||
*
|
||||
* Authors:
|
||||
* Beth Kon <bkon@us.ibm.com>
|
||||
*
|
||||
* This work is licensed under the terms of the GNU GPL, version 2. See
|
||||
* the COPYING file in the top-level directory.
|
||||
*
|
||||
*/
|
||||
#ifndef QEMU_HPET_EMUL_H
|
||||
#define QEMU_HPET_EMUL_H
|
||||
|
||||
#define HPET_BASE 0xfed00000
|
||||
#define HPET_CLK_PERIOD 10000000ULL /* 10000000 femtoseconds == 10ns*/
|
||||
|
||||
#define FS_PER_NS 1000000
|
||||
#define HPET_NUM_TIMERS 3
|
||||
#define HPET_TIMER_TYPE_LEVEL 1
|
||||
#define HPET_TIMER_TYPE_EDGE 0
|
||||
#define HPET_TIMER_DELIVERY_APIC 0
|
||||
#define HPET_TIMER_DELIVERY_FSB 1
|
||||
#define HPET_TIMER_CAP_FSB_INT_DEL (1 << 15)
|
||||
#define HPET_TIMER_CAP_PER_INT (1 << 4)
|
||||
|
||||
#define HPET_CFG_ENABLE 0x001
|
||||
#define HPET_CFG_LEGACY 0x002
|
||||
|
||||
#define HPET_ID 0x000
|
||||
#define HPET_PERIOD 0x004
|
||||
#define HPET_CFG 0x010
|
||||
#define HPET_STATUS 0x020
|
||||
#define HPET_COUNTER 0x0f0
|
||||
#define HPET_TN_CFG 0x000
|
||||
#define HPET_TN_CMP 0x008
|
||||
#define HPET_TN_ROUTE 0x010
|
||||
|
||||
|
||||
#define HPET_TN_ENABLE 0x004
|
||||
#define HPET_TN_PERIODIC 0x008
|
||||
#define HPET_TN_PERIODIC_CAP 0x010
|
||||
#define HPET_TN_SIZE_CAP 0x020
|
||||
#define HPET_TN_SETVAL 0x040
|
||||
#define HPET_TN_32BIT 0x100
|
||||
#define HPET_TN_INT_ROUTE_MASK 0x3e00
|
||||
#define HPET_TN_INT_ROUTE_SHIFT 9
|
||||
#define HPET_TN_INT_ROUTE_CAP_SHIFT 32
|
||||
#define HPET_TN_CFG_BITS_READONLY_OR_RESERVED 0xffff80b1U
|
||||
|
||||
struct HPETState;
|
||||
typedef struct HPETTimer { /* timers */
|
||||
uint8_t tn; /*timer number*/
|
||||
QEMUTimer *qemu_timer;
|
||||
struct HPETState *state;
|
||||
/* Memory-mapped, software visible timer registers */
|
||||
uint64_t config; /* configuration/cap */
|
||||
uint64_t cmp; /* comparator */
|
||||
uint64_t fsb; /* FSB route, not supported now */
|
||||
/* Hidden register state */
|
||||
uint64_t period; /* Last value written to comparator */
|
||||
uint8_t wrap_flag; /* timer pop will indicate wrap for one-shot 32-bit
|
||||
* mode. Next pop will be actual timer expiration.
|
||||
*/
|
||||
} HPETTimer;
|
||||
|
||||
typedef struct HPETState {
|
||||
uint64_t hpet_offset;
|
||||
qemu_irq *irqs;
|
||||
HPETTimer timer[HPET_NUM_TIMERS];
|
||||
|
||||
/* Memory-mapped, software visible registers */
|
||||
uint64_t capability; /* capabilities */
|
||||
uint64_t config; /* configuration */
|
||||
uint64_t isr; /* interrupt status reg */
|
||||
uint64_t hpet_counter; /* main counter */
|
||||
} HPETState;
|
||||
|
||||
#if defined TARGET_I386 || defined TARGET_X86_64
|
||||
extern uint32_t hpet_in_legacy_mode(void);
|
||||
extern void hpet_init(qemu_irq *irq);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+21
@@ -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;
|
||||
|
||||
+24
-5
@@ -26,6 +26,7 @@
|
||||
#include "sysemu.h"
|
||||
#include "pc.h"
|
||||
#include "isa.h"
|
||||
#include "hpet_emul.h"
|
||||
|
||||
//#define DEBUG_CMOS
|
||||
|
||||
@@ -69,6 +70,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 defined TARGET_I386 || defined TARGET_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);
|
||||
|
||||
@@ -78,8 +91,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] & REG_B_PIE)) {
|
||||
#if defined TARGET_I386 || defined TARGET_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] & REG_B_PIE) && !hpet_in_legacy_mode()) {
|
||||
#else
|
||||
if (period_code != 0 && (s->cmos_data[RTC_REG_B] & REG_B_PIE)) {
|
||||
#endif
|
||||
if (period_code <= 2)
|
||||
period_code += 7;
|
||||
/* period in 32 Khz cycles */
|
||||
@@ -100,7 +119,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)
|
||||
@@ -319,14 +338,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] & REG_B_UIE) {
|
||||
s->cmos_data[RTC_REG_C] |= 0x90;
|
||||
qemu_irq_raise(s->irq);
|
||||
rtc_irq_raise(s->irq);
|
||||
}
|
||||
|
||||
/* clear update in progress bit */
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include "fw_cfg.h"
|
||||
#include "virtio-blk.h"
|
||||
#include "virtio-balloon.h"
|
||||
#include "hpet_emul.h"
|
||||
|
||||
/* output Bochs bios info messages */
|
||||
//#define DEBUG_BIOS
|
||||
@@ -977,6 +978,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);
|
||||
}
|
||||
|
||||
@@ -97,6 +97,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);
|
||||
|
||||
@@ -252,6 +252,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],
|
||||
@@ -1531,6 +1536,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", },
|
||||
|
||||
@@ -0,0 +1,190 @@
|
||||
BOCHS BIOS changes to support HPET in QEMU.
|
||||
|
||||
Signed-off-by Beth Kon <eak@us.ibm.com>
|
||||
|
||||
Index: bochs-2.3.7/bios/acpi-dsdt.dsl
|
||||
===================================================================
|
||||
--- bochs-2.3.7.orig/bios/acpi-dsdt.dsl 2008-10-15 12:39:14.000000000 -0500
|
||||
+++ bochs-2.3.7/bios/acpi-dsdt.dsl 2008-10-28 07:58:40.000000000 -0500
|
||||
@@ -159,6 +159,26 @@
|
||||
Return (MEMP)
|
||||
}
|
||||
}
|
||||
+#ifdef BX_QEMU
|
||||
+ Device(HPET) {
|
||||
+ Name(_HID, EISAID("PNP0103"))
|
||||
+ Name(_UID, 0)
|
||||
+ Method (_STA, 0, NotSerialized) {
|
||||
+ Return(0x0F)
|
||||
+ }
|
||||
+ Name(_CRS, ResourceTemplate() {
|
||||
+ DWordMemory(
|
||||
+ ResourceConsumer, PosDecode, MinFixed, MaxFixed,
|
||||
+ NonCacheable, ReadWrite,
|
||||
+ 0x00000000,
|
||||
+ 0xFED00000,
|
||||
+ 0xFED003FF,
|
||||
+ 0x00000000,
|
||||
+ 0x00000400 /* 1K memory: FED00000 - FED003FF */
|
||||
+ )
|
||||
+ })
|
||||
+ }
|
||||
+#endif
|
||||
}
|
||||
|
||||
Scope(\_SB.PCI0) {
|
||||
Index: bochs-2.3.7/bios/rombios32.c
|
||||
===================================================================
|
||||
--- bochs-2.3.7.orig/bios/rombios32.c 2008-10-15 12:39:36.000000000 -0500
|
||||
+++ bochs-2.3.7/bios/rombios32.c 2008-11-12 14:41:41.000000000 -0600
|
||||
@@ -1087,7 +1087,11 @@
|
||||
struct rsdt_descriptor_rev1
|
||||
{
|
||||
ACPI_TABLE_HEADER_DEF /* ACPI common table header */
|
||||
+#ifdef BX_QEMU
|
||||
+ uint32_t table_offset_entry [4]; /* Array of pointers to other */
|
||||
+#else
|
||||
uint32_t table_offset_entry [3]; /* Array of pointers to other */
|
||||
+#endif
|
||||
/* ACPI tables */
|
||||
};
|
||||
|
||||
@@ -1227,6 +1231,32 @@
|
||||
#endif
|
||||
};
|
||||
|
||||
+#ifdef BX_QEMU
|
||||
+/*
|
||||
+ * * ACPI 2.0 Generic Address Space definition.
|
||||
+ * */
|
||||
+struct acpi_20_generic_address {
|
||||
+ uint8_t address_space_id;
|
||||
+ uint8_t register_bit_width;
|
||||
+ uint8_t register_bit_offset;
|
||||
+ uint8_t reserved;
|
||||
+ uint64_t address;
|
||||
+};
|
||||
+
|
||||
+/*
|
||||
+ * * HPET Description Table
|
||||
+ * */
|
||||
+struct acpi_20_hpet {
|
||||
+ ACPI_TABLE_HEADER_DEF /* ACPI common table header */
|
||||
+ uint32_t timer_block_id;
|
||||
+ struct acpi_20_generic_address addr;
|
||||
+ uint8_t hpet_number;
|
||||
+ uint16_t min_tick;
|
||||
+ uint8_t page_protect;
|
||||
+};
|
||||
+#define ACPI_HPET_ADDRESS 0xFED00000UL
|
||||
+#endif
|
||||
+
|
||||
struct madt_io_apic
|
||||
{
|
||||
APIC_HEADER_DEF
|
||||
@@ -1237,6 +1267,17 @@
|
||||
* lines start */
|
||||
};
|
||||
|
||||
+#ifdef BX_QEMU
|
||||
+struct madt_int_override
|
||||
+{
|
||||
+ APIC_HEADER_DEF
|
||||
+ uint8_t bus; /* Identifies ISA Bus */
|
||||
+ uint8_t source; /* Bus-relative interrupt source */
|
||||
+ uint32_t gsi; /* GSI that source will signal */
|
||||
+ uint16_t flags; /* MPS INTI flags */
|
||||
+};
|
||||
+#endif
|
||||
+
|
||||
#include "acpi-dsdt.hex"
|
||||
|
||||
static inline uint16_t cpu_to_le16(uint16_t x)
|
||||
@@ -1342,6 +1383,10 @@
|
||||
struct facs_descriptor_rev1 *facs;
|
||||
struct multiple_apic_table *madt;
|
||||
uint8_t *dsdt, *ssdt;
|
||||
+#ifdef BX_QEMU
|
||||
+ struct acpi_20_hpet *hpet;
|
||||
+ uint32_t hpet_addr;
|
||||
+#endif
|
||||
uint32_t base_addr, rsdt_addr, fadt_addr, addr, facs_addr, dsdt_addr, ssdt_addr;
|
||||
uint32_t acpi_tables_size, madt_addr, madt_size;
|
||||
int i;
|
||||
@@ -1384,10 +1429,21 @@
|
||||
madt_addr = addr;
|
||||
madt_size = sizeof(*madt) +
|
||||
sizeof(struct madt_processor_apic) * smp_cpus +
|
||||
+#ifdef BX_QEMU
|
||||
+ sizeof(struct madt_io_apic) + sizeof(struct madt_int_override);
|
||||
+#else
|
||||
sizeof(struct madt_io_apic);
|
||||
+#endif
|
||||
madt = (void *)(addr);
|
||||
addr += madt_size;
|
||||
|
||||
+#ifdef BX_QEMU
|
||||
+ addr = (addr + 7) & ~7;
|
||||
+ hpet_addr = addr;
|
||||
+ hpet = (void *)(addr);
|
||||
+ addr += sizeof(*hpet);
|
||||
+#endif
|
||||
+
|
||||
acpi_tables_size = addr - base_addr;
|
||||
|
||||
BX_INFO("ACPI tables: RSDP addr=0x%08lx ACPI DATA addr=0x%08lx size=0x%x\n",
|
||||
@@ -1410,6 +1466,9 @@
|
||||
rsdt->table_offset_entry[0] = cpu_to_le32(fadt_addr);
|
||||
rsdt->table_offset_entry[1] = cpu_to_le32(madt_addr);
|
||||
rsdt->table_offset_entry[2] = cpu_to_le32(ssdt_addr);
|
||||
+#ifdef BX_QEMU
|
||||
+ rsdt->table_offset_entry[3] = cpu_to_le32(hpet_addr);
|
||||
+#endif
|
||||
acpi_build_table_header((struct acpi_table_header *)rsdt,
|
||||
"RSDT", sizeof(*rsdt), 1);
|
||||
|
||||
@@ -1448,6 +1507,9 @@
|
||||
{
|
||||
struct madt_processor_apic *apic;
|
||||
struct madt_io_apic *io_apic;
|
||||
+#ifdef BX_QEMU
|
||||
+ struct madt_int_override *int_override;
|
||||
+#endif
|
||||
|
||||
memset(madt, 0, madt_size);
|
||||
madt->local_apic_address = cpu_to_le32(0xfee00000);
|
||||
@@ -1467,10 +1529,34 @@
|
||||
io_apic->io_apic_id = smp_cpus;
|
||||
io_apic->address = cpu_to_le32(0xfec00000);
|
||||
io_apic->interrupt = cpu_to_le32(0);
|
||||
+#ifdef BX_QEMU
|
||||
+ io_apic++;
|
||||
+
|
||||
+ int_override = (void *)io_apic;
|
||||
+ int_override->type = APIC_XRUPT_OVERRIDE;
|
||||
+ int_override->length = sizeof(*int_override);
|
||||
+ int_override->bus = cpu_to_le32(0);
|
||||
+ int_override->source = cpu_to_le32(0);
|
||||
+ int_override->gsi = cpu_to_le32(2);
|
||||
+ int_override->flags = cpu_to_le32(0);
|
||||
+#endif
|
||||
|
||||
acpi_build_table_header((struct acpi_table_header *)madt,
|
||||
"APIC", madt_size, 1);
|
||||
}
|
||||
+
|
||||
+#ifdef BX_QEMU
|
||||
+ /* HPET */
|
||||
+ memset(hpet, 0, sizeof(*hpet));
|
||||
+ /* Note timer_block_id value must be kept in sync with value advertised by
|
||||
+ * emulated hpet
|
||||
+ */
|
||||
+ hpet->timer_block_id = cpu_to_le32(0x8086a201);
|
||||
+ hpet->addr.address = cpu_to_le32(ACPI_HPET_ADDRESS);
|
||||
+ acpi_build_table_header((struct acpi_table_header *)hpet,
|
||||
+ "HPET", sizeof(*hpet), 1);
|
||||
+#endif
|
||||
+
|
||||
}
|
||||
|
||||
/* SMBIOS entry point -- must be written to a 16-bit aligned address
|
||||
@@ -2,3 +2,4 @@
|
||||
0002_e820-high-mem.patch
|
||||
0003_smp-startup-poll.patch
|
||||
0004_no-stack-protector.patch
|
||||
0005_hpet.patch
|
||||
|
||||
Binary file not shown.
@@ -224,6 +224,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;
|
||||
@@ -3956,6 +3957,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"
|
||||
@@ -4067,6 +4069,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,
|
||||
@@ -4180,6 +4183,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 },
|
||||
@@ -5017,6 +5021,9 @@ int main(int argc, char **argv, char **envp)
|
||||
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;
|
||||
|
||||
Reference in New Issue
Block a user