예제 #1
0
파일: smp.c 프로젝트: fgeraci/cs518-sched
void __init smp_callin(void)
{
	int cpu = current->processor;
	
        smp_store_cpu_info(cpu);
	set_dec(tb_ticks_per_jiffy);
	cpu_callin_map[cpu] = 1;

	smp_ops->setup_cpu(cpu);

	init_idle();

	/*
	 * This cpu is now "online".  Only set them online
	 * before they enter the loop below since write access
	 * to the below variable is _not_ guaranteed to be
	 * atomic.
	 *   -- Cort <*****@*****.**>
	 */
	cpu_online_map |= 1UL << smp_processor_id();
	
	while(!smp_commenced)
		barrier();

	/* see smp_commence for more info */
	if (!smp_tb_synchronized && smp_num_cpus == 2) {
		smp_software_tb_sync(cpu);
	}
	__sti();
}
예제 #2
0
파일: system.c 프로젝트: ferranpm/zeos
  main(void)
{

  set_eflags();

  /* Define the kernel segment registers */
  set_seg_regs(__KERNEL_DS, __KERNEL_DS, INITIAL_ESP);

  printk("Kernel Loaded!    ");

  /* Initialize hardware data */
  setGdt(); /* Definicio de la taula de segments de memoria */
  setIdt(); /* Definicio del vector de interrupcions */
  setTSS(); /* Definicio de la TSS */

  /* Initialize Memory */
  init_mm();

/* Initialize an address space to be used for the monoprocess version of ZeOS */

  /* monoprocess_init_addr_space(); TO BE DELETED WHEN ADDED THE PROCESS MANAGEMENT CODE TO BECOME MULTIPROCESS */

  /* Initialize Scheduling */
  init_sched();

  /* Initialize idle task data */
  init_idle();

  /* Initialize task 1 data */
  init_task1();

  /* Initialize keyboard buffer */
  init_keyboard_buffer();

  /* Move user code/data now (after the page table initialization) */
  copy_data((void *) KERNEL_START + *p_sys_size, usr_main, *p_usr_size);

  /* Adds this call in order to perform test suite provided by lab course */
  zeos_init_auxjp();

  printk("Entering user mode...");

  /*
   * zeos_ticks must be initialized after memory initialization and just before
   * enabling interrupts in order to measure the correct elapsed time
   */
  zeos_ticks = 0;

  enable_int();

  /*
   * We return from a 'theorical' call to a 'call gate' to reduce our privileges
   * and going to execute 'magically' at 'usr_main'...
   */
  return_gate(__USER_DS, __USER_DS, USER_ESP, __USER_CS, L_USER_START);

  /* The execution never arrives to this point */
  return 0;
}
예제 #3
0
파일: fork.c 프로젝트: 19Dan01/linux
struct task_struct *fork_idle(int cpu)
{
	struct task_struct *task;
	task = copy_process(CLONE_VM, 0, 0, NULL, &init_struct_pid, 0);
	if (!IS_ERR(task)) {
		init_idle_pids(task->pids);
		init_idle(task, cpu);
	}

	return task;
}
예제 #4
0
파일: fork.c 프로젝트: maliyu/SOM2416
struct task_struct * __cpuinit fork_idle(int cpu)
{
	struct task_struct *task;
	struct pt_regs regs;

	task = copy_process(CLONE_VM, 0, idle_regs(&regs), 0, NULL, NULL, 0);
	if (!IS_ERR(task))
		init_idle(task, cpu);

	return task;
}
예제 #5
0
task_t * __devinit fork_idle(int cpu)
{
	task_t *task;
	struct pt_regs regs;

	task = copy_process(CLONE_VM, 0, idle_regs(&regs), 0, NULL, NULL, 0);
	if (!task)
		return ERR_PTR(-ENOMEM);
	init_idle(task, cpu);
	unhash_process(task);
	return task;
}
예제 #6
0
/*
 * The idle thread. There's no useful work to be
 * done, so just try to conserve power and have a
 * low exit latency (ie sit in a loop waiting for
 * somebody to say that they'd like to reschedule)
 */
