[U-Boot-Users] Some RFCs about U-Boot's the generic FPGA support

Hi,
I am currently setting up a new board that will use U-Boot's generic FPGA support to boot zwi different Xilinx FPGA in slave serial mode. While grep'ing through the U-Boot board config files I noticed that nearly nobody uses this code.
I made a couple of changes to the code. Some of them changes the current behavior a little bit, so I like to request for comments before submitting a final patch.
Since nobody uses this code I see nothing that speaks against these changes:
1) Make the 'size' parameter obsolete for the 'fpga loadb' command. The actual bitstream size is taken from the bitstream.
2) Do not bit-swap the bytes in the xilinx bitstream. When using the slave serial code the bits may not be swapped. I can imagine that this swapping requirement comes from a special board layout. So is should be done in board specific code. When removing the swapping code, we can get rid of the complete malloc/free stuff in fpga_loadbitstream().
3) Fix a signed/unsigned issue in slave serial download code.
4) Make post() and pre() callback optional in relocation. So do not relocate NULL-pointers. This has been discussed a short time ago on the list.
5) Add a post() configuration callback for Spartan II devices in slave serial mode.
6) Add some more devices.
7) Minor typo fixes.
Any comments?
BTW: Are there any boards that use the FPGA stuff and that are not made public ?:-)
Matthias
diff --git a/common/cmd_fpga.c b/common/cmd_fpga.c index 3444091..2e1cf26 100644 --- a/common/cmd_fpga.c +++ b/common/cmd_fpga.c @@ -145,13 +145,14 @@ int fpga_loadbitstream(unsigned long dev dataptr+=4; printf(" bytes in bitstream = %d\n", swapsize);
- /* check consistency of length obtained */ - if (swapsize >= size) { + /* check consistency of length obtained when length parameter is non-0 */ + if (size && (swapsize >= size)) { printf("%s: Could not find right length of data in bitstream\n", __FUNCTION__); return FPGA_FAIL; }
+#if 0 /* mf test-only */ /* allocate memory */ swapdata = (unsigned char *)malloc(swapsize); if (swapdata == NULL) { @@ -178,6 +179,9 @@ int fpga_loadbitstream(unsigned long dev
rc = fpga_load(dev, swapdata, swapsize); free(swapdata); +#else + rc = fpga_load(dev, dataptr, swapsize); +#endif return rc; #else printf("Bitstream support only for Xilinx devices\n"); diff --git a/common/fpga.c b/common/fpga.c index 2eff239..2c231c2 100644 --- a/common/fpga.c +++ b/common/fpga.c @@ -112,11 +112,15 @@ static __attribute__((__const__)) fpga_d printf( "%s: Null buffer.\n", fn ); return (fpga_desc * const)NULL; } +#if 0 /* mf test-only + * bsize might be obsolete so do not check it. + * also bsize=3 is not better than 0 :-) + */ if ( !bsize ) { printf( "%s: Null buffer size.\n", fn ); return (fpga_desc * const)NULL; } - +#endif return desc; }
diff --git a/common/spartan2.c b/common/spartan2.c index 0fb23b6..bcb67ba 100644 --- a/common/spartan2.c +++ b/common/spartan2.c @@ -516,7 +516,7 @@ static int Spartan2_ss_load (Xilinx_desc (*fn->clk) (FALSE, TRUE, cookie); CONFIG_FPGA_DELAY (); /* Write data */ - (*fn->wr) ((val < 0), TRUE, cookie); + (*fn->wr) ((val & 0x80), TRUE, cookie); CONFIG_FPGA_DELAY (); /* Assert the clock */ (*fn->clk) (TRUE, TRUE, cookie); @@ -561,6 +561,13 @@ static int Spartan2_ss_load (Xilinx_desc } putc ('\n'); /* terminate the dotted line */
+ /* + * Run the post configuration function if there is one. + */ + if (*fn->post) { + (*fn->post) (cookie); + } + #ifdef CFG_FPGA_PROG_FEEDBACK if (ret_val == FPGA_SUCCESS) { puts ("Done.\n"); @@ -615,8 +622,10 @@ static int Spartan2_ss_reloc (Xilinx_des PRINTF ("%s: Relocating descriptor at 0x%p\n", __FUNCTION__, desc);
- addr = (ulong) (fn->pre) + reloc_offset; - fn_r->pre = (Xilinx_pre_fn) addr; + if (fn->pre) { + addr = (ulong) (fn->pre) + reloc_offset; + fn_r->pre = (Xilinx_pre_fn) addr; + }
addr = (ulong) (fn->pgm) + reloc_offset; fn_r->pgm = (Xilinx_pgm_fn) addr; @@ -633,6 +642,11 @@ static int Spartan2_ss_reloc (Xilinx_des addr = (ulong) (fn->wr) + reloc_offset; fn_r->wr = (Xilinx_wr_fn) addr;
+ if (fn->post) { + addr = (ulong) (fn->post) + reloc_offset; + fn_r->post = (Xilinx_post_fn) addr; + } + fn_r->relocated = TRUE;
} else { diff --git a/common/spartan3.c b/common/spartan3.c index c0f2b05..1435d1f 100644 --- a/common/spartan3.c +++ b/common/spartan3.c @@ -446,7 +446,7 @@ static int Spartan3_ss_load (Xilinx_desc int ret_val = FPGA_FAIL; /* assume the worst */ Xilinx_Spartan3_Slave_Serial_fns *fn = desc->iface_fns; int i; - char val; + char val;
PRINTF ("%s: start with interface functions @ 0x%p\n", __FUNCTION__, fn); @@ -521,7 +521,7 @@ static int Spartan3_ss_load (Xilinx_desc (*fn->clk) (FALSE, TRUE, cookie); CONFIG_FPGA_DELAY (); /* Write data */ - (*fn->wr) ((val < 0), TRUE, cookie); + (*fn->wr) ((val & 0x80), TRUE, cookie); CONFIG_FPGA_DELAY (); /* Assert the clock */ (*fn->clk) (TRUE, TRUE, cookie); @@ -566,6 +566,13 @@ static int Spartan3_ss_load (Xilinx_desc } putc ('\n'); /* terminate the dotted line */
+ /* + * Run the post configuration function if there is one. + */ + if (*fn->post) { + (*fn->post) (cookie); + } + #ifdef CFG_FPGA_PROG_FEEDBACK if (ret_val == FPGA_SUCCESS) { puts ("Done.\n"); @@ -620,8 +627,10 @@ static int Spartan3_ss_reloc (Xilinx_des PRINTF ("%s: Relocating descriptor at 0x%p\n", __FUNCTION__, desc);
- addr = (ulong) (fn->pre) + reloc_offset; - fn_r->pre = (Xilinx_pre_fn) addr; + if (fn->pre) { + addr = (ulong) (fn->pre) + reloc_offset; + fn_r->pre = (Xilinx_pre_fn) addr; + }
addr = (ulong) (fn->pgm) + reloc_offset; fn_r->pgm = (Xilinx_pgm_fn) addr; @@ -638,6 +647,11 @@ static int Spartan3_ss_reloc (Xilinx_des addr = (ulong) (fn->wr) + reloc_offset; fn_r->wr = (Xilinx_wr_fn) addr;
+ if (fn->post) { + addr = (ulong) (fn->post) + reloc_offset; + fn_r->post = (Xilinx_post_fn) addr; + } + fn_r->relocated = TRUE;
} else { diff --git a/include/spartan2.h b/include/spartan2.h index d2e81e3..bd159e1 100644 --- a/include/spartan2.h +++ b/include/spartan2.h @@ -58,6 +58,7 @@ typedef struct { Xilinx_init_fn init; Xilinx_done_fn done; Xilinx_wr_fn wr; + Xilinx_post_fn post; int relocated; } Xilinx_Spartan2_Slave_Serial_fns;
@@ -69,6 +70,7 @@ typedef struct { #define XILINX_XC2S50_SIZE 559232/8 #define XILINX_XC2S100_SIZE 781248/8 #define XILINX_XC2S150_SIZE 1040128/8 +#define XILINX_XC2S200_SIZE 1335872/8
/* Spartan-IIE (1.8V) */ #define XILINX_XC2S50E_SIZE 630048/8 @@ -95,6 +97,9 @@ typedef struct { #define XILINX_XC2S150_DESC(iface, fn_table, cookie) \ { Xilinx_Spartan2, iface, XILINX_XC2S150_SIZE, fn_table, cookie }
+#define XILINX_XC2S200_DESC(iface, fn_table, cookie) \ +{ Xilinx_Spartan2, iface, XILINX_XC2S200_SIZE, fn_table, cookie } + #define XILINX_XC2S50E_DESC(iface, fn_table, cookie) \ { Xilinx_Spartan2, iface, XILINX_XC2S50E_SIZE, fn_table, cookie }
diff --git a/include/spartan3.h b/include/spartan3.h index b14db03..95f62bc 100644 --- a/include/spartan3.h +++ b/include/spartan3.h @@ -58,6 +58,7 @@ typedef struct { Xilinx_init_fn init; Xilinx_done_fn done; Xilinx_wr_fn wr; + Xilinx_post_fn post; int relocated; } Xilinx_Spartan3_Slave_Serial_fns;
@@ -73,9 +74,12 @@ typedef struct { #define XILINX_XC3S4000_SIZE 11316864/8 #define XILINX_XC3S5000_SIZE 13271936/8
+/* Spartan-IIIE (1.2V) */ +#define XILINX_XC3S1200E_SIZE 3841184/8 + /* Descriptor Macros *********************************************************************/ -/* Spartan-II devices */ +/* Spartan-III devices */ #define XILINX_XC3S50_DESC(iface, fn_table, cookie) \ { Xilinx_Spartan3, iface, XILINX_XC3S50_SIZE, fn_table, cookie }
@@ -100,4 +104,9 @@ typedef struct { #define XILINX_XC3S5000_DESC(iface, fn_table, cookie) \ { Xilinx_Spartan3, iface, XILINX_XC3S5000E_SIZE, fn_table, cookie }
+ +/* Spartan-IIIE devices */ +#define XILINX_XC3S1200E_DESC(iface, fn_table, cookie) \ +{ Xilinx_Spartan3, iface, XILINX_XC3S1200E_SIZE, fn_table, cookie } + #endif /* _SPARTAN3_H_ */

Hi Matthias,
On Monday 20 August 2007 15:13, Matthias Fuchs wrote:
Hi,
I am currently setting up a new board that will use U-Boot's generic FPGA support to boot zwi different Xilinx FPGA in slave serial mode. While grep'ing through the U-Boot board config files I noticed that nearly nobody uses this code.
I made a couple of changes to the code. Some of them changes the current behavior a little bit, so I like to request for comments before submitting a final patch.
Since nobody uses this code I see nothing that speaks against these changes:
- Make the 'size' parameter obsolete for the 'fpga loadb' command.
The actual bitstream size is taken from the bitstream.
- Do not bit-swap the bytes in the xilinx bitstream. When using the
slave serial code the bits may not be swapped. I can imagine that this swapping requirement comes from a special board layout. So is should be done in board specific code. When removing the swapping code, we can get rid of the complete malloc/free stuff in fpga_loadbitstream().
Bit-swapping is required when dealing with .bit files. The Development System Reference Guide, Chapter 16 (PROMgen) states that:
"In a bitstream contained in a BIT file, the Least Significant Bit (LSB) is always on the left side of a byte. But when a PROM programmer or a microprocessor reads a data byte, it identifies the LSB on the right side of the byte. In order for the PROM programmer or microprocessor to read the bitstream correctly, the bits in each byte must first be swapped so they are read in the correct order."
Fix a signed/unsigned issue in slave serial download code.
Make post() and pre() callback optional in relocation. So do
not relocate NULL-pointers. This has been discussed a short time ago on the list.
Ack. I ran into the same issue and fixed the relocation issue, but found later that I actually needed pre() and post() methods, so I never submitted a patch.
- Add a post() configuration callback for Spartan II devices in slave
serial mode.
Add some more devices.
Minor typo fixes.
Any comments?
You should probably split your patch. Point 6 is a good candidate for a standalone patch.
BTW: Are there any boards that use the FPGA stuff and that are not made public ?:-)
Yes. I use slave-parallel loading with a Spartan-3E.
Best regards,

Hi Laurent,
On Monday 20 August 2007 15:47, Laurent Pinchart wrote:
Hi Matthias,
On Monday 20 August 2007 15:13, Matthias Fuchs wrote:
Hi,
I am currently setting up a new board that will use U-Boot's generic FPGA support to boot zwi different Xilinx FPGA in slave serial mode. While grep'ing through the U-Boot board config files I noticed that nearly nobody uses this code.
I made a couple of changes to the code. Some of them changes the current behavior a little bit, so I like to request for comments before submitting a final patch.
Since nobody uses this code I see nothing that speaks against these changes:
- Make the 'size' parameter obsolete for the 'fpga loadb' command.
The actual bitstream size is taken from the bitstream.
- Do not bit-swap the bytes in the xilinx bitstream. When using the
slave serial code the bits may not be swapped. I can imagine that this swapping requirement comes from a special board layout. So is should be done in board specific code. When removing the swapping code, we can get rid of the complete malloc/free stuff in fpga_loadbitstream().
Bit-swapping is required when dealing with .bit files. The Development System Reference Guide, Chapter 16 (PROMgen) states that:
"In a bitstream contained in a BIT file, the Least Significant Bit (LSB) is always on the left side of a byte. But when a PROM programmer or a microprocessor reads a data byte, it identifies the LSB on the right side of the byte. In order for the PROM programmer or microprocessor to read the bitstream correctly, the bits in each byte must first be swapped so they are read in the correct order."
Yes and no. The U-Boot FPGA sub system provides two ways to boot FPGAs: 'load' and 'loadb'. The first one takes the FPGA data stream and shifts it out left/MSBit first (slave serial mode). This works fine for me with bitgen generated .bit file.
The loadb option does nearly the same, but it also dumps information from the bitstream (creation date, size, device etc.), then it mirrors the bits and finally calls the same code as the load option. You are right, when you say that prom files (generated by xilinx' promgen) are bitwise mirrored against the .bit files, but they do not contain the bitstream information that is parsed by the loadb option. Without the swapping of bits I can use 'load' or 'loadb' with .bit files/images. I dare to say that 'loadb' will never programm prom files that are incompatible to .bit files.
So what option are you using for and which bitsteam format/file are you using?
I still vote for removing the bit mirror :-)
Fix a signed/unsigned issue in slave serial download code.
Make post() and pre() callback optional in relocation. So do
not relocate NULL-pointers. This has been discussed a short time ago on the list.
Ack. I ran into the same issue and fixed the relocation issue, but found later that I actually needed pre() and post() methods, so I never submitted a patch.
- Add a post() configuration callback for Spartan II devices in slave
serial mode.
Add some more devices.
Minor typo fixes.
Any comments?
You should probably split your patch. Point 6 is a good candidate for a standalone patch.
Of course. This was only for comments.
BTW: Are there any boards that use the FPGA stuff and that are not made public ?:-)
Yes. I use slave-parallel loading with a Spartan-3E.
Are you using .bit Images, PROM files and which fpga command option do you use? load or loadb?
Matthias

Hi Matthias,
On Monday 20 August 2007 17:46, Matthias Fuchs wrote:
Hi Laurent,
On Monday 20 August 2007 15:47, Laurent Pinchart wrote:
Hi Matthias,
On Monday 20 August 2007 15:13, Matthias Fuchs wrote:
Hi,
I am currently setting up a new board that will use U-Boot's generic FPGA support to boot zwi different Xilinx FPGA in slave serial mode. While grep'ing through the U-Boot board config files I noticed that nearly nobody uses this code.
I made a couple of changes to the code. Some of them changes the current behavior a little bit, so I like to request for comments before submitting a final patch.
Since nobody uses this code I see nothing that speaks against these changes:
- Make the 'size' parameter obsolete for the 'fpga loadb' command.
The actual bitstream size is taken from the bitstream.
- Do not bit-swap the bytes in the xilinx bitstream. When using the
slave serial code the bits may not be swapped. I can imagine that this swapping requirement comes from a special board layout. So is should be done in board specific code. When removing the swapping code, we can get rid of the complete malloc/free stuff in fpga_loadbitstream().
Bit-swapping is required when dealing with .bit files. The Development System Reference Guide, Chapter 16 (PROMgen) states that:
"In a bitstream contained in a BIT file, the Least Significant Bit (LSB) is always on the left side of a byte. But when a PROM programmer or a microprocessor reads a data byte, it identifies the LSB on the right side of the byte. In order for the PROM programmer or microprocessor to read the bitstream correctly, the bits in each byte must first be swapped so they are read in the correct order."
Yes and no. The U-Boot FPGA sub system provides two ways to boot FPGAs: 'load' and 'loadb'. The first one takes the FPGA data stream and shifts it out left/MSBit first (slave serial mode). This works fine for me with bitgen generated .bit file.
The loadb option does nearly the same, but it also dumps information from the bitstream (creation date, size, device etc.), then it mirrors the bits and finally calls the same code as the load option. You are right, when you say that prom files (generated by xilinx' promgen) are bitwise mirrored against the .bit files, but they do not contain the bitstream information that is parsed by the loadb option. Without the swapping of bits I can use 'load' or 'loadb' with .bit files/images. I dare to say that 'loadb' will never programm prom files that are incompatible to .bit files.
So what option are you using for and which bitsteam format/file are you using?
I'm calling fpga_load directly from board-specific code, using PROMgen generated data (with bit mirroring applied).
Bit mirroring might not be needed in slave serial mode, but is needed in slave parallel mode. Bytes in the .bit file are stored with the LSB on the left side. The bytes must then be reversed before being written in slave parallel mode, as the FPGA expects the LSB on D0, not on D7.
In slave serial mode, you can choose the shift direction, so mirroring is not required.
I still vote for removing the bit mirror :-)
Without mirroring, bitstreams won't load in slave parallel mode. You should keep mirroring, and change the slave serial code to shift bits the other way around.
Fix a signed/unsigned issue in slave serial download code.
Make post() and pre() callback optional in relocation. So do
not relocate NULL-pointers. This has been discussed a short time ago on the list.
Ack. I ran into the same issue and fixed the relocation issue, but found later that I actually needed pre() and post() methods, so I never submitted a patch.
- Add a post() configuration callback for Spartan II devices in slave
serial mode.
Add some more devices.
Minor typo fixes.
Any comments?
You should probably split your patch. Point 6 is a good candidate for a standalone patch.
Of course. This was only for comments.
BTW: Are there any boards that use the FPGA stuff and that are not made public ?:-)
Yes. I use slave-parallel loading with a Spartan-3E.
Are you using .bit Images, PROM files and which fpga command option do you use? load or loadb?
I don't use the fpga commands, but call fpga_load() directly from board specific code. This is roughly equivalent to "fpga load". The data come from a bit-mirrored PROM file. I used to use a .bit file, which required "fpga loadb" to be loaded correctly.

Laurent,
now things are getting clearer. All this sounds to me that the shift direction in slave serial mode is not compatible to the parallel download code. When we say that fpga_load (and the fpga load command) should only work for promgen files with mirrored bits and fpga_loadbitstream() (and the fpga loadb command) should be used for .bit files, I would like to get rid of the mirroring at least for slave serial mode because changing the shift order is much more efficient.
Bruce suggested a CONFIG option to turn on/off mirroring. This is not the right way. It should be handled by the FPGA subsystem. What about passing a bitorder flag down to the load functions? So we get rid of the huge malloc in loadbitstream and we can just swap bits in parallel mode just before writing it to the FPGA port. For Slave serial mode the _load funtion can use the correct shift direction and so swapping is needed.
Matthias
On Tuesday 21 August 2007 10:59, Laurent Pinchart wrote:
So what option are you using for and which bitsteam format/file are you using?
I'm calling fpga_load directly from board-specific code, using PROMgen generated data (with bit mirroring applied).
Bit mirroring might not be needed in slave serial mode, but is needed in slave parallel mode. Bytes in the .bit file are stored with the LSB on the left side. The bytes must then be reversed before being written in slave parallel mode, as the FPGA expects the LSB on D0, not on D7.
In slave serial mode, you can choose the shift direction, so mirroring is not required.
I still vote for removing the bit mirror :-)
Without mirroring, bitstreams won't load in slave parallel mode. You should keep mirroring, and change the slave serial code to shift bits the other way around.
Are you using .bit Images, PROM files and which fpga command option do you use? load or loadb?
I don't use the fpga commands, but call fpga_load() directly from board specific code. This is roughly equivalent to "fpga load". The data come from a bit-mirrored PROM file. I used to use a .bit file, which required "fpga loadb" to be loaded correctly.

On Tuesday 21 August 2007 12:46, Matthias Fuchs wrote:
Laurent,
now things are getting clearer. All this sounds to me that the shift direction in slave serial mode is not compatible to the parallel download code. When we say that fpga_load (and the fpga load command) should only work for promgen files with mirrored bits and fpga_loadbitstream() (and the fpga loadb command) should be used for .bit files, I would like to get rid of the mirroring at least for slave serial mode because changing the shift order is much more efficient.
If I understand things well, you would like to get rid of the bit mirroring code to optimize slave serial loading (where changing the shift direction has no performance impact).
Bruce suggested a CONFIG option to turn on/off mirroring. This is not the right way. It should be handled by the FPGA subsystem.
Agreed.
What about passing a bitorder flag down to the load functions? So we get rid of the huge malloc in loadbitstream and we can just swap bits in parallel mode just before writing it to the FPGA port.
Would it have an impact on slave parallel performances ? Mirroring each byte separately in the slave parallel code might slow things down. I personally don't use the bitstream mirroring code (I use PROM files, so the bitstream is mirrored on the host before loading it to the target flash memory), but it might affect other users.
For Slave serial mode the _load funtion can use the correct shift direction and so swapping is needed.
I suppose you mean "swapping is not needed", as the load function would choose the shift direction depending on the bitorder flag.
it seemed cleaner to me to handler mirroring at the high level, so lower-level layers wouldn't have to care about it. If you want to optimize performances, why don't you use a PROM file instead of a .bit file ?
Laurent Pinchart
On Tuesday 21 August 2007 10:59, Laurent Pinchart wrote:
So what option are you using for and which bitsteam format/file are you using?
I'm calling fpga_load directly from board-specific code, using PROMgen generated data (with bit mirroring applied).
Bit mirroring might not be needed in slave serial mode, but is needed in slave parallel mode. Bytes in the .bit file are stored with the LSB on the left side. The bytes must then be reversed before being written in slave parallel mode, as the FPGA expects the LSB on D0, not on D7.
In slave serial mode, you can choose the shift direction, so mirroring is not required.
I still vote for removing the bit mirror :-)
Without mirroring, bitstreams won't load in slave parallel mode. You should keep mirroring, and change the slave serial code to shift bits the other way around.
Are you using .bit Images, PROM files and which fpga command option do you use? load or loadb?
I don't use the fpga commands, but call fpga_load() directly from board specific code. This is roughly equivalent to "fpga load". The data come from a bit-mirrored PROM file. I used to use a .bit file, which required "fpga loadb" to be loaded correctly.

Laurent,
On Tuesday 21 August 2007 13:33, Laurent Pinchart wrote:
On Tuesday 21 August 2007 12:46, Matthias Fuchs wrote:
Laurent,
now things are getting clearer. All this sounds to me that the shift direction in slave serial mode is not compatible to the parallel download code. When we say that fpga_load (and the fpga load command) should only work for promgen files with mirrored bits and fpga_loadbitstream() (and the fpga loadb command) should be used for .bit files, I would like to get rid of the mirroring at least for slave serial mode because changing the shift order is much more efficient.
If I understand things well, you would like to get rid of the bit mirroring code to optimize slave serial loading (where changing the shift direction has no performance impact).
yes.
Bruce suggested a CONFIG option to turn on/off mirroring. This is not the right way. It should be handled by the FPGA subsystem.
Agreed.
What about passing a bitorder flag down to the load functions? So we get rid of the huge malloc in loadbitstream and we can just swap bits in parallel mode just before writing it to the FPGA port.
Would it have an impact on slave parallel performances ? Mirroring each byte separately in the slave parallel code might slow things down. I personally don't use the bitstream mirroring code (I use PROM files, so the bitstream is mirrored on the host before loading it to the target flash memory), but it might affect other users.
Well, there is only one public board that uses the FPGA code.
For Slave serial mode the _load funtion can use the correct shift direction and so swapping is needed.
I suppose you mean "swapping is not needed", as the load function would choose the shift direction depending on the bitorder flag.
yes, of course.
it seemed cleaner to me to handler mirroring at the high level, so lower-level layers wouldn't have to care about it. If you want to optimize performances, why don't you use a PROM file instead of a .bit file ?
We never used prom files before:-) And as you have noticed I was not aware of this mirroring issues before. I also do not want to miss the informational header of the .bit files.
In the end I will starting fixing the current implementation keeping the swapping in 'loadb' but this means that the shift direction of the serial slave functions must be changed.
Matthias

Bit mirroring might not be needed in slave serial mode, but is needed in slave parallel mode. Bytes in the .bit file are stored with the LSB on the
left
side. The bytes must then be reversed before being written in slave
parallel
mode, as the FPGA expects the LSB on D0, not on D7.
Again, it depends on the processor you are using and how it's hooked up to the FPGA. BTW, according to the Spartan 3 data sheet "data bit D0 is the MOST-significant (msb) bit and D7 is the least-significant bit (lsb)" (pg 167, Xilinx UG332 Spartan-3 Generation confiuration User Guide). Maybe you are refering to a different FPGA?
Without mirroring, bitstreams won't load in slave parallel mode. You
should
keep mirroring, and change the slave serial code to shift bits the other
way
around.
I must respectfully disagree. In my design, if I mirror in the code the FPGA does NOT load. In a PPC, D0 is the MSB, NOT the LSB. In a Spartan 3 FPGA, D0 is the MSB, NOT the LSB. Therefore if you connect your bus straight across between the PPC and the Spartan 3 FPGA, AND do mirroring in the code, your FPGA will not load.
Bruce

Hi Bruce,
On Tuesday 21 August 2007 22:09, Bruce_Leonard@selinc.com wrote:
Bit mirroring might not be needed in slave serial mode, but is needed in slave parallel mode. Bytes in the .bit file are stored with the LSB on the left side. The bytes must then be reversed before being written in slave parallel mode, as the FPGA expects the LSB on D0, not on D7.
Again, it depends on the processor you are using and how it's hooked up to the FPGA. BTW, according to the Spartan 3 data sheet "data bit D0 is the MOST-significant (msb) bit and D7 is the least-significant bit (lsb)" (pg 167, Xilinx UG332 Spartan-3 Generation confiuration User Guide). Maybe you are refering to a different FPGA?
Ok. You're right. The Spartan-3E datasheet (DS312) was silent about the bit ordering. UG322 sheds some light on the issue. D0-D7 are indeed MSB-LSB, making the SelectMAP interface use the big-endian PPC bit ordering convention.
Without mirroring, bitstreams won't load in slave parallel mode. You should keep mirroring, and change the slave serial code to shift bits the other way around.
I must respectfully disagree. In my design, if I mirror in the code the FPGA does NOT load. In a PPC, D0 is the MSB, NOT the LSB. In a Spartan 3 FPGA, D0 is the MSB, NOT the LSB. Therefore if you connect your bus straight across between the PPC and the Spartan 3 FPGA, AND do mirroring in the code, your FPGA will not load.
I got a similar design, except that D0-D7 on the PPC are connected to D7-D0 on the FPGA. I'll go scold our hardware engineer :-)
With a properly connected bus between the processor and the FPGA, bit reversal is thus not needed when loading a .bit file (fpga loadb) or a non mirrored PROM file (fpga load).
For hardware with bit mirroring on the bus, I suggest either using a mirrored PROM file or mirroring the bit in the data write callback. I thus vote for removing bit mirroring in fpga_loadbitstream() and adding an explanation of this issue (either in the code or in the documentation) to prevent hardware mistakes in future designs.
Best regards,

Hi Laurent,
you cannot imagine how many grey hair this bit naming and numbering convention cost me. I learned to never use D0/7 when meaning MSB/LSB:-)
On Wednesday 22 August 2007 09:28, Laurent Pinchart wrote:
I must respectfully disagree. In my design, if I mirror in the code the FPGA does NOT load. In a PPC, D0 is the MSB, NOT the LSB. In a Spartan 3 FPGA, D0 is the MSB, NOT the LSB. Therefore if you connect your bus straight across between the PPC and the Spartan 3 FPGA, AND do mirroring in the code, your FPGA will not load.
I got a similar design, except that D0-D7 on the PPC are connected to D7-D0 on the FPGA. I'll go scold our hardware engineer :-)
Sometimes it's even worth as softwa/orkers to review schematics when you know that you will get the board on your desk for writing software :-) (But do not sign anything or the hardware engineer will scold you afterwards.)
With a properly connected bus between the processor and the FPGA, bit reversal is thus not needed when loading a .bit file (fpga loadb) or a non mirrored PROM file (fpga load).
BTW, you can even load a .bit file using fpga load because the FPGA will discard the header.
For hardware with bit mirroring on the bus, I suggest either using a mirrored PROM file or mirroring the bit in the data write callback. I thus vote for
Ack
removing bit mirroring in fpga_loadbitstream() and adding an explanation of
Ack. So all the malloc and the timeconsuming loop code will disappear. Yippi!
this issue (either in the code or in the documentation) to prevent hardware mistakes in future designs.
Good idea. But do you think that hardware engineers will read through the cmd_fpga.c file?
I will cleanup my changes and submit a patch soon.
Matthias

Hi Matthias,
On Wednesday 22 August 2007 09:59, Matthias Fuchs wrote:
Hi Laurent,
you cannot imagine how many grey hair this bit naming and numbering convention cost me. I learned to never use D0/7 when meaning MSB/LSB:-)
On Wednesday 22 August 2007 09:28, Laurent Pinchart wrote:
I must respectfully disagree. In my design, if I mirror in the code the FPGA does NOT load. In a PPC, D0 is the MSB, NOT the LSB. In a Spartan 3 FPGA, D0 is the MSB, NOT the LSB. Therefore if you connect your bus straight across between the PPC and the Spartan 3 FPGA, AND do mirroring in the code, your FPGA will not load.
I got a similar design, except that D0-D7 on the PPC are connected to D7-D0 on the FPGA. I'll go scold our hardware engineer :-)
Sometimes it's even worth as softwa/orkers to review schematics when you know that you will get the board on your desk for writing software :-) (But do not sign anything or the hardware engineer will scold you afterwards.)
With a properly connected bus between the processor and the FPGA, bit reversal is thus not needed when loading a .bit file (fpga loadb) or a non mirrored PROM file (fpga load).
BTW, you can even load a .bit file using fpga load because the FPGA will discard the header.
Except when the bitstream start sequence is present in the header. "fpga load" with a .bit file shouldn't be adviced, especially if we remove the bit mirroring from fpga_loadbitstream.
For hardware with bit mirroring on the bus, I suggest either using a mirrored PROM file or mirroring the bit in the data write callback. I thus vote for
Ack
removing bit mirroring in fpga_loadbitstream() and adding an explanation of
Ack. So all the malloc and the timeconsuming loop code will disappear. Yippi!
this issue (either in the code or in the documentation) to prevent hardware mistakes in future designs.
Good idea. But do you think that hardware engineers will read through the cmd_fpga.c file?
Probably not, that's why a more visible place would be better.
I will cleanup my changes and submit a patch soon.
Best regards,

Matthias Fuchs matthias.fuchs@esd-electronics.com wrote on 08/22/2007 12:59:49 AM:
Sometimes it's even worth as softwa/orkers to review schematics when you
know that you will get the board on your desk for writing software :-) (But do not sign anything or the hardware engineer will scold you
afterwards.)
The advantage of being a HW engineer forced to do the devil's work of SW engineering is I get to catch these sorts of problems early. I'm heavily involved in the HW design of the products I then have to bring to life :).
Bruce

