Changeset View
Changeset View
Standalone View
Standalone View
head/sys/arm/mv/mv_pci.c
| Show First 20 Lines • Show All 94 Lines • ▼ Show 20 Lines | |||||
| struct mv_pci_range { | struct mv_pci_range { | ||||
| u_long base_pci; | u_long base_pci; | ||||
| u_long base_parent; | u_long base_parent; | ||||
| u_long len; | u_long len; | ||||
| }; | }; | ||||
| #define FDT_RANGES_CELLS ((3 + 3 + 2) * 2) | #define FDT_RANGES_CELLS ((3 + 3 + 2) * 2) | ||||
| #define PCI_SPACE_LEN 0x00100000 | |||||
| static void | static void | ||||
| mv_pci_range_dump(struct mv_pci_range *range) | mv_pci_range_dump(struct mv_pci_range *range) | ||||
| { | { | ||||
| #ifdef DEBUG | #ifdef DEBUG | ||||
| printf("\n"); | printf("\n"); | ||||
| printf(" base_pci = 0x%08lx\n", range->base_pci); | printf(" base_pci = 0x%08lx\n", range->base_pci); | ||||
| printf(" base_par = 0x%08lx\n", range->base_parent); | printf(" base_par = 0x%08lx\n", range->base_parent); | ||||
| printf(" len = 0x%08lx\n", range->len); | printf(" len = 0x%08lx\n", range->len); | ||||
| #endif | #endif | ||||
| } | } | ||||
| static int | static int | ||||
| mv_pci_ranges_decode(phandle_t node, struct mv_pci_range *io_space, | mv_pci_ranges_decode(phandle_t node, struct mv_pci_range *io_space, | ||||
| struct mv_pci_range *mem_space) | struct mv_pci_range *mem_space) | ||||
| { | { | ||||
| pcell_t ranges[FDT_RANGES_CELLS]; | pcell_t ranges[FDT_RANGES_CELLS]; | ||||
| struct mv_pci_range *pci_space; | struct mv_pci_range *pci_space; | ||||
| pcell_t addr_cells, size_cells, par_addr_cells; | pcell_t addr_cells, size_cells, par_addr_cells; | ||||
| pcell_t *rangesptr; | pcell_t *rangesptr; | ||||
| pcell_t cell0, cell1, cell2; | pcell_t cell0, cell1, cell2; | ||||
| int tuple_size, tuples, i, rv, offset_cells, len; | int tuple_size, tuples, i, rv, offset_cells, len; | ||||
| int portid, is_io_space; | |||||
| /* | /* | ||||
| * Retrieve 'ranges' property. | * Retrieve 'ranges' property. | ||||
| */ | */ | ||||
| if ((fdt_addrsize_cells(node, &addr_cells, &size_cells)) != 0) | if ((fdt_addrsize_cells(node, &addr_cells, &size_cells)) != 0) | ||||
| return (EINVAL); | return (EINVAL); | ||||
| if (addr_cells != 3 || size_cells != 2) | if (addr_cells != 3 || size_cells != 2) | ||||
| return (ERANGE); | return (ERANGE); | ||||
| Show All 25 Lines | mv_pci_ranges_decode(phandle_t node, struct mv_pci_range *io_space, | ||||
| offset_cells = 0; | offset_cells = 0; | ||||
| for (i = 0; i < tuples; i++) { | for (i = 0; i < tuples; i++) { | ||||
| cell0 = fdt_data_get((void *)rangesptr, 1); | cell0 = fdt_data_get((void *)rangesptr, 1); | ||||
| rangesptr++; | rangesptr++; | ||||
| cell1 = fdt_data_get((void *)rangesptr, 1); | cell1 = fdt_data_get((void *)rangesptr, 1); | ||||
| rangesptr++; | rangesptr++; | ||||
| cell2 = fdt_data_get((void *)rangesptr, 1); | cell2 = fdt_data_get((void *)rangesptr, 1); | ||||
| rangesptr++; | rangesptr++; | ||||
| portid = fdt_data_get((void *)(rangesptr+1), 1); | |||||
| if (cell0 & 0x02000000) { | if (cell0 & 0x02000000) { | ||||
| pci_space = mem_space; | pci_space = mem_space; | ||||
| is_io_space = 0; | |||||
| } else if (cell0 & 0x01000000) { | } else if (cell0 & 0x01000000) { | ||||
| pci_space = io_space; | pci_space = io_space; | ||||
| is_io_space = 1; | |||||
| } else { | } else { | ||||
| rv = ERANGE; | rv = ERANGE; | ||||
| goto out; | goto out; | ||||
| } | } | ||||
| if (par_addr_cells == 3) { | if (par_addr_cells == 3) { | ||||
| /* | /* | ||||
| * This is a PCI subnode 'ranges'. Skip cell0 and | * This is a PCI subnode 'ranges'. Skip cell0 and | ||||
| Show All 14 Lines | for (i = 0; i < tuples; i++) { | ||||
| if (size_cells > 2) { | if (size_cells > 2) { | ||||
| rv = ERANGE; | rv = ERANGE; | ||||
| goto out; | goto out; | ||||
| } | } | ||||
| pci_space->len = fdt_data_get((void *)rangesptr, size_cells); | pci_space->len = fdt_data_get((void *)rangesptr, size_cells); | ||||
| rangesptr += size_cells; | rangesptr += size_cells; | ||||
| pci_space->base_pci = cell2; | pci_space->base_pci = cell2; | ||||
| if (pci_space->len == 0) { | |||||
| pci_space->len = PCI_SPACE_LEN; | |||||
| pci_space->base_parent = fdt_immr_va + | |||||
| PCI_SPACE_LEN * ( 2 * portid + is_io_space); | |||||
| } | |||||
| } | } | ||||
| rv = 0; | rv = 0; | ||||
| out: | out: | ||||
| return (rv); | return (rv); | ||||
| } | } | ||||
| static int | static int | ||||
| mv_pci_ranges(phandle_t node, struct mv_pci_range *io_space, | mv_pci_ranges(phandle_t node, struct mv_pci_range *io_space, | ||||
| ▲ Show 20 Lines • Show All 1,066 Lines • Show Last 20 Lines | |||||