ppc970 initial porting.

git-svn-id: svn://svn.coreboot.org/coreboot/trunk@2082 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
This commit is contained in:
Eswar Nallusamy 2005-11-02 17:32:49 +00:00
parent 987ca8e08c
commit ed00937103
23 changed files with 9234 additions and 1947 deletions

View File

@ -5,6 +5,16 @@ makerule linuxbios.rom
action "cp $< $@"
end
makerule clean
action "rm -f linuxbios.* *~"
action "rm -f linuxbios"
action "rm -f ldscript.ld"
action "rm -f a.out *.s *.l *.o *.E *.inc"
action "rm -f TAGS tags romcc*"
action "rm -f docipl buildrom* chips.c *chip.c linuxbios_ram* linuxbios_pay*"
action "rm -f build_opt_tbl* nrv2b* option_table.c"
end
dir init
dir lib
dir boot

File diff suppressed because it is too large Load Diff

279
src/arch/ppc/include/ppc970lib.h Executable file
View File

@ -0,0 +1,279 @@
#ifndef _ppc970lib_h_
#define _ppc970lib_h_
/*----------------------------------------------------------------------------+
| Time base structure.
+----------------------------------------------------------------------------*/
typedef struct tb {
unsigned long tb_all;
} tb_t;
/*----------------------------------------------------------------------------+
| 970FX specific ppc prototypes.
+----------------------------------------------------------------------------*/
void ppcMfvscr(
void );
void ppcMtvscr(
void );
int ppcMfvr(
unsigned int reg_num,
unsigned long *data_msb,
unsigned long *data_lsb );
int ppcMtvr(
unsigned int reg_num,
unsigned long data_msb,
unsigned long data_lsb );
void ppcLvxl(
unsigned int reg_num,
void *addr );
void ppcStvx(
unsigned int reg_num,
void *addr );
unsigned long ppcMflr(
void );
unsigned char inbyte(
unsigned long addr );
void outbyte(
unsigned long addr,
unsigned int data );
unsigned short inhalf(
unsigned long addr );
void outhalf(
unsigned long addr,
unsigned int data );
unsigned short inhalf_brx(
unsigned long addr );
void outhalf_brx(
unsigned long addr,
unsigned int data );
unsigned long inword(
unsigned long addr );
void outword(
unsigned long addr,
unsigned long data );
unsigned int inint(
unsigned long addr );
void outint(
unsigned long addr,
unsigned int data );
unsigned int inint_brx(
unsigned long addr );
void outint_brx(
unsigned long addr,
unsigned int data );
void ppcDflush(
void );
void ppcDcbz_area(
unsigned long addr,
unsigned long len );
unsigned long ppcTlbsync(
void );
unsigned long ppcTlbie(
unsigned long vaddr,
int large_page );
void ppcTlbiel(
unsigned long vaddr );
void ppcSlbie(
unsigned long rb );
void ppcSlbia(
void );
void ppcSlbmte(
unsigned long rs,
unsigned long rb );
unsigned long ppcSlbmfev(
int index );
unsigned long ppcSlbmfee(
int index );
void ppcAbend(
void );
unsigned long ppcAndMsr(
unsigned long value );
unsigned int ppcCntlzw(
unsigned int value );
unsigned int ppcCntlzd(
unsigned long value );
void ppcDcbf(
void *addr );
void ppcDcbst(
void *addr );
void ppcDcbz(
void *addr );
void ppcHalt(
void );
void ppcIcbi(
void *addr );
void ppcIsync(
void );
unsigned long ppcMfgpr1(
void );
unsigned long ppcMfgpr2(
void );
void ppcMtmsr(
unsigned long msr_value );
unsigned long ppcMfmsr(
void );
unsigned long ppcOrMsr(
unsigned long value );
void ppcSync(
void );
void ppcLwsync(
void );
void ppcPtesync(
void );
void ppcEieio(
void );
void ppcTestandset(
unsigned long addr,
unsigned long value );
unsigned long ppcMfscom(
unsigned int scom_num );
void ppcMtscom(
unsigned int scom_num,
unsigned long scom_data );
/*----------------------------------------------------------------------------+
| 970FX SPR's.
+----------------------------------------------------------------------------*/
void ppcMthid0(
unsigned long data );
void ppcMthid1(
unsigned long data );
void ppcMthid4(
unsigned long data );
void ppcMthid5(
unsigned long data );
void ppcMftb(
tb_t *clock_data );
void ppcMttb(
tb_t *clock_data );
void ppcMtspr_any(
unsigned int spr_num,
unsigned long value );
unsigned long ppcMfspr_any(
unsigned int spr_num );
/*----------------------------------------------------------------------------+
| Additional functions required by debug connection.
+----------------------------------------------------------------------------*/
int ppcCachelinesize(
void );
unsigned long ppcProcid(
void );
void ppcMtmmucr(
unsigned long data );
void ppcMttlb1(
unsigned long index,
unsigned long value );
void ppcMttlb2(
unsigned long index,
unsigned long value );
void ppcMttlb3(
unsigned long index,
unsigned long value );
unsigned long ppcMftlb1(
unsigned long index );
unsigned long ppcMftlb2(
unsigned long index );
unsigned long ppcMftlb3(
unsigned long index );
unsigned long ppcMfmmucr(
void );
unsigned long ppcMfdcr_any(
unsigned long dcr_num );
unsigned long ppcMfspr_any_name(
char *name,
unsigned long *value_msb );
void ppcMtdcr_any(
unsigned long dcr_num,
unsigned long value );
void ppcMtspr_any_name(
char *name,
unsigned long value_lsb,
unsigned long value_msb );
int ppcIstrap(
void );
unsigned long p_ptegg(
int lp,
unsigned long ea,
unsigned long sdr1,
unsigned long vsid );
unsigned long s_ptegg(
int lp,
unsigned long ea,
unsigned long sdr1,
unsigned long vsid );
#endif /* _ppc970lib_h_ */

View File

@ -1,94 +1,372 @@
/*
* Memory map:
*
* _ROMBASE : start of ROM
* _RESET : reset vector (may be at top of ROM)
* _EXCEPTIONS_VECTORS : exception table
*
* _ROMSTART : linuxbios text
* : payload text
*
* _RAMBASE : address to copy payload
*/
/*----------------------------------------------------------------------------+
| Memory layout. RAM length is referenced again in __heap_size variable
| definition.
+----------------------------------------------------------------------------*/
MEMORY
{
RAM_VECT (rwx) : ORIGIN = 0x00000000, LENGTH = 0x00010000
RAM (rwx) : ORIGIN = 0x00010000, LENGTH = 0x003F0000
ROM_INIT (r x) : ORIGIN = 0xFFF00000, LENGTH = 0x00002000
ROM (r x) : ORIGIN = 0xFFF02000, LENGTH = 0x000FE000
}
/*
* Written by Johan Rydberg, based on work by Daniel Kahlin.
* Rewritten by Eric Biederman
* Re-rewritten by Greg Watson for PPC
*/
/*
* We use ELF as output format. So that we can
* debug the code in some form.
*/
OUTPUT_FORMAT("elf32-powerpc")
ENTRY(_start)
TARGET(binary)
INPUT(linuxbios_ram.rom)
/*----------------------------------------------------------------------------+
| Sections originally taken from default GNU LD script.
+----------------------------------------------------------------------------*/
SECTIONS
{
/*
* Absolute location of base of ROM
*/
. = _ROMBASE;
/*
* Absolute location of reset vector. This may actually be at the
* the top of ROM.
*/
. = _RESET;
.reset . : {
*(.rom.reset);
. = ALIGN(16);
}
/*-------------------------------------------------------------------------+
| Create dummy section. We need to do this so that the __stext symbol is
| set correctly.
+-------------------------------------------------------------------------*/
.dummyt :
{
LONG(0x00000000)
} > RAM
/*
* Absolute location of exception vector table.
*/
. = _EXCEPTION_VECTORS;
.exception_vectors . : {
*(.rom.exception_vectors);
. = ALIGN(16);
}
/*-------------------------------------------------------------------------+
| Create variable holding the value of the start of the text.
+-------------------------------------------------------------------------*/
__stext = . - SIZEOF(.dummyt);
/*
* Absolute location of LinuxBIOS initialization code in ROM.
*/
. = _ROMSTART;
.rom . : {
_rom = .;
*(.rom.text);
*(.text);
*(.rom.data);
*(.rodata);
*(EXCLUDE_FILE(linuxbios_ram.rom) .data);
. = ALIGN(16);
_erom = .;
}
_lrom = LOADADDR(.rom);
_elrom = LOADADDR(.rom) + SIZEOF(.rom);
/*
* Ram is the LinuxBIOS code that runs from RAM.
*/
.ram . : {
_ram = . ;
linuxbios_ram.rom(*)
_eram = . ;
}
.hash :
{
*(.hash)
} > RAM
/*
* Absolute location of where LinuxBIOS will be relocated in RAM.
*/
_iseg = _RAMBASE;
_eiseg = _iseg + SIZEOF(.ram);
_liseg = _ram;
_eliseg = _eram;
.dynsym :
{
*(.dynsym)
} > RAM
.dynstr :
{
*(.dynstr)
} > RAM
.rel.init :
{
*(.rel.init)
} > RAM
.rela.init :
{
*(.rela.init)
} > RAM
.rel.text :
{
*(.rel.text)
*(.rel.text.*)
*(.rel.gnu.linkonce.t.*)
} > RAM
.rela.text :
{
*(.rela.text)
*(.rela.text.*)
*(.rela.gnu.linkonce.t.*)
} > RAM
.rel.rodata :
{
*(.rel.rodata)
*(.rel.rodata.*)
*(.rel.gnu.linkonce.r.*)
} > RAM
.rela.rodata :
{
*(.rela.rodata)
*(.rela.rodata.*)
*(.rela.gnu.linkonce.r.*)
} > RAM
.rel.data :
{
*(.rel.data)
*(.rel.data.*)
*(.rel.gnu.linkonce.d.*)
} > RAM
.rela.data :
{
*(.rela.data)
*(.rela.data.*)
*(.rela.gnu.linkonce.d.*)
} > RAM
.rel.sdata :
{
*(.rel.sdata)
*(.rel.sdata.*)
*(.rel.gnu.linkonce.s.*)
} > RAM
.rela.sdata :
{
*(.rela.sdata)
*(.rela.sdata.*)
*(.rela.gnu.linkonce.s.*)
} > RAM
.rel.sbss :
{
*(.rel.sbss)
*(.rel.sbss.*)
*(.rel.gnu.linkonce.sb.*)
} > RAM
.rela.sbss :
{
*(.rela.sbss)
*(.rela.sbss.*)
*(.rel.gnu.linkonce.sb.*)
} > RAM
.rel.sdata2 :
{
*(.rel.sdata2)
*(.rel.sdata2.*)
*(.rel.gnu.linkonce.s2.*)
} > RAM
.rela.sdata2 :
{
*(.rela.sdata2)
*(.rela.sdata2.*)
*(.rela.gnu.linkonce.s2.*)
} > RAM
.rel.sbss2 :
{
*(.rel.sbss2)
*(.rel.sbss2.*)
*(.rel.gnu.linkonce.sb2.*)
} > RAM
.rela.sbss2 :
{
*(.rela.sbss2)
*(.rela.sbss2.*)
*(.rela.gnu.linkonce.sb2.*)
} > RAM
.rel.bss :
{
*(.rel.bss)
*(.rel.bss.*)
*(.rel.gnu.linkonce.b.*)
} > RAM
.rela.bss :
{
*(.rela.bss)
*(.rela.bss.*)
*(.rela.gnu.linkonce.b.*)
} > RAM
.rel.plt :
{
*(.rel.plt)
} > RAM
.rela.plt :
{
*(.rela.plt)
} > RAM
/*-------------------------------------------------------------------------+
| Keep the .init sections even if they are not referenced. Fill in the
| space (if any) in the .init serctions with 0.
+-------------------------------------------------------------------------*/
.text :
{
*(.text)
*(.text.*)
*(.stub)
*(.gnu.warning)
*(.gnu.linkonce.t.*)
} > RAM = 0
/*-------------------------------------------------------------------------+
| Create variable holding the value of the end of the text.
+-------------------------------------------------------------------------*/
__etext = .;
/*-------------------------------------------------------------------------+
| Create variable holding the value of the start of the data.
+-------------------------------------------------------------------------*/
__sdata = .;
.rodata :
{
*(.rodata)
*(.rodata.*)
*(.gnu.linkonce.r.*)
} > RAM
.rodata1 :
{
*(.rodata1)
} > RAM
.sdata2 :
{
*(.sdata2)
*(.sdata2.*)
*(.gnu.linkonce.s2.*)
} > RAM
.sbss2 :
{
*(.sbss2)
*(.sbss2.*)
*(.gnu.linkonce.sb2.*)
} > RAM
/*-------------------------------------------------------------------------+
| Align data to word boundary.
+-------------------------------------------------------------------------*/
. = ALIGN(4);
.data :
{
*(.data)
*(.data.*)
*(.gnu.linkonce.d.*)
} > RAM
.toc :
{
*(.toc)
*(.toc.*)
} > RAM
.opd :
{
*(.opd)
*(.opd.*)
} > RAM
.data1 :
{
*(.data1)
} > RAM
.eh_frame :
{
KEEP(*(.eh_frame))
} > RAM
.fixup :
{
*(.fixup)
} > RAM
.dynamic :
{
*(.dynamic)
} > RAM
/*-------------------------------------------------------------------------+
| We want the small data sections together, so single-instruction offsets
| can access them all, and initialized data all before uninitialized, so
| we can shorten the on-disk segment size.
+-------------------------------------------------------------------------*/
.sdata :
{
*(.sdata)
*(.sdata.*)
*(.gnu.linkonce.s.*)
} > RAM
/*-------------------------------------------------------------------------+
| Create variable holding the value of the end of the data.
+-------------------------------------------------------------------------*/
__edata = .;
/*-------------------------------------------------------------------------+
| Create variable holding the value of the start of the bss.
+-------------------------------------------------------------------------*/
__sbss = .;
.sbss :
{
*(.dynsbss)
*(.sbss)
*(.sbss.*)
*(.gnu.linkonce.sb.*)
*(.scommon)
} > RAM
.plt :
{
*(.plt)
} > RAM
/*-------------------------------------------------------------------------+
| Common symbols are placed in the BSS section.
+-------------------------------------------------------------------------*/
.bss :
{
*(.dynbss)
*(.bss)
*(.bss.*)
*(.gnu.linkonce.b.*)
*(COMMON)
} > RAM
/*-------------------------------------------------------------------------+
| Align so that the bss size and __ebss are word aligned.
+-------------------------------------------------------------------------*/
. = ALIGN(4);
/*-------------------------------------------------------------------------+
| Create variable holding the value of the end of the bss.
+-------------------------------------------------------------------------*/
__ebss = .;
/*-------------------------------------------------------------------------+
| Create variables describing the heap. The value "0x3F0000" must be
| equal to RAM length.
+-------------------------------------------------------------------------*/
__heap_start = .;
__heap_size = 0x3F0000 + ADDR(.dummyt) - .;
/*-------------------------------------------------------------------------+
| Stabs. Symbols in the following sections are relative to the beginning
| of the section so we begin them at 0.
+-------------------------------------------------------------------------*/
.stab 0 :
{
*(.stab)
}
.stabstr 0 :
{
*(.stabstr)
}
.stab.excl 0 :
{
*(.stab.excl)
}
.stab.exclstr 0 :
{
*(.stab.exclstr)
}
.stab.index 0 :
{
*(.stab.index)
}
.stab.indexstr 0 :
{
*(.stab.indexstr)
}
/DISCARD/ : {
*(.comment)
*(.note)
}
}

