source: trunk/softs/tsar_boot/reset.S @ 281

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

Keep BEV bit set in STATUS register, and add an exception handler at
0xbfc0380. This handler just prints STATUS, CAUSE and EPC register and
stalls (does an infinite loop).

File size: 4.2 KB
Line 
1#################################################################################
2#   File : reset.s
3#   Author : Alain Greiner
4#   Date : 15/04/2011
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#   - Each processor initializes the stack pointer ($29) depending on pid.
11#   - Only processor 0 initializes the Interrupt vector (TTY, DMA & IOC).
12#       - Each processor initialises its private ICU mask register.
13#   - Each processor initializes the Status Register (SR)
14#   - Each processor initializes the EPC register, and jumps to the main
15#     address in kernel mode...
16#################################################################################
17
18#include <defs.h>
19    .section .boot,"ax",@progbits
20
21    .extern seg_stack_base
22    .extern _boot_loader_entry
23
24    .extern dtb_addr
25    .extern boot_putc
26    .extern boot_getc
27    .extern _ioc_read
28
29    .globl  boot               # makes reset an external symbol
30    .ent    boot
31    .align  2
32    .set noreorder
33
34boot:
35    b       _boot               #0xbfc0000
36    nop                         #0xbfc0004
37    .word   BOOT_VERSION        #0xbfc0008
38    .word   dtb_addr            #0xbfc000c
39    .word   boot_putc           #0xbfc0010
40    .word   boot_getc           #0xbfc0014
41    .word   _ioc_read           #0xbfc0018
42
43_boot:
44    # Disable interruptions, keep STATUSbev enabled
45
46    la      $4,     (1 << 22)
47    mtc0    $4,     $12
48
49    # computes proc_id, local_id, cluster_id, and cluster_increment
50
51    mfc0    $26,    $15,    1
52    andi    $10,    $26,    0x3FF   # $10 <= proc_id (at most 1024 processors)
53    la      $26,    NB_PROCS        # $26 <= number of processors per cluster
54    divu    $10,    $26
55    mfhi    $11                     # $11 <= local_id = proc_id % NB_PROCS
56    mflo    $12                     # $12 <= cluster_id = proc_id / NB_PROCS
57
58    mfc0    $26,    $15,    1
59    andi    $10,    $26,    0x3FF   # $10 <= proc_id (at most 1024 processors)
60
61    la      $26,    NB_CLUSTERS
62    li      $13,    0x80000000
63    divu    $13,    $26
64    mflo    $14
65    sll     $14,    1               # $14 <= cluster_increment = 4G / NB_CLUSTERS
66    mult    $14,    $12
67    mflo    $13                     # $13 <= cluster_id * cluster_increment
68
69    # Initialization of the count register in the coprocessor 0
70
71    mtc0    $0 ,    $9
72
73    # in each cluster, the ICU base address depends on the cluster_id
74
75    la      $20,    ICU_BASE
76    addu    $20,    $20,    $13     # $20 <= ICU_BASE + cluster_id*cluster_increment
77    # we have:
78    # $20 xicu base address
79    # $12 cluster id
80    # $11 local id
81    # $10 global id
82    #
83    # only processor 0 in cluster 0 executes the boot loader
84    bne     $0,    $10,     _reset_wait
85    nop
86    # initializes stack pointer
87
88    la      $27,    seg_stack_base
89    li      $26,    0x10000         # $26 <= 0x10000
90    addu    $29,    $27,    $26     # $29 <= seg_stack_base + 0x10000
91
92    # Jump to the boot loader routine
93    la      $26,    _boot_loader_entry
94    jalr    $26
95    nop
96
97    # We jump to the main function, which is the entry point in the
98    # ELF file. The address is returned by _boot_loader_entry
99    # all arguments are 0
100
101    move    $4,    $0
102    move    $5,    $0
103    move    $6,    $0
104    move    $7,    $0
105    jr      $2
106    nop
107
108
109# Wait until the application wakes us.
110# The application wakes up the non-boot CPUs with a IPI with a non-0
111# value in the mailbox. This non-0 value is the address to jump to.
112_reset_wait:
113    # we have:
114    # $20 xicu base address
115    # $12 cluster id
116    # $11 local id
117    # $10 global id
118
119    sll     $13,    $11,    2   # $13 = local_id * 4
120    addu    $21,    $13,    $20 # $21 = XICU_WTI_REG(local_id)
1211:
122    lw      $2,     0($21)
123    beq     $0,     $2,     1b
124    nop   
125    jr      $2
126
127# exeption entry point
128.org    0x0380
129_exep:
130    mfc0    $4, $12, 0  # first arg is status
131    mfc0    $5, $13, 0  # second arg is cause
132    mfc0    $6, $14, 0  # third argc is epc
133    nop
134    j       handle_exept
135    nop
136
137    .end    boot
138
139    .set reorder
Note: See TracBrowser for help on using the repository browser.