コード例 #1
0
ファイル: start.c プロジェクト: benwei/simple_os
// copy from 30days_os/projects/09_day/harib06b/bootpack.c
u32 memtest(volatile u32 start, volatile u32 end)
{
  u32 memtest_sub(volatile u32 start, volatile u32 end);

	char flg486 = 0;
	u32 eflg, cr0, i;

	/* 386‚©A486ˆÈ~‚È‚Ì‚©‚ÌŠm”F */
	eflg = io_load_eflags();
	eflg |= EFLAGS_AC_BIT; /* AC-bit = 1 */
	io_store_eflags(eflg);
	eflg = io_load_eflags();
	if ((eflg & EFLAGS_AC_BIT) != 0) { /* 386‚Å‚ÍAC=1‚É‚µ‚Ä‚àŽ©“®‚Å0‚É–ß‚Á‚Ä‚µ‚Ü‚¤ */
		flg486 = 1;
	}
	eflg &= ~EFLAGS_AC_BIT; /* AC-bit = 0 */
	io_store_eflags(eflg);

	if (flg486 != 0) {
		cr0 = load_cr0();
		cr0 |= CR0_CACHE_DISABLE; /* ƒLƒƒƒbƒVƒ…‹ÖŽ~ */
		store_cr0(cr0);
	}

	i = memtest_sub(start, end);

	if (flg486 != 0) {
		cr0 = load_cr0();
		cr0 &= ~CR0_CACHE_DISABLE; /* ƒLƒƒƒbƒVƒ…‹–‰Â */
		store_cr0(cr0);
	}

	return i;
}
コード例 #2
0
ファイル: mem.cpp プロジェクト: koba-e964/ktest
uint memtest(uint start,uint end)
{
	char b486=0;
	uint eflg,cr0,i;


	eflg=load_eflags();
	eflg|=EFLAGS_AC_BIT;
	store_eflags(eflg);
	eflg=load_eflags();
	if((eflg&EFLAGS_AC_BIT)!=0)//on 386,even if you let ac=1,ac will automatically cleared.
		b486=1;
	eflg&=~EFLAGS_AC_BIT;
	store_eflags(eflg);
	if(b486!=0)
	{
		cr0=load_cr0();
		cr0|=CR0_CACHE_DISABLE;//CPU is prevented from caching.
		store_cr0(cr0);
	}

	//i=memtest_sub((char*)start,(char*)end);
	i=memtest_sub_iasm((char*)start,(char*)end);
	if(b486!=0)
	{
		cr0=load_cr0();
		cr0&=~CR0_CACHE_DISABLE;//CPU is allowed to cache.
		store_cr0(cr0);
	}

	return i;
}
コード例 #3
0
ファイル: mem.c プロジェクト: amaliujia/MonkOS
unsigned int memtest(unsigned int start ,unsigned int end)
{
    char flg486 = 0;
    unsigned int eflg, cr0, i;
    
    /* 判断CPU是386还是486及以后 */
    eflg = io_load_eflags();
    eflg |= EFLAGS_AC_BIT; /* AC-bit = 1 */
    io_store_eflags(eflg);
    eflg = io_load_eflags();
    if ((eflg & EFLAGS_AC_BIT) != 0) { /* 386‚AC = 0 */
        flg486 = 1;
    }
    eflg &= ~EFLAGS_AC_BIT;  //AC-bit = 0
    io_store_eflags(eflg);
    
    if (flg486 != 0) {
        cr0 = load_cr0();
        cr0 |= CR0_CACHE_DISABLE; /* forbid cache*/
        store_cr0(cr0);
    }
    
    i = memtest_sub(start, end);
    
    if (flg486 != 0) {
        cr0 = load_cr0();
        cr0 &= ~CR0_CACHE_DISABLE; /* allow cache*/
        store_cr0(cr0);
    }
    return i;
}
コード例 #4
0
/*
 * Initialize BBL_CR_CTL3 (Control register 3: used to configure the
 * L2 cache).
 */
static void
init_mendocino(void)
{
#ifdef CPU_PPRO2CELERON
	u_long	eflags;
	u_int64_t	bbl_cr_ctl3;

	eflags = read_eflags();
	disable_intr();

	load_cr0(rcr0() | CR0_CD | CR0_NW);
	wbinvd();

	bbl_cr_ctl3 = rdmsr(MSR_BBL_CR_CTL3);

	/* If the L2 cache is configured, do nothing. */
	if (!(bbl_cr_ctl3 & 1)) {
		bbl_cr_ctl3 = 0x134052bLL;

		/* Set L2 Cache Latency (Default: 5). */
#ifdef	CPU_CELERON_L2_LATENCY
#if CPU_L2_LATENCY > 15
#error invalid CPU_L2_LATENCY.
#endif
		bbl_cr_ctl3 |= CPU_L2_LATENCY << 1;
#else
		bbl_cr_ctl3 |= 5 << 1;
#endif
		wrmsr(MSR_BBL_CR_CTL3, bbl_cr_ctl3);
	}

	load_cr0(rcr0() & ~(CR0_CD | CR0_NW));
	write_eflags(eflags);
#endif /* CPU_PPRO2CELERON */
}
コード例 #5
0
/*
 * Initialize BBL_CR_CTL3 (Control register 3: used to configure the
 * L2 cache).
 */
