/* * Copyright (C) 2016 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include #include namespace nvram { namespace { // Executes an operation on the |NvramDeviceAdapter| corresponding to |device|. // |command| identifies the type of operation, |request_payload| provides the // input parameters. Output parameters are stored in |response_payload|, and the // the nvram operation result code is returned. template nvram_result_t Execute(const nvram_device_t* device, RequestPayload&& request_payload, ResponsePayload* response_payload) { NvramDeviceAdapter* adapter = reinterpret_cast( const_cast(device)); nvram::Request request; request.payload.Activate() = std::move(request_payload); nvram::Response response; adapter->nvram_implementation()->Execute(request, &response); if (response.result != NV_RESULT_SUCCESS) { return response.result; } ResponsePayload* response_payload_ptr = response.payload.get(); if (!response_payload_ptr) { return NV_RESULT_INTERNAL_ERROR; } *response_payload = std::move(*response_payload_ptr); return NV_RESULT_SUCCESS; } // All the HAL methods need to be callable from C code. extern "C" { nvram_result_t device_get_total_size_in_bytes(const nvram_device_t* device, uint64_t* total_size) { nvram::GetInfoRequest get_info_request; nvram::GetInfoResponse get_info_response; nvram_result_t result = Execute( device, std::move(get_info_request), &get_info_response); *total_size = get_info_response.total_size; return result; } nvram_result_t device_get_available_size_in_bytes(const nvram_device_t* device, uint64_t* available_size) { nvram::GetInfoRequest get_info_request; nvram::GetInfoResponse get_info_response; nvram_result_t result = Execute( device, std::move(get_info_request), &get_info_response); *available_size = get_info_response.available_size; return result; } nvram_result_t device_get_max_space_size_in_bytes(const nvram_device_t* device, uint64_t* max_space_size) { nvram::GetInfoRequest get_info_request; nvram::GetInfoResponse get_info_response; nvram_result_t result = Execute( device, std::move(get_info_request), &get_info_response); *max_space_size = get_info_response.max_space_size; return result; } nvram_result_t device_get_max_spaces(const nvram_device_t* device, uint32_t* num_spaces) { nvram::GetInfoRequest get_info_request; nvram::GetInfoResponse get_info_response; nvram_result_t result = Execute( device, std::move(get_info_request), &get_info_response); *num_spaces = get_info_response.max_spaces; return result; } nvram_result_t device_get_space_list(const nvram_device_t* device, uint32_t max_list_size, uint32_t* space_index_list, uint32_t* list_size) { nvram::GetInfoRequest get_info_request; nvram::GetInfoResponse get_info_response; nvram_result_t result = Execute( device, std::move(get_info_request), &get_info_response); if (space_index_list) { *list_size = std::min(get_info_response.space_list.size(), static_cast(max_list_size)); for (size_t i = 0; i < *list_size; ++i) { space_index_list[i] = get_info_response.space_list[i]; } } else { *list_size = get_info_response.space_list.size(); } return result; } nvram_result_t device_get_space_size(const nvram_device_t* device, uint32_t index, uint64_t* size) { nvram::GetSpaceInfoRequest get_space_info_request; get_space_info_request.index = index; nvram::GetSpaceInfoResponse get_space_info_response; nvram_result_t result = Execute( device, std::move(get_space_info_request), &get_space_info_response); *size = get_space_info_response.size; return result; } nvram_result_t device_get_space_controls(const nvram_device_t* device, uint32_t index, uint32_t max_list_size, nvram_control_t* control_list, uint32_t* list_size) { nvram::GetSpaceInfoRequest get_space_info_request; get_space_info_request.index = index; nvram::GetSpaceInfoResponse get_space_info_response; nvram_result_t result = Execute( device, std::move(get_space_info_request), &get_space_info_response); if (control_list) { *list_size = std::min(get_space_info_response.controls.size(), static_cast(max_list_size)); for (size_t i = 0; i < *list_size; ++i) { control_list[i] = get_space_info_response.controls[i]; } } else { *list_size = get_space_info_response.controls.size(); } return result; } nvram_result_t device_is_space_locked(const nvram_device_t* device, uint32_t index, int* write_lock_enabled, int* read_lock_enabled) { nvram::GetSpaceInfoRequest get_space_info_request; get_space_info_request.index = index; nvram::GetSpaceInfoResponse get_space_info_response; nvram_result_t result = Execute( device, std::move(get_space_info_request), &get_space_info_response); *write_lock_enabled = get_space_info_response.write_locked; *read_lock_enabled = get_space_info_response.read_locked; return result; } nvram_result_t device_create_space(const nvram_device_t* device, uint32_t index, uint64_t size_in_bytes, const nvram_control_t* control_list, uint32_t list_size, const uint8_t* authorization_value, uint32_t authorization_value_size) { nvram::CreateSpaceRequest create_space_request; create_space_request.index = index; create_space_request.size = size_in_bytes; if (!create_space_request.controls.Resize(list_size)) { return NV_RESULT_INTERNAL_ERROR; } for (size_t i = 0; i < list_size; ++i) { create_space_request.controls[i] = control_list[i]; } if (!create_space_request.authorization_value.Assign( authorization_value, authorization_value_size)) { return NV_RESULT_INTERNAL_ERROR; } nvram::CreateSpaceResponse create_space_response; return Execute( device, std::move(create_space_request), &create_space_response); } nvram_result_t device_delete_space(const nvram_device_t* device, uint32_t index, const uint8_t* authorization_value, uint32_t authorization_value_size) { nvram::DeleteSpaceRequest delete_space_request; delete_space_request.index = index; if (!delete_space_request.authorization_value.Assign( authorization_value, authorization_value_size)) { return NV_RESULT_INTERNAL_ERROR; } nvram::DeleteSpaceResponse delete_space_response; return Execute( device, std::move(delete_space_request), &delete_space_response); } nvram_result_t device_disable_create(const nvram_device_t* device) { nvram::DisableCreateRequest disable_create_request; nvram::DisableCreateResponse disable_create_response; return Execute( device, std::move(disable_create_request), &disable_create_response); } nvram_result_t device_write_space(const nvram_device_t* device, uint32_t index, const uint8_t* buffer, uint64_t buffer_size, const uint8_t* authorization_value, uint32_t authorization_value_size) { nvram::WriteSpaceRequest write_space_request; write_space_request.index = index; if (!write_space_request.buffer.Assign(buffer, buffer_size) || !write_space_request.authorization_value.Assign( authorization_value, authorization_value_size)) { return NV_RESULT_INTERNAL_ERROR; } nvram::WriteSpaceResponse write_space_response; return Execute( device, std::move(write_space_request), &write_space_response); } nvram_result_t device_read_space(const nvram_device_t* device, uint32_t index, uint64_t num_bytes_to_read, const uint8_t* authorization_value, uint32_t authorization_value_size, uint8_t* buffer, uint64_t* bytes_read) { nvram::ReadSpaceRequest read_space_request; read_space_request.index = index; if (!read_space_request.authorization_value.Assign( authorization_value, authorization_value_size)) { return NV_RESULT_INTERNAL_ERROR; } nvram::ReadSpaceResponse read_space_response; nvram_result_t result = Execute( device, std::move(read_space_request), &read_space_response); *bytes_read = std::min(static_cast(num_bytes_to_read), read_space_response.buffer.size()); memcpy(buffer, read_space_response.buffer.data(), *bytes_read); return result; } nvram_result_t device_enable_write_lock(const nvram_device_t* device, uint32_t index, const uint8_t* authorization_value, uint32_t authorization_value_size) { nvram::LockSpaceWriteRequest lock_space_write_request; lock_space_write_request.index = index; if (!lock_space_write_request.authorization_value.Assign( authorization_value, authorization_value_size)) { return NV_RESULT_INTERNAL_ERROR; } nvram::LockSpaceWriteResponse lock_space_write_response; return Execute( device, std::move(lock_space_write_request), &lock_space_write_response); } nvram_result_t device_enable_read_lock(const nvram_device_t* device, uint32_t index, const uint8_t* authorization_value, uint32_t authorization_value_size) { nvram::LockSpaceReadRequest lock_space_read_request; lock_space_read_request.index = index; if (!lock_space_read_request.authorization_value.Assign( authorization_value, authorization_value_size)) { return NV_RESULT_INTERNAL_ERROR; } nvram::LockSpaceReadResponse lock_space_read_response; return Execute( device, std::move(lock_space_read_request), &lock_space_read_response); } int device_nvram_device_close(struct hw_device_t* device) { delete reinterpret_cast( reinterpret_cast(device)); return 0; } } // extern "C" } // namespace NvramDeviceAdapter::NvramDeviceAdapter(const hw_module_t* module, NvramImplementation* implementation) : implementation_(implementation) { memset(&device_, 0, sizeof(nvram_device_t)); device_.common.tag = HARDWARE_DEVICE_TAG; device_.common.version = NVRAM_DEVICE_API_VERSION_1_1; device_.common.module = const_cast(module); device_.common.close = device_nvram_device_close; device_.get_total_size_in_bytes = device_get_total_size_in_bytes; device_.get_available_size_in_bytes = device_get_available_size_in_bytes; device_.get_max_space_size_in_bytes = device_get_max_space_size_in_bytes; device_.get_max_spaces = device_get_max_spaces; device_.get_space_list = device_get_space_list; device_.get_space_size = device_get_space_size; device_.get_space_controls = device_get_space_controls; device_.is_space_locked = device_is_space_locked; device_.create_space = device_create_space; device_.delete_space = device_delete_space; device_.disable_create = device_disable_create; device_.write_space = device_write_space; device_.read_space = device_read_space; device_.enable_write_lock = device_enable_write_lock; device_.enable_read_lock = device_enable_read_lock; } } // namespace nvram