Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 4 Feb 2012 11:22:32 GMT
From:      Robert Watson <rwatson@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 205675 for review
Message-ID:  <201202041122.q14BMWRp044633@skunkworks.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://p4web.freebsd.org/@@205675?ac=10

Change 205675 by rwatson@rwatson_svr_ctsrd_mipsbuild on 2012/02/04 11:22:06

	Take a first cut at adapting the Deimos Altera JTAG UART for use in
	FreeBSD.  It still relies on direct reads/writes to the xkphys space
	rather than going through appropriate bus routines, but now
	interfaces with the FreeBSD low-level console driver interface.

Affected files ...

.. //depot/projects/ctsrd/beribsd/src/sys/mips/beri/files.beri#3 edit
.. //depot/projects/ctsrd/beribsd/src/sys/mips/beri/uart_altera.c#2 edit

Differences ...

==== //depot/projects/ctsrd/beribsd/src/sys/mips/beri/files.beri#3 (text+ko) ====

@@ -1,4 +1,5 @@
 # $FreeBSD$
 mips/beri/beri_machdep.c		standard
+mips/beri/uart_altera.c			standard
 mips/mips/intr_machdep.c		standard
 mips/mips/tick.c			standard

==== //depot/projects/ctsrd/beribsd/src/sys/mips/beri/uart_altera.c#2 (text+ko) ====

@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2011 Robert N. M. Watson
+ * Copyright (c) 2011-2012 Robert N. M. Watson
  * All rights reserved.
  *
  * This software was developed by SRI International and the University of
@@ -28,19 +28,88 @@
  * SUCH DAMAGE.
  */
 
-#include "include/cheri.h"
-#include "include/mips.h"
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/cons.h>
+#include <sys/endian.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+
+static cn_probe_t	aj_uart_cnprobe;
+static cn_init_t	aj_uart_cninit;
+static cn_term_t	aj_uart_cnterm;
+static cn_getc_t	aj_uart_cngetc;
+static cn_putc_t	aj_uart_cnputc;
+static cn_grab_t	aj_uart_cngrab;
+static cn_ungrab_t	aj_uart_cnungrab;
+
+/*
+ * I/O routines lifted from Deimos.
+ *
+ * XXXRW: Should be using FreeBSD's bus routines here.
+ */
+#define	MIPS_XKPHYS_UNCACHED_BASE	0x9000000000000000
+
+typedef	uint64_t	paddr_t;
+typedef	uint64_t	vaddr_t;
+
+static inline vaddr_t
+mips_phys_to_uncached(paddr_t phys)            
+{
+
+	return (phys | MIPS_XKPHYS_UNCACHED_BASE);
+}
+
+static inline uint32_t
+mips_ioread_uint32(vaddr_t vaddr)
+{
+	uint32_t v;
+
+	__asm__ __volatile__ ("lw %0, 0(%1)" : "=r" (v) : "r" (vaddr));
+	return (v);
+}
+
+static inline void
+mips_iowrite_uint32(vaddr_t vaddr, uint32_t v)
+{
+
+	__asm__ __volatile__ ("sw %0, 0(%1)" : : "r" (v), "r" (vaddr));
+}
+
+/*
+ * Little-endian versions of 32-bit I/O routines.
+ */
+static inline uint32_t
+mips_ioread_uint32le(vaddr_t vaddr)
+{
+
+	return (le32toh(mips_ioread_uint32(vaddr)));
+}
+
+static inline void
+mips_iowrite_uint32le(vaddr_t vaddr, uint32_t v)
+{
+
+	mips_iowrite_uint32(vaddr, htole32(v));
+}
 
-#include "dev/uart/uart.h"
+/*
+ * Base physical address of the JTAG UART in BERI.
+ *
+ * XXXRW: Should be set using FDT and/or device.hints.
+ */
+#define	BERI_UART_BASE		0x7f000000	/* JTAG UART */
 
 /*-
- * Routines for interacting with the CHERI console UART.  Programming details
- * from the June 2011 "Embedded Peripherals User Guide" by Altera
+ * Routines for interacting with the BERI console JTAG UART.  Programming
+ * details from the June 2011 "Embedded Peripherals User Guide" by Altera
  * Corporation, tables 6-2 (JTAG UART Core Register Map), 6-3 (Data Register
  * Bits), and 6-4 (Control Register Bits).
  *
  * Offsets of data and control registers relative to the base.  Altera
- * conventions are maintained in CHERI.
+ * conventions are maintained in BERI.
  */
 #define	ALTERA_JTAG_UART_DATA_OFF	0x00000000
 #define	ALTERA_JTAG_UART_CONTROL_OFF	0x00000004
