|
|
1.1 root 1: /*
2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
6: * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7: * Reserved. This file contains Original Code and/or Modifications of
8: * Original Code as defined in and that are subject to the Apple Public
9: * Source License Version 1.1 (the "License"). You may not use this file
10: * except in compliance with the License. Please obtain a copy of the
11: * License at http://www.apple.com/publicsource and read it before using
12: * this file.
13: *
14: * The Original Code and all software distributed under the License are
15: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
19: * License for the specific language governing rights and limitations
20: * under the License.
21: *
22: * @APPLE_LICENSE_HEADER_END@
23: */
24:
25: /*
26: * Copyright (c) 1993 NeXT Computer, Inc.
27: *
28: * PC support initialization.
29: *
30: * HISTORY
31: *
32: * 9 Mar 1993 ? at NeXT
33: * Created.
34: */
35:
36: #import <mach/mach_types.h>
37:
38: #import <kern/kern_port.h>
39:
40: #import <vm/vm_kern.h>
41:
42: #import "PCprivate.h"
43:
44: kern_return_t
45: PCcreate(
46: port_t th_port,
47: vm_offset_t paddress,
48: boolean_t anywhere
49: )
50: {
51: kern_return_t result;
52: task_t target_task = current_task();
53: vm_offset_t address;
54: thread_t thread;
55: kern_port_t th_kport;
56: PCprivate_t priv;
57:
58: if (!suser())
59: return (KERN_FAILURE);
60:
61: if (!anywhere) {
62: if (copyin(paddress, &address, sizeof (address)))
63: return (KERN_INVALID_ARGUMENT);
64:
65: address = trunc_page(address);
66: }
67: else
68: address = vm_map_min(target_task->map);
69:
70: if (!object_copyin(
71: target_task,
72: th_port, MSG_TYPE_PORT,
73: FALSE, (void *)&th_kport))
74: return (KERN_INVALID_ARGUMENT);
75:
76: thread = convert_port_to_thread(th_kport);
77:
78: port_release(th_kport);
79:
80: if (thread == THREAD_NULL)
81: return (KERN_INVALID_ARGUMENT);
82:
83: if (thread->pcb->PCpriv) {
84: if (anywhere) {
85: address = thread->pcb->PCpriv->taskShared;
86:
87: if (copyout(&address, paddress, sizeof (address)))
88: result = KERN_INVALID_ARGUMENT;
89: else
90: result = KERN_SUCCESS;
91: }
92: else {
93: if (address == thread->pcb->PCpriv->taskShared)
94: result = KERN_SUCCESS;
95: else
96: result = KERN_INVALID_ADDRESS;
97: }
98:
99: thread_deallocate(thread);
100:
101: return (result);
102: }
103:
104: result = vm_map_find(
105: target_task->map,
106: VM_OBJECT_NULL, 0,
107: &address, round_page(sizeof (struct PCshared)),
108: anywhere);
109:
110: if (result != KERN_SUCCESS) {
111: thread_deallocate(thread);
112:
113: return (result);
114: }
115:
116: if (anywhere) {
117: if (copyout(&address, paddress, sizeof (address))) {
118: thread_deallocate(thread);
119:
120: return (KERN_INVALID_ARGUMENT);
121: }
122: }
123:
124: vm_map_reference(target_task->map);
125:
126: priv = (PCprivate_t)kalloc(sizeof (struct PCprivate));
127: *priv = (struct PCprivate) { 0 };
128:
129: (void) kmem_alloc_wired(kernel_map,
130: (PCshared_t *)&priv->shared,
131: sizeof (struct PCshared));
132: priv->task = target_task->map;
133: priv->taskShared = address;
134:
135: pmap_enter_shared_range(
136: vm_map_pmap(priv->task),
137: priv->taskShared,
138: sizeof (struct PCshared),
139: (vm_offset_t)priv->shared);
140:
141: priv->shared->versionNumber = PCVERSIONNUMBER;
142: priv->shared->releaseNumber = PCRELEASENUMBER;
143:
144: thread->pcb->PCpriv = priv;
145:
146: thread_deallocate(thread);
147:
148: return (KERN_SUCCESS);
149: }
150:
151: void
152: PCdestroy(
153: thread_t thread
154: )
155: {
156: PCprivate_t priv = thread->pcb->PCpriv;
157:
158: pmap_remove(
159: vm_map_pmap(priv->task),
160: priv->taskShared,
161: round_page(priv->taskShared + sizeof (struct PCshared)));
162:
163: (void) vm_map_remove(
164: priv->task,
165: priv->taskShared,
166: round_page(priv->taskShared + sizeof (struct PCshared)));
167:
168: vm_map_deallocate(priv->task);
169:
170: PCcancelAllTimers(thread);
171:
172: kmem_free(
173: kernel_map,
174: (vm_offset_t)priv->shared,
175: round_page(sizeof (struct PCshared)));
176:
177: kfree(priv, sizeof (struct PCprivate));
178: }
179:
180: kern_return_t
181: PCldt(
182: port_t th_port,
183: vm_offset_t address,
184: vm_size_t size
185: )
186: {
187: kern_return_t result;
188: thread_t thread;
189: kern_port_t th_kport;
190: thread_saved_state_t *saved_state;
191:
192: if (!suser())
193: return (KERN_FAILURE);
194:
195: if (!object_copyin(
196: current_task(),
197: th_port, MSG_TYPE_PORT,
198: FALSE, (void *)&th_kport))
199: return (KERN_INVALID_ARGUMENT);
200:
201: thread = convert_port_to_thread(th_kport);
202:
203: port_release(th_kport);
204:
205: if (thread == THREAD_NULL)
206: return (KERN_INVALID_ARGUMENT);
207:
208: saved_state = USER_REGS(thread);
209:
210: if (address == (vm_offset_t)-1 && size == (vm_offset_t)-1)
211: result = task_default_ldt(thread->task);
212: else
213: result = task_locate_ldt(thread->task, address, size);
214:
215: if (result == KERN_SUCCESS) {
216: saved_state->frame.cs = UCODE_SEL;
217: saved_state->frame.ss = UDATA_SEL;
218: saved_state->regs.ds = UDATA_SEL;
219: saved_state->regs.es = UDATA_SEL;
220: saved_state->regs.fs = NULL_SEL;
221: saved_state->regs.gs = NULL_SEL;
222: }
223:
224: thread_deallocate(thread);
225:
226: return (result);
227: }
228:
229: kern_return_t
230: PCcopyBIOSData(
231: vm_address_t dest
232: )
233: {
234: if (dest == (vm_address_t)0)
235: return (KERN_INVALID_ARGUMENT);
236:
237: if (copyout((vm_address_t)BIOS_DATA_ADDR, dest, BIOS_DATA_SIZE))
238: return (KERN_INVALID_ARGUMENT);
239:
240: return (KERN_SUCCESS);
241: }
242:
243: vm_size_t
244: PCsizeBIOSExtData(void)
245: {
246: return (CNV_MEM_END_ADDR - bios_extdata_addr());
247: }
248:
249: kern_return_t
250: PCcopyBIOSExtData(
251: vm_address_t dest
252: )
253: {
254: vm_address_t data = bios_extdata_addr();
255:
256: if (dest == (vm_address_t)0)
257: return (KERN_INVALID_ARGUMENT);
258:
259: if (copyout(data, dest, CNV_MEM_END_ADDR - data))
260: return (KERN_INVALID_ARGUMENT);
261:
262: return (KERN_SUCCESS);
263: }
264:
265: kern_return_t
266: PCmapBIOSRom(
267: port_t task_port,
268: vm_offset_t paddress,
269: boolean_t anywhere
270: )
271: {
272: kern_return_t result;
273: vm_offset_t address;
274: task_t target_task;
275: kern_port_t task_kport;
276:
277: if (!anywhere) {
278: if (copyin(paddress, &address, sizeof (address)))
279: return (KERN_INVALID_ARGUMENT);
280:
281: address = trunc_page(address);
282: }
283: else
284: address = vm_map_min(target_task->map);
285:
286: if (!object_copyin(
287: current_task(),
288: task_port, MSG_TYPE_PORT,
289: FALSE, (void *)&task_kport))
290: return (KERN_INVALID_ARGUMENT);
291:
292: target_task = convert_port_to_task(task_kport);
293:
294: port_release(task_kport);
295:
296: if (target_task == TASK_NULL)
297: return (KERN_INVALID_ARGUMENT);
298:
299: result = vm_map_find(
300: target_task->map,
301: VM_OBJECT_NULL, 0,
302: &address, round_page(BIOS_ROM_SIZE),
303: anywhere);
304:
305: if (result != KERN_SUCCESS) {
306: task_deallocate(target_task);
307:
308: return (result);
309: }
310:
311: if (anywhere) {
312: if (copyout(&address, paddress, sizeof (address))) {
313: task_deallocate(target_task);
314:
315: return (KERN_INVALID_ARGUMENT);
316: }
317: }
318:
319: {
320: vm_offset_t end = round_page(address + BIOS_ROM_SIZE);
321: vm_offset_t phys = trunc_page(BIOS_ROM_ADDR);
322:
323: while (address < end) {
324: pmap_enter(
325: vm_map_pmap(target_task->map),
326: address,
327: phys,
328: VM_PROT_READ,
329: TRUE);
330:
331: address += PAGE_SIZE; phys += PAGE_SIZE;
332: }
333: }
334:
335: task_deallocate(target_task);
336:
337: return (KERN_SUCCESS);
338: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.