]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - arch/x86/cpu/mtrr.c
Merge branch 'master' of git://git.denx.de/u-boot-ti
[karo-tx-uboot.git] / arch / x86 / cpu / mtrr.c
1 /*
2  * (C) Copyright 2014 Google, Inc
3  *
4  * SPDX-License-Identifier:     GPL-2.0+
5  *
6  * Memory Type Range Regsters - these are used to tell the CPU whether
7  * memory is cacheable and if so the cache write mode to use.
8  *
9  * These can speed up booting. See the mtrr command.
10  *
11  * Reference: Intel Architecture Software Developer's Manual, Volume 3:
12  * System Programming
13  */
14
15 #include <common.h>
16 #include <asm/io.h>
17 #include <asm/msr.h>
18 #include <asm/mtrr.h>
19
20 /* Prepare to adjust MTRRs */
21 void mtrr_open(struct mtrr_state *state)
22 {
23         state->enable_cache = dcache_status();
24
25         if (state->enable_cache)
26                 disable_caches();
27         state->deftype = native_read_msr(MTRR_DEF_TYPE_MSR);
28         wrmsrl(MTRR_DEF_TYPE_MSR, state->deftype & ~MTRR_DEF_TYPE_EN);
29 }
30
31 /* Clean up after adjusting MTRRs, and enable them */
32 void mtrr_close(struct mtrr_state *state)
33 {
34         wrmsrl(MTRR_DEF_TYPE_MSR, state->deftype | MTRR_DEF_TYPE_EN);
35         if (state->enable_cache)
36                 enable_caches();
37 }
38
39 int mtrr_commit(bool do_caches)
40 {
41         struct mtrr_request *req = gd->arch.mtrr_req;
42         struct mtrr_state state;
43         uint64_t mask;
44         int i;
45
46         mtrr_open(&state);
47         for (i = 0; i < gd->arch.mtrr_req_count; i++, req++) {
48                 mask = ~(req->size - 1);
49                 mask &= (1ULL << CONFIG_CPU_ADDR_BITS) - 1;
50                 wrmsrl(MTRR_PHYS_BASE_MSR(i), req->start | req->type);
51                 wrmsrl(MTRR_PHYS_MASK_MSR(i), mask | MTRR_PHYS_MASK_VALID);
52         }
53
54         /* Clear the ones that are unused */
55         for (; i < MTRR_COUNT; i++)
56                 wrmsrl(MTRR_PHYS_MASK_MSR(i), 0);
57         mtrr_close(&state);
58
59         return 0;
60 }
61
62 int mtrr_add_request(int type, uint64_t start, uint64_t size)
63 {
64         struct mtrr_request *req;
65         uint64_t mask;
66
67         if (gd->arch.mtrr_req_count == MAX_MTRR_REQUESTS)
68                 return -ENOSPC;
69         req = &gd->arch.mtrr_req[gd->arch.mtrr_req_count++];
70         req->type = type;
71         req->start = start;
72         req->size = size;
73         debug("%d: type=%d, %08llx  %08llx\n", gd->arch.mtrr_req_count - 1,
74               req->type, req->start, req->size);
75         mask = ~(req->size - 1);
76         mask &= (1ULL << CONFIG_CPU_ADDR_BITS) - 1;
77         mask |= MTRR_PHYS_MASK_VALID;
78         debug("   %016llx %016llx\n", req->start | req->type, mask);
79
80         return 0;
81 }