|
|
1.1 root 1: /*
2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
1.1.1.2 ! root 6: * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
1.1 root 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
1.1.1.2 ! root 9: * Source License Version 1.0 (the 'License'). You may not use this file
1.1 root 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
1.1.1.2 ! root 15: * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
1.1 root 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) 1992 NeXT Computer, Inc.
27: *
28: * Driverkit kernel support.
29: *
30: * HISTORY
31: *
32: * 15 Jan 1998 Martin Minow
33: * Added kern_IOCreateMachPort
34: * 28 Aug 1992 Joe Pasqua
35: * Use new interface to interrupt mechanism.
36: * 25 Aug 1992 Joe Pasqua
37: * Added minimal implementations of kern{IOAttach|Detach}Interrupt,
38: * kern_IOCreateDevicePort.
39: * 9 August 1992 ? at NeXT
40: * Created.
41: */
42:
43: #import <mach/mach_types.h>
44:
45: #import <ipc/ipc_space.h>
46:
47: #import <kern/kern_port.h>
48: #import <kern/task.h>
49:
50: #import <vm/vm_kern.h>
51:
52: #import <driverkit/generalFuncs.h>
53: #import <driverkit/IODevice.h>
54: #import <driverkit/IODeviceParams.h>
55: #import <driverkit/KernDevice.h>
56: #import <driverkit/KernDeviceDescription.h>
57: #import <driverkit/KernBus.h>
58: #import <driverkit/interruptMsg.h>
59: #import <driverkit/driverServerXXX.h>
60: #import <driverkit/autoconfCommon.h>
61: #import <driverkit/Device_ddm.h>
62: #import <driverkit/kernelDriver.h>
63: #import <driverkit/driverTypesPrivate.h>
64: #import <driverkit/configTableKern.h>
1.1.1.2 ! root 65:
! 66: #ifdef __i386__
! 67: #import <driverkit/i386/driverServer.h>
! 68: #import <driverkit/i386/EISAKernBus.h>
! 69: #endif
! 70:
! 71: #ifdef __ppc__
! 72: #import <driverkit/ppc/PPCKernBus.h>
! 73: #endif
! 74:
1.1 root 75: #import <sys/param.h>
76: #import <sys/systm.h>
77: #import <machkit/NXLock.h>
78: #import <objc/List.h>
79:
80: void
81: dev_server_init(
82: void
83: )
84: {
85: #if i386
86: /*
87: * Initialize dma controller(s).
88: */
89: dma_initialize();
90:
91: /*
92: * Initialize DMA lock mechanism.
93: */
94: initDmaLock();
95: #endif i386
96: }
97:
98: KernDevice *
99: convert_port_to_dev(
100: port_t dev_port
101: )
102: {
103: KernDevice *kernDevice = nil;
104: kern_port_t port = (kern_port_t)dev_port;
105:
106: if (port == IP_NULL)
107: return nil;
108:
109: ip_lock(port);
110:
111: if(ip_kotype(port) == IKOT_DEVICE)
112: kernDevice = (KernDevice *)port->ip_kobject;
113:
114: ip_unlock(port);
115:
116: return kernDevice;
117: }
118:
119: port_t
120: create_dev_port(
121: KernDevice *kernDevice
122: )
123: {
124: kern_port_t devicePort;
125: if ((devicePort = ipc_port_alloc_kernel()) == IP_NULL)
126: return (PORT_NULL);
127:
128: ipc_kobject_set(devicePort, (unsigned int)kernDevice, IKOT_DEVICE);
129:
130: return (IOConvertPort((port_t)devicePort,
131: IO_Kernel, IO_KernelIOTask));
132: }
133:
134: void
135: destroy_dev_port(
136: port_t port
137: )
138: {
139: kern_port_t devicePort;
140:
141: if (port != PORT_NULL) {
142: devicePort = (kern_port_t)IOConvertPort(port,
143: IO_KernelIOTask, IO_Kernel);
144: ip_lock(devicePort);
145: ipc_port_destroy(devicePort);
146: }
147: }
148:
149: /*
150: * Determine deviceType and deviceName of specified objectNumber.
151: */
152: IOReturn kern_IOLookupByObjectNumber(
153: host_t device_master,
154: IOObjectNumber objectNumber,
155: IOString *deviceKind, // returned
156: IOString *deviceName) // returned
157: {
158: if (device_master == HOST_NULL)
159: return IO_R_PRIVILEGE;
160:
161: return [IODevice lookupByObjectNumber:objectNumber
162: deviceKind:deviceKind
163: deviceName:deviceName];
164: }
165:
166: /*
167: * Determine deviceType and IOObjectNumber of specified IOString.
168: */
169: IOReturn kern_IOLookupByDeviceName(
170: host_t device_master,
171: IOString deviceName,
172: IOObjectNumber *objectNumber, // returned
173: IOString *deviceKind) // returned
174: {
175: if (device_master == HOST_NULL)
176: return IO_R_PRIVILEGE;
177:
178: return [IODevice lookupByDeviceName:deviceName
179: objectNumber:objectNumber
180: deviceKind:deviceKind];
181: }
182:
183: /*
184: * Get/set parameter RPCs.
185: */
186:
187: IOReturn kern_IOGetIntValues(
188: host_t device_master,
189: IOObjectNumber objectNumber,
190: IOParameterName parameterName,
191: unsigned int maxCount, // 0 means "as much as
192: // possible"
193: unsigned int *parameterArray, // data returned here
194: unsigned int *returnedCount) // size returned here
195: {
196: IOReturn rtn;
197: unsigned count = maxCount;
198:
199: if (device_master == HOST_NULL)
200: return IO_R_PRIVILEGE;
201:
202: rtn = [IODevice getIntValues:parameterArray
203: forParameter:parameterName
204: objectNumber:objectNumber
205: count:&count];
206: *returnedCount = count;
207: return rtn;
208: }
209:
210: IOReturn kern_IOGetCharValues(
211: host_t device_master,
212: IOObjectNumber objectNumber,
213: IOParameterName parameterName,
214: unsigned int maxCount, // 0 means "as much as
215: // possible"
216: unsigned char *parameterArray, // data returned here
217: unsigned int *returnedCount) // size returned here
218: {
219: IOReturn rtn;
220: unsigned count = maxCount;
221:
222: if (device_master == HOST_NULL)
223: return IO_R_PRIVILEGE;
224:
225: rtn = [IODevice getCharValues:parameterArray
226: forParameter:parameterName
227: objectNumber:objectNumber
228: count:&count];
229: *returnedCount = count;
230: return rtn;
231: }
232:
233: IOReturn kern_IOSetIntValues(
234: host_priv_t device_master,
235: IOObjectNumber objectNumber,
236: IOParameterName parameterName,
237: unsigned int *parameterArray,
238: unsigned int count) // size of parameterArray
239: {
240: if (device_master == HOST_NULL)
241: return IO_R_PRIVILEGE;
242:
243: return [IODevice setIntValues:parameterArray
244: forParameter:parameterName
245: objectNumber:objectNumber
246: count:count];
247: }
248:
249: IOReturn kern_IOSetCharValues(
250: host_t device_master,
251: IOObjectNumber objectNumber,
252: IOParameterName parameterName,
253: unsigned char *parameterArray,
254: unsigned int count) // size of parameterArray
255: {
256: if (device_master == HOST_NULL)
257: return IO_R_PRIVILEGE;
258:
259: return [IODevice setCharValues:parameterArray
260: forParameter:parameterName
261: objectNumber:objectNumber
262: count:count];
263: }
264:
265: IOReturn kern_IOLookUpByStringPropertyList(
266: host_priv_t device_master,
267: unsigned char * values,
268: unsigned int valuesLen, // Mig added
269: unsigned char * results,
270: unsigned int *returnedCount, // size returned here
271: unsigned int length)
272: {
273: IOReturn rtn;
274:
275: rtn = [IODevice lookUpByStringPropertyList:(const char *)values
276: results : (char *)results
277: maxLength : (unsigned int)length];
278:
279: if( rtn == IO_R_SUCCESS)
280: *returnedCount = strlen( results) + 1;
281:
282: return( rtn);
283: }
284:
285: IOReturn kern_IOGetStringPropertyList(
286: host_priv_t device_master,
287: IOObjectNumber objectNumber,
288: unsigned char * names,
289: unsigned int nameLen, // Mig added
290: unsigned char * results,
291: unsigned int *returnedCount, // size returned here. Mig added
292: unsigned int length)
293: {
294: IOReturn rtn;
295:
296: rtn = [IODevice getStringPropertyList:objectNumber
297: names : (const char *)names
298: results : (char *)results
299: maxLength : (unsigned int)length];
300:
301: if( rtn == IO_R_SUCCESS)
302: *returnedCount = strlen( results) + 1;
303:
304: return( rtn);
305: }
306:
307: IOReturn kern_IOGetByteProperty(
308: host_priv_t device_master,
309: IOObjectNumber objectNumber,
310: unsigned char * name,
311: unsigned int nameLen, // Mig added
312: unsigned char * results,
313: unsigned int *returnedCount, // size returned here. Mig added
314: unsigned int length)
315: {
316: IOReturn rtn;
317: *returnedCount = length;
318:
319: rtn = [IODevice getByteProperty:objectNumber
320: name : (const char *)name
321: results : (char *)results
322: maxLength : (unsigned int *)returnedCount];
323:
324: return( rtn);
325: }
326:
327: IOReturn kern_IOServerConnect(
328: host_t device_master,
329: IOObjectNumber objectNumber,
330: ipc_port_t taskIPCPort,
331: ipc_port_t *serverIPCPort)
332: {
333: extern task_t IOTask_kern; // kernel internal version of IOTask
334: IOReturn rtn;
335:
336: if (device_master == HOST_NULL)
337: return IO_R_PRIVILEGE;
338:
339: rtn = [IODevice serverConnect: (port_t *) serverIPCPort
340: objectNumber: objectNumber
341: taskPort: (port_t) taskIPCPort];
342: if (MACH_PORT_VALID(*serverIPCPort))
343: (void) ipc_object_copyin_compat(IOTask_kern->itk_space,
344: *serverIPCPort, MSG_TYPE_PORT, FALSE, serverIPCPort);
345:
346: return rtn;
347: }
348:
349: IOReturn kern_IOCallDeviceMethod(
350: host_priv_t device_master,
351: IOObjectNumber objectNumber,
352: char * methodName,
353: unsigned char *inputParams,
354: unsigned int inputCount, // size of parameterArray
355: unsigned int *maxCount, // caller's output buffer size
356: // on return the needed size
357: unsigned char *outputParams, // data returned here
358: unsigned int *returnedCount) // size to be returned here
359: {
360: IOReturn rtn;
361: unsigned count = *maxCount;
362:
363: rtn = [IODevice callDeviceMethod : methodName
364: inputParams : inputParams
365: inputCount : inputCount
366: outputParams : outputParams
367: outputCount : &count
368: privileged : device_master
369: objectNumber : objectNumber];
370:
371: if( count <= *maxCount)
372: *returnedCount = count; // how much was returned
373: else
374: *returnedCount = *maxCount;
375:
376: *maxCount = count; // how much is available
377:
378: return rtn;
379: }
380:
381: #ifdef i386
382:
383: IOReturn
384: kern_IOGetEISADeviceConfig(
385: KernDevice *device,
386: IOEISAInterruptList interrupts,
387: unsigned int *interruptNum,
388: IOEISADMAChannelList dmaChannels,
389: unsigned int *dmaChannelNum,
390: IOEISAPortMap ioRegions,
391: unsigned int *ioRegionNum,
392: IOEISAMemoryMap memoryRegions,
393: unsigned int *memoryRegionNum
394: )
395: {
396: int i, num;
397: Range range;
398: id list, deviceDescription;
399:
400: if (device == nil)
401: return IO_R_PRIVILEGE;
402:
403: deviceDescription = [device deviceDescription];
404:
405: list = [deviceDescription resourcesForKey:IRQ_LEVELS_KEY];
406: num = [list count];
407: if (num > IO_NUM_EISA_INTERRUPTS)
408: num = IO_NUM_EISA_INTERRUPTS;
409: for (i = 0; i < num; i++)
410: interrupts[i] = [[list objectAt:i] item];
411: *interruptNum = num;
412:
413: list = [deviceDescription resourcesForKey:DMA_CHANNELS_KEY];
414: num = [list count];
415: if (num > IO_NUM_EISA_DMA_CHANNELS)
416: num = IO_NUM_EISA_DMA_CHANNELS;
417: for (i = 0; i < num; i++)
418: dmaChannels[i] = [[list objectAt:i] item];
419: *dmaChannelNum = num;
420:
421: list = [deviceDescription resourcesForKey:IO_PORTS_KEY];
422: num = [list count];
423: if (num > IO_NUM_EISA_PORT_RANGES)
424: num = IO_NUM_EISA_PORT_RANGES;
425: for (i = 0; i < num; i++) {
426: range = [[list objectAt:i] range];
427: ioRegions[i].start = range.base;
428: ioRegions[i].size = range.length;
429: }
430: *ioRegionNum = num;
431:
432: list = [deviceDescription resourcesForKey:MEM_MAPS_KEY];
433: num = [list count];
434: if (num > IO_NUM_EISA_MEMORY_RANGES)
435: num = IO_NUM_EISA_MEMORY_RANGES;
436: for (i = 0; i < num; i++) {
437: range = [[list objectAt:i] range];
438: memoryRegions[i].start = range.base;
439: memoryRegions[i].size = range.length;
440: }
441: *memoryRegionNum = num;
442:
443: return IO_R_SUCCESS;
444: }
445:
446: IOReturn
447: kern_IOMapEISADevicePorts(
448: KernDevice *device,
449: thread_t thread
450: )
451: {
452: IOReturn rtn;
453:
454: if (device == nil)
455: return (IO_R_PRIVILEGE);
456:
457: if (thread->task->kernel_vm_space)
458: return (IO_R_SUCCESS);
459:
460: rtn = kern_dev_map_port_com(device, thread, FALSE);
461:
462: return (rtn);
463: }
464:
465: IOReturn
466: kern_IOUnMapEISADevicePorts(
467: KernDevice *device,
468: thread_t thread
469: )
470: {
471: IOReturn rtn;
472:
473: if (device == nil)
474: return (IO_R_PRIVILEGE);
475:
476: if (thread->task->kernel_vm_space)
477: return (IO_R_SUCCESS);
478:
479: rtn = kern_dev_map_port_com(device, thread, TRUE);
480:
481: return (rtn);
482: }
483:
484: IOReturn
485: kern_IOMapEISADeviceMemory(
486: KernDevice *device,
487: task_t task,
488: vm_offset_t phys,
489: vm_size_t length,
490: vm_offset_t *addr, // in/out
491: BOOL anywhere,
492: IOCache cache
493: )
494: {
495: IOReturn rtn;
496:
497: if (device == nil)
498: return IO_R_PRIVILEGE;
499:
500: rtn = kern_dev_map_phys(
501: device,
502: task->map,
503: phys,
504: length,
505: addr,
506: anywhere,
507: cache);
508:
509: return (rtn);
510: }
511:
512: IOReturn
513: kern_dev_map_port_com(
514: KernDevice *device,
515: thread_t thread,
516: boolean_t unmap
517: )
518: {
519: id list, deviceDescription;
520: Range range;
521: int i, num;
522:
523: deviceDescription = [device deviceDescription];
524:
525: list = [deviceDescription resourcesForKey:IO_PORTS_KEY];
526: num = [list count];
527:
528: /*
529: * Determine what is the highest port
530: * number we need to map.
531: */
532: for (i = 0; i < num; i++) {
533: range = [[list objectAt:i] range];
534: (void) task_map_io_ports(thread->task, range.base, range.length, unmap);
535: }
536:
537: return (IO_R_SUCCESS);
538: }
539:
540: #endif
541:
542: IOReturn
543: kern_dev_map_phys(
544: KernDevice *device,
545: vm_map_t map,
546: vm_offset_t phys,
547: vm_size_t length,
548: vm_offset_t *addr,
549: boolean_t anywhere,
550: IOCache cache
551: )
552: {
553: id list, deviceDescription;
554: kern_return_t result;
555: vm_offset_t vaddr;
556: Range range;
557: int i, num;
558: cache_spec_t caching;
559:
560: switch (cache) {
561:
562: case IO_CacheOff:
563: caching = cache_disable;
564: break;
565:
566: case IO_WriteThrough:
567: caching = cache_writethrough;
568: break;
569:
570: default:
571: caching = cache_default;
572: break;
573: }
574:
575: deviceDescription = [device deviceDescription];
576:
577: list = [deviceDescription resourcesForKey:MEM_MAPS_KEY];
578: num = [list count];
579:
580: for (i = 0; i < num; i++) {
581: range = [[list objectAt:i] range];
582: if (range.base <= phys &&
583: (range.base + range.length) >= (phys + length))
584: break;
585: }
586:
587: if (i == num)
588: return (IO_R_PRIVILEGE);
589:
590: if (anywhere)
591: *addr = vm_map_min(map);
592: else
593: *addr = trunc_page(*addr);
594:
595: if (map == kernel_map) {
596: if (!anywhere &&
597: *addr < 1*1024*1024) // In the hole... (between 640K and 1M)
598: return (IO_R_SUCCESS);
599: }
600:
601: result = vm_map_find(
602: map,
603: VM_OBJECT_NULL, (vm_offset_t) 0,
604: addr, length,
605: anywhere);
606:
607: if (result != KERN_SUCCESS)
608: return (IO_R_NO_SPACE);
609:
610: vaddr = *addr;
611: vaddr = trunc_page(vaddr);
612: length = round_page(length);
613:
614: (void) vm_map_inherit(
615: map,
616: vaddr, vaddr + length,
617: VM_INHERIT_NONE);
618:
619: phys = trunc_page(phys);
620:
621: while (length > 0) {
622: pmap_enter_cache_spec(
623: map->pmap,
624: vaddr,
625: phys,
626: VM_PROT_READ | VM_PROT_WRITE,
627: TRUE,
628: caching);
629:
630: vaddr += PAGE_SIZE; length -= PAGE_SIZE; phys += PAGE_SIZE;
631: }
632:
633: return (IO_R_SUCCESS);
634: }
635:
636: IOReturn
637: kern_IOProbeDriver(host_priv_t device_master,
638: unsigned char *configData,
639: unsigned int count)
640: {
641: struct probeDriverArgs args;
642: NXConditionLock *loadDeviceLock;
643: char *configString;
644:
645: if (device_master == HOST_NULL)
646: return IO_R_PRIVILEGE;
647:
648: configString = IOMalloc(count + 1);
649: if (configString == NULL)
650: return IO_R_NO_SPACE;
651: bcopy(configData, configString, count);
652: configString[count] = '\0';
653:
654: /*
655: * We need to configure the driver from the IOTask context, so...
656: */
657:
658: /*
659: * Set up a lock so we know when autoconf is complete.
660: */
661: loadDeviceLock = [NXConditionLock alloc];
662: [loadDeviceLock initWith:NO];
663:
664: args.waitLock = loadDeviceLock;
665: args.configData = configString;
666: IOForkThread((IOThreadFunc) configureThread, (void *) &args);
667:
668: [loadDeviceLock lockWhen:YES];
669: [loadDeviceLock free];
670: IOFree(configString, count + 1);
671:
672: return (args.rtn ? IO_R_SUCCESS : IO_R_NO_DEVICE);
673: }
674:
675: extern const char *findBootConfigString(int n);
676:
677: IOReturn kern_IOGetDriverConfig(host_t device_master,
678: unsigned driverNum,
679: unsigned maxDataSize,
680: IOConfigData configData,
681: unsigned int *configDataCnt)
682: {
683: int configLength;
684: const char *configString;
685:
686: if (device_master == HOST_NULL)
687: return IO_R_PRIVILEGE;
688:
689: if(maxDataSize > (IO_CONFIG_TABLE_SIZE - 1)) {
690: maxDataSize = IO_CONFIG_TABLE_SIZE - 1;
691: }
692: configString = findBootConfigString(driverNum);
693: if (configString == NULL) {
694: return IO_R_NO_DEVICE;
695: }
696: configLength = strlen(configString);
697: if(maxDataSize > configLength) {
698: maxDataSize = configLength;
699: }
700: bcopy(configString, configData, maxDataSize);
701: configData[maxDataSize] = '\0';
702: *configDataCnt = maxDataSize + 1;
703: return IO_R_SUCCESS;
704: }
705:
706: IOReturn kern_IOGetSystemConfig(host_t device_master,
707: unsigned maxDataSize,
708: IOConfigData configData,
709: unsigned int *configDataCnt)
710: {
711: return kern_IOGetDriverConfig(
712: device_master,
713: 0,
714: maxDataSize,
715: configData,
716: configDataCnt);
717: }
718:
719: IOReturn kern_IOUnloadDriver(host_t device_master,
720: IOConfigData configData,
721: unsigned int configDataSize)
722: {
723: const char *className;
724: IOConfigTable *configTable = nil;
725: Class theClass;
726:
727: if (device_master == HOST_NULL)
728: return IO_R_PRIVILEGE;
729:
730: configTable = [IOConfigTable newForConfigData:configData];
731: className = [configTable valueForStringKey:"Driver Name"];
732: theClass = objc_getClass(className);
733: if (theClass == nil) {
734: IOLog("IOUnloadDriver: Couldn't find class named %s\n",
735: className);
736: if(configTable)
737: [configTable free];
738: return IO_R_INVALID_ARG;
739: }
740:
741: [theClass unregisterClass: theClass];
742: if (configTable)
743: [configTable free];
744: // FIXME: should we do [theClass free] here?
745: return IO_R_SUCCESS;
746: }
747:
748: #if defined(hppa) || defined(sparc) /* [*/
749:
750: static int mapfun(
751: dev_t dev,
752: vm_offset_t addr,
753: int prot
754: )
755: {
756: vm_offset_t phys = pmap_extract(kernel_pmap, addr);
757: return(atop(phys));
758: }
759:
760: IOReturn kern_IOMapLockShmem(
761: KernDevice *device,
762: task_t task,
763: vm_size_t size,
764: vm_offset_t *shmem)
765: {
766: vm_object_t vmobject;
767: vm_map_t task_map;
768:
769: task_map = task->map;
770: if (task_map == VM_MAP_NULL)
771: return(IO_R_VM_FAILURE);
772: size = round_page(size);
773:
774: /* Create a fake object to "hold" these pages for user mapping. */
775: vmobject = (vm_object_t)vm_object_special(0, mapfun, 0, *shmem, size);
776:
777: /*
778: ** Find some memory of the same size in 'task'. We use vm_map_find()
779: ** to do this. vm_map_find inserts the found memory object in the
780: ** target task's map as a side effect. Ensure that the addresses
781: ** are equivalently mapped to avoid aliasing problems.
782: */
783: if (vm_map_find(task_map, vmobject, 0, shmem, size, FALSE))
784: { // OK, can't get that, so let it find memory
785: if (vm_map_find(task_map, vmobject, 0, shmem, size, TRUE))
786: return(IO_R_NO_MEMORY);
787: }
788:
789: return(IO_R_SUCCESS);
790: }
791:
792: IOReturn kern_IOUnMapLockShmem(
793: KernDevice *device,
794: task_t task,
795: vm_size_t size,
796: vm_offset_t *shmem)
797: {
798: vm_offset_t off;
799: kern_return_t krtn;
800: vm_map_t task_map;
801:
802: task_map = task->map;
803: if (task_map == VM_MAP_NULL)
804: return(IO_R_VM_FAILURE);
805: size = round_page(size);
806:
807: // Pull the shared pages out of the task map
808: for ( off = 0; off < size; off += PAGE_SIZE )
809: {
810: pmap_remove(task_map->pmap, *shmem + off, *shmem + off + PAGE_SIZE);
811: }
812: // Free the former shmem area in the task
813: krtn = vm_map_remove(task_map, *shmem, *shmem + size );
814: if (krtn)
815: {
816: IOLog("IOUnMapLockShmem: vm_map_remove() returned %d\n", krtn);
817: }
818:
819: // This deallocate is commented out because it caused some strange
820: // kernel hang -- Should be looked into some time.
821: // Possibly the ref_cnt is not properly incremented.
822: // vm_map_deallocate(task_map); // discard our reference
823: return(krtn);
824: }
825: #endif /*]*/
826:
827: IOReturn
828: kern_IOMapDeviceMemory(
829: KernDevice *device,
830: task_t task,
831: vm_offset_t phys,
832: vm_size_t length,
833: vm_offset_t *addr, // in/out
834: BOOL anywhere,
835: IOCache cache
836: )
837: {
838: IOReturn rtn;
839:
840: if (device == nil)
841: return IO_R_PRIVILEGE;
842:
843: rtn = kern_dev_map_phys(
844: device,
845: task->map,
846: phys,
847: length,
848: addr,
849: anywhere,
850: cache);
851:
852: return (rtn);
853: }
854:
855: #if hppa /* [ */
856: IOReturn
857: kern_IOGetDeviceConfig(
858: KernDevice *device,
859: IOHPPAInterruptList interrupts,
860: unsigned int *interruptNum,
861: IOHPPAMemoryMap memoryRegions,
862: unsigned int *memoryRegionNum
863: )
864: {
865: int i, num;
866: Range range;
867: id list, deviceDescription;
868:
869: if (device == nil)
870: return IO_R_PRIVILEGE;
871:
872: deviceDescription = [device deviceDescription];
873:
874: list = [deviceDescription resourcesForKey:IRQ_LEVELS_KEY];
875: num = [list count];
876: if (num > IO_NUM_HPPA_INTERRUPTS)
877: num = IO_NUM_HPPA_INTERRUPTS;
878: for (i = 0; i < num; i++)
879: interrupts[i] = [[list objectAt:i] item];
880: *interruptNum = num;
881:
882: list = [deviceDescription resourcesForKey:MEM_MAPS_KEY];
883: num = [list count];
884: if (num > IO_NUM_HPPA_MEMORY_RANGES)
885: num = IO_NUM_HPPA_MEMORY_RANGES;
886: for (i = 0; i < num; i++) {
887: range = [[list objectAt:i] range];
888: memoryRegions[i].start = range.base;
889: memoryRegions[i].size = range.length;
890: }
891: *memoryRegionNum = num;
892:
893: return IO_R_SUCCESS;
894: }
895: #endif /* ] */
896:
897: #if sparc /*[*/
898:
899: IOReturn
900: kern_IOMapSparcDeviceMemory(
901: KernDevice *device,
902: task_t task,
903: vm_offset_t phys,
904: vm_size_t length,
905: vm_offset_t *addr, // in/out
906: BOOL anywhere,
907: IOCache cache
908: )
909: {
910: IOReturn rtn;
911: id list, deviceDescription;
912: kern_return_t result;
913: vm_offset_t vaddr;
914: vm_map_t map;
915: Range range;
916: int i, num;
917: cache_spec_t caching;
918: unsigned int paddr,spaceid;
919:
920: if (device == nil)
921: return IO_R_PRIVILEGE;
922: map = task->map;
923: if (anywhere)
924: *addr = vm_map_min(map);
925: else
926: *addr = trunc_page(*addr);
927: #if 0
928: // needed only for intel
929: if (map == kernel_map) {
930: if (!anywhere &&
931: *addr < 1*1024*1024) // In the hole... (between 640K and 1M)
932: return (IO_R_SUCCESS);
933: }
934: #endif
935: result = vm_map_find(
936: map,
937: VM_OBJECT_NULL, (vm_offset_t) 0,
938: addr, length,
939: anywhere);
940:
941: if (result != KERN_SUCCESS)
942: return (IO_R_NO_SPACE);
943: vaddr = *addr;
944: vaddr = trunc_page(vaddr);
945: length = round_page(length);
946:
947: (void) vm_map_inherit(
948: map,
949: vaddr, vaddr + length,
950: VM_INHERIT_NONE);
951: // Mapping the frame buffer in user context
952: spaceid = (phys ) & 0x0f; // 4bits space id which is packed in bits 24-31;
953: paddr = ((unsigned int)(phys & 0xffffff00));
954: pmap_enter_range( map->pmap,
955: vaddr, paddr,
956: spaceid, length,
957: VM_PROT_READ | VM_PROT_WRITE, FALSE, TRUE );
958: return (IO_R_SUCCESS);
959:
960:
961: }
962:
963: IOReturn
964: kern_IOGetDeviceConfig(
965: KernDevice *device,
966: IOSPARCInterruptList interrupts,
967: unsigned int *interruptNum,
968: IOSPARCMemoryMap memoryRegions,
969: unsigned int *memoryRegionNum
970: )
971: {
972: int i, num;
973: Range range;
974: id list, deviceDescription;
975:
976: if (device == nil)
977: return IO_R_PRIVILEGE;
978:
979: deviceDescription = [device deviceDescription];
980:
981: list = [deviceDescription resourcesForKey:IRQ_LEVELS_KEY];
982: num = [list count];
983: if (num > IO_NUM_SPARC_INTERRUPTS)
984: num = IO_NUM_SPARC_INTERRUPTS;
985: for (i = 0; i < num; i++)
986: interrupts[i] = [[list objectAt:i] item];
987: *interruptNum = num;
988:
989: list = [deviceDescription resourcesForKey:MEM_MAPS_KEY];
990: num = [list count];
991: if (num > IO_NUM_SPARC_MEMORY_RANGES)
992: num = IO_NUM_SPARC_MEMORY_RANGES;
993: for (i = 0; i < num; i++) {
994: range = [[list objectAt:i] range];
995: memoryRegions[i].start = range.base;
996: memoryRegions[i].size = range.length;
997: }
998: *memoryRegionNum = num;
999:
1000: return IO_R_SUCCESS;
1001: }
1002:
1003:
1004: #endif /*]*/
1005:
1006: #if ppc /* [ */
1007: IOReturn
1008: kern_IOGetDeviceConfig(
1009: KernDevice *device,
1010: IOPPCInterruptList interrupts,
1011: unsigned int *interruptNum,
1012: #ifdef notyet
1013: IOPPCDMAChannelList dmaChannels,
1014: unsigned int *dmaChannelNum,
1015: #endif
1016: IOPPCMemoryMap memoryRegions,
1017: unsigned int *memoryRegionNum
1018: )
1019: {
1020: int i, num;
1021: Range range;
1022: id list, deviceDescription;
1023:
1024: if (device == nil)
1025: return IO_R_PRIVILEGE;
1026:
1027: deviceDescription = [device deviceDescription];
1028:
1029: list = [deviceDescription resourcesForKey:IRQ_LEVELS_KEY];
1030: num = [list count];
1031: if (num > IO_NUM_PPC_INTERRUPTS)
1032: num = IO_NUM_PPC_INTERRUPTS;
1033: for (i = 0; i < num; i++)
1034: interrupts[i] = [[list objectAt:i] item];
1035: *interruptNum = num;
1036:
1037: #ifdef notyet
1038: list = [deviceDescription resourcesForKey:DMA_CHANNELS_KEY];
1039: num = [list count];
1040: if (num > IO_NUM_PPC_DMA_CHANNELS)
1041: num = IO_NUM_PPC_DMA_CHANNELS;
1042: for (i = 0; i < num; i++)
1043: dmaChannels[i] = [[list objectAt:i] item];
1044: *dmaChannelNum = num;
1045: #endif
1046: list = [deviceDescription resourcesForKey:MEM_MAPS_KEY];
1047: num = [list count];
1048: if (num > IO_NUM_PPC_MEMORY_RANGES)
1049: num = IO_NUM_PPC_MEMORY_RANGES;
1050: for (i = 0; i < num; i++) {
1051: range = [[list objectAt:i] range];
1052: memoryRegions[i].start = range.base;
1053: memoryRegions[i].size = range.length;
1054: }
1055: *memoryRegionNum = num;
1056:
1057:
1058:
1059: return IO_R_SUCCESS;
1060: }
1061: #endif /* ] */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.