/*
 * boot_entry.S - TSAR bootloader entry point.
 * 
 * Authors :   Alain Greiner / Vu Son  (2016)
 *
 * Copyright (c) UPMC Sorbonne Universites
 *
 * This file is part of ALMOS-MKH.
 *
 * ALMOS-MKH 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.0 of the License.
 *
 * ALMOS-MKH 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.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with ALMOS-MKH; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 */

/**********************************************************************************************/
/* This file contains the entry point of the ALMOS-MK boot-loader for the TSAR architecture,  */
/* that is a generic multi-clusters / multi-processors architecture.                          */
/*                                                                                            */
/* This assembly code is executed by all cores, but not at the same time, because all cores   */
/* are not simultaneously activated. It makes the assuption that the CPO register containing  */
/* the core gid (global hardware identifier) has a fixed format:                              */
/*    gid == (((x << Y_WIDTH) + y) << P_WIDTH) + lid                                          */
/*                                                                                            */
/* It does 3 things:                                                                          */
/* - It initializes the stack pointer depending on the lid extracted from the gid,            */
/*   using the BOOT_STACK_BASE and BOOT_STACK_SIZE parameters that are defined in             */
/*   the boot_config.h file,                                                                  */
/* - It changes the value of the DATA address extension register using the cxy extracted      */
/*   from the gid, with X_WIDTH, Y_WIDTH, P_WIDTH defined in the boot¨config.h file.          */
/* - It jumps to the boot_loader() function defined in the 'boot.c' file, passing the two     */
/*   arguments (cxy and lid).                                                                 */
/**********************************************************************************************/

#include "mips32_registers.h"
#include "boot_config.h"

    .section    .text, "ax", @progbits

    .globl      boot_entry
    .ent        boot_entry

    .align      2
    .set        noreorder

boot_entry:

    /* Get (cxy, lid) values from gid contained in CP0 register  */

    mfc0    k0,     CP0_PROCID          
    andi    k0,     k0,     0xFFF                       /* k0 <= gid                        */
    andi    t1,     k0,     ((1 << P_WIDTH) - 1)        /* t1 <= lid                        */
    srl     t2,     k0,     P_WIDTH                     /* t2 <= cxy                        */
    
    /* Initialize stack pointer from lid value  */
    
    la      t0,     BOOT_STACK_BASE                     /* t0 <= BOOT_STACK_BASE            */
    li      k1,     BOOT_STACK_SIZE                     /* k1 <= BOOT_STACK_SIZE            */
    multu   k1,     t1
    mflo    k0                                          /* k0 <= BOOT_STACK_SIZE * lid      */
    subu    sp,     t0,     k0                          /* P[cxy,lid] sp initialized        */ 

    /* Switch to local DSPACE by changing the value of the address extension register       */

    mtc2    t2,     CP2_DATA_PADDR_EXT

    /* Jump to boot_loader() function after passing (cxy,lid) arguments in the registers    */

    or      a0,     zero,   t1                          /* a0 <= lid                        */     
    or      a1,     zero,   t2                          /* a1 <= cxy                        */
    la      ra,     boot_loader
    jr      ra
    nop

    .end boot_entry

    .set reorder
