summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/powerpc/mcp750/bootloader/head.S
diff options
context:
space:
mode:
Diffstat (limited to 'c/src/lib/libbsp/powerpc/mcp750/bootloader/head.S')
-rw-r--r--c/src/lib/libbsp/powerpc/mcp750/bootloader/head.S381
1 files changed, 0 insertions, 381 deletions
diff --git a/c/src/lib/libbsp/powerpc/mcp750/bootloader/head.S b/c/src/lib/libbsp/powerpc/mcp750/bootloader/head.S
deleted file mode 100644
index 232232be50..0000000000
--- a/c/src/lib/libbsp/powerpc/mcp750/bootloader/head.S
+++ /dev/null
@@ -1,381 +0,0 @@
-/*
- * head.S -- Bootloader Entry point
- *
- * Copyright (C) 1998, 1999 Gabriel Paubert, paubert@iram.es
- *
- * Modified to compile in RTEMS development environment
- * by Eric Valette
- *
- * Copyright (C) 1999 Eric Valette. valette@crf.canon.fr
- *
- * The license and distribution terms for this file may be
- * found in found in the file LICENSE in this distribution or at
- * http://www.OARcorp.com/rtems/license.html.
- *
- * $Id$
- */
-
-#include "bootldr.h"
-#include <libcpu/cpu.h>
-#include <rtems/score/targopts.h>
-#include "asm.h"
-
-#undef TEST_PPCBUG_CALLS
-#define FRAME_SIZE 32
-#define LOCK_CACHES (HID0_DLOCK|HID0_ILOCK)
-#define INVL_CACHES (HID0_DCI|HID0_ICFI)
-#define ENBL_CACHES (HID0_DCE|HID0_ICE)
-
-#define USE_PPCBUG
-#undef USE_PPCBUG
-
-#define MONITOR_ENTER \
- mfmsr r10 ; \
- ori r10,r10,MSR_IP ; \
- mtmsr r10 ; \
- li r10,0x63 ; \
- sc
-
- START_GOT
- GOT_ENTRY(_GOT2_TABLE_)
- GOT_ENTRY(_FIXUP_TABLE_)
- GOT_ENTRY(.bss)
- GOT_ENTRY(codemove)
- GOT_ENTRY(0)
- GOT_ENTRY(__bd)
- GOT_ENTRY(moved)
- GOT_ENTRY(_binary_rtems_gz_start)
- GOT_ENTRY(_binary_initrd_gz_start)
- GOT_ENTRY(_binary_initrd_gz_end)
-#ifdef TEST_PPCBUG_CALLS
- GOT_ENTRY(banner_start)
- GOT_ENTRY(banner_end)
-#endif
- END_GOT
- .globl start
- .type start,@function
-/* Point the stack into the PreP partition header in the x86 reserved
- * code area, so that simple C routines can be called.
- */
-start:
-#ifdef USE_PPCBUG
- MONITOR_ENTER
-#endif
- bl 1f
-1: mflr r1
- li r0,0
- stwu r0,start-1b-0x400+0x1b0-FRAME_SIZE(r1)
- stmw r26,FRAME_SIZE-24(r1)
- GET_GOT
- mfmsr r28 /* Turn off interrupts */
- ori r0,r28,MSR_EE
- xori r0,r0,MSR_EE
- mtmsr r0
-
-/* Enable the caches, from now on cr2.eq set means processor is 601 */
- mfpvr r0
- mfspr r29,HID0
- srwi r0,r0,16
- cmplwi cr2,r0,1
- beq 2,2f
-#ifndef USE_PPCBUG
- ori r0,r29,ENBL_CACHES|INVL_CACHES|LOCK_CACHES
- xori r0,r0,INVL_CACHES|LOCK_CACHES
- sync
- isync
- mtspr HID0,r0
-#endif
-2: bl reloc
-
-/* save all the parameters and the orginal msr/hid0/r31 */
- lwz bd,GOT(__bd)
- stw r3,0(bd)
- stw r4,4(bd)
- stw r5,8(bd)
- stw r6,12(bd)
- lis r3,__size@sectoff@ha
- stw r7,16(bd)
- stw r8,20(bd)
- addi r3,r3,__size@sectoff@l
- stw r9,24(bd)
- stw r10,28(bd)
- stw r28,o_msr(bd)
- stw r29,o_hid0(bd)
- stw r31,o_r31(bd)
-
-/* Call the routine to fill boot_data structure from residual data.
- * And to find where the code has to be moved.
- */
- bl early_setup
-
-/* Now we need to relocate ourselves, where we are told to. First put a
- * copy of the codemove routine to some place in memory.
- * (which may be where the 0x41 partition was loaded, so size is critical).
- */
- lwz r4,GOT(codemove)
- li r5,_size_codemove
- lwz r3,mover(bd)
- lwz r6,cache_lsize(bd)
- bl codemove
- mtctr r3 # Where the temporary codemove is.
- lwz r3,image(bd)
- lis r5,_edata@sectoff@ha
- lwz r4,GOT(0) # Our own address
- addi r5,r5,_edata@sectoff@l
- lwz r6,cache_lsize(bd)
- lwz r8,GOT(moved)
- sub r7,r3,r4 # Difference to adjust pointers.
- add r8,r8,r7
- add r30,r30,r7
- add bd,bd,r7
-/* Call the copy routine but return to the new area. */
- mtlr r8 # for the return address
- bctr # returns to the moved instruction
-/* Establish the new top stack frame. */
-moved: lwz r1,stack(bd)
- li r0,0
- stwu r0,-16(r1)
-
-/* relocate again */
- bl reloc
-/* Clear all of BSS */
- lwz r10,GOT(.bss)
- li r0,__bss_words@sectoff@l
- subi r10,r10,4
- cmpwi r0,0
- mtctr r0
- li r0,0
- beq 4f
-3: stwu r0,4(r10)
- bdnz 3b
-
-/* Final memory initialization. First switch to unmapped mode
- * in case the FW had set the MMU on, and flush the TLB to avoid
- * stale entries from interfering. No I/O access is allowed
- * during this time!
- */
-#ifndef USE_PPCBUG
-4: bl MMUoff
-#endif
- bl flush_tlb
-/* Some firmware versions leave stale values in the BATs, it's time
- * to invalidate them to avoid interferences with our own mappings.
- * But the 601 valid bit is in the BATL (IBAT only) and others are in
- * the [ID]BATU. Bloat, bloat.. fortunately thrown away later.
- */
- li r3,0
- beq cr2,5f
- mtdbatu 0,r3
- mtdbatu 1,r3
- mtdbatu 2,r3
- mtdbatu 3,r3
-5: mtibatu 0,r3
- mtibatl 0,r3
- mtibatu 1,r3
- mtibatl 1,r3
- mtibatu 2,r3
- mtibatl 2,r3
- mtibatu 3,r3
- mtibatl 3,r3
- lis r3,__size@sectoff@ha
- addi r3,r3,__size@sectoff@l
- sync # We are going to touch SDR1 !
- bl mm_init
- bl MMUon
-
-/* Now we are mapped and can perform I/O if we want */
-#ifdef TEST_PPCBUG_CALLS
-/* Experience seems to show that PPCBug can only be called with the
- * data cache disabled and with MMU disabled. Bummer.
- */
- li r10,0x22 # .OUTLN
- lwz r3,GOT(banner_start)
- lwz r4,GOT(banner_end)
- sc
-#endif
- bl setup_hw
- lwz r4,GOT(_binary_rtems_gz_start)
- lis r5,_rtems_gz_size@sectoff@ha
- lwz r6,GOT(_binary_initrd_gz_start)
- lis r3,_rtems_size@sectoff@ha
- lwz r7,GOT(_binary_initrd_gz_end)
- addi r5,r5,_rtems_gz_size@sectoff@l
- addi r3,r3,_rtems_size@sectoff@l
- sub r7,r7,r6
- bl decompress_kernel
-
-/* Back here we are unmapped and we start the kernel, passing up to eight
- * parameters just in case, only r3 to r7 used for now. Flush the tlb so
- * that the loaded image starts in a clean state.
- */
- bl flush_tlb
- lwz r3,0(bd)
- lwz r4,4(bd)
- lwz r5,8(bd)
- lwz r6,12(bd)
- lwz r7,16(bd)
- lwz r8,20(bd)
- lwz r9,24(bd)
- lwz r10,28(bd)
-
- lwz r30,0(0)
- mtctr r30
-/*
- * Linux code again
- lis r30,0xdeadc0de@ha
- addi r30,r30,0xdeadc0de@l
- stw r30,0(0)
- li r30,0
-*/
- dcbst 0,r30 /* Make sure it's in memory ! */
-/* We just flash invalidate and disable the dcache, unless it's a 601,
- * critical areas have been flushed and we don't care about the stack
- * and other scratch areas.
- */
- beq cr2,1f
- mfspr r0,HID0
- ori r0,r0,HID0_DCI|HID0_DCE
- sync
- mtspr HID0,r0
- xori r0,r0,HID0_DCI|HID0_DCE
- mtspr HID0,r0
-/* Provisional return to FW, works for PPCBug */
-#if 0
- MONITOR_ENTER
-#else
-1: bctr
-#endif
-
-
-
-/* relocation function, r30 must point to got2+0x8000 */
-reloc:
-/* Adjust got2 pointers, no need to check for 0, this code already puts
- * a few entries in the table.
- */
- li r0,__got2_entries@sectoff@l
- la r12,GOT(_GOT2_TABLE_)
- lwz r11,GOT(_GOT2_TABLE_)
- mtctr r0
- sub r11,r12,r11
- addi r12,r12,-4
-1: lwzu r0,4(r12)
- add r0,r0,r11
- stw r0,0(r12)
- bdnz 1b
-
-/* Now adjust the fixups and the pointers to the fixups in case we need
- * to move ourselves again.
- */
-2: li r0,__fixup_entries@sectoff@l
- lwz r12,GOT(_FIXUP_TABLE_)
- cmpwi r0,0
- mtctr r0
- addi r12,r12,-4
- beqlr
-3: lwzu r10,4(r12)
- lwzux r0,r10,r11
- add r0,r0,r11
- stw r10,0(r12)
- stw r0,0(r10)
- bdnz 3b
- blr
-
-/* Set the MMU on and off: code is always mapped 1:1 and does not need MMU,
- * but it does not cost so much to map it also and it catches calls through
- * NULL function pointers.
- */
- .globl MMUon
- .type MMUon,@function
-MMUon: mfmsr r0
- ori r0,r0,MSR_IR|MSR_DR|MSR_IP
- mflr r11
- xori r0,r0,MSR_IP
- mtsrr0 r11
- mtsrr1 r0
- rfi
- .globl MMUoff
- .type MMUoff,@function
-MMUoff: mfmsr r0
- ori r0,r0,MSR_IR|MSR_DR|MSR_IP
- mflr r11
- xori r0,r0,MSR_IR|MSR_DR
- mtsrr0 r11
- mtsrr1 r0
- rfi
-
-/* Due to the PPC architecture (and according to the specifications), a
- * series of tlbie which goes through a whole 256 MB segment always flushes
- * the whole TLB. This is obviously overkill and slow, but who cares ?
- * It takes about 1 ms on a 200 MHz 603e and works even if residual data
- * get the number of TLB entries wrong.
- */
-flush_tlb:
- lis r11,0x1000
-1: addic. r11,r11,-0x1000
- tlbie r11
- bnl 1b
-/* tlbsync is not implemented on 601, so use sync which seems to be a superset
- * of tlbsync in all cases and do not bother with CPU dependant code
- */
- sync
- blr
-
- .globl codemove
-codemove:
- .type codemove,@function
-/* r3 dest, r4 src, r5 length in bytes, r6 cachelinesize */
- cmplw cr1,r3,r4
- addi r0,r5,3
- srwi. r0,r0,2
- beq cr1,4f /* In place copy is not necessary */
- beq 7f /* Protect against 0 count */
- mtctr r0
- bge cr1,2f
-
- la r8,-4(r4)
- la r7,-4(r3)
-1: lwzu r0,4(r8)
- stwu r0,4(r7)
- bdnz 1b
- b 4f
-
-2: slwi r0,r0,2
- add r8,r4,r0
- add r7,r3,r0
-3: lwzu r0,-4(r8)
- stwu r0,-4(r7)
- bdnz 3b
-
-/* Now flush the cache: note that we must start from a cache aligned
- * address. Otherwise we might miss one cache line.
- */
-4: cmpwi r6,0
- add r5,r3,r5
- beq 7f /* Always flush prefetch queue in any case */
- subi r0,r6,1
- andc r3,r3,r0
- mr r4,r3
-5: cmplw r4,r5
- dcbst 0,r4
- add r4,r4,r6
- blt 5b
- sync /* Wait for all dcbst to complete on bus */
- mr r4,r3
-6: cmplw r4,r5
- icbi 0,r4
- add r4,r4,r6
- blt 6b
-7: sync /* Wait for all icbi to complete on bus */
- isync
- blr
- .size codemove,.-codemove
-_size_codemove=.-codemove
-
- .section ".data" # .rodata
- .align 2
-#ifdef TEST_PPCBUG_CALLS
-banner_start:
- .ascii "This message was printed by PPCBug with MMU enabled"
-banner_end:
-#endif