On Fri, Aug 19, 2011 at 8:44 PM, Mark Cave-Ayland mark.cave-ayland@siriusit.co.uk wrote:
On 15/08/11 16:01, Bob Breuer wrote:
Here's a preliminary patch for sbus slot probing.
Great work indeed :)
This can be used for the preliminary dbri device patch, see my dbri-pre1 branch at github: https://github.com/breuerr/qemu/tree/dbri-pre1 That branch also has a rewritten fcode rom to avoid the use of the obsolete intr forth word. Use the SS-20 machine to get the dbri device.
Todo: non-faulting reads so that an empty slot can be probed extend to probe other (all?) slots as well only add the slot E range for SS-20, but not SS-10
Is there any existing code for sparc32 which does a non-faulting read? It looks like even cpeek doesn't try to catch any faults.
Not that I know of. It looks as if there may be some work that needs to be done in qemu in order for this to happen as per the comment in hw/sun4m_iommu.c:
case IOMMU_ARBEN: // XXX implement SBus probing: fault when reading unmapped // addresses, fault cause and address stored to MMU/IOMMU s->regs[saddr] = (val & IOMMU_ARBEN_MASK) | IOMMU_MID; break;
I have a feeling that qemu invokes a known trap for unmapped memory, so it could be that given we know the SBus range we could just assume that any traps occurring during a read to that range is a failed probe?
The documentation is pretty weak in this area, the comments above are just my guesses.
Bob
Index: drivers/sbus.c
--- drivers/sbus.c (revision 1046) +++ drivers/sbus.c (working copy) @@ -451,11 +451,36 @@ static void sbus_probe_slot_ss10(unsigned int slot, uint64_t base) {
- ucell fcode;
- unsigned char start;
// OpenBIOS and Qemu don't know how to do Sbus probing switch(slot) { case 2: // SUNW,tcx ob_tcx_init(slot, "/iommu/sbus/SUNW,tcx"); break;
- case 0xe: // dbri
- fcode = ofmem_map_io(base, 0x1000);
- // TODO: non-faulting read
- start = *(unsigned char*)fcode;
- if (start == 0xfd || start == 0xf1) {
See is_fcode() in libopenbios/fcode_load.c.
- push_str("/iommu/sbus");
- fword("select-dev");
- fword("new-device");
- push_str(NULL);
- PUSH(0); // offset
- PUSH(slot); // space
- push_str("encode-unit");
- fword("$call-parent");
- fword("set-args");
- PUSH(fcode);
- PUSH(1);
- fword("byte-load");
- fword("finish-device");
- fword("unselect-dev");
- }
- ofmem_unmap(fcode, 0x1000);
- break;
case 0xf: // le, esp, bpp, power-management ob_macio_init(slot, base, 0); // Power management (APC) XXX should not exist @@ -534,6 +559,7 @@ { 1, 0, 0xe10000000ULL, 0x10000000,}, { 2, 0, 0xe20000000ULL, 0x10000000,}, { 3, 0, 0xe30000000ULL, 0x10000000,},
- [0xe] = { 0xe, 0, 0xee0000000ULL, 0x10000000,},
[0xf] = { 0xf, 0, 0xef0000000ULL, 0x10000000,}, };
The only other thing I'd like to see, as you mention, is the probe moved into a separate function which can be called from the appropriate _init() functions. I'd be interested to follow the discussion related to handling the various traps that occur during a fault access on this thread as you progress.
ATB,
Mark.
-- Mark Cave-Ayland - Senior Technical Architect PostgreSQL - PostGIS Sirius Corporation plc - control through freedom http://www.siriusit.co.uk t: +44 870 608 0063
Sirius Labs: http://www.siriusit.co.uk/labs
-- OpenBIOS http://openbios.org/ Mailinglist: http://lists.openbios.org/mailman/listinfo Free your System - May the Forth be with you