diff options
author | 2019-01-23 09:57:36 +0000 | |
---|---|---|
committer | 2019-01-23 09:57:36 +0000 | |
commit | edbb6e97666aac631ed541eecedeffe58eab577f (patch) | |
tree | 758b298183416264de91d8eb1b476bdb1a68e4d8 | |
parent | Remove 3 as a guess for possible generator during moduli generation. (diff) | |
download | wireguard-openbsd-edbb6e97666aac631ed541eecedeffe58eab577f.tar.xz wireguard-openbsd-edbb6e97666aac631ed541eecedeffe58eab577f.zip |
Add the apm(4) subsystem to arm64.
NB: acpi(4) is not hooked up to this yet.
previous version OK deraadt@ patrick@
OK jsg@
-rw-r--r-- | sys/arch/arm64/arm64/acpiapm.c | 58 | ||||
-rw-r--r-- | sys/arch/arm64/arm64/conf.c | 5 | ||||
-rw-r--r-- | sys/arch/arm64/conf/files.arm64 | 7 | ||||
-rw-r--r-- | sys/arch/arm64/dev/apm.c | 344 | ||||
-rw-r--r-- | sys/arch/arm64/dev/mainbus.c | 17 | ||||
-rw-r--r-- | sys/arch/arm64/include/acpiapm.h | 23 | ||||
-rw-r--r-- | sys/arch/arm64/include/apmvar.h | 8 | ||||
-rw-r--r-- | sys/arch/arm64/include/conf.h | 12 |
8 files changed, 468 insertions, 6 deletions
diff --git a/sys/arch/arm64/arm64/acpiapm.c b/sys/arch/arm64/arm64/acpiapm.c new file mode 100644 index 00000000000..09cc1206a5a --- /dev/null +++ b/sys/arch/arm64/arm64/acpiapm.c @@ -0,0 +1,58 @@ +/* $OpenBSD: acpiapm.c,v 1.1 2019/01/23 09:57:36 phessler Exp $ */ +/* + * Copyright (c) 2007 Ted Unangst <tedu@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/param.h> +#include <machine/conf.h> +#include <sys/event.h> + + +int (*acpiapm_open)(dev_t, int, int, struct proc *); +int (*acpiapm_close)(dev_t, int, int, struct proc *); +int (*acpiapm_ioctl)(dev_t, u_long, caddr_t, int, struct proc *); +int (*acpiapm_kqfilter)(dev_t, struct knote *); + +int +acpiapmopen(dev_t dev, int flag, int mode, struct proc *p) +{ + if (!acpiapm_open) + return ENODEV; + return acpiapm_open(dev, flag, mode, p); +} + +int +acpiapmclose(dev_t dev, int flag, int mode, struct proc *p) +{ + if (!acpiapm_close) + return ENODEV; + return acpiapm_close(dev, flag, mode, p); +} + +int +acpiapmioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) +{ + if (!acpiapm_ioctl) + return ENODEV; + return acpiapm_ioctl(dev, cmd, data, flag, p); +} + +int +acpiapmkqfilter(dev_t dev, struct knote *kn) +{ + if (!acpiapm_kqfilter) + return ENODEV; + return acpiapm_kqfilter(dev, kn); +} diff --git a/sys/arch/arm64/arm64/conf.c b/sys/arch/arm64/arm64/conf.c index 5f0991fad79..3b1ea3fec06 100644 --- a/sys/arch/arm64/arm64/conf.c +++ b/sys/arch/arm64/arm64/conf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: conf.c,v 1.5 2017/01/23 12:34:06 kettenis Exp $ */ +/* $OpenBSD: conf.c,v 1.6 2019/01/23 09:57:36 phessler Exp $ */ /* * Copyright (c) 1994, 1995 Charles M. Hannum. All rights reserved. @@ -46,6 +46,7 @@ bdev_decl(wd); #include "uk.h" #include "vnd.h" #include "rd.h" +#include "apm.h" struct bdevsw bdevsw[] = { @@ -239,7 +240,7 @@ struct cdevsw cdevsw[] = cdev_notdef(), /* 80: gpr? XXX */ cdev_ptm_init(NPTY,ptm), /* 81: pseudo-tty ptm device */ cdev_hotplug_init(NHOTPLUG,hotplug), /* 82: devices hot plugging */ - cdev_notdef(), /* 83 */ + cdev_acpiapm_init(NAPM,acpiapm), /* 83: apm */ cdev_notdef(), /* 84 */ cdev_notdef(), /* 85 */ cdev_notdef(), /* 86 */ diff --git a/sys/arch/arm64/conf/files.arm64 b/sys/arch/arm64/conf/files.arm64 index f67c9d9aec5..72b13758721 100644 --- a/sys/arch/arm64/conf/files.arm64 +++ b/sys/arch/arm64/conf/files.arm64 @@ -1,4 +1,4 @@ -# $OpenBSD: files.arm64,v 1.26 2018/07/30 10:56:00 kettenis Exp $ +# $OpenBSD: files.arm64,v 1.27 2019/01/23 09:57:36 phessler Exp $ maxpartitions 16 maxusers 2 8 64 @@ -148,3 +148,8 @@ file arch/arm64/arm64/acpi_machdep.c acpi_fdt device acpipci: pcibus attach acpipci at acpi file arch/arm64/dev/acpipci.c acpipci + +device apm +attach apm at mainbus +file arch/arm64/dev/apm.c apm needs-flag +file arch/arm64/arm64/acpiapm.c apm diff --git a/sys/arch/arm64/dev/apm.c b/sys/arch/arm64/dev/apm.c new file mode 100644 index 00000000000..48fee1144af --- /dev/null +++ b/sys/arch/arm64/dev/apm.c @@ -0,0 +1,344 @@ +/* $OpenBSD: apm.c,v 1.1 2019/01/23 09:57:36 phessler Exp $ */ + +/*- + * Copyright (c) 2001 Alexander Guy. All rights reserved. + * Copyright (c) 1998-2001 Michael Shalayeff. All rights reserved. + * 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. Neither the names of the authors nor the names of contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS 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 AUTHORS 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 MIND, 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" +#include "wsdisplay.h" + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/kernel.h> +#include <sys/proc.h> +#include <sys/device.h> +#include <sys/fcntl.h> +#include <sys/ioctl.h> +#include <sys/buf.h> +#include <sys/event.h> +#include <sys/reboot.h> +#include <sys/hibernate.h> +#include <dev/rndvar.h> + +#include <machine/conf.h> +#include <machine/cpu.h> +#include <machine/acpiapm.h> +#include <machine/apmvar.h> + +#include <dev/wscons/wsdisplayvar.h> + +#if defined(APMDEBUG) +#define DPRINTF(x) printf x +#else +#define DPRINTF(x) /**/ +#endif + +struct apm_softc { + struct device sc_dev; + struct klist sc_note; + int sc_flags; +}; + +int apmmatch(struct device *, void *, void *); +void apmattach(struct device *, struct device *, void *); + +struct cfattach apm_ca = { + sizeof(struct apm_softc), apmmatch, apmattach +}; + +struct cfdriver apm_cd = { + NULL, "apm", DV_DULL +}; + +#define APMUNIT(dev) (minor(dev)&0xf0) +#define APMDEV(dev) (minor(dev)&0x0f) +#define APMDEV_NORMAL 0 +#define APMDEV_CTL 8 + +void filt_apmrdetach(struct knote *kn); +int filt_apmread(struct knote *kn, long hint); +int apmkqfilter(dev_t dev, struct knote *kn); +int apm_getdefaultinfo(struct apm_power_info *); + +struct filterops apmread_filtops = + { 1, NULL, filt_apmrdetach, filt_apmread}; + +int (*get_apminfo)(struct apm_power_info *) = apm_getdefaultinfo; + +/* + * Flags to control kernel display + * SCFLAG_NOPRINT: do not output APM power messages due to + * a power change event. + * + * SCFLAG_PCTPRINT: do not output APM power messages due to + * to a power change event unless the battery + * percentage changes. + */ + +#define SCFLAG_NOPRINT 0x0008000 +#define SCFLAG_PCTPRINT 0x0004000 +#define SCFLAG_PRINT (SCFLAG_NOPRINT|SCFLAG_PCTPRINT) + +#define SCFLAG_OREAD (1 << 0) +#define SCFLAG_OWRITE (1 << 1) +#define SCFLAG_OPEN (SCFLAG_OREAD|SCFLAG_OWRITE) + + +int +apmmatch(struct device *parent, void *match, void *aux) +{ + return (1); +} + +void +apmattach(struct device *parent, struct device *self, void *aux) +{ + acpiapm_open = apmopen; + acpiapm_close = apmclose; + acpiapm_ioctl = apmioctl; + acpiapm_kqfilter = apmkqfilter; + + printf("\n"); +} + +int +apmopen(dev_t dev, int flag, int mode, struct proc *p) +{ + struct apm_softc *sc; + int error = 0; + + /* apm0 only */ + if (!apm_cd.cd_ndevs || APMUNIT(dev) != 0 || + !(sc = apm_cd.cd_devs[APMUNIT(dev)])) + return ENXIO; + + DPRINTF(("apmopen: dev %d pid %d flag %x mode %x\n", + APMDEV(dev), p->p_p->ps_pid, flag, mode)); + + switch (APMDEV(dev)) { + case APMDEV_CTL: + if (!(flag & FWRITE)) { + error = EINVAL; + break; + } + if (sc->sc_flags & SCFLAG_OWRITE) { + error = EBUSY; + break; + } + sc->sc_flags |= SCFLAG_OWRITE; + break; + case APMDEV_NORMAL: + if (!(flag & FREAD) || (flag & FWRITE)) { + error = EINVAL; + break; + } + sc->sc_flags |= SCFLAG_OREAD; + break; + default: + error = ENXIO; + break; + } + return error; +} + +int +apmclose(dev_t dev, int flag, int mode, struct proc *p) +{ + struct apm_softc *sc; + + /* apm0 only */ + if (!apm_cd.cd_ndevs || APMUNIT(dev) != 0 || + !(sc = apm_cd.cd_devs[APMUNIT(dev)])) + return ENXIO; + + DPRINTF(("apmclose: pid %d flag %x mode %x\n", + p->p_p->ps_pid, flag, mode)); + + switch (APMDEV(dev)) { + case APMDEV_CTL: + sc->sc_flags &= ~SCFLAG_OWRITE; + break; + case APMDEV_NORMAL: + sc->sc_flags &= ~SCFLAG_OREAD; + break; + } + return 0; +} + +int +apmioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) +{ + struct apm_softc *sc; + struct apm_power_info *power; + int error = 0; + + /* apm0 only */ + if (!apm_cd.cd_ndevs || APMUNIT(dev) != 0 || + !(sc = apm_cd.cd_devs[APMUNIT(dev)])) + return ENXIO; + + switch (cmd) { + /* some ioctl names from linux */ + case APM_IOC_STANDBY: + case APM_IOC_STANDBY_REQ: + case APM_IOC_SUSPEND: + case APM_IOC_SUSPEND_REQ: + if ((flag & FWRITE) == 0) + error = EBADF; + error = EOPNOTSUPP; + break; +#ifdef HIBERNATE + case APM_IOC_HIBERNATE: + if ((flag & FWRITE) == 0) + error = EBADF; + error = EOPNOTSUPP; + break; +#endif + case APM_IOC_PRN_CTL: + if ((flag & FWRITE) == 0) + error = EBADF; + else { + int flag = *(int *)data; + DPRINTF(( "APM_IOC_PRN_CTL: %d\n", flag )); + switch (flag) { + case APM_PRINT_ON: /* enable printing */ + sc->sc_flags &= ~SCFLAG_PRINT; + break; + case APM_PRINT_OFF: /* disable printing */ + sc->sc_flags &= ~SCFLAG_PRINT; + sc->sc_flags |= SCFLAG_NOPRINT; + break; + case APM_PRINT_PCT: /* disable some printing */ + sc->sc_flags &= ~SCFLAG_PRINT; + sc->sc_flags |= SCFLAG_PCTPRINT; + break; + default: + error = EINVAL; + break; + } + } + break; + case APM_IOC_DEV_CTL: + if ((flag & FWRITE) == 0) + error = EBADF; + else + error = EOPNOTSUPP; /* XXX */ + break; + case APM_IOC_GETPOWER: + power = (struct apm_power_info *)data; + error = (*get_apminfo)(power); + break; + default: + error = ENOTTY; + } + + return error; +} + +void +filt_apmrdetach(struct knote *kn) +{ + struct apm_softc *sc = (struct apm_softc *)kn->kn_hook; + + SLIST_REMOVE(&sc->sc_note, kn, knote, kn_selnext); +} + +int +filt_apmread(struct knote *kn, long hint) +{ + /* XXX weird kqueue_scan() semantics */ + if (hint && !kn->kn_data) + kn->kn_data = (int)hint; + + return (1); +} + +int +apmkqfilter(dev_t dev, struct knote *kn) +{ + struct apm_softc *sc; + + /* apm0 only */ + if (!apm_cd.cd_ndevs || APMUNIT(dev) != 0 || + !(sc = apm_cd.cd_devs[APMUNIT(dev)])) + return ENXIO; + + switch (kn->kn_filter) { + case EVFILT_READ: + kn->kn_fop = &apmread_filtops; + break; + default: + return (EINVAL); + } + + kn->kn_hook = (caddr_t)sc; + SLIST_INSERT_HEAD(&sc->sc_note, kn, kn_selnext); + + return (0); +} + +int +apm_getdefaultinfo(struct apm_power_info *info) +{ + info->battery_state = APM_BATT_UNKNOWN; + info->ac_state = APM_AC_UNKNOWN; + info->battery_life = 0; + info->minutes_left = -1; + return (0); +} + +void +apm_setinfohook(int (*hook)(struct apm_power_info *)) +{ + get_apminfo = hook; +} + +int +apm_record_event(u_int event, const char *src, const char *msg) +{ + static int apm_evindex; + struct apm_softc *sc; + + /* apm0 only */ + if (apm_cd.cd_ndevs == 0 || (sc = apm_cd.cd_devs[0]) == NULL) + return ENXIO; + + if ((sc->sc_flags & SCFLAG_NOPRINT) == 0) + printf("%s: %s %s\n", sc->sc_dev.dv_xname, src, msg); + + /* skip if no user waiting */ + if ((sc->sc_flags & SCFLAG_OPEN) == 0) + return (1); + + apm_evindex++; + KNOTE(&sc->sc_note, APM_EVENT_COMPOSE(event, apm_evindex)); + + return (0); +} diff --git a/sys/arch/arm64/dev/mainbus.c b/sys/arch/arm64/dev/mainbus.c index 049ecc3fff6..9937a6b8441 100644 --- a/sys/arch/arm64/dev/mainbus.c +++ b/sys/arch/arm64/dev/mainbus.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mainbus.c,v 1.10 2018/08/08 20:57:53 kettenis Exp $ */ +/* $OpenBSD: mainbus.c,v 1.11 2019/01/23 09:57:36 phessler Exp $ */ /* * Copyright (c) 2016 Patrick Wildt <patrick@blueri.se> * Copyright (c) 2017 Mark Kettenis <kettenis@openbsd.org> @@ -38,6 +38,7 @@ void mainbus_attach_cpus(struct device *, cfmatch_t); int mainbus_match_primary(struct device *, void *, void *); int mainbus_match_secondary(struct device *, void *, void *); void mainbus_attach_efi(struct device *); +void mainbus_attach_apm(struct device *); void mainbus_attach_framebuffer(struct device *); struct mainbus_softc { @@ -130,6 +131,8 @@ mainbus_attach(struct device *parent, struct device *self, void *aux) sc->sc_rangeslen); } + mainbus_attach_apm(self); + /* Scan the whole tree. */ sc->sc_early = 1; for (node = OF_child(sc->sc_node); node != 0; node = OF_peer(node)) @@ -310,6 +313,18 @@ mainbus_attach_efi(struct device *self) } void +mainbus_attach_apm(struct device *self) +{ + struct fdt_attach_args fa; + + memset(&fa, 0, sizeof(fa)); + fa.fa_name = "apm"; + + config_found(self, &fa, NULL); + +} + +void mainbus_attach_framebuffer(struct device *self) { int node = OF_finddevice("/chosen"); diff --git a/sys/arch/arm64/include/acpiapm.h b/sys/arch/arm64/include/acpiapm.h new file mode 100644 index 00000000000..f9cefdcdfe9 --- /dev/null +++ b/sys/arch/arm64/include/acpiapm.h @@ -0,0 +1,23 @@ +/* $OpenBSD: acpiapm.h,v 1.1 2019/01/23 09:57:36 phessler Exp $ */ +/* + * Copyright (c) 2007 Ted Unangst <tedu@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + +extern int (*acpiapm_open)(dev_t, int, int, struct proc *); +extern int (*acpiapm_close)(dev_t, int, int, struct proc *); +extern int (*acpiapm_ioctl)(dev_t, u_long, caddr_t, int, struct proc *); +extern int (*acpiapm_kqfilter)(dev_t, struct knote *); + diff --git a/sys/arch/arm64/include/apmvar.h b/sys/arch/arm64/include/apmvar.h index 4668424a84f..1544733d59f 100644 --- a/sys/arch/arm64/include/apmvar.h +++ b/sys/arch/arm64/include/apmvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: apmvar.h,v 1.1 2016/12/17 23:38:33 patrick Exp $ */ +/* $OpenBSD: apmvar.h,v 1.2 2019/01/23 09:57:36 phessler Exp $ */ /* * Copyright (c) 2001 Alexander Guy @@ -67,6 +67,7 @@ #define APM_USER_SUSPEND_REQ 0x000A #define APM_SYS_STANDBY_RESUME 0x000B #define APM_CAPABILITY_CHANGE 0x000C /* apm v1.2 */ +#define APM_USER_HIBERNATE_REQ 0x000D #define APM_EVENT_MASK 0xffff #define APM_EVENT_COMPOSE(t,i) ((((i) & 0x7fff) << 16)|((t) & APM_EVENT_MASK)) @@ -118,4 +119,9 @@ struct apm_ctl { #define APM_IOC_SUSPEND_REQ _IO('A', 8) /* request suspend */ #define APM_IOC_HIBERNATE _IO('A', 9) /* put system into hibernate */ +#ifdef _KERNEL +void apm_setinfohook(int (*)(struct apm_power_info *)); +int apm_record_event(u_int, const char *, const char *); +#endif + #endif /* _MACHINE_APMVAR_H_ */ diff --git a/sys/arch/arm64/include/conf.h b/sys/arch/arm64/include/conf.h index 38af7b62f8b..8fc109a63c1 100644 --- a/sys/arch/arm64/include/conf.h +++ b/sys/arch/arm64/include/conf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: conf.h,v 1.2 2017/01/23 12:34:06 kettenis Exp $ */ +/* $OpenBSD: conf.h,v 1.3 2019/01/23 09:57:36 phessler Exp $ */ /* $NetBSD: conf.h,v 1.2 1996/05/05 19:28:34 christos Exp $ */ /* @@ -48,6 +48,16 @@ cdev_decl(mm); cdev_decl(openprom); +/* open, close, write, ioctl, kqueue */ +#define cdev_acpiapm_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, selfalse, \ + (dev_type_mmap((*))) enodev, 0, 0, dev_init(c,n,kqfilter) } + +cdev_decl(apm); +cdev_decl(acpiapm); + /* * These numbers have to be in sync with bdevsw/cdevsw. */ |