Hi Laurent,
Laurent Pinchart laurentp@cse-semaphore.com wrote on 08/22/2007 12:28:36 AM:
Hi Bruce,
ordering. UG322 sheds some light on the issue. D0-D7 are indeed MSB-LSB,
making the SelectMAP interface use the big-endian PPC bit ordering convention.
I'm with Matthaias, I've learned to refer to them as MSB/LSB on the list :). Avoids confusion.
to D7-D0 on the FPGA. I'll go scold our hardware engineer :-)
Don't scold him to hard. It's an easy mistake to make especially if you're used to everything being little endian. (I can say this because I am a HW engineer and I've made this mistake!)
With a properly connected bus between the processor and the FPGA, bit reversal is thus not needed when loading a .bit file (fpga loadb) or a non
mirrored
PROM file (fpga load).
For hardware with bit mirroring on the bus, I suggest either using
amirrored
PROM file or mirroring the bit in the data write callback. I thus vote
for
removing bit mirroring in fpga_loadbitstream() and adding an explanation
of
this issue (either in the code or in the documentation) to prevent
hardware
mistakes in future designs.
I agree with all of this with the exception of totally removing the bit mirroring in fpga_loadbitstream(). If this were going in only a single product or it was being done for the first timeI would be all over that, however we know for a fact that there's at least one board out in the wild that relies on that bit mirroring to take place (another un-enlightened HW engineer no doubt ;) ). Flat out removing the code will break that board and I'm not inclined to face the wrath of the maintainer. If we can figure out who depends on that and get them to push the bit mirroring down to the call back function where it rightfully belongs than I agree remove the code. Otherwise I think it needs to conditionally stay.
Bruce

