1139731Simp/*-
24Srgrimes * Mach Operating System
34Srgrimes * Copyright (c) 1991,1990 Carnegie Mellon University
44Srgrimes * All Rights Reserved.
58876Srgrimes *
64Srgrimes * Permission to use, copy, modify and distribute this software and its
74Srgrimes * documentation is hereby granted, provided that both the copyright
84Srgrimes * notice and this permission notice appear in all copies of the
94Srgrimes * software, derivative works or modified versions, and any portions
104Srgrimes * thereof, and that both notices appear in supporting documentation.
118876Srgrimes *
128876Srgrimes * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
134Srgrimes * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
144Srgrimes * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
158876Srgrimes *
164Srgrimes * Carnegie Mellon requests users of this software to return to
178876Srgrimes *
184Srgrimes *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
194Srgrimes *  School of Computer Science
204Srgrimes *  Carnegie Mellon University
214Srgrimes *  Pittsburgh PA 15213-3890
228876Srgrimes *
234Srgrimes * any improvements or extensions that they make and grant Carnegie the
244Srgrimes * rights to redistribute these changes.
254Srgrimes */
264Srgrimes
27118031Sobrien#include <sys/cdefs.h>
28118031Sobrien__FBSDID("$FreeBSD: releng/10.3/sys/amd64/amd64/db_interface.c 208392 2010-05-21 17:17:56Z jhb $");
29118031Sobrien
304Srgrimes/*
314Srgrimes * Interface to new debugger.
324Srgrimes */
332056Swollman#include <sys/param.h>
342056Swollman#include <sys/systm.h>
35131952Smarcel#include <sys/kdb.h>
3649558Sphk#include <sys/cons.h>
3776440Sjhb#include <sys/pcpu.h>
3875274Sjhb#include <sys/proc.h>
395588Sbde
4030789Sbde#include <machine/cpu.h>
415588Sbde
4212662Sdg#include <vm/vm.h>
434Srgrimes#include <vm/pmap.h>
444Srgrimes
4512662Sdg#include <ddb/ddb.h>
4624345Sbde
474Srgrimes/*
48131952Smarcel * Read bytes from kernel address space for debugger.
494Srgrimes */
50798Swollmanint
51131952Smarceldb_read_bytes(vm_offset_t addr, size_t size, char *data)
524Srgrimes{
53131952Smarcel	jmp_buf jb;
54131952Smarcel	void *prev_jb;
55131952Smarcel	char *src;
56131952Smarcel	int ret;
574Srgrimes
58131952Smarcel	prev_jb = kdb_jmpbuf(jb);
59131952Smarcel	ret = setjmp(jb);
60131952Smarcel	if (ret == 0) {
61131952Smarcel		src = (char *)addr;
62131952Smarcel		while (size-- > 0)
63131952Smarcel			*data++ = *src++;
6412356Sbde	}
65131952Smarcel	(void)kdb_jmpbuf(prev_jb);
66131952Smarcel	return (ret);
674Srgrimes}
684Srgrimes
694Srgrimes/*
704Srgrimes * Write bytes to kernel address space for debugger.
714Srgrimes */
72131952Smarcelint
73103753Smarkmdb_write_bytes(vm_offset_t addr, size_t size, char *data)
744Srgrimes{
75131952Smarcel	jmp_buf jb;
76131952Smarcel	void *prev_jb;
77131952Smarcel	char *dst;
78111271Sjake	pt_entry_t	*ptep0 = NULL;
79111271Sjake	pt_entry_t	oldmap0 = 0;
804Srgrimes	vm_offset_t	addr1;
81111271Sjake	pt_entry_t	*ptep1 = NULL;
82111271Sjake	pt_entry_t	oldmap1 = 0;
83131952Smarcel	int ret;
844Srgrimes
85131952Smarcel	prev_jb = kdb_jmpbuf(jb);
86131952Smarcel	ret = setjmp(jb);
87131952Smarcel	if (ret == 0) {
88131952Smarcel		if (addr > trunc_page((vm_offset_t)btext) - size &&
89131952Smarcel		    addr < round_page((vm_offset_t)etext)) {
904Srgrimes
91131952Smarcel			ptep0 = vtopte(addr);
92131952Smarcel			oldmap0 = *ptep0;
93131952Smarcel			*ptep0 |= PG_RW;
9417865Spst
95131952Smarcel			/*
96131952Smarcel			 * Map another page if the data crosses a page
97131952Smarcel			 * boundary.
98131952Smarcel			 */
99131952Smarcel			if ((*ptep0 & PG_PS) == 0) {
100131952Smarcel				addr1 = trunc_page(addr + size - 1);
101131952Smarcel				if (trunc_page(addr) != addr1) {
102131952Smarcel					ptep1 = vtopte(addr1);
103131952Smarcel					oldmap1 = *ptep1;
104131952Smarcel					*ptep1 |= PG_RW;
105131952Smarcel				}
106131952Smarcel			} else {
107131952Smarcel				addr1 = trunc_2mpage(addr + size - 1);
108131952Smarcel				if (trunc_2mpage(addr) != addr1) {
109131952Smarcel					ptep1 = vtopte(addr1);
110131952Smarcel					oldmap1 = *ptep1;
111131952Smarcel					*ptep1 |= PG_RW;
112131952Smarcel				}
113131952Smarcel			}
11431317Sbde
115131952Smarcel			invltlb();
11627950Sdyson		}
11717865Spst
118131952Smarcel		dst = (char *)addr;
119131952Smarcel
120131952Smarcel		while (size-- > 0)
121131952Smarcel			*dst++ = *data++;
1224Srgrimes	}
1234Srgrimes
124131952Smarcel	(void)kdb_jmpbuf(prev_jb);
1254Srgrimes
1264Srgrimes	if (ptep0) {
127131952Smarcel		*ptep0 = oldmap0;
12817865Spst
129131952Smarcel		if (ptep1)
130131952Smarcel			*ptep1 = oldmap1;
13117865Spst
132131952Smarcel		invltlb();
1334Srgrimes	}
1344Srgrimes
135131952Smarcel	return (ret);
1364Srgrimes}
13775274Sjhb
13887702Sjhbvoid
13987702Sjhbdb_show_mdpcpu(struct pcpu *pc)
14075274Sjhb{
14175274Sjhb
142208392Sjhb	db_printf("curpmap      = %p\n", pc->pc_curpmap);
143208392Sjhb	db_printf("tssp         = %p\n", pc->pc_tssp);
144208392Sjhb	db_printf("commontssp   = %p\n", pc->pc_commontssp);
145208392Sjhb	db_printf("rsp0         = 0x%lx\n", pc->pc_rsp0);
146208392Sjhb	db_printf("gs32p        = %p\n", pc->pc_gs32p);
147208392Sjhb	db_printf("ldt          = %p\n", pc->pc_ldt);
148208392Sjhb	db_printf("tss          = %p\n", pc->pc_tss);
14975274Sjhb}
150