Subversion Repositories freemyipod

Rev

Rev 66 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 66 Rev 68
Line 92... Line 92...
92
static struct mutex nand_mtx;
92
static struct mutex nand_mtx;
93
static struct wakeup nand_wakeup;
93
static struct wakeup nand_wakeup;
94
static struct mutex ecc_mtx;
94
static struct mutex ecc_mtx;
95
static struct wakeup ecc_wakeup;
95
static struct wakeup ecc_wakeup;
96
 
96
 
97
static uint8_t nand_data[0x800] CACHEALIGN_ATTR;
-
 
98
static uint8_t nand_ctrl[0x200] CACHEALIGN_ATTR;
97
static uint8_t nand_ctrl[0x200] CACHEALIGN_ATTR;
99
static uint8_t nand_spare[0x40] CACHEALIGN_ATTR;
98
static uint8_t nand_spare[0x40] CACHEALIGN_ATTR;
100
static uint8_t nand_ecc[0x30] CACHEALIGN_ATTR;
99
static uint8_t nand_ecc[0x30] CACHEALIGN_ATTR;
101
 
100
 
102
 
101
 
Line 373... Line 372...
373
 
372
 
374
uint32_t nand_read_page(uint32_t bank, uint32_t page, void* databuffer,
373
uint32_t nand_read_page(uint32_t bank, uint32_t page, void* databuffer,
375
                        void* sparebuffer, uint32_t doecc,
374
                        void* sparebuffer, uint32_t doecc,
376
                        uint32_t checkempty)
375
                        uint32_t checkempty)
