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

Last change on this file since 349 was 349, checked in by cfuguet, 11 years ago

Rearranging addresses in the function pointer table
to keep backward compatibility with applications using
the old values.

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