コード例 #1
0
static void
smp_chrp_setup_cpu(int cpu_nr)
{
	static atomic_t ready = ATOMIC_INIT(1);
	static volatile int frozen = 0;

	if (systemcfg->platform == PLATFORM_PSERIES_LPAR) {
		/* timebases already synced under the hypervisor. */
		paca[cpu_nr].next_jiffy_update_tb = tb_last_stamp = get_tb();
		if (cpu_nr == 0) {
			systemcfg->tb_orig_stamp = tb_last_stamp;
			/* Should update naca->stamp_xsec.
			 * For now we leave it which means the time can be some
			 * number of msecs off until someone does a settimeofday()
			 */
		}
		smp_tb_synchronized = 1;
	} else {
		if (cpu_nr == 0) {
			/* wait for all the others */
			while (atomic_read(&ready) < smp_num_cpus)
				barrier();
			atomic_set(&ready, 1);
			/* freeze the timebase */
			rtas_call(rtas_token("freeze-time-base"), 0, 1, NULL);
			mb();
			frozen = 1;
			set_tb(0, 0);
			paca[0].next_jiffy_update_tb = 0;
			smp_space_timers(smp_num_cpus);
			while (atomic_read(&ready) < smp_num_cpus)
				barrier();
			/* thaw the timebase again */
			rtas_call(rtas_token("thaw-time-base"), 0, 1, NULL);
			mb();
			frozen = 0;
			tb_last_stamp = get_tb();
			systemcfg->tb_orig_stamp = tb_last_stamp;
			smp_tb_synchronized = 1;
		} else {
			atomic_inc(&ready);
			while (!frozen)
				barrier();
			set_tb(0, 0);
			mb();
			atomic_inc(&ready);
			while (frozen)
				barrier();
		}
	}

	if (OpenPIC_Addr) {
		do_openpic_setup_cpu();
	} else {
	  if (cpu_nr > 0)
	    xics_setup_cpu();
	}
}
コード例 #2
0
ファイル: smp.c プロジェクト: 1x23/unifi-gpl
void __devinit smp_chrp_take_timebase(void)
{
	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);
	printk("CPU %i taken timebase\n", smp_processor_id());
}
コード例 #3
0
ファイル: chrp_smp.c プロジェクト: liexusong/Linux-2.4.16
static void __init
smp_chrp_setup_cpu(int cpu_nr)
{
	static atomic_t ready = ATOMIC_INIT(1);
	static volatile int frozen = 0;

	if (cpu_nr == 0) {
		/* wait for all the others */
		while (atomic_read(&ready) < smp_num_cpus)
			barrier();
		atomic_set(&ready, 1);
		/* freeze the timebase */
		call_rtas("freeze-time-base", 0, 1, NULL);
		mb();
		frozen = 1;
		/* XXX assumes this is not a 601 */
		set_tb(0, 0);
		last_jiffy_stamp(0) = 0;
		while (atomic_read(&ready) < smp_num_cpus)
			barrier();
		/* thaw the timebase again */
		call_rtas("thaw-time-base", 0, 1, NULL);
		mb();
		frozen = 0;
		smp_tb_synchronized = 1;
	} else {
		atomic_inc(&ready);
		while (!frozen)
			barrier();
		set_tb(0, 0);
		last_jiffy_stamp(0) = 0;
		mb();
		atomic_inc(&ready);
		while (frozen)
			barrier();
	}

	if (OpenPIC_Addr)
		do_openpic_setup_cpu();
}
コード例 #4
0
/**************************************************************************
 * FUNCTION: chestnut_setup_arch
 *
 * DESCRIPTION: ppc_md machine configuration callback
 *
 ****/
