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 */
29static void arch_enable_ints(void);
30static void arch_disable_ints(void);
31static bool arch_ints_disabled(void);
32
33static uint64_t arch_cycle_count(void);
34
35static cpu_num_t arch_curr_cpu_num(void);
36static uint arch_max_num_cpus(void);
37static uint arch_cpu_features(void);
38
39void arch_disable_cache(uint flags);
40void arch_enable_cache(uint flags);
41
42void arch_clean_cache_range(addr_t start, size_t len);
43void arch_clean_invalidate_cache_range(addr_t start, size_t len);
44void arch_invalidate_cache_range(addr_t start, size_t len);
45void 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. */
51typedef struct event event_t;
52void arch_flush_state_and_halt(event_t *flush_done) __NO_RETURN;
53
54int arch_idle_thread_routine(void*) __NO_RETURN;
55
56/* function to call in spinloops to idle */
57static void arch_spinloop_pause(void);
58
59/* arch optimized version of a page zero routine against a page aligned buffer */
60void 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. */
72static inline bool arch_blocking_disallowed(void) {
73    return READ_PERCPU_FIELD32(blocking_disallowed);
74}
75
76static 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