summaryrefslogtreecommitdiff
path: root/ports/risc-v64/gnu/example_build/erbium/tx_initialize_low_level.S
blob: fe0653ae833a81ece628d6561b3b9d2af6952060 (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
133
134
135
136
137
138
139
140
141
142
/***************************************************************************
 * Copyright (c) 2026 Eclipse ThreadX contributors
 *
 * This program and the accompanying materials are made available under the
 * terms of the MIT License which is available at
 * https://opensource.org/licenses/MIT.
 *
 * AI Disclosure: This file was largely AI-generated by Claude Code (Opus 5.5).
 * The AI-generated portions may be considered public domain (CC0-1.0)
 * and not subject to the project's licence. The human contributor has
 * reviewed and verified that the code is correct.
 *
 * SPDX-License-Identifier: MIT and CC0-1.0
 **************************************************************************/

#include "csr.h"
#include "tx_port.h"

/* Erbium ignores mtvec base bits 11:1, so the trap vector must be 4 KiB
   aligned.  */
    .section .text.trap, "ax", @progbits
    .balign 4096
/**************************************************************************/
/*                                                                        */
/*  FUNCTION                                               RELEASE        */
/*                                                                        */
/*    trap_entry                                         RISC-V64/GNU     */
/*                                                                        */
/*  DESCRIPTION                                                           */
/*                                                                        */
/*    This function is the machine-mode trap vector (direct mode).  It    */
/*    saves the interrupted context, calls trap_handler with mcause,      */
/*    mepc and mtval, and leaves through the ThreadX context restore.     */
/*                                                                        */
/*  INPUT                                                                 */
/*                                                                        */
/*    None                                                                */
/*                                                                        */
/*  OUTPUT                                                                */
/*                                                                        */
/*    None                                                                */
/*                                                                        */
/*  CALLS                                                                 */
/*                                                                        */
/*    _tx_thread_context_save               Save interrupted context      */
/*    trap_handler                          Dispatch the trap             */
/*    _tx_thread_context_restore            Restore or schedule a thread  */
/*                                                                        */
/*  CALLED BY                                                             */
/*                                                                        */
/*    Hardware trap                                                       */
/*                                                                        */
/**************************************************************************/
    .global  trap_entry
    .extern  trap_handler
    .extern  _tx_thread_context_save
    .extern  _tx_thread_context_restore
trap_entry:
    addi    sp, sp, -TX_RISCV_TRAP_FRAME_SIZE       // Interrupt frame from the port contract
    sd      x1, 28*8(sp)                            // Save RA before the call below overwrites it

    call    _tx_thread_context_save

    csrr    a0, mcause
    csrr    a1, mepc
    csrr    a2, mtval
    addi    sp, sp, -16                             // 16 bytes keep sp 16-byte aligned at the call
    sd      ra, 0(sp)
    call    trap_handler
    ld      ra, 0(sp)
    addi    sp, sp, 16

    call    _tx_thread_context_restore
    /* _tx_thread_context_restore does not return.  */
_trap_entry_hang:
    j       _trap_entry_hang


    .section .text
/**************************************************************************/
/*                                                                        */
/*  FUNCTION                                               RELEASE        */
/*                                                                        */
/*    _tx_initialize_low_level                           RISC-V64/GNU     */
/*                                                                        */
/*  DESCRIPTION                                                           */
/*                                                                        */
/*    This function is responsible for any low-level processor            */
/*    initialization, including setting up interrupt vectors, setting     */
/*    up a periodic timer interrupt source, saving the system stack       */
/*    pointer for use in ISR processing later, and finding the first      */
/*    available RAM memory address for tx_application_define.             */
/*                                                                        */
/*  INPUT                                                                 */
/*                                                                        */
/*    None                                                                */
/*                                                                        */
/*  OUTPUT                                                                */
/*                                                                        */
/*    None                                                                */
/*                                                                        */
/*  CALLS                                                                 */
/*                                                                        */
/*    board_init                            Initialize the peripherals    */
/*                                                                        */
/*  CALLED BY                                                             */
/*                                                                        */
/*    _tx_initialize_kernel_enter           ThreadX entry function        */
/*                                                                        */
/**************************************************************************/
/* VOID   _tx_initialize_low_level(VOID)
{  */
    .global  _tx_initialize_low_level              // Strong definition: must beat the port's weak default
    .extern  _end
    .extern  board_init
    .extern  _tx_thread_system_stack_ptr
    .extern  _tx_initialize_unused_memory
_tx_initialize_low_level:
    la      t0, _tx_thread_system_stack_ptr
    sd      sp, 0(t0)                               // Save system stack pointer

    la      t0, _end                                // Pickup first free address
    la      t1, _tx_initialize_unused_memory
    sd      t0, 0(t1)                               // Save unused memory address

    li      t0, MSTATUS_MIE
    csrrc   zero, mstatus, t0                       // Keep interrupts off until the scheduler runs
    li      t0, (MSTATUS_MPP_M | MSTATUS_MPIE)
    csrrs   zero, mstatus, t0                       // mret stays in M-mode with interrupts enabled
    li      t0, (MIE_MTIE | MIE_MEIE)
    csrrs   zero, mie, t0                           // Enable timer and external interrupts

    addi    sp, sp, -16                             // 16 bytes keep sp 16-byte aligned at the call
    sd      ra, 0(sp)
    call    board_init
    ld      ra, 0(sp)
    addi    sp, sp, 16

    la      t0, trap_entry
    csrw    mtvec, t0                               // Direct mode: trap_entry is 4 KiB aligned
    ret
/* }  */