Bruce_Leonard@selinc.com wrote:
Hi Laurent,
Laurent Pinchart laurentp@cse-semaphore.com wrote on 08/22/2007 12:28:36 AM:
Hi Bruce,
ordering. UG322 sheds some light on the issue. D0-D7 are indeed MSB-LSB,
making the SelectMAP interface use the big-endian PPC bit ordering convention.
I'm with Matthaias, I've learned to refer to them as MSB/LSB on the list :). Avoids confusion.
In my experience, numbering the MSB as 0 is an IBM phenomenon. Where it isn't a direct IBM artifact, if you dig you will likely find IBM's influence (e.g. Mil-Std-1750 was heavily influenced by IBM, PowerPC is an IBM architecture, I don't know about Jovial and Ada but suspect IBM Federal Systems had their say in them).
I've read an explanation that makes sense to me, although it be a urban legend. The first computers (many made by IBM) were used to compute artillery trajectories and used fixed point math. Numbers were therefore: 2^ 0 = 1 2^-1 = 0.5 2^-2 = 0.75 ... so numbering the MSB...LSB as 0,1,2...31 (dropping the "-" sign) made sense to the mathematicians who were writing the trajectory solving programs.
to D7-D0 on the FPGA. I'll go scold our hardware engineer :-)
Don't scold him to hard. It's an easy mistake to make especially if you're used to everything being little endian. (I can say this because I am a HW engineer and I've made this mistake!)
Sometimes is is a Good Thing[tm], and sometimes you are screwed regardless. :-/ Each case needs to be thought through carefully. The whole issue is very confusing and it is awfully easy to chose wrong. Then it is always "sorry, but the software will have to fix it." :-/
[snip]
gvb

