LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   Can't build simple program!! (https://www.linuxquestions.org/questions/programming-9/cant-build-simple-program-257396/)

kwlux 11-20-2004 06:53 PM

Can't build simple program!!
 
I'm at my wits end. I can't figure this thing out - it makes no sense to me.

System:

Sony Vaio w/ugraded CPU (Athlon 2600+)
Topologilinux 5.0.0 (slackware 10 base)
kernels 2.4.26 and 2.6.9

I'm trying to modify the cpufreq driver powernow-k7.c to simply set the CPU core voltage to 1.225V (by BIOS doesn't have a PST for my CPU).

I have simple program for WinXP that works flawlesly doing this.

I simply removed everything except the FID and VID table (for reference) and the functions to set the VID and the FID.

The program compiles, but then returns:

In function: 'Change_FID':
:undefined reference to 'rdmsrl'
In function: 'Change_FID':
:undefined reference to 'wrmsrl'
In function: 'Change_VID':
:undefined reference to 'rdmsrl'
In function: 'Change_VID':
:undefined reference to 'wrmsrl'

which I dorn't understand since rdmsrl and wrmdrl are defined explicitly in msr.h:

#ifndef __ASM_MSR_H
#define __ASM_MSR_H

/*
* Access to machine-specific registers (available on 586 and better only)
* Note: the rd* operations modify the parameters directly (without using
* pointer indirection), this allows gcc to optimize better
*/

#define rdmsr(msr,val1,val2) \
__asm__ __volatile__("rdmsr" \
: "=a" (val1), "=d" (val2) \
: "c" (msr))

#define wrmsr(msr,val1,val2) \
__asm__ __volatile__("wrmsr" \
: /* no outputs */ \
: "c" (msr), "a" (val1), "d" (val2))

#define rdmsrl(msr,val) do { \
unsigned long l__,h__; \
rdmsr (msr, l__, h__); \
val = l__; \
val |= ((u64)h__<<32); \
} while(0)

static inline void wrmsrl (unsigned long msr, unsigned long long val)
{
unsigned long lo, hi;
lo = (unsigned long) val;
hi = val >> 32;
wrmsr (msr, lo, hi);
}




Here is the listing of the program:

/*
*

Sets Athlon K7 Core Voltage to 1.225 V

Using AMD K7 Powernow driver.
* (C) 2003 Dave Jones <davej@codemonkey.org.uk> on behalf of SuSE Labs.
* (C) 2003-2004 Dave Jones <davej@redhat.com>
*
* Licensed under the terms of the GNU GPL License version 2.
* Based upon datasheets & sample CPUs kindly provided by AMD.
*
* Errata 5: Processor may fail to execute a FID/VID change in presence of interrupt.
* - We cli/sti on stepping A0 CPUs around the FID/VID transition.
* Errata 15: Processors with half frequency multipliers may hang upon wakeup from disconnect.
* - We disable half multipliers if ACPI is used on A0 stepping CPUs.
*/
#include <stdio.h>
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
//#include <linux/cpufreq.h>
#include <linux/slab.h>
#include <linux/string.h>
//#include <linux/dmi.h>

//#include <asm/msr.h>
#include <asm/timex.h>
#include <asm/io.h>
#include <asm/system.h>

#include "powernow-k7.h"

#include "/usr/src/linux/include/asm-i386/msr.h"

#define PFX "powernow: "


// Back to main program


/* divide by 1000 to get VID. */
static int mobile_vid_table[32] = {
2000, 1950, 1900, 1850, 1800, 1750, 1700, 1650,
1600, 1550, 1500, 1450, 1400, 1350, 1300, 0,
1275, 1250, 1225, 1200, 1175, 1150, 1125, 1100,
1075, 1050, 1024, 1000, 975, 950, 925, 0,
};

/* divide by 10 to get FID. */
static int fid_codes[32] = {
110, 115, 120, 125, 50, 55, 60, 65,
70, 75, 80, 85, 90, 95, 100, 105,
30, 190, 40, 200, 130, 135, 140, 210,
150, 225, 160, 165, 170, 180, -1, -1,
};

/* This parameter is used in order to force ACPI instead of legacy method for
* configuration purpose.
*/

static int acpi_force;
static int debug;

//static struct cpufreq_frequency_table *powernow_table;

/*static unsigned int can_scale_bus;
static unsigned int can_scale_vid;
static unsigned int minimum_speed=-1;
static unsigned int maximum_speed;
static unsigned int number_scales;
static unsigned int fsb;
static unsigned int latency;
static char have_a0;
*/

static unsigned int latency=100;

static void change_FID(int fid)
{
union msr_fidvidctl fidvidctl;

rdmsrl (MSR_K7_FID_VID_CTL, fidvidctl.val);
if (fidvidctl.bits.FID != fid) {
fidvidctl.bits.SGTC = latency;
fidvidctl.bits.FID = fid;
fidvidctl.bits.VIDC = 0;
fidvidctl.bits.FIDC = 1;
wrmsrl (MSR_K7_FID_VID_CTL, fidvidctl.val);
}
}


static void change_VID(int vid)
{
union msr_fidvidctl fidvidctl;

rdmsrl (MSR_K7_FID_VID_CTL, fidvidctl.val);
if (fidvidctl.bits.VID != vid) {
fidvidctl.bits.SGTC = latency;
fidvidctl.bits.VID = vid;
fidvidctl.bits.FIDC = 0;
fidvidctl.bits.VIDC = 1;
wrmsrl (MSR_K7_FID_VID_CTL, fidvidctl.val);
}
}

int main (void)
{
printf("Changing VID to index 18 =1.225 V");
change_VID(18);
return 0;
}

itsme86 11-20-2004 07:00 PM

Header files don't contain the functions, just the function prototypes. The functions themselves are probably contained in a library that you need to link into your program.

kwlux 11-20-2004 08:10 PM

I have no idea what library they are in.

But it looks like rdmsrl and wrmsrl are defined in msr.h, not just listed as prototypes.

I have googled "wrmsrl" and "rdmsrl" in an attempt to find the libraries, but I only get links to these functions in code, no libraries.

Cedrik 11-21-2004 05:17 AM

Did you read Documentation/cpu-freq/amd-powernow.txt from your kernel tree ?

Also for my part I enable powersaving with setpci at boot in a init script folowing this link :
http://ldp.kernelnotes.de/HOWTO/Athl...pproaches.html


All times are GMT -5. The time now is 05:00 PM.