Merge tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
[linux-2.6-microblaze.git] / arch / mips / cavium-octeon / executive / cvmx-boot-vector.c
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 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  */
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);