Add a function to query YAMON for the CPU frequency, and set up the

parameters for delay() from this.
This commit is contained in:
simonb 2003-10-27 23:41:42 +00:00
parent 39dd1b6e20
commit eb24c3d567
2 changed files with 55 additions and 6 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: yamon.c,v 1.2 2003/07/15 01:37:32 lukem Exp $ */
/* $NetBSD: yamon.c,v 1.3 2003/10/27 23:41:42 simonb Exp $ */
/*
* Copyright 2002 Wasabi Systems, Inc.
@ -38,11 +38,12 @@
/* XXX move to arch/mips/yamon/yamon.c or similar? */
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: yamon.c,v 1.2 2003/07/15 01:37:32 lukem Exp $");
__KERNEL_RCSID(0, "$NetBSD: yamon.c,v 1.3 2003/10/27 23:41:42 simonb Exp $");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/device.h>
#include <sys/kernel.h>
#include <sys/systm.h>
#include <dev/cons.h>
@ -120,3 +121,38 @@ yamon_exit(uint32_t rc)
YAMON_EXIT(rc);
}
/*
* Ask YAMON for the CPU frequency.
* If "force" is set, then use a random frequency (100MHz) so
* that at least delay() works, even though not perfectly.
* Return 1 if YAMON returns a CPU frequency.
*/
int
yamon_setcpufreq(int force)
{
uint32_t freq;
int ret;
ret = YAMON_SYSCON_READ(SYSCON_BOARD_CPU_CLOCK_FREQ_ID, &freq,
sizeof(freq));
if (!force && (ret != 0 || freq == 0))
return 0;
if (ret != 0 || freq == 0) {
freq = 100 * 1000 * 1000;
ret = 0;
} else
ret = 1;
curcpu()->ci_cpu_freq = freq;
curcpu()->ci_cycles_per_hz = (freq + hz / 2) / hz;
curcpu()->ci_divisor_delay = ((freq + 500000) / 1000000);
if (mips_cpu_flags & CPU_MIPS_DOUBLE_COUNT) {
curcpu()->ci_cycles_per_hz /= 2;
curcpu()->ci_divisor_delay /= 2;
}
MIPS_SET_CI_RECIPRICAL(curcpu());
return ret;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: yamon.h,v 1.1 2002/03/07 14:44:02 simonb Exp $ */
/* $NetBSD: yamon.h,v 1.2 2003/10/27 23:41:42 simonb Exp $ */
/*
* Copyright 2002 Wasabi Systems, Inc.
@ -58,7 +58,8 @@
#define YAMON_FUNC(ofs) (*(uint32_t *)(MIPS_PHYS_TO_KSEG0(ofs)))
typedef void (*t_yamon_print_count)(uint32_t port, char *s, uint32_t count);
#define YAMON_PRINT_COUNT(s, count) ((t_yamon_print_count)(YAMON_FUNC(YAMON_PRINT_COUNT_OFS)))(0, s, count)
#define YAMON_PRINT_COUNT(s, count) \
((t_yamon_print_count)(YAMON_FUNC(YAMON_PRINT_COUNT_OFS)))(0, s, count)
typedef void (*t_yamon_exit)(uint32_t rc);
#define YAMON_EXIT(rc) ((t_yamon_exit)(YAMON_FUNC(YAMON_EXIT_OFS)))(rc)
@ -67,16 +68,28 @@ typedef void (*t_yamon_print)(uint32_t port, char *s);
#define YAMON_PRINT(s) ((t_yamon_print)(YAMON_FUNC(YAMON_PRINT_OFS)))(0, s)
typedef int (*t_yamon_getchar)(uint32_t port, char *ch);
#define YAMON_GETCHAR(ch) ((t_yamon_getchar)(YAMON_FUNC(YAMON_GETCHAR_OFS)))(0, ch)
#define YAMON_GETCHAR(ch) \
((t_yamon_getchar)(YAMON_FUNC(YAMON_GETCHAR_OFS)))(0, ch)
typedef int t_yamon_syscon_id;
typedef int (*t_yamon_syscon_read)(t_yamon_syscon_id id, void *param, uint32_t size);
#define YAMON_SYSCON_READ(id, param, size) \
((t_yamon_syscon_read)(YAMON_FUNC(YAMON_SYSCON_READ_OFS)))\
(id, param, size)
typedef struct {
char *name;
char *val;
} yamon_env_var;
#define SYSCON_BOARD_CPU_CLOCK_FREQ_ID 34 /* UINT32 */
#define SYSCON_BOARD_BUS_CLOCK_FREQ_ID 35 /* UINT32 */
#define SYSCON_BOARD_PCI_FREQ_KHZ_ID 36 /* UINT32 */
char *yamon_getenv(char *);
void yamon_print(char *);
void yamon_exit(uint32_t);
int yamon_setcpufreq(int);
extern yamon_env_var *yamon_envp;
extern struct consdev yamon_promcd;