summaryrefslogtreecommitdiffstats
path: root/scripts/afm-debug.in
blob: 84b2196d3f3d1b027b62c6aa2bd0201f0b01f161 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#!/bin/bash

###########################################################################
# Copyright (C) 2017-2019 IoT.bzh
#
# Author: Stephane Desneux <sdx@iot.bzh>
#         Sebastien Douheret <sebastien@iot.bzh>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
###########################################################################

# This script should be invoked by gdb client through a ssh connection.
# It relays gdbmi protocol from gdbserver to gdb client
#
# WARNING: nothing should be sent to stdout except gdbserver output

# FIXME: add support of --debugger option to support tcf or gdb-remote


function error() {
	echo "ERR: $@" >&2
	exit 1
}
function info() {
	echo "INF: $@" >&2
}

# setup debug dir (shared with service file)
DBGDIR=@afm_platform_rundir@/debug
mkdir -p $DBGDIR

# check application name passed as first arg by gdb
APP=$1
[[ -z "$APP" ]] && error "Invalid application name"

# redirect to log file
exec 2>$DBGDIR/$APP.dbgclt.log

# activate DEBUG in environment file sourced in systemd service
AFB_WAIT_POINT="start-start"
echo "AFB_DEBUG_WAIT=$AFB_WAIT_POINT" >$DBGDIR/$APP.env

# remove debug env file on exit
trap "rm $DBGDIR/$APP.*" STOP INT QUIT EXIT

# ask appfw to start application
pid=$(afm-util start $APP)
[[ -z "$pid" || ! -e "/proc/$pid" ]] && error "Failed to start application $APP"
info "$APP started with pid=$pid"

# wait debugging process is stop/waiting at start-start point
AFB_FILE=/tmp/afb-debug-$pid
tmo=100
info "Waiting for process stopped..."
while [[ ! -e "$AFB_FILE" ]]; do
    sleep 0.1
    tmo=$(expr $tmo - 1)
    [[ "$tmo" == "0" ]] && error "Timeout waiting for process $pid stopped"
done

info "Waiting for process stopped..."
AFB_WAIT_FILE=/tmp/afb-debug-$pid
tmo=100
res=1
while [[ "$res" != "0" ]]; do
    sleep 0.1
    tmo=$(expr $tmo - 1)
    [[ "$tmo" == "0" ]] && error "Timeout waiting for process $pid stopped"
    grep $AFB_WAIT_POINT $AFB_WAIT_FILE > /dev/null 2>&1
    res=$?
done

# debugging
info "Attaching gdbserver to pid $pid ..."
gdbserver --attach - $pid

