Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/arch/mips/cavium-octeon/executive/cvmx-boot-vector.c
26481 views
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
16
reset_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
53
wait_loop:
54
wait
55
nop
56
57
b wait_loop
58
nop
59
60
nop
61
nop
62
------------------------------------
63
64
0000000000000000 <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
98
0000000000000058 <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
112
static 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
134
static 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 available */
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
*/
159
struct 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
}
167
EXPORT_SYMBOL(cvmx_boot_vector_get);
168
169