示例#1
0
文件: smp.c 项目: dduval/kernel-rhel3
void __init smp_commence(void)
{
	/*
	 *	Lets the callin's below out of their loop.
	 */
	if (ppc_md.progress) ppc_md.progress("smp_commence", 0x370);
	wmb();
	smp_commenced = 1;

	/* if the smp_ops->setup_cpu function has not already synched the
	 * timebases with a nicer hardware-based method, do so now
	 *
	 * I am open to suggestions for improvements to this method
	 * -- Troy <*****@*****.**>
	 *
	 * NOTE: if you are debugging, set smp_tb_synchronized for now
	 * since if this code runs pretty early and needs all cpus that
	 * reported in in smp_callin_map to be working
	 *
	 * NOTE2: this code doesn't seem to work on > 2 cpus. -- paulus/BenH
	 */
	if (!smp_tb_synchronized && smp_num_cpus == 2) {
		unsigned long flags;
		__save_and_cli(flags);	
		smp_software_tb_sync(0);
		__restore_flags(flags);
	}
}
示例#2
0
static void
conf_write(unsigned long addr, unsigned int value, unsigned char type1,
	   struct pci_controler *hose)
{
	unsigned long flags;
	unsigned long mid = MCPCIA_HOSE2MID(hose->index);
	unsigned int stat0, temp, cpu;

	cpu = smp_processor_id();

	__save_and_cli(flags);	/* avoid getting hit by machine check */

	/* Reset status register to avoid losing errors.  */
	stat0 = *(vuip)MCPCIA_CAP_ERR(mid);
	*(vuip)MCPCIA_CAP_ERR(mid) = stat0; mb();
	temp = *(vuip)MCPCIA_CAP_ERR(mid);
	DBG_CFG(("conf_write: MCPCIA CAP_ERR(%d) was 0x%x\n", mid, stat0));

	draina();
	mcheck_expected(cpu) = 1;
	mcheck_extra(cpu) = mid;
	mb();

	/* Access configuration space.  */
	*((vuip)addr) = value;
	mb();
	mb();  /* magic */
	temp = *(vuip)MCPCIA_CAP_ERR(mid); /* read to force the write */
	mcheck_expected(cpu) = 0;
	mb();

	DBG_CFG(("conf_write(): finished\n"));
	__restore_flags(flags);
}
示例#3
0
文件: indy_sc.c 项目: TitaniumBoy/lin
static void indy_sc_wback_invalidate(unsigned long addr, unsigned long size)
{
	unsigned long first_line, last_line;
	unsigned int flags;

#ifdef DEBUG_CACHE
	printk("indy_sc_wback_invalidate[%08lx,%08lx]", addr, size);
#endif

	if (!size)
		return;

	/* Which lines to flush?  */
	first_line = SC_INDEX(addr);
	last_line = SC_INDEX(addr + size - 1);

	__save_and_cli(flags);
	if (first_line <= last_line) {
		indy_sc_wipe(first_line, last_line);
		goto out;
	}

	indy_sc_wipe(first_line, SC_SIZE - SC_LINE);
	indy_sc_wipe(0, last_line);
out:
	__restore_flags(flags);
}
示例#4
0
void local_flush_tlb_all(void)
{
	unsigned long flags;
	unsigned long old_ctx;
	int entry;

#ifdef DEBUG_TLB
	printk("[tlball]");
#endif

	__save_and_cli(flags);
	/* Save old context and create impossible VPN2 value */
	old_ctx = (get_entryhi() & 0xff);
	set_entryhi(KSEG0);
	set_entrylo0(0);
	set_entrylo1(0);
	BARRIER;

	entry = get_wired();

	/* Blast 'em all away. */
	while(entry < mips_cpu.tlbsize) {
	        /* Make sure all entries differ. */
	        set_entryhi(KSEG0+entry*0x2000);
		set_index(entry);
		BARRIER;
		tlb_write_indexed();
		BARRIER;
		entry++;
	}
	BARRIER;
	set_entryhi(old_ctx);
	__restore_flags(flags);
}
示例#5
0
/* Drop into the prom, with the chance to continue with the 'go'
 * prom command.
 */
