|
|
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.