[U-Boot-Users] Where does U-Boot's CFI driver check for top/bottom boot?

Can someone point me to the code where the CFI driver checks if the flash is top-boot or bottom boot? The spec says that that information is in offset 1E of the Primary Vendor-Specific Extension Query Table, but I don't see any code that references that. Do I need to add an entry into flash.h for my part (29LV640BT)?

(Resending as original mail bounced by mail list)
Timur Tabi wrote:
Can someone point me to the code where the CFI driver checks if the flash is top-boot or bottom boot? The spec says that that information is in offset 1E of the Primary Vendor-Specific Extension Query Table, but I don't see any code that references that. Do I need to add an entry into flash.h for my part (29LV640BT)?
The code that you should be looking is flash_get_size(). Take a look at the section of code that reads 4 bytes at (FLASH_OFFSET_ERASE_REGIONS + i * 4) and after a computation sets erase_region_size. If you enable DEBUG in U-Boot you should see the debug output there which prints the size of each erase region. Can you do make clean and #define DEBUG and rebuilt and reflash debug build of u-boot. This should enable those debug output.
The current CFI driver is checking vendor specific extension query table. It is only working with standard CFI tables. Vendor specific tables can vary greatly from manufacturer to manufacturer and even from model to model for the same manufacturer. This table is not easily usable. I personally wouldn't want to add code looking to vendor specific tables unless there is no other means that we can find this information from the primary tables. For example, the top/bottom boot code is not available on Intel vendor specific table for top/bottom/uniform boot sector parts.
I just looked at the datasheet of your flash part as well as datasheet of a couple of intel flash parts as well as the current code. As I suspected for your particular part, it looks like they are using the same values for "Erase Bank Area 1" and "Erase Bank Area 2" irrespective of top boot or bottom boot flash. I think, this is fundamentally wrong and non-compliant with the general CFI standard.
I will look at some AMD part datasheets. If this is generally available on all AMD and AMD like parts, we can add it as a patch for AMD only. Otherwise, we will either add CONFIG_GEOMETRY_REVERSED definition or restrict a patch to specific vendor ids (and possibly part ids) which is then a pain to manage.
Best regards, Tolunay

Tolunay Orkun wrote:
I will look at some AMD part datasheets. If this is generally available on all AMD and AMD like parts, we can add it as a patch for AMD only.
I have found the AMD CFI specification at the following URL:
http://www.amd.com/us-en/assets/content_type/DownloadableAssets/cfi_r20.pdf
For completeness, Intel CFI specification is here:
http://www.intel.com/design/flcomp/applnots/292204.htm
Intel does not have top/bottom boot field. It is trivial to limit any code to AMD command set only. For AMD command sets, I see the Top/Bottom field is in Vendor Specific Tables for those flash parts that implement CFI Specification 1.1 or later. CFI Specification 1.0 does not support this.
However, the note from 1.1 table says if this field contains 0 for such devices and check device ID codes for Am29LV160 and Am29LV116 to determine top/bottom boot determination. I do not know if these are the only 2 devices that are CFI 1.0 compliant or there are more to handle differently.
Tolunay

