diff --git a/arch/x86/mtrr.c b/arch/x86/mtrr.c new file mode 100644 index 00000000..81cb7f0a --- /dev/null +++ b/arch/x86/mtrr.c @@ -0,0 +1,57 @@ +/* + * Copyright © 2022 Amazon.com, Inc. or its affiliates. + * All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include + +mtrr_cap_t mtrr_read_cap(void) { + mtrr_cap_t c; + c.reg = rdmsr(MSR_MTRR_CAP); + return c; +} + +mtrr_def_type_t mtrr_read_def_type(void) { + mtrr_def_type_t t; + t.reg = rdmsr(MSR_MTRR_DEF_TYPE); + return t; +} + +bool mtrr_set_phys_base(mtrr_base_t base, uint8_t reg) { + mtrr_cap_t cap = mtrr_read_cap(); + if (reg < cap.vcnt) { + wrmsr(MSR_MTRR_PHYS_BASE(reg), base.reg); + return true; + } + return false; +} + +bool mtrr_set_phys_mask(mtrr_mask_t mask, uint8_t reg) { + mtrr_cap_t cap = mtrr_read_cap(); + if (reg < cap.vcnt) { + wrmsr(MSR_MTRR_PHYS_MASK(reg), mask.reg); + return true; + } + return false; +} diff --git a/include/arch/x86/processor.h b/include/arch/x86/processor.h index 86096c10..b9a41535 100644 --- a/include/arch/x86/processor.h +++ b/include/arch/x86/processor.h @@ -93,6 +93,24 @@ */ #define MSR_PAT 0x277 +#define MSR_MTRR_FIX_64K_00000 0x250 +#define MSR_MTRR_FIX_16K_80000 0x258 +#define MSR_MTRR_FIX_16K_A0000 0x259 +#define MSR_MTRR_FIX_4K_C0000 0x268 +#define MSR_MTRR_FIX_4K_C8000 0x269 +#define MSR_MTRR_FIX_4K_D0000 0x26A +#define MSR_MTRR_FIX_4K_D8000 0x26B +#define MSR_MTRR_FIX_4K_E0000 0x26C +#define MSR_MTRR_FIX_4K_E8000 0x26D +#define MSR_MTRR_FIX_4K_F0000 0x26E +#define MSR_MTRR_FIX_4K_F8000 0x26F + +#define MSR_MTRR_CAP 0x2FF +#define MSR_MTRR_DEF_TYPE 0x2FF + +#define MSR_MTRR_PHYS_BASE(n) (0x200 + (n * 2)) +#define MSR_MTRR_PHYS_MASK(n) (0x201 + (n * 2)) + #define MSR_APIC_BASE 0x0000001B #define MSR_EFER 0xc0000080 /* Extended Feature Enable Register */ diff --git a/include/mtrr.h b/include/mtrr.h new file mode 100644 index 00000000..7a24c56b --- /dev/null +++ b/include/mtrr.h @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2022 Amazon.com, Inc. or its affiliates. + * All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef KTF_MTRR_H +#define KTF_MTRR_H + +#include + +enum mtrr_memory_type { + MTRR_UC = 0, /* Uncacheable */ + MTRR_WC = 1, /* Write Combining */ + MTRR_WT = 4, /* Write Through */ + MTRR_WP, /* Write Protected */ + MTRR_WB, /* Write Back */ +}; +typedef enum mtrr_memory_type mtrr_memory_type_t; + +union mtrr_cap { + struct { + /* clang-format off */ + uint64_t vcnt : 8, + fix : 1, + _rsvd : 1, + wc : 1, + _rsvd2 : 53; + /* clang-format on */ + } __packed; + uint64_t reg; +}; +typedef union mtrr_cap mtrr_cap_t; + +union mtrr_def_type { + struct { + /* clang-format off */ + uint64_t type : 8, + _rsvd : 2, + fe : 1, + e : 1, + _rsvd2 : 52; + /* clang-format on */ + } __packed; + uint64_t reg; +}; +typedef union mtrr_def_type mtrr_def_type_t; + +union mtrr_base { + struct { + /* clang-format off */ + uint64_t type : 8, + _rsvd : 4, + phys_base : 40, + _rsvd2 : 12; + /* clang-format on */ + } __packed; + uint64_t reg; +}; +typedef union mtrr_base mtrr_base_t; + +union mtrr_mask { + struct { + /* clang-format off */ + uint64_t _rsvd : 10, + valid : 1, + phys_base : 40, + _rsvd2 : 13; + /* clang-format on */ + } __packed; + uint64_t reg; +}; +typedef union mtrr_mask mtrr_mask_t; + +extern mtrr_cap_t mtrr_read_cap(void); +extern mtrr_def_type_t mtrr_read_def_type(void); +extern bool mtrr_set_phys_base(mtrr_base_t base, uint8_t reg); +extern bool mtrr_set_phys_mask(mtrr_mask_t mask, uint8_t reg); + +#endif /* KTF_MTRR_H */