Skip to contentSkip to conversation

Add flash emulation to the ARM Versatile PB platform

PATCH In review Thomas Petazzoni 4 participants 13 messages Oct 10, 2008

lore
Share & tools
lore
#0 lore raw

cover Add flash emulation to the ARM Versatile PB platform

Hi,

The following two patches add flash emulation to the ARM Versatile PB platform. Compared to the previous version of the patchset sent on October, 2nd, this version has the following changes :

- Drop the two patches that have been included in SVN ;

- In the write buffer increase patch, instead of changing the type of cmd from uint8_t to uint16_t, directly use value to set pfl->counter, since value is not 8 bits masked. Suggested by Andrzej Zaborowski ;

- Change the memory reservation scheme for the Versatile platform. Instead of hardcoding the RAM size, we use the .ram_require machine argument to reserve memory for the flash, and allow the user to define a custom RAM size using the -m option. Hopefully, this adresses Paul Brook's comment about this patch.

Thanks !

Thomas

Signature · 4 lines
Thomas Petazzoni, Free Electrons
Kernel, drivers and embedded Linux development,
consulting, training and support.
http://free-electrons.com
#1 lore raw

PATCH 1/2 Increase write buffer size in pflash emulation

The current flash emulation code advertises a write buffer size of 16 bytes (1 << 4, according to offset 0x2A of the CFI table). This is very small compared to normal write buffer sizes, and makes the process of writing to the flash very slow (at least from U-Boot).

This patch increases this size to 2048 bytes. Except the modification of the CFI table, the only other required modification is to use "value" instead of "cmd" to set pfl->counter, because cmd is truncated to the 8 lower bits of value, while the number of bytes for a write can now be greater than 255 bytes.

---
 hw/pflash_cfi01.c |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
hw/pflash_cfi01.c +3 -3
Index: qemu/hw/pflash_cfi01.c
===================================================================
@@ -276,8 +276,8 @@
 
             break;
         case 0xe8:
-            DPRINTF("%s: block write of %x bytes\n", __func__, cmd);
-            pfl->counter = cmd;
+            DPRINTF("%s: block write of %x bytes\n", __func__, value);
+            pfl->counter = value;
             pfl->wcycle++;
             break;
         case 0x60:
@@ -583,7 +583,7 @@
     pfl->cfi_table[0x28] = 0x02;
     pfl->cfi_table[0x29] = 0x00;
     /* Max number of bytes in multi-bytes write */
-    pfl->cfi_table[0x2A] = 0x04;
+    pfl->cfi_table[0x2A] = 0x0B;
     pfl->cfi_table[0x2B] = 0x00;
     /* Number of erase block regions (uniform) */
     pfl->cfi_table[0x2C] = 0x01;
Signature · 4 lines
Thomas Petazzoni, Free Electrons
Kernel, drivers and embedded Linux development,
consulting, training and support.
http://free-electrons.com
#2 lore raw

PATCH 2/2 Add Flash support to the Versatile PB platform

In reply to Thomas Petazzoni

This patch adds the emulation of the 64 MB Intel Flash present at address 0x34000000 on the ARM Versatile PB platform, with a 256 KB sector size. This flash emulation is enabled using the -pflash option. If not enabled, Qemu falls back to the traditionnal way of loading the kernel.

---
 hw/versatilepb.c |   43 ++++++++++++++++++++++++++++++++++++-------
 1 file changed, 36 insertions(+), 7 deletions(-)
hw/versatilepb.c +36 -7
Index: qemu/hw/versatilepb.c
===================================================================
@@ -15,6 +15,7 @@
 #include "sysemu.h"
 #include "pci.h"
 #include "boards.h"
+#include "flash.h"
 
 /* Primary interrupt controller.  */
 
@@ -159,6 +160,10 @@
 
 static struct arm_boot_info versatile_binfo;
 
+#define VERSATILE_FLASH_ADDR      0x34000000
+#define VERSATILE_FLASH_SIZE      (64 * 1024 * 1024)
+#define VERSATILE_FLASH_SECT_SIZE (256 * 1024)
+
 static void versatile_init(ram_addr_t ram_size, int vga_ram_size,
                      const char *boot_device, DisplayState *ds,
                      const char *kernel_filename, const char *kernel_cmdline,
@@ -174,6 +179,7 @@
     int n;
     int done_smc = 0;
     int index;
+    int hasflash = 0;
 
     if (!cpu_model)
         cpu_model = "arm926";
@@ -184,7 +190,8 @@
     }
     /* ??? RAM should repeat to fill physical memory space.  */
     /* SDRAM at address zero.  */
