source: trunk/tools/bootloader_tsar/boot_entry.S @ 262

Last change on this file since 262 was 6, checked in by alain, 6 years ago

Modify the boot_info_t struct to describe external peripherals in all clusters.

File size: 8.5 KB
Line 
1/*
2 * boot_entry.S - TSAR bootloader entry point.
3 *
4 * Authors :   Alain Greiner / Vu Son  (2016)
5 *
6 * Copyright (c) UPMC Sorbonne Universites
7 *
8 * This file is part of ALMOS-MKH.
9 *
10 * ALMOS-MKH is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; version 2.0 of the License.
13 *
14 * ALMOS-MKH is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with ALMOS-MKH; if not, write to the Free Software Foundation,
21 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
24/*************************************************************************************************
25 * This file contains the entry point of the ALMOS-MK boot-loader for TSAR architecture.         *
26 * It supports a generic multi-clusters / multi-processors architecture                          *
27 *                                                                                               *
28 * - The number of clusters is defined by the (X_SIZE, Y_SIZE) parameters in the                 *
29 *   hard_config.h file (up to 256 clusters).                                                    *
30 * - The number of processors per cluster is defined by the NB_PROCS_MAX parameter in the        *
31 *   hard_config.h file (up to 4 processors per cluster).                                        *
32 *                                                                                               *
33 * This assembly code is executed by all cores. It has 2 versions (in order to see if the        *
34 * contention created by the ARCHINFO core descriptor table scanning loops is acceptable):       *
35 * with or without the assumption that the core hardware identifier gid has a fixed format:      *
36 *                                                                                               *
37 * - Version with fixed format: gid == (((x << Y_WIDTH) + y) << PADDR_WIDTH) + lid               *
38 *   It does 3 things:                                                                           *
39 *      + It initializes the stack pointer depending on the lid extracted from the gid,          *
40 *        using the BOOT_STACK_BASE and BOOT_STACK_SIZE parameters defined in the                *
41 *        'boot_config.h' file,                                                                  *
42 *      + It changes the value of the address extension registers using the cxy extracted        *
43 *        from the gid,                                                                          *
44 *      + It jumps to the boot_loader() function defined in the 'boot.c' file and passes 2       *
45 *        arguments which are the cxy and lid of each core to this function.                     *
46 *                                                                                               *
47 * - Version without fixed format                                                                *
48 *   It has to perform an additional step in order to extract the (cxy,lid) values from the      *
49 *   arch_info.bin structure that has been loaded in the cluster (0,0) memory by the bscpu.      *
50 *      + Each core other than the bscpu scans the core descriptor table in the arch_info.bin    *
51 *        structure to make an associative search on the (gid), and get the (cxy,lid).           *
52 *      + It initializes the stack pointer depending on the lid, using the BOOT_STACK_BASE       *
53 *        and BOOT_STACK_SIZE parameters defined in the 'boot_config.h' file,                    *
54 *      + It changes the value of the address extension registers using cxy obtained             *
55 *        previously,                                                                            *
56 *      + It jumps to the boot_loader() function defined in the 'boot.c' file and passes 2       *
57 *        arguments which are the cxy and lid of each core to this function.                     *
58 *************************************************************************************************/
59
60#include "mips32_registers.h"
61#include "hard_config.h"
62#include "boot_config.h"
63
64    .section    .text, "ax", @progbits
65
66    .globl      boot_entry
67    .ent        boot_entry
68
69    .align      2
70    .set        noreorder
71
72boot_entry:
73
74#if USE_FIXED_FORMAT
75
76/*************
77 * VERSION 1 *
78 *************/
79
80    /*
81     * Get (cxy, lid) values from gid contained in coprocessor0 register.
82     */
83
84    mfc0    k0,     CP0_PROCID         
85    andi    k0,     k0,     0xFFF                       /* k0 <= gid                        */
86    andi    t1,     k0,     ((1 << P_WIDTH) - 1)        /* t1 <= lid                        */
87    srl     t2,     k0,     P_WIDTH                     /* t2 <= cxy                        */
88   
89    /* Initialize stack pointer from previously retrieved lid value  */
90   
91    la      t0,     BOOT_STACK_BASE                     /* t0 <= BOOT_STACK_BASE            */
92    li      k1,     BOOT_STACK_SIZE                     /* k1 <= BOOT_STACK_SIZE            */
93    multu   k1,     t1
94    mflo    k0                                          /* k0 <= BOOT_STACK_SIZE * lid      */
95    subu    sp,     t0,     k0                          /* P[cxy,lid] stack top initialized */
96
97    /* Switch to local DSPACE by changing the value of the address extension registers  */
98
99    mtc2    t2,     CP2_DATA_PADDR_EXT
100
101    /* Jump to boot_loader() function after passing 2 arguments in the registers  */
102
103    or      a0,     zero,   t1                          /* a0 <= lid                        */     
104    or      a1,     zero,   t2                          /* a1 <= cxy                        */
105    la      ra,     boot_loader
106    jr      ra
107    nop
108
109#else
110
111/*************
112 * VERSION 2 *
113 *************/
114
115    /* Test if this is bscpu  */
116
117    mfc0    k0,     CP0_PROCID         
118    andi    k0,     k0,     0xFFF                       /* k0 <= gid                        */
119
120    li      t1,     BOOT_CORE_GID                       /* t1 <= bscpu gid                  */
121    or      t3,     zero,   zero                        /* t3 <= bscpu lid = 0              */
122    beq     k0,     t1,     bscpu_exit                  /* if bscpu, skip scanning core tbl */
123    li      t4,     BOOT_CORE_CXY                       /* t4 <= bscpu cxy                  */
124
125    /* Get base address of the core descriptor table in 'arch_info.bin' file */
126
127    la      t0,     ARCHINFO_BASE                       /* t0 <= ARCHINFO_BASE              */
128    li      t1,     0x80                                /* t1 <= ARCHINFO_HEADER_SIZE       */
129    addu    t2,     t0,     t1                          /* t2 <= ARCHINFO_CORE_BASE         */
130
131    /* scan the core descriptor table if this is not bscpu. TODO If not found?  */
132
133    li      t3,     0x8                                 /* t3 <= ARCHINFO_CORE_SIZE         */
134   
135scanning_core_table:
136    lw      t1,     0(t2)                               /* t1 <= archinfo_core.gid          */
137    bne     t1,     k0,     scanning_core_table         /* if (t1 != k0) => loop            */
138    addu    t2,     t2,     t3                          /* t2 <= @ next archinfo_core       */
139
140    /* Get (cxy, lid) values from the found core descriptor  */
141   
142    lw      t3,     -8(t2)                              /* t3 <= lid                        */
143    lw      t4,     -4(t2)                              /* t4 <= cxy                        */
144
145    /* Initialize stack pointer from previously retrieved lid value  */
146
147bscpu_exit:   
148    la      t0,     BOOT_STACK_BASE                     /* t0 <= BOOT_STACK_BASE            */
149    li      k1,     BOOT_STACK_SIZE                     /* k1 <= BOOT_STACK_SIZE            */
150    multu   k1,     t3
151    mflo    k0                                          /* k0 <= BOOT_STACK_SIZE * lid      */
152    subu    sp,     t0,     k0                          /* P[cxy,lid] stack top initialized */
153
154    /* Switch to local DSPACE by changing the value of the address extension registers  */
155
156    mtc2    t4,     CP2_DATA_PADDR_EXT
157
158    /* Jumping to boot_loader() function after passing 2 arguments in registers */
159
160    or      a0,     zero,   t3                          /* a0 <= lid                        */     
161    or      a1,     zero,   t4                          /* a1 <= cxy                        */
162    la      ra,     boot_loader
163    jr      ra
164    nop
165
166#endif
167
168    .end boot_entry
169
170    .set reorder
Note: See TracBrowser for help on using the repository browser.