static void
init_mendocino(void)
{
#ifdef CPU_PPRO2CELERON
	register_t	saveintr;
	u_int64_t	bbl_cr_ctl3;

	saveintr = intr_disable();

	load_cr0(rcr0() | CR0_CD | CR0_NW);
	wbinvd();

	bbl_cr_ctl3 = rdmsr(MSR_BBL_CR_CTL3);

	/* If the L2 cache is configured, do nothing. */
	if (!(bbl_cr_ctl3 & 1)) {
		bbl_cr_ctl3 = 0x134052bLL;

		/* Set L2 Cache Latency (Default: 5). */
#ifdef	CPU_CELERON_L2_LATENCY
#if CPU_L2_LATENCY > 15
#error invalid CPU_L2_LATENCY.
#endif
		bbl_cr_ctl3 |= CPU_L2_LATENCY << 1;
#else
		bbl_cr_ctl3 |= 5 << 1;
#endif
		wrmsr(MSR_BBL_CR_CTL3, bbl_cr_ctl3);
	}

	load_cr0(rcr0() & ~(CR0_CD | CR0_NW));
	intr_restore(saveintr);
#endif /* CPU_PPRO2CELERON */
}
コード例 #6
0
ファイル: memory.c プロジェクト: zwy1135/myos
unsigned int memtest(unsigned int start,unsigned int end)
{
	char flag486 = 0;
	unsigned int eflag,cr0,i;
	//确认是386还是486
	eflag = io_load_eflags();
	eflag |= EFLAGS_AC_BIT;				//设定AC_BIT = 1,386设完后会自动归零
	io_store_eflags(eflag);
	eflag = io_load_eflags();
	if((eflag & EFLAGS_AC_BIT) != 0)	//判断AC_BIT是否为1
	{
		flag486 = 1;
	}
	eflag &= ~EFLAGS_AC_BIT;			//AC_BIT = 0
	io_store_eflags(eflag);
	
	if(flag486 != 0)
	{
		cr0 = load_cr0();
		cr0 |= CR0_CACHE_DISABLE;		//禁止缓存
		store_cr0(cr0);
	}
	
	i = memtest_sub(start,end);
	
	if(flag486 != 0)
	{
		cr0 = load_cr0();
		cr0 &= ~CR0_CACHE_DISABLE;		//启用缓存
		store_cr0(cr0);
	}
	return i;
}
コード例 #7
0
ファイル: bootpack.c プロジェクト: siutin/self_os
unsigned int memtest(unsigned int start, unsigned int end)
{
	char flg486=0;
	unsigned int eflg,cr0,i;
	//确认CPU是386还是486以上的
	eflg=io_load_eflags();
	eflg|=EFLAGS_AC_BIT;
	io_store_eflags(eflg);
	eflg=io_load_eflags();
	if((eflg&EFLAGS_AC_BIT)!=0){//如果是386,即使设定AC=1,AC的值还会自动回到0
		flg486=1;
	}
	eflg&=~EFLAGS_AC_BIT;
	io_store_eflags(eflg);
	
	if(flg486!=0){
		cr0=load_cr0();
		cr0|=CR0_CACHE_DISABLE;//禁止缓存
		store_cr0(cr0);
	}
	
	i=memtest_sub(start,end);
	
	if(flg486!=0){
		cr0=load_cr0();
		cr0&=~CR0_CACHE_DISABLE;//禁止缓存
		store_cr0(cr0);
	}
	
	return i;
}
コード例 #8
0
ファイル: bootpack.c プロジェクト: FuDesign2008/mess
unsigned int memtest(unsigned int start, unsigned int end)
{
	char flg486 = 0;
	unsigned int eflg, cr0, i;

	/* 386か、486以降なのかの確認 */
	eflg = io_load_eflags();
	eflg |= EFLAGS_AC_BIT; /* AC-bit = 1 */
	io_store_eflags(eflg);
	eflg = io_load_eflags();
	if ((eflg & EFLAGS_AC_BIT) != 0) { /* 386ではAC=1にしても自動で0に戻ってしまう */
		flg486 = 1;
	}
	eflg &= ~EFLAGS_AC_BIT; /* AC-bit = 0 */
	io_store_eflags(eflg);

	if (flg486 != 0) {
		cr0 = load_cr0();
		cr0 |= CR0_CACHE_DISABLE; /* キャッシュ禁止 */
		store_cr0(cr0);
	}

	i = memtest_sub(start, end);

	if (flg486 != 0) {
		cr0 = load_cr0();
		cr0 &= ~CR0_CACHE_DISABLE; /* キャッシュ許可 */
		store_cr0(cr0);
	}

	return i;
}
コード例 #9
0
ファイル: memory.c プロジェクト: freebz/os
unsigned int memtest(unsigned int start, unsigned int end)
{
  char flg486 = 0;
  unsigned int eflg, cr0, i;

  /* 386인가, 486 이후인가의 확인 */
  eflg = io_load_eflags();
  eflg |= EFLAGS_AC_BIT;	/* AC-bit = 1 */
  io_store_eflags(eflg);
  eflg = io_load_eflags();
  if ((eflg & EFLAGS_AC_BIT) != 0) {
    /* 386에서는 AC=1로 해도 자동으로 0이 되어 버린다. */
    flg486 = 1;
  }
  eflg &= ~EFLAGS_AC_BIT;	/* AC-bit = 0 */
  io_store_eflags(eflg);

  if (flg486 != 0) {
    cr0 = load_cr0();
    cr0 |= CR0_CACHE_DISABLE;	/* 캐시 금지 */
    store_cr0(cr0);
  }

  i = memtest_sub(start, end);

  if (flg486 != 0) {
    cr0 = load_cr0();
    cr0 &= ~ CR0_CACHE_DISABLE;	/* 캐시 허가 */
    store_cr0(cr0);
  }

  return i;
}
コード例 #10
0
ファイル: bootpack.c プロジェクト: SeanHAu/OSASK
unsigned int memtest(unsigned int start, unsigned int end)
{
	char flg486 = 0;
	unsigned int eflg, cr0, i;

	/* 确认CPU是386还是486以上的 */
	eflg = io_load_eflags();
	eflg |= EFLAGS_AC_BIT; /* AC-bit = 1 */
	io_store_eflags(eflg);
	eflg = io_load_eflags();
	if ((eflg & EFLAGS_AC_BIT) != 0) { /* 如果是386,即使设定AC=1,AC还是会回到0 */
		flg486 = 1;
	}
	eflg &= ~EFLAGS_AC_BIT; /* AC-bit = 0 */
	io_store_eflags(eflg);

	if (flg486 != 0) {
		cr0 = load_cr0();
		cr0 |= CR0_CACHE_DISABLE; /* 禁止缓存 */
		store_cr0(cr0);
	}

	i = memtest_sub(start, end);

	if (flg486 != 0) {
		cr0 = load_cr0();
		cr0 &= ~CR0_CACHE_DISABLE; /* 允许缓存 */
		store_cr0(cr0);
	}

	return i;
}
コード例 #11
0
ファイル: memman.c プロジェクト: zy-sunshine/hackos01
unsigned int memtest(unsigned int start, unsigned int end)
{
    char flg486 = 0;
    unsigned int eflg, cr0, i;
    
    eflg = io_load_eflags();
    eflg |= EFLAGS_AC_BIT; /* AC-bit = 1 */
    io_store_eflags(eflg);
    eflg = io_load_eflags();
    if((eflg & EFLAGS_AC_BIT) != 0) {
        flg486 = 1;
    }
    eflg &= ~EFLAGS_AC_BIT;
    io_store_eflags(eflg);
    
    if(flg486 != 0){
        // disable cache
        cr0 = load_cr0();
        cr0 |= CR0_CACHE_DISABLE;
        store_cr0(cr0);
    }
    i = memtest_sub(start, end);
    if (flg486 != 0) {
        // enable cache
        cr0 = load_cr0();
        cr0 &= ~CR0_CACHE_DISABLE;
        store_cr0(cr0);
    }
    return i;
}
コード例 #12
0
/*
 * IBM Blue Lightning
 */
