Apply all changes doe so for prior to GitHub upload

This commit is contained in:
Andrzej Flis
2015-11-14 21:49:35 +01:00
parent 95b0c215fc
commit c692c6ed8b
50 changed files with 669 additions and 1047 deletions

View File

@@ -1,107 +0,0 @@
#ifndef _OMAP_SERIAL_H
#define _OMAP_SERIAL_H
/* UART register map */
#define OMAP3_UART1_BASE 0x4806A000 /* UART1 physical address */
#define OMAP3_UART2_BASE 0x4806C000 /* UART2 physical address */
#define OMAP3_UART3_BASE 0x49020000 /* UART3 physical address */
/* UART registers */
#define OMAP3_THR 0 /* Transmit holding register */
#define OMAP3_RHR 0 /* Receive holding register */
#define OMAP3_DLL 0 /* Divisor latches low */
#define OMAP3_DLH 1 /* Divisor latches high */
#define OMAP3_IER 1 /* Interrupt enable register */
#define OMAP3_IIR 2 /* Interrupt identification register */
#define OMAP3_EFR 2 /* Extended features register */
#define OMAP3_FCR 2 /* FIFO control register */
#define OMAP3_LCR 3 /* Line control register */
#define OMAP3_MCR 4 /* Modem control register */
#define OMAP3_LSR 5 /* Line status register */
#define OMAP3_MSR 6 /* Modem status register */
#define OMAP3_TCR 6
#define OMAP3_MDR1 0x08 /* Mode definition register 1 */
#define OMAP3_MDR2 0x09 /* Mode definition register 2 */
#define OMAP3_SCR 0x10 /* Supplementary control register */
#define OMAP3_SSR 0x11 /* Supplementary status register */
#define OMAP3_SYSC 0x15 /* System configuration register */
#define OMAP3_SYSS 0x16 /* System status register */
/* Enhanced Features Register bits */
#define UART_EFR_ECB (1 << 4)/* Enhanced control bit */
#define UART_EFR_AUTO_CTS (1 << 6)/* auto cts enable */
#define UART_EFR_AUTO_RTS (1 << 7)/* auto rts enable */
/* Interrupt Enable Register bits */
#define UART_IER_MSI 0x08 /* Modem status interrupt */
#define UART_IER_RLSI 0x04 /* Receiver line status interrupt */
#define UART_IER_THRI 0x02 /* Transmitter holding register int. */
#define UART_IER_RDI 0x01 /* Receiver data interrupt */
/* FIFO control register */
#define OMAP_UART_FCR_RX_FIFO_TRIG_SHIFT 6
#define OMAP_UART_FCR_RX_FIFO_TRIG_MASK (0x3 << 6)
#define OMAP_UART_FCR_TX_FIFO_TRIG_SHIFT 4
#define OMAP_UART_FCR_TX_FIFO_TRIG_MASK (0x3 << 4)
#define UART_FCR_ENABLE_FIFO 0x01 /* Enable the fifo */
#define UART_FCR_CLR_RCVR 0x02 /* Clear the RCVR FIFO */
#define UART_FCR_CLR_XMIT 0x04 /* Clear the XMIT FIFO */
/* Interrupt Identification Register bits */
#define UART_IIR_RDI 0x04 /* Data ready interrupt */
#define UART_IIR_THRI 0x02 /* Transmitter holding register empty */
#define UART_IIR_NO_INT 0x01 /* No interrupt is pending */
/* Line Control Register bits */
#define UART_LCR_DLAB 0x80 /* Divisor latch access bit */
#define UART_LCR_SBC 0x40 /* Set break control */
#define UART_LCR_EPAR 0x10 /* Even parity select */
#define UART_LCR_PARITY 0x08 /* Enable parity */
#define UART_LCR_STOP 0x04 /* Stop bits; 0=1 bit, 1=2 bits */
#define UART_LCR_WLEN5 0x00 /* Wordlength 5 bits */
#define UART_LCR_WLEN6 0x01 /* Wordlength 6 bits */
#define UART_LCR_WLEN7 0x02 /* Wordlength 7 bits */
#define UART_LCR_WLEN8 0x03 /* Wordlength 8 bits */
#define UART_LCR_CONF_MODE_A UART_LCR_DLAB /* Configuration Mode A */
#define UART_LCR_CONF_MODE_B 0xBF /* Configuration Mode B */
/* Line Status Register bits */
#define UART_LSR_THRE 0x20 /* Transmit-hold-register empty */
#define UART_LSR_BI 0x10 /* Break condition */
#define UART_LSR_DR 0x01 /* Data ready */
/* Modem Control Register bits */
#define UART_MCR_TCRTLR 0x40 /* Access TCR/TLR */
#define UART_MCR_OUT2 0x08 /* Out2 complement */
#define UART_MCR_RTS 0x02 /* RTS complement */
#define UART_MCR_DTR 0x01 /* DTR output low */
/* Mode Definition Register 1 bits */
#define OMAP_MDR1_DISABLE 0x07
#define OMAP_MDR1_MODE13X 0x03
#define OMAP_MDR1_MODE16X 0x00
/* Modem Status Register bits */
#define UART_MSR_DCD 0x80 /* Data Carrier Detect */
#define UART_MSR_CTS 0x10 /* Clear to Send */
#define UART_MSR_DDCD 0x08 /* Delta DCD */
/* Supplementary control Register bits */
#define OMAP_UART_SCR_RX_TRIG_GRANU1_MASK (1 << 7)
/* System Control Register bits */
#define UART_SYSC_SOFTRESET 0x02
/* System Status Register bits */
#define UART_SYSS_RESETDONE 0x01
/* Line status register fields */
#define OMAP3_LSR_TX_FIFO_E (1 << 5) /* Transmit FIFO empty */
#define OMAP3_LSR_RX_FIFO_E (1 << 0) /* Receive FIFO empty */
#define OMAP3_LSR_RXOE (1 << 1) /* Overrun error.*/
/* Supplementary status register fields */
#define OMAP3_SSR_TX_FIFO_FULL (1 << 0) /* Transmit FIFO full */
#endif /* _OMAP_SERIAL_H */

View File

@@ -0,0 +1,74 @@
#ifndef _RPI_SERIAL_H
#define _RPI_SERIAL_H
#define RPI_UART_BASE 0x20201000 /* UART1 physical address */
#define UART011_FR_TXFF 0x020 /* Transmit-hold-register empty */
#define UART011_FR_RXFE 0x010
#define RPI_UART_MSR_CTS 0x10 /* Current Clear to Send */
#define UART011_DR 0x00 /* Data read or written from the interface. */
#define UART011_FR 0x18 /* Flag register (Read only). */
#define UART010_IIR 0x1C /* Interrupt indentification register (Read). */
#define UART011_IBRD 0x24 /* Integer baud rate divisor register. */
#define UART011_FBRD 0x28 /* Fractional baud rate divisor register. */
#define UART011_LCRH 0x2c /* Line control register. */
#define UART011_CR 0x30 /* Control register. */
#define UART011_IFLS 0x34 /* Interrupt fifo level select. */
#define UART011_IMSC 0x38 /* Interrupt mask. */
#define UART011_MIS 0x40 /* Masked interrupt status. */
#define UART011_ICR 0x44 /* Interrupt clear register. */
#define UART011_DR_OE (1 << 11)
#define UART011_LCRH_SPS 0x80
#define UART011_LCRH_WLEN_8 0x60
#define UART011_LCRH_WLEN_7 0x40
#define UART011_LCRH_WLEN_6 0x20
#define UART011_LCRH_WLEN_5 0x00
#define UART011_LCRH_FEN 0x10
#define UART011_LCRH_STP2 0x08
#define UART011_LCRH_EPS 0x04
#define UART011_LCRH_PEN 0x02
#define UART011_LCRH_BRK 0x01
#define UART011_CR_LBE 0x0080 /* loopback enable */
#define UART011_CR_UARTEN 0x0001 /* UART enable */
#define UART011_CR_TXE 0x0100 /* transmit enable */
#define UART011_CR_RXE 0x0200 /* receive enable */
#define UART011_CR_DTR 0x0400 /* DTR */
#define UART011_CR_RTS 0x0800 /* RTS */
#define UART011_CR_RTSEN 0x4000 /* RTS hardware flow control */
#define UART011_CR_CTSEN 0x8000 /* CTS hardware flow control */
#define UART011_CR_OUT2 0x2000 /* OUT2 */
#define UART011_CR_OUT1 0x1000 /* OUT1 */
#define UART011_FR_BUSY (1 << 3) /* set to 1 when UART is transmitting data */
#define UART011_TXIM (1 << 5) /* transmit interrupt mask */
#define UART011_RXIM (1 << 4) /* receive interrupt mask */
#define UART011_RTIM (1 << 6) /* receive timeout interrupt mask */
#define UART011_OEIS (1 << 10) /* overrun error interrupt status */
#define UART011_BEIS (1 << 9) /* break error interrupt status */
#define UART011_PEIS (1 << 8) /* parity error interrupt status */
#define UART011_FEIS (1 << 7) /* framing error interrupt status */
#define UART011_RTIS (1 << 6) /* receive timeout interrupt status */
#define UART011_TXIS (1 << 5) /* transmit interrupt status */
#define UART011_RXIS (1 << 4) /* receive interrupt status */
#define UART011_DSRMIS (1 << 3) /* DSR interrupt status */
#define UART011_DCDMIS (1 << 2) /* DCD interrupt status */
#define UART011_CTSMIS (1 << 1) /* CTS interrupt status */
#define UART011_RIMIS (1 << 0) /* RI interrupt status */
#define UART011_IFLS_RX4_8 (2 << 3)
#define UART011_IFLS_TX4_8 (2 << 0)
#define UART011_FR_CTS 0x001
#define UART011_FR_DSR 0x002
#define UART011_FR_DCD 0x004
#define UART011_FR_MODEM_ANY (UART011_FR_DCD|UART011_FR_DSR|UART011_FR_CTS)
#endif /* _OMAP_SERIAL_H */

View File