Tolunay Orkun wrote:
Can you do make clean and #define DEBUG and rebuilt and reflash debug build of u-boot. This should enable those debug output.
Here's what I get:
FLASH: flash detect cfi fwc addr fe000000 cmd 0 0 8bit x 8 bit fwc addr fe000055 cmd 98 98 8bit x 8 bit is= cmd 51(Q) addr fe000010 is= 0 51 fwc addr fe000000 cmd 0 0000 16bit x 8 bit fwc addr fe0000aa cmd 98 9898 16bit x 8 bit is= cmd 51(Q) addr fe000020 is= 0051 5151 fwc addr fe000000 cmd 0 0000 16bit x 16 bit fwc addr fe0000aa cmd 98 0098 16bit x 16 bit is= cmd 51(Q) addr fe000020 is= 0051 0051 is= cmd 52(R) addr fe000022 is= 0052 0052 is= cmd 59(Y) addr fe000024 is= 0059 0059 ushort addr is at fe000050 info->portwidth = 2 addr[0] = 0x0 addr[1] = 0x2 addr[2] = 0x0 addr[3] = 0x0 retval = 0x2 device interface is 2 found port 2 chip 2 port 16 bits chip 16 bits ushort addr is at fe000026 info->portwidth = 2 addr[0] = 0x0 addr[1] = 0x2 addr[2] = 0x0 addr[3] = 0x0 retval = 0x2 fe000020 : 00 51 00 52 00 59 00 02 00 00 00 40 00 00 00 00 .Q.R.Y.....@.... fe000030 : 00 00 00 00 00 00 00 27 00 36 00 00 00 00 00 04 .......'.6...... fe000040 : 00 00 00 0a 00 00 00 05 00 00 00 04 00 00 00 17 ................ fe000050 : 00 02 00 00 00 00 00 00 00 02 00 07 00 00 00 20 ............... fe000060 : 00 00 00 7e 00 00 00 00 00 01 00 00 00 00 00 00 ...~............ fe000070 : 00 00 00 00 00 00 00 00 00 00 ff ff ff ff ff ff ................ fe000080 : 00 50 00 52 00 49 00 31 00 31 00 00 00 02 00 04 .P.R.I.1.1...... fe000090 : 00 01 00 04 00 00 00 00 00 00 00 b5 00 c5 00 03 ................ manufacturer is 2 size_ratio 1 port 16 bits chip 16 bits found 2 erase regions long addr is at fe00005a info->portwidth = 2 addr[0] = 0x0 addr[1] = 0x7 addr[2] = 0x0 addr[3] = 0x0 addr[4] = 0x0 addr[5] = 0x20 addr[6] = 0x0 addr[7] = 0x0 erase_region_count = 8 erase_region_size = 8192 long addr is at fe000062 info->portwidth = 2 addr[0] = 0x0 addr[1] = 0x7e addr[2] = 0x0 addr[3] = 0x0 addr[4] = 0x0 addr[5] = 0x0 addr[6] = 0x0 addr[7] = 0x1 erase_region_count = 127 erase_region_size = 65536 ushort addr is at fe000054 info->portwidth = 2 addr[0] = 0x0 addr[1] = 0x0 addr[2] = 0x0 addr[3] = 0x0 retval = 0x0 fwc addr fe000000 cmd f0 00f0 16bit x 16 bit flash detect cfi fwc addr fe800000 cmd 0 0 8bit x 8 bit fwc addr fe800055 cmd 98 98 8bit x 8 bit is= cmd 51(Q) addr fe800010 is= 0 51 fwc addr fe800000 cmd 0 0000 16bit x 8 bit fwc addr fe8000aa cmd 98 9898 16bit x 8 bit is= cmd 51(Q) addr fe800020 is= 0051 5151 fwc addr fe800000 cmd 0 0000 16bit x 16 bit fwc addr fe8000aa cmd 98 0098 16bit x 16 bit is= cmd 51(Q) addr fe800020 is= 0051 0051 is= cmd 52(R) addr fe800022 is= 0052 0052 is= cmd 59(Y) addr fe800024 is= 0059 0059 ushort addr is at fe800050 info->portwidth = 2 addr[0] = 0x0 addr[1] = 0x2 addr[2] = 0x0 addr[3] = 0x0 retval = 0x2 device interface is 2 found port 2 chip 2 port 16 bits chip 16 bits ushort addr is at fe800026 info->portwidth = 2 addr[0] = 0x0 addr[1] = 0x2 addr[2] = 0x0 addr[3] = 0x0 retval = 0x2 fe800020 : 00 51 00 52 00 59 00 02 00 00 00 40 00 00 00 00 .Q.R.Y.....@.... fe800030 : 00 00 00 00 00 00 00 27 00 36 00 00 00 00 00 04 .......'.6...... fe800040 : 00 00 00 0a 00 00 00 05 00 00 00 04 00 00 00 17 ................ fe800050 : 00 02 00 00 00 00 00 00 00 02 00 07 00 00 00 20 ............... fe800060 : 00 00 00 7e 00 00 00 00 00 01 00 00 00 00 00 00 ...~............ fe800070 : 00 00 00 00 00 00 00 00 00 00 ff ff ff ff ff ff ................ fe800080 : 00 50 00 52 00 49 00 31 00 31 00 00 00 02 00 04 .P.R.I.1.1...... fe800090 : 00 01 00 04 00 00 00 00 00 00 00 b5 00 c5 00 03 ................ manufacturer is 2 size_ratio 1 port 16 bits chip 16 bits found 2 erase regions long addr is at fe80005a info->portwidth = 2 addr[0] = 0x0 addr[1] = 0x7 addr[2] = 0x0 addr[3] = 0x0 addr[4] = 0x0 addr[5] = 0x20 addr[6] = 0x0 addr[7] = 0x0 erase_region_count = 8 erase_region_size = 8192 long addr is at fe800062 info->portwidth = 2 addr[0] = 0x0 addr[1] = 0x7e addr[2] = 0x0 addr[3] = 0x0 addr[4] = 0x0 addr[5] = 0x0 addr[6] = 0x0 addr[7] = 0x1 erase_region_count = 127 erase_region_size = 65536 ushort addr is at fe800054 info->portwidth = 2 addr[0] = 0x0 addr[1] = 0x0 addr[2] = 0x0 addr[3] = 0x0 retval = 0x0 fwc addr fe800000 cmd f0 00f0 16bit x 16 bit 16 MB
I'm currently studying what all this means, but I figured I email it now anyway.
I will look at some AMD part datasheets. If this is generally available on all AMD and AMD like parts, we can add it as a patch for AMD only. Otherwise, we will either add CONFIG_GEOMETRY_REVERSED definition or restrict a patch to specific vendor ids (and possibly part ids) which is then a pain to manage.
I'd like to help with this endeavor, although I currently don't know a whole lot about flash programming.

Tolunay Orkun wrote:
I just looked at the datasheet of your flash part as well as datasheet of a couple of intel flash parts as well as the current code. As I suspected for your particular part, it looks like they are using the same values for "Erase Bank Area 1" and "Erase Bank Area 2" irrespective of top boot or bottom boot flash. I think, this is fundamentally wrong and non-compliant with the general CFI standard.
Using the PDF you specified, I see that my chip has a value of 03h for the "Top/Bottom Boot Sector Flag", at offset (P+F)h. That indicates a top-boot, which is correct (smaller sectors at the end of memory).
Why can't we just check this byte if we're on an AMD part, and adjust accordingly?
participants (2)
-
Timur Tabi
-
Tolunay Orkun