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

Last change on this file since 276 was 276, checked in by bouyer, 12 years ago

A boot loader to be stored in ROM of a TSAR platform.
Based on Cesar FUGUET's work.
Platform-specific files are in a subdirectory, e.g. platform_fpga_de2-115,
so the same code can be targetted to different platforms.
The platform is selected with the PLATFORM_DIR environnement variable.
The supported variant are soclib and fpga, the later being the default
and the former selected by defining the SOCLIB environnement variable.
The boot loader embeds a binary device tree describing the platform,
to be used by the loaded software.

File size: 3.9 KB
RevLine 
[276]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
45
46    mtc0    $0,     $12
47
48    # computes proc_id, local_id, cluster_id, and cluster_increment
49
50    mfc0    $26,    $15,    1
51    andi    $10,    $26,    0x3FF   # $10 <= proc_id (at most 1024 processors)
52    la      $26,    NB_PROCS        # $26 <= number of processors per cluster
53    divu    $10,    $26
54    mfhi    $11                     # $11 <= local_id = proc_id % NB_PROCS
55    mflo    $12                     # $12 <= cluster_id = proc_id / NB_PROCS
56
57    mfc0    $26,    $15,    1
58    andi    $10,    $26,    0x3FF   # $10 <= proc_id (at most 1024 processors)
59
60    la      $26,    NB_CLUSTERS
61    li      $13,    0x80000000
62    divu    $13,    $26
63    mflo    $14
64    sll     $14,    1               # $14 <= cluster_increment = 4G / NB_CLUSTERS
65    mult    $14,    $12
66    mflo    $13                     # $13 <= cluster_id * cluster_increment
67
68    # Initialization of the count register in the coprocessor 0
69
70    mtc0    $0 ,    $9
71
72    # in each cluster, the ICU base address depends on the cluster_id
73
74    la      $20,    ICU_BASE
75    addu    $20,    $20,    $13     # $20 <= ICU_BASE + cluster_id*cluster_increment
76    # we have:
77    # $20 xicu base address
78    # $12 cluster id
79    # $11 local id
80    # $10 global id
81    #
82    # only processor 0 in cluster 0 executes the boot loader
83    bne     $0,    $10,     _reset_wait
84    nop
85    # initializes stack pointer
86
87    la      $27,    seg_stack_base
88    li      $26,    0x10000         # $26 <= 0x10000
89    addu    $29,    $27,    $26     # $29 <= seg_stack_base + 0x10000
90
91    # Jump to the boot loader routine
92    la      $26,    _boot_loader_entry
93    jalr    $26
94    nop
95
96    # We jump to the main function, which is the entry point in the
97    # ELF file. The address is returned by _boot_loader_entry
98    # all arguments are 0
99
100    move    $4,    $0
101    move    $5,    $0
102    move    $6,    $0
103    move    $7,    $0
104    jr      $2
105    nop
106
107
108# Wait until the application wakes us.
109# The application wakes up the non-boot CPUs with a IPI with a non-0
110# value in the mailbox. This non-0 value is the address to jump to.
111_reset_wait:
112    # we have:
113    # $20 xicu base address
114    # $12 cluster id
115    # $11 local id
116    # $10 global id
117
118    sll     $13,    $11,    2   # $13 = local_id * 4
119    addu    $21,    $13,    $20 # $21 = XICU_WTI_REG(local_id)
1201:
121    lw      $2,     0($21)
122    beq     $0,     $2,     1b
123    nop   
124    jr      $2
125
126    .end    boot
127
128    .set reorder
Note: See TracBrowser for help on using the repository browser.