summaryrefslogtreecommitdiff
path: root/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/scrub.S
blob: 08b4a73dcb274118e95e506c5dcb3612dfc9aa28 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/* Copyright 2020 SiFive, Inc */
/* SPDX-License-Identifier: Apache-2.0 */

/*
 * Scrub memory with zeroes
 */

/* Keep it in metal.init section with _enter */
.section .text.metal.init.scrub
/* Disable linker relaxation */
.option push
.option norelax

/* Function to zero-scrub specified memory
 * a0 : start address for zero-scrub
 * a1 : size memory region size in bytes
 */
.global metal_mem_scrub
.type metal_mem_scrub, @function
metal_mem_scrub:

    /* Disable machine interrupts,
    restore previous mstatus value at exit */
    li      a3, 8
    csrrc   t1, mstatus, a3

#if __riscv_xlen == 32
    addi    t0, x0, 4
1:
    blt     a1, t0, 2f
    andi    a2, a0, 3
    beqz    a2, 3f
2:
    sb      x0, 0(a0)
    addi    a0, a0, 1
    addi    a1, a1, -1
    bgtz    a1, 1b
    csrw    mstatus, t1
    ret
3:
    sw      x0, 0(a0)
    addi    a0, a0, 4
    addi    a1, a1, -4
    bgtz    a1, 1b
    csrw    mstatus, t1
    ret
#else
    addi    t0, x0, 8
1:
    blt     a1, t0, 2f
    andi    a2, a0, 7
    beqz    a2, 3f
2:
    sb      x0, 0(a0)
    addi    a0, a0, 1
    addi    a1, a1, -1
    bgtz    a1, 1b
    csrw    mstatus, t1
    ret
3:
    sd      x0, 0(a0)
    addi    a0, a0, 8
    addi    a1, a1, -8
    bgtz    a1, 1b
    csrw    mstatus, t1
    ret
#endif

.type __metal_memory_scrub, @function
__metal_memory_scrub:
/* Zero out specified memory regions */
1:
#if __riscv_xlen == 32
    sw      x0, 0(t1)
    addi    t1, t1, 4
    blt     t1, t2, 1b
#else
    sd      x0, 0(t1)
    addi    t1, t1, 8
    blt     t1, t2, 1b
#endif
    ret

/*
 * Initialize memories to zero
 * This must be called before setting up any stack(s)
 */
.weak __metal_eccscrub_bit
.weak __metal_before_start
.global __metal_before_start
.type __metal_before_start, @function
__metal_before_start:
    /* Save caller ra */
    mv      s0, ra

    la      t0, __metal_eccscrub_bit
    beqz    t0, skip_scrub

    la      t0, __metal_boot_hart
    csrr    a5, mhartid

    /* Disable machine interrupts to be safe */
    li      a3, 8
    csrc    mstatus, a3

    /* Zero out per hart stack */
    mv      t1, sp
    la      t2, __stack_size
    add     t2, t2, sp
    beq     t1, t2, 1f
    jal     __metal_memory_scrub
1:
    bne     a5, t0, skip_scrub

    /* Zero out data segment */
    la      t1, metal_segment_data_target_start
    la      t2, metal_segment_data_target_end
    beq     t1, t2, 1f
    jal     __metal_memory_scrub
1:
    /* Zero out itim memory */
    la      t1, metal_segment_itim_target_start
    la      t2, metal_segment_itim_target_end
    beq     t1, t2, skip_scrub
    jal     __metal_memory_scrub

skip_scrub:
    /* Restore caller ra */
    mv      ra, s0
    ret

.option pop