void cpu_idle(void)
{
	/* endless idle loop with no priority at all */
	init_idle();

	while (1) {
		while (!current->need_resched) {
		}
		schedule();
		check_pgt_cache();
	}
}
예제 #7
0
파일: system.c 프로젝트: felixramos/so2
main(void)
{
    
    set_eflags();
    
    /* Define the kernel segment registers  and a stack to execute the 'main' code */
    // It is necessary to use a global static array for the stack, because the
    // compiler will know its final memory location. Otherwise it will try to use the
    // 'ds' register to access the address... but we are not ready for that yet
    // (we are still in real mode).
    set_seg_regs(__KERNEL_DS, __KERNEL_DS, (DWord) &protected_tasks[5]);
    
    printk("Kernel Loaded!    ");
    
    /* Initialize hardware data */
    setGdt(); /* Definicio de la taula de segments de memoria */
    setIdt(); /* Definicio del vector de interrupcions */
    setTSS(); /* Definicio de la TSS */
    
    /* Initialize Memory */
    init_mm();
    
    /* Initialize an address space to be used for the monoprocess version of ZeOS */
    
    monoprocess_init_addr_space(); /* TO BE DELETED WHEN ADDED THE PROCESS MANAGEMENT CODE TO BECOME MULTIPROCESS */
    
    /* Initialize Scheduling */
    init_sched();
    
    /* Initialize idle task  data */
    init_idle();
    /* Initialize task 1 data */
    init_task1();

    /* Initialize semaphores */
    init_semaphores();
    
    /* Move user code/data now (after the page table initialization) */
    copy_data((void *) KERNEL_START + *p_sys_size, usr_main, *p_usr_size);
    
    
    printk("Entering user mode...");
    
    enable_int();
    /*
     * We return from a 'theorical' call to a 'call gate' to reduce our privileges
     * and going to execute 'magically' at 'usr_main'...
     */
    return_gate(__USER_DS, __USER_DS, USER_ESP, __USER_CS, L_USER_START);
    
    /* The execution never arrives to this point */
    return 0;
}
예제 #8
0
ATTRIB_NORET void cpu_idle(void)
{
	/* endless idle loop with no priority at all */
	init_idle();

	while (1) {
		while (!current->need_resched)
			if (cpu_wait)
				(*cpu_wait)();
		schedule();
		check_pgt_cache();
	}
}
예제 #9
0
struct task_struct * __cpuinit fork_idle(int cpu)
{
	struct task_struct *task;
	struct pt_regs regs;

	task = copy_process(CLONE_VM, 0, idle_regs(&regs), 0, NULL,
			    &init_struct_pid, 0);
	if (!IS_ERR(task)) {
		init_idle_pids(task->pids);
		init_idle(task, cpu);
	}

	return task;
}
예제 #10
0
파일: process.c 프로젝트: nhanh0/hah
/* This is being executed in task 0 'user space'. */
int cpu_idle(void)
{
	/* endless idle loop with no priority at all */
	current->nice = 20;
	current->counter = -100;
	init_idle();

	while(1) {
		if(current->need_resched) {
			schedule();
			check_pgt_cache();
		}
		barrier(); /* or else gcc optimizes... */
	}
}
예제 #11
0
void cpu_idle(void)
{
	/* endless idle loop with no priority at all */
	current->nice = 20;
	current->counter = -100;
	init_idle();

	while (1) {
		while (!current->need_resched)
			if (cpu_wait)
				(*cpu_wait)();
		schedule();
		check_pgt_cache();
	}
}
예제 #12
0
파일: system.c 프로젝트: Arau/ZeOS
  main(void) 
{

  set_eflags();

  /* Define the kernel segment registers */
  set_seg_regs(__KERNEL_DS, __KERNEL_DS, KERNEL_ESP);


  printk("Kernel Loaded!    "); 

  /* Initialize hardware data */
  setGdt(); /* Definicio de la taula de segments de memoria */
  setIdt(); /* Definicio del vector de interrupcions */
  setTSS(); /* Definicio de la TSS */

  /* Initialize Memory */
  init_mm();

/* Initialize an address space to be used for the monoprocess version of ZeOS */

//  monoprocess_init_addr_space(); /* TO BE DELETED WHEN ADDED THE PROCESS MANAGEMENT CODE TO BECOME MULTIPROCESS */

  /* Initialize Scheduling */
  init_sched();

  /* Initialize idle task  data */
  init_idle();
  /* Initialize task 1 data */
  init_task1();

  /* Move user code/data now (after the page table initialization) */
  copy_data((void *) KERNEL_START + *p_sys_size, usr_main, *p_usr_size);


  
  printk("Entering user mode..."); 
  
  enable_int();
  /*
   * We return from a 'theorical' call to a 'call gate' to reduce our privileges
   * and going to execute 'magically' at 'usr_main'...
   */
  return_gate(__USER_DS, __USER_DS, USER_ESP, __USER_CS, L_USER_START);

  /* The execution never arrives to this point */
  return 0;
}
예제 #13
0
파일: process.c 프로젝트: nhanh0/hah
/*
 * the idle loop on a Sparc... ;)
 */
