]> git.sur5r.net Git - u-boot/blobdiff - cpu/ppc4xx/start.S
* Add support for PPChameleon Eval Board
[u-boot] / cpu / ppc4xx / start.S
index baaaba4fab15c2a7236d92797d22d39483c125e4..215a925b937b869865883a73e07f206df9a4e97f 100644 (file)
        GOT_ENTRY(_end_of_vectors)
        GOT_ENTRY(transfer_to_handler)
 
+       GOT_ENTRY(__init_end)
        GOT_ENTRY(_end)
-       GOT_ENTRY(.bss)
+       GOT_ENTRY(__bss_start)
        END_GOT
 
 /*
@@ -297,7 +298,7 @@ _start_440:
        mflr    r1
        mtspr   srr0,r1
        rfi
-#endif
+#endif /* CONFIG_440 */
 
 /*
  * r3 - 1st arg to board_init(): IMMP pointer
@@ -504,7 +505,7 @@ _start:
 #endif /* CONFIG_IOP480 */
 
 /*****************************************************************************/
-#if defined(CONFIG_405GP) || defined(CONFIG_405CR) || defined(CONFIG_405)
+#if defined(CONFIG_405GP) || defined(CONFIG_405CR) || defined(CONFIG_405) || defined(CONFIG_405EP)
        /*----------------------------------------------------------------------- */
        /* Clear and set up some registers. */
        /*----------------------------------------------------------------------- */
@@ -551,26 +552,37 @@ _start:
        bl      ext_bus_cntlr_init
 #endif
 
+#if defined(CONFIG_405EP)
+       /*----------------------------------------------------------------------- */
+       /* DMA Status, clear to come up clean */
+       /*----------------------------------------------------------------------- */
+       addis   r3,r0, 0xFFFF         /* Clear all existing DMA status */
+       ori     r3,r3, 0xFFFF
+       mtdcr   dmasr, r3
+
+       bl      ppc405ep_init         /* do ppc405ep specific init */
+#endif /* CONFIG_405EP */
+
 #if defined(CFG_OCM_DATA_ADDR) && defined(CFG_OCM_DATA_SIZE)
        /********************************************************************
         * Setup OCM - On Chip Memory
         *******************************************************************/
        /* Setup OCM */
-       lis     r0, 0x7FFF
-       ori     r0, r0, 0xFFFF
-       mfdcr   r3, ocmiscntl           /* get instr-side IRAM config */
-       mfdcr   r4, ocmdscntl   /* get data-side IRAM config */
-       and     r3, r3, r0      /* disable data-side IRAM */
-       and     r4, r4, r0      /* disable data-side IRAM */
-       mtdcr   ocmiscntl, r3   /* set instr-side IRAM config */
-       mtdcr   ocmdscntl, r4   /* set data-side IRAM config */
-       isync
+       lis     r0, 0x7FFF
+       ori     r0, r0, 0xFFFF
+       mfdcr   r3, ocmiscntl           /* get instr-side IRAM config */
+       mfdcr   r4, ocmdscntl   /* get data-side IRAM config */
+       and     r3, r3, r0      /* disable data-side IRAM */
+       and     r4, r4, r0      /* disable data-side IRAM */
+       mtdcr   ocmiscntl, r3   /* set instr-side IRAM config */
+       mtdcr   ocmdscntl, r4   /* set data-side IRAM config */
+       isync
 
        addis   r3, 0, CFG_OCM_DATA_ADDR@h /* OCM location */
        mtdcr   ocmdsarc, r3
        addis   r4, 0, 0xC000           /* OCM data area enabled */
        mtdcr   ocmdscntl, r4
-       isync
+       isync
 #endif
 
        /*----------------------------------------------------------------------- */
@@ -685,14 +697,16 @@ _start:
 
        GET_GOT                 /* initialize GOT access                        */
 
-               bl      cpu_init_f      /* run low-level CPU init code     (from Flash) */
+       bl      cpu_init_f      /* run low-level CPU init code     (from Flash) */
 
        /* NEVER RETURNS! */
        bl      board_init_f    /* run first part of init code (from Flash)     */
 
