All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Michael S. Tsirkin" <mst@redhat.com>
To: Eric DeVolder <eric.devolder@oracle.com>
Cc: berrange@redhat.com, ehabkost@redhat.com, konrad.wilk@oracle.com,
	qemu-devel@nongnu.org, pbonzini@redhat.com, ani@anisinha.ca,
	imammedo@redhat.com, boris.ostrovsky@oracle.com, rth@twiddle.net
Subject: Re: [PATCH v10 06/10] ACPI ERST: build the ACPI ERST table
Date: Mon, 13 Dec 2021 19:05:02 -0500	[thread overview]
Message-ID: <20211213185833-mutt-send-email-mst@kernel.org> (raw)
In-Reply-To: <21c92605-8039-974b-7f62-fb1d22e4a206@oracle.com>

On Mon, Dec 13, 2021 at 04:02:26PM -0600, Eric DeVolder wrote:
> Michael,
> Thanks for reviewing! Inline responses below.
> eric
> 
> On 12/12/21 16:56, Michael S. Tsirkin wrote:
> > On Thu, Dec 09, 2021 at 12:57:31PM -0500, Eric DeVolder wrote:
> > > This builds the ACPI ERST table to inform OSPM how to communicate
> > > with the acpi-erst device.
> > > 
> > > Signed-off-by: Eric DeVolder <eric.devolder@oracle.com>
> > > ---
> > >   hw/acpi/erst.c | 241 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> > >   1 file changed, 241 insertions(+)
> > > 
> > > diff --git a/hw/acpi/erst.c b/hw/acpi/erst.c
> > > index 81f5435..753425a 100644
> > > --- a/hw/acpi/erst.c
> > > +++ b/hw/acpi/erst.c
> > > @@ -711,6 +711,247 @@ static const MemoryRegionOps erst_reg_ops = {
> > >       .endianness = DEVICE_NATIVE_ENDIAN,
> > >   };
> > > +
> > > +/*******************************************************************/
> > > +/*******************************************************************/
> > > +
> > > +/* ACPI 4.0: Table 17-19 Serialization Instructions */
> > > +#define INST_READ_REGISTER                 0x00
> > > +#define INST_READ_REGISTER_VALUE           0x01
> > > +#define INST_WRITE_REGISTER                0x02
> > > +#define INST_WRITE_REGISTER_VALUE          0x03
> > > +#define INST_NOOP                          0x04
> > > +#define INST_LOAD_VAR1                     0x05
> > > +#define INST_LOAD_VAR2                     0x06
> > > +#define INST_STORE_VAR1                    0x07
> > > +#define INST_ADD                           0x08
> > > +#define INST_SUBTRACT                      0x09
> > > +#define INST_ADD_VALUE                     0x0A
> > > +#define INST_SUBTRACT_VALUE                0x0B
> > > +#define INST_STALL                         0x0C
> > > +#define INST_STALL_WHILE_TRUE              0x0D
> > > +#define INST_SKIP_NEXT_INSTRUCTION_IF_TRUE 0x0E
> > > +#define INST_GOTO                          0x0F
> > > +#define INST_SET_SRC_ADDRESS_BASE          0x10
> > > +#define INST_SET_DST_ADDRESS_BASE          0x11
> > > +#define INST_MOVE_DATA                     0x12
> > > +
> > 
> > I would create wrappers for the specific uses that we do have. Leave the
> > rest alone.
> > You just use 4 of these right? And a bunch of parameters are
> > always the same. E.g. flags always 0, address always same.
> 
> If I understand correctly, I think you are suggesting making wrappers for
> the 4 in use (ie WRITE, WRITE_VALUE, READ, READ_VALUE). in an effort to
> simplify/hide the underlying call to
> build_serialization_instruction_entry(). OK, I'll do that.
> 
> > 
> > > +/* ACPI 4.0: 17.4.1.2 Serialization Instruction Entries */
> > > +static void build_serialization_instruction_entry(GArray *table_data,
> > > +    uint8_t serialization_action,
> > > +    uint8_t instruction,
> > > +    uint8_t flags,
> > > +    uint8_t register_bit_width,
> > 
> > maybe make it width in bytes, then you do not need a switch.
> 
> I can make it bytes, but the switch is still needed as the corresponding
> field is an encoding (ie 1,2,3,4 vs 1, 2, 4, 8).

So it's ffs basically?

> > 
> > > +    uint64_t register_address,
> > > +    uint64_t value,
> > > +    uint64_t mask)
> > > +{
> > > +    /* ACPI 4.0: Table 17-18 Serialization Instruction Entry */
> > > +    struct AcpiGenericAddress gas;
> > > +
> > > +    /* Serialization Action */
> > > +    build_append_int_noprefix(table_data, serialization_action, 1);
> > > +    /* Instruction */
> > > +    build_append_int_noprefix(table_data, instruction         , 1);
> > > +    /* Flags */
> > > +    build_append_int_noprefix(table_data, flags               , 1);
> > > +    /* Reserved */
> > > +    build_append_int_noprefix(table_data, 0                   , 1);
> > > +    /* Register Region */
> > > +    gas.space_id = AML_SYSTEM_MEMORY;
> > > +    gas.bit_width = register_bit_width;
> > > +    gas.bit_offset = 0;
> > > +    switch (register_bit_width) {
> > > +    case 8:
> > > +        gas.access_width = 1;
> > > +        break;
> > > +    case 16:
> > > +        gas.access_width = 2;
> > > +        break;
> > > +    case 32:
> > > +        gas.access_width = 3;
> > > +        break;
> > > +    case 64:
> > > +        gas.access_width = 4;
> > > +        break;
> > > +    default:
> > > +        gas.access_width = 0;
> > > +        break;
> > 
> > does this default actually work?
> I actually have no idea. But given that this is driven by code in this file,
> I'll set an assert there instead; this should never happen.
> 
> > 
> > > +    }
> > > +    gas.address = register_address;
> > > +    build_append_gas_from_struct(table_data, &gas);
> > > +    /* Value */
> > > +    build_append_int_noprefix(table_data, value  , 8);
> > > +    /* Mask */
> > > +    build_append_int_noprefix(table_data, mask   , 8);
> > > +}
> > > +
> > > +/* ACPI 4.0: 17.4.1 Serialization Action Table */
> > > +void build_erst(GArray *table_data, BIOSLinker *linker, Object *erst_dev,
> > > +    const char *oem_id, const char *oem_table_id)
> > > +{
> > > +    GArray *table_instruction_data;
> > > +    unsigned action;
> > > +    pcibus_t bar0, bar1;
> > > +    AcpiTable table = { .sig = "ERST", .rev = 1, .oem_id = oem_id,
> > > +                        .oem_table_id = oem_table_id };
> > > +
> > > +    bar0 = (pcibus_t)pci_get_bar_addr(PCI_DEVICE(erst_dev), 0);
> > > +    trace_acpi_erst_pci_bar_0(bar0);
> > > +    bar1 = (pcibus_t)pci_get_bar_addr(PCI_DEVICE(erst_dev), 1);
> > 
> > why do we need the cast here?
> > Also assignment at declaration point will be cleaner, won't it?
> Corrected; cast removed and assigned at declaration.
> > 
> > > +    trace_acpi_erst_pci_bar_1(bar1);
> > 
> > bar1 seems unused ... why do we bother with it just for trace?
> Corrected; bar1 not needed.
> 
> > 
> > > +
> > > +#define MASK8  0x00000000000000FFUL
> > > +#define MASK16 0x000000000000FFFFUL
> > > +#define MASK32 0x00000000FFFFFFFFUL
> > > +#define MASK64 0xFFFFFFFFFFFFFFFFUL
> > 
> > 
> > can't we just pass # of bytes?
> I could, but then I'd need a switch statement to convert to one of these
> masks. The full mask is embedded in the generic address structure.
> 
> Perhaps in the wrapper I can use width in bytes and the switch statement can
> producing the encoding and the mask...

we don't need a switch, mask is just (1ULL << (bytes * BITS_PER_BYTE - 1) << 1) - 1
encoding is just ffs(bytes)


> > 
> > > +
> > > +    /*
> > > +     * Serialization Action Table
> > > +     * The serialization action table must be generated first
> > > +     * so that its size can be known in order to populate the
> > > +     * Instruction Entry Count field.
> > > +     */
> > > +    table_instruction_data = g_array_new(FALSE, FALSE, sizeof(char));
> > > +
> > > +    /* Serialization Instruction Entries */
> > > +    action = ACTION_BEGIN_WRITE_OPERATION;
> > > +    build_serialization_instruction_entry(table_instruction_data,
> > > +        action, INST_WRITE_REGISTER_VALUE, 0, 32,
> > > +        bar0 + ERST_ACTION_OFFSET, action, MASK8);
> > > +
> > > +    action = ACTION_BEGIN_READ_OPERATION;
> > > +    build_serialization_instruction_entry(table_instruction_data,
> > > +        action, INST_WRITE_REGISTER_VALUE, 0, 32,
> > > +        bar0 + ERST_ACTION_OFFSET, action, MASK8);
> > > +
> > > +    action = ACTION_BEGIN_CLEAR_OPERATION;
> > > +    build_serialization_instruction_entry(table_instruction_data,
> > > +        action, INST_WRITE_REGISTER_VALUE, 0, 32,
> > > +        bar0 + ERST_ACTION_OFFSET, action, MASK8);
> > > +
> > > +    action = ACTION_END_OPERATION;
> > > +    build_serialization_instruction_entry(table_instruction_data,
> > > +        action, INST_WRITE_REGISTER_VALUE, 0, 32,
> > > +        bar0 + ERST_ACTION_OFFSET, action, MASK8);
> > > +
> > > +    action = ACTION_SET_RECORD_OFFSET;
> > > +    build_serialization_instruction_entry(table_instruction_data,
> > > +        action, INST_WRITE_REGISTER      , 0, 32,
> > > +        bar0 + ERST_VALUE_OFFSET , 0, MASK32);
> > > +    build_serialization_instruction_entry(table_instruction_data,
> > > +        action, INST_WRITE_REGISTER_VALUE, 0, 32,
> > > +        bar0 + ERST_ACTION_OFFSET, action, MASK8);
> > > +
> > > +    action = ACTION_EXECUTE_OPERATION;
> > > +    build_serialization_instruction_entry(table_instruction_data,
> > > +        action, INST_WRITE_REGISTER_VALUE, 0, 32,
> > > +        bar0 + ERST_VALUE_OFFSET , ERST_EXECUTE_OPERATION_MAGIC, MASK8);
> > > +    build_serialization_instruction_entry(table_instruction_data,
> > > +        action, INST_WRITE_REGISTER_VALUE, 0, 32,
> > > +        bar0 + ERST_ACTION_OFFSET, action, MASK8);
> > > +
> > > +    action = ACTION_CHECK_BUSY_STATUS;
> > > +    build_serialization_instruction_entry(table_instruction_data,
> > > +        action, INST_WRITE_REGISTER_VALUE, 0, 32,
> > > +        bar0 + ERST_ACTION_OFFSET, action, MASK8);
> > > +    build_serialization_instruction_entry(table_instruction_data,
> > > +        action, INST_READ_REGISTER_VALUE , 0, 32,
> > > +        bar0 + ERST_VALUE_OFFSET, 0x01, MASK8);
> > > +
> > > +    action = ACTION_GET_COMMAND_STATUS;
> > > +    build_serialization_instruction_entry(table_instruction_data,
> > > +        action, INST_WRITE_REGISTER_VALUE, 0, 32,
> > > +        bar0 + ERST_ACTION_OFFSET, action, MASK8);
> > > +    build_serialization_instruction_entry(table_instruction_data,
> > > +        action, INST_READ_REGISTER       , 0, 32,
> > > +        bar0 + ERST_VALUE_OFFSET, 0, MASK8);
> > > +
> > > +    action = ACTION_GET_RECORD_IDENTIFIER;
> > > +    build_serialization_instruction_entry(table_instruction_data,
> > > +        action, INST_WRITE_REGISTER_VALUE, 0, 32,
> > > +        bar0 + ERST_ACTION_OFFSET, action, MASK8);
> > > +    build_serialization_instruction_entry(table_instruction_data,
> > > +        action, INST_READ_REGISTER       , 0, 64,
> > > +        bar0 + ERST_VALUE_OFFSET, 0, MASK64);
> > > +
> > > +    action = ACTION_SET_RECORD_IDENTIFIER;
> > > +    build_serialization_instruction_entry(table_instruction_data,
> > > +        action, INST_WRITE_REGISTER      , 0, 64,
> > > +        bar0 + ERST_VALUE_OFFSET , 0, MASK64);
> > > +    build_serialization_instruction_entry(table_instruction_data,
> > > +        action, INST_WRITE_REGISTER_VALUE, 0, 32,
> > > +        bar0 + ERST_ACTION_OFFSET, action, MASK8);
> > > +
> > > +    action = ACTION_GET_RECORD_COUNT;
> > > +    build_serialization_instruction_entry(table_instruction_data,
> > > +        action, INST_WRITE_REGISTER_VALUE, 0, 32,
> > > +        bar0 + ERST_ACTION_OFFSET, action, MASK8);
> > > +    build_serialization_instruction_entry(table_instruction_data,
> > > +        action, INST_READ_REGISTER       , 0, 32,
> > > +        bar0 + ERST_VALUE_OFFSET, 0, MASK32);
> > > +
> > > +    action = ACTION_BEGIN_DUMMY_WRITE_OPERATION;
> > > +    build_serialization_instruction_entry(table_instruction_data,
> > > +        action, INST_WRITE_REGISTER_VALUE, 0, 32,
> > > +        bar0 + ERST_ACTION_OFFSET, action, MASK8);
> > > +
> > > +    action = ACTION_GET_ERROR_LOG_ADDRESS_RANGE;
> > > +    build_serialization_instruction_entry(table_instruction_data,
> > > +        action, INST_WRITE_REGISTER_VALUE, 0, 32,
> > > +        bar0 + ERST_ACTION_OFFSET, action, MASK8);
> > > +    build_serialization_instruction_entry(table_instruction_data,
> > > +        action, INST_READ_REGISTER       , 0, 64,
> > > +        bar0 + ERST_VALUE_OFFSET, 0, MASK64);
> > > +
> > > +    action = ACTION_GET_ERROR_LOG_ADDRESS_LENGTH;
> > > +    build_serialization_instruction_entry(table_instruction_data,
> > > +        action, INST_WRITE_REGISTER_VALUE, 0, 32,
> > > +        bar0 + ERST_ACTION_OFFSET, action, MASK8);
> > > +    build_serialization_instruction_entry(table_instruction_data,
> > > +        action, INST_READ_REGISTER       , 0, 64,
> > > +        bar0 + ERST_VALUE_OFFSET, 0, MASK32);
> > > +
> > > +    action = ACTION_GET_ERROR_LOG_ADDRESS_RANGE_ATTRIBUTES;
> > > +    build_serialization_instruction_entry(table_instruction_data,
> > > +        action, INST_WRITE_REGISTER_VALUE, 0, 32,
> > > +        bar0 + ERST_ACTION_OFFSET, action, MASK8);
> > > +    build_serialization_instruction_entry(table_instruction_data,
> > > +        action, INST_READ_REGISTER       , 0, 32,
> > > +        bar0 + ERST_VALUE_OFFSET, 0, MASK32);
> > > +
> > > +    action = ACTION_GET_EXECUTE_OPERATION_TIMINGS;
> > > +    build_serialization_instruction_entry(table_instruction_data,
> > > +        action, INST_WRITE_REGISTER_VALUE, 0, 32,
> > > +        bar0 + ERST_ACTION_OFFSET, action, MASK8);
> > > +    build_serialization_instruction_entry(table_instruction_data,
> > > +        action, INST_READ_REGISTER       , 0, 64,
> > > +        bar0 + ERST_VALUE_OFFSET, 0, MASK64);
> > > +
> > > +    /* Serialization Header */
> > > +    acpi_table_begin(&table, table_data);
> > > +
> > > +    /* Serialization Header Size */
> > > +    build_append_int_noprefix(table_data, 48, 4);
> > > +
> > > +    /* Reserved */
> > > +    build_append_int_noprefix(table_data,  0, 4);
> > > +
> > > +    /*
> > > +     * Instruction Entry Count
> > > +     * Each instruction entry is 32 bytes
> > > +     */
> > 
> > assert that it's a multiple of 32 maybe
> done!
> 
> > 
> > > +    build_append_int_noprefix(table_data,
> > > +        (table_instruction_data->len / 32), 4);
> > > +
> > > +    /* Serialization Instruction Entries */
> > > +    g_array_append_vals(table_data, table_instruction_data->data,
> > > +        table_instruction_data->len);
> > > +    g_array_free(table_instruction_data, TRUE);
> > > +
> > > +    acpi_table_end(linker, &table);
> > > +}
> > > +
> > >   /*******************************************************************/
> > >   /*******************************************************************/
> > >   static int erst_post_load(void *opaque, int version_id)
> > > -- 
> > > 1.8.3.1
> > 



  reply	other threads:[~2021-12-14  0:06 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-12-09 17:57 [PATCH v10 00/10] acpi: Error Record Serialization Table, ERST, support for QEMU Eric DeVolder
2021-12-09 17:57 ` [PATCH v10 01/10] ACPI ERST: bios-tables-test.c steps 1 and 2 Eric DeVolder
2021-12-09 17:57 ` [PATCH v10 02/10] ACPI ERST: specification for ERST support Eric DeVolder
2021-12-09 17:57 ` [PATCH v10 03/10] ACPI ERST: PCI device_id for ERST Eric DeVolder
2021-12-09 17:57 ` [PATCH v10 04/10] ACPI ERST: header file " Eric DeVolder
2021-12-09 17:57 ` [PATCH v10 05/10] ACPI ERST: support for ACPI ERST feature Eric DeVolder
2021-12-10 14:18   ` Ani Sinha
2021-12-09 17:57 ` [PATCH v10 06/10] ACPI ERST: build the ACPI ERST table Eric DeVolder
2021-12-12 13:43   ` Ani Sinha
2021-12-13 21:26     ` Eric DeVolder
2021-12-14  2:58       ` Ani Sinha
2021-12-14 18:12         ` Eric DeVolder
2021-12-15  3:22           ` Ani Sinha
2021-12-12 22:56   ` Michael S. Tsirkin
2021-12-13 22:02     ` Eric DeVolder
2021-12-14  0:05       ` Michael S. Tsirkin [this message]
2021-12-09 17:57 ` [PATCH v10 07/10] ACPI ERST: create ACPI ERST table for pc/x86 machines Eric DeVolder
2021-12-09 17:57 ` [PATCH v10 08/10] ACPI ERST: qtest for ERST Eric DeVolder
2021-12-09 17:57 ` [PATCH v10 09/10] ACPI ERST: bios-tables-test testcase Eric DeVolder
2021-12-09 17:57 ` [PATCH v10 10/10] ACPI ERST: step 6 of bios-tables-test.c Eric DeVolder

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=20211213185833-mutt-send-email-mst@kernel.org \
    --to=mst@redhat.com \
    --cc=ani@anisinha.ca \
    --cc=berrange@redhat.com \
    --cc=boris.ostrovsky@oracle.com \
    --cc=ehabkost@redhat.com \
    --cc=eric.devolder@oracle.com \
    --cc=imammedo@redhat.com \
    --cc=konrad.wilk@oracle.com \
    --cc=pbonzini@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=rth@twiddle.net \
    /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.