Am 28. Oktober 2023 13:03:41 UTC schrieb BALATON Zoltan <bala...@eik.bme.hu>:
>On Sat, 28 Oct 2023, Bernhard Beschow wrote:
>> If enabled, SMIs can be triggered via software by writing to an IO-mapped 
>> port.
>> SMIs usually trigger execution of BIOS code. If appropriate values are 
>> written
>> to the port, the BIOS transitions the system into or out of ACPI mode.
>> 
>> Note that APMState implements Intel-specific behavior where there are two IO
>> ports which are mapped at fixed addresses. In VIA, there is only one such 
>> port
>> which is located inside a relocatable IO-mapped region. Hence, there is no 
>> point
>> in reusing APMState.
>> 
>> Signed-off-by: Bernhard Beschow <shen...@gmail.com>
>> ---
>> hw/isa/vt82c686.c | 95 +++++++++++++++++++++++++++++++++++++++++++----
>> 1 file changed, 87 insertions(+), 8 deletions(-)
>> 
>> diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c
>> index e8ec63dea9..361b3bed0a 100644
>> --- a/hw/isa/vt82c686.c
>> +++ b/hw/isa/vt82c686.c
>> @@ -27,7 +27,6 @@
>> #include "hw/timer/i8254.h"
>> #include "hw/rtc/mc146818rtc.h"
>> #include "migration/vmstate.h"
>> -#include "hw/isa/apm.h"
>> #include "hw/acpi/acpi.h"
>> #include "hw/i2c/pm_smbus.h"
>> #include "qapi/error.h"
>> @@ -42,6 +41,16 @@
>> #define TYPE_VIA_PM "via-pm"
>> OBJECT_DECLARE_SIMPLE_TYPE(ViaPMState, VIA_PM)
>> 
>> +#define VIA_PM_IO_GBLEN 0x2a
>> +#define VIA_PM_IO_GBLEN_SW_SMI_EN (1 << 6)
>> +
>> +#define VIA_PM_IO_GBLCTL 0x2c
>> +#define VIA_PM_IO_GBLCTL_SMI_EN 1
>> +#define VIA_PM_IO_GBLCTL_SMIIG (1 << 4)
>> +#define VIA_PM_IO_GBLCTL_INSMI (1 << 8)
>> +
>> +#define VIA_PM_IO_SMI_CMD 0x2f
>> +
>> #define VIA_PM_GPE_LEN 4
>> 
>> #define VIA_PM_SCI_SELECT_OFS 0x42
>
>If we'll make a copy of the data sheet in form of #defines could these be in 
>the header to less clutter the source?

Last time I did that I was asked to move the defines back into the source file. 
I can't find the link right now, otherwise I'd have placed it here.

Best regards,
Bernhard

