From: Beth Kon <eak@us.ibm.com>
To: kvm@vger.kernel.org
Cc: Beth Kon <eak@us.ibm.com>
Subject: [RFC][PATCH 2/2] Finish hpet implementation for KVM
Date: Thu, 22 Jan 2009 22:29:37 -0600 [thread overview]
Message-ID: <1232684977-4530-2-git-send-email-eak@us.ibm.com> (raw)
In-Reply-To: <1232684977-4530-1-git-send-email-eak@us.ibm.com>
- add hpet to BIOS
- add disable/enable of kernel pit when hpet enters/leaves legacy mode
Signed-off-by: Beth Kon <eak@us.ibm.com>
diff --git a/bios/acpi-dsdt.dsl b/bios/acpi-dsdt.dsl
index d67616d..9981a1f 100755
--- a/bios/acpi-dsdt.dsl
+++ b/bios/acpi-dsdt.dsl
@@ -233,6 +233,24 @@ DefinitionBlock (
,, , AddressRangeMemory, TypeStatic)
})
}
+ 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 */
+ )
+ })
+ }
}
Scope(\_SB.PCI0) {
diff --git a/bios/rombios32.c b/bios/rombios32.c
index 84f15fb..17c3704 100755
--- a/bios/rombios32.c
+++ b/bios/rombios32.c
@@ -1272,7 +1272,7 @@ struct rsdp_descriptor /* Root System Descriptor Pointer */
struct rsdt_descriptor_rev1
{
ACPI_TABLE_HEADER_DEF /* ACPI common table header */
- uint32_t table_offset_entry [2]; /* Array of pointers to other */
+ uint32_t table_offset_entry [3]; /* Array of pointers to other */
/* ACPI tables */
} __attribute__((__packed__));
@@ -1412,6 +1412,31 @@ struct madt_processor_apic
#endif
} __attribute__((__packed__));
+/*
+ * * 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;
+} __attribute__((__packed__));
+
+/*
+ * * 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;
+} __attribute__((__packed__));
+
+#define ACPI_HPET_ADDRESS 0xFED00000UL
+
struct madt_io_apic
{
APIC_HEADER_DEF
@@ -1484,6 +1509,8 @@ void acpi_bios_init(void)
struct facs_descriptor_rev1 *facs;
struct multiple_apic_table *madt;
uint8_t *dsdt;
+ struct acpi_20_hpet *hpet;
+ uint32_t hpet_addr;
uint32_t base_addr, rsdt_addr, fadt_addr, addr, facs_addr, dsdt_addr;
uint32_t acpi_tables_size, madt_addr, madt_size;
int i;
@@ -1531,6 +1558,11 @@ void acpi_bios_init(void)
madt_size += sizeof(struct madt_intsrcovr);
addr += madt_size;
+ addr = (addr + 7) & ~7;
+ hpet_addr = addr;
+ hpet = (void *)(addr);
+ addr += sizeof(*hpet);
+
acpi_tables_size = addr - base_addr;
BX_INFO("ACPI tables: RSDP addr=0x%08lx ACPI DATA addr=0x%08lx size=0x%x\n",
@@ -1552,6 +1584,7 @@ void acpi_bios_init(void)
memset(rsdt, 0, sizeof(*rsdt));
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(hpet_addr);
acpi_build_table_header((struct acpi_table_header *)rsdt,
"RSDT", sizeof(*rsdt), 1);
@@ -1641,6 +1674,15 @@ void acpi_bios_init(void)
}
acpi_build_table_header((struct acpi_table_header *)madt,
"APIC", madt_size, 1);
+ /* 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);
}
}
diff --git a/qemu/hw/hpet.c b/qemu/hw/hpet.c
index 7df2d05..80b2edd 100644
--- a/qemu/hw/hpet.c
+++ b/qemu/hw/hpet.c
@@ -30,8 +30,9 @@
#include "console.h"
#include "qemu-timer.h"
#include "hpet_emul.h"
+#include "qemu-kvm.h"
-//#define HPET_DEBUG
+#define HPET_DEBUG
#ifdef HPET_DEBUG
#define dprintf printf
#else
@@ -48,6 +49,43 @@ uint32_t hpet_in_legacy_mode(void)
return 0;
}
+static void hpet_kpit_enable(void)
+{
+ struct kvm_pit_state ps;
+ kvm_get_pit(kvm_context, &ps);
+ kvm_set_pit(kvm_context, &ps);
+}
+
+static void hpet_kpit_disable(void)
+{
+ struct kvm_pit_state ps;
+ kvm_get_pit(kvm_context, &ps);
+ ps.channels[0].mode = 0xff;
+ kvm_set_pit(kvm_context, &ps);
+}
+
+static void hpet_legacy_enable(void)
+{
+ if (qemu_kvm_pit_in_kernel()) {
+ hpet_kpit_disable();
+ dprintf("qemu: hpet disabled kernel pit\n");
+ } else {
+ hpet_pit_disable();
+ dprintf("qemu: hpet disabled userspace pit\n");
+ }
+}
+
+static void hpet_legacy_disable(void)
+{
+ if (qemu_kvm_pit_in_kernel()) {
+ hpet_kpit_enable();
+ dprintf("qemu: hpet enabled kernel pit\n");
+ } else {
+ hpet_pit_enable();
+ dprintf("qemu: hpet enabled userspace pit\n");
+ }
+}
+
static uint32_t timer_int_route(struct HPETTimer *timer)
{
uint32_t route;
@@ -475,9 +513,9 @@ static void hpet_ram_writel(void *opaque, target_phys_addr_t addr,
}
/* i8254 and RTC are disabled when HPET is in legacy mode */
if (activating_bit(old_val, new_val, HPET_CFG_LEGACY)) {
- hpet_pit_disable();
+ hpet_legacy_enable();
} else if (deactivating_bit(old_val, new_val, HPET_CFG_LEGACY)) {
- hpet_pit_enable();
+ hpet_legacy_disable();
}
break;
case HPET_CFG + 4:
@@ -560,7 +598,7 @@ static void hpet_reset(void *opaque) {
* hpet_reset is called due to system reset. At this point control must
* be returned to pit until SW reenables hpet.
*/
- hpet_pit_enable();
+ hpet_legacy_disable();
count = 1;
}
diff --git a/qemu/vl.c b/qemu/vl.c
index 21b3e51..c977deb 100644
--- a/qemu/vl.c
+++ b/qemu/vl.c
@@ -5877,6 +5877,12 @@ int main(int argc, char **argv, char **envp)
kvm_init_ap();
if (kvm_irqchip && !kvm_has_gsi_routing(kvm_context)) {
irq0override = 0;
+
+ /* if kernel can't do irq routing, interrupt source
+ * override 0->2 can not be set up as required by hpet,
+ * so disable hpet.
+ */
+ no_hpet=1;
}
}
next prev parent reply other threads:[~2009-01-23 4:33 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-01-23 4:29 [RFC][PATCH 1/2] Make irq0->inti2 override in BIOS configurable from userspace Beth Kon
2009-01-23 4:29 ` Beth Kon [this message]
2009-01-25 1:31 ` Marcelo Tosatti
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1232684977-4530-2-git-send-email-eak@us.ibm.com \
--to=eak@us.ibm.com \
--cc=kvm@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.