377
{
376
{
378
    uint8_t* data = nand_data;
377
    uint8_t* data = (uint8_t*)databuffer;
379
    uint8_t* spare = nand_spare;
378
    uint8_t* spare = nand_spare;
380
    if (databuffer && !((uint32_t)databuffer & 0xf))
379
    if (sparebuffer) spare = (uint8_t*)sparebuffer;
381
        data = (uint8_t*)databuffer;
380
	if ((uint32_t)databuffer & 0xf)
-
 
381
		panicf(PANIC_KILLUSERTHREADS,
-
 
382
	           "nand_read_page: Misaligned data buffer at %08X (bank %lu, page %lu)",
-
 
383
			   (unsigned int)databuffer, bank, page);
382
    if (sparebuffer && !((uint32_t)sparebuffer & 0xf))
384
	if ((uint32_t)sparebuffer & 0xf)
-
 
385
		panicf(PANIC_KILLUSERTHREADS,
-
 
386
	           "nand_read_page: Misaligned spare buffer at %08X (bank %lu, page %lu)",
383
        spare = (uint8_t*)sparebuffer;
387
			   (unsigned int)sparebuffer, bank, page);
384
    mutex_lock(&nand_mtx, TIMEOUT_BLOCK);
388
    mutex_lock(&nand_mtx, TIMEOUT_BLOCK);
385
    nand_last_activity_value = USEC_TIMER;
389
    nand_last_activity_value = USEC_TIMER;
386
    if (!nand_powered) nand_power_up();
390
    if (!nand_powered) nand_power_up();
387
    uint32_t rc, eccresult;
391
    uint32_t rc, eccresult;
388
    nand_set_fmctrl0(bank, FMCTRL0_ENABLEDMA);
392
    nand_set_fmctrl0(bank, FMCTRL0_ENABLEDMA);
389
    if (nand_send_cmd(NAND_CMD_READ)) return nand_unlock(1);
393
    if (nand_send_cmd(NAND_CMD_READ)) return nand_unlock(1);
390
    if (nand_send_address(page, databuffer ? 0 : 0x800))
394
    if (nand_send_address(page, data ? 0 : 0x800))
391
        return nand_unlock(1);
395
        return nand_unlock(1);
392
    if (nand_send_cmd(NAND_CMD_READ2)) return nand_unlock(1);
396
    if (nand_send_cmd(NAND_CMD_READ2)) return nand_unlock(1);
393
    if (nand_wait_status_ready(bank)) return nand_unlock(1);
397
    if (nand_wait_status_ready(bank)) return nand_unlock(1);
394
    if (databuffer)
398
    if (data)
395
        if (nand_transfer_data(bank, 0, data, 0x800))
399
        if (nand_transfer_data(bank, 0, data, 0x800))
396
            return nand_unlock(1);
400
            return nand_unlock(1);
397
    rc = 0;
401
    rc = 0;
398
    if (!doecc)
402
    if (!doecc)
399
    {
403
    {
400
        if (databuffer && data != databuffer) memcpy(databuffer, data, 0x800);
-
 
401
        if (sparebuffer)
404
        if (sparebuffer)
402
        {
405
        {
403
            if (nand_transfer_data(bank, 0, spare, 0x40))
406
            if (nand_transfer_data(bank, 0, spare, 0x40))
404
                return nand_unlock(1);
407
                return nand_unlock(1);
405
            if (sparebuffer && spare != sparebuffer) 
408
            if (sparebuffer) 
406
                memcpy(sparebuffer, spare, 0x800);
409
                memcpy(sparebuffer, spare, 0x800);
407
            if (checkempty)
410
            if (checkempty)
408
                rc = nand_check_empty((uint8_t*)sparebuffer) << 1;
411
                rc = nand_check_empty((uint8_t*)sparebuffer) << 1;
409
        }
412
        }
410
        return nand_unlock(rc);
413
        return nand_unlock(rc);
Line 412... Line 415...
412
    if (nand_transfer_data(bank, 0, spare, 0x40)) return nand_unlock(1);
415
    if (nand_transfer_data(bank, 0, spare, 0x40)) return nand_unlock(1);
413
    if (databuffer)
416
    if (databuffer)
414
    {
417
    {
415
        memcpy(nand_ecc, &spare[0xC], 0x28);
418
        memcpy(nand_ecc, &spare[0xC], 0x28);
416
        rc |= (ecc_decode(3, data, nand_ecc) & 0xF) << 4;
419
        rc |= (ecc_decode(3, data, nand_ecc) & 0xF) << 4;
417
        if (data != databuffer) memcpy(databuffer, data, 0x800);
-
 
418
    }
420
    }
419
    memset(nand_ctrl, 0xFF, 0x200);
421
    memset(nand_ctrl, 0xFF, 0x200);
420
    memcpy(nand_ctrl, spare, 0xC);
422
    memcpy(nand_ctrl, spare, 0xC);
421
    memcpy(nand_ecc, &spare[0x34], 0xC);
423
    memcpy(nand_ecc, &spare[0x34], 0xC);
422
    eccresult = ecc_decode(0, nand_ctrl, nand_ecc);
424
    eccresult = ecc_decode(0, nand_ctrl, nand_ecc);
423
    rc |= (eccresult & 0xF) << 8;
425
    rc |= (eccresult & 0xF) << 8;
424
    if (sparebuffer)
426
    if (sparebuffer)
425
    {
427
    {
426
        if (spare != sparebuffer) memcpy(sparebuffer, spare, 0x40);
-
 
427
        if (eccresult & 1) memset(sparebuffer, 0xFF, 0xC);
428
        if (eccresult & 1) memset(sparebuffer, 0xFF, 0xC);
428
        else memcpy(sparebuffer, nand_ctrl, 0xC);
429
        else memcpy(sparebuffer, nand_ctrl, 0xC);
429
    }
430
    }
430
    if (checkempty) rc |= nand_check_empty(spare) << 1;
431
    if (checkempty) rc |= nand_check_empty(spare) << 1;
431
 
432
 
Line 434... Line 435...
434
 
435
 
435
static uint32_t nand_write_page_int(uint32_t bank, uint32_t page,
436
static uint32_t nand_write_page_int(uint32_t bank, uint32_t page,
436
                                    void* databuffer, void* sparebuffer,
437
                                    void* databuffer, void* sparebuffer,
437
                                    uint32_t doecc, uint32_t wait)
438
                                    uint32_t doecc, uint32_t wait)
438
{
439
{
439
    uint8_t* data = nand_data;
440
    uint8_t* data = (uint8_t*)databuffer;
440
    uint8_t* spare = nand_spare;
441
    uint8_t* spare = nand_spare;
441
    if (databuffer && !((uint32_t)databuffer & 0xf))
442
    if (sparebuffer) spare = (uint8_t*)sparebuffer;
442
        data = (uint8_t*)databuffer;
443
	if ((uint32_t)databuffer & 0xf)
-
 
444
		panicf(PANIC_KILLUSERTHREADS,
-
 
445
	           "nand_write_page: Misaligned data buffer at %08X (bank %lu, page %lu)",
-
 
446
			   (unsigned int)databuffer, bank, page);
443
    if (sparebuffer && !((uint32_t)sparebuffer & 0xf))
447
	if ((uint32_t)sparebuffer & 0xf)
-
 
448
		panicf(PANIC_KILLUSERTHREADS,
-
 
449
	           "nand_write_page: Misaligned spare buffer at %08X (bank %lu, page %lu)",
444
        spare = (uint8_t*)sparebuffer;
450
			   (unsigned int)sparebuffer, bank, page);
445
    mutex_lock(&nand_mtx, TIMEOUT_BLOCK);
451
    mutex_lock(&nand_mtx, TIMEOUT_BLOCK);
446
    nand_last_activity_value = USEC_TIMER;
452
    nand_last_activity_value = USEC_TIMER;
447
    if (!nand_powered) nand_power_up();
453
    if (!nand_powered) nand_power_up();
448
    if (sparebuffer)
-
 
449
    {
-
 
450
        if (spare != sparebuffer) memcpy(spare, sparebuffer, 0x40);
-
 
451
    }
-
 
452
    else memset(spare, 0xFF, 0x40);
454
    if (!sparebuffer) memset(spare, 0xFF, 0x40);
453
    nand_set_fmctrl0(bank, FMCTRL0_ENABLEDMA);
455
    nand_set_fmctrl0(bank, FMCTRL0_ENABLEDMA);
454
    if (nand_send_cmd(NAND_CMD_PROGRAM)) return nand_unlock(1);
456
    if (nand_send_cmd(NAND_CMD_PROGRAM)) return nand_unlock(1);
455
    if (nand_send_address(page, databuffer ? 0 : 0x800))
457
    if (nand_send_address(page, data ? 0 : 0x800))
456
        return nand_unlock(1);
458
        return nand_unlock(1);
457
    if (databuffer && data != databuffer) memcpy(data, databuffer, 0x800);
-
 
458
    if (databuffer) nand_transfer_data_start(bank, 1, data, 0x800);
459
    if (data) nand_transfer_data_start(bank, 1, data, 0x800);
459
    if (doecc)
460
    if (doecc)
460
    {
461
    {
461
        if (ecc_encode(3, data, nand_ecc)) return nand_unlock(1);
462
        if (ecc_encode(3, data, nand_ecc)) return nand_unlock(1);
462
        memcpy(&spare[0xC], nand_ecc, 0x28);
463
        memcpy(&spare[0xC], nand_ecc, 0x28);
463
        memset(nand_ctrl, 0xFF, 0x200);
464
        memset(nand_ctrl, 0xFF, 0x200);
464
        memcpy(nand_ctrl, spare, 0xC);
465
        memcpy(nand_ctrl, spare, 0xC);
465
        if (ecc_encode(0, nand_ctrl, nand_ecc)) return nand_unlock(1);
466
        if (ecc_encode(0, nand_ctrl, nand_ecc)) return nand_unlock(1);
466
        memcpy(&spare[0x34], nand_ecc, 0xC);
467
        memcpy(&spare[0x34], nand_ecc, 0xC);
467
    }
468
    }
468
    if (databuffer)
469
    if (data)
469
        if (nand_transfer_data_collect(1))
470
        if (nand_transfer_data_collect(1))
470
            return nand_unlock(1);
471
            return nand_unlock(1);
471
    if (sparebuffer || doecc)
472
    if (sparebuffer || doecc)
472
        if (nand_transfer_data(bank, 1, spare, 0x40))
473
        if (nand_transfer_data(bank, 1, spare, 0x40))
473
            return nand_unlock(1);
474
            return nand_unlock(1);