-    cpu_register_physical_memory(0, ram_size, IO_MEM_RAM);
+    cpu_register_physical_memory(0, ram_size,
+				 qemu_ram_alloc(ram_size) | IO_MEM_RAM);
 
     arm_sysctl_init(0x10000000, 0x41007004);
     pic = arm_pic_init_cpu(env);
@@ -249,6 +256,21 @@
     /* Add PL031 Real Time Clock. */
     pl031_init(0x101e8000,pic[10]);
 
+    index = drive_get_index(IF_PFLASH, 0, 0);
+    if (index != -1) {
+      if (!pflash_cfi01_register(VERSATILE_FLASH_ADDR,
+				 qemu_ram_alloc(VERSATILE_FLASH_SIZE),
+				 drives_table[index].bdrv,
+				 VERSATILE_FLASH_SECT_SIZE,
+				 VERSATILE_FLASH_SIZE / VERSATILE_FLASH_SECT_SIZE,
+				 4, 0, 0, 0, 0)) {
+	fprintf(stderr, "qemu: error registering flash memory.\n");
+	exit(1);
+      }
+
+      hasflash = 1;
+    }
+
     /* Memory map for Versatile/PB:  */
     /* 0x10000000 System registers.  */
     /* 0x10001000 PCI controller config registers.  */
@@ -285,12 +307,17 @@
     /*  0x101f3000 UART2.  */
     /* 0x101f4000 SSPI.  */
 
-    versatile_binfo.ram_size = ram_size;
-    versatile_binfo.kernel_filename = kernel_filename;
-    versatile_binfo.kernel_cmdline = kernel_cmdline;
-    versatile_binfo.initrd_filename = initrd_filename;
-    versatile_binfo.board_id = board_id;
-    arm_load_kernel(env, &versatile_binfo);
+    if (! hasflash) {
+      versatile_binfo.ram_size = ram_size;
+      versatile_binfo.kernel_filename = kernel_filename;
+      versatile_binfo.kernel_cmdline = kernel_cmdline;
+      versatile_binfo.initrd_filename = initrd_filename;
+      versatile_binfo.board_id = board_id;
+      arm_load_kernel(env, &versatile_binfo);
+    }
+    else {
+      env->regs[15] = 0x34000000;
+    }
 }
 
 static void vpb_init(ram_addr_t ram_size, int vga_ram_size,
@@ -321,6 +348,7 @@
     .init = vpb_init,
     .use_scsi = 1,
     .max_cpus = 1,
+    .ram_require = VERSATILE_FLASH_SIZE,
 };
 
 QEMUMachine versatileab_machine = {
@@ -329,4 +357,5 @@
     .init = vab_init,
     .use_scsi = 1,
     .max_cpus = 1,
+    .ram_require = VERSATILE_FLASH_SIZE,
 };
Signature · 4 lines
Thomas Petazzoni, Free Electrons
Kernel, drivers and embedded Linux development,
consulting, training and support.
http://free-electrons.com
#3 lore raw

Re: [Qemu-devel] [patch 2/2] Add Flash support to the Versatile PB platform

hw/versatilepb.c line 311

