Initial import of NFC GNSS SDK project
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
MODULE = patchlib
|
||||
|
||||
include $(RIOTBASE)/Makefile.base
|
||||
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Offset = 0xD8010
|
||||
*
|
||||
* 00 0D 80 10
|
||||
* Bits 31-24 23-16 15-8 7-0
|
||||
* 0000 0000 0000 1101 1000 0000 0001 0000
|
||||
*
|
||||
* Bits 31-25 24 23 22 21-12 11-2 10
|
||||
* 0000000 0 0 0 0011011000 0000000100 00
|
||||
* S I1 I2 H L
|
||||
*
|
||||
* J1 = ~I1 ^ S = 1
|
||||
* J2 = ~I2 ^ S = 1
|
||||
* https://web.eecs.umich.edu/~prabal/teaching/eecs373-f10/readings/ARMv7-M_ARM.pdf
|
||||
* A.6.7.18
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define FIXED2_BL 0x3
|
||||
#define FIXED2_B 0x2
|
||||
/*---------------------------------------------------------------------------*/
|
||||
typedef union {
|
||||
struct {
|
||||
unsigned last1 : 1;
|
||||
unsigned imm11l : 11;
|
||||
unsigned imm10h : 10;
|
||||
unsigned i2 : 1;
|
||||
unsigned i1 : 1;
|
||||
unsigned s : 1;
|
||||
unsigned msb7 : 7;
|
||||
} o;
|
||||
int v;
|
||||
} bl_offset_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
unsigned imm11l : 11;
|
||||
unsigned j2 : 1;
|
||||
unsigned fixed1 : 1;
|
||||
unsigned j1 : 1;
|
||||
unsigned fixed2 : 2;
|
||||
unsigned imm10h : 10;
|
||||
unsigned s : 1;
|
||||
unsigned msb5 : 5;
|
||||
} i;
|
||||
unsigned v;
|
||||
} bl_instruction_t;
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/*
|
||||
* Provide the address shown in the disassembler for the instruction to
|
||||
* calculate for. When the code executes this will be PC.
|
||||
* Provide the address of the function (branch traget / btarget) the code
|
||||
* should branch to.
|
||||
* The return value will be an encode instruction ready to be an instruction
|
||||
* that can be patched into an ARM binary with a hex editor.
|
||||
* Why would you use this?
|
||||
* If you want to branch to a different function with the same (or at least
|
||||
* comptabile) signature, you can replace the branch instruction and
|
||||
* alter the code. This particular instruction is a little trickier than
|
||||
* direct branch instructions.
|
||||
*/
|
||||
static unsigned
|
||||
bl_encode_common(unsigned pc, unsigned target, unsigned fixed2)
|
||||
{
|
||||
bl_offset_t offset;
|
||||
bl_instruction_t final_instr;
|
||||
|
||||
pc += 4; /* Due to arm pipeline */
|
||||
pc &= 0xfffffffe; /* 2 byte alignment */
|
||||
|
||||
offset.v = target - pc;
|
||||
assert(offset.v < 16 * 1024 * 1024 && offset.v > -16 * 1024 * 1024);
|
||||
final_instr.v = 0;
|
||||
|
||||
/* bits 27-31 = 0b11110 */
|
||||
final_instr.i.msb5 = 0x1e;
|
||||
|
||||
/* bit 26 = S */
|
||||
final_instr.i.s = offset.o.s;
|
||||
|
||||
/* imm10h, bits 16-25 */
|
||||
final_instr.i.imm10h = offset.o.imm10h;
|
||||
|
||||
/* static */
|
||||
final_instr.i.fixed2 = fixed2;
|
||||
|
||||
/* j1 */
|
||||
final_instr.i.j1 = (offset.o.i1 ^ 0x1) ^ offset.o.s;
|
||||
|
||||
/* static */
|
||||
final_instr.i.fixed1 = 0x1;
|
||||
|
||||
/* j2 */
|
||||
final_instr.i.j2 = (offset.o.i2 ^ 0x1) ^ offset.o.s;
|
||||
|
||||
/* imm11l */
|
||||
final_instr.i.imm11l = offset.o.imm11l;
|
||||
|
||||
unsigned v = final_instr.v;
|
||||
v = v >> 16 | v << 16;
|
||||
|
||||
return v;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
unsigned
|
||||
bl_encode(unsigned pc, unsigned target)
|
||||
{
|
||||
return bl_encode_common(pc, target, FIXED2_BL);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
unsigned
|
||||
b_encode(unsigned pc, unsigned target)
|
||||
{
|
||||
return bl_encode_common(pc, target, FIXED2_B);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
Reference in New Issue
Block a user