From eacc39709b9d7d7c441553dea179a2b5b9ee7adc Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Fri, 4 Feb 2011 20:45:49 -0500 Subject: [PATCH] --- yaml --- r: 235519 b: refs/heads/master c: 5427bcf5e95245d3e220742ac703182bdb973769 h: refs/heads/master i: 235517: c00803e5f6307af68b1c2bc74796e208694318b7 235515: c85d0214e5cba9fb12dd37e11c91b2a6f6da45fa 235511: 9bdc4d6764c478891c8190033a41bf26f0467b68 235503: eed74006ae1ca4a3f26ce85adbf878d8421630c1 235487: e5b6909930a57d0e042596c8cbfcc5673066f72f 235455: 8e6dbc4eb8560bf74e434c9c2b756ae3a0384dd7 235391: 9f50e03a80051b6a6e37b7b1e76ade220a56663b 235263: 9cf0338fb99d8b5ea082ccb9391e02cada9300f3 235007: f469f1f10ad75d106cb803031a0192b98ed62495 234495: 17e522513e3f851e47435721b330b74bd722ee84 233471: 084caba7e692ebffef08f75651b84a0942241987 v: v3 --- [refs] | 2 +- trunk/drivers/char/Kconfig | 9 +++ trunk/drivers/tty/hvc/Makefile | 1 + trunk/drivers/tty/hvc/hvc_bfin_jtag.c | 105 ++++++++++++++++++++++++++ 4 files changed, 116 insertions(+), 1 deletion(-) create mode 100644 trunk/drivers/tty/hvc/hvc_bfin_jtag.c diff --git a/[refs] b/[refs] index 44747dc9a850..5bccf602fcc6 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 9fc3de9c83565fcaa23df74c2fc414bb6e7efb0a +refs/heads/master: 5427bcf5e95245d3e220742ac703182bdb973769 diff --git a/trunk/drivers/char/Kconfig b/trunk/drivers/char/Kconfig index b7980a83ce2d..17f9b968b988 100644 --- a/trunk/drivers/char/Kconfig +++ b/trunk/drivers/char/Kconfig @@ -691,6 +691,15 @@ config HVC_DCC driver. This console is used through a JTAG only on ARM. If you don't have a JTAG then you probably don't want this option. +config HVC_BFIN_JTAG + bool "Blackfin JTAG console" + depends on BLACKFIN + select HVC_DRIVER + help + This console uses the Blackfin JTAG to create a console under the + the HVC driver. If you don't have JTAG, then you probably don't + want this option. + config VIRTIO_CONSOLE tristate "Virtio console" depends on VIRTIO diff --git a/trunk/drivers/tty/hvc/Makefile b/trunk/drivers/tty/hvc/Makefile index e6bed5f177ff..7b0edbce9009 100644 --- a/trunk/drivers/tty/hvc/Makefile +++ b/trunk/drivers/tty/hvc/Makefile @@ -9,5 +9,6 @@ obj-$(CONFIG_HVC_IRQ) += hvc_irq.o obj-$(CONFIG_HVC_XEN) += hvc_xen.o obj-$(CONFIG_HVC_IUCV) += hvc_iucv.o obj-$(CONFIG_HVC_UDBG) += hvc_udbg.o +obj-$(CONFIG_HVC_BFIN_JTAG) += hvc_bfin_jtag.o obj-$(CONFIG_HVCS) += hvcs.o obj-$(CONFIG_VIRTIO_CONSOLE) += virtio_console.o diff --git a/trunk/drivers/tty/hvc/hvc_bfin_jtag.c b/trunk/drivers/tty/hvc/hvc_bfin_jtag.c new file mode 100644 index 000000000000..31d6cc6a77af --- /dev/null +++ b/trunk/drivers/tty/hvc/hvc_bfin_jtag.c @@ -0,0 +1,105 @@ +/* + * Console via Blackfin JTAG Communication + * + * Copyright 2008-2011 Analog Devices Inc. + * + * Enter bugs at http://blackfin.uclinux.org/ + * + * Licensed under the GPL-2 or later. + */ + +#include +#include +#include +#include +#include +#include + +#include "hvc_console.h" + +/* See the Debug/Emulation chapter in the HRM */ +#define EMUDOF 0x00000001 /* EMUDAT_OUT full & valid */ +#define EMUDIF 0x00000002 /* EMUDAT_IN full & valid */ +#define EMUDOOVF 0x00000004 /* EMUDAT_OUT overflow */ +#define EMUDIOVF 0x00000008 /* EMUDAT_IN overflow */ + +/* Helper functions to glue the register API to simple C operations */ +static inline uint32_t bfin_write_emudat(uint32_t emudat) +{ + __asm__ __volatile__("emudat = %0;" : : "d"(emudat)); + return emudat; +} + +static inline uint32_t bfin_read_emudat(void) +{ + uint32_t emudat; + __asm__ __volatile__("%0 = emudat;" : "=d"(emudat)); + return emudat; +} + +/* Send data to the host */ +static int hvc_bfin_put_chars(uint32_t vt, const char *buf, int count) +{ + static uint32_t outbound_len; + uint32_t emudat; + int ret; + + if (bfin_read_DBGSTAT() & EMUDOF) + return 0; + + if (!outbound_len) { + outbound_len = count; + bfin_write_emudat(outbound_len); + return 0; + } + + ret = min(outbound_len, (uint32_t)4); + memcpy(&emudat, buf, ret); + bfin_write_emudat(emudat); + outbound_len -= ret; + + return ret; +} + +/* Receive data from the host */ +static int hvc_bfin_get_chars(uint32_t vt, char *buf, int count) +{ + static uint32_t inbound_len; + uint32_t emudat; + int ret; + + if (!(bfin_read_DBGSTAT() & EMUDIF)) + return 0; + emudat = bfin_read_emudat(); + + if (!inbound_len) { + inbound_len = emudat; + return 0; + } + + ret = min(inbound_len, (uint32_t)4); + memcpy(buf, &emudat, ret); + inbound_len -= ret; + + return ret; +} + +/* Glue the HVC layers to the Blackfin layers */ +static const struct hv_ops hvc_bfin_get_put_ops = { + .get_chars = hvc_bfin_get_chars, + .put_chars = hvc_bfin_put_chars, +}; + +static int __init hvc_bfin_console_init(void) +{ + hvc_instantiate(0, 0, &hvc_bfin_get_put_ops); + return 0; +} +console_initcall(hvc_bfin_console_init); + +static int __init hvc_bfin_init(void) +{ + hvc_alloc(0, 0, &hvc_bfin_get_put_ops, 128); + return 0; +} +device_initcall(hvc_bfin_init);