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
 102        # This is the variable where the next core to boot os stored
 103        PTR_LA  t0, octeon_processor_boot
 104octeon_spin_wait_boot:
 105        # Get the core id of the next to be booted
 106        LONG_L  t1, (t0)
 107        # Keep looping if it isn't me
 108        bne t1, v0, octeon_spin_wait_boot
 109        nop
 110        # Get my GP from the global variable
 111        PTR_LA  t0, octeon_processor_gp
 112        LONG_L  gp, (t0)
 113        # Get my SP from the global variable
 114        PTR_LA  t0, octeon_processor_sp
 115        LONG_L  sp, (t0)
 116        # Set the SP global variable to zero so the master knows we've started
 117        LONG_S  zero, (t0)
 118#ifdef __OCTEON__
 119        syncw
 120        syncw
 121#else
 122        sync
 123#endif
 124        # Jump to the normal Linux SMP entry point
 125        j   smp_bootstrap
 126        nop
 127#else /* CONFIG_SMP */
 128
 129        #
 130        # Someone tried to boot SMP with a non SMP kernel. All extra cores
 131        # will halt here.
 132        #
 133octeon_wait_forever:
 134        wait
 135        b   octeon_wait_forever
 136        nop
 137
 138#endif /* CONFIG_SMP */
 139octeon_main_processor:
 140        .set pop
 141.endm
 142
 143/*
 144 * Do SMP slave processor setup necessary before we can safely execute C code.
 145 */
 146        .macro  smp_slave_setup
 147        .endm
 148
 149#endif /* __ASM_MACH_CAVIUM_OCTEON_KERNEL_ENTRY_H */
 150