> Date: Sun, 16 Oct 2022 11:48:56 -0400
> From: George Koehler <kern...@gmail.com>
> 
> This diff will add a few features to the macppc kernel:
> 
>  - sysctl hw.power will be set to 0 or 1 when I unplug or plug in
>    my PowerBook's AC adapter.
>  - sysctl machdep.lidaction and machdep.pwraction will exist.
>  - The default machdep.pwraction=1 will power off my macppc when I
>    push the power button.
>  - The default machdep.lidaction=1 should suspend, but will do
>    nothing, because suspend is not yet implemented.
>  - PowerBooks and iBooks will have a lid sensor, which looks like
> 
> $ sysctl hw.sensors
> hw.sensors.adb0.indicator0=On (lid open)
> 
> machdep.{lid,pwr}action are documented in acpi(4), but macppcs
> don't have acpi.  This diff doesn't change any manuals.  To access
> the new sysctls, I needed to build a kernel, install the kernel's
> includes, and build sysctl(8).  machdep.pwraction=0 will disable the
> power button, which I might do on my Cube G4, where I sometimes touch
> the power button by accident.  Small kernels (bsd.rd) will ignore the
> power button.  Some other models of macppcs might have power buttons
> or lids that don't work with this diff.
> 
> Most of these features use adb(4)'s environment interrupt, which
> this diff renames from PMU_INT_WAKEUP to PMU_INT_ENVIRONMENT to
> match Linux, FreeBSD, NetBSD.  I will commit this diff in a few
> days, unless it breaks my build.  A 2nd commit will connect the
> power button and lid interrupts to the incomplete suspend code.
> 
> --George

The consensus is that calling prsignal() from interrupt context isn't
safe.  See dev/fdt/dapmic.c for a way to avoid that.

You probably want to remove the #ifdef 0 code before committing this.