View File

@ -6,11 +6,13 @@
#include <board.h>
#include <sdram.h>
#ifndef __PPC64__
extern unsigned _iseg[];
extern unsigned _liseg[];
extern unsigned _eliseg[];
void (*payload)(void) = (void (*)(void))_iseg;
#endif
/*
* At this point we're running out of flash with our
@ -21,7 +23,9 @@ void (*payload)(void) = (void (*)(void))_iseg;
* - start hardwaremain() which does remainder of setup
*/
#ifndef __PPC64__
extern void flush_dcache(void);
#endif
void ppc_main(void)
{
@ -43,6 +47,7 @@ void ppc_main(void)
*/
board_init2();
#ifndef __PPC64__
/*
* Flush cache now that memory is enabled.
*/
@ -59,6 +64,7 @@ void ppc_main(void)
}
payload();
#endif
/* NOT REACHED */
}

View File

@ -7,6 +7,7 @@
* configuring the machine.
*/
#ifndef __PPC64__
#define ASM
#include "ppcreg.h"
#include <ppc_asm.tmpl>
@ -109,3 +110,5 @@ __DTOR_LIST__:
.globl __DTOR_END__
__DTOR_END__:
blr
#endif

View File

@ -15,8 +15,13 @@
*/
#include <ppc_asm.tmpl>
#ifndef __PPC64__
.globl __div64_32
__div64_32:
#else
.globl .__div64_32
.__div64_32:
#endif
lwz r5,0(r3) # get the dividend into r5/r6
lwz r6,4(r3)
cmplw r5,r4

View File

@ -28,8 +28,13 @@
/*
* unsigned long long _get_ticks(void);
*/
#ifndef __PPC64__
.globl _get_ticks
_get_ticks:
#else
.globl ._get_ticks
._get_ticks:
#endif
1: mftbu r3
mftb r4
mftbu r5
@ -40,17 +45,30 @@ _get_ticks:
/*
* Delay for a number of ticks
*/
#ifndef __PPC64__
.globl _wait_ticks
_wait_ticks:
#else
.globl ._wait_ticks
._wait_ticks:
#endif
mflr r8 /* save link register */
mr r7, r3 /* save tick count */
#ifndef __PPC64__
bl _get_ticks /* Get start time */
#else
bl ._get_ticks /* Get start time */
#endif
/* Calculate end time */
addc r7, r4, r7 /* Compute end time lower */
addze r6, r3 /* and end time upper */
#ifndef __PPC64__
1: bl _get_ticks /* Get current time */
#else
1: bl ._get_ticks /* Get current time */
#endif
subfc r4, r4, r7 /* Subtract current time from end time */
subfe. r3, r3, r6
bge 1b /* Loop until time expired */

View File

@ -11,5 +11,12 @@ uses USE_DCACHE_RAM
##
default USE_DCACHE_RAM=0
initinclude "FAMILY_INIT" cpu/ppc/ppc970/ppc970.inc
initinclude "EXCEPTION_VECTOR_TABLE" cpu/ppc/ppc970/ppc970excp.S
initinclude "PROCESSOR_INIT" cpu/ppc/ppc970/ppc970.inc
object clock.o
initobject clock.o
initobject ppc970lib.S
dir /cpu/simple_init

View File

@ -0,0 +1,27 @@
#include <ppc.h>
static int PLL_multiplier[] = {
25, /* 0000 - 2.5x */
75, /* 0001 - 7.5x */
70, /* 0010 - 7x */
10, /* 0011 - bypass */
20, /* 0100 - 2x */
65, /* 0101 - 6.5x */
100, /* 0110 - 10x */
45, /* 0111 - 4.5x */
30, /* 1000 - 3x */
55, /* 1001 - 5.5x */
40, /* 1010 - 4x */
50, /* 1011 - 5x */
80, /* 1100 - 8x */
60, /* 1101 - 6x */
35, /* 1110 - 3.5x */
0, /* 1111 - off */
};
unsigned long
get_timer_freq(void)
{
unsigned long clock = CONFIG_SYS_CLK_FREQ * 1000000;
return clock * PLL_multiplier[ppc_gethid1() >> 28] / 10;
}

View File

