1
\$\begingroup\$

Background:

I recently upgraded my 64 MB NOR flash on my PowerPC (P2020) embedded board to a 256 MB NOR flash. (The board has 2 GB of DDR RAM.) I had to decrease the page offset to provide enough room for VMALLOC of the the 256MB NOR, just like this:

https://community.freescale.com/message/438327#438327

Problem:

This allows me to see all 256 MB of the NOR from Linux-user space. (I've verified by writing in u-boot, rebooting, and reading from Linux-user.)

However, I can only erase the first 139 MB of 256 MB. Curiously, the virtual memory boundary where the erases begin to fail is close to 0xE0000000. (Maybe it's nothing.)

I have instrumented the kernel code (printk) and verified that the erase fails above 139MB, because the CFI driver does not read-back 0xFFFF as expected after erase.

Because I can read and write all of the NOR from u-boot, I suspect this is a software problem. Specifically, I fear it is some kind of Linux kernel-virtual memory layout issue, but I'm not sure what would allow me to read all of a memory region - but only write to part of the same region.

Question:

Is there any memory (high, low, virtual) configuration in the kernel that would explain this behavior, being able to read all 256 MB of NOR but only able to write to the first 139 MB? Since I've verified the hardware in u-boot, what other software issue should I consider, if not the kernel?

Thanks!

Boot Log:

FWIW, at boot, the kernel-virtual memory layout is reported as:

[    0.000000] Zone PFN ranges:
[    0.000000]   DMA      0x00000000 -> 0x00020000
[    0.000000]   Normal   0x00020000 -> 0x00020000
[    0.000000]   HighMem  0x00020000 -> 0x00080000
[    0.000000] Movable zone start PFN for each node
[    0.000000] early_node_map[1] active PFN ranges
[    0.000000]     0: 0x00000000 -> 0x00080000
[    0.000000] MMU: Allocated 1088 bytes of context maps for 255 contexts
[    0.000000] PERCPU: Embedded 7 pages/cpu @b1c0d000 s7688 r8192 d12792 u65536
[    0.000000] pcpu-alloc: s7688 r8192 d12792 u65536 alloc=16*4096
[    0.000000] pcpu-alloc: [0] 0 [0] 1 
[    0.000000] Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 520192
...
[    0.000000] PID hash table entries: 2048 (order: 1, 8192 bytes)
[    0.000000] Dentry cache hash table entries: 65536 (order: 6, 262144 bytes)
[    0.000000] Inode-cache hash table entries: 32768 (order: 5, 131072 bytes)
[    0.000000] Memory: 2072548k/2097152k available (6360k kernel code, 23728k reserved, 252k data, 151k bss, 232k init)
[    0.000000] Kernel virtual memory layout:
[    0.000000]   * 0xfffe0000..0xfffff000  : fixmap
[    0.000000]   * 0xff800000..0xffc00000  : highmem PTEs
[    0.000000]   * 0xff7fe000..0xff800000  : early ioremap
[    0.000000]   * 0xd1000000..0xff7fe000  : vmalloc & ioremap
[    0.000000] SLUB: Genslabs=13, HWalign=32, Order=0-3, MinObjects=0, CPUs=2, Nodes=1
...
[ 1546.968602] e0000000.nor: Found 1 x16 devices at 0x0 in 16-bit bank
[ 1546.974874]  Amd/Fujitsu Extended Query Table at 0x0040
[ 1546.980463] Using buffer write method
[ 1546.984122] e0000000.nor: CFI does not contain boot bank location. Assuming top.
[ 1546.991518] number of CFI chips: 1
[ 1546.994912] cfi_cmdset_0002: Disabling erase-suspend-program due to code brokenness.
[ 1547.002680] Searching for RedBoot partition table in e0000000.nor at offset 0xffe0000
[ 1547.133862] No RedBoot partition table detected in e0000000.nor
[ 1547.139807] Creating 8 MTD partitions on "e0000000.nor":
[ 1547.145120] 0x000000000000-0x000002700000 : "NOR Partition 1"
[ 1547.153078] mtd: Giving out device 0 to NOR Partition 1
[ 1547.160343] 0x000002700000-0x000002800000 : "NOR Partition 2"
[ 1547.167177] mtd: Giving out device 1 to NOR Partition 2
[ 1547.173324] 0x000002800000-0x000003300000 : "NOR Partition 3"
[ 1547.181109] mtd: Giving out device 2 to NOR Partition 3
[ 1547.188201] 0x00000f300000-0x00000fe00000 : "NOR Partition 4"
[ 1547.195743] mtd: Giving out device 3 to NOR Partition 4
[ 1547.202574] 0x00000fe00000-0x00000ff40000 : "NOR Partition 5"
[ 1547.209759] mtd: Giving out device 4 to NOR Partition 5
[ 1547.216244] 0x00000ff40000-0x00000ff60000 : "NOR Partition 6 - DTB"
[ 1547.223602] mtd: Giving out device 5 to NOR Partition 6 - DTB
[ 1547.230273] 0x00000ff60000-0x00000ff80000 : "NOR Partition 7 - ENV"
[ 1547.238674] mtd: Giving out device 6 to NOR Partition 7 - ENV
[ 1547.246405] 0x00000ff80000-0x000010000000 : "NOR Partition 8 - u-boot"
[ 1547.254371] mtd: Giving out device 7 to NOR Partition 8 - u-boot
\$\endgroup\$

closed as off-topic by Scott Seidman, nidhin, Chetan Bhargava, stanri, PeterJ Feb 12 '15 at 21:43

This question appears to be off-topic. The users who voted to close gave this specific reason:

  • "Questions on the use of electronic devices are off-topic as this site is intended specifically for questions on electronics design." – Scott Seidman, nidhin, Chetan Bhargava, stanri, PeterJ
If this question can be reworded to fit the rules in the help center, please edit the question.

  • \$\begingroup\$ This is off topic as it is a software question, not hardware (question about the Linux kernel/device driver). I also recall the same question before, probably on stackoverflow so I'm not suggesting to migrate the question. \$\endgroup\$ – DoxyLover Jan 26 '15 at 20:24
  • 1
    \$\begingroup\$ Yes, this was question was posted there, but it was closed as off-topic, because it was not software enough. Suggestions on where to move this? If it doesn't belong here, I don't know where it could belong. \$\endgroup\$ – Trevor Jan 27 '15 at 1:04
  • 1
    \$\begingroup\$ Frankly, I'd think it'd be better suited to SO. Since you say it works correctly in Uboot but not under Linux, it is clearly a software issue. I cannot say why it was closed there. \$\endgroup\$ – DoxyLover Jan 27 '15 at 7:58
  • \$\begingroup\$ I'd say it belongs here: unix.stackexchange.com \$\endgroup\$ – stanri Feb 9 '15 at 7:03
  • \$\begingroup\$ As this concerns hardware interface it is perfectly appropriate here. U-boot working means the hardware probably isn't (too) broken, but developing hardware-aware drivers for a different environment is still a fitting role here. And no, the generic unix/linux site is not a fit. \$\endgroup\$ – Chris Stratton Feb 9 '15 at 16:45
0
\$\begingroup\$

Specify Chip Range in Device Tree:

New to me ... Apparently, it is possible to include multiple chips in the same package, each having its own unique control address. The Linux CFI cmdset-2 driver is already equipped to handle this, but the "number of chips" and their range has to be provided either in the board file or in the device tree, like so:

....
localbus@ffe05000 {
    #address-cells = <2>;
    #size-cells = <1>;
    compatible = "fsl,p2020-elbc", "fsl,elbc", "simple-bus";
    reg = <0 0xffe05000 0 0x1000>;
    interrupts = <19 2>;
    interrupt-parent = <&mpic>;

    /* NOR Flash */
    ranges = <0x0 0x0 0x0 0xE0000000 0x10000000>;

    nor@0,0 {
        #address-cells = <1>;
        #size-cells = <1>;
        compatible = "cfi-flash";
        /* 2 chips of 128MB = 256M total */
        reg = <0x0 0x00000000 0x08000000
               0x0 0x08000000 0x08000000>;
        bank-width = <2>;
        device-width = <1>;

        partition@0 {
            /* 39 MB for SquashFS Root File System - Image #1 */
            reg = <0x00000000 0x02700000>;
            label = "NOR (RO) SquashFS Root File System";
            /* read-only; */
        };
        ...

Notice that the NOR's entire range is subdivided into 2 separate register ranges. Modifying my device tree, like above, solved my problem.

Hope this helps someone else! :)

Kernel Docs:

See:

http://lxr.free-electrons.com/source/Documentation/devicetree/bindings/mtd/mtd-physmap.txt

Specifically:

http://lxr.free-electrons.com/source/Documentation/devicetree/bindings/mtd/mtd-physmap.txt#L9

and

http://lxr.free-electrons.com/source/Documentation/devicetree/bindings/mtd/mtd-physmap.txt#L62

\$\endgroup\$

Not the answer you're looking for? Browse other questions tagged or ask your own question.