Allow the cacheline size on PowerPC to be set at runtime. This is essential for

supporting 64-bit CPUs, which often have 128-byte cache lines instead of the
standard 32.
This commit is contained in:
Nathan Whitehorn 2008-09-24 00:28:46 +00:00
parent 6b41097822
commit 4c01c0b965
5 changed files with 36 additions and 62 deletions

View file

@ -1,4 +1,4 @@
/*
/*-
* Copyright (C) 1995-1997, 1999 Wolfgang Solfrank.
* Copyright (C) 1995-1997, 1999 TooLs GmbH.
* All rights reserved.
@ -47,28 +47,25 @@ static const char rcsid[] =
#include <machine/cpu.h>
#include <machine/md_var.h>
#if defined(_KERNEL) || defined(_STANDALONE)
#ifndef CACHELINESIZE
#error "Must know the size of a cache line"
#ifndef _KERNEL
int cacheline_size = 32;
#endif
#else
#if !defined(_KERNEL) && !defined(_STANDALONE)
#include <stdlib.h>
static void getcachelinesize(void);
static int _cachelinesize;
#define CACHELINESIZE _cachelinesize
static void
getcachelinesize()
{
static int cachemib[] = { CTL_MACHDEP, CPU_CACHELINE };
int clen;
clen = sizeof(_cachelinesize);
clen = sizeof(cacheline_size);
if (sysctl(cachemib, sizeof(cachemib) / sizeof(cachemib[0]),
&_cachelinesize, &clen, NULL, 0) < 0 || !_cachelinesize) {
&cacheline_size, &clen, NULL, 0) < 0 || !cacheline_size) {
abort();
}
}
@ -81,21 +78,24 @@ __syncicache(void *from, int len)
char *p;
#if !defined(_KERNEL) && !defined(_STANDALONE)
if (!_cachelinesize)
if (!cacheline_size)
getcachelinesize();
#endif
off = (u_int)from & (CACHELINESIZE - 1);
off = (u_int)from & (cacheline_size - 1);
l = len += off;
p = (char *)from - off;
do {
__asm __volatile ("dcbst 0,%0" :: "r"(p));
p += CACHELINESIZE;
} while ((l -= CACHELINESIZE) > 0);
p += cacheline_size;
} while ((l -= cacheline_size) > 0);
__asm __volatile ("sync");
p = (char *)from - off;
do {
__asm __volatile ("icbi 0,%0" :: "r"(p));
p += CACHELINESIZE;
} while ((len -= CACHELINESIZE) > 0);
p += cacheline_size;
} while ((len -= cacheline_size) > 0);
__asm __volatile ("sync; isync");
}

View file

@ -128,6 +128,7 @@ extern vm_offset_t ksym_start, ksym_end;
#endif
int cold = 1;
int cacheline_size = 32;
struct pcpu __pcpu[MAXCPU];
@ -136,13 +137,12 @@ static struct trapframe frame0;
char machine[] = "powerpc";
SYSCTL_STRING(_hw, HW_MACHINE, machine, CTLFLAG_RD, machine, 0, "");
static int cacheline_size = CACHELINESIZE;
SYSCTL_INT(_machdep, CPU_CACHELINE, cacheline_size,
CTLFLAG_RD, &cacheline_size, 0, "");
static void cpu_startup(void *);
SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_startup, NULL);
SYSCTL_INT(_machdep, CPU_CACHELINE, cacheline_size,
CTLFLAG_RD, &cacheline_size, 0, "");
u_int powerpc_init(u_int, u_int, u_int, void *);
int save_ofw_mapping(void);

View file

@ -171,9 +171,10 @@ struct bootinfo *bootinfo;
char machine[] = "powerpc";
SYSCTL_STRING(_hw, HW_MACHINE, machine, CTLFLAG_RD, machine, 0, "");
static int cacheline_size = CACHELINESIZE;
int cacheline_size = 32;
SYSCTL_INT(_machdep, CPU_CACHELINE, cacheline_size,
CTLFLAG_RD, &cacheline_size, 0, "");
CTLFLAG_RD, &cacheline_size, 0, "");
static void cpu_e500_startup(void *);
SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_e500_startup, NULL);

View file

@ -45,10 +45,7 @@ extern vm_offset_t kstack0_phys;
extern u_long ns_per_tick;
extern int powerpc_pow_enabled;
#if defined(_KERNEL) || defined(_STANDALONE)
#define CACHELINESIZE 32
#endif
extern int cacheline_size;
void __syncicache(void *, int);

View file

@ -31,8 +31,10 @@
* $NetBSD: syncicache.c,v 1.2 1999/05/05 12:36:40 tsubai Exp $
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#ifndef lint
static const char rcsid[] =
"$FreeBSD$";
#endif /* not lint */
#include <sys/param.h>
#if defined(_KERNEL) || defined(_STANDALONE)
@ -42,55 +44,29 @@ __FBSDID("$FreeBSD$");
#endif
#include <sys/sysctl.h>
#include <machine/cpu.h>
#include <machine/md_var.h>
#if defined(_KERNEL) || defined(_STANDALONE)
#ifndef CACHELINESIZE
#error "Must know the size of a cache line"
#endif
#else
static void getcachelinesize(void);
static int _cachelinesize;
#define CACHELINESIZE _cachelinesize
static void
getcachelinesize()
{
static int cachemib[] = { CTL_MACHDEP, CPU_CACHELINE };
int clen;
clen = sizeof(_cachelinesize);
if (sysctl(cachemib, sizeof(cachemib) / sizeof(cachemib[0]),
&_cachelinesize, &clen, NULL, 0) < 0 || !_cachelinesize) {
abort();
}
}
#endif
void
__syncicache(void *from, int len)
{
int l, off;
char *p;
#if !defined(_KERNEL) && !defined(_STANDALONE)
if (!_cachelinesize)
getcachelinesize();
#endif
off = (u_int)from & (CACHELINESIZE - 1);
off = (u_int)from & (cacheline_size - 1);
l = len += off;
p = (char *)from - off;
do {
__asm __volatile ("dcbst 0,%0" :: "r"(p));
p += CACHELINESIZE;
} while ((l -= CACHELINESIZE) > 0);
p += cacheline_size;
} while ((l -= cacheline_size) > 0);
__asm __volatile ("sync");
p = (char *)from - off;
do {
__asm __volatile ("icbi 0,%0" :: "r"(p));
p += CACHELINESIZE;
} while ((len -= CACHELINESIZE) > 0);
p += cacheline_size;
} while ((len -= cacheline_size) > 0);
__asm __volatile ("sync; isync");
}