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

Last change on this file since 294 was 292, checked in by cfuguet, 12 years ago

Changing directory structure of the TSAR boot loader.
A README.txt file has been included to explain the new structure
and the MAKEFILE parameters.

Erasing the heap segment for the boot elf loader. All the work space
is allocated in the stack.

The stack size is defined in the include/defs.h.

Important modification in the reset.S file. The non-boot
processors (processor id != 0) wait in a low comsumption energy
mode to be wake up by processor 0 using an IPI. Each processor
has a private mailbox in the local XICU. The value written in
the mailbox will be used as address to jump by the processors.

The waking up of non-boot processors is not done in this boot loader
so it must be done in the application loaded.

The boot_loader_elf function loads into memory an executable .elf file
which must be placed in the BOOT_LOADER_LBA block of the disk. This
constant can be defined in the include/defs.h file.

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