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