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 | } |