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 $< $@" action "cp $< $@"
end 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 init
dir lib dir lib
dir boot 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: | Memory layout. RAM length is referenced again in __heap_size variable
* | definition.
* _ROMBASE : start of ROM +----------------------------------------------------------------------------*/
* _RESET : reset vector (may be at top of ROM) MEMORY
* _EXCEPTIONS_VECTORS : exception table {
* RAM_VECT (rwx) : ORIGIN = 0x00000000, LENGTH = 0x00010000
* _ROMSTART : linuxbios text RAM (rwx) : ORIGIN = 0x00010000, LENGTH = 0x003F0000
* : payload text ROM_INIT (r x) : ORIGIN = 0xFFF00000, LENGTH = 0x00002000
* ROM (r x) : ORIGIN = 0xFFF02000, LENGTH = 0x000FE000
* _RAMBASE : address to copy payload }
*/
/* /*----------------------------------------------------------------------------+
* Written by Johan Rydberg, based on work by Daniel Kahlin. | Sections originally taken from default GNU LD script.
* 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 SECTIONS
{ {
/*
* Absolute location of base of ROM
*/
. = _ROMBASE;
/* /*-------------------------------------------------------------------------+
* Absolute location of reset vector. This may actually be at the | Create dummy section. We need to do this so that the __stext symbol is
* the top of ROM. | set correctly.
*/ +-------------------------------------------------------------------------*/
. = _RESET; .dummyt :
.reset . : { {
*(.rom.reset); LONG(0x00000000)
. = ALIGN(16); } > RAM
}
/* /*-------------------------------------------------------------------------+
* Absolute location of exception vector table. | Create variable holding the value of the start of the text.
*/ +-------------------------------------------------------------------------*/
. = _EXCEPTION_VECTORS; __stext = . - SIZEOF(.dummyt);
.exception_vectors . : {
*(.rom.exception_vectors);
. = ALIGN(16);
}
/* .hash :
* Absolute location of LinuxBIOS initialization code in ROM. {
*/ *(.hash)
. = _ROMSTART; } > RAM
.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 = . ;
}
/* .dynsym :
* Absolute location of where LinuxBIOS will be relocated in RAM. {
*/ *(.dynsym)
_iseg = _RAMBASE; } > RAM
_eiseg = _iseg + SIZEOF(.ram);
_liseg = _ram; .dynstr :
_eliseg = _eram; {
*(.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 <board.h>
#include <sdram.h> #include <sdram.h>
#ifndef __PPC64__
extern unsigned _iseg[]; extern unsigned _iseg[];
extern unsigned _liseg[]; extern unsigned _liseg[];
extern unsigned _eliseg[]; extern unsigned _eliseg[];
void (*payload)(void) = (void (*)(void))_iseg; void (*payload)(void) = (void (*)(void))_iseg;
#endif
/* /*
* At this point we're running out of flash with our * 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 * - start hardwaremain() which does remainder of setup
*/ */
#ifndef __PPC64__
extern void flush_dcache(void); extern void flush_dcache(void);
#endif
void ppc_main(void) void ppc_main(void)
{ {
@ -43,6 +47,7 @@ void ppc_main(void)
*/ */
board_init2(); board_init2();
#ifndef __PPC64__
/* /*
* Flush cache now that memory is enabled. * Flush cache now that memory is enabled.
*/ */
@ -59,6 +64,7 @@ void ppc_main(void)
} }
payload(); payload();
#endif
/* NOT REACHED */ /* NOT REACHED */
} }

View File

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

View File

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

View File

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

View File

