mirror of
https://github.com/LIV2/A4092-dev.git
synced 2025-12-06 00:32:49 +00:00
a4092flash overhaul
- Implement reading and probing - Show supported flash part names
This commit is contained in:
parent
6048c860e7
commit
cdd811c8df
@ -49,6 +49,15 @@ struct Config* configure(int argc, char *argv[]) {
|
||||
case 'W':
|
||||
if (i+1 < argc) {
|
||||
config->scsi_rom_filename = argv[i+1];
|
||||
config->writeFlash = true;
|
||||
i++;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'R':
|
||||
if (i+1 < argc) {
|
||||
config->scsi_rom_filename = argv[i+1];
|
||||
config->readFlash = true;
|
||||
i++;
|
||||
}
|
||||
break;
|
||||
@ -57,10 +66,14 @@ struct Config* configure(int argc, char *argv[]) {
|
||||
config->eraseFlash = true;
|
||||
break;
|
||||
|
||||
case 'R':
|
||||
case 'B':
|
||||
config->rebootRequired = true;
|
||||
break;
|
||||
|
||||
case 'P':
|
||||
config->probeFlash = true;
|
||||
break;
|
||||
|
||||
case 'Y':
|
||||
config->assumeYes = true;
|
||||
break;
|
||||
@ -69,7 +82,13 @@ struct Config* configure(int argc, char *argv[]) {
|
||||
}
|
||||
}
|
||||
|
||||
if (config->scsi_rom_filename == NULL && config->eraseFlash == false) {
|
||||
if (config->readFlash == false && config->writeFlash == false &&
|
||||
config->eraseFlash == false && config->probeFlash == false) {
|
||||
printf("You need to specify one of -E, -R, -W, -P.\n");
|
||||
error = true;
|
||||
}
|
||||
if (config->readFlash == true && config->writeFlash == true) {
|
||||
printf("a4092flash: -R, -W are mutually exclusive.\n");
|
||||
error = true;
|
||||
}
|
||||
|
||||
@ -84,9 +103,12 @@ struct Config* configure(int argc, char *argv[]) {
|
||||
/** usage
|
||||
* @brief Print the usage information
|
||||
*/
|
||||
void usage() {
|
||||
printf("\nUsage: a4092flash [-I <a4092.rom>]\n\n");
|
||||
printf(" -W <a4092.rom> - Flash A4092 ROM.\n");
|
||||
void usage(void) {
|
||||
printf("\nUsage: a4092flash [-Y] { -R <a4092.rom> | -W <a4092.rom> | -E | -P }\n\n");
|
||||
printf(" -Y assume YES as answer to all questions\n");
|
||||
printf(" -R <a4092.rom> - Read A4092 ROM to file\n");
|
||||
printf(" -W <a4092.rom> - Flash A4092 ROM from file\n");
|
||||
printf(" -E Erase flash.\n");
|
||||
printf(" -R reboot.\n");
|
||||
printf(" -P Probe flash.\n");
|
||||
printf(" -B Reboot.\n");
|
||||
}
|
||||
|
||||
@ -20,6 +20,9 @@
|
||||
|
||||
struct Config {
|
||||
char *scsi_rom_filename;
|
||||
bool readFlash;
|
||||
bool writeFlash;
|
||||
bool probeFlash;
|
||||
bool eraseFlash;
|
||||
bool rebootRequired;
|
||||
bool assumeYes;
|
||||
|
||||
@ -16,6 +16,7 @@
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <proto/expansion.h>
|
||||
#include <exec/types.h>
|
||||
#include <stdbool.h>
|
||||
@ -23,7 +24,7 @@
|
||||
#include "flash.h"
|
||||
#include "flash_constants.h"
|
||||
|
||||
volatile ULONG flashbase;
|
||||
static ULONG flashbase;
|
||||
|
||||
/**
|
||||
* @brief Reads a single byte from the flash memory at the given byte address,
|
||||
@ -36,7 +37,8 @@ volatile ULONG flashbase;
|
||||
* @param byte_address The byte address (0x000000 - 0x7FFFFF) to read from.
|
||||
* @return The UBYTE value read from the flash.
|
||||
*/
|
||||
static UBYTE flash_read_byte(ULONG byte_address) {
|
||||
static UBYTE flash_read_byte(ULONG byte_address)
|
||||
{
|
||||
// Calculate the physical 32-bit word address in memory.
|
||||
// Each byte address maps to a unique 32-bit word in the underlying memory.
|
||||
volatile ULONG *word_ptr = (volatile ULONG *)(flashbase + (byte_address * 4));
|
||||
@ -67,7 +69,8 @@ static UBYTE flash_read_byte(ULONG byte_address) {
|
||||
* @param byte_address The byte address (0x000000 - 0x7FFFFF) to write to.
|
||||
* @param data The UBYTE value to write to the flash.
|
||||
*/
|
||||
static void flash_write_byte(ULONG byte_address, UBYTE data) {
|
||||
static void flash_write_byte(ULONG byte_address, UBYTE data)
|
||||
{
|
||||
// Calculate the physical 32-bit word address in memory.
|
||||
// Each byte address maps to a unique 32-bit word in the underlying memory.
|
||||
volatile ULONG *word_ptr = (volatile ULONG *)(flashbase + (byte_address * 4));
|
||||
@ -91,18 +94,25 @@ static void flash_write_byte(ULONG byte_address, UBYTE data) {
|
||||
static inline void flash_command(UBYTE);
|
||||
static inline void flash_poll(ULONG);
|
||||
|
||||
static const LONG devices_supported[] = {
|
||||
0x1F03, // AT49BV512
|
||||
0xBFB5, // SST39SF010
|
||||
0xBFB6, // SST39SF020
|
||||
0xBFB7, // SST39SF040
|
||||
0xBFD5, // SST39(L/V)F010
|
||||
0xBFD6, // SST39(L/V)F020
|
||||
0xBFD7, // SST39(L/V)F040
|
||||
0xC2A4, // MX29F040C
|
||||
0x0120, // AM29F010
|
||||
0x01A4, // AM29F040
|
||||
0
|
||||
struct flashchips {
|
||||
UWORD id;
|
||||
UWORD size;
|
||||
const char *vendor;
|
||||
const char *device;
|
||||
};
|
||||
|
||||
static const struct flashchips devices_supported[] = {
|
||||
{ 0x0120, 128, "AMD", "AM29F010" },
|
||||
{ 0x01A4, 512, "AMD", "AM29F040" },
|
||||
{ 0x1F03, 64, "Atmel", "AT49BV512" },
|
||||
{ 0xBFB5, 128, "SST", "SST39SF010" },
|
||||
{ 0xBFB6, 256, "SST", "SST39SF020" },
|
||||
{ 0xBFB7, 512, "SST", "SST39SF040" },
|
||||
{ 0xBFD5, 128, "SST", "SST39(L/V)F010" },
|
||||
{ 0xBFD6, 256, "SST", "SST39(L/V)F020" },
|
||||
{ 0xBFD7, 512, "SST", "SST39(L/V)F040" },
|
||||
{ 0xC2A4, 512, "Macronix", "MX29F040C" },
|
||||
{ 0x0000, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
/** flash_is_supported
|
||||
@ -112,13 +122,22 @@ static const LONG devices_supported[] = {
|
||||
* @param device the device id
|
||||
* @returns boolean result
|
||||
*/
|
||||
static bool flash_is_supported(UBYTE manufacturer, UBYTE device) {
|
||||
static bool flash_is_supported(UBYTE manufacturer, UBYTE device, UWORD *size)
|
||||
{
|
||||
ULONG deviceId = (manufacturer << 8) | device;
|
||||
int i = 0;
|
||||
|
||||
while (devices_supported[i] != 0) {
|
||||
if (devices_supported[i] == deviceId)
|
||||
if (size) *size = 0;
|
||||
|
||||
while (devices_supported[i].id != 0) {
|
||||
if (devices_supported[i].id == deviceId) {
|
||||
printf("Flash part: %s %s (%d KB)\n",
|
||||
devices_supported[i].vendor,
|
||||
devices_supported[i].device,
|
||||
devices_supported[i].size);
|
||||
*size = devices_supported[i].size;
|
||||
return true;
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
@ -133,7 +152,8 @@ static bool flash_is_supported(UBYTE manufacturer, UBYTE device) {
|
||||
* @param device the device id
|
||||
* @returns UWORD sector size in bytes
|
||||
*/
|
||||
static UWORD flash_get_sectorSize(UBYTE manufacturer, UBYTE device) {
|
||||
static UWORD flash_get_sectorSize(UBYTE manufacturer, UBYTE device)
|
||||
{
|
||||
ULONG deviceId = (manufacturer << 8) | device;
|
||||
UWORD sectorSize;
|
||||
|
||||
@ -164,7 +184,8 @@ static UWORD flash_get_sectorSize(UBYTE manufacturer, UBYTE device) {
|
||||
* @param address Address to read from
|
||||
* @return The data that was read
|
||||
*/
|
||||
UBYTE flash_readByte(ULONG address) {
|
||||
UBYTE flash_readByte(ULONG address)
|
||||
{
|
||||
// Mask address to ensure it is within the valid flash size.
|
||||
address &= (FLASH_SIZE - 1);
|
||||
|
||||
@ -179,7 +200,8 @@ UBYTE flash_readByte(ULONG address) {
|
||||
* @param address Address to write to
|
||||
* @param data The data to be written
|
||||
*/
|
||||
void flash_writeByte(ULONG address, UBYTE data) {
|
||||
void flash_writeByte(ULONG address, UBYTE data)
|
||||
{
|
||||
// Mask address to ensure it is within the valid flash size.
|
||||
address &= (FLASH_SIZE - 1);
|
||||
|
||||
@ -195,7 +217,8 @@ void flash_writeByte(ULONG address, UBYTE data) {
|
||||
* @brief send a command to the Flash
|
||||
* @param command The command byte to send.
|
||||
*/
|
||||
static inline void flash_command(UBYTE command) {
|
||||
static inline void flash_command(UBYTE command)
|
||||
{
|
||||
// Write command byte to the specific command address
|
||||
flash_write_byte(ADDR_CMD_STEP_1, command);
|
||||
return;
|
||||
@ -205,7 +228,8 @@ static inline void flash_command(UBYTE command) {
|
||||
*
|
||||
* @brief Send the SDP command sequence
|
||||
*/
|
||||
void flash_unlock_sdp() {
|
||||
void flash_unlock_sdp(void)
|
||||
{
|
||||
// Write the sequence bytes to the specific addresses
|
||||
flash_write_byte(ADDR_CMD_STEP_1, CMD_SDP_STEP_1);
|
||||
flash_write_byte(ADDR_CMD_STEP_2, CMD_SDP_STEP_2);
|
||||
@ -216,7 +240,8 @@ void flash_unlock_sdp() {
|
||||
*
|
||||
* @brief Perform a chip erase.
|
||||
*/
|
||||
void flash_erase_chip() {
|
||||
void flash_erase_chip(void)
|
||||
{
|
||||
flash_unlock_sdp();
|
||||
flash_command(CMD_ERASE);
|
||||
flash_unlock_sdp();
|
||||
@ -230,7 +255,8 @@ void flash_erase_chip() {
|
||||
* Erase the currently selected 32KB bank
|
||||
*
|
||||
*/
|
||||
void flash_erase_bank(UWORD sectorSize) {
|
||||
void flash_erase_bank(UWORD sectorSize)
|
||||
{
|
||||
if (sectorSize > 0) {
|
||||
int count = 32768 / sectorSize;
|
||||
for (int i = 0; i < count; i++) {
|
||||
@ -245,7 +271,8 @@ void flash_erase_bank(UWORD sectorSize) {
|
||||
* @param address Address of sector to erase
|
||||
*
|
||||
*/
|
||||
void flash_erase_sector(ULONG address) {
|
||||
void flash_erase_sector(ULONG address)
|
||||
{
|
||||
// Mask address to ensure it is within the valid flash size.
|
||||
address &= (FLASH_SIZE - 1);
|
||||
|
||||
@ -262,7 +289,8 @@ void flash_erase_sector(ULONG address) {
|
||||
* @brief Poll the status bits at address, until they indicate that the operation has completed.
|
||||
* @param address Address to poll
|
||||
*/
|
||||
static inline void flash_poll(ULONG address) {
|
||||
static inline void flash_poll(ULONG address)
|
||||
{
|
||||
// Mask address to ensure it is within the valid flash size.
|
||||
address &= (FLASH_SIZE - 1);
|
||||
|
||||
@ -283,11 +311,15 @@ static inline void flash_poll(ULONG address) {
|
||||
* @param flashbase Pointer to the Flash base address
|
||||
* @return True if the manufacturer ID matches the expected value and flashbase is valid.
|
||||
*/
|
||||
bool flash_init(UBYTE *manuf, UBYTE *devid, ULONG *base, UWORD *sectorSize) {
|
||||
bool flash_init(UBYTE *manuf, UBYTE *devid, volatile UBYTE *base, ULONG *size, UWORD *sectorSize)
|
||||
{
|
||||
bool ret = false;
|
||||
UBYTE manufId;
|
||||
UBYTE deviceId;
|
||||
|
||||
if (size) *size = 0;
|
||||
if (sectorSize) *sectorSize = 0;
|
||||
|
||||
// Set the global flashbase pointer.
|
||||
flashbase = (ULONG)base;
|
||||
|
||||
@ -306,12 +338,14 @@ bool flash_init(UBYTE *manuf, UBYTE *devid, ULONG *base, UWORD *sectorSize) {
|
||||
if (devid) *devid = deviceId;
|
||||
|
||||
// Check if the device is supported and flashbase is valid.
|
||||
if (flash_is_supported(manufId, deviceId) && flashbase) {
|
||||
UWORD flash_size;
|
||||
if (flash_is_supported(manufId, deviceId, &flash_size) && flashbase) {
|
||||
// Update size if pointer is valid.
|
||||
if (size) *size = flash_size * 1024;
|
||||
// Update the sector size if pointer is valid.
|
||||
if (sectorSize) *sectorSize = flash_get_sectorSize(manufId, deviceId);
|
||||
ret = true;
|
||||
}
|
||||
|
||||
// Update the sector size if pointer is valid.
|
||||
if (sectorSize) *sectorSize = flash_get_sectorSize(manufId, deviceId);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
@ -22,12 +22,12 @@
|
||||
#include <exec/types.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
void flash_unlock_sdp();
|
||||
void flash_erase_chip();
|
||||
UBYTE flash_readByte(ULONG);
|
||||
void flash_writeByte(ULONG, UBYTE);
|
||||
bool flash_init(UBYTE *, UBYTE *, ULONG *, UWORD *);
|
||||
void flash_erase_sector(ULONG);
|
||||
void flash_erase_bank(UWORD);
|
||||
void flash_unlock_sdp(void);
|
||||
void flash_erase_chip(void);
|
||||
UBYTE flash_readByte(ULONG address);
|
||||
void flash_writeByte(ULONG address, UBYTE data);
|
||||
bool flash_init(UBYTE *manuf, UBYTE *devid, volatile UBYTE *base, ULONG *size, UWORD *sectorSize);
|
||||
void flash_erase_sector(ULONG address);
|
||||
void flash_erase_bank(UWORD sectorSize);
|
||||
|
||||
#endif
|
||||
|
||||
@ -31,7 +31,8 @@
|
||||
#include "main.h"
|
||||
#include "config.h"
|
||||
|
||||
#define MANUF_ID_COMMODORE 513
|
||||
#define MANUF_ID_COMMODORE_BRAUNSCHWEIG 513
|
||||
#define MANUF_ID_COMMODORE 514
|
||||
|
||||
#define PROD_ID_A4092 84
|
||||
|
||||
@ -49,7 +50,8 @@ bool devsInhibited = false;
|
||||
* Kickstart V36 (2.0+) and up contain a function for this
|
||||
* But for 1.3 we will need to provide our own function
|
||||
*/
|
||||
static void _ColdReboot() {
|
||||
static void _ColdReboot(void)
|
||||
{
|
||||
// Copied from coldboot.asm
|
||||
// http://amigadev.elowar.com/read/ADCD_2.1/Hardware_Manual_guide/node02E3.html
|
||||
asm("move.l 4,a6 \n\t" // SysBase
|
||||
@ -73,7 +75,8 @@ static void _ColdReboot() {
|
||||
*
|
||||
* @param inhibit (bool) True: inhibit, False: uninhibit
|
||||
*/
|
||||
bool inhibitDosDevs(bool inhibit) {
|
||||
bool inhibitDosDevs(bool inhibit)
|
||||
{
|
||||
bool success = true;
|
||||
struct MsgPort *mp = CreatePort(NULL,0);
|
||||
struct Message msg;
|
||||
@ -180,8 +183,9 @@ bool inhibitDosDevs(bool inhibit) {
|
||||
* Configure the board struct for an A4092 Board
|
||||
* @param board pointer to the board struct
|
||||
*/
|
||||
static void setup_a4092_board(struct scsiBoard *board) {
|
||||
board->flashbase = board->cd->cd_BoardAddr;
|
||||
static void setup_a4092_board(struct scsiBoard *board)
|
||||
{
|
||||
board->flashbase = (volatile UBYTE *)board->cd->cd_BoardAddr;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -191,7 +195,8 @@ static void setup_a4092_board(struct scsiBoard *board) {
|
||||
* @param config pointer to the config struct
|
||||
* @return boolean true / false
|
||||
*/
|
||||
static bool promptUser(struct Config *config) {
|
||||
static bool promptUser(struct Config *config)
|
||||
{
|
||||
int c;
|
||||
char answer = 'y'; // Default to yes
|
||||
|
||||
@ -214,6 +219,8 @@ static bool promptUser(struct Config *config) {
|
||||
return (answer == 'y');
|
||||
}
|
||||
|
||||
static BOOL probeFlash(ULONG romSize);
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
SysBase = *((struct ExecBase **)4UL);
|
||||
@ -230,13 +237,13 @@ int main(int argc, char *argv[])
|
||||
return(rc);
|
||||
}
|
||||
|
||||
printf("\n==== A4092 Flash Updater ====\n");
|
||||
printf("\n%s\n\n", VERSION);
|
||||
|
||||
struct Task *task = FindTask(0);
|
||||
SetTaskPri(task,20);
|
||||
if ((config = configure(argc,argv)) != NULL) {
|
||||
|
||||
if (config->scsi_rom_filename) {
|
||||
if (config->writeFlash && config->scsi_rom_filename) {
|
||||
romSize = getFileSize(config->scsi_rom_filename);
|
||||
if (romSize == 0) {
|
||||
rc = 5;
|
||||
@ -289,6 +296,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
switch (cd->cd_Rom.er_Manufacturer) {
|
||||
case MANUF_ID_COMMODORE:
|
||||
case MANUF_ID_COMMODORE_BRAUNSCHWEIG:
|
||||
if (cd->cd_Rom.er_Product == PROD_ID_A4092) {
|
||||
printf("Found A4091 / A4092");
|
||||
setup_a4092_board(&board);
|
||||
@ -305,34 +313,53 @@ int main(int argc, char *argv[])
|
||||
boards_found++;
|
||||
|
||||
// Ask the user if they wish to update this board
|
||||
if (!promptUser(config)) continue;
|
||||
if ((config->writeFlash || config->eraseFlash) && !promptUser(config)) continue;
|
||||
|
||||
UBYTE manufId,devId;
|
||||
UWORD sectorSize;
|
||||
ULONG flashSize;
|
||||
|
||||
if (flash_init(&manufId,&devId,board.flashbase,§orSize)) {
|
||||
if (flash_init(&manufId,&devId,board.flashbase,&flashSize,§orSize)) {
|
||||
if (config->eraseFlash) {
|
||||
printf("Erasing flash.\n");
|
||||
printf("Erasing whole flash.\n");
|
||||
flash_erase_chip();
|
||||
}
|
||||
|
||||
if (config->scsi_rom_filename) {
|
||||
if (config->writeFlash && config->scsi_rom_filename) {
|
||||
if (config->eraseFlash == false) {
|
||||
if (sectorSize > 0) {
|
||||
printf("Erasing A4092 bank...\n");
|
||||
printf("Erasing flash bank.\n");
|
||||
flash_erase_bank(sectorSize);
|
||||
} else {
|
||||
printf("Erasing A4092 flash...\n");
|
||||
printf("Erasing whole flash.\n");
|
||||
flash_erase_chip();
|
||||
}
|
||||
}
|
||||
printf("Writing A4092 ROM.\n");
|
||||
writeBufToFlash(&board,driver_buffer,board.flashbase,romSize);
|
||||
printf("Writing A4092 ROM image to flash memory.\n");
|
||||
writeBufToFlash(&board, driver_buffer, board.flashbase, romSize);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
if (config->readFlash && config->scsi_rom_filename && flashSize) {
|
||||
printf("Writing A4092 flash memory to file.\n");
|
||||
if (writeFlashToFile(config->scsi_rom_filename,flashSize) == false) {
|
||||
rc = 5;
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
if (config->probeFlash && flashSize) {
|
||||
if (probeFlash(flashSize) == false) {
|
||||
rc = 5;
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
printf("Error: A4092 - Unknown Flash device Manufacturer: %02X Device: %02X\n", manufId, devId);
|
||||
if (manufId == 0x9f && devId == 0xaf)
|
||||
printf("This is likely an A4091. Only A4092 has flash memory.\n");
|
||||
else
|
||||
printf("Error: A4092 - Unknown Flash device Manufacturer: %02X Device: %02X\n", manufId, devId);
|
||||
rc = 5;
|
||||
}
|
||||
}
|
||||
@ -377,7 +404,8 @@ exit:
|
||||
* @param filename file to check the size of
|
||||
* @returns File size in bytes
|
||||
*/
|
||||
ULONG getFileSize(char *filename) {
|
||||
ULONG getFileSize(char *filename)
|
||||
{
|
||||
BPTR fileLock;
|
||||
ULONG fileSize = 0;
|
||||
struct FileInfoBlock *FIB;
|
||||
@ -408,7 +436,8 @@ ULONG getFileSize(char *filename) {
|
||||
* @param filename Name of the file to open
|
||||
* @return true on success
|
||||
*/
|
||||
BOOL readFileToBuf(char *filename, void *buffer) {
|
||||
BOOL readFileToBuf(char *filename, void *buffer)
|
||||
{
|
||||
ULONG romSize = getFileSize(filename);
|
||||
BOOL ret = true;
|
||||
|
||||
@ -434,6 +463,52 @@ BOOL readFileToBuf(char *filename, void *buffer) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* writeFlashToFile()
|
||||
*
|
||||
* Write the Flash content to the specified file
|
||||
*
|
||||
* @param filename file to write
|
||||
* @param size number of bytes to write
|
||||
* @returns true on success
|
||||
*/
|
||||
BOOL writeFlashToFile(char *filename, ULONG romSize)
|
||||
{
|
||||
BOOL ret = true;
|
||||
char * buffer;
|
||||
|
||||
if (romSize == 0) return false;
|
||||
fprintf (stdout, "Flash size: %d KB\n", romSize / 1024);
|
||||
buffer = AllocMem(romSize, 0);
|
||||
|
||||
BPTR fh;
|
||||
|
||||
if (buffer) {
|
||||
fprintf(stdout, "Reading Flash...\n");
|
||||
int i;
|
||||
for (i=0; i<romSize; i++) {
|
||||
buffer[i] = flash_readByte(i);
|
||||
}
|
||||
fprintf(stdout, "Writing File %s...\n", filename);
|
||||
fh = Open(filename,MODE_NEWFILE);
|
||||
|
||||
if (fh) {
|
||||
Write(fh,buffer,romSize);
|
||||
Close(fh);
|
||||
FreeMem(buffer, romSize);
|
||||
} else {
|
||||
printf("Error opening %s\n",filename);
|
||||
FreeMem(buffer, romSize);
|
||||
return false;
|
||||
}
|
||||
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* writeBufToFlash()
|
||||
*
|
||||
@ -444,7 +519,8 @@ BOOL readFileToBuf(char *filename, void *buffer) {
|
||||
* @param size number of bytes to write
|
||||
* @returns true on success
|
||||
*/
|
||||
BOOL writeBufToFlash(struct scsiBoard *board, UBYTE *source, UBYTE *dest, ULONG size) {
|
||||
BOOL writeBufToFlash(struct scsiBoard *board, UBYTE *source, volatile UBYTE *dest, ULONG size)
|
||||
{
|
||||
UBYTE *sourcePtr = NULL;
|
||||
UBYTE destVal = 0;
|
||||
|
||||
@ -492,3 +568,63 @@ BOOL writeBufToFlash(struct scsiBoard *board, UBYTE *source, UBYTE *dest, ULONG
|
||||
fflush(stdout);
|
||||
return true;
|
||||
}
|
||||
|
||||
static int find_a409x_version(const unsigned char *buffer, ULONG romSize) {
|
||||
const char *needle = "A4091 scsidisk";
|
||||
size_t needle_len = strlen(needle);
|
||||
|
||||
// We can only search up to (romSize - needle_len)
|
||||
for (size_t i = 0; i <= romSize - needle_len; i++) {
|
||||
if (memcmp(buffer + i, needle, needle_len) == 0) {
|
||||
return (int)i;
|
||||
}
|
||||
}
|
||||
return -1; // Not found
|
||||
}
|
||||
|
||||
/**
|
||||
* probeFlash()
|
||||
*
|
||||
* Analyze flash content
|
||||
*
|
||||
* @param size number of bytes to write
|
||||
* @returns true on success
|
||||
*/
|
||||
static BOOL probeFlash(ULONG romSize)
|
||||
{
|
||||
BOOL ret = true;
|
||||
char * buffer;
|
||||
|
||||
if (romSize == 0) return false;
|
||||
buffer = AllocMem(romSize, 0);
|
||||
|
||||
if (buffer) {
|
||||
fprintf(stdout, "Reading Flash...\n");
|
||||
int i;
|
||||
for (i=0; i<romSize; i++) {
|
||||
buffer[i] = flash_readByte(i);
|
||||
}
|
||||
|
||||
ULONG magic1,magic2;
|
||||
memcpy (&magic1, buffer+0x10000-8, 4);
|
||||
memcpy (&magic2, buffer+0x10000-4, 4);
|
||||
if (magic1 == 0xFFFF5352 && magic2 == 0x2F434448) {
|
||||
printf("Found 64KB A4091/A4092 image.\n");
|
||||
} else {
|
||||
printf("Not a standard image.\n");
|
||||
}
|
||||
|
||||
int offset = find_a409x_version(buffer, romSize);
|
||||
if (offset > 0) {
|
||||
printf("Version: %s\n", buffer + offset);
|
||||
} else {
|
||||
printf("Could not determine version.\n");
|
||||
}
|
||||
|
||||
FreeMem(buffer, romSize);
|
||||
} else {
|
||||
ret=false;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -24,6 +24,7 @@
|
||||
#define XSTR(s) STR(s) /* Turn s into a string literal after macro-expanding it. */
|
||||
|
||||
#define VERSION_STRING "$VER: a4092flash " XSTR(DEVICE_VERSION) "." XSTR(DEVICE_REVISION) " (" XSTR(BUILD_DATE) ") " XSTR(GIT_REF)
|
||||
#define VERSION "a4092flash " XSTR(DEVICE_VERSION) "." XSTR(DEVICE_REVISION) " (" XSTR(BUILD_DATE) ") " XSTR(GIT_REF)
|
||||
|
||||
#undef FindConfigDev
|
||||
// NDK 1.3 definition of FindConfigDev is incorrect which causes "makes pointer from integer without a cast" warning
|
||||
@ -31,7 +32,7 @@ struct ConfigDev* FindConfigDev(struct ConfigDev*, LONG, LONG);
|
||||
|
||||
// NDK 1.3 includes lacks these, so define them here
|
||||
#ifdef __KICK13__
|
||||
void ColdReboot();
|
||||
void ColdReboot(void);
|
||||
struct DosList *LockDosList(ULONG);
|
||||
struct DosList *NextDosEntry(struct DosList *, ULONG);
|
||||
void *UnLockDosList(ULONG);
|
||||
@ -39,7 +40,7 @@ void *UnLockDosList(ULONG);
|
||||
|
||||
struct scsiBoard {
|
||||
struct ConfigDev *cd;
|
||||
void * volatile flashbase;
|
||||
volatile UBYTE *flashbase;
|
||||
};
|
||||
|
||||
struct dosDev {
|
||||
@ -50,6 +51,7 @@ struct dosDev {
|
||||
|
||||
ULONG getFileSize(char *);
|
||||
BOOL readFileToBuf(char *, void *);
|
||||
BOOL writeBufToFlash(struct scsiBoard *board, UBYTE *source, UBYTE *dest, ULONG size);
|
||||
BOOL writeFlashToFile(char *filename, ULONG romSize);
|
||||
BOOL writeBufToFlash(struct scsiBoard *board, UBYTE *source, volatile UBYTE *dest, ULONG size);
|
||||
|
||||
#endif
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user