source: trunk/softs/tsar_boot/src/reset.S @ 757

Last change on this file since 757 was 755, checked in by cfuguet, 10 years ago

tsar_boot: preloader stack

  • During preloader execution, only processor 0 initializes its stack.
  • The stack allocation for other processors must be done by the loaded Operating System during its boot loader execution.
  • The stack size for processor 0 is defined by the RESET_STACK_SIZE preprocessor constant in the defs.h file. For now it is 8 Kbytes and it can be changed if further modifications in the preloader need it.
File size: 7.4 KB
RevLine 
[586]1/*
[292]2 * \file  : reset.S
3 * \date  : 01/12/2012
4 * \author: Cesar FUGUET & Manuel BOUYER & Alain Greiner
5 *
[586]6 * This is a generic reset code for a generic multi-clusters / multi-processors
[755]7 * TSAR architecture (up to 256 clusters / up to 4 processors per cluster).
[292]8 *
[586]9 * There is one XICU, one TTY, one DMA, and one memory bank per cluster.
10 *
[755]11 * This preloader uses a stack segment allocated in cluster 0 for processor 0.
12 * The stack allocation is not performed for other processors as they do not
13 * need it during the preloader execution. Therefore, this allocation should be
14 * done by the loaded Operating System.
15 *
[586]16 * The replicated XICU is used to awake the sleeping processors:
[606]17 *      xicu_paddr_base = ICU_PADDR_BASE + (cluster_xy << 32)
[586]18 *
19 * It is intended to be used with various operating systems or nano kernels,
[755]20 * including NetBSD, Linux, ALMOS, and GIET_VM.
[586]21 *
22 * - Each processor initializes its Status Register (SR) to disable interrupts.
23 * - Each processor initializes its Count Register.
24 * - Each processor initialises its private XICU WTI mask register.
[755]25 * - Only processor 0 executes the reset_load_elf function to load into memory
26 *   the system specific boot-loader stored on disk at BOOT_LOADER_LBA
[586]27 * - All other processors wait in a low power consumption mode that the
28 *   processor 0 wakes them using an IPI (Inter Processor Interruption)
[292]29 */
30
31    #include <defs.h>
32    #include <mips32_registers.h>
33
[606]34    /* These define should be consistent with values defined in map.xml file  */
[292]35
[586]36    .section .reset,"ax",@progbits
37
[348]38    .extern dtb_addr
[586]39    .extern reset_putc
40    .extern reset_getc
41    .extern reset_ioc_read
42    .extern reset_elf_loader
[425]43    .extern memcpy
[586]44    .extern reset_puts
45    .extern reset_putx
46    .extern reset_putd
47    .extern reset_ioc_init
[502]48    .extern versionstr
[292]49
[586]50    .globl  reset                    /* Makes reset an external symbol */
51    .ent    reset
[292]52
53    .align  2
54    .set noreorder
55
[586]56reset:
[755]57    b       _reset                   /* 0xbfc0000 */
58    nop                              /* 0xbfc0004 */
[292]59
[586]60    /*  Addresses of the functions provided by this reset code */
[292]61
[634]62preloader_vector:
[755]63    .word   RESET_VERSION            /* 0xbfc0008 */
64    .word   dtb_addr                 /* 0xbfc000c */
65    .word   reset_putc               /* 0xbfc0010 */
66    .word   reset_getc               /* 0xbfc0014 */
67    .word   reset_ioc_read           /* 0xbfc0018 */
68    .word   reset_elf_loader         /* 0xbfc001C */
69    .word   memcpy                   /* 0xbfc0020 */
70    .word   reset_puts               /* 0xbfc0024 */
71    .word   reset_putx               /* 0xbfc0028 */
72    .word   reset_putd               /* 0xbfc002C */
[292]73
[586]74_reset:
[292]75
[586]76    /* All processors Disable interruptions, keep STATUSbev enabled */
77
[292]78    li      k0,     (1 << 22)
79    mtc0    k0,     CP0_STATUS
80
[755]81    /* All processors compute pid, lpid, cluster_xy */
[292]82
83    mfc0    k0,     CP0_EBASE
[755]84    andi    t0,     k0,     0x3FF    /* t0 <= pid (at most 1024 procs)      */
[292]85
86    move    t3,     t0
87
[755]88    la      k0,     NB_PROCS         /* k0 <= # of processors per cluster   */
[292]89    divu    t3,     k0
[755]90    mfhi    t1                       /* t1 <= lpid       = pid % NB_PROCS   */
91    mflo    t2                       /* t2 <= cluster_xy = pid / NB_PROCS   */
[292]92
[586]93    /* All processors initialise the count register in CP0 */
[292]94
95    mtc0    zero,   CP0_COUNT
96
[586]97    /*
[755]98     * All processors enable the WTI for XICU
[586]99     * Each processor may have IRQ_PER_PROC irq outputs from the XICU
[755]100     * In each cluster, the XICU base address depends on the cluster_xy
[292]101     */
[302]102
[755]103    la      t3,     ICU_PADDR_BASE   /* t3 <= ICU base address              */
104    move    t4,     t1               /* t4 <= local_id                      */
105    li      t5,     IRQ_PER_PROC     /* t5 <= IRQ_PER_PROC                  */
106    multu   t4,     t5
107    mflo    t6                       /* t6 <= IRQ_PER_PROC * local_id       */
108    sll     t4,     t6,     2        /* t4 <= OUT_INDEX = t6 * 4            */
[302]109
[755]110    li      t5,     (0xC << 7)       /* t5 <= FUNC      = XICU_MSK_WTI      */
111    or      t4,     t4,     t5       /* t4 <= FUNC | INDEX | 00             */
112    or      t5,     t3,     t4       /* t5 <= &XICU[MSK_WTI][OUT_INDEX]     */
[292]113
[755]114    /* All processors set WTI mask using the physical address extension */
115
[292]116    li      t4,     1
[755]117    sllv    t4,     t4,     t1       /* Set XICU[MSK_WTI][INDEX][local_id]  */
[292]118
[755]119    mtc2    t2,     CP2_PADDR_EXT    /* set PADDR extension                 */
120    sw      t4,     0(t5)            /* XICU[MSK_WTI][INDEX] <= t4          */
121    mtc2    zero,   CP2_PADDR_EXT    /* reset PADDR extension               */
[567]122
[586]123    /*
[755]124     * Only processor 0 in cluster 0 loads and executes the boot-loader
[292]125     * We have:
[755]126     * t0: global pid
127     * t1: local pid
[606]128     * t2: cluster_xy
[586]129     * t3: xicu physical base address in cluster 0
[292]130     */
131
132    bne     zero,   t0,     _reset_wait
133    nop
134
[755]135    /* Processor 0 initializes stack pointer */
136
137    la      k0,     _stack
138    li      k1,     RESET_STACK_SIZE /* k1 <= P0 stack size                 */
139    addu    sp,     k0,     k1       /* P0 stack from base to (base + size) */
140
[586]141    /* Processor 0 displays version for this reset code */
[292]142
[587]143    la      a0,     versionstr
[755]144    la      k0,     reset_puts
[587]145    jalr    k0
146    nop
[292]147
[502]148
[653]149#if USE_SPI
[292]150
[653]151    /* Processor 0 Initialize the SPI controller */
[292]152
[586]153    la      k0,     reset_ioc_init
[292]154    jalr    k0
155    nop
156
157#endif
158
[586]159    /*
[755]160     * Processor 0 jumps to the reset_elf_loader routine passing as argument
161     * the block number in which is loaded the .elf file
[292]162     */
163
[586]164    la      k0,     reset_elf_loader
[292]165    li      a0,     BOOT_LOADER_LBA
166    jalr    k0
167    nop
168
[755]169    /*
170     * Processor O jumps to the entry address defined in the .elf file, and
171     * returned by reset_elf_loader function.
172     * First argument is pointer to the preloader function vectors other
173     * function arguments are 0
[292]174     */
175
[755]176    la      a0,     preloader_vector
[292]177    move    a1,     zero
178    move    a2,     zero
179    move    a3,     zero
180    jr      v0
181    nop
182
[586]183    /*
[755]184     * All processor (but processor 0) wait in low power mode until processor 0
185     * wakes them using an IPI.
[292]186     * We have:
187     * t0: global id
188     * t1: local id
189     * t2: cluster id
[586]190     * t3: xicu physical base address in cluster 0
[292]191     */
192
[586]193_reset_wait:
[292]194
[755]195    sll     t4,     t1,     2        /* t4 <= local_id * 4                  */
196    addu    t5,     t4,     t3       /* t5 <= &XICU[WTI_REG][local_id]      */
[586]197
[292]198    wait
199
[755]200    /*
201     * All other processors, when exiting wait mode, read from XICU the address
202     * to jump.
203     * This address is the boot-loader entry address that has been written in
204     * the mailbox by the IPI sent by processor 0
[586]205     */
[567]206
[755]207    mtc2    t2,     CP2_PADDR_EXT    /* set PADDR extension                 */
208    lw      k0,     0(t5)            /* k0 <= XICU[WTI_REG][local_id]       */
209    mtc2    zero,   CP2_PADDR_EXT    /* reset PADDR extension               */
[567]210
[292]211    jr      k0
212    nop
213
214/* Exception entry point */
[586]215
[292]216.org 0x0380
217_excep:
[755]218    mfc0    a0,     CP0_STATUS       /* first arg is status                 */
219    mfc0    a1,     CP0_CAUSE        /* second arg is cause                 */
220    mfc0    a2,     CP0_EPC          /* third argc is epc                   */
221    mfc2    a3,     CP2_DBVAR        /* fourth argc is dbvar                */
[292]222    nop
223    j       handle_except
224    nop
225
[586]226    .end reset
[292]227
228    .set reorder
[302]229
[755]230    .section .data
231
232_stack:
233
234    .space RESET_STACK_SIZE
235
[302]236/*
237 * vim: tabstop=4 : shiftwidth=4 : expandtab
238 */
Note: See TracBrowser for help on using the repository browser.