@ -1,365 +1,555 @@
/*bsp_970fx/bootlib/init_core.s, pibs_970, pibs_970_1.0 1/14/05 14:58:41*/
/*----------------------------------------------------------------------------+
| COPYRIGHT I B M CORPORATION 2002, 2004
| LICENSED MATERIAL - PROGRAM PROPERTY OF I B M
| US Government Users Restricted Rights - Use, duplication or
| disclosure restricted by GSA ADP Schedule Contract with
| IBM Corp.
+----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------+
| PPC970FX BSP for EPOS
| Author: Maciej P. Tyrlik
| Component: Boot library.
| File: init_core.s
| Purpose: Basic PPC405 core initialization.
| Changes:
| Date: Comment:
| ----- --------
| 29-Jan-02 Created MPT
| 30-Jan-02 Completed MPT
| 19-Apr-02 Changed some instructions to macros so that new GCC AS worksMPT
| 23-Apr-02 Removed critical interrupt enabling after rfi MPT
| 31-Jul-02 Fixed data cache invalidate code MPT
| 01-Feb-03 Ported to Argan 7XXFX CRB
| 07-Aug-03 Ported to PPC7XXGX CRB
| 12-Sep-03 Removed PVR definitions, now in board include file MCG
| 16-Sep-03 Do not enable HID0[MUM] or L2CR[L2CE] if 7XXGX DD1.0 MCG
| 31-Oct-03 Enable cache for MV64460 integrated SRAM MCG
| 07-Jan-04 Initialize FPRs to avoid errata. MCG
| 10-Feb-04 Port to PPC970FX MPT
+----------------------------------------------------------------------------*/
#include <ppc970.h>
/*----------------------------------------------------------------------------+
| Local defines.
+----------------------------------------------------------------------------*/
#define INITIAL_SLB_VSID_VAL 0x0000000000000C00
#define INITIAL_SLB_ESID_VAL 0x0000000008000000
#define INITIAL_SLB_INVA_VAL 0x0000000000000000
/*----------------------------------------------------------------------------+
| Init_core. Assumption: hypervisor on, 64-bit on, HID1[10]=0, HID4[23]=0.
| Data cahability must be turned on. Instruction cahability must be off.
+----------------------------------------------------------------------------*/
/*--------------------------------------------------------------------+
| Set time base to 0.
+--------------------------------------------------------------------*/
addi r4,r0,0x0000
mtspr SPR_TBU_WRITE,r4
mtspr SPR_TBL_WRITE,r4
/*--------------------------------------------------------------------+
| Set HID1[10] to 0 (instruction cache off) and set HID4[23] to 0 (data
| cache on), set HID4[DC_SET1] and HID4[DC_SET2] to 0.
+--------------------------------------------------------------------*/
LOAD_64BIT_VAL(r4,HID1_EN_IC)
nor r4,r4,r4
mfspr r5,SPR_HID1
isync
and r5,r5,r4
mtspr SPR_HID1,r5
mtspr SPR_HID1,r5
isync
LOAD_64BIT_VAL(r4,HID4_RM_CI|HID4_DC_SET1|HID4_DC_SET2)
nor r4,r4,r4
mfspr r5,SPR_HID4
LOAD_64BIT_VAL(r6,HID4_L1DC_FLSH)
isync
and r5,r5,r4
or r5,r5,r6
sync
mtspr SPR_HID4,r5
isync
/*--------------------------------------------------------------------+
| Clear the flash invalidate L1 data cache bit in HID4.
+--------------------------------------------------------------------*/
nor r6,r6,r6
and r5,r5,r6
sync
mtspr SPR_HID4,r5
isync
/*--------------------------------------------------------------------+
| Clear and set up some registers.
+--------------------------------------------------------------------*/
addi r4,r0,0x0000
mtxer r4
/*--------------------------------------------------------------------+
| Invalidate SLB. First load SLB with known values then perform
| invalidate. Invalidate will clear the D-ERAT and I-ERAT. The SLB
| is 64 entry fully associative. On power on D-ERAT and I-ERAT are all
| set to invalid values.
+--------------------------------------------------------------------*/
addi r5,r0,SLB_SIZE
mtctr r5
LOAD_64BIT_VAL(r6,INITIAL_SLB_VSID_VAL)
LOAD_64BIT_VAL(r7,INITIAL_SLB_ESID_VAL)
addis r8,r0,0x1000
0: slbmte r6,r7
addi r6,r6,0x1000
add r7,r7,r8
addi r7,r7,0x0001
bdnz 0b
mtctr r5
LOAD_64BIT_VAL(r6,INITIAL_SLB_INVA_VAL)
1: slbie r6
add r6,r6,r8
bdnz 1b
/*--------------------------------------------------------------------+
| Load SLB. Following is the initial memory map.
| Entry(6) ESID(36) VSID
| 0x0 0x000000000 0x0000000000000 (large page cachable)
| 0x1 0x00000000F 0x000000000000F (small non-cachable, G)
| at 0x00000000 there will be 48MB mapped (SDRAM)
| at 0xF8000000 there will be 16MB mapped (NB)
| at 0xF4000000 there will be 64KB mapped (I/O space)
| at 0xFF000000 there will be 16MB or 1MB mapped (FLASH)
+--------------------------------------------------------------------*/
addi r6,r0,0x0100
addis r7,r0,0x0800
slbmte r6,r7
addi r6,r0,0x0000
ori r6,r6,0xF000
addi r7,r0,0x0001
oris r7,r7,0xF800
slbmte r6,r7
/*--------------------------------------------------------------------+
| Invalidate all 1024 instruction and data TLBs (4 way)
+--------------------------------------------------------------------*/
addi r8,r0,0x0100
mtspr CTR,r8
addi r8,r0,0x0000
2: TLBIEL(r8)
addi r8,r8,0x1000
bdnz 2b
ptesync
/*--------------------------------------------------------------------+
| Dcbz the page table space. Calculate SDR1 address. Store SDR1
| address in r30.
+--------------------------------------------------------------------*/
mfspr r3,SPR_PIR
cmpi cr0,1,r3,0x0000
bne 3f
addis r3,r0,INITIAL_PAGE_TABLE_ADDR_CPU0@h
ori r3,r3,INITIAL_PAGE_TABLE_ADDR_CPU0@l
b 4f
3: addis r3,r0,INITIAL_PAGE_TABLE_ADDR_CPU1@h
ori r3,r3,INITIAL_PAGE_TABLE_ADDR_CPU1@l
4: addis r4,r0,INITIAL_PAGE_TABLE_SIZE@h
ori r4,r4,INITIAL_PAGE_TABLE_SIZE@l
rlwinm r5,r4,14,14,31
cntlzw r5,r5
subfic r5,r5,31
or r30,r3,r5
bl .ppcDcbz_area
/*--------------------------------------------------------------------+
| Setup 0x00000000FFFFFFFF mask in r29.
+--------------------------------------------------------------------*/
addi r29,r0,0x0001
rldicl r29,r29,32,31
addi r29,r29,-1
/*--------------------------------------------------------------------+
| Setup 48MB of addresses in DRAM in page table (3 large PTE). The
| parameters to p_ptegg are: r3 = lp, r4 = ea, r5 = sdr1, r6 = vsid.
+--------------------------------------------------------------------*/
addi r3,r0,0x0001
addi r4,r0,0x0000
ori r5,r30,0x0000
addi r6,r0,0x0000
bl .p_ptegg
addi r4,r0,0x0001
stw r4,0x0004(r3)
addi r4,r0,0x0180
stw r4,0x000C(r3)
/*--------------------------------------------------------------------+
| Second 16MB is mapped here.
+--------------------------------------------------------------------*/
addi r3,r0,0x0001
addis r4,r0,0x0100
ori r5,r30,0x0000
addi r6,r0,0x0000
bl .p_ptegg
addi r4,r0,0x0101
stw r4,0x0004(r3)
addis r4,r0,0x0100
ori r4,r4,0x0180
stw r4,0x000C(r3)
/*--------------------------------------------------------------------+
| Third 16MB is mapped here.
+--------------------------------------------------------------------*/
addi r3,r0,0x0001
addis r4,r0,0x0200
ori r5,r30,0x0000
addi r6,r0,0x0000
bl .p_ptegg
addi r4,r0,0x0201
stw r4,0x0004(r3)
addis r4,r0,0x0200
ori r4,r4,0x0180
stw r4,0x000C(r3)
/*--------------------------------------------------------------------+
| Setup 64KB of addresses in I/O space (0xF4000000).
+--------------------------------------------------------------------*/
addi r3,r0,0x0010
mtctr r3
addis r31,r0,0xF400
and r31,r31,r29
5: addi r3,r0,0x0000
ori r4,r31,0x0000
ori r5,r30,0x0000
addi r6,r0,0x000F
bl .p_ptegg
addi r6,r3,0x0080
6: lwz r4,0x0004(r3)
cmpli cr0,1,r4,0x0000
beq 8f
addi r3,r3,0x0010
cmp cr0,1,r3,r6
blt 6b
7: b 7b
8: rlwinm r4,r31,16,4,24
ori r4,r4,0x0001
stw r4,0x0004(r3)
ori r4,r31,0x01AC
stw r4,0x000C(r3)
addi r31,r31,0x1000
bdnz 5b
/*--------------------------------------------------------------------+
| Setup 16MB of addresses in NB register space (0xF8000000).
+--------------------------------------------------------------------*/
addi r3,r0,0x1000
mtctr r3
addis r31,r0,0xF800
and r31,r31,r29
9: addi r3,r0,0x0000
ori r4,r31,0x0000
ori r5,r30,0x0000
addi r6,r0,0x000F
bl .p_ptegg
addi r6,r3,0x0080
10: lwz r4,0x0004(r3)
cmpli cr0,1,r4,0x0000
beq 12f
addi r3,r3,0x0010
cmp cr0,1,r3,r6
blt 10b
11: b 11b
12: rlwinm r4,r31,16,4,24
ori r4,r4,0x0001
stw r4,0x0004(r3)
ori r4,r31,0x01AC
stw r4,0x000C(r3)
addi r31,r31,0x1000
bdnz 9b
/*--------------------------------------------------------------------+
| Setup 16MB or 1MB of addresses in ROM (at 0xFF000000 or 0xFFF00000).
+--------------------------------------------------------------------*/
mfspr r3,SPR_HIOR
LOAD_64BIT_VAL(r4,BOOT_BASE_AS)
cmpd cr0,r3,r4
beq 13f
addi r3,r0,0x0100
mtctr r3
addis r31,r0,0xFFF0
b 14f
13: addi r3,r0,0x1000
mtctr r3
addis r31,r0,0xFF00
14: and r31,r31,r29
15: addi r3,r0,0x0000
ori r4,r31,0x0000
ori r5,r30,0x0000
addi r6,r0,0x000F
bl .p_ptegg
addi r6,r3,0x0080
16: lwz r4,0x0004(r3)
cmpli cr0,1,r4,0x0000
beq 18f
addi r3,r3,0x0010
cmp cr0,1,r3,r6
blt 16b
17: b 17b
18: rlwinm r4,r31,16,4,24
ori r4,r4,0x0001
stw r4,0x0004(r3)
ori r4,r31,0x01A3
stw r4,0x000C(r3)
addi r31,r31,0x1000
bdnz 15b
/*--------------------------------------------------------------------+
| Synchronize after setting up page table.
+--------------------------------------------------------------------*/
ptesync
/*--------------------------------------------------------------------+
| Set the SDR1 register.
+--------------------------------------------------------------------*/
mtspr SPR_SDR1,r30
/*--------------------------------------------------------------------+
| Clear SRR0, SRR1.
+--------------------------------------------------------------------*/
addi r0,r0,0x0000
mtspr SPR_SRR0,r0
mtspr SPR_SRR1,r0
/*--------------------------------------------------------------------+
| Setup for subsequent MSR[ME] initialization to enable machine checks
| and translation.
+--------------------------------------------------------------------*/
mfmsr r3
ori r3,r3,(MSR_ME|MSR_IS|MSR_DS|MSR_FP)
mtsrr1 r3
mtmsrd r3,0
isync
/*--------------------------------------------------------------------+
| Setup HID registers (HID0, HID1, HID4, HID5). When HIOR is set to
| 0 HID0 external time base bit is inherited from current HID0. When
| HIOR is set to FLASH_BASE_INTEL_AS then HID0 external time base bit
| is set to 1 in order to indicate that the tiembase is driven by
| external source. When HIOR is greater than FLASH_BASE_INTEL_AS then
| HID0 external time base bit is set to 0 in order to indicate that the
| tiembase is driven from internal clock.
+--------------------------------------------------------------------*/
LOAD_64BIT_VAL(r6,HID0_EXT_TB_EN)
LOAD_64BIT_VAL(r7,FLASH_BASE_INTEL_AS)
mfspr r5,SPR_HIOR
cmpdi cr0,r5,0x0000
beq 19f
cmpd cr0,r5,r7
beq 20f
addi r8,r0,0x0000
b 21f
20: ori r8,r6,0x0000
b 21f
19: mfspr r5,SPR_HID0
and r8,r5,r6
21: LOAD_64BIT_VAL(r4,HID0_PREFEAR)
andc r4,r4,r6
or r4,r4,r8
sync
mtspr SPR_HID0,r4
mfspr r4,SPR_HID0
mfspr r4,SPR_HID0
mfspr r4,SPR_HID0
mfspr r4,SPR_HID0
mfspr r4,SPR_HID0
mfspr r4,SPR_HID0
LOAD_64BIT_VAL(r4,HID1_PREFEAR)
mtspr SPR_HID1,r4
mtspr SPR_HID1,r4
isync
LOAD_64BIT_VAL(r4,HID4_PREFEAR)
sync
mtspr SPR_HID4,r4
isync
sync
LOAD_64BIT_VAL(r4,HID5_PREFEAR)
mtspr SPR_HID5,r4
isync
/*--------------------------------------------------------------------+
| Synchronize memory accesses (sync).
+--------------------------------------------------------------------*/
sync
LOAD_64BIT_VAL(r0,.init_chip)
mfspr r1,SPR_HIOR
or r0,r0,r1
eieio
mtspr SPR_SRR0,r0
rfid
#include <ppc970.h>
/******** init_core.s ***************/
/*----------------------------------------------------------------------------+
| Local defines.
+----------------------------------------------------------------------------*/
#define INITIAL_SLB_VSID_VAL 0x0000000000000C00
#define INITIAL_SLB_ESID_VAL 0x0000000008000000
#define INITIAL_SLB_INVA_VAL 0x0000000000000000
/*----------------------------------------------------------------------------+
| Init_core. Assumption: hypervisor on, 64-bit on, HID1[10]=0, HID4[23]=0.
| Data cahability must be turned on. Instruction cahability must be off.
+----------------------------------------------------------------------------*/
function_prolog(init_core)
/*--------------------------------------------------------------------+
| Set time base to 0.
+--------------------------------------------------------------------*/
addi r4,r0,0x0000
mtspr SPR_TBU_WRITE,r4
mtspr SPR_TBL_WRITE,r4
/*--------------------------------------------------------------------+
| Set HID1[10] to 0 (instruction cache off) and set HID4[23] to 0 (data
| cache on), set HID4[DC_SET1] and HID4[DC_SET2] to 0.
+--------------------------------------------------------------------*/
LOAD_64BIT_VAL(r4,HID1_EN_IC)
nor r4,r4,r4
mfspr r5,SPR_HID1
isync
and r5,r5,r4
mtspr SPR_HID1,r5
mtspr SPR_HID1,r5
isync
LOAD_64BIT_VAL(r4,HID4_RM_CI|HID4_DC_SET1|HID4_DC_SET2)
nor r4,r4,r4
mfspr r5,SPR_HID4
LOAD_64BIT_VAL(r6,HID4_L1DC_FLSH)
isync
and r5,r5,r4
or r5,r5,r6
sync
mtspr SPR_HID4,r5
isync
/*--------------------------------------------------------------------+
| Clear the flash invalidate L1 data cache bit in HID4.
+--------------------------------------------------------------------*/
nor r6,r6,r6
and r5,r5,r6
sync
mtspr SPR_HID4,r5
isync
/*--------------------------------------------------------------------+
| Clear and set up some registers.
+--------------------------------------------------------------------*/
addi r4,r0,0x0000
mtxer r4
/*--------------------------------------------------------------------+
| Invalidate SLB. First load SLB with known values then perform
| invalidate. Invalidate will clear the D-ERAT and I-ERAT. The SLB
| is 64 entry fully associative. On power on D-ERAT and I-ERAT are all
| set to invalid values.
+--------------------------------------------------------------------*/
addi r5,r0,SLB_SIZE
mtctr r5
LOAD_64BIT_VAL(r6,INITIAL_SLB_VSID_VAL)
LOAD_64BIT_VAL(r7,INITIAL_SLB_ESID_VAL)
addis r8,r0,0x1000
..slbl: slbmte r6,r7
addi r6,r6,0x1000
add r7,r7,r8
addi r7,r7,0x0001
bdnz ..slbl
mtctr r5
LOAD_64BIT_VAL(r6,INITIAL_SLB_INVA_VAL)
..slbi: slbie r6
add r6,r6,r8
bdnz ..slbi
/*--------------------------------------------------------------------+
| Load SLB. Following is the initial memory map.
| Entry(6) ESID(36) VSID
| 0x0 0x000000000 0x0000000000000 (large page cachable)
| 0x1 0x00000000F 0x000000000000F (small non-cachable, G)
| at 0x00000000 there will be 32MB mapped (SDRAM)
| at 0xF8000000 there will be 16MB mapped (NB)
| at 0xF4000000 there will be 64KB mapped (I/O space)
| at 0xFF000000 there will be 16MB or 1MB mapped (FLASH)
+--------------------------------------------------------------------*/
addi r6,r0,0x0100
addis r7,r0,0x0800
slbmte r6,r7
addi r6,r0,0x0000
ori r6,r6,0xF000
addi r7,r0,0x0001
oris r7,r7,0xF800
slbmte r6,r7
/*--------------------------------------------------------------------+
| Invalidate all 1024 instruction and data TLBs (4 way)
+--------------------------------------------------------------------*/
addi r8,r0,0x0100
mtspr ctr,r8
addi r8,r0,0x0000
..ivt: TLBIEL(r8)
addi r8,r8,0x1000
bdnz ..ivt
ptesync
/*--------------------------------------------------------------------+
| Dcbz the page table space. Calculate SDR1 address. Store SDR1
| address in r30.
+--------------------------------------------------------------------*/
mfspr r3,SPR_PIR
cmpi cr0,1,r3,0x0000
bne ..cpu1_init_core
addis r3,r0,INITIAL_PAGE_TABLE_ADDR_CPU0@h
ori r3,r3,INITIAL_PAGE_TABLE_ADDR_CPU0@l
b ..skcpu
..cpu1_init_core: addis r3,r0,INITIAL_PAGE_TABLE_ADDR_CPU1@h
ori r3,r3,INITIAL_PAGE_TABLE_ADDR_CPU1@l
..skcpu:addis r4,r0,INITIAL_PAGE_TABLE_SIZE@h
ori r4,r4,INITIAL_PAGE_TABLE_SIZE@l
rlwinm r5,r4,14,14,31
cntlzw r5,r5
subfic r5,r5,31
or r30,r3,r5
bl .ppcDcbz_area
/*--------------------------------------------------------------------+
| Setup 0x00000000FFFFFFFF mask in r29.
+--------------------------------------------------------------------*/
addi r29,r0,0x0001
rldicl r29,r29,32,31
addi r29,r29,-1
/*--------------------------------------------------------------------+
| Setup 32MB of addresses in DRAM in page table (2 large PTE). The
| parameters to p_ptegg are: r3 = lp, r4 = ea, r5 = sdr1, r6 = vsid.
+--------------------------------------------------------------------*/
addi r3,r0,0x0001
addi r4,r0,0x0000
ori r5,r30,0x0000
addi r6,r0,0x0000
bl .p_ptegg
addi r4,r0,0x0001
stw r4,0x0004(r3)
addi r4,r0,0x0180
stw r4,0x000C(r3)
/*--------------------------------------------------------------------+
| Second 32MB is mapped here.
+--------------------------------------------------------------------*/
addi r3,r0,0x0001
addis r4,r0,0x0100
ori r5,r30,0x0000
addi r6,r0,0x0000
bl .p_ptegg
addi r4,r0,0x0101
stw r4,0x0004(r3)
addis r4,r0,0x0100
ori r4,r4,0x0180
stw r4,0x000C(r3)
/*--------------------------------------------------------------------+
| Setup 64KB of addresses in I/O space (0xF4000000).
+--------------------------------------------------------------------*/
addi r3,r0,0x0010
mtctr r3
addis r31,r0,0xF400
and r31,r31,r29
..aF4: addi r3,r0,0x0000
ori r4,r31,0x0000
ori r5,r30,0x0000
addi r6,r0,0x000F
bl .p_ptegg
addi r6,r3,0x0080
..aF4a: lwz r4,0x0004(r3)
cmpli cr0,1,r4,0x0000
beq ..aF4s
addi r3,r3,0x0010
cmp cr0,1,r3,r6
blt ..aF4a
..aF4h: b ..aF4h
..aF4s: rlwinm r4,r31,16,4,24
ori r4,r4,0x0001
stw r4,0x0004(r3)
ori r4,r31,0x01AC
stw r4,0x000C(r3)
addi r31,r31,0x1000
bdnz ..aF4
/*--------------------------------------------------------------------+
| Setup 16MB of addresses in NB register space (0xF8000000).
+--------------------------------------------------------------------*/
addi r3,r0,0x1000
mtctr r3
addis r31,r0,0xF800
and r31,r31,r29
..aF8: addi r3,r0,0x0000
ori r4,r31,0x0000
ori r5,r30,0x0000
addi r6,r0,0x000F
bl .p_ptegg
addi r6,r3,0x0080
..aF8a: lwz r4,0x0004(r3)
cmpli cr0,1,r4,0x0000
beq ..aF8s
addi r3,r3,0x0010
cmp cr0,1,r3,r6
blt ..aF8a
..aF8h: b ..aF8h
..aF8s: rlwinm r4,r31,16,4,24
ori r4,r4,0x0001
stw r4,0x0004(r3)
ori r4,r31,0x01AC
stw r4,0x000C(r3)
addi r31,r31,0x1000
bdnz ..aF8
/*--------------------------------------------------------------------+
| Setup 16MB or 1MB of addresses in ROM (at 0xFF000000 or 0xFFF00000).
+--------------------------------------------------------------------*/
mfspr r3,SPR_HIOR
LOAD_64BIT_VAL(r4,BOOT_BASE_AS)
cmpd cr0,r3,r4
beq ..big
addi r3,r0,0x0100
mtctr r3
addis r31,r0,0xFFF0
b ..done
..big: addi r3,r0,0x1000
mtctr r3
addis r31,r0,0xFF00
..done: and r31,r31,r29
..aFF: addi r3,r0,0x0000
ori r4,r31,0x0000
ori r5,r30,0x0000
addi r6,r0,0x000F
bl .p_ptegg
addi r6,r3,0x0080
..aFFa: lwz r4,0x0004(r3)
cmpli cr0,1,r4,0x0000
beq ..aFFs
addi r3,r3,0x0010
cmp cr0,1,r3,r6
blt ..aFFa
..aFFh: b ..aFFh
..aFFs: rlwinm r4,r31,16,4,24
ori r4,r4,0x0001
stw r4,0x0004(r3)
ori r4,r31,0x01A3
stw r4,0x000C(r3)
addi r31,r31,0x1000
bdnz ..aFF
/*--------------------------------------------------------------------+
| Synchronize after setting up page table.
+--------------------------------------------------------------------*/
ptesync
/*--------------------------------------------------------------------+
| Set the SDR1 register.
+--------------------------------------------------------------------*/
mtspr SPR_SDR1,r30
/*--------------------------------------------------------------------+
| Clear SRR0, SRR1.
+--------------------------------------------------------------------*/
addi r0,r0,0x0000
mtspr SPR_SRR0,r0
mtspr SPR_SRR1,r0
/*--------------------------------------------------------------------+
| Setup for subsequent MSR[ME] initialization to enable machine checks
| and translation.
+--------------------------------------------------------------------*/
mfmsr r3
ori r3,r3,(MSR_ME|MSR_IS|MSR_DS|MSR_FP)
mtsrr1 r3
mtmsrd r3,0
isync
/*--------------------------------------------------------------------+
| Setup HID registers (HID0, HID1, HID4, HID5). When HIOR is set to
| 0 HID0 external time base bit is inherited from current HID0. When
| HIOR is set to FLASH_BASE_INTEL_AS then HID0 external time base bit
| is set to 1 in order to indicate that the tiembase is driven by
| external source. When HIOR is greater than FLASH_BASE_INTEL_AS then
| HID0 external time base bit is set to 0 in order to indicate that the
| tiembase is driven from internal clock.
+--------------------------------------------------------------------*/
LOAD_64BIT_VAL(r6,HID0_EXT_TB_EN)
LOAD_64BIT_VAL(r7,FLASH_BASE_INTEL_AS)
mfspr r5,SPR_HIOR
cmpdi cr0,r5,0x0000
beq ..hior0
cmpd cr0,r5,r7
beq ..hiorl
addi r8,r0,0x0000
b ..hiors
..hiorl:ori r8,r6,0x0000
b ..hiors
..hior0:mfspr r5,SPR_HID0
and r8,r5,r6
..hiors:LOAD_64BIT_VAL(r4,HID0_PREFEAR)
andc r4,r4,r6
or r4,r4,r8
sync
mtspr SPR_HID0,r4
mfspr r4,SPR_HID0
mfspr r4,SPR_HID0
mfspr r4,SPR_HID0
mfspr r4,SPR_HID0
mfspr r4,SPR_HID0
mfspr r4,SPR_HID0
LOAD_64BIT_VAL(r4,HID1_PREFEAR)
mtspr SPR_HID1,r4
mtspr SPR_HID1,r4
isync
LOAD_64BIT_VAL(r4,HID4_PREFEAR)
sync
mtspr SPR_HID4,r4
isync
sync
LOAD_64BIT_VAL(r4,HID5_PREFEAR)
mtspr SPR_HID5,r4
isync
/*--------------------------------------------------------------------+
| Synchronize memory accesses (sync).
+--------------------------------------------------------------------*/
sync
LOAD_64BIT_VAL(r0,.init_chip)
mfspr r1,SPR_HIOR
or r0,r0,r1
eieio
mtspr SPR_SRR0,r0
rfid
function_epilog(init_core)
/******** init_chip.s ***************/
/*----------------------------------------------------------------------------+
| Local defines.
+----------------------------------------------------------------------------*/
#define CPU1_DELAY 0x00010000
/*----------------------------------------------------------------------------+
| Init_chip.
+----------------------------------------------------------------------------*/
function_prolog(init_chip)
/*--------------------------------------------------------------------+
| Skip if CPU1.
+--------------------------------------------------------------------*/
mfspr r3,SPR_PIR
cmpi cr0,1,r3,0x0000
bne ..cpu1
/*--------------------------------------------------------------------+
| Initialize the stack in the data cache for the "C" code that gets
| called.
+--------------------------------------------------------------------*/
addis r3,r0,BOOT_STACK_ADDR@h
ori r3,r3,BOOT_STACK_ADDR@l
addis r4,r0,BOOT_STACK_SIZE@h
ori r4,r4,BOOT_STACK_SIZE@l
add r1,r3,r4
bl .ppcDcbz_area
addi r1,r1,-stack_frame_min
addi r5,r0,0x0000
std r5,stack_frame_bc(r1)
/*--------------------------------------------------------------------+
| Load TOC. Can't use ld since the TOC value might not be aligned on
| double word boundary.
+--------------------------------------------------------------------*/
bl ..ot_init_chip
.quad .TOC.@tocbase
..ot_init_chip: mflr r3
lwz r2,0x0000(r3)
lwz r3,0x0004(r3)
rldicr r2,r2,32,31
or r2,r2,r3
mfspr r3,SPR_HIOR
or r2,r2,r3
/*--------------------------------------------------------------------+
| Code for chip initialization code goes here. Subtractive decoding
| allows access to specified registers.
+--------------------------------------------------------------------*/
bl .super_io_setup
/*--------------------------------------------------------------------+
| Setup default serial port using default baud rate.
+--------------------------------------------------------------------*/
// bl .sinit_default_no_global
/*--------------------------------------------------------------------+
| Enable SDRAM only if running from FLASH.
+--------------------------------------------------------------------*/
mflr r3
LOAD_64BIT_VAL(r4,BOOT_BASE_AS)
cmpld cr0,r3,r4
blt ..skip
bl memory_init
/*--------------------------------------------------------------------+
| Check the memory where PIBS data section will be placed.
+--------------------------------------------------------------------*/
..skip: bl ..skip_data
.string "\nMemory check failed at 0x%x, expected 0x%x, actual 0x%x"
.align 2
..skip_data:
addis r3,r0,MEM_CHK_START_ADDR@h
ori r3,r3,MEM_CHK_START_ADDR@l
addis r4,r0,MEM_CHK_SIZE@h
ori r4,r4,MEM_CHK_SIZE@l
mflr r5
// bl mem_check
/*--------------------------------------------------------------------+
| Initialize RAM area that holds boot information for CPU1.
+--------------------------------------------------------------------*/
LOAD_64BIT_VAL(r31,CPU1_DATA_STRUCT_ADDR)
addi r3,r0,0x0000
std r3,CPU1_DATA_STRUCT_VALID_OFF(r31)
/*--------------------------------------------------------------------+
| DCBZ area stack is left in the cache since there is no way to
| invalidate data cache. This area will be written to memory at some
| point. Main memory should be functional at this point.
+--------------------------------------------------------------------*/
b .init_data
/*--------------------------------------------------------------------+
| CPU1 will spin waiting for the CPU0 to initialize the system. CPU1
| then will check if the image for CPU1 has been loaded. If the image
| for CPU1 has been loaded CPU1 will jump to that image. If the image
| for CPU1 has not been loaded CPU1 will spin waiting for the image to
| be loaded.
+--------------------------------------------------------------------*/
..cpu1: LOAD_64BIT_VAL(r31,NB_HW_INIT_STATE_ASM)
lwz r30,0x0000(r31)
cmpi cr0,1,r30,0x0000
beq ..cpu1
/*--------------------------------------------------------------------+
| Jump to SDRAM (cachable storage) and wait there.
+--------------------------------------------------------------------*/
sync
ba ..loada
/*--------------------------------------------------------------------+
| Wait for image valid indicator.
+--------------------------------------------------------------------*/
..loada:LOAD_64BIT_VAL(r31,CPU1_DATA_STRUCT_ADDR)
ld r3,CPU1_DATA_STRUCT_VALID_OFF(r31)
cmpi cr0,1,r3,0x0000
beq ..spin2
ld r3,CPU1_DATA_STRUCT_SRR0_OFF(r31)
mtspr SPR_SRR0,r3
ld r4,CPU1_DATA_STRUCT_SRR1_OFF(r31)
mtspr SPR_SRR1,r4
ld r3,CPU1_DATA_STRUCT_R3_OFF(r31)
isync
rfid
..spin2:mfspr r29,tblr
LOAD_64BIT_VAL(r31,CPU1_DELAY)
..spin3:mfspr r30,tblr
subf r30,r29,r30
cmp cr0,1,r30,r31
blt ..spin3
b ..loada
function_epilog(init_chip)
/******** init_data.s ***************/
/*----------------------------------------------------------------------------+
| Init_data.
+----------------------------------------------------------------------------*/
function_prolog(init_data)
/*--------------------------------------------------------------------+
| Check if we are running from FLASH. If running from FLASH copy 1M
| of FLASH to SDRAM.
+--------------------------------------------------------------------*/
bl ..next
..next: mflr r3
LOAD_64BIT_VAL(r4,BOOT_BASE_AS)
cmpld cr0,r3,r4
blt ..sk_c
/*--------------------------------------------------------------------+
| Perform the copy operation. This copies data starting from SPR_HIOR
| for number of bytes queal to __edata - __stext.
+--------------------------------------------------------------------*/
LOAD_64BIT_VAL(r6,__stext)
addi r3,r6,-8
mfspr r4,SPR_HIOR
addi r4,r4,-8
LOAD_64BIT_VAL(r5,__edata);
sub r5,r5,r6
rlwinm r5,r5,29,3,31
addi r5,r5,0x0001
mtctr r5
..again1:ldu r6,0x0008(r4)
stdu r6,0x0008(r3)
bdnz ..again1
/*--------------------------------------------------------------------+
| Get the size of BSS into r6.
+--------------------------------------------------------------------*/
..sk_c: LOAD_64BIT_VAL(r4,__sbss)
LOAD_64BIT_VAL(r5,__ebss)
sub r6,r5,r4
/*--------------------------------------------------------------------+
| Clear BSS.
+--------------------------------------------------------------------*/
addi r8,r4,-1
mtspr ctr,r6
addi r9,r0,0x0000
..bag: stbu r9,0x0001(r8)
bdnz ..bag
/*--------------------------------------------------------------------+
| Synchronize.
+--------------------------------------------------------------------*/
sync
ba .init_cenv
function_epilog(init_data)
/******** init_cenv.s ***************/
/*----------------------------------------------------------------------------+
| TOC entry for __initial_stack.
+----------------------------------------------------------------------------*/
TOC_ENTRY(.LC0,__initial_stack)
/*----------------------------------------------------------------------------+
| Initial stack.
+----------------------------------------------------------------------------*/
data_prolog(__initial_stack)
.space MY_MAIN_STACK_SIZE
data_epilog(__initial_stack)
/*----------------------------------------------------------------------------+
| Init_cenv.
+----------------------------------------------------------------------------*/
function_prolog(init_cenv)
/*--------------------------------------------------------------------+
| Load TOC. Can't use ld since the TOC value might not be aligned on
| double word boundary. R2 is loaded for the first time here when
| loaded by PIBS (second time when originally running from FLASH).
+--------------------------------------------------------------------*/
bl ..ot
.quad .TOC.@tocbase
..ot: mflr r3
lwz r2,0x0000(r3)
lwz r3,0x0004(r3)
rldicr r2,r2,32,31
or r2,r2,r3
/*--------------------------------------------------------------------+
| Get the address and size of the stack.
+--------------------------------------------------------------------*/
GETSYMADDR(r3,__initial_stack,.LC0)
addis r4,r0,MY_MAIN_STACK_SIZE@h
ori r4,r4,MY_MAIN_STACK_SIZE@l
/*--------------------------------------------------------------------+
| Setup the stack, stack bust be quadword (128-bit) aligned.
+--------------------------------------------------------------------*/
add r1,r3,r4
addi r1,r1,-stack_frame_min
rldicr r1,r1,0,59
addi r5,r0,0x0000
std r5,stack_frame_bc(r1)
std r5,stack_frame_lr(r1)
/*--------------------------------------------------------------------+
| Call the "C" function.
+--------------------------------------------------------------------*/
// b .my_main
b .ppc_main
..spin: b ..spin
function_epilog(init_cenv)

