Re: [PATCH 10/16] hw/i3c/aspeed_i3c: Add IBI handling
Hi Joe, > +static int aspeed_i3c_device_ibi_finish(I3CBus *bus) > +{ > + AspeedI3CDevice *s = ASPEED_I3C_DEVICE(bus->qbus.parent); > + bool nack_and_disable_hj = ARRAY_FIELD_EX32(s->regs, DEVICE_CTRL, > + HOT_JOIN_ACK_NACK_CTRL); > + if (nack_and_disable_hj || s->ibi_data.send_direct_disec) { > + aspeed_i3c_device_send_disec(s); > + } Shouldn't this be conditional on the ibi being a HJ request? With this, I'm seeing the DISEC happen on *all* IBIs. Cheers, Jeremy
Re: [PATCH 14/16] hw/i3c: remote_i3c: Add model
Hi Joe, > > 1) Is this something that qemu upstream would accept? Do we need a > > formal description of the guest-to-host interface somewhere? Or is there > > a more standard way of exposing busses like this? > > > Not sure! I'm open to ideas. > I think the most controversial portion of the remote target like this > might be doing socket transfers in an MMIO context. > i.e. driver does a write to I3C controller -> triggers a transaction > to remote target -> remote target sends/reads data over socket. > > Because of that, we might need to add a way to do these transactions > asynchronously. OK, that plus the general concept of having a socket interface to the i3c bus might need a review from someone above my qemu pay-grade. but, on the assumption that those are acceptable in general: > > Assuming we do adopt your approach though, I think the protocol > > description needs some work. There seems to be other messages not listed > > in your protocol comments, and the direction of some seems to be > > reversed. I'm happy to contribute to that documentation if you like. > > Oops. I'll reread and revise in v2. If you have anything else you want > to add too, let me know and I'll add them as well. So I implemented a little daemon for the other side of the socket interface. I have a few thoughts on the protocol structure: * can we change the target -> controller read response messages (data + len) into a normal message type (ie, assign an opcode and use that in the header)? We may want to use separate opcodes for each response type. * I would suggest expanding the start behaviour a little: the message could contain the target address, and the target responds with an ACK/NACK event. The model would need to block on the response in order to return the correct ACK/NACK value (and pass to the hardware), but this means we can either implement the protocol at the bus level, or at the individual-device level. (with the current standalone NACK event, I don't see how a model could reliably handle that) * I'm not clear on why the RemoteI3CRXEvents are defined separately. Can these just be normal messages with an opcode (and no payload)? I've yet to implement IBIs though, that's next on my list. Happy to chat separately if this gets off-topic for the qemu general discussion. Overall though, this is great work! Thanks for the contributions. Cheers, Jeremy
Re: [PATCH 00/16] i3c: aspeed: Add I3C support
Hi Joe, > > > Jeremy, how different is it ? Could we introduce properties or sub > > > classes, to support both. > > > > The differences (at least from the view of the current Linux driver > > implementation) are very minor; unless we want to be errata-compatible, > > you could use the dw driver directly, plus the ast2600-specific global > > register space. > > > > This is my understanding as well from an outside look. > From a QEMU standpoint I could split off the dwc portion into a > dwc_i3c model, which the aspeed_i3c portion inherits from. I can do > that in a v2 if that sounds good with everyone. I'm not a qemu maintainer, but for the record: I'm fine with the current approach. I don't have access to any of the non-aspeed dw documentation, so verifying what should go into the dw model vs. what is ast2600-specific has been a bit tricky. If someone needs a non-aspeed dw model, and has a bit of documentation about the underlying dw hardware, it should be easy enough to split back out. Maybe just make sure any "known" divergences - like the IBI PEC behaviour - are well commented. That said, if you're keen to do the split dw+aspeed models, that's also good :) Cheers, Jeremy
Re: [PATCH 09/16] hw/i3c/aspeed_i3c: Add data TX and RX
Hi Joe, > +static uint8_t aspeed_i3c_device_target_addr(AspeedI3CDevice *s, > + uint16_t offset) > +{ > + if (offset > ASPEED_I3C_NR_DEVICES) { > + qemu_log_mask(LOG_GUEST_ERROR, "%s: Device addr table offset %d out > of " > + "bounds\n", object_get_canonical_path(OBJECT(s)), > offset); > + /* If we're out of bounds, return an address of 0. */ > + return 0; > + } > + > + uint16_t dev_index = R_DEVICE_ADDR_TABLE_LOC1 + offset; > + /* I2C devices use a static address. */ > + if (aspeed_i3c_device_target_is_i2c(s, offset)) { > + return FIELD_EX32(s->regs[dev_index], DEVICE_ADDR_TABLE_LOC1, > + DEV_STATIC_ADDR); > + } > + return FIELD_EX32(s->regs[dev_index], DEVICE_ADDR_TABLE_LOC1, > + DEV_DYNAMIC_ADDR); > +} Depending on the usage of this function, you'll probably want to mask out the parity bit (the msb) from the DEV_DYNAMIC_ADDR field. Currently, you're returning this value directly from the ENTDAA handler, which is ending up assigning addresses with the high bit set. (doing a bit of a piecemeal review here, as I'm testing out the model...) Cheers, Jeremy
Re: [PATCH 14/16] hw/i3c: remote_i3c: Add model
Hi Joe, > Adds a model to communicate to remote I3C devices over chardev. This > allows QEMU to communicate to I3C targets that exist outside of QEMU. Nice! I've been wanting something similar for a while, both for i2c and i3c busses, to the point of having a similar concept partly implemented. A couple of design decisions though: 1) Is this something that qemu upstream would accept? Do we need a formal description of the guest-to-host interface somewhere? Or is there a more standard way of exposing busses like this? 2) My approach was at the bus level rather than the device level: the protocol is bidirectional to allow the model to either participate as a i3c controller or a target. There's quite a bit of mis-fit when applying that to the qemu device structure though, so your approach is a lot cleaner. I'll have a go at adapting my client to your protocol, and see how the device interface goes. Assuming we do adopt your approach though, I think the protocol description needs some work. There seems to be other messages not listed in your protocol comments, and the direction of some seems to be reversed. I'm happy to contribute to that documentation if you like. Cheers, Jeremy
Re: [PATCH 10/16] hw/i3c/aspeed_i3c: Add IBI handling
Hi Joe, First up, nice work with this series! I haven't yet had a thorough look at the series, but one item on something that caught me up on the Linux side: > +static void aspeed_i3c_device_ibi_queue_push(AspeedI3CDevice *s) > +{ > + /* Stored value is in 32-bit chunks, convert it to byte chunks. */ > + uint8_t ibi_slice_size = aspeed_i3c_device_ibi_slice_size(s); > + uint8_t num_slices = fifo8_num_used(>ibi_data.ibi_intermediate_queue) > / > + ibi_slice_size; > + uint8_t ibi_status_count = num_slices; > + union { > + uint8_t b[sizeof(uint32_t)]; > + uint32_t val32; > + } ibi_data = { > + .val32 = 0 > + }; > + > + /* The report was suppressed, do nothing. */ > + if (s->ibi_data.ibi_nacked && !s->ibi_data.notify_ibi_nack) { > + ARRAY_FIELD_DP32(s->regs, PRESENT_STATE, CM_TFR_ST_STATUS, > + ASPEED_I3C_TRANSFER_STATE_IDLE); > + ARRAY_FIELD_DP32(s->regs, PRESENT_STATE, CM_TFR_STATUS, > + ASPEED_I3C_TRANSFER_STATUS_IDLE); > + return; > + } > + > + /* If we don't have any slices to push, just push the status. */ > + if (num_slices == 0) { > + s->ibi_data.ibi_queue_status = > + FIELD_DP32(s->ibi_data.ibi_queue_status, IBI_QUEUE_STATUS, > + LAST_STATUS, 1); > + fifo32_push(>ibi_queue, s->ibi_data.ibi_queue_status); > + ibi_status_count = 1; > + } > + > + for (uint8_t i = 0; i < num_slices; i++) { > + /* If this is the last slice, set LAST_STATUS. */ > + if (fifo8_num_used(>ibi_data.ibi_intermediate_queue) < > + ibi_slice_size) { > + s->ibi_data.ibi_queue_status = > + FIELD_DP32(s->ibi_data.ibi_queue_status, IBI_QUEUE_STATUS, > + IBI_DATA_LEN, > + > fifo8_num_used(>ibi_data.ibi_intermediate_queue)); > + s->ibi_data.ibi_queue_status = > + FIELD_DP32(s->ibi_data.ibi_queue_status, IBI_QUEUE_STATUS, > + LAST_STATUS, 1); > + } else { > + s->ibi_data.ibi_queue_status = > + FIELD_DP32(s->ibi_data.ibi_queue_status, IBI_QUEUE_STATUS, > + IBI_DATA_LEN, ibi_slice_size); > + } > + > + /* Push the IBI status header. */ > + fifo32_push(>ibi_queue, s->ibi_data.ibi_queue_status); > + /* Move each IBI byte into a 32-bit word and push it into the queue. > */ > + for (uint8_t j = 0; j < ibi_slice_size; ++j) { > + if (fifo8_is_empty(>ibi_data.ibi_intermediate_queue)) { > + break; > + } > + > + ibi_data.b[j & 3] = > fifo8_pop(>ibi_data.ibi_intermediate_queue); > + /* We have 32-bits, push it to the IBI FIFO. */ > + if ((j & 0x03) == 0x03) { > + fifo32_push(>ibi_queue, ibi_data.val32); > + ibi_data.val32 = 0; > + } > + } You'll probably want to handle the IBI_PEC_EN DAT field when pushing the IBI to the fifo here. Due to a HW errata, the driver will *always* need to enable PEC_EN. In cases where the remote isn't actually sending a PEC, this will consume the last byte of the IBI payload (and probably cause a PEC error, which the driver needs to ignore). See here for the driver side, in patches 4/5 and 5/5: https://lore.kernel.org/linux-i3c/d5d76a8d2336d2a71886537f42e71d51db184df6.1680161823.git...@codeconstruct.com.au/T/#u Cheers, Jeremy
Re: [PATCH 00/16] i3c: aspeed: Add I3C support
Hi Cédric, > > Isn't this the designware i3c ip block, and as such could we name > > it so? > > Currently, QEMU only has a model for a dummy Aspeed I3C variant so > this is a great addition. [...] > According to recent work on the kernel, it is indeed based on > designware I3C : > > https://lore.kernel.org/all/20230331091501.3800299-1...@codeconstruct.com.au/ > > Jeremy, how different is it ? Could we introduce properties or sub > classes, to support both. The differences (at least from the view of the current Linux driver implementation) are very minor; unless we want to be errata-compatible, you could use the dw driver directly, plus the ast2600-specific global register space. Cheers, Jeremy
Re: [PATCH RFC 2/3] hw/i2c: add mctp core
Hi Klaus, > I had to reverse the target mode functionality in QEMU from the linux > driver, so I am really not too sure if having START and STOP set in > the interrupt register is allowed behavior or not >From my interpretation of things, there's nothing explicitly preventing both a pending start and stop - more that the interrupt is very likely to have been serviced between those two events on the kind of speeds we would see on the i2c bus. I guess we could try (temporarily) masking the irq on real hardware and see what happens? :D Cheers, Jeremy
Re: [PATCH RFC 2/3] hw/i2c: add mctp core
Hi Klaus, > With those changes, I can get control protocol going, and multi- > packet messages work. Ah, I also needed a change to the aspeed I2C driver, as I'm seeing the interrupt handler being invoked with both a stop and a start event pending. Patch below; if this seems sensible I will propose upstream. Cheers, Jeremy --- >From 6331cf2499c182606979029d2aaed93ee3e544fa Mon Sep 17 00:00:00 2001 From: Jeremy Kerr Date: Fri, 18 Nov 2022 14:04:50 +0800 Subject: [PATCH] i2c: aspeed: Allow combined STOP & START irqs Currently, if we enter our interrupt handler with both a stop and start condition pending, the stop event handler will override the current state, so we'll then lose the start condition. This change handles the stop condition before anything else, which means we can then restart the state machine on any pending start state. Because of this, we no longer need the ASPEED_I2C_SLAVE_STOP state, because we're just reverting directly to INACTIVE. I have only seen this condition on emulation; it may be impossible to hit on real HW. Signed-off-by: Jeremy Kerr --- drivers/i2c/busses/i2c-aspeed.c | 23 --- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/drivers/i2c/busses/i2c-aspeed.c b/drivers/i2c/busses/i2c-aspeed.c index 185dedfebbac..45f2766b2b66 100644 --- a/drivers/i2c/busses/i2c-aspeed.c +++ b/drivers/i2c/busses/i2c-aspeed.c @@ -135,7 +135,6 @@ enum aspeed_i2c_slave_state { ASPEED_I2C_SLAVE_READ_PROCESSED, ASPEED_I2C_SLAVE_WRITE_REQUESTED, ASPEED_I2C_SLAVE_WRITE_RECEIVED, - ASPEED_I2C_SLAVE_STOP, }; struct aspeed_i2c_bus { @@ -250,6 +249,14 @@ static u32 aspeed_i2c_slave_irq(struct aspeed_i2c_bus *bus, u32 irq_status) command = readl(bus->base + ASPEED_I2C_CMD_REG); + /* handle a stop before starting any new events */ + if (bus->slave_state != ASPEED_I2C_SLAVE_INACTIVE && + irq_status & ASPEED_I2CD_INTR_NORMAL_STOP) { + irq_handled |= ASPEED_I2CD_INTR_NORMAL_STOP; + i2c_slave_event(slave, I2C_SLAVE_STOP, ); + bus->slave_state = ASPEED_I2C_SLAVE_INACTIVE; + } + /* Slave was requested, restart state machine. */ if (irq_status & ASPEED_I2CD_INTR_SLAVE_MATCH) { irq_handled |= ASPEED_I2CD_INTR_SLAVE_MATCH; @@ -278,15 +285,11 @@ static u32 aspeed_i2c_slave_irq(struct aspeed_i2c_bus *bus, u32 irq_status) irq_handled |= ASPEED_I2CD_INTR_RX_DONE; } - /* Slave was asked to stop. */ - if (irq_status & ASPEED_I2CD_INTR_NORMAL_STOP) { - irq_handled |= ASPEED_I2CD_INTR_NORMAL_STOP; - bus->slave_state = ASPEED_I2C_SLAVE_STOP; - } if (irq_status & ASPEED_I2CD_INTR_TX_NAK && bus->slave_state == ASPEED_I2C_SLAVE_READ_PROCESSED) { irq_handled |= ASPEED_I2CD_INTR_TX_NAK; - bus->slave_state = ASPEED_I2C_SLAVE_STOP; + i2c_slave_event(slave, I2C_SLAVE_STOP, ); + bus->slave_state = ASPEED_I2C_SLAVE_INACTIVE; } switch (bus->slave_state) { @@ -316,13 +319,11 @@ static u32 aspeed_i2c_slave_irq(struct aspeed_i2c_bus *bus, u32 irq_status) case ASPEED_I2C_SLAVE_WRITE_RECEIVED: i2c_slave_event(slave, I2C_SLAVE_WRITE_RECEIVED, ); break; - case ASPEED_I2C_SLAVE_STOP: - i2c_slave_event(slave, I2C_SLAVE_STOP, ); - bus->slave_state = ASPEED_I2C_SLAVE_INACTIVE; - break; case ASPEED_I2C_SLAVE_START: /* Slave was just started. Waiting for the next event. */; break; + case ASPEED_I2C_SLAVE_INACTIVE: + break; default: dev_err(bus->dev, "unknown slave_state: %d\n", bus->slave_state); -- 2.35.1
Re: [PATCH RFC 2/3] hw/i2c: add mctp core
Hi Klaus, > Add an abstract MCTP over I2C endpoint model. This implements MCTP > control message handling as well as handling the actual I2C transport > (packetization). > > Devices are intended to derive from this and implement the class > methods. Looks good, nice to see how it's used by the nmi device later too. A couple of issues with the state machine though, comments inline, and a bit of a patch below. > +static void i2c_mctp_tx(void *opaque) > +{ > + DeviceState *dev = DEVICE(opaque); > + I2CBus *i2c = I2C_BUS(qdev_get_parent_bus(dev)); > + I2CSlave *slave = I2C_SLAVE(dev); > + MCTPI2CEndpoint *mctp = MCTP_I2C_ENDPOINT(dev); > + MCTPI2CEndpointClass *mc = MCTP_I2C_ENDPOINT_GET_CLASS(mctp); > + MCTPI2CPacket *pkt = (MCTPI2CPacket *)mctp->buffer; > + uint8_t flags = 0; > + > + switch (mctp->tx.state) { > + case I2C_MCTP_STATE_TX_SEND_BYTE: > + if (mctp->pos < mctp->len) { > + uint8_t byte = mctp->buffer[mctp->pos]; > + > + trace_i2c_mctp_tx_send_byte(mctp->pos, byte); > + > + /* send next byte */ > + i2c_send_async(i2c, byte); > + > + mctp->pos++; > + > + break; > + } > + > + /* packet sent */ > + i2c_end_transfer(i2c); If we're sending a control message, mctp->len will be set to the control msg len here, then: > + > + /* fall through */ > + > + case I2C_MCTP_STATE_TX_START_SEND: > + if (mctp->tx.is_control) { > + /* packet payload is already in buffer */ > + flags |= MCTP_H_FLAGS_SOM | MCTP_H_FLAGS_EOM; > + } else { > + /* get message bytes from derived device */ > + mctp->len = mc->get_message_bytes(mctp, pkt->mctp.payload, > + I2C_MCTP_MAXMTU, ); > + } ... it doesn't get cleared above, so: > + > + if (!mctp->len) { ... we don't hit this conditional, and hence keep sending unlimited bytes. This presents as continuous interrupts to the aspeed i2c driver when replying to any control message. I think we need a mctp->len = 0 with the i2c_end_transfer(). With that, I can get control protocol communication working with mctpd. > +static int i2c_mctp_event_cb(I2CSlave *i2c, enum i2c_event event) > +{ > + MCTPI2CEndpoint *mctp = MCTP_I2C_ENDPOINT(i2c); > + MCTPI2CEndpointClass *mc = MCTP_I2C_ENDPOINT_GET_CLASS(mctp); > + MCTPI2CPacket *pkt = (MCTPI2CPacket *)mctp->buffer; > + size_t payload_len; > + uint8_t pec; > + > + switch (event) { > + case I2C_START_SEND: > + if (mctp->state != I2C_MCTP_STATE_IDLE) { > + return -1; mctp->state may (validly) be I2C_MCTP_STATE_RX here, if we're receiving the start event for the second packet of a multi-packet message. > + } > + > + /* the i2c core eats the slave address, so put it back in */ > + pkt->i2c.dest = i2c->address << 1; > + mctp->len = 1; > + > + mctp->state = I2C_MCTP_STATE_RX_STARTED; > + > + return 0; > + > + case I2C_FINISH: > + payload_len = mctp->len - (1 + offsetof(MCTPI2CPacket, > mctp.payload)); > + > + if (pkt->i2c.byte_count + 3 != mctp->len - 1) { > + trace_i2c_mctp_drop_invalid_length(pkt->i2c.byte_count + > 3, > + mctp->len - 1); > + goto drop; > + } > + > + pec = i2c_smbus_pec(0, mctp->buffer, mctp->len - 1); > + if (mctp->buffer[mctp->len - 1] != pec) { > + trace_i2c_mctp_drop_invalid_pec(mctp->buffer[mctp->len - 1], > pec); > + goto drop; > + } > + > + if (pkt->mctp.hdr.eid.dest != mctp->my_eid) { > + trace_i2c_mctp_drop_invalid_eid(pkt->mctp.hdr.eid.dest, > + mctp->my_eid); > + goto drop; > + } > + > + if (pkt->mctp.hdr.flags & MCTP_H_FLAGS_SOM) { > + mctp->tx.is_control = false; > + > + if (mctp->state == I2C_MCTP_STATE_RX) { > + mc->reset_message(mctp); > + } > + > + mctp->state = I2C_MCTP_STATE_RX; > + > + mctp->tx.addr = pkt->i2c.source; > + mctp->tx.eid = pkt->mctp.hdr.eid.source; > + mctp->tx.flags = pkt->mctp.hdr.flags & 0x7; > + mctp->tx.pktseq = (pkt->mctp.hdr.flags >> 4) & 0x3; > + > + if ((pkt->mctp.payload[0] & 0x7f) == MCTP_MESSAGE_TYPE_CONTROL) { > + mctp->tx.is_control = true; > + > + i2c_mctp_handle_control(mctp); > + > + return 0; > + } > + } else if (mctp->state == I2C_MCTP_STATE_RX_STARTED) { > + trace_i2c_mctp_drop("expected SOM"); > + goto drop; > + } else if (((pkt->mctp.hdr.flags >> 4) & 0x3) != (mctp->tx.pktseq++ > & 0x3)) { The pktseq is the sequence number of the last packet seen, so you want a pre-increment there: ++mctp->tx.pktseq & 0x3 } else if
Re: [PATCH 0/3] hw/{i2c,nvme}: mctp endpoint, nvme management interface model
Hi Klaus, [+CC Matt] > This adds a generic MCTP endpoint model that other devices may derive > from. I'm not 100% happy with the design of the class methods, but > it's a start. Thanks for posting these! I'll have a more thorough look through soon, but wanted to tackle some of the larger design-points first (and we've already spoken a bit about these, but rehashing a little of that for others CCed too). For me, the big decision here is where we want to run the NVMe-MI device model. Doing it in the qemu process certainly makes things easier to set up, and we can just configure the machine+nvme-mi device as the one operation. The alternative would be to have the NVMe-MI model run as an external process, and not part of the qemu tree; it looks like Peter D is going for that approach with [1]. The advantage there is that we would be able to test against closer-to-reality "MI firmware" (say, a device vendor running their NVMe-MI firmware directly in another emulator? are folks interested in doing that?) The complexity around the latter approach will be where we split the processes, and arrange for IPC. [1] suggests at the i2c layer, but that does seem to have complexities with i2c controller model compatibility; we could certainly extend that to a "generic" i2c-over-something protocol (which would also be handy for other things), or go higher up and use MCTP directly as the transport (say, the serial binding over a chardev). The former would be more useful for direct firmware emulation. My interest is mainly in testing the software stack, so either approach is fine; I assume your interest is from the device implementation side? Cheers, Jeremy [1]: https://github.com/facebook/openbmc/blob/helium/common/recipes-devtools/qemu/qemu/0007-hw-misc-Add-i2c-netdev-device.patch
Re: who's using the ozlabs patchwork install for QEMU patches ?
Hi Greg, > > The standard process is to send me an email :) > > Is this standard process mentioned somewhere ? No, not really. I usually let the folks who request the project in the first place know though. > > You're wanting to add user 'groug' to the qemu project, is that > > correct? > > > > Yes. Thanks ! Sure thing, done! You should now have access to modify patch states in the qemu patchwork. If you'd prefer to work with patchwork from the command- line, check out the pwclient, git-pw and pwnm-sync tools, at: https://patchwork.readthedocs.io/en/latest/usage/clients/ Cheers, Jeremy
Re: who's using the ozlabs patchwork install for QEMU patches ?
Hi Alexey, > Jeremy or Stephen (cc-ing) do definitely know if there is a better > way. The standard process is to send me an email :) You're wanting to add user 'groug' to the qemu project, is that correct? Cheers, Jeremy
Re: [Qemu-devel] [PATCH v4 0/4] Add ASPEED AST2400 SoC and OpenPower BMC machine
Hi Andrew, > This patch series models enough of the ASPEED AST2400 ARM9 SoC[0] to > boot an aspeed_defconfig Linux kernel[1][2]. Specifically, the series > implements the ASPEED timer and VIC devices, integrates them into an > AST2400 SoC and exposes it all through a new opbmc2400 machine. The > device model patches only partially implement the hardware features of > the timer and VIC, again mostly just enough to boot Linux. Awesome! Nice to have these patches escaping the lab :) In terms of naming suggestions: I think this depends on what we're looking to emulate here. I see two options: The qemu platform becomes a "reference" for OpenPOWER bmc hardware, but doesn't necessarily align with an actual machine. In that case, something generic like opbmc- would make sense. On the other hand, if we'd like to create qemu platforms that represent actual machines (eg, the OpenPOWER "palmetto" machine), then -bmc would seem more appropriate. In this case, the machine name would be palmetto-bmc. No need to include the SoC name in that, as it's defined by the hardware implementation. I think the latter option may be more generally useful. Regards, Jeremy
Re: [Qemu-devel] tracking qemu-devel at patchwork.ozlabs.org
Hi Michael, We'd like to add Peter Maydellpeter.mayd...@linaro.org as an additional patchwork admin. Could you do this please? Sure thing, all done. Cheers, Jeremy
[Qemu-devel] Re: [RFC PATCH 0/7] QEMU patches to generate FDT from qdevs
Hi Grant, This is an experimental set of patches for populating the flattened device tree (fdt) data from the actual set of qdevs in the platform. Neat. I've pulled these into my qemu tree, and have updated it to the current qemu master branch too (only a minor change, as qemu_error has been removed). Could you try out the new branch to see if it all works for you? Cheers, Jeremy