Apparently, the Erratum ENGcm09395 for iMX515 made the OpenOCD problems clear. It states the location of ROM Table is misreported. But still, I wanted to implement the ROM Table location autodetection as Oyvind Harboe hinted me to.
Therefore I added a function for handling quirks as this and did some code shuffling in OpenOCD. The patches for this are already in the OpenOCD mailing list. I'm still a bit uncertain about them, but I hope after one or two iterations, they will land in mainline OpenOCD.
Sunday, October 31, 2010
Saturday, October 30, 2010
Studies, U-Boot, OpenOCD and CortexA8
The lack of additions on this blog recently wasn't caused by me disappearing out of the blue. It was caused by me preparing for my degree's exams, then fighting with U-Boot and recently working on a new hardware. Read on.
Studies
In case you're only interested in technical stuff, you can skip this part, which is mostly about gaining my bachelor's degree at the Faculty of Mathematics and Physics Charles University and the OpenBSD thesis.
Due to rather personal than other circumstances, I ended up finishing my first academic degree at the end of the summer rather than at the beginning of it. Well, whatever.
That means, the OpenBSD hacking days are past me since I finished my bachelor's thesis. I believe I wrote about this in some of the previous blogs, but now it's officially past me and sealed away. In the end, the thesis was graded A by both the opponent (Mgr. Martin Decky) and the supervisor (RNDr. Leo Galambos, Ph.D.) so the final grade from the thesis was A as well.
Note, the grading system in our country is different than in most other countries. Here, it's numeric, but "1" is equal to A, "2" to B, "3" to C and "4" to Failed. I'll hereby stick with the system using letters to make it less confusing.
Then I had to prepare for the exams, which were really thorough so the preparation certainly couldn't be underestimated. That took me about a month where I didn't hack on stuff much, I was just reviewing patches and from time to time I sent some minor fixes. At the exam, I finished with a total grade of B.
Apparently, on the diploma, there is only one grade, not two (one from thesis and one from examination), so the examination committee has to ultimately decide this grade. My final grade was A, which is what will be on my bachelor's diploma, which I'll receive later next month.
U-Boot
Once the exam was past me, I got back to maintaining U-Boot PXA. Apparently, there were a lot of changes going on inside the U-Boot.
Firstly, Wolfgang Denk pushed me to rework pxa-regs.h so the standard accessors can be used to access PXA CPU registers instead of the preprocessor goo that was there before. This was a patch over 6000 lines big as it affected a lot of code in U-Boot, not only pxa-regs.h. Obviously, platform code as well as drivers were affected and had to be patched to use {read[blw],write[bwl]}() accessors. Catching all the damaged code wasn't really easy in some cases, but I think I caught them all.
With that out of the way, I checked pxa-lcd driver and fixed various, mostly coding-style related problems and added a few new LCD definitions. Then, I fixed PXA250 UART problem, where the UART was omitted in U-Boot from the initialization routine on PXA25x and PXA26x.
Also, the Palm LifeDrive, Palm Tungsten|C and Balloon3 support went in, Voipac PXA270 got various bugs fixed and there were also fixes for the memory init code by Mikhail Kshevetskiy. I also got an USB3.0 flash disk, but apparently, it didn't work with USB on PXA in U-Boot, so I submitted a patch for this.
Then though, Heiko Schocher introduced a change in U-Boot, which allows it to relocate in RAM. More into detail, this change allows U-Boot to always sit at the end of RAM, which is useful on systems where there are various models with different size of RAM detected at runtime. This change broke the PXA port of U-Boot altogether.
This was a good enough motivation to completely rework the PXA init code. I rewrote half of the start.S assembler bootstrap from scratch, because the code there was really old, messy and and with the relocation patches in, no longer suitable for the purpose. The start.S can no longer use RAM until certain point, but it needs to use stack. Sure, for stack, SRAM can be used on PXA27x, but there are PXA CPUs older than that which have no SRAM. This set me in front of a challenge -- where should I point stack pointer register is there's no RAM.
The solution is somehow easy, but needs you to understand how the caches on ARMv5/XScale core work. What was the trick? It was easy, the caches allow the user to lock entries in them. That is, they allow the user to write into the cached area, while convince the CPU not to actually write the data into that area, but only keep them in cache. But for using caches, MMU has to be enabled. So the big picture is, I manually generated an 1:1 VA:PA mapping MMU table within the U-Boot binary and at the bootstrap, I point the CPU at this table and enable MMU. Within this table, at the place which indexes RAM start +1MB*, I made a special entry that configures the area as cachable. Then I used the information from the XScale core documentation to lock 4 kb of data to create a tiny, 4 kb in-cache RAM. So writing to that area of RAM behaves as if the RAM was where and was working, even though there's no backing store. The rest was just a matter of pointing a stack pointer there, end of the fairy tale.
This wasn't the only thing about relocation patches though. Because there was no need to init the RAM in assembler code anymore, I could push the RAM init into the C routines which were executed much later. I did this and in current state, most of the hardware initialization takes place much later. This has one very big advantage in the long-term. As the hardware is not initialized in C code, it'll now be easily possible to walk a Flattened Device Tree and do the hardware initialization according to that. So imagine having single U-Boot binary work many CPUs and only supplying a FDT for each board. That's the long-term plan now.
There were other changes related to this relocation stuff, which in the end generated about 30 patches in total. One more thing is interesting though. Because there are boards which have multiple variants and it's not possible to detect which variant is which on the fly, there started to appear a Makefile pollution in U-Boot, which Wolfgang Denk didn't like. We discussed this and came to a conclusion about a solution. I implemented first version, then he improved it and committed it. So now, all of the U-Boot board variant setup should happen in boards.cfg finally and there's no longer need to touch Makefile.
OpenOCD and CortexA8
About a month ago, I received an Genesi USA EfikaMX Smarttop from their developer sponsorship program called Power Developer. My task was to support this device with OpenOCD so common people can JTAG it with those cheap FT2232-based JTAG dongles.
The system contains an Freescale iMX515 CPU, for which apparently there were some previous unsuccessful attempts to make it work. I based my efforts on these, but did a further investigation of the matter. "Sadly", all the support for Cortex A8 was already in place, which spoiled my fun ;-)
And in the end, it turned out the solution of the problem was very simple. The people trying to get iMX515 working with OpenOCD forget, that the Cortex A8 support there was OMAP3-centric. The DAP address was hardcoded for OMAP3, which has it at 0x54011000 address, but for iMX515, the DAP address is at 0x60008000. Adjusting this in the source code made the CPU mostly work.
The problem with this though is, that this stuff should be auto-detectable. So far, I was digging in the CortexA8 stuff for about two days so I have still a lot to learn about this. But I was hinted by Oyvind Harboe and Zack Welch to use the "dap info 1" command and look around that. The command reads the MEM-AP's BASE register to figure out the location of ROM Table. And by parsing the ROM table, it's possible to figure out the location of DAP, which is exactly the address I mentioned in previous paragraph that needs to be autodetected.
The problem is, this command for some reason misdetects the location of ROM Table and returns the ROM Table is empty. By manually adjusting the source code and pointing the command to a proper location of ROM Table, the parsing algoright catches up and correctly dumps the contents. You can keep an eye on further development of this matter for example here (or the OpenOCD mailing list obviously).
There, you can also find preliminary patches with which the iMX515 works, but the autodetection of ROM Table base is still missing. So, if you want to use iMX515 with OpenOCD, you can, but those three patches won't probably make it into mainline OpenOCD until the autodetection problem is solved.
Studies
In case you're only interested in technical stuff, you can skip this part, which is mostly about gaining my bachelor's degree at the Faculty of Mathematics and Physics Charles University and the OpenBSD thesis.
Due to rather personal than other circumstances, I ended up finishing my first academic degree at the end of the summer rather than at the beginning of it. Well, whatever.
That means, the OpenBSD hacking days are past me since I finished my bachelor's thesis. I believe I wrote about this in some of the previous blogs, but now it's officially past me and sealed away. In the end, the thesis was graded A by both the opponent (Mgr. Martin Decky) and the supervisor (RNDr. Leo Galambos, Ph.D.) so the final grade from the thesis was A as well.
Note, the grading system in our country is different than in most other countries. Here, it's numeric, but "1" is equal to A, "2" to B, "3" to C and "4" to Failed. I'll hereby stick with the system using letters to make it less confusing.
Then I had to prepare for the exams, which were really thorough so the preparation certainly couldn't be underestimated. That took me about a month where I didn't hack on stuff much, I was just reviewing patches and from time to time I sent some minor fixes. At the exam, I finished with a total grade of B.
Apparently, on the diploma, there is only one grade, not two (one from thesis and one from examination), so the examination committee has to ultimately decide this grade. My final grade was A, which is what will be on my bachelor's diploma, which I'll receive later next month.
U-Boot
Once the exam was past me, I got back to maintaining U-Boot PXA. Apparently, there were a lot of changes going on inside the U-Boot.
Firstly, Wolfgang Denk pushed me to rework pxa-regs.h so the standard accessors can be used to access PXA CPU registers instead of the preprocessor goo that was there before. This was a patch over 6000 lines big as it affected a lot of code in U-Boot, not only pxa-regs.h. Obviously, platform code as well as drivers were affected and had to be patched to use {read[blw],write[bwl]}() accessors. Catching all the damaged code wasn't really easy in some cases, but I think I caught them all.
With that out of the way, I checked pxa-lcd driver and fixed various, mostly coding-style related problems and added a few new LCD definitions. Then, I fixed PXA250 UART problem, where the UART was omitted in U-Boot from the initialization routine on PXA25x and PXA26x.
Also, the Palm LifeDrive, Palm Tungsten|C and Balloon3 support went in, Voipac PXA270 got various bugs fixed and there were also fixes for the memory init code by Mikhail Kshevetskiy. I also got an USB3.0 flash disk, but apparently, it didn't work with USB on PXA in U-Boot, so I submitted a patch for this.
Then though, Heiko Schocher introduced a change in U-Boot, which allows it to relocate in RAM. More into detail, this change allows U-Boot to always sit at the end of RAM, which is useful on systems where there are various models with different size of RAM detected at runtime. This change broke the PXA port of U-Boot altogether.
This was a good enough motivation to completely rework the PXA init code. I rewrote half of the start.S assembler bootstrap from scratch, because the code there was really old, messy and and with the relocation patches in, no longer suitable for the purpose. The start.S can no longer use RAM until certain point, but it needs to use stack. Sure, for stack, SRAM can be used on PXA27x, but there are PXA CPUs older than that which have no SRAM. This set me in front of a challenge -- where should I point stack pointer register is there's no RAM.
The solution is somehow easy, but needs you to understand how the caches on ARMv5/XScale core work. What was the trick? It was easy, the caches allow the user to lock entries in them. That is, they allow the user to write into the cached area, while convince the CPU not to actually write the data into that area, but only keep them in cache. But for using caches, MMU has to be enabled. So the big picture is, I manually generated an 1:1 VA:PA mapping MMU table within the U-Boot binary and at the bootstrap, I point the CPU at this table and enable MMU. Within this table, at the place which indexes RAM start +1MB*, I made a special entry that configures the area as cachable. Then I used the information from the XScale core documentation to lock 4 kb of data to create a tiny, 4 kb in-cache RAM. So writing to that area of RAM behaves as if the RAM was where and was working, even though there's no backing store. The rest was just a matter of pointing a stack pointer there, end of the fairy tale.
This wasn't the only thing about relocation patches though. Because there was no need to init the RAM in assembler code anymore, I could push the RAM init into the C routines which were executed much later. I did this and in current state, most of the hardware initialization takes place much later. This has one very big advantage in the long-term. As the hardware is not initialized in C code, it'll now be easily possible to walk a Flattened Device Tree and do the hardware initialization according to that. So imagine having single U-Boot binary work many CPUs and only supplying a FDT for each board. That's the long-term plan now.
There were other changes related to this relocation stuff, which in the end generated about 30 patches in total. One more thing is interesting though. Because there are boards which have multiple variants and it's not possible to detect which variant is which on the fly, there started to appear a Makefile pollution in U-Boot, which Wolfgang Denk didn't like. We discussed this and came to a conclusion about a solution. I implemented first version, then he improved it and committed it. So now, all of the U-Boot board variant setup should happen in boards.cfg finally and there's no longer need to touch Makefile.
OpenOCD and CortexA8
About a month ago, I received an Genesi USA EfikaMX Smarttop from their developer sponsorship program called Power Developer. My task was to support this device with OpenOCD so common people can JTAG it with those cheap FT2232-based JTAG dongles.
The system contains an Freescale iMX515 CPU, for which apparently there were some previous unsuccessful attempts to make it work. I based my efforts on these, but did a further investigation of the matter. "Sadly", all the support for Cortex A8 was already in place, which spoiled my fun ;-)
And in the end, it turned out the solution of the problem was very simple. The people trying to get iMX515 working with OpenOCD forget, that the Cortex A8 support there was OMAP3-centric. The DAP address was hardcoded for OMAP3, which has it at 0x54011000 address, but for iMX515, the DAP address is at 0x60008000. Adjusting this in the source code made the CPU mostly work.
The problem with this though is, that this stuff should be auto-detectable. So far, I was digging in the CortexA8 stuff for about two days so I have still a lot to learn about this. But I was hinted by Oyvind Harboe and Zack Welch to use the "dap info 1" command and look around that. The command reads the MEM-AP's BASE register to figure out the location of ROM Table. And by parsing the ROM table, it's possible to figure out the location of DAP, which is exactly the address I mentioned in previous paragraph that needs to be autodetected.
The problem is, this command for some reason misdetects the location of ROM Table and returns the ROM Table is empty. By manually adjusting the source code and pointing the command to a proper location of ROM Table, the parsing algoright catches up and correctly dumps the contents. You can keep an eye on further development of this matter for example here (or the OpenOCD mailing list obviously).
There, you can also find preliminary patches with which the iMX515 works, but the autodetection of ROM Table base is still missing. So, if you want to use iMX515 with OpenOCD, you can, but those three patches won't probably make it into mainline OpenOCD until the autodetection problem is solved.
Monday, August 16, 2010
U-Boot: PXA27x Matrix keypad driver
Today, I hacked together a PXA27x matrix keypad driver for U-Boot bootloader. It behaves as a usual stdin. Then I made ZipitZ2 utilize this new driver. I also implemented support for various modifier keys directly into the driver for convenience's sake. The driver still has a few rough edges and needs some more care, but it does it's job on ZipitZ2 well.
The source code can be found in u-boot-pxa -devel branch.
The source code can be found in u-boot-pxa -devel branch.
Saturday, August 14, 2010
Last month's hacking report
Today's blog entry will be a long one as it will span my activities over the last month. I focused more on hacking than on blogging, but the time has come and the FIFO got filled so it's time to empty it.
Voipac PXA270
Firstly, I got a bit involved with Android. Radoslav Deak and me did some kernel and userland hacking on it to get it running on the Voipac PXA270 board. The Android kernel changes didn't make me feel well, but the userland made me cry, no more words needed here I believe. Anyway, the Android does not support 18bpp LCD, therefore I was told they'll send me another board with 16bpp LCD. Though a mistake happened and I got a board with 18bpp LCD again. Luckily enough, I don't have to hack on Android anymore, but it's not only Android that doesn't support 18bpp LCD, it's also X.org.
Here you'll probably already start questioning my sanity when I say I started digging in the X.org to get this fixed. The X.org developers are actually very nice and very helpful people and they helped me with patching the X.org. One thing worth noting is that I compiled the X.org on the other Voipac PXA270 board which is running Debian already. The building took a little bit of time anyway. The patch is already in mainline X.org I believe and it was not all that hard in the end.
The only trouble with this change is that it uses four bits of memory for each pixel and with the 104MHz SDRAM on the Voipac PXA270 and 640x480 LCD, this eats a lot of memory bus bandwidth.
One more thing is worth noting, that is the xserver-xfbdev, which is capable of 18bpp already, but it's not certain whether the apps connecting to this kind of Xserver won't have problems with 18bpp. On the other hand, this kind of problem may happen even with the standard Xserver, but so far, GDM worked well (and probably whole GTK does, I didn't test anything but that).
There were some other minor changes on the Voipac PXA270 front, but these were mostly bugfixes. There were also bootloader related changes and fixes though. The most relevant one was the one adding support for 128MB variant of the module. All these changes can be found either in my kernel tree or in my u-boot tree.
The OpenBSD
Here comes one sad piece of news. Sad, because I had to leave a piece of code unmaintained. I won't disclose the reasons why as I believe interested people will be able to find it themselves. To put it short, I'm not a member of the OpenBSD developer community anymore. I released the rest of the patches for Palm port to their mailing list and I hope jasper@ and drahn@ will at least not let the code bitrot.
On the other hand, it's actually quite a relief as I can now fully focus on Linux kernel hacking and U-Boot bootloader hacking. My opinion of the OpenBSD kernel code is biased and therefore you won't find it here. Though I think drahn@ did a very good job on the ARM code.
Well, at least I managed to finish my thesis and the system actually works quite well on Palm hardware, including Xenocara (the OpenBSD version of X.org), touchscreen etc.
Palm hacking again
A lot of redundant code in the Palm hardware support code and Eric's whining on that matter some time ago motivated me to consider trimming it a bit. Though hacking on the Palm hardware was different from the old Hack&Dev days this time.
I introduced a set of common functions which each registered one piece of hardware on the Palm handheld in question. This allowed me to remove about six copies of redundant data structures and other stuff. While at this, I wrote the common functions modular so in case the support for a particular piece of hardware isn't compiled in kernel, the support structures are removed as well.
I also added a long lost patch for the MAX1586A PMIC into the common code as that's used in all Palms while at that. Further on, I modularized the rest of the non-common code in all the Palm devices in the same fashion. I'm actually quite happy about the code quality now. And Eric did his little Linus-like gag about the number of deletions ;-)
This was not all on the Palm front though. As my Palm Tungsten|C is a nice toy I like quite a bit and I needed a PXA255 testing platform, I updated the U-Boot on this device to mainline version. This can be found in my u-boot tree again. I also modularized the kernel code the same way I did with PXA27x Palms, though I don't use the common code as this platform is quite different. While at that, I added support for LEDs and switched the UDC to gpio-vbus. All these changes can be found in my kernel tree.
U-Boot
I already said this earlier probably, but I'm now the U-Boot-PXA maintainer. Therefore support for some new machines hit mainline and support for a few others is underway. This time, the new ones are surprisingly the Palm LifeDrive, Palm Tungsten|C and Balloon3. The Palm Tungsten|C is no news as the code to support that hardware in U-Boot is about one year old. So this one was only updated, see above.
The Palm LifeDrive is a different thing though. Because I wanted to avoid destroying my unit, I figured out a way how to pseudo-dual-boot PalmOS and U-Boot for testing purposes. This turned out to be quite simple, though without JTAG one has to be very careful. Firstly, the size of flash in Palm LifeDrive is only 512kb -- 0x80000 bytes -- and the last 0x20000 bytes are unused and PalmOS ignores them. That's enough for slightly stripped down U-Boot binary, but there's one more thing missing, that is, in case U-Boot was installed in that part of flash, something must execute it.
Executing it means jumping to it's first instruction. By looking at the disassembly dump of the Palm LifeDrive flash, very close to the beginning, the code clears register "r0" by moving zero into it. By replacing this instruction with a jump at the 0x60000 address, the U-Boot can be executed. But that would make the dual-boot impossible in case there was just pure U-Boot at 0x60000.
The trick is to add code to 0x60000, that checks PSPR register aka. the only register that survives suspend-to-mem. This register always contains value that modulo 4 gives no remainder, ie. is aligned to four bytes in PalmOS. The last two bits are unused though and that's the trick.
The point is to load U-Boot just after this code that checks PSPR. In case these last two bits in PSPR are set, the code will not jump right past the place where the "r0" was zeroed, but instead will just continue executing the code further on, which means CPU will reach U-Boot. Otherwise, the PalmOS loader will just continue execution. I also had to zero the "r0" before jumping back to the PalmOS loader in the later case.
One more thing is important here. To set the PSPR, I adjusted the suspend routine in Linux kernel to store some totally broken number into it and when I then pressed any of the "unsuspend" buttons, the U-Boot came up. Note, the U-Boot I used for this had the wakeup capability disabled, which is very important.
To get the U-Boot wakeup the kernel properly, it's necessary to replace the Palm LifeDrive bootloader altogether. That's what I did and it worked very well for me, until I wanted to test a newly compiled version for Tomas Cech. The battery choked while the system was being updated. Well, that's sad. Luckily, I already have a replacement device.
Cypress EZUSB SX2
Having U-Boot on Palm LifeDrive means it can now be fully used with Linux. That also means need for some kind of connection to the outside world. Most of the people involved with Hack&Dev certainly recall the USB 2.0 chip in Palm LifeDrive. The chip is actually quite simple, but also quite incompatible with Linux's perception of an USB gadget chip.
The SX2 requires the so called Descriptor RAM to be filled with proper USB descriptor in order to enumerate at all. I started writing a driver for the SX2, but it's still very incomplete. In the current state, it can send data from host and to host and is behaving as 4 bulk endpoints. That implies it can be used probably only with g_serial for now. But it's still far from complete. The draft can be found in my kernel tree and anyone willing to hack on it is welcome.
The drinking party
During the Linaro conference in Prague, me and some other people -- Eric Miao, Nicolas Pitre, Daniel Mack, to name a few -- went for a beer. The party turned out into an awesome thing, it was probably the most enjoyable evening and night of the year for me.
Anyway, Eric decided to give up his maintainership of the Sharp Akita and pushed it into me. The current support for Sharp Akita in mainline is kind of poor, but with improving tendencies. The power management code is very broken and there are still a few other issues.
I decided to try fixing the power management issue so I joined efforts with Pavel Machek who started putting together a new battery driver for Sharp Spitz. Actually this also work on Sharp Akita and Sharp Borzoi. The driver currently has more rough edges than I'd love it to have, but it's kind of usable given enough knowledge on the user side. The problem with it is, that it still doesn't check the battery temperature so the user has to be careful not to overcharge the battery. Actually, there should be some GPIO, that prevents the battery from turning the device into a lethal weapon and the driver checks this GPIO, but according to Pavel, this is not safe enough.
I met with Wookey the other day and got a Balloon3 board with some additional peripherals. That obviously ended up in me porting U-Boot to this board and doing some heavy rework on the side of mainline kernel.
The first problem I faced was the FPGA that's on the Balloon3 board. That's used to route various CPU lines to hardware. It also controls NAND, CF and such. The PCMCIA/CF driver had to be slightly fixed on the Balloon3, because in case of FPGA, the only working firmware is version 0.3. For CPLD, which is integrated on some other Balloon3 boards, there is already version 1.0 of the firmware which has a different behaviour. I hope the fix for the FPGA firmware is underway as Hector Oron told me he'd look into it.
The worse thing was the NAND driver. For that, I used the gen_nand driver and implemented various necessary callbacks based on the original out-of-the-tree NAND driver for Balloon3. I heavily reworked this so the driver was used only as a technical documentation. Pretty much all the hardware is implemented on the board I have by now.
When I was hacking on the NAND driver, I noticed a bug in the gen_nand driver where it ignored the number of chips passed to the driver. The gen_nand assumed the number of chips was always one, which was true for all the boards that used the driver so far. But on balloon3, there were four chips in total. I fixed this and even implemented a check for invalid value of number of chips as per David Woodhouse's suggestion.
Toradex Colibri PXA3xx
Recently, there were a few people concerned about the status of Toradex Colibri PXA3xx. I was aware of a fact, that the code needs to be reworked for quite some time already. Just recently, I was motivated enough to go forth and do it. Therefore the code that's now in my tree is the reworked support for the board and the CPU card. I also reworked support for Colibri PXA300/PXA310 while at it. It is done in a very similar fashion to the PXA27x Colibri support. Actually, I used the evalboard code for Colibri PXA27x. Now all the Colibris use the same evalboard code and that's how it should be.
This is not all though. There was some stuff going on in the OpenPXA project about the Colibri PXA320 recently too and I was also pestering the tech support in Toradex. The result is that the E-Boot bootloader supplied by Toradex is not the only one that can update the CPLD firmware on the Colibri PXA320 board anymore.
Toradex provided me with the information on how the CPLD JTAG is connected to the CPU GPIO pins and an xsvf file for the CPLD containing the latest version of the CPLD firmware. And by using an xsvf player that I found is already in U-Boot and used on some PowerPC platforms, I was able to reprogram the CPLD to the latest version v1.7 of the CPLD firmware.
The xsvf player needed some obvious changes to operate the GPIO-emulated JTAG correctly, but the code is well abstracted and I think I'll make it into a generic code soon. Currently there are two copies of the same code in my U-Boot tree, which is no good. Note that the v1.7 of the CPLD firmware is probably some internal testing version from Toradex and I still have to ask them about the license for that file. It'd be best of they just put this xsvf file on their website.
Still, this is not the end. Because I wanted to use CF memory card on the Toradex PXA320 board, I decided to start implementing the PXA320 PCMCIA support. I first had to patch the pxa2xx_base to support different locations of the Static Memory controller registers, the MCIO, MCATT, MCMEM and MECR registers. That was the easier part.
After a bit of struggling with the Toradex CPLD and GPIO pin configuration and muxing, which is doing some obscure stuff to the PCMCIA signals, I managed to get the PCMCIA partly working. Note the struggle means I was stuck with it for more than a two days until I figured out what Toradex actually did. Their tech support on the other hand is very good and helpful even if a little bit slow, I'm happy about this.
The partly working above means, that if I insert a Marvell CF8385 into the CF slot, the card is detected, firmware is downloaded and no problems observed. Once I insert a memory card though, nothing happens. The card insertion GPIO is asserted, but it probably reads zeroes or something from the CIS. This issue can actually be just about anything, starting from wrong timing to misconfigured GPIOs. The more confusing thing here is that if I insert an Emtec or Patriot card, the card insertion is only detected. In case I insert a SanDisk card, the pata_pcmcia driver is loaded, but in the end, the disk is not recognized.
The cluster
You might have noticed the hardware kind of started piling up. That's true, but it's not unused actually. I use the boards that are in good shape software- and hardware-wise as an ARM compile cluster nodes. I run distcc on these and use it to build Debian packages. It's also an awesome stability testing and bug hunting mechanism for these platforms.
The cluster is still growing, but currently there are these machines:
Other
Just a few days ago, Mike Rapoport aranged it so I received a CM-X300 board. I was still unable to replace the bootloader there as I still don't have JTAG connected to that board.
I also started plumbing into the Debian u-boot package and prepared a patch. The problem is the current maintainer is totally ignoring any requests from me so far. I hope it's just temporary as he was busy with organising the debconf.
I hope you enjoyed reading the text.
Voipac PXA270
Firstly, I got a bit involved with Android. Radoslav Deak and me did some kernel and userland hacking on it to get it running on the Voipac PXA270 board. The Android kernel changes didn't make me feel well, but the userland made me cry, no more words needed here I believe. Anyway, the Android does not support 18bpp LCD, therefore I was told they'll send me another board with 16bpp LCD. Though a mistake happened and I got a board with 18bpp LCD again. Luckily enough, I don't have to hack on Android anymore, but it's not only Android that doesn't support 18bpp LCD, it's also X.org.
Here you'll probably already start questioning my sanity when I say I started digging in the X.org to get this fixed. The X.org developers are actually very nice and very helpful people and they helped me with patching the X.org. One thing worth noting is that I compiled the X.org on the other Voipac PXA270 board which is running Debian already. The building took a little bit of time anyway. The patch is already in mainline X.org I believe and it was not all that hard in the end.
The only trouble with this change is that it uses four bits of memory for each pixel and with the 104MHz SDRAM on the Voipac PXA270 and 640x480 LCD, this eats a lot of memory bus bandwidth.
One more thing is worth noting, that is the xserver-xfbdev, which is capable of 18bpp already, but it's not certain whether the apps connecting to this kind of Xserver won't have problems with 18bpp. On the other hand, this kind of problem may happen even with the standard Xserver, but so far, GDM worked well (and probably whole GTK does, I didn't test anything but that).
There were some other minor changes on the Voipac PXA270 front, but these were mostly bugfixes. There were also bootloader related changes and fixes though. The most relevant one was the one adding support for 128MB variant of the module. All these changes can be found either in my kernel tree or in my u-boot tree.
The OpenBSD
Here comes one sad piece of news. Sad, because I had to leave a piece of code unmaintained. I won't disclose the reasons why as I believe interested people will be able to find it themselves. To put it short, I'm not a member of the OpenBSD developer community anymore. I released the rest of the patches for Palm port to their mailing list and I hope jasper@ and drahn@ will at least not let the code bitrot.
On the other hand, it's actually quite a relief as I can now fully focus on Linux kernel hacking and U-Boot bootloader hacking. My opinion of the OpenBSD kernel code is biased and therefore you won't find it here. Though I think drahn@ did a very good job on the ARM code.
Well, at least I managed to finish my thesis and the system actually works quite well on Palm hardware, including Xenocara (the OpenBSD version of X.org), touchscreen etc.
Palm hacking again
A lot of redundant code in the Palm hardware support code and Eric's whining on that matter some time ago motivated me to consider trimming it a bit. Though hacking on the Palm hardware was different from the old Hack&Dev days this time.
I introduced a set of common functions which each registered one piece of hardware on the Palm handheld in question. This allowed me to remove about six copies of redundant data structures and other stuff. While at this, I wrote the common functions modular so in case the support for a particular piece of hardware isn't compiled in kernel, the support structures are removed as well.
I also added a long lost patch for the MAX1586A PMIC into the common code as that's used in all Palms while at that. Further on, I modularized the rest of the non-common code in all the Palm devices in the same fashion. I'm actually quite happy about the code quality now. And Eric did his little Linus-like gag about the number of deletions ;-)
This was not all on the Palm front though. As my Palm Tungsten|C is a nice toy I like quite a bit and I needed a PXA255 testing platform, I updated the U-Boot on this device to mainline version. This can be found in my u-boot tree again. I also modularized the kernel code the same way I did with PXA27x Palms, though I don't use the common code as this platform is quite different. While at that, I added support for LEDs and switched the UDC to gpio-vbus. All these changes can be found in my kernel tree.
U-Boot
I already said this earlier probably, but I'm now the U-Boot-PXA maintainer. Therefore support for some new machines hit mainline and support for a few others is underway. This time, the new ones are surprisingly the Palm LifeDrive, Palm Tungsten|C and Balloon3. The Palm Tungsten|C is no news as the code to support that hardware in U-Boot is about one year old. So this one was only updated, see above.
The Palm LifeDrive is a different thing though. Because I wanted to avoid destroying my unit, I figured out a way how to pseudo-dual-boot PalmOS and U-Boot for testing purposes. This turned out to be quite simple, though without JTAG one has to be very careful. Firstly, the size of flash in Palm LifeDrive is only 512kb -- 0x80000 bytes -- and the last 0x20000 bytes are unused and PalmOS ignores them. That's enough for slightly stripped down U-Boot binary, but there's one more thing missing, that is, in case U-Boot was installed in that part of flash, something must execute it.
Executing it means jumping to it's first instruction. By looking at the disassembly dump of the Palm LifeDrive flash, very close to the beginning, the code clears register "r0" by moving zero into it. By replacing this instruction with a jump at the 0x60000 address, the U-Boot can be executed. But that would make the dual-boot impossible in case there was just pure U-Boot at 0x60000.
The trick is to add code to 0x60000, that checks PSPR register aka. the only register that survives suspend-to-mem. This register always contains value that modulo 4 gives no remainder, ie. is aligned to four bytes in PalmOS. The last two bits are unused though and that's the trick.
The point is to load U-Boot just after this code that checks PSPR. In case these last two bits in PSPR are set, the code will not jump right past the place where the "r0" was zeroed, but instead will just continue executing the code further on, which means CPU will reach U-Boot. Otherwise, the PalmOS loader will just continue execution. I also had to zero the "r0" before jumping back to the PalmOS loader in the later case.
One more thing is important here. To set the PSPR, I adjusted the suspend routine in Linux kernel to store some totally broken number into it and when I then pressed any of the "unsuspend" buttons, the U-Boot came up. Note, the U-Boot I used for this had the wakeup capability disabled, which is very important.
To get the U-Boot wakeup the kernel properly, it's necessary to replace the Palm LifeDrive bootloader altogether. That's what I did and it worked very well for me, until I wanted to test a newly compiled version for Tomas Cech. The battery choked while the system was being updated. Well, that's sad. Luckily, I already have a replacement device.
Cypress EZUSB SX2
Having U-Boot on Palm LifeDrive means it can now be fully used with Linux. That also means need for some kind of connection to the outside world. Most of the people involved with Hack&Dev certainly recall the USB 2.0 chip in Palm LifeDrive. The chip is actually quite simple, but also quite incompatible with Linux's perception of an USB gadget chip.
The SX2 requires the so called Descriptor RAM to be filled with proper USB descriptor in order to enumerate at all. I started writing a driver for the SX2, but it's still very incomplete. In the current state, it can send data from host and to host and is behaving as 4 bulk endpoints. That implies it can be used probably only with g_serial for now. But it's still far from complete. The draft can be found in my kernel tree and anyone willing to hack on it is welcome.
The drinking party
During the Linaro conference in Prague, me and some other people -- Eric Miao, Nicolas Pitre, Daniel Mack, to name a few -- went for a beer. The party turned out into an awesome thing, it was probably the most enjoyable evening and night of the year for me.
Anyway, Eric decided to give up his maintainership of the Sharp Akita and pushed it into me. The current support for Sharp Akita in mainline is kind of poor, but with improving tendencies. The power management code is very broken and there are still a few other issues.
I decided to try fixing the power management issue so I joined efforts with Pavel Machek who started putting together a new battery driver for Sharp Spitz. Actually this also work on Sharp Akita and Sharp Borzoi. The driver currently has more rough edges than I'd love it to have, but it's kind of usable given enough knowledge on the user side. The problem with it is, that it still doesn't check the battery temperature so the user has to be careful not to overcharge the battery. Actually, there should be some GPIO, that prevents the battery from turning the device into a lethal weapon and the driver checks this GPIO, but according to Pavel, this is not safe enough.
I met with Wookey the other day and got a Balloon3 board with some additional peripherals. That obviously ended up in me porting U-Boot to this board and doing some heavy rework on the side of mainline kernel.
The first problem I faced was the FPGA that's on the Balloon3 board. That's used to route various CPU lines to hardware. It also controls NAND, CF and such. The PCMCIA/CF driver had to be slightly fixed on the Balloon3, because in case of FPGA, the only working firmware is version 0.3. For CPLD, which is integrated on some other Balloon3 boards, there is already version 1.0 of the firmware which has a different behaviour. I hope the fix for the FPGA firmware is underway as Hector Oron told me he'd look into it.
The worse thing was the NAND driver. For that, I used the gen_nand driver and implemented various necessary callbacks based on the original out-of-the-tree NAND driver for Balloon3. I heavily reworked this so the driver was used only as a technical documentation. Pretty much all the hardware is implemented on the board I have by now.
When I was hacking on the NAND driver, I noticed a bug in the gen_nand driver where it ignored the number of chips passed to the driver. The gen_nand assumed the number of chips was always one, which was true for all the boards that used the driver so far. But on balloon3, there were four chips in total. I fixed this and even implemented a check for invalid value of number of chips as per David Woodhouse's suggestion.
Toradex Colibri PXA3xx
Recently, there were a few people concerned about the status of Toradex Colibri PXA3xx. I was aware of a fact, that the code needs to be reworked for quite some time already. Just recently, I was motivated enough to go forth and do it. Therefore the code that's now in my tree is the reworked support for the board and the CPU card. I also reworked support for Colibri PXA300/PXA310 while at it. It is done in a very similar fashion to the PXA27x Colibri support. Actually, I used the evalboard code for Colibri PXA27x. Now all the Colibris use the same evalboard code and that's how it should be.
This is not all though. There was some stuff going on in the OpenPXA project about the Colibri PXA320 recently too and I was also pestering the tech support in Toradex. The result is that the E-Boot bootloader supplied by Toradex is not the only one that can update the CPLD firmware on the Colibri PXA320 board anymore.
Toradex provided me with the information on how the CPLD JTAG is connected to the CPU GPIO pins and an xsvf file for the CPLD containing the latest version of the CPLD firmware. And by using an xsvf player that I found is already in U-Boot and used on some PowerPC platforms, I was able to reprogram the CPLD to the latest version v1.7 of the CPLD firmware.
The xsvf player needed some obvious changes to operate the GPIO-emulated JTAG correctly, but the code is well abstracted and I think I'll make it into a generic code soon. Currently there are two copies of the same code in my U-Boot tree, which is no good. Note that the v1.7 of the CPLD firmware is probably some internal testing version from Toradex and I still have to ask them about the license for that file. It'd be best of they just put this xsvf file on their website.
Still, this is not the end. Because I wanted to use CF memory card on the Toradex PXA320 board, I decided to start implementing the PXA320 PCMCIA support. I first had to patch the pxa2xx_base to support different locations of the Static Memory controller registers, the MCIO, MCATT, MCMEM and MECR registers. That was the easier part.
After a bit of struggling with the Toradex CPLD and GPIO pin configuration and muxing, which is doing some obscure stuff to the PCMCIA signals, I managed to get the PCMCIA partly working. Note the struggle means I was stuck with it for more than a two days until I figured out what Toradex actually did. Their tech support on the other hand is very good and helpful even if a little bit slow, I'm happy about this.
The partly working above means, that if I insert a Marvell CF8385 into the CF slot, the card is detected, firmware is downloaded and no problems observed. Once I insert a memory card though, nothing happens. The card insertion GPIO is asserted, but it probably reads zeroes or something from the CIS. This issue can actually be just about anything, starting from wrong timing to misconfigured GPIOs. The more confusing thing here is that if I insert an Emtec or Patriot card, the card insertion is only detected. In case I insert a SanDisk card, the pata_pcmcia driver is loaded, but in the end, the disk is not recognized.
The cluster
You might have noticed the hardware kind of started piling up. That's true, but it's not unused actually. I use the boards that are in good shape software- and hardware-wise as an ARM compile cluster nodes. I run distcc on these and use it to build Debian packages. It's also an awesome stability testing and bug hunting mechanism for these platforms.
The cluster is still growing, but currently there are these machines:
- Palm Tungsten|C
- PXA255 400MHz
- 64MB RAM
- 1GB MMC+ card
- USB CDC Ethernet
- Debian SID
- Voipac PXA270
- PXA270C5 520MHz
- 128MB RAM
- 2GB SD card
- Ethernet connection
- Debian SID
- Voipac PXA270
- PXA270C5 520MHz
- 256MB RAM
- 160GB harddrive
- Ethernet connection
- Debian SID
- Balloon3
- PXA270C0 520MHz
- 384MB RAM
- 1GB NAND + 4GB CF card
- USB Ethernet connection
- Debian SID
Other
Just a few days ago, Mike Rapoport aranged it so I received a CM-X300 board. I was still unable to replace the bootloader there as I still don't have JTAG connected to that board.
I also started plumbing into the Debian u-boot package and prepared a patch. The problem is the current maintainer is totally ignoring any requests from me so far. I hope it's just temporary as he was busy with organising the debconf.
I hope you enjoyed reading the text.
Friday, July 9, 2010
Marvell Zylonite PXA300
Just a quick entry concerning OpenPXA today. In need for some rest, I hacked on the Marvell Zylonite PXA300 board I got some time ago. It is currently supported by the OpenPXA OBM2 as well as U-Boot (u-boot-pxa -openpxa).
I also tested the new SDHC capable PXAMCI driver I recently added to U-Boot on PXA300. It works if I disabled the High-Speed support, which is a new feature on PXA3xx where the card runs at 26 MHz. I think that it's just some really simple problem, maybe miscomputation of the clock speed or something, but I'll analyze that later. For now, I use the old driver on pxa3xx.
I'll also need to sort out the PXA3xx branch of U-Boot (the -openpxa branch), as the mess there starts being bigger and bigger. Once that's done and I have the Zylonite PXA320 fixed, I'll start pushing this stuff into mainline U-Boot.
Not to forget a quick summary of other happenings, I added LCD support to ZipitZ2 U-Boot port. That also implies a SPI interface, which I did using the softspi (GPIO driven SPI) driver. Lastly, I started pushing the PXA2xx fixes and improvements into mainline U-Boot.
I also tested the new SDHC capable PXAMCI driver I recently added to U-Boot on PXA300. It works if I disabled the High-Speed support, which is a new feature on PXA3xx where the card runs at 26 MHz. I think that it's just some really simple problem, maybe miscomputation of the clock speed or something, but I'll analyze that later. For now, I use the old driver on pxa3xx.
I'll also need to sort out the PXA3xx branch of U-Boot (the -openpxa branch), as the mess there starts being bigger and bigger. Once that's done and I have the Zylonite PXA320 fixed, I'll start pushing this stuff into mainline U-Boot.
Not to forget a quick summary of other happenings, I added LCD support to ZipitZ2 U-Boot port. That also implies a SPI interface, which I did using the softspi (GPIO driven SPI) driver. Lastly, I started pushing the PXA2xx fixes and improvements into mainline U-Boot.
Wednesday, June 30, 2010
U-Boot: PXA SDHC support
Today, it'll be just a quick entry about a recent achievement in the U-Boot land. I was reported by some people from the Zipit Z2 project that U-Boot doesn't detect their SDHC cards. That was really troublesome and so was the state of the pxa_mmc driver in U-Boot.
Actually, pxa_mmc was probably the last SD/MMC driver in U-Boot that used the old driver interface there. I decided it needs a rewrite. I based the new code on the Linux version of pxa_mmc driver. The resulting pxa_mmc_gen.c now uses the generic SD/MMC framework in U-Boot and the code is much more cleaner. It also supports SDHC well. And one more benefit is that the timing issues that were observed with the old driver are gone now.
The code wasn't merged mainline yet and is currently held as a separate driver to make the transition from the old driver to the new one as smooth as possible. Also, I'd like the driver to get some testing before some other boards are converted to use it.
The code is currently available in the u-boot-pxa.git -devel branch. Also, it was submitted to the u-boot mailing list. To enable the new driver, you'll have to replace
#define CONFIG_GENERIC_MMC
#define CONFIG_PXA_MMC_GENERIC
And recompile the U-Boot.
To use the new driver, you can use commands like:
$ mmcinfo
$ fatls mmc 0
etc. Note, that the "mmcinfo" command is new and the old "mmc" command class is gone. So no "mmc init" anymore.
Actually, pxa_mmc was probably the last SD/MMC driver in U-Boot that used the old driver interface there. I decided it needs a rewrite. I based the new code on the Linux version of pxa_mmc driver. The resulting pxa_mmc_gen.c now uses the generic SD/MMC framework in U-Boot and the code is much more cleaner. It also supports SDHC well. And one more benefit is that the timing issues that were observed with the old driver are gone now.
The code wasn't merged mainline yet and is currently held as a separate driver to make the transition from the old driver to the new one as smooth as possible. Also, I'd like the driver to get some testing before some other boards are converted to use it.
The code is currently available in the u-boot-pxa.git -devel branch. Also, it was submitted to the u-boot mailing list. To enable the new driver, you'll have to replace
#define CONFIG_PXA_MMC
with#define CONFIG_GENERIC_MMC
#define CONFIG_PXA_MMC_GENERIC
And recompile the U-Boot.
To use the new driver, you can use commands like:
$ mmcinfo
$ fatls mmc 0
etc. Note, that the "mmcinfo" command is new and the old "mmc" command class is gone. So no "mmc init" anymore.
Monday, June 21, 2010
OpenPXA: first release
The OpenPXA project proudly released first beta version of the bootloader package for PXA3xx. The package supports the following boards:
The package contains the OpenPXA OBM2 and U-Boot bootloader binaries for the boards as well as installation instructions. The package can be downloaded from the OpenPXA website.
- Toradex Colibri PXA300
- Toradex Colibri PXA310
- Toradex Colibri PXA320
- Marvell Littleton PXA310
The package contains the OpenPXA OBM2 and U-Boot bootloader binaries for the boards as well as installation instructions. The package can be downloaded from the OpenPXA website.
Subscribe to:
Posts (Atom)