|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved. ! 3: * ! 4: * @APPLE_LICENSE_HEADER_START@ ! 5: * ! 6: * The contents of this file constitute Original Code as defined in and ! 7: * are subject to the Apple Public Source License Version 1.1 (the ! 8: * "License"). You may not use this file except in compliance with the ! 9: * License. Please obtain a copy of the License at ! 10: * http://www.apple.com/publicsource and read it before using this file. ! 11: * ! 12: * This Original Code and all software distributed under the License are ! 13: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER ! 14: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, ! 15: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, ! 16: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the ! 17: * License for the specific language governing rights and limitations ! 18: * under the License. ! 19: * ! 20: * @APPLE_LICENSE_HEADER_END@ ! 21: */ ! 22: /* ! 23: * ! 24: * IOFWAddressSpace.cpp ! 25: * ! 26: * Classes which describe addresses in the local node which are accessable to other nodes ! 27: * via firewire asynchronous read/write/lock requests. ! 28: */ ! 29: #include <IOKit/firewire/IOFWAddressSpace.h> ! 30: ! 31: /* ! 32: * Base class for FireWire address space objects ! 33: */ ! 34: OSDefineMetaClass( IOFWAddressSpace, OSObject ) ! 35: OSDefineAbstractStructors(IOFWAddressSpace, OSObject) ! 36: ! 37: /* ! 38: * Direct physical memory <-> FireWire address. ! 39: * Accesses to these addresses will be handled automatically by the ! 40: * hardware without notification. ! 41: * ! 42: * The 64 bit FireWire address of (32 bit) physical addr xxxx:xxxx is hostNode:0000:xxxx:xxxx ! 43: */ ! 44: OSDefineMetaClassAndStructors(IOFWPhysicalAddressSpace, IOFWAddressSpace) ! 45: ! 46: bool IOFWPhysicalAddressSpace::initWithDesc(IOMemoryDescriptor *mem) ! 47: { ! 48: if(!IOFWAddressSpace::init()) ! 49: return false; ! 50: fMem = mem; ! 51: fLen = mem->getLength(); ! 52: { ! 53: vm_size_t pos; ! 54: IOPhysicalAddress phys; ! 55: pos = 0; ! 56: while(pos < fLen) { ! 57: IOPhysicalLength lengthOfSegment; ! 58: phys = fMem->getPhysicalSegment(pos, &lengthOfSegment); ! 59: pos += PAGE_SIZE - (phys & (PAGE_SIZE-1)); ! 60: } ! 61: } ! 62: ! 63: return true; ! 64: } ! 65: ! 66: UInt32 IOFWPhysicalAddressSpace::doRead(UInt16 nodeID, FWAddress addr, UInt32 len, ! 67: IOMemoryDescriptor **buf, IOByteCount * offset, ! 68: bool lockRead) ! 69: { ! 70: UInt32 res = kFWResponseAddressError; ! 71: vm_size_t pos; ! 72: IOPhysicalAddress phys; ! 73: if(addr.addressHi != 0) ! 74: return kFWResponseAddressError; ! 75: ! 76: pos = 0; ! 77: while(pos < fLen) { ! 78: IOPhysicalLength lengthOfSegment; ! 79: phys = fMem->getPhysicalSegment(pos, &lengthOfSegment); ! 80: if(addr.addressLo >= phys && addr.addressLo+len <= phys+lengthOfSegment) { ! 81: // OK, block is in space and is within one VM page ! 82: // Set position to exact start ! 83: *offset = pos + addr.addressLo - phys; ! 84: *buf = fMem; ! 85: res = kFWResponseComplete; ! 86: break; ! 87: } ! 88: pos += PAGE_SIZE - (phys & (PAGE_SIZE-1)); ! 89: } ! 90: return res; ! 91: } ! 92: ! 93: UInt32 IOFWPhysicalAddressSpace::doWrite(UInt16 nodeID, FWAddress addr, UInt32 len, ! 94: const void *buf, bool lockWrite) ! 95: { ! 96: UInt32 res = kFWResponseAddressError; ! 97: vm_size_t pos; ! 98: IOPhysicalAddress phys; ! 99: if(addr.addressHi != 0) ! 100: return kFWResponseAddressError; ! 101: ! 102: pos = 0; ! 103: while(pos < fLen) { ! 104: IOPhysicalLength lengthOfSegment; ! 105: phys = fMem->getPhysicalSegment(pos, &lengthOfSegment); ! 106: if(addr.addressLo >= phys && addr.addressLo+len <= phys+lengthOfSegment) { ! 107: // OK, block is in space and is within one VM page ! 108: // Set position to exact start ! 109: fMem->writeBytes(pos + addr.addressLo - phys, buf, len); ! 110: res = kFWResponseComplete; ! 111: break; ! 112: } ! 113: pos += PAGE_SIZE - (phys & (PAGE_SIZE-1)); ! 114: } ! 115: return res; ! 116: } ! 117: ! 118: /* ! 119: * Pseudo firewire addresses usually represent emulated registers of some kind. ! 120: * Accesses to these addresses will result in the owner being notified. ! 121: * ! 122: * Virtual addresses should not have zero as the top 16 bits of the 48 bit local address, ! 123: * since that may look like a physical address to hardware (eg. OHCI). ! 124: * if reader is NULL then reads will not be allowed. ! 125: * if writer is NULL then writes will not be allowed. ! 126: * if either is NULL then lock requests will not be allowed. ! 127: * refcon is passed back as the first argument of read and write callbacks. ! 128: */ ! 129: OSDefineMetaClassAndStructors(IOFWPseudoAddressSpace, IOFWAddressSpace) ! 130: ! 131: UInt32 IOFWPseudoAddressSpace::simpleReader(void *refcon, UInt16 nodeID, ! 132: FWAddress addr, UInt32 len, IOMemoryDescriptor **buf, ! 133: IOByteCount * offset, bool lockRead) ! 134: { ! 135: IOFWPseudoAddressSpace * space = (IOFWPseudoAddressSpace *)refcon; ! 136: *buf = space->fDesc; ! 137: *offset = addr.addressLo - space->fBase.addressLo; ! 138: ! 139: return kFWResponseComplete; ! 140: } ! 141: ! 142: UInt32 IOFWPseudoAddressSpace::simpleWriter(void *refcon, UInt16 nodeID, ! 143: FWAddress addr, UInt32 len, const void *buf, bool lockRead) ! 144: { ! 145: IOFWPseudoAddressSpace * space = (IOFWPseudoAddressSpace *)refcon; ! 146: space->fDesc->writeBytes(addr.addressLo - space->fBase.addressLo, buf, len); ! 147: ! 148: return kFWResponseComplete; ! 149: } ! 150: ! 151: IOFWPseudoAddressSpace * ! 152: IOFWPseudoAddressSpace::simpleRead(FWAddress addr, UInt32 len, const void *data) ! 153: { ! 154: IOFWPseudoAddressSpace * me; ! 155: me = new IOFWPseudoAddressSpace; ! 156: do { ! 157: if(!me) ! 158: break; ! 159: if(!me->initAll(addr, len, simpleReader, NULL, (void *)me)) { ! 160: me->release(); ! 161: me = NULL; ! 162: break; ! 163: } ! 164: me->fDesc = IOMemoryDescriptor::withAddress((void *)data, len, kIODirectionOut); ! 165: if(!me->fDesc) { ! 166: me->release(); ! 167: me = NULL; ! 168: } ! 169: } while(false); ! 170: ! 171: return me; ! 172: } ! 173: ! 174: IOFWPseudoAddressSpace *IOFWPseudoAddressSpace::simpleRW(FWAddress addr, UInt32 len, void *data) ! 175: { ! 176: IOFWPseudoAddressSpace * me; ! 177: me = new IOFWPseudoAddressSpace; ! 178: do { ! 179: if(!me) ! 180: break; ! 181: if(!me->initAll(addr, len, simpleReader, simpleWriter, (void *)me)) { ! 182: me->release(); ! 183: me = NULL; ! 184: break; ! 185: } ! 186: me->fDesc = IOMemoryDescriptor::withAddress(data, len, kIODirectionOut); ! 187: if(!me->fDesc) { ! 188: me->release(); ! 189: me = NULL; ! 190: } ! 191: } while(false); ! 192: ! 193: return me; ! 194: } ! 195: ! 196: bool IOFWPseudoAddressSpace::initAll(FWAddress addr, UInt32 len, ! 197: FWReadCallback reader, FWWriteCallback writer, void *refCon) ! 198: { ! 199: if(!IOFWAddressSpace::init()) ! 200: return false; ! 201: ! 202: fBase = addr; ! 203: fBase.addressHi &= 0xFFFF; // Mask off nodeID part. ! 204: fLen = len; ! 205: fDesc = NULL; // Only used by simpleRead case. ! 206: fRefCon = refCon; ! 207: fReader = reader; ! 208: fWriter = writer; ! 209: return true; ! 210: } ! 211: ! 212: void IOFWPseudoAddressSpace::free() ! 213: { ! 214: if(fDesc) ! 215: fDesc->release(); ! 216: IOFWAddressSpace::free(); ! 217: } ! 218: ! 219: UInt32 IOFWPseudoAddressSpace::doRead(UInt16 nodeID, FWAddress addr, UInt32 len, ! 220: IOMemoryDescriptor **buf, IOByteCount * offset, ! 221: bool lockRead) ! 222: { ! 223: if(addr.addressHi != fBase.addressHi) ! 224: return kFWResponseAddressError; ! 225: if(addr.addressLo < fBase.addressLo) ! 226: return kFWResponseAddressError; ! 227: if(addr.addressLo > fBase.addressLo+fLen) ! 228: return kFWResponseAddressError; ! 229: if(!fReader) ! 230: return kFWResponseTypeError; ! 231: if(lockRead && !fWriter) ! 232: return kFWResponseTypeError; ! 233: ! 234: return fReader(fRefCon, nodeID, addr, len, buf, offset, lockRead); ! 235: } ! 236: ! 237: UInt32 IOFWPseudoAddressSpace::doWrite(UInt16 nodeID, FWAddress addr, UInt32 len, ! 238: const void *buf, bool lockWrite) ! 239: { ! 240: if(addr.addressHi != fBase.addressHi) ! 241: return kFWResponseAddressError; ! 242: if(addr.addressLo < fBase.addressLo) ! 243: return kFWResponseAddressError; ! 244: if(addr.addressLo > fBase.addressLo+fLen) ! 245: return kFWResponseAddressError; ! 246: if(!fWriter) ! 247: return kFWResponseTypeError; ! 248: if(lockWrite && !fReader) ! 249: return kFWResponseTypeError; ! 250: ! 251: return fWriter(fRefCon, nodeID, addr, len, buf, lockWrite); ! 252: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.