ia64/xen-unstable

changeset 5587:ca9f091afdd2

bitkeeper revision 1.1761 (42c0704c_K5N6pcA--cz5L-FX_z0zw)

Merge arcadians.cl.cam.ac.uk:/auto/groups/xeno-xenod/BK/xeno.bk
into arcadians.cl.cam.ac.uk:/auto/anfs/nos1/ach61/bk
author ach61@arcadians.cl.cam.ac.uk
date Mon Jun 27 21:31:56 2005 +0000 (2005-06-27)
parents b08cd3331fdb 2cadc83e2306
children 9bcdcf2dbb54
files .rootkeys tools/debugger/pdb/Domain.ml tools/debugger/pdb/Intel.ml tools/debugger/pdb/Makefile tools/debugger/pdb/PDB.ml tools/debugger/pdb/Process.ml tools/debugger/pdb/Process.mli tools/debugger/pdb/Util.ml tools/debugger/pdb/Xen_domain.ml tools/debugger/pdb/Xen_domain.mli tools/debugger/pdb/debugger.ml tools/debugger/pdb/evtchn.ml tools/debugger/pdb/evtchn.mli tools/debugger/pdb/linux-2.6-module/Makefile tools/debugger/pdb/linux-2.6-module/debug.c tools/debugger/pdb/linux-2.6-module/module.c tools/debugger/pdb/linux-2.6-module/pdb_module.h tools/debugger/pdb/pdb_caml_domain.c tools/debugger/pdb/pdb_caml_evtchn.c tools/debugger/pdb/pdb_caml_process.c tools/debugger/pdb/pdb_caml_xc.c tools/debugger/pdb/pdb_caml_xcs.c tools/debugger/pdb/pdb_caml_xen.h tools/debugger/pdb/pdb_xen.c tools/debugger/pdb/server.ml tools/debugger/pdb/xcs.ml tools/debugger/pdb/xcs.mli xen/include/public/io/domain_controller.h
line diff
     1.1 --- a/.rootkeys	Mon Jun 27 20:17:02 2005 +0000
     1.2 +++ b/.rootkeys	Mon Jun 27 21:31:56 2005 +0000
     1.3 @@ -543,13 +543,26 @@ 42a0c8d9PgBvaWPzTHSFb9ngii7c7w tools/deb
     1.4  42a0c8danHHGiNywdeer6j4jzxAc2A tools/debugger/pdb/Process.ml
     1.5  42a0c8dav_08OtySI4kYP1lahlVrpQ tools/debugger/pdb/Process.mli
     1.6  42a0c8da51EqubQT5PJ4sxCKLF3xSw tools/debugger/pdb/Util.ml
     1.7 +42c06ff2SIoOLsDHH2ZyWKnYzA4Mkw tools/debugger/pdb/Xen_domain.ml
     1.8 +42c06ff2OXdWXeLK8YWeIIiHk3N6Xw tools/debugger/pdb/Xen_domain.mli
     1.9  42a0c8daxftpiXuvLmc9fOOEhdFWiQ tools/debugger/pdb/debugger.ml
    1.10  42a0c8da81tzhpvIAfkx9nZqUNrQvg tools/debugger/pdb/evtchn.ml
    1.11  42a0c8dasiso9c-2sCvHBzP6YVjATA tools/debugger/pdb/evtchn.mli
    1.12 +42c06ff2FXdouy4s5_DM6rUgaeJrOA tools/debugger/pdb/linux-2.6-module/Makefile
    1.13 +42c06ff27x60l_XDMTZRnv688McFfg tools/debugger/pdb/linux-2.6-module/debug.c
    1.14 +42c06ff2crmxKZFQw7KCkQlLnJh2TQ tools/debugger/pdb/linux-2.6-module/module.c
    1.15 +42c06ff2tC-1f7KRAGcEGrxjSao60g tools/debugger/pdb/linux-2.6-module/pdb_module.h
    1.16 +42c06ff2n2Ib0UeptbyAYZoF9-gFMQ tools/debugger/pdb/pdb_caml_domain.c
    1.17 +42c06ff2jKvaB6JHP-B_AR8f-7KeVQ tools/debugger/pdb/pdb_caml_evtchn.c
    1.18 +42c06ff3XPemRQRAfNIEV2qw2o6IUw tools/debugger/pdb/pdb_caml_process.c
    1.19  42a0c8daXD_6Y62A_u5-PO_Klrhi0w tools/debugger/pdb/pdb_caml_xc.c
    1.20 +42c06ff3joi_6rE-l4jh76qYUihAZA tools/debugger/pdb/pdb_caml_xcs.c
    1.21 +42c06ff3zUNt7tOZ-AgTTWcy9pirvg tools/debugger/pdb/pdb_caml_xen.h
    1.22  42a0c8danJXun9ay5SPBhhkKvuUPfg tools/debugger/pdb/pdb_xen.c
    1.23  42b03d06llc_GE7fXGQ6-rYR4VFAcw tools/debugger/pdb/readme
    1.24  42a0c8dbjK6Du89D2SUcxsuAdlUu3w tools/debugger/pdb/server.ml
    1.25 +42c06ff3v6Ks9EscwR6L0OTqdZn5kA tools/debugger/pdb/xcs.ml
    1.26 +42c06ff3j-5U79rRFb4bGqx1Ajhw4Q tools/debugger/pdb/xcs.mli
    1.27  401d7e160vaxMBAUSLSicuZ7AQjJ3w tools/examples/Makefile
    1.28  401d7e16UgeqroJQTIhwkrDVkoWgZQ tools/examples/README
    1.29  41597996VhTbNuHbuscYSfRb-WR6fA tools/examples/block-enbd
     2.1 --- a/tools/debugger/pdb/Domain.ml	Mon Jun 27 20:17:02 2005 +0000
     2.2 +++ b/tools/debugger/pdb/Domain.ml	Mon Jun 27 21:31:56 2005 +0000
     2.3 @@ -21,13 +21,10 @@ let default_context = { domain = 0; exec
     2.4  let new_context dom exec_dom = {domain = dom; execution_domain = exec_dom}
     2.5  
     2.6  let set_domain ctx value =
     2.7 -  ctx.domain <- value;
     2.8 -  print_endline (Printf.sprintf "ctx.domain <- %d" ctx.domain)
     2.9 +  ctx.domain <- value
    2.10  
    2.11  let set_execution_domain ctx value =
    2.12 -  ctx.execution_domain <- value;
    2.13 -  print_endline (Printf.sprintf "ctx.execution_domain <- %d"
    2.14 -		 ctx.execution_domain)
    2.15 +  ctx.execution_domain <- value
    2.16  
    2.17  let get_domain ctx =
    2.18    ctx.domain
    2.19 @@ -39,25 +36,25 @@ let string_of_context ctx =
    2.20        Printf.sprintf "{domain} domain: %d, execution_domain: %d"
    2.21                        ctx.domain  ctx.execution_domain
    2.22  
    2.23 -external read_registers : context_t -> registers = "read_registers"
    2.24 +external read_registers : context_t -> registers = "dom_read_registers"
    2.25  external write_register : context_t -> register -> int32 -> unit =
    2.26 -  "write_register"
    2.27 +  "dom_write_register"
    2.28  external read_memory : context_t -> int32 -> int -> int list = 
    2.29 -  "read_memory"
    2.30 +  "dom_read_memory"
    2.31  external write_memory : context_t -> int32 -> int list -> unit = 
    2.32 -  "write_memory"
    2.33 +  "dom_write_memory"
    2.34  	
    2.35 -external continue : context_t -> unit = "continue_target"
    2.36 -external step : context_t -> unit = "step_target"
    2.37 +external continue : context_t -> unit = "dom_continue_target"
    2.38 +external step : context_t -> unit = "dom_step_target"
    2.39  
    2.40  external insert_memory_breakpoint : context_t -> int32 -> int -> unit = 
    2.41 -  "insert_memory_breakpoint"
    2.42 +  "dom_insert_memory_breakpoint"
    2.43  external remove_memory_breakpoint : context_t -> int32 -> int -> unit = 
    2.44 -  "remove_memory_breakpoint"
    2.45 +  "dom_remove_memory_breakpoint"
    2.46  
    2.47 -external attach_debugger : int -> int -> unit = "attach_debugger"
    2.48 -external detach_debugger : int -> int -> unit = "detach_debugger"
    2.49 -external pause_target : int -> unit = "pause_target"
    2.50 +external attach_debugger : int -> int -> unit = "dom_attach_debugger"
    2.51 +external detach_debugger : int -> int -> unit = "dom_detach_debugger"
    2.52 +external pause_target : int -> unit = "dom_pause_target"
    2.53  
    2.54  let pause ctx =
    2.55    pause_target ctx.domain
     3.1 --- a/tools/debugger/pdb/Intel.ml	Mon Jun 27 20:17:02 2005 +0000
     3.2 +++ b/tools/debugger/pdb/Intel.ml	Mon Jun 27 21:31:56 2005 +0000
     3.3 @@ -9,63 +9,58 @@
     3.4  
     3.5  
     3.6  type register =
     3.7 -  | EBX
     3.8 +  | EAX
     3.9    | ECX
    3.10    | EDX
    3.11 +  | EBX
    3.12 +  | ESP
    3.13 +  | EBP
    3.14    | ESI
    3.15    | EDI
    3.16 -  | EBP
    3.17 -  | EAX
    3.18 -  | Error_code
    3.19 -  | Entry_vector
    3.20    | EIP
    3.21 +  | EFL
    3.22    | CS
    3.23 -  | EFLAGS
    3.24 -  | ESP
    3.25    | SS
    3.26 +  | DS
    3.27    | ES
    3.28 -  | DS
    3.29    | FS
    3.30    | GS
    3.31  
    3.32  type registers =
    3.33 -    { ebx : int32;
    3.34 +    { eax : int32;
    3.35        ecx : int32;
    3.36        edx : int32;
    3.37 +      ebx : int32;
    3.38 +      esp : int32;
    3.39 +      ebp : int32;
    3.40        esi : int32;
    3.41        edi : int32;
    3.42 -      ebp : int32;
    3.43 -      eax : int32;
    3.44 -      error_code : int32;
    3.45 -      entry_vector : int32;
    3.46        eip : int32;
    3.47 -      cs : int32;
    3.48 -      eflags : int32;
    3.49 -      esp : int32;
    3.50 -      ss : int32;
    3.51 -      es : int32;
    3.52 -      ds : int32;
    3.53 -      fs : int32;
    3.54 -      gs : int32
    3.55 +      efl : int32;
    3.56 +      cs  : int32;
    3.57 +      ss  : int32;
    3.58 +      ds  : int32;
    3.59 +      es  : int32;
    3.60 +      fs  : int32;
    3.61 +      gs  : int32
    3.62      }
    3.63  
    3.64  let null_registers =
    3.65 -  { ebx = 0l;
    3.66 -    ecx = 0l;
    3.67 -    edx = 0l;
    3.68 -    esi = 0l;
    3.69 -    edi = 0l;
    3.70 -    ebp = 0l;
    3.71 -    eax = 0l;
    3.72 -    error_code = 0l;
    3.73 -    entry_vector = 0l;
    3.74 -    eip = 0l;
    3.75 -    cs = 0l;
    3.76 -    eflags = 0l;
    3.77 -    esp = 0l;
    3.78 -    ss = 0l;
    3.79 -    es = 0l;
    3.80 -    ds = 0l;
    3.81 -    fs = 0l;
    3.82 -    gs = 0l
    3.83 -  }
    3.84 +    { eax = 0l;
    3.85 +      ecx = 0l;
    3.86 +      edx = 0l;
    3.87 +      ebx = 0l;
    3.88 +      esp = 0l;
    3.89 +      ebp = 0l;
    3.90 +      esi = 0l;
    3.91 +      edi = 0l;
    3.92 +      eip = 0l;
    3.93 +      efl = 0l;
    3.94 +      cs  = 0l;
    3.95 +      ss  = 0l;
    3.96 +      ds  = 0l;
    3.97 +      es  = 0l;
    3.98 +      fs  = 0l;
    3.99 +      gs  = 0l
   3.100 +    }
   3.101 +
     4.1 --- a/tools/debugger/pdb/Makefile	Mon Jun 27 20:17:02 2005 +0000
     4.2 +++ b/tools/debugger/pdb/Makefile	Mon Jun 27 21:31:56 2005 +0000
     4.3 @@ -7,10 +7,8 @@ include $(XEN_ROOT)/tools/Rules.mk
     4.4  # otherwise, ocamlmktop gets confused.
     4.5  LDFLAGS     =
     4.6  
     4.7 -OCAML_ROOT=/usr/local
     4.8  # force ocaml 3.08
     4.9 -# OCAML_ROOT  = /anfs/nos1/ach61/ocaml
    4.10 -
    4.11 +OCAML_ROOT  = /usr/local
    4.12  OCAMLC      = $(OCAML_ROOT)/bin/ocamlc
    4.13  OCAMLMKTOP  = $(OCAML_ROOT)/bin/ocamlmktop
    4.14  OCAMLLIBPATH= $(OCAML_ROOT)/lib/ocaml
    4.15 @@ -18,6 +16,7 @@ OCAMLLIBPATH= $(OCAML_ROOT)/lib/ocaml
    4.16  INCLUDES   += -I $(XEN_XC)
    4.17  INCLUDES   += -I $(XEN_LIBXC)
    4.18  INCLUDES   += -I ../libxendebug
    4.19 +INCLUDES   += -I ./linux-2.6-module
    4.20  INCLUDES   += -I $(OCAML_ROOT)/lib/ocaml
    4.21  
    4.22  CFLAGS     += $(INCLUDES)
    4.23 @@ -27,29 +26,26 @@ CFLAGS     += -g
    4.24  
    4.25  CLIBS      += xc
    4.26  CLIBS      += xendebug
    4.27 -CLIBS      += pdb
    4.28  
    4.29  LIBDIRS    += $(XEN_LIBXC)
    4.30 -LIBDIRS    += $(XEN_LIBXUTIL)
    4.31  LIBDIRS    += ../libxendebug
    4.32 -LIBDIRS    += .
    4.33  
    4.34  LIBS       += unix str
    4.35  
    4.36 -PRE_TARGETS = libpdb.a
    4.37 -
    4.38 -all : bc
    4.39 +# bc = byte-code, dc = debug byte-code
    4.40 +all : dc
    4.41  
    4.42 -libpdb.a : pdb_xen.o
    4.43 -	ar rc $@ $^
    4.44 -	ranlib $@
    4.45 -
    4.46 -SOURCES    += pdb_caml_xc.c pdb_xen.c
    4.47 +SOURCES    += pdb_caml_xc.c 
    4.48 +SOURCES    += pdb_caml_domain.c pdb_caml_process.c
    4.49 +SOURCES    += pdb_caml_evtchn.c pdb_caml_xcs.c pdb_xen.c
    4.50  SOURCES    += Util.ml Intel.ml 
    4.51  SOURCES    += evtchn.ml evtchn.mli
    4.52 +SOURCES    += xcs.ml xcs.mli
    4.53 +SOURCES    += Xen_domain.ml Xen_domain.mli
    4.54  SOURCES    += Domain.ml  Process.ml
    4.55  SOURCES    += Domain.mli Process.mli
    4.56  SOURCES    += PDB.ml debugger.ml server.ml
    4.57 +
    4.58  RESULT      = pdb
    4.59  
    4.60  include $(OCAMLMAKEFILE)
     5.1 --- a/tools/debugger/pdb/PDB.ml	Mon Jun 27 20:17:02 2005 +0000
     5.2 +++ b/tools/debugger/pdb/PDB.ml	Mon Jun 27 21:31:56 2005 +0000
     5.3 @@ -13,139 +13,26 @@ exception Unknown_domain
     5.4  
     5.5  type context_t =
     5.6    | Void
     5.7 -  | Event_channel
     5.8 +  | Xen_virq
     5.9 +  | Xen_xcs
    5.10 +  | Xen_domain of Xen_domain.context_t
    5.11    | Domain of Domain.context_t
    5.12    | Process of Process.context_t
    5.13  
    5.14  let string_of_context ctx =
    5.15    match ctx with
    5.16    | Void -> "{void}"
    5.17 -  | Event_channel -> "{event channel}"
    5.18 +  | Xen_virq  -> "{Xen virq evtchn}"
    5.19 +  | Xen_xcs   -> "{Xen xcs socket}"
    5.20 +  | Xen_domain d -> Xen_domain.string_of_context d
    5.21    | Domain d  -> Domain.string_of_context d
    5.22    | Process p -> Process.string_of_context p
    5.23  
    5.24  
    5.25 -
    5.26 -let read_registers ctx =
    5.27 -  match ctx with
    5.28 -  | Domain d  -> Domain.read_registers d 
    5.29 -  | _ -> Intel.null_registers
    5.30 -
    5.31 -let write_register ctx register value =
    5.32 -  match ctx with
    5.33 -  | Domain d  -> Domain.write_register d register value
    5.34 -  | _ -> raise (Unimplemented "write register")
    5.35 -
    5.36 -
    5.37 -let read_memory ctx addr len =
    5.38 -  match ctx with
    5.39 -  | Domain d  -> Domain.read_memory d addr len
    5.40 -  | _ -> raise (Unimplemented "read memory")
    5.41 -
    5.42 -let write_memory ctx addr values =
    5.43 -  match ctx with
    5.44 -  | Domain d  -> Domain.write_memory d addr values
    5.45 -  | _ -> raise (Unimplemented "write memory")
    5.46 -
    5.47 -
    5.48 -let continue ctx =
    5.49 -  match ctx with
    5.50 -  | Domain d  -> Domain.continue d
    5.51 -  | _ -> raise (Unimplemented "continue")
    5.52 -
    5.53 -let step ctx =
    5.54 -  match ctx with
    5.55 -  | Domain d  -> Domain.step d
    5.56 -  | _ -> raise (Unimplemented "step")
    5.57 -
    5.58 -
    5.59 -let insert_memory_breakpoint ctx addr len =
    5.60 -  match ctx with
    5.61 -  | Domain d  -> Domain.insert_memory_breakpoint d addr len
    5.62 -  | _ -> raise (Unimplemented "insert memory breakpoint")
    5.63 -
    5.64 -let remove_memory_breakpoint ctx addr len =
    5.65 -  match ctx with
    5.66 -  | Domain d  -> Domain.remove_memory_breakpoint d addr len
    5.67 -  | _ -> raise (Unimplemented "remove memory breakpoint")
    5.68 -
    5.69 -
    5.70 -let pause ctx =
    5.71 -  match ctx with
    5.72 -  | Domain d  -> Domain.pause d
    5.73 -  | _ -> raise (Unimplemented "pause target")
    5.74 +let hash = Hashtbl.create 10
    5.75  
    5.76  
    5.77 -let attach_debugger ctx =
    5.78 -  match ctx with
    5.79 -  | Domain d  -> Domain.attach_debugger (Domain.get_domain d) 
    5.80 -	                                (Domain.get_execution_domain d)
    5.81 -  | _ -> raise (Unimplemented "attach debugger")
    5.82 -
    5.83 -let detach_debugger ctx =
    5.84 -  match ctx with
    5.85 -  | Domain d  -> Domain.detach_debugger (Domain.get_domain d) 
    5.86 -	                                (Domain.get_execution_domain d)
    5.87 -  | _ -> raise (Unimplemented "detach debugger")
    5.88 -
    5.89 -external open_debugger : unit -> unit = "open_context"
    5.90 -external close_debugger : unit -> unit = "close_context"
    5.91 -
    5.92 -(* this is just the domains right now... expand to other contexts later *)
    5.93 -external debugger_status : unit -> unit = "debugger_status"
    5.94 -
    5.95 -
    5.96 -(***********************************************************)
    5.97 -
    5.98 -
    5.99 -let hash = Hashtbl.create 10
   5.100 -
   5.101 -let debug_contexts () =
   5.102 -  print_endline "context list:";
   5.103 -  let print_context key ctx = 
   5.104 -    match ctx with
   5.105 -    | Void -> print_endline (Printf.sprintf "  [%s] {void}" 
   5.106 -			       (Util.get_connection_info key))
   5.107 -    | Event_channel -> print_endline (Printf.sprintf "  [%s] {event_channel}" 
   5.108 -			       (Util.get_connection_info key))
   5.109 -    | Process p -> print_endline (Printf.sprintf "  [%s] %s" 
   5.110 -				    (Util.get_connection_info key)
   5.111 -				    (Process.string_of_context p))
   5.112 -    | Domain d -> print_endline (Printf.sprintf "  [%s] %s" 
   5.113 -				   (Util.get_connection_info key)
   5.114 -				   (Domain.string_of_context d))
   5.115 -  in
   5.116 -  Hashtbl.iter print_context hash
   5.117 -
   5.118 -(** add_context : add a new context to the hash table.
   5.119 - *  if there is an existing context for the same key then it 
   5.120 - *  is first removed implictly by the hash table replace function.
   5.121 - *)
   5.122 -let add_context (key:Unix.file_descr) context params =
   5.123 -  match context with
   5.124 -  | "void" -> Hashtbl.replace hash key Void
   5.125 -  | "event channel" -> Hashtbl.replace hash key Event_channel
   5.126 -  | "domain" -> 
   5.127 -      begin
   5.128 -	match params with
   5.129 -	| dom::exec_dom::_ ->
   5.130 -            let d = Domain(Domain.new_context dom exec_dom) in
   5.131 -	    attach_debugger d;
   5.132 -            Hashtbl.replace hash key d
   5.133 -	| _ -> failwith "bogus parameters to domain context"
   5.134 -      end
   5.135 -  | "process" -> 
   5.136 -      begin
   5.137 -	match params with
   5.138 -	| dom::pid::_ ->
   5.139 -	    let p = Process.new_context dom pid in
   5.140 -	    Hashtbl.replace hash key (Process(p))
   5.141 -	| _ -> failwith "bogus parameters to process context"
   5.142 -      end
   5.143 -  | _ -> raise (Unknown_context context)
   5.144 -
   5.145 -let add_default_context sock =
   5.146 -  add_context sock "void" []
   5.147 +(***************************************************************************)
   5.148  
   5.149  let find_context key =
   5.150    try
   5.151 @@ -158,16 +45,18 @@ let find_context key =
   5.152  let delete_context key =
   5.153    Hashtbl.remove hash key
   5.154  
   5.155 -(** find_domain : Locate the context(s) matching a particular domain 
   5.156 - *  and execution_domain pair.
   5.157 +(**
   5.158 +   find_domain : Locate the socket associated with the context(s)
   5.159 +   matching a particular (domain, vcpu) pair.  if there are multiple
   5.160 +   contexts (there shouldn't be), then return the first one.
   5.161   *)
   5.162  
   5.163 -let find_domain dom exec_dom =
   5.164 +let find_domain dom vcpu =
   5.165      let find key ctx list =
   5.166        match ctx with
   5.167        |	Domain d ->
   5.168  	  if (((Domain.get_domain d) = dom) &&
   5.169 -	      ((Domain.get_execution_domain d) = exec_dom))
   5.170 +	      ((Domain.get_execution_domain d) = vcpu))
   5.171  	  then
   5.172  	    key :: list
   5.173  	  else
   5.174 @@ -178,3 +67,186 @@ let find_domain dom exec_dom =
   5.175      match sock_list with
   5.176      | hd::tl -> hd
   5.177      | [] -> raise Unknown_domain
   5.178 +
   5.179 +(**
   5.180 +   find_xen_domain_context : fetch the socket associated with the
   5.181 +   xen_domain context for a domain.  if there are multiple contexts
   5.182 +   (there shouldn't be), then return the first one.
   5.183 + *)
   5.184 +
   5.185 +let find_xen_domain_context domain =
   5.186 +  let find key ctx list =
   5.187 +    match ctx with
   5.188 +      | Xen_domain d ->
   5.189 +	  if ((Xen_domain.get_domain d) = domain)
   5.190 +	  then
   5.191 +	    key :: list
   5.192 +	  else
   5.193 +	    list
   5.194 +      | _ -> list
   5.195 +  in
   5.196 +  let sock_list = Hashtbl.fold find hash [] in
   5.197 +  match sock_list with
   5.198 +    | hd::tl -> hd
   5.199 +    | [] -> raise Unknown_domain
   5.200 +
   5.201 +let attach_debugger ctx =
   5.202 +  match ctx with
   5.203 +  | Domain d  -> Domain.attach_debugger (Domain.get_domain d) 
   5.204 +	                                (Domain.get_execution_domain d)
   5.205 +  | Process p ->
   5.206 +      begin
   5.207 +	let xdom_sock = find_xen_domain_context (Process.get_domain p) in
   5.208 +	let xdom_ctx = find_context xdom_sock in
   5.209 +	match xdom_ctx with
   5.210 +	  | Xen_domain d ->
   5.211 +	      Process.attach_debugger p d
   5.212 +	  | _ -> failwith ("context has wrong xen domain type")
   5.213 +      end
   5.214 +  | _ -> raise (Unimplemented "attach debugger")
   5.215 +
   5.216 +let detach_debugger ctx =
   5.217 +  match ctx with
   5.218 +  | Domain d  -> Domain.detach_debugger (Domain.get_domain d) 
   5.219 +	                                (Domain.get_execution_domain d)
   5.220 +  | Process p  -> Process.detach_debugger p
   5.221 +  | _ -> raise (Unimplemented "detach debugger")
   5.222 +
   5.223 +
   5.224 +let debug_contexts () =
   5.225 +  print_endline "context list:";
   5.226 +  let print_context key ctx = 
   5.227 +    match ctx with
   5.228 +    | Void -> print_endline (Printf.sprintf "  [%s] {void}" 
   5.229 +			       (Util.get_connection_info key))
   5.230 +    | Xen_virq  -> print_endline (Printf.sprintf "  [%s] {xen virq evtchn}" 
   5.231 +	                          (Util.get_connection_info key))
   5.232 +    | Xen_xcs   -> print_endline (Printf.sprintf "  [%s] {xen xcs socket}" 
   5.233 +			          (Util.get_connection_info key))
   5.234 +    | Xen_domain d -> print_endline (Printf.sprintf "  [%s] %s" 
   5.235 +			          (Util.get_connection_info key) 
   5.236 +                                  (Xen_domain.string_of_context d))
   5.237 +    | Domain d  -> print_endline (Printf.sprintf "  [%s] %s" 
   5.238 +				  (Util.get_connection_info key)
   5.239 +				  (Domain.string_of_context d))
   5.240 +    | Process p -> print_endline (Printf.sprintf "  [%s] %s" 
   5.241 +				  (Util.get_connection_info key)
   5.242 +				  (Process.string_of_context p))
   5.243 +  in
   5.244 +  Hashtbl.iter print_context hash
   5.245 +
   5.246 +(** add_context : add a new context to the hash table.
   5.247 + *  if there is an existing context for the same key then it 
   5.248 + *  is first removed implictly by the hash table replace function.
   5.249 + *)
   5.250 +let add_context (key:Unix.file_descr) context params =
   5.251 +  match context with
   5.252 +  | "void"     -> Hashtbl.replace hash key Void
   5.253 +  | "xen virq" -> Hashtbl.replace hash key Xen_virq
   5.254 +  | "xen xcs"  -> Hashtbl.replace hash key Xen_xcs
   5.255 +  | "domain" -> 
   5.256 +      begin
   5.257 +	match params with
   5.258 +	| dom::vcpu::_ ->
   5.259 +            let d = Domain(Domain.new_context dom vcpu) in
   5.260 +	    attach_debugger d;
   5.261 +            Hashtbl.replace hash key d
   5.262 +	| _ -> failwith "bogus parameters to domain context"
   5.263 +      end
   5.264 +  | "process" -> 
   5.265 +      begin
   5.266 +	match params with
   5.267 +	| dom::pid::_ ->
   5.268 +	    let p = Process(Process.new_context dom pid) in
   5.269 +	    attach_debugger p;
   5.270 +	    Hashtbl.replace hash key p
   5.271 +	| _ -> failwith "bogus parameters to process context"
   5.272 +      end
   5.273 +  | "xen domain"
   5.274 +  | _ -> raise (Unknown_context context)
   5.275 +
   5.276 +(* 
   5.277 + * this is really bogus.  add_xen_domain_context should really
   5.278 + * be a case within add_context.  however, we need to pass in
   5.279 + * a pointer that can only be represented as an int32.
   5.280 + * this would require a different type for params... :(
   5.281 + * 31 bit integers suck.
   5.282 + *)
   5.283 +let add_xen_domain_context (key:Unix.file_descr) dom evtchn sring =
   5.284 +  let d = Xen_domain.new_context dom evtchn sring in
   5.285 +  Hashtbl.replace hash key (Xen_domain(d))
   5.286 +
   5.287 +
   5.288 +let add_default_context sock =
   5.289 +  add_context sock "void" []
   5.290 +
   5.291 +(***************************************************************************)
   5.292 +
   5.293 +(***************************************************************************)
   5.294 +
   5.295 +let read_registers ctx =
   5.296 +  match ctx with
   5.297 +  | Void -> Intel.null_registers                    (* default for startup *)
   5.298 +  | Domain d  -> Domain.read_registers d 
   5.299 +  | Process p -> Process.read_registers p
   5.300 +  | _ -> raise (Unimplemented "read registers")
   5.301 +
   5.302 +let write_register ctx register value =
   5.303 +  match ctx with
   5.304 +  | Domain d  -> Domain.write_register d register value
   5.305 +  | Process p -> Process.write_register p register value
   5.306 +  | _ -> raise (Unimplemented "write register")
   5.307 +
   5.308 +
   5.309 +let read_memory ctx addr len =
   5.310 +  match ctx with
   5.311 +  | Domain d  -> Domain.read_memory d addr len
   5.312 +  | Process p -> Process.read_memory p addr len
   5.313 +  | _ -> raise (Unimplemented "read memory")
   5.314 +
   5.315 +let write_memory ctx addr values =
   5.316 +  match ctx with
   5.317 +  | Domain d  -> Domain.write_memory d addr values
   5.318 +  | Process p -> Process.write_memory p addr values
   5.319 +  | _ -> raise (Unimplemented "write memory")
   5.320 +
   5.321 +
   5.322 +let continue ctx =
   5.323 +  match ctx with
   5.324 +  | Domain d  -> Domain.continue d
   5.325 +  | Process p  -> Process.continue p
   5.326 +  | _ -> raise (Unimplemented "continue")
   5.327 +
   5.328 +let step ctx =
   5.329 +  match ctx with
   5.330 +  | Domain d  -> Domain.step d
   5.331 +  | Process p  -> Process.step p
   5.332 +  | _ -> raise (Unimplemented "step")
   5.333 +
   5.334 +
   5.335 +let insert_memory_breakpoint ctx addr len =
   5.336 +  match ctx with
   5.337 +  | Domain d  -> Domain.insert_memory_breakpoint d addr len
   5.338 +  | Process p  -> Process.insert_memory_breakpoint p addr len
   5.339 +  | _ -> raise (Unimplemented "insert memory breakpoint")
   5.340 +
   5.341 +let remove_memory_breakpoint ctx addr len =
   5.342 +  match ctx with
   5.343 +  | Domain d  -> Domain.remove_memory_breakpoint d addr len
   5.344 +  | Process p  -> Process.remove_memory_breakpoint p addr len
   5.345 +  | _ -> raise (Unimplemented "remove memory breakpoint")
   5.346 +
   5.347 +
   5.348 +let pause ctx =
   5.349 +  match ctx with
   5.350 +  | Domain d  -> Domain.pause d
   5.351 +  | Process p  -> Process.pause p
   5.352 +  | _ -> raise (Unimplemented "pause target")
   5.353 +
   5.354 +
   5.355 +external open_debugger : unit -> unit = "open_context"
   5.356 +external close_debugger : unit -> unit = "close_context"
   5.357 +
   5.358 +(* this is just the domains right now... expand to other contexts later *)
   5.359 +external debugger_status : unit -> unit = "debugger_status"
   5.360 +
     6.1 --- a/tools/debugger/pdb/Process.ml	Mon Jun 27 20:17:02 2005 +0000
     6.2 +++ b/tools/debugger/pdb/Process.ml	Mon Jun 27 21:31:56 2005 +0000
     6.3 @@ -12,13 +12,16 @@ open Intel
     6.4  
     6.5  type context_t =
     6.6  {
     6.7 -  mutable domain : int;
     6.8 +  mutable domain  : int;
     6.9    mutable process : int;
    6.10 +  mutable evtchn  : int;
    6.11 +  mutable ring    : int32;
    6.12  }
    6.13  
    6.14 -let default_context = { domain = 0; process = 0 }
    6.15 +let default_context = { domain = 0; process = 0; evtchn = 0; ring = 0l }
    6.16  
    6.17 -let new_context dom proc = { domain = dom; process = proc }
    6.18 +let new_context dom proc = { domain = dom; process = proc; 
    6.19 +                             evtchn = 0; ring = 0l }
    6.20  
    6.21  let string_of_context ctx =
    6.22    Printf.sprintf "{process} domain: %d, process: %d"
    6.23 @@ -37,3 +40,35 @@ let get_domain ctx =
    6.24  
    6.25  let get_process ctx =
    6.26    ctx.process
    6.27 +
    6.28 +external _attach_debugger : context_t -> unit = "proc_attach_debugger"
    6.29 +external detach_debugger : context_t -> unit = "proc_detach_debugger"
    6.30 +external pause_target : context_t -> unit = "proc_pause_target"
    6.31 +
    6.32 +(* save the event channel and ring for the domain for future use *)
    6.33 +let attach_debugger proc_ctx dom_ctx =
    6.34 +  print_endline (Printf.sprintf "%d %lx"
    6.35 +    (Xen_domain.get_evtchn dom_ctx)
    6.36 +    (Xen_domain.get_ring dom_ctx));
    6.37 +  proc_ctx.evtchn <- Xen_domain.get_evtchn dom_ctx;
    6.38 +  proc_ctx.ring   <- Xen_domain.get_ring   dom_ctx;
    6.39 +  _attach_debugger proc_ctx
    6.40 +
    6.41 +external read_registers : context_t -> registers = "proc_read_registers"
    6.42 +external write_register : context_t -> register -> int32 -> unit =
    6.43 +  "proc_write_register"
    6.44 +external read_memory : context_t -> int32 -> int -> int list = 
    6.45 +  "proc_read_memory"
    6.46 +external write_memory : context_t -> int32 -> int list -> unit = 
    6.47 +  "proc_write_memory"
    6.48 +
    6.49 +external continue : context_t -> unit = "proc_continue_target"
    6.50 +external step : context_t -> unit = "proc_step_target"
    6.51 +
    6.52 +external insert_memory_breakpoint : context_t -> int32 -> int -> unit = 
    6.53 +  "proc_insert_memory_breakpoint"
    6.54 +external remove_memory_breakpoint : context_t -> int32 -> int -> unit = 
    6.55 +  "proc_remove_memory_breakpoint"
    6.56 +
    6.57 +let pause ctx =
    6.58 +  pause_target ctx
     7.1 --- a/tools/debugger/pdb/Process.mli	Mon Jun 27 20:17:02 2005 +0000
     7.2 +++ b/tools/debugger/pdb/Process.mli	Mon Jun 27 21:31:56 2005 +0000
     7.3 @@ -7,6 +7,9 @@
     7.4   *  @version 1
     7.5   *)
     7.6  
     7.7 +open Int32
     7.8 +open Intel
     7.9 +
    7.10  type context_t
    7.11  
    7.12  val default_context : context_t
    7.13 @@ -18,3 +21,19 @@ val set_process : context_t -> int -> un
    7.14  val get_process : context_t -> int
    7.15  
    7.16  val string_of_context : context_t -> string
    7.17 +
    7.18 +val attach_debugger : context_t -> Xen_domain.context_t -> unit
    7.19 +val detach_debugger : context_t -> unit
    7.20 +val pause : context_t -> unit
    7.21 +
    7.22 +
    7.23 +val read_registers : context_t -> registers
    7.24 +val write_register : context_t -> register -> int32 -> unit
    7.25 +val read_memory : context_t -> int32 -> int -> int list
    7.26 +val write_memory : context_t -> int32 -> int list -> unit
    7.27 +	
    7.28 +val continue : context_t -> unit
    7.29 +val step : context_t -> unit
    7.30 +
    7.31 +val insert_memory_breakpoint : context_t -> int32 -> int -> unit
    7.32 +val remove_memory_breakpoint : context_t -> int32 -> int -> unit
     8.1 --- a/tools/debugger/pdb/Util.ml	Mon Jun 27 20:17:02 2005 +0000
     8.2 +++ b/tools/debugger/pdb/Util.ml	Mon Jun 27 21:31:56 2005 +0000
     8.3 @@ -103,7 +103,7 @@ let get_connection_info fd =
     8.4    let get_local_info fd =
     8.5      let sockname = Unix.getsockname fd in
     8.6      match sockname with
     8.7 -    | Unix.ADDR_UNIX(s) -> s
     8.8 +    | Unix.ADDR_UNIX(s) -> "unix"
     8.9      | Unix.ADDR_INET(a,p) -> ((Unix.string_of_inet_addr a) ^ ":" ^
    8.10  			      (string_of_int p))
    8.11    and get_remote_info fd =
    8.12 @@ -119,6 +119,9 @@ let get_connection_info fd =
    8.13    | Unix.Unix_error (Unix.ENOTSOCK, s1, s2) -> 
    8.14        let s = Unix.fstat fd in
    8.15        Printf.sprintf "dev: %d, inode: %d" s.Unix.st_dev s.Unix.st_ino
    8.16 +  | Unix.Unix_error (Unix.EBADF, s1, s2) -> 
    8.17 +      let s = Unix.fstat fd in
    8.18 +      Printf.sprintf "dev: %d, inode: %d" s.Unix.st_dev s.Unix.st_ino
    8.19    | _ -> get_local_info fd
    8.20  
    8.21  
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/tools/debugger/pdb/Xen_domain.ml	Mon Jun 27 21:31:56 2005 +0000
     9.3 @@ -0,0 +1,35 @@
     9.4 +
     9.5 +type context_t =
     9.6 +{
     9.7 +  mutable domain : int;
     9.8 +  mutable evtchn : int;
     9.9 +  mutable pdb_front_ring : int32
    9.10 +}
    9.11 +
    9.12 +let default_context = { domain = 0; evtchn = 0; pdb_front_ring = 0l }
    9.13 +
    9.14 +let new_context dom evtchn ring = 
    9.15 +  {domain = dom; evtchn = evtchn; pdb_front_ring = ring}
    9.16 +
    9.17 +let set_domain ctx value =
    9.18 +  ctx.domain <- value
    9.19 +
    9.20 +let set_evtchn ctx value =
    9.21 +  ctx.evtchn <- value
    9.22 +
    9.23 +let set_ring ctx value =
    9.24 +  ctx.pdb_front_ring <- value
    9.25 +
    9.26 +let get_domain ctx =
    9.27 +  ctx.domain
    9.28 +
    9.29 +let get_evtchn ctx =
    9.30 +  ctx.evtchn
    9.31 +
    9.32 +let get_ring ctx =
    9.33 +  ctx.pdb_front_ring
    9.34 +
    9.35 +let string_of_context ctx =
    9.36 +      Printf.sprintf "{xen domain assist} domain: %d" ctx.domain 
    9.37 +
    9.38 +external process_response : int32 -> unit = "process_handle_response"
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/tools/debugger/pdb/Xen_domain.mli	Mon Jun 27 21:31:56 2005 +0000
    10.3 @@ -0,0 +1,17 @@
    10.4 +
    10.5 +type context_t
    10.6 +
    10.7 +val default_context : context_t
    10.8 +val new_context : int -> int -> int32 -> context_t 
    10.9 +
   10.10 +val set_domain : context_t -> int -> unit
   10.11 +val get_domain : context_t -> int
   10.12 +val set_evtchn : context_t -> int -> unit
   10.13 +val get_evtchn : context_t -> int
   10.14 +val set_ring   : context_t -> int32 -> unit
   10.15 +val get_ring   : context_t -> int32
   10.16 +
   10.17 +val string_of_context : context_t -> string
   10.18 +
   10.19 +val process_response : int32 -> unit
   10.20 +
    11.1 --- a/tools/debugger/pdb/debugger.ml	Mon Jun 27 20:17:02 2005 +0000
    11.2 +++ b/tools/debugger/pdb/debugger.ml	Mon Jun 27 21:31:56 2005 +0000
    11.3 @@ -77,7 +77,7 @@ let gdb_read_registers ctx =
    11.4      (Printf.sprintf "%08lx" (Util.flip_int32 regs.esi)) ^
    11.5      (Printf.sprintf "%08lx" (Util.flip_int32 regs.edi)) ^
    11.6      (Printf.sprintf "%08lx" (Util.flip_int32 regs.eip)) ^
    11.7 -    (Printf.sprintf "%08lx" (Util.flip_int32 regs.eflags)) ^
    11.8 +    (Printf.sprintf "%08lx" (Util.flip_int32 regs.efl)) ^
    11.9      (Printf.sprintf "%08lx" (Util.flip_int32 regs.cs)) ^
   11.10      (Printf.sprintf "%08lx" (Util.flip_int32 regs.ss)) ^
   11.11      (Printf.sprintf "%08lx" (Util.flip_int32 regs.ds)) ^
   11.12 @@ -140,7 +140,7 @@ let gdb_write_register ctx command =
   11.13      |  6 -> PDB.write_register ctx ESI new_val
   11.14      |  7 -> PDB.write_register ctx EDI new_val
   11.15      |  8 -> PDB.write_register ctx EIP new_val
   11.16 -    |  9 -> PDB.write_register ctx EFLAGS new_val
   11.17 +    |  9 -> PDB.write_register ctx EFL new_val
   11.18      | 10 -> PDB.write_register ctx CS new_val
   11.19      | 11 -> PDB.write_register ctx SS new_val
   11.20      | 12 -> PDB.write_register ctx DS new_val
   11.21 @@ -195,13 +195,15 @@ let gdb_last_signal =
   11.22   *)
   11.23  let pdb_extensions command sock =
   11.24    let process_extension key value =
   11.25 -    (* since this command can change the context, we need to grab it each time *)
   11.26 +    (* since this command can change the context, 
   11.27 +       we need to grab it again each time *)
   11.28      let ctx = PDB.find_context sock in
   11.29      match key with
   11.30      | "status" ->
   11.31 -	print_endline (string_of_context ctx);
   11.32  	PDB.debug_contexts ();
   11.33 -	debugger_status ()
   11.34 +	(* print_endline ("debugger status");
   11.35 +	   debugger_status () 
   11.36 +	*)
   11.37      | "context" ->
   11.38          PDB.add_context sock (List.hd value) 
   11.39                               (int_list_of_string_list (List.tl value))
   11.40 @@ -216,6 +218,7 @@ let pdb_extensions command sock =
   11.41    | Unknown_context s -> 
   11.42        print_endline (Printf.sprintf "unknown context [%s]" s);
   11.43        "E01"
   11.44 +  | Unknown_domain -> "E01"
   11.45    | Failure s -> "E01"
   11.46  
   11.47  
   11.48 @@ -274,27 +277,47 @@ let process_command command sock =
   11.49      | 'Z' -> gdb_insert_bwcpoint ctx command
   11.50      | _ -> 
   11.51  	print_endline (Printf.sprintf "unknown gdb command [%s]" command);
   11.52 -	""
   11.53 +	"E02"
   11.54    with
   11.55      Unimplemented s ->
   11.56        print_endline (Printf.sprintf "loser. unimplemented command [%s][%s]" 
   11.57  		                    command s);
   11.58 -      ""
   11.59 -
   11.60 +      "E03"
   11.61  
   11.62  (**
   11.63 -   process_evtchn  
   11.64 +   process_xen_domain
   11.65 +
   11.66 +   This is called whenever a domain debug assist responds to a
   11.67 +   pdb packet.
   11.68 +*)
   11.69 +
   11.70 +let process_xen_domain fd =
   11.71 +  let channel = Evtchn.read fd in
   11.72 +  let ctx = find_context fd in
   11.73 +  
   11.74 +  begin
   11.75 +    match ctx with
   11.76 +      | Xen_domain d -> Xen_domain.process_response (Xen_domain.get_ring d)
   11.77 +      | _ -> failwith ("process_xen_domain called without Xen_domain context")
   11.78 +  end;
   11.79 +    
   11.80 +  Evtchn.unmask fd channel                                (* allow next virq *)
   11.81 +  
   11.82 +
   11.83 +(**
   11.84 +   process_xen_virq
   11.85  
   11.86     This is called each time a virq_pdb is sent from xen to dom 0.
   11.87     It is sent by Xen when a domain hits a breakpoint. 
   11.88  
   11.89 -   Think of this as the continuation function for a "c" or "s" command.
   11.90 +   Think of this as the continuation function for a "c" or "s" command
   11.91 +   issued to a domain.
   11.92  *)
   11.93  
   11.94  external query_domain_stop : unit -> (int * int) list = "query_domain_stop"
   11.95  (* returns a list of paused domains : () -> (domain, vcpu) list *)
   11.96  
   11.97 -let process_evtchn fd =
   11.98 +let process_xen_virq fd =
   11.99    let channel = Evtchn.read fd in
  11.100    let find_pair (dom, vcpu) =
  11.101      print_endline (Printf.sprintf "checking %d.%d" dom vcpu);
  11.102 @@ -313,3 +336,17 @@ let process_evtchn fd =
  11.103    Util.send_reply sock "S05";
  11.104    Evtchn.unmask fd channel                                (* allow next virq *)
  11.105    
  11.106 +
  11.107 +(**
  11.108 +   process_xen_xcs
  11.109 +
  11.110 +   This is called each time the software assist residing in a backend 
  11.111 +   domain starts up.  The control message includes the address of a 
  11.112 +   shared ring page and our end of an event channel (which indicates
  11.113 +   when data is available on the ring).
  11.114 +*)
  11.115 +
  11.116 +let process_xen_xcs xcs_fd =
  11.117 +  let (local_evtchn_fd, evtchn, dom, ring) = Xcs.read xcs_fd in
  11.118 +  add_xen_domain_context local_evtchn_fd dom evtchn ring;
  11.119 +  local_evtchn_fd
    12.1 --- a/tools/debugger/pdb/evtchn.ml	Mon Jun 27 20:17:02 2005 +0000
    12.2 +++ b/tools/debugger/pdb/evtchn.ml	Mon Jun 27 21:31:56 2005 +0000
    12.3 @@ -14,6 +14,7 @@ let dev_minor = 201                     
    12.4  let virq_pdb = 6                                      (* as defined VIRQ_PDB *)
    12.5  
    12.6  external bind_virq : int -> int = "evtchn_bind_virq"
    12.7 +external bind_interdomain : int -> int * int = "evtchn_bind_interdomain"
    12.8  external bind : Unix.file_descr -> int -> unit = "evtchn_bind"
    12.9  external unbind : Unix.file_descr -> int -> unit = "evtchn_unbind"
   12.10  external ec_open : string -> int -> int -> Unix.file_descr = "evtchn_open"
   12.11 @@ -21,10 +22,17 @@ external read : Unix.file_descr -> int =
   12.12  external ec_close : Unix.file_descr -> unit = "evtchn_close"
   12.13  external unmask : Unix.file_descr -> int -> unit = "evtchn_unmask"
   12.14  
   12.15 +let _setup () =
   12.16 +  let fd = ec_open dev_name dev_major dev_minor in
   12.17 +  fd
   12.18 +
   12.19 +let _bind fd port =
   12.20 +  bind fd port
   12.21 +
   12.22  let setup () =
   12.23    let port = bind_virq virq_pdb in
   12.24 -  let fd = ec_open dev_name dev_major dev_minor in
   12.25 -  bind fd port;
   12.26 +  let fd = _setup() in
   12.27 +  _bind fd port;
   12.28    fd
   12.29  
   12.30  let teardown fd =
    13.1 --- a/tools/debugger/pdb/evtchn.mli	Mon Jun 27 20:17:02 2005 +0000
    13.2 +++ b/tools/debugger/pdb/evtchn.mli	Mon Jun 27 21:31:56 2005 +0000
    13.3 @@ -7,6 +7,11 @@
    13.4   *  @version 1
    13.5   *)
    13.6  
    13.7 +val _setup : unit -> Unix.file_descr
    13.8 +val _bind : Unix.file_descr -> int -> unit
    13.9 +
   13.10 +val bind_interdomain : int -> int * int
   13.11 +
   13.12  
   13.13  val setup : unit -> Unix.file_descr
   13.14  val read : Unix.file_descr -> int
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/tools/debugger/pdb/linux-2.6-module/Makefile	Mon Jun 27 21:31:56 2005 +0000
    14.3 @@ -0,0 +1,18 @@
    14.4 +XEN_ROOT=/anfs/nos1/ach61/bk
    14.5 +KDIR=$(XEN_ROOT)/linux-2.6.11-xenU
    14.6 +
    14.7 +obj-m    += pdb.o
    14.8 +pdb-objs += module.o
    14.9 +pdb-objs += debug.o
   14.10 +
   14.11 +CFLAGS += -g
   14.12 +CFLAGS += -Wall
   14.13 +CFLAGS += -Werror
   14.14 +
   14.15 +module : 
   14.16 +#	make KBUILD_VERBOSE=1 ARCH=xen -C $(KDIR) M=$(PWD) modules
   14.17 +	make                  ARCH=xen -C $(KDIR) M=$(PWD) modules
   14.18 +
   14.19 +clean :
   14.20 +	make -C $(KDIR) M=$(PWD) clean
   14.21 +
    15.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.2 +++ b/tools/debugger/pdb/linux-2.6-module/debug.c	Mon Jun 27 21:31:56 2005 +0000
    15.3 @@ -0,0 +1,169 @@
    15.4 +/*
    15.5 + * debug.c
    15.6 + * pdb debug functionality for processes.
    15.7 + */
    15.8 +
    15.9 +
   15.10 +#include <linux/module.h>
   15.11 +#include <linux/sched.h>
   15.12 +#include <asm-xen/asm-i386/ptrace.h>
   15.13 +#include <asm-xen/xen-public/xen.h>
   15.14 +
   15.15 +#include "pdb_module.h"
   15.16 +
   15.17 +EXPORT_SYMBOL(pdb_attach);
   15.18 +EXPORT_SYMBOL(pdb_detach);
   15.19 +
   15.20 +int
   15.21 +pdb_attach (int pid)
   15.22 +{
   15.23 +    struct task_struct *target;
   15.24 +    u32 rc = 0;
   15.25 +
   15.26 +    printk ("pdb attach: 0x%x\n", pid);
   15.27 +
   15.28 +    read_lock(&tasklist_lock);
   15.29 +    target = find_task_by_pid(pid);
   15.30 +    if (target)
   15.31 +        get_task_struct(target);
   15.32 +    read_unlock(&tasklist_lock);
   15.33 +
   15.34 +    force_sig(SIGSTOP, target);                    /* force_sig_specific ??? */
   15.35 +
   15.36 +    return rc;
   15.37 +}
   15.38 +
   15.39 +int
   15.40 +pdb_detach (int pid)
   15.41 +{
   15.42 +    int rc = 0;
   15.43 +    struct task_struct *target;
   15.44 +
   15.45 +    printk ("pdb detach: 0x%x\n", pid);
   15.46 +
   15.47 +    read_lock(&tasklist_lock);
   15.48 +    target = find_task_by_pid(pid);
   15.49 +    if (target)
   15.50 +        get_task_struct(target);
   15.51 +    read_unlock(&tasklist_lock);
   15.52 +
   15.53 +    wake_up_process(target);
   15.54 +
   15.55 +    return rc;
   15.56 +}
   15.57 +
   15.58 +/*
   15.59 + * from linux-2.6.11/arch/i386/kernel/ptrace.c::getreg()
   15.60 + */
   15.61 +int
   15.62 +pdb_read_register (int pid, pdb_op_rd_reg_p op, unsigned long *dest)
   15.63 +{
   15.64 +    int rc = 0;
   15.65 +    struct task_struct *target;
   15.66 +    unsigned long offset;
   15.67 +    unsigned char *stack = 0L;
   15.68 +
   15.69 +    *dest = ~0UL;
   15.70 +
   15.71 +    read_lock(&tasklist_lock);
   15.72 +    target = find_task_by_pid(pid);
   15.73 +    if (target)
   15.74 +        get_task_struct(target);
   15.75 +    read_unlock(&tasklist_lock);
   15.76 +
   15.77 +    switch (op->reg)
   15.78 +    {
   15.79 +    case FS:
   15.80 +        *dest = target->thread.fs;
   15.81 +        break;
   15.82 +    case GS:
   15.83 +        *dest = target->thread.gs;
   15.84 +        break;
   15.85 +    case DS:
   15.86 +    case ES:
   15.87 +    case SS:
   15.88 +    case CS:
   15.89 +        *dest = 0xffff;
   15.90 +        /* fall through */
   15.91 +    default:
   15.92 +        if (op->reg > GS)
   15.93 +            op->reg -= 2;
   15.94 +
   15.95 +        offset = op->reg * sizeof(long);
   15.96 +        offset -= sizeof(struct pt_regs);
   15.97 +        stack = (unsigned char *)target->thread.esp0;
   15.98 +        stack += offset;
   15.99 +        *dest &= *((int *)stack);
  15.100 +    }
  15.101 +
  15.102 +    /*
  15.103 +    printk ("pdb read register: 0x%x %2d 0x%p 0x%lx\n", 
  15.104 +            pid, op->reg, stack, *dest);
  15.105 +    */
  15.106 +
  15.107 +    return rc;
  15.108 +}
  15.109 +
  15.110 +/*
  15.111 + * from linux-2.6.11/arch/i386/kernel/ptrace.c::putreg()
  15.112 + */
  15.113 +int
  15.114 +pdb_write_register (int pid, pdb_op_wr_reg_p op)
  15.115 +{
  15.116 +    int rc = 0;
  15.117 +    struct task_struct *target;
  15.118 +    unsigned long offset;
  15.119 +    unsigned char *stack;
  15.120 +    unsigned long value = op->value;
  15.121 +
  15.122 +    /*
  15.123 +    printk ("pdb write register: 0x%x %2d 0x%lx\n", pid, op->reg, value);
  15.124 +    */
  15.125 +
  15.126 +    read_lock(&tasklist_lock);
  15.127 +    target = find_task_by_pid(pid);
  15.128 +    if (target)
  15.129 +        get_task_struct(target);
  15.130 +    read_unlock(&tasklist_lock);
  15.131 +
  15.132 +    switch (op->reg)
  15.133 +    {
  15.134 +    case FS:
  15.135 +        target->thread.fs = value;
  15.136 +        return rc;
  15.137 +    case GS:
  15.138 +        target->thread.gs = value;
  15.139 +        return rc;
  15.140 +    case DS:
  15.141 +    case ES:
  15.142 +        value &= 0xffff;
  15.143 +        break;
  15.144 +    case SS:
  15.145 +    case CS:
  15.146 +        value &= 0xffff;
  15.147 +        break;
  15.148 +    case EFL:
  15.149 +        break;
  15.150 +    }
  15.151 +
  15.152 +    if (op->reg > GS)
  15.153 +        op->reg -= 2;
  15.154 +    offset = op->reg * sizeof(long);
  15.155 +    offset -= sizeof(struct pt_regs);
  15.156 +    stack = (unsigned char *)target->thread.esp0;
  15.157 +    stack += offset;
  15.158 +    *(unsigned long *) stack = op->value;
  15.159 +
  15.160 +    return rc;
  15.161 +}
  15.162 +
  15.163 +/*
  15.164 + * Local variables:
  15.165 + * mode: C
  15.166 + * c-set-style: "BSD"
  15.167 + * c-basic-offset: 4
  15.168 + * tab-width: 4
  15.169 + * indent-tabs-mode: nil
  15.170 + * End:
  15.171 + */
  15.172 +
    16.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.2 +++ b/tools/debugger/pdb/linux-2.6-module/module.c	Mon Jun 27 21:31:56 2005 +0000
    16.3 @@ -0,0 +1,226 @@
    16.4 +
    16.5 +/*
    16.6 + * module.c
    16.7 + *
    16.8 + * Handles initial registration with pdb when the pdb module starts up
    16.9 + * and cleanup when the module goes away (sortof :)
   16.10 + * Also receives each request from pdb in domain 0 and dispatches to the
   16.11 + * appropriate debugger function.
   16.12 + */
   16.13 +
   16.14 +#include <linux/module.h>
   16.15 +#include <linux/interrupt.h>
   16.16 +
   16.17 +#include <asm-xen/evtchn.h>
   16.18 +#include <asm-xen/ctrl_if.h>
   16.19 +#include <asm-xen/hypervisor.h>
   16.20 +#include <asm-xen/xen-public/io/domain_controller.h>
   16.21 +#include <asm-xen/xen-public/xen.h>
   16.22 +
   16.23 +#include <asm-xen/xen-public/io/ring.h>
   16.24 +
   16.25 +#include "pdb_module.h"
   16.26 +
   16.27 +#define PDB_RING_SIZE __RING_SIZE((pdb_sring_t *)0, PAGE_SIZE)
   16.28 +
   16.29 +static pdb_back_ring_t pdb_ring;
   16.30 +static unsigned int    pdb_evtchn;
   16.31 +static unsigned int    pdb_irq;
   16.32 +
   16.33 +/*
   16.34 + * send response to a pdb request
   16.35 + */
   16.36 +static void
   16.37 +pdb_send_response (pdb_response_t *response)
   16.38 +{
   16.39 +    pdb_response_t *resp;
   16.40 +
   16.41 +    resp = RING_GET_RESPONSE(&pdb_ring, pdb_ring.rsp_prod_pvt);
   16.42 +
   16.43 +    memcpy(resp, response, sizeof(pdb_response_t));
   16.44 +    
   16.45 +    wmb();                 /* Ensure other side can see the response fields. */
   16.46 +    pdb_ring.rsp_prod_pvt++;
   16.47 +    RING_PUSH_RESPONSES(&pdb_ring);
   16.48 +    notify_via_evtchn(pdb_evtchn);
   16.49 +    return;
   16.50 +}
   16.51 +
   16.52 +/*
   16.53 + * handle a debug command from the front end
   16.54 + */
   16.55 +static void
   16.56 +pdb_process_request (pdb_request_t *request)
   16.57 +{
   16.58 +    pdb_response_t resp;
   16.59 +
   16.60 +    switch (request->operation)
   16.61 +    {
   16.62 +    case PDB_OPCODE_ATTACH :
   16.63 +        pdb_attach(request->process);
   16.64 +        resp.status = PDB_RESPONSE_OKAY;
   16.65 +        break;
   16.66 +    case PDB_OPCODE_DETACH :
   16.67 +        pdb_detach(request->process);
   16.68 +        resp.status = PDB_RESPONSE_OKAY;
   16.69 +        break;
   16.70 +    case PDB_OPCODE_RD_REG :
   16.71 +        pdb_read_register(request->process, &request->u.rd_reg, 
   16.72 +                          (unsigned long *)&resp.value);
   16.73 +        resp.status = PDB_RESPONSE_OKAY;
   16.74 +        break;
   16.75 +    case PDB_OPCODE_WR_REG :
   16.76 +        pdb_write_register(request->process, &request->u.wr_reg);
   16.77 +        resp.status = PDB_RESPONSE_OKAY;
   16.78 +        break;
   16.79 +    default:
   16.80 +        printk("(pdb) unknown request operation %d\n", request->operation);
   16.81 +        resp.status = PDB_RESPONSE_ERROR;
   16.82 +    }
   16.83 +        
   16.84 +    resp.operation = request->operation;
   16.85 +            
   16.86 +    pdb_send_response (&resp);
   16.87 +    return;
   16.88 +}
   16.89 +
   16.90 +/*
   16.91 + * receive a pdb request
   16.92 + */
   16.93 +static irqreturn_t
   16.94 +pdb_interrupt (int irq, void *dev_id, struct pt_regs *ptregs)
   16.95 +{
   16.96 +    pdb_request_t *req;
   16.97 +    RING_IDX i, rp;
   16.98 +
   16.99 +    rp = pdb_ring.sring->req_prod;
  16.100 +    rmb();
  16.101 +
  16.102 +    for ( i = pdb_ring.req_cons; 
  16.103 +          (i != rp) && !RING_REQUEST_CONS_OVERFLOW(&pdb_ring, i);
  16.104 +          i++ )
  16.105 +    {
  16.106 +        req = RING_GET_REQUEST(&pdb_ring, i);
  16.107 +        pdb_process_request(req);
  16.108 +
  16.109 +    }
  16.110 +    pdb_ring.req_cons = i;
  16.111 +
  16.112 +    return IRQ_HANDLED;
  16.113 +}
  16.114 +
  16.115 +
  16.116 +static void
  16.117 +pdb_send_connection_status(int status, memory_t ring)
  16.118 +{
  16.119 +    ctrl_msg_t cmsg = 
  16.120 +    {
  16.121 +        .type = CMSG_DEBUG,
  16.122 +        .subtype = CMSG_DEBUG_CONNECTION_STATUS,
  16.123 +        .length  = sizeof(pdb_connection_t),
  16.124 +    };
  16.125 +    pdb_connection_t *conn = (pdb_connection_t *)cmsg.msg;
  16.126 +
  16.127 +    conn->status = status;
  16.128 +    conn->ring = ring;
  16.129 +    conn->evtchn = 0;
  16.130 +
  16.131 +    ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE);
  16.132 +}
  16.133 +
  16.134 +
  16.135 +/*
  16.136 + * this is called each time a message is received on the control channel
  16.137 + */
  16.138 +static void
  16.139 +pdb_ctrlif_rx(ctrl_msg_t *msg, unsigned long id)
  16.140 +{
  16.141 +printk ("pdb ctrlif rx\n");
  16.142 +
  16.143 +    switch (msg->subtype)
  16.144 +    {
  16.145 +    case CMSG_DEBUG_CONNECTION_STATUS:
  16.146 +        /* initialize event channel created by the pdb server */
  16.147 +
  16.148 +        pdb_evtchn = ((pdb_connection_p) msg->msg)->evtchn;
  16.149 +        pdb_irq = bind_evtchn_to_irq(pdb_evtchn);
  16.150 +
  16.151 +        if ( request_irq(pdb_irq, pdb_interrupt, 
  16.152 +                         SA_SAMPLE_RANDOM, "pdb", NULL) )
  16.153 +        {
  16.154 +            printk("(pdb) request irq failed: %d %d\n", pdb_evtchn, pdb_irq);
  16.155 +        }
  16.156 +        break;
  16.157 +
  16.158 +    default:
  16.159 +        printk ("(pdb) unknown xcs control message: %d\n", msg->subtype);
  16.160 +        break;
  16.161 +    }
  16.162 +
  16.163 +    return;
  16.164 +}
  16.165 +
  16.166 +static int __init 
  16.167 +pdb_initialize(void)
  16.168 +{
  16.169 +    pdb_sring_t *sring;
  16.170 +
  16.171 +    printk("----\npdb initialize   %s %s\n", __DATE__, __TIME__);
  16.172 +
  16.173 +    /*
  16.174 +    if ( xen_start_info.flags & SIF_INITDOMAIN )
  16.175 +        return 1;
  16.176 +    */
  16.177 +
  16.178 +    (void)ctrl_if_register_receiver(CMSG_DEBUG, pdb_ctrlif_rx,
  16.179 +                                    CALLBACK_IN_BLOCKING_CONTEXT);
  16.180 +
  16.181 +    /* rings */
  16.182 +    sring = (pdb_sring_t *)__get_free_page(GFP_KERNEL);
  16.183 +    SHARED_RING_INIT(sring);
  16.184 +    BACK_RING_INIT(&pdb_ring, sring, PAGE_SIZE);
  16.185 + 
  16.186 +    /* notify pdb in dom 0 */
  16.187 +    pdb_send_connection_status(PDB_CONNECTION_STATUS_UP, 
  16.188 +                               virt_to_machine(pdb_ring.sring) >> PAGE_SHIFT);
  16.189 +
  16.190 +    return 0;
  16.191 +}
  16.192 +
  16.193 +static void __exit
  16.194 +pdb_terminate(void)
  16.195 +{
  16.196 +    printk("pdb cleanup\n");
  16.197 +
  16.198 +    (void)ctrl_if_unregister_receiver(CMSG_DEBUG, pdb_ctrlif_rx);
  16.199 +
  16.200 +    if (pdb_irq)
  16.201 +    {
  16.202 +        free_irq(pdb_irq, NULL);
  16.203 +        pdb_irq = 0;
  16.204 +    }
  16.205 +
  16.206 +    if (pdb_evtchn)
  16.207 +    {
  16.208 +        unbind_evtchn_from_irq(pdb_evtchn); 
  16.209 +        pdb_evtchn = 0;
  16.210 +    }
  16.211 +
  16.212 +    pdb_send_connection_status(PDB_CONNECTION_STATUS_DOWN, 0);
  16.213 +}
  16.214 +
  16.215 +
  16.216 +module_init(pdb_initialize);
  16.217 +module_exit(pdb_terminate);
  16.218 +
  16.219 +
  16.220 +/*
  16.221 + * Local variables:
  16.222 + * mode: C
  16.223 + * c-set-style: "BSD"
  16.224 + * c-basic-offset: 4
  16.225 + * tab-width: 4
  16.226 + * indent-tabs-mode: nil
  16.227 + * End:
  16.228 + */
  16.229 +
    17.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.2 +++ b/tools/debugger/pdb/linux-2.6-module/pdb_module.h	Mon Jun 27 21:31:56 2005 +0000
    17.3 @@ -0,0 +1,65 @@
    17.4 +
    17.5 +#ifndef __XEN_PDB_H_
    17.6 +#define __XEN_PDB_H_
    17.7 +
    17.8 +#define PDB_OPCODE_ATTACH 1
    17.9 +#define PDB_OPCODE_DETACH 2
   17.10 +
   17.11 +#define PDB_OPCODE_RD_REG 3
   17.12 +typedef struct pdb_op_rd_reg
   17.13 +{
   17.14 +    u32 reg;
   17.15 +} pdb_op_rd_reg_t, *pdb_op_rd_reg_p;
   17.16 +
   17.17 +#define PDB_OPCODE_WR_REG 4
   17.18 +typedef struct pdb_op_wr_reg
   17.19 +{
   17.20 +    u32 reg;
   17.21 +    u32 value;
   17.22 +} pdb_op_wr_reg_t, *pdb_op_wr_reg_p;
   17.23 +
   17.24 +typedef struct 
   17.25 +{
   17.26 +    u8   operation;       /* PDB_OPCODE_???      */
   17.27 +    u32  domain;
   17.28 +    u32  process;
   17.29 +    union
   17.30 +    {
   17.31 +        pdb_op_rd_reg_t rd_reg;
   17.32 +        pdb_op_wr_reg_t wr_reg;
   17.33 +    } u;
   17.34 +} PACKED pdb_request_t, *pdb_request_p;
   17.35 + 
   17.36 +
   17.37 +#define PDB_RESPONSE_OKAY   0
   17.38 +#define PDB_RESPONSE_ERROR -1
   17.39 +
   17.40 +typedef struct {
   17.41 +    u8   operation;       /* copied from request */
   17.42 +    s16  status;          /* PDB_RESPONSE_???    */
   17.43 +    u32  value;
   17.44 +} PACKED pdb_response_t, *pdb_response_p;
   17.45 +
   17.46 +
   17.47 +DEFINE_RING_TYPES(pdb, pdb_request_t, pdb_response_t);
   17.48 +
   17.49 +
   17.50 +int pdb_attach (int pid);
   17.51 +int pdb_detach (int pid);
   17.52 +int pdb_read_register (int pid, pdb_op_rd_reg_p op, unsigned long *dest);
   17.53 +int pdb_write_register (int pid, pdb_op_wr_reg_p op);
   17.54 +
   17.55 +
   17.56 +#endif
   17.57 +
   17.58 +
   17.59 +/*
   17.60 + * Local variables:
   17.61 + * mode: C
   17.62 + * c-set-style: "BSD"
   17.63 + * c-basic-offset: 4
   17.64 + * tab-width: 4
   17.65 + * indent-tabs-mode: nil
   17.66 + * End:
   17.67 + */
   17.68 +
    18.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.2 +++ b/tools/debugger/pdb/pdb_caml_domain.c	Mon Jun 27 21:31:56 2005 +0000
    18.3 @@ -0,0 +1,485 @@
    18.4 +/*
    18.5 + * pdb_caml_xc.c
    18.6 + *
    18.7 + * http://www.cl.cam.ac.uk/netos/pdb
    18.8 + *
    18.9 + * PDB's OCaml interface library for debugging domains
   18.10 + */
   18.11 +
   18.12 +#include <xc.h>
   18.13 +#include <xendebug.h>
   18.14 +#include <errno.h>
   18.15 +#include <stdio.h>
   18.16 +#include <stdlib.h>
   18.17 +#include <string.h>
   18.18 +#include <sys/mman.h>
   18.19 +#include <caml/alloc.h>
   18.20 +#include <caml/fail.h>
   18.21 +#include <caml/memory.h>
   18.22 +#include <caml/mlvalues.h>
   18.23 +
   18.24 +#include "pdb_caml_xen.h"
   18.25 +
   18.26 +/* this order comes from xen/include/public/arch-x86_32.h */
   18.27 +enum x86_registers { PDB_EBX, PDB_ECX, PDB_EDX, PDB_ESI, PDB_EDI,
   18.28 +                     PDB_EBP, PDB_EAX, PDB_Error_code, PDB_Entry_vector, 
   18.29 +                     PDB_EIP, PDB_CS, PDB_EFLAGS, PDB_ESP, PDB_SS,
   18.30 +                     PDB_ES, PDB_DS, PDB_FS, PDB_GS };
   18.31 +
   18.32 +typedef struct
   18.33 +{
   18.34 +    int domain;
   18.35 +    int vcpu;
   18.36 +} context_t;
   18.37 +
   18.38 +#define decode_context(_ctx, _ocaml)   \
   18.39 +{  \
   18.40 +    (_ctx)->domain = Int_val(Field((_ocaml),0));  \
   18.41 +    (_ctx)->vcpu = Int_val(Field((_ocaml),1));  \
   18.42 +}
   18.43 +
   18.44 +#define encode_context(_ctx, _ocaml)  \
   18.45 +{  \
   18.46 +    (_ocaml) = caml_alloc_tuple(2);  \
   18.47 +    Store_field((_ocaml), 0, Val_int((_ctx)->domain));  \
   18.48 +    Store_field((_ocaml), 1, Val_int((_ctx)->vcpu));  \
   18.49 +}
   18.50 +
   18.51 +
   18.52 +/****************************************************************************/
   18.53 +
   18.54 +/*
   18.55 + * dom_read_registers : context_t -> int32
   18.56 + */
   18.57 +value
   18.58 +dom_read_registers (value context)
   18.59 +{
   18.60 +    CAMLparam1(context);
   18.61 +    CAMLlocal1(result);
   18.62 +
   18.63 +    cpu_user_regs_t *regs;
   18.64 +    context_t ctx;
   18.65 +
   18.66 +    decode_context(&ctx, context);
   18.67 +
   18.68 +    if ( xendebug_read_registers(xc_handle, ctx.domain, ctx.vcpu, &regs) )
   18.69 +    {
   18.70 +        printf("(pdb) read registers error!\n");  fflush(stdout);
   18.71 +        failwith("read registers error");
   18.72 +    }
   18.73 +
   18.74 +    dump_regs(regs);
   18.75 +
   18.76 +    result = caml_alloc_tuple(16);
   18.77 +
   18.78 +    Store_field(result,  0, caml_copy_int32(regs->eax));
   18.79 +    Store_field(result,  1, caml_copy_int32(regs->ecx));
   18.80 +    Store_field(result,  2, caml_copy_int32(regs->edx));
   18.81 +    Store_field(result,  3, caml_copy_int32(regs->ebx));
   18.82 +    Store_field(result,  4, caml_copy_int32(regs->esp));
   18.83 +    Store_field(result,  5, caml_copy_int32(regs->ebp));
   18.84 +    Store_field(result,  6, caml_copy_int32(regs->esi));
   18.85 +    Store_field(result,  7, caml_copy_int32(regs->edi));
   18.86 +    Store_field(result,  8, caml_copy_int32(regs->eip));
   18.87 +    Store_field(result,  9, caml_copy_int32(regs->eflags));
   18.88 +    Store_field(result, 10, caml_copy_int32(regs->cs));                /* 16 */
   18.89 +    Store_field(result, 11, caml_copy_int32(regs->ss));                /* 16 */
   18.90 +    Store_field(result, 12, caml_copy_int32(regs->ds));                /* 16 */
   18.91 +    Store_field(result, 13, caml_copy_int32(regs->es));                /* 16 */
   18.92 +    Store_field(result, 14, caml_copy_int32(regs->fs));                /* 16 */
   18.93 +    Store_field(result, 15, caml_copy_int32(regs->gs));                /* 16 */
   18.94 +
   18.95 +    CAMLreturn(result);
   18.96 +}
   18.97 +
   18.98 +
   18.99 +/*
  18.100 + * dom_write_register : context_t -> register -> int32 -> unit
  18.101 + */
  18.102 +value
  18.103 +dom_write_register (value context, value reg, value newval)
  18.104 +{
  18.105 +    CAMLparam3(context, reg, newval);
  18.106 +
  18.107 +    int my_reg = Int_val(reg);
  18.108 +    int val = Int32_val(newval);
  18.109 +
  18.110 +    context_t ctx;
  18.111 +    cpu_user_regs_t *regs;
  18.112 +
  18.113 +    printf("(pdb) write register\n");
  18.114 +
  18.115 +    decode_context(&ctx, context);
  18.116 +
  18.117 +    if ( xendebug_read_registers(xc_handle, ctx.domain, ctx.vcpu, &regs) )
  18.118 +    {
  18.119 +        printf("(pdb) write register (get) error!\n");  fflush(stdout);
  18.120 +        failwith("write register error");
  18.121 +    }
  18.122 +
  18.123 +    switch (my_reg)
  18.124 +    {
  18.125 +    case PDB_EBX: regs->ebx = val; break;
  18.126 +    case PDB_ECX: regs->ecx = val; break;
  18.127 +    case PDB_EDX: regs->edx = val; break;
  18.128 +    case PDB_ESI: regs->esi = val; break;
  18.129 +    case PDB_EDI: regs->edi = val; break;
  18.130 +
  18.131 +    case PDB_EBP: regs->ebp = val; break;
  18.132 +    case PDB_EAX: regs->eax = val; break;
  18.133 +    case PDB_Error_code: regs->error_code = val; break;
  18.134 +    case PDB_Entry_vector: regs->entry_vector = val; break;
  18.135 + 
  18.136 +    case PDB_EIP: regs->eip = val; break;
  18.137 +    case PDB_CS:  regs->cs  = val; break;
  18.138 +    case PDB_EFLAGS: regs->eflags = val; break;
  18.139 +    case PDB_ESP: regs->esp = val; break;
  18.140 +    case PDB_SS:  regs->ss  = val; break;
  18.141 +    case PDB_ES:  regs->es  = val; break;
  18.142 +    case PDB_DS:  regs->ds  = val; break;
  18.143 +    case PDB_FS:  regs->fs  = val; break;
  18.144 +    case PDB_GS:  regs->gs  = val; break;
  18.145 +    }
  18.146 +
  18.147 +    if ( xendebug_write_registers(xc_handle, ctx.domain, ctx.vcpu, regs) )
  18.148 +    {
  18.149 +        printf("(pdb) write register (set) error!\n");  fflush(stdout);
  18.150 +        failwith("write register error");
  18.151 +    }
  18.152 +
  18.153 +    CAMLreturn(Val_unit);
  18.154 +}
  18.155 +
  18.156 +/*
  18.157 + * dom_read_memory : context_t -> int32 -> int -> int
  18.158 + */
  18.159 +value
  18.160 +dom_read_memory (value context, value address, value length)
  18.161 +{
  18.162 +    CAMLparam3(context, address, length);
  18.163 +    CAMLlocal2(result, temp);
  18.164 +
  18.165 +    context_t ctx;
  18.166 +    int loop;
  18.167 +    char *buffer;
  18.168 +    memory_t my_address = Int32_val(address);
  18.169 +    u32 my_length = Int_val(length);
  18.170 +
  18.171 +    printf ("(pdb) read memory\n");
  18.172 +
  18.173 +    decode_context(&ctx, context);
  18.174 +
  18.175 +    buffer = malloc(my_length);
  18.176 +    if ( buffer == NULL )
  18.177 +    {
  18.178 +        printf("(pdb) read memory: malloc failed.\n");  fflush(stdout);
  18.179 +        failwith("read memory error");
  18.180 +    }
  18.181 +
  18.182 +    if ( xendebug_read_memory(xc_handle, ctx.domain, ctx.vcpu, 
  18.183 +                              my_address, my_length, buffer) )
  18.184 +    {
  18.185 +        printf("(pdb) read memory error!\n");  fflush(stdout);
  18.186 +        failwith("read memory error");
  18.187 +    }
  18.188 +
  18.189 +    result = caml_alloc(2,0);
  18.190 +    if ( my_length > 0 )                                              /* car */
  18.191 +    {
  18.192 +        Store_field(result, 0, Val_int(buffer[my_length - 1] & 0xff));
  18.193 +    }
  18.194 +    else
  18.195 +
  18.196 +    {
  18.197 +        Store_field(result, 0, Val_int(0));                    
  18.198 +    }
  18.199 +    Store_field(result, 1, Val_int(0));                               /* cdr */
  18.200 +
  18.201 +    for (loop = 1; loop < my_length; loop++)
  18.202 +    {
  18.203 +        temp = result;
  18.204 +        result = caml_alloc(2,0);
  18.205 +        Store_field(result, 0, Val_int(buffer[my_length - loop - 1] & 0xff));
  18.206 +        Store_field(result, 1, temp);
  18.207 +    }
  18.208 +
  18.209 +    CAMLreturn(result);
  18.210 +}
  18.211 +
  18.212 +/*
  18.213 + * dom_write_memory : context_t -> int32 -> int list -> unit
  18.214 + */
  18.215 +value
  18.216 +dom_write_memory (value context, value address, value val_list)
  18.217 +{
  18.218 +    CAMLparam3(context, address, val_list);
  18.219 +    CAMLlocal1(node);
  18.220 +
  18.221 +    context_t ctx;
  18.222 +
  18.223 +    char buffer[4096];  /* a big buffer */
  18.224 +    memory_t  my_address;
  18.225 +    u32 length = 0;
  18.226 +
  18.227 +    printf ("(pdb) write memory\n");
  18.228 +
  18.229 +    decode_context(&ctx, context);
  18.230 +
  18.231 +    node = val_list;
  18.232 +    if ( Int_val(node) == 0 )       /* gdb functionalty test uses empty list */
  18.233 +    {
  18.234 +        CAMLreturn(Val_unit);
  18.235 +    }
  18.236 +
  18.237 +    while ( Int_val(Field(node,1)) != 0 )
  18.238 +    {
  18.239 +        buffer[length++] = Int_val(Field(node, 0));
  18.240 +        node = Field(node,1);
  18.241 +    }
  18.242 +    buffer[length++] = Int_val(Field(node, 0));
  18.243 +
  18.244 +    my_address = (memory_t) Int32_val(address);
  18.245 +
  18.246 +    if ( xendebug_write_memory(xc_handle, ctx.domain, ctx.vcpu,
  18.247 +                               my_address, length, buffer) )
  18.248 +    {
  18.249 +        printf("(pdb) write memory error!\n");  fflush(stdout);
  18.250 +        failwith("write memory error");
  18.251 +    }
  18.252 +
  18.253 +    CAMLreturn(Val_unit);
  18.254 +}
  18.255 +
  18.256 +/*
  18.257 + * dom_continue_target : context_t -> unit
  18.258 + */
  18.259 +value
  18.260 +dom_continue_target (value context)
  18.261 +{
  18.262 +    CAMLparam1(context);
  18.263 +
  18.264 +    context_t ctx;
  18.265 +
  18.266 +    decode_context(&ctx, context);
  18.267 +
  18.268 +    if ( xendebug_continue(xc_handle, ctx.domain, ctx.vcpu) )
  18.269 +    {
  18.270 +        printf("(pdb) continue\n");  fflush(stdout);
  18.271 +        failwith("continue");
  18.272 +    }
  18.273 +
  18.274 +    CAMLreturn(Val_unit);
  18.275 +}
  18.276 +
  18.277 +/*
  18.278 + * dom_step_target : context_t -> unit
  18.279 + */
  18.280 +value
  18.281 +dom_step_target (value context)
  18.282 +{
  18.283 +    CAMLparam1(context);
  18.284 +
  18.285 +    context_t ctx;
  18.286 +
  18.287 +    decode_context(&ctx, context);
  18.288 +
  18.289 +    if ( xendebug_step(xc_handle, ctx.domain, ctx.vcpu) )
  18.290 +    {
  18.291 +        printf("(pdb) step\n");  fflush(stdout);
  18.292 +        failwith("step");
  18.293 +    }
  18.294 +
  18.295 +    CAMLreturn(Val_unit);
  18.296 +}
  18.297 +
  18.298 +
  18.299 +
  18.300 +/*
  18.301 + * dom_insert_memory_breakpoint : context_t -> int32 -> int list -> unit
  18.302 + */
  18.303 +value
  18.304 +dom_insert_memory_breakpoint (value context, value address, value length)
  18.305 +{
  18.306 +    CAMLparam3(context, address, length);
  18.307 +
  18.308 +    context_t ctx;
  18.309 +    memory_t my_address = (memory_t) Int32_val(address);
  18.310 +    int my_length = Int_val(length);
  18.311 +
  18.312 +    decode_context(&ctx, context);
  18.313 +
  18.314 +    printf ("(pdb) insert memory breakpoint 0x%lx %d\n",
  18.315 +            my_address, my_length);
  18.316 +
  18.317 +    if ( xendebug_insert_memory_breakpoint(xc_handle, ctx.domain, ctx.vcpu,
  18.318 +                                           my_address, my_length) )
  18.319 +    {
  18.320 +        printf("(pdb) error: insert memory breakpoint\n");  fflush(stdout);
  18.321 +        failwith("insert memory breakpoint");
  18.322 +    }
  18.323 +
  18.324 +
  18.325 +    CAMLreturn(Val_unit);
  18.326 +}
  18.327 +
  18.328 +/*
  18.329 + * dom_remove_memory_breakpoint : context_t -> int32 -> int list -> unit
  18.330 + */
  18.331 +value
  18.332 +dom_remove_memory_breakpoint (value context, value address, value length)
  18.333 +{
  18.334 +    CAMLparam3(context, address, length);
  18.335 +
  18.336 +    context_t ctx;
  18.337 +
  18.338 +    memory_t my_address = (memory_t) Int32_val(address);
  18.339 +    int my_length = Int_val(length);
  18.340 +
  18.341 +    printf ("(pdb) remove memory breakpoint 0x%lx %d\n",
  18.342 +            my_address, my_length);
  18.343 +
  18.344 +    decode_context(&ctx, context);
  18.345 +
  18.346 +    if ( xendebug_remove_memory_breakpoint(xc_handle, 
  18.347 +                                           ctx.domain, ctx.vcpu,
  18.348 +                                           my_address, my_length) )
  18.349 +    {
  18.350 +        printf("(pdb) error: remove memory breakpoint\n");  fflush(stdout);
  18.351 +        failwith("remove memory breakpoint");
  18.352 +    }
  18.353 +
  18.354 +    CAMLreturn(Val_unit);
  18.355 +}
  18.356 +
  18.357 +/*
  18.358 + * dom_attach_debugger : int -> int -> unit
  18.359 + */
  18.360 +value
  18.361 +dom_attach_debugger (value domain, value vcpu)
  18.362 +{
  18.363 +    CAMLparam2(domain, vcpu);
  18.364 +
  18.365 +    int my_domain = Int_val(domain);
  18.366 +    int my_vcpu = Int_val(vcpu);
  18.367 +
  18.368 +    printf ("(pdb) attach domain [%d.%d]\n", my_domain, my_vcpu);
  18.369 +
  18.370 +    if ( xendebug_attach(xc_handle, my_domain, my_vcpu) )
  18.371 +    {
  18.372 +        printf("(pdb) attach error!\n");  fflush(stdout);
  18.373 +        failwith("attach error");
  18.374 +    }
  18.375 +
  18.376 +    CAMLreturn(Val_unit);
  18.377 +}
  18.378 +
  18.379 +
  18.380 +/*
  18.381 + * dom_detach_debugger : int -> int -> unit
  18.382 + */
  18.383 +value
  18.384 +dom_detach_debugger (value domain, value vcpu)
  18.385 +{
  18.386 +    CAMLparam2(domain, vcpu);
  18.387 +
  18.388 +    int my_domain = Int_val(domain);
  18.389 +    int my_vcpu = Int_val(vcpu);
  18.390 +
  18.391 +    printf ("(pdb) detach domain [%d.%d]\n", my_domain, my_vcpu);
  18.392 +
  18.393 +    if ( xendebug_detach(xc_handle, my_domain, my_vcpu) )
  18.394 +    {
  18.395 +        printf("(pdb) detach error!\n");  fflush(stdout);
  18.396 +        failwith("detach error");
  18.397 +    }
  18.398 +
  18.399 +    CAMLreturn(Val_unit);
  18.400 +}
  18.401 +
  18.402 +
  18.403 +/*
  18.404 + * dom_pause_target : int -> unit
  18.405 + */
  18.406 +value
  18.407 +dom_pause_target (value domid)
  18.408 +{
  18.409 +    CAMLparam1(domid);
  18.410 +
  18.411 +    int my_domid = Int_val(domid);
  18.412 +
  18.413 +    printf ("(pdb) pause target %d\n", my_domid);
  18.414 +
  18.415 +    xc_domain_pause(xc_handle, my_domid);
  18.416 +
  18.417 +    CAMLreturn(Val_unit);
  18.418 +}
  18.419 +
  18.420 +/****************************************************************************/
  18.421 +/****************************************************************************/
  18.422 +
  18.423 +/*
  18.424 + * query_domain_stop : unit -> (int * int) list
  18.425 + */
  18.426 +value
  18.427 +query_domain_stop (value unit)
  18.428 +{
  18.429 +    CAMLparam1(unit);
  18.430 +    CAMLlocal3(result, temp, node);
  18.431 +
  18.432 +    int max_domains = 20;
  18.433 +    int dom_list[max_domains];
  18.434 +    int loop, count;
  18.435 +
  18.436 +    count = xendebug_query_domain_stop(xc_handle, dom_list, max_domains);
  18.437 +    if ( count < 0 )
  18.438 +    {
  18.439 +        printf("(pdb) query domain stop!\n");  fflush(stdout);
  18.440 +        failwith("query domain stop");
  18.441 +    }
  18.442 +
  18.443 +    printf ("QDS: %d\n", count);
  18.444 +    for (loop = 0; loop < count; loop ++)
  18.445 +        printf ("  %d %d\n", loop, dom_list[loop]);
  18.446 +
  18.447 +    result = caml_alloc(2,0);
  18.448 +    if ( count > 0 )                                                  /* car */
  18.449 +    {
  18.450 +        node = caml_alloc(2,0);
  18.451 +        Store_field(node, 0, Val_int(dom_list[0]));             /* domain id */
  18.452 +        Store_field(node, 1, Val_int(0));                            /* vcpu */
  18.453 +        Store_field(result, 0, node);
  18.454 +    }
  18.455 +    else
  18.456 +    {
  18.457 +        Store_field(result, 0, Val_int(0));                    
  18.458 +    }
  18.459 +    Store_field(result, 1, Val_int(0));                               /* cdr */
  18.460 +
  18.461 +    for ( loop = 1; loop < count; loop++ )
  18.462 +    {
  18.463 +        temp = result;
  18.464 +        result = caml_alloc(2,0);
  18.465 +        node = caml_alloc(2,0);
  18.466 +        Store_field(node, 0, Val_int(dom_list[loop]));          /* domain id */
  18.467 +        Store_field(node, 1, Val_int(0));                            /* vcpu */
  18.468 +        Store_field(result, 0, node);
  18.469 +        Store_field(result, 1, temp);
  18.470 +    }
  18.471 +
  18.472 +    CAMLreturn(result);
  18.473 +}
  18.474 +
  18.475 +/****************************************************************************/
  18.476 +
  18.477 +
  18.478 +
  18.479 +/*
  18.480 + * Local variables:
  18.481 + * mode: C
  18.482 + * c-set-style: "BSD"
  18.483 + * c-basic-offset: 4
  18.484 + * tab-width: 4
  18.485 + * indent-tabs-mode: nil
  18.486 + * End:
  18.487 + */
  18.488 +
    19.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.2 +++ b/tools/debugger/pdb/pdb_caml_evtchn.c	Mon Jun 27 21:31:56 2005 +0000
    19.3 @@ -0,0 +1,178 @@
    19.4 +#include <xc.h>
    19.5 +#include <stdio.h>
    19.6 +#include <stdlib.h>
    19.7 +#include <string.h>
    19.8 +
    19.9 +#include <caml/alloc.h>
   19.10 +#include <caml/fail.h>
   19.11 +#include <caml/memory.h>
   19.12 +#include <caml/mlvalues.h>
   19.13 +
   19.14 +
   19.15 +#include <errno.h>
   19.16 +#include <sys/ioctl.h>
   19.17 +#include <sys/stat.h>
   19.18 +#include <fcntl.h>
   19.19 +#include <unistd.h>
   19.20 +
   19.21 +int xen_evtchn_bind (int evtchn_fd, int idx);
   19.22 +int xen_evtchn_unbind (int evtchn_fd, int idx);
   19.23 +
   19.24 +int
   19.25 +__evtchn_open (char *filename, int major, int minor)
   19.26 +{
   19.27 +    int   evtchn_fd;
   19.28 +    struct stat st;
   19.29 +    
   19.30 +    /* Make sure any existing device file links to correct device. */
   19.31 +    if ( (lstat(filename, &st) != 0) ||
   19.32 +         !S_ISCHR(st.st_mode) ||
   19.33 +         (st.st_rdev != makedev(major, minor)) )
   19.34 +    {
   19.35 +        (void)unlink(filename);
   19.36 +    }
   19.37 +
   19.38 + reopen:
   19.39 +    evtchn_fd = open(filename, O_RDWR); 
   19.40 +    if ( evtchn_fd == -1 )
   19.41 +    {
   19.42 +        if ( (errno == ENOENT) &&
   19.43 +             ((mkdir("/dev/xen", 0755) == 0) || (errno == EEXIST)) &&
   19.44 +             (mknod(filename, S_IFCHR|0600, makedev(major,minor)) == 0) )
   19.45 +        {
   19.46 +            goto reopen;
   19.47 +        }
   19.48 +        return -errno;
   19.49 +    }
   19.50 +
   19.51 +    return evtchn_fd;
   19.52 +}
   19.53 +
   19.54 +/*
   19.55 + * evtchn_open : string -> int -> int -> Unix.file_descr
   19.56 + *
   19.57 + * OCaml's Unix library doesn't have mknod, so it makes more sense just write
   19.58 + * this in C.  This code is from Keir/Andy.
   19.59 + */
   19.60 +value
   19.61 +evtchn_open (value filename, value major, value minor)
   19.62 +{
   19.63 +    CAMLparam3(filename, major, minor);
   19.64 +
   19.65 +    char *myfilename = String_val(filename);
   19.66 +    int   mymajor = Int_val(major);
   19.67 +    int   myminor = Int_val(minor);
   19.68 +    int   evtchn_fd;
   19.69 +
   19.70 +    evtchn_fd = __evtchn_open(myfilename, mymajor, myminor);
   19.71 +
   19.72 +    CAMLreturn(Val_int(evtchn_fd));
   19.73 +}
   19.74 +
   19.75 +/*
   19.76 + * evtchn_bind : Unix.file_descr -> int -> unit
   19.77 + */
   19.78 +value
   19.79 +evtchn_bind (value fd, value idx)
   19.80 +{
   19.81 +    CAMLparam2(fd, idx);
   19.82 +
   19.83 +    int myfd = Int_val(fd);
   19.84 +    int myidx = Int_val(idx);
   19.85 +
   19.86 +    if ( xen_evtchn_bind(myfd, myidx) < 0 )
   19.87 +    {
   19.88 +        printf("(pdb) evtchn_bind error!\n");  fflush(stdout);
   19.89 +        failwith("evtchn_bind error");
   19.90 +    }
   19.91 +
   19.92 +    CAMLreturn(Val_unit);
   19.93 +}
   19.94 +
   19.95 +/*
   19.96 + * evtchn_unbind : Unix.file_descr -> int -> unit
   19.97 + */
   19.98 +value
   19.99 +evtchn_unbind (value fd, value idx)
  19.100 +{
  19.101 +    CAMLparam2(fd, idx);
  19.102 +
  19.103 +    int myfd = Int_val(fd);
  19.104 +    int myidx = Int_val(idx);
  19.105 +
  19.106 +    if ( xen_evtchn_unbind(myfd, myidx) < 0 )
  19.107 +    {
  19.108 +        printf("(pdb) evtchn_unbind error!\n");  fflush(stdout);
  19.109 +        failwith("evtchn_unbind error");
  19.110 +    }
  19.111 +
  19.112 +    CAMLreturn(Val_unit);
  19.113 +}
  19.114 +
  19.115 +/*
  19.116 + * evtchn_read : Unix.file_descr -> int
  19.117 + */
  19.118 +value
  19.119 +evtchn_read (value fd)
  19.120 +{
  19.121 +    CAMLparam1(fd);
  19.122 +
  19.123 +    u16 v;
  19.124 +    int bytes;
  19.125 +    int rc = -1;
  19.126 +    int myfd = Int_val(fd);
  19.127 +
  19.128 +    while ( (bytes = read(myfd, &v, sizeof(v))) == -1 )
  19.129 +    {
  19.130 +        if ( errno == EINTR )  continue;
  19.131 +        rc = -errno;
  19.132 +        goto exit;
  19.133 +    }
  19.134 +    
  19.135 +    if ( bytes == sizeof(v) )
  19.136 +        rc = v;
  19.137 +    
  19.138 + exit:
  19.139 +    CAMLreturn(Val_int(rc));
  19.140 +}
  19.141 +
  19.142 +
  19.143 +/*
  19.144 + * evtchn_close : Unix.file_descr -> unit
  19.145 + */
  19.146 +value
  19.147 +evtchn_close (value fd)
  19.148 +{
  19.149 +    CAMLparam1(fd);
  19.150 +    int myfd = Int_val(fd);
  19.151 +
  19.152 +    (void)close(myfd);
  19.153 +
  19.154 +    CAMLreturn(Val_unit);
  19.155 +}
  19.156 +
  19.157 +/*
  19.158 + * evtchn_unmask : Unix.file_descr -> int -> unit
  19.159 + */
  19.160 +value
  19.161 +evtchn_unmask (value fd, value idx)
  19.162 +{
  19.163 +    CAMLparam1(fd);
  19.164 +
  19.165 +    int myfd = Int_val(fd);
  19.166 +    u16 myidx = Int_val(idx);
  19.167 +
  19.168 +    (void)write(myfd, &myidx, sizeof(myidx));
  19.169 +
  19.170 +    CAMLreturn(Val_unit);
  19.171 +}
  19.172 +
  19.173 +/*
  19.174 + * Local variables:
  19.175 + * mode: C
  19.176 + * c-set-style: "BSD"
  19.177 + * c-basic-offset: 4
  19.178 + * tab-width: 4
  19.179 + * indent-tabs-mode: nil
  19.180 + * End:
  19.181 + */
    20.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    20.2 +++ b/tools/debugger/pdb/pdb_caml_process.c	Mon Jun 27 21:31:56 2005 +0000
    20.3 @@ -0,0 +1,543 @@
    20.4 +/*
    20.5 + * pdb_caml_process.c
    20.6 + *
    20.7 + * http://www.cl.cam.ac.uk/netos/pdb
    20.8 + *
    20.9 + * PDB's OCaml interface library for debugging processes
   20.10 + */
   20.11 +
   20.12 +#include <errno.h>
   20.13 +#include <stdio.h>
   20.14 +#include <stdlib.h>
   20.15 +#include <string.h>
   20.16 +#include <caml/alloc.h>
   20.17 +#include <caml/fail.h>
   20.18 +#include <caml/memory.h>
   20.19 +#include <caml/mlvalues.h>
   20.20 +
   20.21 +#include <xc.h>
   20.22 +#include <xen/xen.h>
   20.23 +#include <xen/io/domain_controller.h>
   20.24 +#include <xen/linux/privcmd.h>
   20.25 +#include "pdb_module.h"
   20.26 +#include "pdb_caml_xen.h"
   20.27 +
   20.28 +/* this order comes from linux-2.6.11/include/asm-i386/ptrace.h */
   20.29 +enum x86_registers { LINUX_EBX, LINUX_ECX, LINUX_EDX, LINUX_ESI, LINUX_EDI,
   20.30 +                     LINUX_EBP, LINUX_EAX, LINUX_DS,  LINUX_ES,  LINUX_FS,
   20.31 +                     LINUX_GS,  LINUX_ORIG_EAX, LINUX_EIP, LINUX_CS, LINUX_EFL,
   20.32 +                     LINUX_ESP, LINUX_SS };
   20.33 +#define FRAME_SIZE 17
   20.34 +
   20.35 +typedef struct
   20.36 +{
   20.37 +    int domain;
   20.38 +    int process;
   20.39 +    int evtchn;
   20.40 +    pdb_front_ring_t *ring;
   20.41 +} context_t;
   20.42 +
   20.43 +#define decode_context(_ctx, _ocaml)   \
   20.44 +{  \
   20.45 +    (_ctx)->domain  = Int_val(Field((_ocaml),0));  \
   20.46 +    (_ctx)->process = Int_val(Field((_ocaml),1));  \
   20.47 +    (_ctx)->evtchn  = Int_val(Field((_ocaml),2));  \
   20.48 +    (_ctx)->ring    =  (pdb_front_ring_t *)Int32_val(Field((_ocaml),3));  \
   20.49 +}
   20.50 +
   20.51 +#define encode_context(_ctx, _ocaml)  \
   20.52 +{  \
   20.53 +    (_ocaml) = caml_alloc_tuple(2);  \
   20.54 +    Store_field((_ocaml), 0, Val_int((_ctx)->domain));  \
   20.55 +    Store_field((_ocaml), 1, Val_int((_ctx)->process));  \
   20.56 +}
   20.57 +
   20.58 +/*
   20.59 + * send a request to a pdb domain backend.
   20.60 + *
   20.61 + * puts the request on a ring and kicks the backend using an event channel.
   20.62 + */
   20.63 +static void
   20.64 +send_request (pdb_front_ring_t *pdb_ring, int evtchn, pdb_request_t *request)
   20.65 +{
   20.66 +    pdb_request_t    *req;
   20.67 +
   20.68 +    req = RING_GET_REQUEST(pdb_ring, pdb_ring->req_prod_pvt);
   20.69 +
   20.70 +    memcpy(req, request, sizeof(pdb_request_t));
   20.71 +
   20.72 +    pdb_ring->req_prod_pvt++;
   20.73 +
   20.74 +    RING_PUSH_REQUESTS(pdb_ring);
   20.75 +    xc_evtchn_send(xc_handle, evtchn);
   20.76 +}
   20.77 +
   20.78 +/*
   20.79 + * read a response from a pdb domain backend.
   20.80 + *
   20.81 + * grabs the response off a ring.
   20.82 + */
   20.83 +static void
   20.84 +read_response (pdb_front_ring_t *pdb_ring, pdb_response_p response)
   20.85 +{
   20.86 +    RING_IDX loop, rp;
   20.87 +
   20.88 +    rp = pdb_ring->sring->rsp_prod;
   20.89 +    rmb(); /* Ensure we see queued responses up to 'rp'. */
   20.90 +
   20.91 +    for ( loop = pdb_ring->rsp_cons; loop != rp; loop++ )
   20.92 +    {
   20.93 +        pdb_response_p resp;
   20.94 +
   20.95 +        resp = RING_GET_RESPONSE(pdb_ring, loop);
   20.96 +        memcpy(response, resp, sizeof(pdb_response_t));
   20.97 +
   20.98 +        /*        
   20.99 +        printf ("got response %x %x %x\n", response->operation, 
  20.100 +                response->status, response->value);
  20.101 +        */
  20.102 +    }
  20.103 +    pdb_ring->rsp_cons = loop;
  20.104 +}
  20.105 +
  20.106 +/*
  20.107 + * process_handle_response : int32 -> unit
  20.108 + */
  20.109 +
  20.110 +value
  20.111 +process_handle_response (value ring)
  20.112 +{
  20.113 +    CAMLparam1(ring);
  20.114 +
  20.115 +    pdb_front_ring_t *my_ring = (pdb_front_ring_t *)Int32_val(ring);
  20.116 +    pdb_response_t resp;
  20.117 +
  20.118 +    if ( my_ring )
  20.119 +        read_response(my_ring, &resp);
  20.120 +
  20.121 +    CAMLreturn(Val_unit);
  20.122 +}
  20.123 +
  20.124 +/*
  20.125 + * proc_attach_debugger : context_t -> unit
  20.126 + */
  20.127 +value
  20.128 +proc_attach_debugger (value context)
  20.129 +{
  20.130 +    CAMLparam1(context);
  20.131 +    context_t ctx;
  20.132 +    pdb_request_t req;
  20.133 +    pdb_response_t resp;
  20.134 +
  20.135 +    decode_context(&ctx, context);
  20.136 +
  20.137 +    printf("(pdb) attach process [%d.%d] %d %p\n", ctx.domain, ctx.process,
  20.138 +           ctx.evtchn, ctx.ring);
  20.139 +    fflush(stdout);
  20.140 +
  20.141 +    req.operation = PDB_OPCODE_ATTACH;
  20.142 +    req.domain  = ctx.domain;
  20.143 +    req.process = ctx.process;
  20.144 +
  20.145 +    send_request (ctx.ring, ctx.evtchn, &req);
  20.146 +
  20.147 +    printf("awaiting response\n");
  20.148 +    fflush(stdout);
  20.149 +
  20.150 +    read_response (ctx.ring, &resp);
  20.151 +
  20.152 +    printf("response %d %d\n", resp.operation, resp.status);
  20.153 +    fflush(stdout);
  20.154 +
  20.155 +    CAMLreturn(Val_unit);
  20.156 +}
  20.157 +
  20.158 +
  20.159 +/*
  20.160 + * proc_detach_debugger : context_t -> unit
  20.161 + */
  20.162 +value
  20.163 +proc_detach_debugger (value context)
  20.164 +{
  20.165 +    CAMLparam1(context);
  20.166 +    context_t ctx;
  20.167 +    pdb_request_t req;
  20.168 +
  20.169 +    decode_context(&ctx, context);
  20.170 +
  20.171 +    printf("(pdb) detach process [%d.%d] %d %p\n", ctx.domain, ctx.process,
  20.172 +           ctx.evtchn, ctx.ring);
  20.173 +    fflush(stdout);
  20.174 +
  20.175 +    req.operation = PDB_OPCODE_DETACH;
  20.176 +    req.domain  = ctx.domain;
  20.177 +    req.process = ctx.process;
  20.178 +
  20.179 +    send_request (ctx.ring, ctx.evtchn, &req);
  20.180 +
  20.181 +    CAMLreturn(Val_unit);
  20.182 +}
  20.183 +
  20.184 +
  20.185 +/*
  20.186 + * proc_pause_target : int -> unit
  20.187 + */
  20.188 +value
  20.189 +proc_pause_target (value context)
  20.190 +{
  20.191 +    CAMLparam1(context);
  20.192 +    context_t ctx;
  20.193 +
  20.194 +    decode_context(&ctx, context);
  20.195 +
  20.196 +    printf("(pdb) pause target %d %d\n", ctx.domain, ctx.process);
  20.197 +    fflush(stdout);
  20.198 +
  20.199 +    CAMLreturn(Val_unit);
  20.200 +}
  20.201 +
  20.202 +
  20.203 +/*
  20.204 + * proc_read_registers : context_t -> int32
  20.205 + */
  20.206 +value
  20.207 +proc_read_registers (value context)
  20.208 +{
  20.209 +    CAMLparam1(context);
  20.210 +    CAMLlocal1(result);
  20.211 +
  20.212 +    u32 regs[FRAME_SIZE];
  20.213 +
  20.214 +    pdb_request_t req;
  20.215 +    context_t ctx;
  20.216 +    int loop;
  20.217 +
  20.218 +    decode_context(&ctx, context);
  20.219 +
  20.220 +    req.operation = PDB_OPCODE_RD_REG;
  20.221 +    req.domain  = ctx.domain;
  20.222 +    req.process = ctx.process;
  20.223 +
  20.224 +    for (loop = 0; loop < FRAME_SIZE; loop++)
  20.225 +    {
  20.226 +        pdb_response_t resp;
  20.227 +
  20.228 +        req.u.rd_reg.reg = loop;
  20.229 +        send_request(ctx.ring, ctx.evtchn, &req);
  20.230 +        read_response(ctx.ring, &resp);
  20.231 +        regs[loop] = resp.value;
  20.232 +    }
  20.233 +
  20.234 +    result = caml_alloc_tuple(16);
  20.235 +
  20.236 +    Store_field(result,  0, caml_copy_int32(regs[LINUX_EAX]));
  20.237 +    Store_field(result,  1, caml_copy_int32(regs[LINUX_ECX]));
  20.238 +    Store_field(result,  2, caml_copy_int32(regs[LINUX_EDX]));
  20.239 +    Store_field(result,  3, caml_copy_int32(regs[LINUX_EBX]));
  20.240 +    Store_field(result,  4, caml_copy_int32(regs[LINUX_ESP]));
  20.241 +    Store_field(result,  5, caml_copy_int32(regs[LINUX_EBP]));
  20.242 +    Store_field(result,  6, caml_copy_int32(regs[LINUX_ESI]));
  20.243 +    Store_field(result,  7, caml_copy_int32(regs[LINUX_EDI]));
  20.244 +    Store_field(result,  8, caml_copy_int32(regs[LINUX_EIP]));
  20.245 +    Store_field(result,  9, caml_copy_int32(regs[LINUX_EFL]));
  20.246 +    Store_field(result, 10, caml_copy_int32(regs[LINUX_CS]));          /* 16 */
  20.247 +    Store_field(result, 11, caml_copy_int32(regs[LINUX_SS]));          /* 16 */
  20.248 +    Store_field(result, 12, caml_copy_int32(regs[LINUX_DS]));          /* 16 */
  20.249 +    Store_field(result, 13, caml_copy_int32(regs[LINUX_ES]));          /* 16 */
  20.250 +    Store_field(result, 14, caml_copy_int32(regs[LINUX_FS]));          /* 16 */
  20.251 +    Store_field(result, 15, caml_copy_int32(regs[LINUX_GS]));          /* 16 */
  20.252 +
  20.253 +    CAMLreturn(result);
  20.254 +}
  20.255 +
  20.256 +
  20.257 +/*
  20.258 + * proc_write_register : context_t -> register -> int32 -> unit
  20.259 + */
  20.260 +value
  20.261 +proc_write_register (value context, value reg, value newval)
  20.262 +{
  20.263 +    CAMLparam3(context, reg, newval);
  20.264 +
  20.265 +    int my_reg = Int_val(reg);
  20.266 +    unsigned long my_newval = Int32_val(newval);
  20.267 +
  20.268 +    context_t ctx;
  20.269 +    pdb_request_t req;
  20.270 +    pdb_response_t resp;
  20.271 +
  20.272 +    decode_context(&ctx, context);
  20.273 +
  20.274 +    req.operation = PDB_OPCODE_WR_REG;
  20.275 +    req.domain = ctx.domain;
  20.276 +    req.process = ctx.process;
  20.277 +    req.u.wr_reg.value = my_newval;
  20.278 +
  20.279 +    switch (my_reg)
  20.280 +    {
  20.281 +    case GDB_EAX: req.u.wr_reg.reg = LINUX_EAX; break;
  20.282 +    case GDB_ECX: req.u.wr_reg.reg = LINUX_ECX; break;
  20.283 +    case GDB_EDX: req.u.wr_reg.reg = LINUX_EDX; break;
  20.284 +    case GDB_EBX: req.u.wr_reg.reg = LINUX_EBX; break;
  20.285 +
  20.286 +    case GDB_ESP: req.u.wr_reg.reg = LINUX_ESP; break;
  20.287 +    case GDB_EBP: req.u.wr_reg.reg = LINUX_EBP; break;
  20.288 +    case GDB_ESI: req.u.wr_reg.reg = LINUX_ESI; break;
  20.289 +    case GDB_EDI: req.u.wr_reg.reg = LINUX_EDI; break;
  20.290 +
  20.291 +    case GDB_EIP: req.u.wr_reg.reg = LINUX_EIP; break;
  20.292 +    case GDB_EFL: req.u.wr_reg.reg = LINUX_EFL; break;
  20.293 + 
  20.294 +    case GDB_CS:  req.u.wr_reg.reg = LINUX_CS; break;
  20.295 +    case GDB_SS:  req.u.wr_reg.reg = LINUX_SS; break;
  20.296 +    case GDB_DS:  req.u.wr_reg.reg = LINUX_DS; break;
  20.297 +    case GDB_ES:  req.u.wr_reg.reg = LINUX_ES; break;
  20.298 +    case GDB_FS:  req.u.wr_reg.reg = LINUX_FS; break;
  20.299 +    case GDB_GS:  req.u.wr_reg.reg = LINUX_GS; break;
  20.300 +    }
  20.301 +
  20.302 +    send_request(ctx.ring, ctx.evtchn, &req);
  20.303 +    read_response(ctx.ring, &resp);
  20.304 +
  20.305 +    CAMLreturn(Val_unit);
  20.306 +}
  20.307 +
  20.308 +
  20.309 +/*
  20.310 + * proc_read_memory : context_t -> int32 -> int -> int
  20.311 + */
  20.312 +value
  20.313 +proc_read_memory (value context, value address, value length)
  20.314 +{
  20.315 +    CAMLparam3(context, address, length);
  20.316 +    CAMLlocal2(result, temp);
  20.317 +
  20.318 +    context_t ctx;
  20.319 +    int loop;
  20.320 +    char *buffer;
  20.321 +    /*    memory_t my_address = Int32_val(address); */
  20.322 +    u32 my_length = Int_val(length);
  20.323 +
  20.324 +    printf ("(pdb) read memory\n");
  20.325 +
  20.326 +    decode_context(&ctx, context);
  20.327 +
  20.328 +    buffer = malloc(my_length);
  20.329 +    if ( buffer == NULL )
  20.330 +    {
  20.331 +        printf("(pdb) read memory: malloc failed.\n");  fflush(stdout);
  20.332 +        failwith("read memory error");
  20.333 +    }
  20.334 +
  20.335 +    /*
  20.336 +    if ( xendebug_read_memory(xc_handle, ctx.domain, ctx.vcpu, 
  20.337 +                              my_address, my_length, buffer) )
  20.338 +    {
  20.339 +        printf("(pdb) read memory error!\n");  fflush(stdout);
  20.340 +        failwith("read memory error");
  20.341 +    }
  20.342 +    */
  20.343 +
  20.344 +    memset(buffer, 0xff, my_length);
  20.345 +
  20.346 +    result = caml_alloc(2,0);
  20.347 +    if ( my_length > 0 )                                              /* car */
  20.348 +    {
  20.349 +        Store_field(result, 0, Val_int(buffer[my_length - 1] & 0xff));
  20.350 +    }
  20.351 +    else
  20.352 +
  20.353 +    {
  20.354 +        Store_field(result, 0, Val_int(0));                    
  20.355 +    }
  20.356 +    Store_field(result, 1, Val_int(0));                               /* cdr */
  20.357 +
  20.358 +    for (loop = 1; loop < my_length; loop++)
  20.359 +    {
  20.360 +        temp = result;
  20.361 +        result = caml_alloc(2,0);
  20.362 +        Store_field(result, 0, Val_int(buffer[my_length - loop - 1] & 0xff));
  20.363 +        Store_field(result, 1, temp);
  20.364 +    }
  20.365 +
  20.366 +    CAMLreturn(result);
  20.367 +}
  20.368 +
  20.369 +/*
  20.370 + * proc_write_memory : context_t -> int32 -> int list -> unit
  20.371 + */
  20.372 +value
  20.373 +proc_write_memory (value context, value address, value val_list)
  20.374 +{
  20.375 +    CAMLparam3(context, address, val_list);
  20.376 +    CAMLlocal1(node);
  20.377 +
  20.378 +    context_t ctx;
  20.379 +
  20.380 +    char buffer[4096];  /* a big buffer */
  20.381 +    memory_t  my_address;
  20.382 +    u32 length = 0;
  20.383 +
  20.384 +    printf ("(pdb) write memory\n");
  20.385 +
  20.386 +    decode_context(&ctx, context);
  20.387 +
  20.388 +    node = val_list;
  20.389 +    if ( Int_val(node) == 0 )       /* gdb functionalty test uses empty list */
  20.390 +    {
  20.391 +        CAMLreturn(Val_unit);
  20.392 +    }
  20.393 +
  20.394 +    while ( Int_val(Field(node,1)) != 0 )
  20.395 +    {
  20.396 +        buffer[length++] = Int_val(Field(node, 0));
  20.397 +        node = Field(node,1);
  20.398 +    }
  20.399 +    buffer[length++] = Int_val(Field(node, 0));
  20.400 +
  20.401 +    my_address = (memory_t) Int32_val(address);
  20.402 +
  20.403 +    /*
  20.404 +    if ( xendebug_write_memory(xc_handle, ctx.domain, ctx.vcpu,
  20.405 +                               my_address, length, buffer) )
  20.406 +    {
  20.407 +        printf("(pdb) write memory error!\n");  fflush(stdout);
  20.408 +        failwith("write memory error");
  20.409 +    }
  20.410 +    */
  20.411 +    {
  20.412 +        int loop;
  20.413 +        for (loop = 0; loop < length; loop++)
  20.414 +        {
  20.415 +            printf (" %02x", buffer[loop]);
  20.416 +        }
  20.417 +        printf ("\n");
  20.418 +    }
  20.419 +
  20.420 +    CAMLreturn(Val_unit);
  20.421 +}
  20.422 +
  20.423 +
  20.424 +
  20.425 +/*
  20.426 + * proc_continue_target : context_t -> unit
  20.427 + */
  20.428 +value
  20.429 +proc_continue_target (value context)
  20.430 +{
  20.431 +    CAMLparam1(context);
  20.432 +
  20.433 +    context_t ctx;
  20.434 +
  20.435 +    decode_context(&ctx, context);
  20.436 +
  20.437 +    /*
  20.438 +    if ( xendebug_continue(xc_handle, ctx.domain, ctx.vcpu) )
  20.439 +    {
  20.440 +        printf("(pdb) continue\n");  fflush(stdout);
  20.441 +        failwith("continue");
  20.442 +    }
  20.443 +    */
  20.444 +    printf ("CONTINUE\n");
  20.445 +
  20.446 +    CAMLreturn(Val_unit);
  20.447 +}
  20.448 +
  20.449 +/*
  20.450 + * proc_step_target : context_t -> unit
  20.451 + */
  20.452 +value
  20.453 +proc_step_target (value context)
  20.454 +{
  20.455 +    CAMLparam1(context);
  20.456 +
  20.457 +    context_t ctx;
  20.458 +
  20.459 +    decode_context(&ctx, context);
  20.460 +
  20.461 +    /*
  20.462 +    if ( xendebug_step(xc_handle, ctx.domain, ctx.vcpu) )
  20.463 +    {
  20.464 +        printf("(pdb) step\n");  fflush(stdout);
  20.465 +        failwith("step");
  20.466 +    }
  20.467 +    */
  20.468 +    printf ("STEP\n");
  20.469 +
  20.470 +    CAMLreturn(Val_unit);
  20.471 +}
  20.472 +
  20.473 +
  20.474 +
  20.475 +/*
  20.476 + * proc_insert_memory_breakpoint : context_t -> int32 -> int list -> unit
  20.477 + */
  20.478 +value
  20.479 +proc_insert_memory_breakpoint (value context, value address, value length)
  20.480 +{
  20.481 +    CAMLparam3(context, address, length);
  20.482 +
  20.483 +    context_t ctx;
  20.484 +    memory_t my_address = (memory_t) Int32_val(address);
  20.485 +    int my_length = Int_val(length);
  20.486 +
  20.487 +    decode_context(&ctx, context);
  20.488 +
  20.489 +    printf ("(pdb) insert memory breakpoint 0x%lx %d\n",
  20.490 +            my_address, my_length);
  20.491 +
  20.492 +    /*
  20.493 +    if ( xendebug_insert_memory_breakpoint(xc_handle, ctx.domain, ctx.vcpu,
  20.494 +                                           my_address, my_length) )
  20.495 +    {
  20.496 +        printf("(pdb) error: insert memory breakpoint\n");  fflush(stdout);
  20.497 +        failwith("insert memory breakpoint");
  20.498 +    }
  20.499 +    */
  20.500 +
  20.501 +    CAMLreturn(Val_unit);
  20.502 +}
  20.503 +
  20.504 +/*
  20.505 + * proc_remove_memory_breakpoint : context_t -> int32 -> int list -> unit
  20.506 + */
  20.507 +value
  20.508 +proc_remove_memory_breakpoint (value context, value address, value length)
  20.509 +{
  20.510 +    CAMLparam3(context, address, length);
  20.511 +
  20.512 +    context_t ctx;
  20.513 +
  20.514 +    memory_t my_address = (memory_t) Int32_val(address);
  20.515 +    int my_length = Int_val(length);
  20.516 +
  20.517 +    printf ("(pdb) remove memory breakpoint 0x%lx %d\n",
  20.518 +            my_address, my_length);
  20.519 +
  20.520 +    decode_context(&ctx, context);
  20.521 +
  20.522 +    /*
  20.523 +    if ( xendebug_remove_memory_breakpoint(xc_handle, 
  20.524 +                                           ctx.domain, ctx.vcpu,
  20.525 +                                           my_address, my_length) )
  20.526 +    {
  20.527 +        printf("(pdb) error: remove memory breakpoint\n");  fflush(stdout);
  20.528 +        failwith("remove memory breakpoint");
  20.529 +    }
  20.530 +    */
  20.531 +
  20.532 +    CAMLreturn(Val_unit);
  20.533 +}
  20.534 +
  20.535 +
  20.536 +/*
  20.537 + * Local variables:
  20.538 + * mode: C
  20.539 + * c-set-style: "BSD"
  20.540 + * c-basic-offset: 4
  20.541 + * tab-width: 4
  20.542 + * indent-tabs-mode: nil
  20.543 + * End:
  20.544 + */
  20.545 +
  20.546 +
    21.1 --- a/tools/debugger/pdb/pdb_caml_xc.c	Mon Jun 27 20:17:02 2005 +0000
    21.2 +++ b/tools/debugger/pdb/pdb_caml_xc.c	Mon Jun 27 21:31:56 2005 +0000
    21.3 @@ -3,7 +3,7 @@
    21.4   *
    21.5   * http://www.cl.cam.ac.uk/netos/pdb
    21.6   *
    21.7 - * OCaml to libxc interface library for PDB
    21.8 + * PDB's OCaml interface library for debugging domains
    21.9   */
   21.10  
   21.11  #include <xc.h>
   21.12 @@ -18,38 +18,9 @@
   21.13  #include <caml/memory.h>
   21.14  #include <caml/mlvalues.h>
   21.15  
   21.16 -int pdb_evtchn_bind_virq (int xc_handle, int virq, int *port);
   21.17 -int xen_evtchn_bind (int evtchn_fd, int idx);
   21.18 -int xen_evtchn_unbind (int evtchn_fd, int idx);
   21.19 -
   21.20 -/* this order comes from xen/include/public/arch-x86_32.h */
   21.21 -enum x86_registers { PDB_EBX, PDB_ECX, PDB_EDX, PDB_ESI, PDB_EDI,
   21.22 -                     PDB_EBP, PDB_EAX, PDB_Error_code, PDB_Entry_vector, 
   21.23 -                     PDB_EIP, PDB_CS, PDB_EFLAGS, PDB_ESP, PDB_SS,
   21.24 -                     PDB_ES, PDB_DS, PDB_FS, PDB_GS };
   21.25 -
   21.26 -static void dump_regs (cpu_user_regs_t *ctx);
   21.27 -
   21.28 -static int xc_handle = -1;
   21.29 +#include "pdb_caml_xen.h"
   21.30  
   21.31 -typedef struct
   21.32 -{
   21.33 -    int domain;
   21.34 -    int vcpu;
   21.35 -} context_t;
   21.36 -
   21.37 -#define decode_context(_ctx, _ocaml)   \
   21.38 -{  \
   21.39 -    (_ctx)->domain = Int_val(Field((_ocaml),0));  \
   21.40 -    (_ctx)->vcpu = Int_val(Field((_ocaml),1));  \
   21.41 -}
   21.42 -
   21.43 -#define encode_context(_ctx, _ocaml)  \
   21.44 -{  \
   21.45 -    (_ocaml) = caml_alloc_tuple(2);  \
   21.46 -    Store_field((_ocaml), 0, Val_int((_ctx)->domain));  \
   21.47 -    Store_field((_ocaml), 1, Val_int((_ctx)->vcpu));  \
   21.48 -}
   21.49 +int xc_handle = -1;
   21.50  
   21.51  
   21.52  /****************************************************************************/
   21.53 @@ -91,210 +62,6 @@ close_context (value unit)
   21.54      CAMLreturn(Val_unit);
   21.55  }
   21.56  
   21.57 -/*
   21.58 - * read_registers : context_t -> int32
   21.59 - */
   21.60 -value
   21.61 -read_registers (value context)
   21.62 -{
   21.63 -    CAMLparam1(context);
   21.64 -    CAMLlocal1(result);
   21.65 -
   21.66 -    cpu_user_regs_t *regs;
   21.67 -    context_t ctx;
   21.68 -
   21.69 -    decode_context(&ctx, context);
   21.70 -
   21.71 -    if ( xendebug_read_registers(xc_handle, ctx.domain, ctx.vcpu, &regs) )
   21.72 -    {
   21.73 -        printf("(pdb) read registers error!\n");  fflush(stdout);
   21.74 -        failwith("read registers error");
   21.75 -    }
   21.76 -
   21.77 -    dump_regs(regs);
   21.78 -
   21.79 -    result = caml_alloc_tuple(18);                                  /* FIXME */
   21.80 -
   21.81 -    Store_field(result,  0, caml_copy_int32(regs->ebx));
   21.82 -    Store_field(result,  1, caml_copy_int32(regs->ecx));
   21.83 -    Store_field(result,  2, caml_copy_int32(regs->edx));
   21.84 -    Store_field(result,  3, caml_copy_int32(regs->esi));
   21.85 -    Store_field(result,  4, caml_copy_int32(regs->edi));
   21.86 -    Store_field(result,  5, caml_copy_int32(regs->ebp));
   21.87 -    Store_field(result,  6, caml_copy_int32(regs->eax));
   21.88 -    Store_field(result,  7, caml_copy_int32(regs->error_code));        /* 16 */
   21.89 -    Store_field(result,  8, caml_copy_int32(regs->entry_vector));      /* 16 */
   21.90 -    Store_field(result,  9, caml_copy_int32(regs->eip));
   21.91 -    Store_field(result, 10, caml_copy_int32(regs->cs));                /* 16 */
   21.92 -    Store_field(result, 11, caml_copy_int32(regs->eflags));
   21.93 -    Store_field(result, 12, caml_copy_int32(regs->esp));
   21.94 -    Store_field(result, 13, caml_copy_int32(regs->ss));                /* 16 */
   21.95 -    Store_field(result, 14, caml_copy_int32(regs->es));                /* 16 */
   21.96 -    Store_field(result, 15, caml_copy_int32(regs->ds));                /* 16 */
   21.97 -    Store_field(result, 16, caml_copy_int32(regs->fs));                /* 16 */
   21.98 -    Store_field(result, 17, caml_copy_int32(regs->gs));                /* 16 */
   21.99 -
  21.100 -    CAMLreturn(result);
  21.101 -}
  21.102 -
  21.103 -
  21.104 -/*
  21.105 - * write_register : context_t -> register -> int32 -> unit
  21.106 - */
  21.107 -value
  21.108 -write_register (value context, value reg, value newval)
  21.109 -{
  21.110 -    CAMLparam3(context, reg, newval);
  21.111 -
  21.112 -    int my_reg = Int_val(reg);
  21.113 -    int val = Int32_val(newval);
  21.114 -
  21.115 -    context_t ctx;
  21.116 -    cpu_user_regs_t *regs;
  21.117 -
  21.118 -    printf("(pdb) write register\n");
  21.119 -
  21.120 -    decode_context(&ctx, context);
  21.121 -
  21.122 -    if ( xendebug_read_registers(xc_handle, ctx.domain, ctx.vcpu, &regs) )
  21.123 -    {
  21.124 -        printf("(pdb) write register (get) error!\n");  fflush(stdout);
  21.125 -        failwith("write register error");
  21.126 -    }
  21.127 -
  21.128 -    switch (my_reg)
  21.129 -    {
  21.130 -    case PDB_EBX: regs->ebx = val; break;
  21.131 -    case PDB_ECX: regs->ecx = val; break;
  21.132 -    case PDB_EDX: regs->edx = val; break;
  21.133 -    case PDB_ESI: regs->esi = val; break;
  21.134 -    case PDB_EDI: regs->edi = val; break;
  21.135 -
  21.136 -    case PDB_EBP: regs->ebp = val; break;
  21.137 -    case PDB_EAX: regs->eax = val; break;
  21.138 -    case PDB_Error_code: regs->error_code = val; break;
  21.139 -    case PDB_Entry_vector: regs->entry_vector = val; break;
  21.140 - 
  21.141 -    case PDB_EIP: regs->eip = val; break;
  21.142 -    case PDB_CS:  regs->cs  = val; break;
  21.143 -    case PDB_EFLAGS: regs->eflags = val; break;
  21.144 -    case PDB_ESP: regs->esp = val; break;
  21.145 -    case PDB_SS:  regs->ss  = val; break;
  21.146 -    case PDB_ES:  regs->es  = val; break;
  21.147 -    case PDB_DS:  regs->ds  = val; break;
  21.148 -    case PDB_FS:  regs->fs  = val; break;
  21.149 -    case PDB_GS:  regs->gs  = val; break;
  21.150 -    }
  21.151 -
  21.152 -    if ( xendebug_write_registers(xc_handle, ctx.domain, ctx.vcpu, regs) )
  21.153 -    {
  21.154 -        printf("(pdb) write register (set) error!\n");  fflush(stdout);
  21.155 -        failwith("write register error");
  21.156 -    }
  21.157 -
  21.158 -    CAMLreturn(Val_unit);
  21.159 -}
  21.160 -
  21.161 -/*
  21.162 - * read_memory : context_t -> int32 -> int -> int
  21.163 - */
  21.164 -value
  21.165 -read_memory (value context, value address, value length)
  21.166 -{
  21.167 -    CAMLparam3(context, address, length);
  21.168 -    CAMLlocal2(result, temp);
  21.169 -
  21.170 -    context_t ctx;
  21.171 -    int loop;
  21.172 -    char *buffer;
  21.173 -    memory_t my_address = Int32_val(address);
  21.174 -    u32 my_length = Int_val(length);
  21.175 -
  21.176 -    printf ("(pdb) read memory\n");
  21.177 -
  21.178 -    decode_context(&ctx, context);
  21.179 -
  21.180 -    buffer = malloc(my_length);
  21.181 -    if (buffer == NULL)
  21.182 -    {
  21.183 -        printf("(pdb) read memory: malloc failed.\n");  fflush(stdout);
  21.184 -        failwith("read memory error");
  21.185 -    }
  21.186 -
  21.187 -    if ( xendebug_read_memory(xc_handle, ctx.domain, ctx.vcpu, 
  21.188 -                              my_address, my_length, buffer) )
  21.189 -    {
  21.190 -        printf("(pdb) read memory error!\n");  fflush(stdout);
  21.191 -        failwith("read memory error");
  21.192 -    }
  21.193 -
  21.194 -    result = caml_alloc(2,0);
  21.195 -    if ( my_length > 0 )                                              /* car */
  21.196 -    {
  21.197 -        Store_field(result, 0, Val_int(buffer[my_length - 1] & 0xff));
  21.198 -    }
  21.199 -    else
  21.200 -
  21.201 -    {
  21.202 -        Store_field(result, 0, Val_int(0));                    
  21.203 -    }
  21.204 -    Store_field(result, 1, Val_int(0));                               /* cdr */
  21.205 -
  21.206 -    for (loop = 1; loop < my_length; loop++)
  21.207 -    {
  21.208 -        temp = result;
  21.209 -        result = caml_alloc(2,0);
  21.210 -        Store_field(result, 0, Val_int(buffer[my_length - loop - 1] & 0xff));
  21.211 -        Store_field(result, 1, temp);
  21.212 -    }
  21.213 -
  21.214 -    CAMLreturn(result);
  21.215 -}
  21.216 -
  21.217 -/*
  21.218 - * write_memory : context_t -> int32 -> int list -> unit
  21.219 - */
  21.220 -value
  21.221 -write_memory (value context, value address, value val_list)
  21.222 -{
  21.223 -    CAMLparam3(context, address, val_list);
  21.224 -    CAMLlocal1(node);
  21.225 -
  21.226 -    context_t ctx;
  21.227 -
  21.228 -    char buffer[4096];  /* a big buffer */
  21.229 -    memory_t  my_address;
  21.230 -    u32 length = 0;
  21.231 -
  21.232 -    printf ("(pdb) write memory\n");
  21.233 -
  21.234 -    decode_context(&ctx, context);
  21.235 -
  21.236 -    node = val_list;
  21.237 -    if ( Int_val(node) == 0 )       /* gdb functionalty test uses empty list */
  21.238 -    {
  21.239 -        CAMLreturn(Val_unit);
  21.240 -    }
  21.241 -
  21.242 -    while ( Int_val(Field(node,1)) != 0 )
  21.243 -    {
  21.244 -        buffer[length++] = Int_val(Field(node, 0));
  21.245 -        node = Field(node,1);
  21.246 -    }
  21.247 -    buffer[length++] = Int_val(Field(node, 0));
  21.248 -
  21.249 -    my_address = (memory_t) Int32_val(address);
  21.250 -
  21.251 -    if ( xendebug_write_memory(xc_handle, ctx.domain, ctx.vcpu,
  21.252 -                               my_address, length, buffer) )
  21.253 -    {
  21.254 -        printf("(pdb) write memory error!\n");  fflush(stdout);
  21.255 -        failwith("write memory error");
  21.256 -    }
  21.257 -
  21.258 -    CAMLreturn(Val_unit);
  21.259 -}
  21.260 -
  21.261  
  21.262  /*********************************************************************/
  21.263  
  21.264 @@ -322,153 +89,6 @@ dump_regs (cpu_user_regs_t *regs)
  21.265  }
  21.266  
  21.267  /*
  21.268 - * continue_target : context_t -> unit
  21.269 - */
  21.270 -value
  21.271 -continue_target (value context)
  21.272 -{
  21.273 -    CAMLparam1(context);
  21.274 -
  21.275 -    context_t ctx;
  21.276 -
  21.277 -    decode_context(&ctx, context);
  21.278 -
  21.279 -    if ( xendebug_continue(xc_handle, ctx.domain, ctx.vcpu) )
  21.280 -    {
  21.281 -        printf("(pdb) continue\n");  fflush(stdout);
  21.282 -        failwith("continue");
  21.283 -    }
  21.284 -
  21.285 -    CAMLreturn(Val_unit);
  21.286 -}
  21.287 -
  21.288 -/*
  21.289 - * step_target : context_t -> unit
  21.290 - */
  21.291 -value
  21.292 -step_target (value context)
  21.293 -{
  21.294 -    CAMLparam1(context);
  21.295 -
  21.296 -    context_t ctx;
  21.297 -
  21.298 -    decode_context(&ctx, context);
  21.299 -
  21.300 -    if ( xendebug_step(xc_handle, ctx.domain, ctx.vcpu) )
  21.301 -    {
  21.302 -        printf("(pdb) step\n");  fflush(stdout);
  21.303 -        failwith("step");
  21.304 -    }
  21.305 -
  21.306 -    CAMLreturn(Val_unit);
  21.307 -}
  21.308 -
  21.309 -
  21.310 -
  21.311 -/*
  21.312 - * insert_memory_breakpoint : context_t -> int32 -> int list -> unit
  21.313 - */
  21.314 -value
  21.315 -insert_memory_breakpoint (value context, value address, value length)
  21.316 -{
  21.317 -    CAMLparam3(context, address, length);
  21.318 -
  21.319 -    context_t ctx;
  21.320 -    memory_t my_address = (memory_t) Int32_val(address);
  21.321 -    int my_length = Int_val(length);
  21.322 -
  21.323 -    decode_context(&ctx, context);
  21.324 -
  21.325 -    printf ("(pdb) insert memory breakpoint 0x%lx %d\n",
  21.326 -            my_address, my_length);
  21.327 -
  21.328 -    if ( xendebug_insert_memory_breakpoint(xc_handle, ctx.domain, ctx.vcpu,
  21.329 -                                           my_address, my_length) )
  21.330 -    {
  21.331 -        printf("(pdb) error: insert memory breakpoint\n");  fflush(stdout);
  21.332 -        failwith("insert memory breakpoint");
  21.333 -    }
  21.334 -
  21.335 -
  21.336 -    CAMLreturn(Val_unit);
  21.337 -}
  21.338 -
  21.339 -/*
  21.340 - * remove_memory_breakpoint : context_t -> int32 -> int list -> unit
  21.341 - */
  21.342 -value
  21.343 -remove_memory_breakpoint (value context, value address, value length)
  21.344 -{
  21.345 -    CAMLparam3(context, address, length);
  21.346 -
  21.347 -    context_t ctx;
  21.348 -
  21.349 -    memory_t my_address = (memory_t) Int32_val(address);
  21.350 -    int my_length = Int_val(length);
  21.351 -
  21.352 -    printf ("(pdb) remove memory breakpoint 0x%lx %d\n",
  21.353 -            my_address, my_length);
  21.354 -
  21.355 -    decode_context(&ctx, context);
  21.356 -
  21.357 -    if ( xendebug_remove_memory_breakpoint(xc_handle, 
  21.358 -                                           ctx.domain, ctx.vcpu,
  21.359 -                                           my_address, my_length) )
  21.360 -    {
  21.361 -        printf("(pdb) error: remove memory breakpoint\n");  fflush(stdout);
  21.362 -        failwith("remove memory breakpoint");
  21.363 -    }
  21.364 -
  21.365 -    CAMLreturn(Val_unit);
  21.366 -}
  21.367 -
  21.368 -/*
  21.369 - * attach_debugger : int -> int -> unit
  21.370 - */
  21.371 -value
  21.372 -attach_debugger (value domain, value vcpu)
  21.373 -{
  21.374 -    CAMLparam2(domain, vcpu);
  21.375 -
  21.376 -    int my_domain = Int_val(domain);
  21.377 -    int my_vcpu = Int_val(vcpu);
  21.378 -
  21.379 -    printf ("(pdb) attach domain [%d.%d]\n", my_domain, my_vcpu);
  21.380 -
  21.381 -    if ( xendebug_attach(xc_handle, my_domain, my_vcpu) )
  21.382 -    {
  21.383 -        printf("(pdb) attach error!\n");  fflush(stdout);
  21.384 -        failwith("attach error");
  21.385 -    }
  21.386 -
  21.387 -    CAMLreturn(Val_unit);
  21.388 -}
  21.389 -
  21.390 -
  21.391 -/*
  21.392 - * detach_debugger : int -> int -> unit
  21.393 - */
  21.394 -value
  21.395 -detach_debugger (value domain, value vcpu)
  21.396 -{
  21.397 -    CAMLparam2(domain, vcpu);
  21.398 -
  21.399 -    int my_domain = Int_val(domain);
  21.400 -    int my_vcpu = Int_val(vcpu);
  21.401 -
  21.402 -    printf ("(pdb) detach domain [%d.%d]\n", my_domain, my_vcpu);
  21.403 -
  21.404 -    if ( xendebug_detach(xc_handle, my_domain, my_vcpu) )
  21.405 -    {
  21.406 -        printf("(pdb) detach error!\n");  fflush(stdout);
  21.407 -        failwith("detach error");
  21.408 -    }
  21.409 -
  21.410 -    CAMLreturn(Val_unit);
  21.411 -}
  21.412 -
  21.413 -
  21.414 -/*
  21.415   * debugger_status : unit -> unit
  21.416   */
  21.417  value
  21.418 @@ -476,25 +96,6 @@ debugger_status (value unit)
  21.419  {
  21.420      CAMLparam1(unit);
  21.421  
  21.422 -    printf ("(pdb) debugger status\n");
  21.423 -
  21.424 -    CAMLreturn(Val_unit);
  21.425 -}
  21.426 -
  21.427 -/*
  21.428 - * pause_target : int -> unit
  21.429 - */
  21.430 -value
  21.431 -pause_target (value domid)
  21.432 -{
  21.433 -    CAMLparam1(domid);
  21.434 -
  21.435 -    int my_domid = Int_val(domid);
  21.436 -
  21.437 -    printf ("(pdb) pause target %d\n", my_domid);
  21.438 -
  21.439 -    xc_domain_pause(xc_handle, my_domid);
  21.440 -
  21.441      CAMLreturn(Val_unit);
  21.442  }
  21.443  
  21.444 @@ -502,108 +103,6 @@ pause_target (value domid)
  21.445  /****************************************************************************/
  21.446  
  21.447  /*
  21.448 - * query_domain_stop : unit -> (int * int) list
  21.449 - */
  21.450 -value
  21.451 -query_domain_stop (value unit)
  21.452 -{
  21.453 -    CAMLparam1(unit);
  21.454 -    CAMLlocal3(result, temp, node);
  21.455 -
  21.456 -    int max_domains = 20;
  21.457 -    int dom_list[max_domains];
  21.458 -    int loop, count;
  21.459 -
  21.460 -    count = xendebug_query_domain_stop(xc_handle, dom_list, max_domains);
  21.461 -    if ( count < 0 )
  21.462 -    {
  21.463 -        printf("(pdb) query domain stop!\n");  fflush(stdout);
  21.464 -        failwith("query domain stop");
  21.465 -    }
  21.466 -
  21.467 -    printf ("QDS: %d\n", count);
  21.468 -    for (loop = 0; loop < count; loop ++)
  21.469 -        printf ("  %d %d\n", loop, dom_list[loop]);
  21.470 -
  21.471 -    result = caml_alloc(2,0);
  21.472 -    if ( count > 0 )                                                  /* car */
  21.473 -    {
  21.474 -        node = caml_alloc(2,0);
  21.475 -        Store_field(node, 0, Val_int(dom_list[0]));             /* domain id */
  21.476 -        Store_field(node, 1, Val_int(0));                            /* vcpu */
  21.477 -        Store_field(result, 0, node);
  21.478 -    }
  21.479 -    else
  21.480 -    {
  21.481 -        Store_field(result, 0, Val_int(0));                    
  21.482 -    }
  21.483 -    Store_field(result, 1, Val_int(0));                               /* cdr */
  21.484 -
  21.485 -    for ( loop = 1; loop < count; loop++ )
  21.486 -    {
  21.487 -        temp = result;
  21.488 -        result = caml_alloc(2,0);
  21.489 -        node = caml_alloc(2,0);
  21.490 -        Store_field(node, 0, Val_int(dom_list[loop]));          /* domain id */
  21.491 -        Store_field(node, 1, Val_int(0));                            /* vcpu */
  21.492 -        Store_field(result, 0, node);
  21.493 -        Store_field(result, 1, temp);
  21.494 -    }
  21.495 -
  21.496 -    CAMLreturn(result);
  21.497 -}
  21.498 -
  21.499 -/****************************************************************************/
  21.500 -/****************************************************************************/
  21.501 -
  21.502 -#include <errno.h>
  21.503 -#include <sys/ioctl.h>
  21.504 -#include <sys/stat.h>
  21.505 -#include <fcntl.h>
  21.506 -#include <unistd.h>
  21.507 -
  21.508 -/*
  21.509 - * evtchn_open : string -> int -> int -> Unix.file_descr
  21.510 - *
  21.511 - * OCaml's Unix library doesn't have mknod, so it makes more sense just write
  21.512 - * this in C.  This code is from Keir/Andy.
  21.513 - */
  21.514 -value
  21.515 -evtchn_open (value filename, value major, value minor)
  21.516 -{
  21.517 -    CAMLparam3(filename, major, minor);
  21.518 -
  21.519 -    char *myfilename = String_val(filename);
  21.520 -    int   mymajor = Int_val(major);
  21.521 -    int   myminor = Int_val(minor);
  21.522 -    int   evtchn_fd;
  21.523 -    struct stat st;
  21.524 -    
  21.525 -    /* Make sure any existing device file links to correct device. */
  21.526 -    if ( (lstat(myfilename, &st) != 0) ||
  21.527 -         !S_ISCHR(st.st_mode) ||
  21.528 -         (st.st_rdev != makedev(mymajor, myminor)) )
  21.529 -    {
  21.530 -        (void)unlink(myfilename);
  21.531 -    }
  21.532 -
  21.533 - reopen:
  21.534 -    evtchn_fd = open(myfilename, O_RDWR); 
  21.535 -    if ( evtchn_fd == -1 )
  21.536 -    {
  21.537 -        if ( (errno == ENOENT) &&
  21.538 -             ((mkdir("/dev/xen", 0755) == 0) || (errno == EEXIST)) &&
  21.539 -             (mknod(myfilename, S_IFCHR|0600, makedev(mymajor,myminor)) == 0) )
  21.540 -        {
  21.541 -            goto reopen;
  21.542 -        }
  21.543 -        return -errno;
  21.544 -    }
  21.545 -
  21.546 -    CAMLreturn(Val_int(evtchn_fd));
  21.547 -}
  21.548 -
  21.549 -/*
  21.550   * evtchn_bind_virq : int -> int
  21.551   */
  21.552  value
  21.553 @@ -612,8 +111,9 @@ evtchn_bind_virq (value virq)
  21.554      CAMLparam1(virq);
  21.555  
  21.556      int port;
  21.557 +    int my_virq = Int_val(virq);
  21.558  
  21.559 -    if ( pdb_evtchn_bind_virq(xc_handle, Int_val(virq), &port) < 0 )
  21.560 +    if ( xc_evtchn_bind_virq(xc_handle, my_virq, &port) < 0 )
  21.561      {
  21.562          printf("(pdb) evtchn_bind_virq error!\n");  fflush(stdout);
  21.563          failwith("evtchn_bind_virq error");
  21.564 @@ -623,102 +123,40 @@ evtchn_bind_virq (value virq)
  21.565  }
  21.566  
  21.567  /*
  21.568 - * evtchn_bind : Unix.file_descr -> int -> unit
  21.569 - */
  21.570 -value
  21.571 -evtchn_bind (value fd, value idx)
  21.572 -{
  21.573 -    CAMLparam2(fd, idx);
  21.574 -
  21.575 -    int myfd = Int_val(fd);
  21.576 -    int myidx = Int_val(idx);
  21.577 -
  21.578 -    if ( xen_evtchn_bind(myfd, myidx) < 0 )
  21.579 -    {
  21.580 -        printf("(pdb) evtchn_bind error!\n");  fflush(stdout);
  21.581 -        failwith("evtchn_bind error");
  21.582 -    }
  21.583 -
  21.584 -    CAMLreturn(Val_unit);
  21.585 -}
  21.586 -
  21.587 -/*
  21.588 - * evtchn_unbind : Unix.file_descr -> int -> unit
  21.589 - */
  21.590 -value
  21.591 -evtchn_unbind (value fd, value idx)
  21.592 -{
  21.593 -    CAMLparam2(fd, idx);
  21.594 -
  21.595 -    int myfd = Int_val(fd);
  21.596 -    int myidx = Int_val(idx);
  21.597 -
  21.598 -    if ( xen_evtchn_unbind(myfd, myidx) < 0 )
  21.599 -    {
  21.600 -        printf("(pdb) evtchn_unbind error!\n");  fflush(stdout);
  21.601 -        failwith("evtchn_unbind error");
  21.602 -    }
  21.603 -
  21.604 -    CAMLreturn(Val_unit);
  21.605 -}
  21.606 -
  21.607 -/*
  21.608 - * evtchn_read : Unix.file_descr -> int
  21.609 + * evtchn_bind_interdomain : int -> int * int
  21.610   */
  21.611  value
  21.612 -evtchn_read (value fd)
  21.613 +evtchn_bind_interdomain (value remote_domain)
  21.614  {
  21.615 -    CAMLparam1(fd);
  21.616 +    CAMLparam1(remote_domain);
  21.617 +    CAMLlocal1(result);
  21.618  
  21.619 -    u16 v;
  21.620 -    int bytes;
  21.621 -    int rc = -1;
  21.622 -    int myfd = Int_val(fd);
  21.623 +    int my_remote_domain = Int_val(remote_domain);
  21.624 +    int local_domain = 0;
  21.625 +    int local_port = 0;
  21.626 +    int remote_port = 0;
  21.627  
  21.628 -    while ( (bytes = read(myfd, &v, sizeof(v))) == -1 )
  21.629 +    if ( xc_evtchn_bind_interdomain(xc_handle, local_domain, my_remote_domain,
  21.630 +                                    &local_port, &remote_port) < 0 )
  21.631      {
  21.632 -        if ( errno == EINTR )  continue;
  21.633 -        rc = -errno;
  21.634 -        goto exit;
  21.635 +        printf("(pdb) evtchn_bind_interdomain error!\n");  fflush(stdout);
  21.636 +        failwith("evtchn_bind_interdomain error");
  21.637      }
  21.638 -    
  21.639 -    if ( bytes == sizeof(v) )
  21.640 -        rc = v;
  21.641 -    
  21.642 - exit:
  21.643 -    CAMLreturn(Val_int(rc));
  21.644 +
  21.645 +    result = caml_alloc_tuple(2);                                   /* FIXME */
  21.646 +    Store_field(result, 0, Val_int(local_port));
  21.647 +    Store_field(result, 1, Val_int(remote_port));
  21.648 +
  21.649 +    CAMLreturn(result);
  21.650  }
  21.651  
  21.652 -
  21.653 -/*
  21.654 - * evtchn_close : Unix.file_descr -> unit
  21.655 - */
  21.656 -value
  21.657 -evtchn_close (value fd)
  21.658 +void *
  21.659 +map_ring(u32 dom, unsigned long mfn )
  21.660  {
  21.661 -    CAMLparam1(fd);
  21.662 -    int myfd = Int_val(fd);
  21.663 -
  21.664 -    (void)close(myfd);
  21.665 -
  21.666 -    CAMLreturn(Val_unit);
  21.667 +    return xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
  21.668 +                                PROT_READ | PROT_WRITE, mfn);
  21.669  }
  21.670  
  21.671 -/*
  21.672 - * evtchn_unmask : Unix.file_descr -> int -> unit
  21.673 - */
  21.674 -value
  21.675 -evtchn_unmask (value fd, value idx)
  21.676 -{
  21.677 -    CAMLparam1(fd);
  21.678 -
  21.679 -    int myfd = Int_val(fd);
  21.680 -    u16 myidx = Int_val(idx);
  21.681 -
  21.682 -    (void)write(myfd, &myidx, sizeof(myidx));
  21.683 -
  21.684 -    CAMLreturn(Val_unit);
  21.685 -}
  21.686  
  21.687  /*
  21.688   * Local variables:
    22.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    22.2 +++ b/tools/debugger/pdb/pdb_caml_xcs.c	Mon Jun 27 21:31:56 2005 +0000
    22.3 @@ -0,0 +1,305 @@
    22.4 +/*
    22.5 + *  xcs stuff
    22.6 + *
    22.7 + *  this is responsible for establishing the initial connection
    22.8 + *  between a backend domain and the pdb server.
    22.9 + *
   22.10 + *  liberated from xu.c
   22.11 + *
   22.12 + */
   22.13 +#include <stdio.h>
   22.14 +#include <stdlib.h>
   22.15 +#include <unistd.h>
   22.16 +#include <sys/un.h>
   22.17 +#include <sys/types.h>
   22.18 +#include <sys/socket.h>
   22.19 +#include <errno.h>
   22.20 +#include <xc.h>
   22.21 +
   22.22 +#include <xen/xen.h>
   22.23 +#include <xen/io/domain_controller.h>
   22.24 +#include <xen/linux/privcmd.h>
   22.25 +
   22.26 +#include <arpa/inet.h>
   22.27 +#include <xcs_proto.h>
   22.28 +
   22.29 +#include <caml/alloc.h>
   22.30 +#include <caml/fail.h>
   22.31 +#include <caml/memory.h>
   22.32 +#include <caml/mlvalues.h>
   22.33 +
   22.34 +static int control_fd = -1;
   22.35 +
   22.36 +#include "pdb_module.h"
   22.37 +#include "pdb_caml_xen.h"
   22.38 +
   22.39 +void *map_ring(u32 dom, unsigned long mfn );
   22.40 +
   22.41 +/*
   22.42 + * xcs_initialize_ring : int -> int32 -> int32
   22.43 + *
   22.44 + * initialize a communications ring
   22.45 + * (probably belongs in a different file :)
   22.46 + */
   22.47 +
   22.48 +value
   22.49 +xcs_initialize_ring (value domain, value ring)
   22.50 +{
   22.51 +    CAMLparam2(domain, ring);
   22.52 +    int my_domain = Int_val(domain);
   22.53 +    memory_t my_ring = Int32_val(ring);
   22.54 +
   22.55 +    pdb_front_ring_t *front_ring;
   22.56 +    pdb_sring_t *sring;
   22.57 +
   22.58 +    front_ring = (pdb_front_ring_t *)malloc(sizeof(pdb_front_ring_t));
   22.59 +    if ( front_ring == NULL )
   22.60 +    {
   22.61 +        printf("(pdb) xcs initialize ring: malloc failed.\n");  fflush(stdout);
   22.62 +        failwith("xcs initialize ring: malloc");
   22.63 +    }
   22.64 +
   22.65 +    sring = map_ring(my_domain, my_ring);
   22.66 +    if ( sring == NULL )
   22.67 +    {
   22.68 +        printf("(pdb) xcs initialize ring: map ring failed.\n");fflush(stdout);
   22.69 +        failwith("xcs initialize ring: map ring");
   22.70 +    }
   22.71 +    FRONT_RING_INIT(front_ring, sring, PAGE_SIZE);
   22.72 +
   22.73 +    CAMLreturn(caml_copy_int32((unsigned long)front_ring));
   22.74 +}
   22.75 +
   22.76 +
   22.77 +/*
   22.78 + * xcs_write_message : Unix.file_descr -> xcs_message -> unit
   22.79 + *
   22.80 + * ack a packet
   22.81 + */
   22.82 +value
   22.83 +xcs_write_message (value data_fd, value msg)
   22.84 +{
   22.85 +    CAMLparam2(data_fd, msg);
   22.86 +    int my_data_fd = Int_val(data_fd);
   22.87 +    xcs_msg_t my_msg;
   22.88 +    pdb_connection_p conn;
   22.89 +
   22.90 +    my_msg.type = XCS_REQUEST;
   22.91 +    my_msg.u.control.remote_dom = Int_val(Field(msg,0));
   22.92 +    my_msg.u.control.msg.type = CMSG_DEBUG;
   22.93 +    my_msg.u.control.msg.subtype = CMSG_DEBUG_CONNECTION_STATUS;
   22.94 +    my_msg.u.control.msg.id = 0;
   22.95 +    my_msg.u.control.msg.length = sizeof(pdb_connection_t);
   22.96 +
   22.97 +    conn = (pdb_connection_p)my_msg.u.control.msg.msg;
   22.98 +
   22.99 +    conn->status = Int_val(Field(msg,1));
  22.100 +    conn->ring = Int32_val(Field(msg,2));
  22.101 +    conn->evtchn = Int_val(Field(msg,3));
  22.102 +        
  22.103 +    send(my_data_fd, &my_msg, sizeof(xcs_msg_t), 0);                  /* ack */
  22.104 +
  22.105 +    CAMLreturn(Val_unit);
  22.106 +}
  22.107 +
  22.108 +/*
  22.109 + * xcs_read_message : Unix.file_descr -> xcs_message
  22.110 + *
  22.111 + * read pending data on xcs socket.
  22.112 + */
  22.113 +
  22.114 +value
  22.115 +xcs_read_message (value data_fd)
  22.116 +{
  22.117 +    CAMLparam1(data_fd);
  22.118 +    CAMLlocal1(result);
  22.119 +    int my_data_fd = Int_val(data_fd);
  22.120 +    xcs_msg_t msg;
  22.121 +
  22.122 +    if ( read(my_data_fd, &msg, sizeof(xcs_msg_t)) < 0 )
  22.123 +    {
  22.124 +        perror("read");
  22.125 +        failwith("xcs message: read");
  22.126 +    }
  22.127 +
  22.128 +    switch (msg.type)
  22.129 +    {
  22.130 +    case XCS_REQUEST :
  22.131 +    {
  22.132 +        pdb_connection_p conn;
  22.133 +
  22.134 +        if ( msg.u.control.msg.type != CMSG_DEBUG ||
  22.135 +             msg.u.control.msg.subtype != CMSG_DEBUG_CONNECTION_STATUS )
  22.136 +        {
  22.137 +            printf("bogus message type: %d %d\n", 
  22.138 +                   msg.u.control.msg.type, msg.u.control.msg.subtype);
  22.139 +            failwith("xcs message: invalid message type");
  22.140 +        }
  22.141 +
  22.142 +        conn = (pdb_connection_p) msg.u.control.msg.msg;
  22.143 +        
  22.144 +        result = caml_alloc_tuple(4);                               /* FIXME */
  22.145 +        Store_field(result, 0, Val_int(msg.u.control.remote_dom)); /* domain */
  22.146 +        Store_field(result, 1, Val_int(conn->status));             /* status */
  22.147 +        Store_field(result, 2, caml_copy_int32(conn->ring));         /* ring */
  22.148 +        Store_field(result, 3, Val_int(0));                   /* OUT: evtchn */
  22.149 +
  22.150 +        break;
  22.151 +    }
  22.152 +    case XCS_RESPONSE :
  22.153 +    {
  22.154 +        printf("[XCS RESPONSE]  type: %d, remote_dom: %d\n", 
  22.155 +               msg.type, msg.u.control.remote_dom);
  22.156 +        printf("strange.  we never initiate messages, so what is the ");
  22.157 +        printf("domain responding to?\n");
  22.158 +        failwith ("xcs message: resonse");
  22.159 +        break;
  22.160 +    }
  22.161 +    default:
  22.162 +    {
  22.163 +        printf("[XCS IGNORE] type: %d\n", msg.type);
  22.164 +        failwith ("xcs message: unknown");
  22.165 +        break;
  22.166 +    }
  22.167 +    }
  22.168 +
  22.169 +    CAMLreturn(result);
  22.170 +}
  22.171 +
  22.172 +/*
  22.173 + * xcs_connect : string -> int -> Unix.file_descr
  22.174 + */
  22.175 +
  22.176 +value
  22.177 +xcs_connect (value path, value msg_type)
  22.178 +{
  22.179 +    CAMLparam2(path, msg_type);
  22.180 +    char *my_path = String_val(path);
  22.181 +    int my_msg_type = Int_val(msg_type);
  22.182 +    struct sockaddr_un addr;
  22.183 +    u32 session_id = 0;
  22.184 +    int data_fd;
  22.185 +    int ret, len;
  22.186 +    xcs_msg_t msg;
  22.187 +
  22.188 +    /* setup control channel connection to xcs */
  22.189 +
  22.190 +    control_fd = socket(AF_UNIX, SOCK_STREAM, 0);
  22.191 +    if ( control_fd < 0 )
  22.192 +    {
  22.193 +        printf("error creating xcs socket!\n");
  22.194 +        goto fail;
  22.195 +    }
  22.196 +
  22.197 +    addr.sun_family = AF_UNIX;
  22.198 +    strcpy(addr.sun_path, my_path);
  22.199 +    len = sizeof(addr.sun_family) + strlen(addr.sun_path) + 1;
  22.200 +
  22.201 +    ret = connect(control_fd, (struct sockaddr *)&addr, len);
  22.202 +    if (ret < 0) 
  22.203 +    {
  22.204 +        printf("error connecting to xcs(ctrl)! (%d)\n", errno);
  22.205 +        goto ctrl_fd_fail;
  22.206 +    }
  22.207 +            
  22.208 +    msg.type = XCS_CONNECT_CTRL;
  22.209 +    msg.u.connect.session_id = session_id;
  22.210 +    send(control_fd, &msg, sizeof(xcs_msg_t), 0);
  22.211 +    /* bug: this should have a timeout & error! */
  22.212 +    read(control_fd, &msg, sizeof(xcs_msg_t));
  22.213 +    
  22.214 +    if (msg.result != XCS_RSLT_OK)
  22.215 +    {
  22.216 +        printf("error connecting xcs control channel!\n");
  22.217 +        goto ctrl_fd_fail;
  22.218 +    }
  22.219 +    session_id = msg.u.connect.session_id;
  22.220 +
  22.221 +
  22.222 +    /* setup data channel connection to xcs */
  22.223 +    
  22.224 +    data_fd = socket(AF_UNIX, SOCK_STREAM, 0);
  22.225 +    if ( data_fd < 0 )
  22.226 +    {
  22.227 +        printf("error creating xcs data socket!\n");
  22.228 +        goto ctrl_fd_fail;
  22.229 +    }
  22.230 +    
  22.231 +    addr.sun_family = AF_UNIX;
  22.232 +    strcpy(addr.sun_path, my_path);
  22.233 +    len = sizeof(addr.sun_family) + strlen(addr.sun_path) + 1;
  22.234 +    
  22.235 +    ret = connect(data_fd, (struct sockaddr *)&addr, len);
  22.236 +    if (ret < 0) 
  22.237 +    {
  22.238 +        printf("error connecting to xcs(data)! (%d)\n", errno);
  22.239 +        goto data_fd_fail;
  22.240 +    }
  22.241 +
  22.242 +    msg.type = XCS_CONNECT_DATA;
  22.243 +    msg.u.connect.session_id = session_id;
  22.244 +    send(data_fd, &msg, sizeof(xcs_msg_t), 0);
  22.245 +    read(data_fd, &msg, sizeof(xcs_msg_t));                      /* same bug */
  22.246 +    
  22.247 +    if ( msg.result != XCS_RSLT_OK )
  22.248 +    {
  22.249 +        printf("error connecting xcs control channel!\n");
  22.250 +        goto ctrl_fd_fail;
  22.251 +    }
  22.252 +
  22.253 +
  22.254 +
  22.255 +    /* now request all messages of a particular type */
  22.256 +
  22.257 +    msg.type = XCS_MSG_BIND;
  22.258 +    msg.u.bind.port = PORT_WILDCARD;
  22.259 +    msg.u.bind.type = my_msg_type;
  22.260 +    send(control_fd, &msg, sizeof(xcs_msg_t), 0);
  22.261 +    read(control_fd, &msg, sizeof(xcs_msg_t));                /* still buggy */
  22.262 +
  22.263 +    if (msg.result != XCS_RSLT_OK) {
  22.264 +        printf ("error: MSG BIND\n");
  22.265 +	goto bind_fail;
  22.266 +    }
  22.267 +
  22.268 +    CAMLreturn(Val_int(data_fd));
  22.269 +
  22.270 +bind_fail:
  22.271 +data_fd_fail: 
  22.272 +    close(data_fd);  
  22.273 +    
  22.274 +ctrl_fd_fail:
  22.275 +    close(control_fd);
  22.276 +     
  22.277 +fail:
  22.278 +    failwith("xcs connection error");             /* should be more explicit */
  22.279 +}
  22.280 +
  22.281 +
  22.282 +/* xcs_disconnect: Unix.file_descr -> unit */
  22.283 +
  22.284 +value
  22.285 +xcs_disconnect (value data_fd)
  22.286 +{
  22.287 +    CAMLparam1(data_fd);
  22.288 +
  22.289 +    int my_data_fd = Int_val(data_fd);
  22.290 +
  22.291 +    close(my_data_fd);
  22.292 +    close(control_fd);
  22.293 +    control_fd = -1;
  22.294 +
  22.295 +    CAMLreturn(Val_unit);
  22.296 +}
  22.297 +
  22.298 +
  22.299 +/*
  22.300 + * Local variables:
  22.301 + * mode: C
  22.302 + * c-set-style: "BSD"
  22.303 + * c-basic-offset: 4
  22.304 + * tab-width: 4
  22.305 + * indent-tabs-mode: nil
  22.306 + * End:
  22.307 + */
  22.308 +
    23.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    23.2 +++ b/tools/debugger/pdb/pdb_caml_xen.h	Mon Jun 27 21:31:56 2005 +0000
    23.3 @@ -0,0 +1,18 @@
    23.4 +
    23.5 +#ifndef _PDB_CAML_XEN_DEFINED_
    23.6 +#define _PDB_CAML_XEN_DEFINED_
    23.7 +
    23.8 +enum gdb_registers { GDB_EAX, GDB_ECX, GDB_EDX, GDB_EBX,
    23.9 +                     GDB_ESP, GDB_EBP, GDB_ESI, GDB_EDI,
   23.10 +                     GDB_EIP, GDB_EFL, 
   23.11 +                     GDB_CS,  GDB_SS,  GDB_DS,  GDB_ES,
   23.12 +                     GDB_FS,  GDB_GS };
   23.13 +
   23.14 +#define PAGE_SIZE 4096
   23.15 +
   23.16 +extern int xc_handle;
   23.17 +
   23.18 +void dump_regs (cpu_user_regs_t *ctx);
   23.19 +
   23.20 +#endif
   23.21 +
    24.1 --- a/tools/debugger/pdb/pdb_xen.c	Mon Jun 27 20:17:02 2005 +0000
    24.2 +++ b/tools/debugger/pdb/pdb_xen.c	Mon Jun 27 21:31:56 2005 +0000
    24.3 @@ -42,20 +42,6 @@ pdb_close (int xc_handle)
    24.4  }
    24.5  
    24.6  
    24.7 -int 
    24.8 -pdb_evtchn_bind_virq (int xc_handle, int virq, int *port)
    24.9 -{
   24.10 -    int rc;
   24.11 -    
   24.12 -    if ( (rc = xc_evtchn_bind_virq(xc_handle, virq, port) < 0 ) )
   24.13 -    {
   24.14 -        fprintf(stderr, "(pdb) error binding virq to event channel: %d (%s)\n",
   24.15 -                errno, strerror(errno));
   24.16 -    }
   24.17 -    return rc;
   24.18 -}
   24.19 -
   24.20 -
   24.21  #include <sys/ioctl.h>
   24.22  
   24.23  /* /dev/xen/evtchn ioctls */
    25.1 --- a/tools/debugger/pdb/server.ml	Mon Jun 27 20:17:02 2005 +0000
    25.2 +++ b/tools/debugger/pdb/server.ml	Mon Jun 27 21:31:56 2005 +0000
    25.3 @@ -59,6 +59,7 @@ let process_input conn sock =
    25.4    conn.length <- conn.length + length;
    25.5    let re = Str.regexp "[^\\$]*\\$\\([^#]*\\)#\\(..\\)" in
    25.6  
    25.7 +  (* interrupt the target if there was a ctrl-c *)
    25.8    begin
    25.9      try
   25.10        let break = String.index conn.buffer '\003' + 1 in
   25.11 @@ -118,9 +119,13 @@ let process_input conn sock =
   25.12   *  connection_hash is a hash (duh!) with one connection_t for each
   25.13   *  open connection.
   25.14   * 
   25.15 - *  in_list is a list of active sockets.  it also contains two 
   25.16 - *  magic entries: server_sock for accepting new entries and 
   25.17 - *  event_sock for Xen event channel asynchronous notifications.
   25.18 + *  in_list is a list of active sockets.  it also contains a number
   25.19 + *  of magic entries: 
   25.20 + *  - server_sock   for accepting new client connections (e.g. gdb)
   25.21 + *  - xen_virq_sock for Xen virq asynchronous notifications (via evtchn).
   25.22 + *                  This is used by context = domain
   25.23 + *  - xcs_sock      for xcs messages when a new backend domain registers
   25.24 + *                  This is used by context = process
   25.25   *)
   25.26  let main_server_loop sockaddr =
   25.27    let connection_hash = Hashtbl.create 10
   25.28 @@ -143,10 +148,20 @@ let main_server_loop sockaddr =
   25.29        begin
   25.30  	try
   25.31  	  match PDB.find_context sock with
   25.32 -	  | PDB.Event_channel ->
   25.33 -	      print_endline (Printf.sprintf "[%s] event channel"
   25.34 +	  | PDB.Xen_virq ->
   25.35 +	      print_endline (Printf.sprintf "[%s] Xen virq"
   25.36  			                    (Util.get_connection_info sock));
   25.37 -	      Debugger.process_evtchn sock;
   25.38 +	      Debugger.process_xen_virq sock;
   25.39 +	      (new_list, closed_list)
   25.40 +	  | PDB.Xen_xcs ->
   25.41 +	      print_endline (Printf.sprintf "[%s] Xen xcs"
   25.42 +			                    (Util.get_connection_info sock));
   25.43 +	      let new_xen_domain = Debugger.process_xen_xcs sock in
   25.44 +	      (new_xen_domain :: new_list, closed_list)
   25.45 +	  | PDB.Xen_domain d ->
   25.46 +	      print_endline (Printf.sprintf "[%s] Xen domain"
   25.47 +			                    (Util.get_connection_info sock));
   25.48 +	      Debugger.process_xen_domain sock;
   25.49  	      (new_list, closed_list)
   25.50  	  | _ ->
   25.51  	      let conn = Hashtbl.find connection_hash sock in
   25.52 @@ -167,18 +182,22 @@ let main_server_loop sockaddr =
   25.53  	    (new_list, sock :: closed_list)
   25.54        end
   25.55    in
   25.56 +
   25.57    let rec helper in_list server_sock =
   25.58 -  (*
   25.59 -   * List.iter (fun x->Printf.printf "{%s} " 
   25.60 -   *                                (Util.get_connection_info x)) in_list;   
   25.61 -   * Printf.printf "\n";
   25.62 -   *)
   25.63 +
   25.64 +    (*    
   25.65 +     List.iter (fun x->Printf.printf " {%s}\n" 
   25.66 +                                    (Util.get_connection_info x)) in_list;   
   25.67 +     Printf.printf "\n";
   25.68 +    *)
   25.69 +
   25.70      let (rd_list, _, _) = select in_list [] [] (-1.0) in 
   25.71      let (new_list, closed_list) = List.fold_left (process_socket server_sock)
   25.72  	                                         ([],[]) rd_list  in
   25.73      let merge_list = Util.list_remove (new_list @ in_list) closed_list  in
   25.74      helper merge_list server_sock
   25.75    in
   25.76 +
   25.77    try
   25.78      let server_sock = socket (domain_of_sockaddr sockaddr) SOCK_STREAM 0 in
   25.79      setsockopt server_sock SO_REUSEADDR true;
   25.80 @@ -186,16 +205,19 @@ let main_server_loop sockaddr =
   25.81      listen server_sock 2;
   25.82  
   25.83      PDB.open_debugger ();
   25.84 -    let event_sock = Evtchn.setup () in
   25.85 -    PDB.add_context event_sock "event channel" [];
   25.86 -    helper [server_sock; event_sock] server_sock
   25.87 +    let xen_virq_sock = Evtchn.setup () in
   25.88 +    PDB.add_context xen_virq_sock "xen virq" [];
   25.89 +
   25.90 +    let xcs_sock = Xcs.setup () in
   25.91 +    PDB.add_context xcs_sock "xen xcs" [];
   25.92 +    helper [server_sock; xen_virq_sock; xcs_sock] server_sock
   25.93    with
   25.94    | Sys.Break ->
   25.95        print_endline "break: cleaning up";
   25.96        PDB.close_debugger ();
   25.97        Hashtbl.iter (fun sock conn -> close sock) connection_hash
   25.98 -  | Unix_error(e,err,param) -> 
   25.99 -      Printf.printf "unix error: [%s][%s][%s]\n" (error_message e) err param
  25.100 +(*  | Unix_error(e,err,param) -> 
  25.101 +      Printf.printf "unix error: [%s][%s][%s]\n" (error_message e) err param*)
  25.102    | Sys_error s -> Printf.printf "sys error: [%s]\n" s
  25.103    | Failure s -> Printf.printf "failure: [%s]\n" s
  25.104    | End_of_file -> Printf.printf "end of file\n"
  25.105 @@ -207,7 +229,7 @@ let get_port () =
  25.106      int_of_string Sys.argv.(1)
  25.107    else
  25.108      begin
  25.109 -      print_endline (Printf.sprintf "syntax error: %s <port>" Sys.argv.(0));
  25.110 +      print_endline (Printf.sprintf "error: %s <port>" Sys.argv.(0));
  25.111        exit 1
  25.112      end
  25.113  
    26.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    26.2 +++ b/tools/debugger/pdb/xcs.ml	Mon Jun 27 21:31:56 2005 +0000
    26.3 @@ -0,0 +1,85 @@
    26.4 +(** xcs.ml
    26.5 + *
    26.6 + *  xen control switch interface
    26.7 + *
    26.8 + *  @author copyright (c) 2005 alex ho
    26.9 + *  @see <www.cl.cam.ac.uk/netos/pdb> pervasive debugger
   26.10 + *  @version 1
   26.11 + *)
   26.12 +
   26.13 +open Int32
   26.14 +
   26.15 +let xcs_path = "/var/lib/xen/xcs_socket"                    (* XCS_SUN_PATH *)
   26.16 +let xcs_type = 11                                             (* CMSG_DEBUG *)
   26.17 +
   26.18 +
   26.19 +type xcs_message =
   26.20 +    {
   26.21 +              domain  : int;
   26.22 +              status  : int;
   26.23 +              ring    : int32;
   26.24 +      mutable evtchn  : int;
   26.25 +    }
   26.26 +
   26.27 +external connect : string -> int -> Unix.file_descr = "xcs_connect"
   26.28 +external disconnect : Unix.file_descr -> unit = "xcs_disconnect"
   26.29 +external read_message : Unix.file_descr -> xcs_message = "xcs_read_message"
   26.30 +external write_message : Unix.file_descr -> xcs_message -> unit = 
   26.31 +                                                            "xcs_write_message"
   26.32 +external initialize_ring : int -> int32 -> int32 = "xcs_initialize_ring"
   26.33 +
   26.34 +(*
   26.35 + * initialize xcs stuff
   26.36 + *)
   26.37 +let setup () =
   26.38 +  connect xcs_path xcs_type
   26.39 +
   26.40 +
   26.41 +(*
   26.42 + * adios
   26.43 + *)
   26.44 +let teardown fd =
   26.45 +  disconnect fd
   26.46 +
   26.47 +
   26.48 +(*
   26.49 + * message from a domain backend
   26.50 + *)
   26.51 +let read socket =
   26.52 +  let xcs = read_message socket in
   26.53 +  begin
   26.54 +    match xcs.status with
   26.55 +      | 1 ->                                    (* PDB_CONNECTION_STATUS_UP *)
   26.56 +	  begin
   26.57 +	    print_endline (Printf.sprintf "  new backend domain available (%d)"
   26.58 +	                   xcs.domain);
   26.59 +	    let ring = initialize_ring xcs.domain xcs.ring in
   26.60 +
   26.61 +	    let (local_evtchn, remote_evtchn) = 
   26.62 +	      Evtchn.bind_interdomain xcs.domain in
   26.63 +
   26.64 +	    xcs.evtchn <- remote_evtchn;
   26.65 +	    write_message socket xcs;
   26.66 +
   26.67 +	    let evtchn_fd = Evtchn._setup () in
   26.68 +	    Evtchn._bind evtchn_fd local_evtchn;
   26.69 +
   26.70 +	    (evtchn_fd, local_evtchn, xcs.domain, ring)
   26.71 +	  end
   26.72 +      | 2 ->                                  (* PDB_CONNECTION_STATUS_DOWN *)
   26.73 +	  begin
   26.74 +	    (* TODO:
   26.75 +	       unmap the ring
   26.76 +	       unbind event channel  xen_evtchn_unbind
   26.77 +	       find the evtchn_fd for this domain and close it
   26.78 +	       finally, need to failwith something
   26.79 +	    *)
   26.80 +	    print_endline (Printf.sprintf "  close connection from domain %d"
   26.81 +	                   xcs.domain);
   26.82 +	    (socket, 0, 0, 0l)
   26.83 +	  end
   26.84 +      | _ ->
   26.85 +	  failwith "xcs read: unknown xcs status"
   26.86 +  end
   26.87 +    
   26.88 +
    27.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    27.2 +++ b/tools/debugger/pdb/xcs.mli	Mon Jun 27 21:31:56 2005 +0000
    27.3 @@ -0,0 +1,5 @@
    27.4 +
    27.5 +
    27.6 +val setup : unit -> Unix.file_descr
    27.7 +val read : Unix.file_descr -> Unix.file_descr * int * int * int32
    27.8 +val teardown : Unix.file_descr -> unit
    28.1 --- a/xen/include/public/io/domain_controller.h	Mon Jun 27 20:17:02 2005 +0000
    28.2 +++ b/xen/include/public/io/domain_controller.h	Mon Jun 27 21:31:56 2005 +0000
    28.3 @@ -62,6 +62,7 @@ typedef struct {
    28.4  #define CMSG_USBIF_BE       8  /* USB controller backend  */
    28.5  #define CMSG_USBIF_FE       9  /* USB controller frontend */
    28.6  #define CMSG_VCPU_HOTPLUG  10  /* Hotplug VCPU messages   */
    28.7 +#define CMSG_DEBUG         11  /* PDB backend             */
    28.8  
    28.9  /******************************************************************************
   28.10   * CONSOLE DEFINITIONS
   28.11 @@ -795,4 +796,17 @@ typedef struct {
   28.12  } PACKED mem_request_t; /* 8 bytes */
   28.13  
   28.14  
   28.15 +/******************************************************************************
   28.16 + * PDB INTERFACE DEFINITIONS
   28.17 + */
   28.18 +
   28.19 +#define CMSG_DEBUG_CONNECTION_STATUS 0
   28.20 +typedef struct {
   28.21 +#define PDB_CONNECTION_STATUS_UP   1
   28.22 +#define PDB_CONNECTION_STATUS_DOWN 2
   28.23 +    u32      status;
   28.24 +    memory_t ring;       /* status: UP */
   28.25 +    u32      evtchn;     /* status: UP */
   28.26 +} PACKED pdb_connection_t, *pdb_connection_p;
   28.27 +
   28.28  #endif /* __XEN_PUBLIC_IO_DOMAIN_CONTROLLER_H__ */