00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00092 #include "StdAfx.h"
00093 #include "Flash.h"
00094 #include "System.h"
00095 #include "AlphaCPU.h"
00096
00097
00098 #define MODE_READ 0
00099 #define MODE_STEP1 1
00100 #define MODE_STEP2 2
00101 #define MODE_AUTOSEL 3
00102 #define MODE_PROGRAM 4
00103 #define MODE_ERASE_STEP3 5
00104 #define MODE_ERASE_STEP4 6
00105 #define MODE_ERASE_STEP5 7
00106 #define MODE_CONFIRM_0 8
00107 #define MODE_CONFIRM_1 9
00108
00109 extern CAlphaCPU* cpu[4];
00110
00114 CFlash::CFlash(CConfigurator* cfg, CSystem* c) : CSystemComponent(cfg, c)
00115 {
00116 if(theSROM)
00117 FAILURE(Configuration, "More than one Flash");
00118 theSROM = this;
00119 c->RegisterMemory(this, 0, U64(0x0000080100000000), 0x8000000);
00120 memset(state.Flash, 0xff, 2 * 1024 * 1024);
00121 RestoreStateF();
00122 state.mode = MODE_READ;
00123
00124 printf("%s: $Id: Flash.cpp,v 1.19 2008/03/24 22:11:50 iamcamiel Exp $\n",
00125 devid_string);
00126 }
00127
00131 CFlash::~CFlash()
00132 { }
00133
00139 u64 CFlash::ReadMem(int index, u64 address, int dsize)
00140 {
00141 u64 data = 0;
00142 int a = (int) (address >> 6);
00143
00144 switch(state.mode)
00145 {
00146 case MODE_AUTOSEL:
00147 switch(a)
00148 {
00149 case 0: data = 1;
00150 break;
00151 case 1: data = 0xad;
00152 break;
00153 default: data = 0;
00154 }
00155 break;
00156
00157 case MODE_CONFIRM_0:
00158 data = 0x80;
00159 state.mode = MODE_READ;
00160 break;
00161
00162 case MODE_CONFIRM_1:
00163 data = 0x80;
00164 state.mode = MODE_CONFIRM_0;
00165 break;
00166
00167 default:
00168 data = state.Flash[a];
00169 }
00170
00171 return data;
00172 }
00173
00217 void CFlash::WriteMem(int index, u64 address, int dsize, u64 data)
00218 {
00219 int a = (int) (address >> 6);
00220
00221 switch(state.mode)
00222 {
00223 case MODE_READ:
00224 case MODE_AUTOSEL:
00225 if((a == 0x5555) && (data == 0xaa))
00226 {
00227 state.mode = MODE_STEP1;
00228 return;
00229 }
00230
00231 state.mode = MODE_READ;
00232 return;
00233
00234 case MODE_STEP1:
00235 if((a == 0x2aaa) && (data == 0x55))
00236 {
00237 state.mode = MODE_STEP2;
00238 return;
00239 }
00240
00241 state.mode = MODE_READ;
00242 return;
00243
00244 case MODE_STEP2:
00245 if(a != 0x5555)
00246 {
00247 state.mode = MODE_READ;
00248 return;
00249 }
00250
00251 switch(data)
00252 {
00253 case 0x90: state.mode = MODE_AUTOSEL; return;
00254 case 0xa0: state.mode = MODE_PROGRAM; return;
00255 case 0x80: state.mode = MODE_ERASE_STEP3; return;
00256 }
00257
00258 state.mode = MODE_READ;
00259 return;
00260
00261 case MODE_ERASE_STEP3:
00262 if((a == 0x5555) && (data == 0xaa))
00263 {
00264 state.mode = MODE_ERASE_STEP4;
00265 return;
00266 }
00267
00268 state.mode = MODE_READ;
00269 return;
00270
00271 case MODE_ERASE_STEP4:
00272 if((a == 0x2aaa) && (data == 0x55))
00273 {
00274 state.mode = MODE_ERASE_STEP5;
00275 return;
00276 }
00277
00278 state.mode = MODE_READ;
00279 return;
00280
00281 case MODE_ERASE_STEP5:
00282 if((a == 0x5555) && (data == 0x10))
00283 {
00284 memset(state.Flash, 0xff, 1 << 21);
00285 state.mode = MODE_CONFIRM_1;
00286 return;
00287 }
00288
00289 if(data == 0x30)
00290 {
00291 memset(&state.Flash[(a >> 16) << 16], 0xff, 1 << 16);
00292 state.mode = MODE_CONFIRM_1;
00293 return;
00294 }
00295
00296 state.mode = MODE_READ;
00297 return;
00298 }
00299
00300
00301 state.Flash[a] = (u8) data;
00302 state.mode = MODE_READ;
00303 }
00304
00308 void CFlash::SaveStateF(char* fn)
00309 {
00310 FILE* ff;
00311 ff = fopen(fn, "wb");
00312 if(ff)
00313 {
00314 SaveState(ff);
00315 fclose(ff);
00316 printf("%%FLS-I-SAVEST: Flash state saved to %s\n", fn);
00317 }
00318 else
00319 {
00320 printf("%%FLS-F-NOSAVE: Flash could not be saved to %s\n", fn);
00321 }
00322 }
00323
00327 void CFlash::SaveStateF()
00328 {
00329 SaveStateF(myCfg->get_text_value("rom.flash", "flash.rom"));
00330 }
00331
00335 void CFlash::RestoreStateF(char* fn)
00336 {
00337 FILE* ff;
00338 ff = fopen(fn, "rb");
00339 if(ff)
00340 {
00341 RestoreState(ff);
00342 fclose(ff);
00343 printf("%%FLS-I-RESTST: Flash state restored from %s\n", fn);
00344 }
00345 else
00346 {
00347 printf("%%FLS-F-NOREST: Flash could not be restored from %s\n", fn);
00348 }
00349 }
00350
00354 void CFlash::RestoreStateF()
00355 {
00356 RestoreStateF(myCfg->get_text_value("rom.flash", "flash.rom"));
00357 }
00358
00359 static u32 flash_magic1 = 0xFF3E3FF3;
00360 static u32 flash_magic2 = 0x3FF3E3FF;
00361
00365 int CFlash::SaveState(FILE* f)
00366 {
00367 long ss = sizeof(state);
00368 fwrite(&flash_magic1, sizeof(u32), 1, f);
00369 fwrite(&ss, sizeof(long), 1, f);
00370 fwrite(&state, sizeof(state), 1, f);
00371 fwrite(&flash_magic2, sizeof(u32), 1, f);
00372 printf("flash: %d bytes saved.\n", ss);
00373 return 0;
00374 }
00375
00379 int CFlash::RestoreState(FILE* f)
00380 {
00381 long ss;
00382 u32 m1;
00383 u32 m2;
00384 size_t r;
00385
00386 r = fread(&m1, sizeof(u32), 1, f);
00387 if(r != 1)
00388 {
00389 printf("flash: unexpected end of file!\n");
00390 return -1;
00391 }
00392
00393 if(m1 != flash_magic1)
00394 {
00395 printf("flash: MAGIC 1 does not match!\n");
00396 return -1;
00397 }
00398
00399 fread(&ss, sizeof(long), 1, f);
00400 if(r != 1)
00401 {
00402 printf("flash: unexpected end of file!\n");
00403 return -1;
00404 }
00405
00406 if(ss != sizeof(state))
00407 {
00408 printf("flash: STRUCT SIZE does not match!\n");
00409 return -1;
00410 }
00411
00412 fread(&state, sizeof(state), 1, f);
00413 if(r != 1)
00414 {
00415 printf("flash: unexpected end of file!\n");
00416 return -1;
00417 }
00418
00419 r = fread(&m2, sizeof(u32), 1, f);
00420 if(r != 1)
00421 {
00422 printf("flash: unexpected end of file!\n");
00423 return -1;
00424 }
00425
00426 if(m2 != flash_magic2)
00427 {
00428 printf("flash: MAGIC 1 does not match!\n");
00429 return -1;
00430 }
00431
00432 printf("flash: %d bytes restored.\n", ss);
00433 return 0;
00434 }
00435
00436 CFlash* theSROM = 0;