Cmep

The F00D processor performs most of the PSVita cryptography tasks including storing and handing of the most secure keys. There is little information about it though. It was named after the  field of the ELF headers, but its official name is CMeP (Control MeP). CMEP is a Toshiba MeP-c5 core.

More information can be found in Toshiba documentations. For example: https://toshiba.semicon-storage.com/info/docget.jsp?did=14997&prodName=TMPV7504XBG.

Communication
Communication seems to go through some sort of FIFO register.

Write
To write, put the double word into. Next read  until it returns 0, which indicates the data was read by the F00D processor.

Read
To read, get a double word from. If it returns 0, no data is available. Otherwise, acknowledge that the data has been read by putting the same data into.

Extra ports
In addition to the  and , the communication with F00D seems to happen with other ports too.

Protocol
A 32-bit command buffer is defined below. The command is sent to the F00D processor with the method listed above.

Command ID
There are a total of 14 commands. Below are notes on different commands. Commands pass data through the 0x100 shared buffer that is setup in command 0.

0x0
This command is used to setup a shared buffer with F00D. Firstly F00D will write in  either 0x200 or 0x600 (and if an error happened, 0x400 ?). If the value 0x600 is written, it will setup a buffer that contains the F00D secure_kernel.enp. It will write 0x1 to  and after that 0x0 to , next, it will wait   return 0 and   return a value <= 0x0. If everything goes alright, it will clear the low 2 bits of the F00D secure_kernel.enp address (normally at 0x1F850000) and OR it with 0x1 and then write it to. After it, the process is the same that the 0x200. If the value 0x200 is written, it will set the 0x100 sized shared buffer. The physical address of the buffer is written to  and then command 0x0 is written.

0x1
This command is called by a subroutine of SceSblSmsched or SceSblSmsched module_start (if an error happened while SceSblSmsched was initializing). This command seems to be used to ask F00D to remove all resource allocated (like shared memory address, secure module loaded, etc), and probably power off or reset it.

0x2
Load a sm.

0x3
Load previously suspended sm.

0x4
Suspend current sm.

0x5
Kill current sm.

0x6
Force stop? Called from sceSblSmSchedDeleteAll.

0x7
Unused.

0x8
Unused.

0x9
Set a 0x80 sized shared buffer.

This seems like a SceKernelPARange.

0xA
Set the encrypted signed revoke list.

Interrupts
There are 4 interrupts that F00D sends. There are only two interrupt handles, however.


 * : handles interrupt 200. This is notifications about current sm status changes (loaded, unloaded, suspended, etc)
 * : handles interrupts 201, 202, 203. This interrupt is sent once an sm command has finished processing (see below).

Executing SM commands
You can find an open source ARM TZ<->F00D protocol implementation at https://github.com/xyzz/f00d. It allows calling SM commands with a maximum of control over the sent data, received data and timing.

When a SM is loaded, you can execute a command it provides by writing into registers 0xE0000014, 0xE0000018, 0xE000001C paddr to the request buffer OR'd with 1.

Once result is available, ARM will get an interrupt 201-203. Read status code from 0xE0000004 (or 0xE0000008, 0xE000000C) and confirm you received it by writing it back to the same register.

Possible results:


 * 1: command executed successfully
 * 3: invalid command ID
 * 5: invalid command buffer paddr (e.g. trying to pass secure memory)
 * 9: SCE_SBL_ERROR_COMMON_EIO

Memory
F00D has its own private 128kB memory from  to. Secure Modules are typically loaded to. secure_kernel is loaded to.

SM Task states
ARM TrustZone implements a scheduler for SM tasks. Normally, only one task can run on F00D at a time. The external SM scheduler running on ARM allows to have multiple tasks at once. The following provides an explanation of various states the task can be in.