x86: Split large structs into portions

The C parser does not enjoy parsing structs with many fields
This commit is contained in:
Adrian Danis 2017-05-18 10:20:51 +10:00
parent 4f3f89bc21
commit 2038316358
3 changed files with 103 additions and 87 deletions

View file

@ -34,30 +34,35 @@ typedef struct multiboot_mmap {
} PACKED multiboot_mmap_t;
typedef struct multiboot_info {
uint32_t flags;
uint32_t mem_lower;
uint32_t mem_upper;
uint32_t boot_device;
uint32_t cmdline;
uint32_t mod_count;
uint32_t mod_list;
/* struct split into multiple parts due to details of how C parser works */
struct multiboot_part1 {
uint32_t flags;
uint32_t mem_lower;
uint32_t mem_upper;
uint32_t boot_device;
uint32_t cmdline;
uint32_t mod_count;
uint32_t mod_list;
} part1;
/* The symbol table information in the multiboot header is comprised of a union
* as we neither a. support unions in the kernel or b. need the symbol information
* we will just skip the 4 words of this */
uint32_t syms[4];
uint32_t mmap_length;
uint32_t mmap_addr;
uint32_t drives_length;
uint32_t drives_addr;
uint32_t config_table;
uint32_t boot_loader_name;
uint32_t apm_table;
uint32_t vbe_control_info;
uint32_t vbe_mode_info;
uint16_t vbe_mode;
uint16_t vbe_interface_seg;
uint16_t vbe_interface_off;
uint16_t vbe_interface_len;
struct multiboot_part2 {
uint32_t syms[4];
uint32_t mmap_length;
uint32_t mmap_addr;
uint32_t drives_length;
uint32_t drives_addr;
uint32_t config_table;
uint32_t boot_loader_name;
uint32_t apm_table;
uint32_t vbe_control_info;
uint32_t vbe_mode_info;
uint16_t vbe_mode;
uint16_t vbe_interface_seg;
uint16_t vbe_interface_off;
uint16_t vbe_interface_len;
} part2;
} PACKED multiboot_info_t;
#define MULTIBOOT_INFO_MEM_FLAG BIT(0)

View file

@ -31,60 +31,71 @@ typedef struct seL4_VBEInfoBlock {
seL4_Uint8 oemData[256];
} SEL4_PACKED seL4_VBEInfoBlock_t;
/* struct is split into multiple parts to aid the C parser */
typedef struct seL4_VBEModeInfoBlock {
/* All VBE revisions */
seL4_Uint16 modeAttr;
seL4_Uint8 winAAttr;
seL4_Uint8 winBAttr;
seL4_Uint16 winGranularity;
seL4_Uint16 winSize;
seL4_Uint16 winASeg;
seL4_Uint16 winBSeg;
seL4_Uint32 winFuncPtr;
seL4_Uint16 bytesPerScanLine;
struct vbe_info_common {
seL4_Uint16 modeAttr;
seL4_Uint8 winAAttr;
seL4_Uint8 winBAttr;
seL4_Uint16 winGranularity;
seL4_Uint16 winSize;
seL4_Uint16 winASeg;
seL4_Uint16 winBSeg;
seL4_Uint32 winFuncPtr;
seL4_Uint16 bytesPerScanLine;
} vbe_common;
/* VBE 1.2+ */
seL4_Uint16 xRes;
seL4_Uint16 yRes;
seL4_Uint8 xCharSize;
seL4_Uint8 yCharSize;
seL4_Uint8 planes;
seL4_Uint8 bitsPerPixel;
seL4_Uint8 banks;
seL4_Uint8 memoryModel;
seL4_Uint8 bankSize;
seL4_Uint8 imagePages;
seL4_Uint8 reserved1;
struct vbe_info_12_part1 {
seL4_Uint16 xRes;
seL4_Uint16 yRes;
seL4_Uint8 xCharSize;
seL4_Uint8 yCharSize;
seL4_Uint8 planes;
seL4_Uint8 bitsPerPixel;
seL4_Uint8 banks;
seL4_Uint8 memoryModel;
seL4_Uint8 bankSize;
seL4_Uint8 imagePages;
seL4_Uint8 reserved1;
} vbe12_part1;
seL4_Uint8 redLen;
seL4_Uint8 redOff;
seL4_Uint8 greenLen;
seL4_Uint8 greenOff;
seL4_Uint8 blueLen;
seL4_Uint8 blueOff;
seL4_Uint8 rsvdLen;
seL4_Uint8 rsvdOff;
seL4_Uint8 directColorInfo; /* direct color mode attributes */
struct vbe_info_12_part2 {
seL4_Uint8 redLen;
seL4_Uint8 redOff;
seL4_Uint8 greenLen;
seL4_Uint8 greenOff;
seL4_Uint8 blueLen;
seL4_Uint8 blueOff;
seL4_Uint8 rsvdLen;
seL4_Uint8 rsvdOff;
seL4_Uint8 directColorInfo; /* direct color mode attributes */
} vbe12_part2;
/* VBE 2.0+ */
seL4_Uint32 physBasePtr;
seL4_Uint8 reserved2[6];
struct vbe_info_20 {
seL4_Uint32 physBasePtr;
seL4_Uint8 reserved2[6];
} vbe20;
/* VBE 3.0+ */
seL4_Uint16 linBytesPerScanLine;
seL4_Uint8 bnkImagePages;
seL4_Uint8 linImagePages;
seL4_Uint8 linRedLen;
seL4_Uint8 linRedOff;
seL4_Uint8 linGreenLen;
seL4_Uint8 linGreenOff;
seL4_Uint8 linBlueLen;
seL4_Uint8 linBlueOff;
seL4_Uint8 linRsvdLen;
seL4_Uint8 linRsvdOff;
seL4_Uint32 maxPixelClock;
seL4_Uint16 modeId;
seL4_Uint8 depth;
struct vbe_info_30 {
seL4_Uint16 linBytesPerScanLine;
seL4_Uint8 bnkImagePages;
seL4_Uint8 linImagePages;
seL4_Uint8 linRedLen;
seL4_Uint8 linRedOff;
seL4_Uint8 linGreenLen;
seL4_Uint8 linGreenOff;
seL4_Uint8 linBlueLen;
seL4_Uint8 linBlueOff;
seL4_Uint8 linRsvdLen;
seL4_Uint8 linRsvdOff;
seL4_Uint32 maxPixelClock;
seL4_Uint16 modeId;
seL4_Uint8 depth;
} vbe30;
seL4_Uint8 reserved3[187];
} SEL4_PACKED seL4_VBEModeInfoBlock_t;