static void
init_bluelightning(void)
{
	u_long	eflags;

#if defined(PC98) && !defined(CPU_UPGRADE_HW_CACHE)
	need_post_dma_flush = 1;
#endif

	eflags = read_eflags();
	disable_intr();

	load_cr0(rcr0() | CR0_CD | CR0_NW);
	invd();

#ifdef CPU_BLUELIGHTNING_FPU_OP_CACHE
	wrmsr(0x1000, 0x9c92LL);	/* FP operand can be cacheable on Cyrix FPU */
#else
	wrmsr(0x1000, 0x1c92LL);	/* Intel FPU */
#endif
	/* Enables 13MB and 0-640KB cache. */
	wrmsr(0x1001, (0xd0LL << 32) | 0x3ff);
#ifdef CPU_BLUELIGHTNING_3X
	wrmsr(0x1002, 0x04000000LL);	/* Enables triple-clock mode. */
#else
	wrmsr(0x1002, 0x03000000LL);	/* Enables double-clock mode. */
#endif

	/* Enable caching in CR0. */
	load_cr0(rcr0() & ~(CR0_CD | CR0_NW));	/* CD = 0 and NW = 0 */
	invd();
	write_eflags(eflags);
}
コード例 #13
0
/*
 * Cyrix 6x86MX (code-named M2)
 *
 * XXX - What should I do here?  Please let me know.
 */
static void
init_6x86MX(void)
{
	u_long	eflags;
	u_char	ccr3, ccr4;

	eflags = read_eflags();
	disable_intr();

	load_cr0(rcr0() | CR0_CD | CR0_NW);
	wbinvd();

	/* Initialize CCR0. */
	write_cyrix_reg(CCR0, read_cyrix_reg(CCR0) | CCR0_NC1);

	/* Initialize CCR1. */
#ifdef CPU_CYRIX_NO_LOCK
	write_cyrix_reg(CCR1, read_cyrix_reg(CCR1) | CCR1_NO_LOCK);
#else
	write_cyrix_reg(CCR1, read_cyrix_reg(CCR1) & ~CCR1_NO_LOCK);
#endif

	/* Initialize CCR2. */
#ifdef CPU_SUSP_HLT
	write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) | CCR2_SUSP_HLT);
#else
	write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) & ~CCR2_SUSP_HLT);
#endif

	ccr3 = read_cyrix_reg(CCR3);
	write_cyrix_reg(CCR3, CCR3_MAPEN0);

	/* Initialize CCR4. */
	ccr4 = read_cyrix_reg(CCR4);
	ccr4 &= ~CCR4_IOMASK;
#ifdef CPU_IORT
	write_cyrix_reg(CCR4, ccr4 | (CPU_IORT & CCR4_IOMASK));
#else
	write_cyrix_reg(CCR4, ccr4 | 7);
#endif

	/* Initialize CCR5. */
#ifdef CPU_WT_ALLOC
	write_cyrix_reg(CCR5, read_cyrix_reg(CCR5) | CCR5_WT_ALLOC);
#endif

	/* Restore CCR3. */
	write_cyrix_reg(CCR3, ccr3);

	/* Unlock NW bit in CR0. */
	write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) & ~CCR2_LOCK_NW);

	load_cr0(rcr0() & ~(CR0_CD | CR0_NW));	/* CD = 0 and NW = 0 */

	/* Lock NW bit in CR0. */
	write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) | CCR2_LOCK_NW);

	write_eflags(eflags);
}
コード例 #14
0
/*
 * Cyrix 486S/DX series
 */
