📄 bf561_prom16.dsp
字号:
[P1+OFFSET_(SICA_IWR1)] = R3;
//----------------------------------------------------------
// Set DMA for 16-bit flash read with modify = 2 bytes
//----------------------------------------------------------
// Source Modify = 2
R6 = 0x2 (Z);
W[P1+OFFSET_(MDMA2_S0_X_MODIFY)] = R6;
// Destination Modify = 2 for 16 bit transfers
W[P1+OFFSET_(MDMA2_D0_X_MODIFY)] = R6;
// set the DMA config words for 16 bit DMA transfers
// Source DMAConfig Value (16-bit words)
R3.L = 0x5;
R3.H = 0;
// Destination DMAConfig Value (16-bit words)
R4.L = 0x87;
R4.H = 0;
// Read the DXE count for each DXE we want to skip
// beginning with DXE #0, which was the 2nd stage loader
// P0 Points to the beginning of CORE MMR Space
P0.H = UPPER_(COREMMR_BASE);
P0.L = LOWER_(COREMMR_BASE);
// see if it's the load program command (0)
R2.L = 0;
R2.H = 0;
CC = R0 == R2;
IF CC JUMP LOAD_PROGRAM;
// see if it's the jump to user program command (1)
R2.L = 1;
CC = R0 == R2;
IF !CC JUMP COMMAND_ERROR;
P0.L = JUMP_USER_PROGRAM;
P0.H = JUMP_USER_PROGRAM;
JUMP (P0);
COMMAND_ERROR:
R0.L = 0x05;
R0.H = 0x00;
RTS;
LOAD_PROGRAM:
// R1 = WHICH program to load; put it in R5
R5 = R1;
// The following must be repeated for each DXE we want to skip over,
// to get to the DXE we want to boot load. R5 will contain the DXE#.
// skip the global header
// now we are pointing to the ten byte block header for the DXE count.
R0.L = 0x0004;
R0.H = 0x2000;
SKIP_DXE:
// skip the DXE count 10 byte header
R0 += 10;
// R1 is destination address
R1.L = LOWER_(GPStorage);
R1.H = UPPER_(GPStorage);
// count value for reading 4 byte DXE byte count
R2 = 0x2 (Z);
CALL MEM_DMA;
// Update the Source Address
R0 = [P1+OFFSET_(MDMA2_S0_CURR_ADDR)];
// Get the value just read from the external device = DXE count
P3 = R1;
nop;nop;nop;nop;
R1 = [P3];
// Add the DXE count to the current source pointer
R0 = R0 + R1;
R5 += -1;
CC = R5 == 0;
IF !CC JUMP SKIP_DXE;
// The above would be repeated to read DXE 2, 3, 4, etc.
//-----------------------------------------------------------------------
// Reading the block header
//-----------------------------------------------------------------------
.ALIGN 2;
FGRAB_HEADER:
// From now on, P3 Points to the Header Buffer in core A scratch
P3.L = LOWER_(HeaderBuffer);
P3.H = UPPER_(HeaderBuffer);
// DMA Destination Address
R1 = P3; // P3 contains the destination pointer
// Count Value for Header: 10 bytes, 5 words
R2 = 0x5 (Z);
// Source Modify = 2 = 16 bit transfer from Flash
R6 = 0x2 (Z); //
W[P1+OFFSET_(MDMA2_S0_X_MODIFY)] = R6;
// Destination Modify = 2 for 16 bit transfers
W[P1+OFFSET_(MDMA2_D0_X_MODIFY)] = R6;
CALL MEM_DMA;
// Get Source Base Address
R0 = [P1+OFFSET_(MDMA2_S0_CURR_ADDR)];
// and save for zero fill
R7 = R0;
// Get Destination Base Address
R1 = [P3];
// Get Count
R2 = [P3+0x4];
// Get Flag
R5 = W[P3+0x8] (Z);
FCHECK_ZERO_FILL_BIT:
// Bit zero of the flag word indicates zero fill block
cc = BITTST(R5,0);
IF !CC JUMP FDO_DMA;
// Source Base Address = ZERO Location
R0 = P4;
R6 = 0x0;
// Source Modify = 0 for Zero Fill
W[P1+OFFSET_(MDMA2_S0_X_MODIFY)] = R6;
FDO_DMA:
// divide count by 2 for 16 bit transfer
R2 >>= 1;
CALL MEM_DMA;
// Bit zero of the flag word indicates zero fill block
cc = BITTST(R5,0);
IF !CC JUMP GET_DMA_CURR_PTR;
// Restore Source Modify to 2 (it was just changed to 0 for zero fill)
R6 = 0x2 (Z);
W[P1+OFFSET_(MDMA2_S0_X_MODIFY)] = R6;
// Restore R0 to Flash Memory Address (was pointing to "ZERO")
JUMP GET_NEXT_FLASH_PTR;
GET_DMA_CURR_PTR:
// read CURR pointer if last block was not a zero fill
// otherwise CURR pointer will point just beyond the zero!
R7 = [P1+OFFSET_(MDMA2_S0_CURR_ADDR)];
GET_NEXT_FLASH_PTR:
// if last block was zero fill, R7 still has the saved flash pointer
// if last block was NOT zero fill, R7 has DMA CURR pointer
// put in in R0 for next call to MEM_DMA
R0 = R7;
F_CHECK_FOR_LAST_SECTION:
// Last Section?
CC = BITTST(R5,15);
// If not, Jump to grab header
IF !CC JUMP FGRAB_HEADER;
RETS = [sp++];
// return a success flag back to the command protocol
R0 = 0x0;
RTS;
////////////////////////////////////////////////////////////////
DMA_ERROR_OR_EXCEPT:
//--------------
// Clear flash DMA_ERR condition
R0 = 0x3;
W[P1+OFFSET_(MDMA2_D0_IRQ_STATUS)] = R0;
W[P1+OFFSET_(MDMA2_S0_IRQ_STATUS)] = R0;
// Disable MEM DMA to completely clear the error, so we can continue to
// use MEMDMA again, if we want.
R0 = 0x0;
W[P1+OFFSET_(MDMA2_S0_CONFIG)] = R0;
W[P1+OFFSET_(MDMA2_D0_CONFIG)] = R0;
IDLE;
//// ZERO will point to a zero (accessed as both byte and word) ////////
.align 4;
.BYTE ZERO[4] = 0x0, 0x0, 0x0, 0x0;
.align 4;
//=========================================================
JUMP_USER_PROGRAM:
// zero out the last locations of L2
P0.L = 0xFFE8;
P0.H = 0xFEB1;
R0 = 0x0;
[P0++] = R0; // ffe8
[P0++] = R0; // ffeC
[P0++] = R0; // fff0
[P0++] = R0; // fff4
[P0++] = R0; // fff8
[P0++] = R0; // fffC
P2.L = LOWER_(CoreA_Code_SRAM); // point the user_code address
P2.H = UPPER_(CoreA_Code_SRAM);
// Erase the 2nd stage loader from beginning to almost the end
// End address in R3
R2.L = end_ldr;
R2.H = end_ldr;
R1.L = START_ERASE;
R1.H = START_ERASE;
// Get count in R2 for DMA transfer
R2 = R2 - R1;
// divide count by 2
R2 >>= 1;
// Source Base Address = ZERO Location
R0 = P4;
// Source Modify = 0 for Zero Fill
R6 = 0x0;
W[P1+OFFSET_(MDMA2_S0_X_MODIFY)] = R6;
// Source Base Address
[P1+OFFSET_(MDMA2_S0_START_ADDR)] = R0;
// Source Count
W[P1+OFFSET_(MDMA2_S0_X_COUNT)] = R2;
// Destination Base Address
[P1+OFFSET_(MDMA2_D0_START_ADDR)] = R1;
// Destination Count
W[P1+OFFSET_(MDMA2_D0_X_COUNT)] = R2;
// Source DMAConfig
W[P1+OFFSET_(MDMA2_S0_CONFIG)] = R3;
// Destination DMAConfig
W[P1+OFFSET_(MDMA2_D0_CONFIG)] = R4;
end_ldr:
// Wait for DMA to Complete
IDLE;
R0 = 0x1;
// Write 1 to clear DMA interrupt
W[P1+OFFSET_(MDMA2_D0_IRQ_STATUS)] = R0;
JUMP(P2); // jump to user code
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -