From d762df1df1e33784875302c754e2ed77415b3ee7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Duval?= Date: Thu, 25 Apr 2013 18:08:05 +0200 Subject: [PATCH] GCC 4.7.x doesn't allow setting a field in a referenced packed struct. * error message: error: cannot bind packed field 'args->kernel_args::platform_args.platform_kernel_args::apm' to 'apm_info&' * the reason would be that the reference doesn't have alignment information anymore. * changed the reference to const for read access, and use the long form for setting a field. --- src/system/boot/platform/bios_ia32/apm.cpp | 22 +++++++++++----------- src/system/kernel/arch/x86/32/apm.cpp | 11 +++++++---- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/src/system/boot/platform/bios_ia32/apm.cpp b/src/system/boot/platform/bios_ia32/apm.cpp index 3e4aec15fe..9e71b0888d 100644 --- a/src/system/boot/platform/bios_ia32/apm.cpp +++ b/src/system/boot/platform/bios_ia32/apm.cpp @@ -36,9 +36,9 @@ apm_init(void) return B_ERROR; } - apm_info &info = gKernelArgs.platform_args.apm; - info.version = regs.eax & 0xffff; - info.flags = regs.ecx & 0xffff; + const apm_info &info = gKernelArgs.platform_args.apm; + gKernelArgs.platform_args.apm.version = regs.eax & 0xffff; + gKernelArgs.platform_args.apm.flags = regs.ecx & 0xffff; dprintf("APM version %d.%d available, flags %x.\n", (info.version >> 8) & 0xf, info.version & 0xf, info.flags); @@ -64,19 +64,19 @@ apm_init(void) call_bios(0x15, ®s); if ((regs.flags & CARRY_FLAG) != 0) { // reset the version, so that the kernel won't try to use APM - info.version = 0; + gKernelArgs.platform_args.apm.version = 0; return B_ERROR; } - info.code32_segment_base = regs.eax & 0xffff; - info.code32_segment_offset = regs.ebx; - info.code32_segment_length = regs.esi & 0xffff; + gKernelArgs.platform_args.apm.code32_segment_base = regs.eax & 0xffff; + gKernelArgs.platform_args.apm.code32_segment_offset = regs.ebx; + gKernelArgs.platform_args.apm.code32_segment_length = regs.esi & 0xffff; - info.code16_segment_base = regs.ecx & 0xffff; - info.code16_segment_length = regs.esi >> 16; + gKernelArgs.platform_args.apm.code16_segment_base = regs.ecx & 0xffff; + gKernelArgs.platform_args.apm.code16_segment_length = regs.esi >> 16; - info.data_segment_base = regs.edx & 0xffff; - info.data_segment_length = regs.edi & 0xffff; + gKernelArgs.platform_args.apm.data_segment_base = regs.edx & 0xffff; + gKernelArgs.platform_args.apm.data_segment_length = regs.edi & 0xffff; TRACE((" code32: 0x%x, 0x%lx, length 0x%x\n", info.code32_segment_base, info.code32_segment_offset, info.code32_segment_length)); diff --git a/src/system/kernel/arch/x86/32/apm.cpp b/src/system/kernel/arch/x86/32/apm.cpp index f34b0b1b30..1c6b72b178 100644 --- a/src/system/kernel/arch/x86/32/apm.cpp +++ b/src/system/kernel/arch/x86/32/apm.cpp @@ -274,7 +274,7 @@ apm_shutdown(void) status_t apm_init(kernel_args *args) { - apm_info &info = args->platform_args.apm; + const apm_info &info = args->platform_args.apm; TRACE(("apm_init()\n")); @@ -338,11 +338,14 @@ apm_init(kernel_args *args) if ((info.data_segment_base << 4) < 0xe0000) { // use the BIOS data segment as data segment for APM - if (info.data_segment_length == 0) - info.data_segment_length = B_PAGE_SIZE - info.data_segment_base; + if (info.data_segment_length == 0) { + args->platform_args.apm.data_segment_length = B_PAGE_SIZE + - info.data_segment_base; + } set_segment_descriptor(&gGDT[APM_DATA_SEGMENT >> 3], - (addr_t)gDmaAddress + (info.data_segment_base << 4), info.data_segment_length, + (addr_t)gDmaAddress + (info.data_segment_base << 4), + info.data_segment_length, DT_DATA_WRITEABLE, DPL_KERNEL); } else { // use the BIOS area as data segment