[ndebug] Move NDebug from main LK tree to Coral tree.

This commit is contained in:
Gurjant Kalsi
2016-06-03 16:28:00 -07:00
parent c01adc6e0d
commit 5324238022
15 changed files with 2 additions and 1256 deletions

View File

View File

@@ -1,53 +0,0 @@
/*
* Copyright 2016 Google Inc. All Rights Reserved.
* Author: gkalsi@google.com (Gurjant Kalsi)
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#pragma once
#include <compiler.h>
#include <stdint.h>
#include <sys/types.h>
#define NDEBUG_MAX_PACKET_SIZE (64)
__BEGIN_CDECLS
typedef enum {
NDEBUG_CHANNEL_SYS,
NDEBUG_CHANNEL_USR,
NDEBUG_CHANNEL_COUNT, // Count: always last.
} channel_t;
void ndebug_init(void);
ssize_t ndebug_usb_read(const channel_t ch, const size_t n,
const lk_time_t timeout, uint8_t *buf);
ssize_t ndebug_usb_write(const channel_t ch, const size_t n,
const lk_time_t timeout, uint8_t *buf);
status_t ndebug_await_connection(const channel_t ch, const lk_time_t timeout);
status_t msg_host(const channel_t ch, const uint32_t message,
const lk_time_t timeout, uint8_t *buf);
__END_CDECLS

View File

@@ -1,44 +0,0 @@
/*
* Copyright 2016 Google Inc. All Rights Reserved.
* Author: gkalsi@google.com (Gurjant Kalsi)
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#pragma once
#include <stdint.h>
typedef struct __attribute__((packed)) {
uint32_t magic;
uint32_t type;
} ndebug_ctrl_packet_t;
#define NDEBUG_CTRL_PACKET_MAGIC (0x4354524C)
#define NDEBUG_CTRL_CMD_RESET (0x01)
#define NDEBUG_CTRL_CMD_DATA (0x02)
#define NDEBUG_CTRL_CMD_ESTABLISHED (0x03)
#define NDEBUG_USB_CLASS_USER_DEFINED (0xFF)
#define NDEBUG_SUBCLASS (0x02)
#define NDEBUG_PROTOCOL_LK_SYSTEM (0x01)
#define NDEBUG_PROTOCOL_SERIAL_PIPE (0x02)

View File

@@ -1,43 +0,0 @@
/*
* Copyright 2016 Google Inc. All Rights Reserved.
* Author: gkalsi@google.com (Gurjant Kalsi)
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#pragma once
#include <compiler.h>
#include <lib/ndebug/ndebug.h>
#include <lib/ndebug/shared_structs.h>
__BEGIN_CDECLS
#define NDEBUG_USR_MAX_PACKET_SIZE (NDEBUG_MAX_PACKET_SIZE - sizeof(ndebug_ctrl_packet_t))
// Read and write to the NDebug user channel.
ssize_t ndebug_read_usr(uint8_t *buf, const lk_time_t timeout);
ssize_t ndebug_write_usr(uint8_t *buf, const size_t n, const lk_time_t timeout);
// Wait for the host to establish a connection on the usr channel.
status_t ndebug_await_connection_usr(lk_time_t timeout);
__END_CDECLS

View File

@@ -1,292 +0,0 @@
/*
* Copyright 2016 Google Inc. All Rights Reserved.
* Author: gkalsi@google.com (Gurjant Kalsi)
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <lib/ndebug/ndebug.h>
#include <assert.h>
#include <dev/udc.h>
#include <dev/usb.h>
#include <dev/usbc.h>
#include <err.h>
#include <kernel/event.h>
#include <lib/ndebug/shared_structs.h>
#include <string.h>
#include <trace.h>
#define LOCAL_TRACE 0
#define W(w) (w & 0xff), (w >> 8)
#define W3(w) (w & 0xff), ((w >> 8) & 0xff), ((w >> 16) & 0xff)
#define IFACE_SUBCLASS_IDX (0x06)
#define IFACE_PROTOCOL_IDX (0x07)
#define IFACE_IN_ADDR_IDX (0x0B)
#define IFACE_OUT_ADDR_IDX (0x12)
#define CH_TO_ADDR(CH) ((CH) + 1)
#define CHECK_CHANNEL(CH) \
do { DEBUG_ASSERT((CH) < NDEBUG_CHANNEL_COUNT); } while (false);
#define SYS_EP_ADDR (CH_TO_ADDR(NDEBUG_CHANNEL_SYS))
#define USR_EP_ADDR (CH_TO_ADDR(NDEBUG_CHANNEL_USR))
#define NDEBUG_SUBCLASS (0x02)
#define NDEBUG_PROTOCOL_LK_SYSTEM (0x01)
#define NDEBUG_PROTOCOL_SERIAL_PIPE (0x02)
static usbc_transfer_t rx_transfer[NDEBUG_CHANNEL_COUNT];
static usbc_transfer_t tx_transfer[NDEBUG_CHANNEL_COUNT];
static event_t rx_event[NDEBUG_CHANNEL_COUNT];
static event_t tx_event[NDEBUG_CHANNEL_COUNT];
static event_t usb_online_event;
static const uint8_t bulk_pair_descriptor_template[] = {
0x09, /* length */
INTERFACE, /* type */
0x00, /* interface num - Unused, patched in by dev/usb */
0x00, /* alternates */
0x02, /* endpoint count */
0xff, /* interface class - User Deficned */
0x00, /* interface subclass - Patched by client */
0x00, /* interface protocol - Patched by client */
0x00, /* string index */
/* endpoint 1 IN */
0x07, /* length */
ENDPOINT, /* type */
0x80, /* address - Patched by Client */
0x02, /* type: bulk */
W(64), /* max packet size: 64 */
00, /* interval - unused for bulk */
/* endpoint 1 OUT */
0x07, /* length */
ENDPOINT, /* type */
0x00, /* address - Patched by client */
0x02, /* type: bulk */
W(64), /* max packet size: 64 */
00, /* interval - unused for bulk */
};
static void init_channel(uint8_t subclass, uint8_t protocol, uint8_t ep_addr)
{
uint8_t desc[sizeof(bulk_pair_descriptor_template)];
// Make a copy of the template descriptor and fill in the missing fields.
memcpy(desc, bulk_pair_descriptor_template,
sizeof(bulk_pair_descriptor_template));
desc[IFACE_SUBCLASS_IDX] = subclass;
desc[IFACE_PROTOCOL_IDX] = protocol;
desc[IFACE_IN_ADDR_IDX] = ep_addr | 0x80;
desc[IFACE_OUT_ADDR_IDX] = ep_addr;
// Append the interfaces.
usb_append_interface_lowspeed(desc, sizeof(desc));
usb_append_interface_highspeed(desc, sizeof(desc));
}
static void setup_usb_endpoint(uint8_t ep_num)
{
usbc_setup_endpoint(ep_num, USB_IN, 0x40, USB_BULK);
usbc_setup_endpoint(ep_num, USB_OUT, 0x40, USB_BULK);
}
static status_t ndebug_register_cb(
void *cookie,
usb_callback_op_t op,
const union usb_callback_args *args
)
{
if (op == USB_CB_ONLINE) {
for (channel_t ch = 0; ch < NDEBUG_CHANNEL_COUNT; ++ch) {
setup_usb_endpoint(CH_TO_ADDR(ch));
}
event_signal(&usb_online_event, false);
} else if (op == USB_CB_RESET || op == USB_CB_DISCONNECT ||
op == USB_CB_OFFLINE) {
event_unsignal(&usb_online_event);
}
return NO_ERROR;
}
void ndebug_init(void)
{
for (channel_t ch = 0; ch < NDEBUG_CHANNEL_COUNT; ++ch) {
event_init(&rx_event[ch], 0, EVENT_FLAG_AUTOUNSIGNAL);
event_init(&tx_event[ch], 0, EVENT_FLAG_AUTOUNSIGNAL);
}
init_channel(NDEBUG_SUBCLASS, NDEBUG_PROTOCOL_LK_SYSTEM, SYS_EP_ADDR);
init_channel(NDEBUG_SUBCLASS, NDEBUG_PROTOCOL_SERIAL_PIPE, USR_EP_ADDR);
event_init(&usb_online_event, 0, 0);
usb_register_callback(&ndebug_register_cb, NULL);
}
static status_t usb_xmit_cplt_cb(ep_t endpoint, usbc_transfer_t *t)
{
uint32_t channel = (uint32_t)t->extra;
CHECK_CHANNEL(channel);
event_signal(&tx_event[channel], false);
return 0;
}
static status_t usb_recv_cplt_cb(ep_t endpoint, usbc_transfer_t *t)
{
uint32_t channel = (uint32_t)t->extra;
CHECK_CHANNEL(channel);
event_signal(&rx_event[channel], false);
return 0;
}
ssize_t ndebug_usb_read(const channel_t ch, const size_t n,
const lk_time_t timeout, uint8_t *buf)
{
CHECK_CHANNEL(ch);
usbc_transfer_t *transfer = &rx_transfer[ch];
transfer->callback = &usb_recv_cplt_cb;
transfer->result = 0;
transfer->buf = buf;
transfer->buflen = n;
transfer->bufpos = 0;
transfer->extra = (void *)ch;
usbc_queue_rx(CH_TO_ADDR(ch), transfer);
status_t res = event_wait_timeout(&rx_event[ch], timeout);
if (res != NO_ERROR) {
return res;
}
if (transfer->result != NO_ERROR) {
return transfer->result;
}
return transfer->bufpos;
}
ssize_t ndebug_usb_write(const channel_t ch, const size_t n,
const lk_time_t timeout, uint8_t *buf)
{
CHECK_CHANNEL(ch);
usbc_transfer_t *transfer = &tx_transfer[ch];
transfer->callback = &usb_xmit_cplt_cb;
transfer->result = 0;
transfer->buf = buf;
transfer->buflen = n;
transfer->bufpos = 0;
transfer->extra = (void *)ch;
usbc_queue_tx(CH_TO_ADDR(ch), transfer);
status_t res = event_wait_timeout(&tx_event[ch], timeout);
if (res != NO_ERROR) {
return res;
}
if (transfer->result != NO_ERROR) {
return transfer->result;
}
return n;
}
static bool is_valid_connection_request(ssize_t n, const uint8_t *buf)
{
LTRACEF("length: %ld, buf: 0x%p\n", n, buf);
if (n < (ssize_t)sizeof(ndebug_ctrl_packet_t)) {
dprintf(INFO, "Malformed Packet. Expected at least %u bytes, got %ld\n",
sizeof(ndebug_ctrl_packet_t), n);
return false;
}
ndebug_ctrl_packet_t *pkt = (ndebug_ctrl_packet_t *)buf;
return pkt->magic == NDEBUG_CTRL_PACKET_MAGIC &&
pkt->type == NDEBUG_CTRL_CMD_RESET;
}
status_t msg_host(
const channel_t ch, const uint32_t message,
const lk_time_t timeout, uint8_t *buf
)
{
LTRACEF("message: %d\n", message);
ndebug_ctrl_packet_t *pkt = (ndebug_ctrl_packet_t *)buf;
pkt->magic = NDEBUG_CTRL_PACKET_MAGIC;
pkt->type = message;
ssize_t res =
ndebug_usb_write(ch, sizeof(ndebug_ctrl_packet_t), timeout, buf);
if (res == ERR_TIMED_OUT) {
dprintf(INFO, "send message %d timed out\n", message);
} else if (res < 0) {
dprintf(INFO, "send message %d failed with error %ld\n", message, res);
}
return res;
}
status_t ndebug_await_connection(const channel_t ch, const lk_time_t timeout)
{
LTRACEF("channel: %u, timeout: %u\n", ch, timeout);
uint8_t buf[NDEBUG_MAX_PACKET_SIZE];
status_t result = event_wait_timeout(&usb_online_event, timeout);
if (result != NO_ERROR) {
return result;
}
while (true) {
ssize_t bytes =
ndebug_usb_read(ch, NDEBUG_MAX_PACKET_SIZE, timeout, buf);
if (bytes < 0) return bytes;
if (bytes < (ssize_t)sizeof(ndebug_ctrl_packet_t)) continue;
if (!is_valid_connection_request(bytes, buf)) {
msg_host(ch, NDEBUG_CTRL_CMD_RESET, timeout, buf);
continue;
}
if (msg_host(ch, NDEBUG_CTRL_CMD_ESTABLISHED, timeout, buf) < 0) {
continue;
}
return NO_ERROR;
}
}

