Skip to content
This repository has been archived by the owner on Apr 14, 2021. It is now read-only.

Commit

Permalink
hw: virt: Add basic ACPI timer support
Browse files Browse the repository at this point in the history
For the reduced ACPI platform implement the basic ACPI PM_TMR support.
Implement only the basic counter and not the optional interupt
triggering when the counter's carry changes value.

This is useful for implementing basic timekeeping in early firmware.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
  • Loading branch information
rbradford committed Dec 13, 2018
1 parent 24ef048 commit 4728f53
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 0 deletions.
3 changes: 3 additions & 0 deletions hw/acpi/reduced.c
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,9 @@ static void build_fadt_reduced(GArray *table_data, BIOSLinker *linker,
.sleep_status_reg = { .space_id = AML_AS_SYSTEM_IO,
.bit_width = 8, .bit_offset = 0,
.address = ACPI_REDUCED_SLEEP_STATUS_IOPORT },
.pm_tmr = { .space_id = AML_AS_SYSTEM_IO,
.bit_width = 32, .bit_offset = 0,
.address = ACPI_REDUCED_PMTIMER_IOPORT },
};

build_fadt(table_data, linker, &fadt, NULL, NULL);
Expand Down
24 changes: 24 additions & 0 deletions hw/i386/virt/acpi.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ typedef struct VirtAcpiState {
MemoryRegion sleep_iomem;
MemoryRegion sleep_status_iomem;
MemoryRegion reset_iomem;
MemoryRegion pm_timer_iomem;
} VirtAcpiState;

#define TYPE_VIRT_ACPI "virt-acpi"
Expand Down Expand Up @@ -209,6 +210,25 @@ static const MemoryRegionOps virt_reset_ops = {
.write = virt_acpi_reset_write,
};

static void virt_acpi_pm_timer_write(void *opaque, hwaddr addr,
uint64_t val, unsigned width)
{
return;
}

static uint64_t virt_acpi_pm_timer_read(void *opaque, hwaddr addr,
unsigned width)
{
uint64_t counter = muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL),
PM_TIMER_FREQUENCY, NANOSECONDS_PER_SECOND);
return counter & 0xffffff;
}

const MemoryRegionOps virt_pm_timer_ops = {
.write = virt_acpi_pm_timer_write,
.read = virt_acpi_pm_timer_read,
};

static void virt_device_realize(DeviceState *dev, Error **errp)
{
VirtAcpiState *s = VIRT_ACPI(dev);
Expand Down Expand Up @@ -236,6 +256,10 @@ static void virt_device_realize(DeviceState *dev, Error **errp)
memory_region_init_io(&s->reset_iomem, OBJECT(dev),
&virt_reset_ops, s, TYPE_VIRT_ACPI, 1);
sysbus_add_io(sys, ACPI_REDUCED_RESET_IOPORT, &s->reset_iomem);

memory_region_init_io(&s->pm_timer_iomem, OBJECT(dev),
&virt_pm_timer_ops, s, TYPE_VIRT_ACPI, 4);
sysbus_add_io(sys, ACPI_REDUCED_PMTIMER_IOPORT, &s->pm_timer_iomem);
}

DeviceState *virt_acpi_init(qemu_irq *gsi, PCIBus *pci_bus)
Expand Down
1 change: 1 addition & 0 deletions include/hw/acpi/reduced.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#define ACPI_REDUCED_SLEEP_STATUS_IOPORT 0x3D0
#define ACPI_REDUCED_RESET_IOPORT 0x3C0
#define ACPI_REDUCED_RESET_VALUE 4
#define ACPI_REDUCED_PMTIMER_IOPORT 0x3E0

void acpi_reduced_setup(MachineState *machine, AcpiConfiguration *conf);

Expand Down

0 comments on commit 4728f53

Please sign in to comment.