1 // Copyright 2016 The Fuchsia Authors
2 // Copyright (c) 2008-2014 Travis Geiselbrecht
3 //
4 // Use of this source code is governed by a MIT-style
5 // license that can be found in the LICENSE file or at
6 // https://opensource.org/licenses/MIT
7 
8 #pragma once
9 
10 /* #defines for the cache routines below */
11 #define ICACHE 1
12 #define DCACHE 2
13 #define UCACHE (ICACHE|DCACHE)
14 
15 #ifndef __ASSEMBLER__
16 
17 #include <arch/defines.h>
18 #include <kernel/atomic.h>
19 #include <kernel/cpu.h>
20 #include <zircon/compiler.h>
21 #include <stdbool.h>
22 #include <stddef.h>
23 #include <stdint.h>
24 #include <sys/types.h>
25 
26 __BEGIN_CDECLS
27 
28 /* fast routines that most arches will implement inline */
29 static void arch_enable_ints(void);
30 static void arch_disable_ints(void);
31 static bool arch_ints_disabled(void);
32 
33 static uint64_t arch_cycle_count(void);
34 
35 static cpu_num_t arch_curr_cpu_num(void);
36 static uint arch_max_num_cpus(void);
37 static uint arch_cpu_features(void);
38 
39 void arch_disable_cache(uint flags);
40 void arch_enable_cache(uint flags);
41 
42 void arch_clean_cache_range(addr_t start, size_t len);
43 void arch_clean_invalidate_cache_range(addr_t start, size_t len);
44 void arch_invalidate_cache_range(addr_t start, size_t len);
45 void arch_sync_cache_range(addr_t start, size_t len);
46 
47 /* Used to suspend work on a CPU until it is further shutdown.
48  * This will only be invoked with interrupts disabled.  This function
49  * must not re-enter the scheduler.
50  * flush_done should be signaled after state is flushed. */
51 typedef struct event event_t;
52 void arch_flush_state_and_halt(event_t *flush_done) __NO_RETURN;
53 
54 int arch_idle_thread_routine(void*) __NO_RETURN;
55 
56 /* function to call in spinloops to idle */
57 static void arch_spinloop_pause(void);
58 
59 /* arch optimized version of a page zero routine against a page aligned buffer */
60 void arch_zero_page(void *);
61 
62 /* give the specific arch a chance to override some routines */
63 #include <arch/arch_ops.h>
64 
65 /* The arch_blocking_disallowed() flag is used to check that in-kernel interrupt
66  * handlers do not do any blocking operations.  This is a per-CPU flag.
67  * Various blocking operations, such as mutex_acquire(), contain assertions
68  * that arch_blocking_disallowed() is false.
69  *
70  * arch_blocking_disallowed() should only be true when interrupts are
71  * disabled. */
arch_blocking_disallowed(void)72 static inline bool arch_blocking_disallowed(void) {
73     return READ_PERCPU_FIELD32(blocking_disallowed);
74 }
75 
arch_set_blocking_disallowed(bool value)76 static inline void arch_set_blocking_disallowed(bool value) {
77     WRITE_PERCPU_FIELD32(blocking_disallowed, value);
78 }
79 
80 __END_CDECLS
81 
82 #endif // !__ASSEMBLER__
83