1279377Simp/*
2279377Simp * Copyright (c) 2003-2009 Apple Inc. All rights reserved.
3279377Simp *
4279377Simp * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5279377Simp *
6279377Simp * This file contains Original Code and/or Modifications of Original Code
7279377Simp * as defined in and that are subject to the Apple Public Source License
8279377Simp * Version 2.0 (the 'License'). You may not use this file except in
9279377Simp * compliance with the License. The rights granted to you under the License
10279377Simp * may not be used to create, or enable the creation or redistribution of,
11279377Simp * unlawful or unlicensed copies of an Apple operating system, or to
12279377Simp * circumvent, violate, or enable the circumvention or violation of, any
13279377Simp * terms of an Apple operating system software license agreement.
14279377Simp *
15279377Simp * Please obtain a copy of the License at
16279377Simp * http://www.opensource.apple.com/apsl/ and read it before using this file.
17279377Simp *
18279377Simp * The Original Code and all software distributed under the License are
19279377Simp * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20279377Simp * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21279377Simp * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22279377Simp * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23279377Simp * Please see the License for the specific language governing rights and
24279377Simp * limitations under the License.
25279377Simp *
26279377Simp * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27279377Simp */
28279377Simp
29279377Simp#ifndef _I386_COMMPAGE_H
30279377Simp#define _I386_COMMPAGE_H
31279377Simp
32279377Simp#ifndef	__ASSEMBLER__
33279377Simp#include <stdint.h>
34279377Simp#include <mach/boolean.h>
35279377Simp#include <mach/vm_types.h>
36279377Simp#include <machine/cpu_capabilities.h>
37279377Simp#endif /* __ASSEMBLER__ */
38279377Simp
39279377Simp/* When trying to acquire a spinlock or mutex, we will spin in
40279377Simp * user mode for awhile, before entering the kernel to relinquish.
41279377Simp * MP_SPIN_TRIES is the initial value of _COMM_PAGE_SPIN_COUNT.
42279377Simp * The idea is that _COMM_PAGE_SPIN_COUNT will be adjusted up or
43279377Simp * down as the machine is plugged in/out, etc.
44279377Simp * At present spinlocks do not use _COMM_PAGE_SPIN_COUNT.
45279377Simp * They use MP_SPIN_TRIES directly.
46279377Simp */
47279377Simp#define	MP_SPIN_TRIES	1000
48279377Simp
49279377Simp
50279377Simp/* The following macro is used to generate the 64-bit commpage address for a given
51279377Simp * routine, based on its 32-bit address.  This is used in the kernel to compile
52279377Simp * the 64-bit commpage.  Since the kernel can be a 32-bit object, cpu_capabilities.h
53279377Simp * only defines the 32-bit address.
54279377Simp */
55279377Simp#define	_COMM_PAGE_32_TO_64( ADDRESS )	( ADDRESS + _COMM_PAGE64_START_ADDRESS - _COMM_PAGE32_START_ADDRESS )
56279377Simp
57279377Simp
58279377Simp#ifdef	__ASSEMBLER__
59279377Simp
60279377Simp#define COMMPAGE_DESCRIPTOR_NAME(label)  _commpage_ ## label
61279377Simp
62279377Simp#if defined (__i386__)
63279377Simp
64279377Simp#define COMMPAGE_DESCRIPTOR_FIELD_POINTER .long
65279377Simp#define COMMPAGE_DESCRIPTOR_REFERENCE(label) \
66279377Simp	.long COMMPAGE_DESCRIPTOR_NAME(label)
67279377Simp
68279377Simp#elif defined (__x86_64__)
69279377Simp
70279377Simp#define COMMPAGE_DESCRIPTOR_FIELD_POINTER .quad
71279377Simp#define COMMPAGE_DESCRIPTOR_REFERENCE(label) \
72279377Simp	.quad COMMPAGE_DESCRIPTOR_NAME(label)
73279377Simp
74279377Simp#else
75279377Simp#error unsupported architecture
76279377Simp#endif
77279377Simp
78279377Simp#define COMMPAGE_FUNCTION_START(label,codetype,alignment) \
79279377Simp.text								;\
80279377Simp.code ## codetype						;\
81279377Simp.align alignment, 0x90						;\
82279377SimpL ## label ## :
83279377Simp
84279377Simp#define	COMMPAGE_DESCRIPTOR(label,address)			\
85279377SimpL ## label ## _end:						;\
86279377Simp.set L ## label ## _size, L ## label ## _end - L ## label	;\
87279377Simp.const_data							;\
88279377Simp.private_extern COMMPAGE_DESCRIPTOR_NAME(label)			;\
89279377SimpCOMMPAGE_DESCRIPTOR_NAME(label) ## :				;\
90279377Simp    COMMPAGE_DESCRIPTOR_FIELD_POINTER	L ## label 		;\
91279377Simp    .long				L ## label ## _size	;\
92279377Simp    .long				address			;\
93279377Simp.text
94279377Simp
95279377Simp
96279377Simp/* COMMPAGE_CALL(target,from,start)
97279377Simp *
98279377Simp * This macro compiles a relative near call to one
99279377Simp * commpage routine from another.
100279377Simp * The assembler cannot handle this directly because the code
101279377Simp * is not being assembled at the address at which it will execute.
102279377Simp * The alternative to this macro would be to use an
103279377Simp * indirect call, which is slower because the target of an
104279377Simp * indirect branch is poorly predicted.
105279377Simp * The macro arguments are:
106279377Simp *	target = the commpage routine we are calling
107279377Simp *	from   = the commpage routine we are in now
108279377Simp *	start  = the label at the start of the code for this func
109279377Simp * This is admitedly ugly and fragile.  Is there a better way?
110279377Simp */
111279377Simp#define COMMPAGE_CALL(target,from,start)			\
112279377Simp	COMMPAGE_CALL_INTERNAL(target,from,start,__LINE__)
113279377Simp
114279377Simp#define COMMPAGE_CALL_INTERNAL(target,from,start,unique)	\
115279377Simp	.byte 0xe8						;\
116279377Simp.set UNIQUEID(unique), L ## start - . + target - from - 4	;\
117279377Simp	.long	UNIQUEID(unique)
118279377Simp
119279377Simp#define UNIQUEID(name)	L ## name
120279377Simp
121279377Simp#else /* __ASSEMBLER__ */
122279377Simp
123279377Simp/* Each potential commpage routine is described by one of these.
124279377Simp * Note that the COMMPAGE_DESCRIPTOR macro (above), used in
125279377Simp * assembly language, must agree with this.
126279377Simp */
127279377Simp
128279377Simptypedef	struct	commpage_descriptor	{
129279377Simp    void		*code_address;				// address of code
130279377Simp    uint32_t	 	code_length;				// length in bytes
131279377Simp    uint32_t		commpage_address;			// put at this address (_COMM_PAGE_BCOPY etc)
132279377Simp} commpage_descriptor;
133279377Simp
134279377Simp
135279377Simp/* Warning: following structure must match the layout of the commpage.  */
136279377Simp/* This is the data starting at _COMM_PAGE_TIME_DATA_START, ie for nanotime() and gettimeofday() */
137279377Simp
138279377Simptypedef	volatile struct	commpage_time_data	{
139279377Simp	uint64_t	nt_tsc_base;				// _COMM_PAGE_NT_TSC_BASE
140279377Simp	uint32_t	nt_scale;				// _COMM_PAGE_NT_SCALE
141279377Simp	uint32_t	nt_shift;				// _COMM_PAGE_NT_SHIFT
142279377Simp	uint64_t	nt_ns_base;				// _COMM_PAGE_NT_NS_BASE
143279377Simp	uint32_t	nt_generation;				// _COMM_PAGE_NT_GENERATION
144279377Simp	uint32_t	gtod_generation;			// _COMM_PAGE_GTOD_GENERATION
145279377Simp	uint64_t	gtod_ns_base;				// _COMM_PAGE_GTOD_NS_BASE
146279377Simp	uint64_t	gtod_sec_base;				// _COMM_PAGE_GTOD_SEC_BASE
147279377Simp} commpage_time_data;
148279377Simp
149279377Simp
150279377Simpextern	char	*commPagePtr32;				// virt address of 32-bit commpage in kernel map
151279377Simpextern	char	*commPagePtr64;				// ...and of 64-bit commpage
152279377Simp
153279377Simpextern	void	commpage_set_timestamp(uint64_t abstime, uint64_t secs);
154279377Simpextern	void	commpage_disable_timestamp( void );
155279377Simpextern  void	commpage_set_nanotime(uint64_t tsc_base, uint64_t ns_base, uint32_t scale, uint32_t shift);
156279377Simpextern	void	commpage_set_memory_pressure(unsigned int  pressure);
157279377Simpextern	void	commpage_set_spin_count(unsigned int  count);
158279377Simpextern	void	commpage_sched_gen_inc(void);
159279377Simpextern	void	commpage_update_active_cpus(void);
160279377Simp
161279377Simpextern	uint32_t	commpage_is_in_pfz32(uint32_t);
162279377Simpextern	uint32_t	commpage_is_in_pfz64(addr64_t);
163279377Simp
164279377Simp#endif	/* __ASSEMBLER__ */
165279377Simp
166279377Simp#endif /* _I386_COMMPAGE_H */
167279377Simp