static void
init_cy486dx(void)
{
	u_long	eflags;
	u_char	ccr2;

	eflags = read_eflags();
	disable_intr();
	invd();

	ccr2 = read_cyrix_reg(CCR2);
#ifdef CPU_SUSP_HLT
	ccr2 |= CCR2_SUSP_HLT;
#endif

#ifdef PC98
	/* Enables WB cache interface pin and Lock NW bit in CR0. */
	ccr2 |= CCR2_WB | CCR2_LOCK_NW;
	/* Unlock NW bit in CR0. */
	write_cyrix_reg(CCR2, ccr2 & ~CCR2_LOCK_NW);
	load_cr0((rcr0() & ~CR0_CD) | CR0_NW);	/* CD = 0, NW = 1 */
#endif

	write_cyrix_reg(CCR2, ccr2);
	write_eflags(eflags);
}
コード例 #15
0
/*
 * Cyrix 486S/DX series
 */
static void
init_cy486dx(void)
{
	register_t saveintr;
	u_char	ccr2;

	saveintr = intr_disable();
	invd();

	ccr2 = read_cyrix_reg(CCR2);
#ifdef CPU_SUSP_HLT
	ccr2 |= CCR2_SUSP_HLT;
#endif

#ifdef PC98
	/* Enables WB cache interface pin and Lock NW bit in CR0. */
	ccr2 |= CCR2_WB | CCR2_LOCK_NW;
	/* Unlock NW bit in CR0. */
	write_cyrix_reg(CCR2, ccr2 & ~CCR2_LOCK_NW);
	load_cr0((rcr0() & ~CR0_CD) | CR0_NW);	/* CD = 0, NW = 1 */
#endif

	write_cyrix_reg(CCR2, ccr2);
	intr_restore(saveintr);
}
コード例 #16
0
ファイル: mp_machdep.c プロジェクト: AhmadTux/DragonFlyBSD
/*
 * AP cpu's call this to sync up protected mode.
 *
 * WARNING!  We must ensure that the cpu is sufficiently initialized to
 * be able to use to the FP for our optimized bzero/bcopy code before
 * we enter more mainstream C code.
 *
 * WARNING! %fs is not set up on entry.  This routine sets up %fs.
 */
