The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/mips/mips/db_interface.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      $OpenBSD: db_machdep.c,v 1.2 1998/09/15 10:50:13 pefo Exp $ */
    2 
    3 /*-
    4  * Copyright (c) 1998 Per Fogelstrom, Opsycon AB
    5  *
    6  * Redistribution and use in source and binary forms, with or without
    7  * modification, are permitted provided that the following conditions
    8  * are met:
    9  * 1. Redistributions of source code must retain the above copyright
   10  *    notice, this list of conditions and the following disclaimer.
   11  * 2. Redistributions in binary form must reproduce the above copyright
   12  *    notice, this list of conditions and the following disclaimer in the
   13  *    documentation and/or other materials provided with the distribution.
   14  * 3. All advertising materials mentioning features or use of this software
   15  *    must display the following acknowledgement:
   16  *      This product includes software developed under OpenBSD by
   17  *      Per Fogelstrom, Opsycon AB, Sweden.
   18  * 4. The name of the author may not be used to endorse or promote products
   19  *    derived from this software without specific prior written permission.
   20  *
   21  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
   22  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
   23  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
   25  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   31  * SUCH DAMAGE.
   32  *
   33  *      JNPR: db_interface.c,v 1.6.2.1 2007/08/29 12:24:49 girish
   34  */
   35 
   36 #include <sys/cdefs.h>
   37 __FBSDID("$FreeBSD: releng/10.1/sys/mips/mips/db_interface.c 250138 2013-05-01 06:57:46Z imp $");
   38 
   39 #include <sys/types.h>
   40 #include <sys/param.h>
   41 #include <sys/systm.h>
   42 #include <sys/cons.h>
   43 #include <sys/lock.h>
   44 #include <vm/vm.h>
   45 #include <vm/vm_object.h>
   46 #include <vm/vm_page.h>
   47 #include <vm/pmap.h>
   48 #include <vm/vm_map.h>
   49 #include <sys/user.h>
   50 #include <sys/proc.h>
   51 #include <sys/reboot.h>
   52 
   53 #include <machine/cache.h>
   54 #include <machine/db_machdep.h>
   55 #include <machine/mips_opcode.h>
   56 #include <machine/vmparam.h>
   57 #include <machine/md_var.h>
   58 #include <machine/setjmp.h>
   59 
   60 #include <ddb/ddb.h>
   61 #include <ddb/db_sym.h>
   62 #include <ddb/db_access.h>
   63 #include <ddb/db_output.h>
   64 #include <ddb/db_variables.h>
   65 #include <sys/kdb.h>
   66 
   67 static db_varfcn_t db_frame;
   68 
   69 #define DB_OFFSET(x)    (db_expr_t *)offsetof(struct trapframe, x)
   70 struct db_variable db_regs[] = {
   71         { "at",  DB_OFFSET(ast),        db_frame },
   72         { "v0",  DB_OFFSET(v0),         db_frame },
   73         { "v1",  DB_OFFSET(v1),         db_frame },
   74         { "a0",  DB_OFFSET(a0),         db_frame },
   75         { "a1",  DB_OFFSET(a1),         db_frame },
   76         { "a2",  DB_OFFSET(a2),         db_frame },
   77         { "a3",  DB_OFFSET(a3),         db_frame },
   78 #if defined(__mips_n32) || defined(__mips_n64)
   79         { "a4",  DB_OFFSET(a4),         db_frame },
   80         { "a5",  DB_OFFSET(a5),         db_frame },
   81         { "a6",  DB_OFFSET(a6),         db_frame },
   82         { "a7",  DB_OFFSET(a7),         db_frame },
   83         { "t0",  DB_OFFSET(t0),         db_frame },
   84         { "t1",  DB_OFFSET(t1),         db_frame },
   85         { "t2",  DB_OFFSET(t2),         db_frame },
   86         { "t3",  DB_OFFSET(t3),         db_frame },
   87 #else
   88         { "t0",  DB_OFFSET(t0),         db_frame },
   89         { "t1",  DB_OFFSET(t1),         db_frame },
   90         { "t2",  DB_OFFSET(t2),         db_frame },
   91         { "t3",  DB_OFFSET(t3),         db_frame },
   92         { "t4",  DB_OFFSET(t4),         db_frame },
   93         { "t5",  DB_OFFSET(t5),         db_frame },
   94         { "t6",  DB_OFFSET(t6),         db_frame },
   95         { "t7",  DB_OFFSET(t7),         db_frame },
   96 #endif
   97         { "s0",  DB_OFFSET(s0),         db_frame },
   98         { "s1",  DB_OFFSET(s1),         db_frame },
   99         { "s2",  DB_OFFSET(s2),         db_frame },
  100         { "s3",  DB_OFFSET(s3),         db_frame },
  101         { "s4",  DB_OFFSET(s4),         db_frame },
  102         { "s5",  DB_OFFSET(s5),         db_frame },
  103         { "s6",  DB_OFFSET(s6),         db_frame },
  104         { "s7",  DB_OFFSET(s7),         db_frame },
  105         { "t8",  DB_OFFSET(t8),         db_frame },
  106         { "t9",  DB_OFFSET(t9),         db_frame },
  107         { "k0",  DB_OFFSET(k0),         db_frame },
  108         { "k1",  DB_OFFSET(k1),         db_frame },
  109         { "gp",  DB_OFFSET(gp),         db_frame },
  110         { "sp",  DB_OFFSET(sp),         db_frame },
  111         { "s8",  DB_OFFSET(s8),         db_frame },
  112         { "ra",  DB_OFFSET(ra),         db_frame },
  113         { "sr",  DB_OFFSET(sr),         db_frame },
  114         { "lo",  DB_OFFSET(mullo),      db_frame },
  115         { "hi",  DB_OFFSET(mulhi),      db_frame },
  116         { "bad", DB_OFFSET(badvaddr),   db_frame },
  117         { "cs",  DB_OFFSET(cause),      db_frame },
  118         { "pc",  DB_OFFSET(pc),         db_frame },
  119 };
  120 struct db_variable *db_eregs = db_regs + sizeof(db_regs)/sizeof(db_regs[0]);
  121 
  122 int (*do_db_log_stack_trace_cmd)(char *);
  123 
  124 static int
  125 db_frame(struct db_variable *vp, db_expr_t *valuep, int op)
  126 {
  127         register_t *reg;
  128 
  129         if (kdb_frame == NULL)
  130                 return (0);
  131 
  132         reg = (register_t *)((uintptr_t)kdb_frame + (size_t)(intptr_t)vp->valuep);
  133         if (op == DB_VAR_GET)
  134                 *valuep = *reg;
  135         else
  136                 *reg = *valuep;
  137         return (1);
  138 }
  139 
  140 int
  141 db_read_bytes(vm_offset_t addr, size_t size, char *data)
  142 {
  143         jmp_buf jb;
  144         void *prev_jb;
  145         int ret;
  146 
  147         prev_jb = kdb_jmpbuf(jb);
  148         ret = setjmp(jb);
  149         if (ret == 0) {
  150                 /*
  151                  * 'addr' could be a memory-mapped I/O address.  Try to
  152                  * do atomic load/store in unit of size requested.
  153                  */
  154                 if ((size == 2 || size == 4 || size == 8) &&
  155                     ((addr & (size -1)) == 0) &&
  156                     (((vm_offset_t)data & (size -1)) == 0)) {
  157                         switch (size) {
  158                         case 2:
  159                                 *(uint16_t *)data = *(uint16_t *)addr;
  160                                 break;
  161                         case 4:
  162                                 *(uint32_t *)data = *(uint32_t *)addr;
  163                                 break;
  164                         case 8:
  165                                 atomic_load_64((volatile u_int64_t *)addr,
  166                                     (u_int64_t *)data);
  167                         break;
  168                         }
  169                 } else {
  170                         char *src;
  171 
  172                         src = (char *)addr;
  173                         while (size-- > 0)
  174                                 *data++ = *src++;
  175                 }
  176         }
  177 
  178         (void)kdb_jmpbuf(prev_jb);
  179         return (ret);
  180 }
  181 
  182 int
  183 db_write_bytes(vm_offset_t addr, size_t size, char *data)
  184 {
  185         int ret;
  186         jmp_buf jb;
  187         void *prev_jb;
  188 
  189         prev_jb = kdb_jmpbuf(jb);
  190         ret = setjmp(jb);
  191 
  192         if (ret == 0) {
  193                 /*
  194                  * 'addr' could be a memory-mapped I/O address.  Try to
  195                  * do atomic load/store in unit of size requested.
  196                  */
  197                 if ((size == 2 || size == 4 || size == 8) &&
  198                     ((addr & (size -1)) == 0) &&
  199                     (((vm_offset_t)data & (size -1)) == 0)) {
  200                         switch (size) {
  201                         case 2:
  202                                 *(uint16_t *)addr = *(uint16_t *)data;
  203                                 break;
  204                         case 4:
  205                                 *(uint32_t *)addr = *(uint32_t *)data;
  206                                 break;
  207                         case 8:
  208                                 atomic_store_64((volatile u_int64_t *)addr,
  209                                     (u_int64_t *)data);
  210                         break;
  211                         }
  212                 } else {
  213                         char *dst;
  214                         size_t len = size;
  215 
  216                         dst = (char *)addr;
  217                         while (len-- > 0)
  218                                 *dst++ = *data++;
  219                 }
  220 
  221                 mips_icache_sync_range((db_addr_t) addr, size);
  222                 mips_dcache_wbinv_range((db_addr_t) addr, size);
  223         }
  224         (void)kdb_jmpbuf(prev_jb);
  225         return (ret);
  226 }
  227 
  228 /*
  229  *      To do a single step ddb needs to know the next address
  230  *      that we will get to. It means that we need to find out
  231  *      both the address for a branch taken and for not taken, NOT! :-)
  232  *      MipsEmulateBranch will do the job to find out _exactly_ which
  233  *      address we will end up at so the 'dual bp' method is not
  234  *      requiered.
  235  */
  236 db_addr_t
  237 next_instr_address(db_addr_t pc, boolean_t bd)
  238 {
  239         db_addr_t next;
  240 
  241         next = (db_addr_t)MipsEmulateBranch(kdb_frame, pc, 0, 0);
  242         return (next);
  243 }
  244 
  245 
  246 /*
  247  *      Decode instruction and figure out type.
  248  */
  249 int
  250 db_inst_type(int ins)
  251 {
  252         InstFmt inst;
  253         int     ityp = 0;
  254 
  255         inst.word = ins;
  256         switch ((int)inst.JType.op) {
  257         case OP_SPECIAL:
  258                 switch ((int)inst.RType.func) {
  259                 case OP_JR:
  260                         ityp = IT_BRANCH;
  261                         break;
  262                 case OP_JALR:
  263                 case OP_SYSCALL:
  264                         ityp = IT_CALL;
  265                         break;
  266                 }
  267                 break;
  268 
  269         case OP_BCOND:
  270                 switch ((int)inst.IType.rt) {
  271                 case OP_BLTZ:
  272                 case OP_BLTZL:
  273                 case OP_BGEZ:
  274                 case OP_BGEZL:
  275                         ityp = IT_BRANCH;
  276                         break;
  277 
  278                 case OP_BLTZAL:
  279                 case OP_BLTZALL:
  280                 case OP_BGEZAL:
  281                 case OP_BGEZALL:
  282                         ityp = IT_CALL;
  283                         break;
  284                 }
  285                 break;
  286 
  287         case OP_JAL:
  288                 ityp = IT_CALL;
  289                 break;
  290 
  291         case OP_J:
  292         case OP_BEQ:
  293         case OP_BEQL:
  294         case OP_BNE:
  295         case OP_BNEL:
  296         case OP_BLEZ:
  297         case OP_BLEZL:
  298         case OP_BGTZ:
  299         case OP_BGTZL:
  300                 ityp = IT_BRANCH;
  301                 break;
  302 
  303         case OP_COP1:
  304                 switch (inst.RType.rs) {
  305                 case OP_BCx:
  306                 case OP_BCy:
  307                         ityp = IT_BRANCH;
  308                         break;
  309                 }
  310                 break;
  311 
  312         case OP_LB:
  313         case OP_LH:
  314         case OP_LW:
  315         case OP_LD:
  316         case OP_LBU:
  317         case OP_LHU:
  318         case OP_LWU:
  319         case OP_LWC1:
  320                 ityp = IT_LOAD;
  321                 break;
  322 
  323         case OP_SB:
  324         case OP_SH:
  325         case OP_SW:
  326         case OP_SD:  
  327         case OP_SWC1:
  328                 ityp = IT_STORE;
  329                 break;
  330         }
  331         return (ityp);
  332 }
  333 
  334 /*
  335  * Return the next pc if the given branch is taken.
  336  * MachEmulateBranch() runs analysis for branch delay slot.
  337  */
  338 db_addr_t
  339 branch_taken(int inst, db_addr_t pc)
  340 {
  341         db_addr_t ra;
  342         register_t fpucsr;
  343 
  344         /* TBD: when is fsr set */
  345         fpucsr = (curthread) ? curthread->td_pcb->pcb_regs.fsr : 0;
  346         ra = (db_addr_t)MipsEmulateBranch(kdb_frame, pc, fpucsr, 0);
  347         return (ra);
  348 }

Cache object: 90734ead73303283db360975466376ff


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.