The way the bootroms work is immutable, but that really only affects the way the first bit of firmware is loaded. After that we do the loading, and we can do it however we like. As far as how that interacts with CBFS, that's really a question of how the CBFS driver attaches to the driver that talks to the underlying media, typically SPI flash but sometimes not, and not how the bootrom loads the initial bit of firmware.

I think the division between the CBFS code and the underlying driver isn't very clean (as I detailed in my reply on the other thread), but besides that it seems entirely reasonable to come up with a consistent scheme for how to talk to drivers. For instance, my simplistic understanding of the Linux driver model is that there are character drivers and block drivers which seems like a reasonable place to start.

As far as the Exynos SPI controller, you can tell it to do things in 1, 2 or 4 byte chunks, but the driver always sets it to use 4 bytes. That doesn't imply a 4 byte alignment so much as it forces you to send/receive data in a size that's a multiple of 4. The driver could be smarter and figure out what size to use, but practically it hasn't been necessary in coreboot. The driver in depthcharge works that way, however, and that could be ported back to coreboot.

Another thing to consider is how to handle multiple instances of the same type of device. You can assume there's only one and configure it's parameters with kconfig (how serial works, I think). You can define a well known ordering for the controllers and define an array of properties in the driver or elsewhere, and then specify which one you're talking to when calling driver functions (how i2c works). You can define a structure to describe each instance of the hardware for configuration (partially how depthcharge works).

Similarly, you'll need to decide how to handle multiple drivers which control the same type of hardware. There's the fairly simplistic approach of having i2c_read() and i2c_write() in the global namespace and those being linked against the right driver. That doesn't really let you have multiple drivers unless you have a front end which figures out based on, say, the bus id (i2c on the 5420). Alternatively, you can have a structure with function pointers in it which lets you have multiple independent drivers.

The model I went with in depthcharge is to have a structure which has function pointers in it which is common and which is embedded in a larger structure which has the parameters for the driver. When the drivers functions are called they're passed the common structure and they use math to find the larger structure which has their parameters. I set up those structures manually in a C function which is called at startup, but in coreboot we could use that device tree instead. I definitely wouldn't say the model I'm using is perfect, but it's worked well for me and could be a useful point to start discussion. The code is over here if you'd like to see it in use:

https://chromium.googlesource.com/chromiumos/platform/depthcharge/+/master

Gabe


On Fri, Jan 10, 2014 at 4:09 PM, mrnuke <mr.nuke.me@gmail.com> wrote:
On 01/10/2014 05:05 PM, Gabe Black wrote:
> It really depends on how that blob built into the SOC works. On the
> Tegra chips and on the SOC in the Beaglebone, the amount that's loaded
> depends on a data structure bundled in with the firmware. On the
> Beaglebone I told it to load enough of CBFS that it could get the ROM
> stage out of SRAM without having to talk to the boot media again.
> Anything beyond that, though, would require talking to the media. On
> Exynos the blob on the SOC loads another fixed size Samsung provided
> blob from the boot media which then loads the actual firmware. There it
> depends on how that blob works. Sometimes the blob loads a fixed size
> chunk, and sometimes it loads a variably sized blob which is described
> in a small header. I think the blobs we have in the coreboot repository
> are one of each, fixed size for the 5250 and variably sized for the 5420.
>
Gabe, that's the perfect example. We have a different way for each chip
because "it really depends on how that blob built into the SOC works".
Is that really the case? Every time there's a new ARM SoC we have to
reinvent CBFS loading. That sounds wrong. Ron was talking about a
unified approach. I think it's time we start doing that now, before it
gets messy.

Re Exynos, the SPI code imposes an alignment of 4 bytes. It's cleverly
hidden, but that is a little block device logic nonetheless.

Alex