The present document relates patching of program code. In particular, the present document relates a mechanism to support patching of program code executed from a one Time Programmable (OTP) memory.
The availability of high density OTP (One Time Programmable) memory macros creates a lower cost non-volatile program storage option for ICs with embedded processors (fewer mask layers are required than EEPROMs for example).
As its name suggests, OTP memory does not support (full) reprogramming of memory locations—either because of the use of an anti-fuse cell design or because (for floating gate designs) erasing requires exposure to UV light which is not typically possible once the device has been packaged. OTP memory has therefore been typically treated in the same way as read only memory (ROM) from the point of view of code storage, with the entire code footprint copied into shadow random access memory (RAM) before execution start. A patch table is then used to overlay code that needs to be updated.
Copying the OTP memory contents into RAM prior to enabling the processor requires not only a shadow RAM but also a boot loader to carry out the initial copy and then to overlay the patches. While the relatively higher current consumption of OTP read cycles compared to RAM may make this approach preferable it is not the case in all application areas. In particular where the processor is active for a small percentage of the time, the average current consumption difference is reduced and the area cost of silicon may become the dominant factor when deciding on the memory architecture. Some means of patching program code when executed from OTP memory is required.
A disadvantage of prior art is that it relies on additional hardware, external intervention or RAM. It would be desirable to use a mechanism to support patching of program code stored in and directly executed from OTP.
An object of the present disclosure is to create program code in an OTP memory using a processor instruction set that includes an ‘all zeroes’ or equivalent ‘benign’ operation code (opcode).
A further object of the present disclosure is to create program code in an OTP memory using a processor instruction set that includes a benign opcode that can be created by setting one or more bits of an existing opcode in a program to 0 or 1.
A further object of the present disclosure is to achieve the ability to set the OTP memory programming voltage and enable the programming mode of a packaged device.
A further object of the present disclosure is to achieve a mechanism to support patching of program code stored in and directly executed from OTP.
A further object of the present disclosure is to achieve a patch mechanism that does not rely on additional hardware, external intervention or RAM.
In accordance with the objects of this disclosure a method to support patching of program code executed from OTP memory at a subroutine level has been achieved. The method disclosed comprises the steps of: (1) providing an one-time programmable (OTP) memory and a means to convert bits of the OTP memory, wherein one or more hooks comprising jump instructions are inserted into an original code on the OTP memory such that subroutine calls can be made to a subroutine, (2) programming a new subroutine in the formerly unprogrammed OTP memory area; and (3) patching an existing hook jumping to a subroutine to be retired, wherein the modified hook is capable to jump to the new subroutine.
In accordance with the objects of this disclosure a method to support patching of program code executed from OTP memory at a subroutine level has been achieved. The method disclosed comprises the steps of: (1) providing an one-time programmable (OTP) memory and a means to convert bits of the OTP memory, wherein one or more hooks comprising jump instructions are inserted into an original code on the OTP memory such that subroutine calls can be made from the hook to a subroutine hook, wherein the hook comprises one or more instructions that jump to the subroutine, followed by a number of unprogrammed memory locations, (2) clearing the one or more existing jump instructions pointing to a subroutine to be retired, wherein the one or more jump instructions are replaced by some other benign instructions, (3) programming a new subroutine in the formerly unprogrammed OTP memory area, wherein the subroutine at the patch address begins itself with a hook header comprising one or more instructions that jump to the new subroutine, so that the new subroutine can be patched in turn thus enabling a further patch, and (4) programming new one or more jump instructions in formerly unprogrammed memory locations of the original hook, following the benign instructions of the previous step, wherein the new one or more jump instructions point to a patch address of a different subroutine in an unprogrammed OTP memory space.
The invention is explained below in an exemplary manner with reference to the accompanying drawings, wherein
Similar to other non-volatile memories (such as EEPROM), high density OTP memories usually have the same unprogrammed value of either ‘0’ for all bits or ‘1’ for all bits. The programming process is therefore the task of changing some of the bits to the opposite of the unprogrammed value. “One Time Programmable” in this respect means that any bit value may be inverted just once.
This disclosure takes advantage of the ability to program the OTP memory in several passes (patches), with each pass inverting more unprogrammed bits of the memory.
The following description and examples assume OTP with an unprogrammed value of ‘1’ in all bits. This is for clarity only—the techniques are equally applicable for OTP with an unprogrammed value of ‘0’ as well.
Code patching is done at the subroutine level. Hooks are inserted into the original code such that subroutine calls are made to the subroutine hook rather than directly to the subroutine start address itself. The hook contains one or more instructions that jump to the subroutine, followed by the same number of (or fewer or more) unprogrammed memory locations. The number of memory locations depends on the instruction set available and the position of the unprogrammed OTP space. As an example areas of unprogrammed OTP space may be always located within “short jump” range of a subroutine hook, whereas the subroutine hook itself might require a “long jump”. The instruction set may require different numbers of instruction operation codes (opcodes) to implement “short jump” and “long jump”.
Patching is carried out by changing the jump instruction(s) into some other ‘benign’ instruction(s), followed by a jump to a different subroutine address (the patch address). A benign instruction is defined as any instruction that does not modify the state of the processor, including register and flag values. Program execution continues with the next instruction after the benign instruction.
The unprogrammed locations for operation codes are available to program the new jump instruction. The processor should ‘fall through’ the modified codes to reach the new jump instruction.
The subroutine at the patch address should itself begin with a hook, so that it can in turn be patched.
Here is an example subroutine hook at address 0x8000 using an imaginary 16-bit instruction set:
The hook contains as an example 3 operation codes (opcodes) (jump to address 0xA55A) followed by 3 unprogrammed operation codes locations, wherein a first operation code loads the most significant part of an address into the most significant part of a register, a second operation code loads the least significant part of an address into the least significant part of said register, and the third operation code performs the jump to the address defined in the register. It should be noted that other numbers of the programmed operation codes and other numbers of the unprogrammed operation codes locations may be used.
It should be noted that in the above example register A is clobbered as part of the jump process. It may be preferable, if possible, to create the jump without affecting any registers or flags.
The instruction set in the following example has a “jump immediate” instruction that expects the full jump address to be contained in the next address location. In this case the jump address does not first need to be loaded into a register.
The Opcode 0x0000 in our imaginary instruction set corresponds to the NOP (no operation) instruction. By programming all opcode bits to 0 an instruction can therefore always be changed to NOP, regardless of its previous value. The first step in applying a patch is to clear the existing jump instructions:
Every daisy chain step adds further delay before the subroutine begins. This should be considered as part of the patch preparation process.
Sometimes the jump code in the hook can be optimized to minimize the additional latency, for example:
The above optimization is only possible if the necessary instructions are available in the instruction set.
The above example adds 2 to the current program counter value (which will already be loaded with the next instruction address) and stores it in register A. The next instruction is an indirect load:
1) A0x8004
2) PC0xA55A
[0x8004]
[A]
The program counter is loaded with the value 0xA55A, which is equivalent to a jump to that address. The OTP space needed to store the instructions is the same as before, but this time the jump is achieved in only 2 instructions rather than 3. There are still 3 memory reads required so the end result will depend on the processor and bus interface architecture.
The number of memory locations required to describe the jump operation may be less than, the same as or more than the number of unprogrammed memory locations reserved for patching. In each case the number of memory locations may be less than 3, 3, or more than 3.
In latency critical applications, there may be ways to limit the length of the daisy-chain:
For some instruction sets the ‘all zeroes’ or ‘all ones’ opcode is not equivalent to a transparent NOP instruction. In these cases an alternative must be found.
If every hook consists of the same known opcode sequence, for example a register load followed by a jump, it may be possible to modify the opcodes so that the new opcodes have the equivalent function to a NOR Careful opcode selection for the initial hook will be required to allow this to happen.
Suppose in our initial example that the all zeroes opcode is not a NOP, but a register move instruction can be created by changing some of the existing opcode bits to 0.
A register move to itself is effectively a NOP (as long as no flags are updated in the process). If the MOV, B, B instruction opcode is by chance 0x1400, then the modified hook could be:
With performing non-destructive patching, modifications are only made to the hook headers, not the subroutine bodies themselves. This means that a patch can be reversed at any time by branching back to the original subroutine body in the current hook.
Furthermore an additional subroutine can be inserted into a flow of subroutines by programming said additional subroutine in the unprogrammed OTP memory area and by patching the hook header of an original subroutine to jump to the additional subroutine, then by branching back from a hook of the additional subroutine to a body of said original subroutine.
Nested Subroutine Calls
A first step 40 shows providing an one-time programmable (OTP) memory and a means to convert bits of the OTP memory, wherein one or more hooks comprising jump instructions are inserted into an original code on the OTP memory such that subroutine calls can be made from the hook to a subroutine hook rather than directly to the subroutine start address itself.
The next step 41 describes programming a new subroutine in the formerly unprogrammed OTP memory area, and the last step 42 illustrates patching an existing hook jumping to a subroutine to be retired, wherein the modified hook is capable to jump to the new subroutine.
A first step 50 shows providing an one-time programmable (OTP) memory and a means to convert bits of the OTP memory, wherein one or more hooks comprising jump instructions are inserted into an original code on the OTP memory such that subroutine calls can be made from the hook to a subroutine hook rather than directly to the subroutine start address itself, wherein the hook comprises one or more instructions that jump to the subroutine, followed by a number of unprogrammed memory locations.
It should be noted that tools to convert bits of an OTP memory will be specific to the chip. One example requires a 7.5V programming voltage to be connected to a pin with the programming sequence controlled by writing to on-chip registers.
The following step 51 describes clearing the one or more existing jump instructions pointing to a subroutine to be retired, wherein the one or more jump instructions are replaced by some other benign instructions. Step 52 shows programming a new subroutine in the formerly unprogrammed OTP memory area, wherein the subroutine at the patch address begins itself with a hook header comprising one or more instructions that jump to the new subroutine, so that the new subroutine can be patched in turn thus enabling a further patch. Finally step 53 illustrates programming new one or more jump instructions in formerly unprogrammed memory locations of the original hook, following the benign instructions of the previous step, wherein the new one or more jump instructions point to a patch address of a different subroutine in an unprogrammed OTP memory space.
While the invention has been particularly shown and described with reference to the preferred embodiments thereof, it will be understood by those skilled in the art that various changes in form and details may be made without departing from the spirit and scope of the invention.
Number | Date | Country | Kind |
---|---|---|---|
14368020.5 | Apr 2014 | EP | regional |