@ -11,5 +11,12 @@ uses USE_DCACHE_RAM
## ##
default USE_DCACHE_RAM=0 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*/
/*----------------------------------------------------------------------------+ #include <ppc970.h>
| COPYRIGHT I B M CORPORATION 2002, 2004
| LICENSED MATERIAL - PROGRAM PROPERTY OF I B M /******** init_core.s ***************/
| US Government Users Restricted Rights - Use, duplication or /*----------------------------------------------------------------------------+
| disclosure restricted by GSA ADP Schedule Contract with | Local defines.
| IBM Corp. +----------------------------------------------------------------------------*/
+----------------------------------------------------------------------------*/ #define INITIAL_SLB_VSID_VAL 0x0000000000000C00
/*----------------------------------------------------------------------------+ #define INITIAL_SLB_ESID_VAL 0x0000000008000000
| PPC970FX BSP for EPOS #define INITIAL_SLB_INVA_VAL 0x0000000000000000
| Author: Maciej P. Tyrlik
| Component: Boot library. /*----------------------------------------------------------------------------+
| File: init_core.s | Init_core. Assumption: hypervisor on, 64-bit on, HID1[10]=0, HID4[23]=0.
| Purpose: Basic PPC405 core initialization. | Data cahability must be turned on. Instruction cahability must be off.
| Changes: +----------------------------------------------------------------------------*/
| Date: Comment: function_prolog(init_core)
| ----- -------- /*--------------------------------------------------------------------+
| 29-Jan-02 Created MPT | Set time base to 0.
| 30-Jan-02 Completed MPT +--------------------------------------------------------------------*/
| 19-Apr-02 Changed some instructions to macros so that new GCC AS worksMPT addi r4,r0,0x0000
| 23-Apr-02 Removed critical interrupt enabling after rfi MPT mtspr SPR_TBU_WRITE,r4
| 31-Jul-02 Fixed data cache invalidate code MPT mtspr SPR_TBL_WRITE,r4
| 01-Feb-03 Ported to Argan 7XXFX CRB /*--------------------------------------------------------------------+
| 07-Aug-03 Ported to PPC7XXGX CRB | Set HID1[10] to 0 (instruction cache off) and set HID4[23] to 0 (data
| 12-Sep-03 Removed PVR definitions, now in board include file MCG | cache on), set HID4[DC_SET1] and HID4[DC_SET2] to 0.
| 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 LOAD_64BIT_VAL(r4,HID1_EN_IC)
| 07-Jan-04 Initialize FPRs to avoid errata. MCG nor r4,r4,r4
| 10-Feb-04 Port to PPC970FX MPT mfspr r5,SPR_HID1
+----------------------------------------------------------------------------*/ isync
and r5,r5,r4
#include <ppc970.h> mtspr SPR_HID1,r5
mtspr SPR_HID1,r5
/*----------------------------------------------------------------------------+ isync
| Local defines. LOAD_64BIT_VAL(r4,HID4_RM_CI|HID4_DC_SET1|HID4_DC_SET2)
+----------------------------------------------------------------------------*/ nor r4,r4,r4
#define INITIAL_SLB_VSID_VAL 0x0000000000000C00 mfspr r5,SPR_HID4
#define INITIAL_SLB_ESID_VAL 0x0000000008000000 LOAD_64BIT_VAL(r6,HID4_L1DC_FLSH)
#define INITIAL_SLB_INVA_VAL 0x0000000000000000 isync
and r5,r5,r4
/*----------------------------------------------------------------------------+ or r5,r5,r6
| Init_core. Assumption: hypervisor on, 64-bit on, HID1[10]=0, HID4[23]=0. sync
| Data cahability must be turned on. Instruction cahability must be off. mtspr SPR_HID4,r5
+----------------------------------------------------------------------------*/ isync
/*--------------------------------------------------------------------+ /*--------------------------------------------------------------------+
| Set time base to 0. | Clear the flash invalidate L1 data cache bit in HID4.
+--------------------------------------------------------------------*/ +--------------------------------------------------------------------*/
addi r4,r0,0x0000 nor r6,r6,r6
mtspr SPR_TBU_WRITE,r4 and r5,r5,r6
mtspr SPR_TBL_WRITE,r4 sync
/*--------------------------------------------------------------------+ mtspr SPR_HID4,r5
| Set HID1[10] to 0 (instruction cache off) and set HID4[23] to 0 (data isync
| cache on), set HID4[DC_SET1] and HID4[DC_SET2] to 0. /*--------------------------------------------------------------------+
+--------------------------------------------------------------------*/ | Clear and set up some registers.
LOAD_64BIT_VAL(r4,HID1_EN_IC) +--------------------------------------------------------------------*/
nor r4,r4,r4 addi r4,r0,0x0000
mfspr r5,SPR_HID1 mtxer r4
isync /*--------------------------------------------------------------------+
and r5,r5,r4 | Invalidate SLB. First load SLB with known values then perform
mtspr SPR_HID1,r5 | invalidate. Invalidate will clear the D-ERAT and I-ERAT. The SLB
mtspr SPR_HID1,r5 | is 64 entry fully associative. On power on D-ERAT and I-ERAT are all
isync | set to invalid values.
LOAD_64BIT_VAL(r4,HID4_RM_CI|HID4_DC_SET1|HID4_DC_SET2) +--------------------------------------------------------------------*/
nor r4,r4,r4 addi r5,r0,SLB_SIZE
mfspr r5,SPR_HID4 mtctr r5
LOAD_64BIT_VAL(r6,HID4_L1DC_FLSH) LOAD_64BIT_VAL(r6,INITIAL_SLB_VSID_VAL)
isync LOAD_64BIT_VAL(r7,INITIAL_SLB_ESID_VAL)
and r5,r5,r4 addis r8,r0,0x1000
or r5,r5,r6 ..slbl: slbmte r6,r7
sync addi r6,r6,0x1000
mtspr SPR_HID4,r5 add r7,r7,r8
isync addi r7,r7,0x0001
/*--------------------------------------------------------------------+ bdnz ..slbl
| Clear the flash invalidate L1 data cache bit in HID4. mtctr r5
+--------------------------------------------------------------------*/ LOAD_64BIT_VAL(r6,INITIAL_SLB_INVA_VAL)
nor r6,r6,r6 ..slbi: slbie r6
and r5,r5,r6 add r6,r6,r8
sync bdnz ..slbi
mtspr SPR_HID4,r5 /*--------------------------------------------------------------------+
isync | Load SLB. Following is the initial memory map.
/*--------------------------------------------------------------------+ | Entry(6) ESID(36) VSID
| Clear and set up some registers. | 0x0 0x000000000 0x0000000000000 (large page cachable)
+--------------------------------------------------------------------*/ | 0x1 0x00000000F 0x000000000000F (small non-cachable, G)
addi r4,r0,0x0000 | at 0x00000000 there will be 32MB mapped (SDRAM)
mtxer r4 | at 0xF8000000 there will be 16MB mapped (NB)
/*--------------------------------------------------------------------+ | at 0xF4000000 there will be 64KB mapped (I/O space)
| Invalidate SLB. First load SLB with known values then perform | at 0xFF000000 there will be 16MB or 1MB mapped (FLASH)
| 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 addi r6,r0,0x0100
| set to invalid values. addis r7,r0,0x0800
+--------------------------------------------------------------------*/ slbmte r6,r7
addi r5,r0,SLB_SIZE addi r6,r0,0x0000
mtctr r5 ori r6,r6,0xF000
LOAD_64BIT_VAL(r6,INITIAL_SLB_VSID_VAL) addi r7,r0,0x0001
LOAD_64BIT_VAL(r7,INITIAL_SLB_ESID_VAL) oris r7,r7,0xF800
addis r8,r0,0x1000 slbmte r6,r7
0: slbmte r6,r7 /*--------------------------------------------------------------------+
addi r6,r6,0x1000 | Invalidate all 1024 instruction and data TLBs (4 way)
add r7,r7,r8 +--------------------------------------------------------------------*/
addi r7,r7,0x0001 addi r8,r0,0x0100
bdnz 0b mtspr ctr,r8
mtctr r5 addi r8,r0,0x0000
LOAD_64BIT_VAL(r6,INITIAL_SLB_INVA_VAL) ..ivt: TLBIEL(r8)
1: slbie r6 addi r8,r8,0x1000
add r6,r6,r8 bdnz ..ivt
bdnz 1b ptesync
/*--------------------------------------------------------------------+ /*--------------------------------------------------------------------+
| Load SLB. Following is the initial memory map. | Dcbz the page table space. Calculate SDR1 address. Store SDR1
| Entry(6) ESID(36) VSID | address in r30.
| 0x0 0x000000000 0x0000000000000 (large page cachable) +--------------------------------------------------------------------*/
| 0x1 0x00000000F 0x000000000000F (small non-cachable, G) mfspr r3,SPR_PIR
| at 0x00000000 there will be 48MB mapped (SDRAM) cmpi cr0,1,r3,0x0000
| at 0xF8000000 there will be 16MB mapped (NB) bne ..cpu1_init_core
| at 0xF4000000 there will be 64KB mapped (I/O space) addis r3,r0,INITIAL_PAGE_TABLE_ADDR_CPU0@h
| at 0xFF000000 there will be 16MB or 1MB mapped (FLASH) ori r3,r3,INITIAL_PAGE_TABLE_ADDR_CPU0@l
+--------------------------------------------------------------------*/ b ..skcpu
addi r6,r0,0x0100 ..cpu1_init_core: addis r3,r0,INITIAL_PAGE_TABLE_ADDR_CPU1@h
addis r7,r0,0x0800 ori r3,r3,INITIAL_PAGE_TABLE_ADDR_CPU1@l
slbmte r6,r7 ..skcpu:addis r4,r0,INITIAL_PAGE_TABLE_SIZE@h
addi r6,r0,0x0000 ori r4,r4,INITIAL_PAGE_TABLE_SIZE@l
ori r6,r6,0xF000 rlwinm r5,r4,14,14,31
addi r7,r0,0x0001 cntlzw r5,r5
oris r7,r7,0xF800 subfic r5,r5,31
slbmte r6,r7 or r30,r3,r5
/*--------------------------------------------------------------------+ bl .ppcDcbz_area
| Invalidate all 1024 instruction and data TLBs (4 way) /*--------------------------------------------------------------------+
+--------------------------------------------------------------------*/ | Setup 0x00000000FFFFFFFF mask in r29.
addi r8,r0,0x0100 +--------------------------------------------------------------------*/
mtspr CTR,r8 addi r29,r0,0x0001
addi r8,r0,0x0000 rldicl r29,r29,32,31
2: TLBIEL(r8) addi r29,r29,-1
addi r8,r8,0x1000 /*--------------------------------------------------------------------+
bdnz 2b | Setup 32MB of addresses in DRAM in page table (2 large PTE). The
ptesync | parameters to p_ptegg are: r3 = lp, r4 = ea, r5 = sdr1, r6 = vsid.
/*--------------------------------------------------------------------+ +--------------------------------------------------------------------*/
| Dcbz the page table space. Calculate SDR1 address. Store SDR1 addi r3,r0,0x0001
| address in r30. addi r4,r0,0x0000
+--------------------------------------------------------------------*/ ori r5,r30,0x0000
mfspr r3,SPR_PIR addi r6,r0,0x0000
cmpi cr0,1,r3,0x0000 bl .p_ptegg
bne 3f addi r4,r0,0x0001
addis r3,r0,INITIAL_PAGE_TABLE_ADDR_CPU0@h stw r4,0x0004(r3)
ori r3,r3,INITIAL_PAGE_TABLE_ADDR_CPU0@l addi r4,r0,0x0180
b 4f stw r4,0x000C(r3)
3: addis r3,r0,INITIAL_PAGE_TABLE_ADDR_CPU1@h /*--------------------------------------------------------------------+
ori r3,r3,INITIAL_PAGE_TABLE_ADDR_CPU1@l | Second 32MB is mapped here.
4: addis r4,r0,INITIAL_PAGE_TABLE_SIZE@h +--------------------------------------------------------------------*/
ori r4,r4,INITIAL_PAGE_TABLE_SIZE@l addi r3,r0,0x0001
rlwinm r5,r4,14,14,31 addis r4,r0,0x0100
cntlzw r5,r5 ori r5,r30,0x0000
subfic r5,r5,31 addi r6,r0,0x0000
or r30,r3,r5 bl .p_ptegg
bl .ppcDcbz_area addi r4,r0,0x0101
/*--------------------------------------------------------------------+ stw r4,0x0004(r3)
| Setup 0x00000000FFFFFFFF mask in r29. addis r4,r0,0x0100
+--------------------------------------------------------------------*/ ori r4,r4,0x0180
addi r29,r0,0x0001 stw r4,0x000C(r3)
rldicl r29,r29,32,31 /*--------------------------------------------------------------------+
addi r29,r29,-1 | Setup 64KB of addresses in I/O space (0xF4000000).
/*--------------------------------------------------------------------+ +--------------------------------------------------------------------*/
| Setup 48MB of addresses in DRAM in page table (3 large PTE). The addi r3,r0,0x0010
| parameters to p_ptegg are: r3 = lp, r4 = ea, r5 = sdr1, r6 = vsid. mtctr r3
+--------------------------------------------------------------------*/ addis r31,r0,0xF400
addi r3,r0,0x0001 and r31,r31,r29
addi r4,r0,0x0000 ..aF4: addi r3,r0,0x0000
ori r5,r30,0x0000 ori r4,r31,0x0000
addi r6,r0,0x0000 ori r5,r30,0x0000
bl .p_ptegg addi r6,r0,0x000F
addi r4,r0,0x0001 bl .p_ptegg
stw r4,0x0004(r3) addi r6,r3,0x0080
addi r4,r0,0x0180 ..aF4a: lwz r4,0x0004(r3)
stw r4,0x000C(r3) cmpli cr0,1,r4,0x0000
/*--------------------------------------------------------------------+ beq ..aF4s
| Second 16MB is mapped here. addi r3,r3,0x0010
+--------------------------------------------------------------------*/ cmp cr0,1,r3,r6
addi r3,r0,0x0001 blt ..aF4a
addis r4,r0,0x0100 ..aF4h: b ..aF4h
ori r5,r30,0x0000 ..aF4s: rlwinm r4,r31,16,4,24
addi r6,r0,0x0000 ori r4,r4,0x0001
bl .p_ptegg stw r4,0x0004(r3)
addi r4,r0,0x0101 ori r4,r31,0x01AC
stw r4,0x0004(r3) stw r4,0x000C(r3)
addis r4,r0,0x0100 addi r31,r31,0x1000
ori r4,r4,0x0180 bdnz ..aF4
stw r4,0x000C(r3) /*--------------------------------------------------------------------+
/*--------------------------------------------------------------------+ | Setup 16MB of addresses in NB register space (0xF8000000).
| Third 16MB is mapped here. +--------------------------------------------------------------------*/
+--------------------------------------------------------------------*/ addi r3,r0,0x1000
addi r3,r0,0x0001 mtctr r3
addis r4,r0,0x0200 addis r31,r0,0xF800
ori r5,r30,0x0000 and r31,r31,r29
addi r6,r0,0x0000 ..aF8: addi r3,r0,0x0000
bl .p_ptegg ori r4,r31,0x0000
addi r4,r0,0x0201 ori r5,r30,0x0000
stw r4,0x0004(r3) addi r6,r0,0x000F
addis r4,r0,0x0200 bl .p_ptegg
ori r4,r4,0x0180 addi r6,r3,0x0080
stw r4,0x000C(r3) ..aF8a: lwz r4,0x0004(r3)
/*--------------------------------------------------------------------+ cmpli cr0,1,r4,0x0000
| Setup 64KB of addresses in I/O space (0xF4000000). beq ..aF8s
+--------------------------------------------------------------------*/ addi r3,r3,0x0010
addi r3,r0,0x0010 cmp cr0,1,r3,r6
mtctr r3 blt ..aF8a
addis r31,r0,0xF400 ..aF8h: b ..aF8h
and r31,r31,r29 ..aF8s: rlwinm r4,r31,16,4,24
5: addi r3,r0,0x0000 ori r4,r4,0x0001
ori r4,r31,0x0000 stw r4,0x0004(r3)
ori r5,r30,0x0000 ori r4,r31,0x01AC
addi r6,r0,0x000F stw r4,0x000C(r3)
bl .p_ptegg addi r31,r31,0x1000
addi r6,r3,0x0080 bdnz ..aF8
6: lwz r4,0x0004(r3) /*--------------------------------------------------------------------+
cmpli cr0,1,r4,0x0000 | Setup 16MB or 1MB of addresses in ROM (at 0xFF000000 or 0xFFF00000).
beq 8f +--------------------------------------------------------------------*/
addi r3,r3,0x0010 mfspr r3,SPR_HIOR
cmp cr0,1,r3,r6 LOAD_64BIT_VAL(r4,BOOT_BASE_AS)
blt 6b cmpd cr0,r3,r4
7: b 7b beq ..big
8: rlwinm r4,r31,16,4,24 addi r3,r0,0x0100
ori r4,r4,0x0001 mtctr r3
stw r4,0x0004(r3) addis r31,r0,0xFFF0
ori r4,r31,0x01AC b ..done
stw r4,0x000C(r3) ..big: addi r3,r0,0x1000
addi r31,r31,0x1000 mtctr r3
bdnz 5b addis r31,r0,0xFF00
/*--------------------------------------------------------------------+ ..done: and r31,r31,r29
| Setup 16MB of addresses in NB register space (0xF8000000). ..aFF: addi r3,r0,0x0000
+--------------------------------------------------------------------*/ ori r4,r31,0x0000
addi r3,r0,0x1000 ori r5,r30,0x0000
mtctr r3 addi r6,r0,0x000F
addis r31,r0,0xF800 bl .p_ptegg
and r31,r31,r29 addi r6,r3,0x0080
9: addi r3,r0,0x0000 ..aFFa: lwz r4,0x0004(r3)
ori r4,r31,0x0000 cmpli cr0,1,r4,0x0000
ori r5,r30,0x0000 beq ..aFFs
addi r6,r0,0x000F addi r3,r3,0x0010
bl .p_ptegg cmp cr0,1,r3,r6
addi r6,r3,0x0080 blt ..aFFa
10: lwz r4,0x0004(r3) ..aFFh: b ..aFFh
cmpli cr0,1,r4,0x0000 ..aFFs: rlwinm r4,r31,16,4,24
beq 12f ori r4,r4,0x0001
addi r3,r3,0x0010 stw r4,0x0004(r3)
cmp cr0,1,r3,r6 ori r4,r31,0x01A3
blt 10b stw r4,0x000C(r3)
11: b 11b addi r31,r31,0x1000
12: rlwinm r4,r31,16,4,24 bdnz ..aFF
ori r4,r4,0x0001 /*--------------------------------------------------------------------+
stw r4,0x0004(r3) | Synchronize after setting up page table.
ori r4,r31,0x01AC +--------------------------------------------------------------------*/
stw r4,0x000C(r3) ptesync
addi r31,r31,0x1000 /*--------------------------------------------------------------------+
bdnz 9b | Set the SDR1 register.
/*--------------------------------------------------------------------+ +--------------------------------------------------------------------*/
| Setup 16MB or 1MB of addresses in ROM (at 0xFF000000 or 0xFFF00000). mtspr SPR_SDR1,r30
+--------------------------------------------------------------------*/ /*--------------------------------------------------------------------+
mfspr r3,SPR_HIOR | Clear SRR0, SRR1.
LOAD_64BIT_VAL(r4,BOOT_BASE_AS) +--------------------------------------------------------------------*/
cmpd cr0,r3,r4 addi r0,r0,0x0000
beq 13f mtspr SPR_SRR0,r0
addi r3,r0,0x0100 mtspr SPR_SRR1,r0
mtctr r3 /*--------------------------------------------------------------------+
addis r31,r0,0xFFF0 | Setup for subsequent MSR[ME] initialization to enable machine checks
b 14f | and translation.
13: addi r3,r0,0x1000 +--------------------------------------------------------------------*/
mtctr r3 mfmsr r3
addis r31,r0,0xFF00 ori r3,r3,(MSR_ME|MSR_IS|MSR_DS|MSR_FP)
14: and r31,r31,r29 mtsrr1 r3
15: addi r3,r0,0x0000 mtmsrd r3,0
ori r4,r31,0x0000 isync
ori r5,r30,0x0000 /*--------------------------------------------------------------------+
addi r6,r0,0x000F | Setup HID registers (HID0, HID1, HID4, HID5). When HIOR is set to
bl .p_ptegg | 0 HID0 external time base bit is inherited from current HID0. When
addi r6,r3,0x0080 | HIOR is set to FLASH_BASE_INTEL_AS then HID0 external time base bit
16: lwz r4,0x0004(r3) | is set to 1 in order to indicate that the tiembase is driven by
cmpli cr0,1,r4,0x0000 | external source. When HIOR is greater than FLASH_BASE_INTEL_AS then
beq 18f | HID0 external time base bit is set to 0 in order to indicate that the
addi r3,r3,0x0010 | tiembase is driven from internal clock.
cmp cr0,1,r3,r6 +--------------------------------------------------------------------*/
blt 16b LOAD_64BIT_VAL(r6,HID0_EXT_TB_EN)
17: b 17b LOAD_64BIT_VAL(r7,FLASH_BASE_INTEL_AS)
18: rlwinm r4,r31,16,4,24 mfspr r5,SPR_HIOR
ori r4,r4,0x0001 cmpdi cr0,r5,0x0000
stw r4,0x0004(r3) beq ..hior0
ori r4,r31,0x01A3 cmpd cr0,r5,r7
stw r4,0x000C(r3) beq ..hiorl
addi r31,r31,0x1000 addi r8,r0,0x0000
bdnz 15b b ..hiors
/*--------------------------------------------------------------------+ ..hiorl:ori r8,r6,0x0000
| Synchronize after setting up page table. b ..hiors
+--------------------------------------------------------------------*/ ..hior0:mfspr r5,SPR_HID0
ptesync and r8,r5,r6
/*--------------------------------------------------------------------+ ..hiors:LOAD_64BIT_VAL(r4,HID0_PREFEAR)
| Set the SDR1 register. andc r4,r4,r6
+--------------------------------------------------------------------*/ or r4,r4,r8
mtspr SPR_SDR1,r30 sync
/*--------------------------------------------------------------------+ mtspr SPR_HID0,r4
| Clear SRR0, SRR1. mfspr r4,SPR_HID0
+--------------------------------------------------------------------*/ mfspr r4,SPR_HID0
addi r0,r0,0x0000 mfspr r4,SPR_HID0
mtspr SPR_SRR0,r0 mfspr r4,SPR_HID0
mtspr SPR_SRR1,r0 mfspr r4,SPR_HID0
/*--------------------------------------------------------------------+ mfspr r4,SPR_HID0
| Setup for subsequent MSR[ME] initialization to enable machine checks LOAD_64BIT_VAL(r4,HID1_PREFEAR)
| and translation. mtspr SPR_HID1,r4
+--------------------------------------------------------------------*/ mtspr SPR_HID1,r4
mfmsr r3 isync
ori r3,r3,(MSR_ME|MSR_IS|MSR_DS|MSR_FP) LOAD_64BIT_VAL(r4,HID4_PREFEAR)
mtsrr1 r3 sync
mtmsrd r3,0 mtspr SPR_HID4,r4
isync isync
/*--------------------------------------------------------------------+ sync
| Setup HID registers (HID0, HID1, HID4, HID5). When HIOR is set to LOAD_64BIT_VAL(r4,HID5_PREFEAR)
| 0 HID0 external time base bit is inherited from current HID0. When mtspr SPR_HID5,r4
| HIOR is set to FLASH_BASE_INTEL_AS then HID0 external time base bit isync
| 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 | Synchronize memory accesses (sync).
| HID0 external time base bit is set to 0 in order to indicate that the +--------------------------------------------------------------------*/
| tiembase is driven from internal clock. sync
+--------------------------------------------------------------------*/ LOAD_64BIT_VAL(r0,.init_chip)
LOAD_64BIT_VAL(r6,HID0_EXT_TB_EN) mfspr r1,SPR_HIOR
LOAD_64BIT_VAL(r7,FLASH_BASE_INTEL_AS) or r0,r0,r1
mfspr r5,SPR_HIOR eieio
cmpdi cr0,r5,0x0000 mtspr SPR_SRR0,r0
beq 19f rfid
cmpd cr0,r5,r7 function_epilog(init_core)
beq 20f
addi r8,r0,0x0000
b 21f /******** init_chip.s ***************/
20: ori r8,r6,0x0000 /*----------------------------------------------------------------------------+
b 21f | Local defines.
19: mfspr r5,SPR_HID0 +----------------------------------------------------------------------------*/
and r8,r5,r6 #define CPU1_DELAY 0x00010000
21: LOAD_64BIT_VAL(r4,HID0_PREFEAR)
andc r4,r4,r6 /*----------------------------------------------------------------------------+
or r4,r4,r8 | Init_chip.
sync +----------------------------------------------------------------------------*/
mtspr SPR_HID0,r4 function_prolog(init_chip)
mfspr r4,SPR_HID0 /*--------------------------------------------------------------------+
mfspr r4,SPR_HID0 | Skip if CPU1.
mfspr r4,SPR_HID0 +--------------------------------------------------------------------*/
mfspr r4,SPR_HID0 mfspr r3,SPR_PIR
mfspr r4,SPR_HID0 cmpi cr0,1,r3,0x0000
mfspr r4,SPR_HID0 bne ..cpu1
LOAD_64BIT_VAL(r4,HID1_PREFEAR) /*--------------------------------------------------------------------+
mtspr SPR_HID1,r4 | Initialize the stack in the data cache for the "C" code that gets
mtspr SPR_HID1,r4 | called.
isync +--------------------------------------------------------------------*/
LOAD_64BIT_VAL(r4,HID4_PREFEAR) addis r3,r0,BOOT_STACK_ADDR@h
sync ori r3,r3,BOOT_STACK_ADDR@l
mtspr SPR_HID4,r4 addis r4,r0,BOOT_STACK_SIZE@h
isync ori r4,r4,BOOT_STACK_SIZE@l
sync add r1,r3,r4
LOAD_64BIT_VAL(r4,HID5_PREFEAR) bl .ppcDcbz_area
mtspr SPR_HID5,r4 addi r1,r1,-stack_frame_min
isync addi r5,r0,0x0000
/*--------------------------------------------------------------------+ std r5,stack_frame_bc(r1)
| Synchronize memory accesses (sync). /*--------------------------------------------------------------------+
+--------------------------------------------------------------------*/ | Load TOC. Can't use ld since the TOC value might not be aligned on
sync | double word boundary.
LOAD_64BIT_VAL(r0,.init_chip) +--------------------------------------------------------------------*/
mfspr r1,SPR_HIOR bl ..ot_init_chip
or r0,r0,r1 .quad .TOC.@tocbase
eieio ..ot_init_chip: mflr r3
mtspr SPR_SRR0,r0 lwz r2,0x0000(r3)
rfid 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 ## linuxBIOS C code runs at this location in RAM
default _RAMBASE=0x00100000 default _RAMBASE=0x00100000
default CROSS_COMPILE="powerpc-405-linux-gnu-"
### End Options.lb ### End Options.lb
end end

