[BACK]Return to db_memrw.c CVS log [TXT][DIR] Up to [local] / sys / arch / amd64 / amd64

Annotation of sys/arch/amd64/amd64/db_memrw.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: db_memrw.c,v 1.3 2005/10/21 18:55:00 martin Exp $     */
                      2: /*     $NetBSD: db_memrw.c,v 1.1 2003/04/26 18:39:27 fvdl Exp $        */
                      3:
                      4: /*-
                      5:  * Copyright (c) 1996, 2000 The NetBSD Foundation, Inc.
                      6:  * All rights reserved.
                      7:  *
                      8:  * This code is derived from software contributed to The NetBSD Foundation
                      9:  * by Gordon W. Ross and Jason R. Thorpe.
                     10:  *
                     11:  * Redistribution and use in source and binary forms, with or without
                     12:  * modification, are permitted provided that the following conditions
                     13:  * are met:
                     14:  * 1. Redistributions of source code must retain the above copyright
                     15:  *    notice, this list of conditions and the following disclaimer.
                     16:  * 2. Redistributions in binary form must reproduce the above copyright
                     17:  *    notice, this list of conditions and the following disclaimer in the
                     18:  *    documentation and/or other materials provided with the distribution.
                     19:  * 3. All advertising materials mentioning features or use of this software
                     20:  *    must display the following acknowledgement:
                     21:  *        This product includes software developed by the NetBSD
                     22:  *        Foundation, Inc. and its contributors.
                     23:  * 4. Neither the name of The NetBSD Foundation nor the names of its
                     24:  *    contributors may be used to endorse or promote products derived
                     25:  *    from this software without specific prior written permission.
                     26:  *
                     27:  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
                     28:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     29:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     30:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
                     31:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     32:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     33:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     34:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     35:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     36:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     37:  * POSSIBILITY OF SUCH DAMAGE.
                     38:  */
                     39:
                     40: /*
                     41:  * Interface to the debugger for virtual memory read/write.
                     42:  * This file is shared by DDB and KGDB, and must work even
                     43:  * when only KGDB is included (thus no db_printf calls).
                     44:  *
                     45:  * To write in the text segment, we have to first make
                     46:  * the page writable, do the write, then restore the PTE.
                     47:  * For writes outside the text segment, and all reads,
                     48:  * just do the access -- if it causes a fault, the debugger
                     49:  * will recover with a longjmp to an appropriate place.
                     50:  *
                     51:  * ALERT!  If you want to access device registers with a
                     52:  * specific size, then the read/write functions have to
                     53:  * make sure to do the correct sized pointer access.
                     54:  *
                     55:  * Modified for i386 from hp300 version by
                     56:  * Jason R. Thorpe <thorpej@zembu.com>.
                     57:  *
                     58:  * Basic copy to amd64 by fvdl.
                     59:  */
                     60:
                     61: #include <sys/param.h>
                     62: #include <sys/proc.h>
                     63: #include <sys/systm.h>
                     64:
                     65: #include <uvm/uvm_extern.h>
                     66:
                     67: #include <machine/db_machdep.h>
                     68:
                     69: #include <ddb/db_access.h>
                     70:
                     71: /*
                     72:  * Read bytes from kernel address space for debugger.
                     73:  */
                     74: void
                     75: db_read_bytes(vaddr_t addr, size_t size, char *data)
                     76: {
                     77:        char *src;
                     78:
                     79:        src = (char *)addr;
                     80:
                     81:        if (size == 8) {
                     82:                *((long *)data) = *((long *)src);
                     83:                return;
                     84:        }
                     85:
                     86:        if (size == 4) {
                     87:                *((int *)data) = *((int *)src);
                     88:                return;
                     89:        }
                     90:
                     91:        if (size == 2) {
                     92:                *((short *)data) = *((short *)src);
                     93:                return;
                     94:        }
                     95:
                     96:        while (size-- > 0)
                     97:                *data++ = *src++;
                     98: }
                     99:
                    100: /*
                    101:  * Write bytes somewhere in the kernel text.  Make the text
                    102:  * pages writable temporarily.
                    103:  */
                    104: static void
                    105: db_write_text(vaddr_t addr, size_t size, char *data)
                    106: {
                    107:        pt_entry_t *pte, oldpte, tmppte;
                    108:        vaddr_t pgva;
                    109:        size_t limit;
                    110:        char *dst;
                    111:
                    112:        if (size == 0)
                    113:                return;
                    114:
                    115:        dst = (char *)addr;
                    116:
                    117:        do {
                    118:                /*
                    119:                 * Get the PTE for the page.
                    120:                 */
                    121:                pte = kvtopte(addr);
                    122:                oldpte = *pte;
                    123:
                    124:                if ((oldpte & PG_V) == 0) {
                    125:                        printf(" address %p not a valid page\n", dst);
                    126:                        return;
                    127:                }
                    128:
                    129:                /*
                    130:                 * Get the VA for the page.
                    131:                 */
                    132:                if (oldpte & PG_PS)
                    133:                        pgva = (vaddr_t)dst & PG_LGFRAME;
                    134:                else
                    135:                        pgva = trunc_page((vaddr_t)dst);
                    136:
                    137:                /*
                    138:                 * Compute number of bytes that can be written
                    139:                 * with this mapping and subtract it from the
                    140:                 * total size.
                    141:                 */
                    142:                if (oldpte & PG_PS)
                    143:                        limit = NBPD_L2 - ((vaddr_t)dst & (NBPD_L2 - 1));
                    144:                else
                    145:                        limit = PAGE_SIZE - ((vaddr_t)dst & PGOFSET);
                    146:                if (limit > size)
                    147:                        limit = size;
                    148:                size -= limit;
                    149:
                    150:                tmppte = (oldpte & ~PG_KR) | PG_KW;
                    151:                *pte = tmppte;
                    152:                pmap_update_pg(pgva);
                    153:
                    154:                /*
                    155:                 * Page is now writable.  Do as much access as we
                    156:                 * can in this page.
                    157:                 */
                    158:                for (; limit > 0; limit--)
                    159:                        *dst++ = *data++;
                    160:
                    161:                /*
                    162:                 * Restore the old PTE.
                    163:                 */
                    164:                *pte = oldpte;
                    165:
                    166:                pmap_update_pg(pgva);
                    167:
                    168:        } while (size != 0);
                    169: }
                    170:
                    171: /*
                    172:  * Write bytes to kernel address space for debugger.
                    173:  */
                    174: void
                    175: db_write_bytes(vaddr_t addr, size_t size, char *data)
                    176: {
                    177:        extern char etext;
                    178:        char *dst;
                    179:
                    180:        dst = (char *)addr;
                    181:
                    182:        /* If any part is in kernel text, use db_write_text() */
                    183:        if (addr >= KERNBASE && addr < (vaddr_t)&etext) {
                    184:                db_write_text(addr, size, data);
                    185:                return;
                    186:        }
                    187:
                    188:        dst = (char *)addr;
                    189:
                    190:        if (size == 8) {
                    191:                *((long *)dst) = *((long *)data);
                    192:                return;
                    193:        }
                    194:
                    195:        if (size == 4) {
                    196:                *((int *)dst) = *((int *)data);
                    197:                return;
                    198:        }
                    199:
                    200:        if (size == 2) {
                    201:                *((short *)dst) = *((short *)data);
                    202:                return;
                    203:        }
                    204:
                    205:        while (size-- > 0)
                    206:                *dst++ = *data++;
                    207: }

CVSweb