1 /* -*- mode: c; c-basic-offset: 8; -*-
4 * RCA: Interface between CRAY RCA and linux kernel
6 * Copyright (c) 2003 Cray Inc.
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version
11 * 2 of the License, or (at your option) any later version.
16 * This code is licensed under the GNU General Public License,
17 * Version 2. See the file COPYING for more details.
21 #include <lwk/kernel.h>
22 #include <lwk/string.h>
23 #include <lwk/errno.h>
24 #include <lwk/delay.h>
25 #include <lwk/version.h>
26 #include <rca/rca_l0_linux.h>
27 #include <rca/rca_l0.h>
28 extern void set_debug_traps(void) ; /* GDB routine */
30 #if defined(CONFIG_CRAY_RS_DEBUG)
31 #define assert(expr) \
33 printk( "Assertion failed! %s,%s,%s,line=%d\n", \
34 #expr,__FILE__,__FUNCTION__,__LINE__); \
38 #endif /* CONFIG_CRAY_RS_DEBUG */
40 /* States for up channel. Used for calling the tx_done callback only if reqd */
41 #define CHAN_TX_STATE_AVAIL (0)
42 #define CHAN_TX_STATE_FULL (1)
43 #define GET_CHAN_STATE(x) ((x)->state)
44 #define SET_CHAN_STATE(x, s) ((x)->state = (s))
46 typedef struct l0rca_mapped_ch {
47 uint32_t num_obj; /* number of objects */
49 volatile uint32_t *ch_ridx; /* Pointer to ridx */
50 volatile uint32_t *ch_widx; /* Pointer to widx */
51 rs_event_t *ch_buf_ptr; /* Pointer to channel buffer */
52 l0rca_down_handle_t down_handler;
53 l0rca_up_handle_t up_handler;
55 int poll; /* timeout */
56 int tshhld; /* timeout */
57 int state; /* outgoing chan full or not */
60 #define L0RCA_INITVAL (0xAA55F00D)
62 typedef struct l0rca_mapped_config {
63 uint32_t version; /* config version */
64 rs_node_t proc_id; /* node id */
65 int32_t proc_num; /* cpu number (0-3) */
66 l0rca_mapped_ch_t ch_data[NUM_L0RCA_CHANNELS];
67 volatile uint32_t *l0rca_l0_intr_ptr; /* interrupt to L0 */
69 } l0rca_mapped_config_t;
71 /* Our copy with virt addrs; so we can directly access the config area */
72 l0rca_mapped_config_t l0rca_early_cfg = {0};
74 /* Pointer to the actual config struct in Seastar RAM shared memory */
75 l0rca_config_t *l0rca_cfg = NULL;
77 /* Store the size of the event header without the msg body */
78 uint32_t rs_ev_hdr_sz;
81 void send_intr_to_l0(l0rca_mapped_ch_t *ch)
83 volatile uint32_t *addr = &(((l0rca_intr_t *)(l0rca_early_cfg.l0rca_l0_intr_ptr))->l0r_intr_set);
84 SSPUT32(addr, (ch)->intr_bit);
88 * Function: l0rca_event_data
90 * Description: Return a pointer to the data portion and length of the
91 * data portion of the event.
92 * NB: Reflect any changes to l0rca_event_data in gdb_l0rca_event_data
94 * Arguments: rs_event_t *evp IN: Event whose data is of interest
95 * void **data OUT: Upon return will point to data portion of event
96 * int32_t *len OUT: Upon return will have the length of the data
97 * portion of the event
99 * Returns: No Return Value.
100 * Note: The main purpose of this routine is to read in the data portion of the
101 * event from Seastar memory.
103 void l0rca_event_data(rs_event_t *evp, void **data, int32_t *len)
105 /* Get length and data portion from the event */
107 *data = &evp->ev_data;
108 } /* l0rca_event_data */
111 * Function: l0rca_get_proc_id
113 * Description: Return the node/processor id.
117 * Returns: The proc id.
119 rs_node_t l0rca_get_proc_id(void)
121 return l0rca_cfg->proc_id;
125 * Function: l0rca_get_proc_num
127 * Description: Returns this processor's CPU number, 0-3.
131 * Returns: The CPU number of this node.
133 int l0rca_get_proc_num(void)
136 SSGET32(&(l0rca_cfg->proc_num),tmp);
141 * Function: set_chan_tx_state
143 * Description: Looks at the read and write indices to determine if the
144 * channel is full or not. Sets state accordingly.
145 * NB: Reflect any changes to set_chan_tx_state in gdb_set_chan_tx_state.
147 * Arguments: l0rca_mapped_ch_t *ch_ptr IN: Pointer to channel being set.
151 static inline void set_chan_tx_state(l0rca_mapped_ch_t *ch_ptr)
153 volatile uint32_t wx, rx;
155 SSGET32(ch_ptr->ch_widx, wx);
156 SSGET32(ch_ptr->ch_ridx, rx);
157 not_full = (wx - rx) < ch_ptr->num_obj;
158 SET_CHAN_STATE(ch_ptr, not_full ? CHAN_TX_STATE_AVAIL : CHAN_TX_STATE_FULL);
163 * Function: l0rca_init_config
165 * Description: Read L0 - RCA communication config structure and populate
166 * our personal copy. If there is any error, the OS panics
167 * since not being able to communicate with L0 is a total disaster.
168 * If already initialized then returns silently.
175 void l0rca_init_config(void)
179 volatile uint64_t tmp64;
180 volatile uint32_t tmp32;
183 * Check if already initialized; No locking is needed as this
184 * is called during the boot process from within the kernel (as
185 * opposed from a driver)
187 if (L0RCA_INITVAL == l0rca_early_cfg.initialized)
190 l0rca_cfg = (l0rca_config_t *)rca_l0_comm_va(L0_SIC_RAM);
192 /* TODO - first order of business is to check the Version Number */
193 /* Also, should we panic if version mismatch? */
194 #ifdef CONFIG_CRAY_RS_DEBUG
195 printk ("l0 config at virtual %p\n", l0rca_cfg);
196 printk ("Phys event bufs 0x%llx intr reg 0x%llx\n",
197 l0rca_cfg->l0rca_buf_addr,
198 l0rca_cfg->l0rca_l0_intr_addr);
199 #endif /* CONFIG_CRAY_RS_DEBUG */
201 /* convert event buffer address from physical to virtual */
202 SSGET64(&(l0rca_cfg->l0rca_buf_addr),tmp64);
203 ev_buf = (rs_event_t *)rca_l0_comm_va(tmp64);
205 /* convert intr reg address from physical to virtual */
206 SSGET64(&(l0rca_cfg->l0rca_l0_intr_addr), tmp64);
207 l0rca_early_cfg.l0rca_l0_intr_ptr = (uint32_t *)rca_l0_comm_va(tmp64);
209 #ifdef CONFIG_CRAY_RS_DEBUG
210 printk ("event bufs %p intr reg %p\n", ev_buf,
211 l0rca_early_cfg.l0rca_l0_intr_ptr);
212 #endif /* CONFIG_CRAY_RS_DEBUG */
214 /* Now setup the channel buffers */
215 for (i = 0; i < NUM_L0RCA_CHANNELS; i++)
218 SSGET32(&(l0rca_cfg->chnl_data[i].num_obj), tmp32);
221 /* Skip if channel is unused */
225 /* Ensure num_obj is a power of 2 */
226 if (num_obj & (num_obj - 1))
229 panic ("l0rca_init_config: num_obj[%u] for channel %d is not power of 2\n",
233 l0rca_early_cfg.ch_data[i].num_obj = num_obj;
234 SSGET32(&(l0rca_cfg->chnl_data[i].l0_intr_bit), tmp32);
235 l0rca_early_cfg.ch_data[i].intr_bit = tmp32;
237 /* Point to the read/writew index */
238 l0rca_early_cfg.ch_data[i].ch_ridx = &l0rca_cfg->chnl_data[i].ridx;
239 l0rca_early_cfg.ch_data[i].ch_widx = &l0rca_cfg->chnl_data[i].widx;
240 l0rca_early_cfg.ch_data[i].ch_buf_ptr = ev_buf;
244 #ifdef CONFIG_CRAY_RS_DEBUG
245 printk ("Buffer %p for channel %d rd %u wr %u\n",
246 l0rca_early_cfg.ch_data[i].ch_buf_ptr, i,
247 l0rca_cfg->chnl_data[i].ridx,
248 l0rca_cfg->chnl_data[i].widx);
249 #endif /* CONFIG_CRAY_RS_DEBUG */
252 /* Set the remaining fields */
253 SSGET32(&(l0rca_cfg->version), l0rca_early_cfg.version);
254 SSGET32(&(l0rca_cfg->proc_id), l0rca_early_cfg.proc_id);
255 SSGET32(&(l0rca_cfg->proc_num), l0rca_early_cfg.proc_num);
257 /* Assumes ev_data is the last element TODO: this should be
258 * defined via a macro in the rs_event_t structure definition */
259 rs_ev_hdr_sz = offsetof(rs_event_t, ev_data);
261 /* Indicate we have a initialized the mapped copy */
262 l0rca_early_cfg.initialized = L0RCA_INITVAL;
268 * Function: register_ch_up
270 * Description: Register function for the upload channel. It is expected that
271 * there be at most one registered user for an upload channel. This user
272 * provides a callback to be invoked when the buffer drains below tshhld
273 * (only if the buffer became full last time the tshhld was crossed)
275 * Arguments: int ch_num IN: channel number to register on
276 * l0rca_up_handle_t handler IN: callback routine
277 * int tshhld IN: buffer to drain before invoking callback; ignored
278 * if poll is negative.
279 * int poll IN: if > zero - duration in ms to check for buffer drain
280 * if = zero - tx done interrupt invokes callback (TODO)
281 * if < zero - do nothing. It is assumed that the user (TODO)
282 * has her own means to check for buffer drain
284 * Returns: -EBUSY - If another user is already registered.
285 * -EINVAL - if ch_num is not in range.
286 * zero (SUCCESS) otherwise.
288 * Note: It is expected that the buffer is empty upon call to this routine.
289 * This should be true on system startup and after an unregister call.
291 * Note: As of 12/1/04, the polling is forced, and is hard coded in
292 * l0rca_linux.c. Thus, the tshhld and poll params have no meaning.
295 register_ch_up(int ch_num, l0rca_up_handle_t handler, int tshhld, int poll)
297 volatile uint32_t wx, rx;
298 l0rca_mapped_ch_t *ch_ptr = &l0rca_early_cfg.ch_data[ch_num];
300 if (NUM_L0RCA_CHANNELS <= ch_num)
303 /* Allow only one user per channel */
304 if (ch_ptr->reg_count)
307 SSGET32(ch_ptr->ch_widx, wx);
308 SSGET32(ch_ptr->ch_ridx, rx);
311 SET_CHAN_STATE(ch_ptr, CHAN_TX_STATE_AVAIL);
312 ch_ptr->down_handler = NULL; /* Clear the down handler */
315 ch_ptr->up_handler = handler;
316 ch_ptr->tshhld = tshhld;
322 * Function: register_ch_down
324 * Description: Register function for the download channel. It is expected that
325 * there be at most one registered user for a download channel. This user
326 * provides a callback to be invoked when data from L0 arrives on the channel.
328 * Arguments: int ch_num IN: channel number to register on
329 * l0rca_down_handle_t handler IN: callback routine
330 * int poll IN: if > zero - duration in ms to check for event
331 * if = zero - event arrival is interrupt driven.
332 * if < zero - do nothing. It is assumed that the user
333 * has her own means to check for event arrival.
335 * Returns: EBUSY - If another user is already registered.
336 * zero (SUCCESS) otherwise.
338 * Note: As of 12/1/04, the polling is forced, and is hard coded in
339 * l0rca_linux.c. Thus, the poll parameter has no meaning.
341 int register_ch_down(int ch_num, l0rca_down_handle_t handler, int poll)
343 l0rca_mapped_ch_t *ch_ptr = &l0rca_early_cfg.ch_data[ch_num];
345 if (NUM_L0RCA_CHANNELS <= ch_num)
348 /* Allow only one user per channel */
349 if (ch_ptr->reg_count)
353 ch_ptr->down_handler = handler;
357 /* Do any OS specific initialization e.g. set irq, timers etc. */
360 panic ("Unable to initialize OS service for L0RCA interface\n");
367 #ifdef CONFIG_CRAY_RS_DEBUG
368 uint32_t l0rca_buf_full;
369 #endif /* CONFIG_CRAY_RS_DEBUG */
371 * Function: ch_send_data
373 * Description: Sends data towards the L0.
374 * The data that buf points to is sent as the payload in an rs_event structure.
375 * The header is a separate parameter and the send routine directly copies
376 * the header and the data into the circular buffer, thus avoiding a copy.
378 * NB: Reflect any changes to ch_send_data in gdb_ch_send_data
380 * Arguments: int ch_num IN: channel number on which to send data
381 * rs_event_t *ev_hdr IN: Header without len & timestamp
382 * void* buf IN: Buffer with data
383 * int len IN: length of data to transfer
385 * Returns: -EINVAL - if no user registered on the channel (Debug only)
386 * -EFAULT - if buf or ev_hdr is NULL (Debug only)
387 * -E2BIG - if len exceeds max event payload (RS_MSG_LEN) (Debug only)
388 * zero - SUCCESS, all bytes sent.
389 * > 0 - Bytes not sent. Sender should retry.
391 * Notes: data in buf will be copied to the channel buffer, therfore, upon
392 * return, user can free the buf. buf may not be NULL and the len must
393 * not be zero. Use ch_send_event to send events with zero length data
397 int ch_send_data(int ch_num, const rs_event_t *ev_hdr,
398 void* buf, unsigned int len)
400 l0rca_mapped_ch_t *ch_ptr = &l0rca_early_cfg.ch_data[ch_num];
402 volatile uint32_t tmpwx, tmprx;
404 #ifdef CONFIG_CRAY_RS_DEBUG
405 uint32_t wr, rd, no_events;
406 if ((NULL == ev_hdr) || (NULL == buf))
411 if ((NUM_L0RCA_CHANNELS <= ch_num) || (0 == len) ||
412 (L0RCA_INITVAL != l0rca_early_cfg.initialized) ||
413 (0 == ch_ptr->reg_count))
418 /* Normalize the write & read indexes */
419 SSGET32(ch_ptr->ch_widx, tmpwx);
420 wr = tmpwx & (ch_ptr->num_obj - 1);
421 SSGET32(ch_ptr->ch_ridx, tmprx);
422 rd = tmprx & (ch_ptr->num_obj - 1);
425 /* Calculate the number of events we will be sending */
426 no_events = (len + RS_MSG_LEN -1)/RS_MSG_LEN;
427 if ((wr + (no_events) - rd) < ch_ptr->num_obj)
432 #endif /* CONFIG_CRAY_RS_DEBUG */
434 /* Optimize for buf not full and only one event needed to send */
437 * Masking of indexes is not needed for the check in while() below.
438 * Both widx & ridx are unsigned and increase monotonically such that
439 * ridx cannot lag behind widx by more than the circular buf size i.e.
440 * num_obj. widx will overflow before ridx.
441 * 'widx - ridx' will always yield the difference between the two
442 * even if widx has overflowed and ridx has not yet overflowed.
444 SSGET32(ch_ptr->ch_widx, tmpwx);
445 SSGET32(ch_ptr->ch_ridx, tmprx);
446 while ((tmpwx - tmprx) < ch_ptr->num_obj)
448 rs_event_t *wr_ev_ptr =
449 &ch_ptr->ch_buf_ptr[tmpwx & (ch_ptr->num_obj - 1)];
451 /* Copy same header for each event */
452 SSMEMPUT(wr_ev_ptr, (uint32_t*) ev_hdr, rs_ev_hdr_sz);
454 /* Copy the data portion over */
455 ev_len = (RS_MSG_LEN > len) ? len : RS_MSG_LEN;
456 SSPUT32(&(wr_ev_ptr->ev_len), ev_len);
457 SSMEMPUT((char*)wr_ev_ptr + rs_ev_hdr_sz, buf, RS_MSG_LEN);
459 /* TODO: Set the timestamp in each event */
461 SSPUT32(wr_ev_ptr->_ev_stp, 0x0);
465 * After updating the widx, DO NOT access any field in that
466 * event. Though not desirable, the reader is free to alter
467 * fields in the event.
469 SSGET32(ch_ptr->ch_widx, tmpwx);
470 SSPUT32(ch_ptr->ch_widx, tmpwx + 1);
471 set_chan_tx_state(ch_ptr);
473 /* Let L0 know an ev is available */
474 send_intr_to_l0(ch_ptr);
479 buf = (void *)(((char *)buf) + RS_MSG_LEN);
481 SSGET32(ch_ptr->ch_widx, tmpwx);
482 SSGET32(ch_ptr->ch_ridx, tmprx);
484 return len; /* bytes remaining, if any */
488 * Function: ch_send_event
490 * Description: Sends an event to L0. An event with zero length data portion
493 * Arguments: int ch_num IN: channel number on which to send the event
494 * const rs_event_t *evp IN: EVent to send
496 * Returns: -EINVAL - if no user registered on the channel (Debug only)
497 * -EFAULT - if evp is NULL (Debug only)
498 * zero - SUCCESS, event sent.
499 * +EBUSY - Event not sent. Sender should retry.
501 * Notes: The event will be copied to the channel buffer, therfore, upon
502 * return, user may free the space associated with the event
504 int ch_send_event(int ch_num, const rs_event_t *evp)
507 l0rca_mapped_ch_t *ch_ptr = &l0rca_early_cfg.ch_data[ch_num];
508 volatile uint32_t tmpwx, tmprx;
510 #ifdef CONFIG_CRAY_RS_DEBUG
516 if ((NUM_L0RCA_CHANNELS <= ch_num) ||
517 (L0RCA_INITVAL != l0rca_early_cfg.initialized) ||
518 (0 == ch_ptr->reg_count))
522 #endif /* CONFIG_CRAY_RS_DEBUG */
524 /* Optimize for circular buffer not full */
527 * Masking of indexes is not needed for the check in while() below.
528 * Both widx & ridx are unsigned and increase monotonically such that
529 * ridx cannot lag behind widx by more than the circular buf size i.e.
530 * num_obj. widx will overflow before ridx.
531 * 'widx - ridx' will always yield the difference between the two
532 * even if widx has overflowed and ridx has not yet overflowed.
534 SSGET32(ch_ptr->ch_widx,tmpwx);
535 SSGET32(ch_ptr->ch_ridx,tmprx);
536 if((tmpwx - tmprx) < ch_ptr->num_obj)
538 rs_event_t *wr_ev_ptr =
539 &ch_ptr->ch_buf_ptr[tmpwx & (ch_ptr->num_obj - 1)];
541 /* Copy header & data length for the event */
542 SSMEMPUT(wr_ev_ptr, (uint32_t*)evp, rs_ev_hdr_sz + evp->ev_len);
544 SSGET32(ch_ptr->ch_widx, tmpwx);
545 SSPUT32(ch_ptr->ch_widx, tmpwx + 1);
546 set_chan_tx_state(ch_ptr);
548 /* Let L0 know an ev is available */
549 send_intr_to_l0(ch_ptr);
559 * Function: l0rca_ch_get_event
561 * Description: Read an event from L0 (if any). If an event is availabe then
562 * the read pointer is advanced.
563 * NB: Reflect any changes to l0rca_ch_get_event in gdb_l0rca_ch_get_event
565 * Arguments: int ch_num IN: channel number from which to read the event
566 * rs_event_t *evp IN: Buffer to place the event
568 * Returns: -EINVAL - if no user registered on the channel (Debug only)
569 * -EFAULT - if evp is NULL (Debug only)
570 * zero - no event to receive at this time
571 * > 0 - Event received
574 int l0rca_ch_get_event(int ch_num, rs_event_t *evp)
576 l0rca_mapped_ch_t *ch_ptr = &l0rca_early_cfg.ch_data[ch_num];
579 volatile uint32_t tmpwx, tmprx;
581 #ifdef CONFIG_CRAY_RS_DEBUG
585 if ((NUM_L0RCA_CHANNELS <= ch_num) ||
586 (L0RCA_INITVAL != l0rca_early_cfg.initialized) ||
587 (0 == ch_ptr->reg_count))
589 #endif /* CONFIG_CRAY_RS_DEBUG */
591 SSGET32(ch_ptr->ch_widx,tmpwx);
592 SSGET32(ch_ptr->ch_ridx,tmprx);
595 rs_event_t *wr_ev_ptr =
596 &ch_ptr->ch_buf_ptr[tmprx & (ch_ptr->num_obj - 1)];
598 /* Copy over the event */
599 SSGET32(&(wr_ev_ptr->ev_len), nbytes);
600 SSMEMGET(evp, (uint32_t*)wr_ev_ptr, nbytes + rs_ev_hdr_sz);
602 /* Update the rd index */
603 SSGET32(ch_ptr->ch_ridx, tmprx);
604 SSPUT32(ch_ptr->ch_ridx, tmprx + 1);
606 /* Let L0 know that the event has been drained */
607 send_intr_to_l0(ch_ptr);
616 * Function: unregister_ch_down
618 * Description: Unregister function for the upload channel. Use to indicate
619 * that the channel is no longer to be used. The read & write pointers are
620 * equalized to make the circ buffer empty.
622 * Arguments: int ch_num IN: channel number to unregister
624 * Returns: -EINVAL - if ch_num is not correct or no user registered
627 int unregister_ch_down(int ch_num)
629 l0rca_mapped_ch_t *ch_ptr = &l0rca_early_cfg.ch_data[ch_num];
630 volatile uint32_t tmpwx;
632 if (NUM_L0RCA_CHANNELS <= ch_num)
635 /* Check if user is using this channel */
636 if (!ch_ptr->reg_count)
639 ch_ptr->down_handler = NULL;
642 /* Equalize the read & write pointers i.e. drain the circ buffer */
643 /* NOTE: We cannot really stop the L0 from sending data */
644 SSGET32(ch_ptr->ch_widx, tmpwx);
645 SSPUT32(ch_ptr->ch_ridx, tmpwx);
651 * Function: unregister_ch_up
653 * Description: Unregister function for the download channel. Use to indicate
654 * that the channel is no longer to be used.
656 * Arguments: int ch_num IN: channel number to unregister
658 * Returns: -EINVAL - if ch_num is not correct or no user registered
661 int unregister_ch_up(int ch_num)
663 l0rca_mapped_ch_t *ch_ptr = &l0rca_early_cfg.ch_data[ch_num];
664 volatile uint32_t tmpwx, tmprx;
666 if (NUM_L0RCA_CHANNELS <= ch_num)
669 /* Check if user is using this channel */
670 if (!ch_ptr->reg_count)
673 /* Wait for events to be drained by the L0 */
674 SSGET32(ch_ptr->ch_widx,tmpwx);
675 SSGET32(ch_ptr->ch_ridx,tmprx);
676 while(tmpwx != tmprx)
679 SSGET32(ch_ptr->ch_widx,tmpwx);
680 SSGET32(ch_ptr->ch_ridx,tmprx);
683 ch_ptr->up_handler = NULL;
689 /* TODO: If we decide to use the PKT_MODE register to indicate the channels
690 * that need attention then use PKT_MODE instead of looking at each channel.
691 * TODO: Currently the rx_done callback is invoked for each event in the
692 * incoming channel. Change this to be called with all the pending events.
693 * Note that since the channel is a circular buffer and the pending events
694 * wrap around, then the callback needs to be invoked twice - once with events
695 * upto the "end" of the circular buffer and then with events starting from the
696 * "start" of the circular buffer.
697 * TODO: To prevent thrashing of the tx_done callback in case the circular
698 * buffer is being operated under almost full condition, obey the threshold
699 * specified at the registration. The tx_done callback is only called once the
700 * circular buffer occupancy is below the specified threshold.
703 * Function: l0rca_poll_callback
705 * Description: Scan the incoming channels and call the receive callback
706 * (if any) in case an event is pending to be processed.
707 * Update the read pointer. Next scan the outgoing channels
708 * and if the channel was full, call the transmit done callback
709 * so that events may be sent.
713 * Returns: 0 if no events were processed, else 1.
715 * Note: It is possible that this routine is called from interrupt
716 * context. The callbacks invoked *must* not block.
719 int l0rca_poll_callback(void)
723 rs_event_t ev, *wr_ev_ptr;
724 volatile uint32_t tmpwx, tmprx;
726 /* Loop through all channels with incoming events */
727 for (i = 1; i < NUM_L0RCA_CHANNELS; i+=2)
729 l0rca_mapped_ch_t *ch_ptr = &l0rca_early_cfg.ch_data[i];
731 /* GDB handled separately.
733 if (i == L0RCA_CH_KGDB_DOWN)
736 if ((0 == ch_ptr->reg_count) || (NULL == ch_ptr->down_handler))
739 if ((ch_ptr->ch_ridx == 0) || (ch_ptr->ch_widx == 0)) {
743 if (!ch_ptr->num_obj) {
744 SSGET32(ch_ptr->ch_widx, tmpwx);
745 SSGET32(ch_ptr->ch_ridx, tmprx);
749 SSGET32(ch_ptr->ch_widx, tmpwx);
750 SSGET32(ch_ptr->ch_ridx, tmprx);
753 wr_ev_ptr = (rs_event_t*)&ch_ptr->ch_buf_ptr[tmprx & (ch_ptr->num_obj - 1)];
754 /* read the entire event */
755 SSMEMGET((uint32_t*)&ev, (uint32_t*)wr_ev_ptr, rs_sizeof_event(RS_MSG_LEN));
757 /* Call callback routine with one event */
758 (ch_ptr->down_handler)(i, &ev, 1);
760 /* We are done with this event */
762 SSGET32(ch_ptr->ch_ridx, tmprx);
763 SSPUT32(ch_ptr->ch_ridx, tmprx + 1);
765 /* Let L0 know that the event has been drained */
766 send_intr_to_l0(ch_ptr);
768 } /* End of for incoming channels */
770 /* Loop through all channels with outgoing events */
771 for (i = 0; i < NUM_L0RCA_CHANNELS; i+=2)
773 l0rca_mapped_ch_t *ch_ptr = &l0rca_early_cfg.ch_data[i];
775 /* GDB handled separately.
777 if (i == L0RCA_CH_KGDB_UP)
780 if(NULL != ch_ptr->up_handler)
782 /* Lock needed for mutex with tx routine */
784 if (CHAN_TX_STATE_FULL == GET_CHAN_STATE(ch_ptr))
786 /* Call the callback if chan no longer full */
787 assert(0 != ch_ptr->reg_count);
788 SSGET32(ch_ptr->ch_widx, tmpwx);
789 SSGET32(ch_ptr->ch_ridx, tmprx);
790 if((tmpwx - tmprx) < ch_ptr->num_obj)
793 SET_CHAN_STATE(ch_ptr,CHAN_TX_STATE_AVAIL);
795 (ch_ptr->up_handler)(i);
806 #if defined(CONFIG_CRAY_XT_KGDB) || defined(CONFIG_CRAY_KGDB)
807 /* Kernel mode GDB via L0 interface routines.
809 * Note that this code was derived from gdbl0.c,
810 * which was derived from Linux gdbserial.c,
811 * which contains no copyright notice. Parts
812 * of this may need to be rewritten if a GPL
813 * copyright notice was removed from gdbserial.c
817 #define LRPRINTF printk
819 #undef PRNT /* define for debug printing */
821 #define GDB_BUF_SIZE 512 /* power of 2, please */
823 static char gdb_buf[GDB_BUF_SIZE] ;
824 static int gdb_buf_in_inx ;
825 static int gdb_buf_in_cnt ;
826 static int gdb_buf_out_inx ;
828 static int initialized = -1;
830 int gdb_store_overflow;
833 /* Preset this with constant fields in the event header */
834 static rs_event_t l0rca_gdb_ev_template = {0};
837 * Function: rcal0_gdb_template
839 * Description: Hand craft a event header to be sent with each outgoing event
845 * Note: The len & timestamp are not filled in.
847 static void rcal0_gdb_template(void)
849 l0rca_gdb_ev_template.ev_id = ec_kgdb_output;
850 l0rca_gdb_ev_template.ev_gen = RCA_MKSVC(RCA_INST_ANY,
851 RCA_SVCTYPE_TEST0, l0rca_get_proc_id());
852 l0rca_gdb_ev_template.ev_src = l0rca_gdb_ev_template.ev_gen;
853 l0rca_gdb_ev_template.ev_priority = RCA_LOG_DEBUG;
854 l0rca_gdb_ev_template.ev_flag = 0; /* For Debugging */
856 /* Timestamp, len & data is filled at the time of sending event */
860 * Function: l0_gdb_init
862 * Description: Take steps to set things up for early_printk output
864 * Arguments: struct console *console IN: pointer to console struct
865 * char *input IN: Not used
867 * Returns: zero (SUCCESS)
869 int l0_gdb_init(void)
874 /* RCA already initialized on Q
876 /* Read the configuration information provided by L0 */
879 /* Setup the Event template to use for outgoing events */
880 rcal0_gdb_template();
882 /* Set up channel internal state by calling
883 * registration routines.
886 /* Register with the KGDB out channel to send gdb data */
887 ret = register_ch_up (L0RCA_CH_KGDB_UP, NULL, 0, 0);
891 /* Register with the KGDB in channel to receive gdb commands */
892 ret = register_ch_down(L0RCA_CH_KGDB_DOWN, NULL, 0);
898 extern void breakpoint(void);
906 * Call GDB routine to setup the exception vectors for the debugger.
909 /* Setup both kgdb channels */
910 retval = l0_gdb_init();
912 /* TODO: on Linux the call to printk in this
913 * routine no longer generate output.
915 * Did something change in the setup of the
924 LRPRINTF("gdb_hook: l0_gdb_init() failed: %d\n", retval);
932 * Function: l0rca_kgdb_down_getc()
934 * Description: Checks for an event on the KGDB DOWN L0 channel
935 * and returns the first character, other characters
936 * are thrown away. Used to detect control C for
937 * breakpointing the kernel. Returns 0 when no
938 * input is available or on error where gdb_read_error
941 int l0rca_kgdb_down_getc(void)
947 if ((ret = l0rca_ch_get_event(L0RCA_CH_KGDB_DOWN, &ev)) <= 0) {
952 l0rca_event_data(&ev, (void *)&chp, &len);
956 } /* l0rca_kgdb_down_getc */
958 /* Only routines used by the Kernel trap mode KGDB interface
959 * should follow this point.
961 * These functions should only call other `gdb_.*' functions.
963 * This is best done by examining the assembly file and
964 * ensuring that all assembly call statements only call
965 * routines that match `gdb_.*', in all of the routines
968 * NB: SETTING BREAKPOINTS IN THE FOLLOWING ROUTINES MAY
969 * BREAK THE KERNEL DEBUGGER.
973 * Function: gdb_l0rca_event_data
975 * Description: Clone of l0rca_event_data to only be called by kernel GDB.
976 * data portion of the event.
978 * Arguments: rs_event_t *evp IN: Event whose data is of interest
979 * void **data OUT: Upon return will point to data portion of event
980 * int32_t *len OUT: Upon return will have the length of the data
981 * portion of the event
983 * Returns: No Return Value.
985 void gdb_l0rca_event_data(rs_event_t *evp, void **data, int32_t *len)
987 /* Get length and data portion from the event */
989 *data = &evp->ev_data;
990 } /* gdb_l0rca_event_data */
993 * Function: gdb_set_chan_tx_state
995 * Description: Clone of set_chan_tx_state to only be called by kernel GDB.
997 static inline void gdb_set_chan_tx_state(l0rca_mapped_ch_t *ch_ptr)
1000 int not_full = (*ch_ptr->ch_widx - *ch_ptr->ch_ridx) < ch_ptr->num_obj;
1002 SET_CHAN_STATE(ch_ptr, not_full ? CHAN_TX_STATE_AVAIL : CHAN_TX_STATE_FULL);
1005 static void gdb_memcpy(void *dest, const void *src, int cnt)
1009 const char *ps = src;
1011 for (i = 0; i < cnt; i++)
1016 * Function: gdb_ch_send_data
1018 * Description: Clone of ch_send_data to be only called by kernel GDB.
1021 int gdb_ch_send_data(int ch_num, const rs_event_t *ev_hdr,
1022 void* buf, unsigned int len)
1024 l0rca_mapped_ch_t *ch_ptr = &l0rca_early_cfg.ch_data[ch_num];
1026 /* No registration checks needed.
1029 /* Optimize for buf not full and only one event needed to send */
1032 * Masking of indexes is not needed for the check in while() below.
1033 * Both widx & ridx are unsigned and increase monotonically such that
1034 * ridx cannot lag behind widx by more than the circular buf size i.e.
1035 * num_obj. widx will overflow before ridx.
1036 * 'widx - ridx' will always yield the difference between the two
1037 * even if widx has overflowed and ridx has not yet overflowed.
1039 while((*ch_ptr->ch_widx - *ch_ptr->ch_ridx) < ch_ptr->num_obj)
1041 rs_event_t *wr_ev_ptr =
1042 &ch_ptr->ch_buf_ptr[*ch_ptr->ch_widx & (ch_ptr->num_obj - 1)];
1044 /* Copy same header for each event */
1045 gdb_memcpy(wr_ev_ptr, (void *) ev_hdr, rs_ev_hdr_sz);
1047 /* Copy the data portion over */
1048 wr_ev_ptr->ev_len = (RS_MSG_LEN > len) ? len : RS_MSG_LEN;
1049 gdb_memcpy((char *)wr_ev_ptr + rs_ev_hdr_sz, buf,
1052 /* TODO: Set the timestamp in each event */
1054 wr_ev_ptr->_ev_stp = 0x0;
1057 len -= wr_ev_ptr->ev_len;
1059 * After updating the widx, DO NOT access any field in that
1060 * event. Though not desirable, the reader is free to alter
1061 * fields in the event.
1063 (*ch_ptr->ch_widx)++;
1064 gdb_set_chan_tx_state(ch_ptr);
1066 /* Let L0 know an ev is available */
1067 send_intr_to_l0(ch_ptr);
1073 } /* End of while */
1075 return len; /* bytes remaining, if any */
1079 * Function: gdb_l0rca_ch_get_event
1081 * Description: Clone of l0rca_ch_get_event to only be called by kernel GDB.
1082 * the read pointer is advanced.
1085 int gdb_l0rca_ch_get_event(int ch_num, rs_event_t *evp)
1087 l0rca_mapped_ch_t *ch_ptr = &l0rca_early_cfg.ch_data[ch_num];
1090 /* No registration checks needed
1093 if(*ch_ptr->ch_widx != *ch_ptr->ch_ridx)
1095 rs_event_t *wr_ev_ptr =
1096 &ch_ptr->ch_buf_ptr[*ch_ptr->ch_ridx & (ch_ptr->num_obj - 1)];
1098 /* Copy over the event */
1099 gdb_memcpy(evp, (void *)wr_ev_ptr, wr_ev_ptr->ev_len+rs_ev_hdr_sz);
1101 /* Update the rd index */
1102 (*ch_ptr->ch_ridx)++;
1104 /* Let L0 know that the event has been drained */
1105 send_intr_to_l0(ch_ptr);
1114 * Function: gdb_store_char_in_buf
1116 * Description: Check for overflow and place the incoming character into
1117 * the local buffer for later retreival.
1119 * Arguments: int ch IN: Incoming character
1121 * Returns: zero - (SUCCESS)
1122 * -1 - Buffer Overflow
1124 static int gdb_store_char_in_buf(char ch)
1126 if (gdb_buf_in_cnt >= GDB_BUF_SIZE)
1127 { /* buffer overflow, clear it */
1128 gdb_buf_in_inx = 0 ;
1129 gdb_buf_in_cnt = 0 ;
1130 gdb_buf_out_inx = 0 ;
1134 gdb_buf[gdb_buf_in_inx++] = ch;
1135 gdb_buf_in_inx &= (GDB_BUF_SIZE - 1) ;
1142 * Wait until the interface can accept a char, then write it.
1144 static void gdb_write_char(char chr)
1148 while ((ret = gdb_ch_send_data(L0RCA_CH_KGDB_UP, &l0rca_gdb_ev_template,
1149 (void *)&chr, sizeof(char))) > 0)
1151 /* Buffer full; keep trying.... */
1153 } /* End of while */
1156 } /* gdb_write_char */
1161 * This is a GDB stub routine. It waits for a character from the
1162 * L0 interface and then returns it.
1164 int gdb_getc(int wait)
1166 char *chp, *end_buf;
1168 rs_event_t ev = {0};
1171 LRPRINTF("gdb_getc:") ;
1173 /* First check if the receive callback has any chars pending */
1174 if (gdb_buf_in_cnt == 0)
1176 /* No chars from rx_callback; Loop until a char is available */
1177 while ((ret = gdb_l0rca_ch_get_event(L0RCA_CH_KGDB_DOWN, &ev))
1182 /* Error!! This is death */
1188 } /* End of while */
1190 /* Get the data in the event */
1191 gdb_l0rca_event_data(&ev, (void *)&chp, &len);
1193 /* We have an event; fill the local buffer */
1194 for (end_buf = chp+len; chp < end_buf; chp++)
1196 if (gdb_store_char_in_buf(*chp) < 0)
1198 gdb_store_overflow++;
1203 /* There should be something for us in the local buffer now */
1204 chp = &gdb_buf[gdb_buf_out_inx++] ;
1205 gdb_buf_out_inx &= (GDB_BUF_SIZE - 1) ;
1209 LRPRINTF("%c\n", *chp > ' ' && *chp < 0x7F ? *chp : ' ') ;
1218 * This is a GDB stub routine. It waits until the interface is ready
1219 * to transmit a char and then sends it. If there is no serial
1220 * interface connection then it simply returns to its caller, having
1221 * pretended to send the char.
1223 int gdb_putc(char chr)
1226 LRPRINTF("gdb_putc: chr=%02x '%c'\n", chr,
1227 chr > ' ' && chr < 0x7F ? chr : ' ') ;
1230 gdb_write_char(chr); /* this routine will wait */
1236 int putDebugPacket(char *buf, int n)
1240 /* Loop sending the data */
1243 if ((ret = gdb_ch_send_data(L0RCA_CH_KGDB_UP, &l0rca_gdb_ev_template,
1244 (void *)buf, n)) <= 0) {
1245 /* Either error or we are done */
1250 /* Some bytes were sent, point to the remaining data */
1258 #endif /* CONFIG_CRAY_KGDB */