qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH] qemu PPC Linux 2.6 IDE
@ 2005-02-23 22:28 Thayne Harbaugh
  2005-02-24 10:52 ` [Qemu-devel] " J. Mayer
  0 siblings, 1 reply; 2+ messages in thread
From: Thayne Harbaugh @ 2005-02-23 22:28 UTC (permalink / raw)
  To: qemu-devel

[-- Attachment #1: Type: text/plain, Size: 846 bytes --]

I have qemu PPC booting Linux 2.6.  Here's a patch for IDE.

IDE detection of macio has changed significantly.  2.4
drivers/ide/ppc/pmac.c:pmac_ide_probe() simply looked for the IDE/ATA
controllers in OF.  2.6 pmac.c:pmace_ide_probe() registers macio device
filters for IDE/ATA and relies on macio device enumeration to connect to
the IDE driver.  Where things are broken is that
drivers/macintosh/macio_asic.c:macio_pci_probe() fails to match the
macio device due to the bus:devfn not being set as a "reg" property in
OHW.

There are two questions about this patch:

* What is the complete information expected in the "reg" property of a
PCI device?

* Where should the current macio "reg" information really be stored, if
at all?

I should be able to investigate the above two questions in the next few
days.

A fix for 2.6 FB should be soon.


[-- Attachment #2: OpenHackWare-0.4-pre1c-2.6_ide.patch --]
[-- Type: text/x-patch, Size: 3009 bytes --]

Index: src/bios.h
===================================================================
--- src/bios.h	(revision 89)
+++ src/bios.h	(working copy)
@@ -405,7 +405,7 @@
                               uint8_t devfn, uint8_t rev, uint32_t ccode,
                               uint16_t min_grant, uint16_t max_latency);
 void *OF_register_pci_device (void *parent, pci_dev_t *dev,
-                              uint8_t devfn, uint8_t rev, uint32_t ccode,
+                              uint8_t bus, uint8_t devfn, uint8_t rev, uint32_t ccode,
                               uint16_t min_grant, uint16_t max_latency);
 void OF_finalize_pci_host (void *dev, int first_bus, int nb_busses);
 void OF_finalize_pci_device (void *dev, uint32_t *regions, uint32_t *sizes);
Index: src/pci.c
===================================================================
--- src/pci.c	(revision 89)
+++ src/pci.c	(working copy)
@@ -1908,12 +1914,12 @@
     /* register PCI device in OF tree */
     if (bridge->dev.common.type == PCI_FAKE_BRIDGE) {
         newd->common.OF_private =
-            OF_register_pci_device(host->dev.common.OF_private, dev, devfn,
+            OF_register_pci_device(host->dev.common.OF_private, dev, bus, devfn,
                                    rev, ccode, min_grant, max_latency);
     } else {
         newd->common.OF_private =
-            OF_register_pci_device(bridge->dev.common.OF_private, dev, devfn,
+            OF_register_pci_device(bridge->dev.common.OF_private, dev, bus, devfn,
                                    rev, ccode, min_grant, max_latency);
     }
  configure_device:
Index: src/of.c
===================================================================
--- src/of.c	(revision 90)
+++ src/of.c	(working copy)
@@ -2122,10 +2125,11 @@
 
 __attribute__ (( section (".OpenFirmware") ))
 void *OF_register_pci_device (void *parent, pci_dev_t *dev,
-                              uint8_t devfn, uint8_t rev, uint32_t ccode,
+                              uint8_t bus, uint8_t devfn, uint8_t rev, uint32_t ccode,
                               uint16_t min_grant, uint16_t max_latency)
 {
     OF_env_t *OF_env;
+    OF_regprop_t regs[1];
     OF_node_t *pci_dev;
 
     OF_env = OF_env_main;
@@ -2134,6 +2138,10 @@
     pci_dev = OF_pci_device_new(OF_env, parent, dev, devfn >> 3,
                                 rev, ccode, min_grant, max_latency);
 
+    /* FIXME - this likely isn't complete: low 8 and high 8 of the 32 bits? */
+    regs[0].address = (bus << 16) | (devfn << 8);
+    OF_property_new(OF_env, pci_dev, "reg", regs, sizeof(OF_regprop_t));
+
     return pci_dev;
 }
 
@@ -2347,7 +2355,8 @@
     pregs[0].addr.lo = 0x00000000;
     pregs[0].size_hi = 0x00000000;
     pregs[0].size_lo = size;
-    OF_property_new(OF_env, mio, "reg",
+    /* FIXME - pregs can't be property "reg" because bus:devfn is expected in "reg" */
+    OF_property_new(OF_env, mio, "preg",
                     &pregs, 2 * sizeof(pci_reg_prop_t));
 #endif
     pregs[0].addr.hi = 0x00000000;

^ permalink raw reply	[flat|nested] 2+ messages in thread

* [Qemu-devel] Re: [PATCH] qemu PPC Linux 2.6 IDE
  2005-02-23 22:28 [Qemu-devel] [PATCH] qemu PPC Linux 2.6 IDE Thayne Harbaugh
@ 2005-02-24 10:52 ` J. Mayer
  0 siblings, 0 replies; 2+ messages in thread
