|  | @@ -339,3 +339,165 @@ marvel_init_io7(struct io7 *io7)
 | 
	
		
			
				|  |  |  	 * 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);
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +void
 | 
	
		
			
				|  |  | +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)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +	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<n:2>: 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;
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +gct6_search_struct gct_wanted_node_list[] = {
 | 
	
		
			
				|  |  | +	{ 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)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/*
 | 
	
		
			
				|  |  | + * PCI Configuration Space access functions
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * Configuration space addresses have the following format:
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * 	|2 2 2 2|1 1 1 1|1 1 1 1|1 1 
 | 
	
		
			
				|  |  | + * 	|3 2 1 0|9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0
 | 
	
		
			
				|  |  | + * 	+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 | 
	
		
			
				|  |  | + * 	|B|B|B|B|B|B|B|B|D|D|D|D|D|F|F|F|R|R|R|R|R|R|R|R|
 | 
	
		
			
				|  |  | + * 	+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + *	 n:24	reserved for hose base
 | 
	
		
			
				|  |  | + *	23:16	bus number (8 bits = 128 possible buses)
 | 
	
		
			
				|  |  | + *	15:11	Device number (5 bits)
 | 
	
		
			
				|  |  | + *	10:8	function number
 | 
	
		
			
				|  |  | + *	 7:2	register number
 | 
	
		
			
				|  |  | + *  
 | 
	
		
			
				|  |  | + * Notes:
 | 
	
		
			
				|  |  | + *	IO7 determines whether to use a type 0 or type 1 config cycle
 | 
	
		
			
				|  |  | + *	based on the bus number. Therefore the bus number must be set 
 | 
	
		
			
				|  |  | + *	to 0 for the root bus on any hose.
 | 
	
		
			
				|  |  | + *	
 | 
	
		
			
				|  |  | + *	The function number selects which function of a multi-function device 
 | 
	
		
			
				|  |  | + *	(e.g., SCSI and Ethernet).
 | 
	
		
			
				|  |  | + * 
 | 
	
		
			
				|  |  | + */
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +static inline unsigned long
 | 
	
		
			
				|  |  | +build_conf_addr(struct pci_controller *hose, u8 bus, 
 | 
	
		
			
				|  |  | +		unsigned int devfn, int where)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +	return (hose->config_space_base | (bus << 16) | (devfn << 8) | where);
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 |