@@ -7,14 +7,14 @@
#include <assert.h>
#include <signal.h>
#include <termios.h>
#include "omap_serial.h"
#include "rpi_serial.h"
#include "tty.h"
#if NR_RS_LINES > 0
#define UART_FREQ 48000000L /* timer frequency */
#define UART_FREQ 3000000L /* timer frequency */
#if 0
#define DFLT_BAUD TSPEED_DEF /* default baud rate */
#define DFLT_BAUD TSPEED_DEF /* default baud rate */
#else
#define DFLT_BAUD B115200 /* default baud rate */
#endif
@@ -48,19 +48,18 @@
* OUT2 is also kept high all the time.
*/
#define istart(rs) \
(serial_out((rs), OMAP3_MCR, UART_MCR_OUT2|UART_MCR_RTS|UART_MCR_DTR),\
(serial_out((rs), UART011_CR, UART011_CR_UARTEN|UART011_CR_RXE|UART011_CR_TXE),\
(rs)->idevready = TRUE)
#define istop(rs) \
(serial_out((rs), OMAP3_MCR, UART_MCR_OUT2|UART_MCR_DTR), \
(serial_out((rs), UART011_CR, UART011_CR_OUT2|UART011_CR_DTR), \
(rs)->idevready = FALSE)
/* Macro to tell if device is ready. The rs->cts field is set to UART_MSR_CTS
* if CLOCAL is in effect for a line without a CTS wire.
*/
#define devready(rs) ((serial_in(rs, OMAP3_MSR) | rs->cts) & UART_MSR_CTS)
#define devready(rs) ((serial_in(rs, UART011_FR) | rs->cts) & UART011_FR_CTS)
/* Macro to tell if transmitter is ready. */
#define txready(rs) (serial_in(rs, OMAP3_LSR) & UART_LSR_THRE)
#define txready(rs) (serial_in(rs, UART011_FR) & UART011_FR_TXFF)
/* RS232 device structure, one per device. */
typedef struct rs232 {
@@ -76,10 +75,10 @@ typedef struct rs232 {
#define ODONE 1 /* output completed (< output enable bits) */
#define ORAW 2 /* raw mode for xoff disable (< enab. bits) */
#define OWAKEUP 4 /* tty_wakeup() pending (asm code only) */
#define ODEVREADY UART_MSR_CTS /* external device hardware ready (CTS) */
#define ODEVREADY 0x10 /* external device hardware ready (CTS) */
#define OQUEUED 0x20 /* output buffer not empty */
#define OSWREADY 0x40 /* external device software ready (no xoff) */
#define ODEVHUP UART_MSR_DCD /* external device has dropped carrier */
#define ODEVHUP 0x80 /* external device has dropped carrier */
#define OSOFTBITS (ODONE | ORAW | OWAKEUP | OQUEUED | OSWREADY)
/* user-defined bits */
#if (OSOFTBITS | ODEVREADY | ODEVHUP) == OSOFTBITS
@@ -95,12 +94,11 @@ typedef struct rs232 {
phys_bytes phys_base; /* UART physical base address (I/O map) */
unsigned int reg_offset; /* UART register offset */
unsigned int ier; /* copy of ier register */
unsigned int im; /* copy of im register */
unsigned int scr; /* copy of scr register */
unsigned int fcr; /* copy of fcr register */
unsigned int dll; /* copy of dll register */
unsigned int dlh; /* copy of dlh register */
unsigned int uartclk; /* UART clock rate */
unsigned int old_status;
unsigned char lstatus; /* last line status */
int rx_overrun_events;
@@ -120,16 +118,8 @@ typedef struct uart_port {
int irq;
} uart_port_t;
/* OMAP3 UART base addresses. */
static uart_port_t dm37xx_ports[] = {
{ OMAP3_UART1_BASE, 72}, /* UART1 */
{ OMAP3_UART2_BASE, 73}, /* UART2 */
{ OMAP3_UART3_BASE, 74}, /* UART3 */
{ 0, 0 }
};
static uart_port_t am335x_ports[] = {
{ 0x44E09000 , 72 }, /* UART0 */
static uart_port_t rpi_ports[] = {
{ RPI_UART_BASE , 72 }, /* UART0 */
{ 0, 0 },
{ 0, 0 },
{ 0, 0 }
@@ -189,14 +179,13 @@ serial_out(rs232_t *rs, int offset, int val)
static void
rs_reset(rs232_t *rs)
{
u32_t syss;
serial_out(rs, OMAP3_SYSC, UART_SYSC_SOFTRESET);
/* Poll until done */
do {
syss = serial_in(rs, OMAP3_SYSS);
} while (!(syss & UART_SYSS_RESETDONE));
unsigned int lcr;
while( serial_in( rs, UART011_FR ) & UART011_FR_BUSY )
{
}
lcr = serial_in( rs, UART011_LCRH );
lcr &= ~(UART011_LCRH_BRK | UART011_LCRH_FEN);
serial_out( rs, UART011_LCRH, lcr );
}
static int
@@ -318,37 +307,10 @@ rs_ioctl(tty_t *tp, int UNUSED(dummy))
return 0; /* dummy */
}
static unsigned int
omap_get_divisor(rs232_t *rs, unsigned int baud)
{
/* Calculate divisor value. The 16750 has two oversampling modes to reach
* high baud rates with little error rate (see table 17-1 in OMAP TRM).
* Baud rates 460800, 921600, 1843200, and 3686400 use 13x oversampling,
* the other rates 16x. The baud rate is calculated as follows:
* baud rate = (functional clock / oversampling) / divisor.
*/
unsigned int oversampling;
assert(baud != 0);
switch(baud) {
case B460800: /* Fall through */
case B921600: /* Fall through */
#if 0
case B1843200: /* Fall through */
case B3686400:
#endif
oversampling = 13; break;
default: oversampling = 16;
}
return (rs->uartclk / oversampling) / baud;
}
static int
termios_baud_rate(struct termios *term)
{
int baud;
int baud, denom, div, rem, ibrd, fbrd;
switch(term->c_ospeed) {
case B300: baud = 300; break;
case B600: baud = 600; break;
@@ -369,71 +331,62 @@ termios_baud_rate(struct termios *term)
baud = termios_baud_rate(term);
}
return baud;
denom = 16 * baud;
div = UART_FREQ / denom;
rem = UART_FREQ % denom;
ibrd = div << 6;
fbrd = (((8 * rem) / baud) + 1) / 2;
/* Tolerance? */
return ibrd | fbrd;
}
static void rs_config(rs232_t *rs)
{
/* Set various line control parameters for RS232 I/O. */
tty_t *tp = rs->tty;
unsigned int divisor, efr, lcr, mcr, baud;
unsigned int divisor, efr, lcr, mcr, rate, old_cr;
/* Clear pending error and receive interrupts */
serial_out( rs, UART011_ICR, (UART011_OEIS | UART011_BEIS | UART011_PEIS | UART011_FEIS | UART011_RTIS | UART011_RXIS) );
serial_out( rs, UART011_IFLS, ( UART011_IFLS_RX4_8 | UART011_IFLS_TX4_8 ) );
/*
* Provoke TX FIFO interrupt into asserting.
*/
serial_out( rs, UART011_CR, 0 );
while( serial_in( rs, UART011_FR ) & UART011_FR_BUSY );
/* Fifo and DMA settings */
/* See OMAP35x TRM 17.5.1.1.2 */
lcr = serial_in(rs, OMAP3_LCR); /* 1a */
serial_out(rs, OMAP3_LCR, UART_LCR_CONF_MODE_B); /* 1b */
efr = serial_in(rs, OMAP3_EFR); /* 2a */
serial_out(rs, OMAP3_EFR, efr | UART_EFR_ECB); /* 2b */
serial_out(rs, OMAP3_LCR, UART_LCR_CONF_MODE_A); /* 3 */
mcr = serial_in(rs, OMAP3_MCR); /* 4a */
serial_out(rs, OMAP3_MCR, mcr | UART_MCR_TCRTLR); /* 4b */
/* Set up FIFO */
rs->fcr = 0;
/* Set FIFO interrupt trigger levels high */
rs->fcr |= (0x3 << OMAP_UART_FCR_RX_FIFO_TRIG_SHIFT);
rs->fcr |= (0x3 << OMAP_UART_FCR_TX_FIFO_TRIG_SHIFT);
rs->fcr |= UART_FCR_ENABLE_FIFO;
serial_out(rs, OMAP3_FCR, rs->fcr); /* 5 */
serial_out(rs, OMAP3_LCR, UART_LCR_CONF_MODE_B); /* 6 */
/* DMA triggers, not supported by this driver */ /* 7 */
rs->scr = OMAP_UART_SCR_RX_TRIG_GRANU1_MASK;
serial_out(rs, OMAP3_SCR, rs->scr); /* 8 */
serial_out(rs, OMAP3_EFR, efr); /* 9 */
serial_out(rs, OMAP3_LCR, UART_LCR_CONF_MODE_A); /* 10 */
serial_out(rs, OMAP3_MCR, mcr); /* 11 */
serial_out(rs, OMAP3_LCR, lcr); /* 12 */
/* RS232 needs to know the xoff character, and if CTS works. */
rs->oxoff = tp->tty_termios.c_cc[VSTOP];
rs->cts = (tp->tty_termios.c_cflag & CLOCAL) ? UART_MSR_CTS : 0;
baud = termios_baud_rate(&tp->tty_termios);
rs->old_status = serial_in( rs, UART011_FR ) & UART011_FR_MODEM_ANY;
/* RS232 needs to know the xoff character, and if CTS works. */
rs->oxoff = tp->tty_termios.c_cc[VSTOP];
rs->cts = (tp->tty_termios.c_cflag & CLOCAL) ? UART011_FR_CTS : 0;
/* Look up the 16750 rate divisor from the output speed. */
divisor = omap_get_divisor(rs, baud);
rs->dll = divisor & 0xFF;
rs->dlh = divisor >> 8;
/* Compute line control flag bits. */
lcr = 0;
if (tp->tty_termios.c_cflag & PARENB) {
lcr |= UART_LCR_PARITY;
if (!(tp->tty_termios.c_cflag & PARODD)) lcr |= UART_LCR_EPAR;
}
if (tp->tty_termios.c_cflag & CSTOPB) lcr |= UART_LCR_STOP;
switch(tp->tty_termios.c_cflag & CSIZE) {
rate = termios_baud_rate(&tp->tty_termios);
/* Compute line control flag bits. */
lcr = 0;
if (tp->tty_termios.c_cflag & PARENB) {
lcr |= UART011_LCRH_PEN;
if (!(tp->tty_termios.c_cflag & PARODD)) lcr |= UART011_LCRH_EPS;
}
if (tp->tty_termios.c_cflag & CSTOPB) lcr |= UART011_LCRH_STP2;
switch(tp->tty_termios.c_cflag & CSIZE) {
case CS5:
lcr |= UART_LCR_WLEN5;
lcr |= UART011_LCRH_WLEN_5;
break;
case CS6:
lcr |= UART_LCR_WLEN6;
lcr |= UART011_LCRH_WLEN_6;
break;
case CS7:
lcr |= UART_LCR_WLEN7;
lcr |= UART011_LCRH_WLEN_7;
break;
default:
case CS8:
lcr |= UART_LCR_WLEN8;
lcr |= UART011_LCRH_WLEN_8;
break;
}
}
/* Lock out interrupts while setting the speed. The receiver register
* is going to be hidden by the div_low register, but the input
@@ -444,32 +397,26 @@ static void rs_config(rs232_t *rs)
if (sys_irqdisable(&rs->irq_hook_kernel_id) != OK)
panic("unable to disable interrupts");
/* Select the baud rate divisor registers and change the rate. */
/* See OMAP35x TRM 17.5.1.1.3 */
serial_out(rs, OMAP3_MDR1, OMAP_MDR1_DISABLE); /* 1 */
serial_out(rs, OMAP3_LCR, UART_LCR_CONF_MODE_B); /* 2 */
efr = serial_in(rs, OMAP3_EFR); /* 3a */
serial_out(rs, OMAP3_EFR, efr | UART_EFR_ECB); /* 3b */
serial_out(rs, OMAP3_LCR, 0); /* 4 */
serial_out(rs, OMAP3_IER, 0); /* 5 */
serial_out(rs, OMAP3_LCR, UART_LCR_CONF_MODE_B); /* 6 */
serial_out(rs, OMAP3_DLL, rs->dll); /* 7 */
serial_out(rs, OMAP3_DLH, rs->dlh); /* 7 */
serial_out(rs, OMAP3_LCR, 0); /* 8 */
serial_out(rs, OMAP3_IER, rs->ier); /* 9 */
serial_out(rs, OMAP3_LCR, UART_LCR_CONF_MODE_B); /* 10 */
serial_out(rs, OMAP3_EFR, efr); /* 11 */
serial_out(rs, OMAP3_LCR, lcr); /* 12 */
if (baud > 230400 && baud != 3000000)
serial_out(rs, OMAP3_MDR1, OMAP_MDR1_MODE13X); /* 13 */
else
serial_out(rs, OMAP3_MDR1, OMAP_MDR1_MODE16X);
rs->ostate = devready(rs) | ORAW | OSWREADY; /* reads MSR */
/* first disable everything */
serial_out(rs, UART011_CR, 0 );
/* Set baud rate */
serial_out(rs, UART011_FBRD, (rate & ((1 << 6) - 1)) );
serial_out(rs, UART011_IBRD, (rate >> 6) );
/*
* ----------v----------v----------v----------v-----
* NOTE: MUST BE WRITTEN AFTER UARTLCR_M & UARTLCR_L
* ----------^----------^----------^----------^-----
*/
serial_out(rs, UART011_LCRH, (lcr | UART011_LCRH_FEN) );
serial_out(rs, UART011_IMSC , rs->im );
lcr = UART011_CR_UARTEN | UART011_CR_RXE | UART011_CR_TXE;
serial_out( rs, UART011_CR, lcr );
rs->ostate = devready(rs) | ORAW | OSWREADY; /* reads MSR */
if ((tp->tty_termios.c_lflag & IXON) && rs->oxoff != _POSIX_VDISABLE)
rs->ostate &= ~ORAW;
(void) serial_in(rs, OMAP3_IIR);
if (sys_irqenable(&rs->irq_hook_kernel_id) != OK)
panic("unable to enable interrupts");
}
@@ -480,7 +427,7 @@ rs_init(tty_t *tp)
/* Initialize RS232 for one line. */
register rs232_t *rs;
int line;
uart_port_t this_omap3;
uart_port_t this_rpi;
char l[10];
struct minix_mem_range mr;
struct machine machine;
@@ -492,12 +439,6 @@ rs_init(tty_t *tp)
* serial line, making tty not look at the irq and returning ENXIO
* for all requests on it from userland. (The kernel will use it.)
*/
if(env_get_param(SERVARNAME, l, sizeof(l)-1) == OK && atoi(l) == line){
printf("TTY: rs232 line %d not initialized (used by kernel)\n",
line);
return;
}
rs = tp->tty_priv = &rs_lines[line];
rs->tty = tp;
@@ -506,14 +447,12 @@ rs_init(tty_t *tp)
sys_getmachine(&machine);
if (BOARD_IS_BBXM(machine.board_id)){
this_omap3 = dm37xx_ports[line];
} else if (BOARD_IS_BB(machine.board_id)){
this_omap3 = am335x_ports[line];
if (BOARD_IS_RPI(machine.board_id)){
this_rpi = rpi_ports[line];
} else {
return;
}
if (this_omap3.base_addr == 0) return;
if (this_rpi.base_addr == 0) return;
/* Configure memory access */
mr.mr_base = rs->phys_base;
@@ -522,12 +461,12 @@ rs_init(tty_t *tp)
panic("Unable to request access to UART memory");
}
rs->phys_base = (vir_bytes) vm_map_phys(SELF,
(void *) this_omap3.base_addr, 0x100);
(void *) this_rpi.base_addr, 0x1000);
if (rs->phys_base == (vir_bytes) MAP_FAILED) {
panic("Unable to request access to UART memory");
}
rs->reg_offset = 2;
rs->reg_offset = 0;
rs->uartclk = UART_FREQ;
rs->ohead = rs->otail = rs->obuf;
@@ -541,7 +480,7 @@ rs_init(tty_t *tp)
tp->tty_termios.c_ospeed = DFLT_BAUD;
/* Configure IRQ */
rs->irq = this_omap3.irq;
rs->irq = this_rpi.irq;
/* callback with irq line number + 1 because using line number 0
fails eslewhere */
@@ -566,7 +505,7 @@ rs_init(tty_t *tp)
/* Enable interrupts */
rs_reset(rs);
rs->ier = UART_IER_RLSI | UART_IER_RDI | UART_IER_MSI;
rs->im = UART011_RXIM | UART011_RTIM;
rs_config(rs);
/* Fill in TTY function hooks. */
@@ -580,7 +519,7 @@ rs_init(tty_t *tp)
tp->tty_break_off = rs_break_off;
tp->tty_open = rs_open;
tp->tty_close = rs_close;
printf("rs_init done\n");
/* Tell external device we are ready. */
istart(rs);
}
@@ -683,8 +622,8 @@ rs_break_on(tty_t *tp, int UNUSED(dummy))
rs232_t *rs = tp->tty_priv;
unsigned int lsr;
lsr = serial_in(rs, OMAP3_LSR);
serial_out(rs, OMAP3_LSR, lsr | UART_LSR_BI);
lsr = serial_in(rs, UART011_LCRH);
serial_out(rs, UART011_LCRH, lsr | UART011_LCRH_BRK);
return 0; /* dummy */
}
@@ -695,8 +634,8 @@ rs_break_off(tty_t *tp, int UNUSED(dummy))
rs232_t *rs = tp->tty_priv;
unsigned int lsr;
lsr = serial_in(rs, OMAP3_LSR);
serial_out(rs, OMAP3_LSR, lsr & ~UART_LSR_BI);
lsr = serial_in(rs, UART011_LCRH);
serial_out(rs, UART011_LCRH, lsr & ~UART011_LCRH_BRK);
return 0; /* dummy */
}
@@ -713,13 +652,11 @@ rs_close(tty_t *tp, int UNUSED(dummy))
{
/* The line is closed; optionally hang up. */
rs232_t *rs = tp->tty_priv;
if (tp->tty_termios.c_cflag & HUPCL) {
serial_out(rs, OMAP3_MCR, UART_MCR_OUT2|UART_MCR_RTS);
if (rs->ier & UART_IER_THRI) {
rs->ier &= ~UART_IER_THRI;
serial_out(rs, OMAP3_IER, rs->ier);
}
unsigned int lcr;
lcr = UART011_CR_RXE | UART011_CR_TXE;
serial_out(rs, UART011_CR, lcr);
serial_out(rs, UART011_IMSC, (UART011_RTIM | UART011_RXIM));
}
return 0; /* dummy */
}
@@ -732,23 +669,27 @@ rs232_handler(struct rs232 *rs)
/* Handle interrupt of a UART port */
unsigned int iir, lsr;
iir = serial_in(rs, OMAP3_IIR);
if (iir & UART_IIR_NO_INT) /* No interrupt */
return;
lsr = serial_in(rs, OMAP3_LSR);
if (iir & UART_IIR_RDI) { /* Data ready interrupt */
if (lsr & UART_LSR_DR) {
read_chars(rs, lsr);
}
}
check_modem_status(rs);
if (iir & UART_IIR_THRI) {
if (lsr & UART_LSR_THRE) {
/* Ready to send and space available */
write_chars(rs);
}
}
iir = serial_in(rs, UART011_MIS);
if ( iir )
{
do
{
serial_out(rs, UART011_ICR, (iir & ~(UART011_TXIS|UART011_RTIS|UART011_RXIS)));
if ( iir & (UART011_RTIS|UART011_RXIS))
{
read_chars(rs, 0);
}
if ( iir & (UART011_DSRMIS|UART011_DCDMIS|UART011_CTSMIS|UART011_RIMIS))
{
check_modem_status(rs);
}
if ( iir & (UART011_TXIS))
{
write_chars(rs);
}
iir = serial_in(rs, UART011_MIS);
} while ( iir != 0 );
}
}
static void
@@ -756,13 +697,13 @@ read_chars(rs232_t *rs, unsigned int status)
{
unsigned char c;
if(serial_in(rs,OMAP3_LSR) & OMAP3_LSR_RXOE) {
rs->rx_overrun_events++;
}
/* check the line status to know if there are more chars */
while (serial_in(rs, OMAP3_LSR) & UART_LSR_DR) {
c = serial_in(rs, OMAP3_RHR);
while ( (serial_in(rs, UART011_FR) & UART011_FR_RXFE) == 0 ) {
c = serial_in(rs, UART011_DR);
if ( c & UART011_DR_OE )
{
rs->rx_overrun_events++;
}
if (!(rs->ostate & ORAW)) {
if (c == rs->oxoff) {
rs->ostate &= ~OSWREADY;
@@ -801,23 +742,23 @@ write_chars(rs232_t *rs)
if (rs->ostate >= (ODEVREADY | OQUEUED | OSWREADY)) {
/* Bit test allows ORAW and requires the others. */
serial_out(rs, OMAP3_THR, *rs->otail);
serial_out(rs, UART011_DR, *rs->otail);
if (++rs->otail == bufend(rs->obuf))
rs->otail = rs->obuf;
if (--rs->ocount == 0) {
/* Turn on ODONE flag, turn off OQUEUED */
rs->ostate ^= (ODONE | OQUEUED);
rs->tty->tty_events = 1;
if (rs->ier & UART_IER_THRI) {
rs->ier &= ~UART_IER_THRI;
serial_out(rs, OMAP3_IER, rs->ier);
if (rs->im & UART011_TXIM) {
rs->im &= ~UART011_TXIM;
serial_out(rs, UART011_IMSC, rs->im);
}
} else {
if (rs->icount == RS_OLOWWATER)
rs->tty->tty_events = 1;
if (!(rs->ier & UART_IER_THRI)) {
rs->ier |= UART_IER_THRI;
serial_out(rs, OMAP3_IER, rs->ier);
if (!(rs->im & UART011_TXIM)) {
rs->im |= UART011_TXIM;
serial_out(rs, UART011_IMSC, rs->im);
}
}
}
@@ -830,8 +771,8 @@ check_modem_status(rs232_t *rs)
unsigned int msr;
msr = serial_in(rs, OMAP3_MSR); /* Resets modem interrupt */
if ((msr & (UART_MSR_DCD|UART_MSR_DDCD)) == UART_MSR_DDCD) {
msr = serial_in(rs, UART011_FR); /* Resets modem interrupt */
if ((msr & (UART011_FR_DCD|UART011_FR_DSR)) == UART011_FR_DSR) {
rs->ostate |= ODEVHUP;
rs->tty->tty_events = 1;
}

View File

@@ -178,6 +178,10 @@ arm/vm.h
#define ARM_TTBR_ADDR_MASK (0xffffc000) /* only the 18 upper bits are to be used as address */
#define ARM_TTBR_FLAGS_CACHED ARM_TTBR_OUTER_WBWA
#define ARM_PMCCTL_E (1<<0)
#define ARM_PMCCTL_P (1<<1)
#define ARM_PMCCTL_C (1<<2)
/* Fault status */
#define ARM_VM_PFE_FS(s) \
((((s) & ARM_VM_PFE_FS4) >> 6) | ((s) & ARM_VM_PFE_FS3_0))

View File

@@ -81,9 +81,9 @@ clock_t tmrs_settimer(minix_timer_t **tmrs, minix_timer_t *tp, clock_t exp_time,
static int _cum_instances; \
u64_t _next_cum_spent, _starttime, _endtime, _dt, _cum_dt; \
u32_t _dt_micros; \
read_tsc_64(&_starttime); \
arch_read_tsc_64(&_starttime); \
do { timed_code_block } while(0); \
read_tsc_64(&_endtime); \
arch_read_tsc_64(&_endtime); \
_dt = _endtime - _starttime; \
if(_cum_instances == 0) { \
RESET_STATS(_starttime, _cum_instances, _cum_spenttime, _cum_starttime); \

View File

@@ -6,7 +6,7 @@ HERE=${.CURDIR}/arch/${MACHINE_ARCH}
# objects we want unpaged from -lc
MINLIB_OBJS_UNPAGED= get_bp.o
get_bp.o: ${NETBSDSRCDIR}/minix/lib/libc/arch/arm/get_bp.S
get_bp.o: ${NETBSDSRCDIR}/minix/lib/libc/arch/${MACHINE_ARCH}/get_bp.S
# objects we want unpaged from -lsys
SYS_OBJS_UNPAGED=assert.o stacktrace.o

View File

@@ -216,3 +216,8 @@ void __switch_address_space(struct proc *p, struct proc **__ptproc)
return;
}
void announce_by_arch(void)
{
}

View File

@@ -6,7 +6,7 @@ HERE=${.CURDIR}/arch/${MACHINE_ARCH}
# objects we want unpaged from -lc
MINLIB_OBJS_UNPAGED= get_bp.o
get_bp.o: ${NETBSDSRCDIR}/minix/lib/libc/arch/arm/get_bp.S
get_bp.o: ${NETBSDSRCDIR}/minix/lib/libc/arch/${MACHINE_ARCH}/get_bp.S
# objects we want unpaged from -lsys
SYS_OBJS_UNPAGED=assert.o stacktrace.o

View File

@@ -28,10 +28,8 @@ int init_local_timer(unsigned freq)
{
bsp_timer_init(freq);
if (BOARD_IS_BBXM(machine.board_id)) {
tsc_per_ms[0] = 16250;
} else if (BOARD_IS_BB(machine.board_id)) {
tsc_per_ms[0] = 15000;
if (BOARD_IS_RPI(machine.board_id)) {
tsc_per_ms[0] = 1000;
} else {
panic("Can not do the clock setup. machine (0x%08x) is unknown\n",machine.board_id);
};
@@ -64,7 +62,7 @@ void context_stop(struct proc * p)
u64_t * __tsc_ctr_switch = get_cpulocal_var_ptr(tsc_ctr_switch);
read_tsc_64(&tsc);
assert(tsc >= *__tsc_ctr_switch);
tsc_delta = tsc - *__tsc_ctr_switch;
p->p_cycles += tsc_delta;

View File

@@ -95,7 +95,7 @@ void cpu_identify(void)
cpu_info[cpu].arch = (midr >> 16) & 0xF;
cpu_info[cpu].part = (midr >> 4) & 0xFFF;
cpu_info[cpu].revision = midr & 0xF;
cpu_info[cpu].freq = 660; /* 660 Mhz hardcoded */
cpu_info[cpu].freq = 700; /* 700 Mhz hardcoded */
}
void arch_init(void)
@@ -120,12 +120,9 @@ void arch_init(void)
asm volatile ("MRC p15, 0, %0, c15, c12, 0\t\n": "=r" (value));
value |= PMU_PMCR_C; /* Reset counter */
value |= PMU_PMCR_E; /* Enable counter hardware */
value |= PMU_PMCR_CCR;
asm volatile ("MCR p15, 0, %0, c15, c12, 0\t\n": : "r" (value));
/* enable CCNT counting: ARM ARM B4.1.116 */
value = PMU_PMCNTENSET_C; /* Enable PMCCNTR cycle counter */
asm volatile ("MCR p15, 0, %0, c15, c12, 1\t\n": : "r" (value));
/* enable cycle counter in user mode: ARM ARM B4.1.124 */
/* http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0360e/I1003211.html */
value = PMU_PMUSERENR_EN;
@@ -218,3 +215,8 @@ void __switch_address_space(struct proc *p, struct proc **__ptproc)
return;
}
void announce_by_arch(void)
{
printf("RaspberryPi B+ port by Andrzej Flis andrzej.flis@gmail.com\n");
}

View File

@@ -2,243 +2,16 @@
#define _RPI_INTR_H
/* Interrupt controller memory map */
#define RPI_INTR_BASE 0x2000B200 /* INTCPS physical address */
#define RPI_INTCPS_PENDING_IRQ_BASIC 0x00
#define RPI_INTCPS_PENDING_IRQ0 0x04
#define RPI_INTCPS_PENDING_IRQ1 0x08
#define RPI_INTCPS_MIR_SET0 0x1C /* Set interrupt mask bits */
#define RPI_INTCPS_MIR_SET1 0x20 /* Set interrupt mask bits */
#define RPI_INTCPS_MIR_SET_BASIC 0x24 /* Set interrupt mask bits */
#define RPI_INTCPS_MIR_CLEAR0 0x10 /* Clear interrupt mask bits */
#define RPI_INTCPS_MIR_CLEAR1 0x14 /* Clear interrupt mask bits */
#define RPI_INTCPS_MIR_CLEAR_BASIC 0x18 /* Clear interrupt mask bits */
#define RPI_INTR_BASE 0x2000B000 /* INTCPS physical address */
#define RPI_INTCPS_PENDING_IRQ_BASIC 0x200
#define RPI_INTCPS_PENDING_IRQ0 0x204
#define RPI_INTCPS_PENDING_IRQ1 0x208
#define RPI_INTCPS_MIR_SET0 0x21C /* Set interrupt mask bits */
#define RPI_INTCPS_MIR_SET1 0x220 /* Set interrupt mask bits */
#define RPI_INTCPS_MIR_SET_BASIC 0x224 /* Set interrupt mask bits */
#define RPI_INTCPS_MIR_CLEAR0 0x210 /* Clear interrupt mask bits */
#define RPI_INTCPS_MIR_CLEAR1 0x214 /* Clear interrupt mask bits */
#define RPI_INTCPS_MIR_CLEAR_BASIC 0x218 /* Clear interrupt mask bits */
#define BCM2835_INT_TIMER3 3
/* Interrupt controller memory map */
#define OMAP3_AM335X_INTR_BASE 0x48200000 /* INTCPS physical address */
/* Interrupt controller registers */
#define OMAP3_INTCPS_REVISION 0x000 /* IP revision code */
#define OMAP3_INTCPS_SYSCONFIG 0x010 /* Controls params */
#define OMAP3_INTCPS_SYSSTATUS 0x014 /* Status */
#define OMAP3_INTCPS_SIR_IRQ 0x040 /* Active IRQ number */
#define OMAP3_INTCPS_SIR_FIQ 0x044 /* Active FIQ number */
#define OMAP3_INTCPS_CONTROL 0x048 /* New int agreement bits */
#define OMAP3_INTCPS_PROTECTION 0x04C /* Protection for other regs */
#define OMAP3_INTCPS_IDLE 0x050 /* Clock auto-idle/gating */
#define OMAP3_INTCPS_IRQ_PRIORITY 0x060 /* Active IRQ priority level */
#define OMAP3_INTCPS_FIQ_PRIORITY 0x064 /* Active FIQ priority level */
#define OMAP3_INTCPS_THRESHOLD 0x068 /* Priority threshold */
#define OMAP3_INTCPS_ITR0 0x080 /* Raw pre-masking interrupt status */
#define OMAP3_INTCPS_MIR0 0x084 /* Interrupt mask */
#define OMAP3_INTCPS_MIR_CLEAR0 0x088 /* Clear interrupt mask bits */
#define OMAP3_INTCPS_MIR_SET0 0x08C /* Set interrupt mask bits */
#define OMAP3_INTCPS_ISR_SET0 0x090 /* Set software int bits */
#define OMAP3_INTCPS_ISR_CLEAR0 0x094 /* Clear software int bits */
#define OMAP3_INTCPS_PENDING_IRQ0 0x098 /* IRQ status post-masking */
#define OMAP3_INTCPS_PENDING_FIQ0 0x09C /* FIQ status post-masking */
#define OMAP3_INTCPS_ILR0 0x100 /* Priority for interrupts */
#define OMAP3_INTR_ITR(base,n) \
(base + OMAP3_INTCPS_ITR0 + 0x20 * (n))
#define OMAP3_INTR_MIR(base,n) \
(base + OMAP3_INTCPS_MIR0 + 0x20 * (n))
#define OMAP3_INTR_MIR_CLEAR(base,n) \
(base + OMAP3_INTCPS_MIR_CLEAR0 + 0x20 * (n))
#define OMAP3_INTR_MIR_SET(base,n) \
(base + OMAP3_INTCPS_MIR_SET0 + 0x20 * (n))
#define OMAP3_INTR_ISR_SET(base,n) \
(base + OMAP3_INTCPS_ISR_SET0 + 0x20 * (n))
#define OMAP3_INTR_ISR_CLEAR(base,n) \
(base + OMAP3_INTCPS_ISR_CLEAR0 + 0x20 * (n))
#define OMAP3_INTR_PENDING_IRQ(base,n) \
(base + OMAP3_INTCPS_PENDING_IRQ0 + 0x20 * (n))
#define OMAP3_INTR_PENDING_FIQ(base,n) \
(base + OMAP3_INTCPS_PENDING_FIQ0 + 0x20 * (n))
#define OMAP3_INTR_ILR(base,m) \
(base + OMAP3_INTCPS_ILR0 + 0x4 * (m))
#define OMAP3_INTR_ACTIVEIRQ_MASK 0x7f /* Active IRQ mask for SIR_IRQ */
#define OMAP3_INTR_NEWIRQAGR 0x1 /* New IRQ Generation */
#define OMAP3_DM337X_NR_IRQ_VECTORS 96
/* Interrupt mappings */
#define OMAP3_MCBSP2_ST_IRQ 4 /* Sidestone McBSP2 overflow */
#define OMAP3_MCBSP3_ST_IRQ 5 /* Sidestone McBSP3 overflow */
#define OMAP3_SYS_NIRQ 7 /* External source (active low) */
#define OMAP3_SMX_DBG_IRQ 9 /* L3 interconnect error for debug */
#define OMAP3_SMX_APP_IRQ 10 /* L3 interconnect error for application */
#define OMAP3_PRCM_IRQ 11 /* PRCM module */
#define OMAP3_SDMA0_IRQ 12 /* System DMA request 0 */
#define OMAP3_SDMA1_IRQ 13 /* System DMA request 1 */
#define OMAP3_SDMA2_IRQ 14 /* System DMA request 2 */
#define OMAP3_SDMA3_IRQ 15 /* System DMA request 3 */
#define OMAP3_MCBSP1_IRQ 16 /* McBSP module 1 */
#define OMAP3_MCBSP2_IRQ 17 /* McBSP module 2 */
#define OMAP3_GPMC_IRQ 20 /* General-purpose memory controller */
#define OMAP3_SGX_IRQ 21 /* 2D/3D graphics module */
#define OMAP3_MCBSP3_IRQ 22 /* McBSP module 3 */
#define OMAP3_MCBSP4_IRQ 23 /* McBSP module 4 */
#define OMAP3_CAM0_IRQ 24 /* Camera interface request 0 */
#define OMAP3_DSS_IRQ 25 /* Display subsystem module */
#define OMAP3_MAIL_U0_IRQ 26 /* Mailbox user 0 request */
#define OMAP3_MCBSP5_IRQ 27 /* McBSP module 5 */
#define OMAP3_IVA2_MMU_IRQ 28 /* IVA2 MMU */
#define OMAP3_GPIO1_IRQ 29 /* GPIO module 1 */
#define OMAP3_GPIO2_IRQ 30 /* GPIO module 2 */
#define OMAP3_GPIO3_IRQ 31 /* GPIO module 3 */
#define OMAP3_GPIO4_IRQ 32 /* GPIO module 4 */
#define OMAP3_GPIO5_IRQ 33 /* GPIO module 5 */
#define OMAP3_GPIO6_IRQ 34 /* GPIO module 6 */
#define OMAP3_WDT3_IRQ 36 /* Watchdog timer module 3 overflow */
#define OMAP3_GPT1_IRQ 37 /* General-purpose timer module 1 */
#define OMAP3_GPT2_IRQ 38 /* General-purpose timer module 2 */
#define OMAP3_GPT3_IRQ 39 /* General-purpose timer module 3 */
#define OMAP3_GPT4_IRQ 40 /* General-purpose timer module 4 */
#define OMAP3_GPT5_IRQ 41 /* General-purpose timer module 5 */
#define OMAP3_GPT6_IRQ 42 /* General-purpose timer module 6 */
#define OMAP3_GPT7_IRQ 43 /* General-purpose timer module 7 */
#define OMAP3_GPT8_IRQ 44 /* General-purpose timer module 8 */
#define OMAP3_GPT9_IRQ 45 /* General-purpose timer module 9 */
#define OMAP3_GPT10_IRQ 46 /* General-purpose timer module 10 */
#define OMAP3_GPT11_IRQ 47 /* General-purpose timer module 11 */
#define OMAP3_SPI4_IRQ 48 /* McSPI module 4 */
#define OMAP3_MCBSP4_TX_IRQ 54 /* McBSP module 4 transmit */
#define OMAP3_MCBSP4_RX_IRQ 55 /* McBSP module 4 receive */
#define OMAP3_I2C1_IRQ 56 /* I2C module 1 */
#define OMAP3_I2C2_IRQ 57 /* I2C module 2 */
#define OMAP3_HDQ_IRQ 58 /* HDQ/1-Wire */
#define OMAP3_MCBSP1_TX_IRQ 59 /* McBSP module 1 transmit */
#define OMAP3_MCBSP1_RX_IRQ 60 /* McBSP module 1 receive */
#define OMAP3_I2C3_IRQ 61 /* I2C module 3 */
#define OMAP3_MCBSP2_TX_IRQ 62 /* McBSP module 2 transmit */
#define OMAP3_MCBSP2_RX_IRQ 63 /* McBSP module 2 receive */
#define OMAP3_SPI1_IRQ 65 /* McSPI module 1 */
#define OMAP3_SPI2_IRQ 66 /* McSPI module 2 */
#define OMAP3_UART1_IRQ 72 /* UART module 1 */
#define OMAP3_UART2_IRQ 73 /* UART module 2 */
#define OMAP3_PBIAS_IRQ 75 /* Merged interrupt for PBIASlite 1/2 */
#define OMAP3_OHCI_IRQ 76 /* OHCI HSUSB MP Host Interrupt */
#define OMAP3_EHCI_IRQ 77 /* EHCI HSUSB MP Host Interrupt */
#define OMAP3_TLL_IRQ 78 /* HSUSB MP TLL Interrupt */
#define OMAP3_MCBSP5_TX_IRQ 81 /* McBSP module 5 transmit */
#define OMAP3_MCBSP5_RX_IRQ 82 /* McBSP module 5 receive */
#define OMAP3_MMC1_IRQ 83 /* MMC/SD module 1 */
#define OMAP3_MMC2_IRQ 86 /* MMC/SD module 2 */
#define OMAP3_ICR_IRQ 87 /* MPU ICR */
#define OMAP3_D2DFRINT_IRQ 88 /* 3G coproc (in stacked modem config) */
#define OMAP3_MCBSP3_TX_IRQ 89 /* McBSP module 3 transmit */
#define OMAP3_MCBSP3_RX_IRQ 90 /* McBSP module 3 receive */
#define OMAP3_SPI3_IRQ 91 /* McSPI module 3 */
#define OMAP3_HSUSB_MC_IRQ 92 /* High-speed USB OTG */
#define OMAP3_HSUSB_DMA_IRQ 93 /* High-speed USB OTG DMA */
#define OMAP3_MMC3_IRQ 94 /* MMC/SD module 3 */
#define AM335X_INT_EMUINT 0 /* Emulation interrupt (EMUICINTR) */
#define AM335X_INT_COMMTX 1 /* CortexA8 COMMTX */
#define AM335X_INT_COMMRX 2 /* CortexA8 COMMRX */
#define AM335X_INT_BENCH 3 /* CortexA8 NPMUIRQ */
#define AM335X_INT_ELM_IRQ 4 /* Sinterrupt (Error location process completion) */
#define AM335X_INT_NMI 7 /* nmi_int */
#define AM335X_INT_L3DEBUG 9 /* l3_FlagMux_top_FlagOut1 */
#define AM335X_INT_L3APPINT 10 /* l3_FlagMux_top_FlagOut0 */
#define AM335X_INT_PRCMINT 11 /* irq_mpu */
#define AM335X_INT_EDMACOMPINT 12 /* tpcc_int_pend_po0 */
#define AM335X_INT_EDMAMPERR 13 /* tpcc_mpint_pend_po */
#define AM335X_INT_EDMAERRINT 14 /* tpcc_errint_pend_po */
#define AM335X_INT_ADC_TSC_GENINT 16 /* gen_intr_pend */
#define AM335X_INT_USBSSINT 17 /* usbss_intr_pend */
#define AM335X_INT_USB0 18 /* usb0_intr_pend */
#define AM335X_INT_USB1 19 /* usb1_intr_pend */
#define AM335X_INT_PRUSS1_EVTOUT0 20 /* pr1_host_intr0_intr_pend */
#define AM335X_INT_PRUSS1_EVTOUT1 21 /* pr1_host_intr1_intr_pend */
#define AM335X_INT_PRUSS1_EVTOUT2 22 /* pr1_host_intr2_intr_pend */
#define AM335X_INT_PRUSS1_EVTOUT3 23 /* pr1_host_intr3_intr_pend */
#define AM335X_INT_PRUSS1_EVTOUT4 24 /* pr1_host_intr4_intr_pend */
#define AM335X_INT_PRUSS1_EVTOUT5 25 /* pr1_host_intr5_intr_pend */
#define AM335X_INT_PRUSS1_EVTOUT6 26 /* pr1_host_intr6_intr_pend */
#define AM335X_INT_PRUSS1_EVTOUT7 27 /* pr1_host_intr7_intr_pend */
#define AM335X_INT_MMCSD1INT 28 /* MMCSD1 SINTERRUPTN */
#define AM335X_INT_MMCSD2INT 29 /* MMCSD2 SINTERRUPT */
#define AM335X_INT_I2C2INT 30 /* I2C2 POINTRPEND */
#define AM335X_INT_eCAP0INT 31 /* ecap_intr_intr_pend */
#define AM335X_INT_GPIOINT2A 32 /* GPIO 2 POINTRPEND1 */
#define AM335X_INT_GPIOINT2B 33 /* GPIO 2 POINTRPEND2 */
#define AM335X_INT_USBWAKEUP 34 /* USBSS slv0p_Swakeup */
#define AM335X_INT_LCDCINT 36 /* LCDC lcd_irq */
#define AM335X_INT_GFXINT 37 /* SGX530 THALIAIRQ */
#define AM335X_INT_ePWM2INT 39 /* (PWM Subsystem) epwm_intr_intr_pend */
#define AM335X_INT_3PGSWRXTHR0 40 /* (Ethernet) c0_rx_thresh_pend (RX_THRESH_PULSE) */
#define AM335X_INT_3PGSWRXINT0 41 /* CPSW (Ethernet) c0_rx_pend */
#define AM335X_INT_3PGSWTXINT0 42 /* CPSW (Ethernet) c0_tx_pend */
#define AM335X_INT_3PGSWMISC0 43 /* CPSW (Ethernet) c0_misc_pend */
#define AM335X_INT_UART3INT 44 /* UART3 niq */
#define AM335X_INT_UART4INT 45 /* UART4 niq */
#define AM335X_INT_UART5INT 46 /* UART5 niq */
#define AM335X_INT_eCAP1INT 47 /* (PWM Subsystem) ecap_intr_intr_pend */
#define AM335X_INT_DCAN0_INT0 52 /* DCAN0 dcan_intr0_intr_pend */
#define AM335X_INT_DCAN0_INT1 53 /* DCAN0 dcan_intr1_intr_pend */
#define AM335X_INT_DCAN0_PARITY 54 /* DCAN0 dcan_uerr_intr_pend */
#define AM335X_INT_DCAN1_INT0 55 /* DCAN1 dcan_intr0_intr_pend */
#define AM335X_INT_DCAN1_INT1 56 /* DCAN1 dcan_intr1_intr_pend */
#define AM335X_INT_DCAN1_PARITY 57 /* DCAN1 dcan_uerr_intr_pend */
#define AM335X_INT_ePWM0_TZINT 58 /* eHRPWM0 TZ interrupt (PWM epwm_tz_intr_pend Subsystem) */
#define AM335X_INT_ePWM1_TZINT 59 /* eHRPWM1 TZ interrupt (PWM epwm_tz_intr_pend Subsystem) */
#define AM335X_INT_ePWM2_TZINT 60 /* eHRPWM2 TZ interrupt (PWM epwm_tz_intr_pend Subsystem) */
#define AM335X_INT_eCAP2INT 61 /* eCAP2 (PWM Subsystem) ecap_intr_intr_pend */
#define AM335X_INT_GPIOINT3A 62 /* GPIO 3 POINTRPEND1 */
#define AM335X_INT_GPIOINT3B 63 /* GPIO 3 POINTRPEND2 */
#define AM335X_INT_MMCSD0INT 64 /* MMCSD0 SINTERRUPTN */
#define AM335X_INT_SPI0INT 65 /* McSPI0 SINTERRUPTN */
#define AM335X_INT_TINT0 66 /* Timer0 POINTR_PEND */
#define AM335X_INT_TINT1_1MS 67 /* DMTIMER_1ms POINTR_PEND */
#define AM335X_INT_TINT2 68 /* DMTIMER2 POINTR_PEND */
#define AM335X_INT_TINT3 69 /* DMTIMER3 POINTR_PEND */
#define AM335X_INT_I2C0INT 70 /* I2C0 POINTRPEND */
#define AM335X_INT_I2C1INT 71 /* I2C1 POINTRPEND */
#define AM335X_INT_UART0INT 72 /* UART0 niq */
#define AM335X_INT_UART1INT 73 /* UART1 niq */
#define AM335X_INT_UART2INT 74 /* UART2 niq */
#define AM335X_INT_RTCINT 75 /* RTC timer_intr_pend */
#define AM335X_INT_RTCALARMINT 76 /* RTC alarm_intr_pend */
#define AM335X_INT_MBINT0 77 /* Mailbox0 (mail_u0_irq) initiator_sinterrupt_q_n */
#define AM335X_INT_M3_TXEV 78 /* Wake M3 Subsystem TXEV */
#define AM335X_INT_eQEP0INT 79 /* eQEP0 (PWM Subsystem) eqep_intr_intr_pend */
#define AM335X_INT_MCATXINT0 80 /* McASP0 mcasp_x_intr_pend */
#define AM335X_INT_MCARXINT0 81 /* McASP0 mcasp_r_intr_pend */
#define AM335X_INT_MCATXINT1 82 /* McASP1 mcasp_x_intr_pend */
#define AM335X_INT_MCARXINT1 83 /* McASP1 mcasp_r_intr_pend */
#define AM335X_INT_ePWM0INT 86 /* (PWM Subsystem) epwm_intr_intr_pend */
#define AM335X_INT_ePWM1INT 87 /* (PWM Subsystem) epwm_intr_intr_pend */
#define AM335X_INT_eQEP1INT 88 /* (PWM Subsystem) eqep_intr_intr_pend */
#define AM335X_INT_eQEP2INT 89 /* (PWM Subsystem) eqep_intr_intr_pend */
#define AM335X_INT_DMA_INTR_PIN2 90 /* External DMA/Interrupt Pin2 pi_x_dma_event_intr2 (xdma_event_intr2) */
#define AM335X_INT_WDT1INT 91 /* (Public Watchdog) WDTIMER1 PO_INT_PEND */
#define AM335X_INT_TINT4 92 /* DMTIMER4 POINTR_PEN */
#define AM335X_INT_TINT5 93 /* DMTIMER5 POINTR_PEN */
#define AM335X_INT_TINT6 94 /* DMTIMER6 POINTR_PEND */
#define AM335X_INT_TINT7 95 /* DMTIMER7 POINTR_PEND */
#define AM335X_INT_GPIOINT0A 96 /* GPIO 0 POINTRPEND1 */
#define AM335X_INT_GPIOINT0B 97 /* GPIO 0 POINTRPEND2 */
#define AM335X_INT_GPIOINT1A 98 /* GPIO 1 POINTRPEND1 */
#define AM335X_INT_GPIOINT1B 99 /* GPIO 1 POINTRPEND2 */
#define AM335X_INT_GPMCINT 100 /* GPMC gpmc_sinterrupt */
#define AM335X_INT_DDRERR0 101 /* EMIF sys_err_intr_pend */
#define AM335X_INT_TCERRINT0 112 /* TPTC0 tptc_erint_pend_po */
#define AM335X_INT_TCERRINT1 113 /* TPTC1 tptc_erint_pend_po */
#define AM335X_INT_TCERRINT2 114 /* TPTC2 tptc_erint_pend_po */
#define AM335X_INT_ADC_TSC_PENINT 115 /* ADC_TSC pen_intr_pend */
#define AM335X_INT_SMRFLX_Sabertooth 120 /* Smart Reflex 0 intrpen */
#define AM335X_INT_SMRFLX_Core 121 /* Smart Reflex 1 intrpend */
#define AM335X_INT_DMA_INTR_PIN0 123 /* pi_x_dma_event_intr0 (xdma_event_intr0) */
#define AM335X_INT_DMA_INTR_PIN1 124 /* pi_x_dma_event_intr1 (xdma_event_intr1) */
#define AM335X_INT_SPI1INT 125 /* McSPI1 SINTERRUPTN */
#define OMAP3_AM335X_NR_IRQ_VECTORS 125
#endif /* _OMAP_INTR_H */
#endif /* _RPI_INTR_H */

View File

@@ -15,131 +15,47 @@
#include "bsp_intr.h"
/* interrupt handler hook */
static irq_hook_t omap3_timer_hook;
static irq_hook_t rpi_timer_hook;
static u32_t counts_per_hz = ~0;
static u64_t high_frc;
struct omap_timer_registers;
struct rpi_timer_registers;
struct omap_timer
struct bcm2835_timer
{
vir_bytes base;
int irq_nr;
struct omap_timer_registers *regs;
struct rpi_timer_registers *regs;
};
struct omap_timer_registers
struct rpi_timer_registers
{
vir_bytes TIDR;
vir_bytes TIOCP_CFG;
vir_bytes TISTAT;
vir_bytes TISR;
vir_bytes TIER;
vir_bytes TWER;
vir_bytes TCLR;
vir_bytes TCRR;
vir_bytes TLDR;
vir_bytes TTGR;
vir_bytes TWPS;
vir_bytes TMAR;
vir_bytes TCAR1;
vir_bytes TSICR;
vir_bytes TCAR2;
vir_bytes TPIR;
vir_bytes TNIR;
vir_bytes TCVR;
vir_bytes TOCR;
vir_bytes TOWR;
vir_bytes STCLO;
vir_bytes STC3;
};
static struct omap_timer_registers regs_v1 = {
.TIDR = OMAP3_TIMER_TIDR,
.TIOCP_CFG = OMAP3_TIMER_TIOCP_CFG,
.TISTAT = OMAP3_TIMER_TISTAT,
.TISR = OMAP3_TIMER_TISR,
.TIER = OMAP3_TIMER_TIER,
.TWER = OMAP3_TIMER_TWER,
.TCLR = OMAP3_TIMER_TCLR,
.TCRR = OMAP3_TIMER_TCRR,
.TLDR = OMAP3_TIMER_TLDR,
.TTGR = OMAP3_TIMER_TTGR,
.TWPS = OMAP3_TIMER_TWPS,
.TMAR = OMAP3_TIMER_TMAR,
.TCAR1 = OMAP3_TIMER_TCAR1,
.TSICR = OMAP3_TIMER_TSICR,
.TCAR2 = OMAP3_TIMER_TCAR2,
.TPIR = OMAP3_TIMER_TPIR,
.TNIR = OMAP3_TIMER_TNIR,
.TCVR = OMAP3_TIMER_TCVR,
.TOCR = OMAP3_TIMER_TOCR,
.TOWR = OMAP3_TIMER_TOWR,
static struct rpi_timer_registers regs_v1 =
{
.STCLO = BCM2835_STIMER_CLO,
.STC3 = BCM2835_STIMER_C3,
};
/* AM335X has a different ip block for the non
1ms timers */
static struct omap_timer_registers regs_v2 = {
.TIDR = AM335X_TIMER_TIDR,
.TIOCP_CFG = AM335X_TIMER_TIOCP_CFG,
.TISTAT = AM335X_TIMER_IRQSTATUS_RAW,
.TISR = AM335X_TIMER_IRQSTATUS,
.TIER = AM335X_TIMER_IRQENABLE_SET,
.TWER = AM335X_TIMER_IRQWAKEEN,
.TCLR = AM335X_TIMER_TCLR,
.TCRR = AM335X_TIMER_TCRR,
.TLDR = AM335X_TIMER_TLDR,
.TTGR = AM335X_TIMER_TTGR,
.TWPS = AM335X_TIMER_TWPS,
.TMAR = AM335X_TIMER_TMAR,
.TCAR1 = AM335X_TIMER_TCAR1,
.TSICR = AM335X_TIMER_TSICR,
.TCAR2 = AM335X_TIMER_TCAR2,
.TPIR = -1, /* UNDEF */
.TNIR = -1, /* UNDEF */
.TCVR = -1, /* UNDEF */
.TOCR = -1, /* UNDEF */
.TOWR = -1 /* UNDEF */
};
static struct omap_timer dm37xx_timer = {
.base = OMAP3_GPTIMER1_BASE,
.irq_nr = OMAP3_GPT1_IRQ,
static struct bcm2835_timer rpi_timer = {
.base = BCM2835_STIMER_BASE,
.irq_nr = BCM2835_INT_TIMER3,
.regs = &regs_v1
};
/* free running timer */
static struct omap_timer dm37xx_fr_timer = {
.base = OMAP3_GPTIMER10_BASE,
.irq_nr = OMAP3_GPT10_IRQ,
.regs = &regs_v1
};
/* normal timer */
static struct omap_timer am335x_timer = {
.base = AM335X_DMTIMER1_1MS_BASE,
.irq_nr = AM335X_INT_TINT1_1MS,
.regs = &regs_v1
};
/* free running timer */
static struct omap_timer am335x_fr_timer = {
.base = AM335X_DMTIMER7_BASE,
.irq_nr = AM335X_INT_TINT7,
.regs = &regs_v2
};
static struct omap_timer *timer;
static struct omap_timer *fr_timer;
static int done = 0;
static struct bcm2835_timer *timer;
int
bsp_register_timer_handler(const irq_handler_t handler)
{
/* Initialize the CLOCK's interrupt hook. */
omap3_timer_hook.proc_nr_e = NONE;
omap3_timer_hook.irq = timer->irq_nr;
rpi_timer_hook.proc_nr_e = NONE;
rpi_timer_hook.irq = timer->irq_nr;
put_irq_handler(&omap3_timer_hook, timer->irq_nr, handler);
put_irq_handler(&rpi_timer_hook, timer->irq_nr, handler);
/* only unmask interrupts after registering */
bsp_irq_unmask(timer->irq_nr);
@@ -148,250 +64,36 @@ bsp_register_timer_handler(const irq_handler_t handler)
/* meta data for remapping */
static kern_phys_map timer_phys_map;
static kern_phys_map fr_timer_phys_map;
static kern_phys_map fr_timer_user_phys_map; /* struct for when the free */
/* running timer is mapped to */
/* userland */
/* callback for when the free running clock gets mapped */
int
kern_phys_fr_user_mapped(vir_bytes id, phys_bytes address)
{
/* the only thing we need to do at this stage is to set the address */
/* in the kerninfo struct */
if (BOARD_IS_BBXM(machine.board_id)) {
minix_kerninfo.minix_frclock_tcrr = address + OMAP3_TIMER_TCRR;
minix_kerninfo.minix_arm_frclock_hz = 1625000;
} else if (BOARD_IS_BB(machine.board_id)) {
minix_kerninfo.minix_frclock_tcrr =
address + AM335X_TIMER_TCRR;
minix_kerninfo.minix_arm_frclock_hz = 1500000;
}
return 0;
}
void
omap3_frclock_init(void)
{
u32_t tisr;
/* enable the clock */
if (BOARD_IS_BBXM(machine.board_id)) {
fr_timer = &dm37xx_fr_timer;
kern_phys_map_ptr(fr_timer->base, ARM_PAGE_SIZE,
VMMF_UNCACHED | VMMF_WRITE, &fr_timer_phys_map,
(vir_bytes) & fr_timer->base);
/* the timer is also mapped in user space hence the this */
/* second mapping and callback to set kerninfo frclock_tcrr */
kern_req_phys_map(fr_timer->base, ARM_PAGE_SIZE,
VMMF_UNCACHED | VMMF_USER,
&fr_timer_user_phys_map, kern_phys_fr_user_mapped, 0);
/* Stop timer */
mmio_clear(fr_timer->base + fr_timer->regs->TCLR,
OMAP3_TCLR_ST);
/* Use functional clock source for GPTIMER10 */
mmio_set(OMAP3_CM_CLKSEL_CORE, OMAP3_CLKSEL_GPT10);
/* Scale timer down to 13/8 = 1.625 Mhz to roughly get
* microsecond ticks */
/* The scale is computed as 2^(PTV+1). So if PTV == 2, we get
* 2^3 = 8. */
mmio_set(fr_timer->base + fr_timer->regs->TCLR,
(2 << OMAP3_TCLR_PTV));
} else if (BOARD_IS_BB(machine.board_id)) {
fr_timer = &am335x_fr_timer;
kern_phys_map_ptr(fr_timer->base, ARM_PAGE_SIZE,
VMMF_UNCACHED | VMMF_WRITE,
&fr_timer_phys_map, (vir_bytes) & fr_timer->base);
/* the timer is also mapped in user space hence the this */
/* second mapping and callback to set kerninfo frclock_tcrr */
kern_req_phys_map(fr_timer->base, ARM_PAGE_SIZE,
VMMF_UNCACHED | VMMF_USER,
&fr_timer_user_phys_map, kern_phys_fr_user_mapped, 0);
/* Disable the module and wait for the module to be disabled */
set32(CM_PER_TIMER7_CLKCTRL, CM_MODULEMODE_MASK,
CM_MODULEMODE_DISABLED);
while ((mmio_read(CM_PER_TIMER7_CLKCTRL) & CM_CLKCTRL_IDLEST)
!= CM_CLKCTRL_IDLEST_DISABLE);
set32(CLKSEL_TIMER7_CLK, CLKSEL_TIMER7_CLK_SEL_MASK,
CLKSEL_TIMER7_CLK_SEL_SEL2);
while ((read32(CLKSEL_TIMER7_CLK) & CLKSEL_TIMER7_CLK_SEL_MASK)
!= CLKSEL_TIMER7_CLK_SEL_SEL2);
/* enable the module and wait for the module to be ready */
set32(CM_PER_TIMER7_CLKCTRL, CM_MODULEMODE_MASK,
CM_MODULEMODE_ENABLE);
while ((mmio_read(CM_PER_TIMER7_CLKCTRL) & CM_CLKCTRL_IDLEST)
!= CM_CLKCTRL_IDLEST_FUNC);
/* Stop timer */
mmio_clear(fr_timer->base + fr_timer->regs->TCLR,
OMAP3_TCLR_ST);
/* 24Mhz / 16 = 1.5 Mhz */
mmio_set(fr_timer->base + fr_timer->regs->TCLR,
(3 << OMAP3_TCLR_PTV));
}
/* Start and auto-reload at 0 */
mmio_write(fr_timer->base + fr_timer->regs->TLDR, 0x0);
mmio_write(fr_timer->base + fr_timer->regs->TCRR, 0x0);
/* Set up overflow interrupt */
tisr = OMAP3_TISR_MAT_IT_FLAG | OMAP3_TISR_OVF_IT_FLAG |
OMAP3_TISR_TCAR_IT_FLAG;
/* Clear interrupt status */
mmio_write(fr_timer->base + fr_timer->regs->TISR, tisr);
mmio_write(fr_timer->base + fr_timer->regs->TIER,
OMAP3_TIER_OVF_IT_ENA);
/* Start timer */
mmio_set(fr_timer->base + fr_timer->regs->TCLR,
OMAP3_TCLR_OVF_TRG | OMAP3_TCLR_AR | OMAP3_TCLR_ST |
OMAP3_TCLR_PRE);
done = 1;
}
void
omap3_frclock_stop()
{
mmio_clear(fr_timer->base + fr_timer->regs->TCLR, OMAP3_TCLR_ST);
}
void
bsp_timer_init(unsigned freq)
{
/* we only support 1ms resolution */
u32_t tisr;
if (BOARD_IS_BBXM(machine.board_id)) {
timer = &dm37xx_timer;
if ( BOARD_IS_RPI(machine.board_id))
{
u32_t stclo;
timer = &rpi_timer;
counts_per_hz = BCM2835_STIMER_HZ / freq;
kern_phys_map_ptr(timer->base, ARM_PAGE_SIZE,
VMMF_UNCACHED | VMMF_WRITE,
&timer_phys_map, (vir_bytes) & timer->base);
/* Stop timer */
mmio_clear(timer->base + timer->regs->TCLR, OMAP3_TCLR_ST);
/* Use 32 KHz clock source for GPTIMER1 */
mmio_clear(OMAP3_CM_CLKSEL_WKUP, OMAP3_CLKSEL_GPT1);
} else if (BOARD_IS_BB(machine.board_id)) {
timer = &am335x_timer;
kern_phys_map_ptr(timer->base, ARM_PAGE_SIZE,
VMMF_UNCACHED | VMMF_WRITE,
&timer_phys_map, (vir_bytes) & timer->base);
/* disable the module and wait for the module to be disabled */
set32(CM_WKUP_TIMER1_CLKCTRL, CM_MODULEMODE_MASK,
CM_MODULEMODE_DISABLED);
while ((mmio_read(CM_WKUP_TIMER1_CLKCTRL) & CM_CLKCTRL_IDLEST)
!= CM_CLKCTRL_IDLEST_DISABLE);
set32(CLKSEL_TIMER1MS_CLK, CLKSEL_TIMER1MS_CLK_SEL_MASK,
CLKSEL_TIMER1MS_CLK_SEL_SEL2);
while ((read32(CLKSEL_TIMER1MS_CLK) &
CLKSEL_TIMER1MS_CLK_SEL_MASK) !=
CLKSEL_TIMER1MS_CLK_SEL_SEL2);
/* enable the module and wait for the module to be ready */
set32(CM_WKUP_TIMER1_CLKCTRL, CM_MODULEMODE_MASK,
CM_MODULEMODE_ENABLE);
while ((mmio_read(CM_WKUP_TIMER1_CLKCTRL) & CM_CLKCTRL_IDLEST)
!= CM_CLKCTRL_IDLEST_FUNC);
/* Stop timer */
mmio_clear(timer->base + timer->regs->TCLR, OMAP3_TCLR_ST);
stclo = mmio_read( timer->base + timer->regs->STCLO );
stclo += counts_per_hz;
mmio_write( timer->base + timer->regs->STC3, stclo );
frclock_init();
}
/* Use 1-ms tick mode for GPTIMER1 TRM 16.2.4.2.1 */
mmio_write(timer->base + timer->regs->TPIR, 232000);
mmio_write(timer->base + timer->regs->TNIR, -768000);
mmio_write(timer->base + timer->regs->TLDR,
0xffffffff - (32768 / freq) + 1);
mmio_write(timer->base + timer->regs->TCRR,
0xffffffff - (32768 / freq) + 1);
/* Set up overflow interrupt */
tisr = OMAP3_TISR_MAT_IT_FLAG | OMAP3_TISR_OVF_IT_FLAG |
OMAP3_TISR_TCAR_IT_FLAG;
/* Clear interrupt status */
mmio_write(timer->base + timer->regs->TISR, tisr);
mmio_write(timer->base + timer->regs->TIER, OMAP3_TIER_OVF_IT_ENA);
/* Start timer */
mmio_set(timer->base + timer->regs->TCLR,
OMAP3_TCLR_OVF_TRG | OMAP3_TCLR_AR | OMAP3_TCLR_ST);
/* also initilize the free runnning timer */
omap3_frclock_init();
}
void
bsp_timer_stop()
{
mmio_clear(timer->base + timer->regs->TCLR, OMAP3_TCLR_ST);
}
static u32_t
read_frc(void)
{
if (done == 0) {
return 0;
}
return mmio_read(fr_timer->base + fr_timer->regs->TCRR);
}
/*
* Check if the free running clock has overflown and
* increase the high free running clock counter if
* so. This method takes the current timer value as
* parameter to ensure the overflow check is done
* on the current timer value.
*
* To compose the current timer value (64 bits) you
* need to follow the following sequence:
* read the current timer value.
* call the overflow check
* compose the 64 bits time based on the current timer value
* and high_frc.
*/
static void
frc_overflow_check(u32_t cur_frc)
{
static int prev_frc_valid;
static u32_t prev_frc;
if (prev_frc_valid && prev_frc > cur_frc) {
high_frc++;
}
prev_frc = cur_frc;
prev_frc_valid = 1;
}
void
bsp_timer_int_handler()
{
/* Clear all interrupts */
u32_t tisr, now;
/* when the kernel itself is running interrupts are disabled. We
* should therefore also read the overflow counter to detect this as
* to not miss events. */
tisr = OMAP3_TISR_MAT_IT_FLAG | OMAP3_TISR_OVF_IT_FLAG |
OMAP3_TISR_TCAR_IT_FLAG;
mmio_write(timer->base + timer->regs->TISR, tisr);
now = read_frc();
frc_overflow_check(now);
u32_t stclo;
stclo = mmio_read( timer->base + timer->regs->STCLO );
stclo += counts_per_hz;
mmio_write( timer->base + timer->regs->STC3, stclo );
}
/* Use the free running clock as TSC */
void
read_tsc_64(u64_t * t)
{
u32_t now;
now = read_frc();
frc_overflow_check(now);
*t = (u64_t) now + (high_frc << 32);
}

View File

@@ -1,68 +1,15 @@
#ifndef _OMAP_TIMER_REGISTERS_H
#define _OMAP_TIMER_REGISTERS_H
#ifndef _RPI_TIMER_REGISTERS_H
#define _RPI_TIMER_REGISTERS_H
#define BCM2835_STIMER_HZ 1000000
/* General-purpose timer register map */
#define OMAP3_GPTIMER1_BASE 0x48318000 /* GPTIMER1 physical address */
#define OMAP3_GPTIMER2_BASE 0x49032000 /* GPTIMER2 physical address */
#define OMAP3_GPTIMER3_BASE 0x49034000 /* GPTIMER3 physical address */
#define OMAP3_GPTIMER4_BASE 0x49036000 /* GPTIMER4 physical address */
#define OMAP3_GPTIMER5_BASE 0x49038000 /* GPTIMER5 physical address */
#define OMAP3_GPTIMER6_BASE 0x4903A000 /* GPTIMER6 physical address */
#define OMAP3_GPTIMER7_BASE 0x4903C000 /* GPTIMER7 physical address */
#define OMAP3_GPTIMER8_BASE 0x4903E000 /* GPTIMER8 physical address */
#define OMAP3_GPTIMER9_BASE 0x49040000 /* GPTIMER9 physical address */
#define OMAP3_GPTIMER10_BASE 0x48086000 /* GPTIMER10 physical address */
#define OMAP3_GPTIMER11_BASE 0x48088000 /* GPTIMER11 physical address */
#define BCM2835_STIMER_BASE 0x20003000 /* System Timer */
/* General-purpose timer registers */
#define OMAP3_TIMER_TIDR 0x000 /* IP revision code */
#define OMAP3_TIMER_TIOCP_CFG 0x010 /* Controls params for GP timer L4 interface */
#define OMAP3_TIMER_TISTAT 0x014 /* Status (excl. interrupt status) */
#define OMAP3_TIMER_TISR 0x018 /* Pending interrupt status */
#define OMAP3_TIMER_TIER 0x01C /* Interrupt enable */
#define OMAP3_TIMER_TWER 0x020 /* Wakeup enable */
#define OMAP3_TIMER_TCLR 0x024 /* Controls optional features */
#define OMAP3_TIMER_TCRR 0x028 /* Internal counter value */
#define OMAP3_TIMER_TLDR 0x02C /* Timer load value */
#define OMAP3_TIMER_TTGR 0x030 /* Triggers counter reload */
#define OMAP3_TIMER_TWPS 0x034 /* Indicates if Write-Posted pending */
#define OMAP3_TIMER_TMAR 0x038 /* Value to be compared with counter */
#define OMAP3_TIMER_TCAR1 0x03C /* First captured value of counter register */
#define OMAP3_TIMER_TSICR 0x040 /* Control posted mode and functional SW reset */
#define OMAP3_TIMER_TCAR2 0x044 /* Second captured value of counter register */
#define OMAP3_TIMER_TPIR 0x048 /* Positive increment (1 ms tick) */
#define OMAP3_TIMER_TNIR 0x04C /* Negative increment (1 ms tick) */
#define OMAP3_TIMER_TCVR 0x050 /* Defines TCRR is sub/over-period (1 ms tick) */
#define OMAP3_TIMER_TOCR 0x054 /* Masks tick interrupt */
#define OMAP3_TIMER_TOWR 0x058 /* Number of masked overflow interrupts */
#define AM335X_DMTIMER0_BASE 0x44E05000 /* DMTimer0 Registers */
#define AM335X_DMTIMER1_1MS_BASE 0x44E31000 /* DMTimer1 1ms Registers (Accurate 1ms timer) */
#define AM335X_DMTIMER2_BASE 0x48040000 /* DMTimer2 Registers */
#define AM335X_DMTIMER3_BASE 0x48042000 /* DMTimer3 Registers */
#define AM335X_DMTIMER4_BASE 0x48044000 /* DMTimer4 Registers */
#define AM335X_DMTIMER5_BASE 0x48046000 /* DMTimer5 Registers */
#define AM335X_DMTIMER6_BASE 0x48048000 /* DMTimer6 Registers */
#define AM335X_DMTIMER7_BASE 0x4804A000 /* DMTimer7 Registers */
/* General-purpose timer registers AM335x non 1MS timers have different offsets */
#define AM335X_TIMER_TIDR 0x000 /* IP revision code */
#define AM335X_TIMER_TIOCP_CFG 0x010 /* Controls params for GP timer L4 interface */
#define AM335X_TIMER_IRQSTATUS_RAW 0x024 /* Timer IRQSTATUS Raw Register */
#define AM335X_TIMER_IRQSTATUS 0x028 /* Timer IRQSTATUS Register */
#define AM335X_TIMER_IRQENABLE_SET 0x02C /* Timer IRQENABLE Set Register */
#define AM335X_TIMER_IRQENABLE_CLR 0x030 /* Timer IRQENABLE Clear Register */
#define AM335X_TIMER_IRQWAKEEN 0x034 /* Timer IRQ Wakeup Enable Register */
#define AM335X_TIMER_TCLR 0x038 /* Controls optional features */
#define AM335X_TIMER_TCRR 0x03C /* Internal counter value */
#define AM335X_TIMER_TLDR 0x040 /* Timer load value */
#define AM335X_TIMER_TTGR 0x044 /* Triggers counter reload */
#define AM335X_TIMER_TWPS 0x048 /* Indicates if Write-Posted pending */
#define AM335X_TIMER_TMAR 0x04C /* Value to be compared with counter */
#define AM335X_TIMER_TCAR1 0x050 /* First captured value of counter register */
#define AM335X_TIMER_TSICR 0x054 /* Control posted mode and functional SW reset */
#define AM335X_TIMER_TCAR2 0x058 /* Second captured value of counter register */
#define BCM2835_STIMER_CLO 0x04 /* System Timer Counter Lower 32 bits */
#define BCM2835_STIMER_C3 0x18 /* System Timer Compare 3 */
#define RPI_WDT_BASE 0x20100000 /* watchdog timer */
#define RPI_PM_RSTC 0x1c
@@ -73,89 +20,4 @@
#define RPI_PM_RSTC_FULL_RESET 0x00000020
#define RPI_PM_WDOG_TIMEMASK 0x000fffff
/* Interrupt status register fields */
#define OMAP3_TISR_MAT_IT_FLAG (1 << 0) /* Pending match interrupt status */
#define OMAP3_TISR_OVF_IT_FLAG (1 << 1) /* Pending overflow interrupt status */
#define OMAP3_TISR_TCAR_IT_FLAG (1 << 2) /* Pending capture interrupt status */
/* Interrupt enable register fields */
#define OMAP3_TIER_MAT_IT_ENA (1 << 0) /* Enable match interrupt */
#define OMAP3_TIER_OVF_IT_ENA (1 << 1) /* Enable overflow interrupt */
#define OMAP3_TIER_TCAR_IT_ENA (1 << 2) /* Enable capture interrupt */
/* Timer control fields */
#define OMAP3_TCLR_ST (1 << 0) /* Start/stop timer */
#define OMAP3_TCLR_AR (1 << 1) /* Autoreload or one-shot mode */
#define OMAP3_TCLR_PRE (1 << 5) /* Prescaler on */
#define OMAP3_TCLR_PTV 2
#define OMAP3_TCLR_OVF_TRG (1 << 10) /* Overflow trigger */
#define OMAP3_CM_CLKSEL_GFX 0x48004b40
#define OMAP3_CM_CLKEN_PLL 0x48004d00
#define OMAP3_CM_FCLKEN1_CORE 0x48004A00
#define OMAP3_CM_CLKSEL_CORE 0x48004A40 /* GPT10 src clock sel. */
#define OMAP3_CM_FCLKEN_PER 0x48005000
#define OMAP3_CM_CLKSEL_PER 0x48005040
#define OMAP3_CM_CLKSEL_WKUP 0x48004c40 /* GPT1 source clock selection */
#define CM_MODULEMODE_MASK (0x3 << 0)
#define CM_MODULEMODE_ENABLE (0x2 << 0)
#define CM_MODULEMODE_DISABLED (0x0 << 0)
#define CM_CLKCTRL_IDLEST (0x3 << 16)
#define CM_CLKCTRL_IDLEST_FUNC (0x0 << 16)
#define CM_CLKCTRL_IDLEST_TRANS (0x1 << 16)
#define CM_CLKCTRL_IDLEST_IDLE (0x2 << 16)
#define CM_CLKCTRL_IDLEST_DISABLE (0x3 << 16)
#define CM_WKUP_BASE 0x44E00400 /* Clock Module Wakeup Registers */
#define CM_WKUP_TIMER1_CLKCTRL (CM_WKUP_BASE + 0xC4) /* This register manages the TIMER1 clocks. [Memory Mapped] */
#define CM_PER_BASE 0x44E00000 /* Clock Module Peripheral Registers */
#define CM_PER_TIMER7_CLKCTRL (CM_PER_BASE + 0x7C) /* This register manages the TIMER7 clocks. [Memory Mapped] */
/* CM_DPLL registers */
#define CM_DPLL_BASE 0x44E00500 /* Clock Module PLL Registers */
#define CLKSEL_TIMER1MS_CLK (CM_DPLL_BASE + 0x28)
#define CLKSEL_TIMER1MS_CLK_SEL_MASK (0x7 << 0)
#define CLKSEL_TIMER1MS_CLK_SEL_SEL1 (0x0 << 0) /* Select CLK_M_OSC clock */
#define CLKSEL_TIMER1MS_CLK_SEL_SEL2 (0x1 << 0) /* Select CLK_32KHZ clock */
#define CLKSEL_TIMER1MS_CLK_SEL_SEL3 (0x2 << 0) /* Select TCLKIN clock */
#define CLKSEL_TIMER1MS_CLK_SEL_SEL4 (0x3 << 0) /* Select CLK_RC32K clock */
#define CLKSEL_TIMER1MS_CLK_SEL_SEL5 (0x4 << 0) /* Selects the CLK_32768 from 32KHz Crystal Osc */
#define CLKSEL_TIMER7_CLK (CM_DPLL_BASE + 0x04)
#define CLKSEL_TIMER7_CLK_SEL_MASK (0x3 << 0)
#define CLKSEL_TIMER7_CLK_SEL_SEL1 (0x0 << 0) /* Select TCLKIN clock */
#define CLKSEL_TIMER7_CLK_SEL_SEL2 (0x1 << 0) /* Select CLK_M_OSC clock */
#define CLKSEL_TIMER7_CLK_SEL_SEL3 (0x2 << 0) /* Select CLK_32KHZ clock */
#define CLKSEL_TIMER7_CLK_SEL_SEL4 (0x3 << 0) /* Reserved */
#define OMAP3_CLKSEL_GPT1 (1 << 0) /* Selects GPTIMER 1 source
* clock:
*
* 0: use 32KHz clock
* 1: sys clock)
*/
#define OMAP3_CLKSEL_GPT10 (1 << 6)
#define OMAP3_CLKSEL_GPT11 (1 << 7)
#define TIMER_FREQ 1000 /* clock frequency for OMAP timer (1ms) */
#define TIMER_COUNT(freq) (TIMER_FREQ/(freq)) /* initial value for counter*/
#endif /* _OMAP_TIMER_REGISTERS_H */
#endif /* _RPI_TIMER_REGISTERS_H */

View File

@@ -6,6 +6,7 @@
#define PMU_PMCNTENSET_C (1 << 31) /* Enable PMCCNTR cycle counter */
/* ARM ARM B4.1.117 PMCR */
#define PMU_PMCR_CCR (1 << 10)
#define PMU_PMCR_DP (1 << 5) /* Disable when ev. cnt. prohibited */
#define PMU_PMCR_X (1 << 4) /* Export enable */
#define PMU_PMCR_D (1 << 3) /* Clock divider */

View File

@@ -33,7 +33,7 @@ static inline void dsb(void)
/* Instruction synchronization barrier */
static inline void isb(void)
{
asm volatile("mcr p15, 0, %0, c7, c5, 4" : : "r" (0) : "memory");
asm volatile("mcr p15, 0, %0, c7, c5, 4" : : "r" (0) : "memory");
}
static inline void barrier(void)
@@ -475,4 +475,13 @@ static inline void write_cpsr(u32_t status)
: : [status] "r" (status));
}
static inline void frclock_init()
{
u32_t pmcctl = ARM_PMCCTL_E | ARM_PMCCTL_P | ARM_PMCCTL_C;
/* Setup for ArmV6*/
asm volatile("mcr p15, 0, %[pmcctl], c15, c12, 1 @ Write PMCCTL\n\t"
: : [pmcctl] "r" (pmcctl));
}
#endif /* _ARM_CPUFUNC_H */

View File

@@ -218,10 +218,10 @@ void vm_enable_paging(void)
sctlr |= CPU_CONTROL_MMU_ENABLE;
/* TRE set to zero (default reset value): TEX[2:0] are used, plus C and B bits.*/
//sctlr &= ~CPU_CONTROL_TR_ENABLE;
sctlr &= ~CPU_CONTROL_TR_ENABLE;
/* AFE set to zero (default reset value): not using simplified model. */
//sctlr &= ~CPU_CONTROL_AF_ENABLE;
sctlr &= ~CPU_CONTROL_AF_ENABLE;
/* Enable instruction ,data cache and branch prediction */
sctlr |= CPU_CONTROL_DC_ENABLE;

View File

@@ -676,3 +676,8 @@ static void ser_init(void)
outb(COM1_LCR, lcr);
}
#endif
void announce_by_arch(void)
{
}

View File

@@ -497,7 +497,7 @@ static void statmsg(message *msg, struct proc *srcp, struct proc *dstp)
static int lastprint;
/* Stat message. */
assert(src);
assert(srcp);
proc2slot(srcp, src);
proc2slot(dstp, dst);
messages[src][dst]++;

View File

@@ -47,7 +47,7 @@
#define DEBUG_DUMPIPC 0
/* If defined, restrict DEBUG_DUMPIPC to particular process names */
/* #define DEBUG_DUMPIPC_NAMES { "tty", "inet" } */
#define DEBUG_DUMPIPC_NAMES { "tty", "mfs", "vm", "pfs", "init" }
/* DEBUG_IPCSTATS collects information on who sends messages to whom. */
#define DEBUG_IPCSTATS 0

View File

@@ -336,6 +336,7 @@ static void announce(void)
"Copyright 2014, Vrije Universiteit, Amsterdam, The Netherlands\n",
OS_RELEASE);
printf("MINIX is open source software, see http://www.minix3.org\n");
announce_by_arch();
}
/*===========================================================================*

View File

@@ -227,6 +227,9 @@ void busy_delay_ms(int ms);
/* utility.c */
void cpu_print_freq(unsigned cpu);
void announce_by_arch(void);
void arch_read_tsc_64(u64_t *t );
#endif /* __kernel__ */
#endif /* PROTO_H */

View File

@@ -13,7 +13,7 @@
#include <string.h>
#include <minix/sys_config.h>
#include "direct_utils.h"
#define ARE_PANICING 0xDEADC0FF
/*===========================================================================*
@@ -22,6 +22,7 @@
void panic(const char *fmt, ...)
{
va_list arg;
/* The system has run aground of a fatal kernel error. Terminate execution. */
if (kinfo.minix_panicing == ARE_PANICING) {
reset();

View File

@@ -1,5 +0,0 @@
C_HERE=${NETBSDSRCDIR}/minix/lib/libc/arch/${ARCHSUBDIR}
.PATH: ${C_HERE}
SRCS+= get_bp.S \
read_tsc.c

View File

@@ -0,0 +1,5 @@
C_HERE=${NETBSDSRCDIR}/minix/lib/libc/arch/${MACHINE_ARCH}
.PATH: ${C_HERE}
SRCS+= get_bp.S \
read_tsc.c

View File

@@ -1,5 +1,5 @@
# rts sources
HERE=${NETBSDSRCDIR}/minix/lib/libc/arch/${ARCHSUBDIR}/sys
HERE=${NETBSDSRCDIR}/minix/lib/libc/arch/${MACHINE_ARCH}/sys
.PATH: ${HERE}
TMP=ucontextoffsets.h.tmp

View File

@@ -0,0 +1,5 @@
C_HERE=${NETBSDSRCDIR}/minix/lib/libc/arch/${MACHINE_ARCH}
.PATH: ${C_HERE}
SRCS+= get_bp.S \
read_tsc.c

View File

@@ -0,0 +1,10 @@
/* get_bp.s */
/* */
/* return fp in r0 */
/* */
#include <machine/asm.h>
ENTRY(get_bp)
mov r0, fp
bx lr

View File

@@ -0,0 +1,17 @@
#include <sys/types.h>
#include <minix/minlib.h>
void
read_tsc(u32_t *hi, u32_t *lo)
{
/* Read Clock Cycle Counter (CCNT). Intel calls it Time Stamp Counter (TSC) */
u32_t ccnt;
/* Setup for ArmV6*/
asm volatile ("MRC p15, 0, %0, c15, c12, 1\t\n" : "=r" (ccnt) : : "%0");
/* The ARMv7-A clock cycle counter is only 32-bits, but read_tsc is
* expected to return a 64-bit value. hi is therefore always 0.
*/
*hi = 0;
*lo = ccnt;
}

View File

@@ -0,0 +1,28 @@
# rts sources
HERE=${NETBSDSRCDIR}/minix/lib/libc/arch/${MACHINE_ARCH}/sys
.PATH: ${HERE}
TMP=ucontextoffsets.h.tmp
CF=${HERE}/ucontextoffsets.cf
INCS+=ucontextoffsets.h
ucontext.o: ucontextoffsets.h
SRCS+= \
__sigreturn.S \
_do_kernel_call_intr.S \
_ipc.S \
brksize.S \
get_minix_kerninfo.S \
ucontext.S
ucontextoffsets.h: ${CF}
ucontextoffsets.h: ${NETBSDSRCDIR}/sys/sys/ucontext.h
ucontextoffsets.h: ${NETBSDSRCDIR}/minix/include/arch/${MACHINE_ARCH}/include/stackframe.h
ucontextoffsets.h:
${_MKTARGET_CREATE}
cat ${CF} | \
${TOOL_GENASSYM} -- ${CC} ${CFLAGS} ${CPPFLAGS} ${PROF} >$TMP && \
mv -f $TMP $@

View File

@@ -0,0 +1,9 @@
/* This routine is the low-level code for returning from signals. */
/* It calls _sigreturn, which is the normal "system call" routine. */
/* Both __sigreturn and _sigreturn are needed. */
#include <machine/asm.h>
IMPORT(sigreturn)
ENTRY(__sigreturn)
pop {r0} /* load sigframe.sf_scp into r0 as parameter */
b _C_LABEL(sigreturn) /* _sigreturn(struct sigcontext *sf_scpcopy) */

View File

@@ -0,0 +1,8 @@
#include <minix/ipcconst.h>
#include <machine/asm.h>
ENTRY(_do_kernel_call_intr)
/* r0 already holds msg ptr */
mov r3, #KERVEC_INTR /* r3 determines the SVC type */
svc #0 /* trap to kernel */
bx lr

View File

@@ -0,0 +1,74 @@
#include <minix/ipcconst.h>
#include <machine/asm.h>
/**========================================================================* */
/* IPC assembly routines * */
/**========================================================================* */
ENTRY(_ipc_send_intr)
push {fp}
mov fp, sp
mov r2, r1 /* r2 = msg ptr */
mov r1, r0 /* r1 = src_dest */
mov r0, #SEND /* _ipc_send(dest, ptr) */
mov r3, #IPCVEC_INTR /* r3 determines the SVC type */
svc #0 /* trap to kernel */
pop {fp}
bx lr
ENTRY(_ipc_receive_intr)
push {fp}
mov fp, sp
push {r2} /* save status ptr */
mov r2, r1 /* r2 = msg ptr */
mov r1, r0 /* r1 = src_dest */
mov r0, #RECEIVE /* _ipc_receive(src, ptr) */
mov r3, #IPCVEC_INTR /* r3 determines the SVC type */
svc #0 /* trap to kernel */
pop {r2} /* restore status ptr */
str r1, [r2]
pop {fp}
bx lr
ENTRY(_ipc_sendrec_intr)
push {fp}
mov fp, sp
mov r2, r1 /* r2 = msg ptr */
mov r1, r0 /* r1 = src_dest */
mov r0, #SENDREC /* _ipc_sendrec(srcdest, ptr) */
mov r3, #IPCVEC_INTR /* r3 determines the SVC type */
svc #0 /* trap to kernel */
pop {fp}
bx lr
ENTRY(_ipc_notify_intr)
push {fp}
mov fp, sp
mov r1, r0 /* r1 = src_dest */
mov r0, #NOTIFY /* _ipc_notify(srcdst) */
mov r3, #IPCVEC_INTR /* r3 determines the SVC type */
svc #0 /* trap to kernel */
pop {fp}
bx lr
ENTRY(_ipc_sendnb_intr)
push {fp}
mov fp, sp
mov r2, r1 /* r2 = msg ptr */
mov r1, r0 /* r1 = src_dest */
mov r0, #SENDNB /* _ipc_sendnb(dest, ptr) */
mov r3, #IPCVEC_INTR /* r3 determines the SVC type */
svc #0 /* trap to kernel */
pop {fp}
bx lr
ENTRY(_ipc_senda_intr)
push {fp}
mov fp, sp
mov r2, r0 /* r2 = table */
/* r1 already holds count */
mov r0, #SENDA /* _ipc_senda(table, count) */
mov r3, #IPCVEC_INTR /* r3 determines the SVC type */
svc #0 /* trap to kernel */
pop {fp}
bx lr

View File

@@ -0,0 +1,5 @@
.globl _end
.globl _brksize
.data
_brksize: .long _end

View File

@@ -0,0 +1,17 @@
#include <minix/ipcconst.h>
#include <machine/asm.h>
ENTRY(get_minix_kerninfo)
push {fp}
mov fp, sp
push {r0}
mov r1, #0
mov r2, #0
mov r0, #MINIX_KERNINFO /* _get_minix_kerninfo() */
mov r3, #IPCVEC_INTR /* r3 determines the SVC type */
svc #0 /* trap to kernel */
pop {r2} /* r2 = return struct ptr (was r0) */
str r1, [r2]
pop {fp}
bx lr

View File

@@ -0,0 +1,143 @@
#include <machine/asm.h>
#include <ucontextoffsets.h>
IMPORT(getuctx)
IMPORT(setuctx)
IMPORT(resumecontext)
/* int getcontext(ucontext_t *ucp)
* Initialise the structure pointed to by ucp to the current user context
* of the calling thread. */
ENTRY(getcontext)
ENTRY(_getcontext)
/* In case a process does not use the FPU and is neither interested in
* saving its signal mask, then we can skip the context switch to
* PM and kernel altogether and only save general-purpose registers. */
mov r3, lr /* Save return address:
* When setcontext or swapcontext is called,
* we jump to this address and continue
* running. */
/* r0 = ucp */
/* Check null pointer */
cmp r0, #0 /* ucp == NULL? */
bne 3f /* Not null, continue */
mov r1, #EFAULT
ldr r2, =_C_LABEL(errno)
str r1, [r2] /* errno = EFAULT */
mov r0, #-1 /* return -1 */
bx lr
3: /* Check flags */
ldr r1, [r0, #UC_FLAGS] /* r1 = ucp->uc_flags */
and r1, r1, #[_UC_IGNFPU|_UC_IGNSIGM]
cmp r1, #[_UC_IGNFPU|_UC_IGNSIGM] /* Allowed to ignore both? */
beq 1f /* If so, skip getuctx */
0:
push {r0, r3}
bl _C_LABEL(getuctx) /* getuctx(ucp) */
pop {r0, r3}
1:
/* Save the context */
mov lr, r3 /* Restore lr */
str lr, [r0, #LRREG] /* Save lr */
str lr, [r0, #PCREG] /* Save real RTA in mcp struct */
str sp, [r0, #SPREG] /* Save stack pointer */
str fp, [r0, #FPREG] /* Save fp */
str r4, [r0, #REG4] /* Save r4 */
str r5, [r0, #REG5] /* Save r5 */
str r6, [r0, #REG6] /* Save r6 */
str r7, [r0, #REG7] /* Save r7 */
str r8, [r0, #REG8] /* Save r8 */
str r9, [r0, #REG9] /* Save r9 */
str r10, [r0, #REG10] /* Save r10 */
ldr r1, =MCF_MAGIC
str r1, [r0, #MAGIC] /* Set magic value */
mov r1, #0
str r1, [r0, #REG0] /* Return 0 */
mov r0, #0 /* Return 0 */
2:
bx lr /* Restore return address */
/* int setcontext(const ucontext_t *ucp)
* Restore the user context pointed to by ucp. A successful call to
* setcontext does not return; program execution resumes at the point
* specified by the ucp argument. If ucp was created with getcontext(),
* program execution continues as if the corresponding call of getcontext()
* had just returned. If ucp was created with makecontext(), program
* execution continues with the function passed to makecontext(). */
ENTRY(setcontext)
/* In case a process does not use the FPU and is neither interested in
* restoring its signal mask, then we can skip the context switch to
* PM and kernel altogether and restore state here. */
/* r0 = ucp */
/* Check null pointer */
cmp r0, #0 /* ucp == NULL? */
bne 3f /* Not null, continue */
mov r1, #EFAULT
ldr r2, =_C_LABEL(errno)
str r1, [r2] /* errno = EFAULT */
mov r0, #-1 /* return -1 */
bx lr
3: /* Check flags */
ldr r1, [r0, #MAGIC] /* r1 = ucp->mc_context.mc_magic */
ldr r2, =MCF_MAGIC
cmp r1, r2 /* is the magic value set (is context valid)?*/
beq 4f /* is set, proceed */
mov r1, #EINVAL /* not set, return error code */
ldr r2, =_C_LABEL(errno)
str r1, [r2] /* errno = EINVAL */
mov r0, #-1 /* return -1 */
bx lr
4: ldr r1, [r0, #UC_FLAGS] /* r1 = ucp->uc_flags */
and r1, r1, #[_UC_IGNFPU|_UC_IGNSIGM]
cmp r1, #[_UC_IGNFPU|_UC_IGNSIGM] /* Allowed to ignore both? */
beq 1f /* Neither are set, so don't bother restoring FPU
* state and signal mask */
push {r0, r3}
0: bl _C_LABEL(setuctx) /* setuctx(ucp) */
pop {r0, r3}
1: /* Restore the registers */
ldr r4, [r0, #REG4] /* Restore r4 */
ldr r5, [r0, #REG5] /* Restore r5 */
ldr r6, [r0, #REG6] /* Restore r6 */
ldr r7, [r0, #REG7] /* Restore r7 */
ldr r8, [r0, #REG8] /* Restore r8 */
ldr r9, [r0, #REG9] /* Restore r9 */
ldr r10, [r0, #REG10] /* Restore r10 */
ldr r12, [r0, #REG12] /* Restore r12 */
ldr fp, [r0, #FPREG] /* Restore fp */
ldr sp, [r0, #SPREG] /* Restore sp */
ldr lr, [r0, #LRREG] /* Restore lr */
mov r3, r0
ldr r0, [r3, #REG0] /* Restore r0 */
2:
ldr pc, [r3, #PCREG] /* Restore pc */
/* void ctx_start()
* A wrapper to call resumecontext. Makecontext puts the ucp in r4.
* This function moves the ucp into r0 so that the ucp is the first
* parameter for resumecontext. The call to resumecontext will start
* the next context in the linked list (or exit the program if there
* is no context). */
ENTRY(ctx_start)
mov r0, r4
b _C_LABEL(resumecontext)

View File

@@ -0,0 +1,31 @@
include <minix/type.h>
include <sys/ucontext.h>
include <sys/errno.h>
include <machine/mcontext.h>
struct __ucontext
member UC_FLAGS uc_flags
member UC_LINK uc_link
member MAGIC uc_mcontext.mc_magic
member REG0 uc_mcontext.__gregs[_REG_R0]
member REG1 uc_mcontext.__gregs[_REG_R1]
member REG2 uc_mcontext.__gregs[_REG_R2]
member REG3 uc_mcontext.__gregs[_REG_R3]
member REG4 uc_mcontext.__gregs[_REG_R4]
member REG5 uc_mcontext.__gregs[_REG_R5]
member REG6 uc_mcontext.__gregs[_REG_R6]
member REG7 uc_mcontext.__gregs[_REG_R7]
member REG8 uc_mcontext.__gregs[_REG_R8]
member REG9 uc_mcontext.__gregs[_REG_R9]
member REG10 uc_mcontext.__gregs[_REG_R10]
member FPREG uc_mcontext.__gregs[_REG_FP]
member REG12 uc_mcontext.__gregs[_REG_R12]
member SPREG uc_mcontext.__gregs[_REG_SP]
member LRREG uc_mcontext.__gregs[_REG_LR]
member PCREG uc_mcontext.__gregs[_REG_PC]
define EFAULT EFAULT
define EINVAL EINVAL
define MCF_MAGIC MCF_MAGIC
define _UC_IGNFPU _UC_IGNFPU
define _UC_IGNSIGM _UC_IGNSIGM

View File

@@ -32,5 +32,5 @@ OBJS+= lchown.o lchmod.o
lchown.o lchown.pico lchown.bc: ${NETBSDSRCDIR}/tools/compat/lchown.c
lchmod.o lchmod.pico lchmod.bc: ${NETBSDSRCDIR}/tools/compat/lchmod.c
.include "${NETBSDSRCDIR}/minix/lib/libc/arch/${ARCHSUBDIR}/sys/Makefile.inc"
.include "${NETBSDSRCDIR}/minix/lib/libc/arch/${ARCHSUBDIR}/Makefile.inc"
.include "${NETBSDSRCDIR}/minix/lib/libc/arch/${MACHINE_ARCH}/sys/Makefile.inc"
.include "${NETBSDSRCDIR}/minix/lib/libc/arch/${MACHINE_ARCH}/Makefile.inc"

View File

@@ -24,7 +24,7 @@ MKPIC= no # Never used as a dynamic library
LIBSADIR= ${NETBSDSRCDIR}/sys/lib/libsa
LIBSYSDIR= ${NETBSDSRCDIR}/minix/lib/libsys
LIBMINIXCDIR= ${NETBSDSRCDIR}/minix/lib/libc
LIBMINIXCARCHDIR= ${NETBSDSRCDIR}/minix/lib/libc/arch/${MACHINE_CPU}
LIBMINIXCARCHDIR= ${NETBSDSRCDIR}/minix/lib/libc/arch/${MACHINE_ARCH}
LIBCDIR= ${NETBSDSRCDIR}/lib/libc
LIBCARCHDIR= ${LIBCDIR}/arch/${MACHINE_CPU}
LIBCOMMONCDIR= ${NETBSDSRCDIR}/common/lib/libc
@@ -300,7 +300,7 @@ CLEANFILES+= ${f:C/\.o/.bc/}
.endif # ${USE_BITCODE:Uno} == "yes"
.endfor
ARCHSUBDIR=${MACHINE_CPU}
.include "${NETBSDSRCDIR}/minix/lib/libc/arch/${MACHINE_CPU}/Makefile.inc"
ARCHSUBDIR=${MACHINE_ARCH}
.include "${NETBSDSRCDIR}/minix/lib/libc/arch/${MACHINE_ARCH}/Makefile.inc"
.include <bsd.lib.mk>

View File

@@ -93,7 +93,7 @@ CLEANFILES+= ${f}
.endfor
.if defined(HAVE_GCC) && ${HAVE_GCC} >= 45
.if (${MACHINE_CPU} == "arm")
.if (${MACHINE_ARCH} == "earm")
COPTS.softfloat.c+= -Wno-enum-compare -fno-tree-vrp
.endif
.endif

View File

@@ -93,7 +93,7 @@ CLEANFILES+= ${f}
.endfor
.if defined(HAVE_GCC) && ${HAVE_GCC} >= 45
.if (${MACHINE_CPU} == "arm")
.if (${MACHINE_ARCH} == "earmv6hf")
COPTS.softfloat.c+= -Wno-enum-compare -fno-tree-vrp
.endif
.endif