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