11
src/cpu/ppc/ppc970/ppc970excp.S Executable file
View File

@ -0,0 +1,11 @@
#include <ppc970.h>
/*----------------------------------------------------------------------------+
| Init_excp. The external interrupt vector should never be called before
| io_init() is called so it can be removed from this file.
+----------------------------------------------------------------------------*/
function_prolog(init_excp)
.space 0x100
b .init_core /* 0100 */
function_epilog(init_excp)

5027
src/cpu/ppc/ppc970/ppc970lib.S Executable file

File diff suppressed because it is too large Load Diff

View File

@ -137,5 +137,6 @@ default _ROMSTART=0xfff03000
## linuxBIOS C code runs at this location in RAM
default _RAMBASE=0x00100000
default CROSS_COMPILE="powerpc-405-linux-gnu-"
### End Options.lb
end

View File

@ -5,60 +5,61 @@
##
## Early board initialization, called from ppc_main()
##
#initobject init.c
initobject init.c
initobject mainboard.c
initobject boardutil.c
initobject timerspeed.S
arch ppc end
chip northbridge/ibm/cpc925
device pci_domain 0 on
device pci 00.0 on end
device pci 00.1 on end
device pci 01.0 on end
device pci 02.0 on
chip southbridge/intel/pxhd # pxhd1
device pci 00.0 on end
device pci 00.1 on end
device pci 00.2 on
chip drivers/generic/generic
device pci 04.0 on end
device pci 04.1 on end
end
chip southbridge/amd/amd8131
device pci 01.0 on #PCI-X Bridge
chip drivers/pci/onboard #intel GD31244 chip
device pci 01.0 on end #SATA controller
end
device pci 00.3 on end
end
end
device pci 06.0 on end
chip southbridge/intel/ich5r # ich5r
device pci 1d.0 on end
device pci 1d.1 on end
device pci 1d.2 on end
device pci 1d.3 off end
device pci 1d.7 on end
device pci 1e.0 on
device pci 01.1 on end #APIC controller
device pci 02.0 on end #PCI-X Bridge
device pci 02.1 on end #APIC controller
device pci 03.0 on #PCI-X Bridge
chip drivers/pci/onboard #intel i82546EB chip
device pci 01.0 on end #GB Ethernet 0
device pci 01.1 on end #GB Ethernet 1
end
end
device pci 03.1 on end #APIC controller
device pci 04.0 on end #PCI-X Bridge
device pci 04.1 on end #APIC controller
end #amd8131
chip southbridge/amd/amd8111
device pci 5.0 on #PCI Bridge
device pci 0.0 on end #USB Controller 0
device pci 0.1 on end #USB Controller 1
device pci 0.2 on end #USB Controller 2
device pci 1.0 on end #10/100 Ethernet Controller
chip drivers/ati/ragexl
device pci 0c.0 on end
device pci 3.0 on end # ATI Rage Video Controller
end
end
device pci 1f.0 on
chip superio/NSC/pc87427
device pci 6.0 on #ISA Bridge/LPC Controller
chip superio/NSC/pc87427 #NSC Super IO chip
device pnp 2e.0 off end
device pnp 2e.2 on
# io 0x60 = 0x2f8
# irq 0x70 = 3
io 0x60 = 0x3f8
io 0x60 = 0x3f8
irq 0x70 = 4
end
device pnp 2e.3 on
# io 0x60 = 0x3f8
# irq 0x70 = 4
io 0x60 = 0x2f8
io 0x60 = 0x2f8
irq 0x70 = 3
end
device pnp 2e.4 off end
device pnp 2e.5 off end
device pnp 2e.6 on
io 0x60 = 0x60
io 0x62 = 0x64
io 0x60 = 0x60
io 0x62 = 0x64
irq 0x70 = 1
end
device pnp 2e.7 off end
@ -67,36 +68,18 @@ chip northbridge/ibm/cpc925
device pnp 2e.f on end
device pnp 2e.10 off end
device pnp 2e.14 off end
end
end
device pci 1f.1 on end
device pci 1f.2 off end
device pci 1f.3 on end
device pci 1f.5 off end
device pci 1f.6 off end
register "gpio[40]" = "ICH5R_GPIO_USE_AS_GPIO"
register "gpio[48]" = "ICH5R_GPIO_USE_AS_GPIO | ICH5R_GPIO_SEL_OUTPUT | ICH5R_GPIO_LVL_LOW"
register "gpio[41]" = "ICH5R_GPIO_USE_AS_GPIO | ICH5R_GPIO_SEL_INPUT"
end
end
device apic_cluster 0 on
chip cpu/ppc/ppc970 # cpu 0
end
chip cpu/ppc/ppc970 # cpu 1
end
end
end
end #NSC Super IO chip
end #ISA Bridge/LPC
device pci 6.1 on end #IDE Controller
device pci 6.2 on end #SMBus Controller
device pci 6.3 on end #ACPI
device pci 6.5 off end #AC97 Audio
device pci 6.6 off end #MC97 Modem
end #amd8111
end #pci domain 0
end #cpc925
chip cpu/ppc/ppc4xx
device pci_domain 0 on
device pci 0.0 on end
chip southbridge/winbond/w83c553
device pci 9.0 on end # ISA bridge
device pci 9.1 on end # IDE contoller
end
device pci e.0 on end
end
chip cpu/ppc/ppc970
end
##

