/*
 * Copyright 2011 Tilera Corporation. All Rights Reserved.
 *
 *   This program is free software; you can redistribute it and/or
 *   modify it under the terms of the GNU General Public License
 *   as published by the Free Software Foundation, version 2.
 *
 *   This program is distributed in the hope that it will be useful, but
 *   WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
 *   NON INFRINGEMENT.  See the GNU General Public License for
 *   more details.
 *
 * TILE startup code.
 */

#include <linux/linkage.h>
#include <linux/init.h>
#include <asm/page.h>
#include <asm/pgtable.h>
#include <asm/thread_info.h>
#include <asm/processor.h>
#include <asm/asm-offsets.h>
#include <hv/hypervisor.h>
#include <arch/chip.h>
#include <arch/spr_def.h>

/*
 * This module contains the entry code for kernel images. It performs the
 * minimal setup needed to call the generic C routines.
 */

	__HEAD
ENTRY(_start)
	/* Notify the hypervisor of what version of the API we want */
	{
	  movei r1, TILE_CHIP
	  movei r2, TILE_CHIP_REV
	}
	{
	  moveli r0, _HV_VERSION
	  jal hv_init
	}
	/* Get a reasonable default ASID in r0 */
	{
	  move r0, zero
	  jal hv_inquire_asid
	}

	/*
	 * Install the default page table.  The relocation required to
	 * statically define the table is a bit too complex, so we have
	 * to plug in the pointer from the L0 to the L1 table by hand.
	 * We only do this on the first cpu to boot, though, since the
	 * other CPUs should see a properly-constructed page table.
	 */
	{
	  v4int_l r2, zero, r0    /* ASID for hv_install_context */
	  moveli r4, hw1_last(swapper_pgprot - PAGE_OFFSET)
	}
	{
	  shl16insli r4, r4, hw0(swapper_pgprot - PAGE_OFFSET)
	}
	{
	  ld r1, r4               /* access_pte for hv_install_context */
	}
	{
	  moveli r0, hw1_last(.Lsv_data_pmd - PAGE_OFFSET)
	  moveli r6, hw1_last(temp_data_pmd - PAGE_OFFSET)
	}
	{
	  /* After initializing swapper_pgprot, HV_PTE_GLOBAL is set. */
	  bfextu r7, r1, HV_PTE_INDEX_GLOBAL, HV_PTE_INDEX_GLOBAL
	  inv r4
	}
	bnez r7, .Lno_write
	{
	  shl16insli r0, r0, hw0(.Lsv_data_pmd - PAGE_OFFSET)
	  shl16insli r6, r6, hw0(temp_data_pmd - PAGE_OFFSET)
	}
	{
	  /* Cut off the low bits of the PT address. */
	  shrui r6, r6, HV_LOG2_PAGE_TABLE_ALIGN
	  /* Start with our access pte. */
	  move r5, r1
	}
	{
	  /* Stuff the address into the page table pointer slot of the PTE. */
	  bfins r5, r6, HV_PTE_INDEX_PTFN, \
			HV_PTE_INDEX_PTFN + HV_PTE_PTFN_BITS - 1
	}
	{
	  /* Store the L0 data PTE. */
	  st r0, r5
	  addli r6, r6, (temp_code_pmd - temp_data_pmd) >> \
			HV_LOG2_PAGE_TABLE_ALIGN
	}
	{
	  addli r0, r0, .Lsv_code_pmd - .Lsv_data_pmd
	  bfins r5, r6, HV_PTE_INDEX_PTFN, \
			HV_PTE_INDEX_PTFN + HV_PTE_PTFN_BITS - 1
	}
	/* Store the L0 code PTE. */
	st r0, r5

.Lno_write:
	moveli lr, hw2_last(1f)
	{
	  shl16insli lr, lr, hw1(1f)
	  moveli r0, hw1_last(swapper_pg_dir - PAGE_OFFSET)
	}
	{
	  shl16insli lr, lr, hw0(1f)
	  shl16insli r0, r0, hw0(swapper_pg_dir - PAGE_OFFSET)
	}
	{
	  move r3, zero
	  j hv_install_context
	}
1:

	/* Install the interrupt base. */
	moveli r0, hw2_last(MEM_SV_START)
	shl16insli r0, r0, hw1(MEM_SV_START)
	shl16insli r0, r0, hw0(MEM_SV_START)
	mtspr SPR_INTERRUPT_VECTOR_BASE_K, r0

	/*
	 * Get our processor number and save it away in SAVE_K_0.
	 * Extract stuff from the topology structure: r4 = y, r6 = x,
	 * r5 = width.  FIXME: consider whether we want to just make these
	 * 64-bit values (and if so fix smp_topology write below, too).
	 */
	jal hv_inquire_topology
	{
	  v4int_l r5, zero, r1    /* r5 = width */
	  shrui r4, r0, 32        /* r4 = y */
	}
	{
	  v4int_l r6, zero, r0    /* r6 = x */
	  mul_lu_lu r4, r4, r5
	}
	{
	  add r4, r4, r6          /* r4 == cpu == y*width + x */
	}