>
>Regards,
>BALATON Zoltan
>
>> @@ -49,14 +58,19 @@ OBJECT_DECLARE_SIMPLE_TYPE(ViaPMState, VIA_PM)
>> 
>> struct ViaPMState {
>>     PCIDevice dev;
>> +
>>     MemoryRegion io;
>>     ACPIREGS ar;
>> -    APMState apm;
>> +    uint16_t gbl_en;
>> +    uint16_t gbl_ctl;
>> +    uint8_t smi_cmd;
>> +
>>     PMSMBus smb;
>> 
>>     Notifier powerdown_notifier;
>> 
>>     qemu_irq sci_irq;
>> +    qemu_irq smi_irq;
>> };
>> 
>> static void pm_io_space_update(ViaPMState *s)
>> @@ -90,7 +104,7 @@ static int vmstate_acpi_post_load(void *opaque, int 
>> version_id)
>> 
>> static const VMStateDescription vmstate_acpi = {
>>     .name = "vt82c686b_pm",
>> -    .version_id = 1,
>> +    .version_id = 2,
>>     .minimum_version_id = 1,
>>     .post_load = vmstate_acpi_post_load,
>>     .fields = (VMStateField[]) {
>> @@ -98,9 +112,11 @@ static const VMStateDescription vmstate_acpi = {
>>         VMSTATE_UINT16(ar.pm1.evt.sts, ViaPMState),
>>         VMSTATE_UINT16(ar.pm1.evt.en, ViaPMState),
>>         VMSTATE_UINT16(ar.pm1.cnt.cnt, ViaPMState),
>> -        VMSTATE_STRUCT(apm, ViaPMState, 0, vmstate_apm, APMState),
>>         VMSTATE_TIMER_PTR(ar.tmr.timer, ViaPMState),
>>         VMSTATE_INT64(ar.tmr.overflow_time, ViaPMState),
>> +        VMSTATE_UINT16(gbl_en, ViaPMState),
>> +        VMSTATE_UINT16(gbl_ctl, ViaPMState),
>> +        VMSTATE_UINT8(smi_cmd, ViaPMState),
>>         VMSTATE_END_OF_LIST()
>>     }
>> };
>> @@ -128,15 +144,75 @@ static void pm_write_config(PCIDevice *d, uint32_t 
>> addr, uint32_t val, int len)
>>     }
>> }
>> 
>> +static void via_pm_apm_ctrl_changed(ViaPMState *s, uint8_t val)
>> +{
>> +    s->smi_cmd = val;
>> +
>> +    if (s->gbl_en & VIA_PM_IO_GBLEN_SW_SMI_EN
>> +        && s->gbl_ctl & VIA_PM_IO_GBLCTL_SMI_EN
>> +        && !(s->gbl_ctl & VIA_PM_IO_GBLCTL_SMIIG
>> +             && s->gbl_ctl & VIA_PM_IO_GBLCTL_INSMI)) {
>> +        s->gbl_ctl |= VIA_PM_IO_GBLCTL_INSMI;
>> +
>> +        if (s->smi_irq) {
>> +            qemu_irq_raise(s->smi_irq);
>> +        }
>> +    }
>> +}
>> +
>> static void pm_io_write(void *op, hwaddr addr, uint64_t data, unsigned size)
>> {
>> +    ViaPMState *s = op;
>> +
>>     trace_via_pm_io_write(addr, data, size);
>> +
>> +    switch (addr) {
>> +    case VIA_PM_IO_GBLEN:
>> +        s->gbl_en = (s->gbl_en & 0xff00) | data;
>> +        break;
>> +    case VIA_PM_IO_GBLEN + 1:
>> +        s->gbl_en = (s->gbl_en & 0x00ff) | (data << 8);
>> +        break;
>> +    case VIA_PM_IO_GBLCTL:
>> +        s->gbl_ctl = (s->gbl_ctl & 0xff00) | data;
>> +        break;
>> +    case VIA_PM_IO_GBLCTL + 1:
>> +        data <<= 8;
>> +        data &= ~(s->gbl_ctl & VIA_PM_IO_GBLCTL_INSMI);
>> +        s->gbl_ctl = (s->gbl_ctl & 0x00ff) | data;
>> +        break;
>> +    case VIA_PM_IO_SMI_CMD:
>> +        via_pm_apm_ctrl_changed(s, data);
>> +        break;
>> +    }
>> }
>> 
>> static uint64_t pm_io_read(void *op, hwaddr addr, unsigned size)
>> {
>> -    trace_via_pm_io_read(addr, 0, size);
>> -    return 0;
>> +    ViaPMState *s = op;
>> +    uint64_t data = 0;
>> +
>> +    switch (addr) {
>> +    case VIA_PM_IO_GBLEN:
>> +        data = s->gbl_en & 0xff;
>> +        break;
>> +    case VIA_PM_IO_GBLEN + 1:
>> +        data = s->gbl_en >> 8;
>> +        break;
>> +    case VIA_PM_IO_GBLCTL:
>> +        data = s->gbl_ctl & 0xff;
>> +        break;
>> +    case VIA_PM_IO_GBLCTL + 1:
>> +        data = (s->gbl_ctl >> 8) & 0xd;
>> +        break;
>> +    case VIA_PM_IO_SMI_CMD:
>> +        data = s->smi_cmd;
>> +        break;
>> +    }
>> +
>> +    trace_via_pm_io_read(addr, data, size);
>> +
>> +    return data;
>> }
>> 
>> static const MemoryRegionOps pm_io_ops = {
>> @@ -166,6 +242,10 @@ static void via_pm_reset(DeviceState *d)
>>     /* SMBus IO base */
>>     pci_set_long(s->dev.config + 0x90, 1);
>> 
>> +    s->gbl_en = 0;
>> +    s->gbl_ctl = VIA_PM_IO_GBLCTL_SMIIG;
>> +    s->smi_cmd = 0;
>> +
>>     acpi_pm1_evt_reset(&s->ar);
>>     acpi_pm1_cnt_reset(&s->ar);
>>     acpi_pm_tmr_reset(&s->ar);
>> @@ -194,8 +274,6 @@ static void via_pm_realize(PCIDevice *dev, Error **errp)
>>     memory_region_add_subregion(pci_address_space_io(dev), 0, &s->smb.io);
>>     memory_region_set_enabled(&s->smb.io, false);
>> 
>> -    apm_init(dev, &s->apm, NULL, s);
>> -
>>     memory_region_init_io(&s->io, OBJECT(dev), &pm_io_ops, s, "via-pm", 128);
>>     memory_region_add_subregion(pci_address_space_io(dev), 0, &s->io);
>>     memory_region_set_enabled(&s->io, false);
>> @@ -214,6 +292,7 @@ static void via_pm_init(Object *obj)
>>     ViaPMState *s = VIA_PM(obj);
>> 
>>     qdev_init_gpio_out_named(DEVICE(obj), &s->sci_irq, "sci", 1);
>> +    qdev_init_gpio_out_named(DEVICE(obj), &s->smi_irq, "smi-irq", 1);
>> }
>> 
>> typedef struct via_pm_init_info {
>> 

Reply via email to