Esempio n. 1
0
int __init nvram_init(void)
{
	struct device_node *nvram;
	unsigned int *nbytes_p, proplen;
	if ((nvram = find_type_devices("nvram")) != NULL) {
		nbytes_p = (unsigned int *)get_property(nvram, "#bytes", &proplen);
		if (nbytes_p && proplen == sizeof(unsigned int)) {
			rtas_nvram_size = *nbytes_p;
		}
	}
	nvram_fetch = rtas_token("nvram-fetch");
	nvram_store = rtas_token("nvram-store");
	printk(KERN_INFO "PPC64 nvram contains %d bytes\n", rtas_nvram_size);

	return misc_register(&nvram_dev);
}
Esempio n. 2
0
/*
 * Assume here that all clock rates are the same in a
 * smp system.  -- Cort
 */
int __openfirmware
of_show_percpuinfo(struct seq_file *m, int i)
{
	struct device_node *cpu_node;
	int *fp, s;
			
	cpu_node = find_type_devices("cpu");
	if (!cpu_node)
		return 0;
	for (s = 0; s < i && cpu_node->next; s++)
		cpu_node = cpu_node->next;
	fp = (int *) get_property(cpu_node, "clock-frequency", NULL);
	if (fp)
		seq_printf(m, "clock\t\t: %dMHz\n", *fp / 1000000);
	return 0;
}
Esempio n. 3
0
static int __init smp_core99_probe(void)
{
	struct device_node *cpus;
	int ncpus = 1;

	/* Maybe use systemconfiguration here ? */
	if (ppc_md.progress) ppc_md.progress("smp_core99_probe", 0x345);
	cpus = find_type_devices("cpu");
	if (cpus == NULL)
		return 0;

       	while ((cpus = cpus->next) != NULL)
	       	++ncpus;

	printk(KERN_INFO "PowerMac SMP probe found %d cpus\n", ncpus);

	if (ncpus > 1)
		openpic_request_IPIs();

	return ncpus;
}
Esempio n. 4
0
int __pmac
pmac_show_cpuinfo(struct seq_file *m)
{
	struct device_node *np;
	char *pp;
	int plen;

	/* find motherboard type */
	seq_printf(m, "machine\t\t: ");
	np = find_devices("device-tree");
	if (np != NULL) {
		pp = (char *) get_property(np, "model", NULL);
		if (pp != NULL)
			seq_printf(m, "%s\n", pp);
		else
			seq_printf(m, "PowerMac\n");
		pp = (char *) get_property(np, "compatible", &plen);
		if (pp != NULL) {
			seq_printf(m, "motherboard\t:");
			while (plen > 0) {
				int l = strlen(pp) + 1;
				seq_printf(m, " %s", pp);
				plen -= l;
				pp += l;
			}
			seq_printf(m, "\n");
		}
	} else
		seq_printf(m, "PowerMac\n");

	/* find l2 cache info */
	np = find_devices("l2-cache");
	if (np == 0)
		np = find_type_devices("cache");
	if (np != 0) {
		unsigned int *ic = (unsigned int *)
			get_property(np, "i-cache-size", NULL);
		unsigned int *dc = (unsigned int *)
			get_property(np, "d-cache-size", NULL);
		seq_printf(m, "L2 cache\t:");
		has_l2cache = 1;
		if (get_property(np, "cache-unified", NULL) != 0 && dc) {
			seq_printf(m, " %dK unified", *dc / 1024);
		} else {
			if (ic)
				seq_printf(m, " %dK instruction", *ic / 1024);
			if (dc)
				seq_printf(m, "%s %dK data",
					   (ic? " +": ""), *dc / 1024);
		}
		pp = get_property(np, "ram-type", NULL);
		if (pp)
			seq_printf(m, " %s", pp);
		seq_printf(m, "\n");
	}

	/* find ram info */
	np = find_devices("memory");
	if (np != 0) {
		int n;
		struct reg_property *reg = (struct reg_property *)
			get_property(np, "reg", &n);
		
		if (reg != 0) {
			unsigned long total = 0;

			for (n /= sizeof(struct reg_property); n > 0; --n)
				total += (reg++)->size;
			seq_printf(m, "memory\t\t: %luMB\n", total >> 20);
		}
Esempio n. 5
0
__initfunc(void
pmac_pic_init(void))
{
        int i;
        struct device_node *irqctrler;
        volatile struct pmac_irq_hw *addr;
	int second_irq;

	/* We first try to detect Apple's new Core99 chipset, since mac-io
	 * is quite different on those machines and contains an IBM MPIC2.
	 */
	irqctrler = find_type_devices("open-pic");
	if (irqctrler != NULL) {
	    printk("PowerMac using OpenPIC irq controller\n");
	    if (irqctrler->n_addrs > 0) {
#ifdef CONFIG_XMON
		struct device_node* pswitch;
#endif /* CONFIG_XMON */	
		OpenPIC = (volatile struct OpenPIC *)
			ioremap(irqctrler->addrs[0].address,
			irqctrler->addrs[0].size);
		for ( i = 0 ; i < NR_IRQS ; i++ ) {
		    irq_desc[i].ctl = &pmac_open_pic;
		    irq_desc[i].level = 0;
		}
		openpic_init(1);
		has_openpic = 1;
#ifdef CONFIG_XMON
		pswitch = find_devices("programmer-switch");
		if (pswitch && pswitch->n_intrs)
			request_irq(pswitch->intrs[0].line, xmon_irq, 0,	
				"NMI - XMON", 0);
#endif	/* CONFIG_XMON */
		return;
	    }
	    irqctrler = NULL;
	}

	/*
	 * G3 powermacs and 1999 G3 PowerBooks have 64 interrupts,
	 * 1998 G3 Series PowerBooks have 128, 
	 * other powermacs have 32.
	 * The combo ethernet/modem card for the Powerstar powerbooks
	 * (2400/3400/3500, ohare based) has a second ohare chip
	 * effectively making a total of 64.
	 */
	max_irqs = max_real_irqs = 32;
	irqctrler = find_devices("mac-io");
	if (irqctrler)
	{
		max_real_irqs = 64;
		if (irqctrler->next)
			max_irqs = 128;
		else
			max_irqs = 64;
	}
	for ( i = 0; i < max_real_irqs ; i++ )
		irq_desc[i].ctl = &pmac_pic;

	/* get addresses of first controller */
	if (irqctrler) {
		if  (irqctrler->n_addrs > 0) {
			addr = ioremap(irqctrler->addrs[0].address, 0x40);
			addr += 2;
			for (i = 0; i < 2; ++i, --addr)
				pmac_irq_hw[i] = addr;
		}
		
		/* get addresses of second controller */
		irqctrler = irqctrler->next;
		if (irqctrler && irqctrler->n_addrs > 0) {
			addr = ioremap(irqctrler->addrs[0].address, 0x40);
			addr += 2;
			for (i = 2; i < 4; ++i, --addr)
				pmac_irq_hw[i] = addr;
		}
	}

	/* PowerBooks 3400 and 3500 can have a second controller in a second
	   ohare chip, on the combo ethernet/modem card */
	if (machine_is_compatible("AAPL,3400/2400")
	     || machine_is_compatible("AAPL,3500"))
		enable_second_ohare();

	/* disable all interrupts in all controllers */
	for (i = 0; i * 32 < max_irqs; ++i)
		out_le32(&pmac_irq_hw[i]->enable, 0);
	
	/* get interrupt line of secondary interrupt controller */
	if (irqctrler) {
		second_irq = irqctrler->intrs[0].line;
		printk(KERN_INFO "irq: secondary controller on irq %d\n",
			(int)second_irq);
		if (device_is_compatible(irqctrler, "gatwick"))
			pmac_fix_gatwick_interrupts(irqctrler, max_real_irqs);
		request_irq( second_irq, gatwick_action, SA_INTERRUPT,
			     "interrupt cascade", 0 );
	}
	for (i = max_real_irqs; i < max_irqs; i++)
		irq_desc[i].ctl = &gatwick_pic;
	printk("System has %d possible interrupts\n", max_irqs);
	if (max_irqs != max_real_irqs)
		printk(KERN_DEBUG "%d interrupts on main controller\n",
			max_real_irqs);

#ifdef CONFIG_XMON
	request_irq(20, xmon_irq, 0, "NMI - XMON", 0);
#endif	/* CONFIG_XMON */
}
Esempio n. 6
0
void __init
pmac_ide_probe(void)
{
	struct device_node *np;
	int i;
	struct device_node *atas;
	struct device_node *p, **pp, *removables, **rp;
	unsigned long base;
	int irq, big_delay;
	ide_hwif_t *hwif;

	if (_machine != _MACH_Pmac)
		return;
	pp = &atas;
	rp = &removables;
	p = find_devices("ATA");
	if (p == NULL)
		p = find_devices("IDE");
	if (p == NULL)
		p = find_type_devices("ide");
	if (p == NULL)
		p = find_type_devices("ata");
	/* Move removable devices such as the media-bay CDROM
	   on the PB3400 to the end of the list. */
	for (; p != NULL; p = p->next) {
		if (p->parent && p->parent->type
		    && strcasecmp(p->parent->type, "media-bay") == 0) {
			*rp = p;
			rp = &p->next;
		} else {
			*pp = p;
			pp = &p->next;
		}
	}
	*rp = NULL;
	*pp = removables;
	big_delay = 0;

	for (i = 0, np = atas; i < MAX_HWIFS && np != NULL; np = np->next) {
		struct device_node *tp;
		int *bidp;
		int in_bay = 0;

		/*
		 * If this node is not under a mac-io or dbdma node,
		 * leave it to the generic PCI driver.
		 */
		for (tp = np->parent; tp != 0; tp = tp->parent)
			if (tp->type && (strcmp(tp->type, "mac-io") == 0
					 || strcmp(tp->type, "dbdma") == 0))
				break;
		if (tp == 0)
			continue;

		if (np->n_addrs == 0) {
			printk(KERN_WARNING "ide: no address for device %s\n",
			       np->full_name);
			continue;
		}

		/*
		 * If this slot is taken (e.g. by ide-pci.c) try the next one.
		 */
		while (i < MAX_HWIFS
		       && ide_hwifs[i].io_ports[IDE_DATA_OFFSET] != 0)
			++i;
		if (i >= MAX_HWIFS)
			break;

		base = (unsigned long) ioremap(np->addrs[0].address, 0x200) - _IO_BASE;

		/* XXX This is bogus. Should be fixed in the registry by checking
		   the kind of host interrupt controller, a bit like gatwick
		   fixes in irq.c
		 */
		if (np->n_intrs == 0) {
			printk(KERN_WARNING "ide: no intrs for device %s, using 13\n",
			       np->full_name);
			irq = 13;
		} else {
			irq = np->intrs[0].line;
		}
		pmac_ide[i].regbase = base;
		pmac_ide[i].irq = irq;
		pmac_ide[i].node = np;
		if (device_is_compatible(np, "keylargo-ata")) {
			if (strcmp(np->name, "ata-4") == 0)
				pmac_ide[i].kind = controller_kl_ata4;
			else
				pmac_ide[i].kind = controller_kl_ata3;
		} else if (device_is_compatible(np, "heathrow-ata"))
			pmac_ide[i].kind = controller_heathrow;
		else
			pmac_ide[i].kind = controller_ohare;

		bidp = (int *)get_property(np, "AAPL,bus-id", NULL);
		pmac_ide[i].aapl_bus_id =  bidp ? *bidp : 0;

		if (np->parent && np->parent->name
		    && strcasecmp(np->parent->name, "media-bay") == 0) {
#ifdef CONFIG_PMAC_PBOOK
			media_bay_set_ide_infos(np->parent,base,irq,i);
#endif /* CONFIG_PMAC_PBOOK */
			in_bay = 1;
		} else if (pmac_ide[i].kind == controller_ohare) {
			/* The code below is having trouble on some ohare machines
			 * (timing related ?). Until I can put my hand on one of these
			 * units, I keep the old way
			 */
			 feature_set(np, FEATURE_IDE0_enable);
		} else {
 			/* This is necessary to enable IDE when net-booting */
			printk(KERN_INFO "pmac_ide: enabling IDE bus ID %d\n",
				pmac_ide[i].aapl_bus_id);
			switch(pmac_ide[i].aapl_bus_id) {
			    case 0:
				feature_set(np, FEATURE_IDE0_reset);
				mdelay(10);
 				feature_set(np, FEATURE_IDE0_enable);
				mdelay(10);
				feature_clear(np, FEATURE_IDE0_reset);
				break;
			    case 1:
				feature_set(np, FEATURE_IDE1_reset);
				mdelay(10);
 				feature_set(np, FEATURE_IDE1_enable);
				mdelay(10);
				feature_clear(np, FEATURE_IDE1_reset);
				break;
			    case 2:
			    	/* This one exists only for KL, I don't know
				   about any enable bit */
				feature_set(np, FEATURE_IDE2_reset);
				mdelay(10);
				feature_clear(np, FEATURE_IDE2_reset);
				break;
			}
			big_delay = 1;
		}

		hwif = &ide_hwifs[i];
		pmac_ide_init_hwif_ports(&hwif->hw, base, 0, &hwif->irq);
		memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->io_ports));
		hwif->chipset = ide_pmac;
		hwif->noprobe = !hwif->io_ports[IDE_DATA_OFFSET] || in_bay;
#ifdef CONFIG_PMAC_PBOOK
		if (in_bay && check_media_bay_by_base(base, MB_CD) == 0)
			hwif->noprobe = 0;
#endif /* CONFIG_PMAC_PBOOK */

#ifdef CONFIG_BLK_DEV_IDEDMA_PMAC
		if (np->n_addrs >= 2) {
			/* has a DBDMA controller channel */
			pmac_ide_setup_dma(np, i);
		}
#endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */

		++i;
	}
	pmac_ide_count = i;
	if (big_delay)
		mdelay(IDE_WAKEUP_DELAY_MS);

#ifdef CONFIG_PMAC_PBOOK
	pmu_register_sleep_notifier(&idepmac_sleep_notifier);
#endif /* CONFIG_PMAC_PBOOK */
}
/******************************************************************
 * Find all PHBs in the system and initialize a set of data 
 * structures to represent them.
 ******************************************************************/
