From: Wayne W. <wh...@ma...> - 2002-02-20 22:54:23
|
On Wed, 20 Feb 2002, Grover, Andrew wrote: > The change from the until now is that instead of just making sure the > latency for C2 is OK, we also check that the plvl2 address is legit. I > think the old version saying you had C2 was wrong. So, I'd say the > chances of getting C2 working on this machine are zero. Sorry. Thank you for your speedy response! I have two followups questions, in case you have a chance to consider them: 1) Do you know if the problem is that the Sis 735 doesn't support putting the processor into C2, or that the ECS BIOS writers haven't included the appropriate information in the ACPI tables? In the latter case I could try bugging ECS. 2) Secondly, as I say my interest is in using the "bus disconnect on STPGNT". Someone pointed me towards a Linux version of the user mode vcool program that is supposed to support the Sis 735. The program is very simple and I include it below. It basically sets a bit in the northbridge (register 0x6A bit 1) to turn on the "bus disconnect on STPGNT" and then runs an idle loop which repeatedly reads some port (presumably the PLVL_2 register). Running the program kills any audio playback and locks up my machine after a few minutes, but it does cause the CPU temperature to drop 4-5 degrees Celsius before it locks up. So I was wondering if that shows that it is possible to enter C2 state on this hardware. Best wishes, Wayne /*************************************************************************** LVCool.c Sets the "enable Bus disconnect on STPGNT" bit on the northbridge and runs and idle loop that puts the CPU into STPGNT mode. Since I'm not a Linux guy just the minimum approach here *g* ------------------- begin : Fri Jul 6 10:13:24 CEST 2001 copyright : (C) 2001 by Martin Peters modified for SiS735 by thgr8t ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifdef HAVE_CONFIG_H #include <config.h> #endif #include <stdlib.h> #include <sys/io.h> #include <unistd.h> #include <stdio.h> int Reg_PL2; int nb_b=0, nb_d=0, nb_f=0; #define CONFIG_ADDRESS 0xcf8 #define CONFIG_DATA 0xcfc #define FORWARD_REG 0xcfa #define PCI_CONF1_ADDRESS(bus, dev, fn, reg) \ (0x80000000 | (bus << 16) | (dev << 11) | (fn << 8) | (reg & ~3)) #define u32 unsigned int #define u8 unsigned char #define u16 unsigned short static int pci_conf1_read (int seg, int bus, int dev, int fn, int reg, int len, u32 *value) { if (!value || (bus > 255) || (dev > 31) || (fn > 7) || (reg > 255)) return -1; outl(PCI_CONF1_ADDRESS(bus, dev, fn, reg), 0xCF8); switch (len) { case 1: *value = inb(0xCFC + (reg & 3)); break; case 2: *value = inw(0xCFC + (reg & 2)); break; case 4: *value = inl(0xCFC); break; } return 0; } static int pci_conf1_write (int seg, int bus, int dev, int fn, int reg, int len, u32 value) { if ((bus > 255) || (dev > 31) || (fn > 7) || (reg > 255)) return -1; outl(PCI_CONF1_ADDRESS(bus, dev, fn, reg), 0xCF8); switch (len) { case 1: outb((u8)value, 0xCFC + (reg & 3)); break; case 2: outw((u16)value, 0xCFC + (reg & 2)); break; case 4: outl((u32)value, 0xCFC); break; } return 0; } #undef PCI_CONF1_ADDRESS static int pci_conf1_read_config_byte(int bus, int dev, int fun, int reg, u8 *value) { int result; u32 data; if (!value) return -1; result = pci_conf1_read(0, bus, dev, fun, reg, 1, &data); *value = (u8)data; return result; } static int pci_conf1_read_config_word(int bus, int dev, int fun, int reg, u16 *value) { int result; u32 data; if (!value) return -1; result = pci_conf1_read(0, bus, dev, fun, reg, 2, &data); *value = (u16)data; return result; } static int pci_conf1_read_config_dword(int bus, int dev, int fun, int reg, u32 *value) { if (!value) return -1; return pci_conf1_read(0, bus, dev, fun, reg, 4, value); } static int pci_conf1_write_config_byte(int bus, int dev, int fun, int reg, u8 value) { return pci_conf1_write(0, bus, dev, fun, reg, 1, value); } static int pci_conf1_write_config_word(int bus, int dev, int fun, int reg, u16 value) { return pci_conf1_write(0, bus, dev, fun, reg, 2, value); } static int pci_conf1_write_config_dword(int bus, int dev, int fun, int reg, u32 value) { return pci_conf1_write(0, bus, dev, fun, reg, 4, value); } int InitPCI() { u32 res; int found=0; int bus,dev,fun,i=0; u16 acpi; u8 states; int ioaddr; for (bus=0;!found && (bus<255);bus++) { for (dev=0;!found && (dev<32);dev++) { for (fun=0;!found && (fun<7);fun++) { pci_conf1_read_config_dword(bus, dev, fun, 0, &res); if (res==0xffffffff) continue; if (res==0x07351039) { nb_b=bus; nb_d=dev; nb_f=fun; printf("Found SiS735 on bus %d dev %d fun %d\n", nb_b, nb_d, nb_f); found = 1; } } } } // enable ACPI and find I/O-Space if (found) { nb_f = 0; pci_conf1_read_config_word(nb_b, nb_d, nb_f, 0x68, &acpi); printf("ACPI Control reg seems to be: 0x%08x\n", (int)acpi); pci_conf1_read_config_byte(nb_b, nb_d, nb_f, 0x6A, &states); printf("ACPI States reg seems to be: 0x%08x\n", (int)states); if (acpi & 0x01) { printf("Value is valid\n"); ioaddr = (acpi & 0xFF00); printf("Value is %x\n", ioaddr); Reg_PL2=ioaddr+0x14; states = states | 0x02; /* set disconnect enable */ pci_conf1_write_config_byte(nb_b, nb_d, nb_f, 0x6A, states); } } return found; } void Idleloop() { if(nice(20) == -1) { perror("nice"); } while(1) inb(Reg_PL2); } int main(int argc, char *argv[]) { if (iopl(3)<0) perror("must run as root"); if (InitPCI()) { Idleloop(); } else { printf("SiS735 not found :(.\n"); } return EXIT_SUCCESS; } |