LibXenon
Bare-metal Xbox 360 homebrew library
Loading...
Searching...
No Matches
xenon_sfcx.c
Go to the documentation of this file.
1#include <xetypes.h>
2#include <stdio.h>
3#include <stdlib.h>
4#include <unistd.h>
5#include <fcntl.h>
6#include <time/time.h>
7#include <xb360/xb360.h>
8#include "xenon_sfcx.h"
9
10struct sfc sfc = {0};
11unsigned char* blockbuf;
12//static unsigned char sfcx_page[MAX_PAGE_SZ]; //Max known hardware physical page size
13//static unsigned char sfcx_block[MAX_BLOCK_SZ]; //Max known hardware physical block size
14
15void sfcx_writereg(int addr, unsigned long data)
16{
17 *(volatile unsigned int*)(0xea00c000UL | addr) = __builtin_bswap32(data);
18}
19
20unsigned long sfcx_readreg(int addr)
21{
22 return __builtin_bswap32(*(volatile unsigned int*)(0xea00c000UL | addr));
23}
24
25int sfcx_read_page(unsigned char *data, int address, int raw)
26{
27 int status;
28
30
31 // Set flash address (logical)
32 //address &= 0x3fffe00; // Align to page
34
35 // Command the read
36 // Either a logical read (0x200 bytes, no meta data)
37 // or a Physical read (0x210 bytes with meta data)
39
40 // Wait Busy
42
43 if (!SFCX_SUCCESS(status))
44 {
45 if (status & STATUS_BB_ER)
46 printf(" ! SFCX: Bad block found at %08X\n", sfcx_address_to_block(address));
47 else if (status & STATUS_ECC_ER)
48 // printf(" ! SFCX: (Corrected) ECC error at address %08X: %08X\n", address, status);
49 status = status;
50 else if (!raw && (status & STATUS_ILL_LOG))
51 printf(" ! SFCX: Illegal logical block at %08X (status: %08X)\n", sfcx_address_to_block(address), status);
52 else
53 printf(" ! SFCX: Unknown error at address %08X: %08X. Please worry.\n", address, status);
54 }
55
56 // Set internal page buffer pointer to 0
58
59 int i;
60 int page_sz = raw ? sfc.page_sz_phys : sfc.page_sz;
61
62 for (i = 0; i < page_sz ; i += 4)
63 {
64 // Transfer data from buffer to register
66
67 // Read out our data through the register
68 *(int*)(data + i) = __builtin_bswap32(sfcx_readreg(SFCX_DATA));
69 }
70
71 return status;
72}
73
74int sfcx_write_page(unsigned char *data, int address)
75{
77
78 // Enable Writes
80
81 // Set internal page buffer pointer to 0
83
84 int i;
85 for (i = 0; i < sfc.page_sz_phys; i+=4)
86 {
87 // Write out our data through the register
88 sfcx_writereg(SFCX_DATA, __builtin_bswap32(*(int*)(data + i)));
89
90 // Transfer data from register to buffer
92 }
93
94 // Set flash address (logical)
95 //address &= 0x3fffe00; // Align to page
97
98 // Unlock sequence (for write)
101
102 // Wait Busy
104
105 // Command the write
107
108 // Wait Busy
110
112 if (!SFCX_SUCCESS(status))
113 printf(" ! SFCX: Unexpected sfcx_write_page status %08X\n", status);
114
115 // Disable Writes
117
118 return status;
119}
120
121int sfcx_read_block(unsigned char *data, int address, int raw)
122{
123 int p;
124 int status = 0;
125 int page_sz = raw ? sfc.page_sz_phys : sfc.page_sz;
126
127 for (p = 0; p < sfc.pages_in_block; p++)
128 {
129 status |= sfcx_read_page(&data[p * page_sz], address + (p * sfc.page_sz), raw);
130 //if (!SFCX_SUCCESS(status))
131 // break;
132 }
133 return status;
134}
135
136int sfcx_write_block(unsigned char *data, int address)
137{
138 int p;
139 int status = 0;
140
141 for (p = 0; p < sfc.pages_in_block; p++)
142 {
144 //if (!SFCX_SUCCESS(status))
145 // break;
146 }
147 return status;
148}
149
151{
152 // Enable Writes
155
156 // Set flash address (logical)
157 //address &= 0x3fffe00; // Align to page
159
160 // Wait Busy
162
163 // Unlock sequence (for erase)
166
167 // Wait Busy
169
170 // Command the block erase
172
173 // Wait Busy
175
177 //if (!SFCX_SUCCESS(status))
178 // printf(" ! SFCX: Unexpected sfcx_erase_block status %08X\n", status);
180
181 // Disable Writes
183
184 return status;
185}
186
187void sfcx_calcecc_ex(unsigned int *data, unsigned char* edc) {
188 unsigned int i=0, val=0;
189 unsigned int v=0;
190
191 for (i = 0; i < 0x1066; i++)
192 {
193 if (!(i & 31))
194 v = ~__builtin_bswap32(*data++);
195 val ^= v & 1;
196 v>>=1;
197 if (val & 1)
198 val ^= 0x6954559;
199 val >>= 1;
200 }
201
202 val = ~val;
203
204 // 26 bit ecc data
205 edc[0] = (val << 6) & 0xFF;
206 edc[1] = (val >> 2) & 0xFF;
207 edc[2] = (val >> 10) & 0xFF;
208 edc[3] = (val >> 18) & 0xFF;
209}
210
211void sfcx_calcecc(unsigned int *data)
212{
213 unsigned char *edc = ((unsigned char*)data) + sfc.page_sz;
214 sfcx_calcecc_ex(data, &edc[0xC]);
215}
216
217int sfcx_get_blocknumber(unsigned char *data)
218{
219 int num = 0;
220 switch (sfc.meta_type)
221 {
222 case META_TYPE_0:
223 num = (data[sfc.page_sz + 0x1] << 8) | (data[sfc.page_sz + 0x0]);
224 break;
225 case META_TYPE_1:
226 num = (data[sfc.page_sz + 0x2] << 8) | (data[sfc.page_sz + 0x1]);
227 break;
228 case META_TYPE_2:
229 num = (data[sfc.page_sz + 0x2] << 8) | (data[sfc.page_sz + 0x1]);
230 break;
231 }
232 return num;
233}
234
235void sfcx_set_blocknumber(unsigned char *data, int num)
236{
237 switch (sfc.meta_type)
238 {
239 case META_TYPE_0:
240 data[sfc.page_sz + 0x1] = (num >> 8) & 0xFF;
241 data[sfc.page_sz + 0x0] = (num >> 0) & 0xFF;
242 break;
243 case META_TYPE_1:
244 data[sfc.page_sz + 0x2] = (num >> 8) & 0xFF;
245 data[sfc.page_sz + 0x1] = (num >> 0) & 0xFF;
246 break;
247 case META_TYPE_2:
248 data[sfc.page_sz + 0x2] = (num >> 8) & 0xFF;
249 data[sfc.page_sz + 0x1] = (num >> 0) & 0xFF;
250 break;
251 }
252}
253
254int sfcx_get_blockversion(unsigned char *data)
255{
256 int ver = 0;
257 switch (sfc.meta_type)
258 {
259 case META_TYPE_0:
260 ver = (data[sfc.page_sz + 0x6] << 24) | (data[sfc.page_sz + 0x4] << 16) |
261 (data[sfc.page_sz + 0x3] << 8) | (data[sfc.page_sz + 0x2]);
262 break;
263 case META_TYPE_1:
264 ver = (data[sfc.page_sz + 0x6] << 24) | (data[sfc.page_sz + 0x4] << 16) |
265 (data[sfc.page_sz + 0x3] << 8) | (data[sfc.page_sz + 0x0]);
266 break;
267 case META_TYPE_2:
268 ver = (data[sfc.page_sz + 0x6] << 24) | (data[sfc.page_sz + 0x4] << 16) |
269 (data[sfc.page_sz + 0x3] << 8) | (data[sfc.page_sz + 0x5]);
270 break;
271 }
272 return ver;
273}
274
275void sfcx_set_blockversion(unsigned char *data, int ver)
276{
277 switch (sfc.meta_type)
278 {
279 case META_TYPE_0:
280 data[sfc.page_sz + 0x2] = (ver >> 0) & 0xFF;
281 data[sfc.page_sz + 0x3] = (ver >> 8) & 0xFF;
282 data[sfc.page_sz + 0x4] = (ver >> 16) & 0xFF;
283 data[sfc.page_sz + 0x6] = (ver >> 24) & 0xFF;
284 break;
285 case META_TYPE_1:
286 data[sfc.page_sz + 0x0] = (ver >> 0) & 0xFF;
287 data[sfc.page_sz + 0x3] = (ver >> 8) & 0xFF;
288 data[sfc.page_sz + 0x4] = (ver >> 16) & 0xFF;
289 data[sfc.page_sz + 0x6] = (ver >> 24) & 0xFF;
290 break;
291 case META_TYPE_2:
292 data[sfc.page_sz + 0x5] = (ver >> 0) & 0xFF;
293 data[sfc.page_sz + 0x3] = (ver >> 8) & 0xFF;
294 data[sfc.page_sz + 0x4] = (ver >> 16) & 0xFF;
295 data[sfc.page_sz + 0x6] = (ver >> 24) & 0xFF;
296 break;
297 }
298}
299
300void sfcx_set_pagevalid(unsigned char *data)
301{
302 switch (sfc.meta_type)
303 {
304 case META_TYPE_0:
305 data[sfc.page_sz + 0x5] = 0xFF;
306 break;
307 case META_TYPE_1:
308 data[sfc.page_sz + 0x5] = 0xFF;
309 break;
310 case META_TYPE_2:
311 data[sfc.page_sz + 0x0] = 0xFF;
312 break;
313 }
314}
315
316void sfcx_set_pageinvalid(unsigned char *data)
317{
318 switch (sfc.meta_type)
319 {
320 case META_TYPE_0:
321 data[sfc.page_sz + 0x5] = 0x00;
322 break;
323 case META_TYPE_1:
324 data[sfc.page_sz + 0x5] = 0x00;
325 break;
326 case META_TYPE_2:
327 data[sfc.page_sz + 0x0] = 0x00;
328 break;
329 }
330}
331
332int sfcx_is_pagevalid(unsigned char *data)
333{
334 int valid = 0;
335 switch (sfc.meta_type)
336 {
337 case META_TYPE_0:
338 valid = data[sfc.page_sz + 0x5] == 0xFF;
339 break;
340 case META_TYPE_1:
341 valid = data[sfc.page_sz + 0x5] == 0xFF;
342 break;
343 case META_TYPE_2:
344 valid = data[sfc.page_sz + 0x0] == 0xFF;
345 break;
346 }
347 return valid;
348}
349
350int sfcx_is_pagezeroed(unsigned char *data)
351{
352 int i;
353 for(i = 0; i < sfc.page_sz; i++)
354 {
355 if (data[i]!=0x00)
356 return 0;
357 }
358 return 1;
359}
360
361int sfcx_is_pageerased(unsigned char *data)
362{
363 int i;
364 for(i = 0; i < sfc.page_sz_phys; i++)
365 {
366 if (data[i]!=0xFF)
367 return 0;
368 }
369 return 1;
370}
371
373{
374 return block * sfc.block_sz;
375}
376
378{
379 return address / sfc.block_sz;
380}
381
383{
384 return block * sfc.block_sz_phys;
385}
386
388{
389 return address / sfc.block_sz_phys;
390}
391
393 int id = 0;
394 if (len >= 0x4410)
395 {
396 // Xenon, Falcon, Zephyr, JasperSB
397 id = ((blockbuf[sfc.page_sz + 1] << 8) | blockbuf[sfc.page_sz]);
398 if ((id == 0) && (blockbuf[sfc.page_sz + 5] == 0xFF))
399 {
400 //FIXME! I cannot handle badblock on block 1 yet...
401 id = ((blockbuf[0x4401] << 8) | blockbuf[0x4400]);
402 if ((id == 1) && (blockbuf[0x4405] == 0xFF))
403 {
405 return 0;
406 }
407 else if ((blockbuf[0x4405] != 0xFF))
408 {
409 printf(" ! Badblock on block 1 detected! Unable to check for META Type 0/1!\n");
410 return -3;
411 }
412 }
413 // Jasper, Trinity, Corona
414 id = ((blockbuf[sfc.page_sz + 2] << 8) | blockbuf[sfc.page_sz + 1]);
415 if ((id == 0) && (blockbuf[sfc.page_sz + 5] == 0xFF))
416 {
417 //FIXME! I cannot handle badblock on block 1 yet...
418 id = ((blockbuf[0x4402] << 8) | blockbuf[0x4401]);
419 if ((id == 1) && (blockbuf[0x4405] == 0xFF))
420 {
422 return 0;
423 }
424 }
425 }
426 else
427 {
428 printf(" ! Bad incompatible size");
429 return -2;
430 }
431 if (len >= 0x4410)
432 {
433 // BigBlock Jasper (256 or 512)
434 id = ((blockbuf[0x4402] << 8) | blockbuf[0x4401]);
435 if ((id == 0) && (blockbuf[0x4400] == 0xFF))
436 {
438 return 0;
439 }
440 }
441 else
442 {
443 printf(" ! Incompatible size\n");
444 return -2;
445 }
446 printf(" ! Bad meta data for this console type\n");
447 return -1;
448}
449
450int rawflash_checkImage_ecd_page(unsigned char* page) {
451 unsigned char ecd[4];
452 sfcx_calcecc_ex((unsigned int*)page, ecd);
453 if ((ecd[0] == page[0x20C]) && (ecd[1] == page[0x20D]) && (ecd[2] == page[0x20E]) && (ecd[3] == page[0x20F]))
454 return 0;
455 //printf("ecd[0] = 0x%x\necd[1] = 0x%x\necd[2] = 0x%x\necd[3] = 0x%x\n", ecd[0], ecd[1], ecd[2], ecd[3]);
456 //printf("page[0x20C] = 0x%x\npage[0x20D] = 0x%x\npage[0x20E] = 0x%x\npage[0x20F] = 0x%x\n", page[0x20C], page[0x20D], page[0x20E], page[0x20F]);
457 return -1;
458}
459
461 int offset = 0;
462 int result = 0;
463 while (offset < len / 0x210)
464 {
465 if (rawflash_checkImage_ecd_page(&blockbuf[offset]) != 0)
466 {
467 printf(" ! Bad ECD detected on page %i\n", offset / 0x210);
468 result = -1; // Bad ECD, probably because there's no spare data?!
469 }
470 offset += 0x210;
471 }
472 return result;
473}
474
476{
477 sfcx_init(); // Make sure sfcx is initalized!
478 int len = 0;
479 //if(sfc.meta_type == META_TYPE_2)
480 //len = 0x21210; // 257 pages
481 //else
482 len = 0x4410; // 33 pages
483 blockbuf = malloc(len);
484 if(blockbuf == NULL)
485 {
486 printf(" ! ERROR: unable to allocate 0x%x bytes for a buffer!\n", len);
487 return -1;
488 }
489 if (read(f, blockbuf, len) != len)
490 {
491 printf(" ! ERROR: Can't read enough data...");
492 free(blockbuf);
493 return -2;
494 }
495 if ((rawflash_checkImage_meta(len) != 0) || (rawflash_checkImage_ecd(len) != 0))
496 {
497 free(blockbuf);
498 return -1;
499 }
500 free(blockbuf);
501 return 0;
502}
503
504int rawflash_writeImage(int len, int f)
505{
506 int i=0;
507 int secondPgOffset = sfc.page_sz_phys;
508 int addr, addrphy, status, r;
509 int readsz = sfc.pages_in_block*sfc.page_sz_phys;
510 int numblocks = (len/sfc.block_sz_phys);
511 blockbuf = malloc(readsz);
512 if(blockbuf == NULL)
513 {
514 printf("ERROR: unable to allocate 0x%x bytes for a buffer!\n", readsz);
515 return 0;
516 }
518 secondPgOffset = 0x1080; // 0x210*8
519 while(i < numblocks)
520 {
521 printf("processing block 0x%04x of 0x%04x \r", i+1, numblocks);
522 addr = i*sfc.block_sz;
523 // check first two pages of each block to find out if it's a good block
524 status = sfcx_read_block(blockbuf, addr, 1);
525 if((sfcx_is_pagevalid(blockbuf) == 0) || (sfcx_is_pagevalid(&blockbuf[secondPgOffset]) == 0))
527 r = read(f, blockbuf, readsz);
528 if (r < 0)
529 {
530 printf("ERROR: failed to read %d bytes from file\n\n",readsz);
531 return 0;
532 }
533 if((status & (STATUS_BB_ER|STATUS_ECC_ER)) != 0)
534 {
535 printf("block 0x%x seems bad, status 0x%08x\n", i, status);
536 sfcx_erase_block(addr);
537 status = sfcx_erase_block(addr);
538 if (status == 0x200)
539 {
540 printf("Block recovered! (A.K.A The block wasn't bad in the first place...)\n");
542 }
543 else
544 printf("Block cannot be recovered (A.K.A it's really bad)\n");
545 }
546 else
547 {
548 addr = i*sfc.block_sz_phys;
549 addrphy = i*sfc.block_sz;
550 sfcx_erase_block(addrphy);
551 status = sfcx_write_block(blockbuf, addrphy);
552 }
553 i++;
554 }
555 printf("\n\n");
556 return 1;
557}
558
559int try_rawflash(char *filename)
560{
561 return try_rawflash_internal(filename, false);
562}
563
564int try_rawflash_internal(char *filename, bool ignoreMetadataCheck)
565{
566 struct stat s;
567
568 memset(&s, 0, sizeof(struct stat));
569 stat(filename, &s);
570 long size = s.st_size;
571 if (size <= 0)
572 return -1; //Invalid Filesize
573
574 int f = open(filename, O_RDONLY);
575 if (f < 0)
576 return f; //Can't open file!
577
578 printf(" * rawflash v5 started (by cOz, modified By Swizzy)\n");
579
580 if(ignoreMetadataCheck)
581 {
582 printf("\n" \
583 " ! ****** Warning ******\n" \
584 " ! NAND image validity checks are being skipped for this flash!\n" \
585 " ! This should only be used when intentionally flashing an image\n" \
586 " ! with mismatching metadata, e.g. a PSB image on an XSB console.\n" \
587 " ! Press power NOW to shut down and delete %s\n" \
588 " ! if you don't understand what this means!\n", filename);
589
590 delay(10);
591 }
592
593 if((size == (RAW_NAND_64*4)) || (size == (RAW_NAND_64*8))) // 256 or 512M NAND image, only flash 64M
595 else if((size != 0x1080000)&& (size != RAW_NAND_64)) // 16 M size
596 {
597 printf("error: %s - size %d is not valid image size!\n", filename, size);
598 close(f);
599 return -1;
600 }
601
602 printf("\n * found '%s'. press power NOW if you don't want to flash the NAND.\n",filename);
603 delay(15);
604
605 printf(" * Checking NAND File to be of matching type...\n");
606
607 if (rawflash_checkImage(f) != 0)
608 {
609 printf(" ! Bad Image for this console... ");
610
611 if(ignoreMetadataCheck)
612 {
613 printf("rawflash_checkImage result ignored, flashing the image anyway...\n");
614 }
615 else
616 {
617 printf("Please replace the file and try again...\n");
618 return -1;
619 }
620 }
621 else
622 {
623 printf(" * Image matches expected data...\n");
624 }
625
626 close(f); // to re-align it to the start again
627 f = open(filename, O_RDONLY);
628 if (f < 0)
629 return f; //Can't open file!
630
631 printf("%s opened OK, attempting to write 0x%x bytes to flash...\n",filename, size);
632 if(rawflash_writeImage(size, f) == 1)
633 printf("image written, shut down now!\n");
634 else
635 printf("failed to write image :(\n");
636
637 close(f);
638 if(blockbuf != NULL)
639 free(blockbuf);
640
641 for(;;); // loop
642 return -1;
643}
644
645/*
646int sfcx_read_metadata_type(void)
647{
648 int bid = 0; //Block ID
649
650 //Lets read what is actually on the nand
651 sfcx_read_page(sfcx_page, 0x8000, 1);
652
653 // Normal Xenon Type
654 bid = (sfcx_page[sfc.page_sz + 0x1] << 8) | (sfcx_page[sfc.page_sz + 0x0]);
655 if (bid == 2 && sfcx_page[sfc.page_sz + 0x5] == 0xFF){
656 return META_TYPE_0;
657 }
658
659 // Jasper 16MB Small Block
660 bid = (sfcx_page[sfc.page_sz + 0x2] << 8) | (sfcx_page[sfc.page_sz + 0x1]);
661 if (bid == 2 && sfcx_page[sfc.page_sz + 0x5] == 0xFF){
662 return META_TYPE_1;
663 }
664
665 // Jasper 256/512 Large Block
666 bid = (sfcx_page[sfc.page_sz + 0x2] << 8) | (sfcx_page[sfc.page_sz + 0x1]);
667 if (bid == 0 && sfcx_page[sfc.page_sz + 0x0] == 0xFF){
668 return META_TYPE_2;
669 }
670
671 return -1;
672
673}
674*/
675
676unsigned int sfcx_init(void)
677{
678 if ((xenon_get_PCIBridgeRevisionID() >= 0x70) && (sfcx_readreg(SFCX_PHISON) != 0)) {
679 printf(" ! SFCX: Unsupported Type - PHISON eMMC\n");
680 return 3;
681 }
682
683 unsigned int config = sfcx_readreg(SFCX_CONFIG);
684
685 if (sfc.initialized) return config;
686
687 sfc.initialized = 0;
688 sfc.meta_type = 0;
689 sfc.page_sz = 0x200;
690 sfc.meta_sz = 0x10;
692
693 //Turn off interrupts, turn off WP_EN, and set DMA pages to 0
695
696 switch ((config >> 17) & 0x03)
697 {
698 case 0: // Small block original SFC (pre jasper)
701
702 switch ((config >> 4) & 0x3)
703 {
704 case 0: // Unsupported 8MB?
705 printf(" ! SFCX: Unsupported Type A-0\n");
706 delay(5);
707 return 1;
708
709 //sfc.block_sz = 0x4000; // 16 KB
710 //sfc.size_blocks = 0x200;
711 //sfc.size_bytes = sfc.size_blocks << 0xE;
712 //sfc.size_usable_fs = 0xXXX;
713 //sfc.addr_config = 0x07BE000 - 0x4000;
714
715 case 1: // 16MB
716 sfc.block_sz = 0x4000; // 16 KB
717 sfc.size_blocks = 0x400;
718 sfc.size_bytes = sfc.size_blocks << 0xE;
719 sfc.size_usable_fs = 0x3E0;
721 break;
722
723 case 2: // 32MB
724 sfc.block_sz = 0x4000; // 16 KB
725 sfc.size_blocks = 0x800;
726 sfc.size_bytes = sfc.size_blocks << 0xE;
727 sfc.size_usable_fs = 0x7C0;
729 break;
730
731 case 3: // 64MB
732 sfc.block_sz = 0x4000; // 16 KB
733 sfc.size_blocks = 0x1000;
734 sfc.size_bytes = sfc.size_blocks << 0xE;
735 sfc.size_usable_fs = 0xF80;
737 break;
738 }
739 break;
740
741 case 1: // New SFC/Southbridge: Codename "Panda"?
742 case 2: // New SFC/Southbridge: Codename "Panda" v2?
743 switch ((config >> 4) & 0x3)
744 {
745 case 0:
746
747 if(((config >> 17) & 0x03) == 0x01)
748 {
749 // Unsupported
751 printf(" ! SFCX: Unsupported Type B-0\n");
752 delay(5);
753 return 2;
754 }
755 else
756 {
758 sfc.block_sz = 0x4000; // 16 KB
759 sfc.size_blocks = 0x400;
760 sfc.size_bytes = sfc.size_blocks << 0xE;
762 sfc.size_usable_fs = 0x3E0;
764 break;
765 }
766
767 case 1:
768
769 if(((config >> 17) & 0x03) == 0x01)
770 {
771 // Small block 16MB setup
773 sfc.block_sz = 0x4000; // 16 KB
774 sfc.size_blocks = 0x400;
775 sfc.size_bytes = sfc.size_blocks << 0xE;
777 sfc.size_usable_fs = 0x3E0;
779 break;
780 }
781 else
782 {
783 // Small block 64MB setup
785 sfc.block_sz = 0x4000; // 16 KB
786 sfc.size_blocks = 0x1000;
787 sfc.size_bytes = sfc.size_blocks << 0xE;
789 sfc.size_usable_fs = 0xF80;
791 break;
792 }
793
794 case 2: // Large Block: Current Jasper 256MB and 512MB
796 sfc.block_sz = 0x20000; // 128KB
797 sfc.size_bytes = 0x1 << (((config >> 19) & 0x3) + ((config >> 21) & 0xF) + 0x17);
798 sfc.size_blocks = sfc.size_bytes >> 0x11;
800 sfc.size_usable_fs = 0x1E0;
802 break;
803
804 case 3: // Large Block: Future or unknown hardware
806 sfc.block_sz = 0x40000; // 256KB
807 sfc.size_bytes = 0x1 << (((config >> 19) & 0x3) + ((config >> 21) & 0xF) + 0x17);
808 sfc.size_blocks = sfc.size_bytes >> 0x12;
810 sfc.size_usable_fs = 0xF0;
812 break;
813 }
814 break;
815
816 default:
817 printf(" ! SFCX: Unsupported Type\n");
818 delay(5);
819 return 3;
820 }
821
822 sfc.len_config = sfc.block_sz * 0x04; //4 physical blocks
823
826
829
831 sfc.size_mb = sfc.size_bytes >> 20;
832
833/*
834 int meta_type;
835
836 meta_type = sfcx_read_metadata_type();
837 if (meta_type == -1){
838 printf(" ! SFCX: Meta Type detection error\n");
839 delay(5);
840 return 4;
841 }
842
843 if (meta_type != sfc.meta_type){
844 printf(" ! SFCX: Meta Type detection difference\n");
845 printf(" ! SFCX: expecting type: '%d' detected: '%d'\n", sfc.meta_type, meta_type);
846 sfc.meta_type = meta_type;
847 }
848
849*/
850
851
852#if 0
853 printf(" config register = %08X\n", config);
854
855 printf(" sfc:page_sz = %08X\n", sfc.page_sz);
856 printf(" sfc:meta_sz = %08X\n", sfc.meta_sz);
857 printf(" sfc:page_sz_phys = %08X\n", sfc.page_sz_phys);
858
859 printf(" sfc:pages_in_block = %08X\n", sfc.pages_in_block);
860 printf(" sfc:block_sz = %08X\n", sfc.block_sz);
861 printf(" sfc:block_sz_phys = %08X\n", sfc.block_sz_phys);
862
863 printf(" sfc:size_mb = %dMB\n", sfc.size_mb);
864 printf(" sfc:size_bytes = %08X\n", sfc.size_bytes);
865 printf(" sfc:size_bytes_phys = %08X\n", sfc.size_bytes_phys);
866
867 printf(" sfc:size_pages = %08X\n", sfc.size_pages);
868 printf(" sfc:size_blocks = %08X\n", sfc.size_blocks);
869 printf("\n");
870#endif
871
873 return config;
874}
875
uint32_t address
Definition: ata.h:0
#define NULL
Definition: def.h:47
u32 status
Definition: ehci_defs.h:15
static uint32_t val
Definition: io.h:17
u32 size
Definition: iso9660.c:537
int close(int fileDesc)
Definition: newlib.c:829
int stat(const char *file, struct stat *st)
Definition: newlib.c:643
int read(int fileDesc, void *ptr, size_t len)
Definition: newlib.c:559
int open(const char *file, int flags, int mode)
Definition: newlib.c:522
Definition: xenon_sfcx.h:86
int page_sz_phys
Definition: xenon_sfcx.h:92
int page_sz
Definition: xenon_sfcx.h:90
int len_config
Definition: xenon_sfcx.h:107
int size_bytes_phys
Definition: xenon_sfcx.h:100
int meta_type
Definition: xenon_sfcx.h:88
int size_blocks
Definition: xenon_sfcx.h:102
int blocks_per_lg_block
Definition: xenon_sfcx.h:104
int size_bytes
Definition: xenon_sfcx.h:99
int size_mb
Definition: xenon_sfcx.h:98
int meta_sz
Definition: xenon_sfcx.h:91
int block_sz
Definition: xenon_sfcx.h:95
int initialized
Definition: xenon_sfcx.h:87
int addr_config
Definition: xenon_sfcx.h:106
int pages_in_block
Definition: xenon_sfcx.h:94
int size_usable_fs
Definition: xenon_sfcx.h:105
int block_sz_phys
Definition: xenon_sfcx.h:96
int size_pages
Definition: xenon_sfcx.h:101
void delay(int u)
Definition: time.c:22
unsigned int xenon_get_PCIBridgeRevisionID()
Definition: xb360.c:489
unsigned long sfcx_readreg(int addr)
Definition: xenon_sfcx.c:20
int rawflash_checkImage(int f)
Definition: xenon_sfcx.c:475
int sfcx_is_pageerased(unsigned char *data)
Definition: xenon_sfcx.c:361
int sfcx_read_page(unsigned char *data, int address, int raw)
Definition: xenon_sfcx.c:25
void sfcx_set_pagevalid(unsigned char *data)
Definition: xenon_sfcx.c:300
int sfcx_write_page(unsigned char *data, int address)
Definition: xenon_sfcx.c:74
void sfcx_set_pageinvalid(unsigned char *data)
Definition: xenon_sfcx.c:316
unsigned char * blockbuf
Definition: xenon_sfcx.c:11
int sfcx_rawaddress_to_block(int address)
Definition: xenon_sfcx.c:387
int sfcx_block_to_rawaddress(int block)
Definition: xenon_sfcx.c:382
int sfcx_get_blocknumber(unsigned char *data)
Definition: xenon_sfcx.c:217
int sfcx_address_to_block(int address)
Definition: xenon_sfcx.c:377
int sfcx_get_blockversion(unsigned char *data)
Definition: xenon_sfcx.c:254
void sfcx_set_blockversion(unsigned char *data, int ver)
Definition: xenon_sfcx.c:275
int sfcx_read_block(unsigned char *data, int address, int raw)
Definition: xenon_sfcx.c:121
int rawflash_checkImage_ecd_page(unsigned char *page)
Definition: xenon_sfcx.c:450
void sfcx_calcecc_ex(unsigned int *data, unsigned char *edc)
Definition: xenon_sfcx.c:187
int rawflash_writeImage(int len, int f)
Definition: xenon_sfcx.c:504
int sfcx_is_pagezeroed(unsigned char *data)
Definition: xenon_sfcx.c:350
void sfcx_calcecc(unsigned int *data)
Definition: xenon_sfcx.c:211
int try_rawflash_internal(char *filename, bool ignoreMetadataCheck)
Definition: xenon_sfcx.c:564
void sfcx_writereg(int addr, unsigned long data)
Definition: xenon_sfcx.c:15
int rawflash_checkImage_meta(int len)
Definition: xenon_sfcx.c:392
int rawflash_checkImage_ecd(int len)
Definition: xenon_sfcx.c:460
int sfcx_is_pagevalid(unsigned char *data)
Definition: xenon_sfcx.c:332
int try_rawflash(char *filename)
Definition: xenon_sfcx.c:559
unsigned int sfcx_init(void)
Definition: xenon_sfcx.c:676
int sfcx_erase_block(int address)
Definition: xenon_sfcx.c:150
int sfcx_block_to_address(int block)
Definition: xenon_sfcx.c:372
int sfcx_write_block(unsigned char *data, int address)
Definition: xenon_sfcx.c:136
void sfcx_set_blocknumber(unsigned char *data, int num)
Definition: xenon_sfcx.c:235
#define SFCX_COMMAND
Definition: xenon_sfcx.h:9
#define PHY_PAGE_TO_BUF
Definition: xenon_sfcx.h:22
#define LOG_PAGE_TO_BUF
Definition: xenon_sfcx.h:21
#define SFCX_CONFIG
Definition: xenon_sfcx.h:7
#define SFCX_INITIALIZED
Definition: xenon_sfcx.h:78
#define SFCX_SUCCESS(status)
Definition: xenon_sfcx.h:83
#define META_TYPE_1
Definition: xenon_sfcx.h:67
#define WRITE_PAGE_TO_PHY
Definition: xenon_sfcx.h:23
#define SFCX_ADDRESS
Definition: xenon_sfcx.h:10
#define CONFIG_INT_EN
Definition: xenon_sfcx.h:40
#define BLOCK_ERASE
Definition: xenon_sfcx.h:24
#define STATUS_BB_ER
Definition: xenon_sfcx.h:50
#define META_TYPE_0
Definition: xenon_sfcx.h:66
#define PAGE_BUF_TO_REG
Definition: xenon_sfcx.h:19
#define UNLOCK_CMD_0
Definition: xenon_sfcx.h:28
#define REG_TO_PAGE_BUF
Definition: xenon_sfcx.h:20
#define STATUS_ILL_LOG
Definition: xenon_sfcx.h:45
#define SFCX_DATA
Definition: xenon_sfcx.h:11
#define CONFIG_DMA_LEN
Definition: xenon_sfcx.h:37
#define STATUS_BUSY
Definition: xenon_sfcx.h:54
#define STATUS_ECC_ER
Definition: xenon_sfcx.h:52
#define RAW_NAND_64
Definition: xenon_sfcx.h:76
#define SFCX_STATUS
Definition: xenon_sfcx.h:8
#define SFCX_PHISON
Definition: xenon_sfcx.h:16
#define CONFIG_WP_EN
Definition: xenon_sfcx.h:39
#define CONFIG_BLOCKS
Definition: xenon_sfcx.h:70
#define META_TYPE_2
Definition: xenon_sfcx.h:68
#define UNLOCK_CMD_1
Definition: xenon_sfcx.h:29
union @15 data