All of lore.kernel.org
 help / color / mirror / Atom feed
From: Eric DeVolder <eric.devolder@oracle.com>
To: "Michael S. Tsirkin" <mst@redhat.com>
Cc: berrange@redhat.com, ehabkost@redhat.com, konrad.wilk@oracle.com,
	qemu-devel@nongnu.org, pbonzini@redhat.com,
	Ani Sinha <ani@anisinha.ca>,
	imammedo@redhat.com, boris.ostrovsky@oracle.com, rth@twiddle.net
Subject: Re: [PATCH v14 06/10] ACPI ERST: build the ACPI ERST table
Date: Fri, 28 Jan 2022 10:01:18 -0600	[thread overview]
Message-ID: <db012849-b7ec-eecc-bf41-a6b211c021f0@oracle.com> (raw)
In-Reply-To: <20220128105311-mutt-send-email-mst@kernel.org>

Michael, thanks! See inline response below, please.
eric

On 1/28/22 09:54, Michael S. Tsirkin wrote:
> On Fri, Jan 28, 2022 at 09:11:41AM -0600, Eric DeVolder wrote:
>> Michael,
>> Thanks for examining this. Inline response below.
>> eric
>>
>> On 1/27/22 18:37, Michael S. Tsirkin wrote:
>>> On Thu, Jan 27, 2022 at 04:02:07PM -0600, Eric DeVolder wrote:
>>>> Ani,
>>>> Thanks for the RB! Inline responses below.
>>>> eric
>>>>
>>>> On 1/27/22 02:36, Ani Sinha wrote:
>>>>>
>>>>>
>>>>> On Wed, 26 Jan 2022, Eric DeVolder wrote:
>>>>>
>>>>>> This builds the ACPI ERST table to inform OSPM how to communicate
>>>>>> with the acpi-erst device.
>>>>>
>>>>> There might be more optimizations possible but I think we have messaged
>>>>> this code enough. We can further rework the code if needed in subsequent
>>>>> patches once this is pushed.
>>>>>
>>>>>>
>>>>>> Signed-off-by: Eric DeVolder <eric.devolder@oracle.com>
>>>>>
>>>>> with some minor comments,
>>>>>
>>>>> Reviewed-by: Ani Sinha <ani@anisinha.ca>
>>>>>
>>>>>>     hw/acpi/erst.c | 225 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>>>>>>     1 file changed, 225 insertions(+)
>>>>>>
>>>>>> diff --git a/hw/acpi/erst.c b/hw/acpi/erst.c
>>>>>> index fe9ba51..5d5a639 100644
>>>>>> --- a/hw/acpi/erst.c
>>>>>> +++ b/hw/acpi/erst.c
>>>>>> @@ -59,6 +59,27 @@
>>>>>>     #define STATUS_RECORD_STORE_EMPTY     0x04
>>>>>>     #define STATUS_RECORD_NOT_FOUND       0x05
>>>>>>
>>>>>> +/* 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
>>>>>> +
>>>>>>     /* UEFI 2.1: Appendix N Common Platform Error Record */
>>>>>>     #define UEFI_CPER_RECORD_MIN_SIZE 128U
>>>>>>     #define UEFI_CPER_RECORD_LENGTH_OFFSET 20U
>>>>>> @@ -172,6 +193,210 @@ typedef struct {
>>>>>>
>>>>>>     /*******************************************************************/
>>>>>>     /*******************************************************************/
>>>>>> +typedef struct {
>>>>>> +    GArray *table_data;
>>>>>> +    pcibus_t bar;
>>>>>> +    uint8_t instruction;
>>>>>> +    uint8_t flags;
>>>>>> +    uint8_t register_bit_width;
>>>>>> +    pcibus_t register_offset;
>>>>>> +} BuildSerializationInstructionEntry;
>>>>>> +
>>>>>> +/* ACPI 4.0: 17.4.1.2 Serialization Instruction Entries */
>>>>>> +static void build_serialization_instruction(
>>>>>> +    BuildSerializationInstructionEntry *e,
>>>>>> +    uint8_t serialization_action,
>>>>>> +    uint64_t value)
>>>>>> +{
>>>>>> +    /* ACPI 4.0: Table 17-18 Serialization Instruction Entry */
>>>>>> +    struct AcpiGenericAddress gas;
>>>>>> +    uint64_t mask;
>>>>>> +
>>>>>> +    /* Serialization Action */
>>>>>> +    build_append_int_noprefix(e->table_data, serialization_action, 1);
>>>>>> +    /* Instruction */
>>>>>> +    build_append_int_noprefix(e->table_data, e->instruction, 1);
>>>>>> +    /* Flags */
>>>>>> +    build_append_int_noprefix(e->table_data, e->flags, 1);
>>>>>> +    /* Reserved */
>>>>>> +    build_append_int_noprefix(e->table_data, 0, 1);
>>>>>> +    /* Register Region */
>>>>>> +    gas.space_id = AML_SYSTEM_MEMORY;
>>>>>> +    gas.bit_width = e->register_bit_width;
>>>>>> +    gas.bit_offset = 0;
>>>>>> +    gas.access_width = ctz32(e->register_bit_width) - 2;
>>>>>
>>>>> Should this be casted as unit8_t?
>>>> OK, done.
>>>>
>>>>>
>>>>>> +    gas.address = (uint64_t)(e->bar + e->register_offset);
>>>>>> +    build_append_gas_from_struct(e->table_data, &gas);
>>>>>> +    /* Value */
>>>>>> +    build_append_int_noprefix(e->table_data, value, 8);
>>>>>> +    /* Mask */
>>>>>> +    mask = (1ULL << (e->register_bit_width - 1) << 1) - 1;
>>>>>> +    build_append_int_noprefix(e->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)
>>>>>> +{
>>>>>> +    /*
>>>>>> +     * 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.
>>>>>> +     */
>>>>>> +    GArray *table_instruction_data = g_array_new(FALSE, FALSE, sizeof(char));
>>>>>> +    pcibus_t bar0 = pci_get_bar_addr(PCI_DEVICE(erst_dev), 0);
>>>>>> +    AcpiTable table = { .sig = "ERST", .rev = 1, .oem_id = oem_id,
>>>>>> +                        .oem_table_id = oem_table_id };
>>>>>> +    /* Contexts for the different ways ACTION and VALUE are accessed */
>>>>>> +    BuildSerializationInstructionEntry rd_value_32_val = {
>>>>>> +        .table_data = table_instruction_data,
>>>>>> +        .bar = bar0,
>>>>>> +        .instruction = INST_READ_REGISTER_VALUE,
>>>>>> +        .flags = 0,
>>>>>> +        .register_bit_width = 32,
>>>>>> +        .register_offset = ERST_VALUE_OFFSET,
>>>>>> +    };
>>>>>> +    BuildSerializationInstructionEntry rd_value_32 = {
>>>>>> +        .table_data = table_instruction_data,
>>>>>> +        .bar = bar0,
>>>>>> +        .instruction = INST_READ_REGISTER,
>>>>>> +        .flags = 0,
>>>>>> +        .register_bit_width = 32,
>>>>>> +        .register_offset = ERST_VALUE_OFFSET,
>>>>>> +    };
>>>>>> +    BuildSerializationInstructionEntry rd_value_64 = {
>>>>>> +        .table_data = table_instruction_data,
>>>>>> +        .bar = bar0,
>>>>>> +        .instruction = INST_READ_REGISTER,
>>>>>> +        .flags = 0,
>>>>>> +        .register_bit_width = 64,
>>>>>> +        .register_offset = ERST_VALUE_OFFSET,
>>>>>> +    };
>>>>>> +    BuildSerializationInstructionEntry wr_value_32_val = {
>>>>>> +        .table_data = table_instruction_data,
>>>>>> +        .bar = bar0,
>>>>>> +        .instruction = INST_WRITE_REGISTER_VALUE,
>>>>>> +        .flags = 0,
>>>>>> +        .register_bit_width = 32,
>>>>>> +        .register_offset = ERST_VALUE_OFFSET,
>>>>>> +    };
>>>>>> +    BuildSerializationInstructionEntry wr_value_32 = {
>>>>>> +        .table_data = table_instruction_data,
>>>>>> +        .bar = bar0,
>>>>>> +        .instruction = INST_WRITE_REGISTER,
>>>>>> +        .flags = 0,
>>>>>> +        .register_bit_width = 32,
>>>>>> +        .register_offset = ERST_VALUE_OFFSET,
>>>>>> +    };
>>>>>> +    BuildSerializationInstructionEntry wr_value_64 = {
>>>>>> +        .table_data = table_instruction_data,
>>>>>> +        .bar = bar0,
>>>>>> +        .instruction = INST_WRITE_REGISTER,
>>>>>> +        .flags = 0,
>>>>>> +        .register_bit_width = 64,
>>>>>> +        .register_offset = ERST_VALUE_OFFSET,
>>>>>> +    };
>>>>>> +    BuildSerializationInstructionEntry wr_action = {
>>>>>> +        .table_data = table_instruction_data,
>>>>>> +        .bar = bar0,
>>>>>> +        .instruction = INST_WRITE_REGISTER_VALUE,
>>>>>> +        .flags = 0,
>>>>>> +        .register_bit_width = 32,
>>>>>> +        .register_offset = ERST_ACTION_OFFSET,
>>>>>> +    };
>>>>>
>>>>> We can probably write a macro to simply generating these structs. I see
>>>>> .bar and .flags are the same in all structs. The .bit_width can be a param
>>>>> into the macro etc.
>>>> Agree, however the request was to NOT hide the use of local variables in
>>>> macros, so while .flags is always 0, .instruction, .register_bit_width and .register_offset
>>>> would be parameters, that leaves .table_data and .bar which just need the local
>>>> variables. Is the following acceptable (which hides the use of the local variables)?
>>>
>>> You can just use assignment:
>>>
>>>      BuildSerializationInstructionEntry entry = {
>>>          .table_data = table_instruction_data,
>>>          .bar = bar0,
>>>          .flags = 0,
>>>          .register_bit_width = 32,
>>>      };
>>>      BuildSerializationInstructionEntry rd_value_32_val = entry;
>>>      rd_value_32_val.action = INST_READ_REGISTER_VALUE;
>>>      rd_value_32_val.register_offset = ERST_ACTION_OFFSET;
>>>
>>> and so on.
>>> not sure it's worth it, it's just a couple of lines.
>>>
>>
>> OK, here is the equivalent using struct assignment, is this what you were after?
>>
>>      BuildSerializationInstructionEntry base = {
>>          .table_data = table_instruction_data,
>>          .bar = bar0,
>>          .instruction = INST_WRITE_REGISTER,
>>          .flags = 0,
>>          .register_bit_width = 32,
>>          .register_offset = ERST_VALUE_OFFSET,
>>      };
>>      BuildSerializationInstructionEntry rd_value_32_val = base;
>>      rd_value_32_val.instruction = INST_READ_REGISTER_VALUE;
>>      BuildSerializationInstructionEntry rd_value_32 = base;
>>      rd_value_32.instruction = INST_READ_REGISTER;
>>      BuildSerializationInstructionEntry rd_value_64 = base;
>>      rd_value_64.instruction = INST_READ_REGISTER;
>>      rd_value_64.register_bit_width = 64;
>>      BuildSerializationInstructionEntry wr_value_32_val = base;
>>      wr_value_32_val.instruction = INST_WRITE_REGISTER_VALUE;
>>      BuildSerializationInstructionEntry wr_value_32 = base;
>>      BuildSerializationInstructionEntry wr_value_64 = base;
>>      wr_value_64.register_bit_width = 64;
>>      BuildSerializationInstructionEntry wr_action = base;
>>      wr_action.instruction = INST_WRITE_REGISTER_VALUE;
>>      wr_action.register_offset = ERST_ACTION_OFFSET;
>>
> 
> That's what I described, yes. We should have some empty lines here I
> guess. I'm ok with the original one too, there's not too much
> duplication.

Are the blank lines referring to spacing out the setup of each of the 7 accesors?
If so, I could put a one line comment between each setup? Or is a blank line also
needed?

Is it OK to post v15 with the struct assignment approach? Or would you prefer the
explicit structs (which is what I think you mean by 'the original one')?

Thanks!
eric
> 
> 
>>
>>>
>>>
>>>> #define SERIALIZATIONINSTRUCTIONCTX(name, \
>>>>       inst, bit_width, offset) \
>>>>       BuildSerializationInstructionEntry name = { \
>>>>           .table_data = table_instruction_data, \
>>>>           .bar = bar0, \
>>>>           .instruction = inst, \
>>>>           .flags = 0, \
>>>>           .register_bit_width = bit_width, \
>>>>           .register_offset = offset, \
>>>>       }
>>>>       SERIALIZATIONINSTRUCTIONCTX(rd_value_32_val,
>>>>           INST_READ_REGISTER_VALUE, 32, ERST_VALUE_OFFSET);
>>>>       SERIALIZATIONINSTRUCTIONCTX(rd_value_32,
>>>>           INST_READ_REGISTER, 32, ERST_VALUE_OFFSET);
>>>>       SERIALIZATIONINSTRUCTIONCTX(rd_value_64,
>>>>           INST_READ_REGISTER, 64, ERST_VALUE_OFFSET);
>>>>       SERIALIZATIONINSTRUCTIONCTX(wr_value_32_val,
>>>>           INST_WRITE_REGISTER_VALUE, 32, ERST_VALUE_OFFSET);
>>>>       SERIALIZATIONINSTRUCTIONCTX(wr_value_32,
>>>>           INST_WRITE_REGISTER, 32, ERST_VALUE_OFFSET);
>>>>       SERIALIZATIONINSTRUCTIONCTX(wr_value_64,
>>>>           INST_WRITE_REGISTER, 64, ERST_VALUE_OFFSET);
>>>>       SERIALIZATIONINSTRUCTIONCTX(wr_action,
>>>>           INST_WRITE_REGISTER_VALUE, 32, ERST_ACTION_OFFSET);
>>>>
>>>> These are the 7 accessors needed.
>>>
>>> not at all sure this one is worth the macro mess.
>>
>> I'm hoping to produce a v15 with the style you want.
>> eric
>>
>>>
>>>>>
>>>>>> +    unsigned action;
>>>>>> +
>>>>>> +    trace_acpi_erst_pci_bar_0(bar0);
>>>>>> +
>>>>>> +    /* Serialization Instruction Entries */
>>>>>> +    action = ACTION_BEGIN_WRITE_OPERATION;
>>>>>> +    build_serialization_instruction(&wr_action, action, action);
>>>>>> +
>>>>>> +    action = ACTION_BEGIN_READ_OPERATION;
>>>>>> +    build_serialization_instruction(&wr_action, action, action);
>>>>>> +
>>>>>> +    action = ACTION_BEGIN_CLEAR_OPERATION;
>>>>>> +    build_serialization_instruction(&wr_action, action, action);
>>>>>> +
>>>>>> +    action = ACTION_END_OPERATION;
>>>>>> +    build_serialization_instruction(&wr_action, action, action);
>>>>>> +
>>>>>> +    action = ACTION_SET_RECORD_OFFSET;
>>>>>> +    build_serialization_instruction(&wr_value_32, action, 0);
>>>>>> +    build_serialization_instruction(&wr_action, action, action);
>>>>>> +
>>>>>> +    action = ACTION_EXECUTE_OPERATION;
>>>>>> +    build_serialization_instruction(&wr_value_32_val, action,
>>>>>> +        ERST_EXECUTE_OPERATION_MAGIC);
>>>>>> +    build_serialization_instruction(&wr_action, action, action);
>>>>>> +
>>>>>> +    action = ACTION_CHECK_BUSY_STATUS;
>>>>>> +    build_serialization_instruction(&wr_action, action, action);
>>>>>> +    build_serialization_instruction(&rd_value_32_val, action, 0x01);
>>>>>> +
>>>>>> +    action = ACTION_GET_COMMAND_STATUS;
>>>>>> +    build_serialization_instruction(&wr_action, action, action);
>>>>>> +    build_serialization_instruction(&rd_value_32, action, 0);
>>>>>> +
>>>>>> +    action = ACTION_GET_RECORD_IDENTIFIER;
>>>>>> +    build_serialization_instruction(&wr_action, action, action);
>>>>>> +    build_serialization_instruction(&rd_value_64, action, 0);
>>>>>> +
>>>>>> +    action = ACTION_SET_RECORD_IDENTIFIER;
>>>>>> +    build_serialization_instruction(&wr_value_64, action, 0);
>>>>>> +    build_serialization_instruction(&wr_action, action, action);
>>>>>> +
>>>>>> +    action = ACTION_GET_RECORD_COUNT;
>>>>>> +    build_serialization_instruction(&wr_action, action, action);
>>>>>> +    build_serialization_instruction(&rd_value_32, action, 0);
>>>>>> +
>>>>>> +    action = ACTION_BEGIN_DUMMY_WRITE_OPERATION;
>>>>>> +    build_serialization_instruction(&wr_action, action, action);
>>>>>> +
>>>>>> +    action = ACTION_GET_ERROR_LOG_ADDRESS_RANGE;
>>>>>> +    build_serialization_instruction(&wr_action, action, action);
>>>>>> +    build_serialization_instruction(&rd_value_64, action, 0);
>>>>>> +
>>>>>> +    action = ACTION_GET_ERROR_LOG_ADDRESS_LENGTH;
>>>>>> +    build_serialization_instruction(&wr_action, action, action);
>>>>>> +    build_serialization_instruction(&rd_value_64, action, 0);
>>>>>> +
>>>>>> +    action = ACTION_GET_ERROR_LOG_ADDRESS_RANGE_ATTRIBUTES;
>>>>>> +    build_serialization_instruction(&wr_action, action, action);
>>>>>> +    build_serialization_instruction(&rd_value_32, action, 0);
>>>>>> +
>>>>>> +    action = ACTION_GET_EXECUTE_OPERATION_TIMINGS;
>>>>>> +    build_serialization_instruction(&wr_action, action, action);
>>>>>> +    build_serialization_instruction(&rd_value_64, action, 0);
>>>>>> +
>>>>>> +    /* 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
>>>>>> +     */
>>>>>> +    g_assert((table_instruction_data->len) % 32 == 0);
>>>>>> +    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 uint8_t *get_nvram_ptr_by_index(ERSTDeviceState *s, unsigned index)
>>>>>>     {
>>>>>>         uint8_t *rc = NULL;
>>>>>> --
>>>>>> 1.8.3.1
>>>>>>
>>>>>>
>>>
> 


  reply	other threads:[~2022-01-28 17:27 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-01-26 16:28 [PATCH v14 00/10] acpi: Error Record Serialization Table, ERST, support for QEMU Eric DeVolder
2022-01-26 16:28 ` [PATCH v14 01/10] ACPI ERST: bios-tables-test.c steps 1 and 2 Eric DeVolder
2022-01-26 16:28 ` [PATCH v14 02/10] ACPI ERST: specification for ERST support Eric DeVolder
2022-01-26 16:28 ` [PATCH v14 03/10] ACPI ERST: PCI device_id for ERST Eric DeVolder
2022-01-26 16:28 ` [PATCH v14 04/10] ACPI ERST: header file " Eric DeVolder
2022-01-26 16:28 ` [PATCH v14 05/10] ACPI ERST: support for ACPI ERST feature Eric DeVolder
2022-01-26 16:28 ` [PATCH v14 06/10] ACPI ERST: build the ACPI ERST table Eric DeVolder
2022-01-27  8:36   ` Ani Sinha
2022-01-27 22:02     ` Eric DeVolder
2022-01-28  0:37       ` Michael S. Tsirkin
2022-01-28  9:01         ` Ani Sinha
2022-01-28 15:11         ` Eric DeVolder
2022-01-28 15:54           ` Michael S. Tsirkin
2022-01-28 16:01             ` Eric DeVolder [this message]
2022-01-28 16:14               ` Michael S. Tsirkin
2022-01-28 17:25                 ` Ani Sinha
2022-01-28 18:18                   ` Eric DeVolder
2022-01-26 16:28 ` [PATCH v14 07/10] ACPI ERST: create ACPI ERST table for pc/x86 machines Eric DeVolder
2022-01-26 16:28 ` [PATCH v14 08/10] ACPI ERST: qtest for ERST Eric DeVolder
2022-01-26 16:28 ` [PATCH v14 09/10] ACPI ERST: bios-tables-test testcase Eric DeVolder
2022-01-26 16:28 ` [PATCH v14 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=db012849-b7ec-eecc-bf41-a6b211c021f0@oracle.com \
    --to=eric.devolder@oracle.com \
    --cc=ani@anisinha.ca \
    --cc=berrange@redhat.com \
    --cc=boris.ostrovsky@oracle.com \
    --cc=ehabkost@redhat.com \
    --cc=imammedo@redhat.com \
    --cc=konrad.wilk@oracle.com \
    --cc=mst@redhat.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.