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

Last change on this file since 556 was 554, checked in by bouyer, 11 years ago

Make sure the boot loader won't try to write to the ROM.
Store read-write data in BSS along with the stack at seg_stack_base.

File size: 6.5 KB
Line 
1/**
2 * \file  : reset.S
3 * \date  : 01/12/2012
4 * \author: Cesar FUGUET & Manuel BOUYER & Alain Greiner
5 *
6 * This is a boot code for a generic multi-clusters / multi-processors
7 * TSAR architecture (up to 256 clusters / up to 4  processors per cluster).
8 * There is one XICU, one TTY, one DMA and one stack segment per cluster.
9 * segment base adresses = base + cluster_segment_increment*cluster_id
10 *
11 * - Each processor initializes the Status Register (SR) to disable interrupts.
12 * - Each processor initializes the Count Register.
13 * - Each processor initialises its private XICU Write Triggered Interruption
14 *   mask register.
15 * - Only processor 0 initializes the stack pointer ($29).
16 * - Only processor 0 (boot processor) executes the boot_load_elf function to
17 *   load in memory the boot loader stored in the block BOOT_LOADER_LBA of
18 *   the disk.
19 * - All non-boot processors wait in a low power consumption mode that the
20 *   processor 0 wakes them using the IPI (Inter Processor Interruption)
21 *   functionality of the XICU device.
22 */
23
24    #include <defs.h>
25    #include <mips32_registers.h>
26
27    .section .boot,"ax",@progbits
28
29    .extern seg_stack_base
30
31    .extern dtb_addr
32    .extern boot_putc
33    .extern boot_getc
34    .extern boot_ioc_read
35    .extern boot_elf_loader
36    .extern memcpy
37    .extern boot_puts
38    .extern boot_putx
39    .extern boot_putd
40    .extern boot_ioc_init
41    .extern versionstr
42
43    .globl  boot                    /* Make reset an external symbol */
44    .ent    boot
45
46    .align  2
47    .set noreorder
48
49boot:
50    b       _boot                   /* 0xbfc0000 */
51    nop                             /* 0xbfc0004 */
52
53    /*  Addresses of the functions provided by this pre-loader */
54
55    .word   BOOT_VERSION            /* 0xbfc0008 */
56    .word   dtb_addr                /* 0xbfc000c */
57    .word   boot_putc               /* 0xbfc0010 */
58    .word   boot_getc               /* 0xbfc0014 */
59    .word   boot_ioc_read           /* 0xbfc0018 */
60    .word   boot_elf_loader         /* 0xbfc001C */
61    .word   memcpy                  /* 0xbfc0020 */
62    .word   boot_puts               /* 0xbfc0024 */
63    .word   boot_putx               /* 0xbfc0028 */
64    .word   boot_putd               /* 0xbfc002C */
65
66_boot:
67    /* Disable interruptions, keep STATUSbev enabled */
68
69    li      k0,     (1 << 22)
70    mtc0    k0,     CP0_STATUS
71
72    /* Computes proc_id, local_id, cluster_id, and cluster_increment */
73
74    mfc0    k0,     CP0_EBASE
75    andi    t0,     k0,     0x3FF   /* t0 <= proc_id (at most 1024 processors)    */
76
77    move    t3,     t0
78
79    la      k0,     NB_PROCS        /* k0 <= number of processors per cluster     */
80    divu    t3,     k0
81    mfhi    t1                      /* t1 <= local_id   = proc_id % NB_PROCS      */
82    mflo    t2                      /* t2 <= cluster_id = proc_id / NB_PROCS      */
83
84    la      k0,     NB_CLUSTERS
85    li      t3,     0x80000000
86    divu    t3,     k0
87    mflo    t4
88    sll     t4,     1               /* t4 <= cluster_increment = 4G / NB_CLUSTERS */
89
90    mult    t4,     t2
91    mflo    t5                      /* t5 <= cluster_id * cluster_increment       */
92 
93    /* Initialization of the count register in the coprocessor 0 */
94
95    mtc0    zero,   CP0_COUNT
96
97    /* In each cluster, the ICU base address depends on the cluster_id */
98
99    la      t3,     ICU_BASE
100    addu    t3,     t3,     t5      /* t3 <= ICU_BASE +                       */
101                                    /*       (cluster_id * cluster_increment) */
102
103    /**
104     * Compute the output index for the Write Triggered Interruption mask.
105     * Each processor enable the WTI for its irq output
106     * Each processor may have IRQ_PER_PROC private irq outputs from
107     * the XICU
108     */
109
110    move    t4,     t1              /* t4 <= local_id                   */
111    li      t5,     IRQ_PER_PROC    /* t5 <= IRQ_PER_PROC               */
112    multu   t4,     t5             
113    mflo    t6                      /* t6 <= IRQ_PER_PROC * local_id    */
114    sll     t4,     t6,     2       /* t4 <= OUT_INDEX = t6 * 4         */
115
116    li      t5,     (0xC << 7)      /* t5 <= FUNC      = XICU_MSK_WTI   */
117    or      t4,     t4,     t5      /* t4 <= FUNC | INDEX | 00          */
118    or      t5,     t3,     t4      /* t5 <= &XICU[MSK_WTI][OUT_INDEX]  */
119   
120    /* Compute and set WTI mask */
121
122    li      t4,     1
123    sllv    t4,     t4,     t1      /* Set XICU[MSK_WTI][INDEX][local_id] */
124    sw      t4,     0(t5)           /* XICU[MSK_WTI][INDEX] <= t4         */
125
126    /**
127     * We have:
128     * t0: global id
129     * t1: local id
130     * t2: cluster id
131     * t3: xicu base address
132     *
133     * Only processor 0 in cluster 0 executes the boot loader
134     */
135
136    bne     zero,   t0,     _reset_wait
137    nop
138
139    /* Initializes stack pointer */
140
141    la      sp,     stk
142
143    la      a0,     versionstr
144    la      k0,     boot_puts
145    jalr    k0
146    nop
147
148#ifndef SOCLIB_IOC
149
150    /* Initialize the block device */
151
152    la      k0,     boot_ioc_init
153    jalr    k0
154    nop
155
156#endif
157
158    /**
159     * Jump to the boot elf loader routine
160     * Passing as argument the block number in which it must be
161     * the executable elf file to load
162     */
163
164    la      k0,     boot_elf_loader
165    li      a0,     BOOT_LOADER_LBA
166    jalr    k0
167    nop
168
169    /**
170     * We jump to the entry point address defined in the
171     * ELF file. This address is returned by boot_elf_loader function.
172     * All function arguments are 0
173     */
174
175    move    a0,     zero
176    move    a1,     zero
177    move    a2,     zero
178    move    a3,     zero
179    jr      v0
180    nop
181
182/**
183 * Wait in low power consumption mode until the application wakes us.
184 * The application wakes up the non-boot CPUs using a IPI with a non-0
185 * value in the mailbox. This non-0 value is the address to jump to.
186 */
187
188_reset_wait:
189    /**
190     * We have:
191     * t0: global id
192     * t1: local id
193     * t2: cluster id
194     * t3: xicu base address
195     */
196
197    sll     t4,     t1,     2       /* t4 <= local_id * 4             */
198    addu    t5,     t4,     t3      /* t5 <= &XICU[WTI_REG][local_id] */
199
200    wait
201
202    lw      k0,     0(t5)           /* k0 <= XICU[WTI_REG][local_id]  */
203    jr      k0
204    nop
205
206/* Exception entry point */
207.org 0x0380
208_excep:
209    mfc0    a0, CP0_STATUS          /* first arg is status */
210    mfc0    a1, CP0_CAUSE           /* second arg is cause */
211    mfc0    a2, CP0_EPC             /* third argc is epc   */
212    nop
213    j       handle_except
214    nop
215
216    .end boot
217
218    .set reorder
219
220    .section .data
221    .space BOOT_STACK_SIZE
222stk:
223    .space 1
224
225/*
226 * vim: tabstop=4 : shiftwidth=4 : expandtab
227 */
Note: See TracBrowser for help on using the repository browser.