/*
 * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 *
 * Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * Neither the name of ARM nor the names of its contributors may be used
 * to endorse or promote products derived from this software without specific
 * prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include <arch_helpers.h>
#include <assert.h>
#include <bl_common.h>
#include <context.h>
#include <context_mgmt.h>
#include <console.h>
#include <debug.h>
#include <delay_timer.h>
#include <fiq_smp_call.h>
#include <log.h>
#include <mt_common.h>
#include <plat_private.h>
#include <platform.h>
#include <runtime_svc.h>
#include <spinlock.h>
#include <stdio.h>
#include <xlat_tables.h>

#if 0
/* For check mode test case */
#define MTK_AEE_TC_CHECK_MODE
#endif

#if 0
/* For early exception, coming cpu dump its stack */
#define MTK_AEE_TC_KWDT_NOT_READY
#endif

#define DCACHE_IS_ENABLE (read_sctlr_el3() & SCTLR_C_BIT)
extern atf_arg_t gteearg;
extern uint64_t wdt_kernel_cb_addr;
extern uint64_t get_kernel_k32_64(void);

spinlock_t aee_wdt_dump_lock;
extern atf_log_ctrl_t *p_atf_log_ctrl;
void aee_flush_log_cache (void)
{
	flush_dcache_range((unsigned long)p_atf_log_ctrl->info.atf_buf_addr, p_atf_log_ctrl->info.atf_buf_size);
}
void aee_wdt_dump(void __unused *cookie)
{
	struct atf_aee_regs *regs;
	cpu_context_t *ns_cpu_context;
	uint64_t mpidr = read_mpidr();
	uint32_t linear_id = platform_get_core_pos(mpidr);
	unsigned long sp_phys, count;
	uint64_t *pp;
	uint64_t spsr;
	int i;
	uint64_t sp_el0;
	uint64_t el1_lr;

	/* save context if from non-secure */
	if(read_scr_el3() & SCR_NS_BIT)
		cm_el1_sysregs_context_save(NON_SECURE);

	ns_cpu_context = cm_get_context_by_mpidr(mpidr, NON_SECURE);
	sp_el0 = read_ctx_reg(get_gpregs_ctx(ns_cpu_context), CTX_GPREG_SP_EL0);
	el1_lr = read_ctx_reg(get_gpregs_ctx(ns_cpu_context), CTX_GPREG_LR);
	/* This cpu maybe not yet enter EL1 before */
	if (el1_lr == 0 && sp_el0 == 0) {
		NOTICE("EL1_LR and SP_EL0 is 0x0, no need to dump\n");
		return;
	}

	/* lock aee_wdt_dump_lock for fine print */
	if (DCACHE_IS_ENABLE)
		spin_lock(&aee_wdt_dump_lock);

	/* Log starts here... */
	INFO("%s: on cpu%d\n", __func__, (int)linear_id);

	/* compatible to the earlier chipset */
#if (defined(MACH_TYPE_MT6735) || defined(MACH_TYPE_MT6735M) || \
	defined(MACH_TYPE_MT6753) || defined(MACH_TYPE_MT8173))
	atf_arg_t_ptr teearg = (atf_arg_t_ptr)(uintptr_t)TEE_BOOT_INFO_ADDR;
#else
	atf_arg_t_ptr teearg = &gteearg;
#endif
	regs = (void *)(teearg->atf_aee_debug_buf_start + (linear_id * sizeof(struct atf_aee_regs)));

	/* save debug infos */
	regs->pstate = SMC_GET_EL3(ns_cpu_context, CTX_SPSR_EL3)
	regs->pc = SMC_GET_EL3(ns_cpu_context, CTX_ELR_EL3)
	regs->sp = read_ctx_reg(get_sysregs_ctx(ns_cpu_context), CTX_SP_EL1);
	for (i=0; i<31; i++)
		regs->regs[i] = SMC_GET_GP(ns_cpu_context, (CTX_GPREG_X0 + (i<<3)));

	/* dump debug infos in pretty print */
	INFO("(%d) pc:<%016lx> lr:<%016lx> sp:<%016lx> pstate=%lx\n",
		(int)linear_id, regs->pc, regs->regs[30], regs->sp, regs->pstate);
	for (i=29; i>=0; i-=3) {
		INFO("(%d) x%02d: %016lx x%02d: %016lx x%02d: %016lx\n",
			(int)linear_id, i, regs->regs[i], (i-1), regs->regs[i-1], (i-2), regs->regs[i-2]);
	}

