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 */