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