I have looked at the recommendations for both my question and searched for my question's headline but did not find anything related. The line I am confused about is below the comments in mmu.c
.
I want to set up the MMU translation table on an ARM v7 32-bit processor. The function void map_virt_to_phys_adr(uint32_t virt_adr, uint32_t phys_adr, uint32_t AP, uint32_t PXN, uint32_t XN)
takes both the virtual and physical address as parameters and permission flags. It simply creates an entry in the translation table that has the offset of the physical/virtual address (they need to be the same). I do not understand why the compiler gives the errors: a cast from the (L1_table_entry) (section_base_adr | (phys_adr & L1_table_index))
to L1_table_index
is not allowed (there is no explanation). And why it says that a ')' is expected at L1_table_index
in (phys_adr & L1_table_index))
.
// mmu.h
#define L1_section_index ((uint32_t)1 << (21)) - 1;
#define L1_table_index ~L1_section_index;
typedef struct L1_table_entry{
uint32_t PXN:1;
uint32_t unused_1:3;
uint32_t XN:1;
uint32_t DOMAIN:4;
uint32_t unused:1;
uint32_t AP_0_1:2;
uint32_t unused_2:3;
uint32_t AP_2:1;
uint32_t unused_3:4;
uint32_t base_address:12;
}L1_table_entry;
typedef struct L1_fault_entry{
uint32_t fault:2;
uint32_t unused:30;
}L1_fault_entry;
enum MMU_entry_type {L1_ENTRY, L1_FAULT};
typedef struct MMU_entry{
union {
L1_table_entry L1_entry;
L1_fault_entry L1_fault_entry;
};
enum MMU_entry_type type;
} MMU_entry;
// ...
//mmu.c
void map_virt_to_phys_adr(uint32_t virt_adr, uint32_t phys_adr, uint32_t AP, uint32_t PXN, uint32_t XN){
uint32_t section_index = virt_adr & L1_section_index;
uint32_t table_index = virt_adr & L1_table_index;
uint32_t section_base_adr = phys_adr & L1_table_index;
// cast to L1_table_entry is not allowed. Expected a ')' at L1_table_index.
L1_table_entry = (L1_table_entry) (section_base_adr | (phys_adr & L1_table_index));
L1_table[table_index] = phys_adr & L1_table_index;
}
Edit: I am interested in the reasons for the errors and a solution :)
Casting to or from a struct
is not allowed.
Unless the type name specifies a void type, the type name shall specify qualified or unqualified scalar type and the operand shall have scalar type.
Use a union for type punning.
Or, if you are feeling adventurous, create an integer variable, take its address, cast it to a pointer to struct, and dereference the result. It is UB but will probably work.