Commit 4edc0201227ac15ba6b4d353025e3b34fe287d0d
1 parent
66cbdd2f
disable debug, use common nand code in emulation,
we reach mount root stage, though read seems failed
Showing
5 changed files
with
36 additions
and
33 deletions
hw/at91.h
| @@ -56,6 +56,7 @@ extern void at91_pdc_reset(PDCState *s); | @@ -56,6 +56,7 @@ extern void at91_pdc_reset(PDCState *s); | ||
| 56 | extern void at91_pdc_write(void *opaque, target_phys_addr_t offset, uint32_t val); | 56 | extern void at91_pdc_write(void *opaque, target_phys_addr_t offset, uint32_t val); |
| 57 | extern uint32_t at91_pdc_read(void *opaque, target_phys_addr_t offset); | 57 | extern uint32_t at91_pdc_read(void *opaque, target_phys_addr_t offset); |
| 58 | 58 | ||
| 59 | -extern void at91_nand_register(void); | 59 | +struct NANDFlashState; |
| 60 | +extern void at91_nand_register(struct NANDFlashState *st); | ||
| 60 | 61 | ||
| 61 | #endif /* !AT91_H */ | 62 | #endif /* !AT91_H */ |
hw/at91_nand.c
| 1 | #include <stdio.h> | 1 | #include <stdio.h> |
| 2 | 2 | ||
| 3 | #include "hw.h" | 3 | #include "hw.h" |
| 4 | +#include "flash.h" | ||
| 4 | #include "at91.h" | 5 | #include "at91.h" |
| 5 | 6 | ||
| 6 | typedef struct NandState { | 7 | typedef struct NandState { |
| 7 | - unsigned int cmd; | 8 | + NANDFlashState *nand_state; |
| 8 | } NandState; | 9 | } NandState; |
| 9 | 10 | ||
| 10 | -#define AT91_NAND_DEBUG | 11 | +//#define AT91_NAND_DEBUG |
| 11 | #ifdef AT91_NAND_DEBUG | 12 | #ifdef AT91_NAND_DEBUG |
| 12 | #define DPRINTF(fmt, ...) \ | 13 | #define DPRINTF(fmt, ...) \ |
| 13 | do { \ | 14 | do { \ |
| @@ -23,23 +24,19 @@ static uint32_t at91_nand_mem_read(void *opaque, target_phys_addr_t offset) | @@ -23,23 +24,19 @@ static uint32_t at91_nand_mem_read(void *opaque, target_phys_addr_t offset) | ||
| 23 | { | 24 | { |
| 24 | NandState *s = opaque; | 25 | NandState *s = opaque; |
| 25 | 26 | ||
| 26 | - DPRINTF("(IP %X) read from %X\n", g_env->regs[15], offset); | ||
| 27 | - switch (s->cmd) { | ||
| 28 | - case 0x70: | ||
| 29 | - s->cmd = 0; | ||
| 30 | - return 0x40; | ||
| 31 | - default: | ||
| 32 | - return 0x0; | ||
| 33 | - } | 27 | + uint8_t res = nand_getio(s->nand_state); |
| 28 | + DPRINTF("(IP %X) read from %X (res %X)\n", g_env->regs[15], offset, res); | ||
| 29 | + return res; | ||
| 34 | } | 30 | } |
| 35 | 31 | ||
| 36 | static void at91_nand_mem_write(void *opaque, target_phys_addr_t offset, | 32 | static void at91_nand_mem_write(void *opaque, target_phys_addr_t offset, |
| 37 | uint32_t value) | 33 | uint32_t value) |
| 38 | { | 34 | { |
| 39 | - NandState *s = opaque; | 35 | + NandState *s = opaque; |
| 40 | 36 | ||
| 37 | + nand_setpins(s->nand_state, offset & (1 << 22), offset & (1 << 21), 0, 1, 0); | ||
| 41 | DPRINTF("(IP %X) write to %X %X\n", g_env->regs[15], offset, value); | 38 | DPRINTF("(IP %X) write to %X %X\n", g_env->regs[15], offset, value); |
| 42 | - s->cmd = value; | 39 | + nand_setio(s->nand_state, value & 0xFF); |
| 43 | } | 40 | } |
| 44 | 41 | ||
| 45 | static CPUReadMemoryFunc *at91_nand_readfn[] = { | 42 | static CPUReadMemoryFunc *at91_nand_readfn[] = { |
| @@ -54,12 +51,13 @@ static CPUWriteMemoryFunc *at91_nand_writefn[] = { | @@ -54,12 +51,13 @@ static CPUWriteMemoryFunc *at91_nand_writefn[] = { | ||
| 54 | at91_nand_mem_write, | 51 | at91_nand_mem_write, |
| 55 | }; | 52 | }; |
| 56 | 53 | ||
| 57 | -void at91_nand_register(void) | 54 | +void at91_nand_register(NANDFlashState *st) |
| 58 | { | 55 | { |
| 59 | NandState *s; | 56 | NandState *s; |
| 60 | int iomemtype; | 57 | int iomemtype; |
| 61 | 58 | ||
| 62 | s = qemu_mallocz(sizeof(*s)); | 59 | s = qemu_mallocz(sizeof(*s)); |
| 60 | + s->nand_state = st; | ||
| 63 | iomemtype = cpu_register_io_memory(at91_nand_readfn, at91_nand_writefn, s); | 61 | iomemtype = cpu_register_io_memory(at91_nand_readfn, at91_nand_writefn, s); |
| 64 | cpu_register_physical_memory(0x40000000, 0x10000000, iomemtype); | 62 | cpu_register_physical_memory(0x40000000, 0x10000000, iomemtype); |
| 65 | } | 63 | } |
hw/at91_pdc.c
| @@ -24,7 +24,7 @@ | @@ -24,7 +24,7 @@ | ||
| 24 | #define PDC_PTCR_TXTEN (1 << 8) | 24 | #define PDC_PTCR_TXTEN (1 << 8) |
| 25 | #define PDC_PTCR_TXTDIS (1 << 9) | 25 | #define PDC_PTCR_TXTDIS (1 << 9) |
| 26 | 26 | ||
| 27 | -#define AT91_PDC_DEBUG | 27 | +//#define AT91_PDC_DEBUG |
| 28 | #ifdef AT91_PDC_DEBUG | 28 | #ifdef AT91_PDC_DEBUG |
| 29 | #define DPRINTF(fmt, ...) \ | 29 | #define DPRINTF(fmt, ...) \ |
| 30 | do { \ | 30 | do { \ |
hw/at91sam9.c
| @@ -344,6 +344,8 @@ static void at91sam9_init(ram_addr_t ram_size, | @@ -344,6 +344,8 @@ static void at91sam9_init(ram_addr_t ram_size, | ||
| 344 | dinfo = drive_get(IF_PFLASH, 0, 0); | 344 | dinfo = drive_get(IF_PFLASH, 0, 0); |
| 345 | if (dinfo) { | 345 | if (dinfo) { |
| 346 | if (bms) { | 346 | if (bms) { |
| 347 | + NANDFlashState *nand_state; | ||
| 348 | + | ||
| 347 | if (spi_flash_register(dinfo->bdrv, 4 * 1024 * 1024, cs0_spi_handler) < 0) { | 349 | if (spi_flash_register(dinfo->bdrv, 4 * 1024 * 1024, cs0_spi_handler) < 0) { |
| 348 | fprintf(stderr, "init of spi flash failed\n"); | 350 | fprintf(stderr, "init of spi flash failed\n"); |
| 349 | exit(EXIT_FAILURE); | 351 | exit(EXIT_FAILURE); |
| @@ -352,7 +354,8 @@ static void at91sam9_init(ram_addr_t ram_size, | @@ -352,7 +354,8 @@ static void at91sam9_init(ram_addr_t ram_size, | ||
| 352 | //rom | 354 | //rom |
| 353 | cpu_register_physical_memory(0x0, 100 * 1024, | 355 | cpu_register_physical_memory(0x0, 100 * 1024, |
| 354 | sam9->bootrom | IO_MEM_ROMD); | 356 | sam9->bootrom | IO_MEM_ROMD); |
| 355 | - at91_nand_register(); | 357 | + nand_state = nand_init(NAND_MFR_MICRON, 0xba); |
| 358 | + at91_nand_register(nand_state); | ||
| 356 | } else { | 359 | } else { |
| 357 | //nor flash | 360 | //nor flash |
| 358 | ram_addr_t nor_flash_mem = qemu_ram_alloc(NOR_FLASH_SIZE); | 361 | ram_addr_t nor_flash_mem = qemu_ram_alloc(NOR_FLASH_SIZE); |
hw/nand.c
| @@ -39,7 +39,7 @@ | @@ -39,7 +39,7 @@ | ||
| 39 | # define NAND_IOSTATUS_PLANE1 (1 << 2) | 39 | # define NAND_IOSTATUS_PLANE1 (1 << 2) |
| 40 | # define NAND_IOSTATUS_PLANE2 (1 << 3) | 40 | # define NAND_IOSTATUS_PLANE2 (1 << 3) |
| 41 | # define NAND_IOSTATUS_PLANE3 (1 << 4) | 41 | # define NAND_IOSTATUS_PLANE3 (1 << 4) |
| 42 | -# define NAND_IOSTATUS_BUSY (1 << 6) | 42 | +# define NAND_IOSTATUS_READY (1 << 6) |
| 43 | # define NAND_IOSTATUS_UNPROTCT (1 << 7) | 43 | # define NAND_IOSTATUS_UNPROTCT (1 << 7) |
| 44 | 44 | ||
| 45 | # define MAX_PAGE 0x800 | 45 | # define MAX_PAGE 0x800 |
| @@ -207,7 +207,8 @@ static void nand_reset(NANDFlashState *s) | @@ -207,7 +207,8 @@ static void nand_reset(NANDFlashState *s) | ||
| 207 | s->addrlen = 0; | 207 | s->addrlen = 0; |
| 208 | s->iolen = 0; | 208 | s->iolen = 0; |
| 209 | s->offset = 0; | 209 | s->offset = 0; |
| 210 | - s->status &= NAND_IOSTATUS_UNPROTCT; | 210 | + s->status = NAND_IOSTATUS_READY; |
| 211 | + s->status &= ~NAND_IOSTATUS_UNPROTCT; | ||
| 211 | } | 212 | } |
| 212 | 213 | ||
| 213 | static void nand_command(NANDFlashState *s) | 214 | static void nand_command(NANDFlashState *s) |
| @@ -358,11 +359,11 @@ void nand_setio(NANDFlashState *s, uint8_t value) | @@ -358,11 +359,11 @@ void nand_setio(NANDFlashState *s, uint8_t value) | ||
| 358 | } | 359 | } |
| 359 | if (value == NAND_CMD_READ0) | 360 | if (value == NAND_CMD_READ0) |
| 360 | s->offset = 0; | 361 | s->offset = 0; |
| 361 | - else if (value == NAND_CMD_READ1) { | 362 | + else if (value == NAND_CMD_READ1) { |
| 362 | s->offset = 0x100; | 363 | s->offset = 0x100; |
| 363 | value = NAND_CMD_READ0; | 364 | value = NAND_CMD_READ0; |
| 364 | } | 365 | } |
| 365 | - else if (value == NAND_CMD_READ2) { | 366 | + else if (value == NAND_CMD_READ2) { |
| 366 | s->offset = 1 << s->page_shift; | 367 | s->offset = 1 << s->page_shift; |
| 367 | value = NAND_CMD_READ0; | 368 | value = NAND_CMD_READ0; |
| 368 | } | 369 | } |
| @@ -370,12 +371,12 @@ void nand_setio(NANDFlashState *s, uint8_t value) | @@ -370,12 +371,12 @@ void nand_setio(NANDFlashState *s, uint8_t value) | ||
| 370 | s->cmd = value; | 371 | s->cmd = value; |
| 371 | 372 | ||
| 372 | if (s->cmd == NAND_CMD_READSTATUS || | 373 | if (s->cmd == NAND_CMD_READSTATUS || |
| 373 | - s->cmd == NAND_CMD_PAGEPROGRAM2 || | ||
| 374 | - s->cmd == NAND_CMD_BLOCKERASE1 || | ||
| 375 | - s->cmd == NAND_CMD_BLOCKERASE2 || | ||
| 376 | - s->cmd == NAND_CMD_NOSERIALREAD2 || | ||
| 377 | - s->cmd == NAND_CMD_RANDOMREAD2 || | ||
| 378 | - s->cmd == NAND_CMD_RESET) | 374 | + s->cmd == NAND_CMD_PAGEPROGRAM2 || |
| 375 | + s->cmd == NAND_CMD_BLOCKERASE1 || | ||
| 376 | + s->cmd == NAND_CMD_BLOCKERASE2 || | ||
| 377 | + s->cmd == NAND_CMD_NOSERIALREAD2 || | ||
| 378 | + s->cmd == NAND_CMD_RANDOMREAD2 || | ||
| 379 | + s->cmd == NAND_CMD_RESET) | ||
| 379 | nand_command(s); | 380 | nand_command(s); |
| 380 | 381 | ||
| 381 | if (s->cmd != NAND_CMD_RANDOMREAD2) { | 382 | if (s->cmd != NAND_CMD_RANDOMREAD2) { |
| @@ -392,14 +393,14 @@ void nand_setio(NANDFlashState *s, uint8_t value) | @@ -392,14 +393,14 @@ void nand_setio(NANDFlashState *s, uint8_t value) | ||
| 392 | nand_command(s); | 393 | nand_command(s); |
| 393 | 394 | ||
| 394 | if (!(nand_flash_ids[s->chip_id].options & NAND_SAMSUNG_LP) && | 395 | if (!(nand_flash_ids[s->chip_id].options & NAND_SAMSUNG_LP) && |
| 395 | - s->addrlen == 3 && ( | ||
| 396 | - s->cmd == NAND_CMD_READ0 || | ||
| 397 | - s->cmd == NAND_CMD_PAGEPROGRAM1)) | 396 | + s->addrlen == 3 && ( |
| 397 | + s->cmd == NAND_CMD_READ0 || | ||
| 398 | + s->cmd == NAND_CMD_PAGEPROGRAM1)) | ||
| 398 | nand_command(s); | 399 | nand_command(s); |
| 399 | if ((nand_flash_ids[s->chip_id].options & NAND_SAMSUNG_LP) && | 400 | if ((nand_flash_ids[s->chip_id].options & NAND_SAMSUNG_LP) && |
| 400 | - s->addrlen == 4 && ( | ||
| 401 | - s->cmd == NAND_CMD_READ0 || | ||
| 402 | - s->cmd == NAND_CMD_PAGEPROGRAM1)) | 401 | + s->addrlen == 4 && ( |
| 402 | + s->cmd == NAND_CMD_READ0 || | ||
| 403 | + s->cmd == NAND_CMD_PAGEPROGRAM1)) | ||
| 403 | nand_command(s); | 404 | nand_command(s); |
| 404 | } | 405 | } |
| 405 | 406 | ||
| @@ -408,7 +409,7 @@ void nand_setio(NANDFlashState *s, uint8_t value) | @@ -408,7 +409,7 @@ void nand_setio(NANDFlashState *s, uint8_t value) | ||
| 408 | s->io[s->iolen ++] = value; | 409 | s->io[s->iolen ++] = value; |
| 409 | } else if (!s->cle && !s->ale && s->cmd == NAND_CMD_COPYBACKPRG1) { | 410 | } else if (!s->cle && !s->ale && s->cmd == NAND_CMD_COPYBACKPRG1) { |
| 410 | if ((s->addr & ((1 << s->addr_shift) - 1)) < | 411 | if ((s->addr & ((1 << s->addr_shift) - 1)) < |
| 411 | - (1 << s->page_shift) + (1 << s->oob_shift)) { | 412 | + (1 << s->page_shift) + (1 << s->oob_shift)) { |
| 412 | s->io[s->iolen + (s->addr & ((1 << s->addr_shift) - 1))] = value; | 413 | s->io[s->iolen + (s->addr & ((1 << s->addr_shift) - 1))] = value; |
| 413 | s->addr ++; | 414 | s->addr ++; |
| 414 | } | 415 | } |