cros_ec_python.ioports.freebsdportio
This file provides a way to interact with the /dev/io device file on
FreeBSD.
1""" 2This file provides a way to interact with the `/dev/io` device file on 3FreeBSD. 4""" 5 6from typing import Final, IO 7from fcntl import ioctl 8import struct 9 10from .baseportio import PortIOClass 11 12IODEV_PIO_READ: Final = 0 13IODEV_PIO_WRITE: Final = 1 14 15 16def _IOC(inout: int, group: str, num: int, length: int): 17 """ 18 Create an ioctl command number. 19 Based on the FreeBSD kernels sys/sys/ioccom.h. 20 """ 21 IOCPARM_SHIFT: Final = 13 # number of bits for ioctl size 22 IOCPARM_MASK: Final = ((1 << IOCPARM_SHIFT) - 1) # parameter length mask 23 24 return (((inout) | (((length) & IOCPARM_MASK) << 16) | (ord(group) << 8) | (num))) 25 26 27def _IOWR(group: str, num: int, length: int): 28 """ 29 Create an ioctl command number for read/write commands. 30 Based on the FreeBSD kernels sys/sys/ioccom.h. 31 """ 32 IOC_VOID: Final = 0x20000000 # no parameters 33 IOC_OUT: Final = 0x40000000 # copy out parameters 34 IOC_IN: Final = 0x80000000 # copy in parameters 35 IOC_INOUT: Final = (IOC_IN|IOC_OUT) # copy parameters in and out 36 IOC_DIRMASK: Final = (IOC_VOID|IOC_OUT|IOC_IN) # mask for IN/OUT/VOID 37 return _IOC(IOC_INOUT, group, num, length) 38 39 40def IODEV_PIO(): 41 """ 42 Create an ioctl command number for the `/dev/io` device file. 43 """ 44 45 # struct iodev_pio_req { 46 # u_int access; 47 # u_int port; 48 # u_int width; 49 # u_int val; 50 # }; 51 52 length = struct.calcsize("IIII") 53 return _IOWR("I", 0, length) 54 55 56class FreeBsdPortIO(PortIOClass): 57 """ 58 A class to interact with the `/dev/io` device file on FreeBSD. 59 """ 60 61 _dev_io: IO | None = None 62 63 def __init__(self): 64 """ 65 Initialize the `/dev/port` device file. 66 """ 67 self._dev_io = open("/dev/io", "wb", buffering=0) 68 69 def __del__(self): 70 """ 71 Close the `/dev/port` device file. 72 """ 73 if self._dev_io: 74 self._dev_io.close() 75 76 def out_bytes(self, data: bytes, port: int) -> None: 77 """ 78 Write data to the specified port. 79 :param data: Data to write. 80 :param port: Port to write to. 81 """ 82 iodev_pio_req = struct.pack( 83 "IIII", IODEV_PIO_WRITE, port, len(data), int.from_bytes(data, "little") 84 ) 85 ioctl(self._dev_io, IODEV_PIO(), iodev_pio_req) 86 87 def outb(self, data: int, port: int) -> None: 88 """ 89 Write a byte (8 bit) to the specified port. 90 :param data: Byte to write. 91 :param port: Port to write to. 92 """ 93 self.out_bytes(data.to_bytes(1, "little"), port) 94 95 def outw(self, data: int, port: int) -> None: 96 """ 97 Write a word (16 bit) to the specified port. 98 :param data: Word to write. 99 :param port: Port to write to. 100 """ 101 self.out_bytes(data.to_bytes(2, "little"), port) 102 103 def outl(self, data: int, port: int) -> None: 104 """ 105 Write a long (32 bit) to the specified port. 106 :param data: Long to write. 107 :param port: Port to write to. 108 """ 109 self.out_bytes(data.to_bytes(4, "little"), port) 110 111 def in_bytes(self, port: int, num: int) -> bytes: 112 """ 113 Read data from the specified port. 114 :param port: Port to read from. 115 :param num: Number of bytes to read (1 - 4). 116 :return: Data read. 117 """ 118 iodev_pio_req = struct.pack("IIII", IODEV_PIO_READ, port, num, 0) 119 return ioctl(self._dev_io, IODEV_PIO(), iodev_pio_req)[struct.calcsize("III") :] 120 121 def inb(self, port: int) -> int: 122 """ 123 Read a byte (8 bit) from the specified port. 124 :param port: Port to read from. 125 :return: Byte read. 126 """ 127 return int.from_bytes(self.in_bytes(port, 1), "little") 128 129 def inw(self, port: int) -> int: 130 """ 131 Read a word (16 bit) from the specified port. 132 :param port: Port to read from. 133 :return: Word read. 134 """ 135 return int.from_bytes(self.in_bytes(port, 2), "little") 136 137 def inl(self, port: int) -> int: 138 """ 139 Read a long (32 bit) from the specified port. 140 :param port: Port to read from. 141 :return: Long read. 142 """ 143 return int.from_bytes(self.in_bytes(port, 4), "little") 144 145 def ioperm(self, port: int, num: int, turn_on: bool) -> None: 146 """ 147 `ioperm` stub function. The iopl will already be raised from opening `/dev/io` and is not required. 148 """ 149 pass 150 151 def iopl(self, level: int) -> None: 152 """ 153 `iopl` stub function. The iopl will already be raised from opening `/dev/io` and is not required. 154 """ 155 pass
IODEV_PIO_READ: Final =
0
IODEV_PIO_WRITE: Final =
1
def
IODEV_PIO():
41def IODEV_PIO(): 42 """ 43 Create an ioctl command number for the `/dev/io` device file. 44 """ 45 46 # struct iodev_pio_req { 47 # u_int access; 48 # u_int port; 49 # u_int width; 50 # u_int val; 51 # }; 52 53 length = struct.calcsize("IIII") 54 return _IOWR("I", 0, length)
Create an ioctl command number for the /dev/io device file.
57class FreeBsdPortIO(PortIOClass): 58 """ 59 A class to interact with the `/dev/io` device file on FreeBSD. 60 """ 61 62 _dev_io: IO | None = None 63 64 def __init__(self): 65 """ 66 Initialize the `/dev/port` device file. 67 """ 68 self._dev_io = open("/dev/io", "wb", buffering=0) 69 70 def __del__(self): 71 """ 72 Close the `/dev/port` device file. 73 """ 74 if self._dev_io: 75 self._dev_io.close() 76 77 def out_bytes(self, data: bytes, port: int) -> None: 78 """ 79 Write data to the specified port. 80 :param data: Data to write. 81 :param port: Port to write to. 82 """ 83 iodev_pio_req = struct.pack( 84 "IIII", IODEV_PIO_WRITE, port, len(data), int.from_bytes(data, "little") 85 ) 86 ioctl(self._dev_io, IODEV_PIO(), iodev_pio_req) 87 88 def outb(self, data: int, port: int) -> None: 89 """ 90 Write a byte (8 bit) to the specified port. 91 :param data: Byte to write. 92 :param port: Port to write to. 93 """ 94 self.out_bytes(data.to_bytes(1, "little"), port) 95 96 def outw(self, data: int, port: int) -> None: 97 """ 98 Write a word (16 bit) to the specified port. 99 :param data: Word to write. 100 :param port: Port to write to. 101 """ 102 self.out_bytes(data.to_bytes(2, "little"), port) 103 104 def outl(self, data: int, port: int) -> None: 105 """ 106 Write a long (32 bit) to the specified port. 107 :param data: Long to write. 108 :param port: Port to write to. 109 """ 110 self.out_bytes(data.to_bytes(4, "little"), port) 111 112 def in_bytes(self, port: int, num: int) -> bytes: 113 """ 114 Read data from the specified port. 115 :param port: Port to read from. 116 :param num: Number of bytes to read (1 - 4). 117 :return: Data read. 118 """ 119 iodev_pio_req = struct.pack("IIII", IODEV_PIO_READ, port, num, 0) 120 return ioctl(self._dev_io, IODEV_PIO(), iodev_pio_req)[struct.calcsize("III") :] 121 122 def inb(self, port: int) -> int: 123 """ 124 Read a byte (8 bit) from the specified port. 125 :param port: Port to read from. 126 :return: Byte read. 127 """ 128 return int.from_bytes(self.in_bytes(port, 1), "little") 129 130 def inw(self, port: int) -> int: 131 """ 132 Read a word (16 bit) from the specified port. 133 :param port: Port to read from. 134 :return: Word read. 135 """ 136 return int.from_bytes(self.in_bytes(port, 2), "little") 137 138 def inl(self, port: int) -> int: 139 """ 140 Read a long (32 bit) from the specified port. 141 :param port: Port to read from. 142 :return: Long read. 143 """ 144 return int.from_bytes(self.in_bytes(port, 4), "little") 145 146 def ioperm(self, port: int, num: int, turn_on: bool) -> None: 147 """ 148 `ioperm` stub function. The iopl will already be raised from opening `/dev/io` and is not required. 149 """ 150 pass 151 152 def iopl(self, level: int) -> None: 153 """ 154 `iopl` stub function. The iopl will already be raised from opening `/dev/io` and is not required. 155 """ 156 pass
A class to interact with the /dev/io device file on FreeBSD.
FreeBsdPortIO()
64 def __init__(self): 65 """ 66 Initialize the `/dev/port` device file. 67 """ 68 self._dev_io = open("/dev/io", "wb", buffering=0)
Initialize the /dev/port device file.
def
out_bytes(self, data: bytes, port: int) -> None:
77 def out_bytes(self, data: bytes, port: int) -> None: 78 """ 79 Write data to the specified port. 80 :param data: Data to write. 81 :param port: Port to write to. 82 """ 83 iodev_pio_req = struct.pack( 84 "IIII", IODEV_PIO_WRITE, port, len(data), int.from_bytes(data, "little") 85 ) 86 ioctl(self._dev_io, IODEV_PIO(), iodev_pio_req)
Write data to the specified port.
Parameters
- data: Data to write.
- port: Port to write to.
def
outb(self, data: int, port: int) -> None:
88 def outb(self, data: int, port: int) -> None: 89 """ 90 Write a byte (8 bit) to the specified port. 91 :param data: Byte to write. 92 :param port: Port to write to. 93 """ 94 self.out_bytes(data.to_bytes(1, "little"), port)
Write a byte (8 bit) to the specified port.
Parameters
- data: Byte to write.
- port: Port to write to.
def
outw(self, data: int, port: int) -> None:
96 def outw(self, data: int, port: int) -> None: 97 """ 98 Write a word (16 bit) to the specified port. 99 :param data: Word to write. 100 :param port: Port to write to. 101 """ 102 self.out_bytes(data.to_bytes(2, "little"), port)
Write a word (16 bit) to the specified port.
Parameters
- data: Word to write.
- port: Port to write to.
def
outl(self, data: int, port: int) -> None:
104 def outl(self, data: int, port: int) -> None: 105 """ 106 Write a long (32 bit) to the specified port. 107 :param data: Long to write. 108 :param port: Port to write to. 109 """ 110 self.out_bytes(data.to_bytes(4, "little"), port)
Write a long (32 bit) to the specified port.
Parameters
- data: Long to write.
- port: Port to write to.
def
in_bytes(self, port: int, num: int) -> bytes:
112 def in_bytes(self, port: int, num: int) -> bytes: 113 """ 114 Read data from the specified port. 115 :param port: Port to read from. 116 :param num: Number of bytes to read (1 - 4). 117 :return: Data read. 118 """ 119 iodev_pio_req = struct.pack("IIII", IODEV_PIO_READ, port, num, 0) 120 return ioctl(self._dev_io, IODEV_PIO(), iodev_pio_req)[struct.calcsize("III") :]
Read data from the specified port.
Parameters
- port: Port to read from.
- num: Number of bytes to read (1 - 4).
Returns
Data read.
def
inb(self, port: int) -> int:
122 def inb(self, port: int) -> int: 123 """ 124 Read a byte (8 bit) from the specified port. 125 :param port: Port to read from. 126 :return: Byte read. 127 """ 128 return int.from_bytes(self.in_bytes(port, 1), "little")
Read a byte (8 bit) from the specified port.
Parameters
- port: Port to read from.
Returns
Byte read.
def
inw(self, port: int) -> int:
130 def inw(self, port: int) -> int: 131 """ 132 Read a word (16 bit) from the specified port. 133 :param port: Port to read from. 134 :return: Word read. 135 """ 136 return int.from_bytes(self.in_bytes(port, 2), "little")
Read a word (16 bit) from the specified port.
Parameters
- port: Port to read from.
Returns
Word read.
def
inl(self, port: int) -> int:
138 def inl(self, port: int) -> int: 139 """ 140 Read a long (32 bit) from the specified port. 141 :param port: Port to read from. 142 :return: Long read. 143 """ 144 return int.from_bytes(self.in_bytes(port, 4), "little")
Read a long (32 bit) from the specified port.
Parameters
- port: Port to read from.
Returns
Long read.
def
ioperm(self, port: int, num: int, turn_on: bool) -> None:
146 def ioperm(self, port: int, num: int, turn_on: bool) -> None: 147 """ 148 `ioperm` stub function. The iopl will already be raised from opening `/dev/io` and is not required. 149 """ 150 pass
ioperm stub function. The iopl will already be raised from opening /dev/io and is not required.