Skip to content

Commit

Permalink
Update portio HAL to import halbase and simplify api
Browse files Browse the repository at this point in the history
Signed-off-by: Nathaniel Mitchell <[email protected]>
  • Loading branch information
npmitche committed Dec 12, 2024
1 parent ec3b1c4 commit 84f09ae
Show file tree
Hide file tree
Showing 13 changed files with 150 additions and 168 deletions.
4 changes: 2 additions & 2 deletions chipsec/cfg/parsers/registers/io.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,10 @@ def read(self):
"""Read the object"""
self.logger.log_debug(f'reading {self.name}')
_cs = cs()
self.value = _cs.hals.PortIO.read_port(self.io_port, self.size)
self.value = _cs.hals.Io.read(self.io_port, self.size)
return self.value

def write(self, value):
"""Write the object"""
_cs = cs()
_cs.hals.PortIO.write_port(self.io_port, value, self.size)
_cs.hals.Io.write(self.io_port, value, self.size)
4 changes: 2 additions & 2 deletions chipsec/cfg/parsers/registers/iobar.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ def read(self):
if self.io_port is None:
(self.bar_base, self.bar_size) = _cs.hals.PortIObar.get_IO_BAR_base_address(self.bar, self.instance)
self.io_port = self.bar_base + self.offset
self.value = _cs.hals.PortIO.read_port(self.io_port, self.size)
self.value = _cs.hals.Io.read(self.io_port, self.size)
self.logger.log_debug('done reading')
return self.value

Expand All @@ -77,4 +77,4 @@ def write(self, value):
if self.io_port is None:
(self.bar_base, self.bar_size) = _cs.hals.PortIObar.get_IO_BAR_base_address(self.bar, self.instance.instance)
self.io_port = self.bar_base + self.offset
_cs.hals.PortIO.write_port(self.io_port, value, self.size)
_cs.hals.Io.write(self.io_port, value, self.size)
24 changes: 12 additions & 12 deletions chipsec/hal/common/cmos.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,35 +52,35 @@ def __init__(self, cs):
super(CMOS, self).__init__(cs)

def read_cmos_high(self, offset: int) -> int:
self.cs.hals.PortIO.write_port_byte(CMOS_ADDR_PORT_HIGH, offset)
return self.cs.hals.PortIO.read_port_byte(CMOS_DATA_PORT_HIGH)
self.cs.hals.Io.write(CMOS_ADDR_PORT_HIGH, offset)
return self.cs.hals.Io.read(CMOS_DATA_PORT_HIGH)

def write_cmos_high(self, offset: int, value: int) -> None:
self.cs.hals.PortIO.write_port_byte(CMOS_ADDR_PORT_HIGH, offset)
self.cs.hals.PortIO.write_port_byte(CMOS_DATA_PORT_HIGH, value)
self.cs.hals.Io.write(CMOS_ADDR_PORT_HIGH, offset)
self.cs.hals.Io.write(CMOS_DATA_PORT_HIGH, value)

def read_cmos_low(self, offset: int) -> int:
self.cs.hals.PortIO.write_port_byte(CMOS_ADDR_PORT_LOW, 0x80 | offset)
return self.cs.hals.PortIO.read_port_byte(CMOS_DATA_PORT_LOW)
self.cs.hals.Io.write(CMOS_ADDR_PORT_LOW, 0x80 | offset)
return self.cs.hals.Io.read(CMOS_DATA_PORT_LOW)

def write_cmos_low(self, offset: int, value: int) -> None:
self.cs.hals.PortIO.write_port_byte(CMOS_ADDR_PORT_LOW, offset)
self.cs.hals.PortIO.write_port_byte(CMOS_DATA_PORT_LOW, value)
self.cs.hals.Io.write(CMOS_ADDR_PORT_LOW, offset)
self.cs.hals.Io.write(CMOS_DATA_PORT_LOW, value)

def dump_low(self) -> List[int]:
cmos_buf = [0xFF] * 0x80
orig = self.cs.hals.PortIO.read_port_byte(CMOS_ADDR_PORT_LOW)
orig = self.cs.hals.Io.read(CMOS_ADDR_PORT_LOW)
for off in range(0x80):
cmos_buf[off] = self.read_cmos_low(off)
self.cs.hals.PortIO.write_port_byte(CMOS_ADDR_PORT_LOW, orig)
self.cs.hals.Io.write(CMOS_ADDR_PORT_LOW, orig)
return cmos_buf