View File

@@ -1,12 +0,0 @@
LOCAL_DIR := $(GET_LOCAL_DIR)
MODULE := $(LOCAL_DIR)
# MODULE_DEPS := \
MODULE_SRCS += \
$(LOCAL_DIR)/ndebug.c \
$(LOCAL_DIR)/user.c \
include make/module.mk

View File

@@ -1,157 +0,0 @@
/*
* Copyright 2016 Google Inc. All Rights Reserved.
* Author: gkalsi@google.com (Gurjant Kalsi)
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <lib/ndebug/ndebug.h>
#include <lib/ndebug/shared_structs.h>
#include <lib/ndebug/user.h>
#include <assert.h>
#include <err.h>
#include <kernel/mutex.h>
#include <stdlib.h>
#include <string.h>
#include <trace.h>
#define LOCAL_TRACE 0
#define HOST_MSG_TIMEOUT (1000) // 1 Second
static volatile bool connected = false;
static mutex_t usr_mutex = MUTEX_INITIAL_VALUE(usr_mutex);
static uint8_t scratch_buffer[NDEBUG_MAX_PACKET_SIZE];
status_t ndebug_await_connection_usr(lk_time_t timeout)
{
LTRACEF("timeout: %u\n", timeout);
status_t result = ndebug_await_connection(NDEBUG_CHANNEL_USR, timeout);
if (result == NO_ERROR) {
connected = true;
} else {
connected = false;
}
return result;
}
ssize_t ndebug_read_usr(uint8_t *buf, const lk_time_t timeout)
{
LTRACEF("buf: 0x%p, timeout: %u\n", buf, timeout);
if (!connected) {
// User must call ndebugusr_await_host and establish a connection
// before continuing.
return ERR_CHANNEL_CLOSED;
}
mutex_acquire(&usr_mutex);
// Retry Loop
while (true) {
ssize_t result = ndebug_usb_read(NDEBUG_CHANNEL_USR,
NDEBUG_MAX_PACKET_SIZE,
timeout, scratch_buffer);
if (result < (ssize_t)sizeof(ndebug_ctrl_packet_t)) {
dprintf(INFO, "Short Packet. Len = %ld\n", result);
continue;
}
ndebug_ctrl_packet_t *ctrl = (ndebug_ctrl_packet_t *)scratch_buffer;
if (ctrl->magic != NDEBUG_CTRL_PACKET_MAGIC) {
dprintf(INFO, "Bad Packet Magic = %u\n", ctrl->magic);
continue;
}
if (ctrl->type == NDEBUG_CTRL_CMD_RESET) {
msg_host(NDEBUG_CHANNEL_USR, NDEBUG_CTRL_CMD_RESET, timeout,
scratch_buffer);
connected = false;
mutex_release(&usr_mutex);
return ERR_CHANNEL_CLOSED;
} else if (ctrl->type == NDEBUG_CTRL_CMD_DATA) {
const ssize_t n_data_bytes = result - sizeof(ndebug_ctrl_packet_t);
memcpy(buf, scratch_buffer + sizeof(ndebug_ctrl_packet_t),
n_data_bytes);
mutex_release(&usr_mutex);
return n_data_bytes;
} else {
dprintf(INFO, "Unexpected packet type = %u\n", ctrl->type);
}
}
}
ssize_t ndebug_write_usr(uint8_t *buf, const size_t n, const lk_time_t timeout)
{
LTRACEF("buf = 0x%p, n = %u, timeout = %u\n", buf, n, timeout);
if (!connected) {
// User must call ndebugusr_await_host and establish a connection
// before continuing.
return ERR_CHANNEL_CLOSED;
}
mutex_acquire(&usr_mutex);
uint8_t *cursor = scratch_buffer;
ndebug_ctrl_packet_t *pkt = (ndebug_ctrl_packet_t *)cursor;
pkt->magic = NDEBUG_CTRL_PACKET_MAGIC;
pkt->type = NDEBUG_CTRL_CMD_DATA;
cursor += sizeof(ndebug_ctrl_packet_t);
ssize_t res;
size_t bytes_remaining = n;
do {
size_t bytes_to_copy = MIN(NDEBUG_USR_MAX_PACKET_SIZE, bytes_remaining);
memcpy(cursor, buf, bytes_to_copy);
buf += bytes_to_copy;
bytes_remaining -= bytes_to_copy;
res = ndebug_usb_write(
NDEBUG_CHANNEL_USR,
bytes_to_copy + sizeof(ndebug_ctrl_packet_t),
timeout,
scratch_buffer
);
if (res < 0) {
break;
}
} while (bytes_remaining > 0);
mutex_release(&usr_mutex);
if (res < 0) {
return res;
} else {
return (ssize_t)n;
}
}