nand: boot code cleanupdev-mini2440-stablemaster
authorMichel Pollet <buserror@gmail.com>
Thu, 13 Oct 2011 11:24:48 +0000 (13 12:24 +0100)
committerMichel Pollet <buserror@gmail.com>
Thu, 13 Oct 2011 11:24:48 +0000 (13 12:24 +0100)
Refactored the init phase added a MINI2440_BOOT=nor/nand environment
variable to act like the hardware switch in the real board, and added
a few warnings for when the image doesn't match what's needed.

Signed-off-by: Michel Pollet <buserror@gmail.com>
hw/mini2440.c
hw/nand.c
mini2440/mini2440_start.sh

index 780f4ff..40edb06 100644 (file)
@@ -35,6 +35,8 @@
 #define MINI2440_IRQ_nSD_DETECT                S3C_EINT(16)
 #define MINI2440_IRQ_DM9000                    S3C_EINT(7)
 
+#define FLASH_NOR_SIZE (2*1024*1024)
+
 #define BOOT_NONE      0
 #define BOOT_NOR       1
 #define BOOT_NAND      2
@@ -46,6 +48,7 @@ struct mini2440_board_s {
     const char * kernel;
     SDState * mmc;
     NANDFlashState *nand;
+    pflash_t * nor;
     int bl_level;
     int boot_mode;
 };
@@ -265,38 +268,38 @@ static void mini2440_reset(void *opaque)
 
     s->cpu->env->regs[15] = 0;
 
