How to get rom code to go on FADS?
Dan A. Dickey
ddickey at charter.net
Sat May 13 23:54:33 EST 2000
Richard Hendricks wrote:
...
> Maybe if you could post the "bare-bones" init code you are trying
> to use, we can offer more help.
Ok, here is the start.S I'm using - its pretty much from 8xxROM,
but with some changes by me.
-Dan
/* 8xxROM - Startup Code for the FADS8xx series of Embedded Boards
* Copyright (C) 1998 Dan Malek <dmalek at jlc.net>
* Copyright (C) 1999 Magnus Damm <kieraypc01.p.y.kie.era.ericsson.se>
*
* 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., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA
*
* The processor starts at 0x00000100 and the code is executed
* from flash. The code is organized to be at an other address
* in memory, but as long we don't jump around before relocating.
* board_init lies at a quite high address and when the cpu has
* jumped there, everything is ok.
* This works because the cpu gives the flash (CS0) the whole
* address space at startup, and board_init lies as a echo of
* the flash somewhere up there in the memorymap.
*
* board_init will change CS0 to be positioned at the correct
* address and (s)dram will be positioned at address 0
*/
#include "config.h"
#define CONFIG_8xx 1
#define _LINUX_CONFIG_H 1
#include "ppc_asm.tmpl"
#include "ppc_defs.h"
#include <asm/processor.h>
#include <asm/cache.h>
#include <asm/mmu.h>
#include <board/board.h>
/* We don't want the MMU yet.
*/
#undef MSR_KERNEL
#define MSR_KERNEL MSR_
.text
.globl version_string
version_string:
.string "8xxROM 0.3.0"
. =
0x100
.globl _start
Xreset:
addis r2,0,_start at h
ori r2,r2,_start at l
mtspr LR,r2
bclr 20,0
/* Machine check */
STD_EXCEPTION(0x200, MachineCheck, MachineCheckException)
/* Data Storage exception. "Never" generated on the 860. */
STD_EXCEPTION(0x300, DataStorage, UnknownException)
/* Instruction Storage exception. "Never" generated on the 860. */
STD_EXCEPTION(0x400, InstStorage, UnknownException)
/* External Interrupt exception. */
STD_EXCEPTION(0x500, ExtInterrupt, UnknownException)
/* Alignment exception. */
. = 0x600
Alignment:
EXCEPTION_PROLOG
mfspr r4,DAR
stw r4,_DAR(r21)
mfspr r5,DSISR
stw r5,_DSISR(r21)
addi r3,r1,STACK_FRAME_OVERHEAD
li r20,MSR_KERNEL
rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
lis r6, transfer_to_handler at h
ori r6, r6, transfer_to_handler at l
mtlr r6
blrl
.long AlignmentException
.long int_return
/* Program check exception */
. = 0x700
ProgramCheck:
EXCEPTION_PROLOG
addi r3,r1,STACK_FRAME_OVERHEAD
li r20,MSR_KERNEL
rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
lis r6, transfer_to_handler at h
ori r6, r6, transfer_to_handler at l
mtlr r6
blrl
.long ProgramCheckException
.long int_return
/* No FPU on MPC8xx. This exception is not supposed to
happen.
*/
STD_EXCEPTION(0x800, FPUnavailable, UnknownException)
/* I guess we could implement decrementer, and may have
* to someday for timekeeping.
*/
STD_EXCEPTION(0x900, Decrementer, UnknownException)
STD_EXCEPTION(0xa00, Trap_0a, UnknownException)
STD_EXCEPTION(0xb00, Trap_0b, UnknownException)
STD_EXCEPTION(0xc00, SystemCall, UnknownException)
STD_EXCEPTION(0xd00, SingleStep, UnknownException)
STD_EXCEPTION(0xe00, Trap_0e, UnknownException)
STD_EXCEPTION(0xf00, Trap_0f, UnknownException)
/* On the MPC8xx, this is a software emulation interrupt. It
occurs
* for all unimplemented and illegal instructions.
*/
STD_EXCEPTION(0x1000, SoftEmu, SoftEmuException)
STD_EXCEPTION(0x1100, InstructionTLBMiss, UnknownException)
STD_EXCEPTION(0x1200, DataTLBMiss, UnknownException)
STD_EXCEPTION(0x1300, InstructionTLBError, UnknownException)
STD_EXCEPTION(0x1400, DataTLBError, UnknownException)
STD_EXCEPTION(0x1500, Reserved5, UnknownException)
STD_EXCEPTION(0x1600, Reserved6, UnknownException)
STD_EXCEPTION(0x1700, Reserved7, UnknownException)
STD_EXCEPTION(0x1800, Reserved8, UnknownException)
STD_EXCEPTION(0x1900, Reserved9, UnknownException)
STD_EXCEPTION(0x1a00, ReservedA, UnknownException)
STD_EXCEPTION(0x1b00, ReservedB, UnknownException)
STD_EXCEPTION(0x1c00, DataBreakpoint, UnknownException)
STD_EXCEPTION(0x1d00, InstructionBreakpoint, UnknownException)
STD_EXCEPTION(0x1e00, PeripheralBreakpoint, UnknownException)
STD_EXCEPTION(0x1f00, DevPortBreakpoint, UnknownException)
.globl _end_of_vectors
_end_of_vectors:
. = 0x2000
_start:
/* the original fadsrom code by Dan Malek did a lot of setup
*/
/* in assembler, I moved most of the code to C for readability
*/
addis r3, 0, _start at h
ori r3, r3, _start at l
addi r3, r3, 0x0014 /* Jumps us into the NOPs below */
mtctr
r3
bctr
nop
nop
/* Now we need to fix the LR since it points back to
0x0000_010x,
* not 0x0280_010x like it needs to after we muck up the BCSR's
*/
mflr r3
oris r3, r3, 0x0280
mtlr r3
addis r0,0,0
addi r3, r0, MSR_ /* Set ME, RI flags */
mtmsr r3
mtspr SRR1, r3 /* Make SRR1 match MSR */
/* Make the LR equal the PC. */
oris r3,r0,sync_jump at h
ori r3,r3,sync_jump at l
mtspr LR,r3
bclr 20,0
sync_jump:
#if 1
/* position IMMR */
lis r1, IMMR_VALUE at h
ori r1, r1, 0
mtspr 638, r1
bror1start:
/* need to setup BR1/OR1 to get to the BCSR on the fads */
lis r9,0xffff
ori r9,r9,0x8110
lis r10,0x0210
ori r10,r10,0x0001
stw r9,0x10C(r1)
stw r10,0x108(r1)
/* signal on */
lis r8,0x210
ori r8,r8,16
lis r9,0x210
ori r9,r9,16
lwz r10,0(r9)
rlwinm r9,r10,0,4,2
stw r9,0(r8)
#if 1
/* signal delay */
lis r8,0x5
sdloop1:
addi r8,r8,-1
li r9,-1
cmpw r0,r8,r9
bc 4,2,sdcont1
b sdstop1
sdcont1:
b sdloop1
sdstop1:
#endif
/* signal off */
lis r8,0x210
ori r8,r8,16
lis r9,0x210
ori r9,r9,16
lwz r10,0(r9)
oris r9,r10,0x1000
stw r9,0(r8)
#if 1
/* signal delay */
lis r8,0x5
sdloop2:
addi r8,r8,-1
li r9,-1
cmpw r0,r8,r9
bc 4,2,sdcont2
b sdstop2
sdcont2:
b sdloop2
sdstop2:
#endif
/* signal on */
lis r8,0x210
ori r8,r8,16
lis r9,0x210
ori r9,r9,16
lwz r10,0(r9)
rlwinm r9,r10,0,4,2
stw r9,0(r8)
#endif
addis r0,0,0
/* invalidate all tlb's */
tlbia
isync
#if 1
/* Reset the caches.
*/
lis r21, IDC_UNALL at h /* Unlock all */
mtspr IC_CST, r21
mtspr DC_CST, r21
lis r21, IDC_INVALL at h /* Invalidate all */
mtspr IC_CST, r21
mtspr DC_CST, r21
lis r21, IDC_DISABLE at h /* Disable data cache */
mtspr DC_CST, r21
#if 0
lis r21, IDC_ENABLE at h /* Enable instruction cache */
#else
lis r21, IDC_DISABLE at h /* Disable instruction cache */
#endif
mtspr IC_CST, r21
#endif
/* initialize some sprs that are hard to access from c */
/* Disable serialized ifetch and show cycles (i.e. set processor
* to normal mode).
* this is also a silicon bug workaround, see errata
*/
li r21, 0x0007
mtspr ICTRL, r21
/* Disable debug mode entry.
*/
li r21, 0
mtspr DER, r21
/* position IMMR */
lis r1, IMMR_VALUE at h
mtspr 638, r1
/* set up the stack to the internal DPRAM */
/* oris r1,r0,0 */
ori r1,r1,0x3000
/* load the stack pointer 72 bytes down from top of stack to
ensure one
* stack frame of safety margin.
*/
stwu r0,-72(r1)
/* let the c-code set up the rest */
lis r2,board_init at h
ori r2,r2,board_init at l
mtlr r2 /* Easiest way to do an absolute
jump */
blr
/* board_init will call start_main as the last thing it does. */
.globl start_main
start_main:
/* Initialize stack pointer and jump to main function.
* the c-code passed the stackpointer in r3 and the
* argument to main in r4.
*/
mr r1, r3 /* first argument from c-code */
mr r3, r4 /* second argument to first */
mr r4, r5 /* third argument to second */
bl main_loop
1: b 1b /* Loop forever if main exits */
/*
* This code finishes saving the registers to the exception frame
* and jumps to the appropriate handler for the exception.
* Register r21 is pointer into trap frame, r1 has new stack pointer.
*/
.globl transfer_to_handler
transfer_to_handler:
stw r22,_NIP(r21)
lis r22,MSR_POW at h
andc r23,r23,r22
stw r23,_MSR(r21)
SAVE_GPR(7, r21)
SAVE_4GPRS(8, r21)
SAVE_8GPRS(12, r21)
SAVE_8GPRS(24, r21)
#if 0
andi. r23,r23,MSR_PR
mfspr r23,SPRG3 /* if from user, fix up tss.regs
*/
beq 2f
addi r24,r1,STACK_FRAME_OVERHEAD
stw r24,PT_REGS(r23)
2: addi r2,r23,-TSS /* set r2 to current */
tovirt(r2,r2,r23)
#endif
mflr r23
andi. r24,r23,0x3f00 /* get vector offset */
stw r24,TRAP(r21)
li r22,0
stw r22,RESULT(r21)
mtspr SPRG2,r22 /* r1 is now kernel sp */
#if 0
addi r24,r2,TASK_STRUCT_SIZE /* check for kernel stack
overflow */
cmplw 0,r1,r2
cmplw
1,r1,r24
crand 1,1,4
bgt stack_ovf /* if r2 < r1 <
r2+TASK_STRUCT_SIZE */
#endif
lwz r24,0(r23) /* virtual address of handler */
lwz r23,4(r23) /* where to go when done */
mtspr SRR0,r24
mtspr SRR1,r20
mtlr r23
SYNC
rfi /* jump to handler, enable MMU
*/
int_return:
mfmsr r30 /* Disable interrupts */
li r4,0
ori r4,r4,MSR_EE
andc r30,r30,r4
SYNC /* Some chip revs need this... */
mtmsr r30
SYNC
lwz r2,_CTR(r1)
lwz r0,_LINK(r1)
mtctr r2
mtlr r0
lwz r2,_XER(r1)
lwz r0,_CCR(r1)
mtspr XER,r2
mtcrf 0xFF,r0
REST_10GPRS(3, r1)
REST_10GPRS(13, r1)
REST_8GPRS(23, r1)
REST_GPR(31, r1)
lwz r2,_NIP(r1) /* Restore environment */
lwz r0,_MSR(r1)
mtspr SRR0,r2
mtspr SRR1,r0
lwz r0,GPR0(r1)
lwz r2,GPR2(r1)
lwz r1,GPR1(r1)
SYNC
rfi
/* Cache functions.
*/
.globl icache_enable
icache_enable:
SYNC
lis r3, IDC_INVALL at h
mtspr IC_CST, r3
lis r3, IDC_ENABLE at h
mtspr IC_CST, r3
blr
.globl icache_disable
icache_disable:
SYNC
lis r3, IDC_DISABLE at h
mtspr IC_CST, r3
blr
.globl dcache_enable
dcache_enable:
#if 0
SYNC
#endif
#if 1
lis r3, 0x0400 /* Set cache mode with MMU off
*/
mtspr MD_CTR, r3
#endif
lis r3, IDC_INVALL at h
mtspr DC_CST, r3
#if 0
lis r3, DC_SFWT at h
mtspr DC_CST, r3
#endif
lis r3, IDC_ENABLE at h
mtspr DC_CST, r3
blr
.globl dcache_disable
dcache_disable:
SYNC
lis r3, IDC_DISABLE at h
mtspr DC_CST, r3
lis r3, IDC_INVALL at h
mtspr DC_CST, r3
blr
.globl dc_stat
dc_stat:
mfspr r3, DC_CST
blr
.globl dc_read
dc_read:
mtspr DC_ADR, r3
mfspr r3, DC_DAT
blr
#if 1
.globl udelay
udelay:
mulli r4,r3,1000 /* nanoseconds */
addi r4,r4,59
li r5,60
divw r4,r4,r5 /* BUS ticks */
1: mftbu r5
mftb
r6
mftbu r7
cmp 0,r5,r7
bne 1b /* Get [synced] base time */
addc r9,r6,r4 /* Compute end time */
addze r8,r5
2: mftbu r5
cmp 0,r5,r8
blt 2b
bgt 3f
mftb r6
cmp 0,r6,r9
blt 2b
3: blr
#endif
.globl get_immr
get_immr:
mfspr r3, 638
blr
.globl get_pvr
get_pvr:
mfspr r3, PVR
blr
.globl wr_ic_cst
wr_ic_cst:
mtspr IC_CST, r3
blr
.globl rd_ic_cst
rd_ic_cst:
mfspr r3, IC_CST
blr
.globl wr_ic_adr
wr_ic_adr:
mtspr IC_ADR, r3
blr
.globl wr_dc_cst
wr_dc_cst:
mtspr DC_CST, r3
blr
.globl rd_dc_cst
rd_dc_cst:
mfspr r3, DC_CST
blr
.globl
wr_dc_adr
wr_dc_adr:
mtspr DC_ADR, r3
blr
** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/
More information about the Linuxppc-embedded
mailing list