-#endif /* CONFIG_405GP || CONFIG_405CR */
+#endif /* CONFIG_405GP || CONFIG_405CR || CONFIG_405 || CONFIG_405EP */
+       /*----------------------------------------------------------------------- */
 
 
+/*****************************************************************************/
        .globl  _start_of_vectors
 _start_of_vectors:
 
@@ -703,7 +717,7 @@ _start_of_vectors:
 #endif
 
 /* Machine check */
-       STD_EXCEPTION(0x200, MachineCheck, MachineCheckException)
+       CRIT_EXCEPTION(0x200, MachineCheck, MachineCheckException)
 
 /* Data Storage exception. */
        STD_EXCEPTION(0x300, DataStorage, UnknownException)
@@ -756,61 +770,7 @@ ProgramCheck:
        STD_EXCEPTION(0x900, Decrementer, timer_interrupt)
        STD_EXCEPTION(0xa00, Trap_0a, UnknownException)
        STD_EXCEPTION(0xb00, Trap_0b, UnknownException)
-
-       . = 0xc00
-/*
- * r0 - SYSCALL number
- * r3-... arguments
- */
-SystemCall:
-       addis   r11,r0,0                /* get functions table addr */
-       ori     r11,r11,0               /* Note: this code is patched in trap_init */
-       addis   r12,r0,0                /* get number of functions */
-       ori     r12,r12,0
-
-       cmplw   0, r0, r12
-       bge     1f
-
-       rlwinm  r0,r0,2,0,31            /* fn_addr = fn_tbl[r0] */
-       add     r11,r11,r0
-       lwz     r11,0(r11)
-
-       li      r12,0xd00-4*3           /* save LR & SRRx */
-       mflr    r0
-       stw     r0,0(r12)
-       mfspr   r0,SRR0
-       stw     r0,4(r12)
-       mfspr   r0,SRR1
-       stw     r0,8(r12)
-
-       li      r12,0xc00+_back-SystemCall
-       mtlr    r12
-       mtspr   SRR0,r11
-
-1:     SYNC
-       rfi
-
-_back:
-
-       mfmsr   r11                     /* Disable interrupts */
-       li      r12,0
-       ori     r12,r12,MSR_EE
-       andc    r11,r11,r12
-       SYNC                            /* Some chip revs need this... */
-       mtmsr   r11
-       SYNC
-
-       li      r12,0xd00-4*3           /* restore regs */
-       lwz     r11,0(r12)
-       mtlr    r11
-       lwz     r11,4(r12)
-       mtspr   SRR0,r11
-       lwz     r11,8(r12)
-       mtspr   SRR1,r11
-
-       SYNC
-       rfi
-
+       STD_EXCEPTION(0xc00, SystemCall, UnknownException)
        STD_EXCEPTION(0xd00, SingleStep, UnknownException)
 
        STD_EXCEPTION(0xe00, Trap_0e, UnknownException)
@@ -1209,8 +1169,8 @@ relocate_code:
        mr      r3,  r5                         /* Destination Address  */
        lis     r4, CFG_MONITOR_BASE@h          /* Source      Address  */
        ori     r4, r4, CFG_MONITOR_BASE@l
-       lis     r5, CFG_MONITOR_LEN@h           /* Length in Bytes      */
-       ori     r5, r5, CFG_MONITOR_LEN@l
+       lwz     r5, GOT(__init_end)
+       sub     r5, r5, r4
        li      r6, CFG_CACHELINE_SIZE          /* Cache Line Size      */
 
        /*
@@ -1325,7 +1285,7 @@ clear_bss:
        /*
         * Now clear BSS segment
         */
-       lwz     r3,GOT(.bss)
+       lwz     r3,GOT(__bss_start)
        lwz     r4,GOT(_end)
 
        cmplw   0, r3, r4
@@ -1343,12 +1303,6 @@ clear_bss:
        mr      r4, r10         /* Destination Address          */
        bl      board_init_r
 
