Message ID | 1311211654-14326-15-git-send-email-agraf@suse.de |
---|---|
State | New |
Headers | show |
On Thu, 21 Jul 2011 03:27:25 +0200 Alexander Graf <agraf@suse.de> wrote: > +/* Try to find a device tree node for a CPU with clock-frequency property */ > +static int kvmppc_find_cpu_dt(char *buf, int buf_len) > +{ > + struct dirent *dirp; > + DIR *dp; > + > + if ((dp = opendir(PROC_DEVTREE_CPU)) == NULL) { > + printf("Can't open directory " PROC_DEVTREE_CPU "\n"); > + return -1; > + } > + > + buf[0] = '\0'; > + while ((dirp = readdir(dp)) != NULL) { > + FILE *f; > + snprintf(buf, buf_len, "%s%s/clock-frequency", PROC_DEVTREE_CPU, > + dirp->d_name); > + f = fopen(buf, "r"); > + if (f) { > + snprintf(buf, buf_len, "%scpus/%s", PROC_DEVTREE_CPU, dirp->d_name); > + fclose(f); > + break; > + } > + buf[0] = '\0'; > + } > + closedir(dp); > + if (buf[0] == '\0') { > + printf("Unknown host!\n"); > + return -1; > + } "Unknown host!" is a little vague for an error message. > +uint32_t kvmppc_get_clockfreq(void) > +{ > + char buf[512]; > + uint32_t tb; > + FILE *f; > + int len; > + > + if (kvmppc_find_cpu_dt(buf, sizeof(buf))) { > + return 0; > + } > + > + snprintf(buf, sizeof(buf), "%s/clock-frequency", buf); > + > + f = fopen(buf, "rb"); > + if (!f) { > + return -1; > + } > + > + len = fread(&tb, sizeof(tb), 1, f); > + if (len != 1) { > + goto err; > + } > + > + return tb; > +err: > + fclose(f); > + return 0; > +} Need to convert endian from big to host. Also, the frequency can be 64-bit. -Scott
Am 21.07.2011 um 19:51 schrieb Scott Wood <scottwood@freescale.com>: > On Thu, 21 Jul 2011 03:27:25 +0200 > Alexander Graf <agraf@suse.de> wrote: > >> +/* Try to find a device tree node for a CPU with clock-frequency property */ >> +static int kvmppc_find_cpu_dt(char *buf, int buf_len) >> +{ >> + struct dirent *dirp; >> + DIR *dp; >> + >> + if ((dp = opendir(PROC_DEVTREE_CPU)) == NULL) { >> + printf("Can't open directory " PROC_DEVTREE_CPU "\n"); >> + return -1; >> + } >> + >> + buf[0] = '\0'; >> + while ((dirp = readdir(dp)) != NULL) { >> + FILE *f; >> + snprintf(buf, buf_len, "%s%s/clock-frequency", PROC_DEVTREE_CPU, >> + dirp->d_name); >> + f = fopen(buf, "r"); >> + if (f) { >> + snprintf(buf, buf_len, "%scpus/%s", PROC_DEVTREE_CPU, dirp->d_name); >> + fclose(f); >> + break; >> + } >> + buf[0] = '\0'; >> + } >> + closedir(dp); >> + if (buf[0] == '\0') { >> + printf("Unknown host!\n"); >> + return -1; >> + } > > "Unknown host!" is a little vague for an error message. > >> +uint32_t kvmppc_get_clockfreq(void) >> +{ >> + char buf[512]; >> + uint32_t tb; >> + FILE *f; >> + int len; >> + >> + if (kvmppc_find_cpu_dt(buf, sizeof(buf))) { >> + return 0; >> + } >> + >> + snprintf(buf, sizeof(buf), "%s/clock-frequency", buf); >> + >> + f = fopen(buf, "rb"); >> + if (!f) { >> + return -1; >> + } >> + >> + len = fread(&tb, sizeof(tb), 1, f); >> + if (len != 1) { >> + goto err; >> + } >> + >> + return tb; >> +err: >> + fclose(f); >> + return 0; >> +} > > Need to convert endian from big to host. Hm. This is kvm specific code for ppc, so only ever runs on host==big :) > Also, the frequency can be 64-bit. Would the parameter just be 2 cells then? Got an example how this works? Alex > > -Scott >
On Thu, 21 Jul 2011 20:59:40 +0200 Alexander Graf <agraf@suse.de> wrote: > >> +uint32_t kvmppc_get_clockfreq(void) > >> +{ > >> + char buf[512]; > >> + uint32_t tb; > >> + FILE *f; > >> + int len; > >> + > >> + if (kvmppc_find_cpu_dt(buf, sizeof(buf))) { > >> + return 0; > >> + } > >> + > >> + snprintf(buf, sizeof(buf), "%s/clock-frequency", buf); > >> + > >> + f = fopen(buf, "rb"); > >> + if (!f) { > >> + return -1; > >> + } > >> + > >> + len = fread(&tb, sizeof(tb), 1, f); > >> + if (len != 1) { > >> + goto err; > >> + } > >> + > >> + return tb; > >> +err: > >> + fclose(f); > >> + return 0; > >> +} > > > > Need to convert endian from big to host. > > Hm. This is kvm specific code for ppc, so only ever runs on host==big :) Sigh. I looked at what file it was specifically to check whether it was in a ppc or generic file, and somehow I still didn't see the "ppc". :-P > > Also, the frequency can be 64-bit. > > Would the parameter just be 2 cells then? Got an example how this works? Yes, it would be 2 cells. Just check the property length. -Scott
diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c index 21f35af..13aa9ae 100644 --- a/target-ppc/kvm.c +++ b/target-ppc/kvm.c @@ -14,6 +14,7 @@ * */ +#include <dirent.h> #include <sys/types.h> #include <sys/ioctl.h> #include <sys/mman.h> @@ -38,6 +39,8 @@ do { } while (0) #endif +#define PROC_DEVTREE_CPU "/proc/device-tree/cpus/" + const KVMCapabilityInfo kvm_arch_required_capabilities[] = { KVM_CAP_LAST_INFO }; @@ -509,6 +512,68 @@ uint32_t kvmppc_get_tbfreq(void) return retval; } +/* Try to find a device tree node for a CPU with clock-frequency property */ +static int kvmppc_find_cpu_dt(char *buf, int buf_len) +{ + struct dirent *dirp; + DIR *dp; + + if ((dp = opendir(PROC_DEVTREE_CPU)) == NULL) { + printf("Can't open directory " PROC_DEVTREE_CPU "\n"); + return -1; + } + + buf[0] = '\0'; + while ((dirp = readdir(dp)) != NULL) { + FILE *f; + snprintf(buf, buf_len, "%s%s/clock-frequency", PROC_DEVTREE_CPU, + dirp->d_name); + f = fopen(buf, "r"); + if (f) { + snprintf(buf, buf_len, "%scpus/%s", PROC_DEVTREE_CPU, dirp->d_name); + fclose(f); + break; + } + buf[0] = '\0'; + } + closedir(dp); + if (buf[0] == '\0') { + printf("Unknown host!\n"); + return -1; + } + + return 0; +} + +uint32_t kvmppc_get_clockfreq(void) +{ + char buf[512]; + uint32_t tb; + FILE *f; + int len; + + if (kvmppc_find_cpu_dt(buf, sizeof(buf))) { + return 0; + } + + snprintf(buf, sizeof(buf), "%s/clock-frequency", buf); + + f = fopen(buf, "rb"); + if (!f) { + return -1; + } + + len = fread(&tb, sizeof(tb), 1, f); + if (len != 1) { + goto err; + } + + return tb; +err: + fclose(f); + return 0; +} + int kvmppc_get_hypercall(CPUState *env, uint8_t *buf, int buf_len) { uint32_t *hc = (uint32_t*)buf; diff --git a/target-ppc/kvm_ppc.h b/target-ppc/kvm_ppc.h index 2f32249..1827a13 100644 --- a/target-ppc/kvm_ppc.h +++ b/target-ppc/kvm_ppc.h @@ -23,6 +23,7 @@ int kvmppc_read_host_property(const char *node_path, const char *prop, #endif uint32_t kvmppc_get_tbfreq(void); +uint32_t kvmppc_get_clockfreq(void); int kvmppc_get_hypercall(CPUState *env, uint8_t *buf, int buf_len); int kvmppc_set_interrupt(CPUState *env, int irq, int level);
We need to find out the host's clock-frequency when running on KVM, so let's export a respective function. Signed-off-by: Alexander Graf <agraf@suse.de> --- target-ppc/kvm.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++ target-ppc/kvm_ppc.h | 1 + 2 files changed, 66 insertions(+), 0 deletions(-)