Remove dev/fdt/fdt_pci.c, which was code specific to Marvell ARM SoCs,
related to setting up static device mappings. Since it was only used by arm/mv/mv_pci.c, it's now just static functions within that file, plus one public function that gets called only from arm/mv/mv_machdep.c.
This commit is contained in:
parent
3e02329a38
commit
02c7dba919
@ -54,7 +54,5 @@ extern bus_space_tag_t fdtbus_bs_tag;
|
||||
struct arm_devmap_entry;
|
||||
|
||||
int fdt_localbus_devmap(phandle_t, struct arm_devmap_entry *, int, int *);
|
||||
int fdt_pci_devmap(phandle_t, struct arm_devmap_entry *devmap, vm_offset_t,
|
||||
vm_offset_t);
|
||||
|
||||
#endif /* _MACHINE_FDT_H_ */
|
||||
|
@ -294,11 +294,11 @@ out:
|
||||
}
|
||||
|
||||
/*
|
||||
* Supply a default do-nothing implementation of fdt_pci_devmap() via a weak
|
||||
* Supply a default do-nothing implementation of mv_pci_devmap() via a weak
|
||||
* alias. Many Marvell platforms don't support a PCI interface, but to support
|
||||
* those that do, we end up with a reference to this function below, in
|
||||
* initarm_devmap_init(). If "device pci" appears in the kernel config, the
|
||||
* real implementation of this function in dev/fdt/fdt_pci.c overrides the weak
|
||||
* real implementation of this function in arm/mv/mv_pci.c overrides the weak
|
||||
* alias defined here.
|
||||
*/
|
||||
int mv_default_fdt_pci_devmap(phandle_t node, struct arm_devmap_entry *devmap,
|
||||
@ -310,7 +310,7 @@ mv_default_fdt_pci_devmap(phandle_t node, struct arm_devmap_entry *devmap,
|
||||
|
||||
return (0);
|
||||
}
|
||||
__weak_reference(mv_default_fdt_pci_devmap, fdt_pci_devmap);
|
||||
__weak_reference(mv_default_fdt_pci_devmap, mv_pci_devmap);
|
||||
|
||||
/*
|
||||
* XXX: When device entry in devmap has pd_size smaller than section size,
|
||||
@ -379,7 +379,7 @@ initarm_devmap_init(void)
|
||||
* XXX this should account for PCI and multiple ranges
|
||||
* of a given kind.
|
||||
*/
|
||||
if (fdt_pci_devmap(child, &fdt_devmap[i], MV_PCI_VA_IO_BASE,
|
||||
if (mv_pci_devmap(child, &fdt_devmap[i], MV_PCI_VA_IO_BASE,
|
||||
MV_PCI_VA_MEM_BASE) != 0)
|
||||
return (ENXIO);
|
||||
i += 2;
|
||||
|
@ -70,6 +70,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include "ofw_bus_if.h"
|
||||
#include "pcib_if.h"
|
||||
|
||||
#include <machine/devmap.h>
|
||||
#include <machine/resource.h>
|
||||
#include <machine/bus.h>
|
||||
|
||||
@ -83,6 +84,172 @@ __FBSDID("$FreeBSD$");
|
||||
#define debugf(fmt, args...)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Code and data related to fdt-based PCI configuration.
|
||||
*
|
||||
* This stuff used to be in dev/fdt/fdt_pci.c and fdt_common.h, but it was
|
||||
* always Marvell-specific so that was deleted and the code now lives here.
|
||||
*/
|
||||
|
||||
struct mv_pci_range {
|
||||
u_long base_pci;
|
||||
u_long base_parent;
|
||||
u_long len;
|
||||
};
|
||||
|
||||
#define FDT_RANGES_CELLS ((3 + 3 + 2) * 2)
|
||||
|
||||
static void
|
||||
mv_pci_range_dump(struct mv_pci_range *range)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
printf("\n");
|
||||
printf(" base_pci = 0x%08lx\n", range->base_pci);
|
||||
printf(" base_par = 0x%08lx\n", range->base_parent);
|
||||
printf(" len = 0x%08lx\n", range->len);
|
||||
#endif
|
||||
}
|
||||
|
||||
static int
|
||||
mv_pci_ranges_decode(phandle_t node, struct mv_pci_range *io_space,
|
||||
struct mv_pci_range *mem_space)
|
||||
{
|
||||
pcell_t ranges[FDT_RANGES_CELLS];
|
||||
struct mv_pci_range *pci_space;
|
||||
pcell_t addr_cells, size_cells, par_addr_cells;
|
||||
pcell_t *rangesptr;
|
||||
pcell_t cell0, cell1, cell2;
|
||||
int tuple_size, tuples, i, rv, offset_cells, len;
|
||||
|
||||
/*
|
||||
* Retrieve 'ranges' property.
|
||||
*/
|
||||
if ((fdt_addrsize_cells(node, &addr_cells, &size_cells)) != 0)
|
||||
return (EINVAL);
|
||||
if (addr_cells != 3 || size_cells != 2)
|
||||
return (ERANGE);
|
||||
|
||||
par_addr_cells = fdt_parent_addr_cells(node);
|
||||
if (par_addr_cells > 3)
|
||||
return (ERANGE);
|
||||
|
||||
len = OF_getproplen(node, "ranges");
|
||||
if (len > sizeof(ranges))
|
||||
return (ENOMEM);
|
||||
|
||||
if (OF_getprop(node, "ranges", ranges, sizeof(ranges)) <= 0)
|
||||
return (EINVAL);
|
||||
|
||||
tuple_size = sizeof(pcell_t) * (addr_cells + par_addr_cells +
|
||||
size_cells);
|
||||
tuples = len / tuple_size;
|
||||
|
||||
/*
|
||||
* Initialize the ranges so that we don't have to worry about
|
||||
* having them all defined in the FDT. In particular, it is
|
||||
* perfectly fine not to want I/O space on PCI busses.
|
||||
*/
|
||||
bzero(io_space, sizeof(*io_space));
|
||||
bzero(mem_space, sizeof(*mem_space));
|
||||
|
||||
rangesptr = &ranges[0];
|
||||
offset_cells = 0;
|
||||
for (i = 0; i < tuples; i++) {
|
||||
cell0 = fdt_data_get((void *)rangesptr, 1);
|
||||
rangesptr++;
|
||||
cell1 = fdt_data_get((void *)rangesptr, 1);
|
||||
rangesptr++;
|
||||
cell2 = fdt_data_get((void *)rangesptr, 1);
|
||||
rangesptr++;
|
||||
|
||||
if (cell0 & 0x02000000) {
|
||||
pci_space = mem_space;
|
||||
} else if (cell0 & 0x01000000) {
|
||||
pci_space = io_space;
|
||||
} else {
|
||||
rv = ERANGE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (par_addr_cells == 3) {
|
||||
/*
|
||||
* This is a PCI subnode 'ranges'. Skip cell0 and
|
||||
* cell1 of this entry and only use cell2.
|
||||
*/
|
||||
offset_cells = 2;
|
||||
rangesptr += offset_cells;
|
||||
}
|
||||
|
||||
if (fdt_data_verify((void *)rangesptr, par_addr_cells -
|
||||
offset_cells)) {
|
||||
rv = ERANGE;
|
||||
goto out;
|
||||
}
|
||||
pci_space->base_parent = fdt_data_get((void *)rangesptr,
|
||||
par_addr_cells - offset_cells);
|
||||
rangesptr += par_addr_cells - offset_cells;
|
||||
|
||||
if (fdt_data_verify((void *)rangesptr, size_cells)) {
|
||||
rv = ERANGE;
|
||||
goto out;
|
||||
}
|
||||
pci_space->len = fdt_data_get((void *)rangesptr, size_cells);
|
||||
rangesptr += size_cells;
|
||||
|
||||
pci_space->base_pci = cell2;
|
||||
}
|
||||
rv = 0;
|
||||
out:
|
||||
return (rv);
|
||||
}
|
||||
|
||||
static int
|
||||
mv_pci_ranges(phandle_t node, struct mv_pci_range *io_space,
|
||||
struct mv_pci_range *mem_space)
|
||||
{
|
||||
int err;
|
||||
|
||||
debugf("Processing PCI node: %x\n", node);
|
||||
if ((err = mv_pci_ranges_decode(node, io_space, mem_space)) != 0) {
|
||||
debugf("could not decode parent PCI node 'ranges'\n");
|
||||
return (err);
|
||||
}
|
||||
|
||||
debugf("Post fixup dump:\n");
|
||||
mv_pci_range_dump(io_space);
|
||||
mv_pci_range_dump(mem_space);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
mv_pci_devmap(phandle_t node, struct arm_devmap_entry *devmap, vm_offset_t io_va,
|
||||
vm_offset_t mem_va)
|
||||
{
|
||||
struct mv_pci_range io_space, mem_space;
|
||||
int error;
|
||||
|
||||
if ((error = mv_pci_ranges_decode(node, &io_space, &mem_space)) != 0)
|
||||
return (error);
|
||||
|
||||
devmap->pd_va = (io_va ? io_va : io_space.base_parent);
|
||||
devmap->pd_pa = io_space.base_parent;
|
||||
devmap->pd_size = io_space.len;
|
||||
devmap->pd_prot = VM_PROT_READ | VM_PROT_WRITE;
|
||||
devmap->pd_cache = PTE_NOCACHE;
|
||||
devmap++;
|
||||
|
||||
devmap->pd_va = (mem_va ? mem_va : mem_space.base_parent);
|
||||
devmap->pd_pa = mem_space.base_parent;
|
||||
devmap->pd_size = mem_space.len;
|
||||
devmap->pd_prot = VM_PROT_READ | VM_PROT_WRITE;
|
||||
devmap->pd_cache = PTE_NOCACHE;
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Code and data related to the Marvell pcib driver.
|
||||
*/
|
||||
|
||||
#define PCI_CFG_ENA (1U << 31)
|
||||
#define PCI_CFG_BUS(bus) (((bus) & 0xff) << 16)
|
||||
#define PCI_CFG_DEV(dev) (((dev) & 0x1f) << 11)
|
||||
@ -912,13 +1079,13 @@ mv_pcib_route_interrupt(device_t bus, device_t dev, int pin)
|
||||
static int
|
||||
mv_pcib_decode_win(phandle_t node, struct mv_pcib_softc *sc)
|
||||
{
|
||||
struct fdt_pci_range io_space, mem_space;
|
||||
struct mv_pci_range io_space, mem_space;
|
||||
device_t dev;
|
||||
int error;
|
||||
|
||||
dev = sc->sc_dev;
|
||||
|
||||
if ((error = fdt_pci_ranges(node, &io_space, &mem_space)) != 0) {
|
||||
if ((error = mv_pci_ranges(node, &io_space, &mem_space)) != 0) {
|
||||
device_printf(dev, "could not retrieve 'ranges' data\n");
|
||||
return (error);
|
||||
}
|
||||
@ -1026,3 +1193,4 @@ mv_pcib_release_msi(device_t dev, device_t child, int count, int *irqs)
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -46,6 +46,8 @@
|
||||
#include <vm/pmap.h>
|
||||
#include <machine/vm.h>
|
||||
|
||||
#include <dev/ofw/openfirm.h>
|
||||
|
||||
#define MV_TYPE_PCI 0
|
||||
#define MV_TYPE_PCIE 1
|
||||
|
||||
@ -135,4 +137,9 @@ uint32_t mv_drbl_get_msg(int mnr, int dir, int unit);
|
||||
|
||||
int mv_msi_data(int irq, uint64_t *addr, uint32_t *data);
|
||||
|
||||
struct arm_devmap_entry;
|
||||
|
||||
int mv_pci_devmap(phandle_t, struct arm_devmap_entry *, vm_offset_t,
|
||||
vm_offset_t);
|
||||
|
||||
#endif /* _MVVAR_H_ */
|
||||
|
@ -1402,7 +1402,6 @@ dev/fb/fb_if.m standard
|
||||
dev/fb/splash.c optional sc splash
|
||||
dev/fdt/fdt_common.c optional fdt
|
||||
dev/fdt/fdt_ic_if.m optional fdt
|
||||
dev/fdt/fdt_pci.c optional fdt pci
|
||||
dev/fdt/fdt_slicer.c optional fdt cfi | fdt nand
|
||||
dev/fdt/fdt_static_dtb.S optional fdt fdt_dtb_static \
|
||||
dependency "$S/boot/fdt/dts/${FDT_DTS_FILE}"
|
||||
|
@ -40,12 +40,6 @@
|
||||
|
||||
#define DI_MAX_INTR_NUM 32
|
||||
|
||||
struct fdt_pci_range {
|
||||
u_long base_pci;
|
||||
u_long base_parent;
|
||||
u_long len;
|
||||
};
|
||||
|
||||
struct fdt_sense_level {
|
||||
enum intr_trigger trig;
|
||||
enum intr_polarity pol;
|
||||
@ -100,9 +94,6 @@ int fdt_is_enabled(phandle_t);
|
||||
int fdt_pm_is_enabled(phandle_t);
|
||||
int fdt_is_type(phandle_t, const char *);
|
||||
int fdt_parent_addr_cells(phandle_t);
|
||||
int fdt_pci_ranges(phandle_t, struct fdt_pci_range *, struct fdt_pci_range *);
|
||||
int fdt_pci_ranges_decode(phandle_t, struct fdt_pci_range *,
|
||||
struct fdt_pci_range *);
|
||||
int fdt_ranges_verify(pcell_t *, int, int, int, int);
|
||||
int fdt_reg_to_rl(phandle_t, struct resource_list *);
|
||||
int fdt_pm(phandle_t);
|
||||
|
@ -1,211 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 2010 The FreeBSD Foundation
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software was developed by Semihalf under sponsorship from
|
||||
* the FreeBSD Foundation.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/ktr.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/rman.h>
|
||||
#include <sys/malloc.h>
|
||||
|
||||
#include <dev/fdt/fdt_common.h>
|
||||
#include <dev/pci/pcireg.h>
|
||||
|
||||
#if defined(__arm__)
|
||||
#include <vm/vm.h>
|
||||
#include <vm/pmap.h>
|
||||
#include <machine/devmap.h>
|
||||
#include <machine/fdt.h>
|
||||
#endif
|
||||
|
||||
#include "ofw_bus_if.h"
|
||||
#include "pcib_if.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
#define debugf(fmt, args...) do { printf("%s(): ", __func__); \
|
||||
printf(fmt,##args); } while (0)
|
||||
#else
|
||||
#define debugf(fmt, args...)
|
||||
#endif
|
||||
|
||||
#define FDT_RANGES_CELLS ((3 + 3 + 2) * 2)
|
||||
|
||||
static void
|
||||
fdt_pci_range_dump(struct fdt_pci_range *range)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
printf("\n");
|
||||
printf(" base_pci = 0x%08lx\n", range->base_pci);
|
||||
printf(" base_par = 0x%08lx\n", range->base_parent);
|
||||
printf(" len = 0x%08lx\n", range->len);
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
fdt_pci_ranges_decode(phandle_t node, struct fdt_pci_range *io_space,
|
||||
struct fdt_pci_range *mem_space)
|
||||
{
|
||||
pcell_t ranges[FDT_RANGES_CELLS];
|
||||
struct fdt_pci_range *pci_space;
|
||||
pcell_t addr_cells, size_cells, par_addr_cells;
|
||||
pcell_t *rangesptr;
|
||||
pcell_t cell0, cell1, cell2;
|
||||
int tuple_size, tuples, i, rv, offset_cells, len;
|
||||
|
||||
/*
|
||||
* Retrieve 'ranges' property.
|
||||
*/
|
||||
if ((fdt_addrsize_cells(node, &addr_cells, &size_cells)) != 0)
|
||||
return (EINVAL);
|
||||
if (addr_cells != 3 || size_cells != 2)
|
||||
return (ERANGE);
|
||||
|
||||
par_addr_cells = fdt_parent_addr_cells(node);
|
||||
if (par_addr_cells > 3)
|
||||
return (ERANGE);
|
||||
|
||||
len = OF_getproplen(node, "ranges");
|
||||
if (len > sizeof(ranges))
|
||||
return (ENOMEM);
|
||||
|
||||
if (OF_getprop(node, "ranges", ranges, sizeof(ranges)) <= 0)
|
||||
return (EINVAL);
|
||||
|
||||
tuple_size = sizeof(pcell_t) * (addr_cells + par_addr_cells +
|
||||
size_cells);
|
||||
tuples = len / tuple_size;
|
||||
|
||||
/*
|
||||
* Initialize the ranges so that we don't have to worry about
|
||||
* having them all defined in the FDT. In particular, it is
|
||||
* perfectly fine not to want I/O space on PCI busses.
|
||||
*/
|
||||
bzero(io_space, sizeof(*io_space));
|
||||
bzero(mem_space, sizeof(*mem_space));
|
||||
|
||||
rangesptr = &ranges[0];
|
||||
offset_cells = 0;
|
||||
for (i = 0; i < tuples; i++) {
|
||||
cell0 = fdt_data_get((void *)rangesptr, 1);
|
||||
rangesptr++;
|
||||
cell1 = fdt_data_get((void *)rangesptr, 1);
|
||||
rangesptr++;
|
||||
cell2 = fdt_data_get((void *)rangesptr, 1);
|
||||
rangesptr++;
|
||||
|
||||
if (cell0 & 0x02000000) {
|
||||
pci_space = mem_space;
|
||||
} else if (cell0 & 0x01000000) {
|
||||
pci_space = io_space;
|
||||
} else {
|
||||
rv = ERANGE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (par_addr_cells == 3) {
|
||||
/*
|
||||
* This is a PCI subnode 'ranges'. Skip cell0 and
|
||||
* cell1 of this entry and only use cell2.
|
||||
*/
|
||||
offset_cells = 2;
|
||||
rangesptr += offset_cells;
|
||||
}
|
||||
|
||||
if (fdt_data_verify((void *)rangesptr, par_addr_cells -
|
||||
offset_cells)) {
|
||||
rv = ERANGE;
|
||||
goto out;
|
||||
}
|
||||
pci_space->base_parent = fdt_data_get((void *)rangesptr,
|
||||
par_addr_cells - offset_cells);
|
||||
rangesptr += par_addr_cells - offset_cells;
|
||||
|
||||
if (fdt_data_verify((void *)rangesptr, size_cells)) {
|
||||
rv = ERANGE;
|
||||
goto out;
|
||||
}
|
||||
pci_space->len = fdt_data_get((void *)rangesptr, size_cells);
|
||||
rangesptr += size_cells;
|
||||
|
||||
pci_space->base_pci = cell2;
|
||||
}
|
||||
rv = 0;
|
||||
out:
|
||||
return (rv);
|
||||
}
|
||||
|
||||
int
|
||||
fdt_pci_ranges(phandle_t node, struct fdt_pci_range *io_space,
|
||||
struct fdt_pci_range *mem_space)
|
||||
{
|
||||
int err;
|
||||
|
||||
debugf("Processing PCI node: %x\n", node);
|
||||
if ((err = fdt_pci_ranges_decode(node, io_space, mem_space)) != 0) {
|
||||
debugf("could not decode parent PCI node 'ranges'\n");
|
||||
return (err);
|
||||
}
|
||||
|
||||
debugf("Post fixup dump:\n");
|
||||
fdt_pci_range_dump(io_space);
|
||||
fdt_pci_range_dump(mem_space);
|
||||
return (0);
|
||||
}
|
||||
|
||||
#if defined(__arm__)
|
||||
int
|
||||
fdt_pci_devmap(phandle_t node, struct arm_devmap_entry *devmap, vm_offset_t io_va,
|
||||
vm_offset_t mem_va)
|
||||
{
|
||||
struct fdt_pci_range io_space, mem_space;
|
||||
int error;
|
||||
|
||||
if ((error = fdt_pci_ranges_decode(node, &io_space, &mem_space)) != 0)
|
||||
return (error);
|
||||
|
||||
devmap->pd_va = (io_va ? io_va : io_space.base_parent);
|
||||
devmap->pd_pa = io_space.base_parent;
|
||||
devmap->pd_size = io_space.len;
|
||||
devmap->pd_prot = VM_PROT_READ | VM_PROT_WRITE;
|
||||
devmap->pd_cache = PTE_NOCACHE;
|
||||
devmap++;
|
||||
|
||||
devmap->pd_va = (mem_va ? mem_va : mem_space.base_parent);
|
||||
devmap->pd_pa = mem_space.base_parent;
|
||||
devmap->pd_size = mem_space.len;
|
||||
devmap->pd_prot = VM_PROT_READ | VM_PROT_WRITE;
|
||||
devmap->pd_cache = PTE_NOCACHE;
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user