-       /* Problems accessing "end" in C, so do it here */
-       .globl  get_endaddr
-get_endaddr:
-       lwz     r3,GOT(_end)
-       blr
-
        /*
         * Copy exception vector code to low memory
         *
@@ -1360,7 +1314,7 @@ trap_init:
        lwz     r7, GOT(_start)
        lwz     r8, GOT(_end_of_vectors)
 
-       rlwinm  r9, r7, 0, 18, 31       /* _start & 0x3FFF      */
+       li      r9, 0x100               /* reset vector always at 0x100 */
 
        cmplw   0, r7, r8
        bgelr                           /* return if r7>=r8 - just in case */
@@ -1423,3 +1377,164 @@ trap_reloc:
        stw     r0, 4(r7)
 
        blr
+
+
+/**************************************************************************/
+/* PPC405EP specific stuff                                                */
+/**************************************************************************/
+#ifdef CONFIG_405EP
+ppc405ep_init:
+       /*
+       !-----------------------------------------------------------------------
+       ! Check FPGA for PCI internal/external arbitration
+       !   If board is set to internal arbitration, update cpc0_pci
+       !-----------------------------------------------------------------------
+       */
+       addi    r3,0,CPC0_PCI_HOST_CFG_EN
+#ifdef CONFIG_BUBINGA405EP
+       addis   r5,r0,FPGA_REG1@h      /* set offset for FPGA_REG1 */
+       ori     r5,r5,FPGA_REG1@l
+       lbz     r5,0x0(r5)              /* read to get PCI arb selection */
+       andi.   r6,r5,FPGA_REG1_PCI_INT_ARB  /* using internal arbiter ?*/
+       beq     ..pci_cfg_set             /* if not set, then bypass reg write*/
+#endif
+       ori     r3,r3,CPC0_PCI_ARBIT_EN
+..pci_cfg_set:
+       mtdcr   CPC0_PCI, r3             /* Enable internal arbiter*/
+
+       /*
+       !-----------------------------------------------------------------------
+       ! Check to see if chip is in bypass mode.
+       ! If so, write stored CPC0_PLLMR0 and CPC0_PLLMR1 values and perform a
+       ! CPU reset   Otherwise, skip this step and keep going.
+       ! Note:  Running BIOS in bypass mode is not supported since PLB speed
+       !        will not be fast enough for the SDRAM (min 66MHz)
+       !-----------------------------------------------------------------------
+       */
+       mfdcr   r5, CPC0_PLLMR1
+       rlwinm  r4,r5,1,0x1            /* get system clock source (SSCS) */
+       cmpi    cr0,0,r4,0x1
+
+       beq    pll_done                   /* if SSCS =b'1' then PLL has */
+                                         /* already been set */
+                                         /* and CPU has been reset */
+                                         /* so skip to next section */
+
+#ifdef CONFIG_BUBINGA405EP
+       /*
+       !-----------------------------------------------------------------------
+       ! Read NVRAM to get value to write in PLLMR.
+       ! If value has not been correctly saved, write default value
+       ! Default config values (assuming on-board 33MHz SYS_CLK) are above.
+       ! See CPU_DEFAULT_200 and CPU_DEFAULT_266 above.
+       !
+       ! WARNING:  This code assumes the first three words in the nvram_t
+       !           structure in openbios.h.  Changing the beginning of
+       !           the structure will break this code.
+       !
+       !-----------------------------------------------------------------------
+       */
+       addis   r3,0,NVRAM_BASE@h
+       addi    r3,r3,NVRAM_BASE@l
+
+       lwz     r4, 0(r3)
+       addis   r5,0,NVRVFY1@h
+       addi    r5,r5,NVRVFY1@l
+       cmp     cr0,0,r4,r5            /* Compare 1st NVRAM Magic number*/
+       bne     ..no_pllset
+       addi    r3,r3,4
+       lwz     r4, 0(r3)
+       addis   r5,0,NVRVFY2@h
+       addi    r5,r5,NVRVFY2@l
+       cmp     cr0,0,r4,r5            /* Compare 2 NVRAM Magic number */
+       bne     ..no_pllset
+       addi    r3,r3,8                 /* Skip over conf_size */
+       lwz     r4, 4(r3)               /* Load PLLMR1 value from NVRAM */
+       lwz     r3, 0(r3)               /* Load PLLMR0 value from NVRAM */
+       rlwinm  r5,r4,1,0x1             /* get system clock source (SSCS) */
+       cmpi     cr0,0,r5,1             /* See if PLL is locked */
+       beq     pll_write
+..no_pllset:
+#endif /* CONFIG_BUBINGA405EP */
+
+       addis   r3,0,PLLMR0_DEFAULT@h       /* PLLMR0 default value */
+       ori     r3,r3,PLLMR0_DEFAULT@l     /* */
+       addis   r4,0,PLLMR1_DEFAULT@h       /* PLLMR1 default value */
+       ori     r4,r4,PLLMR1_DEFAULT@l     /* */
+
+       b       pll_write                 /* Write the CPC0_PLLMR with new value */
+
+pll_done:
+       /*
+       !-----------------------------------------------------------------------
+       ! Clear Soft Reset Register
+       ! This is needed to enable PCI if not booting from serial EPROM
+       !-----------------------------------------------------------------------
+               */
+       addi    r3, 0, 0x0
+       mtdcr   CPC0_SRR, r3
+
+       addis    r3,0,0x0010
+       mtctr   r3
+pci_wait:
+       bdnz    pci_wait
+
+       blr                               /* return to main code */
+
+/*
+!-----------------------------------------------------------------------------
+! Function:     pll_write
+! Description:  Updates the value of the CPC0_PLLMR according to CMOS27E documentation
+!               That is:
+!                         1.  Pll is first disabled (de-activated by putting in bypass mode)
+!                         2.  PLL is reset
+!                         3.  Clock dividers are set while PLL is held in reset and bypassed
+!                         4.  PLL Reset is cleared
+!                         5.  Wait 100us for PLL to lock
+!                         6.  A core reset is performed
+! Input: r3 = Value to write to CPC0_PLLMR0
+! Input: r4 = Value to write to CPC0_PLLMR1
+! Output r3 = none
+!-----------------------------------------------------------------------------
+*/
+pll_write:
+       mfdcr  r5, CPC0_UCR
+       andis. r5,r5,0xFFFF
+       ori    r5,r5,0x0101              /* Stop the UART clocks */
+       mtdcr  CPC0_UCR,r5               /* Before changing PLL */
+
+       mfdcr  r5, CPC0_PLLMR1
+       rlwinm r5,r5,0,0x7FFFFFFF        /* Disable PLL */
+       mtdcr   CPC0_PLLMR1,r5
+       oris   r5,r5,0x4000              /* Set PLL Reset */
+       mtdcr   CPC0_PLLMR1,r5
+
+       mtdcr   CPC0_PLLMR0,r3           /* Set clock dividers */
+       rlwinm r5,r4,0,0x3FFFFFFF        /* Reset & Bypass new PLL dividers */
+       oris   r5,r5,0x4000              /* Set PLL Reset */
+       mtdcr   CPC0_PLLMR1,r5           /* Set clock dividers */
+       rlwinm r5,r5,0,0xBFFFFFFF        /* Clear PLL Reset */
+       mtdcr   CPC0_PLLMR1,r5
+
+               /*
+       ! Wait min of 100us for PLL to lock.
+       ! See CMOS 27E databook for more info.
+       ! At 200MHz, that means waiting 20,000 instructions
+                */
+       addi    r3,0,20000              /* 2000 = 0x4e20 */
+       mtctr   r3
+pll_wait:
+       bdnz    pll_wait
+
+       oris   r5,r5,0x8000             /* Enable PLL */
+       mtdcr   CPC0_PLLMR1,r5          /* Engage */
+
+       /*
+        * Reset CPU to guarantee timings are OK
+        * Not sure if this is needed...
+        */
+       addis r3,0,0x1000
+       mtspr dbcr0,r3               /* This will cause a CPU core reset, and */
+                                    /* execution will continue from the poweron */
+                                    /* vector of 0xfffffffc */
+#endif /* CONFIG_405EP */