From: J. Mayer @ 2005-02-24 10:52 UTC (permalink / raw)
  To: Thayne Harbaugh; +Cc: qemu-devel

[-- Attachment #1: Type: text/plain, Size: 1902 bytes --]

On Wed, 2005-02-23 at 23:28, Thayne Harbaugh wrote:
> I have qemu PPC booting Linux 2.6.  Here's a patch for IDE.
> 
> IDE detection of macio has changed significantly.  2.4
> drivers/ide/ppc/pmac.c:pmac_ide_probe() simply looked for the IDE/ATA
> controllers in OF.  2.6 pmac.c:pmace_ide_probe() registers macio device
> filters for IDE/ATA and relies on macio device enumeration to connect to
> the IDE driver.  Where things are broken is that
> drivers/macintosh/macio_asic.c:macio_pci_probe() fails to match the
> macio device due to the bus:devfn not being set as a "reg" property in
> OHW.

OK, your patch is as false as what I've done for many reasons (see
below)

> 
> There are two questions about this patch:
> 
> * What is the complete information expected in the "reg" property of a
> PCI device?

"reg" is supposed to contain information about the configuration space,
I/O regions and memory regions for the PCI device.

> * Where should the current macio "reg" information really be stored, if
> at all?

Current MacIO "reg" informations are to be stored in "reg" property, but
there are false, as you've seen. Those "reg" properties where taken from
a real mac...
I did not notice that I should have changed the preg.hi cell to match
the Qemu PCI device informations, but the real fix is to generate the
whole information...

I made a quick fix, following OF bindings for PCI specifications.
Note that I already had a fix for OF_property_set with no value, less
intrusive than yours.
I also did add a dprintf (as debug printf) function to make early debug
easier and there's also a needed fix in CHRP boot file loader.

Please consider this patch against 0.4-pre1d, it should fix the macIO
problem the right way.
There's still a lack of informations about configuration space in reg
properties for PCI devices, but this should not hurt.

-- 
J. Mayer <l_indien@magic.fr>
Never organized

