PERFORCE change 205675 for review
Robert Watson
rwatson at FreeBSD.org
Sat Feb 4 11:22:33 UTC 2012
http://p4web.freebsd.org/@@205675?ac=10
Change 205675 by rwatson at 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);
More information about the p4-projects
mailing list