void
init_secondary(void)
{
	int	gsel_tss;
	int	x, myid = bootAP;
	u_int	cr0;
	struct mdglobaldata *md;
	struct privatespace *ps;

	ps = &CPU_prvspace[myid];

	gdt_segs[GPRIV_SEL].ssd_base = (int)ps;
	gdt_segs[GPROC0_SEL].ssd_base =
		(int) &ps->mdglobaldata.gd_common_tss;
	ps->mdglobaldata.mi.gd_prvspace = ps;

	for (x = 0; x < NGDT; x++) {
		ssdtosd(&gdt_segs[x], &gdt[myid * NGDT + x].sd);
	}

	r_gdt.rd_limit = NGDT * sizeof(gdt[0]) - 1;
	r_gdt.rd_base = (int) &gdt[myid * NGDT];
	lgdt(&r_gdt);			/* does magic intra-segment return */

	lidt(&r_idt);

	lldt(_default_ldt);
	mdcpu->gd_currentldt = _default_ldt;

	gsel_tss = GSEL(GPROC0_SEL, SEL_KPL);
	gdt[myid * NGDT + GPROC0_SEL].sd.sd_type = SDT_SYS386TSS;

	md = mdcpu;	/* loaded through %fs:0 (mdglobaldata.mi.gd_prvspace)*/

	md->gd_common_tss.tss_esp0 = 0;	/* not used until after switch */
	md->gd_common_tss.tss_ss0 = GSEL(GDATA_SEL, SEL_KPL);
	md->gd_common_tss.tss_ioopt = (sizeof md->gd_common_tss) << 16;
	md->gd_tss_gdt = &gdt[myid * NGDT + GPROC0_SEL].sd;
	md->gd_common_tssd = *md->gd_tss_gdt;
	ltr(gsel_tss);

	/*
	 * Set to a known state:
	 * Set by mpboot.s: CR0_PG, CR0_PE
	 * Set by cpu_setregs: CR0_NE, CR0_MP, CR0_TS, CR0_WP, CR0_AM
	 */
	cr0 = rcr0();
	cr0 &= ~(CR0_CD | CR0_NW | CR0_EM);
	load_cr0(cr0);
	pmap_set_opt();		/* PSE/4MB pages, etc */

	/* set up CPU registers and state */
	cpu_setregs();

	/* set up FPU state on the AP */
	npxinit(__INITIAL_NPXCW__);

	/* set up SSE registers */
	enable_sse();
}
コード例 #17
0
ファイル: intrpt.c プロジェクト: hikalium/chnos
void cpu_exception_abort(int exception, int *esp)
{
	int i;
	char s[32];

//	putfonts32_asc(system.data.info.vesa.PhysBasePtr, system.data.info.boot.scrnx, 0, 0, 0xFFFFFF, (const uchar *)cpu_exceptions[exception]);
//	putfonts32_asc(system.data.info.vesa.PhysBasePtr, system.data.info.boot.scrnx, 0, 16, 0xFFFFFF, "***registers info***");

	sprintf(s, "%s\n\r", (uchar *)cpu_exceptions[exception]);
	send_serial(s);

//	putfonts32_asc(system.data.info.vesa.PhysBasePtr, system.data.info.boot.scrnx, 0, 32, 0xFFFFFF, "#PUSHAD by _asm_inthandler");

	send_serial("#PUSHAD by _asm_inthandler\n\r");

	for(i = 0; i <= 7; i++){
//		sprintf(s, "%s:0x%08X", cpu_exception_infos[i], esp[i]);
//		putfonts32_asc(system.data.info.vesa.PhysBasePtr, system.data.info.boot.scrnx, 0, 16 * (i + 3), 0xFFFFFF, s);

		sprintf(s, "%s:0x%08X\n\r", cpu_exception_infos[i], esp[i]);
		send_serial(s);
	}

//	putfonts32_asc(system.data.info.vesa.PhysBasePtr, system.data.info.boot.scrnx, 0, 176, 0xFFFFFF, "#PUSH by _asm_inthandler");
	send_serial("#PUSH by _asm_inthandler\n\r");

	for(i = 8; i <= 9; i++){
//		sprintf(s, "%s:0x%08X", cpu_exception_infos[i], esp[i]);
//		putfonts32_asc(system.data.info.vesa.PhysBasePtr, system.data.info.boot.scrnx, 0, 16 * (i + 4), 0xFFFFFF, s);

		sprintf(s, "%s:0x%08X\n\r", cpu_exception_infos[i], esp[i]);
		send_serial(s);
	}

//	putfonts32_asc(system.data.info.vesa.PhysBasePtr, system.data.info.boot.scrnx, 0, 224, 0xFFFFFF, "#PUSH by CPU");

	send_serial("#PUSH by CPU\n\r");
	for(i = 10; i <= 15; i++){
//		sprintf(s, "%s:0x%08X", cpu_exception_infos[i], esp[i]);
//		putfonts32_asc(system.data.info.vesa.PhysBasePtr, system.data.info.boot.scrnx, 0, 16 * (i + 5), 0xFFFFFF, s);

		sprintf(s, "%s:0x%08X\n\r", cpu_exception_infos[i], esp[i]);
		send_serial(s);
	}

	send_serial("#Control Registers\n\r");
	sprintf(s, "CR0 = 0x%08X\n\r", load_cr0());
	send_serial(s);
	sprintf(s, "CR2 = 0x%08X\n\r", load_cr2());
	send_serial(s);
	sprintf(s, "CR3 = 0x%08X\n\r", load_cr3());
	send_serial(s);

	for(;;){
		io_hlt();
	}
}
コード例 #18
0
ファイル: bootpack.c プロジェクト: flamearrow/30dayos
/*
	memtest is used to calculate available memory, basicly it does the following:
	we first need to check if a memory unit (a byte) is valid. It's valid if 
		1) we read the value from the memroy unit
		2) we change the value to value' and write back to memroy unit
		3) we read the value from memory again, if it's value', then the memory is valid 
	Now we move to the next memory unit to check if it's valid, we keep increasing the pointer until the check fails
	then the pointer will point to the LAST availe memory, which is the size of memory available

*/
unsigned int memtest(unsigned int start, unsigned int end)
{	
	char flg486 = 0;
	unsigned int eflg, cr0, i;
	/* 
		to do the write read check, we need to disable cache, 
		because with cache in place writing to a memory might be cached 
			and reading from the same address unit might return differernt value
		Note only 486+ CPU has cache, therefore we need first check if it's 486 or lower
		if it's lower then we don't need to disable cache
	*/
	eflg = io_load_eflags();
	/* only 486+ has AC bit, that said in 386 and lower, even if we set AC to 1, it will be cleared */
	eflg |= EFLAGS_AC_BIT; 
	io_store_eflags(eflg);
	eflg = io_load_eflags();
	if((eflg & EFLAGS_AC_BIT) != 0) {
		/* if AC is NOT cleared, then it's 486 and we need to disable cache */
		flg486 = 1;
	}
	eflg &= ~EFLAGS_AC_BIT;
	io_store_eflags(eflg);

	/* disable cache by setting a bit in CR0 register */
	if(flg486) {
		cr0 = load_cr0();
		cr0 |= CR0_CACHE_DISABLE;
		store_cr0(cr0);
	}

	i = memtest_sub(start, end);

	/* re-enable cache */
	if(flg486) {
		cr0 = load_cr0();
		cr0 &= ~CR0_CACHE_DISABLE;
		store_cr0(cr0);
	}

	return i;
}
コード例 #19
0
ファイル: initcpu.c プロジェクト: madhavsuresh/DragonFlyBSD
/*
 * There are i486 based upgrade products for i386 machines.
 * In this case, BIOS doesn't enables CPU cache.
 */
void
init_i486_on_386(void)
{
	u_long	eflags;

	eflags = read_eflags();
	cpu_disable_intr();

	load_cr0(rcr0() & ~(CR0_CD | CR0_NW));	/* CD = 0, NW = 0 */

	write_eflags(eflags);
}
コード例 #20
0
void
cpu_setregs(void)
{
#if 0
    unsigned int cr0;

    cr0 = rcr0();
    cr0 |= CR0_NE;			/* Done by npxinit() */
    cr0 |= CR0_MP | CR0_TS;		/* Done at every execve() too. */
    cr0 |= CR0_WP | CR0_AM;
    load_cr0(cr0);
    load_gs(_udatasel);
#endif
}
コード例 #21
0
ファイル: memory.c プロジェクト: red13/chos
unsigned int memtest( unsigned int start, unsigned int end )
{
    char flg486 = 0;
    unsigned int eflg;
    unsigned int cr0;
    unsigned int i;

    /* 386か,486以降なのかを確認する */
    eflg = io_load_eflags();
    eflg |= EFLAGS_AC_BIT;
    io_store_eflags( eflg );
    eflg = io_load_eflags();
    if( ( eflg & EFLAGS_AC_BIT ) != 0 )
    {
        flg486 = 1;
    }
    eflg &= ~EFLAGS_AC_BIT;
    io_store_eflags( eflg );

    if( flg486 != 0 )
    {
        cr0 = load_cr0();
        cr0 |= CR0_CACHE_DISABLE;
        store_cr0( cr0 );
    }

    i = memtest_sub( start, end );

    if( flg486 != 0 )
    {
        cr0 = load_cr0();
        cr0 &= ~CR0_CACHE_DISABLE;
        store_cr0( cr0 );
    }

    return i;
}
コード例 #22
0
/*
 * There are i486 based upgrade products for i386 machines.
 * In this case, BIOS doesn't enable CPU cache.
 */
