1 // SPDX-License-Identifier: GPL-2.0
2 #include <linux/init.h>
15 static u8 centaur_mcr_reserved
;
16 static u8 centaur_mcr_type
; /* 0 for winchip, 1 for winchip2 */
19 * centaur_get_free_region - Get a free MTRR.
21 * @base: The starting (base) address of the region.
22 * @size: The size (in bytes) of the region.
24 * Returns: the index of the region on success, else -1 on error.
27 centaur_get_free_region(unsigned long base
, unsigned long size
, int replace_reg
)
29 unsigned long lbase
, lsize
;
34 if (replace_reg
>= 0 && replace_reg
< max
)
37 for (i
= 0; i
< max
; ++i
) {
38 if (centaur_mcr_reserved
& (1 << i
))
40 mtrr_if
->get(i
, &lbase
, &lsize
, <ype
);
49 * Report boot time MCR setups
51 void mtrr_centaur_report_mcr(int mcr
, u32 lo
, u32 hi
)
53 centaur_mcr
[mcr
].low
= lo
;
54 centaur_mcr
[mcr
].high
= hi
;
58 centaur_get_mcr(unsigned int reg
, unsigned long *base
,
59 unsigned long *size
, mtrr_type
* type
)
61 *base
= centaur_mcr
[reg
].high
>> PAGE_SHIFT
;
62 *size
= -(centaur_mcr
[reg
].low
& 0xfffff000) >> PAGE_SHIFT
;
63 *type
= MTRR_TYPE_WRCOMB
; /* write-combining */
65 if (centaur_mcr_type
== 1 && ((centaur_mcr
[reg
].low
& 31) & 2))
66 *type
= MTRR_TYPE_UNCACHABLE
;
67 if (centaur_mcr_type
== 1 && (centaur_mcr
[reg
].low
& 31) == 25)
68 *type
= MTRR_TYPE_WRBACK
;
69 if (centaur_mcr_type
== 0 && (centaur_mcr
[reg
].low
& 31) == 31)
70 *type
= MTRR_TYPE_WRBACK
;
74 centaur_set_mcr(unsigned int reg
, unsigned long base
,
75 unsigned long size
, mtrr_type type
)
77 unsigned long low
, high
;
83 high
= base
<< PAGE_SHIFT
;
84 if (centaur_mcr_type
== 0) {
85 /* Only support write-combining... */
86 low
= -size
<< PAGE_SHIFT
| 0x1f;
88 if (type
== MTRR_TYPE_UNCACHABLE
)
89 low
= -size
<< PAGE_SHIFT
| 0x02; /* NC */
91 low
= -size
<< PAGE_SHIFT
| 0x09; /* WWO, WC */
94 centaur_mcr
[reg
].high
= high
;
95 centaur_mcr
[reg
].low
= low
;
96 wrmsr(MSR_IDT_MCR0
+ reg
, low
, high
);
100 centaur_validate_add_page(unsigned long base
, unsigned long size
, unsigned int type
)
103 * FIXME: Winchip2 supports uncached
105 if (type
!= MTRR_TYPE_WRCOMB
&&
106 (centaur_mcr_type
== 0 || type
!= MTRR_TYPE_UNCACHABLE
)) {
107 pr_warn("mtrr: only write-combining%s supported\n",
108 centaur_mcr_type
? " and uncacheable are" : " is");
114 static const struct mtrr_ops centaur_mtrr_ops
= {
115 .vendor
= X86_VENDOR_CENTAUR
,
116 .set
= centaur_set_mcr
,
117 .get
= centaur_get_mcr
,
118 .get_free_region
= centaur_get_free_region
,
119 .validate_add_page
= centaur_validate_add_page
,
120 .have_wrcomb
= positive_have_wrcomb
,
123 int __init
centaur_init_mtrr(void)
125 set_mtrr_ops(¢aur_mtrr_ops
);