static void __init
chestnut_setup_arch(void)
{
    if (ppc_md.progress)
        ppc_md.progress("chestnut_setup_arch: enter", 0);

    /* init to some ~sane value until calibrate_delay() runs */
    loops_per_jiffy = 50000000 / HZ;

    /* if the time base value is greater than bus freq/4 (the TB and
    	* decrementer tick rate) + signed integer rollover value, we
    	* can spend a fair amount of time waiting for the rollover to
    	* happen.  To get around this, initialize the time base register
    	* to a "safe" value.
    	*/
    set_tb(0, 0);

#ifdef CONFIG_BLK_DEV_INITRD
    if (initrd_start)
        ROOT_DEV = Root_RAM0;
    else
#endif
#ifdef CONFIG_ROOT_NFS
        ROOT_DEV = Root_NFS;
#else
        ROOT_DEV = Root_SDA2;
#endif

    /*
    	* Set up the L2CR register.
    	*/
    _set_L2CR(_get_L2CR() | L2CR_L2E);

    chestnut_setup_bridge();
    chestnut_setup_peripherals();

#ifdef CONFIG_DUMMY_CONSOLE
    conswitchp = &dummy_con;
#endif

#if defined(CONFIG_SERIAL_8250)
    chestnut_early_serial_map();
#endif

    /* Identify the system */
    printk(KERN_INFO "System Identification: IBM 750FX/GX Eval Board\n");
    printk(KERN_INFO "IBM 750FX/GX port (C) 2004 MontaVista Software, Inc."
           " ([email protected])\n");

    if (ppc_md.progress)
        ppc_md.progress("chestnut_setup_arch: exit", 0);
}
コード例 #5
0
ファイル: katana.c プロジェクト: janrinze/loox7xxport
static void __init
katana_setup_arch(void)
{
	if (ppc_md.progress)
		ppc_md.progress("katana_setup_arch: enter", 0);

	set_tb(0, 0);

#ifdef CONFIG_BLK_DEV_INITRD
	if (initrd_start)
		ROOT_DEV = Root_RAM0;
	else
#endif
#ifdef   CONFIG_ROOT_NFS
		ROOT_DEV = Root_NFS;
#else
		ROOT_DEV = Root_SDA2;
#endif

	/*
	 * Set up the L2CR register.
	 *
	 * 750FX has only L2E, L2PE (bits 2-8 are reserved)
	 * DD2.0 has bug that requires the L2 to be in WRT mode
	 * avoid dirty data in cache
	 */
	if (PVR_REV(mfspr(SPRN_PVR)) == 0x0200) {
		printk(KERN_INFO "DD2.0 detected. Setting L2 cache"
			"to Writethrough mode\n");
		_set_L2CR(L2CR_L2E | L2CR_L2PE | L2CR_L2WT);
	} else
		_set_L2CR(L2CR_L2E | L2CR_L2PE);

	if (ppc_md.progress)
		ppc_md.progress("katana_setup_arch: calling setup_bridge", 0);

	katana_setup_bridge();
	katana_setup_peripherals();
	katana_enable_ipmi();

	katana_bus_frequency = katana_bus_freq(cpld_base);

	printk(KERN_INFO "Artesyn Communication Products, LLC - Katana(TM)\n");
	if (ppc_md.progress)
		ppc_md.progress("katana_setup_arch: exit", 0);
}
コード例 #6
0
ファイル: ev64360.c プロジェクト: 274914765/C
static void __init
ev64360_setup_arch(void)
{
    if (ppc_md.progress)
        ppc_md.progress("ev64360_setup_arch: enter", 0);

    set_tb(0, 0);

#ifdef CONFIG_BLK_DEV_INITRD
    if (initrd_start)
        ROOT_DEV = Root_RAM0;
    else
#endif
#ifdef   CONFIG_ROOT_NFS
        ROOT_DEV = Root_NFS;
#else
        ROOT_DEV = Root_SDA2;
#endif

    /*
     * Set up the L2CR register.
     */
    _set_L2CR(L2CR_L2E | L2CR_L2PE);

    if (ppc_md.progress)
        ppc_md.progress("ev64360_setup_arch: calling setup_bridge", 0);

    ev64360_setup_bridge();
    ev64360_setup_peripherals();
    ev64360_bus_frequency = ev64360_bus_freq();

    printk(KERN_INFO "%s %s port (C) 2005 Lee Nicks "
        "([email protected])\n", BOARD_VENDOR, BOARD_MACHINE);
    if (ppc_md.progress)
        ppc_md.progress("ev64360_setup_arch: exit", 0);
}
コード例 #7
0
ファイル: smp.c プロジェクト: dduval/kernel-rhel3
void __init smp_software_tb_sync(int cpu)
{
#define PASSES 4	/* 4 passes.. */
	int pass;
	int i, j;

	/* stop - start will be the number of timebase ticks it takes for cpu0
	 * to send a message to all others and the first reponse to show up.
	 *
	 * ASSUMPTION: this time is similiar for all cpus
	 * ASSUMPTION: the time to send a one-way message is ping/2
	 */
	register unsigned long start = 0;
	register unsigned long stop = 0;
	register unsigned long temp = 0;

	set_tb(0, 0);

	/* multiple passes to get in l1 cache.. */
	for (pass = 2; pass < 2+PASSES; pass++){
		if (cpu == 0){
			mb();
			for (i = j = 1; i < smp_num_cpus; i++, j++){
				/* skip stuck cpus */
				while (!cpu_callin_map[j])
					++j;
				while (cpu_callin_map[j] != pass)
					barrier();
			}
			mb();
			tb_sync_flag = pass;
			start = get_tbl();	/* start timing */
			while (tb_sync_flag)
				mb();
			stop = get_tbl();	/* end timing */
			/* theoretically, the divisor should be 2, but
			 * I get better results on my dual mtx. someone
			 * please report results on other smp machines..
			 */
			tb_offset = (stop-start)/4;
			mb();
			tb_sync_flag = pass;
			udelay(10);
			mb();
			tb_sync_flag = 0;
			mb();
			set_tb(0,0);
			mb();
		} else {
			cpu_callin_map[cpu] = pass;
			mb();
			while (!tb_sync_flag)
				mb();		/* wait for cpu0 */
			mb();
			tb_sync_flag = 0;	/* send response for timing */
			mb();
			while (!tb_sync_flag)
				mb();
			temp = tb_offset;	/* make sure offset is loaded */
			while (tb_sync_flag)
				mb();
			set_tb(0,temp);		/* now, set the timebase */
			mb();
		}
	}
	if (cpu == 0) {
		smp_tb_synchronized = 1;
		printk("smp_software_tb_sync: %d passes, final offset: %ld\n",
			PASSES, tb_offset);
	}
	/* so time.c doesn't get confused */
	set_dec(tb_ticks_per_jiffy);
	last_jiffy_stamp(cpu) = 0;
}