예제 #1
0
int _cpufeature(int cpufeature)
{
	u32_t cpuid_feature_edx = 0;
	int proc;

	proc = getprocessor();

	/* If processor supports CPUID and its CPUID supports enough
	 * parameters, retrieve EDX feature flags to test against.
	 */
	if(proc >= 586) {
		u32_t params, a, b, c, d;
		_cpuid(0, &params, &b, &c, &d);
		if(params > 0) {
			_cpuid(1, &a, &b, &c, &cpuid_feature_edx);
		}
	}

	switch(cpufeature) {
		case _CPUF_I386_PSE:
			return cpuid_feature_edx & CPUID1_EDX_PSE;
		case _CPUF_I386_PGE:
			return cpuid_feature_edx & CPUID1_EDX_PGE;
	}

	return 0;
}
예제 #2
0
int _cpufeature(int cpufeature)
{
	u32_t eax, ebx, ecx, edx;
	int proc;

	eax = ebx = ecx = edx = 0;
	proc = getprocessor();

	/* If processor supports CPUID and its CPUID supports enough
	 * parameters, retrieve EDX feature flags to test against.
	 */
	if(proc >= 586) {
		eax = 0;
		_cpuid(&eax, &ebx, &ecx, &edx);
		if(eax > 0) {
			eax = 1;
			_cpuid(&eax, &ebx, &ecx, &edx);
		}
	}

	switch(cpufeature) {
		case _CPUF_I386_PSE:
			return edx & CPUID1_EDX_PSE;
		case _CPUF_I386_PGE:
			return edx & CPUID1_EDX_PGE;
		case _CPUF_I386_APIC_ON_CHIP:
			return edx & CPUID1_EDX_APIC_ON_CHIP;
		case _CPUF_I386_TSC:
			return edx & CPUID1_EDX_TSC;
		case _CPUF_I386_FPU:
			return edx & CPUID1_EDX_FPU;
#define SSE_FULL_EDX (CPUID1_EDX_FXSR | CPUID1_EDX_SSE | CPUID1_EDX_SSE2)
#define SSE_FULL_ECX (CPUID1_ECX_SSE3 | CPUID1_ECX_SSSE3 | \
	CPUID1_ECX_SSE4_1 | CPUID1_ECX_SSE4_2)
		case _CPUF_I386_SSE1234_12:
			return	(edx & SSE_FULL_EDX) == SSE_FULL_EDX &&
				(ecx & SSE_FULL_ECX) == SSE_FULL_ECX;
		case _CPUF_I386_FXSR:
			return edx & CPUID1_EDX_FXSR;
		case _CPUF_I386_SSE:
			return edx & CPUID1_EDX_SSE;
		case _CPUF_I386_SSE2:
			return edx & CPUID1_EDX_SSE2;
		case _CPUF_I386_SSE3:
			return ecx & CPUID1_ECX_SSE3;
		case _CPUF_I386_SSSE3:
			return ecx & CPUID1_ECX_SSSE3;
		case _CPUF_I386_SSE4_1:
			return ecx & CPUID1_ECX_SSE4_1;
		case _CPUF_I386_SSE4_2:
			return ecx & CPUID1_ECX_SSE4_2;
		case _CPUF_I386_HTT:
			return edx & CPUID1_EDX_HTT;
		case _CPUF_I386_HTT_MAX_NUM:
			return (ebx >> 16) & 0xff;
	}

	return 0;
}
예제 #3
0
파일: boot.c 프로젝트: klenovic/nucleos
void main(void)
{
	memset(&boot_params, 0, sizeof(boot_params));

	/* processor */
	processor = getprocessor();

	/* memory map */
	get_memory_map(processor);

	/* Get environment variables from the parameter sector. */
	get_parameters();

	if (boot_nucleos() < 0)
		printf("Error while booting kernel\n");

	/* @nucleos: only in case of error */
	while (1) halt_cpu();
}
/*===========================================================================*
 *		            sef_cb_init_fresh                                *
 *===========================================================================*/
