Author: gonzo
Date: Wed Aug 15 03:49:10 2012
New Revision: 239274
URL: http://svn.freebsd.org/changeset/base/239274

Log:
  Merging of projects/armv6, part 4
  
  r233822:
    Remove useless and wrong piece of code in fdt_get_range() which i
    overwrites passed phandle_t node. Modify debug printf in fdt_reg_to_rl()
    to be consistent (that is, print start and end *virtual* addresses).
  
  r230560:
    Handle "ranges;"
    Make fdt_reg_to_rl() responsible for mapping the device memory, instead
    on just hoping that there's only one simplebus, and using fdt_immr_va as
    the base VA.
  
  r230315
    Add a function to get the PA from range, instead of (ab)using
    fdt_immr_pa, and use it for the UART driver

Modified:
  head/sys/dev/fdt/fdt_common.c
  head/sys/dev/fdt/fdt_common.h
  head/sys/dev/fdt/fdtbus.c
  head/sys/dev/fdt/simplebus.c
  head/sys/dev/uart/uart_bus_fdt.c

Modified: head/sys/dev/fdt/fdt_common.c
==============================================================================
--- head/sys/dev/fdt/fdt_common.c       Wed Aug 15 03:33:57 2012        
(r239273)
+++ head/sys/dev/fdt/fdt_common.c       Wed Aug 15 03:49:10 2012        
(r239274)
@@ -35,6 +35,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/kernel.h>
 #include <sys/module.h>
 #include <sys/bus.h>
+#include <sys/limits.h>
 
 #include <machine/fdt.h>
 #include <machine/resource.h>
@@ -63,30 +64,12 @@ vm_offset_t fdt_immr_va;
 vm_offset_t fdt_immr_size;
 
 int
-fdt_immr_addr(vm_offset_t immr_va)
+fdt_get_range(phandle_t node, int range_id, u_long *base, u_long *size)
 {
        pcell_t ranges[6], *rangesptr;
-       phandle_t node;
-       u_long base, size;
        pcell_t addr_cells, size_cells, par_addr_cells;
        int len, tuple_size, tuples;
 
-       /*
-        * Try to access the SOC node directly i.e. through /aliases/.
-        */
-       if ((node = OF_finddevice("soc")) != -1)
-               if (fdt_is_compatible_strict(node, "simple-bus"))
-                       goto moveon;
-       /*
-        * Find the node the long way.
-        */
-       if ((node = OF_finddevice("/")) == -1)
-               return (ENXIO);
-
-       if ((node = fdt_find_compatible(node, "simple-bus", 1)) == 0)
-               return (ENXIO);
-
-moveon:
        if ((fdt_addrsize_cells(node, &addr_cells, &size_cells)) != 0)
                return (ENXIO);
        /*
@@ -99,6 +82,14 @@ moveon:
        len = OF_getproplen(node, "ranges");
        if (len > sizeof(ranges))
                return (ENOMEM);
+       if (len == 0) {
+               *base = 0;
+               *size = ULONG_MAX;
+               return (0);
+       }
+
+       if (!(range_id < len))
+               return (ERANGE);
 
        if (OF_getprop(node, "ranges", ranges, sizeof(ranges)) <= 0)
                return (EINVAL);
@@ -111,21 +102,48 @@ moveon:
            addr_cells, size_cells)) {
                return (ERANGE);
        }
-       base = 0;
-       size = 0;
-       rangesptr = &ranges[0];
+       *base = 0;
+       *size = 0;
+       rangesptr = &ranges[range_id];
 
-       base = fdt_data_get((void *)rangesptr, addr_cells);
+       *base = fdt_data_get((void *)rangesptr, addr_cells);
        rangesptr += addr_cells;
-       base += fdt_data_get((void *)rangesptr, par_addr_cells);
+       *base += fdt_data_get((void *)rangesptr, par_addr_cells);
        rangesptr += par_addr_cells;
-       size = fdt_data_get((void *)rangesptr, size_cells);
+       *size = fdt_data_get((void *)rangesptr, size_cells);
+       return (0);
+}
 
-       fdt_immr_pa = base;
-       fdt_immr_va = immr_va;
-       fdt_immr_size = size;
+int
+fdt_immr_addr(vm_offset_t immr_va)
+{
+       phandle_t node;
+       u_long base, size;
+       int r;
 
-       return (0);
+       /*
+        * Try to access the SOC node directly i.e. through /aliases/.
+        */
+       if ((node = OF_finddevice("soc")) != 0)
+               if (fdt_is_compatible_strict(node, "simple-bus"))
+                       goto moveon;
+       /*
+        * Find the node the long way.
+        */
+       if ((node = OF_finddevice("/")) == 0)
+               return (ENXIO);
+
+       if ((node = fdt_find_compatible(node, "simple-bus", 1)) == 0)
+               return (ENXIO);
+
+moveon:
+       if ((r = fdt_get_range(node, 0, &base, &size)) == 0) {
+               fdt_immr_pa = base;
+               fdt_immr_va = immr_va;
+               fdt_immr_size = size;
+       }
+
+       return (r);
 }
 
 /*
@@ -401,16 +419,19 @@ fdt_regsize(phandle_t node, u_long *base
 }
 
 int
-fdt_reg_to_rl(phandle_t node, struct resource_list *rl, u_long base)
+fdt_reg_to_rl(phandle_t node, struct resource_list *rl)
 {
        u_long start, end, count;
        pcell_t *reg, *regptr;
        pcell_t addr_cells, size_cells;
        int tuple_size, tuples;
        int i, rv;
+       long vaddr;
+       long busaddr, bussize;
 
        if (fdt_addrsize_cells(OF_parent(node), &addr_cells, &size_cells) != 0)
                return (ENXIO);
+       fdt_get_range(OF_parent(node), 0, &busaddr, &bussize);
 
        tuple_size = sizeof(pcell_t) * (addr_cells + size_cells);
        tuples = OF_getprop_alloc(node, "reg", tuple_size, (void **)&reg);
@@ -432,14 +453,15 @@ fdt_reg_to_rl(phandle_t node, struct res
                reg += addr_cells + size_cells;
 
                /* Calculate address range relative to base. */
