⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hdpu.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 2 页
字号:
{	hdpu_halt();	/* NOTREACHED */}static int hdpu_show_cpuinfo(struct seq_file *m){	uint pvid;	pvid = mfspr(SPRN_PVR);	seq_printf(m, "vendor\t\t: Sky Computers\n");	seq_printf(m, "machine\t\t: HDPU Compute Blade\n");	seq_printf(m, "PVID\t\t: 0x%x, vendor: %s\n",		   pvid, (pvid & (1 << 15) ? "IBM" : "Motorola"));	return 0;}static void __init hdpu_calibrate_decr(void){	ulong freq;	if (ppcboot_bd_valid)		freq = ppcboot_bd.bi_busfreq / 4;	else		freq = 133000000;	printk("time_init: decrementer frequency = %lu.%.6lu MHz\n",	       freq / 1000000, freq % 1000000);	tb_ticks_per_jiffy = freq / HZ;	tb_to_us = mulhwu_scale_factor(freq, 1000000);	return;}static void parse_bootinfo(unsigned long r3,			   unsigned long r4, unsigned long r5,			   unsigned long r6, unsigned long r7){	bd_t *bd = NULL;	char *cmdline_start = NULL;	int cmdline_len = 0;	if (r3) {		if ((r3 & 0xf0000000) == 0)			r3 += KERNELBASE;		if ((r3 & 0xf0000000) == KERNELBASE) {			bd = (void *)r3;			memcpy(&ppcboot_bd, bd, sizeof(ppcboot_bd));			ppcboot_bd_valid = 1;		}	}#ifdef CONFIG_BLK_DEV_INITRD	if (r4 && r5 && r5 > r4) {		if ((r4 & 0xf0000000) == 0)			r4 += KERNELBASE;		if ((r5 & 0xf0000000) == 0)			r5 += KERNELBASE;		if ((r4 & 0xf0000000) == KERNELBASE) {			initrd_start = r4;			initrd_end = r5;			initrd_below_start_ok = 1;		}	}#endif				/* CONFIG_BLK_DEV_INITRD */	if (r6 && r7 && r7 > r6) {		if ((r6 & 0xf0000000) == 0)			r6 += KERNELBASE;		if ((r7 & 0xf0000000) == 0)			r7 += KERNELBASE;		if ((r6 & 0xf0000000) == KERNELBASE) {			cmdline_start = (void *)r6;			cmdline_len = (r7 - r6);			strncpy(cmd_line, cmdline_start, cmdline_len);		}	}}#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)static voidhdpu_ide_request_region(ide_ioreg_t from, unsigned int extent, const char *name){	request_region(from, extent, name);	return;}static void hdpu_ide_release_region(ide_ioreg_t from, unsigned int extent){	release_region(from, extent);	return;}static void __inithdpu_ide_pci_init_hwif_ports(hw_regs_t * hw, ide_ioreg_t data_port,			     ide_ioreg_t ctrl_port, int *irq){	struct pci_dev *dev;	pci_for_each_dev(dev) {		if (((dev->class >> 8) == PCI_CLASS_STORAGE_IDE) ||		    ((dev->class >> 8) == PCI_CLASS_STORAGE_RAID)) {			hw->irq = dev->irq;			if (irq != NULL) {				*irq = dev->irq;			}		}	}	return;}#endifvoid hdpu_heartbeat(void){	if (mv64x60_read(&bh, MV64x60_GPP_VALUE) & (1 << 5))		mv64x60_write(&bh, MV64x60_GPP_VALUE_CLR, (1 << 5));	else		mv64x60_write(&bh, MV64x60_GPP_VALUE_SET, (1 << 5));	ppc_md.heartbeat_count = ppc_md.heartbeat_reset;}static void __init hdpu_map_io(void){	io_block_mapping(0xf1000000, 0xf1000000, 0x20000, _PAGE_IO);}#ifdef CONFIG_SMPchar hdpu_smp0[] = "SMP Cpu #0";char hdpu_smp1[] = "SMP Cpu #1";static irqreturn_t hdpu_smp_cpu0_int_handler(int irq, void *dev_id,					     struct pt_regs *regs){	volatile unsigned int doorbell;	doorbell = mv64x60_read(&bh, MV64360_CPU0_DOORBELL);	/* Ack the doorbell interrupts */	mv64x60_write(&bh, MV64360_CPU0_DOORBELL_CLR, doorbell);	if (doorbell & 1) {		smp_message_recv(0, regs);	}	if (doorbell & 2) {		smp_message_recv(1, regs);	}	if (doorbell & 4) {		smp_message_recv(2, regs);	}	if (doorbell & 8) {		smp_message_recv(3, regs);	}	return IRQ_HANDLED;}static irqreturn_t hdpu_smp_cpu1_int_handler(int irq, void *dev_id,					     struct pt_regs *regs){	volatile unsigned int doorbell;	doorbell = mv64x60_read(&bh, MV64360_CPU1_DOORBELL);	/* Ack the doorbell interrupts */	mv64x60_write(&bh, MV64360_CPU1_DOORBELL_CLR, doorbell);	if (doorbell & 1) {		smp_message_recv(0, regs);	}	if (doorbell & 2) {		smp_message_recv(1, regs);	}	if (doorbell & 4) {		smp_message_recv(2, regs);	}	if (doorbell & 8) {		smp_message_recv(3, regs);	}	return IRQ_HANDLED;}static void smp_hdpu_CPU_two(void){	__asm__ __volatile__	    ("\n"	     "lis     3,0x0000\n"	     "ori     3,3,0x00c0\n"	     "mtspr   26, 3\n" "li      4,0\n" "mtspr   27,4\n" "rfi");}static int smp_hdpu_probe(void){	int *cpu_count_reg;	int num_cpus = 0;	cpu_count_reg = ioremap(HDPU_NEXUS_ID_BASE, HDPU_NEXUS_ID_SIZE);	if (cpu_count_reg) {		num_cpus = (*cpu_count_reg >> 20) & 0x3;		iounmap(cpu_count_reg);	}	/* Validate the bits in the CPLD. If we could not map the reg, return 2.	 * If the register reported 0 or 3, return 2.	 * Older CPLD revisions set these bits to all ones (val = 3).	 */	if ((num_cpus < 1) || (num_cpus > 2)) {		printk		    ("Unable to determine the number of processors %d . deafulting to 2.\n",		     num_cpus);		num_cpus = 2;	}	return num_cpus;}static voidsmp_hdpu_message_pass(int target, int msg){	if (msg > 0x3) {		printk("SMP %d: smp_message_pass: unknown msg %d\n",		       smp_processor_id(), msg);		return;	}	switch (target) {	case MSG_ALL:		mv64x60_write(&bh, MV64360_CPU0_DOORBELL, 1 << msg);		mv64x60_write(&bh, MV64360_CPU1_DOORBELL, 1 << msg);		break;	case MSG_ALL_BUT_SELF:		if (smp_processor_id())			mv64x60_write(&bh, MV64360_CPU0_DOORBELL, 1 << msg);		else			mv64x60_write(&bh, MV64360_CPU1_DOORBELL, 1 << msg);		break;	default:		if (target == 0)			mv64x60_write(&bh, MV64360_CPU0_DOORBELL, 1 << msg);		else			mv64x60_write(&bh, MV64360_CPU1_DOORBELL, 1 << msg);		break;	}}static void smp_hdpu_kick_cpu(int nr){	volatile unsigned int *bootaddr;	if (ppc_md.progress)		ppc_md.progress("smp_hdpu_kick_cpu", 0);	hdpu_cpustate_set(CPUSTATE_KERNEL_MAJOR | CPUSTATE_KERNEL_CPU1_KICK);       /* Disable BootCS. Must also reduce the windows size to zero. */	bh.ci->disable_window_32bit(&bh, MV64x60_CPU2BOOT_WIN);	mv64x60_set_32bit_window(&bh, MV64x60_CPU2BOOT_WIN, 0, 0, 0);	bootaddr = ioremap(HDPU_INTERNAL_SRAM_BASE, HDPU_INTERNAL_SRAM_SIZE);	if (!bootaddr) {		if (ppc_md.progress)			ppc_md.progress("smp_hdpu_kick_cpu: ioremap failed", 0);		return;	}	memcpy((void *)(bootaddr + 0x40), (void *)&smp_hdpu_CPU_two, 0x20);	/* map SRAM to 0xfff00000 */	bh.ci->disable_window_32bit(&bh, MV64x60_CPU2SRAM_WIN);	mv64x60_set_32bit_window(&bh, MV64x60_CPU2SRAM_WIN,				 0xfff00000, HDPU_INTERNAL_SRAM_SIZE, 0);	bh.ci->enable_window_32bit(&bh, MV64x60_CPU2SRAM_WIN);	/* Enable CPU1 arbitration */	mv64x60_clr_bits(&bh, MV64x60_CPU_MASTER_CNTL, (1 << 9));	/*	 * Wait 100mSecond until other CPU has reached __secondary_start.	 * When it reaches, it is permittable to rever the SRAM mapping etc...	 */	mdelay(100);	*(unsigned long *)KERNELBASE = nr;	asm volatile ("dcbf 0,%0"::"r" (KERNELBASE):"memory");	iounmap(bootaddr);	/* Set up window for internal sram (256KByte insize) */	bh.ci->disable_window_32bit(&bh, MV64x60_CPU2SRAM_WIN);	mv64x60_set_32bit_window(&bh, MV64x60_CPU2SRAM_WIN,				 HDPU_INTERNAL_SRAM_BASE,				 HDPU_INTERNAL_SRAM_SIZE, 0);	bh.ci->enable_window_32bit(&bh, MV64x60_CPU2SRAM_WIN);	/*	 * Set up windows for embedded FLASH (using boot CS window).	 */	bh.ci->disable_window_32bit(&bh, MV64x60_CPU2BOOT_WIN);	mv64x60_set_32bit_window(&bh, MV64x60_CPU2BOOT_WIN,				 HDPU_EMB_FLASH_BASE, HDPU_EMB_FLASH_SIZE, 0);	bh.ci->enable_window_32bit(&bh, MV64x60_CPU2BOOT_WIN);}static void smp_hdpu_setup_cpu(int cpu_nr){	if (cpu_nr == 0) {		if (ppc_md.progress)			ppc_md.progress("smp_hdpu_setup_cpu 0", 0);		mv64x60_write(&bh, MV64360_CPU0_DOORBELL_CLR, 0xff);		mv64x60_write(&bh, MV64360_CPU0_DOORBELL_MASK, 0xff);		request_irq(60, hdpu_smp_cpu0_int_handler,			    SA_INTERRUPT, hdpu_smp0, 0);	}	if (cpu_nr == 1) {		if (ppc_md.progress)			ppc_md.progress("smp_hdpu_setup_cpu 1", 0);		hdpu_cpustate_set(CPUSTATE_KERNEL_MAJOR |				  CPUSTATE_KERNEL_CPU1_OK);		/* Enable L1 Parity Bits */		hdpu_set_l1pe();		/* Enable L2 cache */		_set_L2CR(0);		_set_L2CR(0x80080000);		mv64x60_write(&bh, MV64360_CPU1_DOORBELL_CLR, 0x0);		mv64x60_write(&bh, MV64360_CPU1_DOORBELL_MASK, 0xff);		request_irq(28, hdpu_smp_cpu1_int_handler,			    SA_INTERRUPT, hdpu_smp1, 0);	}}void __devinit hdpu_tben_give(){	volatile unsigned long *val = 0;	/* By writing 0 to the TBEN_BASE, the timebases is frozen */	val = ioremap(HDPU_TBEN_BASE, 4);	*val = 0;	mb();	spin_lock(&timebase_lock);	timebase_upper = get_tbu();	timebase_lower = get_tbl();	spin_unlock(&timebase_lock);	while (timebase_upper || timebase_lower)		barrier();	/* By writing 1 to the TBEN_BASE, the timebases is thawed */	*val = 1;	mb();	iounmap(val);}void __devinit hdpu_tben_take(){	while (!(timebase_upper || timebase_lower))		barrier();	spin_lock(&timebase_lock);	set_tb(timebase_upper, timebase_lower);	timebase_upper = 0;	timebase_lower = 0;	spin_unlock(&timebase_lock);}static struct smp_ops_t hdpu_smp_ops = {	.message_pass = smp_hdpu_message_pass,	.probe = smp_hdpu_probe,	.kick_cpu = smp_hdpu_kick_cpu,	.setup_cpu = smp_hdpu_setup_cpu,	.give_timebase = hdpu_tben_give,	.take_timebase = hdpu_tben_take,};#endif				/* CONFIG_SMP */void __initplatform_init(unsigned long r3, unsigned long r4, unsigned long r5,	      unsigned long r6, unsigned long r7){	parse_bootinfo(r3, r4, r5, r6, r7);	isa_mem_base = 0;	ppc_md.setup_arch = hdpu_setup_arch;	ppc_md.init = hdpu_init2;	ppc_md.show_cpuinfo = hdpu_show_cpuinfo;	ppc_md.init_IRQ = hdpu_init_irq;	ppc_md.get_irq = mv64360_get_irq;	ppc_md.restart = hdpu_restart;	ppc_md.power_off = hdpu_power_off;	ppc_md.halt = hdpu_halt;	ppc_md.find_end_of_memory = hdpu_find_end_of_memory;	ppc_md.calibrate_decr = hdpu_calibrate_decr;	ppc_md.setup_io_mappings = hdpu_map_io;	bh.p_base = CONFIG_MV64X60_NEW_BASE;	bh.v_base = (unsigned long *)bh.p_base;	hdpu_set_bat();#if defined(CONFIG_SERIAL_TEXT_DEBUG)	ppc_md.progress = hdpu_mpsc_progress;	/* embedded UART */	mv64x60_progress_init(bh.p_base);#endif				/* CONFIG_SERIAL_TEXT_DEBUG */#ifdef CONFIG_SMP	smp_ops = &hdpu_smp_ops;#endif				/* CONFIG_SMP */#if defined(CONFIG_SERIAL_MPSC) || defined(CONFIG_MV643XX_ETH)	platform_notify = hdpu_platform_notify;#endif	return;}#if defined(CONFIG_SERIAL_TEXT_DEBUG) && defined(CONFIG_SERIAL_MPSC_CONSOLE)/* SMP safe version of the serial text debug routine. Uses Semaphore 0 */void hdpu_mpsc_progress(char *s, unsigned short hex){	while (mv64x60_read(&bh, MV64360_WHO_AM_I) !=	       mv64x60_read(&bh, MV64360_SEMAPHORE_0)) {	}	mv64x60_mpsc_progress(s, hex);	mv64x60_write(&bh, MV64360_SEMAPHORE_0, 0xff);}#endifstatic void hdpu_cpustate_set(unsigned char new_state){	unsigned int state = (new_state << 21);	mv64x60_write(&bh, MV64x60_GPP_VALUE_CLR, (0xff << 21));	mv64x60_write(&bh, MV64x60_GPP_VALUE_CLR, state);}#ifdef CONFIG_MTD_PHYSMAPstatic struct mtd_partition hdpu_partitions[] = {	{	 .name = "Root FS",	 .size = 0x03400000,	 .offset = 0,	 .mask_flags = 0,	 },{	 .name = "User FS",	 .size = 0x00800000,	 .offset = 0x03400000,	 .mask_flags = 0,	 },{	 .name = "Kernel Image",	 .size = 0x002C0000,	 .offset = 0x03C00000,	 .mask_flags = 0,	 },{	 .name = "bootEnv",	 .size = 0x00040000,	 .offset = 0x03EC0000,	 .mask_flags = 0,	 },{	 .name = "bootROM",	 .size = 0x00100000,	 .offset = 0x03F00000,	 .mask_flags = 0,	 }};static int __init hdpu_setup_mtd(void){	physmap_set_partitions(hdpu_partitions, 5);	return 0;}arch_initcall(hdpu_setup_mtd);#endif#ifdef CONFIG_HDPU_FEATURESstatic struct resource hdpu_cpustate_resources[] = {	[0] = {	       .name = "addr base",	       .start = MV64x60_GPP_VALUE_SET,	       .end = MV64x60_GPP_VALUE_CLR + 1,	       .flags = IORESOURCE_MEM,	       },};static struct resource hdpu_nexus_resources[] = {	[0] = {	       .name = "nexus register",	       .start = HDPU_NEXUS_ID_BASE,	       .end = HDPU_NEXUS_ID_BASE + HDPU_NEXUS_ID_SIZE,	       .flags = IORESOURCE_MEM,	       },};static struct platform_device hdpu_cpustate_device = {	.name = HDPU_CPUSTATE_NAME,	.id = 0,	.num_resources = ARRAY_SIZE(hdpu_cpustate_resources),	.resource = hdpu_cpustate_resources,};static struct platform_device hdpu_nexus_device = {	.name = HDPU_NEXUS_NAME,	.id = 0,	.num_resources = ARRAY_SIZE(hdpu_nexus_resources),	.resource = hdpu_nexus_resources,};static int __init hdpu_add_pds(void){	platform_device_register(&hdpu_cpustate_device);	platform_device_register(&hdpu_nexus_device);	return 0;}arch_initcall(hdpu_add_pds);#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -