Monday, October 27, 2008

LCD driver done?

I had a lot of trouble getting the LCD driver to work. Everything seems to be fine except that when I try to write to the memory address range reserved for the LCD's gamma tables, it doesn't register. It's as if some clock or some device hadn't gotten turned on or something. Therefore, after loading openiboot from iBoot, the screen gets all screwed up.

However, if you load iBEC from iBoot, the screen doesn't get screwed up: you can still use bgcolor and everything works. I thought that meant at first there was something wrong with my LCD init code. I spent a frustrating day carefully auditing it for errors, and I did find two bugs that I fixed, but unfortunately it did not have any effect on the main problem. I got as far as I could with static methods so I decided to perform a series of experiments.

First, I had some trouble chainloading iBoot and iBEC from openiboot. There was a series of fails that I fixed along the way: trouble with USB send (just a silly typo in the client), trouble getting the resulting thing to execute in memory (you've gotta turn off the CPU caches, disable MMU and interrupts for it to work properly. It also can't be run as part of an ISR because, well, iBoot expects to be able to receive interrupts, so I had to move the command processor onto the main thread and just have the ISR queue up commands for the main thread to process). Anyway, those were eventually fixed.

My experiments showed that after openiboot did its inits, chainloaded iBoot and iBEC was unable to reinit the LCD properly (they had the same problem). I narrowed the problem down to the place in power.c where I "turn off" the LCD controller. This happened in the 114 iBoot, so I thought it was necessary. Analyzing the newer 2.x iBoots, that routine was actually removed. Since I am reasonably confident that my syrah_init is functionally identical to their merlot_init and this that power init that when present, causes LCD init to fail in all cases and when absent, allows LCD init to succeed in all cases, I'm pretty sure that's the problem.

So I went ahead and removed it. This may or may not mean I am actually depending on the iBoot that I chainloaded openiboot from for the LCD init. We'll see after I try to replace iBoot entirely in the bootchain.

Anyway, USB is solid as a rock now seemingly and chainloading seems to be working quite well. I'm actually able to load iBoot from NOR, patch it in memory, and then execute it from openiboot. This probably means I'm ready to try flashing the thing again.

Then we'll see how well it truly works.