1/*
2 * Copyright 2005-2008, Haiku Inc. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
4 */
5#ifndef _KERNEL_EXPORT_H
6#define _KERNEL_EXPORT_H
7
8
9#include <SupportDefs.h>
10#include <OS.h>
11
12
13/* interrupts and spinlocks */
14
15typedef ulong cpu_status;
16
17// WARNING: For Haiku debugging only! This changes the spinlock type in a
18// binary incompatible way!
19//#define B_DEBUG_SPINLOCK_CONTENTION	1
20
21#if B_DEBUG_SPINLOCK_CONTENTION
22	typedef struct {
23		int32	lock;
24		int32		failed_try_acquire;
25		bigtime_t	total_wait;
26		bigtime_t	total_held;
27		bigtime_t	last_acquired;
28	} spinlock;
29
30#	define B_SPINLOCK_INITIALIZER { 0, 0, 0, 0, 0 }
31#	define B_INITIALIZE_SPINLOCK(spinlock)	do {	\
32			(spinlock)->lock = 0;					\
33			(spinlock)->failed_try_acquire = 0;		\
34			(spinlock)->total_wait = 0;				\
35			(spinlock)->total_held = 0;				\
36			(spinlock)->last_acquired = 0;			\
37		} while (false)
38#else
39	typedef struct {
40		int32	lock;
41	} spinlock;
42
43#	define B_SPINLOCK_INITIALIZER { 0 }
44#	define B_INITIALIZE_SPINLOCK(spinlock)	do {	\
45			(spinlock)->lock = 0;					\
46		} while (false)
47#endif
48
49#define B_SPINLOCK_IS_LOCKED(spinlock)	(atomic_get(&(spinlock)->lock) > 0)
50
51typedef struct {
52	int32		lock;
53} rw_spinlock;
54
55#define B_RW_SPINLOCK_INITIALIZER	{ 0 }
56#define B_INITIALIZE_RW_SPINLOCK(rw_spinlock)	do {	\
57		(rw_spinlock)->lock = 0;						\
58	} while (false)
59
60typedef struct {
61	spinlock	lock;
62	uint32		count;
63} seqlock;
64
65#define B_SEQLOCK_INITIALIZER	{ B_SPINLOCK_INITIALIZER, 0 }
66#define B_INITIALIZE_SEQLOCK(seqlock)	do {		\
67		B_INITIALIZE_SPINLOCK(&(seqlock)->lock);	\
68		(seqlock)->count = 0;						\
69	} while (false)
70
71/* interrupt handling support for device drivers */
72
73typedef int32 (*interrupt_handler)(void *data);
74
75/* Values returned by interrupt handlers */
76#define B_UNHANDLED_INTERRUPT	0	/* pass to next handler */
77#define B_HANDLED_INTERRUPT		1	/* don't pass on */
78#define B_INVOKE_SCHEDULER		2	/* don't pass on; invoke the scheduler */
79
80/* Flags that can be passed to install_io_interrupt_handler() */
81#define B_NO_ENABLE_COUNTER		1
82
83
84/* timer interrupts services */
85
86typedef struct timer timer;
87typedef	int32 (*timer_hook)(timer *);
88
89struct timer {
90	struct timer *next;
91	int64		schedule_time;
92	void		*user_data;
93	uint16		flags;
94	uint16		cpu;
95	timer_hook	hook;
96	bigtime_t	period;
97};
98
99#define B_ONE_SHOT_ABSOLUTE_TIMER	1
100#define	B_ONE_SHOT_RELATIVE_TIMER	2
101#define	B_PERIODIC_TIMER			3
102
103
104/* virtual memory buffer functions */
105
106#define B_DMA_IO		0x00000001
107#define B_READ_DEVICE	0x00000002
108
109typedef struct {
110	phys_addr_t	address;	/* address in physical memory */
111	phys_size_t	size;		/* size of block */
112} physical_entry;
113
114/* address specifications for mapping physical memory */
115#define	B_ANY_KERNEL_BLOCK_ADDRESS	(B_ANY_KERNEL_ADDRESS + 1)
116
117/* area protection flags for the kernel */
118#define B_KERNEL_READ_AREA			(1 << 4)
119#define B_KERNEL_WRITE_AREA			(1 << 5)
120#define B_KERNEL_EXECUTE_AREA		(1 << 6)
121#define B_KERNEL_STACK_AREA			(1 << 7)
122
123/* MTR attributes for mapping physical memory (Intel Architecture only) */
124// TODO: rename those to something more meaningful
125#define	B_MTR_UC	0x10000000
126#define	B_MTR_WC	0x20000000
127#define	B_MTR_WT	0x30000000
128#define	B_MTR_WP	0x40000000
129#define	B_MTR_WB	0x50000000
130#define	B_MTR_MASK	0xf0000000
131
132
133/* kernel daemon service */
134
135typedef void (*daemon_hook)(void *arg, int iteration);
136
137
138/* kernel debugging facilities */
139
140/* special return codes for kernel debugger */
141#define  B_KDEBUG_CONT   2
142#define  B_KDEBUG_QUIT   3
143
144typedef int (*debugger_command_hook)(int argc, char **argv);
145
146
147#ifdef __cplusplus
148extern "C" {
149#endif
150
151/* interrupts, spinlock, and timers */
152extern cpu_status	disable_interrupts(void);
153extern void			restore_interrupts(cpu_status status);
154
155extern void			acquire_spinlock(spinlock *lock);
156extern void			release_spinlock(spinlock *lock);
157
158extern bool			try_acquire_write_spinlock(rw_spinlock* lock);
159extern void			acquire_write_spinlock(rw_spinlock* lock);
160extern void			release_write_spinlock(rw_spinlock* lock);
161extern bool			try_acquire_read_spinlock(rw_spinlock* lock);
162extern void			acquire_read_spinlock(rw_spinlock* lock);
163extern void			release_read_spinlock(rw_spinlock* lock);
164
165extern bool			try_acquire_write_seqlock(seqlock* lock);
166extern void			acquire_write_seqlock(seqlock* lock);
167extern void			release_write_seqlock(seqlock* lock);
168extern uint32		acquire_read_seqlock(seqlock* lock);
169extern bool			release_read_seqlock(seqlock* lock, uint32 count);
170
171extern status_t		install_io_interrupt_handler(int32 interrupt_number,
172						interrupt_handler handler, void *data, uint32 flags);
173extern status_t		remove_io_interrupt_handler(int32 interrupt_number,
174						interrupt_handler handler, void	*data);
175
176extern status_t		add_timer(timer *t, timer_hook hook, bigtime_t period,
177						int32 flags);
178extern bool			cancel_timer(timer *t);
179
180/* kernel threads */
181extern thread_id	spawn_kernel_thread(thread_func function,
182						const char *name, int32 priority, void *arg);
183
184/* signal functions */
185extern int			send_signal_etc(pid_t thread, uint signal, uint32 flags);
186
187/* virtual memory */
188extern status_t		lock_memory_etc(team_id team, void *buffer, size_t numBytes,
189						uint32 flags);
190extern status_t		lock_memory(void *buffer, size_t numBytes, uint32 flags);
191extern status_t		unlock_memory_etc(team_id team, void *address,
192						size_t numBytes, uint32 flags);
193extern status_t		unlock_memory(void *buffer, size_t numBytes, uint32 flags);
194extern status_t		get_memory_map_etc(team_id team, const void *address,
195						size_t numBytes, physical_entry *table,
196						uint32* _numEntries);
197extern int32		get_memory_map(const void *buffer, size_t size,
198						physical_entry *table, int32 numEntries);
199extern area_id		map_physical_memory(const char *areaName,
200						phys_addr_t physicalAddress, size_t size, uint32 flags,
201						uint32 protection, void **_mappedAddress);
202
203/* kernel debugging facilities */
204#if defined(_KERNEL_MODE) || defined(_BOOT_MODE)
205extern void			dprintf(const char *format, ...) _PRINTFLIKE(1, 2);
206#endif
207extern void			dvprintf(const char *format, va_list args);
208extern void			kprintf(const char *fmt, ...) _PRINTFLIKE(1, 2);
209
210extern void 		dump_block(const char *buffer, int size, const char *prefix);
211						/* TODO: temporary API: hexdumps given buffer */
212
213extern bool			set_dprintf_enabled(bool new_state);
214
215extern void			panic(const char *format, ...) _PRINTFLIKE(1, 2);
216
217extern void			kernel_debugger(const char *message);
218extern uint64		parse_expression(const char *string);
219
220extern int			add_debugger_command(const char *name,
221						debugger_command_hook hook, const char *help);
222extern int			remove_debugger_command(const char *name,
223						debugger_command_hook hook);
224
225/* Miscellaneous */
226extern void			spin(bigtime_t microseconds);
227
228extern status_t		register_kernel_daemon(daemon_hook hook, void *arg,
229						int frequency);
230extern status_t		unregister_kernel_daemon(daemon_hook hook, void *arg);
231
232extern void			call_all_cpus(void (*func)(void *, int), void *cookie);
233extern void			call_all_cpus_sync(void (*func)(void *, int), void *cookie);
234extern void			memory_read_barrier(void);
235extern void			memory_write_barrier(void);
236
237/* safe methods to access user memory without having to lock it */
238extern status_t		user_memcpy(void *to, const void *from, size_t size);
239extern ssize_t		user_strlcpy(char *to, const char *from, size_t size);
240extern status_t		user_memset(void *start, char c, size_t count);
241
242#ifdef __cplusplus
243}
244#endif
245
246#endif	/* _KERNEL_EXPORT_H */
247