summaryrefslogtreecommitdiffstats
path: root/sys/arm/at91
diff options
context:
space:
mode:
authorcognet <cognet@FreeBSD.org>2006-05-13 23:41:16 +0000
committercognet <cognet@FreeBSD.org>2006-05-13 23:41:16 +0000
commit2e58b619628d5c8e5ecbe445140aade714d9c2f3 (patch)
treead2cd12970015c6c1b03b6f9f087319ea6f2e34f /sys/arm/at91
parent456f2593a536e19a6666580ad6ede280d3e7459e (diff)
downloadFreeBSD-src-2e58b619628d5c8e5ecbe445140aade714d9c2f3.zip
FreeBSD-src-2e58b619628d5c8e5ecbe445140aade714d9c2f3.tar.gz
Resurrect Skyeye support :
Add a new option, SKYEYE_WORKAROUNDS, which as the name suggests adds workarounds for things skyeye doesn't simulate. Specifically : - Use USART0 instead of DBGU as the console, make it not use DMA, and manually provoke an interrupt when we're done in the transmit function. - Skyeye maintains an internal counter for clock, but apparently there's no way to access it, so hack the timecounter code to return a value which is increased at every clock interrupts. This is gross, but I didn't find a better way to implement timecounters without hacking Skyeye to get the counter value. - Force the write-back of PTEs once we're done writing them, even if they are supposed to be write-through. I don't know why I have to do that.
Diffstat (limited to 'sys/arm/at91')
-rw-r--r--sys/arm/at91/at91.c8
-rw-r--r--sys/arm/at91/at91_st.c18
-rw-r--r--sys/arm/at91/if_ate.c2
-rw-r--r--sys/arm/at91/uart_bus_at91usart.c12
-rw-r--r--sys/arm/at91/uart_cpu_at91rm9200usart.c10
-rw-r--r--sys/arm/at91/uart_dev_at91usart.c24
6 files changed, 46 insertions, 28 deletions
diff --git a/sys/arm/at91/at91.c b/sys/arm/at91/at91.c
index 928faa9..8f9177b 100644
--- a/sys/arm/at91/at91.c
+++ b/sys/arm/at91/at91.c
@@ -314,6 +314,7 @@ struct cpu_devs at91rm9200_devs[] =
AT91RM92_BASE + AT91RM92_EMAC_BASE, AT91RM92_EMAC_SIZE,
AT91RM92_IRQ_EMAC
},
+#ifndef SKYEYE_WORKAROUNDS
{
"uart", 0,
AT91RM92_BASE + AT91RM92_DBGU_BASE, AT91RM92_DBGU_SIZE,
@@ -339,6 +340,13 @@ struct cpu_devs at91rm9200_devs[] =
AT91RM92_BASE + AT91RM92_USART3_BASE, AT91RM92_USART_SIZE,
AT91RM92_IRQ_USART3
},
+#else
+ {
+ "uart", 0,
+ AT91RM92_BASE + AT91RM92_USART0_BASE, AT91RM92_USART_SIZE,
+ AT91RM92_IRQ_USART0
+ },
+#endif
{
"at91_ssc", 0,
AT91RM92_BASE + AT91RM92_SSC0_BASE, AT91RM92_SSC_SIZE,
diff --git a/sys/arm/at91/at91_st.c b/sys/arm/at91/at91_st.c
index 1960e61..10cccc3 100644
--- a/sys/arm/at91/at91_st.c
+++ b/sys/arm/at91/at91_st.c
@@ -72,7 +72,11 @@ static unsigned at91st_get_timecount(struct timecounter *tc);
static struct timecounter at91st_timecounter = {
at91st_get_timecount, /* get_timecount */
NULL, /* no poll_pps */
+#ifdef SKYEYE_WORKAROUNDS
+ 0xffffffffu, /* counter_mask */
+#else
0xfffffu, /* counter_mask */
+#endif
32768, /* frequency */
"AT91RM9200 timer", /* name */
0 /* quality */
@@ -122,10 +126,18 @@ static devclass_t at91st_devclass;
DRIVER_MODULE(at91_st, atmelarm, at91st_driver, at91st_devclass, 0, 0);
+#ifdef SKYEYE_WORKAROUNDS
+static unsigned long tot_count = 0;
+#endif
+
static unsigned
at91st_get_timecount(struct timecounter *tc)
{
+#ifdef SKYEYE_WORKAROUNDS
+ return (tot_count);
+#else
return (st_crtr());
+#endif
}
static void
@@ -134,8 +146,12 @@ clock_intr(void *arg)
struct trapframe *fp = arg;
/* The interrupt is shared, so we have to make sure it's for us. */
- if (RD4(ST_SR) & ST_SR_PITS)
+ if (RD4(ST_SR) & ST_SR_PITS) {
+#ifdef SKYEYE_WORKAROUNDS
+ tot_count += 32768 / hz;
+#endif
hardclock(TRAPF_USERMODE(fp), TRAPF_PC(fp));
+ }
}
void
diff --git a/sys/arm/at91/if_ate.c b/sys/arm/at91/if_ate.c
index 651d2b1..b33d9ac 100644
--- a/sys/arm/at91/if_ate.c
+++ b/sys/arm/at91/if_ate.c
@@ -71,7 +71,7 @@ __FBSDID("$FreeBSD$");
#include "miibus_if.h"
-#define ATE_MAX_TX_BUFFERS 2 /* We have ping-pong tx buffers */
+#define ATE_MAX_TX_BUFFERS 64 /* We have ping-pong tx buffers */
#define ATE_MAX_RX_BUFFERS 64
struct ate_softc
diff --git a/sys/arm/at91/uart_bus_at91usart.c b/sys/arm/at91/uart_bus_at91usart.c
index c9ab85c..af1773b 100644
--- a/sys/arm/at91/uart_bus_at91usart.c
+++ b/sys/arm/at91/uart_bus_at91usart.c
@@ -76,22 +76,20 @@ usart_at91rm92_probe(device_t dev)
switch (device_get_unit(dev))
{
case 0:
+#ifdef SKYEYE_WORKAROUNDS
+ device_set_desc(dev, "USART0");
+#else
device_set_desc(dev, "DBGU");
-#ifndef USART0_CONSOLE
+#endif
/*
* Setting sc_sysdev makes this device a 'system device' and
* indirectly makes it the system console.
*/
sc->sc_sysdev = SLIST_FIRST(&uart_sysdevs);
bcopy(&sc->sc_sysdev->bas, &sc->sc_bas, sizeof(sc->sc_bas));
-#endif
break;
case 1:
device_set_desc(dev, "USART0");
-#ifdef USART0_CONSOLE
- sc->sc_sysdev = SLIST_FIRST(&uart_sysdevs);
- bcopy(&sc->sc_sysdev->bas, &sc->sc_bas, sizeof(sc->sc_bas));
-#endif
break;
case 2:
device_set_desc(dev, "USART1");
@@ -104,7 +102,7 @@ usart_at91rm92_probe(device_t dev)
break;
}
sc->sc_class = &at91_usart_class;
- return (uart_bus_probe(dev, 0, 0, 0, 0));
+ return (uart_bus_probe(dev, 0, 0, 0, device_get_unit(dev)));
}
diff --git a/sys/arm/at91/uart_cpu_at91rm9200usart.c b/sys/arm/at91/uart_cpu_at91rm9200usart.c
index 2af5e2e..75a053d 100644
--- a/sys/arm/at91/uart_cpu_at91rm9200usart.c
+++ b/sys/arm/at91/uart_cpu_at91rm9200usart.c
@@ -62,13 +62,11 @@ uart_cpu_getdev(int devtype, struct uart_devinfo *di)
* XXX: Not pretty, but will work because we map VA == PA early
* for the last 1MB of memory.
*/
-#ifdef USART0_CONSOLE
+#ifdef SKYEYE_WORKAROUNDS
di->bas.bsh = AT91RM92_BASE + AT91RM92_USART0_BASE;
- di->bas.chan = 1;
di->baudrate = 38400;
#else
di->bas.bsh = AT91RM92_BASE + AT91RM92_SYS_BASE + DBGU;
- di->bas.chan = 0;
di->baudrate = 115200;
#endif
di->bas.regshft = 0;
@@ -76,12 +74,10 @@ uart_cpu_getdev(int devtype, struct uart_devinfo *di)
di->databits = 8;
di->stopbits = 1;
di->parity = UART_PARITY_NONE;
+ uart_bus_space_io = &at91_bs_tag;
+ uart_bus_space_mem = NULL;
/* Check the environment for overrides */
if (uart_getenv(devtype, di) == 0)
return (0);
-
- uart_bus_space_io = &at91_bs_tag;
- uart_bus_space_mem = NULL;
-
return (0);
}
diff --git a/sys/arm/at91/uart_dev_at91usart.c b/sys/arm/at91/uart_dev_at91usart.c
index 43905b2..fc304cc9 100644
--- a/sys/arm/at91/uart_dev_at91usart.c
+++ b/sys/arm/at91/uart_dev_at91usart.c
@@ -1,6 +1,6 @@
/*-
* Copyright (c) 2005 M. Warner Losh
- * Copyright (c) 2005 cognet
+ * Copyright (c) 2005 Olivier Houchard
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -322,6 +322,7 @@ errout:;
return (err);
}
+#ifndef SKYEYE_WORKAROUNDS
static void
at91_getaddr(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
{
@@ -329,22 +330,28 @@ at91_getaddr(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
return;
*(bus_addr_t *)arg = segs[0].ds_addr;
}
+#endif
static int
at91_usart_bus_transmit(struct uart_softc *sc)
{
+#ifndef SKYEYE_WORKAROUNDS
bus_addr_t addr;
+#endif
struct at91_usart_softc *atsc;
atsc = (struct at91_usart_softc *)sc;
+#ifndef SKYEYE_WORKAROUNDS
if (bus_dmamap_load(atsc->dmatag, atsc->tx_map, sc->sc_txbuf,
sc->sc_txdatasz, at91_getaddr, &addr, 0) != 0)
return (EAGAIN);
bus_dmamap_sync(atsc->dmatag, atsc->tx_map, BUS_DMASYNC_PREWRITE);
+#endif
uart_lock(sc->sc_hwmtx);
sc->sc_txbusy = 1;
+#ifndef SKYEYE_WORKAROUNDS
/*
* Setup the PDC to transfer the data and interrupt us when it
* is done. We've already requested the interrupt.
@@ -353,7 +360,9 @@ at91_usart_bus_transmit(struct uart_softc *sc)
WR4(&sc->sc_bas, PDC_TCR, sc->sc_txdatasz);
WR4(&sc->sc_bas, PDC_PTCR, PDC_PTCR_TXTEN);
uart_unlock(sc->sc_hwmtx);
-#ifdef USART0_CONSOLE
+#else
+ for (int i = 0; i < sc->sc_txdatasz; i++)
+ at91_usart_putc(&sc->sc_bas, sc->sc_txbuf[i]);
/*
* XXX: Gross hack : Skyeye doesn't raise an interrupt once the
* transfer is done, so simulate it.
@@ -416,16 +425,7 @@ at91_usart_bus_ipend(struct uart_softc *sc)
int ipend = 0;
struct at91_usart_softc *atsc;
- atsc = (struct at91_usart_softc *)sc;
-#ifdef USART0_CONSOLE
- /*
- * XXX: We have to cheat for skyeye, as it will return 0xff for all
- * the devices it doesn't emulate.
- */
- if (sc->sc_bas.chan != 1)
- return (0);
-#endif
-
+ atsc = (struct at91_usart_softc *)sc;
if (csr & USART_CSR_ENDTX) {
bus_dmamap_sync(atsc->dmatag, atsc->tx_map,
BUS_DMASYNC_POSTWRITE);
OpenPOWER on IntegriCloud