⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tgt_machdep.c

📁 国产CPU-龙芯(loongson)BIOS源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/*	$Id: tgt_machdep.c,v 1.7 2004/05/27 04:14:49 wlin Exp $ *//* * Copyright (c) 2001 Opsycon AB  (www.opsycon.se) *  * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by Opsycon AB, Sweden. * 4. The name of the author may not be used to endorse or promote products *    derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * */#include <sys/param.h>#include <sys/syslog.h>#include <machine/endian.h>#include <sys/device.h>#include <machine/cpu.h>#include <machine/pio.h>#include <machine/intr.h>#include <dev/pci/pcivar.h>#include <sys/types.h>#include <termio.h>#include <string.h>#include <time.h>#include <stdlib.h>#include <autoconf.h>#include <machine/cpu.h>#include <machine/pio.h>#include "pflash.h"#include "dev/pflash_tgt.h"#include <include/it8172.h>#include <include/rtc.h>#include <pmon/dev/ns16550.h>#include <pmon.h>#include "mod_x86emu.h"#include "mod_x86emu_int10.h"#include "mod_vgacon.h"extern void vga_bios_init(void);extern int kbd_initialize(void);extern int write_at_cursor(char val);extern const char *kbd_error_msgs[];#include "flash.h"#if (NMOD_FLASH_AMD + NMOD_FLASH_INTEL) == 0#ifdef HAVE_FLASH#undef HAVE_FLASH#endif#else#define HAVE_FLASH#endif#if NMOD_X86EMU_INT10 == 0//int vga_available=0;#endifextern int boot_i2c_read(int addr);extern int sis6326_init(int fbaddress, int ioaddress);extern int fb_init(void);extern struct trapframe DBGREG;extern void *memset(void *, int, size_t);int kbd_available;static int md_pipefreq = 0;static int md_cpufreq = 0;static int clk_invalid = 0;static int nvram_invalid = 0;static int cksum(void *p, size_t s, int set);static void _probe_frequencies(void);#ifndef NVRAM_IN_FLASHvoid nvram_get(char *);void nvram_put(char *);#endifextern int vgaterm(int op, struct DevEntry * dev, unsigned long param, int data);extern int fbterm(int op, struct DevEntry * dev, unsigned long param, int data);extern struct pci_device *vga_dev;ConfigEntry	ConfigTable[] ={	{ (char *)(IT8172_PCI_IO_BASE + IT_UART_BASE), 0, ns16550, 256, CONS_BAUD, NS16550HZ },#if NMOD_VGACON > 0#ifndef CONFIG_VGA_CARD_SIS6326	{ (char *)1, 0, vgaterm, 256, CONS_BAUD, NS16550HZ },#else	{ (char *)1, 0, fbterm, 256, CONS_BAUD, NS16550HZ },#endif#endif	{ 0 }};unsigned long _filebase;extern int memorysize;extern int memorysize_high;extern char MipsException[], MipsExceptionEnd[];unsigned char hwethadr[6];int fb_available = 0;unsigned long fbaddress = 0;unsigned long ioaddress = 0;void initmips(unsigned int memsz);void addr_tst1(void);void addr_tst2(void);void movinv1(int iter, ulong p1, ulong p2);void test_regs(void);voidinitmips(unsigned int memsz){	memorysize=(memsz&0x0000ffff) << 20;	printf("initmips start\n");	tgt_cpufreq();	/*	 *  Init PMON and debug	 */	cpuinfotab[0] = &DBGREG;	dbginit(NULL);	/*	 *  Set up exception vectors.	 */	SBD_DISPLAY("BEV1",0);	bcopy(MipsException, (char *)TLB_MISS_EXC_VEC, MipsExceptionEnd - MipsException);	bcopy(MipsException, (char *)GEN_EXC_VEC, MipsExceptionEnd - MipsException);	CPU_FlushCache();	CPU_SetSR(0, SR_BOOT_EXC_VEC);	SBD_DISPLAY("BEV0",0);		printf("BEV in SR set to zero.\n");#if 0	/* memtest */	addr_tst1();	addr_tst2();	movinv1(2,0,~0);	movinv1(2,0xaa5555aa,~0xaa5555aa);	printf("memtest done\n");#endif	/*	 * Launch!	 */	main();	}/* *  Put all machine dependent initialization here. This call *  is done after console has been initialized so it's safe *  to output configuration and debug information with printf. */voidtgt_devconfig(){#if NMOD_VGACON >0	int rc;#endif	_pci_devinit(1);	/* PCI device initialization */	SBD_DISPLAY("VGAI", 0);#if (NMOD_X86EMU_INT10 > 0) || (NMOD_X86EMU >0)	vga_bios_init();#endif#ifdef CONFIG_VGA_CARD_SIS6326	SBD_DISPLAY("FRBI", 0); 	fbaddress  =_pci_conf_read(vga_dev->pa.pa_tag,0x10);	ioaddress  =_pci_conf_read(vga_dev->pa.pa_tag,0x18);                                                                                                                                                                    fbaddress = fbaddress &0xffffff00; //laster 8 bit        ioaddress = ioaddress &0xfffffff0; //laster 4 bit                                                                                                                                                                   sis6326_init(fbaddress, ioaddress);        fb_init();        fb_available=1;#endif	        config_init();        configure();#if NMOD_VGACON >0	rc=kbd_initialize();	printf("%s\n",kbd_error_msgs[rc]);	if(!rc){ 		kbd_available=1;	}#endif}extern int test_icache_1(short *addr);extern int test_icache_2(int addr);extern int test_icache_3(int addr);extern int test_ld(void);extern void godson2_cache_flush(void);#define tgt_putchar_uc(x) (*(void (*)(char)) (((long)tgt_putchar)|0x20000000)) (x)#ifdef DEEP_DEBUGvoid tgt_test_memory(void){	register unsigned i,j;        register volatile char * volatile cmem;        register volatile unsigned * volatile imem;        register volatile unsigned * volatile imem_uc;  //      long long * volatile imem;	printf("%s:%d executing...\n",__FUNCTION__,__LINE__);	j = 0;	for (i=0;i<100000;i++) {		i++;	}	tgt_putchar('1');	if (i!=j) { tgt_putchar('2'); }         else { tgt_putchar('('); }        cmem = (char*)0x80400000L;        imem = (unsigned *)0x80400000L;        imem_uc = (unsigned *)0xa0400000L;        for (i=0;i<64*1024/sizeof(*cmem);i++) {          cmem[i] = 0x5a;          if (cmem[i]!=0x5a) {	   tgt_putchar('4');          }else{	   //tgt_putchar('3');          }        }	puts("char access test passed");        for (i=0;i<64*1024/sizeof(*imem);i++) {          imem[i] = 0xaa55aa55;          if (imem[i]!=0xaa55aa55) {	   tgt_putchar('6');          }else{	   //tgt_putchar('5');          }        }	puts("word access test passed");	printf("executing...\n");        for (i=0,j=0x87654321;i<64*1024/sizeof(*imem);i++,j+=0x01010101) {	  imem[i] = j;	  if (imem[i] != j) printf("error1(imem[i]=0x%x,j=0x%x.\n", imem[i],j);	}	CPU_FlushDCache((int)imem, 64*1024);        for (i=0,j=0x87654321;i<64*1024/sizeof(*imem);i++,j+=0x01010101) {	  if (imem_uc[i] != j) printf("%s:%d error(imem_uc[i]=0x%x,j=0x%x.\n", __FUNCTION__,__LINE__,imem_uc[i],j);	}        for (i=0,j=0x87654321;i<64*1024/sizeof(*imem);i++,j+=0x01010101) {	  if (imem[i] != j) printf("%s:%d error(imem[i]=0x%x,j=0x%x.\n", __FUNCTION__,__LINE__,imem[i],j);	}	printf("%s:%d executing...\n",__FUNCTION__,__LINE__);        for (i=0,j=0x12345678;i<64*1024/sizeof(*imem);i++,j+=0x01010101) {	  imem_uc[i] = j;	  if (imem_uc[i] != j) printf("%s:%d error(imem_uc[i]=0x%x,j=0x%x.\n", __FUNCTION__,__LINE__,imem_uc[i],j);	}	CPU_HitInvalidateDCache((int)imem, 64*1024);        for (i=0,j=0x12345678;i<64*1024/sizeof(*imem);i++,j+=0x01010101) {	  if (imem[i] != j) printf("%s:%d error(imem[i]=0x%x,j=0x%x.\n", __FUNCTION__,__LINE__,imem[i],j);	}        for (i=0,j=0x12345678;i<64*1024/sizeof(*imem);i++,j+=0x01010101) {	  if (imem_uc[i] != j) printf("%s:%d error(imem_uc[i]=0x%x,j=0x%x.\n", __FUNCTION__,__LINE__,imem_uc[i],j);	}}#endifvoidtgt_devinit(){	/*	 *  Gather info about and configure caches.	 */	if(getenv("ocache_off")) {		CpuOnboardCacheOn = 0;	}	else {		CpuOnboardCacheOn = 1;	}	if(getenv("ecache_off")) {		CpuExternalCacheOn = 0;	}	else {		CpuExternalCacheOn = 1;	}#ifdef DEEP_DEBUG       test_ld();#endif/*       tgt_putchar('!');       tgt_putchar('@');       tgt_putchar('#');       tgt_putchar('$');*/	       SBD_DISPLAY("CACH",0);       CPU_ConfigCache();       printf("CpuPrimaryDataCacheSize %d\n",CpuPrimaryDataCacheSize);       SBD_DISPLAY("CAC2",0);       SBD_DISPLAY("CAC3",0);       //godson2_cache_flush();/*       tgt_putchar('^');       tgt_putchar('&');       tgt_putchar('*');       tgt_putchar('%');       tgt_putchar('^');       tgt_putchar('&');       tgt_putchar('*');*/       //test_icache_2(0);       //test_icache_3(0);       //tgt_putchar(0x30+i);       //tgt_putchar('Y');             //tgt_test_memory();       //tgt_putchar('Z');	_pci_businit(1);	/* PCI bus initialization */}voidtgt_reboot(){	void (*longreach) __P((void));		longreach = (void *)0xbfc00000;	(*longreach)();	while(1);}/* *  This function makes inital HW setup for debugger and *  returns the apropriate setting for the status register. */register_ttgt_enable(int machtype){	/* XXX Do any HW specific setup */	return(SR_COP_1_BIT|SR_FR_32|SR_EXL);}/* *  Target dependent version printout. *  Printout available target version information. */voidtgt_cmd_vers(){#if 0	printf("Board revision level: %c.\n", in8(PLD_BAR) + 'A');	printf("PLD revision levels: %d.%d and %d.%d.\n",					in8(PLD_ID1) >> 4, in8(PLD_ID1) & 15,					in8(PLD_ID2) >> 4, in8(PLD_ID2) & 15);#endif}/* *  Display any target specific logo. */voidtgt_logo(){    printf("\n");    printf("[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[\n");    printf("[[[            [[[[   [[[[[[[[[[   [[[[            [[[[   [[[[[[[  [[\n");    printf("[[   [[[[[[[[   [[[    [[[[[[[[    [[[   [[[[[[[[   [[[    [[[[[[  [[\n");    printf("[[  [[[[[[[[[[  [[[  [  [[[[[[  [  [[[  [[[[[[[[[[  [[[  [  [[[[[  [[\n");    printf("[[  [[[[[[[[[[  [[[  [[  [[[[  [[  [[[  [[[[[[[[[[  [[[  [[  [[[[  [[\n");    printf("[[   [[[[[[[[   [[[  [[[  [[  [[[  [[[  [[[[[[[[[[  [[[  [[[  [[[  [[\n");    printf("[[             [[[[  [[[[    [[[[  [[[  [[[[[[[[[[  [[[  [[[[  [[  [[\n");    printf("[[  [[[[[[[[[[[[[[[  [[[[[  [[[[[  [[[  [[[[[[[[[[  [[[  [[[[[  [  [[\n");    printf("[[  [[[[[[[[[[[[[[[  [[[[[[[[[[[[  [[[  [[[[[[[[[[  [[[  [[[[[[    [[\n");    printf("[[  [[[[[[[[[[[[[[[  [[[[[[[[[[[[  [[[   [[[[[[[[   [[[  [[[[[[[   [[\n");    printf("[[  [[[[[[[[[[[[[[[  [[[[[[[[[[[[  [[[[            [[[[  [[[[[[[[  [[\n");    printf("[[[[[[[2000][[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[\n"); }#define IT8172_RTC_ADR_REG  (IT8172_PCI_IO_BASE + IT_RTC_BASE)#define IT8172_RTC_DAT_REG  (IT8172_RTC_ADR_REG + 1)/* Local Variables */static volatile char *rtc_adr_reg =        KSEG1ADDR((volatile char *)IT8172_RTC_ADR_REG);static volatile char *rtc_dat_reg =        KSEG1ADDR((volatile char *)IT8172_RTC_DAT_REG); static inline unsigned char CMOS_READ (unsigned long addr){	unsigned char retval; 	*rtc_adr_reg = addr;	 retval =  *rtc_dat_reg;	 return retval;}voidCMOS_WRITE (unsigned char data, unsigned long addr){	*rtc_adr_reg = addr;	*rtc_dat_reg = data;}/* Pending */static void init_it8172_rtc(void){	int year, month, date, hour, min, sec;	CMOS_WRITE(0x20, RTC_REG_A);/* Normal operation */	CMOS_WRITE(RTCSB_24HR | RTC_DM_BINARY | RTC_SET, RTC_REG_B);	CMOS_WRITE(0, RTC_REG_C);	CMOS_WRITE(0, RTC_REG_D);	year = CMOS_READ(RTC_YEAR);	month = CMOS_READ(RTC_MONTH);	date = CMOS_READ(RTC_DAY_OF_MONTH);	hour = CMOS_READ(RTC_HOURS);	min = CMOS_READ(RTC_MINUTES);	sec = CMOS_READ(RTC_SECONDS);	if( (year > 99) || (month < 1 || month > 12) || 		(date < 1 || date > 31) || (hour > 23) || (min > 59) ||		(sec > 59) ){		/*		printf("RTC time invalid, reset to epoch.\n");*/		CMOS_WRITE(3, RTC_YEAR);		CMOS_WRITE(1, RTC_MONTH);		CMOS_WRITE(1, RTC_DAY_OF_MONTH);		CMOS_WRITE(0, RTC_HOURS);		CMOS_WRITE(0, RTC_MINUTES);		CMOS_WRITE(0, RTC_SECONDS);	}	CMOS_WRITE(RTCSB_24HR | RTC_DM_BINARY, RTC_REG_B);}/* Pending */static unsigned int cal_r4koff(void){	unsigned long count;	unsigned int 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. */	CPU_SetCOUNT(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));		count = CPU_GetCOUNT();		return (count / 100);}/* Pending */static void_probe_frequencies(){	 unsigned long r4k_offset;	 unsigned long est_freq;	 clk_invalid = 1;	 init_it8172_rtc();	 r4k_offset = cal_r4koff();	 est_freq = 2*r4k_offset*100;	 est_freq += 5000;    /* round */         est_freq -= est_freq%10000;	 md_pipefreq = est_freq*3/2;	 md_cpufreq = est_freq;	 printf("/nCPU frequency %d.%02d MHz\n", est_freq/1000000,	          (est_freq%1000000)*100/1000000);}/* *   Returns the CPU pipelie clock frequency */inttgt_pipefreq(){	if(md_pipefreq == 0) {		_probe_frequencies();	}	return(md_pipefreq);}/* *   Returns the external clock frequency, usually the bus clock */inttgt_cpufreq(){	if(md_cpufreq == 0) {		_probe_frequencies();	}	return(md_cpufreq);}static inline time_t_mktime (unsigned int year, unsigned int mon,        unsigned int day, unsigned int hour,        unsigned int min, unsigned int sec){	if (0 >= (int) (mon -= 2)) {        /* 1..12 -> 11,12,1..10 */		mon += 12;              /* Puts Feb last since it has leap day */		year -= 1;	}	return ((((unsigned long) (year/4 - year/100 + year/400 + 367*mon/12 + day) +	         year*365 - 719499)*24 + hour /* now have hours */	         )*60 + min /* now have minutes */		 )*60 + sec; /* finally seconds */}time_ttgt_gettime(){	unsigned int year, mon, day, hour, min, sec;	unsigned char save_control;        CMOS_WRITE(CMOS_READ(RTC_CONTROL) | RTC_DM_BINARY, RTC_CONTROL);	save_control = CMOS_READ(RTC_CONTROL);	        /* Freeze it. */        CMOS_WRITE(save_control | RTC_SET, RTC_CONTROL);	/* Read regs. */	sec = CMOS_READ(RTC_SECONDS);	min = CMOS_READ(RTC_MINUTES);	hour = CMOS_READ(RTC_HOURS);	        if (!(save_control & RTC_24H))	{		if ((hour & 0xf) == 0xc)			hour &= 0x80;		if (hour & 0x80)			hour = (hour & 0xf) + 12;	}	day = CMOS_READ(RTC_DAY_OF_MONTH);	mon = CMOS_READ(RTC_MONTH);	year = CMOS_READ(RTC_YEAR);	/* Unfreeze clock. */	CMOS_WRITE(save_control, RTC_CONTROL);	if ((year += 1900) < 1970)	year += 100;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -