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.
3027 lines
74 KiB
3027 lines
74 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.
|
|
*
|
|
*/
|
|
|
|
#define STDIN ((kbd_available|usb_kbd_available)?3:0)
|
|
|
|
#include <include/stdarg.h>
|
|
unsigned int mem_size = 0;
|
|
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 <include/file.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 <pmon.h>
|
|
|
|
#include "../pci/amd_780e.h"
|
|
#include "../pci/rs780_cmn.h"
|
|
#include "../pci/sb700.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"
|
|
#if PCI_IDSEL_CS5536 != 0
|
|
#include <include/cs5536.h>
|
|
#endif
|
|
#if (NMOD_X86EMU_INT10 > 0)||(NMOD_X86EMU >0)
|
|
extern int vga_bios_init(void);
|
|
#endif
|
|
extern int radeon_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 + 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
|
|
|
|
int tgt_i2cread(int type,unsigned char *addr,int addrlen,unsigned char reg,unsigned char* buf ,int count);
|
|
int tgt_i2cwrite(int type,unsigned char *addr,int addrlen,unsigned char reg,unsigned char* buf ,int count);
|
|
extern struct trapframe DBGREG;
|
|
extern void *memset(void *, int, size_t);
|
|
|
|
int kbd_available;
|
|
int bios_available;
|
|
int usb_kbd_available;;
|
|
int vga_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);
|
|
|
|
#ifdef INTERFACE_3A780E
|
|
#define REV_ROW_LINE 560
|
|
#define INF_ROW_LINE 576
|
|
|
|
int afxIsReturnToPmon = 0;
|
|
|
|
struct FackTermDev
|
|
{
|
|
int dev;
|
|
};
|
|
|
|
#endif
|
|
#ifdef USE_GPIO_SERIAL
|
|
//modified by zhanghualiang
|
|
//this function is for parallel port to send and received data
|
|
//via GPIO
|
|
//GPIO bit 2 for Receive clk clk hight for request
|
|
//GPIO bit 3 for receive data
|
|
#define DBG
|
|
#define WAITSTART 10
|
|
#define START 20
|
|
#define HIBEGCLK 30
|
|
#define HINEXTCLK 40
|
|
#define LOWCLK 50
|
|
#define RXERROR 60
|
|
//static int zhlflg = 0;
|
|
static int
|
|
ppns16550 (int op, struct DevEntry *dev, unsigned long param, int data)
|
|
{
|
|
volatile ns16550dev *dp;
|
|
static int zhlflg = 0;
|
|
int crev,crevp,dat,datap,clk,clkp; //zhl begin
|
|
int cnt = 0;
|
|
int tick = 0;
|
|
int STAT = START;
|
|
int tmp;
|
|
char cget = 0;
|
|
crev = 0;
|
|
crevp = 0;
|
|
dat = 0;
|
|
datap = 0;
|
|
clk = 0;
|
|
clkp = 0;
|
|
cget = 0; //zhl end
|
|
|
|
dp = (ns16550dev *) dev->sio;
|
|
if(dp==-1)return 1;
|
|
switch (op) {
|
|
case OP_INIT:
|
|
return 1;
|
|
|
|
case OP_XBAUD:
|
|
case OP_BAUD:
|
|
return 0;
|
|
|
|
case OP_TXRDY:
|
|
return 1;
|
|
|
|
case OP_TX:
|
|
tgt_putchar(data);
|
|
break;
|
|
|
|
case OP_RXRDY:
|
|
tmp = *(volatile int *)(0xbfe0011c);
|
|
// tgt_printf("tmp=(%x)H, %d ",tmp,tmp);
|
|
tmp = tmp >> 18;
|
|
tmp = tmp & 1;
|
|
if (tmp)
|
|
{
|
|
// tgt_printf("pmon pmon pom pmon pomn pmon get signal ");
|
|
// tgt_putchar('O');
|
|
// tgt_putchar('K');
|
|
tgt_putchar(0x80);
|
|
// tgt_printf("\n");
|
|
}
|
|
return (tmp);
|
|
|
|
case OP_RX:
|
|
cget = 0;
|
|
cnt = 0;
|
|
tick = 0;
|
|
while (cnt < 8)
|
|
{
|
|
crevp = crev;
|
|
tmp = *(volatile int *)(0xbfe0011c);
|
|
// tgt_printf("pmon tmp=%x,\n",tmp);
|
|
tmp = tmp >> 18;
|
|
tmp = tmp & 3;
|
|
crev = tmp;
|
|
|
|
clkp = clk;
|
|
clk = crev & 1;
|
|
datap = dat;
|
|
dat = crev & 2;
|
|
dat = dat >> 1;
|
|
dat = dat & 1;
|
|
// if (clkp != clk)
|
|
// {
|
|
tick++;
|
|
if(tick>5000000)
|
|
{
|
|
// tgt_putchar(0x80);
|
|
return 10;
|
|
}
|
|
// tgt_printf("%d,%d\n",clk,dat);
|
|
// }
|
|
// continue;
|
|
switch(STAT)
|
|
{
|
|
case START:
|
|
if (clk == 0)
|
|
{
|
|
STAT = LOWCLK;
|
|
}
|
|
break;
|
|
|
|
case LOWCLK:
|
|
if(clk == 1)
|
|
{
|
|
STAT = HIBEGCLK;
|
|
}
|
|
break;
|
|
|
|
case HIBEGCLK:
|
|
dat = dat << cnt;
|
|
cget = cget | dat;
|
|
cnt++;
|
|
STAT = HINEXTCLK;
|
|
// tgt_printf("p c=%d, d=%d,\n",cnt,dat);
|
|
if (cnt == 8 )
|
|
{
|
|
do {
|
|
tmp = *(volatile int *)(0xbfe0011c);
|
|
tmp = tmp >> 18;
|
|
tmp = tmp & 1;
|
|
}
|
|
while(tmp);
|
|
/* { sl_tgt_putchar('p');
|
|
sl_tgt_putchar(' ');
|
|
sl_tgt_putchar('c');
|
|
sl_tgt_putchar('=');
|
|
sl_tgt_putchar(cget);
|
|
sl_tgt_putchar('\n');
|
|
} */
|
|
// tgt_printf(" ch = (%x)h,%d\n",cget,cget);
|
|
return cget;
|
|
}
|
|
break;
|
|
|
|
case HINEXTCLK:
|
|
if (clk == 0)
|
|
STAT = LOWCLK;
|
|
break;
|
|
|
|
case RXERROR:
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
case OP_RXSTOP:
|
|
return (0);
|
|
break;
|
|
}
|
|
return 0;
|
|
}
|
|
//end modification by zhanghualiang
|
|
#endif
|
|
|
|
|
|
|
|
ConfigEntry ConfigTable[] =
|
|
{
|
|
#ifdef HAVE_NB_SERIAL
|
|
#ifdef DEVBD2F_FIREWALL
|
|
{ (char *)LS2F_COMA_ADDR, 0, ns16550, 256, CONS_BAUD, NS16550HZ/2 },
|
|
#else
|
|
#ifdef USE_LPC_UART
|
|
{ (char *)COM3_BASE_ADDR, 0, ns16550, 256, CONS_BAUD, NS16550HZ },
|
|
#else
|
|
#ifdef USE_SB700_LPC_UART
|
|
{ (char *)0xb80003f8, 0, ns16550, 256, CONS_BAUD, NS16550HZ },
|
|
#else
|
|
{ (char *)GS3_UART_BASE, 0, ns16550, 256, CONS_BAUD, NS16550HZ },
|
|
#endif
|
|
#endif
|
|
#endif
|
|
#elif defined(USE_SM502_UART0)
|
|
{ (char *)0xb6030000, 0, ns16550, 256, CONS_BAUD, NS16550HZ/2 },
|
|
#elif defined(USE_GPIO_SERIAL)
|
|
{ (char *)COM1_BASE_ADDR, 0,ppns16550, 256, CONS_BAUD, NS16550HZ },
|
|
#else
|
|
{ (char *)COM1_BASE_ADDR, 0, ns16550, 256, CONS_BAUD, NS16550HZ/2 },
|
|
#endif
|
|
#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
|
|
#ifdef DEVBD2F_FIREWALL
|
|
{ (char *)LS2F_COMB_ADDR, 0, ns16550, 256, CONS_BAUD, NS16550HZ/2 ,1},
|
|
#endif
|
|
{ 0 }
|
|
};
|
|
|
|
unsigned long _filebase;
|
|
|
|
extern unsigned long long memorysize;
|
|
extern unsigned long long memorysize_high;
|
|
#ifdef MULTI_CHIP
|
|
extern unsigned long long memorysize_high_n1;
|
|
extern unsigned long long memorysize_high_n2;
|
|
extern unsigned long long memorysize_high_n3;
|
|
#endif
|
|
|
|
extern char MipsException[], MipsExceptionEnd[];
|
|
|
|
unsigned char hwethadr[6];
|
|
|
|
void initmips(unsigned int raw_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 euperio_reinit();
|
|
|
|
void
|
|
initmips(unsigned int raw_memsz)
|
|
{
|
|
int i;
|
|
int* io_addr;
|
|
unsigned long long memsz;
|
|
tgt_fpuenable();
|
|
#ifdef DEVBD2F_SM502
|
|
{
|
|
/*set lio bus to 16 bit*/
|
|
volatile int *p=0xbfe00108;
|
|
*p=((*p)&~(0x1f<<8))|(0x8<<8) |(1<<13);
|
|
}
|
|
#endif
|
|
//tgt_printf("memsz %d\n",memsz);
|
|
/*enable float*/
|
|
tgt_fpuenable();
|
|
//CPU_TLBClear(); /* Lc modify */
|
|
|
|
#if PCI_IDSEL_CS5536 != 0
|
|
superio_reinit();
|
|
#endif
|
|
memsz = raw_memsz & 0xff;
|
|
memsz = memsz << 29;
|
|
memsz = memsz - 0x1000000;
|
|
memsz = memsz >> 20;
|
|
/*
|
|
* 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
|
|
//memorysize = memsz > 256 ? 256 << 20 : memsz << 20;
|
|
//memorysize_high = memsz > 256 ? (memsz - 256) << 20 : 0;
|
|
memorysize = memsz > 240 ? 240 << 20 : memsz << 20;
|
|
memorysize_high = memsz > 240 ? (((unsigned long long)memsz) - 240) << 20 : 0;
|
|
mem_size = memsz;
|
|
|
|
#ifdef MULTI_CHIP
|
|
memsz = raw_memsz & 0xff00;
|
|
memsz = memsz >> 8;
|
|
memsz = memsz << 29;
|
|
memorysize_high_n1 = (memsz == 0) ? 0 : (memsz - (256 << 20));
|
|
tgt_printf("memorysize_high_n1 0x%llx\n", memorysize_high_n1);
|
|
#endif
|
|
#ifdef DUAL_3B
|
|
memsz = raw_memsz & 0xff0000;
|
|
memsz = memsz >> 16;
|
|
memsz = memsz << 29;
|
|
memorysize_high_n2 = (memsz == 0) ? 0 : (memsz - (256 << 20));
|
|
memsz = raw_memsz & 0xff000000;
|
|
memsz = memsz >> 24;
|
|
memsz = memsz << 29;
|
|
memorysize_high_n3 = (memsz == 0) ? 0 : (memsz - (256 << 20));
|
|
tgt_printf("memorysize_high_n2 0x%llx\n", memorysize_high_n2);
|
|
tgt_printf("memorysize_high_n3 0x%llx\n", memorysize_high_n3);
|
|
#endif
|
|
#if 0 /* whd : Disable gpu controller of MCP68 */
|
|
//*(unsigned int *)0xbfe809e8 = 0x122380;
|
|
//*(unsigned int *)0xbfe809e8 = 0x2280;
|
|
*(unsigned int *)0xba0009e8 = 0x2280;
|
|
#endif
|
|
|
|
#if 0 /* whd : Enable IDE controller of MCP68 */
|
|
*(unsigned int *)0xbfe83050 = (*(unsigned int *)0xbfe83050) | 0x2;
|
|
|
|
#endif
|
|
|
|
#if 0
|
|
asm(\
|
|
" sd %1,0x18(%0);;\n" \
|
|
" sd %2,0x28(%0);;\n" \
|
|
" sd %3,0x20(%0);;\n" \
|
|
::"r"(0xffffffffbff00000ULL),"r"(memorysize),"r"(memorysize_high),"r"(0x20000000)
|
|
:"$2"
|
|
);
|
|
#endif
|
|
|
|
#if 0
|
|
{
|
|
int start = 0x80000000;
|
|
int end = 0x80000000 + 16384;
|
|
|
|
while (start < end) {
|
|
__asm__ volatile (" cache 1,0(%0)\r\n"
|
|
" cache 1,1(%0)\r\n"
|
|
" cache 1,2(%0)\r\n"
|
|
" cache 1,3(%0)\r\n"
|
|
" cache 0,0(%0)\r\n"::"r"(start));
|
|
start += 32;
|
|
}
|
|
|
|
__asm__ volatile ( " mfc0 $2,$16\r\n"
|
|
" and $2, $2, 0xfffffff8\r\n"
|
|
" or $2, $2, 2\r\n"
|
|
" mtc0 $2, $16\r\n" :::"$2");
|
|
}
|
|
#endif
|
|
|
|
/*
|
|
* 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 PCI_IDSEL_VIA686B
|
|
if(getenv("powermg"))
|
|
{
|
|
pcitag_t mytag;
|
|
unsigned char data;
|
|
unsigned int addr;
|
|
mytag=_pci_make_tag(0,PCI_IDSEL_VIA686B,4);
|
|
data=_pci_conf_readn(mytag,0x41,1);
|
|
_pci_conf_writen(mytag,0x41,data|0x80,1);
|
|
addr=_pci_allocate_io(_pci_head,256);
|
|
printf("power management addr=%x\n",addr);
|
|
_pci_conf_writen(mytag,0x48,addr|1,4);
|
|
}
|
|
#endif
|
|
|
|
#if 0//HT BUS DEBUG whd
|
|
printf("HT-PCI header scan:\n");
|
|
io_addr = 0xbfe84000;
|
|
for(i=0 ;i < 16;i++)
|
|
{
|
|
printf("io_addr : 0x%8X = 0x%8X\n",io_addr, *io_addr);
|
|
io_addr = io_addr + 1;
|
|
}
|
|
|
|
//printf("BUS 9 scan:\n");
|
|
//io_addr = 0xbe090000;
|
|
//for(i=0 ;i < 16;i++)
|
|
//{
|
|
// printf("io_addr : 0x%X = 0x%X\n",io_addr, *io_addr);
|
|
// io_addr = io_addr + (1<<9);
|
|
//}
|
|
|
|
printf("PCI bus header scan:\n");
|
|
io_addr = 0xbe014800;
|
|
for(i=0 ;i < 16;i++)
|
|
{
|
|
printf("io_addr : 0x%8X = 0x%8X\n",io_addr, *io_addr);
|
|
io_addr = io_addr + 1;
|
|
}
|
|
|
|
//printf("write network IO space test\n");
|
|
//io_addr = 0xba00ffc0;
|
|
//for(i=0 ;i < 16;i++)
|
|
//{
|
|
// printf("io_addr : 0x%X = 0x%X\n",io_addr, *io_addr);
|
|
// io_addr = io_addr + 1;
|
|
//}
|
|
|
|
//io_addr = 0xba00ffc0;
|
|
//i = *io_addr;
|
|
// printf("io_addr : 0x%X = 0x%X\n",io_addr, i);
|
|
|
|
//i = i | 0x1000000;
|
|
//*io_addr = i;
|
|
// printf("io_addr : 0x%X = 0x%X\n",io_addr, *io_addr);
|
|
//
|
|
//printf("HT-SATA header scan:\n");
|
|
//io_addr = 0xbfe84800;
|
|
//for(i=0 ;i < 64;i++)
|
|
//{
|
|
// printf("io_addr : 0x%8X = 0x%8X\n",io_addr, *io_addr);
|
|
// io_addr = io_addr + 1;
|
|
//}
|
|
//printf("HT Register\n");
|
|
//io_addr = 0xbb000050;
|
|
//for(i=0 ;i < 1;i++)
|
|
//{
|
|
// printf("io_addr : 0x%X = 0x%X\n",io_addr, *io_addr);
|
|
// io_addr = io_addr + 1;
|
|
//}
|
|
#endif
|
|
|
|
/*
|
|
* Launch!
|
|
*/
|
|
_pci_conf_write(_pci_make_tag(0,0,0),0x90,0xff800000);
|
|
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);
|
|
|
|
extern int fb_init(unsigned long,unsigned long);
|
|
|
|
extern unsigned long long uma_memory_base;
|
|
extern unsigned long long uma_memory_size;
|
|
|
|
void tgt_devconfig()
|
|
{
|
|
int ic, len;
|
|
int count = 0;
|
|
char key;
|
|
char copyright[9] ="REV_";
|
|
char bootup[] = "Booting...";
|
|
char *tmp_copy = NULL;
|
|
char tmp_date[11];
|
|
char * s;
|
|
#if NMOD_VGACON > 0
|
|
int rc=1;
|
|
#if NMOD_FRAMEBUFFER > 0
|
|
unsigned long fbaddress,ioaddress;
|
|
extern struct pci_device *vga_dev;
|
|
#ifdef RS780E
|
|
int test;
|
|
int i;
|
|
// printf(" ==================== frame buffer test begin======================:%x \n" , test);
|
|
for (i = 0;i < 0x100000;i += 4)
|
|
{
|
|
//printf(" i = %x \n" , i);
|
|
*((volatile int *)(BONITO_PCILO_BASE_VA + i)) = i;
|
|
}
|
|
|
|
for (i = 0xffffc;i >= 0;i -= 4)
|
|
{
|
|
if (*((volatile int *)(BONITO_PCILO_BASE_VA + i)) != i)
|
|
{
|
|
//printf(" not equal ==== %x\n" ,i);
|
|
break;
|
|
}
|
|
}
|
|
|
|
// printf(" ==================== frame buffer test end======================:%x \n" , test);
|
|
|
|
|
|
#endif
|
|
#endif
|
|
#endif
|
|
_pci_devinit(1); /* PCI device initialization */
|
|
#if (NMOD_X86EMU_INT10 > 0)||(NMOD_X86EMU >0)
|
|
SBD_DISPLAY("VGAI", 0);
|
|
rc = vga_bios_init();
|
|
#endif
|
|
#if defined(VESAFB)
|
|
SBD_DISPLAY("VESA", 0);
|
|
if(rc > 0)
|
|
vesafb_init();
|
|
#endif
|
|
#if (NMOD_X86EMU_INT10 == 0 && defined(RADEON7000))
|
|
SBD_DISPLAY("VGAI", 0);
|
|
rc = radeon_init();
|
|
#endif
|
|
#if NMOD_FRAMEBUFFER > 0
|
|
vga_available=0;
|
|
if(!vga_dev) {
|
|
printf("ERROR !!! VGA device is not found\n");
|
|
rc = -1;
|
|
}
|
|
if (rc > 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
|
|
|
|
#if NMOD_SISFB
|
|
fbaddress=sisfb_init_module();
|
|
#endif
|
|
printf("fbaddress 0x%x\tioaddress 0x%x\n",fbaddress, ioaddress);
|
|
|
|
#if NMOD_SMI712 > 0
|
|
fbaddress |= 0xb0000000;
|
|
//ioaddress |= 0xbfd00000;
|
|
ioaddress |= BONITO_PCIIO_BASE_VA;
|
|
smi712_init((unsigned char *)fbaddress,(unsigned char *)ioaddress);
|
|
#endif
|
|
|
|
#if NMOD_SMI502 > 0
|
|
rc = video_hw_init ();
|
|
fbaddress =_pci_conf_read(vga_dev->pa.pa_tag,0x10);
|
|
ioaddress =_pci_conf_read(vga_dev->pa.pa_tag,0x14);
|
|
fbaddress |= 0xb0000000;
|
|
ioaddress |= 0xb0000000;
|
|
#endif
|
|
|
|
/* lwg add.
|
|
* The address mapped from 0x10000000 to 0xf800000
|
|
* wouldn't work through tlb.
|
|
_*/
|
|
#ifdef CONFIG_GFXUMA
|
|
fbaddress = 0x50000000; // virtual address mapped to the second 256M memory
|
|
#else
|
|
fbaddress = uma_memory_base | BONITO_PCILO_BASE_VA;
|
|
#endif
|
|
printf("fbaddress = %08x\n", fbaddress);
|
|
|
|
printf("begin fb_init\n");
|
|
fb_init(fbaddress, ioaddress);
|
|
printf("after fb_init\n");
|
|
|
|
} else {
|
|
printf("vga bios init failed, rc=%d\n",rc);
|
|
}
|
|
#endif
|
|
|
|
#if (NMOD_FRAMEBUFFER > 0) || (NMOD_VGACON > 0 )
|
|
if (rc > 0)
|
|
if(!getenv("novga")) vga_available=1;
|
|
else vga_available=0;
|
|
#endif
|
|
config_init();
|
|
configure();
|
|
//#if ((NMOD_VGACON >0) &&(PCI_IDSEL_VIA686B !=0)|| (PCI_IDSEL_CS5536 !=0))
|
|
#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
|
|
#ifdef INTERFACE_3A780E
|
|
|
|
vga_available = 1;
|
|
kbd_available=1;
|
|
bios_available = 1; //support usb_kbd in bios
|
|
// Ask user whether to set bios menu
|
|
printf("Press <Del> to set BIOS,waiting for 3 seconds here..... \n");
|
|
|
|
get_update(tmp_date);
|
|
len = strlen(tmp_date);
|
|
for (ic = 0; ic < 1; ic++){
|
|
video_putchar1(2 + (len+2)*8+ic*8, 560, tmp_date[ic]);
|
|
}
|
|
|
|
video_set_color(0xf);
|
|
|
|
// init_win_device();
|
|
|
|
vga_available = 0; //lwg close printf output
|
|
|
|
{
|
|
struct FackTermDev *devp;
|
|
int fd = 0;
|
|
DevEntry* p;
|
|
Msg msg; //==char msg
|
|
int sign = 0;
|
|
|
|
//get input without wait =========== add by oldtai
|
|
fd = ((FILE*)stdin)->fd;
|
|
devp = (struct FackTermDev *)(_file[fd].data);
|
|
p = &DevTable[devp->dev];
|
|
|
|
for (count = 0;count < 10;count++)
|
|
{
|
|
//get input without wait
|
|
scandevs();
|
|
|
|
while(!tgt_smplock());
|
|
|
|
/* 'DEL' to BIOS Interface */
|
|
if(p->rxq->count >= 3){
|
|
if ((p->rxq->dat[p->rxq->first + p->rxq->count-3] == 0x1b)
|
|
&& (p->rxq->dat[p->rxq->first + p->rxq->count-2] == '[')
|
|
&& (p->rxq->dat[p->rxq->first + p->rxq->count-1] == 'G')) {
|
|
sign = 1;
|
|
p->rxq->count -= 3;
|
|
}
|
|
if (sign == 1) {
|
|
tgt_smpunlock();
|
|
break;
|
|
}
|
|
}
|
|
tgt_smpunlock();
|
|
|
|
//delay1(30);
|
|
/*If you want to Press <Del> to set BIOS open it(from 0 to 1)*/
|
|
#if 1
|
|
delay1(300);
|
|
#endif
|
|
}
|
|
|
|
vga_available = 1;
|
|
video_set_color(0xf);
|
|
|
|
for (ic = 0; ic < 64; ic++)
|
|
{
|
|
video_putchar1(2 + ic*8, REV_ROW_LINE, ' ');
|
|
video_putchar1(2 + ic*8, INF_ROW_LINE, ' ');
|
|
}
|
|
|
|
vga_available = 0;
|
|
|
|
if (count >= 10)
|
|
goto run;
|
|
else
|
|
goto bios;
|
|
|
|
bios:
|
|
|
|
if(!(s = getenv("SHOW_DISPLAY")) || s[0] !='2')
|
|
{
|
|
char buf[10];
|
|
video_set_color(0xf);
|
|
video_set_color(0x8);
|
|
tty_flush();
|
|
vga_available = 1;
|
|
do_cmd("main");
|
|
if (!afxIsReturnToPmon)
|
|
{
|
|
vga_available = 0;
|
|
}
|
|
}
|
|
|
|
run:
|
|
vga_available = 1;
|
|
bios_available = 0;//support usb_kbd in bios
|
|
kbd_available = 1;
|
|
|
|
len = strlen(bootup);
|
|
for (ic = 0; ic < len; ic++)
|
|
{
|
|
video_putchar1(2 + ic*8, INF_ROW_LINE,bootup[ic]);
|
|
}
|
|
}
|
|
#endif
|
|
printf("devconfig done.\n");
|
|
|
|
sb700_interrupt_fixup();
|
|
}
|
|
|
|
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 cs5536_gpio_init(void);
|
|
extern void test_gpio_function(void);
|
|
extern void cs5536_pci_fixup(void);
|
|
|
|
#if PCI_IDSEL_SB700 != 0
|
|
static int w83627_read(int dev,int addr)
|
|
{
|
|
int data;
|
|
#if 0
|
|
/*enter*/
|
|
outb(0xbfd0002e,0x87);
|
|
outb(0xbfd0002e,0x87);
|
|
/*select logic dev reg */
|
|
outb(0xbfd0002e,0x7);
|
|
outb(0xbfd0002f,dev);
|
|
/*access reg */
|
|
outb(0xbfd0002e,addr);
|
|
data=inb(0xbfd0002f);
|
|
/*exit*/
|
|
outb(0xbfd0002e,0xaa);
|
|
outb(0xbfd0002e,0xaa);
|
|
#endif
|
|
/*enter*/
|
|
outb(BONITO_PCIIO_BASE_VA + 0x002e,0x87);
|
|
outb(BONITO_PCIIO_BASE_VA + 0x002e,0x87);
|
|
/*select logic dev reg */
|
|
outb(BONITO_PCIIO_BASE_VA + 0x002e,0x7);
|
|
outb(BONITO_PCIIO_BASE_VA + 0x002f,dev);
|
|
/*access reg */
|
|
outb(BONITO_PCIIO_BASE_VA + 0x002e,addr);
|
|
data=inb(BONITO_PCIIO_BASE_VA + 0x002f);
|
|
/*exit*/
|
|
outb(BONITO_PCIIO_BASE_VA + 0x002e,0xaa);
|
|
outb(BONITO_PCIIO_BASE_VA + 0x002e,0xaa);
|
|
return data;
|
|
}
|
|
|
|
static void w83627_write(int dev,int addr,int data)
|
|
{
|
|
#if 0
|
|
/*enter*/
|
|
outb(0xbfd0002e,0x87);
|
|
outb(0xbfd0002e,0x87);
|
|
/*select logic dev reg */
|
|
outb(0xbfd0002e,0x7);
|
|
outb(0xbfd0002f,dev);
|
|
/*access reg */
|
|
outb(0xbfd0002e,addr);
|
|
outb(0xbfd0002f,data);
|
|
/*exit*/
|
|
outb(0xbfd0002e,0xaa);
|
|
outb(0xbfd0002e,0xaa);
|
|
#endif
|
|
/*enter*/
|
|
outb(BONITO_PCIIO_BASE_VA + 0x002e,0x87);
|
|
outb(BONITO_PCIIO_BASE_VA + 0x002e,0x87);
|
|
/*select logic dev reg */
|
|
outb(BONITO_PCIIO_BASE_VA + 0x002e,0x7);
|
|
outb(BONITO_PCIIO_BASE_VA + 0x002f,dev);
|
|
/*access reg */
|
|
outb(BONITO_PCIIO_BASE_VA + 0x002e,addr);
|
|
outb(BONITO_PCIIO_BASE_VA + 0x002f,data);
|
|
/*exit*/
|
|
outb(BONITO_PCIIO_BASE_VA + 0x002e,0xaa);
|
|
outb(BONITO_PCIIO_BASE_VA + 0x002e,0xaa);
|
|
}
|
|
#endif
|
|
|
|
#if PCI_IDSEL_CS5536 != 0
|
|
static int w83627_read(int dev,int addr)
|
|
{
|
|
int data;
|
|
#if 0
|
|
/*enter*/
|
|
outb(0xbfd0002e,0x87);
|
|
outb(0xbfd0002e,0x87);
|
|
/*select logic dev reg */
|
|
outb(0xbfd0002e,0x7);
|
|
outb(0xbfd0002f,dev);
|
|
/*access reg */
|
|
outb(0xbfd0002e,addr);
|
|
data=inb(0xbfd0002f);
|
|
/*exit*/
|
|
outb(0xbfd0002e,0xaa);
|
|
outb(0xbfd0002e,0xaa);
|
|
#endif
|
|
/*enter*/
|
|
outb(BONITO_PCIIO_BASE_VA + 0x002e,0x87);
|
|
outb(BONITO_PCIIO_BASE_VA + 0x002e,0x87);
|
|
/*select logic dev reg */
|
|
outb(BONITO_PCIIO_BASE_VA + 0x002e,0x7);
|
|
outb(BONITO_PCIIO_BASE_VA + 0x002f,dev);
|
|
/*access reg */
|
|
outb(BONITO_PCIIO_BASE_VA + 0x002e,addr);
|
|
data=inb(BONITO_PCIIO_BASE_VA + 0x002f);
|
|
/*exit*/
|
|
outb(BONITO_PCIIO_BASE_VA + 0x002e,0xaa);
|
|
outb(BONITO_PCIIO_BASE_VA + 0x002e,0xaa);
|
|
return data;
|
|
}
|
|
|
|
static void w83627_write(int dev,int addr,int data)
|
|
{
|
|
#if 0
|
|
/*enter*/
|
|
outb(0xbfd0002e,0x87);
|
|
outb(0xbfd0002e,0x87);
|
|
/*select logic dev reg */
|
|
outb(0xbfd0002e,0x7);
|
|
outb(0xbfd0002f,dev);
|
|
/*access reg */
|
|
outb(0xbfd0002e,addr);
|
|
outb(0xbfd0002f,data);
|
|
/*exit*/
|
|
outb(0xbfd0002e,0xaa);
|
|
outb(0xbfd0002e,0xaa);
|
|
#endif
|
|
/*enter*/
|
|
outb(BONITO_PCIIO_BASE_VA + 0x002e,0x87);
|
|
outb(BONITO_PCIIO_BASE_VA + 0x002e,0x87);
|
|
/*select logic dev reg */
|
|
outb(BONITO_PCIIO_BASE_VA + 0x002e,0x7);
|
|
outb(BONITO_PCIIO_BASE_VA + 0x002f,dev);
|
|
/*access reg */
|
|
outb(BONITO_PCIIO_BASE_VA + 0x002e,addr);
|
|
outb(BONITO_PCIIO_BASE_VA + 0x002f,data);
|
|
/*exit*/
|
|
outb(BONITO_PCIIO_BASE_VA + 0x002e,0xaa);
|
|
outb(BONITO_PCIIO_BASE_VA + 0x002e,0xaa);
|
|
}
|
|
#endif
|
|
#if PCI_IDSEL_SB700 != 0
|
|
static void superio_reinit()
|
|
{
|
|
w83627_write(0,0x24,0xc1);
|
|
|
|
w83627_write(5,0x30,1);
|
|
w83627_write(5,0x60,0);
|
|
w83627_write(5,0x61,0x60);
|
|
w83627_write(5,0x62,0);
|
|
w83627_write(5,0x63,0x64);
|
|
w83627_write(5,0x70,1);
|
|
w83627_write(5,0x72,0xc);
|
|
w83627_write(5,0xf0,0x80);
|
|
|
|
//w83627_UART1
|
|
w83627_write(2,0x30,0x01);
|
|
w83627_write(2,0x60,0x03);
|
|
w83627_write(2,0x61,0xf8);
|
|
w83627_write(2,0x70,0x04);
|
|
w83627_write(2,0xf0,0x00);
|
|
|
|
//w83627_UART2
|
|
w83627_write(3,0x30,0x01);
|
|
w83627_write(3,0x60,0x02);
|
|
w83627_write(3,0x61,0xf8);
|
|
w83627_write(3,0x70,0x03);
|
|
w83627_write(3,0xf0,0x00);
|
|
|
|
////w83627_PALLPort
|
|
w83627_write(1,0x30,0x01);
|
|
w83627_write(1,0x60,0x03);
|
|
w83627_write(1,0x61,0x78);
|
|
w83627_write(1,0x70,0x07);
|
|
w83627_write(1,0x74,0x04);
|
|
w83627_write(1,0xf0,0xF0);
|
|
}
|
|
#endif
|
|
|
|
#if PCI_IDSEL_CS5536 != 0
|
|
static void superio_reinit()
|
|
{
|
|
w83627_write(0,0x24,0xc1);
|
|
w83627_write(5,0x30,1);
|
|
w83627_write(5,0x60,0);
|
|
w83627_write(5,0x61,0x60);
|
|
w83627_write(5,0x62,0);
|
|
w83627_write(5,0x63,0x64);
|
|
w83627_write(5,0x70,1);
|
|
w83627_write(5,0x72,0xc);
|
|
w83627_write(5,0xf0,0x80);
|
|
_wrmsr(GET_MSR_ADDR(0x5140001F), 0, 0);//no keyboard emulation
|
|
|
|
#ifdef USE_CS5536_UART
|
|
//w83627_UART1
|
|
w83627_write(2,0x30,0x01);
|
|
w83627_write(2,0x60,0x03);
|
|
w83627_write(2,0x61,0xe8);
|
|
w83627_write(2,0x70,0x04);
|
|
w83627_write(2,0xf0,0x00);
|
|
|
|
//w83627_UART2
|
|
w83627_write(3,0x30,0x01);
|
|
w83627_write(3,0x60,0x02);
|
|
w83627_write(3,0x61,0xe8);
|
|
w83627_write(3,0x70,0x03);
|
|
w83627_write(3,0xf0,0x00);
|
|
#else
|
|
//w83627_UART1
|
|
w83627_write(2,0x30,0x01);
|
|
w83627_write(2,0x60,0x03);
|
|
w83627_write(2,0x61,0xf8);
|
|
w83627_write(2,0x70,0x04);
|
|
w83627_write(2,0xf0,0x00);
|
|
|
|
//w83627_UART2
|
|
w83627_write(3,0x30,0x01);
|
|
w83627_write(3,0x60,0x02);
|
|
w83627_write(3,0x61,0xf8);
|
|
w83627_write(3,0x70,0x03);
|
|
w83627_write(3,0xf0,0x00);
|
|
#endif
|
|
|
|
////w83627_PALLPort
|
|
w83627_write(1,0x30,0x01);
|
|
w83627_write(1,0x60,0x03);
|
|
w83627_write(1,0x61,0x78);
|
|
w83627_write(1,0x70,0x07);
|
|
w83627_write(1,0x74,0x04);
|
|
w83627_write(1,0xf0,0xF0);
|
|
ConfigTable[0].flag=1;//reinit serial
|
|
}
|
|
#endif
|
|
|
|
void
|
|
tgt_devinit()
|
|
{
|
|
int value;
|
|
|
|
#if (PCI_IDSEL_VIA686B != 0)
|
|
SBD_DISPLAY("686I",0);
|
|
|
|
vt82c686_init();
|
|
#endif
|
|
|
|
#if (PCI_IDSEL_CS5536 != 0)
|
|
SBD_DISPLAY("5536",0);
|
|
cs5536_init();
|
|
#endif
|
|
|
|
tgt_printf("rs780_early_setup\n");
|
|
rs780_early_setup();
|
|
|
|
tgt_printf("sb700_early_setup\n");
|
|
sb700_early_setup();
|
|
tgt_printf("rs780_before_pci_fixup\n");
|
|
rs780_before_pci_fixup();
|
|
tgt_printf("sb700_before_pci_fixup\n");
|
|
sb700_before_pci_fixup();
|
|
tgt_printf("rs780_enable\n");
|
|
//vga test
|
|
//rs780_enable(_pci_make_tag(0, 0, 0));
|
|
//rs780_enable(_pci_make_tag(0, 1, 0));
|
|
rs780_after_pci_fixup(); //name dug
|
|
tgt_printf("sb700_enable\n");
|
|
sb700_enable();
|
|
|
|
#if 1
|
|
tgt_printf("disable bus0 device pcie bridges\n");
|
|
//disable bus0 device 3 pci bridges (dev2 to dev7, dev9-dev10)
|
|
//dev 2 and dev3 should not be open otherwise the vga could not work
|
|
//==by oldtai
|
|
set_nbmisc_enable_bits(_pci_make_tag(0,0,0), 0x0c,(1<<2|1<<3|1<<5|1<<6|1<<7|1<<17),
|
|
(0<<2|0<<3|1<<5|1<<6|1<<7|0<<17));
|
|
#endif
|
|
|
|
#ifndef USE_780E_VGA
|
|
tgt_printf("disable internal graphics\n");
|
|
//disable internal graphics
|
|
set_nbcfg_enable_bits_8(_pci_make_tag(0,0,0), 0x7c, 1, 1);
|
|
#endif
|
|
|
|
#if 1
|
|
//SBD_DISPLAY("disable OHCI and EHCI controller",0);
|
|
//disable OHCI and EHCI controller
|
|
tgt_printf("disable OHCI and EHCI controller\n");
|
|
_pci_conf_write8(_pci_make_tag(0,0x14, 0), 0x68, 0x0);
|
|
#endif
|
|
|
|
#if 1
|
|
/* usb enable,68h
|
|
1<<0:usb1 ohci0 enable
|
|
1<<1:usb1 ohci1 enable
|
|
1<<2:usb1 ehci enable
|
|
1<<3:reserved
|
|
1<<4:usb2 ohci0 enable
|
|
1<<5:usb2 ohci1 enable
|
|
1<<6:usb2 ehci enable
|
|
1<<7:usb3 ohci enable */
|
|
tgt_printf("enable OHCI controller\n");
|
|
_pci_conf_write8(_pci_make_tag(0,0x14, 0), 0x68, (1<<0)|(1<<1)|(1<<4)|(1<<5)|(1<<7));
|
|
// _pci_conf_write8(_pci_make_tag(0,0x14, 0), 0x68, (1<<0));
|
|
#endif
|
|
|
|
|
|
#ifndef ENABLE_SATA
|
|
//SBD_DISPLAY("disable data",0);
|
|
//disable sata
|
|
tgt_printf("disable sata\n");
|
|
value = _pci_conf_read32(_pci_make_tag(0, 0x14, 0), 0xac);
|
|
value &= ~(1 << 8);
|
|
_pci_conf_write32(_pci_make_tag(0, 0x14, 0), 0xac, value);
|
|
#endif
|
|
|
|
|
|
/*
|
|
* Gather info about and configure caches.
|
|
*/
|
|
if(getenv("ocache_off")) {
|
|
CpuOnboardCacheOn = 0;
|
|
}
|
|
else {
|
|
CpuOnboardCacheOn = 1;
|
|
}
|
|
if(getenv("ecache_off")) {
|
|
CpuExternalCacheOn = 0;
|
|
}
|
|
else {
|
|
CpuExternalCacheOn = 1;
|
|
}
|
|
|
|
#if 1
|
|
CPU_ConfigCache();
|
|
#else
|
|
{
|
|
#define CTYPE_HAS_L2 0x100
|
|
CpuPrimaryInstCacheSize = 64<<10;
|
|
CpuPrimaryInstCacheLSize = 32;
|
|
CpuPrimaryInstSetSize = (64<<10)/32/4;
|
|
CpuPrimaryDataCacheSize = 64<<10;
|
|
CpuPrimaryDataCacheLSize = 32;;
|
|
CpuPrimaryDataSetSize = (64<<10)/32/4;
|
|
//CpuCacheAliasMask ;
|
|
CpuSecondaryCacheSize = ((1024*4)<<10);
|
|
CpuTertiaryCacheSize = 0;
|
|
CpuNWayCache = 4;
|
|
CpuCacheType = CTYPE_HAS_L2 ; /* R4K, R5K, RM7K */
|
|
//CpuConfigRegister;
|
|
//CpuStatusRegister;
|
|
//CpuExternalCacheOn; /* R5K, RM7K */
|
|
//CpuOnboardCacheOn; /* RM7K */
|
|
|
|
//printf("whd:2\n");
|
|
//CPU_FlushCache();
|
|
//printf("whd:3\n");
|
|
asm volatile("mfc0 $4, $16\n"
|
|
"and $4,0xfffffff8\n"
|
|
"or $4,0x3\n"
|
|
"mtc0 $4,$16\n":::"a0");
|
|
|
|
//printf("whd:4\n");
|
|
#if 0
|
|
unsigned long config1, config2, lsize, linesz, sets, ways;
|
|
asm(".word 0x40028001\n":"=r"(config2));
|
|
if ((lsize = ((config2 >> 4) & 15)))
|
|
linesz = 2 << lsize;
|
|
else
|
|
linesz = lsize;
|
|
|
|
sets = 64 << ((config2 >> 8) & 15);
|
|
ways = 1 + ((config2 ) & 15);
|
|
|
|
CPUSecondaryCacheSize = sets * ways * linesz;
|
|
#endif
|
|
}
|
|
#endif
|
|
superio_reinit();
|
|
uart_init();
|
|
|
|
_pci_businit(1); /* PCI bus initialization */
|
|
#if defined(VIA686B_POWERFIXUP) && (PCI_IDSEL_VIA686B != 0)
|
|
if(getenv("noautopower")) vt82c686_powerfixup();
|
|
#endif
|
|
|
|
#if (PCI_IDSEL_CS5536 != 0)
|
|
cs5536_pci_fixup();
|
|
#endif
|
|
tgt_printf("sb700_after_pci_fixup\n");
|
|
sb700_after_pci_fixup();
|
|
}
|
|
|
|
|
|
#ifdef DEVBD2F_CS5536
|
|
void
|
|
tgt_reboot()
|
|
{
|
|
unsigned long hi, lo;
|
|
|
|
/* reset the cs5536 whole chip */
|
|
_rdmsr(0xe0000014, &hi, &lo);
|
|
lo |= 0x00000001;
|
|
_wrmsr(0xe0000014, hi, lo);
|
|
|
|
while(1);
|
|
}
|
|
|
|
void
|
|
tgt_poweroff()
|
|
{
|
|
unsigned long val;
|
|
unsigned long tag;
|
|
unsigned long base;
|
|
|
|
tag = _pci_make_tag(0, 14, 0);
|
|
base = _pci_conf_read(tag, 0x14);
|
|
//base |= 0xbfd00000;
|
|
base |= BONITO_PCIIO_BASE_VA;
|
|
base &= ~3;
|
|
|
|
/* make cs5536 gpio13 output enable */
|
|
val = *(volatile unsigned long *)(base + 0x04);
|
|
val = ( val & ~(1 << (16 + 13)) ) | (1 << 13) ;
|
|
*(volatile unsigned long *)(base + 0x04) = val;
|
|
|
|
/* make cs5536 gpio13 output low level voltage. */
|
|
val = *(volatile unsigned long *)(base + 0x00);
|
|
val = (val | (1 << (16 + 13))) & ~(1 << 13);
|
|
*(volatile unsigned long *)(base + 0x00) = val;
|
|
|
|
while(1);
|
|
}
|
|
#else
|
|
static void delay(int j)
|
|
{
|
|
volatile int i, k;
|
|
|
|
for(k = 0; k < j; k++)
|
|
for(i = 0; i < 1000; i++);
|
|
|
|
}
|
|
|
|
void
|
|
tgt_poweroff()
|
|
{
|
|
char * watch_dog_base = 0xb8000cd6;
|
|
char * watch_dog_config = 0xba00a041;
|
|
unsigned int * watch_dog_mem = 0xbe010000;
|
|
unsigned char * reg_cf9 = (unsigned char *)0xb8000cf9;
|
|
|
|
delay(100);
|
|
*reg_cf9 = 4;
|
|
|
|
/* enable WatchDogTimer */
|
|
delay(100);
|
|
* watch_dog_base = 0x69;
|
|
*(watch_dog_base + 1) = 0x0;
|
|
|
|
/* set WatchDogTimer base address is 0x10000 */
|
|
delay(100);
|
|
* watch_dog_base = 0x6c;
|
|
*(watch_dog_base + 1) = 0x0;
|
|
|
|
delay(100);
|
|
* watch_dog_base = 0x6d;
|
|
*(watch_dog_base + 1) = 0x0;
|
|
|
|
delay(100);
|
|
* watch_dog_base = 0x6e;
|
|
*(watch_dog_base + 1) = 0x1;
|
|
|
|
delay(100);
|
|
* watch_dog_base = 0x6f;
|
|
*(watch_dog_base + 1) = 0x0;
|
|
|
|
delay(100);
|
|
* watch_dog_config = 0xff;
|
|
|
|
/* set WatchDogTimer to starting */
|
|
delay(100);
|
|
* watch_dog_mem = 0x05;
|
|
delay(100);
|
|
*(watch_dog_mem + 1) = 0x1000;
|
|
delay(100);
|
|
* watch_dog_mem = 0x85;
|
|
|
|
|
|
}
|
|
void tgt_reboot(void)
|
|
{
|
|
watchdog_enable();
|
|
}
|
|
#endif
|
|
|
|
|
|
/*
|
|
* 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("[[[[[[[2009 Loongson][[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[\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;
|
|
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);
|
|
year = year%16 + year/16*10;
|
|
month = month%16 + month/16*10;
|
|
date = date%16 + date/16*10;
|
|
hour = hour%16 + hour/16*10;
|
|
min = min%16 + min/16*10;
|
|
sec = sec%16 + sec/16*10;
|
|
CMOS_WRITE(DS_CTLB_24 | DS_CTLB_DM, DS_REG_CTLB);
|
|
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;
|
|
|
|
#if defined(DEVBD2F_VIA)||defined(DEVBD2F_CS5536)||defined(DEVBD2F_EVA)
|
|
linux_outb_p(addr, 0x70);
|
|
val = linux_inb_p(0x71);
|
|
#elif defined(DEVBD2F_SM502)
|
|
|
|
pcitag_t tag;
|
|
unsigned char value;
|
|
char i2caddr[]={(unsigned char)0x64};
|
|
if(addr >= 0x0a)
|
|
return 0;
|
|
switch(addr)
|
|
{
|
|
case 0:
|
|
break;
|
|
case 2:
|
|
addr = 1;
|
|
break;
|
|
case 4:
|
|
addr = 2;
|
|
break;
|
|
case 6:
|
|
addr = 3;
|
|
break;
|
|
case 7:
|
|
addr = 4;
|
|
break;
|
|
case 8:
|
|
addr = 5;
|
|
break;
|
|
case 9:
|
|
addr = 6;
|
|
break;
|
|
|
|
}
|
|
|
|
tgt_i2cread(I2C_SINGLE,i2caddr,1,0xe<<4,&value,1);
|
|
value = value|0x20;
|
|
tgt_i2cwrite(I2C_SINGLE,i2caddr,1,0xe<<4,&value,1);
|
|
tgt_i2cread(I2C_SINGLE,i2caddr,1,addr<<4,&val,1);
|
|
tmp1 = ((val>>4)&0x0f)*10;
|
|
tmp2 = val&0x0f;
|
|
val = tmp1 + tmp2;
|
|
|
|
#elif defined(DEVBD2F_FIREWALL)
|
|
char i2caddr[]={0xde,0};
|
|
if(addr >= 0x0a)
|
|
return 0;
|
|
switch(addr)
|
|
{
|
|
case 0:
|
|
addr= 0x30;
|
|
break;
|
|
case 2:
|
|
addr = 0x31;
|
|
break;
|
|
case 4:
|
|
addr = 0x32;
|
|
break;
|
|
case 6:
|
|
addr = 0x36;
|
|
break;
|
|
case 7:
|
|
addr = 0x33;
|
|
break;
|
|
case 8:
|
|
addr = 0x34;
|
|
break;
|
|
case 9:
|
|
addr = 0x35;
|
|
break;
|
|
|
|
}
|
|
#ifndef GPIO_I2C
|
|
//atp8620_i2c_read(0xde,addr,&tmp,1);
|
|
#else
|
|
tgt_i2cread(I2C_SINGLE,i2caddr,2,addr,&tmp,1);
|
|
#endif
|
|
if(addr == 0x32)
|
|
tmp = tmp&0x7f;
|
|
val = ((tmp>>4)&0x0f)*10;
|
|
val = val + (tmp&0x0f);
|
|
#endif
|
|
|
|
return val;
|
|
}
|
|
|
|
static inline void CMOS_WRITE(unsigned char val, unsigned char addr)
|
|
{
|
|
|
|
char a;
|
|
#if defined(DEVBD2F_VIA)||defined(DEVBD2F_CS5536)||defined(DEVBD2F_EVA)
|
|
linux_outb_p(addr, 0x70);
|
|
linux_outb_p(val, 0x71);
|
|
|
|
#elif defined(DEVBD2F_SM502)
|
|
|
|
unsigned char tmp1,tmp2;
|
|
volatile int tmp;
|
|
char i2caddr[]={(unsigned char)0x64};
|
|
tmp1 = (val/10)<<4;
|
|
tmp2 = (val%10);
|
|
val = tmp1|tmp2;
|
|
if(addr >=0x0a)
|
|
return 0;
|
|
switch(addr)
|
|
{
|
|
case 0:
|
|
break;
|
|
case 2:
|
|
addr = 1;
|
|
break;
|
|
case 4:
|
|
addr = 2;
|
|
break;
|
|
case 6:
|
|
addr = 3;
|
|
break;
|
|
case 7:
|
|
addr = 4;
|
|
break;
|
|
case 8:
|
|
addr = 5;
|
|
break;
|
|
case 9:
|
|
addr = 6;
|
|
break;
|
|
|
|
}
|
|
{
|
|
unsigned char value;
|
|
|
|
tgt_i2cread(I2C_SINGLE,i2caddr,1,0xe<<4,&value,1);
|
|
value = value|0x20;
|
|
tgt_i2cwrite(I2C_SINGLE,i2caddr,1,0xe<<4,&value,1);
|
|
tgt_i2cwrite(I2C_SINGLE,i2caddr,1,addr<<4,&val,1);
|
|
}
|
|
|
|
#elif defined(DEVBD2F_FIREWALL)
|
|
unsigned char tmp;
|
|
char i2caddr[]={0xde,0,0};
|
|
if(addr >= 0x0a)
|
|
return 0;
|
|
switch(addr)
|
|
{
|
|
case 0:
|
|
addr= 0x30;
|
|
break;
|
|
case 2:
|
|
addr = 0x31;
|
|
break;
|
|
case 4:
|
|
addr = 0x32;
|
|
break;
|
|
case 6:
|
|
addr = 0x36;
|
|
break;
|
|
case 7:
|
|
addr = 0x33;
|
|
break;
|
|
case 8:
|
|
addr = 0x34;
|
|
break;
|
|
case 9:
|
|
addr = 0x35;
|
|
break;
|
|
|
|
}
|
|
|
|
tmp = (val/10)<<4;
|
|
val = tmp|(val%10);
|
|
#ifndef GPIO_I2C
|
|
atp8620_i2c_write(0xde,addr,&val,1);
|
|
#else
|
|
a = 2;
|
|
tgt_i2cwrite(I2C_SINGLE,i2caddr,2,0x3f,&a,1);
|
|
a = 6;
|
|
tgt_i2cwrite(I2C_SINGLE,i2caddr,2,0x3f,&a,1);
|
|
tgt_i2cwrite(I2C_SINGLE,i2caddr,2,addr,&tmp,1);
|
|
#endif
|
|
#endif
|
|
}
|
|
|
|
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
|
|
#ifdef DEVBD2F_FIREWALL
|
|
{
|
|
extern void __main();
|
|
char tmp;
|
|
char i2caddr[]={0xde};
|
|
tgt_i2cread(I2C_SINGLE,i2caddr,2,0x3f,&tmp,1);
|
|
/*
|
|
* bit0:Battery is run out ,please replace the rtc battery
|
|
* bit4:Rtc oscillator is no operating,please reset the machine
|
|
*/
|
|
tgt_printf("0x3f value %x\n",tmp);
|
|
init_legacy_rtc();
|
|
tgt_i2cread(I2C_SINGLE,i2caddr,2,0x14,&tmp,1);
|
|
tgt_printf("0x14 value %x\n",tmp);
|
|
}
|
|
#else
|
|
init_legacy_rtc();
|
|
#endif
|
|
|
|
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;
|
|
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)||(cur !=((sec+1)%60))) && (CPU_GetCOUNT() - cnt<0x30000000));
|
|
} while(timeout != 0 && (cur == sec));
|
|
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 ctrlbsave;
|
|
time_t t;
|
|
int year, month, date, hour, min, sec, wday;
|
|
/*gx 2005-01-17 */
|
|
//return 0;
|
|
|
|
#ifdef HAVE_TOD
|
|
if(!clk_invalid) {
|
|
ctrlbsave = CMOS_READ(DS_REG_CTLB);
|
|
CMOS_WRITE(ctrlbsave | DS_CTLB_SET, DS_REG_CTLB);
|
|
year = CMOS_READ(DS_REG_YEAR);
|
|
month = CMOS_READ(DS_REG_MONTH);
|
|
month = CMOS_READ(DS_REG_MONTH);
|
|
date = CMOS_READ(DS_REG_DATE);
|
|
wday = CMOS_READ(DS_REG_WDAY);
|
|
hour = CMOS_READ(DS_REG_HOUR);
|
|
min = CMOS_READ(DS_REG_MIN);
|
|
sec = CMOS_READ(DS_REG_SEC);
|
|
|
|
year = year%16 + year/16*10;
|
|
if(year < 50) year += 100;
|
|
month = (month%16 + month/16*10) - 1;
|
|
wday = wday%16 + wday/16*10;
|
|
date = date%16 + date/16*10;
|
|
hour = hour%16 + hour/16*10;
|
|
min = min%16 + min/16*10;
|
|
sec = sec%16 + sec/16*10;
|
|
tm.tm_sec = sec;
|
|
tm.tm_min = min;
|
|
tm.tm_hour = hour;
|
|
tm.tm_wday = wday;
|
|
tm.tm_mday = date;
|
|
tm.tm_mon = month;
|
|
tm.tm_year = year;
|
|
|
|
CMOS_WRITE(ctrlbsave & ~DS_CTLB_SET, DS_REG_CTLB);
|
|
|
|
tm.tm_isdst = tm.tm_gmtoff = 0;
|
|
t = gmmktime(&tm);
|
|
}
|
|
else
|
|
#endif
|
|
{
|
|
t = 957960000; /* Wed May 10 14:00:00 2000 :-) */
|
|
}
|
|
return(t);
|
|
|
|
}
|
|
|
|
char gpio_i2c_settime(struct tm *tm);
|
|
|
|
/*
|
|
* Set the current time if a TOD clock is present
|
|
*/
|
|
void
|
|
tgt_settime(time_t t)
|
|
{
|
|
struct tm *tm;
|
|
int ctrlbsave;
|
|
#ifdef HAVE_TOD
|
|
if(!clk_invalid) {
|
|
tm = gmtime(&t);
|
|
#ifndef DEVBD2F_FIREWALL
|
|
ctrlbsave = CMOS_READ(DS_REG_CTLB);
|
|
CMOS_WRITE(ctrlbsave | DS_CTLB_SET, DS_REG_CTLB);
|
|
|
|
CMOS_WRITE((((tm->tm_year) % 100)/10*16 + ((tm->tm_year) % 100)%10), DS_REG_YEAR);
|
|
CMOS_WRITE((((tm->tm_mon) + 1)/10*16 + ((tm->tm_mon) + 1)%10), DS_REG_MONTH);
|
|
CMOS_WRITE(tm->tm_mday/10*16 + tm->tm_mday%10, DS_REG_DATE);
|
|
CMOS_WRITE(tm->tm_wday/10*16 + tm->tm_wday%10, DS_REG_WDAY);
|
|
CMOS_WRITE(tm->tm_hour/10*16 + tm->tm_hour%10, DS_REG_HOUR);
|
|
CMOS_WRITE(tm->tm_min/10*16 + tm->tm_min%10, DS_REG_MIN);
|
|
CMOS_WRITE(tm->tm_sec/10*16 + tm->tm_sec%10, DS_REG_SEC);
|
|
|
|
CMOS_WRITE(ctrlbsave & ~DS_CTLB_SET, DS_REG_CTLB);
|
|
#else
|
|
gpio_i2c_settime(tm);
|
|
#endif
|
|
}
|
|
#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_CACHED(memorysize & ~7) - 64);
|
|
/*
|
|
#if LS3_HT
|
|
return((register_t)(int)PHYS_TO_CACHED(memorysize & ~7) - 64);
|
|
#else
|
|
return((register_t)(int)PHYS_TO_UNCACHED(memorysize & ~7) - 64);
|
|
#endif
|
|
*/
|
|
}
|
|
|
|
#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);
|
|
}
|
|
|
|
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 {
|
|
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;
|
|
}
|
|
}
|
|
}
|
|
|
|
printf("NVRAM@%x\n",(u_int32_t)nvram);
|
|
|
|
/*
|
|
* Ethernet address for Galileo ethernet is stored in the last
|
|
* six bytes of nvram storage. Set environment to it.
|
|
*/
|
|
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);
|
|
|
|
#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);
|
|
|
|
#ifdef MULTI_CHIP
|
|
sprintf(env, "%d", memorysize_high_n1 / (1024 * 1024));
|
|
(*func)("memorysize_high_n1", env);
|
|
|
|
sprintf(env, "%d", memorysize_high_n2 / (1024 * 1024));
|
|
(*func)("memorysize_high_n2", env);
|
|
|
|
sprintf(env, "%d", memorysize_high_n3 / (1024 * 1024));
|
|
(*func)("memorysize_high_n3", env);
|
|
|
|
#endif
|
|
|
|
sprintf(env, "%d", md_pipefreq);
|
|
(*func)("cpuclock", env);
|
|
|
|
sprintf(env, "%d", md_cpufreq);
|
|
(*func)("busclock", env);
|
|
|
|
sprintf(env, "%d",VRAM_SIZE);
|
|
(*func)("vramsize", env);
|
|
|
|
#ifdef CONFIG_GFXUMA
|
|
sprintf(env, "%d",1);
|
|
#else
|
|
sprintf(env, "%d",0);
|
|
#endif
|
|
(*func)("sharevram", 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;
|
|
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');
|
|
}
|
|
}
|
|
|
|
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 (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);
|
|
|
|
bcopy(hwethadr, &nvramsecbuf[ETHER_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
|
|
#include "mycmd.c"
|
|
|
|
#ifdef DEVBD2F_FIREWALL
|
|
#include "i2c-sm502.c"
|
|
#elif defined(DEVBD2F_SM502)
|
|
#include "i2c-sm502.c"
|
|
|
|
#elif (PCI_IDSEL_CS5536 != 0)
|
|
#include "i2c-cs5536.c"
|
|
#else
|
|
#include "i2c-via.c"
|
|
#endif
|
|
|
|
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;
|
|
}
|
|
|
|
/********************************************
|
|
* PCI/PCIE device interrupt talbe **
|
|
*********************************************
|
|
BUS:DEV:FUN interrupt line
|
|
01:05:00 6
|
|
02:00:00 3
|
|
03:00:00 3
|
|
04:00:00 3
|
|
05:00:00 3
|
|
07:00:00 5
|
|
0a:04:00 3
|
|
0a:05:00 3
|
|
*******************************************/
|
|
|
|
/*
|
|
PCI IRQ Routing Index
|
|
0 – INTA#
|
|
1 – INTB#
|
|
2 – INTC#
|
|
3 – INTD#
|
|
4 – SCI
|
|
5 – SMBus interrupt
|
|
9 – INTE#
|
|
0Ah – INTF#
|
|
0Bh – INTG#
|
|
0Ch – INTH#
|
|
|
|
0 ~ 15 : IRQ0 to IRQ15
|
|
IRQ0, 2, 8, 13 are reserved
|
|
*/
|
|
|
|
#define SMBUS_IO_BASE 0x0000 //ynn
|
|
#define PCI_BRADGE_TOTAL 0x0001 //ynn
|
|
|
|
#define DEBUG_FIXINTERRUPT
|
|
#ifdef DEBUG_FIXINTERRUPT
|
|
#define fixup_interrupt_printf(format, args...) printf(format, ##args)
|
|
#else
|
|
#define fixup_interrupt_printf(format, args...) __asm__ __volatile__("sync")
|
|
#endif
|
|
|
|
#define MULTY_FUNCTION (0x1 << 7)
|
|
|
|
void sb700_interrupt_fixup(void)
|
|
{
|
|
unsigned char * pic_index = 0xb8000c00 + SMBUS_IO_BASE;
|
|
unsigned char * pic_data = 0xb8000c01 + SMBUS_IO_BASE;
|
|
unsigned short * intr_contrl = 0xb80004d0 + SMBUS_IO_BASE;
|
|
unsigned short busnum, funnum;
|
|
unsigned short origin_busnum;
|
|
|
|
device_t dev,dev1;
|
|
u32 val, tmp;
|
|
u8 byte;
|
|
|
|
//0. smubs fixup
|
|
fixup_interrupt_printf("\n-----------------godson3a_smbus_fixup---------------\n");
|
|
|
|
/* Set SATA and PATA Controller to combined mode
|
|
* Port0-Port3 is SATA mode, Port4-Port5 is IDE mode */
|
|
dev = _pci_make_tag(0, 0x14, 0x0);
|
|
|
|
/*1. usb interrupt map smbus reg:0XBE map usbint1map usbint3map(ohci use) to PCI_INTC#
|
|
map usbint2map usbint4map(ehci use) to PCI_INTC# */
|
|
pci_write_config16(dev, 0xbe, ((2<<0)|(2 << 3)|(2 << 8)|(2 << 11)) );
|
|
val = pci_read_config16(dev, 0xbe);
|
|
fixup_interrupt_printf(" set smbus reg (0xbe) :%x (usb intr map)\n", val);
|
|
|
|
/*2. sata interrupt map smbus reg:0Xaf map sataintmap to PCI_INTH#*/
|
|
pci_write_config8(dev, 0xaf, 0x1c);
|
|
byte = pci_read_config8(dev, 0xaf);
|
|
fixup_interrupt_printf(" set smbus reg (0xaf) :%x (sata intr map)\n", byte);
|
|
|
|
#if 0 // Lc modify
|
|
/* Set SATA and PATA Controller to combined mode
|
|
* Port0-Port3 is SATA mode, Port4-Port5 is IDE mode
|
|
*/
|
|
byte = pci_read_config8(dev, 0xad);
|
|
byte |= 0x1<<3;
|
|
byte &= ~(0x1<<4);
|
|
pci_write_config8(dev, 0xad, byte);
|
|
|
|
/* Map the HDA interrupt to INTE */
|
|
byte = pci_read_config8(dev, 0x63);
|
|
byte &= 0xf8;
|
|
pci_write_config8(dev, 0x63, byte|0x4);
|
|
|
|
/* Set GPIO42, GPIO43, GPIO44, GPIO46 as HD function */
|
|
pci_write_config16(dev, 0xf8, 0x0);
|
|
//pci_write_config16(dev, 0xfc, 0x2<<0 | 0x2 << 2 | 0x2 << 4 | 0x2 << 6);
|
|
pci_write_config16(dev, 0xfc, 0x2 << 0);
|
|
#endif
|
|
|
|
//Begin to set SB700 interrupt PIC
|
|
fixup_interrupt_printf("SB700 interrupt PIC set begin, \n");
|
|
/* bus4: INTA -->IRQ5 PCIE_slot(right) */
|
|
*(pic_index) = 0x0;
|
|
*(pic_data) = 0x5;
|
|
if (*(pic_data) != 0x5)
|
|
fixup_interrupt_printf("set pic fail: read back %d,should be 0x5\n", *(pic_data));
|
|
else
|
|
fixup_interrupt_printf("set pic_5 pass\n");
|
|
|
|
/* bus5: INTB -->IRQ5 NIC 82574 on borad */
|
|
*(pic_index) = 0x1;
|
|
*(pic_data) = 0x5;
|
|
if (*(pic_data) != 0x5)
|
|
fixup_interrupt_printf("set pic fail: read back %d,should be 0x5\n", *(pic_data));
|
|
else
|
|
fixup_interrupt_printf("set pic_5 pass\n");
|
|
|
|
/* INTC -->IRQ6 NIC 82574, ohci0, ohci1, PCIE_slot(left) */
|
|
*(pic_index) = 0x2;
|
|
*(pic_data) = 0x6;
|
|
if (*(pic_data) != 0x6)
|
|
fixup_interrupt_printf("set pic fail: read back %d,should be 0x6\n", *(pic_data));
|
|
else
|
|
fixup_interrupt_printf("set pic_6 pass\n");
|
|
|
|
/* bus7: INTD -->IRQ5 PCIE_slot(middle) */
|
|
*(pic_index) = 0x3;
|
|
*(pic_data) = 0x5;
|
|
if (*(pic_data) != 0x5)
|
|
fixup_interrupt_printf("set pic fail: read back %d,should be 0x5\n", *(pic_data));
|
|
else
|
|
fixup_interrupt_printf("set pic_5 pass\n");
|
|
|
|
/* INTE -->IRQ5 PCI_slot(left) */
|
|
*(pic_index) = 0x9;
|
|
*(pic_data) = 0x5;
|
|
if (*(pic_data) != 0x5)
|
|
fixup_interrupt_printf("set pic fail: read back %d,should be 0x5\n", *(pic_data));
|
|
else
|
|
fixup_interrupt_printf("set pic_5 pass\n");
|
|
|
|
/* bus 10: dev 4: INTF -->IRQ5 PCI_slot(right) */
|
|
*(pic_index) = 0xa;
|
|
*(pic_data) = 0x5;
|
|
if (*(pic_data) != 0x5)
|
|
fixup_interrupt_printf("set pic fail: read back %d,should be 0x5\n", *(pic_data));
|
|
else
|
|
fixup_interrupt_printf("set pic_a pass\n");
|
|
|
|
#if 1
|
|
/* bus 7: dev 5: func 2: INTG -->IRQ3 PCI(right) */
|
|
*(pic_index) = 0xb;
|
|
*(pic_data) = 0x3;
|
|
if (*(pic_data) != 0x3)
|
|
fixup_interrupt_printf("set pic fail: read back %d,should be 0x3\n", *(pic_data));
|
|
else
|
|
fixup_interrupt_printf("set pic_9 pass\n");
|
|
#endif
|
|
|
|
/* INTH -->IRQ5 SATA */
|
|
*(pic_index) = 0xc;
|
|
*(pic_data) = 0x5;
|
|
if (*(pic_data) != 0x5)
|
|
fixup_interrupt_printf("set pic fail: read back %d,should be 0x5\n", *(pic_data));
|
|
else
|
|
fixup_interrupt_printf("set pic_5 pass\n");
|
|
|
|
/* 5. set int triggle model: level or edge */
|
|
dev = _pci_make_tag(0, 0x14, 0x0);
|
|
fixup_interrupt_printf("PIC control bit: %08x\n", pci_read_config16(dev, 0x64));
|
|
|
|
fixup_interrupt_printf("original int mode: 0x%08x \n", (*intr_contrl));
|
|
(*intr_contrl) = ((*intr_contrl)|(1<<6)|(1<<5)|(1<<4)|(1<<3));
|
|
fixup_interrupt_printf("<1> now int mode: 0x%08x \n", (*intr_contrl));
|
|
fixup_interrupt_printf("waiting....\n");
|
|
#if 1
|
|
(*intr_contrl) = ((*intr_contrl)|(1<<6)|(1<<5)|(1<<4)|(1<<3));
|
|
fixup_interrupt_printf("<1> now int mode: 0x%08x \n", (*intr_contrl));
|
|
#endif
|
|
|
|
fixup_interrupt_printf("SB700 interrupt PIC set done \n");
|
|
|
|
|
|
|
|
// Fix bonito interrupt according fixup_3a780e.c in kernel source code
|
|
fixup_interrupt_printf("SB700 device interrupt route begin \n");
|
|
|
|
// 1.fix up 82574:
|
|
/* NIC 82574 on board (left) bus5 dev0 fun 0*/
|
|
fixup_interrupt_printf("\nrte0 fixup: em0 ---------------> int5\n");
|
|
fixup_interrupt_printf("SB700 device route em0: int5 \n");
|
|
|
|
for( funnum = 0; funnum < 8; funnum++)
|
|
{
|
|
dev = _pci_make_tag(5, 0x0, funnum);
|
|
val = pci_read_config32(dev, 0x00);
|
|
if ( val != 0xffffffff) // device on the slot
|
|
pci_write_config8(dev, 0x3c, 0x05);
|
|
}
|
|
|
|
/* NIC 82574 on board (right) bus6 dev0 fun0 */
|
|
fixup_interrupt_printf("SB700 device route em1: int6 \n");
|
|
for( funnum = 0; funnum < 8; funnum++)
|
|
{
|
|
dev = _pci_make_tag(6, 0x0, funnum);
|
|
val = pci_read_config32(dev, 0x00);
|
|
if ( val != 0xffffffff) // device on the slot
|
|
pci_write_config8(dev, 0x3c, 0x06);
|
|
}
|
|
|
|
//2.fixup sata int line
|
|
fixup_interrupt_printf("\n godson3a_sata_fixup: sata ---------------> int5 \n"); /* Lc: use irq num 5, after shoud be 4*/
|
|
|
|
/*2.1. enable the subcalss code register for setting sata controller mode*/
|
|
dev = _pci_make_tag(0, 0x11, 0x0);
|
|
val = pci_read_config8(dev, 0x40);
|
|
(void) pci_write_config8(dev, 0x40, (val | 0x01) );
|
|
|
|
/*2.2. set sata controller act as AHCI mode
|
|
* sata controller support IDE mode, AHCI mode, Raid mode*/
|
|
(void) pci_write_config8(dev, 0x09, 0x01);
|
|
(void) pci_write_config8(dev, 0x0a, 0x06);
|
|
|
|
/*2.3. disable the subcalss code register*/
|
|
val = pci_read_config8(dev, 0x40);
|
|
(void) pci_write_config8(dev, 0x40, val & (~0x01));
|
|
fixup_interrupt_printf("-----------------tset sata------------------\n");
|
|
val = pci_read_config32(dev, 0x40);
|
|
fixup_interrupt_printf("sata pci_config 0x40 (%x)\n", val);
|
|
/*2.4. set interrput vector */
|
|
pci_write_config8(dev, 0x3c, 0x5);
|
|
fixup_interrupt_printf("godson3a_sata: fix sata mode==:%d\n",pci_read_config8(dev,0x3c));
|
|
|
|
/*3. ide fixup*/
|
|
fixup_interrupt_printf("godson3a_ide_fixup: fix ide mode\n");
|
|
dev = _pci_make_tag(0, 0x14, 1);
|
|
|
|
/* enable IDE DMA --Multi-Word DMA */
|
|
pci_write_config32(dev, 0x44, 0x20000000);
|
|
byte = pci_read_config8(dev, 0x54);
|
|
byte |= 1 << 0;
|
|
pci_write_config8(dev, 0x54, byte);
|
|
|
|
#if 0
|
|
/*set IDE ultra DMA enable as master and slalve device*/
|
|
(void) pci_write_config8(dev, 0x54, 0xf);
|
|
/*set ultral DAM mode 0~6 we use 6 as high speed !*/
|
|
(void) pci_write_config16(dev, 0x56, (0x6 << 0)|(0x6 << 4)|(0x6 << 8)|(0x6 << 12));
|
|
fixup_interrupt_printf("godson3a_ide_fixup: fix ide mode\n");
|
|
#endif
|
|
|
|
/*4. usb fixup*/
|
|
fixup_interrupt_printf("godson3a fixup: usb ------> int6 \n");
|
|
dev = _pci_make_tag(0, 0x12, 0); //OHCI0
|
|
pci_write_config8(dev, 0x3c, 0x6);
|
|
fixup_interrupt_printf("godson3a fixup: usb ------> int6 \n");
|
|
dev = _pci_make_tag(0, 0x12, 1); //OHCI1
|
|
pci_write_config8(dev, 0x3c, 0x6);
|
|
fixup_interrupt_printf("godson3a fixup: usb ------> int6 \n");
|
|
dev = _pci_make_tag(0, 0x12, 2); //EHCI
|
|
pci_write_config8(dev, 0x3c, 0x6);
|
|
fixup_interrupt_printf("godson3a fixup: usb ------> int6 \n");
|
|
dev = _pci_make_tag(0, 0x13, 0); //OHCI0
|
|
pci_write_config8(dev, 0x3c, 0x6);
|
|
fixup_interrupt_printf("godson3a fixup: usb ------> int6 \n");
|
|
dev = _pci_make_tag(0, 0x13, 1); //OHCI1
|
|
pci_write_config8(dev, 0x3c, 0x6);
|
|
fixup_interrupt_printf("godson3a fixup: usb ------> int6 \n");
|
|
dev = _pci_make_tag(0, 0x13, 2); //EHCI
|
|
pci_write_config8(dev, 0x3c, 0x6);
|
|
fixup_interrupt_printf("godson3a fixup: usb ------> int6 \n");
|
|
dev = _pci_make_tag(0, 0x14, 5); //USB controller
|
|
pci_write_config8(dev, 0x3c, 0x6);
|
|
fixup_interrupt_printf("godson3a fixup: usb ------> int6 \n");
|
|
|
|
#if 0
|
|
/*5. lpc fixup*/
|
|
dev = _pci_make_tag(0, 0x14, 3);
|
|
fixup_interrupt_printf("godson3a fixup: lpc ------> int6 \n");
|
|
val = pci_read_config8(dev, 0x46);
|
|
fixup_interrupt_printf("Fixup: lpc: 0x46 value is 0x%x\n",val);
|
|
pci_write_config8(dev, 0x46, val|(0x3 << 6));
|
|
val = pci_read_config8(dev, 0x46);
|
|
fixup_interrupt_printf("Fixup: lpc: 0x47 value is 0x%x\n",val);
|
|
|
|
val = pci_read_config8(dev, 0x47);
|
|
fixup_interrupt_printf("Fixup: lpc: 0x47 value is 0x%x\n",val);
|
|
pci_write_config8(dev, 0x47, val|0xff);
|
|
val = pci_read_config8(dev, 0x47);
|
|
fixup_interrupt_printf("Fixup: lpc: 0x47 value is 0x%x\n",val);
|
|
|
|
val = pci_read_config8(dev, 0x48);
|
|
fixup_interrupt_printf("Fixup: lpc: 0x48 value is 0x%x\n",val);
|
|
pci_write_config8(dev, 0x48, val|0xff);
|
|
val = pci_read_config8(dev, 0x48);
|
|
fixup_interrupt_printf("Fixup: lpc: 0x48 value is 0x%x\n",val);
|
|
#endif
|
|
|
|
#if 0
|
|
/*6. hda fixup*/
|
|
fixup_interrupt_printf("godson3a fixup: HDA ------> int5 \n");
|
|
dev = _pci_make_tag(0, 0x14, 2);
|
|
pci_write_config8(dev,0x3c,0x05);
|
|
|
|
fixup_interrupt_printf("godson3a fixup: HDA ------> int5 \n");
|
|
#endif
|
|
|
|
/*7. VGA fixup*/
|
|
fixup_interrupt_printf("godson3a fixup: VGA ------> int6 \n");
|
|
dev = _pci_make_tag(1, 0x5, 0);
|
|
pci_write_config8(dev,0x3c,0x06);
|
|
|
|
fixup_interrupt_printf("godson3a fixup: VGA ------> int6 \n");
|
|
|
|
/*8. pci/pcie slot fixup */
|
|
#if 0
|
|
//8.1. route 00:06:00 (pcie slot) INTA->INTC# -----------------> int6
|
|
// First check if any device in the slot ( return -1 means no device, else there is device )
|
|
dev = _pci_make_tag(6, 0x0, 0x0); //added to fixup pci bridge card
|
|
val = pci_read_config32(dev, 0x00);
|
|
if ( val != 0xffffffff) // device on the slot
|
|
pci_write_config8(dev, 0x3c, 0x03);
|
|
#endif
|
|
|
|
// 8.2.1 route 00:04:00 (pcie_slot(right)) INTA->INTB# -----------------> int5
|
|
// 8.2.2 route 00:04:01 (pcie_slot(right)) INTB->INTC# -----------------> int6
|
|
// 8.2.3 route 00:04:02 (pcie_slot(right)) INTC->INTD# -----------------> int5
|
|
// 8.2.4 route 00:04:03 (pcie_slot(right)) INTD->INTE# -----------------> int5
|
|
// First check if any device in the slot ( return -1 means no device, else there is device )
|
|
dev = _pci_make_tag(4, 0x0, 0x00);
|
|
val = pci_read_config32(dev, 0x00);
|
|
if ( val != 0xffffffff)
|
|
pci_write_config8(dev, 0x3c, 0x05);
|
|
|
|
val = pci_read_config8(dev, 0x0e); // judge whether multi-function card
|
|
|
|
if ( val & MULTY_FUNCTION) {
|
|
dev = _pci_make_tag(4, 0x0, 0x01);
|
|
val = pci_read_config32(dev, 0x00);
|
|
if ( val != 0xffffffff)
|
|
pci_write_config8(dev, 0x3c, 0x06);
|
|
|
|
dev = _pci_make_tag(4, 0x0, 0x02);
|
|
val = pci_read_config32(dev, 0x00);
|
|
if ( val != 0xffffffff)
|
|
pci_write_config8(dev, 0x3c, 0x05);
|
|
|
|
dev = _pci_make_tag(4, 0x0, 0x03);
|
|
val = pci_read_config32(dev, 0x00);
|
|
if ( val != 0xffffffff)
|
|
pci_write_config8(dev, 0x3c, 0x05);
|
|
}
|
|
|
|
// 8.3.1 route 00:03:00 (pcie_slot(middle)) INTA->INTA# -----------------> int5
|
|
// 8.3.2 route 00:03:01 (pcie_slot(middle)) INTB->INTB# -----------------> int5
|
|
// 8.3.3 route 00:03:02 (pcie_slot(middle)) INTC->INTC# -----------------> int6
|
|
// 8.3.4 route 00:03:03 (pcie_slot(middle)) INTD->INTD# -----------------> int5
|
|
// First check if any device in the slot ( return -1 means no device, else there is device )
|
|
dev = _pci_make_tag(3, 0x0, 0x00);
|
|
val = pci_read_config32(dev, 0x00);
|
|
if ( val != 0xffffffff)
|
|
pci_write_config8(dev, 0x3c, 0x05);
|
|
|
|
val = pci_read_config8(dev, 0x0e);
|
|
|
|
if ( val & MULTY_FUNCTION) {
|
|
dev = _pci_make_tag(3, 0x0, 0x01);
|
|
val = pci_read_config32(dev, 0x00);
|
|
if ( val != 0xffffffff)
|
|
pci_write_config8(dev, 0x3c, 0x05);
|
|
|
|
dev = _pci_make_tag(3, 0x0, 0x02);
|
|
val = pci_read_config32(dev, 0x00);
|
|
if ( val != 0xffffffff)
|
|
pci_write_config8(dev, 0x3c, 0x06);
|
|
|
|
dev = _pci_make_tag(3, 0x0, 0x03);
|
|
val = pci_read_config32(dev, 0x00);
|
|
if ( val != 0xffffffff)
|
|
pci_write_config8(dev, 0x3c, 0x05);
|
|
}
|
|
|
|
// 8.4.1 route 00:02:00 (pcie_slot(left)) INTA->INTC# -----------------> int6
|
|
// 8.4.2 route 00:02:01 (pcie_slot(left)) INTB->INTD# -----------------> int5
|
|
// 8.4.3 route 00:02:02 (pcie_slot(left)) INTC->INTE# -----------------> int5
|
|
// 8.4.4 route 00:02:03 (pcie_slot(left)) INTD->INTF# -----------------> int5
|
|
// First check if any device in the slot ( return -1 means no device, else there is device )
|
|
dev = _pci_make_tag(2, 0x0, 0x00);
|
|
val = pci_read_config32(dev, 0x00);
|
|
if ( val != 0xffffffff)
|
|
pci_write_config8(dev, 0x3c, 0x06);
|
|
|
|
val = pci_read_config8(dev, 0x0e);
|
|
|
|
if ( val & MULTY_FUNCTION) {
|
|
dev = _pci_make_tag(2, 0x0, 0x01);
|
|
val = pci_read_config32(dev, 0x00);
|
|
if ( val != 0xffffffff)
|
|
pci_write_config8(dev, 0x3c, 0x05);
|
|
|
|
dev = _pci_make_tag(2, 0x0, 0x02);
|
|
val = pci_read_config32(dev, 0x00);
|
|
if ( val != 0xffffffff)
|
|
pci_write_config8(dev, 0x3c, 0x05);
|
|
|
|
dev = _pci_make_tag(2, 0x0, 0x03);
|
|
val = pci_read_config32(dev, 0x00);
|
|
if ( val != 0xffffffff)
|
|
pci_write_config8(dev, 0x3c, 0x05);
|
|
}
|
|
|
|
// 9. route 07:0x:0x (pci slot: con30 and con19)
|
|
// NOTICE here: now assume dev 2, dev3 and dev 4 are all enable on x16 pcie slot, but
|
|
// in fact only one dev need to be enable. If only one device is enable, all code in this function
|
|
// need to be update (that means bus number should minus 2, and interrupt need to be routed again),
|
|
// But at this moment, don't care this "bug".
|
|
|
|
// At most "PCI_BRADGE_TOTAL" pci bridge is support before bus "origin_busnum" is scaned,
|
|
// now begin probing pci slot...
|
|
|
|
origin_busnum = 7;
|
|
for ( busnum = origin_busnum; busnum <= PCI_BRADGE_TOTAL + origin_busnum ; busnum++)
|
|
{
|
|
|
|
// 9.1.1 route 07:05:00 (con38 with add_21) INTA->PCI_INTA --> INTE# ---------------------> int5
|
|
// 9.1.2 route 07:05:01 (con38 with add_21) INTB->PCI_INTB --> INTF# ---------------------> int5
|
|
// 9.1.3 route 07:05:02 (con38 with add_21) INTC->PCI_INTC --> INTG# ---------------------> int3
|
|
// 9.1.4 route 07:05:03 (con38 with add_21) INTD->PCI_INTD --> INTH# ---------------------> int5
|
|
dev = _pci_make_tag(busnum, 0x5, 0x0);
|
|
val = pci_read_config32(dev, 0x00);
|
|
if ( val != 0xffffffff) // device on the slot
|
|
pci_write_config8(dev, 0x3c, 0x5);
|
|
|
|
val = pci_read_config8(dev, 0x0e);
|
|
|
|
if ( val & MULTY_FUNCTION) {
|
|
dev = _pci_make_tag(busnum, 0x5, 0x1);
|
|
val = pci_read_config32(dev, 0x00);
|
|
if ( val != 0xffffffff) // device on the slot
|
|
pci_write_config8(dev, 0x3c, 0x5);
|
|
|
|
dev = _pci_make_tag(busnum, 0x5, 0x2);
|
|
val = pci_read_config32(dev, 0x00);
|
|
if ( val != 0xffffffff) // device on the slot
|
|
pci_write_config8(dev, 0x3c, 0x3);
|
|
|
|
dev = _pci_make_tag(busnum, 0x5, 0x3);
|
|
val = pci_read_config32(dev, 0x00);
|
|
if ( val != 0xffffffff) // device on the slot
|
|
pci_write_config8(dev, 0x3c, 0x5);
|
|
}
|
|
|
|
// 9.2.1 route 07:06:00 (con45 with add_22) INTA->PCI_INTB --> INTF# ---------------------> int5
|
|
// 9.2.2 route 07:06:01 (con45 with add_22) INTB->PCI_INTC --> INTG# ---------------------> int3
|
|
// 9.2.3 route 07:06:02 (con45 with add_22) INTC->PCI_INTD --> INTH# ---------------------> int5
|
|
// 9.2.4 route 07:06:03 (con45 with add_22) INTD->PCI_INTA --> INTE# ---------------------> int5
|
|
dev = _pci_make_tag(busnum, 0x6, 0x0);
|
|
val = pci_read_config32(dev, 0x00);
|
|
if ( val != 0xffffffff) // device on the slot
|
|
pci_write_config8(dev, 0x3c, 0x05);
|
|
|
|
val = pci_read_config8(dev, 0x0e);
|
|
|
|
if ( val & MULTY_FUNCTION) {
|
|
dev = _pci_make_tag(busnum, 0x6, 0x1);
|
|
val = pci_read_config32(dev, 0x00);
|
|
if ( val != 0xffffffff) // device on the slot
|
|
pci_write_config8(dev, 0x3c, 0x03);
|
|
|
|
dev = _pci_make_tag(busnum, 0x6, 0x2);
|
|
val = pci_read_config32(dev, 0x00);
|
|
if ( val != 0xffffffff) // device on the slot
|
|
pci_write_config8(dev, 0x3c, 0x05);
|
|
|
|
dev = _pci_make_tag(busnum, 0x6, 0x3);
|
|
val = pci_read_config32(dev, 0x00);
|
|
if ( val != 0xffffffff) // device on the slot
|
|
pci_write_config8(dev, 0x3c, 0x05);
|
|
}
|
|
}
|
|
|
|
|
|
/*******************************************************/
|
|
// below added to check pci/pcie interrupt line register
|
|
/*******************************************************/
|
|
// 10.1 check all pcie slot interrupt line register
|
|
for ( tmp = 2; tmp < 7; tmp++)
|
|
{
|
|
dev = _pci_make_tag(tmp, 0x0, 0x0);
|
|
val = pci_read_config32(dev, 0x00);
|
|
if ( val != 0xffffffff) // device on the slot
|
|
{
|
|
val = pci_read_config8(dev, 0x3c);
|
|
if ( val != 0x3)
|
|
fixup_interrupt_printf("%02x:00:00 interrupt line : Error\n",tmp );
|
|
}
|
|
}
|
|
|
|
// 10.2 check all pci slot interrupt line register
|
|
for ( tmp = 0x4; tmp < 0x6; tmp++)
|
|
{
|
|
dev = _pci_make_tag(0xa, tmp, 0x0);
|
|
val = pci_read_config32(dev, 0x00);
|
|
if ( val != 0xffffffff) // device on the slot
|
|
{
|
|
val = pci_read_config8(dev, 0x3c);
|
|
if ( val != 0x3)
|
|
fixup_interrupt_printf("0a:%02x:00 interrupt line : Error\n",tmp );
|
|
}
|
|
}
|
|
|
|
// 10.4 check RTE/CON30 interrupt line register
|
|
dev = _pci_make_tag(0x7, 0x0, 0x0);
|
|
val = pci_read_config32(dev, 0x00);
|
|
if ( val != 0xffffffff) // device on the slot
|
|
{
|
|
val = pci_read_config8(dev, 0x3c);
|
|
if ( val != 0x5)
|
|
fixup_interrupt_printf("07:00:00 interrupt line : Error\n");
|
|
}
|
|
|
|
// 10.5 check VGA interrupt line register
|
|
dev = _pci_make_tag(0x1, 0x5, 0x0);
|
|
val = pci_read_config32(dev, 0x00);
|
|
if ( val != 0xffffffff) // device on the slot
|
|
{
|
|
val = pci_read_config8(dev, 0x3c);
|
|
if ( val != 0x6)
|
|
fixup_interrupt_printf("01:05:00 interrupt line : Error\n");
|
|
}
|
|
|
|
}
|
|
|
|
|