Hi All:
Did anybody use u-boot to load vxWorks? I have sequoia board (NOR flash) and when I tried simply boot vxWorks elf, it hangs.
vxWorks native bootrom.bin works fine, booting the very same vxWorks elf perfectly.
Thanks,
Leonid.

Hi there Leonid,
It's been a long while, but here's the commands I used to boot vxWorks on an mpc8641 processor:
setenv bootargs motetsec(0,0)host:74kap1 h=10.120.1.2 e=10.120.1.226 dcache on tftpboot 0x2000000 8641D_74K_1 bootvx 0x2000000
'Course, you won't have to do the tftpboot command if you've already got the image in flash.
Hope that helps, Chris
On Wed, 2007-08-22 at 11:03 -0700, Leonid wrote:
Hi All:
Did anybody use u-boot to load vxWorks? I have sequoia board (NOR flash) and when I tried simply boot vxWorks elf, it hangs.
vxWorks native bootrom.bin works fine, booting the very same vxWorks elf perfectly.
Thanks,
Leonid.
This SF.net email is sponsored by: Splunk Inc. Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/ _______________________________________________ U-Boot-Users mailing list U-Boot-Users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/u-boot-users

Hi, Chris:
Could you please clarify what 8641D_74K_1 image was? vxWorks elf, binary, or some combination of bootrom and kernel?
Thanks a lot,
Leonid.
-----Original Message----- From: Chris Fester [mailto:cfester@iphase.com] Sent: Wednesday, August 22, 2007 12:40 PM To: Leonid Cc: u-boot-users@lists.sourceforge.net Subject: Re: [U-Boot-Users] Loading vxWorks by u-boot.
Hi there Leonid,
It's been a long while, but here's the commands I used to boot vxWorks on an mpc8641 processor:
setenv bootargs motetsec(0,0)host:74kap1 h=10.120.1.2 e=10.120.1.226 dcache on tftpboot 0x2000000 8641D_74K_1 bootvx 0x2000000
'Course, you won't have to do the tftpboot command if you've already got the image in flash.
Hope that helps, Chris
On Wed, 2007-08-22 at 11:03 -0700, Leonid wrote:
Hi All:
Did anybody use u-boot to load vxWorks? I have sequoia board (NOR flash) and when I tried simply boot vxWorks elf, it hangs.
vxWorks native bootrom.bin works fine, booting the very same vxWorks elf perfectly.
Thanks,
Leonid.
--- This SF.net email is sponsored by: Splunk Inc. Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a
browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/ _______________________________________________ U-Boot-Users mailing list U-Boot-Users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/u-boot-users

