diff --git a/kernel/Makefile b/kernel/Makefile index 10915d4c..63715c63 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -56,7 +56,6 @@ ifdef X86FAMILY $(CPUDIR)/syscall.o \ x86-family/cmos.o \ x86-family/time.o \ - x86-family/mtrr.o \ x86-family/pat.o \ x86-family/float.o \ x86-family/ps2.o \ diff --git a/kernel/include/sortix/kernel/mtrr.h b/kernel/include/sortix/kernel/mtrr.h deleted file mode 100644 index e68d3abc..00000000 --- a/kernel/include/sortix/kernel/mtrr.h +++ /dev/null @@ -1,47 +0,0 @@ -/******************************************************************************* - - Copyright(C) Jonas 'Sortie' Termansen 2013. - - This file is part of Sortix. - - Sortix is free software: you can redistribute it and/or modify it under the - terms of the GNU General Public License as published by the Free Software - Foundation, either version 3 of the License, or (at your option) any later - version. - - Sortix is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - details. - - You should have received a copy of the GNU General Public License along with - Sortix. If not, see . - - sortix/kernel/mtrr.h - Functions to manipulate Memory Type Range Registers. - -*******************************************************************************/ - -#ifndef INCLUDE_SORTIX_KERNEL_MTRR_H -#define INCLUDE_SORTIX_KERNEL_MTRR_H - -#include -#include - -#include - -namespace Sortix { - -#if defined(__i386__) || defined(__x86_64__) - -bool IsMTRRSupported(); -const char* SetupMTRRForWC(addr_t base, size_t size, int* ret = NULL); -void EnableMTRR(int mtrr); -void DisableMTRR(int mtrr); -void CopyMTRR(int dst, int src); - -#endif - -} // namespace Sortix - -#endif diff --git a/kernel/x86-family/mtrr.cpp b/kernel/x86-family/mtrr.cpp deleted file mode 100644 index df6062fe..00000000 --- a/kernel/x86-family/mtrr.cpp +++ /dev/null @@ -1,194 +0,0 @@ -/******************************************************************************* - - Copyright(C) Jonas 'Sortie' Termansen 2012, 2013. - Copyright(C) Free Software Foundation, Inc. 2005, 2006, 2007, 2008, 2009. - - This file is part of Sortix. - - Sortix is free software: you can redistribute it and/or modify it under the - terms of the GNU General Public License as published by the Free Software - Foundation, either version 3 of the License, or (at your option) any later - version. - - Sortix is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - details. - - You should have received a copy of the GNU General Public License along with - Sortix. If not, see . - - x86-family/mtrr.cpp - Functions to access and modify memory type range registers. This is in part - based on code from GNU GRUB. - -*******************************************************************************/ - -#include -#include - -#include -#include -#include - -namespace Sortix { - -const uint32_t bit_MTRR = 0x00001000U; - -bool IsMTRRSupported() -{ - if ( !IsCPUIdSupported() ) - return false; - uint32_t eax, ebx, ecx, edx; - cpuid(1, eax, ebx, ecx, edx); - uint32_t features = edx; - return features & bit_MTRR; -} - -#define mtrr_base(reg) (0x200 + (reg) * 2 + 0) -#define mtrr_mask(reg) (0x200 + (reg) * 2 + 1) - -static const uint64_t MTRR_MASK_VALID = 0x800; - -void EnableMTRR(int mtrr) -{ - wrmsr(mtrr_mask(mtrr), rdmsr(mtrr_mask(mtrr)) | MTRR_MASK_VALID); -} - -void DisableMTRR(int mtrr) -{ - wrmsr(mtrr_mask(mtrr), rdmsr(mtrr_mask(mtrr)) & ~MTRR_MASK_VALID); -} - -void CopyMTRR(int dst, int src) -{ - uint64_t base = rdmsr(mtrr_base(src)); - uint64_t mask = rdmsr(mtrr_mask(src)); - wrmsr(mtrr_base(dst), base); - wrmsr(mtrr_mask(dst), mask); -} - -// TODO: Yes, returning a string as an error and giving the result in a pointer -// is very bad design. Please fix this at some point. Also improve the code such -// that it is more flexible. -const char* SetupMTRRForWC(addr_t base, size_t size, int* ret) -{ - uint32_t eax, ebx, ecx, edx; - uint32_t mtrrcap; - int var_mtrrs; - uint32_t max_extended_cpuid; - uint32_t maxphyaddr; - uint64_t fb_base, fb_size; - uint64_t size_bits, fb_mask; - uint32_t bits_lo, bits_hi; - uint64_t bits; - int i, first_unused = -1; - uint32_t base_lo, base_hi, mask_lo, mask_hi; - - fb_base = (uint64_t) base; - fb_size = (uint64_t) size; - - // Check that fb_base and fb_size can be represented using a single MTRR. - - if ( fb_base < 1 << 20 ) - return "below 1MB, so covered by fixed-range MTRRs"; - if ( fb_base >= 1LL << 36 ) - return "over 36 bits, so out of range"; - if ( fb_size < 1 << 12 ) - return "variable-range MTRRs must cover at least 4KB"; - - size_bits = fb_size; - while ( size_bits > 1 ) - size_bits >>= 1; - if ( size_bits != 1 ) - return "not a power of two"; - - if ( fb_base & (fb_size - 1) ) - return "not aligned on size boundary"; - - fb_mask = ~(fb_size - 1); - - // Check CPU capabilities. - - if ( !IsCPUIdSupported() ) - return "cpuid not supported, therefore mtrr not supported"; - - if ( !IsMTRRSupported() ) - return "cpu does not support mtrr"; - - rdmsr_split(0xFE, &eax, &edx); - mtrrcap = eax; - if ( !(mtrrcap & 0x00000400) ) /* write-combining */ - return "write combining doesn't seem to be supported"; - var_mtrrs = mtrrcap & 0xFF; - - cpuid(0x80000000, eax, ebx, ecx, edx); - max_extended_cpuid = eax; - if ( max_extended_cpuid >= 0x80000008 ) - { - cpuid(0x80000008, eax, ebx, ecx, edx); - maxphyaddr = eax & 0xFF; - } - else - maxphyaddr = 36; - bits_lo = 0xFFFFF000; /* assume maxphyaddr >= 36 */ - bits_hi = (1 << (maxphyaddr - 32)) - 1; - bits = bits_lo | (uint64_t) bits_hi << 32; - - // Check whether an MTRR already covers this region. If not, take an unused - // one if possible. - for ( i = 0; i < var_mtrrs; i++ ) - { - rdmsr_split(mtrr_mask(i), &eax, &edx); - mask_lo = eax; - mask_hi = edx; - if ( mask_lo & MTRR_MASK_VALID ) - { - uint64_t real_base, real_mask; - - rdmsr_split(mtrr_base(i), &eax, &edx); - base_lo = eax; - base_hi = edx; - - real_base = (uint64_t) (base_hi & bits_hi) << 32 | - (base_lo & bits_lo); - real_mask = (uint64_t) (mask_hi & bits_hi) << 32 | - (mask_lo & bits_lo); - - if ( real_base < fb_base + fb_size && - real_base + (~real_mask & bits) >= fb_base ) - return "region already covered by another mtrr"; - } - else if ( first_unused < 0 ) - first_unused = i; - } - - if ( first_unused < 0 ) - return "all MTRRs in use"; - - // Set up the first unused MTRR we found. - rdmsr_split(mtrr_base(first_unused), &eax, &edx); - base_lo = eax; - base_hi = edx; - rdmsr_split(mtrr_mask(first_unused), &eax, &edx); - mask_lo = eax; - mask_hi = edx; - - base_lo = (base_lo & ~bits_lo & ~0xFF) | - (fb_base & bits_lo) | 0x01 /* WC */; - base_hi = (base_hi & ~bits_hi) | - ((fb_base >> 32) & bits_hi); - wrmsr_split(mtrr_base(first_unused), base_lo, base_hi); - mask_lo = (mask_lo & ~bits_lo) | - (fb_mask & bits_lo) | MTRR_MASK_VALID; - mask_hi = (mask_hi & ~bits_hi) | - ((fb_mask >> 32) & bits_hi); - wrmsr_split(mtrr_mask(first_unused), mask_lo, mask_hi); - - if ( ret ) - *ret = first_unused; - - return NULL; -} - -} // namespace Sortix