summaryrefslogtreecommitdiff
path: root/fw/fe310/bsp/gloss/crt0.S
blob: a8c5a74df401c2188c9f7980e03522a640840769 (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
#=========================================================================
# crt0.S : Entry point for RISC-V user programs
#=========================================================================

  .section .text.libgloss.start
  .global _start
  .type   _start, @function
_start:
  # Initialize global pointer
  .option push
  .option norelax
1:auipc gp, %pcrel_hi(__global_pointer$)
  addi  gp, gp, %pcrel_lo(1b)
  .option pop

  # Clear the bss segment
  la      a0, metal_segment_bss_start
  la      a2, metal_segment_bss_end
  sub     a2, a2, a0
  li      a1, 0
  call    memset

  # Copy data segment
  la      a0, metal_segment_data_target_start
  la      a1, metal_segment_data_source_start
  la      a2, metal_segment_data_target_end
  sub     a2, a2, a0
  call    memcpy

  fence.i

  # Copy itim segment
  la      a0, metal_segment_itim_target_start
  la      a1, metal_segment_itim_source_start
  la      a2, metal_segment_itim_target_end
  sub     a2, a2, a0
  call    memcpy

  # Copy lim segment
  la      a0, metal_segment_lim_target_start
  la      a1, metal_segment_lim_source_start
  la      a2, metal_segment_lim_target_end
  sub     a2, a2, a0
  call    memcpy

  la      a0, __libc_fini_array   # Register global termination functions
  call    atexit                  #  to be called upon exit
  call    __libc_init_array       # Run global initialization functions

  li      a0, 1     # a0 = argc = 1
  la      a1, argv  # a1 = argv = {"libgloss", NULL}
  la      a2, envp  # a2 = envp = NULL
  call    main
  tail    exit
  .size  _start, .-_start

  .global _init
  .type   _init, @function
  .global _fini
  .type   _fini, @function
_init:
_fini:
  # These don't have to do anything since we use init_array/fini_array.
  ret
  .size  _init, .-_init
  .size  _fini, .-_fini

/* This shim allows main() to be passed a set of arguments that can satisfy the
 * requirements of the C API. */
  .section .rodata.libgloss.start
  .balign 8
argv:
  .dc.a name
envp:
  .dc.a 0
name:
  .asciz "libgloss"