On 03/11/15 21:45, Gabriel L. Somlo wrote: > On Wed, Mar 11, 2015 at 07:50:40PM +0100, Laszlo Ersek wrote: >> On 03/11/15 16:27, Gabriel L. Somlo wrote: >>> Hi, >>> >>> I'm looking for the closest thing to an official spec for qemu's >>> fw_cfg device, and so far I have found this: >>> >>> http://lists.gnu.org/archive/html/qemu-devel/2011-04/msg00238.html >>> >>> but it apparently never got committed to qemu (any idea why not?). >> >> Must have fallen through the cracks. (Just speculating; in April 2011 I >> had been with RH for less than half a year, and learning Xen. :)) >> >>> Googling around didn't get me much further than that. >>> >>> Is there anything better or more up to date floating around out >>> there somewhere ? >> >> I won't say "better", but it is "committed": check >> "Documentation/devicetree/bindings/arm/fw-cfg.txt" in the kernel tree. >> It is intentionally vague on the set of keys and fw_cfg files that qemu >> provides, because that's a moving target. You can only rely on the qemu >> source for those. > > The fw_cfg interface from the guest's perspective is pretty > straightforward: select something on the control port, read a blob > from the data port. > > I was more interested in the "hardware" implementation details, > and the reasoning behind them. > > For instance, I get there's a total of 0x30 entries > (FWCfgEntry entries), the last 0x10 of which have > "file names" and are referenced from the "FWCfgFiles *files" > structure. > > I don't quite get the part where > > struct FWCfgState { > ... > FWCfgEntry entries[2][FW_CFG_MAX_ENTRY]; > ... > } > > is accessed via > > int arch = !!(key & FW_CFG_ARCH_LOCAL); > ... > s->entries[arch][key].foo = ... > > I.e., what's the significance of arch==0 vs. arch==1 ?
Well, from that aborted :) text file of mine: > The client writes a 16-bit wide selector to the control port. The most > significant bit (FW_CFG_ARCH_LOCAL) selects the namespace: 0 > corresponds to "generic" namespace, while 1 corresponds to > "architecture specific" namespace. Jordan had also dedicated a paragraph to Bit15 in his patch that you linked above. > Also, what's the significance of handling guest-initiated writes to > the data port ? Could the guest write larger chunks of data than the > current size of the selected entry ? No. Again, from that aborted text file: > The client code writes a selector (a key) to the control port, and > then can read the corresponding data (produced by qemu-kvm) via the > data port, or, if the selected entry is writable, rewrite it. If > qemu-kvm has associated a callback with the entry: when the entry is > completely rewritten, qemu-kvm runs the callback. This way the client > code can exchange data with and even invoke functions in qemu-kvm. > Would the selected entry's size > grow accordingly ? Would it shrink if the guest (over)wrote less than > the current size ? No. Please see the fw_cfg_write() function. Only the same size can be written, and the write callback runs when that's completed. In any case, I'm unaware of *any* instance when an fw_cfg blob is rewritten by the guest. In fact, such *write* callbacks are registered in qemu with fw_cfg_add_callback(), and I can't see any calls to that function. It's dead code, apparently. (fw_cfg_add_file_callback() is different; it is much more recent, and it is for read callbacks.) > I know it's all going to start making sense eventually, if I stare at > the source long enough :) I'm just trying to speed up that process as > much as possible. > > Right now, at a quick glance, qemu writes a bunch of stuff into the > fw_cfg data structure before starting the guest, and the guest (well, > mostly the guest's BIOS) does a bunch of things based on the > "breadcrumbs" it reads from the fw_cfg device. > > But that doesn't seem to be the whole story... It is pretty close; it's almost the whole story, as far as I'm aware. What more should an interface called "firmware config" do than, well, configure the firmware? :) (Even -kernel / -initrd / -append abuse the original intent of fw_cfg, because those blobs are huge, and not configuration-like at all. But they got popular and now we're stuck with them; higher level tools depend on them heavily.) There is though a bit more to the story: the (recent) read callbacks. Qemu sometimes decides to re-generate a "bunch of stuff" in the fw_cfg blobs. See the commit message here: https://github.com/tianocore/edk2/commit/66b280df (The edk2 patch visible in that commit has been completely reimplemented since, but the qemu description in the commit *message* remains valid.) >> If you have a ton of time, you could try documenting fw_cfg yourself, >> but as I said, it's a moving target, so the description would either >> become stale quickly, or require people to keep it in sync with the >> source all the time. Updating documentation sucks *hard*. > > Once I start getting what's going on (e.g., w.r.t. the questions above) > I wouldn't mind just adding *comments* to the source, for the next guy > who, like me, is trying to get the lay of the land, but I'm not there > yet... I believe that would be useful, yes. Thanks Laszlo