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 | 56 | extern void at91_pdc_write(void *opaque, target_phys_addr_t offset, uint32_t val); |
| 57 | 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 | 62 | #endif /* !AT91_H */ | ... | ... |
hw/at91_nand.c
| 1 | 1 | #include <stdio.h> |
| 2 | 2 | |
| 3 | 3 | #include "hw.h" |
| 4 | +#include "flash.h" | |
| 4 | 5 | #include "at91.h" |
| 5 | 6 | |
| 6 | 7 | typedef struct NandState { |
| 7 | - unsigned int cmd; | |
| 8 | + NANDFlashState *nand_state; | |
| 8 | 9 | } NandState; |
| 9 | 10 | |
| 10 | -#define AT91_NAND_DEBUG | |
| 11 | +//#define AT91_NAND_DEBUG | |
| 11 | 12 | #ifdef AT91_NAND_DEBUG |
| 12 | 13 | #define DPRINTF(fmt, ...) \ |
| 13 | 14 | do { \ |
| ... | ... | @@ -23,23 +24,19 @@ static uint32_t at91_nand_mem_read(void *opaque, target_phys_addr_t offset) |
| 23 | 24 | { |
| 24 | 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 | 32 | static void at91_nand_mem_write(void *opaque, target_phys_addr_t offset, |
| 37 | 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 | 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 | 42 | static CPUReadMemoryFunc *at91_nand_readfn[] = { |
| ... | ... | @@ -54,12 +51,13 @@ static CPUWriteMemoryFunc *at91_nand_writefn[] = { |
| 54 | 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 | 56 | NandState *s; |
| 60 | 57 | int iomemtype; |
| 61 | 58 | |
| 62 | 59 | s = qemu_mallocz(sizeof(*s)); |
| 60 | + s->nand_state = st; | |
| 63 | 61 | iomemtype = cpu_register_io_memory(at91_nand_readfn, at91_nand_writefn, s); |
| 64 | 62 | cpu_register_physical_memory(0x40000000, 0x10000000, iomemtype); |
| 65 | 63 | } | ... | ... |
hw/at91_pdc.c
hw/at91sam9.c
| ... | ... | @@ -344,6 +344,8 @@ static void at91sam9_init(ram_addr_t ram_size, |
| 344 | 344 | dinfo = drive_get(IF_PFLASH, 0, 0); |
| 345 | 345 | if (dinfo) { |
| 346 | 346 | if (bms) { |
| 347 | + NANDFlashState *nand_state; | |
| 348 | + | |
| 347 | 349 | if (spi_flash_register(dinfo->bdrv, 4 * 1024 * 1024, cs0_spi_handler) < 0) { |
| 348 | 350 | fprintf(stderr, "init of spi flash failed\n"); |
| 349 | 351 | exit(EXIT_FAILURE); |
| ... | ... | @@ -352,7 +354,8 @@ static void at91sam9_init(ram_addr_t ram_size, |
| 352 | 354 | //rom |
| 353 | 355 | cpu_register_physical_memory(0x0, 100 * 1024, |
| 354 | 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 | 359 | } else { |
| 357 | 360 | //nor flash |
| 358 | 361 | ram_addr_t nor_flash_mem = qemu_ram_alloc(NOR_FLASH_SIZE); | ... | ... |
hw/nand.c
| ... | ... | @@ -39,7 +39,7 @@ |
| 39 | 39 | # define NAND_IOSTATUS_PLANE1 (1 << 2) |
| 40 | 40 | # define NAND_IOSTATUS_PLANE2 (1 << 3) |
| 41 | 41 | # define NAND_IOSTATUS_PLANE3 (1 << 4) |
| 42 | -# define NAND_IOSTATUS_BUSY (1 << 6) | |
| 42 | +# define NAND_IOSTATUS_READY (1 << 6) | |
| 43 | 43 | # define NAND_IOSTATUS_UNPROTCT (1 << 7) |
| 44 | 44 | |
| 45 | 45 | # define MAX_PAGE 0x800 |
| ... | ... | @@ -207,7 +207,8 @@ static void nand_reset(NANDFlashState *s) |
| 207 | 207 | s->addrlen = 0; |
| 208 | 208 | s->iolen = 0; |
| 209 | 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 | 214 | static void nand_command(NANDFlashState *s) |
| ... | ... | @@ -358,11 +359,11 @@ void nand_setio(NANDFlashState *s, uint8_t value) |
| 358 | 359 | } |
| 359 | 360 | if (value == NAND_CMD_READ0) |
| 360 | 361 | s->offset = 0; |
| 361 | - else if (value == NAND_CMD_READ1) { | |
| 362 | + else if (value == NAND_CMD_READ1) { | |
| 362 | 363 | s->offset = 0x100; |
| 363 | 364 | value = NAND_CMD_READ0; |
| 364 | 365 | } |
| 365 | - else if (value == NAND_CMD_READ2) { | |
| 366 | + else if (value == NAND_CMD_READ2) { | |
| 366 | 367 | s->offset = 1 << s->page_shift; |
| 367 | 368 | value = NAND_CMD_READ0; |
| 368 | 369 | } |
| ... | ... | @@ -370,12 +371,12 @@ void nand_setio(NANDFlashState *s, uint8_t value) |
| 370 | 371 | s->cmd = value; |
| 371 | 372 | |
| 372 | 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 | 380 | nand_command(s); |
| 380 | 381 | |
| 381 | 382 | if (s->cmd != NAND_CMD_RANDOMREAD2) { |
| ... | ... | @@ -392,14 +393,14 @@ void nand_setio(NANDFlashState *s, uint8_t value) |
| 392 | 393 | nand_command(s); |
| 393 | 394 | |
| 394 | 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 | 399 | nand_command(s); |
| 399 | 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 | 404 | nand_command(s); |
| 404 | 405 | } |
| 405 | 406 | |
| ... | ... | @@ -408,7 +409,7 @@ void nand_setio(NANDFlashState *s, uint8_t value) |
| 408 | 409 | s->io[s->iolen ++] = value; |
| 409 | 410 | } else if (!s->cle && !s->ale && s->cmd == NAND_CMD_COPYBACKPRG1) { |
| 410 | 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 | 413 | s->io[s->iolen + (s->addr & ((1 << s->addr_shift) - 1))] = value; |
| 413 | 414 | s->addr ++; |
| 414 | 415 | } | ... | ... |