/* * 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 TSAR architecture. * * It supports a generic multi-clusters / multi-processors architecture * * * * - The number of clusters is defined by the (X_SIZE, Y_SIZE) parameters in the * * hard_config.h file (up to 256 clusters). * * - The number of processors per cluster is defined by the NB_PROCS_MAX parameter in the * * hard_config.h file (up to 4 processors per cluster). * * * * This assembly code is executed by all cores. It has 2 versions (in order to see if the * * contention created by the ARCHINFO core descriptor table scanning loops is acceptable): * * with or without the assumption that the core hardware identifier gid has a fixed format: * * * * - Version with fixed format: gid == (((x << Y_WIDTH) + y) << PADDR_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 defined in the * * 'boot_config.h' file, * * + It changes the value of the address extension registers using the cxy extracted * * from the gid, * * + It jumps to the boot_loader() function defined in the 'boot.c' file and passes 2 * * arguments which are the cxy and lid of each core to this function. * * * * - Version without fixed format * * It has to perform an additional step in order to extract the (cxy,lid) values from the * * arch_info.bin structure that has been loaded in the cluster (0,0) memory by the bscpu. * * + Each core other than the bscpu scans the core descriptor table in the arch_info.bin * * structure to make an associative search on the (gid), and get the (cxy,lid). * * + It initializes the stack pointer depending on the lid, using the BOOT_STACK_BASE * * and BOOT_STACK_SIZE parameters defined in the 'boot_config.h' file, * * + It changes the value of the address extension registers using cxy obtained * * previously, * * + It jumps to the boot_loader() function defined in the 'boot.c' file and passes 2 * * arguments which are the cxy and lid of each core to this function. * *************************************************************************************************/ #include "mips32_registers.h" #include "hard_config.h" #include "boot_config.h" .section .text, "ax", @progbits .globl boot_entry .ent boot_entry .align 2 .set noreorder boot_entry: #if USE_FIXED_FORMAT /************* * VERSION 1 * *************/ /* * Get (cxy, lid) values from gid contained in coprocessor0 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 previously retrieved 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] stack top initialized */ /* Switch to local DSPACE by changing the value of the address extension registers */ mtc2 t2, CP2_DATA_PADDR_EXT /* Jump to boot_loader() function after passing 2 arguments in the registers */ or a0, zero, t1 /* a0 <= lid */ or a1, zero, t2 /* a1 <= cxy */ la ra, boot_loader jr ra nop #else /************* * VERSION 2 * *************/ /* Test if this is bscpu */ mfc0 k0, CP0_PROCID andi k0, k0, 0xFFF /* k0 <= gid */ li t1, BOOT_CORE_GID /* t1 <= bscpu gid */ or t3, zero, zero /* t3 <= bscpu lid = 0 */ beq k0, t1, bscpu_exit /* if bscpu, skip scanning core tbl */ li t4, BOOT_CORE_CXY /* t4 <= bscpu cxy */ /* Get base address of the core descriptor table in 'arch_info.bin' file */ la t0, ARCHINFO_BASE /* t0 <= ARCHINFO_BASE */ li t1, 0x80 /* t1 <= ARCHINFO_HEADER_SIZE */ addu t2, t0, t1 /* t2 <= ARCHINFO_CORE_BASE */ /* scan the core descriptor table if this is not bscpu. TODO If not found? */ li t3, 0x8 /* t3 <= ARCHINFO_CORE_SIZE */ scanning_core_table: lw t1, 0(t2) /* t1 <= archinfo_core.gid */ bne t1, k0, scanning_core_table /* if (t1 != k0) => loop */ addu t2, t2, t3 /* t2 <= @ next archinfo_core */ /* Get (cxy, lid) values from the found core descriptor */ lw t3, -8(t2) /* t3 <= lid */ lw t4, -4(t2) /* t4 <= cxy */ /* Initialize stack pointer from previously retrieved lid value */ bscpu_exit: la t0, BOOT_STACK_BASE /* t0 <= BOOT_STACK_BASE */ li k1, BOOT_STACK_SIZE /* k1 <= BOOT_STACK_SIZE */ multu k1, t3 mflo k0 /* k0 <= BOOT_STACK_SIZE * lid */ subu sp, t0, k0 /* P[cxy,lid] stack top initialized */ /* Switch to local DSPACE by changing the value of the address extension registers */ mtc2 t4, CP2_DATA_PADDR_EXT /* Jumping to boot_loader() function after passing 2 arguments in registers */ or a0, zero, t3 /* a0 <= lid */ or a1, zero, t4 /* a1 <= cxy */ la ra, boot_loader jr ra nop #endif .end boot_entry .set reorder