Hi, Chris:
I did thing similar to yours:
vxargs=setenv bootargs emac(0,0)h=192.168.0.141 e=192.168.0.204 f=0x86 dcache on vx_ld_addr=2000000 vxget=tftp ${vx_ld_addr} windriver/vxWorks vxload=run vxargs vxget; bootvx ${vx_ld_addr}
Now I run vxload:
=> run vxload ENET Speed is 100 Mbps - FULL duplex connection Using ppc_4xx_eth0 device TFTP from server 192.168.0.141; our IP address is 192.168.0.204 Filename 'windriver/vxWorks'. Load address: 0x2000000 Loading: #################################################################
#################################################################
#################################################################
#################################################################
#################################################################
################################################################# ################################## done Bytes transferred = 2169653 (211b35 hex) ## Ethernet MAC address not copied to NV RAM Loading .text @ 0x00010000 (1412464 bytes) Loading .data @ 0x00168d80 (146880 bytes) Clearing .bss @ 0x0018cb40 (88848 bytes) ## Using bootline (@ 0x4200): emac(0,0)h=192.168.0.141 e=192.168.0.204 f=0x86 dcache on ## Starting vxWorks at 0x00010000 ...
This is it...
I have console running on 9600 8N1 (which as I figured defined in vxWorks as well) and the very same vxWorks elf runs OK from bootrom.
Thanks,
Leonid. -----Original Message----- From: Chris Fester [mailto:cfester@iphase.com] Sent: Wednesday, August 22, 2007 1:42 PM To: Leonid Cc: u-boot-users@lists.sourceforge.net Subject: RE: [U-Boot-Users] Loading vxWorks by u-boot.
On Wed, 2007-08-22 at 13:12 -0700, Leonid wrote:
Hi, Chris:
Could you please clarify what 8641D_74K_1 image was? vxWorks elf, binary, or some combination of bootrom and kernel?
It was a vxWorks elf. No bootrom.
Chris

