UInt32 FakeSMCKeyStore::addKeysFromDictionary(OSDictionary* dictionary)
{
    UInt32 keysAdded = 0;

    if (dictionary) {
        if (OSIterator *iterator = OSCollectionIterator::withCollection(dictionary)) {
            while (const OSSymbol *key = (const OSSymbol *)iterator->getNextObject()) {
                if (OSArray *array = OSDynamicCast(OSArray, dictionary->getObject(key))) {
                    if (OSIterator *aiterator = OSCollectionIterator::withCollection(array)) {

                        OSString *type = OSDynamicCast(OSString, aiterator->getNextObject());
                        OSData *value = OSDynamicCast(OSData, aiterator->getNextObject());

                        if (type && value) {
                            addKeyWithValue(key->getCStringNoCopy(), type->getCStringNoCopy(), value->getLength(), value->getBytesNoCopy());
                            keysAdded++;
                        }

                        OSSafeRelease(aiterator);
                    }
                }
                key = 0;
            }
            
            OSSafeRelease(iterator);
        }
    }

    return keysAdded;
}
Exemplo n.º 2
0
UInt32 FakeSMCDevice::loadKeysFromNVRAM()
{
    UInt32 count = 0;
    
    // Find driver and load keys from NVRAM
    if (OSDictionary *matching = serviceMatching("IODTNVRAM")) {
        if (IODTNVRAM *nvram = OSDynamicCast(IODTNVRAM, waitForMatchingService(matching, 1000000000ULL * 15))) {
            
            useNVRAM = true;
            
            if ((genericNVRAM = (0 == strncmp(nvram->getName(), "AppleNVRAM", sizeof("AppleNVRAM")))))
                HWSensorsInfoLog("fallback to generic NVRAM methods");
            
            OSSerialize *s = OSSerialize::withCapacity(0); // Workaround for IODTNVRAM->getPropertyTable returns IOKitPersonalities instead of NVRAM properties dictionary
            
            if (nvram->serializeProperties(s)) {
                if (OSDictionary *props = OSDynamicCast(OSDictionary, OSUnserializeXML(s->text()))) {
                    if (OSCollectionIterator *iterator = OSCollectionIterator::withCollection(props)) {
                        
                        size_t prefix_length = strlen(kFakeSMCKeyPropertyPrefix);
                        
                        char name[5]; name[4] = 0;
                        char type[5]; type[4] = 0;
                        
                        while (OSString *property = OSDynamicCast(OSString, iterator->getNextObject())) {
                            const char *buffer = static_cast<const char *>(property->getCStringNoCopy());
                            
                            if (property->getLength() >= prefix_length + 1 + 4 + 1 + 0 && 0 == strncmp(buffer, kFakeSMCKeyPropertyPrefix, prefix_length)) {
                                if (OSData *data = OSDynamicCast(OSData, props->getObject(property))) {
                                    strncpy(name, buffer + prefix_length + 1, 4); // fakesmc-key-???? ->
                                    strncpy(type, buffer + prefix_length + 1 + 4 + 1, 4); // fakesmc-key-xxxx-???? ->
                                    
                                    if (addKeyWithValue(name, type, data->getLength(), data->getBytesNoCopy())) {
                                        HWSensorsDebugLog("key %s of type %s loaded from NVRAM", name, type);
                                        count++;
                                    }
                                }
                            }
                        }
                        
                        OSSafeRelease(iterator);
                    }
                    
                    OSSafeRelease(props);
                }
            }
            
            OSSafeRelease(s);
            OSSafeRelease(nvram);
        }
        else {
            HWSensorsWarningLog("NVRAM is unavailable");
        }
        
        OSSafeRelease(matching);
    }
    
    return count;
}
Exemplo n.º 3
0
IOReturn FakeSMCDevice::callPlatformFunction(const OSSymbol *functionName, bool waitForFunction, void *param1, void *param2, void *param3, void *param4 )
{
    IOReturn result = kIOReturnUnsupported;
    
    if (functionName->isEqualTo(kFakeSMCAddKeyHandler)) {
        
        result = kIOReturnBadArgument;
        
        if (param1 && param2 && param3 && param4) {
            const char *name = (const char *)param1;
            const char *type = (const char *)param2;
            UInt8 size = (UInt64)param3;
            IOService *handler = (IOService*)param4;
            
            if (name && type && size > 0 && handler) {
                if (addKeyWithHandler(name, type, size, handler))
                    result = kIOReturnSuccess;
                else
                    result = kIOReturnError;
            }
        }
	}
    else if (functionName->isEqualTo(kFakeSMCGetKeyHandler)) {
        
        result = kIOReturnBadArgument;
        
        if (const char *name = (const char *)param1) {
            
            result = kIOReturnError;
            
            if (FakeSMCKey *key = OSDynamicCast(FakeSMCKey, getKey(name))) {
                
                result = kIOReturnSuccess;
                
                if (key->getHandler()) {
                    
                    result = kIOReturnBadArgument;
                    
                    if (param2) {
                        IOService **handler = (IOService**)param2;
                        *handler = key->getHandler();
                        result = kIOReturnSuccess;
                    }
                }
            }
        }
	}
    else if (functionName->isEqualTo(kFakeSMCRemoveKeyHandler)) {
        
        result = kIOReturnBadArgument;
        
        if (param1) {
            result = kIOReturnError;
            
            if (OSCollectionIterator *iterator = OSCollectionIterator::withCollection(keys)) {
                IOService *handler = (IOService *)param1;
                while (FakeSMCKey *key = OSDynamicCast(FakeSMCKey, iterator->getNextObject())) {
                    if (key->getHandler() == handler)
                        key->setHandler(NULL);
                }
                result = kIOReturnSuccess;
                OSSafeRelease(iterator);
            }
        }
    }
    else if (functionName->isEqualTo(kFakeSMCAddKeyValue)) {
        
        result = kIOReturnBadArgument;
        
        if (param1 && param2 && param3) {
            const char *name = (const char *)param1;
            const char *type = (const char *)param2;
            UInt8 size = (UInt64)param3;
            const void *value = (const void *)param4;
            
            if (name && type && size > 0) {
                if (addKeyWithValue(name, type, size, value))
                    result = kIOReturnSuccess;
                else
                    result = kIOReturnError;
            }
        }
	}
    else if (functionName->isEqualTo(kFakeSMCSetKeyValue)) {
        
        result = kIOReturnBadArgument;
        
        if (param1 && param2 && param3) {
            const char *name = (const char *)param1;
            UInt8 size = (UInt64)param2;
            const void *data = (const void *)param3;
            
            result = kIOReturnError;
            
            if (name && data && size > 0) {
                if (FakeSMCKey *key = OSDynamicCast(FakeSMCKey, getKey(name))) {
                    if (key->setValueFromBuffer(data, size)) {
                        result = kIOReturnSuccess;
                    }
                }
            }
        }
	}
    else if (functionName->isEqualTo(kFakeSMCGetKeyValue)) {
        
        result = kIOReturnBadArgument;
        
        if (const char *name = (const char *)param1) {
            
            result = kIOReturnError;
            
            if (FakeSMCKey *key = getKey(name)) {
                
                result = kIOReturnBadArgument;
                
                if (param2 && param3) {
                    UInt8 *size = (UInt8*)param2;
                    const void **value = (const void **)param3;
                    
                    *size = key->getSize();
                    *value = key->getValue();
                    
                    result = kIOReturnSuccess;
                }
            }
        }
	}
    else if (functionName->isEqualTo(kFakeSMCTakeVacantGPUIndex)) {
        
        result = kIOReturnBadArgument;
        
        KEYSLOCK;
        
        if (SInt8 *index = (SInt8*)param1) {
            for (UInt8 i = 0; i <= 0xf; i++) {
                if (!bit_get(vacantGPUIndex, BIT(i))) {
                    bit_set(vacantGPUIndex, BIT(i));
                    *index = i;
                    result = kIOReturnSuccess;
                    break;
                }
            }
            
            if (result != kIOReturnSuccess)
                result = kIOReturnError;
        }
        
        KEYSUNLOCK;
    }
    else if (functionName->isEqualTo(kFakeSMCTakeGPUIndex)) {
        
        result = kIOReturnBadArgument;
        
        KEYSLOCK;
        
        if (UInt8 *index = (UInt8*)param1) {
            if (*index < 0xf && !bit_get(vacantGPUIndex, BIT(*index))) {
                bit_set(vacantGPUIndex, BIT(*index));
                result = kIOReturnSuccess;
            }
            
            if (result != kIOReturnSuccess)
                result = kIOReturnError;
        }
        
        KEYSUNLOCK;
    }
    else if (functionName->isEqualTo(kFakeSMCReleaseGPUIndex)) {
        
        result = kIOReturnBadArgument;
        
        KEYSLOCK;
        
        if (UInt8 *index = (UInt8*)param1) {
            if (*index <= 0xf) {
                bit_clear(vacantGPUIndex, BIT(*index));
                result = kIOReturnSuccess;
            }
        }
        
        KEYSUNLOCK;
    }
    else if (functionName->isEqualTo(kFakeSMCTakeVacantFanIndex)) {
        
        result = kIOReturnBadArgument;
        
        KEYSLOCK;
        
        if (SInt8 *index = (SInt8*)param1) {
            for (UInt8 i = 0; i <= 0xf; i++) {
                if (!bit_get(vacantFanIndex, BIT(i))) {
                    bit_set(vacantFanIndex, BIT(i));
                    *index = i;
                    updateFanCounterKey();
                    result = kIOReturnSuccess;
                    break;
                }
            }
            
            if (result != kIOReturnSuccess)
                result = kIOReturnError;
        }
        
        KEYSUNLOCK;
    }
    else if (functionName->isEqualTo(kFakeSMCReleaseFanIndex)) {
        
        result = kIOReturnBadArgument;
        
        KEYSLOCK;
        
        if (UInt8 *index = (UInt8*)param1) {
            if (*index <= 0xf) {
                bit_clear(vacantFanIndex, BIT(*index));
                updateFanCounterKey();
                result = kIOReturnSuccess;
            }
        }
        
        KEYSUNLOCK;
    }
    else {
        
        result = super::callPlatformFunction(functionName, waitForFunction, param1, param2, param3, param4);
    }
    
	return result;
}
Exemplo n.º 4
0
bool FakeSMCDevice::initAndStart(IOService *platform, IOService *provider)
{
	if (!provider || !super::init(platform, 0, 0))
		return false;
    
    OSDictionary *properties = OSDynamicCast(OSDictionary, provider->getProperty("Configuration"));
    
    if (!properties)
        return false;
    
	status = (ApleSMCStatus *) IOMalloc(sizeof(struct AppleSMCStatus));
	bzero((void*)status, sizeof(struct AppleSMCStatus));
	interrupt_handler = 0;
    
	keys = OSArray::withCapacity(1);
    types = OSDictionary::withCapacity(0);
    exposedValues = OSDictionary::withCapacity(0);
    
    // Add fist key - counter key
    keyCounterKey = FakeSMCKey::withValue(KEY_COUNTER, TYPE_UI32, TYPE_UI32_SIZE, "\0\0\0\1");
	keys->setObject(keyCounterKey);
    
    fanCounterKey = FakeSMCKey::withValue(KEY_FAN_NUMBER, TYPE_UI8, TYPE_UI8_SIZE, "\0");
    keys->setObject(fanCounterKey);
    
    if (!gKeysLock)
        gKeysLock = IORecursiveLockAlloc();
    
    // Load preconfigured keys
    FakeSMCDebugLog("loading keys...");
    
    if (OSDictionary *dictionary = OSDynamicCast(OSDictionary, properties->getObject("Keys"))) {
		if (OSIterator *iterator = OSCollectionIterator::withCollection(dictionary)) {
			while (const OSSymbol *key = (const OSSymbol *)iterator->getNextObject()) {
				if (OSArray *array = OSDynamicCast(OSArray, dictionary->getObject(key))) {
					if (OSIterator *aiterator = OSCollectionIterator::withCollection(array)) {
                        
						OSString *type = OSDynamicCast(OSString, aiterator->getNextObject());
						OSData *value = OSDynamicCast(OSData, aiterator->getNextObject());
                        
						if (type && value)
							addKeyWithValue(key->getCStringNoCopy(), type->getCStringNoCopy(), value->getLength(), value->getBytesNoCopy());
                        
                        OSSafeRelease(aiterator);
					}
				}
				key = 0;
			}
            
			OSSafeRelease(iterator);
		}
        
		HWSensorsInfoLog("%d preconfigured key%s added", keys->getCount(), keys->getCount() == 1 ? "" : "s");
	}
	else {
		HWSensorsWarningLog("no preconfigured keys found");
	}
    
    // Load wellknown type names
    FakeSMCDebugLog("loading types...");
    
    if (OSDictionary *dictionary = OSDynamicCast(OSDictionary, properties->getObject("Types"))) {
        if (OSIterator *iterator = OSCollectionIterator::withCollection(dictionary)) {
			while (OSString *key = OSDynamicCast(OSString, iterator->getNextObject())) {
                if (OSString *value = OSDynamicCast(OSString, dictionary->getObject(key))) {
                    types->setObject(key, value);
                }
            }
            OSSafeRelease(iterator);
        }
    }
    
    // Set Clover platform keys
    if (OSDictionary *dictionary = OSDynamicCast(OSDictionary, properties->getObject("Clover"))) {
        UInt32 count = 0;
        if (IORegistryEntry* cloverPlatformNode = fromPath("/efi/platform", gIODTPlane)) {
            if (OSIterator *iterator = OSCollectionIterator::withCollection(dictionary)) {
                while (OSString *name = OSDynamicCast(OSString, iterator->getNextObject())) {
                    if (OSData *data = OSDynamicCast(OSData, cloverPlatformNode->getProperty(name))) {
                        if (OSArray *items = OSDynamicCast(OSArray, dictionary->getObject(name))) {
                            OSString *key = OSDynamicCast(OSString, items->getObject(0));
                            OSString *type = OSDynamicCast(OSString, items->getObject(1));
                            
                            if (addKeyWithValue(key->getCStringNoCopy(), type->getCStringNoCopy(), data->getLength(), data->getBytesNoCopy()))
                                count++;
                        }
                    }
                }
                OSSafeRelease(iterator);
            }
        }
        
        if (count)
            HWSensorsInfoLog("%d key%s exported by Clover EFI", count, count == 1 ? "" : "s");
    }
    
    // Start SMC device
    
    if (!super::start(platform))
        return false;
    
	this->setName("SMC");
    
    FakeSMCSetProperty("name", "APP0001");
    
	if (OSString *compatibleKey = OSDynamicCast(OSString, properties->getObject("smc-compatible")))
		FakeSMCSetProperty("compatible", (const char *)compatibleKey->getCStringNoCopy());
	else
		FakeSMCSetProperty("compatible", "smc-napa");
    
	if (!this->setProperty("_STA", (unsigned long long)0x0000000b, 32)) {
        HWSensorsErrorLog("failed to set '_STA' property");
        return false;
    }
    
	if (OSBoolean *debugKey = OSDynamicCast(OSBoolean, properties->getObject("debug")))
		debug = debugKey->getValue();
    else
        debug = false;
    
    if (OSBoolean *traceKey = OSDynamicCast(OSBoolean, properties->getObject("trace")))
		trace = traceKey->getValue();
    else
        trace = false;
    
	IODeviceMemory::InitElement	rangeList[1];
    
	rangeList[0].start = 0x300;
	rangeList[0].length = 0x20;
//    rangeList[1].start = 0xfef00000;
//	rangeList[1].length = 0x10000;
    
	if(OSArray *array = IODeviceMemory::arrayFromList(rangeList, 1)) {
		this->setDeviceMemory(array);
		OSSafeRelease(array);
	}
	else
	{
		HWSensorsFatalLog("failed to create Device memory array");
		return false;
	}
    
	OSArray *controllers = OSArray::withCapacity(1);
    
    if(!controllers) {
		HWSensorsFatalLog("failed to create controllers array");
        return false;
    }
    
    controllers->setObject((OSSymbol *)OSSymbol::withCStringNoCopy("io-apic-0"));
    
	OSArray *specifiers  = OSArray::withCapacity(1);
    
    if(!specifiers) {
		HWSensorsFatalLog("failed to create specifiers array");
        return false;
    }
    
	UInt64 line = 0x06;
    
    OSData *tmpData = OSData::withBytes(&line, sizeof(line));
    
    if (!tmpData) {
		HWSensorsFatalLog("failed to create specifiers data");
        return false;
    }
    
    specifiers->setObject(tmpData);
    
	this->setProperty(gIOInterruptControllersKey, controllers) && this->setProperty(gIOInterruptSpecifiersKey, specifiers);
	this->attachToParent(platform, gIOServicePlane);
    
    registerService();
    
	HWSensorsInfoLog("successfully initialized");
    
	return true;
}
Exemplo n.º 5
0
void FakeSMCDevice::applesmc_io_data_writeb(void *opaque, uint32_t addr, uint32_t val)
{
    struct AppleSMCStatus *s = (struct AppleSMCStatus *)opaque;
    //    IOLog("APPLESMC: DATA Write B: %#x = %#x\n", addr, val);
    switch(s->cmd) {
        case APPLESMC_READ_CMD:
            if(s->read_pos < 4) {
                s->key[s->read_pos] = val;
                s->status = 0x04;
            } else if(s->read_pos == 4) {
                s->data_len = val;
                s->status = 0x05;
                s->data_pos = 0;
                //                IOLog("APPLESMC: Key = %c%c%c%c Len = %d\n", s->key[0], s->key[1], s->key[2], s->key[3], val);
                applesmc_fill_data(s);
            }
            s->read_pos++;
            break;
		case APPLESMC_WRITE_CMD:
            //			IOLog("FakeSMC: attempting to write(WRITE_CMD) to io port value %x ( %c )\n", val, val);
			if(s->read_pos < 4) {
                s->key[s->read_pos] = val;
                s->status = 0x04;
			} else if(s->read_pos == 4) {
				s->status = 0x05;
				s->data_pos=0;
				s->data_len = val;
                //				IOLog("FakeSMC: System Tried to write Key = %c%c%c%c Len = %d\n", s->key[0], s->key[1], s->key[2], s->key[3], val);
			} else if( s->data_pos < s->data_len ) {
				s->value[s->data_pos] = val;
				s->data_pos++;
				s->status = 0x05;
				if(s->data_pos == s->data_len) {
					s->status = 0x00;
                    
                    // Add or update key
                    char name[5]; name[4] = 0; memcpy(name, s->key, 4);
                    
                    FakeSMCDebugLog("system writing key %s, length %d", name, s->data_len);
                    
                    FakeSMCKey* key = addKeyWithValue(name, 0, s->data_len, s->value);

                    bzero(s->value, 255);
                    
                    if (key) saveKeyToNVRAM(key);
				}
			};
			s->read_pos++;
			break;
		case APPLESMC_GET_KEY_BY_INDEX_CMD:
            //			IOLog("FakeSMC: System Tried to write GETKEYBYINDEX = %x (%c) at pos %x\n",val , val, s->read_pos);
			if(s->read_pos < 4) {
                s->key_index += val << (24 - s->read_pos * 8);
                s->status = 0x04;
				s->read_pos++;
			};
			if(s->read_pos == 4) {
				s->status = 0x05;
                //				IOLog("FakeSMC: trying to find key by index %x\n", s->key_index);
				if(const char * key = applesmc_get_key_by_index(s->key_index, s))
					bcopy(key, s->key, 4);
			}
            
			break;
		case APPLESMC_GET_KEY_TYPE_CMD:
            //			IOLog("FakeSMC: System Tried to write GETKEYTYPE = %x (%c) at pos %x\n",val , val, s->read_pos);
			if(s->read_pos < 4) {
                s->key[s->read_pos] = val;
                s->status = 0x04;
            };
			s->read_pos++;
			if(s->read_pos == 4) {
				s->data_len = 6;  ///s->data_len = val ; ? val should be 6 here too
				s->status = 0x05;
				s->data_pos=0;
				applesmc_fill_info(s);
			}
			break;
    }
}