1 /* $NetBSD: darwin_commpage.c,v 1.14 2008/03/30 20:58:08 christos Exp $ */
4 * Copyright (c) 2004 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
32 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD: darwin_commpage.c,v 1.14 2008/03/30 20:58:08 christos Exp $");
35 #include <sys/param.h>
36 #include <sys/kernel.h>
37 #include <sys/sysctl.h>
41 #include <compat/sys/signal.h>
42 #include <compat/sys/signalvar.h>
45 #include <machine/darwin_machdep.h>
47 #include <uvm/uvm_extern.h>
48 #include <uvm/uvm_map.h>
51 #include <compat/darwin/darwin_commpage.h>
53 /* XXX: this does not belong here! */
55 #include "opt_altivec.h"
59 #define DPRINTF(a) uprintf a
64 static struct uvm_object
*darwin_commpage_uao
= NULL
;
66 static void darwin_commpage_init(struct darwin_commpage
*);
69 darwin_commpage_map(struct proc
*p
)
77 * XXX This crashes. For now we map only one page,
78 * to avoid the crash, but this ought to be fixed
80 memsize
= round_page(sizeof(struct darwin_commpage
));
82 if (darwin_commpage_uao
== NULL
) {
83 darwin_commpage_uao
= uao_create(memsize
, 0);
84 kvaddr
= vm_map_min(kernel_map
);
86 error
= uvm_map(kernel_map
, &kvaddr
, memsize
,
87 darwin_commpage_uao
, 0, PAGE_SIZE
,
88 UVM_MAPFLAG(UVM_PROT_RW
, UVM_PROT_RW
,
89 UVM_INH_SHARE
, UVM_ADV_RANDOM
, 0));
91 DPRINTF(("kernel uvm_map darwin_compage failed "
92 "(error %d)\n", error
));
93 uao_detach(darwin_commpage_uao
);
94 darwin_commpage_uao
= NULL
;
98 error
= uvm_map_pageable(kernel_map
, kvaddr
,
99 kvaddr
+ memsize
, FALSE
, 0);
101 DPRINTF(("kernel uvm_map_pageable darwin_compage "
102 "failed (error %d)\n", error
));
103 uao_detach(darwin_commpage_uao
);
104 darwin_commpage_uao
= NULL
;
108 darwin_commpage_init((struct darwin_commpage
*)kvaddr
);
111 uao_reference(darwin_commpage_uao
);
112 pvaddr
= DARWIN_COMMPAGE_BASE
;
114 if ((error
= uvm_map(&p
->p_vmspace
->vm_map
, &pvaddr
,
115 memsize
, darwin_commpage_uao
, 0, 0,
116 UVM_MAPFLAG(UVM_PROT_RX
, UVM_PROT_RX
,
117 UVM_INH_SHARE
, UVM_ADV_NORMAL
, UVM_FLAG_FIXED
))) != 0) {
118 DPRINTF(("user uvm_map darwin_commpage failed at "
119 "0x%08lx/memsize (error %d)\n", (long)pvaddr
, error
));
123 DPRINTF(("mapped darwin_commpage at 0x%08lx\n", (long)pvaddr
));
128 #define DCP_MEMCPY(x) { \
131 len = (size_t)darwin_commpage_##x##_size; \
133 if (len > sizeof(dcp->dcp_##x)) { \
134 printf("darwin_commpage: %s too big (%zu/%zu)\n", #x, \
135 len, sizeof(dcp->dcp_##x)); \
137 memcpy(dcp->dcp_##x, (void *)darwin_commpage_##x, len); \
142 darwin_commpage_init(struct darwin_commpage
*dcp
)
145 * XXX Only one page is mapped yet (see higher in the file)
147 (void)memset(dcp
, 0, sizeof(*dcp
));
149 dcp
->dcp_version
= DARWIN_COMMPAGE_VERSION
;
150 dcp
->dcp_ncpu
= ncpu
;
151 dcp
->dcp_cap
|= (ncpu
<< DARWIN_CAP_NCPUSHIFT
);
155 dcp
->dcp_cap
|= DARWIN_CAP_UP
;
158 /* XXX: This needs to be processor specific */
161 dcp
->dcp_cap
|= DARWIN_CAP_ALTIVEC
;
164 #if defined(_LP64) && defined(DARWIN_CAP_64BIT)
166 dcp
->dcp_cap
|= DARWIN_CAP_64BIT
;
169 #ifndef CACHELINESIZE
170 #define CACHELINESIZE 32 /* for i386... */
172 dcp
->dcp_cachelinelen
= CACHELINESIZE
;
173 #if (CACHELINESIZE == 32)
174 dcp
->dcp_cap
|= DARWIN_CAP_CACHE32
;
175 #elif (CACHELINESIZE == 64)
176 dcp
->dcp_cap
|= DARWIN_CAP_CACHE64
;
177 #elif (CACHELINESIZE == 128)
178 dcp
->dcp_cap
|= DARWIN_CAP_CACHE128
;
181 dcp
->dcp_2pow52
= 4503599627370496ULL; /* 2^52 */
182 dcp
->dcp_10pow6
= 1000000ULL; /* 10^6 */
185 * On Darwin, these are maintained up to date by the kernel
187 dcp
->dcp_timebase
= 0; /* XXX */
188 dcp
->dcp_timestamp
= 0; /* XXX */
189 dcp
->dcp_secpertick
= hz
; /* XXX Not sure */
191 DCP_MEMCPY(mach_absolute_time
);
192 DCP_MEMCPY(spinlock_try
);
193 DCP_MEMCPY(spinlock_lock
);
194 DCP_MEMCPY(spinlock_unlock
);
195 DCP_MEMCPY(pthread_getspecific
);
196 DCP_MEMCPY(gettimeofday
);
197 DCP_MEMCPY(sys_dcache_flush
);
198 DCP_MEMCPY(sys_icache_invalidate
);
199 DCP_MEMCPY(pthread_self
);
200 DCP_MEMCPY(spinlock_relinquish
);