> 
> Index: arch/macppc/dev/adb.c
> ===================================================================
> RCS file: /cvs/src/sys/arch/macppc/dev/adb.c,v
> retrieving revision 1.46
> diff -u -p -r1.46 adb.c
> --- arch/macppc/dev/adb.c     2 Jul 2022 08:50:41 -0000       1.46
> +++ arch/macppc/dev/adb.c     8 Oct 2022 03:52:17 -0000
> @@ -831,6 +831,41 @@ adb_soft_intr(void)
>       }
>  }
>  
> +void
> +adb_lid_closed_intr(void)
> +{
> +#ifndef SMALL_KERNEL
> +     switch (lid_action) {
> +     case 1:
> +             /* Suspend. */
> +             break;
> +     case 2:
> +             /* Hibernate. */
> +             break;
> +     }
> +#endif
> +}
> +
> +void
> +adb_power_button_intr(void)
> +{
> +#ifndef SMALL_KERNEL
> +     extern int allowpowerdown;
> +
> +     switch (pwr_action) {
> +     case 1:
> +             if (allowpowerdown == 1) {
> +                     allowpowerdown = 0;
> +                     prsignal(initprocess, SIGUSR2);
> +             }
> +             break;
> +     case 2:
> +             /* Suspend. */
> +             break;
> +     }
> +#endif
> +}
> +
>  
>  /*
>   * This is my version of the ADBOp routine. It mainly just calls the
> @@ -1597,6 +1632,7 @@ adbattach(struct device *parent, struct 
>               adbHardware = ADB_HW_CUDA;
>       else if (strcmp(ca->ca_name, "via-pmu") == 0) {
>               adbHardware = ADB_HW_PMU;
> +             pm_in_adbattach(sc->sc_dev.dv_xname);
>  
>               /*
>                * Bus reset can take a long time if no adb devices are
> Index: arch/macppc/dev/pm_direct.c
> ===================================================================
> RCS file: /cvs/src/sys/arch/macppc/dev/pm_direct.c,v
> retrieving revision 1.31
> diff -u -p -r1.31 pm_direct.c
> --- arch/macppc/dev/pm_direct.c       18 Sep 2022 21:36:41 -0000      1.31
> +++ arch/macppc/dev/pm_direct.c       8 Oct 2022 03:52:17 -0000
> @@ -42,6 +42,7 @@
>  #include <sys/param.h>
>  #include <sys/device.h>
>  #include <sys/systm.h>
> +#include <sys/sensors.h>
>  
>  #include <machine/cpu.h>
>  
> @@ -142,6 +143,9 @@ signed char pm_receive_cmd_type[] = {
>         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
>  };
>  
> +int pm_old_env;
> +struct ksensor pm_lid_sens;
> +struct ksensordev pm_sensdev;
>  
>  /*
>   * Define the private functions
> @@ -161,6 +165,10 @@ int      pm_send(u_char);
>  void pm_adb_get_TALK_result(PMData *);
>  void pm_adb_get_ADB_data(PMData *);
>  
> +void pm_env_intr(PMData *);
> +
> +
> +extern int   hw_power;
>  
>  /*
>   * These variables are in adb_direct.c.
> @@ -413,6 +421,21 @@ pmgrop(PMData *pmdata)
>       return rval;
>  }
>  
> +void
> +pm_in_adbattach(const char *devname)
> +{
> +     /* A PowerBook (including iBook) has a lid. */
> +     if (strncmp(hw_prod, "PowerBook", 9) == 0) {
> +             strlcpy(pm_sensdev.xname, devname,
> +                 sizeof(pm_sensdev.xname));
> +             strlcpy(pm_lid_sens.desc, "lid open",
> +                 sizeof(pm_lid_sens.desc));
> +             pm_lid_sens.type = SENSOR_INDICATOR;
> +             sensor_attach(&pm_sensdev, &pm_lid_sens);
> +             sensordev_install(&pm_sensdev);
> +             pm_lid_sens.value = 1; /* This is a guess. */
> +     }
> +}
>  
>  /*
>   * My PM interrupt routine for the PB Duo series and the PB 5XX series
> @@ -456,9 +479,11 @@ pm_intr(void)
>       case 0x16:              /* ADB device event */
>       case 0x18:
>       case 0x1e:
> -     case PMU_INT_WAKEUP:
>               pm_adb_get_ADB_data(&pmdata);
>               break;
> +     case PMU_INT_ENVIRONMENT:
> +             pm_env_intr(&pmdata);
> +             break;
>       default:
>  #ifdef ADB_DEBUG
>               if (adb_debug)
> @@ -664,6 +689,41 @@ pm_adb_get_ADB_data(PMData *pmdata)
>  }
>  
>  void
> +pm_env_intr(PMData *pmdata)
> +{
> +     int env, old;
> +#if 0
> +     int i;
> +
> +     printf("pm_env_intr:");
> +     for (i = 3; i < pmdata->num_data; i++)
> +             printf(" %02x", pmdata->data[i]);
> +     printf("\n");
> +#endif
> +
> +     /* We might have 3 bytes data[3..5], but use only data[3]. */
> +     if (pmdata->num_data < 3)
> +             return;
> +     env = pmdata->data[3];
> +     old = pm_old_env;
> +
> +     pm_lid_sens.value = !(env & PMU_ENV_LID_CLOSED);
> +     if (!(old & PMU_ENV_LID_CLOSED) && (env & PMU_ENV_LID_CLOSED))
> +             adb_lid_closed_intr();
> +
> +     hw_power = !!(env & PMU_ENV_AC_POWER);
> +
> +     /*
> +      * Act if one presses and releases the power button on a Mac
> +      * with no ADB keyboard.
> +      */
> +     if ((old & PMU_ENV_POWER_BUTTON) && !(env & PMU_ENV_POWER_BUTTON))
> +             adb_power_button_intr();
> +
> +     pm_old_env = env;
> +}
> +
> +void
>  pm_adb_restart(void)
>  {
>       PMData p;
> @@ -753,6 +813,7 @@ pm_battery_info(int battery, struct pmu_
>       pmgrop(&p);
>  
>       info->flags = p.data[1];
> +     hw_power = !!(info->flags & PMU_PWR_AC_PRESENT);
>  
>       switch (p.data[0]) {
>       case 3:
> Index: arch/macppc/dev/pm_direct.h
> ===================================================================
> RCS file: /cvs/src/sys/arch/macppc/dev/pm_direct.h,v
> retrieving revision 1.14
> diff -u -p -r1.14 pm_direct.h
> --- arch/macppc/dev/pm_direct.h       18 Sep 2022 21:36:41 -0000      1.14
> +++ arch/macppc/dev/pm_direct.h       8 Oct 2022 03:52:17 -0000
> @@ -49,6 +49,7 @@ typedef     struct  {
>  }    PMData;
>  
>  int  pmgrop(PMData *);
> +void pm_in_adbattach(const char *);
>  int  pm_adb_op(u_char *, void *, void *, int);
>  void pm_adb_restart(void);
>  void pm_adb_poweroff(void);
> @@ -104,7 +105,7 @@ void pmu_fileserver_mode(int);
>  #define PMU_INT_SNDBRT               0x08    /* sound/brightness up/down 
> buttons */
>  #define PMU_INT_ADB          0x10    /* ADB autopoll or reply data */
>  #define PMU_INT_BATTERY              0x20
> -#define PMU_INT_WAKEUP               0x40
> +#define PMU_INT_ENVIRONMENT  0x40
>  #define PMU_INT_TICK         0x80    /* 1-second tick interrupt */
>  #define PMU_INT_ALL          0xff    /* Mask of all interrupts */
>  
> @@ -119,6 +120,13 @@ void pmu_fileserver_mode(int);
>  #define PMU_POW_CHARGER              0x02    /* battery charger power */
>  #define PMU_POW_IRLED                0x04    /* IR led power (on wallstreet) 
> */
>  #define PMU_POW_MEDIABAY     0x08    /* media bay power (wallstreet/lombard 
> ?) */
> +
> +/* Bits from PMU_INT_ENVIRONMENT */
> +#define PMU_ENV_LID_CLOSED   0x01    /* The lid is closed */
> +#define PMU_ENV_AC_POWER     0x04    /* AC is plugged in */
> +#define PMU_ENV_POWER_BUTTON 0x08    /* power button on ADB-less Macs */
> +#define PMU_ENV_BATTERY              0x10
> +#define PMU_ENV_OVER_TEMP    0x20
>  
>  /* PMU PMU_POWER_EVENTS commands */
>  enum {
> Index: arch/macppc/include/cpu.h
> ===================================================================
> RCS file: /cvs/src/sys/arch/macppc/include/cpu.h,v
> retrieving revision 1.14
> diff -u -p -r1.14 cpu.h
> --- arch/macppc/include/cpu.h 9 Oct 2013 17:43:50 -0000       1.14
> +++ arch/macppc/include/cpu.h 8 Oct 2022 03:52:17 -0000
> @@ -39,12 +39,16 @@
>   */
>  #define CPU_ALLOWAPERTURE    1       /* allow mmap of /dev/xf86 */
>  #define CPU_ALTIVEC          2       /* altivec is present */
> -#define CPU_MAXID            3       /* number of valid machdep ids */
> +#define CPU_LIDACTION                3       /* action caused by lid close */
> +#define CPU_PWRACTION                4       /* action caused by power 
> button */
> +#define CPU_MAXID            5       /* number of valid machdep ids */
>  
>  #define      CTL_MACHDEP_NAMES { \
>       { 0, 0 }, \
>       { "allowaperture", CTLTYPE_INT }, \
>       { "altivec", CTLTYPE_INT }, \
> +     { "lidaction", CTLTYPE_INT }, \
> +     { "pwraction", CTLTYPE_INT }, \
>  }
>  
>  #ifdef _KERNEL
> @@ -64,6 +68,9 @@ extern void (*ppc64_slew_voltage)(u_int)
>  
>  extern u_int32_t     ticks_per_sec;
>  extern u_int32_t     ns_per_tick;
> +
> +extern int           lid_action;
> +extern int           pwr_action;
>  
>  #endif /* _KERNEL */
>  #endif /* _MACHINE_CPU_H_ */
> Index: arch/macppc/macppc/machdep.c
> ===================================================================
> RCS file: /cvs/src/sys/arch/macppc/macppc/machdep.c,v
> retrieving revision 1.196
> diff -u -p -r1.196 machdep.c
> --- arch/macppc/macppc/machdep.c      19 May 2022 05:43:48 -0000      1.196
> +++ arch/macppc/macppc/machdep.c      8 Oct 2022 03:52:17 -0000
> @@ -117,6 +117,8 @@ void * startsym, *endsym;
>  #ifdef APERTURE
>  int allowaperture = 0;
>  #endif
> +int lid_action = 1;
> +int pwr_action = 1;
>  
>  void dumpsys(void);
>  int lcsplx(int ipl); /* called from LCore */
> @@ -346,7 +348,7 @@ install_extint(void (*handler)(void))
>       extint_call = (extint_call & 0xfc000003) | offset;
>       bcopy(&extint, (void *)EXC_EXI, (size_t)&extsize);
>       syncicache((void *)&extint_call, sizeof extint_call);
> -     syncicache((void *)EXC_EXI, (int)&extsize);
> +     syncicache((void *)EXC_EXI, (size_t)&extsize);
>       ppc_mtmsr(omsr);
>  }
>  
> @@ -533,9 +535,14 @@ sys_sigreturn(struct proc *p, void *v, r
>       return EJUSTRETURN;
>  }
>  
> +const struct sysctl_bounded_args cpuctl_vars[] = {
> +     { CPU_ALTIVEC, &ppc_altivec, SYSCTL_INT_READONLY },
> +     { CPU_LIDACTION, &lid_action, 0, 2 },
> +     { CPU_PWRACTION, &pwr_action, 0, 2 },
> +};
> +
>  /*
>   * Machine dependent system variables.
> - * None for now.
>   */
>  int
>  cpu_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
> @@ -556,10 +563,9 @@ cpu_sysctl(int *name, u_int namelen, voi
>  #else
>               return (sysctl_rdint(oldp, oldlenp, newp, 0));
>  #endif
> -     case CPU_ALTIVEC:
> -             return (sysctl_rdint(oldp, oldlenp, newp, ppc_altivec));
>       default:
> -             return EOPNOTSUPP;
> +             return (sysctl_bounded_arr(cpuctl_vars, nitems(cpuctl_vars),
> +                 name, namelen, oldp, oldlenp, newp, newlen));
>       }
>  }
>  
> Index: dev/adb/adb.h
> ===================================================================
> RCS file: /cvs/src/sys/dev/adb/adb.h,v
> retrieving revision 1.5
> diff -u -p -r1.5 adb.h
> --- dev/adb/adb.h     16 Jun 2011 10:44:33 -0000      1.5
> +++ dev/adb/adb.h     8 Oct 2022 03:52:18 -0000
> @@ -139,6 +139,8 @@ typedef struct {
>  } ADBDataBlock;
>  
>  int  adbprint(void *, const char *);
> +void adb_lid_closed_intr(void);
> +void adb_power_button_intr(void);
>  int  adb_op_sync(Ptr, short);
>  int  set_adb_info(ADBSetInfoBlock *, int);
>  
> Index: dev/adb/akbd.c
> ===================================================================
> RCS file: /cvs/src/sys/dev/adb/akbd.c,v
> retrieving revision 1.15
> diff -u -p -r1.15 akbd.c
> --- dev/adb/akbd.c    6 Apr 2022 18:59:27 -0000       1.15
> +++ dev/adb/akbd.c    8 Oct 2022 03:52:18 -0000
> @@ -467,13 +467,14 @@ akbd_processevent(struct akbd_softc *sc,
>       case 2:
>               /*
>                * The reset (or power) key sends 0x7f7f on press and
> -              * 0xffff on release, and we ignore it.
> +              * 0xffff on release.
>                */
>               if (event->bytes[0] == event->bytes[1] &&
>                   ADBK_KEYVAL(event->bytes[0]) == ADBK_RESET) {
> -                     if (event->bytes[0] == ADBK_KEYDOWN(ADBK_RESET))
> +                     if (event->bytes[0] == ADBK_KEYDOWN(ADBK_RESET)) {
>                               SET(sc->sc_caps, CL_DOWN_RESET);
> -                     else {
> +                             adb_power_button_intr();
> +                     } else {
>                               if (ISSET(sc->sc_caps, CL_DOWN_RESET))
>                                       CLR(sc->sc_caps, CL_DOWN_RESET);
>                               else if (ISSET(sc->sc_caps, CL_DOWN_ADB)) {
> 
> 

Reply via email to