PERFORCE change 213999 for review
Robert Watson
rwatson at FreeBSD.org
Fri Jul 6 22:40:12 UTC 2012
http://p4web.freebsd.org/@@213999?ac=10
Change 213999 by rwatson at rwatson_svr_ctsrd_mipsbuild on 2012/07/06 22:39:08
Integrate CheriBSD branch to brin in Altera JTAG UART driver
improvements, significant demo application work.
Affected files ...
.. //depot/projects/ctsrd/cheribsd/src/ctsrd-lib/libde4tc/Makefile#2 integrate
.. //depot/projects/ctsrd/cheribsd/src/ctsrd-lib/libde4tc/de4tc.c#2 integrate
.. //depot/projects/ctsrd/cheribsd/src/ctsrd-lib/libde4tc/de4tc.h#2 integrate
.. //depot/projects/ctsrd/cheribsd/src/ctsrd-lib/libde4tc/syscons-fonts.c#1 branch
.. //depot/projects/ctsrd/cheribsd/src/ctsrd-lib/libvuln_magic/Makefile#1 branch
.. //depot/projects/ctsrd/cheribsd/src/ctsrd-lib/libvuln_magic/config.h#1 branch
.. //depot/projects/ctsrd/cheribsd/src/ctsrd-lib/libvuln_magic/funcs.c#1 branch
.. //depot/projects/ctsrd/cheribsd/src/ctsrd/Makefile#3 integrate
.. //depot/projects/ctsrd/cheribsd/src/ctsrd/browser/Makefile#1 branch
.. //depot/projects/ctsrd/cheribsd/src/ctsrd/browser/browser.c#1 branch
.. //depot/projects/ctsrd/cheribsd/src/ctsrd/browser/images/Makefile#1 branch
.. //depot/projects/ctsrd/cheribsd/src/ctsrd/browser/images/browser.png#1 branch
.. //depot/projects/ctsrd/cheribsd/src/ctsrd/browser/images/icons.png#1 branch
.. //depot/projects/ctsrd/cheribsd/src/ctsrd/cycle_led/Makefile#1 branch
.. //depot/projects/ctsrd/cheribsd/src/ctsrd/cycle_led/cycle_led.sh#1 branch
.. //depot/projects/ctsrd/cheribsd/src/ctsrd/flashit/flashit.sh#2 integrate
.. //depot/projects/ctsrd/cheribsd/src/ctsrd/minifile/Makefile#1 branch
.. //depot/projects/ctsrd/cheribsd/src/ctsrd/minifile/minifile.c#1 branch
.. //depot/projects/ctsrd/cheribsd/src/ctsrd/pictview/Makefile#2 integrate
.. //depot/projects/ctsrd/cheribsd/src/ctsrd/pictview/pictview.c#3 integrate
.. //depot/projects/ctsrd/cheribsd/src/ctsrd/showimage/Makefile#1 branch
.. //depot/projects/ctsrd/cheribsd/src/ctsrd/showimage/images/Makefile#1 branch
.. //depot/projects/ctsrd/cheribsd/src/ctsrd/showimage/images/booting.png#1 branch
.. //depot/projects/ctsrd/cheribsd/src/ctsrd/showimage/images/upgrade-complete.png#1 branch
.. //depot/projects/ctsrd/cheribsd/src/ctsrd/showimage/images/upgrade-inprogress.png#1 branch
.. //depot/projects/ctsrd/cheribsd/src/ctsrd/showimage/showimage.c#1 branch
.. //depot/projects/ctsrd/cheribsd/src/ctsrd/spinner/spinner.c#2 integrate
.. //depot/projects/ctsrd/cheribsd/src/etc/mtree/BSD.usr.dist#2 integrate
.. //depot/projects/ctsrd/cheribsd/src/etc/rc#2 integrate
.. //depot/projects/ctsrd/cheribsd/src/etc/rc.subr#2 integrate
.. //depot/projects/ctsrd/cheribsd/src/sys/conf/options.mips#4 integrate
.. //depot/projects/ctsrd/cheribsd/src/sys/dev/altera/avgen/altera_avgen.c#2 integrate
.. //depot/projects/ctsrd/cheribsd/src/sys/dev/altera/jtag_uart/altera_jtag_uart.h#2 integrate
.. //depot/projects/ctsrd/cheribsd/src/sys/dev/altera/jtag_uart/altera_jtag_uart_cons.c#2 integrate
.. //depot/projects/ctsrd/cheribsd/src/sys/dev/altera/jtag_uart/altera_jtag_uart_tty.c#2 integrate
.. //depot/projects/ctsrd/cheribsd/src/sys/dev/terasic/de4led/terasic_de4led.c#2 integrate
.. //depot/projects/ctsrd/cheribsd/src/sys/mips/conf/BERI_DE4.hints#2 integrate
.. //depot/projects/ctsrd/cheribsd/src/sys/mips/conf/BERI_DE4_MDROOT#2 integrate
.. //depot/projects/ctsrd/cheribsd/src/sys/mips/conf/BERI_DE4_SDROOT#2 integrate
.. //depot/projects/ctsrd/cheribsd/src/sys/mips/conf/BERI_SIM_MDROOT#2 integrate
.. //depot/projects/ctsrd/cheribsd/src/sys/mips/mips/stack_machdep.c#2 integrate
.. //depot/projects/ctsrd/cheribsd/src/usr.sbin/isfctl/isfctl.c#2 integrate
Differences ...
==== //depot/projects/ctsrd/cheribsd/src/ctsrd-lib/libde4tc/Makefile#2 (text+ko) ====
@@ -5,12 +5,15 @@
LIB= de4tc
SHLIB_MAJOR= 1
-SRCS= de4tc.c
+SRCS= de4tc.c syscons-fonts.c
INCS= de4tc.h
+.PATH: ${.CURDIR}/../../usr.sbin/vidcontrol
+CFLAGS+=-I${.CURDIR}/../../usr.sbin/vidcontrol
+SRCS+= decode.c
+
CFLAGS+= -I${.CURDIR}/../libvuln_png/
-#LDADD+= -L../libvuln_png/ -lvuln_png -lz -lm
#WARNS?= 0
==== //depot/projects/ctsrd/cheribsd/src/ctsrd-lib/libde4tc/de4tc.c#2 (text+ko) ====
@@ -52,7 +52,7 @@
static int dispfd;
static int textfd;
static int fademode=0;
-static volatile u_int32_t *pfbp;
+volatile u_int32_t *pfbp;
static volatile u_int16_t *tfbp;
static volatile u_int32_t *mtlctrl;
@@ -62,7 +62,10 @@
// number of lines in the line pattern
static const int num_lines_pattern = 600;
+const int fb_height = 480;
+const int fb_width = 800;
+
/*****************************************************************************
* hack around endian issue
* TODO: replace with endian library call (but not present in Linux?)
@@ -208,6 +211,17 @@
void
+fb_fill_region(u_int32_t colour, int x, int y, int w, int h)
+{
+ int col, row;
+
+ for (row = 0; row < h; row++)
+ for (col = 0; col < w; col++)
+ pfbp[(y + row) * fb_width + (x + col)] = colour;
+}
+
+
+void
fb_post(u_int32_t *buf)
{
int addr;
@@ -217,6 +231,17 @@
void
+fb_post_region(u_int32_t *buf, int x, int y, int w, int h)
+{
+ int col, row;
+
+ for (row = 0; row < h; row++)
+ for (col = 0; col < w; col++)
+ pfbp[(y + row) * fb_width + (x + col)] = buf[row * w + col];
+}
+
+
+void
fb_blend(int blend_text_bg, int blend_text_fg, int blend_pixel, int wash __unused)
{
mtlctrl[0] =
==== //depot/projects/ctsrd/cheribsd/src/ctsrd-lib/libde4tc/de4tc.h#2 (text+ko) ====
@@ -1,5 +1,6 @@
/*-
* Copyright (c) 2012 Simon W. Moore
+ * Copyright (c) 2012 SRI International
* All rights reserved.
*
* This software was developed by SRI International and the University of
@@ -38,8 +39,8 @@
extern int touch_gesture;
extern int touch_count;
-const int fb_height = 480;
-const int fb_width = 800;
+extern const int fb_height;
+extern const int fb_width;
void multitouch_pole(void);
void multitouch_filter(void);
@@ -49,7 +50,9 @@
u_int32_t fb_colour(int r, int g, int b);
void fb_putpixel(int px, int py, int colour);
void fb_fill(int col);
+void fb_fill_region(u_int32_t colour, int x, int y, int w, int h);
void fb_post(u_int32_t *buf);
+void fb_post_region(u_int32_t *buf, int x, int y, int w, int h);
void fb_blend(int blend_text_bg, int blend_text_fg, int blend_pixel, int wash);
void fb_text_cursor(int x, int y);
void fb_fade2off(void);
@@ -58,4 +61,10 @@
void plot_line(int x1, int y1, int x2, int y2, unsigned int colour);
void read_png_file(const char* file_name, u_int32_t* imgbuf, int maxwidth, int maxheight);
+void fb_load_syscons_font(const char *type, const char *filename);
+int fb_get_font_height(void);
+int fb_get_font_width(void);
+void fb_render_text(const char *string, int expand, u_int32_t con, u_int32_t coff,
+ u_int32_t *buffer, int w, int h);
+
#endif /* !_DE4TC_H_ */
==== //depot/projects/ctsrd/cheribsd/src/ctsrd/Makefile#3 (text+ko) ====
@@ -1,7 +1,11 @@
.include <bsd.own.mk>
-SUBDIR= flashit \
+SUBDIR= browser \
+ cycle_led \
+ flashit \
+ minifile \
pictview \
+ showimage \
spinner
.include <bsd.arch.inc.mk>
==== //depot/projects/ctsrd/cheribsd/src/ctsrd/flashit/flashit.sh#2 (text+ko) ====
@@ -1,24 +1,26 @@
#!/bin/sh
+isf0_DEV=isf0
+isf0_OFFSET=0
+isf0_MAXLEN=0x02000000
+
+isf1_DEV=isf1
+isf1_OFFSET=0
+isf1_MAXLEN=0x02000000
+
fpga_DEV=isf0
fpga_OFFSET=0x00020000
-fpga_MAXLEN=0x00FE0000
+fpga_MAXLEN=0x00C00000
fpga_SKIP=0x20000
-# New kernel location on isf0
-kernel_DEV=isf0
-kernel_OFFSET=0x01000000
-kernel_MAXLEN=0x01000000
+fpga2_DEV=isf0
+fpga2_OFFSET=0x00C20000
+fpga2_MAXLEN=0x00C00000
+fpga2_SKIP=0x20000
-# Old kernel location on isf1
-kernel2_DEV=isf1
-kernel2_OFFSET=0x01000000
-kernel2_MAXLEN=0x01000000
-
-# Proposed root location
-root_DEV=isf1
-root_OFFSET=0x00000000
-root_MAXLEN=0x02000000
+kernel_DEV=isf1
+kernel_OFFSET=0x00000000
+kernel_MAXLEN=0x02000000
TARGETS="fpga:kernel:kernel2:root"
@@ -114,11 +116,17 @@
case "${source}" in
*.bz2)
+ if [ -z "${tmpdir}" ]; then
+ err 1 "Can't make a temporary directory, is /tmp writable?"
+ fi
binfile="${tmpdir}/${src_name%.bz2}"
echo "Extracting to ${binfile}"
bunzip2 -c "${source}" > "${binfile}"
;;
*.gz)
+ if [ -z "${tmpdir}" ]; then
+ err 1 "Can't make a temporary directory, is /tmp writable?"
+ fi
binfile="${tmpdir}/${src_name%.gz}"
echo "Extracting to ${binfile}"
gunzip -c "${source}" > "${binfile}"
==== //depot/projects/ctsrd/cheribsd/src/ctsrd/pictview/Makefile#2 (text+ko) ====
@@ -9,7 +9,7 @@
WARNS= 0
-LDADD+= -lde4tc -lvuln_png -lz -lm
+LDADD+= -lde4tc -lvuln_png -lz -lm -lutil
# Disable the stack protector, we want to be vulnerable
SSP_CFLAGS=
==== //depot/projects/ctsrd/cheribsd/src/ctsrd/pictview/pictview.c#3 (text+ko) ====
@@ -29,16 +29,22 @@
*/
#include <sys/types.h>
+#include <sys/ioctl.h>
#include <sys/stat.h>
+#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <syslog.h>
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <libutil.h>
+#include <poll.h>
#include <stdarg.h>
-#include <fcntl.h>
+#include <stdbool.h>
+#include <string.h>
+#include <termios.h>
#include <unistd.h>
-#include <errno.h>
-#include <err.h>
-#include <stdbool.h>
#include <de4tc.h>
@@ -48,8 +54,6 @@
u_int32_t *fb_buf;
-
-
void
pen_drawing_clear_screen(void)
{
@@ -140,6 +144,20 @@
read_png_file("/usr/share/images/keyboardC.png", keyboard_imgs[3], keyboard_width, keyboard_height);
}
+static void
+writeall(int fd, const char *buf, size_t len)
+{
+ int wlen = 0, n;
+
+ while (wlen != len) {
+ n = write(fd, buf + wlen, len - wlen);
+ if (n < 0) {
+ syslog(LOG_ALERT, "write failed: %s", strerror(errno));
+ err(1, "write");
+ }
+ wlen += n;
+ }
+}
void
keyboard_on(void)
@@ -152,6 +170,16 @@
int prev_keymode = -1;
int keyYpos = fb_height-keyboard_height;
+ const int poll_timeout = touch_timeout;
+ int wait_poll_timeout = poll_timeout;
+
+ static int pmaster;
+ static pid_t pid;
+ int pslave, n;
+ char *devpath, buf[1024];
+ ssize_t rlen;
+ struct pollfd pfd[1];
+
// extra mapping codes:
// ctrl key = \xff -> keymode=3
// num key = \xfe -> keymode=2
@@ -180,6 +208,28 @@
keymap[1][1][3] = '\xff';
keymap[2][1][3] = '\xff';
+ if (kbdfd < 0) {
+ /* XXX: need to handle the case of the shell exiting. */
+ if (openpty(&pmaster, &pslave, NULL, NULL, NULL) == -1)
+ err(1, "openpty");
+ pid = fork();
+ if (pid < 0)
+ err(1, "fork()");
+ else if (pid > 0) {
+ close(pslave);
+ kbdfd = pmaster;
+ } else {
+ close(pmaster);
+ if (login_tty(pslave) < 0) {
+ syslog(LOG_ALERT, "login_tty failed in child: %s", strerror(errno));
+ err(1, "tty_login");
+ }
+ execl("/bin/sh", "sh", NULL);
+ syslog(LOG_ALERT, "exec of /bin/sh failed: %s", strerror(errno));
+ err(1, "execl()");
+ }
+ }
+
fb_fade2off();
fb_fade2text(127);
do {
@@ -236,9 +286,7 @@
}
if(ic < 0x80) {
// printf("key = \"%c\" = 0x%02x\n", c, ic);
- /* XXX: should handle full buffers */
- if (write(kbdfd, &c, 1) == -1)
- err(1, "write");
+ writeall(kbdfd, &c, 1);
// cancel shift and ctrl modes after character sent
if((keymode==1) || (keymode==3))
keymode=0;
@@ -256,6 +304,43 @@
keyYpos -= fb_height; // put on screen
prev_keymode = -1; // redraw keyboard
}
+
+ if (kbdfd != 0) {
+ if (wait_poll_timeout > 0) {
+ wait_poll_timeout--;
+ continue;
+ }
+ wait_poll_timeout = poll_timeout;
+
+ /*
+ * If the child has exited, reset the state and return to the
+ * main screen.
+ */
+ if (wait4(pid, NULL, WNOHANG, NULL) != 0) {
+ kbdfd = -1;
+ close(pmaster);
+ break;
+ }
+
+ /* Check for output from the child and post it if needed */
+ pfd[0].fd = pmaster;
+ pfd[0].events = POLLIN;
+ n = poll(pfd, 1, 0);
+ if (n == 0)
+ continue;
+ if (n < 0) {
+ syslog(LOG_ALERT, "poll failed with %s", strerror(errno));
+ err(1, "poll");
+ }
+ if (pfd[0].revents & POLLIN) {
+ rlen = read(pfd[0].fd, buf, sizeof(buf));
+ if (rlen < 0) {
+ syslog(LOG_ALERT, "read failed: %s", strerror(errno));
+ err(1, "read");
+ } else if (rlen > 0)
+ writeall(0, buf, rlen);
+ }
+ }
} while(!((touch_count==2) && (touch_gesture==0x49)));
}
@@ -551,8 +636,7 @@
int
main(int argc, char *argv[])
{
- int ofd, pipefds[2];
- pid_t pid;
+ int tty;
char *devpath;
fb_buf = malloc(sizeof(*fb_buf) * fb_width * fb_height);
@@ -571,34 +655,19 @@
if (argc > 2)
errx(1, "usage: pictview [tty]");
if (argc == 2) {
- if (pipe(pipefds) == -1)
- err(1, "pipe()");
- pid = fork();
- if (pid < 0)
- return (pid);
- else if (pid > 0) {
- /* XXX: should probably wait a bit and see if the child fails quickly */
- kbdfd=pipefds[0];
- } else {
- if (dup2(pipefds[1], 0) == -1)
- err(1, "dup2(%d, 0)", pipefds[1]);
- if (argv[1][0] != '/')
- asprintf(&devpath, "/dev/%s", argv[1]);
- else
- devpath = argv[1];
- ofd = open(devpath, O_WRONLY);
- if (ofd < 0)
- err(1, "open(%s)", argv[1]);
- if (dup2(ofd, 1) == -1) {
- syslog(LOG_ALERT, "redir: dup2(%d, 1) failed with %d", ofd, errno);
- exit(1);
- }
- if (dup2(ofd, 2) == -1) {
- syslog(LOG_ALERT, "redir: dup2(%d, 2) failed with %d", ofd, errno);
- exit(1);
- }
- execl("/bin/sh", "sh", "-i", NULL);
- err(1, "execl()");
+ kbdfd = -1;
+ if (argv[1][0] != '/')
+ asprintf(&devpath, "/dev/%s", argv[1]);
+ else
+ devpath = argv[1];
+ if ((tty = open(devpath, O_RDWR)) < 0) {
+ syslog(LOG_ALERT, "open failed with %s", strerror(errno));
+ err(1, "open(%s)", devpath);
+ }
+
+ if (login_tty(tty) < 0) {
+ syslog(LOG_ALERT, "login_tty failed: %s", strerror(errno));
+ err(1, "login_tty()");
}
}
==== //depot/projects/ctsrd/cheribsd/src/ctsrd/spinner/spinner.c#2 (text+ko) ====
@@ -80,7 +80,7 @@
main(int argc, char *argv[])
{
int alpha, ch, i, ofd;
- pid_t pid;
+ pid_t pid = 0;
char *ep;
char imgpath[MAXPATHLEN];
u_int32_t *bottom, *top;
@@ -164,7 +164,8 @@
for (i = 0; i < NSPINNERS; i++) {
- poll_child(pid);
+ if (pid != 0)
+ poll_child(pid);
snprintf(imgpath, sizeof(imgpath),
"%s/spinner%02d.png", IMGDIR, i);
read_png_file(imgpath, spinners[i], fb_width, fb_height);
@@ -191,7 +192,8 @@
if (i >= NSPINNERS)
i = 0;
fb_post(spinners[i]);
- poll_child(pid);
+ if (pid != 0)
+ poll_child(pid);
}
fb_fade2off();
==== //depot/projects/ctsrd/cheribsd/src/etc/mtree/BSD.usr.dist#2 (text+ko) ====
@@ -322,6 +322,8 @@
fortune
..
..
+ images
+ ..
info
..
i18n
==== //depot/projects/ctsrd/cheribsd/src/etc/rc#2 (text+ko) ====
@@ -82,7 +82,11 @@
# Do a first pass to get everything up to $early_late_divider so that
# we can do a second pass that includes $local_startup directories
#
-files=`rcorder ${skip} /etc/rc.d/* 2>/dev/null`
+if [ -r /etc/rcorder.start ]; then
+ files=`read_fixed_rcorder /etc/rcorder.start`
+else
+ files=`rcorder ${skip} /etc/rc.d/* 2>/dev/null`
+fi
_rc_elem_done=' '
for _rc_elem in ${files}; do
@@ -104,7 +108,11 @@
*) find_local_scripts_new ;;
esac
-files=`rcorder ${skip} /etc/rc.d/* ${local_rc} 2>/dev/null`
+if [ -r /etc/rcorder.start ]; then
+ files=`read_fixed_rcorder /etc/rcorder.start`
+else
+ files=`rcorder ${skip} /etc/rc.d/* ${local_rc} 2>/dev/null`
+fi
for _rc_elem in ${files}; do
case "$_rc_elem_done" in
*" $_rc_elem "*) continue ;;
==== //depot/projects/ctsrd/cheribsd/src/etc/rc.subr#2 (text+ko) ====
@@ -1738,6 +1738,20 @@
esac
}
+read_fixed_rcorder()
+{
+ local _files _file
+
+ _files=""
+ while read _file; do
+ if [ -r ${_file} ]; then
+ _files="${_files} ${_file}"
+ fi
+ done < $1
+
+ echo ${_files}
+}
+
fi # [ -z "${_rc_subr_loaded}" ]
_rc_subr_loaded=:
==== //depot/projects/ctsrd/cheribsd/src/sys/conf/options.mips#4 (text+ko) ====
==== //depot/projects/ctsrd/cheribsd/src/sys/dev/altera/avgen/altera_avgen.c#2 (text+ko) ====
@@ -382,16 +382,18 @@
device_printf(dev, "couldn't map memory\n");
return (ENXIO);
}
- if (rman_get_size(sc->avg_res) % PAGE_SIZE != 0) {
- device_printf(dev,
- "memory region not even multiple of page size\n");
- error = ENXIO;
- goto error;
- }
- if (rman_get_start(sc->avg_res) % PAGE_SIZE != 0) {
- device_printf(dev, "memory region not page-aligned\n");
- error = ENXIO;
- goto error;
+ if (rman_get_size(sc->avg_res) >= PAGE_SIZE || str_mmapio != NULL) {
+ if (rman_get_size(sc->avg_res) % PAGE_SIZE != 0) {
+ device_printf(dev,
+ "memory region not even multiple of page size\n");
+ error = ENXIO;
+ goto error;
+ }
+ if (rman_get_start(sc->avg_res) % PAGE_SIZE != 0) {
+ device_printf(dev, "memory region not page-aligned\n");
+ error = ENXIO;
+ goto error;
+ }
}
/* Device node allocation. */
==== //depot/projects/ctsrd/cheribsd/src/sys/dev/altera/jtag_uart/altera_jtag_uart.h#2 (text+ko) ====
@@ -56,7 +56,8 @@
u_int ajus_flags;
struct mtx *ajus_lockp;
struct mtx ajus_lock;
- struct callout ajus_callout;
+ struct callout ajus_io_callout;
+ struct callout ajus_ac_callout;
/*
* One-character buffer required because it's not possible to peek at
@@ -66,6 +67,10 @@
int *ajus_buffer_validp;
uint8_t ajus_buffer_data;
uint8_t *ajus_buffer_datap;
+ int ajus_jtag_present;
+ int *ajus_jtag_presentp;
+ u_int ajus_jtag_missed;
+ u_int *ajus_jtag_missedp;
};
#define AJU_TTYNAME "ttyu"
@@ -126,6 +131,8 @@
extern struct mtx aju_cons_lock;
extern char aju_cons_buffer_data;
extern int aju_cons_buffer_valid;
+extern int aju_cons_jtag_present;
+extern u_int aju_cons_jtag_missed;
/*
* Base physical address of the JTAG UART in BERI.
==== //depot/projects/ctsrd/cheribsd/src/sys/dev/altera/jtag_uart/altera_jtag_uart_cons.c#2 (text+ko) ====
@@ -55,6 +55,8 @@
*/
char aju_cons_buffer_data;
int aju_cons_buffer_valid;
+int aju_cons_jtag_present;
+u_int aju_cons_jtag_missed;
struct mtx aju_cons_lock;
/*
@@ -69,6 +71,16 @@
static cn_ungrab_t aju_cnungrab;
/*
+ * JTAG sets the ALTERA_JTAG_UART_CONTROL_AC bit whenever it accesses the
+ * FIFO. This allows us to (sort of) tell when JTAG is present, so that we
+ * can adopt lossy, rather than blocking, behaviour when JTAG isn't there.
+ * When it is present, we do full flow control. This delay is how long we
+ * wait to see if JTAG has really disappeared when finding a full buffer and
+ * no AC bit set.
+ */
+#define ALTERA_JTAG_UART_AC_POLL_DELAY 10000
+
+/*
* I/O routines lifted from Deimos. This is not only MIPS-specific, but also
* BERI-specific, as we're hard coding the the address at which we expect to
* find the Altera JTAG UART and using it unconditionally. We use these
@@ -154,17 +166,17 @@
ALTERA_JTAG_UART_CONTROL_OFF)));
}
-/*
- * Slightly higher-level routines aware of buffering and flow control.
- */
-static int
-aju_cons_writable(void)
+static inline void
+aju_cons_control_write(uint32_t v)
{
- return ((aju_cons_control_read() &
- ALTERA_JTAG_UART_CONTROL_WSPACE) != 0);
+ mips_iowrite_uint32le(mips_phys_to_uncached(BERI_UART_BASE +
+ ALTERA_JTAG_UART_CONTROL_OFF), v);
}
+/*
+ * Slightly higher-level routines aware of buffering and flow control.
+ */
static int
aju_cons_readable(void)
{
@@ -186,10 +198,46 @@
static void
aju_cons_write(char ch)
{
+ uint32_t v;
AJU_CONSOLE_LOCK_ASSERT();
- while (!aju_cons_writable());
+ /*
+ * The flow control logic here is somewhat subtle: we want to wait for
+ * write buffer space only while JTAG is present. However, we can't
+ * directly ask if JTAG is present -- just whether it's been seen
+ * since we last cleared the ALTERA_JTAG_UART_CONTROL_AC bit. As
+ * such, implement a polling loop in which we both wait for space and
+ * try to decide whether JTAG has disappeared on us. We will have to
+ * wait one complete polling delay to detect that JTAG has gone away,
+ * but otherwise shouldn't wait any further once it has gone. And we
+ * had to wait for buffer space anyway, if it was there.
+ *
+ * If JTAG is spotted, reset the TTY-layer miss counter so console-
+ * layer clearing of the bit doesn't trigger a TTY-layer
+ * disconnection.
+ *
+ * XXXRW: The polling delay may require tuning.
+ */
+ v = aju_cons_control_read();
+ if (v & ALTERA_JTAG_UART_CONTROL_AC) {
+ aju_cons_jtag_present = 1;
+ aju_cons_jtag_missed = 0;
+ v &= ~ALTERA_JTAG_UART_CONTROL_AC;
+ aju_cons_control_write(v);
+ }
+ while ((v & ALTERA_JTAG_UART_CONTROL_WSPACE) == 0) {
+ if (!aju_cons_jtag_present)
+ return;
+ DELAY(ALTERA_JTAG_UART_AC_POLL_DELAY);
+ v = aju_cons_control_read();
+ if (v & ALTERA_JTAG_UART_CONTROL_AC) {
+ aju_cons_jtag_present = 1;
+ v &= ~ALTERA_JTAG_UART_CONTROL_AC;
+ aju_cons_control_write(v);
+ } else
+ aju_cons_jtag_present = 0;
+ }
aju_cons_data_write(ch);
}
@@ -218,8 +266,15 @@
static void
aju_cninit(struct consdev *cp)
{
+ uint32_t v;
AJU_CONSOLE_LOCK_INIT();
+
+ AJU_CONSOLE_LOCK();
+ v = aju_cons_control_read();
+ v &= ~ALTERA_JTAG_UART_CONTROL_AC;
+ aju_cons_control_write(v);
+ AJU_CONSOLE_UNLOCK();
}
static void
==== //depot/projects/ctsrd/cheribsd/src/sys/dev/altera/jtag_uart/altera_jtag_uart_tty.c#2 (text+ko) ====
@@ -55,7 +55,8 @@
static struct altera_jtag_uart_softc *aju_cons_sc;
static tsw_outwakeup_t aju_outwakeup;
-static void aju_timeout(void *);
+static void aju_ac_callout(void *);
+static void aju_io_callout(void *);
static struct ttydevsw aju_ttydevsw = {
.tsw_flags = TF_NOPREFIX,
@@ -63,9 +64,16 @@
};
/*
- * Poll for new input every (aju_pollinterval) ticks.
+ * When polling for the AC bit, the number of times we have to not see it
+ * before assuming JTAG has disappeared on us. By default, one second.
+ */
+#define AJU_JTAG_MAXMISS 5
+
+/*
+ * Polling intervals for input/output and JTAG connection events.
*/
-static u_int aju_pollinterval = 1;
+#define AJU_IO_POLLINTERVAL (hz/100)
+#define AJU_AC_POLLINTERVAL (hz/5)
/*
* Low-level read and write register routines; the Altera UART is little
@@ -232,6 +240,7 @@
static void
aju_handle_output(struct altera_jtag_uart_softc *sc, struct tty *tp)
{
+ uint32_t v;
uint8_t ch;
tty_lock_assert(tp, MA_OWNED);
@@ -240,14 +249,31 @@
AJU_UNLOCK(sc);
while (ttydisc_getc_poll(tp) != 0) {
AJU_LOCK(sc);
- if (aju_writable(sc)) {
+ v = aju_control_read(sc);
+ if ((v & ALTERA_JTAG_UART_CONTROL_WSPACE) != 0) {
AJU_UNLOCK(sc);
if (ttydisc_getc(tp, &ch, sizeof(ch)) != sizeof(ch))
panic("%s: ttydisc_getc", __func__);
AJU_LOCK(sc);
aju_data_write(sc, ch);
} else {
- aju_intr_writable_enable(sc);
+ /*
+ * If JTAG is not present, then we will drop this
+ * character instead of perhaps scheduling an
+ * interrupt to let us know when there is buffer
+ * space. Otherwise we might get a write interrupt
+ * later even though we aren't interested in sending
+ * anymore. Loop to drain TTY-layer buffer.
+ */
+ if (*sc->ajus_jtag_presentp == 0) {
+ if (ttydisc_getc(tp, &ch, sizeof(ch)) !=
+ sizeof(ch))
+ panic("%s: ttydisc_getc 2", __func__);
+ AJU_UNLOCK(sc);
+ continue;
+ }
+ if (sc->ajus_irq_res != NULL)
+ aju_intr_writable_enable(sc);
return;
}
AJU_UNLOCK(sc);
@@ -269,7 +295,7 @@
}
static void
-aju_timeout(void *arg)
+aju_io_callout(void *arg)
{
struct altera_jtag_uart_softc *sc = arg;
struct tty *tp = sc->ajus_ttyp;
@@ -293,7 +319,39 @@
* pending in the output buffer, or have we recently had input, but we
* don't.
*/
- callout_reset(&sc->ajus_callout, aju_pollinterval, aju_timeout, sc);
+ callout_reset(&sc->ajus_io_callout, AJU_IO_POLLINTERVAL,
+ aju_io_callout, sc);
+ AJU_UNLOCK(sc);
+ tty_unlock(tp);
+}
+
+static void
+aju_ac_callout(void *arg)
+{
+ struct altera_jtag_uart_softc *sc = arg;
+ struct tty *tp = sc->ajus_ttyp;
+ uint32_t v;
+
+ tty_lock(tp);
+ AJU_LOCK(sc);
+ v = aju_control_read(sc);
+ if (v & ALTERA_JTAG_UART_CONTROL_AC) {
+ v &= ~ALTERA_JTAG_UART_CONTROL_AC;
+ aju_control_write(sc, v);
+ if (*sc->ajus_jtag_presentp == 0) {
+ *sc->ajus_jtag_missedp = 0;
+ *sc->ajus_jtag_presentp = 1;
+ aju_handle_output(sc, tp);
+ }
+ } else if (*sc->ajus_jtag_presentp != 0) {
+ (*sc->ajus_jtag_missedp)++;
+ if (*sc->ajus_jtag_missedp >= AJU_JTAG_MAXMISS) {
+ *sc->ajus_jtag_presentp = 0;
+ aju_handle_output(sc, tp);
+ }
+ }
+ callout_reset(&sc->ajus_ac_callout, AJU_AC_POLLINTERVAL,
+ aju_ac_callout, sc);
AJU_UNLOCK(sc);
tty_unlock(tp);
}
@@ -333,11 +391,15 @@
sc->ajus_lockp = &aju_cons_lock;
sc->ajus_buffer_validp = &aju_cons_buffer_valid;
sc->ajus_buffer_datap = &aju_cons_buffer_data;
+ sc->ajus_jtag_presentp = &aju_cons_jtag_present;
+ sc->ajus_jtag_missedp = &aju_cons_jtag_missed;
sc->ajus_flags |= ALTERA_JTAG_UART_FLAG_CONSOLE;
} else {
sc->ajus_lockp = &sc->ajus_lock;
sc->ajus_buffer_validp = &sc->ajus_buffer_valid;
sc->ajus_buffer_datap = &sc->ajus_buffer_data;
+ sc->ajus_jtag_presentp = &sc->ajus_jtag_present;
+ sc->ajus_jtag_missedp = &sc->ajus_jtag_missed;
}
/*
@@ -376,10 +438,13 @@
aju_intr_readable_enable(sc);
AJU_UNLOCK(sc);
} else {
- callout_init(&sc->ajus_callout, CALLOUT_MPSAFE);
- callout_reset(&sc->ajus_callout, aju_pollinterval,
- aju_timeout, sc);
+ callout_init(&sc->ajus_io_callout, CALLOUT_MPSAFE);
+ callout_reset(&sc->ajus_io_callout, AJU_IO_POLLINTERVAL,
+ aju_io_callout, sc);
}
+ callout_init(&sc->ajus_ac_callout, CALLOUT_MPSAFE);
+ callout_reset(&sc->ajus_ac_callout, AJU_AC_POLLINTERVAL,
+ aju_ac_callout, sc);
return (0);
}
@@ -399,7 +464,8 @@
bus_teardown_intr(sc->ajus_dev, sc->ajus_irq_res,
sc->ajus_irq_cookie);
} else
- callout_drain(&sc->ajus_callout);
+ callout_drain(&sc->ajus_io_callout);
+ callout_drain(&sc->ajus_ac_callout);
if (sc->ajus_flags & ALTERA_JTAG_UART_FLAG_CONSOLE)
aju_cons_sc = NULL;
tty_lock(tp);
==== //depot/projects/ctsrd/cheribsd/src/sys/dev/terasic/de4led/terasic_de4led.c#2 (text+ko) ====
@@ -63,56 +63,56 @@
}
static void
-led_1(void *arg, int onoff)
+led_0(void *arg, int onoff)
{
led_update(arg, 0, onoff);
}
static void
-led_2(void *arg, int onoff)
+led_1(void *arg, int onoff)
{
led_update(arg, 1, onoff);
}
static void
-led_3(void *arg, int onoff)
+led_2(void *arg, int onoff)
{
led_update(arg, 2, onoff);
}
static void
-led_4(void *arg, int onoff)
+led_3(void *arg, int onoff)
{
led_update(arg, 3, onoff);
}
static void
-led_5(void *arg, int onoff)
+led_4(void *arg, int onoff)
{
led_update(arg, 4, onoff);
}
static void
-led_6(void *arg, int onoff)
+led_5(void *arg, int onoff)
{
led_update(arg, 5, onoff);
}
static void
-led_7(void *arg, int onoff)
+led_6(void *arg, int onoff)
{
led_update(arg, 6, onoff);
}
static void
-led_8(void *arg, int onoff)
+led_7(void *arg, int onoff)
{
led_update(arg, 7, onoff);
>>> TRUNCATED FOR MAIL (1000 lines) <<<
More information about the p4-projects
mailing list