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

📄 tgt_machdep.c

📁 MIPS处理器的bootloader,龙芯就是用的修改过的PMON2
💻 C
📖 第 1 页 / 共 2 页
字号:
/*	$Id: tgt_machdep.c,v 1.3 2003/06/13 09:00:48 pefo 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/ds15x1reg.h>#include <autoconf.h>#include <machine/cpu.h>#include <machine/pio.h>#include "pflash.h"#include "dev/pflash_tgt.h"#include "include/ev64240.h"#include <pmon/dev/gt64240reg.h>#include <pmon/dev/ns16550.h>#include <pmon.h>#include "mod_x86emu.h"extern void vga_bios_init(void);#include "flash.h"#if (NMOD_FLASH_AMD + NMOD_FLASH_INTEL) == 0#ifdef HAVE_FLASH#undef HAVE_FLASH#endif#else#define HAVE_FLASH#endifextern int boot_i2c_read(int addr);extern struct trapframe DBGREG;extern void *memset(void *, int, size_t);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 *);#endifConfigEntry	ConfigTable[] ={	{ (char *)COM1_BASE_ADDR, 0, ns16550, 256, CONS_BAUD, NS16550HZ },	{ (char *)COM2_BASE_ADDR, 0, ns16550, 256, CONS_BAUD, NS16550HZ },	{ 0 }};unsigned long _filebase;extern int memorysize;extern char MipsException[], MipsExceptionEnd[];unsigned char hwethadr[6];void initmips(void);voidinitmips(){	int	m1size, m2size;	int	m1banks, m2banks;	int	lo0, lo1, hi0, hi1;SBD_DISPLAY ("MSIZ", CHKPNT_AUTO); 	if (boot_i2c_read(0x600) < 0) {		m1size = 0;	}	else {		m1banks = boot_i2c_read(0x605);		m1size = boot_i2c_read(0x611);		m1size *= boot_i2c_read(0x61f);		m1size *= m1banks * 0x100000;	}	if (boot_i2c_read(0x400) < 0) {		m2size = 0;	}	else {		m2banks = boot_i2c_read(0x405);		m2size = boot_i2c_read(0x411);		m2size *= boot_i2c_read(0x41f);		m2size *= m2banks * 0x100000;	}	memorysize = m1size + m2size;	/*	 *  Set up memory address decoders to map entire memory.	 *  But first move away bootrom map to high memory.	 */	GT_WRITE(BOOTCS_LOW_DECODE_ADDRESS, BOOT_BASE >> 20);	GT_WRITE(BOOTCS_HIGH_DECODE_ADDRESS, (BOOT_BASE + BOOT_SIZE - 1) >> 20);	lo0 = lo1 = 0xfff;	hi0 = hi1 = 0x000;	if (m2size > 0) {		lo0 = m1size >> 20;		hi0 = (m1size + m2size - 1) >> 20;		if (m2banks > 1) {			hi1 = hi0;			lo1 = (m1size + (m2size >> 1)) >> 20;			hi0 = lo1 - 1;		}	}	GT_WRITE(SCS_2_LOW_DECODE_ADDRESS, lo0);	GT_WRITE(SCS_2_HIGH_DECODE_ADDRESS, hi0);	GT_WRITE(SCS_3_LOW_DECODE_ADDRESS, lo1);	GT_WRITE(SCS_3_HIGH_DECODE_ADDRESS, hi1);	lo0 = lo1 = 0xfff;	hi0 = hi1 = 0x000;	if (m1size > 0) {		lo0 = 0;		hi0 = (m1size - 1) >> 20;		if (m1banks > 1) {			hi1 = hi0;			lo1 = m1size >> 21;			hi0 = lo1 - 1;		}	}	GT_WRITE(SCS_0_LOW_DECODE_ADDRESS, lo0);	GT_WRITE(SCS_0_HIGH_DECODE_ADDRESS, hi0);	GT_WRITE(SCS_1_LOW_DECODE_ADDRESS, lo1);	GT_WRITE(SCS_1_HIGH_DECODE_ADDRESS, hi1);	/*	 *  Probe clock frequencys so delays will work properly.	 */	tgt_cpufreq();	/*	 *  Init PMON and debug	 */	cpuinfotab[0] = &DBGREG;	dbginit(NULL);	/*	 *  Set up exception vectors.	 */	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);	/*	 * Launch!	 */	pmon_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(){	/* 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, 0x43541717);	GT_WRITE(MPP_CONTROL1, 0x44009911);	GT_WRITE(MPP_CONTROL2, 0x40091818);	GT_WRITE(MPP_CONTROL3, 0x00090066);	_pci_devinit(1);	/* PCI device initialization */        config_init();        configure();#if NMOD_X86EMU >= 0	vga_bios_init();#endif}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;	}	CPU_ConfigCache();	_pci_businit(1);	/* PCI bus initialization */}voidtgt_reboot(){	void (*longreach) __P((void));	printf("Watchdog reboot failed!\n");	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(){	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);}/* *  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_probe_frequencies(){#ifdef HAVE_TOD	int i, timeout, cur, sec, cnt;#endifextern void tgt_setpar100mhz __P((void));	SBD_DISPLAY ("FREQ", CHKPNT_FREQ);	md_pipefreq = 300000000;	/* Defaults */	md_cpufreq  = 100000000;	clk_invalid = 1;#ifdef HAVE_TOD	/*	 *  Check if clock is stopped and start it if it is.	 */	i = inb(RTC_BASE + DS_REG_CTLB);	outb(RTC_BASE + DS_REG_CTLB, i | DS_CTLB_TE);	i = inb(RTC_BASE + DS_REG_MONTH) & 0x3f;	outb(RTC_BASE + DS_REG_MONTH, i | DS_MONTH_E32K);	/*	 * 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;		sec = inb(RTC_BASE + DS_REG_SEC);		do {			timeout--;			cur = inb(RTC_BASE + 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;	}	/*	 * Hack to change timing of GT64240 if not 125Mhz FSB.	 */	if(md_cpufreq < 110000000) {		tgt_setpar100mhz();	}#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);}#ifdef HAVE_TOD/* *  Returns the current time if a TOD clock is present or 0 *  This code is defunct after 2088... (out of bits) */#define FROMBCD(x)      (((x) >> 4) * 10 + ((x) & 0xf))#define TOBCD(x)        (((x) / 10 * 16) + ((x) % 10)) #define YEARDAYS(year)  ((((year) % 4) == 0 && \                         ((year % 100) != 0 || (year % 400) == 0)) ? 366 : 365)#define SECMIN  (60)            /* seconds per minute */#define SECHOUR (60*SECMIN)     /* seconds per hour */#define SECDAY  (24*SECHOUR)    /* seconds per day */#define SECYR   (365*SECDAY)    /* seconds per common year */static const short dayyr[12] =    { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };time_ttgt_gettime(){	struct tm tm;	int ctrlbsave;	time_t t;	if(!clk_invalid) {		/* Freeze readout data regs */		ctrlbsave =  inb(RTC_BASE + DS_REG_CTLB);		outb(RTC_BASE + DS_REG_CTLB, ctrlbsave & ~DS_CTLB_TE);		tm.tm_sec = FROMBCD(inb(RTC_BASE + DS_REG_SEC));		tm.tm_min = FROMBCD(inb(RTC_BASE + DS_REG_MIN));		tm.tm_hour = FROMBCD(inb(RTC_BASE + DS_REG_HOUR));		tm.tm_wday = FROMBCD(inb(RTC_BASE + DS_REG_WDAY));		tm.tm_mday = FROMBCD(inb(RTC_BASE + DS_REG_DATE));		tm.tm_mon = FROMBCD(inb(RTC_BASE + DS_REG_MONTH) & 0x1f) - 1;		tm.tm_year = FROMBCD(inb(RTC_BASE + DS_REG_YEAR));		tm.tm_year += 100 * (FROMBCD(inb(RTC_BASE + DS_REG_CENT)) - 19);		outb(RTC_BASE + DS_REG_CTLB, ctrlbsave | DS_CTLB_TE);		tm.tm_isdst = tm.tm_gmtoff = 0;		t = gmmktime(&tm);	}	else {		t = 957960000;  /* Wed May 10 14:00:00 2000 :-) */	}	return(t);}/* *  Set the current time if a TOD clock is present */voidtgt_settime(time_t t){	struct tm *tm;	int ctrlbsave;	if(!clk_invalid) {		tm = gmtime(&t);		/* Enable register writing */		ctrlbsave =  inb(RTC_BASE + DS_REG_CTLB);		outb(RTC_BASE + DS_REG_CTLB, ctrlbsave & ~DS_CTLB_TE);		outb(RTC_BASE + DS_REG_CENT, TOBCD(tm->tm_year / 100 + 19));		outb(RTC_BASE + DS_REG_YEAR, TOBCD(tm->tm_year % 100));		outb(RTC_BASE + DS_REG_MONTH,TOBCD(tm->tm_mon + 1));		outb(RTC_BASE + DS_REG_DATE, TOBCD(tm->tm_mday));		outb(RTC_BASE + DS_REG_WDAY, TOBCD(tm->tm_wday));		outb(RTC_BASE + DS_REG_HOUR, TOBCD(tm->tm_hour));		outb(RTC_BASE + DS_REG_MIN,  TOBCD(tm->tm_min));		outb(RTC_BASE + DS_REG_SEC,  TOBCD(tm->tm_sec));		/* Transfer new time to counters */		outb(RTC_BASE + DS_REG_CTLB, ctrlbsave | DS_CTLB_TE);	}}#elsetime_ttgt_gettime(){	return(957960000);  /* Wed May 10 14:00:00 2000 :-) */}#endif /* HAVE_TOD *//* *  Print out any target specific memory information */voidtgt_memprint(){	printf("Primary Instruction cache size %dkb (%d line, %d way)\n",		CpuPrimaryInstCacheSize / 1024, CpuPrimaryInstCacheLSize, CpuNWayCache);	printf("Primary Data cache size %dkb (%d line, %d way)\n",		CpuPrimaryDataCacheSize / 1024, CpuPrimaryDataCacheLSize, CpuNWayCache);	if(CpuSecondaryCacheSize != 0) {		printf("Secondary cache size %dkb\n", CpuSecondaryCacheSize / 1024);	}	if(CpuTertiaryCacheSize != 0) {		printf("Tertiary cache size %dkb\n", CpuTertiaryCacheSize / 1024);	}}voidtgt_machprint(){	printf("Copyright 2000-2002, Opsycon AB, Sweden.\n");	printf("CPU %s @", md_cpuname());} /* *  Return a suitable address for the client stack. *  Usually top of RAM memory. */register_ttgt_clienttos(){	return((register_t)(int)PHYS_TO_UNCACHED(memorysize & ~7) - 64);}#ifdef HAVE_FLASH/*

⌨️ 快捷键说明

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