surenyi
6 years ago
4 changed files with 130 additions and 2 deletions
@ -0,0 +1,123 @@ |
|||
/**
|
|||
* @file nor.c |
|||
* |
|||
* @brief The nor boot driver |
|||
*/ |
|||
|
|||
#include "types.h" |
|||
#include "loader.h" |
|||
#include <string.h> |
|||
#include <stdlib.h> |
|||
|
|||
/**
|
|||
* @brief The nor master control block which tracks the current nor boot information |
|||
*/ |
|||
typedef struct memmcb_s { |
|||
uint32 fpos; /**< Current file position. This is an absolute address, not relative to startPos */ |
|||
uint32 startPos; /**< Initial file position */ |
|||
} memmcb_t; |
|||
|
|||
static memmcb_t memmcb; |
|||
|
|||
/**
|
|||
* @brief |
|||
* Set the current file position |
|||
*/ |
|||
static Int32 __mem_seek (Int32 loc, Int32 from) |
|||
{ |
|||
/* Can't seek from the end of the file, since the end is not known */ |
|||
if (from == 0) |
|||
memmcb.fpos = memmcb.startPos + loc; |
|||
else if (from == 1) |
|||
memmcb.fpos += loc; |
|||
else |
|||
return (-1); |
|||
|
|||
if (memmcb.fpos < memmcb.startPos) |
|||
memmcb.fpos = memmcb.startPos; |
|||
|
|||
return (0); |
|||
} |
|||
|
|||
|
|||
/**
|
|||
* @brief |
|||
* Initialize the control structure. Note that the interface value was |
|||
* previously verified in the top level nor boot control. |
|||
*/ |
|||
static Int32 __mem_open (void *ptr_driver, void (*asyncComplete)(void *)) |
|||
{ |
|||
Uint32 *start_addr = (Uint32 *)ptr_driver; |
|||
|
|||
memmcb.startPos = memmcb.fpos = *start_addr; |
|||
return 0; |
|||
} |
|||
|
|||
/**
|
|||
* @brief |
|||
* Read data from the current address. This function is used |
|||
* for peek as well as read. |
|||
*/ |
|||
static Int32 __mem_read (Uint8 *ptr_buf, Uint32 num_bytes) |
|||
{ |
|||
volatile uint8_t * ep = (volatile uint8_t *)memmcb.fpos; |
|||
|
|||
memcpy(ptr_buf, (const void *)ep, num_bytes); |
|||
memmcb.fpos += num_bytes; |
|||
|
|||
return 0; |
|||
} |
|||
|
|||
static Int32 __mem_peek(Uint8 *ptr_buf, Uint32 num) |
|||
{ |
|||
volatile uint8_t * ep = (volatile uint8_t *)memmcb.fpos; |
|||
memcpy(ptr_buf, (const void *)ep, num); |
|||
return 0; |
|||
} |
|||
|
|||
/**
|
|||
* @brief |
|||
* Return the number of bytes available for current read. |
|||
* Always return 1k |
|||
*/ |
|||
Int32 __mem_query (void) |
|||
{ |
|||
return (0x400); |
|||
|
|||
} |
|||
|
|||
/**
|
|||
* @brief |
|||
* Close the nor driver |
|||
*/ |
|||
static Int32 __mem_close (void) |
|||
{ |
|||
return (0); |
|||
} |
|||
|
|||
/**
|
|||
* @brief |
|||
* The global nor module function table |
|||
*/ |
|||
static BOOT_MODULE_FXN_TABLE _boot_module = { |
|||
__mem_open, /* Open API */ |
|||
__mem_close, /* Close API */ |
|||
__mem_read, /* Read API */ |
|||
NULL, /* Write API */ |
|||
__mem_peek, /* Peek API */ |
|||
__mem_seek, /* Seek API */ |
|||
__mem_query /* Query API */ |
|||
}; |
|||
|
|||
unsigned int mem_load_elf(unsigned int base) |
|||
{ |
|||
unsigned int entry; |
|||
|
|||
if (_boot_module.open(&base, NULL)) { |
|||
return 0; |
|||
} |
|||
load_elf(&_boot_module, &entry); |
|||
_boot_module.close(); |
|||
return entry; |
|||
} |
|||
|
Loading…
Reference in new issue