/* Cesar project {{{ * * Copyright (C) 2007 Spidcom * * <<>> * * }}} */ /** * \file lib/src/read_word.c * \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 */ #include "common/std.h" #include "lib/read_word.h" /** * 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) { u64 data; data = read_u32_from_word (addr) | ((u64)read_u32_from_word(addr + sizeof(uint)) << 32); return data; } /** * 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) { u64 data; data = read_u32_from_word (addr) | ((u64)read_u24_from_word(addr + sizeof(uint)) << 32); return data; } /** * 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) { u64 data; data = read_u32_from_word (addr) | ((u64)read_u16_from_word(addr + sizeof(uint)) << 32); return data; } u64 read_u40_from_word (u8 *addr) { u64 data; data = read_u32_from_word (addr) | ((u64)read_u8_from_word(addr + sizeof(uint)) << 32); return data; } /** * 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) { return read_bytes_from_word(addr, 4); } /** * Reads 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) { return read_bytes_from_word (addr, 3) & 0x00FFFFFF; } /** * 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) { return read_bytes_from_word (addr, 2) & 0x0000FFFF; } /** * 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) { return read_bytes_from_word (addr, 1) & 0x000000FF; }