1/**
2 * \file
3 * \brief x86 debug registers
4 */
5
6/*
7 * Copyright (c) 2007, 2008, 2009, 2010, ETH Zurich.
8 * All rights reserved.
9 *
10 * This file is distributed under the terms in the attached LICENSE file.
11 * If you do not find this file, copies can be found by writing to:
12 * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
13 */
14
15#include <kernel.h>
16#include <arch/x86/debugregs.h>
17
18void debugregs_set_breakpoint(uintptr_t addr, uint8_t mode, uint8_t len)
19{
20    uintptr_t dr7 = 0;
21
22    // Enable breakpoint 0 and make it global
23    dr7 |= 3;
24
25    // Require exact breakpoints (even if not supported - suggested by Intel
26    // Software Developer's Manual Vol. 3A)
27    dr7 |= 3 << 8;
28
29    // Set mode and length
30    dr7 |= (mode & 3) << 16;
31    dr7 |= (len & 3) << 18;
32
33    // Needs to be aligned on multi-byte breakpoint
34    switch(len) {
35    case 1:
36        assert(addr % 2 == 0);
37        break;
38    case 3:
39        assert(addr % 4 == 0);
40        break;
41    }
42
43    // Set the breakpoint address
44    __asm volatile ("mov %[addr], %%dr0" :: [addr] "r" (addr));
45
46    // Set status (this enables the breakpoint)
47    __asm volatile ("mov %[dr7], %%dr7" :: [dr7] "r" (dr7));
48}
49