linux/arch/mips/include/asm/mach-cavium-octeon/kernel-entry-init.h
<<
>>
Prefs
   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
  634:      # core-16057 work around
  64        or      v0, v0, 0x2000          # Set IPREF bit.
  65
  665:      # 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
  761:      dsubu   v0, 8
  77        sd      $0, -32768(v0)
  78        bnez    v0, 1b
  792:
  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
  881:
  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
 102octeon_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
 1111:
 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        #
 144octeon_wait_forever:
 145        wait
 146        b   octeon_wait_forever
 147        nop
 148
 149#endif /* CONFIG_SMP */
 150octeon_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 */
 161