mirror of
https://github.com/chipsec/chipsec
synced 2026-06-08 13:31:00 +00:00
1259e568de
Signed-off-by: Nathaniel Mitchell <nathaniel.p.mitchell@intel.com>
245 lines
11 KiB
Python
245 lines
11 KiB
Python
# CHIPSEC: Platform Security Assessment Framework
|
|
# Copyright (c) 2025, Intel Corporation
|
|
#
|
|
# This program is free software; you can redistribute it and/or
|
|
# modify it under the terms of the GNU General Public License
|
|
# as published by the Free Software Foundation; Version 2.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program; if not, write to the Free Software
|
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
#
|
|
# Contact information:
|
|
# chipsec@intel.com
|
|
#
|
|
|
|
import unittest
|
|
|
|
from unittest.mock import MagicMock, call, patch
|
|
from chipsec.hal.common.smbus import SMBus, SMBUS_POLL_COUNT, SMBusMMIO
|
|
from chipsec.library.exceptions import IOBARNotFoundError
|
|
|
|
class TestSMBUS(unittest.TestCase):
|
|
def test_get_SMBus_Base_Address_valid_base(self):
|
|
base_address = 123456
|
|
mock_cs = MagicMock()
|
|
smbus_hal = SMBus(mock_cs)
|
|
mock_cs.hals.iobar.is_IO_BAR_defined.return_value = True
|
|
mock_cs.hals.iobar.get_IO_BAR_base_address.return_value = (base_address, None)
|
|
self.assertEqual(smbus_hal.get_SMBus_Base_Address(), base_address)
|
|
|
|
def test_get_SMBus_Base_Address_invalid_base(self):
|
|
mock_cs = MagicMock()
|
|
smbus_hal = SMBus(mock_cs)
|
|
mock_cs.hals.iobar.is_IO_BAR_defined.return_value = False
|
|
self.assertRaises(IOBARNotFoundError, smbus_hal.get_SMBus_Base_Address)
|
|
|
|
def test_display_SMBus_info(self):
|
|
reg_read_val = 123456
|
|
base_address = 456789
|
|
mock_cs = MagicMock()
|
|
mock_cs.register.is_defined.return_value = True
|
|
mock_cs.register.get_instance_by_name().read.return_value = reg_read_val
|
|
mock_cs.hals.iobar.is_IO_BAR_defined.return_value = True
|
|
mock_cs.hals.iobar.get_IO_BAR_base_address.return_value = (base_address, None)
|
|
smbus_hal = SMBus(mock_cs)
|
|
smbus_hal.logger = MagicMock()
|
|
smbus_hal.logger.HAL = True
|
|
smbus_hal.display_SMBus_info()
|
|
self.assertTrue(call(f'[smbus] SMBus Base Address: 0x{base_address:04X}') in smbus_hal.logger.log.call_args_list)
|
|
|
|
def test_is_SMBus_enabled(self):
|
|
mock_cs = MagicMock()
|
|
smbus_hal = SMBus(mock_cs)
|
|
mock_cs.device.is_enabled.return_value = True
|
|
self.assertTrue(smbus_hal.is_SMBus_enabled())
|
|
|
|
def test_is_SMBus_supported_valid(self):
|
|
did = 1234
|
|
vid = 0x8086
|
|
mock_cs = MagicMock()
|
|
smbus_hal = SMBus(mock_cs)
|
|
mock_cs.device.get_VendorID.return_value = (did, vid)
|
|
self.assertTrue(smbus_hal.is_SMBus_supported())
|
|
|
|
def test_is_SMBus_supported_invalid(self):
|
|
mock_cs = MagicMock()
|
|
smbus_hal = SMBus(mock_cs)
|
|
mock_cs.device.get_bus.return_value = None
|
|
self.assertFalse(smbus_hal.is_SMBus_supported())
|
|
|
|
def test_is_SMBus_host_controller_enabled_valid(self):
|
|
hst_en = 1
|
|
mock_cs = MagicMock()
|
|
mock_cs.register.get_instance_by_name().get_field.return_value = hst_en
|
|
smbus_hal = SMBus(mock_cs)
|
|
self.assertEqual(smbus_hal.is_SMBus_host_controller_enabled(), hst_en)
|
|
|
|
def test_enable_SMBus_host_controller(self):
|
|
mock_cs = MagicMock()
|
|
mock_cs.register.get_instance_by_name().read.return_value = 0
|
|
smbus_hal = SMBus(mock_cs)
|
|
smbus_hal.enable_SMBus_host_controller()
|
|
self.assertEqual(smbus_hal.cs.register.get_instance_by_name().write.call_count, 1)
|
|
self.assertEqual(smbus_hal.cs.register.get_instance_by_name().read.call_count, 1)
|
|
|
|
# enable_SMBus_io_mem_space
|
|
def test_enable_SMBus_io_mem_space(self):
|
|
mock_cs = MagicMock()
|
|
mock_cs.register.get_instance_by_name().read.return_value = 0
|
|
smbus_hal = SMBus(mock_cs)
|
|
smbus_hal.enable_SMBus_io_mem_space()
|
|
self.assertEqual(smbus_hal.cs.register.get_instance_by_name().write.call_count, 1)
|
|
self.assertEqual(smbus_hal.cs.register.get_instance_by_name().read.call_count, 1)
|
|
|
|
# enable_pch_i2c_comm
|
|
def test_enable_pch_i2c_comm(self):
|
|
mock_cs = MagicMock()
|
|
mock_cs.register.get_instance_by_name().read.return_value = 0
|
|
smbus_hal = SMBus(mock_cs)
|
|
smbus_hal.enable_pch_i2c_comm()
|
|
self.assertEqual(smbus_hal.cs.register.get_instance_by_name().write.call_count, 1)
|
|
self.assertEqual(smbus_hal.cs.register.get_instance_by_name().read.call_count, 2)
|
|
|
|
def test_disable_pch_i2c_comm(self):
|
|
mock_cs = MagicMock()
|
|
mock_cs.register.get_instance_by_name().read.return_value = 0xF
|
|
smbus_hal = SMBus(mock_cs)
|
|
smbus_hal.disable_pch_i2c_comm()
|
|
self.assertEqual(smbus_hal.cs.register.get_instance_by_name().write.call_count, 1)
|
|
self.assertEqual(smbus_hal.cs.register.get_instance_by_name().read.call_count, 2)
|
|
|
|
def test_reset_SMBus_controller_valid(self):
|
|
mock_cs = MagicMock()
|
|
smbus_hal = SMBus(mock_cs)
|
|
mock_cs.register.get_instance_by_name().read.side_effect = [321, 0x8, 0]
|
|
self.assertTrue(smbus_hal.reset_SMBus_controller())
|
|
self.assertEqual(smbus_hal.cs.register.get_instance_by_name().read.call_count, 3)
|
|
|
|
def test_reset_SMBus_controller_invalid(self):
|
|
mock_cs = MagicMock()
|
|
smbus_hal = SMBus(mock_cs)
|
|
mock_cs.register.get_instance_by_name().read.return_value = 0x8
|
|
self.assertFalse(smbus_hal.reset_SMBus_controller())
|
|
self.assertEqual(smbus_hal.cs.register.get_instance_by_name().read.call_count, SMBUS_POLL_COUNT + 1)
|
|
|
|
def test__is_smbus_ready_valid(self):
|
|
mock_cs = MagicMock()
|
|
smbus_hal = SMBus(mock_cs)
|
|
mock_cs.register.get_instance_by_name().get_field.return_value = 0
|
|
mock_cs.register.get_instance_by_name().value = 0
|
|
self.assertTrue(smbus_hal._is_smbus_ready())
|
|
self.assertEqual(smbus_hal.cs.register.get_instance_by_name.return_value.get_field.call_count, 1)
|
|
|
|
def test__is_smbus_ready_invalid(self):
|
|
mock_cs = MagicMock()
|
|
smbus_hal = SMBus(mock_cs)
|
|
mock_cs.register.get_instance_by_name().get_field.return_value = 1
|
|
mock_cs.register.get_instance_by_name().value = 1
|
|
self.assertFalse(smbus_hal._is_smbus_ready())
|
|
self.assertEqual(smbus_hal.cs.register.get_instance_by_name().get_field.call_count, SMBUS_POLL_COUNT)
|
|
|
|
def test__wait_for_cycle_pass(self):
|
|
mock_cs = MagicMock()
|
|
smbus_hal = SMBus(mock_cs)
|
|
mock_cs.register.get_instance_by_name().get_field.side_effect = [0, 0, 0, 0]
|
|
self.assertTrue(smbus_hal._wait_for_cycle())
|
|
|
|
def test__wait_for_cycle_fail(self):
|
|
mock_cs = MagicMock()
|
|
smbus_hal = SMBus(mock_cs)
|
|
smbus_hal.logger = MagicMock()
|
|
smbus_hal.logger.HAL = True
|
|
mock_cs.register.get_field.side_effect = [1, 1, 1]
|
|
self.assertFalse(smbus_hal._wait_for_cycle())
|
|
|
|
def test__wait_for_cycle_invalid_dev_err(self):
|
|
mock_cs = MagicMock()
|
|
smbus_hal = SMBus(mock_cs)
|
|
smbus_hal.logger = MagicMock()
|
|
smbus_hal.logger.HAL = True
|
|
mock_cs.register.get_instance_by_name().get_field.side_effect = [1, 1, 0, 1]
|
|
self.assertFalse(smbus_hal._wait_for_cycle())
|
|
|
|
|
|
def test_read_byte_pass(self):
|
|
mock_cs = MagicMock()
|
|
smbus_hal = SMBus(mock_cs)
|
|
read_field_val = 1234
|
|
mock_cs.register.get_instance_by_name().read.return_value = read_field_val
|
|
mock_cs.register.get_instance_by_name().read_field.return_value = 0
|
|
mock_cs.register.get_instance_by_name().get_field.return_value = 0
|
|
mock_cs.register.get_instance_by_name().value = 0
|
|
self.assertEqual(smbus_hal.read_byte(1, 2), [read_field_val])
|
|
|
|
def test_read_byte_fail(self):
|
|
mock_cs = MagicMock()
|
|
smbus_hal = SMBus(mock_cs)
|
|
mock_cs.register.get_instance_by_name().read_field.return_value = 0
|
|
mock_cs.register.get_instance_by_name().get_field.return_value = 1
|
|
mock_cs.register.get_instance_by_name().value = 1
|
|
self.assertEqual(smbus_hal.read_byte(1, 2), False)
|
|
|
|
def test_write_byte_pass(self):
|
|
mock_cs = MagicMock()
|
|
smbus_hal = SMBus(mock_cs)
|
|
mock_cs.register.get_instance_by_name().read_field.return_value = 0
|
|
mock_cs.register.get_instance_by_name().get_field.return_value = 0
|
|
mock_cs.register.get_instance_by_name().value = 0
|
|
self.assertTrue(smbus_hal.write_byte(1, 2, 3))
|
|
|
|
def test_write_byte_fail(self):
|
|
mock_cs = MagicMock()
|
|
smbus_hal = SMBus(mock_cs)
|
|
mock_cs.register.get_instance_by_name().read_field.return_value = 0
|
|
mock_cs.register.get_instance_by_name().get_field.return_value = 1
|
|
mock_cs.register.get_instance_by_name().value = 1
|
|
self.assertFalse(smbus_hal.write_byte(1, 2, 3))
|
|
|
|
def test_enable_with_i2c(self):
|
|
mock_cs = MagicMock()
|
|
smbus_hal = SMBus(mock_cs)
|
|
smbus_hal.i2c_mode = True
|
|
smbus_hal.enable()
|
|
self.assertEqual(smbus_hal.cs.register.get_instance_by_name().read.call_count, 7)
|
|
self.assertEqual(smbus_hal.cs.register.get_instance_by_name().get_field.call_count, 2)
|
|
|
|
def test_enable_without_i2c(self):
|
|
mock_cs = MagicMock()
|
|
smbus_hal = SMBus(mock_cs)
|
|
smbus_hal.i2c_mode = False
|
|
smbus_hal.enable()
|
|
self.assertEqual(smbus_hal.cs.register.get_instance_by_name().read.call_count, 5)
|
|
self.assertEqual(smbus_hal.cs.register.get_instance_by_name().get_field.call_count, 2)
|
|
|
|
def test_process_call(self):
|
|
mock_cs = MagicMock()
|
|
smbus_hal = SMBus(mock_cs)
|
|
mock_cs.register.get_instance_by_name().get_field.return_value = 0
|
|
mock_cs.register.get_instance_by_name().read.return_value = 0x5
|
|
mock_cs.register.get_instance_by_name().value = 0
|
|
self.assertTrue(smbus_hal.process_call(1, 1, 0x5, 0x5))
|
|
|
|
class TestSMBUSMmio(unittest.TestCase):
|
|
|
|
def test_enable_with_i2c(self):
|
|
mock_cs = MagicMock()
|
|
smbus_hal = SMBusMMIO(mock_cs)
|
|
smbus_hal.i2c_mode = True
|
|
smbus_hal.enable()
|
|
self.assertEqual(smbus_hal.cs.register.get_instance_by_name().read.call_count, 9)
|
|
self.assertEqual(smbus_hal.cs.register.get_instance_by_name().get_field.call_count, 2)
|
|
|
|
def test_enable_without_i2c(self):
|
|
mock_cs = MagicMock()
|
|
smbus_hal = SMBusMMIO(mock_cs)
|
|
smbus_hal.i2c_mode = False
|
|
smbus_hal.enable()
|
|
self.assertEqual(smbus_hal.cs.register.get_instance_by_name().read.call_count, 7)
|
|
self.assertEqual(smbus_hal.cs.register.get_instance_by_name().get_field.call_count, 2)
|
|
pass |