mirror of
https://git.FreeBSD.org/src.git
synced 2025-01-17 15:27:36 +00:00
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.
This commit is contained in:
parent
9fd9594daf
commit
d5d776c16b
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=158531
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)));
|
||||
}
|
||||
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -33,7 +33,6 @@ makeoptions CONF_CFLAGS=-mcpu=arm9
|
||||
options DDB
|
||||
options KDB
|
||||
|
||||
options USART0_CONSOLE
|
||||
|
||||
options SCHED_4BSD #4BSD scheduler
|
||||
options INET #InterNETworking
|
||||
@ -43,6 +42,7 @@ options SOFTUPDATES #Enable FFS soft updates support
|
||||
options UFS_ACL #Support for access control lists
|
||||
options UFS_DIRHASH #Improve performance on big directories
|
||||
options MD_ROOT #MD is a potential root device
|
||||
options MD_ROOT_SIZE=4096
|
||||
options ROOTDEVNAME=\"ufs:md0\"
|
||||
options NFSCLIENT #Network Filesystem Client
|
||||
options NFSSERVER #Network Filesystem Server
|
||||
@ -83,6 +83,7 @@ device uart
|
||||
|
||||
device mem # Memory and kernel memory devices
|
||||
device md
|
||||
options SKYEYE_WORKAROUNDS
|
||||
options ARM32_NEW_VM_LAYOUT
|
||||
# Floppy drives
|
||||
|
||||
|
@ -332,12 +332,17 @@ extern int pmap_needs_pte_sync;
|
||||
|
||||
#endif /* ARM_NMMUS > 1 */
|
||||
|
||||
#ifdef SKYEYE_WORKAROUNDS
|
||||
#define PMAP_NEEDS_PTE_SYNC 1
|
||||
#define PMAP_INCLUDE_PTE_SYNC
|
||||
#else
|
||||
#if (ARM_MMU_SA1 == 1) && (ARM_NMMUS == 1)
|
||||
#define PMAP_NEEDS_PTE_SYNC 1
|
||||
#define PMAP_INCLUDE_PTE_SYNC
|
||||
#elif (ARM_MMU_SA1 == 0)
|
||||
#define PMAP_NEEDS_PTE_SYNC 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* These macros return various bits based on kernel/user and protection.
|
||||
|
@ -9,9 +9,10 @@ CPU_SA1100 opt_global.h
|
||||
CPU_SA1110 opt_global.h
|
||||
CPU_ARM9 opt_global.h
|
||||
CPU_XSCALE_80321 opt_global.h
|
||||
PHYSADDR opt_global.h
|
||||
KERNPHYSADDR opt_global.h
|
||||
KERNVIRTADDR opt_global.h
|
||||
PHYSADDR opt_global.h
|
||||
SKYEYE_WORKAROUNDS opt_global.h
|
||||
STARTUP_PAGETABLE_ADDR opt_global.h
|
||||
XSCALE_CACHE_READ_WRITE_ALLOCATE opt_global.h
|
||||
XSACLE_DISABLE_CCNT opt_timer.h
|
||||
|
Loading…
Reference in New Issue
Block a user