ia64/xen-unstable

view tools/debugger/pdb/linux-2.6-module/module.c @ 6316:f7dfaa2af90c

merge?
author cl349@firebug.cl.cam.ac.uk
date Sun Aug 21 11:02:00 2005 +0000 (2005-08-21)
parents 1872e09bfba3
children 6721abf6b16d
line source
2 /*
3 * module.c
4 *
5 * Handles initial registration with pdb when the pdb module starts up
6 * and cleanup when the module goes away (sortof :)
7 * Also receives each request from pdb in domain 0 and dispatches to the
8 * appropriate debugger function.
9 */
11 #include <linux/module.h>
12 #include <linux/interrupt.h>
14 #include <asm-i386/kdebug.h>
16 #include <asm-xen/evtchn.h>
17 #include <asm-xen/ctrl_if.h>
18 #include <asm-xen/hypervisor.h>
19 #include <asm-xen/xen-public/io/domain_controller.h>
20 #include <asm-xen/xen-public/xen.h>
22 #include <asm-xen/xen-public/io/ring.h>
24 #include "pdb_module.h"
25 #include "pdb_debug.h"
27 #define PDB_RING_SIZE __RING_SIZE((pdb_sring_t *)0, PAGE_SIZE)
29 static pdb_back_ring_t pdb_ring;
30 static unsigned int pdb_evtchn;
31 static unsigned int pdb_irq;
32 static unsigned int pdb_domain;
34 /* work queue */
35 static void pdb_work_handler(void *unused);
36 static DECLARE_WORK(pdb_deferred_work, pdb_work_handler, NULL);
38 /*
39 * send response to a pdb request
40 */
41 void
42 pdb_send_response (pdb_response_t *response)
43 {
44 pdb_response_t *resp;
46 resp = RING_GET_RESPONSE(&pdb_ring, pdb_ring.rsp_prod_pvt);
48 memcpy(resp, response, sizeof(pdb_response_t));
49 resp->domain = pdb_domain;
51 wmb(); /* Ensure other side can see the response fields. */
52 pdb_ring.rsp_prod_pvt++;
53 RING_PUSH_RESPONSES(&pdb_ring);
54 notify_via_evtchn(pdb_evtchn);
55 return;
56 }
58 /*
59 * handle a debug command from the front end
60 */
61 static void
62 pdb_process_request (pdb_request_t *request)
63 {
64 pdb_response_t resp;
65 struct task_struct *target;
67 read_lock(&tasklist_lock);
68 target = find_task_by_pid(request->process);
69 if (target)
70 get_task_struct(target);
71 read_unlock(&tasklist_lock);
73 resp.operation = request->operation;
74 resp.process = request->process;
76 if (!target)
77 {
78 printk ("(linux) target not found 0x%x\n", request->process);
79 resp.status = PDB_RESPONSE_ERROR;
80 goto response;
81 }
83 switch (request->operation)
84 {
85 case PDB_OPCODE_PAUSE :
86 pdb_suspend(target);
87 resp.status = PDB_RESPONSE_OKAY;
88 break;
89 case PDB_OPCODE_ATTACH :
90 pdb_suspend(target);
91 pdb_domain = request->u.attach.domain;
92 printk("(linux) attach dom:0x%x pid:0x%x\n",
93 pdb_domain, request->process);
94 resp.status = PDB_RESPONSE_OKAY;
95 break;
96 case PDB_OPCODE_DETACH :
97 pdb_resume(target);
98 printk("(linux) detach 0x%x\n", request->process);
99 resp.status = PDB_RESPONSE_OKAY;
100 break;
101 case PDB_OPCODE_RD_REG :
102 resp.u.rd_reg.reg = request->u.rd_reg.reg;
103 pdb_read_register(target, &resp.u.rd_reg);
104 resp.status = PDB_RESPONSE_OKAY;
105 break;
106 case PDB_OPCODE_RD_REGS :
107 pdb_read_registers(target, &resp.u.rd_regs);
108 resp.status = PDB_RESPONSE_OKAY;
109 break;
110 case PDB_OPCODE_WR_REG :
111 pdb_write_register(target, &request->u.wr_reg);
112 resp.status = PDB_RESPONSE_OKAY;
113 break;
114 case PDB_OPCODE_RD_MEM :
115 pdb_access_memory(target, request->u.rd_mem.address,
116 &resp.u.rd_mem.data, request->u.rd_mem.length,
117 PDB_MEM_READ);
118 resp.u.rd_mem.address = request->u.rd_mem.address;
119 resp.u.rd_mem.length = request->u.rd_mem.length;
120 resp.status = PDB_RESPONSE_OKAY;
121 break;
122 case PDB_OPCODE_WR_MEM :
123 pdb_access_memory(target, request->u.wr_mem.address,
124 &request->u.wr_mem.data, request->u.wr_mem.length,
125 PDB_MEM_WRITE);
126 resp.status = PDB_RESPONSE_OKAY;
127 break;
128 case PDB_OPCODE_CONTINUE :
129 pdb_continue(target);
130 goto no_response;
131 break;
132 case PDB_OPCODE_STEP :
133 pdb_step(target);
134 resp.status = PDB_RESPONSE_OKAY;
135 goto no_response;
136 break;
137 case PDB_OPCODE_SET_BKPT :
138 pdb_insert_memory_breakpoint(target, request->u.bkpt.address,
139 request->u.bkpt.length);
140 resp.status = PDB_RESPONSE_OKAY;
141 break;
142 case PDB_OPCODE_CLR_BKPT :
143 pdb_remove_memory_breakpoint(target, request->u.bkpt.address,
144 request->u.bkpt.length);
145 resp.status = PDB_RESPONSE_OKAY;
146 break;
147 case PDB_OPCODE_SET_WATCHPT :
148 pdb_insert_watchpoint(target, &request->u.watchpt);
149 resp.status = PDB_RESPONSE_OKAY;
150 break;
151 case PDB_OPCODE_CLR_WATCHPT :
152 pdb_remove_watchpoint(target, &request->u.watchpt);
153 resp.status = PDB_RESPONSE_OKAY;
154 break;
155 default:
156 printk("(pdb) unknown request operation %d\n", request->operation);
157 resp.status = PDB_RESPONSE_ERROR;
158 }
160 response:
161 pdb_send_response (&resp);
163 no_response:
164 return;
165 }
167 /*
168 * work queue
169 */
170 static void
171 pdb_work_handler (void *unused)
172 {
173 pdb_request_t *req;
174 RING_IDX i, rp;
176 rp = pdb_ring.sring->req_prod;
177 rmb();
179 for ( i = pdb_ring.req_cons;
180 (i != rp) && !RING_REQUEST_CONS_OVERFLOW(&pdb_ring, i);
181 i++ )
182 {
183 req = RING_GET_REQUEST(&pdb_ring, i);
184 pdb_process_request(req);
186 }
187 pdb_ring.req_cons = i;
188 }
190 /*
191 * receive a pdb request
192 */
193 static irqreturn_t
194 pdb_interrupt (int irq, void *dev_id, struct pt_regs *ptregs)
195 {
196 schedule_work(&pdb_deferred_work);
198 return IRQ_HANDLED;
199 }
201 static void
202 pdb_send_connection_status(int status, unsigned long ring)
203 {
204 ctrl_msg_t cmsg =
205 {
206 .type = CMSG_DEBUG,
207 .subtype = CMSG_DEBUG_CONNECTION_STATUS,
208 .length = sizeof(pdb_connection_t),
209 };
210 pdb_connection_t *conn = (pdb_connection_t *)cmsg.msg;
212 conn->status = status;
213 conn->ring = ring;
214 conn->evtchn = 0;
216 ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE);
217 }
220 /*
221 * this is called each time a message is received on the control channel
222 */
223 static void
224 pdb_ctrlif_rx(ctrl_msg_t *msg, unsigned long id)
225 {
226 switch (msg->subtype)
227 {
228 case CMSG_DEBUG_CONNECTION_STATUS:
229 /* initialize event channel created by the pdb server */
231 pdb_evtchn = ((pdb_connection_p) msg->msg)->evtchn;
232 pdb_irq = bind_evtchn_to_irq(pdb_evtchn);
234 if ( request_irq(pdb_irq, pdb_interrupt,
235 SA_SAMPLE_RANDOM, "pdb", NULL) )
236 {
237 printk("(pdb) request irq failed: %d %d\n", pdb_evtchn, pdb_irq);
238 }
239 break;
241 default:
242 printk ("(pdb) unknown xcs control message: %d\n", msg->subtype);
243 break;
244 }
246 return;
247 }
250 /********************************************************************/
252 static struct notifier_block pdb_exceptions_nb =
253 {
254 .notifier_call = pdb_exceptions_notify,
255 .priority = 0x1 /* low priority */
256 };
259 static int __init
260 pdb_initialize (void)
261 {
262 int err;
263 pdb_sring_t *sring;
265 printk("----\npdb initialize %s %s\n", __DATE__, __TIME__);
267 /*
268 if ( xen_start_info.flags & SIF_INITDOMAIN )
269 return 1;
270 */
272 pdb_evtchn = 0;
273 pdb_irq = 0;
274 pdb_domain = 0;
276 (void)ctrl_if_register_receiver(CMSG_DEBUG, pdb_ctrlif_rx,
277 CALLBACK_IN_BLOCKING_CONTEXT);
279 /* rings */
280 sring = (pdb_sring_t *)__get_free_page(GFP_KERNEL);
281 SHARED_RING_INIT(sring);
282 BACK_RING_INIT(&pdb_ring, sring, PAGE_SIZE);
284 /* notify pdb in dom 0 */
285 pdb_send_connection_status(PDB_CONNECTION_STATUS_UP,
286 virt_to_machine(pdb_ring.sring) >> PAGE_SHIFT);
288 /* handler for int1 & int3 */
289 err = register_die_notifier(&pdb_exceptions_nb);
291 return err;
292 }
294 static void __exit
295 pdb_terminate(void)
296 {
297 int err = 0;
299 printk("pdb cleanup\n");
301 (void)ctrl_if_unregister_receiver(CMSG_DEBUG, pdb_ctrlif_rx);
303 if (pdb_irq)
304 {
305 free_irq(pdb_irq, NULL);
306 pdb_irq = 0;
307 }
309 if (pdb_evtchn)
310 {
311 unbind_evtchn_from_irq(pdb_evtchn);
312 pdb_evtchn = 0;
313 }
315 pdb_send_connection_status(PDB_CONNECTION_STATUS_DOWN, 0);
317 /* handler for int1 & int3 */
318 err = unregister_die_notifier(&pdb_exceptions_nb);
320 return;
321 }
324 module_init(pdb_initialize);
325 module_exit(pdb_terminate);
328 /*
329 * Local variables:
330 * mode: C
331 * c-set-style: "BSD"
332 * c-basic-offset: 4
333 * tab-width: 4
334 * indent-tabs-mode: nil
335 * End:
336 */