View File

@ -0,0 +1,406 @@
/*
* Copyright (C) 2003, Greg Watson <gwatson@lanl.gov>
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
/*
* Do very early board initialization:
*
* - Configure External Bus (EBC)
* - Setup Flash
* - Setup NVRTC
* - Setup Board Control and Status Registers (BCSR)
* - Enable UART0 for debugging
*/
#include "boardutil.h"
#include "ppc970lib.h"
#include "ppc970.h"
#include "stddef.h"
#include "string.h"
/*----------------------------------------------------------------------------+
| What_platform.
+----------------------------------------------------------------------------*/
int what_platform()
{
#ifdef PPC970FX_EVB_LITE
return(PLATFORM_EVB_LITE);
#endif
#ifdef PPC970FX_EVB
return(PLATFORM_EVB_FINAL);
#endif
}
/*----------------------------------------------------------------------------+
| Get_system_info. Cannot access any global variables in this function.
+----------------------------------------------------------------------------*/
void get_system_info(board_cfg_data_t *board_cfg)
{
unsigned long msr;
unsigned long data;
if (board_cfg==NULL) {
(void)ppcHalt();
}
msr=ppcAndMsr((unsigned long)~MSR_EE);
board_cfg->usr_config_ver[0]='1';
board_cfg->usr_config_ver[1]='.';
board_cfg->usr_config_ver[2]='0';
board_cfg->usr_config_ver[3]='\0';
/*-------------------------------------------------------------------------+
| Read power status register.
+-------------------------------------------------------------------------*/
data=read_psr()&SCOM_PSR_FREQ_MASK;
if (data==SCOM_PSR_FREQ_FULL) {
board_cfg->freq_ratio=1;
} else if (data==SCOM_PSR_FREQ_HALF) {
board_cfg->freq_ratio=2;
} else if (data==SCOM_PSR_FREQ_QUARTER) {
board_cfg->freq_ratio=4;
} else {
board_cfg->freq_ratio=0;
}
/*-------------------------------------------------------------------------+
| Read information passed from service processor.
+-------------------------------------------------------------------------*/
if (get_ei_ratio(&data)==0) {
board_cfg->ei_ratio=data;
} else {
board_cfg->ei_ratio=0;
}
if (get_sys_clk(&data)==0) {
board_cfg->sys_freq=data;
} else {
board_cfg->sys_freq=0;
}
if (get_pll_mult(&data)==0) {
if (board_cfg->freq_ratio!=0) {
board_cfg->cpu_freq=(board_cfg->sys_freq* data)/ board_cfg->freq_ratio;
} else {
board_cfg->cpu_freq=0;
}
} else {
data=0;
board_cfg->cpu_freq=0;
}
/*-------------------------------------------------------------------------+
| On some boards we have to execute with timers running on internal clock.
+-------------------------------------------------------------------------*/
if ((ppcMfspr_any(SPR_HID0)&HID0_EXT_TB_EN)==0) {
board_cfg->tmr_freq=(board_cfg->sys_freq* data)/ PPC970_TB_RATIO;
} else {
board_cfg->tmr_freq=EXT_TIME_BASE_FREQ;
}
/*-------------------------------------------------------------------------+
| If the above calculation did not yield valid timer speed try to estimate
| it.
+-------------------------------------------------------------------------*/
if (board_cfg->tmr_freq==0) {
board_cfg->tmr_freq=timebase_speed_calc(UART1_MMIO_BASE);
}
/*-------------------------------------------------------------------------+
| Read information passed from service processor.
+-------------------------------------------------------------------------*/
board_cfg->mem_size=sdram_size();
/*-------------------------------------------------------------------------+
| Assign rest of the information.
+-------------------------------------------------------------------------*/
board_cfg->ser_freq=UART_INPUT_CLOCK;
board_cfg->procver=ppcMfspr_any(SPR_PVR);
board_cfg->hid0=ppcMfspr_any(SPR_HID0);
board_cfg->hid1=ppcMfspr_any(SPR_HID1);
board_cfg->hid4=ppcMfspr_any(SPR_HID4);
board_cfg->hid5=ppcMfspr_any(SPR_HID5);
board_cfg->hior=ppcMfspr_any(SPR_HIOR);
board_cfg->sdr1=ppcMfspr_any(SPR_SDR1);
board_cfg->procstr[0]='9';
board_cfg->procstr[1]='7';
board_cfg->procstr[2]='0';
board_cfg->procstr[3]='F';
board_cfg->procstr[4]='X';
board_cfg->procstr[5]='\0';
board_cfg->reserved[0]='\0';
(void)get_hwd_addr((char *)board_cfg->hwaddr0, 0);
(void)ppcMtmsr(msr);
return;
}
/*----------------------------------------------------------------------------+
| Get_hwd_addr.
+----------------------------------------------------------------------------*/
int get_hwd_addr(char *dest,
int ethernet_num)
{
bios_data_struct_t *bios_data;
char *src;
unsigned char nc;
int len;
int num;
bios_data=(bios_data_struct_t *)PIBS_DATABASE_ADDR;
if (ethernet_num!=0) {
for(len=0;len<ETHERNET_HW_ADDR_LEN;len++) {
dest[len]=(char)0xFF;
}
return(-1);
} else {
src=bios_data->bios_eth_hwd0;
}
len=0;
while((src[len]!='\0') && (len<(ETHERNET_HW_ADDR_LEN* 3))) {
len++;
}
if (len!=(ETHERNET_HW_ADDR_LEN* 2)) {
for(len=0;len<ETHERNET_HW_ADDR_LEN;len++) {
dest[len]=(char)0xFF;
}
return(-1);
}
for(len=0;len<(ETHERNET_HW_ADDR_LEN* 2);len++) {
nc=toupper((int)src[len]);
if ((nc>='0') && (nc<='9')) {
num=nc- '0';
} else if ((nc>='A') && (nc<='F')) {
num=nc- 'A'+ 0xA;
} else {
for(len=0;len<ETHERNET_HW_ADDR_LEN;len++) {
dest[len]=(char)0xFF;
}
return(-1);
}
if ((len%2)==0) {
dest[len/ 2]=(char)num;
} else {
dest[len/ 2]=(char)((dest[len/ 2]* 0x10)+ num);
}
}
return(0);
}
/*----------------------------------------------------------------------------+
| Get_sys_clk.
+----------------------------------------------------------------------------*/
int get_sys_clk(unsigned long *value)
{
unsigned long data;
if (read_sp_data(SUPER_IO_NVRAM_DATA_VALID, 4, &data)!=0) {
return(-1);
}
if (data!=SUPER_IO_VALID_VALUE) {
return(-1);
}
if (read_sp_data(SUPER_IO_NVRAM_SYS_CLK, 4, &data)!=0) {
return(-1);
}
*value=data;
return(0);
}
/*----------------------------------------------------------------------------+
| Get_pll_mult.
+----------------------------------------------------------------------------*/
int get_pll_mult(unsigned long *value)
{
unsigned long data;
if (read_sp_data(SUPER_IO_NVRAM_DATA_VALID, 4, &data)!=0) {
return(-1);
}
if (data!=SUPER_IO_VALID_VALUE) {
return(-1);
}
if (read_sp_data(SUPER_IO_NVRAM_CLK_MULT, 1, value)!=0) {
return(-1);
}
return(0);
}
/*----------------------------------------------------------------------------+
| Get_ei_ratio.
+----------------------------------------------------------------------------*/
int get_ei_ratio(unsigned long *value)
{
unsigned long data;
if (read_sp_data(SUPER_IO_NVRAM_DATA_VALID, 4, &data)!=0) {
return(-1);
}
if (data!=SUPER_IO_VALID_VALUE) {
return(-1);
}
if (read_sp_data(SUPER_IO_NVRAM_EI_RATIO, 1, &data)!=0) {
return(-1);
}
if (data==0x0000000000000000) data=PPC970_EI_RATIO_000;
else if (data==0x0000000000000001) data=PPC970_EI_RATIO_001;
else if (data==0x0000000000000002) data=PPC970_EI_RATIO_010;
else if (data==0x0000000000000003) data=PPC970_EI_RATIO_011;
else if (data==0x0000000000000004) data=PPC970_EI_RATIO_100;
else if (data==0x0000000000000005) data=PPC970_EI_RATIO_101;
else if (data==0x0000000000000006) data=PPC970_EI_RATIO_110;
else return(-1);
*value=data;
return(0);
}
/*----------------------------------------------------------------------------+
| Read_sp_data.
+----------------------------------------------------------------------------*/
int read_sp_data(unsigned int offset,
unsigned int count, unsigned long *data)
{
unsigned long addr_index;
unsigned long addr_data;
unsigned long addr;
unsigned int new_data;
unsigned int i;
/*-------------------------------------------------------------------------+
| If this is not a JS20 or EVB platform then just return.
+-------------------------------------------------------------------------*/
if (what_platform()==PLATFORM_EVB_FINAL) {
addr_index=NB_HT_IO_BASE_CPU+ SUPER_IO_ADDR_NVRAM;
addr_data=NB_HT_IO_BASE_CPU+ SUPER_IO_ADDR_NVRAM+ 1;
*data=0x0000000000000000;
for(i=0;i<count;i++) {
(void)outbyte(addr_index, offset+ i);
new_data=inbyte(addr_data);
*data|=new_data<<((count- i- 1)* 8);
}
return(0);
} else if (what_platform()==PLATFORM_EVB_LITE) {
addr=SB_NVRAM_ADDR;
*data=0x0000000000000000;
for(i=0;i<count;i++) {
new_data=inbyte(addr+ i+ offset);
*data|=new_data<<((count- i- 1)* 8);
}
return(0);
}
return(-1);
}
/*----------------------------------------------------------------------------+
| Write_sp_data.
+----------------------------------------------------------------------------*/
int write_sp_data(unsigned int offset,
unsigned int data)
{
unsigned long addr_index;
unsigned long addr_data;
unsigned long addr;
/*-------------------------------------------------------------------------+
| If this is not a JS20 or EVB platform then just return.
+-------------------------------------------------------------------------*/
if (what_platform()==PLATFORM_EVB_FINAL) {
addr_index=NB_HT_IO_BASE_CPU+ SUPER_IO_ADDR_NVRAM;
addr_data=NB_HT_IO_BASE_CPU+ SUPER_IO_ADDR_NVRAM+ 1;
(void)outbyte(addr_index, offset);
(void)outbyte(addr_data, data);
return(0);
} else if (what_platform()==PLATFORM_EVB_LITE) {
addr=SB_NVRAM_ADDR;
(void)outbyte(addr+ offset, data);
return(0);
}
return(-1);
}
/*----------------------------------------------------------------------------+
| Read_psr.
+----------------------------------------------------------------------------*/
unsigned long read_psr()
{
unsigned long msr;
unsigned long value;
msr=ppcAndMsr((unsigned long)~MSR_EE);
(void)ppcMtspr_any(SPR_SCOMC, SCOM_ADDR_PSR_READ);
(void)ppcIsync();
value=ppcMfspr_any(SPR_SCOMD);
(void)ppcIsync();
(void)ppcMtmsr(msr);
return(value);
}
/*----------------------------------------------------------------------------+
| Write_pcr_pcrh.
+----------------------------------------------------------------------------*/
void write_pcr_pcrh(unsigned long data)
{
unsigned long msr;
msr=ppcAndMsr((unsigned long)~MSR_EE);
/*-------------------------------------------------------------------------+
| First write to PCR with all 0 (errata).
+-------------------------------------------------------------------------*/
(void)ppcMtspr_any(SPR_SCOMD, SCOM_ADDR_PCR_DATA_MASK);
(void)ppcIsync();
(void)ppcMtspr_any(SPR_SCOMC, SCOM_ADDR_PCR_WRITE);
(void)ppcIsync();
/*-------------------------------------------------------------------------+
| Write to PCRH.
+-------------------------------------------------------------------------*/
(void)ppcMtspr_any(SPR_SCOMD, 0x0000000000000000UL);
(void)ppcIsync();
(void)ppcMtspr_any(SPR_SCOMC, SCOM_ADDR_PCR_WRITE);
(void)ppcIsync();
/*-------------------------------------------------------------------------+
| Write to PCR.
+-------------------------------------------------------------------------*/
(void)ppcMtspr_any(SPR_SCOMD, data|SCOM_ADDR_PCR_DATA_MASK);
(void)ppcIsync();
(void)ppcMtspr_any(SPR_SCOMC, SCOM_ADDR_PCR_WRITE);
(void)ppcIsync();
(void)ppcMtmsr(msr);
return;
}
/*----------------------------------------------------------------------------+
| Is_writable.
+----------------------------------------------------------------------------*/
int is_writable(unsigned long addr,
unsigned long len)
{
if ((addr>=BOOT_BASE) && (addr<SDRAM_UPPER_BASE)) {
return(0);
}
if ((addr+ len)>=BOOT_BASE) {
return(0);
}
return(1);
}

