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

📄 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 <stdarg.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 <linux/io.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 == 0int vga_available=0;#endifextern int boot_i2c_read(int addr);extern int sis6326_init(int fbaddress, int ioaddress);extern int gsim_vbe_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 *)(KSEG1 + IT8172_PCI_IO_BASE + IT_UART_BASE), 0, ns16550, 256, CONS_BAUD, NS16550HZ },	{ (char *)(KSEG1 + 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);voidflash_gpio (int code){        *((volatile unsigned short *)0xb4013802) = 0x0550;        *((volatile unsigned char *)0xb4013800) = (code & 0xf) << 2;}voidinitmips(unsigned int memsz){	memorysize = memsz;	/*	 *  Init PMON and debug	 */	cpuinfotab[0] = &DBGREG;	dbginit(NULL);	tgt_cpufreq();	/*	 *  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();	}/* * serial printf */voidtgt_puts(char *buf){	char *p;	for (p = buf; *p != '\0'; p++)		tgt_putchar(*p);}inttgt_printf(const char *fmt, ...){	int len;	va_list	ap;	char buf[200];		va_start(ap,fmt);	len = vsprintf(buf, fmt, ap);	tgt_puts(buf);	va_end(ap);	return (len);}/* *  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. *//*** LPC ***/// MB PnP configuration register#define LPC_KEY_ADDR    0x2E#define LPC_DATA_ADDR   0x2F// Device LDN#define LDN_SERIAL1     0x01 #define LDN_SERIAL2     0x02#define LDN_PARALLEL    0x03 #define LDN_KEYBOARD    0x05#define LDN_MOUSE       0x06static void LPCEnterMBPnP(void){	int i;	unsigned char key[4] = {0x87, 0x01, 0x55, 0x55};	for (i = 0; i<4; i++)		linux_outb(key[i], LPC_KEY_ADDR);}static void LPCExitMBPnP(void){	linux_outb(0x02, LPC_KEY_ADDR);	linux_outb(0x02, LPC_DATA_ADDR);}static void LPCSetConfig(char LdnNumber, char Index, char data){	LPCEnterMBPnP();				// Enter IT8712 MB PnP mode	linux_outb(0x07, LPC_KEY_ADDR);	linux_outb(LdnNumber, LPC_DATA_ADDR);	linux_outb(Index, LPC_KEY_ADDR);	linux_outb(data, LPC_DATA_ADDR);	LPCExitMBPnP();}static char LPCGetConfig(char LdnNumber, char Index){	char rtn;	LPCEnterMBPnP();				// Enter IT8712 MB PnP mode	linux_outb(0x07, LPC_KEY_ADDR);	linux_outb(LdnNumber, LPC_DATA_ADDR);	linux_outb(Index, LPC_KEY_ADDR);	rtn = linux_inb(LPC_DATA_ADDR);	LPCExitMBPnP();	return rtn;}static int SearchIT8712(void){	unsigned char Id1, Id2;	unsigned short Id;	LPCEnterMBPnP();	linux_outb(0x20, LPC_KEY_ADDR); /* chip id byte 1 */	Id1 = linux_inb(LPC_DATA_ADDR);	linux_outb(0x21, LPC_KEY_ADDR); /* chip id byte 2 */	Id2 = linux_inb(LPC_DATA_ADDR);	Id = (Id1 << 8) | Id2;	LPCExitMBPnP();	if (Id == 0x8712)		return 1;	else		return 0;}static void InitLPCInterface(void){	unsigned char bus, dev_fn;	unsigned long data;	bus = 0;	dev_fn = 1<<3 | 4;	/* pci cmd, SERR# Enable */	IT_WRITE(IT_CONFADDR,		 (bus         << IT_BUSNUM_SHF)   |		 (dev_fn      << IT_FUNCNUM_SHF) |		 ((0x4 / 4) << IT_REGNUM_SHF));	IT_READ(IT_CONFDATA, data);	data |= 0x0100;	IT_WRITE(IT_CONFADDR,		 (bus         << IT_BUSNUM_SHF)   |		 (dev_fn      << IT_FUNCNUM_SHF) |		 ((0x4 / 4) << IT_REGNUM_SHF));	IT_WRITE(IT_CONFDATA, data);	/* setup serial irq control register */	IT_WRITE(IT_CONFADDR,		 (bus         << IT_BUSNUM_SHF)   |		 (dev_fn      << IT_FUNCNUM_SHF) |		 ((0x48 / 4) << IT_REGNUM_SHF));	IT_READ(IT_CONFDATA, data);	data  = (data & 0xffff00ff) | 0xc400;	IT_WRITE(IT_CONFADDR,		 (bus         << IT_BUSNUM_SHF)   |		 (dev_fn      << IT_FUNCNUM_SHF) |		 ((0x48 / 4) << IT_REGNUM_SHF));	IT_WRITE(IT_CONFDATA, data);	/* Enable I/O Space Subtractive Decode */	/* default 0x4C is 0x3f220000 */	IT_WRITE(IT_CONFADDR,		 (bus         << IT_BUSNUM_SHF)   |		 (dev_fn      << IT_FUNCNUM_SHF) |		 ((0x4C / 4) << IT_REGNUM_SHF));	IT_WRITE(IT_CONFDATA, 0x3f2200f3);}/* * According to the ITE Special BIOS Note for waking up the * keyboard controller... */static int init_8712_keyboard(void){	unsigned int cmd_port = 0x64;	unsigned int data_port = 0x60;	unsigned char data;	int i;	linux_outb(0xaa, cmd_port); /* send self-test cmd */	i = 0;	while (!(linux_inb(cmd_port) & 0x1)) { /* wait output buffer full */		i++;		if (i > 0xffffff)			return 0;	}	data = linux_inb(data_port);	linux_outb(0xcb, cmd_port); /* set ps2 mode */	while (linux_inb(cmd_port) & 0x2) { /* wait while input buffer full */		i++;		if (i > 0xffffff)			return 0;	}	linux_outb(0x01, data_port);	while (linux_inb(cmd_port) & 0x2) { /* wait while input buffer full */		i++;		if (i > 0xffffff)			return 0;	}	linux_outb(0x60, cmd_port); /* write 8042 command byte */	while (linux_inb(cmd_port) & 0x2) { /* wait while input buffer full */		i++;		if (i > 0xffffff)			return 0;	}	linux_outb(0x45, data_port); /* at interface, keyboard enabled, system flag */	while (linux_inb(cmd_port) & 0x2) { /* wait while input buffer full */		i++;		if (i > 0xffffff)			return 0;	}	linux_outb(0xae, cmd_port); /* enable interface */	return 1;}static int init_8712(void){  	printf("8712 initializing..\n");	InitLPCInterface();  	printf("LPC initialized\n");	if (!SearchIT8712()) {	  printf("8712 not found!\n");	  return 0;	}	// enable IT8712 serial port	LPCSetConfig(LDN_SERIAL1, 0x30, 0x01); /* enable */	LPCSetConfig(LDN_SERIAL1, 0x23, 0x01); /* clock selection */	if (!init_8712_keyboard()) {	  printf("Unable to initialize keyboard!\n");	  return 0;	}	LPCSetConfig(LDN_KEYBOARD, 0x30, 0x1);	LPCSetConfig(LDN_KEYBOARD, 0xf0, 0x2);	LPCSetConfig(LDN_KEYBOARD, 0x71, 0x3);	LPCSetConfig(LDN_MOUSE, 0x30, 0x1); /* enable mouse */	if ((LPCGetConfig(LDN_KEYBOARD, 0x30) == 0) ||	    (LPCGetConfig(LDN_MOUSE, 0x30) == 0))	  printf("Error: keyboard or mouse not enabled\n");	return 1;}voidtgt_devconfig(){#if NMOD_VGACON >0	int rc;#endif	/* put IDE controller to normal mode 	 *	 * FIXME: a bit late, pci scan won't find and configure ide interfaces.	 * but if we put this into starto or initmips, we will have to change	 * ide interface setting(pci conf space) to make base regs writable	 * at that time.	 */        *((volatile unsigned short *)0xb4015800) &= ~0x200;	_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	if (vga_dev != NULL) {	  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;	} else {	  /* hack: for gsim */	  fbaddress = 0x12000000;	  ioaddress = 0x1cc;	  gsim_vbe_init(fbaddress,ioaddress);	  fb_init();	  fb_available=1;	}#endif	        config_init();        configure();#if NMOD_VGACON >0	init_8712();	rc=kbd_initialize();	printf("%s\n",kbd_error_msgs[rc]);	if(!rc){ 		kbd_available=1;	}#endif}#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;	}	       SBD_DISPLAY("CACH",0);       CPU_ConfigCache();       SBD_DISPLAY("CAC2",0);       SBD_DISPLAY("CAC3",0);	_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 = (volatile char*)        KSEG1ADDR((volatile char *)IT8172_RTC_ADR_REG);static volatile char *rtc_dat_reg = (volatile char*)        KSEG1ADDR((volatile char *)IT8172_RTC_DAT_REG); static inline unsigned char CMOS_READ (unsigned char addr){	unsigned char retval; 	*rtc_adr_reg = addr;	 retval =  *rtc_dat_reg;	 return retval;}voidCMOS_WRITE (unsigned char data, unsigned char addr){	*rtc_adr_reg = addr;	*rtc_dat_reg = data;}

⌨️ 快捷键说明

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