-               start &= 0x000ffffful;
-               start = base + start;
-               end = start + count - 1;
+               start += busaddr;
+               if (bus_space_map(fdtbus_bs_tag, start, count, 0, &vaddr) != 0)
+                       panic("Couldn't map the device memory");
+               end = vaddr + count - 1;
 
-               debugf("reg addr start = %lx, end = %lx, count = %lx\n", start,
+               debugf("reg addr start = %lx, end = %lx, count = %lx\n", vaddr,
                    end, count);
 
-               resource_list_add(rl, SYS_RES_MEMORY, i, start, end,
+               resource_list_add(rl, SYS_RES_MEMORY, i, vaddr, end,
                    count);
        }
        rv = 0;

Modified: head/sys/dev/fdt/fdt_common.h
==============================================================================
--- head/sys/dev/fdt/fdt_common.h       Wed Aug 15 03:33:57 2012        
(r239273)
+++ head/sys/dev/fdt/fdt_common.h       Wed Aug 15 03:49:10 2012        
(r239274)
@@ -91,6 +91,7 @@ int fdt_data_verify(void *, int);
 phandle_t fdt_find_compatible(phandle_t, const char *, int);
 int fdt_get_mem_regions(struct mem_region *, int *, uint32_t *);
 int fdt_get_phyaddr(phandle_t, device_t, int *, void **);
+int fdt_get_range(phandle_t, int, u_long *, u_long *);
 int fdt_immr_addr(vm_offset_t);
 int fdt_regsize(phandle_t, u_long *, u_long *);
 int fdt_intr_decode(phandle_t, pcell_t *, int *, int *, int *);
@@ -107,7 +108,7 @@ int fdt_pci_ranges_decode(phandle_t, str
     struct fdt_pci_range *);
 int fdt_pci_route_intr(int, int, int, int, struct fdt_pci_intr *, int *);
 int fdt_ranges_verify(pcell_t *, int, int, int, int);
-int fdt_reg_to_rl(phandle_t, struct resource_list *, u_long);
+int fdt_reg_to_rl(phandle_t, struct resource_list *);
 int fdt_pm(phandle_t);
 
 #endif /* _FDT_COMMON_H_ */

Modified: head/sys/dev/fdt/fdtbus.c
==============================================================================
--- head/sys/dev/fdt/fdtbus.c   Wed Aug 15 03:33:57 2012        (r239273)
+++ head/sys/dev/fdt/fdtbus.c   Wed Aug 15 03:49:10 2012        (r239274)
@@ -289,7 +289,7 @@ newbus_device_create(device_t dev_par, p
 
        resource_list_init(&di->di_res);
 
-       if (fdt_reg_to_rl(node, &di->di_res, fdt_immr_va)) {
+       if (fdt_reg_to_rl(node, &di->di_res)) {
                device_printf(child, "could not process 'reg' property\n");
                newbus_device_destroy(child);
                child = NULL;

Modified: head/sys/dev/fdt/simplebus.c
==============================================================================
--- head/sys/dev/fdt/simplebus.c        Wed Aug 15 03:33:57 2012        
(r239273)
+++ head/sys/dev/fdt/simplebus.c        Wed Aug 15 03:49:10 2012        
(r239274)
@@ -61,9 +61,6 @@ static MALLOC_DEFINE(M_SIMPLEBUS, "simpl
 struct simplebus_softc {
        int     sc_addr_cells;
        int     sc_size_cells;
-       u_long  sc_start_pa;
-       u_long  sc_start_va;
-       u_long  sc_size;
 };
 
 struct simplebus_devinfo {
@@ -155,10 +152,6 @@ simplebus_attach(device_t dev)
 
        sc = device_get_softc(dev);
 
-       sc->sc_start_pa = fdt_immr_pa;
-       sc->sc_start_va = fdt_immr_va;
-       sc->sc_size = fdt_immr_size;
-
        /*
         * Walk simple-bus and add direct subordinates as our children.
         */
@@ -182,10 +175,11 @@ simplebus_attach(device_t dev)
                }
 
                resource_list_init(&di->di_res);
-
-               if (fdt_reg_to_rl(dt_child, &di->di_res, sc->sc_start_va)) {
-                       device_printf(dev, "%s: could not process 'reg' "
+               if (fdt_reg_to_rl(dt_child, &di->di_res)) {
+                       device_printf(dev,
+                           "%s: could not process 'reg' "
                            "property\n", di->di_ofw.obd_name);
+                       /* XXX should unmap */
                        ofw_bus_gen_destroy_devinfo(&di->di_ofw);
                        free(di, M_SIMPLEBUS);
                        continue;
@@ -195,6 +189,7 @@ simplebus_attach(device_t dev)
                        device_printf(dev, "%s: could not process "
                            "'interrupts' property\n", di->di_ofw.obd_name);
                        resource_list_free(&di->di_res);
+                       /* XXX should unmap */
                        ofw_bus_gen_destroy_devinfo(&di->di_ofw);
                        free(di, M_SIMPLEBUS);
                        continue;
@@ -206,6 +201,7 @@ simplebus_attach(device_t dev)
                        device_printf(dev, "could not add child: %s\n",
                            di->di_ofw.obd_name);
                        resource_list_free(&di->di_res);
+                       /* XXX should unmap */
                        ofw_bus_gen_destroy_devinfo(&di->di_ofw);
                        free(di, M_SIMPLEBUS);
                        continue;

Modified: head/sys/dev/uart/uart_bus_fdt.c
==============================================================================
--- head/sys/dev/uart/uart_bus_fdt.c    Wed Aug 15 03:33:57 2012        
(r239273)
+++ head/sys/dev/uart/uart_bus_fdt.c    Wed Aug 15 03:49:10 2012        
(r239274)
@@ -137,7 +137,7 @@ uart_cpu_getdev(int devtype, struct uart
        struct uart_class *class;
        phandle_t node, chosen;
        pcell_t shift, br, rclk;
-       u_long start, size;
+       u_long start, size, pbase, psize;
        int err;
 
        uart_bus_space_mem = fdtbus_bs_tag;
@@ -197,7 +197,9 @@ uart_cpu_getdev(int devtype, struct uart
        err = fdt_regsize(node, &start, &size);
        if (err)
                return (ENXIO);
-       start += fdt_immr_va;
+
+       fdt_get_range(OF_parent(node), 0, &pbase, &psize);
+       start += pbase;
 
        return (bus_space_map(di->bas.bst, start, size, 0, &di->bas.bsh));
 }
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "[email protected]"

Reply via email to