static void
init_i486_on_386(void)
{
	register_t saveintr;

#if defined(PC98) && !defined(CPU_UPGRADE_HW_CACHE)
	need_post_dma_flush = 1;
#endif

	saveintr = intr_disable();

	load_cr0(rcr0() & ~(CR0_CD | CR0_NW));	/* CD = 0, NW = 0 */

	intr_restore(saveintr);
}
コード例 #23
0
/*
 * There are i486 based upgrade products for i386 machines.
 * In this case, BIOS doesn't enables CPU cache.
 */
static void
init_i486_on_386(void)
{
	u_long	eflags;

#if defined(PC98) && !defined(CPU_UPGRADE_HW_CACHE)
	need_post_dma_flush = 1;
#endif

	eflags = read_eflags();
	disable_intr();

	load_cr0(rcr0() & ~(CR0_CD | CR0_NW));	/* CD = 0, NW = 0 */

	write_eflags(eflags);
}
コード例 #24
0
/*
 * Cyrix 486SLC/DLC/SR/DR series
 */
static void
init_486dlc(void)
{
	u_long	eflags;
	u_char	ccr0;

	eflags = read_eflags();
	disable_intr();
	invd();

	ccr0 = read_cyrix_reg(CCR0);
#ifndef CYRIX_CACHE_WORKS
	ccr0 |= CCR0_NC1 | CCR0_BARB;
	write_cyrix_reg(CCR0, ccr0);
	invd();
#else
	ccr0 &= ~CCR0_NC0;
#ifndef CYRIX_CACHE_REALLY_WORKS
	ccr0 |= CCR0_NC1 | CCR0_BARB;
#else
	ccr0 |= CCR0_NC1;
#endif
#ifdef CPU_DIRECT_MAPPED_CACHE
	ccr0 |= CCR0_CO;			/* Direct mapped mode. */
#endif
	write_cyrix_reg(CCR0, ccr0);

	/* Clear non-cacheable region. */
	write_cyrix_reg(NCR1+2, NCR_SIZE_0K);
	write_cyrix_reg(NCR2+2, NCR_SIZE_0K);
	write_cyrix_reg(NCR3+2, NCR_SIZE_0K);
	write_cyrix_reg(NCR4+2, NCR_SIZE_0K);

	write_cyrix_reg(0, 0);	/* dummy write */

	/* Enable caching in CR0. */
	load_cr0(rcr0() & ~(CR0_CD | CR0_NW));	/* CD = 0 and NW = 0 */
	invd();
#endif /* !CYRIX_CACHE_WORKS */
	write_eflags(eflags);
}
コード例 #25
0
/*
 * Clear registers on exec
 */
void
exec_setregs(u_long entry, u_long stack, u_long ps_strings)
{
    struct thread *td = curthread;
    struct lwp *lp = td->td_lwp;
    struct trapframe *regs = lp->lwp_md.md_regs;
    struct pcb *pcb = lp->lwp_thread->td_pcb;

    /* was i386_user_cleanup() in NetBSD */
    user_ldt_free(pcb);

    bzero((char *)regs, sizeof(struct trapframe));
    regs->tf_eip = entry;
    regs->tf_esp = stack;
    regs->tf_eflags = PSL_USER | (regs->tf_eflags & PSL_T);
    regs->tf_ss = 0;
    regs->tf_ds = 0;
    regs->tf_es = 0;
    regs->tf_fs = 0;
    regs->tf_gs = 0;
    regs->tf_cs = 0;

    /* PS_STRINGS value for BSD/OS binaries.  It is 0 for non-BSD/OS. */
    regs->tf_ebx = ps_strings;

    /*
     * Reset the hardware debug registers if they were in use.
     * They won't have any meaning for the newly exec'd process.
     */
    if (pcb->pcb_flags & PCB_DBREGS) {
        pcb->pcb_dr0 = 0;
        pcb->pcb_dr1 = 0;
        pcb->pcb_dr2 = 0;
        pcb->pcb_dr3 = 0;
        pcb->pcb_dr6 = 0;
        pcb->pcb_dr7 = 0;
        if (pcb == td->td_pcb) {
            /*
            * Clear the debug registers on the running
             * CPU, otherwise they will end up affecting
             * the next process we switch to.
             */
            reset_dbregs();
        }
        pcb->pcb_flags &= ~PCB_DBREGS;
    }

    /*
     * Initialize the math emulator (if any) for the current process.
     * Actually, just clear the bit that says that the emulator has
     * been initialized.  Initialization is delayed until the process
     * traps to the emulator (if it is done at all) mainly because
     * emulators don't provide an entry point for initialization.
     */
    pcb->pcb_flags &= ~FP_SOFTFP;

    /*
     * note: do not set CR0_TS here.  npxinit() must do it after clearing
     * gd_npxthread.  Otherwise a preemptive interrupt thread may panic
     * in npxdna().
     */
    crit_enter();
#if 0
    load_cr0(rcr0() | CR0_MP);
#endif

#if NNPX > 0
    /* Initialize the npx (if any) for the current process. */
    npxinit();
#endif
    crit_exit();

    /*
     * note: linux emulator needs edx to be 0x0 on entry, which is
     * handled in execve simply by setting the 64 bit syscall
     * return value to 0.
     */
}
コード例 #26
0
/*
 * AP cpu's call this to sync up protected mode.
 *
 * WARNING! %gs is not set up on entry.  This routine sets up %gs.
 */