--- Leonid Leonid@a-k-a.net wrote:
Hi All:
Did anybody use u-boot to load vxWorks? I have sequoia board (NOR flash) and when I tried simply boot vxWorks elf, it hangs.
vxWorks native bootrom.bin works fine, booting the very same vxWorks elf perfectly.
Thanks,
Leonid.
I did it a couple of years ago on an 8260 based board. I seem to recall having to adjust the entry point address.
____________________________________________________________________________________ Luggage? GPS? Comic books? Check out fitting gifts for grads at Yahoo! Search http://search.yahoo.com/search?fr=oni_on_mail&p=graduation+gifts&cs=...

LeonidLeonid@a-k-a.net schrieb am 22.08.07 um 20:03 in Nachricht
406A31B117F2734987636D6CCC93EE3C020FFE89@ehost011-3.exch011.intermedia.net:
Hi All:
Did anybody use u-boot to load vxWorks? I have sequoia board (NOR flash) and when I tried simply boot vxWorks elf, it hangs.
vxWorks native bootrom.bin works fine, booting the very same vxWorks elf perfectly.
Please take a look at "[PATCH] Make Sequoia boot vxWorks" posted on Juli 30. Problem areas are two different chip selects and different TLB settings, which collide (u-Boot needs TLB#0 for the boot flash and vxWorks needs TLB#0 for its exception handling).
I have a custom PPC440EPx work where I have to make vxWorks work on it, which is a real pain. If you are interested to share insight you may also contact me directly.
Niklaus Giger Netstal Maschinen AG CH-8752 Naefels niklaus.giger@netstal.com Phone: ++41 55 618 64 68

Jerry,
Did you ever put together a patch for all those things we discussed this summer? I don't see anything in the latest from the main git tree.
Bruce

Hi Bruce,
On Wednesday 22 August 2007 19:09, Bruce_Leonard@selinc.com wrote:
I agree with all of this with the exception of totally removing the bit mirroring in fpga_loadbitstream(). If this were going in only a single product or it was being done for the first timeI would be all over that, however we know for a fact that there's at least one board out in the wild that relies on that bit mirroring to take place (another un-enlightened HW engineer no doubt ;) ). Flat out removing the code will break that board and I'm not inclined to face the wrath of the maintainer. If we can figure out who depends on that and get them to push the bit mirroring down to the call back function where it rightfully belongs than I agree remove the code. Otherwise I think it needs to conditionally stay.
there is only one known board (GEN860) out there that uses the FPGA sub system. That's why I put Keith as its maintainer on cc. As Wolfgang stated we should not care about U-Boot ports that not made public and are not part of the U-Boot repository. I will submit patches for two new boards that will use the fpga subsystem as soon as this discussion has calmed down (and I did some more testing).
Matthias

Matthias,
there is only one known board (GEN860) out there that uses the FPGA sub system. That's why I put Keith as its maintainer on cc. As Wolfgang stated we should not care about U-Boot ports that not made public and are not part of the U-Boot repository.
Well, I was assuming that it was a public board since it's what I used as a starting point for my work. I just didn't want to see it get shot in the back by any changes we made.
Bruce

In message 200708201513.02231.matthias.fuchs@esd-electronics.com you wrote:
BTW: Are there any boards that use the FPGA stuff and that are not made public ?:-)
We don't have to be considerate of those.
Best regards,
Wolfgang Denk

