github.com/jlmucb/cloudproxy@v0.0.0-20170830161738-b5aa0b619bc4/cpvmm/vmm/libc/bitarray_utilities.c (about) 1 /* 2 * Copyright (c) 2013 Intel Corporation 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * Unless required by applicable law or agreed to in writing, software 9 * distributed under the License is distributed on an "AS IS" BASIS, 10 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 * See the License for the specific language governing permissions and 12 * limitations under the License. 13 */ 14 15 #include "vmm_defs.h" 16 #include "hw_utils.h" 17 18 // Implement utilities for BITARRAY 19 20 #if 8 == ARCH_ADDRESS_WIDTH 21 #define SCAN_TYPE UINT64 22 #define SCAN_FUNC hw_scan_bit_forward64 23 #else 24 #define SCAN_TYPE UINT32 25 #define SCAN_FUNC hw_scan_bit_forward 26 #endif 27 28 void bitarray_enumerate_bits( UINT8* bitarray, UINT32 bitarray_size_in_bits, 29 BITARRAY_ENUM_FUNC cb, void* cb_data ) 30 { 31 UINT32 base_field_id = 0; 32 UINT32 idx; 33 UINT32 bit_idx; 34 UINT32 bytes_to_copy; 35 UINT32 extra_bytes; 36 37 union { 38 SCAN_TYPE uint; 39 UINT8 uint8[sizeof(SCAN_TYPE)]; 40 } temp_mask; 41 42 // something was changed. need to copy it to the hw data base 43 base_field_id = 0; 44 45 while (base_field_id < bitarray_size_in_bits) { 46 // fill what to search. Bit numbers in our case raise from MSB to LSB. 47 bytes_to_copy = sizeof(SCAN_TYPE); 48 extra_bytes = (bitarray_size_in_bits - base_field_id + 7) / 8; 49 if (extra_bytes < bytes_to_copy) { 50 bytes_to_copy = extra_bytes; 51 } 52 53 temp_mask.uint = 0; 54 for (idx = 0; idx < bytes_to_copy; ++idx) { 55 temp_mask.uint8[idx] = bitarray[ BITARRAY_BYTE( base_field_id + idx*8 ) ]; 56 } 57 58 while (temp_mask.uint != 0) { 59 SCAN_FUNC( &bit_idx, temp_mask.uint ); 60 BITARRAY_CLR( temp_mask.uint8, bit_idx); 61 cb( base_field_id + bit_idx, cb_data); 62 } 63 base_field_id += sizeof(SCAN_TYPE) * 8; 64 } 65 } 66 67