View File

@ -0,0 +1,154 @@
#ifndef _boardutil_h_
#define _boardutil_h_
/*----------------------------------------------------------------------------+
| Board specific defines.
+----------------------------------------------------------------------------*/
#define FLASH_INTEL_SECTORSIZE 0x00020000
#define FLASH_AMD_SECTORSIZE 0x00010000
#define PIBS2_MAX_SIZE 0x000E0000
#define PIBS_DATABASE_SIZE 0x00020000
#define PIBS_DATABASE_ADDR 0x00000000FFFE0000UL
#define PIBS_DATA_FIELDSIZE 256
#define ETHERNET_HW_ADDR_LEN 6
/*----------------------------------------------------------------------------+
| Current board settings.
+----------------------------------------------------------------------------*/
typedef struct board_cfg_data {
char usr_config_ver[4];
unsigned char reserved[28];
unsigned long tmr_freq;
unsigned long mem_size;
unsigned long ei_ratio;
unsigned long sys_freq;
unsigned long cpu_freq;
unsigned long freq_ratio;
unsigned long ser_freq;
unsigned long procver;
unsigned long hid0;
unsigned long hid1;
unsigned long hid4;
unsigned long hid5;
unsigned long hior;
unsigned long sdr1;
char procstr[16];
unsigned char hwaddr0[ETHERNET_HW_ADDR_LEN];
unsigned char pad_size[2];
} board_cfg_data_t;
/*----------------------------------------------------------------------------+
| PIBS data CPU2.
+----------------------------------------------------------------------------*/
typedef struct cpu_data {
unsigned long img_srr0;
unsigned long img_srr1;
unsigned long r3_value;
unsigned long img_valid;
} cpu_data_t;
/*----------------------------------------------------------------------------+
| PIBS data.
+----------------------------------------------------------------------------*/
typedef struct bios_data_struct {
/*-------------------------------------------------------------------------+
| Is this data section valid? [TRUE|FALSE] string.
+-------------------------------------------------------------------------*/
char bios_data_valid[PIBS_DATA_FIELDSIZE];
/*-------------------------------------------------------------------------+
| Information about the main PIBS board image [TRUE|FALSE] string.
+-------------------------------------------------------------------------*/
char pibs2_valid[PIBS_DATA_FIELDSIZE];
/*-------------------------------------------------------------------------+
| Autoboot configuration.
+-------------------------------------------------------------------------*/
char autoboot_parm[PIBS_DATA_FIELDSIZE];
/*-------------------------------------------------------------------------+
| Configuration.
+-------------------------------------------------------------------------*/
char bios_eth_hwd0[PIBS_DATA_FIELDSIZE];
char ifconfig_parm0[PIBS_DATA_FIELDSIZE];
char route_parm[PIBS_DATA_FIELDSIZE];
/*-------------------------------------------------------------------------+
| TFTP information.
+-------------------------------------------------------------------------*/
char bios_tftp_fname[PIBS_DATA_FIELDSIZE];
char bios_tftp_destip[PIBS_DATA_FIELDSIZE];
/*-------------------------------------------------------------------------+
| Chip and board clocking information.
+-------------------------------------------------------------------------*/
char clocking_valid[PIBS_DATA_FIELDSIZE];
char clocking_parm[PIBS_DATA_FIELDSIZE];
/*-------------------------------------------------------------------------+
| User data, alias list, autoboot delay, dhcp flag.
+-------------------------------------------------------------------------*/
char user_data[PIBS_DATA_FIELDSIZE];
char aliaslist[PIBS_DATA_FIELDSIZE];
char autoboot_delay[PIBS_DATA_FIELDSIZE];
char dhcp0[PIBS_DATA_FIELDSIZE];
/*-------------------------------------------------------------------------+
| HT link optimization variable.
+-------------------------------------------------------------------------*/
char opthtlink[PIBS_DATA_FIELDSIZE];
/*-------------------------------------------------------------------------+
| Indicates IDE cable type.
+-------------------------------------------------------------------------*/
char ide80wire[PIBS_DATA_FIELDSIZE];
/*-------------------------------------------------------------------------+
| Automatically initialize IDE.
+-------------------------------------------------------------------------*/
char initide[PIBS_DATA_FIELDSIZE];
/*-------------------------------------------------------------------------+
| OpenFirmware interface private variable
+-------------------------------------------------------------------------*/
char openfirmware[PIBS_DATA_FIELDSIZE];
} bios_data_struct_t;
/*----------------------------------------------------------------------------+
| Function prototypes.
+----------------------------------------------------------------------------*/
void get_system_info(
board_cfg_data_t *board_cfg );
int get_hwd_addr(
char *dest,
int ethernet_num );
int get_sys_clk(
unsigned long *value );
int get_pll_mult(
unsigned long *value );
int get_ei_ratio(
unsigned long *value );
int read_sp_data(
unsigned int offset,
unsigned int count,
unsigned long *data );
int write_sp_data(
unsigned int offset,
unsigned int data );
unsigned long read_psr(
void );
void write_pcr_pcrh(
unsigned long data );
int is_writable(
unsigned long addr,
unsigned long len );
void super_io_setup(
void );
unsigned long sdram_size(
void );
#endif /* _boardutil_h_ */

