* PReP residual to device-tree converter
@ 2008-05-26 6:25 Paul Mackerras
2008-07-09 10:47 ` Johannes Berg
0 siblings, 1 reply; 5+ messages in thread
From: Paul Mackerras @ 2008-05-26 6:25 UTC (permalink / raw)
To: linuxppc-dev
Here is a program that takes a PReP residual blob as input and
generates a device tree as output. Currently the back-end uses printf
to output the tree in dts format, but it would be easy to do an
alternative back-end that outputs a dtb. The idea is that this will
end up in the wrapper (with a dtb back-end), making it straightforward
to support PReP in arch/powerpc.
I would like people that have PReP machines to take a copy of
/proc/residual, run this program on it, and check that the output is
sane. If it isn't, or if it is missing bits, send me the residual
blob with a description of what's wrong in the generated dts. Since I
have only tested this with 2 blobs, both from IBM machines, it is very
likely that there are some assumptions in there that break on PRePs
from Motorola or other manufacturers.
To compile this program you'll need residual.h and pnp.h from
include/asm-ppc. I found it easiest to create a symlink called "asm"
in the current directory, pointing to $kernelsource/include/asm-ppc,
and use -I. on the gcc command line. Or you can copy residual.h and
pnp.h somewhere and munge the #include lines.
Paul.
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <unistd.h>
#define __KERNEL__
#include <asm/residual.h>
RESIDUAL resid;
int indent;
void prindent(void)
{
int i;
for (i = 0; i < indent; ++i)
printf("\t");
}
void start_node(const char *name)
{
printf("\n");
prindent();
printf("%s {\n", name);
++indent;
}
void end_node(void)
{
--indent;
prindent();
printf("};\n");
}
void strprop(const char *name, const char *val)
{
prindent();
printf("%s = \"%s\";\n", name, val);
}
void strnprop(const char *name, const unsigned char *val, int len)
{
prindent();
printf("%s = \"%.*s\";\n", name, len, val);
}
void multistrprop(const char *name, int n, ...)
{
int i;
va_list args;
const char *sep = "=";
const char *p;
prindent();
printf("%s ", name);
va_start(args, n);
for (i = 0; i < n; ++i) {
p = va_arg(args, const char *);
if (p) {
printf("%s \"%s\"", sep, p);
sep = ",";
}
}
va_end(args);
printf(";\n");
}
void intprop(const char *name, int val)
{
prindent();
printf("%s = <%d>;\n", name, val);
}
void voidprop(const char *name)
{
prindent();
printf("%s;\n", name);
}
void bufprop(const char *name, unsigned int *buf, int ncells, int npl)
{
const char *sep = "<";
int i, l = 0;
prindent();
printf("%s = ", name);
for (i = 0; i < ncells; ++i) {
if (l++ == npl) {
printf("\n");
prindent();
printf("\t");
l = 1;
}
printf("%s0x%x", sep, buf[i]);
sep = " ";
}
printf(">;\n");
}
const char *cpu_states[] = {
"okay", "disabled", "fail-off", "fail"
};
struct pvr_table {
unsigned int mask, value;
const char *name;
} pvr_table[] = {
{ 0xffff0000, 0x00010000, "PowerPC,601" },
{ 0xffff0000, 0x00030000, "PowerPC,603" },
{ 0xffff0000, 0x00040000, "PowerPC,604" },
{ 0xffff0000, 0x00060000, "PowerPC,603e" },
{ 0xffff0000, 0x00070000, "PowerPC,603ev" },
{ 0xffff0000, 0x00080000, "PowerPC,750" },
{ 0xfffff000, 0x00090000, "PowerPC,604e" },
{ 0xffff0000, 0x00090000, "PowerPC,604r" },
{ 0xffff0000, 0x000a0000, "PowerPC,604ev" },
{ 0xffff0000, 0x000c0000, "PowerPC,7400" },
{ 0xffff0000, 0x80000000, "PowerPC,7450" },
{ 0xffff0000, 0x80010000, "PowerPC,7455" },
{ 0xffff0000, 0x80020000, "PowerPC,7447" },
{ 0xffff0000, 0x80030000, "PowerPC,7447A" },
{ 0xffff0000, 0x80040000, "PowerPC,7448" },
{ 0xffff0000, 0x800c0000, "PowerPC,7410" },
{ 0, 0, "PowerPC" }
};
const char *match_pvr(unsigned int pvr)
{
struct pvr_table *p;
for (p = pvr_table; (pvr & p->mask) != p->value; ++p)
;
return p->name;
}
#define getw(p) ((p)[0] + ((p)[1] << 8))
#define getl(p) ((p)[0] + ((p)[1] << 8) + ((p)[2] << 16) + ((p)[3] << 24))
PPC_DEVICE *find_dev(PnP_BASE_TYPE basetype, PnP_SUB_TYPE subtype,
int intf, PPC_DEVICE *last)
{
int i = 0;
if (last != NULL)
i = (last - resid.Devices) + 1;
for (; i < resid.ActualNumDevices; ++i)
if (resid.Devices[i].DeviceId.BaseType == basetype &&
resid.Devices[i].DeviceId.SubType == subtype &&
(intf < 0 || resid.Devices[i].DeviceId.Interface == intf))
return &resid.Devices[i];
return NULL;
}
unsigned char *find_pnp(int *offsetp, int tag, int minlen, int byte0,
int *lenp)
{
unsigned char *p = &resid.DevicePnPHeap[*offsetp];
int nb, t;
for (;;) {
t = *p++;
if (!(t & 0x80)) {
nb = t & 7;
t >>= 3;
} else {
nb = getw(p);
p += 2;
}
if (t == tag && nb >= minlen && (byte0 < 0 || p[0] == byte0)) {
*offsetp = p - resid.DevicePnPHeap + nb;
if (lenp)
*lenp = nb;
return p;
}
if (t == EndTag)
return NULL;
p += nb;
}
}
void decode3(char *buf, unsigned int vendor)
{
buf[0] = '@' + ((vendor >> 10) & 0x1f);
buf[1] = '@' + ((vendor >> 5) & 0x1f);
buf[2] = '@' + (vendor & 0x1f);
}
char *decode_chipid(unsigned char *p)
{
static char buf[8];
int vendor = (p[1] << 8) + p[2];
int devid = (p[3] << 8) + p[4];
decode3(buf, vendor);
sprintf(&buf[3], "%.4X", devid);
return buf;
}
#define VPD resid.VitalProductData
#define i8259_phandle 0x3ffff
#define mpic_phandle 0x40000
unsigned int buf[2048];
void do_pci_bus(unsigned int);
void do_model(PPC_DEVICE *dev)
{
int offset;
unsigned char *p;
offset = dev->AllocatedOffset;
p = find_pnp(&offset, SmallVendorItem, 5, 1, NULL);
if (p)
strprop("model", decode_chipid(p));
}
unsigned int find_8259_ack_addr(void)
{
PPC_DEVICE *dev;
int offset;
unsigned char *p;
dev = find_dev(SystemPeripheral, ProgrammableInterruptController,
ISA_PIC, NULL);
if (!dev)
return 0;
offset = dev->AllocatedOffset;
while ((p = find_pnp(&offset, L4_Packet, 21, 9, NULL)) != NULL)
if (p[1] == 3 && p[2] == 32)
return getl(p + 5);
return 0;
}
int make_isa_reg(PPC_DEVICE *dev)
{
int offset, i = 0;
unsigned char *p;
unsigned int space;
/* Look for Address tags */
offset = dev->AllocatedOffset;
while ((p = find_pnp(&offset, L4_Packet, 21, 9, NULL)) != NULL) {
if (p[1] == 1) {
if (p[2] <= 10)
space = 3;
else if (p[2] == 11)
space = 5;
else
space = 1;
} else if (p[1] == 2) {
space = 0;
} else
continue;
buf[i++] = space;
buf[i++] = getl(p + 5);
buf[i++] = getl(p + 13);
}
/* Look for IOPort tags */
offset = dev->AllocatedOffset;
while ((p = find_pnp(&offset, IOPort, 7, 1, NULL)) != NULL) {
buf[i++] = 1;
buf[i++] = getw(p + 1);
buf[i++] = p[6];
}
return i;
}
void do_pci_addresses(PPC_DEVICE *dev)
{
int offset, i = 0;
unsigned char *p;
unsigned int bar;
bar = (dev->BusAccess.PCIAccess.BusNumber << 16) |
(dev->BusAccess.PCIAccess.DevFuncNumber << 8) | 0x80000010u;
/* Look for Address tags */
offset = dev->AllocatedOffset;
while ((p = find_pnp(&offset, L4_Packet, 21, 9, NULL)) != NULL) {
if (p[1] == 1 || p[1] == 2) {
buf[i++] = bar + (p[1] << 24);
buf[i++] = getl(p + 9);
buf[i++] = getl(p + 5);
buf[i++] = getl(p + 17);
buf[i++] = getl(p + 13);
bar += 4;
}
}
if (i > 0)
bufprop("assigned-addresses", buf, i, 5);
}
const char *isa_space_tag[] = { "m", "i" };
static int seen_8042;
void do_isa_dev(PPC_DEVICE *dev)
{
int offset, i, j;
unsigned char *p;
char name[32];
char pnp[12];
const char *type, *compat;
int is_8259 = 0;
unsigned int mask;
strcpy(pnp, "pnp");
decode3(pnp + 3, dev->DeviceId.DevId >> 16);
sprintf(pnp + 6, ",%lX", dev->DeviceId.DevId & 0xffff);
type = pnp;
compat = NULL;
switch (dev->DeviceId.BaseType) {
case MassStorageDevice:
switch (dev->DeviceId.SubType) {
case IDEController:
type = "ide";
break;
case FloppyController:
type = "fdc";
break;
}
break;
case MultimediaController:
switch (dev->DeviceId.SubType) {
case AudioController:
type = "sound";
break;
}
break;
case CommunicationsDevice:
switch (dev->DeviceId.SubType) {
case RS232Device:
type = "serial";
break;
case ATCompatibleParallelPort:
type = "parallel";
break;
}
break;
case SystemPeripheral:
switch (dev->DeviceId.SubType) {
case ProgrammableInterruptController:
type = "interrupt-controller";
if (dev->DeviceId.Interface == ISA_PIC) {
is_8259 = 1;
compat = "chrp,iic";
}
break;
case DMAController:
type = "dma-controller";
break;
case SystemTimer:
type = "timer";
break;
case RealTimeClock:
type = "rtc";
break;
case L2Cache:
type = "cache-controller";
break;
case NVRAM:
type = "nvram";
break;
case PowerManagement:
type = "IBM,pwr-mgmt";
break;
case OperatorPanel:
type = "IBM,op-panel";
break;
}
break;
case InputDevice:
switch (dev->DeviceId.SubType) {
case KeyboardController:
case MouseController:
if (seen_8042)
return;
seen_8042 = 1;
type = "8042";
compat = "chrp,8042";
break;
case TabletController:
type = "IBM,tablet-port";
break;
}
break;
}
i = make_isa_reg(dev);
if (!i)
return;
sprintf(name, "%s@%s%x", type, isa_space_tag[buf[0] & 1], buf[1]);
start_node(name);
bufprop("reg", buf, i, 6);
multistrprop("compatible", 2, compat, pnp);
do_model(dev);
if (is_8259) {
voidprop("interrupt-controller");
intprop("#interrupt-cells", 2);
buf[0] = i8259_phandle;
bufprop("linux,phandle", buf, 1, 1);
if (find_dev(SystemPeripheral, ProgrammableInterruptController,
MPIC, NULL)) {
/* hard-code cascade to mpic interrupt 0 */
buf[0] = mpic_phandle;
bufprop("interrupt-parent", buf, 1, 1);
buf[0] = 0;
buf[1] = 2;
bufprop("interrupts", buf, 2, 2);
}
} else {
/* look for interrupts */
i = 0;
offset = dev->AllocatedOffset;
while ((p = find_pnp(&offset, IRQFormat, 2, -1, NULL))) {
mask = getw(p);
for (j = 0; mask != 0; ++j, mask >>= 1)
if (mask & 1) {
buf[i++] = j;
buf[i++] = 3;
}
}
if (i > 0)
bufprop("interrupts", buf, i, 4);
}
end_node();
}
unsigned int do_pci_bridge(PPC_DEVICE *pci)
{
int offset, i, j, len;
unsigned int bus = 0;
unsigned char *p;
unsigned int irq_parent, irq, irq_sense;
/* find PCI bridge info */
offset = pci->AllocatedOffset;
p = find_pnp(&offset, L4_Packet, 21, 3, &len);
if (!p)
return 0;
bus = getl(p + 17);
/* generate interrupt-map and mask by iterating over slots */
i = 0;
p += 21;
for (len -= 21; len >= 12; len -= 12, p += 12) {
if (p[2] == 1) {
irq_parent = i8259_phandle;
irq_sense = 3; /* XXX ? */
} else if (p[2] == 2) {
irq_parent = mpic_phandle;
irq_sense = 2;
} else
continue;
for (j = 0; j < 4; ++j) {
irq = getw(p + 4 + 2*j);
if (irq == 0xffff)
continue;
buf[i++] = p[1] << 8; /* devfn */
buf[i++] = 0;
buf[i++] = 0;
buf[i++] = j;
buf[i++] = irq_parent;
buf[i++] = irq;
buf[i++] = irq_sense;
}
}
if (i > 0) {
bufprop("interrupt-map", buf, i, 7);
buf[0] = 0xf800;
buf[1] = 0;
buf[2] = 0;
buf[3] = 7;
bufprop("interrupt-map-mask", buf, 4, 4);
}
return bus;
}
void do_pci_dev(PPC_DEVICE *dev)
{
int i;
unsigned int bus;
char str[16];
const char *name;
int devfn = dev->BusAccess.PCIAccess.DevFuncNumber;
unsigned int pciloc;
/* construct a minimal reg property */
i = 0;
pciloc = (dev->BusAccess.PCIAccess.BusNumber << 16) + (devfn << 8);
buf[i++] = pciloc;
buf[i++] = 0;
buf[i++] = 0;
buf[i++] = 0;
buf[i++] = 0;
/* see if it's something we care about */
if (dev->DeviceId.BaseType == BridgeController &&
dev->DeviceId.SubType == ISABridge)
name = "isa";
else if (dev->DeviceId.BaseType == BridgeController &&
dev->DeviceId.SubType == PCIBridge)
name = "pci";
else if (dev->DeviceId.BaseType == SystemPeripheral &&
dev->DeviceId.SubType == ProgrammableInterruptController &&
dev->DeviceId.Interface == MPIC) {
name = "interrupt-controller";
/* add an entry for BAR 0 so we can have assigned-addresses */
buf[i++] = 0x02000010 | pciloc;
buf[i++] = 0;
buf[i++] = 0;
buf[i++] = 0;
buf[i++] = 0x40000;
} else
return; /* ignore things we can probe */
if (devfn & 7)
sprintf(str, "%s@%x,%x", name, devfn >> 3, devfn & 7);
else
sprintf(str, "%s@%x", name, devfn >> 3);
start_node(str);
bufprop("reg", buf, i, 5);
/* find chip ID */
do_model(dev);
if (strcmp(name, "pci") == 0) {
strprop("device_type", "pci");
bus = do_pci_bridge(dev);
do_pci_bus(bus);
} else if (strcmp(name, "isa") == 0) {
buf[0] = i8259_phandle;
bufprop("interrupt-parent", buf, 1, 1);
for (i = 0; i < resid.ActualNumDevices; ++i)
if (resid.Devices[i].DeviceId.BusId == ISADEVICE)
do_isa_dev(&resid.Devices[i]);
} else { /* must be interrupt-controller */
voidprop("interrupt-controller");
strprop("device_type", "open-pic");
strprop("compatible", "chrp,open-pic");
intprop("#interrupt-cells", 2);
buf[0] = mpic_phandle;
bufprop("linux,phandle", buf, 1, 1);
do_pci_addresses(dev);
}
end_node();
}
void do_pci_bus(unsigned int bus)
{
int j;
for (j = 0; j < resid.ActualNumDevices; ++j)
if (resid.Devices[j].DeviceId.BusId == PCIDEVICE &&
resid.Devices[j].BusAccess.PCIAccess.BusNumber == bus)
do_pci_dev(&resid.Devices[j]);
}
void do_cpu(PPC_CPU *cpu, unsigned int tbfreq)
{
PPC_DEVICE *l2;
char num[20];
int offset;
unsigned char *p;
if (cpu->CpuState > CPU_FAILED)
return;
sprintf(num, "%s@%x", match_pvr(cpu->CpuType), cpu->CpuNumber);
start_node(num);
strprop("device_type", "cpu");
intprop("reg", cpu->CpuNumber);
strprop("status", cpu_states[cpu->CpuState]);
intprop("clock-frequency", VPD.ProcessorHz);
intprop("timebase-frequency", tbfreq);
intprop("bus-frequency", VPD.ProcessorBusHz);
intprop("reservation-granule-size", VPD.GranuleSize);
if (VPD.CacheAttrib == SplitCAC) {
intprop("d-cache-size", VPD.D_CacheSize * 1024);
intprop("d-cache-block-size", VPD.D_CacheLineSize);
intprop("d-cache-line-size", VPD.D_CacheLineSize);
intprop("d-cache-sets", VPD.D_CacheSize * 1024
/ VPD.D_CacheLineSize / VPD.D_CacheAssoc);
intprop("i-cache-size", VPD.I_CacheSize * 1024);
intprop("i-cache-block-size", VPD.I_CacheLineSize);
intprop("i-cache-line-size", VPD.I_CacheLineSize);
intprop("i-cache-sets", VPD.I_CacheSize * 1024
/ VPD.I_CacheLineSize / VPD.I_CacheAssoc);
} else if (VPD.CacheAttrib == CombinedCAC) {
voidprop("cache-unified");
intprop("cache-size", VPD.CacheSize * 1024);
intprop("cache-block-size", VPD.CacheLineSize);
intprop("cache-line-size", VPD.CacheLineSize);
intprop("cache-sets", VPD.CacheSize * 1024
/ VPD.CacheLineSize / VPD.CacheAssoc);
}
if (VPD.TLBAttrib != NoneTLB) {
intprop("tlb-size", VPD.TLBSize);
intprop("tlb-sets", VPD.TLBSize / VPD.TLBAssoc);
if (VPD.TLBAttrib == SplitTLB) {
voidprop("tlb-split");
intprop("d-tlb-size", VPD.D_TLBSize);
intprop("d-tlb-sets",
VPD.D_TLBSize / VPD.D_TLBAssoc);
intprop("i-tlb-size", VPD.I_TLBSize);
intprop("i-tlb-sets",
VPD.I_TLBSize / VPD.I_TLBAssoc);
}
}
l2 = find_dev(SystemPeripheral, L2Cache, -1, NULL);
if (l2) {
offset = l2->AllocatedOffset;
p = find_pnp(&offset, L4_Packet, 13, 2, NULL);
if (p) {
unsigned int csize = getl(p + 1) * 1024;
unsigned int assoc = getw(p + 5);
unsigned int lsize = getw(p + 7);
start_node("l2-cache");
voidprop("cache-unified");
intprop("d-cache-size", csize);
intprop("d-cache-line-size", lsize);
intprop("d-cache-sets", csize / lsize / assoc);
intprop("i-cache-size", csize);
intprop("i-cache-line-size", lsize);
intprop("i-cache-sets", csize / lsize / assoc);
end_node();
}
}
end_node();
}
int main(int ac, char **av)
{
int i, n, offset;
int tbfreq, rem;
unsigned char *p;
PPC_DEVICE *pci;
n = read(0, &resid, sizeof(resid));
if (n < 0) {
perror("read");
exit(1);
}
if (n != resid.ResidualLength) {
fprintf(stderr, "length error: read %d should be %lu\n",
n, resid.ResidualLength);
exit(1);
}
printf("/dts-v1/;\n");
start_node("/");
strnprop("model", VPD.PrintableModel, 32);
strprop("compatible", "prep");
intprop("#address-cells", 1);
intprop("#size-cells", 1);
strnprop("serial-number", VPD.Serial, 16);
intprop("clock-frequency", VPD.ProcessorBusHz);
start_node("chosen");
end_node();
start_node("cpus");
intprop("#address-cells", 1);
intprop("#size-cells", 0);
tbfreq = (VPD.ProcessorBusHz / VPD.TimeBaseDivisor) * 1000;
rem = VPD.ProcessorBusHz % VPD.TimeBaseDivisor;
if (rem)
tbfreq += (rem * 1000) / VPD.TimeBaseDivisor;
for (i = 0; i < resid.MaxNumCpus; ++i)
do_cpu(&resid.Cpus[i], tbfreq);
end_node();
start_node("memory@0");
strprop("device_type", "memory");
buf[0] = 0;
buf[1] = resid.GoodMemory; /* or TotalMemory? */
bufprop("reg", buf, 2, 2);
end_node();
pci = NULL;
while ((pci = find_dev(BridgeController, PCIBridge, -1, pci)) != NULL)
if (pci->DeviceId.BusId == PROCESSORDEVICE)
break;
if (pci) {
unsigned int bus;
start_node("pci");
strprop("device_type", "pci");
strprop("compatible", "prep-pci");
intprop("#address-cells", 3);
intprop("#size-cells", 2);
/* find chip ID */
do_model(pci);
bus = do_pci_bridge(pci);
/* Generate ranges */
i = 0;
offset = pci->AllocatedOffset;
while ((p = find_pnp(&offset, L4_Packet, 29, 5, NULL))) {
unsigned int space;
if (p[3] == 1)
space = 2; /* PCI memory */
else if (p[3] == 2)
space = 1; /* PCI I/O */
else
continue;
buf[i++] = space << 24;
buf[i++] = getl(p + 17); /* PCI address */
buf[i++] = getl(p + 13);
buf[i++] = getl(p + 5); /* cpu address */
buf[i++] = 0;
buf[i++] = getl(p + 21); /* size */
}
if (i > 0)
bufprop("ranges", buf, i, 5);
/* fake up a bus-range */
buf[0] = bus;
buf[1] = 0xff;
bufprop("bus-range", buf, 2, 2);
buf[0] = find_8259_ack_addr();
if (buf[0])
bufprop("8259-interrupt-acknowledge", buf, 1, 1);
/* look for devices on this bus */
do_pci_bus(bus);
end_node();
}
end_node();
if (indent)
fprintf(stderr, "unbalanced: indent = %d\n", indent);
exit(0);
}
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: PReP residual to device-tree converter
2008-05-26 6:25 PReP residual to device-tree converter Paul Mackerras
@ 2008-07-09 10:47 ` Johannes Berg
2008-07-09 11:29 ` Johannes Berg
0 siblings, 1 reply; 5+ messages in thread
From: Johannes Berg @ 2008-07-09 10:47 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev, Milton Miller, David Gibson
[-- Attachment #1: Type: text/plain, Size: 689 bytes --]
> I would like people that have PReP machines to take a copy of
> /proc/residual, run this program on it, and check that the output is
> sane. If it isn't, or if it is missing bits, send me the residual
> blob with a description of what's wrong in the generated dts.
Here's the output from qemu:
/dts-v1/;
/ {
model = "Qemu";
compatible = "prep";
#address-cells = <1>;
#size-cells = <1>;
serial-number = "";
clock-frequency = <100000000>;
chosen {
};
cpus {
#address-cells = <1>;
#size-cells = <0>;
};
memory@0 {
device_type = "memory";
reg = <0x0 0x9000000>;
};
};
Let me know if you want the blob too (it's ~10k)
johannes
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: PReP residual to device-tree converter
2008-07-09 10:47 ` Johannes Berg
@ 2008-07-09 11:29 ` Johannes Berg
2008-07-09 11:33 ` Johannes Berg
2008-07-09 11:39 ` Johannes Berg
0 siblings, 2 replies; 5+ messages in thread
From: Johannes Berg @ 2008-07-09 11:29 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev, Milton Miller, David Gibson
[-- Attachment #1: Type: text/plain, Size: 1042 bytes --]
On Wed, 2008-07-09 at 12:48 +0200, Johannes Berg wrote:
> > I would like people that have PReP machines to take a copy of
> > /proc/residual, run this program on it, and check that the output is
> > sane. If it isn't, or if it is missing bits, send me the residual
> > blob with a description of what's wrong in the generated dts.
>
> Here's the output from qemu:
[...]
Milton wanted iomem and ioports, I didn't manage to get userspace
working so I printed them in the kernel (hopefully correctly):
iomem:
c0000000-feffffff : PCI host bridge
c80000f0-c80000ff : 0000:00:01.0
ioports:
00000000-007fffff : PCI host bridge
00000000-0000001f : dma1
00000020-00000021 : 8259 (master)
00000040-0000005f : timer
00000080-0000008f : dma page reg
000000a0-000000a1 : 8259 (slave)
000000c0-000000df : dma2
000004d0-000004d1 : 8259 edge control
FWIW, my qemu command line was:
qemu-system-ppc -initrd initrd -kernel linux/arch/ppc/boot/images/zImage.prep -M prep -cpu 604 -serial stdio
johannes
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: PReP residual to device-tree converter
2008-07-09 11:29 ` Johannes Berg
@ 2008-07-09 11:33 ` Johannes Berg
2008-07-09 11:39 ` Johannes Berg
1 sibling, 0 replies; 5+ messages in thread
From: Johannes Berg @ 2008-07-09 11:33 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev, Milton Miller, David Gibson
[-- Attachment #1: Type: text/plain, Size: 860 bytes --]
On Wed, 2008-07-09 at 13:29 +0200, Johannes Berg wrote:
> On Wed, 2008-07-09 at 12:48 +0200, Johannes Berg wrote:
> > > I would like people that have PReP machines to take a copy of
> > > /proc/residual, run this program on it, and check that the output is
> > > sane. If it isn't, or if it is missing bits, send me the residual
> > > blob with a description of what's wrong in the generated dts.
> >
> > Here's the output from qemu:
> [...]
>
> Milton wanted iomem and ioports, I didn't manage to get userspace
> working so I printed them in the kernel (hopefully correctly):
>
> iomem:
> c0000000-feffffff : PCI host bridge
> c80000f0-c80000ff : 0000:00:01.0
Oh and if I attach a virtual ne2k_pci, it changes:
c0000000-feffffff : PCI host bridge
c1100000-c110000f : 0000:00:02.0
c80000f0-c80000ff : 0000:00:01.0
johannes
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: PReP residual to device-tree converter
2008-07-09 11:29 ` Johannes Berg
2008-07-09 11:33 ` Johannes Berg
@ 2008-07-09 11:39 ` Johannes Berg
1 sibling, 0 replies; 5+ messages in thread
From: Johannes Berg @ 2008-07-09 11:39 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev, Milton Miller, David Gibson
[-- Attachment #1: Type: text/plain, Size: 1440 bytes --]
On Wed, 2008-07-09 at 13:29 +0200, Johannes Berg wrote:
> On Wed, 2008-07-09 at 12:48 +0200, Johannes Berg wrote:
> > > I would like people that have PReP machines to take a copy of
> > > /proc/residual, run this program on it, and check that the output is
> > > sane. If it isn't, or if it is missing bits, send me the residual
> > > blob with a description of what's wrong in the generated dts.
> >
> > Here's the output from qemu:
> [...]
>
> Milton wanted iomem and ioports, I didn't manage to get userspace
> working so I printed them in the kernel (hopefully correctly):
I printed them far too early. After letting it probe drivers first, I
get:
iomem:
c0000000-feffffff : PCI host bridge
c0000000-c000000f : 0000:00:03.0
c1100000-c110000f : 0000:00:02.0
c80000f0-c80000ff : 0000:00:01.0
ioport:
00000000-007fffff : PCI host bridge
00000000-0000001f : dma1
00000020-00000021 : 8259 (master)
00000040-0000005f : timer
00000080-0000008f : dma page reg
000000a0-000000a1 : 8259 (slave)
000000c0-000000df : dma2
000001f0-000001f7 : ide0
000003f2-000003f5 : floppy
000003f6-000003f6 : ide0
000003f7-000003f7 : floppy DIR
000003f8-000003ff : serial
000004d0-000004d1 : 8259 edge control
which was with usb too:
qemu-system-ppc -initrd initrd -kernel linux/arch/ppc/boot/images/zImage.prep -M prep -cpu 604 -serial stdio -net nic,model=ne2k_pci -usb
johannes
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2008-07-09 11:39 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-05-26 6:25 PReP residual to device-tree converter Paul Mackerras
2008-07-09 10:47 ` Johannes Berg
2008-07-09 11:29 ` Johannes Berg
2008-07-09 11:33 ` Johannes Berg
2008-07-09 11:39 ` Johannes Berg
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).