#ifdef CONFIG_SMP
	/*
	 * Load up our per-cpu offset.  When the first (master) tile
	 * boots, this value is still zero, so we will load boot_pc
	 * with start_kernel, and boot_sp with init_stack + THREAD_SIZE.
	 * The master tile initializes the per-cpu offset array, so that
	 * when subsequent (secondary) tiles boot, they will instead load
	 * from their per-cpu versions of boot_sp and boot_pc.
	 */
	moveli r5, hw2_last(__per_cpu_offset)
	shl16insli r5, r5, hw1(__per_cpu_offset)
	shl16insli r5, r5, hw0(__per_cpu_offset)
	shl3add r5, r4, r5
	ld r5, r5
	bnez r5, 1f

	/*
	 * Save the width and height to the smp_topology variable
	 * for later use.
	 */
	moveli r0, hw2_last(smp_topology + HV_TOPOLOGY_WIDTH_OFFSET)
	shl16insli r0, r0, hw1(smp_topology + HV_TOPOLOGY_WIDTH_OFFSET)
	shl16insli r0, r0, hw0(smp_topology + HV_TOPOLOGY_WIDTH_OFFSET)
	st r0, r1
1:
#else
	move r5, zero
#endif

	/* Load and go with the correct pc and sp. */
	{
	  moveli r1, hw2_last(boot_sp)
	  moveli r0, hw2_last(boot_pc)
	}
	{
	  shl16insli r1, r1, hw1(boot_sp)
	  shl16insli r0, r0, hw1(boot_pc)
	}
	{
	  shl16insli r1, r1, hw0(boot_sp)
	  shl16insli r0, r0, hw0(boot_pc)
	}
	{
	  add r1, r1, r5
	  add r0, r0, r5
	}
	ld r0, r0
	ld sp, r1
	or r4, sp, r4
	mtspr SPR_SYSTEM_SAVE_K_0, r4  /* save ksp0 + cpu */
	addi sp, sp, -STACK_TOP_DELTA
	{
	  move lr, zero   /* stop backtraces in the called function */
	  jr r0
	}
	ENDPROC(_start)

__PAGE_ALIGNED_BSS
	.align PAGE_SIZE
ENTRY(empty_zero_page)
	.fill PAGE_SIZE,1,0
	END(empty_zero_page)

	.macro PTE cpa, bits1
	.quad HV_PTE_PAGE | HV_PTE_DIRTY | HV_PTE_PRESENT | HV_PTE_ACCESSED |\
	      HV_PTE_GLOBAL | (HV_PTE_MODE_CACHE_NO_L3 << HV_PTE_INDEX_MODE) |\
	      (\bits1) | (HV_CPA_TO_PFN(\cpa) << HV_PTE_INDEX_PFN)
	.endm

__PAGE_ALIGNED_DATA
	.align PAGE_SIZE
ENTRY(swapper_pg_dir)
	.org swapper_pg_dir + HV_L0_INDEX(PAGE_OFFSET) * HV_PTE_SIZE
.Lsv_data_pmd:
	.quad 0  /* PTE temp_data_pmd - PAGE_OFFSET, 0 */
	.org swapper_pg_dir + HV_L0_INDEX(MEM_SV_START) * HV_PTE_SIZE
.Lsv_code_pmd:
	.quad 0  /* PTE temp_code_pmd - PAGE_OFFSET, 0 */
	.org swapper_pg_dir + HV_L0_SIZE
	END(swapper_pg_dir)

	.align HV_PAGE_TABLE_ALIGN
ENTRY(temp_data_pmd)
	/*
	 * We fill the PAGE_OFFSET pmd with huge pages with
	 * VA = PA + PAGE_OFFSET.  We remap things with more precise access
	 * permissions later.
	 */
	.set addr, 0
	.rept HV_L1_ENTRIES
	PTE addr, HV_PTE_READABLE | HV_PTE_WRITABLE
	.set addr, addr + HV_PAGE_SIZE_LARGE
	.endr
	.org temp_data_pmd + HV_L1_SIZE
	END(temp_data_pmd)

	.align HV_PAGE_TABLE_ALIGN
ENTRY(temp_code_pmd)
	/*
	 * We fill the MEM_SV_START pmd with huge pages with
	 * VA = PA + PAGE_OFFSET.  We remap things with more precise access
	 * permissions later.
	 */
	.set addr, 0
	.rept HV_L1_ENTRIES
	PTE addr, HV_PTE_READABLE | HV_PTE_EXECUTABLE
	.set addr, addr + HV_PAGE_SIZE_LARGE
	.endr
	.org temp_code_pmd + HV_L1_SIZE
	END(temp_code_pmd)

	/*
	 * Isolate swapper_pgprot to its own cache line, since each cpu
	 * starting up will read it using VA-is-PA and local homing.
	 * This would otherwise likely conflict with other data on the cache
	 * line, once we have set its permanent home in the page tables.
	 */
	__INITDATA
	.align CHIP_L2_LINE_SIZE()
ENTRY(swapper_pgprot)
	.quad HV_PTE_PRESENT | (HV_PTE_MODE_CACHE_NO_L3 << HV_PTE_INDEX_MODE)
	.align CHIP_L2_LINE_SIZE()
	END(swapper_pgprot)