-    if (s->boot_mode == BOOT_NAND) {
-       /*
-        * Normally we would load 4 KB of nand to SRAM and jump there, but
-        * it is not working perfectly as expected, so we cheat and load
-        * it from nand directly relocated to 0x33f80000 and jump there
-        */
-       if (mini2440_load_from_nand(s->nand, 0, S3C_RAM_BASE | 0x03f80000, 256*1024)> 0) {
-               mini2440_printf("loaded default u-boot from NAND\n");
-               s->cpu->env->regs[15] = S3C_RAM_BASE | 0x03f80000; /* start address, u-boot already relocated */
-       }
+       if (s->boot_mode == BOOT_NAND) {
+               /*
+                * Normally we would load 4 KB of nand to SRAM and jump there, but
+                * it is not working perfectly as expected, so we cheat and load
+                * it from nand directly relocated to 0x33f80000 and jump there
+                */
+               if (mini2440_load_from_nand(s->nand, 0, S3C_RAM_BASE | 0x03f80000, 256*1024)> 0) {
+                       mini2440_printf("loaded default u-boot from NAND\n");
+                       s->cpu->env->regs[15] = S3C_RAM_BASE | 0x03f80000; /* start address, u-boot already relocated */
+               }
 #if 0 && defined(LATER)
-       if (mini2440_load_from_nand(s->nand, 0, S3C_SRAM_BASE_NANDBOOT, S3C_SRAM_SIZE) > 0) {
-           s->cpu->env->regs[15] = S3C_SRAM_BASE_NANDBOOT;     /* start address, u-boot relocating code */
-           mini2440_printf("4KB SteppingStone loaded from NAND\n");
-       }
+               if (mini2440_load_from_nand(s->nand, 0, S3C_SRAM_BASE_NANDBOOT, S3C_SRAM_SIZE) > 0) {
+                       s->cpu->env->regs[15] = S3C_SRAM_BASE_NANDBOOT; /* start address, u-boot relocating code */
+                       mini2440_printf("4KB SteppingStone loaded from NAND\n");
+               }
 #endif
 
-       /*
-        * if a u--boot is available as a file, we always use it
-        */
-       {
-           image_size = load_image("mini2440/u-boot.bin", qemu_get_ram_ptr(0x03f80000));
-           if (image_size < 0)
-                   image_size = load_image("u-boot.bin", qemu_get_ram_ptr(0x03f80000));
-               if (image_size > 0) {
-                       if (image_size & (512 -1))      /* round size to a NAND block size */
-                               image_size = (image_size + 512) & ~(512-1);
-                       mini2440_printf("loaded override u-boot (size %x)\n", image_size);
-                   s->cpu->env->regs[15] = S3C_RAM_BASE | 0x03f80000;  /* start address, u-boot already relocated */
-               }
+               /*
+                * if a u--boot is available as a file, we always use it
+                */
+               {
+                       image_size = load_image("mini2440/u-boot.bin", qemu_get_ram_ptr(0x03f80000));
+                       if (image_size < 0)
+                               image_size = load_image("u-boot.bin", qemu_get_ram_ptr(0x03f80000));
+                       if (image_size > 0) {
+                               if (image_size & (512 -1))      /* round size to a NAND block size */
+                                       image_size = (image_size + 512) & ~(512-1);
+                               mini2440_printf("loaded override u-boot (size %x)\n", image_size);
+                               s->cpu->env->regs[15] = S3C_RAM_BASE | 0x03f80000;      /* start address, u-boot already relocated */
+                       }
+               }
        }
-    }
        /*
         * if a kernel was explicitly specified, we load it too
         */
@@ -317,40 +320,90 @@ static const int mini2440_ts_scale[6] = {
     (940 - 75) * 256 / 1021, 0, 75 * 256 * 32,
 };
 
-/* Board init.  */
-static struct mini2440_board_s *mini2440_init_common(struct mini2440_board_s *s,
-               int ram_size,
-                const char *kernel_filename, const char *cpu_model,
-                SDState *mmc)
+static void
+mini2440_init(
+               ram_addr_t ram_size,
+               const char *boot_device,
+               const char *kernel_filename,
+               const char *kernel_cmdline,
+               const char *initrd_filename,
+               const char *cpu_model)
 {
-    uint32_t sram_base;
+    struct mini2440_board_s *mini =
+               (struct mini2440_board_s *)qemu_mallocz(sizeof(struct mini2440_board_s));
+    int sd_idx = drive_get_index(IF_SD, 0, 0);
+    int nor_idx = drive_get_index(IF_PFLASH, 0, 0);
+    int nand_idx = drive_get_index(IF_MTD, 0, 0);
+    int nand_cid = 0x76;               // 128MB flash == 0xf1
 
-    s->ram = 0x04000000;
-    s->kernel = kernel_filename;
-    s->mmc = mmc;
+    mini->ram = 0x04000000;
+    mini->kernel = kernel_filename;
+    mini->mmc = sd_idx >= 0 ? sd_init(drives_table[sd_idx].bdrv, 0) : NULL;
+    mini->boot_mode = BOOT_NAND;
 
-    /* Setup CPU & memory */
-    if (ram_size < s->ram + S3C_SRAM_SIZE) {
-       mini2440_printf("This platform requires %i bytes of memory (not %d)\n",
-                        s->ram + S3C_SRAM_SIZE, ram_size);
-        exit(1);
-    }
     if (cpu_model && strcmp(cpu_model, "arm920t")) {
        mini2440_printf("This platform requires an ARM920T core\n");
         exit(2);
     }
 
-    if (s->boot_mode == BOOT_NOR)
-           sram_base = S3C_SRAM_BASE_NORBOOT;
-    else
-           sram_base = S3C_SRAM_BASE_NANDBOOT;
+    uint32_t sram_base = 0;
+    /*
+     * Use an environment variable to set the boot mode "switch"
+     */
+    const char * boot_mode = getenv("MINI2440_BOOT");
+
+    if (boot_mode) {
+       if (!strcasecmp(boot_mode, "nor")) {
+               if (nor_idx < 0) {
+                       printf("%s MINI2440_BOOT(nor) error, no flash file specified", __func__);
+                       abort();
+               } else
+                   mini->boot_mode = BOOT_NOR;
+       } else if (!strcasecmp(boot_mode, "nand")) {
+               if (nor_idx < 0) {
+                       printf("%s MINI2440_BOOT(nand) error, no flash file specified", __func__);
+                       abort();
+               } else
+                   mini->boot_mode = BOOT_NOR;
+       } else
+                       printf("%s MINI2440_BOOT(%s) ignored, invalid value", __func__, boot_mode);
+    }
+    printf("%s: Boot mode: %s\n", __func__, mini->boot_mode == BOOT_NOR ? "NOR": "NAND");
+    /* Check the boot mode */
+    switch (mini->boot_mode) {
+       case BOOT_NAND:
+           sram_base = S3C_SRAM_BASE_NANDBOOT;
+           int size = bdrv_getlength(drives_table[nand_idx].bdrv);
+           switch (size) {
+               case 2 * 65536 * (512 + 16):
+                                       nand_cid = 0x76;
+                       break;
+               case 4 * 65536 * (512 + 16):
+                       nand_cid = 0xf1;
+                                       break;
+               default:
+                       printf("%s: Unknown NAND size/id %d (%dMB) defaulting to old 64MB\n",
+                                       __func__, size, ((size / (512 + 16)) * 512) / 1024 / 1024);
+                       break;
+           }
+           break;
+       case BOOT_NOR: {
+           sram_base = S3C_SRAM_BASE_NORBOOT;
+           int nor_size = bdrv_getlength(drives_table[nor_idx].bdrv);
+           if (nor_size > FLASH_NOR_SIZE)
+                   printf("%s: file too big (2MBytes)\n", __func__);
+           printf("%s: Register parallel flash %d size 0x%x '%s'\n", __func__,
+                           nor_idx, nor_size,
+                           bdrv_get_device_name(drives_table[nor_idx].bdrv));
+       }       break;
+    }
 
-    s->cpu = s3c24xx_init(S3C_CPU_2440, 12000000 /* 12 mhz */, s->ram, sram_base, s->mmc);
+    mini->cpu = s3c24xx_init(S3C_CPU_2440, 12000000 /* 12 mhz */, mini->ram, sram_base, mini->mmc);
 
     /* Setup peripherals */
-    mini2440_gpio_setup(s);
+    mini2440_gpio_setup(mini);
 
-       s->eeprom = ee24c08_init(s3c_i2c_bus(s->cpu->i2c));
+       mini->eeprom = ee24c08_init(s3c_i2c_bus(mini->cpu->i2c));
 
        {
                NICInfo* nd;
@@ -358,73 +411,28 @@ static struct mini2440_board_s *mini2440_init_common(struct mini2440_board_s *s,
                if (!nd->model)
                    nd->model = "dm9000";
                if (strcmp(nd->model, "dm9000") == 0) {
-                       dm9000_init(nd, 0x20000000, 0x300, 0x304, s3c_gpio_in_get(s->cpu->io)[MINI2440_IRQ_DM9000]);
+                       dm9000_init(nd, 0x20000000, 0x300, 0x304, s3c_gpio_in_get(mini->cpu->io)[MINI2440_IRQ_DM9000]);
                }
        }
 
-    s3c_adc_setscale(s->cpu->adc, mini2440_ts_scale);
+    s3c_adc_setscale(mini->cpu->adc, mini2440_ts_scale);
 
     /* Setup initial (reset) machine state */
-    qemu_register_reset(mini2440_reset, s);
+    qemu_register_reset(mini2440_reset, mini);
 
-    return s;
-}
-
-#define FLASH_NOR_SIZE (2*1024*1024)
-
-static void mini2440_init(ram_addr_t ram_size,
-        const char *boot_device,
-        const char *kernel_filename,
-        const char *kernel_cmdline,
-        const char *initrd_filename,
-        const char *cpu_model)
-{
-    struct mini2440_board_s *mini = (struct mini2440_board_s *)
-            qemu_mallocz(sizeof(struct mini2440_board_s));
-    int sd_idx = drive_get_index(IF_SD, 0, 0);
-    int nor_idx = drive_get_index(IF_PFLASH, 0, 0);
-    int nand_idx = drive_get_index(IF_MTD, 0, 0);
-    SDState *sd = 0;
-    ram_addr_t phys_flash;
-
-    /* Check the boot mode */
-    if (nand_idx == 0)
-           mini->boot_mode = BOOT_NAND;
-    if (nor_idx == 0)
-           mini->boot_mode = BOOT_NOR;
-
-    printf("Boot mode: %s\n", mini->boot_mode == BOOT_NOR ? "NOR": "NAND");
-
-    /* Flash NOR init */
-    if (mini->boot_mode == BOOT_NOR) {
-
-           int nor_size = bdrv_getlength(drives_table[nor_idx].bdrv);
-           if (nor_size > FLASH_NOR_SIZE)
-                   printf("file too big (2MBytes)\n");
-           printf("Register parallel flash %d size 0x%x '%s'\n",
-                           nor_idx, nor_size,
-                           bdrv_get_device_name(drives_table[nor_idx].bdrv));
-
-
-
-           phys_flash = qemu_ram_alloc(FLASH_NOR_SIZE);
-           pflash_cfi02_register(0, phys_flash,
-                           nor_idx != -1 ? drives_table[nor_idx].bdrv : NULL, (64 * 1024),
-                           FLASH_NOR_SIZE >> 16,
-                           1, 2, 0x0000, 0x0000, 0x0000, 0x0000,
-                           0x555, 0x2aa);
-    }
-
-    /* SD init */
-    if (sd_idx >= 0)
-        sd = sd_init(drives_table[sd_idx].bdrv, 0);
-
-    mini = mini2440_init_common(mini, ram_size,
-                    kernel_filename, cpu_model, sd);
-
-    mini->nand = nand_init(NAND_MFR_SAMSUNG, 0x76);
+       // Original 64MB NAND (obsolete part)
+ //   mini->nand = nand_init(NAND_MFR_SAMSUNG, 0x76);
+       // 128MB nand -- the hardware can also have 256, 1GB parts
+    mini->nand = nand_init(NAND_MFR_SAMSUNG, nand_cid);
     mini->cpu->nand->reg(mini->cpu->nand, mini->nand);
 
+       mini->nor = pflash_cfi02_register(0, 
+               qemu_ram_alloc(FLASH_NOR_SIZE),
+               nor_idx != -1 ? drives_table[nor_idx].bdrv : NULL, (64 * 1024),
+               FLASH_NOR_SIZE >> 16,
+               1, 2, 0x0000, 0x0000, 0x0000, 0x0000,
+               0x555, 0x2aa);
+
     mini2440_reset(mini);
 }
 
index 0b084b4..c1e7acf 100644 (file)
--- a/hw/nand.c
+++ b/hw/nand.c
@@ -503,9 +503,12 @@ NANDFlashState *nand_init(int manf_id, int chip_id)
 
     if (!s->bdrv)
         pagesize += 1 << s->page_shift;
-    if (pagesize)
+    if (pagesize) {
+       printf("%s no/invalid block device, allocating %d*%d in ram\n",
+                       __func__, s->pages, pagesize);
         s->storage = (uint8_t *) memset(qemu_malloc(s->pages * pagesize),
                         0xff, s->pages * pagesize);
+    }
     /* Give s->ioaddr a sane value in case we save state before it
        is used.  */
     s->ioaddr = s->io;
index 6bff64c..4950455 100755 (executable)
@@ -1,27 +1,27 @@
 #!/bin/bash
+#
+# Run with script with 
+# -sd <SD card image file> to have a SD card loaded
+# -kernel <kernel uImage file> to have a kernel preloaded in RAM
+#
 
 base=$(dirname $0)
 
 echo Starting in $base
 
-name_nand="$base/mini2440_nand.bin"
-name_snapshots="$base/mini2440_snapshots.img"
+name_nand="$base/mini2440_nand128.bin"
 
 if [ ! -f "$name_nand" ]; then
        echo $0 : creating NAND empty image : "$name_nand"
-       dd if=/dev/zero of="$name_nand" bs=528 count=131072
+#      dd if=/dev/zero of="$name_nand" bs=528 count=131072
+       dd if=/dev/zero of="$name_nand" bs=2112 count=65536
+       echo "** NAND file created - make sure to 'nand scrub' in u-boot"
 fi
-if [ ! -f "$name_snapshots" ]; then
-       echo $0 : creating empty snapshot image : "$name_snapshots"
-       qemu-img create "$name_snapshots" 100MB
-fi
-
 
+#      -kernel /tftpboot/uImage
 cmd="$base/../arm-softmmu/qemu-system-arm \
        -M mini2440 $* \
-       -drive file=$name_snapshots,snapshot=on \
        -serial stdio \
-       -kernel /tftpboot/uImage \
        -mtdblock "$name_nand" \
        -show-cursor \
        -usb -usbdevice keyboard -usbdevice mouse \
@@ -29,8 +29,5 @@ cmd="$base/../arm-softmmu/qemu-system-arm \
        -net tap,vlan=0,ifname=tap0 \
        -monitor telnet::5555,server,nowait"
 
-# cmd="gdbserver :3333 $cmd"
-#      -monitor unix:.mini2440_monitor,server,nowait"
-
 echo $cmd
 $cmd