Quoted 2 lines
hw/versatilepb.c +2 -0
+    if (! hasflash) {
+      versatile_binfo.ram_size = ram_size;

This should be dependent on the presence of the -kernel option, not the absence of flash.

Paul

#4 lore raw

Re: [Qemu-devel] [patch 2/2] Add Flash support to the Versatile PB platform

Quoted 5 lines · Paul Brook

hw/versatilepb.c line 311

Quoted 2 lines
hw/versatilepb.c +2 -0
+    if (! hasflash) {
+      versatile_binfo.ram_size = ram_size;

This should be dependent on the presence of the -kernel option, not the absence of flash.

Yes, makes sense. How should it behave when neither -kernel nor -pflash are present ? Just display an error message and exit ?

Thanks a lot for your feedback,

Thomas

Signature · 4 lines
Thomas Petazzoni, Free Electrons
Kernel, drivers and embedded Linux development,
consulting, training and support.
http://free-electrons.com
#5 lore raw

Re: [Qemu-devel] [patch 2/2] Add Flash support to the Versatile PB platform

Quoted 11 lines · Thomas Petazzoni

Le Fri, 10 Oct 2008 14:02:17 +0100,

Quoted 5 lines · Paul Brook

hw/versatilepb.c line 311

Quoted 2 lines
hw/versatilepb.c +2 -0
+    if (! hasflash) {
+      versatile_binfo.ram_size = ram_size;

This should be dependent on the presence of the -kernel option, not the absence of flash.

Yes, makes sense. How should it behave when neither -kernel nor -pflash are present ? Just display an error message and exit ?

Yes.

Paul

#6 lore raw

Re: [Qemu-devel] [patch 2/2] Add Flash support to the Versatile PB platform

Quoted 4 lines · Paul Brook
Quoted 2 lines

Yes, makes sense. How should it behave when neither -kernel nor -pflash are present ? Just display an error message and exit ?

Yes.

The following patch implements this, except that the case where neither -kernel nor -pflash are present is already handled by vl.c:main(), so we don't bother handling it again in the machine-specific code.

Thanks a lot for your feedback !

Thomas

---

Add Flash support to the Versatile PB platform

This patch adds the emulation of the 64 MB Intel Flash present at address 0x34000000 on the ARM Versatile PB platform, with a 256 KB sector size. This flash emulation is enabled using the -pflash option.

If a -pflash option is present but no -kernel option has been specified, Qemu starts execution at the flash starting address. If a -kernel option has been specified together with a -pflash option, then Qemu normally boots from the kernel (but the flash is still emulated, of course).

The case where neither -kernel nor -pflash have been specified is already catched by the Qemu main function :

    if (!linux_boot && net_boot == 0 &&
        !machine->nodisk_ok && nb_drives_opt == 0)
        help(1);
---
 hw/versatilepb.c |   43 ++++++++++++++++++++++++++++++++++++-------
 1 file changed, 36 insertions(+), 7 deletions(-)
hw/versatilepb.c +36 -7
Index: qemu/hw/versatilepb.c
===================================================================
@@ -15,6 +15,7 @@
 #include "sysemu.h"
 #include "pci.h"
 #include "boards.h"
+#include "flash.h"
 
 /* Primary interrupt controller.  */
 
@@ -159,6 +160,10 @@
 
 static struct arm_boot_info versatile_binfo;
 
+#define VERSATILE_FLASH_ADDR      0x34000000
+#define VERSATILE_FLASH_SIZE      (64 * 1024 * 1024)
+#define VERSATILE_FLASH_SECT_SIZE (256 * 1024)
+
 static void versatile_init(ram_addr_t ram_size, int vga_ram_size,
                      const char *boot_device, DisplayState *ds,
                      const char *kernel_filename, const char *kernel_cmdline,
@@ -174,6 +179,7 @@
     int n;
     int done_smc = 0;
     int index;
+    int hasflash = 0;
 
     if (!cpu_model)
         cpu_model = "arm926";
@@ -184,7 +190,8 @@
     }
     /* ??? RAM should repeat to fill physical memory space.  */
     /* SDRAM at address zero.  */
-    cpu_register_physical_memory(0, ram_size, IO_MEM_RAM);
+    cpu_register_physical_memory(0, ram_size,
+				 qemu_ram_alloc(ram_size) | IO_MEM_RAM);
 
     arm_sysctl_init(0x10000000, 0x41007004);
     pic = arm_pic_init_cpu(env);
@@ -249,6 +256,21 @@
     /* Add PL031 Real Time Clock. */
     pl031_init(0x101e8000,pic[10]);
 
+    index = drive_get_index(IF_PFLASH, 0, 0);
+    if (index != -1) {
+      if (!pflash_cfi01_register(VERSATILE_FLASH_ADDR,
+				 qemu_ram_alloc(VERSATILE_FLASH_SIZE),
+				 drives_table[index].bdrv,
+				 VERSATILE_FLASH_SECT_SIZE,
+				 VERSATILE_FLASH_SIZE / VERSATILE_FLASH_SECT_SIZE,
+				 4, 0, 0, 0, 0)) {
+	fprintf(stderr, "qemu: error registering flash memory.\n");
+	exit(1);
+      }
+
+      hasflash = 1;
+    }
+
     /* Memory map for Versatile/PB:  */
     /* 0x10000000 System registers.  */
     /* 0x10001000 PCI controller config registers.  */
@@ -285,12 +307,17 @@
     /*  0x101f3000 UART2.  */
     /* 0x101f4000 SSPI.  */
 
-    versatile_binfo.ram_size = ram_size;
-    versatile_binfo.kernel_filename = kernel_filename;
-    versatile_binfo.kernel_cmdline = kernel_cmdline;
-    versatile_binfo.initrd_filename = initrd_filename;
-    versatile_binfo.board_id = board_id;
-    arm_load_kernel(env, &versatile_binfo);
+    if (kernel_filename) {
+      versatile_binfo.ram_size = ram_size;
+      versatile_binfo.kernel_filename = kernel_filename;
+      versatile_binfo.kernel_cmdline = kernel_cmdline;
+      versatile_binfo.initrd_filename = initrd_filename;
+      versatile_binfo.board_id = board_id;
+      arm_load_kernel(env, &versatile_binfo);
+    }
+    else if (hasflash) {
+      env->regs[15] = VERSATILE_FLASH_ADDR;
+    }
 }
 
 static void vpb_init(ram_addr_t ram_size, int vga_ram_size,
@@ -321,6 +348,7 @@
     .init = vpb_init,
     .use_scsi = 1,
     .max_cpus = 1,
+    .ram_require = VERSATILE_FLASH_SIZE,
 };
 
 QEMUMachine versatileab_machine = {
@@ -329,4 +357,5 @@
     .init = vab_init,
     .use_scsi = 1,
     .max_cpus = 1,
+    .ram_require = VERSATILE_FLASH_SIZE,
 };
Signature · 4 lines
Thomas Petazzoni, Free Electrons
Kernel, drivers and embedded Linux development,
consulting, training and support.
http://free-electrons.com
#7 lore raw
In reply to Thomas Petazzoni
Quoted 5 lines · Thomas Petazzoni

Hi,

The following two patches add flash emulation to the ARM Versatile PB platform. Compared to the previous version of the patchset sent on October, 2nd, this version has the following changes :

I suppose that if you propose such a change, you are using the flash with a bootloader in it. Could you please give us more details about it?

Signature · 4 lines
  .''`.  Aurelien Jarno	            | GPG: 1024D/F1BCDB73
 : :' :  Debian developer           | Electrical Engineer
 `. `'   [email protected]         | [email protected]
   `-    people.debian.org/~aurel32 | www.aurel32.net
#8 lore raw
Quoted 3 lines · Aurelien Jarno

I suppose that if you propose such a change, you are using the flash with a bootloader in it. Could you please give us more details about it?

Sure. With these patches in place, I'm able to boot U-Boot in Qemu, use TFTP to load a kernel, flash it, and boot it. I've detailed what I've done at http://thomas.enix.org/Blog-20081002153859-Technologie.

It works pretty well, except that I add to hack the CFG_HZ and timer configuration values in U-Boot to get some same network timeout values and such. Any help in this area would be appreciated.

If you want more details, I'll be glad to give them.

Sincerly,

Thomas

Signature · 4 lines
Thomas Petazzoni, Free Electrons
Kernel, drivers and embedded Linux development,
consulting, training and support.
http://free-electrons.com
#9 lore raw
Quoted 11 lines · Thomas Petazzoni
Quoted 3 lines · Aurelien Jarno

I suppose that if you propose such a change, you are using the flash with a bootloader in it. Could you please give us more details about it?

Sure. With these patches in place, I'm able to boot U-Boot in Qemu, use TFTP to load a kernel, flash it, and boot it. I've detailed what I've done at http://thomas.enix.org/Blog-20081002153859-Technologie.

Quoted 5 lines

It works pretty well, except that I add to hack the CFG_HZ and timer configuration values in U-Boot to get some same network timeout values and such. Any help in this area would be appreciated.

If you want more details, I'll be glad to give them.

I think I'll nice to add u-boot ML too and the ARM maintainer in copy maybe

Best Regards,
J.

#10 lore raw
Quoted 9 lines · Jean-Christophe PLAGNIOL-VILLARD
Quoted 9 lines
Quoted 3 lines

I suppose that if you propose such a change, you are using the flash with a bootloader in it. Could you please give us more details about it?

Sure. With these patches in place, I'm able to boot U-Boot in Qemu, use TFTP to load a kernel, flash it, and boot it. I've detailed what I've done at
http://thomas.enix.org/Blog-20081002153859-Technologie.

Quoted 7 lines
Quoted 5 lines

It works pretty well, except that I add to hack the CFG_HZ and timer configuration values in U-Boot to get some same network timeout values and such. Any help in this area would be appreciated.

If you want more details, I'll be glad to give them.

I think I'll nice to add u-boot ML too and the ARM maintainer in copy maybe

Yes, maybe I should contact the U-Boot people. To get U-Boot to work on the Versatile PB platform, I had to make several modifications to the U-Boot configuration :

* Switch to a custom versatile flash driver to the generic CFI driver. The custom versatile flash driver used by the default U-Boot versatile configuration doesn't play well with Qemu flash emulation for reasons that I haven't investigated.

At least one people in 2005 sent patches to convert U-Boot versatile to use the generic CFI flash driver, but it seems that the patches haven't been integrated:
http://lists.denx.de/pipermail/u-boot/2005-October/012334.html

I'd be glad to send the patch to the U-Boot people, but I couldn't test it on the hardware, so I'm not sure they work properly.

* Switch to an external phy for the ethernet adapter. This works on Qemu, but probably won't work on the real hardware. But again, I couldn't test this on the hardware, so I'm not sure about posting a patch that I haven't been able to test.

* Tune the CFG_HZ and CFG_TIMER_CTRL to get some sane timing behaviour. Here again, I wasn't able to test this on real hardware. And I don't even understand the new values, I just changed them until I found a combination that "worked".

Having a U-Boot configuration that works on Qemu would certainly be nice, but I'm not sure how to proceed with these three problems. Any hint maybe ?

Thanks !

Thomas

Signature · 4 lines
Thomas Petazzoni, Free Electrons
Kernel, drivers and embedded Linux development,
consulting, training and support.
http://free-electrons.com
#11 lore raw
Quoted 25 lines
Quoted 2 lines

I think I'll nice to add u-boot ML too and the ARM maintainer in copy maybe

Yes, maybe I should contact the U-Boot people. To get U-Boot to work on the Versatile PB platform, I had to make several modifications to the U-Boot configuration :

* Switch to a custom versatile flash driver to the generic CFI driver. The custom versatile flash driver used by the default U-Boot versatile configuration doesn't play well with Qemu flash emulation for reasons that I haven't investigated.

At least one people in 2005 sent patches to convert U-Boot versatile to use the generic CFI flash driver, but it seems that the patches haven't been integrated:
http://lists.denx.de/pipermail/u-boot/2005-October/012334.html

I'd be glad to send the patch to the U-Boot people, but I couldn't test it on the hardware, so I'm not sure they work properly.

* Switch to an external phy for the ethernet adapter. This works on Qemu, but probably won't work on the real hardware. But again, I couldn't test this on the hardware, so I'm not sure about posting a patch that I haven't been able to test.

Quoted 8 lines

* Tune the CFG_HZ and CFG_TIMER_CTRL to get some sane timing behaviour. Here again, I wasn't able to test this on real hardware. And I don't even understand the new values, I just changed them until I found a combination that "worked".

Having a U-Boot configuration that works on Qemu would certainly be nice, but I'm not sure how to proceed with these three problems. Any hint maybe ?

I think it's important to have an emulation that respect the hardware behavior specialy in this case where people could use also qemu to test U-Boot modification for this board and/or others as example to check other boards and/or others arch.

Best Regards,
J.

#12 lore raw

PATCH 1/1 Update documentation

In reply to Thomas Petazzoni
Quoted 3 lines · Thomas Petazzoni

The following two patches add flash emulation to the ARM Versatile PB platform. Compared to the previous version of the patchset sent on October, 2nd, this version has the following changes :

Another patch, which updates the documentation concerning flash emulation in the ARM Versatile platform.

If you want me to resend the complete patchset properly, just ask.

Sincerly,

Thomas

---

Mention flash emulation in Versatile documentation

In the Qemu documentation, mention the fact the flash emulation is available for the Versatile platform.

---
 qemu-doc.texi |    2 ++
 1 file changed, 2 insertions(+)
qemu-doc.texi +2 -0
Index: qemu/qemu-doc.texi
===================================================================
@@ -2528,6 +2528,8 @@
 @item
 PL190 Vectored Interrupt Controller
 @item
+Intel-compatible Flash memory (64 megabytes)
+@item
 Four PL011 UARTs
 @item
 SMC 91c111 Ethernet adapter
Signature · 4 lines
Thomas Petazzoni, Free Electrons
Kernel, drivers and embedded Linux development,
consulting, training and support.
http://free-electrons.com