@@ -92,52 +161,56 @@
  * endian, so we byte swap 32-bit reads and writes.
  */
 static inline uint32_t
-uart_data_read(void)
+aj_uart_data_read(void)
 {
 
-	return (mips_ioread_uint32le(mips_phys_to_uncached(CHERI_UART_BASE +
+	return (mips_ioread_uint32le(mips_phys_to_uncached(BERI_UART_BASE +
 	    ALTERA_JTAG_UART_DATA_OFF)));
 }
 
 static inline void
-uart_data_write(uint32_t v)
+aj_uart_data_write(uint32_t v)
 {
 
-	mips_iowrite_uint32le(mips_phys_to_uncached(CHERI_UART_BASE +
+	mips_iowrite_uint32le(mips_phys_to_uncached(BERI_UART_BASE +
 	    ALTERA_JTAG_UART_DATA_OFF), v);
 }
 
 static inline uint32_t
-uart_control_read(void)
+aj_uart_control_read(void)
 {
 
-	return (mips_ioread_uint32le(mips_phys_to_uncached(CHERI_UART_BASE +
+	return (mips_ioread_uint32le(mips_phys_to_uncached(BERI_UART_BASE +
 	    ALTERA_JTAG_UART_CONTROL_OFF)));
 }
 
 static inline void
-uart_control_write(uint32_t v)
+aj_uart_control_write(uint32_t v)
 {
 
-	mips_iowrite_uint32le(mips_phys_to_uncached(CHERI_UART_BASE +
+	mips_iowrite_uint32le(mips_phys_to_uncached(BERI_UART_BASE +
 	    ALTERA_JTAG_UART_DATA_OFF), v);
 }
 
-int
-uart_writable(void)
+/*
+ * Slightly higher-level routines aware of buffering and flow control.
+ */
+static int
+aj_uart_writable(void)
 {
 
-	return ((uart_control_read() & ALTERA_JTAG_UART_CONTROL_WSPACE) != 0);
+	return ((aj_uart_control_read() &
+	    ALTERA_JTAG_UART_CONTROL_WSPACE) != 0);
 }
 
-int
-uart_readable(void)
+static int
+aj_uart_readable(void)
 {
 	uint32_t v;
 
 	if (buffer_valid)
 		return (1);
-	v = uart_data_read();
+	v = aj_uart_data_read();
 	if ((v & ALTERA_JTAG_UART_DATA_RVALID) != 0) {
 		buffer_valid = 1;
 		buffer_data = (v & ALTERA_JTAG_UART_DATA_DATA);
@@ -145,25 +218,70 @@
 	return (0);
 }
 
-char
-uart_read(void)
+static void
+aj_uart_write(char ch)
+{
+
+	while (!aj_uart_writable());
+	aj_uart_data_write(ch);
+}
+
+static char
+aj_uart_read(void)
 {
 
-	while (!uart_readable());
+	while (!aj_uart_readable());
 	buffer_valid = 0;
 	return (buffer_data);
 }
 
-void
-uart_write(char ch)
+/*
+ * Implementation of a FreeBSD low-level, polled console driver.
+ */
+static void
+aj_uart_cnprobe(struct consdev *cp)
+{
+
+	sprintf(cp->cn_name, "aj_uart");
+	cp->cn_pri = CN_NORMAL;
+}
+
+static void
+aj_uart_cninit(struct consdev *cp)
+{
+
+}
+
+static void
+aj_uart_cnterm(struct consdev *cp)
+{
+
+}
+
+static int
+aj_uart_cngetc(struct consdev *cp)
+{
+
+	return (aj_uart_read());
+}
+
+static void
+aj_uart_cnputc(struct consdev *cp, int c)
+{
+
+	aj_uart_write(c);
+}
+
+static void
+aj_uart_cngrab(struct consdev *cp)
 {
 
-	uart_data_write(ch);
 }
 
-void
-uart_init(void)
+static void
+aj_uart_cnungrab(struct consdev *cp)
 {
 
-	/* Nothing required. */
 }
+
+CONSOLE_DRIVER(aj_uart);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201202041122.q14BMWRp044633>