18c2ecf20Sopenharmony_ci/* 28c2ecf20Sopenharmony_ci * This file is subject to the terms and conditions of the GNU General Public 38c2ecf20Sopenharmony_ci * License. See the file "COPYING" in the main directory of this archive 48c2ecf20Sopenharmony_ci * for more details. 58c2ecf20Sopenharmony_ci * 68c2ecf20Sopenharmony_ci * Copyright (C) 2004-2017 Cavium, Inc. 78c2ecf20Sopenharmony_ci */ 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci/* 118c2ecf20Sopenharmony_ci We install this program at the bootvector: 128c2ecf20Sopenharmony_ci------------------------------------ 138c2ecf20Sopenharmony_ci .set noreorder 148c2ecf20Sopenharmony_ci .set nomacro 158c2ecf20Sopenharmony_ci .set noat 168c2ecf20Sopenharmony_cireset_vector: 178c2ecf20Sopenharmony_ci dmtc0 $k0, $31, 0 # Save $k0 to DESAVE 188c2ecf20Sopenharmony_ci dmtc0 $k1, $31, 3 # Save $k1 to KScratch2 198c2ecf20Sopenharmony_ci 208c2ecf20Sopenharmony_ci mfc0 $k0, $12, 0 # Status 218c2ecf20Sopenharmony_ci mfc0 $k1, $15, 1 # Ebase 228c2ecf20Sopenharmony_ci 238c2ecf20Sopenharmony_ci ori $k0, 0x84 # Enable 64-bit addressing, set 248c2ecf20Sopenharmony_ci # ERL (should already be set) 258c2ecf20Sopenharmony_ci andi $k1, 0x3ff # mask out core ID 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_ci mtc0 $k0, $12, 0 # Status 288c2ecf20Sopenharmony_ci sll $k1, 5 298c2ecf20Sopenharmony_ci 308c2ecf20Sopenharmony_ci lui $k0, 0xbfc0 318c2ecf20Sopenharmony_ci cache 17, 0($0) # Core-14345, clear L1 Dcache virtual 328c2ecf20Sopenharmony_ci # tags if the core hit an NMI 338c2ecf20Sopenharmony_ci 348c2ecf20Sopenharmony_ci ld $k0, 0x78($k0) # k0 <- (bfc00078) pointer to the reset vector 358c2ecf20Sopenharmony_ci synci 0($0) # Invalidate ICache to get coherent 368c2ecf20Sopenharmony_ci # view of target code. 378c2ecf20Sopenharmony_ci 388c2ecf20Sopenharmony_ci daddu $k0, $k0, $k1 398c2ecf20Sopenharmony_ci nop 408c2ecf20Sopenharmony_ci 418c2ecf20Sopenharmony_ci ld $k0, 0($k0) # k0 <- core specific target address 428c2ecf20Sopenharmony_ci dmfc0 $k1, $31, 3 # Restore $k1 from KScratch2 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_ci beqz $k0, wait_loop # Spin in wait loop 458c2ecf20Sopenharmony_ci nop 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_ci jr $k0 488c2ecf20Sopenharmony_ci nop 498c2ecf20Sopenharmony_ci 508c2ecf20Sopenharmony_ci nop # NOPs needed here to fill delay slots 518c2ecf20Sopenharmony_ci nop # on endian reversal of previous instructions 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_ciwait_loop: 548c2ecf20Sopenharmony_ci wait 558c2ecf20Sopenharmony_ci nop 568c2ecf20Sopenharmony_ci 578c2ecf20Sopenharmony_ci b wait_loop 588c2ecf20Sopenharmony_ci nop 598c2ecf20Sopenharmony_ci 608c2ecf20Sopenharmony_ci nop 618c2ecf20Sopenharmony_ci nop 628c2ecf20Sopenharmony_ci------------------------------------ 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_ci0000000000000000 <reset_vector>: 658c2ecf20Sopenharmony_ci 0: 40baf800 dmtc0 k0,c0_desave 668c2ecf20Sopenharmony_ci 4: 40bbf803 dmtc0 k1,c0_kscratch2 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_ci 8: 401a6000 mfc0 k0,c0_status 698c2ecf20Sopenharmony_ci c: 401b7801 mfc0 k1,c0_ebase 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_ci 10: 375a0084 ori k0,k0,0x84 728c2ecf20Sopenharmony_ci 14: 337b03ff andi k1,k1,0x3ff 738c2ecf20Sopenharmony_ci 748c2ecf20Sopenharmony_ci 18: 409a6000 mtc0 k0,c0_status 758c2ecf20Sopenharmony_ci 1c: 001bd940 sll k1,k1,0x5 768c2ecf20Sopenharmony_ci 778c2ecf20Sopenharmony_ci 20: 3c1abfc0 lui k0,0xbfc0 788c2ecf20Sopenharmony_ci 24: bc110000 cache 0x11,0(zero) 798c2ecf20Sopenharmony_ci 808c2ecf20Sopenharmony_ci 28: df5a0078 ld k0,120(k0) 818c2ecf20Sopenharmony_ci 2c: 041f0000 synci 0(zero) 828c2ecf20Sopenharmony_ci 838c2ecf20Sopenharmony_ci 30: 035bd02d daddu k0,k0,k1 848c2ecf20Sopenharmony_ci 34: 00000000 nop 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_ci 38: df5a0000 ld k0,0(k0) 878c2ecf20Sopenharmony_ci 3c: 403bf803 dmfc0 k1,c0_kscratch2 888c2ecf20Sopenharmony_ci 898c2ecf20Sopenharmony_ci 40: 13400005 beqz k0,58 <wait_loop> 908c2ecf20Sopenharmony_ci 44: 00000000 nop 918c2ecf20Sopenharmony_ci 928c2ecf20Sopenharmony_ci 48: 03400008 jr k0 938c2ecf20Sopenharmony_ci 4c: 00000000 nop 948c2ecf20Sopenharmony_ci 958c2ecf20Sopenharmony_ci 50: 00000000 nop 968c2ecf20Sopenharmony_ci 54: 00000000 nop 978c2ecf20Sopenharmony_ci 988c2ecf20Sopenharmony_ci0000000000000058 <wait_loop>: 998c2ecf20Sopenharmony_ci 58: 42000020 wait 1008c2ecf20Sopenharmony_ci 5c: 00000000 nop 1018c2ecf20Sopenharmony_ci 1028c2ecf20Sopenharmony_ci 60: 1000fffd b 58 <wait_loop> 1038c2ecf20Sopenharmony_ci 64: 00000000 nop 1048c2ecf20Sopenharmony_ci 1058c2ecf20Sopenharmony_ci 68: 00000000 nop 1068c2ecf20Sopenharmony_ci 6c: 00000000 nop 1078c2ecf20Sopenharmony_ci 1088c2ecf20Sopenharmony_ci */ 1098c2ecf20Sopenharmony_ci 1108c2ecf20Sopenharmony_ci#include <asm/octeon/cvmx-boot-vector.h> 1118c2ecf20Sopenharmony_ci 1128c2ecf20Sopenharmony_cistatic unsigned long long _cvmx_bootvector_data[16] = { 1138c2ecf20Sopenharmony_ci 0x40baf80040bbf803ull, /* patch low order 8-bits if no KScratch*/ 1148c2ecf20Sopenharmony_ci 0x401a6000401b7801ull, 1158c2ecf20Sopenharmony_ci 0x375a0084337b03ffull, 1168c2ecf20Sopenharmony_ci 0x409a6000001bd940ull, 1178c2ecf20Sopenharmony_ci 0x3c1abfc0bc110000ull, 1188c2ecf20Sopenharmony_ci 0xdf5a0078041f0000ull, 1198c2ecf20Sopenharmony_ci 0x035bd02d00000000ull, 1208c2ecf20Sopenharmony_ci 0xdf5a0000403bf803ull, /* patch low order 8-bits if no KScratch*/ 1218c2ecf20Sopenharmony_ci 0x1340000500000000ull, 1228c2ecf20Sopenharmony_ci 0x0340000800000000ull, 1238c2ecf20Sopenharmony_ci 0x0000000000000000ull, 1248c2ecf20Sopenharmony_ci 0x4200002000000000ull, 1258c2ecf20Sopenharmony_ci 0x1000fffd00000000ull, 1268c2ecf20Sopenharmony_ci 0x0000000000000000ull, 1278c2ecf20Sopenharmony_ci OCTEON_BOOT_MOVEABLE_MAGIC1, 1288c2ecf20Sopenharmony_ci 0 /* To be filled in with address of vector block*/ 1298c2ecf20Sopenharmony_ci}; 1308c2ecf20Sopenharmony_ci 1318c2ecf20Sopenharmony_ci/* 2^10 CPUs */ 1328c2ecf20Sopenharmony_ci#define VECTOR_TABLE_SIZE (1024 * sizeof(struct cvmx_boot_vector_element)) 1338c2ecf20Sopenharmony_ci 1348c2ecf20Sopenharmony_cistatic void cvmx_boot_vector_init(void *mem) 1358c2ecf20Sopenharmony_ci{ 1368c2ecf20Sopenharmony_ci uint64_t kseg0_mem; 1378c2ecf20Sopenharmony_ci int i; 1388c2ecf20Sopenharmony_ci 1398c2ecf20Sopenharmony_ci memset(mem, 0, VECTOR_TABLE_SIZE); 1408c2ecf20Sopenharmony_ci kseg0_mem = cvmx_ptr_to_phys(mem) | 0x8000000000000000ull; 1418c2ecf20Sopenharmony_ci 1428c2ecf20Sopenharmony_ci for (i = 0; i < 15; i++) { 1438c2ecf20Sopenharmony_ci uint64_t v = _cvmx_bootvector_data[i]; 1448c2ecf20Sopenharmony_ci 1458c2ecf20Sopenharmony_ci if (OCTEON_IS_OCTEON1PLUS() && (i == 0 || i == 7)) 1468c2ecf20Sopenharmony_ci v &= 0xffffffff00000000ull; /* KScratch not availble. */ 1478c2ecf20Sopenharmony_ci cvmx_write_csr(CVMX_MIO_BOOT_LOC_ADR, i * 8); 1488c2ecf20Sopenharmony_ci cvmx_write_csr(CVMX_MIO_BOOT_LOC_DAT, v); 1498c2ecf20Sopenharmony_ci } 1508c2ecf20Sopenharmony_ci cvmx_write_csr(CVMX_MIO_BOOT_LOC_ADR, 15 * 8); 1518c2ecf20Sopenharmony_ci cvmx_write_csr(CVMX_MIO_BOOT_LOC_DAT, kseg0_mem); 1528c2ecf20Sopenharmony_ci cvmx_write_csr(CVMX_MIO_BOOT_LOC_CFGX(0), 0x81fc0000); 1538c2ecf20Sopenharmony_ci} 1548c2ecf20Sopenharmony_ci 1558c2ecf20Sopenharmony_ci/** 1568c2ecf20Sopenharmony_ci * Get a pointer to the per-core table of reset vector pointers 1578c2ecf20Sopenharmony_ci * 1588c2ecf20Sopenharmony_ci */ 1598c2ecf20Sopenharmony_cistruct cvmx_boot_vector_element *cvmx_boot_vector_get(void) 1608c2ecf20Sopenharmony_ci{ 1618c2ecf20Sopenharmony_ci struct cvmx_boot_vector_element *ret; 1628c2ecf20Sopenharmony_ci 1638c2ecf20Sopenharmony_ci ret = cvmx_bootmem_alloc_named_range_once(VECTOR_TABLE_SIZE, 0, 1648c2ecf20Sopenharmony_ci (1ull << 32) - 1, 8, "__boot_vector1__", cvmx_boot_vector_init); 1658c2ecf20Sopenharmony_ci return ret; 1668c2ecf20Sopenharmony_ci} 1678c2ecf20Sopenharmony_ciEXPORT_SYMBOL(cvmx_boot_vector_get); 168