int cpu_idle(void)
{
	int ret = -EPERM;

	if (current->pid != 0)
		goto out;

	/* endless idle loop with no priority at all */
	current->nice = 20;
	current->counter = -100;
	init_idle();

	for (;;) {
		if (ARCH_SUN4C_SUN4) {
			static int count = HZ;
			static unsigned long last_jiffies = 0;
			static unsigned long last_faults = 0;
			static unsigned long fps = 0;
			unsigned long now;
			unsigned long faults;
			unsigned long flags;

			extern unsigned long sun4c_kernel_faults;
			extern void sun4c_grow_kernel_ring(void);

			save_and_cli(flags);
			now = jiffies;
			count -= (now - last_jiffies);
			last_jiffies = now;
			if (count < 0) {
				count += HZ;
				faults = sun4c_kernel_faults;
				fps = (fps + (faults - last_faults)) >> 1;
				last_faults = faults;
#if 0
				printk("kernel faults / second = %d\n", fps);
#endif
				if (fps >= SUN4C_FAULT_HIGH) {
					sun4c_grow_kernel_ring();
				}
			}
			restore_flags(flags);
		}
		check_pgt_cache();
		schedule();
	}
예제 #14
0
void __init smp_callin(void)
{
	int cpu = current->processor;
	
        smp_store_cpu_info(cpu);
	set_dec(paca[cpu].default_decr);
	cpu_callin_map[cpu] = 1;

	ppc_md.smp_setup_cpu(cpu);

	init_idle();

	set_bit(smp_processor_id(), &cpu_online_map);
	
	while(!smp_commenced) {
		barrier();
	}
	__sti();
}
예제 #15
0
int idled(void)
{
	int do_power_save = 0;

	/* Check if CPU can powersave (get rid of that soon!) */
	if (cur_cpu_spec[smp_processor_id()]->cpu_features &
		(CPU_FTR_CAN_DOZE | CPU_FTR_CAN_NAP))
		do_power_save = 1;

	/* endless loop with no priority at all */
	current->nice = 20;
	current->counter = -100;
	init_idle();
	for (;;) {
#ifdef CONFIG_SMP
		if (!do_power_save) {
			/*
			 * Deal with another CPU just having chosen a thread to
			 * run here:
			 */
			int oldval = xchg(&current->need_resched, -1);

			if (!oldval) {
				while(current->need_resched == -1)
					; /* Do Nothing */
			}
		}
#endif
#ifdef CONFIG_6xx
		if (do_power_save && !current->need_resched)
			power_save_6xx();
#endif /* CONFIG_6xx */			

		if (current->need_resched) {
			schedule();
			check_pgt_cache();
		}
	}
	return 0;
}
예제 #16
0
파일: main.c 프로젝트: zzt93/os-lab1
void
os_init_cont(void) {
    /* Reset the GDT. Although user processes in Nanos run in Ring 0,
       they have their own virtual address space. Therefore, the
       old GDT located in physical address 0x7C00 cannot be used again. */
    init_segment();

    /* Initialize the serial port. After that, you can use printk() */
    init_serial();

    /* Set up interrupt and exception handlers,
       just as we did in the game. */
    init_idt();

    /* Initialize the intel 8259 PIC. */
    //The Intel 8259 is a Programmable Interrupt Controller (PIC)
    init_intr();

    /**
       initialize kmalloc -- have to initialize it before init
       process, for using it in allocating memory for PCB
    */
    init_kmalloc();
    // make it NOINTR, can receive msg, can schedule
    init_idle();

    NOINTR;

    /**
       init_driver() have to before init_file_system() for FM have
       to send message to `ide` to read file system
     */
    init_driver();
    init_manager();
    NOINTR;
    init_error_msg();
    // init_proc() and init_manager() can replace??
    // solved by split set count_of_lock out of init_proc();

    //more_frequent();
    // init empty thread
    init_proc_test();

    // here is to initialize shell process, which must later
    // than init_manager -- for it will send message to
    // managers
    //ram_user_process();


    // @checked: move from locked state to unlocked state
    init_file_system();

    unlock(); // set interrupt enabled
    INTR;

    /**
       init_file_system() have to before init_proc()
       for init_proc() will using the `default_cwd` which is
       initialized by FM
    */
    /* Initialize the state of process idle, ie the running
       process for set up right lock num to avoid other
       initialization enable the interrupt and cause problem
    */

    // @checked: move from locked state to unlocked state
    welcome();

    user_process();
    // set idle not to using cpu time
    // for it is originally set to sleep when send message
    current->state = SLEEPED;


    /* This context now becomes the idle process. */
    while (1) {
        printk("!");
        wait_intr();
    }
}
예제 #17
0
static int __devinit
do_boot_cpu (int sapicid, int cpu)
{
    int timeout;
    struct create_idle c_idle = {
        .cpu	= cpu,
        .done	= COMPLETION_INITIALIZER(c_idle.done),
    };
    DECLARE_WORK(work, do_fork_idle, &c_idle);

    c_idle.idle = get_idle_for_cpu(cpu);
    if (c_idle.idle) {
        init_idle(c_idle.idle, cpu);
        goto do_rest;
    }

    /*
     * We can't use kernel_thread since we must avoid to reschedule the child.
     */
    if (!keventd_up() || current_is_keventd())
        work.func(work.data);
    else {
        schedule_work(&work);
        wait_for_completion(&c_idle.done);
    }

    if (IS_ERR(c_idle.idle))
        panic("failed fork for CPU %d", cpu);

    set_idle_for_cpu(cpu, c_idle.idle);

do_rest:
    task_for_booting_cpu = c_idle.idle;

    Dprintk("Sending wakeup vector %lu to AP 0x%x/0x%x.\n", ap_wakeup_vector, cpu, sapicid);

    set_brendez_area(cpu);
    platform_send_ipi(cpu, ap_wakeup_vector, IA64_IPI_DM_INT, 0);

    /*
     * Wait 10s total for the AP to start
     */
    Dprintk("Waiting on callin_map ...");
    for (timeout = 0; timeout < 100000; timeout++) {
        if (cpu_isset(cpu, cpu_callin_map))
            break;  /* It has booted */
        udelay(100);
    }
    Dprintk("\n");

    if (!cpu_isset(cpu, cpu_callin_map)) {
        printk(KERN_ERR "Processor 0x%x/0x%x is stuck.\n", cpu, sapicid);
        ia64_cpu_to_sapicid[cpu] = -1;
        cpu_clear(cpu, cpu_online_map);  /* was set in smp_callin() */
        return -EINVAL;
    }
    return 0;
}

static int __init
decay (char *str)
{
    int ticks;
    get_option (&str, &ticks);
    return 1;
}
예제 #18
0
파일: smp.c 프로젝트: dduval/kernel-rhel3
void __init smp_boot_cpus(void)
{
	extern struct task_struct *current_set[NR_CPUS];
	int i, cpu_nr;
	struct task_struct *p;

	printk("Entering SMP Mode...\n");
	smp_num_cpus = 1;
        smp_store_cpu_info(0);
	cpu_online_map = 1UL;

	/*
	 * assume for now that the first cpu booted is
	 * cpu 0, the master -- Cort
	 */
	cpu_callin_map[0] = 1;
	current->processor = 0;

	for (i = 0; i < NR_CPUS; i++) {
		prof_counter[i] = 1;
		prof_multiplier[i] = 1;
	}

	/*
	 * XXX very rough, assumes 20 bus cycles to read a cache line,
	 * timebase increments every 4 bus cycles, 32kB L1 data cache.
	 */
	cacheflush_time = 5 * 1024;

	smp_ops = ppc_md.smp_ops;
	if (smp_ops == NULL) {
		printk("SMP not supported on this machine.\n");
		return;
	}

#ifndef CONFIG_750_SMP
	/* check for 750's, they just don't work with linux SMP.
	 * If you actually have 750 SMP hardware and want to try to get
	 * it to work, send me a patch to make it work and
	 * I'll make CONFIG_750_SMP a config option.  -- Troy ([email protected])
	 */
	if ( PVR_VER(mfspr(PVR)) == 8 ){
		printk("SMP not supported on 750 cpus. %s line %d\n",
				__FILE__, __LINE__);
		return;
	}
#endif


	/* Probe arch for CPUs */
	cpu_nr = smp_ops->probe();

	/* Backup CPU 0 state */
	__save_cpu_setup();
	
	/*
	 * only check for cpus we know exist.  We keep the callin map
	 * with cpus at the bottom -- Cort
	 */
	if (cpu_nr > max_cpus)
		cpu_nr = max_cpus;
	for (i = 1; i < cpu_nr; i++) {
		int c;
		struct pt_regs regs;
		
		/* create a process for the processor */
		/* only regs.msr is actually used, and 0 is OK for it */
		memset(&regs, 0, sizeof(struct pt_regs));
		if (do_fork(CLONE_VM|CLONE_PID, 0, &regs, 0) < 0)
			panic("failed fork for CPU %d", i);
		p = init_task.prev_task;
		if (!p)
			panic("No idle task for CPU %d", i);
		init_idle(p, i);

		unhash_process(p);
		init_tasks[i] = p;

		p->processor = i;
		p->cpus_runnable = 1 << i; /* we schedule the first task manually */
		current_set[i] = p;

		/*
		 * There was a cache flush loop here to flush the cache
		 * to memory for the first 8MB of RAM.  The cache flush
		 * has been pushed into the kick_cpu function for those
		 * platforms that need it.
		 */

		/* wake up cpus */
		smp_ops->kick_cpu(i);
		
		/*
		 * wait to see if the cpu made a callin (is actually up).
		 * use this value that I found through experimentation.
		 * -- Cort
		 */
		for ( c = 10000; c && !cpu_callin_map[i] ; c-- )
			udelay(100);
		
		if ( cpu_callin_map[i] )
		{
			char buf[32];
			sprintf(buf, "found cpu %d", i);
			if (ppc_md.progress) ppc_md.progress(buf, 0x350+i);
			printk("Processor %d found.\n", i);
			smp_num_cpus++;
		} else {
			char buf[32];
			sprintf(buf, "didn't find cpu %d", i);
			if (ppc_md.progress) ppc_md.progress(buf, 0x360+i);
			printk("Processor %d is stuck.\n", i);
		}
	}

	/* Setup CPU 0 last (important) */
	smp_ops->setup_cpu(0);
	
	if (smp_num_cpus < 2)
		smp_tb_synchronized = 1;
}
예제 #19
0
asmlinkage void __init start_kernel(void)
{
   char * command_line;
   extern char saved_command_line[];
   extern struct kernel_param __start___param[], __stop___param[];

#ifdef TARGET_OS2
   LX_set_sysstate(LXSYSSTATE_KERNEL_BOOT_STARTED,0);
#endif
/*
 * Interrupts are still disabled. Do necessary setups, then
 * enable them
 */
   lock_kernel();
   page_address_init();
   printk(linux_banner);
   setup_arch(&command_line);
   setup_per_cpu_areas();

   /*
    * Mark the boot cpu "online" so that it can call console drivers in
    * printk() and can access its per-cpu storage.
    */
   smp_prepare_boot_cpu();

   build_all_zonelists();
   page_alloc_init();
   printk("Kernel command line: %s\n", saved_command_line);
   #ifdef TARGET_OS2
   parse_args("Booting kernel", command_line, __start___param,
         0,
         &unknown_bootoption);
   #else
   parse_args("Booting kernel", command_line, __start___param,
         __stop___param - __start___param,
         &unknown_bootoption);
   #endif
   sort_main_extable();
   trap_init();
   rcu_init();
   init_IRQ();
   pidhash_init();
   sched_init();
   softirq_init();
   time_init();

   /*
    * HACK ALERT! This is early. We're enabling the console before
    * we've done PCI setups etc, and console_init() must be aware of
    * this. But we do want output early, in case something goes wrong.
    */
   console_init();
   if (panic_later)
      panic(panic_later, panic_param);
   profile_init();
   local_irq_enable();
#ifdef CONFIG_BLK_DEV_INITRD
   if (initrd_start && !initrd_below_start_ok &&
         initrd_start < min_low_pfn << PAGE_SHIFT) {
      printk(KERN_CRIT "initrd overwritten (0x%08lx < 0x%08lx) - "
          "disabling it.\n",initrd_start,min_low_pfn << PAGE_SHIFT);
      initrd_start = 0;
   }
#endif
   mem_init();
   kmem_cache_init();
   if (late_time_init)
      late_time_init();
   calibrate_delay();
   pidmap_init();
   pgtable_cache_init();
   pte_chain_init();
#ifdef CONFIG_X86
   if (efi_enabled)
      efi_enter_virtual_mode();
#endif
   fork_init(num_physpages);
   proc_caches_init();
   buffer_init();
   unnamed_dev_init();
   security_scaffolding_startup();
   vfs_caches_init(num_physpages);
   radix_tree_init();
   signals_init();
   /* rootfs populating might need page-writeback */
   page_writeback_init();
#ifdef CONFIG_PROC_FS
   proc_root_init();
#endif
   check_bugs();
   printk("POSIX conformance testing by UNIFIX\n");
   /*
    * We count on the initial thread going ok
    * Like idlers init is an unlocked kernel thread, which will
    * make syscalls (and thus be locked).
    */
   init_idle(current, smp_processor_id());
   /* Do the rest non-__init'ed, we're now alive */
   rest_init();
}
예제 #20
0
파일: uManage.c 프로젝트: jcolag/uManage
int main (int argc, char *argv[]) {
#ifdef GUI
    void               *status;
    char                path[256];
    pthread_t           thr_menu;
#endif

    /*
     * Program setup
     *     Handle user interrupt and alarm
     *     Get program options
     *     Open report file for logging if needed
     *     Initialize UI
     */
    signal(SIGINT, handle_break);
    signal(SIGALRM, handle_alarm);
    alarm(1);

    get_configuration(&opts);
    if (parse_options(argc, argv, &opts)) {
        return 1;
    }
    if (opts.save_options) {
        save_configuration(&opts);
    }

    if (opts.text_out) {
        report = fopen(opts.filename, "a");
        if(report == NULL) {
            report = stdout;
        }
    }

    init_idle();
    init_winmgmt(&opts);
    window_state_init(&current);
#ifdef GUI
    get_executable_path(path, sizeof(path));
    init_indicator(argc, argv, path, &opts);
    if (opts.menu_items != NULL) {
        add_menu_items(opts.menu_items);
    }
    fflush(NULL);
    pthread_create(&thr_menu, NULL, run_indicator, &current.force);
#endif
    if (opts.use_database) {
        open_database(opts.dbname);
    }

    while(poll_continue || current.force) {
        sleep(1);                       /* Just wait for program close */
    }
    /*
     * Clean up
     */
    alarm(1);                           /* Last hurrah */
    sleep(1);
#ifdef GUI
    pthread_join(thr_menu, &status);
#endif
    if (report != stdout && opts.text_out) {
        fclose(report);
    }
    if (opts.use_database) {
        close_database();
    }
    return 0;
}
예제 #21
0
void __init smp_boot_cpus(void)
{
	extern struct current_set_struct current_set[];
	extern void __secondary_start_chrp(void);
	int i, cpu_nr;
	struct task_struct *p;
	unsigned long sp;

	printk("Entering SMP Mode...\n");
	PPCDBG(PPCDBG_SMP, "smp_boot_cpus: start.  NR_CPUS = 0x%lx\n", NR_CPUS);

	smp_num_cpus = 1;
        smp_store_cpu_info(0);
	cpu_online_map = 1UL;

	/*
	 * assume for now that the first cpu booted is
	 * cpu 0, the master -- Cort
	 */
	cpu_callin_map[0] = 1;
	current->processor = 0;

	init_idle();

	for (i = 0; i < NR_CPUS; i++) {
		paca[i].prof_counter = 1;
		paca[i].prof_multiplier = 1;
		if(i != 0) {
		        /*
			 * Processor 0's segment table is statically 
			 * initialized to real address STAB0_PHYS_ADDR.  The
			 * Other processor's tables are created and
			 * initialized here.
			 */
			paca[i].xStab_data.virt = (unsigned long)&stab_array[PAGE_SIZE * (i-1)];
			memset((void *)paca[i].xStab_data.virt, 0, PAGE_SIZE); 
			paca[i].xStab_data.real = __v2a(paca[i].xStab_data.virt);
			paca[i].default_decr = tb_ticks_per_jiffy / decr_overclock;
		}
	}

	/*
	 * XXX very rough, assumes 20 bus cycles to read a cache line,
	 * timebase increments every 4 bus cycles, 32kB L1 data cache.
	 */
	cacheflush_time = 5 * 1024;

	/* Probe arch for CPUs */
	cpu_nr = ppc_md.smp_probe();

	printk("Probe found %d CPUs\n", cpu_nr);

	/*
	 * only check for cpus we know exist.  We keep the callin map
	 * with cpus at the bottom -- Cort
	 */
	if (cpu_nr > max_cpus)
		cpu_nr = max_cpus;

#ifdef CONFIG_PPC_ISERIES
	smp_space_timers( cpu_nr );
#endif

	printk("Waiting for %d CPUs\n", cpu_nr-1);

	for ( i = 1 ; i < cpu_nr; i++ ) {
		int c;
		struct pt_regs regs;
		
		/* create a process for the processor */
		/* we don't care about the values in regs since we'll
		   never reschedule the forked task. */
		/* We DO care about one bit in the pt_regs we
		   pass to do_fork.  That is the MSR_FP bit in
		   regs.msr.  If that bit is on, then do_fork
		   (via copy_thread) will call giveup_fpu.
		   giveup_fpu will get a pointer to our (current's)
		   last register savearea via current->thread.regs
		   and using that pointer will turn off the MSR_FP,
		   MSR_FE0 and MSR_FE1 bits.  At this point, this
		   pointer is pointing to some arbitrary point within
		   our stack */

		memset(&regs, 0, sizeof(struct pt_regs));

		if (do_fork(CLONE_VM|CLONE_PID, 0, &regs, 0) < 0)
			panic("failed fork for CPU %d", i);
		p = init_task.prev_task;
		if (!p)
			panic("No idle task for CPU %d", i);

		PPCDBG(PPCDBG_SMP,"\tProcessor %d, task = 0x%lx\n", i, p);

		del_from_runqueue(p);
		unhash_process(p);
		init_tasks[i] = p;

		p->processor = i;
		p->cpus_runnable = 1 << i; /* we schedule the first task manually */
		current_set[i].task = p;
		sp = ((unsigned long)p) + sizeof(union task_union)
			- STACK_FRAME_OVERHEAD;
		current_set[i].sp_real = (void *)__v2a(sp);

		/* wake up cpus */
		ppc_md.smp_kick_cpu(i);

		/*
		 * wait to see if the cpu made a callin (is actually up).
		 * use this value that I found through experimentation.
		 * -- Cort
		 */
		for ( c = 5000; c && !cpu_callin_map[i] ; c-- ) {
			udelay(100);
		}
		
		if ( cpu_callin_map[i] )
		{
			printk("Processor %d found.\n", i);
			PPCDBG(PPCDBG_SMP, "\tProcessor %d found.\n", i);
			/* this sync's the decr's -- Cort */
			smp_num_cpus++;
		} else {
			printk("Processor %d is stuck.\n", i);
			PPCDBG(PPCDBG_SMP, "\tProcessor %d is stuck.\n", i);
		}
	}

	/* Setup CPU 0 last (important) */
	ppc_md.smp_setup_cpu(0);
	
	if (smp_num_cpus < 2) {
	        tb_last_stamp = get_tb();
		smp_tb_synchronized = 1;
	}
}
예제 #22
0
/*
 * Bring one cpu online.
 */
int __init smp_boot_one_cpu(int cpuid, int cpunum)
{
	struct task_struct *idle;
	long timeout;

	/* 
	 * Create an idle task for this CPU.  Note the address wed* give 
	 * to kernel_thread is irrelevant -- it's going to start
	 * where OS_BOOT_RENDEVZ vector in SAL says to start.  But
	 * this gets all the other task-y sort of data structures set
	 * up like we wish.   We need to pull the just created idle task 
	 * off the run queue and stuff it into the init_tasks[] array.  
	 * Sheesh . . .
	 */

	idle = fork_by_hand();
	if (IS_ERR(idle))
		panic("SMP: fork failed for CPU:%d", cpuid);

	wake_up_forked_process(idle);
	init_idle(idle, cpunum);
	unhash_process(idle);
	idle->thread_info->cpu = cpunum;

	/* Let _start know what logical CPU we're booting
	** (offset into init_tasks[],cpu_data[])
	*/
	cpu_now_booting = cpunum;

	/* 
	** boot strap code needs to know the task address since
	** it also contains the process stack.
	*/
	smp_init_current_idle_task = idle ;
	mb();

	/*
	** This gets PDC to release the CPU from a very tight loop.
	** See MEM_RENDEZ comments in head.S.
	*/
	__raw_writel(IRQ_OFFSET(TIMER_IRQ), cpu_data[cpunum].hpa);
	mb();

	/* 
	 * OK, wait a bit for that CPU to finish staggering about. 
	 * Slave will set a bit when it reaches smp_cpu_init().
	 * Once the "monarch CPU" sees the bit change, it can move on.
	 */
	for (timeout = 0; timeout < 10000; timeout++) {
		if(cpu_online(cpunum)) {
			/* Which implies Slave has started up */
			cpu_now_booting = 0;
			smp_init_current_idle_task = NULL;
			goto alive ;
		}
		udelay(100);
		barrier();
	}

	put_task_struct(idle);
	idle = NULL;

	printk(KERN_CRIT "SMP: CPU:%d is stuck.\n", cpuid);
	return -1;

alive:
	/* Remember the Slave data */
#if (kDEBUG>=100)
	printk(KERN_DEBUG "SMP: CPU:%d (num %d) came alive after %ld _us\n",
		cpuid,  cpunum, timeout * 100);
#endif /* kDEBUG */
#ifdef ENTRY_SYS_CPUS
	cpu_data[cpunum].state = STATE_RUNNING;
#endif
	return 0;
}
예제 #23
0
파일: smp.c 프로젝트: TitaniumBoy/lin
void __init smp_boot_cpus(void)
{
	int i;

	smp_num_cpus = prom_setup_smp();
	init_new_context(current, &init_mm);
	current->processor = 0;
	atomic_set(&cpus_booted, 1);  /* Master CPU is already booted... */
	init_idle();
	for (i = 1; i < smp_num_cpus; i++) {
		struct task_struct *p;
		struct pt_regs regs;
		printk("Starting CPU %d... ", i);

		/* Spawn a new process normally.  Grab a pointer to
		   its task struct so we can mess with it */
		do_fork(CLONE_VM|CLONE_PID, 0, &regs, 0);
		p = init_task.prev_task;

		/* Schedule the first task manually */
		p->processor = i;
		p->cpus_runnable = 1 << i; /* we schedule the first task manually */

		/* Attach to the address space of init_task. */
		atomic_inc(&init_mm.mm_count);
		p->active_mm = &init_mm;
		init_tasks[i] = p;

		del_from_runqueue(p);
		unhash_process(p);

		prom_boot_secondary(i,
				    (unsigned long)p + KERNEL_STACK_SIZE - 32,
				    (unsigned long)p);

#if 0

		/* This is copied from the ip-27 code in the mips64 tree */

		struct task_struct *p;

		/*
		 * The following code is purely to make sure
		 * Linux can schedule processes on this slave.
		 */
		kernel_thread(0, NULL, CLONE_PID);
		p = init_task.prev_task;
		sprintf(p->comm, "%s%d", "Idle", i);
		init_tasks[i] = p;
		p->processor = i;
		p->cpus_runnable = 1 << i; /* we schedule the first task manually *
		del_from_runqueue(p);
		unhash_process(p);
		/* Attach to the address space of init_task. */
		atomic_inc(&init_mm.mm_count);
		p->active_mm = &init_mm;
		prom_boot_secondary(i, 
				    (unsigned long)p + KERNEL_STACK_SIZE - 32,
				    (unsigned long)p);
#endif
	}

	/* Wait for everyone to come up */
	while (atomic_read(&cpus_booted) != smp_num_cpus);
}
예제 #24
0
파일: smp.c 프로젝트: fgeraci/cs518-sched
void __init smp_boot_cpus(void)
{
	extern struct task_struct *current_set[NR_CPUS];
	int i, cpu_nr;
	struct task_struct *p;

	printk("Entering SMP Mode...\n");
	smp_num_cpus = 1;
        smp_store_cpu_info(0);
	cpu_online_map = 1UL;

	/*
	 * assume for now that the first cpu booted is
	 * cpu 0, the master -- Cort
	 */
	cpu_callin_map[0] = 1;
	current->processor = 0;

	init_idle();

	for (i = 0; i < NR_CPUS; i++) {
		prof_counter[i] = 1;
		prof_multiplier[i] = 1;
	}

	/*
	 * XXX very rough, assumes 20 bus cycles to read a cache line,
	 * timebase increments every 4 bus cycles, 32kB L1 data cache.
	 */
	cacheflush_time = 5 * 1024;

	smp_ops = ppc_md.smp_ops;
	if (smp_ops == NULL) {
		printk("SMP not supported on this machine.\n");
		return;
	}

	/* Probe arch for CPUs */
	cpu_nr = smp_ops->probe();

	/*
	 * only check for cpus we know exist.  We keep the callin map
	 * with cpus at the bottom -- Cort
	 */
	if (cpu_nr > max_cpus)
		cpu_nr = max_cpus;
	for (i = 1; i < cpu_nr; i++) {
		int c;
		struct pt_regs regs;
		
		/* create a process for the processor */
		/* we don't care about the values in regs since we'll
		   never reschedule the forked task. */
		/* We DO care about one bit in the pt_regs we
		   pass to do_fork.  That is the MSR_FP bit in 
		   regs.msr.  If that bit is on, then do_fork
		   (via copy_thread) will call giveup_fpu.
		   giveup_fpu will get a pointer to our (current's)
		   last register savearea via current->thread.regs 
		   and using that pointer will turn off the MSR_FP,
		   MSR_FE0 and MSR_FE1 bits.  At this point, this 
		   pointer is pointing to some arbitrary point within
		   our stack. */

		memset(&regs, 0, sizeof(struct pt_regs));
		
		if (do_fork(CLONE_VM|CLONE_PID, 0, &regs, 0) < 0)
			panic("failed fork for CPU %d", i);
		p = init_task.prev_task;
		if (!p)
			panic("No idle task for CPU %d", i);
		del_from_runqueue(p);
		unhash_process(p);
		init_tasks[i] = p;

		p->processor = i;
		p->cpus_runnable = 1 << i; /* we schedule the first task manually */
		current_set[i] = p;

		/*
		 * There was a cache flush loop here to flush the cache
		 * to memory for the first 8MB of RAM.  The cache flush
		 * has been pushed into the kick_cpu function for those
		 * platforms that need it.
		 */

		/* wake up cpus */
		smp_ops->kick_cpu(i);
		
		/*
		 * wait to see if the cpu made a callin (is actually up).
		 * use this value that I found through experimentation.
		 * -- Cort
		 */
		for ( c = 1000; c && !cpu_callin_map[i] ; c-- )
			udelay(100);
		
		if ( cpu_callin_map[i] )
		{
			char buf[32];
			sprintf(buf, "found cpu %d", i);
			if (ppc_md.progress) ppc_md.progress(buf, 0x350+i);
			printk("Processor %d found.\n", i);
			smp_num_cpus++;
		} else {
			char buf[32];
			sprintf(buf, "didn't find cpu %d", i);
			if (ppc_md.progress) ppc_md.progress(buf, 0x360+i);
			printk("Processor %d is stuck.\n", i);
		}
	}

	/* Setup CPU 0 last (important) */
	smp_ops->setup_cpu(0);
	
	if (smp_num_cpus < 2)
		smp_tb_synchronized = 1;
}
예제 #25
0
/*
 * Cycle through the APs sending Wakeup IPIs to boot each.
 */
void __init
smp_boot_cpus (void)
{
	int sapicid, cpu;
	int boot_cpu_id = hard_smp_processor_id();

	/*
	 * Initialize the logical to physical CPU number mapping
	 * and the per-CPU profiling counter/multiplier
	 */

	for (cpu = 0; cpu < NR_CPUS; cpu++)
		ia64_cpu_to_sapicid[cpu] = -1;
	smp_setup_percpu_timer();

	/*
	* We have the boot CPU online for sure.
	*/
	set_bit(0, &cpu_online_map);
	set_bit(0, &cpu_callin_map);

	local_cpu_data->loops_per_jiffy = loops_per_jiffy;
	ia64_cpu_to_sapicid[0] = boot_cpu_id;

	printk("Boot processor id 0x%x/0x%x\n", 0, boot_cpu_id);

	global_irq_holder = 0;
	current->processor = 0;
	init_idle();

	/*
	 * If SMP should be disabled, then really disable it!
	 */
	if (!max_cpus || (max_cpus < -1)) {
		printk(KERN_INFO "SMP mode deactivated.\n");
		cpu_online_map =  1;
		smp_num_cpus = 1;
		goto smp_done;
	}
	if  (max_cpus != -1)
		printk (KERN_INFO "Limiting CPUs to %d\n", max_cpus);

	if (smp_boot_data.cpu_count > 1) {

		printk(KERN_INFO "SMP: starting up secondaries.\n");

		for (cpu = 0; cpu < smp_boot_data.cpu_count; cpu++) {
			/*
			 * Don't even attempt to start the boot CPU!
			 */
			sapicid = smp_boot_data.cpu_phys_id[cpu];
			if ((sapicid == -1) || (sapicid == hard_smp_processor_id()))
				continue;

			if ((max_cpus > 0) && (cpucount + 1 >= max_cpus))
				break;

			do_boot_cpu(sapicid);

			/*
			 * Make sure we unmap all failed CPUs
			 */
			if (ia64_cpu_to_sapicid[cpu] == -1)
				printk("phys CPU#%d not responding - cannot use it.\n", cpu);
		}

		smp_num_cpus = cpucount + 1;

		/*
		 * Allow the user to impress friends.
		 */

		printk("Before bogomips.\n");
		if (!cpucount) {
			printk(KERN_WARNING "Warning: only one processor found.\n");
		} else {
			unsigned long bogosum = 0;
  			for (cpu = 0; cpu < NR_CPUS; cpu++)
				if (cpu_online_map & (1UL << cpu))
					bogosum += cpu_data(cpu)->loops_per_jiffy;

			printk(KERN_INFO"Total of %d processors activated (%lu.%02lu BogoMIPS).\n",
			       cpucount + 1, bogosum/(500000/HZ), (bogosum/(5000/HZ))%100);
		}
	}
  smp_done:
	;
}