summaryrefslogtreecommitdiff
path: root/test/tx/cmake/module_qemu/src/tx_initialize_low_level.S
blob: 2e6ecfdf0fca389bf62693b960896a0bb1d72b1b (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
/***************************************************************************
 * 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
 **************************************************************************/

@ Low-level initialisation for the module execution harness on QEMU's MPS2
@ AN385 (Cortex-M3) and AN386 (Cortex-M4) boards, both clocked at 25 MHz.

    .syntax unified
    .thumb

    .global _tx_initialize_unused_memory
    .global _tx_timer_interrupt
    .global __RAM_segment_used_end__

SYSTEM_CLOCK    =   25000000
SYSTICK_CYCLES  =   ((SYSTEM_CLOCK / 100) - 1)

    .text
    .align  2

@ VOID _tx_initialize_low_level(VOID)

    .global _tx_initialize_low_level
    .thumb_func
_tx_initialize_low_level:

    CPSID   i                               @ Interrupts stay off until the scheduler starts

    @ First free memory follows everything the image uses.

    LDR     r0, =_tx_initialize_unused_memory
    LDR     r1, =__RAM_segment_used_end__
    ADD     r1, r1, #4
    STR     r1, [r0]

    @ Vector table base, in case the board boots with another.

    LDR     r0, =0xE000ED08                 @ VTOR
    LDR     r1, =_vectors
    STR     r1, [r0]

    @ SysTick at 100 Hz.

    LDR     r0, =0xE000E000
    MOV     r1, #0
    STR     r1, [r0, #0x10]                 @ SysTick control: off
    STR     r1, [r0, #0x18]                 @ SysTick current value
    LDR     r1, =SYSTICK_CYCLES
    STR     r1, [r0, #0x14]                 @ SysTick reload
    MOV     r1, #0x7
    STR     r1, [r0, #0x10]                 @ SysTick control: on, interrupt, core clock

    @ Handler priorities: the faults highest, SVCall and PendSV lowest, as the
    @ module port requires.

    LDR     r1, =0x00000000                 @ Reserved, UsageFault, BusFault, MemManage
    STR     r1, [r0, #0xD18]
    LDR     r1, =0xFF000000                 @ SVCall, reserved x3
    STR     r1, [r0, #0xD1C]
    LDR     r1, =0x40FF0000                 @ SysTick, PendSV, reserved, debug monitor
    STR     r1, [r0, #0xD20]

    BX      lr

@ SysTick: drive the ThreadX timer.

    .global __tx_SysTickHandler
    .global SysTick_Handler
    .thumb_func
__tx_SysTickHandler:
    .thumb_func
SysTick_Handler:
    PUSH    {r0, lr}
    BL      _tx_timer_interrupt
    POP     {r0, lr}
    BX      lr