unsigned long __init
find_and_init_phbs(void)
{
        struct device_node *Pci_Node;
        struct pci_controller *phb;
        unsigned int root_addr_size_words = 0, this_addr_size_words = 0;
	unsigned int this_addr_count = 0, range_stride;
        unsigned int *ui_ptr = NULL, *ranges;
        char *model;
	struct pci_range64 range;
	struct resource *res;
	unsigned int memno, rlen, i, index;
	unsigned int *opprop;
	int has_isa = 0;
        PPCDBG(PPCDBG_PHBINIT, "find_and_init_phbs\n"); 

	read_pci_config = rtas_token("read-pci-config");
	write_pci_config = rtas_token("write-pci-config");
	ibm_read_pci_config = rtas_token("ibm,read-pci-config");
	ibm_write_pci_config = rtas_token("ibm,write-pci-config");

	if (naca->interrupt_controller == IC_OPEN_PIC) {
		opprop = (unsigned int *)get_property(find_path_device("/"),
				"platform-open-pic", NULL);
	}

	/* Get the root address word size. */
	ui_ptr = (unsigned int *) get_property(find_path_device("/"), 
					       "#size-cells", NULL);
	if (ui_ptr) {
		root_addr_size_words = *ui_ptr;
	} else {
		PPCDBG(PPCDBG_PHBINIT, "\tget #size-cells failed.\n"); 
		return(-1);
	}

	if (find_type_devices("isa")) {
		has_isa = 1;
		PPCDBG(PPCDBG_PHBINIT, "\tFound an ISA bus.\n"); 
	}

	index = 0;

	/******************************************************************
	* Find all PHB devices and create an object for them.
	******************************************************************/
	for (Pci_Node = find_devices("pci"); Pci_Node != NULL; Pci_Node = Pci_Node->next) {
		model = (char *) get_property(Pci_Node, "model", NULL);
		if (model != NULL)  {
			phb = alloc_phb(Pci_Node, model, root_addr_size_words);
			if (phb == NULL) return(-1);
		}
		else {
         		continue;
		}
		
		/* Get this node's address word size. */
		ui_ptr = (unsigned int *) get_property(Pci_Node, "#size-cells", NULL);
		if (ui_ptr)
			this_addr_size_words = *ui_ptr;
		else
			this_addr_size_words = 1;
		/* Get this node's address word count. */
		ui_ptr = (unsigned int *) get_property(Pci_Node, "#address-cells", NULL);
		if (ui_ptr)
			this_addr_count = *ui_ptr;
		else
			this_addr_count = 3;
		
		range_stride = this_addr_count + root_addr_size_words + this_addr_size_words;
	      
		memno = 0;
		phb->io_base_phys = 0;
         
		ranges = (unsigned int *) get_property(Pci_Node, "ranges", &rlen);
		PPCDBG(PPCDBG_PHBINIT, "\trange_stride = 0x%lx, rlen = 0x%x\n", range_stride, rlen);
                
		for (i = 0; i < (rlen/sizeof(*ranges)); i+=range_stride) {
		  	/* Put the PCI addr part of the current element into a 
			 * '64' struct. 
			 */
		  	range = *((struct pci_range64 *)(ranges + i));

			/* If this is a '32' element, map into a 64 struct. */
			if ((range_stride * sizeof(int)) == 
			   sizeof(struct pci_range32)) {
				range.parent_addr = 
					(unsigned long)(*(ranges + i + 3));
				range.size = 
					(((unsigned long)(*(ranges + i + 4)))<<32) | 
					(*(ranges + i + 5));
			} else {
				range.parent_addr = 
					(((unsigned long)(*(ranges + i + 3)))<<32) | 
					(*(ranges + i + 4));
				range.size = 
					(((unsigned long)(*(ranges + i + 5)))<<32) | 
					(*(ranges + i + 6));
			}
			
			PPCDBG(PPCDBG_PHBINIT, "\trange.parent_addr    = 0x%lx\n", 
			       range.parent_addr);
			PPCDBG(PPCDBG_PHBINIT, "\trange.child_addr.hi  = 0x%lx\n", 
			       range.child_addr.a_hi);
			PPCDBG(PPCDBG_PHBINIT, "\trange.child_addr.mid = 0x%lx\n", 
			       range.child_addr.a_mid);
			PPCDBG(PPCDBG_PHBINIT, "\trange.child_addr.lo  = 0x%lx\n", 
			       range.child_addr.a_lo);
			PPCDBG(PPCDBG_PHBINIT, "\trange.size           = 0x%lx\n", 
			       range.size);

			res = NULL;
		        switch ((range.child_addr.a_hi >> 24) & 0x3) {
			case 1:		/* I/O space */
				PPCDBG(PPCDBG_PHBINIT, "\tIO Space\n");
				phb->io_base_phys = range.parent_addr;
				res = &phb->io_resource;
				res->name = Pci_Node->full_name;
				res->flags = IORESOURCE_IO;
				phb->io_base_virt = __ioremap(phb->io_base_phys, range.size, _PAGE_NO_CACHE);
				if (!pci_io_base) {
					pci_io_base = (unsigned long)phb->io_base_virt;
					if (has_isa)
						isa_io_base = pci_io_base;
				}
				res->start = ((((unsigned long) range.child_addr.a_mid) << 32) | (range.child_addr.a_lo));
				res->start += (unsigned long)phb->io_base_virt - pci_io_base;
				res->end =   res->start + range.size - 1;
				res->parent = NULL;
				res->sibling = NULL;
				res->child = NULL;
				phb->pci_io_offset = range.parent_addr - 
					((((unsigned long)
					   range.child_addr.a_mid) << 32) | 
					 (range.child_addr.a_lo));
				PPCDBG(PPCDBG_PHBINIT, "\tpci_io_offset  = 0x%lx\n", 
				       phb->pci_io_offset);
			  	break;
			case 2:		/* mem space */
				PPCDBG(PPCDBG_PHBINIT, "\tMem Space\n");
				phb->pci_mem_offset = range.parent_addr - 
					((((unsigned long)
					   range.child_addr.a_mid) << 32) | 
					 (range.child_addr.a_lo));
				PPCDBG(PPCDBG_PHBINIT, "\tpci_mem_offset = 0x%lx\n", 
				       phb->pci_mem_offset);
				if (memno < sizeof(phb->mem_resources)/sizeof(phb->mem_resources[0])) {
					res = &(phb->mem_resources[memno]);
					++memno;
					res->name = Pci_Node->full_name;
					res->flags = IORESOURCE_MEM;
					res->start = range.parent_addr;
					res->end =   range.parent_addr + range.size - 1;
					res->parent = NULL;
					res->sibling = NULL;
					res->child = NULL;
				}
			  	break;
			}
		}
		PPCDBG(PPCDBG_PHBINIT, "\tphb->io_base_phys   = 0x%lx\n", 
		       phb->io_base_phys); 
		PPCDBG(PPCDBG_PHBINIT, "\tphb->pci_mem_offset = 0x%lx\n", 
		       phb->pci_mem_offset); 

		if (naca->interrupt_controller == IC_OPEN_PIC) {
			int addr = root_addr_size_words * (index + 2) - 1;
			openpic_setup_ISU(index, opprop[addr]); 
		}
		index++;
	}
	pci_devs_phb_init();
	return 0;	 /*Success */
}
Esempio n. 8
0
void
xics_init_IRQ( void )
{
	int i;
	unsigned long intr_size = 0;
	struct device_node *np;
	uint *ireg, ilen, indx=0;

	ibm_get_xive = rtas_token("ibm,get-xive");
	ibm_set_xive = rtas_token("ibm,set-xive");
	ibm_int_off = rtas_token("ibm,int-off");

	np = find_type_devices("PowerPC-External-Interrupt-Presentation");
	if (!np) {
		printk(KERN_WARNING "Can't find Interrupt Presentation\n");
		udbg_printf("Can't find Interrupt Presentation\n");
		while (1);
	}
nextnode:
	ireg = (uint *)get_property(np, "ibm,interrupt-server-ranges", 0);
	if (ireg) {
		/*
		 * set node starting index for this node
		 */
		indx = *ireg;
	}

	ireg = (uint *)get_property(np, "reg", &ilen);
	if (!ireg) {
		printk(KERN_WARNING "Can't find Interrupt Reg Property\n");
		udbg_printf("Can't find Interrupt Reg Property\n");
		while (1);
	}
	
	while (ilen) {
		inodes[indx].addr = (unsigned long long)*ireg++ << 32;
		ilen -= sizeof(uint);
		inodes[indx].addr |= *ireg++;
		ilen -= sizeof(uint);
		inodes[indx].size = (unsigned long long)*ireg++ << 32;
		ilen -= sizeof(uint);
		inodes[indx].size |= *ireg++;
		ilen -= sizeof(uint);
		indx++;
		if (indx >= NR_CPUS) break;
	}

	np = np->next;
	if ((indx < NR_CPUS) && np) goto nextnode;

	/* Find the server numbers for the boot cpu. */
	for (np = find_type_devices("cpu"); np; np = np->next) {
		ireg = (uint *)get_property(np, "reg", &ilen);
		if (ireg && ireg[0] == hard_smp_processor_id()) {
			ireg = (uint *)get_property(np, "ibm,ppc-interrupt-gserver#s", &ilen);
			i = ilen / sizeof(int);
			if (ireg && i > 0) {
				default_server = ireg[0];
				default_distrib_server = ireg[i-1]; /* take last element */
			}
			break;
		}
	}

	intr_base = inodes[0].addr;
	intr_size = (ulong)inodes[0].size;

	np = find_type_devices("interrupt-controller");
	if (!np) {
		printk(KERN_WARNING "xics:  no ISA Interrupt Controller\n");
		xics_irq_8259_cascade = -1;
	} else {
		ireg = (uint *) get_property(np, "interrupts", 0);
		if (!ireg) {
			printk(KERN_WARNING "Can't find ISA Interrupts Property\n");
			udbg_printf("Can't find ISA Interrupts Property\n");
			while (1);
		}
		xics_irq_8259_cascade_real = *ireg;
		xics_irq_8259_cascade = virt_irq_create_mapping(xics_irq_8259_cascade_real);
	}

	if (naca->platform == PLATFORM_PSERIES) {
#ifdef CONFIG_SMP
		for (i = 0; i < naca->processorCount; ++i) {
			xics_info.per_cpu[i] =
			  __ioremap((ulong)inodes[get_hard_smp_processor_id(i)].addr, 
				  (ulong)inodes[get_hard_smp_processor_id(i)].size, _PAGE_NO_CACHE);
		}
#else
		xics_info.per_cpu[0] = __ioremap((ulong)intr_base, intr_size, _PAGE_NO_CACHE);
#endif /* CONFIG_SMP */
#ifdef CONFIG_PPC_PSERIES
	/* actually iSeries does not use any of xics...but it has link dependencies
	 * for now, except this new one...
	 */
	} else if (naca->platform == PLATFORM_PSERIES_LPAR) {
		ops = &pSeriesLP_ops;
#endif
	}

	xics_8259_pic.enable = i8259_pic.enable;
	xics_8259_pic.disable = i8259_pic.disable;
	for (i = 0; i < 16; ++i)
		irq_desc[i].handler = &xics_8259_pic;
	for (; i < NR_IRQS; ++i)
		irq_desc[i].handler = &xics_pic;

	ops->cppr_info(0, 0xff);
	iosync();
	if (xics_irq_8259_cascade != -1) {
		if (request_irq(xics_irq_8259_cascade + XICS_IRQ_OFFSET, no_action,
				0, "8259 cascade", 0))
			printk(KERN_ERR "xics_init_IRQ: couldn't get 8259 cascade\n");
		i8259_init();
	}

#ifdef CONFIG_SMP
	real_irq_to_virt_map[XICS_IPI] = virt_irq_to_real_map[XICS_IPI] = XICS_IPI;
	request_irq(XICS_IPI + XICS_IRQ_OFFSET, xics_ipi_action, 0, "IPI", 0);
	irq_desc[XICS_IPI+XICS_IRQ_OFFSET].status |= IRQ_PER_CPU;
#endif
}
Esempio n. 9
0
int __pmac
pmac_show_cpuinfo(struct seq_file *m)
{
	struct device_node *np;
	char *pp;
	int plen;
	int mbmodel = pmac_call_feature(PMAC_FTR_GET_MB_INFO,
		NULL, PMAC_MB_INFO_MODEL, 0);
	unsigned int mbflags = (unsigned int)pmac_call_feature(PMAC_FTR_GET_MB_INFO,
		NULL, PMAC_MB_INFO_FLAGS, 0);
	char* mbname;

	if (pmac_call_feature(PMAC_FTR_GET_MB_INFO, NULL, PMAC_MB_INFO_NAME, (int)&mbname) != 0)
		mbname = "Unknown";

	/* find motherboard type */
	seq_printf(m, "machine\t\t: ");
	np = find_devices("device-tree");
	if (np != NULL) {
		pp = (char *) get_property(np, "model", NULL);
		if (pp != NULL)
			seq_printf(m, "%s\n", pp);
		else
			seq_printf(m, "PowerMac\n");
		pp = (char *) get_property(np, "compatible", &plen);
		if (pp != NULL) {
			seq_printf(m, "motherboard\t:");
			while (plen > 0) {
				int l = strlen(pp) + 1;
				seq_printf(m, " %s", pp);
				plen -= l;
				pp += l;
			}
			seq_printf(m, "\n");
		}
	} else
		seq_printf(m, "PowerMac\n");

	/* print parsed model */
	seq_printf(m, "detected as\t: %d (%s)\n", mbmodel, mbname);
	seq_printf(m, "pmac flags\t: %08x\n", mbflags);

	/* find l2 cache info */
	np = find_devices("l2-cache");
	if (np == 0)
		np = find_type_devices("cache");
	if (np != 0) {
		unsigned int *ic = (unsigned int *)
			get_property(np, "i-cache-size", NULL);
		unsigned int *dc = (unsigned int *)
			get_property(np, "d-cache-size", NULL);
		seq_printf(m, "L2 cache\t:");
		has_l2cache = 1;
		if (get_property(np, "cache-unified", NULL) != 0 && dc) {
			seq_printf(m, " %dK unified", *dc / 1024);
		} else {
			if (ic)
				seq_printf(m, " %dK instruction", *ic / 1024);
			if (dc)
				seq_printf(m, "%s %dK data",
					   (ic? " +": ""), *dc / 1024);
		}
		pp = get_property(np, "ram-type", NULL);
		if (pp)
			seq_printf(m, " %s", pp);
		seq_printf(m, "\n");
	}

	/* find ram info */
	np = find_devices("memory");
	if (np != 0) {
		int n;
		struct reg_property *reg = (struct reg_property *)
			get_property(np, "reg", &n);

		if (reg != 0) {
			unsigned long total = 0;

			for (n /= sizeof(struct reg_property); n > 0; --n)
				total += (reg++)->size;
			seq_printf(m, "memory\t\t: %luMB\n", total >> 20);
		}
Esempio n. 10
0
static int __init parse_numa_properties(void)
{
	struct device_node *cpu;
	struct device_node *memory;
	int *cpu_associativity;
	int *memory_associativity;
	int depth;
	int max_domain = 0;

	cpu = find_type_devices("cpu");
	if (!cpu)
		return -1;

	memory = find_type_devices("memory");
	if (!memory)
		return -1;

	cpu_associativity = (int *)get_property(cpu, "ibm,associativity", NULL);
	if (!cpu_associativity)
		return -1;

	memory_associativity = (int *)get_property(memory, "ibm,associativity",
						   NULL);
	if (!memory_associativity)
		return -1;

	/* find common depth */
	if (cpu_associativity[0] < memory_associativity[0])
		depth = cpu_associativity[0];
	else
		depth = memory_associativity[0];

	for (cpu = find_type_devices("cpu"); cpu; cpu = cpu->next) {
		int *tmp;
		int cpu_nr, numa_domain;

		tmp = (int *)get_property(cpu, "reg", NULL);
		if (!tmp)
			continue;
		cpu_nr = *tmp;

		tmp = (int *)get_property(cpu, "ibm,associativity",
					  NULL);
		if (!tmp)
			continue;
		numa_domain = tmp[depth];

		/* FIXME */
		if (numa_domain == 0xffff) {
			dbg("cpu %d has no numa doman\n", cpu_nr);
			numa_domain = 0;
		}

		if (numa_domain >= MAX_NUMNODES)
			BUG();

		if (max_domain < numa_domain)
			max_domain = numa_domain;

		map_cpu_to_node(cpu_nr, numa_domain);
	}

	for (memory = find_type_devices("memory"); memory;
	     memory = memory->next) {
		int *tmp1, *tmp2;
		unsigned long i;
		unsigned long start = 0;
		unsigned long size = 0;
		int numa_domain;
		int ranges;

		tmp1 = (int *)get_property(memory, "reg", NULL);
		if (!tmp1)
			continue;

		ranges = memory->n_addrs;
new_range:

		i = prom_n_size_cells(memory);
		while (i--) {
			start = (start << 32) | *tmp1;
			tmp1++;
		}

		i = prom_n_size_cells(memory);
		while (i--) {
			size = (size << 32) | *tmp1;
			tmp1++;
		}

		start = _ALIGN_DOWN(start, MEMORY_INCREMENT);
		size = _ALIGN_UP(size, MEMORY_INCREMENT);

		if ((start + size) > MAX_MEMORY)
			BUG();

		tmp2 = (int *)get_property(memory, "ibm,associativity",
					   NULL);
		if (!tmp2)
			continue;
		numa_domain = tmp2[depth];

		/* FIXME */
		if (numa_domain == 0xffff) {
			dbg("memory has no numa doman\n");
			numa_domain = 0;
		}

		if (numa_domain >= MAX_NUMNODES)
			BUG();

		if (max_domain < numa_domain)
			max_domain = numa_domain;

		/* 
		 * For backwards compatibility, OF splits the first node
		 * into two regions (the first being 0-4GB). Check for
		 * this simple case and complain if there is a gap in
		 * memory
		 */
		if (node_data[numa_domain].node_spanned_pages) {
			unsigned long shouldstart =
				node_data[numa_domain].node_start_pfn + 
				node_data[numa_domain].node_spanned_pages;
			if (shouldstart != (start / PAGE_SIZE)) {
				printk(KERN_ERR "Hole in node, disabling "
						"region start %lx length %lx\n",
						start, size);
				continue;
			}
			node_data[numa_domain].node_spanned_pages += size / PAGE_SIZE;
		} else {
			node_data[numa_domain].node_start_pfn =
				start / PAGE_SIZE;
			node_data[numa_domain].node_spanned_pages = size / PAGE_SIZE;
		}

		for (i = start ; i < (start+size); i += MEMORY_INCREMENT)
			numa_memory_lookup_table[i >> MEMORY_INCREMENT_SHIFT] =
				numa_domain;

		dbg("memory region %lx to %lx maps to domain %d\n",
		    start, start+size, numa_domain);

		ranges--;
		if (ranges)
			goto new_range;
	}

	numnodes = max_domain + 1;

	return 0;
}