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

Last change on this file since 949 was 949, checked in by cfuguet, 9 years ago

preloader: when loading LINUX, copy the DTB in low memory addresses

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