scall * to determine information about the i/o system. Since XFree86 * relies on glibc's determination to tell whether or not to use * sparse access, we need to point the pci_isa_hose at a real hose * so at least that determination is correct. */ if (hose->index == 0) pci_isa_hose = hose; io7_port->csrs = csrs; io7_port->hose = hose; hose->sysdata = io7_port; hose->io_space = alloc_resource(); hose->mem_space = alloc_resource(); /* * Base addresses for userland consumption. Since these are going * to be mapped, they are pure physical addresses. */ hose->sparse_mem_base = hose->sparse_io_base = 0; hose->dense_mem_base = IO7_MEM_PHYS(io7->pe, port); hose->dense_io_base = IO7_IO_PHYS(io7->pe, port); /* * Base addresses and resource ranges for kernel consumption. */ hose->config_space_base = (unsigned long)IO7_CONF_KERN(io7->pe, port); hose->io_space->start = (unsigned long)IO7_IO_KERN(io7->pe, port); hose->io_space->end = hose->io_space->start + IO7_IO_SPACE - 1; hose->io_space->name = mk_resource_name(io7->pe, port, "IO"); hose->io_space->flags = IORESOURCE_IO; hose->mem_space->start = (unsigned long)IO7_MEM_KERN(io7->pe, port); hose->mem_space->end = hose->mem_space->start + IO7_MEM_SPACE - 1; hose->mem_space->name = mk_resource_name(io7->pe, port, "MEM"); hose->mem_space->flags = IORESOURCE_MEM; if (request_resource(&ioport_resource, hose->io_space) < 0) printk(KERN_ERR "Failed to request IO on hose %d\n", hose->index); if (request_resource(&iomem_resource, hose->mem_space) < 0) printk(KERN_ERR "Failed to request MEM on hose %d\n", hose->index); /* * Save the existing DMA window settings for later restoration. */ for (i = 0; i < 4; i++) { io7_port->saved_wbase[i] = csrs->POx_WBASE[i].csr; io7_port->saved_wmask[i] = csrs->POx_WMASK[i].csr; io7_port->saved_tbase[i] = csrs->POx_TBASE[i].csr; } /* * Set up the PCI to main memory translation windows. * * Window 0 is scatter-gather 8MB at 8MB * Window 1 is direct access 1GB at 2GB * Window 2 is scatter-gather (up-to) 1GB at 3GB * Window 3 is disabled */ /* * TBIA before modifying windows. */ marvel_pci_tbi(hose, 0, -1); /* * Set up window 0 for scatter-gather 8MB at 8MB. */ hose->sg_isa = iommu_arena_new_node(0, hose, 0x00800000, 0x00800000, 0); hose->sg_isa->align_entry = 8; /* cache line boundary */ csrs->POx_WBASE[0].csr = hose->sg_isa->dma_base | wbase_m_ena | wbase_m_sg; csrs->POx_WMASK[0].csr = (hose->sg_isa->size - 1) & wbase_m_addr; csrs->POx_TBASE[0].csr = virt_to_phys(hose->sg_isa->ptes); /* * Set up window 1 for direct-mapped 1GB at 2GB. */ csrs->POx_WBASE[1].csr = __direct_map_base | wbase_m_ena; csrs->POx_WMASK[1].csr = (__direct_map_size - 1) & wbase_m_addr; csrs->POx_TBASE[1].csr = 0; /* * Set up window 2 for scatter-gather (up-to) 1GB at 3GB. */ hose->sg_pci = iommu_arena_new_node(0, hose, 0xc0000000, 0x40000000, 0); hose->sg_pci->align_entry = 8; /* cache line boundary */ csrs->POx_WBASE[2].csr = hose->sg_pci->dma_base | wbase_m_ena | wbase_m_sg; csrs->POx_WMASK[2].csr = (hose->sg_pci->size - 1) & wbase_m_addr; csrs->POx_TBASE[2].csr = virt_to_phys(hose->sg_pci->ptes); /* * Disable window 3. */ csrs->POx_WBASE[3].csr = 0; /* * Make sure that the AGP Monster Window is disabled. */ csrs->POx_CTRL.csr &= ~(1UL << 61); #if 1 printk("FIXME: disabling master aborts\n"); csrs->POx_MSK_HEI.csr &= ~(3UL << 14); #endif /* * TBIA after modifying windows. */ marvel_pci_tbi(hose, 0, -1); } static void __init marvel_init_io7(struct io7 *io7) { int i; printk("Initializing IO7 at PID %d\n", io7->pe); /* * Get the Port 7 CSR pointer. */ io7->csrs = IO7_PORT7_CSRS_KERN(io7->pe); /* * Init this IO7's hoses. */ for (i = 0; i < IO7_NUM_PORTS; i++) { io7_ioport_csrs *csrs = IO7_CSRS_KERN(io7->pe, i); if (csrs->POx_CACHE_CTL.csr == 8) { io7->ports[i].enabled = 1; io7_init_hose(io7, i); } } } static void __init marvel_io7_present(gct6_node *node) { int pe; if (node->type != GCT_TYPE_HOSE || node->subtype != GCT_SUBTYPE_IO_PORT_MODULE) return; pe = (node->id >> 8) & 0xff; printk("Found an IO7 at PID %d\n", pe); alloc_io7(pe); } static void __init marvel_find_console_vga_hose(void) { #ifdef CONFIG_VGA_HOSE u64 *pu64 = (u64 *)((u64)hwrpb + hwrpb->ctbt_offset); if (pu64[7] == 3) { /* TERM_TYPE == graphics */ struct pci_controller *hose = NULL; int h = (pu64[30] >> 24) & 0xff; /* TERM_OUT_LOC, hose # */ struct io7 *io7; int pid, port; /* FIXME - encoding is going to have to change for Marvel * since hose will be able to overflow a byte... * need to fix this decode when the console * changes its encoding */ printk("console graphics is on hose %d (console)\n", h); /* * The console's hose numbering is: * * hose: PID * hose<1:0>: PORT * * We need to find the hose at that pid and port */ pid = h >> 2; port = h & 3; if ((io7 = marvel_find_io7(pid))) hose = io7->ports[port].hose; if (hose) { printk("Console graphics on hose %d\n", hose->index); pci_vga_hose = hose; } } #endif } gct6_search_struct gct_wanted_node_list[] __initdata = { { GCT_TYPE_HOSE, GCT_SUBTYPE_IO_PORT_MODULE, marvel_io7_present }, { 0, 0, NULL } }; /* * In case the GCT is not complete, let the user specify PIDs with IO7s * at boot time. Syntax is 'io7=a,b,c,...,n' where a-n are the PIDs (decimal) * where IO7s are connected */ static int __init marvel_specify_io7(char *str) { unsigned long pid; struct io7 *io7; char *pchar; do { pid = simple_strtoul(str, &pchar, 0); if (pchar != str) { printk("User-specified IO7 at PID %lu\n", pid); io7 = alloc_io7(pid); if (io7) marvel_init_io7(io7); } if (pchar == str) pchar++; str = pchar; } while(*str); return 1; } __setup("io7=", marvel_specify_io7); void __init marvel_init_arch(void) { struct io7 *io7; /* With multiple PCI busses, we play with I/O as physical addrs. */ ioport_resource.end = ~0UL; /* PCI DMA Direct Mapping is 1GB at 2GB. */ __direct_map_base = 0x80000000; __direct_map_size = 0x40000000; /* Parse the config tree. */ gct6_find_nodes(GCT_NODE_PTR(0), gct_wanted_node_list); /* Init the io7s. */ for (io7 = NULL; NULL != (io7 = marvel_next_io7(io7)); ) marvel_init_io7(io7); /* Check for graphic console location (if any). */ marvel_find_console_vga_hose(); } void marvel_kill_arch(int mode) { }