/* Allocate a buffer which can be used directly by hardware, 4kb aligned */ static ump_handle ump_ref_drv_allocate_internal(unsigned long size, ump_alloc_constraints constraints, ump_cache_enabled cache) { ump_secure_id secure_id; unsigned long allocated_size = size; UMP_DEBUG_PRINT(4, ("Allocating UMP memory of size %lu", size)); secure_id = ump_arch_allocate(&allocated_size, constraints); if (secure_id != UMP_INVALID_SECURE_ID) { unsigned long cookie; void * mapping; mapping = ump_arch_map(secure_id, allocated_size, cache, &cookie); if (NULL != mapping) { /* * PS: By now we have actually increased the ref count in the device driver by 2, * one for the allocation iteself, and one for the mapping. */ ump_mem * mem; mem = _ump_osu_calloc(1, sizeof(*mem)); if (NULL != mem) { mem->secure_id = secure_id; mem->mapped_mem = mapping; mem->size = allocated_size; mem->cookie = cookie; mem->is_cached = 1; /* Default to ON, is disabled later if not */ _ump_osu_lock_auto_init(&mem->ref_lock, 0, 0, 0); UMP_DEBUG_ASSERT(NULL != mem->ref_lock, ("Failed to initialize lock\n")); mem->ref_count = 1; /* * ump_arch_allocate() gave us a kernel space reference, and the same did ump_arch_map() * We release the one from ump_arch_allocate(), and rely solely on the one from the ump_arch_map() * That is, ump_arch_unmap() should now do the final release towards the UMP kernel space driver. */ ump_arch_reference_release(secure_id); /* This is called only to set the cache settings in this handle */ ump_cpu_msync_now((ump_handle)mem, UMP_MSYNC_READOUT_CACHE_ENABLED, NULL, 0); UMP_DEBUG_PRINT(4, ("UMP handle created for ID %u of size %lu, mapped into address 0x%08lx", mem->secure_id, mem->size, (unsigned long)mem->mapped_mem)); return (ump_handle)mem; } ump_arch_unmap(mapping, allocated_size, cookie); /* Unmap the memory */ ump_arch_reference_release(secure_id); /* Release reference added when we allocated the UMP memory */ } ump_arch_reference_release(secure_id); /* Release reference added when we allocated the UMP memory */ } UMP_DEBUG_PRINT(4, ("Allocation of UMP memory failed")); return UMP_INVALID_MEMORY_HANDLE; }
UMP_API_EXPORT ump_handle ump_handle_create_from_secure_id(ump_secure_id secure_id) { unsigned long size; UMP_DEBUG_ASSERT(UMP_INVALID_SECURE_ID != secure_id, ("Secure ID is invalid")); size = ump_arch_size_get(secure_id); if (0 != size) { unsigned long cookie; /* * The UMP memory which the secure_id referes to could now be deleted and re-created * since we don't have any references to it yet. The mapping below will however fail if * we have supplied incorrect size, so we are safe. */ void *mapping = ump_arch_map(secure_id, size, UMP_CACHE_DISABLE, &cookie); if (NULL != mapping) { ump_mem *mem = _ump_osu_calloc(1, sizeof(*mem)); if (NULL != mem) { mem->secure_id = secure_id; mem->mapped_mem = mapping; mem->size = size; mem->cookie = cookie; mem->is_cached = UMP_CACHE_ENABLE; /* Is set to actually check in the ump_cpu_msync_now() function */ _ump_osu_lock_auto_init(&mem->ref_lock, _UMP_OSU_LOCKFLAG_DEFAULT, 0, 0); UMP_DEBUG_ASSERT(NULL != mem->ref_lock, ("Failed to initialize lock\n")); mem->ref_count = 1; /* This is called only to set the cache settings in this handle */ ump_cpu_msync_now((ump_handle)mem, UMP_MSYNC_READOUT_CACHE_ENABLED, NULL, 0); UMP_DEBUG_PRINT(4, ("UMP handle created for ID %u of size %lu, mapped into address 0x%08lx", mem->secure_id, mem->size, (unsigned long)mem->mapped_mem)); return (ump_handle)mem; } ump_arch_unmap(mapping, size, cookie); } } UMP_DEBUG_PRINT(2, ("UMP handle creation failed for ID %u", secure_id)); return UMP_INVALID_MEMORY_HANDLE; }