tgt_machdep.c

来自「国产CPU-龙芯(loongson)BIOS源代码」· C语言 代码 · 共 2,203 行 · 第 1/4 页

C
2,203
字号
/*	$Id: tgt_machdep.c,v 1.4 2004/05/17 10:39:22 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. * */#if 1#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>#endif#include <sys/types.h>#include <termio.h>#include <string.h>#include <time.h>#include <stdlib.h>#include <dev/ic/mc146818reg.h>#include <linux/io.h>#include <autoconf.h>#include <machine/cpu.h>#include <machine/pio.h>#include "pflash.h"#include "dev/pflash_tgt.h"#include "include/bonito.h"#include <pmon/dev/gt64240reg.h>#include <pmon/dev/ns16550.h>#include <pmon.h>#include "mod_x86emu_int10.h"//#include "mod_x86emu.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#endifextern struct trapframe DBGREG;extern void *memset(void *, int, size_t);extern int sis6326_init(int fbaddress, int ioaddress);extern int fb_init(void);int kbd_available;int vga_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;void error(unsigned long *adr, unsigned long good, unsigned long bad);void modtst(int offset, int iter, unsigned long p1, unsigned long p2);void do_tick(void);void print_hdr(void);void ad_err2(unsigned long *adr, unsigned long bad);void ad_err1(unsigned long *adr1, unsigned long *adr2, unsigned long good, unsigned long bad);void mv_error(unsigned long *adr, unsigned long good, unsigned long bad);void print_err( unsigned long *adr, unsigned long good, unsigned long bad, unsigned long xor);static inline unsigned char CMOS_READ(unsigned char addr);static inline void CMOS_WRITE(unsigned char val, unsigned char addr);static void init_piix_rtc(void);ConfigEntry	ConfigTable[] ={	{ (char *)COM1_BASE_ADDR, 0, ns16550, 256, CONS_BAUD, NS16550HZ },	{ (char *)COM2_BASE_ADDR, 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);voidinitmips(unsigned int memsz){	/*	 *	Set up memory address decoders to map entire memory.	 *	But first move away bootrom map to high memory.	 */#if 0	GT_WRITE(BOOTCS_LOW_DECODE_ADDRESS, BOOT_BASE >> 20);	GT_WRITE(BOOTCS_HIGH_DECODE_ADDRESS, (BOOT_BASE - 1 + BOOT_SIZE) >> 20);#endif	int i=0;	memorysize=(memsz&0x0000ffff) << 20;	memorysize_high=((memsz&0xffff0000)>>16) << 20;	/*	 *  Probe clock frequencys so delays will work properly.	 */	tgt_cpufreq();	SBD_DISPLAY("DONE",0);	/*	 *  Init PMON and debug	 */	cpuinfotab[0] = &DBGREG;	for (i=0;i<0x100000;i++);	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#if 0	/* Set the PHY addresses for the GT ethernet */	GT_WRITE(ETH_PHY_ADDR_REG, 0x18a4);	GT_WRITE(MAIN_ROUTING_REGISTER, 0x007ffe38);	GT_WRITE(SERIAL_PORT_MULTIPLEX, 0x00000102);	/* Route Multi Purpose Pins */	GT_WRITE(MPP_CONTROL0, 0x77777777);	GT_WRITE(MPP_CONTROL1, 0x00000000);	GT_WRITE(MPP_CONTROL2, 0x00888888);	GT_WRITE(MPP_CONTROL3, 0x00000066);#endif	_pci_devinit(1);	/* PCI device initialization */	SBD_DISPLAY("VGAI", 0);#if NMOD_X86EMU_INT10 > 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	printf("fbaddress 0x%x\tioaddress 0x%x\n",fbaddress, ioaddress);                                                                                                                                                                    sis6326_init(fbaddress, ioaddress);        fb_init();	printf("after fb_init\n");        fb_available=1;#endif        config_init();        configure();#if 1#if NMOD_VGACON >0	rc=kbd_initialize();	printf("%s\n",kbd_error_msgs[rc]);	if(!rc){ 		kbd_available=1;	}#endif#endif	printf("devconfig done.\n");}extern int test_icache_1(short *addr);extern int test_icache_2(int addr);extern int test_icache_3(int addr);extern void godson1_cache_flush(void);#define tgt_putchar_uc(x) (*(void (*)(char)) (((long)tgt_putchar)|0x20000000)) (x)voidtgt_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;	}/*       tgt_putchar('!');       tgt_putchar('@');       tgt_putchar('#');       tgt_putchar('$');*/	       CPU_ConfigCache();       //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,#endif					in8(PLD_ID2) >> 4, in8(PLD_ID2) & 15);}/* *  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"); }static void init_piix_rtc(void){        int year, month, date, hour, min, sec;        CMOS_WRITE(DS_CTLA_DV1, DS_REG_CTLA);        CMOS_WRITE(DS_CTLB_24 | DS_CTLB_DM | DS_CTLB_SET, DS_REG_CTLB);        CMOS_WRITE(0, DS_REG_CTLC);        CMOS_WRITE(0, DS_REG_CTLD);        year = CMOS_READ(DS_REG_YEAR);        month = CMOS_READ(DS_REG_MONTH);        date = CMOS_READ(DS_REG_DATE);        hour = CMOS_READ(DS_REG_HOUR);        min = CMOS_READ(DS_REG_MIN);        sec = CMOS_READ(DS_REG_SEC);        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, DS_REG_YEAR);                CMOS_WRITE(1, DS_REG_MONTH);                CMOS_WRITE(1, DS_REG_DATE);                CMOS_WRITE(0, DS_REG_HOUR);                CMOS_WRITE(0, DS_REG_MIN);                CMOS_WRITE(0, DS_REG_SEC);        }        CMOS_WRITE(DS_CTLB_24 | DS_CTLB_DM, DS_REG_CTLB);#ifdef	BEBUG_RTC        for(;;){                while(CMOS_READ(DS_REG_CTLA)&DS_CTLA_UIP);                year = CMOS_READ(DS_REG_YEAR);                month = CMOS_READ(DS_REG_MONTH);                date = CMOS_READ(DS_REG_DATE);                hour = CMOS_READ(DS_REG_HOUR);                min = CMOS_READ(DS_REG_MIN);                sec = CMOS_READ(DS_REG_SEC);                                                                                               printf("RTC: %02d-%02d-%02d %02d:%02d:%02d\n",                        year, month, date, hour, min, sec);        }#endif}static inline unsigned char CMOS_READ(unsigned char addr){        unsigned char val;        linux_outb_p(addr, 0x70);        val = linux_inb_p(0x71);        return val;}                                                                               static inline void CMOS_WRITE(unsigned char val, unsigned char addr){        linux_outb_p(addr, 0x70);        linux_outb_p(val, 0x71);}static void_probe_frequencies(){#ifdef HAVE_TOD        int i, timeout, cur, sec, cnt;#endif                                                                                       SBD_DISPLAY ("FREQ", CHKPNT_FREQ);                                                                                                                                                                      md_pipefreq = 300000000;        /* Defaults */        md_cpufreq  = 66000000;        clk_invalid = 1;#ifdef HAVE_TOD        init_piix_rtc();        /*         * Do the next twice for two reasons. First make sure we run from         * cache. Second make sure synched on second update. (Pun intended!)         */        for(i = 2;  i != 0; i--) {                cnt = CPU_GetCOUNT();                timeout = 10000000;                while(CMOS_READ(DS_REG_CTLA) & DS_CTLA_UIP);                                                                                               sec = CMOS_READ(DS_REG_SEC);                                                                                               do {                        timeout--;                        while(CMOS_READ(DS_REG_CTLA) & DS_CTLA_UIP);                                                                                                       cur = CMOS_READ(DS_REG_SEC);                } while(timeout != 0 && cur == sec);                                                                                               cnt = CPU_GetCOUNT() - cnt;                if(timeout == 0) {                        break;          /* Get out if clock is not running */                }        }                                                                                       /*         *  Get PLL programming info.         */        i =  2 - ((CPU_GetCONFIG() >> 16) & 1);         /* Halfclock bit */        i = (((CPU_GetCONFIG() >> 28) & 7) + 2) * i;    /* Multiplier */        /*         *  Calculate the external bus clock frequency.         */        if (timeout != 0) {                clk_invalid = 0;                md_pipefreq = cnt / 10000;                md_pipefreq *= 20000;                md_cpufreq = (md_pipefreq * 2) / i;        }        else {                md_pipefreq = (md_cpufreq * i) / 2;        }                                                                                                                                                              #endif /* HAVE_TOD */}                                                                               /* *   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);}time_ttgt_gettime(){        struct tm tm;        int ctrlbsave;        time_t t;                                                                                       if(!clk_invalid) {                ctrlbsave = CMOS_READ(DS_REG_CTLB);                CMOS_WRITE(ctrlbsave | DS_CTLB_SET, DS_REG_CTLB);                                                                                               tm.tm_sec = CMOS_READ(DS_REG_SEC);                tm.tm_min = CMOS_READ(DS_REG_MIN);                tm.tm_hour = CMOS_READ(DS_REG_HOUR);                tm.tm_wday = CMOS_READ(DS_REG_WDAY);                tm.tm_mday = CMOS_READ(DS_REG_DATE);                tm.tm_mon = CMOS_READ(DS_REG_MONTH) - 1;

⌨️ 快捷键说明

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