def dump_high(self) -> List[int]:
cmos_buf = [0xFF] * 0x80
orig = self.cs.hals.PortIO.read_port_byte(CMOS_ADDR_PORT_HIGH)
orig = self.cs.hals.Io.read(CMOS_ADDR_PORT_HIGH)
for off in range(0x80):
cmos_buf[off] = self.read_cmos_high(off)
self.cs.hals.PortIO.write_port_byte(CMOS_ADDR_PORT_HIGH, orig)
self.cs.hals.Io.write(CMOS_ADDR_PORT_HIGH, orig)
return cmos_buf

def dump(self) -> None:
Expand Down
22 changes: 11 additions & 11 deletions chipsec/hal/common/ec.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,29 +84,29 @@ class EC(hal_base.HALBase):
# Wait for EC input buffer empty
def _wait_ec_inbuf_empty(self) -> bool:
to = 1000
while (self.cs.hals.PortIO.read_port_byte(IO_PORT_EC_STATUS) & EC_STS_IBF) and to:
while (self.cs.hals.Io.read(IO_PORT_EC_STATUS) & EC_STS_IBF) and to:
to = to - 1
return True

# Wait for EC output buffer full
def _wait_ec_outbuf_full(self) -> bool:
to = 1000
while not (self.cs.hals.PortIO.read_port_byte(IO_PORT_EC_STATUS) & EC_STS_OBF) and to:
while not (self.cs.hals.Io.read(IO_PORT_EC_STATUS) & EC_STS_OBF) and to:
to = to - 1
return True

def write_command(self, command: int) -> None:
self._wait_ec_inbuf_empty()
return self.cs.hals.PortIO.write_port_byte(IO_PORT_EC_COMMAND, command)
return self.cs.hals.Io.write(IO_PORT_EC_COMMAND, command)

def write_data(self, data: int) -> None:
self._wait_ec_inbuf_empty()
return self.cs.hals.PortIO.write_port_byte(IO_PORT_EC_DATA, data)
return self.cs.hals.Io.write(IO_PORT_EC_DATA, data)

def read_data(self) -> Optional[int]:
if not self._wait_ec_outbuf_full():
return None
return self.cs.hals.PortIO.read_port_byte(IO_PORT_EC_DATA)
return self.cs.hals.Io.read(IO_PORT_EC_DATA)

def read_memory(self, offset: int) -> Optional[int]:
self.write_command(EC_COMMAND_ACPI_READ)
Expand Down Expand Up @@ -167,17 +167,17 @@ def write_range(self, start_offset: int, buffer: bytes) -> bool:
# EC Intex I/O access
#
def read_idx(self, offset: int) -> int:
self.cs.hals.PortIO.write_port_byte(IO_PORT_EC_INDEX_ADDRL, offset & 0xFF)
self.cs.hals.PortIO.write_port_byte(IO_PORT_EC_INDEX_ADDRH, (offset >> 8) & 0xFF)
value = self.cs.hals.PortIO.read_port_byte(IO_PORT_EC_INDEX_DATA)
self.cs.hals.Io.write(IO_PORT_EC_INDEX_ADDRL, offset & 0xFF)
self.cs.hals.Io.write(IO_PORT_EC_INDEX_ADDRH, (offset >> 8) & 0xFF)
value = self.cs.hals.Io.read(IO_PORT_EC_INDEX_DATA)
self.logger.log_hal(f'[ec] index read: offset 0x{offset:02X} > 0x{value:02X}:')
return value

def write_idx(self, offset: int, value: int) -> bool:
self.logger.log_hal(f'[ec] index write: offset 0x{offset:02X} < 0x{value:02X}:')
self.cs.hals.PortIO.write_port_byte(IO_PORT_EC_INDEX_ADDRL, offset & 0xFF)
self.cs.hals.PortIO.write_port_byte(IO_PORT_EC_INDEX_ADDRH, (offset >> 8) & 0xFF)
self.cs.hals.PortIO.write_port_byte(IO_PORT_EC_INDEX_DATA, value & 0xFF)
self.cs.hals.Io.write(IO_PORT_EC_INDEX_ADDRL, offset & 0xFF)
self.cs.hals.Io.write(IO_PORT_EC_INDEX_ADDRH, (offset >> 8) & 0xFF)
self.cs.hals.Io.write(IO_PORT_EC_INDEX_DATA, value & 0xFF)
return True