Hi Matthias,
I replied to your reply to me before I saw your new post. Sorry for the noise. See my comments below.
- Make the 'size' parameter obsolete for the 'fpga loadb' command.
The actual bitstream size is taken from the bitstream.
Agreed, plus you can remove the check against the size parameter passed in from the command line that doesn't make any sense.
- Do not bit-swap the bytes in the xilinx bitstream. When using the
slave serial code the bits may not be swapped. I can imagine that this swapping requirement comes from a special board layout. So is should be done in board specific code. When removing the swapping code, we can get rid of the complete malloc/free stuff in fpga_loadbitstream().
I would make this optional/configurable as I mentioned in my last post. Doing the bit swapping makes sense for a little endian processor but doesn't make sense for the big endian machines like the PPC.
- Make post() and pre() callback optional in relocation. So do
not relocate NULL-pointers. This has been discussed a short time ago on the list.
Agreed
- Add some more devices.
More devices are always good. That way folks in the future have a starting place.
BTW: Are there any boards that use the FPGA stuff and that are not made public ?:-)
Our board is totally custom and will never be used by anyone but us, but as Wolfgang pointed out that's not the lists problem that's our problem. Folks using u-boot need to be aware that things change and they need to be careful when doing pulls from the repository.
Matthias
diff --git a/common/cmd_fpga.c b/common/cmd_fpga.c index 3444091..2e1cf26 100644
I haven't gone through your diffs yet, I wanted to get comments back to you early. I'll look them over today and give any feedback if I need to later.
Thanks for your work on this. It saves me from the embarrassment of having to submit patches for the first time ;). Not looking forward to that beating!
Bruce

