All of lore.kernel.org
 help / color / mirror / Atom feed
* cpufreq and P-IIIM
@ 2003-08-16 20:28 Jan Rychter
  2003-08-18 11:29 ` Ducrot Bruno
  0 siblings, 1 reply; 11+ messages in thread
From: Jan Rychter @ 2003-08-16 20:28 UTC (permalink / raw)
  To: cpufreq


[-- Attachment #1.1: Type: text/plain, Size: 2595 bytes --]

Hi,

I've just tried the latest 2.4 snapshot of cpufreq. Unfortunately, it
doesn't seem to work on my hardware. It says:

  cpufreq: Intel(R) SpeedStep(TM) support $Revision: 1.7.2.6 $
  cpufreq: Intel(R) SpeedStep(TM) for this chipset not (yet) available.

/proc/cpuinfo says:
  processor       : 0
  vendor_id       : GenuineIntel
  cpu family      : 6
  model           : 11
  model name      : Intel(R) Pentium(R) III Mobile CPU       750MHz
  stepping        : 1
  cpu MHz         : 746.352
  cache size      : 512 KB
  fdiv_bug        : no
  hlt_bug         : no
  f00f_bug        : no
  coma_bug        : no
  fpu             : yes
  fpu_exception   : yes
  cpuid level     : 2
  wp              : yes
  flags           : fpu vme de pse tsc msr pae mce cx8 sep mtrr pge mca cmov pat pse36 mmx fxsr sse
  bogomips        : 1490.94

lspci says:
  00:00.0 Class 0600: 8086:7194 (rev 01)
  00:00.1 Class 0401: 8086:7195
  00:00.2 Class 0703: 8086:7196
  00:07.0 Class 0601: 8086:7198 (rev 01)
  00:07.1 Class 0101: 8086:7199
  00:07.2 Class 0c03: 8086:719a
  00:07.3 Class 0680: 8086:719b
  00:09.0 Class 0300: 1002:4c52 (rev 64)
  00:0a.0 Class 0607: 104c:ac1b (rev 03)
  00:0a.1 Class 0607: 104c:ac1b (rev 03)
  00:0b.0 Class 0200: 10ec:8139 (rev 10)

which translates to:
  00:00.0 Host bridge: Intel Corp. 82440MX Host Bridge (rev 01)
  00:00.1 Multimedia audio controller: Intel Corp. 82440MX AC'97 Audio Controller
  00:00.2 Modem: Intel Corp. 82440MX AC'97 Modem Controller
  00:07.0 ISA bridge: Intel Corp. 82440MX ISA Bridge (rev 01)
  00:07.1 IDE interface: Intel Corp. 82440MX EIDE Controller
  00:07.2 USB Controller: Intel Corp. 82440MX USB Universal Host Controller
  00:07.3 Bridge: Intel Corp. 82440MX Power Management Controller
  00:09.0 VGA compatible controller: ATI Technologies Inc Rage Mobility P/M (rev 64)
  00:0a.0 CardBus bridge: Texas Instruments PCI1450 (rev 03)
  00:0a.1 CardBus bridge: Texas Instruments PCI1450 (rev 03)
  00:0b.0 Ethernet controller: Realtek Semiconductor Co., Ltd. RTL-8139/8139C/8139C+ (rev 10)

Now, I have been successfully using Marc Lehmann's 'speedstep' utility,
which after minor changes (mostly uncommenting security checks) works
perfectly for me. When checking state (speedstep -g), it prints:
  EDI == 02020304 != 02020005|02020004,

but I can check speedstep state, and switch it up or down using this
utility. I've attached the (lobotomized by me) speedstep.c that works
for me just fine.

Is there a chance that cpufreq could start supporting my machine?

--J.

[-- Attachment #1.2: speedstep.c --]
[-- Type: application/octet-stream, Size: 8335 bytes --]

/*
 * Copyright (c) 2000 Marc Alexander Lehmann <pcg@goof.com>
 * 
 * Redistribution and use in source and binary forms, with or without modifica-
 * tion, 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 MER-
 * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO
 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
 * CIAL, 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 OTH-
 * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/io.h>
#include <signal.h>

/* daemon mode. */
#define PERFORMANCE 85	/* cpu usage percentage at which to go into maximum performance mode. */
#define BATTERY     75 /* cpu usage percentage at which to enter battery optimized mode. */
#define MINSECS      5  /* enter battery optimized mode only when no activity this number of seconds. */

static int eax, ebx, ecx, edx, esi, edi;

static int opt_quiet;

static void
magic (int function, int state)
{
  asm("movl $-1, %%edi\n"
      "out %%al, (%%dx)\n"
      : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx), "=S" (esi), "=D" (edi)
      : "a" (0x47534982), "b" (function), "c" (state), "d" (0xb2)
  );
}

static void
bailout (char *msg)
{
  fprintf (stderr, "FATAL: %s\n", msg);
  fprintf (stderr,
           "eax %08x\nebx %08x\necx %08x\nedx %08x\nesi %08x\nedi %08x\n",
           eax, ebx, ecx, edx, esi, edi);

  exit(77);
}

static int
get_state (void)
{
  magic (1, 1);

  if (eax != 0)
    bailout ("get state probably failed,\nplease report to <speedstep@plan9.de>, together with /proc/cpuinfo");

  /* 02020005 == on_ac_power, 02020004 == battery power */
  if (edi != 0x02020005 && edi != 0x02020004 && edi != 0x02020305 && !opt_quiet)
    fprintf (stderr, "EDI == %08x != 02020005|02020004,\n"
                     "please report this to <speedstep@plan9.de>, together with /proc/cpuinfo\n"
                     "(suppress this notice with -q)\n", edi);

  if (!opt_quiet)
    printf ("current state: %s\n", ebx ? "battery optimized" : "maximum performance");

  return !!ebx;
}

static void
set_state (int slowdown)
{
  if (!opt_quiet)
    if (slowdown)
      printf ("switching to battery optimized mode\n");
    else
      printf ("switching to maximum performance mode\n");

  magic (2, slowdown);

  /*if (edi != 0)
    bailout ("EDI != 0: setting failed,\nplease report to <speedstep@plan9.de>, together with /proc/cpuinfo\n");*/

/*  if (ebx != slowdown)
    bailout ("could not switch power mode,\nplease report to <speedstep@plan9.de>, together with /proc/cpuinfo\n");*/
}

static void
usage (int rc)
{
  fprintf (stderr, "\n"
      "intel type 2 speedstep mode switching utility version " VERSION "\n"
      "\n"
      "Usage: speedstep [-qhbmg] [-s0] [-s1]\n"
      "         -h        this help\n"
      "         -q        quiet operation\n"
      "         -b | -s1  switch to battery optimized mode\n"
      "         -m | -s0  switch to maximum performance mode\n"
      "         -g        print current mode (default)\n"
      "         -G        exit immediately with the current mode as exit status\n"
      "\n"
      "         -d        go into daemon mode (forks)\n"
      "         -D        same as -d, but don't fork and log mode changes\n"
      "\n"
      "Please report bugs to <speedstep@plan9.de>\n"
      "http://speedstep.plan9.de/\n"
      "\n");
  exit (rc);
}

static int stat_fd;
static unsigned long stat_cpu, stat_noop;

static void
get_stat (void)
{
  char line[80];
  static unsigned long stat_user, stat_nice, stat_system, stat_idle;
  unsigned long n_user, n_nice, n_system, n_idle;

  lseek (stat_fd, 0, SEEK_SET);
  read (stat_fd, line, 79);
  line[79] = 0;

  if (4 != sscanf (line, "%*s %lu %lu %lu %lu", &n_user, &n_nice, &n_system, &n_idle))
    {
      fprintf (stderr, "unable to parse /proc/stat format (%s)\n", line);
      exit (77);
    }

  stat_cpu  = (n_user - stat_user) + (n_system - stat_system);
  stat_noop = stat_cpu + (n_nice - stat_nice) + (n_idle - stat_idle);

  stat_user   = n_user;
  stat_nice   = n_nice;
  stat_system = n_system;
  stat_idle   = n_idle;
}

static enum { MODE_P_DYNAMIC, MODE_B_DYNAMIC,
              MODE_P_STATIC,  MODE_B_STATIC } daemon_mode = MODE_B_DYNAMIC;

static int current_state;

#define SET_STATE(state) if (state != current_state) set_state ((current_state = state))
#define GET_STATE()      get_state ()

static void
daemon_loop (void)
{
  int p_hyst = 0;

  current_state = GET_STATE ();

  for (;;)
    switch (daemon_mode)
      {
        case MODE_P_DYNAMIC:
          SET_STATE (0);

          sleep (2); get_stat ();
          if (stat_cpu * 100 < BATTERY * stat_noop)
            {
              p_hyst += 2;
              if (p_hyst < MINSECS)
                break;

              daemon_mode = MODE_B_DYNAMIC;
            }

          p_hyst = 0;

          break;

        case MODE_B_DYNAMIC:
          SET_STATE (1);

          sleep (1); get_stat ();

          if (stat_cpu * 100 >= PERFORMANCE * stat_noop)
            daemon_mode = MODE_P_DYNAMIC;

          break;

        case MODE_P_STATIC:
          SET_STATE (0);
          pause ();
          break;

        case MODE_B_STATIC:
          SET_STATE (1);
          pause ();
          break;
      }
}

static void handle_signal (int signum)
{
  switch (signum)
    {
      case SIGHUP: 
        current_state = GET_STATE ();
        daemon_mode = current_state ? MODE_B_DYNAMIC : MODE_P_DYNAMIC;
        break;

      case SIGUSR1: daemon_mode = MODE_P_STATIC;  break;
      case SIGUSR2: daemon_mode = MODE_B_STATIC;  break;
    }
}

static void
install_sighands (void)
{
  struct sigaction sa;

  sa.sa_handler = handle_signal;
  sa.sa_flags = SA_RESTART;
  sigemptyset (&sa.sa_mask);

  sigaction (SIGHUP , &sa, 0);
  sigaction (SIGUSR1, &sa, 0);
  sigaction (SIGUSR2, &sa, 0);
}

static void
daemonize (void)
{
  stat_fd = open ("/proc/stat", O_RDONLY);

  if (!stat_fd)
    {
      perror ("/proc/stat");
      exit (1);
    }

  get_stat ();

  install_sighands ();

  chdir ("/");

  if (opt_quiet)
    {
      int i;

      for (i = 0; i <1023; i++)
        if (i != stat_fd)
          close (i);

      if (fork () != 0)
        exit (0);

      setsid ();
    }

  daemon_loop ();
}

int main(int argc, char *argv[])
{
  char *arg;

  ioperm (0xb2, 1, 1); /* we need port b2 */

  if (argc <= 1)
    {
      get_state ();
      exit (0);
    }
  else
    while ((arg = *++argv))
      if (arg[0] != '-')
        usage (1);
      else
        switch (arg[1]) {
          case 'q': opt_quiet++; break;
          case 'g': get_state (); break;
          case 'G': exit (get_state ()); break;
          case 'm': set_state (0); break;
          case 'b': set_state (1); break;

          case 's':
                    if (arg[2] == '0')
                      set_state (0);
                    else if (arg[2] == '1')
                      set_state (1);
                    else
                      usage (1);
                    break;

          case 'd': opt_quiet = 1; daemonize (); break;
          case 'D': daemonize (); break;

          case 'h':
          case '?': usage (0); break;

          default: usage(1); break;
        }

  return 0;
}


[-- Attachment #2: Type: application/pgp-signature, Size: 188 bytes --]

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2003-08-20 17:30 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2003-08-16 20:28 cpufreq and P-IIIM Jan Rychter
2003-08-18 11:29 ` Ducrot Bruno
2003-08-18 17:02   ` Jan Rychter
2003-08-18 18:07     ` Russell King
2003-08-18 18:21       ` cpufreq CVS [Was: Re: cpufreq and P-IIIM] Dominik Brodowski
2003-08-18 18:33         ` Russell King
2003-08-20 11:25           ` Ducrot Bruno
2003-08-20 17:30             ` Benjamin Herrenschmidt
2003-08-19 14:57         ` Bas Mevissen
2003-08-18 17:18   ` cpufreq and P-IIIM Jan Rychter
2003-08-19  8:03     ` Ducrot Bruno

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.