linux/arch/mips/cavium-octeon/executive/cvmx-boot-vector.c
<<
>>
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) 2004-2017 Cavium, Inc.
   7 */
   8
   9
  10/*
  11  We install this program at the bootvector:
  12------------------------------------
  13        .set noreorder
  14        .set nomacro
  15        .set noat
  16reset_vector:
  17        dmtc0   $k0, $31, 0     # Save $k0 to DESAVE
  18        dmtc0   $k1, $31, 3     # Save $k1 to KScratch2
  19
  20        mfc0    $k0, $12, 0     # Status
  21        mfc0    $k1, $15, 1     # Ebase
  22
  23        ori     $k0, 0x84       # Enable 64-bit addressing, set
  24                                # ERL (should already be set)
  25        andi    $k1, 0x3ff      # mask out core ID
  26
  27        mtc0    $k0, $12, 0     # Status
  28        sll     $k1, 5
  29
  30        lui     $k0, 0xbfc0
  31        cache   17, 0($0)       # Core-14345, clear L1 Dcache virtual
  32                                # tags if the core hit an NMI
  33
  34        ld      $k0, 0x78($k0)  # k0 <- (bfc00078) pointer to the reset vector
  35        synci   0($0)           # Invalidate ICache to get coherent
  36                                # view of target code.
  37
  38        daddu   $k0, $k0, $k1
  39        nop
  40
  41        ld      $k0, 0($k0)     # k0 <- core specific target address
  42        dmfc0   $k1, $31, 3     # Restore $k1 from KScratch2
  43
  44        beqz    $k0, wait_loop  # Spin in wait loop
  45        nop
  46
  47        jr      $k0
  48        nop
  49
  50        nop                     # NOPs needed here to fill delay slots
  51        nop                     # on endian reversal of previous instructions
  52
  53wait_loop:
  54        wait
  55        nop
  56
  57        b       wait_loop
  58        nop
  59
  60        nop
  61        nop
  62------------------------------------
  63
  640000000000000000 <reset_vector>:
  65   0:   40baf800        dmtc0   k0,c0_desave
  66   4:   40bbf803        dmtc0   k1,c0_kscratch2
  67
  68   8:   401a6000        mfc0    k0,c0_status
  69   c:   401b7801        mfc0    k1,c0_ebase
  70
  71  10:   375a0084        ori     k0,k0,0x84
  72  14:   337b03ff        andi    k1,k1,0x3ff
  73
  74  18:   409a6000        mtc0    k0,c0_status
  75  1c:   001bd940        sll     k1,k1,0x5
  76
  77  20:   3c1abfc0        lui     k0,0xbfc0
  78  24:   bc110000        cache   0x11,0(zero)
  79
  80  28:   df5a0078        ld      k0,120(k0)
  81  2c:   041f0000        synci   0(zero)
  82
  83  30:   035bd02d        daddu   k0,k0,k1
  84  34:   00000000        nop
  85
  86  38:   df5a0000        ld      k0,0(k0)
  87  3c:   403bf803        dmfc0   k1,c0_kscratch2
  88
  89  40:   13400005        beqz    k0,58 <wait_loop>
  90  44:   00000000        nop
  91
  92  48:   03400008        jr      k0
  93  4c:   00000000        nop
  94
  95  50:   00000000        nop
  96  54:   00000000        nop
  97
  980000000000000058 <wait_loop>:
  99  58:   42000020        wait
 100  5c:   00000000        nop
 101
 102  60:   1000fffd        b       58 <wait_loop>
 103  64:   00000000        nop
 104
 105  68:   00000000        nop
 106  6c:   00000000        nop
 107
 108 */
 109
 110#include <asm/octeon/cvmx-boot-vector.h>
 111
 112static unsigned long long _cvmx_bootvector_data[16] = {
 113        0x40baf80040bbf803ull,  /* patch low order 8-bits if no KScratch*/
 114        0x401a6000401b7801ull,
 115        0x375a0084337b03ffull,
 116        0x409a6000001bd940ull,
 117        0x3c1abfc0bc110000ull,
 118        0xdf5a0078041f0000ull,
 119        0x035bd02d00000000ull,
 120        0xdf5a0000403bf803ull,  /* patch low order 8-bits if no KScratch*/
 121        0x1340000500000000ull,
 122        0x0340000800000000ull,
 123        0x0000000000000000ull,
 124        0x4200002000000000ull,
 125        0x1000fffd00000000ull,
 126        0x0000000000000000ull,
 127        OCTEON_BOOT_MOVEABLE_MAGIC1,
 128        0 /* To be filled in with address of vector block*/
 129};
 130
 131/* 2^10 CPUs */
 132#define VECTOR_TABLE_SIZE (1024 * sizeof(struct cvmx_boot_vector_element))
 133
 134static void cvmx_boot_vector_init(void *mem)
 135{
 136        uint64_t kseg0_mem;
 137        int i;
 138
 139        memset(mem, 0, VECTOR_TABLE_SIZE);
 140        kseg0_mem = cvmx_ptr_to_phys(mem) | 0x8000000000000000ull;
 141
 142        for (i = 0; i < 15; i++) {
 143                uint64_t v = _cvmx_bootvector_data[i];
 144
 145                if (OCTEON_IS_OCTEON1PLUS() && (i == 0 || i == 7))
 146                        v &= 0xffffffff00000000ull; /* KScratch not availble. */
 147                cvmx_write_csr(CVMX_MIO_BOOT_LOC_ADR, i * 8);
 148                cvmx_write_csr(CVMX_MIO_BOOT_LOC_DAT, v);
 149        }
 150        cvmx_write_csr(CVMX_MIO_BOOT_LOC_ADR, 15 * 8);
 151        cvmx_write_csr(CVMX_MIO_BOOT_LOC_DAT, kseg0_mem);
 152        cvmx_write_csr(CVMX_MIO_BOOT_LOC_CFGX(0), 0x81fc0000);
 153}
 154
 155/**
 156 * Get a pointer to the per-core table of reset vector pointers
 157 *
 158 */
 159struct cvmx_boot_vector_element *cvmx_boot_vector_get(void)
 160{
 161        struct cvmx_boot_vector_element *ret;
 162
 163        ret = cvmx_bootmem_alloc_named_range_once(VECTOR_TABLE_SIZE, 0,
 164                (1ull << 32) - 1, 8, "__boot_vector1__", cvmx_boot_vector_init);
 165        return ret;
 166}
 167EXPORT_SYMBOL(cvmx_boot_vector_get);
 168