Bruce,
On Monday 20 August 2007 20:46, Bruce_Leonard@selinc.com wrote:
- Make the 'size' parameter obsolete for the 'fpga loadb' command.
The actual bitstream size is taken from the bitstream.
Agreed, plus you can remove the check against the size parameter passed in from the command line that doesn't make any sense.
Yes, I thought about that, too. But I wanted to take care about people using the useless size parameter:-)
- Do not bit-swap the bytes in the xilinx bitstream. When using the
slave serial code the bits may not be swapped. I can imagine that this swapping requirement comes from a special board layout. So is should be done in board specific code. When removing the swapping code, we can get rid of the complete malloc/free stuff in fpga_loadbitstream().
I would make this optional/configurable as I mentioned in my last post. Doing the bit swapping makes sense for a little endian processor but doesn't make sense for the big endian machines like the PPC.
Why? AFAIK, the _bit_order has nothing to do with die CPU endianess. We are talking about mirrowing the 8 bits in a byte.
BTW, you can tell Xilinx promgen tool to use the other bitorder, so there is no need to do correct it in U-Boot.
- Make post() and pre() callback optional in relocation. So do
not relocate NULL-pointers. This has been discussed a short time ago on the list.
Agreed
- Add some more devices.
More devices are always good. That way folks in the future have a starting place.
BTW: Are there any boards that use the FPGA stuff and that are not made public ?:-)
Our board is totally custom and will never be used by anyone but us, but as Wolfgang pointed out that's not the lists problem that's our problem. Folks using u-boot need to be aware that things change and they need to be careful when doing pulls from the repository.
Even totally custom boards should be in the U-Boot repository. Many boards that are supported by U-Boot are custom boards. For examples esd build more than 25 boards that are using U-Boot as bootloader. Less than 50% of these boards are COTS product. The others are totally customized boards.
Matthias

Matthias,
Matthias Fuchs matthias.fuchs@esd-electronics.com wrote on 08/21/2007 01:30:19 AM:
I would make this optional/configurable as I mentioned in my last
post.
Doing the bit swapping makes sense for a little endian processor but doesn't make sense for the big endian machines like the PPC.
Why? AFAIK, the _bit_order has nothing to do with die CPU endianess. We are talking about mirrowing the 8 bits in a byte.
Well I may be in over my head here on using terminology so I'll go back to basics. With the MPC834x (which is what we're using), bit D0 is the MSB. In the parallel mode the Xilinx FPGA's MSB is also D0. So all you have to do is connect D0 to D0, D1 to D1, etc., and there is no bit swapping needed.
However with processors from Intel D0 is the LSB. So to make the data correct you need to do one of two things: 1) connect D0 on the processor to D7 on the FPGA, D1 to D6, etc, or; 2) you need to bit swap the data in the code before sending it to the FPGA.
My goal of making this configurable was to make the code workable on any combination of processor with a Xilinx FPGA. However, if there's a custom call back function that HAS to be written for every application where they bit-swapping can be put if it's needed, then by all means let's go that way. It keeps it hidden away and it's the individual BSP that's responsible for getting it right. Fewer #define's cluttering up common code.
Bruce
participants (9)
-
Bruce_Leonard@selinc.com
-
Chris Fester
-
Frank
-
Jerry Van Baren
-
Laurent Pinchart
-
Leonid
-
Matthias Fuchs
-
Niklaus Giger
-
Wolfgang Denk