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-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-2  -  FREEBSD-11-1  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-4  -  FREEBSD-10-3  -  FREEBSD-10-2  -  FREEBSD-10-1  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-3  -  FREEBSD-9-2  -  FREEBSD-9-1  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-4  -  FREEBSD-8-3  -  FREEBSD-8-2  -  FREEBSD-8-1  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-4  -  FREEBSD-7-3  -  FREEBSD-7-2  -  FREEBSD-7-1  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-4  -  FREEBSD-6-3  -  FREEBSD-6-2  -  FREEBSD-6-1  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-5  -  FREEBSD-5-4  -  FREEBSD-5-3  -  FREEBSD-5-2  -  FREEBSD-5-1  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  linux-2.6  -  linux-2.4.22  -  MK83  -  MK84  -  PLAN9  -  DFBSD  -  NETBSD  -  NETBSD5  -  NETBSD4  -  NETBSD3  -  NETBSD20  -  OPENBSD  -  xnu-517  -  xnu-792  -  xnu-792.6.70  -  xnu-1228  -  xnu-1456.1.26  -  xnu-1699.24.8  -  xnu-2050.18.24  -  OPENSOLARIS  -  minix-3-1-1 
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/8.4/sys/mips/mips/db_interface.c 215938 2010-11-27 12:26:40Z jchandra $");
   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 #define NO_REG_DEFS     1       /* Prevent asm.h from including regdef.h */
   59 #include <machine/asm.h>
   60 #include <machine/setjmp.h>
   61 
   62 #include <ddb/ddb.h>
   63 #include <ddb/db_sym.h>
   64 #include <ddb/db_access.h>
   65 #include <ddb/db_output.h>
   66 #include <ddb/db_variables.h>
   67 #include <sys/kdb.h>
   68 
   69 static db_varfcn_t db_frame;
   70 
   71 #define DB_OFFSET(x)    (db_expr_t *)offsetof(struct trapframe, x)
   72 struct db_variable db_regs[] = {
   73         { "at",  DB_OFFSET(ast),        db_frame },
   74         { "v0",  DB_OFFSET(v0),         db_frame },
   75         { "v1",  DB_OFFSET(v1),         db_frame },
   76         { "a0",  DB_OFFSET(a0),         db_frame },
   77         { "a1",  DB_OFFSET(a1),         db_frame },
   78         { "a2",  DB_OFFSET(a2),         db_frame },
   79         { "a3",  DB_OFFSET(a3),         db_frame },
   80         { "t0",  DB_OFFSET(t0),         db_frame },
   81         { "t1",  DB_OFFSET(t1),         db_frame },
   82         { "t2",  DB_OFFSET(t2),         db_frame },
   83         { "t3",  DB_OFFSET(t3),         db_frame },
   84         { "t4",  DB_OFFSET(t4),         db_frame },
   85         { "t5",  DB_OFFSET(t5),         db_frame },
   86         { "t6",  DB_OFFSET(t6),         db_frame },
   87         { "t7",  DB_OFFSET(t7),         db_frame },
   88         { "s0",  DB_OFFSET(s0),         db_frame },
   89         { "s1",  DB_OFFSET(s1),         db_frame },
   90         { "s2",  DB_OFFSET(s2),         db_frame },
   91         { "s3",  DB_OFFSET(s3),         db_frame },
   92         { "s4",  DB_OFFSET(s4),         db_frame },
   93         { "s5",  DB_OFFSET(s5),         db_frame },
   94         { "s6",  DB_OFFSET(s6),         db_frame },
   95         { "s7",  DB_OFFSET(s7),         db_frame },
   96         { "t8",  DB_OFFSET(t8),         db_frame },
   97         { "t9",  DB_OFFSET(t9),         db_frame },
   98         { "k0",  DB_OFFSET(k0),         db_frame },
   99         { "k1",  DB_OFFSET(k1),         db_frame },
  100         { "gp",  DB_OFFSET(gp),         db_frame },
  101         { "sp",  DB_OFFSET(sp),         db_frame },
  102         { "s8",  DB_OFFSET(s8),         db_frame },
  103         { "ra",  DB_OFFSET(ra),         db_frame },
  104         { "sr",  DB_OFFSET(sr),         db_frame },
  105         { "lo",  DB_OFFSET(mullo),      db_frame },
  106         { "hi",  DB_OFFSET(mulhi),      db_frame },
  107         { "bad", DB_OFFSET(badvaddr),   db_frame },
  108         { "cs",  DB_OFFSET(cause),      db_frame },
  109         { "pc",  DB_OFFSET(pc),         db_frame },
  110 };
  111 struct db_variable *db_eregs = db_regs + sizeof(db_regs)/sizeof(db_regs[0]);
  112 
  113 int (*do_db_log_stack_trace_cmd)(char *);
  114 
  115 static int
  116 db_frame(struct db_variable *vp, db_expr_t *valuep, int op)
  117 {
  118         register_t *reg;
  119 
  120         if (kdb_frame == NULL)
  121                 return (0);
  122 
  123         reg = (register_t *)((uintptr_t)kdb_frame + (size_t)(intptr_t)vp->valuep);
  124         if (op == DB_VAR_GET)
  125                 *valuep = *reg;
  126         else
  127                 *reg = *valuep;
  128         return (1);
  129 }
  130 
  131 int
  132 db_read_bytes(vm_offset_t addr, size_t size, char *data)
  133 {
  134         jmp_buf jb;
  135         void *prev_jb;
  136         int ret;
  137 
  138         prev_jb = kdb_jmpbuf(jb);
  139         ret = setjmp(jb);
  140         if (ret == 0) {
  141                 /*
  142                  * 'addr' could be a memory-mapped I/O address.  Try to
  143                  * do atomic load/store in unit of size requested.
  144                  */
  145                 if ((size == 2 || size == 4 || size == 8) &&
  146                     ((addr & (size -1)) == 0) &&
  147                     (((vm_offset_t)data & (size -1)) == 0)) {
  148                         switch (size) {
  149                         case 2:
  150                                 *(uint16_t *)data = *(uint16_t *)addr;
  151                                 break;
  152                         case 4:
  153                                 *(uint32_t *)data = *(uint32_t *)addr;
  154                                 break;
  155                         case 8:
  156                                 atomic_load_64((volatile u_int64_t *)addr,
  157                                     (u_int64_t *)data);
  158                         break;
  159                         }
  160                 } else {
  161                         char *src;
  162 
  163                         src = (char *)addr;
  164                         while (size-- > 0)
  165                                 *data++ = *src++;
  166                 }
  167         }
  168 
  169         (void)kdb_jmpbuf(prev_jb);
  170         return (ret);
  171 }
  172 
  173 int
  174 db_write_bytes(vm_offset_t addr, size_t size, char *data)
  175 {
  176         int ret;
  177         jmp_buf jb;
  178         void *prev_jb;
  179 
  180         prev_jb = kdb_jmpbuf(jb);
  181         ret = setjmp(jb);
  182 
  183         if (ret == 0) {
  184                 /*
  185                  * 'addr' could be a memory-mapped I/O address.  Try to
  186                  * do atomic load/store in unit of size requested.
  187                  */
  188                 if ((size == 2 || size == 4 || size == 8) &&
  189                     ((addr & (size -1)) == 0) &&
  190                     (((vm_offset_t)data & (size -1)) == 0)) {
  191                         switch (size) {
  192                         case 2:
  193                                 *(uint16_t *)addr = *(uint16_t *)data;
  194                                 break;
  195                         case 4:
  196                                 *(uint32_t *)addr = *(uint32_t *)data;
  197                                 break;
  198                         case 8:
  199                                 atomic_store_64((volatile u_int64_t *)addr,
  200                                     (u_int64_t *)data);
  201                         break;
  202                         }
  203                 } else {
  204                         char *dst;
  205                         size_t len = size;
  206 
  207                         dst = (char *)addr;
  208                         while (len-- > 0)
  209                                 *dst++ = *data++;
  210                 }
  211 
  212                 mips_icache_sync_range((db_addr_t) addr, size);
  213                 mips_dcache_wbinv_range((db_addr_t) addr, size);
  214         }
  215         (void)kdb_jmpbuf(prev_jb);
  216         return (ret);
  217 }
  218 
  219 /*
  220  *      To do a single step ddb needs to know the next address
  221  *      that we will get to. It means that we need to find out
  222  *      both the address for a branch taken and for not taken, NOT! :-)
  223  *      MipsEmulateBranch will do the job to find out _exactly_ which
  224  *      address we will end up at so the 'dual bp' method is not
  225  *      requiered.
  226  */
  227 db_addr_t
  228 next_instr_address(db_addr_t pc, boolean_t bd)
  229 {
  230         db_addr_t next;
  231 
  232         next = (db_addr_t)MipsEmulateBranch(kdb_frame, pc, 0, 0);
  233         return (next);
  234 }
  235 
  236 
  237 /*
  238  *      Decode instruction and figure out type.
  239  */
  240 int
  241 db_inst_type(int ins)
  242 {
  243         InstFmt inst;
  244         int     ityp = 0;
  245 
  246         inst.word = ins;
  247         switch ((int)inst.JType.op) {
  248         case OP_SPECIAL:
  249                 switch ((int)inst.RType.func) {
  250                 case OP_JR:
  251                         ityp = IT_BRANCH;
  252                         break;
  253                 case OP_JALR:
  254                 case OP_SYSCALL:
  255                         ityp = IT_CALL;
  256                         break;
  257                 }
  258                 break;
  259 
  260         case OP_BCOND:
  261                 switch ((int)inst.IType.rt) {
  262                 case OP_BLTZ:
  263                 case OP_BLTZL:
  264                 case OP_BGEZ:
  265                 case OP_BGEZL:
  266                         ityp = IT_BRANCH;
  267                         break;
  268 
  269                 case OP_BLTZAL:
  270                 case OP_BLTZALL:
  271                 case OP_BGEZAL:
  272                 case OP_BGEZALL:
  273                         ityp = IT_CALL;
  274                         break;
  275                 }
  276                 break;
  277 
  278         case OP_JAL:
  279                 ityp = IT_CALL;
  280                 break;
  281 
  282         case OP_J:
  283         case OP_BEQ:
  284         case OP_BEQL:
  285         case OP_BNE:
  286         case OP_BNEL:
  287         case OP_BLEZ:
  288         case OP_BLEZL:
  289         case OP_BGTZ:
  290         case OP_BGTZL:
  291                 ityp = IT_BRANCH;
  292                 break;
  293 
  294         case OP_COP1:
  295                 switch (inst.RType.rs) {
  296                 case OP_BCx:
  297                 case OP_BCy:
  298                         ityp = IT_BRANCH;
  299                         break;
  300                 }
  301                 break;
  302 
  303         case OP_LB:
  304         case OP_LH:
  305         case OP_LW:
  306         case OP_LD:
  307         case OP_LBU:
  308         case OP_LHU:
  309         case OP_LWU:
  310         case OP_LWC1:
  311                 ityp = IT_LOAD;
  312                 break;
  313 
  314         case OP_SB:
  315         case OP_SH:
  316         case OP_SW:
  317         case OP_SD:  
  318         case OP_SWC1:
  319                 ityp = IT_STORE;
  320                 break;
  321         }
  322         return (ityp);
  323 }
  324 
  325 /*
  326  * Return the next pc if the given branch is taken.
  327  * MachEmulateBranch() runs analysis for branch delay slot.
  328  */
  329 db_addr_t
  330 branch_taken(int inst, db_addr_t pc)
  331 {
  332         db_addr_t ra;
  333         register_t fpucsr;
  334 
  335         /* TBD: when is fsr set */
  336         fpucsr = (curthread) ? curthread->td_pcb->pcb_regs.fsr : 0;
  337         ra = (db_addr_t)MipsEmulateBranch(kdb_frame, pc, fpucsr, 0);
  338         return (ra);
  339 }

Cache object: f60efc2f2b651c29c73f8ad6a12f3815


[ 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.