ACK: [PATCH][RESEND] Allow RSDP to be provided manually or scan for it in klog (LP: #1260400)
Keng-Yu Lin
keng-yu.lin at canonical.com
Fri Dec 20 09:15:07 UTC 2013
On Mon, Dec 16, 2013 at 11:29 AM, IvanHu <ivan.hu at canonical.com> wrote:
> On 12/13/2013 04:19 AM, Colin King wrote:
>>
>> From: Colin Ian King <colin.king at canonical.com>
>>
>> During work on an early development machine we found a situation where
>> the RSDP could not be automatically probed using the current methods.
>> So, allow the RSDP to be specified either manually using the new -R or
>> --rsdp options or found by scanning the kernel log (ugly, but is our
>> final easy option).
>>
>> We should also sanity check the RDSP by ensuring it lies on a 16 byte
>> boundary and contains a valid signature.
>>
>> Signed-off-by: Colin Ian King <colin.king at canonical.com>
>> ---
>> doc/fwts.1 | 4 +++
>> src/lib/include/fwts_framework.h | 1 +
>> src/lib/src/fwts_acpi_tables.c | 64
>> +++++++++++++++++++++++++++++++++-------
>> src/lib/src/fwts_framework.c | 7 +++++
>> 4 files changed, 66 insertions(+), 10 deletions(-)
>>
>> diff --git a/doc/fwts.1 b/doc/fwts.1
>> index 234278d..a12aca9 100644
>> --- a/doc/fwts.1
>> +++ b/doc/fwts.1
>> @@ -201,6 +201,10 @@ no pretty printing of horizontal separators in the
>> results log file.
>> specify the results output log file.
>> One can also specify stdout and stderr to redirect to these output
>> streams.
>> .TP
>> +.B \-R, \-\-rsdp=physaddr
>> +specify the physical address of ACPI RSDP. This is useful on some systems
>> where
>> +it cannot be automatically detected.
>> +.TP
>> .B \-\-s3\-delay\-delta=N
>> time to be added onto delay between each S3 iteration.
>> .TP
>> diff --git a/src/lib/include/fwts_framework.h
>> b/src/lib/include/fwts_framework.h
>> index f365d74..1e5171c 100644
>> --- a/src/lib/include/fwts_framework.h
>> +++ b/src/lib/include/fwts_framework.h
>> @@ -144,6 +144,7 @@ typedef struct {
>> fwts_list errors_filter_discard; /* Results to discard,
>> empty = discard none */
>> bool error_filtered_out; /* True if a klog message
>> has been filtered out */
>> fwts_acpica_mode acpica_mode; /* ACPICA mode flags */
>> + void *rsdp; /* ACPI RSDP address */
>> } fwts_framework;
>>
>> typedef struct {
>> diff --git a/src/lib/src/fwts_acpi_tables.c
>> b/src/lib/src/fwts_acpi_tables.c
>> index 6f1e964..f9f6ba0 100644
>> --- a/src/lib/src/fwts_acpi_tables.c
>> +++ b/src/lib/src/fwts_acpi_tables.c
>> @@ -52,6 +52,34 @@ static void *fwts_acpi_find_rsdp_efi(void)
>> }
>>
>> /*
>> + * fwts_acpi_find_rsdp_klog()
>> + * Get RSDP by parsing kernel log
>> + */
>> +static void *fwts_acpi_find_rsdp_klog(void)
>> +{
>> + fwts_list *klog;
>> + fwts_list_link *item;
>> + void *rsdp = NULL;
>> +
>> + if ((klog = fwts_klog_read()) == NULL)
>> + return NULL;
>> +
>> + fwts_list_foreach(item, klog) {
>> + char *text = fwts_text_list_text(item);
>> + char *ptr = strstr(text, "ACPI: RSDP");
>> +
>> + if (ptr) {
>> + rsdp = (void *)strtoul(ptr + 11, NULL, 16);
>> + break;
>> + }
>> + }
>> +
>> + fwts_text_list_free(klog);
>> +
>> + return rsdp;
>> +}
>> +
>> +/*
>> * fwts_acpi_find_rsdp_bios()
>> * Find RSDP address by scanning BIOS memory
>> */
>> @@ -94,21 +122,26 @@ static void *fwts_acpi_find_rsdp_bios(void)
>> static fwts_acpi_table_rsdp *fwts_acpi_get_rsdp(void *addr, size_t
>> *rsdp_len)
>> {
>> uint8_t *mem;
>> - fwts_acpi_table_rsdp *rsdp;
>> + fwts_acpi_table_rsdp *rsdp = NULL;
>> *rsdp_len = 0;
>>
>> if ((mem = fwts_mmap((off_t)addr, sizeof(fwts_acpi_table_rsdp)))
>> == FWTS_MAP_FAILED)
>> return NULL;
>>
>> - /* Determine original RSDP size from revision. */
>> rsdp = (fwts_acpi_table_rsdp*)mem;
>> + /* Determine original RSDP size from revision. */
>> *rsdp_len = (rsdp->revision < 1) ? 20 : 36;
>>
>> + /* Must have the correct signature */
>> + if (strncmp(rsdp->signature, "RSD PTR ", 8))
>> + goto out;
>> +
>> /* Assume version 2.0 size, we don't care about a few bytes over
>> allocation if it's version 1.0 */
>> if ((rsdp = (fwts_acpi_table_rsdp*)fwts_low_calloc(1,
>> sizeof(fwts_acpi_table_rsdp))) == NULL)
>> - return NULL;
>> + goto out;
>>
>> memcpy(rsdp, mem, *rsdp_len);
>> +out:
>> (void)fwts_munmap(mem, sizeof(fwts_acpi_table_rsdp));
>>
>> return rsdp;
>> @@ -238,22 +271,33 @@ static void
>> fwts_acpi_handle_fadt(fwts_acpi_table_fadt *fadt, fwts_acpi_table_pr
>> * fwts_acpi_load_tables_from_firmware()
>> * Load up cached copies of all the ACPI tables
>> */
>> -static int fwts_acpi_load_tables_from_firmware(void)
>> +static int fwts_acpi_load_tables_from_firmware(fwts_framework *fw)
>> {
>> fwts_acpi_table_rsdp *rsdp;
>> fwts_acpi_table_xsdt *xsdt;
>> fwts_acpi_table_rsdt *rsdt;
>> fwts_acpi_table_header *header;
>>
>> - void * rsdp_addr;
>> + void * rsdp_addr = NULL;
>> size_t rsdp_len;
>> int num_entries;
>> int i;
>>
>> - /* Check for RSDP in EFI, then BIOS, if not found, give up */
>> - if ((rsdp_addr = fwts_acpi_find_rsdp_efi()) == NULL)
>> - if ((rsdp_addr = fwts_acpi_find_rsdp_bios()) == NULL)
>> - return FWTS_ERROR;
>> + /* Check for RSDP as EFI, then BIOS, parsed klog, if not found,
>> give up */
>> + if (fw->rsdp)
>> + rsdp_addr = (void*)fw->rsdp;
>> + if (!rsdp_addr)
>> + rsdp_addr = fwts_acpi_find_rsdp_efi();
>> + if (!rsdp_addr)
>> + rsdp_addr = fwts_acpi_find_rsdp_bios();
>> + if (!rsdp_addr)
>> + rsdp_addr = fwts_acpi_find_rsdp_klog();
>> + if (!rsdp_addr)
>> + return FWTS_ERROR;
>> +
>> + /* Must be on a 16 byte boundary */
>> + if (((unsigned long)rsdp_addr & 0xf))
>> + return FWTS_ERROR;
>>
>> /* Load and save cached RSDP */
>> if ((rsdp = fwts_acpi_get_rsdp(rsdp_addr, &rsdp_len)) == NULL)
>> @@ -712,7 +756,7 @@ int fwts_acpi_load_tables(fwts_framework *fw)
>> else if (fw->acpi_table_acpidump_file != NULL)
>> ret = fwts_acpi_load_tables_from_acpidump(fw);
>> else if (fwts_check_root_euid(fw, true) == FWTS_OK)
>> - ret = fwts_acpi_load_tables_from_firmware();
>> + ret = fwts_acpi_load_tables_from_firmware(fw);
>> else
>> ret = FWTS_ERROR_NO_PRIV;
>>
>> diff --git a/src/lib/src/fwts_framework.c b/src/lib/src/fwts_framework.c
>> index eae5907..92aa74d 100644
>> --- a/src/lib/src/fwts_framework.c
>> +++ b/src/lib/src/fwts_framework.c
>> @@ -83,6 +83,7 @@ static fwts_option fwts_framework_options[] = {
>> { "acpica-debug", "", 0, "Enable ACPICA debug/warning
>> messages." },
>> { "acpica", "", 1, "Enable ACPICA run time options."
>> },
>> { "uefi", "", 0, "Run UEFI tests." },
>> + { "rsdp", "R:", 1, "Specify the physical address of
>> the ACPI RSDP." },
>> { NULL, NULL, 0, NULL }
>> };
>>
>> @@ -1138,6 +1139,9 @@ int fwts_framework_options_handler(fwts_framework
>> *fw, int argc, char * const ar
>> case 38: /* --uefi */
>> fw->flags |= FWTS_FLAG_TEST_UEFI;
>> break;
>> + case 39: /* --rsdp */
>> + fw->rsdp = (void *)strtoul(optarg, NULL, 0);
>> + break;
>> }
>> break;
>> case 'a': /* --all */
>> @@ -1214,6 +1218,9 @@ int fwts_framework_options_handler(fwts_framework
>> *fw, int argc, char * const ar
>> case 'w': /* --log-width=N */
>> fwts_log_set_line_width(atoi(optarg));
>> break;
>> + case 'R': /* --rsdp=addr */
>> + fw->rsdp = (void *)strtoul(optarg, NULL, 0);
>> + break;
>> }
>> return FWTS_OK;
>> }
>>
>
> Acked-by: Ivan Hu <ivan.hu at canonical.com>
>
Acked-by: Keng-Yu Lin <kengyu at canonical.com>
More information about the fwts-devel
mailing list