void
init_secondary(void)
{
	int	gsel_tss;
	int	x, myid = bootAP;
	u_int64_t msr, cr0;
	struct mdglobaldata *md;
	struct privatespace *ps;

	ps = &CPU_prvspace[myid];

	gdt_segs[GPROC0_SEL].ssd_base =
		(long) &ps->mdglobaldata.gd_common_tss;
	ps->mdglobaldata.mi.gd_prvspace = ps;

	/* We fill the 32-bit segment descriptors */
	for (x = 0; x < NGDT; x++) {
		if (x != GPROC0_SEL && x != (GPROC0_SEL + 1))
			ssdtosd(&gdt_segs[x], &gdt[myid * NGDT + x]);
	}
	/* And now a 64-bit one */
	ssdtosyssd(&gdt_segs[GPROC0_SEL],
	    (struct system_segment_descriptor *)&gdt[myid * NGDT + GPROC0_SEL]);

	r_gdt.rd_limit = NGDT * sizeof(gdt[0]) - 1;
	r_gdt.rd_base = (long) &gdt[myid * NGDT];
	lgdt(&r_gdt);			/* does magic intra-segment return */

	/* lgdt() destroys the GSBASE value, so we load GSBASE after lgdt() */
	wrmsr(MSR_FSBASE, 0);		/* User value */
	wrmsr(MSR_GSBASE, (u_int64_t)ps);
	wrmsr(MSR_KGSBASE, 0);		/* XXX User value while we're in the kernel */

	lidt(&r_idt_arr[mdcpu->mi.gd_cpuid]);

#if 0
	lldt(_default_ldt);
	mdcpu->gd_currentldt = _default_ldt;
#endif

	gsel_tss = GSEL(GPROC0_SEL, SEL_KPL);
	gdt[myid * NGDT + GPROC0_SEL].sd_type = SDT_SYSTSS;

	md = mdcpu;	/* loaded through %gs:0 (mdglobaldata.mi.gd_prvspace)*/

	md->gd_common_tss.tss_rsp0 = 0;	/* not used until after switch */
#if 0 /* JG XXX */
	md->gd_common_tss.tss_ioopt = (sizeof md->gd_common_tss) << 16;
#endif
	md->gd_tss_gdt = &gdt[myid * NGDT + GPROC0_SEL];
	md->gd_common_tssd = *md->gd_tss_gdt;

	/* double fault stack */
	md->gd_common_tss.tss_ist1 =
		(long)&md->mi.gd_prvspace->idlestack[
			sizeof(md->mi.gd_prvspace->idlestack)];

	ltr(gsel_tss);

	/*
	 * Set to a known state:
	 * Set by mpboot.s: CR0_PG, CR0_PE
	 * Set by cpu_setregs: CR0_NE, CR0_MP, CR0_TS, CR0_WP, CR0_AM
	 */
	cr0 = rcr0();
	cr0 &= ~(CR0_CD | CR0_NW | CR0_EM);
	load_cr0(cr0);

	/* Set up the fast syscall stuff */
	msr = rdmsr(MSR_EFER) | EFER_SCE;
	wrmsr(MSR_EFER, msr);
	wrmsr(MSR_LSTAR, (u_int64_t)IDTVEC(fast_syscall));
	wrmsr(MSR_CSTAR, (u_int64_t)IDTVEC(fast_syscall32));
	msr = ((u_int64_t)GSEL(GCODE_SEL, SEL_KPL) << 32) |
	      ((u_int64_t)GSEL(GUCODE32_SEL, SEL_UPL) << 48);
	wrmsr(MSR_STAR, msr);
	wrmsr(MSR_SF_MASK, PSL_NT|PSL_T|PSL_I|PSL_C|PSL_D|PSL_IOPL);

	pmap_set_opt();		/* PSE/4MB pages, etc */
	pmap_init_pat();	/* Page Attribute Table */

	/* set up CPU registers and state */
	cpu_setregs();

	/* set up SSE/NX registers */
	initializecpu(myid);

	/* set up FPU state on the AP */
	npxinit(__INITIAL_FPUCW__);

	/* disable the APIC, just to be SURE */
	lapic->svr &= ~APIC_SVR_ENABLE;
}
コード例 #27
0
/*
 * Cyrix 5x86
 */
