1 /* SPDX-License-Identifier: GPL-2.0+ */
2 /*
3  * Copyright (c) 2012 The Chromium OS Authors.
4  *
5  * (C) Copyright 2008-2011
6  * Graeme Russ, <graeme.russ@gmail.com>
7  *
8  * (C) Copyright 2002
9  * Daniel Engström, Omicron Ceti AB, <daniel@omicron.se>
10  *
11  * Portions of this file are derived from the Linux kernel source
12  *  Copyright (C) 1991, 1992  Linus Torvalds
13  */
14 
15 #ifndef __X86_CONTROL_REGS_H
16 #define __X86_CONTROL_REGS_H
17 
18 /*
19  * The memory clobber prevents the GCC from reordering the read/write order
20  * of CR0
21 */
22 static inline unsigned long read_cr0(void)
23 {
24 	unsigned long val;
25 
26 	asm volatile ("movl %%cr0, %0" : "=r" (val) : : "memory");
27 	return val;
28 }
29 
30 static inline void write_cr0(unsigned long val)
31 {
32 	asm volatile ("movl %0, %%cr0" : : "r" (val) : "memory");
33 }
34 
35 static inline unsigned long read_cr2(void)
36 {
37 	unsigned long val;
38 
39 	asm volatile("mov %%cr2,%0\n\t" : "=r" (val) : : "memory");
40 	return val;
41 }
42 
43 static inline unsigned long read_cr3(void)
44 {
45 	unsigned long val;
46 
47 	asm volatile("mov %%cr3,%0\n\t" : "=r" (val) : : "memory");
48 	return val;
49 }
50 
51 static inline unsigned long read_cr4(void)
52 {
53 	unsigned long val;
54 
55 	asm volatile("mov %%cr4,%0\n\t" : "=r" (val) : : "memory");
56 	return val;
57 }
58 
59 static inline unsigned long get_debugreg(int regno)
60 {
61 	unsigned long val = 0;  /* Damn you, gcc! */
62 
63 	switch (regno) {
64 	case 0:
65 		asm("mov %%db0, %0" : "=r" (val));
66 		break;
67 	case 1:
68 		asm("mov %%db1, %0" : "=r" (val));
69 		break;
70 	case 2:
71 		asm("mov %%db2, %0" : "=r" (val));
72 		break;
73 	case 3:
74 		asm("mov %%db3, %0" : "=r" (val));
75 		break;
76 	case 6:
77 		asm("mov %%db6, %0" : "=r" (val));
78 		break;
79 	case 7:
80 		asm("mov %%db7, %0" : "=r" (val));
81 		break;
82 	default:
83 		val = 0;
84 	}
85 	return val;
86 }
87 
88 #endif
89