Add tests for DSDT table address parsing

This commit is contained in:
Muhammad Rais Fathin Mudzakir
2016-05-30 12:37:50 +10:00
parent 2aa7fc4893
commit 2e6a64bcb2
2 changed files with 161 additions and 21 deletions
+68 -14
View File
@@ -59,9 +59,6 @@ class ACPIHelper(TestHelper):
XSDT_ADDRESS = 0x100
RSDT_ADDRESS = 0x200
RSDT_ENTRIES = []
XSDT_ENTRIES = []
def _create_rsdp(self):
rsdp = None
if self.USE_RSDP_REV_0:
@@ -96,40 +93,97 @@ class ACPIHelper(TestHelper):
"CRRV") # Creator Revision
def _create_rsdt(self):
rsdt_length = 36 + 4 * len(self.RSDT_ENTRIES) # 36 : ACPI table header size
rsdt_length = 36 + 4 * len(self.rsdt_entries) # 36 : ACPI table header size
rsdt = self._create_generic_acpi_table_header("RSDT", rsdt_length)
for rsdt_entry in self.RSDT_ENTRIES:
for rsdt_entry in self.rsdt_entries:
rsdt += struct.pack("<I", rsdt_entry)
return rsdt
def _create_xsdt(self):
xsdt_length = 36 + 8 * len(self.XSDT_ENTRIES) # 36 : ACPI table header size
xsdt_length = 36 + 8 * len(self.xsdt_entries) # 36 : ACPI table header size
xsdt = self._create_generic_acpi_table_header("XSDT", xsdt_length)
for xsdt_entry in self.XSDT_ENTRIES:
for xsdt_entry in self.xsdt_entries:
xsdt += struct.pack("<Q", xsdt_entry)
return xsdt
def _add_entry_to_rsdt(self, entry):
self.rsdt_entries.append(entry)
self.rsdt_descriptor = self._create_rsdt()
def _add_entry_to_xsdt(self, entry):
self.xsdt_entries.append(entry)
self.xsdt_descriptor = self._create_xsdt()
def __init__(self):
super(ACPIHelper, self).__init__()
self.RSDP_DESCRIPTOR = self._create_rsdp()
self.RSDT_DESCRIPTOR = self._create_rsdt()
self.XSDT_DESCRIPTOR = self._create_xsdt()
self.rsdt_entries = []
self.xsdt_entries = []
self.rsdp_descriptor = self._create_rsdp()
self.rsdt_descriptor = self._create_rsdt()
self.xsdt_descriptor = self._create_xsdt()
def read_phys_mem(self, pa_hi, pa_lo, length):
if pa_lo == 0x40E:
return struct.pack("<H", self.EBDA_ADDRESS >> 4)
elif pa_lo >= self.EBDA_ADDRESS and \
pa_lo < self.RSDP_ADDRESS + len(self.RSDP_DESCRIPTOR):
mem = "\x00" * self.EBDA_PADDING + self.RSDP_DESCRIPTOR
pa_lo < self.RSDP_ADDRESS + len(self.rsdp_descriptor):
mem = "\x00" * self.EBDA_PADDING + self.rsdp_descriptor
offset = pa_lo - self.EBDA_ADDRESS
return mem[offset:offset+length]
elif pa_lo == self.RSDT_ADDRESS:
return self.RSDT_DESCRIPTOR[:length]
return self.rsdt_descriptor[:length]
elif pa_lo == self.XSDT_ADDRESS:
return self.XSDT_DESCRIPTOR[:length]
return self.xsdt_descriptor[:length]
else:
return "\xFF" * length
class DSDTParsingHelper(ACPIHelper):
"""Test helper containing generic descriptor for RSDP, RSDT, and FADT to parse DSDT
Default entry for DSDT and X_DSDT inside FADT is 0x0
One additional region is defined:
* FADT table [0x400, 0x514]
"""
USE_FADT_WITH_X_DSDT = True
FADT_ADDRESS = 0x400
DSDT_ADDRESS = 0x0
X_DSDT_ADDRESS = 0x0
def _add_fadt_to_sdt_entries(self):
if self.USE_RSDP_REV_0:
self._add_entry_to_rsdt(self.FADT_ADDRESS)
else:
self._add_entry_to_xsdt(self.FADT_ADDRESS)
def _create_fadt(self):
fadt = ""
if self.USE_FADT_WITH_X_DSDT:
fadt = self._create_generic_acpi_table_header("FACP", 0x10C)
fadt += struct.pack("<I", 0x500) # Address of FACS
fadt += struct.pack("<I", self.DSDT_ADDRESS) # 32-bit address of DSDT
fadt += struct.pack("<B", 0x1) * 96 # Bits between DSDT and X_DSDT
fadt += struct.pack("<Q", self.X_DSDT_ADDRESS) # X_DSDT
fadt += struct.pack("<B", 0x1) * 120 # Remaining fields
else:
fadt = self._create_generic_acpi_table_header("FACP", 0x74)
fadt += struct.pack("<I", 0x500) # Address of FACS
fadt += struct.pack("<I", self.DSDT_ADDRESS) # 32-bit address of DSDT
fadt += struct.pack("<B", 0x1) * 72 # Remaining fields
return fadt
def __init__(self):
super(DSDTParsingHelper, self).__init__()
self._add_fadt_to_sdt_entries()
self.fadt_descriptor = self._create_fadt()
def read_phys_mem(self, pa_hi, pa_lo, length):
if pa_lo == self.FADT_ADDRESS:
return self.fadt_descriptor[:length]
else:
return super(DSDTParsingHelper, self).read_phys_mem(pa_hi, pa_lo, length)
class SPIHelper(TestHelper):
"""Generic SPI emulation
+93 -7
View File
@@ -60,7 +60,9 @@ class TestChipsecUtil(unittest.TestCase):
USE_RSDP_REV_0 = False
XSDT_ENTRIES = [0x400]
def __init__(self):
super(ACPIHelper, self).__init__()
self._add_entry_to_xsdt(0x400)
def read_phys_mem(self, pa_hi, pa_lo, length):
if pa_lo == 0x400:
@@ -75,15 +77,17 @@ class TestChipsecUtil(unittest.TestCase):
class ACPIHelper(mock_helper.ACPIHelper):
RSDT_ENTRIES = [0x300]
def __init__(self):
super(ACPIHelper, self).__init__()
self._add_entry_to_rsdt(0x300)
def read_phys_mem(self, pa_hi, pa_lo, length):
if pa_lo >= self.EBDA_ADDRESS and \
pa_lo < self.RSDP_ADDRESS + len(self.RSDP_DESCRIPTOR):
pa_lo < self.RSDP_ADDRESS + len(self.rsdp_descriptor):
# Simulate a condition where there is no RSDP in EBDA
return "\xFF" * length
elif pa_lo == 0xE0000:
return self.RSDP_DESCRIPTOR[:length]
return self.rsdp_descriptor[:length]
elif pa_lo == 0x300:
return "ABCD"
else:
@@ -92,10 +96,88 @@ class TestChipsecUtil(unittest.TestCase):
self._chipsec_util("acpi list", ACPIHelper)
self.assertIn("ABCD: 0x0000000000000300", self.log)
def test_acpi_facp_list(self):
self._chipsec_util("acpi table FACP", mock_helper.DSDTParsingHelper)
self.assertIn("DSDT: 0x00000000", self.log)
self.assertIn("X_DSDT: 0x0000000000000000", self.log)
def test_mismatch_dsdt_x_dsdt_error(self):
class DSDTParsingHelper(mock_helper.DSDTParsingHelper):
DSDT_ADDRESS = 0x400
X_DSDT_ADDRESS = 0x312
self._chipsec_util("acpi table FACP", DSDTParsingHelper)
self.assertIn("DSDT: 0x00000400", self.log)
self.assertIn("X_DSDT: 0x0000000000000312", self.log)
self.assertIn("Unable to determine the correct DSDT address", self.log)
def test_mismatch_dsdt_x_dsdt_ok_dsdt_zero(self):
class DSDTParsingHelper(mock_helper.DSDTParsingHelper):
DSDT_ADDRESS = 0x0
X_DSDT_ADDRESS = 0x400
self._chipsec_util("acpi table FACP", DSDTParsingHelper)
self.assertIn("DSDT: 0x00000000", self.log)
self.assertIn("X_DSDT: 0x0000000000000400", self.log)
self.assertNotIn("Unable to determine the correct DSDT address", self.log)
def test_mismatch_dsdt_x_dsdt_ok_x_dsdt_zero(self):
class DSDTParsingHelper(mock_helper.DSDTParsingHelper):
DSDT_ADDRESS = 0x400
X_DSDT_ADDRESS = 0x0
self._chipsec_util("acpi table FACP", DSDTParsingHelper)
self.assertIn("DSDT: 0x00000400", self.log)
self.assertIn("X_DSDT: 0x0000000000000000", self.log)
self.assertNotIn("Unable to determine the correct DSDT address", self.log)
def test_no_x_dsdt(self):
class DSDTParsingHelper(mock_helper.DSDTParsingHelper):
USE_FADT_WITH_X_DSDT = False
DSDT_ADDRESS = 0x400
self._chipsec_util("acpi table FACP", DSDTParsingHelper)
self.assertIn("DSDT: 0x00000400", self.log)
self.assertIn("X_DSDT: Not found", self.log)
self.assertIn("Cannot find X_DSDT entry in FADT.", self.log)
def test_show_dsdt(self):
class DSDTParsingHelper(mock_helper.DSDTParsingHelper):
DSDT_ADDRESS = 0x600
DSDT_DESCRIPTOR = ("DSDT" + # Signature
struct.pack("<I", 0x30) + # Length
struct.pack("<B", 0x1) + # Revision
struct.pack("<B", 0x1) + # Checksum
"OEMDSD" + # OEMID
"OEMTBLID" + # OEM Table ID
"OEMR" + # OEM Revision
"CRID" + # Creator ID
"CRRV" + # Creator Revision
struct.pack("<Q", 0x129)) # AML code
def read_phys_mem(self, pa_hi, pa_lo, length):
if pa_lo == self.DSDT_ADDRESS:
return self.DSDT_DESCRIPTOR[:length]
else:
return super(DSDTParsingHelper, self).read_phys_mem(pa_hi, pa_lo, length)
self._chipsec_util("acpi table DSDT", DSDTParsingHelper)
self.assertIn("OEMDSD", self.log)
def test_platform(self):
self._chipsec_util("platform")
def test_cmos_dump(self):
"""Test to verify the output of 'cmos dump'.
@@ -182,8 +264,6 @@ class TestChipsecUtil(unittest.TestCase):
* SSDT table [0x600, 0x630]
* SSDT table [0x800, 0x830]
"""
RSDT_ENTRIES = [0x400, 0x600, 0x800]
SSDT1_DESCRIPTOR = ("SSDT" + # Signature
struct.pack("<I", 0x30) + # Length
struct.pack("<B", 0x1) + # Revision
@@ -217,6 +297,12 @@ class TestChipsecUtil(unittest.TestCase):
"CRRV" + # Creator Revision
struct.pack("<Q", 0x199)) # AML code
def __init__(self):
super(SSDTParsingHelper, self).__init__()
self._add_entry_to_rsdt(0x400)
self._add_entry_to_rsdt(0x600)
self._add_entry_to_rsdt(0x800)
def read_phys_mem(self, pa_hi, pa_lo, length):
if pa_lo == 0x400:
return self.SSDT1_DESCRIPTOR[:length]