View File

@ -0,0 +1,133 @@
/*
* Copyright (C) 2003, Greg Watson <gwatson@lanl.gov>
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
/*
* Do very early board initialization:
*
* - Setup SIO
*/
#include "ppc970.h"
#include "boardutil.h"
/*----------------------------------------------------------------------------+
| Local defines.
+----------------------------------------------------------------------------*/
#define BASE_MASK 0xFFFFFFFF
void
board_init(void)
{
super_io_setup();
}
/*----------------------------------------------------------------------------+
| Super_io_setup.
+----------------------------------------------------------------------------*/
void super_io_setup()
{
unsigned long io_base;
unsigned long sio_index;
unsigned long sio_data;
int platform;
unsigned int i;
/*-------------------------------------------------------------------------+
| If this is not a JS20 or EVB platform then just return.
+-------------------------------------------------------------------------*/
platform=what_platform();
if (platform==PLATFORM_EVB_FINAL) {
/*----------------------------------------------------------------------+
| Assign addresses.
+----------------------------------------------------------------------*/
io_base=(unsigned long)(NB_HT_IO_BASE_BYTE<<NB_HT_IO_BASE_BYTE_SH);
io_base&=BASE_MASK;
sio_index=io_base+ SUPER_IO_INDEX_OFF;
sio_data=io_base+ SUPER_IO_DATA_OFF;
/*----------------------------------------------------------------------+
| Serial 1 setup/enable.
+----------------------------------------------------------------------*/
(void)outbyte(sio_index, SUPER_IO_DEVICE_SEL);
(void)outbyte(sio_data, SUPER_IO_DEVICE_S1);
(void)outbyte(sio_index, SUPER_IO_BASE_DEV_MSB);
(void)outbyte(sio_data, (unsigned int)((UART0_MMIO_BASE>>8)&0xFF));
(void)outbyte(sio_index, SUPER_IO_BASE_DEV_LSB);
(void)outbyte(sio_data, (unsigned int)((UART0_MMIO_BASE>>0)&0xFF));
(void)outbyte(sio_index, SUPER_IO_DEVICE_CTRL);
(void)outbyte(sio_data, SUPER_IO_DEVICE_ENABLE);
/*----------------------------------------------------------------------+
| Serial 2 setup/enable.
+----------------------------------------------------------------------*/
(void)outbyte(sio_index, SUPER_IO_DEVICE_SEL);
(void)outbyte(sio_data, SUPER_IO_DEVICE_S2);
(void)outbyte(sio_index, SUPER_IO_BASE_DEV_MSB);
(void)outbyte(sio_data, (unsigned int)((UART1_MMIO_BASE>>8)&0xFF));
(void)outbyte(sio_index, SUPER_IO_BASE_DEV_LSB);
(void)outbyte(sio_data, (unsigned int)((UART1_MMIO_BASE>>0)&0xFF));
(void)outbyte(sio_index, SUPER_IO_DEVICE_CTRL);
(void)outbyte(sio_data, SUPER_IO_DEVICE_ENABLE);
/*----------------------------------------------------------------------+
| X-bus setup/enable.
+----------------------------------------------------------------------*/
(void)outbyte(sio_index, SUPER_IO_DEVICE_SEL);
(void)outbyte(sio_data, SUPER_IO_DEVICE_XBUS);
(void)outbyte(sio_index, SUPER_IO_BASE_DEV_MSB);
(void)outbyte(sio_data, (SUPER_IO_ADDR_XBUS>>8)&0xFF);
(void)outbyte(sio_index, SUPER_IO_BASE_DEV_LSB);
(void)outbyte(sio_data, (SUPER_IO_ADDR_XBUS>>0)&0xFF);
(void)outbyte(sio_index, SUPER_IO_XBUS_CONFIG);
(void)outbyte(sio_data, SUPER_IO_BIOS_SIZE_1M);
(void)outbyte(sio_index, SUPER_IO_DEVICE_CTRL);
(void)outbyte(sio_data, SUPER_IO_DEVICE_ENABLE);
for(i=0;i<16;i++) {
(void)outbyte(io_base+ SUPER_IO_XBUS_HOST_ACCESS, i);
}
/*----------------------------------------------------------------------+
| RTC setup/enable.
+----------------------------------------------------------------------*/
(void)outbyte(sio_index, SUPER_IO_DEVICE_SEL);
(void)outbyte(sio_data, SUPER_IO_DEVICE_RTC);
(void)outbyte(sio_index, SUPER_IO_BASE_DEV_MSB);
(void)outbyte(sio_data, (SUPER_IO_ADDR_RTC>>8)&0xFF);
(void)outbyte(sio_index, SUPER_IO_BASE_DEV_LSB);
(void)outbyte(sio_data, (SUPER_IO_ADDR_RTC>>0)&0xFF);
(void)outbyte(sio_index, SUPER_IO_EXT_DEV_MSB);
(void)outbyte(sio_data, (SUPER_IO_ADDR_NVRAM>>8)&0xFF);
(void)outbyte(sio_index, SUPER_IO_EXT_DEV_LSB);
(void)outbyte(sio_data, (SUPER_IO_ADDR_NVRAM>>0)&0xFF);
(void)outbyte(sio_index, SUPER_IO_RTC_DATE_ALARM_OFF);
(void)outbyte(sio_data, SUPER_IO_RTC_DATE_ALARM_LOC);
(void)outbyte(sio_index, SUPER_IO_RTC_MONTH_ALARM_OFF);
(void)outbyte(sio_data, SUPER_IO_RTC_MONTH_ALARM_LOC);
(void)outbyte(sio_index, SUPER_IO_RTC_CENTURY_ALARM_OFF);
(void)outbyte(sio_data, SUPER_IO_RTC_CENTURY_ALARM_LOC);
(void)outbyte(sio_index, SUPER_IO_DEVICE_CTRL);
(void)outbyte(sio_data, SUPER_IO_DEVICE_ENABLE);
}
return;
}
void
board_init2(void)
{
}

View File

