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