#ifdef MTK_AEE_TC_KWDT_NOT_READY
	wdt_kernel_cb_addr = 0;
#endif

	if (0 == wdt_kernel_cb_addr) {

		NOTICE("Kernel WDT not ready. cpu%d\n", (int)linear_id);

		if (0 == regs->sp) {
			NOTICE("NULL sp, skip stack dump.\n");
		} else {
			/* physical address of sp */
			sp_phys = (regs->sp - 0xffffffc000000000) + 0x40000000;
			NOTICE("sp_phys:0x%lx\n", sp_phys);

			NOTICE("sp_phys(aligned):0x%lx\n", (sp_phys & ~(PAGE_SIZE_2MB_MASK)));

			/* map spphyscial memory for 2MB */
			mmap_add_region((sp_phys & ~(PAGE_SIZE_2MB_MASK)),
					(sp_phys & ~(PAGE_SIZE_2MB_MASK)),
					PAGE_SIZE_2MB,
					MT_DEVICE | MT_RW | MT_NS);

			/* re-fill translation table */
			init_xlat_tables();

			/* flush sp content  */
			flush_dcache_range((uint64_t)sp_phys, (uint64_t)0x2000);

			/* dump 8k */
			pp = (uint64_t *)(uintptr_t)sp_phys;
			count = (0x4000 - (sp_phys &(0x4000-1)))/8;

			NOTICE("dump sp(16k), count:%ld, mask: 0x3fff\n", count);
			for(i=0; i<count ; i+=4,pp+=4)
				INFO("%016lx| %016lx %016lx %016lx %016lx\n",(unsigned long)(uintptr_t)pp, \
				(unsigned long)(uintptr_t)*pp, (unsigned long)(uintptr_t)*(pp+1), \
				(unsigned long)(uintptr_t)*(pp+2), (unsigned long)(uintptr_t)*(pp+3));
		}
		NOTICE("Wait timeout.\n");
		aee_flush_log_cache();
		if (DCACHE_IS_ENABLE)
			spin_unlock(&aee_wdt_dump_lock);
		while(1);
	}

	/* release aee_wdt_dump_lock */
	if (DCACHE_IS_ENABLE)
		spin_unlock(&aee_wdt_dump_lock);

	/* default enter EL1(64b) or SVC(32b) when enter AEE dump */
	spsr = SMC_GET_EL3(ns_cpu_context, CTX_SPSR_EL3);
	if (LINUX_KERNEL_32 == get_kernel_k32_64()){
		spsr = (spsr & ~((MODE32_MASK) << MODE32_SHIFT));
		spsr = (spsr | ((MODE32_svc) << MODE32_SHIFT));
	} else {
		spsr = (spsr & ~((MODE_EL_MASK << MODE_EL_SHIFT)|(MODE_SP_MASK << MODE_SP_SHIFT)|(MODE_RW_MASK << MODE_RW_SHIFT)));
		spsr = (spsr | (MODE_EL1 << MODE_EL_SHIFT)|(MODE_SP_ELX << MODE_SP_SHIFT)|(MODE_RW_64 << MODE_RW_SHIFT));
	}

	/* disable IRQ when enter AEE dump */
	spsr = (spsr | (DAIF_IRQ_BIT << SPSR_AIF_SHIFT));
#ifdef MTK_AEE_TC_CHECK_MODE
	/* ready to make test case */
	if (linear_id == 0) {
		spsr = 0x000000000000008d;
		SMC_SET_EL3(ns_cpu_context, CTX_SPSR_EL3, spsr);
	}
#else
	SMC_SET_EL3(ns_cpu_context, CTX_SPSR_EL3, spsr);
#endif

	/* wdt kernel callback addr should be ready now... */
	SMC_SET_EL3(ns_cpu_context, CTX_ELR_EL3, wdt_kernel_cb_addr);

	/* Restore non-secure state */
	cm_el1_sysregs_context_restore(NON_SECURE);
	cm_set_next_eret_context(NON_SECURE);
	aee_flush_log_cache();

}
void aee_wdt_dump_all_core(void __unused *cookie) {
	mt_fiq_smp_call_function(aee_wdt_dump, 0, 0);
	aee_wdt_dump(NULL);
}
