Beginnings of APM support: we now connect to the APM BIOS in 32 bit protected mode.

We don't do anything with it yet, though, so the BIOS will probably ignore us since
we are supposed to poll for events.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@15900 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler 2006-01-10 22:54:36 +00:00
parent 5143d99bb0
commit ba61df6d0b
7 changed files with 151 additions and 6 deletions

View File

@ -0,0 +1,21 @@
#ifndef KERNEL_APM_H
#define KERNEL_APM_H
#include <SupportDefs.h>
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 */

View File

@ -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

View File

@ -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 <boot/kernel_args.h> only
#endif
#include <apm.h>
#include <bios_drive.h>
@ -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 */

View File

@ -24,6 +24,7 @@ KernelMergeObject boot_platform_bios_ia32.o :
smp_trampoline.S
support.S
video.cpp
apm.cpp
# generic
text_menu.cpp

View File

@ -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 <boot/kernel_args.h>
#include <boot/platform.h>
#include <boot/stage2.h>
//#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, &regs);
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, &regs);
// 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, &regs);
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;
}

View File

@ -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 <SupportDefs.h>
extern
#ifdef __cplusplus
"C"
#endif
status_t apm_init(void);
#endif /* APM_H */

View File

@ -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);
}