View file

@ -389,15 +389,15 @@ try_boot_sys(
paddr_t load_paddr;
word_t i;
p_region_t ui_p_regs;
multiboot_module_t *modules = (multiboot_module_t*)(word_t)mbi->mod_list;
multiboot_module_t *modules = (multiboot_module_t*)(word_t)mbi->part1.mod_list;
if (multiboot_magic != MULTIBOOT_MAGIC) {
printf("Boot loader not multiboot compliant\n");
return false;
}
cmdline_parse((const char *)(word_t)mbi->cmdline, &cmdline_opt);
cmdline_parse((const char *)(word_t)mbi->part1.cmdline, &cmdline_opt);
if ((mbi->flags & MULTIBOOT_INFO_MEM_FLAG) == 0) {
if ((mbi->part1.flags & MULTIBOOT_INFO_MEM_FLAG) == 0) {
printf("Boot loader did not provide information about physical memory size\n");
return false;
}
@ -416,7 +416,7 @@ try_boot_sys(
#if CONFIG_MAX_NUM_NODES > 1
/* copy boot code for APs to lower memory to run in real mode */
if (!copy_boot_code_aps(mbi->mem_lower)) {
if (!copy_boot_code_aps(mbi->part1.mem_lower)) {
return false;
}
/* Initialize any kernel TLS */
@ -430,11 +430,11 @@ try_boot_sys(
* important or kernel devices. */
boot_state.mem_p_regs.count = 0;
init_allocated_p_regions();
if (mbi->flags & MULTIBOOT_INFO_MMAP_FLAG) {
if (!parse_mem_map(mbi->mmap_length, mbi->mmap_addr)) {
if (mbi->part1.flags & MULTIBOOT_INFO_MMAP_FLAG) {
if (!parse_mem_map(mbi->part2.mmap_length, mbi->part2.mmap_addr)) {
return false;
}
uint32_t multiboot_mmap_length = mbi->mmap_length;
uint32_t multiboot_mmap_length = mbi->part2.mmap_length;
if (multiboot_mmap_length > (SEL4_MULTIBOOT_MAX_MMAP_ENTRIES * sizeof(seL4_X86_mb_mmap_t))) {
multiboot_mmap_length = SEL4_MULTIBOOT_MAX_MMAP_ENTRIES * sizeof(seL4_X86_mb_mmap_t);
printf("Warning: Multiboot has reported more memory map entries, %zd, "
@ -442,13 +442,13 @@ try_boot_sys(
"These extra regions will still be turned into untyped caps.",
multiboot_mmap_length / sizeof(seL4_X86_mb_mmap_t), SEL4_MULTIBOOT_MAX_MMAP_ENTRIES);
}
memcpy(&boot_state.mb_mmap_info.mmap, (void*)(word_t)mbi->mmap_addr, multiboot_mmap_length);
memcpy(&boot_state.mb_mmap_info.mmap, (void*)(word_t)mbi->part2.mmap_addr, multiboot_mmap_length);
boot_state.mb_mmap_info.mmap_length = multiboot_mmap_length;
} else {
/* calculate memory the old way */
p_region_t avail;
avail.start = HIGHMEM_PADDR;
avail.end = ROUND_DOWN(avail.start + (mbi->mem_upper << 10), PAGE_BITS);
avail.end = ROUND_DOWN(avail.start + (mbi->part1.mem_upper << 10), PAGE_BITS);
if (!add_mem_p_regs(avail)) {
return false;
}
@ -458,17 +458,17 @@ try_boot_sys(
boot_state.ki_p_reg.end = kpptr_to_paddr(ki_end);
/* copy VESA information from multiboot header */
if ((mbi->flags & MULTIBOOT_INFO_GRAPHICS_FLAG) == 0) {
if ((mbi->part1.flags & MULTIBOOT_INFO_GRAPHICS_FLAG) == 0) {
boot_state.vbe_info.vbeMode = -1;
printf("Multiboot gave us no video information\n");
} else {
boot_state.vbe_info.vbeInfoBlock = *(seL4_VBEInfoBlock_t*)(seL4_Word)mbi->vbe_control_info;
boot_state.vbe_info.vbeModeInfoBlock = *(seL4_VBEModeInfoBlock_t*)(seL4_Word)mbi->vbe_mode_info;
boot_state.vbe_info.vbeMode = mbi->vbe_mode;
printf("Got VBE info in multiboot. Current video mode is %d\n", mbi->vbe_mode);
boot_state.vbe_info.vbeInterfaceSeg = mbi->vbe_interface_seg;
boot_state.vbe_info.vbeInterfaceOff = mbi->vbe_interface_off;
boot_state.vbe_info.vbeInterfaceLen = mbi->vbe_interface_len;
boot_state.vbe_info.vbeInfoBlock = *(seL4_VBEInfoBlock_t*)(seL4_Word)mbi->part2.vbe_control_info;
boot_state.vbe_info.vbeModeInfoBlock = *(seL4_VBEModeInfoBlock_t*)(seL4_Word)mbi->part2.vbe_mode_info;
boot_state.vbe_info.vbeMode = mbi->part2.vbe_mode;
printf("Got VBE info in multiboot. Current video mode is %d\n", mbi->part2.vbe_mode);
boot_state.vbe_info.vbeInterfaceSeg = mbi->part2.vbe_interface_seg;
boot_state.vbe_info.vbeInterfaceOff = mbi->part2.vbe_interface_off;
boot_state.vbe_info.vbeInterfaceLen = mbi->part2.vbe_interface_len;
}
printf("Kernel loaded to: start=0x%lx end=0x%lx size=0x%lx entry=0x%lx\n",
@ -528,21 +528,21 @@ try_boot_sys(
}
}
if (!(mbi->flags & MULTIBOOT_INFO_MODS_FLAG)) {
if (!(mbi->part1.flags & MULTIBOOT_INFO_MODS_FLAG)) {
printf("Boot loader did not provide information about boot modules\n");
return false;
}
printf("Detected %d boot module(s):\n", mbi->mod_count);
printf("Detected %d boot module(s):\n", mbi->part1.mod_count);
if (mbi->mod_count < 1) {
if (mbi->part1.mod_count < 1) {
printf("Expect at least one boot module (containing a userland image)\n");
return false;
}
mods_end_paddr = 0;
for (i = 0; i < mbi->mod_count; i++) {
for (i = 0; i < mbi->part1.mod_count; i++) {
printf(
" module #%ld: start=0x%x end=0x%x size=0x%x name='%s'\n",
i,