INL-retro-progdump/firmware/source/bootload.c

196 lines
5.6 KiB
C

#include "bootload.h"
//=================================================================================================
//
// BOOTLOAD operations
// This file includes all the bootload functions possible to be called from the bootload dictionary.
//
// See description of the commands contained here in shared/shared_dictionaries.h
//
//=================================================================================================
//const uint32_t fixed_const __attribute__((at(0x0800F000)));
//fixed_const= 0xDEADBEEF;
//int gSquared __attribute__((at(0x5000))); // Place at 0x5000
/* Desc:Function takes an opcode which was transmitted via USB
* then decodes it to call designated function.
* shared_dict_bootload.h is used in both host and fw to ensure opcodes/names align
* Pre: Macros must be defined in firmware pinport.h & bootload.h
* opcode must be defined in shared_dict_bootload.h
* Post:function call complete.
* Rtn: SUCCESS if opcode found, error if opcode not present or other problem.
*/
uint16_t addrh;
uint16_t *addr_ptr;
typedef void (*pFunction)(void);
uint8_t bootload_call( uint8_t opcode, uint8_t miscdata, uint16_t operand, uint8_t *rdata )
{
#define RD_LEN 0
#define RD0 1
#define RD1 2
#define RD2 3
#define RD3 4
#define BYTE_LEN 1
#define HWORD_LEN 2
#define WORD_LEN 4
pFunction JumpToApplication;
switch (opcode) {
#ifdef STM_CORE
//case JUMP_BL: jump_to_bootloader(); break;
//device won't respond after this point so actually expect an error to result
case LOAD_ADDRH: addrh = operand; break;
case JUMP_ADDR: //jump2addr((addrh<<16) | (operand)); break;
JumpToApplication = (void (*)(void)) ((addrh<<16|operand)); //Base of flash
//JumpToApplication = (void (*)(void)) (*((uint32_t *) ((0x1FFFC400 + 4)))); //jump to vector
JumpToApplication();
break;
//device may not respond depending on the address/function being jumped to
case PREP_FWUPDATE:
//while we are directly jumping to fwupdate section
//it should be okay since it's in a fixed location
return fwupdate_forever(); break;
//this function hijacked the stack frame to steal execution
//after returing from the current USB ISR
//it returns SUCCESS if it found and modified
//the stack frame successfully
//if it didn't find the stack frame it probably exceeded SRAM
//space and caused a hardfault.
//Once the USB ISR is completed, exectution left main application code for good
//will respond to usb interrupts, but are directed to fwupdater
case SET_PTR_HI:
addr_ptr = (uint16_t*) ((((uint32_t)addr_ptr) & 0x0000FFFF) | (operand<<16));
break;
case SET_PTR_LO:
addr_ptr = (uint16_t*) ((((uint32_t)addr_ptr) & 0xFFFF0000) | (operand));
break;
case GET_PTR:
//update ptr with offset
rdata[RD_LEN] = WORD_LEN;
rdata[RD0] = (uint32_t)addr_ptr;
rdata[RD1] = ((uint32_t)addr_ptr)>>8;
rdata[RD2] = ((uint32_t)addr_ptr)>>16;
rdata[RD3] = ((uint32_t)addr_ptr)>>24;
break;
case RD_PTR_OFFSET:
//use offset from current pointer but don't change it
rdata[RD_LEN] = HWORD_LEN;
rdata[RD0] = addr_ptr[operand];
rdata[RD1] = (addr_ptr[operand])>>8;
break;
case WR_PTR_OFFSET:
//use offset from current pointer but don't change it
addr_ptr[miscdata] = operand;
break;
case RD_PTR_OFF_UP:
//update ptr with offset
addr_ptr += operand;
rdata[RD_LEN] = HWORD_LEN;
rdata[RD0] = *addr_ptr;
rdata[RD1] = (*addr_ptr)>>8;
break;
case WR_PTR_OFF_UP:
//update ptr with miscdata
addr_ptr += miscdata;
//write operand to address that's being pointed to
*addr_ptr = operand;
break;
//can't get this to go where I want 0x08000800
//so for now I'll just put it there manually post-build
//can use the pointer to read 4bytes at 0x08000800
//which is the begining of application code space
//should include ascii "AV00" with the digits for version
// case GET_APP_VER:
// rdata[RD_LEN] = WORD_LEN;
// rdata[RD0] = app_version[0];
// rdata[RD1] = app_version[1];
// rdata[RD2] = app_version[2];
// rdata[RD3] = app_version[3];
// break;
default:
//opcode doesn't exist
return ERR_UNKN_BOOTLOAD_OPCODE;
#endif
}
return SUCCESS;
}
//void jump_to_bootloader()
//{
//
//#ifdef STM_INL6
//// 070C6 jump to: 0x1FFFC519
//// 070RB jump to: 0x1FFFCBC1
//
//
// asm(
// //"ldr pc, boot_addr\n\t"
//// "ldr r0, =0x12345678\n\t"
//// "mov r0, r0\n\t"
//// "mov r0, r0\n\t"
// //".p2align 2\n\t"
// //"boot_addr:\n\t"
// //".word 0x1FFFC519"
// "ldr r0, [pc, #8]\n\t"// @ remember pc is 8 bytes ahead
// "mov r13, r0\n\t" //load main stack pointer
// "ldr r0, [pc, #8]\n\t"// @ remember pc is 8 bytes ahead
// //"mov lr, r0\n\t"
// //"bx lr \n\t"// @ function return
// //"bkpt\n\t"
// "mov r0, r0\n\t"
// //"mov pc, r0\n\t"
// "bx r0\n\t"
// //"bootaddr\n\t"//
// //".word 0x1FFFC519" //070C6
// ".p2align 2\n\t"
// ".word 0x20001278\n\t" //C6 MSP @ reset
//// ".word 0x00010002\n\t"
// //".word 0x00030004\n\t"
// //".word 0x1FFFC519\n\t" //C6 AN2606
// ".word 0x1FFFCAC5\n\t" //C6 BL reset vector
// //".word 0x1FFFCBC1\n\t" //stlink PC when connecting with BL grounded
// //".word 0x1FFFC919\n\t" //best guess based on C6
// //".word 0x1FFFCBC1\n\t" //bootloader reset vector
// ".word 0x00050006\n\t"
// ".word 0x00070008\n\t"
//// ".word 0x1FFFC919\n\t"
//// ".word 0x1FFFC919\n\t"
//// ".word 0x1FFFC919\n\t"
//// ".word 0x1FFFC919\n\t"
//// ".word 0x1FFFC919\n\t"
// ".word 0x1FFFC919"
// //".word 0x1FFFCBC1"
// );
//bootaddr:
// asm(
// ".word 0xDEADBEEF"
// );
//
//#endif
//
//
//}