diff --git a/headers/private/kernel/arch/x86/apm.h b/headers/private/kernel/arch/x86/apm.h new file mode 100644 index 0000000000..3a973489a9 --- /dev/null +++ b/headers/private/kernel/arch/x86/apm.h @@ -0,0 +1,21 @@ +#ifndef KERNEL_APM_H +#define KERNEL_APM_H + + +#include + + +typedef struct apm_info { + uint16 version; + uint16 flags; + uint16 code32_segment_base; + uint32 code32_segment_offset; + uint16 code32_segment_length; + uint16 code16_segment_base; + uint16 code16_segment_length; + uint16 data_segment_base; + uint16 data_segment_length; +} apm_info; + + +#endif /* KERNEL_APM_H */ diff --git a/headers/private/kernel/arch/x86/descriptors.h b/headers/private/kernel/arch/x86/descriptors.h index 1e4a86f4b8..b138d5773d 100644 --- a/headers/private/kernel/arch/x86/descriptors.h +++ b/headers/private/kernel/arch/x86/descriptors.h @@ -1,7 +1,10 @@ /* -** Copyright 2001-2002, Travis Geiselbrecht. All rights reserved. -** Distributed under the terms of the NewOS License. -*/ + * Copyright 2002-2006, Axel Dörfler, axeld@pinc-software.de. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Copyright 2001-2002, Travis Geiselbrecht. All rights reserved. + * Distributed under the terms of the NewOS License. + */ #ifndef _KERNEL_ARCH_x86_DESCRIPTORS_H #define _KERNEL_ARCH_x86_DESCRIPTORS_H @@ -12,14 +15,18 @@ #define USER_CODE_SEG 0x1b #define USER_DATA_SEG 0x23 +#define APM_CODE32_SEGMENT 0x28 +#define APM_CODE16_SEGMENT 0x30 +#define APM_DATA_SEGMENT 0x38 #ifndef _ASSEMBLER // this file can also be included from assembler as well // (and is in arch_interrupts.S) -#define DOUBLE_FAULT_TSS_BASE_SEGMENT 5 +#define DOUBLE_FAULT_TSS_BASE_SEGMENT 8 #define TSS_BASE_SEGMENT (DOUBLE_FAULT_TSS_BASE_SEGMENT + smp_get_num_cpus()) #define TLS_BASE_SEGMENT (TSS_BASE_SEGMENT + smp_get_num_cpus()) +#define APM_BASE_SEGMENT (TLS_BASE_SEGMENT + smp_get_num_cpus()) // defines entries in the GDT/LDT diff --git a/headers/private/kernel/boot/platform/bios_ia32/platform_kernel_args.h b/headers/private/kernel/boot/platform/bios_ia32/platform_kernel_args.h index d0875e72c3..dd637cb791 100644 --- a/headers/private/kernel/boot/platform/bios_ia32/platform_kernel_args.h +++ b/headers/private/kernel/boot/platform/bios_ia32/platform_kernel_args.h @@ -1,5 +1,5 @@ /* - * Copyright 2003-2004, Axel Dörfler, axeld@pinc-software.de. + * Copyright 2003-2006, Axel Dörfler, axeld@pinc-software.de. * Distributed under the terms of the MIT License. */ #ifndef KERNEL_BOOT_PLATFORM_BIOS_IA32_KERNEL_ARGS_H @@ -9,6 +9,8 @@ # error This file is included from only #endif + +#include #include @@ -25,6 +27,8 @@ typedef struct { uint16 boot_drive_number; bios_drive *drives; // this does not contain the boot drive + + apm_info apm; } platform_kernel_args; #endif /* KERNEL_BOOT_PLATFORM_BIOS_IA32_KERNEL_ARGS_H */ diff --git a/src/system/boot/platform/bios_ia32/Jamfile b/src/system/boot/platform/bios_ia32/Jamfile index 4a40605dea..399725fb94 100644 --- a/src/system/boot/platform/bios_ia32/Jamfile +++ b/src/system/boot/platform/bios_ia32/Jamfile @@ -24,6 +24,7 @@ KernelMergeObject boot_platform_bios_ia32.o : smp_trampoline.S support.S video.cpp + apm.cpp # generic text_menu.cpp diff --git a/src/system/boot/platform/bios_ia32/apm.cpp b/src/system/boot/platform/bios_ia32/apm.cpp new file mode 100644 index 0000000000..e191707924 --- /dev/null +++ b/src/system/boot/platform/bios_ia32/apm.cpp @@ -0,0 +1,92 @@ +/* + * Copyright 2006, Axel Dörfler, axeld@pinc-software.de. + * Distributed under the terms of the MIT License. + */ + + +#include "apm.h" +#include "bios.h" + +#include +#include +#include + + +//#define TRACE_APM +#ifdef TRACE_APM +# define TRACE(x) dprintf x +#else +# define TRACE(x) ; +#endif + + +// int 0x15 APM definitions +#define BIOS_APM_CHECK 0x5300 +#define BIOS_APM_CONNECT_32_BIT 0x5303 +#define BIOS_APM_DISCONNECT 0x5304 + + +status_t +apm_init(void) +{ + // check if APM is available + + struct bios_regs regs; + regs.eax = BIOS_APM_CHECK; + regs.ebx = 0; + call_bios(0x15, ®s); + + if ((regs.flags & CARRY_FLAG) != 0 + || (regs.ebx & 0xffff) != 'PM') { + dprintf("No APM available.\n"); + return B_ERROR; + } + + apm_info &info = gKernelArgs.platform_args.apm; + info.version = regs.eax & 0xffff; + info.flags = regs.ecx & 0xffff; + + dprintf("APM version %d.%d available, flags %x.\n", + (info.version >> 8) & 0xf, info.version & 0xf, info.flags); + + if ((info.version & 0xf) < 2) { + // 32-bit protected mode interface was not available before 1.2 + return B_ERROR; + } + + // there can always be one connection, so make sure we're + // the one - and disconnect + + regs.eax = BIOS_APM_DISCONNECT; + regs.ebx = 0; + call_bios(0x15, ®s); + // We don't care if this fails - there might not have been + // any connection before. + + // try to connect to the 32-bit interface + + regs.eax = BIOS_APM_CONNECT_32_BIT; + regs.ebx = 0; + call_bios(0x15, ®s); + if ((regs.flags & CARRY_FLAG) != 0) + return B_ERROR; + + info.code32_segment_base = regs.eax & 0xffff; + info.code32_segment_offset = regs.ebx; + info.code32_segment_length = regs.esi & 0xffff; + + info.code16_segment_base = regs.ecx & 0xffff; + info.code16_segment_length = regs.esi >> 16; + + info.data_segment_base = regs.edx & 0xffff; + info.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)); + TRACE((" code16: 0x%x, length 0x%x\n", + info.code16_segment_base, info.code16_segment_length)); + TRACE((" data: 0x%x, length 0x%x\n", + info.data_segment_base, info.data_segment_length)); + + return B_OK; +} diff --git a/src/system/boot/platform/bios_ia32/apm.h b/src/system/boot/platform/bios_ia32/apm.h new file mode 100644 index 0000000000..2abe1fffe1 --- /dev/null +++ b/src/system/boot/platform/bios_ia32/apm.h @@ -0,0 +1,18 @@ +/* + * Copyright 2006, Axel Dörfler, axeld@pinc-software.de. + * Distributed under the terms of the MIT License. + */ +#ifndef APM_H +#define APM_H + + +#include + + +extern +#ifdef __cplusplus +"C" +#endif +status_t apm_init(void); + +#endif /* APM_H */ diff --git a/src/system/boot/platform/bios_ia32/start.c b/src/system/boot/platform/bios_ia32/start.c index 8e38402c4d..e9b9d30249 100644 --- a/src/system/boot/platform/bios_ia32/start.c +++ b/src/system/boot/platform/bios_ia32/start.c @@ -1,11 +1,12 @@ /* - * Copyright 2003-2005, Axel Dörfler, axeld@pinc-software.de. All rights reserved. + * Copyright 2003-2006, Axel Dörfler, axeld@pinc-software.de. All rights reserved. * Distributed under the terms of the MIT License. */ #include "serial.h" #include "console.h" +#include "apm.h" #include "cpu.h" #include "mmu.h" #include "smp.h" @@ -128,6 +129,7 @@ _start(void) //if (sBootOptions & BOOT_OPTION_DEBUG_OUTPUT) serial_enable(); + apm_init(); smp_init(); main(&args); }