void
prom_cmdline(void)
{
	unsigned long flags;

	__save_and_cli(flags);

#ifdef CONFIG_SUN_CONSOLE
	if(!serial_console && prom_palette)
		prom_palette (1);
#endif

#ifdef CONFIG_SMP
	smp_capture();
#endif

	p1275_cmd ("enter", P1275_INOUT(0,0));

#ifdef CONFIG_SMP
	smp_release();
	spin_unlock_wait(&__br_write_locks[BR_GLOBALIRQ_LOCK].lock);
#endif

#ifdef CONFIG_SUN_CONSOLE
	if(!serial_console && prom_palette)
		prom_palette (0);
#endif

	__restore_flags(flags);
}
示例#6
0
文件: time.c 项目: TKr/Wive-ng-rt8186
void __init mips_time_init(void)
{
        unsigned int est_freq, flags;

	__save_and_cli(flags);

        /* Set Data mode - binary. */ 
        CMOS_WRITE(CMOS_READ(RTC_CONTROL) | RTC_DM_BINARY, RTC_CONTROL);

	printk("calculating r4koff... ");
	r4k_offset = cal_r4koff();
	printk("%08x(%d)\n", r4k_offset, r4k_offset);

        if ((read_32bit_cp0_register(CP0_PRID) & 0xffff00) == 
	    (PRID_COMP_MIPS | PRID_IMP_20KC))
		est_freq = r4k_offset*HZ;
	else
		est_freq = 2*r4k_offset*HZ;

	est_freq += 5000;    /* round */
	est_freq -= est_freq%10000;
	printk("CPU frequency %d.%02d MHz\n", est_freq/1000000, 
	       (est_freq%1000000)*100/1000000);

	__restore_flags(flags);
}
示例#7
0
static void r5900_flush_page_to_ram_d64(struct page *page)
{
	unsigned long flags;

	__save_and_cli(flags);
	blast_dcache64_page((unsigned long)page_address(page));
	__restore_flags(flags);
}
示例#8
0
static inline void r5900_flush_cache_all_d64i64(void)
{
	unsigned long flags;

	__save_and_cli(flags);
	blast_dcache64(); blast_icache64();
	__restore_flags(flags);
}
示例#9
0
static void r5900_flush_cache_page_d64i64(struct vm_area_struct *vma,
					unsigned long page)
{
	struct mm_struct *mm = vma->vm_mm;
	unsigned long flags;
	pgd_t *pgdp;
	pmd_t *pmdp;
	pte_t *ptep;
	int text;

	/*
	 * If ownes no valid ASID yet, cannot possibly have gotten
	 * this page into the cache.
	 */
	if(mm->context == 0)
		return;

#ifdef DEBUG_CACHE
	printk("cpage[%d,%08lx]", (int)mm->context, page);
#endif
	__save_and_cli(flags);
	page &= PAGE_MASK;
	pgdp = pgd_offset(mm, page);
	pmdp = pmd_offset(pgdp, page);
	ptep = pte_offset(pmdp, page);

	/*
	 * If the page isn't marked valid, the page cannot possibly be
	 * in the cache.
	 */
	if (!(pte_val(*ptep) & _PAGE_VALID))
		goto out;

	text = (vma->vm_flags & VM_EXEC);
	/*
	 * Doing flushes for another ASID than the current one is
	 * too difficult since stupid R4k caches do a TLB translation
	 * for every cache flush operation.  So we do indexed flushes
	 * in that case, which doesn't overly flush the cache too much.
	 */
	if(mm == current->mm) {
		blast_dcache64_page(page);
		if(text)
			blast_icache64_page(page);
	} else {
		/* Do indexed flush, too much work to get the (possible)
		 * tlb refills to work correctly.
		 */
		page = (KSEG0 + (page & (dcache_size - 1)));
		blast_dcache64_page_indexed(page);
		if(text)
			blast_icache64_page_indexed(page);
	}
out:
	__restore_flags(flags);
}
示例#10
0
static void
r5900_flush_icache_page_p(struct vm_area_struct *vma, struct page *page)
{
	unsigned long flags;

	if (!(vma->vm_flags & VM_EXEC))
		return;

	__save_and_cli(flags);
	blast_icache64();
	__restore_flags(flags);
}
示例#11
0
static inline void r49_flush_cache_all_d32i32(void)
{
    unsigned long flags, config;

    __save_and_cli(flags);
    blast_dcache32_wayLSB();
    /* disable icache (set ICE#) */
    config = read_32bit_cp0_register(CP0_CONFIG);
    write_32bit_cp0_register(CP0_CONFIG, config|TX49_CONF_IC);
    blast_icache32_wayLSB();
    write_32bit_cp0_register(CP0_CONFIG, config);
    __restore_flags(flags);
}
示例#12
0
void local_flush_tlb_range(struct mm_struct *mm, unsigned long start,
				unsigned long end)
{
	if (CPU_CONTEXT(smp_processor_id(), mm) != 0) {
		unsigned long flags;
		int size;

#ifdef DEBUG_TLB
		printk("[tlbrange<%02x,%08lx,%08lx>]", (mm->context & 0xff),
		       start, end);
#endif
		__save_and_cli(flags);
		size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
		size = (size + 1) >> 1;
		if(size <= mips_cpu.tlbsize/2) {
			int oldpid = (get_entryhi() & 0xff);
			int newpid = (CPU_CONTEXT(smp_processor_id(), mm) &
				      0xff);

			start &= (PAGE_MASK << 1);
			end += ((PAGE_SIZE << 1) - 1);
			end &= (PAGE_MASK << 1);
			while(start < end) {
				int idx;

				set_entryhi(start | newpid);
				start += (PAGE_SIZE << 1);
				BARRIER;
				tlb_probe();
				BARRIER;
				idx = get_index();
				set_entrylo0(0);
				set_entrylo1(0);
				if(idx < 0)
					continue;
				/* Make sure all entries differ. */
				set_entryhi(KSEG0+idx*0x2000);
				BARRIER;
				tlb_write_indexed();
				BARRIER;
			}
			set_entryhi(oldpid);
		} else {
			get_new_mmu_context(mm, smp_processor_id());
			if (mm == current->active_mm)
				set_entryhi(CPU_CONTEXT(smp_processor_id(),
							mm) & 0xff);
		}
		__restore_flags(flags);
	}
示例#13
0
void __init
ns87312_enable_ide(long ide_base)
{
	int data;
	unsigned long flags;

	__save_and_cli(flags);
	outb(0, ide_base);		/* set the index register for reg #0 */
	data = inb(ide_base+1);		/* read the current contents */
	outb(0, ide_base);		/* set the index register for reg #0 */
	outb(data | 0x40, ide_base+1);	/* turn on IDE */
	outb(data | 0x40, ide_base+1);	/* turn on IDE, really! */
	__restore_flags(flags);
}
示例#14
0
文件: tlb-r4k.c 项目: nhanh0/hah
void local_flush_tlb_mm(struct mm_struct *mm)
{
    if (mm->context != 0) {
        unsigned long flags;

#ifdef DEBUG_TLB
        printk("[tlbmm<%d>]", mm->context);
#endif
        __save_and_cli(flags);
        get_new_mmu_context(mm, smp_processor_id());
        if (mm == current->active_mm)
            set_entryhi(mm->context & 0xff);
        __restore_flags(flags);
    }
}
示例#15
0
static void r5900_flush_cache_range_d64i64(struct mm_struct *mm,
					 unsigned long start,
					 unsigned long end)
{
	if(mm->context != 0) {
		unsigned long flags;

#ifdef DEBUG_CACHE
		printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
#endif
		__save_and_cli(flags);
		blast_dcache64(); blast_icache64();
		__restore_flags(flags);
	}
}
示例#16
0
static unsigned int
conf_read(unsigned long addr, unsigned char type1,
	  struct pci_controler *hose)
{
	unsigned long flags;
	unsigned long mid = MCPCIA_HOSE2MID(hose->index);
	unsigned int stat0, value, temp, cpu;

	cpu = smp_processor_id();

	__save_and_cli(flags);

	DBG_CFG(("conf_read(addr=0x%lx, type1=%d, hose=%d)\n",
		 addr, type1, mid));

	/* Reset status register to avoid losing errors.  */
	stat0 = *(vuip)MCPCIA_CAP_ERR(mid);
	*(vuip)MCPCIA_CAP_ERR(mid) = stat0;
	mb();
	temp = *(vuip)MCPCIA_CAP_ERR(mid);
	DBG_CFG(("conf_read: MCPCIA_CAP_ERR(%d) was 0x%x\n", mid, stat0));

	mb();
	draina();
	mcheck_expected(cpu) = 1;
	mcheck_taken(cpu) = 0;
	mcheck_extra(cpu) = mid;
	mb();

	/* Access configuration space.  */
	value = *((vuip)addr);
	mb();
	mb();  /* magic */

	if (mcheck_taken(cpu)) {
		mcheck_taken(cpu) = 0;
		value = 0xffffffffU;
		mb();
	}
	mcheck_expected(cpu) = 0;
	mb();

	DBG_CFG(("conf_read(): finished\n"));

	__restore_flags(flags);
	return value;
}
示例#17
0
文件: sb1.c 项目: TitaniumBoy/lin
void flush_tlb_all(void)
{
	unsigned long flags;
	unsigned long old_ctx;
	int entry;

	__save_and_cli(flags);
	/* Save old context and create impossible VPN2 value */
	old_ctx = (get_entryhi() & 0xff);
	set_entrylo0(0);
	set_entrylo1(0);
	for (entry = 0; entry < tlb_entries; entry++) {
		set_entryhi(KSEG0 + (PAGE_SIZE << 1) * entry);
		set_index(entry);
		tlb_write_indexed();
	}
	set_entryhi(old_ctx);
	__restore_flags(flags);	
}
示例#18
0
void __init it8172_time_init(void)
{
        unsigned int est_freq, flags;

	__save_and_cli(flags);
        /* Set Data mode - binary. */ 
        CMOS_WRITE(CMOS_READ(RTC_CONTROL) | RTC_DM_BINARY, RTC_CONTROL);

	printk("calculating r4koff... ");
	r4k_offset = cal_r4koff();
	printk("%08lx(%d)\n", r4k_offset, (int) r4k_offset);

	est_freq = 2*r4k_offset*HZ;	
	est_freq += 5000;    /* round */
	est_freq -= est_freq%10000;
	printk("CPU frequency %d.%02d MHz\n", est_freq/1000000, 
	       (est_freq%1000000)*100/1000000);
	__restore_flags(flags);
}
示例#19
0
static void r49_flush_cache_range_d16i32(struct mm_struct *mm,
        unsigned long start,
        unsigned long end)
{
    if (mm->context != 0) {
        unsigned long flags, config;

#ifdef DEBUG_CACHE
        printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
#endif
        __save_and_cli(flags);
        blast_dcache16_wayLSB();
        /* disable icache (set ICE#) */
        config = read_32bit_cp0_register(CP0_CONFIG);
        write_32bit_cp0_register(CP0_CONFIG, config|TX49_CONF_IC);
        blast_icache32_wayLSB();
        write_32bit_cp0_register(CP0_CONFIG, config);
        __restore_flags(flags);
    }
}
示例#20
0
static void
r5900_dma_cache_inv_pc(unsigned long addr, unsigned long size)
{
	unsigned long end, a;

	if (size >= dcache_size) {
		flush_cache_all();
	} else {
		unsigned long flags;
		__save_and_cli(flags);
		a = addr & ~(dc_lsize - 1);
		end = (addr + size) & ~(dc_lsize - 1);
		while (1) {
			flush_dcache_line(a); /* Hit_Writeback_Inv_D */
			if (a == end) break;
			a += dc_lsize;
		}
		__restore_flags(flags);
	}
	bc_inv(addr, size);
}
示例#21
0
/* Drop into the prom, with the chance to continue with the 'go'
 * prom command.
 */
void
prom_cmdline(void)
{
    unsigned long flags;

    __save_and_cli(flags);

#ifdef CONFIG_SUN_CONSOLE
    if(!serial_console && prom_palette)
        prom_palette (1);
#endif

    /* We always arrive here via a serial interrupt.
     * So in order for everything to work reliably, even
     * on SMP, we need to drop the IRQ locks we hold.
     */
#ifdef CONFIG_SMP
    irq_exit(smp_processor_id(), 0);
    smp_capture();
#else
    local_irq_count(smp_processor_id())--;
#endif

    p1275_cmd ("enter", P1275_INOUT(0,0));

#ifdef CONFIG_SMP
    smp_release();
    irq_enter(smp_processor_id(), 0);
    spin_unlock_wait(&__br_write_locks[BR_GLOBALIRQ_LOCK].lock);
#else
    local_irq_count(smp_processor_id())++;
#endif

#ifdef CONFIG_SUN_CONSOLE
    if(!serial_console && prom_palette)
        prom_palette (0);
#endif

    __restore_flags(flags);
}
示例#22
0
void
dump_tlb_addr(unsigned long addr)
{
	unsigned int flags, oldpid;
	int index;

	__save_and_cli(flags);
	oldpid = get_entryhi() & 0xff;
	set_entryhi((addr & PAGE_MASK) | oldpid);
	tlb_probe();
	index = get_index();
	set_entryhi(oldpid);
	__restore_flags(flags);

	if (index < 0) {
		printk("No entry for address 0x%08lx in TLB\n", addr);
		return;
	}

	printk("Entry %d maps address 0x%08lx\n", index, addr);
	dump_tlb(index, index);
}
示例#23
0
int __init SMC93x_Init(void)
{
	unsigned long SMCUltraBase;
	unsigned long flags;

	__save_and_cli(flags);
	if ((SMCUltraBase = SMCDetectUltraIO()) != 0UL) {
#if SMC_DEBUG
		SMCReportDeviceStatus(SMCUltraBase);
#endif
		SMCEnableDevice(SMCUltraBase, SER1, COM1_BASE, COM1_INTERRUPT);
		DBG_DEVS(("SMC FDC37C93X: SER1 done\n"));
		SMCEnableDevice(SMCUltraBase, SER2, COM2_BASE, COM2_INTERRUPT);
		DBG_DEVS(("SMC FDC37C93X: SER2 done\n"));
		SMCEnableDevice(SMCUltraBase, PARP, PARP_BASE, PARP_INTERRUPT);
		DBG_DEVS(("SMC FDC37C93X: PARP done\n"));
		/* On PC164, IDE on the SMC is not enabled;
		   CMD646 (PCI) on MB */
		SMCEnableKYBD(SMCUltraBase);
		DBG_DEVS(("SMC FDC37C93X: KYB done\n"));
		SMCEnableFDC(SMCUltraBase);
		DBG_DEVS(("SMC FDC37C93X: FDC done\n"));
#if SMC_DEBUG
		SMCReportDeviceStatus(SMCUltraBase);
#endif
		SMCRunState(SMCUltraBase);
		__restore_flags(flags);
		printk("SMC FDC37C93X Ultra I/O Controller found @ 0x%lx\n",
		       SMCUltraBase);
		return 1;
	}
	else {
		__restore_flags(flags);
		DBG_DEVS(("No SMC FDC37C93X Ultra I/O Controller found\n"));
		return 0;
	}
}
示例#24
0
/* 
 * Figure out the r4k offset, the amount to increment the compare
 * register for each time tick. 
 * Use the RTC to calculate offset.
 */
static unsigned long __init cal_r4koff(void)
{
	unsigned int flags;

	__save_and_cli(flags);

	/* Start counter exactly on falling edge of update flag */
	while (CMOS_READ(RTC_REG_A) & RTC_UIP);
	while (!(CMOS_READ(RTC_REG_A) & RTC_UIP));

	/* Start r4k counter. */
	write_32bit_cp0_register(CP0_COUNT, 0);

	/* Read counter exactly on falling edge of update flag */
	while (CMOS_READ(RTC_REG_A) & RTC_UIP);
	while (!(CMOS_READ(RTC_REG_A) & RTC_UIP));

	mips_counter_frequency = read_32bit_cp0_register(CP0_COUNT);

	/* restore interrupts */
	__restore_flags(flags);
		
	return (mips_counter_frequency / HZ);
}
示例#25
0
static void __init sun4m_init_timers(void (*counter_fn)(int, void *, struct pt_regs *))
{
	int reg_count, irq, cpu;
	struct linux_prom_registers cnt_regs[PROMREG_MAX];
	int obio_node, cnt_node;
	struct resource r;

	cnt_node = 0;
	if((obio_node =
	    prom_searchsiblings (prom_getchild(prom_root_node), "obio")) == 0 ||
	   (obio_node = prom_getchild (obio_node)) == 0 ||
	   (cnt_node = prom_searchsiblings (obio_node, "counter")) == 0) {
		prom_printf("Cannot find /obio/counter node\n");
		prom_halt();
	}
	reg_count = prom_getproperty(cnt_node, "reg",
				     (void *) cnt_regs, sizeof(cnt_regs));
	reg_count = (reg_count/sizeof(struct linux_prom_registers));
    
	/* Apply the obio ranges to the timer registers. */
	prom_apply_obio_ranges(cnt_regs, reg_count);
    
	cnt_regs[4].phys_addr = cnt_regs[reg_count-1].phys_addr;
	cnt_regs[4].reg_size = cnt_regs[reg_count-1].reg_size;
	cnt_regs[4].which_io = cnt_regs[reg_count-1].which_io;
	for(obio_node = 1; obio_node < 4; obio_node++) {
		cnt_regs[obio_node].phys_addr =
			cnt_regs[obio_node-1].phys_addr + PAGE_SIZE;
		cnt_regs[obio_node].reg_size = cnt_regs[obio_node-1].reg_size;
		cnt_regs[obio_node].which_io = cnt_regs[obio_node-1].which_io;
	}

	memset((char*)&r, 0, sizeof(struct resource));
	/* Map the per-cpu Counter registers. */
	r.flags = cnt_regs[0].which_io;
	r.start = cnt_regs[0].phys_addr;
	sun4m_timers = (struct sun4m_timer_regs *) sbus_ioremap(&r, 0,
	    PAGE_SIZE*SUN4M_NCPUS, "sun4m_cpu_cnt");
	/* Map the system Counter register. */
	/* XXX Here we expect consequent calls to yeld adjusent maps. */
	r.flags = cnt_regs[4].which_io;
	r.start = cnt_regs[4].phys_addr;
	sbus_ioremap(&r, 0, cnt_regs[4].reg_size, "sun4m_sys_cnt");

	sun4m_timers->l10_timer_limit =  (((1000000/HZ) + 1) << 10);
	master_l10_counter = &sun4m_timers->l10_cur_count;
	master_l10_limit = &sun4m_timers->l10_timer_limit;

	irq = request_irq(TIMER_IRQ,
			  counter_fn,
			  (SA_INTERRUPT | SA_STATIC_ALLOC),
			  "timer", NULL);
	if (irq) {
		prom_printf("time_init: unable to attach IRQ%d\n",TIMER_IRQ);
		prom_halt();
	}
    
	if(linux_num_cpus > 1) {
		for(cpu = 0; cpu < 4; cpu++)
			sun4m_timers->cpu_timers[cpu].l14_timer_limit = 0;
		sun4m_interrupts->set = SUN4M_INT_E14;
	} else {
		sun4m_timers->cpu_timers[0].l14_timer_limit = 0;
	}
#ifdef CONFIG_SMP
	{
		unsigned long flags;
		extern unsigned long lvl14_save[4];
		struct tt_entry *trap_table = &sparc_ttable[SP_TRAP_IRQ1 + (14 - 1)];

		/* For SMP we use the level 14 ticker, however the bootup code
		 * has copied the firmwares level 14 vector into boot cpu's
		 * trap table, we must fix this now or we get squashed.
		 */
		__save_and_cli(flags);
		trap_table->inst_one = lvl14_save[0];
		trap_table->inst_two = lvl14_save[1];
		trap_table->inst_three = lvl14_save[2];
		trap_table->inst_four = lvl14_save[3];
		local_flush_cache_all();
		__restore_flags(flags);
	}
#endif
}