static void
init_5x86(void)
{
	u_long	eflags;
	u_char	ccr2, ccr3, ccr4, pcr0;

	eflags = read_eflags();
	disable_intr();

	load_cr0(rcr0() | CR0_CD | CR0_NW);
	wbinvd();

	(void)read_cyrix_reg(CCR3);		/* dummy */

	/* Initialize CCR2. */
	ccr2 = read_cyrix_reg(CCR2);
	ccr2 |= CCR2_WB;
#ifdef CPU_SUSP_HLT
	ccr2 |= CCR2_SUSP_HLT;
#else
	ccr2 &= ~CCR2_SUSP_HLT;
#endif
	ccr2 |= CCR2_WT1;
	write_cyrix_reg(CCR2, ccr2);

	/* Initialize CCR4. */
	ccr3 = read_cyrix_reg(CCR3);
	write_cyrix_reg(CCR3, CCR3_MAPEN0);

	ccr4 = read_cyrix_reg(CCR4);
	ccr4 |= CCR4_DTE;
	ccr4 |= CCR4_MEM;
#ifdef CPU_FASTER_5X86_FPU
	ccr4 |= CCR4_FASTFPE;
#else
	ccr4 &= ~CCR4_FASTFPE;
#endif
	ccr4 &= ~CCR4_IOMASK;
	/********************************************************************
	 * WARNING: The "BIOS Writers Guide" mentions that I/O recovery time
	 * should be 0 for errata fix.
	 ********************************************************************/
#ifdef CPU_IORT
	ccr4 |= CPU_IORT & CCR4_IOMASK;
#endif
	write_cyrix_reg(CCR4, ccr4);

	/* Initialize PCR0. */
	/****************************************************************
	 * WARNING: RSTK_EN and LOOP_EN could make your system unstable.
	 * BTB_EN might make your system unstable.
	 ****************************************************************/
	pcr0 = read_cyrix_reg(PCR0);
#ifdef CPU_RSTK_EN
	pcr0 |= PCR0_RSTK;
#else
	pcr0 &= ~PCR0_RSTK;
#endif
#ifdef CPU_BTB_EN
	pcr0 |= PCR0_BTB;
#else
	pcr0 &= ~PCR0_BTB;
#endif
#ifdef CPU_LOOP_EN
	pcr0 |= PCR0_LOOP;
#else
	pcr0 &= ~PCR0_LOOP;
#endif

	/****************************************************************
	 * WARNING: if you use a memory mapped I/O device, don't use
	 * DISABLE_5X86_LSSER option, which may reorder memory mapped
	 * I/O access.
	 * IF YOUR MOTHERBOARD HAS PCI BUS, DON'T DISABLE LSSER.
	 ****************************************************************/
#ifdef CPU_DISABLE_5X86_LSSER
	pcr0 &= ~PCR0_LSSER;
#else
	pcr0 |= PCR0_LSSER;
#endif
	write_cyrix_reg(PCR0, pcr0);

	/* Restore CCR3. */
	write_cyrix_reg(CCR3, ccr3);

	(void)read_cyrix_reg(0x80);		/* dummy */

	/* Unlock NW bit in CR0. */
	write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) & ~CCR2_LOCK_NW);
	load_cr0((rcr0() & ~CR0_CD) | CR0_NW);	/* CD = 0, NW = 1 */
	/* Lock NW bit in CR0. */
	write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) | CCR2_LOCK_NW);

	write_eflags(eflags);
}
コード例 #28
0
/*
 * Cyrix 6x86
 *
 * XXX - What should I do here?  Please let me know.
 */
static void
init_6x86(void)
{
	u_long	eflags;
	u_char	ccr3, ccr4;

	eflags = read_eflags();
	disable_intr();

	load_cr0(rcr0() | CR0_CD | CR0_NW);
	wbinvd();

	/* Initialize CCR0. */
	write_cyrix_reg(CCR0, read_cyrix_reg(CCR0) | CCR0_NC1);

	/* Initialize CCR1. */
#ifdef CPU_CYRIX_NO_LOCK
	write_cyrix_reg(CCR1, read_cyrix_reg(CCR1) | CCR1_NO_LOCK);
#else
	write_cyrix_reg(CCR1, read_cyrix_reg(CCR1) & ~CCR1_NO_LOCK);
#endif

	/* Initialize CCR2. */
#ifdef CPU_SUSP_HLT
	write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) | CCR2_SUSP_HLT);
#else
	write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) & ~CCR2_SUSP_HLT);
#endif

	ccr3 = read_cyrix_reg(CCR3);
	write_cyrix_reg(CCR3, CCR3_MAPEN0);

	/* Initialize CCR4. */
	ccr4 = read_cyrix_reg(CCR4);
	ccr4 |= CCR4_DTE;
	ccr4 &= ~CCR4_IOMASK;
#ifdef CPU_IORT
	write_cyrix_reg(CCR4, ccr4 | (CPU_IORT & CCR4_IOMASK));
#else
	write_cyrix_reg(CCR4, ccr4 | 7);
#endif

	/* Initialize CCR5. */
#ifdef CPU_WT_ALLOC
	write_cyrix_reg(CCR5, read_cyrix_reg(CCR5) | CCR5_WT_ALLOC);
#endif

	/* Restore CCR3. */
	write_cyrix_reg(CCR3, ccr3);

	/* Unlock NW bit in CR0. */
	write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) & ~CCR2_LOCK_NW);

	/*
	 * Earlier revision of the 6x86 CPU could crash the system if
	 * L1 cache is in write-back mode.
	 */
	if ((cyrix_did & 0xff00) > 0x1600)
		load_cr0(rcr0() & ~(CR0_CD | CR0_NW));	/* CD = 0 and NW = 0 */
	else {
		/* Revision 2.6 and lower. */
#ifdef CYRIX_CACHE_REALLY_WORKS
		load_cr0(rcr0() & ~(CR0_CD | CR0_NW));	/* CD = 0 and NW = 0 */
#else
		load_cr0((rcr0() & ~CR0_CD) | CR0_NW);	/* CD = 0 and NW = 1 */
#endif
	}

	/* Lock NW bit in CR0. */
	write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) | CCR2_LOCK_NW);

	write_eflags(eflags);
}