diff mbox

[4/5] acpi: acpidump: Add SLIC table dump

Message ID 1340975467-23977-5-git-send-email-colin.king@canonical.com
State Accepted
Headers show

Commit Message

Colin Ian King June 29, 2012, 1:11 p.m. UTC
From: Colin Ian King <colin.king@canonical.com>

Managed to figure out how SLIC tables are formatted, so I'm adding
the ability to dump these out in acpidump.  This required adding
an extra helper function to dump out large chunks of unsigned ints
as a hex dump.

Also, increased the field width in acpi_dump_field_info() to allow
us to dump fields > 99 bytes in size without messing up the formatting

Signed-off-by: Colin Ian King <colin.king@canonical.com>
---
 src/acpi/acpidump/acpidump.c |   90 +++++++++++++++++++++++++++++++++++++++++-
 src/lib/include/fwts_acpi.h  |   28 +++++++++++++
 2 files changed, 117 insertions(+), 1 deletion(-)

Comments

Alex Hung July 2, 2012, 6:15 a.m. UTC | #1
On 06/29/2012 09:11 PM, Colin King wrote:
> From: Colin Ian King <colin.king@canonical.com>
>
> Managed to figure out how SLIC tables are formatted, so I'm adding
> the ability to dump these out in acpidump.  This required adding
> an extra helper function to dump out large chunks of unsigned ints
> as a hex dump.
>
> Also, increased the field width in acpi_dump_field_info() to allow
> us to dump fields > 99 bytes in size without messing up the formatting
>
> Signed-off-by: Colin Ian King <colin.king@canonical.com>
> ---
>   src/acpi/acpidump/acpidump.c |   90 +++++++++++++++++++++++++++++++++++++++++-
>   src/lib/include/fwts_acpi.h  |   28 +++++++++++++
>   2 files changed, 117 insertions(+), 1 deletion(-)
>
> diff --git a/src/acpi/acpidump/acpidump.c b/src/acpi/acpidump/acpidump.c
> index 79d4c4d..6591bc3 100644
> --- a/src/acpi/acpidump/acpidump.c
> +++ b/src/acpi/acpidump/acpidump.c
> @@ -60,6 +60,9 @@ typedef struct fwts_acpidump_field {
>   #define FIELD_UINT(text, type, field)			\
>   	FIELD(text, type, field, acpi_dump_uint, 0, 0, NULL, 0, NULL)
>
> +#define FIELD_UINTS(text, type, field)			\
> +	FIELD(text, type, field, acpi_dump_uints, 0, 0, NULL, 0, NULL)
> +
>   #define FIELD_STR(text, type, field)			\
>   	FIELD(text, type, field, acpi_dump_str, 0, 0, NULL, 0, NULL)
>
> @@ -81,7 +84,7 @@ static char *acpi_dump_field_info(char *label, int size, int offset)
>   {
>   	static char buffer[1024];
>
> -	snprintf(buffer, sizeof(buffer), "[0x%3.3x %4.4d %2d] %40.40s:",
> +	snprintf(buffer, sizeof(buffer), "[0x%3.3x %4.4d %3d] %40.40s:",
>   		offset, offset, size, label);
>
>   	return buffer;
> @@ -154,6 +157,27 @@ static void acpi_dump_uint(fwts_framework *fw, fwts_acpidump_field *info, void *
>   	}
>   }
>
> +static void acpi_dump_uints(fwts_framework *fw, fwts_acpidump_field *info, void *data, int offset)
> +{
> +	int n;
> +	int length = info->size;
> +	uint8_t *ptr = (uint8_t *)data;
> +
> +        for (n = 0; n < length; n += 8) {
> +		int i;
> +		int j;
> +		int todo = length - n > 8 ? 8 : length - n;
> +		char buffer[128];
> +
> +		for (i = 0, j = 0, *buffer = '\0'; i < todo; i++, ptr++)
> +                	j += snprintf(buffer + j, sizeof(buffer) - j, "%2.2x ", *ptr);
> +
> +		fwts_log_info_verbatum(fw, "%s %s",
> +		 	acpi_dump_field_info(info->label, info->size, info->offset + offset),
> +			buffer);
> +	}
> +}
> +
>   static void acpi_dump_strings(fwts_framework *fw, fwts_acpidump_field *info, void *data, int offset)
>   {
>   	int hexdigits = info->size << 1;
> @@ -1318,6 +1342,69 @@ static void acpidump_dmar(fwts_framework *fw, fwts_acpi_table_info *table)
>   	}
>   }
>
> +/*
> + *  acpidump_slic()
> + *	dump out SLIC
> + */
> +static void acpidump_slic(fwts_framework *fw, fwts_acpi_table_info *table)
> +{
> +	uint8_t *data = (uint8_t *)table->data;
> +	size_t length = table->length;
> +	uint8_t *ptr = data;
> +
> +	static fwts_acpidump_field slic_header_fields[] = {
> +		FIELD_UINT("Type", 	fwts_acpi_table_slic_header, type),
> +		FIELD_UINT("Length", 	fwts_acpi_table_slic_header, length),
> +		FIELD_END
> +	};
> +
> +	static fwts_acpidump_field slic_key_fields[] = {
> +		FIELD_UINT("Key Type", 	fwts_acpi_table_slic_key, key_type),
> +		FIELD_UINT("Version", 	fwts_acpi_table_slic_key, version),
> +		FIELD_UINT("Reserved", 	fwts_acpi_table_slic_key, reserved),
> +		FIELD_UINT("Algorithm", fwts_acpi_table_slic_key, algorithm),
> +		FIELD_UINT("Magic", 	fwts_acpi_table_slic_key, magic),
> +		FIELD_UINT("Bit Length",fwts_acpi_table_slic_key, bit_length),
> +		FIELD_UINTS("Modulus", 	fwts_acpi_table_slic_key, modulus),
> +		FIELD_END
> +	};
> +
> +	static fwts_acpidump_field slic_marker_fields[] = {
> +		FIELD_UINT("Version", 		fwts_acpi_table_slic_marker, version),
> +		FIELD_STR("OEM ID", 		fwts_acpi_table_slic_marker, oem_id),
> +		FIELD_STR("OEM TABLE ID", 	fwts_acpi_table_slic_marker, oem_table_id),
> +		FIELD_UINTS("Windows Flag",	fwts_acpi_table_slic_marker, windows_flag),
> +		FIELD_UINT("SLIC Version", 	fwts_acpi_table_slic_marker, slic_version),
> +		FIELD_UINTS("Reserved",		fwts_acpi_table_slic_marker, reserved),
> +		FIELD_UINTS("Signature", 	fwts_acpi_table_slic_marker, signature),
> +		FIELD_END
> +	};
> +
> +	ptr += sizeof(fwts_acpi_table_header);
> +
> +	while (ptr < data + length) {
> +		fwts_log_nl(fw);
> +		fwts_acpi_table_slic_header *header =
> +			(fwts_acpi_table_slic_header *)ptr;
> +	
> +		switch(header->type) {
> +		case 0:
> +			__acpi_dump_table_fields(fw, ptr, slic_header_fields, ptr - data);
> +			__acpi_dump_table_fields(fw, ptr, slic_key_fields, ptr - data);
> +			break;
> +		case 1:
> +			__acpi_dump_table_fields(fw, ptr, slic_header_fields, ptr - data);
> +			__acpi_dump_table_fields(fw, ptr, slic_marker_fields, ptr - data);
> +			break;
> +		default:
> +			__acpi_dump_table_fields(fw, ptr, slic_header_fields, ptr - data);
> +			break;
> +		}
> +
> +		ptr += header->length;
> +	}
> +}
> +
>   typedef struct {
>   	char *name;
>   	void (*func)(fwts_framework *fw, fwts_acpi_table_info *table);
> @@ -1352,6 +1439,7 @@ static acpidump_table_vec table_vec[] = {
>   	{ "SBST", 	acpidump_sbst,  1 },
>   	{ "SSDT", 	acpidump_amlcode, 1 },
>   	{ "SLIT", 	acpidump_slit,  1 },
> +	{ "SLIC", 	acpidump_slic,  1 },
>   	{ "SRAT", 	acpidump_srat,  1 },
>   	{ "TCPA",	acpidump_tcpa,	1 },
>   	{ "XSDT", 	acpidump_xsdt, 	1 },
> diff --git a/src/lib/include/fwts_acpi.h b/src/lib/include/fwts_acpi.h
> index ef25ef5..3e5eda9 100644
> --- a/src/lib/include/fwts_acpi.h
> +++ b/src/lib/include/fwts_acpi.h
> @@ -557,6 +557,34 @@ typedef struct {
>   	uint8_t		path[0];
>   } __attribute__ ((packed)) fwts_acpi_table_dmar_device_scope;
>
> +/* SLIC, see "OEM Activation 2.0 for Windows Vista Operating Systems" */
> +typedef struct {
> +	uint32_t	type;
> +	uint32_t	length;
> +} __attribute__ ((packed)) fwts_acpi_table_slic_header;
> +
> +typedef struct {
> +	fwts_acpi_table_slic_header header;
> +	uint8_t		key_type;
> +	uint8_t		version;
> +	uint16_t	reserved;
> +	uint32_t	algorithm;
> +	uint8_t		magic[4];
> +	uint32_t	bit_length;
> +	uint8_t		modulus[128];
> +} __attribute__ ((packed)) fwts_acpi_table_slic_key;
> +
> +typedef struct {
> +	fwts_acpi_table_slic_header header;
> +	uint32_t	version;
> +	uint8_t		oem_id[6];
> +	uint8_t		oem_table_id[8];
> +	uint8_t		windows_flag[8];
> +	uint32_t	slic_version;
> +	uint8_t		reserved[16];
> +	uint8_t		signature[128];
> +} __attribute__ ((packed)) fwts_acpi_table_slic_marker;
> +
>   void fwts_acpi_table_get_header(fwts_acpi_table_header *hdr, uint8_t *data);
>
>   #endif
>
Acked-by: Alex Hung <alex.hung@canonical.com>
Keng-Yu Lin July 3, 2012, 6:57 a.m. UTC | #2
On Fri, Jun 29, 2012 at 9:11 PM, Colin King <colin.king@canonical.com> wrote:
> From: Colin Ian King <colin.king@canonical.com>
>
> Managed to figure out how SLIC tables are formatted, so I'm adding
> the ability to dump these out in acpidump.  This required adding
> an extra helper function to dump out large chunks of unsigned ints
> as a hex dump.
>
> Also, increased the field width in acpi_dump_field_info() to allow
> us to dump fields > 99 bytes in size without messing up the formatting
>
> Signed-off-by: Colin Ian King <colin.king@canonical.com>
> ---
>  src/acpi/acpidump/acpidump.c |   90 +++++++++++++++++++++++++++++++++++++++++-
>  src/lib/include/fwts_acpi.h  |   28 +++++++++++++
>  2 files changed, 117 insertions(+), 1 deletion(-)
>
> diff --git a/src/acpi/acpidump/acpidump.c b/src/acpi/acpidump/acpidump.c
> index 79d4c4d..6591bc3 100644
> --- a/src/acpi/acpidump/acpidump.c
> +++ b/src/acpi/acpidump/acpidump.c
> @@ -60,6 +60,9 @@ typedef struct fwts_acpidump_field {
>  #define FIELD_UINT(text, type, field)                  \
>         FIELD(text, type, field, acpi_dump_uint, 0, 0, NULL, 0, NULL)
>
> +#define FIELD_UINTS(text, type, field)                 \
> +       FIELD(text, type, field, acpi_dump_uints, 0, 0, NULL, 0, NULL)
> +
>  #define FIELD_STR(text, type, field)                   \
>         FIELD(text, type, field, acpi_dump_str, 0, 0, NULL, 0, NULL)
>
> @@ -81,7 +84,7 @@ static char *acpi_dump_field_info(char *label, int size, int offset)
>  {
>         static char buffer[1024];
>
> -       snprintf(buffer, sizeof(buffer), "[0x%3.3x %4.4d %2d] %40.40s:",
> +       snprintf(buffer, sizeof(buffer), "[0x%3.3x %4.4d %3d] %40.40s:",
>                 offset, offset, size, label);
>
>         return buffer;
> @@ -154,6 +157,27 @@ static void acpi_dump_uint(fwts_framework *fw, fwts_acpidump_field *info, void *
>         }
>  }
>
> +static void acpi_dump_uints(fwts_framework *fw, fwts_acpidump_field *info, void *data, int offset)
> +{
> +       int n;
> +       int length = info->size;
> +       uint8_t *ptr = (uint8_t *)data;
> +
> +        for (n = 0; n < length; n += 8) {
> +               int i;
> +               int j;
> +               int todo = length - n > 8 ? 8 : length - n;
> +               char buffer[128];
> +
> +               for (i = 0, j = 0, *buffer = '\0'; i < todo; i++, ptr++)
> +                       j += snprintf(buffer + j, sizeof(buffer) - j, "%2.2x ", *ptr);
> +
> +               fwts_log_info_verbatum(fw, "%s %s",
> +                       acpi_dump_field_info(info->label, info->size, info->offset + offset),
> +                       buffer);
> +       }
> +}
> +
>  static void acpi_dump_strings(fwts_framework *fw, fwts_acpidump_field *info, void *data, int offset)
>  {
>         int hexdigits = info->size << 1;
> @@ -1318,6 +1342,69 @@ static void acpidump_dmar(fwts_framework *fw, fwts_acpi_table_info *table)
>         }
>  }
>
> +/*
> + *  acpidump_slic()
> + *     dump out SLIC
> + */
> +static void acpidump_slic(fwts_framework *fw, fwts_acpi_table_info *table)
> +{
> +       uint8_t *data = (uint8_t *)table->data;
> +       size_t length = table->length;
> +       uint8_t *ptr = data;
> +
> +       static fwts_acpidump_field slic_header_fields[] = {
> +               FIELD_UINT("Type",      fwts_acpi_table_slic_header, type),
> +               FIELD_UINT("Length",    fwts_acpi_table_slic_header, length),
> +               FIELD_END
> +       };
> +
> +       static fwts_acpidump_field slic_key_fields[] = {
> +               FIELD_UINT("Key Type",  fwts_acpi_table_slic_key, key_type),
> +               FIELD_UINT("Version",   fwts_acpi_table_slic_key, version),
> +               FIELD_UINT("Reserved",  fwts_acpi_table_slic_key, reserved),
> +               FIELD_UINT("Algorithm", fwts_acpi_table_slic_key, algorithm),
> +               FIELD_UINT("Magic",     fwts_acpi_table_slic_key, magic),
> +               FIELD_UINT("Bit Length",fwts_acpi_table_slic_key, bit_length),
> +               FIELD_UINTS("Modulus",  fwts_acpi_table_slic_key, modulus),
> +               FIELD_END
> +       };
> +
> +       static fwts_acpidump_field slic_marker_fields[] = {
> +               FIELD_UINT("Version",           fwts_acpi_table_slic_marker, version),
> +               FIELD_STR("OEM ID",             fwts_acpi_table_slic_marker, oem_id),
> +               FIELD_STR("OEM TABLE ID",       fwts_acpi_table_slic_marker, oem_table_id),
> +               FIELD_UINTS("Windows Flag",     fwts_acpi_table_slic_marker, windows_flag),
> +               FIELD_UINT("SLIC Version",      fwts_acpi_table_slic_marker, slic_version),
> +               FIELD_UINTS("Reserved",         fwts_acpi_table_slic_marker, reserved),
> +               FIELD_UINTS("Signature",        fwts_acpi_table_slic_marker, signature),
> +               FIELD_END
> +       };
> +
> +       ptr += sizeof(fwts_acpi_table_header);
> +
> +       while (ptr < data + length) {
> +               fwts_log_nl(fw);
> +               fwts_acpi_table_slic_header *header =
> +                       (fwts_acpi_table_slic_header *)ptr;
> +
> +               switch(header->type) {
> +               case 0:
> +                       __acpi_dump_table_fields(fw, ptr, slic_header_fields, ptr - data);
> +                       __acpi_dump_table_fields(fw, ptr, slic_key_fields, ptr - data);
> +                       break;
> +               case 1:
> +                       __acpi_dump_table_fields(fw, ptr, slic_header_fields, ptr - data);
> +                       __acpi_dump_table_fields(fw, ptr, slic_marker_fields, ptr - data);
> +                       break;
> +               default:
> +                       __acpi_dump_table_fields(fw, ptr, slic_header_fields, ptr - data);
> +                       break;
> +               }
> +
> +               ptr += header->length;
> +       }
> +}
> +
>  typedef struct {
>         char *name;
>         void (*func)(fwts_framework *fw, fwts_acpi_table_info *table);
> @@ -1352,6 +1439,7 @@ static acpidump_table_vec table_vec[] = {
>         { "SBST",       acpidump_sbst,  1 },
>         { "SSDT",       acpidump_amlcode, 1 },
>         { "SLIT",       acpidump_slit,  1 },
> +       { "SLIC",       acpidump_slic,  1 },
>         { "SRAT",       acpidump_srat,  1 },
>         { "TCPA",       acpidump_tcpa,  1 },
>         { "XSDT",       acpidump_xsdt,  1 },
> diff --git a/src/lib/include/fwts_acpi.h b/src/lib/include/fwts_acpi.h
> index ef25ef5..3e5eda9 100644
> --- a/src/lib/include/fwts_acpi.h
> +++ b/src/lib/include/fwts_acpi.h
> @@ -557,6 +557,34 @@ typedef struct {
>         uint8_t         path[0];
>  } __attribute__ ((packed)) fwts_acpi_table_dmar_device_scope;
>
> +/* SLIC, see "OEM Activation 2.0 for Windows Vista Operating Systems" */
> +typedef struct {
> +       uint32_t        type;
> +       uint32_t        length;
> +} __attribute__ ((packed)) fwts_acpi_table_slic_header;
> +
> +typedef struct {
> +       fwts_acpi_table_slic_header header;
> +       uint8_t         key_type;
> +       uint8_t         version;
> +       uint16_t        reserved;
> +       uint32_t        algorithm;
> +       uint8_t         magic[4];
> +       uint32_t        bit_length;
> +       uint8_t         modulus[128];
> +} __attribute__ ((packed)) fwts_acpi_table_slic_key;
> +
> +typedef struct {
> +       fwts_acpi_table_slic_header header;
> +       uint32_t        version;
> +       uint8_t         oem_id[6];
> +       uint8_t         oem_table_id[8];
> +       uint8_t         windows_flag[8];
> +       uint32_t        slic_version;
> +       uint8_t         reserved[16];
> +       uint8_t         signature[128];
> +} __attribute__ ((packed)) fwts_acpi_table_slic_marker;
> +
>  void fwts_acpi_table_get_header(fwts_acpi_table_header *hdr, uint8_t *data);
>
>  #endif
> --
> 1.7.10.4
>
Acked-by: Keng-Yu Lin <kengyu@canonical.com>
diff mbox

Patch

diff --git a/src/acpi/acpidump/acpidump.c b/src/acpi/acpidump/acpidump.c
index 79d4c4d..6591bc3 100644
--- a/src/acpi/acpidump/acpidump.c
+++ b/src/acpi/acpidump/acpidump.c
@@ -60,6 +60,9 @@  typedef struct fwts_acpidump_field {
 #define FIELD_UINT(text, type, field)			\
 	FIELD(text, type, field, acpi_dump_uint, 0, 0, NULL, 0, NULL)
 
+#define FIELD_UINTS(text, type, field)			\
+	FIELD(text, type, field, acpi_dump_uints, 0, 0, NULL, 0, NULL)
+
 #define FIELD_STR(text, type, field)			\
 	FIELD(text, type, field, acpi_dump_str, 0, 0, NULL, 0, NULL)
 
@@ -81,7 +84,7 @@  static char *acpi_dump_field_info(char *label, int size, int offset)
 {
 	static char buffer[1024];
 
-	snprintf(buffer, sizeof(buffer), "[0x%3.3x %4.4d %2d] %40.40s:",
+	snprintf(buffer, sizeof(buffer), "[0x%3.3x %4.4d %3d] %40.40s:",
 		offset, offset, size, label);
 
 	return buffer;
@@ -154,6 +157,27 @@  static void acpi_dump_uint(fwts_framework *fw, fwts_acpidump_field *info, void *
 	}
 }
 
+static void acpi_dump_uints(fwts_framework *fw, fwts_acpidump_field *info, void *data, int offset)
+{
+	int n;
+	int length = info->size;
+	uint8_t *ptr = (uint8_t *)data;
+
+        for (n = 0; n < length; n += 8) {
+		int i;
+		int j;
+		int todo = length - n > 8 ? 8 : length - n;
+		char buffer[128];
+
+		for (i = 0, j = 0, *buffer = '\0'; i < todo; i++, ptr++)
+                	j += snprintf(buffer + j, sizeof(buffer) - j, "%2.2x ", *ptr);
+
+		fwts_log_info_verbatum(fw, "%s %s", 
+		 	acpi_dump_field_info(info->label, info->size, info->offset + offset),
+			buffer);
+	}
+}
+
 static void acpi_dump_strings(fwts_framework *fw, fwts_acpidump_field *info, void *data, int offset)
 {
 	int hexdigits = info->size << 1;
@@ -1318,6 +1342,69 @@  static void acpidump_dmar(fwts_framework *fw, fwts_acpi_table_info *table)
 	}
 }
 
+/*
+ *  acpidump_slic()
+ *	dump out SLIC
+ */
+static void acpidump_slic(fwts_framework *fw, fwts_acpi_table_info *table)
+{
+	uint8_t *data = (uint8_t *)table->data;
+	size_t length = table->length;
+	uint8_t *ptr = data;
+
+	static fwts_acpidump_field slic_header_fields[] = {
+		FIELD_UINT("Type", 	fwts_acpi_table_slic_header, type),
+		FIELD_UINT("Length", 	fwts_acpi_table_slic_header, length),
+		FIELD_END
+	};
+
+	static fwts_acpidump_field slic_key_fields[] = {
+		FIELD_UINT("Key Type", 	fwts_acpi_table_slic_key, key_type),
+		FIELD_UINT("Version", 	fwts_acpi_table_slic_key, version),
+		FIELD_UINT("Reserved", 	fwts_acpi_table_slic_key, reserved),
+		FIELD_UINT("Algorithm", fwts_acpi_table_slic_key, algorithm),
+		FIELD_UINT("Magic", 	fwts_acpi_table_slic_key, magic),
+		FIELD_UINT("Bit Length",fwts_acpi_table_slic_key, bit_length),
+		FIELD_UINTS("Modulus", 	fwts_acpi_table_slic_key, modulus),
+		FIELD_END
+	};
+
+	static fwts_acpidump_field slic_marker_fields[] = {
+		FIELD_UINT("Version", 		fwts_acpi_table_slic_marker, version),
+		FIELD_STR("OEM ID", 		fwts_acpi_table_slic_marker, oem_id),
+		FIELD_STR("OEM TABLE ID", 	fwts_acpi_table_slic_marker, oem_table_id),
+		FIELD_UINTS("Windows Flag",	fwts_acpi_table_slic_marker, windows_flag),
+		FIELD_UINT("SLIC Version", 	fwts_acpi_table_slic_marker, slic_version),
+		FIELD_UINTS("Reserved",		fwts_acpi_table_slic_marker, reserved),
+		FIELD_UINTS("Signature", 	fwts_acpi_table_slic_marker, signature),
+		FIELD_END
+	};
+
+	ptr += sizeof(fwts_acpi_table_header);
+
+	while (ptr < data + length) {
+		fwts_log_nl(fw);
+		fwts_acpi_table_slic_header *header =
+			(fwts_acpi_table_slic_header *)ptr;
+	
+		switch(header->type) {
+		case 0:
+			__acpi_dump_table_fields(fw, ptr, slic_header_fields, ptr - data);
+			__acpi_dump_table_fields(fw, ptr, slic_key_fields, ptr - data);
+			break;
+		case 1:
+			__acpi_dump_table_fields(fw, ptr, slic_header_fields, ptr - data);
+			__acpi_dump_table_fields(fw, ptr, slic_marker_fields, ptr - data);
+			break;
+		default:
+			__acpi_dump_table_fields(fw, ptr, slic_header_fields, ptr - data);
+			break;
+		}
+
+		ptr += header->length;
+	}
+}
+
 typedef struct {
 	char *name;
 	void (*func)(fwts_framework *fw, fwts_acpi_table_info *table);
@@ -1352,6 +1439,7 @@  static acpidump_table_vec table_vec[] = {
 	{ "SBST", 	acpidump_sbst,  1 },
 	{ "SSDT", 	acpidump_amlcode, 1 },
 	{ "SLIT", 	acpidump_slit,  1 },
+	{ "SLIC", 	acpidump_slic,  1 },
 	{ "SRAT", 	acpidump_srat,  1 },
 	{ "TCPA",	acpidump_tcpa,	1 },
 	{ "XSDT", 	acpidump_xsdt, 	1 },
diff --git a/src/lib/include/fwts_acpi.h b/src/lib/include/fwts_acpi.h
index ef25ef5..3e5eda9 100644
--- a/src/lib/include/fwts_acpi.h
+++ b/src/lib/include/fwts_acpi.h
@@ -557,6 +557,34 @@  typedef struct {
 	uint8_t		path[0];
 } __attribute__ ((packed)) fwts_acpi_table_dmar_device_scope;
 
+/* SLIC, see "OEM Activation 2.0 for Windows Vista Operating Systems" */
+typedef struct {
+	uint32_t	type;
+	uint32_t	length;
+} __attribute__ ((packed)) fwts_acpi_table_slic_header;
+
+typedef struct {
+	fwts_acpi_table_slic_header header;
+	uint8_t		key_type;
+	uint8_t		version;
+	uint16_t	reserved;
+	uint32_t	algorithm;
+	uint8_t		magic[4];
+	uint32_t	bit_length;
+	uint8_t		modulus[128];
+} __attribute__ ((packed)) fwts_acpi_table_slic_key;
+
+typedef struct {
+	fwts_acpi_table_slic_header header;
+	uint32_t	version;
+	uint8_t		oem_id[6];
+	uint8_t		oem_table_id[8];
+	uint8_t		windows_flag[8];
+	uint32_t	slic_version;
+	uint8_t		reserved[16];
+	uint8_t		signature[128];
+} __attribute__ ((packed)) fwts_acpi_table_slic_marker;
+
 void fwts_acpi_table_get_header(fwts_acpi_table_header *hdr, uint8_t *data);
 
 #endif