static int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *UNUSED(info))
{
/* Initialize the process manager. 
 * Memory use info is collected from the boot monitor, the kernel, and
 * all processes compiled into the system image. Initially this information
 * is put into an array mem_chunks. Elements of mem_chunks are struct memory,
 * and hold base, size pairs in units of clicks. This array is small, there
 * should be no more than 8 chunks. After the array of chunks has been built
 * the contents are used to initialize the hole list. Space for the hole list
 * is reserved as an array with twice as many elements as the maximum number
 * of processes allowed. It is managed as a linked list, and elements of the
 * array are struct hole, which, in addition to storage for a base and size in 
 * click units also contain space for a link, a pointer to another element.
*/
  int s;
  static struct boot_image image[NR_BOOT_PROCS];
  register struct boot_image *ip;
  static char core_sigs[] = { SIGQUIT, SIGILL, SIGTRAP, SIGABRT,
				SIGEMT, SIGFPE, SIGBUS, SIGSEGV };
  static char ign_sigs[] = { SIGCHLD, SIGWINCH, SIGCONT };
  static char noign_sigs[] = { SIGILL, SIGTRAP, SIGEMT, SIGFPE, 
				SIGBUS, SIGSEGV };
  register struct mproc *rmp;
  register char *sig_ptr;
  message mess;

  /* Initialize process table, including timers. */
  for (rmp=&mproc[0]; rmp<&mproc[NR_PROCS]; rmp++) {
	init_timer(&rmp->mp_timer);
	rmp->mp_magic = MP_MAGIC;
  }

  /* Build the set of signals which cause core dumps, and the set of signals
   * that are by default ignored.
   */
  sigemptyset(&core_sset);
  for (sig_ptr = core_sigs; sig_ptr < core_sigs+sizeof(core_sigs); sig_ptr++)
	sigaddset(&core_sset, *sig_ptr);
  sigemptyset(&ign_sset);
  for (sig_ptr = ign_sigs; sig_ptr < ign_sigs+sizeof(ign_sigs); sig_ptr++)
	sigaddset(&ign_sset, *sig_ptr);
  sigemptyset(&noign_sset);
  for (sig_ptr = noign_sigs; sig_ptr < noign_sigs+sizeof(noign_sigs); sig_ptr++)
	sigaddset(&noign_sset, *sig_ptr);

  /* Obtain a copy of the boot monitor parameters and the kernel info struct.  
   * Parse the list of free memory chunks. This list is what the boot monitor 
   * reported, but it must be corrected for the kernel and system processes.
   */
  if ((s=sys_getmonparams(monitor_params, sizeof(monitor_params))) != OK)
      panic("get monitor params failed: %d", s);
  if ((s=sys_getkinfo(&kinfo)) != OK)
      panic("get kernel info failed: %d", s);

  /* Initialize PM's process table. Request a copy of the system image table 
   * that is defined at the kernel level to see which slots to fill in.
   */
  if (OK != (s=sys_getimage(image))) 
  	panic("couldn't get image table: %d", s);
  procs_in_use = 0;				/* start populating table */
  for (ip = &image[0]; ip < &image[NR_BOOT_PROCS]; ip++) {
  	if (ip->proc_nr >= 0) {			/* task have negative nrs */
  		procs_in_use += 1;		/* found user process */

		/* Set process details found in the image table. */
		rmp = &mproc[ip->proc_nr];	
  		strlcpy(rmp->mp_name, ip->proc_name, PROC_NAME_LEN); 
  		(void) sigemptyset(&rmp->mp_ignore);	
  		(void) sigemptyset(&rmp->mp_sigmask);
  		(void) sigemptyset(&rmp->mp_catch);
		if (ip->proc_nr == INIT_PROC_NR) {	/* user process */
  			/* INIT is root, we make it father of itself. This is
  			 * not really OK, INIT should have no father, i.e.
  			 * a father with pid NO_PID. But PM currently assumes 
  			 * that mp_parent always points to a valid slot number.
  			 */
  			rmp->mp_parent = INIT_PROC_NR;
  			rmp->mp_procgrp = rmp->mp_pid = INIT_PID;
			rmp->mp_flags |= IN_USE; 

			/* Set scheduling info */
			rmp->mp_scheduler = KERNEL;
			rmp->mp_nice = get_nice_value(USR_Q);
		}
		else {					/* system process */
  			if(ip->proc_nr == RS_PROC_NR) {
  				rmp->mp_parent = INIT_PROC_NR;
  			}
  			else {
  				rmp->mp_parent = RS_PROC_NR;
  			}
  			rmp->mp_pid = get_free_pid();
			rmp->mp_flags |= IN_USE | PRIV_PROC;

			/* RS schedules this process */
			rmp->mp_scheduler = NONE;
			rmp->mp_nice = get_nice_value(SRV_Q);
		}

		/* Get kernel endpoint identifier. */
		rmp->mp_endpoint = ip->endpoint;

		/* Tell VFS about this system process. */
		mess.m_type = PM_INIT;
		mess.PM_SLOT = ip->proc_nr;
		mess.PM_PID = rmp->mp_pid;
		mess.PM_PROC = rmp->mp_endpoint;
  		if (OK != (s=send(VFS_PROC_NR, &mess)))
			panic("can't sync up with VFS: %d", s);
  	}
  }

  /* Tell VFS that no more system processes follow and synchronize. */
  mess.PR_ENDPT = NONE;
  if (sendrec(VFS_PROC_NR, &mess) != OK || mess.m_type != OK)
	panic("can't sync up with VFS");

#if defined(__i386__)
        uts_val.machine[0] = 'i';
        strcpy(uts_val.machine + 1, itoa(getprocessor()));
#elif defined(__arm__)
        strcpy(uts_val.machine, "arm");
#endif  

 system_hz = sys_hz();

  /* Initialize user-space scheduling. */
  sched_init();

  return(OK);
}