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)72static inline bool arch_blocking_disallowed(void) { 73 return READ_PERCPU_FIELD32(blocking_disallowed); 74 } 75 arch_set_blocking_disallowed(bool value)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