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);
|