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