|
|
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: /* Copyright (c) 1991 NeXT Computer, Inc. All rights reserved.
25: *
26: * libIO.m - IO Library, kernel version.
27: *
28: * HISTORY
29: * 17-Apr-91 Doug Mitchell at NeXT
30: * Created.
31: *
32: * This file contains most of the kernel libIO implementation. Some portions
33: * deal with kernel task_t and thread_t structs directly; that code is
34: * in libIO_Private.m.
35: */
36:
37: #import <bsd/sys/types.h>
38: #import <objc/objc.h>
39: #import <driverkit/return.h>
40: #import <driverkit/memcpy.h>
41: #import <driverkit/generalFuncs.h>
42: #import <mach/mach_user_internal.h>
43: #import <mach/mach_interface.h>
44: #import <stdarg.h>
45: #import <machkit/NXLock.h>
46: #import <machine/mach_param.h>
47: #import <bsd/sys/syslog.h>
48: #import <bsd/sys/callout.h>
49: #import <bsd/dev/ldd.h>
50: #import <kernserv/ns_timer.h>
51: #import <kern/clock.h>
52:
53: /*
54: * Misc. kernel prototypes.
55: */
56:
57: extern port_name_t IOTask; // IOTask's task port
58:
59: /*
60: * Take this out when we have a kernel debugger that works.
61: */
62: extern int libIO_dbg;
63: #define cdprint(x) { \
64: if(libIO_dbg) { \
65: printf x; \
66: } \
67: }
68:
69: /*
70: * Kernel level libIO implementation.
71: */
72:
73: void *IOMalloc(int size)
74: {
75: return(kalloc(size));
76: }
77:
78: void IOFree(void *p, int size)
79: {
80: kfree(p, size);
81: }
82:
83: void IOCopyMemory(void *from, void *to, unsigned int numBytes,
84: unsigned int bytesPerTransfer)
85: {
86: _IOCopyMemory(from, to, numBytes, bytesPerTransfer);
87: }
88:
89:
90: void IOSleep(unsigned milliseconds)
91: {
92: ns_sleep((ns_time_t)(milliseconds) * 1000000LL);
93: }
94:
95: /*
96: * Spin for indicated number of microseconds.
97: */
98: void IODelay(unsigned microseconds)
99: {
100: DELAY(microseconds);
101: }
102:
103: /*
104: * Call function fcn with argument arg in specified number of seconds.
105: */
106: void IOScheduleFunc(IOThreadFunc fcn, void *arg, int seconds)
107: {
108: ns_time_t ns_time = (ns_time_t) seconds * 1000000000;
109:
110: ns_timeout((func)fcn, arg, ns_time, CALLOUT_PRI_THREAD);
111: }
112:
113: /*
114: * Cancel callout requested in IOScheduleFunc().
115: */
116: void IOUnscheduleFunc(IOThreadFunc fcn, void *arg)
117: {
118: ns_untimeout((func)fcn, arg);
119: }
120:
121: /*
122: * Obtain current time in nanoseconds.
123: */
124: void IOGetTimestamp(ns_time_t *nsp)
125: {
126: tvalspec_t now = clock_get_counter(System);
127:
128: *nsp = ((ns_time_t)now.tv_sec * NSEC_PER_SEC) + now.tv_nsec;
129: }
130:
131: void IOLog(const char *format, ...)
132: {
133: va_list ap;
134:
135: va_start(ap, format);
136: vlog(LOG_INFO, format, ap);
137: va_end(ap);
138: }
139:
140: /*
141: * Panic.
142: */
143: void IOPanic(const char *reason)
144: {
145: panic(reason);
146: }
147:
148:
149: /*
150: * Convert a integer constant (typically a #define or enum) to a string.
151: */
152: static char noValue[80];
153:
154: const char *IOFindNameForValue(int value, const IONamedValue *regValueArray)
155: {
156: for( ; regValueArray->name; regValueArray++) {
157: if(regValueArray->value == value)
158: return(regValueArray->name);
159: }
160: sprintf(noValue, "%d(d) (UNDEFINED)", value);
161: return((const char *)noValue);
162: }
163:
164: IOReturn IOFindValueForName(const char *string,
165: const IONamedValue *regValueArray,
166: int *value)
167: {
168: for( ; regValueArray->name; regValueArray++) {
169: if(!strcmp(regValueArray->name, string)) {
170: *value = regValueArray->value;
171: return IO_R_SUCCESS;
172: }
173: }
174: return IO_R_INVALID_ARG;
175: }
176:
177: IOAlignment IOSizeToAlignment(unsigned int size)
178: {
179: register int shift;
180: const intsize = sizeof(unsigned int) * 8;
181:
182: for (shift = 1; shift < intsize; shift++) {
183: if (size & 0x80000000)
184: return (IOAlignment)(intsize - shift);
185: size <<= 1;
186: }
187: return 0;
188: }
189:
190: unsigned int IOAlignmentToSize(IOAlignment align)
191: {
192: unsigned int size;
193:
194: for (size = 1; align; align--) {
195: size <<= 1;
196: }
197: return size;
198: }
199:
200: /*
201: * Temporary test of IOTask context.
202: */
203: #ifdef DEBUG
204: void iotaskTest()
205: {
206: kern_return_t krtn;
207: port_t port1;
208: port_t port2;
209: msg_header_t *msg1, *msg2;
210:
211: /*
212: * Allocate 2 ports.
213: */
214: krtn = port_allocate(task_self(), &port1);
215: if(krtn) {
216: printf("iotaskTest: port_allocate() returned %d\n", krtn);
217: return;
218: }
219: else {
220: cdprint(("...iotaskTest port1 %d\n", port1));
221: }
222: krtn = port_allocate(task_self(), &port2);
223: if(krtn) {
224: printf("iotaskTest: port_allocate() returned %d\n", krtn);
225: return;
226: }
227: else {
228: cdprint(("...iotaskTest port2 %d\n", port2));
229: }
230:
231: /*
232: * Send a dummy message from one port to another.
233: */
234: msg1 = IOMalloc(sizeof(*msg1));
235: msg1->msg_simple = 1;
236: msg1->msg_size = sizeof(*msg1);
237: msg1->msg_type = MSG_TYPE_NORMAL;
238: msg1->msg_local_port = port1;
239: msg1->msg_remote_port = port2;
240: msg1->msg_id = 123;
241: krtn = msg_send(msg1, SEND_TIMEOUT, 1);
242: if(krtn) {
243: printf("iotaskTest: msg_send() returned %d\n", krtn);
244: return;
245: }
246:
247: /*
248: * Receive the message.
249: */
250: msg2 = IOMalloc(sizeof(*msg2));
251: msg2->msg_size = sizeof(*msg2);
252: msg2->msg_local_port = port2;
253: krtn = msg_receive(msg2, RCV_TIMEOUT, 0);
254: if(krtn) {
255: printf("iotaskTest: msg_receive() returned %d\n", krtn);
256: return;
257: }
258: cdprint(("iotaskTest: SUCCESS\n"));
259: port_deallocate(task_self(), port1);
260: port_deallocate(task_self(), port2);
261: IOFree(msg1, sizeof(*msg1));
262: IOFree(msg2, sizeof(*msg2));
263: IOExitThread();
264: }
265: #endif DEBUG
266: /* end of libIO.m */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.