View File

@ -5,60 +5,61 @@
## ##
## Early board initialization, called from ppc_main() ## 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 arch ppc end
chip northbridge/ibm/cpc925 chip northbridge/ibm/cpc925
device pci_domain 0 on device pci_domain 0 on
device pci 00.0 on end chip southbridge/amd/amd8131
device pci 00.1 on end device pci 01.0 on #PCI-X Bridge
device pci 01.0 on end chip drivers/pci/onboard #intel GD31244 chip
device pci 02.0 on device pci 01.0 on end #SATA controller
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
end end
device pci 00.3 on end
end end
end device pci 01.1 on end #APIC controller
device pci 06.0 on end device pci 02.0 on end #PCI-X Bridge
chip southbridge/intel/ich5r # ich5r device pci 02.1 on end #APIC controller
device pci 1d.0 on end device pci 03.0 on #PCI-X Bridge
device pci 1d.1 on end chip drivers/pci/onboard #intel i82546EB chip
device pci 1d.2 on end device pci 01.0 on end #GB Ethernet 0
device pci 1d.3 off end device pci 01.1 on end #GB Ethernet 1
device pci 1d.7 on end end
device pci 1e.0 on 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 chip drivers/ati/ragexl
device pci 0c.0 on end device pci 3.0 on end # ATI Rage Video Controller
end end
end end
device pci 1f.0 on device pci 6.0 on #ISA Bridge/LPC Controller
chip superio/NSC/pc87427 chip superio/NSC/pc87427 #NSC Super IO chip
device pnp 2e.0 off end device pnp 2e.0 off end
device pnp 2e.2 on device pnp 2e.2 on
# io 0x60 = 0x2f8 io 0x60 = 0x3f8
# irq 0x70 = 3
io 0x60 = 0x3f8
irq 0x70 = 4 irq 0x70 = 4
end end
device pnp 2e.3 on device pnp 2e.3 on
# io 0x60 = 0x3f8 io 0x60 = 0x2f8
# irq 0x70 = 4
io 0x60 = 0x2f8
irq 0x70 = 3 irq 0x70 = 3
end end
device pnp 2e.4 off end device pnp 2e.4 off end
device pnp 2e.5 off end device pnp 2e.5 off end
device pnp 2e.6 on device pnp 2e.6 on
io 0x60 = 0x60 io 0x60 = 0x60
io 0x62 = 0x64 io 0x62 = 0x64
irq 0x70 = 1 irq 0x70 = 1
end end
device pnp 2e.7 off end device pnp 2e.7 off end
@ -67,36 +68,18 @@ chip northbridge/ibm/cpc925
device pnp 2e.f on end device pnp 2e.f on end
device pnp 2e.10 off end device pnp 2e.10 off end
device pnp 2e.14 off end device pnp 2e.14 off end
end end #NSC Super IO chip
end end #ISA Bridge/LPC
device pci 1f.1 on end device pci 6.1 on end #IDE Controller
device pci 1f.2 off end device pci 6.2 on end #SMBus Controller
device pci 1f.3 on end device pci 6.3 on end #ACPI
device pci 1f.5 off end device pci 6.5 off end #AC97 Audio
device pci 1f.6 off end device pci 6.6 off end #MC97 Modem
register "gpio[40]" = "ICH5R_GPIO_USE_AS_GPIO" end #amd8111
register "gpio[48]" = "ICH5R_GPIO_USE_AS_GPIO | ICH5R_GPIO_SEL_OUTPUT | ICH5R_GPIO_LVL_LOW" end #pci domain 0
register "gpio[41]" = "ICH5R_GPIO_USE_AS_GPIO | ICH5R_GPIO_SEL_INPUT" end #cpc925
end
end
device apic_cluster 0 on
chip cpu/ppc/ppc970 # cpu 0
end
chip cpu/ppc/ppc970 # cpu 1
end
end
end
chip cpu/ppc/ppc970
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
end 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.o
initobject cpc925_pci.o initobject cpc925_pci.o
initobject cpc925_sdram.o
object cpc925.o object cpc925.o
object cpc925_pci.o object cpc925_pci.o
object cpc925_sdram.o
driver cpc925_northbridge.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);
}