@ -0,0 +1,12 @@
#include <console/console.h>
#include <device/device.h>
#include <device/pci.h>
#include <device/pci_ids.h>
#include <device/pci_ops.h>
#include "chip.h"
#if CONFIG_CHIP_NAME == 1
struct chip_operations mainboard_tyan_s2735_ops = {
CHIP_NAME("Momentum Apache mainboard")
};
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,378 @@
#include <ppc970.h>
/*----------------------------------------------------------------------------+
| Cycle counts ((1/ 9600)* 10) / (1/speed)) - 2%.
+----------------------------------------------------------------------------*/
#define SPEED_6_25 (0x0000196E- (65* 2))
#define SPEED_7_159 (0x00001D21- (74* 2))
#define SPEED_8_33 (0x000021E5- (86* 2))
#define SPEED_10_4 (0x00002A51- (108* 2))
#define SPEED_14_318 (0x00003A42- (149* 2))
#define SPEED_16_66 (0x000043D0- (173* 2))
#define SPEED_25 (0x000065B9- (260* 2))
#define SPEED_33 (0x000087A2- (347* 2))
#define SPEED_40 (0x0000A2C2- (416* 2))
#define SPEED_50 (0x0000CB73- (520* 2))
#define SPEED_66 (0x00010C8E- (687* 2))
#define SPEED_80 (0x00014585- (833* 2))
#define SPEED_100 (0x000196E6- (1041* 2))
#define SPEED_125 (0x0001FCA0- (1302* 2))
#define SPEED_133 (0x00021D2D- (1385* 2))
#define SPEED_150 (0x0002625A- (1562* 2))
#define SPEED_166 (0x0002A374- (1729* 2))
#define SPEED_175 (0x0002C813- (1822* 2))
#define SPEED_200 (0x00032DCD- (2093* 2))
#define SPEED_225 (0x00039387- (2343* 2))
#define SPEED_250 (0x0003F940- (2604* 2))
#define SPEED_275 (0x00045EFA- (2864* 2))
#define SPEED_300 (0x0004C4B4- (3125* 2))
#define SPEED_3375 (0x00055D4A- (3515* 2))
#define SPEED_375 (0x0005F5E1- (3906* 2))
#define SPEED_400 (0x00065B9A- (4166* 2))
#define SPEED_433 (0x0006E1E1- (4510* 2))
#define SPEED_466 (0x00076828- (4854* 2))
#define SPEED_500 (0x0007F281- (5208* 2))
/*----------------------------------------------------------------------------+
| Timebase_speed_calc
+----------------------------------------------------------------------------*/
function_prolog(timebase_speed_calc)
mfmsr r10
rlwinm r11,r10,0,17,15
mtmsrd r11,1
isync
/*--------------------------------------------------------------------+
| Make sure that all the characters in the transmit buffer are sent.
+--------------------------------------------------------------------*/
..sent: lbz r6,asyncLSR(r3)
andi. r6,r6,0x0060
cmpi cr0,1,r6,0x0060
bne ..sent
/*--------------------------------------------------------------------+
| Store current serial port settings in r11, r12.
| r11 BH (baud high), BL (baud low), LCR
| r12 MCR, IER, FCR
+--------------------------------------------------------------------*/
lbz r4,asyncLCR(r3)
ori r11,r4,0x0000
lbz r4,asyncFCR(r3)
ori r12,r4,0x0000
lbz r4,asyncIER(r3)
rlwimi r12,r4,8,16,23
lbz r4,asyncMCR(r3)
rlwimi r12,r4,16,8,15
/*--------------------------------------------------------------------+
| Store BH and BL and program new baud rate.
+--------------------------------------------------------------------*/
addi r4,r0,0x80
stb r4,asyncLCR(r3)
lbz r4,asyncDLABMsb(r3)
rlwimi r11,r4,16,8,15
addi r4,r0,DIV_HIGH_9600
stb r4,asyncDLABMsb(r3)
lbz r4,asyncDLABLsb(r3)
rlwimi r11,r4,8,16,23
addi r4,r0,DIV_LOW_9600
stb r4,asyncDLABLsb(r3)
addi r4,r0,0x03
stb r4,asyncLCR(r3)
/*--------------------------------------------------------------------+
| Put the serial port in loop-back mode.
+--------------------------------------------------------------------*/
addi r4,r0,0x00
stb r4,asyncFCR(r3)
stb r4,asyncIER(r3)
addi r4,r0,0x10
stb r4,asyncMCR(r3)
lbz r4,asyncRxBuffer(r3)
addi r4,r0,0x0041
/*--------------------------------------------------------------------+
| Again make sure there are no characters in transmit buffer.
+--------------------------------------------------------------------*/
addi r5,r0,0
..again:lbz r6,asyncLSR(r3)
andi. r6,r6,0x0060
cmpi cr0,1,r6,0x0060
bne ..again
/*--------------------------------------------------------------------+
| Take a snapshot of the timebase.
+--------------------------------------------------------------------*/
mfspr r7,tblr
/*--------------------------------------------------------------------+
| Send a character while in loopback mode. This will be done twice.
| Once to get the instuctions into I-cache, the second time for the
| real measurement.
+--------------------------------------------------------------------*/
stb r4,asyncTxBuffer(r3)
..spnlp:lbz r6,asyncLSR(r3)
andi. r6,r6,0x01
beq ..spnlp
mfspr r9,tblr
/*--------------------------------------------------------------------+
| Perform subtraction to determine how many timebase ticks it took
| to transmit the character.
+--------------------------------------------------------------------*/
subfc r9,r7,r9
/*--------------------------------------------------------------------+
| Consume the character sent in loopback mode.
+--------------------------------------------------------------------*/
lbz r4,asyncRxBuffer(r3)
eieio
/*--------------------------------------------------------------------+
| If the first character was just sent, go back and send a second.
+--------------------------------------------------------------------*/
cmpi cr0,1,r5,0x0000
addi r5,r5,1
beq ..again
/*--------------------------------------------------------------------+
| Restore serial port settings.
+--------------------------------------------------------------------*/
addi r4,r0,0x80
stb r4,asyncLCR(r3)
rlwinm r4,r11,16,24,31
stb r4,asyncDLABMsb(r3)
rlwinm r4,r11,24,24,31
stb r4,asyncDLABLsb(r3)
rlwinm r4,r11,0,24,31
stb r4,asyncLCR(r3)
rlwinm r4,r12,16,24,31
stb r4,asyncMCR(r3)
rlwinm r4,r12,24,24,31
stb r4,asyncIER(r3)
rlwinm r4,r12,0,24,31
stb r4,asyncFCR(r3)
/*--------------------------------------------------------------------+
| Calculate timebase speed (r9 is the time we are referencing).
+--------------------------------------------------------------------*/
addis r4,r0,SPEED_7_159@h
ori r4,r4,SPEED_7_159@l
cmp cr0,r9,r4
blt ..freq6
addis r4,r0,SPEED_8_33@h
ori r4,r4,SPEED_8_33@l
cmp cr0,r9,r4
blt ..freq7
addis r4,r0,SPEED_10_4@h
ori r4,r4,SPEED_10_4@l
cmp cr0,r9,r4
blt ..freq8
addis r4,r0,SPEED_14_318@h
ori r4,r4,SPEED_14_318@l
cmp cr0,r9,r4
blt ..freq10
addis r4,r0,SPEED_16_66@h
ori r4,r4,SPEED_16_66@l
cmp cr0,r9,r4
blt ..freq14
addis r4,r0,SPEED_25@h
ori r4,r4,SPEED_25@l
cmp cr0,r9,r4
blt ..freq16
addis r4,r0,SPEED_33@h
ori r4,r4,SPEED_33@l
cmp cr0,r9,r4
blt ..freq25
addis r4,r0,SPEED_40@h
ori r4,r4,SPEED_40@l
cmp cr0,r9,r4
blt ..freq33
addis r4,r0,SPEED_50@h
ori r4,r4,SPEED_50@l
cmp cr0,r9,r4
blt ..freq40
addis r4,r0,SPEED_66@h
ori r4,r4,SPEED_66@l
cmp cr0,r9,r4
blt ..freq50
addis r4,r0,SPEED_80@h
ori r4,r4,SPEED_80@l
cmp cr0,r9,r4
blt ..freq66
addis r4,r0,SPEED_100@h
ori r4,r4,SPEED_100@l
cmp cr0,r9,r4
blt ..freq80
addis r4,r0,SPEED_125@h
ori r4,r4,SPEED_125@l
cmp cr0,r9,r4
blt ..freq100
addis r4,r0,SPEED_133@h
ori r4,r4,SPEED_133@l
cmp cr0,r9,r4
blt ..freq125
addis r4,r0,SPEED_150@h
ori r4,r4,SPEED_150@l
cmp cr0,r9,r4
blt ..freq133
addis r4,r0,SPEED_166@h
ori r4,r4,SPEED_166@l
cmp cr0,r9,r4
blt ..freq150
addis r4,r0,SPEED_175@h
ori r4,r4,SPEED_175@l
cmp cr0,r9,r4
blt ..freq166
addis r4,r0,SPEED_200@h
ori r4,r4,SPEED_200@l
cmp cr0,r9,r4
blt ..freq175
addis r4,r0,SPEED_225@h
ori r4,r4,SPEED_225@l
cmp cr0,r9,r4
blt ..freq200
addis r4,r0,SPEED_250@h
ori r4,r4,SPEED_250@l
cmp cr0,r9,r4
blt ..freq225
addis r4,r0,SPEED_275@h
ori r4,r4,SPEED_275@l
cmp cr0,r9,r4
blt ..freq250
addis r4,r0,SPEED_300@h
ori r4,r4,SPEED_300@l
cmp cr0,r9,r4
blt ..freq275
addis r4,r0,SPEED_3375@h
ori r4,r4,SPEED_3375@l
cmp cr0,r9,r4
blt ..freq300
addis r4,r0,SPEED_375@h
ori r4,r4,SPEED_375@l
cmp cr0,r9,r4
blt ..freq3375
addis r4,r0,SPEED_400@h
ori r4,r4,SPEED_400@l
cmp cr0,r9,r4
blt ..freq375
addis r4,r0,SPEED_433@h
ori r4,r4,SPEED_433@l
cmp cr0,r9,r4
blt ..freq400
addis r4,r0,SPEED_466@h
ori r4,r4,SPEED_466@l
cmp cr0,r9,r4
blt ..freq433
addis r4,r0,SPEED_500@h
ori r4,r4,SPEED_500@l
cmp cr0,r9,r4
blt ..freq466
b ..freq500
..freq6:
addis r3,r0,0x005F
ori r3,r3,0x5e10
b ..end
..freq7:
addis r3,r0,0x006D
ori r3,r3,0x3CD8
b ..end
..freq8:
addis r3,r0,0x007F
ori r3,r3,0x2815
b ..end
..freq10:
addis r3,r0,0x009e
ori r3,r3,0xb100
b ..end
..freq14:
addis r3,r0,0x00da
ori r3,r3,0x79b0
b ..end
..freq16:
addis r3,r0,0x00fe
ori r3,r3,0x502A
b ..end
..freq25:
addis r3,r0,0x017D
ori r3,r3,0x7840
b ..end
..freq33:
addis r3,r0,0x01FC
ori r3,r3,0xA055
b ..end
..freq40:
addis r3,r0,0x0262
ori r3,r3,0x5A00
b ..end
..freq50:
addis r3,r0,0x02FA
ori r3,r3,0xF080
b ..end
..freq66:
addis r3,r0,0x03F9
ori r3,r3,0x40AA
b ..end
..freq80:
addis r3,r0,0x04C4
ori r3,r3,0xB400
b ..end
..freq100:
addis r3,r0,0x05F5
ori r3,r3,0xE100
b ..end
..freq125:
addis r3,r0,0x0773
ori r3,r3,0x5940
b ..end
..freq133:
addis r3,r0,0x07F2
ori r3,r3,0x8155
b ..end
..freq150:
addis r3,r0,0x08F0
ori r3,r3,0xD180
b ..end
..freq166:
addis r3,r0,0x09EF
ori r3,r3,0x21AA
b ..end
..freq175:
addis r3,r0,0x0A6E
ori r3,r3,0x49C0
b ..end
..freq200:
addis r3,r0,0x0BEB
ori r3,r3,0xC200
b ..end
..freq225:
addis r3,r0,0x0D69
ori r3,r3,0x3A40
b ..end
..freq250:
addis r3,r0,0x0EE6
ori r3,r3,0xB280
b ..end
..freq275:
addis r3,r0,0x1064
ori r3,r3,0x2AC0
b ..end
..freq300:
addis r3,r0,0x11E1
ori r3,r3,0xA300
b ..end
..freq3375:
addis r3,r0,0x141D
ori r3,r3,0xD760
b ..end
..freq375:
addis r3,r0,0x165A
ori r3,r3,0x0BC0
b ..end
..freq400:
addis r3,r0,0x17D7
ori r3,r3,0x8400
b ..end
..freq433:
addis r3,r0,0x19CF
ori r3,r3,0x0E40
b ..end
..freq466:
addis r3,r0,0x1BC6
ori r3,r3,0x9880
b ..end
..freq500:
addis r3,r0,0x1DCD
ori r3,r3,0x6500
..end: mtmsrd r10,1
isync
blr
function_epilog(timebase_speed_calc)

View File

@ -6,7 +6,9 @@ config chip.h
initobject cpc925.o
initobject cpc925_pci.o
initobject cpc925_sdram.o
object cpc925.o
object cpc925_pci.o
object cpc925_sdram.o
driver cpc925_northbridge.o

View File

@ -0,0 +1,13 @@
#include "ppc970.h"
unsigned long sdram_size(void)
{
unsigned long addr1, addr2;
addr1=inint(NB_SDRAM_BASE+NB_SDRAM_MEMMODE7)&SDRAM_MEMMODE_BASEBANKADDR;
addr1=addr1<<11;
addr2=inint(NB_SDRAM_BASE+NB_SDRAM_MEMBOUNDAD7)&SDRAM_MEMBOUNDAD_BASEBANKADDR;
addr2=addr2<<3;
return(addr1|addr2);
}