qemu-arm
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-arm] [Qemu-devel] [PATCH 5/9] pc: acpi: isolate FADT specific


From: Igor Mammedov
Subject: Re: [Qemu-arm] [Qemu-devel] [PATCH 5/9] pc: acpi: isolate FADT specific data into AcpiFadtData structure
Date: Tue, 27 Feb 2018 16:44:24 +0100

On Tue, 27 Feb 2018 14:47:16 +0100
Auger Eric <address@hidden> wrote:

> Hi Igor,
> 
> On 22/02/18 13:42, Igor Mammedov wrote:
> > move FADT data initialization out of fadt_setup() into dedicated
> > init_fadt_data() that will set common for pc/q35 values in
> > AcpiFadtData structure and acpi_get_pm_info() will complement
> > it with pc/q35 specific values initialization.  
> acpi_get_pm_info only adds reset stuff + version info on top of
> previously initialized common data, right?
yep

> > That will allow to get rid of fadt_setup() and generalize
> > build_fadt() so it could be easily extended for rev5 and
> > reused by ARM target.
> > 
> > While at it also move facs/dsdt/xdsdt offsets from build_fadt()
> > arg list into AcpiFadtData, as they belong to the same dataset.
> > 
> > Signed-off-by: Igor Mammedov <address@hidden>
> > ---
> >  include/hw/acpi/acpi-defs.h |  28 ++++++
> >  hw/i386/acpi-build.c        | 204 
> > ++++++++++++++++++++++++--------------------
> >  2 files changed, 138 insertions(+), 94 deletions(-)
> > 
> > diff --git a/include/hw/acpi/acpi-defs.h b/include/hw/acpi/acpi-defs.h
> > index 9942bc5..e0accc4 100644
> > --- a/include/hw/acpi/acpi-defs.h
> > +++ b/include/hw/acpi/acpi-defs.h
> > @@ -175,6 +175,34 @@ struct AcpiFadtDescriptorRev5_1 {
> >  
> >  typedef struct AcpiFadtDescriptorRev5_1 AcpiFadtDescriptorRev5_1;
> >  
> > +typedef struct AcpiFadtData {
> > +    struct AcpiGenericAddress pm1_cnt;   /* PM1a_CNT_BLK */  
> Any reason why we don't use the same field names as in
> AcpiFadtDescriptorRev3?
I'll amend it on respin as you suggest.

> 
> for instance pm1a_cnt?
> > +    struct AcpiGenericAddress pm1_evt;   /* PM1a_EVT_BLK */  
> pm1a_evt?
> > +    struct AcpiGenericAddress pm_tmr;    /* PM_TMR_BLK */
> > +    struct AcpiGenericAddress gpe0_blk;  /* GPE0_BLK */
> > +    struct AcpiGenericAddress reset_reg; /* RESET_REG */
> > +    uint8_t reset_val;         /* RESET_VALUE */
> > +    uint8_t  rev;              /* Revision */
> > +    uint32_t flags;            /* Flags */
> > +    uint32_t smi_cmd;          /* SMI_CMD */
> > +    uint16_t sci_int;          /* SCI_INT */
> > +    uint8_t  int_model;        /* INT_MODEL */
> > +    uint8_t  acpi_enable_cmd;  /* ACPI_ENABLE */
> > +    uint8_t  acpi_disable_cmd; /* ACPI_DISABLE */
> > +    uint8_t  rtc_century;      /* CENTURY */
> > +    uint16_t c2_latency;       /* P_LVL2_LAT */  
> same?
> > +    uint16_t c3_latency;       /* P_LVL3_LAT */
> > +
> > +    /*
> > +     * respective tables offsets within ACPI_BUILD_TABLE_FILE,
> > +     * NULL if table doesn't exist (in that case field's value
> > +     * won't be patched by linker and will be kept set to 0)
> > +     */
> > +    unsigned *facs_tbl_offset; /* FACS offset in */
> > +    unsigned *dsdt_tbl_offset;
> > +    unsigned *xdsdt_tbl_offset;
> > +} AcpiFadtData;
> > +
> >  #define ACPI_FADT_ARM_PSCI_COMPLIANT  (1 << 0)
> >  #define ACPI_FADT_ARM_PSCI_USE_HVC    (1 << 1)
> >  
> > diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> > index b85fefe..706ba35 100644
> > --- a/hw/i386/acpi-build.c
> > +++ b/hw/i386/acpi-build.c
> > @@ -91,17 +91,11 @@ typedef struct AcpiMcfgInfo {
> >  } AcpiMcfgInfo;
> >  
> >  typedef struct AcpiPmInfo {
> > -    bool force_rev1_fadt;
> >      bool s3_disabled;
> >      bool s4_disabled;
> >      bool pcihp_bridge_en;
> >      uint8_t s4_val;
> > -    uint16_t sci_int;
> > -    uint8_t acpi_enable_cmd;
> > -    uint8_t acpi_disable_cmd;
> > -    uint32_t gpe0_blk;
> > -    uint32_t gpe0_blk_len;
> > -    uint32_t io_base;
> > +    AcpiFadtData fadt;
> >      uint16_t cpu_hp_io_base;
> >      uint16_t pcihp_io_base;
> >      uint16_t pcihp_io_len;
> > @@ -124,20 +118,60 @@ typedef struct AcpiBuildPciBusHotplugState {
> >      bool pcihp_bridge_en;
> >  } AcpiBuildPciBusHotplugState;
> >  
> > +#define ACPI_PORT_SMI_CMD           0x00b2 /* TODO: this is APM_CNT_IOPORT 
> > */  
> Can't we take benefit of this series to move that define in hw/isa/apm.h?
> > +
> > +static void init_fadt_data(Object *o, AcpiFadtData *data)
> > +{
> > +    uint32_t io = object_property_get_uint(o, ACPI_PM_PROP_PM_IO_BASE, 
> > NULL);
> > +    AmlAddressSpace as = AML_AS_SYSTEM_IO;
> > +    AcpiFadtData fadt = {
> > +        .rev = 3,
> > +        .flags =
> > +            (1 << ACPI_FADT_F_WBINVD) |
> > +            (1 << ACPI_FADT_F_PROC_C1) |
> > +            (1 << ACPI_FADT_F_SLP_BUTTON) |
> > +            (1 << ACPI_FADT_F_RTC_S4) |
> > +            (1 << ACPI_FADT_F_USE_PLATFORM_CLOCK) |
> > +            /* APIC destination mode ("Flat Logical") has an upper limit 
> > of 8
> > +             * CPUs for more than 8 CPUs, "Clustered Logical" mode has to 
> > be
> > +             * used
> > +             */
> > +            ((max_cpus > 8) ? (1 << ACPI_FADT_F_FORCE_APIC_CLUSTER_MODEL) 
> > : 0),
> > +        .int_model = 1 /* Multiple APIC */,
> > +        .rtc_century = RTC_CENTURY,
> > +        .c2_latency = 0xfff /* C2 state not supported */,
> > +        .c3_latency = 0xfff /* C3 state not supported */,
> > +        .smi_cmd = ACPI_PORT_SMI_CMD,
> > +        .sci_int = object_property_get_uint(o, ACPI_PM_PROP_SCI_INT, NULL),
> > +        .acpi_enable_cmd =
> > +            object_property_get_uint(o, ACPI_PM_PROP_ACPI_ENABLE_CMD, 
> > NULL),
> > +        .acpi_disable_cmd =
> > +            object_property_get_uint(o, ACPI_PM_PROP_ACPI_DISABLE_CMD, 
> > NULL),
> > +        .pm1_evt = { .space_id = as, .bit_width = 4 * 8, .address = io },
> > +        .pm1_cnt = { .space_id = as, .bit_width = 2 * 8, .address = io + 
> > 0x04 },
> > +        .pm_tmr = { .space_id = as, .bit_width = 4 * 8, .address = io + 
> > 0x08 },
> > +        .gpe0_blk = { .space_id = as, .bit_width =
> > +            object_property_get_uint(o, ACPI_PM_PROP_GPE0_BLK_LEN, NULL) * 
> > 8,
> > +            .address = object_property_get_uint(o, ACPI_PM_PROP_GPE0_BLK, 
> > NULL)
> > +        },
> > +    };
> > +    *data = fadt;
> > +}
> > +
> >  static void acpi_get_pm_info(AcpiPmInfo *pm)
> >  {
> >      Object *piix = piix4_pm_find();
> >      Object *lpc = ich9_lpc_find();
> >      Object *obj = piix ? piix : lpc;
> >      QObject *o;
> > -
> > -    pm->force_rev1_fadt = false;
> >      pm->cpu_hp_io_base = 0;
> >      pm->pcihp_io_base = 0;
> >      pm->pcihp_io_len = 0;
> > +
> > +    init_fadt_data(obj, &pm->fadt);
> >      if (piix) {
> >          /* w2k requires FADT(rev1) or it won't boot, keep PC compatible */
> > -        pm->force_rev1_fadt = true;
> > +        pm->fadt.rev = 1;
> >          pm->cpu_hp_io_base = PIIX4_CPU_HOTPLUG_IO_BASE;
> >          pm->pcihp_io_base =
> >              object_property_get_uint(obj, ACPI_PCIHP_IO_BASE_PROP, NULL);
> > @@ -145,10 +179,19 @@ static void acpi_get_pm_info(AcpiPmInfo *pm)
> >              object_property_get_uint(obj, ACPI_PCIHP_IO_LEN_PROP, NULL);
> >      }
> >      if (lpc) {
> > +        struct AcpiGenericAddress r = { .space_id = AML_AS_SYSTEM_IO,
> > +            .bit_width = 8, .address = ICH9_RST_CNT_IOPORT };
> > +        pm->fadt.reset_reg = r;
> > +        pm->fadt.reset_val = 0xf;
> > +        pm->fadt.flags |= 1 << ACPI_FADT_F_RESET_REG_SUP;
> >          pm->cpu_hp_io_base = ICH9_CPU_HOTPLUG_IO_BASE;  
> Wouldn't it be possible to pass an other parameter to init_fadt_data()
> to tell whether we are in pc or q35 or the target rev and do those
> initializations there?
It's possible but I wanted to keep pc/q35 specific pieces explicitly
split from common data initialization as personally for me this way
it's easier to see difference (i.e. there is no need to jump into 
init_fadt_data()).

Perhaps I should rename init_fadt_data() to init_common_fadt_data().


> >      }
> >      assert(obj);
> >  
> > +    /* The above need not be conditional on machine type because the reset 
> > port
> > +     * happens to be the same on PIIX (pc) and ICH9 (q35). */
> > +    QEMU_BUILD_BUG_ON(ICH9_RST_CNT_IOPORT != RCR_IOPORT);
> > +
> >      /* Fill in optional s3/s4 related properties */
> >      o = object_property_get_qobject(obj, ACPI_PM_PROP_S3_DISABLED, NULL);
> >      if (o) {
> > @@ -172,22 +215,6 @@ static void acpi_get_pm_info(AcpiPmInfo *pm)
> >      }
> >      qobject_decref(o);
> >  
> > -    /* Fill in mandatory properties */
> > -    pm->sci_int = object_property_get_uint(obj, ACPI_PM_PROP_SCI_INT, 
> > NULL);
> > -
> > -    pm->acpi_enable_cmd = object_property_get_uint(obj,
> > -                                                   
> > ACPI_PM_PROP_ACPI_ENABLE_CMD,
> > -                                                   NULL);
> > -    pm->acpi_disable_cmd =
> > -        object_property_get_uint(obj,
> > -                                 ACPI_PM_PROP_ACPI_DISABLE_CMD,
> > -                                 NULL);
> > -    pm->io_base = object_property_get_uint(obj, ACPI_PM_PROP_PM_IO_BASE,
> > -                                           NULL);
> > -    pm->gpe0_blk = object_property_get_uint(obj, ACPI_PM_PROP_GPE0_BLK,
> > -                                            NULL);
> > -    pm->gpe0_blk_len = object_property_get_uint(obj, 
> > ACPI_PM_PROP_GPE0_BLK_LEN,
> > -                                                NULL);
> >      pm->pcihp_bridge_en =
> >          object_property_get_bool(obj, 
> > "acpi-pci-hotplug-with-bridge-support",
> >                                   NULL);
> > @@ -255,8 +282,6 @@ static void acpi_get_pci_holes(Range *hole, Range 
> > *hole64)
> >                                                 NULL));
> >  }
> >  
> > -#define ACPI_PORT_SMI_CMD           0x00b2 /* TODO: this is APM_CNT_IOPORT 
> > */
> > -
> >  static void acpi_align_size(GArray *blob, unsigned align)
> >  {
> >      /* Align size to multiple of given size. This reduces the chance
> > @@ -275,73 +300,53 @@ build_facs(GArray *table_data, BIOSLinker *linker)
> >  }
> >  
> >  /* Load chipset information in FADT */
> > -static void fadt_setup(AcpiFadtDescriptorRev3 *fadt, AcpiPmInfo *pm)
> > +static void fadt_setup(AcpiFadtDescriptorRev3 *fadt, AcpiFadtData f)
> >  {
> > -    fadt->model = 1;
> > +    fadt->model = f.int_model;
> >      fadt->reserved1 = 0;
> > -    fadt->sci_int = cpu_to_le16(pm->sci_int);
> > -    fadt->smi_cmd = cpu_to_le32(ACPI_PORT_SMI_CMD);
> > -    fadt->acpi_enable = pm->acpi_enable_cmd;
> > -    fadt->acpi_disable = pm->acpi_disable_cmd;
> > +    fadt->sci_int = cpu_to_le16(f.sci_int);
> > +    fadt->smi_cmd = cpu_to_le32(f.smi_cmd);
> > +    fadt->acpi_enable = f.acpi_enable_cmd;
> > +    fadt->acpi_disable = f.acpi_disable_cmd;
> >      /* EVT, CNT, TMR offset matches hw/acpi/core.c */
> > -    fadt->pm1a_evt_blk = cpu_to_le32(pm->io_base);
> > -    fadt->pm1a_cnt_blk = cpu_to_le32(pm->io_base + 0x04);
> > -    fadt->pm_tmr_blk = cpu_to_le32(pm->io_base + 0x08);
> > -    fadt->gpe0_blk = cpu_to_le32(pm->gpe0_blk);
> > +    fadt->pm1a_evt_blk = cpu_to_le32(f.pm1_evt.address);
> > +    fadt->pm1a_cnt_blk = cpu_to_le32(f.pm1_cnt.address);
> > +    fadt->pm_tmr_blk = cpu_to_le32(f.pm_tmr.address);
> > +    fadt->gpe0_blk = cpu_to_le32(f.gpe0_blk.address);
> >      /* EVT, CNT, TMR length matches hw/acpi/core.c */
> > -    fadt->pm1_evt_len = 4;
> > -    fadt->pm1_cnt_len = 2;
> > -    fadt->pm_tmr_len = 4;
> > -    fadt->gpe0_blk_len = pm->gpe0_blk_len;
> > -    fadt->plvl2_lat = cpu_to_le16(0xfff); /* C2 state not supported */
> > -    fadt->plvl3_lat = cpu_to_le16(0xfff); /* C3 state not supported */
> > -    fadt->flags = cpu_to_le32((1 << ACPI_FADT_F_WBINVD) |
> > -                              (1 << ACPI_FADT_F_PROC_C1) |
> > -                              (1 << ACPI_FADT_F_SLP_BUTTON) |
> > -                              (1 << ACPI_FADT_F_RTC_S4));
> > -    fadt->flags |= cpu_to_le32(1 << ACPI_FADT_F_USE_PLATFORM_CLOCK);
> > -    /* APIC destination mode ("Flat Logical") has an upper limit of 8 CPUs
> > -     * For more than 8 CPUs, "Clustered Logical" mode has to be used
> > -     */
> > -    if (max_cpus > 8) {
> > -        fadt->flags |= cpu_to_le32(1 << 
> > ACPI_FADT_F_FORCE_APIC_CLUSTER_MODEL);
> > -    }
> > -    fadt->century = RTC_CENTURY;
> > -    if (pm->force_rev1_fadt) {
> > +    fadt->pm1_evt_len = f.pm1_evt.bit_width / 8;
> > +    fadt->pm1_cnt_len = f.pm1_cnt.bit_width / 8;
> > +    fadt->pm_tmr_len = f.pm_tmr.bit_width / 8;
> > +    fadt->gpe0_blk_len = f.gpe0_blk.bit_width / 8;
> > +    fadt->plvl2_lat = cpu_to_le16(f.c2_latency);
> > +    fadt->plvl3_lat = cpu_to_le16(f.c3_latency);
> > +    fadt->flags = cpu_to_le32(f.flags);
> > +    fadt->century = f.rtc_century;
> > +    if (f.rev == 1) {
> >          return;
> >      }
> >  
> > -    fadt->flags |= cpu_to_le32(1 << ACPI_FADT_F_RESET_REG_SUP);
> > -    fadt->reset_value = 0xf;
> > -    fadt->reset_register.space_id = AML_SYSTEM_IO;
> > -    fadt->reset_register.bit_width = 8;
> > -    fadt->reset_register.address = cpu_to_le64(ICH9_RST_CNT_IOPORT);
> > -    /* The above need not be conditional on machine type because the reset 
> > port
> > -     * happens to be the same on PIIX (pc) and ICH9 (q35). */
> > -    QEMU_BUILD_BUG_ON(ICH9_RST_CNT_IOPORT != RCR_IOPORT);
> > +    fadt->reset_value = f.reset_val;
> > +    fadt->reset_register = f.reset_reg;
> > +    fadt->reset_register.address = cpu_to_le64(f.reset_reg.address);
> >  
> > -    fadt->xpm1a_event_block.space_id = AML_SYSTEM_IO;
> > -    fadt->xpm1a_event_block.bit_width = fadt->pm1_evt_len * 8;
> > -    fadt->xpm1a_event_block.address = cpu_to_le64(pm->io_base);
> > +    fadt->xpm1a_event_block = f.pm1_evt;
> > +    fadt->xpm1a_event_block.address = cpu_to_le64(f.pm1_evt.address);
> >  
> > -    fadt->xpm1a_control_block.space_id = AML_SYSTEM_IO;
> > -    fadt->xpm1a_control_block.bit_width = fadt->pm1_cnt_len * 8;
> > -    fadt->xpm1a_control_block.address = cpu_to_le64(pm->io_base + 0x4);
> > +    fadt->xpm1a_control_block = f.pm1_cnt;
> > +    fadt->xpm1a_control_block.address = cpu_to_le64(f.pm1_cnt.address);
> >  
> > -    fadt->xpm_timer_block.space_id = AML_SYSTEM_IO;
> > -    fadt->xpm_timer_block.bit_width = fadt->pm_tmr_len * 8;
> > -    fadt->xpm_timer_block.address = cpu_to_le64(pm->io_base + 0x8);
> > +    fadt->xpm_timer_block = f.pm_tmr;
> > +    fadt->xpm_timer_block.address = cpu_to_le64(f.pm_tmr.address);
> >  
> > -    fadt->xgpe0_block.space_id = AML_SYSTEM_IO;
> > -    fadt->xgpe0_block.bit_width = pm->gpe0_blk_len * 8;
> > -    fadt->xgpe0_block.address = cpu_to_le64(pm->gpe0_blk);
> > +    fadt->xgpe0_block = f.gpe0_blk;
> > +    fadt->xgpe0_block.address = cpu_to_le64(f.gpe0_blk.address);
> >  }
> >  
> >  
> >  /* FADT */
> >  static void
> > -build_fadt(GArray *table_data, BIOSLinker *linker, AcpiPmInfo *pm,
> > -           unsigned facs_tbl_offset, unsigned dsdt_tbl_offset,
> > +build_fadt(GArray *table_data, BIOSLinker *linker, AcpiFadtData *f,
> >             const char *oem_id, const char *oem_table_id)
> >  {
> >      AcpiFadtDescriptorRev3 *fadt = acpi_data_push(table_data, 
> > sizeof(*fadt));
> > @@ -349,29 +354,32 @@ build_fadt(GArray *table_data, BIOSLinker *linker, 
> > AcpiPmInfo *pm,
> >      unsigned dsdt_entry_offset = (char *)&fadt->dsdt - table_data->data;
> >      unsigned xdsdt_entry_offset = (char *)&fadt->x_dsdt - table_data->data;
> >      int fadt_size = sizeof(*fadt);
> > -    int rev = 3;
> >  
> >      /* FACS address to be filled by Guest linker */
> > -    bios_linker_loader_add_pointer(linker,
> > -        ACPI_BUILD_TABLE_FILE, fw_ctrl_offset, sizeof(fadt->firmware_ctrl),
> > -        ACPI_BUILD_TABLE_FILE, facs_tbl_offset);
> > +    if (f->facs_tbl_offset) {  
> this test was not there originally. How does it relate to above changes?

[...]
> > +    if (f->dsdt_tbl_offset) {  
> same
I guess it is sort of slipped in from (7/9) patch,
as this fields can be 0 and don't need dynamic patching.

Theoretically facs/dsdt could be 0 for x86 too if we drop support
for 32bit guests (which isn't going to happen).

I can move it to 7/9 which moves build_fadt into generic code from x86 specific,
which is more appropriate place for it.


> > +        bios_linker_loader_add_pointer(linker,
> > +            ACPI_BUILD_TABLE_FILE, dsdt_entry_offset, sizeof(fadt->dsdt),
> > +            ACPI_BUILD_TABLE_FILE, *f->dsdt_tbl_offset);
> > +    }
> > +    if (f->rev == 1) {
> >          fadt_size = offsetof(typeof(*fadt), reset_register);
> > -    } else {
> > +    } else if (f->xdsdt_tbl_offset) {
> >          bios_linker_loader_add_pointer(linker,
> >              ACPI_BUILD_TABLE_FILE, xdsdt_entry_offset, 
> > sizeof(fadt->x_dsdt),
> > -            ACPI_BUILD_TABLE_FILE, dsdt_tbl_offset);
> > +            ACPI_BUILD_TABLE_FILE, *f->xdsdt_tbl_offset);
> >      }
> >  
> >      build_header(linker, table_data,
> > -                 (void *)fadt, "FACP", fadt_size, rev, oem_id, 
> > oem_table_id);
> > +                (void *)fadt, "FACP", fadt_size, f->rev,
> > +                oem_id, oem_table_id);
> >  }
> >  
> >  void pc_madt_cpu_entry(AcpiDeviceIf *adev, int uid,
> > @@ -2051,7 +2059,12 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
> >      aml_append(dev, aml_name_decl("_STA", aml_int(0xB)));
> >      crs = aml_resource_template();
> >      aml_append(crs,
> > -        aml_io(AML_DECODE16, pm->gpe0_blk, pm->gpe0_blk, 1, 
> > pm->gpe0_blk_len)
> > +        aml_io(
> > +               AML_DECODE16,
> > +               pm->fadt.gpe0_blk.address,
> > +               pm->fadt.gpe0_blk.address,
> > +               1,
> > +               pm->fadt.gpe0_blk.bit_width / 8)
> >      );
> >      aml_append(dev, aml_name_decl("_CRS", crs));
> >      aml_append(scope, dev);
> > @@ -2698,7 +2711,10 @@ void acpi_build(AcpiBuildTables *tables, 
> > MachineState *machine)
> >      /* ACPI tables pointed to by RSDT */
> >      fadt = tables_blob->len;
> >      acpi_add_table(table_offsets, tables_blob);
> > -    build_fadt(tables_blob, tables->linker, &pm, facs, dsdt,
> > +    pm.fadt.facs_tbl_offset = &facs;
> > +    pm.fadt.dsdt_tbl_offset = &dsdt;
> > +    pm.fadt.xdsdt_tbl_offset = &dsdt;
> > +    build_fadt(tables_blob, tables->linker, &pm.fadt,
> >                 slic_oem.id, slic_oem.table_id);
> >      aml_len += tables_blob->len - fadt;
> >  
> >   
> Otherwise looks good to me.
> 
> Thanks
> 
> Eric




reply via email to

[Prev in Thread] Current Thread [Next in Thread]