summaryrefslogtreecommitdiff
path: root/sys/arch
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arch')
-rw-r--r--sys/arch/i386/apm_init/Makefile56
-rw-r--r--sys/arch/i386/apm_init/Makefile.inc39
-rw-r--r--sys/arch/i386/apm_init/apm_bios.h185
-rw-r--r--sys/arch/i386/apm_init/apm_init.S215
-rw-r--r--sys/arch/i386/apm_init/apm_segments.h30
-rw-r--r--sys/arch/i386/apm_init/apm_setup.h24
-rw-r--r--sys/arch/i386/apm_init/bin2asm.sh21
-rw-r--r--sys/arch/i386/apm_init/real_prot.S186
-rw-r--r--sys/arch/i386/apm_init/real_prot.h57
-rw-r--r--sys/arch/i386/apm_init/rmaouthdr6
-rw-r--r--sys/arch/i386/apm_init/table.c25
-rw-r--r--sys/arch/i386/conf/HELIOS_PCMCIA39
-rw-r--r--sys/arch/i386/conf/Makefile.i3868
-rw-r--r--sys/arch/i386/conf/PCMCIA138
-rw-r--r--sys/arch/i386/conf/files.i38625
-rw-r--r--sys/arch/i386/i386/apm.c844
-rw-r--r--sys/arch/i386/i386/conf.c17
-rw-r--r--sys/arch/i386/i386/gdt.c12
-rw-r--r--sys/arch/i386/i386/genassym.c20
-rw-r--r--sys/arch/i386/i386/locore.s196
-rw-r--r--sys/arch/i386/i386/machdep.c28
-rw-r--r--sys/arch/i386/i386/mainbus.c17
-rw-r--r--sys/arch/i386/include/apmvar.h263
-rw-r--r--sys/arch/i386/include/gdt.h5
-rw-r--r--sys/arch/i386/include/segments.h5
25 files changed, 2431 insertions, 30 deletions
diff --git a/sys/arch/i386/apm_init/Makefile b/sys/arch/i386/apm_init/Makefile
new file mode 100644
index 00000000000..44e521eba13
--- /dev/null
+++ b/sys/arch/i386/apm_init/Makefile
@@ -0,0 +1,56 @@
+#
+# LP (Laptop Package)
+#
+# (C) 1994 by HOSOKAWA, Tatsumi <hosokawa@mt.cs.keio.ac.jp>
+#
+# This software may be used, modified, copied, and distributed in
+# both source and binary form provided that the above copyright and
+# these terms are retained. Under no circumstances is the author
+# responsible for the proper functioning of this software, nor does
+# the author assume any responsibility for damages incurred with its
+# use.
+#
+# Sep., 1994 Implemented on FreeBSD 1.1.5.1R (Toshiba AVS001WD)
+# Oct., 1994 NetBSD port (1.0 BETA 10/2) by ukai
+# Dec., 1995 NetBSD 1.1 kernel build retrofit, jtk@netbsd.org
+#
+
+DIR=${APMREL}${APMDIR}
+
+.if exists (${DIR}/arch/${MACHINE_ARCH}/Makefile.inc)
+.PATH: ${DIR}/arch/${MACHINE_ARCH}
+.include "${DIR}/arch/${MACHINE_ARCH}/Makefile.inc"
+.endif
+
+.PATH: ${DIR}
+
+CC = ${APMCC}
+CFLAGS += -DINITIALIZER -I${DIR} -DKERNEL \
+ ${APMCFLAGS:S@-I.@-I${KERNREL}.@g}
+
+OBJS = apm_init.o real_prot.o table.o
+
+#.SUFFIXES: .c .S .o
+#
+#.c.o:
+# $(CC) $(CFLAGS) $(OPTFLAGS) $(INC) -c $<
+#
+.S.o:
+ $(CC) $(CFLAGS) $(INC) -c $<
+
+apm_init.inc: apm_init
+ sh ${DIR}/bin2asm.sh apm_init > apm_init.inc
+
+apm_init: $(OBJS)
+ $(LD) -Bstatic -N -T 0 -o apm_init $(OBJS)
+ cp apm_init apm_init.sym
+ @strip apm_init
+ @sh ${DIR}/rmaouthdr apm_init apm_init.tmp
+ @mv -f apm_init.tmp apm_init
+
+#allclean: clean
+# @rm -f apm_init.inc
+clean:
+ rm -f *.o apm_init apm_init.sym apm_init.inc
+
+#.include <bsd.prog.mk>
diff --git a/sys/arch/i386/apm_init/Makefile.inc b/sys/arch/i386/apm_init/Makefile.inc
new file mode 100644
index 00000000000..715da6093c5
--- /dev/null
+++ b/sys/arch/i386/apm_init/Makefile.inc
@@ -0,0 +1,39 @@
+# $NetBSD: Makefile.inc,v 1.12 1995/10/07 09:56:55 mycroft Exp $
+#
+# NOTE: $S must correspond to the top of the 'sys' tree
+
+APMDIR= ${I386}/apm_init
+
+APMDST= lib/apm_init
+APMREL?= ../../
+APMINC?= ${APMDST}/apm_init.inc
+
+APMDEPS= \
+ ${APMDIR}/Makefile \
+ ${APMDIR}/apm_bios.h \
+ ${APMDIR}/apm_init.S \
+ ${APMDIR}/apm_segments.h \
+ ${APMDIR}/bin2asm.sh \
+ ${APMDIR}/real_prot.S \
+ ${APMDIR}/real_prot.h \
+ ${APMDIR}/rmaouthdr \
+ ${APMDIR}/table.c
+
+${APMINC}: ${APMDEPS} ${APMDST}
+ @echo making sure the apm grappling hook is up to date...
+ @(cd ${APMDST} && ${MAKE} -f ${APMREL}${APMDIR}/Makefile \
+ APMCC="${CC}" \
+ APMCFLAGS="${CFLAGS}" \
+ APMREL="${APMREL}" \
+ APMDIR="${APMDIR}" apm_init.inc)
+
+clean:: .NOTMAIN __always_make_apmlib
+ @echo cleaning the apm grappling hook objects
+ @(cd ${APMDST} && ${MAKE} -f ${APMREL}${APMDIR}/Makefile \
+ APMCC="${CC}" \
+ APMCFLAGS="${CFLAGS}" \
+ APMREL="${APMREL}" \
+ APMDIR="${APMDIR}" clean)
+
+${APMDST} __always_make_apmlib: .NOTMAIN
+ @([ -d ${APMDST} ] || mkdir -p ${APMDST})
diff --git a/sys/arch/i386/apm_init/apm_bios.h b/sys/arch/i386/apm_init/apm_bios.h
new file mode 100644
index 00000000000..5354b9ccfb7
--- /dev/null
+++ b/sys/arch/i386/apm_init/apm_bios.h
@@ -0,0 +1,185 @@
+/*
+ * Advanced Power Management (APM) BIOS driver for laptop PCs.
+ *
+ * Copyright (c) 1994 by HOSOKAWA Tatsumi <hosokawa@mt.cs.keio.ac.jp>
+ *
+ * This software may be used, modified, copied, and distributed, in
+ * both source and binary form provided that the above copyright and
+ * these terms are retained. Under no circumstances is the author
+ * responsible for the proper functioning of this software, nor does
+ * the author assume any responsibility for damages incurred with its
+ * use.
+ *
+ * Aug, 1994 Implemented on FreeBSD 1.1.5.1R (Toshiba AVS001WD)
+ * Oct, 1994 NetBSD port (1.0 BETA 10/2) by ukai
+ */
+
+#ifndef APM_BIOS_H
+#define APM_BIOS_H 1
+
+#ifdef KERNEL
+
+/* BIOS id */
+#define APM_BIOS 0x53
+#define SYSTEM_BIOS 0x15
+
+/* APM flags */
+#define APM_16BIT_SUPPORT 0x01
+#define APM_32BIT_SUPPORT 0x02
+#define APM_CPUIDLE_SLOW 0x04
+#define APM_DISABLED 0x08
+#define APM_DISENGAGED 0x10
+
+/* APM initializer physical address */
+#define APM_OURADDR 0x00080000
+
+/* Error code of APM initializer */
+#define APMINI_CANTFIND 0xffffffff
+#define APMINI_NOT32BIT 0xfffffffe
+#define APMINI_CONNECTERR 0xfffffffd
+#define APMINI_BADVER 0xfffffffc
+
+/* APM functions */
+#define APM_INSTCHECK 0x00
+#define APM_REALCONNECT 0x01
+#define APM_PROT16CONNECT 0x02
+#define APM_PROT32CONNECT 0x03
+#define APM_DISCONNECT 0x04
+#define APM_CPUIDLE 0x05
+#define APM_CPUBUSY 0x06
+#define APM_SETPWSTATE 0x07
+#define APM_ENABLEDISABLEPM 0x08
+#define APM_RESTOREDEFAULT 0x09
+#define APM_GETPWSTATUS 0x0a
+#define APM_GETPMEVENT 0x0b
+#define APM_GETPWSTATE 0x0c
+#define APM_ENABLEDISABLEDPM 0x0d
+#define APM_DRVVERSION 0x0e
+#define APM_ENGAGEDISENGAGEPM 0x0f
+#define APM_OEMFUNC 0x80
+
+/* error code */
+#define APME_OK 0x00
+#define APME_PMDISABLED 0x01
+#define APME_REALESTABLISHED 0x02
+#define APME_NOTCONNECTED 0x03
+#define APME_PROT16ESTABLISHED 0x05
+#define APME_PROT16NOTSUPPORTED 0x06
+#define APME_PROT32ESTABLISHED 0x07
+#define APME_PROT32NOTDUPPORTED 0x08
+#define APME_UNKNOWNDEVICEID 0x09
+#define APME_OUTOFRANGE 0x0a
+#define APME_NOTENGAGED 0x0b
+#define APME_CANTENTERSTATE 0x60
+#define APME_NOPMEVENT 0x80
+#define APME_NOAPMPRESENT 0x86
+
+
+/* device code */
+#define PMDV_APMBIOS 0x0000
+#define PMDV_ALLDEV 0x0001
+#define PMDV_DISP0 0x0100
+#define PMDV_DISP1 0x0101
+#define PMDV_2NDSTORAGE0 0x0200
+#define PMDV_2NDSTORAGE1 0x0201
+#define PMDV_2NDSTORAGE2 0x0202
+#define PMDV_2NDSTORAGE3 0x0203
+#define PMDV_PARALLEL0 0x0300
+#define PMDV_PARALLEL1 0x0301
+#define PMDV_SERIAL0 0x0400
+#define PMDV_SERIAL1 0x0401
+#define PMDV_SERIAL2 0x0402
+#define PMDV_SERIAL3 0x0403
+#define PMDV_SERIAL4 0x0404
+#define PMDV_SERIAL5 0x0405
+#define PMDV_SERIAL6 0x0406
+#define PMDV_SERIAL7 0x0407
+#define PMDV_NET0 0x0500
+#define PMDV_NET1 0x0501
+#define PMDV_NET2 0x0502
+#define PMDV_NET3 0x0503
+#define PMDV_PCMCIA0 0x0600
+#define PMDV_PCMCIA1 0x0601
+#define PMDV_PCMCIA2 0x0602
+#define PMDV_PCMCIA3 0x0603
+/* 0x0700 - 0xdfff Reserved */
+/* 0xe000 - 0xefff OEM-defined power device IDs */
+/* 0xf000 - 0xffff Reserved */
+
+/* Power state */
+#define PMST_APMENABLED 0x0000
+#define PMST_STANDBY 0x0001
+#define PMST_SUSPEND 0x0002
+#define PMST_OFF 0x0003
+#define PMST_LASTREQNOTIFY 0x0004
+#define PMST_LASTREQREJECT 0x0005
+/* 0x0006 - 0x001f Reserved system states */
+/* 0x0020 - 0x003f OEM-defined system states */
+/* 0x0040 - 0x007f OEM-defined device states */
+/* 0x0080 - 0xffff Reserved device states */
+
+#if !defined(ASM) && !defined(INITIALIZER)
+
+/* C definitions */
+typedef struct apm_hook_func {
+ struct apm_hook_func *next; /* Linked list */
+ int (*func)(void);
+ const char *name;
+ int order;
+} *apm_hook_func_t;
+
+apm_hook_func_t apm_resume_hook_init(int (*func)(void), char *name, int order);
+void apm_resume_hook_delete(apm_hook_func_t delete_func);
+apm_hook_func_t apm_suspend_hook_init(int (*func)(void), char *name, int order);
+void apm_suspend_hook_delete(apm_hook_func_t delete_func);
+void apm_suspend_resume(void);
+void apm_cpu_idle(void);
+void apm_cpu_busy(void);
+
+#endif /* !ASM && !INITIALIZER */
+
+#define APM_MIN_ORDER 0x00
+#define APM_MID_ORDER 0x80
+#define APM_MAX_ORDER 0xff
+
+#endif /* KERNEL */
+
+/* power management event code */
+#define PMEV_NOEVENT 0x0000
+#define PMEV_STANDBYREQ 0x0001
+#define PMEV_SUSPENDREQ 0x0002
+#define PMEV_NORMRESUME 0x0003
+#define PMEV_CRITRESUME 0x0004
+#define PMEV_BATTERYLOW 0x0005
+#define PMEV_POWERSTATECHANGE 0x0006
+#define PMEV_UPDATETIME 0x0007
+#define PMEV_CRITSUSPEND 0x0008
+#define PMEV_USERSTANDBYREQ 0x0009
+#define PMEV_USERSUSPENDREQ 0x000a
+#define PMEV_STANDBYRESUME 0x000b
+/* 0x000c - 0x00ff Reserved system events */
+/* 0x0100 - 0x01ff Reserved device events */
+/* 0x0200 - 0x02ff OEM-defined APM events */
+/* 0x0300 - 0xffff Reserved */
+#define PMEV_DEFAULT 0xffffffff /* used for customization */
+
+#if !defined(ASM) && !defined(INITIALIZER)
+
+typedef struct apm_info {
+ u_int ai_major; /* APM major version */
+ u_int ai_minor; /* APM minor version */
+ u_int ai_acline; /* AC line status */
+ u_int ai_batt_stat; /* Battery status */
+ u_int ai_batt_life; /* Remaining battery life */
+} *apm_info_t;
+
+#define APMIO_SUSPEND _IO('P', 1)
+#define APMIO_GETINFO _IOR('P', 2, struct apm_info)
+#define APMIO_ENABLE _IO('P', 3)
+#define APMIO_DISABLE _IO('P', 4)
+#define APMIO_HALTCPU _IO('P', 5)
+#define APMIO_NOTHALTCPU _IO('P', 6)
+
+#endif /* !ASM && !INITIALIZER */
+
+#endif /* APM_BIOS_H */
diff --git a/sys/arch/i386/apm_init/apm_init.S b/sys/arch/i386/apm_init/apm_init.S
new file mode 100644
index 00000000000..945c251446a
--- /dev/null
+++ b/sys/arch/i386/apm_init/apm_init.S
@@ -0,0 +1,215 @@
+/*
+ * LP (Laptop Package)
+ *
+ * Copyright (C) 1994 by HOSOKAWA, Tatsumi <hosokawa@mt.cs.keio.ac.jp>
+ *
+ * This software may be used, modified, copied, and distributed, in
+ * both source and binary form provided that the above copyright and
+ * these terms are retained. Under no circumstances is the author
+ * responsible for the proper functioning of this software, nor does
+ * the author assume any responsibility for damages incurred with its
+ * use.
+ *
+ * Sep., 1994 Implemented on FreeBSD 1.1.5.1R (Toshiba AVS001WD)
+ * Oct., 1994 NetBSD port (1.0 BETA 10/2) by ukai
+ */
+
+/*
+ * If you want to know the specification of APM BIOS, see the following
+ * documentations,
+ *
+ * [1] Intel Corporation and Microsoft Corporation, "Advanced Power
+ * Management, The Next Generation, Version 1.0", Feb.,1992.
+ *
+ * [2] Intel Corporation and Microsoft Corporation, "Advanced Power
+ * Management (APM) BIOS Interface Specification Revision 1.1",
+ * Sep.,1993, Intel Order Number: 241704-001, Microsoft Part
+ * Number: 781-110-X01
+ *
+ * or contact
+ *
+ * APM Support Desk (Intel Corporation, US)
+ * TEL: (800)628-8686
+ * FAX: (916)356-6100.
+ */
+
+ .file "apm_init.S"
+
+#define ASM
+
+#include "real_prot.h"
+#include <apm_bios.h>
+#include <apm_segments.h>
+
+/*
+ * APM BIOS initializer
+ *
+ * Return value:
+ * %eax 0xfffffff Can't find APM BIOS
+ * 0xffffffe Don't support 32bit connection
+ * 0xffffffd Connection error
+ * otherwise APM version (16bit BCD format)
+ * %ebx APM cs entry offset (32bit)
+ * %ecx lower 16bit APM 16bit cs base (real mode segment)
+ * upper 16bit APM 32bit cs base (real mode segment)
+ * %edx lower 16bit APM ds limit (real mode segment)
+ * upper 16bit [Reserved]
+ * %esi lower 16bit APM cs limit (APM 1.1 or later)
+ * upper 16bit APM ds limit (APM 1.1 or later)
+ * %edi bit0 = 1 16bit protected mode interface supported
+ * bit1 = 1 32bit protected mode interface supported
+ * bit2 = 1 "CPU idle" call slows processor clock speed
+ * bit3 = 1 APM BIOS Power Management disabled
+ * bit4 = 1 APM BIOS Power Management disengaged
+ */
+
+ .text
+ENTRY(apm_init)
+ cli /* disable interrupt */
+ push %ebp /* save original base pointer */
+ /* ebp is used as a register variable */
+ /*
+ * save old data segments: We assume that %ds == %es && %ds == %ss
+ */
+ push %fs
+ movw %ds, %ax
+ movw %ax, %fs
+ movw $(APM_INIT_DS_SEL), %ax /* initializer data segment */
+ movw %ax, %ds
+ movw %ax, %es
+ movw %ax, %ss
+ movl %esp, old_esp /* save original stack pointer */
+ movl $0xf000, %esp /* setup temporary stack */
+ /* (note that it isn't 0x00000000) */
+
+ sidt EXT(Idtr_prot) /* save current IDT */
+ call EXT(prot_to_real) /* return to real mode */
+
+ /*
+ * APM installation check
+ */
+ movb $(APM_BIOS), %ah
+ movb $(APM_INSTCHECK), %al
+ data32
+ movl $(PMDV_APMBIOS), %ebx
+ sti
+ int $(SYSTEM_BIOS) /* call system BIOS */
+ cli
+
+ jnc 1f /* if found, goto 1f */
+
+ data32
+ call EXT(real_to_prot) /* come back again to protected mode */
+ movl $(APMINI_CANTFIND), apm_version
+ /* can't find APM BIOS */
+ jmp finish
+
+1:
+ movl %eax, %edx /* actually, movw %ax, %dx */
+ /* save the value of %ax */
+ data32
+ call EXT(real_to_prot) /* come back again to protected mode */
+ cmpb $0x50, %bh /* %bh == 'P'? */
+ jnz 1f
+ cmpb $0x4d, %bl /* %bl == 'M'? */
+ jz 2f
+
+1:
+ movl $(APMINI_BADVER), apm_version
+ /* can't find APM BIOS */
+ jmp finish
+
+2:
+ testl $(APM_32BIT_SUPPORT), %ecx
+ /* supports 32bit connection? */
+ jnz 1f
+
+ movl $(APMINI_NOT32BIT), apm_version
+ /* don't support 32bit connection */
+ jmp finish
+1:
+ movl %edx, apm_version
+ andl $0x0000ffff, %ecx
+ movl %ecx, apm_flags
+
+ /*
+ * APM Protected Mode 32-bit Interface Connect
+ */
+ call EXT(prot_to_real) /* return to real mode */
+
+ movb $(APM_BIOS), %ah
+ movb $(APM_DISCONNECT), %al /* just in case bootloader connected*/
+ data32
+ movl $(PMDV_APMBIOS), %ebx
+ sti
+ int $(SYSTEM_BIOS)
+ cli
+ movb $(APM_BIOS), %ah
+ movb $(APM_PROT32CONNECT), %al
+ data32
+ movl $(PMDV_APMBIOS), %ebx
+ sti
+ int $(SYSTEM_BIOS)
+ cli
+ jnc 1f /* if successed, go to 1f */
+ data32
+ call EXT(real_to_prot)
+ movl $(APMINI_CONNECTERR), apm_version
+ /* connection error */
+ jmp finish
+1:
+ /* save PM 32bit code segment into %bp */
+ movl %eax, %ebp /* actually, movw %ax, %bp */
+ data32
+ call EXT(real_to_prot)
+ movl $0x0000ffff, %eax
+ andl %eax, %ebp /* 32bit cs base */
+ andl %eax, %ecx /* 16bit cs base */
+ andl %eax, %edx /* ds base */
+ andl %eax, %esi /* cs length (APM 1.1 or later) */
+ andl %eax, %edi /* ds length (APM 1.1 or later) */
+ /* %ebx is code offset */
+ /* pack 32bit cs and 16bit cs into %ecx */
+ shll $16, %ebp
+ orl %ebp, %ecx
+ /* pack cs length and ds length into %esi */
+ shll $16, %edi
+ orl %edi, %esi
+finish:
+ cli
+ lidt EXT(Idtr_prot) /* restore old IDTR */
+ movl old_esp, %esp /* restore old stack pointer */
+ movl apm_version, %ebp /* stored to %eax later */
+ movl apm_flags, %edi
+#if 0
+ movw $(BOOTSTRAP_DS_SEL), %ax
+ /* restore old data segments */
+#else
+ movw %fs, %ax
+#endif
+ movw %ax, %ss
+ movw %ax, %es
+ movw %ax, %ds
+ movl %ebp, %eax
+ pop %fs
+ popl %ebp /* restore old base pointer */
+ lret /* restore old code segment */
+
+ .data
+
+ .globl EXT(ouraddr)
+LEXT(ouraddr)
+ .long APM_OURADDR
+
+old_esp:
+ .long 0
+apm_version:
+ .long 0
+apm_flags:
+ .long 0
+old_ds:
+ .word 0
+old_es:
+ .word 0
+old_ss:
+ .word 0
diff --git a/sys/arch/i386/apm_init/apm_segments.h b/sys/arch/i386/apm_init/apm_segments.h
new file mode 100644
index 00000000000..5e5fcdbe7e4
--- /dev/null
+++ b/sys/arch/i386/apm_init/apm_segments.h
@@ -0,0 +1,30 @@
+/*
+ * LP (Laptop Package)
+ *
+ * Copyright (C) 1994 by HOSOKAWA Tatsumi <hosokawa@mt.cs.keio.ac.jp>
+ *
+ * This software may be used, modified, copied, and distributed, in
+ * both source and binary form provided that the above copyright and
+ * these terms are retained. Under no circumstances is the author
+ * responsible for the proper functioning of this software, nor does
+ * the author assume any responsibility for damages incurred with its
+ * use.
+ *
+ * Sep., 1994 Implemented on FreeBSD 1.1.5.1R (Toshiba AVS001WD)
+ */
+
+#define SIZEOF_GDT 8
+#define BOOTSTRAP_GDT_NUM 9
+
+#define APM_INIT_CS_INDEX (BOOTSTRAP_GDT_NUM - 3)
+#define APM_INIT_DS_INDEX (BOOTSTRAP_GDT_NUM - 2)
+#define APM_INIT_CS16_INDEX (BOOTSTRAP_GDT_NUM - 1)
+#define APM_INIT_CS_SEL (APM_INIT_CS_INDEX << 3)
+#define APM_INIT_DS_SEL (APM_INIT_DS_INDEX << 3)
+#define APM_INIT_CS16_SEL (APM_INIT_CS16_INDEX << 3)
+
+#define CS32_ATTRIB 0x4F9e
+#define CS16_ATTRIB 0x009e
+#define DS32_ATTRIB 0x4F92
+
+#define BOOTSTRAP_DS_SEL 0x10
diff --git a/sys/arch/i386/apm_init/apm_setup.h b/sys/arch/i386/apm_init/apm_setup.h
new file mode 100644
index 00000000000..fdc380e50be
--- /dev/null
+++ b/sys/arch/i386/apm_init/apm_setup.h
@@ -0,0 +1,24 @@
+/*
+ * LP (Laptop Package)
+ *
+ * Copyright (C) 1994 by HOSOKAWA, Tatsumi <hosokawa@mt.cs.keio.ac.jp>
+ *
+ * This software may be used, modified, copied, distributed, and sold,
+ * in both source and binary form provided that the above copyright and
+ * these terms are retained. Under no circumstances is the author
+ * responsible for the proper functioning of this software, nor does
+ * the author assume any responsibility for damages incurred with its
+ * use.
+ *
+ * Sep., 1994 Implemented on FreeBSD 1.1.5.1R (Toshiba AVS001WD)
+ * Oct., 1994 NetBSD port (1.0 BETA 10/2) by ukai
+ */
+
+extern u_long apm_version;
+extern u_long apm_cs_entry;
+extern u_short apm_cs32_base;
+extern u_short apm_cs16_base;
+extern u_short apm_ds_base;
+extern u_short apm_cs_limit;
+extern u_short apm_ds_limit;
+extern u_short apm_flags;
diff --git a/sys/arch/i386/apm_init/bin2asm.sh b/sys/arch/i386/apm_init/bin2asm.sh
new file mode 100644
index 00000000000..6694b49d9b5
--- /dev/null
+++ b/sys/arch/i386/apm_init/bin2asm.sh
@@ -0,0 +1,21 @@
+#!/bin/sh -
+# bin2asm (binary to asm) shell script version by ukai
+#
+#
+if [ $# -lt 1 ]; then
+ echo 'usage: $0 [in]'
+ exit 1
+fi
+in=$1
+size=`ls -l ${in} | awk '{print $5}'`
+# Oops, must 8 byte align
+len=`expr \( $size + 8 \) / 8 \* 8`
+
+echo "/* This file is automatically generated by bin2asm.sh */"
+echo "/* Original file is '${in}' */"
+echo
+dd if=${in} bs=${len} conv=sync |\
+ hexdump -v -e '" .byte " 7/1 "0x%02x, " 1/1 " 0x%02x" "\n"'
+echo
+echo "/* Total size = $size -> $len */"
+echo "/* End of File */"
diff --git a/sys/arch/i386/apm_init/real_prot.S b/sys/arch/i386/apm_init/real_prot.S
new file mode 100644
index 00000000000..5f9e97ecf68
--- /dev/null
+++ b/sys/arch/i386/apm_init/real_prot.S
@@ -0,0 +1,186 @@
+/*
+ * Mach Operating System
+ * Copyright (c) 1992, 1991 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie Mellon
+ * the rights to redistribute these changes.
+ *
+ * from: Mach, Revision 2.2 92/04/04 11:34:13 rpd
+ * $Id: real_prot.S,v 1.1 1996/04/29 14:15:43 hvozda Exp $
+ */
+
+
+/*
+ Copyright 1988, 1989, 1990, 1991, 1992
+ by Intel Corporation, Santa Clara, California.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and
+its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appears in all
+copies and that both the copyright notice and this permission notice
+appear in supporting documentation, and that the name of Intel
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+
+INTEL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
+IN NO EVENT SHALL INTEL BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
+CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
+NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*/
+
+/*
+ * LP (Laptop Package)
+ *
+ * Copyright (C) 1994 by HOSOKAWA, Tatsumi <hosokawa@mt.cs.keio.ac.jp>
+ *
+ * This software may be used, modified, copied, and distributed, in
+ * both source and binary form provided that the above copyright and
+ * these terms are retained. Under no circumstances is the author
+ * responsible for the proper functioning of this software, nor does
+ * the author assume any responsibility for damages incurred with its
+ * use.
+ *
+ * Sep., 1994 Implemented on FreeBSD 1.1.5.1R (Toshiba AVS001WD)
+ * Oct., 1994 NetBSD port (1.0 BETA 10/2) by ukai
+ */
+
+/*
+ * Modified for APM BIOS initializer by HOSOKAWA Tatsumi
+ *
+ * See also locore.s. It supports these functions works correctly.
+ */
+
+ .file "real_prot.S"
+
+#include "real_prot.h"
+#include "apm_segments.h"
+
+CR0_PE_ON = 0x1
+CR0_PE_OFF = 0xfffffffe
+
+.globl _ouraddr
+ .text
+
+/*
+ *
+ * real_to_prot()
+ * transfer from real mode to protected mode.
+ */
+
+ENTRY(real_to_prot)
+ /* guarantee that interrupt is disabled when in prot mode */
+ cli
+
+ /*
+ * deleted for APM initializer by HOSOKAWA Tatsumi
+ * <hosoakwa@mt.cs.keio.ac.jp>
+ */
+#if 0
+ /* load the gdtr */
+ addr32
+ data32
+ lgdt EXT(Gdtr)
+#endif
+
+ /* set the PE bit of CR0 */
+ mov %cr0, %eax
+
+ data32
+ or $CR0_PE_ON, %eax
+ mov %eax, %cr0
+
+ /*
+ * make intrasegment jump to flush the processor pipeline and
+ * reload CS register
+ */
+ data32
+ ljmp $(APM_INIT_CS_SEL), $xprot
+
+xprot:
+ /*
+ * we are in USE32 mode now
+ * set up the protected mode segment registers : DS, SS, ES
+ */
+ mov $(APM_INIT_DS_SEL), %eax
+ movw %ax, %ds
+ movw %ax, %ss
+ movw %ax, %es
+
+ /* load idtr so we can debug */
+ lidt EXT(Idtr_prot)
+
+ ret
+
+/*
+ *
+ * prot_to_real()
+ * transfer from protected mode to real mode
+ *
+ */
+
+ENTRY(prot_to_real)
+
+ /* set up a dummy stack frame for the second seg change. */
+ movl _ouraddr, %eax
+ sarl $4, %eax
+ pushw %ax
+ movw $xreal, %ax /* gas botches pushw $xreal - extra bytes 0, 0*/
+ pushw %ax /* decode to add %al, (%eax) (%al usually 0) */
+
+ /* Change to use16 mode. */
+ ljmp $(APM_INIT_CS16_SEL), $x16
+
+x16:
+ /* clear the PE bit of CR0 */
+ mov %cr0, %eax
+ data32
+ and $CR0_PE_OFF, %eax
+ mov %eax, %cr0
+
+ /*
+ * make intersegment jmp to flush the processor pipeline
+ * using the fake stack frame set up earlier
+ * and reload CS register
+ */
+ lret
+
+xreal:
+ /*
+ * we are in real mode now
+ * set up the real mode segment registers : DS, SS, ES
+ */
+ movw %cs, %ax
+ movw %ax, %ds
+ movw %ax, %ss
+ movw %ax, %es
+
+ /* load idtr so we can debug */
+ addr32
+ data32
+ lidt EXT(Idtr_real)
+
+ data32
+ ret
diff --git a/sys/arch/i386/apm_init/real_prot.h b/sys/arch/i386/apm_init/real_prot.h
new file mode 100644
index 00000000000..51e91cf05d9
--- /dev/null
+++ b/sys/arch/i386/apm_init/real_prot.h
@@ -0,0 +1,57 @@
+/*
+ * Mach Operating System
+ * Copyright (c) 1991,1990,1989 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie Mellon
+ * the rights to redistribute these changes.
+ *
+ * from: Mach, Revision 2.7 92/02/29 15:33:41 rpd
+ * $Id: real_prot.h,v 1.1 1996/04/29 14:15:14 hvozda Exp $
+ */
+
+/*
+ * LP (Laptop Package)
+ *
+ * Copyright (C) 1994 by HOSOKAWA, Tatsumi <hosokawa@mt.cs.keio.ac.jp>
+ *
+ * This software may be used, modified, copied, and distributed, in
+ * both source and binary form provided that the above copyright and
+ * these terms are retained. Under no circumstances is the author
+ * responsible for the proper functioning of this software, nor does
+ * the author assume any responsibility for damages incurred with its
+ * use.
+ *
+ * Sep., 1994 Implemented on FreeBSD 1.1.5.1R (Toshiba AVS001WD)
+ * Oct., 1994 NetBSD port (1.0 BETA 10/2) by ukai
+ */
+
+/*
+ * Modified to APM BIOS initializer by HOSOKAWA, Tatsumi
+ */
+
+#define ALIGN 4
+#define EXT(x) _ ## x
+#define LEXT(x) _ ## x ## :
+
+#define addr32 .byte 0x67
+#define data32 .byte 0x66
+
+#define ENTRY(x) .globl EXT(x); .align ALIGN; LEXT(x)
diff --git a/sys/arch/i386/apm_init/rmaouthdr b/sys/arch/i386/apm_init/rmaouthdr
new file mode 100644
index 00000000000..608715015fe
--- /dev/null
+++ b/sys/arch/i386/apm_init/rmaouthdr
@@ -0,0 +1,6 @@
+#!/bin/csh -f
+#
+# from: Mach, Revision 2.2 92/04/04 11:36:01 rpd
+# $Id: rmaouthdr,v 1.1 1996/04/29 14:15:35 hvozda Exp $
+#
+dd if=$1 of=$2 ibs=32 skip=1 obs=1024b
diff --git a/sys/arch/i386/apm_init/table.c b/sys/arch/i386/apm_init/table.c
new file mode 100644
index 00000000000..d3cc1d98670
--- /dev/null
+++ b/sys/arch/i386/apm_init/table.c
@@ -0,0 +1,25 @@
+/*
+ * LP (Laptop Package)
+ *
+ * Copyright (C) 1994 by HOSOKAWA, Tatsumi <hosokawa@mt.cs.keio.ac.jp>
+ *
+ * This software may be used, modified, copied, and distributed, in
+ * both source and binary form provided that the above copyright and
+ * these terms are retained. Under no circumstances is the author
+ * responsible for the proper functioning of this software, nor does
+ * the author assume any responsibility for damages incurred with its
+ * use.
+ *
+ * Sep., 1994 Implemented on FreeBSD 1.1.5.1R (Toshiba AVS001WD)
+ * Oct., 1994 NetBSD port (1.0 BETA 10/2) by ukai
+ */
+
+#include <apm_bios.h>
+
+struct pseudo_desc {
+ unsigned short limit;
+ unsigned long base __attribute__ ((packed));
+};
+
+struct pseudo_desc Idtr_prot = { 0, 0 }; /* filled on run time */
+struct pseudo_desc Idtr_real = { 0x400 - 1, 0x0 };
diff --git a/sys/arch/i386/conf/HELIOS_PCMCIA b/sys/arch/i386/conf/HELIOS_PCMCIA
index b412cdfb0ad..2b91d0e76f8 100644
--- a/sys/arch/i386/conf/HELIOS_PCMCIA
+++ b/sys/arch/i386/conf/HELIOS_PCMCIA
@@ -1,4 +1,4 @@
-# $OpenBSD: HELIOS_PCMCIA,v 1.3 1996/04/18 18:55:35 niklas Exp $
+# $OpenBSD: HELIOS_PCMCIA,v 1.4 1996/04/29 14:12:01 hvozda Exp $
#
# HELIOS_PCMCIA -- Eric Hvozda's notebook
#
@@ -25,6 +25,7 @@ options KTRACE # system call tracing, a la ktrace(1)
options COMPAT_NOMID # compatibility with 386BSD, BSDI, NetBSD 0.8,
options COMPAT_09 # NetBSD 0.9,
options COMPAT_10 # NetBSD 1.0,
+options COMPAT_11 # NetBSD 1.1,
options COMPAT_43 # and 4.3BSD
options LKM # loadable kernel modules
@@ -48,26 +49,46 @@ options FDSCRIPTS # secure setuid scripts
options INET # IP + ICMP + TCP + UDP
-config bsd root on wd0a swap on wd0b and vnd0b dumps on wd0b
+config bsd root on wd0a swap on wd0b dumps on wd0b
mainbus0 at root
isa0 at mainbus0
pci0 at mainbus0
+#apm0 at mainbus0
npx0 at isa? port 0xf0 irq 13 # math coprocessor
pc0 at isa? port 0x60 irq 1 # generic PC console device
-
-pcic0 at isa? port 0x3E0 flags 0
-pcmcia0 at pcic? iomem 0xd4000 iosiz 4096
-com2 at pcmcia? port 0x3e8 irq 12
-ed2 at pcmcia? port 0x300 iomem 0xcc000 irq 10
+#spkr0 at pckbd? port 0x61 # PC speaker
+
+# Multiple controllers need some testing. Some laptops have multiple PCIC
+# controllers instead of two-slot controllers.
+# The i82365 (pcic) controller uses the same ports for the first two
+# controllers and for the second two controllers.
+
+# IRQ 2/9 doesn't seem to work for status change interrupts, so use one
+# of the higher ones.
+pcicmaster0 at isa? port 0x3E0 size 2
+pcic0 at pcicmaster0 irq 11 iomem 0xd4000 iosiz 4096
+pcic1 at pcicmaster0 irq 12 iomem 0xd5000 iosiz 4096
+pcicmaster1 at isa? port 0x3E2 size 2
+pcic2 at pcicmaster1 irq 11 iomem 0xd6000 iosiz 4096
+pcic3 at pcicmaster1 irq 12 iomem 0xd7000 iosiz 4096
+
+pcmcia* at pcic?
+
+#ed0 at pcmcia? port 0x300 iomem 0xd8000 iosiz 8192 irq 10
+ed0 at pcmcia? port 0x300 size 0x20 irq 10 slot ?
+#ep0 at pcmcia? port 0x300 size 0x10 irq 10 slot ?
+#com1 at pcmcia? port 0x2f8 size 8 irq 5 slot ?
+com2 at pcmcia? port 0x3e8 size 8 irq 5 slot ?
+#com3 at pcmcia? port 0x2e8 size 8 irq 3 slot ?
com0 at isa? port 0x3f8 irq 4 # standard PC serial ports
com1 at isa? port 0x2f8 irq 3
-lpt0 at isa? port 0x378 irq 7 # standard PC parallel ports
+lpt0 at isa? port 0x378 # standard PC parallel ports
fdc0 at isa? port 0x3f0 irq 6 drq 2 # standard PC floppy controllers
fd0 at fdc? drive 0
@@ -75,7 +96,7 @@ fd0 at fdc? drive 0
wdc0 at isa? port 0x1f0 irq 14 # ST506, ESDI, and IDE controllers
wd0 at wdc? drive 0
-sb0 at isa? port 0x240 irq 5 drq 1 # SoundBlaster
+sb0 at isa? port 0x240 irq 7 drq 1 # SoundBlaster
pseudo-device loop 1 # network loopback
pseudo-device bpfilter 8 # packet filter
diff --git a/sys/arch/i386/conf/Makefile.i386 b/sys/arch/i386/conf/Makefile.i386
index aee08091430..0edf4047ae1 100644
--- a/sys/arch/i386/conf/Makefile.i386
+++ b/sys/arch/i386/conf/Makefile.i386
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile.i386,v 1.8 1996/04/24 12:05:17 mickey Exp $
+# $OpenBSD: Makefile.i386,v 1.9 1996/04/29 14:12:10 hvozda Exp $
# $NetBSD: Makefile.i386,v 1.66 1996/02/29 20:56:16 cgd Exp $
# Makefile for OpenBSD
@@ -145,10 +145,14 @@ links:
sed 's,../.*/\(.*.o\),rm -f \1; ln -s ../GENERIC/\1 \1,' > makelinks
sh makelinks && rm -f dontlink
+# depend on APM
+.include "${I386}/apm_init/Makefile.inc"
+locore.o: ${APMINC}
+
SRCS= ${I386}/i386/locore.s \
param.c ioconf.c ${CFILES} ${SFILES}
depend: .depend
-.depend: ${SRCS} assym.h param.c
+.depend: ${SRCS} assym.h param.c ${APMINC}
mkdep ${AFLAGS} ${CPPFLAGS} ${I386}/i386/locore.s
mkdep -a ${CFLAGS} ${CPPFLAGS} param.c ioconf.c ${CFILES}
mkdep -a ${AFLAGS} ${CPPFLAGS} ${SFILES}
diff --git a/sys/arch/i386/conf/PCMCIA b/sys/arch/i386/conf/PCMCIA
new file mode 100644
index 00000000000..2544e06c62c
--- /dev/null
+++ b/sys/arch/i386/conf/PCMCIA
@@ -0,0 +1,138 @@
+# $Id: PCMCIA,v 1.1 1996/04/29 14:12:24 hvozda Exp $
+# $Source: /cvs/OpenBSD/src/sys/arch/i386/conf/Attic/PCMCIA,v $
+#
+# ATHENA-AHA -- ATHENA kernel for Adaptec & others...
+#
+# from: GENERIC -- everything that's currently supported
+# NetBSD: GENERIC,v 1.12 1995/02/21 01:43:02 brezak Exp
+#
+
+machine i386 # architecture, used by config; REQUIRED
+
+options I586_CPU
+options I486_CPU
+options I386_CPU
+options INSECURE
+options MATH_EMULATE
+
+options DUMMY_NOPS # speed hack; recommanded
+options XSERVER,UCONSOLE
+options MACHINE_NONCONTIG
+
+maxusers 32 # estimated number of users
+options TIMEZONE=300 # time zone to adjust RTC time by
+options DST=1 # daylight savings time used by RTC
+
+options SWAPPAGER # paging; REQUIRED
+options VNODEPAGER # mmap() of files
+options DEVPAGER # mmap() of devices
+
+options DDB # in-kernel debugger
+#makeoptions DEBUG="-g" # compile full symbol table
+#options DIAGNOSTIC # internally consistency checks
+options KTRACE # system call tracing, a la ktrace(1)
+
+options SYSVMSG # System V-like message queues
+options SYSVSEM # System V-like semaphores
+options SYSVSHM # System V-like memory sharing
+#options SHMMAXPGS=1024 # 1024 pages is the default
+
+options COMPAT_NOMID # compatibility with 386BSD, BSDI, NetBSD 0.8,
+options COMPAT_09 # NetBSD 0.9,
+options COMPAT_10 # NetBSD 1.0,
+options COMPAT_43 # and 4.3BSD
+options TCP_COMPAT_42 # TCP bug compatibility with 4.2BSD
+
+options COMPAT_SVR4 # binary compatibility with SVR4
+options COMPAT_IBCS2 # binary compatibility with SCO and ISC
+options COMPAT_LINUX # binary compatibility with Linux
+
+options USER_LDT # user-settable LDT; used by WINE
+options LKM # loadable kernel modules
+
+options FFS #,QUOTA # UFS and quotas
+#options LFS # log-structured file system
+options MFS # memory file system
+
+options NFSCLIENT # Network File System client
+options NFSSERVER # Network File System server
+options HAS_VOPLEASE # XXX
+
+options APM_NOIDLE
+#options PCIVERBOSE
+#options PCMCIA_DEBUG
+#options PCMCIA_ISA_DEBUG
+
+### SCSI:
+#options CD9660 # ISO 9660 + Rock Ridge file system
+###
+options MSDOSFS # MS-DOS file system
+options FIFO # FIFOs; RECOMMENDED
+options PROCFS # /proc
+
+#options GATEWAY # packet forwarding
+options INET # IP + ICMP + TCP + UDP
+#options NS # XNS
+#options ISO,TPIP # OSI
+#options EON # OSI tunneling over IP
+#options CCITT,LLC,HDLC # X.25
+
+config netbsd swap generic
+options GENERIC
+
+# Local Athena options
+
+options PCVT_CTRL_ALT_DEL # For screwed-over Linux weenies
+
+mainbus0 at root
+isa0 at mainbus0
+pci0 at mainbus0 bus 0
+
+npx0 at isa? port 0xf0 irq 13 # math coprocessor
+
+vt0 at isa? port 0x60 irq 1
+
+com0 at isa? port 0x3f8 irq 4 # standard PC serial ports
+com1 at isa? port 0x2f8 irq 3
+com2 at isa? port 0x3e8 irq 5
+
+lpt0 at isa? port 0x378 irq 7 # standard PC parallel ports
+
+pms0 at pckbd? irq 12 # PS/2 auxiliary port mouse
+
+fdc0 at isa? port 0x3f0 irq 6 drq 2 # standard PC floppy controllers
+fd0 at fdc0 drive 0
+
+wdc0 at isa? port 0x1f0 irq 14 # ST506, ESDI, and IDE controllers
+wd0 at wdc0 drive 0
+
+spkr0 at pckbd? port 0x61
+#apm0 at mainbus?
+
+# Multiple controllers need some testing. Some laptops have multiple PCIC
+# controllers instead of two-slot controllers.
+# The i82365 (pcic) controller uses the same ports for the first two
+# controllers and for the second two controllers.
+
+# IRQ 2/9 doesn't seem to work for status change interrupts, so use one
+# of the higher ones.
+pcicmaster0 at isa? port 0x3E0 size 2
+pcic0 at pcicmaster0 irq 11 iomem 0xd4000 iosiz 4096
+pcic1 at pcicmaster0 irq 12 iomem 0xd5000 iosiz 4096
+pcicmaster1 at isa? port 0x3E2 size 2
+pcic2 at pcicmaster1 irq 11 iomem 0xd6000 iosiz 4096
+pcic3 at pcicmaster1 irq 12 iomem 0xd7000 iosiz 4096
+
+pcmcia* at pcic?
+
+#ed0 at pcmcia? port 0x300 iomem 0xd8000 iosiz 8192 irq 10
+ed0 at pcmcia? port 0x300 size 0x20 irq 10 slot ?
+ep0 at pcmcia? port 0x300 size 0x10 irq 10 slot ?
+#com1 at pcmcia? port 0x2f8 size 8 irq 5 slot ?
+#com2 at pcmcia? port 0x3e8 size 8 irq 5 slot ?
+com3 at pcmcia? port 0x2e8 size 8 irq 3 slot ?
+
+pseudo-device loop 1 # network loopback
+pseudo-device bpfilter 4 # packet filter
+pseudo-device ppp 2 # PPP
+pseudo-device pty 64 # pseudo-terminals
diff --git a/sys/arch/i386/conf/files.i386 b/sys/arch/i386/conf/files.i386
index c434f132f04..2bd8ee7cb59 100644
--- a/sys/arch/i386/conf/files.i386
+++ b/sys/arch/i386/conf/files.i386
@@ -1,4 +1,4 @@
-# $OpenBSD: files.i386,v 1.13 1996/04/28 17:02:01 mickey Exp $
+# $OpenBSD: files.i386,v 1.14 1996/04/29 14:12:16 hvozda Exp $
# $NetBSD: files.i386,v 1.72 1996/04/09 22:59:03 cgd Exp $
#
# new style config file for i386 architecture
@@ -52,7 +52,8 @@ major {rd = 17}
# System bus types
#
-device mainbus: isabus, eisabus, pcibus
+define mainbus { }
+device mainbus: isabus, eisabus, pcibus, mainbus
attach mainbus at root
file arch/i386/i386/mainbus.c mainbus
@@ -69,6 +70,12 @@ file arch/i386/pci/pci_machdep.c pci
file arch/i386/pci/pci_compat.c pci # XXX compatibility
#
+# Pcmcia, before ISA (to define device stuff)
+#
+
+include "../../../dev/pcmcia/files.pcmcia"
+
+#
# ISA and mixed ISA+EISA or ISA+PCI or ISA+PCMCIA drivers
#
@@ -77,10 +84,6 @@ major {mcd = 7}
major {wd = 0}
major {wt = 3}
-#define pcic here until config issues are resolved
-#device pcic at isa: pcmciabus
-#file dev/isa/pcmcia_pcic.c pcic
-
include "../../../dev/isa/files.isa"
file arch/i386/isa/isa_machdep.c isabus
@@ -138,9 +141,9 @@ file arch/i386/isa/spkr.c spkr needs-flag
# National Semiconductor DS8390/WD83C690-based boards
# (WD/SMC 80x3 family, SMC Ultra [8216], 3Com 3C503, NE[12]000, and clones)
# XXX conflicts with other ports; can't be in files.isa
-device ed: ether, ifnet
-attach ed at isa
-file dev/isa/if_ed.c ed
+#device ed: ether, ifnet
+#attach ed at isa
+#file dev/isa/if_ed.c ed
# AMD am7990 (Lance) -based boards
# (BICC Isolan, NE2100, DEPCA)
@@ -183,3 +186,7 @@ file arch/i386/i386/linux_machdep.c compat_linux
# FreeBSD binary compatibility (COMPAT_FREEBSD)
include "../../../compat/freebsd/files.freebsd"
file arch/i386/i386/freebsd_machdep.c compat_freebsd
+
+device apm
+attach apm at mainbus
+file arch/i386/i386/apm.c apm needs-count
diff --git a/sys/arch/i386/i386/apm.c b/sys/arch/i386/i386/apm.c
new file mode 100644
index 00000000000..03483c7a868
--- /dev/null
+++ b/sys/arch/i386/i386/apm.c
@@ -0,0 +1,844 @@
+/* $NetBSD $ */
+
+/*-
+ * Copyright (c) 1995 John T. Kohl. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#include "apm.h"
+#if NAPM > 0
+
+#if NAPM > 1
+#error only one APM device may be configured
+#endif
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/signalvar.h>
+#include <sys/kernel.h>
+#include <sys/map.h>
+#include <sys/proc.h>
+#include <sys/user.h>
+#include <sys/malloc.h>
+#include <sys/device.h>
+#include <sys/fcntl.h>
+#include <sys/ioctl.h>
+
+#include <machine/cpu.h>
+#include <machine/cpufunc.h>
+#include <machine/gdt.h>
+#include <machine/psl.h>
+
+#include <dev/isa/isareg.h>
+#include <i386/isa/isa_machdep.h>
+#include <i386/isa/nvram.h>
+#include <dev/isa/isavar.h>
+
+#include <machine/apmvar.h>
+
+#if defined(DEBUG) || defined(APMDEBUG)
+#define DPRINTF(x) printf x
+#define STATIC /**/
+#else
+#define DPRINTF(x) /**/
+#define STATIC static
+#endif
+
+int apmprobe __P((struct device *, void *, void *));
+void apmattach __P((struct device *, struct device *, void *));
+
+#define APM_NEVENTS 16
+
+struct apm_softc {
+ struct device sc_dev;
+ struct selinfo sc_rsel;
+ struct selinfo sc_xsel;
+ int sc_flags;
+ int event_count;
+ int event_ptr;
+ struct apm_event_info event_list[APM_NEVENTS];
+};
+#define SCFLAG_OREAD 0x0000001
+#define SCFLAG_OWRITE 0x0000002
+#define SCFLAG_OPEN (SCFLAG_OREAD|SCFLAG_OWRITE)
+
+#define APMUNIT(dev) (minor(dev)&0xf0)
+#define APMDEV(dev) (minor(dev)&0x0f)
+#define APMDEV_NORMAL 0
+#define APMDEV_CTL 8
+
+struct cfattach apm_ca = {
+ sizeof(struct apm_softc), apmprobe, apmattach
+};
+
+struct cfdriver apm_cd = {
+ NULL, "apm", DV_DULL
+};
+
+struct apm_connect_info apminfo = { 0 };
+u_char apm_majver;
+u_char apm_minver;
+u_short apminited;
+int apm_dobusy;
+
+STATIC int apm_get_powstat __P((struct apmregs *));
+STATIC void apm_power_print __P((struct apm_softc *, struct apmregs *));
+STATIC void apm_event_handle __P((struct apm_softc *, struct apmregs *));
+STATIC int apm_get_event __P((struct apmregs *));
+STATIC void apm_set_ver __P((struct apm_softc *));
+STATIC void apm_periodic_check __P((void *));
+STATIC void apm_disconnect __P((void *));
+STATIC void apm_perror __P((const char *, struct apmregs *));
+STATIC void apm_powmgt_enable __P((int onoff));
+STATIC void apm_powmgt_engage __P((int onoff, u_int devid));
+STATIC void apm_devpowmgt_enable __P((int onoff, u_int devid));
+STATIC void apm_suspend __P((void));
+STATIC void apm_standby __P((void));
+STATIC int apm_record_event __P((struct apm_softc *sc, u_int event_type));
+
+STATIC const char *
+apm_err_translate(code)
+int code;
+{
+ switch(code) {
+ case APM_ERR_PM_DISABLED:
+ return "power management disabled";
+ case APM_ERR_REALALREADY:
+ return "real mode interface already connected";
+ case APM_ERR_NOTCONN:
+ return "interface not connected";
+ case APM_ERR_16ALREADY:
+ return "16-bit interface already connected";
+ case APM_ERR_16NOTSUPP:
+ return "16-bit interface not supported";
+ case APM_ERR_32ALREADY:
+ return "32-bit interface already connected";
+ case APM_ERR_32NOTSUPP:
+ return "32-bit interface not supported";
+ case APM_ERR_UNRECOG_DEV:
+ return "unrecognized device ID";
+ case APM_ERR_ERANGE:
+ return "parameter out of range";
+ case APM_ERR_NOTENGAGED:
+ return "interface not engaged";
+ case APM_ERR_UNABLE:
+ return "unable to enter requested state";
+ case APM_ERR_NOEVENTS:
+ return "No pending events";
+ case APM_ERR_NOT_PRESENT:
+ return "No APM present";
+ default:
+ return "unknown error code?";
+ }
+}
+
+STATIC void
+apm_perror(str, regs)
+const char *str;
+struct apmregs *regs;
+{
+ printf("APM %s: %s (%d)\n", str,
+ apm_err_translate(APM_ERR_CODE(regs)),
+ APM_ERR_CODE(regs));
+}
+
+STATIC void
+apm_power_print (sc, regs)
+struct apm_softc *sc;
+struct apmregs *regs;
+{
+ if (BATT_LIFE(regs) != APM_BATT_LIFE_UNKNOWN) {
+ printf("%s: battery life expectancy %d%%\n",
+ sc->sc_dev.dv_xname,
+ BATT_LIFE(regs));
+ }
+ printf("%s: A/C state: ", sc->sc_dev.dv_xname);
+ switch (AC_STATE(regs)) {
+ case APM_AC_OFF:
+ printf("off\n");
+ break;
+ case APM_AC_ON:
+ printf("on\n");
+ break;
+ case APM_AC_BACKUP:
+ printf("backup power\n");
+ break;
+ default:
+ case APM_AC_UNKNOWN:
+ printf("unknown\n");
+ break;
+ }
+ printf("%s: battery charge state:", sc->sc_dev.dv_xname);
+ if (apm_minver == 0)
+ switch (BATT_STATE(regs)) {
+ case APM_BATT_HIGH:
+ printf("high\n");
+ break;
+ case APM_BATT_LOW:
+ printf("low\n");
+ break;
+ case APM_BATT_CRITICAL:
+ printf("critical\n");
+ break;
+ case APM_BATT_CHARGING:
+ printf("charging\n");
+ break;
+ case APM_BATT_UNKNOWN:
+ printf("unknown\n");
+ break;
+ default:
+ printf("undecoded state %x\n", BATT_STATE(regs));
+ break;
+ }
+ else if (apm_minver >= 1) {
+ if (BATT_FLAGS(regs) & APM_BATT_FLAG_NOBATTERY)
+ printf(" no battery");
+ else {
+ if (BATT_FLAGS(regs) & APM_BATT_FLAG_HIGH)
+ printf(" high");
+ if (BATT_FLAGS(regs) & APM_BATT_FLAG_LOW)
+ printf(" low");
+ if (BATT_FLAGS(regs) & APM_BATT_FLAG_CRITICAL)
+ printf(" critical");
+ if (BATT_FLAGS(regs) & APM_BATT_FLAG_CHARGING)
+ printf(" charging");
+ }
+ printf("\n");
+ if (BATT_REM_VALID(regs))
+ printf("%s: estimated %d:%02d minutes\n",
+ sc->sc_dev.dv_xname,
+ BATT_REMAINING(regs) / 60,
+ BATT_REMAINING(regs)%60);
+ }
+ return;
+}
+
+int apm_standbys = 0;
+int apm_userstandbys = 0;
+int apm_suspends = 0;
+int apm_battlow = 0;
+
+STATIC void
+apm_get_powstate(dev)
+u_int dev;
+{
+ struct apmregs regs;
+ int rval;
+ regs.bx = dev;
+ rval = apmcall(APM_GET_POWER_STATE, &regs);
+ if (rval == 0) {
+ printf("apm dev %04x state %04x\n", dev, regs.cx);
+ }
+}
+
+STATIC void
+apm_suspend()
+{
+ (void) apm_set_powstate(APM_DEV_ALLDEVS, APM_SYS_SUSPEND);
+}
+
+STATIC void
+apm_standby()
+{
+ (void) apm_set_powstate(APM_DEV_ALLDEVS, APM_SYS_STANDBY);
+}
+
+static int apm_evindex = 0;
+
+STATIC int
+apm_record_event(sc, event_type)
+struct apm_softc *sc;
+u_int event_type;
+{
+ struct apm_event_info *evp;
+
+ if ((sc->sc_flags & SCFLAG_OPEN) == 0)
+ return 1; /* no user waiting */
+ if (sc->event_count == APM_NEVENTS)
+ return 1; /* overflow */
+ evp = &sc->event_list[sc->event_ptr];
+ sc->event_count++;
+ sc->event_ptr++;
+ sc->event_ptr %= APM_NEVENTS;
+ evp->type = event_type;
+ evp->index = ++apm_evindex;
+ selwakeup(&sc->sc_rsel);
+ return (sc->sc_flags & SCFLAG_OWRITE) ? 0 : 1; /* user may handle */
+}
+
+STATIC void
+apm_event_handle(sc, regs)
+struct apm_softc *sc;
+struct apmregs *regs;
+{
+ int error;
+ struct apmregs nregs;
+
+ switch(regs->bx) {
+ case APM_USER_STANDBY_REQ:
+ DPRINTF(("user wants STANDBY--fat chance\n"));
+ (void) apm_set_powstate(APM_DEV_ALLDEVS, APM_LASTREQ_REJECTED);
+ (void) apm_record_event(sc, regs->bx);
+ apm_userstandbys++;
+ break;
+ case APM_STANDBY_REQ:
+ DPRINTF(("standby requested\n"));
+ if (apm_standbys || apm_suspends)
+ DPRINTF(("damn fool BIOS did not wait for answer\n"));
+ if (apm_record_event(sc, regs->bx)) {
+ (void) apm_set_powstate(APM_DEV_ALLDEVS,
+ APM_LASTREQ_INPROG);
+ apm_standbys++;
+ } else
+ (void) apm_set_powstate(APM_DEV_ALLDEVS,
+ APM_LASTREQ_REJECTED);
+ break;
+ case APM_USER_SUSPEND_REQ:
+ DPRINTF(("user wants suspend--fat chance!\n"));
+ (void) apm_set_powstate(APM_DEV_ALLDEVS,
+ APM_LASTREQ_REJECTED);
+ apm_suspends++;
+ apm_record_event(sc, regs->bx);
+ break;
+ case APM_SUSPEND_REQ:
+ DPRINTF(("suspend requested\n"));
+ if (apm_standbys || apm_suspends)
+ DPRINTF(("damn fool BIOS did not wait for answer\n"));
+ if (apm_record_event(sc, regs->bx)) {
+ (void) apm_set_powstate(APM_DEV_ALLDEVS,
+ APM_LASTREQ_INPROG);
+ apm_suspends++;
+ } else
+ (void) apm_set_powstate(APM_DEV_ALLDEVS,
+ APM_LASTREQ_REJECTED);
+ break;
+ case APM_POWER_CHANGE:
+ DPRINTF(("power status change\n"));
+ error = apm_get_powstat(&nregs);
+ if (error == 0)
+ apm_power_print(sc, &nregs);
+ apm_record_event(sc, regs->bx);
+ break;
+ case APM_NORMAL_RESUME:
+ DPRINTF(("system resumed\n"));
+ inittodr(time.tv_sec);
+ apm_record_event(sc, regs->bx);
+ break;
+ case APM_CRIT_RESUME:
+ DPRINTF(("system resumed without us!\n"));
+ inittodr(time.tv_sec);
+ apm_record_event(sc, regs->bx);
+ break;
+ case APM_SYS_STANDBY_RESUME:
+ DPRINTF(("system standby resume\n"));
+ inittodr(time.tv_sec);
+ apm_record_event(sc, regs->bx);
+ break;
+ case APM_UPDATE_TIME:
+ DPRINTF(("update time, please\n"));
+ inittodr(time.tv_sec);
+ apm_record_event(sc, regs->bx);
+ break;
+ case APM_CRIT_SUSPEND_REQ:
+ DPRINTF(("suspend required immediately\n"));
+ apm_record_event(sc, regs->bx);
+ apm_suspend();
+ break;
+ case APM_BATTERY_LOW:
+ DPRINTF(("Battery low!\n"));
+ apm_battlow++;
+ apm_record_event(sc, regs->bx);
+ break;
+ default:
+ printf("APM nonstandard event code %x\n", regs->bx);
+ }
+}
+
+STATIC int
+apm_get_event(regs)
+struct apmregs *regs;
+{
+ return apmcall(APM_GET_PM_EVENT, regs);
+}
+
+STATIC void
+apm_periodic_check(arg)
+void *arg;
+{
+ struct apmregs regs;
+ struct apm_softc *sc = arg;
+ while (apm_get_event(&regs) == 0) {
+ apm_event_handle(sc, &regs);
+ };
+ if (APM_ERR_CODE(&regs) != APM_ERR_NOEVENTS)
+ apm_perror("get event", &regs);
+ if (apm_suspends /*|| (apm_battlow && apm_userstandbys)*/) {
+ /* stupid TI TM5000! */
+ apm_suspend();
+ } else if (apm_standbys || apm_userstandbys) {
+ apm_standby();
+ }
+ apm_suspends = apm_standbys = apm_battlow = apm_userstandbys =0;
+ timeout(apm_periodic_check, sc, hz);
+}
+
+STATIC void
+apm_powmgt_enable(onoff)
+int onoff;
+{
+ struct apmregs regs;
+ regs.bx = apm_minver == 0 ? APM_MGT_ALL : APM_DEV_APM_BIOS;
+ regs.cx = onoff ? APM_MGT_ENABLE : APM_MGT_DISABLE;
+ if (apmcall(APM_PWR_MGT_ENABLE, &regs) != 0)
+ apm_perror("power management enable", &regs);
+}
+
+STATIC void
+apm_powmgt_engage(onoff, dev)
+int onoff;
+u_int dev;
+{
+ struct apmregs regs;
+ if (apm_minver == 0)
+ return;
+ regs.bx = dev;
+ regs.cx = onoff ? APM_MGT_ENGAGE : APM_MGT_DISENGAGE;
+ if (apmcall(APM_PWR_MGT_ENGAGE, &regs) != 0)
+ printf("APM power mgmt engage (device %x): %s (%d)\n",
+ dev, apm_err_translate(APM_ERR_CODE(&regs)),
+ APM_ERR_CODE(&regs));
+}
+
+STATIC void
+apm_devpowmgt_enable(onoff, dev)
+int onoff;
+u_int dev;
+{
+ struct apmregs regs;
+ if (apm_minver == 0)
+ return;
+ regs.bx = dev;
+ /* enable is auto BIOS managment.
+ * disable is program control.
+ */
+ regs.cx = onoff ? APM_MGT_ENABLE : APM_MGT_DISABLE;
+ if (apmcall(APM_DEVICE_MGMT_ENABLE, &regs) != 0)
+ printf("APM device engage (device %x): %s (%d)\n",
+ dev, apm_err_translate(APM_ERR_CODE(&regs)),
+ APM_ERR_CODE(&regs));
+}
+
+int
+apm_set_powstate(dev, state)
+u_int dev, state;
+{
+ struct apmregs regs;
+ if (!apminited || (apm_minver == 0 && state > APM_SYS_OFF))
+ return EINVAL;
+ regs.bx = dev;
+ regs.cx = state;
+ if (apmcall(APM_SET_PWR_STATE, &regs) != 0) {
+ apm_perror("set power state", &regs);
+ return EIO;
+ }
+ return 0;
+}
+
+#ifdef APM_NOIDLE
+int apmidleon = 0;
+#else
+int apmidleon = 1;
+#endif
+
+void
+apm_cpu_busy()
+{
+ struct apmregs regs;
+ if (!apminited)
+ return;
+ if ((apminfo.apm_detail & APM_IDLE_SLOWS) &&
+ apmcall(APM_CPU_BUSY, &regs) != 0)
+ apm_perror("set CPU busy", &regs);
+}
+
+void
+apm_cpu_idle()
+{
+ struct apmregs regs;
+ if (!apminited || !apmidleon)
+ return;
+ if (apmcall(APM_CPU_IDLE, &regs) != 0)
+ apm_perror("set CPU idle", &regs);
+}
+
+void *apm_sh;
+
+#ifdef APM_V10_ONLY
+int apm_v11_enabled = 0;
+#else
+int apm_v11_enabled = 1;
+#endif
+
+STATIC void
+apm_set_ver(self)
+struct apm_softc *self;
+{
+ struct apmregs regs;
+ int error;
+
+ regs.cx = 0x0101; /* APM Version 1.1 */
+ regs.bx = APM_DEV_APM_BIOS;
+
+ if (apm_v11_enabled &&
+ (error = apmcall(APM_DRIVER_VERSION, &regs)) == 0) {
+ apm_majver = APM_CONN_MAJOR(&regs);
+ apm_minver = APM_CONN_MINOR(&regs);
+ } else {
+ apm_majver = 1;
+ apm_minver = 0;
+ }
+ printf(": Power Management spec V%d.%d",
+ apm_majver, apm_minver);
+ apminited = 1;
+ if (apminfo.apm_detail & APM_IDLE_SLOWS) {
+#ifdef DEBUG
+ /* not relevant much */
+ printf(" (slowidle)");
+#endif
+ apm_dobusy = 1;
+ } else
+ apm_dobusy = 0;
+#ifdef DIAGNOSTIC
+ if (apminfo.apm_detail & APM_BIOS_PM_DISABLED)
+ printf(" (BIOS mgmt disabled)");
+ if (apminfo.apm_detail & APM_BIOS_PM_DISENGAGED)
+ printf(" (BIOS managing devices)");
+#endif
+ printf("\n");
+}
+
+STATIC int
+apm_get_powstat(regs)
+struct apmregs *regs;
+{
+ regs->bx = APM_DEV_ALLDEVS;
+ return apmcall(APM_POWER_STATUS, regs);
+}
+
+STATIC void
+apm_disconnect(xxx)
+void *xxx;
+{
+ struct apmregs regs;
+ regs.bx = apm_minver == 1 ? APM_DEV_ALLDEVS : APM_DEFAULTS_ALL;
+ if (apmcall(APM_SYSTEM_DEFAULTS, &regs))
+ apm_perror("system defaults failed", &regs);
+
+ regs.bx = APM_DEV_APM_BIOS;
+ if (apmcall(APM_DISCONNECT, &regs))
+ apm_perror("disconnect failed", &regs);
+ else
+ printf("APM disconnected\n");
+}
+
+int
+apmprobe(parent, match, aux)
+ struct device *parent;
+ void *match, *aux;
+{
+ struct apm_attach_args *aaa = aux;
+
+ if (apminited)
+ return 0;
+ if ((apminfo.apm_detail & APM_32BIT_SUPPORTED) &&
+ strcmp(aaa->aaa_busname, "apm") == 0) {
+ return 1;
+ }
+ return 0;
+}
+
+void
+apmattach(parent, self, aux)
+ struct device *parent, *self;
+ void *aux;
+{
+ struct apm_softc *apmsc = (void *)self;
+ struct apmregs regs;
+ int error;
+ /*
+ * set up GDT descriptors for APM
+ */
+ if (apminfo.apm_detail & APM_32BIT_SUPPORTED) {
+ apminfo.apm_segsel = GSEL(GAPM32CODE_SEL,SEL_KPL);
+ apminfo.apm_code32_seg_base <<= 4;
+ apminfo.apm_code16_seg_base <<= 4;
+ apminfo.apm_data_seg_base <<= 4;
+ /* something is still amiss in the limit-fetch in the boot
+ loader; it returns incorrect (too small) limits.
+ for now, force them to max size. */
+ apminfo.apm_code32_seg_len = 65536;
+ apminfo.apm_data_seg_len = 65536;
+#if 0
+ switch ((APM_MAJOR_VERS(apminfo.apm_detail) << 8) +
+ APM_MINOR_VERS(apminfo.apm_detail)) {
+ case 0x0100:
+ apminfo.apm_code32_seg_len = 65536;
+ apminfo.apm_data_seg_len = 65536;
+ break;
+ default:
+ if (apminfo.apm_data_seg_len == 0)
+ apminfo.apm_data_seg_len = 65536;
+ break;
+ }
+#endif
+ setsegment(&dynamic_gdt[GAPM32CODE_SEL].sd,
+ (void *)ISA_HOLE_VADDR(apminfo.apm_code32_seg_base),
+ apminfo.apm_code32_seg_len-1,
+ SDT_MEMERA, SEL_KPL, 1, 0);
+ setsegment(&dynamic_gdt[GAPM16CODE_SEL].sd,
+ (void *)ISA_HOLE_VADDR(apminfo.apm_code16_seg_base),
+ 65536-1, /* just in case */
+ SDT_MEMERA, SEL_KPL, 0, 0);
+ setsegment(&dynamic_gdt[GAPMDATA_SEL].sd,
+ (void *)ISA_HOLE_VADDR(apminfo.apm_data_seg_base),
+ apminfo.apm_data_seg_len-1,
+ SDT_MEMRWA, SEL_KPL, 1, 0);
+#if defined(DEBUG) || defined(APMDEBUG)
+ printf(": detail %x 32b:%x/%x/%x 16b:%x/%x data %x/%x/%x ep %x (%x:%x)\n%s",
+ apminfo.apm_detail,
+ apminfo.apm_code32_seg_base,
+ ISA_HOLE_VADDR(apminfo.apm_code32_seg_base),
+ apminfo.apm_code32_seg_len,
+ apminfo.apm_code16_seg_base,
+ ISA_HOLE_VADDR(apminfo.apm_code16_seg_base),
+ apminfo.apm_data_seg_base,
+ ISA_HOLE_VADDR(apminfo.apm_data_seg_base),
+ apminfo.apm_data_seg_len,
+ apminfo.apm_entrypt,
+ apminfo.apm_segsel,
+ apminfo.apm_entrypt+ISA_HOLE_VADDR(apminfo.apm_code32_seg_base),
+ apmsc->sc_dev.dv_xname);
+#endif
+ apm_set_ver(apmsc);
+ /*
+ * Engage cooperative power mgt (we get to do it)
+ * on all devices (v1.1).
+ */
+ apm_powmgt_engage(1, APM_DEV_ALLDEVS);
+#if 0
+ /* doesn't seem to work, sigh. */
+ apm_powmgt_engage(1, APM_DEV_DISPLAY(APM_DEV_ALLUNITS));
+ apm_powmgt_engage(1, APM_DEV_DISK(APM_DEV_ALLUNITS));
+ apm_powmgt_engage(1, APM_DEV_PARALLEL(APM_DEV_ALLUNITS));
+ apm_powmgt_engage(1, APM_DEV_NETWORK(APM_DEV_ALLUNITS));
+ apm_powmgt_engage(1, APM_DEV_PCMCIA(APM_DEV_ALLUNITS));
+#endif
+ error = apm_get_powstat(&regs);
+ if (error == 0) {
+ apm_power_print(apmsc, &regs);
+ } else
+ apm_perror("get power status", &regs);
+ apm_cpu_busy();
+ apm_periodic_check(apmsc);
+ } else {
+ dynamic_gdt[GAPM32CODE_SEL] = dynamic_gdt[GNULL_SEL];
+ dynamic_gdt[GAPM16CODE_SEL] = dynamic_gdt[GNULL_SEL];
+ dynamic_gdt[GAPMDATA_SEL] = dynamic_gdt[GNULL_SEL];
+ }
+}
+
+int
+apmopen(dev, flag, mode, p)
+ dev_t dev;
+ int flag, mode;
+ struct proc *p;
+{
+ int unit = APMUNIT(dev);
+ int ctl = APMDEV(dev);
+ struct apm_softc *sc;
+
+ if (unit >= apm_cd.cd_ndevs)
+ return ENXIO;
+ sc = apm_cd.cd_devs[unit];
+ if (!sc)
+ return ENXIO;
+
+ switch (ctl) {
+ case APMDEV_CTL:
+ if (!(flag & FWRITE))
+ return EINVAL;
+ if (sc->sc_flags & SCFLAG_OWRITE)
+ return EBUSY;
+ sc->sc_flags |= SCFLAG_OWRITE;
+ break;
+ case APMDEV_NORMAL:
+ if (!(flag & FREAD) || (flag & FWRITE))
+ return EINVAL;
+ sc->sc_flags |= SCFLAG_OREAD;
+ break;
+ default:
+ return ENXIO;
+ break;
+ }
+ return 0;
+}
+
+int
+apmclose(dev, flag, mode, p)
+ dev_t dev;
+ int flag, mode;
+ struct proc *p;
+{
+ struct apm_softc *sc = apm_cd.cd_devs[APMUNIT(dev)];
+ int ctl = APMDEV(dev);
+
+ DPRINTF(("apmclose: pid %d flag %x mode %x\n", p->p_pid, flag, mode));
+ switch (ctl) {
+ case APMDEV_CTL:
+ sc->sc_flags &= ~SCFLAG_OWRITE;
+ break;
+ case APMDEV_NORMAL:
+ sc->sc_flags &= ~SCFLAG_OREAD;
+ break;
+ }
+ if ((sc->sc_flags & SCFLAG_OPEN) == 0) {
+ sc->event_count = 0;
+ sc->event_ptr = 0;
+ }
+ return 0;
+}
+
+int
+apmioctl(dev, cmd, data, flag, p)
+ dev_t dev;
+ u_long cmd;
+ caddr_t data;
+ int flag;
+ struct proc *p;
+{
+ int error;
+ struct apm_softc *sc = apm_cd.cd_devs[APMUNIT(dev)];
+ struct apm_power_info *powerp;
+ struct apm_event_info *evp;
+ struct apmregs regs;
+ register int i;
+ struct apm_ctl *actl;
+
+ switch (cmd) {
+ /* some ioctl names from linux */
+ case APM_IOC_STANDBY:
+ if ((flag & FWRITE) == 0)
+ return EBADF;
+ apm_userstandbys++;
+ return 0;
+ case APM_IOC_SUSPEND:
+ if ((flag & FWRITE) == 0)
+ return EBADF;
+ apm_suspends++;
+ return 0;
+ case APM_IOC_DEV_CTL:
+ actl = (struct apm_ctl *)data;
+ if ((flag & FWRITE) == 0)
+ return EBADF;
+ apm_get_powstate(actl->dev); /* XXX */
+ return apm_set_powstate(actl->dev, actl->mode);
+ case APM_IOC_NEXTEVENT:
+ if (sc->event_count) {
+ evp = (struct apm_event_info *)data;
+ i = sc->event_ptr + APM_NEVENTS - sc->event_count;
+ i %= APM_NEVENTS;
+ *evp = sc->event_list[i];
+ sc->event_count--;
+ return 0;
+ } else
+ return EAGAIN;
+ case APM_IOC_GETPOWER:
+ powerp = (struct apm_power_info *)data;
+ error = apm_get_powstat(&regs);
+ if (error == 0) {
+ bzero(powerp, sizeof(*powerp));
+ if (BATT_LIFE(&regs) != APM_BATT_LIFE_UNKNOWN)
+ powerp->battery_life = BATT_LIFE(&regs);
+ powerp->ac_state = AC_STATE(&regs);
+ switch (apm_minver) {
+ case 0:
+ powerp->battery_state = BATT_STATE(&regs);
+ break;
+ case 1:
+ default:
+ powerp->battery_state = APM_BATT_UNKNOWN;
+ if (BATT_FLAGS(&regs) & APM_BATT_FLAG_HIGH)
+ powerp->battery_state = APM_BATT_HIGH;
+ else if (BATT_FLAGS(&regs) & APM_BATT_FLAG_LOW)
+ powerp->battery_state = APM_BATT_LOW;
+ else if (BATT_FLAGS(&regs) & APM_BATT_FLAG_CRITICAL)
+ powerp->battery_state = APM_BATT_CRITICAL;
+ else if (BATT_FLAGS(&regs) & APM_BATT_FLAG_CHARGING)
+ powerp->battery_state = APM_BATT_CHARGING;
+ else if (BATT_FLAGS(&regs) & APM_BATT_FLAG_NOBATTERY)
+ powerp->battery_state = APM_BATTERY_ABSENT;
+ if (BATT_REM_VALID(&regs))
+ powerp->minutes_left = BATT_REMAINING(&regs);
+ }
+ } else {
+ apm_perror("ioctl get power status", &regs);
+ error = EIO;
+ }
+ break;
+
+ default:
+ return ENOTTY;
+ }
+ return 0;
+}
+
+int
+apmselect(dev, rw, p)
+ dev_t dev;
+ int rw;
+ struct proc *p;
+{
+ struct apm_softc *sc = apm_cd.cd_devs[APMUNIT(dev)];
+
+ switch (rw) {
+ case FREAD:
+ if (sc->event_count)
+ return 1;
+ selrecord(p, &sc->sc_rsel);
+ break;
+ case FWRITE:
+ case 0:
+ return 0;
+ }
+ return 0;
+}
+
+#endif /* NAPM > 0 */
diff --git a/sys/arch/i386/i386/conf.c b/sys/arch/i386/i386/conf.c
index c56ad7712fd..9b68b21902b 100644
--- a/sys/arch/i386/i386/conf.c
+++ b/sys/arch/i386/i386/conf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: conf.c,v 1.12 1996/04/21 22:16:23 deraadt Exp $ */
+/* $OpenBSD: conf.c,v 1.13 1996/04/29 14:12:41 hvozda Exp $ */
/* $NetBSD: conf.c,v 1.74 1996/03/30 07:30:33 mycroft Exp $ */
/*
@@ -124,6 +124,13 @@ int nblkdev = sizeof(bdevsw) / sizeof(bdevsw[0]);
(dev_type_mmap((*))) enodev }
#define cdev_joy_init cdev_ss_init
+/* open, close, ioctl, select -- XXX should be a generic device */
+#define cdev_ocis_init(c,n) { \
+ dev_init(c,n,open), dev_init(c,n,close), (dev_type_read((*))) enodev, \
+ (dev_type_write((*))) enodev, dev_init(c,n,ioctl), \
+ (dev_type_stop((*))) enodev, 0, dev_init(c,n,select), \
+ (dev_type_mmap((*))) enodev, 0 }
+
cdev_decl(cn);
cdev_decl(ctty);
#define mmread mmrw
@@ -161,6 +168,8 @@ cdev_decl(ch);
dev_decl(filedesc,open);
#include "bpfilter.h"
cdev_decl(bpf);
+#include "pcmcia.h"
+cdev_decl(pcmcia);
#include "spkr.h"
cdev_decl(spkr);
#ifdef LKM
@@ -187,6 +196,8 @@ cdev_decl(svr4_net);
cdev_decl(ccd);
#include "joy.h"
cdev_decl(joy);
+#include "apm.h"
+cdev_decl(apm);
#include "rnd.h"
cdev_decl(rnd);
@@ -222,11 +233,11 @@ struct cdevsw cdevsw[] =
cdev_disk_init(NCCD,ccd), /* 18: concatenated disk driver */
cdev_ss_init(NSS,ss), /* 19: SCSI scanner */
cdev_notdef(), /* 20 */
- cdev_notdef(), /* 21 */
+ cdev_ocis_init(NAPM,apm), /* 21: Advancded Power Management */
cdev_fd_init(1,filedesc), /* 22: file descriptor pseudo-device */
cdev_bpftun_init(NBPFILTER,bpf),/* 23: Berkeley packet filter */
cdev_notdef(), /* 24 */
- cdev_notdef(), /* 25 */
+ cdev_ocis_init(NPCMCIA,pcmcia), /* 25: PCMCIA Bus */
cdev_joy_init(NJOY,joy), /* 26: joystick */
cdev_spkr_init(NSPKR,spkr), /* 27: PC speaker */
cdev_lkm_init(NLKM,lkm), /* 28: loadable module driver */
diff --git a/sys/arch/i386/i386/gdt.c b/sys/arch/i386/i386/gdt.c
index a511ab550b7..37361fba4a2 100644
--- a/sys/arch/i386/i386/gdt.c
+++ b/sys/arch/i386/i386/gdt.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: gdt.c,v 1.7 1996/04/18 19:18:08 niklas Exp $ */
+/* $OpenBSD: gdt.c,v 1.8 1996/04/29 14:12:48 hvozda Exp $ */
/* $NetBSD: gdt.c,v 1.7 1996/02/27 22:45:01 jtc Exp $ */
/*-
@@ -214,6 +214,16 @@ gdt_get_slot()
if (gdt_next != gdt_count)
panic("gdt_get_slot botch 1");
if (gdt_next >= gdt_size) {
+ /*
+ * gdt_size is clamped by maxproc, set in
+ * /sys/conf/param.c and clamped in init386().
+ * It's held there to (MAXGDTSIZ - NGDT) if no
+ * user LDTs, or half that if user LDTs are
+ * allowed. It's important to count that
+ * correctly, because by the time we get here,
+ * it's too late to abort the fork operation
+ * -- we must have a GDT slot available.
+ */
if (gdt_size >= MAXGDTSIZ)
panic("gdt_get_slot botch 2");
if (dynamic_gdt == gdt)
diff --git a/sys/arch/i386/i386/genassym.c b/sys/arch/i386/i386/genassym.c
index d3e01c4094d..8bba187b0d9 100644
--- a/sys/arch/i386/i386/genassym.c
+++ b/sys/arch/i386/i386/genassym.c
@@ -51,6 +51,11 @@
#include <machine/pmap.h>
#include <machine/vmparam.h>
+#include "apm.h"
+#if NAPM > 0
+#include <machine/apmvar.h>
+#endif
+
#ifdef COMPAT_SVR4
#include <compat/svr4/svr4_ucontext.h>
#endif
@@ -150,6 +155,21 @@ main()
off("IH_COUNT", struct intrhand, ih_count);
off("IH_NEXT", struct intrhand, ih_next);
#endif
+#if NAPM > 0
+ off("APM_CODE32", struct apm_connect_info, apm_code32_seg_base);
+ off("APM_CODE16", struct apm_connect_info, apm_code16_seg_base);
+ off("APM_DATA", struct apm_connect_info, apm_data_seg_base);
+ off("APM_CODE32_LEN", struct apm_connect_info, apm_code32_seg_len);
+ off("APM_DATA_LEN", struct apm_connect_info, apm_data_seg_len);
+ off("APM_ENTRY", struct apm_connect_info, apm_entrypt);
+ off("APM_DETAIL", struct apm_connect_info, apm_detail);
+ off("APM_CALL", struct apm_connect_info, apm_entrypt);
+ def("APM_SIZE", sizeof(struct apm_connect_info));
+ off("APMREG_AX", struct apmregs, ax);
+ off("APMREG_BX", struct apmregs, bx);
+ off("APMREG_CX", struct apmregs, cx);
+ off("APMREG_DX", struct apmregs, dx);
+#endif
exit(0);
}
diff --git a/sys/arch/i386/i386/locore.s b/sys/arch/i386/i386/locore.s
index e7af2889ce0..65f33efa92e 100644
--- a/sys/arch/i386/i386/locore.s
+++ b/sys/arch/i386/i386/locore.s
@@ -41,6 +41,7 @@
#include "npx.h"
#include "assym.h"
+#include "apm.h"
#include <sys/errno.h>
#include <sys/syscall.h>
@@ -142,6 +143,16 @@
.globl _cpu,_cpu_vendor,_cold,_esym,_boothowto,_bootdev,_atdevbase
.globl _cyloffset,_proc0paddr,_curpcb,_PTDpaddr,_dynamic_gdt
+#if NAPM > 0
+#include <machine/apmvar.h>
+ .globl _apminfo
+ .globl _apm_current_gdt_pdesc /* current GDT pseudo desc. */
+ .globl _bootstrap_gdt
+_apm_current_gdt_pdesc:
+ .word 0, 0, 0
+_bootstrap_gdt:
+ .space SIZEOF_GDTE * BOOTSTRAP_GDT_NUM
+#endif
_cpu: .long 0 # are we 386, 386sx, or 486
_cpu_vendor: .space 16 # vendor string returned by `cpuid' instruction
_cold: .long 1 # cold till we are not
@@ -178,6 +189,102 @@ start: movw $0x1234,0x472 # warm boot
addl $KERNBASE,%eax
1: movl %eax,RELOC(_esym)
+#if NAPM > 0
+
+ /*
+ * Setup APM BIOS:
+ *
+ * APM BIOS initialization should be done from real mode or V86 mode.
+ *
+ * (by HOSOKAWA, Tatsumi <hosokawa@mt.cs.keio.ac.jp>)
+ */
+
+ /*
+ * Cleanup %fs and %gs:
+ *
+ * Some BIOS bootstrap routine store junk value into %fs
+ * and %gs.
+ */
+
+ xorl %eax, %eax
+ movw %ax, %fs
+ movw %ax, %gs
+
+ /* get GDT base */
+ sgdt RELOC(_apm_current_gdt_pdesc)
+
+ /* copy GDT to _bootstrap_gdt */
+ xorl %ecx, %ecx
+ movw RELOC(_apm_current_gdt_pdesc), %cx
+ movl RELOC(_apm_current_gdt_pdesc)+2, %esi
+ lea RELOC(_bootstrap_gdt), %edi
+ cld
+ rep
+ movsb
+
+ /* setup GDT pseudo descriptor */
+ movw $(SIZEOF_GDTE*BOOTSTRAP_GDT_NUM), %ax
+ movw %ax, RELOC(_apm_current_gdt_pdesc)
+ leal RELOC(_bootstrap_gdt), %eax
+ movl %eax, RELOC(_apm_current_gdt_pdesc)+2
+
+ /* load new GDTR */
+ lgdt RELOC(_apm_current_gdt_pdesc)
+
+ /*
+ * Copy APM initializer under 1MB boundary:
+ *
+ * APM initializer program must switch the CPU to real mode.
+ * But NetBSD kernel runs above 1MB boundary. So we must
+ * copy the initializer code to conventional memory.
+ */
+ movl RELOC(_apm_init_image_size), %ecx /* size */
+ lea RELOC(_apm_init_image), %esi /* source */
+ movl $ APM_OURADDR, %edi /* destination */
+ cld
+ rep
+ movsb
+
+ /* setup GDT for APM initializer */
+ lea RELOC(_bootstrap_gdt), %ecx
+ movl $(APM_OURADDR), %eax /* use %ax for 15..0 */
+ movl %eax, %ebx
+ shrl $16, %ebx /* use %bl for 23..16 */
+ /* use %bh for 31..24 */
+#define APM_SETUP_GDT(index, attrib) \
+ movl $(index), %si ; \
+ lea 0(%ecx,%esi,8), %edx ; \
+ movw $0xffff, (%edx) ; \
+ movw %ax, 2(%edx) ; \
+ movb %bl, 4(%edx) ; \
+ movw $(attrib), 5(%edx) ; \
+ movb %bh, 7(%edx)
+
+ APM_SETUP_GDT(APM_INIT_CS_INDEX , CS32_ATTRIB)
+ APM_SETUP_GDT(APM_INIT_DS_INDEX , DS32_ATTRIB)
+ APM_SETUP_GDT(APM_INIT_CS16_INDEX, CS16_ATTRIB)
+
+ /*
+ * Call the initializer:
+ *
+ * direct intersegment call to conventional memory code
+ */
+ .byte 0x9a /* actually, lcall $APM_INIT_CS_SEL, $0 */
+ .long 0
+ .word APM_INIT_CS_SEL
+
+ movw %ax,RELOC(_apminfo+APM_DETAIL)
+ movw %di,RELOC(_apminfo+APM_DETAIL)+2
+ movl %ebx,RELOC(_apminfo+APM_ENTRY)
+ movw %cx,RELOC(_apminfo+APM_CODE32)
+ shrl $16, %ecx
+ movw %cx,RELOC(_apminfo+APM_CODE16)
+ movw %dx,RELOC(_apminfo+APM_DATA)
+ movw %si,RELOC(_apminfo+APM_CODE32_LEN)
+ shrl $16, %esi
+ movw %si,RELOC(_apminfo+APM_DATA_LEN)
+#endif /* APM */
+
/* First, reset the PSL. */
pushl $PSL_MBO
popfl
@@ -363,7 +470,7 @@ try586: /* Use the `cpuid' instruction. */
#endif
/* Calculate where to start the bootstrap tables. */
- movl %edi,%esi # edi = esym ?: end
+ movl %edi,%esi # edi = esym ? esym : end
addl $PGOFSET,%esi # page align up
andl $~PGOFSET,%esi
@@ -1481,6 +1588,9 @@ ENTRY(remrq)
3: .asciz "remrq"
#endif /* DIAGNOSTIC */
+#if NAPM > 0
+ .globl _apm_cpu_idle,_apm_cpu_busy,_apm_dobusy
+#endif
/*
* When no processes are on the runq, cpu_switch() branches to here to wait for
* something to come ready.
@@ -1491,7 +1601,16 @@ ENTRY(idle)
testl %ecx,%ecx
jnz sw1
sti
+#if NAPM > 0
+ call _apm_cpu_idle
+#endif
hlt
+#if NAPM > 0
+ cmpl $0,_apm_dobusy
+ je 1f
+ call _apm_cpu_busy
+1:
+#endif
jmp _idle
#ifdef DIAGNOSTIC
@@ -2075,3 +2194,78 @@ ENTRY(bzero)
popl %edi
ret
+
+#if NAPM > 0
+/*
+ * int apmcall(int function, struct apmregs *regs):
+ * call the APM protected mode bios function FUNCTION for BIOS selection
+ * WHICHBIOS.
+ * Fills in *regs with registers as returned by APM.
+ * returns nonzero if error returned by APM.
+ */
+apmstatus: .long 0
+ENTRY(apmcall)
+ pushl %ebp
+ movl %esp,%ebp
+ pushl %esi
+ pushl %edi
+ pushl %ebx
+
+#if defined(DEBUG) || defined(DIAGNOSTIC)
+ pushl %ds
+ pushl %es
+ pushl %fs
+ pushl %gs
+ xorl %ax,%ax
+/* movl %ax,%ds # can't toss %ds, we need it for apmstatus*/
+ movl %ax,%es
+ movl %ax,%fs
+ movl %ax,%gs
+#endif
+ movb %cs:8(%ebp),%al
+ movb $0x53,%ah
+ movl %cs:12(%ebp),%ebx
+ movw %cs:APMREG_CX(%ebx),%cx
+ movw %cs:APMREG_DX(%ebx),%dx
+ movw %cs:APMREG_BX(%ebx),%bx
+ pushfl
+ cli
+ pushl %ds
+ lcall %cs:(_apminfo+APM_CALL)
+ popl %ds
+ setc apmstatus
+ popfl
+#if defined(DEBUG) || defined(DIAGNOSTIC)
+ popl %gs
+ popl %fs
+ popl %es
+ popl %ds # see above
+#endif
+ movl 12(%ebp),%esi
+ movw %ax,APMREG_AX(%esi)
+ movw %bx,APMREG_BX(%esi)
+ movw %cx,APMREG_CX(%esi)
+ movw %dx,APMREG_DX(%esi)
+/* todo: do something with %edi? */
+ cmpl $0,apmstatus
+ jne 1f
+ xorl %eax,%eax
+1:
+ popl %ebx
+ popl %edi
+ popl %esi
+ popl %ebp
+ ret
+
+_apm_init_image:
+ .globl _apm_init_image
+
+8:
+#include "lib/apm_init/apm_init.inc"
+9:
+
+_apm_init_image_size:
+ .globl _apm_init_image_size
+ .long 9b - 8b
+
+#endif /* APM */
diff --git a/sys/arch/i386/i386/machdep.c b/sys/arch/i386/i386/machdep.c
index e3bdb4ad24b..27438f0608e 100644
--- a/sys/arch/i386/i386/machdep.c
+++ b/sys/arch/i386/i386/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.13 1996/04/21 22:16:31 deraadt Exp $ */
+/* $OpenBSD: machdep.c,v 1.14 1996/04/29 14:13:15 hvozda Exp $ */
/* $NetBSD: machdep.c,v 1.197 1996/04/12 08:44:40 mycroft Exp $ */
/*-
@@ -93,6 +93,12 @@
#include <i386/isa/isa_machdep.h>
#include <i386/isa/nvram.h>
+#include "apm.h"
+
+#if NAPM > 0
+#include <machine/apmvar.h>
+#endif
+
#ifdef VM86
#include <machine/vm86.h>
#endif
@@ -736,6 +742,16 @@ haltsys:
doshutdownhooks();
if (howto & RB_HALT) {
+#if NAPM > 0 && !defined(APM_NO_POWEROFF)
+ /* turn off, if we can. But try to turn disk off and
+ * wait a bit first--some disk drives are slow to clean up
+ * and users have reported disk corruption.
+ */
+ delay(500000);
+ apm_set_powstate(APM_DEV_DISK(0xff), APM_SYS_OFF);
+ delay(500000);
+ apm_set_powstate(APM_DEV_ALLDEVS, APM_SYS_OFF);
+#endif
printf("\n");
printf("The operating system has halted.\n");
printf("Please press any key to reboot.\n\n");
@@ -1169,6 +1185,16 @@ init386(first_avail)
/* call pmap initialization to make new kernel address space */
pmap_bootstrap((vm_offset_t)atdevbase + IOM_SIZE);
+#ifdef USER_LDT
+#define MAXPROC ((MAXGDTSIZ-NGDT)/2)
+#else
+#define MAXPROC (MAXGDTSIZ-NGDT)
+#endif
+ if (maxproc > MAXPROC) {
+ printf("reducing maxproc to %d to fit into gdt\n", MAXPROC);
+ maxproc = MAXPROC;
+ }
+
#ifdef DDB
ddb_init();
if (boothowto & RB_KDB)
diff --git a/sys/arch/i386/i386/mainbus.c b/sys/arch/i386/i386/mainbus.c
index 5de4b476180..c20a774c307 100644
--- a/sys/arch/i386/i386/mainbus.c
+++ b/sys/arch/i386/i386/mainbus.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mainbus.c,v 1.2 1996/04/21 22:16:32 deraadt Exp $ */
+/* $OpenBSD: mainbus.c,v 1.3 1996/04/29 14:13:25 hvozda Exp $ */
/* $NetBSD: mainbus.c,v 1.8 1996/04/11 22:13:37 cgd Exp $ */
/*
@@ -45,6 +45,11 @@
#include <i386/isa/isa_machdep.h>
#include "pci.h"
+#include "apm.h"
+
+#if NAPM > 0
+#include <machine/apmvar.h>
+#endif
int mainbus_match __P((struct device *, void *, void *));
void mainbus_attach __P((struct device *, struct device *, void *));
@@ -64,6 +69,9 @@ union mainbus_attach_args {
struct pcibus_attach_args mba_pba;
struct eisabus_attach_args mba_eba;
struct isabus_attach_args mba_iba;
+#if NAPM > 0
+ struct apm_attach_args mba_aaa;
+#endif
};
/*
@@ -118,7 +126,12 @@ mainbus_attach(parent, self, aux)
config_found(self, &mba.mba_pba, mainbus_print);
}
#endif
-
+#if NAPM > 0
+ {
+ mba.mba_aaa.aaa_busname = "apm";
+ config_found(self, &mba.mba_aaa, mainbus_print);
+ }
+#endif
}
int
diff --git a/sys/arch/i386/include/apmvar.h b/sys/arch/i386/include/apmvar.h
new file mode 100644
index 00000000000..75dfd2c155d
--- /dev/null
+++ b/sys/arch/i386/include/apmvar.h
@@ -0,0 +1,263 @@
+/* $NetBSD$ */
+/*
+ * Copyright (c) 1995 John T. Kohl
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef __I386_APM_H__
+#define __I386_APM_H__
+
+/* Advanced Power Management (v1.0 and v1.1 specification)
+ * functions/defines/etc.
+ */
+#define APM_BIOS_FNCODE (0x53)
+#define APM_SYSTEM_BIOS (0x15)
+#define APM_BIOS_FN(x) ((APM_BIOS_FNCODE<<8)|(x))
+/*
+ * APM info word from boot loader
+ */
+#define APM_MAJOR_VERS(info) (((info)&0xff00)>>8)
+#define APM_MINOR_VERS(info) ((info)&0xff)
+#define APM_16BIT_SUPPORTED 0x00010000
+#define APM_32BIT_SUPPORTED 0x00020000
+#define APM_IDLE_SLOWS 0x00040000
+#define APM_BIOS_PM_DISABLED 0x00080000
+#define APM_BIOS_PM_DISENGAGED 0x00100000
+
+#define APM_ERR_CODE(regs) (((regs)->ax & 0xff00) >> 8)
+#define APM_ERR_PM_DISABLED 0x01
+#define APM_ERR_REALALREADY 0x02
+#define APM_ERR_NOTCONN 0x03
+#define APM_ERR_16ALREADY 0x05
+#define APM_ERR_16NOTSUPP 0x06
+#define APM_ERR_32ALREADY 0x07
+#define APM_ERR_32NOTSUPP 0x08
+#define APM_ERR_UNRECOG_DEV 0x09
+#define APM_ERR_ERANGE 0x0A
+#define APM_ERR_NOTENGAGED 0x0B
+#define APM_ERR_UNABLE 0x60
+#define APM_ERR_NOEVENTS 0x80
+#define APM_ERR_NOT_PRESENT 0x86
+
+#define APM_DEV_APM_BIOS 0x0000
+#define APM_DEV_ALLDEVS 0x0001
+/* device classes are high byte; device IDs go in low byte */
+#define APM_DEV_DISPLAY(x) (0x0100|((x)&0xff))
+#define APM_DEV_DISK(x) (0x0200|((x)&0xff))
+#define APM_DEV_PARALLEL(x) (0x0300|((x)&0xff))
+#define APM_DEV_SERIAL(x) (0x0400|((x)&0xff))
+#define APM_DEV_NETWORK(x) (0x0500|((x)&0xff))
+#define APM_DEV_PCMCIA(x) (0x0600|((x)&0xff))
+#define APM_DEV_ALLUNITS 0xff
+
+#define APM_INSTALLATION_CHECK 0x00 /* int15 only */
+#define APM_REALMODE_CONNECT 0x01 /* int15 only */
+#define APM_16BIT_CONNECT 0x02 /* int15 only */
+#define APM_32BIT_CONNECT 0x03 /* int15 only */
+#define APM_DISCONNECT 0x04 /* %bx = APM_DEV_APM_BIOS */
+#define APM_CPU_IDLE 0x05
+#define APM_CPU_BUSY 0x06
+#define APM_SET_PWR_STATE 0x07
+#define APM_SYS_READY 0x0000 /* %cx */
+#define APM_SYS_STANDBY 0x0001
+#define APM_SYS_SUSPEND 0x0002
+#define APM_SYS_OFF 0x0003
+#define APM_LASTREQ_INPROG 0x0004
+#define APM_LASTREQ_REJECTED 0x0005
+
+/* system standby is device ID (%bx) 0x0001, APM_SYS_STANDBY */
+/* system suspend is device ID (%bx) 0x0001, APM_SYS_SUSPEND */
+
+#define APM_PWR_MGT_ENABLE 0x08
+#define APM_MGT_ALL 0xffff /* %bx */
+#define APM_MGT_DISABLE 0x0 /* %cx */
+#define APM_MGT_ENABLE 0x1
+
+#define APM_SYSTEM_DEFAULTS 0x09
+#define APM_DEFAULTS_ALL 0xffff /* %bx */
+
+#define APM_POWER_STATUS 0x0a
+#define APM_AC_OFF 0x00
+#define APM_AC_ON 0x01
+#define APM_AC_BACKUP 0x02
+#define APM_AC_UNKNOWN 0xff
+#define APM_BATT_HIGH 0x00
+#define APM_BATT_LOW 0x01
+#define APM_BATT_CRITICAL 0x02
+#define APM_BATT_CHARGING 0x03
+#define APM_BATT_UNKNOWN 0xff
+#define APM_BATT_FLAG_HIGH 0x01
+#define APM_BATT_FLAG_LOW 0x02
+#define APM_BATT_FLAG_CRITICAL 0x04
+#define APM_BATT_FLAG_CHARGING 0x08
+#define APM_BATT_FLAG_NOBATTERY 0x80
+#define APM_BATT_LIFE_UNKNOWN 0xff
+#define BATT_STATE(regp) ((regp)->bx & 0xff)
+#define BATT_FLAGS(regp) (((regp)->cx & 0xff00) >> 8)
+#define AC_STATE(regp) (((regp)->bx & 0xff00) >> 8)
+#define BATT_LIFE(regp) ((regp)->cx & 0xff) /* in % */
+#define BATT_REMAINING(regp) (((regp)->dx & 0x8000) ? \
+ ((regp)->dx & 0x7fff)*60 : \
+ ((regp)->dx & 0x7fff))
+#define BATT_REM_VALID(regp) (((regp)->dx & 0xffff) != 0xffff)
+#define APM_GET_PM_EVENT 0x0b
+#define APM_STANDBY_REQ 0x0001 /* %bx on return */
+#define APM_SUSPEND_REQ 0x0002
+#define APM_NORMAL_RESUME 0x0003
+#define APM_CRIT_RESUME 0x0004 /* suspend/resume happened
+ without us */
+#define APM_BATTERY_LOW 0x0005
+#define APM_POWER_CHANGE 0x0006
+#define APM_UPDATE_TIME 0x0007
+#define APM_CRIT_SUSPEND_REQ 0x0008
+#define APM_USER_STANDBY_REQ 0x0009
+#define APM_USER_SUSPEND_REQ 0x000A
+#define APM_SYS_STANDBY_RESUME 0x000B
+
+#define APM_GET_POWER_STATE 0x0c
+#define APM_DEVICE_MGMT_ENABLE 0x0d
+
+#define APM_DRIVER_VERSION 0x0e
+/* %bx should be DEV value (APM_DEV_APM_BIOS)
+ %ch = driver major vno
+ %cl = driver minor vno
+ return: %ah = conn major; %al = conn minor
+ */
+#define APM_CONN_MINOR(regp) ((regp)->ax & 0xff)
+#define APM_CONN_MAJOR(regp) (((regp)->ax & 0xff00) >> 8)
+
+#define APM_PWR_MGT_ENGAGE 0x0F
+#define APM_MGT_DISENGAGE 0x0 /* %cx */
+#define APM_MGT_ENGAGE 0x1
+
+#define APM_OEM 0x80
+
+#ifdef _LOCORE
+/*
+ * LP (Laptop Package)
+ *
+ * Copyright (C) 1994 by HOSOKAWA Tatsumi <hosokawa@mt.cs.keio.ac.jp>
+ *
+ * This software may be used, modified, copied, and distributed, in
+ * both source and binary form provided that the above copyright and
+ * these terms are retained. Under no circumstances is the author
+ * responsible for the proper functioning of this software, nor does
+ * the author assume any responsibility for damages incurred with its
+ * use.
+ *
+ * Sep., 1994 Implemented on FreeBSD 1.1.5.1R (Toshiba AVS001WD)
+ */
+
+/* Error code of APM initializer */
+#define APMINI_CANTFIND 0xffffffff
+#define APMINI_NOT32BIT 0xfffffffe
+#define APMINI_CONNECTERR 0xfffffffd
+
+#define SIZEOF_GDTE 8
+#define BOOTSTRAP_GDT_NUM 9 /* see i386/boot/table.c */
+
+#define APM_INIT_CS_INDEX (BOOTSTRAP_GDT_NUM - 3)
+#define APM_INIT_DS_INDEX (BOOTSTRAP_GDT_NUM - 2)
+#define APM_INIT_CS16_INDEX (BOOTSTRAP_GDT_NUM - 1)
+#define APM_INIT_CS_SEL (APM_INIT_CS_INDEX << 3)
+#define APM_INIT_DS_SEL (APM_INIT_DS_INDEX << 3)
+#define APM_INIT_CS16_SEL (APM_INIT_CS16_INDEX << 3)
+
+#define CS32_ATTRIB 0xCF9e
+#define CS16_ATTRIB 0x0F9e
+#define DS32_ATTRIB 0xCF92
+
+#define BOOTSTRAP_DS_SEL 0x10
+/* APM initializer physical address */
+#define APM_OURADDR 0x00080000
+#define APM_RELOC(x) ((x) - _apm_init_image)
+
+#else /* !_LOCORE */
+
+/* filled in by apmcall */
+struct apmregs {
+ u_short ax;
+ u_short bx;
+ u_short cx;
+ u_short dx;
+};
+
+struct apm_connect_info {
+ u_int apm_code32_seg_base; /* real-mode style segment selector */
+ u_int apm_code16_seg_base;
+ u_int apm_data_seg_base;
+ u_int apm_entrypt;
+ u_short apm_segsel; /* segment selector for APM */
+ u_short _pad1;
+ u_int apm_code32_seg_len;
+ u_int apm_data_seg_len;
+ u_int apm_detail;
+};
+
+struct apm_event_info {
+ u_int type;
+ u_int index;
+ u_int spare[8];
+};
+
+#define APM_BATTERY_ABSENT 4
+
+struct apm_power_info {
+ u_char battery_state;
+ u_char ac_state;
+ u_char battery_life;
+ u_char spare1;
+ u_int minutes_left; /* estimate */
+ u_int spare2[6];
+};
+
+struct apm_ctl {
+ u_int dev;
+ u_int mode;
+};
+
+#define APM_IOC_REJECT _IOW('A', 0, struct apm_event_info) /* reject request # */
+#define APM_IOC_STANDBY _IO('A', 1) /* put system into standby */
+#define APM_IOC_SUSPEND _IO('A', 2) /* put system into suspend */
+#define APM_IOC_GETPOWER _IOR('A', 3, struct apm_power_info) /* fetch battery state */
+#define APM_IOC_NEXTEVENT _IOR('A', 4, struct apm_event_info) /* fetch event */
+#define APM_IOC_DEV_CTL _IOW('A', 5, struct apm_ctl) /* put device into mode */
+
+struct apm_attach_args {
+ char *aaa_busname;
+};
+
+#ifdef _KERNEL
+extern struct apm_connect_info apminfo; /* in locore */
+extern int apmpresent;
+extern int apmcall __P((int function, struct apmregs *regs));
+extern void apm_cpu_busy __P((void));
+extern void apm_cpu_idle __P((void));
+extern void apminit __P((void));
+int apm_set_powstate __P((u_int devid, u_int powstate));
+#endif /* _KERNEL */
+#endif /* _LOCORE */
+#endif /* __i386_apm_h__ */
diff --git a/sys/arch/i386/include/gdt.h b/sys/arch/i386/include/gdt.h
index ebb8d5b0d57..7b7a6ea5ac5 100644
--- a/sys/arch/i386/include/gdt.h
+++ b/sys/arch/i386/include/gdt.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: gdt.h,v 1.2 1996/04/18 19:21:37 niklas Exp $ */
+/* $OpenBSD: gdt.h,v 1.3 1996/04/29 14:13:48 hvozda Exp $ */
/* $NetBSD: gdt.h,v 1.3 1996/02/27 22:32:11 jtc Exp $ */
/*-
@@ -37,6 +37,9 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
+#define MAXGDTSIZ 8192 /* max # entries in an i386 GDT */
+extern union descriptor *dynamic_gdt;
+
void tss_alloc __P((struct pcb *));
void tss_free __P((struct pcb *));
void ldt_alloc __P((struct pcb *, union descriptor *, size_t));
diff --git a/sys/arch/i386/include/segments.h b/sys/arch/i386/include/segments.h
index a1a332e23f3..4558ccce6aa 100644
--- a/sys/arch/i386/include/segments.h
+++ b/sys/arch/i386/include/segments.h
@@ -217,7 +217,10 @@ void setsegment __P((struct segment_descriptor *, void *, size_t, int, int,
#define GLDT_SEL 3 /* Default LDT descriptor */
#define GUCODE_SEL 4 /* User code descriptor */
#define GUDATA_SEL 5 /* User data descriptor */
-#define NGDT 6
+#define GAPM32CODE_SEL 6
+#define GAPM16CODE_SEL 7
+#define GAPMDATA_SEL 8
+#define NGDT 9
/*
* Entries in the Local Descriptor Table (LDT)