Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
13 years ago

sopc2dts: cfi-flash & usb isp1362-hcd

Hey nios2-community,

I want to update my kernel from version 2.6.35 to version 3.3, but i have some problems integrating cfi-flash and usb. I'm working with a custom board similar to the neek-board and IP-Cores from Altera (mostly). Furthermore i'm using the neat tool: sopc2dts, which is a great help, but i'm not sure if i made some mistakes regarding the configuration of the device-tree.

1) cfi-flash: Everytime i use flashcp or ioctls accessing the otp-register my system freezes. Nevertheless i can create a jffs2-filesystem on my older build and use that on my new build. So i can mount the jffs2 on kernel 3.3 and make everything with the files on it. The system just hangs when i access the flash directly over the flash-utilities and/or ioctls. (the ioctl is changing the mode of cfi-flash to MTD_OTP_FACTORY)

I generated my device-tree with sopc2dts and the configuration regarding the cfi-flash seems to be just right. This is the entry about cfi-flash:


cfi_flash: flash@0x4000000 {
            compatible = "ALTR,cfi_flash-9.0", "cfi-flash";
            reg = < 0x04000000 0x02000000 >;
            bank-width = < 2 >;
            device-width = < 1 >;
           # address-cells = < 1 >;
           # size-cells = < 1 >;
            Linux-Kernel@0 {
                reg = < 0x00000000 0x00800000 >;
            }; //end Linux-Kernel@0
            filesystem@1000000 {
                reg = < 0x01000000 0x01000000 >;
            }; //end filesystem@1000000
}; //end flash@0x4000000 (cfi_flash)
My kernel-configuration is:

-> MTD (x)

-> MTD_OF_PARTS (x)

-> CONFIG_MTD_CHAR (x)

-> MTD_BLOCK (x)

-> RAM/ROM/Flash chip drivers

-> MTD_CFI (x)

-> MTD_CFI_ADV_OPTIONS (x)

-> MTD_OTP (x)

-> MTD_CFI_INTELEXT (x)

-> Mapping drivers for chip access

-> CONFIG_MTD_PHYSMAP_OF (x)

-> BLK_DEV (x)

2) My USB-device isn't working anymore. It fails when checking the clkrdy signal at isp1362-hcd.c. This is really weird, because everything that was in the header-file nios2 in my older build is also in the device-tree. Here is the entry in my device-tree:


isp1362_usb_controller: usb@0xa80 {
            compatible = "nxp,isp1362-1.0", "nxp,usb-isp1362";
            reg = < 0x00000A80 0x00000008
                0x00000B28 0x00000001 >;
            interrupt-parent = < &cpu_linux >;
            interrupts = < 10 11 >;
}; //end usb@0xa80 (isp1362_usb_controller)
I just added "nxp,usb-isp1362" to the compatible string. I think this has to happen otherwise uClinux can't load any driver at all. Btw here is the code snippet from the clkrdy check in isp1362-hcd.c:


/* chip has been reset. First we need to see a clock */
t = jiffies + msecs_to_jiffies(timeout);
while (!clkrdy && time_before_eq(jiffies, t)) {
    spin_lock_irqsave(&isp1362_hcd->lock, flags);
    clkrdy = isp1362_read_reg16(isp1362_hcd, HCuPINT) & HCuPINT_CLKRDY;
    spin_unlock_irqrestore(&isp1362_hcd->lock, flags);
    if (!clkrdy)
        msleep(4);
}
spin_lock_irqsave(&isp1362_hcd->lock, flags);
isp1362_write_reg16(isp1362_hcd, HCuPINT, HCuPINT_CLKRDY);
spin_unlock_irqrestore(&isp1362_hcd->lock, flags);
if (!clkrdy) {
    pr_err("Clock not ready after %lums\n", timeout);
    ret = -ENODEV;
}
return ret;
What am I missing here? I guess something is wrong with my device-tree but I checked a lot of entries in your newslist. I don't know what could be wrong here, so any help would be great.

For information purpose I attached our sopcinfo file. Thanks in advance.

kind regards,

Tobias Biehl

1 Reply

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Hey guys,

    my cfi-flash is now working again :)

    I dont know why flashcp froze my system. I simply made a new kernel-configuration and now it works perfect. I guess I had messed up my config somewhere.

    Nevertheless accessing the otp-register from my cfi-flash was still causing a kernel-panic, Null Pointer reference in particular. I looked through the code and I stumbled on something. When I'm calling ioctl with OTPSELECT to change the mode, the function otp_select_filemode is called in mtdchar.c. There is a call to another function:

    
    /*
    * Make a fake call to mtd_read_fact_prot_reg() to check if OTP
    * operations are supported.
    */
    if (mtd_read_fact_prot_reg(mtd, -1, -1, &retlen, NULL) == -EOPNOTSUP     P)
            return -EOPNOTSUPP;
    
    I dont know if its really a bug, but thats the cause of my kernel-panic. the 3rd parameter is len with type size_t. size_t is defined to be __kernel_size_t which is defined as unsigned long. So this would cause an overflow of len. In read_fact_prot_reg() is another call to the function cfi_intelext_otp_walk, which does mostly all the work except the actual read from the otp-register. This does do_otp_read (action points to that function). The code-lines:

     
    while (len > 0) {
            /* flash geometry fixup */
            data_offset = reg_prot_offset + 1;
            data_offset *= cfi->interleave * cfi->device_type;
            reg_prot_offset *= cfi->interleave * cfi->device_type;
            reg_fact_size *= cfi->interleave;
            reg_user_size *= cfi->interleave;
            if (user_regs) {
                    groups = reg_user_groups;
                    groupsize = reg_user_size;
                    /* skip over factory reg area */
                    groupno = reg_fact_groups;
                    data_offset += reg_fact_groups * reg_fact_size;
            } else {
                    groups = reg_fact_groups;
                    groupsize = reg_fact_size;
                    groupno = 0;
            }
            while (len > 0 && groups > 0) {
                    if (!action) {
                            
                    } else if (from >= groupsize) {
                            from -= groupsize;
                            data_offset += groupsize;
                    } else {
                            int size = groupsize;
                            data_offset += from;
                            size -= from;
                            from = 0;
                            if (size > len)
                                    size = len;
                            ret = action(map, chip, data_offset,
                                     buf, size, reg_prot_offset,
                                     groupno, groupsize);
                            if (ret < 0)
                                     return ret;
                            buf += size;
                            len -= size;
                            *retlen += size;
                            data_offset += size;
                    }
                    groupno++;
                    groups--;
            }
    
    well, len is positive, groups will be 1. from is actually -1, so else. And there is a call action() with our buf which is NULL. In there the function tries to copy data to that location -> kernel panic

    I solved this problem changing the 3rd parameter -1 to 0. I guess this was the idea afterall, that the function just checks if there are otp-register and not trying to read them.

    Maybe I wrote too much here, but now you guys can easily track down this one, if its really a bug. I guess it is, correct me if I'm wrong =)

    And my usb is still not working properly, so if anybody knows something there, i would appreciate it.

    kind regards,

    Tobias Biehl