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
  12#define CP0_CYCLE_COUNTER $9, 6
  13#define CP0_CVMCTL_REG $9, 7
  14#define CP0_CVMMEMCTL_REG $11,7
  15#define CP0_PRID_REG $15, 0
  16#define CP0_PRID_OCTEON_PASS1 0x000d0000
  17#define CP0_PRID_OCTEON_CN30XX 0x000d0200
  18
  19.macro  kernel_entry_setup
  20        # Registers set by bootloader:
  21        # (only 32 bits set by bootloader, all addresses are physical
  22        # addresses, and need to have the appropriate memory region set
  23        # by the kernel
  24        # a0 = argc
  25        # a1 = argv (kseg0 compat addr)
  26        # a2 = 1 if init core, zero otherwise
  27        # a3 = address of boot descriptor block
  28        .set push
  29        .set arch=octeon
  30        # Read the cavium mem control register
  31        dmfc0   v0, CP0_CVMMEMCTL_REG
  32        # Clear the lower 6 bits, the CVMSEG size
  33        dins    v0, $0, 0, 6
  34        ori     v0, CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE
  35        dmtc0   v0, CP0_CVMMEMCTL_REG   # Write the cavium mem control register
  36        dmfc0   v0, CP0_CVMCTL_REG      # Read the cavium control register
  37#ifdef CONFIG_CAVIUM_OCTEON_HW_FIX_UNALIGNED
  38        # Disable unaligned load/store support but leave HW fixup enabled
  39        or  v0, v0, 0x5001
  40        xor v0, v0, 0x1001
  41#else
  42        # Disable unaligned load/store and HW fixup support
  43        or  v0, v0, 0x5001
  44        xor v0, v0, 0x5001
  45#endif
  46        # Read the processor ID register
  47        mfc0 v1, CP0_PRID_REG
  48        # Disable instruction prefetching (Octeon Pass1 errata)
  49        or  v0, v0, 0x2000
  50        # Skip reenable of prefetching for Octeon Pass1
  51        beq v1, CP0_PRID_OCTEON_PASS1, skip
  52        nop
  53        # Reenable instruction prefetching, not on Pass1
  54        xor v0, v0, 0x2000
  55        # Strip off pass number off of processor id
  56        srl v1, 8
  57        sll v1, 8
  58        # CN30XX needs some extra stuff turned off for better performance
  59        bne v1, CP0_PRID_OCTEON_CN30XX, skip
  60        nop
  61        # CN30XX Use random Icache replacement
  62        or  v0, v0, 0x400
  63        # CN30XX Disable instruction prefetching
  64        or  v0, v0, 0x2000
  65skip:
  66        # First clear off CvmCtl[IPPCI] bit and move the performance
  67        # counters interrupt to IRQ 6
  68        li      v1, ~(7 << 7)
  69        and     v0, v0, v1
  70        ori     v0, v0, (6 << 7)
  71        # Write the cavium control register
  72        dmtc0   v0, CP0_CVMCTL_REG
  73        sync
  74        # Flush dcache after config change
  75        cache   9, 0($0)
  76        # Get my core id
  77        rdhwr   v0, $0
  78        # Jump the master to kernel_entry
  79        bne     a2, zero, octeon_main_processor
  80        nop
  81
  82#ifdef CONFIG_SMP
  83
  84        #
  85        # All cores other than the master need to wait here for SMP bootstrap
  86        # to begin
  87        #
  88
  89        # This is the variable where the next core to boot os stored
  90        PTR_LA  t0, octeon_processor_boot
  91octeon_spin_wait_boot:
  92        # Get the core id of the next to be booted
  93        LONG_L  t1, (t0)
  94        # Keep looping if it isn't me
  95        bne t1, v0, octeon_spin_wait_boot
  96        nop
  97        # Get my GP from the global variable
  98        PTR_LA  t0, octeon_processor_gp
  99        LONG_L  gp, (t0)
 100        # Get my SP from the global variable
 101        PTR_LA  t0, octeon_processor_sp
 102        LONG_L  sp, (t0)
 103        # Set the SP global variable to zero so the master knows we've started
 104        LONG_S  zero, (t0)
 105#ifdef __OCTEON__
 106        syncw
 107        syncw
 108#else
 109        sync
 110#endif
 111        # Jump to the normal Linux SMP entry point
 112        j   smp_bootstrap
 113        nop
 114#else /* CONFIG_SMP */
 115
 116        #
 117        # Someone tried to boot SMP with a non SMP kernel. All extra cores
 118        # will halt here.
 119        #
 120octeon_wait_forever:
 121        wait
 122        b   octeon_wait_forever
 123        nop
 124
 125#endif /* CONFIG_SMP */
 126octeon_main_processor:
 127        .set pop
 128.endm
 129
 130/*
 131 * Do SMP slave processor setup necessary before we can savely execute C code.
 132 */
 133        .macro  smp_slave_setup
 134        .endm
 135
 136#endif /* __ASM_MACH_CAVIUM_OCTEON_KERNEL_ENTRY_H */
 137