1/*
2 * ARM64 machine routines.
3 */
4
5#include <arm/asm_help.h>
6#include <assym.s>
7
8/**
9 * __disable_preemption
10 *
11 * Disable preemption for a specified thread.
12 */
13.align 6
14.globl __disable_preemption
15.globl ___disable_preemption
16__disable_preemption:
17___disable_preemption:
18    /* Load the thread register. */
19    mrs    x0, tpidr_el1
20
21    /* Increment the thread register. */
22    ldr    w1, [x0, MACHINE_THREAD_PREEMPT_COUNT]
23    adds   w1, w1, #1
24    str    w1, [x0, MACHINE_THREAD_PREEMPT_COUNT]
25
26    /* Return. */
27    ret   lr
28
29/**
30 * get_preemption_level
31 *
32 * Return the current thread's preemption level.
33 */
34.align 6
35.globl _get_preemption_level
36_get_preemption_level:
37    mrs    x1, tpidr_el1
38    ldr    w0, [x1, MACHINE_THREAD_PREEMPT_COUNT]
39    ret    lr
40
41/**
42 * set_mmu_ttb/friends.
43 *
44 * You should know what this does.
45 */
46.align 6
47.globl _set_mmu_ttb
48.globl _set_mmu_ttb_alt
49.globl _set_mmu_ttbcr
50_set_mmu_ttb:
51    msr    ttbr0_el1, x0
52    ret    lr
53_set_mmu_ttb_alt:
54    msr    ttbr1_el1, x0
55    ret    lr
56_set_mmu_ttbcr:
57    msr    tcr_el1, x0
58    ret    lr
59
60/**
61 * ml_get_interupts_enabled
62 *
63 * Get the current interrupt state.
64 */
65.align 6
66.globl _ml_get_interrupts_enabled
67_ml_get_interrupts_enabled:
68    mrs    x0, daif
69    movz   x0, #1
70    bic    x0, x0, x1, lsr #7
71    ret    lr
72
73/**
74 * __enable_preemption
75 *
76 * Enable task preemption.
77 */
78.align 6
79.globl __enable_preemption
80.globl ___enable_preemption
81__enable_preemption:
82___enable_preemption:
83    mrs    x0, tpidr_el1
84
85    ldr    w1, [x0, MACHINE_THREAD_PREEMPT_COUNT]
86    subs   w1, w1, #1
87    str    w1, [x0, MACHINE_THREAD_PREEMPT_COUNT]
88
89    b.ne   .L_enable_preemption_out
90
91    /* Check for interrupts */
92    mrs    x2, daif
93    tst    x2, #0x80
94    b.ne   .L_enable_preemption_store_count
95
96    /* Get CPU data and add an AST. */
97    ldr    x3, [x0, MACHINE_THREAD_CPU_DATA]
98    add    x4, x3, CPU_PENDING_AST
99    str    w1, [x0, MACHINE_THREAD_PREEMPT_COUNT]
100
101    ands   x2, x4, #4
102    b.ne   .L_enable_preemption_preempt
103    ret    lr
104
105.L_enable_preemption_preempt:
106    orr    x2, x2, #(1 << 6)
107    msr    daif, x2
108    isb    sy
109
110    movz   x0, #7
111    movz   x1, #1
112    b      _ast_taken
113
114.L_enable_preemption_store_count:
115    str    w1, [x0, MACHINE_THREAD_PREEMPT_COUNT]
116
117.L_enable_preemption_out:
118    ret    lr
119
120/* lol. */
121.align 6
122.globl _ml_cause_interrupt
123_ml_cause_interrupt:
124    ret    lr
125
126
127/**
128 * current_thread
129 *
130 * Return the core thread structure of the currently executing thread.
131 */
132.align 6
133.globl _current_thread
134_current_thread:
135    mrs     x0, tpidr_el1
136    ret     lr
137