Expand Down
6 changes: 3 additions & 3 deletions chipsec/hal/common/interrupts.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,14 +76,14 @@ def send_SW_SMI_timed(self, thread_id: int, SMI_code_port_value: int, SMI_data_p

def send_SMI_APMC(self, SMI_code_port_value: int, SMI_data_port_value: int) -> None:
logger().log_hal(f"[intr] sending SMI via APMC ports: code 0xB2 <- 0x{SMI_code_port_value:02X}, data 0xB3 <- 0x{SMI_data_port_value:02X}")
self.cs.hals.PortIO.write_port_byte(SMI_DATA_PORT, SMI_data_port_value)
return self.cs.hals.PortIO.write_port_byte(SMI_APMC_PORT, SMI_code_port_value)
self.cs.hals.Io.write_port_byte(SMI_DATA_PORT, SMI_data_port_value)
return self.cs.hals.Io.write_port_byte(SMI_APMC_PORT, SMI_code_port_value)

def send_NMI(self) -> None:
logger().log_hal("[intr] Sending NMI# through TCO1_CTL[NMI_NOW]")
reg, ba = self.cs.device.get_IO_space("TCOBASE")
tcobase = self.cs.register.read_field(reg, ba)
return self.cs.hals.PortIO.write_port_byte(tcobase + NMI_TCO1_CTL + 1, NMI_NOW)
return self.cs.hals.Io.write_port_byte(tcobase + NMI_TCO1_CTL + 1, NMI_NOW)

def find_ACPI_SMI_Buffer(self) -> Optional[UEFI_TABLE.CommBuffInfo]:
logger().log_hal("Parsing ACPI tables to identify Communication Buffer")
Expand Down
111 changes: 53 additions & 58 deletions chipsec/hal/common/io.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,92 +23,87 @@
Access to Port I/O
usage:
>>> read_port_byte( 0x61 )
>>> read_port_word( 0x61 )
>>> read_port_dword( 0x61 )
>>> write_port_byte( 0x71, 0 )
>>> write_port_word( 0x71, 0 )
>>> write_port_dword( 0x71, 0 )
>>> read(0x61, 1)
>>> read_port_byte(0x61)
>>> read_port_word(0x61)
>>> read_port_dword(0x61)
>>> read_range(0x71, 0x4, 1)
>>> dump_range(0x71, 0x4, 1)
>>> write(0x71, 0, 1)
>>> write_port_byte(0x61, 0xAA)
>>> write_port_word(0x61, 0xAAAA)
>>> write_port_dword(0x61, 0xAAAAAAAA)
"""

from typing import List
from chipsec.hal.hal_base import HALBase
from chipsec.library.exceptions import SizeRuntimeError
from chipsec.library.logger import logger


class PortIO: #TODO: Refactor to derive from HALBase
class Io(HALBase):

def __init__(self, cs):
super(Io, self).__init__(cs)
self.helper = cs.helper
self.cs = cs
self.valid_sizes = [1, 2, 4]

def _read_port(self, io_port: int, size: int) -> int:
def read(self, io_port: int, size: int) -> int:
if size not in self.valid_sizes:
message = f'[HAL] [PortIO] Size of {size} is invalid. Valid sizes: {self.valid_sizes}'
logger().log_bad(message)
raise SizeRuntimeError(message)
value = self.helper.read_io_port(io_port, size)
if logger().HAL:
logger().log(f"[io] IN 0x{io_port:04X}: value = 0x{value:08X}, size = 0x{size:02X}")
logger().log_hal(f"[io] IN 0x{io_port:04X}: value = 0x{value:08X}, size = 0x{size:02X}")
return value

def _write_port(self, io_port: int, value: int, size: int) -> int:
if logger().HAL:
logger().log(f"[io] OUT 0x{io_port:04X}: value = 0x{value:08X}, size = 0x{size:02X}")
def write(self, io_port: int, value: int, size: int) -> int:
if size not in self.valid_sizes:
message = f'[HAL] [PortIO] Size of {size} is invalid. Valid sizes: {self.valid_sizes}'
logger().log_bad(message)
raise SizeRuntimeError(message)
logger().log_hal(f"[io] OUT 0x{io_port:04X}: value = 0x{value:08X}, size = 0x{size:02X}")
status = self.helper.write_io_port(io_port, value, size)
return status

def read_port_dword(self, io_port: int) -> int:
value = self.helper.read_io_port(io_port, 4)
if logger().HAL:
logger().log(f"[io] reading dword from I/O port 0x{io_port:04X} -> 0x{value:08X}")
return value

def read_port_word(self, io_port: int) -> int:
value = self.helper.read_io_port(io_port, 2)
if logger().HAL:
logger().log(f"[io] reading word from I/O port 0x{io_port:04X} -> 0x{value:04X}")
return value

def read_port_byte(self, io_port: int) -> int:
value = self.helper.read_io_port(io_port, 1)
if logger().HAL:
logger().log(f"[io] reading byte from I/O port 0x{io_port:04X} -> 0x{value:02X}")
return value

def write_port_byte(self, io_port: int, value: int) -> int:
if logger().HAL:
logger().log(f"[io] writing byte to I/O port 0x{io_port:04X} <- 0x{value:02X}")
status = self.helper.write_io_port(io_port, value, 1)
return status

def write_port_word(self, io_port: int, value: int) -> int:
if logger().HAL:
logger().log(f"[io] writing word to I/O port 0x{io_port:04X} <- 0x{value:04X}")
status = self.helper.write_io_port(io_port, value, 2)
return status

def write_port_dword(self, io_port: int, value: int) -> int:
if logger().HAL:
logger().log(f"[io] writing dword to I/O port 0x{io_port:04X} <- 0x{value:08X}")
status = self.helper.write_io_port(io_port, value, 4)
return status

#
# Read registers from I/O range
#
def read_IO(self, range_base: int, range_size: int, size: int = 1) -> List[int]:
def read_range(self, range_base: int, range_size: int, size: int = 1) -> List[int]:
n = range_size // size
io_ports = []
for i in range(n):
io_ports.append(self._read_port(range_base + i * size, size))
io_ports.append(self.read(range_base + i * size, size))
return io_ports

#
# Dump I/O range
#
def dump_IO(self, range_base: int, range_size: int, size: int = 1) -> None:
n = range_size // size
fmt = f'0{size * 2:d}X'
def dump_range(self, range_base: int, range_size: int, size: int = 1) -> None:
logger().log(f"[io] I/O register range [0x{range_base:04X}:0x{range_base:04X}+{range_size:04X}]:")
for i in range(n):
reg = self._read_port(range_base + i * size, size)
logger().log(f'+{size * i:04X}: {reg:{fmt}}')
read_ranges = self.read_range(range_base, range_size, size)
for i, read_val in enumerate(read_ranges):
logger().log(f'+{size * i:04X}: {read_val:{f'0{size * 2:d}X'}}')

def read_port_byte(self, io_port: int) -> int:
return self.read(io_port, 1)

def read_port_word(self, io_port: int) -> int:
return self.read(io_port, 2)

def read_port_dword(self, io_port: int) -> int:
return self.read(io_port, 4)

def write_port_byte(self, io_port: int, value: int) -> int:
return self.write(io_port, value, 1)

def write_port_word(self, io_port: int, value: int) -> int:
return self.write(io_port, value, 2)

def write_port_dword(self, io_port: int, value: int) -> int:
return self.write(io_port, value, 4)


haldata = {"arch":['FFFF'], 'name': ['PortIO']}
haldata = {"arch":['FFFF'], 'name': ['Io']}
8 changes: 4 additions & 4 deletions chipsec/hal/common/iobar.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ def read_IO_BAR_reg(self, bar_name: str, offset: int, size: int) -> int:
io_port = bar_base + offset
if offset > bar_size and logger().HAL:
logger().log_warning(f'offset 0x{offset:X} is outside {bar_name} size (0x{size:X})')
value = self.cs.hals.PortIO._read_port(io_port, size)
value = self.cs.hals.Io.read(io_port, size)
return value

#
Expand All @@ -128,7 +128,7 @@ def write_IO_BAR_reg(self, bar_name: str, offset: int, size: int, value: int) ->
io_port = bar_base + offset
if offset > bar_size and logger().HAL:
logger().log_warning(f'offset 0x{offset:X} is outside {bar_name} size (0x{size:X})')
return self.cs.hals.PortIO._write_port(io_port, value, size)
return self.cs.hals.Io.write(io_port, value, size)

#
# Check if I/O range is enabled by BAR name
Expand Down Expand Up @@ -189,7 +189,7 @@ def read_IO_BAR(self, bar_name: str, size: int = 1) -> List[int]:
n = range_size // size
io_ports = []
for i in range(n):
io_ports.append(self.cs.hals.PortIO._read_port(range_base + i * size, size))
io_ports.append(self.cs.hals.Io.read(range_base + i * size, size))
return io_ports

#
Expand All @@ -201,7 +201,7 @@ def dump_IO_BAR(self, bar_name: str, size: int = 1) -> None:
fmt = f'0{size * 2:d}X'
logger().log(f"[iobar] I/O BAR {bar_name}:")
for i in range(n):
reg = self.cs.hals.PortIO._read_port(range_base + i * size, size)
reg = self.cs.hals.Io.read(range_base + i * size, size)
logger().log(f'{size * i:+04X}: {reg:{fmt}}')


Expand Down
Loading

0 comments on commit 84f09ae

Please sign in to comment.