# end of debug session
info "proxy connection terminated - killing $APP (pid $pid)"
afm-util kill $pid >&2
info "$APP killed"
"cp">#include <linux/kobject.h> /* struct kobj_type */ #include <linux/sysfs.h> /* struct attribute */ struct module; /** * Interface type */ enum most_interface_type { ITYPE_LOOPBACK = 1, ITYPE_I2C, ITYPE_I2S, ITYPE_TSI, ITYPE_HBI, ITYPE_MEDIALB_DIM, ITYPE_MEDIALB_DIM2, ITYPE_USB, ITYPE_PCIE }; /** * Channel direction. */ enum most_channel_direction { MOST_CH_RX = 1 << 0, MOST_CH_TX = 1 << 1, }; /** * Channel data type. */ enum most_channel_data_type { MOST_CH_CONTROL = 1 << 0, MOST_CH_ASYNC = 1 << 1, MOST_CH_ISOC = 1 << 2, MOST_CH_SYNC = 1 << 5, }; enum mbo_status_flags { /* MBO was processed successfully (data was send or received )*/ MBO_SUCCESS = 0, /* The MBO contains wrong or missing information. */ MBO_E_INVAL, /* MBO was completed as HDM Channel will be closed */ MBO_E_CLOSE, }; /** * struct most_channel_capability - Channel capability * @direction: Supported channel directions. * The value is bitwise OR-combination of the values from the * enumeration most_channel_direction. Zero is allowed value and means * "channel may not be used". * @data_type: Supported channel data types. * The value is bitwise OR-combination of the values from the * enumeration most_channel_data_type. Zero is allowed value and means * "channel may not be used". * @num_buffer_packet: Maximum number of buffers supported by this channel * for packet data types (Async,Control,QoS) * @buffer_size_packet: Maximum buffer size supported by this channel * for packet data types (Async,Control,QoS) * @num_buffer_streaming: Maximum number of buffers supported by this channel * for streaming data types (Sync,AV Packetized) * @buffer_size_streaming: Maximum buffer size supported by this channel * for streaming data types (Sync,AV Packetized) * @name_suffix: Optional suffix providean by an HDM that is attached to the * regular channel name. * * Describes the capabilities of a MostCore channel like supported Data Types * and directions. This information is provided by an HDM for the MostCore. * * The Core creates read only sysfs attribute files in * /sys/devices/virtual/most/mostcore/devices/mdev-#/mdev#-ch#/ with the * following attributes: * -available_directions * -available_datatypes * -number_of_packet_buffers * -number_of_stream_buffers * -size_of_packet_buffer * -size_of_stream_buffer * where content of each file is a string with all supported properties of this * very channel attribute. */ struct most_channel_capability { u16 direction; u16 data_type; u16 num_buffers_packet; u16 buffer_size_packet; u16 num_buffers_streaming; u16 buffer_size_streaming; const char *name_suffix; }; /** * struct most_channel_config - stores channel configuration * @direction: direction of the channel * @data_type: data type travelling over this channel * @num_buffers: number of buffers * @buffer_size: size of a buffer for AIM. * Buffer size may be cutted down by HDM in a configure callback * to match to a given interface and channel type. * @extra_len: additional buffer space for internal HDM purposes like padding. * May be set by HDM in a configure callback if needed. * @subbuffer_size: size of a subbuffer * @packets_per_xact: number of MOST frames that are packet inside one USB * packet. This is USB specific * * Describes the configuration for a MostCore channel. This information is * provided from the MostCore to a HDM (like the Medusa PCIe Interface) as a * parameter of the "configure" function call. */ struct most_channel_config { enum most_channel_direction direction; enum most_channel_data_type data_type; u16 num_buffers; u16 buffer_size; u16 extra_len; u16 subbuffer_size; u16 packets_per_xact; u16 dbr_size; }; /* * struct mbo - MOST Buffer Object. * @context: context for core completion handler * @priv: private data for HDM * * public: documented fields that are used for the communications * between MostCore and HDMs * * @list: list head for use by the mbo's current owner * @ifp: (in) associated interface instance * @hdm_channel_id: (in) HDM channel instance * @virt_address: (in) kernel virtual address of the buffer * @bus_address: (in) bus address of the buffer * @buffer_length: (in) buffer payload length * @processed_length: (out) processed length * @status: (out) transfer status * @complete: (in) completion routine * * The MostCore allocates and initializes the MBO. * * The HDM receives MBO for transfer from MostCore with the call to enqueue(). * The HDM copies the data to- or from the buffer depending on configured * channel direction, set "processed_length" and "status" and completes * the transfer procedure by calling the completion routine. * * At the end the MostCore deallocates the MBO or recycles it for further * transfers for the same or different HDM. * * Directions of usage: * The core driver should never access any MBO fields (even if marked * as "public") while the MBO is owned by an HDM. The ownership starts with * the call of enqueue() and ends with the call of its complete() routine. * * II. * Every HDM attached to the core driver _must_ ensure that it returns any MBO * it owns (due to a previous call to enqueue() by the core driver) before it * de-registers an interface or gets unloaded from the kernel. If this direction * is violated memory leaks will occur, since the core driver does _not_ track * MBOs it is currently not in control of. * */ struct mbo { void *context; void *priv; struct list_head list; struct most_interface *ifp; int *num_buffers_ptr; u16 hdm_channel_id; void *virt_address; dma_addr_t bus_address; u16 buffer_length; u16 processed_length; enum mbo_status_flags status; void (*complete)(struct mbo *); }; /** * Interface instance description. * * Describes one instance of an interface like Medusa PCIe or Vantage USB. * This structure is allocated and initialized in the HDM. MostCore may not * modify this structure. * * @interface Interface type. \sa most_interface_type. * @description PRELIMINARY. * Unique description of the device instance from point of view of the * interface in free text form (ASCII). * It may be a hexadecimal presentation of the memory address for the MediaLB * IP or USB device ID with USB properties for USB interface, etc. * @num_channels Number of channels and size of the channel_vector. * @channel_vector Properties of the channels. * Array index represents channel ID by the driver. * @configure Callback to change data type for the channel of the * interface instance. May be zero if the instance of the interface is not * configurable. Parameter channel_config describes direction and data * type for the channel, configured by the higher level. The content of * @enqueue Delivers MBO to the HDM for processing. * After HDM completes Rx- or Tx- operation the processed MBO shall * be returned back to the MostCore using completion routine. * The reason to get the MBO delivered from the MostCore after the channel * is poisoned is the re-opening of the channel by the application. * In this case the HDM shall hold MBOs and service the channel as usual. * The HDM must be able to hold at least one MBO for each channel. * The callback returns a negative value on error, otherwise 0. * @poison_channel Informs HDM about closing the channel. The HDM shall * cancel all transfers and synchronously or asynchronously return * all enqueued for this channel MBOs using the completion routine. * The callback returns a negative value on error, otherwise 0. * @request_netinfo: triggers retrieving of network info from the HDM by * means of "Message exchange over MDP/MEP" * The call of the function request_netinfo with the parameter on_netinfo as * NULL prohibits use of the previously obtained function pointer. * @priv Private field used by mostcore to store context information. */ struct most_interface { struct module *mod; struct device *dev; enum most_interface_type interface; const char *description; int num_channels; struct most_channel_capability *channel_vector; void *(*dma_alloc)(struct mbo *mbo, u32 size); void (*dma_free)(struct mbo *mbo, u32 size); int (*configure)(struct most_interface *iface, int channel_idx, struct most_channel_config *channel_config); int (*enqueue)(struct most_interface *iface, int channel_idx, struct mbo *mbo); int (*poison_channel)(struct most_interface *iface, int channel_idx); void (*request_netinfo)(struct most_interface *iface, int channel_idx, void (*on_netinfo)(struct most_interface *iface, unsigned char link_stat, unsigned char *mac_addr)); struct attribute *attrs[14]; struct kobj_type ktype; enum { NONE_ATTRS /* default */, XACT_ATTRS, DBR_ATTRS } extra_attrs; void *priv; }; /** * struct most_aim - identifies MOST device driver to mostcore * @name: Driver name * @probe_channel: function for core to notify driver about channel connection * @disconnect_channel: callback function to disconnect a certain channel * @rx_completion: completion handler for received packets * @tx_completion: completion handler for transmitted packets * @context: context pointer to be used by mostcore */ struct most_aim { const char *name; int (*probe_channel)(struct most_interface *iface, int channel_idx, struct most_channel_config *cfg, struct kobject *parent, char *name); int (*disconnect_channel)(struct most_interface *iface, int channel_idx); int (*rx_completion)(struct mbo *mbo); int (*tx_completion)(struct most_interface *iface, int channel_idx); void *context; }; /** * most_register_interface - Registers instance of the interface. * @iface: Pointer to the interface instance description. * * Returns a pointer to the kobject of the generated instance. * * Note: HDM has to ensure that any reference held on the kobj is * released before deregistering the interface. */ struct kobject *most_register_interface(struct most_interface *iface); /** * Deregisters instance of the interface. * @intf_instance Pointer to the interface instance description. */ void most_deregister_interface(struct most_interface *iface); void most_submit_mbo(struct mbo *mbo); /** * most_stop_enqueue - prevents core from enqueing MBOs * @iface: pointer to interface * @channel_idx: channel index */ void most_stop_enqueue(struct most_interface *iface, int channel_idx); /** * most_resume_enqueue - allow core to enqueue MBOs again * @iface: pointer to interface * @channel_idx: channel index * * This clears the enqueue halt flag and enqueues all MBOs currently * in wait fifo. */ void most_resume_enqueue(struct most_interface *iface, int channel_idx); int most_register_aim(struct most_aim *aim); int most_deregister_aim(struct most_aim *aim); struct mbo *most_get_mbo(struct most_interface *iface, int channel_idx, struct most_aim *); void most_put_mbo(struct mbo *mbo); int channel_has_mbo(struct most_interface *iface, int channel_idx, struct most_aim *aim); int most_start_channel(struct most_interface *iface, int channel_idx, struct most_aim *); int most_stop_channel(struct most_interface *iface, int channel_idx, struct most_aim *); #endif /* MOST_CORE_H_ */