#ifndef LIB_READ_WORD_H_ #define LIB_READ_WORD_H_ /* Cesar project {{{ * * Copyright (C) 2007 Spidcom * * <<>> * * }}} */ /** * \file lib/read_word.h * \brief Read a word from the memory aligned on an integer address. * \ingroup lib * * Allows the system to get a value from the memory reading it word by word * and returning the value request from the user. * * Exemple : we need to get a 4 bytes word from the address 503 on the * memory it will calculate the address from the one it should start reading * the data to be aligned. * So it will read a word from the address 500 and the next one from the @ * 504, it will take the last byte of the first word and concatante it with * the three bytes in the last word. * result = word2 << 24 | word1 * */ /** * Read the necessary words from the memory and return the data requested. * Aware : if less than a word is request, it will need to be masqued to * desable the bytes which are note necessary. * Example : if you only need the two first bytes you should request: * read_bytes_from_word (addr, 2) & 0xFFFF */ extern inline uint read_bytes_from_word (u8 *addr, uint bytes) { u8* addr_new; uint rest; uint result; uint word1; uint word2; dbg_assert (addr); dbg_assert (bytes <= 4); addr_new = (u8*) (((uint) addr) & ~3); rest = (((uint) addr) & 3); if (rest == 0) { result = *(u32*) (addr_new); } else if ((4-rest) >= bytes) { result = (*(u32*) (addr_new)) >> (8* rest); } else { word1 = (*(u32*) addr_new) >> (rest * 8); word2 = (*(u32*) (addr_new + 4)); result = word2 << (4 - rest) * 8 | word1; } return (result & BITS_ONES (bytes * 8)); } /** * Read u64 from two words. * * \param addr the address to read the next two 48 bits. * \return u64 masked on 48 bits. */ u64 read_u64_from_word (u8 *addr); /** * Read u56 from two words. * * \param addr the address to read the next two 48 bits. * \return u64 masked on 48 bits. */ u64 read_u56_from_word (u8 *addr); /** * Read u48 from two words. * * \param addr the address to read the next two 48 bits. * \return u64 masked on 48 bits. */ u64 read_u48_from_word (u8 *addr); /** * Read 40 bits from the word. * * \param addr the address from the one the value should be read. * \return the u64 */ u64 read_u40_from_word (u8 *addr); /** * Read 32 bits from the word. * * \param addr the address from the one the value should be read. * \return the u32 */ uint read_u32_from_word (u8 *addr); /** * Read 24 bits from the word. * * \param addr the address from the one the value should be read. * \return the u32 with the last byte set to 0 */ uint read_u24_from_word (u8 *addr); /** * Read 16 bits from the word. * * \param addr the address from the one the value should be read. * \return the u32 with the last byte set to 0 */ uint read_u16_from_word (u8 *addr); /** * Read 8 bits from the word. * * \param addr the address from the one the value should be read. * \return uint with only one byte filled. */ uint read_u8_from_word (u8 *addr); #endif /*LIB_READ_WORD_H_*/