You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1352 lines
33 KiB

/* $Id: tgt_machdep.c,v 1.1.1.1 2006/09/14 01:59:08 root 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 <include/stdarg.h>
void tgt_putchar (int);
int
tgt_printf (const char *fmt, ...)
{
int n;
char buf[1024];
char *p=buf;
char c;
va_list ap;
va_start(ap, fmt);
n = vsprintf (buf, fmt, ap);
va_end(ap);
while((c=*p++))
{
if(c=='\n')
tgt_putchar('\r');
tgt_putchar(c);
}
return (n);
}
#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 "target/firewall.h"
#include "target/ls1a.h"
#include <pmon.h>
#include "mod_x86emu_int10.h"
#include "mod_x86emu.h"
#include "mod_vgacon.h"
#include "mod_framebuffer.h"
#include "mod_smi712.h"
#include "mod_smi502.h"
#include "mod_sisfb.h"
#include "include/ls1a.h"
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 + NMOD_FLASH_SST) == 0
#ifdef HAVE_FLASH
#undef HAVE_FLASH
#endif
#else
#define HAVE_FLASH
#endif
#if (NMOD_X86EMU_INT10 == 0)&&(NMOD_X86EMU == 0)
int vga_available=0;
#elif defined(VGAROM_IN_BIOS)
#include "vgarom.c"
#endif
extern struct trapframe DBGREG;
extern void *memset(void *, int, size_t);
int kbd_available;
int usb_kbd_available;;
int vga_available;
int bios_available;
int cmd_main_mutex = 0;
int bios_mutex = 0;
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_FLASH
void nvram_get(char *);
void nvram_put(char *);
#endif
extern 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);
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_legacy_rtc(void);
int afxIsReturnToPmon = 0;
ConfigEntry ConfigTable[] =
{
{ (char *)COM1_BASE_ADDR, 0, ns16550, 256, CONS_BAUD, NS16550HZ },
#if NMOD_VGACON >0
#if NMOD_FRAMEBUFFER >0
{ (char *)1, 0, fbterm, 256, CONS_BAUD, NS16550HZ },
#else
{ (char *)1, 0, vgaterm, 256, CONS_BAUD, NS16550HZ },
#endif
#endif
{ (char *)COM0_1A_BASE_ADDR, 0, ns16550_1a, 256, CONS_BAUD, NS16550HZ },
{ 0 }
};
unsigned char activecom = 0x3;
unsigned char em_enable = 0x3;
unsigned long _filebase;
extern unsigned long long memorysize;
extern unsigned long long memorysize_high;
extern char MipsException[], MipsExceptionEnd[];
//extern void get_memorysize(unsigned long long raw_memsz);
unsigned char hwethadr[6];
unsigned char hwethadr1[6];
void initmips(unsigned int memsz);
void addr_tst1(void);
void addr_tst2(void);
void movinv1(int iter, ulong p1, ulong p2);
pcireg_t _pci_allocate_io(struct pci_device *dev, vm_size_t size);
static void superio_reinit();
void
initmips(unsigned int memsz)
{
unsigned int hi;
tgt_fpuenable();
tgt_printf("memsz %d\n",memsz);
tgt_fpuenable();
get_memorysize(memsz);
/*
* Probe clock frequencys so delays will work properly.
*/
tgt_cpufreq();
SBD_DISPLAY("DONE",0);
/*
* 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();
#ifndef ROM_EXCEPTION
CPU_SetSR(0, SR_BOOT_EXC_VEC);
#endif
SBD_DISPLAY("BEV0",0);
printf("BEV in SR set to zero.\n");
#if 0
printf(" bus device irq_number is:\n"); //zxj added for irq
for(hi=0;hi<16;hi++)
printf(" 1 %d INT%c \n",hi,hi%4+'A');
#endif
/*
* Launch!
*/
printf("v1.01\n");
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.
*/
extern void vt82c686_init(void);
int psaux_init(void);
extern int video_hw_init (void);
int dc_init();
extern int fb_init(unsigned long,unsigned long);
void
tgt_devconfig()
{
#if NMOD_VGACON > 0
int rc=0;
#if NMOD_FRAMEBUFFER > 0
unsigned long fbaddress;
#endif
#endif
_pci_devinit(1); /* PCI device initialization */
#if NMOD_FRAMEBUFFER > 0
vga_available=0;
fbaddress = dc_init();
printf("begin fb_init\n");
printf("fbaddress :0x%x\n",fbaddress);
fbaddress |= 0xb4000000;
fb_init(fbaddress, 0);
printf("after fb_init\n");
#endif
#if (NMOD_FRAMEBUFFER > 0) || (NMOD_VGACON > 0 )
if(!getenv("novga"))
vga_available=1;
else
vga_available=0;
#endif
config_init();
configure();
#if (NMOD_VGACON >0)
if(getenv("nokbd"))
rc=1;
else
rc=kbd_initialize();
printf("%s\n",kbd_error_msgs[rc]);
if(!rc){
kbd_available=1;
}
psaux_init();
#endif
init_win_device();
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)
extern void test_gpio_function(void);
void
tgt_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 */
}
#define LS2G_GPIO_EN 0xbfe0011c
#define LS2G_GPIO_DATA 0xbfe00120
void tgt_reboot()
{
*((volatile unsigned int *)LS2G_GPIO_EN) &= ~(1<<4);//set gpio4 is output
*((volatile unsigned int *)LS2G_GPIO_DATA) &= ~(1<<4);//set gpio4 to 0
while(1);
}
void tgt_poweroff()
{
*((volatile unsigned int *)LS1A_PM1_STS_REG) = 0Xffff;//clear wakeup enable bit
*((volatile unsigned int *)LS1A_PM1_EN_REG) = 0X0;//clear wakeup enable bit
*((volatile unsigned int *)LS1A_GPE0_EN_REG) = 0X0;//clear wakeup enable bit
*((volatile unsigned int *)LS1A_PM1_CNT_REG) |= (0x7<<10)|(0x1<<13);//set 1a to s5 mode
while(1);
}
/*
* This function makes inital HW setup for debugger and
* returns the apropriate setting for the status register.
*/
register_t
tgt_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.
*/
void
tgt_cmd_vers()
{
}
/*
* Display any target specific logo.
*/
void
tgt_logo()
{
#if 0
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("[[[[[[[2005][[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[\n");
#endif
printf("\n");
printf("[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[\n");
printf("[[ [[[[[[[[[ [[[[[ [[[[ [[[[[ [[[[[ [[[[[ [[[[[ [[[[ [[[[[ [[\n");
printf("[[ [[[[[[[[ [[[[ [[[ [[[[ [[[ [[[[ [[[[ [[[[ [[[ [[[[ [[[ [[[[ [[[ [[[[ [[\n");
printf("[[ [[[[[[[[ [[[[[[ [[[ [[[[[[ [[[ [ [[[ [[[ [[[[[[[[[[[[ [[[[[[[ [[[[[[ [[[ [ [[[ [[\n");
printf("[[ [[[[[[[[ [[[[[[ [[[ [[[[[[ [[[ [[ [[ [[[ [[[ [[[[[[[ [[[[ [[[[[[ [[[ [[ [[ [[\n");
printf("[[ [[[[[[[[ [[[[[[ [[[ [[[[[[ [[[ [[[ [ [[[ [[[[[ [[[[[[[[[[ [[[ [[[[[[ [[[ [[[ [ [[\n");
printf("[[ [[[[[[[[ [[[[ [[[ [[[[ [[[ [[[[ [[[ [[[[ [[[ [[[ [[[[ [[[[ [[[ [[[[ [[\n");
printf("[[ [[[[ [[[[[ [[[[ [[[[[ [[[[ [[[[[ [[[[[[ [[[[ [[[[[ [[\n");
printf("[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[2011 Loongson][[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[\n");
}
static void init_legacy_rtc(void)
{
int year, month, date, hour, min, sec, val,test;
int year1,year2;
val = (1 << 13) | (1 << 11) | (1 << 8);
outl(LS1A_RTC_CTRL_REG, val);
outl(LS1A_TOY_TRIM_REG, 0);
outl(LS1A_RTC_TRIM_REG, 0);
year = inl(LS1A_TOY_READ1_REG);
val = inl(LS1A_TOY_READ0_REG);
month = ((val >> 26) & 0x3f) - 1;
date = (val >> 21) & 0x1f;
hour = (val >> 16) & 0x1f;
min = (val >> 10) & 0x3f;
sec = (val >> 4) & 0x3f;
if ((year < 0 || year > 138)
|| (month < 1 || month > 12)
|| (date < 1 || date > 31)
|| (hour > 23) || (min > 59)
|| (sec > 59)) {
tgt_printf("RTC time invalid, reset to epoch.\n");
/* 2000-01-01 00:00:00 */
val = (2 << 26) | (1 << 21);
outl(LS1A_TOY_WRITE1_REG, 0x64);
outl(LS1A_TOY_WRITE0_REG, val);
}
tgt_printf("RTC: %02d-%02d-%02d %02d:%02d:%02d\n",
year, month, date, hour, min, sec);
}
int word_addr;
static inline unsigned char CMOS_READ(unsigned char addr)
{
unsigned char val;
unsigned char tmp1,tmp2;
volatile int tmp;
linux_outb_p(addr, 0x70);
val = linux_inb_p(0x71);
return val;
}
static inline void CMOS_WRITE(unsigned char val, unsigned char addr)
{
char a;
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);
#if 0
md_pipefreq = 300000000; /* Defaults */
md_cpufreq = 66000000;
#else
md_pipefreq = 660000000; /* NB FPGA*/
md_cpufreq = 60000000;
#endif
clk_invalid = 1;
#ifdef HAVE_TOD
init_legacy_rtc();
SBD_DISPLAY ("FREI", CHKPNT_FREQ);
/*
* Do the next twice for two reasons. First make sure we run from
* cache. Second make sure synched on second update. (Pun intended!)
*/
aa:
for(i = 2; i != 0; i--) {
cnt = CPU_GetCOUNT();
timeout = 10000000;
sec = ((inl(LS1A_TOY_READ0_REG) >> 4) & 0x3f);
do {
timeout--;
cur = ((inl(LS1A_TOY_READ0_REG) >> 4) & 0x3f);
} while(timeout != 0 && ((cur == sec)||(cur !=((sec+1)%60))) && (CPU_GetCOUNT() - cnt<0x30000000));
cnt = CPU_GetCOUNT() - cnt;
if(timeout == 0) {
tgt_printf("time out!\n");
break; /* Get out if clock is not running */
}
}
/*
* Calculate the external bus clock frequency.
*/
if (timeout != 0) {
clk_invalid = 0;
md_pipefreq = cnt / 10000;
md_pipefreq *= 20000;
/* we have no simple way to read multiplier value
*/
md_cpufreq = 66000000;
}
tgt_printf("cpu fre %u\n",md_pipefreq);
#endif /* HAVE_TOD */
}
/*
* Returns the CPU pipelie clock frequency
*/
int
tgt_pipefreq()
{
if(md_pipefreq == 0) {
_probe_frequencies();
}
return(md_pipefreq);
}
/*
* Returns the external clock frequency, usually the bus clock
*/
int
tgt_cpufreq()
{
if(md_cpufreq == 0) {
_probe_frequencies();
}
return(md_cpufreq);
}
time_t
tgt_gettime()
{
struct tm tm;
int val;
time_t t;
#ifdef HAVE_TOD
if(!clk_invalid) {
val = inl(LS1A_TOY_READ0_REG);
tm.tm_sec = (val >> 4) & 0x3f;
tm.tm_min = (val >> 10) & 0x3f;
tm.tm_hour = (val >> 16) & 0x1f;
tm.tm_mday = (val >> 21) & 0x1f;
tm.tm_mon = ((val >> 26) & 0x3f) - 1;
tm.tm_year = inl(LS1A_TOY_READ1_REG);
if(tm.tm_year < 50)
tm.tm_year += 100;
tm.tm_isdst = tm.tm_gmtoff = 0;
t = gmmktime(&tm);
}
else
#endif
{
t = 957960000; /* Wed May 10 14:00:00 2000 :-) */
}
return(t);
}
/*
* Set the current time if a TOD clock is present
*/
void
tgt_settime(time_t t)
{
struct tm *tm;
//int ctrlbsave;
int year, month, date, hour, min, sec;
unsigned int time_value;
//return ;
#ifdef HAVE_TOD
if(!clk_invalid) {
tm = gmtime(&t);
year = tm->tm_year;
month = tm->tm_mon;
date = tm->tm_mday;
hour = tm->tm_hour;
min = tm->tm_min;
sec = tm->tm_sec;
time_value = ((month + 1)<<26 | date<<21 | hour<<16 | min<<10 | sec<<4);
outl(LS1A_TOY_WRITE0_REG, time_value);
outl(LS1A_TOY_WRITE1_REG, year);
}
#endif
}
/*
* Print out any target specific memory information
*/
void
tgt_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);
}
}
void
tgt_machprint()
{
printf("Copyright 2000-2002, Opsycon AB, Sweden.\n");
printf("Copyright 2005, ICT CAS.\n");
printf("CPU %s @", md_cpuname());
}
/*
* Return a suitable address for the client stack.
* Usually top of RAM memory.
*/
register_t
tgt_clienttos()
{
return((register_t)(int)PHYS_TO_UNCACHED(memorysize & ~7) - 64);
}
#ifdef HAVE_FLASH
/*
* Flash programming support code.
*/
/*
* Table of flash devices on target. See pflash_tgt.h.
*/
struct fl_map tgt_fl_map_boot16[]={
TARGET_FLASH_DEVICES_16
};
struct fl_map *
tgt_flashmap()
{
return tgt_fl_map_boot16;
}
void
tgt_flashwrite_disable()
{
}
int
tgt_flashwrite_enable()
{
return(1);
}
void
tgt_flashinfo(void *p, size_t *t)
{
struct fl_map *map;
map = fl_find_map(p);
if(map) {
*t = map->fl_map_size;
}
else {
*t = 0;
}
}
void
tgt_flashprogram(void *p, int size, void *s, int endian)
{
printf("Programming flash %x:%x into %x\n", s, size, p);
if(fl_erase_device(p, size, TRUE)) {
printf("Erase failed!\n");
return;
}
if(fl_program_device(p, s, size, TRUE)) {
printf("Programming failed!\n");
}
fl_verify_device(p, s, size, TRUE);
}
#endif /* PFLASH */
/*
* Network stuff.
*/
void
tgt_netinit()
{
}
int
tgt_ethaddr(char *p)
{
bcopy((void *)&hwethadr, p, 6);
return(0);
}
int
tgt_ethaddr1(char *p)
{
bcopy((void *)&hwethadr1, p, 6);
return(0);
}
void
tgt_netreset()
{
}
/*************************************************************************/
/*
* Target dependent Non volatile memory support code
* =================================================
*
*
* On this target a part of the boot flash memory is used to store
* environment. See EV64260.h for mapping details. (offset and size).
*/
/*
* Read in environment from NV-ram and set.
*/
void
tgt_mapenv(int (*func) __P((char *, char *)))
{
char *ep;
char env[512];
char *nvram;
int i;
/*
* Check integrity of the NVRAM env area. If not in order
* initialize it to empty.
*/
printf("in envinit\n");
#ifdef NVRAM_IN_FLASH
nvram = (char *)(tgt_flashmap())->fl_map_base;
printf("nvram=%08x\n",(unsigned int)nvram);
if(fl_devident(nvram, NULL) == 0 ||
cksum(nvram + NVRAM_OFFS, NVRAM_SIZE, 0) != 0) {
#else
nvram = (char *)malloc(512);
nvram_get(nvram);
if(cksum(nvram, NVRAM_SIZE, 0) != 0) {
#endif
printf("NVRAM is invalid!\n");
nvram_invalid = 1;
}
else {
#ifdef NVRAM_IN_FLASH
nvram += NVRAM_OFFS;
ep = nvram+2;;
while(*ep != 0) {
char *val = 0, *p = env;
i = 0;
while((*p++ = *ep++) && (ep <= nvram + NVRAM_SIZE - 1) && i++ < 255) {
if((*(p - 1) == '=') && (val == NULL)) {
*(p - 1) = '\0';
val = p;
}
}
if(ep <= nvram + NVRAM_SIZE - 1 && i < 255) {
(*func)(env, val);
}
else {
nvram_invalid = 2;
break;
}
}
#endif
}
printf("NVRAM@%x\n",(u_int32_t)nvram);
#ifdef NVRAM_IN_FLASH
printf("ACTIVECOM_OFFS = %d, = 0x%x\n", ACTIVECOM_OFFS, ACTIVECOM_OFFS);
printf("MASTER_BRIDGE_OFFS = %d, = 0x%x\n", MASTER_BRIDGE_OFFS, MASTER_BRIDGE_OFFS);
printf("before :activecom = %d. em_enable = %d\n", activecom, em_enable);
// printf("nuram[MASTER_BRIDGE_OFFS] = %d.\n" nvram[MASTER_BRIDGE_OFFS]);
if(!nvram_invalid)
bcopy(&nvram[ACTIVECOM_OFFS],&activecom, 1);
else
activecom = 3 /*1*/;
sprintf(env,"0x%02x",activecom);
(*func)("activecom",env); /*tangyt*/
if(!nvram_invalid)
bcopy(&nvram[MASTER_BRIDGE_OFFS],&em_enable, 1);
else
em_enable = 3 /*1*/;
sprintf(env,"0x%02x",em_enable);
(*func)("em_enable",env); /*tangyt*/
printf("activecom = %d. em_enable = %d.\n", activecom, em_enable);
#endif
/*
* Ethernet address for Galileo ethernet is stored in the last
* six bytes of nvram storage. Set environment to it.
*/
if(!nvram_invalid)
bcopy(&nvram[ETHER_OFFS], hwethadr, 6);
sprintf(env, "%02x:%02x:%02x:%02x:%02x:%02x", hwethadr[0], hwethadr[1],
hwethadr[2], hwethadr[3], hwethadr[4], hwethadr[5]);
(*func)("ethaddr", env);
if(!nvram_invalid)
bcopy(&nvram[ETHER1_OFFS], hwethadr1, 6);
sprintf(env, "%02x:%02x:%02x:%02x:%02x:%02x", hwethadr1[0], hwethadr1[1],
hwethadr1[2], hwethadr1[3], hwethadr1[4], hwethadr1[5]);
(*func)("ethaddr1", env);
#ifndef NVRAM_IN_FLASH
free(nvram);
#endif
#ifdef no_thank_you
(*func)("vxWorks", env);
#endif
sprintf(env, "%d", memorysize / (1024 * 1024));
(*func)("memsize", env);
sprintf(env, "%d", memorysize_high / (1024 * 1024));
(*func)("highmemsize", env);
sprintf(env, "%d", md_pipefreq);
(*func)("cpuclock", env);
sprintf(env, "%d", md_cpufreq);
(*func)("busclock", env);
(*func)("systype", SYSTYPE);
}
int
tgt_unsetenv(char *name)
{
char *ep, *np, *sp;
char *nvram;
char *nvrambuf;
char *nvramsecbuf;
int status;
if(nvram_invalid) {
return(0);
}
/* Use first defined flash device (we probably have only one) */
#ifdef NVRAM_IN_FLASH
nvram = (char *)(tgt_flashmap())->fl_map_base;
/* Map. Deal with an entire sector even if we only use part of it */
nvram += NVRAM_OFFS & ~(NVRAM_SECSIZE - 1);
nvramsecbuf = (char *)malloc(NVRAM_SECSIZE);
if(nvramsecbuf == 0) {
printf("Warning! Unable to malloc nvrambuffer!\n");
return(-1);
}
memcpy(nvramsecbuf, nvram, NVRAM_SECSIZE);
nvrambuf = nvramsecbuf + (NVRAM_OFFS & (NVRAM_SECSIZE - 1));
#else
nvramsecbuf = nvrambuf = nvram = (char *)malloc(512);
nvram_get(nvram);
#endif
ep = nvrambuf + 2;
status = 0;
#ifdef NVRAM_IN_FLASH
while((*ep != '\0') && (ep <= nvrambuf + NVRAM_SIZE)) {
np = name;
sp = ep;
while((*ep == *np) && (*ep != '=') && (*np != '\0')) {
ep++;
np++;
}
if((*np == '\0') && ((*ep == '\0') || (*ep == '='))) {
while(*ep++);
while(ep <= nvrambuf + NVRAM_SIZE) {
*sp++ = *ep++;
}
if(nvrambuf[2] == '\0') {
nvrambuf[3] = '\0';
}
cksum(nvrambuf, NVRAM_SIZE, 1);
#ifdef NVRAM_IN_FLASH
if(fl_erase_device(nvram, NVRAM_SECSIZE, FALSE)) {
status = -1;
break;
}
if(fl_program_device(nvram, nvramsecbuf, NVRAM_SECSIZE, FALSE)) {
status = -1;
break;
}
#else
nvram_put(nvram);
#endif
status = 1;
break;
}
else if(*ep != '\0') {
while(*ep++ != '\0');
}
}
#endif
free(nvramsecbuf);
return(status);
}
int
tgt_setenv(char *name, char *value) {
char *ep;
int envlen;
char *nvrambuf;
char *nvramsecbuf;
#ifdef NVRAM_IN_FLASH
char *nvram;
#endif
/* Non permanent vars. */
if(strcmp(EXPERT, name) == 0) {
return(1);
}
/* Calculate total env mem size requiered */
envlen = strlen(name);
if(envlen == 0) {
return(0);
}
if(value != NULL) {
envlen += strlen(value);
}
envlen += 2; /* '=' + null byte */
if(envlen > 255) {
return(0); /* Are you crazy!? */
}
/* Use first defined flash device (we probably have only one) */
#ifdef NVRAM_IN_FLASH
nvram = (char *)(tgt_flashmap())->fl_map_base;
/* Deal with an entire sector even if we only use part of it */
nvram += NVRAM_OFFS & ~(NVRAM_SECSIZE - 1);
#endif
/* If NVRAM is found to be uninitialized, reinit it. */
if(nvram_invalid) {
nvramsecbuf = (char *)malloc(NVRAM_SECSIZE);
if(nvramsecbuf == 0) {
printf("Warning! Unable to malloc nvrambuffer!\n");
return(-1);
}
#ifdef NVRAM_IN_FLASH
memcpy(nvramsecbuf, nvram, NVRAM_SECSIZE);
#endif
nvrambuf = nvramsecbuf + (NVRAM_OFFS & (NVRAM_SECSIZE - 1));
memset(nvrambuf, -1, NVRAM_SIZE);
nvrambuf[2] = '\0';
nvrambuf[3] = '\0';
cksum((void *)nvrambuf, NVRAM_SIZE, 1);
printf("Warning! NVRAM checksum fail. Reset!\n");
#ifdef NVRAM_IN_FLASH
if(fl_erase_device(nvram, NVRAM_SECSIZE, FALSE)) {
printf("Error! Nvram erase failed!\n");
free(nvramsecbuf);
return(-1);
}
if(fl_program_device(nvram, nvramsecbuf, NVRAM_SECSIZE, FALSE)) {
printf("Error! Nvram init failed!\n");
free(nvramsecbuf);
return(-1);
}
#else
nvram_put(nvramsecbuf);
#endif
nvram_invalid = 0;
free(nvramsecbuf);
}
/* Remove any current setting */
tgt_unsetenv(name);
/* Find end of evironment strings */
nvramsecbuf = (char *)malloc(NVRAM_SECSIZE);
if(nvramsecbuf == 0) {
printf("Warning! Unable to malloc nvrambuffer!\n");
return(-1);
}
#ifndef NVRAM_IN_FLASH
nvram_get(nvramsecbuf);
#else
memcpy(nvramsecbuf, nvram, NVRAM_SECSIZE);
#endif
nvrambuf = nvramsecbuf + (NVRAM_OFFS & (NVRAM_SECSIZE - 1));
/* Etheraddr is special case to save space */
#if 1 /*added by tangyt*/
if (strcmp("activecom",name)==0)
{
activecom=strtoul(value,0,0);
printf("set activecom to com %d\n",activecom);
}else if (strcmp("em_enable",name)==0)
{
em_enable=strtoul(value,0,0);
printf("set em_enable to com %d\n",em_enable);
}
else
if (strcmp("ethaddr1", name) == 0) {
char *s = value;
int i;
int32_t v;
for(i = 0; i < 6; i++) {
gethex(&v, s, 2);
hwethadr1[i] = v;
s += 3; /* Don't get to fancy here :-) */
}
}
else
#endif
if (strcmp("ethaddr", name) == 0) {
char *s = value;
int i;
int32_t v;
for(i = 0; i < 6; i++) {
gethex(&v, s, 2);
hwethadr[i] = v;
s += 3; /* Don't get to fancy here :-) */
}
} else {
ep = nvrambuf+2;
if(*ep != '\0') {
do {
while(*ep++ != '\0');
} while(*ep++ != '\0');
ep--;
}
if(((int)ep + NVRAM_SIZE - (int)ep) < (envlen + 1)) {
free(nvramsecbuf);
return(0); /* Bummer! */
}
/*
* Special case heaptop must always be first since it
* can change how memory allocation works.
*/
if(strcmp("heaptop", name) == 0) {
bcopy(nvrambuf+2, nvrambuf+2 + envlen,
ep - nvrambuf+1);
ep = nvrambuf+2;
while(*name != '\0') {
*ep++ = *name++;
}
if(value != NULL) {
*ep++ = '=';
while((*ep++ = *value++) != '\0');
}
else {
*ep++ = '\0';
}
}
else {
while(*name != '\0') {
*ep++ = *name++;
}
if(value != NULL) {
*ep++ = '=';
while((*ep++ = *value++) != '\0');
}
else {
*ep++ = '\0';
}
*ep++ = '\0'; /* End of env strings */
}
}
cksum(nvrambuf, NVRAM_SIZE, 1);
#ifdef NVRAM_IN_FLASH
bcopy(&activecom,&nvrambuf[ACTIVECOM_OFFS], 1);
bcopy(&em_enable,&nvrambuf[MASTER_BRIDGE_OFFS], 1);
#endif
bcopy(hwethadr, &nvramsecbuf[ETHER_OFFS], 6);
bcopy(hwethadr1, &nvramsecbuf[ETHER1_OFFS], 6);
#ifdef NVRAM_IN_FLASH
if(fl_erase_device(nvram, NVRAM_SECSIZE, FALSE)) {
printf("Error! Nvram erase failed!\n");
free(nvramsecbuf);
return(0);
}
if(fl_program_device(nvram, nvramsecbuf, NVRAM_SECSIZE, FALSE)) {
printf("Error! Nvram program failed!\n");
free(nvramsecbuf);
return(0);
}
#else
nvram_put(nvramsecbuf);
#endif
free(nvramsecbuf);
return(1);
}
/*
* Calculate checksum. If 'set' checksum is calculated and set.
*/
static int
cksum(void *p, size_t s, int set)
{
u_int16_t sum = 0;
u_int8_t *sp = p;
int sz = s / 2;
if(set) {
*sp = 0; /* Clear checksum */
*(sp+1) = 0; /* Clear checksum */
}
while(sz--) {
sum += (*sp++) << 8;
sum += *sp++;
}
if(set) {
sum = -sum;
*(u_int8_t *)p = sum >> 8;
*((u_int8_t *)p+1) = sum;
}
return(sum);
}
#ifndef NVRAM_IN_FLASH
/*
* Read and write data into non volatile memory in clock chip.
*/
void
nvram_get(char *buffer)
{
int i;
for(i = 0; i < 114; i++) {
linux_outb(i + RTC_NVRAM_BASE, RTC_INDEX_REG); /* Address */
buffer[i] = linux_inb(RTC_DATA_REG);
}
}
void
nvram_put(char *buffer)
{
int i;
for(i = 0; i < 114; i++) {
linux_outb(i+RTC_NVRAM_BASE, RTC_INDEX_REG); /* Address */
linux_outb(buffer[i],RTC_DATA_REG);
}
}
#endif
/*
* Simple display function to display a 4 char string or code.
* Called during startup to display progress on any feasible
* display before any serial port have been initialized.
*/
void
tgt_display(char *msg, int x)
{
/* Have simple serial port driver */
tgt_putchar(msg[0]);
tgt_putchar(msg[1]);
tgt_putchar(msg[2]);
tgt_putchar(msg[3]);
tgt_putchar('\r');
tgt_putchar('\n');
}
void
clrhndlrs()
{
}
int
tgt_getmachtype()
{
return(md_cputype());
}
/*
* Create stubs if network is not compiled in
*/
#ifdef INET
void
tgt_netpoll()
{
splx(splhigh());
}
#else
extern void longjmp(label_t *, int);
void gsignal(label_t *jb, int sig);
void
gsignal(label_t *jb, int sig)
{
if(jb != NULL) {
longjmp(jb, 1);
}
};
int netopen (const char *, int);
int netread (int, void *, int);
int netwrite (int, const void *, int);
long netlseek (int, long, int);
int netioctl (int, int, void *);
int netclose (int);
int netopen(const char *p, int i) { return -1;}
int netread(int i, void *p, int j) { return -1;}
int netwrite(int i, const void *p, int j) { return -1;}
int netclose(int i) { return -1;}
long int netlseek(int i, long j, int k) { return -1;}
int netioctl(int j, int i, void *p) { return -1;}
void tgt_netpoll() {};
#endif /*INET*/
#define SPINSZ 0x800000
#define DEFTESTS 7
#define MOD_SZ 20
#define BAILOUT if (bail) goto skip_test;
#define BAILR if (bail) return;
/* memspeed operations */
#define MS_BCOPY 1
#define MS_COPY 2
#define MS_WRITE 3
#define MS_READ 4
char *tran_month(char *c, char *i)
{
switch (*c++){
case 'J':
if(*c++ == 'a') /* Jan */
i = "01";
else if(*c++ == 'n') /* June */
i = "06";
else /* July */
i = "07";
break;
case 'F': /* Feb */
i = "02";
break;
case 'M':
c++;
if(*c++ == 'r') /* Mar */
i = "03";
else /* May */
i = "05";
break;
case 'A':
if(*c++ == 'p') /* Apr */
i = "04";
else /* Aug */
i = "08";
break;
case 'S': /* Sept */
i = "09";
break;
case 'O': /* Oct */
i = "10";
break;
case 'N': /* Nov */
i = "11";
break;
case 'D': /* Dec */
i = "12";
break;
default :
i = NULL;
}
return i;
}
int get_update(char *p)
{
int i=0;
char *t,*mp,m[3];
t = strstr(vers, ":");
strncpy(p, t+26, 4); /* year */
p[4] = '-';
mp = tran_month(t+6, m); /* month */
strncpy(p+5,mp,2);
p[7]='-';
strncpy(p+8, t+10, 2); /* day */
p[10] = '\0';
return 0;
}
extern struct efi_memory_map_loongson g_map;
#include "../../../pmon/cmds/bootparam.h"
#include "../../../pmon/common/smbios/smbios.h"
struct efi_memory_map_loongson * init_memory_map()
{
struct efi_memory_map_loongson *emap = &g_map;
int i = 0;
unsigned long long size = memorysize_high;
#define EMAP_ENTRY(entry, node, type, start, size) \
emap->map[(entry)].node_id = (node), \
emap->map[(entry)].mem_type = (type), \
emap->map[(entry)].mem_start = (start), \
emap->map[(entry)].mem_size = (size), \
(entry)++
EMAP_ENTRY(i, 0, SYSTEM_RAM_LOW, 0x00200000, 0x0ee);
/* for entry with mem_size < 1M, we set bit31 to 1 to indicate
* that the unit in mem_size is Byte not MBype */
EMAP_ENTRY(i, 0, SMBIOS_TABLE, (SMBIOS_PHYSICAL_ADDRESS & 0x0fffffff),
(SMBIOS_SIZE_LIMIT | 0x80000000));
EMAP_ENTRY(i, 0, SYSTEM_RAM_HIGH, 0x90000000, size >> 20);
emap->vers = 0;
emap->nr_map = i;
return emap;
#undef EMAP_ENTRY
}