root/arch/mips/include/asm/mach-cavium-octeon/kernel-entry-init.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


   1 /*
   2  * This file is subject to the terms and conditions of the GNU General Public
   3  * License.  See the file "COPYING" in the main directory of this archive
   4  * for more details.
   5  *
   6  * Copyright (C) 2005-2008 Cavium Networks, Inc
   7  */
   8 #ifndef __ASM_MACH_CAVIUM_OCTEON_KERNEL_ENTRY_H
   9 #define __ASM_MACH_CAVIUM_OCTEON_KERNEL_ENTRY_H
  10 
  11 #define CP0_CVMCTL_REG $9, 7
  12 #define CP0_CVMMEMCTL_REG $11,7
  13 #define CP0_PRID_REG $15, 0
  14 #define CP0_DCACHE_ERR_REG $27, 1
  15 #define CP0_PRID_OCTEON_PASS1 0x000d0000
  16 #define CP0_PRID_OCTEON_CN30XX 0x000d0200
  17 
  18 .macro  kernel_entry_setup
  19         # Registers set by bootloader:
  20         # (only 32 bits set by bootloader, all addresses are physical
  21         # addresses, and need to have the appropriate memory region set
  22         # by the kernel
  23         # a0 = argc
  24         # a1 = argv (kseg0 compat addr)
  25         # a2 = 1 if init core, zero otherwise
  26         # a3 = address of boot descriptor block
  27         .set push
  28         .set arch=octeon
  29         # Read the cavium mem control register
  30         dmfc0   v0, CP0_CVMMEMCTL_REG
  31         # Clear the lower 6 bits, the CVMSEG size
  32         dins    v0, $0, 0, 6
  33         ori     v0, CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE
  34         dmtc0   v0, CP0_CVMMEMCTL_REG   # Write the cavium mem control register
  35         dmfc0   v0, CP0_CVMCTL_REG      # Read the cavium control register
  36         # Disable unaligned load/store support but leave HW fixup enabled
  37         # Needed for octeon specific memcpy
  38         or  v0, v0, 0x5001
  39         xor v0, v0, 0x1001
  40         # First clear off CvmCtl[IPPCI] bit and move the performance
  41         # counters interrupt to IRQ 6
  42         dli     v1, ~(7 << 7)
  43         and     v0, v0, v1
  44         ori     v0, v0, (6 << 7)
  45 
  46         mfc0    v1, CP0_PRID_REG
  47         and     t1, v1, 0xfff8
  48         xor     t1, t1, 0x9000          # 63-P1
  49         beqz    t1, 4f
  50         and     t1, v1, 0xfff8
  51         xor     t1, t1, 0x9008          # 63-P2
  52         beqz    t1, 4f
  53         and     t1, v1, 0xfff8
  54         xor     t1, t1, 0x9100          # 68-P1
  55         beqz    t1, 4f
  56         and     t1, v1, 0xff00
  57         xor     t1, t1, 0x9200          # 66-PX
  58         bnez    t1, 5f                  # Skip WAR for others.
  59         and     t1, v1, 0x00ff
  60         slti    t1, t1, 2               # 66-P1.2 and later good.
  61         beqz    t1, 5f
  62 
  63 4:      # core-16057 work around
  64         or      v0, v0, 0x2000          # Set IPREF bit.
  65 
  66 5:      # No core-16057 work around
  67         # Write the cavium control register
  68         dmtc0   v0, CP0_CVMCTL_REG
  69         sync
  70         # Flush dcache after config change
  71         cache   9, 0($0)
  72         # Zero all of CVMSEG to make sure parity is correct
  73         dli     v0, CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE
  74         dsll    v0, 7
  75         beqz    v0, 2f
  76 1:      dsubu   v0, 8
  77         sd      $0, -32768(v0)
  78         bnez    v0, 1b
  79 2:
  80         mfc0    v0, CP0_PRID_REG
  81         bbit0   v0, 15, 1f
  82         # OCTEON II or better have bit 15 set.  Clear the error bits.
  83         and     t1, v0, 0xff00
  84         dli     v0, 0x9500
  85         bge     t1, v0, 1f  # OCTEON III has no DCACHE_ERR_REG COP0
  86         dli     v0, 0x27
  87         dmtc0   v0, CP0_DCACHE_ERR_REG
  88 1:
  89         # Get my core id
  90         rdhwr   v0, $0
  91         # Jump the master to kernel_entry
  92         bne     a2, zero, octeon_main_processor
  93         nop
  94 
  95 #ifdef CONFIG_SMP
  96 
  97         #
  98         # All cores other than the master need to wait here for SMP bootstrap
  99         # to begin
 100         #
 101 
 102 octeon_spin_wait_boot:
 103 #ifdef CONFIG_RELOCATABLE
 104         PTR_LA  t0, octeon_processor_relocated_kernel_entry
 105         LONG_L  t0, (t0)
 106         beq     zero, t0, 1f
 107         nop
 108 
 109         jr      t0
 110         nop
 111 1:
 112 #endif /* CONFIG_RELOCATABLE */
 113 
 114         # This is the variable where the next core to boot is stored
 115         PTR_LA  t0, octeon_processor_boot
 116         # Get the core id of the next to be booted
 117         LONG_L  t1, (t0)
 118         # Keep looping if it isn't me
 119         bne t1, v0, octeon_spin_wait_boot
 120         nop
 121         # Get my GP from the global variable
 122         PTR_LA  t0, octeon_processor_gp
 123         LONG_L  gp, (t0)
 124         # Get my SP from the global variable
 125         PTR_LA  t0, octeon_processor_sp
 126         LONG_L  sp, (t0)
 127         # Set the SP global variable to zero so the master knows we've started
 128         LONG_S  zero, (t0)
 129 #ifdef __OCTEON__
 130         syncw
 131         syncw
 132 #else
 133         sync
 134 #endif
 135         # Jump to the normal Linux SMP entry point
 136         j   smp_bootstrap
 137         nop
 138 #else /* CONFIG_SMP */
 139 
 140         #
 141         # Someone tried to boot SMP with a non SMP kernel. All extra cores
 142         # will halt here.
 143         #
 144 octeon_wait_forever:
 145         wait
 146         b   octeon_wait_forever
 147         nop
 148 
 149 #endif /* CONFIG_SMP */
 150 octeon_main_processor:
 151         .set pop
 152 .endm
 153 
 154 /*
 155  * Do SMP slave processor setup necessary before we can safely execute C code.
 156  */
 157         .macro  smp_slave_setup
 158         .endm
 159 
 160 #endif /* __ASM_MACH_CAVIUM_OCTEON_KERNEL_ENTRY_H */

/* [<][>][^][v][top][bottom][index][help] */