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

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

Modifications in tsar_boot:

  • Creating new files boot_utils.[c h] containing the memcpy, memset and some ELF format debug functions
  • Introducing assert in the boot_elf_loader to show an error when some of segments to load conflicts with some of the pre-loader segments
  • Cosmetic changes in boot_elf_loader to improve code readibility
  • Fixing bug in dcache_buf_invalidate function used by boot_ioc_read when cache coherence not supported. The condition in the for loop was erroneous.
  • Modification in Makefile: The SYSCLK_FREQ parameter is not passed anymore

as a Makefile parameter but it is definesd in the defs_platform.h file

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
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   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.