|
TIPRU(4) |
Device Drivers Manual (armv7) |
TIPRU(4) |
NAME
tipru — Texas Instruments programmable realtime unit controller
DESCRIPTION
The
tipru driver supports the Programmable Realtime Unit and Industrial Communication Subsystem (PRU-ICSS) integrated in Texas Instruments' line of AM335x SoCs. The PRU is a pair of 32-bit modified Harvard architecture processor cores which run a simple RISC instruction set. The PRU forgoes any kind of heuristic caching mechanisms (TLBs, L1/L2/etc caches) as well as instruction pipelining as to allow for completely predictable and deterministic timing behavior. The PRU is clocked at 200MHz and executes one instruction every cycle insofar as it operates within its local data/instruction/shared memory spaces (See
CAVEATS for additional details.)
tipru's primary interface is through its write-only character device file. Writes to this file populate the PRU's data/instruction/shared memory and must occur at predefined offsets. Further
ioctl(2) calls control the PRU's execution. All
write(2) operations and some
ioctl(2) operations must occur when the system's
securelevel(7) is equal to or lesser than zero, and only after
tipru has been explicitly enabled via
ioctl(2) call listed in the following section. (See
SECURITY CONSIDERATIONS for additional details.)
IOCTLS
The following
ioctl(2) commands are supported, and allowed only when system
securelevel(7) is lesser than or equal to zero:
-
PRUEN
-
Enables the tipru driver itself. All the following ioctl(2) calls in this section, along with all open(2) and write(2) operations attempted on tipru's character device file will fail if they are attempted before a successful call to this ioctl(2).
-
PRUIRQEN int *
-
Not yet implemented.
-
PRURESET
-
Halts all PRU cores, zeroes all data/instruction/shared memory, and resets cores' program counters.
The following
ioctl(2) commands are supported, and allowed only when system
securelevel(7) is greater than zero:
-
PRUIRQBLOCK int *
-
Not yet implemented.
-
PRUKILL
-
Halts and resets PRU cores, and zeroes all data/instruction/shared memory spaces. No further PRU activity occurs (or is even possible) after this ioctl(2) call is made until the system is rebooted.
The following
ioctl(2) commands are supported, and allowed regardless of system
securelevel(7):
-
PRUCTL int *
-
Start/halt PRU cores. Setting a core's *_SEL bit will change its execution state to whatever the corresponding *_EN bit specifies.
FILES
-
/dev/tipru
-
Character device for accessing PRU instruction/data space and controlling chip.
ERRORS
-
[ENODEV]
-
Character device was opened with mode other than O_WRONLY or a read(2) call was attempted.
-
[EBUSY]
-
Another process already has an open file descriptor on the character device file.
-
[ENOTSUPP]
-
Driver received an unsupported ioctl(2) call.
-
[ENOSYS]
-
Driver received an unimplemented ioctl(2) call.
-
[EFAULT]
-
write(2) attempted at offset not corresponding to top of PRU's data/instruction/shared memory.
-
[EOVERFLOW]
-
write(2) attempted that would overflow targeted memory space.
-
[EPERM]
-
write(2), open(2), or ioctl(2) call attempted by user other than root, or attempted when the system was in an improper securelevel(7) for the attempted call.
-
[ECANCELED]
-
Operation attempted after tipru driver was disabled via PRUKILL ioctl(2) call or attempted before a PRUEN ioctl(2) call completed successfully.
HISTORY
The tipru driver will hopefully soon appear in OpenBSD 6.0.
CAVEATS
While the PRU has its own data/instruction/shared memory, it is capable of accessing all physical addresses on the system (even its own control registers). Disabling the OCP ports (the mechanism through which the PRU accesses outside memory) provides no extra security as the PRU itself can arbitrarily enable it (See
BUGS for additional details.)
The PRU's runtime characteristics are only deterministic insofar as it accesses memory within its own local address space. All timing guarantees are forfeit once non-local memory is accessed.
BUGS
If the PRU attempts to access memory outside its own local address space, the system will hang unless the OCP master ports are enabled via the SYSCFG register. This is due to a silicon bug wholly irrectifiable by software (See AM335x Technical Reference Manual for additional details.)
SECURITY CONSIDERATIONS
The PRU has comprehensive and unconditional access to all physical memory present in the system. Accordingly,
tipru implements a number of additional safeguards to prevent exploitation, listed below:
-
tipru will only grant file descriptors, honor write(2) attempts, and process ioctl(2) calls from real root (ruid 0) regardless of the device file's permission bits, user login class, or current securelevel(7).
-
tipru comes disabled by default. Attempts to enable tipru, and following modification of the instruction/data/shared memory spaces, are only allowed when the system's securelevel(7) is equal or lesser than zero. When the system's securelevel(7) is greater than zero the PRU cores may only be started or halted via the PRUCTL ioctl(2) call, and the driver itself may be disabled via the PRUKILL ioctl(2) call which effectively halts and prevents the PRU from performing any actions until the system is rebooted.