before we start, yes I know, that's not the GCC optimizations that makes my kernel crash but badly written code. So I figured out which portion of code does not behave correctly in my code and I found out that setting optimizations for the following function makes it work uncorrectly:
Code: Select all
#pragma GCC push_options
#pragma GCC optimize ("O1")
OS_RETURN_E kernel_direct_mmap(const void* virt_addr, const void* phys_addr,
const uint32_t mapping_size,
const uint16_t flags,
const uint16_t allow_remap)
{
uint32_t pgdir_entry;
uint32_t pgtable_entry;
uint32_t* page_table;
uint32_t* page_entry;
uint32_t end_map;
uint32_t i;
uint32_t* current_pgdir;
uint32_t* new_frame;
OS_RETURN_E err;
#if PAGING_KERNEL_DEBUG == 1
uint32_t virt_save;
#endif
if(init == 0)
{
return OS_ERR_PAGING_NOT_INIT;
}
current_pgdir = (uint32_t*)&kernel_current_pgdir;
/* Get end mapping addr */
end_map = (uint32_t)virt_addr + mapping_size;
#if PAGING_KERNEL_DEBUG == 1
kernel_serial_debug("Mapping (before align) 0x%08x, to 0x%08x (%d bytes)\n",
virt_addr, phys_addr, mapping_size);
#endif
/* Align addr */
virt_addr = (uint8_t*)((uint32_t)virt_addr & 0xFFFFF000);
phys_addr = (uint8_t*)((uint32_t)phys_addr & 0xFFFFF000);
#if PAGING_KERNEL_DEBUG == 1
kernel_serial_debug("Mapping (after align) 0x%08x, to 0x%08x (%d bytes)\n",
virt_addr, phys_addr, mapping_size);
virt_save = (uint32_t)virt_addr;
#endif
/* Map all pages needed */
while((uint32_t)virt_addr < end_map)
{
/* Get PGDIR entry */
pgdir_entry = (((uint32_t)virt_addr) >> 22);
/* Get PGTABLE entry */
pgtable_entry = (((uint32_t)virt_addr) >> 12) & 0x03FF;
/* If page table not present create it */
if((current_pgdir[pgdir_entry] & PG_DIR_FLAG_PAGE_PRESENT) !=
PG_DIR_FLAG_PAGE_PRESENT)
{
new_frame = kernel_paging_alloc_frames(1, &err);
if(new_frame == NULL)
{
break;
}
page_table = map_pgtable(new_frame);
for(i = 0; i < 1024; ++i)
{
page_table[i] = PAGE_FLAG_SUPER_ACCESS |
PAGE_FLAG_READ_ONLY |
PAGE_FLAG_NOT_PRESENT;
}
current_pgdir[pgdir_entry] = (uint32_t)new_frame |
PG_DIR_FLAG_PAGE_SIZE_4KB |
PG_DIR_FLAG_PAGE_SUPER_ACCESS |
PG_DIR_FLAG_PAGE_READ_WRITE |
PG_DIR_FLAG_PAGE_PRESENT;
}
/* Map the address */
page_table = (uint32_t*)
((uint32_t)current_pgdir[pgdir_entry] & 0xFFFFF000);
page_table = map_pgtable(page_table);
page_entry = &page_table[pgtable_entry];
/* Check if already mapped */
if((*page_entry & PAGE_FLAG_PRESENT) == PAGE_FLAG_PRESENT &&
allow_remap == 0)
{
#if PAGING_KERNEL_DEBUG == 1
kernel_serial_debug("Mapping (after align) 0x%08x, to 0x%08x "
"(%d bytes) Already mapped)\n",
virt_addr, phys_addr, mapping_size);
virt_save = (uint32_t)virt_addr;
#endif
return OS_ERR_MAPPING_ALREADY_EXISTS;
}
*page_entry = (uint32_t)phys_addr |
flags |
PAGE_FLAG_PRESENT;
#if PAGING_KERNEL_DEBUG == 1
kernel_serial_debug("Mapped 0x%08x -> 0x%08x\n", virt_addr, phys_addr);
#endif
virt_addr = (uint8_t*)virt_addr + KERNEL_PAGE_SIZE;
phys_addr = (uint8_t*)phys_addr + KERNEL_PAGE_SIZE;
}
invalidate_tlb();
return OS_NO_ERR;
}
#pragma GCC pop_options
So my question is: can you help me find what causes the function to stop working when optimizations are turned on? I there a way to turn on optimizations one by one (and not by level) to find which one en-light the bad behavior of the core?