NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
re: port-amd64/38480
this lame patch makes this problem go away for me, but it only papers over
the general problem, and works for MTRR VCNT < 8 case that now exists in
the real hardware.
i haven't tested this on real intel hardware (i don't have any that don't
have this problem i can easily reboot) so it would be great if someone
else tested this patch on an older intel cpu (i686-class, please :-)
andy, OK to commit this given it works? this PR can be decreased in
priority and i686_mtrr.c will need more work for >8 VCNT to properly
close it, but for now this lets my system actually work.
.mrg.
Index: include/mtrr.h
===================================================================
RCS file: /cvsroot/src/sys/arch/x86/include/mtrr.h,v
retrieving revision 1.3
diff -p -r1.3 mtrr.h
*** include/mtrr.h 28 Apr 2008 20:23:40 -0000 1.3
--- include/mtrr.h 29 Jun 2008 19:53:43 -0000
***************
*** 36,42 ****
#define MTRR_I686_FIXED_IDX16K 1
#define MTRR_I686_FIXED_IDX4K 3
! #define MTRR_I686_NVAR 8
#define MTRR_I686_64K_START 0x00000
#define MTRR_I686_16K_START 0x80000
--- 36,42 ----
#define MTRR_I686_FIXED_IDX16K 1
#define MTRR_I686_FIXED_IDX4K 3
! #define MTRR_I686_NVAR_MAX 8 /* could be upto 255? */
#define MTRR_I686_64K_START 0x00000
#define MTRR_I686_16K_START 0x80000
Index: x86/mtrr_i686.c
===================================================================
RCS file: /cvsroot/src/sys/arch/x86/x86/mtrr_i686.c,v
retrieving revision 1.17
diff -p -r1.17 mtrr_i686.c
*** x86/mtrr_i686.c 12 May 2008 14:41:07 -0000 1.17
--- x86/mtrr_i686.c 29 Jun 2008 19:53:43 -0000
*************** mtrr_raw[] = {
*** 96,104 ****
--- 96,106 ----
{ MSR_MTRRfix4K_F0000, 0 },
{ MSR_MTRRfix4K_F8000, 0 },
{ MSR_MTRRdefType, 0 },
+
};
static const int nmtrr_raw = sizeof(mtrr_raw)/sizeof(mtrr_raw[0]);
+ static int i686_mtrr_vcnt = 0;
static struct mtrr_state *mtrr_var_raw;
static struct mtrr_state *mtrr_fixed_raw;
*************** i686_mtrr_reload(int synch)
*** 229,234 ****
--- 231,238 ----
for (i = 0; i < nmtrr_raw; i++) {
uint64_t val = mtrr_raw[i].msrval;
uint32_t addr = mtrr_raw[i].msraddr;
+ if (addr == 0)
+ continue;
if (addr == MSR_MTRRdefType)
val &= ~MTRR_I686_ENABLE_MASK;
wrmsr(addr, val);
*************** i686_mtrr_init_first(void)
*** 294,302 ****
{
int i;
- for (i = 0; i < nmtrr_raw; i++)
- mtrr_raw[i].msrval = rdmsr(mtrr_raw[i].msraddr);
i686_mtrr_cap = rdmsr(MSR_MTRRcap);
#if 0
mtrr_dump("init mtrr");
#endif
--- 298,320 ----
{
int i;
i686_mtrr_cap = rdmsr(MSR_MTRRcap);
+ i686_mtrr_vcnt = i686_mtrr_cap & MTRR_I686_CAP_VCNT_MASK;
+
+ if (i686_mtrr_vcnt > MTRR_I686_NVAR_MAX)
+ printf("\%s: FIXME: more than 8 mtrr's\n", __FILE__);
+ else if (i686_mtrr_vcnt < MTRR_I686_NVAR_MAX) {
+ for (i = MTRR_I686_NVAR_MAX - i686_mtrr_vcnt; i; i--) {
+ mtrr_raw[16 - (i*2)].msraddr = 0;
+ mtrr_raw[17 - (i*2)].msraddr = 0;
+ }
+ }
+
+ for (i = 0; i < nmtrr_raw; i++)
+ if (mtrr_raw[i].msraddr)
+ mtrr_raw[i].msrval = rdmsr(mtrr_raw[i].msraddr);
+ else
+ mtrr_raw[i].msrval = 0;
#if 0
mtrr_dump("init mtrr");
#endif
*************** i686_mtrr_init_first(void)
*** 308,319 ****
panic("can't allocate fixed MTRR array");
mtrr_var = (struct mtrr *)
! malloc(MTRR_I686_NVAR * sizeof (struct mtrr), M_TEMP, M_NOWAIT);
if (mtrr_var == NULL)
panic("can't allocate variable MTRR array");
mtrr_var_raw = &mtrr_raw[0];
! mtrr_fixed_raw = &mtrr_raw[MTRR_I686_NVAR * 2];
mtrr_funcs = &i686_mtrr_funcs;
i686_raw2soft();
--- 326,337 ----
panic("can't allocate fixed MTRR array");
mtrr_var = (struct mtrr *)
! malloc(i686_mtrr_vcnt * sizeof (struct mtrr), M_TEMP, M_NOWAIT);
if (mtrr_var == NULL)
panic("can't allocate variable MTRR array");
mtrr_var_raw = &mtrr_raw[0];
! mtrr_fixed_raw = &mtrr_raw[MTRR_I686_NVAR_MAX * 2];
mtrr_funcs = &i686_mtrr_funcs;
i686_raw2soft();
*************** i686_raw2soft(void)
*** 326,332 ****
struct mtrr *mtrrp;
uint64_t base, mask;
! for (i = 0; i < MTRR_I686_NVAR; i++) {
mtrrp = &mtrr_var[i];
memset(mtrrp, 0, sizeof *mtrrp);
mask = mtrr_var_raw[i * 2 + 1].msrval;
--- 344,350 ----
struct mtrr *mtrrp;
uint64_t base, mask;
! for (i = 0; i < i686_mtrr_vcnt; i++) {
mtrrp = &mtrr_var[i];
memset(mtrrp, 0, sizeof *mtrrp);
mask = mtrr_var_raw[i * 2 + 1].msrval;
*************** i686_soft2raw(void)
*** 391,397 ****
uint64_t val;
struct mtrr *mtrrp;
! for (i = 0; i < MTRR_I686_NVAR; i++) {
mtrrp = &mtrr_var[i];
mtrr_var_raw[i * 2].msrval = mtrr_base_value(mtrrp);
mtrr_var_raw[i * 2 + 1].msrval = mtrr_mask_value(mtrrp);
--- 409,415 ----
uint64_t val;
struct mtrr *mtrrp;
! for (i = 0; i < i686_mtrr_vcnt; i++) {
mtrrp = &mtrr_var[i];
mtrr_var_raw[i * 2].msrval = mtrr_base_value(mtrrp);
mtrr_var_raw[i * 2 + 1].msrval = mtrr_mask_value(mtrrp);
*************** i686_mtrr_setone(struct mtrr *mtrrp, str
*** 588,594 ****
low = mtrrp->base;
high = low + mtrrp->len;
freep = NULL;
! for (i = 0; i < MTRR_I686_NVAR; i++) {
if (!(mtrr_var[i].flags & MTRR_VALID)) {
freep = &mtrr_var[i];
continue;
--- 606,612 ----
low = mtrrp->base;
high = low + mtrrp->len;
freep = NULL;
! for (i = 0; i < i686_mtrr_vcnt; i++) {
if (!(mtrr_var[i].flags & MTRR_VALID)) {
freep = &mtrr_var[i];
continue;
*************** i686_mtrr_clean(struct proc *p)
*** 631,637 ****
mtrr_fixed[i].flags &= ~MTRR_PRIVATE;
}
! for (i = 0; i < MTRR_I686_NVAR; i++) {
if ((mtrr_var[i].flags & MTRR_PRIVATE) &&
(mtrr_var[i].owner == p->p_pid))
mtrr_var[i].flags &= ~(MTRR_PRIVATE | MTRR_VALID);
--- 649,655 ----
mtrr_fixed[i].flags &= ~MTRR_PRIVATE;
}
! for (i = 0; i < i686_mtrr_vcnt; i++) {
if ((mtrr_var[i].flags & MTRR_PRIVATE) &&
(mtrr_var[i].owner == p->p_pid))
mtrr_var[i].flags &= ~(MTRR_PRIVATE | MTRR_VALID);
*************** i686_mtrr_set(struct mtrr *mtrrp, int *n
*** 646,652 ****
int i, error;
struct mtrr mtrr;
! if (*n > (MTRR_I686_NFIXED_SOFT + MTRR_I686_NVAR)) {
*n = 0;
return EINVAL;
}
--- 664,670 ----
int i, error;
struct mtrr mtrr;
! if (*n > (MTRR_I686_NFIXED_SOFT + MTRR_I686_NVAR_MAX)) {
*n = 0;
return EINVAL;
}
*************** i686_mtrr_get(struct mtrr *mtrrp, int *n
*** 678,684 ****
int idx, i, error;
if (mtrrp == NULL) {
! *n = MTRR_I686_NFIXED_SOFT + MTRR_I686_NVAR;
return 0;
}
--- 696,702 ----
int idx, i, error;
if (mtrrp == NULL) {
! *n = MTRR_I686_NFIXED_SOFT + MTRR_I686_NVAR_MAX;
return 0;
}
*************** i686_mtrr_get(struct mtrr *mtrrp, int *n
*** 698,704 ****
return error;
}
! for (i = 0; i < MTRR_I686_NVAR && idx < *n; idx++, i++) {
if (flags & MTRR_GETSET_USER) {
error = copyout(&mtrr_var[i], &mtrrp[idx],
sizeof *mtrrp);
--- 716,722 ----
return error;
}
! for (i = 0; i < i686_mtrr_vcnt && idx < *n; idx++, i++) {
if (flags & MTRR_GETSET_USER) {
error = copyout(&mtrr_var[i], &mtrrp[idx],
sizeof *mtrrp);
Home |
Main Index |
Thread Index |
Old Index