[-- Attachment #2: current.diff --]
[-- Type: text/x-patch, Size: 13886 bytes --]

Index: src/bios.h
===================================================================
--- src/bios.h	(revision 105)
+++ src/bios.h	(working copy)
@@ -401,7 +401,8 @@ void *OF_register_pci_device (void *pare
                               uint8_t devfn, uint8_t rev, uint32_t ccode,
                               uint16_t min_grant, uint16_t max_latency);
 void OF_finalize_pci_host (void *dev, int first_bus, int nb_busses);
-void OF_finalize_pci_device (void *dev, uint32_t *regions, uint32_t *sizes);
+void OF_finalize_pci_device (void *dev, uint8_t bus, uint8_t devfn,
+                             uint32_t *regions, uint32_t *sizes);
 void OF_finalize_pci_macio (void *dev, uint32_t base_address, uint32_t size,
                             void *private_data);
 int OF_register_bus (const unsigned char *name, uint32_t address,

Index: src/of.c
===================================================================
--- src/of.c	(revision 99)
+++ src/of.c	(working copy)
@@ -886,7 +886,7 @@ static OF_prop_t *OF_property_set (OF_en
     if (prop != NULL) {
         OF_DPRINTF("change property [%s]\n", name);
         tmp = malloc(len);
-        if (tmp == NULL) {
+        if (tmp == NULL && len != 0) {
             ERROR("%s cannot set property '%s'\n", __func__, name);
             return NULL;
         }
@@ -2009,7 +2009,7 @@ static void *OF_pci_device_new (OF_env_t
 {
     OF_node_t *node;
 
-    printf("register '%s' '%s' '%s' '%s' 0x%08x in '%s' 0x%08x\n",
+    dprintf("register '%s' '%s' '%s' '%s' 0x%08x in '%s' 0x%08x\n",
            dev->name, dev->type, dev->compat, dev->model, address,
            parent->prop_name->value, *(uint32_t *)parent->prop_address->value);
     node = OF_node_new(OF_env, parent, dev->name, address);
@@ -2033,7 +2033,7 @@ static void *OF_pci_device_new (OF_env_t
         OF_prop_int_new(OF_env, node, "#interrupt-cells", dev->acells);
     if (dev->icells != 0)
         OF_prop_int_new(OF_env, node, "#size-cells", dev->acells);
-    printf("Done %p %p\n", parent, node);
+    dprintf("Done %p %p\n", parent, node);
     
     return node;
 }
@@ -2150,35 +2156,112 @@ void OF_finalize_pci_host (void *dev, in
     OF_property_new(OF_env, dev, "bus-range", regs, sizeof(OF_regprop_t));
 }
 
-void OF_finalize_pci_device (void *dev, uint32_t *regions, uint32_t *sizes)
+void OF_finalize_pci_device (void *dev, uint8_t bus, uint8_t devfn,
+                             uint32_t *regions, uint32_t *sizes)
 {
     OF_env_t *OF_env;
-    pci_reg_prop_t pregs[6];
-    int i, j;
+    pci_reg_prop_t pregs[6], rregs[6];
+    uint32_t mask;
+    int i, j, k;
 
     OF_env = OF_env_main;
     if (regions[0] != 0x00000000)
         OF_prop_int_set(OF_env, dev, "address", regions[0] & ~0x0000000F);
-    for (i = 0, j = 0; i < 6; i++) {
+    for (i = 0, j = 0, k = 0; i < 6; i++) {
         if (regions[i] != 0x00000000 && sizes[i] != 0x00000000) {
+            /* Generate "reg" property */
             if (regions[i] & 1) {
-                pregs[j].addr.hi = 0x01000000;
+                /* IO space */
+                rregs[j].addr.hi = 0x01000000;
+                mask = 0x00000001;
+            } else if (regions[i] & 4) {
+                /* 64 bits address space */
+                rregs[j].addr.hi = 0x83000000;
+                mask = 0x0000000F;
+#if 0
+            } else if ((regions[i] & 0xF) == 0x00) { /* ? */
+                /* Configuration space */
+                rregs[j].addr.hi = 0x00000000;
+                mask = 0x0000000F;
+#endif
             } else {
-                pregs[j].addr.hi = 0x02000000;
+                /* 32 bits address space */
+                rregs[j].addr.hi = 0x82000000;
+                mask = 0x0000000F;
+            }
+            /* Set bus number */
+            rregs[j].addr.hi |= bus << 16;
+            /* Set device/function */
+            rregs[j].addr.hi |= devfn << 8;
+            /* Set register */
+#if 1
+            rregs[j].addr.hi |= 0x10 + (i * sizeof(uint32_t));
+#endif
+            /* Set address */
+            rregs[j].addr.mid = 0x00000000;
+            rregs[j].addr.lo = regions[i] & ~mask;
+            /* Set size */
+            rregs[j].size_hi = 0x00000000;
+            rregs[j].size_lo = sizes[i];
+#if 0
+            if ((rregs[j].addr.hi & 0x03000000) != 0x00000000)
+#endif
+            {
+                /* No assigned address for configuration space */
+                pregs[k].addr.hi = rregs[j].addr.hi;
+                pregs[k].addr.mid = rregs[j].addr.mid;
+                pregs[k].addr.lo = rregs[j].addr.lo;
+                pregs[k].size_hi = rregs[j].size_hi;
+                pregs[k].size_lo = rregs[j].size_lo;
+                k++;
             }
-            pregs[j].addr.mid = 0x00000000;
-            pregs[j].addr.lo = regions[i] & ~0x0000000F;
-            pregs[j].size_hi = 0x00000000;
-            pregs[j].size_lo = sizes[i];
             j++;
         }
     }
     if (j > 0) {
+        OF_property_new(OF_env, dev, "reg",
+                        rregs, j * sizeof(pci_reg_prop_t));
+    } else {
+        OF_property_new(OF_env, dev, "reg", NULL, 0);
+    }
+    if (k > 0) {
         OF_property_new(OF_env, dev, "assigned-addresses",
-                        pregs, j * sizeof(pci_reg_prop_t));
+                        pregs, k * sizeof(pci_reg_prop_t));
     } else {
         OF_property_new(OF_env, dev, "assigned-addresses", NULL, 0);
     }
+#if 1
+    {
+        OF_prop_t *prop_name = ((OF_node_t *)dev)->prop_name;
+
+        if (j > 0) {
+            dprintf("PCI device '%s' %d %d %d reg properties:\n",
+                    prop_name->value, bus, devfn >> 3, devfn & 7);
+            for (i = 0; i < j; i++) {
+                dprintf("  addr: %08x %08x %08x size: %08x %08x\n",
+                        rregs[i].addr.hi, rregs[i].addr.mid, rregs[i].addr.lo,
+                        rregs[i].size_hi, rregs[i].size_lo);
+            }
+        } else {
+            dprintf("PCI device '%s' %d %d %d has no reg properties:\n",
+                    prop_name->value, bus, devfn >> 3, devfn & 7);
+        }
+        if (k > 0) {
+            dprintf("PCI device '%s' %d %d %d "
+                    "assigned addresses properties:\n",
+                    prop_name->value, bus, devfn >> 3, devfn & 7);
+            for (i = 0; i < j; i++) {
+                dprintf("  addr: %08x %08x %08x size: %08x %08x\n",
+                        pregs[i].addr.hi, pregs[i].addr.mid, pregs[i].addr.lo,
+                        pregs[i].size_hi, pregs[i].size_lo);
+            }
+        } else {
+            dprintf("PCI device '%s' %d %d %d has no "
+                    "assigned addresses properties:\n",
+                    prop_name->value, bus, devfn >> 3, devfn & 7);
+        }
+    }
+#endif
 }
 
 __attribute__ (( section (".OpenFirmware") ))
@@ -2340,7 +2423,7 @@ void OF_finalize_pci_macio (void *dev, u
     /* Mac-IO is mandatory for OSX to boot */
     mio = dev;
     mio->private_data = private_data;
-#if 1
+#if 0 // Done by generic PCI device registration routines
     pregs[0].addr.hi = 0x00013800;
     pregs[0].addr.mid = 0x00000000;
     pregs[0].addr.lo = 0x00000000;
@@ -3811,9 +3894,9 @@ static void OF_setprop (OF_env_t *OF_env
         return;
     }
     value = malloc(len);
-    if (value == NULL) {
+    if (value == NULL && len != 0) {
         pushd(OF_env, -1);
-        ERROR("%s: Cannot alloc property\n", __func__);
+        ERROR("%s: Cannot alloc property '%s' (%d)\n", __func__, name, len);
         return;
     }
     for (i = 0; i < len; i++)

Index: src/pci.c
===================================================================
--- src/pci.c	(revision 100)
+++ src/pci.c	(working copy)
@@ -2003,7 +2003,7 @@ static pci_u_t *pci_check_device (pci_ho
     }
  update_device:
     pci_update_device(bridge, newd, min_grant, max_latency, irq_line);
-    OF_finalize_pci_device(newd->common.OF_private,
+    OF_finalize_pci_device(newd->common.OF_private, bus, devfn,
                            newd->regions, newd->sizes);
     /* Call special inits if needed */
     if (dev->config_cb != NULL)
Index: src/char.c
===================================================================
--- src/char.c	(revision 101)
+++ src/char.c	(working copy)
@@ -300,6 +300,20 @@ static cops_t pc_serial_ops = {
     .close = &pc_serial_close,
 };
 
+/* XXX: debug stuff only ! (TOFIX with a generic debug console) */
+int serial_write (const void *buffer, int len)
+{
+    const char *p;
+
+    for (p = buffer; len > 0; len--) {
+        if (!(inb(0x3F8 + PC_SERIAL_LSR_OFFSET) & 0x20))
+            usleep(100);
+        outb(0x3F8, *p++);
+    }
+
+    return 0;
+}
+
 int pc_serial_register (uint16_t base)
 {
     pc_serial_t *serial;
Index: src/libc/include/stdio.h
===================================================================
--- src/libc/include/stdio.h	(revision 90)
+++ src/libc/include/stdio.h	(working copy)
@@ -35,9 +35,11 @@
 #define EOF ((int)-1)
 
 int printf (const char *format, ...);
+int dprintf (const char *format, ...);
 int sprintf (char *str, const char *format, ...);
 int snprintf (char *str, size_t size, const char *format, ...);
 int vprintf (const char *format, va_list ap);
+int vdprintf (const char *format, va_list ap);
 int vsprintf (char *str, const char *format, va_list ap);
 int vsnprintf (char *str, size_t size, const char *format, va_list ap);
 

Index: src/libc/src/format.c
===================================================================
--- src/libc/src/format.c	(revision 90)
+++ src/libc/src/format.c	(working copy)
@@ -41,6 +41,8 @@
 
 #define unused __attribute__ (( unused ))
 int console_write (const void *buffer, int len);
+int serial_write (const void *buffer, int len);
+#define debug_write serial_write
 
 /* Low level output fonctions */
 typedef size_t (*outf_t)(void *private, const unsigned char *buf, size_t len);
@@ -57,6 +59,16 @@ size_t outfd (void *private, const unsig
     return write(*fd, buf, len);
 }
 
+size_t outf_dbg (void *private, const unsigned char *buf, size_t len)
+{
+    int *fd = private;
+
+    if (*fd == 1 || *fd == 2)
+        return debug_write(buf, len);
+
+    return write(*fd, buf, len);
+}
+
 /* output to buffer */
 size_t outbuf (void *private, const unsigned char *buf, size_t len)
 {
@@ -362,6 +374,7 @@ int _vprintf(outf_t outf, void *private,
 }
 #else /* defined (__USE__vprintf__) */
 size_t outfd (void *private, const unsigned char *buf, size_t len);
+size_t outf_dbg (void *private, const unsigned char *buf, size_t len);
 size_t outbuf (void *private, const unsigned char *buf, size_t len);
 int _vprintf(outf_t outf, void *private, size_t maxlen,
              const unsigned char *format, va_list ap);
@@ -382,6 +395,21 @@ int printf (const char *format, ...)
 }
 #endif /* defined (__USE_printf__) */
 
+#if defined (__USE_dprintf__)
+int dprintf (const char *format, ...)
+{
+    va_list ap;
+    int fd = 1;
+    int ret;
+
+    va_start(ap, format);
+    ret = _vprintf(&outf_dbg, &fd, -1, format, ap);
+    va_end(ap);
+
+    return ret;
+}
+#endif /* defined (__USE_dprintf__) */
+
 #if defined (__USE_sprintf__)
 int sprintf (char *str, const char *format, ...)
 {
@@ -419,6 +447,15 @@ int vprintf (const char *format, va_list
 }
 #endif /* defined (__USE_vprintf__) */
 
+#if defined (__USE_vdprintf__)
+int vdprintf (const char *format, va_list ap)
+{
+    int fd = 1;
+
+    return _vprintf(&outf_dbg, &fd, -1, format, ap);
+}
+#endif /* defined (__USE_vdprintf__) */
+
 #if defined (__USE_vsprintf__)
 int vsprintf (char *str, const char *format, va_list ap)
 {

Index: src/libexec/chrp.c
===================================================================
--- src/libexec/chrp.c	(revision 90)
+++ src/libexec/chrp.c	(working copy)
@@ -168,7 +168,7 @@ int exec_load_chrp (inode_t *file, void 
                     if (*(char *)tag->data == 0x0d) {
                         pos++;
                     }
-                    DPRINTF("Boot file: '%s'\n", pos);
+                    DPRINTF("Description: '%s'\n", pos);
                     break;
                 case CHRP_TAG_BOOT_SCRIPT:
                     /* Here is the interresting part... */
@@ -255,7 +255,8 @@ int exec_load_chrp (inode_t *file, void 
                             /* Find file name end */
                         redo:
                             for (endc = pos;
-                                 *endc != ' ' && *endc != '"' && *endc != '\n';
+                                 *endc != ' ' && *endc != '"' &&
+                                 *endc != '\n' && *endc != '\r';
                                  endc++)
                                 continue;
                             if (memcmp(pos, "ofwboot", 7) == 0) {
@@ -274,8 +275,7 @@ int exec_load_chrp (inode_t *file, void 
                             *endc = '/';
                         }
                         /* check if it's a path or just a file */
-                        if (strchr(pos, '/') == NULL ||
-                            (pos[0] == '/' && pos[1] == '/')) {
+                        if (pos[0] == '/' && pos[1] == '/') {
                             unsigned char *bootdir;
                             bootdir = fs_get_boot_dirname(part_fs(part));
                             if (bootdir == NULL) {

Index: Makefile
===================================================================
--- Makefile	(revision 104)
+++ Makefile	(working copy)
@@ -72,6 +72,7 @@ main.out_OBJS:= main.o bootinfos.o bloc.
 main.out_OBJS:= $(addprefix $(OBJDIR)/, $(main.out_OBJS))
 # Pseudo-libc objects
 FORMAT_FUNCS:= _vprintf printf sprintf snprintf vprintf vsprintf vsnprintf
+FORMAT_FUNCS+= dprintf vdprintf
 MEM_FUNCS:= memcpy memccpy mempcpy memmove memcmove mempmove
 MEM_FUNCS+= memset memcmp memchr rawmemchr memrchr memmem
 STR_FUNCS:= strcpy strdup strndup stpcpy stpncpy strcat strncat

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2005-02-24 11:24 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-02-23 22:28 [Qemu-devel] [PATCH] qemu PPC Linux 2.6 IDE Thayne Harbaugh
2005-02-24 10:52 ` [Qemu-devel] " J. Mayer

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).