diff options
| author | Paul Mackerras <paulus@tango.paulus.ozlabs.org> | 2002-02-11 20:41:44 +1100 |
|---|---|---|
| committer | Paul Mackerras <paulus@tango.paulus.ozlabs.org> | 2002-02-11 20:41:44 +1100 |
| commit | db7bfdb0276574b29618179004ced1de8dcf40c0 (patch) | |
| tree | f65179bd228616f902065bc92a96ad394f4b0097 | |
| parent | 0dc68d77428413d0f417df3a378f857a2e798ebf (diff) | |
Import arch/ppc and include/asm-ppc changes from linuxppc_2_5 tree
485 files changed, 75327 insertions, 11795 deletions
diff --git a/arch/ppc/4xx_io/Config.in b/arch/ppc/4xx_io/Config.in new file mode 100644 index 000000000000..e9ac9bb95d07 --- /dev/null +++ b/arch/ppc/4xx_io/Config.in @@ -0,0 +1,16 @@ +# +# MPC4xx driver options +# +mainmenu_option next_comment + +comment 'MPC4xx Driver Options' + +if [ "$CONFIG_STB03xxx" = "y" ]; then + bool 'STB IR Keyboard' CONFIG_STB_KB + bool 'SICC Serial port' CONFIG_SERIAL_SICC + if [ "$CONFIG_SERIAL_SICC" = "y" -a "$CONFIG_UART0_TTYS1" = "y" ]; then + define_bool CONFIG_UART1_DFLT_CONSOLE y + define_bool CONFIG_SERIAL_SICC_CONSOLE y + fi +fi +endmenu diff --git a/arch/ppc/4xx_io/Makefile b/arch/ppc/4xx_io/Makefile new file mode 100644 index 000000000000..8c0700cf083c --- /dev/null +++ b/arch/ppc/4xx_io/Makefile @@ -0,0 +1,12 @@ +# +# Makefile for the linux MPC4xx ppc-specific parts +# + +O_TARGET := 4xx_io.o + +#obj-y := + +obj-$(CONFIG_STB_KB) += stb_kb.o +obj-$(CONFIG_SERIAL_SICC) += serial_sicc.o + +include $(TOPDIR)/Rules.make diff --git a/arch/ppc/4xx_io/serial_sicc.c b/arch/ppc/4xx_io/serial_sicc.c new file mode 100644 index 000000000000..863dbfabc451 --- /dev/null +++ b/arch/ppc/4xx_io/serial_sicc.c @@ -0,0 +1,2133 @@ +/* + * arch/ppc/4xx_io/serial_sicc.c + * + * Driver for IBM STB3xxx SICC serial port + * + * Based on drivers/char/serial_amba.c, by ARM Ltd. + * + * Copyright 2001 IBM Crop. + * Author: IBM China Research Lab + * Yudong Yang <yangyud@cn.ibm.com> + * Yi Ge <geyi@cn.ibm.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * + * This is a driver for SICC serial port on IBM Redwood 4 evaluation board. + * The driver support both as a console device and normal serial device and + * is compatible with normal ttyS* devices. + */ + +#include <linux/config.h> +#include <linux/module.h> +#include <linux/errno.h> +#include <linux/signal.h> +#include <linux/sched.h> +#include <linux/interrupt.h> +#include <linux/tty.h> +#include <linux/tty_flip.h> +#include <linux/major.h> +#include <linux/string.h> +#include <linux/fcntl.h> +#include <linux/ptrace.h> +#include <linux/ioport.h> +#include <linux/mm.h> +#include <linux/slab.h> +#include <linux/init.h> +#include <linux/circ_buf.h> +#include <linux/serial.h> +#include <linux/console.h> +#include <linux/sysrq.h> + +#include <asm/system.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/uaccess.h> +#include <asm/bitops.h> +#include <asm/serial.h> + + +#include <linux/serialP.h> + + +/* ----------------------------------------------------------------------------- + * From STB03xxx SICC UART Specification + * ----------------------------------------------------------------------------- + * UART Register Offsets. + */ + +#define BL_SICC_LSR 0x0000000 /* line status register read/clear */ +#define BL_SICC_LSRS 0x0000001 /* set line status register read/set */ +#define BL_SICC_HSR 0x0000002 /* handshake status register r/clear */ +#define BL_SICC_HSRS 0x0000003 /* set handshake status register r/set */ +#define BL_SICC_BRDH 0x0000004 /* baudrate divisor high reg r/w */ +#define BL_SICC_BRDL 0x0000005 /* baudrate divisor low reg r/w */ +#define BL_SICC_LCR 0x0000006 /* control register r/w */ +#define BL_SICC_RCR 0x0000007 /* receiver command register r/w */ +#define BL_SICC_TxCR 0x0000008 /* transmitter command register r/w */ +#define BL_SICC_RBR 0x0000009 /* receive buffer r */ +#define BL_SICC_TBR 0x0000009 /* transmit buffer w */ +#define BL_SICC_CTL2 0x000000A /* added for Vesta */ +#define BL_SICC_IrCR 0x000000B /* added for Vesta IR */ + +/* masks and definitions for serial port control register */ + +#define _LCR_LM_MASK 0xc0 /* loop back modes */ +#define _LCR_DTR_MASK 0x20 /* data terminal ready 0-inactive */ +#define _LCR_RTS_MASK 0x10 /* request to send 0-inactive */ +#define _LCR_DB_MASK 0x08 /* data bits mask */ +#define _LCR_PE_MASK 0x04 /* parity enable */ +#define _LCR_PTY_MASK 0x02 /* parity */ +#define _LCR_SB_MASK 0x01 /* stop bit mask */ + +#define _LCR_LM_NORM 0x00 /* normal operation */ +#define _LCR_LM_LOOP 0x40 /* internal loopback mode */ +#define _LCR_LM_ECHO 0x80 /* automatic echo mode */ +#define _LCR_LM_RES 0xc0 /* reserved */ + +#define _LCR_DTR_ACTIVE _LCR_DTR_MASK /* DTR is active */ +#define _LCR_RTS_ACTIVE _LCR_RTS_MASK /* RTS is active */ +#define _LCR_DB_8_BITS _LCR_DB_MASK /* 8 data bits */ +#define _LCR_DB_7_BITS 0x00 /* 7 data bits */ +#define _LCR_PE_ENABLE _LCR_PE_MASK /* parity enabled */ +#define _LCR_PE_DISABLE 0x00 /* parity disabled */ +#define _LCR_PTY_EVEN 0x00 /* even parity */ +#define _LCR_PTY_ODD _LCR_PTY_MASK /* odd parity */ +#define _LCR_SB_1_BIT 0x00 /* one stop bit */ +#define _LCR_SB_2_BIT _LCR_SB_MASK /* two stop bit */ + +/* serial port handshake register */ + +#define _HSR_DIS_MASK 0x80 /* DSR input inactive error mask */ +#define _HSR_CS_MASK 0x40 /* CTS input inactive error mask */ +#define _HSR_DIS_ACT 0x00 /* dsr input is active */ +#define _HSR_DIS_INACT _HSR_DIS_MASK /* dsr input is inactive */ +#define _HSR_CS_ACT 0x00 /* cts input is active */ +#define _HSR_CS_INACT _HSR_CS_MASK /* cts input is active */ + +/* serial port line status register */ + +#define _LSR_RBR_MASK 0x80 /* receive buffer ready mask */ +#define _LSR_FE_MASK 0x40 /* framing error */ +#define _LSR_OE_MASK 0x20 /* overrun error */ +#define _LSR_PE_MASK 0x10 /* parity error */ +#define _LSR_LB_MASK 0x08 /* line break */ +#define _LSR_TBR_MASK 0x04 /* transmit buffer ready */ +#define _LSR_TSR_MASK 0x02 /* transmit shift register ready */ + +#define _LSR_RBR_FULL _LSR_RBR_MASK /* receive buffer is full */ +#define _LSR_FE_ERROR _LSR_FE_MASK /* framing error detected */ +#define _LSR_OE_ERROR _LSR_OE_MASK /* overrun error detected */ +#define _LSR_PE_ERROR _LSR_PE_MASK /* parity error detected */ +#define _LSR_LB_BREAK _LSR_LB_MASK /* line break detected */ +#define _LSR_TBR_EMPTY _LSR_TBR_MASK /* transmit buffer is ready */ +#define _LSR_TSR_EMPTY _LSR_TSR_MASK /* transmit shift register is empty */ +#define _LSR_TX_ALL 0x06 /* all physical transmit is done */ + +#define _LSR_RX_ERR (_LSR_LB_BREAK | _LSR_FE_MASK | _LSR_OE_MASK | \ + _LSR_PE_MASK ) + +/* serial port reciever command register */ + +#define _RCR_ER_MASK 0x80 /* enable receiver mask */ +#define _RCR_DME_MASK 0x60 /* dma mode */ +#define _RCR_EIE_MASK 0x10 /* error interrupt enable mask */ +#define _RCR_PME_MASK 0x08 /* pause mode mask */ + +#define _RCR_ER_ENABLE _RCR_ER_MASK /* receiver enabled */ +#define _RCR_DME_DISABLE 0x00 /* dma disabled */ +#define _RCR_DME_RXRDY 0x20 /* dma disabled, RxRDY interrupt enabled*/ +#define _RCR_DME_ENABLE2 0x40 /* dma enabled,receiver src channel 2 */ +#define _RCR_DME_ENABLE3 0x60 /* dma enabled,receiver src channel 3 */ +#define _RCR_PME_HARD _RCR_PME_MASK /* RTS controlled by hardware */ +#define _RCR_PME_SOFT 0x00 /* RTS controlled by software */ + +/* serial port transmit command register */ + +#define _TxCR_ET_MASK 0x80 /* transmiter enable mask */ +#define _TxCR_DME_MASK 0x60 /* dma mode mask */ +#define _TxCR_TIE_MASK 0x10 /* empty interrupt enable mask */ +#define _TxCR_EIE_MASK 0x08 /* error interrupt enable mask */ +#define _TxCR_SPE_MASK 0x04 /* stop/pause mask */ +#define _TxCR_TB_MASK 0x02 /* transmit break mask */ + +#define _TxCR_ET_ENABLE _TxCR_ET_MASK /* transmiter enabled */ +#define _TxCR_DME_DISABLE 0x00 /* transmiter disabled, TBR intr disabled */ +#define _TxCR_DME_TBR 0x20 /* transmiter disabled, TBR intr enabled */ +#define _TxCR_DME_CHAN_2 0x40 /* dma enabled, destination chann 2 */ +#define _TxCR_DME_CHAN_3 0x60 /* dma enabled, destination chann 3 */ + +/* serial ctl reg 2 - added for Vesta */ + +#define _CTL2_EXTERN 0x80 /* */ +#define _CTL2_USEFIFO 0x40 /* */ +#define _CTL2_RESETRF 0x08 /* */ +#define _CTL2_RESETTF 0x04 /* */ + + + +#define SERIAL_SICC_NAME "ttySICC" +#define SERIAL_SICC_MAJOR 150 +#define SERIAL_SICC_MINOR 1 +#define SERIAL_SICC_NR 1 + +#define CALLOUT_SICC_NAME "cuasicc" +#define CALLOUT_SICC_MAJOR 151 +#define CALLOUT_SICC_MINOR 1 +#define CALLOUT_SICC_NR SERIAL_SICC_NR + +#ifndef TRUE +#define TRUE 1 +#endif +#ifndef FALSE +#define FALSE 0 +#endif + +#define DEBUG 0 + + + +/* + * Things needed by tty driver + */ +static struct tty_driver siccnormal_driver, sicccallout_driver; +static int siccuart_refcount; +static struct tty_struct *siccuart_table[SERIAL_SICC_NR]; +static struct termios *siccuart_termios[SERIAL_SICC_NR]; +static struct termios *siccuart_termios_locked[SERIAL_SICC_NR]; + +#if defined(CONFIG_SERIAL_SICC_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) +#define SUPPORT_SYSRQ +#endif + +/* + * Things needed internally to this driver + */ + +/* + * tmp_buf is used as a temporary buffer by serial_write. We need to + * lock it in case the copy_from_user blocks while swapping in a page, + * and some other program tries to do a serial write at the same time. + * Since the lock will only come under contention when the system is + * swapping and available memory is low, it makes sense to share one + * buffer across all the serial ports, since it significantly saves + * memory if large numbers of serial ports are open. + */ +static u_char *tmp_buf; +static DECLARE_MUTEX(tmp_buf_sem); + +#define HIGH_BITS_OFFSET ((sizeof(long)-sizeof(int))*8) + +/* number of characters left in xmit buffer before we ask for more */ +#define WAKEUP_CHARS 256 +#define SICC_ISR_PASS_LIMIT 256 + +#define EVT_WRITE_WAKEUP 0 + +struct SICC_icount { + __u32 cts; + __u32 dsr; + __u32 rng; + __u32 dcd; + __u32 rx; + __u32 tx; + __u32 frame; + __u32 overrun; + __u32 parity; + __u32 brk; + __u32 buf_overrun; +}; + +/* + * Static information about the port + */ +struct SICC_port { + unsigned int uart_base; + unsigned int uart_base_phys; + unsigned int irqrx; + unsigned int irqtx; + unsigned int uartclk; + unsigned int fifosize; + unsigned int tiocm_support; + void (*set_mctrl)(struct SICC_port *, u_int mctrl); +}; + +/* + * This is the state information which is persistent across opens + */ +struct SICC_state { + struct SICC_icount icount; + unsigned int line; + unsigned int close_delay; + unsigned int closing_wait; + unsigned int custom_divisor; + unsigned int flags; + struct termios normal_termios; + struct termios callout_termios; + + int count; + struct SICC_info *info; +}; + +#define SICC_XMIT_SIZE 1024 +/* + * This is the state information which is only valid when the port is open. + */ +struct SICC_info { + struct SICC_port *port; + struct SICC_state *state; + struct tty_struct *tty; + unsigned char x_char; + unsigned char old_status; + unsigned char read_status_mask; + unsigned char ignore_status_mask; + struct circ_buf xmit; + unsigned int flags; +#ifdef SUPPORT_SYSRQ + unsigned long sysrq; +#endif + + unsigned int event; + unsigned int timeout; + unsigned int lcr_h; + unsigned int mctrl; + int blocked_open; + pid_t session; + pid_t pgrp; + + struct tasklet_struct tlet; + + wait_queue_head_t open_wait; + wait_queue_head_t close_wait; + wait_queue_head_t delta_msr_wait; +}; + +#ifdef CONFIG_SERIAL_SICC_CONSOLE +static struct console siccuart_cons; +#endif +static void siccuart_change_speed(struct SICC_info *info, struct termios *old_termios); +static void siccuart_wait_until_sent(struct tty_struct *tty, int timeout); + + + +static void powerpcMtcic_cr(unsigned long value) +{ + mtdcr(DCRN_CICCR, value); +} + +static unsigned long powerpcMfcic_cr(void) +{ + return mfdcr(DCRN_CICCR); +} + +static unsigned long powerpcMfclkgpcr(void) +{ + return mfdcr(DCRN_SCCR); +} + +static void sicc_set_mctrl_null(struct SICC_port *port, u_int mctrl) +{ +} + +static struct SICC_port sicc_ports[SERIAL_SICC_NR] = { + { + uart_base: 0, + uart_base_phys: SICC0_IO_BASE, + irqrx: SICC0_INTRX, + irqtx: SICC0_INTTX, +// uartclk: 0, + fifosize: 1, + set_mctrl: sicc_set_mctrl_null, + } +}; + +static struct SICC_state sicc_state[SERIAL_SICC_NR]; + +static void siccuart_enable_rx_interrupt(struct SICC_info *info) +{ + unsigned char cr; + + cr = readb(info->port->uart_base+BL_SICC_RCR); + cr &= ~_RCR_DME_MASK; + cr |= _RCR_DME_RXRDY; + writeb(cr, info->port->uart_base+BL_SICC_RCR); +} + +static void siccuart_disable_rx_interrupt(struct SICC_info *info) +{ + unsigned char cr; + + cr = readb(info->port->uart_base+BL_SICC_RCR); + cr &= ~_RCR_DME_MASK; + cr |= _RCR_DME_DISABLE; + writeb(cr, info->port->uart_base+BL_SICC_RCR); +} + + +static void siccuart_enable_tx_interrupt(struct SICC_info *info) +{ + unsigned char cr; + + cr = readb(info->port->uart_base+BL_SICC_TxCR); + cr &= ~_TxCR_DME_MASK; + cr |= _TxCR_DME_TBR; + writeb(cr, info->port->uart_base+BL_SICC_TxCR); +} + +static void siccuart_disable_tx_interrupt(struct SICC_info *info) +{ + unsigned char cr; + + cr = readb(info->port->uart_base+BL_SICC_TxCR); + cr &= ~_TxCR_DME_MASK; + cr |= _TxCR_DME_DISABLE; + writeb(cr, info->port->uart_base+BL_SICC_TxCR); +} + + +static void siccuart_stop(struct tty_struct *tty) +{ + struct SICC_info *info = tty->driver_data; + unsigned long flags; + + save_flags(flags); cli(); + siccuart_disable_tx_interrupt(info); + restore_flags(flags); +} + +static void siccuart_start(struct tty_struct *tty) +{ + struct SICC_info *info = tty->driver_data; + unsigned long flags; + + save_flags(flags); cli(); + if (info->xmit.head != info->xmit.tail + && info->xmit.buf) + siccuart_enable_tx_interrupt(info); + restore_flags(flags); +} + + +/* + * This routine is used by the interrupt handler to schedule + * processing in the software interrupt portion of the driver. + */ +static void siccuart_event(struct SICC_info *info, int event) +{ + info->event |= 1 << event; + tasklet_schedule(&info->tlet); +} + +static void +#ifdef SUPPORT_SYSRQ +siccuart_rx_chars(struct SICC_info *info, struct pt_regs *regs) +#else +siccuart_rx_chars(struct SICC_info *info) +#endif +{ + struct tty_struct *tty = info->tty; + unsigned int status, ch, rsr, flg, ignored = 0; + struct SICC_icount *icount = &info->state->icount; + struct SICC_port *port = info->port; + + status = readb(port->uart_base+BL_SICC_LSR ); + while (status & _LSR_RBR_FULL) { + ch = readb(port->uart_base+BL_SICC_RBR); + + if (tty->flip.count >= TTY_FLIPBUF_SIZE) + goto ignore_char; + icount->rx++; + + flg = TTY_NORMAL; + + /* + * Note that the error handling code is + * out of the main execution path + */ + rsr = readb(port->uart_base+BL_SICC_LSR); + if (rsr & _LSR_RX_ERR) + goto handle_error; +#ifdef SUPPORT_SYSRQ + if (info->sysrq) { + if (ch && time_before(jiffies, info->sysrq)) { + handle_sysrq(ch, regs, NULL, NULL); + info->sysrq = 0; + goto ignore_char; + } + info->sysrq = 0; + } +#endif + error_return: + *tty->flip.flag_buf_ptr++ = flg; + *tty->flip.char_buf_ptr++ = ch; + tty->flip.count++; + ignore_char: + status = readb(port->uart_base+BL_SICC_LSR ); + } +out: + tty_flip_buffer_push(tty); + return; + +handle_error: + if (rsr & _LSR_LB_BREAK) { + rsr &= ~(_LSR_FE_MASK | _LSR_PE_MASK); + icount->brk++; + +#ifdef SUPPORT_SYSRQ + if (info->state->line == siccuart_cons.index) { + if (!info->sysrq) { + info->sysrq = jiffies + HZ*5; + goto ignore_char; + } + } +#endif + } else if (rsr & _LSR_PE_MASK) + icount->parity++; + else if (rsr & _LSR_FE_MASK) + icount->frame++; + if (rsr & _LSR_OE_MASK) + icount->overrun++; + + if (rsr & info->ignore_status_mask) { + if (++ignored > 100) + goto out; + goto ignore_char; + } + rsr &= info->read_status_mask; + + if (rsr & _LSR_LB_BREAK) + flg = TTY_BREAK; + else if (rsr & _LSR_PE_MASK) + flg = TTY_PARITY; + else if (rsr & _LSR_FE_MASK) + flg = TTY_FRAME; + + if (rsr & _LSR_OE_MASK) { + /* + * CHECK: does overrun affect the current character? + * ASSUMPTION: it does not. + */ + *tty->flip.flag_buf_ptr++ = flg; + *tty->flip.char_buf_ptr++ = ch; + tty->flip.count++; + if (tty->flip.count >= TTY_FLIPBUF_SIZE) + goto ignore_char; + ch = 0; + flg = TTY_OVERRUN; + } +#ifdef SUPPORT_SYSRQ + info->sysrq = 0; +#endif + goto error_return; +} + +static void siccuart_tx_chars(struct SICC_info *info) +{ + struct SICC_port *port = info->port; + int count; + unsigned char status; + + + if (info->x_char) { + writeb(info->x_char, port->uart_base+ BL_SICC_TBR); + info->state->icount.tx++; + info->x_char = 0; + return; + } + if (info->xmit.head == info->xmit.tail + || info->tty->stopped + || info->tty->hw_stopped) { + siccuart_disable_tx_interrupt(info); + writeb(status&(~_LSR_RBR_MASK),port->uart_base+BL_SICC_LSR); + return; + } + + count = port->fifosize; + do { + writeb(info->xmit.buf[info->xmit.tail], port->uart_base+ BL_SICC_TBR); + info->xmit.tail = (info->xmit.tail + 1) & (SICC_XMIT_SIZE - 1); + info->state->icount.tx++; + if (info->xmit.head == info->xmit.tail) + break; + } while (--count > 0); + + if (CIRC_CNT(info->xmit.head, + info->xmit.tail, + SICC_XMIT_SIZE) < WAKEUP_CHARS) + siccuart_event(info, EVT_WRITE_WAKEUP); + + if (info->xmit.head == info->xmit.tail) { + siccuart_disable_tx_interrupt(info); + } +} + + +static void siccuart_int_rx(int irq, void *dev_id, struct pt_regs *regs) +{ + struct SICC_info *info = dev_id; + +#ifdef SUPPORT_SYSRQ + siccuart_rx_chars(info, regs); +#else + siccuart_rx_chars(info); +#endif + + //powerpcClearUicsrBits(0x00000400); +} + + +static void siccuart_int_tx(int irq, void *dev_id, struct pt_regs *regs) +{ + struct SICC_info *info = dev_id; + siccuart_tx_chars(info); + +} + +static void siccuart_tasklet_action(unsigned long data) +{ + struct SICC_info *info = (struct SICC_info *)data; + struct tty_struct *tty; + + tty = info->tty; + if (!tty || !test_and_clear_bit(EVT_WRITE_WAKEUP, &info->event)) + return; + + if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && + tty->ldisc.write_wakeup) + (tty->ldisc.write_wakeup)(tty); + wake_up_interruptible(&tty->write_wait); +} + +static int siccuart_startup(struct SICC_info *info) +{ + unsigned long flags; + unsigned long page; + int retval = 0; + + if (info->flags & ASYNC_INITIALIZED) { + return 0; + } + + page = get_zeroed_page(GFP_KERNEL); + if (!page) + return -ENOMEM; + + if (info->port->uart_base == 0) + info->port->uart_base = (int)ioremap(info->port->uart_base_phys, PAGE_SIZE); + if (info->port->uart_base == 0) { + free_page(page); + return -ENOMEM; + } + + save_flags(flags); cli(); + + if (info->xmit.buf) + free_page(page); + else + info->xmit.buf = (unsigned char *) page; + + + info->mctrl = 0; + if (info->tty->termios->c_cflag & CBAUD) + info->mctrl = TIOCM_RTS | TIOCM_DTR; + info->port->set_mctrl(info->port, info->mctrl); + + /* + * initialise the old status of the modem signals + */ + info->old_status = 0; // UART_GET_FR(info->port) & AMBA_UARTFR_MODEM_ANY; + + + if (info->tty) + clear_bit(TTY_IO_ERROR, &info->tty->flags); + info->xmit.head = info->xmit.tail = 0; + + /* + * Set up the tty->alt_speed kludge + */ + if (info->tty) { + if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) + info->tty->alt_speed = 57600; + if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) + info->tty->alt_speed = 115200; + if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) + info->tty->alt_speed = 230400; + if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) + info->tty->alt_speed = 460800; + } + + + writeb( 0x00, info->port->uart_base + BL_SICC_IrCR ); // disable IrDA + + + /* + * and set the speed of the serial port + */ + siccuart_change_speed(info, 0); + + // enable rx/tx ports + writeb(_RCR_ER_ENABLE /*| _RCR_PME_HARD*/, info->port->uart_base + BL_SICC_RCR); + writeb(_TxCR_ET_ENABLE , info->port->uart_base + BL_SICC_TxCR); + + readb(info->port->uart_base + BL_SICC_RBR); // clear rx port + + writeb(0xf8, info->port->uart_base + BL_SICC_LSR); /* reset bits 0-4 of LSR */ + + /* + * Finally, enable interrupts + */ + + /* + * Allocate the IRQ + */ + retval = request_irq(info->port->irqrx, siccuart_int_rx, 0, "SICC rx", info); + if (retval) { + if (capable(CAP_SYS_ADMIN)) { + if (info->tty) + set_bit(TTY_IO_ERROR, &info->tty->flags); + retval = 0; + } + goto errout; + } + retval = request_irq(info->port->irqtx, siccuart_int_tx, 0, "SICC tx", info); + if (retval) { + if (capable(CAP_SYS_ADMIN)) { + if (info->tty) + set_bit(TTY_IO_ERROR, &info->tty->flags); + retval = 0; + } + free_irq(info->port->irqrx, info); + goto errout; + } + + siccuart_enable_rx_interrupt(info); + + info->flags |= ASYNC_INITIALIZED; + restore_flags(flags); + return 0; + + +errout: + restore_flags(flags); + return retval; +} + +/* + * This routine will shutdown a serial port; interrupts are disabled, and + * DTR is dropped if the hangup on close termio flag is on. + */ +static void siccuart_shutdown(struct SICC_info *info) +{ + unsigned long flags; + + if (!(info->flags & ASYNC_INITIALIZED)) + return; + + save_flags(flags); cli(); /* Disable interrupts */ + + /* + * clear delta_msr_wait queue to avoid mem leaks: we may free the irq + * here so the queue might never be woken up + */ + wake_up_interruptible(&info->delta_msr_wait); + + /* + * disable all interrupts, disable the port + */ + siccuart_disable_rx_interrupt(info); + siccuart_disable_tx_interrupt(info); + + /* + * Free the IRQ + */ + free_irq(info->port->irqtx, info); + free_irq(info->port->irqrx, info); + + if (info->xmit.buf) { + unsigned long pg = (unsigned long) info->xmit.buf; + info->xmit.buf = NULL; + free_page(pg); + } + + + if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) + info->mctrl &= ~(TIOCM_DTR|TIOCM_RTS); + info->port->set_mctrl(info->port, info->mctrl); + + /* kill off our tasklet */ + tasklet_kill(&info->tlet); + if (info->tty) + set_bit(TTY_IO_ERROR, &info->tty->flags); + + info->flags &= ~ASYNC_INITIALIZED; + + restore_flags(flags); +} + + +static void siccuart_change_speed(struct SICC_info *info, struct termios *old_termios) +{ + unsigned int lcr_h, baud, quot, cflag, old_rcr, old_tcr, bits; + unsigned long flags; + + if (!info->tty || !info->tty->termios) + return; + + cflag = info->tty->termios->c_cflag; + +#if DEBUG + printk("siccuart_set_cflag(0x%x) called\n", cflag); +#endif + /* byte size and parity */ + switch (cflag & CSIZE) { + case CS7: lcr_h = _LCR_PE_DISABLE | _LCR_DB_7_BITS | _LCR_SB_1_BIT; bits = 9; break; + default: lcr_h = _LCR_PE_DISABLE | _LCR_DB_8_BITS | _LCR_SB_1_BIT; bits = 10; break; // CS8 + } + if (cflag & CSTOPB) { + lcr_h |= _LCR_SB_2_BIT; + bits ++; + } + if (cflag & PARENB) { + lcr_h |= _LCR_PE_ENABLE; + bits++; + if (!(cflag & PARODD)) + lcr_h |= _LCR_PTY_ODD; + else + lcr_h |= _LCR_PTY_EVEN; + } + + do { + /* Determine divisor based on baud rate */ + baud = tty_get_baud_rate(info->tty); + if (!baud) + baud = 9600; + + + { + // here is ppc403SetBaud(com_port, baud); + unsigned long divisor, clockSource, temp; + + /* Ensure CICCR[7] is 0 to select Internal Baud Clock */ + powerpcMtcic_cr((unsigned long)(powerpcMfcic_cr() & 0xFEFFFFFF)); + + /* Determine Internal Baud Clock Frequency */ + /* powerpcMfclkgpcr() reads DCR 0x120 - the*/ + /* SCCR (Serial Clock Control Register) on Vesta */ + temp = powerpcMfclkgpcr(); + + if(temp & 0x00000080) { + clockSource = 324000000; + } + else { + clockSource = 216000000; + } + clockSource = clockSource/(unsigned long)((temp&0x00FC0000)>>18); + divisor = clockSource/(16*baud) - 1; + /* divisor has only 12 bits of resolution */ + if(divisor>0x00000FFF){ + divisor=0x00000FFF; + } + + quot = divisor; + } + + if (baud == 38400 && + ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)) + quot = info->state->custom_divisor; + + if (!quot && old_termios) { + info->tty->termios->c_cflag &= ~CBAUD; + info->tty->termios->c_cflag |= (old_termios->c_cflag & CBAUD); + old_termios = NULL; + } + } while (quot == 0 && old_termios); + + /* As a last resort, if the quotient is zero, default to 9600 bps */ + if (!quot) + quot = (info->port->uartclk / (16 * 9600)) - 1; + + info->timeout = info->port->fifosize * HZ * bits / baud; + info->timeout += HZ/50; /* Add .02 seconds of slop */ + + if (cflag & CRTSCTS) + info->flags |= ASYNC_CTS_FLOW; + else + info->flags &= ~ASYNC_CTS_FLOW; + if (cflag & CLOCAL) + info->flags &= ~ASYNC_CHECK_CD; + else + info->flags |= ASYNC_CHECK_CD; + + /* + * Set up parity check flag + */ +#define RELEVENT_IFLAG(iflag) ((iflag) & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK)) + + info->read_status_mask = _LSR_OE_MASK; + if (I_INPCK(info->tty)) + info->read_status_mask |= _LSR_FE_MASK | _LSR_PE_MASK; + if (I_BRKINT(info->tty) || I_PARMRK(info->tty)) + info->read_status_mask |= _LSR_LB_MASK; + + /* + * Characters to ignore + */ + info->ignore_status_mask = 0; + if (I_IGNPAR(info->tty)) + info->ignore_status_mask |= _LSR_FE_MASK | _LSR_PE_MASK; + if (I_IGNBRK(info->tty)) { + info->ignore_status_mask |= _LSR_LB_MASK; + /* + * If we're ignoring parity and break indicators, + * ignore overruns to (for real raw support). + */ + if (I_IGNPAR(info->tty)) + info->ignore_status_mask |= _LSR_OE_MASK; + } + + /* first, disable everything */ + save_flags(flags); cli(); + + old_rcr = readb(info->port->uart_base + BL_SICC_RCR); + old_tcr = readb(info->port->uart_base + BL_SICC_TxCR); + + + writeb(0, info->port->uart_base + BL_SICC_RCR); + writeb(0, info->port->uart_base + BL_SICC_TxCR); + + /*RLBtrace (&ppc403Chan0, 0x2000000c, 0, 0);*/ + + + restore_flags(flags); + + + /* Set baud rate */ + writeb((quot & 0x00000F00)>>8, info->port->uart_base + BL_SICC_BRDH ); + writeb( quot & 0x00000FF, info->port->uart_base + BL_SICC_BRDL ); + + /* Set CTL2 reg to use external clock (ExtClk) and enable FIFOs. */ + /* For now, do NOT use FIFOs since 403 UART did not have this */ + /* capability and this driver was inherited from 403UART. */ + writeb(_CTL2_EXTERN, info->port->uart_base + BL_SICC_CTL2); + + writeb(lcr_h, info->port->uart_base + BL_SICC_LCR); + + writeb(old_rcr, info->port->uart_base + BL_SICC_RCR); // restore rcr + writeb(old_tcr, info->port->uart_base + BL_SICC_TxCR); // restore txcr + +} + + +static void siccuart_put_char(struct tty_struct *tty, u_char ch) +{ + struct SICC_info *info = tty->driver_data; + unsigned long flags; + + if (!tty || !info->xmit.buf) + return; + + save_flags(flags); cli(); + if (CIRC_SPACE(info->xmit.head, info->xmit.tail, SICC_XMIT_SIZE) != 0) { + info->xmit.buf[info->xmit.head] = ch; + info->xmit.head = (info->xmit.head + 1) & (SICC_XMIT_SIZE - 1); + } + restore_flags(flags); +} + +static void siccuart_flush_chars(struct tty_struct *tty) +{ + struct SICC_info *info = tty->driver_data; + unsigned long flags; + + if (info->xmit.head == info->xmit.tail + || tty->stopped + || tty->hw_stopped + || !info->xmit.buf) + return; + + save_flags(flags); cli(); + siccuart_enable_tx_interrupt(info); + restore_flags(flags); +} + +static int siccuart_write(struct tty_struct *tty, int from_user, + const u_char * buf, int count) +{ + struct SICC_info *info = tty->driver_data; + unsigned long flags; + int c, ret = 0; + + if (!tty || !info->xmit.buf || !tmp_buf) + return 0; + + save_flags(flags); + if (from_user) { + down(&tmp_buf_sem); + while (1) { + int c1; + c = CIRC_SPACE_TO_END(info->xmit.head, + info->xmit.tail, + SICC_XMIT_SIZE); + if (count < c) + c = count; + if (c <= 0) + break; + + c -= copy_from_user(tmp_buf, buf, c); + if (!c) { + if (!ret) + ret = -EFAULT; + break; + } + cli(); + c1 = CIRC_SPACE_TO_END(info->xmit.head, + info->xmit.tail, + SICC_XMIT_SIZE); + if (c1 < c) + c = c1; + memcpy(info->xmit.buf + info->xmit.head, tmp_buf, c); + info->xmit.head = (info->xmit.head + c) & + (SICC_XMIT_SIZE - 1); + restore_flags(flags); + buf += c; + count -= c; + ret += c; + } + up(&tmp_buf_sem); + } else { + cli(); + while (1) { + c = CIRC_SPACE_TO_END(info->xmit.head, + info->xmit.tail, + SICC_XMIT_SIZE); + if (count < c) + c = count; + if (c <= 0) + break; + memcpy(info->xmit.buf + info->xmit.head, buf, c); + info->xmit.head = (info->xmit.head + c) & + (SICC_XMIT_SIZE - 1); + buf += c; + count -= c; + ret += c; + } + restore_flags(flags); + } + if (info->xmit.head != info->xmit.tail + && !tty->stopped + && !tty->hw_stopped) + siccuart_enable_tx_interrupt(info); + return ret; +} + +static int siccuart_write_room(struct tty_struct *tty) +{ + struct SICC_info *info = tty->driver_data; + + return CIRC_SPACE(info->xmit.head, info->xmit.tail, SICC_XMIT_SIZE); +} + +static int siccuart_chars_in_buffer(struct tty_struct *tty) +{ + struct SICC_info *info = tty->driver_data; + + return CIRC_CNT(info->xmit.head, info->xmit.tail, SICC_XMIT_SIZE); +} + +static void siccuart_flush_buffer(struct tty_struct *tty) +{ + struct SICC_info *info = tty->driver_data; + unsigned long flags; + +#if DEBUG + printk("siccuart_flush_buffer(%d) called\n", + MINOR(tty->device) - tty->driver.minor_start); +#endif + save_flags(flags); cli(); + info->xmit.head = info->xmit.tail = 0; + restore_flags(flags); + wake_up_interruptible(&tty->write_wait); + if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && + tty->ldisc.write_wakeup) + (tty->ldisc.write_wakeup)(tty); +} + +/* + * This function is used to send a high-priority XON/XOFF character to + * the device + */ +static void siccuart_send_xchar(struct tty_struct *tty, char ch) +{ + struct SICC_info *info = tty->driver_data; + + info->x_char = ch; + if (ch) + siccuart_enable_tx_interrupt(info); +} + +static void siccuart_throttle(struct tty_struct *tty) +{ + struct SICC_info *info = tty->driver_data; + unsigned long flags; + + if (I_IXOFF(tty)) + siccuart_send_xchar(tty, STOP_CHAR(tty)); + + if (tty->termios->c_cflag & CRTSCTS) { + save_flags(flags); cli(); + info->mctrl &= ~TIOCM_RTS; + info->port->set_mctrl(info->port, info->mctrl); + restore_flags(flags); + } +} + +static void siccuart_unthrottle(struct tty_struct *tty) +{ + struct SICC_info *info = (struct SICC_info *) tty->driver_data; + unsigned long flags; + + if (I_IXOFF(tty)) { + if (info->x_char) + info->x_char = 0; + else + siccuart_send_xchar(tty, START_CHAR(tty)); + } + + if (tty->termios->c_cflag & CRTSCTS) { + save_flags(flags); cli(); + info->mctrl |= TIOCM_RTS; + info->port->set_mctrl(info->port, info->mctrl); + restore_flags(flags); + } +} + +static int get_serial_info(struct SICC_info *info, struct serial_struct *retinfo) +{ + struct SICC_state *state = info->state; + struct SICC_port *port = info->port; + struct serial_struct tmp; + + memset(&tmp, 0, sizeof(tmp)); + tmp.type = 0; + tmp.line = state->line; + tmp.port = port->uart_base; + if (HIGH_BITS_OFFSET) + tmp.port_high = port->uart_base >> HIGH_BITS_OFFSET; + tmp.irq = port->irqrx; + tmp.flags = 0; + tmp.xmit_fifo_size = port->fifosize; + tmp.baud_base = port->uartclk / 16; + tmp.close_delay = state->close_delay; + tmp.closing_wait = state->closing_wait; + tmp.custom_divisor = state->custom_divisor; + + if (copy_to_user(retinfo, &tmp, sizeof(*retinfo))) + return -EFAULT; + return 0; +} + +static int set_serial_info(struct SICC_info *info, + struct serial_struct *newinfo) +{ + struct serial_struct new_serial; + struct SICC_state *state, old_state; + struct SICC_port *port; + unsigned long new_port; + unsigned int i, change_irq, change_port; + int retval = 0; + + if (copy_from_user(&new_serial, newinfo, sizeof(new_serial))) + return -EFAULT; + + state = info->state; + old_state = *state; + port = info->port; + + new_port = new_serial.port; + if (HIGH_BITS_OFFSET) + new_port += (unsigned long) new_serial.port_high << HIGH_BITS_OFFSET; + + change_irq = new_serial.irq != port->irqrx; + change_port = new_port != port->uart_base; + + if (!capable(CAP_SYS_ADMIN)) { + if (change_irq || change_port || + (new_serial.baud_base != port->uartclk / 16) || + (new_serial.close_delay != state->close_delay) || + (new_serial.xmit_fifo_size != port->fifosize) || + ((new_serial.flags & ~ASYNC_USR_MASK) != + (state->flags & ~ASYNC_USR_MASK))) + return -EPERM; + state->flags = ((state->flags & ~ASYNC_USR_MASK) | + (new_serial.flags & ASYNC_USR_MASK)); + info->flags = ((info->flags & ~ASYNC_USR_MASK) | + (new_serial.flags & ASYNC_USR_MASK)); + state->custom_divisor = new_serial.custom_divisor; + goto check_and_exit; + } + + if ((new_serial.irq >= NR_IRQS) || (new_serial.irq < 0) || + (new_serial.baud_base < 9600)) + return -EINVAL; + + if (new_serial.type && change_port) { + for (i = 0; i < SERIAL_SICC_NR; i++) + if ((port != sicc_ports + i) && + sicc_ports[i].uart_base != new_port) + return -EADDRINUSE; + } + + if ((change_port || change_irq) && (state->count > 1)) + return -EBUSY; + + /* + * OK, past this point, all the error checking has been done. + * At this point, we start making changes..... + */ + port->uartclk = new_serial.baud_base * 16; + state->flags = ((state->flags & ~ASYNC_FLAGS) | + (new_serial.flags & ASYNC_FLAGS)); + info->flags = ((state->flags & ~ASYNC_INTERNAL_FLAGS) | + (info->flags & ASYNC_INTERNAL_FLAGS)); + state->custom_divisor = new_serial.custom_divisor; + state->close_delay = new_serial.close_delay * HZ / 100; + state->closing_wait = new_serial.closing_wait * HZ / 100; + info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0; + port->fifosize = new_serial.xmit_fifo_size; + + if (change_port || change_irq) { + /* + * We need to shutdown the serial port at the old + * port/irq combination. + */ + siccuart_shutdown(info); + port->irqrx = new_serial.irq; + port->uart_base = new_port; + } + +check_and_exit: + if (!port->uart_base) + return 0; + if (info->flags & ASYNC_INITIALIZED) { + if ((old_state.flags & ASYNC_SPD_MASK) != + (state->flags & ASYNC_SPD_MASK) || + (old_state.custom_divisor != state->custom_divisor)) { + if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) + info->tty->alt_speed = 57600; + if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) + info->tty->alt_speed = 115200; + if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) + info->tty->alt_speed = 230400; + if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) + info->tty->alt_speed = 460800; + siccuart_change_speed(info, NULL); + } + } else + retval = siccuart_startup(info); + return retval; +} + + +/* + * get_lsr_info - get line status register info + */ +static int get_lsr_info(struct SICC_info *info, unsigned int *value) +{ + unsigned int result, status; + unsigned long flags; + + save_flags(flags); cli(); + status = readb(info->port->uart_base + BL_SICC_LSR); + restore_flags(flags); + result = status & _LSR_TSR_EMPTY ? TIOCSER_TEMT : 0; + + /* + * If we're about to load something into the transmit + * register, we'll pretend the transmitter isn't empty to + * avoid a race condition (depending on when the transmit + * interrupt happens). + */ + if (info->x_char || + ((CIRC_CNT(info->xmit.head, info->xmit.tail, + SICC_XMIT_SIZE) > 0) && + !info->tty->stopped && !info->tty->hw_stopped)) + result &= TIOCSER_TEMT; + + return put_user(result, value); +} + +static int get_modem_info(struct SICC_info *info, unsigned int *value) +{ + unsigned int result = info->mctrl; + + return put_user(result, value); +} + +static int set_modem_info(struct SICC_info *info, unsigned int cmd, + unsigned int *value) +{ + unsigned int arg, old; + unsigned long flags; + + if (get_user(arg, value)) + return -EFAULT; + + old = info->mctrl; + switch (cmd) { + case TIOCMBIS: + info->mctrl |= arg; + break; + + case TIOCMBIC: + info->mctrl &= ~arg; + break; + + case TIOCMSET: + info->mctrl = arg; + break; + + default: + return -EINVAL; + } + save_flags(flags); cli(); + if (old != info->mctrl) + info->port->set_mctrl(info->port, info->mctrl); + restore_flags(flags); + return 0; +} + +static void siccuart_break_ctl(struct tty_struct *tty, int break_state) +{ + struct SICC_info *info = tty->driver_data; + unsigned long flags; + unsigned int lcr_h; + + + save_flags(flags); cli(); + lcr_h = readb(info->port + BL_SICC_LSR); + if (break_state == -1) + lcr_h |= _LSR_LB_MASK; + else + lcr_h &= ~_LSR_LB_MASK; + writeb(lcr_h, info->port + BL_SICC_LSRS); + restore_flags(flags); +} + +static int siccuart_ioctl(struct tty_struct *tty, struct file *file, + unsigned int cmd, unsigned long arg) +{ + struct SICC_info *info = tty->driver_data; + struct SICC_icount cnow; + struct serial_icounter_struct icount; + unsigned long flags; + + if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && + (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGSTRUCT) && + (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) { + if (tty->flags & (1 << TTY_IO_ERROR)) + return -EIO; + } + + switch (cmd) { + case TIOCMGET: + return get_modem_info(info, (unsigned int *)arg); + case TIOCMBIS: + case TIOCMBIC: + case TIOCMSET: + return set_modem_info(info, cmd, (unsigned int *)arg); + case TIOCGSERIAL: + return get_serial_info(info, + (struct serial_struct *)arg); + case TIOCSSERIAL: + return set_serial_info(info, + (struct serial_struct *)arg); + case TIOCSERGETLSR: /* Get line status register */ + return get_lsr_info(info, (unsigned int *)arg); + /* + * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change + * - mask passed in arg for lines of interest + * (use |'ed TIOCM_RNG/DSR/CD/CTS for masking) + * Caller should use TIOCGICOUNT to see which one it was + */ + case TIOCMIWAIT: + return 0; + /* + * Get counter of input serial line interrupts (DCD,RI,DSR,CTS) + * Return: write counters to the user passed counter struct + * NB: both 1->0 and 0->1 transitions are counted except for + * RI where only 0->1 is counted. + */ + case TIOCGICOUNT: + save_flags(flags); cli(); + cnow = info->state->icount; + restore_flags(flags); + icount.cts = cnow.cts; + icount.dsr = cnow.dsr; + icount.rng = cnow.rng; + icount.dcd = cnow.dcd; + icount.rx = cnow.rx; + icount.tx = cnow.tx; + icount.frame = cnow.frame; + icount.overrun = cnow.overrun; + icount.parity = cnow.parity; + icount.brk = cnow.brk; + icount.buf_overrun = cnow.buf_overrun; + + return copy_to_user((void *)arg, &icount, sizeof(icount)) + ? -EFAULT : 0; + + default: + return -ENOIOCTLCMD; + } + return 0; +} + +static void siccuart_set_termios(struct tty_struct *tty, struct termios *old_termios) +{ + struct SICC_info *info = tty->driver_data; + unsigned long flags; + unsigned int cflag = tty->termios->c_cflag; + + if ((cflag ^ old_termios->c_cflag) == 0 && + RELEVENT_IFLAG(tty->termios->c_iflag ^ old_termios->c_iflag) == 0) + return; + + siccuart_change_speed(info, old_termios); + + /* Handle transition to B0 status */ + if ((old_termios->c_cflag & CBAUD) && + !(cflag & CBAUD)) { + save_flags(flags); cli(); + info->mctrl &= ~(TIOCM_RTS | TIOCM_DTR); + info->port->set_mctrl(info->port, info->mctrl); + restore_flags(flags); + } + + /* Handle transition away from B0 status */ + if (!(old_termios->c_cflag & CBAUD) && + (cflag & CBAUD)) { + save_flags(flags); cli(); + info->mctrl |= TIOCM_DTR; + if (!(cflag & CRTSCTS) || + !test_bit(TTY_THROTTLED, &tty->flags)) + info->mctrl |= TIOCM_RTS; + info->port->set_mctrl(info->port, info->mctrl); + restore_flags(flags); + } + + /* Handle turning off CRTSCTS */ + if ((old_termios->c_cflag & CRTSCTS) && + !(cflag & CRTSCTS)) { + tty->hw_stopped = 0; + siccuart_start(tty); + } + +#if 0 + /* + * No need to wake up processes in open wait, since they + * sample the CLOCAL flag once, and don't recheck it. + * XXX It's not clear whether the current behavior is correct + * or not. Hence, this may change..... + */ + if (!(old_termios->c_cflag & CLOCAL) && + (tty->termios->c_cflag & CLOCAL)) + wake_up_interruptible(&info->open_wait); +#endif +} + +static void siccuart_close(struct tty_struct *tty, struct file *filp) +{ + struct SICC_info *info = tty->driver_data; + struct SICC_state *state; + unsigned long flags; + + if (!info) + return; + + state = info->state; + +#if DEBUG + //printk("siccuart_close() called\n"); +#endif + + save_flags(flags); cli(); + + if (tty_hung_up_p(filp)) { + MOD_DEC_USE_COUNT; + restore_flags(flags); + return; + } + + if ((tty->count == 1) && (state->count != 1)) { + /* + * Uh, oh. tty->count is 1, which means that the tty + * structure will be freed. state->count should always + * be one in these conditions. If it's greater than + * one, we've got real problems, since it means the + * serial port won't be shutdown. + */ + printk("siccuart_close: bad serial port count; tty->count is 1, state->count is %d\n", state->count); + state->count = 1; + } + if (--state->count < 0) { + printk("rs_close: bad serial port count for %s%d: %d\n", tty->driver.name, info->state->line, state->count); + state->count = 0; + } + if (state->count) { + MOD_DEC_USE_COUNT; + restore_flags(flags); + return; + } + info->flags |= ASYNC_CLOSING; + restore_flags(flags); + /* + * Save the termios structure, since this port may have + * separate termios for callout and dialin. + */ + if (info->flags & ASYNC_NORMAL_ACTIVE) + info->state->normal_termios = *tty->termios; + if (info->flags & ASYNC_CALLOUT_ACTIVE) + info->state->callout_termios = *tty->termios; + /* + * Now we wait for the transmit buffer to clear; and we notify + * the line discipline to only process XON/XOFF characters. + */ + tty->closing = 1; + if (info->state->closing_wait != ASYNC_CLOSING_WAIT_NONE) + tty_wait_until_sent(tty, info->state->closing_wait); + /* + * At this point, we stop accepting input. To do this, we + * disable the receive line status interrupts. + */ + if (info->flags & ASYNC_INITIALIZED) { + siccuart_disable_rx_interrupt(info); + /* + * Before we drop DTR, make sure the UART transmitter + * has completely drained; this is especially + * important if there is a transmit FIFO! + */ + siccuart_wait_until_sent(tty, info->timeout); + } + siccuart_shutdown(info); + if (tty->driver.flush_buffer) + tty->driver.flush_buffer(tty); + if (tty->ldisc.flush_buffer) + tty->ldisc.flush_buffer(tty); + tty->closing = 0; + info->event = 0; + info->tty = NULL; + if (info->blocked_open) { + if (info->state->close_delay) { + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(info->state->close_delay); + } + wake_up_interruptible(&info->open_wait); + } + info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE| + ASYNC_CLOSING); + wake_up_interruptible(&info->close_wait); + MOD_DEC_USE_COUNT; +} + +static void siccuart_wait_until_sent(struct tty_struct *tty, int timeout) +{ + struct SICC_info *info = (struct SICC_info *) tty->driver_data; + unsigned long char_time, expire; + + if (info->port->fifosize == 0) + return; + + /* + * Set the check interval to be 1/5 of the estimated time to + * send a single character, and make it at least 1. The check + * interval should also be less than the timeout. + * + * Note: we have to use pretty tight timings here to satisfy + * the NIST-PCTS. + */ + char_time = (info->timeout - HZ/50) / info->port->fifosize; + char_time = char_time / 5; + if (char_time == 0) + char_time = 1; + + // Crazy!! sometimes the input arg 'timeout' can be negtive numbers :-( + if (timeout >= 0 && timeout < char_time) + char_time = timeout; + /* + * If the transmitter hasn't cleared in twice the approximate + * amount of time to send the entire FIFO, it probably won't + * ever clear. This assumes the UART isn't doing flow + * control, which is currently the case. Hence, if it ever + * takes longer than info->timeout, this is probably due to a + * UART bug of some kind. So, we clamp the timeout parameter at + * 2*info->timeout. + */ + if (!timeout || timeout > 2 * info->timeout) + timeout = 2 * info->timeout; + + expire = jiffies + timeout; +#if DEBUG + printk("siccuart_wait_until_sent(%d), jiff=%lu, expire=%lu char_time=%lu...\n", + MINOR(tty->device) - tty->driver.minor_start, jiffies, + expire, char_time); +#endif + while ((readb(info->port->uart_base + BL_SICC_LSR) & _LSR_TX_ALL) != _LSR_TX_ALL) { + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(char_time); + if (signal_pending(current)) + break; + if (timeout && time_after(jiffies, expire)) + break; + } + set_current_state(TASK_RUNNING); +} + +static void siccuart_hangup(struct tty_struct *tty) +{ + struct SICC_info *info = tty->driver_data; + struct SICC_state *state = info->state; + + siccuart_flush_buffer(tty); + if (info->flags & ASYNC_CLOSING) + return; + siccuart_shutdown(info); + info->event = 0; + state->count = 0; + info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE); + info->tty = NULL; + wake_up_interruptible(&info->open_wait); +} + +static int block_til_ready(struct tty_struct *tty, struct file *filp, + struct SICC_info *info) +{ + DECLARE_WAITQUEUE(wait, current); + struct SICC_state *state = info->state; + unsigned long flags; + int do_clocal = 0, extra_count = 0, retval; + + /* + * If the device is in the middle of being closed, then block + * until it's done, and then try again. + */ + if (tty_hung_up_p(filp) || + (info->flags & ASYNC_CLOSING)) { + if (info->flags & ASYNC_CLOSING) + interruptible_sleep_on(&info->close_wait); + return (info->flags & ASYNC_HUP_NOTIFY) ? + -EAGAIN : -ERESTARTSYS; + } + + /* + * If this is a callout device, then just make sure the normal + * device isn't being used. + */ + if (tty->driver.subtype == SERIAL_TYPE_CALLOUT) { + if (info->flags & ASYNC_NORMAL_ACTIVE) + return -EBUSY; + if ((info->flags & ASYNC_CALLOUT_ACTIVE) && + (info->flags & ASYNC_SESSION_LOCKOUT) && + (info->session != current->session)) + return -EBUSY; + if ((info->flags & ASYNC_CALLOUT_ACTIVE) && + (info->flags & ASYNC_PGRP_LOCKOUT) && + (info->pgrp != current->pgrp)) + return -EBUSY; + info->flags |= ASYNC_CALLOUT_ACTIVE; + return 0; + } + + /* + * If non-blocking mode is set, or the port is not enabled, + * then make the check up front and then exit. + */ + if ((filp->f_flags & O_NONBLOCK) || + (tty->flags & (1 << TTY_IO_ERROR))) { + if (info->flags & ASYNC_CALLOUT_ACTIVE) + return -EBUSY; + info->flags |= ASYNC_NORMAL_ACTIVE; + return 0; + } + + if (info->flags & ASYNC_CALLOUT_ACTIVE) { + if (state->normal_termios.c_cflag & CLOCAL) + do_clocal = 1; + } else { + if (tty->termios->c_cflag & CLOCAL) + do_clocal = 1; + } + + /* + * Block waiting for the carrier detect and the line to become + * free (i.e., not in use by the callout). While we are in + * this loop, state->count is dropped by one, so that + * rs_close() knows when to free things. We restore it upon + * exit, either normal or abnormal. + */ + retval = 0; + add_wait_queue(&info->open_wait, &wait); + save_flags(flags); cli(); + if (!tty_hung_up_p(filp)) { + extra_count = 1; + state->count--; + } + restore_flags(flags); + info->blocked_open++; + while (1) { + save_flags(flags); cli(); + if (!(info->flags & ASYNC_CALLOUT_ACTIVE) && + (tty->termios->c_cflag & CBAUD)) { + info->mctrl = TIOCM_DTR | TIOCM_RTS; + info->port->set_mctrl(info->port, info->mctrl); + } + restore_flags(flags); + set_current_state(TASK_INTERRUPTIBLE); + if (tty_hung_up_p(filp) || + !(info->flags & ASYNC_INITIALIZED)) { + if (info->flags & ASYNC_HUP_NOTIFY) + retval = -EAGAIN; + else + retval = -ERESTARTSYS; + break; + } + if (!(info->flags & ASYNC_CALLOUT_ACTIVE) && + !(info->flags & ASYNC_CLOSING) && + (do_clocal /*|| (UART_GET_FR(info->port) & SICC_UARTFR_DCD)*/)) + break; + if (signal_pending(current)) { + retval = -ERESTARTSYS; + break; + } + schedule(); + } + set_current_state(TASK_RUNNING); + remove_wait_queue(&info->open_wait, &wait); + if (extra_count) + state->count++; + info->blocked_open--; + if (retval) + return retval; + info->flags |= ASYNC_NORMAL_ACTIVE; + return 0; +} + +static struct SICC_info *siccuart_get(int line) +{ + struct SICC_info *info; + struct SICC_state *state = sicc_state + line; + + state->count++; + if (state->info) + return state->info; + info = kmalloc(sizeof(struct SICC_info), GFP_KERNEL); + if (info) { + memset(info, 0, sizeof(struct SICC_info)); + init_waitqueue_head(&info->open_wait); + init_waitqueue_head(&info->close_wait); + init_waitqueue_head(&info->delta_msr_wait); + info->flags = state->flags; + info->state = state; + info->port = sicc_ports + line; + tasklet_init(&info->tlet, siccuart_tasklet_action, + (unsigned long)info); + } + if (state->info) { + kfree(info); + return state->info; + } + state->info = info; + return info; +} + +static int siccuart_open(struct tty_struct *tty, struct file *filp) +{ + struct SICC_info *info; + int retval, line = MINOR(tty->device) - tty->driver.minor_start; + + + // is this a line that we've got? + MOD_INC_USE_COUNT; + if (line >= SERIAL_SICC_NR) { + MOD_DEC_USE_COUNT; + return -ENODEV; + } + + info = siccuart_get(line); + if (!info) + return -ENOMEM; + + tty->driver_data = info; + info->tty = tty; + info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0; + + /* + * Make sure we have the temporary buffer allocated + */ + if (!tmp_buf) { + unsigned long page = get_zeroed_page(GFP_KERNEL); + if (tmp_buf) + free_page(page); + else if (!page) { + MOD_DEC_USE_COUNT; + return -ENOMEM; + } + tmp_buf = (u_char *)page; + } + + /* + * If the port is in the middle of closing, bail out now. + */ + if (tty_hung_up_p(filp) || + (info->flags & ASYNC_CLOSING)) { + if (info->flags & ASYNC_CLOSING) + interruptible_sleep_on(&info->close_wait); + MOD_DEC_USE_COUNT; + return -EAGAIN; + } + + /* + * Start up the serial port + */ + retval = siccuart_startup(info); + if (retval) { + MOD_DEC_USE_COUNT; + return retval; + } + + retval = block_til_ready(tty, filp, info); + if (retval) { + MOD_DEC_USE_COUNT; + return retval; + } + + if ((info->state->count == 1) && + (info->flags & ASYNC_SPLIT_TERMIOS)) { + if (tty->driver.subtype == SERIAL_TYPE_NORMAL) { + *tty->termios = info->state->normal_termios; + } + else { + *tty->termios = info->state->callout_termios; + } + } +#ifdef CONFIG_SERIAL_SICC_CONSOLE + if (siccuart_cons.cflag && siccuart_cons.index == line) { + tty->termios->c_cflag = siccuart_cons.cflag; + siccuart_cons.cflag = 0; + siccuart_change_speed(info, NULL); + } +#endif + info->session = current->session; + info->pgrp = current->pgrp; + return 0; +} + +int __init siccuart_init(void) +{ + int i; + printk("IBM Vesta SICC serial port driver V 0.1 by Yudong Yang and Yi Ge / IBM CRL .\n"); + siccnormal_driver.magic = TTY_DRIVER_MAGIC; + siccnormal_driver.driver_name = "serial_sicc"; + siccnormal_driver.name = SERIAL_SICC_NAME; + siccnormal_driver.major = SERIAL_SICC_MAJOR; + siccnormal_driver.minor_start = SERIAL_SICC_MINOR; + siccnormal_driver.num = SERIAL_SICC_NR; + siccnormal_driver.type = TTY_DRIVER_TYPE_SERIAL; + siccnormal_driver.subtype = SERIAL_TYPE_NORMAL; + siccnormal_driver.init_termios = tty_std_termios; + siccnormal_driver.init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; + siccnormal_driver.flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS; + siccnormal_driver.refcount = &siccuart_refcount; + siccnormal_driver.table = siccuart_table; + siccnormal_driver.termios = siccuart_termios; + siccnormal_driver.termios_locked = siccuart_termios_locked; + + siccnormal_driver.open = siccuart_open; + siccnormal_driver.close = siccuart_close; + siccnormal_driver.write = siccuart_write; + siccnormal_driver.put_char = siccuart_put_char; + siccnormal_driver.flush_chars = siccuart_flush_chars; + siccnormal_driver.write_room = siccuart_write_room; + siccnormal_driver.chars_in_buffer = siccuart_chars_in_buffer; + siccnormal_driver.flush_buffer = siccuart_flush_buffer; + siccnormal_driver.ioctl = siccuart_ioctl; + siccnormal_driver.throttle = siccuart_throttle; + siccnormal_driver.unthrottle = siccuart_unthrottle; + siccnormal_driver.send_xchar = siccuart_send_xchar; + siccnormal_driver.set_termios = siccuart_set_termios; + siccnormal_driver.stop = siccuart_stop; + siccnormal_driver.start = siccuart_start; + siccnormal_driver.hangup = siccuart_hangup; + siccnormal_driver.break_ctl = siccuart_break_ctl; + siccnormal_driver.wait_until_sent = siccuart_wait_until_sent; + siccnormal_driver.read_proc = NULL; + + /* + * The callout device is just like the normal device except for + * the major number and the subtype code. + */ + sicccallout_driver = siccnormal_driver; + sicccallout_driver.name = CALLOUT_SICC_NAME; + sicccallout_driver.major = CALLOUT_SICC_MAJOR; + sicccallout_driver.subtype = SERIAL_TYPE_CALLOUT; + sicccallout_driver.read_proc = NULL; + sicccallout_driver.proc_entry = NULL; + + if (tty_register_driver(&siccnormal_driver)) + panic("Couldn't register SICC serial driver\n"); + if (tty_register_driver(&sicccallout_driver)) + panic("Couldn't register SICC callout driver\n"); + + for (i = 0; i < SERIAL_SICC_NR; i++) { + struct SICC_state *state = sicc_state + i; + state->line = i; + state->close_delay = 5 * HZ / 10; + state->closing_wait = 30 * HZ; + state->callout_termios = sicccallout_driver.init_termios; + state->normal_termios = siccnormal_driver.init_termios; + } + + + return 0; +} + +__initcall(siccuart_init); + +#ifdef CONFIG_SERIAL_SICC_CONSOLE +/************** console driver *****************/ + +/* + * This code is currently never used; console->read is never called. + * Therefore, although we have an implementation, we don't use it. + * FIXME: the "const char *s" should be fixed to "char *s" some day. + * (when the definition in include/linux/console.h is also fixed) + */ +#ifdef used_and_not_const_char_pointer +static int siccuart_console_read(struct console *co, const char *s, u_int count) +{ + struct SICC_port *port = &sicc_ports[co->index]; + unsigned int status; + char *w; + int c; +#if DEBUG + printk("siccuart_console_read() called\n"); +#endif + + c = 0; + w = s; + while (c < count) { + if(readb(port->uart_base + BL_SICC_LSR) & _LSR_RBR_FULL) { + *w++ = readb(port->uart_base + BL_SICC_RBR); + c++; + } else { + // nothing more to get, return + return c; + } + } + // return the count + return c; +} +#endif + +/* + * Print a string to the serial port trying not to disturb + * any possible real use of the port... + * + * The console_lock must be held when we get here. + */ +static void siccuart_console_write(struct console *co, const char *s, u_int count) +{ + struct SICC_port *port = &sicc_ports[co->index]; + unsigned int old_cr; + int i; + + /* + * First save the CR then disable the interrupts + */ + old_cr = readb(port->uart_base + BL_SICC_TxCR); + writeb(old_cr & ~_TxCR_DME_MASK, port->uart_base + BL_SICC_TxCR); + + /* + * Now, do each character + */ + for (i = 0; i < count; i++) { + while ((readb(port->uart_base + BL_SICC_LSR)&_LSR_TX_ALL) != _LSR_TX_ALL); + writeb(s[i], port->uart_base + BL_SICC_TBR); + if (s[i] == '\n') { + while ((readb(port->uart_base + BL_SICC_LSR)&_LSR_TX_ALL) != _LSR_TX_ALL); + writeb('\r', port->uart_base + BL_SICC_TBR); + } + } + + /* + * Finally, wait for transmitter to become empty + * and restore the TCR + */ + while ((readb(port->uart_base + BL_SICC_LSR)&_LSR_TX_ALL) != _LSR_TX_ALL); + writeb(old_cr, port->uart_base + BL_SICC_TxCR); +} + +/* + * Receive character from the serial port + */ +static int siccuart_console_wait_key(struct console *co) +{ + struct SICC_port *port = &sicc_ports[co->index]; + int c; + + while(!(readb(port->uart_base + BL_SICC_LSR) & _LSR_RBR_FULL)); + c = readb(port->uart_base + BL_SICC_RBR); + return c; +} + +static kdev_t siccuart_console_device(struct console *c) +{ + return MKDEV(SERIAL_SICC_MAJOR, SERIAL_SICC_MINOR + c->index); +} + + +static int __init siccuart_console_setup(struct console *co, char *options) +{ + struct SICC_port *port; + int baud = 9600; + int bits = 8; + int parity = 'n'; + u_int cflag = CREAD | HUPCL | CLOCAL; + u_int lcr_h, quot; + + + if (co->index >= SERIAL_SICC_NR) + co->index = 0; + + port = &sicc_ports[co->index]; + + if (port->uart_base == 0) + port->uart_base = (int)ioremap(port->uart_base_phys, PAGE_SIZE); + + if (options) { + char *s = options; + baud = simple_strtoul(s, NULL, 10); + while (*s >= '0' && *s <= '9') + s++; + if (*s) parity = *s++; + if (*s) bits = *s - '0'; + } + + /* + * Now construct a cflag setting. + */ + switch (baud) { + case 1200: cflag |= B1200; break; + case 2400: cflag |= B2400; break; + case 4800: cflag |= B4800; break; + default: cflag |= B9600; baud = 9600; break; + case 19200: cflag |= B19200; break; + case 38400: cflag |= B38400; break; + case 57600: cflag |= B57600; break; + case 115200: cflag |= B115200; break; + } + switch (bits) { + case 7: cflag |= CS7; lcr_h = _LCR_PE_DISABLE | _LCR_DB_7_BITS | _LCR_SB_1_BIT; break; + default: cflag |= CS8; lcr_h = _LCR_PE_DISABLE | _LCR_DB_8_BITS | _LCR_SB_1_BIT; break; + } + switch (parity) { + case 'o': + case 'O': cflag |= PARODD; lcr_h |= _LCR_PTY_ODD; break; + case 'e': + case 'E': cflag |= PARENB; lcr_h |= _LCR_PE_ENABLE | _LCR_PTY_ODD; break; + } + + co->cflag = cflag; + + + { + // a copy of is inserted here ppc403SetBaud(com_port, (int)9600); + unsigned long divisor, clockSource, temp; + unsigned int rate = baud; + + /* Ensure CICCR[7] is 0 to select Internal Baud Clock */ + powerpcMtcic_cr((unsigned long)(powerpcMfcic_cr() & 0xFEFFFFFF)); + + /* Determine Internal Baud Clock Frequency */ + /* powerpcMfclkgpcr() reads DCR 0x120 - the*/ + /* SCCR (Serial Clock Control Register) on Vesta */ + temp = powerpcMfclkgpcr(); + + if(temp & 0x00000080) { + clockSource = 324000000; + } + else { + clockSource = 216000000; + } + clockSource = clockSource/(unsigned long)((temp&0x00FC0000)>>18); + divisor = clockSource/(16*rate) - 1; + /* divisor has only 12 bits of resolution */ + if(divisor>0x00000FFF){ + divisor=0x00000FFF; + } + + quot = divisor; + } + + writeb((quot & 0x00000F00)>>8, port->uart_base + BL_SICC_BRDH ); + writeb( quot & 0x00000FF, port->uart_base + BL_SICC_BRDL ); + + /* Set CTL2 reg to use external clock (ExtClk) and enable FIFOs. */ + /* For now, do NOT use FIFOs since 403 UART did not have this */ + /* capability and this driver was inherited from 403UART. */ + writeb(_CTL2_EXTERN, port->uart_base + BL_SICC_CTL2); + + writeb(lcr_h, port->uart_base + BL_SICC_LCR); + writeb(_RCR_ER_ENABLE | _RCR_PME_HARD, port->uart_base + BL_SICC_RCR); + writeb( _TxCR_ET_ENABLE , port->uart_base + BL_SICC_TxCR); + + // writeb(, info->port->uart_base + BL_SICC_RCR ); + /* + * Transmitter Command Register: Transmitter enabled & DMA + TBR interrupt + * + Transmitter Empty interrupt + Transmitter error interrupt disabled & + * Stop mode when CTS active enabled & Transmit Break + Pattern Generation + * mode disabled. + */ + + writeb( 0x00, port->uart_base + BL_SICC_IrCR ); // disable IrDA + + readb(port->uart_base + BL_SICC_RBR); + + writeb(0xf8, port->uart_base + BL_SICC_LSR); /* reset bits 0-4 of LSR */ + + /* we will enable the port as we need it */ + + return 0; +} + +static struct console siccuart_cons = +{ + name: SERIAL_SICC_NAME, + write: siccuart_console_write, +#ifdef used_and_not_const_char_pointer + read: siccuart_console_read, +#endif + device: siccuart_console_device, + wait_key: siccuart_console_wait_key, + setup: siccuart_console_setup, + flags: CON_PRINTBUFFER, + index: -1, +}; + +void __init sicc_console_init(void) +{ + register_console(&siccuart_cons); +} + +#endif /* CONFIG_SERIAL_SICC_CONSOLE */ diff --git a/arch/ppc/4xx_io/stb_kb.c b/arch/ppc/4xx_io/stb_kb.c new file mode 100644 index 000000000000..f723e28029d6 --- /dev/null +++ b/arch/ppc/4xx_io/stb_kb.c @@ -0,0 +1,293 @@ +/* + * arch/ppc/4xx_io/stb_kb.c + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive for + * more details. + */ +#include <linux/config.h> + +#include <linux/spinlock.h> +#include <linux/sched.h> +#include <linux/interrupt.h> +#include <linux/tty.h> +#include <linux/mm.h> +#include <linux/signal.h> +#include <linux/init.h> +#include <linux/kbd_ll.h> +#include <linux/delay.h> +#include <linux/random.h> +#include <linux/poll.h> +#include <linux/miscdevice.h> +#include <linux/malloc.h> +#include <linux/kbd_kern.h> + +/* the following are borrowed from pc_keyb.c, thanks to those involved! */ +/* + * Translation of escaped scancodes to keycodes. + * This is now user-settable. + * The keycodes 1-88,96-111,119 are fairly standard, and + * should probably not be changed - changing might confuse X. + * X also interprets scancode 0x5d (KEY_Begin). + * + * For 1-88 keycode equals scancode. + */ + +#define E0_KPENTER 96 +#define E0_RCTRL 97 +#define E0_KPSLASH 98 +#define E0_PRSCR 99 +#define E0_RALT 100 +#define E0_BREAK 101 /* (control-pause) */ +#define E0_HOME 102 +#define E0_UP 103 +#define E0_PGUP 104 +#define E0_LEFT 105 +#define E0_RIGHT 106 +#define E0_END 107 +#define E0_DOWN 108 +#define E0_PGDN 109 +#define E0_INS 110 +#define E0_DEL 111 + +#define E1_PAUSE 119 + +/* + * The keycodes below are randomly located in 89-95,112-118,120-127. + * They could be thrown away (and all occurrences below replaced by 0), + * but that would force many users to use the `setkeycodes' utility, where + * they needed not before. It does not matter that there are duplicates, as + * long as no duplication occurs for any single keyboard. + */ +#define SC_LIM 89 + +#define FOCUS_PF1 85 /* actual code! */ +#define FOCUS_PF2 89 +#define FOCUS_PF3 90 +#define FOCUS_PF4 91 +#define FOCUS_PF5 92 +#define FOCUS_PF6 93 +#define FOCUS_PF7 94 +#define FOCUS_PF8 95 +#define FOCUS_PF9 120 +#define FOCUS_PF10 121 +#define FOCUS_PF11 122 +#define FOCUS_PF12 123 + +#define JAP_86 124 +/* tfj@olivia.ping.dk: + * The four keys are located over the numeric keypad, and are + * labelled A1-A4. It's an rc930 keyboard, from + * Regnecentralen/RC International, Now ICL. + * Scancodes: 59, 5a, 5b, 5c. + */ +#define RGN1 124 +#define RGN2 125 +#define RGN3 126 +#define RGN4 127 + +static unsigned char high_keys[128 - SC_LIM] = { + RGN1, RGN2, RGN3, RGN4, 0, 0, 0, /* 0x59-0x5f */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 0x60-0x67 */ + 0, 0, 0, 0, 0, FOCUS_PF11, 0, FOCUS_PF12, /* 0x68-0x6f */ + 0, 0, 0, FOCUS_PF2, FOCUS_PF9, 0, 0, FOCUS_PF3, /* 0x70-0x77 */ + FOCUS_PF4, FOCUS_PF5, FOCUS_PF6, FOCUS_PF7, /* 0x78-0x7b */ + FOCUS_PF8, JAP_86, FOCUS_PF10, 0 /* 0x7c-0x7f */ +}; + +/* BTC */ +#define E0_MACRO 112 +/* LK450 */ +#define E0_F13 113 +#define E0_F14 114 +#define E0_HELP 115 +#define E0_DO 116 +#define E0_F17 117 +#define E0_KPMINPLUS 118 +/* + * My OmniKey generates e0 4c for the "OMNI" key and the + * right alt key does nada. [kkoller@nyx10.cs.du.edu] + */ +#define E0_OK 124 +/* + * New microsoft keyboard is rumoured to have + * e0 5b (left window button), e0 5c (right window button), + * e0 5d (menu button). [or: LBANNER, RBANNER, RMENU] + * [or: Windows_L, Windows_R, TaskMan] + */ +#define E0_MSLW 125 +#define E0_MSRW 126 +#define E0_MSTM 127 + +static unsigned char e0_keys[128] = { + 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00-0x07 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 0x08-0x0f */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10-0x17 */ + 0, 0, 0, 0, E0_KPENTER, E0_RCTRL, 0, 0, /* 0x18-0x1f */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 0x20-0x27 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 0x28-0x2f */ + 0, 0, 0, 0, 0, E0_KPSLASH, 0, E0_PRSCR, /* 0x30-0x37 */ + E0_RALT, 0, 0, 0, 0, E0_F13, E0_F14, E0_HELP, /* 0x38-0x3f */ + E0_DO, E0_F17, 0, 0, 0, 0, E0_BREAK, E0_HOME, /* 0x40-0x47 */ + E0_UP, E0_PGUP, 0, E0_LEFT, E0_OK, E0_RIGHT, E0_KPMINPLUS, E0_END,/* 0x48-0x4f */ + E0_DOWN, E0_PGDN, E0_INS, E0_DEL, 0, 0, 0, 0, /* 0x50-0x57 */ + 0, 0, 0, E0_MSLW, E0_MSRW, E0_MSTM, 0, 0, /* 0x58-0x5f */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 0x60-0x67 */ + 0, 0, 0, 0, 0, 0, 0, E0_MACRO, /* 0x68-0x6f */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 0x70-0x77 */ + 0, 0, 0, 0, 0, 0, 0, 0 /* 0x78-0x7f */ +}; + +void __init rawirkbd_init_hw(void) { + +} +/* +int rawirkbd_setkeycode(unsigned int scancode, unsigned int keycode) +{ + return -EINVAL; +} + +int rawirkbd_getkeycode(unsigned int scancode) +{ + return -EINVAL; +} +*/ + +int rawirkbd_setkeycode(unsigned int scancode, unsigned int keycode) +{ + if (scancode < SC_LIM || scancode > 255 || keycode > 127) + return -EINVAL; + if (scancode < 128) + high_keys[scancode - SC_LIM] = keycode; + else + e0_keys[scancode - 128] = keycode; + return 0; +} + +int rawirkbd_getkeycode(unsigned int scancode) +{ + return + (scancode < SC_LIM || scancode > 255) ? -EINVAL : + (scancode < 128) ? high_keys[scancode - SC_LIM] : + e0_keys[scancode - 128]; +} + +int rawirkbd_translate(unsigned char scancode, unsigned char *keycode, + char raw_mode) +{ + static int prev_scancode = 0; + + /* special prefix scancodes.. */ + if (scancode == 0xe0 || scancode == 0xe1) { + prev_scancode = scancode; + return 0; + } + + /* 0xFF is sent by a few keyboards, ignore it. 0x00 is error */ + if (scancode == 0x00 || scancode == 0xff) { + prev_scancode = 0; + return 0; + } + + scancode &= 0x7f; + + if (prev_scancode) { + /* + * usually it will be 0xe0, but a Pause key generates + * e1 1d 45 e1 9d c5 when pressed, and nothing when released + */ + if (prev_scancode != 0xe0) { + if (prev_scancode == 0xe1 && scancode == 0x1d) { + prev_scancode = 0x100; + return 0; + } else if (prev_scancode == 0x100 && scancode == 0x45) { + *keycode = E1_PAUSE; + prev_scancode = 0; + } else { +#ifdef KBD_REPORT_UNKN + if (!raw_mode) + printk(KERN_INFO "keyboard: unknown e1 escape sequence\n"); +#endif + prev_scancode = 0; + return 0; + } + } else { + prev_scancode = 0; + /* + * The keyboard maintains its own internal caps lock and + * num lock statuses. In caps lock mode E0 AA precedes make + * code and E0 2A follows break code. In num lock mode, + * E0 2A precedes make code and E0 AA follows break code. + * We do our own book-keeping, so we will just ignore these. + */ + /* + * For my keyboard there is no caps lock mode, but there are + * both Shift-L and Shift-R modes. The former mode generates + * E0 2A / E0 AA pairs, the latter E0 B6 / E0 36 pairs. + * So, we should also ignore the latter. - aeb@cwi.nl + */ + if (scancode == 0x2a || scancode == 0x36) + return 0; + + if (e0_keys[scancode]) + *keycode = e0_keys[scancode]; + else { +#ifdef KBD_REPORT_UNKN + if (!raw_mode) + printk(KERN_INFO "keyboard: unknown scancode e0 %02x\n", + scancode); +#endif + return 0; + } + } + } else if (scancode >= SC_LIM) { + /* This happens with the FOCUS 9000 keyboard + Its keys PF1..PF12 are reported to generate + 55 73 77 78 79 7a 7b 7c 74 7e 6d 6f + Moreover, unless repeated, they do not generate + key-down events, so we have to zero up_flag below */ + /* Also, Japanese 86/106 keyboards are reported to + generate 0x73 and 0x7d for \ - and \ | respectively. */ + /* Also, some Brazilian keyboard is reported to produce + 0x73 and 0x7e for \ ? and KP-dot, respectively. */ + + *keycode = high_keys[scancode - SC_LIM]; + + if (!*keycode) { + if (!raw_mode) { +#ifdef KBD_REPORT_UNKN + printk(KERN_INFO "keyboard: unrecognized scancode (%02x)" + " - ignored\n", scancode); +#endif + } + return 0; + } + } else + *keycode = scancode; + return 1; +} + +char rawirkbd_unexpected_up(unsigned char keycode) +{ + /* unexpected, but this can happen: maybe this was a key release for a + FOCUS 9000 PF key; if we want to see it, we have to clear up_flag */ + if (keycode >= SC_LIM || keycode == 85) + return 0; + else + return 0200; +} + +#include <asm/machdep.h> + +void redwood_irkb_init(void) +{ + extern struct machdep_calls ppc_md; + + ppc_md.kbd_setkeycode = rawirkbd_setkeycode; + ppc_md.kbd_getkeycode = rawirkbd_getkeycode; + ppc_md.kbd_translate = rawirkbd_translate; + ppc_md.kbd_unexpected_up = rawirkbd_unexpected_up; + ppc_md.kbd_leds = NULL; /*rawirkbd_leds;*/ + ppc_md.kbd_init_hw = rawirkbd_init_hw; +} + diff --git a/arch/ppc/8260_io/Config.in b/arch/ppc/8260_io/Config.in index 4db16a068a75..0dd823287b47 100644 --- a/arch/ppc/8260_io/Config.in +++ b/arch/ppc/8260_io/Config.in @@ -1,6 +1,9 @@ # # MPC8260 Communication options # +mainmenu_option next_comment +comment 'MPC8260 Communication Options' +bool 'Enable SCC Console' CONFIG_SCC_CONSOLE if [ "$CONFIG_NET_ETHERNET" = "y" ]; then mainmenu_option next_comment comment 'MPC8260 Communication Options' @@ -20,6 +23,13 @@ if [ "$CONFIG_NET_ETHERNET" = "y" ]; then bool 'Ethernet on FCC1' CONFIG_FCC1_ENET bool 'Ethernet on FCC2' CONFIG_FCC2_ENET bool 'Ethernet on FCC3' CONFIG_FCC3_ENET + bool 'Use MDIO for PHY configuration' CONFIG_USE_MDIO + if [ "$CONFIG_USE_MDIO" = "y" ]; then + choice 'Type of PHY' \ + "LXT970 CONFIG_FCC_LXT970 \ + LXT971 CONFIG_FCC_LXT971 \ + QS6612 CONFIG_FCC_QS6612" CONFIG_FCC_LXT971 + fi fi - endmenu fi +endmenu diff --git a/arch/ppc/8260_io/fcc_enet.c b/arch/ppc/8260_io/fcc_enet.c index bcd2b0c694bf..fbb59ad2e810 100644 --- a/arch/ppc/8260_io/fcc_enet.c +++ b/arch/ppc/8260_io/fcc_enet.c @@ -1,21 +1,23 @@ /* - * BK Id: SCCS/s.fcc_enet.c 1.7 05/17/01 18:14:20 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * Fast Ethernet Controller (FCC) driver for Motorola MPC8260. * Copyright (c) 2000 MontaVista Software, Inc. Dan Malek (dmalek@jlc.net) * * This version of the driver is a combination of the 8xx fec and - * 8260 SCC Ethernet drivers. People seem to be choosing common I/O - * configurations, so this driver will work on the EST8260 boards and - * others yet to be announced. + * 8260 SCC Ethernet drivers. This version has some additional + * configuration options, which should probably be moved out of + * here. This driver currently works for the EST SBC8260, + * SBS Diablo/BCM, Embedded Planet RPX6, TQM8260, and others. * * Right now, I am very watseful with the buffers. I allocate memory * pages and then divide them into 2K frame buffers. This way I know I * have buffers large enough to hold one frame within one buffer descriptor. * Once I get this working, I will use 64 or 128 byte CPM buffers, which * will be much more memory efficient and will easily handle lots of - * small packets. + * small packets. Since this is a cache coherent processor and CPM, + * I could also preallocate SKB's and use them directly on the interface. * */ @@ -48,6 +50,56 @@ */ #define TX_TIMEOUT (2*HZ) +#ifdef CONFIG_USE_MDIO +/* Forward declarations of some structures to support different PHYs */ + +typedef struct { + uint mii_data; + void (*funct)(uint mii_reg, struct net_device *dev); +} phy_cmd_t; + +typedef struct { + uint id; + char *name; + + const phy_cmd_t *config; + const phy_cmd_t *startup; + const phy_cmd_t *ack_int; + const phy_cmd_t *shutdown; +} phy_info_t; + +/* Register definitions for the PHY. */ + +#define MII_REG_CR 0 /* Control Register */ +#define MII_REG_SR 1 /* Status Register */ +#define MII_REG_PHYIR1 2 /* PHY Identification Register 1 */ +#define MII_REG_PHYIR2 3 /* PHY Identification Register 2 */ +#define MII_REG_ANAR 4 /* A-N Advertisement Register */ +#define MII_REG_ANLPAR 5 /* A-N Link Partner Ability Register */ +#define MII_REG_ANER 6 /* A-N Expansion Register */ +#define MII_REG_ANNPTR 7 /* A-N Next Page Transmit Register */ +#define MII_REG_ANLPRNPR 8 /* A-N Link Partner Received Next Page Reg. */ + +/* values for phy_status */ + +#define PHY_CONF_ANE 0x0001 /* 1 auto-negotiation enabled */ +#define PHY_CONF_LOOP 0x0002 /* 1 loopback mode enabled */ +#define PHY_CONF_SPMASK 0x00f0 /* mask for speed */ +#define PHY_CONF_10HDX 0x0010 /* 10 Mbit half duplex supported */ +#define PHY_CONF_10FDX 0x0020 /* 10 Mbit full duplex supported */ +#define PHY_CONF_100HDX 0x0040 /* 100 Mbit half duplex supported */ +#define PHY_CONF_100FDX 0x0080 /* 100 Mbit full duplex supported */ + +#define PHY_STAT_LINK 0x0100 /* 1 up - 0 down */ +#define PHY_STAT_FAULT 0x0200 /* 1 remote fault */ +#define PHY_STAT_ANC 0x0400 /* 1 auto-negotiation complete */ +#define PHY_STAT_SPMASK 0xf000 /* mask for speed */ +#define PHY_STAT_10HDX 0x1000 /* 10 Mbit half duplex selected */ +#define PHY_STAT_10FDX 0x2000 /* 10 Mbit full duplex selected */ +#define PHY_STAT_100HDX 0x4000 /* 100 Mbit half duplex selected */ +#define PHY_STAT_100FDX 0x8000 /* 100 Mbit full duplex selected */ +#endif /* CONFIG_USE_MDIO */ + /* The number of Tx and Rx buffers. These are allocated from the page * pool. The code may assume these are power of two, so it is best * to keep them that size. @@ -77,12 +129,12 @@ static int fcc_enet_open(struct net_device *dev); static int fcc_enet_start_xmit(struct sk_buff *skb, struct net_device *dev); static int fcc_enet_rx(struct net_device *dev); -static void fcc_enet_mii(struct net_device *dev); static void fcc_enet_interrupt(int irq, void * dev_id, struct pt_regs * regs); static int fcc_enet_close(struct net_device *dev); static struct net_device_stats *fcc_enet_get_stats(struct net_device *dev); static void set_multicast_list(struct net_device *dev); -static void restart_fcc(struct net_device *dev); +static void fcc_restart(struct net_device *dev, int duplex); +static int fcc_enet_set_mac_address(struct net_device *dev, void *addr); /* These will be configurable for the FCC choice. * Multiple ports can be configured. There is little choice among the @@ -166,8 +218,14 @@ static void restart_fcc(struct net_device *dev); /* MII status/control serial interface. */ -#define PC_MDIO ((uint)0x00400000) -#define PC_MDCK ((uint)0x00200000) +#ifdef CONFIG_TQM8260 +/* TQM8260 has MDIO and MDCK on PC30 and PC31 respectively */ +#define PC_MDIO ((uint)0x00000002) +#define PC_MDCK ((uint)0x00000001) +#else +#define PC_MDIO ((uint)0x00000004) +#define PC_MDCK ((uint)0x00000020) +#endif /* A table of information for supporting FCCs. This does two things. * First, we know how many FCCs we have and they are always externally @@ -191,17 +249,31 @@ static fcc_info_t fcc_ports[] = { #ifdef CONFIG_FCC1_ENET { 0, CPM_CR_FCC1_SBLOCK, CPM_CR_FCC1_PAGE, PROFF_FCC1, SIU_INT_FCC1, (PC_F1RXCLK | PC_F1TXCLK), CMX1_CLK_ROUTE, CMX1_CLK_MASK, +# if defined(CONFIG_TQM8260) PC_MDIO, PC_MDCK }, +# else + 0x00000004, 0x00000100 }, +# endif #endif #ifdef CONFIG_FCC2_ENET { 1, CPM_CR_FCC2_SBLOCK, CPM_CR_FCC2_PAGE, PROFF_FCC2, SIU_INT_FCC2, (PC_F2RXCLK | PC_F2TXCLK), CMX2_CLK_ROUTE, CMX2_CLK_MASK, +# if defined(CONFIG_TQM8260) PC_MDIO, PC_MDCK }, +# elif defined(CONFIG_EST8260) || defined(CONFIG_ADS8260) + 0x00400000, 0x00200000 }, +# else + 0x00000002, 0x00000080 }, +# endif #endif #ifdef CONFIG_FCC3_ENET { 2, CPM_CR_FCC3_SBLOCK, CPM_CR_FCC3_PAGE, PROFF_FCC3, SIU_INT_FCC3, (PC_F3RXCLK | PC_F3TXCLK), CMX3_CLK_ROUTE, CMX3_CLK_MASK, +# if defined(CONFIG_TQM8260) PC_MDIO, PC_MDCK }, +# else + 0x00000001, 0x00000040 }, +# endif #endif }; @@ -230,9 +302,23 @@ struct fcc_enet_private { struct net_device_stats stats; uint tx_full; spinlock_t lock; - uint phy_address; - uint phy_type; - uint phy_duplex; + +#ifdef CONFIG_USE_MDIO + uint phy_id; + uint phy_id_done; + uint phy_status; + phy_info_t *phy; + struct tq_struct phy_task; + + uint sequence_done; + + uint phy_addr; +#endif /* CONFIG_USE_MDIO */ + + int link; + int old_link; + int full_duplex; + fcc_info_t *fip; }; @@ -244,55 +330,31 @@ static void init_fcc_ioports(fcc_info_t *fip, volatile iop8260_t *io, static void init_fcc_param(fcc_info_t *fip, struct net_device *dev, volatile immap_t *immap); -/* MII processing. We keep this as simple as possible. Requests are - * placed on the list (if there is room). When the request is finished - * by the MII, an optional function may be called. - */ -typedef struct mii_list { - uint mii_regval; - void (*mii_func)(uint val, struct net_device *dev); - struct mii_list *mii_next; -} mii_list_t; - -#define NMII 20 -mii_list_t mii_cmds[NMII]; -mii_list_t *mii_free; -mii_list_t *mii_head; -mii_list_t *mii_tail; - -static int phyaddr; -static uint phytype; - -static int mii_queue(int request, void (*func)(uint, struct net_device *)); -static void mii_startup_cmds(void); +#ifdef CONFIG_USE_MDIO +static int mii_queue(struct net_device *dev, int request, void (*func)(uint, struct net_device *)); static uint mii_send_receive(fcc_info_t *fip, uint cmd); +static void fcc_stop(struct net_device *dev); + /* Make MII read/write commands for the FCC. */ - -#define mk_mii_phyaddr(ADDR) (0x60020000 | ((ADDR) << 23) | (2 << 18)) - -#define mk_mii_read(REG) (0x60020000 | ((phyaddr << 23) | \ - (REG & 0x1f) << 18)) - -#define mk_mii_write(REG, VAL) (0x50020000 | ((phyaddr << 23) | \ - (REG & 0x1f) << 18) | \ +#define mk_mii_read(REG) (0x60020000 | ((REG & 0x1f) << 18)) +#define mk_mii_write(REG, VAL) (0x50020000 | ((REG & 0x1f) << 18) | \ (VAL & 0xffff)) +#define mk_mii_end 0 +#endif /* CONFIG_USE_MDIO */ static int -fcc_enet_open(struct net_device *dev) -{ - netif_start_queue(dev); - return 0; /* Always succeed */ -} - -static int fcc_enet_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct fcc_enet_private *cep = (struct fcc_enet_private *)dev->priv; volatile cbd_t *bdp; + if (!cep->link) { + /* Link is down or autonegotiation is in progress. */ + return 1; + } /* Fill in a Tx ring entry */ bdp = cep->cur_tx; @@ -307,24 +369,20 @@ fcc_enet_start_xmit(struct sk_buff *skb, struct net_device *dev) } #endif - /* Clear all of the status flags. - */ + /* Clear all of the status flags. */ bdp->cbd_sc &= ~BD_ENET_TX_STATS; - /* If the frame is short, tell CPM to pad it. - */ + /* If the frame is short, tell CPM to pad it. */ if (skb->len <= ETH_ZLEN) bdp->cbd_sc |= BD_ENET_TX_PAD; else bdp->cbd_sc &= ~BD_ENET_TX_PAD; - /* Set buffer length and buffer pointer. - */ + /* Set buffer length and buffer pointer. */ bdp->cbd_datlen = skb->len; bdp->cbd_bufaddr = __pa(skb->data); - /* Save skb pointer. - */ + /* Save skb pointer. */ cep->tx_skbuff[cep->skb_cur] = skb; cep->stats.tx_bytes += skb->len; @@ -338,14 +396,12 @@ fcc_enet_start_xmit(struct sk_buff *skb, struct net_device *dev) bdp->cbd_sc |= (BD_ENET_TX_READY | BD_ENET_TX_INTR | BD_ENET_TX_LAST | BD_ENET_TX_TC); #if 0 - /* Errata says don't do this. - */ + /* Errata says don't do this. */ cep->fccp->fcc_ftodr = 0x8000; #endif dev->trans_start = jiffies; - /* If this was the last BD in the ring, start at the beginning again. - */ + /* If this was the last BD in the ring, start at the beginning again. */ if (bdp->cbd_sc & BD_ENET_TX_WRAP) bdp = cep->tx_bd_base; else @@ -398,8 +454,7 @@ fcc_enet_timeout(struct net_device *dev) netif_wake_queue(dev); } -/* The interrupt handler. - */ +/* The interrupt handler. */ static void fcc_enet_interrupt(int irq, void * dev_id, struct pt_regs * regs) { @@ -469,13 +524,11 @@ fcc_enet_interrupt(int irq, void * dev_id, struct pt_regs * regs) if (bdp->cbd_sc & BD_ENET_TX_DEF) cep->stats.collisions++; - /* Free the sk buffer associated with this last transmit. - */ + /* Free the sk buffer associated with this last transmit. */ dev_kfree_skb_irq(cep->tx_skbuff[cep->skb_dirty]); cep->skb_dirty = (cep->skb_dirty + 1) & TX_RING_MOD_MASK; - /* Update pointer to next buffer descriptor to be transmitted. - */ + /* Update pointer to next buffer descriptor to be transmitted. */ if (bdp->cbd_sc & BD_ENET_TX_WRAP) bdp = cep->tx_bd_base; else @@ -510,8 +563,13 @@ fcc_enet_interrupt(int irq, void * dev_id, struct pt_regs * regs) * down. We now issue a restart transmit. Since the * errors close the BD and update the pointers, the restart * _should_ pick up without having to reset any of our - * pointers either. + * pointers either. Also, To workaround 8260 device erratum + * CPM37, we must disable and then re-enable the transmitter + * following a Late Collision, Underrun, or Retry Limit error. */ + cep->fccp->fcc_gfmr &= ~FCC_GFMR_ENT; + udelay(10); /* wait a few microseconds just on principle */ + cep->fccp->fcc_gfmr |= FCC_GFMR_ENT; cp = cpmp; cp->cp_cpcr = @@ -564,8 +622,7 @@ for (;;) { printk("CPM ENET: rcv is not first+last\n"); #endif - /* Frame too long or too short. - */ + /* Frame too long or too short. */ if (bdp->cbd_sc & (BD_ENET_RX_LG | BD_ENET_RX_SH)) cep->stats.rx_length_errors++; if (bdp->cbd_sc & BD_ENET_RX_NO) /* Frame alignment */ @@ -574,28 +631,22 @@ for (;;) { cep->stats.rx_crc_errors++; if (bdp->cbd_sc & BD_ENET_RX_OV) /* FIFO overrun */ cep->stats.rx_crc_errors++; - - /* Report late collisions as a frame error. - * On this error, the BD is closed, but we don't know what we - * have in the buffer. So, just drop this frame on the floor. - */ - if (bdp->cbd_sc & BD_ENET_RX_CL) { + if (bdp->cbd_sc & BD_ENET_RX_CL) /* Late Collision */ cep->stats.rx_frame_errors++; - } - else { - /* Process the incoming frame. - */ + if (!(bdp->cbd_sc & + (BD_ENET_RX_LG | BD_ENET_RX_SH | BD_ENET_RX_NO | BD_ENET_RX_CR + | BD_ENET_RX_OV | BD_ENET_RX_CL))) + { + /* Process the incoming frame. */ cep->stats.rx_packets++; - pkt_len = bdp->cbd_datlen; + + /* Remove the FCS from the packet length. */ + pkt_len = bdp->cbd_datlen - 4; cep->stats.rx_bytes += pkt_len; - /* This does 16 byte alignment, much more than we need. - * The packet length includes FCS, but we don't want to - * include that when passing upstream as it messes up - * bridging applications. - */ - skb = dev_alloc_skb(pkt_len-4); + /* This does 16 byte alignment, much more than we need. */ + skb = dev_alloc_skb(pkt_len); if (skb == NULL) { printk("%s: Memory squeeze, dropping packet.\n", dev->name); @@ -603,25 +654,22 @@ for (;;) { } else { skb->dev = dev; - skb_put(skb,pkt_len-4); /* Make room */ + skb_put(skb,pkt_len); /* Make room */ eth_copy_and_sum(skb, (unsigned char *)__va(bdp->cbd_bufaddr), - pkt_len-4, 0); + pkt_len, 0); skb->protocol=eth_type_trans(skb,dev); netif_rx(skb); } } - /* Clear the status flags for this buffer. - */ + /* Clear the status flags for this buffer. */ bdp->cbd_sc &= ~BD_ENET_RX_STATS; - /* Mark the buffer empty. - */ + /* Mark the buffer empty. */ bdp->cbd_sc |= BD_ENET_RX_EMPTY; - /* Update BD pointer to next entry. - */ + /* Update BD pointer to next entry. */ if (bdp->cbd_sc & BD_ENET_RX_WRAP) bdp = cep->rx_bd_base; else @@ -636,8 +684,7 @@ for (;;) { static int fcc_enet_close(struct net_device *dev) { - /* Don't know what to do yet. - */ + /* Don't know what to do yet. */ netif_stop_queue(dev); return 0; @@ -650,340 +697,527 @@ static struct net_device_stats *fcc_enet_get_stats(struct net_device *dev) return &cep->stats; } -/* The MII is simulated from the 8xx FEC implementation. The FCC - * is not responsible for the MII control/status interface. +#ifdef CONFIG_USE_MDIO + +/* NOTE: Most of the following comes from the FEC driver for 860. The + * overall structure of MII code has been retained (as it's proved stable + * and well-tested), but actual transfer requests are processed "at once" + * instead of being queued (there's no interrupt-driven MII transfer + * mechanism, one has to toggle the data/clock bits manually). */ -static void -fcc_enet_mii(struct net_device *dev) +static int +mii_queue(struct net_device *dev, int regval, void (*func)(uint, struct net_device *)) { - struct fcc_enet_private *fep; - mii_list_t *mip; - uint mii_reg; + struct fcc_enet_private *fep; + int retval, tmp; - fep = (struct fcc_enet_private *)dev->priv; -#if 0 - ep = &(((immap_t *)IMAP_ADDR)->im_cpm.cp_fec); - mii_reg = ep->fec_mii_data; -#endif - - if ((mip = mii_head) == NULL) { - printk("MII and no head!\n"); + /* Add PHY address to register command. */ + fep = dev->priv; + regval |= fep->phy_addr << 23; + + retval = 0; + + tmp = mii_send_receive(fep->fip, regval); + if (func) + func(tmp, dev); + + return retval; +} + +static void mii_do_cmd(struct net_device *dev, const phy_cmd_t *c) +{ + int k; + + if(!c) return; - } - if (mip->mii_func != NULL) - (*(mip->mii_func))(mii_reg, dev); + for(k = 0; (c+k)->mii_data != mk_mii_end; k++) + mii_queue(dev, (c+k)->mii_data, (c+k)->funct); +} - mii_head = mip->mii_next; - mip->mii_next = mii_free; - mii_free = mip; +static void mii_parse_sr(uint mii_reg, struct net_device *dev) +{ + volatile struct fcc_enet_private *fep = dev->priv; + uint s = fep->phy_status; -#if 0 - if ((mip = mii_head) != NULL) - ep->fec_mii_data = mip->mii_regval; -#endif + s &= ~(PHY_STAT_LINK | PHY_STAT_FAULT | PHY_STAT_ANC); + + if (mii_reg & 0x0004) + s |= PHY_STAT_LINK; + if (mii_reg & 0x0010) + s |= PHY_STAT_FAULT; + if (mii_reg & 0x0020) + s |= PHY_STAT_ANC; + + fep->phy_status = s; + fep->link = (s & PHY_STAT_LINK) ? 1 : 0; } -static int -mii_queue(int regval, void (*func)(uint, struct net_device *)) +static void mii_parse_cr(uint mii_reg, struct net_device *dev) { - unsigned long flags; - mii_list_t *mip; - int retval; + volatile struct fcc_enet_private *fep = dev->priv; + uint s = fep->phy_status; - retval = 0; + s &= ~(PHY_CONF_ANE | PHY_CONF_LOOP); - save_flags(flags); - cli(); - - if ((mip = mii_free) != NULL) { - mii_free = mip->mii_next; - mip->mii_regval = regval; - mip->mii_func = func; - mip->mii_next = NULL; - if (mii_head) { - mii_tail->mii_next = mip; - mii_tail = mip; - } - else { - mii_head = mii_tail = mip; -#if 0 - (&(((immap_t *)IMAP_ADDR)->im_cpm.cp_fec))->fec_mii_data = regval; -#endif - } - } - else { - retval = 1; - } + if (mii_reg & 0x1000) + s |= PHY_CONF_ANE; + if (mii_reg & 0x4000) + s |= PHY_CONF_LOOP; + + fep->phy_status = s; +} + +static void mii_parse_anar(uint mii_reg, struct net_device *dev) +{ + volatile struct fcc_enet_private *fep = dev->priv; + uint s = fep->phy_status; + + s &= ~(PHY_CONF_SPMASK); - restore_flags(flags); + if (mii_reg & 0x0020) + s |= PHY_CONF_10HDX; + if (mii_reg & 0x0040) + s |= PHY_CONF_10FDX; + if (mii_reg & 0x0080) + s |= PHY_CONF_100HDX; + if (mii_reg & 0x00100) + s |= PHY_CONF_100FDX; - return(retval); + fep->phy_status = s; } +/* ------------------------------------------------------------------------- */ +/* The Level one LXT970 is used by many boards */ -static volatile uint full_duplex; +#ifdef CONFIG_FCC_LXT970 -static void -mii_status(uint mii_reg, struct net_device *dev) +#define MII_LXT970_MIRROR 16 /* Mirror register */ +#define MII_LXT970_IER 17 /* Interrupt Enable Register */ +#define MII_LXT970_ISR 18 /* Interrupt Status Register */ +#define MII_LXT970_CONFIG 19 /* Configuration Register */ +#define MII_LXT970_CSR 20 /* Chip Status Register */ + +static void mii_parse_lxt970_csr(uint mii_reg, struct net_device *dev) { - volatile uint prev_duplex; + volatile struct fcc_enet_private *fep = dev->priv; + uint s = fep->phy_status; - if (((mii_reg >> 18) & 0x1f) == 1) { - /* status register. - */ - printk("fec: "); - if (mii_reg & 0x0004) - printk("link up"); - else - printk("link down"); + s &= ~(PHY_STAT_SPMASK); - if (mii_reg & 0x0010) - printk(",remote fault"); - if (mii_reg & 0x0020) - printk(",auto complete"); - printk("\n"); - } - if (((mii_reg >> 18) & 0x1f) == 0x14) { - /* Extended chip status register. - */ - prev_duplex = full_duplex; - printk("fec: "); - if (mii_reg & 0x0800) - printk("100 Mbps"); + if (mii_reg & 0x0800) { + if (mii_reg & 0x1000) + s |= PHY_STAT_100FDX; + else + s |= PHY_STAT_100HDX; + } else { + if (mii_reg & 0x1000) + s |= PHY_STAT_10FDX; else - printk("10 Mbps"); + s |= PHY_STAT_10HDX; + } - if (mii_reg & 0x1000) { - printk(", Full-Duplex\n"); - full_duplex = 1; - } - else { - printk(", Half-Duplex\n"); - full_duplex = 0; - } + fep->phy_status = s; +} + +static phy_info_t phy_info_lxt970 = { + 0x07810000, + "LXT970", + + (const phy_cmd_t []) { /* config */ #if 0 - if (prev_duplex != full_duplex) - restart_fec(dev); -#endif - } - if (((mii_reg >> 18) & 0x1f) == 31) { - /* QS6612 PHY Control/Status. - * OK, now we have it all, so figure out what is going on. +// { mk_mii_write(MII_REG_ANAR, 0x0021), NULL }, + + /* Set default operation of 100-TX....for some reason + * some of these bits are set on power up, which is wrong. */ - prev_duplex = full_duplex; - printk("fec: "); + { mk_mii_write(MII_LXT970_CONFIG, 0), NULL }, +#endif + { mk_mii_read(MII_REG_CR), mii_parse_cr }, + { mk_mii_read(MII_REG_ANAR), mii_parse_anar }, + { mk_mii_end, } + }, + (const phy_cmd_t []) { /* startup - enable interrupts */ + { mk_mii_write(MII_LXT970_IER, 0x0002), NULL }, + { mk_mii_write(MII_REG_CR, 0x1200), NULL }, /* autonegotiate */ + { mk_mii_end, } + }, + (const phy_cmd_t []) { /* ack_int */ + /* read SR and ISR to acknowledge */ + + { mk_mii_read(MII_REG_SR), mii_parse_sr }, + { mk_mii_read(MII_LXT970_ISR), NULL }, + + /* find out the current status */ + + { mk_mii_read(MII_LXT970_CSR), mii_parse_lxt970_csr }, + { mk_mii_end, } + }, + (const phy_cmd_t []) { /* shutdown - disable interrupts */ + { mk_mii_write(MII_LXT970_IER, 0x0000), NULL }, + { mk_mii_end, } + }, +}; - mii_reg = (mii_reg >> 2) & 7; +#endif /* CONFIG_FEC_LXT970 */ - if (mii_reg & 1) - printk("10 Mbps"); - else - printk("100 Mbps"); +/* ------------------------------------------------------------------------- */ +/* The Level one LXT971 is used on some of my custom boards */ - if (mii_reg > 4) { - printk(", Full-Duplex\n"); - full_duplex = 1; - } - else { - printk(", Half-Duplex\n"); - full_duplex = 0; - } +#ifdef CONFIG_FCC_LXT971 -#if 0 - if (prev_duplex != full_duplex) - restart_fec(dev); -#endif - } -} +/* register definitions for the 971 */ -static uint phyno; +#define MII_LXT971_PCR 16 /* Port Control Register */ +#define MII_LXT971_SR2 17 /* Status Register 2 */ +#define MII_LXT971_IER 18 /* Interrupt Enable Register */ +#define MII_LXT971_ISR 19 /* Interrupt Status Register */ +#define MII_LXT971_LCR 20 /* LED Control Register */ +#define MII_LXT971_TCR 30 /* Transmit Control Register */ -static void -mii_discover_phy3(uint mii_reg, struct net_device *dev) +/* + * I had some nice ideas of running the MDIO faster... + * The 971 should support 8MHz and I tried it, but things acted really + * weird, so 2.5 MHz ought to be enough for anyone... + */ + +static void mii_parse_lxt971_sr2(uint mii_reg, struct net_device *dev) { - phytype <<= 16; - phytype |= (mii_reg & 0xffff); - printk("fec: Phy @ 0x%x, type 0x%08x\n", phyno, phytype); - mii_startup_cmds(); + volatile struct fcc_enet_private *fep = dev->priv; + uint s = fep->phy_status; + + s &= ~(PHY_STAT_SPMASK); + + if (mii_reg & 0x4000) { + if (mii_reg & 0x0200) + s |= PHY_STAT_100FDX; + else + s |= PHY_STAT_100HDX; + } else { + if (mii_reg & 0x0200) + s |= PHY_STAT_10FDX; + else + s |= PHY_STAT_10HDX; + } + if (mii_reg & 0x0008) + s |= PHY_STAT_FAULT; + + fep->phy_status = s; } -static void -mii_discover_phy(uint mii_reg, struct net_device *dev) +static phy_info_t phy_info_lxt971 = { + 0x0001378e, + "LXT971", + + (const phy_cmd_t []) { /* config */ +// { mk_mii_write(MII_REG_ANAR, 0x021), NULL }, /* 10 Mbps, HD */ + { mk_mii_read(MII_REG_CR), mii_parse_cr }, + { mk_mii_read(MII_REG_ANAR), mii_parse_anar }, + { mk_mii_end, } + }, + (const phy_cmd_t []) { /* startup - enable interrupts */ + { mk_mii_write(MII_LXT971_IER, 0x00f2), NULL }, + { mk_mii_write(MII_REG_CR, 0x1200), NULL }, /* autonegotiate */ + + /* Somehow does the 971 tell me that the link is down + * the first read after power-up. + * read here to get a valid value in ack_int */ + + { mk_mii_read(MII_REG_SR), mii_parse_sr }, + { mk_mii_end, } + }, + (const phy_cmd_t []) { /* ack_int */ + /* find out the current status */ + + { mk_mii_read(MII_REG_SR), mii_parse_sr }, + { mk_mii_read(MII_LXT971_SR2), mii_parse_lxt971_sr2 }, + + /* we only need to read ISR to acknowledge */ + + { mk_mii_read(MII_LXT971_ISR), NULL }, + { mk_mii_end, } + }, + (const phy_cmd_t []) { /* shutdown - disable interrupts */ + { mk_mii_write(MII_LXT971_IER, 0x0000), NULL }, + { mk_mii_end, } + }, +}; + +#endif /* CONFIG_FEC_LXT970 */ + + +/* ------------------------------------------------------------------------- */ +/* The Quality Semiconductor QS6612 is used on the RPX CLLF */ + +#ifdef CONFIG_FCC_QS6612 + +/* register definitions */ + +#define MII_QS6612_MCR 17 /* Mode Control Register */ +#define MII_QS6612_FTR 27 /* Factory Test Register */ +#define MII_QS6612_MCO 28 /* Misc. Control Register */ +#define MII_QS6612_ISR 29 /* Interrupt Source Register */ +#define MII_QS6612_IMR 30 /* Interrupt Mask Register */ +#define MII_QS6612_PCR 31 /* 100BaseTx PHY Control Reg. */ + +static void mii_parse_qs6612_pcr(uint mii_reg, struct net_device *dev) { - if (phyno < 32) { - if ((phytype = (mii_reg & 0xffff)) != 0xffff) { - phyaddr = phyno; - mii_queue(mk_mii_read(3), mii_discover_phy3); - } - else { - phyno++; - mii_queue(mk_mii_phyaddr(phyno), mii_discover_phy); - } - } - else { - printk("FEC: No PHY device found.\n"); + volatile struct fcc_enet_private *fep = dev->priv; + uint s = fep->phy_status; + + s &= ~(PHY_STAT_SPMASK); + + switch((mii_reg >> 2) & 7) { + case 1: s |= PHY_STAT_10HDX; break; + case 2: s |= PHY_STAT_100HDX; break; + case 5: s |= PHY_STAT_10FDX; break; + case 6: s |= PHY_STAT_100FDX; break; } + + fep->phy_status = s; } -static void -mii_discover_phy_poll(fcc_info_t *fip) +static phy_info_t phy_info_qs6612 = { + 0x00181440, + "QS6612", + + (const phy_cmd_t []) { /* config */ +// { mk_mii_write(MII_REG_ANAR, 0x061), NULL }, /* 10 Mbps */ + + /* The PHY powers up isolated on the RPX, + * so send a command to allow operation. + */ + + { mk_mii_write(MII_QS6612_PCR, 0x0dc0), NULL }, + + /* parse cr and anar to get some info */ + + { mk_mii_read(MII_REG_CR), mii_parse_cr }, + { mk_mii_read(MII_REG_ANAR), mii_parse_anar }, + { mk_mii_end, } + }, + (const phy_cmd_t []) { /* startup - enable interrupts */ + { mk_mii_write(MII_QS6612_IMR, 0x003a), NULL }, + { mk_mii_write(MII_REG_CR, 0x1200), NULL }, /* autonegotiate */ + { mk_mii_end, } + }, + (const phy_cmd_t []) { /* ack_int */ + + /* we need to read ISR, SR and ANER to acknowledge */ + + { mk_mii_read(MII_QS6612_ISR), NULL }, + { mk_mii_read(MII_REG_SR), mii_parse_sr }, + { mk_mii_read(MII_REG_ANER), NULL }, + + /* read pcr to get info */ + + { mk_mii_read(MII_QS6612_PCR), mii_parse_qs6612_pcr }, + { mk_mii_end, } + }, + (const phy_cmd_t []) { /* shutdown - disable interrupts */ + { mk_mii_write(MII_QS6612_IMR, 0x0000), NULL }, + { mk_mii_end, } + }, +}; + + +#endif /* CONFIG_FEC_QS6612 */ + + +static phy_info_t *phy_info[] = { + +#ifdef CONFIG_FCC_LXT970 + &phy_info_lxt970, +#endif /* CONFIG_FEC_LXT970 */ + +#ifdef CONFIG_FCC_LXT971 + &phy_info_lxt971, +#endif /* CONFIG_FEC_LXT971 */ + +#ifdef CONFIG_FCC_QS6612 + &phy_info_qs6612, +#endif /* CONFIG_FEC_LXT971 */ + + NULL +}; + +static void mii_display_status(struct net_device *dev) { - uint rv; - int i; + volatile struct fcc_enet_private *fep = dev->priv; + uint s = fep->phy_status; + + if (!fep->link && !fep->old_link) { + /* Link is still down - don't print anything */ + return; + } + + printk("%s: status: ", dev->name); - for (i=0; i<32; i++) { - rv = mii_send_receive(fip, mk_mii_phyaddr(i)); - if ((phytype = (rv & 0xffff)) != 0xffff) { - phyaddr = i; - rv = mii_send_receive(fip, mk_mii_read(3)); - phytype <<= 16; - phytype |= (rv & 0xffff); - printk("fec: Phy @ 0x%x, type 0x%08x\n", phyaddr, phytype); + if (!fep->link) { + printk("link down"); + } else { + printk("link up"); + + switch(s & PHY_STAT_SPMASK) { + case PHY_STAT_100FDX: printk(", 100 Mbps Full Duplex"); break; + case PHY_STAT_100HDX: printk(", 100 Mbps Half Duplex"); break; + case PHY_STAT_10FDX: printk(", 10 Mbps Full Duplex"); break; + case PHY_STAT_10HDX: printk(", 10 Mbps Half Duplex"); break; + default: + printk(", Unknown speed/duplex"); } + + if (s & PHY_STAT_ANC) + printk(", auto-negotiation complete"); } + + if (s & PHY_STAT_FAULT) + printk(", remote fault"); + + printk(".\n"); } -static void -mii_startup_cmds(void) +static void mii_display_config(struct net_device *dev) { + volatile struct fcc_enet_private *fep = dev->priv; + uint s = fep->phy_status; -#if 1 - /* Level One PHY. - */ + printk("%s: config: auto-negotiation ", dev->name); - /* Read status registers to clear any pending interrupt. - */ - mii_queue(mk_mii_read(1), mii_status); - mii_queue(mk_mii_read(18), mii_status); + if (s & PHY_CONF_ANE) + printk("on"); + else + printk("off"); - /* Read extended chip status register. - */ - mii_queue(mk_mii_read(0x14), mii_status); + if (s & PHY_CONF_100FDX) + printk(", 100FDX"); + if (s & PHY_CONF_100HDX) + printk(", 100HDX"); + if (s & PHY_CONF_10FDX) + printk(", 10FDX"); + if (s & PHY_CONF_10HDX) + printk(", 10HDX"); + if (!(s & PHY_CONF_SPMASK)) + printk(", No speed/duplex selected?"); - /* Set default operation of 100-TX....for some reason - * some of these bits are set on power up, which is wrong. - */ - mii_queue(mk_mii_write(0x13, 0), NULL); + if (s & PHY_CONF_LOOP) + printk(", loopback enabled"); - /* Enable Link status change interrupts. - */ - mii_queue(mk_mii_write(0x11, 0x0002), NULL); + printk(".\n"); - /* Don't advertize Full duplex. - mii_queue(mk_mii_write(0x04, 0x0021), NULL); - */ -#endif + fep->sequence_done = 1; +} +static void mii_relink(struct net_device *dev) +{ + struct fcc_enet_private *fep = dev->priv; + int duplex; + + fep->link = (fep->phy_status & PHY_STAT_LINK) ? 1 : 0; + mii_display_status(dev); + fep->old_link = fep->link; + + if (fep->link) { + duplex = 0; + if (fep->phy_status + & (PHY_STAT_100FDX | PHY_STAT_10FDX)) + duplex = 1; + fcc_restart(dev, duplex); + } else { + fcc_stop(dev); + } } -/* This supports the mii_link interrupt below. - * We should get called three times. Once for register 1, once for - * register 18, and once for register 20. - */ -static uint mii_saved_reg1; +static void mii_queue_relink(uint mii_reg, struct net_device *dev) +{ + struct fcc_enet_private *fep = dev->priv; + fep->phy_task.routine = (void *)mii_relink; + fep->phy_task.data = dev; + schedule_task(&fep->phy_task); +} + +static void mii_queue_config(uint mii_reg, struct net_device *dev) +{ + struct fcc_enet_private *fep = dev->priv; + + fep->phy_task.routine = (void *)mii_display_config; + fep->phy_task.data = dev; + schedule_task(&fep->phy_task); +} + + + +phy_cmd_t phy_cmd_relink[] = { { mk_mii_read(MII_REG_CR), mii_queue_relink }, + { mk_mii_end, } }; +phy_cmd_t phy_cmd_config[] = { { mk_mii_read(MII_REG_CR), mii_queue_config }, + { mk_mii_end, } }; + + +/* Read remainder of PHY ID. +*/ static void -mii_relink(uint mii_reg, struct net_device *dev) +mii_discover_phy3(uint mii_reg, struct net_device *dev) { - volatile uint prev_duplex; - unsigned long flags; + struct fcc_enet_private *fep; + int i; - if (((mii_reg >> 18) & 0x1f) == 1) { - /* Just save the status register and get out. - */ - mii_saved_reg1 = mii_reg; - return; - } - if (((mii_reg >> 18) & 0x1f) == 18) { - /* Not much here, but has to be read to clear the - * interrupt condition. - */ - if ((mii_reg & 0x8000) == 0) - printk("fec: re-link and no IRQ?\n"); - if ((mii_reg & 0x4000) == 0) - printk("fec: no PHY power?\n"); - } - if (((mii_reg >> 18) & 0x1f) == 20) { - /* Extended chip status register. - * OK, now we have it all, so figure out what is going on. - */ - prev_duplex = full_duplex; - printk("fec: "); - if (mii_saved_reg1 & 0x0004) - printk("link up"); - else - printk("link down"); + fep = dev->priv; + fep->phy_id |= (mii_reg & 0xffff); - if (mii_saved_reg1 & 0x0010) - printk(", remote fault"); - if (mii_saved_reg1 & 0x0020) - printk(", auto complete"); + for(i = 0; phy_info[i]; i++) + if(phy_info[i]->id == (fep->phy_id >> 4)) + break; - if (mii_reg & 0x0800) - printk(", 100 Mbps"); - else - printk(", 10 Mbps"); + if(!phy_info[i]) + panic("%s: PHY id 0x%08x is not supported!\n", + dev->name, fep->phy_id); - if (mii_reg & 0x1000) { - printk(", Full-Duplex\n"); - full_duplex = 1; - } - else { - printk(", Half-Duplex\n"); - full_duplex = 0; - } - if (prev_duplex != full_duplex) { - save_flags(flags); - cli(); -#if 0 - restart_fec(dev); -#endif - restore_flags(flags); - } - } - if (((mii_reg >> 18) & 0x1f) == 31) { - /* QS6612 PHY Control/Status. - * OK, now we have it all, so figure out what is going on. - */ - prev_duplex = full_duplex; - printk("fec: "); - if (mii_saved_reg1 & 0x0004) - printk("link up"); - else - printk("link down"); + fep->phy = phy_info[i]; - if (mii_saved_reg1 & 0x0010) - printk(", remote fault"); - if (mii_saved_reg1 & 0x0020) - printk(", auto complete"); + printk("%s: Phy @ 0x%x, type %s (0x%08x)\n", + dev->name, fep->phy_addr, fep->phy->name, fep->phy_id); +} - mii_reg = (mii_reg >> 2) & 7; +/* Scan all of the MII PHY addresses looking for someone to respond + * with a valid ID. This usually happens quickly. + */ +static void +mii_discover_phy(uint mii_reg, struct net_device *dev) +{ + struct fcc_enet_private *fep; + uint phytype; - if (mii_reg & 1) - printk(", 10 Mbps"); - else - printk(", 100 Mbps"); + fep = dev->priv; - if (mii_reg > 4) { - printk(", Full-Duplex\n"); - full_duplex = 1; - } - else { - printk(", Half-Duplex\n"); - full_duplex = 0; - } + if ((phytype = (mii_reg & 0xfff)) != 0xfff) { -#if 0 - if (prev_duplex != full_duplex) { - save_flags(flags); - cli(); - restart_fec(dev); - restore_flags(flags); + /* Got first part of ID, now get remainder. */ + fep->phy_id = phytype << 16; + mii_queue(dev, mk_mii_read(MII_REG_PHYIR2), mii_discover_phy3); + } else { + fep->phy_addr++; + if (fep->phy_addr < 32) { + mii_queue(dev, mk_mii_read(MII_REG_PHYIR1), + mii_discover_phy); + } else { + printk("fec: No PHY device found.\n"); } -#endif } } +/* This interrupt occurs when the PHY detects a link change. */ +static void +mii_link_interrupt(int irq, void * dev_id, struct pt_regs * regs) +{ + struct net_device *dev = dev_id; + struct fcc_enet_private *fep = dev->priv; + + mii_do_cmd(dev, fep->phy->ack_int); + mii_do_cmd(dev, phy_cmd_relink); /* restart and display status */ +} + +#endif /* CONFIG_USE_MDIO */ + /* Set or clear the multicast filter for this adaptor. * Skeleton taken from sunlance driver. * The CPM Ethernet implementation allows Multicast as well as individual @@ -1062,6 +1296,33 @@ return; } } + +/* Set the individual MAC address. + */ +int fcc_enet_set_mac_address(struct net_device *dev, void *p) +{ + struct sockaddr *addr= (struct sockaddr *) p; + struct fcc_enet_private *cep; + volatile fcc_enet_t *ep; + unsigned char *eap; + int i; + + cep = (struct fcc_enet_private *)(dev->priv); + ep = cep->ep; + + if (netif_running(dev)) + return -EBUSY; + + memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); + + eap = (unsigned char *) &(ep->fen_paddrh); + for (i=5; i>=0; i--) + *eap++ = addr->sa_data[i]; + + return 0; +} + + /* Initialize the CPM Ethernet on FCC. */ int __init fec_enet_init(void) @@ -1113,19 +1374,22 @@ int __init fec_enet_init(void) dev->stop = fcc_enet_close; dev->get_stats = fcc_enet_get_stats; dev->set_multicast_list = set_multicast_list; + dev->set_mac_address = fcc_enet_set_mac_address; init_fcc_startup(fip, dev); - printk("%s: FCC ENET Version 0.2, ", dev->name); + printk("%s: FCC ENET Version 0.3, ", dev->name); for (i=0; i<5; i++) printk("%02x:", dev->dev_addr[i]); printk("%02x\n", dev->dev_addr[5]); - /* This is just a hack for now that works only on the EST - * board, or anything else that has MDIO/CK configured. - * It is mainly to test the MII software clocking. - */ - mii_discover_phy_poll(fip); +#ifdef CONFIG_USE_MDIO + /* Queue up command to detect the PHY and initialize the + * remainder of the interface. + */ + cep->phy_addr = 0; + mii_queue(dev, mk_mii_read(MII_REG_PHYIR1), mii_discover_phy); +#endif /* CONFIG_USE_MDIO */ fip++; } @@ -1200,12 +1464,14 @@ init_fcc_ioports(fcc_info_t *fip, volatile iop8260_t *io, io->iop_pdirc &= ~(fip->fc_trxclocks); io->iop_pparc |= fip->fc_trxclocks; +#ifdef CONFIG_USE_MDIO /* ....and the MII serial clock/data. */ io->iop_pdatc |= (fip->fc_mdio | fip->fc_mdck); - io->iop_podrc |= fip->fc_mdio; + io->iop_podrc &= ~(fip->fc_mdio | fip->fc_mdck); io->iop_pdirc |= (fip->fc_mdio | fip->fc_mdck); io->iop_pparc &= ~(fip->fc_mdio | fip->fc_mdck); +#endif /* CONFIG_USE_MDIO */ /* Configure Serial Interface clock routing. * First, clear all FCC bits to zero, @@ -1446,6 +1712,12 @@ init_fcc_startup(fcc_info_t *fip, struct net_device *dev) "fenet", dev) < 0) printk("Can't get FCC IRQ %d\n", fip->fc_interrupt); +#ifdef CONFIG_USE_MDIO + if (request_8xxirq(PHY_INTERRUPT, mii_link_interrupt, 0, + "mii", dev) < 0) + printk("Can't get MII IRQ %d\n", fip->fc_interrupt); +#endif /* CONFIG_USE_MDIO */ + /* Set GFMR to enable Ethernet operating mode. */ fccp->fcc_gfmr = (FCC_GFMR_TCI | FCC_GFMR_MODE_ENET); @@ -1460,11 +1732,25 @@ init_fcc_startup(fcc_info_t *fip, struct net_device *dev) */ fccp->fcc_fpsmr = FCC_PSMR_ENCRC; - /* And last, enable the transmit and receive processing. +#ifdef CONFIG_ADS8260 + /* Enable the PHY. */ - fccp->fcc_gfmr |= (FCC_GFMR_ENR | FCC_GFMR_ENT); + ads_csr_addr[1] |= BCSR1_FETH_RST; /* Remove reset */ + ads_csr_addr[1] &= ~BCSR1_FETHIEN; /* Enable */ +#endif + +#if defined(CONFIG_USE_MDIO) || defined(CONFIG_TQM8260) + /* start in full duplex mode, and negotiate speed + */ + fcc_restart (dev, 1); +#else + /* start in half duplex mode + */ + fcc_restart (dev, 0); +#endif } +#ifdef CONFIG_USE_MDIO /* MII command/status interface. * I'm not going to describe all of the details. You can find the * protocol definition in many other places, including the data sheet @@ -1472,136 +1758,153 @@ init_fcc_startup(fcc_info_t *fip, struct net_device *dev) * I wonder what "they" were thinking (maybe weren't) when they leave * the I2C in the CPM but I have to toggle these bits...... */ + +#define FCC_PDATC_MDIO(bit) \ + if (bit) \ + io->iop_pdatc |= fip->fc_mdio; \ + else \ + io->iop_pdatc &= ~fip->fc_mdio; + +#define FCC_PDATC_MDC(bit) \ + if (bit) \ + io->iop_pdatc |= fip->fc_mdck; \ + else \ + io->iop_pdatc &= ~fip->fc_mdck; + static uint mii_send_receive(fcc_info_t *fip, uint cmd) { - unsigned long flags; uint retval; - int read_op, i; + int read_op, i, off; volatile immap_t *immap; volatile iop8260_t *io; immap = (immap_t *)IMAP_ADDR; io = &immap->im_ioport; - /* When we get here, both clock and data are high, outputs. - * Output is open drain. - * Data transitions on high->low clock, is valid on low->high clock. - * Spec says edge transitions no closer than 160 nSec, minimum clock - * cycle 400 nSec. I could only manage about 500 nSec edges with - * an XOR loop, so I won't worry about delays yet. - * I disable interrupts during bit flipping to ensure atomic - * updates of the registers. I do lots of interrupt disable/enable - * to ensure we don't hang out too long with interrupts disabled. - */ - - /* First, crank out 32 1-bits as preamble. - * This is 64 transitions to clock the bits, with clock/data - * left high. - */ - save_flags(flags); - cli(); - for (i=0; i<64; i++) { - io->iop_pdatc ^= fip->fc_mdck; - udelay(0); - } - restore_flags(flags); + io->iop_pdirc |= (fip->fc_mdio | fip->fc_mdck); read_op = ((cmd & 0xf0000000) == 0x60000000); - /* We return the command word on a write op, or the command portion - * plus the new data on a read op. This is what the 8xx FEC does, - * and it allows the functions to simply look at the returned value - * and know the PHY/register as well. + /* Write preamble */ - if (read_op) - retval = cmd; - else - retval = (cmd >> 16); - - /* Clock out the first 16 MS bits of the command. - */ - save_flags(flags); - cli(); - for (i=0; i<16; i++) { - io->iop_pdatc &= ~(fip->fc_mdck); - if (cmd & 0x80000000) - io->iop_pdatc |= fip->fc_mdio; - else - io->iop_pdatc &= ~(fip->fc_mdio); - cmd <<= 1; - io->iop_pdatc |= fip->fc_mdck; - udelay(0); + for (i = 0; i < 32; i++) + { + FCC_PDATC_MDC(0); + FCC_PDATC_MDIO(1); + udelay(1); + FCC_PDATC_MDC(1); + udelay(1); } - /* Do the turn-around. If read op, we make the IO and input. - * If write op, do the 1/0 thing. + /* Write data */ - io->iop_pdatc &= ~(fip->fc_mdck); - if (read_op) - io->iop_pdirc &= ~(fip->fc_mdio); - else - io->iop_pdatc |= fip->fc_mdio; - io->iop_pdatc |= fip->fc_mdck; + for (i = 0, off = 31; i < (read_op ? 14 : 32); i++, --off) + { + FCC_PDATC_MDC(0); + FCC_PDATC_MDIO((cmd >> off) & 0x00000001); + udelay(1); + FCC_PDATC_MDC(1); + udelay(1); + } - /* I do this mainly to get just a little delay. - */ - restore_flags(flags); - save_flags(flags); - cli(); - io->iop_pdatc &= ~(fip->fc_mdck); - io->iop_pdirc &= ~(fip->fc_mdio); - io->iop_pdatc |= fip->fc_mdck; - - restore_flags(flags); - save_flags(flags); - cli(); - - /* For read, clock in 16 bits. For write, clock out - * rest of command. - */ - if (read_op) { - io->iop_pdatc &= ~(fip->fc_mdck); - udelay(0); - for (i=0; i<16; i++) { - io->iop_pdatc |= fip->fc_mdck; - udelay(0); + retval = cmd; + + if (read_op) + { + retval >>= 16; + + FCC_PDATC_MDC(0); + io->iop_pdirc &= ~fip->fc_mdio; + udelay(1); + FCC_PDATC_MDC(1); + udelay(1); + FCC_PDATC_MDC(0); + udelay(1); + + for (i = 0, off = 15; i < 16; i++, off--) + { + FCC_PDATC_MDC(1); retval <<= 1; if (io->iop_pdatc & fip->fc_mdio) - retval |= 1; - io->iop_pdatc &= ~(fip->fc_mdck); - udelay(0); + retval++; + udelay(1); + FCC_PDATC_MDC(0); + udelay(1); } } - else { - for (i=0; i<16; i++) { - io->iop_pdatc &= ~(fip->fc_mdck); - if (cmd & 0x80000000) - io->iop_pdatc |= fip->fc_mdio; - else - io->iop_pdatc &= ~(fip->fc_mdio); - cmd <<= 1; - io->iop_pdatc |= fip->fc_mdck; - udelay(0); - } - io->iop_pdatc &= ~(fip->fc_mdck); + + io->iop_pdirc |= (fip->fc_mdio | fip->fc_mdck); + + for (i = 0; i < 32; i++) + { + FCC_PDATC_MDC(0); + FCC_PDATC_MDIO(1); + udelay(1); + FCC_PDATC_MDC(1); + udelay(1); } - restore_flags(flags); - /* Some diagrams show two 1 bits for "idle". I don't know if - * this is really necessary or if it was just to indicate nothing - * is going to happen for a while. - * Make the data pin an output, set the data high, and clock it. - */ - save_flags(flags); - cli(); - io->iop_pdatc |= fip->fc_mdio; - io->iop_pdirc |= fip->fc_mdio; - for (i=0; i<3; i++) - io->iop_pdatc ^= fip->fc_mdck; - restore_flags(flags); - - /* We exit with the same conditions as entry. - */ - return(retval); + return retval; +} + +static void +fcc_stop(struct net_device *dev) +{ + volatile fcc_t *fccp; + struct fcc_enet_private *fcp; + + fcp = (struct fcc_enet_private *)(dev->priv); + fccp = fcp->fccp; + + /* Disable transmit/receive */ + fccp->fcc_gfmr &= ~(FCC_GFMR_ENR | FCC_GFMR_ENT); } +#endif /* CONFIG_USE_MDIO */ + +static void +fcc_restart(struct net_device *dev, int duplex) +{ + volatile fcc_t *fccp; + struct fcc_enet_private *fcp; + + fcp = (struct fcc_enet_private *)(dev->priv); + fccp = fcp->fccp; + + if (duplex) + fccp->fcc_fpsmr |= FCC_PSMR_FDE; + else + fccp->fcc_fpsmr &= ~FCC_PSMR_FDE; + + /* Enable transmit/receive */ + fccp->fcc_gfmr |= FCC_GFMR_ENR | FCC_GFMR_ENT; +} + +static int +fcc_enet_open(struct net_device *dev) +{ + struct fcc_enet_private *fep = dev->priv; + +#ifdef CONFIG_USE_MDIO + fep->sequence_done = 0; + fep->link = 0; + + if (fep->phy) { + mii_do_cmd(dev, fep->phy->ack_int); + mii_do_cmd(dev, fep->phy->config); + mii_do_cmd(dev, phy_cmd_config); /* display configuration */ + while(!fep->sequence_done) + schedule(); + + mii_do_cmd(dev, fep->phy->startup); + netif_start_queue(dev); + return 0; /* Success */ + } + return -ENODEV; /* No PHY we understand */ +#else + fep->link = 1; + netif_start_queue(dev); + return 0; /* Always succeed */ +#endif /* CONFIG_USE_MDIO */ +} + diff --git a/arch/ppc/8260_io/uart.c b/arch/ppc/8260_io/uart.c index 419a38c361d9..8f3a9e91de10 100644 --- a/arch/ppc/8260_io/uart.c +++ b/arch/ppc/8260_io/uart.c @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.uart.c 1.6 05/17/01 18:14:20 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * UART driver for MPC8260 CPM SCC or SMC @@ -53,12 +53,21 @@ #ifdef CONFIG_SERIAL_CONSOLE #include <linux/console.h> +/* SCC Console configuration. Not quite finished. The SCC_CONSOLE + * should be the number of the SCC to use, but only SCC1 will + * work at this time. + */ +#ifdef CONFIG_SCC_CONSOLE +#define SCC_CONSOLE 1 +#endif + /* this defines the index into rs_table for the port to use */ #ifndef CONFIG_SERIAL_CONSOLE_PORT #define CONFIG_SERIAL_CONSOLE_PORT 0 #endif #endif +#define CONFIG_SERIAL_CONSOLE_PORT 0 #define TX_WAKEUP ASYNC_SHARE_IRQ @@ -105,6 +114,18 @@ static int serial_console_setup(struct console *co, char *options); */ #define smc_scc_num hub6 +/* The choice of serial port to use for KGDB. If the system has + * two ports, you can use one for console and one for KGDB (which + * doesn't make sense to me, but people asked for it). + */ +#ifdef CONFIG_KGDB_TTYS1 +#define KGDB_SER_IDX 1 /* SCC2/SMC2 */ +#else +#define KGDB_SER_IDX 0 /* SCC1/SMC1 */ +#endif + +#ifndef SCC_CONSOLE + /* SMC2 is sometimes used for low performance TDM interfaces. Define * this as 1 if you want SMC2 as a serial port UART managed by this driver. * Define this as 0 if you wish to use SMC2 for something else. @@ -129,10 +150,26 @@ static struct serial_state rs_table[] = { #if USE_SMC2 { 0, 0, PROFF_SMC2, SIU_INT_SMC2, 0, 1 }, /* SMC2 ttyS1 */ #endif - { 0, 0, PROFF_SCC2, SIU_INT_SCC2, 0, SCC_NUM_BASE}, /* SCC2 ttyS2 */ - { 0, 0, PROFF_SCC3, SIU_INT_SCC3, 0, SCC_NUM_BASE + 1}, /* SCC3 ttyS3 */ +#ifndef CONFIG_SCC1_ENET + { 0, 0, PROFF_SCC1, SIU_INT_SCC1, 0, SCC_NUM_BASE}, /* SCC1 ttyS2 */ +#endif +#ifndef CONFIG_SCC2_ENET + { 0, 0, PROFF_SCC2, SIU_INT_SCC2, 0, SCC_NUM_BASE + 1}, /* SCC2 ttyS3 */ +#endif }; +#else /* SCC_CONSOLE */ +#define SCC_NUM_BASE 0 /* SCC base tty "number" */ +#define SCC_IDX_BASE 0 /* table index */ +static struct serial_state rs_table[] = { + /* UART CLK PORT IRQ FLAGS NUM */ + { 0, 0, PROFF_SCC1, SIU_INT_SCC1, 0, SCC_NUM_BASE}, /* SCC1 ttyS2 */ + { 0, 0, PROFF_SCC2, SIU_INT_SCC2, 0, SCC_NUM_BASE + 1}, /* SCC2 ttyS3 */ +}; +#endif /* SCC_CONSOLE */ + +#define PORT_NUM(P) (((P) < (SCC_NUM_BASE)) ? (P) : (P)-(SCC_NUM_BASE)) + #define NR_PORTS (sizeof(rs_table)/sizeof(struct serial_state)) static struct tty_struct *serial_table[NR_PORTS]; @@ -349,6 +386,13 @@ static _INLINE_ void receive_chars(ser_info_t *info) i = bdp->cbd_datlen; cp = (unsigned char *)__va(bdp->cbd_bufaddr); status = bdp->cbd_sc; +#ifdef CONFIG_KGDB + if (info->state->smc_scc_num == KGDB_SER_IDX) { + if (*cp == 0x03 || *cp == '$') + breakpoint(); + return; + } +#endif /* Check to see if there is room in the tty buffer for * the characters in our BD buffer. If not, we exit @@ -775,7 +819,10 @@ static void shutdown(ser_info_t * info) else { sccp = &immr->im_scc[idx - SCC_IDX_BASE]; sccp->scc_sccm &= ~(UART_SCCM_TX | UART_SCCM_RX); - sccp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT); +#ifdef CONFIG_SERIAL_CONSOLE + if (idx != CONFIG_SERIAL_CONSOLE_PORT) + sccp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT); +#endif } if (info->tty) @@ -1736,7 +1783,7 @@ static void rs_8xx_wait_until_sent(struct tty_struct *tty, int timeout) schedule_timeout(char_time); if (signal_pending(current)) break; - if (timeout && ((orig_jiffies + timeout) < jiffies)) + if (timeout && time_after(jiffies, orig_jiffies + timeout)) break; bdp = info->tx_cur; } while (bdp->cbd_sc & BD_SC_READY); @@ -2006,7 +2053,7 @@ static int inline line_info(char *buf, struct serial_state *state) ret = sprintf(buf, "%d: uart:%s port:%X irq:%d", state->line, (state->smc_scc_num < SCC_NUM_BASE) ? "SMC" : "SCC", - state->port, state->irq); + (unsigned int)(state->port), state->irq); if (!state->port || (state->type == PORT_UNKNOWN)) { ret += sprintf(buf+ret, "\n"); @@ -2129,8 +2176,11 @@ static _INLINE_ void show_serial_version(void) /* * Print a string to the serial port trying not to disturb any possible * real use of the port... + * These funcitons work equally well for SCC, even though they are + * designed for SMC. Our only interests are the transmit/receive + * buffers, which are identically mapped for either the SCC or SMC. */ -static void serial_console_write(struct console *c, const char *s, +static void my_console_write(int idx, const char *s, unsigned count) { struct serial_state *ser; @@ -2140,7 +2190,7 @@ static void serial_console_write(struct console *c, const char *s, volatile smc_uart_t *up; volatile u_char *cp; - ser = rs_table + c->index; + ser = rs_table + idx; /* If the port has been initialized for general use, we have * to use the buffer descriptors allocated there. Otherwise, @@ -2177,8 +2227,15 @@ static void serial_console_write(struct console *c, const char *s, * that, not that it is ready for us to send. */ while (bdp->cbd_sc & BD_SC_READY); - /* Send the character out. */ - cp = __va(bdp->cbd_bufaddr); + + /* Send the character out. + * If the buffer address is in the CPM DPRAM, don't + * convert it. + */ + if ((uint)(bdp->cbd_bufaddr) > (uint)IMAP_ADDR) + cp = (u_char *)(bdp->cbd_bufaddr); + else + cp = __va(bdp->cbd_bufaddr); *cp = *s; bdp->cbd_datlen = 1; @@ -2216,9 +2273,196 @@ static void serial_console_write(struct console *c, const char *s, info->tx_cur = (cbd_t *)bdp; } +static void serial_console_write(struct console *c, const char *s, + unsigned count) +{ +#if defined(CONFIG_KGDB) && !defined(CONFIG_USE_SERIAL2_KGDB) + /* Try to let stub handle output. Returns true if it did. */ + if (kgdb_output_string(s, count)) + return; +#endif + my_console_write(c->index, s, count); +} + +#ifdef CONFIG_XMON +int +xmon_8xx_write(const char *s, unsigned count) +{ + my_console_write(KGDB_SER_IDX, s, count); + return(count); +} +#endif + +#ifdef CONFIG_KGDB +void +putDebugChar(char ch) +{ + my_console_write(KGDB_SER_IDX, &ch, 1); +} +#endif + +#if defined(CONFIG_XMON) || defined(CONFIG_KGDB) +/* + * Receive character from the serial port. This only works well + * before the port is initialize for real use. + */ +static int my_console_wait_key(int idx, int xmon, char *obuf) +{ + struct serial_state *ser; + u_char c, *cp; + ser_info_t *info; + volatile cbd_t *bdp; + volatile smc_uart_t *up; + int i; + + ser = rs_table + idx; + + /* Pointer to UART in parameter ram. + */ + up = (smc_uart_t *)&immr->im_dprambase[ser->port]; + + /* Get the address of the host memory buffer. + * If the port has been initialized for general use, we must + * use information from the port structure. + */ + if ((info = (ser_info_t *)ser->info)) + bdp = info->rx_cur; + else + bdp = (cbd_t *)&immr->im_dprambase[up->smc_rbase]; + + /* + * We need to gracefully shut down the receiver, disable + * interrupts, then read the input. + * XMON just wants a poll. If no character, return -1, else + * return the character. + */ + if (!xmon) { + while (bdp->cbd_sc & BD_SC_EMPTY); + } + else { + if (bdp->cbd_sc & BD_SC_EMPTY) + return -1; + } + + /* If the buffer address is in the CPM DPRAM, don't + * convert it. + */ + if ((uint)(bdp->cbd_bufaddr) > (uint)IMAP_ADDR) + cp = (u_char *)(bdp->cbd_bufaddr); + else + cp = __va(bdp->cbd_bufaddr); + + if (obuf) { + i = c = bdp->cbd_datlen; + while (i-- > 0) + *obuf++ = *cp++; + } + else { + c = *cp; + } + bdp->cbd_sc |= BD_SC_EMPTY; + + if (info) { + if (bdp->cbd_sc & BD_SC_WRAP) { + bdp = info->rx_bd_base; + } + else { + bdp++; + } + info->rx_cur = (cbd_t *)bdp; + } + + return((int)c); +} +#endif /* CONFIG_XMON || CONFIG_KGDB */ + +#ifdef CONFIG_XMON +int +xmon_8xx_read_poll(void) +{ + return(my_console_wait_key(KGDB_SER_IDX, 1, NULL)); +} + +int +xmon_8xx_read_char(void) +{ + return(my_console_wait_key(KGDB_SER_IDX, 0, NULL)); +} +#endif + +#ifdef CONFIG_KGDB +static char kgdb_buf[RX_BUF_SIZE], *kgdp; +static int kgdb_chars; + +char +getDebugChar(void) +{ + if (kgdb_chars <= 0) { + kgdb_chars = my_console_wait_key(KGDB_SER_IDX, 0, kgdb_buf); + kgdp = kgdb_buf; + } + kgdb_chars--; + + return(*kgdp++); +} + +void kgdb_interruptible(int yes) +{ + volatile smc_t *smcp; + + smcp = &immr->im_smc[KGDB_SER_IDX]; + + if (yes == 1) + smcp->smc_smcm |= SMCM_RX; + else + smcp->smc_smcm &= ~SMCM_RX; +} + +void kgdb_map_scc(void) +{ + ushort serbase; + uint mem_addr; + volatile cbd_t *bdp; + volatile smc_uart_t *up; + + /* The serial port has already been initialized before + * we get here. We have to assign some pointers needed by + * the kernel, and grab a memory location in the CPM that will + * work until the driver is really initialized. + */ + immr = (immap_t *)IMAP_ADDR; + + /* Right now, assume we are using SMCs. + */ +#ifdef USE_KGDB_SMC2 + *(ushort *)(&immr->im_dprambase[PROFF_SMC2_BASE]) = serbase = PROFF_SMC2; +#else + *(ushort *)(&immr->im_dprambase[PROFF_SMC1_BASE]) = serbase = PROFF_SMC1; +#endif + up = (smc_uart_t *)&immr->im_dprambase[serbase]; + + /* Allocate space for an input FIFO, plus a few bytes for output. + * Allocate bytes to maintain word alignment. + */ + mem_addr = (uint)(&immr->im_dprambase[0x1000]); + + /* Set the physical address of the host memory buffers in + * the buffer descriptors. + */ + bdp = (cbd_t *)&immr->im_dprambase[up->smc_rbase]; + bdp->cbd_bufaddr = mem_addr; + + bdp = (cbd_t *)&immr->im_dprambase[up->smc_tbase]; + bdp->cbd_bufaddr = mem_addr+RX_BUF_SIZE; + + up->smc_mrblr = RX_BUF_SIZE; /* receive buffer length */ + up->smc_maxidl = RX_BUF_SIZE; +} +#endif + static kdev_t serial_console_device(struct console *c) { - return MKDEV(TTYAUX_MAJOR, 64 + c->index); + return MKDEV(TTY_MAJOR, 64 + c->index); } @@ -2276,7 +2520,11 @@ int __init rs_8xx_init(void) __clear_user(&serial_driver,sizeof(struct tty_driver)); serial_driver.magic = TTY_DRIVER_MAGIC; serial_driver.driver_name = "serial"; +#ifdef CONFIG_DEVFS_FS + serial_driver.name = "tts/%d"; +#else serial_driver.name = "ttyS"; +#endif serial_driver.major = TTY_MAJOR; serial_driver.minor_start = 64; serial_driver.num = NR_PORTS; @@ -2314,7 +2562,11 @@ int __init rs_8xx_init(void) * major number and the subtype code. */ callout_driver = serial_driver; +#ifdef CONFIG_DEVFS_FS + callout_driver.name = "cua/%d"; +#else callout_driver.name = "cua"; +#endif callout_driver.major = TTYAUX_MAJOR; callout_driver.subtype = SERIAL_TYPE_CALLOUT; callout_driver.read_proc = 0; @@ -2340,6 +2592,7 @@ int __init rs_8xx_init(void) * Configure SMCs Tx/Rx. SMC1 is only on Port D, SMC2 is * only on Port A. You either pick 'em, or not. */ +#ifndef SCC_CONSOLE io->iop_ppard |= 0x00c00000; io->iop_pdird |= 0x00400000; io->iop_pdird &= ~0x00800000; @@ -2375,6 +2628,27 @@ int __init rs_8xx_init(void) */ immap->im_cpmux.cmx_scr &= ~0x00ffff00; immap->im_cpmux.cmx_scr |= 0x00121b00; +#else + io->iop_pparb |= 0x008b0000; + io->iop_pdirb |= 0x00880000; + io->iop_psorb |= 0x00880000; + io->iop_pdirb &= ~0x00030000; + io->iop_psorb &= ~0x00030000; + + /* Use Port D for SCC1 instead of other functions. + */ + io->iop_ppard |= 0x00000003; + io->iop_psord &= ~0x00000001; /* Rx */ + io->iop_psord |= 0x00000002; /* Tx */ + io->iop_pdird &= ~0x00000001; /* Rx */ + io->iop_pdird |= 0x00000002; /* Tx */ + + /* Connect SCC1, SCC2, SCC3 to NMSI. Connect BRG1 to SCC1, + * BRG2 to SCC2, BRG3 to SCC3. + */ + immap->im_cpmux.cmx_scr &= ~0xffffff00; + immap->im_cpmux.cmx_scr |= 0x00091200; +#endif for (i = 0, state = rs_table; i < NR_PORTS; i++,state++) { state->magic = SSTATE_MAGIC; @@ -2390,9 +2664,12 @@ int __init rs_8xx_init(void) state->icount.rx = state->icount.tx = 0; state->icount.frame = state->icount.parity = 0; state->icount.overrun = state->icount.brk = 0; - printk(KERN_INFO "ttyS%02d at 0x%04x is a %s\n", - i, state->port, - (state->smc_scc_num < SCC_NUM_BASE) ? "SMC" : "SCC"); + printk (KERN_INFO "ttyS%d on %s%d at 0x%04x, BRG%d\n", + i, + (state->smc_scc_num < SCC_NUM_BASE) ? "SMC" : "SCC", + PORT_NUM(state->smc_scc_num) + 1, + (unsigned int)(state->port), + state->smc_scc_num + 1); #ifdef CONFIG_SERIAL_CONSOLE /* If we just printed the message on the console port, and * we are about to initialize it for general use, we have @@ -2400,7 +2677,7 @@ int __init rs_8xx_init(void) * make it out of the transmit buffer. */ if (i == CONFIG_SERIAL_CONSOLE_PORT) - mdelay(2); + mdelay(300); #endif info = kmalloc(sizeof(ser_info_t), GFP_KERNEL); if (info) { @@ -2452,6 +2729,7 @@ int __init rs_8xx_init(void) else { scp = &immap->im_scc[idx - SCC_IDX_BASE]; sup = (scc_uart_t *)&immap->im_dprambase[state->port]; + scp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT); sup->scc_genscc.scc_rbase = dp_addr; } @@ -2555,6 +2833,22 @@ int __init rs_8xx_init(void) /* Send the CPM an initialize command. */ +#ifdef SCC_CONSOLE + switch (state->smc_scc_num) { + case 0: + page = CPM_CR_SCC1_PAGE; + sblock = CPM_CR_SCC1_SBLOCK; + break; + case 1: + page = CPM_CR_SCC2_PAGE; + sblock = CPM_CR_SCC2_SBLOCK; + break; + case 2: + page = CPM_CR_SCC3_PAGE; + sblock = CPM_CR_SCC3_SBLOCK; + break; + } +#else if (state->smc_scc_num == 2) { page = CPM_CR_SCC2_PAGE; sblock = CPM_CR_SCC2_SBLOCK; @@ -2563,6 +2857,7 @@ int __init rs_8xx_init(void) page = CPM_CR_SCC3_PAGE; sblock = CPM_CR_SCC3_SBLOCK; } +#endif cp->cp_cpcr = mk_cr_cmd(page, sblock, 0, CPM_CR_INIT_TRX) | CPM_CR_FLG; @@ -2596,8 +2891,12 @@ int __init rs_8xx_init(void) /* If the port is the console, enable Rx and Tx. */ #ifdef CONFIG_SERIAL_CONSOLE - if (i == CONFIG_SERIAL_CONSOLE_PORT) - sp->smc_smcmr |= SMCMR_REN | SMCMR_TEN; + if (i == CONFIG_SERIAL_CONSOLE_PORT) { + if (idx < SCC_NUM_BASE) + sp->smc_smcmr |= SMCMR_REN | SMCMR_TEN; + else + scp->scc_gsmrl |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT); + } #endif } } @@ -2614,8 +2913,12 @@ static int __init serial_console_setup(struct console *co, char *options) volatile cbd_t *bdp; volatile cpm8260_t *cp; volatile immap_t *immap; +#ifndef SCC_CONSOLE volatile smc_t *sp; volatile smc_uart_t *up; +#endif + volatile scc_t *scp; + volatile scc_uart_t *sup; volatile iop8260_t *io; bd_t *bd; @@ -2630,11 +2933,25 @@ static int __init serial_console_setup(struct console *co, char *options) ser = rs_table + co->index; - immap = immr; cp = &immap->im_cpm; io = &immap->im_ioport; +#ifdef SCC_CONSOLE + scp = (scc_t *)&(immap->im_scc[SCC_CONSOLE-1]); + sup = (scc_uart_t *)&immap->im_dprambase[PROFF_SCC1 + ((SCC_CONSOLE-1) << 8)]; + scp->scc_sccm &= ~(UART_SCCM_TX | UART_SCCM_RX); + scp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT); + + /* Use Port D for SCC1 instead of other functions. + */ + io->iop_ppard |= 0x00000003; + io->iop_psord &= ~0x00000001; /* Rx */ + io->iop_psord |= 0x00000002; /* Tx */ + io->iop_pdird &= ~0x00000001; /* Rx */ + io->iop_pdird |= 0x00000002; /* Tx */ + +#else /* This should have been done long ago by the early boot code, * but do it again to make sure. */ @@ -2662,6 +2979,7 @@ static int __init serial_console_setup(struct console *co, char *options) io->iop_pdird |= 0x00400000; io->iop_pdird &= ~0x00800000; io->iop_psord &= ~0x00c00000; +#endif /* Allocate space for two buffer descriptors in the DP ram. */ @@ -2686,6 +3004,68 @@ static int __init serial_console_setup(struct console *co, char *options) /* Set up the uart parameters in the parameter ram. */ +#ifdef SCC_CONSOLE + sup->scc_genscc.scc_rbase = dp_addr; + sup->scc_genscc.scc_tbase = dp_addr + sizeof(cbd_t); + + /* Set up the uart parameters in the + * parameter ram. + */ + sup->scc_genscc.scc_rfcr = CPMFCR_GBL | CPMFCR_EB; + sup->scc_genscc.scc_tfcr = CPMFCR_GBL | CPMFCR_EB; + + sup->scc_genscc.scc_mrblr = 1; + sup->scc_maxidl = 0; + sup->scc_brkcr = 1; + sup->scc_parec = 0; + sup->scc_frmec = 0; + sup->scc_nosec = 0; + sup->scc_brkec = 0; + sup->scc_uaddr1 = 0; + sup->scc_uaddr2 = 0; + sup->scc_toseq = 0; + sup->scc_char1 = 0x8000; + sup->scc_char2 = 0x8000; + sup->scc_char3 = 0x8000; + sup->scc_char4 = 0x8000; + sup->scc_char5 = 0x8000; + sup->scc_char6 = 0x8000; + sup->scc_char7 = 0x8000; + sup->scc_char8 = 0x8000; + sup->scc_rccm = 0xc0ff; + + /* Send the CPM an initialize command. + */ + cp->cp_cpcr = mk_cr_cmd(CPM_CR_SCC1_PAGE, CPM_CR_SCC1_SBLOCK, 0, + CPM_CR_INIT_TRX) | CPM_CR_FLG; + while (cp->cp_cpcr & CPM_CR_FLG); + + /* Set UART mode, 8 bit, no parity, one stop. + * Enable receive and transmit. + */ + scp->scc_gsmrh = 0; + scp->scc_gsmrl = + (SCC_GSMRL_MODE_UART | SCC_GSMRL_TDCR_16 | SCC_GSMRL_RDCR_16); + + /* Disable all interrupts and clear all pending + * events. + */ + scp->scc_sccm = 0; + scp->scc_scce = 0xffff; + scp->scc_dsr = 0x7e7e; + scp->scc_pmsr = 0x3000; + + /* Wire BRG1 to SCC1. The serial init will take care of + * others. + */ + immap->im_cpmux.cmx_scr = 0; + + /* Set up the baud rate generator. + */ + m8260_cpm_setbrg(ser->smc_scc_num, bd->bi_baudrate); + + scp->scc_gsmrl |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT); +#else up->smc_rbase = dp_addr; /* Base of receive buffer desc. */ up->smc_tbase = dp_addr+sizeof(cbd_t); /* Base of xmt buffer desc. */ up->smc_rfcr = CPMFCR_GBL | CPMFCR_EB; @@ -2714,6 +3094,7 @@ static int __init serial_console_setup(struct console *co, char *options) /* And finally, enable Rx and Tx. */ sp->smc_smcmr |= SMCMR_REN | SMCMR_TEN; +#endif return 0; } diff --git a/arch/ppc/8xx_io/Config.in b/arch/ppc/8xx_io/Config.in index 75c2e6084c15..2bd85a3f45ea 100644 --- a/arch/ppc/8xx_io/Config.in +++ b/arch/ppc/8xx_io/Config.in @@ -25,6 +25,10 @@ if [ "$CONFIG_SMC2_UART" = "y" ]; then fi bool 'Enable SCC2 and SCC3 for UART' CONFIG_USE_SCC_IO +if [ "$CONFIG_SOUND" = "y" ]; then + bool 'Embedded Planet HIOX Audio' CONFIG_HTDMSOUND +fi + # This doesn't really belong here, but it is convenient to ask # 8xx specific questions. diff --git a/arch/ppc/8xx_io/Makefile b/arch/ppc/8xx_io/Makefile index 9242a4da410e..73dcd28771ee 100644 --- a/arch/ppc/8xx_io/Makefile +++ b/arch/ppc/8xx_io/Makefile @@ -1,4 +1,4 @@ -# BK Id: SCCS/s.Makefile 1.6 08/30/01 09:33:48 trini +# BK Id: %F% %I% %G% %U% %#% # # # Makefile for the linux MPC8xx ppc-specific parts of comm processor @@ -16,5 +16,6 @@ obj-y := commproc.o uart.o obj-$(CONFIG_FEC_ENET) += fec.o obj-$(CONFIG_SCC_ENET) += enet.o obj-$(CONFIG_UCODE_PATCH) += micropatch.o +obj-$(CONFIG_HTDMSOUND) += cs4218_tdm.o include $(TOPDIR)/Rules.make diff --git a/arch/ppc/8xx_io/commproc.c b/arch/ppc/8xx_io/commproc.c index 9c49b2733625..56d1a590746d 100644 --- a/arch/ppc/8xx_io/commproc.c +++ b/arch/ppc/8xx_io/commproc.c @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.commproc.c 1.15 10/16/01 16:21:52 trini + * BK Id: %F% %I% %G% %U% %#% */ /* @@ -55,7 +55,63 @@ struct cpm_action { static struct cpm_action cpm_vecs[CPMVEC_NR]; static void cpm_interrupt(int irq, void * dev, struct pt_regs * regs); static void cpm_error_interrupt(void *, struct pt_regs * regs); +static void alloc_host_memory(void); +#if 1 +void +m8xx_cpm_reset() +{ + volatile immap_t *imp; + volatile cpm8xx_t *commproc; + pte_t *pte; + + imp = (immap_t *)IMAP_ADDR; + commproc = (cpm8xx_t *)&imp->im_cpm; + +#ifdef CONFIG_UCODE_PATCH + /* Perform a reset. + */ + commproc->cp_cpcr = (CPM_CR_RST | CPM_CR_FLG); + + /* Wait for it. + */ + while (commproc->cp_cpcr & CPM_CR_FLG); + + cpm_load_patch(imp); +#endif + + /* Set SDMA Bus Request priority 5. + * On 860T, this also enables FEC priority 6. I am not sure + * this is what we realy want for some applications, but the + * manual recommends it. + * Bit 25, FAM can also be set to use FEC aggressive mode (860T). + */ + imp->im_siu_conf.sc_sdcr = 1; + + /* Reclaim the DP memory for our use. + */ + dp_alloc_base = CPM_DATAONLY_BASE; + dp_alloc_top = dp_alloc_base + CPM_DATAONLY_SIZE; + + /* Tell everyone where the comm processor resides. + */ + cpmp = (cpm8xx_t *)commproc; +} + +/* We used to do this earlier, but have to postpone as long as possible + * to ensure the kernel VM is now running. + */ +static void +alloc_host_memory() +{ + uint physaddr; + + /* Set the host page for allocation. + */ + host_buffer = (uint)consistent_alloc(GFP_KERNEL, PAGE_SIZE, &physaddr); + host_end = host_buffer + PAGE_SIZE; +} +#else void m8xx_cpm_reset(uint host_page_addr) { @@ -111,6 +167,7 @@ m8xx_cpm_reset(uint host_page_addr) */ cpmp = (cpm8xx_t *)commproc; } +#endif /* This is called during init_IRQ. We used to do it above, but this * was too early since init_IRQ was not yet called. @@ -222,6 +279,12 @@ m8xx_cpm_dpalloc(uint size) return(retloc); } +uint +m8xx_cpm_dpalloc_index(void) +{ + return dp_alloc_base; +} + /* We also own one page of host buffer space for the allocation of * UART "fifos" and the like. */ @@ -230,6 +293,11 @@ m8xx_cpm_hostalloc(uint size) { uint retloc; +#if 1 + if (host_buffer == 0) + alloc_host_memory(); +#endif + if ((host_buffer + size) >= host_end) return(0); diff --git a/arch/ppc/8xx_io/cs4218.h b/arch/ppc/8xx_io/cs4218.h new file mode 100644 index 000000000000..a3c38c5a5db2 --- /dev/null +++ b/arch/ppc/8xx_io/cs4218.h @@ -0,0 +1,167 @@ +#ifndef _cs4218_h_ +/* + * Hacked version of linux/drivers/sound/dmasound/dmasound.h + * + * + * Minor numbers for the sound driver. + * + * Unfortunately Creative called the codec chip of SB as a DSP. For this + * reason the /dev/dsp is reserved for digitized audio use. There is a + * device for true DSP processors but it will be called something else. + * In v3.0 it's /dev/sndproc but this could be a temporary solution. + */ +#define _cs4218_h_ + +#include <linux/types.h> +#include <linux/config.h> + +#define SND_NDEVS 256 /* Number of supported devices */ +#define SND_DEV_CTL 0 /* Control port /dev/mixer */ +#define SND_DEV_SEQ 1 /* Sequencer output /dev/sequencer (FM + synthesizer and MIDI output) */ +#define SND_DEV_MIDIN 2 /* Raw midi access */ +#define SND_DEV_DSP 3 /* Digitized voice /dev/dsp */ +#define SND_DEV_AUDIO 4 /* Sparc compatible /dev/audio */ +#define SND_DEV_DSP16 5 /* Like /dev/dsp but 16 bits/sample */ +#define SND_DEV_STATUS 6 /* /dev/sndstat */ +/* #7 not in use now. Was in 2.4. Free for use after v3.0. */ +#define SND_DEV_SEQ2 8 /* /dev/sequencer, level 2 interface */ +#define SND_DEV_SNDPROC 9 /* /dev/sndproc for programmable devices */ +#define SND_DEV_PSS SND_DEV_SNDPROC + +/* switch on various prinks */ +#define DEBUG_DMASOUND 1 + +#define MAX_AUDIO_DEV 5 +#define MAX_MIXER_DEV 4 +#define MAX_SYNTH_DEV 3 +#define MAX_MIDI_DEV 6 +#define MAX_TIMER_DEV 3 + +#define MAX_CATCH_RADIUS 10 + +#define le2be16(x) (((x)<<8 & 0xff00) | ((x)>>8 & 0x00ff)) +#define le2be16dbl(x) (((x)<<8 & 0xff00ff00) | ((x)>>8 & 0x00ff00ff)) + +#define IOCTL_IN(arg, ret) \ + do { int error = get_user(ret, (int *)(arg)); \ + if (error) return error; \ + } while (0) +#define IOCTL_OUT(arg, ret) ioctl_return((int *)(arg), ret) + +static inline int ioctl_return(int *addr, int value) +{ + return value < 0 ? value : put_user(value, addr); +} + +#define HAS_RECORD + + /* + * Initialization + */ + +/* description of the set-up applies to either hard or soft settings */ + +typedef struct { + int format; /* AFMT_* */ + int stereo; /* 0 = mono, 1 = stereo */ + int size; /* 8/16 bit*/ + int speed; /* speed */ +} SETTINGS; + + /* + * Machine definitions + */ + +typedef struct { + const char *name; + const char *name2; + void (*open)(void); + void (*release)(void); + void *(*dma_alloc)(unsigned int, int); + void (*dma_free)(void *, unsigned int); + int (*irqinit)(void); +#ifdef MODULE + void (*irqcleanup)(void); +#endif + void (*init)(void); + void (*silence)(void); + int (*setFormat)(int); + int (*setVolume)(int); + int (*setBass)(int); + int (*setTreble)(int); + int (*setGain)(int); + void (*play)(void); + void (*record)(void); /* optional */ + void (*mixer_init)(void); /* optional */ + int (*mixer_ioctl)(u_int, u_long); /* optional */ + int (*write_sq_setup)(void); /* optional */ + int (*read_sq_setup)(void); /* optional */ + int (*sq_open)(mode_t); /* optional */ + int (*state_info)(char *, size_t); /* optional */ + void (*abort_read)(void); /* optional */ + int min_dsp_speed; + int max_dsp_speed; + int version ; + int hardware_afmts ; /* OSS says we only return h'ware info */ + /* when queried via SNDCTL_DSP_GETFMTS */ + int capabilities ; /* low-level reply to SNDCTL_DSP_GETCAPS */ + SETTINGS default_hard ; /* open() or init() should set something valid */ + SETTINGS default_soft ; /* you can make it look like old OSS, if you want to */ +} MACHINE; + + /* + * Low level stuff + */ + +typedef struct { + ssize_t (*ct_ulaw)(const u_char *, size_t, u_char *, ssize_t *, ssize_t); + ssize_t (*ct_alaw)(const u_char *, size_t, u_char *, ssize_t *, ssize_t); + ssize_t (*ct_s8)(const u_char *, size_t, u_char *, ssize_t *, ssize_t); + ssize_t (*ct_u8)(const u_char *, size_t, u_char *, ssize_t *, ssize_t); + ssize_t (*ct_s16be)(const u_char *, size_t, u_char *, ssize_t *, ssize_t); + ssize_t (*ct_u16be)(const u_char *, size_t, u_char *, ssize_t *, ssize_t); + ssize_t (*ct_s16le)(const u_char *, size_t, u_char *, ssize_t *, ssize_t); + ssize_t (*ct_u16le)(const u_char *, size_t, u_char *, ssize_t *, ssize_t); +} TRANS; + + + /* + * Sound queue stuff, the heart of the driver + */ + +struct sound_queue { + /* buffers allocated for this queue */ + int numBufs; /* real limits on what the user can have */ + int bufSize; /* in bytes */ + char **buffers; + + /* current parameters */ + int locked ; /* params cannot be modified when != 0 */ + int user_frags ; /* user requests this many */ + int user_frag_size ; /* of this size */ + int max_count; /* actual # fragments <= numBufs */ + int block_size; /* internal block size in bytes */ + int max_active; /* in-use fragments <= max_count */ + + /* it shouldn't be necessary to declare any of these volatile */ + int front, rear, count; + int rear_size; + /* + * The use of the playing field depends on the hardware + * + * Atari, PMac: The number of frames that are loaded/playing + * + * Amiga: Bit 0 is set: a frame is loaded + * Bit 1 is set: a frame is playing + */ + int active; + wait_queue_head_t action_queue, open_queue, sync_queue; + int open_mode; + int busy, syncing, xruns, died; +}; + +#define SLEEP(queue) interruptible_sleep_on_timeout(&queue, HZ) +#define WAKE_UP(queue) (wake_up_interruptible(&queue)) + +#endif /* _cs4218_h_ */ diff --git a/arch/ppc/8xx_io/cs4218_tdm.c b/arch/ppc/8xx_io/cs4218_tdm.c new file mode 100644 index 000000000000..6b025c201bae --- /dev/null +++ b/arch/ppc/8xx_io/cs4218_tdm.c @@ -0,0 +1,2849 @@ + +/* This is a modified version of linux/drivers/sound/dmasound.c to + * support the CS4218 codec on the 8xx TDM port. Thanks to everyone + * that contributed to the dmasound software (which includes me :-). + * + * The CS4218 is configured in Mode 4, sub-mode 0. This provides + * left/right data only on the TDM port, as a 32-bit word, per frame + * pulse. The control of the CS4218 is provided by some other means, + * like the SPI port. + * Dan Malek (dmalek@jlc.net) + */ + +#include <linux/module.h> +#include <linux/sched.h> +#include <linux/timer.h> +#include <linux/major.h> +#include <linux/config.h> +#include <linux/fcntl.h> +#include <linux/errno.h> +#include <linux/mm.h> +#include <linux/slab.h> +#include <linux/sound.h> +#include <linux/init.h> +#include <linux/delay.h> + +#include <asm/system.h> +#include <asm/irq.h> +#include <asm/pgtable.h> +#include <asm/uaccess.h> +#include <asm/io.h> + +/* Should probably do something different with this path name..... + * Actually, I should just stop using it... + */ +#include "cs4218.h" +#include <linux/soundcard.h> + +#include <asm/mpc8xx.h> +#include <asm/8xx_immap.h> +#include <asm/commproc.h> + +#define DMASND_CS4218 5 + +#define MAX_CATCH_RADIUS 10 +#define MIN_BUFFERS 4 +#define MIN_BUFSIZE 4 +#define MAX_BUFSIZE 128 + +#define HAS_8BIT_TABLES + +static int sq_unit = -1; +static int mixer_unit = -1; +static int state_unit = -1; +static int irq_installed = 0; +static char **sound_buffers = NULL; +static char **sound_read_buffers = NULL; + +/* Local copies of things we put in the control register. Output + * volume, like most codecs is really attenuation. + */ +static int cs4218_rate_index; + +/* + * Stuff for outputting a beep. The values range from -327 to +327 + * so we can multiply by an amplitude in the range 0..100 to get a + * signed short value to put in the output buffer. + */ +static short beep_wform[256] = { + 0, 40, 79, 117, 153, 187, 218, 245, + 269, 288, 304, 316, 323, 327, 327, 324, + 318, 310, 299, 288, 275, 262, 249, 236, + 224, 213, 204, 196, 190, 186, 183, 182, + 182, 183, 186, 189, 192, 196, 200, 203, + 206, 208, 209, 209, 209, 207, 204, 201, + 197, 193, 188, 183, 179, 174, 170, 166, + 163, 161, 160, 159, 159, 160, 161, 162, + 164, 166, 168, 169, 171, 171, 171, 170, + 169, 167, 163, 159, 155, 150, 144, 139, + 133, 128, 122, 117, 113, 110, 107, 105, + 103, 103, 103, 103, 104, 104, 105, 105, + 105, 103, 101, 97, 92, 86, 78, 68, + 58, 45, 32, 18, 3, -11, -26, -41, + -55, -68, -79, -88, -95, -100, -102, -102, + -99, -93, -85, -75, -62, -48, -33, -16, + 0, 16, 33, 48, 62, 75, 85, 93, + 99, 102, 102, 100, 95, 88, 79, 68, + 55, 41, 26, 11, -3, -18, -32, -45, + -58, -68, -78, -86, -92, -97, -101, -103, + -105, -105, -105, -104, -104, -103, -103, -103, + -103, -105, -107, -110, -113, -117, -122, -128, + -133, -139, -144, -150, -155, -159, -163, -167, + -169, -170, -171, -171, -171, -169, -168, -166, + -164, -162, -161, -160, -159, -159, -160, -161, + -163, -166, -170, -174, -179, -183, -188, -193, + -197, -201, -204, -207, -209, -209, -209, -208, + -206, -203, -200, -196, -192, -189, -186, -183, + -182, -182, -183, -186, -190, -196, -204, -213, + -224, -236, -249, -262, -275, -288, -299, -310, + -318, -324, -327, -327, -323, -316, -304, -288, + -269, -245, -218, -187, -153, -117, -79, -40, +}; + +#define BEEP_SPEED 5 /* 22050 Hz sample rate */ +#define BEEP_BUFLEN 512 +#define BEEP_VOLUME 15 /* 0 - 100 */ + +static int beep_volume = BEEP_VOLUME; +static int beep_playing = 0; +static int beep_state = 0; +static short *beep_buf; +static void (*orig_mksound)(unsigned int, unsigned int); + +/* This is found someplace else......I guess in the keyboard driver + * we don't include. + */ +static void (*kd_mksound)(unsigned int, unsigned int); + +static int catchRadius = 0; +static int numBufs = 4, bufSize = 32; +static int numReadBufs = 4, readbufSize = 32; + + +/* TDM/Serial transmit and receive buffer descriptors. +*/ +static volatile cbd_t *rx_base, *rx_cur, *tx_base, *tx_cur; + +MODULE_PARM(catchRadius, "i"); +MODULE_PARM(numBufs, "i"); +MODULE_PARM(bufSize, "i"); +MODULE_PARM(numreadBufs, "i"); +MODULE_PARM(readbufSize, "i"); + +#define arraysize(x) (sizeof(x)/sizeof(*(x))) +#define le2be16(x) (((x)<<8 & 0xff00) | ((x)>>8 & 0x00ff)) +#define le2be16dbl(x) (((x)<<8 & 0xff00ff00) | ((x)>>8 & 0x00ff00ff)) + +#define IOCTL_IN(arg, ret) \ + do { int error = get_user(ret, (int *)(arg)); \ + if (error) return error; \ + } while (0) +#define IOCTL_OUT(arg, ret) ioctl_return((int *)(arg), ret) + +/* CS4218 serial port control in mode 4. +*/ +#define CS_INTMASK ((uint)0x40000000) +#define CS_DO1 ((uint)0x20000000) +#define CS_LATTEN ((uint)0x1f000000) +#define CS_RATTEN ((uint)0x00f80000) +#define CS_MUTE ((uint)0x00040000) +#define CS_ISL ((uint)0x00020000) +#define CS_ISR ((uint)0x00010000) +#define CS_LGAIN ((uint)0x0000f000) +#define CS_RGAIN ((uint)0x00000f00) + +#define CS_LATTEN_SET(X) (((X) & 0x1f) << 24) +#define CS_RATTEN_SET(X) (((X) & 0x1f) << 19) +#define CS_LGAIN_SET(X) (((X) & 0x0f) << 12) +#define CS_RGAIN_SET(X) (((X) & 0x0f) << 8) + +#define CS_LATTEN_GET(X) (((X) >> 24) & 0x1f) +#define CS_RATTEN_GET(X) (((X) >> 19) & 0x1f) +#define CS_LGAIN_GET(X) (((X) >> 12) & 0x0f) +#define CS_RGAIN_GET(X) (((X) >> 8) & 0x0f) + +/* The control register is effectively write only. We have to keep a copy + * of what we write. + */ +static uint cs4218_control; + +/* A place to store expanding information. +*/ +static int expand_bal; +static int expand_data; + +/* Since I can't make the microcode patch work for the SPI, I just + * clock the bits using software. + */ +static void sw_spi_init(void); +static void sw_spi_io(u_char *obuf, u_char *ibuf, uint bcnt); +static uint cs4218_ctl_write(uint ctlreg); + +/*** Some low level helpers **************************************************/ + +/* 16 bit mu-law */ + +static short ulaw2dma16[] = { + -32124, -31100, -30076, -29052, -28028, -27004, -25980, -24956, + -23932, -22908, -21884, -20860, -19836, -18812, -17788, -16764, + -15996, -15484, -14972, -14460, -13948, -13436, -12924, -12412, + -11900, -11388, -10876, -10364, -9852, -9340, -8828, -8316, + -7932, -7676, -7420, -7164, -6908, -6652, -6396, -6140, + -5884, -5628, -5372, -5116, -4860, -4604, -4348, -4092, + -3900, -3772, -3644, -3516, -3388, -3260, -3132, -3004, + -2876, -2748, -2620, -2492, -2364, -2236, -2108, -1980, + -1884, -1820, -1756, -1692, -1628, -1564, -1500, -1436, + -1372, -1308, -1244, -1180, -1116, -1052, -988, -924, + -876, -844, -812, -780, -748, -716, -684, -652, + -620, -588, -556, -524, -492, -460, -428, -396, + -372, -356, -340, -324, -308, -292, -276, -260, + -244, -228, -212, -196, -180, -164, -148, -132, + -120, -112, -104, -96, -88, -80, -72, -64, + -56, -48, -40, -32, -24, -16, -8, 0, + 32124, 31100, 30076, 29052, 28028, 27004, 25980, 24956, + 23932, 22908, 21884, 20860, 19836, 18812, 17788, 16764, + 15996, 15484, 14972, 14460, 13948, 13436, 12924, 12412, + 11900, 11388, 10876, 10364, 9852, 9340, 8828, 8316, + 7932, 7676, 7420, 7164, 6908, 6652, 6396, 6140, + 5884, 5628, 5372, 5116, 4860, 4604, 4348, 4092, + 3900, 3772, 3644, 3516, 3388, 3260, 3132, 3004, + 2876, 2748, 2620, 2492, 2364, 2236, 2108, 1980, + 1884, 1820, 1756, 1692, 1628, 1564, 1500, 1436, + 1372, 1308, 1244, 1180, 1116, 1052, 988, 924, + 876, 844, 812, 780, 748, 716, 684, 652, + 620, 588, 556, 524, 492, 460, 428, 396, + 372, 356, 340, 324, 308, 292, 276, 260, + 244, 228, 212, 196, 180, 164, 148, 132, + 120, 112, 104, 96, 88, 80, 72, 64, + 56, 48, 40, 32, 24, 16, 8, 0, +}; + +/* 16 bit A-law */ + +static short alaw2dma16[] = { + -5504, -5248, -6016, -5760, -4480, -4224, -4992, -4736, + -7552, -7296, -8064, -7808, -6528, -6272, -7040, -6784, + -2752, -2624, -3008, -2880, -2240, -2112, -2496, -2368, + -3776, -3648, -4032, -3904, -3264, -3136, -3520, -3392, + -22016, -20992, -24064, -23040, -17920, -16896, -19968, -18944, + -30208, -29184, -32256, -31232, -26112, -25088, -28160, -27136, + -11008, -10496, -12032, -11520, -8960, -8448, -9984, -9472, + -15104, -14592, -16128, -15616, -13056, -12544, -14080, -13568, + -344, -328, -376, -360, -280, -264, -312, -296, + -472, -456, -504, -488, -408, -392, -440, -424, + -88, -72, -120, -104, -24, -8, -56, -40, + -216, -200, -248, -232, -152, -136, -184, -168, + -1376, -1312, -1504, -1440, -1120, -1056, -1248, -1184, + -1888, -1824, -2016, -1952, -1632, -1568, -1760, -1696, + -688, -656, -752, -720, -560, -528, -624, -592, + -944, -912, -1008, -976, -816, -784, -880, -848, + 5504, 5248, 6016, 5760, 4480, 4224, 4992, 4736, + 7552, 7296, 8064, 7808, 6528, 6272, 7040, 6784, + 2752, 2624, 3008, 2880, 2240, 2112, 2496, 2368, + 3776, 3648, 4032, 3904, 3264, 3136, 3520, 3392, + 22016, 20992, 24064, 23040, 17920, 16896, 19968, 18944, + 30208, 29184, 32256, 31232, 26112, 25088, 28160, 27136, + 11008, 10496, 12032, 11520, 8960, 8448, 9984, 9472, + 15104, 14592, 16128, 15616, 13056, 12544, 14080, 13568, + 344, 328, 376, 360, 280, 264, 312, 296, + 472, 456, 504, 488, 408, 392, 440, 424, + 88, 72, 120, 104, 24, 8, 56, 40, + 216, 200, 248, 232, 152, 136, 184, 168, + 1376, 1312, 1504, 1440, 1120, 1056, 1248, 1184, + 1888, 1824, 2016, 1952, 1632, 1568, 1760, 1696, + 688, 656, 752, 720, 560, 528, 624, 592, + 944, 912, 1008, 976, 816, 784, 880, 848, +}; + + +/*** Translations ************************************************************/ + + +static ssize_t cs4218_ct_law(const u_char *userPtr, size_t userCount, + u_char frame[], ssize_t *frameUsed, + ssize_t frameLeft); +static ssize_t cs4218_ct_s8(const u_char *userPtr, size_t userCount, + u_char frame[], ssize_t *frameUsed, + ssize_t frameLeft); +static ssize_t cs4218_ct_u8(const u_char *userPtr, size_t userCount, + u_char frame[], ssize_t *frameUsed, + ssize_t frameLeft); +static ssize_t cs4218_ct_s16(const u_char *userPtr, size_t userCount, + u_char frame[], ssize_t *frameUsed, + ssize_t frameLeft); +static ssize_t cs4218_ct_u16(const u_char *userPtr, size_t userCount, + u_char frame[], ssize_t *frameUsed, + ssize_t frameLeft); +static ssize_t cs4218_ctx_law(const u_char *userPtr, size_t userCount, + u_char frame[], ssize_t *frameUsed, + ssize_t frameLeft); +static ssize_t cs4218_ctx_s8(const u_char *userPtr, size_t userCount, + u_char frame[], ssize_t *frameUsed, + ssize_t frameLeft); +static ssize_t cs4218_ctx_u8(const u_char *userPtr, size_t userCount, + u_char frame[], ssize_t *frameUsed, + ssize_t frameLeft); +static ssize_t cs4218_ctx_s16(const u_char *userPtr, size_t userCount, + u_char frame[], ssize_t *frameUsed, + ssize_t frameLeft); +static ssize_t cs4218_ctx_u16(const u_char *userPtr, size_t userCount, + u_char frame[], ssize_t *frameUsed, + ssize_t frameLeft); +static ssize_t cs4218_ct_s16_read(const u_char *userPtr, size_t userCount, + u_char frame[], ssize_t *frameUsed, + ssize_t frameLeft); +static ssize_t cs4218_ct_u16_read(const u_char *userPtr, size_t userCount, + u_char frame[], ssize_t *frameUsed, + ssize_t frameLeft); + + +/*** Low level stuff *********************************************************/ + +struct cs_sound_settings { + MACHINE mach; /* machine dependent things */ + SETTINGS hard; /* hardware settings */ + SETTINGS soft; /* software settings */ + SETTINGS dsp; /* /dev/dsp default settings */ + TRANS *trans_write; /* supported translations for playback */ + TRANS *trans_read; /* supported translations for record */ + int volume_left; /* volume (range is machine dependent) */ + int volume_right; + int bass; /* tone (range is machine dependent) */ + int treble; + int gain; + int minDev; /* minor device number currently open */ +}; + +static struct cs_sound_settings sound; + +static void *CS_Alloc(unsigned int size, int flags); +static void CS_Free(void *ptr, unsigned int size); +static int CS_IrqInit(void); +#ifdef MODULE +static void CS_IrqCleanup(void); +#endif /* MODULE */ +static void CS_Silence(void); +static void CS_Init(void); +static void CS_Play(void); +static void CS_Record(void); +static int CS_SetFormat(int format); +static int CS_SetVolume(int volume); +static void cs4218_tdm_tx_intr(void *devid); +static void cs4218_tdm_rx_intr(void *devid); +static void cs4218_intr(void *devid, struct pt_regs *regs); +static int cs_get_volume(uint reg); +static int cs_volume_setter(int volume, int mute); +static int cs_get_gain(uint reg); +static int cs_set_gain(int gain); +static void cs_mksound(unsigned int hz, unsigned int ticks); +static void cs_nosound(unsigned long xx); + +/*** Mid level stuff *********************************************************/ + + +static void sound_silence(void); +static void sound_init(void); +static int sound_set_format(int format); +static int sound_set_speed(int speed); +static int sound_set_stereo(int stereo); +static int sound_set_volume(int volume); + +static ssize_t sound_copy_translate(const u_char *userPtr, + size_t userCount, + u_char frame[], ssize_t *frameUsed, + ssize_t frameLeft); +static ssize_t sound_copy_translate_read(const u_char *userPtr, + size_t userCount, + u_char frame[], ssize_t *frameUsed, + ssize_t frameLeft); + + +/* + * /dev/mixer abstraction + */ + +struct sound_mixer { + int busy; + int modify_counter; +}; + +static struct sound_mixer mixer; + +static struct sound_queue sq; +static struct sound_queue read_sq; + +#define sq_block_address(i) (sq.buffers[i]) +#define SIGNAL_RECEIVED (signal_pending(current)) +#define NON_BLOCKING(open_mode) (open_mode & O_NONBLOCK) +#define ONE_SECOND HZ /* in jiffies (100ths of a second) */ +#define NO_TIME_LIMIT 0xffffffff + +/* + * /dev/sndstat + */ + +struct sound_state { + int busy; + char buf[512]; + int len, ptr; +}; + +static struct sound_state state; + +/*** Common stuff ********************************************************/ + +static long long sound_lseek(struct file *file, long long offset, int orig); + +/*** Config & Setup **********************************************************/ + +void dmasound_setup(char *str, int *ints); + +/*** Translations ************************************************************/ + + +/* ++TeSche: radically changed for new expanding purposes... + * + * These two routines now deal with copying/expanding/translating the samples + * from user space into our buffer at the right frequency. They take care about + * how much data there's actually to read, how much buffer space there is and + * to convert samples into the right frequency/encoding. They will only work on + * complete samples so it may happen they leave some bytes in the input stream + * if the user didn't write a multiple of the current sample size. They both + * return the number of bytes they've used from both streams so you may detect + * such a situation. Luckily all programs should be able to cope with that. + * + * I think I've optimized anything as far as one can do in plain C, all + * variables should fit in registers and the loops are really short. There's + * one loop for every possible situation. Writing a more generalized and thus + * parameterized loop would only produce slower code. Feel free to optimize + * this in assembler if you like. :) + * + * I think these routines belong here because they're not yet really hardware + * independent, especially the fact that the Falcon can play 16bit samples + * only in stereo is hardcoded in both of them! + * + * ++geert: split in even more functions (one per format) + */ + +static ssize_t cs4218_ct_law(const u_char *userPtr, size_t userCount, + u_char frame[], ssize_t *frameUsed, + ssize_t frameLeft) +{ + short *table = sound.soft.format == AFMT_MU_LAW ? ulaw2dma16: alaw2dma16; + ssize_t count, used; + short *p = (short *) &frame[*frameUsed]; + int val, stereo = sound.soft.stereo; + + frameLeft >>= 2; + if (stereo) + userCount >>= 1; + used = count = min(userCount, frameLeft); + while (count > 0) { + u_char data; + if (get_user(data, userPtr++)) + return -EFAULT; + val = table[data]; + *p++ = val; + if (stereo) { + if (get_user(data, userPtr++)) + return -EFAULT; + val = table[data]; + } + *p++ = val; + count--; + } + *frameUsed += used * 4; + return stereo? used * 2: used; +} + + +static ssize_t cs4218_ct_s8(const u_char *userPtr, size_t userCount, + u_char frame[], ssize_t *frameUsed, + ssize_t frameLeft) +{ + ssize_t count, used; + short *p = (short *) &frame[*frameUsed]; + int val, stereo = sound.soft.stereo; + + frameLeft >>= 2; + if (stereo) + userCount >>= 1; + used = count = min(userCount, frameLeft); + while (count > 0) { + u_char data; + if (get_user(data, userPtr++)) + return -EFAULT; + val = data << 8; + *p++ = val; + if (stereo) { + if (get_user(data, userPtr++)) + return -EFAULT; + val = data << 8; + } + *p++ = val; + count--; + } + *frameUsed += used * 4; + return stereo? used * 2: used; +} + + +static ssize_t cs4218_ct_u8(const u_char *userPtr, size_t userCount, + u_char frame[], ssize_t *frameUsed, + ssize_t frameLeft) +{ + ssize_t count, used; + short *p = (short *) &frame[*frameUsed]; + int val, stereo = sound.soft.stereo; + + frameLeft >>= 2; + if (stereo) + userCount >>= 1; + used = count = min(userCount, frameLeft); + while (count > 0) { + u_char data; + if (get_user(data, userPtr++)) + return -EFAULT; + val = (data ^ 0x80) << 8; + *p++ = val; + if (stereo) { + if (get_user(data, userPtr++)) + return -EFAULT; + val = (data ^ 0x80) << 8; + } + *p++ = val; + count--; + } + *frameUsed += used * 4; + return stereo? used * 2: used; +} + + +/* This is the default format of the codec. Signed, 16-bit stereo + * generated by an application shouldn't have to be copied at all. + * We should just get the phsical address of the buffers and update + * the TDM BDs directly. + */ +static ssize_t cs4218_ct_s16(const u_char *userPtr, size_t userCount, + u_char frame[], ssize_t *frameUsed, + ssize_t frameLeft) +{ + ssize_t count, used; + int stereo = sound.soft.stereo; + short *fp = (short *) &frame[*frameUsed]; + + frameLeft >>= 2; + userCount >>= (stereo? 2: 1); + used = count = min(userCount, frameLeft); + if (!stereo) { + short *up = (short *) userPtr; + while (count > 0) { + short data; + if (get_user(data, up++)) + return -EFAULT; + *fp++ = data; + *fp++ = data; + count--; + } + } else { + if (copy_from_user(fp, userPtr, count * 4)) + return -EFAULT; + } + *frameUsed += used * 4; + return stereo? used * 4: used * 2; +} + +static ssize_t cs4218_ct_u16(const u_char *userPtr, size_t userCount, + u_char frame[], ssize_t *frameUsed, + ssize_t frameLeft) +{ + ssize_t count, used; + int mask = (sound.soft.format == AFMT_U16_LE? 0x0080: 0x8000); + int stereo = sound.soft.stereo; + short *fp = (short *) &frame[*frameUsed]; + short *up = (short *) userPtr; + + frameLeft >>= 2; + userCount >>= (stereo? 2: 1); + used = count = min(userCount, frameLeft); + while (count > 0) { + int data; + if (get_user(data, up++)) + return -EFAULT; + data ^= mask; + *fp++ = data; + if (stereo) { + if (get_user(data, up++)) + return -EFAULT; + data ^= mask; + } + *fp++ = data; + count--; + } + *frameUsed += used * 4; + return stereo? used * 4: used * 2; +} + + +static ssize_t cs4218_ctx_law(const u_char *userPtr, size_t userCount, + u_char frame[], ssize_t *frameUsed, + ssize_t frameLeft) +{ + unsigned short *table = (unsigned short *) + (sound.soft.format == AFMT_MU_LAW ? ulaw2dma16: alaw2dma16); + unsigned int data = expand_data; + unsigned int *p = (unsigned int *) &frame[*frameUsed]; + int bal = expand_bal; + int hSpeed = sound.hard.speed, sSpeed = sound.soft.speed; + int utotal, ftotal; + int stereo = sound.soft.stereo; + + frameLeft >>= 2; + if (stereo) + userCount >>= 1; + ftotal = frameLeft; + utotal = userCount; + while (frameLeft) { + u_char c; + if (bal < 0) { + if (userCount == 0) + break; + if (get_user(c, userPtr++)) + return -EFAULT; + data = table[c]; + if (stereo) { + if (get_user(c, userPtr++)) + return -EFAULT; + data = (data << 16) + table[c]; + } else + data = (data << 16) + data; + userCount--; + bal += hSpeed; + } + *p++ = data; + frameLeft--; + bal -= sSpeed; + } + expand_bal = bal; + expand_data = data; + *frameUsed += (ftotal - frameLeft) * 4; + utotal -= userCount; + return stereo? utotal * 2: utotal; +} + + +static ssize_t cs4218_ctx_s8(const u_char *userPtr, size_t userCount, + u_char frame[], ssize_t *frameUsed, + ssize_t frameLeft) +{ + unsigned int *p = (unsigned int *) &frame[*frameUsed]; + unsigned int data = expand_data; + int bal = expand_bal; + int hSpeed = sound.hard.speed, sSpeed = sound.soft.speed; + int stereo = sound.soft.stereo; + int utotal, ftotal; + + frameLeft >>= 2; + if (stereo) + userCount >>= 1; + ftotal = frameLeft; + utotal = userCount; + while (frameLeft) { + u_char c; + if (bal < 0) { + if (userCount == 0) + break; + if (get_user(c, userPtr++)) + return -EFAULT; + data = c << 8; + if (stereo) { + if (get_user(c, userPtr++)) + return -EFAULT; + data = (data << 16) + (c << 8); + } else + data = (data << 16) + data; + userCount--; + bal += hSpeed; + } + *p++ = data; + frameLeft--; + bal -= sSpeed; + } + expand_bal = bal; + expand_data = data; + *frameUsed += (ftotal - frameLeft) * 4; + utotal -= userCount; + return stereo? utotal * 2: utotal; +} + + +static ssize_t cs4218_ctx_u8(const u_char *userPtr, size_t userCount, + u_char frame[], ssize_t *frameUsed, + ssize_t frameLeft) +{ + unsigned int *p = (unsigned int *) &frame[*frameUsed]; + unsigned int data = expand_data; + int bal = expand_bal; + int hSpeed = sound.hard.speed, sSpeed = sound.soft.speed; + int stereo = sound.soft.stereo; + int utotal, ftotal; + + frameLeft >>= 2; + if (stereo) + userCount >>= 1; + ftotal = frameLeft; + utotal = userCount; + while (frameLeft) { + u_char c; + if (bal < 0) { + if (userCount == 0) + break; + if (get_user(c, userPtr++)) + return -EFAULT; + data = (c ^ 0x80) << 8; + if (stereo) { + if (get_user(c, userPtr++)) + return -EFAULT; + data = (data << 16) + ((c ^ 0x80) << 8); + } else + data = (data << 16) + data; + userCount--; + bal += hSpeed; + } + *p++ = data; + frameLeft--; + bal -= sSpeed; + } + expand_bal = bal; + expand_data = data; + *frameUsed += (ftotal - frameLeft) * 4; + utotal -= userCount; + return stereo? utotal * 2: utotal; +} + + +static ssize_t cs4218_ctx_s16(const u_char *userPtr, size_t userCount, + u_char frame[], ssize_t *frameUsed, + ssize_t frameLeft) +{ + unsigned int *p = (unsigned int *) &frame[*frameUsed]; + unsigned int data = expand_data; + unsigned short *up = (unsigned short *) userPtr; + int bal = expand_bal; + int hSpeed = sound.hard.speed, sSpeed = sound.soft.speed; + int stereo = sound.soft.stereo; + int utotal, ftotal; + + frameLeft >>= 2; + userCount >>= (stereo? 2: 1); + ftotal = frameLeft; + utotal = userCount; + while (frameLeft) { + unsigned short c; + if (bal < 0) { + if (userCount == 0) + break; + if (get_user(data, up++)) + return -EFAULT; + if (stereo) { + if (get_user(c, up++)) + return -EFAULT; + data = (data << 16) + c; + } else + data = (data << 16) + data; + userCount--; + bal += hSpeed; + } + *p++ = data; + frameLeft--; + bal -= sSpeed; + } + expand_bal = bal; + expand_data = data; + *frameUsed += (ftotal - frameLeft) * 4; + utotal -= userCount; + return stereo? utotal * 4: utotal * 2; +} + + +static ssize_t cs4218_ctx_u16(const u_char *userPtr, size_t userCount, + u_char frame[], ssize_t *frameUsed, + ssize_t frameLeft) +{ + int mask = (sound.soft.format == AFMT_U16_LE? 0x0080: 0x8000); + unsigned int *p = (unsigned int *) &frame[*frameUsed]; + unsigned int data = expand_data; + unsigned short *up = (unsigned short *) userPtr; + int bal = expand_bal; + int hSpeed = sound.hard.speed, sSpeed = sound.soft.speed; + int stereo = sound.soft.stereo; + int utotal, ftotal; + + frameLeft >>= 2; + userCount >>= (stereo? 2: 1); + ftotal = frameLeft; + utotal = userCount; + while (frameLeft) { + unsigned short c; + if (bal < 0) { + if (userCount == 0) + break; + if (get_user(data, up++)) + return -EFAULT; + data ^= mask; + if (stereo) { + if (get_user(c, up++)) + return -EFAULT; + data = (data << 16) + (c ^ mask); + } else + data = (data << 16) + data; + userCount--; + bal += hSpeed; + } + *p++ = data; + frameLeft--; + bal -= sSpeed; + } + expand_bal = bal; + expand_data = data; + *frameUsed += (ftotal - frameLeft) * 4; + utotal -= userCount; + return stereo? utotal * 4: utotal * 2; +} + +static ssize_t cs4218_ct_s8_read(const u_char *userPtr, size_t userCount, + u_char frame[], ssize_t *frameUsed, + ssize_t frameLeft) +{ + ssize_t count, used; + short *p = (short *) &frame[*frameUsed]; + int val, stereo = sound.soft.stereo; + + frameLeft >>= 2; + if (stereo) + userCount >>= 1; + used = count = min(userCount, frameLeft); + while (count > 0) { + u_char data; + + val = *p++; + data = val >> 8; + if (put_user(data, (u_char *)userPtr++)) + return -EFAULT; + if (stereo) { + val = *p; + data = val >> 8; + if (put_user(data, (u_char *)userPtr++)) + return -EFAULT; + } + p++; + count--; + } + *frameUsed += used * 4; + return stereo? used * 2: used; +} + + +static ssize_t cs4218_ct_u8_read(const u_char *userPtr, size_t userCount, + u_char frame[], ssize_t *frameUsed, + ssize_t frameLeft) +{ + ssize_t count, used; + short *p = (short *) &frame[*frameUsed]; + int val, stereo = sound.soft.stereo; + + frameLeft >>= 2; + if (stereo) + userCount >>= 1; + used = count = min(userCount, frameLeft); + while (count > 0) { + u_char data; + + val = *p++; + data = (val >> 8) ^ 0x80; + if (put_user(data, (u_char *)userPtr++)) + return -EFAULT; + if (stereo) { + val = *p; + data = (val >> 8) ^ 0x80; + if (put_user(data, (u_char *)userPtr++)) + return -EFAULT; + } + p++; + count--; + } + *frameUsed += used * 4; + return stereo? used * 2: used; +} + + +static ssize_t cs4218_ct_s16_read(const u_char *userPtr, size_t userCount, + u_char frame[], ssize_t *frameUsed, + ssize_t frameLeft) +{ + ssize_t count, used; + int stereo = sound.soft.stereo; + short *fp = (short *) &frame[*frameUsed]; + + frameLeft >>= 2; + userCount >>= (stereo? 2: 1); + used = count = min(userCount, frameLeft); + if (!stereo) { + short *up = (short *) userPtr; + while (count > 0) { + short data; + data = *fp; + if (put_user(data, up++)) + return -EFAULT; + fp+=2; + count--; + } + } else { + if (copy_to_user((u_char *)userPtr, fp, count * 4)) + return -EFAULT; + } + *frameUsed += used * 4; + return stereo? used * 4: used * 2; +} + +static ssize_t cs4218_ct_u16_read(const u_char *userPtr, size_t userCount, + u_char frame[], ssize_t *frameUsed, + ssize_t frameLeft) +{ + ssize_t count, used; + int mask = (sound.soft.format == AFMT_U16_LE? 0x0080: 0x8000); + int stereo = sound.soft.stereo; + short *fp = (short *) &frame[*frameUsed]; + short *up = (short *) userPtr; + + frameLeft >>= 2; + userCount >>= (stereo? 2: 1); + used = count = min(userCount, frameLeft); + while (count > 0) { + int data; + + data = *fp++; + data ^= mask; + if (put_user(data, up++)) + return -EFAULT; + if (stereo) { + data = *fp; + data ^= mask; + if (put_user(data, up++)) + return -EFAULT; + } + fp++; + count--; + } + *frameUsed += used * 4; + return stereo? used * 4: used * 2; +} + +static TRANS transCSNormal = { + cs4218_ct_law, cs4218_ct_law, cs4218_ct_s8, cs4218_ct_u8, + cs4218_ct_s16, cs4218_ct_u16, cs4218_ct_s16, cs4218_ct_u16 +}; + +static TRANS transCSExpand = { + cs4218_ctx_law, cs4218_ctx_law, cs4218_ctx_s8, cs4218_ctx_u8, + cs4218_ctx_s16, cs4218_ctx_u16, cs4218_ctx_s16, cs4218_ctx_u16 +}; + +static TRANS transCSNormalRead = { + NULL, NULL, cs4218_ct_s8_read, cs4218_ct_u8_read, + cs4218_ct_s16_read, cs4218_ct_u16_read, + cs4218_ct_s16_read, cs4218_ct_u16_read +}; + +/*** Low level stuff *********************************************************/ + +static void *CS_Alloc(unsigned int size, int flags) +{ + int order; + + size >>= 13; + for (order=0; order < 5; order++) { + if (size == 0) + break; + size >>= 1; + } + return (void *)__get_free_pages(flags, order); +} + +static void CS_Free(void *ptr, unsigned int size) +{ + int order; + + size >>= 13; + for (order=0; order < 5; order++) { + if (size == 0) + break; + size >>= 1; + } + free_pages((ulong)ptr, order); +} + +static int __init CS_IrqInit(void) +{ + cpm_install_handler(CPMVEC_SMC2, cs4218_intr, NULL); + return 1; +} + +#ifdef MODULE +static void CS_IrqCleanup(void) +{ + volatile smc_t *sp; + volatile cpm8xx_t *cp; + + /* First disable transmitter and receiver. + */ + sp = &cpmp->cp_smc[1]; + sp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN); + + /* And now shut down the SMC. + */ + cp = cpmp; /* Get pointer to Communication Processor */ + cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_SMC2, + CPM_CR_STOP_TX) | CPM_CR_FLG; + while (cp->cp_cpcr & CPM_CR_FLG); + + /* Release the interrupt handler. + */ + cpm_free_handler(CPMVEC_SMC2); + + if (beep_buf) + kfree(beep_buf); + kd_mksound = orig_mksound; +} +#endif /* MODULE */ + +static void CS_Silence(void) +{ + volatile smc_t *sp; + + /* Disable transmitter. + */ + sp = &cpmp->cp_smc[1]; + sp->smc_smcmr &= ~SMCMR_TEN; +} + +/* Frequencies depend upon external oscillator. There are two + * choices, 12.288 and 11.2896 MHz. The RPCG audio supports both through + * and external control register selection bit. + */ +static int cs4218_freqs[] = { + /* 12.288 11.2896 */ + 48000, 44100, + 32000, 29400, + 24000, 22050, + 19200, 17640, + 16000, 14700, + 12000, 11025, + 9600, 8820, + 8000, 7350 +}; + +static void CS_Init(void) +{ + int i, tolerance; + + switch (sound.soft.format) { + case AFMT_S16_LE: + case AFMT_U16_LE: + sound.hard.format = AFMT_S16_LE; + break; + default: + sound.hard.format = AFMT_S16_BE; + break; + } + sound.hard.stereo = 1; + sound.hard.size = 16; + + /* + * If we have a sample rate which is within catchRadius percent + * of the requested value, we don't have to expand the samples. + * Otherwise choose the next higher rate. + */ + i = (sizeof(cs4218_freqs) / sizeof(int)); + do { + tolerance = catchRadius * cs4218_freqs[--i] / 100; + } while (sound.soft.speed > cs4218_freqs[i] + tolerance && i > 0); + if (sound.soft.speed >= cs4218_freqs[i] - tolerance) + sound.trans_write = &transCSNormal; + else + sound.trans_write = &transCSExpand; + sound.trans_read = &transCSNormalRead; + sound.hard.speed = cs4218_freqs[i]; + cs4218_rate_index = i; + + /* The CS4218 has seven selectable clock dividers for the sample + * clock. The HIOX then provides one of two external rates. + * An even numbered frequency table index uses the high external + * clock rate. + */ + *(uint *)HIOX_CSR4_ADDR &= ~(HIOX_CSR4_AUDCLKHI | HIOX_CSR4_AUDCLKSEL); + if ((i & 1) == 0) + *(uint *)HIOX_CSR4_ADDR |= HIOX_CSR4_AUDCLKHI; + i >>= 1; + *(uint *)HIOX_CSR4_ADDR |= (i & HIOX_CSR4_AUDCLKSEL); + + expand_bal = -sound.soft.speed; +} + +static int CS_SetFormat(int format) +{ + int size; + + switch (format) { + case AFMT_QUERY: + return sound.soft.format; + case AFMT_MU_LAW: + case AFMT_A_LAW: + case AFMT_U8: + case AFMT_S8: + size = 8; + break; + case AFMT_S16_BE: + case AFMT_U16_BE: + case AFMT_S16_LE: + case AFMT_U16_LE: + size = 16; + break; + default: /* :-) */ + printk(KERN_ERR "dmasound: unknown format 0x%x, using AFMT_U8\n", + format); + size = 8; + format = AFMT_U8; + } + + sound.soft.format = format; + sound.soft.size = size; + if (sound.minDev == SND_DEV_DSP) { + sound.dsp.format = format; + sound.dsp.size = size; + } + + CS_Init(); + + return format; +} + +/* Volume is the amount of attenuation we tell the codec to impose + * on the outputs. There are 32 levels, with 0 the "loudest". + */ +#define CS_VOLUME_TO_MASK(x) (31 - ((((x) - 1) * 31) / 99)) +#define CS_MASK_TO_VOLUME(y) (100 - ((y) * 99 / 31)) + +static int cs_get_volume(uint reg) +{ + int volume; + + volume = CS_MASK_TO_VOLUME(CS_LATTEN_GET(reg)); + volume |= CS_MASK_TO_VOLUME(CS_RATTEN_GET(reg)) << 8; + return volume; +} + +static int cs_volume_setter(int volume, int mute) +{ + uint tempctl; + + if (mute && volume == 0) { + tempctl = cs4218_control | CS_MUTE; + } else { + tempctl = cs4218_control & ~CS_MUTE; + tempctl = tempctl & ~(CS_LATTEN | CS_RATTEN); + tempctl |= CS_LATTEN_SET(CS_VOLUME_TO_MASK(volume & 0xff)); + tempctl |= CS_RATTEN_SET(CS_VOLUME_TO_MASK((volume >> 8) & 0xff)); + volume = cs_get_volume(tempctl); + } + if (tempctl != cs4218_control) { + cs4218_ctl_write(tempctl); + } + return volume; +} + + +/* Gain has 16 steps from 0 to 15. These are in 1.5dB increments from + * 0 (no gain) to 22.5 dB. + */ +#define CS_RECLEVEL_TO_GAIN(v) \ + ((v) < 0 ? 0 : (v) > 100 ? 15 : (v) * 3 / 20) +#define CS_GAIN_TO_RECLEVEL(v) (((v) * 20 + 2) / 3) + +static int cs_get_gain(uint reg) +{ + int gain; + + gain = CS_GAIN_TO_RECLEVEL(CS_LGAIN_GET(reg)); + gain |= CS_GAIN_TO_RECLEVEL(CS_RGAIN_GET(reg)) << 8; + return gain; +} + +static int cs_set_gain(int gain) +{ + uint tempctl; + + tempctl = cs4218_control & ~(CS_LGAIN | CS_RGAIN); + tempctl |= CS_LGAIN_SET(CS_RECLEVEL_TO_GAIN(gain & 0xff)); + tempctl |= CS_RGAIN_SET(CS_RECLEVEL_TO_GAIN((gain >> 8) & 0xff)); + gain = cs_get_gain(tempctl); + + if (tempctl != cs4218_control) { + cs4218_ctl_write(tempctl); + } + return gain; +} + +static int CS_SetVolume(int volume) +{ + return cs_volume_setter(volume, CS_MUTE); +} + +static void CS_Play(void) +{ + int i, count; + unsigned long flags; + volatile cbd_t *bdp; + volatile cpm8xx_t *cp; + + save_flags(flags); cli(); +#if 0 + if (awacs_beep_state) { + /* sound takes precedence over beeps */ + out_le32(&awacs_txdma->control, (RUN|PAUSE|FLUSH|WAKE) << 16); + out_le32(&awacs->control, + (in_le32(&awacs->control) & ~0x1f00) + | (awacs_rate_index << 8)); + out_le32(&awacs->byteswap, sound.hard.format != AFMT_S16_BE); + out_le32(&awacs_txdma->cmdptr, virt_to_bus(&(awacs_tx_cmds[(sq.front+sq.active) % sq.max_count]))); + + beep_playing = 0; + awacs_beep_state = 0; + } +#endif + i = sq.front + sq.active; + if (i >= sq.max_count) + i -= sq.max_count; + while (sq.active < 2 && sq.active < sq.count) { + count = (sq.count == sq.active + 1)?sq.rear_size:sq.block_size; + if (count < sq.block_size && !sq.syncing) + /* last block not yet filled, and we're not syncing. */ + break; + + bdp = &tx_base[i]; + bdp->cbd_datlen = count; + + flush_dcache_range((ulong)sound_buffers[i], + (ulong)(sound_buffers[i] + count)); + + if (++i >= sq.max_count) + i = 0; + + if (sq.active == 0) { + /* The SMC does not load its fifo until the first + * TDM frame pulse, so the transmit data gets shifted + * by one word. To compensate for this, we incorrectly + * transmit the first buffer and shorten it by one + * word. Subsequent buffers are then aligned properly. + */ + bdp->cbd_datlen -= 2; + + /* Start up the SMC Transmitter. + */ + cp = cpmp; + cp->cp_smc[1].smc_smcmr |= SMCMR_TEN; + cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_SMC2, + CPM_CR_RESTART_TX) | CPM_CR_FLG; + while (cp->cp_cpcr & CPM_CR_FLG); + } + + /* Buffer is ready now. + */ + bdp->cbd_sc |= BD_SC_READY; + + ++sq.active; + } + restore_flags(flags); +} + + +static void CS_Record(void) +{ + unsigned long flags; + volatile smc_t *sp; + + if (read_sq.active) + return; + + save_flags(flags); cli(); + + /* This is all we have to do......Just start it up. + */ + sp = &cpmp->cp_smc[1]; + sp->smc_smcmr |= SMCMR_REN; + + read_sq.active = 1; + + restore_flags(flags); +} + + +static void +cs4218_tdm_tx_intr(void *devid) +{ + int i = sq.front; + volatile cbd_t *bdp; + + while (sq.active > 0) { + bdp = &tx_base[i]; + if (bdp->cbd_sc & BD_SC_READY) + break; /* this frame is still going */ + --sq.count; + --sq.active; + if (++i >= sq.max_count) + i = 0; + } + if (i != sq.front) + WAKE_UP(sq.action_queue); + sq.front = i; + + CS_Play(); + + if (!sq.active) + WAKE_UP(sq.sync_queue); +} + + +static void +cs4218_tdm_rx_intr(void *devid) +{ + + /* We want to blow 'em off when shutting down. + */ + if (read_sq.active == 0) + return; + + /* Check multiple buffers in case we were held off from + * interrupt processing for a long time. Geeze, I really hope + * this doesn't happen. + */ + while ((rx_base[read_sq.rear].cbd_sc & BD_SC_EMPTY) == 0) { + + /* Invalidate the data cache range for this buffer. + */ + invalidate_dcache_range( + (uint)(sound_read_buffers[read_sq.rear]), + (uint)(sound_read_buffers[read_sq.rear] + read_sq.block_size)); + + /* Make buffer available again and move on. + */ + rx_base[read_sq.rear].cbd_sc |= BD_SC_EMPTY; + read_sq.rear++; + + /* Wrap the buffer ring. + */ + if (read_sq.rear >= read_sq.max_active) + read_sq.rear = 0; + + /* If we have caught up to the front buffer, bump it. + * This will cause weird (but not fatal) results if the + * read loop is currently using this buffer. The user is + * behind in this case anyway, so weird things are going + * to happen. + */ + if (read_sq.rear == read_sq.front) { + read_sq.front++; + if (read_sq.front >= read_sq.max_active) + read_sq.front = 0; + } + } + + WAKE_UP(read_sq.action_queue); +} + +static void cs_nosound(unsigned long xx) +{ + unsigned long flags; + + save_flags(flags); cli(); + if (beep_playing) { +#if 0 + st_le16(&beep_dbdma_cmd->command, DBDMA_STOP); +#endif + beep_playing = 0; + } + restore_flags(flags); +} + +static struct timer_list beep_timer = { + function: cs_nosound +}; + +static void cs_mksound(unsigned int hz, unsigned int ticks) +{ + unsigned long flags; + int beep_speed = BEEP_SPEED; + int srate = cs4218_freqs[beep_speed]; + int period, ncycles, nsamples; + int i, j, f; + short *p; + static int beep_hz_cache; + static int beep_nsamples_cache; + static int beep_volume_cache; + + if (hz <= srate / BEEP_BUFLEN || hz > srate / 2) { +#if 1 + /* this is a hack for broken X server code */ + hz = 750; + ticks = 12; +#else + /* cancel beep currently playing */ + awacs_nosound(0); + return; +#endif + } + save_flags(flags); cli(); + del_timer(&beep_timer); + if (ticks) { + beep_timer.expires = jiffies + ticks; + add_timer(&beep_timer); + } + if (beep_playing || sq.active || beep_buf == NULL) { + restore_flags(flags); + return; /* too hard, sorry :-( */ + } + beep_playing = 1; +#if 0 + st_le16(&beep_dbdma_cmd->command, OUTPUT_MORE + BR_ALWAYS); +#endif + restore_flags(flags); + + if (hz == beep_hz_cache && beep_volume == beep_volume_cache) { + nsamples = beep_nsamples_cache; + } else { + period = srate * 256 / hz; /* fixed point */ + ncycles = BEEP_BUFLEN * 256 / period; + nsamples = (period * ncycles) >> 8; + f = ncycles * 65536 / nsamples; + j = 0; + p = beep_buf; + for (i = 0; i < nsamples; ++i, p += 2) { + p[0] = p[1] = beep_wform[j >> 8] * beep_volume; + j = (j + f) & 0xffff; + } + beep_hz_cache = hz; + beep_volume_cache = beep_volume; + beep_nsamples_cache = nsamples; + } + +#if 0 + st_le16(&beep_dbdma_cmd->req_count, nsamples*4); + st_le16(&beep_dbdma_cmd->xfer_status, 0); + st_le32(&beep_dbdma_cmd->cmd_dep, virt_to_bus(beep_dbdma_cmd)); + st_le32(&beep_dbdma_cmd->phy_addr, virt_to_bus(beep_buf)); + awacs_beep_state = 1; + + save_flags(flags); cli(); + if (beep_playing) { /* i.e. haven't been terminated already */ + out_le32(&awacs_txdma->control, (RUN|WAKE|FLUSH|PAUSE) << 16); + out_le32(&awacs->control, + (in_le32(&awacs->control) & ~0x1f00) + | (beep_speed << 8)); + out_le32(&awacs->byteswap, 0); + out_le32(&awacs_txdma->cmdptr, virt_to_bus(beep_dbdma_cmd)); + out_le32(&awacs_txdma->control, RUN | (RUN << 16)); + } +#endif + restore_flags(flags); +} + +static void CS_open(void) +{ + MOD_INC_USE_COUNT; +} + +static void CS_release(void) +{ + MOD_DEC_USE_COUNT; +} + +static MACHINE mach_cs4218 = { + name: "HIOX CS4218", + name2: "Built-in Sound", + open: CS_open, + release: CS_release, + dma_alloc: CS_Alloc, + dma_free: CS_Free, + irqinit: CS_IrqInit, +#ifdef MODULE + irqcleanup: CS_IrqCleanup, +#endif /* MODULE */ + init: CS_Init, + silence: CS_Silence, + setFormat: CS_SetFormat, + setVolume: CS_SetVolume, + play: CS_Play +}; + + +/*** Mid level stuff *********************************************************/ + + +static void sound_silence(void) +{ + /* update hardware settings one more */ + (*sound.mach.init)(); + + (*sound.mach.silence)(); +} + + +static void sound_init(void) +{ + (*sound.mach.init)(); +} + + +static int sound_set_format(int format) +{ + return(*sound.mach.setFormat)(format); +} + + +static int sound_set_speed(int speed) +{ + if (speed < 0) + return(sound.soft.speed); + + sound.soft.speed = speed; + (*sound.mach.init)(); + if (sound.minDev == SND_DEV_DSP) + sound.dsp.speed = sound.soft.speed; + + return(sound.soft.speed); +} + + +static int sound_set_stereo(int stereo) +{ + if (stereo < 0) + return(sound.soft.stereo); + + stereo = !!stereo; /* should be 0 or 1 now */ + + sound.soft.stereo = stereo; + if (sound.minDev == SND_DEV_DSP) + sound.dsp.stereo = stereo; + (*sound.mach.init)(); + + return(stereo); +} + + +static int sound_set_volume(int volume) +{ + return(*sound.mach.setVolume)(volume); +} + +static ssize_t sound_copy_translate(const u_char *userPtr, + size_t userCount, + u_char frame[], ssize_t *frameUsed, + ssize_t frameLeft) +{ + ssize_t (*ct_func)(const u_char *, size_t, u_char *, ssize_t *, ssize_t) = NULL; + + switch (sound.soft.format) { + case AFMT_MU_LAW: + ct_func = sound.trans_write->ct_ulaw; + break; + case AFMT_A_LAW: + ct_func = sound.trans_write->ct_alaw; + break; + case AFMT_S8: + ct_func = sound.trans_write->ct_s8; + break; + case AFMT_U8: + ct_func = sound.trans_write->ct_u8; + break; + case AFMT_S16_BE: + ct_func = sound.trans_write->ct_s16be; + break; + case AFMT_U16_BE: + ct_func = sound.trans_write->ct_u16be; + break; + case AFMT_S16_LE: + ct_func = sound.trans_write->ct_s16le; + break; + case AFMT_U16_LE: + ct_func = sound.trans_write->ct_u16le; + break; + } + if (ct_func) + return ct_func(userPtr, userCount, frame, frameUsed, frameLeft); + else + return 0; +} + +static ssize_t sound_copy_translate_read(const u_char *userPtr, + size_t userCount, + u_char frame[], ssize_t *frameUsed, + ssize_t frameLeft) +{ + ssize_t (*ct_func)(const u_char *, size_t, u_char *, ssize_t *, ssize_t) = NULL; + + switch (sound.soft.format) { + case AFMT_MU_LAW: + ct_func = sound.trans_read->ct_ulaw; + break; + case AFMT_A_LAW: + ct_func = sound.trans_read->ct_alaw; + break; + case AFMT_S8: + ct_func = sound.trans_read->ct_s8; + break; + case AFMT_U8: + ct_func = sound.trans_read->ct_u8; + break; + case AFMT_S16_BE: + ct_func = sound.trans_read->ct_s16be; + break; + case AFMT_U16_BE: + ct_func = sound.trans_read->ct_u16be; + break; + case AFMT_S16_LE: + ct_func = sound.trans_read->ct_s16le; + break; + case AFMT_U16_LE: + ct_func = sound.trans_read->ct_u16le; + break; + } + if (ct_func) + return ct_func(userPtr, userCount, frame, frameUsed, frameLeft); + else + return 0; +} + + +/* + * /dev/mixer abstraction + */ + +static int mixer_open(struct inode *inode, struct file *file) +{ + MOD_INC_USE_COUNT; + mixer.busy = 1; + return 0; +} + + +static int mixer_release(struct inode *inode, struct file *file) +{ + mixer.busy = 0; + MOD_DEC_USE_COUNT; + return 0; +} + + +static int mixer_ioctl(struct inode *inode, struct file *file, u_int cmd, + u_long arg) +{ + int data; + uint tmpcs; + + if (_SIOC_DIR(cmd) & _SIOC_WRITE) + mixer.modify_counter++; + if (cmd == OSS_GETVERSION) + return IOCTL_OUT(arg, SOUND_VERSION); + switch (cmd) { + case SOUND_MIXER_INFO: { + mixer_info info; + strncpy(info.id, "CS4218_TDM", sizeof(info.id)); + strncpy(info.name, "CS4218_TDM", sizeof(info.name)); + info.name[sizeof(info.name)-1] = 0; + info.modify_counter = mixer.modify_counter; + if (copy_to_user((int *)arg, &info, sizeof(info))) + return -EFAULT; + return 0; + } + case SOUND_MIXER_READ_DEVMASK: + data = SOUND_MASK_VOLUME | SOUND_MASK_LINE + | SOUND_MASK_MIC | SOUND_MASK_RECLEV + | SOUND_MASK_ALTPCM; + return IOCTL_OUT(arg, data); + case SOUND_MIXER_READ_RECMASK: + data = SOUND_MASK_LINE | SOUND_MASK_MIC; + return IOCTL_OUT(arg, data); + case SOUND_MIXER_READ_RECSRC: + if (cs4218_control & CS_DO1) + data = SOUND_MASK_LINE; + else + data = SOUND_MASK_MIC; + return IOCTL_OUT(arg, data); + case SOUND_MIXER_WRITE_RECSRC: + IOCTL_IN(arg, data); + data &= (SOUND_MASK_LINE | SOUND_MASK_MIC); + if (data & SOUND_MASK_LINE) + tmpcs = cs4218_control | + (CS_ISL | CS_ISR | CS_DO1); + if (data & SOUND_MASK_MIC) + tmpcs = cs4218_control & + ~(CS_ISL | CS_ISR | CS_DO1); + if (tmpcs != cs4218_control) + cs4218_ctl_write(tmpcs); + return IOCTL_OUT(arg, data); + case SOUND_MIXER_READ_STEREODEVS: + data = SOUND_MASK_VOLUME | SOUND_MASK_RECLEV; + return IOCTL_OUT(arg, data); + case SOUND_MIXER_READ_CAPS: + return IOCTL_OUT(arg, 0); + case SOUND_MIXER_READ_VOLUME: + data = (cs4218_control & CS_MUTE)? 0: + cs_get_volume(cs4218_control); + return IOCTL_OUT(arg, data); + case SOUND_MIXER_WRITE_VOLUME: + IOCTL_IN(arg, data); + return IOCTL_OUT(arg, sound_set_volume(data)); + case SOUND_MIXER_WRITE_ALTPCM: /* really bell volume */ + IOCTL_IN(arg, data); + beep_volume = data & 0xff; + /* fall through */ + case SOUND_MIXER_READ_ALTPCM: + return IOCTL_OUT(arg, beep_volume); + case SOUND_MIXER_WRITE_RECLEV: + IOCTL_IN(arg, data); + data = cs_set_gain(data); + return IOCTL_OUT(arg, data); + case SOUND_MIXER_READ_RECLEV: + data = cs_get_gain(cs4218_control); + return IOCTL_OUT(arg, data); + } + + return -EINVAL; +} + + +static struct file_operations mixer_fops = +{ + owner: THIS_MODULE, + llseek: sound_lseek, + ioctl: mixer_ioctl, + open: mixer_open, + release: mixer_release, +}; + + +static void __init mixer_init(void) +{ + mixer_unit = register_sound_mixer(&mixer_fops, -1); + if (mixer_unit < 0) + return; + + mixer.busy = 0; + sound.treble = 0; + sound.bass = 0; + + /* Set Line input, no gain, no attenuation. + */ + cs4218_control = CS_ISL | CS_ISR | CS_DO1; + cs4218_control |= CS_LGAIN_SET(0) | CS_RGAIN_SET(0); + cs4218_control |= CS_LATTEN_SET(0) | CS_RATTEN_SET(0); + cs4218_ctl_write(cs4218_control); +} + + +/* + * Sound queue stuff, the heart of the driver + */ + + +static int sq_allocate_buffers(void) +{ + int i; + + if (sound_buffers) + return 0; + sound_buffers = kmalloc (numBufs * sizeof(char *), GFP_KERNEL); + if (!sound_buffers) + return -ENOMEM; + for (i = 0; i < numBufs; i++) { + sound_buffers[i] = sound.mach.dma_alloc (bufSize << 10, GFP_KERNEL); + if (!sound_buffers[i]) { + while (i--) + sound.mach.dma_free (sound_buffers[i], bufSize << 10); + kfree (sound_buffers); + sound_buffers = 0; + return -ENOMEM; + } + } + return 0; +} + + +static void sq_release_buffers(void) +{ + int i; + + if (sound_buffers) { + for (i = 0; i < numBufs; i++) + sound.mach.dma_free (sound_buffers[i], bufSize << 10); + kfree (sound_buffers); + sound_buffers = 0; + } +} + + +static int sq_allocate_read_buffers(void) +{ + int i; + + if (sound_read_buffers) + return 0; + sound_read_buffers = kmalloc(numReadBufs * sizeof(char *), GFP_KERNEL); + if (!sound_read_buffers) + return -ENOMEM; + for (i = 0; i < numBufs; i++) { + sound_read_buffers[i] = sound.mach.dma_alloc (readbufSize<<10, + GFP_KERNEL); + if (!sound_read_buffers[i]) { + while (i--) + sound.mach.dma_free (sound_read_buffers[i], + readbufSize << 10); + kfree (sound_read_buffers); + sound_read_buffers = 0; + return -ENOMEM; + } + } + return 0; +} + +static void sq_release_read_buffers(void) +{ + int i; + + if (sound_read_buffers) { + cpmp->cp_smc[1].smc_smcmr &= ~SMCMR_REN; + for (i = 0; i < numReadBufs; i++) + sound.mach.dma_free (sound_read_buffers[i], + bufSize << 10); + kfree (sound_read_buffers); + sound_read_buffers = 0; + } +} + + +static void sq_setup(int numBufs, int bufSize, char **write_buffers) +{ + int i; + volatile cbd_t *bdp; + volatile cpm8xx_t *cp; + volatile smc_t *sp; + + /* Make sure the SMC transmit is shut down. + */ + cp = cpmp; + sp = &cpmp->cp_smc[1]; + sp->smc_smcmr &= ~SMCMR_TEN; + + sq.max_count = numBufs; + sq.max_active = numBufs; + sq.block_size = bufSize; + sq.buffers = write_buffers; + + sq.front = sq.count = 0; + sq.rear = -1; + sq.syncing = 0; + sq.active = 0; + + bdp = tx_base; + for (i=0; i<numBufs; i++) { + bdp->cbd_bufaddr = virt_to_bus(write_buffers[i]); + bdp++; + } + + /* This causes the SMC to sync up with the first buffer again. + */ + cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_SMC2, CPM_CR_INIT_TX) | CPM_CR_FLG; + while (cp->cp_cpcr & CPM_CR_FLG); +} + +static void read_sq_setup(int numBufs, int bufSize, char **read_buffers) +{ + int i; + volatile cbd_t *bdp; + volatile cpm8xx_t *cp; + volatile smc_t *sp; + + /* Make sure the SMC receive is shut down. + */ + cp = cpmp; + sp = &cpmp->cp_smc[1]; + sp->smc_smcmr &= ~SMCMR_REN; + + read_sq.max_count = numBufs; + read_sq.max_active = numBufs; + read_sq.block_size = bufSize; + read_sq.buffers = read_buffers; + + read_sq.front = read_sq.count = 0; + read_sq.rear = 0; + read_sq.rear_size = 0; + read_sq.syncing = 0; + read_sq.active = 0; + + bdp = rx_base; + for (i=0; i<numReadBufs; i++) { + bdp->cbd_bufaddr = virt_to_bus(read_buffers[i]); + bdp->cbd_datlen = read_sq.block_size; + bdp++; + } + + /* This causes the SMC to sync up with the first buffer again. + */ + cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_SMC2, CPM_CR_INIT_RX) | CPM_CR_FLG; + while (cp->cp_cpcr & CPM_CR_FLG); +} + + +static void sq_play(void) +{ + (*sound.mach.play)(); +} + + +/* ++TeSche: radically changed this one too */ + +static ssize_t sq_write(struct file *file, const char *src, size_t uLeft, + loff_t *ppos) +{ + ssize_t uWritten = 0; + u_char *dest; + ssize_t uUsed, bUsed, bLeft; + + /* ++TeSche: Is something like this necessary? + * Hey, that's an honest question! Or does any other part of the + * filesystem already checks this situation? I really don't know. + */ + if (uLeft == 0) + return 0; + + /* The interrupt doesn't start to play the last, incomplete frame. + * Thus we can append to it without disabling the interrupts! (Note + * also that sq.rear isn't affected by the interrupt.) + */ + + if (sq.count > 0 && (bLeft = sq.block_size-sq.rear_size) > 0) { + dest = sq_block_address(sq.rear); + bUsed = sq.rear_size; + uUsed = sound_copy_translate(src, uLeft, dest, &bUsed, bLeft); + if (uUsed <= 0) + return uUsed; + src += uUsed; + uWritten += uUsed; + uLeft -= uUsed; + sq.rear_size = bUsed; + } + + do { + while (sq.count == sq.max_active) { + sq_play(); + if (NON_BLOCKING(sq.open_mode)) + return uWritten > 0 ? uWritten : -EAGAIN; + SLEEP(sq.action_queue); + if (SIGNAL_RECEIVED) + return uWritten > 0 ? uWritten : -EINTR; + } + + /* Here, we can avoid disabling the interrupt by first + * copying and translating the data, and then updating + * the sq variables. Until this is done, the interrupt + * won't see the new frame and we can work on it + * undisturbed. + */ + + dest = sq_block_address((sq.rear+1) % sq.max_count); + bUsed = 0; + bLeft = sq.block_size; + uUsed = sound_copy_translate(src, uLeft, dest, &bUsed, bLeft); + if (uUsed <= 0) + break; + src += uUsed; + uWritten += uUsed; + uLeft -= uUsed; + if (bUsed) { + sq.rear = (sq.rear+1) % sq.max_count; + sq.rear_size = bUsed; + sq.count++; + } + } while (bUsed); /* uUsed may have been 0 */ + + sq_play(); + + return uUsed < 0? uUsed: uWritten; +} + + +/***********/ + +/* Here is how the values are used for reading. + * The value 'active' simply indicates the DMA is running. This is + * done so the driver semantics are DMA starts when the first read is + * posted. The value 'front' indicates the buffer we should next + * send to the user. The value 'rear' indicates the buffer the DMA is + * currently filling. When 'front' == 'rear' the buffer "ring" is + * empty (we always have an empty available). The 'rear_size' is used + * to track partial offsets into the current buffer. Right now, I just keep + * The DMA running. If the reader can't keep up, the interrupt tosses + * the oldest buffer. We could also shut down the DMA in this case. + */ +static ssize_t sq_read(struct file *file, char *dst, size_t uLeft, + loff_t *ppos) +{ + + ssize_t uRead, bLeft, bUsed, uUsed; + + if (uLeft == 0) + return 0; + + if (!read_sq.active) + CS_Record(); /* Kick off the record process. */ + + uRead = 0; + + /* Move what the user requests, depending upon other options. + */ + while (uLeft > 0) { + + /* When front == rear, the DMA is not done yet. + */ + while (read_sq.front == read_sq.rear) { + if (NON_BLOCKING(read_sq.open_mode)) { + return uRead > 0 ? uRead : -EAGAIN; + } + SLEEP(read_sq.action_queue); + if (SIGNAL_RECEIVED) + return uRead > 0 ? uRead : -EINTR; + } + + /* The amount we move is either what is left in the + * current buffer or what the user wants. + */ + bLeft = read_sq.block_size - read_sq.rear_size; + bUsed = read_sq.rear_size; + uUsed = sound_copy_translate_read(dst, uLeft, + read_sq.buffers[read_sq.front], &bUsed, bLeft); + if (uUsed <= 0) + return uUsed; + dst += uUsed; + uRead += uUsed; + uLeft -= uUsed; + read_sq.rear_size += bUsed; + if (read_sq.rear_size >= read_sq.block_size) { + read_sq.rear_size = 0; + read_sq.front++; + if (read_sq.front >= read_sq.max_active) + read_sq.front = 0; + } + } + return uRead; +} + +static int sq_open(struct inode *inode, struct file *file) +{ + int rc = 0; + + MOD_INC_USE_COUNT; + if (file->f_mode & FMODE_WRITE) { + if (sq.busy) { + rc = -EBUSY; + if (NON_BLOCKING(file->f_flags)) + goto err_out; + rc = -EINTR; + while (sq.busy) { + SLEEP(sq.open_queue); + if (SIGNAL_RECEIVED) + goto err_out; + } + } + sq.busy = 1; /* Let's play spot-the-race-condition */ + + if (sq_allocate_buffers()) goto err_out_nobusy; + + sq_setup(numBufs, bufSize<<10,sound_buffers); + sq.open_mode = file->f_mode; + } + + + if (file->f_mode & FMODE_READ) { + if (read_sq.busy) { + rc = -EBUSY; + if (NON_BLOCKING(file->f_flags)) + goto err_out; + rc = -EINTR; + while (read_sq.busy) { + SLEEP(read_sq.open_queue); + if (SIGNAL_RECEIVED) + goto err_out; + } + rc = 0; + } + read_sq.busy = 1; + if (sq_allocate_read_buffers()) goto err_out_nobusy; + + read_sq_setup(numReadBufs,readbufSize<<10, sound_read_buffers); + read_sq.open_mode = file->f_mode; + } + + /* Start up the 4218 by: + * Reset. + * Enable, unreset. + */ + *((volatile uint *)HIOX_CSR4_ADDR) &= ~HIOX_CSR4_RSTAUDIO; + eieio(); + *((volatile uint *)HIOX_CSR4_ADDR) |= HIOX_CSR4_ENAUDIO; + mdelay(50); + *((volatile uint *)HIOX_CSR4_ADDR) |= HIOX_CSR4_RSTAUDIO; + + /* We need to send the current control word in case someone + * opened /dev/mixer and changed things while we were shut + * down. Chances are good the initialization that follows + * would have done this, but it is still possible it wouldn't. + */ + cs4218_ctl_write(cs4218_control); + + sound.minDev = MINOR(inode->i_rdev) & 0x0f; + sound.soft = sound.dsp; + sound.hard = sound.dsp; + sound_init(); + if ((MINOR(inode->i_rdev) & 0x0f) == SND_DEV_AUDIO) { + sound_set_speed(8000); + sound_set_stereo(0); + sound_set_format(AFMT_MU_LAW); + } + + return 0; + +err_out_nobusy: + if (file->f_mode & FMODE_WRITE) { + sq.busy = 0; + WAKE_UP(sq.open_queue); + } + if (file->f_mode & FMODE_READ) { + read_sq.busy = 0; + WAKE_UP(read_sq.open_queue); + } +err_out: + MOD_DEC_USE_COUNT; + return rc; +} + + +static void sq_reset(void) +{ + sound_silence(); + sq.active = 0; + sq.count = 0; + sq.front = (sq.rear+1) % sq.max_count; +#if 0 + init_tdm_buffers(); +#endif +} + + +static int sq_fsync(struct file *filp, struct dentry *dentry) +{ + int rc = 0; + + sq.syncing = 1; + sq_play(); /* there may be an incomplete frame waiting */ + + while (sq.active) { + SLEEP(sq.sync_queue); + if (SIGNAL_RECEIVED) { + /* While waiting for audio output to drain, an + * interrupt occurred. Stop audio output immediately + * and clear the queue. */ + sq_reset(); + rc = -EINTR; + break; + } + } + + sq.syncing = 0; + return rc; +} + +static int sq_release(struct inode *inode, struct file *file) +{ + int rc = 0; + + if (sq.busy) + rc = sq_fsync(file, file->f_dentry); + sound.soft = sound.dsp; + sound.hard = sound.dsp; + sound_silence(); + + sq_release_read_buffers(); + sq_release_buffers(); + MOD_DEC_USE_COUNT; + + if (file->f_mode & FMODE_READ) { + read_sq.busy = 0; + WAKE_UP(read_sq.open_queue); + } + + if (file->f_mode & FMODE_WRITE) { + sq.busy = 0; + WAKE_UP(sq.open_queue); + } + + /* Shut down the SMC. + */ + cpmp->cp_smc[1].smc_smcmr &= ~(SMCMR_TEN | SMCMR_REN); + + /* Shut down the codec. + */ + *((volatile uint *)HIOX_CSR4_ADDR) |= HIOX_CSR4_RSTAUDIO; + eieio(); + *((volatile uint *)HIOX_CSR4_ADDR) &= ~HIOX_CSR4_ENAUDIO; + + /* Wake up a process waiting for the queue being released. + * Note: There may be several processes waiting for a call + * to open() returning. */ + + return rc; +} + + +static int sq_ioctl(struct inode *inode, struct file *file, u_int cmd, + u_long arg) +{ + u_long fmt; + int data; +#if 0 + int size, nbufs; +#else + int size; +#endif + + switch (cmd) { + case SNDCTL_DSP_RESET: + sq_reset(); + return 0; + case SNDCTL_DSP_POST: + case SNDCTL_DSP_SYNC: + return sq_fsync(file, file->f_dentry); + + /* ++TeSche: before changing any of these it's + * probably wise to wait until sound playing has + * settled down. */ + case SNDCTL_DSP_SPEED: + sq_fsync(file, file->f_dentry); + IOCTL_IN(arg, data); + return IOCTL_OUT(arg, sound_set_speed(data)); + case SNDCTL_DSP_STEREO: + sq_fsync(file, file->f_dentry); + IOCTL_IN(arg, data); + return IOCTL_OUT(arg, sound_set_stereo(data)); + case SOUND_PCM_WRITE_CHANNELS: + sq_fsync(file, file->f_dentry); + IOCTL_IN(arg, data); + return IOCTL_OUT(arg, sound_set_stereo(data-1)+1); + case SNDCTL_DSP_SETFMT: + sq_fsync(file, file->f_dentry); + IOCTL_IN(arg, data); + return IOCTL_OUT(arg, sound_set_format(data)); + case SNDCTL_DSP_GETFMTS: + fmt = 0; + if (sound.trans_write) { + if (sound.trans_write->ct_ulaw) + fmt |= AFMT_MU_LAW; + if (sound.trans_write->ct_alaw) + fmt |= AFMT_A_LAW; + if (sound.trans_write->ct_s8) + fmt |= AFMT_S8; + if (sound.trans_write->ct_u8) + fmt |= AFMT_U8; + if (sound.trans_write->ct_s16be) + fmt |= AFMT_S16_BE; + if (sound.trans_write->ct_u16be) + fmt |= AFMT_U16_BE; + if (sound.trans_write->ct_s16le) + fmt |= AFMT_S16_LE; + if (sound.trans_write->ct_u16le) + fmt |= AFMT_U16_LE; + } + return IOCTL_OUT(arg, fmt); + case SNDCTL_DSP_GETBLKSIZE: + size = sq.block_size + * sound.soft.size * (sound.soft.stereo + 1) + / (sound.hard.size * (sound.hard.stereo + 1)); + return IOCTL_OUT(arg, size); + case SNDCTL_DSP_SUBDIVIDE: + break; +#if 0 /* Sorry can't do this at the moment. The CPM allocated buffers + * long ago that can't be changed. + */ + case SNDCTL_DSP_SETFRAGMENT: + if (sq.count || sq.active || sq.syncing) + return -EINVAL; + IOCTL_IN(arg, size); + nbufs = size >> 16; + if (nbufs < 2 || nbufs > numBufs) + nbufs = numBufs; + size &= 0xffff; + if (size >= 8 && size <= 30) { + size = 1 << size; + size *= sound.hard.size * (sound.hard.stereo + 1); + size /= sound.soft.size * (sound.soft.stereo + 1); + if (size > (bufSize << 10)) + size = bufSize << 10; + } else + size = bufSize << 10; + sq_setup(numBufs, size, sound_buffers); + sq.max_active = nbufs; + return 0; +#endif + + default: + return mixer_ioctl(inode, file, cmd, arg); + } + return -EINVAL; +} + + + +static struct file_operations sq_fops = +{ + owner: THIS_MODULE, + llseek: sound_lseek, + read: sq_read, /* sq_read */ + write: sq_write, + ioctl: sq_ioctl, + open: sq_open, + release: sq_release, +}; + + +static void __init sq_init(void) +{ + sq_unit = register_sound_dsp(&sq_fops, -1); + if (sq_unit < 0) + return; + + init_waitqueue_head(&sq.action_queue); + init_waitqueue_head(&sq.open_queue); + init_waitqueue_head(&sq.sync_queue); + init_waitqueue_head(&read_sq.action_queue); + init_waitqueue_head(&read_sq.open_queue); + init_waitqueue_head(&read_sq.sync_queue); + + sq.busy = 0; + read_sq.busy = 0; + + /* whatever you like as startup mode for /dev/dsp, + * (/dev/audio hasn't got a startup mode). note that + * once changed a new open() will *not* restore these! + */ + sound.dsp.format = AFMT_S16_BE; + sound.dsp.stereo = 1; + sound.dsp.size = 16; + + /* set minimum rate possible without expanding */ + sound.dsp.speed = 8000; + + /* before the first open to /dev/dsp this wouldn't be set */ + sound.soft = sound.dsp; + sound.hard = sound.dsp; + + sound_silence(); +} + +/* + * /dev/sndstat + */ + + +/* state.buf should not overflow! */ + +static int state_open(struct inode *inode, struct file *file) +{ + char *buffer = state.buf, *mach = "", cs4218_buf[50]; + int len = 0; + + if (state.busy) + return -EBUSY; + + MOD_INC_USE_COUNT; + state.ptr = 0; + state.busy = 1; + + sprintf(cs4218_buf, "Crystal CS4218 on TDM, "); + mach = cs4218_buf; + + len += sprintf(buffer+len, "%sDMA sound driver:\n", mach); + + len += sprintf(buffer+len, "\tsound.format = 0x%x", sound.soft.format); + switch (sound.soft.format) { + case AFMT_MU_LAW: + len += sprintf(buffer+len, " (mu-law)"); + break; + case AFMT_A_LAW: + len += sprintf(buffer+len, " (A-law)"); + break; + case AFMT_U8: + len += sprintf(buffer+len, " (unsigned 8 bit)"); + break; + case AFMT_S8: + len += sprintf(buffer+len, " (signed 8 bit)"); + break; + case AFMT_S16_BE: + len += sprintf(buffer+len, " (signed 16 bit big)"); + break; + case AFMT_U16_BE: + len += sprintf(buffer+len, " (unsigned 16 bit big)"); + break; + case AFMT_S16_LE: + len += sprintf(buffer+len, " (signed 16 bit little)"); + break; + case AFMT_U16_LE: + len += sprintf(buffer+len, " (unsigned 16 bit little)"); + break; + } + len += sprintf(buffer+len, "\n"); + len += sprintf(buffer+len, "\tsound.speed = %dHz (phys. %dHz)\n", + sound.soft.speed, sound.hard.speed); + len += sprintf(buffer+len, "\tsound.stereo = 0x%x (%s)\n", + sound.soft.stereo, sound.soft.stereo ? "stereo" : "mono"); + len += sprintf(buffer+len, "\tsq.block_size = %d sq.max_count = %d" + " sq.max_active = %d\n", + sq.block_size, sq.max_count, sq.max_active); + len += sprintf(buffer+len, "\tsq.count = %d sq.rear_size = %d\n", sq.count, + sq.rear_size); + len += sprintf(buffer+len, "\tsq.active = %d sq.syncing = %d\n", + sq.active, sq.syncing); + state.len = len; + return 0; +} + + +static int state_release(struct inode *inode, struct file *file) +{ + state.busy = 0; + MOD_DEC_USE_COUNT; + return 0; +} + + +static ssize_t state_read(struct file *file, char *buf, size_t count, + loff_t *ppos) +{ + int n = state.len - state.ptr; + if (n > count) + n = count; + if (n <= 0) + return 0; + if (copy_to_user(buf, &state.buf[state.ptr], n)) + return -EFAULT; + state.ptr += n; + return n; +} + + +static struct file_operations state_fops = +{ + owner: THIS_MODULE, + llseek: sound_lseek, + read: state_read, + open: state_open, + release: state_release, +}; + + +static void __init state_init(void) +{ + state_unit = register_sound_special(&state_fops, SND_DEV_STATUS); + if (state_unit < 0) + return; + state.busy = 0; +} + + +/*** Common stuff ********************************************************/ + +static long long sound_lseek(struct file *file, long long offset, int orig) +{ + return -ESPIPE; +} + + +/*** Config & Setup **********************************************************/ + + +int __init tdm8xx_sound_init(void) +{ + int i, has_sound; + uint dp_addr; + volatile uint *sirp; + volatile cbd_t *bdp; + volatile cpm8xx_t *cp; + volatile smc_t *sp; + volatile smc_uart_t *up; + volatile immap_t *immap; + + has_sound = 0; + + /* Program the SI/TSA to use TDMa, connected to SMC2, for 4 bytes. + */ + cp = cpmp; /* Get pointer to Communication Processor */ + immap = (immap_t *)IMAP_ADDR; /* and to internal registers */ + + /* Set all TDMa control bits to zero. This enables most features + * we want. + */ + cp->cp_simode &= ~0x00000fff; + + /* Enable common receive/transmit clock pins, use IDL format. + * Sync on falling edge, transmit rising clock, recieve falling + * clock, delay 1 bit on both Tx and Rx. Common Tx/Rx clocks and + * sync. + * Connect SMC2 to TSA. + */ + cp->cp_simode |= 0x80000141; + + /* Configure port A pins for TDMa operation. + * The RPX-Lite (MPC850/823) loses SMC2 when TDM is used. + */ + immap->im_ioport.iop_papar |= 0x01c0; /* Enable TDMa functions */ + immap->im_ioport.iop_padir |= 0x00c0; /* Enable TDMa Tx/Rx */ + immap->im_ioport.iop_padir &= ~0x0100; /* Enable L1RCLKa */ + + immap->im_ioport.iop_pcpar |= 0x0800; /* Enable L1RSYNCa */ + immap->im_ioport.iop_pcdir &= ~0x0800; + + /* Initialize the SI TDM routing table. We use TDMa only. + * The receive table and transmit table each have only one + * entry, to capture/send four bytes after each frame pulse. + * The 16-bit ram entry is 0000 0001 1000 1111. (SMC2) + */ + cp->cp_sigmr = 0; + sirp = (uint *)cp->cp_siram; + + *sirp = 0x018f0000; /* Receive entry */ + sirp += 64; + *sirp = 0x018f0000; /* Tramsmit entry */ + + /* Enable single TDMa routing. + */ + cp->cp_sigmr = 0x04; + + /* Initialize the SMC for transparent operation. + */ + sp = &cpmp->cp_smc[1]; + up = (smc_uart_t *)&cp->cp_dparam[PROFF_SMC2]; + + /* We need to allocate a transmit and receive buffer + * descriptors from dual port ram. + */ + dp_addr = m8xx_cpm_dpalloc(sizeof(cbd_t) * numReadBufs); + + /* Set the physical address of the host memory + * buffers in the buffer descriptors, and the + * virtual address for us to work with. + */ + bdp = (cbd_t *)&cp->cp_dpmem[dp_addr]; + up->smc_rbase = dp_addr; + rx_cur = rx_base = (cbd_t *)bdp; + + for (i=0; i<(numReadBufs-1); i++) { + bdp->cbd_bufaddr = 0; + bdp->cbd_datlen = 0; + bdp->cbd_sc = BD_SC_EMPTY | BD_SC_INTRPT; + bdp++; + } + bdp->cbd_bufaddr = 0; + bdp->cbd_datlen = 0; + bdp->cbd_sc = BD_SC_WRAP | BD_SC_EMPTY | BD_SC_INTRPT; + + /* Now, do the same for the transmit buffers. + */ + dp_addr = m8xx_cpm_dpalloc(sizeof(cbd_t) * numBufs); + + bdp = (cbd_t *)&cp->cp_dpmem[dp_addr]; + up->smc_tbase = dp_addr; + tx_cur = tx_base = (cbd_t *)bdp; + + for (i=0; i<(numBufs-1); i++) { + bdp->cbd_bufaddr = 0; + bdp->cbd_datlen = 0; + bdp->cbd_sc = BD_SC_INTRPT; + bdp++; + } + bdp->cbd_bufaddr = 0; + bdp->cbd_datlen = 0; + bdp->cbd_sc = (BD_SC_WRAP | BD_SC_INTRPT); + + /* Set transparent SMC mode. + * A few things are specific to our application. The codec interface + * is MSB first, hence the REVD selection. The CD/CTS pulse are + * used by the TSA to indicate the frame start to the SMC. + */ + up->smc_rfcr = SCC_EB; + up->smc_tfcr = SCC_EB; + up->smc_mrblr = readbufSize * 1024; + + /* Set 16-bit reversed data, transparent mode. + */ + sp->smc_smcmr = smcr_mk_clen(15) | + SMCMR_SM_TRANS | SMCMR_REVD | SMCMR_BS; + + /* Enable and clear events. + * Because of FIFO delays, all we need is the receive interrupt + * and we can process both the current receive and current + * transmit interrupt within a few microseconds of the transmit. + */ + sp->smc_smce = 0xff; + sp->smc_smcm = SMCM_TXE | SMCM_TX | SMCM_RX; + + /* Send the CPM an initialize command. + */ + cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_SMC2, + CPM_CR_INIT_TRX) | CPM_CR_FLG; + while (cp->cp_cpcr & CPM_CR_FLG); + + sound.mach = mach_cs4218; + has_sound = 1; + + /* Initialize beep stuff */ + orig_mksound = kd_mksound; + kd_mksound = cs_mksound; + beep_buf = (short *) kmalloc(BEEP_BUFLEN * 4, GFP_KERNEL); + if (beep_buf == NULL) + printk(KERN_WARNING "dmasound: no memory for " + "beep buffer\n"); + + if (!has_sound) + return -ENODEV; + + /* Initialize the software SPI. + */ + sw_spi_init(); + + /* Set up sound queue, /dev/audio and /dev/dsp. */ + + /* Set default settings. */ + sq_init(); + + /* Set up /dev/sndstat. */ + state_init(); + + /* Set up /dev/mixer. */ + mixer_init(); + + if (!sound.mach.irqinit()) { + printk(KERN_ERR "DMA sound driver: Interrupt initialization failed\n"); + return -ENODEV; + } +#ifdef MODULE + irq_installed = 1; +#endif + + printk(KERN_INFO "DMA sound driver installed, using %d buffers of %dk.\n", + numBufs, bufSize); + + return 0; +} + +/* Due to FIFOs and bit delays, the transmit interrupt occurs a few + * microseconds ahead of the receive interrupt. + * When we get an interrupt, we service the transmit first, then + * check for a receive to prevent the overhead of returning through + * the interrupt handler only to get back here right away during + * full duplex operation. + */ +static void +cs4218_intr(void *dev_id, struct pt_regs *regs) +{ + volatile smc_t *sp; + volatile cpm8xx_t *cp; + + sp = &cpmp->cp_smc[1]; + + if (sp->smc_smce & SCCM_TX) { + sp->smc_smce = SCCM_TX; + cs4218_tdm_tx_intr((void *)sp); + } + + if (sp->smc_smce & SCCM_RX) { + sp->smc_smce = SCCM_RX; + cs4218_tdm_rx_intr((void *)sp); + } + + if (sp->smc_smce & SCCM_TXE) { + /* Transmit underrun. This happens with the application + * didn't keep up sending buffers. We tell the SMC to + * restart, which will cause it to poll the current (next) + * BD. If the user supplied data since this occurred, + * we just start running again. If they didn't, the SMC + * will poll the descriptor until data is placed there. + */ + sp->smc_smce = SCCM_TXE; + cp = cpmp; /* Get pointer to Communication Processor */ + cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_SMC2, + CPM_CR_RESTART_TX) | CPM_CR_FLG; + while (cp->cp_cpcr & CPM_CR_FLG); + } +} + + +#define MAXARGS 8 /* Should be sufficient for now */ + +void __init dmasound_setup(char *str, int *ints) +{ + /* check the bootstrap parameter for "dmasound=" */ + + switch (ints[0]) { + case 3: + if ((ints[3] < 0) || (ints[3] > MAX_CATCH_RADIUS)) + printk("dmasound_setup: illegal catch radius, using default = %d\n", catchRadius); + else + catchRadius = ints[3]; + /* fall through */ + case 2: + if (ints[1] < MIN_BUFFERS) + printk("dmasound_setup: illegal number of buffers, using default = %d\n", numBufs); + else + numBufs = ints[1]; + if (ints[2] < MIN_BUFSIZE || ints[2] > MAX_BUFSIZE) + printk("dmasound_setup: illegal buffer size, using default = %d\n", bufSize); + else + bufSize = ints[2]; + break; + case 0: + break; + default: + printk("dmasound_setup: illegal number of arguments\n"); + } +} + +/* Software SPI functions. + * These are on Port B. + */ +#define PB_SPICLK ((uint)0x00000002) +#define PB_SPIMOSI ((uint)0x00000004) +#define PB_SPIMISO ((uint)0x00000008) + +static +void sw_spi_init(void) +{ + volatile cpm8xx_t *cp; + volatile uint *hcsr4; + + hcsr4 = (volatile uint *)HIOX_CSR4_ADDR; + cp = cpmp; /* Get pointer to Communication Processor */ + + *hcsr4 &= ~HIOX_CSR4_AUDSPISEL; /* Disable SPI select */ + + /* Make these Port B signals general purpose I/O. + * First, make sure the clock is low. + */ + cp->cp_pbdat &= ~PB_SPICLK; + cp->cp_pbpar &= ~(PB_SPICLK | PB_SPIMOSI | PB_SPIMISO); + + /* Clock and Master Output are outputs. + */ + cp->cp_pbdir |= (PB_SPICLK | PB_SPIMOSI); + + /* Master Input. + */ + cp->cp_pbdir &= ~PB_SPIMISO; + +} + +/* Write the CS4218 control word out the SPI port. While the + * the control word is going out, the status word is arriving. + */ +static +uint cs4218_ctl_write(uint ctlreg) +{ + uint status; + + sw_spi_io((u_char *)&ctlreg, (u_char *)&status, 4); + + /* Shadow the control register.....I guess we could do + * the same for the status, but for now we just return it + * and let the caller decide. + */ + cs4218_control = ctlreg; + return status; +} + +static +void sw_spi_io(u_char *obuf, u_char *ibuf, uint bcnt) +{ + int bits, i; + u_char outbyte, inbyte; + volatile cpm8xx_t *cp; + volatile uint *hcsr4; + + hcsr4 = (volatile uint *)HIOX_CSR4_ADDR; + cp = cpmp; /* Get pointer to Communication Processor */ + + /* The timing on the bus is pretty slow. Code inefficiency + * and eieio() is our friend here :-). + */ + cp->cp_pbdat &= ~PB_SPICLK; + *hcsr4 |= HIOX_CSR4_AUDSPISEL; /* Enable SPI select */ + eieio(); + + /* Clock in/out the bytes. Data is valid on the falling edge + * of the clock. Data is MSB first. + */ + for (i=0; i<bcnt; i++) { + outbyte = *obuf++; + inbyte = 0; + for (bits=0; bits<8; bits++) { + eieio(); + cp->cp_pbdat |= PB_SPICLK; + eieio(); + if (outbyte & 0x80) + cp->cp_pbdat |= PB_SPIMOSI; + else + cp->cp_pbdat &= ~PB_SPIMOSI; + eieio(); + cp->cp_pbdat &= ~PB_SPICLK; + eieio(); + outbyte <<= 1; + inbyte <<= 1; + if (cp->cp_pbdat & PB_SPIMISO) + inbyte |= 1; + } + *ibuf++ = inbyte; + } + + *hcsr4 &= ~HIOX_CSR4_AUDSPISEL; /* Disable SPI select */ + eieio(); +} + +void cleanup_module(void) +{ + if (irq_installed) { + sound_silence(); +#ifdef MODULE + sound.mach.irqcleanup(); +#endif + } + + sq_release_read_buffers(); + sq_release_buffers(); + + if (mixer_unit >= 0) + unregister_sound_mixer(mixer_unit); + if (state_unit >= 0) + unregister_sound_special(state_unit); + if (sq_unit >= 0) + unregister_sound_dsp(sq_unit); +} + +module_init(tdm8xx_sound_init); +module_exit(cleanup_module); + diff --git a/arch/ppc/8xx_io/enet.c b/arch/ppc/8xx_io/enet.c index 8e1e2331a08d..698298ac2156 100644 --- a/arch/ppc/8xx_io/enet.c +++ b/arch/ppc/8xx_io/enet.c @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.enet.c 1.17 10/11/01 11:55:47 trini + * BK Id: %F% %I% %G% %U% %#% */ /* * Ethernet driver for Motorola MPC8xx. @@ -139,6 +139,11 @@ struct scc_enet_private { cbd_t *cur_rx, *cur_tx; /* The next free ring entry */ cbd_t *dirty_tx; /* The ring entries to be free()ed. */ scc_t *sccp; + + /* Virtual addresses for the receive buffers because we can't + * do a __va() on them anymore. + */ + unsigned char *rx_vaddr[RX_RING_SIZE]; struct net_device_stats stats; uint tx_full; spinlock_t lock; @@ -507,7 +512,7 @@ for (;;) { skb->dev = dev; skb_put(skb,pkt_len-4); /* Make room */ eth_copy_and_sum(skb, - (unsigned char *)__va(bdp->cbd_bufaddr), + cep->rx_vaddr[bdp - cep->rx_bd_base], pkt_len-4, 0); skb->protocol=eth_type_trans(skb,dev); netif_rx(skb); @@ -641,10 +646,9 @@ int __init scc_enet_init(void) { struct net_device *dev; struct scc_enet_private *cep; - int i, j; - unsigned char *eap; - unsigned long mem_addr; - pte_t *pte; + int i, j, k; + unsigned char *eap, *ba; + dma_addr_t mem_addr; bd_t *bd; volatile cbd_t *bdp; volatile cpm8xx_t *cp; @@ -834,24 +838,21 @@ int __init scc_enet_init(void) bdp->cbd_sc |= BD_SC_WRAP; bdp = cep->rx_bd_base; + k = 0; for (i=0; i<CPM_ENET_RX_PAGES; i++) { /* Allocate a page. */ - mem_addr = __get_free_page(GFP_KERNEL); - - /* Make it uncached. - */ - pte = va_to_pte(mem_addr); - pte_val(*pte) |= _PAGE_NO_CACHE; - flush_tlb_page(init_mm.mmap, mem_addr); + ba = (unsigned char *)consistent_alloc(GFP_KERNEL, PAGE_SIZE, &mem_addr); /* Initialize the BD for every fragment in the page. */ for (j=0; j<CPM_ENET_RX_FRPPG; j++) { bdp->cbd_sc = BD_ENET_RX_EMPTY | BD_ENET_RX_INTR; - bdp->cbd_bufaddr = __pa(mem_addr); + bdp->cbd_bufaddr = mem_addr; + cep->rx_vaddr[k++] = ba; mem_addr += CPM_ENET_RX_FRSIZE; + ba += CPM_ENET_RX_FRSIZE; bdp++; } } diff --git a/arch/ppc/8xx_io/fec.c b/arch/ppc/8xx_io/fec.c index 736c3657200e..de60dc8f471a 100644 --- a/arch/ppc/8xx_io/fec.c +++ b/arch/ppc/8xx_io/fec.c @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.fec.c 1.20 10/11/01 11:55:47 trini + * BK Id: %F% %I% %G% %U% %#% */ /* * Fast Ethernet Controller (FEC) driver for Motorola MPC8xx. @@ -163,7 +163,12 @@ struct fec_enet_private { cbd_t *tx_bd_base; cbd_t *cur_rx, *cur_tx; /* The next free ring entry */ cbd_t *dirty_tx; /* The ring entries to be free()ed. */ - scc_t *sccp; + + /* Virtual addresses for the receive buffers because we can't + * do a __va() on them anymore. + */ + unsigned char *rx_vaddr[RX_RING_SIZE]; + struct net_device_stats stats; uint tx_full; spinlock_t lock; @@ -688,7 +693,7 @@ while (!(bdp->cbd_sc & BD_ENET_RX_EMPTY)) { fep->stats.rx_packets++; pkt_len = bdp->cbd_datlen; fep->stats.rx_bytes += pkt_len; - data = (__u8*)__va(bdp->cbd_bufaddr); + data = fep->rx_vaddr[bdp - fep->rx_bd_base]; #ifdef CONFIG_FEC_PACKETHOOK /* Packet hook ... */ @@ -724,9 +729,7 @@ while (!(bdp->cbd_sc & BD_ENET_RX_EMPTY)) { } else { skb->dev = dev; skb_put(skb,pkt_len-4); /* Make room */ - eth_copy_and_sum(skb, - (unsigned char *)__va(bdp->cbd_bufaddr), - pkt_len-4, 0); + eth_copy_and_sum(skb, data, pkt_len-4, 0); skb->protocol=eth_type_trans(skb,dev); netif_rx(skb); } @@ -1504,10 +1507,9 @@ int __init fec_enet_init(void) { struct net_device *dev; struct fec_enet_private *fep; - int i, j; - unsigned char *eap, *iap; + int i, j, k; + unsigned char *eap, *iap, *ba; unsigned long mem_addr; - pte_t *pte; volatile cbd_t *bdp; cbd_t *cbd_base; volatile immap_t *immap; @@ -1578,14 +1580,7 @@ int __init fec_enet_init(void) printk("FEC initialization failed.\n"); return 1; } - mem_addr = __get_free_page(GFP_KERNEL); - cbd_base = (cbd_t *)mem_addr; - - /* Make it uncached. - */ - pte = va_to_pte(mem_addr); - pte_val(*pte) |= _PAGE_NO_CACHE; - flush_tlb_page(init_mm.mmap, mem_addr); + cbd_base = (cbd_t *)consistent_alloc(GFP_KERNEL, PAGE_SIZE, &mem_addr); /* Set receive and transmit descriptor base. */ @@ -1597,24 +1592,21 @@ int __init fec_enet_init(void) /* Initialize the receive buffer descriptors. */ bdp = fep->rx_bd_base; + k = 0; for (i=0; i<FEC_ENET_RX_PAGES; i++) { /* Allocate a page. */ - mem_addr = __get_free_page(GFP_KERNEL); - - /* Make it uncached. - */ - pte = va_to_pte(mem_addr); - pte_val(*pte) |= _PAGE_NO_CACHE; - flush_tlb_page(init_mm.mmap, mem_addr); + ba = (unsigned char *)consistent_alloc(GFP_KERNEL, PAGE_SIZE, &mem_addr); /* Initialize the BD for every fragment in the page. */ for (j=0; j<FEC_ENET_RX_FRPPG; j++) { bdp->cbd_sc = BD_ENET_RX_EMPTY; - bdp->cbd_bufaddr = __pa(mem_addr); + bdp->cbd_bufaddr = mem_addr; + fep->rx_vaddr[k++] = ba; mem_addr += FEC_ENET_RX_FRSIZE; + ba += FEC_ENET_RX_FRSIZE; bdp++; } } @@ -1776,8 +1768,8 @@ fec_restart(struct net_device *dev, int duplex) /* Set receive and transmit descriptor base. */ - fecp->fec_r_des_start = __pa((uint)(fep->rx_bd_base)); - fecp->fec_x_des_start = __pa((uint)(fep->tx_bd_base)); + fecp->fec_r_des_start = iopa((uint)(fep->rx_bd_base)); + fecp->fec_x_des_start = iopa((uint)(fep->tx_bd_base)); fep->dirty_tx = fep->cur_tx = fep->tx_bd_base; fep->cur_rx = fep->rx_bd_base; diff --git a/arch/ppc/8xx_io/uart.c b/arch/ppc/8xx_io/uart.c index 71207e3b654a..281fea1c8146 100644 --- a/arch/ppc/8xx_io/uart.c +++ b/arch/ppc/8xx_io/uart.c @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.uart.c 1.19 10/26/01 09:59:32 trini + * BK Id: %F% %I% %G% %U% %#% */ /* * UART driver for MPC860 CPM SCC or SMC @@ -49,9 +49,7 @@ #endif #ifdef CONFIG_KGDB -extern void breakpoint(void); -extern void set_debug_traps(void); -extern int kgdb_output_string (const char* s, unsigned int count); +#include <asm/kgdb.h> #endif #ifdef CONFIG_SERIAL_CONSOLE @@ -135,6 +133,16 @@ static unsigned long break_pressed; /* break, really ... */ #define NUM_IS_SCC ((int)0x00010000) #define PORT_NUM(P) ((P) & 0x0000ffff) +/* The choice of serial port to use for KGDB. If the system has + * two ports, you can use one for console and one for KGDB (which + * doesn't make sense to me, but people asked for it). + */ +#ifdef CONFIG_KGDB_TTYS1 +#define KGDB_SER_IDX 1 /* SCC2/SMC2 */ +#else +#define KGDB_SER_IDX 0 /* SCC1/SMC1 */ +#endif + /* Processors other than the 860 only get SMCs configured by default. * Either they don't have SCCs or they are allocated somewhere else. * Of course, there are now 860s without some SCCs, so we will need to @@ -211,6 +219,12 @@ typedef struct serial_info { cbd_t *rx_cur; cbd_t *tx_bd_base; cbd_t *tx_cur; + + /* Virtual addresses for the FIFOs because we can't __va() a + * physical address anymore. + */ + unsigned char *rx_va_base; + unsigned char *tx_va_base; } ser_info_t; static struct console sercons = { @@ -387,8 +401,15 @@ static _INLINE_ void receive_chars(ser_info_t *info, struct pt_regs *regs) /* Get the number of characters and the buffer pointer. */ i = bdp->cbd_datlen; - cp = (unsigned char *)__va(bdp->cbd_bufaddr); + cp = info->rx_va_base + ((bdp - info->rx_bd_base) * RX_BUF_SIZE); status = bdp->cbd_sc; +#ifdef CONFIG_KGDB + if (info->state->smc_scc_num == KGDB_SER_IDX) { + if (*cp == 0x03 || *cp == '$') + breakpoint(); + return; + } +#endif /* Check to see if there is room in the tty buffer for * the characters in our BD buffer. If not, we exit @@ -1027,6 +1048,7 @@ static void rs_8xx_put_char(struct tty_struct *tty, unsigned char ch) { ser_info_t *info = (ser_info_t *)tty->driver_data; volatile cbd_t *bdp; + unsigned char *cp; if (serial_paranoia_check(info, tty->device, "rs_put_char")) return; @@ -1037,7 +1059,8 @@ static void rs_8xx_put_char(struct tty_struct *tty, unsigned char ch) bdp = info->tx_cur; while (bdp->cbd_sc & BD_SC_READY); - *((char *)__va(bdp->cbd_bufaddr)) = ch; + cp = info->tx_va_base + ((bdp - info->tx_bd_base) * TX_BUF_SIZE); + *cp = ch; bdp->cbd_datlen = 1; bdp->cbd_sc |= BD_SC_READY; @@ -1058,6 +1081,7 @@ static int rs_8xx_write(struct tty_struct * tty, int from_user, int c, ret = 0; ser_info_t *info = (ser_info_t *)tty->driver_data; volatile cbd_t *bdp; + unsigned char *cp; #ifdef CONFIG_KGDB /* Try to let stub handle output. Returns true if it did. */ @@ -1084,14 +1108,15 @@ static int rs_8xx_write(struct tty_struct * tty, int from_user, break; } + cp = info->tx_va_base + ((bdp - info->tx_bd_base) * TX_BUF_SIZE); if (from_user) { - if (copy_from_user(__va(bdp->cbd_bufaddr), buf, c)) { + if (copy_from_user((void *)cp, buf, c)) { if (!ret) ret = -EFAULT; break; } } else { - memcpy(__va(bdp->cbd_bufaddr), buf, c); + memcpy((void *)cp, buf, c); } bdp->cbd_datlen = c; @@ -1166,6 +1191,7 @@ static void rs_8xx_flush_buffer(struct tty_struct *tty) static void rs_8xx_send_xchar(struct tty_struct *tty, char ch) { volatile cbd_t *bdp; + unsigned char *cp; ser_info_t *info = (ser_info_t *)tty->driver_data; @@ -1175,7 +1201,8 @@ static void rs_8xx_send_xchar(struct tty_struct *tty, char ch) bdp = info->tx_cur; while (bdp->cbd_sc & BD_SC_READY); - *((char *)__va(bdp->cbd_bufaddr)) = ch; + cp = info->tx_va_base + ((bdp - info->tx_bd_base) * TX_BUF_SIZE); + *cp = ch; bdp->cbd_datlen = 1; bdp->cbd_sc |= BD_SC_READY; @@ -1800,7 +1827,7 @@ static void rs_8xx_wait_until_sent(struct tty_struct *tty, int timeout) schedule_timeout(char_time); if (signal_pending(current)) break; - if (timeout && ((orig_jiffies + timeout) < jiffies)) + if (timeout && time_after(jiffies, orig_jiffies + timeout)) break; /* The 'tx_cur' is really the next buffer to send. We @@ -2202,6 +2229,11 @@ static _INLINE_ void show_serial_version(void) #ifdef CONFIG_SERIAL_CONSOLE +/* I need this just so I can store the virtual addresses and have + * common functions for the early console printing. + */ +static ser_info_t consinfo; + /* * Print a string to the serial port trying not to disturb any possible * real use of the port... @@ -2234,6 +2266,8 @@ static void my_console_write(int idx, const char *s, /* Get the address of the host memory buffer. */ bdp = bdbase = (cbd_t *)&cpmp->cp_dpmem[up->smc_tbase]; + + info = &consinfo; } /* @@ -2261,7 +2295,7 @@ static void my_console_write(int idx, const char *s, if ((uint)(bdp->cbd_bufaddr) > (uint)IMAP_ADDR) cp = (u_char *)(bdp->cbd_bufaddr); else - cp = __va(bdp->cbd_bufaddr); + cp = info->tx_va_base + ((bdp - info->tx_bd_base) * TX_BUF_SIZE); *cp = *s; bdp->cbd_datlen = 1; @@ -2275,7 +2309,7 @@ static void my_console_write(int idx, const char *s, /* if a LF, also do CR... */ if (*s == 10) { while (bdp->cbd_sc & BD_SC_READY); - cp = __va(bdp->cbd_bufaddr); + cp = info->tx_va_base + ((bdp - info->tx_bd_base) * TX_BUF_SIZE); *cp = 13; bdp->cbd_datlen = 1; bdp->cbd_sc |= BD_SC_READY; @@ -2350,10 +2384,13 @@ static int my_console_wait_key(int idx, int xmon, char *obuf) * If the port has been initialized for general use, we must * use information from the port structure. */ - if ((info = (ser_info_t *)ser->info)) + if ((info = (ser_info_t *)ser->info)) { bdp = info->rx_cur; - else + } + else { bdp = (cbd_t *)&cpmp->cp_dpmem[up->smc_rbase]; + info = &consinfo; + } /* * We need to gracefully shut down the receiver, disable @@ -2375,7 +2412,7 @@ static int my_console_wait_key(int idx, int xmon, char *obuf) if ((uint)(bdp->cbd_bufaddr) > (uint)IMAP_ADDR) cp = (u_char *)(bdp->cbd_bufaddr); else - cp = __va(bdp->cbd_bufaddr); + cp = info->rx_va_base + ((bdp - info->rx_bd_base) * RX_BUF_SIZE); if (obuf) { i = c = bdp->cbd_datlen; @@ -2418,7 +2455,7 @@ xmon_8xx_read_char(void) static char kgdb_buf[RX_BUF_SIZE], *kgdp; static int kgdb_chars; -unsigned char +char getDebugChar(void) { if (kgdb_chars <= 0) { @@ -2430,9 +2467,18 @@ getDebugChar(void) return(*kgdp++); } -void kgdb_interruptible(int state) +void kgdb_interruptible(int yes) { + volatile smc_t *smcp; + + smcp = &cpmp->cp_smc[KGDB_SER_IDX]; + + if (yes == 1) + smcp->smc_smcm |= SMCM_RX; + else + smcp->smc_smcm &= ~SMCM_RX; } + void kgdb_map_scc(void) { struct serial_state *ser; @@ -2459,7 +2505,7 @@ void kgdb_map_scc(void) /* Allocate space for an input FIFO, plus a few bytes for output. * Allocate bytes to maintain word alignment. */ - mem_addr = (uint)(&cpmp->cp_dpmem[0x1000]); + mem_addr = (uint)(&cpmp->cp_dpmem[0xa00]); /* Set the physical address of the host memory buffers in * the buffer descriptors. @@ -2522,7 +2568,11 @@ int __init rs_8xx_init(void) __clear_user(&serial_driver,sizeof(struct tty_driver)); serial_driver.magic = TTY_DRIVER_MAGIC; serial_driver.driver_name = "serial"; +#ifdef CONFIG_DEVFS_FS + serial_driver.name = "tts/%d"; +#else serial_driver.name = "ttyS"; +#endif serial_driver.major = TTY_MAJOR; serial_driver.minor_start = 64; serial_driver.num = NR_PORTS; @@ -2560,7 +2610,11 @@ int __init rs_8xx_init(void) * major number and the subtype code. */ callout_driver = serial_driver; +#ifdef CONFIG_DEVFS_FS + callout_driver.name = "cua/%d"; +#else callout_driver.name = "cua"; +#endif callout_driver.major = TTYAUX_MAJOR; callout_driver.subtype = SERIAL_TYPE_CALLOUT; callout_driver.read_proc = 0; @@ -2672,6 +2726,7 @@ int __init rs_8xx_init(void) /* Allocate space for FIFOs in the host memory. */ mem_addr = m8xx_cpm_hostalloc(RX_NUM_FIFO * RX_BUF_SIZE); + info->rx_va_base = (unsigned char *)mem_addr; /* Set the physical address of the host memory * buffers in the buffer descriptors, and the @@ -2681,12 +2736,12 @@ int __init rs_8xx_init(void) info->rx_cur = info->rx_bd_base = (cbd_t *)bdp; for (j=0; j<(RX_NUM_FIFO-1); j++) { - bdp->cbd_bufaddr = __pa(mem_addr); + bdp->cbd_bufaddr = iopa(mem_addr); bdp->cbd_sc = BD_SC_EMPTY | BD_SC_INTRPT; mem_addr += RX_BUF_SIZE; bdp++; } - bdp->cbd_bufaddr = __pa(mem_addr); + bdp->cbd_bufaddr = iopa(mem_addr); bdp->cbd_sc = BD_SC_WRAP | BD_SC_EMPTY | BD_SC_INTRPT; idx = PORT_NUM(info->state->smc_scc_num); @@ -2706,6 +2761,7 @@ int __init rs_8xx_init(void) /* Allocate space for FIFOs in the host memory. */ mem_addr = m8xx_cpm_hostalloc(TX_NUM_FIFO * TX_BUF_SIZE); + info->tx_va_base = (unsigned char *)mem_addr; /* Set the physical address of the host memory * buffers in the buffer descriptors, and the @@ -2715,12 +2771,12 @@ int __init rs_8xx_init(void) info->tx_cur = info->tx_bd_base = (cbd_t *)bdp; for (j=0; j<(TX_NUM_FIFO-1); j++) { - bdp->cbd_bufaddr = __pa(mem_addr); + bdp->cbd_bufaddr = iopa(mem_addr); bdp->cbd_sc = BD_SC_INTRPT; mem_addr += TX_BUF_SIZE; bdp++; } - bdp->cbd_bufaddr = __pa(mem_addr); + bdp->cbd_bufaddr = iopa(mem_addr); bdp->cbd_sc = (BD_SC_WRAP | BD_SC_INTRPT); if (info->state->smc_scc_num & NUM_IS_SCC) { @@ -2926,20 +2982,28 @@ static int __init serial_console_setup(struct console *co, char *options) * from dual port ram, and a character buffer area from host mem. */ + /* Allocate space for two FIFOs. We can't allocate from host + * memory yet because vm allocator isn't initialized + * during this early console init. + */ + dp_addr = m8xx_cpm_dpalloc(8); + mem_addr = (uint)(&cpmp->cp_dpmem[dp_addr]); + /* Allocate space for two buffer descriptors in the DP ram. */ dp_addr = m8xx_cpm_dpalloc(sizeof(cbd_t) * 2); - /* Allocate space for two 2 byte FIFOs in the host memory. - */ - mem_addr = m8xx_cpm_hostalloc(8); - /* Set the physical address of the host memory buffers in * the buffer descriptors. */ bdp = (cbd_t *)&cp->cp_dpmem[dp_addr]; - bdp->cbd_bufaddr = __pa(mem_addr); - (bdp+1)->cbd_bufaddr = __pa(mem_addr+4); + bdp->cbd_bufaddr = iopa(mem_addr); + (bdp+1)->cbd_bufaddr = iopa(mem_addr+4); + + consinfo.rx_va_base = mem_addr; + consinfo.rx_bd_base = bdp; + consinfo.tx_va_base = mem_addr + 4; + consinfo.tx_bd_base = bdp+1; /* For the receive, set empty and wrap. * For transmit, set wrap. @@ -3044,3 +3108,18 @@ static int __init serial_console_setup(struct console *co, char *options) return 0; } +#ifdef CONFIG_INPUT_KEYBDEV + +void handle_scancode(unsigned char scancode, int down) +{ + printk("handle_scancode(scancode=0x%x, down=%d)\n", scancode, down); +} + +static void kbd_bh(unsigned long dummy) +{ +} + +DECLARE_TASKLET_DISABLED(keyboard_tasklet, kbd_bh, 0); +void (*kbd_ledfunc)(unsigned int led); + +#endif diff --git a/arch/ppc/Config.help b/arch/ppc/Config.help index 5786797a89b2..3c4c23c663d5 100644 --- a/arch/ppc/Config.help +++ b/arch/ppc/Config.help @@ -1086,3 +1086,45 @@ CONFIG_XMON Include in-kernel hooks for the xmon kernel monitor/debugger supported by the PPC port. +CONFIG_ADVANCED_OPTIONS + This option will enable prompting for a variety of advanced kernel + configuration options. These options can cause the kernel to not + work if they are set incorrectly, but can be used to optimize certain + aspects of kernel memory management. + + Unless you know what you are doing you *should not* enable this option. + +CONFIG_HIGHMEM_START_BOOL + Unless you know what you are doing you *should not* set this option. + + It can be used to override the default PKMAP_BASE address which + is the location of the high memory pool. This can be useful in + optimizing virtual memory usage in a system. + +CONFIG_LOWMEM_SIZE_BOOL + Unless you know what you are doing you *should not* set this option. + + It can be used to override the standard calculated value of + MAX_LOW_MEM. This can be useful in optimizing virtual memory usage + in a system. + +CONFIG_KERNEL_START_BOOL + Unless you know what you are doing you *should not* set this option. + + It can be used to override the standard PAGE_OFFSET/KERNELBASE + value used by the kernel. This can be useful in controlling + amount of virtual address space available to the kernel. + +CONFIG_TASK_SIZE_BOOL + Unless you know what you are doing you *should not* set this option. + + It can be used to override the standard TASK_SIZE value used + by the kernel. This can be useful in controlling amount of + virtual address space available to user tasks. + +CONFIG_BOOT_LOAD_BOOL + Unless you know what you are doing you *should not* set this option. + + It can be used to change the initial load address of the zImage or + zImage.initrd file. This can be useful if you are on a board which has + a small ammount of memory. diff --git a/arch/ppc/Makefile b/arch/ppc/Makefile index b1e268176423..3fbf5d015cab 100644 --- a/arch/ppc/Makefile +++ b/arch/ppc/Makefile @@ -1,4 +1,4 @@ -# BK Id: SCCS/s.Makefile 1.23 09/18/01 11:19:05 paulus +# BK Id: %F% %I% %G% %U% %#% # # This file is included by the global makefile so that you can add your own # architecture-specific flags and dependencies. Remember to do have actions @@ -15,45 +15,55 @@ # # Be sure to change PAGE_OFFSET in include/asm-ppc/page.h to match +ifdef CONFIG_KERNEL_START_BOOL +KERNELLOAD =$(CONFIG_KERNEL_START) +else KERNELLOAD =0xc0000000 +endif ifeq ($(shell uname -m),ppc) CHECKS = checks endif -ASFLAGS = LINKFLAGS = -T arch/ppc/vmlinux.lds -Ttext $(KERNELLOAD) -Bstatic -CPPFLAGS := $(CPPFLAGS) -D__powerpc__ -CFLAGS := $(CFLAGS) -D__powerpc__ -fsigned-char \ +CPPFLAGS := $(CPPFLAGS) -I$(TOPDIR)/arch/$(ARCH) +AFLAGS := $(AFLAGS) -I$(TOPDIR)/arch/$(ARCH) +CFLAGS := $(CFLAGS) -I$(TOPDIR)/arch/$(ARCH) -fsigned-char \ -msoft-float -pipe -ffixed-r2 -Wno-uninitialized \ -mmultiple -mstring CPP = $(CC) -E $(CFLAGS) ifdef CONFIG_4xx -CFLAGS := $(CFLAGS) -mcpu=403 -endif - -ifdef CONFIG_8xx -CFLAGS := $(CFLAGS) -mcpu=860 +CFLAGS := $(CFLAGS) -Wa,-m405 endif ifdef CONFIG_PPC64BRIDGE CFLAGS := $(CFLAGS) -Wa,-mppc64bridge endif +ifdef CONFIG_MORE_COMPILE_OPTIONS +# Use sed to remove the quotes. + CFLAGS += $(shell echo $(CONFIG_COMPILE_OPTIONS) | sed -e 's/"//g') +endif + ifdef CONFIG_4xx HEAD := arch/ppc/kernel/head_4xx.o else ifdef CONFIG_8xx HEAD := arch/ppc/kernel/head_8xx.o else - HEAD := arch/ppc/kernel/head.o + ifdef CONFIG_PPC_ISERIES + HEAD := arch/ppc/kernel/iSeries_head.o + else + HEAD := arch/ppc/kernel/head.o + endif endif endif -ARCH_SUBDIRS = arch/ppc/kernel arch/ppc/mm arch/ppc/lib +ARCH_SUBDIRS = arch/ppc/kernel arch/ppc/platforms arch/ppc/mm arch/ppc/lib SUBDIRS := $(SUBDIRS) $(ARCH_SUBDIRS) -CORE_FILES := arch/ppc/kernel/kernel.o arch/ppc/mm/mm.o arch/ppc/lib/lib.o $(CORE_FILES) +CORE_FILES := arch/ppc/kernel/kernel.o arch/ppc/platforms/platform.o \ + arch/ppc/mm/mm.o arch/ppc/lib/lib.o $(CORE_FILES) ifdef CONFIG_MATH_EMULATION SUBDIRS += arch/ppc/math-emu @@ -77,15 +87,25 @@ SUBDIRS += arch/ppc/8260_io DRIVERS += arch/ppc/8260_io/8260_io.o endif +ifdef CONFIG_4xx +SUBDIRS += arch/ppc/4xx_io +DRIVERS += arch/ppc/4xx_io/4xx_io.o +endif + ifdef CONFIG_APUS SUBDIRS += arch/ppc/amiga CORE_FILES += arch/ppc/amiga/amiga.o endif +ifdef CONFIG_PPC_ISERIES +SUBDIRS += arch/ppc/iSeries +CORE_FILES += arch/ppc/iSeries/iSeries.o +endif + checks: @$(MAKE) -C arch/$(ARCH)/kernel checks -BOOT_TARGETS = zImage zImage.initrd znetboot znetboot.initrd +BOOT_TARGETS = zImage zImage.initrd znetboot znetboot.initrd pImage vmlinux.sm # All the instructions talk about "make bzImage". bzImage: zImage @@ -99,6 +119,7 @@ $(BOOT_TARGETS): $(CHECKS) vmlinux archclean: rm -f arch/ppc/kernel/{mk_defs,ppc_defs.h,find_name,checks} + rm -f arch/ppc/iSeries/ReleaseData.h @$(MAKEBOOT) clean archmrproper: diff --git a/arch/ppc/amiga/amiints.c b/arch/ppc/amiga/amiints.c index dd6ea8bac54e..9458dea47249 100644 --- a/arch/ppc/amiga/amiints.c +++ b/arch/ppc/amiga/amiints.c @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.amiints.c 1.8 05/21/01 00:48:24 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * linux/arch/m68k/amiga/amiints.c -- Amiga Linux interrupt handling code @@ -42,9 +42,10 @@ #include <linux/types.h> #include <linux/kernel.h> #include <linux/sched.h> +#include <linux/interrupt.h> +#include <linux/irq.h> #include <linux/kernel_stat.h> #include <linux/init.h> -#include <linux/seq_file.h> #include <asm/system.h> #include <asm/irq.h> @@ -62,10 +63,6 @@ extern int cia_request_irq(int irq, unsigned long flags, const char *devname, void *dev_id); extern void cia_free_irq(unsigned int irq, void *dev_id); extern void cia_init_IRQ(struct ciabase *base); -extern int cia_get_irq_list(struct ciabase *base, struct seq_file *p); - -/* irq node variables for amiga interrupt sources */ -static irq_node_t *ami_irq_list[AMI_STD_IRQS]; unsigned short ami_intena_vals[AMI_STD_IRQS] = { IF_VERTB, IF_COPER, IF_AUD0, IF_AUD1, IF_AUD2, IF_AUD3, IF_BLIT, @@ -79,7 +76,7 @@ static short ami_ablecount[AMI_IRQS]; static void ami_badint(int irq, void *dev_id, struct pt_regs *fp) { - num_spurious += 1; +/* num_spurious += 1;*/ } /* @@ -98,25 +95,12 @@ void amiga_init_IRQ(void) { int i; - /* initialize handlers */ - for (i = 0; i < AMI_STD_IRQS; i++) { - if (ami_servers[i]) { - ami_irq_list[i] = NULL; - } else { - ami_irq_list[i] = new_irq_node(); - ami_irq_list[i]->handler = ami_badint; - ami_irq_list[i]->flags = 0; - ami_irq_list[i]->dev_id = NULL; - ami_irq_list[i]->devname = NULL; - ami_irq_list[i]->next = NULL; - } - } for (i = 0; i < AMI_IRQS; i++) ami_ablecount[i] = 0; /* turn off PCMCIA interrupts */ if (AMIGAHW_PRESENT(PCMCIA)) - pcmcia_disable_irq(); + gayle.inten = GAYLE_IRQ_IDE; /* turn off all interrupts... */ custom.intena = 0x7fff; @@ -139,152 +123,6 @@ void amiga_init_IRQ(void) cia_init_IRQ(&ciab_base); } -static inline int amiga_insert_irq(irq_node_t **list, irq_node_t *node) -{ - unsigned long flags; - irq_node_t *cur; - - if (!node->dev_id) - printk("%s: Warning: dev_id of %s is zero\n", - __FUNCTION__, node->devname); - - save_flags(flags); - cli(); - - cur = *list; - - if (node->flags & SA_INTERRUPT) { - if (node->flags & SA_SHIRQ) - return -EBUSY; - /* - * There should never be more than one - */ - while (cur && cur->flags & SA_INTERRUPT) { - list = &cur->next; - cur = cur->next; - } - } else { - while (cur) { - list = &cur->next; - cur = cur->next; - } - } - - node->next = cur; - *list = node; - - restore_flags(flags); - return 0; -} - -static inline void amiga_delete_irq(irq_node_t **list, void *dev_id) -{ - unsigned long flags; - irq_node_t *node; - - save_flags(flags); - cli(); - - for (node = *list; node; list = &node->next, node = *list) { - if (node->dev_id == dev_id) { - *list = node->next; - /* Mark it as free. */ - node->handler = NULL; - restore_flags(flags); - return; - } - } - restore_flags(flags); - printk ("%s: tried to remove invalid irq\n", __FUNCTION__); -} - -/* - * amiga_request_irq : add an interrupt service routine for a particular - * machine specific interrupt source. - * If the addition was successful, it returns 0. - */ - -int amiga_request_irq(unsigned int irq, - void (*handler)(int, void *, struct pt_regs *), - unsigned long flags, const char *devname, void *dev_id) -{ - irq_node_t *node; - int error = 0; - - if (irq >= AMI_IRQS) { - printk ("%s: Unknown IRQ %d from %s\n", __FUNCTION__, - irq, devname); - return -ENXIO; - } - - if (irq >= IRQ_AMIGA_AUTO) - return sys_request_irq(irq - IRQ_AMIGA_AUTO, handler, - flags, devname, dev_id); - - if (irq >= IRQ_AMIGA_CIAA) - return cia_request_irq(irq, handler, flags, devname, dev_id); - - /* - * IRQ_AMIGA_PORTS & IRQ_AMIGA_EXTER defaults to shared, - * we could add a check here for the SA_SHIRQ flag but all drivers - * should be aware of sharing anyway. - */ - if (ami_servers[irq]) { - if (!(node = new_irq_node())) - return -ENOMEM; - node->handler = handler; - node->flags = flags; - node->dev_id = dev_id; - node->devname = devname; - node->next = NULL; - error = amiga_insert_irq(&ami_irq_list[irq], node); - } else { - ami_irq_list[irq]->handler = handler; - ami_irq_list[irq]->flags = flags; - ami_irq_list[irq]->dev_id = dev_id; - ami_irq_list[irq]->devname = devname; - } - - /* enable the interrupt */ - if (irq < IRQ_AMIGA_PORTS && !ami_ablecount[irq]) - custom.intena = IF_SETCLR | ami_intena_vals[irq]; - - return error; -} - -void amiga_free_irq(unsigned int irq, void *dev_id) -{ - if (irq >= AMI_IRQS) { - printk ("%s: Unknown IRQ %d\n", __FUNCTION__, irq); - return; - } - - if (irq >= IRQ_AMIGA_AUTO) { - sys_free_irq(irq - IRQ_AMIGA_AUTO, dev_id); - return; - } - if (irq >= IRQ_AMIGA_CIAA) { - cia_free_irq(irq, dev_id); - return; - } - - if (ami_servers[irq]) { - amiga_delete_irq(&ami_irq_list[irq], dev_id); - /* if server list empty, disable the interrupt */ - if (!ami_irq_list[irq] && irq < IRQ_AMIGA_PORTS) - custom.intena = ami_intena_vals[irq]; - } else { - if (ami_irq_list[irq]->dev_id != dev_id) - printk("%s: removing probably wrong IRQ %d from %s\n", - __FUNCTION__, irq, ami_irq_list[irq]->devname); - ami_irq_list[irq]->handler = ami_badint; - ami_irq_list[irq]->flags = 0; - ami_irq_list[irq]->dev_id = NULL; - ami_irq_list[irq]->devname = NULL; - custom.intena = ami_intena_vals[irq]; - } -} - /* * Enable/disable a particular machine specific interrupt source. * Note that this may affect other interrupts in case of a shared interrupt. @@ -351,20 +189,24 @@ void amiga_disable_irq(unsigned int irq) inline void amiga_do_irq(int irq, struct pt_regs *fp) { - kstat.irqs[0][SYS_IRQS + irq]++; - ami_irq_list[irq]->handler(irq, ami_irq_list[irq]->dev_id, fp); + irq_desc_t *desc = irq_desc + irq; + struct irqaction *action = desc->action; + + kstat.irqs[0][irq]++; + action->handler(irq, action->dev_id, fp); } void amiga_do_irq_list(int irq, struct pt_regs *fp) { - irq_node_t *node; + irq_desc_t *desc = irq_desc + irq; + struct irqaction *action; - kstat.irqs[0][SYS_IRQS + irq]++; + kstat.irqs[0][irq]++; custom.intreq = ami_intena_vals[irq]; - for (node = ami_irq_list[irq]; node; node = node->next) - node->handler(irq, node->dev_id, fp); + for (action = desc->action; action; action = action->next) + action->handler(irq, action->dev_id, fp); } /* @@ -470,9 +312,15 @@ static void ami_int7(int irq, void *dev_id, struct pt_regs *fp) /* The PPC irq handling links all handlers requested on the same vector and executes them in a loop. Having ami_badint at the end of the chain is a bad idea. */ -void (*amiga_default_handler[SYS_IRQS])(int, void *, struct pt_regs *) = { - NULL, ami_int1, NULL, ami_int3, - ami_int4, ami_int5, NULL, ami_int7 +struct irqaction amiga_sys_irqaction[AUTO_IRQS] = { + { handler: ami_badint, name: "spurious int" }, + { handler: ami_int1, name: "int1 handler" }, + { 0, /* CIAA */ }, + { handler: ami_int3, name: "int3 handler" }, + { handler: ami_int4, name: "int4 handler" }, + { handler: ami_int5, name: "int5 handler" }, + { 0, /* CIAB */ }, + { handler: ami_int7, name: "int7 handler" }, }; #else void (*amiga_default_handler[SYS_IRQS])(int, void *, struct pt_regs *) = { @@ -480,29 +328,3 @@ void (*amiga_default_handler[SYS_IRQS])(int, void *, struct pt_regs *) = { ami_int4, ami_int5, ami_badint, ami_int7 }; #endif - -int show_amiga_intreeupts(struct seq_file *p, void *v) -{ - int i; - irq_node_t *node; - - for (i = 0; i < AMI_STD_IRQS; i++) { - if (!(node = ami_irq_list[i])) - continue; - seq_printf(p, "ami %2d: %10u ", i, - kstat.irqs[0][SYS_IRQS + i]); - do { - if (node->flags & SA_INTERRUPT) - seq_puts(p, "F "); - else - seq_puts(p, " "); - seq_printf(p, "%s\n", node->devname); - if ((node = node->next)) - seq_puts(p, " "); - } while (node); - } - - cia_get_irq_list(&ciaa_base, p); - cia_get_irq_list(&ciab_base, p); - return len; -} diff --git a/arch/ppc/amiga/cia.c b/arch/ppc/amiga/cia.c index 21f03c0a54a3..21c222c70bf2 100644 --- a/arch/ppc/amiga/cia.c +++ b/arch/ppc/amiga/cia.c @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.cia.c 1.7 05/21/01 00:48:24 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * linux/arch/m68k/amiga/cia.c - CIA support @@ -16,10 +16,10 @@ #include <linux/types.h> #include <linux/kernel.h> #include <linux/sched.h> -#include <linux/errno.h> +#include <linux/interrupt.h> +#include <linux/irq.h> #include <linux/kernel_stat.h> #include <linux/init.h> -#include <linux/seq_file.h> #include <asm/irq.h> #include <asm/amigahw.h> @@ -31,7 +31,6 @@ struct ciabase { u_short int_mask; int handler_irq, cia_irq, server_irq; char *name; - irq_handler_t irq_list[CIA_IRQS]; } ciaa_base = { &ciaa, 0, 0, IF_PORTS, IRQ_AMIGA_AUTO_2, IRQ_AMIGA_CIAA, @@ -100,15 +99,13 @@ unsigned char cia_get_irq_mask(unsigned int irq) } /* - * Enable or disable CIA interrupts, return old interrupt mask, - * interrupts will only be enabled if a handler exists + * Enable or disable CIA interrupts, return old interrupt mask. */ static unsigned char cia_able_irq_private(struct ciabase *base, unsigned char mask) { - u_char old, tmp; - int i; + u_char old; old = base->icr_mask; base->icr_data |= base->cia->icr; @@ -118,12 +115,7 @@ static unsigned char cia_able_irq_private(struct ciabase *base, else base->icr_mask &= ~mask; base->icr_mask &= CIA_ICR_ALL; - for (i = 0, tmp = 1; i < CIA_IRQS; i++, tmp <<= 1) { - if ((tmp & base->icr_mask) && !base->irq_list[i].handler) { - base->icr_mask &= ~tmp; - base->cia->icr = tmp; - } - } + if (base->icr_data & base->icr_mask) custom.intreq = IF_SETCLR | base->int_mask; return old; @@ -145,94 +137,45 @@ unsigned char cia_able_irq(unsigned int irq, int enable) return cia_able_irq_private(base, mask); } -int cia_request_irq(unsigned int irq, - void (*handler)(int, void *, struct pt_regs *), - unsigned long flags, const char *devname, void *dev_id) -{ - u_char mask; - struct ciabase *base; - - CIA_SET_BASE_ADJUST_IRQ(base, irq); - - base->irq_list[irq].handler = handler; - base->irq_list[irq].flags = flags; - base->irq_list[irq].dev_id = dev_id; - base->irq_list[irq].devname = devname; - - /* enable the interrupt */ - mask = 1 << irq; - cia_set_irq_private(base, mask); - cia_able_irq_private(base, CIA_ICR_SETCLR | mask); - return 0; -} - -void cia_free_irq(unsigned int irq, void *dev_id) -{ - struct ciabase *base; - - CIA_SET_BASE_ADJUST_IRQ(base, irq); - - if (base->irq_list[irq].dev_id != dev_id) - printk("%s: removing probably wrong IRQ %i from %s\n", - __FUNCTION__, base->cia_irq + irq, - base->irq_list[irq].devname); - - base->irq_list[irq].handler = NULL; - base->irq_list[irq].flags = 0; - - cia_able_irq_private(base, 1 << irq); -} - static void cia_handler(int irq, void *dev_id, struct pt_regs *fp) { struct ciabase *base = (struct ciabase *)dev_id; - int mach_irq, i; + irq_desc_t *desc; + struct irqaction *action; + int i; unsigned char ints; - mach_irq = base->cia_irq; - irq = SYS_IRQS + mach_irq; + irq = base->cia_irq; + desc = irq_desc + irq; ints = cia_set_irq_private(base, CIA_ICR_ALL); custom.intreq = base->int_mask; - for (i = 0; i < CIA_IRQS; i++, irq++, mach_irq++) { + for (i = 0; i < CIA_IRQS; i++, irq++) { if (ints & 1) { kstat.irqs[0][irq]++; - base->irq_list[i].handler(mach_irq, base->irq_list[i].dev_id, fp); + action = desc->action; + action->handler(irq, action->dev_id, fp); } ints >>= 1; + desc++; } amiga_do_irq_list(base->server_irq, fp); } void __init cia_init_IRQ(struct ciabase *base) { - int i; - - /* init isr handlers */ - for (i = 0; i < CIA_IRQS; i++) { - base->irq_list[i].handler = NULL; - base->irq_list[i].flags = 0; - } + extern struct irqaction amiga_sys_irqaction[AUTO_IRQS]; + struct irqaction *action; /* clear any pending interrupt and turn off all interrupts */ cia_set_irq_private(base, CIA_ICR_ALL); cia_able_irq_private(base, CIA_ICR_ALL); /* install CIA handler */ - request_irq(base->handler_irq, cia_handler, 0, base->name, base); + action = &amiga_sys_irqaction[base->handler_irq-IRQ_AMIGA_AUTO]; + action->handler = cia_handler; + action->dev_id = base; + action->name = base->name; + setup_irq(base->handler_irq, &amiga_sys_irqaction[base->handler_irq-IRQ_AMIGA_AUTO]); custom.intena = IF_SETCLR | base->int_mask; } - -int cia_get_irq_list(struct ciabase *base, struct seq_file *p) -{ - int i, j; - - j = base->cia_irq; - for (i = 0; i < CIA_IRQS; i++) { - seq_printf(p, "cia %2d: %10d ", j + i, - kstat.irqs[0][SYS_IRQS + j + i]); - seq_puts(p, " "); - seq_printf(p, "%s\n", base->irq_list[i].devname); - } - return 0; -} diff --git a/arch/ppc/amiga/config.c b/arch/ppc/amiga/config.c index 90b4f2e49c95..310aa0b907b4 100644 --- a/arch/ppc/amiga/config.c +++ b/arch/ppc/amiga/config.c @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.config.c 1.12 09/18/01 11:19:06 paulus + * BK Id: %F% %I% %G% %U% %#% */ #define m68k_debug_device debug_device @@ -28,7 +28,6 @@ #ifdef CONFIG_ZORRO #include <linux/zorro.h> #endif -#include <linux/seq_file.h> #include <asm/bootinfo.h> #include <asm/setup.h> @@ -92,7 +91,6 @@ extern void amiga_enable_irq (unsigned int); extern void amiga_disable_irq (unsigned int); static void amiga_get_model(char *model); static int amiga_get_hardware_list(char *buffer); -extern int show_amiga_interrupts (struct seq_file *, void *); /* amiga specific timer functions */ static unsigned long amiga_gettimeoffset (void); static void a3000_gettod (int *, int *, int *, int *, int *, int *); @@ -412,8 +410,8 @@ void __init config_amiga(void) mach_keyb_init = amiga_keyb_init; mach_kbdrate = amiga_kbdrate; mach_init_IRQ = amiga_init_IRQ; - mach_default_handler = &amiga_default_handler; #ifndef CONFIG_APUS + mach_default_handler = &amiga_default_handler; mach_request_irq = amiga_request_irq; mach_free_irq = amiga_free_irq; enable_irq = amiga_enable_irq; @@ -421,7 +419,6 @@ void __init config_amiga(void) #endif mach_get_model = amiga_get_model; mach_get_hardware_list = amiga_get_hardware_list; - mach_get_irq_list = show_amiga_interrupts; mach_gettimeoffset = amiga_gettimeoffset; if (AMIGAHW_PRESENT(A3000_CLK)){ mach_gettod = a3000_gettod; diff --git a/arch/ppc/boot/Makefile b/arch/ppc/boot/Makefile index e9930db7d0e5..21d300d12121 100644 --- a/arch/ppc/boot/Makefile +++ b/arch/ppc/boot/Makefile @@ -17,29 +17,32 @@ CFLAGS += -fno-builtin -D__BOOTER__ -I$(TOPDIR)/arch/$(ARCH)/boot/include AFLAGS += -D__BOOTER__ OBJCOPY_ARGS = -O elf32-powerpc -ifeq ($(CONFIG_SMP),y) -TFTPSIMAGE=/tftpboot/sImage.smp -else -TFTPSIMAGE=/tftpboot/sImage -endif +MKIMAGE := ./utils/mkimage.wrapper -lib/zlib.a: +lib/zlib.a: lib/zlib.c $(MAKE) -C lib images/vmlinux.gz: $(TOPDIR)/vmlinux $(MAKE) -C images vmlinux.gz -# Subdirs and tools needed for each. -subdir-y := lib images common -subdir-$(CONFIG_ALL_PPC) += chrp pmac prep -tools-$(CONFIG_ALL_PPC) := addnote piggyback mknote hack-coff mkprep -subdir-$(CONFIG_4xx) += tree -subdir-$(CONFIG_8xx) += mbx -subdir-$(CONFIG_8260) += mbx -tools-$(CONFIG_GEMINI) := mksimage - -# These are dirs we don't want to go into on BOOT_TARGETS -NONBOOT := lib images common +# Subdirs and tools needed for each. Assume we always need to go into +# 'simple' unless told otherwise. +subdir-y := lib common simple +subdir-$(CONFIG_ALL_PPC) := chrp pmac prep +tools-$(CONFIG_ALL_PPC) := addnote mknote hack-coff mkprep +tools-$(CONFIG_PPLUS) := mkbugboot mkprep +tools-$(CONFIG_4xx) := mktree +tools-$(CONFIG_LOPEC) := mkbugboot mkprep +tools-$(CONFIG_MCPN765) := mkbugboot mkprep +tools-$(CONFIG_MENF1) := mkprep +tools-$(CONFIG_MVME5100) := mkbugboot mkprep +tools-$(CONFIG_PRPMC750) := mkbugboot mkprep +tools-$(CONFIG_PRPMC800) := mkbugboot mkprep +tools-$(CONFIG_SPRUCE) := mktree + +# These are dirs we don't want to go into on BOOT_TARGETS. We have them for +# the 'depend' stage. +NONBOOT := lib common # These are the subdirs we want to use BOOTDIRS = $(filter-out $(NONBOOT), $(subdir-y)) @@ -50,37 +53,32 @@ maketools: $(MAKE) -C utils $(tools-y) # The targets all boards support for boot images. -BOOT_TARGETS = zImage -ifndef CONFIG_GEMINI -BOOT_TARGETS += zImage.initrd znetboot znetboot.initrd -endif +BOOT_TARGETS = zImage zImage.initrd znetboot znetboot.initrd -$(BOOT_TARGETS): sImage vmapus lib/zlib.a images/vmlinux.gz maketools +$(BOOT_TARGETS): vmapus lib/zlib.a images/vmlinux.gz maketools ifneq ($(BOOTDIRS),) for d in $(BOOTDIRS); do $(MAKE) -C $$d $@; done endif -sImage: $(TOPDIR)/vmlinux -ifdef CONFIG_GEMINI - $(OBJCOPY) -I elf32-powerpc -O binary $(TOPDIR)/vmlinux images/sImage -endif - vmapus: $(TOPDIR)/vmlinux ifdef CONFIG_APUS $(STRIP) $(TOPDIR)/vmlinux -o images/vmapus gzip $(GZIP_FLAGS) images/vmapus endif -ifdef CONFIG_GEMINI -znetboot : zImage - cp images/sImage $(TFTPSIMAGE) -endif +# Make an image for PPCBoot +pImage: images/vmlinux.gz + $(MKIMAGE) -A ppc -O linux -T kernel -C gzip -a 00000000 -e 00000000 \ + -n 'Linux-$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)' \ + -d $< images/vmlinux.PPCBoot + ln -sf vmlinux.PPCBoot images/pImage + +vmlinux.sm: $(TOPDIR)/vmlinux utils/addSystemMap + ./utils/addSystemMap $(TOPDIR)/System.map $(TOPDIR)/vmlinux images/vmlinux.sm -# Clean up after ourselves. We have to do it like this since only some dirs -# need to be gone into. -- Tom +# These are subdirs with files not normally rm'ed. -- Tom clean: $(MAKE) -C images clean - $(MAKE) -C tree clean $(MAKE) -C utils clean include $(TOPDIR)/Rules.make diff --git a/arch/ppc/boot/chrp/Makefile b/arch/ppc/boot/chrp/Makefile index 21fb7a5f7763..315d9e7abdf1 100644 --- a/arch/ppc/boot/chrp/Makefile +++ b/arch/ppc/boot/chrp/Makefile @@ -1,4 +1,4 @@ -# BK Id: SCCS/s.Makefile 1.13 07/27/01 20:24:17 trini +# BK Id: %F% %I% %G% %U% %#% # # Makefile for making ELF bootable images for booting on CHRP # using Open Firmware. @@ -7,19 +7,9 @@ # # Based on coffboot by Paul Mackerras -ifeq ($(CONFIG_PPC64BRIDGE),y) -MSIZE=.64 -AFLAGS += -Wa,-mppc64bridge -else -MSIZE= -endif - -.c.o: - $(CC) $(CFLAGS) -DKERNELBASE=$(KERNELBASE) -c -o $*.o $< -.S.o: - $(CC) $(AFLAGS) -traditional -c -o $*.o $< +USE_STANDARD_AS_RULE := true -LD_ARGS = -Ttext 0x00400000 +LD_ARGS = -T ../ld.script -Ttext 0x00400000 OBJS = ../common/crt0.o start.o main.o misc.o ../common/string.o image.o \ ../common/ofcommon.o @@ -27,23 +17,20 @@ LIBS = $(TOPDIR)/lib/lib.a ../lib/zlib.a ADDNOTE = ../utils/addnote PIGGYBACK = ../utils/piggyback +ifeq ($(CONFIG_PPC64BRIDGE),y) +END += .64 +AFLAGS += -Wa,-mppc64bridge +endif ifeq ($(CONFIG_SMP),y) -TFTPIMAGE=/tftpboot/zImage.chrp.smp$(MSIZE) -else -TFTPIMAGE=/tftpboot/zImage.chrp$(MSIZE) +END += .smp endif +TFTPIMAGE=/tftpboot/zImage.chrp$(END) + all: zImage znetboot: zImage -ifdef CONFIG_SMP - cp -f $(TOPDIR)/vmlinux /tftpboot/vmlinux.smp -else - cp -f $(TOPDIR)/vmlinux /tftpboot/vmlinux -endif -ifdef CONFIG_PPC64BRIDGE - cp -f $(TOPDIR)/vmlinux /tftpboot/vmlinux.64 -endif + cp -f $(TOPDIR)/vmlinux /tftpboot/vmlinux$(END) cp ../images/zImage.chrp $(TFTPIMAGE) znetboot.initrd: zImage.initrd @@ -52,22 +39,28 @@ znetboot.initrd: zImage.initrd floppy: zImage mcopy zImage a:zImage -image.o: $(PIGGYBACK) ../images/vmlinux.gz - $(PIGGYBACK) image < ../images/vmlinux.gz | $(AS) -o $@ - -sysmap.o: $(PIGGYBACK) $(TOPDIR)/System.map - $(PIGGYBACK) sysmap < $(TOPDIR)/System.map | $(AS) -o $@ - -initrd.o: ../images/ramdisk.image.gz $(PIGGYBACK) - $(PIGGYBACK) initrd < ../images/ramdisk.image.gz | $(AS) -o $@ +image.o: ../images/vmlinux.gz ../common/dummy.o + $(OBJCOPY) ../common/dummy.o $@ \ + --add-section=.image=../images/vmlinux.gz \ + --set-section-flags=.image=contents,alloc,load,readonly,data +ifdef CONFIG_XMON + $(OBJCOPY) $@ $@ \ + --add-section=.sysmap=$(TOPDIR)/System.map \ + --set-section-flags=.sysmap=contents,alloc,load,readonly,data +endif -zImage: $(OBJS) $(LIBS) ../common/no_initrd.o $(ADDNOTE) ../images/vmlinux.gz - $(LD) $(LD_ARGS) -o ../images/$@.chrp $(OBJS) ../common/no_initrd.o $(LIBS) +zImage: $(OBJS) $(LIBS) $(ADDNOTE) + $(LD) $(LD_ARGS) -o ../images/$@.chrp $(OBJS) $(LIBS) + $(OBJCOPY) ../images/$@.chrp ../images/$@.chrp -R .comment -R .ramdisk cp ../images/$@.chrp ../images/$@.chrp-rs6k $(ADDNOTE) ../images/$@.chrp-rs6k -zImage.initrd: $(OBJS) $(LIBS) initrd.o $(ADDNOTE) ../images/vmlinux.gz - $(LD) $(LD_ARGS) -o ../images/$@.chrp $(OBJS) initrd.o $(LIBS) +zImage.initrd: $(OBJS) $(LIBS) $(ADDNOTE) ../images/ramdisk.image.gz + $(OBJCOPY) image.o image.o \ + --add-section=.ramdisk=../images/ramdisk.image.gz \ + --set-section-flags=.ramdisk=contents,alloc,load,readonly,data + $(LD) $(LD_ARGS) -o ../images/$@.chrp $(OBJS) $(LIBS) + $(OBJCOPY) ../images/$@.chrp ../images/$@.chrp -R .comment cp ../images/$@.chrp ../images/$@.chrp-rs6k $(ADDNOTE) ../images/$@.chrp-rs6k diff --git a/arch/ppc/boot/chrp/main.c b/arch/ppc/boot/chrp/main.c index 92455a820e23..898134aac6f9 100644 --- a/arch/ppc/boot/chrp/main.c +++ b/arch/ppc/boot/chrp/main.c @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.main.c 1.13 07/27/01 20:24:17 trini + * BK Id: %F% %I% %G% %U% %#% */ /* * Copyright (C) Paul Mackerras 1997. @@ -11,15 +11,14 @@ */ #include "nonstdio.h" #include <asm/processor.h> +#include <asm/page.h> + +/* Passed from the linker */ +extern char __image_begin, __image_end; +extern char __ramdisk_begin[], __ramdisk_end; +extern char _start, _end; -extern char _end[]; -extern char initrd_data[]; -extern char image_data[]; -extern char sysmap_data[]; extern int getprop(void *, const char *, void *, int); -extern int initrd_len; -extern int image_len; -extern int sysmap_len; extern unsigned int heap_max; extern void claim(unsigned int virt, unsigned int size, unsigned int align); extern void *finddevice(const char *); @@ -53,22 +52,27 @@ chrpboot(int a1, int a2, void *prom) unsigned sa, len; void *dst; unsigned char *im; - unsigned initrd_start=0, initrd_size=0; - extern char _start; + unsigned int initrd_size, initrd_start; printf("chrpboot starting: loaded at 0x%p\n\r", &_start); - if (initrd_len) { - initrd_size = initrd_len; + initrd_size = (char *)(&__ramdisk_end) - (char *)(&__ramdisk_begin); + if (initrd_size) { initrd_start = (RAM_END - initrd_size) & ~0xFFF; + a1 = initrd_start; + a2 = initrd_size; claim(initrd_start, RAM_END - initrd_start, 0); printf("initial ramdisk moving 0x%x <- 0x%p (%x bytes)\n\r", - initrd_start, initrd_data, initrd_size); - memcpy((char *)initrd_start, initrd_data, initrd_size); + initrd_start, (char *)(&__ramdisk_begin), initrd_size); + memcpy((char *)initrd_start, (char *)(&__ramdisk_begin), initrd_size); + } else { + initrd_start = 0; + initrd_size = 0; + a2 = 0xdeadbeef; } - im = image_data; - len = image_len; + im = (char *)(&__image_begin); + len = (char *)(&__image_end) - (char *)(&__image_begin); /* claim 4MB starting at PROG_START */ claim(PROG_START, PROG_SIZE - PROG_START, 0); dst = (void *) PROG_START; diff --git a/arch/ppc/boot/common/Makefile b/arch/ppc/boot/common/Makefile index 144a63685bb6..ac7e537352ee 100644 --- a/arch/ppc/boot/common/Makefile +++ b/arch/ppc/boot/common/Makefile @@ -8,18 +8,7 @@ # Tom Rini January 2001 # -.c.s: - $(CC) $(CFLAGS) -S -o $*.s $< -.s.o: - $(AS) -o $*.o $< -.c.o: - $(CC) $(CFLAGS) -c -o $*.o $< -.S.s: - $(CPP) $(AFLAGS) -traditional -o $*.o $< -.S.o: - $(CC) $(AFLAGS) -traditional -c -o $*.o $< - -OBJCOPY_ARGS = -O elf32-powerpc +USE_STANDARD_AS_RULE := true coffcrt0.o: $(CC) $(AFLAGS) -DXCOFF -traditional -c -o coffcrt0.o crt0.S diff --git a/arch/ppc/boot/common/crt0.S b/arch/ppc/boot/common/crt0.S index e47cea5156ef..dad0c3285883 100644 --- a/arch/ppc/boot/common/crt0.S +++ b/arch/ppc/boot/common/crt0.S @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.crt0.S 1.12 08/09/01 17:09:10 paulus + * BK Id: %F% %I% %G% %U% %#% */ /* Copyright (c) 1997 Paul Mackerras <paulus@cs.anu.edu.au> * Initial Power Macintosh COFF version. @@ -22,7 +22,7 @@ */ #include <linux/config.h> -#include "../../kernel/ppc_asm.tmpl" +#include <asm/ppc_asm.h> .text diff --git a/arch/ppc/boot/common/dummy.c b/arch/ppc/boot/common/dummy.c new file mode 100644 index 000000000000..bee37d7c3f57 --- /dev/null +++ b/arch/ppc/boot/common/dummy.c @@ -0,0 +1,7 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ +int main(void) +{ + return 0; +} diff --git a/arch/ppc/boot/common/misc-simple.c b/arch/ppc/boot/common/misc-simple.c index 06c70a4c1020..a2965595aa5f 100644 --- a/arch/ppc/boot/common/misc-simple.c +++ b/arch/ppc/boot/common/misc-simple.c @@ -3,10 +3,10 @@ * * Misc. bootloader code for many machines. This assumes you have are using * a 6xx/7xx/74xx CPU in your machine. This assumes the chunk of memory - * below 8MB is free. Finally, it assumes you have a NS16550-style uart for + * below 8MB is free. Finally, it assumes you have a NS16550-style uart for * your serial console. If a machine meets these requirements, it can quite * likely use this code during boot. - * + * * Author: Matt Porter <mporter@mvista.com> * Derived from arch/ppc/boot/prep/misc.c * @@ -25,41 +25,59 @@ #include <asm/page.h> #include <asm/processor.h> #include <asm/mmu.h> +#include <asm/bootinfo.h> #include "nonstdio.h" #include "zlib.h" -unsigned long com_port; - -char *avail_ram; -char *end_avail; -extern char _end[]; - +/* Default cmdline */ #ifdef CONFIG_CMDLINE #define CMDLINE CONFIG_CMDLINE #else #define CMDLINE "" #endif + +/* Keyboard (and VGA console)? */ +#ifdef CONFIG_VGA_CONSOLE +#define HAS_KEYB 1 +#else +#define HAS_KEYB 0 +#endif + +char *avail_ram; +char *end_avail; +char *zimage_start; char cmd_preset[] = CMDLINE; char cmd_buf[256]; char *cmd_line = cmd_buf; - -unsigned long initrd_start = 0, initrd_end = 0; -char *zimage_start; +int keyb_present = HAS_KEYB; int zimage_size; +unsigned long com_port; +unsigned long initrd_size = 0; + +/* The linker tells us various locations in the image */ +extern char __image_begin, __image_end; +extern char __ramdisk_begin, __ramdisk_end; +extern char _end[]; +/* Original location */ +extern unsigned long start; + +extern int CRT_tstc(void); +extern unsigned long serial_init(int chan, void *ignored); +extern void serial_close(unsigned long com_port); extern void gunzip(void *, int, unsigned char *, int *); -extern unsigned long serial_init(int chan); +extern void setup_legacy(void); -void +struct bi_record * decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum) { - int timer = 0; - extern unsigned long start; char *cp, ch; + struct bi_record *rec, *birecs; - com_port = serial_init(0); + setup_legacy(); + com_port = serial_init(0, NULL); /* assume the chunk below 8M is free */ end_avail = (char *)0x00800000; @@ -69,7 +87,8 @@ decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum) * were relocated to. */ puts("loaded at: "); puthex(load_addr); - puts(" "); puthex((unsigned long)(load_addr + (4*num_words))); puts("\n"); + puts(" "); puthex((unsigned long)(load_addr + (4*num_words))); + puts("\n"); if ( (unsigned long)load_addr != (unsigned long)&start ) { puts("relocated to: "); puthex((unsigned long)&start); @@ -78,49 +97,31 @@ decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum) puts("\n"); } - /* we have to subtract 0x10000 here to correct for objdump including - the size of the elf header which we strip -- Cort */ - zimage_start = (char *)(load_addr - 0x10000 + ZIMAGE_OFFSET); - zimage_size = ZIMAGE_SIZE; + /* + * We link ourself to 0x00800000. When we run, we relocate + * ourselves there. So we just need __image_begin for the + * start. -- Tom + */ + zimage_start = (char *)(unsigned long)(&__image_begin); + zimage_size = (unsigned long)(&__image_end) - + (unsigned long)(&__image_begin); - if ( INITRD_OFFSET ) - initrd_start = load_addr - 0x10000 + INITRD_OFFSET; - else - initrd_start = 0; - initrd_end = INITRD_SIZE + initrd_start; + initrd_size = (unsigned long)(&__ramdisk_end) - + (unsigned long)(&__ramdisk_begin); /* - * Find a place to stick the zimage and initrd and - * relocate them if we have to. -- Cort + * The zImage and initrd will be between start and _end, so they've + * already been moved once. We're good to go now. -- Tom */ avail_ram = (char *)PAGE_ALIGN((unsigned long)_end); puts("zimage at: "); puthex((unsigned long)zimage_start); - puts(" "); puthex((unsigned long)(zimage_size+zimage_start)); puts("\n"); - if ( (unsigned long)zimage_start <= 0x00800000 ) - { - memcpy( (void *)avail_ram, (void *)zimage_start, zimage_size ); - zimage_start = (char *)avail_ram; - puts("relocated to: "); puthex((unsigned long)zimage_start); - puts(" "); - puthex((unsigned long)zimage_size+(unsigned long)zimage_start); - puts("\n"); + puts(" "); puthex((unsigned long)(zimage_size+zimage_start)); + puts("\n"); - /* relocate initrd */ - if ( initrd_start ) - { - puts("initrd at: "); puthex(initrd_start); - puts(" "); puthex(initrd_end); puts("\n"); - avail_ram = (char *)PAGE_ALIGN( - (unsigned long)zimage_size+(unsigned long)zimage_start); - memcpy ((void *)avail_ram, (void *)initrd_start, INITRD_SIZE ); - initrd_start = (unsigned long)avail_ram; - initrd_end = initrd_start + INITRD_SIZE; - puts("relocated to: "); puthex(initrd_start); - puts(" "); puthex(initrd_end); puts("\n"); - } - } else if ( initrd_start ) { - puts("initrd at: "); puthex(initrd_start); - puts(" "); puthex(initrd_end); puts("\n"); + if ( initrd_size ) { + puts("initrd at: "); + puthex((unsigned long)(&__ramdisk_begin)); + puts(" "); puthex((unsigned long)(&__ramdisk_end));puts("\n"); } avail_ram = (char *)0x00400000; @@ -128,11 +129,28 @@ decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum) puts("avail ram: "); puthex((unsigned long)avail_ram); puts(" "); puthex((unsigned long)end_avail); puts("\n"); + if (keyb_present) + CRT_tstc(); /* Forces keyboard to be initialized */ +#ifdef CONFIG_GEMINI + /* + * If cmd_line is empty and cmd_preset is not, copy cmd_preset + * to cmd_line. This way we can override cmd_preset with the + * command line from Smon. + */ + + if ( (cmd_line[0] == '\0') && (cmd_preset[0] != '\0')) + memcpy (cmd_line, cmd_preset, sizeof(cmd_preset)); +#endif + /* Display standard Linux/PPC boot prompt for kernel args */ puts("\nLinux/PPC load: "); cp = cmd_line; memcpy (cmd_line, cmd_preset, sizeof(cmd_preset)); while ( *cp ) putc(*cp++); + +#ifndef CONFIG_GEMINI + /* Val Henson has requested that Gemini doesn't wait for the + * user to edit the cmdline or not. */ while (timer++ < 5*1000) { if (tstc()) { while ((ch = getc()) != '\n' && ch != '\r') { @@ -158,18 +176,44 @@ decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum) udelay(1000); /* 1 msec */ } *cp = 0; +#endif puts("\n"); - /* mappings on early boot can only handle 16M */ - if ( (int)(cmd_line[0]) > (16<<20)) - puts("cmd_line located > 16M\n"); - if ( initrd_start > (16<<20)) - puts("initrd_start located > 16M\n"); - puts("Uncompressing Linux..."); - gunzip(0, 0x400000, zimage_start, &zimage_size); puts("done.\n"); + /* + * Create bi_recs for cmd_line and initrds + */ + rec = (struct bi_record *)_ALIGN((unsigned long)(zimage_size) + + (1 << 20) - 1, (1 << 20)); + birecs = rec; + + rec->tag = BI_FIRST; + rec->size = sizeof(struct bi_record); + rec = (struct bi_record *)((unsigned long)rec + rec->size); + + rec->tag = BI_CMD_LINE; + memcpy( (char *)rec->data, cmd_line, strlen(cmd_line)+1); + rec->size = sizeof(struct bi_record) + strlen(cmd_line) + 1; + rec = (struct bi_record *)((unsigned long)rec + rec->size); + + if ( initrd_size ) { + rec->tag = BI_INITRD; + rec->data[0] = (unsigned long)(&__ramdisk_begin); + rec->data[1] = initrd_size; + rec->size = sizeof(struct bi_record) + 2 * + sizeof(unsigned long); + rec = (struct bi_record *)((unsigned long)rec + + rec->size); + } + + rec->tag = BI_LAST; + rec->size = sizeof(struct bi_record); + rec = (struct bi_record *)((unsigned long)rec + rec->size); puts("Now booting the kernel\n"); + serial_close(com_port); + + return birecs; } diff --git a/arch/ppc/boot/common/no_initrd.c b/arch/ppc/boot/common/no_initrd.c deleted file mode 100644 index b7191ca747cf..000000000000 --- a/arch/ppc/boot/common/no_initrd.c +++ /dev/null @@ -1,5 +0,0 @@ -/* - * BK Id: SCCS/s.no_initrd.c 1.7 05/18/01 15:17:23 cort - */ -char initrd_data[1]; -int initrd_len = 0; diff --git a/arch/ppc/boot/common/ns16550.c b/arch/ppc/boot/common/ns16550.c index b965f5bc1d71..0b4b1cdfd7c2 100644 --- a/arch/ppc/boot/common/ns16550.c +++ b/arch/ppc/boot/common/ns16550.c @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.ns16550.c 1.9 07/30/01 17:19:40 trini + * BK Id: %F% %I% %G% %U% %#% */ /* * COM1 NS16550 support @@ -10,6 +10,8 @@ #include <linux/serial_reg.h> #include <asm/serial.h> +#define SERIAL_BAUD 9600 + extern void outb(int port, unsigned char val); extern unsigned char inb(int port); extern unsigned long ISA_io; @@ -20,8 +22,10 @@ static struct serial_state rs_table[RS_TABLE_SIZE] = { static int shift; -unsigned long serial_init(int chan) { +unsigned long serial_init(int chan, void *ignored) +{ unsigned long com_port; + unsigned char lcr, dlm; /* We need to find out which type io we're expecting. If it's * 'SERIAL_IO_PORT', we get an offset from the isa_io_base. @@ -40,23 +44,33 @@ unsigned long serial_init(int chan) { /* How far apart the registers are. */ shift = rs_table[chan].iomem_reg_shift; - - /* See if port is present */ - outb(com_port + (UART_LCR << shift), 0x00); - outb(com_port + (UART_IER << shift), 0x00); + + /* save the LCR */ + lcr = inb(com_port + (UART_LCR << shift)); /* Access baud rate */ outb(com_port + (UART_LCR << shift), 0x80); -#ifdef CONFIG_SERIAL_CONSOLE_NONSTD - /* Input clock. */ - outb(com_port + (UART_DLL << shift), - (BASE_BAUD / CONFIG_SERIAL_CONSOLE_BAUD)); - outb(com_port + (UART_DLM << shift), - (BASE_BAUD / CONFIG_SERIAL_CONSOLE_BAUD) >> 8); -#endif - /* 8 data, 1 stop, no parity */ - outb(com_port + (UART_LCR << shift), 0x03); - /* RTS/DTR */ - outb(com_port + (UART_MCR << shift), 0x03); + dlm = inb(com_port + (UART_DLM << shift)); + /* + * Test if serial port is unconfigured. + * We assume that no-one uses less than 110 baud or + * less than 7 bits per character these days. + * -- paulus. + */ + + if ((dlm <= 4) && (lcr & 2)) + /* port is configured, put the old LCR back */ + outb(com_port + (UART_LCR << shift), lcr); + else { + /* Input clock. */ + outb(com_port + (UART_DLL << shift), + (BASE_BAUD / SERIAL_BAUD)); + outb(com_port + (UART_DLM << shift), + (BASE_BAUD / SERIAL_BAUD) >> 8); + /* 8 data, 1 stop, no parity */ + outb(com_port + (UART_LCR << shift), 0x03); + /* RTS/DTR */ + outb(com_port + (UART_MCR << shift), 0x03); + } /* Clear & enable FIFOs */ outb(com_port + (UART_FCR << shift), 0x07); @@ -84,3 +98,8 @@ serial_tstc(unsigned long com_port) { return ((inb(com_port + (UART_LSR << shift)) & UART_LSR_DR) != 0); } + +void +serial_close(unsigned long com_port) +{ +} diff --git a/arch/ppc/boot/common/ofcommon.c b/arch/ppc/boot/common/ofcommon.c index f789f723d218..1e427ff1ba53 100644 --- a/arch/ppc/boot/common/ofcommon.c +++ b/arch/ppc/boot/common/ofcommon.c @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.ofcommon.c 1.1 07/27/01 20:24:18 trini + * BK Id: %F% %I% %G% %U% %#% * * Copyright (C) Paul Mackerras 1997. * @@ -14,6 +14,9 @@ #include <asm/bootinfo.h> #include <asm/page.h> +/* Information from the linker */ +extern char __sysmap_begin, __sysmap_end; + extern int strcmp(const char *s1, const char *s2); extern char *avail_ram, *avail_high; extern char *end_avail; @@ -126,15 +129,22 @@ void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp) inflateEnd(&s); } -/* Make a bi_rec in OF. We need to be passed a name for BI_BOOTLOADER_ID, +/* Make a bi_rec in OF. We need to be passed a name for BI_BOOTLOADER_ID, * a machine type for BI_MACHTYPE, and the location where the end of the * bootloader is (PROG_START + PROG_SIZE) */ void make_bi_recs(unsigned long addr, char *name, unsigned int mach, unsigned long progend) { + unsigned long sysmap_size; struct bi_record *rec; + /* FIgure out the size of a possible System.map we're going to + * pass along. + * */ + sysmap_size = (unsigned long)(&__sysmap_end) - + (unsigned long)(&__sysmap_begin); + /* leave a 1MB gap then align to the next 1MB boundary */ addr = _ALIGN(addr+ (1<<20) - 1, (1<<20)); /* oldworld machine seem very unhappy about this. -- Tom */ @@ -150,21 +160,22 @@ void make_bi_recs(unsigned long addr, char *name, unsigned int mach, sprintf( (char *)rec->data, name); rec->size = sizeof(struct bi_record) + strlen(name) + 1; rec = (struct bi_record *)((unsigned long)rec + rec->size); - + rec->tag = BI_MACHTYPE; rec->data[0] = mach; rec->data[1] = 1; rec->size = sizeof(struct bi_record) + 2 * sizeof(unsigned long); rec = (struct bi_record *)((unsigned long)rec + rec->size); -#ifdef SYSMAP_OFFSET - rec->tag = BI_SYSMAP; - rec->data[0] = SYSMAP_OFFSET; - rec->data[1] = SYSMAP_SIZE; - rec->size = sizeof(struct bi_record) + 2 * sizeof(unsigned long); - rec = (struct bi_record *)((unsigned long)rec + rec->size); -#endif /* SYSMAP_OFFSET */ - + if (sysmap_size) { + rec->tag = BI_SYSMAP; + rec->data[0] = (unsigned long)(&__sysmap_begin); + rec->data[1] = sysmap_size; + rec->size = sizeof(struct bi_record) + 2 * + sizeof(unsigned long); + rec = (struct bi_record *)((unsigned long)rec + rec->size); + } + rec->tag = BI_LAST; rec->size = sizeof(struct bi_record); rec = (struct bi_record *)((unsigned long)rec + rec->size); diff --git a/arch/ppc/boot/common/relocate.S b/arch/ppc/boot/common/relocate.S new file mode 100644 index 000000000000..3f9ba51004b4 --- /dev/null +++ b/arch/ppc/boot/common/relocate.S @@ -0,0 +1,204 @@ +/* + * arch/ppc/boot/simple/relocate.S + * + * This is the common part of the loader relocation and initialization + * process. All of the board/processor specific initialization is + * done before we get here. + * + * Author: Tom Rini + * trini@mvista.com + * Derived from arch/ppc/boot/prep/head.S (Cort Dougan, many others). + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include <linux/config.h> +#include <asm/processor.h> +#include <asm/cache.h> +#include <asm/ppc_asm.h> + +#define GETSYM(reg, sym) \ + lis reg, sym@h; ori reg, reg, sym@l + + .text + /* We get called from the early initialization code. + * Register 3 has the address where we were loaded, + * Register 4 contains any residual data passed from the + * boot rom. + */ + .globl relocate +relocate: + /* Save r3, r4 for later. + * The r8/r11 are legacy registers so I don't have to + * rewrite the code below :-). + */ + mr r8, r3 + mr r11, r4 + + /* compute the size of the whole image in words. */ + GETSYM(r4,start) + GETSYM(r5,end) + + addi r5,r5,3 /* round up */ + sub r5,r5,r4 /* end - start */ + srwi r5,r5,2 + mr r7,r5 /* Save for later use. */ + + /* + * Check if we need to relocate ourselves to the link addr or were + * we loaded there to begin with. + */ + cmp cr0,r3,r4 + beq start_ldr /* If 0, we don't need to relocate */ + + /* Move this code somewhere safe. This is max(load + size, end) + * r8 == load address + */ + GETSYM(r4, start) + GETSYM(r5, end) + + sub r6,r5,r4 + add r6,r8,r6 /* r6 == phys(load + size) */ + + cmpw r5,r6 + bgt 1f + b 2f +1: + mr r6, r5 +2: + /* dest is in r6 */ + /* Ensure alignment --- this code is precautionary */ + addi r6,r6,4 + li r5,0x0003 + andc r6,r6,r5 + + /* Find physical address and size of do_relocate */ + GETSYM(r5, __relocate_start) + GETSYM(r4, __relocate_end) + GETSYM(r3, start) + + /* Size to copy */ + sub r4,r4,r5 + srwi r4,r4,2 + + /* Src addr to copy (= __relocate_start - start + where_loaded) */ + sub r3,r5,r3 + add r5,r8,r3 + + /* Save dest */ + mr r3, r6 + + /* Do the copy */ + mtctr r4 +3: lwz r4,0(r5) + stw r4,0(r3) + addi r3,r3,4 + addi r5,r5,4 + bdnz 3b + + GETSYM(r4, __relocate_start) + GETSYM(r5, do_relocate) + + sub r4,r5,r4 /* Get entry point for do_relocate in + add r6,r6,r4 * relocated section */ + + /* This will return to the relocated do_relocate */ + mtlr r6 + b flush_instruction_cache + + .section ".relocate_code","xa" + +do_relocate: + /* We have 2 cases --- start < load, or start > load + * This determines whether we copy from the end, or the start. + * Its easier to have 2 loops than to have paramaterised + * loops. Sigh. + */ + li r6,0 /* Clear checksum */ + mtctr r7 /* Setup for a loop */ + + GETSYM(r4, start) + mr r3,r8 /* Get the load addr */ + + cmp cr0,r4,r3 /* If we need to copy from the end, do so */ + bgt do_relocate_from_end + +do_relocate_from_start: +1: lwz r5,0(r3) /* Load and decrement */ + stw r5,0(r4) /* Store and decrement */ + addi r3,r3,4 + addi r4,r4,4 + xor r6,r6,r5 /* Update checksum */ + bdnz 1b /* Are we done? */ + b do_relocate_out /* Finished */ + +do_relocate_from_end: + GETSYM(r3, end) + slwi r4,r7,2 + add r4,r8,r4 /* Get the physical end */ +1: lwzu r5,-4(r4) + stwu r5, -4(r3) + xor r6,r6,r5 + bdnz 1b + +do_relocate_out: + GETSYM(r3,start_ldr) + mtlr r3 /* Easiest way to do an absolute jump */ +/* Some boards don't boot up with the I-cache enabled. Do that + * now because the decompress runs much faster that way. + * As a side effect, we have to ensure the data cache is not enabled + * so we can access the serial I/O without trouble. + */ + b flush_instruction_cache + + .previous + +start_ldr: +/* Clear all of BSS and set up stack for C calls */ + lis r3,edata@h + ori r3,r3,edata@l + lis r4,end@h + ori r4,r4,end@l + subi r3,r3,4 + subi r4,r4,4 + li r0,0 +50: stwu r0,4(r3) + cmp cr0,r3,r4 + bne 50b +90: mr r9,r1 /* Save old stack pointer (in case it matters) */ + lis r1,.stack@h + ori r1,r1,.stack@l + addi r1,r1,4096*2 + subi r1,r1,256 + li r2,0x000F /* Mask pointer to 16-byte boundary */ + andc r1,r1,r2 + + /* + * Exec kernel loader + */ + mr r3,r8 /* Load point */ + mr r4,r7 /* Program length */ + mr r5,r6 /* Checksum */ + mr r6,r11 /* Residual data */ + bl decompress_kernel + + /* + * Make sure the kernel knows we don't have things set in + * registers. -- Tom + */ + li r4,0 + li r6,0 + + /* + * Start at the begining. + */ + li r9,0x0000 + mtlr r9 + blr + + .comm .stack,4096*2,4 diff --git a/arch/ppc/boot/common/util.S b/arch/ppc/boot/common/util.S new file mode 100644 index 000000000000..206d7f0d6e40 --- /dev/null +++ b/arch/ppc/boot/common/util.S @@ -0,0 +1,230 @@ +/* + * arch/ppc/boot/common/util.S + * + * Useful bootup functions, which are more easily done in asm than C. + * + * NOTE: Be very very careful about the registers you use here. + * We don't follow any ABI calling convention among the + * assembler functions that call each other, especially early + * in the initialization. Please preserve at least r3 and r4 + * for these early functions, as they often contain information + * passed from boot roms into the C decompress function. + * + * Author: Tom Rini + * trini@mvista.com + * Derived from arch/ppc/boot/prep/head.S (Cort Dougan, many others). + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include <asm/processor.h> +#include <asm/cache.h> +#include <asm/ppc_asm.h> + + + .text + + .globl disable_6xx_mmu +disable_6xx_mmu: + /* Establish default MSR value, exception prefix 0xFFF. + * If necessary, this function must fix up the LR if we + * return to a different address space once the MMU is + * disabled. + */ + li r8,MSR_IP|MSR_FP + mtmsr r8 + + /* Clear BATs */ + li r8,0 + mtspr DBAT0U,r8 + mtspr DBAT0L,r8 + mtspr DBAT1U,r8 + mtspr DBAT1L,r8 + mtspr DBAT2U,r8 + mtspr DBAT2L,r8 + mtspr DBAT3U,r8 + mtspr DBAT3L,r8 + mtspr IBAT0U,r8 + mtspr IBAT0L,r8 + mtspr IBAT1U,r8 + mtspr IBAT1L,r8 + mtspr IBAT2U,r8 + mtspr IBAT2L,r8 + mtspr IBAT3U,r8 + mtspr IBAT3L,r8 + isync + sync + sync + + /* Set segment registers */ + li r8,16 /* load up segment register values */ + mtctr r8 /* for context 0 */ + lis r8,0x2000 /* Ku = 1, VSID = 0 */ + li r10,0 +3: mtsrin r8,r10 + addi r8,r8,0x111 /* increment VSID */ + addis r10,r10,0x1000 /* address of next segment */ + bdnz 3b + + .globl disable_6xx_l1cache +disable_6xx_l1cache: + /* Enable, invalidate and then disable the L1 icache/dcache. */ + li r8,0 + ori r8,r8,(HID0_ICE|HID0_DCE|HID0_ICFI|HID0_DCI) + mfspr r11,HID0 + or r11,r11,r8 + andc r10,r11,r8 + isync + mtspr HID0,r8 + sync + isync + mtspr HID0,r10 + sync + isync + blr + + .globl _setup_L2CR +_setup_L2CR: +/* + * We should be skipping this section on CPUs where this results in an + * illegal instruction. If not, please send trini@kernel.crashing.org + * the PVR of your CPU. + */ + /* Invalidate/disable L2 cache */ + sync + isync + mfspr r8,L2CR + rlwinm r8,r8,0,1,31 + oris r8,r8,0x0020 + sync + isync + mtspr L2CR,r8 + sync + isync + + /* Wait for the invalidation to complete */ +1: mfspr r8,L2CR + rlwinm. r9,r8,0,31,31 + bne 1b + + rlwinm r8,r8,0,11,9 /* Turn off L2I bit */ + sync + isync + mtspr L2CR,r8 + sync + isync + blr + + +/* + * Delay for a number of microseconds + * -- Use the BUS timer (assumes 66MHz) + */ + .globl udelay +udelay: + mfspr r4,PVR + srwi r4,r4,16 + cmpi 0,r4,1 /* 601 ? */ + bne .udelay_not_601 +00: li r0,86 /* Instructions / microsecond? */ + mtctr r0 +10: addi r0,r0,0 /* NOP */ + bdnz 10b + subic. r3,r3,1 + bne 00b + blr + +.udelay_not_601: + mulli r4,r3,1000 /* nanoseconds */ + addi r4,r4,59 + li r5,60 + divw r4,r4,r5 /* BUS ticks */ +1: mftbu r5 + mftb r6 + mftbu r7 + cmp 0,r5,r7 + bne 1b /* Get [synced] base time */ + addc r9,r6,r4 /* Compute end time */ + addze r8,r5 +2: mftbu r5 + cmp 0,r5,r8 + blt 2b + bgt 3f + mftb r6 + cmp 0,r6,r9 + blt 2b +3: blr + +.globl _put_MSR +_put_MSR: + mtmsr r3 + blr + + .section ".relocate_code","xa" +/* + * Flush and enable instruction cache + * First, flush the data cache in case it was enabled and may be + * holding instructions for copy back. + */ +_GLOBAL(flush_instruction_cache) + mflr r6 + bl flush_data_cache + +#ifdef CONFIG_8xx + lis r3, IDC_INVALL@h + mtspr IC_CST, r3 + lis r3, IDC_ENABLE@h + mtspr IC_CST, r3 + lis r3, IDC_DISABLE@h + mtspr DC_CST, r3 +#elif CONFIG_4xx + lis r3,start@h # r9 = &_start + lis r4,_etext@ha + addi r4,r4,_etext@l # r8 = &_etext +1: dcbf r0,r3 # Flush the data cache + icbi r0,r3 # Invalidate the instruction cache + addi r3,r3,0x10 # Increment by one cache line + cmplwi cr0,r3,r4 # Are we at the end yet? + blt 1b # No, keep flushing and invalidating +#else + /* Enable, invalidate and then disable the L1 icache/dcache. */ + li r3,0 + ori r3,r3,(HID0_ICE|HID0_DCE|HID0_ICFI|HID0_DCI) + mfspr r4,HID0 + or r5,r4,r3 + isync + mtspr HID0,r5 + sync + isync + ori r5,r4,HID0_ICE /* Enable cache */ + mtspr HID0,r5 + sync + isync +#endif + mtlr r6 + blr + +#define NUM_CACHE_LINES 128*8 +#define cache_flush_buffer 0x1000 + +/* + * Flush data cache + * Do this by just reading lots of stuff into the cache. + */ +_GLOBAL(flush_data_cache) + lis r3,cache_flush_buffer@h + ori r3,r3,cache_flush_buffer@l + li r4,NUM_CACHE_LINES + mtctr r4 +00: lwz r4,0(r3) + addi r3,r3,L1_CACHE_BYTES /* Next line, please */ + bdnz 00b +10: blr + + .previous + diff --git a/arch/ppc/boot/images/Makefile b/arch/ppc/boot/images/Makefile index d6ee957b9081..8723f6c5519e 100644 --- a/arch/ppc/boot/images/Makefile +++ b/arch/ppc/boot/images/Makefile @@ -5,8 +5,8 @@ include $(TOPDIR)/Rules.make vmlinux.gz: $(TOPDIR)/vmlinux - $(OBJCOPY) -S -O binary $(TOPDIR)/vmlinux vmlinux + $(OBJCOPY) --strip-all -S -O binary $(TOPDIR)/vmlinux vmlinux gzip -vf9 vmlinux clean: - rm -f sImage vmapus vmlinux.* miboot.image* zImage* zvmlinux.* + rm -f sImage vmapus vmlinux* miboot* zImage* zvmlinux* diff --git a/arch/ppc/boot/pmac/ld.script b/arch/ppc/boot/ld.script index 33317e773e22..df5df8fcbe43 100644 --- a/arch/ppc/boot/pmac/ld.script +++ b/arch/ppc/boot/ld.script @@ -26,21 +26,18 @@ SECTIONS .rela.bss : { *(.rela.bss) } .rel.plt : { *(.rel.plt) } .rela.plt : { *(.rela.plt) } - .init : { *(.init) } =0 .plt : { *(.plt) } .text : { *(.text) - *(.rodata) - *(.rodata.*) - *(.rodata1) - *(.got1) + *(.fixup) + __relocate_start = .; + *(.relocate_code) + __relocate_end = .; } - .fini : { *(.fini) } =0 - .ctors : { *(.ctors) } - .dtors : { *(.dtors) } _etext = .; PROVIDE (etext = .); + /* Read-write section, merged into data segment: */ . = (. + 0x0FFF) & 0xFFFFF000; .data : @@ -51,10 +48,26 @@ SECTIONS *(.sdata2) *(.got.plt) *(.got) *(.dynamic) + *(.rodata) + *(.rodata.*) + *(.rodata1) + *(.got1) + __image_begin = .; + *(.image) + __image_end = .; + . = ALIGN(4096); + __ramdisk_begin = .; + *(.ramdisk) + __ramdisk_end = .; + . = ALIGN(4096); + __sysmap_begin = .; + *(.sysmap) + __sysmap_end = .; CONSTRUCTORS } _edata = .; PROVIDE (edata = .); + __bss_start = .; .bss : { @@ -66,4 +79,3 @@ SECTIONS _end = . ; PROVIDE (end = .); } - diff --git a/arch/ppc/boot/lib/zlib.c b/arch/ppc/boot/lib/zlib.c index a6127edf3f9b..47f70ad3811c 100644 --- a/arch/ppc/boot/lib/zlib.c +++ b/arch/ppc/boot/lib/zlib.c @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.zlib.c 1.8 05/18/01 15:17:24 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * This file is derived from various .h and .c files from the zlib-0.95 @@ -651,11 +651,6 @@ struct inflate_blocks_state { /* load local pointers */ #define LOAD {LOADIN LOADOUT} -/* - * The IBM 150 firmware munges the data right after _etext[]. This - * protects it. -- Cort - */ -local uInt protect_mask[] = {0, 0, 0, 0, 0, 0, 0, 0, 0 ,0 ,0 ,0}; /* And'ing with mask[n] masks the lower n bits */ local uInt inflate_mask[] = { 0x0000, diff --git a/arch/ppc/boot/mbx/Makefile b/arch/ppc/boot/mbx/Makefile deleted file mode 100644 index 44069ba2d714..000000000000 --- a/arch/ppc/boot/mbx/Makefile +++ /dev/null @@ -1,135 +0,0 @@ -# BK Id: SCCS/s.Makefile 1.7 06/05/01 20:20:05 paulus -# -# -# arch/ppc/mbxboot/Makefile -# -# This file is subject to the terms and conditions of the GNU General Public -# License. See the file "COPYING" in the main directory of this archive -# for more details. -# -# Copyright (C) 1994 by Linus Torvalds -# Adapted for PowerPC by Gary Thomas -# modified by Cort (cort@cs.nmt.edu) -# -.c.s: - $(CC) $(CFLAGS) -S -o $*.s $< -.s.o: - $(AS) -o $*.o $< -.c.o: - $(CC) $(CFLAGS) -c -o $*.o $< -.S.s: - $(CPP) $(AFLAGS) -traditional -o $*.o $< -.S.o: - $(CC) $(AFLAGS) -traditional -c -o $*.o $< - -TFTPIMAGE := /tftpboot/zImage.embedded - -OFFSET := ../utils/offset -SIZE := ../utils/size - -LIBS := ../lib/zlib.a -OBJCOPY_ARGS := -O elf32-powerpc - -ifdef CONFIG_8xx -ZLINKFLAGS := -T $(TOPDIR)/arch/$(ARCH)/vmlinux.lds -Ttext 0x00180000 -OBJECTS := head.o m8xx_tty.o -CFLAGS += -DCONFIG_8xx -endif - -ifdef CONFIG_8260 -ZLINKFLAGS := -T $(TOPDIR)/arch/$(ARCH)/vmlinux.lds -Ttext 0x00400000 -OBJECTS := head_8260.o m8260_tty.o embed_config.o -CFLAGS += -DCONFIG_8260 -endif - -OBJECTS += ../common/misc-common.o misc.o ../common/string.o -OBJCOPY_ARGS = -O elf32-powerpc - -ifeq ($(CONFIG_MBX),y) -OBJECTS += iic.o embed_config.o pci.o qspan_pci.o -CFLAGS += -DCONFIG_MBX -endif -ifeq ($(CONFIG_RPXLITE),y) -CFLAGS += -DCONFIG_RPXLITE -OBJECTS += iic.o embed_config.o -endif -ifeq ($(CONFIG_RPXCLASSIC),y) -CFLAGS += -DCONFIG_RPXCLASSIC -OBJECTS += iic.o embed_config.o pci.o qspan_pci.o -endif -ifeq ($(CONFIG_BSEIP),y) -CFLAGS += -DCONFIG_BSEIP -OBJECTS += iic.o embed_config.o -endif -ifeq ($(CONFIG_FADS),y) -CFLAGS += -DCONFIG_FADS -OBJECTS += embed_config.o -endif - -all: zImage - -misc.o: misc.c - $(CC) $(CFLAGS) -DINITRD_OFFSET=0 -DINITRD_SIZE=0 -DZIMAGE_OFFSET=0 \ - -DZIMAGE_SIZE=0 -c -o $@ $*.c - -zvmlinux.initrd: $(OBJECTS) $(LIBS) ../images/vmlinux.gz - $(LD) $(ZLINKFLAGS) -o $@.tmp $(OBJECTS) $(LIBS) - $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \ - --add-section=initrd=../images/ramdisk.image.gz \ - --add-section=image=../images/vmlinux.gz \ - $@.tmp $@ - $(CC) $(CFLAGS) -DINITRD_OFFSET=`sh $(OFFSET) $(OBJDUMP) $@ initrd` \ - -DINITRD_SIZE=`sh $(SIZE) $(OBJDUMP) $@ initrd` \ - -DZIMAGE_OFFSET=`sh $(OFFSET) $(OBJDUMP) $@ image` \ - -DZIMAGE_SIZE=`sh $(SIZE) $(OBJDUMP) $@ image` \ - -c -o misc.o misc.c - $(LD) $(ZLINKFLAGS) -o $@.tmp $(OBJECTS) $(LIBS) - $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \ - --add-section=initrd=../images/ramdisk.image.gz \ - --add-section=image=../images/vmlinux.gz \ - $@.tmp ../images/$@.embedded - -zImage: zvmlinux -ifeq ($(CONFIG_RPXCLASSIC),y) - dd if=../images/zvmlinux.embedded of=../images/zImage.embedded bs=65536 skip=1 -else - ln -sf ../images/zvmlinux.embedded ../images/zImage.embedded -endif - -zImage.initrd: zvmlinux.initrd -ifeq ($(CONFIG_RPXCLASSIC),y) - dd if=../images/zvmlinux.initrd.embedded of=../images/zImage.initrd.embedded bs=65536 skip=1 -else - ln -sf ../images/zvmlinux.initrd.embedded ../images/zImage.initrd.embedded -endif - -zvmlinux: $(OBJECTS) $(LIBS) ../images/vmlinux.gz -# -# build the boot loader image and then compute the offset into it -# for the kernel image -# - $(LD) $(ZLINKFLAGS) -o $@.tmp $(OBJECTS) $(LIBS) - $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \ - --add-section=image=../images/vmlinux.gz \ - $@.tmp $@ -# -# then with the offset rebuild the bootloader so we know where the kernel is -# - $(CC) $(CFLAGS) -DINITRD_OFFSET=0 -DINITRD_SIZE=0 \ - -DZIMAGE_OFFSET=`sh $(OFFSET) $(OBJDUMP) $@ image` \ - -DZIMAGE_SIZE=`sh $(SIZE) $(OBJDUMP) $@ image` \ - -c -o misc.o misc.c - $(LD) $(ZLINKFLAGS) -o $@.tmp $(OBJECTS) $(LIBS) - $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \ - --add-section=image=../images/vmlinux.gz \ - $@.tmp ../images/$@.embedded -# Remove zvmlinux and zvmlinux.temp, we have ../images/zvmlinux.embedded - rm -f $@.tmp $@ - -znetboot : zImage - cp ../images/zImage.embedded $(TFTPIMAGE) - -znetboot.initrd : zImage.initrd - cp ../images/zImage.initrd.embedded $(TFTPIMAGE) - -include $(TOPDIR)/Rules.make diff --git a/arch/ppc/boot/mbx/gzimage.c b/arch/ppc/boot/mbx/gzimage.c deleted file mode 100644 index 954e6592b9a8..000000000000 --- a/arch/ppc/boot/mbx/gzimage.c +++ /dev/null @@ -1,11 +0,0 @@ -/* - * BK Id: SCCS/s.gzimage.c 1.6 05/18/01 15:17:06 cort - */ -/* - * gzimage.c - * - * Dummy file to allow a compressed zImage to be added - * into a linker section, accessed by the boot coode - */ - -char dummy_for_gzimage; diff --git a/arch/ppc/boot/mbx/head.S b/arch/ppc/boot/mbx/head.S deleted file mode 100644 index ba26d1360e85..000000000000 --- a/arch/ppc/boot/mbx/head.S +++ /dev/null @@ -1,243 +0,0 @@ -/* - * BK Id: SCCS/s.head.S 1.9 05/18/01 07:54:04 patch - */ -#include <linux/config.h> -#include "../../kernel/ppc_defs.h" -#include "../../kernel/ppc_asm.tmpl" -#include <asm/processor.h> -#include <asm/cache.h> - - .text - -/* - * This code is loaded by the ROM loader at some arbitrary location. - * Move it to high memory so that it can load the kernel at 0x0000. - * - * This is a three step process that will also work when booting from - * a Flash PROM normally located in high memory. - * - * First, the entire image is loaded into some high memory address. - * This is usually at or above 0x02000000. This is done by a network - * boot function supported by the board or a debugger over BDM port. - * - * Second, the start up function here will relocate the decompress - * function to run at the link address of 0x01000000. - * - * Last, the decompression function will reloate the initrd, zImage, and - * the residual data to locations under 8 Meg. This is necessary because - * the embedded kernel start up uses 8 Meg translations to access physical - * space before the MMU is enabled. Finally, the zImage is uncompressed - * to location 0 and we jump to it. - * - * On the MBX, - * R1 - Stack pointer at a high memory address. - * R3 - Pointer to Board Information Block. - * R4 - Pointer to argument string. - * Interrupts masked, cache and MMU disabled. - * - * ...and the first and second functions listed above are - * done for us (it knows ELF images). - * - * For other embedded boards we build the Board Information Block. - */ - - .globl start -start: - bl start_ -start_: -#ifndef CONFIG_MBX - lis r11, local_bd_info@h - ori r11, r11, local_bd_info@l -#else - mr r11, r3 -#endif - - mfmsr r3 /* Turn off interrupts */ - li r4,0 - ori r4,r4,MSR_EE - andc r3,r3,r4 - mtmsr r3 - - li r4,0 /* Zero DER to prevent FRZ */ - mtspr SPRN_DER,r4 - -/* check if we need to relocate ourselves to the link addr or were we - loaded there to begin with -- Cort */ - lis r4,start@h - ori r4,r4,start@l - mflr r3 - subi r3,r3,4 /* we get the nip, not the ip of the branch */ - mr r8,r3 -#if 0 - cmp 0,r3,r4 - beq start_ldr /* Branch if loaded OK */ -#endif - -/* - * no matter where we're loaded, move ourselves to -Ttext address - * This computes the sizes we need to determine other things. - */ - lis r5,end@h - ori r5,r5,end@l - addi r5,r5,3 /* Round up - just in case */ - sub r5,r5,r4 /* Compute # longwords to move */ - srwi r5,r5,2 - mtctr r5 - mr r7,r5 - li r6,0 - subi r3,r3,4 /* Set up for loop */ - subi r4,r4,4 -00: lwzu r5,4(r3) - stwu r5,4(r4) - xor r6,r6,r5 - bdnz 00b - - lis r3,start_ldr@h - ori r3,r3,start_ldr@l - mtlr r3 /* Easiest way to do an absolute jump */ - blr - -start_ldr: -/* Most 8xx boards don't boot up with the I-cache enabled. Do that - * now because the decompress runs much faster that way. - */ - lis r3, IDC_INVALL@h - mtspr IC_CST, r3 - lis r3, IDC_ENABLE@h - mtspr IC_CST, r3 - -/* Clear all of BSS */ - lis r3,edata@h - ori r3,r3,edata@l - lis r4,end@h - ori r4,r4,end@l - subi r3,r3,4 - subi r4,r4,4 - li r0,0 -50: stwu r0,4(r3) - cmp 0,r3,r4 - bne 50b - - lis r1,.stack@h - ori r1,r1,.stack@l - addi r1,r1,4096*2 - subi r1,r1,256 - li r2,0x000F /* Mask pointer to 16-byte boundary */ - andc r1,r1,r2 - - /* Perform configuration of the various boards. This is done - * by reading some configuration data from EEPROM and building - * the board information structure. - */ - mr r3, r11 - mr r21, r11 - mr r22, r8 - mr r23, r7 - mr r24, r6 - - bl embed_config - mr r3, r21 - bl serial_init /* Init MBX serial port */ - - mr r11, r21 - mr r8, r22 - mr r7, r23 - mr r6, r24 - -#ifdef CONFIG_MBX - /* On the MBX (or anything that will TFTP load an ELF image), - * we have to find the intermediate address. The ELF loader - * only moves the Linux boostrap/decompress, not the zImage. - */ -#define ILAP_ADDRESS 0xfa000020 - lis r8, ILAP_ADDRESS@h - lwz r8, ILAP_ADDRESS@l(r8) - addis r8, r8, 1 /* Add 64K */ -#endif - - mr r3,r8 /* Load point */ - mr r4,r7 /* Program length */ - mr r5,r6 /* Checksum */ - mr r6,r11 /* Residual data */ - bl decompress_kernel - - /* changed to use r3 (as firmware does) for kernel - as ptr to residual -- Cort*/ - lis r6,cmd_line@h - ori r6,r6,cmd_line@l - lwz r6, 0(r6) - subi r7,r6,1 -00: lbzu r2,1(r7) - cmpi 0,r2,0 - bne 00b - - /* r4,r5 have initrd_start, size */ - lis r2,initrd_start@h - ori r2,r2,initrd_start@l - lwz r4,0(r2) - lis r2,initrd_end@h - ori r2,r2,initrd_end@l - lwz r5,0(r2) - - /* The world starts from the beginning. - */ - li r9,0x0 - mtlr r9 - - /* Invalidate the instruction cache because we just copied a - * bunch of kernel instructions. - */ - lis r9, IDC_INVALL@h - mtspr IC_CST, r9 - - blr -hang: - b hang - -/* - * Delay for a number of microseconds - * -- Use the BUS timer (assumes 66MHz) - */ - .globl udelay -udelay: - mulli r4,r3,1000 /* nanoseconds */ - addi r4,r4,59 - li r5,60 - divw r4,r4,r5 /* BUS ticks */ -1: mftbu r5 - mftb r6 - mftbu r7 - cmp 0,r5,r7 - bne 1b /* Get [synced] base time */ - addc r9,r6,r4 /* Compute end time */ - addze r8,r5 -2: mftbu r5 - cmp 0,r5,r8 - blt 2b - bgt 3f - mftb r6 - cmp 0,r6,r9 - blt 2b -3: blr - -.globl _get_MSR -_get_MSR: - mfmsr r3 - blr - -.globl _put_MSR -_put_MSR: - mtmsr r3 - blr - - .comm .stack,4096*2,4 -#ifndef CONFIG_MBX -local_bd_info: - .long 0 - .long 0x01000000 - .long 64 - .long 64 - .long 0 - .long 0 - .long 0 -#endif diff --git a/arch/ppc/boot/mbx/head_8260.S b/arch/ppc/boot/mbx/head_8260.S deleted file mode 100644 index 6a063802f677..000000000000 --- a/arch/ppc/boot/mbx/head_8260.S +++ /dev/null @@ -1,259 +0,0 @@ -/* - * BK Id: SCCS/s.head_8260.S 1.8 05/18/01 07:54:04 patch - */ -#include "../../kernel/ppc_defs.h" -#include "../../kernel/ppc_asm.tmpl" -#include <asm/processor.h> -#include <asm/cache.h> - - .text - -/* - * Boot loader philosophy: - * - * ROM loads us to some arbitrary location - * ROM loads these registers: - * - * R3 = Pointer to the board configuration data - * R5 = Pointer to Open Firmware data - * - * ROM jumps to start/start_ - * Move the boot code to the link address (4 MB) - * Call decompress_kernel() - * Relocate the initrd, zimage and residual data to 4 MB - * Decompress the kernel to 0 - * Jump to the kernel entry - * -- Cort - */ - .globl start -start: - bl start_ -start_: - mr r11,r3 /* Save pointer to residual/board data */ - mr r25,r5 /* Save OFW pointer */ - li r3,MSR_IP /* Establish default MSR value */ - mtmsr r3 - -/* check if we need to relocate ourselves to the link addr or were we - loaded there to begin with -- Cort */ - lis r4,start@h - ori r4,r4,start@l - mflr r3 - subi r3,r3,4 /* we get the nip, not the ip of the branch */ - mr r8,r3 - cmp 0,r3,r4 - bne 1010f -/* compute size of whole image in words. this should be moved to - * start_ldr() -- Cort - */ - lis r4,start@h - ori r4,r4,start@l - lis r5,end@h - ori r5,r5,end@l - addi r5,r5,3 /* round up */ - sub r5,r5,r4 - srwi r5,r5,2 - mr r7,r5 - b start_ldr -1010: -/* - * no matter where we're loaded, move ourselves to -Ttext address - */ -relocate: - mflr r3 /* Compute code bias */ - subi r3,r3,4 - mr r8,r3 - lis r4,start@h - ori r4,r4,start@l - lis r5,end@h - ori r5,r5,end@l - addi r5,r5,3 /* Round up - just in case */ - sub r5,r5,r4 /* Compute # longwords to move */ - srwi r5,r5,2 - mtctr r5 - mr r7,r5 - li r6,0 - subi r3,r3,4 /* Set up for loop */ - subi r4,r4,4 -00: lwzu r5,4(r3) - stwu r5,4(r4) - xor r6,r6,r5 - bdnz 00b - lis r3,start_ldr@h - ori r3,r3,start_ldr@l - mtlr r3 /* Easiest way to do an absolute jump */ - blr -start_ldr: -/* Clear all of BSS */ - lis r3,edata@h - ori r3,r3,edata@l - lis r4,end@h - ori r4,r4,end@l - subi r3,r3,4 - subi r4,r4,4 - li r0,0 -50: stwu r0,4(r3) - cmp 0,r3,r4 - bne 50b -90: mr r9,r1 /* Save old stack pointer (in case it matters) */ - lis r1,.stack@h - ori r1,r1,.stack@l - addi r1,r1,4096*2 - subi r1,r1,256 - li r2,0x000F /* Mask pointer to 16-byte boundary */ - andc r1,r1,r2 - - /* Speed us up a little. - */ - bl flush_instruction_cache - -/* Run loader */ - mr r3,r8 /* Load point */ - mr r4,r7 /* Program length */ - mr r5,r6 /* Checksum */ - mr r6,r11 /* Residual data */ - mr r7,r25 /* OFW interfaces */ - bl decompress_kernel - - /* changed to use r3 (as firmware does) for kernel - as ptr to residual -- Cort*/ - lis r6,cmd_line@h - ori r6,r6,cmd_line@l - lwz r6, 0(r6) - subi r7,r6,1 -00: lbzu r2,1(r7) - cmpi 0,r2,0 - bne 00b - - /* r4,r5 have initrd_start, size */ - lis r2,initrd_start@h - ori r2,r2,initrd_start@l - lwz r4,0(r2) - lis r2,initrd_end@h - ori r2,r2,initrd_end@l - lwz r5,0(r2) - - /* tell kernel we're prep */ - /* - * get start address of kernel code which is stored as a coff - * entry. see boot/head.S -- Cort - */ - li r9,0x4 - mtlr r9 - lis r10,0xdeadc0de@h - ori r10,r10,0xdeadc0de@l - li r9,0 - stw r10,0(r9) -/* - * The Radstone firmware maps PCI memory at 0xc0000000 using BAT2 - * so disable BATs before setting this to avoid a clash - */ - li r8,0 - mtspr DBAT0U,r8 - mtspr DBAT1U,r8 - mtspr DBAT2U,r8 - mtspr DBAT3U,r8 - mtspr IBAT0U,r8 - mtspr IBAT1U,r8 - mtspr IBAT2U,r8 - mtspr IBAT3U,r8 - - blr -hang: - b hang - -/* - * Delay for a number of microseconds - * -- Use the BUS timer (assumes 66MHz) - */ - .globl udelay -udelay: - mfspr r4,PVR - srwi r4,r4,16 - cmpi 0,r4,1 /* 601 ? */ - bne .udelay_not_601 -00: li r0,86 /* Instructions / microsecond? */ - mtctr r0 -10: addi r0,r0,0 /* NOP */ - bdnz 10b - subic. r3,r3,1 - bne 00b - blr - -.udelay_not_601: - mulli r4,r3,1000 /* nanoseconds */ - addi r4,r4,59 - li r5,60 - divw r4,r4,r5 /* BUS ticks */ -1: mftbu r5 - mftb r6 - mftbu r7 - cmp 0,r5,r7 - bne 1b /* Get [synced] base time */ - addc r9,r6,r4 /* Compute end time */ - addze r8,r5 -2: mftbu r5 - cmp 0,r5,r8 - blt 2b - bgt 3f - mftb r6 - cmp 0,r6,r9 - blt 2b -3: blr - -.globl _get_HID0 -_get_HID0: - mfspr r3,HID0 - blr - -.globl _put_HID0 -_put_HID0: - mtspr HID0,r3 - blr - -.globl _get_MSR -_get_MSR: - mfmsr r3 - blr - -.globl _put_MSR -_put_MSR: - mtmsr r3 - blr - -/* - * Flush instruction cache - * *** I'm really paranoid here! - */ -_GLOBAL(flush_instruction_cache) - mflr r5 - bl flush_data_cache - mfspr r3,HID0 /* Caches are controlled by this register */ - li r4,0 - ori r4,r4,(HID0_ICE|HID0_ICFI) - or r3,r3,r4 /* Need to enable+invalidate to clear */ - mtspr HID0,r3 - andc r3,r3,r4 - ori r3,r3,HID0_ICE /* Enable cache */ - mtspr HID0,r3 - mtlr r5 - blr - -#define NUM_CACHE_LINES 128*8 -#define CACHE_LINE_SIZE 32 -#define cache_flush_buffer 0x1000 - -/* - * Flush data cache - * *** I'm really paranoid here! - */ -_GLOBAL(flush_data_cache) - lis r3,cache_flush_buffer@h - ori r3,r3,cache_flush_buffer@l - li r4,NUM_CACHE_LINES - mtctr r4 -00: lwz r4,0(r3) - addi r3,r3,CACHE_LINE_SIZE /* Next line, please */ - bdnz 00b -10: blr - .comm .stack,4096*2,4 diff --git a/arch/ppc/boot/mbx/misc.c b/arch/ppc/boot/mbx/misc.c deleted file mode 100644 index 09adb1ed78d2..000000000000 --- a/arch/ppc/boot/mbx/misc.c +++ /dev/null @@ -1,265 +0,0 @@ -/* - * BK Id: SCCS/s.misc.c 1.13 07/27/01 11:44:37 trini - */ -/* - * Adapted for PowerPC by Gary Thomas - * - * Rewritten by Cort Dougan (cort@cs.nmt.edu) - * One day to be replaced by a single bootloader for chrp/prep/pmac. -- Cort - */ - -#include <linux/config.h> -#include <linux/types.h> -#include "zlib.h" -#include <asm/residual.h> -#include <linux/elf.h> -#include <asm/page.h> -#include <asm/processor.h> -#include <asm/mmu.h> -#ifdef CONFIG_8xx -#include <asm/mpc8xx.h> -#endif -#ifdef CONFIG_8260 -#include <asm/mpc8260.h> -#endif - -#include "nonstdio.h" - -/* - * The following references are needed to cause the linker to pull in the - * gzimage.o and rdimage.o files. These object files are special, - * since they get placed into the .gzimage and .rdimage ELF sections - * of the zvmlinux and zvmlinux.initrd files. - */ -extern char dummy_for_gzimage; -extern char dummy_for_rdimage; - -/* - * Please send me load/board info and such data for hardware not - * listed here so I can keep track since things are getting tricky - * with the different load addrs with different firmware. This will - * help to avoid breaking the load/boot process. - * -- Cort - */ -char *avail_ram; -char *end_avail; - -/* See comment below..... -*/ -unsigned int initrd_offset, initrd_size; - -/* Because of the limited amount of memory on embedded, it presents - * loading problems. The biggest is that we load this boot program - * into a relatively low memory address, and the Linux kernel Bss often - * extends into this space when it get loaded. When the kernel starts - * and zeros the BSS space, it also writes over the information we - * save here and pass to the kernel (command line and board info). - * On these boards, we grab some known memory holes to hold this information. - */ -char cmd_buf[256]; -char *cmd_line = cmd_buf; - -/* We need to pass along a 'dummy' com_port. */ -unsigned long com_port = 0; - -/* This is the default cmdline that will be given to the user at boot time.. - * If none was specified at compile time, we'll give it one that should work. - * -- Tom */ -#ifdef CONFIG_CMDLINE_BOOL -char compiled_string[] = CONFIG_CMDLINE; -#endif -char ramroot_string[] = "root=/dev/ram"; -char netroot_string[] = "root=/dev/nfs rw"; - -bd_t hold_resid_buf; -bd_t *hold_residual = &hold_resid_buf; -unsigned long initrd_start = 0, initrd_end = 0; -char *zimage_start; -int zimage_size; - -extern void gunzip(void *, int, unsigned char *, int *); - -unsigned long -decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum, bd_t *bp) -{ - int timer; - extern unsigned long start; - char *cp, ch; - -#ifdef CONFIG_8260 - /* I don't know why I didn't do it this way on the 8xx....... - */ - embed_config(&bp); - serial_init(bp); -#endif - - /* These values must be variables. If not, the compiler optimizer - * will remove some code, causing the size of the code to vary - * when these values are zero. This is bad because we first - * compile with these zero to determine the size and offsets - * in an image, than compile again with these set to the proper - * discovered value.....Ya know, we used to read these from the - * header a long time ago..... - */ - initrd_offset = INITRD_OFFSET; - initrd_size = INITRD_SIZE; - - /* Grab some space for the command line and board info. Since - * we no longer use the ELF header, but it was loaded, grab - * that space. - */ -#ifdef CONFIG_MBX - cmd_line = (char *)(load_addr - 0x10000); - - /* To be like everyone else, we need one too, although this - * board information is passed from the boot rom. - */ - bp->bi_baudrate = 9600; -#else - cmd_line = (char *)(0x200000); -#endif - hold_residual = (bd_t *)(cmd_line + sizeof(cmd_buf)); - /* copy board data */ - if (bp) - memcpy(hold_residual,bp,sizeof(bd_t)); - - /* Set end of memory available to us. It is always the highest - * memory address provided by the board information. - */ - end_avail = (char *)(bp->bi_memsize); - - puts("loaded at: "); puthex(load_addr); - puts(" "); puthex((unsigned long)(load_addr + (4*num_words))); puts("\n"); - if ( (unsigned long)load_addr != (unsigned long)&start ) - { - puts("relocated to: "); puthex((unsigned long)&start); - puts(" "); - puthex((unsigned long)((unsigned long)&start + (4*num_words))); - puts("\n"); - } - - if ( bp ) - { - puts("board data at: "); puthex((unsigned long)bp); - puts(" "); - puthex((unsigned long)((unsigned long)bp + sizeof(bd_t))); - puts("\n"); - puts("relocated to: "); - puthex((unsigned long)hold_residual); - puts(" "); - puthex((unsigned long)((unsigned long)hold_residual + sizeof(bd_t))); - puts("\n"); - } - - /* we have to subtract 0x10000 here to correct for objdump including the - size of the elf header which we strip -- Cort */ - zimage_start = (char *)(load_addr - 0x10000 + ZIMAGE_OFFSET); - zimage_size = ZIMAGE_SIZE; - - if ( initrd_offset ) - initrd_start = load_addr - 0x10000 + initrd_offset; - else - initrd_start = 0; - initrd_end = initrd_size + initrd_start; - - /* - * setup avail_ram - this is the first part of ram usable - * by the uncompress code. -- Cort - */ - avail_ram = (char *)PAGE_ALIGN((unsigned long)zimage_start+zimage_size); - if ( ((load_addr+(num_words*4)) > (unsigned long) avail_ram) - && (load_addr <= 0x01000000) ) - avail_ram = (char *)(load_addr+(num_words*4)); - if ( (((unsigned long)&start+(num_words*4)) > (unsigned long) avail_ram) - && (load_addr <= 0x01000000) ) - avail_ram = (char *)((unsigned long)&start+(num_words*4)); - - /* relocate zimage */ - puts("zimage at: "); puthex((unsigned long)zimage_start); - puts(" "); puthex((unsigned long)(zimage_size+zimage_start)); puts("\n"); - /* - * There is no reason (yet) to relocate zImage for embedded boards. - * To support boot from flash rom on 8xx embedded boards, I - * assume if zimage start is over 16M we are booting from flash. - * In this case, avilable ram will start just above the space we - * have allocated for the command buffer and board information. - */ - if ((unsigned long)zimage_start > 0x01000000) - avail_ram = (char *)PAGE_ALIGN((unsigned long)hold_residual + sizeof(bd_t)); - - /* relocate initrd */ - if ( initrd_start ) - { - puts("initrd at: "); puthex(initrd_start); - puts(" "); puthex(initrd_end); puts("\n"); - - /* We only have to relocate initrd if we find it is in Flash - * rom. This is because the kernel thinks it can toss the - * pages into the free memory pool after it is done. Use - * the same 16M test. - */ - if ((unsigned long)initrd_start > 0x01000000) { - memcpy ((void *)PAGE_ALIGN(-PAGE_SIZE+(unsigned long)end_avail-INITRD_SIZE), - (void *)initrd_start, - initrd_size ); - initrd_start = PAGE_ALIGN(-PAGE_SIZE+(unsigned long)end_avail-INITRD_SIZE); - initrd_end = initrd_start + initrd_size; - end_avail = (char *)initrd_start; - puts("relocated to: "); puthex(initrd_start); - puts(" "); puthex(initrd_end); puts("\n"); - } - else { - avail_ram = (char *)PAGE_ALIGN((unsigned long)initrd_end); - } - } - - - puts("avail ram: "); puthex((unsigned long)avail_ram); puts(" "); - puthex((unsigned long)end_avail); puts("\n"); - puts("\nLinux/PPC load: "); - timer = 0; - cp = cmd_line; - /* This is where we try and pick the right command line for booting. - * If we were given one at compile time, use it. It Is Right. - * If we weren't, see if we have a ramdisk. If so, thats root. - * When in doubt, give them the netroot (root=/dev/nfs rw) -- Tom */ -#ifdef CONFIG_CMDLINE_BOOL - memcpy (cmd_line, compiled_string, sizeof(compiled_string)); -#else - if (initrd_start) - memcpy (cmd_line, ramroot_string, sizeof(ramroot_string)); - else - memcpy (cmd_line, netroot_string, sizeof(netroot_string)); -#endif - while ( *cp ) putc(*cp++); - while (timer++ < 5*1000) { - if (tstc()) { - while ((ch = getc()) != '\n' && ch != '\r') { - if (ch == '\b' || ch == '\177') { - if (cp != cmd_line) { - cp--; - puts("\b \b"); - } - } else if (ch == '\030' /* ^x */ - || ch == '\025') { /* ^u */ - while (cp != cmd_line) { - cp--; - puts("\b \b"); - } - } else { - *cp++ = ch; - putc(ch); - } - } - break; /* Exit 'timer' loop */ - } - udelay(1000); /* 1 msec */ - } - *cp = 0; - puts("\nUncompressing Linux..."); - - gunzip(0, 0x400000, zimage_start, &zimage_size); - puts("done.\n"); - puts("Now booting the kernel\n"); - return (unsigned long)hold_residual; -} diff --git a/arch/ppc/boot/mbx/rdimage.c b/arch/ppc/boot/mbx/rdimage.c deleted file mode 100644 index ffc577ec8e8d..000000000000 --- a/arch/ppc/boot/mbx/rdimage.c +++ /dev/null @@ -1,11 +0,0 @@ -/* - * BK Id: SCCS/s.rdimage.c 1.6 05/18/01 15:17:06 cort - */ -/* - * rdimage.c - * - * Dummy file to allow a compressed initrd to be added - * into a linker section, accessed by the boot coode - */ - -char dummy_for_rdimage; diff --git a/arch/ppc/boot/pmac/Makefile b/arch/ppc/boot/pmac/Makefile index e7dd1dfc36ab..8277856ce0f2 100644 --- a/arch/ppc/boot/pmac/Makefile +++ b/arch/ppc/boot/pmac/Makefile @@ -1,4 +1,4 @@ -# BK Id: SCCS/s.Makefile 1.14 07/27/01 20:24:17 trini +# BK Id: %F% %I% %G% %U% %#% # # Makefile for making XCOFF bootable images for booting on PowerMacs # using Open Firmware. @@ -9,10 +9,10 @@ # Tom Rini January 2001 OBJCOPY_ARGS = -O aixcoff-rs6000 -R .stab -R .stabstr -R .comment -COFF_LD_ARGS = -e _start -T ld.script -Ttext 500000 -Tdata 510000 -Bstatic -CHRP_LD_ARGS = -Ttext 0x01000000 +COFF_LD_ARGS = -T ../ld.script -e _start -Ttext 0x00500000 -Bstatic +CHRP_LD_ARGS = -T ../ld.script -Ttext 0x01000000 -COMMONOBJS = start.o misc.o ../common/string.o image.o ../common/ofcommon.o +COMMONOBJS = start.o misc.o ../common/string.o ../common/ofcommon.o COFFOBJS = ../common/coffcrt0.o $(COMMONOBJS) coffmain.o CHRPOBJS = ../common/crt0.o $(COMMONOBJS) chrpmain.o LIBS = $(TOPDIR)/lib/lib.a ../lib/zlib.a @@ -20,62 +20,58 @@ LIBS = $(TOPDIR)/lib/lib.a ../lib/zlib.a MKNOTE := ../utils/mknote SIZE := ../utils/size OFFSET := ../utils/offset -PIGGYBACK := ../utils/piggyback HACKCOFF := ../utils/hack-coff -ifeq ($(CONFIG_PPC64BRIDGE),y) -MSIZE=.64 -else -MSIZE= +ifdef CONFIG_SMP +END := .smp endif - -ifeq ($(CONFIG_SMP),y) -TFTPIMAGE=/tftpboot/zImage.pmac.smp$(MSIZE) -else -TFTPIMAGE=/tftpboot/zImage.pmac$(MSIZE) +ifdef CONFIG_PPC64BRIDGE +END += .64 endif -../common/crt0.o: - $(MAKE) -C ../common crt0.o +TFTPIMAGE=/tftpboot/zImage.pmac$(END) ../common/coffcrt0.o: $(MAKE) -C ../common coffcrt0.o -chrpmain.o: chrpmain.c - $(CC) $(CFLAGS) -DSYSMAP_OFFSET=0 -DSYSMAP_SIZE=0 -c chrpmain.c +image.o: ../images/vmlinux.gz ../common/dummy.o + $(OBJCOPY) ../common/dummy.o $@ -R .comment \ + --add-section=.image=../images/vmlinux.gz \ + --set-section-flags=.image=contents,alloc,load,readonly,data +ifdef CONFIG_XMON + $(OBJCOPY) $@ $@ \ + --add-section=.sysmap=$(TOPDIR)/System.map \ + --set-section-flags=.sysmap=contents,alloc,load,readonly,data +endif znetboot: vmlinux.coff vmlinux.elf-pmac zImage cp ../images/vmlinux.coff $(TFTPIMAGE) cp ../images/vmlinux.elf-pmac $(TFTPIMAGE).elf -znetboot.initrd: vmlinux.coff.initrd vmlinux.initrd.elf-pmac - cp ../images/vmlinux.coff.initrd $(TFTPIMAGE) - cp ../images/vmlinux.elf-pmac.initrd $(TFTPIMAGE).elf +znetboot.initrd: vmlinux.initrd.coff vmlinux.initrd.elf-pmac + cp ../images/vmlinux.initrd.coff $(TFTPIMAGE) + cp ../images/vmlinux.initrd.elf-pmac $(TFTPIMAGE).elf -#floppy: zImage -# mount -t hfs /dev/fd0 /mnt -# cp vmlinux.coff /mnt -# umount /mnt - -miboot.image: dummy.o ../images/vmlinux.gz +miboot.image: ../common/dummy.o ../images/vmlinux.gz $(OBJCOPY) $(OBJCOPY_ARGS) --add-section=image=../images/vmlinux.gz \ - dummy.o ../images/$@ + ../common/dummy.o ../images/$@ -miboot.image.initrd: miboot.image ../images/ramdisk.image.gz +miboot.initrd.image: miboot.image ../images/ramdisk.image.gz $(OBJCOPY) $(OBJCOPY_ARGS) --add-section=initrd=../images/ramdisk.image.gz \ ../images/miboot.image ../images/$@ -coffboot: $(COFFOBJS) $(LIBS) ../common/no_initrd.o ld.script ../images/vmlinux.gz - $(LD) -o $@ $(COFF_LD_ARGS) $(COFFOBJS) ../common/no_initrd.o $(LIBS) - -coffboot.initrd: $(COFFOBJS) $(LIBS) initrd.o ld.script ../images/vmlinux.gz - $(LD) -o $@ $(COFF_LD_ARGS) $(COFFOBJS) initrd.o $(LIBS) +coffboot: $(COFFOBJS) image.o $(LIBS) ../ld.script + $(LD) -o $@ $(COFF_LD_ARGS) $(COFFOBJS) image.o $(LIBS) + $(OBJCOPY) $@ $@ -R .comment -image.o: $(PIGGYBACK) ../images/vmlinux.gz - $(PIGGYBACK) image < ../images/vmlinux.gz | $(AS) -o $@ - -initrd.o: ../images/ramdisk.image.gz $(PIGGYBACK) - $(PIGGYBACK) initrd < ../images/ramdisk.image.gz | $(AS) -o $@ +coffboot.initrd: $(COFFOBJS) image.o $(LIBS) ../ld.script \ + ../images/ramdisk.image.gz + $(OBJCOPY) image.o image-coff.o \ + --add-section=.ramdisk=../images/ramdisk.image.gz \ + --set-section-flags=.ramdisk=contents,alloc,load,readonly,data + $(LD) -o $@ $(COFF_LD_ARGS) $(COFFOBJS) image-coff.o $(LIBS) + $(OBJCOPY) $@ $@ -R .comment + rm -f image-coff.o vmlinux.coff: coffboot $(HACKCOFF) $(OBJCOPY) $(OBJCOPY_ARGS) coffboot ../images/$@ @@ -83,33 +79,32 @@ vmlinux.coff: coffboot $(HACKCOFF) rm -f coffboot ln -sf vmlinux.coff ../images/zImage.pmac -vmlinux.coff.initrd: coffboot.initrd $(HACKCOFF) +vmlinux.initrd.coff: coffboot.initrd $(HACKCOFF) $(OBJCOPY) $(OBJCOPY_ARGS) coffboot.initrd ../images/$@ $(HACKCOFF) ../images/$@ rm -f coffboot.initrd - ln -sf vmlinux.coff.initrd ../images/zImage.initrd.pmac + ln -sf vmlinux.initrd.coff ../images/zImage.initrd.pmac -vmlinux.elf-pmac: $(CHRPOBJS) $(LIBS) ../common/no_initrd.o $(MKNOTE) ../images/vmlinux.gz - $(LD) $(CHRP_LD_ARGS) -o ../images/$@ $(CHRPOBJS) ../common/no_initrd.o $(LIBS) +vmlinux.elf-pmac: $(CHRPOBJS) $(LIBS) $(MKNOTE) image.o + $(LD) $(CHRP_LD_ARGS) -o ../images/$@ $(CHRPOBJS) $(LIBS) image.o $(MKNOTE) > note $(OBJCOPY) ../images/$@ ../images/$@ --add-section=.note=note \ - --add-section=sysmap=$(TOPDIR)/System.map -R .comment - $(CC) $(CFLAGS) chrpmain.c -c -o chrpmain.o \ - -DSYSMAP_OFFSET=`sh $(OFFSET) $(OBJDUMP) ../images/$@ sysmap` \ - -DSYSMAP_SIZE=`sh $(SIZE) $(OBJDUMP) ../images/$@ sysmap` - $(LD) $(CHRP_LD_ARGS) -o ../images/$@ $(CHRPOBJS) ../common/no_initrd.o $(LIBS) - $(OBJCOPY) ../images/$@ ../images/$@ --add-section=.note=note \ - --add-section=sysmap=$(TOPDIR)/System.map -R .comment + -R .comment -R .ramdisk rm -f note -vmlinux.initrd.elf-pmac: $(CHRPOBJS) $(LIBS) initrd.o $(MKNOTE) ../images/vmlinux.gz - $(LD) $(CHRP_LD_ARGS) -o ../images/$@ $(CHRPOBJS) initrd.o $(LIBS) +vmlinux.initrd.elf-pmac: $(CHRPOBJS) $(LIBS) $(MKNOTE) image.o \ + ../images/ramdisk.image.gz + $(OBJCOPY) image.o image-elf.o \ + --add-section=.ramdisk=../images/ramdisk.image.gz \ + --set-section-flags=.ramdisk=contents,alloc,load,readonly,data + $(LD) $(CHRP_LD_ARGS) -o ../images/$@ $(CHRPOBJS) $(LIBS) image-elf.o $(MKNOTE) > note - $(OBJCOPY) ../images/$@ ../images/$@ --add-section=.note=note -R .comment - rm -f note + $(OBJCOPY) ../images/$@ ../images/$@ --add-section=.note=note \ + -R .comment + rm -f note image-elf.o zImage: vmlinux.coff vmlinux.elf-pmac miboot.image -zImage.initrd: vmlinux.coff.initrd vmlinux.initrd.elf-pmac miboot.image.initrd +zImage.initrd: vmlinux.initrd.coff vmlinux.initrd.elf-pmac miboot.initrd.image include $(TOPDIR)/Rules.make diff --git a/arch/ppc/boot/pmac/chrpmain.c b/arch/ppc/boot/pmac/chrpmain.c index 645a954e3927..407fff6a4bc2 100644 --- a/arch/ppc/boot/pmac/chrpmain.c +++ b/arch/ppc/boot/pmac/chrpmain.c @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.chrpmain.c 1.16 07/27/01 20:24:18 trini + * BK Id: %F% %I% %G% %U% %#% */ /* * Copyright (C) Paul Mackerras 1997. @@ -10,15 +10,17 @@ * 2 of the License, or (at your option) any later version. */ #include "nonstdio.h" -#include "zlib.h" #include <asm/processor.h> +#include <asm/page.h> + +/* Passed from the linker */ +extern char __image_begin, __image_end; +extern char __ramdisk_begin[], __ramdisk_end; +extern char _start, _end; -extern char _end[]; -extern char image_data[], initrd_data[]; -extern int image_len, initrd_len; extern int getprop(void *, const char *, void *, int); extern unsigned int heap_max; -extern void *claim(unsigned int, unsigned int, unsigned int); +extern void *claim(unsigned int virt, unsigned int size, unsigned int align); extern void *finddevice(const char *); extern void flush_cache(void *start, unsigned int len); extern void gunzip(void *, int, unsigned char *, int *); @@ -45,21 +47,23 @@ void boot(int a1, int a2, void *prom) void *dst; unsigned char *im; unsigned initrd_start, initrd_size; - extern char _start; printf("chrpboot starting: loaded at 0x%p\n", &_start); - if (initrd_len) { - initrd_size = initrd_len; + + initrd_size = (char *)(&__ramdisk_end) - (char *)(&__ramdisk_begin); + if (initrd_size) { initrd_start = (RAM_END - initrd_size) & ~0xFFF; a1 = initrd_start; a2 = initrd_size; claim(initrd_start, RAM_END - initrd_start, 0); - printf("initial ramdisk moving 0x%x <- 0x%p (%x bytes)\n", initrd_start, - initrd_data,initrd_size); - memcpy((char *)initrd_start, initrd_data, initrd_size); - } - im = image_data; - len = image_len; + printf("initial ramdisk moving 0x%x <- 0x%p (%x bytes)\n\r", + initrd_start, (char *)(&__ramdisk_begin), initrd_size); + memcpy((char *)initrd_start, (char *)(&__ramdisk_begin), initrd_size); + } else + a2 = 0xdeadbeef; + + im = (char *)(&__image_begin); + len = (char *)(&__image_end) - (char *)(&__image_begin); /* claim 3MB starting at PROG_START */ claim(PROG_START, PROG_SIZE, 0); dst = (void *) PROG_START; diff --git a/arch/ppc/boot/pmac/coffmain.c b/arch/ppc/boot/pmac/coffmain.c index 07702b0104f3..76252faf1f11 100644 --- a/arch/ppc/boot/pmac/coffmain.c +++ b/arch/ppc/boot/pmac/coffmain.c @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.coffmain.c 1.14 07/27/01 20:24:18 trini + * BK Id: %F% %I% %G% %U% %#% */ /* * Copyright (C) Paul Mackerras 1997. @@ -9,11 +9,17 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */ +#include <asm/processor.h> +#include <asm/page.h> + #include "nonstdio.h" #include "zlib.h" -#include <asm/processor.h> -extern char _start[], _end[]; +/* Passed from the linker */ +extern char __image_begin, __image_end; +extern char __ramdisk_begin[], __ramdisk_end; +extern char _start, _end; + extern char *claim(unsigned, unsigned, unsigned); extern char image_data[], initrd_data[]; extern int initrd_len, image_len; @@ -50,18 +56,21 @@ void boot(int a1, int a2, void *prom) printf("coffboot starting: loaded at 0x%p\n", &_start); setup_bats(RAM_START); - if (initrd_len) { - initrd_size = initrd_len; + + initrd_size = (char *)(&__ramdisk_end) - (char *)(&__ramdisk_begin); + if (initrd_size) { initrd_start = (RAM_END - initrd_size) & ~0xFFF; a1 = initrd_start; a2 = initrd_size; - claim(initrd_start - RAM_START, RAM_END - initrd_start, 0); - printf("initial ramdisk moving 0x%x <- 0x%p (%x bytes)\n", - initrd_start, initrd_data, initrd_size); - memcpy((char *)initrd_start, initrd_data, initrd_size); - } - im = image_data; - len = image_len; + claim(initrd_start, RAM_END - initrd_start, 0); + printf("initial ramdisk moving 0x%x <- 0x%p (%x bytes)\n\r", + initrd_start, (char *)(&__ramdisk_begin), initrd_size); + memcpy((char *)initrd_start, (char *)(&__ramdisk_begin), initrd_size); + } else + a2 = 0xdeadbeef; + + im = (char *)(&__image_begin); + len = (char *)(&__image_end) - (char *)(&__image_begin); /* claim 4MB starting at 0 */ claim(0, PROG_SIZE, 0); dst = (void *) RAM_START; diff --git a/arch/ppc/boot/pmac/dummy.c b/arch/ppc/boot/pmac/dummy.c deleted file mode 100644 index a35ff8f451e8..000000000000 --- a/arch/ppc/boot/pmac/dummy.c +++ /dev/null @@ -1,7 +0,0 @@ -/* - * BK Id: SCCS/s.dummy.c 1.6 05/18/01 15:17:15 cort - */ -int main(void) -{ - return 0; -} diff --git a/arch/ppc/boot/prep/Makefile b/arch/ppc/boot/prep/Makefile index f740c82ab901..fff896023e9c 100644 --- a/arch/ppc/boot/prep/Makefile +++ b/arch/ppc/boot/prep/Makefile @@ -1,4 +1,4 @@ -# BK Id: SCCS/s.Makefile 1.26 09/25/01 07:54:40 trini +# BK Id: %F% %I% %G% %U% %#% # # arch/ppc/boot/Makefile # @@ -17,16 +17,15 @@ USE_STANDARD_AS_RULE := true -ifeq ($(CONFIG_SMP),y) -TFTPIMAGE = /tftpboot/zImage.prep.smp -else TFTPIMAGE = /tftpboot/zImage.prep +ifeq ($(CONFIG_SMP),y) +TFTPIMAGE = $(TFTPBOOT).smp endif -ZLINKFLAGS = -T $(TOPDIR)/arch/$(ARCH)/vmlinux.lds \ - -Ttext 0x00800000 -obj-y := head.o misc.o ../common/misc-common.o \ - ../common/string.o of1275.o +LD_ARGS = -T ../ld.script -Ttext 0x00800000 -Bstatic +obj-y := head.o ../simple/legacy.o misc.o of1275.o \ + ../common/util.o ../common/string.o \ + ../common/misc-common.o OBJCOPY_ARGS = -O elf32-powerpc LIBS = ../lib/zlib.a @@ -38,57 +37,34 @@ MKPREP := ../utils/mkprep SIZE := ../utils/size OFFSET := ../utils/offset -all: zImage +# Extra include search dirs +CFLAGS_kbd.o += -I$(TOPDIR)/drivers/char -misc.o: misc.c - $(CC) $(CFLAGS) -DINITRD_OFFSET=0 -DINITRD_SIZE=0 -DZIMAGE_OFFSET=0 \ - -DZIMAGE_SIZE=0 -c -o $@ $*.c +all: zImage -zvmlinux.initrd: $(obj-y) $(LIBS) ../images/vmlinux.gz - $(LD) $(ZLINKFLAGS) -o $@.tmp $(obj-y) $(LIBS) - $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \ - --add-section=initrd=../images/ramdisk.image.gz \ - --add-section=image=../images/vmlinux.gz \ - $@.tmp $@ - $(CC) $(CFLAGS) -DINITRD_OFFSET=`sh $(OFFSET) $(OBJDUMP) $@ initrd` \ - -DINITRD_SIZE=`sh $(SIZE) $(OBJDUMP) $@ initrd` \ - -DZIMAGE_OFFSET=`sh $(OFFSET) $(OBJDUMP) $@ image` \ - -DZIMAGE_SIZE=`sh $(SIZE) $(OBJDUMP) $@ image` \ - -c -o misc.o misc.c - $(LD) $(ZLINKFLAGS) -o $@.tmp $(obj-y) $(LIBS) +zImage: $(obj-y) $(LIBS) ../ld.script ../images/vmlinux.gz ../common/dummy.o \ + $(MKPREP) $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \ - --add-section=initrd=../images/ramdisk.image.gz \ - --add-section=image=../images/vmlinux.gz \ - $@.tmp $@ - rm -f $@.tmp zvmlinux - -zImage: zvmlinux $(MKPREP) - $(MKPREP) -pbp zvmlinux ../images/$@.prep - rm -f zvmlinux - -zImage.initrd: zvmlinux.initrd $(MKPREP) - $(MKPREP) -pbp zvmlinux.initrd ../images/$@.prep - rm -f zvmlinux.initrd + --add-section=.image=../images/vmlinux.gz \ + --set-section-flags=.image=contents,alloc,load,readonly,data \ + ../common/dummy.o image.o + $(LD) $(LD_ARGS) -o $@ $(obj-y) image.o $(LIBS) + $(OBJCOPY) $(OBJCOPY_ARGS) $@ $@ -R .comment -R .stab -R .stabstr + $(MKPREP) -pbp $@ ../images/$@.prep + rm -f $@ -zvmlinux: $(obj-y) $(LIBS) ../images/vmlinux.gz -# -# build the boot loader image and then compute the offset into it -# for the kernel image -# - $(LD) $(ZLINKFLAGS) -o zvmlinux.tmp $(obj-y) $(LIBS) - $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \ - --add-section=image=../images/vmlinux.gz zvmlinux.tmp $@ -# -# then with the offset rebuild the bootloader so we know where the kernel is -# - $(CC) $(CFLAGS) -DINITRD_OFFSET=0 -DINITRD_SIZE=0 \ - -DZIMAGE_OFFSET=`sh $(OFFSET) $(OBJDUMP) zvmlinux image` \ - -DZIMAGE_SIZE=`sh $(SIZE) $(OBJDUMP) zvmlinux image` \ - -c -o misc.o misc.c - $(LD) $(ZLINKFLAGS) -o zvmlinux.tmp $(obj-y) $(LIBS) +zImage.initrd: $(obj-y) $(LIBS) ../ld.script ../images/vmlinux.gz $(MKPREP) \ + ../common/dummy.o $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \ - --add-section=image=../images/vmlinux.gz $@.tmp $@ - rm $@.tmp + --add-section=.ramdisk=../images/ramdisk.image.gz \ + --set-section-flags=.ramdisk=contents,alloc,load,readonly,data \ + --add-section=.image=../images/vmlinux.gz \ + --set-section-flags=.image=contents,alloc,load,readonly,data \ + ../common/dummy.o image.o + $(LD) $(LD_ARGS) -o $@ $(obj-y) image.o $(LIBS) + $(OBJCOPY) $(OBJCOPY_ARGS) $@ $@ -R .comment -R .stab -R .stabstr + $(MKPREP) -pbp $@ ../images/$@.prep + rm -f $@ floppy: zImage dd if=../images/zImage.prep of=/dev/fd0H1440 bs=64b diff --git a/arch/ppc/boot/prep/head.S b/arch/ppc/boot/prep/head.S index 573475baf7df..05935a668182 100644 --- a/arch/ppc/boot/prep/head.S +++ b/arch/ppc/boot/prep/head.S @@ -1,8 +1,8 @@ /* - * BK Id: SCCS/s.head.S 1.11 07/31/01 16:36:06 trini + * BK Id: %F% %I% %G% %U% %#% */ -#include "../../kernel/ppc_defs.h" -#include "../../kernel/ppc_asm.tmpl" + +#include <asm/ppc_asm.h> #include <asm/processor.h> #include <asm/cache.h> @@ -22,34 +22,49 @@ start: bl start_ start_: + + /* Enable, invalidate, Disable L1 icache/dcache */ + li r8, 0 + ori r8, r8, (HID0_ICE|HID0_DCE|HID0_ICFI|HID0_DCI) + mfspr r11,HID0 + or r11,r11,r8 + andc r10,r11,r8 + isync + mtspr HID0,r8 + sync + isync + mtspr HID0,r10 + sync + isync + mr r11,r3 /* Save pointer to residual/board data */ - mr r25,r5 /* Save OFW pointer */ - li r3,MSR_IP /* Establish default MSR value */ + mr r25,r5 /* Save OFW pointer */ + + /* Save the original MSR value */ + mfmsr r26 + + /* Establish default MSR value */ + li r3,MSR_IP|MSR_FP mtmsr r3 -/* check if we need to relocate ourselves to the link addr or were we - loaded there to begin with -- Cort */ - lis r4,start@h - ori r4,r4,start@l - mflr r3 - subi r3,r3,4 /* we get the nip, not the ip of the branch */ - mr r8,r3 - cmp 0,r3,r4 - bne 1010f -/* compute size of whole image in words. this should be moved to - * start_ldr() -- Cort - */ + /* compute the size of the whole image in words. */ lis r4,start@h ori r4,r4,start@l lis r5,end@h ori r5,r5,end@l addi r5,r5,3 /* round up */ - sub r5,r5,r4 + sub r5,r5,r4 /* end - start */ srwi r5,r5,2 - mr r7,r5 - b start_ldr -1010: -/* + mr r7,r5 /* Save for later use. */ + + /* check if we need to relocate ourselves to the link addr or were + * we loaded there to begin with -- Cort */ + mflr r3 + subi r3,r3,4 /* we get the nip, not the ip of the branch */ + mr r8,r3 + cmp 0,r3,r4 + beq start_ldr /* If 0, we don't need to relocate */ +/* * no matter where we're loaded, move ourselves to -Ttext address */ relocate: @@ -58,15 +73,10 @@ relocate: mr r8,r3 lis r4,start@h ori r4,r4,start@l - lis r5,end@h - ori r5,r5,end@l - addi r5,r5,3 /* Round up - just in case */ - sub r5,r5,r4 /* Compute # longwords to move */ - srwi r5,r5,2 - mtctr r5 - mr r7,r5 + mr r5,r7 /* Get the # of longwords again */ + mtctr r5 /* Setup for loop */ li r6,0 - subi r3,r3,4 /* Set up for loop */ + subi r3,r3,4 subi r4,r4,4 00: lwzu r5,4(r3) stwu r5,4(r4) @@ -74,9 +84,17 @@ relocate: bdnz 00b lis r3,start_ldr@h ori r3,r3,start_ldr@l - mtlr r3 /* Easiest way to do an absolute jump */ + mtlr r3 /* Easiest way to do an absolute jump */ blr + start_ldr: +/* Some boards don't boot up with the I-cache enabled. Do that + * now because the decompress runs much faster that way. + * As a side effect, we have to ensure the data cache is not enabled + * so we can access the serial I/O without trouble. + */ + bl flush_instruction_cache + /* Clear all of BSS */ lis r3,edata@h ori r3,r3,edata@l @@ -95,11 +113,12 @@ start_ldr: subi r1,r1,256 li r2,0x000F /* Mask pointer to 16-byte boundary */ andc r1,r1,r2 -/* Setup ISA_io */ - lis r3,ISA_io@h - ori r3,r3,ISA_io@l - lis r4,0x8000 - stw r4,0(r3) + + /* Store the original MSR into 'orig_MSR' */ + lis r3,orig_MSR@h + ori r3,r3,orig_MSR@l + stw r26,0(r3) + /* Run loader */ mr r3,r8 /* Load point */ mr r4,r7 /* Program length */ @@ -107,147 +126,61 @@ start_ldr: mr r6,r11 /* Residual data */ mr r7,r25 /* OFW interfaces */ bl decompress_kernel - - /* changed to use r3 (as firmware does) for kernel - as ptr to residual -- Cort*/ - lis r6,cmd_line@h - ori r6,r6,cmd_line@l - lwz r6, 0(r6) - subi r7,r6,1 -00: lbzu r2,1(r7) - cmpi 0,r2,0 - bne 00b - - /* r4,r5 have initrd_start, size */ - lis r2,initrd_start@h - ori r2,r2,initrd_start@l - lwz r4,0(r2) - lis r2,initrd_end@h - ori r2,r2,initrd_end@l - lwz r5,0(r2) - - - /* tell kernel we're prep */ - /* - * get start address of kernel code which is stored as a coff - * entry. see boot/head.S -- Cort + + /* + * We have to do this after decompress_kernel, just to make + * sure we don't wipe out things mapped in BATs which we need. + * -- Tom */ - li r9,0x4 + li r6,0 + /* Test for a 601 */ + mfspr r9,PVR + srwi r9,r9,16 + cmpi 0,r9,1 /* 601 ? */ + beq .clearbats_601 + + /* Clear BATS */ + mtspr DBAT0U,r6 + mtspr DBAT0L,r6 + mtspr DBAT1U,r6 + mtspr DBAT1L,r6 + mtspr DBAT2U,r6 + mtspr DBAT2L,r6 + mtspr DBAT3U,r6 + mtspr DBAT3L,r6 +.clearbats_601: + mtspr IBAT0U,r6 + mtspr IBAT0L,r6 + mtspr IBAT1U,r6 + mtspr IBAT1L,r6 + mtspr IBAT2U,r6 + mtspr IBAT2L,r6 + mtspr IBAT3U,r6 + mtspr IBAT3L,r6 + isync + sync + sync + + /* Set segment registers */ + li r6,16 /* load up segment register values */ + mtctr r6 /* for context 0 */ + lis r6,0x2000 /* Ku = 1, VSID = 0 */ + li r10,0 +3: mtsrin r6,r10 + addi r6,r6,0x111 /* increment VSID */ + addis r10,r10,0x1000 /* address of next segment */ + bdnz 3b + + /* tell kernel we're prep, by putting 0xdeadc0de at KERNELLOAD, + * and tell the kernel to start on the 4th instruction since we + * overwrite the first 3 sometimes (which are 'nop'). + */ + li r9,0xc mtlr r9 lis r10,0xdeadc0de@h ori r10,r10,0xdeadc0de@l li r9,0 stw r10,0(r9) -/* - * The Radstone firmware maps PCI memory at 0xc0000000 using BAT2 - * so disable BATs before setting this to avoid a clash - */ - li r8,0 - mtspr DBAT0U,r8 - mtspr DBAT1U,r8 - mtspr DBAT2U,r8 - mtspr DBAT3U,r8 - mtspr IBAT0U,r8 - mtspr IBAT1U,r8 - mtspr IBAT2U,r8 - mtspr IBAT3U,r8 - - blr -hang: - b hang - -/* - * Delay for a number of microseconds - * -- Use the BUS timer (assumes 66MHz) - */ - .globl udelay -udelay: - mfspr r4,PVR - srwi r4,r4,16 - cmpi 0,r4,1 /* 601 ? */ - bne .udelay_not_601 -00: li r0,86 /* Instructions / microsecond? */ - mtctr r0 -10: addi r0,r0,0 /* NOP */ - bdnz 10b - subic. r3,r3,1 - bne 00b blr -.udelay_not_601: - mulli r4,r3,1000 /* nanoseconds */ - addi r4,r4,59 - li r5,60 - divw r4,r4,r5 /* BUS ticks */ -1: mftbu r5 - mftb r6 - mftbu r7 - cmp 0,r5,r7 - bne 1b /* Get [synced] base time */ - addc r9,r6,r4 /* Compute end time */ - addze r8,r5 -2: mftbu r5 - cmp 0,r5,r8 - blt 2b - bgt 3f - mftb r6 - cmp 0,r6,r9 - blt 2b -3: blr - -.globl _get_HID0 -_get_HID0: - mfspr r3,HID0 - blr - -.globl _put_HID0 -_put_HID0: - mtspr HID0,r3 - blr - -.globl _get_MSR -_get_MSR: - mfmsr r3 - blr - -.globl _put_MSR -_put_MSR: - mtmsr r3 - blr - -/* - * Flush instruction cache - * *** I'm really paranoid here! - */ -_GLOBAL(flush_instruction_cache) - mflr r5 - bl flush_data_cache - mfspr r3,HID0 /* Caches are controlled by this register */ - li r4,0 - ori r4,r4,(HID0_ICE|HID0_ICFI) - or r3,r3,r4 /* Need to enable+invalidate to clear */ - mtspr HID0,r3 - andc r3,r3,r4 - ori r3,r3,HID0_ICE /* Enable cache */ - mtspr HID0,r3 - mtlr r5 - blr - -#define NUM_CACHE_LINES 128*8 -#define CACHE_LINE_SIZE 32 -#define cache_flush_buffer 0x1000 - -/* - * Flush data cache - * *** I'm really paranoid here! - */ -_GLOBAL(flush_data_cache) - lis r3,cache_flush_buffer@h - ori r3,r3,cache_flush_buffer@l - li r4,NUM_CACHE_LINES - mtctr r4 -00: lwz r4,0(r3) - addi r3,r3,CACHE_LINE_SIZE /* Next line, please */ - bdnz 00b -10: blr .comm .stack,4096*2,4 diff --git a/arch/ppc/boot/prep/kbd.c b/arch/ppc/boot/prep/kbd.c index a3208751d6c5..e9470f32ba55 100644 --- a/arch/ppc/boot/prep/kbd.c +++ b/arch/ppc/boot/prep/kbd.c @@ -1,9 +1,10 @@ /* - * BK Id: SCCS/s.kbd.c 1.7 05/18/01 06:20:29 patch + * BK Id: %F% %I% %G% %U% %#% */ + #include <linux/keyboard.h> -#include <../drivers/char/defkeymap.c> /* yeah I know it's bad -- Cort */ +#include "defkeymap.c" /* yeah I know it's bad -- Cort */ unsigned char shfts, ctls, alts, caps; @@ -130,20 +131,29 @@ enter: /* Wait for key up */ goto loop; } -static void kbdreset(void) +static int __kbdreset(void) { unsigned char c; - int i; + int i, t; /* flush input queue */ + t = 2000; while ((inb(KBSTATP) & KBINRDY)) { (void)inb(KBDATAP); + if (--t == 0) + return 1; } /* Send self-test */ - while (inb(KBSTATP) & KBOUTRDY) ; + t = 20000; + while (inb(KBSTATP) & KBOUTRDY) + if (--t == 0) + return 2; outb(KBSTATP,0xAA); - while ((inb(KBSTATP) & KBINRDY) == 0) ; /* wait input ready */ + t = 200000; + while ((inb(KBSTATP) & KBINRDY) == 0) /* wait input ready */ + if (--t == 0) + return 3; if ((c = inb(KBDATAP)) != 0x55) { puts("Keyboard self test failed - result:"); @@ -151,15 +161,23 @@ static void kbdreset(void) puts("\n"); } /* Enable interrupts and keyboard controller */ - while (inb(KBSTATP) & KBOUTRDY) ; - outb(KBSTATP,0x60); - while (inb(KBSTATP) & KBOUTRDY) ; + t = 20000; + while (inb(KBSTATP) & KBOUTRDY) + if (--t == 0) return 4; + outb(KBSTATP,0x60); + t = 20000; + while (inb(KBSTATP) & KBOUTRDY) + if (--t == 0) return 5; outb(KBDATAP,0x45); for (i = 0; i < 10000; i++) udelay(1); - - while (inb(KBSTATP) & KBOUTRDY) ; + + t = 20000; + while (inb(KBSTATP) & KBOUTRDY) + if (--t == 0) return 6; outb(KBSTATP,0x20); - while ((inb(KBSTATP) & KBINRDY) == 0) ; /* wait input ready */ + t = 200000; + while ((inb(KBSTATP) & KBINRDY) == 0) /* wait input ready */ + if (--t == 0) return 7; if (! (inb(KBDATAP) & 0x40)) { /* * Quote from PS/2 System Reference Manual: @@ -169,15 +187,31 @@ static void kbdreset(void) * output-buffer-full bit in the Controller Status * register are set 0." (KBINRDY and KBOUTRDY) */ - - while (inb(KBSTATP) & (KBINRDY | KBOUTRDY)) ; + t = 200000; + while (inb(KBSTATP) & (KBINRDY | KBOUTRDY)) + if (--t == 0) return 8; outb(KBDATAP,0xF0); - while (inb(KBSTATP) & (KBINRDY | KBOUTRDY)) ; + t = 200000; + while (inb(KBSTATP) & (KBINRDY | KBOUTRDY)) + if (--t == 0) return 9; outb(KBDATAP,0x01); } - - while (inb(KBSTATP) & KBOUTRDY) ; + t = 20000; + while (inb(KBSTATP) & KBOUTRDY) + if (--t == 0) return 10; outb(KBSTATP,0xAE); + return 0; +} + +static void kbdreset(void) +{ + int ret = __kbdreset(); + + if (ret) { + puts("__kbdreset failed: "); + puthex(ret); + puts("\n"); + } } /* We have to actually read the keyboard when CRT_tstc is called, diff --git a/arch/ppc/boot/prep/misc.c b/arch/ppc/boot/prep/misc.c index 7088fb16a4e8..cc76c012d0a1 100644 --- a/arch/ppc/boot/prep/misc.c +++ b/arch/ppc/boot/prep/misc.c @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.misc.c 1.20 09/24/01 18:42:54 trini + * BK Id: %F% %I% %G% %U% %#% * * arch/ppc/boot/prep/misc.c * @@ -32,12 +32,16 @@ */ char *avail_ram; char *end_avail; + +/* The linker tells us where the image is. */ +extern char __image_begin, __image_end; +extern char __ramdisk_begin, __ramdisk_end; extern char _end[]; #ifdef CONFIG_CMDLINE #define CMDLINE CONFIG_CMDLINE #else -#define CMDLINE ""; +#define CMDLINE "" #endif char cmd_preset[] = CMDLINE; char cmd_buf[256]; @@ -46,16 +50,9 @@ char *cmd_line = cmd_buf; int keyb_present = 1; /* keyboard controller is present by default */ RESIDUAL hold_resid_buf; RESIDUAL *hold_residual = &hold_resid_buf; -unsigned long initrd_start = 0, initrd_end = 0; - -/* These values must be variables. If not, the compiler optimizer - * will remove some code, causing the size of the code to vary - * when these values are zero. This is bad because we first - * compile with these zero to determine the size and offsets - * in an image, than compile again with these set to the proper - * discovered value. - */ -unsigned int initrd_offset, initrd_size; +unsigned long initrd_size = 0; +unsigned long orig_MSR; + char *zimage_start; int zimage_size; @@ -71,16 +68,14 @@ int orig_x, orig_y = 24; extern int CRT_tstc(void); extern void of_init(void *handler); extern int of_finddevice(const char *device_specifier, int *phandle); -extern int of_getprop(int phandle, const char *name, void *buf, int buflen, +extern int of_getprop(int phandle, const char *name, void *buf, int buflen, int *size); extern int vga_init(unsigned char *ISA_mem); extern void gunzip(void *, int, unsigned char *, int *); -extern void _put_HID0(unsigned int val); extern void _put_MSR(unsigned int val); -extern unsigned int _get_HID0(void); -extern unsigned int _get_MSR(void); -extern unsigned long serial_init(int chan); +extern unsigned long serial_init(int chan, void *ignored); +extern void setup_legacy(void); void writel(unsigned int val, unsigned int address) @@ -90,7 +85,7 @@ writel(unsigned int val, unsigned int address) *(unsigned int *)address = cpu_to_le32(val); } -unsigned int +unsigned int readl(unsigned int address) { /* Ensure I/O operations complete */ @@ -98,8 +93,8 @@ readl(unsigned int address) return le32_to_cpu(*(unsigned int *)address); } -#define PCI_CFG_ADDR(dev,off) ((0x80<<24) | (dev<<8) | (off&0xfc)) -#define PCI_CFG_DATA(off) (0x80000cfc+(off&3)) +#define PCI_CFG_ADDR(dev,off) ((0x80<<24) | (dev<<8) | (off&0xfc)) +#define PCI_CFG_DATA(off) (0x80000cfc+(off&3)) static void pci_read_config_32(unsigned char devfn, @@ -123,38 +118,14 @@ scroll(void) } #endif /* CONFIG_VGA_CONSOLE */ -/* - * This routine is used to control the second processor on the - * Motorola dual processor platforms. - */ -void -park_cpus(void) -{ - volatile void (*go)(RESIDUAL *, int, int, char *, int); - unsigned int i; - volatile unsigned long *smp_iar = &(hold_residual->VitalProductData.SmpIar); - - /* Wait for indication to continue. If the kernel - was not compiled with SMP support then the second - processor will spin forever here makeing the kernel - multiprocessor safe. */ - while (*smp_iar == 0) { - for (i=0; i < 512; i++); - } - - (unsigned long)go = hold_residual->VitalProductData.SmpIar; - go(hold_residual, 0, 0, cmd_line, sizeof(cmd_preset)); -} - unsigned long decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum, RESIDUAL *residual, void *OFW_interface) { - int timer; + int timer = 0; extern unsigned long start; char *cp, ch; unsigned long TotalMemory; - unsigned long orig_MSR; int dev_handle; int mem_info[2]; int res, size; @@ -162,26 +133,42 @@ decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum, unsigned char base_mod; int start_multi = 0; unsigned int pci_viddid, pci_did, tulip_pci_base, tulip_base; - - /* - * IBM's have the MMU on, so we have to disable it or - * things get really unhappy in the kernel when - * trying to setup the BATs with the MMU on - * -- Cort - */ - flush_instruction_cache(); - _put_HID0(_get_HID0() & ~0x0000C000); - _put_MSR((orig_MSR = _get_MSR()) & ~0x0030); + setup_legacy(); #if defined(CONFIG_SERIAL_CONSOLE) - com_port = serial_init(0); + com_port = serial_init(0, NULL); #endif /* CONFIG_SERIAL_CONSOLE */ #if defined(CONFIG_VGA_CONSOLE) vga_init((unsigned char *)0xC0000000); #endif /* CONFIG_VGA_CONSOLE */ - if (residual) - { + /* + * Tell the user where we were loaded at and where we were relocated + * to for debugging this process. + */ + puts("loaded at: "); puthex(load_addr); + puts(" "); puthex((unsigned long)(load_addr + (4*num_words))); puts("\n"); + if ( (unsigned long)load_addr != (unsigned long)&start ) { + puts("relocated to: "); puthex((unsigned long)&start); + puts(" "); + puthex((unsigned long)((unsigned long)&start + (4*num_words))); + puts("\n"); + } + + if (residual) { + /* + * Tell the user where the residual data is. + */ + puts("board data at: "); puthex((unsigned long)residual); + puts(" "); + puthex((unsigned long)((unsigned long)residual + + sizeof(RESIDUAL))); + puts("\nrelocated to: ");puthex((unsigned long)hold_residual); + puts(" "); + puthex((unsigned long)((unsigned long)hold_residual + + sizeof(RESIDUAL))); + puts("\n"); + /* Is this Motorola PPCBug? */ if ((1 & residual->VitalProductData.FirmwareSupports) && (1 == residual->VitalProductData.FirmwareSupplier)) { @@ -198,8 +185,7 @@ decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum, ((pci_did == PCI_DEVICE_ID_DEC_TULIP_FAST) || (pci_did == PCI_DEVICE_ID_DEC_TULIP) || (pci_did == PCI_DEVICE_ID_DEC_TULIP_PLUS) || - (pci_did == PCI_DEVICE_ID_DEC_21142))) - { + (pci_did == PCI_DEVICE_ID_DEC_21142))) { pci_read_config_32(0x70, 0x10, &tulip_pci_base); @@ -213,7 +199,7 @@ decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum, /* If this is genesis 2 board then check for no * keyboard controller and more than one processor. */ - if (board_type == 0xe0) { + if (board_type == 0xe0) { base_mod = inb(0x803); /* if a MVME2300/2400 or a Sitka then no keyboard */ if((base_mod == 0xFA) || (base_mod == 0xF9) || @@ -225,14 +211,17 @@ decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum, * park the other processor so that the * kernel knows where to find them. */ - if (residual->MaxNumCpus > 1) { + if (residual->MaxNumCpus > 1) start_multi = 1; - } } memcpy(hold_residual,residual,sizeof(RESIDUAL)); } else { + /* Tell the user we didn't find anything. */ + puts("No residual data found.\n"); + /* Assume 32M in the absence of more info... */ TotalMemory = 0x02000000; + /* * This is a 'best guess' check. We want to make sure * we don't try this on a PReP box without OF @@ -240,118 +229,66 @@ decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum, */ while (OFW_interface && ((unsigned long)OFW_interface < 0x10000000) ) { - /* The MMU needs to be on when we call OFW */ + /* We need to restore the slightly inaccurate + * MSR so that OpenFirmware will behave. -- Tom + */ _put_MSR(orig_MSR); of_init(OFW_interface); /* get handle to memory description */ - res = of_finddevice("/memory@0", + res = of_finddevice("/memory@0", &dev_handle); - // puthex(res); puts("\n"); - if (res) break; - + if (res) + break; + /* get the info */ - // puts("get info = "); - res = of_getprop(dev_handle, - "reg", - mem_info, - sizeof(mem_info), + res = of_getprop(dev_handle, + "reg", + mem_info, + sizeof(mem_info), &size); - // puthex(res); puts(", info = "); puthex(mem_info[0]); - // puts(" "); puthex(mem_info[1]); puts("\n"); - if (res) break; - + if (res) + break; + TotalMemory = mem_info[1]; break; } + hold_residual->TotalMemory = TotalMemory; residual = hold_residual; - /* Turn MMU back off */ - _put_MSR(orig_MSR & ~0x0030); - } - if (start_multi) { - hold_residual->VitalProductData.SmpIar = 0; - hold_residual->Cpus[1].CpuState = CPU_GOOD_FW; - residual->VitalProductData.SmpIar = (unsigned long)park_cpus; - residual->Cpus[1].CpuState = CPU_GOOD; - hold_residual->VitalProductData.Reserved5 = 0xdeadbeef; - } + /* Enforce a sane MSR for booting. */ + _put_MSR(MSR_IP); + } /* assume the chunk below 8M is free */ end_avail = (char *)0x00800000; - /* tell the user where we were loaded at and where we - * were relocated to for debugging this process + /* + * We link ourself to 0x00800000. When we run, we relocate + * ourselves there. So we just need __image_begin for the + * start. -- Tom */ - puts("loaded at: "); puthex(load_addr); - puts(" "); puthex((unsigned long)(load_addr + (4*num_words))); puts("\n"); - if ( (unsigned long)load_addr != (unsigned long)&start ) - { - puts("relocated to: "); puthex((unsigned long)&start); - puts(" "); - puthex((unsigned long)((unsigned long)&start + (4*num_words))); - puts("\n"); - } + zimage_start = (char *)(unsigned long)(&__image_begin); + zimage_size = (unsigned long)(&__image_end) - + (unsigned long)(&__image_begin); - if ( residual ) - { - puts("board data at: "); puthex((unsigned long)residual); - puts(" "); - puthex((unsigned long)((unsigned long)residual + sizeof(RESIDUAL))); - puts("\n"); - puts("relocated to: "); - puthex((unsigned long)hold_residual); - puts(" "); - puthex((unsigned long)((unsigned long)hold_residual + sizeof(RESIDUAL))); - puts("\n"); - } - - /* we have to subtract 0x10000 here to correct for objdump including the - size of the elf header which we strip -- Cort */ - zimage_start = (char *)(load_addr - 0x10000 + ZIMAGE_OFFSET); - zimage_size = ZIMAGE_SIZE; - initrd_offset = INITRD_OFFSET; - initrd_size = INITRD_SIZE; - - if ( initrd_offset ) - initrd_start = load_addr - 0x10000 + initrd_offset; - else - initrd_start = 0; - initrd_end = initrd_size + initrd_start; + initrd_size = (unsigned long)(&__ramdisk_end) - + (unsigned long)(&__ramdisk_begin); /* - * Find a place to stick the zimage and initrd and - * relocate them if we have to. -- Cort + * The zImage and initrd will be between start and _end, so they've + * already been moved once. We're good to go now. -- Tom */ avail_ram = (char *)PAGE_ALIGN((unsigned long)_end); puts("zimage at: "); puthex((unsigned long)zimage_start); - puts(" "); puthex((unsigned long)(zimage_size+zimage_start)); puts("\n"); - if ( (unsigned long)zimage_start <= 0x00800000 ) - { - memcpy( (void *)avail_ram, (void *)zimage_start, zimage_size ); - zimage_start = (char *)avail_ram; - puts("relocated to: "); puthex((unsigned long)zimage_start); - puts(" "); - puthex((unsigned long)zimage_size+(unsigned long)zimage_start); - puts("\n"); + puts(" "); puthex((unsigned long)(zimage_size+zimage_start)); + puts("\n"); - /* relocate initrd */ - if ( initrd_start ) - { - puts("initrd at: "); puthex(initrd_start); - puts(" "); puthex(initrd_end); puts("\n"); - avail_ram = (char *)PAGE_ALIGN( - (unsigned long)zimage_size+(unsigned long)zimage_start); - memcpy ((void *)avail_ram, (void *)initrd_start, initrd_size ); - initrd_start = (unsigned long)avail_ram; - initrd_end = initrd_start + initrd_size; - puts("relocated to: "); puthex(initrd_start); - puts(" "); puthex(initrd_end); puts("\n"); - } - } else if ( initrd_start ) { - puts("initrd at: "); puthex(initrd_start); - puts(" "); puthex(initrd_end); puts("\n"); + if ( initrd_size ) { + puts("initrd at: "); + puthex((unsigned long)(&__ramdisk_begin)); + puts(" "); puthex((unsigned long)(&__ramdisk_end));puts("\n"); } avail_ram = (char *)0x00400000; @@ -363,10 +300,10 @@ decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum, CRT_tstc(); /* Forces keyboard to be initialized */ puts("\nLinux/PPC load: "); - timer = 0; cp = cmd_line; memcpy (cmd_line, cmd_preset, sizeof(cmd_preset)); - while ( *cp ) putc(*cp++); + while ( *cp ) + putc(*cp++); while (timer++ < 5*1000) { if (tstc()) { while ((ch = getc()) != '\n' && ch != '\r') { @@ -392,26 +329,24 @@ decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum, udelay(1000); /* 1 msec */ } *cp = 0; - puts("\n"); + puts("\nUncompressing Linux..."); - /* mappings on early boot can only handle 16M */ - if ( (int)(cmd_line[0]) > (16<<20)) - puts("cmd_line located > 16M\n"); - if ( (int)hold_residual > (16<<20)) - puts("hold_residual located > 16M\n"); - if ( initrd_start > (16<<20)) - puts("initrd_start located > 16M\n"); - - puts("Uncompressing Linux..."); - gunzip(0, 0x400000, zimage_start, &zimage_size); puts("done.\n"); - + + if (start_multi) { + puts("Parking cpu1 at 0xc0\n"); + residual->VitalProductData.SmpIar = (unsigned long)0xc0; + residual->Cpus[1].CpuState = CPU_GOOD; + hold_residual->VitalProductData.Reserved5 = 0xdeadbeef; + } + { struct bi_record *rec; - - rec = (struct bi_record *)_ALIGN((unsigned long)(zimage_size)+(1<<20)-1,(1<<20)); - + + rec = (struct bi_record *)_ALIGN((unsigned long)(zimage_size) + + (1 << 20) - 1, (1 << 20)); + rec->tag = BI_FIRST; rec->size = sizeof(struct bi_record); rec = (struct bi_record *)((unsigned long)rec + rec->size); @@ -420,18 +355,29 @@ decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum, memcpy( (void *)rec->data, "prepboot", 9); rec->size = sizeof(struct bi_record) + 8 + 1; rec = (struct bi_record *)((unsigned long)rec + rec->size); - + rec->tag = BI_MACHTYPE; rec->data[0] = _MACH_prep; rec->data[1] = 0; - rec->size = sizeof(struct bi_record) + 2 * sizeof(unsigned long); + rec->size = sizeof(struct bi_record) + 2 * + sizeof(unsigned long); rec = (struct bi_record *)((unsigned long)rec + rec->size); - + rec->tag = BI_CMD_LINE; memcpy( (char *)rec->data, cmd_line, strlen(cmd_line)+1); rec->size = sizeof(struct bi_record) + strlen(cmd_line) + 1; - rec = (struct bi_record *)((ulong)rec + rec->size); - + rec = (struct bi_record *)((unsigned long)rec + rec->size); + + if ( initrd_size ) { + rec->tag = BI_INITRD; + rec->data[0] = (unsigned long)(&__ramdisk_begin); + rec->data[1] = initrd_size; + rec->size = sizeof(struct bi_record) + 2 * + sizeof(unsigned long); + rec = (struct bi_record *)((unsigned long)rec + + rec->size); + } + rec->tag = BI_LAST; rec->size = sizeof(struct bi_record); rec = (struct bi_record *)((unsigned long)rec + rec->size); @@ -439,12 +385,3 @@ decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum, puts("Now booting the kernel\n"); return (unsigned long)hold_residual; } - -/* - * PCI/ISA I/O support - */ -unsigned long -local_to_PCI(unsigned long addr) -{ - return (addr | 0x80000000); -} diff --git a/arch/ppc/boot/prep/vreset.c b/arch/ppc/boot/prep/vreset.c index 2e2844d0182d..b6188d1f99a5 100644 --- a/arch/ppc/boot/prep/vreset.c +++ b/arch/ppc/boot/prep/vreset.c @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.vreset.c 1.11 07/25/01 18:13:07 trini + * BK Id: %F% %I% %G% %U% %#% */ /* * vreset.c @@ -29,7 +29,7 @@ extern int lines, cols; struct VaRegs; /* - * VGA Register + * VGA Register */ struct VgaRegs { @@ -108,51 +108,6 @@ struct VgaRegs GenVgaTextRegs[NREGS+1] = { { ENDMK } }; -struct VgaRegs S3TextRegs[NREGS+1] = { - /* port index value */ - /* SR Regs */ - { 0x3c4, 0x1, 0x0 }, - { 0x3c4, 0x2, 0x3 }, - { 0x3c4, 0x3, 0x0 }, - { 0x3c4, 0x4, 0x2 }, - /* CR Regs */ - { 0x3d4, 0x0, 0x5f }, - { 0x3d4, 0x1, 0x4f }, - { 0x3d4, 0x2, 0x50 }, - { 0x3d4, 0x3, 0x82 }, - { 0x3d4, 0x4, 0x55 }, - { 0x3d4, 0x5, 0x81 }, - { 0x3d4, 0x6, 0xbf }, - { 0x3d4, 0x7, 0x1f }, - { 0x3d4, 0x8, 0x00 }, - { 0x3d4, 0x9, 0x4f }, - { 0x3d4, 0xa, 0x0d }, - { 0x3d4, 0xb, 0x0e }, - { 0x3d4, 0xc, 0x00 }, - { 0x3d4, 0xd, 0x00 }, - { 0x3d4, 0xe, 0x00 }, - { 0x3d4, 0xf, 0x00 }, - { 0x3d4, 0x10, 0x9c }, - { 0x3d4, 0x11, 0x8e }, - { 0x3d4, 0x12, 0x8f }, - { 0x3d4, 0x13, 0x28 }, - { 0x3d4, 0x14, 0x1f }, - { 0x3d4, 0x15, 0x96 }, - { 0x3d4, 0x16, 0xb9 }, - { 0x3d4, 0x17, 0xa3 }, - /* GR Regs */ - { 0x3ce, 0x0, 0x0 }, - { 0x3ce, 0x1, 0x0 }, - { 0x3ce, 0x2, 0x0 }, - { 0x3ce, 0x3, 0x0 }, - { 0x3ce, 0x4, 0x0 }, - { 0x3ce, 0x5, 0x10 }, - { 0x3ce, 0x6, 0xe }, - { 0x3ce, 0x7, 0x0 }, - { 0x3ce, 0x8, 0xff }, - { ENDMK } -}; - struct RGBColors { unsigned char r, g, b; @@ -161,9 +116,9 @@ struct RGBColors /* * Default console text mode color table. * These values were obtained by booting Linux with - * text mode firmware & then dumping the registers. + * text mode firmware & then dumping the registers. */ -struct RGBColors TextCLUT[256] = +struct RGBColors TextCLUT[256] = { /* red green blue */ { 0x0, 0x0, 0x0 }, @@ -424,8 +379,8 @@ struct RGBColors TextCLUT[256] = }; unsigned char AC[21] = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, - 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, + 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x0C, 0x00, 0x0F, 0x08, 0x00}; static int scanPCI(int start_slt); @@ -443,20 +398,13 @@ outw(int port, unsigned short val) outb(port, val >> 8); outb(port+1, val); } - -#define PPC_601 1 int vga_init(unsigned char *ISA_mem) { int slot; struct VgaRegs *VgaTextRegs; -#if 0 - if ((_get_PVR()>>16) == PPC_601) { - return(old_vga_init(ISA_mem)); - } -#endif - + /* See if VGA already in TEXT mode - exit if so! */ outb(0x3CE, 0x06); if ((inb(0x3CF) & 0x01) == 0){ @@ -470,20 +418,19 @@ vga_init(unsigned char *ISA_mem) while((slot = scanPCI(slot)) > -1) { /* find video card in use */ unlockVideo(slot); /* enable I/O to card */ VgaTextRegs = GenVgaTextRegs; - + switch (PCIVendor(slot)) { default: break; case(S3Vendor): unlockS3(); - VgaTextRegs = S3TextRegs; break; - + case(CirrusVendor): outw(0x3C4, 0x0612); /* unlock ext regs */ outw(0x3C4, 0x0700); /* reset ext sequence mode */ break; - + case(ParadiseVendor): /* IBM Portable 850 */ outw(0x3ce, 0x0f05); /* unlock pardise registers */ outw(0x3c4, 0x0648); @@ -508,7 +455,7 @@ vga_init(unsigned char *ISA_mem) } outw(0x3d4, 0x34a0); break; - + #if 0 /* Untested - probably doesn't work */ case(MatroxVendor): case(DiamondVendor): @@ -518,7 +465,7 @@ vga_init(unsigned char *ISA_mem) mdelay(1000); #endif }; - + outw(0x3C4, 0x0120); /* disable video */ setTextRegs(VgaTextRegs); /* initial register setup */ setTextCLUT(0); /* load color lookup table */ @@ -526,23 +473,23 @@ vga_init(unsigned char *ISA_mem) setTextRegs(VgaTextRegs); /* reload registers */ outw(0x3C4, 0x0100); /* re-enable video */ clearVideoMemory(); - + if (PCIVendor(slot) == S3Vendor) { outb(0x3c2, 0x63); /* MISC */ } /* endif */ - + #ifdef DEBUG printslots(); mdelay(5000); #endif - + mdelay(1000); /* give time for the video monitor to come up */ } return (1); /* 'CRT' I/O supported */ } /* - * Write to VGA Attribute registers. + * Write to VGA Attribute registers. */ void writeAttr(unsigned char index, unsigned char data, unsigned char videoOn) @@ -563,18 +510,18 @@ setTextRegs(struct VgaRegs *svp) /* * saved settings - */ + */ while( svp->io_port != ENDMK ) { outb(svp->io_port, svp->io_index); outb(svp->io_port+1, svp->io_value); - svp++; + svp++; } outb(0x3c2, 0x67); /* MISC */ outb(0x3c6, 0xff); /* MASK */ for ( i = 0; i < 0x10; i++) - writeAttr(i, AC[i], 0); /* pallete */ + writeAttr(i, AC[i], 0); /* pallete */ writeAttr(0x10, 0x0c, 0); /* text mode */ writeAttr(0x11, 0x00, 0); /* overscan color (border) */ writeAttr(0x12, 0x0f, 0); /* plane enable */ @@ -587,9 +534,9 @@ setTextCLUT(int shift) { int i; - outb(0x3C6, 0xFF); + outb(0x3C6, 0xFF); i = inb(0x3C7); - outb(0x3C8, 0); + outb(0x3C8, 0); i = inb(0x3C7); for ( i = 0; i < 256; i++) { @@ -604,14 +551,14 @@ loadFont(unsigned char *ISA_mem) { int i, j; unsigned char *font_page = (unsigned char *) &ISA_mem[0xA0000]; - + outb(0x3C2, 0x67); - /* - * Load font + /* + * Load font */ i = inb(0x3DA); /* Reset Attr toggle */ - outb(0x3C0,0x30); + outb(0x3C0,0x30); outb(0x3C0, 0x01); /* graphics mode */ outw(0x3C4, 0x0001); /* reset sequencer */ @@ -706,7 +653,7 @@ unlockS3(void) } /* - * cursor() sets an offset (0-1999) into the 80x25 text area + * cursor() sets an offset (0-1999) into the 80x25 text area. */ void cursor(int x, int y) @@ -737,14 +684,14 @@ clearVideoMemory(void) #define NPCIREGS 5 -/* - should use devfunc number/indirect method to be totally safe on - all machines, this works for now on 3 slot Moto boxes +/* + should use devfunc number/indirect method to be totally safe on + all machines, this works for now on 3 slot Moto boxes */ struct PCI_ConfigInfo { unsigned long * config_addr; - unsigned long regs[NPCIREGS]; + unsigned long regs[NPCIREGS]; } PCI_slots [NSLOTS] = { { (unsigned long *)0x80808000, 0xDEADBEEF }, /* onboard */ @@ -761,10 +708,10 @@ struct PCI_ConfigInfo { /* * The following code modifies the PCI Command register - * to enable memory and I/O accesses. - */ + * to enable memory and I/O accesses. + */ void -unlockVideo(int slot) +unlockVideo(int slot) { volatile unsigned char * ppci; @@ -811,13 +758,13 @@ scanPCI(int start_slt) pslot->regs[r] = SwapBytes ( pslot->config_addr[r] ); } /* card in slot ? */ - if ( pslot->regs[DEVID] != 0xFFFFFFFF ) { + if ( pslot->regs[DEVID] != 0xFFFFFFFF ) { /* VGA ? */ - if ( ((pslot->regs[CLASS] & 0xFFFFFF00) == 0x03000000) || + if ( ((pslot->regs[CLASS] & 0xFFFFFF00) == 0x03000000) || ((pslot->regs[CLASS] & 0xFFFFFF00) == 0x00010000)) { highVgaSlot = slt; /* did firmware enable it ? */ - if ( (pslot->regs[CMD] & 0x03) ) { + if ( (pslot->regs[CMD] & 0x03) ) { theSlot = slt; break; } @@ -840,7 +787,7 @@ return (pslot->regs[DEVID] & 0xFFFF); #ifdef DEBUG static -void printslots(void) +void printslots(void) { int i; #if 0 @@ -853,7 +800,7 @@ void printslots(void) i, pslot->config_addr, pslot->regs[0], pslot->regs[2]); #else puts("PCI Slot number: "); puthex(i); - puts(" Vendor ID: "); + puts(" Vendor ID: "); puthex(PCIVendor(i)); puts("\n"); #endif } diff --git a/arch/ppc/boot/simple/Makefile b/arch/ppc/boot/simple/Makefile new file mode 100644 index 000000000000..2e35355fac93 --- /dev/null +++ b/arch/ppc/boot/simple/Makefile @@ -0,0 +1,261 @@ +# This is far from simple, but I couldn't think of a good name. This is +# for making the 'zImage' or 'zImage.initrd' on a number of targets. +# +# Author: Tom Rini <trini@mvista.com> +# +# Copyright 2001 MontaVista Software Inc. +# +# Notes: For machine targets which produce more than one image, define +# ZNETBOOT and ZNETBOOTRD to the image which should be available for +# 'znetboot' and 'znetboot.initrd` +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. + +USE_STANDARD_AS_RULE := true + +# Normally, we use the 'misc-simple.c' file for decompress_kernel and +# whatnot. Sometimes we need to override this however. +MISC := ../common/misc-simple.o +ifeq ($(CONFIG_TREEBOOT),y) +ZIMAGE := zImage-TREE +ZIMAGEINITRD := zImage.initrd-TREE +TFTPIMAGE := /tftpboot/zImage.embedded +MISC := misc-embedded.o +endif +ifeq ($(CONFIG_EMBEDDEDBOOT),y) +ZIMAGE := zImage-EMBEDDED +ZIMAGEINITRD := zImage.initrd-EMBEDDED +TFTPIMAGE := /tftpboot/zImage.embedded +MISC := misc-embedded.o +endif +ifeq ($(CONFIG_EV64260),y) +ZIMAGE := zImage-EV64260 +ZIMAGEINITRD := zImage.initrd-EV64260 +HEADHELP := direct.o misc-ev64260.o +TFTPIMAGE := /tftpboot/zImage.ev64260 +endif +ifeq ($(CONFIG_GEMINI),y) +ZIMAGE := zImage-SMON +ZIMAGEINITRD := zImage.initrd-SMON +HEADHELP := direct.o +TFTPIMAGE := /tftpboot/zImage.gemini +endif +ifeq ($(CONFIG_MENF1),y) +ZIMAGE := zImage-MENF1 +ZIMAGEINITRD := zImage.initrd-MENF1 +HEADHELP := chrpmap.o +TFTPIMAGE := /tftpboot/zImage.menf1 +endif +ifeq ($(CONFIG_K2),y) +ZIMAGE := zImage-K2 +ZIMAGEINITRD := zImage.initrd-K2 +HEADHELP := legacy.o +TFTPIMAGE := /tftpboot/zImage.k2 +endif +# kbuild-2.4 'feature', only one of these will ever by 'y' at a time. +# The rest will be unset. +ifeq ($(CONFIG_MCPN765)$(CONFIG_MVME5100)$(CONFIG_PRPMC750)$(CONFIG_PRPMC800)$(CONFIG_LOPEC)$(CONFIG_PPLUS),y) +ZIMAGE := zImage-PPLUS +ZIMAGEINITRD := zImage.initrd-PPLUS +HEADHELP := direct.o +TFTPIMAGE := /tftpboot/zImage.pplus +ZNETBOOT := zImage.pplus +ZNETBOOTRD := zImage.initrd.pplus +endif +ifeq ($(CONFIG_PPLUS),y) +HEADHELP := legacy.o +endif +ifeq ($(CONFIG_PCORE),y) +ZIMAGE := zImage-PCORE +ZIMAGEINITRD := zImage.initrd-PCORE +HEADHELP := chrpmap.o +TFTPIMAGE := /tftpboot/zImage.pcore +endif +#Ugh, should come up with a better nameing convention.. +ifeq ($(CONFIG_POWERPMC250),y) +ZIMAGE := zImage-PCORE +ZIMAGEINITRD := zImage.initrd-PCORE +HEADHELP := direct.o +TFTPIMAGE := /tftpboot/zImage.pcore +endif +ifeq ($(CONFIG_SANDPOINT),y) +ZIMAGE := zImage-SP +ZIMAGEINITRD := zImage.initrd-SP +HEADHELP := direct.o +TFTPIMAGE := /tftpboot/zImage.sandpoint +endif +ifeq ($(CONFIG_SPRUCE),y) +ZIMAGE := zImage-SPRUCE +ZIMAGEINITRD := zImage.initrd-SPRUCE +HEADHELP := direct.o +MISC := misc-spruce.o +TFTPIMAGE := /tftpboot/zImage.spruce +endif +ifeq ($(CONFIG_ZX4500),y) +ZIMAGE := zImage-ZX4500 +ZIMAGEINITRD := zImage.initrd-ZX4500 +HEADHELP := direct.o +TFTPIMAGE := /tftpboot/zImage.zx4500 +endif +ifeq ($(CONFIG_SMP),y) +TFTPIMAGE += .smp +endif +ifeq ($(CONFIG_REDWOOD_4),y) +# This is a treeboot that needs init functions until the +# boot rom is sorted out (i.e. this is short lived) +EXTRA_AFLAGS := -Wa,-m405 +HEADHELP := rw4/rw4_init.o rw4/rw4_init_brd.o +endif + +# Default linker args. Link at 0x00800000 or 0x00400000 by default, but +# allow it to be overridden. +ifeq ($(CONFIG_BOOT_LOAD_BOOL),y) +LD_ARGS := -T ../ld.script -Ttext $(CONFIG_BOOT_LOAD) \ + -Bstatic +else +LD_ARGS = -T ../ld.script -Ttext 0x00800000 -Bstatic +ifeq ($(CONFIG_8260)$(CONFIG_4xx)$(CONFIG_8xx),y) +LD_ARGS := -T ../ld.script -Ttext 0x00400000 -Bstatic +endif +endif +OBJCOPY_ARGS := -O elf32-powerpc + +# head.o and ../common/relocate.o must be at the start. +obj-y := head.o ../common/relocate.o $(HEADHELP) \ + $(MISC) ../common/misc-common.o \ + ../common/string.o ../common/util.o +obj-$(CONFIG_4xx) += embed_config.o +obj-$(CONFIG_8xx) += embed_config.o +obj-$(CONFIG_8260) += embed_config.o +obj-$(CONFIG_BSEIP) += iic.o +obj-$(CONFIG_MBX) += iic.o pci.o qspan_pci.o +obj-$(CONFIG_RPXCLASSIC) += iic.o pci.o qspan_pci.o +obj-$(CONFIG_RPXLITE) += iic.o +# Different boards need different serial implementations. +ifeq ($(CONFIG_SERIAL_CONSOLE),y) +obj-$(CONFIG_8xx) += m8xx_tty.o +obj-$(CONFIG_8260) += m8260_tty.o +obj-$(CONFIG_GT64260_CONSOLE) += gt64260_tty.o +obj-$(CONFIG_SERIAL) += ../common/ns16550.o +endif + +LIBS := ../lib/zlib.a + +# Tools +MKBUGBOOT := ../utils/mkbugboot +MKPREP := ../utils/mkprep +MKTREE := ../utils/mktree + +zvmlinux: $(obj-y) $(LIBS) ../ld.script ../images/vmlinux.gz ../common/dummy.o + $(OBJCOPY) $(OBJCOPY_ARGS) \ + --add-section=.image=../images/vmlinux.gz \ + --set-section-flags=.image=contents,alloc,load,readonly,data \ + ../common/dummy.o image.o + $(LD) $(LD_ARGS) -o $@ $(obj-y) image.o $(LIBS) + $(OBJCOPY) $(OBJCOPY_ARGS) $@ $@ -R .comment -R .stab -R .stabstr \ + -R .ramdisk -R .sysmap + +zvmlinux.initrd: $(obj-y) $(LIBS) ../ld.script ../images/vmlinux.gz \ + ../common/dummy.o + $(OBJCOPY) $(OBJCOPY_ARGS) \ + --add-section=.ramdisk=../images/ramdisk.image.gz \ + --set-section-flags=.ramdisk=contents,alloc,load,readonly,data \ + --add-section=.image=../images/vmlinux.gz \ + --set-section-flags=.image=contents,alloc,load,readonly,data \ + ../common/dummy.o image.o + $(LD) $(LD_ARGS) -o $@ $(obj-y) image.o $(LIBS) + $(OBJCOPY) $(OBJCOPY_ARGS) $@ $@ -R .comment -R .stab -R .stabstr \ + -R .sysmap + +# Sort-of dummy rules, that let us format the image we want. +zImage: $(ZIMAGE) + rm -f zvmlinux +zImage.initrd: $(ZIMAGEINITRD) + rm -f zvmlinux.initrd + +znetboot: zImage +ifneq ($(ZNETBOOT),) + cp ../images/$(ZNETBOOT) $(TFTPIMAGE) +else + cp ../images/zImage.* $(TFTPIMAGE) +endif + +znetboot.initrd: zImage.initrd +ifneq ($(ZNETBOOTRD),) + cp ../images/$(ZNETBOOTRD) $(TFTPIMAGE) +else + cp ../images/zImage.* $(TFTPIMAGE) +endif + +zImage-EMBEDDED: zvmlinux + mv zvmlinux ../images/zImage.embedded + +zImage.initrd-EMBEDDED: zvmlinux.initrd + mv zvmlinux.initrd ../images/zImage.initrd.embedded + +zImage-K2: zvmlinux + mv zvmlinux ../images/zImage.k2 + +zImage.initrd-K2: zvmlinux.initrd + mv zvmlinux.initrd ../images/zImage.initrd.k2 + +zImage-EV64260: zvmlinux + mv zvmlinux ../images/zImage.ev64260 + +zImage.initrd-EV64260: zvmlinux.initrd + mv zvmlinux.initrd ../images/zImage.initrd.ev64260 + +zImage-MENF1: zvmlinux + $(MKPREP) -pbp zvmlinux ../images/zImage.menf1 + +zImage.initrd-MENF1: zvmlinux.initrd + $(MKPREP) -pbp zvmlinux.initrd ../images/zImage.initrd.menf1 + +zImage-PCORE: zvmlinux + dd if=zvmlinux of=../images/zImage.pcore skip=64 bs=1k + +zImage.initrd-PCORE: zvmlinux.initrd + dd if=zvmlinux.initrd of=../images/zImage.initrd.pcore skip=64 bs=1k + +zImage-PPLUS: zvmlinux $(MKPREP) $(MKBUGBOOT) + $(MKPREP) -pbp zvmlinux ../images/zImage.pplus + $(MKBUGBOOT) zvmlinux ../images/zImage.bugboot + +zImage.initrd-PPLUS: zvmlinux.initrd $(MKPREP) $(MKBUGBOOT) + $(MKPREP) -pbp zvmlinux.initrd ../images/zImage.initrd.pplus + $(MKBUGBOOT) zvmlinux.initrd ../images/zImage.initrd.bugboot + +zImage-SMON: zvmlinux + dd if=zvmlinux of=../images/zImage.gemini skip=64 bs=1k + +zImage.initrd-SMON: zvmlinux.initrd + dd if=zvmlinux.initrd of=../images/zImage.initrd.gemini skip=64 bs=1k + +zImage-SP: zvmlinux + mv zvmlinux ../images/zImage.sandpoint + +zImage.initrd-SP: zvmlinux.initrd + mv zvmlinux.initrd ../images/zImage.initrd.sandpoint + +zImage-SPRUCE: zvmlinux + $(MKTREE) zvmlinux ../images/zImage.spruce 0x800000 + +zImage.initrd-SPRUCE: zvmlinux.initrd + $(MKTREE) zvmlinux.initrd ../images/zImage.initrd.spruce 0x800000 + +zImage-TREE: zvmlinux + $(MKTREE) zvmlinux ../images/zImage.treeboot + +zImage.initrd-TREE: zvmlinux.initrd + $(MKTREE) zvmlinux.initrd ../images/zImage.initrd.treeboot + +zImage-ZX4500: zvmlinux + dd if=zvmlinux of=../images/zImage.zx4500 skip=64 bs=1k + +zImage.initrd-ZX4500: zvmlinux.initrd + dd if=zvmlinux.initrd of=../images/zImage.initrd.zx4500 skip=64 bs=1k + +include $(TOPDIR)/Rules.make diff --git a/arch/ppc/boot/simple/chrpmap.S b/arch/ppc/boot/simple/chrpmap.S new file mode 100644 index 000000000000..10f1f39a1898 --- /dev/null +++ b/arch/ppc/boot/simple/chrpmap.S @@ -0,0 +1,19 @@ +/* + * arch/ppc/boot/simple/chrpmap.S + * + * Author: Tom Rini <trini@mvista.com> + * + * This will go and setup ISA_io to 0xFE00000. + */ + +#include <asm/ppc_asm.h> + + .text + + .globl setup_legacy +setup_legacy: + lis r3,ISA_io@h /* Load ISA_io */ + ori r3,r3,ISA_io@l + lis r4,0xFE00 /* Load the value, 0xFE00000 */ + stw r4,0(r3) /* store */ + blr diff --git a/arch/ppc/boot/simple/direct.S b/arch/ppc/boot/simple/direct.S new file mode 100644 index 000000000000..3c582b3a99fd --- /dev/null +++ b/arch/ppc/boot/simple/direct.S @@ -0,0 +1,14 @@ +/* + * arch/ppc/boot/simple/direct.S + * + * Author: Tom Rini <trini@mvista.com> + * + * This is an empty function for machines which use SERIAL_IO_MEM + * and don't need ISA_io set to anything but 0; + */ + + .text + + .globl setup_legacy +setup_legacy: + blr diff --git a/arch/ppc/boot/mbx/embed_config.c b/arch/ppc/boot/simple/embed_config.c index 18a381cdd2a1..5c37dd3a6394 100644 --- a/arch/ppc/boot/mbx/embed_config.c +++ b/arch/ppc/boot/simple/embed_config.c @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.embed_config.c 1.7 05/18/01 07:54:04 patch + * BK Id: %F% %I% %G% %U% %#% */ /* Board specific functions for those embedded 8xx boards that do @@ -14,14 +14,24 @@ #include <asm/mpc8260.h> #include <asm/immap_8260.h> #endif +#ifdef CONFIG_4xx +#include <asm/io.h> +#endif +#if defined(CONFIG_405GP) || defined(CONFIG_NP405H) || defined(CONFIG_NP405L) +#include <linux/netdevice.h> +#endif +/* For those boards that don't provide one. +*/ +#if !defined(CONFIG_MBX) +static bd_t bdinfo; +#endif /* IIC functions. * These are just the basic master read/write operations so we can * examine serial EEPROM. */ extern void iic_read(uint devaddr, u_char *buf, uint offset, uint count); -static u_char aschex_to_byte(u_char *cp); /* Supply a default Ethernet address for those eval boards that don't * ship with one. This is an address from the MBX board I have, so @@ -35,11 +45,14 @@ static ushort def_enet_addr[] = { 0x0800, 0x3e26, 0x1559 }; * is where the idea started in the first place. */ void -embed_config(bd_t *bd) +embed_config(bd_t **bdp) { u_char *mp; u_char eebuf[128]; int i; + bd_t *bd; + + bd = *bdp; /* Read the first 128 bytes of the EEPROM. There is more, * but this is all we need. @@ -56,9 +69,8 @@ embed_config(bd_t *bd) else mp = (u_char *)def_enet_addr; - for (i=0; i<6; i++) { + for (i=0; i<6; i++) bd->bi_enetaddr[i] = *mp++; - } /* The boot rom passes these to us in MHz. Linux now expects * them to be in Hz. @@ -72,10 +84,46 @@ embed_config(bd_t *bd) } #endif /* CONFIG_MBX */ -#if defined(CONFIG_RPXLITE) || defined(CONFIG_RPXCLASSIC) || defined(CONFIG_RPX6) - +#if defined(CONFIG_RPXLITE) || defined(CONFIG_RPXCLASSIC) || \ + defined(CONFIG_RPX6) || defined(CONFIG_EP405) /* Helper functions for Embedded Planet boards. */ +/* Because I didn't find anything that would do this....... +*/ +u_char +aschex_to_byte(u_char *cp) +{ + u_char byte, c; + + c = *cp++; + + if ((c >= 'A') && (c <= 'F')) { + c -= 'A'; + c += 10; + } else if ((c >= 'a') && (c <= 'f')) { + c -= 'a'; + c += 10; + } else + c -= '0'; + + byte = c * 16; + + c = *cp; + + if ((c >= 'A') && (c <= 'F')) { + c -= 'A'; + c += 10; + } else if ((c >= 'a') && (c <= 'f')) { + c -= 'a'; + c += 10; + } else + c -= '0'; + + byte += c; + + return(byte); +} + static void rpx_eth(bd_t *bd, u_char *cp) { @@ -87,6 +135,7 @@ rpx_eth(bd_t *bd, u_char *cp) } } +#ifdef CONFIG_RPX6 static uint rpx_baseten(u_char *cp) { @@ -101,7 +150,9 @@ rpx_baseten(u_char *cp) } return(retval); } +#endif +#if defined(CONFIG_RPXLITE) || defined(CONFIG_RPXCLASSIC) static void rpx_brate(bd_t *bd, u_char *cp) { @@ -119,22 +170,6 @@ rpx_brate(bd_t *bd, u_char *cp) } static void -rpx_memsize(bd_t *bd, u_char *cp) -{ - uint size; - - size = 0; - - while (*cp != '\n') { - size *= 10; - size += (*cp) - '0'; - cp++; - } - - bd->bi_memsize = size * 1024 * 1024; -} - -static void rpx_cpuspeed(bd_t *bd, u_char *cp) { uint num, den; @@ -168,63 +203,45 @@ rpx_cpuspeed(bd_t *bd, u_char *cp) if (num > 50) bd->bi_busfreq /= 2; } +#endif -/* Because I didn't find anything that would do this....... -*/ -u_char -aschex_to_byte(u_char *cp) +#if defined(CONFIG_RPXLITE) || defined(CONFIG_RPXCLASSIC) || defined(CONFIG_EP405) +static void +rpx_memsize(bd_t *bd, u_char *cp) { - u_char byte, c; - - c = *cp++; - - if ((c >= 'A') && (c <= 'F')) { - c -= 'A'; - c += 10; - } - else if ((c >= 'a') && (c <= 'f')) { - c -= 'a'; - c += 10; - } - else { - c -= '0'; - } - - byte = c * 16; + uint size; - c = *cp; + size = 0; - if ((c >= 'A') && (c <= 'F')) { - c -= 'A'; - c += 10; - } - else if ((c >= 'a') && (c <= 'f')) { - c -= 'a'; - c += 10; - } - else { - c -= '0'; + while (*cp != '\n') { + size *= 10; + size += (*cp) - '0'; + cp++; } - - byte += c; - return(byte); + bd->bi_memsize = size * 1024 * 1024; } -#endif +#endif /* LITE || CLASSIC || EP405 */ + +#endif /* Embedded Planet boards */ #if defined(CONFIG_RPXLITE) || defined(CONFIG_RPXCLASSIC) /* Read the EEPROM on the RPX-Lite board. */ void -embed_config(bd_t *bd) +embed_config(bd_t **bdp) { u_char eebuf[256], *cp; + bd_t *bd; /* Read the first 256 bytes of the EEPROM. I think this * is really all there is, and I hope if it gets bigger the * info we want is still up front. */ + bd = &bdinfo; + *bdp = bd; + #if 1 iic_read(0xa8, eebuf, 0, 128); iic_read(0xa8, &eebuf[128], 128, 128); @@ -294,10 +311,14 @@ embed_config(bd_t *bd) * variables and a function to read them. */ void -embed_config(bd_t *bd) +embed_config(bd_t **bdp) { u_char *cp; int i; + bd_t *bd; + + bd = &bdinfo; + *bdp = bd; /* Baud rate and processor speed will eventually come * from the environment variables. @@ -324,10 +345,14 @@ embed_config(bd_t *bd) /* Build a board information structure for the FADS. */ void -embed_config(bd_t *bd) +embed_config(bd_t **bdp) { u_char *cp; int i; + bd_t *bd; + + bd = &bdinfo; + *bdp = bd; /* Just fill in some known values. */ @@ -427,10 +452,6 @@ embed_config(bd_t **bdp) #endif /* EST8260 */ #ifdef CONFIG_SBS8260 -/* We have to fill in everything. -*/ -static bd_t bdinfo; - void embed_config(bd_t **bdp) { @@ -464,10 +485,6 @@ embed_config(bd_t **bdp) #endif /* SBS8260 */ #ifdef CONFIG_RPX6 -/* The pointer we are given is for the string of key values. - */ -static bd_t bdinfo; - void embed_config(bd_t **bdp) { @@ -555,10 +572,6 @@ embed_config(bd_t **bdp) #endif /* RPX6 for testing */ #ifdef CONFIG_ADS8260 -/* We have to fill in everything. -*/ -static bd_t bdinfo; - void embed_config(bd_t **bdp) { @@ -591,3 +604,152 @@ embed_config(bd_t **bdp) } #endif /* ADS8260 */ +#ifdef CONFIG_WILLOW +void +embed_config(bd_t **bdp) +{ + u_char *cp; + int i; + bd_t *bd; + + /* Willow has Open Firmware....I should learn how to get this + * information from it. + */ + bd = &bdinfo; + *bdp = bd; + bd->bi_baudrate = 9600; + bd->bi_memsize = 32 * 1024 * 1024; + + /* Set all of the clocks. We have to know the speed of the + * external clock. The development board had 66 MHz. + */ + bd->bi_busfreq = 66666666; + clk_8260(bd); + + /* I don't know how to compute this yet. + */ + bd->bi_intfreq = 200000000; + + + cp = (u_char *)def_enet_addr; + for (i=0; i<6; i++) { + bd->bi_enetaddr[i] = *cp++; + } +} +#endif /* WILLOW */ + +#ifdef CONFIG_TREEBOOT +/* This could possibly work for all treeboot roms. +*/ +#define BOARD_INFO_VECTOR 0xFFFE0B50 + +void +embed_config(bd_t **bdp) +{ + u_char *cp; + int i; + bd_t *bd, *treeboot_bd; + bd_t *(*get_board_info)(void) = + (bd_t *(*)(void))(*(unsigned long *)BOARD_INFO_VECTOR); +#if !defined(CONFIG_STB03xxx) + volatile emac_t *emacp; + emacp = (emac_t *)EMAC0_BASE; /* assume 1st emac - armin */ + + /* shut down the Ethernet controller that the boot rom + * sometimes leaves running. + */ + mtdcr(DCRN_MALCR, MALCR_MMSR); /* 1st reset MAL */ + while (mfdcr(DCRN_MALCR) & MALCR_MMSR) {}; /* wait for the reset */ + emacp->em0mr0 = 0x20000000; /* then reset EMAC */ + eieio(); +#endif + + bd = &bdinfo; + *bdp = bd; + if ((treeboot_bd = get_board_info()) != NULL) { + memcpy(bd, treeboot_bd, sizeof(bd_t)); + } + else { + /* Hmmm...better try to stuff some defaults. + */ + bd->bi_memsize = 16 * 1024 * 1024; + cp = (u_char *)def_enet_addr; + for (i=0; i<6; i++) { + /* I should probably put different ones here, + * hopefully only one is used. + */ + bd->BD_EMAC_ADDR(0,i) = *cp; + +#ifdef CONFIG_PCI + bd->bi_pci_enetaddr[i] = *cp++; +#endif + } + bd->bi_intfreq = 200000000; + bd->bi_busfreq = 100000000; +#ifdef CONFIG_PCI + bd->bi_pci_busfreq = 66666666; +#endif + /* Yeah, this look weird, but on Redwood 4 they are + * different object in the structure. When RW5 uses + * OpenBIOS, it requires a special value. + */ +#ifdef CONFIG_REDWOOD_5 + bd->bi_intfreq = 200 * 1000 * 1000; + bd->bi_busfreq = 0; + + bd->bi_tbfreq = 27 * 1000 * 1000; +#elif CONFIG_REDWOOD_4 + bd->bi_tbfreq = bd->bi_intfreq; +#endif + } +} +#endif + +#ifdef CONFIG_EP405 +void +embed_config(bd_t **bdp) +{ + u_char *cp; + bd_t *bd; + + bd = &bdinfo; + *bdp = bd; +#if 1 + cp = (u_char *)0xF0000EE0; + for (;;) { + if (*cp == 'E') { + cp++; + if (*cp == 'A') { + cp += 2; + rpx_eth(bd, cp); + } + } + + if (*cp == 'D') { + cp++; + if (*cp == '1') { + cp += 2; + rpx_memsize(bd, cp); + } + } + + while ((*cp != '\n') && (*cp != 0xff)) + cp++; + + cp++; + if ((*cp == 0) || (*cp == 0xff)) + break; + } + bd->bi_intfreq = 200000000; + bd->bi_busfreq = 100000000; + bd->bi_pci_busfreq= 33000000 ; +#else + + bd->bi_memsize = 64000000; + bd->bi_intfreq = 200000000; + bd->bi_busfreq = 100000000; + bd->bi_pci_busfreq= 33000000 ; +#endif +} +#endif + diff --git a/arch/ppc/boot/simple/gt64260_tty.c b/arch/ppc/boot/simple/gt64260_tty.c new file mode 100644 index 000000000000..9bd22b0ede78 --- /dev/null +++ b/arch/ppc/boot/simple/gt64260_tty.c @@ -0,0 +1,327 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ +/* + * arch/ppc/boot/simple/gt64260_tty.c + * + * Bootloader version of the embedded MPSC/UART driver for the GT64260[A]. + * Note: Due to 64260A errata, DMA will be used for UART input (via SDMA). + * + * Author: Mark A. Greer <mgreer@mvista.com> + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +/* This code assumes that the data cache has been disabled (L1, L2, L3). */ + +#include <linux/config.h> +#include <linux/serialP.h> +#include <linux/serial_reg.h> +#include <asm/serial.h> +#include <asm/gt64260_defs.h> + +extern void udelay(long); +static void stop_dma(int chan); + +static u32 gt64260_base = EV64260_BRIDGE_REG_BASE; /* base addr of 64260 */ + +inline unsigned +gt64260_in_le32(volatile unsigned *addr) +{ + unsigned ret; + + __asm__ __volatile__("lwbrx %0,0,%1; eieio" : "=r" (ret) : + "r" (addr), "m" (*addr)); + return ret; +} + +inline void +gt64260_out_le32(volatile unsigned *addr, int val) +{ + __asm__ __volatile__("stwbrx %1,0,%2; eieio" : "=m" (*addr) : + "r" (val), "r" (addr)); +} + +#define GT64260_REG_READ(offs) \ + (gt64260_in_le32((volatile uint *)(gt64260_base + (offs)))) +#define GT64260_REG_WRITE(offs, d) \ + (gt64260_out_le32((volatile uint *)(gt64260_base + (offs)), (int)(d))) + + +static struct { + u32 sdc; + u32 sdcm; + u32 rx_desc; + u32 rx_buf_ptr; + u32 scrdp; + u32 tx_desc; + u32 sctdp; + u32 sftdp; +} sdma_regs; + +#define SDMA_REGS_INIT(chan) { \ + sdma_regs.sdc = GT64260_SDMA_##chan##_SDC; \ + sdma_regs.sdcm = GT64260_SDMA_##chan##_SDCM; \ + sdma_regs.rx_desc = GT64260_SDMA_##chan##_RX_DESC; \ + sdma_regs.rx_buf_ptr = GT64260_SDMA_##chan##_RX_BUF_PTR; \ + sdma_regs.scrdp = GT64260_SDMA_##chan##_SCRDP; \ + sdma_regs.tx_desc = GT64260_SDMA_##chan##_TX_DESC; \ + sdma_regs.sctdp = GT64260_SDMA_##chan##_SCTDP; \ + sdma_regs.sftdp = GT64260_SDMA_##chan##_SFTDP; \ +} + +typedef struct { + volatile u16 bufsize; + volatile u16 bytecnt; + volatile u32 cmd_stat; + volatile u32 next_desc_ptr; + volatile u32 buffer; +} gt64260_rx_desc_t; + +typedef struct { + volatile u16 bytecnt; + volatile u16 shadow; + volatile u32 cmd_stat; + volatile u32 next_desc_ptr; + volatile u32 buffer; +} gt64260_tx_desc_t; + +#define MAX_RESET_WAIT 10000 +#define MAX_TX_WAIT 10000 + +#define RX_NUM_DESC 2 +#define TX_NUM_DESC 2 + +#define RX_BUF_SIZE 16 +#define TX_BUF_SIZE 16 + +static gt64260_rx_desc_t rd[RX_NUM_DESC] __attribute__ ((aligned(32))); +static gt64260_tx_desc_t td[TX_NUM_DESC] __attribute__ ((aligned(32))); + +static char rx_buf[RX_NUM_DESC * RX_BUF_SIZE] __attribute__ ((aligned(32))); +static char tx_buf[TX_NUM_DESC * TX_BUF_SIZE] __attribute__ ((aligned(32))); + +static int cur_rd = 0; +static int cur_td = 0; + + +#define RX_INIT_RDP(rdp) { \ + (rdp)->bufsize = 2; \ + (rdp)->bytecnt = 0; \ + (rdp)->cmd_stat = GT64260_SDMA_DESC_CMDSTAT_L | \ + GT64260_SDMA_DESC_CMDSTAT_F | \ + GT64260_SDMA_DESC_CMDSTAT_O; \ +} + +unsigned long +serial_init(int chan, void *ignored) +{ + u32 mpsc_adjust, sdma_adjust, brg_bcr; + int i; + + stop_dma(0); + stop_dma(1); + + if (chan != 1) { + chan = 0; /* default to chan 0 if anything but 1 */ + mpsc_adjust = 0; + sdma_adjust = 0; + brg_bcr = GT64260_BRG_0_BCR; + SDMA_REGS_INIT(0); + } + else { + mpsc_adjust = 0x1000; + sdma_adjust = 0x2000; + brg_bcr = GT64260_BRG_1_BCR; + SDMA_REGS_INIT(1); + } + + /* Set up ring buffers */ + for (i=0; i<RX_NUM_DESC; i++) { + RX_INIT_RDP(&rd[i]); + rd[i].buffer = (u32)&rx_buf[i * RX_BUF_SIZE]; + rd[i].next_desc_ptr = (u32)&rd[i+1]; + } + rd[RX_NUM_DESC - 1].next_desc_ptr = (u32)&rd[0]; + + for (i=0; i<TX_NUM_DESC; i++) { + td[i].bytecnt = 0; + td[i].shadow = 0; + td[i].buffer = (u32)&tx_buf[i * TX_BUF_SIZE]; + td[i].cmd_stat = GT64260_SDMA_DESC_CMDSTAT_F | + GT64260_SDMA_DESC_CMDSTAT_L; + td[i].next_desc_ptr = (u32)&td[i+1]; + } + td[TX_NUM_DESC - 1].next_desc_ptr = (u32)&td[0]; + + /* Set MPSC Routing */ + GT64260_REG_WRITE(GT64260_MPSC_MRR, 0x3ffffe38); + GT64260_REG_WRITE(GT64260_MPP_SERIAL_PORTS_MULTIPLEX, 0x00001102); + + /* MPSC 0/1 Rx & Tx get clocks BRG0/1 */ + GT64260_REG_WRITE(GT64260_MPSC_RCRR, 0x00000100); + GT64260_REG_WRITE(GT64260_MPSC_TCRR, 0x00000100); + + /* clear pending interrupts */ + GT64260_REG_WRITE(GT64260_SDMA_INTR_MASK, 0); + + GT64260_REG_WRITE(GT64260_SDMA_0_SCRDP + sdma_adjust, &rd[0]); + GT64260_REG_WRITE(GT64260_SDMA_0_SCTDP + sdma_adjust, + &td[TX_NUM_DESC - 1]); + GT64260_REG_WRITE(GT64260_SDMA_0_SFTDP + sdma_adjust, + &td[TX_NUM_DESC - 1]); + + GT64260_REG_WRITE(GT64260_SDMA_0_SDC + sdma_adjust, + GT64260_SDMA_SDC_RFT | GT64260_SDMA_SDC_SFM | + GT64260_SDMA_SDC_BLMR | GT64260_SDMA_SDC_BLMT | + (3 << 12)); + + /* Set BRG to generate proper baud rate */ + GT64260_REG_WRITE(brg_bcr, ((8 << 18) | (1 << 16) | 36)); + + /* Put MPSC into UART mode, no null modem, 16x clock mode */ + GT64260_REG_WRITE(GT64260_MPSC_0_MMCRL + mpsc_adjust, 0x000004c4); + GT64260_REG_WRITE(GT64260_MPSC_0_MMCRH + mpsc_adjust, 0x04400400); + + GT64260_REG_WRITE(GT64260_MPSC_0_CHR_1 + mpsc_adjust, 0); + GT64260_REG_WRITE(GT64260_MPSC_0_CHR_9 + mpsc_adjust, 0); + GT64260_REG_WRITE(GT64260_MPSC_0_CHR_10 + mpsc_adjust, 0); + GT64260_REG_WRITE(GT64260_MPSC_0_CHR_3 + mpsc_adjust, 4); + GT64260_REG_WRITE(GT64260_MPSC_0_CHR_4 + mpsc_adjust, 0); + GT64260_REG_WRITE(GT64260_MPSC_0_CHR_5 + mpsc_adjust, 0); + GT64260_REG_WRITE(GT64260_MPSC_0_CHR_6 + mpsc_adjust, 0); + GT64260_REG_WRITE(GT64260_MPSC_0_CHR_7 + mpsc_adjust, 0); + GT64260_REG_WRITE(GT64260_MPSC_0_CHR_8 + mpsc_adjust, 0); + + /* 8 data bits, 1 stop bit */ + GT64260_REG_WRITE(GT64260_MPSC_0_MPCR + mpsc_adjust, (3 << 12)); + + GT64260_REG_WRITE(GT64260_SDMA_0_SDCM + sdma_adjust, + GT64260_SDMA_SDCM_ERD); + + GT64260_REG_WRITE(GT64260_MPSC_0_CHR_2 + sdma_adjust, + GT64260_MPSC_UART_CR_EH); + + udelay(100); + + return (ulong)chan; +} + +static void +stop_dma(int chan) +{ + u32 sdma_sdcm = GT64260_SDMA_0_SDCM; + int i; + + if (chan == 1) { + sdma_sdcm = GT64260_SDMA_1_SDCM; + } + + /* Abort SDMA Rx, Tx */ + GT64260_REG_WRITE(sdma_sdcm, + GT64260_SDMA_SDCM_AR | GT64260_SDMA_SDCM_STD); + + for (i=0; i<MAX_RESET_WAIT; i++) { + if ((GT64260_REG_READ(sdma_sdcm) & (GT64260_SDMA_SDCM_AR | + GT64260_SDMA_SDCM_AT)) == 0) break; + udelay(100); + } + + return; +} + +static int +wait_for_ownership(void) +{ + int i; + + for (i=0; i<MAX_TX_WAIT; i++) { + if ((GT64260_REG_READ(sdma_regs.sdcm) & + GT64260_SDMA_SDCM_TXD) == 0) break; + udelay(1000); + } + + return (i < MAX_TX_WAIT); +} + +void +serial_putc(unsigned long com_port, unsigned char c) +{ + gt64260_tx_desc_t *tdp; + + if (wait_for_ownership() == 0) return; + + tdp = &td[cur_td]; + if (++cur_td >= TX_NUM_DESC) cur_td = 0; + + *(unchar *)(tdp->buffer ^ 7) = c; + tdp->bytecnt = 1; + tdp->shadow = 1; + tdp->cmd_stat = GT64260_SDMA_DESC_CMDSTAT_L | + GT64260_SDMA_DESC_CMDSTAT_F | GT64260_SDMA_DESC_CMDSTAT_O; + + GT64260_REG_WRITE(sdma_regs.sctdp, tdp); + GT64260_REG_WRITE(sdma_regs.sftdp, tdp); + GT64260_REG_WRITE(sdma_regs.sdcm, + GT64260_REG_READ(sdma_regs.sdcm) | GT64260_SDMA_SDCM_TXD); + + return; +} + +unsigned char +serial_getc(unsigned long com_port) +{ + gt64260_rx_desc_t *rdp; + unchar c = '\0'; + + rdp = &rd[cur_rd]; + + if ((rdp->cmd_stat & (GT64260_SDMA_DESC_CMDSTAT_O | + GT64260_SDMA_DESC_CMDSTAT_ES)) == 0) { + c = *(unchar *)(rdp->buffer ^ 7); + RX_INIT_RDP(rdp); + if (++cur_rd >= RX_NUM_DESC) cur_rd = 0; + } + + return c; +} + +int +serial_tstc(unsigned long com_port) +{ + gt64260_rx_desc_t *rdp; + int loop_count = 0; + int rc = 0; + + rdp = &rd[cur_rd]; + + /* Go thru rcv desc's until empty looking for one with data (no error)*/ + while (((rdp->cmd_stat & GT64260_SDMA_DESC_CMDSTAT_O) == 0) && + (loop_count++ < RX_NUM_DESC)) { + + /* If there was an error, reinit the desc & continue */ + if ((rdp->cmd_stat & GT64260_SDMA_DESC_CMDSTAT_ES) != 0) { + RX_INIT_RDP(rdp); + if (++cur_rd >= RX_NUM_DESC) cur_rd = 0; + rdp = (gt64260_rx_desc_t *)rdp->next_desc_ptr; + } + else { + rc = 1; + break; + } + } + + return rc; +} + +void +serial_close(unsigned long com_port) +{ + stop_dma(com_port); + return; +} diff --git a/arch/ppc/boot/simple/head.S b/arch/ppc/boot/simple/head.S new file mode 100644 index 000000000000..7d661d62c9a7 --- /dev/null +++ b/arch/ppc/boot/simple/head.S @@ -0,0 +1,120 @@ +/* + * arch/ppc/boot/simple/head.S + * + * Initial board bringup code for many different boards. + * + * Author: Tom Rini + * trini@mvista.com + * Derived from arch/ppc/boot/prep/head.S (Cort Dougan, many others). + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include <linux/config.h> +#include <asm/processor.h> +#include <asm/cache.h> +#include <asm/ppc_asm.h> + + .text + +/* + * Begin at some arbitrary location in RAM or Flash + * Initialize core registers + * Configure memory controller (Not executing from RAM) + * Move the boot code to the link address (8M) + * Setup C stack + * Initialize UART + * Decompress the kernel to 0x0 + * Jump to the kernel entry + * + */ + + .globl start +start: + bl start_ +#ifdef CONFIG_TREEBOOT + /* The IBM "Tree" bootrom knows that the address of the bootrom + * read only structure is 4 bytes after _start. + */ + .long 0x62726f6d # structure ID - "brom" + .long 0x5f726f00 # - "_ro\0" + .long 1 # structure version + .long bootrom_cmdline # address of *bootrom_cmdline +#endif + +start_: +#ifdef CONFIG_FORCE + /* We have some really bad firmware. We must disable the L1 + * icache/dcache now or the board won't boot. + */ + li r4,0x0000 + isync + mtspr HID0,r4 + sync + isync +#endif + +#if defined(CONFIG_MBX) || defined(CONFIG_RPX6) + mr r29,r3 /* On the MBX860, r3 is the board info pointer. + * On the RPXSUPER, r3 points to the + * NVRAM configuration keys. + */ +#endif + + mflr r3 /* Save our actual starting address. */ + + /* The following functions we call must not modify r3 or r4..... + */ +#ifdef CONFIG_6xx + bl disable_6xx_mmu + bl disable_6xx_l1cache +#if defined(CONFIG_FORCE) || defined(CONFIG_K2) || defined(CONFIG_EV64260) + bl _setup_L2CR +#endif +#endif + +#ifdef CONFIG_8xx + mfmsr r8 /* Turn off interrupts */ + li r9,0 + ori r9,r9,MSR_EE + andc r8,r8,r9 + mtmsr r8 + + /* We do this because some boot roms don't initialize the + * processor correctly. Don't do this if you want to debug + * using a BDM device. + */ + li r4,0 /* Zero DER to prevent FRZ */ + mtspr SPRN_DER,r4 +#endif + +#ifdef CONFIG_REDWOOD_4 + /* All of this Redwood 4 stuff will soon disappear when the + * boot rom is straightened out. + */ + mr r29, r3 /* Easier than changing the other code */ + bl HdwInit + mr r3, r29 +#endif + +#if defined(CONFIG_MBX) || defined(CONFIG_RPX6) + mr r4,r29 /* put the board info pointer where the relocate + * routine will find it + */ +#endif + +#ifdef CONFIG_EV64260 + /* Move 64260's base regs & CS window for external UART */ + bl ev64260_init +#endif + + /* Get the load address. + */ + subi r3, r3, 4 /* Get the actual IP, not NIP */ + b relocate + diff --git a/arch/ppc/boot/mbx/iic.c b/arch/ppc/boot/simple/iic.c index 8e4401036e4f..12b9fad42ee9 100644 --- a/arch/ppc/boot/mbx/iic.c +++ b/arch/ppc/boot/simple/iic.c @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.iic.c 1.10 09/14/01 19:30:13 trini + * BK Id: %F% %I% %G% %U% %#% */ /* Minimal support functions to read configuration from IIC EEPROMS @@ -21,7 +21,7 @@ void iic_read(uint devaddr, u_char *buf, uint offset, uint count); static int iic_init_done; static void -iic_init() +iic_init(void) { volatile iic_t *iip; volatile i2c8xx_t *i2c; diff --git a/arch/ppc/boot/simple/legacy.S b/arch/ppc/boot/simple/legacy.S new file mode 100644 index 000000000000..ae2769a1f512 --- /dev/null +++ b/arch/ppc/boot/simple/legacy.S @@ -0,0 +1,19 @@ +/* + * arch/ppc/boot/simple/legacy.S + * + * Author: Tom Rini <trini@mvista.com> + * + * This will go and setup ISA_io to 0x8000000. + */ + +#include <asm/ppc_asm.h> + + .text + + .globl setup_legacy +setup_legacy: + lis r3,ISA_io@h /* Load ISA_io */ + ori r3,r3,ISA_io@l + lis r4,0x8000 /* Load the value, 0x8000000 */ + stw r4,0(r3) /* store */ + blr diff --git a/arch/ppc/boot/mbx/m8260_tty.c b/arch/ppc/boot/simple/m8260_tty.c index 0035c14db7a4..9402ec60f507 100644 --- a/arch/ppc/boot/mbx/m8260_tty.c +++ b/arch/ppc/boot/simple/m8260_tty.c @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.m8260_tty.c 1.7 05/18/01 07:54:04 patch + * BK Id: %F% %I% %G% %U% %#% */ @@ -24,13 +24,15 @@ static int cons_hold_cnt; #define SCC_CONSOLE 1 #endif -void -serial_init(bd_t *bd) +unsigned long +serial_init(int ignored, bd_t *bd) { volatile smc_t *sp; volatile smc_uart_t *up; +#ifdef SCC_CONSOLE volatile scc_t *sccp; volatile scc_uart_t *sup; +#endif volatile cbd_t *tbdf, *rbdf; volatile immap_t *ip; volatile iop8260_t *io; @@ -149,7 +151,7 @@ serial_init(bd_t *bd) * Enable receive and transmit. */ sccp->scc_gsmrh = 0; - sccp->scc_gsmrl = + sccp->scc_gsmrl = (SCC_GSMRL_MODE_UART | SCC_GSMRL_TDCR_16 | SCC_GSMRL_RDCR_16); /* Disable all interrupts and clear all pending @@ -213,6 +215,42 @@ serial_init(bd_t *bd) */ sp->smc_smcmr |= SMCMR_REN | SMCMR_TEN; #endif + + /* This is ignored. + */ + return 0; +} + +int +serial_readbuf(u_char *cbuf) +{ + volatile cbd_t *rbdf; + volatile char *buf; + volatile smc_uart_t *up; + volatile scc_uart_t *sup; + volatile immap_t *ip; + int i, nc; + + ip = (immap_t *)IMAP_ADDR; + +#ifdef SCC_CONSOLE + sup = (scc_uart_t *)&ip->im_dprambase[PROFF_SCC1 + ((SCC_CONSOLE-1) << 8)]; + rbdf = (cbd_t *)&ip->im_dprambase[sup->scc_genscc.scc_rbase]; +#else + up = (smc_uart_t *)&(ip->im_dprambase[PROFF_SMC1]); + rbdf = (cbd_t *)&ip->im_dprambase[up->smc_rbase]; +#endif + + /* Wait for character to show up. + */ + buf = (char *)rbdf->cbd_bufaddr; + while (rbdf->cbd_sc & BD_SC_EMPTY); + nc = rbdf->cbd_datlen; + for (i=0; i<nc; i++) + *cbuf++ = *buf++; + rbdf->cbd_sc |= BD_SC_EMPTY; + + return(nc); } void @@ -260,17 +298,14 @@ serial_getc(void *ignored) } int -serial_readbuf(u_char *cbuf) +serial_tstc(void *ignored) { volatile cbd_t *rbdf; - volatile char *buf; volatile smc_uart_t *up; volatile scc_uart_t *sup; volatile immap_t *ip; - int i, nc; ip = (immap_t *)IMAP_ADDR; - #ifdef SCC_CONSOLE sup = (scc_uart_t *)&ip->im_dprambase[PROFF_SCC1 + ((SCC_CONSOLE-1) << 8)]; rbdf = (cbd_t *)&ip->im_dprambase[sup->scc_genscc.scc_rbase]; @@ -279,34 +314,10 @@ serial_readbuf(u_char *cbuf) rbdf = (cbd_t *)&ip->im_dprambase[up->smc_rbase]; #endif - /* Wait for character to show up. - */ - buf = (char *)rbdf->cbd_bufaddr; - while (rbdf->cbd_sc & BD_SC_EMPTY); - nc = rbdf->cbd_datlen; - for (i=0; i<nc; i++) - *cbuf++ = *buf++; - rbdf->cbd_sc |= BD_SC_EMPTY; - - return(nc); + return(!(rbdf->cbd_sc & BD_SC_EMPTY)); } -int -serial_tstc(void *ignored) +void +serial_close(unsigned long com_port) { - volatile cbd_t *rbdf; - volatile smc_uart_t *up; - volatile scc_uart_t *sup; - volatile immap_t *ip; - - ip = (immap_t *)IMAP_ADDR; -#ifdef SCC_CONSOLE - sup = (scc_uart_t *)&ip->im_dprambase[PROFF_SCC1 + ((SCC_CONSOLE-1) << 8)]; - rbdf = (cbd_t *)&ip->im_dprambase[sup->scc_genscc.scc_rbase]; -#else - up = (smc_uart_t *)&(ip->im_dprambase[PROFF_SMC1]); - rbdf = (cbd_t *)&ip->im_dprambase[up->smc_rbase]; -#endif - - return(!(rbdf->cbd_sc & BD_SC_EMPTY)); } diff --git a/arch/ppc/boot/mbx/m8xx_tty.c b/arch/ppc/boot/simple/m8xx_tty.c index 902faba609fd..328469241509 100644 --- a/arch/ppc/boot/mbx/m8xx_tty.c +++ b/arch/ppc/boot/simple/m8xx_tty.c @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.m8xx_tty.c 1.10 09/14/01 19:30:13 trini + * BK Id: %F% %I% %G% %U% %#% */ @@ -37,14 +37,17 @@ static volatile iop8xx_t *iopp = (iop8xx_t *)&(((immap_t *)IMAP_ADDR)->im_ioport static cpm8xx_t *cpmp = (cpm8xx_t *)&(((immap_t *)IMAP_ADDR)->im_cpm); -void -serial_init(bd_t *bd) +unsigned long +serial_init(int ignored, bd_t *bd) { volatile smc_t *sp; volatile smc_uart_t *up; volatile cbd_t *tbdf, *rbdf; volatile cpm8xx_t *cp; - uint dpaddr, memaddr, ui; + uint dpaddr, memaddr; +#ifndef CONFIG_MBX + uint ui; +#endif cp = cpmp; sp = (smc_t*)&(cp->cp_smc[SMC_INDEX]); @@ -232,6 +235,10 @@ serial_init(bd_t *bd) /* Enable transmitter/receiver. */ sp->smc_smcmr |= SMCMR_REN | SMCMR_TEN; + + /* This is ignored. + */ + return 0; } void @@ -286,3 +293,8 @@ serial_tstc(void *ignored) return(!(rbdf->cbd_sc & BD_SC_EMPTY)); } + +void +serial_close(unsigned long com_port) +{ +} diff --git a/arch/ppc/boot/simple/misc-embedded.c b/arch/ppc/boot/simple/misc-embedded.c new file mode 100644 index 000000000000..8f2f9a8e0fd8 --- /dev/null +++ b/arch/ppc/boot/simple/misc-embedded.c @@ -0,0 +1,242 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + * + * Originally adapted by Gary Thomas. Much additional work by + * Cort Dougan <cort@fsmlabs.com>. On top of that still more work by + * Dan Malek <dmalek@jlc.net>. + * + * Currently maintained by: Tom Rini <trini@kernel.crashing.org> + */ + +#include <linux/config.h> +#include <linux/types.h> +#include <linux/elf.h> +#include <asm/bootinfo.h> +#include <asm/ibm4xx.h> +#include <asm/mmu.h> +#include <asm/mpc8xx.h> +#include <asm/mpc8260.h> +#include <asm/page.h> +#include <asm/processor.h> +#include <asm/residual.h> + +#include "nonstdio.h" +#include "zlib.h" + +/* The linker tells us where the image is. */ +extern char __image_begin, __image_end; +extern char __ramdisk_begin, __ramdisk_end; +extern char _end[]; + +/* Because of the limited amount of memory on embedded, it presents + * loading problems. The biggest is that we load this boot program + * into a relatively low memory address, and the Linux kernel Bss often + * extends into this space when it get loaded. When the kernel starts + * and zeros the BSS space, it also writes over the information we + * save here and pass to the kernel (usually board info). + * On these boards, we grab some known memory holes to hold this information. + */ +char cmd_buf[256]; +char *cmd_line = cmd_buf; +char *avail_ram; +char *end_avail; +char *zimage_start; + +/* This is for 4xx treeboot. It provides a place for the bootrom + * give us a pointer to a rom environment command line. + */ +char *bootrom_cmdline = ""; + +/* This is the default cmdline that will be given to the user at boot time.. + * If none was specified at compile time, we'll give it one that should work. + * -- Tom */ +#ifdef CONFIG_CMDLINE_BOOL +char compiled_string[] = CONFIG_CMDLINE; +#endif +char ramroot_string[] = "root=/dev/ram"; +char netroot_string[] = "root=/dev/nfs rw ip=auto"; + +/* Serial port to use. */ +unsigned long com_port; + +bd_t hold_resid_buf; +bd_t *hold_residual = &hold_resid_buf; + +extern unsigned long serial_init(int chan, bd_t *bp); +extern void serial_close(unsigned long com_port); +extern unsigned long start; +extern void flush_instruction_cache(void); +extern void gunzip(void *, int, unsigned char *, int *); +extern void embed_config(bd_t **bp); + +unsigned long +decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum, bd_t *bp) +{ + char *cp, ch; + int timer = 0, zimage_size; + unsigned long initrd_size; + + /* First, capture the embedded board information. Then + * initialize the serial console port. + */ + embed_config(&bp); +#ifdef CONFIG_SERIAL_CONSOLE + com_port = serial_init(0, bp); +#endif + + /* Grab some space for the command line and board info. Since + * we no longer use the ELF header, but it was loaded, grab + * that space. + */ +#ifdef CONFIG_MBX + /* Because of the way the MBX loads the ELF image, we can't + * tell where we started. We read a magic variable from the NVRAM + * that gives us the intermediate buffer load address. + */ + load_addr = *(uint *)0xfa000020; + load_addr += 0x10000; /* Skip ELF header */ +#endif + /* copy board data */ + if (bp) + memcpy(hold_residual,bp,sizeof(bd_t)); + + /* Set end of memory available to us. It is always the highest + * memory address provided by the board information. + */ + end_avail = (char *)(bp->bi_memsize); + + puts("\nloaded at: "); puthex(load_addr); + puts(" "); puthex((unsigned long)(load_addr + (4*num_words))); puts("\n"); + if ( (unsigned long)load_addr != (unsigned long)&start ) { + puts("relocated to: "); puthex((unsigned long)&start); + puts(" "); + puthex((unsigned long)((unsigned long)&start + (4*num_words))); + puts("\n"); + } + + if ( bp ) { + puts("board data at: "); puthex((unsigned long)bp); + puts(" "); + puthex((unsigned long)((unsigned long)bp + sizeof(bd_t))); + puts("\nrelocated to: "); + puthex((unsigned long)hold_residual); + puts(" "); + puthex((unsigned long)((unsigned long)hold_residual + sizeof(bd_t))); + puts("\n"); + } + + /* + * We link ourself to an arbitrary low address. When we run, we + * relocate outself to that address. __image_being points to + * the part of the image where the zImage is. -- Tom + */ + zimage_start = (char *)(unsigned long)(&__image_begin); + zimage_size = (unsigned long)(&__image_end) - + (unsigned long)(&__image_begin); + + initrd_size = (unsigned long)(&__ramdisk_end) - + (unsigned long)(&__ramdisk_begin); + + /* + * The zImage and initrd will be between start and _end, so they've + * already been moved once. We're good to go now. -- Tom + */ + puts("zimage at: "); puthex((unsigned long)zimage_start); + puts(" "); puthex((unsigned long)(zimage_size+zimage_start)); + puts("\n"); + + if ( initrd_size ) { + puts("initrd at: "); + puthex((unsigned long)(&__ramdisk_begin)); + puts(" "); puthex((unsigned long)(&__ramdisk_end));puts("\n"); + } + + /* + * setup avail_ram - this is the first part of ram usable + * by the uncompress code. Anything after this program in RAM + * is now fair game. -- Tom + */ + avail_ram = (char *)PAGE_ALIGN((unsigned long)_end); + + puts("avail ram: "); puthex((unsigned long)avail_ram); puts(" "); + puthex((unsigned long)end_avail); puts("\n"); + puts("\nLinux/PPC load: "); + cp = cmd_line; + /* This is where we try and pick the right command line for booting. + * If we were given one at compile time, use it. It Is Right. + * If we weren't, see if we have a ramdisk. If so, thats root. + * When in doubt, give them the netroot (root=/dev/nfs rw) -- Tom + */ +#ifdef CONFIG_CMDLINE_BOOL + memcpy (cmd_line, compiled_string, sizeof(compiled_string)); +#else + if ( initrd_size ) + memcpy (cmd_line, ramroot_string, sizeof(ramroot_string)); + else + memcpy (cmd_line, netroot_string, sizeof(netroot_string)); +#endif + while ( *cp ) + putc(*cp++); + while (timer++ < 5*1000) { + if (tstc()) { + while ((ch = getc()) != '\n' && ch != '\r') { + if (ch == '\b' || ch == '\177') { + if (cp != cmd_line) { + cp--; + puts("\b \b"); + } + } else if (ch == '\030' /* ^x */ + || ch == '\025') { /* ^u */ + while (cp != cmd_line) { + cp--; + puts("\b \b"); + } + } else { + *cp++ = ch; + putc(ch); + } + } + break; /* Exit 'timer' loop */ + } + udelay(1000); /* 1 msec */ + } + *cp = 0; + puts("\nUncompressing Linux..."); + + gunzip(0, 0x400000, zimage_start, &zimage_size); + flush_instruction_cache(); + puts("done.\n"); + { + struct bi_record *rec; + + rec = (struct bi_record *)_ALIGN((unsigned long)zimage_size + + (1 << 20) - 1,(1 << 20)); + + rec->tag = BI_FIRST; + rec->size = sizeof(struct bi_record); + rec = (struct bi_record *)((unsigned long)rec + rec->size); + + rec->tag = BI_CMD_LINE; + memcpy( (char *)rec->data, cmd_line, strlen(cmd_line)+1); + rec->size = sizeof(struct bi_record) + strlen(cmd_line) + 1; + rec = (struct bi_record *)((unsigned long)rec + rec->size); + + if ( initrd_size ) { + rec->tag = BI_INITRD; + rec->data[0] = (unsigned long)(&__ramdisk_begin); + rec->data[1] = initrd_size; + rec->size = sizeof(struct bi_record) + 2 * + sizeof(unsigned long); + rec = (struct bi_record *)((unsigned long)rec + + rec->size); + } + + rec->tag = BI_LAST; + rec->size = sizeof(struct bi_record); + rec = (struct bi_record *)((unsigned long)rec + rec->size); + } + puts("Now booting the kernel\n"); + serial_close(com_port); + + return (unsigned long)hold_residual; +} diff --git a/arch/ppc/boot/simple/misc-ev64260.S b/arch/ppc/boot/simple/misc-ev64260.S new file mode 100644 index 000000000000..7cae45b5c2ff --- /dev/null +++ b/arch/ppc/boot/simple/misc-ev64260.S @@ -0,0 +1,63 @@ +/* + * arch/ppc/boot/simple/misc-ev64260.S + * + * Host bridge init code for the Marvell/Galileo EV-64260-BP evaluation board + * with a GT64260 onboard. + * + * Author: Mark Greer <mgreer@mvista.com> + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include <asm/ppc_asm.h> +#include <asm/processor.h> +#include <asm/cache.h> +#include <asm/gt64260_defs.h> + +#include <platforms/ev64260.h> + + .globl ev64260_init +ev64260_init: + li r20,0 + li r23,20 + + /* Relocate galileo's regs */ + addis r25,0,GT64260_INTERNAL_SPACE_DEFAULT_ADDR@h + ori r25,r25,GT64260_INTERNAL_SPACE_DECODE + lwbrx r26,0,(r25) + lis r24,0xffff + and r26,r26,r24 + addis r24,0,EV64260_BRIDGE_REG_BASE@h + srw r24,r24,r23 + or r26,r26,r24 + stwbrx r26,0,(r25) + sync + + /* Wait for write to take effect */ + addis r25,0,EV64260_BRIDGE_REG_BASE@h + ori r25,r25,GT64260_INTERNAL_SPACE_DECODE +1: lwbrx r24,0,(r25) + cmpw r24,r26 + bne 1b + + /* Change CS2 (UARTS on device module) window */ + addis r25,0,EV64260_BRIDGE_REG_BASE@h + ori r25,r25,GT64260_CPU_CS_DECODE_2_BOT + addis r26,0,EV64260_UART_BASE@h + srw r26,r26,r23 + stwbrx r26,0,(r25) + sync + + addis r25,0,EV64260_BRIDGE_REG_BASE@h + ori r25,r25,GT64260_CPU_CS_DECODE_2_TOP + addis r26,0,EV64260_UART_END@h + srw r26,r26,r23 + stwbrx r26,0,(r25) + sync + + blr diff --git a/arch/ppc/boot/simple/misc-spruce.c b/arch/ppc/boot/simple/misc-spruce.c new file mode 100644 index 000000000000..452a4746a3e3 --- /dev/null +++ b/arch/ppc/boot/simple/misc-spruce.c @@ -0,0 +1,440 @@ +/* + * arch/ppc/boot/spruce/misc.c + * + * Misc. bootloader code for IBM Spruce reference platform + * + * Authors: Johnnie Peters <jpeters@mvista.com> + * Matt Porter <mporter@mvista.com> + * + * Derived from arch/ppc/boot/prep/misc.c + * + * Copyright 2000-2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <linux/types.h> +#include <linux/elf.h> +#include <linux/config.h> +#include <linux/pci.h> + +#include <asm/page.h> +#include <asm/processor.h> +#include <asm/mmu.h> +#include <asm/bootinfo.h> + +#include "zlib.h" + +/* Define some important locations of the Spruce. */ +#define SPRUCE_PCI_CONFIG_ADDR 0xfec00000 +#define SPRUCE_PCI_CONFIG_DATA 0xfec00004 +#define SPRUCE_ISA_IO_BASE 0xf8000000 + +unsigned long com_port; + +char *avail_ram; +char *end_avail; + +/* The linker tells us where the image is. */ +extern char __image_begin, __image_end; +extern char __ramdisk_begin, __ramdisk_end; +extern char _end[]; + +#ifdef CONFIG_CMDLINE +#define CMDLINE CONFIG_CMDLINE +#else +#define CMDLINE "" +#endif +char cmd_preset[] = CMDLINE; +char cmd_buf[256]; +char *cmd_line = cmd_buf; + +unsigned long initrd_size = 0; + +char *zimage_start; +int zimage_size; + +extern void udelay(long); +extern void puts(const char *); +extern void putc(const char c); +extern void puthex(unsigned long val); +extern int getc(void); +extern int tstc(void); +extern void gunzip(void *, int, unsigned char *, int *); + +extern unsigned long serial_init(int chan, void *ignored); + +/* PCI configuration space access routines. */ +unsigned int *pci_config_address = (unsigned int *)SPRUCE_PCI_CONFIG_ADDR; +unsigned char *pci_config_data = (unsigned char *)SPRUCE_PCI_CONFIG_DATA; + +void cpc700_pcibios_read_config_byte(unsigned char bus, unsigned char dev_fn, + unsigned char offset, unsigned char *val) +{ + out_le32(pci_config_address, + (((bus & 0xff)<<16) | (dev_fn<<8) | (offset&0xfc) | 0x80000000)); + + *val= (in_le32((unsigned *)pci_config_data) >> (8 * (offset & 3))) & 0xff; +} + +void cpc700_pcibios_write_config_byte(unsigned char bus, unsigned char dev_fn, + unsigned char offset, unsigned char val) +{ + out_le32(pci_config_address, + (((bus & 0xff)<<16) | (dev_fn<<8) | (offset&0xfc) | 0x80000000)); + + out_8(pci_config_data + (offset&3), val); +} + +void cpc700_pcibios_read_config_word(unsigned char bus, unsigned char dev_fn, + unsigned char offset, unsigned short *val) +{ + out_le32(pci_config_address, + (((bus & 0xff)<<16) | (dev_fn<<8) | (offset&0xfc) | 0x80000000)); + + *val= in_le16((unsigned short *)(pci_config_data + (offset&3))); +} + +void cpc700_pcibios_write_config_word(unsigned char bus, unsigned char dev_fn, + unsigned char offset, unsigned short val) +{ + out_le32(pci_config_address, + (((bus & 0xff)<<16) | (dev_fn<<8) | (offset&0xfc) | 0x80000000)); + + out_le16((unsigned short *)(pci_config_data + (offset&3)), val); +} + +void cpc700_pcibios_read_config_dword(unsigned char bus, unsigned char dev_fn, + unsigned char offset, unsigned int *val) +{ + out_le32(pci_config_address, + (((bus & 0xff)<<16) | (dev_fn<<8) | (offset&0xfc) | 0x80000000)); + + *val= in_le32((unsigned *)pci_config_data); +} + +void cpc700_pcibios_write_config_dword(unsigned char bus, unsigned char dev_fn, + unsigned char offset, unsigned int val) +{ + out_le32(pci_config_address, + (((bus & 0xff)<<16) | (dev_fn<<8) | (offset&0xfc) | 0x80000000)); + + out_le32((unsigned *)pci_config_data, val); +} + +unsigned long isa_io_base = SPRUCE_ISA_IO_BASE; + +#define PCNET32_WIO_RDP 0x10 +#define PCNET32_WIO_RAP 0x12 +#define PCNET32_WIO_RESET 0x14 + +#define PCNET32_DWIO_RDP 0x10 +#define PCNET32_DWIO_RAP 0x14 +#define PCNET32_DWIO_RESET 0x18 + +/* Processor interface config register access */ +#define PIFCFGADDR 0xff500000 +#define PIFCFGDATA 0xff500004 + +#define PLBMIFOPT 0x18 /* PLB Master Interface Options */ + +#define MEM_MBEN 0x24 +#define MEM_TYPE 0x28 +#define MEM_B1SA 0x3c +#define MEM_B1EA 0x5c +#define MEM_B2SA 0x40 +#define MEM_B2EA 0x60 + +unsigned long +decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum) +{ + int timer = 0; + char *cp, ch; + + int loop; + int csr0; + int csr_id; + int *mem_addr = (int *)0xff500008; + int *mem_data = (int *)0xff50000c; + int mem_size = 0; + unsigned long mem_mben; + unsigned long mem_type; + unsigned long mem_start; + unsigned long mem_end; + int *pif_addr = (int *)0xff500000; + int *pif_data = (int *)0xff500004; + int pci_devfn; + int found_multi = 0; + unsigned short vendor; + unsigned short device; + unsigned short command; + unsigned char header_type; + unsigned int bar0; + +#ifdef CONFIG_SERIAL_CONSOLE + /* Initialize the serial console port */ + com_port = serial_init(0, NULL); +#endif + + /* + * Gah, these firmware guys need to learn that hardware + * byte swapping is evil! Disable all hardware byte + * swapping so it doesn't hurt anyone. + */ + *pif_addr = PLBMIFOPT; + asm("sync"); + *pif_data = 0x00000000; + asm("sync"); + + /* Get the size of memory from the memory controller. */ + *mem_addr = MEM_MBEN; + asm("sync"); + mem_mben = *mem_data; + asm("sync"); + for(loop = 0; loop < 1000; loop++); + + *mem_addr = MEM_TYPE; + asm("sync"); + mem_type = *mem_data; + asm("sync"); + for(loop = 0; loop < 1000; loop++); + + *mem_addr = MEM_TYPE; + /* Confirm bank 1 has DRAM memory */ + if ((mem_mben & 0x40000000) && + ((mem_type & 0x30000000) == 0x10000000)) { + *mem_addr = MEM_B1SA; + asm("sync"); + mem_start = *mem_data; + asm("sync"); + for(loop = 0; loop < 1000; loop++); + + *mem_addr = MEM_B1EA; + asm("sync"); + mem_end = *mem_data; + asm("sync"); + for(loop = 0; loop < 1000; loop++); + + mem_size = mem_end - mem_start + 0x100000; + } + + /* Confirm bank 2 has DRAM memory */ + if ((mem_mben & 0x20000000) && + ((mem_type & 0xc000000) == 0x4000000)) { + *mem_addr = MEM_B2SA; + asm("sync"); + mem_start = *mem_data; + asm("sync"); + for(loop = 0; loop < 1000; loop++); + + *mem_addr = MEM_B2EA; + asm("sync"); + mem_end = *mem_data; + asm("sync"); + for(loop = 0; loop < 1000; loop++); + + mem_size += mem_end - mem_start + 0x100000; + } + + /* Search out and turn off the PcNet ethernet boot device. */ + for (pci_devfn = 1; pci_devfn < 0xff; pci_devfn++) { + if (PCI_FUNC(pci_devfn) && !found_multi) + continue; + + cpc700_pcibios_read_config_byte(0, pci_devfn, + PCI_HEADER_TYPE, &header_type); + + if (!PCI_FUNC(pci_devfn)) + found_multi = header_type & 0x80; + + cpc700_pcibios_read_config_word(0, pci_devfn, PCI_VENDOR_ID, + &vendor); + + if (vendor != 0xffff) { + cpc700_pcibios_read_config_word(0, pci_devfn, + PCI_DEVICE_ID, &device); + + /* If this PCI device is the Lance PCNet board then turn it off */ + if ((vendor == PCI_VENDOR_ID_AMD) && + (device == PCI_DEVICE_ID_AMD_LANCE)) { + + /* Turn on I/O Space on the board. */ + cpc700_pcibios_read_config_word(0, pci_devfn, + PCI_COMMAND, &command); + command |= 0x1; + cpc700_pcibios_write_config_word(0, pci_devfn, + PCI_COMMAND, command); + + /* Get the I/O space address */ + cpc700_pcibios_read_config_dword(0, pci_devfn, + PCI_BASE_ADDRESS_0, &bar0); + bar0 &= 0xfffffffe; + + /* Reset the PCNet Board */ + inl (bar0+PCNET32_DWIO_RESET); + inw (bar0+PCNET32_WIO_RESET); + + /* First do a work oriented read of csr0. If the value is + * 4 then this is the correct mode to access the board. + * If not try a double word ortiented read. + */ + outw(0, bar0 + PCNET32_WIO_RAP); + csr0 = inw(bar0 + PCNET32_WIO_RDP); + + if (csr0 == 4) { + /* Check the Chip id register */ + outw(88, bar0 + PCNET32_WIO_RAP); + csr_id = inw(bar0 + PCNET32_WIO_RDP); + + if (csr_id) { + /* This is the valid mode - set the stop bit */ + outw(0, bar0 + PCNET32_WIO_RAP); + outw(csr0, bar0 + PCNET32_WIO_RDP); + } + } else { + outl(0, bar0 + PCNET32_DWIO_RAP); + csr0 = inl(bar0 + PCNET32_DWIO_RDP); + if (csr0 == 4) { + /* Check the Chip id register */ + outl(88, bar0 + PCNET32_WIO_RAP); + csr_id = inl(bar0 + PCNET32_WIO_RDP); + + if (csr_id) { + /* This is the valid mode - set the stop bit*/ + outl(0, bar0 + PCNET32_WIO_RAP); + outl(csr0, bar0 + PCNET32_WIO_RDP); + } + } + } + } + } + } + + /* assume the chunk below 8M is free */ + end_avail = (char *)0x00800000; + + /* + * We link ourself to 0x00800000. When we run, we relocate + * ourselves there. So we just need __image_begin for the + * start. -- Tom + */ + zimage_start = (char *)(unsigned long)(&__image_begin); + zimage_size = (unsigned long)(&__image_end) - + (unsigned long)(&__image_begin); + + initrd_size = (unsigned long)(&__ramdisk_end) - + (unsigned long)(&__ramdisk_begin); + + /* + * The zImage and initrd will be between start and _end, so they've + * already been moved once. We're good to go now. -- Tom + */ + avail_ram = (char *)PAGE_ALIGN((unsigned long)_end); + puts("zimage at: "); puthex((unsigned long)zimage_start); + puts(" "); puthex((unsigned long)(zimage_size+zimage_start)); + puts("\n"); + + if ( initrd_size ) { + puts("initrd at: "); + puthex((unsigned long)(&__ramdisk_begin)); + puts(" "); puthex((unsigned long)(&__ramdisk_end));puts("\n"); + } + + avail_ram = (char *)0x00400000; + end_avail = (char *)0x00800000; + puts("avail ram: "); puthex((unsigned long)avail_ram); puts(" "); + puthex((unsigned long)end_avail); puts("\n"); + + /* Display standard Linux/PPC boot prompt for kernel args */ + puts("\nLinux/PPC load: "); + cp = cmd_line; + memcpy (cmd_line, cmd_preset, sizeof(cmd_preset)); + while ( *cp ) putc(*cp++); + while (timer++ < 5*1000) { + if (tstc()) { + while ((ch = getc()) != '\n' && ch != '\r') { + if (ch == '\b') { + if (cp != cmd_line) { + cp--; + puts("\b \b"); + } + } else { + *cp++ = ch; + putc(ch); + } + } + break; /* Exit 'timer' loop */ + } + udelay(1000); /* 1 msec */ + } + *cp = 0; + puts("\n"); + + puts("Uncompressing Linux..."); + + gunzip(0, 0x400000, zimage_start, &zimage_size); + + puts("done.\n"); + + { + struct bi_record *rec; + + rec = (struct bi_record *)_ALIGN((ulong)zimage_size + + (1<<20)-1,(1<<20)); + + rec->tag = BI_FIRST; + rec->size = sizeof(struct bi_record); + rec = (struct bi_record *)((unsigned long)rec + rec->size); + + rec->tag = BI_BOOTLOADER_ID; + memcpy( (void *)rec->data, "spruceboot", 11); + rec->size = sizeof(struct bi_record) + 10 + 1; + rec = (struct bi_record *)((unsigned long)rec + rec->size); + + rec->tag = BI_MEMSIZE; + rec->data[0] = mem_size; + rec->size = sizeof(struct bi_record) + sizeof(unsigned long); + rec = (struct bi_record *)((unsigned long)rec + rec->size); + + rec->tag = BI_CMD_LINE; + memcpy( (char *)rec->data, cmd_line, strlen(cmd_line)+1); + rec->size = sizeof(struct bi_record) + strlen(cmd_line) + 1; + rec = (struct bi_record *)((ulong)rec + rec->size); + + if ( initrd_size ) { + rec->tag = BI_INITRD; + rec->data[0] = (unsigned long)(&__ramdisk_begin); + rec->data[1] = initrd_size; + rec->size = sizeof(struct bi_record) + 2 * + sizeof(unsigned long); + rec = (struct bi_record *)((unsigned long)rec + + rec->size); + } + + rec->tag = BI_LAST; + rec->size = sizeof(struct bi_record); + rec = (struct bi_record *)((unsigned long)rec + rec->size); + } + + puts("Now booting the kernel\n"); + + return 0; +} diff --git a/arch/ppc/boot/mbx/pci.c b/arch/ppc/boot/simple/pci.c index 85309d68c8cc..0faa57f4bad4 100644 --- a/arch/ppc/boot/mbx/pci.c +++ b/arch/ppc/boot/simple/pci.c @@ -1,13 +1,15 @@ /* - * BK Id: SCCS/s.pci.c 1.6 05/18/01 15:17:06 cort + * BK Id: %F% %I% %G% %U% %#% */ /* Stand alone funtions for QSpan Tundra support. */ #include <linux/types.h> -#include <linux/kernel.h> #include <linux/pci.h> #include <asm/mpc8xx.h> +extern void puthex(unsigned long val); +extern void puts(const char *); + /* To map PCI devices, you first write 0xffffffff into the device * base address registers. When the register is read back, the * number of most significant '1' bits describes the amount of address @@ -34,14 +36,34 @@ void pci_conf_read(int bus, int device, int func, int reg, void *readval); void probe_addresses(int bus, int devfn); void map_pci_addrs(void); +extern int +qs_pci_read_config_byte(unsigned char bus, unsigned char dev_fn, + unsigned char offset, unsigned char *val); +extern int +qs_pci_read_config_word(unsigned char bus, unsigned char dev_fn, + unsigned char offset, unsigned short *val); +extern int +qs_pci_read_config_dword(unsigned char bus, unsigned char dev_fn, + unsigned char offset, unsigned int *val); +extern int +qs_pci_write_config_byte(unsigned char bus, unsigned char dev_fn, + unsigned char offset, unsigned char val); +extern int +qs_pci_write_config_word(unsigned char bus, unsigned char dev_fn, + unsigned char offset, unsigned short val); +extern int +qs_pci_write_config_dword(unsigned char bus, unsigned char dev_fn, + unsigned char offset, unsigned int val); + + /* This is a really stripped version of PCI bus scan. All we are * looking for are devices that exist. */ +void pci_scanner(int addr_probe) { - unsigned int devfn, l, max, class, bus_number; - unsigned char cmd, irq, tmp, hdr_type, is_multi; - int reg; + unsigned int devfn, l, class, bus_number; + unsigned char hdr_type, is_multi; is_multi = 0; bus_number = 0; diff --git a/arch/ppc/boot/mbx/qspan_pci.c b/arch/ppc/boot/simple/qspan_pci.c index d3bf2f1dc345..86a39967850f 100644 --- a/arch/ppc/boot/mbx/qspan_pci.c +++ b/arch/ppc/boot/simple/qspan_pci.c @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.qspan_pci.c 1.6 05/18/01 15:17:06 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * LinuxPPC arch/ppc/kernel/qspan_pci.c Dan Malek (dmalek@jlc.net) @@ -83,7 +83,8 @@ /* Initialize the QSpan device registers after power up. */ -qspan_init() +void +qspan_init(void) { uint *qptr; diff --git a/arch/ppc/boot/simple/rw4/ppc_40x.h b/arch/ppc/boot/simple/rw4/ppc_40x.h new file mode 100644 index 000000000000..5c47acdd13f2 --- /dev/null +++ b/arch/ppc/boot/simple/rw4/ppc_40x.h @@ -0,0 +1,664 @@ +/*----------------------------------------------------------------------------+ +| This source code has been made available to you by IBM on an AS-IS +| basis. Anyone receiving this source is licensed under IBM +| copyrights to use it in any way he or she deems fit, including +| copying it, modifying it, compiling it, and redistributing it either +| with or without modifications. No license under IBM patents or +| patent applications is to be implied by the copyright license. +| +| Any user of this software should understand that IBM cannot provide +| technical support for this software and will not be responsible for +| any consequences resulting from the use of this software. +| +| Any person who transfers this source code or any derivative work +| must include the IBM copyright notice, this paragraph, and the +| preceding two paragraphs in the transferred software. +| +| COPYRIGHT I B M CORPORATION 1997 +| LICENSED MATERIAL - PROGRAM PROPERTY OF I B M ++----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------+ +| Author: Tony J. Cerreto +| Component: Assembler include file. +| File: ppc_40x.h +| Purpose: Include file containing PPC DCR defines. +| +| Changes: +| Date Author Comment +| --------- ------ -------------------------------------------------------- +| 01-Mar-00 tjc Created ++----------------------------------------------------------------------------*/ +/* added by linguohui*/ +#define MW +/*----------------------------------------------------------------------------+ +| PPC Special purpose registers Numbers ++----------------------------------------------------------------------------*/ +#define ccr0 0x3b3 /* core configuration reg */ +#define ctr 0x009 /* count register */ +#define ctrreg 0x009 /* count register */ +#define dbcr0 0x3f2 /* debug control register 0 */ +#define dbcr1 0x3bd /* debug control register 1 */ +#define dbsr 0x3f0 /* debug status register */ +#define dccr 0x3fa /* data cache control reg. */ +#define dcwr 0x3ba /* data cache write-thru reg */ +#define dear 0x3d5 /* data exeption address reg */ +#define esr 0x3d4 /* execption syndrome registe */ +#define evpr 0x3d6 /* exeption vector prefix reg */ +#define iccr 0x3fb /* instruction cache cntrl re */ +#define icdbdr 0x3d3 /* instr cache dbug data reg */ +#define lrreg 0x008 /* link register */ +#define pid 0x3b1 /* process id reg */ +#define pit 0x3db /* programmable interval time */ +#define pvr 0x11f /* processor version register */ +#define sgr 0x3b9 /* storage guarded reg */ +#define sler 0x3bb /* storage little endian reg */ +#define sprg0 0x110 /* special general purpose 0 */ +#define sprg1 0x111 /* special general purpose 1 */ +#define sprg2 0x112 /* special general purpose 2 */ +#define sprg3 0x113 /* special general purpose 3 */ +#define sprg4 0x114 /* special general purpose 4 */ +#define sprg5 0x115 /* special general purpose 5 */ +#define sprg6 0x116 /* special general purpose 6 */ +#define sprg7 0x117 /* special general purpose 7 */ +#define srr0 0x01a /* save/restore register 0 */ +#define srr1 0x01b /* save/restore register 1 */ +#define srr2 0x3de /* save/restore register 2 */ +#define srr3 0x3df /* save/restore register 3 */ +#define tbhi 0x11D +#define tblo 0x11C +#define tcr 0x3da /* timer control register */ +#define tsr 0x3d8 /* timer status register */ +#define xerreg 0x001 /* fixed point exception */ +#define xer 0x001 /* fixed point exception */ +#define zpr 0x3b0 /* zone protection reg */ + +/*----------------------------------------------------------------------------+ +| Decompression Controller ++----------------------------------------------------------------------------*/ +#define kiar 0x014 /* Decompression cntl addr reg */ +#define kidr 0x015 /* Decompression cntl data reg */ +#define kitor0 0x00 /* index table origin Reg 0 */ +#define kitor1 0x01 /* index table origin Reg 1 */ +#define kitor2 0x02 /* index table origin Reg 2 */ +#define kitor3 0x03 /* index table origin Reg 3 */ +#define kaddr0 0x04 /* addr decode Definition Reg 0 */ +#define kaddr1 0x05 /* addr decode Definition Reg 1 */ +#define kconf 0x40 /* Decompression cntl config reg */ +#define kid 0x41 /* Decompression cntl id reg */ +#define kver 0x42 /* Decompression cntl ver number */ +#define kpear 0x50 /* bus error addr reg (PLB) */ +#define kbear 0x51 /* bus error addr reg (DCP-EBC) */ +#define kesr0 0x52 /* bus error status reg 0 */ + +/*----------------------------------------------------------------------------+ +| Romeo Specific Device Control Register Numbers. ++----------------------------------------------------------------------------*/ +#ifndef VESTA +#define cdbcr 0x3d7 /* cache debug cntrl reg */ + +#define a_latcnt 0x1a9 /* PLB Latency count */ +#define a_tgval 0x1ac /* tone generation value */ +#define a_plb_pr 0x1bf /* PLB priority */ + +#define cic_sel1 0x031 /* select register 1 */ +#define cic_sel2 0x032 /* select register 2 */ + +#define clkgcrst 0x122 /* chip reset register */ + +#define cp_cpmsr 0x100 /*rstatus register */ +#define cp_cpmer 0x101 /* enable register */ + +#define dcp_kiar 0x190 /* indirect address register */ +#define dcp_kidr 0x191 /* indirect data register */ + +#define hsmc_mcgr 0x1c0 /* HSMC global register */ +#define hsmc_mcbesr 0x1c1 /* bus error status register */ +#define hsmc_mcbear 0x1c2 /* bus error address register*/ +#define hsmc_mcbr0 0x1c4 /* SDRAM sub-ctrl bank reg 0 */ +#define hsmc_mccr0 0x1c5 /* SDRAM sub-ctrl ctrl reg 0 */ +#define hsmc_mcbr1 0x1c7 /* SDRAM sub-ctrl bank reg 1 */ +#define hsmc_mccr1 0x1c8 /* SDRAM sub-ctrl ctrl reg 1 */ +#define hsmc_sysr 0x1d1 /* system register */ +#define hsmc_data 0x1d2 /* data register */ +#define hsmc_mccrr 0x1d3 /* refresh register */ + +#define ocm_pbar 0x1E0 /* base address register */ + +#define plb0_pacr0 0x057 /* PLB arbiter control reg */ +#define plb1_pacr1 0x067 /* PLB arbiter control reg */ + +#define v_displb 0x157 /* set left border of display*/ +#define v_disptb 0x158 /* top border of display */ +#define v_osd_la 0x159 /* first link address for OSD*/ +#define v_ptsdlta 0x15E /* PTS delta register */ +#define v_v0base 0x16C /* base mem add for VBI-0 */ +#define v_v1base 0x16D /* base mem add for VBI-1 */ +#define v_osbase 0x16E /* base mem add for OSD data */ +#endif + +/*----------------------------------------------------------------------------+ +| Vesta Device Control Register Numbers. ++----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------+ +| Cross bar switch. ++----------------------------------------------------------------------------*/ +#define cbs0_cr 0x010 /* CBS configuration register */ + +/*----------------------------------------------------------------------------+ +| DCR external master (DCRX). ++----------------------------------------------------------------------------*/ +#define dcrx0_icr 0x020 /* internal control register */ +#define dcrx0_isr 0x021 /* internal status register */ +#define dcrx0_ecr 0x022 /* external control register */ +#define dcrx0_esr 0x023 /* external status register */ +#define dcrx0_tar 0x024 /* target address register */ +#define dcrx0_tdr 0x025 /* target data register */ +#define dcrx0_igr 0x026 /* interrupt generation register */ +#define dcrx0_bcr 0x027 /* buffer control register */ + +/*----------------------------------------------------------------------------+ +| Chip interconnect configuration. ++----------------------------------------------------------------------------*/ +#define cic0_cr 0x030 /* CIC control register */ +#define cic0_vcr 0x033 /* video macro control reg */ +#define cic0_sel3 0x035 /* select register 3 */ + +/*----------------------------------------------------------------------------+ +| Chip interconnect configuration. ++----------------------------------------------------------------------------*/ +#define sgpo0_sgpO 0x036 /* simplified GPIO output */ +#define sgpo0_gpod 0x037 /* simplified GPIO open drain */ +#define sgpo0_gptc 0x038 /* simplified GPIO tristate cntl */ +#define sgpo0_gpi 0x039 /* simplified GPIO input */ + +/*----------------------------------------------------------------------------+ +| Universal interrupt controller. ++----------------------------------------------------------------------------*/ +#define uic0_sr 0x040 /* status register */ +#define uic0_srs 0x041 /* status register set */ +#define uic0_er 0x042 /* enable register */ +#define uic0_cr 0x043 /* critical register */ +#define uic0_pr 0x044 /* parity register */ +#define uic0_tr 0x045 /* triggering register */ +#define uic0_msr 0x046 /* masked status register */ +#define uic0_vr 0x047 /* vector register */ +#define uic0_vcr 0x048 /* enable config register */ + +/*----------------------------------------------------------------------------+ +| PLB 0 and 1. ++----------------------------------------------------------------------------*/ +#define pb0_pesr 0x054 /* PLB error status reg 0 */ +#define pb0_pesrs 0x055 /* PLB error status reg 0 set */ +#define pb0_pear 0x056 /* PLB error address reg */ + +#define pb1_pesr 0x064 /* PLB error status reg 1 */ +#define pb1_pesrs 0x065 /* PLB error status reg 1 set */ +#define pb1_pear 0x066 /* PLB error address reg */ + +/*----------------------------------------------------------------------------+ +| EBIU DCR registers. ++----------------------------------------------------------------------------*/ +#define ebiu0_brcrh0 0x070 /* bus region register 0 high */ +#define ebiu0_brcrh1 0x071 /* bus region register 1 high */ +#define ebiu0_brcrh2 0x072 /* bus region register 2 high */ +#define ebiu0_brcrh3 0x073 /* bus region register 3 high */ +#define ebiu0_brcrh4 0x074 /* bus region register 4 high */ +#define ebiu0_brcrh5 0x075 /* bus region register 5 high */ +#define ebiu0_brcrh6 0x076 /* bus region register 6 high */ +#define ebiu0_brcrh7 0x077 /* bus region register 7 high */ +#define ebiu0_brcr0 0x080 /* bus region register 0 */ +#define ebiu0_brcr1 0x081 /* bus region register 1 */ +#define ebiu0_brcr2 0x082 /* bus region register 2 */ +#define ebiu0_brcr3 0x083 /* bus region register 3 */ +#define ebiu0_brcr4 0x084 /* bus region register 4 */ +#define ebiu0_brcr5 0x085 /* bus region register 5 */ +#define ebiu0_brcr6 0x086 /* bus region register 6 */ +#define ebiu0_brcr7 0x087 /* bus region register 7 */ +#define ebiu0_bear 0x090 /* bus error address register */ +#define ebiu0_besr 0x091 /* bus error syndrome reg */ +#define ebiu0_besr0s 0x093 /* bus error syndrome reg */ +#define ebiu0_biucr 0x09a /* bus interface control reg */ + +/*----------------------------------------------------------------------------+ +| OPB bridge. ++----------------------------------------------------------------------------*/ +#define opbw0_gesr 0x0b0 /* error status reg */ +#define opbw0_gesrs 0x0b1 /* error status reg */ +#define opbw0_gear 0x0b2 /* error address reg */ + +/*----------------------------------------------------------------------------+ +| DMA. ++----------------------------------------------------------------------------*/ +#define dma0_cr0 0x0c0 /* DMA channel control reg 0 */ +#define dma0_ct0 0x0c1 /* DMA count register 0 */ +#define dma0_da0 0x0c2 /* DMA destination addr reg 0 */ +#define dma0_sa0 0x0c3 /* DMA source addr register 0 */ +#define dma0_cc0 0x0c4 /* DMA chained count 0 */ +#define dma0_cr1 0x0c8 /* DMA channel control reg 1 */ +#define dma0_ct1 0x0c9 /* DMA count register 1 */ +#define dma0_da1 0x0ca /* DMA destination addr reg 1 */ +#define dma0_sa1 0x0cb /* DMA source addr register 1 */ +#define dma0_cc1 0x0cc /* DMA chained count 1 */ +#define dma0_cr2 0x0d0 /* DMA channel control reg 2 */ +#define dma0_ct2 0x0d1 /* DMA count register 2 */ +#define dma0_da2 0x0d2 /* DMA destination addr reg 2 */ +#define dma0_sa2 0x0d3 /* DMA source addr register 2 */ +#define dma0_cc2 0x0d4 /* DMA chained count 2 */ +#define dma0_cr3 0x0d8 /* DMA channel control reg 3 */ +#define dma0_ct3 0x0d9 /* DMA count register 3 */ +#define dma0_da3 0x0da /* DMA destination addr reg 3 */ +#define dma0_sa3 0x0db /* DMA source addr register 3 */ +#define dma0_cc3 0x0dc /* DMA chained count 3 */ +#define dma0_sr 0x0e0 /* DMA status register */ +#define dma0_srs 0x0e1 /* DMA status register */ +#define dma0_s1 0x031 /* DMA select1 register */ +#define dma0_s2 0x032 /* DMA select2 register */ + +/*---------------------------------------------------------------------------+ +| Clock and power management. ++----------------------------------------------------------------------------*/ +#define cpm0_fr 0x102 /* force register */ + +/*----------------------------------------------------------------------------+ +| Serial Clock Control. ++----------------------------------------------------------------------------*/ +#define ser0_ccr 0x120 /* serial clock control register */ + +/*----------------------------------------------------------------------------+ +| Audio Clock Control. ++----------------------------------------------------------------------------*/ +#define aud0_apcr 0x121 /* audio clock ctrl register */ + +/*----------------------------------------------------------------------------+ +| DENC. ++----------------------------------------------------------------------------*/ +#define denc0_idr 0x130 /* DENC ID register */ +#define denc0_cr1 0x131 /* control register 1 */ +#define denc0_rr1 0x132 /* microvision 1 (reserved 1) */ +#define denc0_cr2 0x133 /* control register 2 */ +#define denc0_rr2 0x134 /* microvision 2 (reserved 2) */ +#define denc0_rr3 0x135 /* microvision 3 (reserved 3) */ +#define denc0_rr4 0x136 /* microvision 4 (reserved 4) */ +#define denc0_rr5 0x137 /* microvision 5 (reserved 5) */ +#define denc0_ccdr 0x138 /* closed caption data */ +#define denc0_cccr 0x139 /* closed caption control */ +#define denc0_trr 0x13A /* teletext request register */ +#define denc0_tosr 0x13B /* teletext odd field line se */ +#define denc0_tesr 0x13C /* teletext even field line s */ +#define denc0_rlsr 0x13D /* RGB rhift left register */ +#define denc0_vlsr 0x13E /* video level shift register */ +#define denc0_vsr 0x13F /* video scaling register */ + +/*----------------------------------------------------------------------------+ +| Video decoder. Suspect 0x179, 0x169, 0x16a, 0x152 (rc). ++----------------------------------------------------------------------------*/ +#define vid0_ccntl 0x140 /* control decoder operation */ +#define vid0_cmode 0x141 /* video operational mode */ +#define vid0_sstc0 0x142 /* STC high order bits 31:0 */ +#define vid0_sstc1 0x143 /* STC low order bit 32 */ +#define vid0_spts0 0x144 /* PTS high order bits 31:0 */ +#define vid0_spts1 0x145 /* PTS low order bit 32 */ +#define vid0_fifo 0x146 /* FIFO data port */ +#define vid0_fifos 0x147 /* FIFO status */ +#define vid0_cmd 0x148 /* send command to decoder */ +#define vid0_cmdd 0x149 /* port for command params */ +#define vid0_cmdst 0x14A /* command status */ +#define vid0_cmdad 0x14B /* command address */ +#define vid0_procia 0x14C /* instruction store */ +#define vid0_procid 0x14D /* data port for I_Store */ +#define vid0_osdm 0x151 /* OSD mode control */ +#define vid0_hosti 0x152 /* base interrupt register */ +#define vid0_mask 0x153 /* interrupt mask register */ +#define vid0_dispm 0x154 /* operational mode for Disp */ +#define vid0_dispd 0x155 /* setting for 'Sync' delay */ +#define vid0_vbctl 0x156 /* VBI */ +#define vid0_ttxctl 0x157 /* teletext control */ +#define vid0_disptb 0x158 /* display left/top border */ +#define vid0_osdgla 0x159 /* Graphics plane link addr */ +#define vid0_osdila 0x15A /* Image plane link addr */ +#define vid0_rbthr 0x15B /* rate buffer threshold */ +#define vid0_osdcla 0x15C /* Cursor link addr */ +#define vid0_stcca 0x15D /* STC common address */ +#define vid0_ptsctl 0x15F /* PTS Control */ +#define vid0_wprot 0x165 /* write protect for I_Store */ +#define vid0_vcqa 0x167 /* video clip queued block Ad */ +#define vid0_vcql 0x168 /* video clip queued block Le */ +#define vid0_blksz 0x169 /* block size bytes for copy op */ +#define vid0_srcad 0x16a /* copy source address bits 6-31 */ +#define vid0_udbas 0x16B /* base mem add for user data */ +#define vid0_vbibas 0x16C /* base mem add for VBI 0/1 */ +#define vid0_osdibas 0x16D /* Image plane base address */ +#define vid0_osdgbas 0x16E /* Graphic plane base address */ +#define vid0_rbbase 0x16F /* base mem add for video buf */ +#define vid0_dramad 0x170 /* DRAM address */ +#define vid0_dramdt 0x171 /* data port for DRAM access */ +#define vid0_dramcs 0x172 /* DRAM command and statusa */ +#define vid0_vcwa 0x173 /* v clip work address */ +#define vid0_vcwl 0x174 /* v clip work length */ +#define vid0_mseg0 0x175 /* segment address 0 */ +#define vid0_mseg1 0x176 /* segment address 1 */ +#define vid0_mseg2 0x177 /* segment address 2 */ +#define vid0_mseg3 0x178 /* segment address 3 */ +#define vid0_fbbase 0x179 /* frame buffer base memory */ +#define vid0_osdcbas 0x17A /* Cursor base addr */ +#define vid0_lboxtb 0x17B /* top left border */ +#define vid0_trdly 0x17C /* transparency gate delay */ +#define vid0_sbord 0x17D /* left/top small pict. bord. */ +#define vid0_zoffs 0x17E /* hor/ver zoom window */ +#define vid0_rbsz 0x17F /* rate buffer size read */ + +/*----------------------------------------------------------------------------+ +| Transport demultiplexer. ++----------------------------------------------------------------------------*/ +#define xpt0_lr 0x180 /* demux location register */ +#define xpt0_data 0x181 /* demux data register */ +#define xpt0_ir 0x182 /* demux interrupt register */ + +#define xpt0_config1 0x0000 /* configuration 1 */ +#define xpt0_control1 0x0001 /* control 1 */ +#define xpt0_festat 0x0002 /* Front-end status */ +#define xpt0_feimask 0x0003 /* Front_end interrupt Mask */ +#define xpt0_ocmcnfg 0x0004 /* OCM Address */ +#define xpt0_settapi 0x0005 /* Set TAP Interrupt */ + +#define xpt0_pcrhi 0x0010 /* PCR High */ +#define xpt0_pcrlow 0x0011 /* PCR Low */ +#define xpt0_lstchi 0x0012 /* Latched STC High */ +#define xpt0_lstclow 0x0013 /* Latched STC Low */ +#define xpt0_stchi 0x0014 /* STC High */ +#define xpt0_stclow 0x0015 /* STC Low */ +#define xpt0_pwm 0x0016 /* PWM */ +#define xpt0_pcrstct 0x0017 /* PCR-STC Threshold */ +#define xpt0_pcrstcd 0x0018 /* PCR-STC Delta */ +#define xpt0_stccomp 0x0019 /* STC Compare */ +#define xpt0_stccmpd 0x001a /* STC Compare Disarm */ + +#define xpt0_dsstat 0x0048 /* Descrambler Status */ +#define xpt0_dsimask 0x0049 /* Descrambler Interrupt Mask */ + +#define xpt0_vcchng 0x01f0 /* Video Channel Change */ +#define xpt0_acchng 0x01f1 /* Audio Channel Change */ +#define xpt0_axenable 0x01fe /* Aux PID Enables */ +#define xpt0_pcrpid 0x01ff /* PCR PID */ + +#define xpt0_config2 0x1000 /* Configuration 2 */ +#define xpt0_pbuflvl 0x1002 /* Packet Buffer Level */ +#define xpt0_intmask 0x1003 /* Interrupt Mask */ +#define xpt0_plbcnfg 0x1004 /* PLB Configuration */ + +#define xpt0_qint 0x1010 /* Queues Interrupts */ +#define xpt0_qintmsk 0x1011 /* Queues Interrupts Mask */ +#define xpt0_astatus 0x1012 /* Audio Status */ +#define xpt0_aintmask 0x1013 /* Audio Interrupt Mask */ +#define xpt0_vstatus 0x1014 /* Video Status */ +#define xpt0_vintmask 0x1015 /* Video Interrupt Mask */ + +#define xpt0_qbase 0x1020 /* Queue Base */ +#define xpt0_bucketq 0x1021 /* Bucket Queue */ +#define xpt0_qstops 0x1024 /* Queue Stops */ +#define xpt0_qresets 0x1025 /* Queue Resets */ +#define xpt0_sfchng 0x1026 /* Section Filter Change */ + +/*----------------------------------------------------------------------------+ +| Audio decoder. Suspect 0x1ad, 0x1b4, 0x1a3, 0x1a5 (read/write status) ++----------------------------------------------------------------------------*/ +#define aud0_ctrl0 0x1a0 /* control 0 */ +#define aud0_ctrl1 0x1a1 /* control 1 */ +#define aud0_ctrl2 0x1a2 /* control 2 */ +#define aud0_cmd 0x1a3 /* command register */ +#define aud0_isr 0x1a4 /* interrupt status register */ +#define aud0_imr 0x1a5 /* interrupt mask register */ +#define aud0_dsr 0x1a6 /* decoder status register */ +#define aud0_stc 0x1a7 /* system time clock */ +#define aud0_csr 0x1a8 /* channel status register */ +#define aud0_lcnt 0x1a9 /* queued address register 2 */ +#define aud0_pts 0x1aa /* presentation time stamp */ +#define aud0_tgctrl 0x1ab /* tone generation control */ +#define aud0_qlr2 0x1ac /* queued length register 2 */ +#define aud0_auxd 0x1ad /* aux data */ +#define aud0_strmid 0x1ae /* stream ID */ +#define aud0_qar 0x1af /* queued address register */ +#define aud0_dsps 0x1b0 /* DSP status */ +#define aud0_qlr 0x1b1 /* queued len address */ +#define aud0_dspc 0x1b2 /* DSP control */ +#define aud0_wlr2 0x1b3 /* working length register 2 */ +#define aud0_instd 0x1b4 /* instruction download */ +#define aud0_war 0x1b5 /* working address register */ +#define aud0_seg1 0x1b6 /* segment 1 base register */ +#define aud0_seg2 0x1b7 /* segment 2 base register */ +#define aud0_avf 0x1b9 /* audio att value front */ +#define aud0_avr 0x1ba /* audio att value rear */ +#define aud0_avc 0x1bb /* audio att value center */ +#define aud0_seg3 0x1bc /* segment 3 base register */ +#define aud0_offset 0x1bd /* offset address */ +#define aud0_wrl 0x1be /* working length register */ +#define aud0_war2 0x1bf /* working address register 2 */ + +/*----------------------------------------------------------------------------+ +| High speed memory controller 0 and 1. ++----------------------------------------------------------------------------*/ +#define hsmc0_gr 0x1e0 /* HSMC global register */ +#define hsmc0_besr 0x1e1 /* bus error status register */ +#define hsmc0_bear 0x1e2 /* bus error address register */ +#define hsmc0_br0 0x1e4 /* SDRAM sub-ctrl bank reg 0 */ +#define hsmc0_cr0 0x1e5 /* SDRAM sub-ctrl ctrl reg 0 */ +#define hsmc0_br1 0x1e7 /* SDRAM sub-ctrl bank reg 1 */ +#define hsmc0_cr1 0x1e8 /* SDRAM sub-ctrl ctrl reg 1 */ +#define hsmc0_sysr 0x1f1 /* system register */ +#define hsmc0_data 0x1f2 /* data register */ +#define hsmc0_crr 0x1f3 /* refresh register */ + +#define hsmc1_gr 0x1c0 /* HSMC global register */ +#define hsmc1_besr 0x1c1 /* bus error status register */ +#define hsmc1_bear 0x1c2 /* bus error address register */ +#define hsmc1_br0 0x1c4 /* SDRAM sub-ctrl bank reg 0 */ +#define hsmc1_cr0 0x1c5 /* SDRAM sub-ctrl ctrl reg 0 */ +#define hsmc1_br1 0x1c7 /* SDRAM sub-ctrl bank reg 1 */ +#define hsmc1_cr1 0x1c8 /* SDRAM sub-ctrl ctrl reg 1 */ +#define hsmc1_sysr 0x1d1 /* system register */ +#define hsmc1_data 0x1d2 /* data register */ +#define hsmc1_crr 0x1d3 /* refresh register */ + +/*----------------------------------------------------------------------------+ +| Machine State Register bit definitions. ++----------------------------------------------------------------------------*/ +#define msr_ape 0x00100000 +#define msr_apa 0x00080000 +#define msr_we 0x00040000 +#define msr_ce 0x00020000 +#define msr_ile 0x00010000 +#define msr_ee 0x00008000 +#define msr_pr 0x00004000 +#define msr_me 0x00001000 +#define msr_de 0x00000200 +#define msr_ir 0x00000020 +#define msr_dr 0x00000010 +#define msr_le 0x00000001 + +/*----------------------------------------------------------------------------+ +| Used during interrupt processing. ++----------------------------------------------------------------------------*/ +#define stack_reg_image_size 160 + +/*----------------------------------------------------------------------------+ +| Function prolog definition and other Metaware (EABI) defines. ++----------------------------------------------------------------------------*/ +#ifdef MW + +#define r0 0 +#define r1 1 +#define r2 2 +#define r3 3 +#define r4 4 +#define r5 5 +#define r6 6 +#define r7 7 +#define r8 8 +#define r9 9 +#define r10 10 +#define r11 11 +#define r12 12 +#define r13 13 +#define r14 14 +#define r15 15 +#define r16 16 +#define r17 17 +#define r18 18 +#define r19 19 +#define r20 20 +#define r21 21 +#define r22 22 +#define r23 23 +#define r24 24 +#define r25 25 +#define r26 26 +#define r27 27 +#define r28 28 +#define r29 29 +#define r30 30 +#define r31 31 + +#define cr0 0 +#define cr1 1 +#define cr2 2 +#define cr3 3 +#define cr4 4 +#define cr5 5 +#define cr6 6 +#define cr7 7 + +#define function_prolog(func_name) .text; \ + .align 2; \ + .globl func_name; \ + func_name: +#define function_epilog(func_name) .type func_name,@function; \ + .size func_name,.-func_name + +#define function_call(func_name) bl func_name + +#define stack_frame_min 8 +#define stack_frame_bc 0 +#define stack_frame_lr 4 +#define stack_neg_off 0 + +#endif + +/*----------------------------------------------------------------------------+ +| Function prolog definition and other DIAB (Elf) defines. ++----------------------------------------------------------------------------*/ +#ifdef ELF_DIAB + +fprolog: macro f_name + .text + .align 2 + .globl f_name +f_name: + endm + +fepilog: macro f_name + .type f_name,@function + .size f_name,.-f_name + endm + +#define function_prolog(func_name) fprolog func_name +#define function_epilog(func_name) fepilog func_name +#define function_call(func_name) bl func_name + +#define stack_frame_min 8 +#define stack_frame_bc 0 +#define stack_frame_lr 4 +#define stack_neg_off 0 + +#endif + +/*----------------------------------------------------------------------------+ +| Function prolog definition and other Xlc (XCOFF) defines. ++----------------------------------------------------------------------------*/ +#ifdef XCOFF + +.machine "403ga" + +#define r0 0 +#define r1 1 +#define r2 2 +#define r3 3 +#define r4 4 +#define r5 5 +#define r6 6 +#define r7 7 +#define r8 8 +#define r9 9 +#define r10 10 +#define r11 11 +#define r12 12 +#define r13 13 +#define r14 14 +#define r15 15 +#define r16 16 +#define r17 17 +#define r18 18 +#define r19 19 +#define r20 20 +#define r21 21 +#define r22 22 +#define r23 23 +#define r24 24 +#define r25 25 +#define r26 26 +#define r27 27 +#define r28 28 +#define r29 29 +#define r30 30 +#define r31 31 + +#define cr0 0 +#define cr1 1 +#define cr2 2 +#define cr3 3 +#define cr4 4 +#define cr5 5 +#define cr6 6 +#define cr7 7 + +#define function_prolog(func_name) .csect .func_name[PR]; \ + .globl .func_name[PR]; \ + func_name: + +#define function_epilog(func_name) .toc; \ + .csect func_name[DS]; \ + .globl func_name[DS]; \ + .long .func_name[PR]; \ + .long TOC[tc0] + +#define function_call(func_name) .extern .func_name[PR]; \ + stw r2,stack_frame_toc(r1); \ + mfspr r2,sprg0; \ + bl .func_name[PR]; \ + lwz r2,stack_frame_toc(r1) + +#define stack_frame_min 56 +#define stack_frame_bc 0 +#define stack_frame_lr 8 +#define stack_frame_toc 20 +#define stack_neg_off 276 + +#endif +#define function_prolog(func_name) .text; \ + .align 2; \ + .globl func_name; \ + func_name: +#define function_epilog(func_name) .type func_name,@function; \ + .size func_name,.-func_name + +#define function_call(func_name) bl func_name + +/*----------------------------------------------------------------------------+ +| Function prolog definition for GNU ++----------------------------------------------------------------------------*/ +#ifdef _GNU_TOOL + +#define function_prolog(func_name) .globl func_name; \ + func_name: +#define function_epilog(func_name) + +#endif diff --git a/arch/ppc/boot/simple/rw4/rw4_init.S b/arch/ppc/boot/simple/rw4/rw4_init.S new file mode 100644 index 000000000000..b1061962e46b --- /dev/null +++ b/arch/ppc/boot/simple/rw4/rw4_init.S @@ -0,0 +1,78 @@ +#define VESTA +#include "ppc_40x.h" +# + .align 2 + .text +# +# added by linguohui + .extern initb_ebiu0, initb_config, hdw_init_finish + .extern initb_hsmc0, initb_hsmc1, initb_cache +# end added + .globl HdwInit +# +HdwInit: +# +#-----------------------------------------------------------------------* +# If we are not executing from the FLASH get out * +#-----------------------------------------------------------------------* +# SAW keep this or comment out a la Hawthorne? +# r3 contains NIP when used with Linux +# rlwinm r28, r3, 8, 24, 31 # if MSB == 0xFF -> FLASH address +# cmpwi r28, 0xff +# bne locn01 +# +# +#------------------------------------------------------------------------ +# Init_cpu. Bank registers are setup for the IBM STB. +#------------------------------------------------------------------------ +# +# Setup processor core clock to be driven off chip. This is GPI4 bit +# twenty. Setup Open Drain, Output Select, Three-State Control, and +# Three-State Select registers. +# + + + pb0pesr = 0x054 + pb0pear = 0x056 + + mflr r30 + +#----------------------------------------------------------------------------- +# Vectors will be at 0x1F000000 +# Dummy Machine check handler just does RFI before true handler gets installed +#----------------------------------------------------------------------------- +#if 1 /* xuwentao added*/ +#ifdef SDRAM16MB + lis r10,0x0000 + addi r10,r10,0x0000 +#else + lis r10,0x1F00 + addi r10,r10,0x0000 +#endif + + mtspr evpr,r10 #EVPR: 0x0 or 0x1f000000 depending + isync # on SDRAM memory model used. + + lis r10,0xFFFF # clear PB0_PESR because some + ori r10,r10,0xFFFF # transitions from flash,changed by linguohui + mtdcr pb0pesr,r10 # to load RAM image via RiscWatch + lis r10,0x0000 # cause PB0_PESR machine checks + mtdcr pb0pear,r10 + addis r10,r10,0x0000 # clear the + mtxer r10 # XER just in case... +#endif /* xuwentao*/ + + bl initb_ebiu0 # init EBIU + + bl initb_config # config PPC and board + + + + +#------------------------------------------------------------------------ +# EVPR setup moved to top of this function. +#------------------------------------------------------------------------ +# + mtlr r30 + blr + .end diff --git a/arch/ppc/boot/simple/rw4/rw4_init_brd.S b/arch/ppc/boot/simple/rw4/rw4_init_brd.S new file mode 100644 index 000000000000..386afdaad6c7 --- /dev/null +++ b/arch/ppc/boot/simple/rw4/rw4_init_brd.S @@ -0,0 +1,1125 @@ +/*----------------------------------------------------------------------------+ +| This source code has been made available to you by IBM on an AS-IS +| basis. Anyone receiving this source is licensed under IBM +| copyrights to use it in any way he or she deems fit, including +| copying it, modifying it, compiling it, and redistributing it either +| with or without modifications. No license under IBM patents or +| patent applications is to be implied by the copyright license. +| +| Any user of this software should understand that IBM cannot provide +| technical support for this software and will not be responsible for +| any consequences resulting from the use of this software. +| +| Any person who transfers this source code or any derivative work +| must include the IBM copyright notice, this paragraph, and the +| preceding two paragraphs in the transferred software. +| +| COPYRIGHT I B M CORPORATION 1997 +| LICENSED MATERIAL - PROGRAM PROPERTY OF I B M ++----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------+ +| Author: Tony J. Cerreto +| Component: BSPS +| File: init_brd.s +| Purpose: Vesta Evaluation Board initialization subroutines. The following +| routines are available: +| 1. INITB_EBIU0: Initialize EBIU0. +| 2. INITB_CONFIG: Configure board. +| 3. INITB_HSMC0: Initialize HSMC0 (SDRAM). +| 4. INITB_HSMC1: Initialize HSMC1 (SDRAM). +| 5. INITB_CACHE: Initialize Data and Instruction Cache. +| 6. INITB_DCACHE: Initialize Data Cache. +| 7. INITB_ICACHE: Initialize Instruction Cache. +| 8. INITB_GET_CSPD: Get CPU Speed (Bus Speed and Processor Speed) +| +| Changes: +| Date: Author Comment: +| --------- ------ -------- +| 01-Mar-00 tjc Created +| 04-Mar-00 jfh Modified CIC_SEL3_VAL to support 1284 (Mux3 & GPIO 21-28) +| 04-Mar-00 jfh Modified XILINIX Reg 0 to support 1284 (Mux3 & GPIO 21-28) +| 04-Mar-00 jfh Modified XILINIX Reg 1 to support 1284 (Mux3 & GPIO 21-28) +| 04-Mar-00 jfh Modified XILINIX Reg 4 to support 1284 (Mux3 & GPIO 21-28) +| 19-May-00 rlb Relcoated HSMC0 to 0x1F000000 to support 32MB of contiguous +| SDRAM space. Changed cache ctl regs to reflect this. +| 22-May-00 tjc Changed initb_get_cspd interface and eliminated +| initb_get_bspd routines. +| 26-May-00 tjc Added two nop instructions after all mtxxx/mfxxx +| instructions due to PPC405 bug. ++----------------------------------------------------------------------------*/ +#define VESTA +#include "ppc_40x.h" +#include "stb.h" + +/*----------------------------------------------------------------------------+ +| BOARD CONFIGURATION DEFINES ++----------------------------------------------------------------------------*/ +#define CBS0_CR_VAL 0x00000002 /* CBS control reg value */ +#define CIC0_CR_VAL 0xD0800448 /* CIC control reg value */ +#define CIC0_SEL3_VAL 0x11500000 /* CIC select 3 reg value */ +#define CIC0_VCR_VAL 0x00631700 /* CIC video cntl reg value */ + +/*----------------------------------------------------------------------------+ +| EBIU0 BANK REGISTERS DEFINES ++----------------------------------------------------------------------------*/ +#define EBIU0_BRCRH0_VAL 0x00000000 /* BR High 0 (Extension Reg)*/ +#define EBIU0_BRCRH1_VAL 0x00000000 /* BR High 1 (Extension Reg)*/ +#define EBIU0_BRCRH2_VAL 0x40000000 /* BR High 2 (Extension Reg)*/ +#define EBIU0_BRCRH3_VAL 0x40000000 /* BR High 3 (Extension Reg)*/ +#define EBIU0_BRCRH4_VAL 0x00000000 /* BR High 4 (Extension Reg)*/ +#define EBIU0_BRCRH5_VAL 0x00000000 /* BR High 5 (Extension Reg)*/ +#define EBIU0_BRCRH6_VAL 0x00000000 /* BR High 6 (Extension Reg)*/ +#define EBIU0_BRCRH7_VAL 0x40000000 /* BR High 7 (Extension Reg)*/ + +#define EBIU0_BRCR0_VAL 0xFC58BFFE /* BR 0: 16 bit Flash 4 MB */ +#define EBIU0_BRCR1_VAL 0xFF00BFFE /* BR 1: Ext Connector 1 MB */ +#if 1 +#define EBIU0_BRCR2_VAL 0x207CFFBE /* BR 2: Xilinx 8 MB */ + /* twt == 0x3f */ +#else +#define EBIU0_BRCR2_VAL 0x207CCFBE /* BR 2: Xilinx 8 MB */ + /* twt == 0x0f */ +#endif +#define EBIU0_BRCR3_VAL 0x407CBFBE /* BR 3: IDE Drive 8 MB */ +#define EBIU0_BRCR4_VAL 0xFF00BFFF /* BR 4: Disabled. 0 MB */ +#define EBIU0_BRCR5_VAL 0xFF00BFFF /* BR 5: Disabled. 0 MB */ +#define EBIU0_BRCR6_VAL 0xFF00BFFF /* BR 6: Disabled. 0 MB */ +#define EBIU0_BRCR7_VAL 0xCE3F0003 /* BR 7: Line Mode DMA 2 MB */ + +/*----------------------------------------------------------------------------+ +| GPIO DEFINES ++----------------------------------------------------------------------------*/ +#define STB_GPIO0_OUTPUT (STB_GPIO0_BASE_ADDRESS+ 0x00) +#define STB_GPIO0_TC (STB_GPIO0_BASE_ADDRESS+ 0x04) +#define STB_GPIO0_OS_0_31 (STB_GPIO0_BASE_ADDRESS+ 0x08) +#define STB_GPIO0_OS_32_63 (STB_GPIO0_BASE_ADDRESS+ 0x0C) +#define STB_GPIO0_TS_0_31 (STB_GPIO0_BASE_ADDRESS+ 0x10) +#define STB_GPIO0_TS_32_63 (STB_GPIO0_BASE_ADDRESS+ 0x14) +#define STB_GPIO0_OD (STB_GPIO0_BASE_ADDRESS+ 0x18) +#define STB_GPIO0_INPUT (STB_GPIO0_BASE_ADDRESS+ 0x1C) +#define STB_GPIO0_R1 (STB_GPIO0_BASE_ADDRESS+ 0x20) +#define STB_GPIO0_R2 (STB_GPIO0_BASE_ADDRESS+ 0x24) +#define STB_GPIO0_R3 (STB_GPIO0_BASE_ADDRESS+ 0x28) +#define STB_GPIO0_IS_1_0_31 (STB_GPIO0_BASE_ADDRESS+ 0x30) +#define STB_GPIO0_IS_1_32_63 (STB_GPIO0_BASE_ADDRESS+ 0x34) +#define STB_GPIO0_IS_2_0_31 (STB_GPIO0_BASE_ADDRESS+ 0x38) +#define STB_GPIO0_IS_2_32_63 (STB_GPIO0_BASE_ADDRESS+ 0x3C) +#define STB_GPIO0_IS_3_0_31 (STB_GPIO0_BASE_ADDRESS+ 0x40) +#define STB_GPIO0_IS_3_32_63 (STB_GPIO0_BASE_ADDRESS+ 0x44) +#define STB_GPIO0_SS_1 (STB_GPIO0_BASE_ADDRESS+ 0x50) +#define STB_GPIO0_SS_2 (STB_GPIO0_BASE_ADDRESS+ 0x54) +#define STB_GPIO0_SS_3 (STB_GPIO0_BASE_ADDRESS+ 0x58) + +#define GPIO0_TC_VAL 0x0C020004 /* three-state control val */ +#define GPIO0_OS_0_31_VAL 0x51A00004 /* output select 0-31 val */ +#define GPIO0_OS_32_63_VAL 0x0000002F /* output select 32-63 val */ +#define GPIO0_TS_0_31_VAL 0x51A00000 /* three-state sel 0-31 val*/ +#define GPIO0_TS_32_63_VAL 0x0000000F /* three-state sel 32-63 val*/ +#define GPIO0_OD_VAL 0xC0000004 /* open drain val */ +#define GPIO0_IS_1_0_31_VAL 0x50000151 /* input select 1 0-31 val */ +#define GPIO0_IS_1_32_63_VAL 0x00000000 /* input select 1 32-63 val */ +#define GPIO0_IS_2_0_31_VAL 0x00000000 /* input select 2 0-31 val */ +#define GPIO0_IS_2_32_63_VAL 0x00000000 /* input select 2 32-63 val */ +#define GPIO0_IS_3_0_31_VAL 0x00000440 /* input select 3 0-31 val */ +#define GPIO0_IS_3_32_63_VAL 0x00000000 /* input select 3 32-63 val */ +#define GPIO0_SS_1_VAL 0x00000000 /* sync select 1 val */ +#define GPIO0_SS_2_VAL 0x00000000 /* sync select 2 val */ +#define GPIO0_SS_3_VAL 0x00000000 /* sync select 3 val */ + +/*----------------------------------------------------------------------------+ +| XILINX DEFINES ++----------------------------------------------------------------------------*/ +#define STB_XILINX_LED (STB_FPGA_BASE_ADDRESS+ 0x0100) +#define STB_XILINX1_REG0 (STB_FPGA_BASE_ADDRESS+ 0x40000) +#define STB_XILINX1_REG1 (STB_FPGA_BASE_ADDRESS+ 0x40002) +#define STB_XILINX1_REG2 (STB_FPGA_BASE_ADDRESS+ 0x40004) +#define STB_XILINX1_REG3 (STB_FPGA_BASE_ADDRESS+ 0x40006) +#define STB_XILINX1_REG4 (STB_FPGA_BASE_ADDRESS+ 0x40008) +#define STB_XILINX1_REG5 (STB_FPGA_BASE_ADDRESS+ 0x4000A) +#define STB_XILINX1_REG6 (STB_FPGA_BASE_ADDRESS+ 0x4000C) +#define STB_XILINX1_ID (STB_FPGA_BASE_ADDRESS+ 0x4000E) +#define STB_XILINX1_FLUSH (STB_FPGA_BASE_ADDRESS+ 0x4000E) +#define STB_XILINX2_REG0 (STB_FPGA_BASE_ADDRESS+ 0x80000) +#define STB_XILINX2_REG1 (STB_FPGA_BASE_ADDRESS+ 0x80002) +#define STB_XILINX2_REG2 (STB_FPGA_BASE_ADDRESS+ 0x80004) + +#define XILINX1_R0_VAL 0x2440 /* Xilinx 1 Register 0 Val */ +#define XILINX1_R1_VAL 0x0025 /* Xilinx 1 Register 1 Val */ +#define XILINX1_R2_VAL 0x0441 /* Xilinx 1 Register 2 Val */ +#define XILINX1_R3_VAL 0x0008 /* Xilinx 1 Register 3 Val */ +#define XILINX1_R4_VAL 0x0100 /* Xilinx 1 Register 4 Val */ +#define XILINX1_R5_VAL 0x6810 /* Xilinx 1 Register 5 Val */ +#define XILINX1_R6_VAL 0x0000 /* Xilinx 1 Register 6 Val */ +#if 0 +#define XILINX2_R0_VAL 0x0008 /* Xilinx 2 Register 0 Val */ +#define XILINX2_R1_VAL 0x0000 /* Xilinx 2 Register 1 Val */ +#else +#define XILINX2_R0_VAL 0x0018 /* disable IBM IrDA RxD */ +#define XILINX2_R1_VAL 0x0008 /* enable SICC MAX chip */ +#endif +#define XILINX2_R2_VAL 0x0000 /* Xilinx 2 Register 2 Val */ + +/*----------------------------------------------------------------------------+ +| HSMC BANK REGISTERS DEFINES ++----------------------------------------------------------------------------*/ +#ifdef SDRAM16MB +#define HSMC0_BR0_VAL 0x000D2D55 /* 0x1F000000-007FFFFF R/W */ +#define HSMC0_BR1_VAL 0x008D2D55 /* 0x1F800000-1FFFFFFF R/W */ +#else +#define HSMC0_BR0_VAL 0x1F0D2D55 /* 0x1F000000-007FFFFF R/W */ +#define HSMC0_BR1_VAL 0x1F8D2D55 /* 0x1F800000-1FFFFFFF R/W */ +#endif +#define HSMC1_BR0_VAL 0xA00D2D55 /* 0xA0000000-A07FFFFF R/W */ +#define HSMC1_BR1_VAL 0xA08D2D55 /* 0xA0800000-A0FFFFFF R/W */ + +/*----------------------------------------------------------------------------+ +| CACHE DEFINES ++----------------------------------------------------------------------------*/ +#define DCACHE_NLINES 128 /* no. D-cache lines */ +#define DCACHE_NBYTES 32 /* no. bytes/ D-cache line */ +#define ICACHE_NLINES 256 /* no. I-cache lines */ +#define ICACHE_NBYTES 32 /* no. bytes/ I-cache line */ +#ifdef SDRAM16MB +#define DCACHE_ENABLE 0x80000000 /* D-cache regions to enable*/ +#define ICACHE_ENABLE 0x80000001 /* I-cache regions to enable*/ +#else +#define DCACHE_ENABLE 0x18000000 /* D-cache regions to enable*/ +#define ICACHE_ENABLE 0x18000001 /* I-cache regions to enable*/ +#endif + +/*----------------------------------------------------------------------------+ +| CPU CORE SPEED CALCULATION DEFINES ++----------------------------------------------------------------------------*/ +#define GCS_LCNT 500000 /* CPU speed loop count */ +#define GCS_TROW_BYTES 8 /* no. bytes in table row */ +#define GCS_CTICK_TOL 100 /* allowable clock tick tol */ +#define GCS_NMULT 4 /* no. of core speed mults */ + + /*--------------------------------------------------------------------+ + | No. 13.5Mhz + | Clock Ticks + | based on a + | loop count Bus + | of 100,000 Speed + +--------------------------------------------------------------------*/ +gcs_lookup_table: + .int 50000, 54000000 /* 54.0 Mhz */ + .int 66667, 40500000 /* 40.5 Mhz */ + .int 54545, 49500000 /* 49.5 Mhz */ + .int 46154, 58500000 /* 58.5 Mhz */ + .int 0, 0 /* end of table flag */ + + +/*****************************************************************************+ +| XXXXXXX XXX XXX XXXXXX XXXXXXX XXXXXX XX XX XX XXXX +| XX X XX XX X XX X XX X XX XX XXX XX XXXX XX +| XX X XXX XX XX X XX XX XXXX XX XX XX XX +| XXXX X XX XXXX XXXXX XX XXXX XX XX XX +| XX X XXX XX XX X XX XX XX XXX XXXXXX XX +| XX X XX XX XX XX X XX XX XX XX XX XX XX XX +| XXXXXXX XXX XXX XXXX XXXXXXX XXX XX XX XX XX XX XXXXXXX ++*****************************************************************************/ +/****************************************************************************** +| +| Routine: INITB_EBIU0. +| +| Purpose: Initialize all the EBIU0 Bank Registers +| Parameters: None. +| Returns: None. +| +******************************************************************************/ + function_prolog(initb_ebiu0) + /*--------------------------------------------------------------------+ + | Set EBIU0 Bank 0 + +--------------------------------------------------------------------*/ + lis r10,EBIU0_BRCR0_VAL@h + ori r10,r10,EBIU0_BRCR0_VAL@l + mtdcr ebiu0_brcr0,r10 + lis r10,EBIU0_BRCRH0_VAL@h + ori r10,r10,EBIU0_BRCRH0_VAL@l + mtdcr ebiu0_brcrh0,r10 + + /*--------------------------------------------------------------------+ + | Set EBIU0 Bank 1 + +--------------------------------------------------------------------*/ + lis r10,EBIU0_BRCR1_VAL@h + ori r10,r10,EBIU0_BRCR1_VAL@l + mtdcr ebiu0_brcr1,r10 + lis r10,EBIU0_BRCRH1_VAL@h + ori r10,r10,EBIU0_BRCRH1_VAL@l + mtdcr ebiu0_brcrh1,r10 + + /*--------------------------------------------------------------------+ + | Set EBIU0 Bank 2 + +--------------------------------------------------------------------*/ + lis r10,EBIU0_BRCR2_VAL@h + ori r10,r10,EBIU0_BRCR2_VAL@l + mtdcr ebiu0_brcr2,r10 + lis r10,EBIU0_BRCRH2_VAL@h + ori r10,r10,EBIU0_BRCRH2_VAL@l + mtdcr ebiu0_brcrh2,r10 + + /*--------------------------------------------------------------------+ + | Set EBIU0 Bank 3 + +--------------------------------------------------------------------*/ + lis r10,EBIU0_BRCR3_VAL@h + ori r10,r10,EBIU0_BRCR3_VAL@l + mtdcr ebiu0_brcr3,r10 + lis r10,EBIU0_BRCRH3_VAL@h + ori r10,r10,EBIU0_BRCRH3_VAL@l + mtdcr ebiu0_brcrh3,r10 + + /*--------------------------------------------------------------------+ + | Set EBIU0 Bank 4 + +--------------------------------------------------------------------*/ + lis r10,EBIU0_BRCR4_VAL@h + ori r10,r10,EBIU0_BRCR4_VAL@l + mtdcr ebiu0_brcr4,r10 + lis r10,EBIU0_BRCRH4_VAL@h + ori r10,r10,EBIU0_BRCRH4_VAL@l + mtdcr ebiu0_brcrh4,r10 + + /*--------------------------------------------------------------------+ + | Set EBIU0 Bank 5 + +--------------------------------------------------------------------*/ + lis r10,EBIU0_BRCR5_VAL@h + ori r10,r10,EBIU0_BRCR5_VAL@l + mtdcr ebiu0_brcr5,r10 + lis r10,EBIU0_BRCRH5_VAL@h + ori r10,r10,EBIU0_BRCRH5_VAL@l + mtdcr ebiu0_brcrh5,r10 + + /*--------------------------------------------------------------------+ + | Set EBIU0 Bank 6 + +--------------------------------------------------------------------*/ + lis r10,EBIU0_BRCR6_VAL@h + ori r10,r10,EBIU0_BRCR6_VAL@l + mtdcr ebiu0_brcr6,r10 + lis r10,EBIU0_BRCRH6_VAL@h + ori r10,r10,EBIU0_BRCRH6_VAL@l + mtdcr ebiu0_brcrh6,r10 + + /*--------------------------------------------------------------------+ + | Set EBIU0 Bank 7 + +--------------------------------------------------------------------*/ + lis r10,EBIU0_BRCR7_VAL@h + ori r10,r10,EBIU0_BRCR7_VAL@l + mtdcr ebiu0_brcr7,r10 + lis r10,EBIU0_BRCRH7_VAL@h + ori r10,r10,EBIU0_BRCRH7_VAL@l + mtdcr ebiu0_brcrh7,r10 + + blr + function_epilog(initb_ebiu0) + + +/****************************************************************************** +| +| Routine: INITB_CONFIG +| +| Purpose: Configure the Vesta Evaluation Board. The following items +| will be configured: +| 1. Cross-Bar Switch. +| 2. Chip Interconnect. +| 3. Clear/reset key PPC registers. +| 4. Xilinx and GPIO Registers. +| +| Returns: None. +| +******************************************************************************/ + function_prolog(initb_config) + /*--------------------------------------------------------------------+ + | Init CROSS-BAR SWITCH + +--------------------------------------------------------------------*/ + lis r10,CBS0_CR_VAL@h /* r10 <- CBS Cntl Reg val */ + ori r10,r10,CBS0_CR_VAL@l + mtdcr cbs0_cr,r10 + + /*--------------------------------------------------------------------+ + | Init Chip-Interconnect (CIC) Registers + +--------------------------------------------------------------------*/ + lis r10,CIC0_CR_VAL@h /* r10 <- CIC Cntl Reg val */ + ori r10,r10,CIC0_CR_VAL@l + mtdcr cic0_cr,r10 + + lis r10,CIC0_SEL3_VAL@h /* r10 <- CIC SEL3 Reg val */ + ori r10,r10,CIC0_SEL3_VAL@l + mtdcr cic0_sel3,r10 + + lis r10,CIC0_VCR_VAL@h /* r10 <- CIC Vid C-Reg val */ + ori r10,r10,CIC0_VCR_VAL@l + mtdcr cic0_vcr,r10 + + /*--------------------------------------------------------------------+ + | Clear SGR and DCWR + +--------------------------------------------------------------------*/ + li r10,0x0000 + mtspr sgr,r10 + mtspr dcwr,r10 + + /*--------------------------------------------------------------------+ + | Clear/set up some machine state registers. + +--------------------------------------------------------------------*/ + li r10,0x0000 /* r10 <- 0 */ + mtdcr ebiu0_besr,r10 /* clr Bus Err Syndrome Reg */ + mtspr esr,r10 /* clr Exceptn Syndrome Reg */ + mttcr r10 /* timer control register */ + + mtdcr uic0_er,r10 /* disable all interrupts */ + + /* UIC_IIC0 | UIC_IIC1 | UIC_U0 | UIC_IR_RCV | UIC_IR_XMIT */ + lis r10, 0x00600e00@h + ori r10,r10,0x00600e00@l + mtdcr uic0_pr,r10 + + li r10,0x00000020 /* UIC_EIR1 */ + mtdcr uic0_tr,r10 + + lis r10,0xFFFF /* r10 <- 0xFFFFFFFF */ + ori r10,r10,0xFFFF /* */ + mtdbsr r10 /* clear/reset the dbsr */ + mtdcr uic0_sr,r10 /* clear pending interrupts */ + + li r10,0x1000 /* set Machine Exception bit*/ + oris r10,r10,0x2 /* set Criticl Exception bit*/ + mtmsr r10 /* change MSR */ + + /*--------------------------------------------------------------------+ + | Clear XER. + +--------------------------------------------------------------------*/ + li r10,0x0000 + mtxer r10 + + /*--------------------------------------------------------------------+ + | Init GPIO0 Registers + +--------------------------------------------------------------------*/ + lis r10, STB_GPIO0_TC@h /* Three-state control */ + ori r10,r10,STB_GPIO0_TC@l + lis r11, GPIO0_TC_VAL@h + ori r11,r11,GPIO0_TC_VAL@l + stw r11,0(r10) + + lis r10, STB_GPIO0_OS_0_31@h /* output select 0-31 */ + ori r10,r10,STB_GPIO0_OS_0_31@l + lis r11, GPIO0_OS_0_31_VAL@h + ori r11,r11,GPIO0_OS_0_31_VAL@l + stw r11,0(r10) + + lis r10, STB_GPIO0_OS_32_63@h /* output select 32-63 */ + ori r10,r10,STB_GPIO0_OS_32_63@l + lis r11, GPIO0_OS_32_63_VAL@h + ori r11,r11,GPIO0_OS_32_63_VAL@l + stw r11,0(r10) + + lis r10, STB_GPIO0_TS_0_31@h /* three-state select 0-31 */ + ori r10,r10,STB_GPIO0_TS_0_31@l + lis r11, GPIO0_TS_0_31_VAL@h + ori r11,r11,GPIO0_TS_0_31_VAL@l + stw r11,0(r10) + + lis r10, STB_GPIO0_TS_32_63@h /* three-state select 32-63 */ + ori r10,r10,STB_GPIO0_TS_32_63@l + lis r11, GPIO0_TS_32_63_VAL@h + ori r11,r11,GPIO0_TS_32_63_VAL@l + stw r11,0(r10) + + lis r10, STB_GPIO0_OD@h /* open drain */ + ori r10,r10,STB_GPIO0_OD@l + lis r11, GPIO0_OD_VAL@h + ori r11,r11,GPIO0_OD_VAL@l + stw r11,0(r10) + + lis r10, STB_GPIO0_IS_1_0_31@h /* input select 1, 0-31 */ + ori r10,r10,STB_GPIO0_IS_1_0_31@l + lis r11, GPIO0_IS_1_0_31_VAL@h + ori r11,r11,GPIO0_IS_1_0_31_VAL@l + stw r11,0(r10) + + lis r10, STB_GPIO0_IS_1_32_63@h /* input select 1, 32-63 */ + ori r10,r10,STB_GPIO0_IS_1_32_63@l + lis r11, GPIO0_IS_1_32_63_VAL@h + ori r11,r11,GPIO0_IS_1_32_63_VAL@l + stw r11,0(r10) + + lis r10, STB_GPIO0_IS_2_0_31@h /* input select 2, 0-31 */ + ori r10,r10,STB_GPIO0_IS_2_0_31@l + lis r11, GPIO0_IS_2_0_31_VAL@h + ori r11,r11,GPIO0_IS_2_0_31_VAL@l + stw r11,0(r10) + + lis r10, STB_GPIO0_IS_2_32_63@h /* input select 2, 32-63 */ + ori r10,r10,STB_GPIO0_IS_2_32_63@l + lis r11, GPIO0_IS_2_32_63_VAL@h + ori r11,r11,GPIO0_IS_2_32_63_VAL@l + stw r11,0(r10) + + lis r10, STB_GPIO0_IS_3_0_31@h /* input select 3, 0-31 */ + ori r10,r10,STB_GPIO0_IS_3_0_31@l + lis r11, GPIO0_IS_3_0_31_VAL@h + ori r11,r11,GPIO0_IS_3_0_31_VAL@l + stw r11,0(r10) + + lis r10, STB_GPIO0_IS_3_32_63@h /* input select 3, 32-63 */ + ori r10,r10,STB_GPIO0_IS_3_32_63@l + lis r11, GPIO0_IS_3_32_63_VAL@h + ori r11,r11,GPIO0_IS_3_32_63_VAL@l + stw r11,0(r10) + + lis r10, STB_GPIO0_SS_1@h /* sync select 1 */ + ori r10,r10,STB_GPIO0_SS_1@l + lis r11, GPIO0_SS_1_VAL@h + ori r11,r11,GPIO0_SS_1_VAL@l + stw r11,0(r10) + + lis r10, STB_GPIO0_SS_2@h /* sync select 2 */ + ori r10,r10,STB_GPIO0_SS_2@l + lis r11, GPIO0_SS_2_VAL@h + ori r11,r11,GPIO0_SS_2_VAL@l + stw r11,0(r10) + + lis r10, STB_GPIO0_SS_3@h /* sync select 3 */ + ori r10,r10,STB_GPIO0_SS_3@l + lis r11, GPIO0_SS_3_VAL@h + ori r11,r11,GPIO0_SS_3_VAL@l + stw r11,0(r10) + + /*--------------------------------------------------------------------+ + | Init Xilinx #1 Registers + +--------------------------------------------------------------------*/ + lis r10, STB_XILINX1_REG0@h /* init Xilinx1 Reg 0 */ + ori r10,r10,STB_XILINX1_REG0@l + li r11,XILINX1_R0_VAL + sth r11,0(r10) + + lis r10, STB_XILINX1_REG1@h /* init Xilinx1 Reg 1 */ + ori r10,r10,STB_XILINX1_REG1@l + li r11,XILINX1_R1_VAL + sth r11,0(r10) + + lis r10, STB_XILINX1_REG2@h /* init Xilinx1 Reg 2 */ + ori r10,r10,STB_XILINX1_REG2@l + li r11,XILINX1_R2_VAL + sth r11,0(r10) + + lis r10, STB_XILINX1_REG3@h /* init Xilinx1 Reg 3 */ + ori r10,r10,STB_XILINX1_REG3@l + li r11,XILINX1_R3_VAL + sth r11,0(r10) + + lis r10, STB_XILINX1_REG4@h /* init Xilinx1 Reg 4 */ + ori r10,r10,STB_XILINX1_REG4@l + li r11,XILINX1_R4_VAL + sth r11,0(r10) + + lis r10, STB_XILINX1_REG5@h /* init Xilinx1 Reg 5 */ + ori r10,r10,STB_XILINX1_REG5@l + li r11,XILINX1_R5_VAL + sth r11,0(r10) + + lis r10, STB_XILINX1_REG6@h /* init Xilinx1 Reg 6 */ + ori r10,r10,STB_XILINX1_REG6@l + li r11,XILINX1_R6_VAL + sth r11,0(r10) + + lis r10, STB_XILINX1_FLUSH@h /* latch registers in Xilinx*/ + ori r10,r10,STB_XILINX1_FLUSH@l + li r11,0x0000 + sth r11,0(r10) + + /*--------------------------------------------------------------------+ + | Init Xilinx #2 Registers + +--------------------------------------------------------------------*/ + lis r10, STB_XILINX2_REG0@h /* init Xilinx2 Reg 0 */ + ori r10,r10,STB_XILINX2_REG0@l + li r11,XILINX2_R0_VAL + sth r11,0(r10) + + lis r10, STB_XILINX2_REG1@h /* init Xilinx2 Reg 1 */ + ori r10,r10,STB_XILINX2_REG1@l + li r11,XILINX2_R1_VAL + sth r11,0(r10) + + lis r10, STB_XILINX2_REG2@h /* init Xilinx2 Reg 2 */ + ori r10,r10,STB_XILINX2_REG2@l + li r11,XILINX2_R2_VAL + sth r11,0(r10) + + blr + function_epilog(initb_config) + + +/****************************************************************************** +| +| Routine: INITB_HSMC0. +| +| Purpose: Initialize the HSMC0 Registers for SDRAM +| Parameters: None. +| Returns: R3 = 0: Successful +| = -1: Unsuccessful, SDRAM did not reset properly. +| +******************************************************************************/ + function_prolog(initb_hsmc0) + mflr r0 /* Save return addr */ + + /*--------------------------------------------------------------------+ + | Set Global SDRAM Controller to recommended default + +--------------------------------------------------------------------*/ + lis r10,0x6C00 + ori r10,r10,0x0000 + mtdcr hsmc0_gr,r10 + + /*--------------------------------------------------------------------+ + | Set HSMC0 Data Register to recommended default + +--------------------------------------------------------------------*/ + lis r10,0x0037 + ori r10,r10,0x0000 + mtdcr hsmc0_data,r10 + + /*--------------------------------------------------------------------+ + | Init HSMC0 Bank Register 0 + +--------------------------------------------------------------------*/ + lis r10,HSMC0_BR0_VAL@h + ori r10,r10,HSMC0_BR0_VAL@l + mtdcr hsmc0_br0,r10 + + /*--------------------------------------------------------------------+ + | Init HSMC0 Bank Register 1 + +--------------------------------------------------------------------*/ + lis r10,HSMC0_BR1_VAL@h + ori r10,r10,HSMC0_BR1_VAL@l + mtdcr hsmc0_br1,r10 + + /*--------------------------------------------------------------------+ + | Set HSMC0 Control Reg 0 + +--------------------------------------------------------------------*/ + lis r10,0x8077 /* PRECHARGE ALL DEVICE BKS */ + ori r10,r10,0x0000 + mtdcr hsmc0_cr0,r10 + li r3,0x0000 + bl hsmc_cr_wait /* wait for op completion */ + cmpwi cr0,r3,0x0000 + bne cr0,hsmc0_err + + lis r10,0x8078 /* AUTO-REFRESH */ + ori r10,r10,0x0000 + mtdcr hsmc0_cr0,r10 + li r3,0x0000 + bl hsmc_cr_wait /* wait for op completion */ + cmpwi cr0,r3,0x0000 + bne cr0,hsmc0_err + + lis r10,0x8070 /* PROG MODE W/DATA REG VAL */ + ori r10,r10,0x8000 + mtdcr hsmc0_cr0,r10 + li r3,0x0000 + bl hsmc_cr_wait /* wait for op completion */ + cmpwi cr0,r3,0x0000 + bne hsmc0_err + + /*--------------------------------------------------------------------+ + | Set HSMC0 Control Reg 1 + +--------------------------------------------------------------------*/ + lis r10,0x8077 /* PRECHARGE ALL DEVICE BKS */ + ori r10,r10,0x0000 + mtdcr hsmc0_cr1,r10 + li r3,0x0001 + bl hsmc_cr_wait /* wait for op completion */ + cmpwi cr0,r3,0x0000 + bne cr0,hsmc0_err + + lis r10,0x8078 /* AUTO-REFRESH */ + ori r10,r10,0x0000 + mtdcr hsmc0_cr1,r10 + li r3,0x0001 + bl hsmc_cr_wait /* wait for op completion */ + cmpwi cr0,r3,0x0000 + bne cr0,hsmc0_err + + lis r10,0x8070 /* PROG MODE W/DATA REG VAL */ + ori r10,r10,0x8000 + mtdcr hsmc0_cr1,r10 + li r3,0x0001 + bl hsmc_cr_wait /* wait for op completion */ + cmpwi cr0,r3,0x0000 + bne cr0,hsmc0_err + + /*--------------------------------------------------------------------+ + | Set HSMC0 Refresh Register + +--------------------------------------------------------------------*/ + lis r10,0x0FE1 + ori r10,r10,0x0000 + mtdcr hsmc0_crr,r10 + li r3,0 + +hsmc0_err: + mtlr r0 + blr + function_epilog(initb_hsmc0) + + +/****************************************************************************** +| +| Routine: INITB_HSMC1. +| +| Purpose: Initialize the HSMC1 Registers for SDRAM +| Parameters: None. +| Returns: R3 = 0: Successful +| = -1: Unsuccessful, SDRAM did not reset properly. +| +******************************************************************************/ + function_prolog(initb_hsmc1) + mflr r0 /* Save return addr */ + + /*--------------------------------------------------------------------+ + | Set Global SDRAM Controller to recommended default + +--------------------------------------------------------------------*/ + lis r10,0x6C00 + ori r10,r10,0x0000 + mtdcr hsmc1_gr,r10 + + /*--------------------------------------------------------------------+ + | Set HSMC1 Data Register to recommended default + +--------------------------------------------------------------------*/ + lis r10,0x0037 + ori r10,r10,0x0000 + mtdcr hsmc1_data,r10 + + /*--------------------------------------------------------------------+ + | Init HSMC1 Bank Register 0 + +--------------------------------------------------------------------*/ + lis r10,HSMC1_BR0_VAL@h + ori r10,r10,HSMC1_BR0_VAL@l + mtdcr hsmc1_br0,r10 + + /*--------------------------------------------------------------------+ + | Init HSMC1 Bank Register 1 + +--------------------------------------------------------------------*/ + lis r10,HSMC1_BR1_VAL@h + ori r10,r10,HSMC1_BR1_VAL@l + mtdcr hsmc1_br1,r10 + + /*--------------------------------------------------------------------+ + | Set HSMC1 Control Reg 0 + +--------------------------------------------------------------------*/ + lis r10,0x8077 /* PRECHARGE ALL DEVICE BANKS */ + ori r10,r10,0x0000 + mtdcr hsmc1_cr0,r10 + li r3,0x0002 + bl hsmc_cr_wait /* wait for operation completion */ + cmpwi cr0,r3,0x0000 + bne hsmc1_err + + lis r10,0x8078 /* AUTO-REFRESH */ + ori r10,r10,0x0000 + mtdcr hsmc1_cr0,r10 + li r3,0x0002 + bl hsmc_cr_wait /* wait for operation completion */ + cmpwi cr0,r3,0x0000 + bne hsmc1_err + + lis r10,0x8070 /* PROGRAM MODE W/DATA REG VALUE */ + ori r10,r10,0x8000 + mtdcr hsmc1_cr0,r10 + li r3,0x0002 + bl hsmc_cr_wait /* wait for operation completion */ + cmpwi cr0,r3,0x0000 + bne hsmc1_err + + /*--------------------------------------------------------------------+ + | Set HSMC1 Control Reg 1 + +--------------------------------------------------------------------*/ + lis r10,0x8077 /* PRECHARGE ALL DEVICE BKS */ + ori r10,r10,0x0000 + mtdcr hsmc1_cr1,r10 + li r3,0x0003 + bl hsmc_cr_wait /* wait for op completion */ + cmpwi cr0,r3,0x0000 + bne hsmc1_err + + lis r10,0x8078 /* AUTO-REFRESH */ + ori r10,r10,0x0000 + mtdcr hsmc1_cr1,r10 + li r3,0x0003 + bl hsmc_cr_wait /* wait for op completion */ + cmpwi cr0,r3,0x0000 + bne hsmc1_err + + lis r10,0x8070 /* PROG MODE W/DATA REG VAL */ + ori r10,r10,0x8000 + mtdcr hsmc1_cr1,r10 + li r3,0x0003 + bl hsmc_cr_wait /* wait for op completion */ + cmpwi cr0,r3,0x0000 + bne hsmc1_err + + /*--------------------------------------------------------------------+ + | Set HSMC1 Refresh Register + +--------------------------------------------------------------------*/ + lis r10,0x0FE1 + ori r10,r10,0x0000 + mtdcr hsmc1_crr,r10 + xor r3,r3,r3 + +hsmc1_err: + mtlr r0 + blr + function_epilog(initb_hsmc1) + + +/****************************************************************************** +| +| Routine: INITB_CACHE +| +| Purpose: This routine will enable Data and Instruction Cache. +| The Data Cache is an 8K two-way set associative and the +| Instruction Cache is an 16K two-way set associative cache. +| +| Parameters: None. +| +| Returns: None. +| +******************************************************************************/ + function_prolog(initb_cache) + mflr r0 /* Save return addr */ + + bl initb_Dcache /* enable D-Cache */ + bl initb_Icache /* enable I-Cache */ + + mtlr r0 + blr + function_epilog(initb_cache) + + +/****************************************************************************** +| +| Routine: INITB_DCACHE +| +| Purpose: This routine will invalidate all data in the Data Cache and +| then enable D-Cache. If cache is enabled already, the D-Cache +| will be flushed before the data is invalidated. +| +| Parameters: None. +| +| Returns: None. +| +******************************************************************************/ + function_prolog(initb_Dcache) + /*--------------------------------------------------------------------+ + | Flush Data Cache if enabled + +--------------------------------------------------------------------*/ + mfdccr r10 /* r10 <- DCCR */ + isync /* ensure prev insts done */ + cmpwi r10,0x00 + beq ic_dcinv /* D-cache off, invalidate */ + + /*--------------------------------------------------------------------+ + | Data Cache enabled, force known memory addresses to be Cached + +--------------------------------------------------------------------*/ + lis r10,HSMC0_BR0_VAL@h /* r10 <- first memory loc */ + andis. r10,r10,0xFFF0 + li r11,DCACHE_NLINES /* r11 <- # A-way addresses */ + addi r11,r11,DCACHE_NLINES /* r11 <- # B-way addresses */ + mtctr r11 /* set loop counter */ + +ic_dcload: + lwz r12,0(r10) /* force cache of address */ + addi r10,r10,DCACHE_NBYTES /* r10 <- next memory loc */ + bdnz ic_dcload + sync /* ensure prev insts done */ + isync + + /*--------------------------------------------------------------------+ + | Flush the known memory addresses from Cache + +--------------------------------------------------------------------*/ + lis r10,HSMC0_BR0_VAL@h /* r10 <- first memory loc */ + andis. r10,r10,0xFFF0 + mtctr r11 /* set loop counter */ + +ic_dcflush: + dcbf 0,r10 /* flush D-cache line */ + addi r10,r10,DCACHE_NBYTES /* r10 <- next memory loc */ + bdnz ic_dcflush + sync /* ensure prev insts done */ + isync + + /*--------------------------------------------------------------------+ + | Disable then invalidate Data Cache + +--------------------------------------------------------------------*/ + li r10,0 /* r10 <- 0 */ + mtdccr r10 /* disable the D-Cache */ + isync /* ensure prev insts done */ + +ic_dcinv: + li r10,0 /* r10 <- line address */ + li r11,DCACHE_NLINES /* r11 <- # lines in cache */ + mtctr r11 /* set loop counter */ + +ic_dcloop: + dccci 0,r10 /* invalidate A/B cache lns */ + addi r10,r10,DCACHE_NBYTES /* bump to next line */ + bdnz ic_dcloop + sync /* ensure prev insts done */ + isync + + /*--------------------------------------------------------------------+ + | Enable Data Cache + +--------------------------------------------------------------------*/ + lis r10,DCACHE_ENABLE@h /* r10 <- D-cache enable msk*/ + ori r10,r10,DCACHE_ENABLE@l + mtdccr r10 + sync /* ensure prev insts done */ + isync + + blr + function_epilog(initb_Dcache) + + +/****************************************************************************** +| +| Routine: INITB_ICACHE +| +| Purpose: This routine will invalidate all data in the Instruction +| Cache then enable I-Cache. +| +| Parameters: None. +| +| Returns: None. +| +******************************************************************************/ + function_prolog(initb_Icache) + /*--------------------------------------------------------------------+ + | Invalidate Instruction Cache + +--------------------------------------------------------------------*/ + li r10,0 /* r10 <- lines address */ + iccci 0,r10 /* invalidate all I-cache */ + sync /* ensure prev insts done */ + isync + + /*--------------------------------------------------------------------+ + | Enable Instruction Cache + +--------------------------------------------------------------------*/ + lis r10,ICACHE_ENABLE@h /* r10 <- I-cache enable msk*/ + ori r10,r10,ICACHE_ENABLE@l + mticcr r10 + sync /* ensure prev insts done */ + isync + + blr + function_epilog(initb_Icache) + +#if 0 +/****************************************************************************** +| +| Routine: INITB_GET_CSPD +| +| Purpose: Determine the CPU Core Speed. The 13.5 Mhz Time Base +| Counter (TBC) is used to measure a conditional branch +| instruction. +| +| Parameters: R3 = Address of Bus Speed +| R4 = Address of Core Speed +| +| Returns: (R3) = >0: Bus Speed. +| 0: Bus Speed not found in Look-Up Table. +| (R4) = >0: Core Speed. +| 0: Core Speed not found in Look-Up Table. +| +| Note: 1. This routine assumes the bdnz branch instruction takes +| two instruction cycles to complete. +| 2. This routine must be called before interrupts are enabled. +| +******************************************************************************/ + function_prolog(initb_get_cspd) + mflr r0 /* Save return address */ + /*--------------------------------------------------------------------+ + | Set-up timed loop + +--------------------------------------------------------------------*/ + lis r9,gcs_time_loop@h /* r9 <- addr loop instr */ + ori r9,r9,gcs_time_loop@l + lis r10,GCS_LCNT@h /* r10 <- loop count */ + ori r10,r10,GCS_LCNT@l + mtctr r10 /* ctr <- loop count */ + lis r11,STB_TIMERS_TBC@h /* r11 <- TBC register addr */ + ori r11,r11,STB_TIMERS_TBC@l + li r12,0 /* r12 <- 0 */ + + /*--------------------------------------------------------------------+ + | Cache timed-loop instruction + +--------------------------------------------------------------------*/ + icbt 0,r9 + sync + isync + + /*--------------------------------------------------------------------+ + | Get number of 13.5 Mhz cycles to execute time-loop + +--------------------------------------------------------------------*/ + stw r12,0(r11) /* reset TBC */ +gcs_time_loop: + bdnz+ gcs_time_loop /* force branch pred taken */ + lwz r5,0(r11) /* r5 <- num 13.5 Mhz ticks */ + li r6,5 /* LUT based on 1/5th the...*/ + divw r5,r5,r6 /*..loop count used */ + sync + isync + + /*--------------------------------------------------------------------+ + | Look-up core speed based on TBC value + +--------------------------------------------------------------------*/ + lis r6,gcs_lookup_table@h /* r6 <- pts at core spd LUT*/ + ori r6,r6,gcs_lookup_table@l + bl gcs_cspd_lookup /* find core speed in LUT */ + + mtlr r0 /* set return address */ + blr + function_epilog(initb_get_cspd) + +#endif +/*****************************************************************************+ +| XXXX XX XX XXXXXX XXXXXXX XXXXXX XX XX XX XXXX +| XX XXX XX X XX X XX X XX XX XXX XX XXXX XX +| XX XXXX XX XX XX X XX XX XXXX XX XX XX XX +| XX XX XXXX XX XXXX XXXXX XX XXXX XX XX XX +| XX XX XXX XX XX X XX XX XX XXX XXXXXX XX +| XX XX XX XX XX X XX XX XX XX XX XX XX XX +| XXXX XX XX XXXX XXXXXXX XXX XX XX XX XX XX XXXXXXX ++*****************************************************************************/ +/****************************************************************************** +| +| Routine: HSMC_CR_WAIT +| +| Purpose: Wait for the HSMC Control Register (bits 12-16) to be reset +| after an auto-refresh, pre-charge or program mode register +| command execution. +| +| Parameters: R3 = HSMC Control Register ID. +| 0: HSMC0 CR0 +| 1: HSMC0 CR1 +| 2: HSMC1 CR0 +| 3: HSMC1 CR1 +| +| Returns: R3 = 0: Successful +| -1: Unsuccessful +| +******************************************************************************/ +hsmc_cr_wait: + + li r11,10 /* r11 <- retry counter */ + mtctr r11 /* set retry counter */ + mr r11,r3 /* r11 <- HSMC CR reg id */ + +hsmc_cr_rep: + bdz hsmc_cr_err /* branch if max retries hit*/ + + /*--------------------------------------------------------------------+ + | GET HSMCx_CRx value based on HSMC Control Register ID + +--------------------------------------------------------------------*/ +try_hsmc0_cr0: /* CHECK IF ID=HSMC0 CR0 REG*/ + cmpwi cr0,r11,0x0000 + bne cr0,try_hsmc0_cr1 + mfdcr r10,hsmc0_cr0 /* r11 <- HSMC0 CR0 value */ + b hsmc_cr_read + +try_hsmc0_cr1: /* CHECK IF ID=HSMC0 CR1 REG*/ + cmpwi cr0,r11,0x0001 + bne cr0,try_hsmc1_cr0 + mfdcr r10,hsmc0_cr1 /* r10 <- HSMC0 CR1 value */ + b hsmc_cr_read + +try_hsmc1_cr0: /* CHECK IF ID=HSMC1 CR0 REG*/ + cmpwi cr0,r11,0x0002 + bne cr0,try_hsmc1_cr1 + mfdcr r10,hsmc1_cr0 /* r10 <- HSMC1 CR0 value */ + b hsmc_cr_read + +try_hsmc1_cr1: /* CHECK IF ID=HSMC1 CR1 REG*/ + cmpwi cr0,r11,0x0003 + bne cr0,hsmc_cr_err + mfdcr r10,hsmc1_cr1 /* r10 <- HSMC1 CR1 value */ + + /*--------------------------------------------------------------------+ + | Check if HSMC CR register was reset after command execution + +--------------------------------------------------------------------*/ +hsmc_cr_read: + lis r12,0x000F /* create "AND" mask */ + ori r12,r12,0x8000 + and. r10,r10,r12 /* r10 <- HSMC CR bits 12-16*/ + bne cr0,hsmc_cr_rep /* wait for bits to reset */ + li r3,0 /* set return code = success*/ + b hsmc_cr_done + +hsmc_cr_err: /* ERROR: SDRAM didn't reset*/ + li r3,-1 /* set RC=unsuccessful */ + +hsmc_cr_done: + blr + +#if 0 +/****************************************************************************** +| +| Routine: GCS_CSPD_LOOKUP +| +| Purpose: Uses the number of 13.5 Mhz clock ticks found after executing +| the branch instruction time loop to look-up the CPU Core Speed +| in the Core Speed Look-up Table. +| +| Parameters: R3 = Address of Bus Speed +| R4 = Address of Core Speed +| R5 = Number of 13.5 Mhz clock ticks found in time loop. +| R6 = Pointer to Core-Speed Look-Up Table +| +| Returns: (R3) = >0: Bus Speed. +| 0: Bus Speed not found in Look-Up Table. +| (R4) = >0: Core Speed. +| 0: Core Speed not found in Look-Up Table. +| +| Note: Core Speed = Bus Speed * Mult Factor (1-4x). +| +******************************************************************************/ +gcs_cspd_lookup: + + li r9,1 /* r9 <- core speed mult */ + /*--------------------------------------------------------------------+ + | Get theoritical number 13.5 Mhz ticks for a given Bus Speed from + | Look-up Table. Check all mult factors to determine if calculated + | value matches theoretical value (within a tolerance). + +--------------------------------------------------------------------*/ +gcs_cspd_loop: + lwz r10,0(r6) /* r10 <- no. ticks from LUT*/ + divw r10,r10,r9 /* r10 <- div mult (1-4x) */ + subi r11,r10,GCS_CTICK_TOL /* r11 <- no. tks low range */ + addi r12,r10,GCS_CTICK_TOL /* r12 <- no. tks high range*/ + + cmpw cr0,r5,r11 /* calc value within range? */ + blt gcs_cspd_retry /* less than low range */ + cmpw cr0,r5,r12 + bgt gcs_cspd_retry /* greater than high range */ + b gcs_cspd_fnd /* calc value within range */ + + /*--------------------------------------------------------------------+ + | SO FAR CORE SPEED NOT FOUND: Check next mult factor + +--------------------------------------------------------------------*/ +gcs_cspd_retry: + addi r9,r9,1 /* bump mult factor (1-4x) */ + cmpwi cr0,r9,GCS_NMULT + ble gcs_cspd_loop + + /*--------------------------------------------------------------------+ + | SO FAR CORE SPEED NOT FOUND: Point at next Bus Speed in LUT + +--------------------------------------------------------------------*/ + li r9,1 /* reset mult factor */ + addi r6,r6,GCS_TROW_BYTES /* point at next table entry*/ + lwz r10,0(r6) + cmpwi cr0,r10,0 /* check for EOT flag */ + bne gcs_cspd_loop + + /*--------------------------------------------------------------------+ + | COMPUTE CORE SPEED AND GET BUS SPEED FROM LOOK-UP TABLE + +--------------------------------------------------------------------*/ +gcs_cspd_fnd: + lwz r5,4(r6) /* r5 <- Bus Speed in LUT */ + mullw r6,r5,r9 /* r6 <- Core speed */ + stw r5,0(r3) /* (r3) <- Bus Speed */ + stw r6,0(r4) /* (r4) <- Core Speed */ + + blr +#endif diff --git a/arch/ppc/boot/simple/rw4/stb.h b/arch/ppc/boot/simple/rw4/stb.h new file mode 100644 index 000000000000..fd98ee0f843e --- /dev/null +++ b/arch/ppc/boot/simple/rw4/stb.h @@ -0,0 +1,239 @@ +/*----------------------------------------------------------------------------+ +| This source code has been made available to you by IBM on an AS-IS +| basis. Anyone receiving this source is licensed under IBM +| copyrights to use it in any way he or she deems fit, including +| copying it, modifying it, compiling it, and redistributing it either +| with or without modifications. No license under IBM patents or +| patent applications is to be implied by the copyright license. +| +| Any user of this software should understand that IBM cannot provide +| technical support for this software and will not be responsible for +| any consequences resulting from the use of this software. +| +| Any person who transfers this source code or any derivative work +| must include the IBM copyright notice, this paragraph, and the +| preceding two paragraphs in the transferred software. +| +| COPYRIGHT I B M CORPORATION 1999 +| LICENSED MATERIAL - PROGRAM PROPERTY OF I B M ++----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------+ +| Author: Maciej P. Tyrlik +| Component: Include file. +| File: stb.h +| Purpose: Common Set-tob-box definitions. +| Changes: +| Date: Comment: +| ----- -------- +| 14-Jan-97 Created for ElPaso pass 1 MPT +| 13-May-97 Added function prototype and global variables MPT +| 08-Dec-98 Added RAW IR task information MPT +| 19-Jan-99 Port to Romeo MPT +| 19-May-00 Changed SDRAM to 32MB contiguous 0x1F000000 - 0x20FFFFFF RLB ++----------------------------------------------------------------------------*/ + +#ifndef _stb_h_ +#define _stb_h_ + +/*----------------------------------------------------------------------------+ +| Read/write from I/O macros. ++----------------------------------------------------------------------------*/ +#define inbyte(port) (*((unsigned char volatile *)(port))) +#define outbyte(port,data) *(unsigned char volatile *)(port)=\ + (unsigned char)(data) + +#define inshort(port) (*((unsigned short volatile *)(port))) +#define outshort(port,data) *(unsigned short volatile *)(port)=\ + (unsigned short)(data) + +#define inword(port) (*((unsigned long volatile *)(port))) +#define outword(port,data) *(unsigned long volatile *)(port)=\ + (unsigned long)(data) + +/*----------------------------------------------------------------------------+ +| STB interrupts. ++----------------------------------------------------------------------------*/ +#define STB_XP_TP_INT 0 +#define STB_XP_APP_INT 1 +#define STB_AUD_INT 2 +#define STB_VID_INT 3 +#define STB_DMA0_INT 4 +#define STB_DMA1_INT 5 +#define STB_DMA2_INT 6 +#define STB_DMA3_INT 7 +#define STB_SCI_INT 8 +#define STB_I2C1_INT 9 +#define STB_I2C2_INT 10 +#define STB_GPT_PWM0 11 +#define STB_GPT_PWM1 12 +#define STB_SCP_INT 13 +#define STB_SSP_INT 14 +#define STB_GPT_PWM2 15 +#define STB_EXT5_INT 16 +#define STB_EXT6_INT 17 +#define STB_EXT7_INT 18 +#define STB_EXT8_INT 19 +#define STB_SCC_INT 20 +#define STB_SICC_RECV_INT 21 +#define STB_SICC_TRAN_INT 22 +#define STB_PPU_INT 23 +#define STB_DCRX_INT 24 +#define STB_EXT0_INT 25 +#define STB_EXT1_INT 26 +#define STB_EXT2_INT 27 +#define STB_EXT3_INT 28 +#define STB_EXT4_INT 29 +#define STB_REDWOOD_ENET_INT STB_EXT1_INT + +/*----------------------------------------------------------------------------+ +| STB tasks, task stack sizes, and task priorities. The actual task priority +| is 1 more than the specified number since priority 0 is reserved (system +| internaly adds 1 to supplied priority number). ++----------------------------------------------------------------------------*/ +#define STB_IDLE_TASK_SS (5* 1024) +#define STB_IDLE_TASK_PRIO 0 +#define STB_LEDTEST_SS (2* 1024) +#define STB_LEDTEST_PRIO 0 +#define STB_CURSOR_TASK_SS (10* 1024) +#define STB_CURSOR_TASK_PRIO 7 +#define STB_MPEG_TASK_SS (10* 1024) +#define STB_MPEG_TASK_PRIO 9 +#define STB_DEMUX_TASK_SS (10* 1024) +#define STB_DEMUX_TASK_PRIO 20 +#define RAW_STB_IR_TASK_SS (10* 1024) +#define RAW_STB_IR_TASK_PRIO 20 + +#define STB_SERIAL_ER_TASK_SS (10* 1024) +#define STB_SERIAL_ER_TASK_PRIO 1 +#define STB_CA_TASK_SS (10* 1024) +#define STB_CA_TASK_PRIO 8 + +#define INIT_DEFAULT_VIDEO_SS (10* 1024) +#define INIT_DEFAULT_VIDEO_PRIO 8 +#define INIT_DEFAULT_SERVI_SS (10* 1024) +#define INIT_DEFAULT_SERVI_PRIO 8 +#define INIT_DEFAULT_POST_SS (10* 1024) +#define INIT_DEFAULT_POST_PRIO 8 +#define INIT_DEFAULT_INTER_SS (10* 1024) +#define INIT_DEFAULT_INTER_PRIO 8 +#define INIT_DEFAULT_BR_SS (10* 1024) +#define INIT_DEFAULT_BR_PRIO 8 +#define INITIAL_TASK_STACK_SIZE (32* 1024) + +#ifdef VESTA +/*----------------------------------------------------------------------------+ +| Vesta Overall Address Map (all addresses are double mapped, bit 0 of the +| address is not decoded. Numbers below are dependent on board configuration. +| FLASH, SDRAM, DRAM numbers can be affected by actual board setup. +| +| FFE0,0000 - FFFF,FFFF FLASH +| F200,0000 - F210,FFFF FPGA logic +| Ethernet = F200,0000 +| LED Display = F200,0100 +| Xilinx #1 Regs = F204,0000 +| Xilinx #2 Regs = F208,0000 +| Spare = F20C,0000 +| IDE CS0 = F210,0000 +| F410,0000 - F410,FFFF IDE CS1 +| C000,0000 - C7FF,FFFF OBP +| C000,0000 - C000,0014 SICC (16550 + infra red) +| C001,0000 - C001,0018 PPU (Parallel Port) +| C002,0000 - C002,001B SC0 (Smart Card 0) +| C003,0000 - C003,000F I2C0 +| C004,0000 - C004,0009 SCC (16550 UART) +| C005,0000 - C005,0124 GPT (Timers) +| C006,0000 - C006,0058 GPIO0 +| C007,0000 - C007,001b SC1 (Smart Card 1) +| C008,0000 - C008,FFFF Unused +| C009,0000 - C009,FFFF Unused +| C00A,0000 - C00A,FFFF Unused +| C00B,0000 - C00B,000F I2C1 +| C00C,0000 - C00C,0006 SCP +| C00D,0000 - C00D,0010 SSP +| A000,0000 - A0FF,FFFF SDRAM1 (16M) +| 0000,0000 - 00FF,FFFF SDRAM0 (16M) ++----------------------------------------------------------------------------*/ +#define STB_FLASH_BASE_ADDRESS 0xFFE00000 +#define STB_FPGA_BASE_ADDRESS 0xF2000000 +#define STB_SICC_BASE_ADDRESS 0xC0000000 +#define STB_PPU_BASE_ADDR 0xC0010000 +#define STB_SC0_BASE_ADDRESS 0xC0020000 +#define STB_I2C1_BASE_ADDRESS 0xC0030000 +#define STB_SCC_BASE_ADDRESS 0xC0040000 +#define STB_TIMERS_BASE_ADDRESS 0xC0050000 +#define STB_GPIO0_BASE_ADDRESS 0xC0060000 +#define STB_SC1_BASE_ADDRESS 0xC0070000 +#define STB_I2C2_BASE_ADDRESS 0xC00B0000 +#define STB_SCP_BASE_ADDRESS 0xC00C0000 +#define STB_SSP_BASE_ADDRESS 0xC00D0000 +/*----------------------------------------------------------------------------+ +|The following are used by the IBM RTOS SW. +|15-May-00 Changed these values to reflect movement of base addresses in +|order to support 32MB of contiguous SDRAM space. +|Points to the cacheable region since these values are used in IBM RTOS +|to establish the vector address. ++----------------------------------------------------------------------------*/ +#define STB_SDRAM1_BASE_ADDRESS 0x20000000 +#define STB_SDRAM1_SIZE 0x01000000 +#define STB_SDRAM0_BASE_ADDRESS 0x1F000000 +#define STB_SDRAM0_SIZE 0x01000000 + +#else +/*----------------------------------------------------------------------------+ +| ElPaso Overall Address Map (all addresses are double mapped, bit 0 of the +| address is not decoded. Numbers below are dependent on board configuration. +| FLASH, SDRAM, DRAM numbers can be affected by actual board setup. OPB +| devices are inside the ElPaso chip. +| FFE0,0000 - FFFF,FFFF FLASH +| F144,0000 - F104,FFFF FPGA logic +| F140,0000 - F100,0000 ethernet (through FPGA logic) +| C000,0000 - C7FF,FFFF OBP +| C000,0000 - C000,0014 SICC (16550+ infra red) +| C001,0000 - C001,0016 PPU (parallel port) +| C002,0000 - C002,001B SC (smart card) +| C003,0000 - C003,000F I2C 1 +| C004,0000 - C004,0009 SCC (16550 UART) +| C005,0000 - C005,0124 Timers +| C006,0000 - C006,0058 GPIO0 +| C007,0000 - C007,0058 GPIO1 +| C008,0000 - C008,0058 GPIO2 +| C009,0000 - C009,0058 GPIO3 +| C00A,0000 - C00A,0058 GPIO4 +| C00B,0000 - C00B,000F I2C 2 +| C00C,0000 - C00C,0006 SCP +| C00D,0000 - C00D,0006 SSP +| A000,0000 - A0FF,FFFF SDRAM 16M +| 0000,0000 - 00FF,FFFF DRAM 16M ++----------------------------------------------------------------------------*/ +#define STB_FLASH_BASE_ADDRESS 0xFFE00000 +#define STB_FPGA_BASE_ADDRESS 0xF1440000 +#define STB_ENET_BASE_ADDRESS 0xF1400000 +#define STB_SICC_BASE_ADDRESS 0xC0000000 +#define STB_PPU_BASE_ADDR 0xC0010000 +#define STB_SC_BASE_ADDRESS 0xC0020000 +#define STB_I2C1_BASE_ADDRESS 0xC0030000 +#define STB_SCC_BASE_ADDRESS 0xC0040000 +#define STB_TIMERS_BASE_ADDRESS 0xC0050000 +#define STB_GPIO0_BASE_ADDRESS 0xC0060000 +#define STB_GPIO1_BASE_ADDRESS 0xC0070000 +#define STB_GPIO2_BASE_ADDRESS 0xC0080000 +#define STB_GPIO3_BASE_ADDRESS 0xC0090000 +#define STB_GPIO4_BASE_ADDRESS 0xC00A0000 +#define STB_I2C2_BASE_ADDRESS 0xC00B0000 +#define STB_SCP_BASE_ADDRESS 0xC00C0000 +#define STB_SSP_BASE_ADDRESS 0xC00D0000 +#define STB_SDRAM_BASE_ADDRESS 0xA0000000 +#endif + +/*----------------------------------------------------------------------------+ +| Other common defines. ++----------------------------------------------------------------------------*/ +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#endif /* _stb_h_ */ diff --git a/arch/ppc/boot/tree/Makefile b/arch/ppc/boot/tree/Makefile deleted file mode 100644 index 6f2498334a00..000000000000 --- a/arch/ppc/boot/tree/Makefile +++ /dev/null @@ -1,66 +0,0 @@ -# BK Id: SCCS/s.Makefile 1.7 06/15/01 13:16:10 paulus -# -# -# Module name: Makefile -# -# Description: -# Makefile for the IBM "tree" evaluation board Linux kernel -# boot loaders. -# -# -# Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu> -# -# PPC-405 modification -# Copyright 2000-2001 MontaVista Software Inc. -# Author: MontaVista Software, Inc. -# frank_rowand@mvista.com or source@mvista.com -# debbie_chu@mvista.com -# - -HOSTCFLAGS = -O -I$(TOPDIR)/include - -CC = $(CROSS_COMPILE)gcc -LD = $(CROSS_COMPILE)ld -OBJCOPY = $(CROSS_COMPILE)objcopy -OBJDUMP = $(CROSS_COMPILE)objdump - -GZIP = gzip -vf9 -RM = rm -f -MKEVIMG = ../utils/mkevimg -l -c -MKIRIMG = ../utils/mkirimg -CFLAGS += -I$(TOPDIR)/drivers/net -LD_ARGS = -e _start -T ld.script -Ttext 0x00200000 -Bstatic - -OBJS = ../common/crt0.o main.o misc.o irSect.o ../common/string.o \ - ../common/misc-common.o ../common/ns16550.o -LIBS = ../lib/zlib.a - -treeboot: $(OBJS) $(LIBS) ld.script - $(LD) -o $@ $(LD_ARGS) $(OBJS) $(LIBS) - -zImage: vmlinux.img - -zImage.initrd: vmlinux.initrd.img - -treeboot.image: treeboot - $(OBJCOPY) --add-section=image=../images/vmlinux.gz treeboot $@ - -treeboot.initrd: treeboot.image ramdisk.image.gz - $(OBJCOPY) --add-section=initrd=ramdisk.image.gz treeboot.image $@ - -vmlinux.img: treeboot.image - $(OBJDUMP) --syms treeboot.image | grep irSectStart > irSectStart.txt - $(MKIRIMG) treeboot.image treeboot.image.out irSectStart.txt - $(MKEVIMG) treeboot.image.out ../images/vmlinux.tree.img - $(RM) treeboot.image treeboot.image.out irSectStart.txt - -vmlinux.initrd.img: treeboot.initrd - $(OBJDUMP) --all-headers treeboot.initrd | grep irSectStart > irSectStart.txt - $(MKIRIMG) treeboot.initrd treeboot.initrd.out irSectStart.txt - $(MKEVIMG) treeboot.initrd.out ../images/vmlinux.tree.initrd.img - $(RM) treeboot.initrd treeboot.initrd.out irSectStart.txt - -clean: - rm -f treeboot treeboot.image treeboot.initrd irSectStart.txt vmlinux.* - -include $(TOPDIR)/Rules.make diff --git a/arch/ppc/boot/tree/irSect.c b/arch/ppc/boot/tree/irSect.c deleted file mode 100644 index 80ecca8b3f74..000000000000 --- a/arch/ppc/boot/tree/irSect.c +++ /dev/null @@ -1,39 +0,0 @@ -/* - * BK Id: SCCS/s.irSect.c 1.6 05/18/01 15:17:22 cort - */ -/* - * - * Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu> - * - * Module name: irSect.c - * - * Description: - * Defines variables to hold the absolute starting address and size - * of the Linux kernel "image" and the initial RAM disk "initrd" - * sections within the boot loader. - * - */ - -#include "irSect.h" - - -/* - * The order of globals below must not change. If more globals are added, - * you must change the script 'mkirimg' accordingly. - * - */ - -/* - * irSectStart must be at beginning of file - */ -unsigned int irSectStart = 0xdeadbeaf; - -unsigned int imageSect_start = 0; -unsigned int imageSect_size = 0; -unsigned int initrdSect_start = 0; -unsigned int initrdSect_size = 0; - -/* - * irSectEnd must be at end of file - */ -unsigned int irSectEnd = 0xdeadbeaf; diff --git a/arch/ppc/boot/tree/irSect.h b/arch/ppc/boot/tree/irSect.h deleted file mode 100644 index 849be573be3a..000000000000 --- a/arch/ppc/boot/tree/irSect.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * BK Id: SCCS/s.irSect.h 1.6 05/18/01 15:17:22 cort - */ -/* - * - * Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu> - * - * Module name: irSect.h - * - * Description: - * Defines variables to hold the absolute starting address and size - * of the Linux kernel "image" and the initial RAM disk "initrd" - * sections within the boot loader. - * - */ - -#ifndef __IRSECT_H__ -#define __IRSECT_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -extern unsigned int imageSect_start; -extern unsigned int imageSect_size; - -extern unsigned int initrdSect_start; -extern unsigned int initrdSect_size; - - -#ifdef __cplusplus -} -#endif - -#endif /* __IRSECT_H__ */ diff --git a/arch/ppc/boot/tree/ld.script b/arch/ppc/boot/tree/ld.script deleted file mode 100644 index 33317e773e22..000000000000 --- a/arch/ppc/boot/tree/ld.script +++ /dev/null @@ -1,69 +0,0 @@ -OUTPUT_ARCH(powerpc) -SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib); -/* Do we need any of these for elf? - __DYNAMIC = 0; */ -SECTIONS -{ - /* Read-only sections, merged into text segment: */ - . = + SIZEOF_HEADERS; - .interp : { *(.interp) } - .hash : { *(.hash) } - .dynsym : { *(.dynsym) } - .dynstr : { *(.dynstr) } - .rel.text : { *(.rel.text) } - .rela.text : { *(.rela.text) } - .rel.data : { *(.rel.data) } - .rela.data : { *(.rela.data) } - .rel.rodata : { *(.rel.rodata) } - .rela.rodata : { *(.rela.rodata) } - .rel.got : { *(.rel.got) } - .rela.got : { *(.rela.got) } - .rel.ctors : { *(.rel.ctors) } - .rela.ctors : { *(.rela.ctors) } - .rel.dtors : { *(.rel.dtors) } - .rela.dtors : { *(.rela.dtors) } - .rel.bss : { *(.rel.bss) } - .rela.bss : { *(.rela.bss) } - .rel.plt : { *(.rel.plt) } - .rela.plt : { *(.rela.plt) } - .init : { *(.init) } =0 - .plt : { *(.plt) } - .text : - { - *(.text) - *(.rodata) - *(.rodata.*) - *(.rodata1) - *(.got1) - } - .fini : { *(.fini) } =0 - .ctors : { *(.ctors) } - .dtors : { *(.dtors) } - _etext = .; - PROVIDE (etext = .); - /* Read-write section, merged into data segment: */ - . = (. + 0x0FFF) & 0xFFFFF000; - .data : - { - *(.data) - *(.data1) - *(.sdata) - *(.sdata2) - *(.got.plt) *(.got) - *(.dynamic) - CONSTRUCTORS - } - _edata = .; - PROVIDE (edata = .); - __bss_start = .; - .bss : - { - *(.sbss) *(.scommon) - *(.dynbss) - *(.bss) - *(COMMON) - } - _end = . ; - PROVIDE (end = .); -} - diff --git a/arch/ppc/boot/tree/main.c b/arch/ppc/boot/tree/main.c deleted file mode 100644 index f97e858011a2..000000000000 --- a/arch/ppc/boot/tree/main.c +++ /dev/null @@ -1,212 +0,0 @@ -/* - * BK Id: SCCS/s.main.c 1.9 06/15/01 13:16:10 paulus - */ -/* - * Copyright (c) 1997 Paul Mackerras <paulus@cs.anu.edu.au> - * Initial Power Macintosh COFF version. - * Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu> - * Modifications for an ELF-based IBM evaluation board version. - * Copyright 2000-2001 MontaVista Software Inc. - * PPC405GP modifications - * Author: MontaVista Software, Inc. - * frank_rowand@mvista.com or source@mvista.com - * debbie_chu@mvista.com - * - * Module name: main.c - * - * Description: - * This module does most of the real work for the boot loader. It - * checks the variables holding the absolute start address and size - * of the Linux kernel "image" and initial RAM disk "initrd" sections - * and if they are present, moves them to their "proper" locations. - * - * For the Linux kernel, "proper" is physical address 0x00000000. - * For the RAM disk, "proper" is the image's size below the top - * of physical memory. The Linux kernel may be in either raw - * binary form or compressed with GNU zip (aka gzip). - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - */ - -#include <linux/config.h> -#include <asm/ppc4xx.h> - -#include "nonstdio.h" -#include "irSect.h" -#if defined(CONFIG_SERIAL_CONSOLE) -#include "ns16550.h" -#endif /* CONFIG_SERIAL_CONSOLE */ - - -/* Preprocessor Defines */ - -/* - * Location of the IBM boot ROM function pointer address for retrieving - * the board information structure. - */ - -#define BOARD_INFO_VECTOR 0xFFFE0B50 - -/* - * Warning: the board_info doesn't contain valid data until get_board_info() - * gets called in start(). - */ -#define RAM_SIZE board_info.bi_memsize - -#define RAM_PBASE 0x00000000 -#define RAM_PEND (RAM_PBASE + RAM_SIZE) - -#define RAM_VBASE 0xC0000000 -#define RAM_VEND (RAM_VBASE + RAM_SIZE) - -#define RAM_START RAM_PBASE -#define RAM_END RAM_PEND -#define RAM_FREE (imageSect_start + imageSect_size + initrdSect_size) - -#define PROG_START RAM_START - - -/* Function Macros */ - -#define ALIGN_UP(x, align) (((x) + ((align) - 1)) & ~((align) - 1)) - -/* Global Variables */ - -/* Needed by zalloc and zfree for allocating memory */ - -char *avail_ram; /* Indicates start of RAM available for heap */ -char *end_avail; /* Indicates end of RAM available for heap */ - -/* Needed for serial I/O. -*/ -extern unsigned long *com_port; - -bd_t board_info; - -/* -** The bootrom may change bootrom_cmdline to point to a buffer in the -** bootrom. -*/ -char *bootrom_cmdline = ""; -char treeboot_bootrom_cmdline[512]; - -#ifdef CONFIG_CMDLINE -char *cmdline = CONFIG_CMDLINE; -#else -char *cmdline = ""; -#endif - -/* Function Prototypes */ - -extern void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp); - -void -kick_watchdog(void) -{ -#ifdef CONFIG_405GP - mtspr(SPRN_TSR, (TSR_ENW | TSR_WIS)); -#endif -} - -void start(void) -{ - void *options; - int ns, oh, i; - unsigned long sa, len; - void *dst; - unsigned char *im; - unsigned long initrd_start, initrd_size; - bd_t *(*get_board_info)(void) = - (bd_t *(*)(void))(*(unsigned long *)BOARD_INFO_VECTOR); - bd_t *bip = NULL; - - - com_port = (struct NS16550 *)serial_init(0); - -#ifdef CONFIG_405GP - /* turn off on-chip ethernet */ - /* This is to fix a problem with early walnut bootrom. */ - - { - /* Physical mapping of ethernet register space. */ - static struct ppc405_enet_regs *ppc405_enet_regp = - (struct ppc405_enet_regs *)PPC405_EM0_REG_ADDR; - - mtdcr(DCRN_MALCR, MALCR_MMSR); /* 1st reset MAL */ - - while (mfdcr(DCRN_MALCR) & MALCR_MMSR) {}; /* wait for the reset */ - - ppc405_enet_regp->em0mr0 = 0x20000000; /* then reset EMAC */ - } -#endif - - if ((bip = get_board_info()) != NULL) - memcpy(&board_info, bip, sizeof(bd_t)); - - /* Init RAM disk (initrd) section */ - - kick_watchdog(); - - if (initrdSect_start != 0 && (initrd_size = initrdSect_size) != 0) { - initrd_start = (RAM_END - initrd_size) & ~0xFFF; - - _printk("Initial RAM disk at 0x%08x (%u bytes)\n", - initrd_start, initrd_size); - - memcpy((char *)initrd_start, - (char *)(initrdSect_start), - initrdSect_size); - - end_avail = (char *)initrd_start; - } else { - initrd_start = initrd_size = 0; - end_avail = (char *)RAM_END; - } - - /* Linux kernel image section */ - - kick_watchdog(); - - im = (unsigned char *)(imageSect_start); - len = imageSect_size; - dst = (void *)PROG_START; - - /* Check for the gzip archive magic numbers */ - - if (im[0] == 0x1f && im[1] == 0x8b) { - - /* The gunzip routine needs everything nice and aligned */ - - void *cp = (void *)ALIGN_UP(RAM_FREE, 8); - avail_ram = (void *)(cp + ALIGN_UP(len, 8)); /* used by zalloc() */ - memcpy(cp, im, len); - - /* I'm not sure what the 0x200000 parameter is for, but it works. */ - /* It tells gzip the end of the area you wish to reserve, and it - * can use data past that point....unfortunately, this value - * isn't big enough (luck ran out). -- Dan - */ - - gunzip(dst, 0x400000, cp, (int *)&len); - } else { - memmove(dst, im, len); - } - - kick_watchdog(); - - flush_cache(dst, len); - - sa = (unsigned long)dst; - - (*(void (*)())sa)(&board_info, - initrd_start, - initrd_start + initrd_size, - cmdline, - cmdline + strlen(cmdline)); - - pause(); -} diff --git a/arch/ppc/boot/tree/misc.S b/arch/ppc/boot/tree/misc.S deleted file mode 100644 index 7d3f6ae885fb..000000000000 --- a/arch/ppc/boot/tree/misc.S +++ /dev/null @@ -1,43 +0,0 @@ -/* - * BK Id: SCCS/s.misc.S 1.7 05/18/01 06:20:29 patch - */ -/* - * Copyright (C) Paul Mackerras 1997. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ - -#include "../../kernel/ppc_asm.tmpl" - - .text - -/* - * Flush the dcache and invalidate the icache for a range of addresses. - * - * flush_cache(addr, len) - */ - .global flush_cache -flush_cache: - mfpvr r5 # Get processor version register - extrwi r5,r5,16,0 # Get the version bits - cmpwi cr0,r5,0x0020 # Is this a 403-based processor? - beq 1f # Yes, it is - li r5,32 # It is not a 403, set to 32 bytes - addi r4,r4,32-1 # len += line_size - 1 - srwi. r4,r4,5 # Convert from bytes to lines - b 2f -1: li r5,16 # It is a 403, set to 16 bytes - addi r4,r4,16-1 # len += line_size - 1 - srwi. r4,r4,4 # Convert from bytes to lines -2: mtctr r4 # Set-up the counter register - beqlr # If it is 0, we are done -3: dcbf r0,r3 # Flush and invalidate the data line - icbi r0,r3 # Invalidate the instruction line - add r3,r3,r5 # Move to the next line - bdnz 3b # Are we done yet? - sync - isync - blr # Return to the caller diff --git a/arch/ppc/boot/utils/Makefile b/arch/ppc/boot/utils/Makefile index 3f5f79a39887..c29bbe44a683 100644 --- a/arch/ppc/boot/utils/Makefile +++ b/arch/ppc/boot/utils/Makefile @@ -10,7 +10,8 @@ HOSTCFLAGS += -I$(TOPDIR)/arch/$(ARCH)/boot/include all: dummy # Simple programs with 1 file and no extra CFLAGS -UTILS = addnote hack-coff mkprep mksimage mknote piggyback mkpmon mkbugboot +UTILS = addnote hack-coff mkprep mknote mkbugboot mktree \ + addSystemMap addRamdDisk $(UTILS): $(HOSTCC) $(HOSTCFLAGS) -o $@ $@.c diff --git a/arch/ppc/boot/utils/addRamDisk.c b/arch/ppc/boot/utils/addRamDisk.c new file mode 100644 index 000000000000..92a09ebf7c12 --- /dev/null +++ b/arch/ppc/boot/utils/addRamDisk.c @@ -0,0 +1,203 @@ +#include <stdio.h> +#include <stdlib.h> +#include <netinet/in.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <string.h> + +#define ElfHeaderSize (64 * 1024) +#define ElfPages (ElfHeaderSize / 4096) +#define KERNELBASE (0xc0000000) + +void get4k(FILE *file, char *buf ) +{ + unsigned j; + unsigned num = fread(buf, 1, 4096, file); + for ( j=num; j<4096; ++j ) + buf[j] = 0; +} + +void put4k(FILE *file, char *buf ) +{ + fwrite(buf, 1, 4096, file); +} + +void death(const char *msg, FILE *fdesc, const char *fname) +{ + printf(msg); + fclose(fdesc); + unlink(fname); + exit(1); +} + +int main(int argc, char **argv) +{ + char inbuf[4096]; + FILE *ramDisk = NULL; + FILE *inputVmlinux = NULL; + FILE *outputVmlinux = NULL; + unsigned i = 0; + u_int32_t ramFileLen = 0; + u_int32_t ramLen = 0; + u_int32_t roundR = 0; + u_int32_t kernelLen = 0; + u_int32_t actualKernelLen = 0; + u_int32_t round = 0; + u_int32_t roundedKernelLen = 0; + u_int32_t ramStartOffs = 0; + u_int32_t ramPages = 0; + u_int32_t roundedKernelPages = 0; + u_int32_t hvReleaseData = 0; + u_int32_t eyeCatcher = 0xc8a5d9c4; + u_int32_t naca = 0; + u_int32_t xRamDisk = 0; + u_int32_t xRamDiskSize = 0; + if ( argc < 2 ) { + printf("Name of RAM disk file missing.\n"); + exit(1); + } + + if ( argc < 3 ) { + printf("Name of vmlinux file missing.\n"); + exit(1); + } + + if ( argc < 4 ) { + printf("Name of vmlinux output file missing.\n"); + exit(1); + } + + ramDisk = fopen(argv[1], "r"); + if ( ! ramDisk ) { + printf("RAM disk file \"%s\" failed to open.\n", argv[1]); + exit(1); + } + inputVmlinux = fopen(argv[2], "r"); + if ( ! inputVmlinux ) { + printf("vmlinux file \"%s\" failed to open.\n", argv[2]); + exit(1); + } + outputVmlinux = fopen(argv[3], "w+"); + if ( ! outputVmlinux ) { + printf("output vmlinux file \"%s\" failed to open.\n", argv[3]); + exit(1); + } + fseek(ramDisk, 0, SEEK_END); + ramFileLen = ftell(ramDisk); + fseek(ramDisk, 0, SEEK_SET); + printf("%s file size = %d\n", argv[1], ramFileLen); + + ramLen = ramFileLen; + + roundR = 4096 - (ramLen % 4096); + if ( roundR ) { + printf("Rounding RAM disk file up to a multiple of 4096, adding %d\n", roundR); + ramLen += roundR; + } + + printf("Rounded RAM disk size is %d\n", ramLen); + fseek(inputVmlinux, 0, SEEK_END); + kernelLen = ftell(inputVmlinux); + fseek(inputVmlinux, 0, SEEK_SET); + printf("kernel file size = %d\n", kernelLen); + if ( kernelLen == 0 ) { + printf("You must have a linux kernel specified as argv[2]\n"); + exit(1); + } + + actualKernelLen = kernelLen - ElfHeaderSize; + + printf("actual kernel length (minus ELF header) = %d\n", actualKernelLen); + + round = actualKernelLen % 4096; + roundedKernelLen = actualKernelLen; + if ( round ) + roundedKernelLen += (4096 - round); + + printf("actual kernel length rounded up to a 4k multiple = %d\n", roundedKernelLen); + + ramStartOffs = roundedKernelLen; + ramPages = ramLen / 4096; + + printf("RAM disk pages to copy = %d\n", ramPages); + + // Copy 64K ELF header + for (i=0; i<(ElfPages); ++i) { + get4k( inputVmlinux, inbuf ); + put4k( outputVmlinux, inbuf ); + } + + roundedKernelPages = roundedKernelLen / 4096; + + fseek(inputVmlinux, ElfHeaderSize, SEEK_SET); + + for ( i=0; i<roundedKernelPages; ++i ) { + get4k( inputVmlinux, inbuf ); + put4k( outputVmlinux, inbuf ); + } + + for ( i=0; i<ramPages; ++i ) { + get4k( ramDisk, inbuf ); + put4k( outputVmlinux, inbuf ); + } + + /* Close the input files */ + fclose(ramDisk); + fclose(inputVmlinux); + /* And flush the written output file */ + fflush(outputVmlinux); + + /* fseek to the hvReleaseData pointer */ + fseek(outputVmlinux, ElfHeaderSize + 0x24, SEEK_SET); + if (fread(&hvReleaseData, 4, 1, outputVmlinux) != 1) { + death("Could not read hvReleaseData pointer\n", outputVmlinux, argv[3]); + } + hvReleaseData = ntohl(hvReleaseData); /* Convert to native int */ + printf("hvReleaseData is at %08x\n", hvReleaseData); + + /* fseek to the hvReleaseData */ + fseek(outputVmlinux, ElfHeaderSize + hvReleaseData, SEEK_SET); + if (fread(inbuf, 0x40, 1, outputVmlinux) != 1) { + death("Could not read hvReleaseData\n", outputVmlinux, argv[3]); + } + /* Check hvReleaseData sanity */ + if (memcmp(inbuf, &eyeCatcher, 4) != 0) { + death("hvReleaseData is invalid\n", outputVmlinux, argv[3]); + } + /* Get the naca pointer */ + naca = ntohl(*((u_int32_t *) &inbuf[0x0c])) - KERNELBASE; + printf("naca is at %08x\n", naca); + + /* fseek to the naca */ + fseek(outputVmlinux, ElfHeaderSize + naca, SEEK_SET); + if (fread(inbuf, 0x18, 1, outputVmlinux) != 1) { + death("Could not read naca\n", outputVmlinux, argv[3]); + } + xRamDisk = ntohl(*((u_int32_t *) &inbuf[0x0c])); + xRamDiskSize = ntohl(*((u_int32_t *) &inbuf[0x14])); + /* Make sure a RAM disk isn't already present */ + if ((xRamDisk != 0) || (xRamDiskSize != 0)) { + death("RAM disk is already attached to this kernel\n", outputVmlinux, argv[3]); + } + /* Fill in the values */ + *((u_int32_t *) &inbuf[0x0c]) = htonl(ramStartOffs); + *((u_int32_t *) &inbuf[0x14]) = htonl(ramPages); + + /* Write out the new naca */ + fflush(outputVmlinux); + fseek(outputVmlinux, ElfHeaderSize + naca, SEEK_SET); + if (fwrite(inbuf, 0x18, 1, outputVmlinux) != 1) { + death("Could not write naca\n", outputVmlinux, argv[3]); + } + printf("RAM Disk of 0x%x pages size is attached to the kernel at offset 0x%08x\n", + ramPages, ramStartOffs); + + /* Done */ + fclose(outputVmlinux); + /* Set permission to executable */ + chmod(argv[3], S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH); + + return 0; +} + diff --git a/arch/ppc/boot/utils/addSystemMap.c b/arch/ppc/boot/utils/addSystemMap.c new file mode 100644 index 000000000000..8eaa7a09a310 --- /dev/null +++ b/arch/ppc/boot/utils/addSystemMap.c @@ -0,0 +1,186 @@ +#include <stdio.h> +#include <stdlib.h> +#include <byteswap.h> +#include <sys/types.h> +#include <sys/stat.h> + +void xlate( char * inb, char * trb, unsigned len ) +{ + unsigned i; + for ( i=0; i<len; ++i ) { + char c = *inb++; + char c1 = c >> 4; + char c2 = c & 0xf; + if ( c1 > 9 ) + c1 = c1 + 'A' - 10; + else + c1 = c1 + '0'; + if ( c2 > 9 ) + c2 = c2 + 'A' - 10; + else + c2 = c2 + '0'; + *trb++ = c1; + *trb++ = c2; + } + *trb = 0; +} + +#define ElfHeaderSize (64 * 1024) +#define ElfPages (ElfHeaderSize / 4096) +#define KERNELBASE (0xc0000000) + +void get4k( /*istream *inf*/FILE *file, char *buf ) +{ + unsigned j; + unsigned num = fread(buf, 1, 4096, file); + for ( j=num; j<4096; ++j ) + buf[j] = 0; +} + +void put4k( /*ostream *outf*/FILE *file, char *buf ) +{ + fwrite(buf, 1, 4096, file); +} + +int main(int argc, char **argv) +{ + char inbuf[4096]; + FILE *ramDisk = NULL; + FILE *inputVmlinux = NULL; + FILE *outputVmlinux = NULL; + unsigned i = 0; + unsigned long ramFileLen = 0; + unsigned long ramLen = 0; + unsigned long roundR = 0; + unsigned long kernelLen = 0; + unsigned long actualKernelLen = 0; + unsigned long round = 0; + unsigned long roundedKernelLen = 0; + unsigned long ramStartOffs = 0; + unsigned long ramPages = 0; + unsigned long roundedKernelPages = 0; + if ( argc < 2 ) { + printf("Name of System Map file missing.\n"); + exit(1); + } + + if ( argc < 3 ) { + printf("Name of vmlinux file missing.\n"); + exit(1); + } + + if ( argc < 4 ) { + printf("Name of vmlinux output file missing.\n"); + exit(1); + } + + ramDisk = fopen(argv[1], "r"); + if ( ! ramDisk ) { + printf("System Map file \"%s\" failed to open.\n", argv[1]); + exit(1); + } + inputVmlinux = fopen(argv[2], "r"); + if ( ! inputVmlinux ) { + printf("vmlinux file \"%s\" failed to open.\n", argv[2]); + exit(1); + } + outputVmlinux = fopen(argv[3], "w"); + if ( ! outputVmlinux ) { + printf("output vmlinux file \"%s\" failed to open.\n", argv[3]); + exit(1); + } + fseek(ramDisk, 0, SEEK_END); + ramFileLen = ftell(ramDisk); + fseek(ramDisk, 0, SEEK_SET); + printf("%s file size = %ld\n", argv[1], ramFileLen); + + ramLen = ramFileLen; + + roundR = 4096 - (ramLen % 4096); + if ( roundR ) { + printf("Rounding System Map file up to a multiple of 4096, adding %ld\n", roundR); + ramLen += roundR; + } + + printf("Rounded System Map size is %ld\n", ramLen); + fseek(inputVmlinux, 0, SEEK_END); + kernelLen = ftell(inputVmlinux); + fseek(inputVmlinux, 0, SEEK_SET); + printf("kernel file size = %ld\n", kernelLen); + if ( kernelLen == 0 ) { + printf("You must have a linux kernel specified as argv[2]\n"); + exit(1); + } + + actualKernelLen = kernelLen - ElfHeaderSize; + + printf("actual kernel length (minus ELF header) = %ld\n", actualKernelLen); + + round = actualKernelLen % 4096; + roundedKernelLen = actualKernelLen; + if ( round ) + roundedKernelLen += (4096 - round); + + printf("actual kernel length rounded up to a 4k multiple = %ld\n", roundedKernelLen); + + ramStartOffs = roundedKernelLen; + ramPages = ramLen / 4096; + + printf("System map pages to copy = %ld\n", ramPages); + + // Copy 64K ELF header + for (i=0; i<(ElfPages); ++i) { + get4k( inputVmlinux, inbuf ); + put4k( outputVmlinux, inbuf ); + } + + + + roundedKernelPages = roundedKernelLen / 4096; + + fseek(inputVmlinux, ElfHeaderSize, SEEK_SET); + + { + for ( i=0; i<roundedKernelPages; ++i ) { + get4k( inputVmlinux, inbuf ); + if ( i == 0 ) { + unsigned long * p; + printf("Storing embedded_sysmap_start at 0x3c\n"); + p = (unsigned long *)(inbuf + 0x3c); + +#if (BYTE_ORDER == __BIG_ENDIAN) + *p = ramStartOffs; +#else + *p = bswap_32(ramStartOffs); +#endif + + printf("Storing embedded_sysmap_end at 0x44\n"); + p = (unsigned long *)(inbuf + 0x44); +#if (BYTE_ORDER == __BIG_ENDIAN) + *p = ramStartOffs + ramFileLen; +#else + *p = bswap_32(ramStartOffs + ramFileLen); +#endif + } + put4k( outputVmlinux, inbuf ); + } + } + + { + for ( i=0; i<ramPages; ++i ) { + get4k( ramDisk, inbuf ); + put4k( outputVmlinux, inbuf ); + } + } + + + fclose(ramDisk); + fclose(inputVmlinux); + fclose(outputVmlinux); + /* Set permission to executable */ + chmod(argv[3], S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH); + + return 0; + +} + diff --git a/arch/ppc/boot/utils/mkbugboot.c b/arch/ppc/boot/utils/mkbugboot.c new file mode 100644 index 000000000000..27a744095d05 --- /dev/null +++ b/arch/ppc/boot/utils/mkbugboot.c @@ -0,0 +1,189 @@ +/* + * arch/ppc/pp3boot/mkbugboot.c + * + * Makes a Motorola PPCBUG ROM bootable image which can be flashed + * into one of the FLASH banks on a Motorola PowerPlus board. + * + * Author: Matt Porter <mporter@mvista.com> + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#define ELF_HEADER_SIZE 65536 + +#include <unistd.h> +#include <sys/stat.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <errno.h> +#include <fcntl.h> + +#ifdef __i386__ +#define cpu_to_be32(x) le32_to_cpu(x) +#define cpu_to_be16(x) le16_to_cpu(x) +#else +#define cpu_to_be32(x) (x) +#define cpu_to_be16(x) (x) +#endif + +#define cpu_to_le32(x) le32_to_cpu((x)) +unsigned long le32_to_cpu(unsigned long x) +{ + return (((x & 0x000000ffU) << 24) | + ((x & 0x0000ff00U) << 8) | + ((x & 0x00ff0000U) >> 8) | + ((x & 0xff000000U) >> 24)); +} + +#define cpu_to_le16(x) le16_to_cpu((x)) +unsigned short le16_to_cpu(unsigned short x) +{ + return (((x & 0x00ff) << 8) | + ((x & 0xff00) >> 8)); +} + +/* size of read buffer */ +#define SIZE 0x1000 + +/* typedef long int32_t; */ +typedef unsigned long uint32_t; +typedef unsigned short uint16_t; +typedef unsigned char uint8_t; + +/* PPCBUG ROM boot header */ +typedef struct bug_boot_header { + uint8_t magic_word[4]; /* "BOOT" */ + uint32_t entry_offset; /* Offset from top of header to code */ + uint32_t routine_length; /* Length of code */ + uint8_t routine_name[8]; /* Name of the boot code */ +} bug_boot_header_t; + +#define HEADER_SIZE sizeof(bug_boot_header_t) + +uint32_t copy_image(int32_t in_fd, int32_t out_fd) +{ + uint8_t buf[SIZE]; + int n; + uint32_t image_size = 0; + uint8_t zero = 0; + + lseek(in_fd, ELF_HEADER_SIZE, SEEK_SET); + + /* Copy an image while recording its size */ + while ( (n = read(in_fd, buf, SIZE)) > 0 ) + { + image_size = image_size + n; + write(out_fd, buf, n); + } + + /* BUG romboot requires that our size is divisible by 2 */ + /* align image to 2 byte boundary */ + if (image_size % 2) + { + image_size++; + write(out_fd, &zero, 1); + } + + return image_size; +} + +void write_bugboot_header(int32_t out_fd, uint32_t boot_size) +{ + uint8_t header_block[HEADER_SIZE]; + bug_boot_header_t *bbh = (bug_boot_header_t *)&header_block[0]; + + bzero(header_block, HEADER_SIZE); + + /* Fill in the PPCBUG ROM boot header */ + strncpy(bbh->magic_word, "BOOT", 4); /* PPCBUG magic word */ + bbh->entry_offset = cpu_to_be32(HEADER_SIZE); /* Entry address */ + bbh->routine_length= cpu_to_be32(HEADER_SIZE+boot_size+2); /* Routine length */ + strncpy(bbh->routine_name, "LINUXROM", 8); /* Routine name */ + + /* Output the header and bootloader to the file */ + write(out_fd, header_block, HEADER_SIZE); +} + +uint16_t calc_checksum(int32_t bug_fd) +{ + uint32_t checksum_var = 0; + uint8_t buf[2]; + int n; + + /* Checksum loop */ + while ( (n = read(bug_fd, buf, 2) ) ) + { + checksum_var = checksum_var + *(uint16_t *)buf; + + /* If we carry out, mask it and add one to the checksum */ + if (checksum_var >> 16) + checksum_var = (checksum_var & 0x0000ffff) + 1; + } + + return checksum_var; +} + +int main(int argc, char *argv[]) +{ + int32_t image_fd, bugboot_fd; + int argptr = 1; + uint32_t kernel_size = 0; + uint16_t checksum = 0; + uint8_t bugbootname[256]; + + if ( (argc != 3) ) + { + fprintf(stderr, "usage: %s <kernel_image> <bugboot>\n",argv[0]); + exit(-1); + } + + /* Get file args */ + + /* kernel image file */ + if ((image_fd = open( argv[argptr] , 0)) < 0) + exit(-1); + argptr++; + + /* bugboot file */ + if ( !strcmp( argv[argptr], "-" ) ) + bugboot_fd = 1; /* stdout */ + else + if ((bugboot_fd = creat( argv[argptr] , 0755)) < 0) + exit(-1); + else + strcpy(bugbootname, argv[argptr]); + argptr++; + + /* Set file position after ROM header block where zImage will be written */ + lseek(bugboot_fd, HEADER_SIZE, SEEK_SET); + + /* Copy kernel image into bugboot image */ + kernel_size = copy_image(image_fd, bugboot_fd); + close(image_fd); + + /* Set file position to beginning where header/romboot will be written */ + lseek(bugboot_fd, 0, SEEK_SET); + + /* Write out BUG header/romboot */ + write_bugboot_header(bugboot_fd, kernel_size); + + /* Close bugboot file */ + close(bugboot_fd); + + /* Reopen it as read/write */ + bugboot_fd = open(bugbootname, O_RDWR); + + /* Calculate checksum */ + checksum = calc_checksum(bugboot_fd); + + /* Write out the calculated checksum */ + write(bugboot_fd, &checksum, 2); + + return 0; +} diff --git a/arch/ppc/boot/utils/mkevimg b/arch/ppc/boot/utils/mkevimg deleted file mode 100644 index 589b18ebc663..000000000000 --- a/arch/ppc/boot/utils/mkevimg +++ /dev/null @@ -1,488 +0,0 @@ -#!/usr/bin/perl - -# -# Copyright (c) 1998-1999 TiVo, Inc. -# All rights reserved. -# -# Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu> -# Major syntactic and usability rework. -# -# Module name: mkevimg -# -# Description: -# Converts an ELF output file from the linker into the format used by -# the IBM evaluation board ROM Monitor to load programs from a host -# onto the evaluation board. The ELF file must be an otherwise execut- -# able file (with the text and data addresses bound at link time) and -# have space reserved after the entry point for the load information -# block: -# -# typedef struct boot_block { -# unsigned long magic; 0x0052504F -# unsigned long dest; Target address of the image -# unsigned long num_512blocks; Size, rounded-up, in 512 byte blocks -# unsigned long debug_flag; Run the debugger or image after load -# unsigned long entry_point; The image address to jump to after load -# unsigned long checksum; 32 bit checksum including header -# unsigned long reserved[2]; -# } boot_block_t; -# -# - -use File::Basename; -use Getopt::Std; - -# -# usage() -# -# Description: -# This routine prints out the proper command line usage for this program -# -# Input(s): -# status - Flag determining what usage information will be printed and what -# the exit status of the program will be after the information is -# printed. -# -# Output(s): -# N/A -# -# Returns: -# This subroutine does not return. -# - -sub usage { - my($status); - $status = $_[0]; - - printf("Usage: %s [-hlvV] <ELF input file> <Evaluation board output file>\n", - $program); - - if ($status != 0) { - printf("Try `%s -h' for more information.\n", $program); - } - - if ($status != 1) { - print(" -c Put checksum in load information block.\n"); - print(" -h Print out this message and exit.\n"); - print(" -l Linux mode; if present, copy 'image' and 'initrd' sections.\n"); - print(" -v Verbose. Print out lots of ELF information.\n"); - print(" -V Print out version information and exit.\n"); - } - - exit($status); -} - -# -# version() -# -# Description: -# This routine prints out program version information -# -# Input(s): -# N/A -# -# Output(s): -# N/A -# -# Returns: -# This subroutine does not return. -# - -sub version { - print("mkevimg Version 1.1.0\n"); - print("Copyright (c) 1998-1999 TiVo, Inc.\n"); - print("Copyright (c) 1999 Grant Erickson <grant\@lcse.umn.edu>\n"); - - exit (0); -} - -# -# file_check() -# -# Description: -# This routine checks an input file to ensure that it exists, is a -# regular file, and is readable. -# -# Input(s): -# file - Input file to be checked. -# -# Output(s): -# N/A -# -# Returns: -# 0 if the file exists, is a regular file, and is readable, otherwise -1. -# - -sub file_check { - my($file); - $file = $_[0]; - - if (!(-e $file)) { - printf("The file \"%s\" does not exist.\n", $file); - return (-1); - } elsif (!(-f $file)) { - printf("The file \"%s\" is not a regular file.\n", $file); - return (-1); - } elsif (!(-r $file)) { - printf("The file \"%s\" is not readable.\n", $file); - return (-1); - } - - return (0); -} - -# -# decode_options() -# -# Description: -# This routine steps through the command-line arguments, parsing out -# recognzied options. -# -# Input(s): -# N/A -# -# Output(s): -# N/A -# -# Returns: -# N/A -# - -sub decode_options { - - if (!getopts("chlvV")) { - usage(1); - } - - if ($opt_c) { - $do_checksum = 1; - } - - if ($opt_h) { - usage(0); - } - - if ($opt_l) { - $linux = 1; - } - - if ($opt_V) { - version(); - exit (0); - } - - if ($opt_v) { - $verbose = 1; - } - - if (!($ifile = shift(@ARGV))) { - usage(1); - } - - if (!($ofile = shift(@ARGV))) { - usage (1); - } - - if (file_check($ifile)) { - exit(1); - } - -} - -# -# ELF file and section header field numbers -# - -require '../utils/elf.pl'; - -# -# Main program body -# - -{ - $program = basename($0); - - decode_options(); - - open(ELF, "<$ifile") || die "Cannot open input file"; - - $ifilesize = (-s $ifile); - - if ($verbose) { - print("Output file: $ofile\n"); - print("Input file: $ifile, $ifilesize bytes.\n"); - } - - if (read(ELF, $ibuf, $ifilesize) != $ifilesize) { - print("Failed to read input file!\n"); - exit(1); - } - - # - # Parse ELF header - # - - @eh = unpack("a16n2N5n6", $ibuf); - - # - # Make sure this is actually a PowerPC ELF file. - # - - if (substr($eh[$e_ident], 0, 4) ne "\177ELF") { - printf("The file \"%s\" is not an ELF file.\n", $ifile); - exit (1); - } elsif ($eh[$e_machine] != 20) { - printf("The file \"%s\" is not a PowerPC ELF file.\n", $ifile); - exit (1); - } - - if ($verbose) { - print("File header:\n"); - printf(" Identifier: %s\n", $eh[$e_ident]); - printf(" Type: %d\n", $eh[$e_type]); - printf(" Machine: %d\n", $eh[$e_machine]); - printf(" Version: %d\n", $eh[$e_version]); - printf(" Entry point: 0x%08x\n", $eh[$e_entry]); - printf(" Program header offset: 0x%x\n", $eh[$e_phoff]); - printf(" Section header offset: 0x%x\n", $eh[$e_shoff]); - printf(" Flags: 0x%08x\n", $eh[$e_flags]); - printf(" Header size: %d\n", $eh[$e_ehsize]); - printf(" Program entry size: %d\n", $eh[$e_phentsize]); - printf(" Program table entries: %d\n", $eh[$e_phnum]); - printf(" Section header size: %d\n", $eh[$e_shentsize]); - printf(" Section table entries: %d\n", $eh[$e_shnum]); - printf(" String table section: %d\n", $eh[$e_shstrndx]); - } - - # - # Find the section header for the string table. - # - - $strtable_section_offset = $eh[$e_shoff] + - $eh[$e_shstrndx] * $eh[$e_shentsize]; - - if ($verbose) { - printf("String table section header offset: 0x%x\n", - $strtable_section_offset); - } - - # - # Find the start of the string table. - # - - @strh = unpack("N10", substr($ibuf, $strtable_section_offset, - $eh[$e_shentsize])); - - if ($verbose) { - printf("Section name strings start at: 0x%x, %d bytes.\n", - $strh[$sh_offset], $strh[$sh_size]); - } - - $names = substr($ibuf, $strh[$sh_offset], $strh[$sh_size]); - - # Grab each section header and find '.text' and '.bss' sections in - # particular. - - if ($verbose) { - print("Section headers:\n"); - print("Idx Name Size Address File off Algn\n"); - print("--- ------------------------ -------- -------- -------- ----\n"); - } - - $off = $eh[$e_shoff]; - - for($i = 0; $i < $eh[$e_shnum]; $i++, $off += $eh[$e_shentsize]) { - @sh = unpack("N10", substr($ibuf, $off, $eh[$e_shentsize])); - - # Take the first section name from the array returned by split. - - ($name) = split(/\000/, substr($names, $sh[$sh_name])); - - if ($verbose) { - printf("%3d %-24s %8x %08x %08x %4d\n", - $i, $name, $sh[$sh_size], $sh[$sh_addr], - $sh[$sh_offset], $sh[$sh_addralign]); - } - - # Attempt to find the .text and .bss sections - - if ($name =~ /^\.bss$/) { - ($bss_addr, $bss_offset, $bss_size) = - ($sh[$sh_addr], $sh[$sh_offset], $sh[$sh_size]); - - } elsif ($name =~ /^\.text$/) { - ($text_addr, $text_offset, $text_size) = - ($sh[$sh_addr], $sh[$sh_offset], $sh[$sh_size]); - - } elsif ($linux && ($name =~ /^\image$/)) { - $image_found = 1; - - ($image_addr, $image_offset, $image_size) = - ($sh[$sh_addr], $sh[$sh_offset], $sh[$sh_size]); - - } elsif ($linux && ($name =~ /^\initrd$/)) { - $initrd_found = 1; - - ($initrd_addr, $initrd_offset, $initrd_size) = - ($sh[$sh_addr], $sh[$sh_offset], $sh[$sh_size]); - - } - } - - printf("Text section - Address: 0x%08x, Size: 0x%08x\n", - $text_addr, $text_size); - printf("Bss section - Address: 0x%08x, Size: 0x%08x\n", - $bss_addr, $bss_size); - - if ($linux) { - if ($image_found) { - printf("Image section - Address: 0x%08x, Size: 0x%08x\n", - $image_addr, $image_size); - } - - if ($initrd_found) { - printf("Initrd section - Address: 0x%08x, Size: 0x%08x\n", - $initrd_addr, $initrd_size); - } - } - - # - # Open output file - # - - open(BOOT, ">$ofile") || die "Cannot open output file"; - - # - # Compute image size - # - - $output_size = $bss_offset - $text_offset + $bss_size; - - if ($linux && $image_found) { - $output_size += $image_size; - } - - if ($linux && $initrd_found) { - $output_size += $initrd_size; - } - - # - # Compute size with header - # - - $header = pack("H8N7", "0052504f", 0, 0, 0, 0, 0, 0, 0); - $num_blocks = ($output_size + length($header) + 511) / 512; - - # - # Write IBM PowerPC evaluation board boot_block_t header - # - - $header = pack("H8N7", "0052504f", $text_addr, $num_blocks, 0, - $text_addr, 0, 0, 0); - - - $bytes = length($header); - - if (($resid = syswrite(BOOT, $header, $bytes)) != $bytes) { - die("Could not write boot image header to output file."); - } - - printf("Entry point = 0x%08x\n", $text_addr); - printf("Image size = 0x%08x (%d bytes) (%d blocks).\n", - $output_size, $output_size, $num_blocks); - - # - # Write image starting after ELF and program headers and - # continuing to beginning of bss - # - - $bytes = $bss_offset - $text_offset + $bss_size; - - if (($resid = syswrite(BOOT, $ibuf, $bytes, $text_offset)) != $bytes) { - die("Could not write boot image to output file.\n"); - } - - # - # If configured, write out the image and initrd sections as well - # - - if ($linux) { - if ($image_found) { - $bytes = $image_size; - if (($resid = syswrite(BOOT, $ibuf, $bytes, $image_offset)) != $bytes) { - die("Could not write boot image to output file.\n"); - } - } - - if ($initrd_found) { - $bytes = $initrd_size; - if (($resid = syswrite(BOOT, $ibuf, $bytes, $initrd_offset)) != $bytes) { - die("Could not write boot image to output file.\n"); - } - } - } - - # - # Pad to a multiple of 512 bytes - # If the (size of the boot image mod 512) is between 509 and 511 bytes - # then the tftp to the Walnut fails. This may be fixed in more recent - # Walnut bootrom. - # - - $pad_size = 512 - ((length($header) + $output_size) % 512); - if ($pad_size == 512) { - $pad_size = 0; - } - - if ($pad_size != 0) { - - if ($verbose) { - print("Padding boot image by an additional $pad_size bytes.\n"); - } - - $pad_string = pack("H8","deadbeef") x 128; - - syswrite(BOOT, $pad_string, $pad_size) or - die "Could not pad boot image in output file.\n"; - - } - - # - # Compute 32 bit checksum over entire file. - # - - if ($do_checksum) { - - close(BOOT); - open(BOOT, "+<$ofile") || die "Cannot open output file"; - undef $/; - $temp = unpack("%32N*", <BOOT>); - # Solaris and PPC Linux return 0x80000000 for "-$temp" when $temp - # is negative. "~($temp - 1)" negates $temp properly. - $csum = ~($temp - 1); - printf("Checksum = 0x%08x\r\n", $csum); - - # - # Rewrite IBM PowerPC evaluation board boot_block_t header, - # this time with the checksum included - # - - $header = pack("H8N7", "0052504f", $text_addr, $num_blocks, 0, - $text_addr, $csum, 0, 0); - - seek(BOOT, 0, 0); - syswrite(BOOT, $header, length($header)) or - die("Could not write boot image header to output file."); - - } - - # - # Clean-up and leave - # - - close(BOOT); - - print("\nBoot image file \"$ofile\" built successfully.\n\n"); - - exit(0); -} diff --git a/arch/ppc/boot/utils/mkimage.wrapper b/arch/ppc/boot/utils/mkimage.wrapper new file mode 100755 index 000000000000..5483d9790ebe --- /dev/null +++ b/arch/ppc/boot/utils/mkimage.wrapper @@ -0,0 +1,16 @@ +#!/bin/bash + +# +# Build PPCBoot image when `mkimage' tool is available. +# + +MKIMAGE=$(type -path mkimage) + +if [ -z "${MKIMAGE}" ]; then + # Doesn't exist + echo '"mkimage" command not found - PPCBoot images will not be built' >&2 + exit 0; +fi + +# Call "mkimage" to create PPCBoot image +${MKIMAGE} "$@" diff --git a/arch/ppc/boot/utils/mkirimg b/arch/ppc/boot/utils/mkirimg deleted file mode 100644 index fa1b5bbb0a5a..000000000000 --- a/arch/ppc/boot/utils/mkirimg +++ /dev/null @@ -1,367 +0,0 @@ -#!/usr/bin/perl -# -# Copyright (c) 1998-1999 TiVo, Inc. -# Original ELF parsing code. -# -# Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu> -# Original code from 'mkevimg'. -# -# Module name: mkirimg -# -# Description: -# Reads an ELF file and assigns global variables 'imageSect_start', -# 'imageSect_size', 'initrdSect_start', and 'initrdSect_size' from -# the "image" and "initrd" section header information. It then -# rewrites the input ELF file with assigned globals to an output -# file. -# -# An input file, "irSectStart.txt" has the memory address of -# 'irSectStart'. The irSectStart memory address is used to find -# the global variables in the ".data" section of the ELF file. -# The 'irSectStart' and the above global variables are defined -# in "irSect.c". -# -# - -use File::Basename; -use Getopt::Std; - -# -# usage() -# -# Description: -# This routine prints out the proper command line usage for this program -# -# Input(s): -# status - Flag determining what usage information will be printed and what -# the exit status of the program will be after the information is -# printed. -# -# Output(s): -# N/A -# -# Returns: -# This subroutine does not return. -# - -sub usage { - my($status); - $status = $_[0]; - - printf("Usage: %s [-hvV] <ELF input file> <Evaluation board output file> <irSectStart.txt file>\n", - $program); - - if ($status != 0) { - printf("Try `%s -h' for more information.\n", $program); - } - - if ($status != 1) { - print(" -h Print out this message and exit.\n"); - print(" -v Verbose. Print out lots of ELF information.\n"); - print(" -V Print out version information and exit.\n"); - } - - exit($status); -} - -# -# version() -# -# Description: -# This routine prints out program version information -# -# Input(s): -# N/A -# -# Output(s): -# N/A -# -# Returns: -# This subroutine does not return. -# - -sub version { - print("mkirimg Version 1.1.0\n"); - print("Copyright (c) 1998-1999 TiVo, Inc.\n"); - print("Copyright (c) 1999 Grant Erickson <grant\@lcse.umn.edu>\n"); - - exit (0); -} - -# -# file_check() -# -# Description: -# This routine checks an input file to ensure that it exists, is a -# regular file, and is readable. -# -# Input(s): -# file - Input file to be checked. -# -# Output(s): -# N/A -# -# Returns: -# 0 if the file exists, is a regular file, and is readable, otherwise -1. -# - -sub file_check { - my($file); - $file = $_[0]; - - if (!(-e $file)) { - printf("The file \"%s\" does not exist.\n", $file); - return (-1); - } elsif (!(-f $file)) { - printf("The file \"%s\" is not a regular file.\n", $file); - return (-1); - } elsif (!(-r $file)) { - printf("The file \"%s\" is not readable.\n", $file); - return (-1); - } - - return (0); -} - -# -# decode_options() -# -# Description: -# This routine steps through the command-line arguments, parsing out -# recognzied options. -# -# Input(s): -# N/A -# -# Output(s): -# N/A -# -# Returns: -# N/A -# - -sub decode_options { - - if (!getopts("hvV")) { - usage(1); - } - - if ($opt_h) { - usage(0); - } - - if ($opt_V) { - version(); - exit (0); - } - - if ($opt_v) { - $verbose = 1; - } - - if (!($ElfFile = shift(@ARGV))) { - usage(1); - } - - if (!($OutputFile = shift(@ARGV))) { - usage (1); - } - - if (!($IrFile = shift(@ARGV))) { - usage (1); - } - - if (file_check($ElfFile)) { - exit(1); - } - - if (file_check($IrFile)) { - exit(1); - } -} - -# -# ELF file and section header field numbers -# - -require '../utils/elf.pl'; - -# -# Main program body -# - -{ - $program = basename($0); - decode_options(); - - open(ELF, "<$ElfFile") || die "Cannot open input file"; - open(OUTPUT, ">$OutputFile") || die "Cannot open output file"; - open(IR, "$IrFile") || die "Cannot open input file"; - - $ElfFilesize = (-s $ElfFile); - - if (read(ELF, $ibuf, $ElfFilesize) != $ElfFilesize) { - print("Failed to read ELF input file!\n"); - exit(1); - } - - if (read(IR, $irbuf, 8) != 8) { - print("Failed to read Ir input file!\n"); - exit(1); - } - - # - # Parse ELF header - # - - @eh = unpack("a16n2N5n6", $ibuf); - - # - # Make sure this is actually a PowerPC ELF file. - # - - if (substr($eh[$e_ident], 0, 4) ne "\177ELF") { - printf("The file \"%s\" is not an ELF file.\n", $ElfFile); - exit (1); - } elsif ($eh[$e_machine] != 20) { - printf("The file \"%s\" is not a PowerPC ELF file.\n", $ElfFile); - exit (1); - } - - # - # Find the section header for the string table. - # - - $strtable_section_offset = $eh[$e_shoff] + - - $eh[$e_shstrndx] * $eh[$e_shentsize]; - - if ($verbose) { - printf("String table section header offset: 0x%x\n", - $strtable_section_offset); - } - - # - # Find the start of the string table. - # - - @strh = unpack("N10", substr($ibuf, $strtable_section_offset, - $eh[$e_shentsize])); - - if ($verbose) { - printf("Section name strings start at: 0x%x, %d bytes.\n", - $strh[$sh_offset], $strh[$sh_size]); - } - - $names = substr($ibuf, $strh[$sh_offset], $strh[$sh_size]); - - # Grab each section header and find '.data', 'image', and - # 'initrd' sections in particular. - - $off = $eh[$e_shoff]; - $imageFound = 0; - $initrdFound = 0; - - for($i = 0; $i < $eh[$e_shnum]; $i++, $off += $eh[$e_shentsize]) { - @sh = unpack("N10", substr($ibuf, $off, $eh[$e_shentsize])); - - # Take the first section name from the array returned by split. - - ($name) = split(/\000/, substr($names, $sh[$sh_name])); - - # Attempt to find the .data, image, and initrd sections - - if ($name =~ /^\image$/) { - ($image_addr, $image_offset, $image_size) = - ($sh[$sh_addr], $sh[$sh_offset], $sh[$sh_size]); - $imageFound = 1; - - } elsif ($name =~ /^\initrd$/) { - ($initrd_addr, $initrd_offset, $initrd_size) = - ($sh[$sh_addr], $sh[$sh_offset], $sh[$sh_size]); - $initrdFound = 1; - - } elsif ($name =~ /^\.data$/) { - ($data_addr, $data_offset, $data_size) = - ($sh[$sh_addr], $sh[$sh_offset], $sh[$sh_size]); - - } elsif ($name =~ /^\.bss$/) { - ($bss_addr, $bss_offset, $bss_size) = - ($sh[$sh_addr], $sh[$sh_offset], $sh[$sh_size]); - - } - } - - if ($verbose) { - printf("Data section - Address: 0x%08x, Size: 0x%08x, File Offset 0x%08x\n", - $data_addr, $data_size, $data_offset); - printf("Bss section - Address: 0x%08x, Size: 0x%08x, File Offset 0x%08x\n", - $bss_addr, $bss_size, $bss_offset); - } - - if ($verbose) { - if ($imageFound) { - printf("Image section - Address: 0x%08x, Size: 0x%08x\n", - $image_addr, $image_size); - } else { - printf("Image section not found in file: $ElfFile\n"); - } - - if ($initrdFound) { - printf("Initrd section - Address: 0x%08x, Size: 0x%08x\n", - $initrd_addr, $initrd_size); - } else { - printf("Initrd section not found in file: $ElfFile\n"); - } - } - - # get file offset of irSectStart - - $irSectStartoffset = hex ($irbuf); - - if ($verbose) { - printf("irSectStartOffset Address: 0x%08x\n", $irSectStartoffset); - } - - # get the offset of global variables - - $initialOffset = ($irSectStartoffset - $data_addr) + $data_offset + 4; - - # write modified values to OUTPUT file - - syswrite(OUTPUT, $ibuf, $initialOffset); - - if ($imageFound) { - $testN = pack ("N2", $bss_addr + $bss_size, $image_size); - syswrite(OUTPUT, $testN, length($testN)); - printf("Updated symbol \"imageSect_start\" to 0x%08x\n", - $bss_addr + $bss_size); - printf("Updated symbol \"imageSect_size\" to 0x%08x\n", $image_size); - } else { - syswrite(OUTPUT, $ibuf, 8, $initialOffset); - } - - if ($initrdFound) { - $testN = pack ("N2", $bss_addr + $bss_size + $image_size, $initrd_size); - syswrite(OUTPUT, $testN, length($testN)); - printf("Updated symbol \"initrdSect_start\" to 0x%08x\n", - $bss_addr + $bss_size + $image_size); - printf("Updated symbol \"initrdSect_size\" to 0x%08x\n", $initrd_size); - } else { - syswrite(OUTPUT, $ibuf,8, $initialOffset + 8); - } - - syswrite(OUTPUT, $ibuf, $ElfFilesize - ($initialOffset + 16), - $initialOffset + 16); - - # - # Clean-up and leave - # - - close (ELF); - close (OUTPUT); - close (IR); - - exit (0); -} - diff --git a/arch/ppc/boot/utils/mksimage.c b/arch/ppc/boot/utils/mksimage.c deleted file mode 100644 index 721856a9b382..000000000000 --- a/arch/ppc/boot/utils/mksimage.c +++ /dev/null @@ -1,127 +0,0 @@ -/* - * BK Id: SCCS/s.mksimage.c 1.6 05/18/01 15:16:42 cort - */ -/* - * - * - * - * - */ - -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#include <stdarg.h> -#include <sys/types.h> -#include <fcntl.h> -#include <unistd.h> -#include <errno.h> - - -#define SIZE 1024 -#define BLOCK_ALIGN(x) (((x)+SIZE-1)&(~(SIZE-1))) - -static void -die(const char *fmt, ...) -{ - va_list args; - va_start(args, fmt); - vfprintf(stderr, fmt, args); - fputc('\n', stderr); - exit(1); -} - -static void -usage(void) -{ - printf("Usage: mkbinimg <bootstrap> <kernel> <ramdisk> -o <binary>\n"); - exit(1); -} - -static int -copy_blocks(int ifd, int ofd, unsigned long *offset, unsigned long *size) -{ - off_t cur; - int amt; - unsigned long len = 0; - char buffer[SIZE]; - - cur = lseek(ofd, 0, SEEK_CUR); - - if (cur % SIZE) { - cur = BLOCK_ALIGN(cur); - cur = lseek(ofd, cur, SEEK_SET); - } - - *offset = (unsigned long) cur; - while((amt = read(ifd, buffer, SIZE)) > 0) { - write(ofd, buffer, amt); - len += amt; - } - *size = len; - return 0; -} - - -int -main(int argc, char *argv[]) -{ - char *kernel, *loader, *rdimage = NULL; - unsigned long ld_off, kern_off, rd_off; - unsigned long ld_size, kern_size, rd_size; - int fd, ofd, len; - char buffer[500]; - - if (argc < 5 && !strcmp(argv[argc-2], "-o")) - usage(); - - if (argc > 5) - rdimage = argv[3]; - - kernel = argv[2]; - loader = argv[1]; - - ofd = open(argv[argc-1], (O_RDWR|O_CREAT), 0755); - if (ofd < 0) { - die("can't open %s: %s", argv[5], strerror(errno)); - } - - ld_off = kern_off = rd_off = 0; - ld_size = kern_size = rd_size = 0; - memset(buffer, 0, 500); - len = 0; - - fd = open(loader, O_RDONLY); - if (fd < 0) - die("can't open loader: %s", strerror(errno)); - - copy_blocks(fd, ofd, &ld_off, &ld_size); - len = sprintf(buffer, "bootloader: %x %x\n", ld_off, ld_size); - close(fd); - - fd = open(kernel, O_RDONLY); - if (fd < 0) - die("can't open kernel: %s", strerror(errno)); - - copy_blocks(fd, ofd, &kern_off, &kern_size); - len += sprintf(buffer+len, "zimage: %x %x\n", kern_off, kern_size); - close(fd); - - if (rdimage) { - fd = open(rdimage, O_RDONLY); - if (fd < 0) - die("can't get ramdisk: %s", strerror(errno)); - - copy_blocks(fd, ofd, &rd_off, &rd_size); - close(fd); - } - - len += sprintf(buffer+len, "initrd: %x %x", rd_off, rd_size); - - close(ofd); - - printf("%s\n", buffer); - - return 0; -} - diff --git a/arch/ppc/boot/utils/mktree.c b/arch/ppc/boot/utils/mktree.c new file mode 100644 index 000000000000..3b5ae6c3dbad --- /dev/null +++ b/arch/ppc/boot/utils/mktree.c @@ -0,0 +1,149 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + * + * Makes a tree bootable image for IBM Evaluation boards. + * Basically, just take a zImage, skip the ELF header, and stuff + * a 32 byte header on the front. + * + * We use htonl, which is a network macro, to make sure we're doing + * The Right Thing on an LE machine. It's non-obvious, but it should + * work on anything BSD'ish. + */ + +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/stat.h> +#include <unistd.h> +#include <netinet/in.h> + +/* This gets tacked on the front of the image. There are also a few + * bytes allocated after the _start label used by the boot rom (see + * head.S for details). + */ +typedef struct boot_block { + unsigned long bb_magic; /* 0x0052504F */ + unsigned long bb_dest; /* Target address of the image */ + unsigned long bb_num_512blocks; /* Size, rounded-up, in 512 byte blks */ + unsigned long bb_debug_flag; /* Run debugger or image after load */ + unsigned long bb_entry_point; /* The image address to start */ + unsigned long bb_checksum; /* 32 bit checksum including header */ + unsigned long reserved[2]; +} boot_block_t; + +#define IMGBLK 512 +char tmpbuf[IMGBLK]; + +int main(int argc, char *argv[]) +{ + int in_fd, out_fd; + int nblks, i; + uint cksum, *cp; + struct stat st; + boot_block_t bt; + + if (argc < 3) { + fprintf(stderr, "usage: %s <zImage-file> <boot-image> [entry-point]\n",argv[0]); + exit(1); + } + + if (stat(argv[1], &st) < 0) { + perror("stat"); + exit(2); + } + + nblks = (st.st_size + IMGBLK) / IMGBLK; + + bt.bb_magic = htonl(0x0052504F); + + /* If we have the optional entry point parameter, use it */ + if (argc == 4) + bt.bb_dest = bt.bb_entry_point = htonl(strtoul(argv[3], NULL, 0)); + else + bt.bb_dest = bt.bb_entry_point = htonl(0x500000); + + /* We know these from the linker command. + * ...and then move it up into memory a little more so the + * relocation can happen. + */ + bt.bb_num_512blocks = htonl(nblks); + bt.bb_debug_flag = 0; + + bt.bb_checksum = 0; + + /* To be neat and tidy :-). + */ + bt.reserved[0] = 0; + bt.reserved[1] = 0; + + if ((in_fd = open(argv[1], O_RDONLY)) < 0) { + perror("zImage open"); + exit(3); + } + + if ((out_fd = open(argv[2], (O_RDWR | O_CREAT | O_TRUNC), 0666)) < 0) { + perror("bootfile open"); + exit(3); + } + + cksum = 0; + cp = (uint *)&bt; + for (i=0; i<sizeof(bt)/sizeof(uint); i++) + cksum += *cp++; + + /* Assume zImage is an ELF file, and skip the 64K header. + */ + if (read(in_fd, tmpbuf, IMGBLK) != IMGBLK) { + fprintf(stderr, "%s is too small to be an ELF image\n", + argv[1]); + exit(4); + } + + if ((*(uint *)tmpbuf) != htonl(0x7f454c46)) { + fprintf(stderr, "%s is not an ELF image\n", argv[1]); + exit(4); + } + + if (lseek(in_fd, (64 * 1024), SEEK_SET) < 0) { + fprintf(stderr, "%s failed to seek in ELF image\n", argv[1]); + exit(4); + } + + nblks -= (64 * 1024) / IMGBLK; + + /* And away we go...... + */ + if (write(out_fd, &bt, sizeof(bt)) != sizeof(bt)) { + perror("boot-image write"); + exit(5); + } + + while (nblks-- > 0) { + if (read(in_fd, tmpbuf, IMGBLK) < 0) { + perror("zImage read"); + exit(5); + } + cp = (uint *)tmpbuf; + for (i=0; i<sizeof(tmpbuf)/sizeof(uint); i++) + cksum += *cp++; + if (write(out_fd, tmpbuf, sizeof(tmpbuf)) != sizeof(tmpbuf)) { + perror("boot-image write"); + exit(5); + } + } + + /* rewrite the header with the computed checksum. + */ + bt.bb_checksum = htonl(cksum); + if (lseek(out_fd, 0, SEEK_SET) < 0) { + perror("rewrite seek"); + exit(1); + } + if (write(out_fd, &bt, sizeof(bt)) != sizeof(bt)) { + perror("boot-image rewrite"); + exit(1); + } + + exit(0); +} diff --git a/arch/ppc/boot/utils/offset b/arch/ppc/boot/utils/offset deleted file mode 100644 index 52a1b5546e6f..000000000000 --- a/arch/ppc/boot/utils/offset +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/bash - -OFFSET=`$1 -h $2 | grep $3 | grep -v zvmlinux| awk '{print $6}'` -echo "0x"$OFFSET diff --git a/arch/ppc/boot/utils/piggyback.c b/arch/ppc/boot/utils/piggyback.c deleted file mode 100644 index 6edfbaaa092e..000000000000 --- a/arch/ppc/boot/utils/piggyback.c +++ /dev/null @@ -1,69 +0,0 @@ -/* - * BK Id: SCCS/s.piggyback.c 1.7 05/18/01 15:17:23 cort - */ -#include <stdio.h> -#include <unistd.h> - -extern long ce_exec_config[]; - -int main(int argc, char *argv[]) -{ - int i, cnt, pos, len; - unsigned int cksum, val; - unsigned char *lp; - unsigned char buf[8192]; - if (argc != 2) - { - fprintf(stderr, "usage: %s name <in-file >out-file\n", - argv[0]); - exit(1); - } - fprintf(stdout, "#\n"); - fprintf(stdout, "# Miscellaneous data structures:\n"); - fprintf(stdout, "# WARNING - this file is automatically generated!\n"); - fprintf(stdout, "#\n"); - fprintf(stdout, "\n"); - fprintf(stdout, "\t.data\n"); - fprintf(stdout, "\t.globl %s_data\n", argv[1]); - fprintf(stdout, "%s_data:\n", argv[1]); - pos = 0; - cksum = 0; - while ((len = read(0, buf, sizeof(buf))) > 0) - { - cnt = 0; - lp = (unsigned char *)buf; - len = (len + 3) & ~3; /* Round up to longwords */ - for (i = 0; i < len; i += 4) - { - if (cnt == 0) - { - fprintf(stdout, "\t.long\t"); - } - fprintf(stdout, "0x%02X%02X%02X%02X", lp[0], lp[1], lp[2], lp[3]); - val = *(unsigned long *)lp; - cksum ^= val; - lp += 4; - if (++cnt == 4) - { - cnt = 0; - fprintf(stdout, " # %x \n", pos+i-12); - fflush(stdout); - } else - { - fprintf(stdout, ","); - } - } - if (cnt) - { - fprintf(stdout, "0\n"); - } - pos += len; - } - fprintf(stdout, "\t.globl %s_len\n", argv[1]); - fprintf(stdout, "%s_len:\t.long\t0x%x\n", argv[1], pos); - fflush(stdout); - fclose(stdout); - fprintf(stderr, "cksum = %x\n", cksum); - exit(0); -} - diff --git a/arch/ppc/boot/utils/sioffset b/arch/ppc/boot/utils/sioffset deleted file mode 100644 index b5245be6c7b1..000000000000 --- a/arch/ppc/boot/utils/sioffset +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/bash - -OFFSET=`grep $1 sImage.map | awk '{print $2}'` -echo "0x"$OFFSET diff --git a/arch/ppc/boot/utils/sisize b/arch/ppc/boot/utils/sisize deleted file mode 100644 index 7e8180125dd4..000000000000 --- a/arch/ppc/boot/utils/sisize +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/bash - -OFFSET=`grep $1 sImage.map | awk '{print $3}'` -echo "0x"$OFFSET diff --git a/arch/ppc/boot/utils/size b/arch/ppc/boot/utils/size deleted file mode 100644 index 6c48f8d1468d..000000000000 --- a/arch/ppc/boot/utils/size +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/bash - -OFFSET=`$1 -h $2 | grep $3 | grep -v zvmlinux | awk '{print $3}'` -echo "0x"$OFFSET diff --git a/arch/ppc/config.in b/arch/ppc/config.in index 3430d8737c7c..647944799449 100644 --- a/arch/ppc/config.in +++ b/arch/ppc/config.in @@ -1,4 +1,4 @@ -# BK Id: SCCS/s.config.in 1.45 11/08/01 07:57:40 paulus +# BK Id: %F% %I% %G% %U% %#% # # For a description of the syntax of this configuration file, # see Documentation/kbuild/config-language.txt. @@ -20,20 +20,23 @@ choice 'Processor Type' \ "6xx/7xx/74xx/8260 CONFIG_6xx \ 4xx CONFIG_4xx \ POWER3 CONFIG_POWER3 \ - POWER4 CONFIG_POWER4 \ - 8xx CONFIG_8xx" 6xx + 8xx CONFIG_8xx \ + iSeries CONFIG_PPC_ISERIES" 6xx if [ "$CONFIG_6xx" = "y" ]; then bool 'MPC8260 CPM Support' CONFIG_8260 fi -if [ "$CONFIG_POWER3" = "y" -o "$CONFIG_POWER4" = "y" ]; then +if [ "$CONFIG_POWER3" = "y" ]; then define_bool CONFIG_PPC64BRIDGE y define_bool CONFIG_ALL_PPC y fi -if [ "$CONFIG_6xx" = "y" -o "$CONFIG_POWER3" = "y" -o \ - "$CONFIG_POWER4" = "y" ]; then +if [ "$CONFIG_PPC_ISERIES" = "y" ]; then + define_bool CONFIG_PPC64BRIDGE y +fi + +if [ "$CONFIG_6xx" = "y" -o "$CONFIG_POWER3" = "y" ]; then define_bool CONFIG_PPC_STD_MMU y else define_bool CONFIG_PPC_STD_MMU n @@ -41,17 +44,30 @@ fi if [ "$CONFIG_8260" = "y" ]; then define_bool CONFIG_SERIAL_CONSOLE y - bool 'Support for EST8260' CONFIG_EST8260 + choice 'Machine Type' \ + "EST8260 CONFIG_EST8260 \ + SBS8260 CONFIG_SBS8260 \ + RPXSUPER CONFIG_RPX6 \ + TQM8260 CONFIG_TQM8260 \ + Willow CONFIG_WILLOW" Willow fi if [ "$CONFIG_4xx" = "y" ]; then choice 'Machine Type' \ - "Oak CONFIG_OAK \ - Walnut CONFIG_WALNUT" Oak + "Ash CONFIG_ASH \ + Ceder CONFIG_CEDER \ + CPCI405 CONFIG_CPCI405 \ + EP405 CONFIG_EP405 \ + Oak CONFIG_OAK \ + Redwood-4 CONFIG_REDWOOD_4 \ + Redwood-5 CONFIG_REDWOOD_5 \ + Tivo CONFIG_TIVO \ + Walnut CONFIG_WALNUT" Walnut fi if [ "$CONFIG_8xx" = "y" ]; then define_bool CONFIG_SERIAL_CONSOLE y + define_bool CONFIG_NOT_COHERENT_CACHE y choice 'Machine Type' \ "RPX-Lite CONFIG_RPXLITE \ @@ -63,11 +79,16 @@ if [ "$CONFIG_8xx" = "y" ]; then TQM855L CONFIG_TQM855L \ TQM860L CONFIG_TQM860L \ FPS850L CONFIG_FPS850L \ - TQM860 CONFIG_TQM860 \ SPD823TS CONFIG_SPD823TS \ IVMS8 CONFIG_IVMS8 \ IVML24 CONFIG_IVML24 \ SM850 CONFIG_SM850 \ + HERMES CONFIG_HERMES_PRO \ + IP860 CONFIG_IP860 \ + LWMON CONFIG_LWMON \ + PCU_E CONFIG_PCU_E \ + CCM CONFIG_CCM \ + LANTEC CONFIG_LANTEC \ MBX CONFIG_MBX \ WinCept CONFIG_WINCEPT" RPX-Lite @@ -84,8 +105,60 @@ fi if [ "$CONFIG_6xx" = "y" -a "$CONFIG_8260" = "n" ]; then choice 'Machine Type' \ "CHRP/PowerMac/PReP CONFIG_ALL_PPC \ - Amiga-APUS CONFIG_APUS \ - Synergy-Gemini CONFIG_GEMINI" CHRP/PowerMac/PReP + Amiga-APUS CONFIG_APUS \ + Cogent-Willow CONFIG_WILLOW \ + Force-PowerCore CONFIG_PCORE \ + Force-PowerPMC250 CONFIG_POWERPMC250 \ + Galileo-EV-64260-BP CONFIG_EV64260 \ + IBM-Spruce CONFIG_SPRUCE \ + MEN-F1 CONFIG_MENF1 \ + Motorola-LoPEC CONFIG_LOPEC \ + Motorola-MCPN765 CONFIG_MCPN765 \ + Motorola-MVME5100 CONFIG_MVME5100 \ + Motorola-PowerPlus CONFIG_PPLUS \ + Motorola-PrPMC750 CONFIG_PRPMC750 \ + Motorola-PrPMC800 CONFIG_PRPMC800 \ + Motorola-Sandpoint CONFIG_SANDPOINT \ + SBS-Adirondack CONFIG_ADIR \ + SBS-K2 CONFIG_K2 \ + Synergy-Gemini CONFIG_GEMINI \ + Zynx-ZX4500 CONFIG_ZX4500" CHRP/PowerMac/PReP +fi + +if [ "$CONFIG_PCORE" = "y" \ + -o "$CONFIG_POWERPMC250" = "y" ]; then + define_bool CONFIG_FORCE y +fi + +if [ "$CONFIG_FORCE" = "y" \ + -o "$CONFIG_MENF1" = "y" \ + -o "$CONFIG_SANDPOINT" = "y" \ + -o "$CONFIG_ZX4500" = "y" ]; then + bool 'Enable MPC10x store gathering' CONFIG_MPC10X_STORE_GATHERING +fi + +if [ "$CONFIG_EV64260" = "y" ]; then + define_bool CONFIG_GT64260 y + define_int CONFIG_SERIAL_CONSOLE_BAUD 115200 +fi + +if [ "$CONFIG_K2" = "y" ]; then + bool 'Enable CPC710 data gathering' CONFIG_CPC710_DATA_GATHERING +fi + +if [ "$CONFIG_MVME5100" = "y" ]; then + bool 'MVME5100 configured with an IPMC761' CONFIG_MVME5100_IPMC761_PRESENT +fi + +if [ "$CONFIG_SANDPOINT" = "y" ]; then + bool 'Sandpoint X3' CONFIG_SANDPOINT_X3 + if [ "$CONFIG_SANDPOINT_X3" = "y" ]; then + define_bool CONFIG_EPIC_SERIAL_MODE y + fi +fi + +if [ "$CONFIG_SPRUCE" = "y" ]; then + bool 'Spruce baud clock support' CONFIG_SPRUCE_BAUD_33M fi if [ "$CONFIG_PPC_STD_MMU" != "y" ]; then @@ -110,14 +183,116 @@ if [ "$CONFIG_4xx" = "y" -o "$CONFIG_8xx" = "y" ]; then bool 'Math emulation' CONFIG_MATH_EMULATION fi +if [ "$CONFIG_4xx" = "y" ]; then +# It's often necessary to know the specific 4xx processor type. +# Fortunately, it is impled (so far) from the board type, so we +# don't need to ask more redundant questions. + if [ "$CONFIG_ASH" = "y" ]; then + define_bool CONFIG_NP405H y + define_bool CONFIG_TREEBOOT y + define_bool CONFIG_IBM405_ERR77 y + define_bool CONFIG_IBM_OCP y + fi + if [ "$CONFIG_CEDER" = "y" ]; then + define_bool CONFIG_NP405L y + define_bool CONFIG_BIOS_FIXUP y + define_bool CONFIG_TREEBOOT y + define_bool CONFIG_IBM405_ERR77 y + define_bool CONFIG_IBM_OCP y + fi + if [ "$CONFIG_CPCI405" = "y" ]; then + define_bool CONFIG_405GP y + define_bool CONFIG_IBM405_ERR77 y + define_bool CONFIG_IBM_OCP y + fi + if [ "$CONFIG_EP405" = "y" ]; then + define_bool CONFIG_405GP y + define_bool CONFIG_BIOS_FIXUP y + define_bool CONFIG_EMBEDDEDBOOT y + define_bool CONFIG_IBM405_ERR77 y + define_bool CONFIG_IBM_OCP y + fi + if [ "$CONFIG_OAK" = "y" -o "$CONFIG_TIVO" = "y" ]; then + define_bool CONFIG_403GCX y + define_bool CONFIG_TREEBOOT y + fi + if [ "$CONFIG_REDWOOD_4" = "y" ]; then + define_bool CONFIG_STB03xxx y + define_bool CONFIG_TREEBOOT y + define_bool CONFIG_IBM405_ERR77 y + define_bool CONFIG_IBM_OCP y + fi + if [ "$CONFIG_REDWOOD_5" = "y" ]; then + define_bool CONFIG_STB03xxx y + define_bool CONFIG_TREEBOOT y + define_bool CONFIG_IBM405_ERR77 y + define_bool CONFIG_IBM_OCP y + fi + if [ "$CONFIG_WALNUT" = "y" ]; then + define_bool CONFIG_405GP y + define_bool CONFIG_BIOS_FIXUP y + define_bool CONFIG_TREEBOOT y + define_bool CONFIG_IBM405_ERR77 y + define_bool CONFIG_IBM_OCP y + fi + + bool 'Blue Logic DMA' CONFIG_405_DMA + dep_bool 'Power Management support (experimental)' CONFIG_PM $CONFIG_EXPERIMENTAL + + if [ "$CONFIG_4xx" = "y" ]; then + choice 'TTYS0 device and default console' \ + "UART0 CONFIG_UART0_TTYS0 \ + UART1 CONFIG_UART0_TTYS1" UART0 + fi + + define_bool CONFIG_IBM405_ERR51 y + define_bool CONFIG_NOT_COHERENT_CACHE y +fi + +if [ "$CONFIG_8xx" = "y" -o "$CONFIG_8260" = "y" ]; then + define_bool CONFIG_EMBEDDEDBOOT y +fi endmenu mainmenu_option next_comment comment 'General setup' -bool 'High memory support (experimental)' CONFIG_HIGHMEM +bool 'Prompt for advanced kernel configuration options' CONFIG_ADVANCED_OPTIONS +bool 'High memory support' CONFIG_HIGHMEM +if [ "$CONFIG_ADVANCED_OPTIONS" = "y" ]; then + if [ "$CONFIG_HIGHMEM" = "y" ]; then + bool " Set high memory pool address" CONFIG_HIGHMEM_START_BOOL + if [ "$CONFIG_HIGHMEM_START_BOOL" = "y" ]; then + hex " Virtual start address of high memory pool" CONFIG_HIGHMEM_START 0xfe000000 + fi + bool " Set maximum low memory" CONFIG_LOWMEM_SIZE_BOOL + if [ "$CONFIG_LOWMEM_SIZE_BOOL" = "y" ]; then + hex " Maximum low memory size (in bytes)" CONFIG_LOWMEM_SIZE 0x20000000 + fi + fi + + bool "Set custom kernel base address" CONFIG_KERNEL_START_BOOL + if [ "$CONFIG_KERNEL_START_BOOL" = "y" ]; then + hex " Virtual address of kernel base" CONFIG_KERNEL_START 0xc0000000 + fi + bool "Set custom user task size" CONFIG_TASK_SIZE_BOOL + if [ "$CONFIG_TASK_SIZE_BOOL" = "y" ]; then + hex " Size of user task space" CONFIG_TASK_SIZE 0x80000000 + fi + if [ "$CONFIG_8xx" = "y" ]; then + bool "Pinned Kernel TLBs (860 ONLY)" CONFIG_PIN_TLB + fi + if [ "$CONFIG_4xx" = "y" ]; then + bool "Pinned Kernel TLBs" CONFIG_PIN_TLB + fi + if [ "$CONFIG_ALL_PPC" = "n" ]; then + bool "Set the boot link/load address" CONFIG_BOOT_LOAD_BOOL + if [ "$CONFIG_BOOT_LOAD_BOOL" = "y" ]; then + hex " Link/load address for booting" CONFIG_BOOT_LOAD 0x00400000 + fi + fi +fi -define_bool CONFIG_ISA n define_bool CONFIG_EISA n define_bool CONFIG_SBUS n @@ -125,7 +300,8 @@ define_bool CONFIG_SBUS n define_bool CONFIG_MCA n if [ "$CONFIG_4xx" = "y" -o "$CONFIG_8260" = "y" ]; then - define_bool CONFIG_PCI n + bool "Enable PCI" CONFIG_PCI + bool 'PC PS/2 style Keyboard' CONFIG_PC_KEYBOARD else if [ "$CONFIG_8xx" = "y" ]; then bool 'QSpan PCI' CONFIG_PCI_QSPAN @@ -135,11 +311,22 @@ else bool 'PCI for Permedia2' CONFIG_PCI_PERMEDIA define_bool CONFIG_PCI $CONFIG_PCI_PERMEDIA else - define_bool CONFIG_PCI y + if [ "$CONFIG_PPC_ISERIES" = "y" ]; then + bool "IBM iSeries Native I/O Support" CONFIG_PCI_ISERIES + define_bool CONFIG_PCI $CONFIG_PCI_ISERIES + else + define_bool CONFIG_PCI y + fi fi fi fi +if [ "$CONFIG_ALL_PPC" = "y" ]; then + bool 'Support for ISA-bus hardware' CONFIG_ISA +else + define_bool CONFIG_ISA n +fi + # only elf supported, a.out is not -- Cort if [ "$CONFIG_PROC_FS" = "y" ]; then define_bool CONFIG_KCORE_ELF y @@ -160,7 +347,7 @@ fi source drivers/parport/Config.in -if [ "$CONFIG_4xx" != "y" ]; then +if [ "$CONFIG_PPC_ISERIES" != "y" ]; then if [ "$CONFIG_APUS" != "y" ]; then tristate 'Support for /dev/rtc' CONFIG_PPC_RTC else @@ -175,7 +362,6 @@ fi if [ "$CONFIG_ALL_PPC" = "y" ]; then bool 'Support for Open Firmware device tree in /proc' CONFIG_PROC_DEVICETREE bool 'Support for RTAS (RunTime Abstraction Services) in /proc' CONFIG_PPC_RTAS - bool 'Support for early boot text console (BootX or OpenFirmware only)' CONFIG_BOOTX_TEXT bool 'Support for PReP Residual Data' CONFIG_PREP_RESIDUAL fi @@ -251,8 +437,12 @@ if [ "$CONFIG_SCSI" != "n" ]; then fi endmenu +source drivers/message/fusion/Config.in + source drivers/ieee1394/Config.in +source drivers/message/i2o/Config.in + if [ "$CONFIG_NET" = "y" ]; then mainmenu_option next_comment comment 'Network device support' @@ -300,6 +490,33 @@ if [ "$CONFIG_FB" = "y" -a "$CONFIG_ALL_PPC" = "y" ]; then fi endmenu + +if [ "$CONFIG_PPC_ISERIES" = "y" ]; then + mainmenu_option next_comment + comment 'iSeries device drivers' + tristate 'iSeries Virtual Console Support' CONFIG_VIOCONS + tristate 'iSeries Virtual I/O disk support' CONFIG_VIODASD + if [ "$CONFIG_VIODASD" = "y" -o "$CONFIG_VIODASD" = "m" ]; then + bool 'iSeries Virtual disk IDE emulation' CONFIG_VIODASD_IDE + fi + tristate 'iSeries Virtual I/O CD support' CONFIG_VIOCD + if [ "$CONFIG_VIOCD" = "y" -o "$CONFIG_VIOCD" = "m" ]; then + bool 'iSeries Virtual CD Aztech emulation' CONFIG_VIOCD_AZTECH + fi + tristate 'iSeries Virtual Tape Support' CONFIG_VIOTAPE + tristate 'iSeries Virtual Ethernet driver support' CONFIG_VETH + if [ "$CONFIG_VIOCONS" != "n" -o "$CONFIG_VIODASD" != "n" \ + -o "$CONFIG_VIOTAPE" != "n" -o "$CONFIG_VIOCD" != "n" ]; then + define_bool CONFIG_VIOPATH y + fi + endmenu +fi + +if [ "$CONFIG_VIOCD" = "y" ]; then + define_bool CONFIG_CD_NO_IDESCSI y + define_bool CONFIG_BLK_DEV_IDECD y +fi + source drivers/input/Config.in mainmenu_option next_comment @@ -311,6 +528,10 @@ if [ "$CONFIG_ALL_PPC" = "y" ]; then bool 'Support for PMU based PowerMacs' CONFIG_ADB_PMU if [ "$CONFIG_ADB_PMU" = "y" ]; then bool ' Power management support for PowerBooks' CONFIG_PMAC_PBOOK + if [ "$CONFIG_PMAC_PBOOK" = "y" ]; then + define_bool CONFIG_PM y + tristate ' APM emulation' CONFIG_PMAC_APM_EMU + fi # made a separate option since backlight may end up beeing used # on non-powerbook machines (but only on PMU based ones AFAIK) bool ' Backlight control for LCD screens' CONFIG_PMAC_BACKLIGHT @@ -336,6 +557,9 @@ if [ "$CONFIG_ALL_PPC" = "y" ]; then if [ "$CONFIG_INPUT" != "n" ]; then define_bool CONFIG_MAC_HID y fi + if [ "$CONFIG_ADB_CUDA" != "n" ]; then + bool 'Support for ANS LCD display' CONFIG_ANSLCD + fi fi endmenu @@ -363,6 +587,10 @@ if [ "$CONFIG_8260" = "y" ]; then source arch/ppc/8260_io/Config.in fi +if [ "$CONFIG_4xx" = "y" ]; then +source arch/ppc/4xx_io/Config.in +fi + source drivers/usb/Config.in if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then @@ -374,7 +602,31 @@ comment 'Kernel hacking' bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ bool 'Include kgdb kernel debugger' CONFIG_KGDB +if [ "$CONFIG_KGDB" = "y" ]; then + choice 'Serial Port' \ + "ttyS0 CONFIG_KGDB_TTYS0 \ + ttyS1 CONFIG_KGDB_TTYS1 \ + ttyS2 CONFIG_KGDB_TTYS2 \ + ttyS3 CONFIG_KGDB_TTYS3" ttyS1 +fi bool 'Include xmon kernel debugger' CONFIG_XMON +bool 'Include BDI-2000 user context switcher' CONFIG_BDI_SWITCH +if [ "$CONFIG_KGDB" = "y" -o "$CONFIG_XMON" = "y" \ + -o "$CONFIG_BDI_SWITCH" = "y" ]; then + bool 'Add any additional compile options' CONFIG_MORE_COMPILE_OPTIONS + if [ "$CONFIG_MORE_COMPILE_OPTIONS" = "y" ]; then + string 'Additional compile arguments' CONFIG_COMPILE_OPTIONS "-g -ggdb" + fi +fi + +if [ "$CONFIG_ALL_PPC" = "y" ]; then + bool 'Support for early boot text console (BootX or OpenFirmware only)' CONFIG_BOOTX_TEXT +fi +if [ "$CONFIG_MCPN765" = "y" -o "$CONFIG_SANDPOINT" = "y" \ + -o "$CONFIG_ZX4500" = "y" -o "$CONFIG_PRPMC800" = "y" \ + -o "$CONFIG_4xx" = "y" -o "$CONFIG_GT64260" = "y" ]; then + bool 'Support for early boot texts over serial port' CONFIG_SERIAL_TEXT_DEBUG +fi endmenu source lib/Config.in diff --git a/arch/ppc/configs/FADS_defconfig b/arch/ppc/configs/FADS_defconfig new file mode 100644 index 000000000000..4c5e04b01526 --- /dev/null +++ b/arch/ppc/configs/FADS_defconfig @@ -0,0 +1,476 @@ +# +# Automatically generated make config: don't edit +# +# CONFIG_UID16 is not set +# CONFIG_RWSEM_GENERIC_SPINLOCK is not set +CONFIG_RWSEM_XCHGADD_ALGORITHM=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODVERSIONS is not set +CONFIG_KMOD=y + +# +# Platform support +# +CONFIG_PPC=y +CONFIG_PPC32=y +# CONFIG_6xx is not set +# CONFIG_4xx is not set +# CONFIG_POWER3 is not set +CONFIG_8xx=y +# CONFIG_PPC_ISERIES is not set +CONFIG_SERIAL_CONSOLE=y +CONFIG_NOT_COHERENT_CACHE=y +# CONFIG_RPXLITE is not set +# CONFIG_RPXCLASSIC is not set +# CONFIG_BSEIP is not set +CONFIG_FADS=y +# CONFIG_TQM823L is not set +# CONFIG_TQM850L is not set +# CONFIG_TQM855L is not set +# CONFIG_TQM860L is not set +# CONFIG_FPS850L is not set +# CONFIG_SPD823TS is not set +# CONFIG_IVMS8 is not set +# CONFIG_IVML24 is not set +# CONFIG_SM850 is not set +# CONFIG_HERMES_PRO is not set +# CONFIG_IP860 is not set +# CONFIG_LWMON is not set +# CONFIG_PCU_E is not set +# CONFIG_CCM is not set +# CONFIG_LANTEC is not set +# CONFIG_MBX is not set +# CONFIG_WINCEPT is not set +# CONFIG_PPC601_SYNC_FIX is not set +# CONFIG_ALL_PPC is not set +# CONFIG_SMP is not set +CONFIG_MATH_EMULATION=y + +# +# General setup +# +# CONFIG_HIGHMEM is not set +# CONFIG_ISA is not set +# CONFIG_EISA is not set +# CONFIG_SBUS is not set +# CONFIG_MCA is not set +# CONFIG_PCI_QSPAN is not set +# CONFIG_PCI is not set +CONFIG_NET=y +CONFIG_SYSCTL=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_KCORE_ELF=y +CONFIG_BINFMT_ELF=y +CONFIG_KERNEL_ELF=y +# CONFIG_BINFMT_MISC is not set +# CONFIG_HOTPLUG is not set +# CONFIG_PCMCIA is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set +# CONFIG_PPC_RTC is not set +# CONFIG_CMDLINE_BOOL is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Plug and Play configuration +# +# CONFIG_PNP is not set +# CONFIG_ISAPNP is not set +# CONFIG_PNPBIOS is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_VIODASD is not set +# CONFIG_BLK_DEV_XD is not set +# CONFIG_PARIDE is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_BLK_DEV_INITRD is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set +# CONFIG_BLK_DEV_MD is not set +# CONFIG_MD_LINEAR is not set +# CONFIG_MD_RAID0 is not set +# CONFIG_MD_RAID1 is not set +# CONFIG_MD_RAID5 is not set +# CONFIG_BLK_DEV_LVM is not set + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_NETLINK=y +# CONFIG_RTNETLINK is not set +# CONFIG_NETLINK_DEV is not set +# CONFIG_NETFILTER is not set +# CONFIG_FILTER is not set +CONFIG_UNIX=y +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_IPV6 is not set +# CONFIG_KHTTPD is not set +# CONFIG_ATM is not set + +# +# +# +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# ATA/IDE/MFM/RLL support +# +# CONFIG_IDE is not set +# CONFIG_BLK_DEV_IDE_MODES is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI support +# +# CONFIG_SCSI is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_ARM_AM79C961A is not set +# CONFIG_MACE is not set +# CONFIG_BMAC is not set +# CONFIG_GMAC is not set +# CONFIG_NCR885E is not set +# CONFIG_OAKNET is not set +# CONFIG_SUNLANCE is not set +# CONFIG_SUNBMAC is not set +# CONFIG_SUNQE is not set +# CONFIG_SUNLANCE is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_NET_ISA is not set +# CONFIG_NET_PCI is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_ACENIC_OMIT_TIGON_I is not set +# CONFIG_DL2K is not set +# CONFIG_MYRI_SBUS is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_SK98LIN is not set +# CONFIG_VETH is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Old CD-ROM drivers (not SCSI, not IDE) +# +# CONFIG_CD_NO_IDESCSI is not set + +# +# Console drivers +# + +# +# Frame-buffer support +# +# CONFIG_FB is not set + +# +# Input core support +# +# CONFIG_INPUT is not set + +# +# Macintosh device drivers +# + +# +# Character devices +# +# CONFIG_VT is not set +# CONFIG_SERIAL is not set +# CONFIG_SERIAL_EXTENDED is not set +# CONFIG_SERIAL_NONSTANDARD is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=32 +# CONFIG_VIOCONS is not set + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set + +# +# Joysticks +# +# CONFIG_JOYSTICK is not set + +# +# Input core support is needed for joysticks +# +# CONFIG_QIC02_TAPE is not set +# CONFIG_VIOTAPE is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_INTEL_RNG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set +# CONFIG_SONYPI is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set +# CONFIG_ADFS_FS is not set +# CONFIG_ADFS_FS_RW is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_FAT_FS is not set +# CONFIG_MSDOS_FS is not set +# CONFIG_UMSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_TMPFS is not set +# CONFIG_RAMFS is not set +# CONFIG_ISO9660_FS is not set +# CONFIG_JOLIET is not set +# CONFIG_MINIX_FS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_NTFS_FS is not set +# CONFIG_NTFS_RW is not set +# CONFIG_HPFS_FS is not set +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVFS_MOUNT is not set +# CONFIG_DEVFS_DEBUG is not set +CONFIG_DEVPTS_FS=y +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_EXT2_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UDF_FS is not set +# CONFIG_UDF_RW is not set +# CONFIG_UFS_FS is not set +# CONFIG_UFS_FS_WRITE is not set + +# +# Network File Systems +# +# CONFIG_CODA_FS is not set +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +CONFIG_ROOT_NFS=y +# CONFIG_NFSD is not set +# CONFIG_NFSD_V3 is not set +CONFIG_SUNRPC=y +CONFIG_LOCKD=y +# CONFIG_SMB_FS is not set +# CONFIG_NCP_FS is not set +# CONFIG_NCPFS_PACKET_SIGNING is not set +# CONFIG_NCPFS_IOCTL_LOCKING is not set +# CONFIG_NCPFS_STRONG is not set +# CONFIG_NCPFS_NFS_NS is not set +# CONFIG_NCPFS_OS2_NS is not set +# CONFIG_NCPFS_SMALLDOS is not set +# CONFIG_NCPFS_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +# CONFIG_MSDOS_PARTITION is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_SMB_NLS is not set +# CONFIG_NLS is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# MPC8xx CPM Options +# +CONFIG_SCC_ENET=y +CONFIG_SCC1_ENET=y +# CONFIG_SCC2_ENET is not set +# CONFIG_SCC3_ENET is not set +# CONFIG_FEC_ENET is not set +CONFIG_ENET_BIG_BUFFERS=y +CONFIG_SMC2_UART=y +# CONFIG_ALTSMC2 is not set +# CONFIG_CONS_SMC2 is not set +# CONFIG_USE_SCC_IO is not set + +# +# Generic MPC8xx Options +# +CONFIG_8xx_COPYBACK=y +# CONFIG_8xx_CPU6 is not set +# CONFIG_UCODE_PATCH is not set + +# +# USB support +# +# CONFIG_USB is not set + +# +# Bluetooth support +# +# CONFIG_BLUEZ is not set + +# +# Kernel hacking +# +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_KGDB is not set +# CONFIG_XMON is not set +# CONFIG_BDI_SWITCH is not set diff --git a/arch/ppc/configs/IVMS8_defconfig b/arch/ppc/configs/IVMS8_defconfig index e5f4f113b9d8..f8f6f28d5a07 100644 --- a/arch/ppc/configs/IVMS8_defconfig +++ b/arch/ppc/configs/IVMS8_defconfig @@ -25,7 +25,6 @@ CONFIG_PPC32=y # CONFIG_6xx is not set # CONFIG_4xx is not set # CONFIG_POWER3 is not set -# CONFIG_POWER4 is not set CONFIG_8xx=y # CONFIG_PPC_STD_MMU is not set CONFIG_SERIAL_CONSOLE=y diff --git a/arch/ppc/configs/SM850_defconfig b/arch/ppc/configs/SM850_defconfig index 747b5026b50d..f10c2dcef59c 100644 --- a/arch/ppc/configs/SM850_defconfig +++ b/arch/ppc/configs/SM850_defconfig @@ -25,7 +25,6 @@ CONFIG_PPC32=y # CONFIG_6xx is not set # CONFIG_4xx is not set # CONFIG_POWER3 is not set -# CONFIG_POWER4 is not set CONFIG_8xx=y # CONFIG_PPC_STD_MMU is not set CONFIG_SERIAL_CONSOLE=y diff --git a/arch/ppc/configs/SPD823TS_defconfig b/arch/ppc/configs/SPD823TS_defconfig index cf110b5639f6..c4e4b15de902 100644 --- a/arch/ppc/configs/SPD823TS_defconfig +++ b/arch/ppc/configs/SPD823TS_defconfig @@ -25,7 +25,6 @@ CONFIG_PPC32=y # CONFIG_6xx is not set # CONFIG_4xx is not set # CONFIG_POWER3 is not set -# CONFIG_POWER4 is not set CONFIG_8xx=y # CONFIG_PPC_STD_MMU is not set CONFIG_SERIAL_CONSOLE=y diff --git a/arch/ppc/configs/TQM823L_defconfig b/arch/ppc/configs/TQM823L_defconfig index aed45375a2b1..fcb59e6a2069 100644 --- a/arch/ppc/configs/TQM823L_defconfig +++ b/arch/ppc/configs/TQM823L_defconfig @@ -25,7 +25,6 @@ CONFIG_PPC32=y # CONFIG_6xx is not set # CONFIG_4xx is not set # CONFIG_POWER3 is not set -# CONFIG_POWER4 is not set CONFIG_8xx=y # CONFIG_PPC_STD_MMU is not set CONFIG_SERIAL_CONSOLE=y diff --git a/arch/ppc/configs/TQM8260_defconfig b/arch/ppc/configs/TQM8260_defconfig new file mode 100644 index 000000000000..2eebf5c78c76 --- /dev/null +++ b/arch/ppc/configs/TQM8260_defconfig @@ -0,0 +1,433 @@ +# +# Automatically generated make config: don't edit +# +# CONFIG_UID16 is not set +# CONFIG_RWSEM_GENERIC_SPINLOCK is not set +CONFIG_RWSEM_XCHGADD_ALGORITHM=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODVERSIONS is not set +CONFIG_KMOD=y + +# +# Platform support +# +CONFIG_PPC=y +CONFIG_6xx=y +# CONFIG_4xx is not set +# CONFIG_POWER3 is not set +# CONFIG_8xx is not set +CONFIG_8260=y +CONFIG_SERIAL_CONSOLE=y +# CONFIG_EST8260 is not set +CONFIG_TQM8260=y +# CONFIG_PPC601_SYNC_FIX is not set +# CONFIG_ALL_PPC is not set +# CONFIG_SMP is not set +CONFIG_MACH_SPECIFIC=y +CONFIG_SASH=y +CONFIG_SASH_PATH="/bin/sash" + +# +# General setup +# +# CONFIG_HIGHMEM is not set +# CONFIG_ISA is not set +# CONFIG_EISA is not set +# CONFIG_SBUS is not set +# CONFIG_MCA is not set +# CONFIG_PCI is not set +CONFIG_NET=y +CONFIG_SYSCTL=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_KCORE_ELF=y +CONFIG_BINFMT_ELF=y +CONFIG_KERNEL_ELF=y +# CONFIG_BINFMT_MISC is not set +# CONFIG_HOTPLUG is not set +# CONFIG_PCMCIA is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set +# CONFIG_PPC_RTC is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Plug and Play configuration +# +# CONFIG_PNP is not set +# CONFIG_ISAPNP is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_XD is not set +# CONFIG_PARIDE is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_INITRD=y + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set +# CONFIG_BLK_DEV_MD is not set +# CONFIG_MD_LINEAR is not set +# CONFIG_MD_RAID0 is not set +# CONFIG_MD_RAID1 is not set +# CONFIG_MD_RAID5 is not set +# CONFIG_BLK_DEV_LVM is not set + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_NETLINK=y +# CONFIG_RTNETLINK is not set +# CONFIG_NETLINK_DEV is not set +# CONFIG_NETFILTER is not set +# CONFIG_FILTER is not set +CONFIG_UNIX=y +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_BOOTP is not set +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_IPV6 is not set +# CONFIG_KHTTPD is not set +# CONFIG_ATM is not set + +# +# +# +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# ATA/IDE/MFM/RLL support +# +# CONFIG_IDE is not set +# CONFIG_BLK_DEV_IDE_MODES is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI support +# +# CONFIG_SCSI is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set +# CONFIG_NET_SB1000 is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_MACE is not set +# CONFIG_BMAC is not set +# CONFIG_GMAC is not set +# CONFIG_NCR885E is not set +# CONFIG_OAKNET is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_AT1700 is not set +# CONFIG_DEPCA is not set +# CONFIG_NET_ISA is not set +# CONFIG_NET_PCI is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_SK98LIN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Old CD-ROM drivers (not SCSI, not IDE) +# +# CONFIG_CD_NO_IDESCSI is not set + +# +# Console drivers +# +# CONFIG_VGA_CONSOLE is not set + +# +# Frame-buffer support +# +# CONFIG_FB is not set + +# +# Input core support +# +# CONFIG_INPUT is not set + +# +# Macintosh device drivers +# + +# +# Character devices +# +# CONFIG_VT is not set +# CONFIG_SERIAL is not set +# CONFIG_SERIAL_EXTENDED is not set +# CONFIG_SERIAL_NONSTANDARD is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=32 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set + +# +# Joysticks +# +# CONFIG_JOYSTICK is not set + +# +# Input core support is needed for joysticks +# +# CONFIG_QIC02_TAPE is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_INTEL_RNG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set +CONFIG_FLASH=y +CONFIG_AMD_FLASH=y +# CONFIG_INTEL_FLASH is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set +# CONFIG_ADFS_FS is not set +# CONFIG_ADFS_FS_RW is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_FAT_FS is not set +# CONFIG_MSDOS_FS is not set +# CONFIG_UMSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_TMPFS is not set +# CONFIG_RAMFS is not set +# CONFIG_ISO9660_FS is not set +# CONFIG_JOLIET is not set +# CONFIG_MINIX_FS is not set +# CONFIG_NTFS_FS is not set +# CONFIG_NTFS_RW is not set +# CONFIG_HPFS_FS is not set +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVFS_MOUNT is not set +# CONFIG_DEVFS_DEBUG is not set +CONFIG_DEVPTS_FS=y +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set +# CONFIG_ROMFS_FS is not set +CONFIG_EXT2_FS=y +# CONFIG_SYSV_FS is not set +# CONFIG_SYSV_FS_WRITE is not set +# CONFIG_UDF_FS is not set +# CONFIG_UDF_RW is not set +# CONFIG_UFS_FS is not set +# CONFIG_UFS_FS_WRITE is not set + +# +# Network File Systems +# +# CONFIG_CODA_FS is not set +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +CONFIG_ROOT_NFS=y +# CONFIG_NFSD is not set +# CONFIG_NFSD_V3 is not set +CONFIG_SUNRPC=y +CONFIG_LOCKD=y +# CONFIG_SMB_FS is not set +# CONFIG_NCP_FS is not set +# CONFIG_NCPFS_PACKET_SIGNING is not set +# CONFIG_NCPFS_IOCTL_LOCKING is not set +# CONFIG_NCPFS_STRONG is not set +# CONFIG_NCPFS_NFS_NS is not set +# CONFIG_NCPFS_OS2_NS is not set +# CONFIG_NCPFS_SMALLDOS is not set +# CONFIG_NCPFS_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +# CONFIG_MSDOS_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_SMB_NLS is not set +# CONFIG_NLS is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# MPC8260 Communication Options +# +# CONFIG_SCC_ENET is not set +CONFIG_FEC_ENET=y +# CONFIG_FCC1_ENET is not set +CONFIG_FCC2_ENET=y +# CONFIG_FCC3_ENET is not set +# CONFIG_USE_MDIO is not set + +# +# Generic MPC82xx Options +# +CONFIG_DCACHE_DISABLE=y + +# +# USB support +# +# CONFIG_USB is not set + +# +# Kernel hacking +# +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_KGDB is not set +# CONFIG_XMON is not set diff --git a/arch/ppc/configs/TQM850L_defconfig b/arch/ppc/configs/TQM850L_defconfig index bfc4da33a0e7..d64e8041a496 100644 --- a/arch/ppc/configs/TQM850L_defconfig +++ b/arch/ppc/configs/TQM850L_defconfig @@ -25,7 +25,6 @@ CONFIG_PPC32=y # CONFIG_6xx is not set # CONFIG_4xx is not set # CONFIG_POWER3 is not set -# CONFIG_POWER4 is not set CONFIG_8xx=y # CONFIG_PPC_STD_MMU is not set CONFIG_SERIAL_CONSOLE=y diff --git a/arch/ppc/configs/TQM860L_defconfig b/arch/ppc/configs/TQM860L_defconfig index 4b8af2d04265..bb7475093e7b 100644 --- a/arch/ppc/configs/TQM860L_defconfig +++ b/arch/ppc/configs/TQM860L_defconfig @@ -25,10 +25,11 @@ CONFIG_PPC32=y # CONFIG_6xx is not set # CONFIG_4xx is not set # CONFIG_POWER3 is not set -# CONFIG_POWER4 is not set CONFIG_8xx=y +# CONFIG_PPC_ISERIES is not set # CONFIG_PPC_STD_MMU is not set CONFIG_SERIAL_CONSOLE=y +CONFIG_NOT_COHERENT_CACHE=y # CONFIG_RPXLITE is not set # CONFIG_RPXCLASSIC is not set # CONFIG_BSEIP is not set @@ -38,12 +39,18 @@ CONFIG_SERIAL_CONSOLE=y # CONFIG_TQM855L is not set CONFIG_TQM860L=y # CONFIG_FPS850L is not set -# CONFIG_TQM860 is not set # CONFIG_SPD823TS is not set # CONFIG_IVMS8 is not set # CONFIG_IVML24 is not set # CONFIG_SM850 is not set +# CONFIG_HERMES_PRO is not set +# CONFIG_IP860 is not set +# CONFIG_LWMON is not set +# CONFIG_PCU_E is not set +# CONFIG_CCM is not set +# CONFIG_LANTEC is not set # CONFIG_MBX is not set +# CONFIG_IDIF860 is not set # CONFIG_WINCEPT is not set CONFIG_TQM8xxL=y # CONFIG_ALL_PPC is not set @@ -93,6 +100,7 @@ CONFIG_PPC_RTC=y # Block devices # # CONFIG_BLK_DEV_FD is not set +# CONFIG_VIODASD is not set # CONFIG_BLK_DEV_XD is not set # CONFIG_PARIDE is not set # CONFIG_BLK_CPQ_DA is not set @@ -263,6 +271,7 @@ CONFIG_NET_ETHERNET=y # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set # CONFIG_SK98LIN is not set +# CONFIG_VETH is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set # CONFIG_PLIP is not set @@ -338,6 +347,7 @@ CONFIG_NET_ETHERNET=y # CONFIG_SERIAL_NONSTANDARD is not set CONFIG_UNIX98_PTYS=y CONFIG_UNIX98_PTY_COUNT=32 +# CONFIG_VIOCONS is not set # # I2C support @@ -363,6 +373,7 @@ CONFIG_UNIX98_PTY_COUNT=32 # Input core support is needed for joysticks # # CONFIG_QIC02_TAPE is not set +# CONFIG_VIOTAPE is not set # # Watchdog Cards @@ -489,10 +500,20 @@ CONFIG_SCC1_ENET=y # CONFIG_SCC3_ENET is not set # CONFIG_FEC_ENET is not set CONFIG_ENET_BIG_BUFFERS=y +CONFIG_SMC1_UART_RX_BDNUM=4 +CONFIG_SMC1_UART_RX_BDSIZE=32 +CONFIG_SMC1_UART_TX_BDNUM=4 +CONFIG_SMC1_UART_TX_BDSIZE=32 CONFIG_SMC2_UART=y # CONFIG_ALTSMC2 is not set # CONFIG_CONS_SMC2 is not set +CONFIG_UART_MAXIDL_SMC2=1 +CONFIG_SMC2_UART_RX_BDNUM=4 +CONFIG_SMC2_UART_RX_BDSIZE=32 +CONFIG_SMC2_UART_TX_BDNUM=4 +CONFIG_SMC2_UART_TX_BDSIZE=32 # CONFIG_USE_SCC_IO is not set +CONFIG_STATUS_LED=y # # Generic MPC8xx Options @@ -614,3 +635,4 @@ CONFIG_8xx_COPYBACK=y # CONFIG_MAGIC_SYSRQ is not set # CONFIG_KGDB is not set # CONFIG_XMON is not set +# CONFIG_BDI_SWITCH is not set diff --git a/arch/ppc/configs/adir_defconfig b/arch/ppc/configs/adir_defconfig new file mode 100644 index 000000000000..15199b0fe6a9 --- /dev/null +++ b/arch/ppc/configs/adir_defconfig @@ -0,0 +1,647 @@ +# +# Automatically generated by make menuconfig: don't edit +# +# CONFIG_UID16 is not set +# CONFIG_RWSEM_GENERIC_SPINLOCK is not set +CONFIG_RWSEM_XCHGADD_ALGORITHM=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODVERSIONS=y +CONFIG_KMOD=y + +# +# Platform support +# +CONFIG_PPC=y +CONFIG_PPC32=y +CONFIG_6xx=y +# CONFIG_4xx is not set +# CONFIG_POWER3 is not set +# CONFIG_8xx is not set +# CONFIG_PPC_ISERIES is not set +# CONFIG_8260 is not set +CONFIG_PPC_STD_MMU=y +# CONFIG_ALL_PPC is not set +# CONFIG_APUS is not set +# CONFIG_SPRUCE is not set +# CONFIG_PCORE is not set +# CONFIG_MENF1 is not set +# CONFIG_LOPEC is not set +# CONFIG_MCPN765 is not set +# CONFIG_MVME5100 is not set +# CONFIG_PRPMC750 is not set +# CONFIG_PRPMC800 is not set +# CONFIG_SANDPOINT is not set +CONFIG_ADIR=y +# CONFIG_K2 is not set +# CONFIG_GEMINI is not set +# CONFIG_WILLOW is not set +# CONFIG_ZX4500 is not set +# CONFIG_SMP is not set +# CONFIG_ALTIVEC is not set +# CONFIG_TAU is not set + +# +# General setup +# +# CONFIG_HIGHMEM is not set +# CONFIG_ISA is not set +# CONFIG_EISA is not set +# CONFIG_SBUS is not set +# CONFIG_MCA is not set +CONFIG_PCI=y +CONFIG_NET=y +CONFIG_SYSCTL=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_KCORE_ELF=y +CONFIG_BINFMT_ELF=y +CONFIG_KERNEL_ELF=y +# CONFIG_BINFMT_MISC is not set +# CONFIG_PCI_NAMES is not set +# CONFIG_HOTPLUG is not set +# CONFIG_PCMCIA is not set + +# +# Parallel port support +# +CONFIG_PARPORT=y +CONFIG_PARPORT_PC=y +CONFIG_PARPORT_PC_CML1=y +# CONFIG_PARPORT_SERIAL is not set +CONFIG_PARPORT_PC_FIFO=y +CONFIG_PARPORT_PC_SUPERIO=y +# CONFIG_PARPORT_AMIGA is not set +# CONFIG_PARPORT_MFC3 is not set +# CONFIG_PARPORT_ATARI is not set +# CONFIG_PARPORT_SUNBPP is not set +# CONFIG_PARPORT_OTHER is not set +CONFIG_PARPORT_1284=y +CONFIG_PPC_RTC=y +CONFIG_CMDLINE_BOOL=y +CONFIG_CMDLINE="ip=on" + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Plug and Play configuration +# +# CONFIG_PNP is not set +# CONFIG_ISAPNP is not set +# CONFIG_PNPBIOS is not set + +# +# Block devices +# +CONFIG_BLK_DEV_FD=y +# CONFIG_VIODASD is not set +# CONFIG_BLK_DEV_XD is not set +# CONFIG_PARIDE is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_INITRD=y + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set +# CONFIG_BLK_DEV_MD is not set +# CONFIG_MD_LINEAR is not set +# CONFIG_MD_RAID0 is not set +# CONFIG_MD_RAID1 is not set +# CONFIG_MD_RAID5 is not set +# CONFIG_MD_MULTIPATH is not set +# CONFIG_BLK_DEV_LVM is not set + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_NETLINK=y +# CONFIG_RTNETLINK is not set +# CONFIG_NETLINK_DEV is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +# CONFIG_FILTER is not set +CONFIG_UNIX=y +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +# CONFIG_IP_PNP_BOOTP is not set +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set + +# +# IP: Netfilter Configuration +# +CONFIG_IP_NF_CONNTRACK=m +CONFIG_IP_NF_FTP=m +# CONFIG_IP_NF_QUEUE is not set +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_LIMIT=m +CONFIG_IP_NF_MATCH_MAC=m +CONFIG_IP_NF_MATCH_MARK=m +CONFIG_IP_NF_MATCH_MULTIPORT=m +CONFIG_IP_NF_MATCH_TOS=m +CONFIG_IP_NF_MATCH_TCPMSS=m +CONFIG_IP_NF_MATCH_STATE=m +CONFIG_IP_NF_MATCH_UNCLEAN=m +CONFIG_IP_NF_MATCH_OWNER=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_MIRROR=m +CONFIG_IP_NF_NAT=m +CONFIG_IP_NF_NAT_NEEDED=y +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_NAT_FTP=m +# CONFIG_IP_NF_MANGLE is not set +# CONFIG_IP_NF_TARGET_LOG is not set +CONFIG_IP_NF_TARGET_TCPMSS=m +CONFIG_IP_NF_COMPAT_IPCHAINS=m +CONFIG_IP_NF_NAT_NEEDED=y +# CONFIG_IP_NF_COMPAT_IPFWADM is not set +# CONFIG_IPV6 is not set +# CONFIG_KHTTPD is not set +# CONFIG_ATM is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# ATA/IDE/MFM/RLL support +# +# CONFIG_IDE is not set +# CONFIG_BLK_DEV_IDE_MODES is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI support +# +CONFIG_SCSI=y +CONFIG_BLK_DEV_SD=y +CONFIG_SD_EXTRA_DEVS=40 +CONFIG_CHR_DEV_ST=y +# CONFIG_CHR_DEV_OSST is not set +CONFIG_BLK_DEV_SR=y +CONFIG_BLK_DEV_SR_VENDOR=y +CONFIG_SR_EXTRA_DEVS=2 +CONFIG_CHR_DEV_SG=y +# CONFIG_SCSI_DEBUG_QUEUES is not set +# CONFIG_SCSI_MULTI_LUN is not set +CONFIG_SCSI_CONSTANTS=y +# CONFIG_SCSI_LOGGING is not set + +# +# SCSI low-level drivers +# +# CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_7000FASST is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_AHA152X is not set +# CONFIG_SCSI_AHA1542 is not set +# CONFIG_SCSI_AHA1740 is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_DPT_I2O is not set +# CONFIG_SCSI_ADVANSYS is not set +# CONFIG_SCSI_IN2000 is not set +# CONFIG_SCSI_AM53C974 is not set +# CONFIG_SCSI_MEGARAID is not set +# CONFIG_SCSI_BUSLOGIC is not set +# CONFIG_SCSI_CPQFCTS is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_DTC3280 is not set +# CONFIG_SCSI_EATA is not set +# CONFIG_SCSI_EATA_DMA is not set +# CONFIG_SCSI_EATA_PIO is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_GDTH is not set +# CONFIG_SCSI_GENERIC_NCR5380 is not set +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_PPA is not set +# CONFIG_SCSI_IMM is not set +# CONFIG_SCSI_NCR53C406A is not set +# CONFIG_SCSI_NCR53C7xx is not set +CONFIG_SCSI_NCR53C8XX=y +CONFIG_SCSI_SYM53C8XX=y +CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=8 +CONFIG_SCSI_NCR53C8XX_MAX_TAGS=32 +CONFIG_SCSI_NCR53C8XX_SYNC=20 +# CONFIG_SCSI_NCR53C8XX_PROFILE is not set +# CONFIG_SCSI_NCR53C8XX_IOMAPPED is not set +# CONFIG_SCSI_NCR53C8XX_PQS_PDS is not set +# CONFIG_SCSI_NCR53C8XX_SYMBIOS_COMPAT is not set +# CONFIG_SCSI_PAS16 is not set +# CONFIG_SCSI_PCI2000 is not set +# CONFIG_SCSI_PCI2220I is not set +# CONFIG_SCSI_PSI240I is not set +# CONFIG_SCSI_QLOGIC_FAS is not set +# CONFIG_SCSI_QLOGIC_ISP is not set +# CONFIG_SCSI_QLOGIC_FC is not set +# CONFIG_SCSI_QLOGIC_1280 is not set +# CONFIG_SCSI_SIM710 is not set +# CONFIG_SCSI_SYM53C416 is not set +# CONFIG_SCSI_DC390T is not set +# CONFIG_SCSI_T128 is not set +# CONFIG_SCSI_U14_34F is not set +# CONFIG_SCSI_DEBUG is not set + +# +# IEEE 1394 (FireWire) support (EXPERIMENTAL) +# +# CONFIG_IEEE1394 is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_MACE is not set +# CONFIG_BMAC is not set +# CONFIG_GMAC is not set +# CONFIG_SUNLANCE is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNBMAC is not set +# CONFIG_SUNQE is not set +# CONFIG_SUNLANCE is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_HP100 is not set +# CONFIG_NET_ISA is not set +CONFIG_NET_PCI=y +# CONFIG_PCNET32 is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_APRICOT is not set +# CONFIG_CS89x0 is not set +# CONFIG_TULIP is not set +# CONFIG_DE4X5 is not set +# CONFIG_DGRS is not set +# CONFIG_DM9102 is not set +CONFIG_EEPRO100=y +# CONFIG_LNE390 is not set +# CONFIG_FEALNX is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_NE3210 is not set +# CONFIG_ES3210 is not set +# CONFIG_8139TOO is not set +# CONFIG_8139TOO_PIO is not set +# CONFIG_8139TOO_TUNE_TWISTER is not set +# CONFIG_8139TOO_8129 is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_TLAN is not set +# CONFIG_VIA_RHINE is not set +# CONFIG_WINBOND_840 is not set +# CONFIG_LAN_SAA9730 is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_MYRI_SBUS is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_SK98LIN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Old CD-ROM drivers (not SCSI, not IDE) +# +# CONFIG_CD_NO_IDESCSI is not set + +# +# Console drivers +# +# CONFIG_VGA_CONSOLE is not set + +# +# Frame-buffer support +# +# CONFIG_FB is not set + +# +# Input core support +# +# CONFIG_INPUT is not set +# CONFIG_INPUT_KEYBDEV is not set +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set + +# +# Macintosh device drivers +# + +# +# Character devices +# +# CONFIG_VT is not set +CONFIG_SERIAL=y +CONFIG_SERIAL_CONSOLE=y +# CONFIG_SERIAL_EXTENDED is not set +# CONFIG_SERIAL_NONSTANDARD is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 +# CONFIG_PRINTER is not set +# CONFIG_PPDEV is not set +# CONFIG_VIOCONS is not set + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set + +# +# Joysticks +# +# CONFIG_INPUT_GAMEPORT is not set +# CONFIG_QIC02_TAPE is not set +# CONFIG_VIOTAPE is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_INTEL_RNG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set +# CONFIG_SONYPI is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set +# CONFIG_ADFS_FS is not set +# CONFIG_ADFS_FS_RW is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_FAT_FS is not set +# CONFIG_MSDOS_FS is not set +# CONFIG_UMSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_CRAMFS is not set +CONFIG_TMPFS=y +# CONFIG_RAMFS is not set +# CONFIG_ISO9660_FS is not set +# CONFIG_JOLIET is not set +# CONFIG_MINIX_FS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_NTFS_FS is not set +# CONFIG_NTFS_RW is not set +# CONFIG_HPFS_FS is not set +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVFS_MOUNT is not set +# CONFIG_DEVFS_DEBUG is not set +CONFIG_DEVPTS_FS=y +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set +# CONFIG_ROMFS_FS is not set +CONFIG_EXT2_FS=y +# CONFIG_SYSV_FS is not set +# CONFIG_UDF_FS is not set +# CONFIG_UDF_RW is not set +# CONFIG_UFS_FS is not set +# CONFIG_UFS_FS_WRITE is not set + +# +# Network File Systems +# +# CONFIG_CODA_FS is not set +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +CONFIG_ROOT_NFS=y +# CONFIG_NFSD is not set +# CONFIG_NFSD_V3 is not set +CONFIG_SUNRPC=y +CONFIG_LOCKD=y +# CONFIG_SMB_FS is not set +# CONFIG_NCP_FS is not set +# CONFIG_NCPFS_PACKET_SIGNING is not set +# CONFIG_NCPFS_IOCTL_LOCKING is not set +# CONFIG_NCPFS_STRONG is not set +# CONFIG_NCPFS_NFS_NS is not set +# CONFIG_NCPFS_OS2_NS is not set +# CONFIG_NCPFS_SMALLDOS is not set +# CONFIG_NCPFS_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_SMB_NLS is not set +# CONFIG_NLS is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set +CONFIG_USB_DEVICEFS=y +# CONFIG_USB_BANDWIDTH is not set +CONFIG_USB_UHCI=y +CONFIG_USB_OHCI=y +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_BLUETOOTH is not set +CONFIG_USB_STORAGE=m +# CONFIG_USB_STORAGE_DEBUG is not set +CONFIG_USB_STORAGE_FREECOM=y +# CONFIG_USB_STORAGE_ISD200 is not set +CONFIG_USB_STORAGE_DPCM=y +# CONFIG_USB_STORAGE_HP8200e is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +CONFIG_USB_ACM=m +# CONFIG_USB_PRINTER is not set +# CONFIG_USB_DC2XX is not set +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_SCANNER is not set +# CONFIG_USB_MICROTEK is not set +# CONFIG_USB_HPUSBSCSI is not set +# CONFIG_USB_IBMCAM is not set +# CONFIG_USB_OV511 is not set +# CONFIG_USB_PWC is not set +# CONFIG_USB_SE401 is not set +# CONFIG_USB_DSBR is not set +# CONFIG_USB_DABUSB is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_CATC is not set +# CONFIG_USB_CDCETHER is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_USBNET is not set +# CONFIG_USB_USS720 is not set + +# +# USB Serial Converter support +# +CONFIG_USB_SERIAL=m +# CONFIG_USB_SERIAL_GENERIC is not set +# CONFIG_USB_SERIAL_BELKIN is not set +# CONFIG_USB_SERIAL_WHITEHEAT is not set +# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set +# CONFIG_USB_SERIAL_EMPEG is not set +# CONFIG_USB_SERIAL_FTDI_SIO is not set +CONFIG_USB_SERIAL_VISOR=m +# CONFIG_USB_SERIAL_IR is not set +# CONFIG_USB_SERIAL_EDGEPORT is not set +# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set +CONFIG_USB_SERIAL_KEYSPAN=m +CONFIG_USB_SERIAL_KEYSPAN_USA28=y +CONFIG_USB_SERIAL_KEYSPAN_USA28X=y +# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set +CONFIG_USB_SERIAL_KEYSPAN_USA19=y +CONFIG_USB_SERIAL_KEYSPAN_USA18X=y +CONFIG_USB_SERIAL_KEYSPAN_USA19W=y +CONFIG_USB_SERIAL_KEYSPAN_USA49W=y +# CONFIG_USB_SERIAL_MCT_U232 is not set +# CONFIG_USB_SERIAL_PL2303 is not set +# CONFIG_USB_SERIAL_CYBERJACK is not set +# CONFIG_USB_SERIAL_XIRCOM is not set +# CONFIG_USB_SERIAL_OMNINET is not set +# CONFIG_USB_RIO500 is not set + +# +# Bluetooth support +# +# CONFIG_BLUEZ is not set + +# +# Kernel hacking +# +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_KGDB is not set +CONFIG_XMON=y +# CONFIG_BDI_SWITCH is not set diff --git a/arch/ppc/configs/apus_defconfig b/arch/ppc/configs/apus_defconfig index 7ab407ae6f06..fc1bdd5af2b0 100644 --- a/arch/ppc/configs/apus_defconfig +++ b/arch/ppc/configs/apus_defconfig @@ -25,7 +25,6 @@ CONFIG_PPC32=y CONFIG_6xx=y # CONFIG_4xx is not set # CONFIG_POWER3 is not set -# CONFIG_POWER4 is not set # CONFIG_8xx is not set # CONFIG_8260 is not set CONFIG_PPC_STD_MMU=y diff --git a/arch/ppc/configs/ash_defconfig b/arch/ppc/configs/ash_defconfig new file mode 100644 index 000000000000..ff2f112d550a --- /dev/null +++ b/arch/ppc/configs/ash_defconfig @@ -0,0 +1,569 @@ +# +# Automatically generated by make menuconfig: don't edit +# +# CONFIG_UID16 is not set +# CONFIG_RWSEM_GENERIC_SPINLOCK is not set +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_HAVE_DEC_LOCK=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODVERSIONS=y +CONFIG_KMOD=y + +# +# Platform support +# +CONFIG_PPC=y +CONFIG_PPC32=y +# CONFIG_6xx is not set +CONFIG_4xx=y +# CONFIG_POWER3 is not set +# CONFIG_8xx is not set +# CONFIG_PPC_ISERIES is not set +# CONFIG_PPC_STD_MMU is not set +CONFIG_ASH=y +# CONFIG_CEDER is not set +# CONFIG_CPCI405 is not set +# CONFIG_EP405 is not set +# CONFIG_OAK is not set +# CONFIG_REDWOOD_4 is not set +# CONFIG_REDWOOD_5 is not set +# CONFIG_TIVO is not set +# CONFIG_WALNUT is not set +# CONFIG_ALL_PPC is not set +# CONFIG_SMP is not set +# CONFIG_MATH_EMULATION is not set +CONFIG_NP405H=y +CONFIG_BIOS_FIXUP=y +CONFIG_TREEBOOT=y +CONFIG_IBM405_ERR77=y +CONFIG_IBM_OCP=y +# CONFIG_405_DMA is not set +CONFIG_UART0_TTYS0=y +# CONFIG_UART0_TTYS1 is not set +CONFIG_IBM405_ERR51=y +CONFIG_NOT_COHERENT_CACHE=y + +# +# General setup +# +# CONFIG_HIGHMEM is not set +# CONFIG_ISA is not set +# CONFIG_EISA is not set +# CONFIG_SBUS is not set +# CONFIG_MCA is not set +CONFIG_PCI=y +# CONFIG_PC_KEYBOARD is not set +CONFIG_NET=y +CONFIG_SYSCTL=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_KCORE_ELF=y +CONFIG_BINFMT_ELF=y +CONFIG_KERNEL_ELF=y +# CONFIG_BINFMT_MISC is not set +# CONFIG_PCI_NAMES is not set +# CONFIG_HOTPLUG is not set +# CONFIG_PCMCIA is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set +CONFIG_PPC_RTC=y +# CONFIG_CMDLINE_BOOL is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Plug and Play configuration +# +# CONFIG_PNP is not set +# CONFIG_ISAPNP is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_XD is not set +# CONFIG_PARIDE is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_INITRD=y + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set +# CONFIG_BLK_DEV_MD is not set +# CONFIG_MD_LINEAR is not set +# CONFIG_MD_RAID0 is not set +# CONFIG_MD_RAID1 is not set +# CONFIG_MD_RAID5 is not set +# CONFIG_MD_MULTIPATH is not set +# CONFIG_BLK_DEV_LVM is not set + +# +# Networking options +# +# CONFIG_PACKET is not set +# CONFIG_NETLINK_DEV is not set +# CONFIG_NETFILTER is not set +# CONFIG_FILTER is not set +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +CONFIG_IP_PNP_RARP=y +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_INET_ECN is not set +CONFIG_SYN_COOKIES=y +# CONFIG_IPV6 is not set +# CONFIG_KHTTPD is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set + +# +# Appletalk devices +# +# CONFIG_DEV_APPLETALK is not set +# CONFIG_LTPC is not set +# CONFIG_COPS is not set +# CONFIG_COPS_DAYNA is not set +# CONFIG_COPS_TANGENT is not set +# CONFIG_IPDDP is not set +# CONFIG_IPDDP_ENCAP is not set +# CONFIG_IPDDP_DECAP is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# ATA/IDE/MFM/RLL support +# +# CONFIG_IDE is not set +# CONFIG_BLK_DEV_IDE_MODES is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI support +# +# CONFIG_SCSI is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set +# CONFIG_FUSION_BOOT is not set +# CONFIG_FUSION_ISENSE is not set +# CONFIG_FUSION_CTL is not set +# CONFIG_FUSION_LAN is not set + +# +# IEEE 1394 (FireWire) support (EXPERIMENTAL) +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# +# CONFIG_I2O is not set +# CONFIG_I2O_PCI is not set +# CONFIG_I2O_BLOCK is not set +# CONFIG_I2O_LAN is not set +# CONFIG_I2O_SCSI is not set +# CONFIG_I2O_PROC is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_MACE is not set +# CONFIG_BMAC is not set +# CONFIG_GMAC is not set +CONFIG_IBM_OCP_ENET=y +# CONFIG_IBM_OCP_ENET_ERROR_MSG is not set +CONFIG_IBM_OCP_ENET_RX_BUFF=64 +CONFIG_IBM_OCP_ENET_TX_BUFF=8 +CONFIG_IBM_OCP_ENET_GAP=8 +# CONFIG_SUNLANCE is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNBMAC is not set +# CONFIG_SUNQE is not set +# CONFIG_SUNLANCE is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_HP100 is not set +# CONFIG_NET_ISA is not set +# CONFIG_NET_PCI is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_MYRI_SBUS is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_SK98LIN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Old CD-ROM drivers (not SCSI, not IDE) +# +# CONFIG_CD_NO_IDESCSI is not set + +# +# Console drivers +# + +# +# Frame-buffer support +# +# CONFIG_FB is not set + +# +# Input core support +# +# CONFIG_INPUT is not set +# CONFIG_INPUT_KEYBDEV is not set +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set + +# +# Macintosh device drivers +# + +# +# Character devices +# +# CONFIG_VT is not set +CONFIG_SERIAL=y +CONFIG_SERIAL_CONSOLE=y +# CONFIG_SERIAL_EXTENDED is not set +# CONFIG_SERIAL_NONSTANDARD is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 + +# +# I2C support +# +CONFIG_I2C=y +# CONFIG_I2C_ALGOBIT is not set +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_CHARDEV is not set +# CONFIG_I2C_PROC is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set + +# +# Joysticks +# +# CONFIG_INPUT_GAMEPORT is not set +# CONFIG_QIC02_TAPE is not set + +# +# Watchdog Cards +# +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set +# CONFIG_SOFT_WATCHDOG is not set +# CONFIG_WDT is not set +# CONFIG_WDTPCI is not set +# CONFIG_PCWATCHDOG is not set +# CONFIG_ACQUIRE_WDT is not set +# CONFIG_ADVANTECH_WDT is not set +# CONFIG_EUROTECH_WDT is not set +# CONFIG_IB700_WDT is not set +# CONFIG_I810_TCO is not set +# CONFIG_MIXCOMWD is not set +# CONFIG_60XX_WDT is not set +# CONFIG_W83877F_WDT is not set +# CONFIG_MACHZ_WDT is not set +CONFIG_PPC405_WDT=y +# CONFIG_INTEL_RNG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set +# CONFIG_ADFS_FS is not set +# CONFIG_ADFS_FS_RW is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_JBD_DEBUG is not set +# CONFIG_FAT_FS is not set +# CONFIG_MSDOS_FS is not set +# CONFIG_UMSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_CRAMFS is not set +CONFIG_TMPFS=y +# CONFIG_RAMFS is not set +# CONFIG_ISO9660_FS is not set +# CONFIG_JOLIET is not set +# CONFIG_ZISOFS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_NTFS_FS is not set +# CONFIG_NTFS_RW is not set +# CONFIG_HPFS_FS is not set +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVFS_MOUNT is not set +# CONFIG_DEVFS_DEBUG is not set +CONFIG_DEVPTS_FS=y +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set +# CONFIG_ROMFS_FS is not set +CONFIG_EXT2_FS=y +# CONFIG_SYSV_FS is not set +# CONFIG_UDF_FS is not set +# CONFIG_UDF_RW is not set +# CONFIG_UFS_FS is not set +# CONFIG_UFS_FS_WRITE is not set + +# +# Network File Systems +# +# CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +CONFIG_ROOT_NFS=y +# CONFIG_NFSD is not set +# CONFIG_NFSD_V3 is not set +CONFIG_SUNRPC=y +CONFIG_LOCKD=y +# CONFIG_SMB_FS is not set +# CONFIG_NCP_FS is not set +# CONFIG_NCPFS_PACKET_SIGNING is not set +# CONFIG_NCPFS_IOCTL_LOCKING is not set +# CONFIG_NCPFS_STRONG is not set +# CONFIG_NCPFS_NFS_NS is not set +# CONFIG_NCPFS_OS2_NS is not set +# CONFIG_NCPFS_SMALLDOS is not set +# CONFIG_NCPFS_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set +# CONFIG_ZISOFS_FS is not set +# CONFIG_ZLIB_FS_INFLATE is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_SMB_NLS is not set +# CONFIG_NLS is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# MPC4xx Driver Options +# + +# +# USB support +# +# CONFIG_USB is not set +# CONFIG_USB_UHCI is not set +# CONFIG_USB_UHCI_ALT is not set +# CONFIG_USB_OHCI is not set +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_BLUETOOTH is not set +# CONFIG_USB_STORAGE is not set +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_HP8200e is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set +# CONFIG_USB_DC2XX is not set +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_SCANNER is not set +# CONFIG_USB_MICROTEK is not set +# CONFIG_USB_HPUSBSCSI is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_CATC is not set +# CONFIG_USB_CDCETHER is not set +# CONFIG_USB_USBNET is not set +# CONFIG_USB_USS720 is not set + +# +# USB Serial Converter support +# +# CONFIG_USB_SERIAL is not set +# CONFIG_USB_SERIAL_GENERIC is not set +# CONFIG_USB_SERIAL_BELKIN is not set +# CONFIG_USB_SERIAL_WHITEHEAT is not set +# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set +# CONFIG_USB_SERIAL_EMPEG is not set +# CONFIG_USB_SERIAL_FTDI_SIO is not set +# CONFIG_USB_SERIAL_VISOR is not set +# CONFIG_USB_SERIAL_IPAQ is not set +# CONFIG_USB_SERIAL_IR is not set +# CONFIG_USB_SERIAL_EDGEPORT is not set +# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set +# CONFIG_USB_SERIAL_KEYSPAN is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set +# CONFIG_USB_SERIAL_MCT_U232 is not set +# CONFIG_USB_SERIAL_KLSI is not set +# CONFIG_USB_SERIAL_PL2303 is not set +# CONFIG_USB_SERIAL_CYBERJACK is not set +# CONFIG_USB_SERIAL_XIRCOM is not set +# CONFIG_USB_SERIAL_OMNINET is not set +# CONFIG_USB_RIO500 is not set + +# +# Bluetooth support +# +# CONFIG_BLUEZ is not set + +# +# Kernel hacking +# +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_KGDB is not set +# CONFIG_XMON is not set +# CONFIG_BDI_SWITCH is not set +# CONFIG_SERIAL_TEXT_DEBUG is not set diff --git a/arch/ppc/configs/bseip_defconfig b/arch/ppc/configs/bseip_defconfig index 6e1b21b0e92e..b44359e43a0b 100644 --- a/arch/ppc/configs/bseip_defconfig +++ b/arch/ppc/configs/bseip_defconfig @@ -23,7 +23,6 @@ CONFIG_PPC32=y # CONFIG_6xx is not set # CONFIG_4xx is not set # CONFIG_POWER3 is not set -# CONFIG_POWER4 is not set CONFIG_8xx=y # CONFIG_PPC_STD_MMU is not set CONFIG_SERIAL_CONSOLE=y diff --git a/arch/ppc/configs/ceder_defconfig b/arch/ppc/configs/ceder_defconfig new file mode 100644 index 000000000000..c3f6f37cf036 --- /dev/null +++ b/arch/ppc/configs/ceder_defconfig @@ -0,0 +1,611 @@ +# +# Automatically generated make config: don't edit +# +# CONFIG_UID16 is not set +# CONFIG_RWSEM_GENERIC_SPINLOCK is not set +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_HAVE_DEC_LOCK=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODVERSIONS=y +CONFIG_KMOD=y + +# +# Platform support +# +CONFIG_PPC=y +CONFIG_PPC32=y +# CONFIG_6xx is not set +CONFIG_4xx=y +# CONFIG_POWER3 is not set +# CONFIG_8xx is not set +# CONFIG_PPC_ISERIES is not set +# CONFIG_PPC_STD_MMU is not set +CONFIG_CEDER=y +# CONFIG_CPCI405 is not set +# CONFIG_EP405 is not set +# CONFIG_OAK is not set +# CONFIG_REDWOOD_4 is not set +# CONFIG_REDWOOD_5 is not set +# CONFIG_TIVO is not set +# CONFIG_WALNUT is not set +# CONFIG_ALL_PPC is not set +# CONFIG_SMP is not set +# CONFIG_MATH_EMULATION is not set +CONFIG_NP405=y +CONFIG_BIOS_FIXUP=y +CONFIG_TREEBOOT=y +CONFIG_IBM405_ERR77=y +CONFIG_IBM_OCP=y +# CONFIG_405_DMA is not set +CONFIG_UART0_TTYS0=y +# CONFIG_UART0_TTYS1 is not set +CONFIG_IBM405_ERR51=y +CONFIG_NOT_COHERENT_CACHE=y + +# +# General setup +# +# CONFIG_HIGHMEM is not set +# CONFIG_ISA is not set +# CONFIG_EISA is not set +# CONFIG_SBUS is not set +# CONFIG_MCA is not set +# CONFIG_PCI is not set +# CONFIG_PC_KEYBOARD is not set +CONFIG_NET=y +CONFIG_SYSCTL=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_KCORE_ELF=y +CONFIG_BINFMT_ELF=y +CONFIG_KERNEL_ELF=y +# CONFIG_BINFMT_MISC is not set +# CONFIG_HOTPLUG is not set +# CONFIG_PCMCIA is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set +CONFIG_PPC_RTC=y +# CONFIG_CMDLINE_BOOL is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Plug and Play configuration +# +# CONFIG_PNP is not set +# CONFIG_ISAPNP is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_XD is not set +# CONFIG_PARIDE is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_INITRD=y + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set +# CONFIG_BLK_DEV_MD is not set +# CONFIG_MD_LINEAR is not set +# CONFIG_MD_RAID0 is not set +# CONFIG_MD_RAID1 is not set +# CONFIG_MD_RAID5 is not set +# CONFIG_MD_MULTIPATH is not set +# CONFIG_BLK_DEV_LVM is not set + +# +# Networking options +# +# CONFIG_PACKET is not set +# CONFIG_NETLINK_DEV is not set +# CONFIG_NETFILTER is not set +# CONFIG_FILTER is not set +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +CONFIG_IP_PNP_RARP=y +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_INET_ECN is not set +CONFIG_SYN_COOKIES=y +# CONFIG_IPV6 is not set +# CONFIG_KHTTPD is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set + +# +# +# +# CONFIG_IPX is not set +# CONFIG_ATALK is not set + +# +# Appletalk devices +# +# CONFIG_DEV_APPLETALK is not set +# CONFIG_LTPC is not set +# CONFIG_COPS is not set +# CONFIG_COPS_DAYNA is not set +# CONFIG_COPS_TANGENT is not set +# CONFIG_IPDDP is not set +# CONFIG_IPDDP_ENCAP is not set +# CONFIG_IPDDP_DECAP is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# ATA/IDE/MFM/RLL support +# +# CONFIG_IDE is not set +# CONFIG_BLK_DEV_IDE_MODES is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI support +# +# CONFIG_SCSI is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set +# CONFIG_FUSION_BOOT is not set +# CONFIG_FUSION_ISENSE is not set +# CONFIG_FUSION_CTL is not set +# CONFIG_FUSION_LAN is not set + +# +# I2O device support +# +# CONFIG_I2O is not set +# CONFIG_I2O_BLOCK is not set +# CONFIG_I2O_LAN is not set +# CONFIG_I2O_SCSI is not set +# CONFIG_I2O_PROC is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_MACE is not set +# CONFIG_BMAC is not set +# CONFIG_GMAC is not set +CONFIG_IBM_OCP_ENET=y +# CONFIG_IBM_OCP_ENET_ERROR_MSG is not set +CONFIG_IBM_OCP_ENET_RX_BUFF=64 +CONFIG_IBM_OCP_ENET_TX_BUFF=8 +CONFIG_IBM_OCP_ENET_GAP=8 +# CONFIG_SUNLANCE is not set +# CONFIG_SUNBMAC is not set +# CONFIG_SUNQE is not set +# CONFIG_SUNLANCE is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_NET_ISA is not set +# CONFIG_NET_PCI is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_MYRI_SBUS is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_SK98LIN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Old CD-ROM drivers (not SCSI, not IDE) +# +# CONFIG_CD_NO_IDESCSI is not set + +# +# Console drivers +# + +# +# Frame-buffer support +# +# CONFIG_FB is not set + +# +# Input core support +# +# CONFIG_INPUT is not set +# CONFIG_INPUT_KEYBDEV is not set +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set + +# +# Macintosh device drivers +# + +# +# Character devices +# +# CONFIG_VT is not set +CONFIG_SERIAL=y +CONFIG_SERIAL_CONSOLE=y +# CONFIG_SERIAL_EXTENDED is not set +# CONFIG_SERIAL_NONSTANDARD is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 + +# +# I2C support +# +CONFIG_I2C=y +# CONFIG_I2C_ALGOBIT is not set +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_CHARDEV is not set +# CONFIG_I2C_PROC is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set + +# +# Joysticks +# +# CONFIG_INPUT_GAMEPORT is not set + +# +# Input core support is needed for gameports +# + +# +# Input core support is needed for joysticks +# +# CONFIG_QIC02_TAPE is not set + +# +# Watchdog Cards +# +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set +# CONFIG_SOFT_WATCHDOG is not set +# CONFIG_WDT is not set +# CONFIG_WDTPCI is not set +# CONFIG_PCWATCHDOG is not set +# CONFIG_ACQUIRE_WDT is not set +# CONFIG_ADVANTECH_WDT is not set +# CONFIG_EUROTECH_WDT is not set +# CONFIG_IB700_WDT is not set +# CONFIG_I810_TCO is not set +# CONFIG_MIXCOMWD is not set +# CONFIG_60XX_WDT is not set +# CONFIG_W83877F_WDT is not set +# CONFIG_MACHZ_WDT is not set +CONFIG_PPC405_WDT=y +# CONFIG_INTEL_RNG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set +# CONFIG_ADFS_FS is not set +# CONFIG_ADFS_FS_RW is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_JBD_DEBUG is not set +# CONFIG_FAT_FS is not set +# CONFIG_MSDOS_FS is not set +# CONFIG_UMSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_CRAMFS is not set +CONFIG_TMPFS=y +# CONFIG_RAMFS is not set +# CONFIG_ISO9660_FS is not set +# CONFIG_JOLIET is not set +# CONFIG_ZISOFS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_NTFS_FS is not set +# CONFIG_NTFS_RW is not set +# CONFIG_HPFS_FS is not set +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVFS_MOUNT is not set +# CONFIG_DEVFS_DEBUG is not set +CONFIG_DEVPTS_FS=y +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set +# CONFIG_ROMFS_FS is not set +CONFIG_EXT2_FS=y +# CONFIG_SYSV_FS is not set +# CONFIG_UDF_FS is not set +# CONFIG_UDF_RW is not set +# CONFIG_UFS_FS is not set +# CONFIG_UFS_FS_WRITE is not set + +# +# Network File Systems +# +# CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +CONFIG_ROOT_NFS=y +# CONFIG_NFSD is not set +# CONFIG_NFSD_V3 is not set +CONFIG_SUNRPC=y +CONFIG_LOCKD=y +# CONFIG_SMB_FS is not set +# CONFIG_NCP_FS is not set +# CONFIG_NCPFS_PACKET_SIGNING is not set +# CONFIG_NCPFS_IOCTL_LOCKING is not set +# CONFIG_NCPFS_STRONG is not set +# CONFIG_NCPFS_NFS_NS is not set +# CONFIG_NCPFS_OS2_NS is not set +# CONFIG_NCPFS_SMALLDOS is not set +# CONFIG_NCPFS_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set +# CONFIG_ZISOFS_FS is not set +# CONFIG_ZLIB_FS_INFLATE is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_SMB_NLS is not set +# CONFIG_NLS is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# MPC4xx Driver Options +# + +# +# USB support +# +# CONFIG_USB is not set + +# +# USB Controllers +# +# CONFIG_USB_UHCI is not set +# CONFIG_USB_UHCI_ALT is not set +# CONFIG_USB_OHCI is not set + +# +# USB Device Class drivers +# +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_BLUETOOTH is not set +# CONFIG_USB_STORAGE is not set +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_HP8200e is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set + +# +# USB Human Interface Devices (HID) +# + +# +# Input core support is needed for USB HID +# + +# +# USB Imaging devices +# +# CONFIG_USB_DC2XX is not set +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_SCANNER is not set +# CONFIG_USB_MICROTEK is not set +# CONFIG_USB_HPUSBSCSI is not set + +# +# USB Multimedia devices +# + +# +# Video4Linux support is needed for USB Multimedia device support +# + +# +# USB Network adaptors +# +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_CATC is not set +# CONFIG_USB_CDCETHER is not set +# CONFIG_USB_USBNET is not set + +# +# USB port drivers +# +# CONFIG_USB_USS720 is not set + +# +# USB Serial Converter support +# +# CONFIG_USB_SERIAL is not set +# CONFIG_USB_SERIAL_GENERIC is not set +# CONFIG_USB_SERIAL_BELKIN is not set +# CONFIG_USB_SERIAL_WHITEHEAT is not set +# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set +# CONFIG_USB_SERIAL_EMPEG is not set +# CONFIG_USB_SERIAL_FTDI_SIO is not set +# CONFIG_USB_SERIAL_VISOR is not set +# CONFIG_USB_SERIAL_IPAQ is not set +# CONFIG_USB_SERIAL_IR is not set +# CONFIG_USB_SERIAL_EDGEPORT is not set +# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set +# CONFIG_USB_SERIAL_KEYSPAN is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set +# CONFIG_USB_SERIAL_MCT_U232 is not set +# CONFIG_USB_SERIAL_KLSI is not set +# CONFIG_USB_SERIAL_PL2303 is not set +# CONFIG_USB_SERIAL_CYBERJACK is not set +# CONFIG_USB_SERIAL_XIRCOM is not set +# CONFIG_USB_SERIAL_OMNINET is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_RIO500 is not set + +# +# Bluetooth support +# +# CONFIG_BLUEZ is not set + +# +# Kernel hacking +# +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_KGDB is not set +# CONFIG_XMON is not set +# CONFIG_BDI_SWITCH is not set +# CONFIG_SERIAL_TEXT_DEBUG is not set diff --git a/arch/ppc/configs/common_defconfig b/arch/ppc/configs/common_defconfig index 9d8bb2ccbd93..71e317246cdf 100644 --- a/arch/ppc/configs/common_defconfig +++ b/arch/ppc/configs/common_defconfig @@ -4,6 +4,7 @@ # CONFIG_UID16 is not set # CONFIG_RWSEM_GENERIC_SPINLOCK is not set CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_HAVE_DEC_LOCK=y # # Code maturity level options @@ -25,13 +26,27 @@ CONFIG_PPC32=y CONFIG_6xx=y # CONFIG_4xx is not set # CONFIG_POWER3 is not set -# CONFIG_POWER4 is not set # CONFIG_8xx is not set +# CONFIG_PPC_ISERIES is not set # CONFIG_8260 is not set CONFIG_PPC_STD_MMU=y CONFIG_ALL_PPC=y # CONFIG_APUS is not set +# CONFIG_SPRUCE is not set +# CONFIG_PCORE is not set +# CONFIG_POWERPMC250 is not set +# CONFIG_MENF1 is not set +# CONFIG_LOPEC is not set +# CONFIG_MCPN765 is not set +# CONFIG_MVME5100 is not set +# CONFIG_PRPMC750 is not set +# CONFIG_PRPMC800 is not set +# CONFIG_SANDPOINT is not set +# CONFIG_ADIR is not set +# CONFIG_K2 is not set # CONFIG_GEMINI is not set +# CONFIG_WILLOW is not set +# CONFIG_ZX4500 is not set # CONFIG_SMP is not set CONFIG_ALTIVEC=y CONFIG_TAU=y @@ -71,7 +86,6 @@ CONFIG_PPC_RTC=y CONFIG_PPC601_SYNC_FIX=y CONFIG_PROC_DEVICETREE=y CONFIG_PPC_RTAS=y -CONFIG_BOOTX_TEXT=y CONFIG_PREP_RESIDUAL=y CONFIG_CMDLINE_BOOL=y CONFIG_CMDLINE="console=ttyS0,9600 console=tty0 root=/dev/sda2" @@ -119,8 +133,6 @@ CONFIG_BLK_DEV_INITRD=y # CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set -CONFIG_NETLINK=y -# CONFIG_RTNETLINK is not set # CONFIG_NETLINK_DEV is not set CONFIG_NETFILTER=y # CONFIG_NETFILTER_DEBUG is not set @@ -133,6 +145,7 @@ CONFIG_IP_MULTICAST=y # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set # CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set # CONFIG_INET_ECN is not set CONFIG_SYN_COOKIES=y @@ -343,15 +356,11 @@ CONFIG_SCSI_ADVANSYS=m # CONFIG_SCSI_INIA100 is not set # CONFIG_SCSI_NCR53C406A is not set # CONFIG_SCSI_NCR53C7xx is not set -CONFIG_SCSI_NCR53C8XX=y -CONFIG_SCSI_SYM53C8XX=y -CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=8 -CONFIG_SCSI_NCR53C8XX_MAX_TAGS=32 -CONFIG_SCSI_NCR53C8XX_SYNC=20 -# CONFIG_SCSI_NCR53C8XX_PROFILE is not set -# CONFIG_SCSI_NCR53C8XX_IOMAPPED is not set -# CONFIG_SCSI_NCR53C8XX_PQS_PDS is not set -# CONFIG_SCSI_NCR53C8XX_SYMBIOS_COMPAT is not set +CONFIG_SCSI_SYM53C8XX_2=y +CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=0 +CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 +CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 +# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set # CONFIG_SCSI_PAS16 is not set # CONFIG_SCSI_PCI2000 is not set # CONFIG_SCSI_PCI2220I is not set @@ -388,7 +397,9 @@ CONFIG_NETDEVICES=y # # Appletalk devices # -# CONFIG_APPLETALK is not set +# CONFIG_LTPC is not set +# CONFIG_COPS is not set +# CONFIG_IPDDP is not set # CONFIG_DUMMY is not set # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set @@ -443,6 +454,7 @@ CONFIG_DE4X5=m # CONFIG_SUNDANCE is not set # CONFIG_TLAN is not set # CONFIG_VIA_RHINE is not set +# CONFIG_VIA_RHINE_MMIO is not set # CONFIG_WINBOND_840 is not set # CONFIG_NET_POCKET is not set @@ -544,6 +556,7 @@ CONFIG_FB_MATROX=y CONFIG_FB_MATROX_MILLENIUM=y CONFIG_FB_MATROX_MYSTIQUE=y # CONFIG_FB_MATROX_G100 is not set +# CONFIG_FB_MATROX_I2C is not set # CONFIG_FB_MATROX_G450 is not set # CONFIG_FB_MATROX_MULTIHEAD is not set CONFIG_FB_ATY=y @@ -587,8 +600,10 @@ CONFIG_INPUT_EVDEV=y # CONFIG_ADB_CUDA=y CONFIG_ADB_PMU=y -# CONFIG_PMAC_PBOOK is not set -# CONFIG_PMAC_BACKLIGHT is not set +CONFIG_PMAC_PBOOK=y +CONFIG_PM=y +CONFIG_PMAC_APM_EMU=y +CONFIG_PMAC_BACKLIGHT=y # CONFIG_MAC_FLOPPY is not set CONFIG_MAC_SERIAL=m CONFIG_ADB=y @@ -597,6 +612,7 @@ CONFIG_INPUT_ADBHID=y CONFIG_MAC_ADBKEYCODES=y CONFIG_MAC_EMUMOUSEBTN=y CONFIG_MAC_HID=y +# CONFIG_ANSLCD is not set # # Character devices @@ -612,7 +628,12 @@ CONFIG_UNIX98_PTY_COUNT=256 # # I2C support # -# CONFIG_I2C is not set +CONFIG_I2C=m +# CONFIG_I2C_ALGOBIT is not set +# CONFIG_I2C_ALGOPCF is not set +CONFIG_I2C_KEYWEST=m +CONFIG_I2C_CHARDEV=m +CONFIG_I2C_PROC=m # # Mice @@ -693,11 +714,15 @@ CONFIG_NVRAM=y # CONFIG_AUTOFS4_FS is not set # CONFIG_REISERFS_FS is not set # CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set # CONFIG_ADFS_FS is not set # CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set CONFIG_HFS_FS=m # CONFIG_BFS_FS is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_JBD_DEBUG is not set CONFIG_FAT_FS=m CONFIG_MSDOS_FS=m # CONFIG_UMSDOS_FS is not set @@ -710,6 +735,7 @@ CONFIG_TMPFS=y # CONFIG_RAMFS is not set CONFIG_ISO9660_FS=y # CONFIG_JOLIET is not set +# CONFIG_ZISOFS is not set # CONFIG_MINIX_FS is not set # CONFIG_VXFS_FS is not set # CONFIG_NTFS_FS is not set @@ -734,13 +760,15 @@ CONFIG_EXT2_FS=y # Network File Systems # # CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set CONFIG_NFS_FS=y -# CONFIG_NFS_V3 is not set +CONFIG_NFS_V3=y # CONFIG_ROOT_NFS is not set CONFIG_NFSD=y -# CONFIG_NFSD_V3 is not set +CONFIG_NFSD_V3=y CONFIG_SUNRPC=y CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y # CONFIG_SMB_FS is not set # CONFIG_NCP_FS is not set # CONFIG_NCPFS_PACKET_SIGNING is not set @@ -751,6 +779,8 @@ CONFIG_LOCKD=y # CONFIG_NCPFS_SMALLDOS is not set # CONFIG_NCPFS_NLS is not set # CONFIG_NCPFS_EXTRAS is not set +# CONFIG_ZISOFS_FS is not set +# CONFIG_ZLIB_FS_INFLATE is not set # # Partition Types @@ -818,8 +848,10 @@ CONFIG_NLS_ISO8859_1=m # Sound # CONFIG_SOUND=m -CONFIG_DMASOUND_AWACS=m +CONFIG_DMASOUND_PMAC=m CONFIG_DMASOUND=m +CONFIG_I2C=m +CONFIG_I2C_KEYWEST=m # CONFIG_SOUND_BT878 is not set # CONFIG_SOUND_CMPCI is not set # CONFIG_SOUND_EMU10K1 is not set @@ -854,7 +886,6 @@ CONFIG_USB=y CONFIG_USB_DEVICEFS=y # CONFIG_USB_BANDWIDTH is not set # CONFIG_USB_LONG_TIMEOUT is not set -# CONFIG_USB_LARGE_CONFIG is not set # # USB Controllers @@ -868,12 +899,12 @@ CONFIG_USB_OHCI=y # # CONFIG_USB_AUDIO is not set # CONFIG_USB_BLUETOOTH is not set -# CONFIG_USB_STORAGE is not set +CONFIG_USB_STORAGE=m # CONFIG_USB_STORAGE_DEBUG is not set # CONFIG_USB_STORAGE_DATAFAB is not set -# CONFIG_USB_STORAGE_FREECOM is not set +CONFIG_USB_STORAGE_FREECOM=y # CONFIG_USB_STORAGE_ISD200 is not set -# CONFIG_USB_STORAGE_DPCM is not set +CONFIG_USB_STORAGE_DPCM=y # CONFIG_USB_STORAGE_HP8200e is not set # CONFIG_USB_STORAGE_SDDR09 is not set # CONFIG_USB_STORAGE_JUMPSHOT is not set @@ -932,15 +963,15 @@ CONFIG_USB_SERIAL_VISOR=m # CONFIG_USB_SERIAL_IR is not set # CONFIG_USB_SERIAL_EDGEPORT is not set # CONFIG_USB_SERIAL_KEYSPAN_PDA is not set -# CONFIG_USB_SERIAL_KEYSPAN is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set +CONFIG_USB_SERIAL_KEYSPAN=m +CONFIG_USB_SERIAL_KEYSPAN_USA28=y +CONFIG_USB_SERIAL_KEYSPAN_USA28X=y # CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set # CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set +CONFIG_USB_SERIAL_KEYSPAN_USA19=y +CONFIG_USB_SERIAL_KEYSPAN_USA18X=y +CONFIG_USB_SERIAL_KEYSPAN_USA19W=y +CONFIG_USB_SERIAL_KEYSPAN_USA49W=y # CONFIG_USB_SERIAL_MCT_U232 is not set # CONFIG_USB_SERIAL_PL2303 is not set # CONFIG_USB_SERIAL_CYBERJACK is not set @@ -963,3 +994,5 @@ CONFIG_USB_SERIAL_VISOR=m CONFIG_MAGIC_SYSRQ=y # CONFIG_KGDB is not set CONFIG_XMON=y +# CONFIG_BDI_SWITCH is not set +CONFIG_BOOTX_TEXT=y diff --git a/arch/ppc/configs/cpci405_defconfig b/arch/ppc/configs/cpci405_defconfig new file mode 100644 index 000000000000..ad2f34b5ac19 --- /dev/null +++ b/arch/ppc/configs/cpci405_defconfig @@ -0,0 +1,646 @@ +# +# Automatically generated make config: don't edit +# +# CONFIG_UID16 is not set +# CONFIG_RWSEM_GENERIC_SPINLOCK is not set +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_HAVE_DEC_LOCK=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODVERSIONS is not set +CONFIG_KMOD=y + +# +# Platform support +# +CONFIG_PPC=y +CONFIG_PPC32=y +# CONFIG_6xx is not set +CONFIG_4xx=y +# CONFIG_POWER3 is not set +# CONFIG_8xx is not set +# CONFIG_PPC_ISERIES is not set +# CONFIG_PPC_STD_MMU is not set +# CONFIG_CEDER is not set +CONFIG_CPCI405=y +# CONFIG_EP405 is not set +# CONFIG_OAK is not set +# CONFIG_REDWOOD_4 is not set +# CONFIG_REDWOOD_5 is not set +# CONFIG_TIVO is not set +# CONFIG_WALNUT is not set +# CONFIG_ALL_PPC is not set +# CONFIG_SMP is not set +# CONFIG_MATH_EMULATION is not set +CONFIG_405GP=y +CONFIG_IBM405_ERR77=y +CONFIG_IBM_OCP=y +# CONFIG_405_DMA is not set +CONFIG_UART0_TTYS0=y +# CONFIG_UART0_TTYS1 is not set +CONFIG_IBM405_ERR51=y +CONFIG_NOT_COHERENT_CACHE=y + +# +# General setup +# +# CONFIG_HIGHMEM is not set +# CONFIG_ISA is not set +# CONFIG_EISA is not set +# CONFIG_SBUS is not set +# CONFIG_MCA is not set +CONFIG_PCI=y +# CONFIG_PC_KEYBOARD is not set +CONFIG_NET=y +CONFIG_SYSCTL=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_KCORE_ELF=y +CONFIG_BINFMT_ELF=y +CONFIG_KERNEL_ELF=y +# CONFIG_BINFMT_MISC is not set +# CONFIG_PCI_NAMES is not set +# CONFIG_HOTPLUG is not set +# CONFIG_PCMCIA is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set +# CONFIG_PPC_RTC is not set +# CONFIG_CMDLINE_BOOL is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Plug and Play configuration +# +# CONFIG_PNP is not set +# CONFIG_ISAPNP is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_XD is not set +# CONFIG_PARIDE is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_INITRD=y + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set +# CONFIG_BLK_DEV_MD is not set +# CONFIG_MD_LINEAR is not set +# CONFIG_MD_RAID0 is not set +# CONFIG_MD_RAID1 is not set +# CONFIG_MD_RAID5 is not set +# CONFIG_MD_MULTIPATH is not set +# CONFIG_BLK_DEV_LVM is not set + +# +# Networking options +# +# CONFIG_PACKET is not set +# CONFIG_NETLINK_DEV is not set +# CONFIG_NETFILTER is not set +# CONFIG_FILTER is not set +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +CONFIG_IP_PNP_RARP=y +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_INET_ECN is not set +CONFIG_SYN_COOKIES=y +# CONFIG_IPV6 is not set +# CONFIG_KHTTPD is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set + +# +# +# +# CONFIG_IPX is not set +# CONFIG_ATALK is not set + +# +# Appletalk devices +# +# CONFIG_DEV_APPLETALK is not set +# CONFIG_LTPC is not set +# CONFIG_COPS is not set +# CONFIG_COPS_DAYNA is not set +# CONFIG_COPS_TANGENT is not set +# CONFIG_IPDDP is not set +# CONFIG_IPDDP_ENCAP is not set +# CONFIG_IPDDP_DECAP is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# ATA/IDE/MFM/RLL support +# +CONFIG_IDE=y + +# +# IDE, ATA and ATAPI Block devices +# +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_HD_IDE is not set +# CONFIG_BLK_DEV_HD is not set +CONFIG_BLK_DEV_IDEDISK=y +# CONFIG_IDEDISK_MULTI_MODE is not set +# CONFIG_BLK_DEV_IDEDISK_VENDOR is not set +# CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set +# CONFIG_BLK_DEV_IDEDISK_IBM is not set +# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set +# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set +# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set +# CONFIG_BLK_DEV_IDEDISK_WD is not set +# CONFIG_BLK_DEV_COMMERIAL is not set +# CONFIG_BLK_DEV_TIVO is not set +# CONFIG_BLK_DEV_IDECS is not set +# CONFIG_BLK_DEV_IDECD is not set +# CONFIG_BLK_DEV_IDETAPE is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set +# CONFIG_BLK_DEV_IDESCSI is not set + +# +# IDE chipset support/bugfixes +# +# CONFIG_BLK_DEV_CMD640 is not set +# CONFIG_BLK_DEV_CMD640_ENHANCED is not set +# CONFIG_BLK_DEV_ISAPNP is not set +# CONFIG_BLK_DEV_RZ1000 is not set +# CONFIG_BLK_DEV_IDEPCI is not set +# CONFIG_BLK_DEV_SL82C105 is not set +CONFIG_BLK_DEV_CPCI405_IDE=y +# CONFIG_IDE_CHIPSETS is not set +# CONFIG_IDEDMA_AUTO is not set +# CONFIG_DMA_NONPCI is not set +# CONFIG_BLK_DEV_IDE_MODES is not set +# CONFIG_BLK_DEV_ATARAID is not set +# CONFIG_BLK_DEV_ATARAID_PDC is not set +# CONFIG_BLK_DEV_ATARAID_HPT is not set + +# +# SCSI support +# +# CONFIG_SCSI is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set +# CONFIG_FUSION_BOOT is not set +# CONFIG_FUSION_ISENSE is not set +# CONFIG_FUSION_CTL is not set +# CONFIG_FUSION_LAN is not set + +# +# IEEE 1394 (FireWire) support (EXPERIMENTAL) +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# +# CONFIG_I2O is not set +# CONFIG_I2O_PCI is not set +# CONFIG_I2O_BLOCK is not set +# CONFIG_I2O_LAN is not set +# CONFIG_I2O_SCSI is not set +# CONFIG_I2O_PROC is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_MACE is not set +# CONFIG_BMAC is not set +# CONFIG_GMAC is not set +CONFIG_IBM_OCP_ENET=y +# CONFIG_IBM_OCP_ENET_ERROR_MSG is not set +CONFIG_IBM_OCP_ENET_RX_BUFF=64 +CONFIG_IBM_OCP_ENET_TX_BUFF=8 +CONFIG_IBM_OCP_ENET_GAP=8 +# CONFIG_SUNLANCE is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNBMAC is not set +# CONFIG_SUNQE is not set +# CONFIG_SUNLANCE is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_HP100 is not set +# CONFIG_NET_ISA is not set +# CONFIG_NET_PCI is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_MYRI_SBUS is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_SK98LIN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Old CD-ROM drivers (not SCSI, not IDE) +# +# CONFIG_CD_NO_IDESCSI is not set + +# +# Console drivers +# + +# +# Frame-buffer support +# +# CONFIG_FB is not set + +# +# Input core support +# +# CONFIG_INPUT is not set +# CONFIG_INPUT_KEYBDEV is not set +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set + +# +# Macintosh device drivers +# + +# +# Character devices +# +# CONFIG_VT is not set +CONFIG_SERIAL=y +CONFIG_SERIAL_CONSOLE=y +# CONFIG_SERIAL_EXTENDED is not set +# CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_UNIX98_PTYS is not set + +# +# I2C support +# +CONFIG_I2C=y +# CONFIG_I2C_ALGOBIT is not set +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_CHARDEV is not set +# CONFIG_I2C_PROC is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set + +# +# Joysticks +# +# CONFIG_INPUT_GAMEPORT is not set + +# +# Input core support is needed for gameports +# + +# +# Input core support is needed for joysticks +# +# CONFIG_QIC02_TAPE is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_INTEL_RNG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set +CONFIG_PPC405_GPIO=y + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set +# CONFIG_ADFS_FS is not set +# CONFIG_ADFS_FS_RW is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_JBD_DEBUG is not set +# CONFIG_FAT_FS is not set +# CONFIG_MSDOS_FS is not set +# CONFIG_UMSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_CRAMFS is not set +CONFIG_TMPFS=y +# CONFIG_RAMFS is not set +# CONFIG_ISO9660_FS is not set +# CONFIG_JOLIET is not set +# CONFIG_ZISOFS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_NTFS_FS is not set +# CONFIG_NTFS_RW is not set +# CONFIG_HPFS_FS is not set +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVFS_MOUNT is not set +# CONFIG_DEVFS_DEBUG is not set +# CONFIG_DEVPTS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set +# CONFIG_ROMFS_FS is not set +CONFIG_EXT2_FS=y +# CONFIG_SYSV_FS is not set +# CONFIG_UDF_FS is not set +# CONFIG_UDF_RW is not set +# CONFIG_UFS_FS is not set +# CONFIG_UFS_FS_WRITE is not set + +# +# Network File Systems +# +# CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +CONFIG_ROOT_NFS=y +# CONFIG_NFSD is not set +# CONFIG_NFSD_V3 is not set +CONFIG_SUNRPC=y +CONFIG_LOCKD=y +# CONFIG_SMB_FS is not set +# CONFIG_NCP_FS is not set +# CONFIG_NCPFS_PACKET_SIGNING is not set +# CONFIG_NCPFS_IOCTL_LOCKING is not set +# CONFIG_NCPFS_STRONG is not set +# CONFIG_NCPFS_NFS_NS is not set +# CONFIG_NCPFS_OS2_NS is not set +# CONFIG_NCPFS_SMALLDOS is not set +# CONFIG_NCPFS_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set +# CONFIG_ZISOFS_FS is not set +# CONFIG_ZLIB_FS_INFLATE is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_SMB_NLS is not set +# CONFIG_NLS is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# MPC4xx Driver Options +# + +# +# USB support +# +# CONFIG_USB is not set + +# +# USB Controllers +# +# CONFIG_USB_UHCI is not set +# CONFIG_USB_UHCI_ALT is not set +# CONFIG_USB_OHCI is not set + +# +# USB Device Class drivers +# +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_BLUETOOTH is not set +# CONFIG_USB_STORAGE is not set +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_HP8200e is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set + +# +# USB Human Interface Devices (HID) +# + +# +# Input core support is needed for USB HID +# + +# +# USB Imaging devices +# +# CONFIG_USB_DC2XX is not set +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_SCANNER is not set +# CONFIG_USB_MICROTEK is not set +# CONFIG_USB_HPUSBSCSI is not set + +# +# USB Multimedia devices +# + +# +# Video4Linux support is needed for USB Multimedia device support +# + +# +# USB Network adaptors +# +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_CATC is not set +# CONFIG_USB_CDCETHER is not set +# CONFIG_USB_USBNET is not set + +# +# USB port drivers +# +# CONFIG_USB_USS720 is not set + +# +# USB Serial Converter support +# +# CONFIG_USB_SERIAL is not set +# CONFIG_USB_SERIAL_GENERIC is not set +# CONFIG_USB_SERIAL_BELKIN is not set +# CONFIG_USB_SERIAL_WHITEHEAT is not set +# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set +# CONFIG_USB_SERIAL_EMPEG is not set +# CONFIG_USB_SERIAL_FTDI_SIO is not set +# CONFIG_USB_SERIAL_VISOR is not set +# CONFIG_USB_SERIAL_IPAQ is not set +# CONFIG_USB_SERIAL_IR is not set +# CONFIG_USB_SERIAL_EDGEPORT is not set +# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set +# CONFIG_USB_SERIAL_KEYSPAN is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set +# CONFIG_USB_SERIAL_MCT_U232 is not set +# CONFIG_USB_SERIAL_KLSI is not set +# CONFIG_USB_SERIAL_PL2303 is not set +# CONFIG_USB_SERIAL_CYBERJACK is not set +# CONFIG_USB_SERIAL_XIRCOM is not set +# CONFIG_USB_SERIAL_OMNINET is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_RIO500 is not set + +# +# Bluetooth support +# +# CONFIG_BLUEZ is not set + +# +# Kernel hacking +# +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_KGDB is not set +# CONFIG_XMON is not set +# CONFIG_BDI_SWITCH is not set +# CONFIG_SERIAL_TEXT_DEBUG is not set diff --git a/arch/ppc/configs/ep405_defconfig b/arch/ppc/configs/ep405_defconfig new file mode 100644 index 000000000000..05e8874cd92c --- /dev/null +++ b/arch/ppc/configs/ep405_defconfig @@ -0,0 +1,605 @@ +# +# Automatically generated make config: don't edit +# +# CONFIG_UID16 is not set +# CONFIG_RWSEM_GENERIC_SPINLOCK is not set +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_HAVE_DEC_LOCK=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODVERSIONS=y +CONFIG_KMOD=y + +# +# Platform support +# +CONFIG_PPC=y +CONFIG_PPC32=y +# CONFIG_6xx is not set +CONFIG_4xx=y +# CONFIG_POWER3 is not set +# CONFIG_8xx is not set +# CONFIG_PPC_ISERIES is not set +# CONFIG_PPC_STD_MMU is not set +# CONFIG_CEDER is not set +# CONFIG_CPCI405 is not set +CONFIG_EP405=y +# CONFIG_OAK is not set +# CONFIG_REDWOOD_4 is not set +# CONFIG_REDWOOD_5 is not set +# CONFIG_TIVO is not set +# CONFIG_WALNUT is not set +# CONFIG_ALL_PPC is not set +# CONFIG_SMP is not set +# CONFIG_MATH_EMULATION is not set +CONFIG_405GP=y +CONFIG_BIOS_FIXUP=y +CONFIG_EMBEDDEDBOOT=y +CONFIG_IBM405_ERR77=y +CONFIG_IBM_OCP=y +# CONFIG_405_DMA is not set +CONFIG_UART0_TTYS0=y +# CONFIG_UART0_TTYS1 is not set +CONFIG_IBM405_ERR51=y +CONFIG_NOT_COHERENT_CACHE=y + +# +# General setup +# +# CONFIG_HIGHMEM is not set +# CONFIG_ISA is not set +# CONFIG_EISA is not set +# CONFIG_SBUS is not set +# CONFIG_MCA is not set +CONFIG_PCI=y +# CONFIG_PC_KEYBOARD is not set +CONFIG_NET=y +CONFIG_SYSCTL=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_KCORE_ELF=y +CONFIG_BINFMT_ELF=y +CONFIG_KERNEL_ELF=y +# CONFIG_BINFMT_MISC is not set +# CONFIG_PCI_NAMES is not set +# CONFIG_HOTPLUG is not set +# CONFIG_PCMCIA is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set +# CONFIG_PPC_RTC is not set +# CONFIG_CMDLINE_BOOL is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Plug and Play configuration +# +# CONFIG_PNP is not set +# CONFIG_ISAPNP is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_XD is not set +# CONFIG_PARIDE is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_INITRD=y + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set +# CONFIG_BLK_DEV_MD is not set +# CONFIG_MD_LINEAR is not set +# CONFIG_MD_RAID0 is not set +# CONFIG_MD_RAID1 is not set +# CONFIG_MD_RAID5 is not set +# CONFIG_MD_MULTIPATH is not set +# CONFIG_BLK_DEV_LVM is not set + +# +# Networking options +# +# CONFIG_PACKET is not set +# CONFIG_NETLINK_DEV is not set +# CONFIG_NETFILTER is not set +# CONFIG_FILTER is not set +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +CONFIG_IP_PNP_RARP=y +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_INET_ECN is not set +CONFIG_SYN_COOKIES=y +# CONFIG_IPV6 is not set +# CONFIG_KHTTPD is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set + +# +# +# +# CONFIG_IPX is not set +# CONFIG_ATALK is not set + +# +# Appletalk devices +# +# CONFIG_DEV_APPLETALK is not set +# CONFIG_LTPC is not set +# CONFIG_COPS is not set +# CONFIG_COPS_DAYNA is not set +# CONFIG_COPS_TANGENT is not set +# CONFIG_IPDDP is not set +# CONFIG_IPDDP_ENCAP is not set +# CONFIG_IPDDP_DECAP is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# ATA/IDE/MFM/RLL support +# +# CONFIG_IDE is not set +# CONFIG_BLK_DEV_IDE_MODES is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI support +# +# CONFIG_SCSI is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set +# CONFIG_FUSION_BOOT is not set +# CONFIG_FUSION_ISENSE is not set +# CONFIG_FUSION_CTL is not set +# CONFIG_FUSION_LAN is not set + +# +# IEEE 1394 (FireWire) support (EXPERIMENTAL) +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# +# CONFIG_I2O is not set +# CONFIG_I2O_PCI is not set +# CONFIG_I2O_BLOCK is not set +# CONFIG_I2O_LAN is not set +# CONFIG_I2O_SCSI is not set +# CONFIG_I2O_PROC is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_MACE is not set +# CONFIG_BMAC is not set +# CONFIG_GMAC is not set +CONFIG_IBM_OCP_ENET=y +# CONFIG_IBM_OCP_ENET_ERROR_MSG is not set +CONFIG_IBM_OCP_ENET_RX_BUFF=64 +CONFIG_IBM_OCP_ENET_TX_BUFF=8 +CONFIG_IBM_OCP_ENET_GAP=8 +# CONFIG_SUNLANCE is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNBMAC is not set +# CONFIG_SUNQE is not set +# CONFIG_SUNLANCE is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_HP100 is not set +# CONFIG_NET_ISA is not set +# CONFIG_NET_PCI is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_MYRI_SBUS is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_SK98LIN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Old CD-ROM drivers (not SCSI, not IDE) +# +# CONFIG_CD_NO_IDESCSI is not set + +# +# Console drivers +# + +# +# Frame-buffer support +# +# CONFIG_FB is not set + +# +# Input core support +# +# CONFIG_INPUT is not set +# CONFIG_INPUT_KEYBDEV is not set +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set + +# +# Macintosh device drivers +# + +# +# Character devices +# +# CONFIG_VT is not set +CONFIG_SERIAL=y +CONFIG_SERIAL_CONSOLE=y +# CONFIG_SERIAL_EXTENDED is not set +# CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_UNIX98_PTYS is not set + +# +# I2C support +# +CONFIG_I2C=y +# CONFIG_I2C_ALGOBIT is not set +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_CHARDEV is not set +# CONFIG_I2C_PROC is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set + +# +# Joysticks +# +# CONFIG_INPUT_GAMEPORT is not set + +# +# Input core support is needed for gameports +# + +# +# Input core support is needed for joysticks +# +# CONFIG_QIC02_TAPE is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_INTEL_RNG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set +# CONFIG_PPC405_GPIO is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set +# CONFIG_ADFS_FS is not set +# CONFIG_ADFS_FS_RW is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_JBD_DEBUG is not set +# CONFIG_FAT_FS is not set +# CONFIG_MSDOS_FS is not set +# CONFIG_UMSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_CRAMFS is not set +CONFIG_TMPFS=y +# CONFIG_RAMFS is not set +# CONFIG_ISO9660_FS is not set +# CONFIG_JOLIET is not set +# CONFIG_ZISOFS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_NTFS_FS is not set +# CONFIG_NTFS_RW is not set +# CONFIG_HPFS_FS is not set +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVFS_MOUNT is not set +# CONFIG_DEVFS_DEBUG is not set +# CONFIG_DEVPTS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set +# CONFIG_ROMFS_FS is not set +CONFIG_EXT2_FS=y +# CONFIG_SYSV_FS is not set +# CONFIG_UDF_FS is not set +# CONFIG_UDF_RW is not set +# CONFIG_UFS_FS is not set +# CONFIG_UFS_FS_WRITE is not set + +# +# Network File Systems +# +# CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +CONFIG_ROOT_NFS=y +# CONFIG_NFSD is not set +# CONFIG_NFSD_V3 is not set +CONFIG_SUNRPC=y +CONFIG_LOCKD=y +# CONFIG_SMB_FS is not set +# CONFIG_NCP_FS is not set +# CONFIG_NCPFS_PACKET_SIGNING is not set +# CONFIG_NCPFS_IOCTL_LOCKING is not set +# CONFIG_NCPFS_STRONG is not set +# CONFIG_NCPFS_NFS_NS is not set +# CONFIG_NCPFS_OS2_NS is not set +# CONFIG_NCPFS_SMALLDOS is not set +# CONFIG_NCPFS_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set +# CONFIG_ZISOFS_FS is not set +# CONFIG_ZLIB_FS_INFLATE is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_SMB_NLS is not set +# CONFIG_NLS is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# MPC4xx Driver Options +# + +# +# USB support +# +# CONFIG_USB is not set + +# +# USB Controllers +# +# CONFIG_USB_UHCI is not set +# CONFIG_USB_UHCI_ALT is not set +# CONFIG_USB_OHCI is not set + +# +# USB Device Class drivers +# +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_BLUETOOTH is not set +# CONFIG_USB_STORAGE is not set +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_HP8200e is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set + +# +# USB Human Interface Devices (HID) +# + +# +# Input core support is needed for USB HID +# + +# +# USB Imaging devices +# +# CONFIG_USB_DC2XX is not set +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_SCANNER is not set +# CONFIG_USB_MICROTEK is not set +# CONFIG_USB_HPUSBSCSI is not set + +# +# USB Multimedia devices +# + +# +# Video4Linux support is needed for USB Multimedia device support +# + +# +# USB Network adaptors +# +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_CATC is not set +# CONFIG_USB_CDCETHER is not set +# CONFIG_USB_USBNET is not set + +# +# USB port drivers +# +# CONFIG_USB_USS720 is not set + +# +# USB Serial Converter support +# +# CONFIG_USB_SERIAL is not set +# CONFIG_USB_SERIAL_GENERIC is not set +# CONFIG_USB_SERIAL_BELKIN is not set +# CONFIG_USB_SERIAL_WHITEHEAT is not set +# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set +# CONFIG_USB_SERIAL_EMPEG is not set +# CONFIG_USB_SERIAL_FTDI_SIO is not set +# CONFIG_USB_SERIAL_VISOR is not set +# CONFIG_USB_SERIAL_IPAQ is not set +# CONFIG_USB_SERIAL_IR is not set +# CONFIG_USB_SERIAL_EDGEPORT is not set +# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set +# CONFIG_USB_SERIAL_KEYSPAN is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set +# CONFIG_USB_SERIAL_MCT_U232 is not set +# CONFIG_USB_SERIAL_KLSI is not set +# CONFIG_USB_SERIAL_PL2303 is not set +# CONFIG_USB_SERIAL_CYBERJACK is not set +# CONFIG_USB_SERIAL_XIRCOM is not set +# CONFIG_USB_SERIAL_OMNINET is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_RIO500 is not set + +# +# Bluetooth support +# +# CONFIG_BLUEZ is not set + +# +# Kernel hacking +# +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_KGDB is not set +# CONFIG_XMON is not set +# CONFIG_BDI_SWITCH is not set +# CONFIG_SERIAL_TEXT_DEBUG is not set diff --git a/arch/ppc/configs/est8260_defconfig b/arch/ppc/configs/est8260_defconfig index 981aa2d0297b..ac028b821836 100644 --- a/arch/ppc/configs/est8260_defconfig +++ b/arch/ppc/configs/est8260_defconfig @@ -23,7 +23,6 @@ CONFIG_PPC32=y CONFIG_6xx=y # CONFIG_4xx is not set # CONFIG_POWER3 is not set -# CONFIG_POWER4 is not set # CONFIG_8xx is not set CONFIG_8260=y CONFIG_PPC_STD_MMU=y diff --git a/arch/ppc/configs/ev64260_defconfig b/arch/ppc/configs/ev64260_defconfig new file mode 100644 index 000000000000..93ec6316e224 --- /dev/null +++ b/arch/ppc/configs/ev64260_defconfig @@ -0,0 +1,607 @@ +# +# Automatically generated by make menuconfig: don't edit +# +# CONFIG_UID16 is not set +# CONFIG_RWSEM_GENERIC_SPINLOCK is not set +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_HAVE_DEC_LOCK=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +# CONFIG_ADVANCED_OPTIONS is not set + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODVERSIONS=y +CONFIG_KMOD=y + +# +# Platform support +# +CONFIG_PPC=y +CONFIG_PPC32=y +CONFIG_6xx=y +# CONFIG_4xx is not set +# CONFIG_POWER3 is not set +# CONFIG_8xx is not set +# CONFIG_PPC_ISERIES is not set +# CONFIG_8260 is not set +CONFIG_PPC_STD_MMU=y +# CONFIG_ALL_PPC is not set +# CONFIG_APUS is not set +# CONFIG_WILLOW is not set +# CONFIG_PCORE is not set +# CONFIG_POWERPMC250 is not set +CONFIG_EV64260=y +# CONFIG_SPRUCE is not set +# CONFIG_MENF1 is not set +# CONFIG_LOPEC is not set +# CONFIG_MCPN765 is not set +# CONFIG_MVME5100 is not set +# CONFIG_PPLUS is not set +# CONFIG_PRPMC750 is not set +# CONFIG_PRPMC800 is not set +# CONFIG_SANDPOINT is not set +# CONFIG_ADIR is not set +# CONFIG_K2 is not set +# CONFIG_GEMINI is not set +# CONFIG_ZX4500 is not set +CONFIG_GT64260=y +CONFIG_SERIAL_CONSOLE_BAUD=115200 + +# +# Galileo GT64260 Options +# +CONFIG_GT64260_ETH=y +CONFIG_GT64260_ETH_0=y +CONFIG_GT64260_ETH_0_MACADDR="feffff000000" +CONFIG_GT64260_ETH_1=y +CONFIG_GT64260_ETH_1_MACADDR="feffff000001" +CONFIG_GT64260_ETH_2=y +CONFIG_GT64260_ETH_2_MACADDR="feffff000002" +# CONFIG_GT64260_MPSC is not set +# CONFIG_SMP is not set +CONFIG_ALTIVEC=y +CONFIG_TAU=y +# CONFIG_TAU_INT is not set +# CONFIG_TAU_AVERAGE is not set + +# +# General setup +# +# CONFIG_HIGHMEM is not set +# CONFIG_ISA is not set +# CONFIG_EISA is not set +# CONFIG_SBUS is not set +# CONFIG_MCA is not set +CONFIG_PCI=y +CONFIG_NET=y +CONFIG_SYSCTL=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_KCORE_ELF=y +CONFIG_BINFMT_ELF=y +CONFIG_KERNEL_ELF=y +CONFIG_BINFMT_MISC=y +CONFIG_PCI_NAMES=y +# CONFIG_HOTPLUG is not set +# CONFIG_PCMCIA is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set +CONFIG_PPC_RTC=y +CONFIG_CMDLINE_BOOL=y +CONFIG_CMDLINE="console=ttyS0,115200 ip=on" + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Plug and Play configuration +# +# CONFIG_PNP is not set +# CONFIG_ISAPNP is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_XD is not set +# CONFIG_PARIDE is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_INITRD=y + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set +# CONFIG_BLK_DEV_MD is not set +# CONFIG_MD_LINEAR is not set +# CONFIG_MD_RAID0 is not set +# CONFIG_MD_RAID1 is not set +# CONFIG_MD_RAID5 is not set +# CONFIG_MD_MULTIPATH is not set +# CONFIG_BLK_DEV_LVM is not set + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +# CONFIG_NETLINK_DEV is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +# CONFIG_FILTER is not set +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +# CONFIG_IP_PNP_BOOTP is not set +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_INET_ECN is not set +CONFIG_SYN_COOKIES=y + +# +# IP: Netfilter Configuration +# +# CONFIG_IP_NF_CONNTRACK is not set +# CONFIG_IP_NF_QUEUE is not set +# CONFIG_IP_NF_IPTABLES is not set +# CONFIG_IP_NF_COMPAT_IPCHAINS is not set +# CONFIG_IP_NF_COMPAT_IPFWADM is not set +# CONFIG_IPV6 is not set +# CONFIG_KHTTPD is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set + +# +# Appletalk devices +# +# CONFIG_DEV_APPLETALK is not set +# CONFIG_LTPC is not set +# CONFIG_COPS is not set +# CONFIG_COPS_DAYNA is not set +# CONFIG_COPS_TANGENT is not set +# CONFIG_IPDDP is not set +# CONFIG_IPDDP_ENCAP is not set +# CONFIG_IPDDP_DECAP is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# ATA/IDE/MFM/RLL support +# +# CONFIG_IDE is not set +# CONFIG_BLK_DEV_IDE_MODES is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI support +# +# CONFIG_SCSI is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set +# CONFIG_FUSION_BOOT is not set +# CONFIG_FUSION_ISENSE is not set +# CONFIG_FUSION_CTL is not set +# CONFIG_FUSION_LAN is not set + +# +# IEEE 1394 (FireWire) support (EXPERIMENTAL) +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# +# CONFIG_I2O is not set +# CONFIG_I2O_PCI is not set +# CONFIG_I2O_BLOCK is not set +# CONFIG_I2O_LAN is not set +# CONFIG_I2O_SCSI is not set +# CONFIG_I2O_PROC is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_MACE is not set +# CONFIG_BMAC is not set +# CONFIG_GMAC is not set +# CONFIG_SUNLANCE is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNBMAC is not set +# CONFIG_SUNQE is not set +# CONFIG_SUNLANCE is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_HP100 is not set +# CONFIG_NET_ISA is not set +CONFIG_NET_PCI=y +# CONFIG_PCNET32 is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_APRICOT is not set +# CONFIG_CS89x0 is not set +CONFIG_TULIP=y +# CONFIG_TULIP_MWI is not set +# CONFIG_TULIP_MMIO is not set +# CONFIG_DE4X5 is not set +# CONFIG_DGRS is not set +# CONFIG_DM9102 is not set +CONFIG_EEPRO100=y +# CONFIG_LNE390 is not set +# CONFIG_FEALNX is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_NE3210 is not set +# CONFIG_ES3210 is not set +# CONFIG_8139CP is not set +# CONFIG_8139TOO is not set +# CONFIG_8139TOO_PIO is not set +# CONFIG_8139TOO_TUNE_TWISTER is not set +# CONFIG_8139TOO_8129 is not set +# CONFIG_8139_NEW_RX_RESET is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_TLAN is not set +# CONFIG_VIA_RHINE is not set +# CONFIG_VIA_RHINE_MMIO is not set +# CONFIG_WINBOND_840 is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_MYRI_SBUS is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_SK98LIN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Old CD-ROM drivers (not SCSI, not IDE) +# +# CONFIG_CD_NO_IDESCSI is not set + +# +# Console drivers +# +# CONFIG_VGA_CONSOLE is not set + +# +# Frame-buffer support +# +# CONFIG_FB is not set + +# +# Input core support +# +# CONFIG_INPUT is not set +# CONFIG_INPUT_KEYBDEV is not set +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set + +# +# Macintosh device drivers +# + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_SERIAL_CONSOLE=y +# CONFIG_SERIAL_EXTENDED is not set +# CONFIG_SERIAL_NONSTANDARD is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 + +# +# I2C support +# +CONFIG_I2C=m +# CONFIG_I2C_ALGOBIT is not set +# CONFIG_I2C_ALGOPCF is not set +CONFIG_I2C_CHARDEV=m +CONFIG_I2C_PROC=m + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set + +# +# Joysticks +# +# CONFIG_INPUT_GAMEPORT is not set +# CONFIG_QIC02_TAPE is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_INTEL_RNG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set +# CONFIG_ADFS_FS is not set +# CONFIG_ADFS_FS_RW is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_JBD_DEBUG is not set +# CONFIG_FAT_FS is not set +# CONFIG_MSDOS_FS is not set +# CONFIG_UMSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_CRAMFS is not set +CONFIG_TMPFS=y +CONFIG_RAMFS=y +# CONFIG_ISO9660_FS is not set +# CONFIG_JOLIET is not set +# CONFIG_ZISOFS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_NTFS_FS is not set +# CONFIG_NTFS_RW is not set +# CONFIG_HPFS_FS is not set +CONFIG_PROC_FS=y +CONFIG_DEVFS_FS=y +# CONFIG_DEVFS_MOUNT is not set +# CONFIG_DEVFS_DEBUG is not set +CONFIG_DEVPTS_FS=y +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set +# CONFIG_ROMFS_FS is not set +CONFIG_EXT2_FS=y +# CONFIG_SYSV_FS is not set +# CONFIG_UDF_FS is not set +# CONFIG_UDF_RW is not set +# CONFIG_UFS_FS is not set +# CONFIG_UFS_FS_WRITE is not set + +# +# Network File Systems +# +# CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +CONFIG_ROOT_NFS=y +# CONFIG_NFSD is not set +# CONFIG_NFSD_V3 is not set +CONFIG_SUNRPC=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +# CONFIG_SMB_FS is not set +# CONFIG_NCP_FS is not set +# CONFIG_NCPFS_PACKET_SIGNING is not set +# CONFIG_NCPFS_IOCTL_LOCKING is not set +# CONFIG_NCPFS_STRONG is not set +# CONFIG_NCPFS_NFS_NS is not set +# CONFIG_NCPFS_OS2_NS is not set +# CONFIG_NCPFS_SMALLDOS is not set +# CONFIG_NCPFS_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set +# CONFIG_ZISOFS_FS is not set +# CONFIG_ZLIB_FS_INFLATE is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_SMB_NLS is not set +# CONFIG_NLS is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB is not set +# CONFIG_USB_UHCI is not set +# CONFIG_USB_UHCI_ALT is not set +# CONFIG_USB_OHCI is not set +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_BLUETOOTH is not set +# CONFIG_USB_STORAGE is not set +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_HP8200e is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set +# CONFIG_USB_DC2XX is not set +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_SCANNER is not set +# CONFIG_USB_MICROTEK is not set +# CONFIG_USB_HPUSBSCSI is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_CATC is not set +# CONFIG_USB_CDCETHER is not set +# CONFIG_USB_USBNET is not set +# CONFIG_USB_USS720 is not set + +# +# USB Serial Converter support +# +# CONFIG_USB_SERIAL is not set +# CONFIG_USB_SERIAL_GENERIC is not set +# CONFIG_USB_SERIAL_BELKIN is not set +# CONFIG_USB_SERIAL_WHITEHEAT is not set +# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set +# CONFIG_USB_SERIAL_EMPEG is not set +# CONFIG_USB_SERIAL_FTDI_SIO is not set +# CONFIG_USB_SERIAL_VISOR is not set +# CONFIG_USB_SERIAL_IPAQ is not set +# CONFIG_USB_SERIAL_IR is not set +# CONFIG_USB_SERIAL_EDGEPORT is not set +# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set +# CONFIG_USB_SERIAL_KEYSPAN is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set +# CONFIG_USB_SERIAL_MCT_U232 is not set +# CONFIG_USB_SERIAL_KLSI is not set +# CONFIG_USB_SERIAL_PL2303 is not set +# CONFIG_USB_SERIAL_CYBERJACK is not set +# CONFIG_USB_SERIAL_XIRCOM is not set +# CONFIG_USB_SERIAL_OMNINET is not set +# CONFIG_USB_RIO500 is not set + +# +# Bluetooth support +# +# CONFIG_BLUEZ is not set + +# +# Kernel hacking +# +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_KGDB is not set +# CONFIG_XMON is not set +# CONFIG_BDI_SWITCH is not set +# CONFIG_SERIAL_TEXT_DEBUG is not set diff --git a/arch/ppc/configs/gemini_defconfig b/arch/ppc/configs/gemini_defconfig index 818ddecefc2b..d1c97d7608be 100644 --- a/arch/ppc/configs/gemini_defconfig +++ b/arch/ppc/configs/gemini_defconfig @@ -4,6 +4,7 @@ # CONFIG_UID16 is not set # CONFIG_RWSEM_GENERIC_SPINLOCK is not set CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_HAVE_DEC_LOCK=y # # Code maturity level options @@ -25,7 +26,6 @@ CONFIG_PPC32=y CONFIG_6xx=y # CONFIG_4xx is not set # CONFIG_POWER3 is not set -# CONFIG_POWER4 is not set # CONFIG_8xx is not set # CONFIG_8260 is not set CONFIG_PPC_STD_MMU=y @@ -109,8 +109,6 @@ CONFIG_BLK_DEV_INITRD=y # CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set -CONFIG_NETLINK=y -# CONFIG_RTNETLINK is not set # CONFIG_NETLINK_DEV is not set CONFIG_NETFILTER=y # CONFIG_NETFILTER_DEBUG is not set @@ -122,6 +120,7 @@ CONFIG_INET=y # CONFIG_IP_PNP is not set # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set # CONFIG_INET_ECN is not set # CONFIG_SYN_COOKIES is not set @@ -221,15 +220,11 @@ CONFIG_SCSI_CONSTANTS=y # CONFIG_SCSI_INIA100 is not set # CONFIG_SCSI_NCR53C406A is not set # CONFIG_SCSI_NCR53C7xx is not set -# CONFIG_SCSI_NCR53C8XX is not set -CONFIG_SCSI_SYM53C8XX=y -CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=8 -CONFIG_SCSI_NCR53C8XX_MAX_TAGS=32 -CONFIG_SCSI_NCR53C8XX_SYNC=20 -# CONFIG_SCSI_NCR53C8XX_PROFILE is not set -# CONFIG_SCSI_NCR53C8XX_IOMAPPED is not set -# CONFIG_SCSI_NCR53C8XX_PQS_PDS is not set -# CONFIG_SCSI_NCR53C8XX_SYMBIOS_COMPAT is not set +CONFIG_SCSI_SYM53C8XX_2=y +CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=0 +CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 +CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 +# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set # CONFIG_SCSI_PAS16 is not set # CONFIG_SCSI_PCI2000 is not set # CONFIG_SCSI_PCI2220I is not set @@ -432,11 +427,15 @@ CONFIG_UNIX98_PTY_COUNT=256 # CONFIG_AUTOFS4_FS is not set # CONFIG_REISERFS_FS is not set # CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set # CONFIG_ADFS_FS is not set # CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set # CONFIG_BFS_FS is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_JBD_DEBUG is not set # CONFIG_FAT_FS is not set # CONFIG_MSDOS_FS is not set # CONFIG_UMSDOS_FS is not set @@ -449,6 +448,7 @@ CONFIG_TMPFS=y # CONFIG_RAMFS is not set CONFIG_ISO9660_FS=y # CONFIG_JOLIET is not set +# CONFIG_ZISOFS is not set # CONFIG_MINIX_FS is not set # CONFIG_VXFS_FS is not set # CONFIG_NTFS_FS is not set @@ -473,6 +473,7 @@ CONFIG_EXT2_FS=y # Network File Systems # # CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set CONFIG_NFS_FS=y # CONFIG_NFS_V3 is not set # CONFIG_ROOT_NFS is not set @@ -490,6 +491,8 @@ CONFIG_LOCKD=y # CONFIG_NCPFS_SMALLDOS is not set # CONFIG_NCPFS_NLS is not set # CONFIG_NCPFS_EXTRAS is not set +# CONFIG_ZISOFS_FS is not set +# CONFIG_ZLIB_FS_INFLATE is not set # # Partition Types diff --git a/arch/ppc/configs/iSeries_defconfig b/arch/ppc/configs/iSeries_defconfig new file mode 100644 index 000000000000..4f1b1a9f7f6f --- /dev/null +++ b/arch/ppc/configs/iSeries_defconfig @@ -0,0 +1,476 @@ +# +# Automatically generated make config: don't edit +# +# CONFIG_UID16 is not set +# CONFIG_RWSEM_GENERIC_SPINLOCK is not set +CONFIG_RWSEM_XCHGADD_ALGORITHM=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODVERSIONS=y +CONFIG_KMOD=y + +# +# Platform support +# +CONFIG_PPC=y +CONFIG_PPC32=y +# CONFIG_6xx is not set +# CONFIG_4xx is not set +# CONFIG_POWER3 is not set +# CONFIG_8xx is not set +CONFIG_PPC_ISERIES=y +CONFIG_PPC64BRIDGE=y +# CONFIG_ALL_PPC is not set +# CONFIG_SMP is not set + +# +# General setup +# +CONFIG_HIGHMEM=y +# CONFIG_ISA is not set +# CONFIG_EISA is not set +# CONFIG_SBUS is not set +# CONFIG_MCA is not set +# CONFIG_PCI_ISERIES is not set +# CONFIG_PCI is not set +CONFIG_NET=y +CONFIG_SYSCTL=y +CONFIG_SYSVIPC=y +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_KCORE_ELF=y +CONFIG_BINFMT_ELF=y +CONFIG_KERNEL_ELF=y +CONFIG_BINFMT_MISC=y +# CONFIG_HOTPLUG is not set +# CONFIG_PCMCIA is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set +# CONFIG_CMDLINE_BOOL is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Plug and Play configuration +# +# CONFIG_PNP is not set +# CONFIG_ISAPNP is not set +# CONFIG_PNPBIOS is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_XD is not set +# CONFIG_PARIDE is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_BLK_DEV_INITRD is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set +# CONFIG_BLK_DEV_MD is not set +# CONFIG_MD_LINEAR is not set +# CONFIG_MD_RAID0 is not set +# CONFIG_MD_RAID1 is not set +# CONFIG_MD_RAID5 is not set +# CONFIG_MD_MULTIPATH is not set +# CONFIG_BLK_DEV_LVM is not set + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_NETLINK=y +# CONFIG_RTNETLINK is not set +# CONFIG_NETLINK_DEV is not set +# CONFIG_NETFILTER is not set +# CONFIG_FILTER is not set +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +# CONFIG_IP_PNP_BOOTP is not set +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_INET_ECN is not set +CONFIG_SYN_COOKIES=y +# CONFIG_IPV6 is not set +# CONFIG_KHTTPD is not set +# CONFIG_ATM is not set + +# +# +# +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# ATA/IDE/MFM/RLL support +# +# CONFIG_IDE is not set +# CONFIG_BLK_DEV_IDE_MODES is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI support +# +# CONFIG_SCSI is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +# CONFIG_NET_ETHERNET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_MYRI_SBUS is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_SK98LIN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Old CD-ROM drivers (not SCSI, not IDE) +# +CONFIG_CD_NO_IDESCSI=y +# CONFIG_AZTCD is not set +# CONFIG_GSCD is not set +# CONFIG_SBPCD is not set +# CONFIG_MCD is not set +# CONFIG_MCDX is not set +# CONFIG_OPTCD is not set +# CONFIG_CM206 is not set +# CONFIG_SJCD is not set +# CONFIG_ISP16_CDI is not set +# CONFIG_CDU31A is not set +# CONFIG_CDU535 is not set + +# +# Console drivers +# +# CONFIG_VGA_CONSOLE is not set + +# +# Frame-buffer support +# +# CONFIG_FB is not set + +# +# iSeries device drivers +# +CONFIG_VIOCONS=y +CONFIG_VIODASD=y +# CONFIG_VIODASD_IDE is not set +CONFIG_VIOCD=y +# CONFIG_VIOCD_AZTECH is not set +CONFIG_VIOTAPE=y +CONFIG_VETH=y +CONFIG_VIOPATH=y +CONFIG_CD_NO_IDESCSI=y +CONFIG_BLK_DEV_IDECD=y + +# +# Input core support +# +# CONFIG_INPUT is not set +# CONFIG_INPUT_KEYBDEV is not set +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set + +# +# Macintosh device drivers +# + +# +# Character devices +# +# CONFIG_VT is not set +# CONFIG_SERIAL is not set +# CONFIG_SERIAL_EXTENDED is not set +# CONFIG_SERIAL_NONSTANDARD is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set + +# +# Joysticks +# +# CONFIG_INPUT_GAMEPORT is not set + +# +# Input core support is needed for gameports +# + +# +# Input core support is needed for joysticks +# +# CONFIG_QIC02_TAPE is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_INTEL_RNG is not set +# CONFIG_NVRAM is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +CONFIG_REISERFS_FS=y +# CONFIG_REISERFS_CHECK is not set +# CONFIG_ADFS_FS is not set +# CONFIG_ADFS_FS_RW is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_FAT_FS is not set +# CONFIG_MSDOS_FS is not set +# CONFIG_UMSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_JFFS2_FS is not set +CONFIG_CRAMFS=y +# CONFIG_TMPFS is not set +CONFIG_RAMFS=y +CONFIG_ISO9660_FS=y +CONFIG_JOLIET=y +# CONFIG_MINIX_FS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_NTFS_FS is not set +# CONFIG_NTFS_RW is not set +# CONFIG_HPFS_FS is not set +CONFIG_PROC_FS=y +CONFIG_DEVFS_FS=y +CONFIG_DEVFS_MOUNT=y +# CONFIG_DEVFS_DEBUG is not set +CONFIG_DEVPTS_FS=y +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set +# CONFIG_ROMFS_FS is not set +CONFIG_EXT2_FS=y +# CONFIG_SYSV_FS is not set +# CONFIG_UDF_FS is not set +# CONFIG_UDF_RW is not set +# CONFIG_UFS_FS is not set +# CONFIG_UFS_FS_WRITE is not set + +# +# Network File Systems +# +# CONFIG_CODA_FS is not set +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +CONFIG_ROOT_NFS=y +# CONFIG_NFSD is not set +# CONFIG_NFSD_V3 is not set +CONFIG_SUNRPC=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +# CONFIG_SMB_FS is not set +# CONFIG_NCP_FS is not set +# CONFIG_NCPFS_PACKET_SIGNING is not set +# CONFIG_NCPFS_IOCTL_LOCKING is not set +# CONFIG_NCPFS_STRONG is not set +# CONFIG_NCPFS_NFS_NS is not set +# CONFIG_NCPFS_OS2_NS is not set +# CONFIG_NCPFS_SMALLDOS is not set +# CONFIG_NCPFS_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_SMB_NLS is not set +CONFIG_NLS=y + +# +# Native Language Support +# +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +CONFIG_NLS_ISO8859_1=y +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB is not set + +# +# Bluetooth support +# +# CONFIG_BLUEZ is not set + +# +# Kernel hacking +# +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_KGDB is not set +# CONFIG_XMON is not set +# CONFIG_BDI_SWITCH is not set diff --git a/arch/ppc/configs/ibmchrp_defconfig b/arch/ppc/configs/ibmchrp_defconfig index a639dc8460be..5414d8694d7e 100644 --- a/arch/ppc/configs/ibmchrp_defconfig +++ b/arch/ppc/configs/ibmchrp_defconfig @@ -4,6 +4,7 @@ # CONFIG_UID16 is not set # CONFIG_RWSEM_GENERIC_SPINLOCK is not set CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_HAVE_DEC_LOCK=y # # Code maturity level options @@ -25,7 +26,6 @@ CONFIG_PPC32=y CONFIG_6xx=y # CONFIG_4xx is not set # CONFIG_POWER3 is not set -# CONFIG_POWER4 is not set # CONFIG_8xx is not set # CONFIG_8260 is not set CONFIG_PPC_STD_MMU=y @@ -112,8 +112,6 @@ CONFIG_BLK_DEV_INITRD=y # CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set -CONFIG_NETLINK=y -# CONFIG_RTNETLINK is not set # CONFIG_NETLINK_DEV is not set CONFIG_NETFILTER=y # CONFIG_NETFILTER_DEBUG is not set @@ -126,6 +124,7 @@ CONFIG_IP_MULTICAST=y # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set # CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set # CONFIG_INET_ECN is not set CONFIG_SYN_COOKIES=y @@ -252,15 +251,11 @@ CONFIG_SCSI_CONSTANTS=y # CONFIG_SCSI_INIA100 is not set # CONFIG_SCSI_NCR53C406A is not set # CONFIG_SCSI_NCR53C7xx is not set -# CONFIG_SCSI_NCR53C8XX is not set -CONFIG_SCSI_SYM53C8XX=y -CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=8 -CONFIG_SCSI_NCR53C8XX_MAX_TAGS=32 -CONFIG_SCSI_NCR53C8XX_SYNC=20 -# CONFIG_SCSI_NCR53C8XX_PROFILE is not set -# CONFIG_SCSI_NCR53C8XX_IOMAPPED is not set -# CONFIG_SCSI_NCR53C8XX_PQS_PDS is not set -# CONFIG_SCSI_NCR53C8XX_SYMBIOS_COMPAT is not set +CONFIG_SCSI_SYM53C8XX_2=y +CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=0 +CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 +CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 +# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set # CONFIG_SCSI_PAS16 is not set # CONFIG_SCSI_PCI2000 is not set # CONFIG_SCSI_PCI2220I is not set @@ -343,6 +338,7 @@ CONFIG_DE4X5=y # CONFIG_SUNDANCE is not set # CONFIG_TLAN is not set # CONFIG_VIA_RHINE is not set +# CONFIG_VIA_RHINE_MMIO is not set # CONFIG_WINBOND_840 is not set # CONFIG_NET_POCKET is not set @@ -546,7 +542,7 @@ CONFIG_PSMOUSE=y # CONFIG_WATCHDOG is not set # CONFIG_INTEL_RNG is not set CONFIG_NVRAM=y -CONFIG_RTC=y +# CONFIG_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -571,11 +567,15 @@ CONFIG_RTC=y # CONFIG_AUTOFS4_FS is not set # CONFIG_REISERFS_FS is not set # CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set # CONFIG_ADFS_FS is not set # CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set # CONFIG_BFS_FS is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_JBD_DEBUG is not set CONFIG_FAT_FS=m CONFIG_MSDOS_FS=m # CONFIG_UMSDOS_FS is not set @@ -588,6 +588,7 @@ CONFIG_TMPFS=y # CONFIG_RAMFS is not set CONFIG_ISO9660_FS=y # CONFIG_JOLIET is not set +# CONFIG_ZISOFS is not set # CONFIG_MINIX_FS is not set # CONFIG_VXFS_FS is not set # CONFIG_NTFS_FS is not set @@ -612,6 +613,7 @@ CONFIG_EXT2_FS=y # Network File Systems # # CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set # CONFIG_NFS_FS is not set # CONFIG_NFS_V3 is not set # CONFIG_ROOT_NFS is not set @@ -629,6 +631,8 @@ CONFIG_EXT2_FS=y # CONFIG_NCPFS_SMALLDOS is not set # CONFIG_NCPFS_NLS is not set # CONFIG_NCPFS_EXTRAS is not set +# CONFIG_ZISOFS_FS is not set +# CONFIG_ZLIB_FS_INFLATE is not set # # Partition Types @@ -677,7 +681,7 @@ CONFIG_NLS_DEFAULT="iso8859-1" # CONFIG_NLS_CODEPAGE_874 is not set # CONFIG_NLS_ISO8859_8 is not set # CONFIG_NLS_CODEPAGE_1251 is not set -# CONFIG_NLS_ISO8859_1 is not set +CONFIG_NLS_ISO8859_1=m # CONFIG_NLS_ISO8859_2 is not set # CONFIG_NLS_ISO8859_3 is not set # CONFIG_NLS_ISO8859_4 is not set diff --git a/arch/ppc/configs/k2_defconfig b/arch/ppc/configs/k2_defconfig new file mode 100644 index 000000000000..781bb8880c9f --- /dev/null +++ b/arch/ppc/configs/k2_defconfig @@ -0,0 +1,638 @@ +# +# Automatically generated by make menuconfig: don't edit +# +# CONFIG_UID16 is not set +# CONFIG_RWSEM_GENERIC_SPINLOCK is not set +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_HAVE_DEC_LOCK=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODVERSIONS=y +CONFIG_KMOD=y + +# +# Platform support +# +CONFIG_PPC=y +CONFIG_PPC32=y +CONFIG_6xx=y +# CONFIG_4xx is not set +# CONFIG_POWER3 is not set +# CONFIG_8xx is not set +# CONFIG_PPC_ISERIES is not set +# CONFIG_8260 is not set +CONFIG_PPC_STD_MMU=y +# CONFIG_ALL_PPC is not set +# CONFIG_APUS is not set +# CONFIG_WILLOW is not set +# CONFIG_PCORE is not set +# CONFIG_POWERPMC250 is not set +# CONFIG_EV64260 is not set +# CONFIG_SPRUCE is not set +# CONFIG_MENF1 is not set +# CONFIG_LOPEC is not set +# CONFIG_MCPN765 is not set +# CONFIG_MVME5100 is not set +# CONFIG_PPLUS is not set +# CONFIG_PRPMC750 is not set +# CONFIG_PRPMC800 is not set +# CONFIG_SANDPOINT is not set +# CONFIG_ADIR is not set +CONFIG_K2=y +# CONFIG_GEMINI is not set +# CONFIG_ZX4500 is not set +# CONFIG_CPC710_DATA_GATHERING is not set +# CONFIG_SMP is not set +# CONFIG_ALTIVEC is not set +# CONFIG_TAU is not set + +# +# General setup +# +# CONFIG_HIGHMEM is not set +# CONFIG_ISA is not set +# CONFIG_EISA is not set +# CONFIG_SBUS is not set +# CONFIG_MCA is not set +CONFIG_PCI=y +CONFIG_NET=y +CONFIG_SYSCTL=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_KCORE_ELF=y +CONFIG_BINFMT_ELF=y +CONFIG_KERNEL_ELF=y +# CONFIG_BINFMT_MISC is not set +# CONFIG_PCI_NAMES is not set +# CONFIG_HOTPLUG is not set +# CONFIG_PCMCIA is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set +CONFIG_PPC_RTC=y +CONFIG_CMDLINE_BOOL=y +CONFIG_CMDLINE="ip=on" + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Plug and Play configuration +# +# CONFIG_PNP is not set +# CONFIG_ISAPNP is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_XD is not set +# CONFIG_PARIDE is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_INITRD=y + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set +# CONFIG_BLK_DEV_MD is not set +# CONFIG_MD_LINEAR is not set +# CONFIG_MD_RAID0 is not set +# CONFIG_MD_RAID1 is not set +# CONFIG_MD_RAID5 is not set +# CONFIG_MD_MULTIPATH is not set +# CONFIG_BLK_DEV_LVM is not set + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_NETLINK=y +# CONFIG_RTNETLINK is not set +# CONFIG_NETLINK_DEV is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +# CONFIG_FILTER is not set +CONFIG_UNIX=y +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +# CONFIG_IP_PNP_BOOTP is not set +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set + +# +# IP: Netfilter Configuration +# +CONFIG_IP_NF_CONNTRACK=m +CONFIG_IP_NF_FTP=m +# CONFIG_IP_NF_IRC is not set +# CONFIG_IP_NF_QUEUE is not set +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_LIMIT=m +CONFIG_IP_NF_MATCH_MAC=m +CONFIG_IP_NF_MATCH_MARK=m +CONFIG_IP_NF_MATCH_MULTIPORT=m +CONFIG_IP_NF_MATCH_TOS=m +# CONFIG_IP_NF_MATCH_LENGTH is not set +# CONFIG_IP_NF_MATCH_TTL is not set +CONFIG_IP_NF_MATCH_TCPMSS=m +CONFIG_IP_NF_MATCH_STATE=m +CONFIG_IP_NF_MATCH_UNCLEAN=m +CONFIG_IP_NF_MATCH_OWNER=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_MIRROR=m +CONFIG_IP_NF_NAT=m +CONFIG_IP_NF_NAT_NEEDED=y +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_REDIRECT=m +# CONFIG_IP_NF_NAT_SNMP_BASIC is not set +CONFIG_IP_NF_NAT_FTP=m +# CONFIG_IP_NF_MANGLE is not set +# CONFIG_IP_NF_TARGET_LOG is not set +CONFIG_IP_NF_TARGET_TCPMSS=m +CONFIG_IP_NF_COMPAT_IPCHAINS=m +CONFIG_IP_NF_NAT_NEEDED=y +# CONFIG_IP_NF_COMPAT_IPFWADM is not set +# CONFIG_IPV6 is not set +# CONFIG_KHTTPD is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# ATA/IDE/MFM/RLL support +# +CONFIG_IDE=y + +# +# IDE, ATA and ATAPI Block devices +# +CONFIG_BLK_DEV_IDE=y +# CONFIG_BLK_DEV_HD_IDE is not set +# CONFIG_BLK_DEV_HD is not set +CONFIG_BLK_DEV_IDEDISK=y +# CONFIG_IDEDISK_MULTI_MODE is not set +# CONFIG_BLK_DEV_IDEDISK_VENDOR is not set +# CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set +# CONFIG_BLK_DEV_IDEDISK_IBM is not set +# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set +# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set +# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set +# CONFIG_BLK_DEV_IDEDISK_WD is not set +# CONFIG_BLK_DEV_COMMERIAL is not set +# CONFIG_BLK_DEV_TIVO is not set +# CONFIG_BLK_DEV_IDECS is not set +# CONFIG_BLK_DEV_IDECD is not set +# CONFIG_BLK_DEV_IDETAPE is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set +# CONFIG_BLK_DEV_IDESCSI is not set +# CONFIG_BLK_DEV_CMD640 is not set +# CONFIG_BLK_DEV_CMD640_ENHANCED is not set +# CONFIG_BLK_DEV_ISAPNP is not set +# CONFIG_BLK_DEV_RZ1000 is not set +CONFIG_BLK_DEV_IDEPCI=y +CONFIG_IDEPCI_SHARE_IRQ=y +CONFIG_BLK_DEV_IDEDMA_PCI=y +CONFIG_BLK_DEV_ADMA=y +# CONFIG_BLK_DEV_OFFBOARD is not set +# CONFIG_IDEDMA_PCI_AUTO is not set +CONFIG_BLK_DEV_IDEDMA=y +# CONFIG_IDEDMA_PCI_WIP is not set +# CONFIG_IDEDMA_NEW_DRIVE_LISTINGS is not set +# CONFIG_BLK_DEV_AEC62XX is not set +# CONFIG_AEC62XX_TUNING is not set +CONFIG_BLK_DEV_ALI15X3=y +# CONFIG_WDC_ALI15X3 is not set +# CONFIG_BLK_DEV_AMD74XX is not set +# CONFIG_AMD74XX_OVERRIDE is not set +# CONFIG_BLK_DEV_CMD64X is not set +# CONFIG_BLK_DEV_CY82C693 is not set +# CONFIG_BLK_DEV_CS5530 is not set +# CONFIG_BLK_DEV_HPT34X is not set +# CONFIG_HPT34X_AUTODMA is not set +# CONFIG_BLK_DEV_HPT366 is not set +# CONFIG_BLK_DEV_NS87415 is not set +# CONFIG_BLK_DEV_OPTI621 is not set +# CONFIG_BLK_DEV_PDC202XX is not set +# CONFIG_PDC202XX_BURST is not set +# CONFIG_PDC202XX_FORCE is not set +# CONFIG_BLK_DEV_SVWKS is not set +# CONFIG_BLK_DEV_SIS5513 is not set +# CONFIG_BLK_DEV_SLC90E66 is not set +# CONFIG_BLK_DEV_TRM290 is not set +# CONFIG_BLK_DEV_VIA82CXXX is not set +# CONFIG_BLK_DEV_SL82C105 is not set +# CONFIG_IDE_CHIPSETS is not set +# CONFIG_IDEDMA_AUTO is not set +# CONFIG_IDEDMA_IVB is not set +# CONFIG_DMA_NONPCI is not set +CONFIG_BLK_DEV_IDE_MODES=y +# CONFIG_BLK_DEV_ATARAID is not set +# CONFIG_BLK_DEV_ATARAID_PDC is not set +# CONFIG_BLK_DEV_ATARAID_HPT is not set + +# +# SCSI support +# +# CONFIG_SCSI is not set + +# +# IEEE 1394 (FireWire) support (EXPERIMENTAL) +# +# CONFIG_IEEE1394 is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_MACE is not set +# CONFIG_BMAC is not set +# CONFIG_GMAC is not set +# CONFIG_SUNLANCE is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNBMAC is not set +# CONFIG_SUNQE is not set +# CONFIG_SUNLANCE is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_HP100 is not set +# CONFIG_NET_ISA is not set +CONFIG_NET_PCI=y +# CONFIG_PCNET32 is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_APRICOT is not set +# CONFIG_CS89x0 is not set +# CONFIG_TULIP is not set +# CONFIG_DE4X5 is not set +# CONFIG_DGRS is not set +# CONFIG_DM9102 is not set +CONFIG_EEPRO100=y +# CONFIG_LNE390 is not set +# CONFIG_FEALNX is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_NE3210 is not set +# CONFIG_ES3210 is not set +# CONFIG_8139CP is not set +# CONFIG_8139TOO is not set +# CONFIG_8139TOO_PIO is not set +# CONFIG_8139TOO_TUNE_TWISTER is not set +# CONFIG_8139TOO_8129 is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_TLAN is not set +# CONFIG_VIA_RHINE is not set +# CONFIG_WINBOND_840 is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_MYRI_SBUS is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_SK98LIN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Old CD-ROM drivers (not SCSI, not IDE) +# +# CONFIG_CD_NO_IDESCSI is not set + +# +# Console drivers +# +# CONFIG_VGA_CONSOLE is not set + +# +# Frame-buffer support +# +# CONFIG_FB is not set + +# +# Input core support +# +# CONFIG_INPUT is not set +# CONFIG_INPUT_KEYBDEV is not set +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set + +# +# Macintosh device drivers +# + +# +# Character devices +# +# CONFIG_VT is not set +CONFIG_SERIAL=y +CONFIG_SERIAL_CONSOLE=y +# CONFIG_SERIAL_EXTENDED is not set +# CONFIG_SERIAL_NONSTANDARD is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set + +# +# Joysticks +# +# CONFIG_INPUT_GAMEPORT is not set +# CONFIG_QIC02_TAPE is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_INTEL_RNG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set +# CONFIG_ADFS_FS is not set +# CONFIG_ADFS_FS_RW is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_JBD_DEBUG is not set +# CONFIG_FAT_FS is not set +# CONFIG_MSDOS_FS is not set +# CONFIG_UMSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_CRAMFS is not set +CONFIG_TMPFS=y +# CONFIG_RAMFS is not set +# CONFIG_ISO9660_FS is not set +# CONFIG_JOLIET is not set +# CONFIG_ZISOFS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_NTFS_FS is not set +# CONFIG_NTFS_RW is not set +# CONFIG_HPFS_FS is not set +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVFS_MOUNT is not set +# CONFIG_DEVFS_DEBUG is not set +CONFIG_DEVPTS_FS=y +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set +# CONFIG_ROMFS_FS is not set +CONFIG_EXT2_FS=y +# CONFIG_SYSV_FS is not set +# CONFIG_UDF_FS is not set +# CONFIG_UDF_RW is not set +# CONFIG_UFS_FS is not set +# CONFIG_UFS_FS_WRITE is not set + +# +# Network File Systems +# +# CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +CONFIG_ROOT_NFS=y +# CONFIG_NFSD is not set +# CONFIG_NFSD_V3 is not set +CONFIG_SUNRPC=y +CONFIG_LOCKD=y +# CONFIG_SMB_FS is not set +# CONFIG_NCP_FS is not set +# CONFIG_NCPFS_PACKET_SIGNING is not set +# CONFIG_NCPFS_IOCTL_LOCKING is not set +# CONFIG_NCPFS_STRONG is not set +# CONFIG_NCPFS_NFS_NS is not set +# CONFIG_NCPFS_OS2_NS is not set +# CONFIG_NCPFS_SMALLDOS is not set +# CONFIG_NCPFS_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set +# CONFIG_ZISOFS_FS is not set +# CONFIG_ZLIB_FS_INFLATE is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_SMB_NLS is not set +# CONFIG_NLS is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB is not set +# CONFIG_USB_UHCI is not set +# CONFIG_USB_UHCI_ALT is not set +# CONFIG_USB_OHCI is not set +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_BLUETOOTH is not set +# CONFIG_USB_STORAGE is not set +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_HP8200e is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set +# CONFIG_USB_DC2XX is not set +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_SCANNER is not set +# CONFIG_USB_MICROTEK is not set +# CONFIG_USB_HPUSBSCSI is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_CATC is not set +# CONFIG_USB_CDCETHER is not set +# CONFIG_USB_USBNET is not set +# CONFIG_USB_USS720 is not set + +# +# USB Serial Converter support +# +# CONFIG_USB_SERIAL is not set +# CONFIG_USB_SERIAL_GENERIC is not set +# CONFIG_USB_SERIAL_BELKIN is not set +# CONFIG_USB_SERIAL_WHITEHEAT is not set +# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set +# CONFIG_USB_SERIAL_EMPEG is not set +# CONFIG_USB_SERIAL_FTDI_SIO is not set +# CONFIG_USB_SERIAL_VISOR is not set +# CONFIG_USB_SERIAL_IR is not set +# CONFIG_USB_SERIAL_EDGEPORT is not set +# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set +# CONFIG_USB_SERIAL_KEYSPAN is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set +# CONFIG_USB_SERIAL_MCT_U232 is not set +# CONFIG_USB_SERIAL_PL2303 is not set +# CONFIG_USB_SERIAL_CYBERJACK is not set +# CONFIG_USB_SERIAL_XIRCOM is not set +# CONFIG_USB_SERIAL_OMNINET is not set +# CONFIG_USB_RIO500 is not set + +# +# Bluetooth support +# +# CONFIG_BLUEZ is not set + +# +# Kernel hacking +# +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_KGDB is not set +CONFIG_XMON=y +# CONFIG_BDI_SWITCH is not set diff --git a/arch/ppc/configs/lopec_defconfig b/arch/ppc/configs/lopec_defconfig new file mode 100644 index 000000000000..d0609732057b --- /dev/null +++ b/arch/ppc/configs/lopec_defconfig @@ -0,0 +1,575 @@ +# +# Automatically generated by make menuconfig: don't edit +# +# CONFIG_UID16 is not set +# CONFIG_RWSEM_GENERIC_SPINLOCK is not set +CONFIG_RWSEM_XCHGADD_ALGORITHM=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODVERSIONS is not set +CONFIG_KMOD=y + +# +# Platform support +# +CONFIG_PPC=y +CONFIG_PPC32=y +CONFIG_6xx=y +# CONFIG_4xx is not set +# CONFIG_POWER3 is not set +# CONFIG_8xx is not set +# CONFIG_PPC_ISERIES is not set +# CONFIG_8260 is not set +CONFIG_PPC_STD_MMU=y +# CONFIG_ALL_PPC is not set +# CONFIG_APUS is not set +# CONFIG_SPRUCE is not set +# CONFIG_PCORE is not set +# CONFIG_MENF1 is not set +CONFIG_LOPEC=y +# CONFIG_MCPN765 is not set +# CONFIG_MVME5100 is not set +# CONFIG_PRPMC750 is not set +# CONFIG_SANDPOINT is not set +# CONFIG_K2 is not set +# CONFIG_GEMINI is not set +# CONFIG_ZX4500 is not set +# CONFIG_PPC601_SYNC_FIX is not set +# CONFIG_SMP is not set +# CONFIG_ALTIVEC is not set +# CONFIG_TAU is not set + +# +# General setup +# +# CONFIG_HIGHMEM is not set +# CONFIG_ISA is not set +# CONFIG_EISA is not set +# CONFIG_SBUS is not set +# CONFIG_MCA is not set +CONFIG_PCI=y +CONFIG_NET=y +CONFIG_SYSCTL=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_KCORE_ELF=y +CONFIG_BINFMT_ELF=y +CONFIG_KERNEL_ELF=y +CONFIG_BINFMT_MISC=m +# CONFIG_PCI_NAMES is not set +# CONFIG_HOTPLUG is not set +# CONFIG_PCMCIA is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set +# CONFIG_PPC_RTC is not set +# CONFIG_CMDLINE_BOOL is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Plug and Play configuration +# +# CONFIG_PNP is not set +# CONFIG_ISAPNP is not set +# CONFIG_PNPBIOS is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_VIODASD is not set +# CONFIG_BLK_DEV_XD is not set +# CONFIG_PARIDE is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_BLK_DEV_INITRD is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set +# CONFIG_BLK_DEV_MD is not set +# CONFIG_MD_LINEAR is not set +# CONFIG_MD_RAID0 is not set +# CONFIG_MD_RAID1 is not set +# CONFIG_MD_RAID5 is not set +# CONFIG_BLK_DEV_LVM is not set + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_NETLINK=y +# CONFIG_RTNETLINK is not set +# CONFIG_NETLINK_DEV is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +# CONFIG_FILTER is not set +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +# CONFIG_IP_PNP_BOOTP is not set +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_INET_ECN is not set +CONFIG_SYN_COOKIES=y + +# +# IP: Netfilter Configuration +# +# CONFIG_IP_NF_CONNTRACK is not set +# CONFIG_IP_NF_QUEUE is not set +# CONFIG_IP_NF_IPTABLES is not set +# CONFIG_IP_NF_COMPAT_IPCHAINS is not set +# CONFIG_IP_NF_COMPAT_IPFWADM is not set +# CONFIG_IPV6 is not set +# CONFIG_KHTTPD is not set +# CONFIG_ATM is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# ATA/IDE/MFM/RLL support +# +# CONFIG_IDE is not set +# CONFIG_BLK_DEV_IDE_MODES is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI support +# +CONFIG_SCSI=y +CONFIG_BLK_DEV_SD=y +CONFIG_SD_EXTRA_DEVS=40 +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +# CONFIG_CHR_DEV_SG is not set +# CONFIG_SCSI_DEBUG_QUEUES is not set +# CONFIG_SCSI_MULTI_LUN is not set +CONFIG_SCSI_CONSTANTS=y +# CONFIG_SCSI_LOGGING is not set + +# +# SCSI low-level drivers +# +# CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_7000FASST is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_AHA152X is not set +# CONFIG_SCSI_AHA1542 is not set +# CONFIG_SCSI_AHA1740 is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_ADVANSYS is not set +# CONFIG_SCSI_IN2000 is not set +# CONFIG_SCSI_AM53C974 is not set +# CONFIG_SCSI_MEGARAID is not set +# CONFIG_SCSI_BUSLOGIC is not set +# CONFIG_SCSI_CPQFCTS is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_DTC3280 is not set +# CONFIG_SCSI_EATA is not set +# CONFIG_SCSI_EATA_DMA is not set +# CONFIG_SCSI_EATA_PIO is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_GDTH is not set +# CONFIG_SCSI_GENERIC_NCR5380 is not set +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_NCR53C406A is not set +# CONFIG_SCSI_NCR53C7xx is not set +# CONFIG_SCSI_NCR53C8XX is not set +CONFIG_SCSI_SYM53C8XX=y +CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=8 +CONFIG_SCSI_NCR53C8XX_MAX_TAGS=32 +CONFIG_SCSI_NCR53C8XX_SYNC=20 +# CONFIG_SCSI_NCR53C8XX_PROFILE is not set +# CONFIG_SCSI_NCR53C8XX_IOMAPPED is not set +# CONFIG_SCSI_NCR53C8XX_PQS_PDS is not set +# CONFIG_SCSI_NCR53C8XX_SYMBIOS_COMPAT is not set +# CONFIG_SCSI_PAS16 is not set +# CONFIG_SCSI_PCI2000 is not set +# CONFIG_SCSI_PCI2220I is not set +# CONFIG_SCSI_PSI240I is not set +# CONFIG_SCSI_QLOGIC_FAS is not set +# CONFIG_SCSI_QLOGIC_ISP is not set +# CONFIG_SCSI_QLOGIC_FC is not set +# CONFIG_SCSI_QLOGIC_1280 is not set +# CONFIG_SCSI_SIM710 is not set +# CONFIG_SCSI_SYM53C416 is not set +# CONFIG_SCSI_DC390T is not set +# CONFIG_SCSI_T128 is not set +# CONFIG_SCSI_U14_34F is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_MESH is not set +# CONFIG_SCSI_MAC53C94 is not set + +# +# IEEE 1394 (FireWire) support (EXPERIMENTAL) +# +# CONFIG_IEEE1394 is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_ARM_AM79C961A is not set +# CONFIG_MACE is not set +# CONFIG_BMAC is not set +# CONFIG_GMAC is not set +# CONFIG_NCR885E is not set +# CONFIG_OAKNET is not set +# CONFIG_SUNLANCE is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNBMAC is not set +# CONFIG_SUNQE is not set +# CONFIG_SUNLANCE is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_HP100 is not set +# CONFIG_NET_ISA is not set +CONFIG_NET_PCI=y +# CONFIG_PCNET32 is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_APRICOT is not set +# CONFIG_CS89x0 is not set +# CONFIG_TULIP is not set +# CONFIG_TULIP_MWI is not set +# CONFIG_TULIP_MMIO is not set +# CONFIG_DE4X5 is not set +# CONFIG_DGRS is not set +# CONFIG_DM9102 is not set +CONFIG_EEPRO100=y +# CONFIG_LNE390 is not set +# CONFIG_FEALNX is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_NE3210 is not set +# CONFIG_ES3210 is not set +# CONFIG_8139TOO is not set +# CONFIG_8139TOO_PIO is not set +# CONFIG_8139TOO_TUNE_TWISTER is not set +# CONFIG_8139TOO_8129 is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_TLAN is not set +# CONFIG_VIA_RHINE is not set +# CONFIG_WINBOND_840 is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_ACENIC_OMIT_TIGON_I is not set +# CONFIG_DL2K is not set +# CONFIG_MYRI_SBUS is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_SK98LIN is not set +# CONFIG_VETH is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Old CD-ROM drivers (not SCSI, not IDE) +# +# CONFIG_CD_NO_IDESCSI is not set + +# +# Console drivers +# +# CONFIG_VGA_CONSOLE is not set + +# +# Frame-buffer support +# +# CONFIG_FB is not set + +# +# Input core support +# +# CONFIG_INPUT is not set + +# +# Macintosh device drivers +# + +# +# Character devices +# +# CONFIG_VT is not set +CONFIG_SERIAL=y +CONFIG_SERIAL_CONSOLE=y +# CONFIG_SERIAL_EXTENDED is not set +# CONFIG_SERIAL_NONSTANDARD is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 +# CONFIG_VIOCONS is not set + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set + +# +# Joysticks +# +# CONFIG_JOYSTICK is not set +# CONFIG_QIC02_TAPE is not set +# CONFIG_VIOTAPE is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_INTEL_RNG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set +# CONFIG_SONYPI is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set +# CONFIG_ADFS_FS is not set +# CONFIG_ADFS_FS_RW is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_FAT_FS is not set +# CONFIG_MSDOS_FS is not set +# CONFIG_UMSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_CRAMFS is not set +CONFIG_TMPFS=y +# CONFIG_RAMFS is not set +# CONFIG_ISO9660_FS is not set +# CONFIG_JOLIET is not set +# CONFIG_MINIX_FS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_NTFS_FS is not set +# CONFIG_NTFS_RW is not set +# CONFIG_HPFS_FS is not set +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVFS_MOUNT is not set +# CONFIG_DEVFS_DEBUG is not set +CONFIG_DEVPTS_FS=y +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_EXT2_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UDF_FS is not set +# CONFIG_UDF_RW is not set +# CONFIG_UFS_FS is not set +# CONFIG_UFS_FS_WRITE is not set + +# +# Network File Systems +# +# CONFIG_CODA_FS is not set +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +CONFIG_ROOT_NFS=y +# CONFIG_NFSD is not set +# CONFIG_NFSD_V3 is not set +CONFIG_SUNRPC=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +# CONFIG_SMB_FS is not set +# CONFIG_NCP_FS is not set +# CONFIG_NCPFS_PACKET_SIGNING is not set +# CONFIG_NCPFS_IOCTL_LOCKING is not set +# CONFIG_NCPFS_STRONG is not set +# CONFIG_NCPFS_NFS_NS is not set +# CONFIG_NCPFS_OS2_NS is not set +# CONFIG_NCPFS_SMALLDOS is not set +# CONFIG_NCPFS_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_SMB_NLS is not set +# CONFIG_NLS is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set +CONFIG_USB_DEVICEFS=y +# CONFIG_USB_BANDWIDTH is not set +# CONFIG_USB_UHCI is not set +# CONFIG_USB_UHCI_ALT is not set +CONFIG_USB_OHCI=y +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_BLUETOOTH is not set +# CONFIG_USB_STORAGE is not set +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set +# CONFIG_USB_DC2XX is not set +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_SCANNER is not set +# CONFIG_USB_MICROTEK is not set +# CONFIG_USB_IBMCAM is not set +# CONFIG_USB_OV511 is not set +# CONFIG_USB_PWC is not set +# CONFIG_USB_SE401 is not set +# CONFIG_USB_DSBR is not set +# CONFIG_USB_DABUSB is not set +# CONFIG_USB_PLUSB is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_CATC is not set +# CONFIG_USB_NET1080 is not set +# CONFIG_USB_USS720 is not set + +# +# USB Serial Converter support +# +# CONFIG_USB_SERIAL is not set +# CONFIG_USB_RIO500 is not set + +# +# Bluetooth support +# +# CONFIG_BLUEZ is not set + +# +# Kernel hacking +# +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_KGDB is not set +CONFIG_XMON=y +# CONFIG_BDI_SWITCH is not set diff --git a/arch/ppc/configs/mbx_defconfig b/arch/ppc/configs/mbx_defconfig index c2c62c30d703..4d0f6c43c0cb 100644 --- a/arch/ppc/configs/mbx_defconfig +++ b/arch/ppc/configs/mbx_defconfig @@ -23,7 +23,6 @@ CONFIG_PPC32=y # CONFIG_6xx is not set # CONFIG_4xx is not set # CONFIG_POWER3 is not set -# CONFIG_POWER4 is not set CONFIG_8xx=y # CONFIG_PPC_STD_MMU is not set CONFIG_SERIAL_CONSOLE=y diff --git a/arch/ppc/configs/mcpn765_defconfig b/arch/ppc/configs/mcpn765_defconfig new file mode 100644 index 000000000000..cb74b61543a5 --- /dev/null +++ b/arch/ppc/configs/mcpn765_defconfig @@ -0,0 +1,475 @@ +# +# Automatically generated by make menuconfig: don't edit +# +# CONFIG_UID16 is not set +# CONFIG_RWSEM_GENERIC_SPINLOCK is not set +CONFIG_RWSEM_XCHGADD_ALGORITHM=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# Loadable module support +# +# CONFIG_MODULES is not set + +# +# Platform support +# +CONFIG_PPC=y +CONFIG_PPC32=y +CONFIG_6xx=y +# CONFIG_4xx is not set +# CONFIG_POWER3 is not set +# CONFIG_8xx is not set +# CONFIG_PPC_ISERIES is not set +# CONFIG_8260 is not set +CONFIG_PPC_STD_MMU=y +# CONFIG_ALL_PPC is not set +# CONFIG_APUS is not set +# CONFIG_SPRUCE is not set +# CONFIG_PCORE is not set +# CONFIG_MENF1 is not set +# CONFIG_LOPEC is not set +CONFIG_MCPN765=y +# CONFIG_MVME5100 is not set +# CONFIG_PRPMC750 is not set +# CONFIG_PRPMC800 is not set +# CONFIG_SANDPOINT is not set +# CONFIG_ADIR is not set +# CONFIG_K2 is not set +# CONFIG_GEMINI is not set +# CONFIG_WILLOW is not set +# CONFIG_ZX4500 is not set +# CONFIG_SMP is not set +CONFIG_ALTIVEC=y +# CONFIG_TAU is not set + +# +# General setup +# +CONFIG_HIGHMEM=y +# CONFIG_ISA is not set +# CONFIG_EISA is not set +# CONFIG_SBUS is not set +# CONFIG_MCA is not set +CONFIG_PCI=y +CONFIG_NET=y +CONFIG_SYSCTL=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_KCORE_ELF=y +CONFIG_BINFMT_ELF=y +CONFIG_KERNEL_ELF=y +# CONFIG_BINFMT_MISC is not set +# CONFIG_PCI_NAMES is not set +# CONFIG_HOTPLUG is not set +# CONFIG_PCMCIA is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set +CONFIG_PPC_RTC=y +CONFIG_CMDLINE_BOOL=y +CONFIG_CMDLINE="ip=on" + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Plug and Play configuration +# +# CONFIG_PNP is not set +# CONFIG_ISAPNP is not set +# CONFIG_PNPBIOS is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_VIODASD is not set +# CONFIG_BLK_DEV_XD is not set +# CONFIG_PARIDE is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_INITRD=y + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set +# CONFIG_BLK_DEV_MD is not set +# CONFIG_MD_LINEAR is not set +# CONFIG_MD_RAID0 is not set +# CONFIG_MD_RAID1 is not set +# CONFIG_MD_RAID5 is not set +# CONFIG_MD_MULTIPATH is not set +# CONFIG_BLK_DEV_LVM is not set + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_NETLINK=y +# CONFIG_RTNETLINK is not set +# CONFIG_NETLINK_DEV is not set +# CONFIG_NETFILTER is not set +# CONFIG_FILTER is not set +CONFIG_UNIX=y +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +# CONFIG_IP_PNP_BOOTP is not set +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_IPV6 is not set +# CONFIG_KHTTPD is not set +# CONFIG_ATM is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# ATA/IDE/MFM/RLL support +# +# CONFIG_IDE is not set +# CONFIG_BLK_DEV_IDE_MODES is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI support +# +# CONFIG_SCSI is not set + +# +# IEEE 1394 (FireWire) support (EXPERIMENTAL) +# +# CONFIG_IEEE1394 is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_MACE is not set +# CONFIG_BMAC is not set +# CONFIG_GMAC is not set +# CONFIG_SUNLANCE is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNBMAC is not set +# CONFIG_SUNQE is not set +# CONFIG_SUNLANCE is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_HP100 is not set +# CONFIG_NET_ISA is not set +CONFIG_NET_PCI=y +# CONFIG_PCNET32 is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_APRICOT is not set +# CONFIG_CS89x0 is not set +CONFIG_TULIP=y +# CONFIG_TULIP_MWI is not set +# CONFIG_TULIP_MMIO is not set +# CONFIG_DE4X5 is not set +# CONFIG_DGRS is not set +# CONFIG_DM9102 is not set +# CONFIG_EEPRO100 is not set +# CONFIG_LNE390 is not set +# CONFIG_FEALNX is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_NE3210 is not set +# CONFIG_ES3210 is not set +# CONFIG_8139TOO is not set +# CONFIG_8139TOO_PIO is not set +# CONFIG_8139TOO_TUNE_TWISTER is not set +# CONFIG_8139TOO_8129 is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_TLAN is not set +# CONFIG_VIA_RHINE is not set +# CONFIG_WINBOND_840 is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_MYRI_SBUS is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_SK98LIN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Old CD-ROM drivers (not SCSI, not IDE) +# +# CONFIG_CD_NO_IDESCSI is not set + +# +# Console drivers +# +# CONFIG_VGA_CONSOLE is not set + +# +# Frame-buffer support +# +# CONFIG_FB is not set + +# +# Input core support +# +# CONFIG_INPUT is not set +# CONFIG_INPUT_KEYBDEV is not set +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set + +# +# Macintosh device drivers +# + +# +# Character devices +# +# CONFIG_VT is not set +CONFIG_SERIAL=y +CONFIG_SERIAL_CONSOLE=y +CONFIG_SERIAL_EXTENDED=y +# CONFIG_SERIAL_MANY_PORTS is not set +CONFIG_SERIAL_SHARE_IRQ=y +CONFIG_SERIAL_DETECT_IRQ=y +# CONFIG_SERIAL_MULTIPORT is not set +# CONFIG_HUB6 is not set +# CONFIG_SERIAL_NONSTANDARD is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 +# CONFIG_VIOCONS is not set + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set + +# +# Joysticks +# +# CONFIG_INPUT_GAMEPORT is not set +# CONFIG_QIC02_TAPE is not set +# CONFIG_VIOTAPE is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_INTEL_RNG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set +# CONFIG_ADFS_FS is not set +# CONFIG_ADFS_FS_RW is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_FAT_FS is not set +# CONFIG_MSDOS_FS is not set +# CONFIG_UMSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_TMPFS is not set +# CONFIG_RAMFS is not set +# CONFIG_ISO9660_FS is not set +# CONFIG_JOLIET is not set +# CONFIG_MINIX_FS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_NTFS_FS is not set +# CONFIG_NTFS_RW is not set +# CONFIG_HPFS_FS is not set +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVFS_MOUNT is not set +# CONFIG_DEVFS_DEBUG is not set +CONFIG_DEVPTS_FS=y +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_EXT2_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UDF_FS is not set +# CONFIG_UDF_RW is not set +# CONFIG_UFS_FS is not set +# CONFIG_UFS_FS_WRITE is not set + +# +# Network File Systems +# +# CONFIG_CODA_FS is not set +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +CONFIG_ROOT_NFS=y +# CONFIG_NFSD is not set +# CONFIG_NFSD_V3 is not set +CONFIG_SUNRPC=y +CONFIG_LOCKD=y +# CONFIG_SMB_FS is not set +# CONFIG_NCP_FS is not set +# CONFIG_NCPFS_PACKET_SIGNING is not set +# CONFIG_NCPFS_IOCTL_LOCKING is not set +# CONFIG_NCPFS_STRONG is not set +# CONFIG_NCPFS_NFS_NS is not set +# CONFIG_NCPFS_OS2_NS is not set +# CONFIG_NCPFS_SMALLDOS is not set +# CONFIG_NCPFS_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_SMB_NLS is not set +# CONFIG_NLS is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB is not set + +# +# Bluetooth support +# +# CONFIG_BLUEZ is not set + +# +# Kernel hacking +# +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_KGDB is not set +# CONFIG_XMON is not set +# CONFIG_BDI_SWITCH is not set +# CONFIG_DEBUG_TEXT is not set diff --git a/arch/ppc/configs/menf1_defconfig b/arch/ppc/configs/menf1_defconfig new file mode 100644 index 000000000000..0cb62d0a4ebe --- /dev/null +++ b/arch/ppc/configs/menf1_defconfig @@ -0,0 +1,684 @@ +# +# Automatically generated make config: don't edit +# +# CONFIG_UID16 is not set +# CONFIG_RWSEM_GENERIC_SPINLOCK is not set +CONFIG_RWSEM_XCHGADD_ALGORITHM=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODVERSIONS=y +CONFIG_KMOD=y + +# +# Platform support +# +CONFIG_PPC=y +CONFIG_PPC32=y +CONFIG_6xx=y +# CONFIG_4xx is not set +# CONFIG_POWER3 is not set +# CONFIG_8xx is not set +# CONFIG_PPC_ISERIES is not set +# CONFIG_8260 is not set +CONFIG_PPC_STD_MMU=y +# CONFIG_ALL_PPC is not set +# CONFIG_APUS is not set +# CONFIG_SPRUCE is not set +# CONFIG_PCORE is not set +CONFIG_MENF1=y +# CONFIG_LOPEC is not set +# CONFIG_MCPN765 is not set +# CONFIG_MVME5100 is not set +# CONFIG_PRPMC750 is not set +# CONFIG_PRPMC800 is not set +# CONFIG_SANDPOINT is not set +# CONFIG_ADIR is not set +# CONFIG_K2 is not set +# CONFIG_GEMINI is not set +# CONFIG_WILLOW is not set +# CONFIG_ZX4500 is not set +CONFIG_MPC10X_STORE_GATHERING=y +# CONFIG_SMP is not set +# CONFIG_ALTIVEC is not set +# CONFIG_TAU is not set + +# +# General setup +# +# CONFIG_HIGHMEM is not set +# CONFIG_ISA is not set +# CONFIG_EISA is not set +# CONFIG_SBUS is not set +# CONFIG_MCA is not set +CONFIG_PCI=y +CONFIG_NET=y +CONFIG_SYSCTL=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_KCORE_ELF=y +CONFIG_BINFMT_ELF=y +CONFIG_KERNEL_ELF=y +# CONFIG_BINFMT_MISC is not set +# CONFIG_PCI_NAMES is not set +# CONFIG_HOTPLUG is not set +# CONFIG_PCMCIA is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set +CONFIG_PPC_RTC=y +CONFIG_CMDLINE_BOOL=y +CONFIG_CMDLINE="ip=on" + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Plug and Play configuration +# +# CONFIG_PNP is not set +# CONFIG_ISAPNP is not set +# CONFIG_PNPBIOS is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_XD is not set +# CONFIG_PARIDE is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_BLK_DEV_INITRD is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set +# CONFIG_BLK_DEV_MD is not set +# CONFIG_MD_LINEAR is not set +# CONFIG_MD_RAID0 is not set +# CONFIG_MD_RAID1 is not set +# CONFIG_MD_RAID5 is not set +# CONFIG_MD_MULTIPATH is not set +# CONFIG_BLK_DEV_LVM is not set + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_NETLINK=y +# CONFIG_RTNETLINK is not set +# CONFIG_NETLINK_DEV is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +# CONFIG_FILTER is not set +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +# CONFIG_IP_PNP_BOOTP is not set +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set + +# +# IP: Netfilter Configuration +# +CONFIG_IP_NF_CONNTRACK=m +CONFIG_IP_NF_FTP=m +# CONFIG_IP_NF_QUEUE is not set +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_LIMIT=m +CONFIG_IP_NF_MATCH_MAC=m +CONFIG_IP_NF_MATCH_MARK=m +CONFIG_IP_NF_MATCH_MULTIPORT=m +CONFIG_IP_NF_MATCH_TOS=m +CONFIG_IP_NF_MATCH_TCPMSS=m +CONFIG_IP_NF_MATCH_STATE=m +CONFIG_IP_NF_MATCH_UNCLEAN=m +CONFIG_IP_NF_MATCH_OWNER=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_MIRROR=m +CONFIG_IP_NF_NAT=m +CONFIG_IP_NF_NAT_NEEDED=y +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_NAT_FTP=m +# CONFIG_IP_NF_MANGLE is not set +# CONFIG_IP_NF_TARGET_LOG is not set +CONFIG_IP_NF_TARGET_TCPMSS=m +CONFIG_IP_NF_COMPAT_IPCHAINS=m +CONFIG_IP_NF_NAT_NEEDED=y +# CONFIG_IP_NF_COMPAT_IPFWADM is not set +# CONFIG_IPV6 is not set +# CONFIG_KHTTPD is not set +# CONFIG_ATM is not set + +# +# +# +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# ATA/IDE/MFM/RLL support +# +CONFIG_IDE=y + +# +# IDE, ATA and ATAPI Block devices +# +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_HD_IDE is not set +# CONFIG_BLK_DEV_HD is not set +CONFIG_BLK_DEV_IDEDISK=y +# CONFIG_IDEDISK_MULTI_MODE is not set +# CONFIG_BLK_DEV_IDEDISK_VENDOR is not set +# CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set +# CONFIG_BLK_DEV_IDEDISK_IBM is not set +# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set +# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set +# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set +# CONFIG_BLK_DEV_IDEDISK_WD is not set +# CONFIG_BLK_DEV_COMMERIAL is not set +# CONFIG_BLK_DEV_TIVO is not set +# CONFIG_BLK_DEV_IDECS is not set +CONFIG_BLK_DEV_IDECD=y +# CONFIG_BLK_DEV_IDETAPE is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set +# CONFIG_BLK_DEV_IDESCSI is not set + +# +# IDE chipset support/bugfixes +# +# CONFIG_BLK_DEV_CMD640 is not set +# CONFIG_BLK_DEV_CMD640_ENHANCED is not set +# CONFIG_BLK_DEV_ISAPNP is not set +# CONFIG_BLK_DEV_RZ1000 is not set +CONFIG_BLK_DEV_IDEPCI=y +# CONFIG_IDEPCI_SHARE_IRQ is not set +# CONFIG_BLK_DEV_IDEDMA_PCI is not set +# CONFIG_BLK_DEV_ADMA is not set +# CONFIG_BLK_DEV_OFFBOARD is not set +# CONFIG_IDEDMA_PCI_AUTO is not set +# CONFIG_BLK_DEV_IDEDMA is not set +# CONFIG_IDEDMA_PCI_WIP is not set +# CONFIG_IDEDMA_NEW_DRIVE_LISTINGS is not set +# CONFIG_BLK_DEV_AEC62XX is not set +# CONFIG_AEC62XX_TUNING is not set +# CONFIG_BLK_DEV_ALI15X3 is not set +# CONFIG_WDC_ALI15X3 is not set +# CONFIG_BLK_DEV_AMD74XX is not set +# CONFIG_AMD74XX_OVERRIDE is not set +# CONFIG_BLK_DEV_CMD64X is not set +# CONFIG_BLK_DEV_CY82C693 is not set +# CONFIG_BLK_DEV_CS5530 is not set +# CONFIG_BLK_DEV_HPT34X is not set +# CONFIG_HPT34X_AUTODMA is not set +# CONFIG_BLK_DEV_HPT366 is not set +# CONFIG_BLK_DEV_NS87415 is not set +# CONFIG_BLK_DEV_OPTI621 is not set +# CONFIG_BLK_DEV_PDC202XX is not set +# CONFIG_PDC202XX_BURST is not set +# CONFIG_PDC202XX_FORCE is not set +# CONFIG_BLK_DEV_SVWKS is not set +# CONFIG_BLK_DEV_SIS5513 is not set +# CONFIG_BLK_DEV_SLC90E66 is not set +# CONFIG_BLK_DEV_TRM290 is not set +# CONFIG_BLK_DEV_VIA82CXXX is not set +# CONFIG_BLK_DEV_SL82C105 is not set +# CONFIG_IDE_CHIPSETS is not set +# CONFIG_IDEDMA_AUTO is not set +# CONFIG_DMA_NONPCI is not set +# CONFIG_BLK_DEV_IDE_MODES is not set +# CONFIG_BLK_DEV_ATARAID is not set +# CONFIG_BLK_DEV_ATARAID_PDC is not set +# CONFIG_BLK_DEV_ATARAID_HPT is not set + +# +# SCSI support +# +# CONFIG_SCSI is not set + +# +# IEEE 1394 (FireWire) support (EXPERIMENTAL) +# +# CONFIG_IEEE1394 is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_MACE is not set +# CONFIG_BMAC is not set +# CONFIG_GMAC is not set +# CONFIG_SUNLANCE is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNBMAC is not set +# CONFIG_SUNQE is not set +# CONFIG_SUNLANCE is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_HP100 is not set +# CONFIG_NET_ISA is not set +CONFIG_NET_PCI=y +# CONFIG_PCNET32 is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_APRICOT is not set +# CONFIG_CS89x0 is not set +CONFIG_TULIP=y +# CONFIG_TULIP_MWI is not set +# CONFIG_TULIP_MMIO is not set +# CONFIG_DE4X5 is not set +# CONFIG_DGRS is not set +# CONFIG_DM9102 is not set +# CONFIG_EEPRO100 is not set +# CONFIG_LNE390 is not set +# CONFIG_FEALNX is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_NE3210 is not set +# CONFIG_ES3210 is not set +# CONFIG_8139CP is not set +# CONFIG_8139TOO is not set +# CONFIG_8139TOO_PIO is not set +# CONFIG_8139TOO_TUNE_TWISTER is not set +# CONFIG_8139TOO_8129 is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_TLAN is not set +# CONFIG_VIA_RHINE is not set +# CONFIG_WINBOND_840 is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_MYRI_SBUS is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_SK98LIN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Old CD-ROM drivers (not SCSI, not IDE) +# +# CONFIG_CD_NO_IDESCSI is not set + +# +# Console drivers +# +# CONFIG_VGA_CONSOLE is not set + +# +# Frame-buffer support +# +# CONFIG_FB is not set + +# +# Input core support +# +# CONFIG_INPUT is not set +# CONFIG_INPUT_KEYBDEV is not set +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set + +# +# Macintosh device drivers +# + +# +# Character devices +# +# CONFIG_VT is not set +CONFIG_SERIAL=y +CONFIG_SERIAL_CONSOLE=y +# CONFIG_SERIAL_EXTENDED is not set +# CONFIG_SERIAL_NONSTANDARD is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set + +# +# Joysticks +# +# CONFIG_INPUT_GAMEPORT is not set + +# +# Input core support is needed for gameports +# + +# +# Input core support is needed for joysticks +# +# CONFIG_QIC02_TAPE is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_INTEL_RNG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set +# CONFIG_MWAVE is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set +# CONFIG_ADFS_FS is not set +# CONFIG_ADFS_FS_RW is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_FAT_FS is not set +# CONFIG_MSDOS_FS is not set +# CONFIG_UMSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_CRAMFS is not set +CONFIG_TMPFS=y +# CONFIG_RAMFS is not set +CONFIG_ISO9660_FS=y +# CONFIG_JOLIET is not set +# CONFIG_MINIX_FS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_NTFS_FS is not set +# CONFIG_NTFS_RW is not set +# CONFIG_HPFS_FS is not set +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVFS_MOUNT is not set +# CONFIG_DEVFS_DEBUG is not set +CONFIG_DEVPTS_FS=y +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set +# CONFIG_ROMFS_FS is not set +CONFIG_EXT2_FS=y +# CONFIG_SYSV_FS is not set +# CONFIG_UDF_FS is not set +# CONFIG_UDF_RW is not set +# CONFIG_UFS_FS is not set +# CONFIG_UFS_FS_WRITE is not set + +# +# Network File Systems +# +# CONFIG_CODA_FS is not set +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +CONFIG_ROOT_NFS=y +# CONFIG_NFSD is not set +# CONFIG_NFSD_V3 is not set +CONFIG_SUNRPC=y +CONFIG_LOCKD=y +# CONFIG_SMB_FS is not set +# CONFIG_NCP_FS is not set +# CONFIG_NCPFS_PACKET_SIGNING is not set +# CONFIG_NCPFS_IOCTL_LOCKING is not set +# CONFIG_NCPFS_STRONG is not set +# CONFIG_NCPFS_NFS_NS is not set +# CONFIG_NCPFS_OS2_NS is not set +# CONFIG_NCPFS_SMALLDOS is not set +# CONFIG_NCPFS_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_SMB_NLS is not set +# CONFIG_NLS is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB is not set + +# +# USB Controllers +# +# CONFIG_USB_UHCI is not set +# CONFIG_USB_UHCI_ALT is not set +# CONFIG_USB_OHCI is not set + +# +# USB Device Class drivers +# +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_BLUETOOTH is not set +# CONFIG_USB_STORAGE is not set +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_HP8200e is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set + +# +# USB Human Interface Devices (HID) +# + +# +# Input core support is needed for USB HID +# + +# +# USB Imaging devices +# +# CONFIG_USB_DC2XX is not set +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_SCANNER is not set +# CONFIG_USB_MICROTEK is not set +# CONFIG_USB_HPUSBSCSI is not set + +# +# USB Multimedia devices +# + +# +# Video4Linux support is needed for USB Multimedia device support +# + +# +# USB Network adaptors +# +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_CATC is not set +# CONFIG_USB_CDCETHER is not set +# CONFIG_USB_USBNET is not set + +# +# USB port drivers +# +# CONFIG_USB_USS720 is not set + +# +# USB Serial Converter support +# +# CONFIG_USB_SERIAL is not set +# CONFIG_USB_SERIAL_GENERIC is not set +# CONFIG_USB_SERIAL_BELKIN is not set +# CONFIG_USB_SERIAL_WHITEHEAT is not set +# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set +# CONFIG_USB_SERIAL_EMPEG is not set +# CONFIG_USB_SERIAL_FTDI_SIO is not set +# CONFIG_USB_SERIAL_VISOR is not set +# CONFIG_USB_SERIAL_IR is not set +# CONFIG_USB_SERIAL_EDGEPORT is not set +# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set +# CONFIG_USB_SERIAL_KEYSPAN is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set +# CONFIG_USB_SERIAL_MCT_U232 is not set +# CONFIG_USB_SERIAL_PL2303 is not set +# CONFIG_USB_SERIAL_CYBERJACK is not set +# CONFIG_USB_SERIAL_XIRCOM is not set +# CONFIG_USB_SERIAL_OMNINET is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_RIO500 is not set + +# +# Bluetooth support +# +# CONFIG_BLUEZ is not set + +# +# Kernel hacking +# +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_KGDB is not set +# CONFIG_XMON is not set +# CONFIG_BDI_SWITCH is not set diff --git a/arch/ppc/configs/mvme5100_defconfig b/arch/ppc/configs/mvme5100_defconfig new file mode 100644 index 000000000000..66bbeaebd59f --- /dev/null +++ b/arch/ppc/configs/mvme5100_defconfig @@ -0,0 +1,630 @@ +# +# Automatically generated make config: don't edit +# +# CONFIG_UID16 is not set +# CONFIG_RWSEM_GENERIC_SPINLOCK is not set +CONFIG_RWSEM_XCHGADD_ALGORITHM=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODVERSIONS=y +CONFIG_KMOD=y + +# +# Platform support +# +CONFIG_PPC=y +CONFIG_PPC32=y +CONFIG_6xx=y +# CONFIG_4xx is not set +# CONFIG_POWER3 is not set +# CONFIG_8xx is not set +# CONFIG_8260 is not set +# CONFIG_ALL_PPC is not set +# CONFIG_APUS is not set +# CONFIG_SPRUCE is not set +# CONFIG_PCORE is not set +# CONFIG_MENF1 is not set +# CONFIG_MCPN765 is not set +CONFIG_MVME5100=y +# CONFIG_PRPMC750 is not set +# CONFIG_SANDPOINT is not set +# CONFIG_K2 is not set +# CONFIG_GEMINI is not set +# CONFIG_ZX4500 is not set +# CONFIG_MVME5100_IPMC761_PRESENT is not set +# CONFIG_PPC601_SYNC_FIX is not set +# CONFIG_SMP is not set +CONFIG_ALTIVEC=y +# CONFIG_TAU is not set + +# +# General setup +# +# CONFIG_HIGHMEM is not set +# CONFIG_ISA is not set +# CONFIG_EISA is not set +# CONFIG_SBUS is not set +# CONFIG_MCA is not set +CONFIG_PCI=y +CONFIG_NET=y +CONFIG_SYSCTL=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_KCORE_ELF=y +CONFIG_BINFMT_ELF=y +CONFIG_KERNEL_ELF=y +# CONFIG_BINFMT_MISC is not set +# CONFIG_PCI_NAMES is not set +# CONFIG_HOTPLUG is not set +# CONFIG_PCMCIA is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set +CONFIG_PPC_RTC=y +CONFIG_CMDLINE_BOOL=y +CONFIG_CMDLINE="ip=on" + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Plug and Play configuration +# +# CONFIG_PNP is not set +# CONFIG_ISAPNP is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_XD is not set +# CONFIG_PARIDE is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_INITRD=y + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set +# CONFIG_BLK_DEV_MD is not set +# CONFIG_MD_LINEAR is not set +# CONFIG_MD_RAID0 is not set +# CONFIG_MD_RAID1 is not set +# CONFIG_MD_RAID5 is not set +# CONFIG_BLK_DEV_LVM is not set + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_NETLINK=y +# CONFIG_RTNETLINK is not set +# CONFIG_NETLINK_DEV is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_FILTER=y +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +# CONFIG_IP_PNP_BOOTP is not set +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set + +# +# IP: Netfilter Configuration +# +CONFIG_IP_NF_CONNTRACK=m +CONFIG_IP_NF_FTP=m +# CONFIG_IP_NF_QUEUE is not set +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_LIMIT=m +CONFIG_IP_NF_MATCH_MAC=m +CONFIG_IP_NF_MATCH_MARK=m +CONFIG_IP_NF_MATCH_MULTIPORT=m +CONFIG_IP_NF_MATCH_TOS=m +CONFIG_IP_NF_MATCH_TCPMSS=m +CONFIG_IP_NF_MATCH_STATE=m +CONFIG_IP_NF_MATCH_UNCLEAN=m +CONFIG_IP_NF_MATCH_OWNER=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_MIRROR=m +CONFIG_IP_NF_NAT=m +CONFIG_IP_NF_NAT_NEEDED=y +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_NAT_FTP=m +# CONFIG_IP_NF_MANGLE is not set +# CONFIG_IP_NF_TARGET_LOG is not set +CONFIG_IP_NF_TARGET_TCPMSS=m +CONFIG_IP_NF_COMPAT_IPCHAINS=m +CONFIG_IP_NF_NAT_NEEDED=y +# CONFIG_IP_NF_COMPAT_IPFWADM is not set +# CONFIG_IPV6 is not set +# CONFIG_KHTTPD is not set +# CONFIG_ATM is not set + +# +# +# +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# ATA/IDE/MFM/RLL support +# +CONFIG_IDE=y + +# +# IDE, ATA and ATAPI Block devices +# +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_HD_IDE is not set +# CONFIG_BLK_DEV_HD is not set +CONFIG_BLK_DEV_IDEDISK=y +# CONFIG_IDEDISK_MULTI_MODE is not set +# CONFIG_BLK_DEV_IDEDISK_VENDOR is not set +# CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set +# CONFIG_BLK_DEV_IDEDISK_IBM is not set +# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set +# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set +# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set +# CONFIG_BLK_DEV_IDEDISK_WD is not set +# CONFIG_BLK_DEV_COMMERIAL is not set +# CONFIG_BLK_DEV_TIVO is not set +# CONFIG_BLK_DEV_IDECS is not set +# CONFIG_BLK_DEV_IDECD is not set +# CONFIG_BLK_DEV_IDETAPE is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set +# CONFIG_BLK_DEV_IDESCSI is not set + +# +# IDE chipset support/bugfixes +# +# CONFIG_BLK_DEV_CMD640 is not set +# CONFIG_BLK_DEV_CMD640_ENHANCED is not set +# CONFIG_BLK_DEV_ISAPNP is not set +# CONFIG_BLK_DEV_RZ1000 is not set +CONFIG_BLK_DEV_IDEPCI=y +# CONFIG_IDEPCI_SHARE_IRQ is not set +# CONFIG_BLK_DEV_IDEDMA_PCI is not set +# CONFIG_BLK_DEV_OFFBOARD is not set +# CONFIG_IDEDMA_PCI_AUTO is not set +# CONFIG_BLK_DEV_IDEDMA is not set +# CONFIG_IDEDMA_PCI_WIP is not set +# CONFIG_IDEDMA_NEW_DRIVE_LISTINGS is not set +# CONFIG_BLK_DEV_AEC62XX is not set +# CONFIG_AEC62XX_TUNING is not set +# CONFIG_BLK_DEV_ALI15X3 is not set +# CONFIG_WDC_ALI15X3 is not set +# CONFIG_BLK_DEV_AMD7409 is not set +# CONFIG_AMD7409_OVERRIDE is not set +# CONFIG_BLK_DEV_CMD64X is not set +# CONFIG_BLK_DEV_CY82C693 is not set +# CONFIG_BLK_DEV_CS5530 is not set +# CONFIG_BLK_DEV_HPT34X is not set +# CONFIG_HPT34X_AUTODMA is not set +# CONFIG_BLK_DEV_HPT366 is not set +# CONFIG_BLK_DEV_NS87415 is not set +# CONFIG_BLK_DEV_OPTI621 is not set +# CONFIG_BLK_DEV_PDC202XX is not set +# CONFIG_PDC202XX_BURST is not set +# CONFIG_BLK_DEV_OSB4 is not set +# CONFIG_BLK_DEV_SIS5513 is not set +# CONFIG_BLK_DEV_SLC90E66 is not set +# CONFIG_BLK_DEV_TRM290 is not set +# CONFIG_BLK_DEV_VIA82CXXX is not set +# CONFIG_BLK_DEV_SL82C105 is not set +# CONFIG_IDE_CHIPSETS is not set +# CONFIG_IDEDMA_AUTO is not set +# CONFIG_DMA_NONPCI is not set +# CONFIG_BLK_DEV_IDE_MODES is not set + +# +# SCSI support +# +CONFIG_SCSI=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +CONFIG_SD_EXTRA_DEVS=40 +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +CONFIG_BLK_DEV_SR=y +# CONFIG_BLK_DEV_SR_VENDOR is not set +CONFIG_SR_EXTRA_DEVS=2 +# CONFIG_CHR_DEV_SG is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_DEBUG_QUEUES is not set +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set + +# +# SCSI low-level drivers +# +# CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_7000FASST is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_AHA152X is not set +# CONFIG_SCSI_AHA1542 is not set +# CONFIG_SCSI_AHA1740 is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_ADVANSYS is not set +# CONFIG_SCSI_IN2000 is not set +# CONFIG_SCSI_AM53C974 is not set +# CONFIG_SCSI_MEGARAID is not set +# CONFIG_SCSI_BUSLOGIC is not set +# CONFIG_SCSI_CPQFCTS is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_DTC3280 is not set +# CONFIG_SCSI_EATA is not set +# CONFIG_SCSI_EATA_DMA is not set +# CONFIG_SCSI_EATA_PIO is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_GDTH is not set +# CONFIG_SCSI_GENERIC_NCR5380 is not set +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_NCR53C406A is not set +# CONFIG_SCSI_NCR53C7xx is not set +# CONFIG_SCSI_NCR53C8XX is not set +CONFIG_SCSI_SYM53C8XX=y +CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=8 +CONFIG_SCSI_NCR53C8XX_MAX_TAGS=32 +CONFIG_SCSI_NCR53C8XX_SYNC=20 +# CONFIG_SCSI_NCR53C8XX_PROFILE is not set +# CONFIG_SCSI_NCR53C8XX_IOMAPPED is not set +# CONFIG_SCSI_NCR53C8XX_PQS_PDS is not set +# CONFIG_SCSI_NCR53C8XX_SYMBIOS_COMPAT is not set +# CONFIG_SCSI_PAS16 is not set +# CONFIG_SCSI_PCI2000 is not set +# CONFIG_SCSI_PCI2220I is not set +# CONFIG_SCSI_PSI240I is not set +# CONFIG_SCSI_QLOGIC_FAS is not set +# CONFIG_SCSI_QLOGIC_ISP is not set +# CONFIG_SCSI_QLOGIC_FC is not set +# CONFIG_SCSI_QLOGIC_1280 is not set +# CONFIG_SCSI_SIM710 is not set +# CONFIG_SCSI_SYM53C416 is not set +# CONFIG_SCSI_DC390T is not set +# CONFIG_SCSI_T128 is not set +# CONFIG_SCSI_U14_34F is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_MESH is not set +# CONFIG_SCSI_MAC53C94 is not set + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set +# CONFIG_NET_SB1000 is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_MACE is not set +# CONFIG_BMAC is not set +# CONFIG_GMAC is not set +# CONFIG_NCR885E is not set +# CONFIG_OAKNET is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_AT1700 is not set +# CONFIG_DEPCA is not set +# CONFIG_HP100 is not set +# CONFIG_NET_ISA is not set +CONFIG_NET_PCI=y +# CONFIG_PCNET32 is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_APRICOT is not set +# CONFIG_CS89x0 is not set +CONFIG_TULIP=y +# CONFIG_DE4X5 is not set +# CONFIG_DGRS is not set +# CONFIG_DM9102 is not set +CONFIG_EEPRO100=y +# CONFIG_EEPRO100_PM is not set +# CONFIG_LNE390 is not set +# CONFIG_FEALNX is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_NE3210 is not set +# CONFIG_ES3210 is not set +# CONFIG_8139TOO is not set +# CONFIG_8139TOO_PIO is not set +# CONFIG_8139TOO_TUNE_TWISTER is not set +# CONFIG_8139TOO_8129 is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_TLAN is not set +# CONFIG_VIA_RHINE is not set +# CONFIG_WINBOND_840 is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_SK98LIN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Old CD-ROM drivers (not SCSI, not IDE) +# +# CONFIG_CD_NO_IDESCSI is not set + +# +# Console drivers +# +# CONFIG_VGA_CONSOLE is not set + +# +# Frame-buffer support +# +# CONFIG_FB is not set + +# +# Input core support +# +# CONFIG_INPUT is not set + +# +# Macintosh device drivers +# + +# +# Character devices +# +# CONFIG_VT is not set +CONFIG_SERIAL=y +CONFIG_SERIAL_CONSOLE=y +# CONFIG_SERIAL_EXTENDED is not set +# CONFIG_SERIAL_NONSTANDARD is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set + +# +# Joysticks +# +# CONFIG_JOYSTICK is not set + +# +# Input core support is needed for joysticks +# +# CONFIG_QIC02_TAPE is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_INTEL_RNG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set +# CONFIG_ADFS_FS is not set +# CONFIG_ADFS_FS_RW is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_FAT_FS is not set +# CONFIG_MSDOS_FS is not set +# CONFIG_UMSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_CRAMFS is not set +CONFIG_TMPFS=y +# CONFIG_RAMFS is not set +# CONFIG_ISO9660_FS is not set +# CONFIG_JOLIET is not set +# CONFIG_MINIX_FS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_NTFS_FS is not set +# CONFIG_NTFS_RW is not set +# CONFIG_HPFS_FS is not set +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVFS_MOUNT is not set +# CONFIG_DEVFS_DEBUG is not set +CONFIG_DEVPTS_FS=y +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set +# CONFIG_ROMFS_FS is not set +CONFIG_EXT2_FS=y +# CONFIG_SYSV_FS is not set +# CONFIG_SYSV_FS_WRITE is not set +# CONFIG_UDF_FS is not set +# CONFIG_UDF_RW is not set +# CONFIG_UFS_FS is not set +# CONFIG_UFS_FS_WRITE is not set + +# +# Network File Systems +# +# CONFIG_CODA_FS is not set +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +CONFIG_ROOT_NFS=y +# CONFIG_NFSD is not set +# CONFIG_NFSD_V3 is not set +CONFIG_SUNRPC=y +CONFIG_LOCKD=y +# CONFIG_SMB_FS is not set +# CONFIG_NCP_FS is not set +# CONFIG_NCPFS_PACKET_SIGNING is not set +# CONFIG_NCPFS_IOCTL_LOCKING is not set +# CONFIG_NCPFS_STRONG is not set +# CONFIG_NCPFS_NFS_NS is not set +# CONFIG_NCPFS_OS2_NS is not set +# CONFIG_NCPFS_SMALLDOS is not set +# CONFIG_NCPFS_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_SMB_NLS is not set +# CONFIG_NLS is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB is not set + +# +# Kernel hacking +# +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_KGDB is not set +# CONFIG_XMON is not set diff --git a/arch/ppc/configs/oak_defconfig b/arch/ppc/configs/oak_defconfig index 521a42553618..68528bf4eba4 100644 --- a/arch/ppc/configs/oak_defconfig +++ b/arch/ppc/configs/oak_defconfig @@ -4,6 +4,7 @@ # CONFIG_UID16 is not set # CONFIG_RWSEM_GENERIC_SPINLOCK is not set CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_HAVE_DEC_LOCK=y # # Code maturity level options @@ -25,14 +26,27 @@ CONFIG_PPC32=y # CONFIG_6xx is not set CONFIG_4xx=y # CONFIG_POWER3 is not set -# CONFIG_POWER4 is not set # CONFIG_8xx is not set +# CONFIG_PPC_ISERIES is not set # CONFIG_PPC_STD_MMU is not set +# CONFIG_CEDER is not set +# CONFIG_CPCI405 is not set +# CONFIG_EP405 is not set CONFIG_OAK=y +# CONFIG_REDWOOD_4 is not set +# CONFIG_REDWOOD_5 is not set +# CONFIG_TIVO is not set # CONFIG_WALNUT is not set # CONFIG_ALL_PPC is not set # CONFIG_SMP is not set # CONFIG_MATH_EMULATION is not set +CONFIG_403GCX=y +CONFIG_TREEBOOT=y +# CONFIG_405_DMA is not set +CONFIG_UART0_TTYS0=y +# CONFIG_UART0_TTYS1 is not set +CONFIG_IBM405_ERR51=y +CONFIG_NOT_COHERENT_CACHE=y # # General setup @@ -43,6 +57,7 @@ CONFIG_OAK=y # CONFIG_SBUS is not set # CONFIG_MCA is not set # CONFIG_PCI is not set +# CONFIG_PC_KEYBOARD is not set CONFIG_NET=y CONFIG_SYSCTL=y CONFIG_SYSVIPC=y @@ -58,6 +73,7 @@ CONFIG_KERNEL_ELF=y # Parallel port support # # CONFIG_PARPORT is not set +CONFIG_PPC_RTC=y # CONFIG_CMDLINE_BOOL is not set # @@ -102,7 +118,7 @@ CONFIG_BLK_DEV_INITRD=y # Networking options # # CONFIG_PACKET is not set -# CONFIG_NETLINK is not set +# CONFIG_NETLINK_DEV is not set # CONFIG_NETFILTER is not set # CONFIG_FILTER is not set CONFIG_UNIX=y @@ -116,6 +132,7 @@ CONFIG_IP_PNP_RARP=y # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set # CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set # CONFIG_INET_ECN is not set CONFIG_SYN_COOKIES=y # CONFIG_IPV6 is not set @@ -128,6 +145,18 @@ CONFIG_SYN_COOKIES=y # # CONFIG_IPX is not set # CONFIG_ATALK is not set + +# +# Appletalk devices +# +# CONFIG_DEV_APPLETALK is not set +# CONFIG_LTPC is not set +# CONFIG_COPS is not set +# CONFIG_COPS_DAYNA is not set +# CONFIG_COPS_TANGENT is not set +# CONFIG_IPDDP is not set +# CONFIG_IPDDP_ENCAP is not set +# CONFIG_IPDDP_DECAP is not set # CONFIG_DECNET is not set # CONFIG_BRIDGE is not set # CONFIG_X25 is not set @@ -157,6 +186,24 @@ CONFIG_SYN_COOKIES=y # CONFIG_SCSI is not set # +# Fusion MPT device support +# +# CONFIG_FUSION is not set +# CONFIG_FUSION_BOOT is not set +# CONFIG_FUSION_ISENSE is not set +# CONFIG_FUSION_CTL is not set +# CONFIG_FUSION_LAN is not set + +# +# I2O device support +# +# CONFIG_I2O is not set +# CONFIG_I2O_BLOCK is not set +# CONFIG_I2O_LAN is not set +# CONFIG_I2O_SCSI is not set +# CONFIG_I2O_PROC is not set + +# # Network device support # CONFIG_NETDEVICES=y @@ -169,6 +216,7 @@ CONFIG_NETDEVICES=y # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set # # Ethernet (10 or 100Mbit) @@ -177,6 +225,7 @@ CONFIG_NET_ETHERNET=y # CONFIG_MACE is not set # CONFIG_BMAC is not set # CONFIG_GMAC is not set +CONFIG_OAKNET=y # CONFIG_SUNLANCE is not set # CONFIG_SUNBMAC is not set # CONFIG_SUNQE is not set @@ -332,11 +381,15 @@ CONFIG_SERIAL_CONSOLE=y # CONFIG_AUTOFS4_FS is not set # CONFIG_REISERFS_FS is not set # CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set # CONFIG_ADFS_FS is not set # CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set # CONFIG_BFS_FS is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_JBD_DEBUG is not set # CONFIG_FAT_FS is not set # CONFIG_MSDOS_FS is not set # CONFIG_UMSDOS_FS is not set @@ -349,6 +402,7 @@ CONFIG_TMPFS=y # CONFIG_RAMFS is not set # CONFIG_ISO9660_FS is not set # CONFIG_JOLIET is not set +# CONFIG_ZISOFS is not set # CONFIG_MINIX_FS is not set # CONFIG_VXFS_FS is not set # CONFIG_NTFS_FS is not set @@ -373,6 +427,7 @@ CONFIG_EXT2_FS=y # Network File Systems # # CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set CONFIG_NFS_FS=y # CONFIG_NFS_V3 is not set CONFIG_ROOT_NFS=y @@ -390,6 +445,8 @@ CONFIG_LOCKD=y # CONFIG_NCPFS_SMALLDOS is not set # CONFIG_NCPFS_NLS is not set # CONFIG_NCPFS_EXTRAS is not set +# CONFIG_ZISOFS_FS is not set +# CONFIG_ZLIB_FS_INFLATE is not set # # Partition Types @@ -405,6 +462,10 @@ CONFIG_MSDOS_PARTITION=y # CONFIG_SOUND is not set # +# MPC4xx Driver Options +# + +# # USB support # # CONFIG_USB is not set @@ -483,6 +544,7 @@ CONFIG_MSDOS_PARTITION=y # CONFIG_USB_SERIAL_EMPEG is not set # CONFIG_USB_SERIAL_FTDI_SIO is not set # CONFIG_USB_SERIAL_VISOR is not set +# CONFIG_USB_SERIAL_IPAQ is not set # CONFIG_USB_SERIAL_IR is not set # CONFIG_USB_SERIAL_EDGEPORT is not set # CONFIG_USB_SERIAL_KEYSPAN_PDA is not set @@ -496,6 +558,7 @@ CONFIG_MSDOS_PARTITION=y # CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set # CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set # CONFIG_USB_SERIAL_MCT_U232 is not set +# CONFIG_USB_SERIAL_KLSI is not set # CONFIG_USB_SERIAL_PL2303 is not set # CONFIG_USB_SERIAL_CYBERJACK is not set # CONFIG_USB_SERIAL_XIRCOM is not set @@ -517,3 +580,5 @@ CONFIG_MSDOS_PARTITION=y # CONFIG_MAGIC_SYSRQ is not set # CONFIG_KGDB is not set # CONFIG_XMON is not set +# CONFIG_BDI_SWITCH is not set +# CONFIG_SERIAL_TEXT_DEBUG is not set diff --git a/arch/ppc/configs/pcore_defconfig b/arch/ppc/configs/pcore_defconfig new file mode 100644 index 000000000000..be9e19b01248 --- /dev/null +++ b/arch/ppc/configs/pcore_defconfig @@ -0,0 +1,569 @@ +# +# Automatically generated make config: don't edit +# +# CONFIG_UID16 is not set +# CONFIG_RWSEM_GENERIC_SPINLOCK is not set +CONFIG_RWSEM_XCHGADD_ALGORITHM=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODVERSIONS=y +CONFIG_KMOD=y + +# +# Platform support +# +CONFIG_PPC=y +CONFIG_PPC32=y +CONFIG_6xx=y +# CONFIG_4xx is not set +# CONFIG_POWER3 is not set +# CONFIG_8xx is not set +# CONFIG_8260 is not set +# CONFIG_ALL_PPC is not set +# CONFIG_APUS is not set +# CONFIG_SPRUCE is not set +CONFIG_PCORE=y +# CONFIG_MENF1 is not set +# CONFIG_MCPN765 is not set +# CONFIG_MVME5100 is not set +# CONFIG_PRPMC750 is not set +# CONFIG_SANDPOINT is not set +# CONFIG_K2 is not set +# CONFIG_GEMINI is not set +# CONFIG_ZX4500 is not set +# CONFIG_MPC10X_STORE_GATHERING is not set +# CONFIG_PPC601_SYNC_FIX is not set +# CONFIG_SMP is not set +CONFIG_ALTIVEC=y +# CONFIG_TAU is not set + +# +# General setup +# +# CONFIG_HIGHMEM is not set +# CONFIG_ISA is not set +# CONFIG_EISA is not set +# CONFIG_SBUS is not set +# CONFIG_MCA is not set +CONFIG_PCI=y +CONFIG_NET=y +CONFIG_SYSCTL=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_KCORE_ELF=y +CONFIG_BINFMT_ELF=y +CONFIG_KERNEL_ELF=y +# CONFIG_BINFMT_MISC is not set +# CONFIG_PCI_NAMES is not set +# CONFIG_HOTPLUG is not set +# CONFIG_PCMCIA is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set +CONFIG_PPC_RTC=y +CONFIG_CMDLINE_BOOL=y +CONFIG_CMDLINE="ip=on" + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Plug and Play configuration +# +# CONFIG_PNP is not set +# CONFIG_ISAPNP is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_XD is not set +# CONFIG_PARIDE is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_INITRD=y + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set +# CONFIG_BLK_DEV_MD is not set +# CONFIG_MD_LINEAR is not set +# CONFIG_MD_RAID0 is not set +# CONFIG_MD_RAID1 is not set +# CONFIG_MD_RAID5 is not set +# CONFIG_BLK_DEV_LVM is not set + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_NETLINK=y +# CONFIG_RTNETLINK is not set +# CONFIG_NETLINK_DEV is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +# CONFIG_FILTER is not set +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +# CONFIG_IP_PNP_BOOTP is not set +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set + +# +# IP: Netfilter Configuration +# +CONFIG_IP_NF_CONNTRACK=m +CONFIG_IP_NF_FTP=m +# CONFIG_IP_NF_QUEUE is not set +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_LIMIT=m +CONFIG_IP_NF_MATCH_MAC=m +CONFIG_IP_NF_MATCH_MARK=m +CONFIG_IP_NF_MATCH_MULTIPORT=m +CONFIG_IP_NF_MATCH_TOS=m +CONFIG_IP_NF_MATCH_TCPMSS=m +CONFIG_IP_NF_MATCH_STATE=m +CONFIG_IP_NF_MATCH_UNCLEAN=m +CONFIG_IP_NF_MATCH_OWNER=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_MIRROR=m +CONFIG_IP_NF_NAT=m +CONFIG_IP_NF_NAT_NEEDED=y +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_NAT_FTP=m +# CONFIG_IP_NF_MANGLE is not set +# CONFIG_IP_NF_TARGET_LOG is not set +CONFIG_IP_NF_TARGET_TCPMSS=m +CONFIG_IP_NF_COMPAT_IPCHAINS=m +CONFIG_IP_NF_NAT_NEEDED=y +# CONFIG_IP_NF_COMPAT_IPFWADM is not set +# CONFIG_IPV6 is not set +# CONFIG_KHTTPD is not set +# CONFIG_ATM is not set + +# +# +# +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# ATA/IDE/MFM/RLL support +# +# CONFIG_IDE is not set +# CONFIG_BLK_DEV_IDE_MODES is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI support +# +CONFIG_SCSI=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +CONFIG_SD_EXTRA_DEVS=40 +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +CONFIG_BLK_DEV_SR=y +# CONFIG_BLK_DEV_SR_VENDOR is not set +CONFIG_SR_EXTRA_DEVS=2 +# CONFIG_CHR_DEV_SG is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_DEBUG_QUEUES is not set +# CONFIG_SCSI_MULTI_LUN is not set +CONFIG_SCSI_CONSTANTS=y +# CONFIG_SCSI_LOGGING is not set + +# +# SCSI low-level drivers +# +# CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_7000FASST is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_AHA152X is not set +# CONFIG_SCSI_AHA1542 is not set +# CONFIG_SCSI_AHA1740 is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_ADVANSYS is not set +# CONFIG_SCSI_IN2000 is not set +# CONFIG_SCSI_AM53C974 is not set +# CONFIG_SCSI_MEGARAID is not set +# CONFIG_SCSI_BUSLOGIC is not set +# CONFIG_SCSI_CPQFCTS is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_DTC3280 is not set +# CONFIG_SCSI_EATA is not set +# CONFIG_SCSI_EATA_DMA is not set +# CONFIG_SCSI_EATA_PIO is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_GDTH is not set +# CONFIG_SCSI_GENERIC_NCR5380 is not set +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_NCR53C406A is not set +# CONFIG_SCSI_NCR53C7xx is not set +# CONFIG_SCSI_NCR53C8XX is not set +CONFIG_SCSI_SYM53C8XX=y +CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=8 +CONFIG_SCSI_NCR53C8XX_MAX_TAGS=32 +CONFIG_SCSI_NCR53C8XX_SYNC=20 +# CONFIG_SCSI_NCR53C8XX_PROFILE is not set +# CONFIG_SCSI_NCR53C8XX_IOMAPPED is not set +# CONFIG_SCSI_NCR53C8XX_PQS_PDS is not set +# CONFIG_SCSI_NCR53C8XX_SYMBIOS_COMPAT is not set +# CONFIG_SCSI_PAS16 is not set +# CONFIG_SCSI_PCI2000 is not set +# CONFIG_SCSI_PCI2220I is not set +# CONFIG_SCSI_PSI240I is not set +# CONFIG_SCSI_QLOGIC_FAS is not set +# CONFIG_SCSI_QLOGIC_ISP is not set +# CONFIG_SCSI_QLOGIC_FC is not set +# CONFIG_SCSI_QLOGIC_1280 is not set +# CONFIG_SCSI_SIM710 is not set +# CONFIG_SCSI_SYM53C416 is not set +# CONFIG_SCSI_DC390T is not set +# CONFIG_SCSI_T128 is not set +# CONFIG_SCSI_U14_34F is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_MESH is not set +# CONFIG_SCSI_MAC53C94 is not set + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set +# CONFIG_NET_SB1000 is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_MACE is not set +# CONFIG_BMAC is not set +# CONFIG_GMAC is not set +# CONFIG_NCR885E is not set +# CONFIG_OAKNET is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_AT1700 is not set +# CONFIG_DEPCA is not set +# CONFIG_HP100 is not set +# CONFIG_NET_ISA is not set +CONFIG_NET_PCI=y +# CONFIG_PCNET32 is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_APRICOT is not set +# CONFIG_CS89x0 is not set +CONFIG_TULIP=y +# CONFIG_DE4X5 is not set +# CONFIG_DGRS is not set +# CONFIG_DM9102 is not set +CONFIG_EEPRO100=y +# CONFIG_EEPRO100_PM is not set +# CONFIG_LNE390 is not set +# CONFIG_FEALNX is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_NE3210 is not set +# CONFIG_ES3210 is not set +# CONFIG_8139TOO is not set +# CONFIG_8139TOO_PIO is not set +# CONFIG_8139TOO_TUNE_TWISTER is not set +# CONFIG_8139TOO_8129 is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_TLAN is not set +# CONFIG_VIA_RHINE is not set +# CONFIG_WINBOND_840 is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_SK98LIN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Old CD-ROM drivers (not SCSI, not IDE) +# +# CONFIG_CD_NO_IDESCSI is not set + +# +# Console drivers +# +# CONFIG_VGA_CONSOLE is not set + +# +# Frame-buffer support +# +# CONFIG_FB is not set + +# +# Input core support +# +# CONFIG_INPUT is not set + +# +# Macintosh device drivers +# + +# +# Character devices +# +# CONFIG_VT is not set +CONFIG_SERIAL=y +CONFIG_SERIAL_CONSOLE=y +# CONFIG_SERIAL_EXTENDED is not set +# CONFIG_SERIAL_NONSTANDARD is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Mice +# +CONFIG_BUSMOUSE=y +# CONFIG_ATIXL_BUSMOUSE is not set +# CONFIG_LOGIBUSMOUSE is not set +# CONFIG_MS_BUSMOUSE is not set +CONFIG_MOUSE=y +CONFIG_PSMOUSE=y +# CONFIG_82C710_MOUSE is not set +# CONFIG_PC110_PAD is not set + +# +# Joysticks +# +# CONFIG_JOYSTICK is not set + +# +# Input core support is needed for joysticks +# +# CONFIG_QIC02_TAPE is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_INTEL_RNG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set +# CONFIG_ADFS_FS is not set +# CONFIG_ADFS_FS_RW is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_FAT_FS is not set +# CONFIG_MSDOS_FS is not set +# CONFIG_UMSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_CRAMFS is not set +CONFIG_TMPFS=y +# CONFIG_RAMFS is not set +# CONFIG_ISO9660_FS is not set +# CONFIG_JOLIET is not set +# CONFIG_MINIX_FS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_NTFS_FS is not set +# CONFIG_NTFS_RW is not set +# CONFIG_HPFS_FS is not set +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVFS_MOUNT is not set +# CONFIG_DEVFS_DEBUG is not set +CONFIG_DEVPTS_FS=y +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set +# CONFIG_ROMFS_FS is not set +CONFIG_EXT2_FS=y +# CONFIG_SYSV_FS is not set +# CONFIG_SYSV_FS_WRITE is not set +# CONFIG_UDF_FS is not set +# CONFIG_UDF_RW is not set +# CONFIG_UFS_FS is not set +# CONFIG_UFS_FS_WRITE is not set + +# +# Network File Systems +# +# CONFIG_CODA_FS is not set +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +CONFIG_ROOT_NFS=y +# CONFIG_NFSD is not set +# CONFIG_NFSD_V3 is not set +CONFIG_SUNRPC=y +CONFIG_LOCKD=y +# CONFIG_SMB_FS is not set +# CONFIG_NCP_FS is not set +# CONFIG_NCPFS_PACKET_SIGNING is not set +# CONFIG_NCPFS_IOCTL_LOCKING is not set +# CONFIG_NCPFS_STRONG is not set +# CONFIG_NCPFS_NFS_NS is not set +# CONFIG_NCPFS_OS2_NS is not set +# CONFIG_NCPFS_SMALLDOS is not set +# CONFIG_NCPFS_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_SMB_NLS is not set +# CONFIG_NLS is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB is not set + +# +# Kernel hacking +# +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_KGDB is not set +# CONFIG_XMON is not set diff --git a/arch/ppc/configs/pmac_defconfig b/arch/ppc/configs/pmac_defconfig new file mode 100644 index 000000000000..f370cb380ace --- /dev/null +++ b/arch/ppc/configs/pmac_defconfig @@ -0,0 +1,1076 @@ +# +# Automatically generated make config: don't edit +# +# CONFIG_UID16 is not set +# CONFIG_RWSEM_GENERIC_SPINLOCK is not set +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_HAVE_DEC_LOCK=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODVERSIONS=y +CONFIG_KMOD=y + +# +# Platform support +# +CONFIG_PPC=y +CONFIG_PPC32=y +CONFIG_6xx=y +# CONFIG_4xx is not set +# CONFIG_POWER3 is not set +# CONFIG_POWER4 is not set +# CONFIG_8xx is not set +# CONFIG_8260 is not set +CONFIG_PPC_STD_MMU=y +CONFIG_ALL_PPC=y +# CONFIG_APUS is not set +# CONFIG_GEMINI is not set +# CONFIG_SMP is not set +CONFIG_ALTIVEC=y +CONFIG_TAU=y +# CONFIG_TAU_INT is not set +# CONFIG_TAU_AVERAGE is not set + +# +# General setup +# +# CONFIG_HIGHMEM is not set +# CONFIG_ISA is not set +# CONFIG_EISA is not set +# CONFIG_SBUS is not set +# CONFIG_MCA is not set +CONFIG_PCI=y +CONFIG_NET=y +CONFIG_SYSCTL=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_KCORE_ELF=y +CONFIG_BINFMT_ELF=y +CONFIG_KERNEL_ELF=y +CONFIG_BINFMT_MISC=m +CONFIG_PCI_NAMES=y +CONFIG_HOTPLUG=y + +# +# PCMCIA/CardBus support +# +CONFIG_PCMCIA=m +CONFIG_CARDBUS=y +CONFIG_I82092=y +CONFIG_I82365=y +CONFIG_TCIC=y + +# +# Parallel port support +# +# CONFIG_PARPORT is not set +CONFIG_PPC_RTC=y +CONFIG_PPC601_SYNC_FIX=y +CONFIG_PROC_DEVICETREE=y +CONFIG_PPC_RTAS=y +CONFIG_BOOTX_TEXT=y +# CONFIG_PREP_RESIDUAL is not set +# CONFIG_CMDLINE_BOOL is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Plug and Play configuration +# +# CONFIG_PNP is not set +# CONFIG_ISAPNP is not set + +# +# Block devices +# +CONFIG_BLK_DEV_FD=m +# CONFIG_BLK_DEV_XD is not set +# CONFIG_PARIDE is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_INITRD=y + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set +# CONFIG_BLK_DEV_MD is not set +# CONFIG_MD_LINEAR is not set +# CONFIG_MD_RAID0 is not set +# CONFIG_MD_RAID1 is not set +# CONFIG_MD_RAID5 is not set +# CONFIG_MD_MULTIPATH is not set +# CONFIG_BLK_DEV_LVM is not set + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +# CONFIG_NETLINK_DEV is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_FILTER=y +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +# CONFIG_IP_PNP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_INET_ECN is not set +CONFIG_SYN_COOKIES=y + +# +# IP: Netfilter Configuration +# +CONFIG_IP_NF_CONNTRACK=m +CONFIG_IP_NF_FTP=m +CONFIG_IP_NF_IRC=m +# CONFIG_IP_NF_QUEUE is not set +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_LIMIT=m +CONFIG_IP_NF_MATCH_MAC=m +CONFIG_IP_NF_MATCH_MARK=m +CONFIG_IP_NF_MATCH_MULTIPORT=m +CONFIG_IP_NF_MATCH_TOS=m +CONFIG_IP_NF_MATCH_LENGTH=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_MATCH_TCPMSS=m +CONFIG_IP_NF_MATCH_STATE=m +CONFIG_IP_NF_MATCH_UNCLEAN=m +CONFIG_IP_NF_MATCH_OWNER=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_MIRROR=m +CONFIG_IP_NF_NAT=m +CONFIG_IP_NF_NAT_NEEDED=y +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_NAT_SNMP_BASIC=m +CONFIG_IP_NF_NAT_IRC=m +CONFIG_IP_NF_NAT_FTP=m +# CONFIG_IP_NF_MANGLE is not set +# CONFIG_IP_NF_TARGET_LOG is not set +CONFIG_IP_NF_TARGET_TCPMSS=m +CONFIG_IP_NF_COMPAT_IPCHAINS=m +CONFIG_IP_NF_NAT_NEEDED=y +# CONFIG_IP_NF_COMPAT_IPFWADM is not set +# CONFIG_IPV6 is not set +# CONFIG_KHTTPD is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set + +# +# +# +# CONFIG_IPX is not set +CONFIG_ATALK=m +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# ATA/IDE/MFM/RLL support +# +CONFIG_IDE=y + +# +# IDE, ATA and ATAPI Block devices +# +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_HD_IDE is not set +# CONFIG_BLK_DEV_HD is not set +CONFIG_BLK_DEV_IDEDISK=y +# CONFIG_IDEDISK_MULTI_MODE is not set +# CONFIG_BLK_DEV_IDEDISK_VENDOR is not set +# CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set +# CONFIG_BLK_DEV_IDEDISK_IBM is not set +# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set +# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set +# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set +# CONFIG_BLK_DEV_IDEDISK_WD is not set +# CONFIG_BLK_DEV_COMMERIAL is not set +# CONFIG_BLK_DEV_TIVO is not set +CONFIG_BLK_DEV_IDECS=m +CONFIG_BLK_DEV_IDECD=y +# CONFIG_BLK_DEV_IDETAPE is not set +CONFIG_BLK_DEV_IDEFLOPPY=y +CONFIG_BLK_DEV_IDESCSI=y + +# +# IDE chipset support/bugfixes +# +# CONFIG_BLK_DEV_CMD640 is not set +# CONFIG_BLK_DEV_CMD640_ENHANCED is not set +# CONFIG_BLK_DEV_ISAPNP is not set +# CONFIG_BLK_DEV_RZ1000 is not set +CONFIG_BLK_DEV_IDEPCI=y +CONFIG_IDEPCI_SHARE_IRQ=y +CONFIG_BLK_DEV_IDEDMA_PCI=y +CONFIG_BLK_DEV_ADMA=y +# CONFIG_BLK_DEV_OFFBOARD is not set +CONFIG_IDEDMA_PCI_AUTO=y +CONFIG_BLK_DEV_IDEDMA=y +# CONFIG_IDEDMA_PCI_WIP is not set +# CONFIG_IDEDMA_NEW_DRIVE_LISTINGS is not set +# CONFIG_BLK_DEV_AEC62XX is not set +# CONFIG_AEC62XX_TUNING is not set +# CONFIG_BLK_DEV_ALI15X3 is not set +# CONFIG_WDC_ALI15X3 is not set +# CONFIG_BLK_DEV_AMD74XX is not set +# CONFIG_AMD74XX_OVERRIDE is not set +CONFIG_BLK_DEV_CMD64X=y +# CONFIG_BLK_DEV_CY82C693 is not set +# CONFIG_BLK_DEV_CS5530 is not set +# CONFIG_BLK_DEV_HPT34X is not set +# CONFIG_HPT34X_AUTODMA is not set +# CONFIG_BLK_DEV_HPT366 is not set +# CONFIG_BLK_DEV_NS87415 is not set +# CONFIG_BLK_DEV_OPTI621 is not set +# CONFIG_BLK_DEV_PDC202XX is not set +# CONFIG_PDC202XX_BURST is not set +# CONFIG_PDC202XX_FORCE is not set +# CONFIG_BLK_DEV_SVWKS is not set +# CONFIG_BLK_DEV_SIS5513 is not set +# CONFIG_BLK_DEV_SLC90E66 is not set +# CONFIG_BLK_DEV_TRM290 is not set +# CONFIG_BLK_DEV_VIA82CXXX is not set +CONFIG_BLK_DEV_SL82C105=y +CONFIG_BLK_DEV_IDE_PMAC=y +CONFIG_BLK_DEV_IDEDMA_PMAC=y +CONFIG_BLK_DEV_IDEDMA_PMAC_AUTO=y +CONFIG_BLK_DEV_IDEDMA=y +CONFIG_BLK_DEV_IDEPCI=y +# CONFIG_IDE_CHIPSETS is not set +CONFIG_IDEDMA_AUTO=y +# CONFIG_IDEDMA_IVB is not set +# CONFIG_DMA_NONPCI is not set +CONFIG_BLK_DEV_IDE_MODES=y +# CONFIG_BLK_DEV_ATARAID is not set +# CONFIG_BLK_DEV_ATARAID_PDC is not set +# CONFIG_BLK_DEV_ATARAID_HPT is not set + +# +# SCSI support +# +CONFIG_SCSI=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +CONFIG_SD_EXTRA_DEVS=40 +CONFIG_CHR_DEV_ST=y +# CONFIG_CHR_DEV_OSST is not set +CONFIG_BLK_DEV_SR=y +CONFIG_BLK_DEV_SR_VENDOR=y +CONFIG_SR_EXTRA_DEVS=2 +CONFIG_CHR_DEV_SG=y + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_DEBUG_QUEUES is not set +# CONFIG_SCSI_MULTI_LUN is not set +CONFIG_SCSI_CONSTANTS=y +# CONFIG_SCSI_LOGGING is not set + +# +# SCSI low-level drivers +# +# CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_7000FASST is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_AHA152X is not set +# CONFIG_SCSI_AHA1542 is not set +# CONFIG_SCSI_AHA1740 is not set +CONFIG_SCSI_AIC7XXX=m +CONFIG_AIC7XXX_CMDS_PER_DEVICE=253 +CONFIG_AIC7XXX_RESET_DELAY_MS=15000 +# CONFIG_AIC7XXX_BUILD_FIRMWARE is not set +CONFIG_SCSI_AIC7XXX_OLD=m +# CONFIG_AIC7XXX_OLD_TCQ_ON_BY_DEFAULT is not set +CONFIG_AIC7XXX_OLD_CMDS_PER_DEVICE=8 +CONFIG_AIC7XXX_OLD_PROC_STATS=y +# CONFIG_SCSI_DPT_I2O is not set +CONFIG_SCSI_ADVANSYS=m +# CONFIG_SCSI_IN2000 is not set +# CONFIG_SCSI_AM53C974 is not set +# CONFIG_SCSI_MEGARAID is not set +# CONFIG_SCSI_BUSLOGIC is not set +# CONFIG_SCSI_CPQFCTS is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_DTC3280 is not set +# CONFIG_SCSI_EATA is not set +# CONFIG_SCSI_EATA_DMA is not set +# CONFIG_SCSI_EATA_PIO is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_GDTH is not set +# CONFIG_SCSI_GENERIC_NCR5380 is not set +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_NCR53C406A is not set +# CONFIG_SCSI_NCR53C7xx is not set +CONFIG_SCSI_SYM53C8XX_2=y +CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=0 +CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 +CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 +# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set +# CONFIG_SCSI_PAS16 is not set +# CONFIG_SCSI_PCI2000 is not set +# CONFIG_SCSI_PCI2220I is not set +# CONFIG_SCSI_PSI240I is not set +# CONFIG_SCSI_QLOGIC_FAS is not set +# CONFIG_SCSI_QLOGIC_ISP is not set +# CONFIG_SCSI_QLOGIC_FC is not set +# CONFIG_SCSI_QLOGIC_1280 is not set +# CONFIG_SCSI_SIM710 is not set +# CONFIG_SCSI_SYM53C416 is not set +# CONFIG_SCSI_DC390T is not set +# CONFIG_SCSI_T128 is not set +# CONFIG_SCSI_U14_34F is not set +# CONFIG_SCSI_DEBUG is not set +CONFIG_SCSI_MESH=y +CONFIG_SCSI_MESH_SYNC_RATE=5 +CONFIG_SCSI_MAC53C94=y + +# +# PCMCIA SCSI adapter support +# +# CONFIG_SCSI_PCMCIA is not set + +# +# IEEE 1394 (FireWire) support (EXPERIMENTAL) +# +CONFIG_IEEE1394=m + +# +# Device Drivers +# +CONFIG_IEEE1394_PCILYNX=m +# CONFIG_IEEE1394_PCILYNX_LOCALRAM is not set +# CONFIG_IEEE1394_PCILYNX_PORTS is not set +CONFIG_IEEE1394_OHCI1394=m + +# +# Protocol Drivers +# +CONFIG_IEEE1394_VIDEO1394=m +CONFIG_IEEE1394_SBP2=m +CONFIG_IEEE1394_RAWIO=m +# CONFIG_IEEE1394_VERBOSEDEBUG is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set + +# +# Appletalk devices +# +# CONFIG_LTPC is not set +# CONFIG_COPS is not set +# CONFIG_IPDDP is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MACE=y +# CONFIG_MACE_AAUI_PORT is not set +CONFIG_BMAC=y +# CONFIG_GMAC is not set +# CONFIG_SUNLANCE is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNBMAC is not set +# CONFIG_SUNQE is not set +# CONFIG_SUNLANCE is not set +CONFIG_SUNGEM=y +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_HP100 is not set +# CONFIG_NET_ISA is not set +CONFIG_NET_PCI=y +CONFIG_PCNET32=y +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_APRICOT is not set +# CONFIG_CS89x0 is not set +CONFIG_TULIP=y +# CONFIG_TULIP_MWI is not set +CONFIG_TULIP_MMIO=y +CONFIG_DE4X5=m +# CONFIG_DGRS is not set +# CONFIG_DM9102 is not set +# CONFIG_EEPRO100 is not set +# CONFIG_LNE390 is not set +# CONFIG_FEALNX is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_NE3210 is not set +# CONFIG_ES3210 is not set +# CONFIG_8139CP is not set +# CONFIG_8139TOO is not set +# CONFIG_8139TOO_PIO is not set +# CONFIG_8139TOO_TUNE_TWISTER is not set +# CONFIG_8139TOO_8129 is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_TLAN is not set +# CONFIG_VIA_RHINE is not set +# CONFIG_VIA_RHINE_MMIO is not set +# CONFIG_WINBOND_840 is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_MYRI_SBUS is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_SK98LIN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +CONFIG_PPP=y +CONFIG_PPP_MULTILINK=y +# CONFIG_PPP_FILTER is not set +CONFIG_PPP_ASYNC=y +CONFIG_PPP_SYNC_TTY=m +CONFIG_PPP_DEFLATE=y +CONFIG_PPP_BSDCOMP=m +# CONFIG_PPPOE is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +CONFIG_NET_RADIO=y +# CONFIG_STRIP is not set +# CONFIG_WAVELAN is not set +# CONFIG_ARLAN is not set +# CONFIG_AIRONET4500 is not set +# CONFIG_AIRONET4500_NONCS is not set +# CONFIG_AIRONET4500_PROC is not set +# CONFIG_AIRO is not set +CONFIG_HERMES=m +CONFIG_APPLE_AIRPORT=m +# CONFIG_PLX_HERMES is not set + +# +# Wireless Pcmcia cards support +# +CONFIG_PCMCIA_HERMES=m +# CONFIG_AIRO_CS is not set +CONFIG_NET_WIRELESS=y + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# PCMCIA network device support +# +CONFIG_NET_PCMCIA=y +# CONFIG_PCMCIA_3C589 is not set +# CONFIG_PCMCIA_3C574 is not set +# CONFIG_PCMCIA_FMVJ18X is not set +# CONFIG_PCMCIA_PCNET is not set +# CONFIG_PCMCIA_AXNET is not set +# CONFIG_PCMCIA_NMCLAN is not set +# CONFIG_PCMCIA_SMC91C92 is not set +# CONFIG_PCMCIA_XIRC2PS is not set +# CONFIG_ARCNET_COM20020_CS is not set +# CONFIG_PCMCIA_IBMTR is not set +# CONFIG_PCMCIA_XIRCOM is not set +# CONFIG_PCMCIA_XIRTULIP is not set +CONFIG_NET_PCMCIA_RADIO=y +# CONFIG_PCMCIA_RAYCS is not set +# CONFIG_PCMCIA_NETWAVE is not set +# CONFIG_PCMCIA_WAVELAN is not set +# CONFIG_AIRONET4500_CS is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +CONFIG_IRDA=m + +# +# IrDA protocols +# +CONFIG_IRLAN=m +CONFIG_IRNET=m +CONFIG_IRCOMM=m +# CONFIG_IRDA_ULTRA is not set +# CONFIG_IRDA_OPTIONS is not set + +# +# Infrared-port device drivers +# + +# +# SIR device drivers +# +CONFIG_IRTTY_SIR=m +# CONFIG_IRPORT_SIR is not set + +# +# Dongle support +# +# CONFIG_DONGLE is not set + +# +# FIR device drivers +# +# CONFIG_USB_IRDA is not set +# CONFIG_NSC_FIR is not set +# CONFIG_WINBOND_FIR is not set +# CONFIG_TOSHIBA_FIR is not set +# CONFIG_SMC_IRCC_FIR is not set +# CONFIG_ALI_FIR is not set +# CONFIG_VLSI_FIR is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Old CD-ROM drivers (not SCSI, not IDE) +# +# CONFIG_CD_NO_IDESCSI is not set + +# +# Console drivers +# +# CONFIG_VGA_CONSOLE is not set + +# +# Frame-buffer support +# +CONFIG_FB=y +CONFIG_DUMMY_CONSOLE=y +# CONFIG_FB_RIVA is not set +# CONFIG_FB_CLGEN is not set +# CONFIG_FB_PM2 is not set +# CONFIG_FB_CYBER2000 is not set +CONFIG_FB_OF=y +CONFIG_FB_CONTROL=y +CONFIG_FB_PLATINUM=y +CONFIG_FB_VALKYRIE=y +CONFIG_FB_CT65550=y +CONFIG_FB_IMSTT=y +# CONFIG_FB_S3TRIO is not set +# CONFIG_FB_VGA16 is not set +CONFIG_FB_MATROX=y +CONFIG_FB_MATROX_MILLENIUM=y +CONFIG_FB_MATROX_MYSTIQUE=y +# CONFIG_FB_MATROX_G100 is not set +# CONFIG_FB_MATROX_I2C is not set +# CONFIG_FB_MATROX_G450 is not set +# CONFIG_FB_MATROX_MULTIHEAD is not set +CONFIG_FB_ATY=y +CONFIG_FB_ATY_GX=y +CONFIG_FB_ATY_CT=y +CONFIG_FB_RADEON=y +CONFIG_FB_ATY128=y +# CONFIG_FB_SIS is not set +CONFIG_FB_3DFX=y +# CONFIG_FB_VOODOO1 is not set +# CONFIG_FB_VIRTUAL is not set +# CONFIG_FBCON_ADVANCED is not set +CONFIG_FBCON_CFB8=y +CONFIG_FBCON_CFB16=y +CONFIG_FBCON_CFB24=y +CONFIG_FBCON_CFB32=y +# CONFIG_FBCON_FONTWIDTH8_ONLY is not set +CONFIG_FBCON_FONTS=y +# CONFIG_FONT_8x8 is not set +CONFIG_FONT_8x16=y +CONFIG_FONT_SUN8x16=y +CONFIG_FONT_SUN12x22=y +# CONFIG_FONT_6x11 is not set +# CONFIG_FONT_PEARL_8x8 is not set +# CONFIG_FONT_ACORN_8x8 is not set +CONFIG_FB_COMPAT_XPMAC=y + +# +# Input core support +# +CONFIG_INPUT=y +CONFIG_INPUT_KEYBDEV=y +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +CONFIG_INPUT_EVDEV=y + +# +# Macintosh device drivers +# +CONFIG_ADB_CUDA=y +CONFIG_ADB_PMU=y +CONFIG_PMAC_PBOOK=y +CONFIG_PM=y +CONFIG_PMAC_APM_EMU=y +CONFIG_PMAC_BACKLIGHT=y +CONFIG_MAC_FLOPPY=y +CONFIG_MAC_SERIAL=y +# CONFIG_SERIAL_CONSOLE is not set +CONFIG_ADB=y +CONFIG_ADB_MACIO=y +CONFIG_INPUT_ADBHID=y +CONFIG_MAC_ADBKEYCODES=y +CONFIG_MAC_EMUMOUSEBTN=y +CONFIG_MAC_HID=y +# CONFIG_ANSLCD is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_SERIAL=m +# CONFIG_SERIAL_EXTENDED is not set +# CONFIG_SERIAL_NONSTANDARD is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 + +# +# I2C support +# +CONFIG_I2C=m +# CONFIG_I2C_ALGOBIT is not set +# CONFIG_I2C_ALGOPCF is not set +CONFIG_I2C_KEYWEST=m +CONFIG_I2C_CHARDEV=m +CONFIG_I2C_PROC=m + +# +# Mice +# +CONFIG_BUSMOUSE=y +# CONFIG_ATIXL_BUSMOUSE is not set +# CONFIG_LOGIBUSMOUSE is not set +# CONFIG_MS_BUSMOUSE is not set +CONFIG_MOUSE=y +CONFIG_PSMOUSE=y +# CONFIG_82C710_MOUSE is not set +# CONFIG_PC110_PAD is not set + +# +# Joysticks +# +# CONFIG_INPUT_GAMEPORT is not set +# CONFIG_INPUT_NS558 is not set +# CONFIG_INPUT_LIGHTNING is not set +# CONFIG_INPUT_PCIGAME is not set +# CONFIG_INPUT_CS461X is not set +# CONFIG_INPUT_EMU10K1 is not set +# CONFIG_INPUT_SERIO is not set +# CONFIG_INPUT_SERPORT is not set + +# +# Joysticks +# +# CONFIG_INPUT_ANALOG is not set +# CONFIG_INPUT_A3D is not set +# CONFIG_INPUT_ADI is not set +# CONFIG_INPUT_COBRA is not set +# CONFIG_INPUT_GF2K is not set +# CONFIG_INPUT_GRIP is not set +# CONFIG_INPUT_INTERACT is not set +# CONFIG_INPUT_TMDC is not set +# CONFIG_INPUT_SIDEWINDER is not set +# CONFIG_INPUT_IFORCE_USB is not set +# CONFIG_INPUT_IFORCE_232 is not set +# CONFIG_INPUT_WARRIOR is not set +# CONFIG_INPUT_MAGELLAN is not set +# CONFIG_INPUT_SPACEORB is not set +# CONFIG_INPUT_SPACEBALL is not set +# CONFIG_INPUT_STINGER is not set +# CONFIG_INPUT_DB9 is not set +# CONFIG_INPUT_GAMECON is not set +# CONFIG_INPUT_TURBOGRAFX is not set +# CONFIG_QIC02_TAPE is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_INTEL_RNG is not set +CONFIG_NVRAM=y +# CONFIG_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set + +# +# PCMCIA character devices +# +# CONFIG_PCMCIA_SERIAL_CS is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set +# CONFIG_ADFS_FS is not set +# CONFIG_ADFS_FS_RW is not set +# CONFIG_AFFS_FS is not set +CONFIG_HFS_FS=m +# CONFIG_BFS_FS is not set +CONFIG_EXT3_FS=y +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_FAT_FS=m +CONFIG_MSDOS_FS=m +# CONFIG_UMSDOS_FS is not set +CONFIG_VFAT_FS=m +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_CRAMFS is not set +CONFIG_TMPFS=y +# CONFIG_RAMFS is not set +CONFIG_ISO9660_FS=y +# CONFIG_JOLIET is not set +# CONFIG_ZISOFS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_NTFS_FS is not set +# CONFIG_NTFS_RW is not set +# CONFIG_HPFS_FS is not set +CONFIG_PROC_FS=y +CONFIG_DEVFS_FS=y +# CONFIG_DEVFS_MOUNT is not set +# CONFIG_DEVFS_DEBUG is not set +CONFIG_DEVPTS_FS=y +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set +# CONFIG_ROMFS_FS is not set +CONFIG_EXT2_FS=y +# CONFIG_SYSV_FS is not set +# CONFIG_UDF_FS is not set +# CONFIG_UDF_RW is not set +# CONFIG_UFS_FS is not set +# CONFIG_UFS_FS_WRITE is not set + +# +# Network File Systems +# +# CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +# CONFIG_ROOT_NFS is not set +CONFIG_NFSD=y +# CONFIG_NFSD_V3 is not set +CONFIG_SUNRPC=y +CONFIG_LOCKD=y +CONFIG_SMB_FS=m +# CONFIG_SMB_NLS_DEFAULT is not set +# CONFIG_NCP_FS is not set +# CONFIG_NCPFS_PACKET_SIGNING is not set +# CONFIG_NCPFS_IOCTL_LOCKING is not set +# CONFIG_NCPFS_STRONG is not set +# CONFIG_NCPFS_NFS_NS is not set +# CONFIG_NCPFS_OS2_NS is not set +# CONFIG_NCPFS_SMALLDOS is not set +# CONFIG_NCPFS_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set +# CONFIG_ZISOFS_FS is not set +# CONFIG_ZLIB_FS_INFLATE is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +CONFIG_MAC_PARTITION=y +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +CONFIG_SMB_NLS=y +CONFIG_NLS=y + +# +# Native Language Support +# +CONFIG_NLS_DEFAULT="iso8859-1" +# CONFIG_NLS_CODEPAGE_437 is not set +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +CONFIG_NLS_ISO8859_1=m +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Sound +# +CONFIG_SOUND=m +CONFIG_DMASOUND_PMAC=m +CONFIG_DMASOUND=m +CONFIG_I2C=m +CONFIG_I2C_KEYWEST=m +# CONFIG_SOUND_BT878 is not set +# CONFIG_SOUND_CMPCI is not set +# CONFIG_SOUND_EMU10K1 is not set +# CONFIG_MIDI_EMU10K1 is not set +# CONFIG_SOUND_FUSION is not set +# CONFIG_SOUND_CS4281 is not set +# CONFIG_SOUND_ES1370 is not set +# CONFIG_SOUND_ES1371 is not set +# CONFIG_SOUND_ESSSOLO1 is not set +# CONFIG_SOUND_MAESTRO is not set +# CONFIG_SOUND_MAESTRO3 is not set +# CONFIG_SOUND_ICH is not set +# CONFIG_SOUND_RME96XX is not set +# CONFIG_SOUND_SONICVIBES is not set +# CONFIG_SOUND_TRIDENT is not set +# CONFIG_SOUND_MSNDCLAS is not set +# CONFIG_SOUND_MSNDPIN is not set +# CONFIG_SOUND_VIA82CXXX is not set +# CONFIG_MIDI_VIA82CXXX is not set +# CONFIG_SOUND_OSS is not set +# CONFIG_SOUND_TVMIXER is not set + +# +# USB support +# +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +# CONFIG_USB_BANDWIDTH is not set +# CONFIG_USB_LONG_TIMEOUT is not set + +# +# USB Controllers +# +# CONFIG_USB_UHCI is not set +# CONFIG_USB_UHCI_ALT is not set +CONFIG_USB_OHCI=y + +# +# USB Device Class drivers +# +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_BLUETOOTH is not set +# CONFIG_USB_STORAGE is not set +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_HP8200e is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +CONFIG_USB_ACM=m +CONFIG_USB_PRINTER=m + +# +# USB Human Interface Devices (HID) +# +CONFIG_USB_HID=y +# CONFIG_USB_HIDDEV is not set +# CONFIG_USB_WACOM is not set + +# +# USB Imaging devices +# +# CONFIG_USB_DC2XX is not set +# CONFIG_USB_MDC800 is not set +CONFIG_USB_SCANNER=m +# CONFIG_USB_MICROTEK is not set +# CONFIG_USB_HPUSBSCSI is not set + +# +# USB Multimedia devices +# + +# +# Video4Linux support is needed for USB Multimedia device support +# + +# +# USB Network adaptors +# +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_CATC is not set +# CONFIG_USB_CDCETHER is not set +# CONFIG_USB_USBNET is not set + +# +# USB port drivers +# +# CONFIG_USB_USS720 is not set + +# +# USB Serial Converter support +# +CONFIG_USB_SERIAL=m +# CONFIG_USB_SERIAL_GENERIC is not set +# CONFIG_USB_SERIAL_BELKIN is not set +# CONFIG_USB_SERIAL_WHITEHEAT is not set +# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set +# CONFIG_USB_SERIAL_EMPEG is not set +# CONFIG_USB_SERIAL_FTDI_SIO is not set +CONFIG_USB_SERIAL_VISOR=m +# CONFIG_USB_SERIAL_IR is not set +# CONFIG_USB_SERIAL_EDGEPORT is not set +# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set +# CONFIG_USB_SERIAL_KEYSPAN is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set +# CONFIG_USB_SERIAL_MCT_U232 is not set +# CONFIG_USB_SERIAL_PL2303 is not set +# CONFIG_USB_SERIAL_CYBERJACK is not set +# CONFIG_USB_SERIAL_XIRCOM is not set +# CONFIG_USB_SERIAL_OMNINET is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_RIO500 is not set + +# +# Bluetooth support +# +# CONFIG_BLUEZ is not set + +# +# Kernel hacking +# +CONFIG_MAGIC_SYSRQ=y +# CONFIG_KGDB is not set +CONFIG_XMON=y diff --git a/arch/ppc/configs/power3_defconfig b/arch/ppc/configs/power3_defconfig index 994814035c9c..54078cba978c 100644 --- a/arch/ppc/configs/power3_defconfig +++ b/arch/ppc/configs/power3_defconfig @@ -4,6 +4,7 @@ # CONFIG_UID16 is not set # CONFIG_RWSEM_GENERIC_SPINLOCK is not set CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_HAVE_DEC_LOCK=y # # Code maturity level options @@ -25,7 +26,6 @@ CONFIG_PPC32=y # CONFIG_6xx is not set # CONFIG_4xx is not set CONFIG_POWER3=y -# CONFIG_POWER4 is not set # CONFIG_8xx is not set CONFIG_PPC64BRIDGE=y CONFIG_ALL_PPC=y @@ -66,6 +66,7 @@ CONFIG_PARPORT_PC_FIFO=y # CONFIG_PARPORT_AMIGA is not set # CONFIG_PARPORT_MFC3 is not set # CONFIG_PARPORT_ATARI is not set +# CONFIG_PARPORT_GSC is not set # CONFIG_PARPORT_SUNBPP is not set # CONFIG_PARPORT_OTHER is not set # CONFIG_PARPORT_1284 is not set @@ -119,8 +120,6 @@ CONFIG_BLK_DEV_LVM=y # CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set -CONFIG_NETLINK=y -# CONFIG_RTNETLINK is not set # CONFIG_NETLINK_DEV is not set # CONFIG_NETFILTER is not set # CONFIG_FILTER is not set @@ -132,6 +131,7 @@ CONFIG_IP_MULTICAST=y # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set # CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set # CONFIG_INET_ECN is not set CONFIG_SYN_COOKIES=y # CONFIG_IPV6 is not set @@ -224,15 +224,11 @@ CONFIG_SCSI_LOGGING=y # CONFIG_SCSI_IMM is not set # CONFIG_SCSI_NCR53C406A is not set # CONFIG_SCSI_NCR53C7xx is not set -# CONFIG_SCSI_NCR53C8XX is not set -CONFIG_SCSI_SYM53C8XX=y -CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=8 -CONFIG_SCSI_NCR53C8XX_MAX_TAGS=32 -CONFIG_SCSI_NCR53C8XX_SYNC=20 -# CONFIG_SCSI_NCR53C8XX_PROFILE is not set -# CONFIG_SCSI_NCR53C8XX_IOMAPPED is not set -# CONFIG_SCSI_NCR53C8XX_PQS_PDS is not set -# CONFIG_SCSI_NCR53C8XX_SYMBIOS_COMPAT is not set +CONFIG_SCSI_SYM53C8XX_2=y +CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=0 +CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 +CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 +# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set # CONFIG_SCSI_PAS16 is not set # CONFIG_SCSI_PCI2000 is not set # CONFIG_SCSI_PCI2220I is not set @@ -315,6 +311,7 @@ CONFIG_PCNET32=y # CONFIG_SUNDANCE is not set # CONFIG_TLAN is not set # CONFIG_VIA_RHINE is not set +# CONFIG_VIA_RHINE_MMIO is not set # CONFIG_WINBOND_840 is not set # CONFIG_NET_POCKET is not set @@ -474,6 +471,7 @@ CONFIG_I2C_ALGOBIT=y # CONFIG_I2C_VELLEMAN is not set CONFIG_I2C_ALGOPCF=y # CONFIG_I2C_ELEKTOR is not set +# CONFIG_I2C_KEYWEST is not set CONFIG_I2C_CHARDEV=y # CONFIG_I2C_PROC is not set @@ -553,11 +551,15 @@ CONFIG_NVRAM=y # CONFIG_AUTOFS4_FS is not set # CONFIG_REISERFS_FS is not set # CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set # CONFIG_ADFS_FS is not set # CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set # CONFIG_BFS_FS is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_JBD_DEBUG is not set CONFIG_FAT_FS=y CONFIG_MSDOS_FS=y # CONFIG_UMSDOS_FS is not set @@ -570,6 +572,7 @@ CONFIG_TMPFS=y # CONFIG_RAMFS is not set CONFIG_ISO9660_FS=y CONFIG_JOLIET=y +# CONFIG_ZISOFS is not set # CONFIG_MINIX_FS is not set # CONFIG_VXFS_FS is not set # CONFIG_NTFS_FS is not set @@ -594,6 +597,7 @@ CONFIG_EXT2_FS=y # Network File Systems # # CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set CONFIG_NFS_FS=y # CONFIG_NFS_V3 is not set # CONFIG_ROOT_NFS is not set @@ -611,6 +615,8 @@ CONFIG_LOCKD=y # CONFIG_NCPFS_SMALLDOS is not set # CONFIG_NCPFS_NLS is not set # CONFIG_NCPFS_EXTRAS is not set +# CONFIG_ZISOFS_FS is not set +# CONFIG_ZLIB_FS_INFLATE is not set # # Partition Types @@ -665,7 +671,7 @@ CONFIG_NLS_ISO8859_1=y # Sound # CONFIG_SOUND=y -# CONFIG_DMASOUND_AWACS is not set +# CONFIG_DMASOUND_PMAC is not set # CONFIG_SOUND_BT878 is not set # CONFIG_SOUND_CMPCI is not set # CONFIG_SOUND_EMU10K1 is not set diff --git a/arch/ppc/configs/pplus_defconfig b/arch/ppc/configs/pplus_defconfig new file mode 100644 index 000000000000..ddbb7bb7a61b --- /dev/null +++ b/arch/ppc/configs/pplus_defconfig @@ -0,0 +1,780 @@ +# +# Automatically generated make config: don't edit +# +# CONFIG_UID16 is not set +# CONFIG_RWSEM_GENERIC_SPINLOCK is not set +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_HAVE_DEC_LOCK=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODVERSIONS=y +CONFIG_KMOD=y + +# +# Platform support +# +CONFIG_PPC=y +CONFIG_PPC32=y +CONFIG_6xx=y +# CONFIG_4xx is not set +# CONFIG_POWER3 is not set +# CONFIG_8xx is not set +# CONFIG_PPC_ISERIES is not set +# CONFIG_8260 is not set +CONFIG_PPC_STD_MMU=y +# CONFIG_ALL_PPC is not set +# CONFIG_APUS is not set +# CONFIG_WILLOW is not set +# CONFIG_PCORE is not set +# CONFIG_POWERPMC250 is not set +# CONFIG_EV64260 is not set +# CONFIG_SPRUCE is not set +# CONFIG_MENF1 is not set +# CONFIG_LOPEC is not set +# CONFIG_MCPN765 is not set +# CONFIG_MVME5100 is not set +CONFIG_PPLUS=y +# CONFIG_PRPMC750 is not set +# CONFIG_PRPMC800 is not set +# CONFIG_SANDPOINT is not set +# CONFIG_ADIR is not set +# CONFIG_K2 is not set +# CONFIG_GEMINI is not set +# CONFIG_ZX4500 is not set +# CONFIG_SMP is not set +# CONFIG_ALTIVEC is not set +# CONFIG_TAU is not set + +# +# General setup +# +# CONFIG_HIGHMEM is not set +# CONFIG_ISA is not set +# CONFIG_EISA is not set +# CONFIG_SBUS is not set +# CONFIG_MCA is not set +CONFIG_PCI=y +CONFIG_NET=y +CONFIG_SYSCTL=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_KCORE_ELF=y +CONFIG_BINFMT_ELF=y +CONFIG_KERNEL_ELF=y +# CONFIG_BINFMT_MISC is not set +# CONFIG_PCI_NAMES is not set +# CONFIG_HOTPLUG is not set +# CONFIG_PCMCIA is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set +CONFIG_PPC_RTC=y +CONFIG_CMDLINE_BOOL=y +CONFIG_CMDLINE="ip=on" + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Plug and Play configuration +# +# CONFIG_PNP is not set +# CONFIG_ISAPNP is not set + +# +# Block devices +# +CONFIG_BLK_DEV_FD=y +# CONFIG_BLK_DEV_XD is not set +# CONFIG_PARIDE is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_BLK_DEV_INITRD is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set +# CONFIG_BLK_DEV_MD is not set +# CONFIG_MD_LINEAR is not set +# CONFIG_MD_RAID0 is not set +# CONFIG_MD_RAID1 is not set +# CONFIG_MD_RAID5 is not set +# CONFIG_MD_MULTIPATH is not set +# CONFIG_BLK_DEV_LVM is not set + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_NETLINK=y +# CONFIG_RTNETLINK is not set +# CONFIG_NETLINK_DEV is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +# CONFIG_FILTER is not set +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +# CONFIG_IP_PNP_BOOTP is not set +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_INET_ECN is not set +CONFIG_SYN_COOKIES=y + +# +# IP: Netfilter Configuration +# +CONFIG_IP_NF_CONNTRACK=m +CONFIG_IP_NF_FTP=m +# CONFIG_IP_NF_IRC is not set +# CONFIG_IP_NF_QUEUE is not set +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_LIMIT=m +CONFIG_IP_NF_MATCH_MAC=m +CONFIG_IP_NF_MATCH_MARK=m +CONFIG_IP_NF_MATCH_MULTIPORT=m +CONFIG_IP_NF_MATCH_TOS=m +# CONFIG_IP_NF_MATCH_LENGTH is not set +# CONFIG_IP_NF_MATCH_TTL is not set +# CONFIG_IP_NF_MATCH_TCPMSS is not set +CONFIG_IP_NF_MATCH_STATE=m +CONFIG_IP_NF_MATCH_UNCLEAN=m +CONFIG_IP_NF_MATCH_OWNER=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_MIRROR=m +CONFIG_IP_NF_NAT=m +CONFIG_IP_NF_NAT_NEEDED=y +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_REDIRECT=m +# CONFIG_IP_NF_NAT_SNMP_BASIC is not set +CONFIG_IP_NF_NAT_FTP=m +# CONFIG_IP_NF_MANGLE is not set +# CONFIG_IP_NF_TARGET_LOG is not set +# CONFIG_IP_NF_TARGET_TCPMSS is not set +CONFIG_IP_NF_COMPAT_IPCHAINS=m +CONFIG_IP_NF_NAT_NEEDED=y +# CONFIG_IP_NF_COMPAT_IPFWADM is not set +# CONFIG_IPV6 is not set +# CONFIG_KHTTPD is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set + +# +# +# +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# ATA/IDE/MFM/RLL support +# +CONFIG_IDE=y + +# +# IDE, ATA and ATAPI Block devices +# +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_HD_IDE is not set +# CONFIG_BLK_DEV_HD is not set +CONFIG_BLK_DEV_IDEDISK=y +# CONFIG_IDEDISK_MULTI_MODE is not set +# CONFIG_BLK_DEV_IDEDISK_VENDOR is not set +# CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set +# CONFIG_BLK_DEV_IDEDISK_IBM is not set +# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set +# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set +# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set +# CONFIG_BLK_DEV_IDEDISK_WD is not set +# CONFIG_BLK_DEV_COMMERIAL is not set +# CONFIG_BLK_DEV_TIVO is not set +# CONFIG_BLK_DEV_IDECS is not set +CONFIG_BLK_DEV_IDECD=y +# CONFIG_BLK_DEV_IDETAPE is not set +CONFIG_BLK_DEV_IDEFLOPPY=y +CONFIG_BLK_DEV_IDESCSI=y + +# +# IDE chipset support/bugfixes +# +# CONFIG_BLK_DEV_CMD640 is not set +# CONFIG_BLK_DEV_CMD640_ENHANCED is not set +# CONFIG_BLK_DEV_ISAPNP is not set +# CONFIG_BLK_DEV_RZ1000 is not set +CONFIG_BLK_DEV_IDEPCI=y +CONFIG_IDEPCI_SHARE_IRQ=y +CONFIG_BLK_DEV_IDEDMA_PCI=y +CONFIG_BLK_DEV_ADMA=y +# CONFIG_BLK_DEV_OFFBOARD is not set +# CONFIG_IDEDMA_PCI_AUTO is not set +CONFIG_BLK_DEV_IDEDMA=y +# CONFIG_IDEDMA_PCI_WIP is not set +# CONFIG_IDEDMA_NEW_DRIVE_LISTINGS is not set +# CONFIG_BLK_DEV_AEC62XX is not set +# CONFIG_AEC62XX_TUNING is not set +# CONFIG_BLK_DEV_ALI15X3 is not set +# CONFIG_WDC_ALI15X3 is not set +# CONFIG_BLK_DEV_AMD74XX is not set +# CONFIG_AMD74XX_OVERRIDE is not set +# CONFIG_BLK_DEV_CMD64X is not set +# CONFIG_BLK_DEV_CY82C693 is not set +# CONFIG_BLK_DEV_CS5530 is not set +# CONFIG_BLK_DEV_HPT34X is not set +# CONFIG_HPT34X_AUTODMA is not set +# CONFIG_BLK_DEV_HPT366 is not set +# CONFIG_BLK_DEV_NS87415 is not set +# CONFIG_BLK_DEV_OPTI621 is not set +# CONFIG_BLK_DEV_PDC202XX is not set +# CONFIG_PDC202XX_BURST is not set +# CONFIG_PDC202XX_FORCE is not set +# CONFIG_BLK_DEV_SVWKS is not set +# CONFIG_BLK_DEV_SIS5513 is not set +# CONFIG_BLK_DEV_SLC90E66 is not set +# CONFIG_BLK_DEV_TRM290 is not set +CONFIG_BLK_DEV_VIA82CXXX=y +CONFIG_BLK_DEV_SL82C105=y +# CONFIG_IDE_CHIPSETS is not set +# CONFIG_IDEDMA_AUTO is not set +# CONFIG_IDEDMA_IVB is not set +# CONFIG_DMA_NONPCI is not set +CONFIG_BLK_DEV_IDE_MODES=y +# CONFIG_BLK_DEV_ATARAID is not set +# CONFIG_BLK_DEV_ATARAID_PDC is not set +# CONFIG_BLK_DEV_ATARAID_HPT is not set + +# +# SCSI support +# +CONFIG_SCSI=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +CONFIG_SD_EXTRA_DEVS=40 +CONFIG_CHR_DEV_ST=y +# CONFIG_CHR_DEV_OSST is not set +CONFIG_BLK_DEV_SR=y +CONFIG_BLK_DEV_SR_VENDOR=y +CONFIG_SR_EXTRA_DEVS=2 +CONFIG_CHR_DEV_SG=y + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_DEBUG_QUEUES is not set +# CONFIG_SCSI_MULTI_LUN is not set +CONFIG_SCSI_CONSTANTS=y +# CONFIG_SCSI_LOGGING is not set + +# +# SCSI low-level drivers +# +# CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_7000FASST is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_AHA152X is not set +# CONFIG_SCSI_AHA1542 is not set +# CONFIG_SCSI_AHA1740 is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_DPT_I2O is not set +# CONFIG_SCSI_ADVANSYS is not set +# CONFIG_SCSI_IN2000 is not set +# CONFIG_SCSI_AM53C974 is not set +# CONFIG_SCSI_MEGARAID is not set +# CONFIG_SCSI_BUSLOGIC is not set +# CONFIG_SCSI_CPQFCTS is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_DTC3280 is not set +# CONFIG_SCSI_EATA is not set +# CONFIG_SCSI_EATA_DMA is not set +# CONFIG_SCSI_EATA_PIO is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_GDTH is not set +# CONFIG_SCSI_GENERIC_NCR5380 is not set +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_NCR53C406A is not set +# CONFIG_SCSI_NCR53C7xx is not set +# CONFIG_SCSI_SYM53C8XX_2 is not set +# CONFIG_SCSI_NCR53C8XX is not set +CONFIG_SCSI_SYM53C8XX=y +CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=8 +CONFIG_SCSI_NCR53C8XX_MAX_TAGS=32 +CONFIG_SCSI_NCR53C8XX_SYNC=20 +# CONFIG_SCSI_NCR53C8XX_PROFILE is not set +# CONFIG_SCSI_NCR53C8XX_IOMAPPED is not set +# CONFIG_SCSI_NCR53C8XX_PQS_PDS is not set +# CONFIG_SCSI_NCR53C8XX_SYMBIOS_COMPAT is not set +# CONFIG_SCSI_PAS16 is not set +# CONFIG_SCSI_PCI2000 is not set +# CONFIG_SCSI_PCI2220I is not set +# CONFIG_SCSI_PSI240I is not set +# CONFIG_SCSI_QLOGIC_FAS is not set +# CONFIG_SCSI_QLOGIC_ISP is not set +# CONFIG_SCSI_QLOGIC_FC is not set +# CONFIG_SCSI_QLOGIC_1280 is not set +# CONFIG_SCSI_SIM710 is not set +# CONFIG_SCSI_SYM53C416 is not set +# CONFIG_SCSI_DC390T is not set +# CONFIG_SCSI_T128 is not set +# CONFIG_SCSI_U14_34F is not set +# CONFIG_SCSI_DEBUG is not set + +# +# IEEE 1394 (FireWire) support (EXPERIMENTAL) +# +# CONFIG_IEEE1394 is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_MACE is not set +# CONFIG_BMAC is not set +# CONFIG_GMAC is not set +# CONFIG_SUNLANCE is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNBMAC is not set +# CONFIG_SUNQE is not set +# CONFIG_SUNLANCE is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_HP100 is not set +# CONFIG_NET_ISA is not set +CONFIG_NET_PCI=y +# CONFIG_PCNET32 is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_APRICOT is not set +# CONFIG_CS89x0 is not set +CONFIG_TULIP=y +# CONFIG_TULIP_MWI is not set +# CONFIG_TULIP_MMIO is not set +# CONFIG_DE4X5 is not set +# CONFIG_DGRS is not set +# CONFIG_DM9102 is not set +CONFIG_EEPRO100=y +# CONFIG_LNE390 is not set +# CONFIG_FEALNX is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_NE3210 is not set +# CONFIG_ES3210 is not set +# CONFIG_8139CP is not set +# CONFIG_8139TOO is not set +# CONFIG_8139TOO_PIO is not set +# CONFIG_8139TOO_TUNE_TWISTER is not set +# CONFIG_8139TOO_8129 is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_TLAN is not set +# CONFIG_VIA_RHINE is not set +# CONFIG_WINBOND_840 is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_MYRI_SBUS is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_SK98LIN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Old CD-ROM drivers (not SCSI, not IDE) +# +# CONFIG_CD_NO_IDESCSI is not set + +# +# Console drivers +# +# CONFIG_VGA_CONSOLE is not set + +# +# Frame-buffer support +# +# CONFIG_FB is not set + +# +# Input core support +# +# CONFIG_INPUT is not set +# CONFIG_INPUT_KEYBDEV is not set +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set + +# +# Macintosh device drivers +# + +# +# Character devices +# +# CONFIG_VT is not set +CONFIG_SERIAL=y +CONFIG_SERIAL_CONSOLE=y +# CONFIG_SERIAL_EXTENDED is not set +# CONFIG_SERIAL_NONSTANDARD is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Mice +# +CONFIG_BUSMOUSE=y +# CONFIG_ATIXL_BUSMOUSE is not set +# CONFIG_LOGIBUSMOUSE is not set +# CONFIG_MS_BUSMOUSE is not set +CONFIG_MOUSE=y +CONFIG_PSMOUSE=y +# CONFIG_82C710_MOUSE is not set +# CONFIG_PC110_PAD is not set + +# +# Joysticks +# +# CONFIG_INPUT_GAMEPORT is not set + +# +# Input core support is needed for gameports +# + +# +# Input core support is needed for joysticks +# +# CONFIG_QIC02_TAPE is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_INTEL_RNG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set +# CONFIG_ADFS_FS is not set +# CONFIG_ADFS_FS_RW is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_JBD_DEBUG is not set +# CONFIG_FAT_FS is not set +# CONFIG_MSDOS_FS is not set +# CONFIG_UMSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_TMPFS is not set +# CONFIG_RAMFS is not set +CONFIG_ISO9660_FS=y +# CONFIG_JOLIET is not set +# CONFIG_ZISOFS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_NTFS_FS is not set +# CONFIG_NTFS_RW is not set +# CONFIG_HPFS_FS is not set +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVFS_MOUNT is not set +# CONFIG_DEVFS_DEBUG is not set +CONFIG_DEVPTS_FS=y +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set +# CONFIG_ROMFS_FS is not set +CONFIG_EXT2_FS=y +# CONFIG_SYSV_FS is not set +# CONFIG_UDF_FS is not set +# CONFIG_UDF_RW is not set +# CONFIG_UFS_FS is not set +# CONFIG_UFS_FS_WRITE is not set + +# +# Network File Systems +# +# CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +CONFIG_ROOT_NFS=y +# CONFIG_NFSD is not set +# CONFIG_NFSD_V3 is not set +CONFIG_SUNRPC=y +CONFIG_LOCKD=y +# CONFIG_SMB_FS is not set +# CONFIG_NCP_FS is not set +# CONFIG_NCPFS_PACKET_SIGNING is not set +# CONFIG_NCPFS_IOCTL_LOCKING is not set +# CONFIG_NCPFS_STRONG is not set +# CONFIG_NCPFS_NFS_NS is not set +# CONFIG_NCPFS_OS2_NS is not set +# CONFIG_NCPFS_SMALLDOS is not set +# CONFIG_NCPFS_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set +# CONFIG_ZISOFS_FS is not set +# CONFIG_ZLIB_FS_INFLATE is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_SMB_NLS is not set +# CONFIG_NLS is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB is not set + +# +# USB Controllers +# +# CONFIG_USB_UHCI is not set +# CONFIG_USB_UHCI_ALT is not set +# CONFIG_USB_OHCI is not set + +# +# USB Device Class drivers +# +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_BLUETOOTH is not set +# CONFIG_USB_STORAGE is not set +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_HP8200e is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set + +# +# USB Human Interface Devices (HID) +# + +# +# Input core support is needed for USB HID +# + +# +# USB Imaging devices +# +# CONFIG_USB_DC2XX is not set +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_SCANNER is not set +# CONFIG_USB_MICROTEK is not set +# CONFIG_USB_HPUSBSCSI is not set + +# +# USB Multimedia devices +# + +# +# Video4Linux support is needed for USB Multimedia device support +# + +# +# USB Network adaptors +# +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_CATC is not set +# CONFIG_USB_CDCETHER is not set +# CONFIG_USB_USBNET is not set + +# +# USB port drivers +# +# CONFIG_USB_USS720 is not set + +# +# USB Serial Converter support +# +# CONFIG_USB_SERIAL is not set +# CONFIG_USB_SERIAL_GENERIC is not set +# CONFIG_USB_SERIAL_BELKIN is not set +# CONFIG_USB_SERIAL_WHITEHEAT is not set +# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set +# CONFIG_USB_SERIAL_EMPEG is not set +# CONFIG_USB_SERIAL_FTDI_SIO is not set +# CONFIG_USB_SERIAL_VISOR is not set +# CONFIG_USB_SERIAL_IR is not set +# CONFIG_USB_SERIAL_EDGEPORT is not set +# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set +# CONFIG_USB_SERIAL_KEYSPAN is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set +# CONFIG_USB_SERIAL_MCT_U232 is not set +# CONFIG_USB_SERIAL_PL2303 is not set +# CONFIG_USB_SERIAL_CYBERJACK is not set +# CONFIG_USB_SERIAL_XIRCOM is not set +# CONFIG_USB_SERIAL_OMNINET is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_RIO500 is not set + +# +# Bluetooth support +# +# CONFIG_BLUEZ is not set + +# +# Kernel hacking +# +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_KGDB is not set +# CONFIG_XMON is not set +# CONFIG_BDI_SWITCH is not set diff --git a/arch/ppc/configs/prpmc750_defconfig b/arch/ppc/configs/prpmc750_defconfig new file mode 100644 index 000000000000..bb6e1807f205 --- /dev/null +++ b/arch/ppc/configs/prpmc750_defconfig @@ -0,0 +1,567 @@ +# +# Automatically generated by make menuconfig: don't edit +# +# CONFIG_UID16 is not set +# CONFIG_RWSEM_GENERIC_SPINLOCK is not set +CONFIG_RWSEM_XCHGADD_ALGORITHM=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODVERSIONS=y +CONFIG_KMOD=y + +# +# Platform support +# +CONFIG_PPC=y +CONFIG_PPC32=y +CONFIG_6xx=y +# CONFIG_4xx is not set +# CONFIG_POWER3 is not set +# CONFIG_8xx is not set +# CONFIG_PPC_ISERIES is not set +# CONFIG_8260 is not set +CONFIG_PPC_STD_MMU=y +# CONFIG_ALL_PPC is not set +# CONFIG_APUS is not set +# CONFIG_SPRUCE is not set +# CONFIG_PCORE is not set +# CONFIG_MENF1 is not set +# CONFIG_LOPEC is not set +# CONFIG_MCPN765 is not set +# CONFIG_MVME5100 is not set +CONFIG_PRPMC750=y +# CONFIG_PRPMC800 is not set +# CONFIG_SANDPOINT is not set +# CONFIG_ADIR is not set +# CONFIG_K2 is not set +# CONFIG_GEMINI is not set +# CONFIG_WILLOW is not set +# CONFIG_ZX4500 is not set +# CONFIG_SMP is not set +# CONFIG_ALTIVEC is not set +# CONFIG_TAU is not set + +# +# General setup +# +# CONFIG_HIGHMEM is not set +# CONFIG_ISA is not set +# CONFIG_EISA is not set +# CONFIG_SBUS is not set +# CONFIG_MCA is not set +CONFIG_PCI=y +CONFIG_NET=y +CONFIG_SYSCTL=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_KCORE_ELF=y +CONFIG_BINFMT_ELF=y +CONFIG_KERNEL_ELF=y +# CONFIG_BINFMT_MISC is not set +# CONFIG_PCI_NAMES is not set +# CONFIG_HOTPLUG is not set +# CONFIG_PCMCIA is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set +# CONFIG_PPC_RTC is not set +CONFIG_CMDLINE_BOOL=y +CONFIG_CMDLINE="ip=on" + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Plug and Play configuration +# +# CONFIG_PNP is not set +# CONFIG_ISAPNP is not set +# CONFIG_PNPBIOS is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_XD is not set +# CONFIG_PARIDE is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_INITRD=y + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set +# CONFIG_BLK_DEV_MD is not set +# CONFIG_MD_LINEAR is not set +# CONFIG_MD_RAID0 is not set +# CONFIG_MD_RAID1 is not set +# CONFIG_MD_RAID5 is not set +# CONFIG_MD_MULTIPATH is not set +# CONFIG_BLK_DEV_LVM is not set + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_NETLINK=y +# CONFIG_RTNETLINK is not set +# CONFIG_NETLINK_DEV is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +# CONFIG_FILTER is not set +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +# CONFIG_IP_PNP_BOOTP is not set +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set + +# +# IP: Netfilter Configuration +# +CONFIG_IP_NF_CONNTRACK=m +CONFIG_IP_NF_FTP=m +# CONFIG_IP_NF_QUEUE is not set +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_LIMIT=m +CONFIG_IP_NF_MATCH_MAC=m +CONFIG_IP_NF_MATCH_MARK=m +CONFIG_IP_NF_MATCH_MULTIPORT=m +CONFIG_IP_NF_MATCH_TOS=m +CONFIG_IP_NF_MATCH_TCPMSS=m +CONFIG_IP_NF_MATCH_STATE=m +CONFIG_IP_NF_MATCH_UNCLEAN=m +CONFIG_IP_NF_MATCH_OWNER=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_MIRROR=m +CONFIG_IP_NF_NAT=m +CONFIG_IP_NF_NAT_NEEDED=y +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_NAT_FTP=m +# CONFIG_IP_NF_MANGLE is not set +# CONFIG_IP_NF_TARGET_LOG is not set +CONFIG_IP_NF_TARGET_TCPMSS=m +CONFIG_IP_NF_COMPAT_IPCHAINS=m +CONFIG_IP_NF_NAT_NEEDED=y +# CONFIG_IP_NF_COMPAT_IPFWADM is not set +# CONFIG_IPV6 is not set +# CONFIG_KHTTPD is not set +# CONFIG_ATM is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# ATA/IDE/MFM/RLL support +# +# CONFIG_IDE is not set +# CONFIG_BLK_DEV_IDE_MODES is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI support +# +# CONFIG_SCSI is not set + +# +# IEEE 1394 (FireWire) support (EXPERIMENTAL) +# +# CONFIG_IEEE1394 is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_MACE is not set +# CONFIG_BMAC is not set +# CONFIG_GMAC is not set +# CONFIG_SUNLANCE is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNBMAC is not set +# CONFIG_SUNQE is not set +# CONFIG_SUNLANCE is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_HP100 is not set +# CONFIG_NET_ISA is not set +CONFIG_NET_PCI=y +# CONFIG_PCNET32 is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_APRICOT is not set +# CONFIG_CS89x0 is not set +CONFIG_TULIP=y +# CONFIG_TULIP_MWI is not set +# CONFIG_TULIP_MMIO is not set +# CONFIG_DE4X5 is not set +# CONFIG_DGRS is not set +# CONFIG_DM9102 is not set +CONFIG_EEPRO100=y +# CONFIG_LNE390 is not set +# CONFIG_FEALNX is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_NE3210 is not set +# CONFIG_ES3210 is not set +# CONFIG_8139CP is not set +# CONFIG_8139TOO is not set +# CONFIG_8139TOO_PIO is not set +# CONFIG_8139TOO_TUNE_TWISTER is not set +# CONFIG_8139TOO_8129 is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_TLAN is not set +# CONFIG_VIA_RHINE is not set +# CONFIG_WINBOND_840 is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_MYRI_SBUS is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_SK98LIN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Old CD-ROM drivers (not SCSI, not IDE) +# +# CONFIG_CD_NO_IDESCSI is not set + +# +# Console drivers +# +# CONFIG_VGA_CONSOLE is not set + +# +# Frame-buffer support +# +# CONFIG_FB is not set + +# +# Input core support +# +# CONFIG_INPUT is not set +# CONFIG_INPUT_KEYBDEV is not set +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set + +# +# Macintosh device drivers +# + +# +# Character devices +# +CONFIG_VT=y +# CONFIG_VT_CONSOLE is not set +CONFIG_SERIAL=y +CONFIG_SERIAL_CONSOLE=y +# CONFIG_SERIAL_EXTENDED is not set +# CONFIG_SERIAL_NONSTANDARD is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Mice +# +CONFIG_BUSMOUSE=y +# CONFIG_ATIXL_BUSMOUSE is not set +# CONFIG_LOGIBUSMOUSE is not set +# CONFIG_MS_BUSMOUSE is not set +CONFIG_MOUSE=y +CONFIG_PSMOUSE=y +# CONFIG_82C710_MOUSE is not set +# CONFIG_PC110_PAD is not set + +# +# Joysticks +# +# CONFIG_INPUT_GAMEPORT is not set +# CONFIG_QIC02_TAPE is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_INTEL_RNG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set +# CONFIG_MWAVE is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set +# CONFIG_ADFS_FS is not set +# CONFIG_ADFS_FS_RW is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_FAT_FS is not set +# CONFIG_MSDOS_FS is not set +# CONFIG_UMSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_CRAMFS is not set +CONFIG_TMPFS=y +# CONFIG_RAMFS is not set +# CONFIG_ISO9660_FS is not set +# CONFIG_JOLIET is not set +# CONFIG_MINIX_FS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_NTFS_FS is not set +# CONFIG_NTFS_RW is not set +# CONFIG_HPFS_FS is not set +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVFS_MOUNT is not set +# CONFIG_DEVFS_DEBUG is not set +CONFIG_DEVPTS_FS=y +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set +# CONFIG_ROMFS_FS is not set +CONFIG_EXT2_FS=y +# CONFIG_SYSV_FS is not set +# CONFIG_UDF_FS is not set +# CONFIG_UDF_RW is not set +# CONFIG_UFS_FS is not set +# CONFIG_UFS_FS_WRITE is not set + +# +# Network File Systems +# +# CONFIG_CODA_FS is not set +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +CONFIG_ROOT_NFS=y +# CONFIG_NFSD is not set +# CONFIG_NFSD_V3 is not set +CONFIG_SUNRPC=y +CONFIG_LOCKD=y +# CONFIG_SMB_FS is not set +# CONFIG_NCP_FS is not set +# CONFIG_NCPFS_PACKET_SIGNING is not set +# CONFIG_NCPFS_IOCTL_LOCKING is not set +# CONFIG_NCPFS_STRONG is not set +# CONFIG_NCPFS_NFS_NS is not set +# CONFIG_NCPFS_OS2_NS is not set +# CONFIG_NCPFS_SMALLDOS is not set +# CONFIG_NCPFS_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_SMB_NLS is not set +# CONFIG_NLS is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB is not set +# CONFIG_USB_UHCI is not set +# CONFIG_USB_UHCI_ALT is not set +# CONFIG_USB_OHCI is not set +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_BLUETOOTH is not set +# CONFIG_USB_STORAGE is not set +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_HP8200e is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set +# CONFIG_USB_DC2XX is not set +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_SCANNER is not set +# CONFIG_USB_MICROTEK is not set +# CONFIG_USB_HPUSBSCSI is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_CATC is not set +# CONFIG_USB_CDCETHER is not set +# CONFIG_USB_USBNET is not set +# CONFIG_USB_USS720 is not set + +# +# USB Serial Converter support +# +# CONFIG_USB_SERIAL is not set +# CONFIG_USB_SERIAL_GENERIC is not set +# CONFIG_USB_SERIAL_BELKIN is not set +# CONFIG_USB_SERIAL_WHITEHEAT is not set +# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set +# CONFIG_USB_SERIAL_EMPEG is not set +# CONFIG_USB_SERIAL_FTDI_SIO is not set +# CONFIG_USB_SERIAL_VISOR is not set +# CONFIG_USB_SERIAL_IR is not set +# CONFIG_USB_SERIAL_EDGEPORT is not set +# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set +# CONFIG_USB_SERIAL_KEYSPAN is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set +# CONFIG_USB_SERIAL_MCT_U232 is not set +# CONFIG_USB_SERIAL_PL2303 is not set +# CONFIG_USB_SERIAL_CYBERJACK is not set +# CONFIG_USB_SERIAL_XIRCOM is not set +# CONFIG_USB_SERIAL_OMNINET is not set +# CONFIG_USB_RIO500 is not set + +# +# Bluetooth support +# +# CONFIG_BLUEZ is not set + +# +# Kernel hacking +# +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_KGDB is not set +# CONFIG_XMON is not set +# CONFIG_BDI_SWITCH is not set diff --git a/arch/ppc/configs/prpmc800_defconfig b/arch/ppc/configs/prpmc800_defconfig new file mode 100644 index 000000000000..0de454bef38b --- /dev/null +++ b/arch/ppc/configs/prpmc800_defconfig @@ -0,0 +1,525 @@ +# +# Automatically generated make config: don't edit +# +# CONFIG_UID16 is not set +# CONFIG_RWSEM_GENERIC_SPINLOCK is not set +CONFIG_RWSEM_XCHGADD_ALGORITHM=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODVERSIONS=y +CONFIG_KMOD=y + +# +# Platform support +# +CONFIG_PPC=y +CONFIG_PPC32=y +CONFIG_6xx=y +# CONFIG_4xx is not set +# CONFIG_POWER3 is not set +# CONFIG_8xx is not set +# CONFIG_PPC_ISERIES is not set +# CONFIG_8260 is not set +CONFIG_PPC_STD_MMU=y +# CONFIG_ALL_PPC is not set +# CONFIG_APUS is not set +# CONFIG_SPRUCE is not set +# CONFIG_PCORE is not set +# CONFIG_MENF1 is not set +# CONFIG_LOPEC is not set +# CONFIG_MCPN765 is not set +# CONFIG_MVME5100 is not set +# CONFIG_PRPMC750 is not set +CONFIG_PRPMC800=y +# CONFIG_SANDPOINT is not set +# CONFIG_ADIR is not set +# CONFIG_K2 is not set +# CONFIG_GEMINI is not set +# CONFIG_WILLOW is not set +# CONFIG_ZX4500 is not set +# CONFIG_SMP is not set +# CONFIG_ALTIVEC is not set +# CONFIG_TAU is not set + +# +# General setup +# +# CONFIG_HIGHMEM is not set +# CONFIG_ISA is not set +# CONFIG_EISA is not set +# CONFIG_SBUS is not set +# CONFIG_MCA is not set +CONFIG_PCI=y +CONFIG_NET=y +CONFIG_SYSCTL=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_KCORE_ELF=y +CONFIG_BINFMT_ELF=y +CONFIG_KERNEL_ELF=y +# CONFIG_BINFMT_MISC is not set +# CONFIG_PCI_NAMES is not set +# CONFIG_HOTPLUG is not set +# CONFIG_PCMCIA is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set +# CONFIG_PPC_RTC is not set +CONFIG_CMDLINE_BOOL=y +CONFIG_CMDLINE="ip=on" + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Plug and Play configuration +# +# CONFIG_PNP is not set +# CONFIG_ISAPNP is not set +# CONFIG_PNPBIOS is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_VIODASD is not set +# CONFIG_BLK_DEV_XD is not set +# CONFIG_PARIDE is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_INITRD=y + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set +# CONFIG_BLK_DEV_MD is not set +# CONFIG_MD_LINEAR is not set +# CONFIG_MD_RAID0 is not set +# CONFIG_MD_RAID1 is not set +# CONFIG_MD_RAID5 is not set +# CONFIG_MD_MULTIPATH is not set +# CONFIG_BLK_DEV_LVM is not set + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_NETLINK=y +# CONFIG_RTNETLINK is not set +# CONFIG_NETLINK_DEV is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +# CONFIG_FILTER is not set +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +# CONFIG_IP_PNP_BOOTP is not set +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set + +# +# IP: Netfilter Configuration +# +CONFIG_IP_NF_CONNTRACK=m +CONFIG_IP_NF_FTP=m +# CONFIG_IP_NF_QUEUE is not set +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_LIMIT=m +CONFIG_IP_NF_MATCH_MAC=m +CONFIG_IP_NF_MATCH_MARK=m +CONFIG_IP_NF_MATCH_MULTIPORT=m +CONFIG_IP_NF_MATCH_TOS=m +CONFIG_IP_NF_MATCH_TCPMSS=m +CONFIG_IP_NF_MATCH_STATE=m +CONFIG_IP_NF_MATCH_UNCLEAN=m +CONFIG_IP_NF_MATCH_OWNER=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_MIRROR=m +CONFIG_IP_NF_NAT=m +CONFIG_IP_NF_NAT_NEEDED=y +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_NAT_FTP=m +# CONFIG_IP_NF_MANGLE is not set +# CONFIG_IP_NF_TARGET_LOG is not set +CONFIG_IP_NF_TARGET_TCPMSS=m +CONFIG_IP_NF_COMPAT_IPCHAINS=m +CONFIG_IP_NF_NAT_NEEDED=y +# CONFIG_IP_NF_COMPAT_IPFWADM is not set +# CONFIG_IPV6 is not set +# CONFIG_KHTTPD is not set +# CONFIG_ATM is not set + +# +# +# +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# ATA/IDE/MFM/RLL support +# +# CONFIG_IDE is not set +# CONFIG_BLK_DEV_IDE_MODES is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI support +# +# CONFIG_SCSI is not set + +# +# IEEE 1394 (FireWire) support (EXPERIMENTAL) +# +# CONFIG_IEEE1394 is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_MACE is not set +# CONFIG_BMAC is not set +# CONFIG_GMAC is not set +# CONFIG_SUNLANCE is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNBMAC is not set +# CONFIG_SUNQE is not set +# CONFIG_SUNLANCE is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_HP100 is not set +# CONFIG_NET_ISA is not set +CONFIG_NET_PCI=y +# CONFIG_PCNET32 is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_APRICOT is not set +# CONFIG_CS89x0 is not set +CONFIG_TULIP=y +# CONFIG_TULIP_MWI is not set +# CONFIG_TULIP_MMIO is not set +# CONFIG_DE4X5 is not set +# CONFIG_DGRS is not set +# CONFIG_DM9102 is not set +CONFIG_EEPRO100=y +# CONFIG_LNE390 is not set +# CONFIG_FEALNX is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_NE3210 is not set +# CONFIG_ES3210 is not set +# CONFIG_8139TOO is not set +# CONFIG_8139TOO_PIO is not set +# CONFIG_8139TOO_TUNE_TWISTER is not set +# CONFIG_8139TOO_8129 is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_TLAN is not set +# CONFIG_VIA_RHINE is not set +# CONFIG_WINBOND_840 is not set +# CONFIG_LAN_SAA9730 is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_MYRI_SBUS is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_SK98LIN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Old CD-ROM drivers (not SCSI, not IDE) +# +# CONFIG_CD_NO_IDESCSI is not set + +# +# Console drivers +# +# CONFIG_VGA_CONSOLE is not set + +# +# Frame-buffer support +# +# CONFIG_FB is not set + +# +# Input core support +# +# CONFIG_INPUT is not set +# CONFIG_INPUT_KEYBDEV is not set +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set + +# +# Macintosh device drivers +# + +# +# Character devices +# +CONFIG_VT=y +# CONFIG_VT_CONSOLE is not set +CONFIG_SERIAL=y +CONFIG_SERIAL_CONSOLE=y +# CONFIG_SERIAL_EXTENDED is not set +# CONFIG_SERIAL_NONSTANDARD is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 +# CONFIG_VIOCONS is not set + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Mice +# +CONFIG_BUSMOUSE=y +# CONFIG_ATIXL_BUSMOUSE is not set +# CONFIG_LOGIBUSMOUSE is not set +# CONFIG_MS_BUSMOUSE is not set +CONFIG_MOUSE=y +CONFIG_PSMOUSE=y +# CONFIG_82C710_MOUSE is not set +# CONFIG_PC110_PAD is not set + +# +# Joysticks +# +# CONFIG_INPUT_GAMEPORT is not set + +# +# Input core support is needed for gameports +# + +# +# Input core support is needed for joysticks +# +# CONFIG_QIC02_TAPE is not set +# CONFIG_VIOTAPE is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_INTEL_RNG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set +# CONFIG_SONYPI is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set +# CONFIG_ADFS_FS is not set +# CONFIG_ADFS_FS_RW is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_FAT_FS is not set +# CONFIG_MSDOS_FS is not set +# CONFIG_UMSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_CRAMFS is not set +CONFIG_TMPFS=y +# CONFIG_RAMFS is not set +# CONFIG_ISO9660_FS is not set +# CONFIG_JOLIET is not set +# CONFIG_MINIX_FS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_NTFS_FS is not set +# CONFIG_NTFS_RW is not set +# CONFIG_HPFS_FS is not set +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVFS_MOUNT is not set +# CONFIG_DEVFS_DEBUG is not set +CONFIG_DEVPTS_FS=y +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set +# CONFIG_ROMFS_FS is not set +CONFIG_EXT2_FS=y +# CONFIG_SYSV_FS is not set +# CONFIG_UDF_FS is not set +# CONFIG_UDF_RW is not set +# CONFIG_UFS_FS is not set +# CONFIG_UFS_FS_WRITE is not set + +# +# Network File Systems +# +# CONFIG_CODA_FS is not set +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +CONFIG_ROOT_NFS=y +# CONFIG_NFSD is not set +# CONFIG_NFSD_V3 is not set +CONFIG_SUNRPC=y +CONFIG_LOCKD=y +# CONFIG_SMB_FS is not set +# CONFIG_NCP_FS is not set +# CONFIG_NCPFS_PACKET_SIGNING is not set +# CONFIG_NCPFS_IOCTL_LOCKING is not set +# CONFIG_NCPFS_STRONG is not set +# CONFIG_NCPFS_NFS_NS is not set +# CONFIG_NCPFS_OS2_NS is not set +# CONFIG_NCPFS_SMALLDOS is not set +# CONFIG_NCPFS_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_SMB_NLS is not set +# CONFIG_NLS is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB is not set + +# +# Bluetooth support +# +# CONFIG_BLUEZ is not set + +# +# Kernel hacking +# +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_KGDB is not set +# CONFIG_XMON is not set +# CONFIG_BDI_SWITCH is not set +# CONFIG_DEBUG_TEXT is not set diff --git a/arch/ppc/configs/redwood5_defconfig b/arch/ppc/configs/redwood5_defconfig new file mode 100644 index 000000000000..043aba310623 --- /dev/null +++ b/arch/ppc/configs/redwood5_defconfig @@ -0,0 +1,582 @@ +# +# Automatically generated by make menuconfig: don't edit +# +# CONFIG_UID16 is not set +# CONFIG_RWSEM_GENERIC_SPINLOCK is not set +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_HAVE_DEC_LOCK=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODVERSIONS is not set +CONFIG_KMOD=y + +# +# Platform support +# +CONFIG_PPC=y +CONFIG_PPC32=y +# CONFIG_6xx is not set +CONFIG_4xx=y +# CONFIG_POWER3 is not set +# CONFIG_8xx is not set +# CONFIG_PPC_ISERIES is not set +# CONFIG_PPC_STD_MMU is not set +# CONFIG_CEDER is not set +# CONFIG_CPCI405 is not set +# CONFIG_EP405 is not set +# CONFIG_OAK is not set +# CONFIG_REDWOOD_4 is not set +CONFIG_REDWOOD_5=y +# CONFIG_TIVO is not set +# CONFIG_WALNUT is not set +# CONFIG_ALL_PPC is not set +# CONFIG_SMP is not set +# CONFIG_MATH_EMULATION is not set +CONFIG_STB03xxx=y +CONFIG_TREEBOOT=y +CONFIG_IBM405_ERR77=y +CONFIG_IBM_OCP=y +# CONFIG_405_DMA is not set +CONFIG_UART0_TTYS0=y +# CONFIG_UART0_TTYS1 is not set +CONFIG_IBM405_ERR51=y +CONFIG_NOT_COHERENT_CACHE=y + +# +# General setup +# +# CONFIG_HIGHMEM is not set +# CONFIG_ISA is not set +# CONFIG_EISA is not set +# CONFIG_SBUS is not set +# CONFIG_MCA is not set +# CONFIG_PCI is not set +# CONFIG_PC_KEYBOARD is not set +CONFIG_NET=y +CONFIG_SYSCTL=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_KCORE_ELF=y +CONFIG_BINFMT_ELF=y +CONFIG_KERNEL_ELF=y +# CONFIG_BINFMT_MISC is not set +# CONFIG_HOTPLUG is not set +# CONFIG_PCMCIA is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set +# CONFIG_PPC_RTC is not set +# CONFIG_CMDLINE_BOOL is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Plug and Play configuration +# +# CONFIG_PNP is not set +# CONFIG_ISAPNP is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_XD is not set +# CONFIG_PARIDE is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_INITRD=y + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set +# CONFIG_BLK_DEV_MD is not set +# CONFIG_MD_LINEAR is not set +# CONFIG_MD_RAID0 is not set +# CONFIG_MD_RAID1 is not set +# CONFIG_MD_RAID5 is not set +# CONFIG_MD_MULTIPATH is not set +# CONFIG_BLK_DEV_LVM is not set + +# +# Networking options +# +# CONFIG_PACKET is not set +# CONFIG_NETLINK_DEV is not set +# CONFIG_NETFILTER is not set +# CONFIG_FILTER is not set +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +CONFIG_IP_PNP_RARP=y +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_INET_ECN is not set +CONFIG_SYN_COOKIES=y +# CONFIG_IPV6 is not set +# CONFIG_KHTTPD is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set + +# +# Appletalk devices +# +# CONFIG_DEV_APPLETALK is not set +# CONFIG_LTPC is not set +# CONFIG_COPS is not set +# CONFIG_COPS_DAYNA is not set +# CONFIG_COPS_TANGENT is not set +# CONFIG_IPDDP is not set +# CONFIG_IPDDP_ENCAP is not set +# CONFIG_IPDDP_DECAP is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# ATA/IDE/MFM/RLL support +# +CONFIG_IDE=y + +# +# IDE, ATA and ATAPI Block devices +# +CONFIG_BLK_DEV_IDE=y +# CONFIG_BLK_DEV_HD_IDE is not set +# CONFIG_BLK_DEV_HD is not set +CONFIG_BLK_DEV_IDEDISK=y +# CONFIG_IDEDISK_MULTI_MODE is not set +# CONFIG_BLK_DEV_IDEDISK_VENDOR is not set +# CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set +# CONFIG_BLK_DEV_IDEDISK_IBM is not set +# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set +# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set +# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set +# CONFIG_BLK_DEV_IDEDISK_WD is not set +# CONFIG_BLK_DEV_COMMERIAL is not set +# CONFIG_BLK_DEV_TIVO is not set +# CONFIG_BLK_DEV_IDECS is not set +# CONFIG_BLK_DEV_IDECD is not set +# CONFIG_BLK_DEV_IDETAPE is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set +# CONFIG_BLK_DEV_IDESCSI is not set +# CONFIG_BLK_DEV_CMD640 is not set +# CONFIG_BLK_DEV_CMD640_ENHANCED is not set +# CONFIG_BLK_DEV_ISAPNP is not set +CONFIG_IBM_OCP_IDE=y +# CONFIG_IDE_CHIPSETS is not set +# CONFIG_IDEDMA_AUTO is not set +# CONFIG_DMA_NONPCI is not set +CONFIG_BLK_DEV_IDE_MODES=y +# CONFIG_BLK_DEV_ATARAID is not set +# CONFIG_BLK_DEV_ATARAID_PDC is not set +# CONFIG_BLK_DEV_ATARAID_HPT is not set + +# +# SCSI support +# +# CONFIG_SCSI is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set +# CONFIG_FUSION_BOOT is not set +# CONFIG_FUSION_ISENSE is not set +# CONFIG_FUSION_CTL is not set +# CONFIG_FUSION_LAN is not set + +# +# I2O device support +# +# CONFIG_I2O is not set +# CONFIG_I2O_BLOCK is not set +# CONFIG_I2O_LAN is not set +# CONFIG_I2O_SCSI is not set +# CONFIG_I2O_PROC is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_MACE is not set +# CONFIG_BMAC is not set +# CONFIG_GMAC is not set +# CONFIG_IBM_OCP_ENET is not set +# CONFIG_SUNLANCE is not set +# CONFIG_SUNBMAC is not set +# CONFIG_SUNQE is not set +# CONFIG_SUNLANCE is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +CONFIG_NET_VENDOR_SMC=y +# CONFIG_WD80x3 is not set +# CONFIG_ULTRAMCA is not set +# CONFIG_ULTRA is not set +# CONFIG_ULTRA32 is not set +# CONFIG_SMC9194 is not set +CONFIG_SMC91111=y +CONFIG_SMC91111_ADVANCED=y +CONFIG_SMC91111_BYTE_SWAP=y +# CONFIG_SMC91111_USE_8_BIT is not set +# CONFIG_SMC91111_USE_32_BIT is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_NET_ISA is not set +# CONFIG_NET_PCI is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_MYRI_SBUS is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_SK98LIN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Old CD-ROM drivers (not SCSI, not IDE) +# +# CONFIG_CD_NO_IDESCSI is not set + +# +# Console drivers +# + +# +# Frame-buffer support +# +# CONFIG_FB is not set + +# +# Input core support +# +# CONFIG_INPUT is not set +# CONFIG_INPUT_KEYBDEV is not set +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set + +# +# Macintosh device drivers +# + +# +# Character devices +# +# CONFIG_VT is not set +CONFIG_SERIAL=y +CONFIG_SERIAL_CONSOLE=y +# CONFIG_SERIAL_EXTENDED is not set +# CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_UNIX98_PTYS is not set + +# +# I2C support +# +CONFIG_I2C=y +# CONFIG_I2C_ALGOBIT is not set +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_CHARDEV is not set +# CONFIG_I2C_PROC is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set + +# +# Joysticks +# +# CONFIG_INPUT_GAMEPORT is not set +# CONFIG_QIC02_TAPE is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_INTEL_RNG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set +# CONFIG_ADFS_FS is not set +# CONFIG_ADFS_FS_RW is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_JBD_DEBUG is not set +# CONFIG_FAT_FS is not set +# CONFIG_MSDOS_FS is not set +# CONFIG_UMSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_CRAMFS is not set +CONFIG_TMPFS=y +# CONFIG_RAMFS is not set +# CONFIG_ISO9660_FS is not set +# CONFIG_JOLIET is not set +# CONFIG_ZISOFS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_NTFS_FS is not set +# CONFIG_NTFS_RW is not set +# CONFIG_HPFS_FS is not set +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVFS_MOUNT is not set +# CONFIG_DEVFS_DEBUG is not set +# CONFIG_DEVPTS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set +# CONFIG_ROMFS_FS is not set +CONFIG_EXT2_FS=y +# CONFIG_SYSV_FS is not set +# CONFIG_UDF_FS is not set +# CONFIG_UDF_RW is not set +# CONFIG_UFS_FS is not set +# CONFIG_UFS_FS_WRITE is not set + +# +# Network File Systems +# +# CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +CONFIG_ROOT_NFS=y +# CONFIG_NFSD is not set +# CONFIG_NFSD_V3 is not set +CONFIG_SUNRPC=y +CONFIG_LOCKD=y +# CONFIG_SMB_FS is not set +# CONFIG_NCP_FS is not set +# CONFIG_NCPFS_PACKET_SIGNING is not set +# CONFIG_NCPFS_IOCTL_LOCKING is not set +# CONFIG_NCPFS_STRONG is not set +# CONFIG_NCPFS_NFS_NS is not set +# CONFIG_NCPFS_OS2_NS is not set +# CONFIG_NCPFS_SMALLDOS is not set +# CONFIG_NCPFS_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set +# CONFIG_ZISOFS_FS is not set +# CONFIG_ZLIB_FS_INFLATE is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_SMB_NLS is not set +# CONFIG_NLS is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# MPC4xx Driver Options +# +# CONFIG_STB_KB is not set +# CONFIG_SERIAL_SICC is not set + +# +# USB support +# +# CONFIG_USB is not set +# CONFIG_USB_UHCI is not set +# CONFIG_USB_UHCI_ALT is not set +# CONFIG_USB_OHCI is not set +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_BLUETOOTH is not set +# CONFIG_USB_STORAGE is not set +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_HP8200e is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set +# CONFIG_USB_DC2XX is not set +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_SCANNER is not set +# CONFIG_USB_MICROTEK is not set +# CONFIG_USB_HPUSBSCSI is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_CATC is not set +# CONFIG_USB_CDCETHER is not set +# CONFIG_USB_USBNET is not set +# CONFIG_USB_USS720 is not set + +# +# USB Serial Converter support +# +# CONFIG_USB_SERIAL is not set +# CONFIG_USB_SERIAL_GENERIC is not set +# CONFIG_USB_SERIAL_BELKIN is not set +# CONFIG_USB_SERIAL_WHITEHEAT is not set +# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set +# CONFIG_USB_SERIAL_EMPEG is not set +# CONFIG_USB_SERIAL_FTDI_SIO is not set +# CONFIG_USB_SERIAL_VISOR is not set +# CONFIG_USB_SERIAL_IPAQ is not set +# CONFIG_USB_SERIAL_IR is not set +# CONFIG_USB_SERIAL_EDGEPORT is not set +# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set +# CONFIG_USB_SERIAL_KEYSPAN is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set +# CONFIG_USB_SERIAL_MCT_U232 is not set +# CONFIG_USB_SERIAL_KLSI is not set +# CONFIG_USB_SERIAL_PL2303 is not set +# CONFIG_USB_SERIAL_CYBERJACK is not set +# CONFIG_USB_SERIAL_XIRCOM is not set +# CONFIG_USB_SERIAL_OMNINET is not set +# CONFIG_USB_RIO500 is not set + +# +# Bluetooth support +# +# CONFIG_BLUEZ is not set + +# +# Kernel hacking +# +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_KGDB is not set +# CONFIG_XMON is not set +# CONFIG_BDI_SWITCH is not set +# CONFIG_SERIAL_TEXT_DEBUG is not set diff --git a/arch/ppc/configs/redwood_defconfig b/arch/ppc/configs/redwood_defconfig new file mode 100644 index 000000000000..b6dbb1b8faad --- /dev/null +++ b/arch/ppc/configs/redwood_defconfig @@ -0,0 +1,546 @@ +# +# Automatically generated make config: don't edit +# +# CONFIG_UID16 is not set +# CONFIG_RWSEM_GENERIC_SPINLOCK is not set +CONFIG_RWSEM_XCHGADD_ALGORITHM=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODVERSIONS=y +CONFIG_KMOD=y + +# +# Platform support +# +CONFIG_PPC=y +CONFIG_PPC32=y +# CONFIG_6xx is not set +CONFIG_4xx=y +# CONFIG_POWER3 is not set +# CONFIG_8xx is not set +# CONFIG_PPC_ISERIES is not set +# CONFIG_PPC_STD_MMU is not set +# CONFIG_OAK is not set +CONFIG_REDWOOD_4=y +# CONFIG_REDWOOD_5 is not set +# CONFIG_TIVO is not set +# CONFIG_EP405 is not set +# CONFIG_CPCI405 is not set +# CONFIG_WALNUT is not set +# CONFIG_ALL_PPC is not set +# CONFIG_SMP is not set +# CONFIG_MATH_EMULATION is not set +CONFIG_STB03xxx=y +CONFIG_TREEBOOT=y +CONFIG_IBM405_ERR77=y +# CONFIG_405_DMA is not set +CONFIG_IBM405_ERR51=y +CONFIG_NOT_COHERENT_CACHE=y + +# +# General setup +# +# CONFIG_HIGHMEM is not set +# CONFIG_ISA is not set +# CONFIG_EISA is not set +# CONFIG_SBUS is not set +# CONFIG_MCA is not set +# CONFIG_PCI is not set +# CONFIG_PC_KEYBOARD is not set +CONFIG_NET=y +CONFIG_SYSCTL=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_KCORE_ELF=y +CONFIG_BINFMT_ELF=y +CONFIG_KERNEL_ELF=y +# CONFIG_BINFMT_MISC is not set +# CONFIG_HOTPLUG is not set +# CONFIG_PCMCIA is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set +# CONFIG_PPC_RTC is not set +# CONFIG_CMDLINE_BOOL is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Plug and Play configuration +# +# CONFIG_PNP is not set +# CONFIG_ISAPNP is not set +# CONFIG_PNPBIOS is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_XD is not set +# CONFIG_PARIDE is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_INITRD=y + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set +# CONFIG_BLK_DEV_MD is not set +# CONFIG_MD_LINEAR is not set +# CONFIG_MD_RAID0 is not set +# CONFIG_MD_RAID1 is not set +# CONFIG_MD_RAID5 is not set +# CONFIG_MD_MULTIPATH is not set +# CONFIG_BLK_DEV_LVM is not set + +# +# Networking options +# +# CONFIG_PACKET is not set +# CONFIG_NETLINK is not set +# CONFIG_NETFILTER is not set +# CONFIG_FILTER is not set +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +CONFIG_IP_PNP_RARP=y +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_INET_ECN is not set +CONFIG_SYN_COOKIES=y +# CONFIG_IPV6 is not set +# CONFIG_KHTTPD is not set +# CONFIG_ATM is not set + +# +# +# +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# ATA/IDE/MFM/RLL support +# +# CONFIG_IDE is not set +# CONFIG_BLK_DEV_IDE_MODES is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI support +# +# CONFIG_SCSI is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_MACE is not set +# CONFIG_BMAC is not set +# CONFIG_GMAC is not set +CONFIG_OAKNET=y +# CONFIG_SUNLANCE is not set +# CONFIG_SUNBMAC is not set +# CONFIG_SUNQE is not set +# CONFIG_SUNLANCE is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_NET_ISA is not set +# CONFIG_NET_PCI is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_MYRI_SBUS is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_SK98LIN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Old CD-ROM drivers (not SCSI, not IDE) +# +# CONFIG_CD_NO_IDESCSI is not set + +# +# Console drivers +# + +# +# Frame-buffer support +# +# CONFIG_FB is not set + +# +# Input core support +# +# CONFIG_INPUT is not set +# CONFIG_INPUT_KEYBDEV is not set +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set + +# +# Macintosh device drivers +# + +# +# Character devices +# +# CONFIG_VT is not set +CONFIG_SERIAL=y +CONFIG_SERIAL_CONSOLE=y +# CONFIG_SERIAL_EXTENDED is not set +# CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_UNIX98_PTYS is not set + +# +# I2C support +# +CONFIG_I2C=y +# CONFIG_I2C_ALGOBIT is not set +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_CHARDEV is not set +# CONFIG_I2C_PROC is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set + +# +# Joysticks +# +# CONFIG_INPUT_GAMEPORT is not set + +# +# Input core support is needed for gameports +# + +# +# Input core support is needed for joysticks +# +# CONFIG_QIC02_TAPE is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_INTEL_RNG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set +# CONFIG_MWAVE is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set +# CONFIG_ADFS_FS is not set +# CONFIG_ADFS_FS_RW is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_FAT_FS is not set +# CONFIG_MSDOS_FS is not set +# CONFIG_UMSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_CRAMFS is not set +CONFIG_TMPFS=y +# CONFIG_RAMFS is not set +# CONFIG_ISO9660_FS is not set +# CONFIG_JOLIET is not set +# CONFIG_MINIX_FS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_NTFS_FS is not set +# CONFIG_NTFS_RW is not set +# CONFIG_HPFS_FS is not set +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVFS_MOUNT is not set +# CONFIG_DEVFS_DEBUG is not set +# CONFIG_DEVPTS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set +# CONFIG_ROMFS_FS is not set +CONFIG_EXT2_FS=y +# CONFIG_SYSV_FS is not set +# CONFIG_UDF_FS is not set +# CONFIG_UDF_RW is not set +# CONFIG_UFS_FS is not set +# CONFIG_UFS_FS_WRITE is not set + +# +# Network File Systems +# +# CONFIG_CODA_FS is not set +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +CONFIG_ROOT_NFS=y +# CONFIG_NFSD is not set +# CONFIG_NFSD_V3 is not set +CONFIG_SUNRPC=y +CONFIG_LOCKD=y +# CONFIG_SMB_FS is not set +# CONFIG_NCP_FS is not set +# CONFIG_NCPFS_PACKET_SIGNING is not set +# CONFIG_NCPFS_IOCTL_LOCKING is not set +# CONFIG_NCPFS_STRONG is not set +# CONFIG_NCPFS_NFS_NS is not set +# CONFIG_NCPFS_OS2_NS is not set +# CONFIG_NCPFS_SMALLDOS is not set +# CONFIG_NCPFS_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_SMB_NLS is not set +# CONFIG_NLS is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# MPC4xx Driver Options +# +# CONFIG_STB_KB is not set +# CONFIG_SERIAL_SICC is not set + +# +# USB support +# +# CONFIG_USB is not set + +# +# USB Controllers +# +# CONFIG_USB_UHCI is not set +# CONFIG_USB_UHCI_ALT is not set +# CONFIG_USB_OHCI is not set + +# +# USB Device Class drivers +# +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_BLUETOOTH is not set +# CONFIG_USB_STORAGE is not set +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_HP8200e is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set + +# +# USB Human Interface Devices (HID) +# + +# +# Input core support is needed for USB HID +# + +# +# USB Imaging devices +# +# CONFIG_USB_DC2XX is not set +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_SCANNER is not set +# CONFIG_USB_MICROTEK is not set +# CONFIG_USB_HPUSBSCSI is not set + +# +# USB Multimedia devices +# + +# +# Video4Linux support is needed for USB Multimedia device support +# + +# +# USB Network adaptors +# +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_CATC is not set +# CONFIG_USB_CDCETHER is not set +# CONFIG_USB_USBNET is not set + +# +# USB port drivers +# +# CONFIG_USB_USS720 is not set + +# +# USB Serial Converter support +# +# CONFIG_USB_SERIAL is not set +# CONFIG_USB_SERIAL_GENERIC is not set +# CONFIG_USB_SERIAL_BELKIN is not set +# CONFIG_USB_SERIAL_WHITEHEAT is not set +# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set +# CONFIG_USB_SERIAL_EMPEG is not set +# CONFIG_USB_SERIAL_FTDI_SIO is not set +# CONFIG_USB_SERIAL_VISOR is not set +# CONFIG_USB_SERIAL_IR is not set +# CONFIG_USB_SERIAL_EDGEPORT is not set +# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set +# CONFIG_USB_SERIAL_KEYSPAN is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set +# CONFIG_USB_SERIAL_MCT_U232 is not set +# CONFIG_USB_SERIAL_PL2303 is not set +# CONFIG_USB_SERIAL_CYBERJACK is not set +# CONFIG_USB_SERIAL_XIRCOM is not set +# CONFIG_USB_SERIAL_OMNINET is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_RIO500 is not set + +# +# Bluetooth support +# +# CONFIG_BLUEZ is not set + +# +# Kernel hacking +# +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_KGDB is not set +# CONFIG_XMON is not set +# CONFIG_BDI_SWITCH is not set +# CONFIG_DEBUG_TEXT is not set diff --git a/arch/ppc/configs/rpxcllf_defconfig b/arch/ppc/configs/rpxcllf_defconfig index 2629adf57550..20b62b250d1b 100644 --- a/arch/ppc/configs/rpxcllf_defconfig +++ b/arch/ppc/configs/rpxcllf_defconfig @@ -23,7 +23,6 @@ CONFIG_PPC32=y # CONFIG_6xx is not set # CONFIG_4xx is not set # CONFIG_POWER3 is not set -# CONFIG_POWER4 is not set CONFIG_8xx=y # CONFIG_PPC_STD_MMU is not set CONFIG_SERIAL_CONSOLE=y diff --git a/arch/ppc/configs/rpxlite_defconfig b/arch/ppc/configs/rpxlite_defconfig index 537770195b5d..218ce15f43cd 100644 --- a/arch/ppc/configs/rpxlite_defconfig +++ b/arch/ppc/configs/rpxlite_defconfig @@ -23,7 +23,6 @@ CONFIG_PPC32=y # CONFIG_6xx is not set # CONFIG_4xx is not set # CONFIG_POWER3 is not set -# CONFIG_POWER4 is not set CONFIG_8xx=y # CONFIG_PPC_STD_MMU is not set CONFIG_SERIAL_CONSOLE=y diff --git a/arch/ppc/configs/sandpoint_defconfig b/arch/ppc/configs/sandpoint_defconfig new file mode 100644 index 000000000000..4e30adf720e6 --- /dev/null +++ b/arch/ppc/configs/sandpoint_defconfig @@ -0,0 +1,655 @@ +# +# Automatically generated make config: don't edit +# +# CONFIG_UID16 is not set +# CONFIG_RWSEM_GENERIC_SPINLOCK is not set +CONFIG_RWSEM_XCHGADD_ALGORITHM=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODVERSIONS=y +CONFIG_KMOD=y + +# +# Platform support +# +CONFIG_PPC=y +CONFIG_PPC32=y +CONFIG_6xx=y +# CONFIG_4xx is not set +# CONFIG_POWER3 is not set +# CONFIG_8xx is not set +# CONFIG_PPC_ISERIES is not set +# CONFIG_8260 is not set +CONFIG_PPC_STD_MMU=y +# CONFIG_ALL_PPC is not set +# CONFIG_APUS is not set +# CONFIG_SPRUCE is not set +# CONFIG_PCORE is not set +# CONFIG_POWERPMC250 is not set +# CONFIG_MENF1 is not set +# CONFIG_LOPEC is not set +# CONFIG_MCPN765 is not set +# CONFIG_MVME5100 is not set +# CONFIG_PRPMC750 is not set +# CONFIG_PRPMC800 is not set +CONFIG_SANDPOINT=y +# CONFIG_ADIR is not set +# CONFIG_K2 is not set +# CONFIG_GEMINI is not set +# CONFIG_WILLOW is not set +# CONFIG_ZX4500 is not set +# CONFIG_MPC10X_STORE_GATHERING is not set +CONFIG_SANDPOINT_X3=y +CONFIG_EPIC_SERIAL_MODE=y +# CONFIG_SMP is not set +CONFIG_ALTIVEC=y +# CONFIG_TAU is not set + +# +# General setup +# +# CONFIG_HIGHMEM is not set +# CONFIG_ISA is not set +# CONFIG_EISA is not set +# CONFIG_SBUS is not set +# CONFIG_MCA is not set +CONFIG_PCI=y +CONFIG_NET=y +CONFIG_SYSCTL=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_KCORE_ELF=y +CONFIG_BINFMT_ELF=y +CONFIG_KERNEL_ELF=y +CONFIG_BINFMT_MISC=y +# CONFIG_PCI_NAMES is not set +# CONFIG_HOTPLUG is not set +# CONFIG_PCMCIA is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set +CONFIG_PPC_RTC=y +# CONFIG_CMDLINE_BOOL is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Plug and Play configuration +# +# CONFIG_PNP is not set +# CONFIG_ISAPNP is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_XD is not set +# CONFIG_PARIDE is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_INITRD=y + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set +# CONFIG_BLK_DEV_MD is not set +# CONFIG_MD_LINEAR is not set +# CONFIG_MD_RAID0 is not set +# CONFIG_MD_RAID1 is not set +# CONFIG_MD_RAID5 is not set +# CONFIG_MD_MULTIPATH is not set +# CONFIG_BLK_DEV_LVM is not set + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_NETLINK=y +# CONFIG_RTNETLINK is not set +# CONFIG_NETLINK_DEV is not set +# CONFIG_NETFILTER is not set +# CONFIG_FILTER is not set +CONFIG_UNIX=y +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_IPV6 is not set +# CONFIG_KHTTPD is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set + +# +# +# +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# ATA/IDE/MFM/RLL support +# +CONFIG_IDE=y + +# +# IDE, ATA and ATAPI Block devices +# +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_HD_IDE is not set +# CONFIG_BLK_DEV_HD is not set +CONFIG_BLK_DEV_IDEDISK=y +# CONFIG_IDEDISK_MULTI_MODE is not set +# CONFIG_BLK_DEV_IDEDISK_VENDOR is not set +# CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set +# CONFIG_BLK_DEV_IDEDISK_IBM is not set +# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set +# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set +# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set +# CONFIG_BLK_DEV_IDEDISK_WD is not set +# CONFIG_BLK_DEV_COMMERIAL is not set +# CONFIG_BLK_DEV_TIVO is not set +# CONFIG_BLK_DEV_IDECS is not set +CONFIG_BLK_DEV_IDECD=y +# CONFIG_BLK_DEV_IDETAPE is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set +# CONFIG_BLK_DEV_IDESCSI is not set + +# +# IDE chipset support/bugfixes +# +# CONFIG_BLK_DEV_CMD640 is not set +# CONFIG_BLK_DEV_CMD640_ENHANCED is not set +# CONFIG_BLK_DEV_ISAPNP is not set +# CONFIG_BLK_DEV_RZ1000 is not set +CONFIG_BLK_DEV_IDEPCI=y +CONFIG_IDEPCI_SHARE_IRQ=y +CONFIG_BLK_DEV_IDEDMA_PCI=y +CONFIG_BLK_DEV_ADMA=y +# CONFIG_BLK_DEV_OFFBOARD is not set +# CONFIG_IDEDMA_PCI_AUTO is not set +CONFIG_BLK_DEV_IDEDMA=y +# CONFIG_IDEDMA_PCI_WIP is not set +# CONFIG_IDEDMA_NEW_DRIVE_LISTINGS is not set +# CONFIG_BLK_DEV_AEC62XX is not set +# CONFIG_AEC62XX_TUNING is not set +# CONFIG_BLK_DEV_ALI15X3 is not set +# CONFIG_WDC_ALI15X3 is not set +# CONFIG_BLK_DEV_AMD74XX is not set +# CONFIG_AMD74XX_OVERRIDE is not set +# CONFIG_BLK_DEV_CMD64X is not set +# CONFIG_BLK_DEV_CY82C693 is not set +# CONFIG_BLK_DEV_CS5530 is not set +# CONFIG_BLK_DEV_HPT34X is not set +# CONFIG_HPT34X_AUTODMA is not set +# CONFIG_BLK_DEV_HPT366 is not set +# CONFIG_BLK_DEV_NS87415 is not set +# CONFIG_BLK_DEV_OPTI621 is not set +# CONFIG_BLK_DEV_PDC202XX is not set +# CONFIG_PDC202XX_BURST is not set +# CONFIG_PDC202XX_FORCE is not set +# CONFIG_BLK_DEV_SVWKS is not set +# CONFIG_BLK_DEV_SIS5513 is not set +# CONFIG_BLK_DEV_SLC90E66 is not set +# CONFIG_BLK_DEV_TRM290 is not set +# CONFIG_BLK_DEV_VIA82CXXX is not set +CONFIG_BLK_DEV_SL82C105=y +# CONFIG_IDE_CHIPSETS is not set +# CONFIG_IDEDMA_AUTO is not set +# CONFIG_IDEDMA_IVB is not set +# CONFIG_DMA_NONPCI is not set +CONFIG_BLK_DEV_IDE_MODES=y +# CONFIG_BLK_DEV_ATARAID is not set +# CONFIG_BLK_DEV_ATARAID_PDC is not set +# CONFIG_BLK_DEV_ATARAID_HPT is not set + +# +# SCSI support +# +# CONFIG_SCSI is not set + +# +# IEEE 1394 (FireWire) support (EXPERIMENTAL) +# +# CONFIG_IEEE1394 is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_MACE is not set +# CONFIG_BMAC is not set +# CONFIG_GMAC is not set +# CONFIG_SUNLANCE is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNBMAC is not set +# CONFIG_SUNQE is not set +# CONFIG_SUNLANCE is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_HP100 is not set +# CONFIG_NET_ISA is not set +CONFIG_NET_PCI=y +# CONFIG_PCNET32 is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_APRICOT is not set +# CONFIG_CS89x0 is not set +CONFIG_TULIP=y +# CONFIG_TULIP_MWI is not set +# CONFIG_TULIP_MMIO is not set +# CONFIG_DE4X5 is not set +# CONFIG_DGRS is not set +# CONFIG_DM9102 is not set +CONFIG_EEPRO100=y +# CONFIG_LNE390 is not set +# CONFIG_FEALNX is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_NE3210 is not set +# CONFIG_ES3210 is not set +# CONFIG_8139CP is not set +# CONFIG_8139TOO is not set +# CONFIG_8139TOO_PIO is not set +# CONFIG_8139TOO_TUNE_TWISTER is not set +# CONFIG_8139TOO_8129 is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_TLAN is not set +# CONFIG_VIA_RHINE is not set +# CONFIG_WINBOND_840 is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_MYRI_SBUS is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_SK98LIN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Old CD-ROM drivers (not SCSI, not IDE) +# +# CONFIG_CD_NO_IDESCSI is not set + +# +# Console drivers +# +# CONFIG_VGA_CONSOLE is not set + +# +# Frame-buffer support +# +# CONFIG_FB is not set + +# +# Input core support +# +# CONFIG_INPUT is not set +# CONFIG_INPUT_KEYBDEV is not set +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set + +# +# Macintosh device drivers +# + +# +# Character devices +# +# CONFIG_VT is not set +CONFIG_SERIAL=y +CONFIG_SERIAL_CONSOLE=y +# CONFIG_SERIAL_EXTENDED is not set +# CONFIG_SERIAL_NONSTANDARD is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set + +# +# Joysticks +# +# CONFIG_INPUT_GAMEPORT is not set + +# +# Input core support is needed for gameports +# + +# +# Input core support is needed for joysticks +# +# CONFIG_QIC02_TAPE is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_INTEL_RNG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set +# CONFIG_ADFS_FS is not set +# CONFIG_ADFS_FS_RW is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_FAT_FS is not set +# CONFIG_MSDOS_FS is not set +# CONFIG_UMSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_CRAMFS is not set +CONFIG_TMPFS=y +# CONFIG_RAMFS is not set +CONFIG_ISO9660_FS=y +# CONFIG_JOLIET is not set +# CONFIG_MINIX_FS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_NTFS_FS is not set +# CONFIG_NTFS_RW is not set +# CONFIG_HPFS_FS is not set +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVFS_MOUNT is not set +# CONFIG_DEVFS_DEBUG is not set +CONFIG_DEVPTS_FS=y +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set +# CONFIG_ROMFS_FS is not set +CONFIG_EXT2_FS=y +# CONFIG_SYSV_FS is not set +# CONFIG_UDF_FS is not set +# CONFIG_UDF_RW is not set +# CONFIG_UFS_FS is not set +# CONFIG_UFS_FS_WRITE is not set + +# +# Network File Systems +# +# CONFIG_CODA_FS is not set +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +CONFIG_ROOT_NFS=y +# CONFIG_NFSD is not set +# CONFIG_NFSD_V3 is not set +CONFIG_SUNRPC=y +CONFIG_LOCKD=y +# CONFIG_SMB_FS is not set +# CONFIG_NCP_FS is not set +# CONFIG_NCPFS_PACKET_SIGNING is not set +# CONFIG_NCPFS_IOCTL_LOCKING is not set +# CONFIG_NCPFS_STRONG is not set +# CONFIG_NCPFS_NFS_NS is not set +# CONFIG_NCPFS_OS2_NS is not set +# CONFIG_NCPFS_SMALLDOS is not set +# CONFIG_NCPFS_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_SMB_NLS is not set +# CONFIG_NLS is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB is not set + +# +# USB Controllers +# +# CONFIG_USB_UHCI is not set +# CONFIG_USB_UHCI_ALT is not set +# CONFIG_USB_OHCI is not set + +# +# USB Device Class drivers +# +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_BLUETOOTH is not set +# CONFIG_USB_STORAGE is not set +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_HP8200e is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set + +# +# USB Human Interface Devices (HID) +# + +# +# Input core support is needed for USB HID +# + +# +# USB Imaging devices +# +# CONFIG_USB_DC2XX is not set +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_SCANNER is not set +# CONFIG_USB_MICROTEK is not set +# CONFIG_USB_HPUSBSCSI is not set + +# +# USB Multimedia devices +# + +# +# Video4Linux support is needed for USB Multimedia device support +# + +# +# USB Network adaptors +# +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_CATC is not set +# CONFIG_USB_CDCETHER is not set +# CONFIG_USB_USBNET is not set + +# +# USB port drivers +# +# CONFIG_USB_USS720 is not set + +# +# USB Serial Converter support +# +# CONFIG_USB_SERIAL is not set +# CONFIG_USB_SERIAL_GENERIC is not set +# CONFIG_USB_SERIAL_BELKIN is not set +# CONFIG_USB_SERIAL_WHITEHEAT is not set +# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set +# CONFIG_USB_SERIAL_EMPEG is not set +# CONFIG_USB_SERIAL_FTDI_SIO is not set +# CONFIG_USB_SERIAL_VISOR is not set +# CONFIG_USB_SERIAL_IR is not set +# CONFIG_USB_SERIAL_EDGEPORT is not set +# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set +# CONFIG_USB_SERIAL_KEYSPAN is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set +# CONFIG_USB_SERIAL_MCT_U232 is not set +# CONFIG_USB_SERIAL_PL2303 is not set +# CONFIG_USB_SERIAL_CYBERJACK is not set +# CONFIG_USB_SERIAL_XIRCOM is not set +# CONFIG_USB_SERIAL_OMNINET is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_RIO500 is not set + +# +# Bluetooth support +# +# CONFIG_BLUEZ is not set + +# +# Kernel hacking +# +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_KGDB is not set +# CONFIG_XMON is not set +# CONFIG_BDI_SWITCH is not set +# CONFIG_DEBUG_TEXT is not set diff --git a/arch/ppc/configs/spruce_defconfig b/arch/ppc/configs/spruce_defconfig new file mode 100644 index 000000000000..5c4da43e6797 --- /dev/null +++ b/arch/ppc/configs/spruce_defconfig @@ -0,0 +1,531 @@ +# +# Automatically generated by make menuconfig: don't edit +# +# CONFIG_UID16 is not set +# CONFIG_RWSEM_GENERIC_SPINLOCK is not set +CONFIG_RWSEM_XCHGADD_ALGORITHM=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODVERSIONS is not set +CONFIG_KMOD=y + +# +# Platform support +# +CONFIG_PPC=y +CONFIG_PPC32=y +CONFIG_6xx=y +# CONFIG_4xx is not set +# CONFIG_POWER3 is not set +# CONFIG_8xx is not set +# CONFIG_PPC_ISERIES is not set +# CONFIG_8260 is not set +CONFIG_PPC_STD_MMU=y +# CONFIG_ALL_PPC is not set +# CONFIG_APUS is not set +CONFIG_SPRUCE=y +# CONFIG_PCORE is not set +# CONFIG_POWERPMC250 is not set +# CONFIG_MENF1 is not set +# CONFIG_LOPEC is not set +# CONFIG_MCPN765 is not set +# CONFIG_MVME5100 is not set +# CONFIG_PRPMC750 is not set +# CONFIG_PRPMC800 is not set +# CONFIG_SANDPOINT is not set +# CONFIG_ADIR is not set +# CONFIG_K2 is not set +# CONFIG_GEMINI is not set +# CONFIG_WILLOW is not set +# CONFIG_ZX4500 is not set +# CONFIG_SPRUCE_BAUD_33M is not set +# CONFIG_SMP is not set +# CONFIG_ALTIVEC is not set +# CONFIG_TAU is not set + +# +# General setup +# +# CONFIG_HIGHMEM is not set +# CONFIG_ISA is not set +# CONFIG_EISA is not set +# CONFIG_SBUS is not set +# CONFIG_MCA is not set +CONFIG_PCI=y +CONFIG_NET=y +CONFIG_SYSCTL=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_KCORE_ELF=y +CONFIG_BINFMT_ELF=y +CONFIG_KERNEL_ELF=y +# CONFIG_BINFMT_MISC is not set +# CONFIG_PCI_NAMES is not set +# CONFIG_HOTPLUG is not set +# CONFIG_PCMCIA is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set +CONFIG_PPC_RTC=y +CONFIG_CMDLINE_BOOL=y +CONFIG_CMDLINE="ip=on" + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Plug and Play configuration +# +# CONFIG_PNP is not set +# CONFIG_ISAPNP is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_XD is not set +# CONFIG_PARIDE is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_BLK_DEV_INITRD is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set +# CONFIG_BLK_DEV_MD is not set +# CONFIG_MD_LINEAR is not set +# CONFIG_MD_RAID0 is not set +# CONFIG_MD_RAID1 is not set +# CONFIG_MD_RAID5 is not set +# CONFIG_MD_MULTIPATH is not set +# CONFIG_BLK_DEV_LVM is not set + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_NETLINK=y +# CONFIG_RTNETLINK is not set +# CONFIG_NETLINK_DEV is not set +# CONFIG_NETFILTER is not set +# CONFIG_FILTER is not set +CONFIG_UNIX=y +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +# CONFIG_IP_PNP_BOOTP is not set +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_IPV6 is not set +# CONFIG_KHTTPD is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# ATA/IDE/MFM/RLL support +# +# CONFIG_IDE is not set +# CONFIG_BLK_DEV_IDE_MODES is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI support +# +# CONFIG_SCSI is not set + +# +# IEEE 1394 (FireWire) support (EXPERIMENTAL) +# +# CONFIG_IEEE1394 is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_MACE is not set +# CONFIG_BMAC is not set +# CONFIG_GMAC is not set +# CONFIG_SUNLANCE is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNBMAC is not set +# CONFIG_SUNQE is not set +# CONFIG_SUNLANCE is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_HP100 is not set +# CONFIG_NET_ISA is not set +CONFIG_NET_PCI=y +CONFIG_PCNET32=y +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_APRICOT is not set +# CONFIG_CS89x0 is not set +# CONFIG_TULIP is not set +# CONFIG_DE4X5 is not set +# CONFIG_DGRS is not set +# CONFIG_DM9102 is not set +# CONFIG_EEPRO100 is not set +# CONFIG_LNE390 is not set +# CONFIG_FEALNX is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_NE3210 is not set +# CONFIG_ES3210 is not set +# CONFIG_8139CP is not set +# CONFIG_8139TOO is not set +# CONFIG_8139TOO_PIO is not set +# CONFIG_8139TOO_TUNE_TWISTER is not set +# CONFIG_8139TOO_8129 is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_TLAN is not set +# CONFIG_VIA_RHINE is not set +# CONFIG_WINBOND_840 is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_MYRI_SBUS is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_SK98LIN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Old CD-ROM drivers (not SCSI, not IDE) +# +# CONFIG_CD_NO_IDESCSI is not set + +# +# Console drivers +# +# CONFIG_VGA_CONSOLE is not set + +# +# Frame-buffer support +# +# CONFIG_FB is not set + +# +# Input core support +# +# CONFIG_INPUT is not set +# CONFIG_INPUT_KEYBDEV is not set +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set + +# +# Macintosh device drivers +# + +# +# Character devices +# +# CONFIG_VT is not set +CONFIG_SERIAL=y +CONFIG_SERIAL_CONSOLE=y +# CONFIG_SERIAL_EXTENDED is not set +# CONFIG_SERIAL_NONSTANDARD is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +CONFIG_MOUSE=y +CONFIG_PSMOUSE=y +# CONFIG_82C710_MOUSE is not set +# CONFIG_PC110_PAD is not set + +# +# Joysticks +# +# CONFIG_INPUT_GAMEPORT is not set +# CONFIG_QIC02_TAPE is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_INTEL_RNG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set +# CONFIG_ADFS_FS is not set +# CONFIG_ADFS_FS_RW is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_FAT_FS is not set +# CONFIG_MSDOS_FS is not set +# CONFIG_UMSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_TMPFS is not set +# CONFIG_RAMFS is not set +CONFIG_ISO9660_FS=y +# CONFIG_JOLIET is not set +# CONFIG_ZISOFS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_NTFS_FS is not set +# CONFIG_NTFS_RW is not set +# CONFIG_HPFS_FS is not set +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVFS_MOUNT is not set +# CONFIG_DEVFS_DEBUG is not set +CONFIG_DEVPTS_FS=y +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set +# CONFIG_ROMFS_FS is not set +CONFIG_EXT2_FS=y +# CONFIG_SYSV_FS is not set +# CONFIG_UDF_FS is not set +# CONFIG_UDF_RW is not set +# CONFIG_UFS_FS is not set +# CONFIG_UFS_FS_WRITE is not set + +# +# Network File Systems +# +# CONFIG_CODA_FS is not set +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +CONFIG_ROOT_NFS=y +# CONFIG_NFSD is not set +# CONFIG_NFSD_V3 is not set +CONFIG_SUNRPC=y +CONFIG_LOCKD=y +# CONFIG_SMB_FS is not set +# CONFIG_NCP_FS is not set +# CONFIG_NCPFS_PACKET_SIGNING is not set +# CONFIG_NCPFS_IOCTL_LOCKING is not set +# CONFIG_NCPFS_STRONG is not set +# CONFIG_NCPFS_NFS_NS is not set +# CONFIG_NCPFS_OS2_NS is not set +# CONFIG_NCPFS_SMALLDOS is not set +# CONFIG_NCPFS_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set +# CONFIG_ZISOFS_FS is not set +# CONFIG_ZLIB_FS_INFLATE is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_SMB_NLS is not set +# CONFIG_NLS is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB is not set +# CONFIG_USB_UHCI is not set +# CONFIG_USB_UHCI_ALT is not set +# CONFIG_USB_OHCI is not set +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_BLUETOOTH is not set +# CONFIG_USB_STORAGE is not set +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_HP8200e is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set +# CONFIG_USB_DC2XX is not set +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_SCANNER is not set +# CONFIG_USB_MICROTEK is not set +# CONFIG_USB_HPUSBSCSI is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_CATC is not set +# CONFIG_USB_CDCETHER is not set +# CONFIG_USB_USBNET is not set +# CONFIG_USB_USS720 is not set + +# +# USB Serial Converter support +# +# CONFIG_USB_SERIAL is not set +# CONFIG_USB_SERIAL_GENERIC is not set +# CONFIG_USB_SERIAL_BELKIN is not set +# CONFIG_USB_SERIAL_WHITEHEAT is not set +# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set +# CONFIG_USB_SERIAL_EMPEG is not set +# CONFIG_USB_SERIAL_FTDI_SIO is not set +# CONFIG_USB_SERIAL_VISOR is not set +# CONFIG_USB_SERIAL_IR is not set +# CONFIG_USB_SERIAL_EDGEPORT is not set +# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set +# CONFIG_USB_SERIAL_KEYSPAN is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set +# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set +# CONFIG_USB_SERIAL_MCT_U232 is not set +# CONFIG_USB_SERIAL_PL2303 is not set +# CONFIG_USB_SERIAL_CYBERJACK is not set +# CONFIG_USB_SERIAL_XIRCOM is not set +# CONFIG_USB_SERIAL_OMNINET is not set +# CONFIG_USB_RIO500 is not set + +# +# Bluetooth support +# +# CONFIG_BLUEZ is not set + +# +# Kernel hacking +# +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_KGDB is not set +# CONFIG_XMON is not set +# CONFIG_BDI_SWITCH is not set diff --git a/arch/ppc/configs/walnut_defconfig b/arch/ppc/configs/walnut_defconfig index 87a588a713d5..1e3e0aa5f319 100644 --- a/arch/ppc/configs/walnut_defconfig +++ b/arch/ppc/configs/walnut_defconfig @@ -4,6 +4,7 @@ # CONFIG_UID16 is not set # CONFIG_RWSEM_GENERIC_SPINLOCK is not set CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_HAVE_DEC_LOCK=y # # Code maturity level options @@ -25,14 +26,30 @@ CONFIG_PPC32=y # CONFIG_6xx is not set CONFIG_4xx=y # CONFIG_POWER3 is not set -# CONFIG_POWER4 is not set # CONFIG_8xx is not set +# CONFIG_PPC_ISERIES is not set # CONFIG_PPC_STD_MMU is not set +# CONFIG_CEDER is not set +# CONFIG_CPCI405 is not set +# CONFIG_EP405 is not set # CONFIG_OAK is not set +# CONFIG_REDWOOD_4 is not set +# CONFIG_REDWOOD_5 is not set +# CONFIG_TIVO is not set CONFIG_WALNUT=y # CONFIG_ALL_PPC is not set # CONFIG_SMP is not set # CONFIG_MATH_EMULATION is not set +CONFIG_405GP=y +CONFIG_BIOS_FIXUP=y +CONFIG_TREEBOOT=y +CONFIG_IBM405_ERR77=y +CONFIG_IBM_OCP=y +# CONFIG_405_DMA is not set +CONFIG_UART0_TTYS0=y +# CONFIG_UART0_TTYS1 is not set +CONFIG_IBM405_ERR51=y +CONFIG_NOT_COHERENT_CACHE=y # # General setup @@ -42,7 +59,8 @@ CONFIG_WALNUT=y # CONFIG_EISA is not set # CONFIG_SBUS is not set # CONFIG_MCA is not set -# CONFIG_PCI is not set +CONFIG_PCI=y +# CONFIG_PC_KEYBOARD is not set CONFIG_NET=y CONFIG_SYSCTL=y CONFIG_SYSVIPC=y @@ -51,6 +69,7 @@ CONFIG_KCORE_ELF=y CONFIG_BINFMT_ELF=y CONFIG_KERNEL_ELF=y # CONFIG_BINFMT_MISC is not set +# CONFIG_PCI_NAMES is not set # CONFIG_HOTPLUG is not set # CONFIG_PCMCIA is not set @@ -58,6 +77,7 @@ CONFIG_KERNEL_ELF=y # Parallel port support # # CONFIG_PARPORT is not set +CONFIG_PPC_RTC=y # CONFIG_CMDLINE_BOOL is not set # @@ -102,7 +122,7 @@ CONFIG_BLK_DEV_INITRD=y # Networking options # # CONFIG_PACKET is not set -# CONFIG_NETLINK is not set +# CONFIG_NETLINK_DEV is not set # CONFIG_NETFILTER is not set # CONFIG_FILTER is not set CONFIG_UNIX=y @@ -116,6 +136,7 @@ CONFIG_IP_PNP_RARP=y # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set # CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set # CONFIG_INET_ECN is not set CONFIG_SYN_COOKIES=y # CONFIG_IPV6 is not set @@ -128,6 +149,18 @@ CONFIG_SYN_COOKIES=y # # CONFIG_IPX is not set # CONFIG_ATALK is not set + +# +# Appletalk devices +# +# CONFIG_DEV_APPLETALK is not set +# CONFIG_LTPC is not set +# CONFIG_COPS is not set +# CONFIG_COPS_DAYNA is not set +# CONFIG_COPS_TANGENT is not set +# CONFIG_IPDDP is not set +# CONFIG_IPDDP_ENCAP is not set +# CONFIG_IPDDP_DECAP is not set # CONFIG_DECNET is not set # CONFIG_BRIDGE is not set # CONFIG_X25 is not set @@ -157,6 +190,30 @@ CONFIG_SYN_COOKIES=y # CONFIG_SCSI is not set # +# Fusion MPT device support +# +# CONFIG_FUSION is not set +# CONFIG_FUSION_BOOT is not set +# CONFIG_FUSION_ISENSE is not set +# CONFIG_FUSION_CTL is not set +# CONFIG_FUSION_LAN is not set + +# +# IEEE 1394 (FireWire) support (EXPERIMENTAL) +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# +# CONFIG_I2O is not set +# CONFIG_I2O_PCI is not set +# CONFIG_I2O_BLOCK is not set +# CONFIG_I2O_LAN is not set +# CONFIG_I2O_SCSI is not set +# CONFIG_I2O_PROC is not set + +# # Network device support # CONFIG_NETDEVICES=y @@ -169,6 +226,7 @@ CONFIG_NETDEVICES=y # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set # # Ethernet (10 or 100Mbit) @@ -177,7 +235,13 @@ CONFIG_NET_ETHERNET=y # CONFIG_MACE is not set # CONFIG_BMAC is not set # CONFIG_GMAC is not set +CONFIG_IBM_OCP_ENET=y +# CONFIG_IBM_OCP_ENET_ERROR_MSG is not set +CONFIG_IBM_OCP_ENET_RX_BUFF=64 +CONFIG_IBM_OCP_ENET_TX_BUFF=8 +CONFIG_IBM_OCP_ENET_GAP=8 # CONFIG_SUNLANCE is not set +# CONFIG_HAPPYMEAL is not set # CONFIG_SUNBMAC is not set # CONFIG_SUNQE is not set # CONFIG_SUNLANCE is not set @@ -186,6 +250,7 @@ CONFIG_NET_ETHERNET=y # CONFIG_LANCE is not set # CONFIG_NET_VENDOR_SMC is not set # CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_HP100 is not set # CONFIG_NET_ISA is not set # CONFIG_NET_PCI is not set # CONFIG_NET_POCKET is not set @@ -315,6 +380,7 @@ CONFIG_I2C=y # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set +# CONFIG_PPC405_GPIO is not set # # Ftape, the floppy tape device driver @@ -336,11 +402,15 @@ CONFIG_I2C=y # CONFIG_AUTOFS4_FS is not set # CONFIG_REISERFS_FS is not set # CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set # CONFIG_ADFS_FS is not set # CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set # CONFIG_BFS_FS is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_JBD_DEBUG is not set # CONFIG_FAT_FS is not set # CONFIG_MSDOS_FS is not set # CONFIG_UMSDOS_FS is not set @@ -353,6 +423,7 @@ CONFIG_TMPFS=y # CONFIG_RAMFS is not set # CONFIG_ISO9660_FS is not set # CONFIG_JOLIET is not set +# CONFIG_ZISOFS is not set # CONFIG_MINIX_FS is not set # CONFIG_VXFS_FS is not set # CONFIG_NTFS_FS is not set @@ -377,6 +448,7 @@ CONFIG_EXT2_FS=y # Network File Systems # # CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set CONFIG_NFS_FS=y # CONFIG_NFS_V3 is not set CONFIG_ROOT_NFS=y @@ -394,6 +466,8 @@ CONFIG_LOCKD=y # CONFIG_NCPFS_SMALLDOS is not set # CONFIG_NCPFS_NLS is not set # CONFIG_NCPFS_EXTRAS is not set +# CONFIG_ZISOFS_FS is not set +# CONFIG_ZLIB_FS_INFLATE is not set # # Partition Types @@ -409,6 +483,10 @@ CONFIG_MSDOS_PARTITION=y # CONFIG_SOUND is not set # +# MPC4xx Driver Options +# + +# # USB support # # CONFIG_USB is not set @@ -487,6 +565,7 @@ CONFIG_MSDOS_PARTITION=y # CONFIG_USB_SERIAL_EMPEG is not set # CONFIG_USB_SERIAL_FTDI_SIO is not set # CONFIG_USB_SERIAL_VISOR is not set +# CONFIG_USB_SERIAL_IPAQ is not set # CONFIG_USB_SERIAL_IR is not set # CONFIG_USB_SERIAL_EDGEPORT is not set # CONFIG_USB_SERIAL_KEYSPAN_PDA is not set @@ -500,6 +579,7 @@ CONFIG_MSDOS_PARTITION=y # CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set # CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set # CONFIG_USB_SERIAL_MCT_U232 is not set +# CONFIG_USB_SERIAL_KLSI is not set # CONFIG_USB_SERIAL_PL2303 is not set # CONFIG_USB_SERIAL_CYBERJACK is not set # CONFIG_USB_SERIAL_XIRCOM is not set @@ -521,3 +601,5 @@ CONFIG_MSDOS_PARTITION=y # CONFIG_MAGIC_SYSRQ is not set # CONFIG_KGDB is not set # CONFIG_XMON is not set +# CONFIG_BDI_SWITCH is not set +# CONFIG_SERIAL_TEXT_DEBUG is not set diff --git a/arch/ppc/configs/zx4500_defconfig b/arch/ppc/configs/zx4500_defconfig new file mode 100644 index 000000000000..8f3c42158211 --- /dev/null +++ b/arch/ppc/configs/zx4500_defconfig @@ -0,0 +1,479 @@ +# +# Automatically generated make config: don't edit +# +# CONFIG_UID16 is not set +# CONFIG_RWSEM_GENERIC_SPINLOCK is not set +CONFIG_RWSEM_XCHGADD_ALGORITHM=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODVERSIONS=y +CONFIG_KMOD=y + +# +# Platform support +# +CONFIG_PPC=y +CONFIG_PPC32=y +CONFIG_6xx=y +# CONFIG_4xx is not set +# CONFIG_POWER3 is not set +# CONFIG_8xx is not set +# CONFIG_PPC_ISERIES is not set +# CONFIG_8260 is not set +CONFIG_PPC_STD_MMU=y +# CONFIG_ALL_PPC is not set +# CONFIG_APUS is not set +# CONFIG_SPRUCE is not set +# CONFIG_PCORE is not set +# CONFIG_MENF1 is not set +# CONFIG_MCPN765 is not set +# CONFIG_MVME5100 is not set +# CONFIG_PRPMC750 is not set +# CONFIG_SANDPOINT is not set +# CONFIG_K2 is not set +# CONFIG_GEMINI is not set +CONFIG_ZX4500=y +# CONFIG_MPC10X_STORE_GATHERING is not set +# CONFIG_PPC601_SYNC_FIX is not set +# CONFIG_SMP is not set +# CONFIG_ALTIVEC is not set +# CONFIG_TAU is not set + +# +# General setup +# +# CONFIG_HIGHMEM is not set +# CONFIG_ISA is not set +# CONFIG_EISA is not set +# CONFIG_SBUS is not set +# CONFIG_MCA is not set +CONFIG_PCI=y +CONFIG_NET=y +CONFIG_SYSCTL=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_KCORE_ELF=y +CONFIG_BINFMT_ELF=y +CONFIG_KERNEL_ELF=y +CONFIG_BINFMT_MISC=y +CONFIG_PCI_NAMES=y +# CONFIG_HOTPLUG is not set +# CONFIG_PCMCIA is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set +# CONFIG_PPC_RTC is not set +# CONFIG_CMDLINE_BOOL is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Plug and Play configuration +# +# CONFIG_PNP is not set +# CONFIG_ISAPNP is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_VIODASD is not set +# CONFIG_BLK_DEV_XD is not set +# CONFIG_PARIDE is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_NBD=y +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=16384 +CONFIG_BLK_DEV_INITRD=y + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set +# CONFIG_BLK_DEV_MD is not set +# CONFIG_MD_LINEAR is not set +# CONFIG_MD_RAID0 is not set +# CONFIG_MD_RAID1 is not set +# CONFIG_MD_RAID5 is not set +# CONFIG_BLK_DEV_LVM is not set + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_NETLINK=y +# CONFIG_RTNETLINK is not set +# CONFIG_NETLINK_DEV is not set +# CONFIG_NETFILTER is not set +# CONFIG_FILTER is not set +CONFIG_UNIX=y +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_INET_ECN is not set +CONFIG_SYN_COOKIES=y +# CONFIG_IPV6 is not set +# CONFIG_KHTTPD is not set +# CONFIG_ATM is not set + +# +# +# +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# ATA/IDE/MFM/RLL support +# +# CONFIG_IDE is not set +# CONFIG_BLK_DEV_IDE_MODES is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI support +# +# CONFIG_SCSI is not set + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_ARM_AM79C961A is not set +# CONFIG_MACE is not set +# CONFIG_BMAC is not set +# CONFIG_GMAC is not set +# CONFIG_NCR885E is not set +# CONFIG_OAKNET is not set +# CONFIG_SUNLANCE is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNBMAC is not set +# CONFIG_SUNQE is not set +# CONFIG_SUNLANCE is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_HP100 is not set +# CONFIG_NET_ISA is not set +CONFIG_NET_PCI=y +# CONFIG_PCNET32 is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_APRICOT is not set +# CONFIG_CS89x0 is not set +CONFIG_TULIP=y +# CONFIG_TULIP_MWI is not set +# CONFIG_TULIP_MMIO is not set +# CONFIG_DE4X5 is not set +# CONFIG_DGRS is not set +# CONFIG_DM9102 is not set +CONFIG_EEPRO100=y +# CONFIG_LNE390 is not set +# CONFIG_FEALNX is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_NE3210 is not set +# CONFIG_ES3210 is not set +# CONFIG_8139TOO is not set +# CONFIG_8139TOO_PIO is not set +# CONFIG_8139TOO_TUNE_TWISTER is not set +# CONFIG_8139TOO_8129 is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_TLAN is not set +# CONFIG_VIA_RHINE is not set +# CONFIG_WINBOND_840 is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_ACENIC_OMIT_TIGON_I is not set +# CONFIG_DL2K is not set +# CONFIG_MYRI_SBUS is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_SK98LIN is not set +# CONFIG_VETH is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Old CD-ROM drivers (not SCSI, not IDE) +# +# CONFIG_CD_NO_IDESCSI is not set + +# +# Console drivers +# +# CONFIG_VGA_CONSOLE is not set + +# +# Frame-buffer support +# +# CONFIG_FB is not set + +# +# Input core support +# +# CONFIG_INPUT is not set + +# +# Macintosh device drivers +# + +# +# Character devices +# +# CONFIG_VT is not set +CONFIG_SERIAL=y +CONFIG_SERIAL_CONSOLE=y +CONFIG_SERIAL_EXTENDED=y +# CONFIG_SERIAL_MANY_PORTS is not set +CONFIG_SERIAL_SHARE_IRQ=y +CONFIG_SERIAL_DETECT_IRQ=y +# CONFIG_SERIAL_MULTIPORT is not set +# CONFIG_HUB6 is not set +# CONFIG_SERIAL_NONSTANDARD is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 +# CONFIG_VIOCONS is not set + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set + +# +# Joysticks +# +# CONFIG_JOYSTICK is not set + +# +# Input core support is needed for joysticks +# +# CONFIG_QIC02_TAPE is not set +# CONFIG_VIOTAPE is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_INTEL_RNG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set +# CONFIG_SONYPI is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set +# CONFIG_ADFS_FS is not set +# CONFIG_ADFS_FS_RW is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_FAT_FS is not set +# CONFIG_MSDOS_FS is not set +# CONFIG_UMSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_CRAMFS is not set +CONFIG_TMPFS=y +# CONFIG_RAMFS is not set +CONFIG_ISO9660_FS=y +# CONFIG_JOLIET is not set +# CONFIG_MINIX_FS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_NTFS_FS is not set +# CONFIG_NTFS_RW is not set +# CONFIG_HPFS_FS is not set +CONFIG_PROC_FS=y +CONFIG_DEVFS_FS=y +# CONFIG_DEVFS_MOUNT is not set +# CONFIG_DEVFS_DEBUG is not set +CONFIG_DEVPTS_FS=y +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set +# CONFIG_ROMFS_FS is not set +CONFIG_EXT2_FS=y +# CONFIG_SYSV_FS is not set +# CONFIG_UDF_FS is not set +# CONFIG_UDF_RW is not set +# CONFIG_UFS_FS is not set +# CONFIG_UFS_FS_WRITE is not set + +# +# Network File Systems +# +# CONFIG_CODA_FS is not set +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +CONFIG_ROOT_NFS=y +CONFIG_NFSD=y +# CONFIG_NFSD_V3 is not set +CONFIG_SUNRPC=y +CONFIG_LOCKD=y +# CONFIG_SMB_FS is not set +# CONFIG_NCP_FS is not set +# CONFIG_NCPFS_PACKET_SIGNING is not set +# CONFIG_NCPFS_IOCTL_LOCKING is not set +# CONFIG_NCPFS_STRONG is not set +# CONFIG_NCPFS_NFS_NS is not set +# CONFIG_NCPFS_OS2_NS is not set +# CONFIG_NCPFS_SMALLDOS is not set +# CONFIG_NCPFS_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_SMB_NLS is not set +# CONFIG_NLS is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB is not set + +# +# Bluetooth support +# +# CONFIG_BLUEZ is not set + +# +# Kernel hacking +# +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_KGDB is not set +# CONFIG_XMON is not set +# CONFIG_DEBUG_TEXT is not set diff --git a/arch/ppc/defconfig b/arch/ppc/defconfig index 9d8bb2ccbd93..71e317246cdf 100644 --- a/arch/ppc/defconfig +++ b/arch/ppc/defconfig @@ -4,6 +4,7 @@ # CONFIG_UID16 is not set # CONFIG_RWSEM_GENERIC_SPINLOCK is not set CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_HAVE_DEC_LOCK=y # # Code maturity level options @@ -25,13 +26,27 @@ CONFIG_PPC32=y CONFIG_6xx=y # CONFIG_4xx is not set # CONFIG_POWER3 is not set -# CONFIG_POWER4 is not set # CONFIG_8xx is not set +# CONFIG_PPC_ISERIES is not set # CONFIG_8260 is not set CONFIG_PPC_STD_MMU=y CONFIG_ALL_PPC=y # CONFIG_APUS is not set +# CONFIG_SPRUCE is not set +# CONFIG_PCORE is not set +# CONFIG_POWERPMC250 is not set +# CONFIG_MENF1 is not set +# CONFIG_LOPEC is not set +# CONFIG_MCPN765 is not set +# CONFIG_MVME5100 is not set +# CONFIG_PRPMC750 is not set +# CONFIG_PRPMC800 is not set +# CONFIG_SANDPOINT is not set +# CONFIG_ADIR is not set +# CONFIG_K2 is not set # CONFIG_GEMINI is not set +# CONFIG_WILLOW is not set +# CONFIG_ZX4500 is not set # CONFIG_SMP is not set CONFIG_ALTIVEC=y CONFIG_TAU=y @@ -71,7 +86,6 @@ CONFIG_PPC_RTC=y CONFIG_PPC601_SYNC_FIX=y CONFIG_PROC_DEVICETREE=y CONFIG_PPC_RTAS=y -CONFIG_BOOTX_TEXT=y CONFIG_PREP_RESIDUAL=y CONFIG_CMDLINE_BOOL=y CONFIG_CMDLINE="console=ttyS0,9600 console=tty0 root=/dev/sda2" @@ -119,8 +133,6 @@ CONFIG_BLK_DEV_INITRD=y # CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set -CONFIG_NETLINK=y -# CONFIG_RTNETLINK is not set # CONFIG_NETLINK_DEV is not set CONFIG_NETFILTER=y # CONFIG_NETFILTER_DEBUG is not set @@ -133,6 +145,7 @@ CONFIG_IP_MULTICAST=y # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set # CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set # CONFIG_INET_ECN is not set CONFIG_SYN_COOKIES=y @@ -343,15 +356,11 @@ CONFIG_SCSI_ADVANSYS=m # CONFIG_SCSI_INIA100 is not set # CONFIG_SCSI_NCR53C406A is not set # CONFIG_SCSI_NCR53C7xx is not set -CONFIG_SCSI_NCR53C8XX=y -CONFIG_SCSI_SYM53C8XX=y -CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=8 -CONFIG_SCSI_NCR53C8XX_MAX_TAGS=32 -CONFIG_SCSI_NCR53C8XX_SYNC=20 -# CONFIG_SCSI_NCR53C8XX_PROFILE is not set -# CONFIG_SCSI_NCR53C8XX_IOMAPPED is not set -# CONFIG_SCSI_NCR53C8XX_PQS_PDS is not set -# CONFIG_SCSI_NCR53C8XX_SYMBIOS_COMPAT is not set +CONFIG_SCSI_SYM53C8XX_2=y +CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=0 +CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 +CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 +# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set # CONFIG_SCSI_PAS16 is not set # CONFIG_SCSI_PCI2000 is not set # CONFIG_SCSI_PCI2220I is not set @@ -388,7 +397,9 @@ CONFIG_NETDEVICES=y # # Appletalk devices # -# CONFIG_APPLETALK is not set +# CONFIG_LTPC is not set +# CONFIG_COPS is not set +# CONFIG_IPDDP is not set # CONFIG_DUMMY is not set # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set @@ -443,6 +454,7 @@ CONFIG_DE4X5=m # CONFIG_SUNDANCE is not set # CONFIG_TLAN is not set # CONFIG_VIA_RHINE is not set +# CONFIG_VIA_RHINE_MMIO is not set # CONFIG_WINBOND_840 is not set # CONFIG_NET_POCKET is not set @@ -544,6 +556,7 @@ CONFIG_FB_MATROX=y CONFIG_FB_MATROX_MILLENIUM=y CONFIG_FB_MATROX_MYSTIQUE=y # CONFIG_FB_MATROX_G100 is not set +# CONFIG_FB_MATROX_I2C is not set # CONFIG_FB_MATROX_G450 is not set # CONFIG_FB_MATROX_MULTIHEAD is not set CONFIG_FB_ATY=y @@ -587,8 +600,10 @@ CONFIG_INPUT_EVDEV=y # CONFIG_ADB_CUDA=y CONFIG_ADB_PMU=y -# CONFIG_PMAC_PBOOK is not set -# CONFIG_PMAC_BACKLIGHT is not set +CONFIG_PMAC_PBOOK=y +CONFIG_PM=y +CONFIG_PMAC_APM_EMU=y +CONFIG_PMAC_BACKLIGHT=y # CONFIG_MAC_FLOPPY is not set CONFIG_MAC_SERIAL=m CONFIG_ADB=y @@ -597,6 +612,7 @@ CONFIG_INPUT_ADBHID=y CONFIG_MAC_ADBKEYCODES=y CONFIG_MAC_EMUMOUSEBTN=y CONFIG_MAC_HID=y +# CONFIG_ANSLCD is not set # # Character devices @@ -612,7 +628,12 @@ CONFIG_UNIX98_PTY_COUNT=256 # # I2C support # -# CONFIG_I2C is not set +CONFIG_I2C=m +# CONFIG_I2C_ALGOBIT is not set +# CONFIG_I2C_ALGOPCF is not set +CONFIG_I2C_KEYWEST=m +CONFIG_I2C_CHARDEV=m +CONFIG_I2C_PROC=m # # Mice @@ -693,11 +714,15 @@ CONFIG_NVRAM=y # CONFIG_AUTOFS4_FS is not set # CONFIG_REISERFS_FS is not set # CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set # CONFIG_ADFS_FS is not set # CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set CONFIG_HFS_FS=m # CONFIG_BFS_FS is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_JBD_DEBUG is not set CONFIG_FAT_FS=m CONFIG_MSDOS_FS=m # CONFIG_UMSDOS_FS is not set @@ -710,6 +735,7 @@ CONFIG_TMPFS=y # CONFIG_RAMFS is not set CONFIG_ISO9660_FS=y # CONFIG_JOLIET is not set +# CONFIG_ZISOFS is not set # CONFIG_MINIX_FS is not set # CONFIG_VXFS_FS is not set # CONFIG_NTFS_FS is not set @@ -734,13 +760,15 @@ CONFIG_EXT2_FS=y # Network File Systems # # CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set CONFIG_NFS_FS=y -# CONFIG_NFS_V3 is not set +CONFIG_NFS_V3=y # CONFIG_ROOT_NFS is not set CONFIG_NFSD=y -# CONFIG_NFSD_V3 is not set +CONFIG_NFSD_V3=y CONFIG_SUNRPC=y CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y # CONFIG_SMB_FS is not set # CONFIG_NCP_FS is not set # CONFIG_NCPFS_PACKET_SIGNING is not set @@ -751,6 +779,8 @@ CONFIG_LOCKD=y # CONFIG_NCPFS_SMALLDOS is not set # CONFIG_NCPFS_NLS is not set # CONFIG_NCPFS_EXTRAS is not set +# CONFIG_ZISOFS_FS is not set +# CONFIG_ZLIB_FS_INFLATE is not set # # Partition Types @@ -818,8 +848,10 @@ CONFIG_NLS_ISO8859_1=m # Sound # CONFIG_SOUND=m -CONFIG_DMASOUND_AWACS=m +CONFIG_DMASOUND_PMAC=m CONFIG_DMASOUND=m +CONFIG_I2C=m +CONFIG_I2C_KEYWEST=m # CONFIG_SOUND_BT878 is not set # CONFIG_SOUND_CMPCI is not set # CONFIG_SOUND_EMU10K1 is not set @@ -854,7 +886,6 @@ CONFIG_USB=y CONFIG_USB_DEVICEFS=y # CONFIG_USB_BANDWIDTH is not set # CONFIG_USB_LONG_TIMEOUT is not set -# CONFIG_USB_LARGE_CONFIG is not set # # USB Controllers @@ -868,12 +899,12 @@ CONFIG_USB_OHCI=y # # CONFIG_USB_AUDIO is not set # CONFIG_USB_BLUETOOTH is not set -# CONFIG_USB_STORAGE is not set +CONFIG_USB_STORAGE=m # CONFIG_USB_STORAGE_DEBUG is not set # CONFIG_USB_STORAGE_DATAFAB is not set -# CONFIG_USB_STORAGE_FREECOM is not set +CONFIG_USB_STORAGE_FREECOM=y # CONFIG_USB_STORAGE_ISD200 is not set -# CONFIG_USB_STORAGE_DPCM is not set +CONFIG_USB_STORAGE_DPCM=y # CONFIG_USB_STORAGE_HP8200e is not set # CONFIG_USB_STORAGE_SDDR09 is not set # CONFIG_USB_STORAGE_JUMPSHOT is not set @@ -932,15 +963,15 @@ CONFIG_USB_SERIAL_VISOR=m # CONFIG_USB_SERIAL_IR is not set # CONFIG_USB_SERIAL_EDGEPORT is not set # CONFIG_USB_SERIAL_KEYSPAN_PDA is not set -# CONFIG_USB_SERIAL_KEYSPAN is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set +CONFIG_USB_SERIAL_KEYSPAN=m +CONFIG_USB_SERIAL_KEYSPAN_USA28=y +CONFIG_USB_SERIAL_KEYSPAN_USA28X=y # CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set # CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set +CONFIG_USB_SERIAL_KEYSPAN_USA19=y +CONFIG_USB_SERIAL_KEYSPAN_USA18X=y +CONFIG_USB_SERIAL_KEYSPAN_USA19W=y +CONFIG_USB_SERIAL_KEYSPAN_USA49W=y # CONFIG_USB_SERIAL_MCT_U232 is not set # CONFIG_USB_SERIAL_PL2303 is not set # CONFIG_USB_SERIAL_CYBERJACK is not set @@ -963,3 +994,5 @@ CONFIG_USB_SERIAL_VISOR=m CONFIG_MAGIC_SYSRQ=y # CONFIG_KGDB is not set CONFIG_XMON=y +# CONFIG_BDI_SWITCH is not set +CONFIG_BOOTX_TEXT=y diff --git a/arch/ppc/iSeries/HvCall.c b/arch/ppc/iSeries/HvCall.c new file mode 100644 index 000000000000..9b08087f6f65 --- /dev/null +++ b/arch/ppc/iSeries/HvCall.c @@ -0,0 +1,127 @@ +/* + * HvCall.c + * Copyright (C) 2001 Mike Corrigan IBM Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <linux/stddef.h> +#include <linux/kernel.h> +#include <linux/mm.h> +#include <linux/slab.h> +#include <asm/system.h> +#include <asm/page.h> +#include <asm/iSeries/HvCall.h> +#include <asm/iSeries/HvCallEvent.h> +#ifndef _HVCALLSC_H +#include <asm/iSeries/HvCallSc.h> +#endif +#include <asm/iSeries/LparData.h> + +#ifndef _HVTYPES_H +#include <asm/iSeries/HvTypes.h> +#endif + +//===================================================================== +// Note that this call takes at MOST one page worth of data +int HvCall_readLogBuffer(HvLpIndex lpIndex, void *buffer, u64 bufLen) +{ + struct HvLpBufferList *bufList; + u64 bytesLeft = bufLen; + u64 leftThisPage; + u64 curPtr = (unsigned long) buffer; + u64 retVal; + int npages; + int i; + + npages = 0; + while (bytesLeft) + { + npages++; + leftThisPage = ((curPtr & PAGE_MASK) + PAGE_SIZE) - curPtr; + + if (leftThisPage > bytesLeft) + bytesLeft = 0; + else + bytesLeft -= leftThisPage; + + curPtr = (curPtr & PAGE_MASK) + PAGE_SIZE; + } + + if (npages == 0) + return 0; + + bufList = (struct HvLpBufferList *)kmalloc(npages * sizeof(struct HvLpBufferList), GFP_ATOMIC); + bytesLeft = bufLen; + curPtr = (unsigned long) buffer; + for(i=0; i<npages; i++) + { + bufList[i].addr = virt_to_absolute(curPtr); + + leftThisPage = ((curPtr & PAGE_MASK) + PAGE_SIZE) - curPtr; + + if (leftThisPage > bytesLeft) + { + bufList[i].len = bytesLeft; + bytesLeft = 0; + } + else + { + bufList[i].len = leftThisPage; + bytesLeft -= leftThisPage; + } + + curPtr = (curPtr & PAGE_MASK) + PAGE_SIZE; + } + + + retVal = HvCall3(HvCallBaseReadLogBuffer,lpIndex, virt_to_absolute((unsigned long)bufList), bufLen); + + kfree(bufList); + + return (int)retVal; +} + +//===================================================================== +void HvCall_writeLogBuffer(const void *buffer, u64 bufLen) +{ + struct HvLpBufferList bufList; + u64 bytesLeft = bufLen; + u64 leftThisPage; + u64 curPtr = (unsigned long) buffer; + + while (bytesLeft) + { + bufList.addr = virt_to_absolute( curPtr ); + + leftThisPage = ((curPtr & PAGE_MASK) + PAGE_SIZE) - curPtr; + + if (leftThisPage > bytesLeft) + { + bufList.len = bytesLeft; + bytesLeft = 0; + } + else + { + bufList.len = leftThisPage; + bytesLeft -= leftThisPage; + } + + HvCall2(HvCallBaseWriteLogBuffer, virt_to_absolute((unsigned long)&bufList), bufList.len); + + curPtr = (curPtr & PAGE_MASK) + PAGE_SIZE; + } +} + diff --git a/arch/ppc/iSeries/HvLpConfig.c b/arch/ppc/iSeries/HvLpConfig.c new file mode 100644 index 000000000000..d2149a9a047e --- /dev/null +++ b/arch/ppc/iSeries/HvLpConfig.c @@ -0,0 +1,27 @@ +/* + * HvLpConfig.c + * Copyright (C) 2001 Kyle A. Lucke, IBM Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _HVLPCONFIG_H +#include <asm/iSeries/HvLpConfig.h> +#endif + +HvLpIndex HvLpConfig_getLpIndex_outline(void) +{ + return HvLpConfig_getLpIndex(); +} diff --git a/arch/ppc/iSeries/HvLpEvent.c b/arch/ppc/iSeries/HvLpEvent.c new file mode 100644 index 000000000000..dc859e3cd7c2 --- /dev/null +++ b/arch/ppc/iSeries/HvLpEvent.c @@ -0,0 +1,87 @@ +/* + * HvLpEvent.c + * Copyright (C) 2001 Mike Corrigan IBM Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <linux/stddef.h> +#include <linux/kernel.h> +#include <asm/system.h> +#include <asm/iSeries/HvLpEvent.h> +#include <asm/iSeries/HvCallEvent.h> +#include <asm/iSeries/LparData.h> + +// Array of LpEvent handler functions +LpEventHandler lpEventHandler[HvLpEvent_Type_NumTypes]; +unsigned lpEventHandlerPaths[HvLpEvent_Type_NumTypes]; + +// Register a handler for an LpEvent type + +int HvLpEvent_registerHandler( HvLpEvent_Type eventType, LpEventHandler handler ) +{ + int rc = 1; + if ( eventType < HvLpEvent_Type_NumTypes ) { + lpEventHandler[eventType] = handler; + rc = 0; + } + return rc; + +} + +int HvLpEvent_unregisterHandler( HvLpEvent_Type eventType ) +{ + int rc = 1; + if ( eventType < HvLpEvent_Type_NumTypes ) { + if ( !lpEventHandlerPaths[eventType] ) { + lpEventHandler[eventType] = NULL; + rc = 0; + } + } + return rc; +} + +// (lpIndex is the partition index of the target partition. +// needed only for VirtualIo, VirtualLan and SessionMgr. Zero +// indicates to use our partition index - for the other types) +int HvLpEvent_openPath( HvLpEvent_Type eventType, HvLpIndex lpIndex ) +{ + int rc = 1; + if ( eventType < HvLpEvent_Type_NumTypes && + lpEventHandler[eventType] ) { + if ( lpIndex == 0 ) + lpIndex = itLpNaca.xLpIndex; + HvCallEvent_openLpEventPath( lpIndex, eventType ); + ++lpEventHandlerPaths[eventType]; + rc = 0; + } + return rc; +} + +int HvLpEvent_closePath( HvLpEvent_Type eventType, HvLpIndex lpIndex ) +{ + int rc = 1; + if ( eventType < HvLpEvent_Type_NumTypes && + lpEventHandler[eventType] && + lpEventHandlerPaths[eventType] ) { + if ( lpIndex == 0 ) + lpIndex = itLpNaca.xLpIndex; + HvCallEvent_closeLpEventPath( lpIndex, eventType ); + --lpEventHandlerPaths[eventType]; + rc = 0; + } + return rc; +} + diff --git a/arch/ppc/iSeries/ItLpQueue.c b/arch/ppc/iSeries/ItLpQueue.c new file mode 100644 index 000000000000..48e5313c57e8 --- /dev/null +++ b/arch/ppc/iSeries/ItLpQueue.c @@ -0,0 +1,178 @@ +/* + * ItLpQueue.c + * Copyright (C) 2001 Mike Corrigan IBM Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <linux/stddef.h> +#include <linux/kernel.h> +#include <linux/sched.h> +#include <asm/system.h> +#include <asm/iSeries/ItLpQueue.h> +#include <asm/iSeries/HvLpEvent.h> +#include <asm/iSeries/HvCallEvent.h> +#include <asm/iSeries/LparData.h> + +static __inline__ int set_inUse( struct ItLpQueue * lpQueue ) +{ + int t; + u32 * inUseP = &(lpQueue->xInUseWord); + + __asm__ __volatile__("\n\ +1: lwarx %0,0,%2 \n\ + cmpi 0,%0,0 \n\ + li %0,0 \n\ + bne- 2f \n\ + addi %0,%0,1 \n\ + stwcx. %0,0,%2 \n\ + bne- 1b \n\ +2: eieio" + : "=&r" (t), "=m" (lpQueue->xInUseWord) + : "r" (inUseP), "m" (lpQueue->xInUseWord) + : "cc"); + + return t; +} + +static __inline__ void clear_inUse( struct ItLpQueue * lpQueue ) +{ + lpQueue->xInUseWord = 0; +} + +// Array of LpEvent handler functions +extern LpEventHandler lpEventHandler[HvLpEvent_Type_NumTypes]; +unsigned long ItLpQueueInProcess = 0; + +struct HvLpEvent * ItLpQueue_getNextLpEvent( struct ItLpQueue * lpQueue ) +{ + struct HvLpEvent * nextLpEvent = + (struct HvLpEvent *)lpQueue->xSlicCurEventPtr; + if ( nextLpEvent->xFlags.xValid ) { + // Set pointer to next potential event + lpQueue->xSlicCurEventPtr += ((nextLpEvent->xSizeMinus1 + + LpEventAlign ) / + LpEventAlign ) * + LpEventAlign; + // Wrap to beginning if no room at end + if (lpQueue->xSlicCurEventPtr > lpQueue->xSlicLastValidEventPtr) + lpQueue->xSlicCurEventPtr = lpQueue->xSlicEventStackPtr; + } + else + nextLpEvent = NULL; + + return nextLpEvent; +} + +int ItLpQueue_isLpIntPending( struct ItLpQueue * lpQueue ) +{ + struct HvLpEvent * nextLpEvent = + (struct HvLpEvent *)lpQueue->xSlicCurEventPtr; + return ( nextLpEvent->xFlags.xValid | + lpQueue->xPlicOverflowIntPending); +} + +void ItLpQueue_clearValid( struct HvLpEvent * event ) +{ + // Clear the valid bit of the event + // Also clear bits within this event that might + // look like valid bits (on 64-byte boundaries) + unsigned extra = (( event->xSizeMinus1 + LpEventAlign ) / + LpEventAlign ) - 1; + switch ( extra ) { + case 3: + ((struct HvLpEvent*)((char*)event+3*LpEventAlign))->xFlags.xValid=0; + case 2: + ((struct HvLpEvent*)((char*)event+2*LpEventAlign))->xFlags.xValid=0; + case 1: + ((struct HvLpEvent*)((char*)event+1*LpEventAlign))->xFlags.xValid=0; + case 0: + } + mb(); + event->xFlags.xValid = 0; +} + +// No lock is necessary when processing the Lp Queue because a single +// processor is assigned to each lpqueue. Interrupts are disabled +// while processing events. +// Some device drivers' interrupt handlers run with interrupts +// enabled. This requires us to prevent being re-entered here. +// We use the xInUse flag for that. + +unsigned lpQueue_proc_count[32] = {}; + +unsigned ItLpQueue_process( struct ItLpQueue * lpQueue, struct pt_regs *regs ) +{ + unsigned numIntsProcessed = 0; + struct HvLpEvent * nextLpEvent; + + // If we have recursed, just return + if ( !set_inUse( lpQueue ) ) + return 0; + + if (ItLpQueueInProcess == 0) + ItLpQueueInProcess = 1; + else + BUG(); + + ++lpQueue_proc_count[current->processor]; + + for (;;) { + nextLpEvent = ItLpQueue_getNextLpEvent( lpQueue ); + + if ( nextLpEvent ) { + // Count events to return to caller + // and count processed events in lpQueue + ++numIntsProcessed; + lpQueue->xLpIntCount++; + // Call appropriate handler here, passing + // a pointer to the LpEvent. The handler + // must make a copy of the LpEvent if it + // needs it in a bottom half. (perhaps for + // an ACK) + + // Handlers are responsible for ACK processing + + // The Hypervisor guarantees that LpEvents will + // only be delivered with types that we have + // registered for, so no type check is necessary + // here! + if ( nextLpEvent->xType < HvLpEvent_Type_NumTypes ) + lpQueue->xLpIntCountByType[nextLpEvent->xType]++; + if ( nextLpEvent->xType < HvLpEvent_Type_NumTypes && + lpEventHandler[nextLpEvent->xType] ) + lpEventHandler[nextLpEvent->xType](nextLpEvent, regs); + else + printk(KERN_INFO "Unexpected Lp Event type=%d\n", nextLpEvent->xType ); + + ItLpQueue_clearValid( nextLpEvent ); + } + else // No more valid events + // If overflow events are pending + // process them + if ( lpQueue->xPlicOverflowIntPending ) { + HvCallEvent_getOverflowLpEvents( + lpQueue->xIndex); + } + else // If nothing left then we are done + break; + } + + ItLpQueueInProcess = 0; + mb(); + clear_inUse( lpQueue ); + + return numIntsProcessed; +} diff --git a/arch/ppc/iSeries/LparData.c b/arch/ppc/iSeries/LparData.c new file mode 100644 index 000000000000..9d0b78ad8333 --- /dev/null +++ b/arch/ppc/iSeries/LparData.c @@ -0,0 +1,331 @@ +/* + * LparData.c + * Copyright (C) 2001 Mike Corrigan IBM Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#define __KERNEL__ 1 +#include <asm/types.h> +#include <asm/page.h> +#include <stddef.h> +#include <linux/config.h> +#include <asm/processor.h> +#include <asm/ptrace.h> +#include <asm/iSeries/Naca.h> +#include <asm/iSeries/ItLpNaca.h> +#include <asm/iSeries/ItLpPaca.h> +#include <asm/iSeries/ItLpRegSave.h> +#include <asm/iSeries/Paca.h> +#include <asm/iSeries/HvReleaseData.h> +#include <asm/iSeries/LparMap.h> +#include <asm/iSeries/LparData.h> +#include <asm/iSeries/ItVpdAreas.h> +#include <asm/iSeries/ItIplParmsReal.h> +#include <asm/iSeries/ItLpQueue.h> +#include <asm/iSeries/IoHriProcessorVpd.h> +#include <asm/iSeries/ItSpCommArea.h> + +#include "ReleaseData.h" + +// maxProcessors is the number of physical processors +// The number of logical processors is twice that +// number to support hardware multi-threading. +// If CONFIG_SMP is not defined, then logical +// processors will be defined, but the other threads +// will spin forever in iSeries_head.S +#define maxProcessors 16 + +extern char _start_boltedStacks[]; +unsigned maxPacas = maxProcessors * 2; + +// The LparMap is used by the hypervisor to map the load area. +// This indicates that the load area should be mapped to VSID +// 0x000000000000C and that this should be made addressable at +// ESID 0x00000000C. On 32-bit machines this is equivalent to +// loading segment register 12 with VSID 12. +// 8192 indicates to map 8192 pages (32 MB) of the load area. + +struct LparMap xLparMap = { + xNumberEsids: 4, // Number ESID/VSID pairs + xNumberRanges: 1, // Number of memory ranges + xSegmentTableOffs: 0, // Segment Table Page (unused) + xKernelEsidC: 0xC, // ESID to map + xKernelVsidC: 0xCCC, // VSID to map + xKernelEsidD: 0xD, // ESID to map + xKernelVsidD: 0xDDD, // VSID to map + xKernelEsidE: 0xE, // ESID to map + xKernelVsidE: 0xEEE, // VSID to map + xKernelEsidF: 0xF, // ESID to map + xKernelVsidF: 0xFFF, // VSID to map + + xPages: HvPagesToMap, // # of pages to map (8192) + xOffset: 0, // Offset into load area + xVPN: 0xCCC0000 // VPN of first mapped page +}; + +// The Naca has a pointer to the ItVpdAreas. The hypervisor finds +// the Naca via the HvReleaseData area. The HvReleaseData has the +// offset into the Naca of the pointer to the ItVpdAreas. + +extern struct ItVpdAreas itVpdAreas; + +struct Naca xNaca = { + 0, (void *)&itVpdAreas, + 0, 0, // Ram Disk start + 0, 0 // Ram Disk size +}; + +// The LpQueue is used to pass event data from the hypervisor to +// the partition. This is where I/O interrupt events are communicated. +// The ItLpQueue must be initialized (even though only to all zeros) +// If it were uninitialized (in .bss) it would get zeroed after the +// kernel gets control. The hypervisor will have filled in some fields +// before the kernel gets control. By initializing it we keep it out +// of the .bss + +struct ItLpQueue xItLpQueue = {}; + +// The Paca is an array with one entry per processor. Each contains an +// ItLpPaca, which contains the information shared between the +// hypervisor and Linux. Each also contains an ItLpRegSave area which +// is used by the hypervisor to save registers. +// On systems with hardware multi-threading, there are two threads +// per processor. The Paca array must contain an entry for each thread. +// The VPD Areas will give a max logical processors = 2 * max physical +// processors. The processor VPD array needs one entry per physical +// processor (not thread). + +#define PacaInit( n, start, lpq ) \ + { 0, (struct ItLpPaca *)(((char *)(&xPaca[(n)]))+offsetof(struct Paca, xLpPaca)), \ + 0, (struct ItLpRegSave *)(((char *)(&xPaca[(n)]))+offsetof(struct Paca, xRegSav)), \ + 0, 0, 0, \ + (n), (start), \ + 0, \ + 0, \ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0},\ + (lpq), \ + 0, 0, {0}, \ + { /* LpPaca */ \ + xDesc: 0xd397d781, /* "LpPa" */ \ + xSize: sizeof(struct ItLpPaca), \ + xFPRegsInUse: 1, \ + xDynProcStatus: 2, \ + xEndOfQuantum: 0xffffffffffffffff \ + }, \ + { /* LpRegSave */ \ + 0xd397d9e2, /* "LpRS" */ \ + sizeof(struct ItLpRegSave) \ + } \ + } + +struct Paca xPaca[maxProcessors*2] = { + PacaInit( 0, 1, &xItLpQueue ) + ,PacaInit( 1, 0, 0 ) + ,PacaInit( 2, 0, 0 ) + ,PacaInit( 3, 0, 0 ) + ,PacaInit( 4, 0, 0 ) + ,PacaInit( 5, 0, 0 ) + ,PacaInit( 6, 0, 0 ) + ,PacaInit( 7, 0, 0 ) + ,PacaInit( 8, 0, 0 ) + ,PacaInit( 9, 0, 0 ) + ,PacaInit( 10, 0, 0 ) + ,PacaInit( 11, 0, 0 ) + ,PacaInit( 12, 0, 0 ) + ,PacaInit( 13, 0, 0 ) + ,PacaInit( 14, 0, 0 ) + ,PacaInit( 15, 0, 0 ) + ,PacaInit( 16, 0, 0 ) + ,PacaInit( 17, 0, 0 ) + ,PacaInit( 18, 0, 0 ) + ,PacaInit( 19, 0, 0 ) + ,PacaInit( 20, 0, 0 ) + ,PacaInit( 21, 0, 0 ) + ,PacaInit( 22, 0, 0 ) + ,PacaInit( 23, 0, 0 ) + ,PacaInit( 24, 0, 0 ) + ,PacaInit( 25, 0, 0 ) + ,PacaInit( 26, 0, 0 ) + ,PacaInit( 27, 0, 0 ) + ,PacaInit( 28, 0, 0 ) + ,PacaInit( 29, 0, 0 ) + ,PacaInit( 30, 0, 0 ) + ,PacaInit( 31, 0, 0 ) +}; + + + +// The HvReleaseData is the root of the information shared between +// the hypervisor and Linux. + +struct HvReleaseData + hvReleaseData = { 0xc8a5d9c4, // desc = "HvRD" ebcdic + sizeof(struct HvReleaseData), + offsetof(struct Naca, xItVpdAreas64), + 0, &xNaca, // 64-bit Naca address + ((u32)&xLparMap-KERNELBASE), + 0, + 1, // tags inactive mode + 1, // 32-bit mode + 0, // shared processors + 0, // hardware multithreading + 6, // TEMP: set me back to 0 + // this allows non-ga 450 driver + 3, // We are v5r1m0 + 3, // Min supported PLIC = v5r1m0 + 3, // Min usuable PLIC = v5r1m0 + RELEASEDATA, + {0} + }; + + +struct ItLpNaca itLpNaca = { 0xd397d581, // desc = "LpNa" ebcdic + 0x0400, // size of ItLpNaca + 0x0300, 19, // offset to int array, # ents + 0, 0, 0, // Part # of primary, serv, me + 0, 0x100, // # of LP queues, offset + 0, 0, 0, // Piranha stuff + { 0,0,0,0,0 }, // reserved + 0,0,0,0,0,0,0, // stuff + { 0,0,0,0,0 }, // reserved + 0, // reserved + 0, // VRM index of PLIC + 0, 0, // min supported, compat SLIC + 0, // 64-bit addr of load area + 0, // chunks for load area + 0, // reserved + { 0 }, // 72 reserved bytes + { 0 }, // 128 reserved bytes + { 0 }, // Old LP Queue + { 0 }, // 384 reserved bytes + { + 0xc0000100, // int 0x100 + 0xc0000200, // int 0x200 + 0xc0000300, // int 0x300 + 0xc0000400, // int 0x400 + 0xc0000500, // int 0x500 + 0xc0000600, // int 0x600 + 0xc0000700, // int 0x700 + 0xc0000800, // int 0x800 + 0xc0000900, // int 0x900 + 0xc0000a00, // int 0xa00 + 0xc0000b00, // int 0xb00 + 0xc0000c00, // int 0xc00 + 0xc0000d00, // int 0xd00 + 0xc0000e00, // int 0xe00 + 0xc0000f00, // int 0xf00 + 0xc0001000, // int 0x1000 + 0xc0001010, // int 0x1010 + 0xc0001020, // int 0x1020 CPU ctls + 0xc0000500 // SC Ret Hdlr + // int 0x380 + // int 0x480 + } + }; + +// All of the data structures that will be filled in by the hypervisor +// must be initialized (even if only to zeroes) to keep them out of +// the bss. If in bss, they will be zeroed by the kernel startup code +// after the hypervisor has filled them in. + +struct ItIplParmsReal xItIplParmsReal = {}; + +struct IoHriProcessorVpd xIoHriProcessorVpd[maxProcessors] = { + { + xTimeBaseFreq: 50000000 + } +}; + + +u64 xMsVpd[3400] = {}; // Space for Main Store Vpd 27,200 bytes + +u64 xRecoveryLogBuffer[32] = {}; // Space for Recovery Log Buffer + +struct SpCommArea xSpCommArea = { + 0xE2D7C3C2, + 1, + {0}, + 0, 0, 0, 0, {0} +}; + +struct ItVpdAreas itVpdAreas = { + 0xc9a3e5c1, // "ItVA" + sizeof( struct ItVpdAreas ), + 0, 0, + 26, // # VPD array entries + 10, // # DMA array entries + maxProcessors*2, maxProcessors, // Max logical, physical procs + offsetof(struct ItVpdAreas,xPlicDmaToks),// offset to DMA toks + offsetof(struct ItVpdAreas,xSlicVpdAdrs),// offset to VPD addrs + offsetof(struct ItVpdAreas,xPlicDmaLens),// offset to DMA lens + offsetof(struct ItVpdAreas,xSlicVpdLens),// offset to VPD lens + 0, // max slot labels + 1, // max LP queues + {0}, {0}, // reserved + {0}, // DMA lengths + {0}, // DMA tokens + { // VPD lengths + 0,0,0,0, // 0 - 3 + sizeof(struct Paca), // 4 length of Paca + 0, // 5 + sizeof(struct ItIplParmsReal),// 6 length of IPL parms + 26992, // 7 length of MS VPD + 0, // 8 + sizeof(struct ItLpNaca),// 9 length of LP Naca + 0, // 10 + 256, // 11 length of Recovery Log Buf + sizeof(struct SpCommArea), // 12 length of SP Comm area + 0,0,0, // 13 - 15 + sizeof(struct IoHriProcessorVpd),// 16 length of Proc Vpd + 0,0,0,0,0,0, // 17 - 22 + sizeof(struct ItLpQueue),// 23 length of Lp Queue + 0,0 // 24 - 25 + }, + { // VPD addresses + {0},{0},{0},{0}, // 0 - 3 + {0, &xPaca[0]}, // 4 first Paca + {0}, // 5 + {0, &xItIplParmsReal}, // 6 IPL parms + {0, &xMsVpd}, // 7 MS Vpd + {0}, // 8 + {0, &itLpNaca}, // 9 LpNaca + {0}, // 10 + {0, &xRecoveryLogBuffer},// 11 Recovery Log Buffer + {0, &xSpCommArea}, // 12 Sp Comm Area + {0},{0},{0}, // 13 - 15 + {0, &xIoHriProcessorVpd},// 16 Proc Vpd + {0},{0},{0},{0},{0},{0},// 17 - 22 + {0, &xItLpQueue}, // 23 Lp Queue + {0},{0} + } + +}; + +// The size of this array determines how much main store can be +// configured for use in the partition. 16384 allows 16384 * 256KB +// which is 4GB. This is enough for the 32-bit +// implementation, but the msChunks array will need to be dynamically +// allocated for really big partitions. +u32 msChunks[16384] = {0}; +u32 totalLpChunks = 0; + +// Data area used in flush_hash_page +long long flush_hash_page_hpte[2] = {0,0}; + +u64 virt_to_absolute_outline(u32 address) +{ + return virt_to_absolute(address); +} diff --git a/arch/ppc/iSeries/Makefile b/arch/ppc/iSeries/Makefile new file mode 100644 index 000000000000..76f8eb13cfee --- /dev/null +++ b/arch/ppc/iSeries/Makefile @@ -0,0 +1,26 @@ +# +# Makefile for Linux arch/ppc/iSeries source directory +# +# Note! Dependencies are done automagically by 'make dep', which also +# removes any old dependencies. DON'T put your own dependencies here +# unless it's something special (ie not a .c file). +# +# Note 2! The CFLAGS definitions are now in the main makefile... + +O_TARGET := iSeries.o +export-objs := iSeries_ksyms.o +obj-y += LparData.o ItLpQueue.o HvLpEvent.o HvCall.o mf.o iSeries_proc.o mf_proc.o iSeries_ksyms.o HvLpConfig.o pmc_proc.o rtc.o + +obj-$(CONFIG_PCI) += XmPciLpEvent.o iSeries_FlightRecorder.o iSeries_IoMmTable.o iSeries_VpdInfo.o iSeries_fixup.o iSeries_irq.o iSeries_pci.o iSeries_pci_proc.o iSeries_reset_device.o + +all: iSeries.o + +LparData.c:: ReleaseData.h + +ReleaseData.h: $(TOPDIR)/Makefile + /bin/bash ./createReleaseData $(KERNELRELEASE) > $@ + +clean: + rm -f ReleaseData.h + +include $(TOPDIR)/Rules.make diff --git a/arch/ppc/iSeries/XmPciLpEvent.c b/arch/ppc/iSeries/XmPciLpEvent.c new file mode 100644 index 000000000000..201da57cd61b --- /dev/null +++ b/arch/ppc/iSeries/XmPciLpEvent.c @@ -0,0 +1,150 @@ +/* + * File XmPciLpEvent.h created by Wayne Holm on Mon Jan 15 2001. + * + * This module handles PCI interrupt events sent by the AS400 Hypervisor. +*/ + + +#include <linux/pci.h> +#include <linux/config.h> +#include <linux/init.h> +#include <linux/threads.h> +#include <linux/smp.h> +#include <linux/param.h> +#include <linux/string.h> +#include <linux/bootmem.h> +#include <linux/blk.h> +#include <linux/ide.h> + +#include <asm/iSeries/HvTypes.h> +#include <asm/iSeries/HvLpEvent.h> +#include <asm/iSeries/HvCallPci.h> +#include <asm/iSeries/XmPciLpEvent.h> + + +enum XmPciLpEvent_Subtype { + XmPciLpEvent_BusCreated = 0, // PHB has been created + XmPciLpEvent_BusFailed = 1, // PHB has failed + XmPciLpEvent_BusRecovered = 12, // PHB has been recovered + XmPciLpEvent_NodeFailed = 4, // Multi-adapter bridge has failed + XmPciLpEvent_NodeRecovered = 5, // Multi-adapter bridge has recovered + XmPciLpEvent_SlotInterrupt = 22 // Slot interrupt +}; + +struct XmPciLpEvent_BusInterrupt { + HvBusNumber busNumber; + HvSubBusNumber subBusNumber; +}; + +struct XmPciLpEvent_NodeInterrupt { + HvBusNumber busNumber; + HvSubBusNumber subBusNumber; + HvAgentId deviceId; +}; + +struct XmPciLpEvent { + struct HvLpEvent hvLpEvent; + + union { + u64 alignData; // Align on an 8-byte boundary + + struct { + u32 fisr; + HvBusNumber busNumber; + HvSubBusNumber subBusNumber; + HvAgentId deviceId; + } slotInterrupt; + + struct XmPciLpEvent_BusInterrupt busFailed; + struct XmPciLpEvent_BusInterrupt busRecovered; + struct XmPciLpEvent_BusInterrupt busCreated; + + struct XmPciLpEvent_NodeInterrupt nodeFailed; + struct XmPciLpEvent_NodeInterrupt nodeRecovered; + + } eventData; + +}; + +static void intReceived(struct XmPciLpEvent* eventParm, struct pt_regs* regsParm); + +static void XmPciLpEvent_handler( struct HvLpEvent* eventParm, struct pt_regs* regsParm) { + if (eventParm && eventParm->xType == HvLpEvent_Type_PciIo) { + switch( eventParm->xFlags.xFunction ) { + case HvLpEvent_Function_Int: + intReceived( (struct XmPciLpEvent*)eventParm, regsParm ); + break; + case HvLpEvent_Function_Ack: + printk(KERN_ERR "XmPciLpEvent.c: unexpected ack received\n"); + break; + default: + printk(KERN_ERR "XmPciLpEvent.c: unexpected event function %d\n", + (int)eventParm->xFlags.xFunction); + break; + }; + } + else { + if (event) { + printk(KERN_ERR "XmPciLpEvent.c: unrecognized event type 0x%x\n", + (int)eventParm->xType); + } + else { + printk(KERN_ERR "XmPciLpEvent.c: NULL event received\n"); + } + } +} + +static void intReceived(struct XmPciLpEvent* eventParm, struct pt_regs* regsParm) { + int irq; + + switch (eventParm->hvLpEvent.xSubtype) { + case XmPciLpEvent_SlotInterrupt: + irq = eventParm->hvLpEvent.xCorrelationToken; + /* Dispatch the interrupt handlers for this irq */ + ppc_irq_dispatch_handler(regsParm, irq); + HvCallPci_eoi(eventParm->eventData.slotInterrupt.busNumber, + eventParm->eventData.slotInterrupt.subBusNumber, + eventParm->eventData.slotInterrupt.deviceId); + break; + /* Ignore error recovery events for now */ + case XmPciLpEvent_BusCreated: + printk(KERN_INFO "XmPciLpEvent.c: system bus %d created\n", eventParm->eventData.busCreated.busNumber); + break; + case XmPciLpEvent_BusFailed: + printk(KERN_INFO "XmPciLpEvent.c: system bus %d failed\n", eventParm->eventData.busFailed.busNumber); + break; + case XmPciLpEvent_BusRecovered: + printk(KERN_INFO "XmPciLpEvent.c: system bus %d recovered\n", eventParm->eventData.busRecovered.busNumber); + break; + case XmPciLpEvent_NodeFailed: + printk(KERN_INFO "XmPciLpEvent.c: multi-adapter bridge %d/%d/%d failed\n", eventParm->eventData.nodeFailed.busNumber, eventParm->eventData.nodeFailed.subBusNumber, eventParm->eventData.nodeFailed.deviceId); + break; + case XmPciLpEvent_NodeRecovered: + printk(KERN_INFO "XmPciLpEvent.c: multi-adapter bridge %d/%d/%d recovered\n", eventParm->eventData.nodeRecovered.busNumber, eventParm->eventData.nodeRecovered.subBusNumber, eventParm->eventData.nodeRecovered.deviceId); + break; + default: + printk(KERN_ERR "XmPciLpEvent.c: unrecognized event subtype 0x%x\n", + eventParm->hvLpEvent.xSubtype); + break; + }; +} + + +/* This should be called sometime prior to buswalk (init_IRQ would be good) */ +int XmPciLpEvent_init() { + int xRc; + + xRc = HvLpEvent_registerHandler(HvLpEvent_Type_PciIo, &XmPciLpEvent_handler); + if (xRc == 0) { + xRc = HvLpEvent_openPath(HvLpEvent_Type_PciIo, 0); + if (xRc != 0) { + printk(KERN_ERR "XmPciLpEvent.c: open event path failed with rc 0x%x\n", xRc); + } + } + else { + printk(KERN_ERR "XmPciLpEvent.c: register handler failed with rc 0x%x\n", xRc); + } + + return xRc; +} + diff --git a/arch/ppc/iSeries/createReleaseData b/arch/ppc/iSeries/createReleaseData new file mode 100644 index 000000000000..f43de83d2bb4 --- /dev/null +++ b/arch/ppc/iSeries/createReleaseData @@ -0,0 +1,115 @@ +#!/bin/bash +#################################################### +# Build a hex ebcdic representation of the +# KERNELRELEASE for use in the iSeries +# hvReleaseData structure +#################################################### + +if [ $# -ne 1 ] +then + echo "Syntax: createReleaseData kernelversion" + exit 1 +fi + +len=${#1} + +rd='' +#################################################### +# ReleaseData is maximum of 12 chars +#################################################### +if [ $len -gt 12 ] +then + len=12 +fi + +#for (( i=0 ; $i < $len ; i=$i+1 )) ; +i=0 +while (($i<$len)); +do + char=${1:$i:1} + case $char in + 'a') xchar='0x81';; + 'b') xchar='0x82';; + 'c') xchar='0x83';; + 'd') xchar='0x84';; + 'e') xchar='0x85';; + 'f') xchar='0x86';; + 'g') xchar='0x87';; + 'h') xchar='0x88';; + 'i') xchar='0x89';; + 'j') xchar='0x91';; + 'k') xchar='0x92';; + 'l') xchar='0x93';; + 'm') xchar='0x94';; + 'n') xchar='0x95';; + 'o') xchar='0x96';; + 'p') xchar='0x97';; + 'q') xchar='0x98';; + 'r') xchar='0x99';; + 's') xchar='0xA2';; + 't') xchar='0xA3';; + 'u') xchar='0xA4';; + 'v') xchar='0xA5';; + 'w') xchar='0xA6';; + 'x') xchar='0xA7';; + 'y') xchar='0xA8';; + 'z') xchar='0xA9';; + 'A') xchar='0xC1';; + 'B') xchar='0xC2';; + 'C') xchar='0xC3';; + 'D') xchar='0xC4';; + 'E') xchar='0xC5';; + 'F') xchar='0xC6';; + 'G') xchar='0xC7';; + 'H') xchar='0xC8';; + 'I') xchar='0xC9';; + 'J') xchar='0xD1';; + 'K') xchar='0xD2';; + 'L') xchar='0xD3';; + 'M') xchar='0xD4';; + 'N') xchar='0xD5';; + 'O') xchar='0xD6';; + 'P') xchar='0xD7';; + 'Q') xchar='0xD8';; + 'R') xchar='0xD9';; + 'S') xchar='0xE2';; + 'T') xchar='0xE3';; + 'U') xchar='0xE4';; + 'V') xchar='0xE5';; + 'W') xchar='0xE6';; + 'X') xchar='0xE7';; + 'Y') xchar='0xE8';; + 'Z') xchar='0xE9';; + '0') xchar='0xF0';; + '1') xchar='0xF1';; + '2') xchar='0xF2';; + '3') xchar='0xF3';; + '4') xchar='0xF4';; + '5') xchar='0xF5';; + '6') xchar='0xF6';; + '7') xchar='0xF7';; + '8') xchar='0xF8';; + '9') xchar='0xF9';; + '.') xchar='0x4B';; + '-') xchar='0x60';; + '_') xchar='0x6D';; + '+') xchar='0x4E';; + '@') xchar='0x7C';; + '$') xchar='0x5B';; + '%') xchar='0x6C';; + *) xchar='';; + esac + + rd=${rd}${xchar} + if [ $(($i+1)) -lt $len ] + then + rd=${rd}', ' + fi + i=$i+1 +done + +#echo "#define RELEASEDATA { $rd }">ReleaseData.h + +echo "#define RELEASEDATA { $rd }" + + diff --git a/arch/ppc/iSeries/iSeries_FlightRecorder.c b/arch/ppc/iSeries/iSeries_FlightRecorder.c new file mode 100644 index 000000000000..a69f6c0ec9f2 --- /dev/null +++ b/arch/ppc/iSeries/iSeries_FlightRecorder.c @@ -0,0 +1,89 @@ +/************************************************************************/ +/* File iSeries_FlightRecorder.c created by Al Trautman on Jan 22 2001. */ +/************************************************************************/ +/* This code supports the pci interface on the IBM iSeries systems. */ +/* Copyright (C) 20yy <Allan H Trautman> <IBM Corp> */ +/* */ +/* This program is free software; you can redistribute it and/or modify */ +/* it under the terms of the GNU General Public License as published by */ +/* the Free Software Foundation; either version 2 of the License, or */ +/* (at your option) any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, */ +/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ +/* GNU General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU General Public License */ +/* along with this program; if not, write to the: */ +/* Free Software Foundation, Inc., */ +/* 59 Temple Place, Suite 330, */ +/* Boston, MA 02111-1307 USA */ +/************************************************************************/ +/* Change Activity: */ +/* Created, Jan 22, 2001 */ +/* Added Time Stamps, April 12, 2001 */ +/* End Change Activity */ +/************************************************************************/ +#include <linux/config.h> +#include <linux/kernel.h> +#include <asm/iSeries/iSeries_FlightRecorder.h> +#include <linux/rtc.h> +#include <asm/iSeries/mf.h> +/************************************************************************/ +/* Log entry into buffer, */ +/* ->If entry is going to wrap, log "WRAP" and start at the top. */ +/************************************************************************/ +void iSeries_LogFr_Entry(FlightRecorder* Fr, char* LogText) { + int Residual, TextLen; + if(Fr->StartingPointer > 0) { /* Initialized yet? */ + Residual = FlightRecorderSize - (Fr->CurrentPointer - Fr->StartingPointer); + TextLen = strlen(LogText); /* Length of Text */ + if(TextLen+16 > Residual) { /* Room for text or need to wrap*/ + strcpy(Fr->CurrentPointer,"WRAP"); + ++Fr->WrapCount; /* Increment Wraps */ + Fr->CurrentPointer = Fr->StartingPointer; + } + strcpy(Fr->CurrentPointer,LogText); + Fr->CurrentPointer += TextLen+1; + strcpy(Fr->CurrentPointer,"<="); + } +} +/************************************************************************/ +/* Log entry with time */ +/************************************************************************/ +void iSeries_LogFr_Time(FlightRecorder* Fr, char* LogText) { + struct rtc_time Rtc; + char LogBuffer[256]; + mf_getRtc(&Rtc); + sprintf(LogBuffer,"%02d:%02d:%02d %s", + Rtc.tm_hour,Rtc.tm_min,Rtc.tm_sec, + LogText); + iSeries_LogFr_Entry(Fr,LogBuffer); +} +/************************************************************************/ +/* Log Entry with Date and call Time Log */ +/************************************************************************/ +void iSeries_LogFr_Date(FlightRecorder* Fr, char* LogText) { + struct rtc_time Rtc; + char LogBuffer[256]; + mf_getRtc(&Rtc); + sprintf(LogBuffer,"%02d.%02d.%02d %02d:%02d:%02d %s", + Rtc.tm_year+1900, Rtc.tm_mon, Rtc.tm_mday, + Rtc.tm_hour,Rtc.tm_min,Rtc.tm_sec, + LogText); + iSeries_LogFr_Entry(Fr,LogBuffer); +} +/************************************************************************/ +/* Initialized the Flight Recorder */ +/************************************************************************/ +void iSeries_Fr_Initialize(FlightRecorder* Fr, char* Signature) { + if(strlen(Signature) > 16) memcpy(Fr->Signature,Signature,16); + else strcpy(Fr->Signature,Signature); + Fr->StartingPointer = &Fr->Buffer[0]; + Fr->CurrentPointer = Fr->StartingPointer; + Fr->logEntry = iSeries_LogFr_Entry; + Fr->logDate = iSeries_LogFr_Date; + Fr->logTime = iSeries_LogFr_Time; + Fr->logEntry(Fr,"FR Initialized."); /* Note, can't use time yet! */ +} diff --git a/arch/ppc/iSeries/iSeries_IoMmTable.c b/arch/ppc/iSeries/iSeries_IoMmTable.c new file mode 100644 index 000000000000..09dbccdcc36b --- /dev/null +++ b/arch/ppc/iSeries/iSeries_IoMmTable.c @@ -0,0 +1,206 @@ +/************************************************************************/ +/* This module supports the iSeries I/O Address translation mapping */ +/* Copyright (C) 20yy <Allan H Trautman> <IBM Corp> */ +/* */ +/* This program is free software; you can redistribute it and/or modify */ +/* it under the terms of the GNU General Public License as published by */ +/* the Free Software Foundation; either version 2 of the License, or */ +/* (at your option) any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, */ +/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ +/* GNU General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU General Public License */ +/* along with this program; if not, write to the: */ +/* Free Software Foundation, Inc., */ +/* 59 Temple Place, Suite 330, */ +/* Boston, MA 02111-1307 USA */ +/************************************************************************/ +/* Change Activity: */ +/* Created, December 14, 2000 */ +/* Added Bar table for IoMm performance. */ +/* End Change Activity */ +/************************************************************************/ +#include <asm/types.h> +#include <asm/resource.h> +#include <linux/pci.h> +#include <linux/spinlock.h> +#include <asm/iSeries/HvCallPci.h> +#include <asm/iSeries/iSeries_FlightRecorder.h> + +#include "iSeries_IoMmTable.h" +#include "iSeries_pci.h" + +void iSeries_allocateDeviceBars(struct pci_dev* PciDevPtr); +/*******************************************************************/ +/* Table defines */ +/* Entry size is 4 MB * 1024 Entries = 4GB. */ +/*******************************************************************/ +#define iSeries_IoMmTable_Entry_Size 0x00400000 +#define iSeries_IoMmTable_Size 1024 +#define iSeries_Base_Io_Memory 0xFFFFFFFF + +/*******************************************************************/ +/* Static and Global variables */ +/*******************************************************************/ +struct pci_dev* iSeries_IoMmTable[iSeries_IoMmTable_Size]; +u8 iSeries_IoBarTable[iSeries_IoMmTable_Size]; +static int iSeries_CurrentIndex; +static char* iSeriesPciIoText = "iSeries PCI I/O"; +static spinlock_t iSeriesIoMmTableLock = SPIN_LOCK_UNLOCKED; +/*******************************************************************/ +/* iSeries_IoMmTable_Initialize */ +/*******************************************************************/ +/* - Initalizes the Address Translation Table and get it ready for */ +/* use. Must be called before any client calls any of the other */ +/* methods. */ +/*******************************************************************/ +void iSeries_IoMmTable_Initialize(void) { + int Index; + spin_lock(&iSeriesIoMmTableLock); + for(Index=0;Index<iSeries_IoMmTable_Size ; ++Index) { + iSeries_IoMmTable[Index] = NULL; + iSeries_IoBarTable[Index] = 0xFF; + } + spin_unlock(&iSeriesIoMmTableLock); + iSeries_CurrentIndex = iSeries_IoMmTable_Size-1; + ISERIES_PCI_FR("IoMmTable Init."); +} +/*******************************************************************/ +/* iSeries_allocateDeviceBars */ +/*******************************************************************/ +/* - Allocates ALL pci_dev BAR's and updates the resources with the*/ +/* BAR value. BARS with zero length will have the resources */ +/* The HvCallPci_getBarParms is used to get the size of the BAR */ +/* space. It calls iSeries_IoMmTable_AllocateEntry to allocate */ +/* each entry. */ +/* - Loops through The Bar resourses(0 - 5) including the the ROM */ +/* is resource(6). */ +/*******************************************************************/ +void iSeries_allocateDeviceBars(struct pci_dev* PciDevPtr) { + struct resource* BarResource; + int BarNumber = 0; /* Current Bar Number */ + if(PciTraceFlag > 0) { + printk("PCI: iSeries_allocateDeviceBars 0x%08X\n",(int)PciDevPtr); + sprintf(PciFrBuffer,"IoBars %08X",(int)PciDevPtr); + ISERIES_PCI_FR(PciFrBuffer); + } + for(BarNumber = 0; BarNumber <= PCI_ROM_RESOURCE; ++BarNumber) { + BarResource = &PciDevPtr->resource[BarNumber]; + iSeries_IoMmTable_AllocateEntry(PciDevPtr, BarNumber); + } +} + +/*******************************************************************/ +/* iSeries_IoMmTable_AllocateEntry */ +/*******************************************************************/ +/* Adds pci_dev entry in address translation table */ +/*******************************************************************/ +/* - Allocates the number of entries required in table base on BAR */ +/* size. */ +/* - This version, allocates top down, starting at 4GB. */ +/* - The size is round up to be a multiple of entry size. */ +/* - CurrentIndex is decremented to keep track of the last entry. */ +/* - Builds the resource entry for allocated BARs. */ +/*******************************************************************/ +void iSeries_IoMmTable_AllocateEntry(struct pci_dev* PciDevPtr, u32 BarNumber) { + struct resource* BarResource = &PciDevPtr->resource[BarNumber]; + int BarSize = BarResource->end - BarResource->start; + u32 BarStartAddr; + u32 BarEndAddr; + /***************************************************************/ + /* No space to allocate, skip Allocation. */ + /***************************************************************/ + if(BarSize == 0) return; /* Quick stage exit */ + + /***************************************************************/ + /* Allocate the table entries needed. */ + /***************************************************************/ + spin_lock(&iSeriesIoMmTableLock); + while(BarSize > 0) { + iSeries_IoMmTable[iSeries_CurrentIndex] = PciDevPtr; + iSeries_IoBarTable[iSeries_CurrentIndex] = BarNumber; + BarSize -= iSeries_IoMmTable_Entry_Size; + --iSeries_CurrentIndex; /* Next Free entry */ + } + spin_unlock(&iSeriesIoMmTableLock); + BarStartAddr = iSeries_IoMmTable_Entry_Size*(iSeries_CurrentIndex+1); + BarEndAddr = BarStartAddr + (u32)(BarResource->end - BarResource->start); + /***************************************************************/ + /* Build Resource info */ + /***************************************************************/ + BarResource->name = iSeriesPciIoText; + BarResource->start = (long)BarStartAddr; + BarResource->end = (long)BarEndAddr; + + /***************************************************************/ + /* Tracing */ + /***************************************************************/ + if(PciTraceFlag > 0) { + printk("PCI: BarAloc %04X-%08X-%08X\n",iSeries_CurrentIndex+1,(int)BarStartAddr, (int)BarEndAddr); + sprintf(PciFrBuffer,"IoMmAloc %04X-%08X-%08X", + iSeries_CurrentIndex+1,(int)BarStartAddr, (int)BarEndAddr); + ISERIES_PCI_FR(PciFrBuffer); + } +} +/*******************************************************************/ +/* Translates an I/O Memory address to pci_dev* */ +/*******************************************************************/ +struct pci_dev* iSeries_xlateIoMmAddress(u32* IoAddress) { + int PciDevIndex; + struct pci_dev* PciDevPtr; + PciDevIndex = (u32)IoAddress/iSeries_IoMmTable_Entry_Size; + PciDevPtr = iSeries_IoMmTable[PciDevIndex]; + if(PciDevPtr == 0) { + printk("PCI: Invalid I/O Address: 0x%08X\n",(int)IoAddress); + sprintf(PciFrBuffer,"Invalid MMIO Address 0x%08X",(int)IoAddress); + ISERIES_PCI_FR(PciFrBuffer); + } + return PciDevPtr; +} +/************************************************************************/ +/* Returns the Bar number of Address */ +/************************************************************************/ +int iSeries_IoMmTable_Bar(u32 *IoAddress) { + int BarIndex = (u32)IoAddress/iSeries_IoMmTable_Entry_Size; + int BarNumber = iSeries_IoBarTable[BarIndex]; + return BarNumber; +} +/************************************************************************/ +/* Return the Bar Base Address or 0. */ +/************************************************************************/ +u32* iSeries_IoMmTable_BarBase(u32 *IoAddress) { + u32 BaseAddr = -1; + pciDev* PciDev = iSeries_xlateIoMmAddress(IoAddress); + if(PciDev != 0) { + int BarNumber = iSeries_IoMmTable_Bar(IoAddress); + if(BarNumber != -1) { + BaseAddr = (&PciDev->resource[BarNumber])->start; + } + } + return (u32*)BaseAddr; +} +/************************************************************************/ +/* Return the Bar offset within the Bar Space */ +/* Note: Assumes that address is valid. */ +/************************************************************************/ +u32 iSeries_IoMmTable_BarOffset(u32* IoAddress) { + u32 BaseAddr = (u32)iSeries_IoMmTable_BarBase(IoAddress); + return (u32)IoAddress-BaseAddr; +} +/************************************************************************/ +/* Return 0 if Address is valid I/O Address */ +/************************************************************************/ +int iSeries_Is_IoMmAddress(unsigned long IoAddress) { + if( iSeries_IoMmTable_Bar((u32*)IoAddress) == -1) return 1; + else return 0; +} +/************************************************************************/ +/* Helper Methods to get TableSize and TableSizeEntry. */ +/************************************************************************/ +u32 iSeries_IoMmTable_TableEntrySize(void) { return iSeries_IoMmTable_Entry_Size; } +u32 iSeries_IoMmTable_TableSize(void) { return iSeries_IoMmTable_Size; } + + diff --git a/arch/ppc/iSeries/iSeries_IoMmTable.h b/arch/ppc/iSeries/iSeries_IoMmTable.h new file mode 100644 index 000000000000..c8a0466e6270 --- /dev/null +++ b/arch/ppc/iSeries/iSeries_IoMmTable.h @@ -0,0 +1,105 @@ +#ifndef _ISERIES_IOMMTABLE_H +#define _ISERIES_IOMMTABLE_H +/************************************************************************/ +/* File iSeries_IoMmTable.h created by Allan Trautman on Dec 12 2001. */ +/************************************************************************/ +/* Interfaces for the write/read Io address translation table. */ +/* Copyright (C) 20yy Allan H Trautman, IBM Corporation */ +/* */ +/* This program is free software; you can redistribute it and/or modify */ +/* it under the terms of the GNU General Public License as published by */ +/* the Free Software Foundation; either version 2 of the License, or */ +/* (at your option) any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, */ +/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ +/* GNU General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU General Public License */ +/* along with this program; if not, write to the: */ +/* Free Software Foundation, Inc., */ +/* 59 Temple Place, Suite 330, */ +/* Boston, MA 02111-1307 USA */ +/************************************************************************/ +/* Change Activity: */ +/* Created December 12, 2000 */ +/* End Change Activity */ +/************************************************************************/ + +/************************************************************************/ +/* iSeries_IoMmTable_Initialize */ +/************************************************************************/ +/* - Initalizes the Address Translation Table and get it ready for use. */ +/* Must be called before any client calls any of the other methods. */ +/* */ +/* Parameters: None. */ +/* */ +/* Return: None. */ +/************************************************************************/ +extern void iSeries_IoMmTable_Initialize(void); + +/************************************************************************/ +/* iSeries_allocateDeviceBars */ +/************************************************************************/ +/* - Allocates ALL pci_dev BAR's and updates the resources with the BAR */ +/* value. BARS with zero length will not have the resources. The */ +/* HvCallPci_getBarParms is used to get the size of the BAR space. */ +/* It calls as400_IoMmTable_AllocateEntry to allocate each entry. */ +/* */ +/* Parameters: */ +/* pci_dev = Pointer to pci_dev structure that will be mapped to pseudo */ +/* I/O Address. */ +/* */ +/* Return: */ +/* The pci_dev I/O resources updated with pseudo I/O Addresses. */ +/************************************************************************/ +extern void iSeries_allocateDeviceBars(struct pci_dev* Device); + +/************************************************************************/ +/* iSeries_IoMmTable_AllocateEntry */ +/************************************************************************/ +/* - Allocates(adds) the pci_dev entry in the Address Translation Table */ +/* and updates the Resources for the device. */ +/* */ +/* Parameters: */ +/* pci_dev = Pointer to pci_dev structure that will be mapped to pseudo */ +/* I/O Address. */ +/* */ +/* BarNumber = Which Bar to be allocated. */ +/* */ +/* Return: */ +/* The pseudo I/O Address in the resources that will map to the */ +/* pci_dev on iSeries_xlateIoMmAddress call. */ +/************************************************************************/ +extern void iSeries_IoMmTable_AllocateEntry(struct pci_dev* Device, u32 BarNumber); + +/************************************************************************/ +/* iSeries_xlateIoMmAddress */ +/************************************************************************/ +/* - Translates an I/O Memory address to pci_dev that has been allocated*/ +/* the psuedo I/O Address. */ +/* */ +/* Parameters: */ +/* IoAddress = I/O Memory Address. */ +/* */ +/* Return: */ +/* A pci_dev pointer to the device mapped to the I/O address. */ +/************************************************************************/ +extern struct pci_dev* iSeries_xlateIoMmAddress(u32* IoAddress); + +/************************************************************************/ +/* Helper Methods */ +/************************************************************************/ +extern int iSeries_IoMmTable_Bar(u32 *IoAddress); +extern u32* iSeries_IoMmTable_BarBase(u32* IoAddress); +extern u32 iSeries_IoMmTable_BarOffset(u32* IoAddress); +extern int iSeries_Is_IoMmAddress(unsigned long address); + +/************************************************************************/ +/* Helper Methods to get TableSize and TableSizeEntry. */ +/************************************************************************/ +extern u32 iSeries_IoMmTable_TableEntrySize(void); +extern u32 iSeries_IoMmTable_TableSize(void); + +#endif /* _ISERIES_IOMMTABLE_H */ diff --git a/arch/ppc/iSeries/iSeries_VpdInfo.c b/arch/ppc/iSeries/iSeries_VpdInfo.c new file mode 100644 index 000000000000..97271d63b473 --- /dev/null +++ b/arch/ppc/iSeries/iSeries_VpdInfo.c @@ -0,0 +1,339 @@ +/************************************************************************/ +/* File iSeries_vpdInfo.c created by Allan Trautman on Fri Feb 2 2001. */ +/************************************************************************/ +/* This code gets the card location of the hardware */ +/* Copyright (C) 20yy <Allan H Trautman> <IBM Corp> */ +/* */ +/* This program is free software; you can redistribute it and/or modify */ +/* it under the terms of the GNU General Public License as published by */ +/* the Free Software Foundation; either version 2 of the License, or */ +/* (at your option) any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, */ +/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ +/* GNU General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU General Public License */ +/* along with this program; if not, write to the: */ +/* Free Software Foundation, Inc., */ +/* 59 Temple Place, Suite 330, */ +/* Boston, MA 02111-1307 USA */ +/************************************************************************/ +/* Change Activity: */ +/* Created, Feb 2, 2001 */ +/* End Change Activity */ +/************************************************************************/ +#include <linux/config.h> +#include <linux/init.h> +#include <linux/pci.h> +#include <asm/types.h> +#include <asm/resource.h> + +#include <asm/iSeries/HvCallPci.h> +#include <asm/iSeries/HvTypes.h> +#include <asm/iSeries/mf.h> +#include <asm/iSeries/LparData.h> +#include <asm/iSeries/HvCallPci.h> +#include <asm/iSeries/iSeries_VpdInfo.h> +#include "iSeries_pci.h" + +/************************************************/ +/* Size of Bus VPD data */ +/************************************************/ +#define BUS_VPDSIZE 1024 +/************************************************/ +/* Bus Vpd Tags */ +/************************************************/ +#define VpdEndOfDataTag 0x78 +#define VpdEndOfAreaTag 0x79 +#define VpdIdStringTag 0x82 +#define VpdVendorAreaTag 0x84 +/************************************************/ +/* Mfg Area Tags */ +/************************************************/ +#define VpdAsmPartNumber 0x504E // "PN" +#define VpdFruFlag 0x4647 // "FG" +#define VpdFruLocation 0x464C // "FL" +#define VpdFruFrameId 0x4649 // "FI" +#define VpdFruPartNumber 0x464E // "FN" +#define VpdFruPowerData 0x5052 // "PR" +#define VpdFruSerial 0x534E // "SN" +#define VpdFruType 0x4343 // "CC" +#define VpdFruCcinExt 0x4345 // "CE" +#define VpdFruRevision 0x5256 // "RV" +#define VpdSlotMapFormat 0x4D46 // "MF" +#define VpdSlotMap 0x534D // "SM" + +/************************************************/ +/* Structures of the areas */ +/************************************************/ +struct BusVpdAreaStruct { + u8 Tag; + u8 LowLength; + u8 HighLength; +}; +typedef struct BusVpdAreaStruct BusVpdArea; +#define BUS_ENTRY_SIZE 3 + +struct MfgVpdAreaStruct { + u16 Tag; + u8 TagLength; +}; +typedef struct MfgVpdAreaStruct MfgVpdArea; +#define MFG_ENTRY_SIZE 3 + +struct SlotMapFormatStruct { + u16 Tag; + u8 TagLength; + u16 Format; +}; + +struct FrameIdMapStruct{ + u16 Tag; + u8 TagLength; + u8 FrameId; +}; +typedef struct FrameIdMapStruct FrameIdMap; + +struct SlotMapStruct { + u8 AgentId; + u8 SecondaryAgentId; + u8 PhbId; + char CardLocation[3]; + char Parms[8]; + char Reserved[2]; +}; +typedef struct SlotMapStruct SlotMap; +#define SLOT_ENTRY_SIZE 16 + +/****************************************************************/ +/* Prototypes */ +/****************************************************************/ +static void iSeries_Parse_Vpd(BusVpdArea*, int, LocationData*); +static void iSeries_Parse_MfgArea(MfgVpdArea*,int, LocationData*); +static void iSeries_Parse_SlotArea(SlotMap*, int, LocationData*); +static void iSeries_Parse_PhbId(BusVpdArea*, int, LocationData*); + +/****************************************************************/ +/* */ +/* */ +/* */ +/****************************************************************/ +LocationData* iSeries_GetLocationData(struct pci_dev* PciDev) { + LocationData* LocationPtr = 0; + BusVpdArea* BusVpdPtr = 0; + int BusVpdLen = 0; + BusVpdPtr = (BusVpdArea*)kmalloc(BUS_VPDSIZE, GFP_KERNEL); + BusVpdLen = HvCallPci_getBusVpd(ISERIES_GET_LPAR_BUS(PciDev->bus->number),REALADDR(BusVpdPtr),BUS_VPDSIZE); + /* printk("PCI: VpdBuffer 0x%08X \n",(int)BusVpdPtr); */ + /***************************************************************/ + /* Need to set Agent Id, Bus in location info before the call */ + /***************************************************************/ + LocationPtr = (LocationData*)kmalloc(LOCATION_DATA_SIZE, GFP_KERNEL); + LocationPtr->Bus = ISERIES_GET_LPAR_BUS(PciDev->bus->number); + LocationPtr->Board = 0; + LocationPtr->FrameId = 0; + iSeries_Parse_PhbId(BusVpdPtr,BusVpdLen,LocationPtr); + LocationPtr->Card = PCI_SLOT(PciDev->devfn); + strcpy(LocationPtr->CardLocation,"Cxx"); + LocationPtr->AgentId = ISERIES_DECODE_DEVICE(PciDev->devfn); + LocationPtr->SecondaryAgentId = 0x10; + /* And for Reference only. */ + LocationPtr->LinuxBus = PciDev->bus->number; + LocationPtr->LinuxDevFn = PciDev->devfn; + /***************************************************************/ + /* Any data to process? */ + /***************************************************************/ + if(BusVpdLen > 0) { + iSeries_Parse_Vpd(BusVpdPtr, BUS_VPDSIZE, LocationPtr); + } + else { + ISERIES_PCI_FR("No VPD Data...."); + } + kfree(BusVpdPtr); + + return LocationPtr; +} +/****************************************************************/ +/* */ +/****************************************************************/ +void iSeries_Parse_Vpd(BusVpdArea* VpdData,int VpdLen, LocationData* LocationPtr) { + MfgVpdArea* MfgVpdPtr = 0; + int BusTagLen = 0; + BusVpdArea* BusVpdPtr = VpdData; + int BusVpdLen = VpdLen; + /*************************************************************/ + /* Make sure this is what I think it is */ + /*************************************************************/ + if(BusVpdPtr->Tag != VpdIdStringTag) { /*0x82 */ + ISERIES_PCI_FR("Not 0x82 start."); + return; + } + BusTagLen = (BusVpdPtr->HighLength*256)+BusVpdPtr->LowLength; + BusTagLen += BUS_ENTRY_SIZE; + BusVpdPtr = (BusVpdArea*)((u32)BusVpdPtr+BusTagLen); + BusVpdLen -= BusTagLen; + /*************************************************************/ + /* Parse the Data */ + /*************************************************************/ + while(BusVpdLen > 0 ) { + BusTagLen = (BusVpdPtr->HighLength*256)+BusVpdPtr->LowLength; + /*********************************************************/ + /* End of data Found */ + /*********************************************************/ + if(BusVpdPtr->Tag == VpdEndOfAreaTag) { + BusVpdLen = 0; /* Done, Make sure */ + } + /*********************************************************/ + /* Was Mfg Data Found */ + /*********************************************************/ + else if(BusVpdPtr->Tag == VpdVendorAreaTag) { + MfgVpdPtr = (MfgVpdArea*)((u32)BusVpdPtr+BUS_ENTRY_SIZE); + iSeries_Parse_MfgArea(MfgVpdPtr,BusTagLen,LocationPtr); + } + /********************************************************/ + /* On to the next tag. */ + /********************************************************/ + if(BusVpdLen > 0) { + BusTagLen += BUS_ENTRY_SIZE; + BusVpdPtr = (BusVpdArea*)((u32)BusVpdPtr+BusTagLen); + BusVpdLen -= BusTagLen; + } + } +} + +/*****************************************************************/ +/* Parse the Mfg Area */ +/*****************************************************************/ +void iSeries_Parse_MfgArea(MfgVpdArea* VpdDataPtr,int VpdLen, LocationData* LocationPtr) { + SlotMap* SlotMapPtr = 0; + u16 SlotMapFmt = 0; + int MfgTagLen = 0; + MfgVpdArea* MfgVpdPtr = VpdDataPtr; + int MfgVpdLen = VpdLen; + + /*************************************************************/ + /* Parse Mfg Data */ + /*************************************************************/ + while(MfgVpdLen > 0) { + MfgTagLen = MfgVpdPtr->TagLength; + if (MfgVpdPtr->Tag == VpdFruFlag) {} /* FG */ + else if(MfgVpdPtr->Tag == VpdFruSerial) {} /* SN */ + else if(MfgVpdPtr->Tag == VpdAsmPartNumber){} /* PN */ + /*********************************************************/ + /* Frame ID */ + /*********************************************************/ + if(MfgVpdPtr->Tag == VpdFruFrameId) { /* FI */ + LocationPtr->FrameId = ((FrameIdMap*)MfgVpdPtr)->FrameId; + } + /*********************************************************/ + /* Slot Map Format */ + /*********************************************************/ + else if(MfgVpdPtr->Tag == VpdSlotMapFormat){ /* MF */ + SlotMapFmt = ((struct SlotMapFormatStruct*)MfgVpdPtr)->Format; + } + /*********************************************************/ + /* Slot Labels */ + /*********************************************************/ + else if(MfgVpdPtr->Tag == VpdSlotMap){ /* SM */ + if(SlotMapFmt == 0x1004) SlotMapPtr = (SlotMap*)((u32)MfgVpdPtr+MFG_ENTRY_SIZE+1); + else SlotMapPtr = (SlotMap*)((u32)MfgVpdPtr+MFG_ENTRY_SIZE); + iSeries_Parse_SlotArea(SlotMapPtr,MfgTagLen, LocationPtr); + } + /*********************************************************/ + /* Point to the next Mfg Area */ + /* Use defined size, sizeof give wrong answer */ + /*********************************************************/ + MfgTagLen += MFG_ENTRY_SIZE; + MfgVpdPtr = (MfgVpdArea*)( (u32)MfgVpdPtr + MfgTagLen); + MfgVpdLen -= MfgTagLen; + } +} +/*****************************************************************/ +/* Look for "BUS" Tag to set the PhbId. */ +/*****************************************************************/ +void iSeries_Parse_PhbId(BusVpdArea* VpdData,int VpdLen,LocationData* LocationPtr) { + int PhbId = 0xff; /* Not found flag */ + char* PhbPtr = (char*)VpdData+3; /* Skip over 82 tag */ + int DataLen = VpdLen; + while(DataLen > 0) { + if(*PhbPtr == 'B' && *(PhbPtr+1) == 'U' && *(PhbPtr+2) == 'S') { + if(*(PhbPtr+3) == ' ') PhbPtr += 4;/* Skip white spac*/ + else PhbPtr += 3; + if (*PhbPtr == '0') PhbId = 0; /* Don't convert, */ + else if(*PhbPtr == '1') PhbId = 1; /* Sanity check */ + else if(*PhbPtr == '2') PhbId = 2; /* values */ + DataLen = 0; /* Exit loop. */ + } + ++PhbPtr; + --DataLen; + } + LocationPtr->PhbId = PhbId; +} +/*****************************************************************/ +/* Parse the Slot Area */ +/*****************************************************************/ +void iSeries_Parse_SlotArea(SlotMap* MapPtr,int MapLen, LocationData* LocationPtr) { + int SlotMapLen = MapLen; + SlotMap* SlotMapPtr = MapPtr; + /*************************************************************/ + /* Parse Slot label until we find the one requrested */ + /*************************************************************/ + while(SlotMapLen > 0) { + if(SlotMapPtr->AgentId == LocationPtr->AgentId && + SlotMapPtr->SecondaryAgentId == LocationPtr->SecondaryAgentId) { + /*****************************************************/ + /* If Phb wasn't found, grab the first one found. */ + /*****************************************************/ + if(LocationPtr->PhbId == 0xff) LocationPtr->PhbId = SlotMapPtr->PhbId; + if( SlotMapPtr->PhbId == LocationPtr->PhbId ) { + /*****************************************************/ + /* Found what we were looking for, extract the data. */ + /*****************************************************/ + memcpy(&LocationPtr->CardLocation,&SlotMapPtr->CardLocation,3); + LocationPtr->CardLocation[3] = 0; /* Null terminate*/ + SlotMapLen = 0; /* We are done */ + } + } + /*********************************************************/ + /* Point to the next Slot */ + /* Use defined size, sizeof may give wrong answer */ + /*********************************************************/ + SlotMapLen -= SLOT_ENTRY_SIZE; + SlotMapPtr = (SlotMap*)((u32)SlotMapPtr+SLOT_ENTRY_SIZE); + } +} +/************************************************************************/ +/* Formats the device information. */ +/* - Pass in pci_dev* pointer to the device. */ +/* - Pass in buffer to place the data. Danger here is the buffer must */ +/* be as big as the client says it is. Should be at least 128 bytes.*/ +/* Return will the length of the string data put in the buffer. */ +/* Format: */ +/* PCI: Bus 0, Device 26, Vendor 0x12AE iSeries: Bus 2, Device 34, Fr*/ +/* ame 1, Card C10 Ethernet controller */ +/************************************************************************/ +int iSeries_Device_Information(struct pci_dev* PciDev,char* Buffer, int BufferSize) { + LocationData* LocationPtr; /* VPD Information */ + char* BufPtr = Buffer; + int LineLen = 0; + if(BufferSize >= 128) { + LineLen = sprintf(BufPtr+LineLen,"PCI: Bus%3d, Device%3d, Vendor %04X ", + PciDev->bus->number, PCI_SLOT(PciDev->devfn),PciDev->vendor); + + LocationPtr = iSeries_GetLocationData(PciDev); + LineLen += sprintf(BufPtr+LineLen,"iSeries: Bus%3d, Device%3d, Frame%3d, Card %4s ", + LocationPtr->Bus,LocationPtr->AgentId, + LocationPtr->FrameId,LocationPtr->CardLocation); + kfree(LocationPtr); + + if(pci_class_name(PciDev->class >> 8) == 0) { + LineLen += sprintf(BufPtr+LineLen,"0x%04X ",(int)(PciDev->class >> 8)); + } + else { + LineLen += sprintf(BufPtr+LineLen,"%s",pci_class_name(PciDev->class >> 8) ); + } + } + return LineLen; +} diff --git a/arch/ppc/iSeries/iSeries_fixup.c b/arch/ppc/iSeries/iSeries_fixup.c new file mode 100644 index 000000000000..5d15384bba19 --- /dev/null +++ b/arch/ppc/iSeries/iSeries_fixup.c @@ -0,0 +1,255 @@ +/************************************************************************/ +/* This module supports the iSeries PCI bus device detection */ +/* Copyright (C) 20yy <Robert L Holtorf> <IBM Corp> */ +/* */ +/* This program is free software; you can redistribute it and/or modify */ +/* it under the terms of the GNU General Public License as published by */ +/* the Free Software Foundation; either version 2 of the License, or */ +/* (at your option) any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, */ +/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ +/* GNU General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU General Public License */ +/* along with this program; if not, write to the: */ +/* Free Software Foundation, Inc., */ +/* 59 Temple Place, Suite 330, */ +/* Boston, MA 02111-1307 USA */ +/************************************************************************/ +/* Change Activity: */ +/* Created, December 13, 2000 by Wayne Holm */ +/* End Change Activity */ +/************************************************************************/ +#include <linux/pci.h> +#include <linux/ide.h> +#include <asm/pci-bridge.h> +#include <asm/iSeries/HvCallXm.h> +#include <asm/iSeries/HvCallPci.h> +#include <asm/iSeries/iSeries_fixup.h> +#include <asm/iSeries/LparData.h> +#include <asm/iSeries/iSeries_irq.h> +#include <asm/iSeries/iSeries_dma.h> +#include <asm/iSeries/iSeries_VpdInfo.h> +#include <asm/iSeries/iSeries_pci.h> +#include "iSeries_IoMmTable.h" +#include "iSeries_pci.h" + + + +unsigned int __init iSeries_scan_slot(struct pci_dev* temp_dev, + u16 hvBus, u8 slotSubBus, u8 maxAgents) +{ + u8 hvIdSel, hvFunction, hvAgentId; + u64 hvRc = 0; + u64 noConnectRc = 0xFFFF; + HvAgentId slotAgentId; + int irq; + + slotAgentId = ISERIES_PCI_AGENTID(ISERIES_GET_DEVICE_FROM_SUBBUS(slotSubBus), ISERIES_GET_FUNCTION_FROM_SUBBUS(slotSubBus)); + irq = iSeries_allocate_IRQ(hvBus, 0, slotAgentId); + for (hvIdSel = 1; hvIdSel <= maxAgents; ++hvIdSel) { + /* Connect all functions of any device found. However, only call pci_scan_slot + once for each idsel. pci_scan_slot handles multifunction devices appropriately */ + for (hvFunction = 0; hvFunction < 8 && hvRc == 0; ++hvFunction) { + hvAgentId = ISERIES_PCI_AGENTID(hvIdSel, hvFunction); + hvRc = HvCallXm_connectBusUnit(hvBus, slotSubBus, hvAgentId, irq); + if (hvRc == 0) { + noConnectRc = 0; + HvCallPci_configStore8(hvBus, slotSubBus, hvAgentId, PCI_INTERRUPT_LINE, irq); // Store the irq in the interrupt line register of the function config space + } + } + if (noConnectRc == 0) { + /* This assumes that the node slot is always on the primary bus! */ + temp_dev->devfn = ISERIES_ENCODE_SUBBUS(ISERIES_GET_DEVICE_FROM_SUBBUS(slotSubBus), + ISERIES_GET_FUNCTION_FROM_SUBBUS(slotSubBus), + 0); + iSeries_assign_IRQ(irq, hvBus, 0, slotAgentId); + pci_scan_slot(temp_dev); + } + } + return 0; +} + +void __init iSeries_fixup_bus(struct pci_bus* bus) +{ + struct pci_dev temp_dev; + struct pci_controller* hose; + u16 hvBus; + u8 hvSubBus, hvIdSel, hvFunction, hvAgentId, maxAgents, irq; + u64 hvRc, devInfoRealAdd, bridgeInfoRealAdd; + struct HvCallPci_DeviceInfo* devInfo; + struct HvCallPci_BridgeInfo* bridgeInfo; + u64 noConnectRc = 0xFFFF; + + hose = (struct pci_controller*)(bus->sysdata); + /* Get the hv bus number from the hose arch_data */ + hvBus = ISERIES_GET_HOSE_HV_BUSNUM(hose); + /* Initialize the global bus number map for this bus */ + iSeries_GlobalBusMap[bus->number][_HVBUSNUMBER_] = hvBus; + iSeries_GlobalBusMap[bus->number][_HVSUBBUSNUMBER_] = 0; + maxAgents = 7; + /* If not a primary bus, set the hypervisor subBus number of this bus into the map */ + if (bus->parent != NULL) { + bridgeInfo = kmalloc(sizeof(*bridgeInfo), GFP_KERNEL); + /* Perform linux virtual address to iSeries PLIC real address translation */ + bridgeInfoRealAdd = virt_to_absolute((u32)bridgeInfo); + bridgeInfoRealAdd = bridgeInfoRealAdd | 0x8000000000000000; + /* Find the Hypervisor address of the bridge which created this bus... */ + if (ISERIES_IS_SUBBUS_ENCODED_IN_DEVFN(bus->self->devfn)) { // This assumes that the bus passed to this function is connected to an EADS slot. The subbus encoding algorithm only applies to bridge cards attached directly to EADS. Future TODO is to allow for n levels of bridging. + hvSubBus = ISERIES_DEVFN_DECODE_SUBBUS(bus->self->devfn); + hvIdSel = 1; + } + else { + /* The hose arch_data needs to map Linux bus number -> PHB bus/subBus number + Could also use a global table, might be cheaper for multiple PHBs */ + // hvSubBus = iSeries_GlobalBusMap[bus->parent->number][_HVSUBBUSNUMBER_]; + hvSubBus = 0; // The bridge card devfn is not subbus encoded and is directly attached to the PCI primary bus. Its subbus number is 0 and the card config space is accessed via type 0 config cycles. + hvIdSel = PCI_SLOT(bus->self->devfn); + } + hvAgentId = ISERIES_PCI_AGENTID(hvIdSel, PCI_FUNC(bus->self->devfn)); + /* Now we know the HV bus/subbus/agent of the bridge creating this bus, + go get the subbus number from HV */ + hvRc = HvCallPci_getBusUnitInfo(hvBus, hvSubBus, hvAgentId, + bridgeInfoRealAdd, sizeof(*bridgeInfo)); + if (hvRc != 0 || bridgeInfo->busUnitInfo.deviceType != HvCallPci_BridgeDevice) { + kfree(bridgeInfo); + // return -1; + } + iSeries_GlobalBusMap[bus->number][_HVSUBBUSNUMBER_] = bridgeInfo->subBusNumber; + maxAgents = bridgeInfo->maxAgents; + kfree(bridgeInfo); + } + /* Bus number mapping is complete, from here on cfgIos should result in HvCalls */ + + hvSubBus = iSeries_GlobalBusMap[bus->number][_HVSUBBUSNUMBER_]; + + devInfo = kmalloc(sizeof(*devInfo), GFP_KERNEL); + devInfoRealAdd = virt_to_absolute((u32)devInfo); + devInfoRealAdd = devInfoRealAdd | 0x8000000000000000; + memset(&temp_dev, 0, sizeof(temp_dev)); + temp_dev.bus = bus; + temp_dev.sysdata = bus->sysdata; + + for (hvIdSel=1; hvIdSel <= maxAgents; ++hvIdSel) { + hvRc = HvCallPci_getDeviceInfo(hvBus, hvSubBus, hvIdSel, + devInfoRealAdd, sizeof(*devInfo)); + if (hvRc == 0) { + switch(devInfo->deviceType) { + case HvCallPci_NodeDevice: + /* bridgeInfo = kmalloc(HvCallPci_MaxBusUnitInfoSize, GFP_KERNEL); */ + bridgeInfo = kmalloc(sizeof(*bridgeInfo), GFP_KERNEL); + /* Loop through each node function to find usable bridges. Scan + the node bridge to create devices. The devices will appear + as if they were connected to the primary bus. */ + for (hvFunction=0; hvFunction < 8; ++hvFunction) { + hvAgentId = ISERIES_PCI_AGENTID(hvIdSel, hvFunction); + irq = 0; + /* Note: hvSubBus should always be 0 here! */ + hvRc = HvCallXm_connectBusUnit(hvBus, hvSubBus, hvAgentId, irq); + if (hvRc == 0) { + bridgeInfoRealAdd = virt_to_absolute((u32)bridgeInfo); + bridgeInfoRealAdd = bridgeInfoRealAdd | 0x8000000000000000; + hvRc = HvCallPci_getBusUnitInfo(hvBus, hvSubBus, hvAgentId, + bridgeInfoRealAdd, sizeof(*bridgeInfo)); + if (hvRc == 0 && bridgeInfo->busUnitInfo.deviceType == HvCallPci_BridgeDevice) + { + // scan any card plugged into this slot + iSeries_scan_slot(&temp_dev, hvBus, bridgeInfo->subBusNumber, + bridgeInfo->maxAgents); + } + } + } + kfree(bridgeInfo); + break; + + case HvCallPci_MultiFunctionDevice: + /* Attempt to connect each device function, then use architecture independent + pci_scan_slot to build the device(s) */ + irq = bus->self->irq; // Assume that this multi-function device is attached to a secondary bus. Get the irq from the dev struct for the bus and pass to Hv on the function connects as well as write it into the interrupt line registers of each function + for (hvFunction=0; hvFunction < 8 && hvRc == 0; ++hvFunction) { + hvAgentId = ISERIES_PCI_AGENTID(hvIdSel, hvFunction); + /* Try to connect each function. */ + hvRc = HvCallXm_connectBusUnit(hvBus, hvSubBus, hvAgentId, irq); + if (hvRc == 0) { + noConnectRc = 0; + HvCallPci_configStore8(hvBus, hvSubBus, hvAgentId, PCI_INTERRUPT_LINE, irq); // Store the irq in the interrupt line register of the function config space + } + } + if (noConnectRc == 0) { + noConnectRc = 0xFFFF; // Reset to error value in case other multi-function devices are attached to this bus + // Note: using hvIdSel assumes this device is on a secondary bus! + temp_dev.devfn = PCI_DEVFN(hvIdSel, 0); + pci_scan_slot(&temp_dev); + } + break; + + case HvCallPci_BridgeDevice: + case HvCallPci_IoaDevice: + /* Single function devices, just try to connect and use pci_scan_slot to + build the device */ + irq = bus->self->irq; + hvAgentId = ISERIES_PCI_AGENTID(hvIdSel, 0); + hvRc = HvCallXm_connectBusUnit(hvBus, hvSubBus, hvAgentId, irq); + if (hvRc == 0) { + HvCallPci_configStore8(hvBus, hvSubBus, hvAgentId, PCI_INTERRUPT_LINE, irq); // Store the irq in the interrupt line register of the device config space + // Note: using hvIdSel assumes this device is on a secondary bus! + temp_dev.devfn = PCI_DEVFN(hvIdSel, 0); + pci_scan_slot(&temp_dev); + } + break; + + default : /* Unrecognized device */ + break; + + }; /* end of switch */ + } + } + + kfree(devInfo); + // return 0; +} +/* Initialize bar space base and limit addresses for each device in the tree */ +void __init iSeries_fixup( void ) { + struct pci_dev *dev; + u8 LinuxBus, iSeriesBus, LastBusNumber; + char DeviceInfoBuffer[256]; + + /*********************************************************/ + /* PCI: Allocate Bars space for each device */ + /*********************************************************/ + pci_for_each_dev(dev) { + iSeries_allocateDeviceBars(dev); + } + /*********************************************************/ + /* Create the TCEs for each iSeries bus now that we know */ + /* how many buses there are. Need only create TCE for */ + /* for each iSeries bus. Multiple linux buses could */ + /* be on the same iSeries bus. AHT */ + /*********************************************************/ + LastBusNumber = 0xFF; /* Invalid */ + for( LinuxBus = 0; LinuxBus < 255; ++ LinuxBus) { + iSeriesBus = ISERIES_GET_LPAR_BUS(LinuxBus); + if(iSeriesBus == 0xFF) break; /* Done */ + else if(LastBusNumber != iSeriesBus ){ /* New Bus */ + create_pci_bus_tce_table(iSeriesBus); + LastBusNumber = iSeriesBus; /* Remember */ + } + } + /*********************************************************/ + /* List out all the PCI devices found... This will go */ + /* into the etc/proc/iSeries/pci info as well.... */ + /* This is to help service figure out who is who...... */ + /*********************************************************/ + pci_for_each_dev(dev) { + struct resource* BarResource = &dev->resource[0]; + iSeries_Device_Information(dev,DeviceInfoBuffer,256); + printk("%s\n",DeviceInfoBuffer); + printk("PCI: Bus%3d, Device%3d, %s at 0x%08x, irq %3d\n", + dev->bus->number, PCI_SLOT(dev->devfn),dev->name,(int)BarResource->start,dev->irq); + } + /* */ + iSeries_activate_IRQs(); // Unmask all device interrupts for assigned IRQs +} + diff --git a/arch/ppc/iSeries/iSeries_irq.c b/arch/ppc/iSeries/iSeries_irq.c new file mode 100644 index 000000000000..c0760bceb475 --- /dev/null +++ b/arch/ppc/iSeries/iSeries_irq.c @@ -0,0 +1,256 @@ +/************************************************************************/ +/* This module supports the iSeries PCI bus interrupt handling */ +/* Copyright (C) 20yy <Robert L Holtorf> <IBM Corp> */ +/* */ +/* This program is free software; you can redistribute it and/or modify */ +/* it under the terms of the GNU General Public License as published by */ +/* the Free Software Foundation; either version 2 of the License, or */ +/* (at your option) any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, */ +/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ +/* GNU General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU General Public License */ +/* along with this program; if not, write to the: */ +/* Free Software Foundation, Inc., */ +/* 59 Temple Place, Suite 330, */ +/* Boston, MA 02111-1307 USA */ +/************************************************************************/ +/* Change Activity: */ +/* Created, December 13, 2000 by Wayne Holm */ +/* End Change Activity */ +/************************************************************************/ + +#include <linux/pci.h> +#include <linux/config.h> +#include <linux/init.h> +#include <linux/threads.h> +#include <linux/smp.h> +#include <linux/param.h> +#include <linux/string.h> +#include <linux/bootmem.h> +#include <linux/blk.h> +#include <linux/ide.h> + +#include <linux/irq.h> +#include <linux/spinlock.h> +#include <linux/malloc.h> + +#include <asm/iSeries/HvCallPci.h> +#include <asm/iSeries/HvCallXm.h> +#include <asm/iSeries/iSeries_irq.h> +#include <asm/iSeries/XmPciLpEvent.h> + + +hw_irq_controller iSeries_IRQ_handler = { + "iSeries irq controller", + iSeries_startup_IRQ, /* startup */ + iSeries_shutdown_IRQ, /* shutdown */ + iSeries_enable_IRQ, /* enable */ + iSeries_disable_IRQ, /* disable */ + NULL, /* ack */ + iSeries_end_IRQ, /* end */ + NULL /* set_affinity */ +}; + + +struct iSeries_irqEntry { + u32 dsa; + struct iSeries_irqEntry* next; +}; + +struct iSeries_irqAnchor { + u8 valid : 1; + u8 reserved : 7; + u16 entryCount; + struct iSeries_irqEntry* head; +}; + +struct iSeries_irqAnchor iSeries_irqMap[NR_IRQS]; + +void iSeries_init_irqMap(int irq); + +/* This is called by init_IRQ. set in ppc_md.init_IRQ by iSeries_setup.c */ +void __init iSeries_init_IRQ(void) +{ + + int i; + + for (i = 0; i < NR_IRQS; i++) { + irq_desc[i].handler = &iSeries_IRQ_handler; + irq_desc[i].status = 0; + irq_desc[i].status |= IRQ_DISABLED; + irq_desc[i].depth = 1; + iSeries_init_irqMap(i); + } + + /* Register PCI event handler and open an event path */ + XmPciLpEvent_init(); + + return; +} + +/* Called by iSeries_init_IRQ */ +void __init iSeries_init_irqMap(int irq) { + /* Prevent IRQs 0 and 255 from being used. IRQ 0 appears in + uninitialized devices. IRQ 255 appears in the PCI interrupt + line register if a PCI error occurs */ + iSeries_irqMap[irq].valid = (irq == 0 || irq == 255)? 0 : 1; + iSeries_irqMap[irq].entryCount = 0; + iSeries_irqMap[irq].head = NULL; +} + +/* This is called out of iSeries_scan_slot to allocate an IRQ for an EADS slot */ +int __init iSeries_allocate_IRQ(HvBusNumber busNumber, HvSubBusNumber subBusNumber, HvAgentId deviceId) { + + u8 idsel = (deviceId >> 4); + u8 function = deviceId & 0x0F; + int irq = ((((busNumber-1)*16 + (idsel-1)*8 + function)*9/8) % 254) + 1; + return irq; +} + +/* This is called out of iSeries_scan_slot to assign the EADS slot to its IRQ number */ +int __init iSeries_assign_IRQ(int irq, HvBusNumber busNumber, HvSubBusNumber subBusNumber, HvAgentId deviceId) { + + int rc; + u32 dsa = (busNumber << 16) | (subBusNumber << 8) | deviceId; + struct iSeries_irqEntry* newEntry; + unsigned long flags; + + if (irq < 0 || irq >= NR_IRQS) + return -1; + + newEntry = kmalloc(sizeof(*newEntry), GFP_KERNEL); + if (newEntry == NULL) + return -ENOMEM; + newEntry->dsa = dsa; + newEntry->next = NULL; + + /* Probably not necessary to lock the irq since allocation is only + done during buswalk, but it should not hurt anything except a little + performance */ + spin_lock_irqsave(&irq_desc[irq].lock, flags); + + if (iSeries_irqMap[irq].valid) { + /* Push the new element onto the irq stack */ + newEntry->next = iSeries_irqMap[irq].head; + iSeries_irqMap[irq].head = newEntry; + ++iSeries_irqMap[irq].entryCount; + rc = 0; + } + else + rc = -1; + + spin_unlock_irqrestore(&irq_desc[irq].lock, flags); + + if (rc != 0 && newEntry) + kfree(newEntry); + + return rc; + +} + + +/* This is called by iSeries_activate_IRQs */ +unsigned int iSeries_startup_IRQ(unsigned int irq) { + struct iSeries_irqEntry* entry; + u32 bus, subBus, deviceId, function, mask; + + /* irq should be locked by the caller */ + + for(entry=iSeries_irqMap[irq].head; entry!=NULL; entry=entry->next) { + bus = (entry->dsa >> 16) & 0xFFFF; + subBus = (entry->dsa >> 8) & 0xFF; + deviceId = entry->dsa & 0xFF; + function = deviceId & 0x0F; + /* Link the IRQ number to the bridge */ + HvCallXm_connectBusUnit(bus, subBus, deviceId, irq); + /* Unmask bridge interrupts in the FISR */ + mask = 0x01010000 << function; + HvCallPci_unmaskFisr(bus, subBus, deviceId, mask); + } + + return 0; +} + +/* This is called out of iSeries_fixup to + activate interrupt generation for usable slots */ +void __init iSeries_activate_IRQs() { + int irq; + unsigned long flags; + + for (irq=0; irq < NR_IRQS; irq++) { + spin_lock_irqsave(&irq_desc[irq].lock, flags); + irq_desc[irq].handler->startup(irq); + spin_unlock_irqrestore(&irq_desc[irq].lock, flags); + } + +} + +/* this is not called anywhere currently */ +void iSeries_shutdown_IRQ(unsigned int irq) { + struct iSeries_irqEntry* entry; + u32 bus, subBus, deviceId, function, mask; + + /* irq should be locked by the caller */ + + for(entry=iSeries_irqMap[irq].head; entry; entry=entry->next) { + bus = (entry->dsa >> 16) & 0xFFFF; + subBus = (entry->dsa >> 8) & 0xFF; + deviceId = entry->dsa & 0xFF; + function = deviceId & 0x0F; + /* Invalidate the IRQ number in the bridge */ + HvCallXm_connectBusUnit(bus, subBus, deviceId, 0); + /* Mask bridge interrupts in the FISR */ + mask = 0x01010000 << function; + HvCallPci_maskFisr(bus, subBus, deviceId, mask); + } + +} + + +/* This will be called by device drivers (via disable_IRQ to disable + INTA in the bridge interrupt status register */ +void iSeries_disable_IRQ(unsigned int irq) { + struct iSeries_irqEntry* entry; + u32 bus, subBus, deviceId, mask; + + /* The IRQ has already been locked by the caller */ + + for(entry=iSeries_irqMap[irq].head; entry; entry=entry->next) { + bus = (entry->dsa >> 16) & 0xFFFF; + subBus = (entry->dsa >> 8) & 0xFF; + deviceId = entry->dsa & 0xFF; + /* Mask secondary INTA */ + mask = 0x80000000; + HvCallPci_maskInterrupts(bus, subBus, deviceId, mask); + } +} + +/* This will be called by device drivers (via enable_IRQ to enable + INTA in the bridge interrupt status register */ +void iSeries_enable_IRQ(unsigned int irq) { + struct iSeries_irqEntry* entry; + u32 bus, subBus, deviceId, mask; + + /* The IRQ has already been locked by the caller */ + + for(entry=iSeries_irqMap[irq].head; entry; entry=entry->next) { + bus = (entry->dsa >> 16) & 0xFFFF; + subBus = (entry->dsa >> 8) & 0xFF; + deviceId = entry->dsa & 0xFF; + /* Unmask secondary INTA */ + mask = 0x80000000; + HvCallPci_unmaskInterrupts(bus, subBus, deviceId, mask); + } +} + +/* Need to define this so ppc_irq_dispatch_handler will NOT call + enable_IRQ at the end of interrupt handling. However, this + does nothing because there is not enough information provided + to do the EOI HvCall. This is done by XmPciLpEvent.c */ +void iSeries_end_IRQ(unsigned int irq) { +} + diff --git a/arch/ppc/iSeries/iSeries_ksyms.c b/arch/ppc/iSeries/iSeries_ksyms.c new file mode 100644 index 000000000000..62432141eac0 --- /dev/null +++ b/arch/ppc/iSeries/iSeries_ksyms.c @@ -0,0 +1,82 @@ +/* File iSeries_ksyms.c created by root on Tue Feb 13 2001. */ + +/* Change Activity: */ +/* End Change Activity */ + +#include <linux/config.h> +#include <linux/module.h> +#include <linux/pci.h> +#include <asm/iSeries/iSeries_dma.h> +#include <asm/iSeries/mf.h> +#include <asm/iSeries/HvCallSc.h> +#include <asm/iSeries/HvLpEvent.h> +#include <asm/iSeries/Naca.h> +#include <asm/iSeries/iSeries_proc.h> +#include <asm/iSeries/ItLpNaca.h> +#include <asm/iSeries/HvLpConfig.h> +#include <asm/iSeries/iSeries_io.h> +#include <asm/iSeries/iSeries_FlightRecorder.h> +#include <asm/iSeries/iSeries_pci.h> +#include <asm/iSeries/iSeries_VpdInfo.h> +#include <asm/delay.h> + +EXPORT_SYMBOL(HvLpEvent_registerHandler); +EXPORT_SYMBOL(HvLpEvent_unregisterHandler); +EXPORT_SYMBOL(HvLpEvent_openPath); +EXPORT_SYMBOL(HvLpEvent_closePath); + +EXPORT_SYMBOL(HvCall1); +EXPORT_SYMBOL(HvCall2); +EXPORT_SYMBOL(HvCall3); +EXPORT_SYMBOL(HvCall4); +EXPORT_SYMBOL(HvCall5); +EXPORT_SYMBOL(HvCall6); +EXPORT_SYMBOL(HvCall7); +EXPORT_SYMBOL(HvCall0); +EXPORT_SYMBOL(HvCall0Ret16); +EXPORT_SYMBOL(HvCall1Ret16); +EXPORT_SYMBOL(HvCall2Ret16); +EXPORT_SYMBOL(HvCall3Ret16); +EXPORT_SYMBOL(HvCall4Ret16); +EXPORT_SYMBOL(HvCall5Ret16); +EXPORT_SYMBOL(HvCall6Ret16); +EXPORT_SYMBOL(HvCall7Ret16); + +EXPORT_SYMBOL(HvLpConfig_getLpIndex_outline); +EXPORT_SYMBOL(virt_to_absolute_outline); + +EXPORT_SYMBOL(mf_allocateLpEvents); +EXPORT_SYMBOL(mf_deallocateLpEvents); + +EXPORT_SYMBOL(iSeries_proc_callback); + + +#ifdef CONFIG_PCI +EXPORT_SYMBOL(pci_map_single); +EXPORT_SYMBOL(pci_unmap_single); + +EXPORT_SYMBOL(iSeries_Readb); +EXPORT_SYMBOL(iSeries_Readw); +EXPORT_SYMBOL(iSeries_Readl); +EXPORT_SYMBOL(iSeries_Writeb); +EXPORT_SYMBOL(iSeries_Writew); +EXPORT_SYMBOL(iSeries_Writel); + +EXPORT_SYMBOL(iSeries_memcpy_fromio); +EXPORT_SYMBOL(iSeries_memcpy_toio); + +EXPORT_SYMBOL(iSeries_GetLocationData); + +EXPORT_SYMBOL(iSeries_Set_PciTraceFlag); +EXPORT_SYMBOL(iSeries_Get_PciTraceFlag); + +EXPORT_SYMBOL(iSeries_Device_Reset_NoIrq); +EXPORT_SYMBOL(iSeries_Device_Reset_Generic); +EXPORT_SYMBOL(iSeries_Device_Reset); +EXPORT_SYMBOL(iSeries_Device_RestoreConfigRegs); +EXPORT_SYMBOL(iSeries_Device_SaveConfigRegs); +EXPORT_SYMBOL(iSeries_Device_ToggleReset); +#endif + + + diff --git a/arch/ppc/iSeries/iSeries_pci.c b/arch/ppc/iSeries/iSeries_pci.c new file mode 100644 index 000000000000..41b9d4a7b140 --- /dev/null +++ b/arch/ppc/iSeries/iSeries_pci.c @@ -0,0 +1,587 @@ +/************************************************************************/ +/* File iSeries_pci.c created by Allan Trautman on Tue Jan 9 2001. */ +/************************************************************************/ +/* This code supports the pci interface on the IBM iSeries systems. */ +/* Copyright (C) 20yy <Allan H Trautman> <IBM Corp> */ +/* */ +/* This program is free software; you can redistribute it and/or modify */ +/* it under the terms of the GNU General Public License as published by */ +/* the Free Software Foundation; either version 2 of the License, or */ +/* (at your option) any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, */ +/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ +/* GNU General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU General Public License */ +/* along with this program; if not, write to the: */ +/* Free Software Foundation, Inc., */ +/* 59 Temple Place, Suite 330, */ +/* Boston, MA 02111-1307 USA */ +/************************************************************************/ +/* Change Activity: */ +/* Created, Jan 9, 2001 */ +/* August, 10, 2001 Added PCI Retry code. */ +/* End Change Activity */ +/************************************************************************/ +#include <linux/config.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/pci.h> + +/************************************************************************/ +/* Arch specific's */ +/************************************************************************/ +#include <asm/io.h> /* Has Io Instructions. */ +#include <asm/iSeries/iSeries_io.h> +#include <asm/pci-bridge.h> +#include <asm/iSeries/HvCallPci.h> +#include <asm/iSeries/HvTypes.h> +#include <asm/iSeries/mf.h> +#include <asm/iSeries/iSeries_proc.h> +#include <asm/iSeries/iSeries_FlightRecorder.h> +#include <asm/iSeries/iSeries_VpdInfo.h> +#include "iSeries_IoMmTable.h" +#include "iSeries_pci.h" + +extern int panic_timeout; /* Panic Timeout reference */ + +/************************************************************************/ +/* /proc/iSeries/pci initialization. */ +/************************************************************************/ +extern void iSeries_pci_proc_init(struct proc_dir_entry *iSeries_proc); + void iSeries_pci_IoError(char* OpCode,iSeries_Device* Device); + +/************************************************************************/ +/* PCI Config Space Access functions for IBM iSeries Systems */ +/* */ +/* Modeled after the IBM Python */ +/* int pci_read_config_word(struct pci_dev*, int Offset, u16* ValuePtr) */ +/************************************************************************/ +/* Note: Normal these routines are defined by a macro and branch */ +/* table is created and stuffed in the pci_bus structure. */ +/* The following is for reference, if it was done this way. However for*/ +/* the first time out, the routines are individual coded. */ +/************************************************************************/ +/* This is the low level architecture depend interface routines. */ +/* 1. They must be in specific order, see <linux/pci.h> for base */ +/* structure. */ +/* 2. The code in not inline here, it calls specific routines in */ +/* this module and HvCalls */ +/* 3. The common convention is to put a pointer to the structure in */ +/* pci_bus->sysdata. */ +/* 4. Direct call is the same as in <linux/pci.h */ +/************************************************************************/ +int iSeries_pci_read_config_byte( struct pci_dev* PciDev, int Offset, u8* ValuePtr) { + iSeries_Device Device; + build_iSeries_Device(&Device, PciDev); + if(Device.BusNumber == 0xFF) Device.RCode = 0x301; /* Trap out invalid bus. */ + else { + Device.RCode = HvCallPci_configLoad8(Device.BusNumber, Device.SubBus, Device.DevFn, Offset, ValuePtr); + if(Device.RCode != 0 || PciTraceFlag > 0) { + sprintf(PciFrBuffer,"RCB: %02X,%02X,%02X,%04X Rtn: %04X,%02X", + Device.BusNumber, Device.SubBus, Device.DevFn, Offset, + Device.RCode, *ValuePtr); + ISERIES_PCI_FR(PciFrBuffer); + if(Device.RCode != 0 ) printk("PCI: I/O Error %s",PciFrBuffer); + } + } + return Device.RCode; +} +int iSeries_pci_read_config_word( struct pci_dev* PciDev, int Offset, u16* ValuePtr) { + iSeries_Device Device; + build_iSeries_Device(&Device, PciDev); + if(Device.BusNumber == 0xFF) Device.RCode = 0x301; /* Trap out invalid bus. */ + else { + Device.RCode = HvCallPci_configLoad16(Device.BusNumber, Device.SubBus, Device.DevFn, Offset, ValuePtr); + if(Device.RCode != 0 || PciTraceFlag > 0) { + sprintf(PciFrBuffer,"RCW: %02X,%02X,%02X,%04X Rtn: %04X,%04X", + Device.BusNumber, Device.SubBus, Device.DevFn, Offset, + Device.RCode, *ValuePtr); + ISERIES_PCI_FR(PciFrBuffer); + if(Device.RCode != 0 ) printk("PCI: I/O Error %s",PciFrBuffer); + } + } + return Device.RCode; +} +int iSeries_pci_read_config_dword( struct pci_dev* PciDev, int Offset, u32* ValuePtr) { + iSeries_Device Device; + build_iSeries_Device(&Device, PciDev); + if(Device.BusNumber == 0xFF) Device.RCode = 0x301; /* Trap out invalid bus. */ + else { + Device.RCode = HvCallPci_configLoad32(Device.BusNumber, Device.SubBus, Device.DevFn, Offset, ValuePtr); + if(Device.RCode != 0 || PciTraceFlag > 0) { + sprintf(PciFrBuffer,"RCL: %02X,%02X,%02X,%04X Rtn: %04X,%08X", + Device.BusNumber, Device.SubBus, Device.DevFn, Offset, + Device.RCode, *ValuePtr); + ISERIES_PCI_FR(PciFrBuffer); + if(Device.RCode != 0 ) printk("PCI: I/O Error %s",PciFrBuffer); + } + } + return Device.RCode; +} +int iSeries_pci_write_config_byte( struct pci_dev* PciDev, int Offset, u8 Value) { + iSeries_Device Device; + build_iSeries_Device(&Device, PciDev); + if(Device.BusNumber == 0xFF) Device.RCode = 0x301; /* Trap out invalid bus. */ + else { + Device.RCode = HvCallPci_configStore8(Device.BusNumber, Device.SubBus, Device.DevFn, Offset, Value); + if(Device.RCode != 0 || PciTraceFlag > 0) { + sprintf(PciFrBuffer,"WCB: %02X,%02X,%02X,%04X Rtn: %04X,%02X", + Device.BusNumber, Device.SubBus, Device.DevFn, Offset, + Device.RCode, Value); + ISERIES_PCI_FR(PciFrBuffer); + if(Device.RCode != 0 ) printk("PCI: I/O Error %s",PciFrBuffer); + } + } + return Device.RCode; +} +int iSeries_pci_write_config_word( struct pci_dev* PciDev, int Offset, u16 Value) { + iSeries_Device Device; + build_iSeries_Device(&Device, PciDev); + if(Device.BusNumber == 0xFF) Device.RCode = 0x301; /* Trap out invalid bus. */ + else { + Device.RCode = HvCallPci_configStore16(Device.BusNumber, Device.SubBus, Device.DevFn, Offset, Value); + if(Device.RCode != 0 || PciTraceFlag > 0) { + sprintf(PciFrBuffer,"WCW: %02X,%02X,%02X,%04X Rtn: %04X,%04X", + Device.BusNumber, Device.SubBus, Device.DevFn, Offset, + Device.RCode, Value); + ISERIES_PCI_FR(PciFrBuffer); + if(Device.RCode != 0 ) printk("PCI: I/O Error %s",PciFrBuffer); + } + } + return Device.RCode; +} +int iSeries_pci_write_config_dword(struct pci_dev* PciDev, int Offset, u32 Value) { + iSeries_Device Device; + build_iSeries_Device(&Device, PciDev); + if(Device.BusNumber == 0xFF) Device.RCode = 0x301; /* Trap out invalid bus. */ + else { + Device.RCode = HvCallPci_configStore32(Device.BusNumber, Device.SubBus, Device.DevFn, Offset, Value); + if(Device.RCode != 0 || PciTraceFlag > 0) { + sprintf(PciFrBuffer,"WCL: %02X,%02X,%02X,%04X Rtn: %04X,%08X", + Device.BusNumber, Device.SubBus, Device.DevFn, Offset, + Device.RCode, Value); + ISERIES_PCI_FR(PciFrBuffer); + if(Device.RCode != 0 ) printk("PCI: I/O Error %s",PciFrBuffer); + } + } + return Device.RCode; +} +/************************************************************************/ +/* Branch Table */ +/************************************************************************/ +struct pci_ops iSeries_pci_ops = { + iSeries_pci_read_config_byte, + iSeries_pci_read_config_word, + iSeries_pci_read_config_dword, + iSeries_pci_write_config_byte, + iSeries_pci_write_config_word, + iSeries_pci_write_config_dword +}; + +/************************************************************************/ +/* Dump the device info into the Flight Recorder */ +/* Call should have 3 char text to prefix FR Entry */ +/************************************************************************/ +void iSeries_DumpDevice(char* Text, iSeries_Device* Device) { + sprintf(PciFrBuffer,"%s:%02X%02X%02X %04X",Text,Device->BusNumber,Device->SubBus,Device->DevFn,Device->RCode); + ISERIES_PCI_FR(PciFrBuffer); + if(Device->BarNumber != 0xFF) { + sprintf(PciFrBuffer,"BAR:%02X %04X ",Device->BarNumber,Device->BarOffset); + ISERIES_PCI_FR(PciFrBuffer); + } + if(Device->RCode != 0) { + /*****************************************************************/ + /* PCI I/O ERROR RDL: Bus: 0x01 Device: 0x06 ReturnCode: 0x000B */ + /*****************************************************************/ + printk("PCI: I/O ERROR %s: Bus: 0x%02X Device: 0x%02X ReturnCode: 0x%04X\n", + Text,Device->PciDevPtr->bus->number,Device->PciDevPtr->devfn,Device->RCode); + } +} + +int IoCounts = 0; +int RetryCounts = 0; +int IoRetry = 0; + +/************************************************************************ + * Check Return Code + * -> On Failure, print and log information. + * Increment Retry Count, if exceeds max, panic partition. + * -> If in retry, print and log success + ************************************************************************ + * PCI: ReadL: I/O Error( 0): 0x1234 + * PCI: Device..: 17:38.10 Bar: 0x00 Offset 0018 + * PCI: Device..: 17:38.10 Retry( 1) Operation ReadL: + * PCI: Retry Successful on Device: 17:38.10 + ************************************************************************/ +int CheckReturnCode(char* TextHdr, iSeries_Device* Device) { + ++IoCounts; + if(Device->RCode != 0) { + + sprintf(PciFrBuffer,"%s: I/O Error(%2d): 0x%04X\n", TextHdr, IoRetry,Device->RCode); + ISERIES_PCI_FR(PciFrBuffer); + printk("PCI: %s",PciFrBuffer); + + sprintf(PciFrBuffer,"Device..: %02X:%02X.%02X Bar: 0x%02X Offset %04X\n", + Device->BusNumber, Device->SubBus, Device->DevFn, + Device->BarNumber, Device->BarOffset); + ISERIES_PCI_FR(PciFrBuffer); + printk("PCI: %s",PciFrBuffer); + + /* Bump the retry and check for max. */ + ++RetryCounts; + ++IoRetry; + + /* Retry Count exceeded or RIO Bus went down. */ + if(IoRetry > 7 || Device->RCode == 0x206) { + mf_displaySrc(0xB6000103); + panic_timeout = 0; + panic("PCI: Hardware I/O Error, SRC B6000103, Automatic Reboot Disabled."); + } + else { + sprintf(PciFrBuffer,"Device..: %02X:%02X.%02X Retry(%2d) Operation: %s\n", + Device->BusNumber, Device->SubBus, Device->DevFn, + IoRetry,TextHdr); + ISERIES_PCI_FR(PciFrBuffer); + printk("PCI: %s\n",PciFrBuffer); + } + } + else { + if(IoRetry > 0 ) { + sprintf(PciFrBuffer,"Retry Successful on Device: %02X:%02X.%02X\n", + Device->BusNumber, Device->SubBus, Device->DevFn); + ISERIES_PCI_FR(PciFrBuffer); + printk("PCI: %s\n",PciFrBuffer); + } + } + return Device->RCode; +} + +/************************************************************************/ +/* Read MM I/O Instructions for the iSeries */ +/* On MM I/O error, all ones are returned and iSeries_pci_IoError is cal*/ +/* else, data is returned in big Endian format. */ +/************************************************************************/ +/* iSeries_Readb = Read Byte ( 8 bit) */ +/* iSeries_Readw = Read Word (16 bit) */ +/* iSeries_Readl = Read Long (32 bit) */ +/************************************************************************/ +u8 iSeries_Readb(u32* IoAddress) { + iSeries_Device Device; + u8 IoData; + u8 Data = -1; + IoRetry = 0; + if(build_iSeries_Device_From_IoAddress(&Device, IoAddress) == 0) { + do { + Device.RCode = HvCallPci_barLoad8 (Device.BusNumber, Device.SubBus,Device.DevFn, + Device.BarNumber, Device.BarOffset, &IoData); + Data = IoData; + if(Device.RCode != 0) CheckReturnCode("ReadB",&Device); + } while(Device.RCode != 0); + } + return Data; +} +u16 iSeries_Readw(u32* IoAddress) { + iSeries_Device Device; + u16 IoData; + u16 Data = -1; + IoRetry = 0; + if(build_iSeries_Device_From_IoAddress(&Device, IoAddress) == 0) { + do { + Device.RCode = HvCallPci_barLoad16(Device.BusNumber, Device.SubBus,Device.DevFn, + Device.BarNumber, Device.BarOffset, &IoData); + Data = swab16(IoData); + if(Device.RCode != 0) CheckReturnCode("ReadW",&Device); + } while(Device.RCode != 0); + } + return Data; +} +u32 iSeries_Readl(u32* IoAddress) { + iSeries_Device Device; + u32 Data = -1; + u32 IoData; + IoRetry = 0; + if(build_iSeries_Device_From_IoAddress(&Device, IoAddress) == 0) { + IoRetry = 0; + do { + Device.RCode = HvCallPci_barLoad32(Device.BusNumber, Device.SubBus,Device.DevFn, + Device.BarNumber, Device.BarOffset, &IoData); + Data = swab32(IoData); + if(Device.RCode != 0) CheckReturnCode("ReadL",&Device); + } while(Device.RCode != 0); + } + return Data; +} +/************************************************************************/ +/* Write MM I/O Instructions for the iSeries */ +/* On MM I/O error, iSeries_pci_IoError is called */ +/* Data is in big Endian format. */ +/************************************************************************/ +/* iSeries_Writeb = Write Byte (8 bit) */ +/* iSeries_Writew = Write Word(16 bit) */ +/* iSeries_Writel = Write Long(32 bit) */ +/************************************************************************/ +void iSeries_Writeb(u8 Data,u32* IoAddress) { + iSeries_Device Device; + u8 IoData = Data; + IoRetry = 0; + if(build_iSeries_Device_From_IoAddress(&Device, IoAddress) == 0) { + do { + Device.RCode = HvCallPci_barStore8 (Device.BusNumber, Device.SubBus,Device.DevFn, + Device.BarNumber, Device.BarOffset, IoData); + if(Device.RCode != 0) CheckReturnCode("WrteB",&Device); + } while(Device.RCode != 0); + } +} +void iSeries_Writew(u16 Data,u32* IoAddress) { + iSeries_Device Device; + u16 IoData = swab16(Data); + IoRetry = 0; + if(build_iSeries_Device_From_IoAddress(&Device, IoAddress) == 0) { + do { + Device.RCode = HvCallPci_barStore16(Device.BusNumber, Device.SubBus,Device.DevFn, + Device.BarNumber, Device.BarOffset, IoData); + if(Device.RCode != 0) CheckReturnCode("WrteW",&Device); + } while(Device.RCode != 0); + } +} +void iSeries_Writel(u32 Data,u32* IoAddress) { + iSeries_Device Device; + u32 IoData = swab32(Data); + IoRetry = 0; + if(build_iSeries_Device_From_IoAddress(&Device, IoAddress) == 0) { + do { + Device.RCode = HvCallPci_barStore32(Device.BusNumber, Device.SubBus,Device.DevFn, + Device.BarNumber, Device.BarOffset, IoData); + if(Device.RCode != 0) CheckReturnCode("WrteL",&Device); + } while(Device.RCode != 0); + } +} +/************************************************************************/ +/* iSeries I/O Remap */ +/* -> Check to see if one of ours */ +/* -> If not, return null to help find the bug. */ +/************************************************************************/ +void* iSeries_ioremap (unsigned long offset, unsigned long size) { + if(iSeries_xlateIoMmAddress((u32*)offset) != 0) { + return (void*)offset; + } + else { + return NULL; + } +} +/************************************************************************/ +/* Routine to build the iSeries_Device for the pci device. */ +/************************************************************************/ +void build_iSeries_Device(iSeries_Device* Device, struct pci_dev* DevPtr) { + Device->PciDevPtr = DevPtr; + Device->BusNumber = ISERIES_GET_LPAR_BUS(DevPtr->bus->number); + if(ISERIES_GET_LPAR_SUBBUS(DevPtr->bus->number) == 0) { + Device->SubBus = ISERIES_DEVFN_DECODE_SUBBUS(DevPtr->devfn); + Device->DevFn = 0x10 | ISERIES_DECODE_FUNCTION(DevPtr->devfn); + } + else { + Device->SubBus = ISERIES_GET_LPAR_SUBBUS(DevPtr->bus->number); + Device->DevFn = ISERIES_44_FORMAT(DevPtr->devfn); + } + Device->BarNumber = 0xFF; + Device->BarOffset = 0; + Device->RCode = 0; +} +/************************************************************************/ +/* Routine to build the iSeries_Device for the IoAddress. */ +/************************************************************************/ +int build_iSeries_Device_From_IoAddress(iSeries_Device* Device, u32* IoAddress) { + Device->PciDevPtr = iSeries_xlateIoMmAddress(IoAddress); + if(Device->PciDevPtr != 0) { /* Valid pci_dev? */ + build_iSeries_Device(Device,Device->PciDevPtr); + Device->BarNumber = iSeries_IoMmTable_Bar(IoAddress); + if( Device->BarNumber != 0xFF) { + Device->BarOffset = iSeries_IoMmTable_BarOffset(IoAddress); + return 0; + } + else { + sprintf(PciFrBuffer,"I/O BAR Address: 0x%08X",(int)IoAddress); + ISERIES_PCI_FR(PciFrBuffer); + printk("PCI: Invalid I/O Address 0x%08X\n",(int)IoAddress); + return -1; + } + } + printk("PCI: Invalid I/O Address 0x%08X\n",(int)IoAddress); + return -1; +} +/************************************************************************/ +/* Returns the iSeries bus value */ +/************************************************************************/ +u8 iSeries_Get_Bus(struct pci_dev* DevPtr) { + return iSeries_GlobalBusMap[DevPtr->bus->number][_HVBUSNUMBER_]; +} +/************************************************************************/ +/* Returns the iSeries subbus value */ +/************************************************************************/ +u8 iSeries_Get_SubBus(struct pci_dev* DevPtr) { + u8 SubBus = iSeries_GlobalBusMap[DevPtr->bus->number][_HVSUBBUSNUMBER_]; + if (SubBus == 0xFF) SubBus = 0xFF; + else if(SubBus == 0) SubBus = ISERIES_DEVFN_DECODE_SUBBUS(DevPtr->devfn); + else SubBus = ISERIES_GET_LPAR_SUBBUS(DevPtr->bus->number); + return SubBus; +} +/************************************************************************/ +/* Returns the iSeries Device and Function Number */ +/************************************************************************/ +u8 iSeries_Get_DevFn(struct pci_dev* DevPtr) { + u8 SubBus = iSeries_GlobalBusMap[DevPtr->bus->number][_HVSUBBUSNUMBER_]; + u8 DevFn; + if (SubBus == 0xFF) DevFn = 0; + else if(SubBus == 0) DevFn = 0x10 | ISERIES_DECODE_FUNCTION(DevPtr->devfn); + else DevFn = ISERIES_44_FORMAT(DevPtr->devfn); + return DevFn; +} + +/************************************************************************/ +/* This is provides the mapping from the Linux bus and devfn to ISeries */ +/* Bus and Subbus. */ +/* Initialize to all FFs, translations will fail if FF entry found. */ +/************************************************************************/ +u8 iSeries_GlobalBusMap[256][2]; /* Global Bus Mapping */ +void __init iSeries_Initialize_GlobalBusMap(void) { + int Index; + for(Index = 0; Index < 256; ++Index) { + iSeries_GlobalBusMap[Index][_HVBUSNUMBER_] = 0xFF; + iSeries_GlobalBusMap[Index][_HVSUBBUSNUMBER_] = 0xFF; + } + ISERIES_PCI_FR("IntGlobalBusMap"); +} +/************************************************************************/ +/* Create the Flight Recorder */ +/************************************************************************/ +FlightRecorder PciFlightRecorder; /* Pci Flight Recorder */ +FlightRecorder* PciFr; /* Pointer to Fr */ +char PciFrBufferData[128]; /* Working buffer */ +char* PciFrBuffer; /* Pointer to buffer */ +int PciTraceFlag = 0; /* Trace Level Flag */ +struct pci_dev* PciDeviceTrace; /* Device Tracing */ + +void __init iSeries_Initialize_FlightRecorder(void) { + PciFr = &PciFlightRecorder; + PciFrBuffer = &PciFrBufferData[0]; + iSeries_Fr_Initialize(PciFr, "PciFlightRecord"); + ISERIES_PCI_FR("August 10,2001."); + PciTraceFlag = 0; +} +/************************************************************************/ +/* Function to turn on and off the Flight Recorder Trace Flag */ +/************************************************************************/ +int iSeries_Set_PciTraceFlag(int TraceFlag) { + int TempFlag = PciTraceFlag; + PciTraceFlag = TraceFlag; + return TempFlag; +} +int iSeries_Get_PciTraceFlag(void) { + return PciTraceFlag; +} +void iSeries_Set_PciFilter(struct pci_dev* PciDevice) { + PciDeviceTrace = PciDevice; +} +/************************************************************************/ +/* Initialize the I/O Tables and maps */ +/************************************************************************/ +void __init iSeries_pci_Initialize(void) { + iSeries_Initialize_FlightRecorder(); /* Flight Recorder 1st. */ + iSeries_Initialize_GlobalBusMap(); /* Global Bus Map */ + iSeries_IoMmTable_Initialize(); /* Io Translate table. */ + iSeries_proc_callback(&iSeries_pci_proc_init); + iSeries_Set_PciErpFlag(4); /* Erp Level set to 4 */ +} + +/************************************************************************/ +/* Erp level when PCI I/O Errors are detected. */ +/* 0 = Be quiet about the errors. */ +/* 1 >= Log error information and continue on. */ +/* 2 = Printk the error information and continue on. */ +/* 3 = Printk the error information and put task to sleep. */ +/* 4 = Printk the error information and panic the kernel with no reboo*/ +/************************************************************************/ +int iSeries_pci_ErpLevel = 0; +/************************************************************************/ +/* Allows clients to set the Erp State */ +/************************************************************************/ +int iSeries_Set_PciErpFlag(int ErpFlag) { + int SavedState = iSeries_pci_ErpLevel; + printk("PCI: PciERPFlag set to %d.\n", ErpFlag); + iSeries_pci_ErpLevel = ErpFlag; + return SavedState; +} +extern int panic_timeout; /* Panic Timeout reference */ +/************************************************************************/ +/* Fatal I/O Error, crash the system. */ +/* PCI: Fatal I/O Error, Device 00/00, Error 0x0000, Status Reg 0x0000 */ +/* PCI: Kernel Panic called with reboot disabled. */ +/************************************************************************/ +void iSeries_pci_IoError(char* OpCode,iSeries_Device* Device) { + char DeviceInfo[128]; + char ErrorInfo[128]; + struct pci_dev* PciDev = Device->PciDevPtr; + + sprintf(ErrorInfo,"I/O Error Detected. Op: %s, Bus%3d, Device%3d Error: 0x%04X\n", + OpCode,PciDev->bus->number, PCI_SLOT(PciDev->devfn),Device->RCode); + iSeries_Device_Information(PciDev,DeviceInfo,128); + + /* Log the error in the flight recorder */ + if(iSeries_pci_ErpLevel > 0) { + if( Device->RCode != 0x0102) { /* Previous error */ + ISERIES_PCI_FR(ErrorInfo); + ISERIES_PCI_FR(DeviceInfo); + } + } + if(iSeries_pci_ErpLevel > 1) { + printk("PCI: %s",ErrorInfo); + printk("PCI: %s\n",DeviceInfo); + } + if(iSeries_pci_ErpLevel == 3) { + printk("PCI: Current process 0x%08X put to sleep for debug.\n",current->pid); + { + DECLARE_WAITQUEUE(WaitQueue, current); + add_wait_queue(¤t->wait_chldexit,&WaitQueue); + current->state = TASK_INTERRUPTIBLE; + schedule(); + current->state = TASK_RUNNING; + remove_wait_queue(¤t->wait_chldexit,&WaitQueue); + } + } + else if(iSeries_pci_ErpLevel == 4) { + mf_displaySrc(0xB6000103); + panic_timeout = 0; /* Don't reboot. */ + /* printk("PCI: Hardware I/O Error, SRC B6000103, Kernel Panic called.\n");*/ + /* panic("Automatic Reboot Disabled.") */ + panic("PCI: Hardware I/O Error, SRC B6000103, Automatic Reboot Disabled."); + } +} + +/************************************************************************/ +/* I/0 Memory copy MUST use mmio commands on iSeries */ +/************************************************************************/ +void* iSeries_memcpy_toio(void *dest, void *source, int n) +{ + char *dst = dest; + char *src = source; + + while (n--) { + writeb (*src++, dst++); + } + + return dest; +} + +void* iSeries_memcpy_fromio(void *dest, void *source, int n) +{ + char *dst = dest; + char *src = source; + + while (n--) + *dst++ = readb (src++); + + return dest; +} diff --git a/arch/ppc/iSeries/iSeries_pci.h b/arch/ppc/iSeries/iSeries_pci.h new file mode 100644 index 000000000000..00e7569787c6 --- /dev/null +++ b/arch/ppc/iSeries/iSeries_pci.h @@ -0,0 +1,139 @@ +#ifdef CONFIG_PPC_ISERIES +#ifndef _ISERIES_PCI_H +#define _ISERIES_PCI_H +/************************************************************************/ +/* File iSeries_pci.h created by Allan Trautman on Tue Jan 9 2001. */ +/************************************************************************/ +/* Define some useful macros for the iseries pci routines. */ +/* Copyright (C) 20yy Allan H Trautman, IBM Corporation */ +/* */ +/* This program is free software; you can redistribute it and/or modify */ +/* it under the terms of the GNU General Public License as published by */ +/* the Free Software Foundation; either version 2 of the License, or */ +/* (at your option) any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, */ +/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ +/* GNU General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU General Public License */ +/* along with this program; if not, write to the: */ +/* Free Software Foundation, Inc., */ +/* 59 Temple Place, Suite 330, */ +/* Boston, MA 02111-1307 USA */ +/************************************************************************/ +/* Change Activity: */ +/* Created December 28, 2000 */ +/* Converted to iseries_pci.h Jan 25, 2001 */ +/* End Change Activity */ +/************************************************************************/ +#include <linux/config.h> +#include <asm/iSeries/HvTypes.h> +#include <asm/iSeries/iSeries_FlightRecorder.h> +#include <asm/iSeries/iSeries_pci.h> + +/************************************************************************************/ +/* Define some useful macros. */ +/* These macros started with Wayne, Al renamed and refined. */ +/************************************************************************************/ +/* Encodes SubBus address(seddddfff), Works only for bridges under EADS 1 and 2. */ +/************************************************************************************/ +/* #define ISERIES_ENCODE_SUBBUS(eads, bridge, device) \ + (0x80 | ((eads-1 & 0x01) << 6) | ((bridge & 0x0F) << 3) | (device & 0x07)) */ +#define ISERIES_ENCODE_SUBBUS(e, ef, df) (((0x80 | ((e&0x02)<<5) | ((ef & 0x07)<<3)) & 0xF8) | (df & 0x03)) // Al - Please Review + +/************************************************************************************/ +/* Combines IdSel and Function into Iseries 4.4 format */ +/* For Linux, see PCI_DEVFN(slot,func) in include/linux/pci.h */ +/************************************************************************************/ +// #define ISERIES_PCI_AGENTID(idsel,func) ((idsel & 0x0F) << 4) | (func & 0x07) +#define ISERIES_PCI_AGENTID(idsel,func) (((idsel & 0x0F) << 4) | (func & 0x0F)) // Al - Please Review + +/************************************************************************************/ +/* Converts DeviceFunction from Linux 5.3(dddddfff) to Iseries 4.4(dddd0fff) */ +/* Converts DeviceFunction from Iseries 4.4(dddd0fff) to Linux 5.3(dddddfff) */ +/************************************************************************************/ +#define ISERIES_44_FORMAT(devfn53) (((devfn53 & 0xF8) << 1) | (devfn53 & 0x07)) +#define ISERIES_53_FORMAT(devfn44) (((devfn44 & 0xF0) >> 1) | (devfn44 & 0x07)) + +/************************************************************************************/ +/* Tests for encoded subbus. */ +/************************************************************************************/ +#define ISERIES_IS_SUBBUS_ENCODED_IN_DEVFN(devfn) ((devfn & 0x80) == 0x80) + +/************************************************************************************/ +/* Decodes the Iseries subbus to devfn, ONLY Works for bus 0!! Use Table lookup. */ +/************************************************************************************/ +/* #define ISERIES_DEVFN_DECODE_SUBBUS(devfn) \ + ((((devfn & 0x40) >> 1) + 0x20) | ((devfn >> 1) & 0x1C)) */ +#define ISERIES_DEVFN_DECODE_SUBBUS(devfn) (((((devfn >> 6 ) & 0x1) + 1) << 5) | (((devfn >> 3) & 0x7) << 2)) // Al - Please Review + +/************************************************************************************/ +/* Decodes Linux DevFn to Iseries DevFn, bridge device, or function. */ +/* For Linux, see PCI_SLOT and PCI_FUNC in include/linux/pci.h */ +/************************************************************************************/ +#define ISERIES_DECODE_DEVFN(linuxdevfn) (((linuxdevfn & 0x71) << 1) | (linuxdevfn & 0x07)) +#define ISERIES_DECODE_DEVICE(linuxdevfn) (((linuxdevfn & 0x38) >> 3) |(((linuxdevfn & 0x40) >> 2) + 0x10)) +#define ISERIES_DECODE_FUNCTION(linuxdevfn) (linuxdevfn & 0x07) + +#define ISERIES_GET_DEVICE_FROM_SUBBUS(subbus) ((subbus >> 5) & 0x7) +#define ISERIES_GET_FUNCTION_FROM_SUBBUS(subbus) ((subbus >> 2) & 0x7) +#define ISERIES_GET_HOSE_HV_BUSNUM(hose) (((struct iSeries_hose_arch_data *)(hose->arch_data))->hvBusNumber) + +/************************************************************************************/ +/* Retreives Iseries Bus and SubBus from GlobalBusMap */ +/************************************************************************************/ +#define ISERIES_GET_LPAR_BUS(linux_bus) iSeries_GlobalBusMap[linux_bus][_HVBUSNUMBER_] +#define ISERIES_GET_LPAR_SUBBUS(linux_bus) iSeries_GlobalBusMap[linux_bus][_HVSUBBUSNUMBER_] + +#define ISERIES_ADD_BUS_GLOBALBUSMAP(linuxbus, iseriesbus, iseriessubbus) \ + iSeries_GlobalBusMap[linuxbus][_HVBUSNUMBER_] = iseriesbus; \ + iSeries_GlobalBusMap[linuxbus][_HVSUBBUSNUMBER_] = iseriessubbus; + +/************************************************************************************/ +/* Global Bus map */ +/* Bus and Subbus index values into the global bus number map array. */ +/************************************************************************************/ +#define ISERIES_GLOBALBUSMAP_SIZE 256 +#define _HVBUSNUMBER_ 0 +#define _HVSUBBUSNUMBER_ 1 +extern u8 iSeries_GlobalBusMap[ISERIES_GLOBALBUSMAP_SIZE][2]; +void iSeries_Initialize_GlobalBusMap(void); +#define pci_assign_all_buses() 1 // Al - NEW + +/************************************************************************************/ +/* Converts Virtual Address to Real Address for Hypervisor calls */ +/************************************************************************************/ +#define REALADDR(virtaddr) (0x8000000000000000 | (virt_to_absolute((u32)virtaddr) )) + +/************************************************************************************/ +/* Define TRUE and FALSE Values for Al */ +/************************************************************************************/ +#ifndef TRUE +#define TRUE 1 +#endif +#ifndef FALSE +#define FALSE 0 +#endif + +typedef struct pci_dev pciDev; +/************************************************************************/ +/* Routines to build the iSeries_Device for the pci device. */ +/************************************************************************/ +extern void build_iSeries_Device(iSeries_Device* Device, struct pci_dev* DevPtr); +extern int build_iSeries_Device_From_IoAddress(iSeries_Device* Device, u32* IoAddress); +extern void iSeries_pci_Initialize(void); + +/************************************************************************/ +/* Flight Recorder Debug Support */ +/************************************************************************/ +extern int PciTraceFlag; /* Conditional Trace */ +void iSeries_Initialize_FlightRecorder(void); +int iSeries_Set_PciTraceFlag(int Flag); /* Sets flag, return old*/ +int iSeries_Get_PciTraceFlag(void); /* Gets Flag. */ +void iSeries_DumpDevice(char* Text, iSeries_Device* ); + +#endif /* _ISERIES_PCI_H */ +#endif /*CONFIG_PPC_ISERIES */ + diff --git a/arch/ppc/iSeries/iSeries_pci_proc.c b/arch/ppc/iSeries/iSeries_pci_proc.c new file mode 100644 index 000000000000..ee5045b898f7 --- /dev/null +++ b/arch/ppc/iSeries/iSeries_pci_proc.c @@ -0,0 +1,185 @@ +/************************************************************************/ +/* File iSeries pci_proc.c created by Allan Trautman on Feb 27 2001. */ +/************************************************************************/ +/* Create /proc/iSeries/pci file that contains iSeries card location. */ +/* Copyright (C) 20yy <Allan H Trautman> <IBM Corp> */ +/* */ +/* This program is free software; you can redistribute it and/or modify */ +/* it under the terms of the GNU General Public License as published by */ +/* the Free Software Foundation; either version 2 of the License, or */ +/* (at your option) any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, */ +/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ +/* GNU General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU General Public License */ +/* along with this program; if not, write to the: */ +/* Free Software Foundation, Inc., */ +/* 59 Temple Place, Suite 330, */ +/* Boston, MA 02111-1307 USA */ +/************************************************************************/ +/* Change Activity: */ +/* Created, Feb 27, 2001 */ +/* End Change Activity */ +/************************************************************************/ +#include <asm/uaccess.h> +#include <asm/iSeries/iSeries_VpdInfo.h> +#include <asm/iSeries/iSeries_proc.h> +#include <asm/iSeries/iSeries_pci.h> +#include <asm/iSeries/iSeries_FlightRecorder.h> +#include <linux/pci.h> +#include <linux/netdevice.h> + +static struct proc_dir_entry *pci_proc_root = NULL; +static struct proc_dir_entry *pciFr_proc_root = NULL; + +int iSeries_proc_pci_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data); +int iSeries_proc_pci_write_proc(struct file *file, const char *buffer, unsigned long count, void *data); +int iSeries_proc_pciFr_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data); +int iSeries_proc_pciFr_write_proc(struct file *file, const char *buffer, unsigned long count, void *data); + + +void iSeries_pci_proc_init(struct proc_dir_entry *iSeries_proc) { + printk("PCI: Creating /proc/iSeries/pci\n"); + + /* Read = User,Group,Other, Write User */ + pci_proc_root = create_proc_entry("pci", S_IFREG | S_IRUGO | S_IWUSR, iSeries_proc); + if (!pci_proc_root) return; + pci_proc_root->nlink = 1; + pci_proc_root->data = (void *)0; + pci_proc_root->read_proc = iSeries_proc_pci_read_proc; + pci_proc_root->write_proc = iSeries_proc_pci_write_proc; + + /* Read = User,Group,Other, Write User */ + printk("PCI: Creating /proc/iSeries/pciFr\n"); + pciFr_proc_root = create_proc_entry("pciFr", S_IFREG | S_IRUGO | S_IWUSR, iSeries_proc); + if (!pciFr_proc_root) return; + pciFr_proc_root->nlink = 1; + pciFr_proc_root->data = (void *)0; + pciFr_proc_root->read_proc = iSeries_proc_pciFr_read_proc; + pciFr_proc_root->write_proc = iSeries_proc_pciFr_write_proc; +} + +/*******************************************************************************/ +/* Get called when client reads the /proc/iSeries/pci file. The data returned */ +/* is the iSeries card locations for service. */ +/*******************************************************************************/ +int iSeries_proc_pci_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data) { + int LineLen; /* Size of new Data */ + struct pci_dev* PciDev; /* Device pointer */ + struct net_device *dev; /* net_device pointer */ + int DeviceCount; /* Device Number */ + /***************************************************************************/ + /* ### Bus Device Bus Dev Frm Card */ + /* 1. Linux: 0/ 28 iSeries: 24/ 36/ 1/C14 */ + /* 2. Linux: 0/ 30 iSeries: 24/ 38/ 2/C14 */ + /***************************************************************************/ + DeviceCount = 1; /* Count the devices listed. */ + LineLen = 0; /* Reset Length */ + + /***************************************************************************/ + /* List the devices */ + /***************************************************************************/ + pci_for_each_dev(PciDev) { + LineLen += sprintf(page+LineLen,"%3d. ",DeviceCount); + LineLen += iSeries_Device_Information(PciDev,page+LineLen,count-LineLen); + for (dev = dev_base; dev != NULL; dev = dev->next) + { + if (dev->base_addr == PciDev->resource[0].start ) { /* Yep, a net_device */ + LineLen += sprintf(page+LineLen, ", Net device: %s", dev->name); + } /* if */ + } /* for */ + LineLen += sprintf(page+LineLen,"\n"); + ++DeviceCount; /* Add for the list. */ + /************************************************************************/ + /* Run out of room in system buffer. */ + /************************************************************************/ + if(LineLen+80 >= count) { /* Room for another line? No. bail out */ + LineLen +=sprintf(page+LineLen,"/proc/pci file full!\n"); + break; + } + } + /***************************************************************************/ + /* If no devices, tell user that instead */ + /***************************************************************************/ + if(DeviceCount == 1) { + LineLen +=sprintf(page+LineLen,"No PCI devices found\n"); + } + /***************************************************************************/ + /* Update counts and return */ + /***************************************************************************/ + *eof = LineLen; + return LineLen; +} + +/*******************************************************************************/ +/* Do nothing, Nothing to support for the write */ +/*******************************************************************************/ +int iSeries_proc_pci_write_proc(struct file *file, const char *buffer, unsigned long count, void *data) { + return count; +} + +/*******************************************************************************/ +/* Get called when client reads the /proc/iSeries/pci file. The data returned */ +/* is the iSeries card locations for service. */ +/*******************************************************************************/ +int iSeries_proc_pciFr_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data) { + struct pci_dev* PciDev; /* Device pointer */ + int DeviceCount = 1; /* Device Number */ + int LineLen = 0; /* Size of new Data */ + + printk("PCI: Dump Flight Recorder!\n"); + /***************************************************************************/ + /* List the devices */ + /***************************************************************************/ + pci_for_each_dev(PciDev) { + LineLen += sprintf(page+LineLen,"%3d. 0x%08X ",DeviceCount,(int)PciDev); + LineLen += sprintf(page+LineLen,"Bus: %02X, Device: %02X ",PciDev->bus->number,PciDev->devfn); + LineLen += sprintf(page+LineLen,"\n"); + ++DeviceCount; /* Add for the list. */ + } + LineLen += sprintf(page+LineLen,"--\n"); + /***************************************************************************/ + /* The Flight Recorder */ + /* Someday handle wrap */ + /***************************************************************************/ + if (PciFr->StartingPointer != NULL) { + char* StartEntry = (char*)PciFr->StartingPointer; + char* EndEntry = (char*)PciFr->CurrentPointer; + while(EndEntry > StartEntry && LineLen+40 < count) { + LineLen += sprintf(page+LineLen,"%s\n",StartEntry); + StartEntry += strlen(StartEntry) + 1; + } + if(LineLen+40 >= count) { + printk("PCI: Max Count Hit %d and %d\n",LineLen,count); + } + } + /***************************************************************************/ + /* Update counts and return */ + /***************************************************************************/ + printk("PCI: End of File at %d\n",LineLen); + *eof = LineLen; + return LineLen; +} +/*******************************************************************************/ +/* Flight Recorder Controls */ +/*******************************************************************************/ +int iSeries_proc_pciFr_write_proc(struct file *file, const char *buffer, unsigned long count, void *data) { + if(buffer != 0 && strlen(buffer) > 0) { + if( strstr(buffer,"trace on") != NULL) { + iSeries_Set_PciTraceFlag(1); + ISERIES_PCI_FR_DATE("PCI Trace turned on!"); + } + else if(strstr(buffer,"trace off") != NULL) { + iSeries_Set_PciTraceFlag(0); + ISERIES_PCI_FR_DATE("PCI Trace turned off!"); + } + else { + ISERIES_PCI_FR_TIME("PCI Trace Option Invalid!"); + readl(0x00000000); + } + } + return count; +} diff --git a/arch/ppc/iSeries/iSeries_proc.c b/arch/ppc/iSeries/iSeries_proc.c new file mode 100644 index 000000000000..6e0be49bb4c7 --- /dev/null +++ b/arch/ppc/iSeries/iSeries_proc.c @@ -0,0 +1,154 @@ +/* + * iSeries_proc.c + * Copyright (C) 2001 Kyle A. Lucke IBM Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +/* Change Activity: */ +/* End Change Activity */ + +#include <linux/proc_fs.h> +#include <linux/spinlock.h> +#ifndef _ISERIES_PROC_H +#include <asm/iSeries/iSeries_proc.h> +#endif + + +static struct proc_dir_entry * iSeries_proc_root = NULL; +static int iSeries_proc_initializationDone = 0; +static spinlock_t iSeries_proc_lock; + +struct iSeries_proc_registration +{ + struct iSeries_proc_registration *next; + iSeriesProcFunction functionMember; +}; + + +struct iSeries_proc_registration preallocated[16]; +#define MYQUEUETYPE(T) struct MYQueue##T +#define MYQUEUE(T) \ +MYQUEUETYPE(T) \ +{ \ +struct T *head; \ +struct T *tail; \ +} +#define MYQUEUECTOR(q) do { (q)->head = NULL; (q)->tail = NULL; } while(0) +#define MYQUEUEENQ(q, p) \ +do { \ +(p)->next = NULL; \ +if ((q)->head != NULL) \ +{ \ +(q)->head->next = (p); \ +(q)->head = (p); \ +} \ +else \ +{ \ +(q)->tail = (q)->head = (p); \ +} \ +} while(0) + +#define MYQUEUEDEQ(q,p) \ +do { \ +(p) = (q)->tail; \ +if ((p) != NULL) \ +{ \ +(q)->tail = (p)->next; \ +(p)->next = NULL; \ +} \ +if ((q)->tail == NULL) \ +(q)->head = NULL; \ +} while(0) +MYQUEUE(iSeries_proc_registration); +typedef MYQUEUETYPE(iSeries_proc_registration) aQueue; + + +aQueue iSeries_free; +aQueue iSeries_queued; + +void iSeries_proc_early_init(void) +{ + int i = 0; + unsigned long flags; + iSeries_proc_initializationDone = 0; + spin_lock_init(&iSeries_proc_lock); + MYQUEUECTOR(&iSeries_free); + MYQUEUECTOR(&iSeries_queued); + + spin_lock_irqsave(&iSeries_proc_lock, flags); + for (i = 0; i < 16; ++i) + { + MYQUEUEENQ(&iSeries_free, preallocated+i); + } + spin_unlock_irqrestore(&iSeries_proc_lock, flags); +} + +void iSeries_proc_create(void) +{ + unsigned long flags; + struct iSeries_proc_registration *reg = NULL; + spin_lock_irqsave(&iSeries_proc_lock, flags); + printk("iSeries_proc: Creating /proc/iSeries\n"); + + iSeries_proc_root = proc_mkdir("iSeries", 0); + if (!iSeries_proc_root) return; + + MYQUEUEDEQ(&iSeries_queued, reg); + + while (reg != NULL) + { + (*(reg->functionMember))(iSeries_proc_root); + + MYQUEUEDEQ(&iSeries_queued, reg); + } + + iSeries_proc_initializationDone = 1; + spin_unlock_irqrestore(&iSeries_proc_lock, flags); +} + +void iSeries_proc_callback(iSeriesProcFunction initFunction) +{ + unsigned long flags; + spin_lock_irqsave(&iSeries_proc_lock, flags); + + if (iSeries_proc_initializationDone) + { + (*initFunction)(iSeries_proc_root); + } + else + { + struct iSeries_proc_registration *reg = NULL; + + MYQUEUEDEQ(&iSeries_free, reg); + + if (reg != NULL) + { +// printk("Registering %p in reg %p\n", initFunction, reg); + reg->functionMember = initFunction; + + MYQUEUEENQ(&iSeries_queued, reg); + } + else + { + printk("Couldn't get a queue entry\n"); + } + } + + spin_unlock_irqrestore(&iSeries_proc_lock, flags); +} + + diff --git a/arch/ppc/iSeries/iSeries_reset_device.c b/arch/ppc/iSeries/iSeries_reset_device.c new file mode 100644 index 000000000000..8199f9196a5e --- /dev/null +++ b/arch/ppc/iSeries/iSeries_reset_device.c @@ -0,0 +1,196 @@ +/************************************************************************/ +/* File iSeries_reset_device.c created by Allan Trautman on Mar 21 2001.*/ +/************************************************************************/ +/* This code supports the pci interface on the IBM iSeries systems. */ +/* Copyright (C) 20yy <Allan H Trautman> <IBM Corp> */ +/* */ +/* This program is free software; you can redistribute it and/or modify */ +/* it under the terms of the GNU General Public License as published by */ +/* the Free Software Foundation; either version 2 of the License, or */ +/* (at your option) any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, */ +/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ +/* GNU General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU General Public License */ +/* along with this program; if not, write to the: */ +/* Free Software Foundation, Inc., */ +/* 59 Temple Place, Suite 330, */ +/* Boston, MA 02111-1307 USA */ +/************************************************************************/ +/* Change Activity: */ +/* Created, March 20, 2001 */ +/* April 30, 2001, Added return codes on functions. */ +/* End Change Activity */ +/************************************************************************/ +#include <linux/config.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/pci.h> +#include <linux/irq.h> +/************************************************************************/ +/* Arch specific's */ +/************************************************************************/ +#include <asm/io.h> +#include <asm/iSeries/HvCallPci.h> +#include <asm/iSeries/HvTypes.h> +#include <asm/iSeries/mf.h> +#include <asm/iSeries/iSeries_FlightRecorder.h> +#include <asm/iSeries/iSeries_pci.h> +#include "iSeries_pci.h" + +/************************************************************************/ +/* Interface to Reset Device, see .h for parms and flavors. */ +/************************************************************************/ +int iSeries_Device_Reset_NoIrq(struct pci_dev* PciDev) { + return iSeries_Device_Reset(PciDev,0,0,1); +} +int iSeries_Device_Reset_Generic(struct pci_dev* PciDev) { + return iSeries_Device_Reset(PciDev,0,0,0); +} +int iSeries_Device_Reset(struct pci_dev* PciDev, int AssertTime, int DelayTime, int IrqState) { + int RCode = 0; + PciReqsSaveArea* RegSaveArea = NULL; + if(PciDev != 0) { + if(IrqState == 0) disable_irq(PciDev->irq); + RegSaveArea = iSeries_Device_SaveConfigRegs(PciDev); + if(RegSaveArea != NULL) { + RCode = iSeries_Device_ToggleReset(PciDev, AssertTime, DelayTime); + if(RCode == 0) { + RCode = iSeries_Device_RestoreConfigRegs(RegSaveArea); + } + } + else { + RCode = -1; + } + if(IrqState == 0) enable_irq(PciDev->irq); + } + return RCode; +} +/************************************************************************/ +/* Interface to toggle the reset line */ +/* Time is in .1 seconds, need for seconds. */ +/************************************************************************/ +int iSeries_Device_ToggleReset(struct pci_dev* PciDev, int AssertTime, int DelayTime) { + unsigned long AssertDelay = AssertTime; + unsigned long WaitDelay = DelayTime; + u16 Bus = ISERIES_GET_LPAR_BUS(PciDev->bus->number); + u8 Slot = ISERIES_DECODE_DEVICE(PciDev->devfn); + int RCode = 0; + + /* Set defaults */ + if(AssertTime < 5) AssertDelay = 5; /* Default is .5 second */ + if(WaitDelay < 30) WaitDelay = 30; /* Default is 3 seconds */ + + /* Assert reset for time specified */ + AssertDelay *= HZ; /* Convert to ticks. */ + AssertDelay /= 10; /* Adjust to whole count */ + RCode = HvCallPci_setSlotReset(Bus, 0x00, Slot, 1); + set_current_state(TASK_UNINTERRUPTIBLE); /* Only Wait. */ + schedule_timeout(AssertDelay); /* Sleep for the time */ + RCode += HvCallPci_setSlotReset(Bus, 0x00, Slot, 0); + + /* Wait for device to reset */ + WaitDelay *= HZ; /* Ticks */ + WaitDelay /= 10; /* Whole count */ + set_current_state(TASK_UNINTERRUPTIBLE); /* Only Wait. */ + schedule_timeout(WaitDelay); /* Sleep for the time */ + + if(RCode == 0) { + sprintf(PciFrBuffer,"Slot Reset on Bus%3d, Device%3d!\n",Bus, Slot); + } + else { + sprintf(PciFrBuffer,"Slot Reset on Bus%3d, Device%3d Failed! RCode: %04X\n",Bus, Slot, RCode); + } + ISERIES_PCI_FR_TIME(PciFrBuffer); + printk("PCI: %s\n",PciFrBuffer); + return RCode; +} + +/************************************************************************/ +/* Allocates space and save the config registers for a device. */ +/************************************************************************/ +/* Note: This does byte reads so the data may appear byte swapped */ +/* when compared to read word or dword. */ +/* The data returned is a structure and will be freed automatically on */ +/* the restore of the data. The is checking so if the save fails, the */ +/* data will not be restore. Yes I know, you are most likey toast. */ +/************************************************************************/ +PciReqsSaveArea* iSeries_Device_SaveConfigRegs(struct pci_dev* DevPtr) { + int Register = 0; + struct pci_dev* PciDev = DevPtr; + PciReqsSaveArea* RegSaveArea = (PciReqsSaveArea*)kmalloc(sizeof(PciReqsSaveArea), GFP_KERNEL); + /*printk("PCI: Save Configuration Registers. 0x%08X\n",(int)RegSaveArea); */ + if(RegSaveArea == 0) { + printk("PCI: Allocation failure in Save Configuration Registers.\n"); + } + /********************************************************************/ + /* Initialize Area. */ + /********************************************************************/ + else { + RegSaveArea->PciDev = DevPtr; + RegSaveArea->Flags = 0x01; + RegSaveArea->ByteCount = PCI_MAX_LAT+1; /* Number of Bytes */ + RegSaveArea->RCode = 0; + RegSaveArea->FailReg = 0; + /****************************************************************/ + /* Save All the Regs, NOTE: restore skips the first 16 bytes. */ + /****************************************************************/ + for(Register = 0;Register < RegSaveArea->ByteCount && RegSaveArea->RCode == 0; ++Register) { + RegSaveArea->RCode = pci_read_config_byte(PciDev, Register, &RegSaveArea->Regs[Register]); + } + /* Check for error during the save. */ + if(RegSaveArea->RCode != 0) { + printk("PCI: I/O Failure in Save Configuration Registers. 0x%02X, 0x%04X\n", + Register,RegSaveArea->RCode); + RegSaveArea->Flags |= 0x80; /* Ouch Flag. */ + RegSaveArea->FailReg = Register; /* Stuff this way */ + } + } + return RegSaveArea; +} +/************************************************************************/ +/* Restores the registers saved via the save function. See the save */ +/* function for details. */ +/************************************************************************/ +int iSeries_Device_RestoreConfigRegs(PciReqsSaveArea* SaveArea) { + int RCode = 0; + if(SaveArea == 0 || SaveArea->PciDev == 0 || + (SaveArea->Flags & 0x80) == 0x80 || SaveArea->RCode != 0) { + printk("PCI: Invalid SaveArea passed to Restore Configuration Registers. 0x%08X\n",(int)SaveArea); + RCode = -1; + } + else { + int Register; + struct pci_dev* PciDev = SaveArea->PciDev; + /***************************************************************/ + /* Don't touch the Cmd or BIST regs, user must restore those. */ + /* Restore PCI_CACHE_LINE_SIZE & PCI_LATENCY_TIMER */ + /* Restore Saved Regs from 0x10 to 0x3F */ + /***************************************************************/ + pci_write_config_byte(PciDev, PCI_CACHE_LINE_SIZE, SaveArea->Regs[PCI_CACHE_LINE_SIZE]); + pci_write_config_byte(PciDev, PCI_LATENCY_TIMER, SaveArea->Regs[PCI_LATENCY_TIMER]); + + for(Register = PCI_BASE_ADDRESS_0; Register < SaveArea->ByteCount && SaveArea->RCode == 0; ++Register) { + SaveArea->RCode = pci_write_config_byte(PciDev, Register, SaveArea->Regs[Register]); + } + if(SaveArea->RCode != 0) { + printk("PCI: I/O Failure in Restore Configuration Registers %d, %02X\n",Register,SaveArea->RCode); + SaveArea->FailReg = Register; + RCode = SaveArea->RCode; + } + else { + RCode = 0; + } + /***************************************************************/ + /* Is the Auto Free Flag on */ + /***************************************************************/ + if(SaveArea->Flags && 0x01 == 0x01 ) { + /* printk("PCI: Auto Free Register Save Area. 0x%08X\n",(int)SaveArea); */ + kfree(SaveArea); + } + } + return RCode; +} diff --git a/arch/ppc/iSeries/mf.c b/arch/ppc/iSeries/mf.c new file mode 100644 index 000000000000..1f2c19f43319 --- /dev/null +++ b/arch/ppc/iSeries/mf.c @@ -0,0 +1,1211 @@ +/* + * mf.c + * Copyright (C) 2001 Troy D. Armstrong IBM Corporation + * + * This modules exists as an interface between a Linux secondary partition + * running on an iSeries and the primary partition's Virtual Service + * Processor (VSP) object. The VSP has final authority over powering on/off + * all partitions in the iSeries. It also provides miscellaneous low-level + * machine facility type operations. + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <asm/iSeries/mf.h> +#include <linux/types.h> +#include <linux/errno.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/mm.h> +#include <asm/iSeries/HvLpConfig.h> +#include <linux/slab.h> +#include <linux/delay.h> +#include <asm/nvram.h> +#include <asm/time.h> +#include <asm/iSeries/ItSpCommArea.h> +#include <asm/iSeries/mf_proc.h> +#include <asm/iSeries/iSeries_proc.h> +#include <asm/uaccess.h> +#include <linux/pci.h> + + +/* + * This is the structure layout for the Machine Facilites LPAR event + * flows. + */ +struct VspCmdData; +struct CeMsgData; +union SafeCast +{ + u64 ptrAsU64; + void *ptr; +}; + + +typedef void (*CeMsgCompleteHandler)( void *token, struct CeMsgData *vspCmdRsp ); + +struct CeMsgCompleteData +{ + CeMsgCompleteHandler xHdlr; + void *xToken; +}; + +struct VspRspData +{ + struct semaphore *xSemaphore; + struct VspCmdData *xResponse; +}; + +struct IoMFLpEvent +{ + struct HvLpEvent xHvLpEvent; + + u16 xSubtypeRc; + u16 xRsvd1; + u32 xRsvd2; + + union + { + + struct AllocData + { + u16 xSize; + u16 xType; + u32 xCount; + u16 xRsvd3; + u8 xRsvd4; + HvLpIndex xTargetLp; + } xAllocData; + + struct CeMsgData + { + u8 xCEMsg[12]; + char xReserved[4]; + struct CeMsgCompleteData *xToken; + } xCEMsgData; + + struct VspCmdData + { + union SafeCast xTokenUnion; + u16 xCmd; + HvLpIndex xLpIndex; + u8 xRc; + u32 xReserved1; + + union VspCmdSubData + { + struct + { + u64 xState; + } xGetStateOut; + + struct + { + u64 xIplType; + } xGetIplTypeOut, xFunction02SelectIplTypeIn; + + struct + { + u64 xIplMode; + } xGetIplModeOut, xFunction02SelectIplModeIn; + + struct + { + u64 xPage[4]; + } xGetSrcHistoryIn; + + struct + { + u64 xFlag; + } xGetAutoIplWhenPrimaryIplsOut, xSetAutoIplWhenPrimaryIplsIn, xWhiteButtonPowerOffIn, xFunction08FastPowerOffIn, xIsSpcnRackPowerIncompleteOut; + + struct + { + u64 xToken; + u64 xAddressType; + u64 xSide; + u32 xTransferLength; + u32 xOffset; + } xSetKernelImageIn, xGetKernelImageIn, xSetKernelCmdLineIn, xGetKernelCmdLineIn; + + struct + { + u32 xTransferLength; + } xGetKernelImageOut,xGetKernelCmdLineOut; + + + u8 xReserved2[80]; + + } xSubData; + } xVspCmd; + } xUnion; +}; + + +/* + * All outgoing event traffic is kept on a FIFO queue. The first + * pointer points to the one that is outstanding, and all new + * requests get stuck on the end. Also, we keep a certain number of + * preallocated stack elements so that we can operate very early in + * the boot up sequence (before kmalloc is ready). + */ +struct StackElement +{ + struct StackElement * next; + struct IoMFLpEvent event; + MFCompleteHandler hdlr; + char dmaData[72]; + unsigned dmaDataLength; + unsigned remoteAddress; +}; +static spinlock_t spinlock; +static struct StackElement * head = NULL; +static struct StackElement * tail = NULL; +static struct StackElement * avail = NULL; +static struct StackElement prealloc[16]; + +/* + * Put a stack element onto the available queue, so it can get reused. + * Attention! You must have the spinlock before calling! + */ +void free( struct StackElement * element ) +{ + if( element != NULL ) + { + element->next = avail; + avail = element; + } +} + +/* + * Enqueue the outbound event onto the stack. If the queue was + * empty to begin with, we must also issue it via the Hypervisor + * interface. There is a section of code below that will touch + * the first stack pointer without the protection of the spinlock. + * This is OK, because we know that nobody else will be modifying + * the first pointer when we do this. + */ +static int signalEvent( struct StackElement * newElement ) +{ + int rc = 0; + unsigned long flags; + int go = 1; + struct StackElement * element; + HvLpEvent_Rc hvRc; + + /* enqueue the event */ + if( newElement != NULL ) + { + spin_lock_irqsave( &spinlock, flags ); + if( head == NULL ) + head = newElement; + else + { + go = 0; + tail->next = newElement; + } + newElement->next = NULL; + tail = newElement; + spin_unlock_irqrestore( &spinlock, flags ); + } + + /* send the event */ + while( go ) + { + go = 0; + + /* any DMA data to send beforehand? */ + if( head->dmaDataLength > 0 ) + HvCallEvent_dmaToSp( head->dmaData, head->remoteAddress, head->dmaDataLength, HvLpDma_Direction_LocalToRemote ); + + hvRc = HvCallEvent_signalLpEvent(&head->event.xHvLpEvent); + if( hvRc != HvLpEvent_Rc_Good ) + { + printk( KERN_ERR "mf.c: HvCallEvent_signalLpEvent() failed with %d\n", (int)hvRc ); + + spin_lock_irqsave( &spinlock, flags ); + element = head; + head = head->next; + if( head != NULL ) + go = 1; + spin_unlock_irqrestore( &spinlock, flags ); + + if( element == newElement ) + rc = -EIO; + else + { + if( element->hdlr != NULL ) + { + union SafeCast mySafeCast; + mySafeCast.ptrAsU64 = element->event.xHvLpEvent.xCorrelationToken; + (*element->hdlr)( mySafeCast.ptr, -EIO ); + } + } + + spin_lock_irqsave( &spinlock, flags ); + free( element ); + spin_unlock_irqrestore( &spinlock, flags ); + } + } + + return rc; +} + +/* + * Allocate a new StackElement structure, and initialize it. + */ +static struct StackElement * newStackElement( void ) +{ + struct StackElement * newElement = NULL; + HvLpIndex primaryLp = HvLpConfig_getPrimaryLpIndex(); + unsigned long flags; + + if( newElement == NULL ) + { + spin_lock_irqsave( &spinlock, flags ); + if( avail != NULL ) + { + newElement = avail; + avail = avail->next; + } + spin_unlock_irqrestore( &spinlock, flags ); + } + + if( newElement == NULL ) + newElement = kmalloc(sizeof(struct StackElement),GFP_ATOMIC); + + if( newElement == NULL ) + { + printk( KERN_ERR "mf.c: unable to kmalloc %d bytes\n", sizeof(struct StackElement) ); + return NULL; + } + + memset( newElement, 0, sizeof(struct StackElement) ); + newElement->event.xHvLpEvent.xFlags.xValid = 1; + newElement->event.xHvLpEvent.xFlags.xAckType = HvLpEvent_AckType_ImmediateAck; + newElement->event.xHvLpEvent.xFlags.xAckInd = HvLpEvent_AckInd_DoAck; + newElement->event.xHvLpEvent.xFlags.xFunction = HvLpEvent_Function_Int; + newElement->event.xHvLpEvent.xType = HvLpEvent_Type_MachineFac; + newElement->event.xHvLpEvent.xSourceLp = HvLpConfig_getLpIndex(); + newElement->event.xHvLpEvent.xTargetLp = primaryLp; + newElement->event.xHvLpEvent.xSizeMinus1 = sizeof(newElement->event)-1; + newElement->event.xHvLpEvent.xRc = HvLpEvent_Rc_Good; + newElement->event.xHvLpEvent.xSourceInstanceId = HvCallEvent_getSourceLpInstanceId(primaryLp,HvLpEvent_Type_MachineFac); + newElement->event.xHvLpEvent.xTargetInstanceId = HvCallEvent_getTargetLpInstanceId(primaryLp,HvLpEvent_Type_MachineFac); + + return newElement; +} + +static int signalVspInstruction( struct VspCmdData *vspCmd ) +{ + struct StackElement * newElement = newStackElement(); + int rc = 0; + struct VspRspData response; + DECLARE_MUTEX_LOCKED(Semaphore); + response.xSemaphore = &Semaphore; + response.xResponse = vspCmd; + + if( newElement == NULL ) + rc = -ENOMEM; + else + { + newElement->event.xHvLpEvent.xSubtype = 6; + newElement->event.xHvLpEvent.x.xSubtypeData = ('M'<<24)+('F'<<16)+('V'<<8)+('I'<<0); + newElement->event.xUnion.xVspCmd.xTokenUnion.ptr = &response; + newElement->event.xUnion.xVspCmd.xCmd = vspCmd->xCmd; + newElement->event.xUnion.xVspCmd.xLpIndex = HvLpConfig_getLpIndex(); + newElement->event.xUnion.xVspCmd.xRc = 0xFF; + newElement->event.xUnion.xVspCmd.xReserved1 = 0; + memcpy(&(newElement->event.xUnion.xVspCmd.xSubData),&(vspCmd->xSubData), sizeof(vspCmd->xSubData)); + mb(); + + rc = signalEvent(newElement); + } + + if (rc == 0) + { + down(&Semaphore); + } + + return rc; +} + + +/* + * Send a 12-byte CE message to the primary partition VSP object + */ +static int signalCEMsg( char * ceMsg, void * token ) +{ + struct StackElement * newElement = newStackElement(); + int rc = 0; + + if( newElement == NULL ) + rc = -ENOMEM; + else + { + newElement->event.xHvLpEvent.xSubtype = 0; + newElement->event.xHvLpEvent.x.xSubtypeData = ('M'<<24)+('F'<<16)+('C'<<8)+('E'<<0); + memcpy( newElement->event.xUnion.xCEMsgData.xCEMsg, ceMsg, 12 ); + newElement->event.xUnion.xCEMsgData.xToken = token; + rc = signalEvent(newElement); + } + + return rc; +} + +/* + * Send a 12-byte CE message and DMA data to the primary partition VSP object + */ +static int dmaAndSignalCEMsg( char * ceMsg, void * token, void * dmaData, unsigned dmaDataLength, unsigned remoteAddress ) +{ + struct StackElement * newElement = newStackElement(); + int rc = 0; + + if( newElement == NULL ) + rc = -ENOMEM; + else + { + newElement->event.xHvLpEvent.xSubtype = 0; + newElement->event.xHvLpEvent.x.xSubtypeData = ('M'<<24)+('F'<<16)+('C'<<8)+('E'<<0); + memcpy( newElement->event.xUnion.xCEMsgData.xCEMsg, ceMsg, 12 ); + newElement->event.xUnion.xCEMsgData.xToken = token; + memcpy( newElement->dmaData, dmaData, dmaDataLength ); + newElement->dmaDataLength = dmaDataLength; + newElement->remoteAddress = remoteAddress; + rc = signalEvent(newElement); + } + + return rc; +} + +/* + * Initiate a nice (hopefully) shutdown of Linux. We simply are + * going to try and send the init process a SIGINT signal. If + * this fails (why?), we'll simply force it off in a not-so-nice + * manner. + */ +static int shutdown( void ) +{ + int rc = kill_proc(1,SIGINT,1); + + if( rc ) + { + printk( KERN_ALERT "mf.c: SIGINT to init failed (%d), hard shutdown commencing\n", rc ); + mf_powerOff(); + } + else + printk( KERN_ALERT "mf.c: init has been successfully notified to proceed with shutdown\n" ); + + return rc; +} + +/* + * The primary partition VSP object is sending us a new + * event flow. Handle it... + */ +static void intReceived( struct IoMFLpEvent * event ) +{ + int freeIt = 0; + struct StackElement * two = NULL; + /* ack the interrupt */ + event->xHvLpEvent.xRc = HvLpEvent_Rc_Good; + HvCallEvent_ackLpEvent( &event->xHvLpEvent ); + + /* process interrupt */ + switch( event->xHvLpEvent.xSubtype ) + { + case 0: /* CE message */ + switch( event->xUnion.xCEMsgData.xCEMsg[3] ) + { + case 0x5B: /* power control notification */ + if( (event->xUnion.xCEMsgData.xCEMsg[5]&0x20) != 0 ) + { + printk( KERN_ALERT "mf.c: Commencing partition shutdown\n" ); + if( shutdown() == 0 ) + signalCEMsg( "\x00\x00\x00\xDB\x00\x00\x00\x00\x00\x00\x00\x00", NULL ); + } + break; + case 0xC0: /* get time */ + { + if ( (head != NULL) && ( head->event.xUnion.xCEMsgData.xCEMsg[3] == 0x40 ) ) + { + freeIt = 1; + if ( head->event.xUnion.xCEMsgData.xToken != 0 ) + { + CeMsgCompleteHandler xHdlr = head->event.xUnion.xCEMsgData.xToken->xHdlr; + void * token = head->event.xUnion.xCEMsgData.xToken->xToken; + + if (xHdlr != NULL) + (*xHdlr)( token, &(event->xUnion.xCEMsgData) ); + } + } + } + break; + } + + /* remove from queue */ + if ( freeIt == 1 ) + { + unsigned long flags; + spin_lock_irqsave( &spinlock, flags ); + if( head != NULL ) + { + struct StackElement *oldHead = head; + head = head->next; + two = head; + free( oldHead ); + } + spin_unlock_irqrestore( &spinlock, flags ); + } + + /* send next waiting event */ + if( two != NULL ) + signalEvent( NULL ); + break; + case 1: /* IT sys shutdown */ + printk( KERN_ALERT "mf.c: Commencing system shutdown\n" ); + shutdown(); + break; + } +} + +/* + * The primary partition VSP object is acknowledging the receipt + * of a flow we sent to them. If there are other flows queued + * up, we must send another one now... + */ +static void ackReceived( struct IoMFLpEvent * event ) +{ + unsigned long flags; + struct StackElement * two = NULL; + unsigned long freeIt = 0; + + /* handle current event */ + if( head != NULL ) + { + switch( event->xHvLpEvent.xSubtype ) + { + case 0: /* CE msg */ + if( event->xUnion.xCEMsgData.xCEMsg[3] == 0x40 ) + { + if ( event->xUnion.xCEMsgData.xCEMsg[2] != 0 ) + { + freeIt = 1; + if ( head->event.xUnion.xCEMsgData.xToken != 0 ) + { + CeMsgCompleteHandler xHdlr = head->event.xUnion.xCEMsgData.xToken->xHdlr; + void * token = head->event.xUnion.xCEMsgData.xToken->xToken; + + if (xHdlr != NULL) + (*xHdlr)( token, &(event->xUnion.xCEMsgData) ); + } + } + } + else + { + freeIt = 1; + } + break; + case 4: /* allocate */ + case 5: /* deallocate */ + if( head->hdlr != NULL ) + { + union SafeCast mySafeCast; + mySafeCast.ptrAsU64 = event->xHvLpEvent.xCorrelationToken; + (*head->hdlr)( mySafeCast.ptr, event->xUnion.xAllocData.xCount ); + } + freeIt = 1; + break; + case 6: + { + struct VspRspData *rsp = (struct VspRspData *)event->xUnion.xVspCmd.xTokenUnion.ptr; + + if (rsp != NULL) + { + if (rsp->xResponse != NULL) + memcpy(rsp->xResponse, &(event->xUnion.xVspCmd), sizeof(event->xUnion.xVspCmd)); + if (rsp->xSemaphore != NULL) + up(rsp->xSemaphore); + } + else + { + printk( KERN_ERR "mf.c: no rsp\n"); + } + freeIt = 1; + } + break; + } + } + else + printk( KERN_ERR "mf.c: stack empty for receiving ack\n" ); + + /* remove from queue */ + spin_lock_irqsave( &spinlock, flags ); + if(( head != NULL ) && ( freeIt == 1 )) + { + struct StackElement *oldHead = head; + head = head->next; + two = head; + free( oldHead ); + } + spin_unlock_irqrestore( &spinlock, flags ); + + /* send next waiting event */ + if( two != NULL ) + signalEvent( NULL ); +} + +/* + * This is the generic event handler we are registering with + * the Hypervisor. Ensure the flows are for us, and then + * parse it enough to know if it is an interrupt or an + * acknowledge. + */ +static void hvHandler( struct HvLpEvent * event, struct pt_regs * regs ) +{ + if( (event != NULL) && (event->xType == HvLpEvent_Type_MachineFac) ) + { + switch( event->xFlags.xFunction ) + { + case HvLpEvent_Function_Ack: + ackReceived( (struct IoMFLpEvent *)event ); + break; + case HvLpEvent_Function_Int: + intReceived( (struct IoMFLpEvent *)event ); + break; + default: + printk( KERN_ERR "mf.c: non ack/int event received\n" ); + break; + } + } + else + printk( KERN_ERR "mf.c: alien event received\n" ); +} + +/* + * Global kernel interface to allocate and seed events into the + * Hypervisor. + */ +void mf_allocateLpEvents( HvLpIndex targetLp, + HvLpEvent_Type type, + unsigned size, + unsigned count, + MFCompleteHandler hdlr, + void * userToken ) +{ + struct StackElement * newElement = newStackElement(); + int rc = 0; + + if( newElement == NULL ) + rc = -ENOMEM; + else + { + union SafeCast mine; + mine.ptr = userToken; + newElement->event.xHvLpEvent.xSubtype = 4; + newElement->event.xHvLpEvent.xCorrelationToken = mine.ptrAsU64; + newElement->event.xHvLpEvent.x.xSubtypeData = ('M'<<24)+('F'<<16)+('M'<<8)+('A'<<0); + newElement->event.xUnion.xAllocData.xTargetLp = targetLp; + newElement->event.xUnion.xAllocData.xType = type; + newElement->event.xUnion.xAllocData.xSize = size; + newElement->event.xUnion.xAllocData.xCount = count; + newElement->hdlr = hdlr; + rc = signalEvent(newElement); + } + + if( (rc != 0) && (hdlr != NULL) ) + (*hdlr)( userToken, rc ); +} + +/* + * Global kernel interface to unseed and deallocate events already in + * Hypervisor. + */ +void mf_deallocateLpEvents( HvLpIndex targetLp, + HvLpEvent_Type type, + unsigned count, + MFCompleteHandler hdlr, + void * userToken ) +{ + struct StackElement * newElement = newStackElement(); + int rc = 0; + + if( newElement == NULL ) + rc = -ENOMEM; + else + { + union SafeCast mine; + mine.ptr = userToken; + newElement->event.xHvLpEvent.xSubtype = 5; + newElement->event.xHvLpEvent.xCorrelationToken = mine.ptrAsU64; + newElement->event.xHvLpEvent.x.xSubtypeData = ('M'<<24)+('F'<<16)+('M'<<8)+('D'<<0); + newElement->event.xUnion.xAllocData.xTargetLp = targetLp; + newElement->event.xUnion.xAllocData.xType = type; + newElement->event.xUnion.xAllocData.xCount = count; + newElement->hdlr = hdlr; + rc = signalEvent(newElement); + } + + if( (rc != 0) && (hdlr != NULL) ) + (*hdlr)( userToken, rc ); +} + +/* + * Global kernel interface to tell the VSP object in the primary + * partition to power this partition off. + */ +void mf_powerOff( void ) +{ + printk( KERN_ALERT "mf.c: Down it goes...\n" ); + signalCEMsg( "\x00\x00\x00\x4D\x00\x00\x00\x00\x00\x00\x00\x00", NULL ); + for(;;); +} + +/* + * Global kernel interface to tell the VSP object in the primary + * partition to reboot this partition. + */ +void mf_reboot( void ) +{ + printk( KERN_ALERT "mf.c: Preparing to bounce...\n" ); + signalCEMsg( "\x00\x00\x00\x4E\x00\x00\x00\x00\x00\x00\x00\x00", NULL ); + for(;;); +} + +/* + * Display a single word SRC onto the VSP control panel. + */ +void mf_displaySrc( u32 word ) +{ + u8 ce[12]; + + memcpy( ce, "\x00\x00\x00\x4A\x00\x00\x00\x01\x00\x00\x00\x00", 12 ); + ce[8] = word>>24; + ce[9] = word>>16; + ce[10] = word>>8; + ce[11] = word; + signalCEMsg( ce, NULL ); +} + +/* + * Display a single word SRC of the form "PROGXXXX" on the VSP control panel. + */ +void mf_displayProgress( u16 value ) +{ + u8 ce[12]; + u8 src[72]; + + memcpy( ce, "\x00\x00\x04\x4A\x00\x00\x00\x48\x00\x00\x00\x00", 12 ); + memcpy( src, + "\x01\x00\x00\x01" + "\x00\x00\x00\x00" + "\x00\x00\x00\x00" + "\x00\x00\x00\x00" + "\x00\x00\x00\x00" + "\x00\x00\x00\x00" + "\x00\x00\x00\x00" + "\x00\x00\x00\x00" + "\x00\x00\x00\x00" + "\x00\x00\x00\x00" + "PROGxxxx" + " ", + 72 ); + src[6] = value>>8; + src[7] = value&255; + src[44] = "0123456789ABCDEF"[(value>>12)&15]; + src[45] = "0123456789ABCDEF"[(value>>8)&15]; + src[46] = "0123456789ABCDEF"[(value>>4)&15]; + src[47] = "0123456789ABCDEF"[value&15]; + dmaAndSignalCEMsg( ce, NULL, src, sizeof(src), 9*64*1024 ); +} + +/* + * Clear the VSP control panel. Used to "erase" an SRC that was + * previously displayed. + */ +void mf_clearSrc( void ) +{ + signalCEMsg( "\x00\x00\x00\x4B\x00\x00\x00\x00\x00\x00\x00\x00", NULL ); +} + +/* + * Initialization code here. + */ +void mf_init( void ) +{ + int i; + + /* initialize */ + spin_lock_init( &spinlock ); + for( i = 0; i < sizeof(prealloc)/sizeof(*prealloc); ++i ) + free( &prealloc[i] ); + HvLpEvent_registerHandler( HvLpEvent_Type_MachineFac, &hvHandler ); + + /* virtual continue ack */ + signalCEMsg( "\x00\x00\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00", NULL ); + + /* initialization complete */ + printk( KERN_NOTICE "mf.c: iSeries Linux LPAR Machine Facilities initialized\n" ); + + iSeries_proc_callback(&mf_proc_init); +} + +void mf_setSide(char side) +{ + int rc = 0; + u64 newSide = 0; + struct VspCmdData myVspCmd; + + memset(&myVspCmd, 0, sizeof(myVspCmd)); + if (side == 'A') + newSide = 0; + else if (side == 'B') + newSide = 1; + else if (side == 'C') + newSide = 2; + else + newSide = 3; + + myVspCmd.xSubData.xFunction02SelectIplTypeIn.xIplType = newSide; + myVspCmd.xCmd = 10; + + rc = signalVspInstruction(&myVspCmd); +} + +char mf_getSide(void) +{ + char returnValue = ' '; + int rc = 0; + struct VspCmdData myVspCmd; + + memset(&myVspCmd, 0, sizeof(myVspCmd)); + myVspCmd.xCmd = 2; + myVspCmd.xSubData.xFunction02SelectIplTypeIn.xIplType = 0; + mb(); + rc = signalVspInstruction(&myVspCmd); + + if(rc != 0) + { + return returnValue; + } + else + { + if (myVspCmd.xRc == 0) + { + if (myVspCmd.xSubData.xGetIplTypeOut.xIplType == 0) + returnValue = 'A'; + else if (myVspCmd.xSubData.xGetIplTypeOut.xIplType == 1) + returnValue = 'B'; + else if (myVspCmd.xSubData.xGetIplTypeOut.xIplType == 2) + returnValue = 'C'; + else + returnValue = 'D'; + } + } + + return returnValue; +} + +void mf_getSrcHistory(char *buffer, int size) +{ + /* struct IplTypeReturnStuff returnStuff; + struct StackElement * newElement = newStackElement(); + int rc = 0; + char *pages[4]; + + pages[0] = kmalloc(4096, GFP_ATOMIC); + pages[1] = kmalloc(4096, GFP_ATOMIC); + pages[2] = kmalloc(4096, GFP_ATOMIC); + pages[3] = kmalloc(4096, GFP_ATOMIC); + if(( newElement == NULL ) || (pages[0] == NULL) || (pages[1] == NULL) || (pages[2] == NULL) || (pages[3] == NULL)) + rc = -ENOMEM; + else + { + returnStuff.xType = 0; + returnStuff.xRc = 0; + returnStuff.xDone = 0; + newElement->event.xHvLpEvent.xSubtype = 6; + newElement->event.xHvLpEvent.x.xSubtypeData = ('M'<<24)+('F'<<16)+('V'<<8)+('I'<<0); + newElement->event.xUnion.xVspCmd.xEvent = &returnStuff; + newElement->event.xUnion.xVspCmd.xCmd = 4; + newElement->event.xUnion.xVspCmd.xLpIndex = HvLpConfig_getLpIndex(); + newElement->event.xUnion.xVspCmd.xRc = 0xFF; + newElement->event.xUnion.xVspCmd.xReserved1 = 0; + newElement->event.xUnion.xVspCmd.xSubData.xGetSrcHistoryIn.xPage[0] = (0x8000000000000000ULL | virt_to_absolute((unsigned long)pages[0])); + newElement->event.xUnion.xVspCmd.xSubData.xGetSrcHistoryIn.xPage[1] = (0x8000000000000000ULL | virt_to_absolute((unsigned long)pages[1])); + newElement->event.xUnion.xVspCmd.xSubData.xGetSrcHistoryIn.xPage[2] = (0x8000000000000000ULL | virt_to_absolute((unsigned long)pages[2])); + newElement->event.xUnion.xVspCmd.xSubData.xGetSrcHistoryIn.xPage[3] = (0x8000000000000000ULL | virt_to_absolute((unsigned long)pages[3])); + mb(); + rc = signalEvent(newElement); + } + + if(rc != 0) + { + return; + } + else + { + while (returnStuff.xDone != 1) + { + udelay(10); + } + + if (returnStuff.xRc == 0) + { + memcpy(buffer, pages[0], size); + } + } + + kfree(pages[0]); + kfree(pages[1]); + kfree(pages[2]); + kfree(pages[3]);*/ +} + +void mf_setCmdLine(const char *cmdline, int size, u64 side) +{ + struct VspCmdData myVspCmd; + int rc = 0; + dma_addr_t dma_addr = 0; + char *page = pci_alloc_consistent(NULL, size, &dma_addr); + + if (page == NULL) { + printk(KERN_ERR "mf.c: couldn't allocate memory to set command line\n"); + return; + } + + copy_from_user(page, cmdline, size); + + memset(&myVspCmd, 0, sizeof(myVspCmd)); + myVspCmd.xCmd = 31; + myVspCmd.xSubData.xSetKernelCmdLineIn.xToken = dma_addr; + myVspCmd.xSubData.xSetKernelCmdLineIn.xAddressType = HvLpDma_AddressType_TceIndex; + myVspCmd.xSubData.xSetKernelCmdLineIn.xSide = side; + myVspCmd.xSubData.xSetKernelCmdLineIn.xTransferLength = size; + mb(); + rc = signalVspInstruction(&myVspCmd); + + pci_free_consistent(NULL, size, page, dma_addr); +} + +int mf_getCmdLine(char *cmdline, int *size, u64 side) +{ + struct VspCmdData myVspCmd; + int rc = 0; + int len = *size; + dma_addr_t dma_addr = pci_map_single(NULL, cmdline, *size, PCI_DMA_FROMDEVICE); + + memset(cmdline, 0, *size); + memset(&myVspCmd, 0, sizeof(myVspCmd)); + myVspCmd.xCmd = 33; + myVspCmd.xSubData.xGetKernelCmdLineIn.xToken = dma_addr; + myVspCmd.xSubData.xGetKernelCmdLineIn.xAddressType = HvLpDma_AddressType_TceIndex; + myVspCmd.xSubData.xGetKernelCmdLineIn.xSide = side; + myVspCmd.xSubData.xGetKernelCmdLineIn.xTransferLength = *size; + mb(); + rc = signalVspInstruction(&myVspCmd); + + if ( ! rc ) { + + if (myVspCmd.xRc == 0) + { + len = myVspCmd.xSubData.xGetKernelCmdLineOut.xTransferLength; + } + // else + // { + // memcpy(cmdline, "Bad cmdline", 11); + // } + } + + pci_unmap_single(NULL, dma_addr, *size, PCI_DMA_FROMDEVICE); + + return len; +} + + +int mf_setVmlinuxChunk(const char *buffer, int size, int offset, u64 side) +{ + struct VspCmdData myVspCmd; + int rc = 0; + + dma_addr_t dma_addr = 0; + + char *page = pci_alloc_consistent(NULL, size, &dma_addr); + + if (page == NULL) { + printk(KERN_ERR "mf.c: couldn't allocate memory to set vmlinux chunk\n"); + return -ENOMEM; + } + + copy_from_user(page, buffer, size); + memset(&myVspCmd, 0, sizeof(myVspCmd)); + + myVspCmd.xCmd = 30; + myVspCmd.xSubData.xGetKernelImageIn.xToken = dma_addr; + myVspCmd.xSubData.xGetKernelImageIn.xAddressType = HvLpDma_AddressType_TceIndex; + myVspCmd.xSubData.xGetKernelImageIn.xSide = side; + myVspCmd.xSubData.xGetKernelImageIn.xOffset = offset; + myVspCmd.xSubData.xGetKernelImageIn.xTransferLength = size; + mb(); + rc = signalVspInstruction(&myVspCmd); + + if(rc == 0) + { + if (myVspCmd.xRc == 0) + { + rc = 0; + } + else + { + rc = -ENOMEM; + } + } + + pci_free_consistent(NULL, size, page, dma_addr); + + return rc; +} + +int mf_getVmlinuxChunk(char *buffer, int *size, int offset, u64 side) +{ + struct VspCmdData myVspCmd; + int rc = 0; + int len = *size; + + dma_addr_t dma_addr = pci_map_single(NULL, buffer, *size, PCI_DMA_FROMDEVICE); + + memset(buffer, 0, len); + + memset(&myVspCmd, 0, sizeof(myVspCmd)); + myVspCmd.xCmd = 32; + myVspCmd.xSubData.xGetKernelImageIn.xToken = dma_addr; + myVspCmd.xSubData.xGetKernelImageIn.xAddressType = HvLpDma_AddressType_TceIndex; + myVspCmd.xSubData.xGetKernelImageIn.xSide = side; + myVspCmd.xSubData.xGetKernelImageIn.xOffset = offset; + myVspCmd.xSubData.xGetKernelImageIn.xTransferLength = len; + mb(); + rc = signalVspInstruction(&myVspCmd); + + if(rc == 0) + { + if (myVspCmd.xRc == 0) + { + *size = myVspCmd.xSubData.xGetKernelImageOut.xTransferLength; + } + else + { + rc = -ENOMEM; + } + } + + pci_unmap_single(NULL, dma_addr, *size, PCI_DMA_FROMDEVICE); + + return rc; +} + +int mf_setRtcTime(unsigned long time) +{ + struct rtc_time tm; + + to_tm(time, &tm); + + return mf_setRtc( &tm ); +} + +struct RtcTimeData +{ + struct semaphore *xSemaphore; + struct CeMsgData xCeMsg; + int xRc; +}; + +void getRtcTimeComplete(void * token, struct CeMsgData *ceMsg) +{ + struct RtcTimeData *rtc = (struct RtcTimeData *)token; + + memcpy(&(rtc->xCeMsg), ceMsg, sizeof(rtc->xCeMsg)); + + rtc->xRc = 0; + up(rtc->xSemaphore); +} + +static unsigned long lastsec = 1; + +int mf_getRtcTime(unsigned long *time) +{ +// unsigned long usec, tsec; + + u32 dataWord1 = *((u32 *)(&xSpCommArea.xBcdTimeAtIplStart)); + u32 dataWord2 = *(((u32 *)&(xSpCommArea.xBcdTimeAtIplStart)) + 1); + int year = 1970; + int year1 = ( dataWord1 >> 24 ) & 0x000000FF; + int year2 = ( dataWord1 >> 16 ) & 0x000000FF; + int sec = ( dataWord1 >> 8 ) & 0x000000FF; + int min = dataWord1 & 0x000000FF; + int hour = ( dataWord2 >> 24 ) & 0x000000FF; + int day = ( dataWord2 >> 8 ) & 0x000000FF; + int mon = dataWord2 & 0x000000FF; + + BCD_TO_BIN(sec); + BCD_TO_BIN(min); + BCD_TO_BIN(hour); + BCD_TO_BIN(day); + BCD_TO_BIN(mon); + BCD_TO_BIN(year1); + BCD_TO_BIN(year2); + year = year1 * 100 + year2; + + *time = mktime(year, mon, day, hour, min, sec); + + *time += ( jiffies / HZ ); + + // Now THIS is a nasty hack! + // It ensures that the first two calls to mf_getRtcTime get different + // answers. That way the loop in init_time (time.c) will not think + // the clock is stuck. + if ( lastsec ) { + *time -= lastsec; + --lastsec; + } + + return 0; + +} + +int mf_getRtc( struct rtc_time * tm ) +{ + + struct CeMsgCompleteData ceComplete; + struct RtcTimeData rtcData; + int rc = 0; + DECLARE_MUTEX_LOCKED(Semaphore); + + memset(&ceComplete, 0, sizeof(ceComplete)); + memset(&rtcData, 0, sizeof(rtcData)); + + rtcData.xSemaphore = &Semaphore; + + ceComplete.xHdlr = &getRtcTimeComplete; + ceComplete.xToken = (void *)&rtcData; + + rc = signalCEMsg( "\x00\x00\x00\x40\x00\x00\x00\x00\x00\x00\x00\x00", &ceComplete ); + + if ( rc == 0 ) + { + down(&Semaphore); + + if ( rtcData.xRc == 0) + { + if ( ( rtcData.xCeMsg.xCEMsg[2] == 0xa9 ) || + ( rtcData.xCeMsg.xCEMsg[2] == 0xaf ) ) { + /* TOD clock is not set */ + tm->tm_sec = 1; + tm->tm_min = 1; + tm->tm_hour = 1; + tm->tm_mday = 10; + tm->tm_mon = 8; + tm->tm_year = 71; + mf_setRtc( tm ); + } + { + u32 dataWord1 = *((u32 *)(rtcData.xCeMsg.xCEMsg+4)); + u32 dataWord2 = *((u32 *)(rtcData.xCeMsg.xCEMsg+8)); + u8 year = (dataWord1 >> 16 ) & 0x000000FF; + u8 sec = ( dataWord1 >> 8 ) & 0x000000FF; + u8 min = dataWord1 & 0x000000FF; + u8 hour = ( dataWord2 >> 24 ) & 0x000000FF; + u8 day = ( dataWord2 >> 8 ) & 0x000000FF; + u8 mon = dataWord2 & 0x000000FF; + + BCD_TO_BIN(sec); + BCD_TO_BIN(min); + BCD_TO_BIN(hour); + BCD_TO_BIN(day); + BCD_TO_BIN(mon); + BCD_TO_BIN(year); + + if ( year <= 69 ) + year += 100; + + tm->tm_sec = sec; + tm->tm_min = min; + tm->tm_hour = hour; + tm->tm_mday = day; + tm->tm_mon = mon; + tm->tm_year = year; + } + } + else + { + rc = rtcData.xRc; + tm->tm_sec = 0; + tm->tm_min = 0; + tm->tm_hour = 0; + tm->tm_mday = 15; + tm->tm_mon = 5; + tm->tm_year = 52; + + } + tm->tm_wday = 0; + tm->tm_yday = 0; + tm->tm_isdst = 0; + + } + + return rc; + +} + +int mf_setRtc(struct rtc_time * tm) +{ + char ceTime[12] = "\x00\x00\x00\x41\x00\x00\x00\x00\x00\x00\x00\x00"; + int rc = 0; + u8 day, mon, hour, min, sec, y1, y2; + unsigned year; + + year = 1900 + tm->tm_year; + y1 = year / 100; + y2 = year % 100; + + sec = tm->tm_sec; + min = tm->tm_min; + hour = tm->tm_hour; + day = tm->tm_mday; + mon = tm->tm_mon + 1; + + BIN_TO_BCD(sec); + BIN_TO_BCD(min); + BIN_TO_BCD(hour); + BIN_TO_BCD(mon); + BIN_TO_BCD(day); + BIN_TO_BCD(y1); + BIN_TO_BCD(y2); + + ceTime[4] = y1; + ceTime[5] = y2; + ceTime[6] = sec; + ceTime[7] = min; + ceTime[8] = hour; + ceTime[10] = day; + ceTime[11] = mon; + + rc = signalCEMsg( ceTime, NULL ); + + return rc; +} + + + diff --git a/arch/ppc/iSeries/mf_proc.c b/arch/ppc/iSeries/mf_proc.c new file mode 100644 index 000000000000..5a21d4fe01d4 --- /dev/null +++ b/arch/ppc/iSeries/mf_proc.c @@ -0,0 +1,309 @@ +/* + * mf_proc.c + * Copyright (C) 2001 Kyle A. Lucke IBM Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +/* Change Activity: */ +/* End Change Activity */ + +#ifndef _MF_PROC_H +#include <asm/iSeries/mf_proc.h> +#endif +#ifndef MF_H_INCLUDED +#include <asm/iSeries/mf.h> +#endif +#include <asm/uaccess.h> + +static struct proc_dir_entry *mf_proc_root = NULL; + +int proc_mf_dump_cmdline +(char *page, char **start, off_t off, int count, int *eof, void *data); + +int proc_mf_dump_vmlinux +(char *page, char **start, off_t off, int count, int *eof, void *data); + +int proc_mf_dump_side +(char *page, char **start, off_t off, int count, int *eof, void *data); + +int proc_mf_change_side +(struct file *file, const char *buffer, unsigned long count, void *data); + +int proc_mf_dump_src +(char *page, char **start, off_t off, int count, int *eof, void *data); +int proc_mf_change_src (struct file *file, const char *buffer, unsigned long count, void *data); +int proc_mf_change_cmdline(struct file *file, const char *buffer, unsigned long count, void *data); +int proc_mf_change_vmlinux(struct file *file, const char *buffer, unsigned long count, void *data); + + +void mf_proc_init(struct proc_dir_entry *iSeries_proc) +{ + struct proc_dir_entry *ent = NULL; + struct proc_dir_entry *mf_a = NULL; + struct proc_dir_entry *mf_b = NULL; + struct proc_dir_entry *mf_c = NULL; + struct proc_dir_entry *mf_d = NULL; + + mf_proc_root = proc_mkdir("mf", iSeries_proc); + if (!mf_proc_root) return; + + mf_a = proc_mkdir("A", mf_proc_root); + if (!mf_a) return; + + ent = create_proc_entry("cmdline", S_IFREG|S_IRUSR|S_IWUSR, mf_a); + if (!ent) return; + ent->nlink = 1; + ent->data = (void *)0; + ent->read_proc = proc_mf_dump_cmdline; + ent->write_proc = proc_mf_change_cmdline; + + ent = create_proc_entry("vmlinux", S_IFREG|S_IRUSR|S_IWUSR, mf_a); + if (!ent) return; + ent->nlink = 1; + ent->data = (void *)0; + ent->read_proc = proc_mf_dump_vmlinux; + ent->write_proc = proc_mf_change_vmlinux; + + mf_b = proc_mkdir("B", mf_proc_root); + if (!mf_b) return; + + ent = create_proc_entry("cmdline", S_IFREG|S_IRUSR|S_IWUSR, mf_b); + if (!ent) return; + ent->nlink = 1; + ent->data = (void *)1; + ent->read_proc = proc_mf_dump_cmdline; + ent->write_proc = proc_mf_change_cmdline; + + ent = create_proc_entry("vmlinux", S_IFREG|S_IRUSR|S_IWUSR, mf_b); + if (!ent) return; + ent->nlink = 1; + ent->data = (void *)1; + ent->read_proc = proc_mf_dump_vmlinux; + ent->write_proc = proc_mf_change_vmlinux; + + mf_c = proc_mkdir("C", mf_proc_root); + if (!mf_c) return; + + ent = create_proc_entry("cmdline", S_IFREG|S_IRUSR|S_IWUSR, mf_c); + if (!ent) return; + ent->nlink = 1; + ent->data = (void *)2; + ent->read_proc = proc_mf_dump_cmdline; + ent->write_proc = proc_mf_change_cmdline; + + ent = create_proc_entry("vmlinux", S_IFREG|S_IRUSR|S_IWUSR, mf_c); + if (!ent) return; + ent->nlink = 1; + ent->data = (void *)2; + ent->read_proc = proc_mf_dump_vmlinux; + ent->write_proc = proc_mf_change_vmlinux; + + mf_d = proc_mkdir("D", mf_proc_root); + if (!mf_d) return; + + + ent = create_proc_entry("cmdline", S_IFREG|S_IRUSR|S_IWUSR, mf_d); + if (!ent) return; + ent->nlink = 1; + ent->data = (void *)3; + ent->read_proc = proc_mf_dump_cmdline; + ent->write_proc = proc_mf_change_cmdline; + + ent = create_proc_entry("vmlinux", S_IFREG|S_IRUSR, mf_d); + if (!ent) return; + ent->nlink = 1; + ent->data = (void *)3; + ent->read_proc = proc_mf_dump_vmlinux; + ent->write_proc = NULL; + + ent = create_proc_entry("side", S_IFREG|S_IRUSR|S_IWUSR, mf_proc_root); + if (!ent) return; + ent->nlink = 1; + ent->data = (void *)0; + ent->read_proc = proc_mf_dump_side; + ent->write_proc = proc_mf_change_side; + + ent = create_proc_entry("src", S_IFREG|S_IRUSR|S_IWUSR, mf_proc_root); + if (!ent) return; + ent->nlink = 1; + ent->data = (void *)0; + ent->read_proc = proc_mf_dump_src; + ent->write_proc = proc_mf_change_src; + + +} + +int proc_mf_dump_cmdline +(char *page, char **start, off_t off, int count, int *eof, void *data) +{ + int len = count; + char *p; + + len = mf_getCmdLine(page, &len, (u64)(int)data); + + p = page + len - 1; + while ( p > page ) { + if ( (*p == 0) || (*p == ' ') ) + --p; + else + break; + } + if ( *p != '\n' ) { + ++p; + *p = '\n'; + } + ++p; + *p = 0; + len = p - page; + + len -= off; + if (len < count) { + *eof = 1; + if (len <= 0) + return 0; + } else + len = count; + *start = page + off; + return len; +} + +int proc_mf_dump_vmlinux +(char *page, char **start, off_t off, int count, int *eof, void *data) +{ + int sizeToGet = count; + if (!capable(CAP_SYS_ADMIN)) + return -EACCES; + + if (mf_getVmlinuxChunk(page, &sizeToGet, off, (u64)(int)data) == 0) + { + if (sizeToGet != 0) + { + *start = page + off; + printk("mf_proc.c: got count %d off %d\n", sizeToGet, (int)off); + return sizeToGet; + } + else + { + printk("mf_proc.c: eof\n"); + *eof = 1; + return 0; + } + } + else + { + printk("mf_proc.c: eof\n"); + *eof = 1; + return 0; + } +} + + +int proc_mf_dump_side +(char *page, char **start, off_t off, int count, int *eof, void *data) +{ + int len = 0; + + char mf_current_side = mf_getSide(); + len = sprintf(page, "%c\n", mf_current_side); + + if (len <= off+count) *eof = 1; + *start = page + off; + len -= off; + if (len>count) len = count; + if (len<0) len = 0; + return len; +} + +int proc_mf_change_side(struct file *file, const char *buffer, unsigned long count, void *data) +{ + if (!capable(CAP_SYS_ADMIN)) + return -EACCES; + + if ((*buffer != 'A') && + (*buffer != 'B') && + (*buffer != 'C') && + (*buffer != 'D')) + { + printk(KERN_ERR "mf_proc.c: proc_mf_change_side: invalid side\n"); + return -EINVAL; + } + + mf_setSide(*buffer); + + return count; +} + +int proc_mf_dump_src +(char *page, char **start, off_t off, int count, int *eof, void *data) +{ + int len = 0; + mf_getSrcHistory(page, count); + len = count; + len -= off; + if (len < count) { + *eof = 1; + if (len <= 0) + return 0; + } else + len = count; + *start = page + off; + return len; +} + +int proc_mf_change_src(struct file *file, const char *buffer, unsigned long count, void *data) +{ + if (!capable(CAP_SYS_ADMIN)) + return -EACCES; + + if ((count < 4) && (count != 1)) + { + printk(KERN_ERR "mf_proc: invalid src\n"); + return -EINVAL; + } + + if ((count == 1) && ((*buffer) == '\0')) + { + mf_clearSrc(); + } + else + { + mf_displaySrc(*(u32 *)buffer); + } + + return count; +} + +int proc_mf_change_cmdline(struct file *file, const char *buffer, unsigned long count, void *data) +{ + if (!capable(CAP_SYS_ADMIN)) + return -EACCES; + + mf_setCmdLine(buffer, count, (u64)(int)data); + + return count; +} + +int proc_mf_change_vmlinux(struct file *file, const char *buffer, unsigned long count, void *data) +{ + if (!capable(CAP_SYS_ADMIN)) + return -EACCES; + + mf_setVmlinuxChunk(buffer, count, file->f_pos, (u64)(int)data); + file->f_pos += count; + + return count; +} diff --git a/arch/ppc/iSeries/pmc_proc.c b/arch/ppc/iSeries/pmc_proc.c new file mode 100644 index 000000000000..73f7ace4d1be --- /dev/null +++ b/arch/ppc/iSeries/pmc_proc.c @@ -0,0 +1,647 @@ +/* + * pmc_proc.c + * Copyright (C) 2001 Mike Corrigan IBM Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +/* Change Activity: */ +/* End Change Activity */ + +#ifndef _PMC_PROC_H +#include <asm/iSeries/pmc_proc.h> +#endif + +#include <asm/iSeries/Paca.h> +#include <asm/iSeries/ItLpPaca.h> +#include <asm/iSeries/ItLpQueue.h> +#include <asm/processor.h> + +#define MMCR0 795 +#define MMCR1 798 +#define MMCRA 786 +#define PMC1 787 +#define PMC2 788 +#define PMC3 789 +#define PMC4 790 +#define PMC5 791 +#define PMC6 792 +#define PMC7 793 +#define PMC8 794 + +static int proc_pmc_control_mode = 0; +#define PMC_CONTROL_CPI 1 +#define PMC_CONTROL_TLB 2 + +static struct proc_dir_entry *pmc_proc_root = NULL; + +int proc_get_lpevents( char *page, char **start, off_t off, int count, int *eof, void *data); +int proc_reset_lpevents( struct file *file, const char *buffer, unsigned long count, void *data); + +int proc_pmc_get_control( char *page, char **start, off_t off, int count, int *eof, void *data); +int proc_pmc_get_mmcr0( char *page, char **start, off_t off, int count, int *eof, void *data); +int proc_pmc_get_mmcr1( char *page, char **start, off_t off, int count, int *eof, void *data); +int proc_pmc_get_mmcra( char *page, char **start, off_t off, int count, int *eof, void *data); +int proc_pmc_get_pmc1( char *page, char **start, off_t off, int count, int *eof, void *data); +int proc_pmc_get_pmc2( char *page, char **start, off_t off, int count, int *eof, void *data); +int proc_pmc_get_pmc3( char *page, char **start, off_t off, int count, int *eof, void *data); +int proc_pmc_get_pmc4( char *page, char **start, off_t off, int count, int *eof, void *data); +int proc_pmc_get_pmc5( char *page, char **start, off_t off, int count, int *eof, void *data); +int proc_pmc_get_pmc6( char *page, char **start, off_t off, int count, int *eof, void *data); +int proc_pmc_get_pmc7( char *page, char **start, off_t off, int count, int *eof, void *data); +int proc_pmc_get_pmc8( char *page, char **start, off_t off, int count, int *eof, void *data); + +int proc_pmc_set_control( struct file *file, const char *buffer, unsigned long count, void *data); +int proc_pmc_set_mmcr0( struct file *file, const char *buffer, unsigned long count, void *data); +int proc_pmc_set_mmcr1( struct file *file, const char *buffer, unsigned long count, void *data); +int proc_pmc_set_mmcra( struct file *file, const char *buffer, unsigned long count, void *data); +int proc_pmc_set_pmc1( struct file *file, const char *buffer, unsigned long count, void *data); +int proc_pmc_set_pmc2( struct file *file, const char *buffer, unsigned long count, void *data); +int proc_pmc_set_pmc3( struct file *file, const char *buffer, unsigned long count, void *data); +int proc_pmc_set_pmc4( struct file *file, const char *buffer, unsigned long count, void *data); +int proc_pmc_set_pmc5( struct file *file, const char *buffer, unsigned long count, void *data); +int proc_pmc_set_pmc6( struct file *file, const char *buffer, unsigned long count, void *data); +int proc_pmc_set_pmc7( struct file *file, const char *buffer, unsigned long count, void *data); +int proc_pmc_set_pmc8( struct file *file, const char *buffer, unsigned long count, void *data); + +void pmc_proc_init(struct proc_dir_entry *iSeries_proc) +{ + struct proc_dir_entry *ent = NULL; + + ent = create_proc_entry("lpevents", S_IFREG|S_IRUGO, iSeries_proc); + if (!ent) return; + ent->nlink = 1; + ent->data = (void *)0; + ent->read_proc = proc_get_lpevents; + ent->write_proc = proc_reset_lpevents; + + pmc_proc_root = proc_mkdir("pmc", iSeries_proc); + if (!pmc_proc_root) return; + + ent = create_proc_entry("control", S_IFREG|S_IRUSR|S_IWUSR, pmc_proc_root); + if (!ent) return; + ent->nlink = 1; + ent->data = (void *)0; + ent->read_proc = proc_pmc_get_control; + ent->write_proc = proc_pmc_set_control; + + ent = create_proc_entry("mmcr0", S_IFREG|S_IRUSR|S_IWUSR, pmc_proc_root); + if (!ent) return; + ent->nlink = 1; + ent->data = (void *)0; + ent->read_proc = proc_pmc_get_mmcr0; + ent->write_proc = proc_pmc_set_mmcr0; + + ent = create_proc_entry("mmcr1", S_IFREG|S_IRUSR|S_IWUSR, pmc_proc_root); + if (!ent) return; + ent->nlink = 1; + ent->data = (void *)0; + ent->read_proc = proc_pmc_get_mmcr1; + ent->write_proc = proc_pmc_set_mmcr1; + + ent = create_proc_entry("mmcra", S_IFREG|S_IRUSR|S_IWUSR, pmc_proc_root); + if (!ent) return; + ent->nlink = 1; + ent->data = (void *)0; + ent->read_proc = proc_pmc_get_mmcra; + ent->write_proc = proc_pmc_set_mmcra; + + ent = create_proc_entry("pmc1", S_IFREG|S_IRUSR|S_IWUSR, pmc_proc_root); + if (!ent) return; + ent->nlink = 1; + ent->data = (void *)0; + ent->read_proc = proc_pmc_get_pmc1; + ent->write_proc = proc_pmc_set_pmc1; + + ent = create_proc_entry("pmc2", S_IFREG|S_IRUSR|S_IWUSR, pmc_proc_root); + if (!ent) return; + ent->nlink = 1; + ent->data = (void *)0; + ent->read_proc = proc_pmc_get_pmc2; + ent->write_proc = proc_pmc_set_pmc2; + + ent = create_proc_entry("pmc3", S_IFREG|S_IRUSR|S_IWUSR, pmc_proc_root); + if (!ent) return; + ent->nlink = 1; + ent->data = (void *)0; + ent->read_proc = proc_pmc_get_pmc3; + ent->write_proc = proc_pmc_set_pmc3; + + ent = create_proc_entry("pmc4", S_IFREG|S_IRUSR|S_IWUSR, pmc_proc_root); + if (!ent) return; + ent->nlink = 1; + ent->data = (void *)0; + ent->read_proc = proc_pmc_get_pmc4; + ent->write_proc = proc_pmc_set_pmc4; + + ent = create_proc_entry("pmc5", S_IFREG|S_IRUSR|S_IWUSR, pmc_proc_root); + if (!ent) return; + ent->nlink = 1; + ent->data = (void *)0; + ent->read_proc = proc_pmc_get_pmc5; + ent->write_proc = proc_pmc_set_pmc5; + + ent = create_proc_entry("pmc6", S_IFREG|S_IRUSR|S_IWUSR, pmc_proc_root); + if (!ent) return; + ent->nlink = 1; + ent->data = (void *)0; + ent->read_proc = proc_pmc_get_pmc6; + ent->write_proc = proc_pmc_set_pmc6; + + ent = create_proc_entry("pmc7", S_IFREG|S_IRUSR|S_IWUSR, pmc_proc_root); + if (!ent) return; + ent->nlink = 1; + ent->data = (void *)0; + ent->read_proc = proc_pmc_get_pmc7; + ent->write_proc = proc_pmc_set_pmc7; + + ent = create_proc_entry("pmc8", S_IFREG|S_IRUSR|S_IWUSR, pmc_proc_root); + if (!ent) return; + ent->nlink = 1; + ent->data = (void *)0; + ent->read_proc = proc_pmc_get_pmc8; + ent->write_proc = proc_pmc_set_pmc8; + + +} + +static int pmc_calc_metrics( char *page, char **start, off_t off, int count, int *eof, int len) +{ + if ( len <= off+count) + *eof = 1; + *start = page+off; + len -= off; + if ( len > count ) + len = count; + if ( len < 0 ) + len = 0; + return len; +} + +static char * lpEventTypes[9] = { + "Hypervisor\t\t", + "Machine Facilities\t", + "Session Manager\t", + "SPD I/O\t\t", + "Virtual Bus\t\t", + "PCI I/O\t\t", + "RIO I/O\t\t", + "Virtual Lan\t\t", + "Virtual I/O\t\t" + }; + + +int proc_get_lpevents +(char *page, char **start, off_t off, int count, int *eof, void *data) +{ + unsigned i; + int len = 0; + + len += sprintf( page+len, "LpEventQueue 0\n" ); + len += sprintf( page+len, " events processed:\t%lu\n", + (unsigned long)xItLpQueue.xLpIntCount ); + for (i=0; i<9; ++i) { + len += sprintf( page+len, " %s %10lu\n", + lpEventTypes[i], + (unsigned long)xItLpQueue.xLpIntCountByType[i] ); + } + return pmc_calc_metrics( page, start, off, count, eof, len ); + +} + +int proc_reset_lpevents( struct file *file, const char *buffer, unsigned long count, void *data ) +{ + return count; +} + +int proc_pmc_get_control +(char *page, char **start, off_t off, int count, int *eof, void *data) +{ + int len = 0; + + if ( proc_pmc_control_mode == PMC_CONTROL_CPI ) { + unsigned long mach_cycles = mfspr( PMC5 ); + unsigned long inst_complete = mfspr( PMC4 ); + unsigned long inst_dispatch = mfspr( PMC3 ); + unsigned long thread_active_run = mfspr( PMC1 ); + unsigned long thread_active = mfspr( PMC2 ); + unsigned long cpi = 0; + unsigned long cpithou = 0; + unsigned long remain; + + if ( inst_complete ) { + cpi = thread_active_run / inst_complete; + remain = thread_active_run % inst_complete; + if ( inst_complete > 1000000 ) + cpithou = remain / ( inst_complete / 1000 ); + else + cpithou = ( remain * 1000 ) / inst_complete; + } + len += sprintf( page+len, "PMC CPI Mode\nRaw Counts\n" ); + len += sprintf( page+len, "machine cycles : %12lu\n", mach_cycles ); + len += sprintf( page+len, "thread active cycles : %12lu\n\n", thread_active ); + + len += sprintf( page+len, "instructions completed : %12lu\n", inst_complete ); + len += sprintf( page+len, "instructions dispatched : %12lu\n", inst_dispatch ); + len += sprintf( page+len, "thread active run cycles : %12lu\n", thread_active_run ); + + len += sprintf( page+len, "thread active run cycles/instructions completed\n" ); + len += sprintf( page+len, "CPI = %lu.%03lu\n", cpi, cpithou ); + + } + else if ( proc_pmc_control_mode == PMC_CONTROL_TLB ) { + len += sprintf( page+len, "PMC TLB Mode\n" ); + len += sprintf( page+len, "I-miss count : %12u\n", mfspr( PMC1 ) ); + len += sprintf( page+len, "I-miss latency : %12u\n", mfspr( PMC2 ) ); + len += sprintf( page+len, "D-miss count : %12u\n", mfspr( PMC3 ) ); + len += sprintf( page+len, "D-miss latency : %12u\n", mfspr( PMC4 ) ); + len += sprintf( page+len, "IERAT miss count : %12u\n", mfspr( PMC5 ) ); + len += sprintf( page+len, "D-reference count : %12u\n", mfspr( PMC6 ) ); + len += sprintf( page+len, "miss PTEs searched : %12u\n", mfspr( PMC7 ) ); + len += sprintf( page+len, "miss >8 PTEs searched : %12u\n", mfspr( PMC8 ) ); + } + /* IMPLEMENT ME */ + return pmc_calc_metrics( page, start, off, count, eof, len ); +} + +int proc_pmc_get_mmcr0 +(char *page, char **start, off_t off, int count, int *eof, void *data) +{ + int len = sprintf( page, "0x%08x", mfspr(MMCR0) ); + return pmc_calc_metrics( page, start, off, count, eof, len ); +} + +int proc_pmc_get_mmcr1 +(char *page, char **start, off_t off, int count, int *eof, void *data) +{ + int len = sprintf( page, "0x%08x", mfspr(MMCR1) ); + return pmc_calc_metrics( page, start, off, count, eof, len ); +} + +int proc_pmc_get_mmcra +(char *page, char **start, off_t off, int count, int *eof, void *data) +{ + int len = sprintf( page, "0x%08x", mfspr(MMCRA) ); + return pmc_calc_metrics( page, start, off, count, eof, len ); +} + +int proc_pmc_get_pmc1 +(char *page, char **start, off_t off, int count, int *eof, void *data) +{ + int len = sprintf( page, "0x%08x", mfspr(PMC1) ); + return pmc_calc_metrics( page, start, off, count, eof, len ); +} + +int proc_pmc_get_pmc2 +(char *page, char **start, off_t off, int count, int *eof, void *data) +{ + int len = sprintf( page, "0x%08x", mfspr(PMC2) ); + return pmc_calc_metrics( page, start, off, count, eof, len ); +} + +int proc_pmc_get_pmc3 +(char *page, char **start, off_t off, int count, int *eof, void *data) +{ + int len = sprintf( page, "0x%08x", mfspr(PMC3) ); + return pmc_calc_metrics( page, start, off, count, eof, len ); +} + +int proc_pmc_get_pmc4 +(char *page, char **start, off_t off, int count, int *eof, void *data) +{ + int len = sprintf( page, "0x%08x", mfspr(PMC4) ); + return pmc_calc_metrics( page, start, off, count, eof, len ); +} + +int proc_pmc_get_pmc5 +(char *page, char **start, off_t off, int count, int *eof, void *data) +{ + int len = sprintf( page, "0x%08x", mfspr(PMC5) ); + return pmc_calc_metrics( page, start, off, count, eof, len ); +} + +int proc_pmc_get_pmc6 +(char *page, char **start, off_t off, int count, int *eof, void *data) +{ + int len = sprintf( page, "0x%08x", mfspr(PMC6) ); + return pmc_calc_metrics( page, start, off, count, eof, len ); +} + +int proc_pmc_get_pmc7 +(char *page, char **start, off_t off, int count, int *eof, void *data) +{ + int len = sprintf( page, "0x%08x", mfspr(PMC7) ); + return pmc_calc_metrics( page, start, off, count, eof, len ); +} + +int proc_pmc_get_pmc8 +(char *page, char **start, off_t off, int count, int *eof, void *data) +{ + int len = sprintf( page, "0x%08x", mfspr(PMC8) ); + return pmc_calc_metrics( page, start, off, count, eof, len ); +} + +unsigned long proc_pmc_conv_int( const char *buf, unsigned count ) +{ + const char * p; + char b0, b1; + unsigned v, multiplier, mult, i; + unsigned long val; + multiplier = 10; + p = buf; + if ( count >= 3 ) { + b0 = buf[0]; + b1 = buf[1]; + if ( ( b0 == '0' ) && + ( ( b1 == 'x' ) || ( b1 == 'X' ) ) ) { + p = buf + 2; + count -= 2; + multiplier = 16; + } + + } + val = 0; + for ( i=0; i<count; ++i ) { + b0 = *p++; + v = 0; + mult = multiplier; + if ( ( b0 >= '0' ) && ( b0 <= '9' ) ) + v = b0 - '0'; + else if ( multiplier == 16 ) { + if ( ( b0 >= 'a' ) && ( b0 <= 'f' ) ) + v = b0 - 'a' + 10; + else if ( ( b0 >= 'A' ) && ( b0 <= 'F' ) ) + v = b0 - 'A' + 10; + else + mult = 1; + } + else + mult = 1; + val *= mult; + val += v; + } + + return val; + +} + +static inline void proc_pmc_stop(void) +{ + // Freeze all counters, leave everything else alone + mtspr( MMCR0, mfspr( MMCR0 ) | 0x80000000 ); +} + +static inline void proc_pmc_start(void) +{ + // Unfreeze all counters, leave everything else alone + mtspr( MMCR0, mfspr( MMCR0 ) & ~0x80000000 ); + +} + +static inline void proc_pmc_reset(void) +{ + // Clear all the PMCs to zero + // Assume a "stop" has already frozen the counters + // Clear all the PMCs + mtspr( PMC1, 0 ); + mtspr( PMC2, 0 ); + mtspr( PMC3, 0 ); + mtspr( PMC4, 0 ); + mtspr( PMC5, 0 ); + mtspr( PMC6, 0 ); + mtspr( PMC7, 0 ); + mtspr( PMC8, 0 ); + +} + +static inline void proc_pmc_cpi(void) +{ + /* Configure the PMC registers to count cycles and instructions */ + /* so we can compute cpi */ + /* + * MMCRA[30] = 1 Don't count in wait state (CTRL[31]=0) + * MMCR0[6] = 1 Freeze counters when any overflow + * MMCR0[19:25] = 0x01 PMC1 counts Thread Active Run Cycles + * MMCR0[26:31] = 0x05 PMC2 counts Thread Active Cycles + * MMCR1[0:4] = 0x07 PMC3 counts Instructions Dispatched + * MMCR1[5:9] = 0x03 PMC4 counts Instructions Completed + * MMCR1[10:14] = 0x06 PMC5 counts Machine Cycles + * + */ + + proc_pmc_control_mode = PMC_CONTROL_CPI; + + // Indicate to hypervisor that we are using the PMCs + ((struct Paca *)mfspr(SPRG1))->xLpPacaPtr->xPMCRegsInUse = 1; + + // Freeze all counters + mtspr( MMCR0, 0x80000000 ); + mtspr( MMCR1, 0x00000000 ); + + // Clear all the PMCs + mtspr( PMC1, 0 ); + mtspr( PMC2, 0 ); + mtspr( PMC3, 0 ); + mtspr( PMC4, 0 ); + mtspr( PMC5, 0 ); + mtspr( PMC6, 0 ); + mtspr( PMC7, 0 ); + mtspr( PMC8, 0 ); + + // Freeze counters in Wait State (CTRL[31]=0) + mtspr( MMCRA, 0x00000002 ); + + // PMC3<-0x07, PMC4<-0x03, PMC5<-0x06 + mtspr( MMCR1, 0x38cc0000 ); + + mb(); + + // PMC1<-0x01, PMC2<-0x05 + // Start all counters + mtspr( MMCR0, 0x02000045 ); + +} + +static inline void proc_pmc_tlb(void) +{ + /* Configure the PMC registers to count tlb misses */ + /* + * MMCR0[6] = 1 Freeze counters when any overflow + * MMCR0[19:25] = 0x55 Group count + * PMC1 counts I misses + * PMC2 counts I miss duration (latency) + * PMC3 counts D misses + * PMC4 counts D miss duration (latency) + * PMC5 counts IERAT misses + * PMC6 counts D references (including PMC7) + * PMC7 counts miss PTEs searched + * PMC8 counts miss >8 PTEs searched + * + */ + + proc_pmc_control_mode = PMC_CONTROL_TLB; + + // Indicate to hypervisor that we are using the PMCs + ((struct Paca *)mfspr(SPRG1))->xLpPacaPtr->xPMCRegsInUse = 1; + + // Freeze all counters + mtspr( MMCR0, 0x80000000 ); + mtspr( MMCR1, 0x00000000 ); + + // Clear all the PMCs + mtspr( PMC1, 0 ); + mtspr( PMC2, 0 ); + mtspr( PMC3, 0 ); + mtspr( PMC4, 0 ); + mtspr( PMC5, 0 ); + mtspr( PMC6, 0 ); + mtspr( PMC7, 0 ); + mtspr( PMC8, 0 ); + + mtspr( MMCRA, 0x00000000 ); + + mb(); + + // PMC1<-0x55 + // Start all counters + mtspr( MMCR0, 0x02001540 ); + +} + +int proc_pmc_set_control( struct file *file, const char *buffer, unsigned long count, void *data ) +{ + if ( ! strncmp( buffer, "stop", 4 ) ) + proc_pmc_stop(); + else if ( ! strncmp( buffer, "start", 5 ) ) + proc_pmc_start(); + else if ( ! strncmp( buffer, "reset", 5 ) ) + proc_pmc_reset(); + else if ( ! strncmp( buffer, "cpi", 3 ) ) + proc_pmc_cpi(); + else if ( ! strncmp( buffer, "tlb", 3 ) ) + proc_pmc_tlb(); + + /* IMPLEMENT ME */ + return count; +} + +int proc_pmc_set_mmcr0( struct file *file, const char *buffer, unsigned long count, void *data ) +{ + unsigned long v; + v = proc_pmc_conv_int( buffer, count ); + v = v & ~0x04000000; /* Don't allow interrupts for now */ + if ( v & ~0x80000000 ) /* Inform hypervisor we are using PMCs */ + ((struct Paca *)mfspr(SPRG1))->xLpPacaPtr->xPMCRegsInUse = 1; + else + ((struct Paca *)mfspr(SPRG1))->xLpPacaPtr->xPMCRegsInUse = 0; + mtspr( MMCR0, v ); + + return count; +} + +int proc_pmc_set_mmcr1( struct file *file, const char *buffer, unsigned long count, void *data ) +{ + unsigned long v; + v = proc_pmc_conv_int( buffer, count ); + mtspr( MMCR1, v ); + + return count; +} + +int proc_pmc_set_mmcra( struct file *file, const char *buffer, unsigned long count, void *data ) +{ + unsigned long v; + v = proc_pmc_conv_int( buffer, count ); + v = v & ~0x00008000; /* Don't allow interrupts for now */ + mtspr( MMCRA, v ); + + return count; +} + + +int proc_pmc_set_pmc1( struct file *file, const char *buffer, unsigned long count, void *data ) +{ + unsigned long v; + v = proc_pmc_conv_int( buffer, count ); + mtspr( PMC1, v ); + + return count; +} + +int proc_pmc_set_pmc2( struct file *file, const char *buffer, unsigned long count, void *data ) +{ + unsigned long v; + v = proc_pmc_conv_int( buffer, count ); + mtspr( PMC2, v ); + + return count; +} + +int proc_pmc_set_pmc3( struct file *file, const char *buffer, unsigned long count, void *data ) +{ + unsigned long v; + v = proc_pmc_conv_int( buffer, count ); + mtspr( PMC3, v ); + + return count; +} + +int proc_pmc_set_pmc4( struct file *file, const char *buffer, unsigned long count, void *data ) +{ + unsigned long v; + v = proc_pmc_conv_int( buffer, count ); + mtspr( PMC4, v ); + + return count; +} + +int proc_pmc_set_pmc5( struct file *file, const char *buffer, unsigned long count, void *data ) +{ + unsigned long v; + v = proc_pmc_conv_int( buffer, count ); + mtspr( PMC5, v ); + + return count; +} + +int proc_pmc_set_pmc6( struct file *file, const char *buffer, unsigned long count, void *data ) +{ + unsigned long v; + v = proc_pmc_conv_int( buffer, count ); + mtspr( PMC6, v ); + + return count; +} + +int proc_pmc_set_pmc7( struct file *file, const char *buffer, unsigned long count, void *data ) +{ + unsigned long v; + v = proc_pmc_conv_int( buffer, count ); + mtspr( PMC7, v ); + + return count; +} + +int proc_pmc_set_pmc8( struct file *file, const char *buffer, unsigned long count, void *data ) +{ + unsigned long v; + v = proc_pmc_conv_int( buffer, count ); + mtspr( PMC8, v ); + + return count; +} + + diff --git a/arch/ppc/iSeries/rtc.c b/arch/ppc/iSeries/rtc.c new file mode 100644 index 000000000000..55e1861d4158 --- /dev/null +++ b/arch/ppc/iSeries/rtc.c @@ -0,0 +1,265 @@ +/* + * Real Time Clock interface for IBM iSeries + * + * Based on rtc.c by Paul Gortmaker + * + * This driver allows use of the real time clock + * from user space. It exports the /dev/rtc + * interface supporting various ioctl() and also the + * /proc/driver/rtc pseudo-file for status information. + * + * iSeries does not support RTC interrupts nor an alarm. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + * 1.0 Mike Corrigan: IBM iSeries rtc support + */ + +#define RTC_VERSION "1.0" + +#include <linux/config.h> +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/miscdevice.h> +#include <linux/ioport.h> +#include <linux/fcntl.h> +#include <linux/mc146818rtc.h> +#include <linux/init.h> +#include <linux/poll.h> +#include <linux/proc_fs.h> +#include <linux/spinlock.h> + +#include <asm/io.h> +#include <asm/uaccess.h> +#include <asm/system.h> + +#include <asm/iSeries/mf.h> + +/* + * We sponge a minor off of the misc major. No need slurping + * up another valuable major dev number for this. If you add + * an ioctl, make sure you don't conflict with SPARC's RTC + * ioctls. + */ + +static loff_t rtc_llseek(struct file *file, loff_t offset, int origin); + +static ssize_t rtc_read(struct file *file, char *buf, + size_t count, loff_t *ppos); + +static int rtc_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg); + +static void get_rtc_time (struct rtc_time *rtc_tm); + +static int rtc_read_proc(char *page, char **start, off_t off, + int count, int *eof, void *data); + +/* + * If this driver ever becomes modularised, it will be really nice + * to make the epoch retain its value across module reload... + */ + +static unsigned long epoch = 1900; /* year corresponding to 0x00 */ + +static const unsigned char days_in_mo[] = +{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; + +/* + * Now all the various file operations that we export. + */ + +static loff_t rtc_llseek(struct file *file, loff_t offset, int origin) +{ + return -ESPIPE; +} + +static ssize_t rtc_read(struct file *file, char *buf, + size_t count, loff_t *ppos) +{ + return -EIO; +} + +static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, + unsigned long arg) +{ + struct rtc_time wtime; + + switch (cmd) { + case RTC_RD_TIME: /* Read the time/date from RTC */ + { + get_rtc_time(&wtime); + break; + } + case RTC_SET_TIME: /* Set the RTC */ + { + struct rtc_time rtc_tm; + unsigned char mon, day, hrs, min, sec, leap_yr; + unsigned int yrs; + + if (!capable(CAP_SYS_TIME)) + return -EACCES; + + if (copy_from_user(&rtc_tm, (struct rtc_time*)arg, + sizeof(struct rtc_time))) + return -EFAULT; + + yrs = rtc_tm.tm_year; + mon = rtc_tm.tm_mon + 1; /* tm_mon starts at zero */ + day = rtc_tm.tm_mday; + hrs = rtc_tm.tm_hour; + min = rtc_tm.tm_min; + sec = rtc_tm.tm_sec; + + if (yrs < 70) + return -EINVAL; + + leap_yr = ((!(yrs % 4) && (yrs % 100)) || !(yrs % 400)); + + if ((mon > 12) || (day == 0)) + return -EINVAL; + + if (day > (days_in_mo[mon] + ((mon == 2) && leap_yr))) + return -EINVAL; + + if ((hrs >= 24) || (min >= 60) || (sec >= 60)) + return -EINVAL; + + if ( yrs > 169 ) + return -EINVAL; + + mf_setRtc( &rtc_tm ); + + return 0; + } + case RTC_EPOCH_READ: /* Read the epoch. */ + { + return put_user (epoch, (unsigned long *)arg); + } + case RTC_EPOCH_SET: /* Set the epoch. */ + { + /* + * There were no RTC clocks before 1900. + */ + if (arg < 1900) + return -EINVAL; + + if (!capable(CAP_SYS_TIME)) + return -EACCES; + + epoch = arg; + return 0; + } + default: + return -EINVAL; + } + return copy_to_user((void *)arg, &wtime, sizeof wtime) ? -EFAULT : 0; +} + +static int rtc_open(struct inode *inode, struct file *file) +{ + return 0; +} + +static int rtc_release(struct inode *inode, struct file *file) +{ + return 0; +} + +/* + * The various file operations we support. + */ + +static struct file_operations rtc_fops = { + owner: THIS_MODULE, + llseek: rtc_llseek, + read: rtc_read, + ioctl: rtc_ioctl, + open: rtc_open, + release: rtc_release, +}; + +static struct miscdevice rtc_dev= +{ + RTC_MINOR, + "rtc", + &rtc_fops +}; + +static int __init rtc_init(void) +{ + misc_register(&rtc_dev); + create_proc_read_entry ("driver/rtc", 0, 0, rtc_read_proc, NULL); + + printk(KERN_INFO "iSeries Real Time Clock Driver v" RTC_VERSION "\n"); + + return 0; +} + +static void __exit rtc_exit (void) +{ + remove_proc_entry ("driver/rtc", NULL); + misc_deregister(&rtc_dev); +} + +module_init(rtc_init); +module_exit(rtc_exit); +EXPORT_NO_SYMBOLS; + +/* + * Info exported via "/proc/driver/rtc". + */ + +static int rtc_proc_output (char *buf) +{ + + char *p; + struct rtc_time tm; + + p = buf; + + get_rtc_time(&tm); + + /* + * There is no way to tell if the luser has the RTC set for local + * time or for Universal Standard Time (GMT). Probably local though. + */ + p += sprintf(p, + "rtc_time\t: %02d:%02d:%02d\n" + "rtc_date\t: %04d-%02d-%02d\n" + "rtc_epoch\t: %04lu\n", + tm.tm_hour, tm.tm_min, tm.tm_sec, + tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, epoch); + + p += sprintf(p, + "DST_enable\t: no\n" + "BCD\t\t: yes\n" + "24hr\t\t: yes\n" ); + + return p - buf; +} + +static int rtc_read_proc(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + int len = rtc_proc_output (page); + if (len <= off+count) *eof = 1; + *start = page + off; + len -= off; + if (len>count) len = count; + if (len<0) len = 0; + return len; +} + +static void get_rtc_time(struct rtc_time *rtc_tm) +{ + mf_getRtc( rtc_tm ); + + rtc_tm->tm_mon--; +} + + diff --git a/arch/ppc/kernel/Makefile b/arch/ppc/kernel/Makefile index 59236099d7a9..d00aacf316d8 100644 --- a/arch/ppc/kernel/Makefile +++ b/arch/ppc/kernel/Makefile @@ -1,4 +1,4 @@ -# BK Id: SCCS/s.Makefile 1.34 10/16/01 15:58:42 trini +# BK Id: %F% %I% %G% %U% %#% # # # Makefile for the linux kernel. @@ -14,17 +14,24 @@ USE_STANDARD_AS_RULE := true ifdef CONFIG_PPC64BRIDGE EXTRA_AFLAGS := -Wa,-mppc64bridge endif +ifdef CONFIG_4xx +EXTRA_AFLAGS := -Wa,-m405 +endif + +CFLAGS_prom_init.o += -mrelocatable-lib +CFLAGS_btext.o += -mrelocatable-lib # Start off with 'head.o', change as needed. HEAD-y := head.o HEAD-$(CONFIG_4xx) := head_4xx.o HEAD-$(CONFIG_8xx) := head_8xx.o +HEAD-$(CONFIG_PPC_ISERIES) := iSeries_head.o all: $(HEAD-y) kernel.o O_TARGET := kernel.o -export-objs := ppc_ksyms.o prep_setup.o time.o +export-objs := ppc_ksyms.o time.o ppc405_dma.o obj-y := entry.o traps.o irq.o idle.o time.o misc.o \ process.o signal.o ptrace.o align.o \ @@ -32,16 +39,20 @@ obj-y := entry.o traps.o irq.o idle.o time.o misc.o \ cputable.o ppc_htab.o obj-$(CONFIG_6xx) += l2cr.o obj-$(CONFIG_MODULES) += ppc_ksyms.o -obj-$(CONFIG_POWER4) += xics.o -obj-$(CONFIG_PCI) += pci.o pci-dma.o +obj-$(CONFIG_PCI) += pci.o +ifneq ($(CONFIG_PPC_ISERIES),y) +obj-$(CONFIG_PCI) += pci-dma.o +endif obj-$(CONFIG_KGDB) += ppc-stub.o obj-$(CONFIG_SMP) += smp.o -obj-$(CONFIG_4xx) += ppc4xx_pic.o -obj-$(CONFIG_OAK) += oak_setup.o -obj-$(CONFIG_WALNUT) += walnut_setup.o obj-$(CONFIG_TAU) += temp.o -ifeq ($(CONFIG_WALNUT),y) -obj-$(CONFIG_PCI) += galaxy_pci.o +ifeq ($(CONFIG_4xx),y) +obj-$(CONFIG_4xx) += ppc4xx_setup.o ppc4xx_pic.o ppc4xx_serial.o +obj-$(CONFIG_PPC_RTC) += todc_time.o +obj-$(CONFIG_KGDB) += ppc4xx_kgdb.o +obj-$(CONFIG_405_DMA) += ppc405_dma.o +obj-$(CONFIG_PCI) += ppc405_pci.o indirect_pci.o pci_auto.o +obj-$(CONFIG_PM) += ppc4xx_pm.o endif obj-$(CONFIG_8xx) += m8xx_setup.o ppc8xx_pic.o ifeq ($(CONFIG_8xx),y) @@ -51,28 +62,41 @@ obj-y += softemu8xx.o endif endif obj-$(CONFIG_MBX) += i8259.o -obj-$(CONFIG_APUS) += apus_setup.o -ifeq ($(CONFIG_APUS),y) -obj-$(CONFIG_PCI) += apus_pci.o -endif -obj-$(CONFIG_ALL_PPC) += pmac_pic.o pmac_setup.o pmac_time.o prom.o \ - feature.o pmac_pci.o chrp_setup.o \ - chrp_time.o chrp_pci.o open_pic.o \ - indirect_pci.o i8259.o prep_pci.o \ - prep_time.o prep_nvram.o prep_setup.o -obj-$(CONFIG_NVRAM) += pmac_nvram.o -obj-$(CONFIG_PMAC_BACKLIGHT) += pmac_backlight.o -obj-$(CONFIG_PMAC_PBOOK) += sleep.o -obj-$(CONFIG_PREP_RESIDUAL) += residual.o -obj-$(CONFIG_PPC_RTAS) += error_log.o proc_rtas.o -obj-$(CONFIG_GEMINI) += gemini_prom.o gemini_pci.o gemini_setup.o \ - open_pic.o +obj-$(CONFIG_ALL_PPC) += prom_init.o prom.o open_pic.o \ + indirect_pci.o i8259.o +obj-$(CONFIG_ADIR) += i8259.o indirect_pci.o pci_auto.o \ + todc_time.o +obj-$(CONFIG_EV64260) += gt64260_common.o gt64260_pic.o \ + indirect_pci.o todc_time.o pci_auto.o +obj-$(CONFIG_GEMINI) += open_pic.o +obj-$(CONFIG_K2) += i8259.o indirect_pci.o todc_time.o \ + pci_auto.o +obj-$(CONFIG_LOPEC) += mpc10x_common.o indirect_pci.o pci_auto.o \ + open_pic.o i8259.o todc_time.o +obj-$(CONFIG_MCPN765) += todc_time.o indirect_pci.o pci_auto.o \ + open_pic.o i8259.o pplus_common.o +obj-$(CONFIG_MENF1) += todc_time.o i8259.o mpc10x_common.o \ + pci_auto.o indirect_pci.o +obj-$(CONFIG_MVME5100) += open_pic.o todc_time.o indirect_pci.o \ + i8259.o pci_auto.o pplus_common.o +obj-$(CONFIG_PCORE) += mpc10x_common.o todc_time.o i8259.o \ + indirect_pci.o pci_auto.o +obj-$(CONFIG_POWERPMC250) += open_pic.o mpc10x_common.o \ + indirect_pci.o pci_auto.o +obj-$(CONFIG_PPLUS) += pplus_common.o open_pic.o i8259.o \ + indirect_pci.o todc_time.o pci_auto.o +obj-$(CONFIG_PRPMC750) += open_pic.o indirect_pci.o pci_auto.o \ + pplus_common.o +obj-$(CONFIG_PRPMC800) += open_pic.o indirect_pci.o pci_auto.o \ + pplus_common.o harrier.o +obj-$(CONFIG_SANDPOINT) += i8259.o open_pic.o mpc10x_common.o \ + pci_auto.o indirect_pci.o todc_time.o +obj-$(CONFIG_SPRUCE) += indirect_pci.o pci_auto.o todc_time.o +obj-$(CONFIG_ZX4500) += indirect_pci.o pci_auto.o mpc10x_common.o \ + i8259.o open_pic.o obj-$(CONFIG_8260) += m8260_setup.o ppc8260_pic.o obj-$(CONFIG_BOOTX_TEXT) += btext.o - -ifeq ($(CONFIG_SMP),y) -obj-$(CONFIG_ALL_PPC) += pmac_smp.o chrp_smp.o -endif +obj-$(CONFIG_PPC_ISERIES) += iSeries_misc.o include $(TOPDIR)/Rules.make @@ -82,7 +106,8 @@ l2cr.o: l2cr.S ppc_defs.h head.o: head.S ppc_defs.h head_4xx.o: head_4xx.S ppc_defs.h head_8xx.o: head_8xx.S ppc_defs.h -gemini_prom.o: gemini_prom.S ppc_defs.h +iSeries_head.o: iSeries_head.S ppc_defs.h +iSeries_misc.o: iSeries_misc.S ppc_defs.h ppc_defs.h: mk_defs.c ppc_defs.head \ $(TOPDIR)/include/asm/mmu.h \ @@ -102,4 +127,3 @@ find_name : find_name.c checks: checks.c $(HOSTCC) -I$(HPATH) $(HOSTCFLAGS) -D__KERNEL__ -fno-builtin -o checks checks.c ./checks - diff --git a/arch/ppc/kernel/align.c b/arch/ppc/kernel/align.c index 4edb4616848c..0f8dbd1cb585 100644 --- a/arch/ppc/kernel/align.c +++ b/arch/ppc/kernel/align.c @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.align.c 1.5 05/17/01 18:14:21 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * align.c - handle alignment exceptions for the Power PC. @@ -24,7 +24,7 @@ struct aligninfo { unsigned char flags; }; -#if defined(CONFIG_4xx) || defined(CONFIG_POWER4) +#if defined(CONFIG_4xx) #define OPCD(inst) (((inst) & 0xFC000000) >> 26) #define RS(inst) (((inst) & 0x03E00000) >> 21) #define RA(inst) (((inst) & 0x001F0000) >> 16) @@ -187,7 +187,7 @@ int fix_alignment(struct pt_regs *regs) { int instr, nb, flags; -#if defined(CONFIG_4xx) || defined(CONFIG_POWER4) +#if defined(CONFIG_4xx) int opcode, f1, f2, f3; #endif int i, t; @@ -200,11 +200,9 @@ fix_alignment(struct pt_regs *regs) unsigned char v[8]; } data; -#if defined(CONFIG_4xx) || defined(CONFIG_POWER4) +#if defined(CONFIG_4xx) /* The 4xx-family processors have no DSISR register, * so we emulate it. - * The POWER4 has a DSISR register but doesn't set it on - * an alignment fault. -- paulus */ instr = *((unsigned int *)regs->nip); diff --git a/arch/ppc/kernel/bitops.c b/arch/ppc/kernel/bitops.c index eebbab590e0e..e61da0d1e978 100644 --- a/arch/ppc/kernel/bitops.c +++ b/arch/ppc/kernel/bitops.c @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.bitops.c 1.7 05/17/01 18:14:21 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * Copyright (C) 1996 Paul Mackerras. @@ -21,8 +21,9 @@ void set_bit(int nr, volatile void * addr) __asm__ __volatile__(SMP_WMB "\n\ 1: lwarx %0,0,%3 \n\ - or %0,%0,%2 \n\ - stwcx. %0,0,%3 \n\ + or %0,%0,%2 \n" + PPC405_ERR77(0,%3) +" stwcx. %0,0,%3 \n\ bne 1b" SMP_MB : "=&r" (old), "=m" (*p) @@ -38,8 +39,9 @@ void clear_bit(int nr, volatile void *addr) __asm__ __volatile__(SMP_WMB "\n\ 1: lwarx %0,0,%3 \n\ - andc %0,%0,%2 \n\ - stwcx. %0,0,%3 \n\ + andc %0,%0,%2 \n" + PPC405_ERR77(0,%3) +" stwcx. %0,0,%3 \n\ bne 1b" SMP_MB : "=&r" (old), "=m" (*p) @@ -55,8 +57,9 @@ void change_bit(int nr, volatile void *addr) __asm__ __volatile__(SMP_WMB "\n\ 1: lwarx %0,0,%3 \n\ - xor %0,%0,%2 \n\ - stwcx. %0,0,%3 \n\ + xor %0,%0,%2 \n" + PPC405_ERR77(0,%3) +" stwcx. %0,0,%3 \n\ bne 1b" SMP_MB : "=&r" (old), "=m" (*p) @@ -72,8 +75,9 @@ int test_and_set_bit(int nr, volatile void *addr) __asm__ __volatile__(SMP_WMB "\n\ 1: lwarx %0,0,%4 \n\ - or %1,%0,%3 \n\ - stwcx. %1,0,%4 \n\ + or %1,%0,%3 \n" + PPC405_ERR77(0,%4) +" stwcx. %1,0,%4 \n\ bne 1b" SMP_MB : "=&r" (old), "=&r" (t), "=m" (*p) @@ -91,8 +95,9 @@ int test_and_clear_bit(int nr, volatile void *addr) __asm__ __volatile__(SMP_WMB "\n\ 1: lwarx %0,0,%4 \n\ - andc %1,%0,%3 \n\ - stwcx. %1,0,%4 \n\ + andc %1,%0,%3 \n" + PPC405_ERR77(0,%4) +" stwcx. %1,0,%4 \n\ bne 1b" SMP_MB : "=&r" (old), "=&r" (t), "=m" (*p) @@ -110,8 +115,9 @@ int test_and_change_bit(int nr, volatile void *addr) __asm__ __volatile__(SMP_WMB "\n\ 1: lwarx %0,0,%4 \n\ - xor %1,%0,%3 \n\ - stwcx. %1,0,%4 \n\ + xor %1,%0,%3 \n" + PPC405_ERR77(0,%4) +" stwcx. %1,0,%4 \n\ bne 1b" SMP_MB : "=&r" (old), "=&r" (t), "=m" (*p) diff --git a/arch/ppc/kernel/btext.c b/arch/ppc/kernel/btext.c index 7cd47d953cf8..ec2befee7d33 100644 --- a/arch/ppc/kernel/btext.c +++ b/arch/ppc/kernel/btext.c @@ -44,10 +44,10 @@ unsigned long disp_BAT[2] __initdata = {0, 0}; static unsigned char vga_font[cmapsz]; -int boot_text_mapped = 1; +int boot_text_mapped; +int force_printk_to_btext = 0; -boot_infos_t *disp_bi; -boot_infos_t fake_bi; +boot_infos_t disp_bi; extern char *klimit; @@ -69,48 +69,47 @@ extern char *klimit; void __init btext_init(boot_infos_t *bi) { - unsigned long offset = reloc_offset(); - - RELOC(g_loc_X) = 0; - RELOC(g_loc_Y) = 0; - RELOC(g_max_loc_X) = (bi->dispDeviceRect[2] - bi->dispDeviceRect[0]) / 8; - RELOC(g_max_loc_Y) = (bi->dispDeviceRect[3] - bi->dispDeviceRect[1]) / 16; - RELOC(disp_bi) = PTRUNRELOC(bi); + g_loc_X = 0; + g_loc_Y = 0; + g_max_loc_X = (bi->dispDeviceRect[2] - bi->dispDeviceRect[0]) / 8; + g_max_loc_Y = (bi->dispDeviceRect[3] - bi->dispDeviceRect[1]) / 16; + disp_bi = *bi; + boot_text_mapped = 1; } void __init -btext_welcome(boot_infos_t* bi) +btext_welcome(void) { - unsigned long offset = reloc_offset(); unsigned long flags; unsigned long pvr; - - btext_drawstring(RELOC("Welcome to Linux, kernel " UTS_RELEASE "\n")); - btext_drawstring(RELOC("\nlinked at : 0x")); + boot_infos_t* bi = &disp_bi; + + btext_drawstring("Welcome to Linux, kernel " UTS_RELEASE "\n"); + btext_drawstring("\nlinked at : 0x"); btext_drawhex(KERNELBASE); - btext_drawstring(RELOC("\nframe buffer at : 0x")); + btext_drawstring("\nframe buffer at : 0x"); btext_drawhex((unsigned long)bi->dispDeviceBase); - btext_drawstring(RELOC(" (phys), 0x")); + btext_drawstring(" (phys), 0x"); btext_drawhex((unsigned long)bi->logicalDisplayBase); - btext_drawstring(RELOC(" (log)")); - btext_drawstring(RELOC("\nklimit : 0x")); - btext_drawhex((unsigned long)RELOC(klimit)); - btext_drawstring(RELOC("\nMSR : 0x")); + btext_drawstring(" (log)"); + btext_drawstring("\nklimit : 0x"); + btext_drawhex((unsigned long)klimit); + btext_drawstring("\nMSR : 0x"); __asm__ __volatile__ ("mfmsr %0" : "=r" (flags)); btext_drawhex(flags); __asm__ __volatile__ ("mfspr %0, 287" : "=r" (pvr)); pvr >>= 16; if (pvr > 1) { - btext_drawstring(RELOC("\nHID0 : 0x")); + btext_drawstring("\nHID0 : 0x"); __asm__ __volatile__ ("mfspr %0, 1008" : "=r" (flags)); btext_drawhex(flags); } if (pvr == 8 || pvr == 12 || pvr == 0x800c) { - btext_drawstring(RELOC("\nICTC : 0x")); + btext_drawstring("\nICTC : 0x"); __asm__ __volatile__ ("mfspr %0, 1019" : "=r" (flags)); btext_drawhex(flags); } - btext_drawstring(RELOC("\n\n")); + btext_drawstring("\n\n"); } /* Calc BAT values for mapping the display and store them @@ -131,28 +130,28 @@ btext_welcome(boot_infos_t* bi) void __init btext_prepare_BAT(void) { - unsigned long offset = reloc_offset(); - boot_infos_t* bi = PTRRELOC(RELOC(disp_bi)); - unsigned long addr = (unsigned long)bi->dispDeviceBase; + boot_infos_t* bi = &disp_bi; unsigned long vaddr = KERNELBASE + 0x10000000; + unsigned long addr; unsigned long lowbits; - if (!RELOC(disp_bi)) { - RELOC(boot_text_mapped) = 0; + addr = (unsigned long)bi->dispDeviceBase; + if (!addr) { + boot_text_mapped = 0; return; } if (PVR_VER(mfspr(PVR)) != 1) { /* 603, 604, G3, G4, ... */ lowbits = addr & ~0xFF000000UL; addr &= 0xFF000000UL; - RELOC(disp_BAT[0]) = vaddr | (BL_16M<<2) | 2; - RELOC(disp_BAT[1]) = addr | (_PAGE_NO_CACHE | _PAGE_GUARDED | BPP_RW); + disp_BAT[0] = vaddr | (BL_16M<<2) | 2; + disp_BAT[1] = addr | (_PAGE_NO_CACHE | _PAGE_GUARDED | BPP_RW); } else { /* 601 */ lowbits = addr & ~0xFF800000UL; addr &= 0xFF800000UL; - RELOC(disp_BAT[0]) = vaddr | (_PAGE_NO_CACHE | PP_RWXX) | 4; - RELOC(disp_BAT[1]) = addr | BL_8M | 0x40; + disp_BAT[0] = vaddr | (_PAGE_NO_CACHE | PP_RWXX) | 4; + disp_BAT[1] = addr | BL_8M | 0x40; } bi->logicalDisplayBase = (void *) (vaddr + lowbits); } @@ -164,15 +163,12 @@ void __init btext_setup_display(int width, int height, int depth, int pitch, unsigned long address) { - unsigned long offset = reloc_offset(); - boot_infos_t* bi; - - RELOC(disp_bi) = &fake_bi; - bi = PTRRELOC((&fake_bi)); - RELOC(g_loc_X) = 0; - RELOC(g_loc_Y) = 0; - RELOC(g_max_loc_X) = width / 8; - RELOC(g_max_loc_Y) = height / 16; + boot_infos_t* bi = &disp_bi; + + g_loc_X = 0; + g_loc_Y = 0; + g_max_loc_X = width / 8; + g_max_loc_Y = height / 16; bi->logicalDisplayBase = (unsigned char *)address; bi->dispDeviceBase = (unsigned char *)address; bi->dispDeviceRowBytes = pitch; @@ -180,6 +176,7 @@ btext_setup_display(int width, int height, int depth, int pitch, bi->dispDeviceRect[0] = bi->dispDeviceRect[1] = 0; bi->dispDeviceRect[2] = width; bi->dispDeviceRect[3] = height; + boot_text_mapped = 1; } /* Here's a small text engine to use during early boot @@ -197,16 +194,18 @@ void __openfirmware map_boot_text(void) { unsigned long base, offset, size; - if (disp_bi == 0) + boot_infos_t *bi = &disp_bi; + + if (bi->dispDeviceBase == 0) return; - base = ((unsigned long) disp_bi->dispDeviceBase) & 0xFFFFF000UL; - offset = ((unsigned long) disp_bi->dispDeviceBase) - base; - size = disp_bi->dispDeviceRowBytes * disp_bi->dispDeviceRect[3] + offset - + disp_bi->dispDeviceRect[0]; - disp_bi->logicalDisplayBase = ioremap(base, size); - if (disp_bi->logicalDisplayBase == 0) + base = ((unsigned long) bi->dispDeviceBase) & 0xFFFFF000UL; + offset = ((unsigned long) bi->dispDeviceBase) - base; + size = bi->dispDeviceRowBytes * bi->dispDeviceRect[3] + offset + + bi->dispDeviceRect[0]; + bi->logicalDisplayBase = ioremap(base, size); + if (bi->logicalDisplayBase == 0) return; - disp_bi->logicalDisplayBase += offset; + bi->logicalDisplayBase += offset; boot_text_mapped = 1; } @@ -229,22 +228,24 @@ void btext_update_display(unsigned long phys, int width, int height, int depth, int pitch) { - if (disp_bi == 0) + boot_infos_t *bi = &disp_bi; + + if (bi->dispDeviceBase == 0) return; - /* check it's the same frame buffer (within 64MB) */ - if ((phys ^ (unsigned long)disp_bi->dispDeviceBase) & 0xfc000000) { + + /* check it's the same frame buffer (within 256MB) */ + if ((phys ^ (unsigned long)bi->dispDeviceBase) & 0xf0000000) return; - } - disp_bi->dispDeviceBase = (__u8 *) phys; - disp_bi->dispDeviceRect[0] = 0; - disp_bi->dispDeviceRect[1] = 0; - disp_bi->dispDeviceRect[2] = width; - disp_bi->dispDeviceRect[3] = height; - disp_bi->dispDeviceDepth = depth; - disp_bi->dispDeviceRowBytes = pitch; + bi->dispDeviceBase = (__u8 *) phys; + bi->dispDeviceRect[0] = 0; + bi->dispDeviceRect[1] = 0; + bi->dispDeviceRect[2] = width; + bi->dispDeviceRect[3] = height; + bi->dispDeviceDepth = depth; + bi->dispDeviceRowBytes = pitch; if (boot_text_mapped) { - iounmap(disp_bi->logicalDisplayBase); + iounmap(bi->logicalDisplayBase); boot_text_mapped = 0; } map_boot_text(); @@ -256,8 +257,7 @@ btext_update_display(unsigned long phys, int width, int height, void BTEXT btext_clearscreen(void) { - unsigned long offset = reloc_offset(); - boot_infos_t* bi = PTRRELOC(RELOC(disp_bi)); + boot_infos_t* bi = &disp_bi; unsigned long *base = (unsigned long *)calc_base(bi, 0, 0); unsigned long width = ((bi->dispDeviceRect[2] - bi->dispDeviceRect[0]) * (bi->dispDeviceDepth >> 3)) >> 2; @@ -279,8 +279,7 @@ __inline__ void dcbst(const void* addr) void BTEXT btext_flushscreen(void) { - unsigned long offset = reloc_offset(); - boot_infos_t* bi = PTRRELOC(RELOC(disp_bi)); + boot_infos_t* bi = &disp_bi; unsigned long *base = (unsigned long *)calc_base(bi, 0, 0); unsigned long width = ((bi->dispDeviceRect[2] - bi->dispDeviceRect[0]) * (bi->dispDeviceDepth >> 3)) >> 2; @@ -301,8 +300,7 @@ void BTEXT btext_flushscreen(void) static BTEXT void scrollscreen(void) { - unsigned long offset = reloc_offset(); - boot_infos_t* bi = PTRRELOC(RELOC(disp_bi)); + boot_infos_t* bi = &disp_bi; unsigned long *src = (unsigned long *)calc_base(bi,0,16); unsigned long *dst = (unsigned long *)calc_base(bi,0,0); unsigned long width = ((bi->dispDeviceRect[2] - bi->dispDeviceRect[0]) * @@ -336,49 +334,48 @@ scrollscreen(void) void BTEXT btext_drawchar(char c) { - unsigned long offset = reloc_offset(); int cline = 0, x; - if (!RELOC(boot_text_mapped)) + if (!boot_text_mapped) return; switch (c) { case '\b': - if (RELOC(g_loc_X) > 0) - --RELOC(g_loc_X); + if (g_loc_X > 0) + --g_loc_X; break; case '\t': - RELOC(g_loc_X) = (RELOC(g_loc_X) & -8) + 8; + g_loc_X = (g_loc_X & -8) + 8; break; case '\r': - RELOC(g_loc_X) = 0; + g_loc_X = 0; break; case '\n': - RELOC(g_loc_X) = 0; - RELOC(g_loc_Y)++; + g_loc_X = 0; + g_loc_Y++; cline = 1; break; default: - draw_byte(c, RELOC(g_loc_X)++, RELOC(g_loc_Y)); + draw_byte(c, g_loc_X++, g_loc_Y); } - if (RELOC(g_loc_X) >= RELOC(g_max_loc_X)) { - RELOC(g_loc_X) = 0; - RELOC(g_loc_Y)++; + if (g_loc_X >= g_max_loc_X) { + g_loc_X = 0; + g_loc_Y++; cline = 1; } #ifndef NO_SCROLL - while (RELOC(g_loc_Y) >= RELOC(g_max_loc_Y)) { + while (g_loc_Y >= g_max_loc_Y) { scrollscreen(); - RELOC(g_loc_Y)--; + g_loc_Y--; } #else /* wrap around from bottom to top of screen so we don't waste time scrolling each line. -- paulus. */ - if (RELOC(g_loc_Y) >= RELOC(g_max_loc_Y)) - RELOC(g_loc_Y) = 0; + if (g_loc_Y >= g_max_loc_Y) + g_loc_Y = 0; if (cline) { - for (x = 0; x < RELOC(g_max_loc_X); ++x) - draw_byte(' ', x, RELOC(g_loc_Y)); + for (x = 0; x < g_max_loc_X; ++x) + draw_byte(' ', x, g_loc_Y); } #endif } @@ -386,9 +383,7 @@ void BTEXT btext_drawchar(char c) void BTEXT btext_drawstring(const char *c) { - unsigned long offset = reloc_offset(); - - if (!RELOC(boot_text_mapped)) + if (!boot_text_mapped) return; while (*c) btext_drawchar(*c++); @@ -398,34 +393,34 @@ void BTEXT btext_drawhex(unsigned long v) { static char hex_table[] = "0123456789abcdef"; - unsigned long offset = reloc_offset(); - if (!RELOC(boot_text_mapped)) + if (!boot_text_mapped) return; - btext_drawchar(RELOC(hex_table)[(v >> 28) & 0x0000000FUL]); - btext_drawchar(RELOC(hex_table)[(v >> 24) & 0x0000000FUL]); - btext_drawchar(RELOC(hex_table)[(v >> 20) & 0x0000000FUL]); - btext_drawchar(RELOC(hex_table)[(v >> 16) & 0x0000000FUL]); - btext_drawchar(RELOC(hex_table)[(v >> 12) & 0x0000000FUL]); - btext_drawchar(RELOC(hex_table)[(v >> 8) & 0x0000000FUL]); - btext_drawchar(RELOC(hex_table)[(v >> 4) & 0x0000000FUL]); - btext_drawchar(RELOC(hex_table)[(v >> 0) & 0x0000000FUL]); + btext_drawchar(hex_table[(v >> 28) & 0x0000000FUL]); + btext_drawchar(hex_table[(v >> 24) & 0x0000000FUL]); + btext_drawchar(hex_table[(v >> 20) & 0x0000000FUL]); + btext_drawchar(hex_table[(v >> 16) & 0x0000000FUL]); + btext_drawchar(hex_table[(v >> 12) & 0x0000000FUL]); + btext_drawchar(hex_table[(v >> 8) & 0x0000000FUL]); + btext_drawchar(hex_table[(v >> 4) & 0x0000000FUL]); + btext_drawchar(hex_table[(v >> 0) & 0x0000000FUL]); btext_drawchar(' '); } static void BTEXT draw_byte(unsigned char c, long locX, long locY) { - unsigned long offset = reloc_offset(); - boot_infos_t* bi = PTRRELOC(RELOC(disp_bi)); + boot_infos_t* bi = &disp_bi; unsigned char *base = calc_base(bi, locX << 3, locY << 4); - unsigned char *font = &RELOC(vga_font)[((unsigned long)c) * 16]; + unsigned char *font = &vga_font[((unsigned long)c) * 16]; int rb = bi->dispDeviceRowBytes; switch(bi->dispDeviceDepth) { + case 24: case 32: draw_byte_32(font, (unsigned long *)base, rb); break; + case 15: case 16: draw_byte_16(font, (unsigned long *)base, rb); break; @@ -490,8 +485,7 @@ draw_byte_16(unsigned char *font, unsigned long *base, int rb) int l, bits; int fg = 0xFFFFFFFFUL; int bg = 0x00000000UL; - unsigned long offset = reloc_offset(); - unsigned long *eb = RELOC(expand_bits_16); + unsigned long *eb = expand_bits_16; for (l = 0; l < 16; ++l) { @@ -510,8 +504,7 @@ draw_byte_8(unsigned char *font, unsigned long *base, int rb) int l, bits; int fg = 0x0F0F0F0FUL; int bg = 0x00000000UL; - unsigned long offset = reloc_offset(); - unsigned long *eb = RELOC(expand_bits_8); + unsigned long *eb = expand_bits_8; for (l = 0; l < 16; ++l) { diff --git a/arch/ppc/kernel/cputable.c b/arch/ppc/kernel/cputable.c index f718c1a91667..d6f8eccb3d76 100644 --- a/arch/ppc/kernel/cputable.c +++ b/arch/ppc/kernel/cputable.c @@ -26,15 +26,14 @@ extern void __setup_cpu_603(int cpu_nr); extern void __setup_cpu_604(int cpu_nr); extern void __setup_cpu_750(int cpu_nr); extern void __setup_cpu_7400(int cpu_nr); +extern void __setup_cpu_7410(int cpu_nr); extern void __setup_cpu_7450(int cpu_nr); extern void __setup_cpu_power3(int cpu_nr); -extern void __setup_cpu_power4(int cpu_nr); extern void __setup_cpu_8xx(int cpu_nr); extern void __setup_cpu_generic(int cpu_nr); -#define CLASSIC_PPC (!defined(CONFIG_8xx) && \ - !defined(CONFIG_4xx) && !defined(CONFIG_POWER3) && \ - !defined(CONFIG_POWER4) && !defined(CONFIG_PPC_ISERIES)) +#define CLASSIC_PPC (!defined(CONFIG_8xx) && !defined(CONFIG_4xx) && \ + !defined(CONFIG_POWER3) && !defined(CONFIG_PPC_ISERIES)) /* This table only contains "desktop" CPUs, it need to be filled with embedded * ones as well... @@ -113,16 +112,40 @@ struct cpu_spec cpu_specs[] = { 32, 32, __setup_cpu_604 }, - { /* 750 (0x4202, don't support TAU ?) */ - 0xffffffff, 0x00084202, "750", + { /* 740/750 (0x4202, don't support TAU ?) */ + 0xffffffff, 0x00084202, "740/750", CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB | CPU_FTR_L2CR | CPU_FTR_HPTE_TABLE, COMMON_PPC, 32, 32, __setup_cpu_750 }, - { /* 750CX */ - 0xffffff00, 0x00082200, "750CX", + { /* 745/755 */ + 0xfffff000, 0x00083000, "745/755", + CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB | + CPU_FTR_L2CR | CPU_FTR_TAU | CPU_FTR_HPTE_TABLE, + COMMON_PPC, + 32, 32, + __setup_cpu_750 + }, + { /* 750CX (80100 and 8010x?) */ + 0xfffffff0, 0x00080100, "750CX", + CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB | + CPU_FTR_L2CR | CPU_FTR_TAU | CPU_FTR_HPTE_TABLE, + COMMON_PPC, + 32, 32, + __setup_cpu_750 + }, + { /* 750CX (82201 and 82202) */ + 0xfffffff0, 0x00082200, "750CX", + CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB | + CPU_FTR_L2CR | CPU_FTR_TAU | CPU_FTR_HPTE_TABLE, + COMMON_PPC, + 32, 32, + __setup_cpu_750 + }, + { /* 750CXe (82214) */ + 0xfffffff0, 0x00082210, "750CXe", CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB | CPU_FTR_L2CR | CPU_FTR_TAU | CPU_FTR_HPTE_TABLE, COMMON_PPC, @@ -159,9 +182,18 @@ struct cpu_spec cpu_specs[] = { CPU_FTR_L2CR | CPU_FTR_TAU | CPU_FTR_ALTIVEC_COMP | CPU_FTR_HPTE_TABLE, COMMON_PPC | PPC_FEATURE_HAS_ALTIVEC, 32, 32, - __setup_cpu_7400 + __setup_cpu_7410 }, - { /* 7450 */ + { /* 7450 2.0 - no doze/nap */ + 0xffffffff, 0x80000200, "7450", + CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | + CPU_FTR_L2CR | CPU_FTR_TAU | CPU_FTR_ALTIVEC_COMP | + CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450, + COMMON_PPC | PPC_FEATURE_HAS_ALTIVEC, + 32, 32, + __setup_cpu_7450 + }, + { /* 7450 others */ 0xffff0000, 0x80000000, "7450", CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB | CPU_FTR_L2CR | CPU_FTR_TAU | CPU_FTR_ALTIVEC_COMP | @@ -215,15 +247,6 @@ struct cpu_spec cpu_specs[] = { __setup_cpu_power3 }, #endif /* CONFIG_PPC64BRIDGE */ -#ifdef CONFIG_POWER4 - { /* Power4 */ - 0xffff0000, 0x00350000, "Power4", - CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE, - COMMON_PPC | PPC_FEATURE_64, - 128, 128, - __setup_cpu_power4 - }, -#endif /* CONFIG_POWER4 */ #ifdef CONFIG_8xx { /* 8xx */ 0xffff0000, 0x00500000, "8xx", @@ -270,6 +293,20 @@ struct cpu_spec cpu_specs[] = { 32, 32, 0, /*__setup_cpu_405 */ }, + { /* STB 04xxx */ + 0xffff0000, 0x41810000, "STB04xxx", + CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB, + PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, + 32, 32, + 0, /*__setup_cpu_405 */ + }, + { /* NP405L */ + 0xffff0000, 0x41610000, "NP405L", + CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB, + PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, + 16, 8, + 0, /*__setup_cpu_405 */ + }, #endif /* CONFIG_4xx */ #if !CLASSIC_PPC { /* default match */ diff --git a/arch/ppc/kernel/entry.S b/arch/ppc/kernel/entry.S index cb4ff46032f5..70fae23e5ffd 100644 --- a/arch/ppc/kernel/entry.S +++ b/arch/ppc/kernel/entry.S @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.entry.S 1.22 08/15/01 22:43:06 paulus + * BK Id: %F% %I% %G% %U% %#% */ /* * PowerPC version @@ -11,6 +11,7 @@ * rewritten by Paul Mackerras. * Copyright (C) 1996 Paul Mackerras. * MPC8xx modifications Copyright (C) 1997 Dan Malek (dmalek@jlc.net). + * Adaptations for iSeries Lpar by Mike Corrigan & Dave Boutcher * * This file contains the system call entry code, context switch * code, and exception/interrupt return code for PowerPC. @@ -22,7 +23,6 @@ * */ -#include "ppc_asm.h" #include <linux/config.h> #include <linux/errno.h> #include <linux/sys.h> @@ -31,6 +31,11 @@ #include <asm/page.h> #include <asm/mmu.h> #include <asm/cputable.h> +#include <asm/ppc_asm.h> +#include "ppc_defs.h" +#ifdef CONFIG_PPC_ISERIES +#include "iSeries_asm.h" +#endif /* CONFIG_PPC_ISERIES */ #undef SHOW_SYSCALLS #undef SHOW_SYSCALLS_TASK @@ -45,6 +50,10 @@ show_syscalls_task: * Handle a system call. */ .text + .stabs "arch/ppc/kernel/",N_SO,0,0,0f + .stabs "entry.S",N_SO,0,0,0f +0: + _GLOBAL(DoSyscall) stw r0,THREAD+LAST_SYSCALL(r2) lwz r11,_CCR(r1) /* Clear SO bit in CR */ @@ -86,8 +95,8 @@ _GLOBAL(DoSyscall) beq- 10f cmpi 0,r0,0x6666 /* Special case for 'sys_rt_sigreturn' */ beq- 16f - lwz r10,TASK_PTRACE(r2) - andi. r10,r10,PT_TRACESYS + lbz r10,SYSCALL_TRACE(r2) + cmpwi r10,0 bne- 50f cmpli 0,r0,NR_syscalls bge- 66f @@ -142,7 +151,7 @@ ret_from_syscall_1: bge ret_from_except b 20b /* Traced system call support */ -50: bl syscall_trace +50: bl do_syscall_trace lwz r0,GPR0(r1) /* Restore original registers */ lwz r3,GPR3(r1) lwz r4,GPR4(r1) @@ -177,7 +186,7 @@ ret_from_syscall_2: oris r10,r10,0x1000 stw r10,_CCR(r1) 60: stw r3,GPR3(r1) /* Update return value */ - bl syscall_trace + bl do_syscall_trace b ret_from_except 66: li r3,ENOSYS b 52b @@ -197,6 +206,9 @@ ret_from_syscall_2: * On entry, r3 points to the THREAD for the current task, r4 * points to the THREAD for the new task. * + * This routine is always called with interrupts disabled + * (soft disabled for iSeries). + * * Note: there are two ways to get to the "going out" portion * of this code; either by coming in via the entry (_switch) * or via "fork" which must set up an environment equivalent @@ -216,6 +228,7 @@ _GLOBAL(_switch) SAVE_8GPRS(14, r1) SAVE_10GPRS(22, r1) mflr r20 /* Return to switch caller */ + stw r20,INT_FRAME_SIZE+4(r1) mfmsr r22 li r0,MSR_FP /* Disable floating-point */ #ifdef CONFIG_ALTIVEC @@ -223,10 +236,12 @@ BEGIN_FTR_SECTION oris r0,r0,MSR_VEC@h /* Disable altivec */ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) #endif /* CONFIG_ALTIVEC */ + and. r0,r0,r22 /* FP or altivec enabled? */ + beq+ 1f andc r22,r22,r0 mtmsr r22 isync - stw r20,_NIP(r1) +1: stw r20,_NIP(r1) stw r22,_MSR(r1) stw r20,_LINK(r1) mfcr r20 @@ -261,9 +276,9 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) .globl ret_from_fork ret_from_fork: bl schedule_tail -#error lwz r0,TASK_PTRACE(r2) - andi. r0,r0,PT_TRACESYS -#error bnel- syscall_trace + lbz r0,SYSCALL_TRACE(r2) + cmpwi r0,0 + bnel- do_syscall_trace b ret_from_except .globl ret_from_intercept @@ -276,94 +291,115 @@ ret_from_intercept: beq restore .globl ret_from_except ret_from_except: - lwz r3,_MSR(r1) /* Returning to user mode? */ - andi. r3,r3,MSR_PR - beq+ do_signal_ret /* if so, check need_resched and signals */ -#error lwz r3,NEED_RESCHED(r2) - cmpi 0,r3,0 /* check need_resched flag */ - beq+ 7f - bl schedule -#error 7: lwz r5,SIGPENDING(r2) /* Check for pending unblocked signals */ - cmpwi 0,r5,0 - beq+ do_signal_ret - li r3,0 - addi r4,r1,STACK_FRAME_OVERHEAD -#error bl do_signal - .globl do_signal_ret -do_signal_ret: - .globl ret_to_user_hook -ret_to_user_hook: - nop -restore: - lwz r3,_XER(r1) - mtspr XER,r3 - REST_10GPRS(9,r1) - REST_10GPRS(19,r1) - REST_2GPRS(29,r1) + REST_10GPRS(13,r1) + REST_8GPRS(23,r1) REST_GPR(31,r1) - /* make sure we hard disable here, even if rtl is active, to protect - * SRR[01] and SPRG2 -- Cort - */ - mfmsr r0 /* Get current interrupt state */ - rlwinm r0,r0,0,17,15 /* clear MSR_EE in r0 */ + /* Hard-disable interrupts so that current->work can't change + * between when we test it and when we return from the interrupt. */ +recheck: + mfmsr r10 + rlwinm r0,r10,0,17,15 /* clear MSR_EE in r0 */ +#ifdef CONFIG_4xx + rlwinm r0,r0,0,23,21 /* clear MSR_DE in r0 */ +#endif SYNC /* Some chip revs have problems here... */ mtmsr r0 /* Update machine state */ - stwcx. r0,0,r1 /* to clear the reservation */ + lwz r3,_MSR(r1) /* Returning to user mode? */ + andi. r3,r3,MSR_PR + beq+ restore /* if not, just restore regs and return */ + + /* Check current->work */ + lwz r3,TASK_WORK(r2) + rlwinm. r0,r3,0,16,7 /* need_resched, sigpending, notify_resume */ + bne do_work + + .globl ret_to_user_hook +ret_to_user_hook: + nop - /* if returning to user mode, set new sprg2 and save kernel SP */ - lwz r0,_MSR(r1) - andi. r0,r0,MSR_PR - beq+ 1f #ifdef CONFIG_ALTIVEC BEGIN_FTR_SECTION lwz r0,THREAD+THREAD_VRSAVE(r2) mtspr SPRN_VRSAVE,r0 /* if G4, restore VRSAVE reg */ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) #endif /* CONFIG_ALTIVEC */ + addi r0,r1,INT_FRAME_SIZE /* size of frame */ stw r0,THREAD+KSP(r2) /* save kernel stack pointer */ + +#ifndef CONFIG_PPC_ISERIES tophys(r8,r1) CLR_TOP32(r8) mtspr SPRG2,r8 /* phys exception stack pointer */ -1: +#else /* CONFIG_PPC_ISERIES */ + mfspr r2,SPRG1 /* Get Paca address */ + stw r1,PACAKSAVE(r2) /* save exception stack pointer */ +#endif /* CONFIG_PPC_ISERIES */ + + /* interrupts are hard-disabled at this point */ +restore: + REST_8GPRS(4, r1) + REST_GPR(12, r1) + lwz r3,_XER(r1) + mtspr XER,r3 + + PPC405_ERR77(0,r1) + stwcx. r0,0,r1 /* to clear the reservation */ + lwz r3,_CTR(r1) lwz r0,_LINK(r1) mtctr r3 mtlr r0 - REST_4GPRS(3, r1) - REST_2GPRS(7, r1) - /* We have to "dummy" load from the context save area in case - * these instructions cause an MMU fault. If this happens - * after we load SRR0/SRR1, our return context is hosed. -- Dan - */ - lwz r0,GPR0(r1) - lwz r0,GPR2(r1) - lwz r0,GPR1(r1) + lwz r0,_MSR(r1) + lwz r3,_CCR(r1) + FIX_SRR1(r0,r2) + lwz r2,_NIP(r1) + mtcrf 0xFF,r3 - /* We re-use r3,r4 here (the load above was to cause the MMU - * fault if necessary). Using r3,r4 removes the need to "dummy" - * load the CCR and NIP. Since we load them we may as well - * use them. + /* + * We can't afford to take an exception between setting SRR0/1 + * and the rfi. Since GPR0(r1) .. GPR3(r1) are in the same cache + * line, loading r3 here should mean that we should have a HPTE + * (for classic PPC) or TLB entry (for 4xx/8xx) for that cache + * line, even if it isn't covered by a BAT register. + * In addition, the cache line itself will be in L1 cache. + * There is still the possibility of the HPTE getting evicted + * on SMP systems. */ - lwz r3,_CCR(r1) - lwz r4,_NIP(r1) + lwz r3,GPR3(r1) - lwz r0,_MSR(r1) - FIX_SRR1(r0,r2) mtspr SRR1,r0 - mtcrf 0xFF,r3 - mtspr SRR0,r4 + mtspr SRR0,r2 lwz r0,GPR0(r1) lwz r2,GPR2(r1) - lwz r3,GPR3(r1) - lwz r4,GPR4(r1) lwz r1,GPR1(r1) SYNC + PPC405_ERR77_SYNC RFI +do_work: + ori r10,r10,MSR_EE + SYNC + mtmsr r10 /* hard-enable interrupts */ + rlwinm. r0,r3,0,0,7 /* test need_resched */ + beq 1f + bl schedule + b recheck +1: + rlwinm. r0,r3,0,16,23 /* test sigpending */ + beq 2f + li r3,0 + addi r4,r1,STACK_FRAME_OVERHEAD + bl do_signal + b recheck +2: + /* nobody uses work.notify_resume yet */ + li r0,0 + stb r0,NOTIFY_RESUME(r2) + b recheck /* * PROM code for specific machines follows. Put it @@ -375,8 +411,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) * On CHRP, the Run-Time Abstraction Services (RTAS) have to be * called with the MMU off. */ - .globl enter_rtas -enter_rtas: +_GLOBAL(enter_rtas) mflr r0 stw r0,20(r1) lis r4,rtas_data@ha @@ -391,9 +426,9 @@ enter_rtas: mfmsr r9 stw r9,8(r1) li r0,0 - ori r0,r0,MSR_EE|MSR_SE|MSR_BE + ori r0,r0,MSR_EE|MSR_SE|MSR_BE|MSR_FE0|MSR_FE1 andc r0,r9,r0 - li r10,MSR_IR|MSR_DR|MSR_FE0|MSR_FE1|MSR_FP + li r10,MSR_IR|MSR_DR|MSR_FP andc r9,r0,r10 SYNC /* disable interrupts so SRR0/1 */ mtmsr r0 /* don't get trashed */ diff --git a/arch/ppc/kernel/feature.c b/arch/ppc/kernel/feature.c deleted file mode 100644 index 21c1d9e20f2f..000000000000 --- a/arch/ppc/kernel/feature.c +++ /dev/null @@ -1,1300 +0,0 @@ -/* - * BK Id: SCCS/s.feature.c 1.21 09/08/01 15:47:42 paulus - */ -/* - * arch/ppc/kernel/feature.c - * - * Copyright (C) 1996 Paul Mackerras (paulus@cs.anu.edu.au) - * Ben. Herrenschmidt (benh@kernel.crashing.org) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - */ -#include <linux/config.h> -#include <linux/types.h> -#include <linux/init.h> -#include <linux/delay.h> -#include <linux/kernel.h> -#include <linux/sched.h> -#include <linux/spinlock.h> -#include <asm/sections.h> -#include <asm/errno.h> -#include <asm/ohare.h> -#include <asm/heathrow.h> -#include <asm/keylargo.h> -#include <asm/uninorth.h> -#include <asm/io.h> -#include <asm/prom.h> -#include <asm/feature.h> -#include <asm/dbdma.h> -#include <asm/machdep.h> - -#undef DEBUG_FEATURE - -#define MAX_FEATURE_CONTROLLERS 2 -#define FREG(c,r) (&(((c)->reg)[(r)>>2])) - -/* Keylargo reg. access. */ -#define KL_FCR(r) (keylargo_base + ((r) >> 2)) -#define KL_IN(r) (in_le32(KL_FCR(r))) -#define KL_OUT(r,v) (out_le32(KL_FCR(r), (v))) -#define KL_BIS(r,v) (KL_OUT((r), KL_IN(r) | (v))) -#define KL_BIC(r,v) (KL_OUT((r), KL_IN(r) & ~(v))) -#define KL_GPIO_IN(r) (in_8(((volatile u8 *)keylargo_base)+(r))) -#define KL_GPIO_OUT(r,v) (out_8(((volatile u8 *)keylargo_base)+(r), (v))) -#define KL_LOCK() spin_lock_irqsave(&keylargo->lock, flags) -#define KL_UNLOCK() spin_unlock_irqrestore(&keylargo->lock, flags) - -/* Uni-N reg. access. Note that Uni-N regs are big endian */ -#define UN_REG(r) (uninorth_base + ((r) >> 2)) -#define UN_IN(r) (in_be32(UN_REG(r))) -#define UN_OUT(r,v) (out_be32(UN_REG(r), (v))) -#define UN_BIS(r,v) (UN_OUT((r), UN_IN(r) | (v))) -#define UN_BIC(r,v) (UN_OUT((r), UN_IN(r) & ~(v))) - -typedef struct feature_bit { - int reg; /* reg. offset from mac-io base */ - unsigned int polarity; /* 0 = normal, 1 = inverse */ - unsigned int mask; /* bit mask */ -} fbit; - -/* Those features concern for OHare-based PowerBooks (2400, 3400, 3500) - */ -static fbit feature_bits_ohare_pbook[] __pmacdata = { - {0x38,0,0}, /* FEATURE_null */ - {0x38,0,OH_SCC_RESET}, /* FEATURE_Serial_reset */ - {0x38,0,OH_SCC_ENABLE}, /* FEATURE_Serial_enable */ - {0x38,0,OH_SCCA_IO}, /* FEATURE_Serial_IO_A */ - {0x38,0,OH_SCCB_IO}, /* FEATURE_Serial_IO_B */ - {0x38,0,OH_FLOPPY_ENABLE}, /* FEATURE_SWIM3_enable */ - {0x38,0,OH_MESH_ENABLE}, /* FEATURE_MESH_enable */ - {0x38,0,OH_IDE0_ENABLE}, /* FEATURE_IDE0_enable */ - {0x38,1,OH_IDE0_RESET_N}, /* FEATURE_IDE0_reset */ - {0x38,0,OH_IOBUS_ENABLE}, /* FEATURE_IOBUS_enable */ - {0x38,1,OH_BAY_RESET_N}, /* FEATURE_Mediabay_reset */ - {0x38,1,OH_BAY_POWER_N}, /* FEATURE_Mediabay_power */ - {0x38,0,OH_BAY_PCI_ENABLE}, /* FEATURE_Mediabay_PCI_enable */ - {0x38,0,OH_BAY_IDE_ENABLE}, /* FEATURE_IDE1_enable */ - {0x38,1,OH_IDE1_RESET_N}, /* FEATURE_IDE1_reset */ - {0x38,0,OH_BAY_FLOPPY_ENABLE}, /* FEATURE_Mediabay_floppy_enable */ - {0x38,0,0}, /* FEATURE_BMac_reset */ - {0x38,0,0}, /* FEATURE_BMac_IO_enable */ - {0x38,0,0}, /* FEATURE_Modem_power */ - {0x38,0,0}, /* FEATURE_Slow_SCC_PCLK */ - {0x38,0,0}, /* FEATURE_Sound_Power */ - {0x38,0,0}, /* FEATURE_Sound_CLK_Enable */ - {0x38,0,0}, /* FEATURE_IDE2_enable */ - {0x38,0,0}, /* FEATURE_IDE2_reset */ - {0x38,0,0}, /* FEATURE_Mediabay_IDE_switch */ - {0x38,0,0}, /* FEATURE_Mediabay_content */ - {0x38,0,0}, /* FEATURE_Airport_reset */ -}; - -/* Those bits concern heathrow-based desktop machines (Beige G3s). We have removed - * the SCC related bits and init them once. They have proven to occasionally cause - * problems with the desktop units. - */ -static fbit feature_bits_heathrow[] __pmacdata = { - {0x38,0,0}, /* FEATURE_null */ - {0x38,0,0}, /* FEATURE_Serial_reset */ - {0x38,0,0}, /* FEATURE_Serial_enable */ - {0x38,0,0}, /* FEATURE_Serial_IO_A */ - {0x38,0,0}, /* FEATURE_Serial_IO_B */ - {0x38,0,HRW_SWIM_ENABLE}, /* FEATURE_SWIM3_enable */ - {0x38,0,HRW_MESH_ENABLE}, /* FEATURE_MESH_enable */ - {0x38,0,HRW_IDE0_ENABLE}, /* FEATURE_IDE0_enable */ - {0x38,1,HRW_IDE0_RESET_N}, /* FEATURE_IDE0_reset */ - {0x38,0,HRW_IOBUS_ENABLE}, /* FEATURE_IOBUS_enable */ - {0x38,1,0}, /* FEATURE_Mediabay_reset */ - {0x38,1,0}, /* FEATURE_Mediabay_power */ - {0x38,0,0}, /* FEATURE_Mediabay_PCI_enable */ - {0x38,0,HRW_BAY_IDE_ENABLE}, /* FEATURE_IDE1_enable */ - {0x38,1,HRW_IDE1_RESET_N}, /* FEATURE_IDE1_reset */ - {0x38,0,0}, /* FEATURE_Mediabay_floppy_enable */ - {0x38,0,HRW_BMAC_RESET}, /* FEATURE_BMac_reset */ - {0x38,0,HRW_BMAC_IO_ENABLE}, /* FEATURE_BMac_IO_enable */ - {0x38,1,0}, /* FEATURE_Modem_power */ - {0x38,0,HRW_SLOW_SCC_PCLK}, /* FEATURE_Slow_SCC_PCLK */ - {0x38,1,0}, /* FEATURE_Sound_Power */ - {0x38,0,0}, /* FEATURE_Sound_CLK_Enable */ - {0x38,0,0}, /* FEATURE_IDE2_enable */ - {0x38,0,0}, /* FEATURE_IDE2_reset */ - {0x38,0,0}, /* FEATURE_Mediabay_IDE_switch */ - {0x38,0,0}, /* FEATURE_Mediabay_content */ - {0x38,0,0}, /* FEATURE_Airport_reset */ -}; - -/* Those bits concern heathrow-based PowerBooks (wallstreet/mainstreet). - * Heathrow-based desktop macs (Beige G3s) are _not_ handled here - */ -static fbit feature_bits_wallstreet[] __pmacdata = { - {0x38,0,0}, /* FEATURE_null */ - {0x38,0,HRW_RESET_SCC}, /* FEATURE_Serial_reset */ - {0x38,0,HRW_SCC_ENABLE}, /* FEATURE_Serial_enable */ - {0x38,0,HRW_SCCA_IO}, /* FEATURE_Serial_IO_A */ - {0x38,0,HRW_SCCB_IO}, /* FEATURE_Serial_IO_B */ - {0x38,0,HRW_SWIM_ENABLE}, /* FEATURE_SWIM3_enable */ - {0x38,0,HRW_MESH_ENABLE}, /* FEATURE_MESH_enable */ - {0x38,0,HRW_IDE0_ENABLE}, /* FEATURE_IDE0_enable */ - {0x38,1,HRW_IDE0_RESET_N}, /* FEATURE_IDE0_reset */ - {0x38,0,HRW_IOBUS_ENABLE}, /* FEATURE_IOBUS_enable */ - {0x38,1,HRW_BAY_RESET_N}, /* FEATURE_Mediabay_reset */ - {0x38,1,HRW_BAY_POWER_N}, /* FEATURE_Mediabay_power */ - {0x38,0,HRW_BAY_PCI_ENABLE}, /* FEATURE_Mediabay_PCI_enable */ - {0x38,0,HRW_BAY_IDE_ENABLE}, /* FEATURE_IDE1_enable */ - {0x38,1,HRW_IDE1_RESET_N}, /* FEATURE_IDE1_reset */ - {0x38,0,HRW_BAY_FLOPPY_ENABLE}, /* FEATURE_Mediabay_floppy_enable */ - {0x38,0,HRW_BMAC_RESET}, /* FEATURE_BMac_reset */ - {0x38,0,HRW_BMAC_IO_ENABLE}, /* FEATURE_BMac_IO_enable */ - {0x38,1,HRW_MODEM_POWER_N}, /* FEATURE_Modem_power */ - {0x38,0,HRW_SLOW_SCC_PCLK}, /* FEATURE_Slow_SCC_PCLK */ - {0x38,1,HRW_SOUND_POWER_N}, /* FEATURE_Sound_Power */ - {0x38,0,HRW_SOUND_CLK_ENABLE}, /* FEATURE_Sound_CLK_Enable */ - {0x38,0,0}, /* FEATURE_IDE2_enable */ - {0x38,0,0}, /* FEATURE_IDE2_reset */ - {0x38,0,0}, /* FEATURE_Mediabay_IDE_switch */ - {0x38,0,0}, /* FEATURE_Mediabay_content */ - {0x38,0,0}, /* FEATURE_Airport_reset */ -}; - -/* - * Those bits are from a 1999 G3 PowerBook, with a paddington chip. - * Mostly the same as the heathrow. They are used on both PowerBooks - * and desktop machines using the paddington chip - */ -static fbit feature_bits_paddington[] __pmacdata = { - {0x38,0,0}, /* FEATURE_null */ - {0x38,0,PADD_RESET_SCC}, /* FEATURE_Serial_reset */ - {0x38,0,HRW_SCC_ENABLE}, /* FEATURE_Serial_enable */ - {0x38,0,HRW_SCCA_IO}, /* FEATURE_Serial_IO_A */ - {0x38,0,HRW_SCCB_IO}, /* FEATURE_Serial_IO_B */ - {0x38,0,HRW_SWIM_ENABLE}, /* FEATURE_SWIM3_enable */ - {0x38,0,HRW_MESH_ENABLE}, /* FEATURE_MESH_enable */ - {0x38,0,HRW_IDE0_ENABLE}, /* FEATURE_IDE0_enable */ - {0x38,1,HRW_IDE0_RESET_N}, /* FEATURE_IDE0_reset */ - {0x38,0,HRW_IOBUS_ENABLE}, /* FEATURE_IOBUS_enable */ - {0x38,1,HRW_BAY_RESET_N}, /* FEATURE_Mediabay_reset */ - {0x38,1,HRW_BAY_POWER_N}, /* FEATURE_Mediabay_power */ - {0x38,0,HRW_BAY_PCI_ENABLE}, /* FEATURE_Mediabay_PCI_enable */ - {0x38,0,HRW_BAY_IDE_ENABLE}, /* FEATURE_IDE1_enable */ - {0x38,1,HRW_IDE1_RESET_N}, /* FEATURE_IDE1_reset */ - {0x38,0,HRW_BAY_FLOPPY_ENABLE}, /* FEATURE_Mediabay_floppy_enable */ - {0x38,0,HRW_BMAC_RESET}, /* FEATURE_BMac_reset */ - {0x38,0,HRW_BMAC_IO_ENABLE}, /* FEATURE_BMac_IO_enable */ - {0x38,1,PADD_MODEM_POWER_N}, /* FEATURE_Modem_power */ - {0x38,0,HRW_SLOW_SCC_PCLK}, /* FEATURE_Slow_SCC_PCLK */ - {0x38,1,HRW_SOUND_POWER_N}, /* FEATURE_Sound_Power */ - {0x38,0,HRW_SOUND_CLK_ENABLE}, /* FEATURE_Sound_CLK_Enable */ - {0x38,0,0}, /* FEATURE_IDE2_enable */ - {0x38,0,0}, /* FEATURE_IDE2_reset */ - {0x38,0,0}, /* FEATURE_Mediabay_IDE_switch */ - {0x38,0,0}, /* FEATURE_Mediabay_content */ - {0x38,0,0}, /* FEATURE_Airport_reset */ -}; - -/* Those bits are for Core99 machines (iBook,G4,iMacSL/DV,Pismo,...). - * Note: Different sets may be needed for iBook, especially for sound - */ -static fbit feature_bits_keylargo[] __pmacdata = { - {0x38,0,0}, /* FEATURE_null */ - {0x38,0,KL0_SCC_RESET}, /* FEATURE_Serial_reset */ - {0x38,0,KL0_SERIAL_ENABLE}, /* FEATURE_Serial_enable */ - {0x38,0,KL0_SCC_A_INTF_ENABLE}, /* FEATURE_Serial_IO_A */ - {0x38,0,KL0_SCC_B_INTF_ENABLE}, /* FEATURE_Serial_IO_B */ - {0x38,0,0}, /* FEATURE_SWIM3_enable */ - {0x38,0,0}, /* FEATURE_MESH_enable */ - {0x3c,0,KL1_EIDE0_ENABLE}, /* FEATURE_IDE0_enable */ - {0x3c,1,KL1_EIDE0_RESET_N}, /* FEATURE_IDE0_reset */ - {0x38,0,0}, /* FEATURE_IOBUS_enable */ - {0x34,1,KL_MBCR_MB0_DEV_RESET}, /* FEATURE_Mediabay_reset */ - {0x34,1,KL_MBCR_MB0_DEV_POWER}, /* FEATURE_Mediabay_power */ - {0x38,0,0}, /* FEATURE_Mediabay_PCI_enable */ - {0x3c,0,KL1_EIDE1_ENABLE}, /* FEATURE_IDE1_enable */ - {0x3c,1,KL1_EIDE1_RESET_N}, /* FEATURE_IDE1_reset */ - {0x38,0,0}, /* FEATURE_Mediabay_floppy_enable */ - {0x38,0,0}, /* FEATURE_BMac_reset */ - {0x38,0,0}, /* FEATURE_BMac_IO_enable */ - {0x40,1,KL2_MODEM_POWER_N}, /* FEATURE_Modem_power */ - {0x38,0,0}, /* FEATURE_Slow_SCC_PCLK */ - {0x38,0,0}, /* FEATURE_Sound_Power */ - {0x38,0,0}, /* FEATURE_Sound_CLK_Enable */ - {0x3c,0,KL1_UIDE_ENABLE}, /* FEATURE_IDE2_enable */ - {0x3c,1,KL1_UIDE_RESET_N}, /* FEATURE_IDE2_reset */ - {0x34,0,KL_MBCR_MB0_DEV_ENABLE},/* FEATURE_Mediabay_IDE_switch */ - {0x34,0,KL_MBCR_MB0_ENABLE}, /* FEATURE_Mediabay_content */ - {0x40,1,KL2_AIRPORT_RESET_N}, /* FEATURE_Airport_reset */ -}; - -/* definition of a feature controller object */ -struct feature_controller { - fbit* bits; - volatile u32* reg; - struct device_node* device; - spinlock_t lock; -}; - -/* static functions */ -static struct feature_controller* -feature_add_controller(struct device_node *controller_device, fbit* bits); - -static struct feature_controller* -feature_lookup_controller(struct device_node *device); - -static void uninorth_init(void); -static void keylargo_init(void); -#ifdef CONFIG_PMAC_PBOOK -static void heathrow_prepare_for_sleep(struct feature_controller* ctrler); -static void heathrow_wakeup(struct feature_controller* ctrler); -static void core99_prepare_for_sleep(struct feature_controller* ctrler); -static void core99_wake_up(struct feature_controller* ctrler); -#endif /* CONFIG_PMAC_PBOOK */ - -/* static variables */ -static struct feature_controller controllers[MAX_FEATURE_CONTROLLERS]; -static int controller_count = 0; - -/* Core99 stuffs */ -/*static*/ volatile u32* uninorth_base; -static volatile u32* keylargo_base; -static struct feature_controller* keylargo; -static int uninorth_rev; -static int keylargo_rev; -static u32 board_features; -static int airport_pwr_state; -static struct device_node* airport_dev; -static struct device_node* uninorth_fw; - -/* Feature bits for Apple motherboards */ -#define FTR_NEED_OPENPIC_TWEAK 0x00000001 -#define FTR_CAN_NAP 0x00000002 -#define FTR_HAS_FW_POWER 0x00000004 -#define FTR_CAN_SLEEP 0x00000008 - -/* This table currently lacks most oldworld machines, but - * they currently don't need it so... - * - * Todo: The whole feature_xxx mecanism need to be redone - * some way to be able to handle the new kind of features - * exposed by core99. At this point, the main "tables" will - * probably be in this table, which will have to be filled with - * all known machines - */ -/* Warning: Don't change ordering of entries as some machines - * adverstise beeing compatible with several models. In those - * case, the "highest" has to be first - */ -static struct board_features_t { - char* compatible; - u32 features; -} board_features_datas[] __initdata = -{ - { "AAPL,PowerMac G3", 0 }, /* Beige G3 */ - { "iMac,1", 0 }, /* First iMac (gossamer) */ - { "PowerMac1,1", 0 }, /* B&W G3 / Yikes */ - { "PowerMac1,2", 0 }, /* B&W G3 / Yikes */ - { "PowerMac2,1", FTR_CAN_SLEEP }, /* r128 based iMac */ - { "PowerMac2,2", FTR_HAS_FW_POWER|FTR_CAN_SLEEP }, /* Summer 2000 iMac */ - { "PowerMac4,1", FTR_CAN_SLEEP }, /* iMac "Flower Power" */ - { "PowerMac3,1", FTR_NEED_OPENPIC_TWEAK }, /* Sawtooth (G4) */ - { "PowerMac3,2", 0 }, /* G4/Dual G4 */ - { "PowerMac3,3", FTR_NEED_OPENPIC_TWEAK }, /* G4/Dual G4 */ - { "PowerMac3,4", 0 }, /* QuickSilver G4 */ - { "PowerMac3,5", 0 }, /* QuickSilver G4 */ - { "PowerMac5,1", FTR_CAN_NAP }, /* Cube */ - { "AAPL,3400/2400", FTR_CAN_SLEEP }, /* 2400/3400 PowerBook */ - { "AAPL,3500", FTR_CAN_SLEEP }, /* 3500 PowerBook (G3) */ - { "AAPL,PowerBook1998", FTR_CAN_SLEEP }, /* Wallstreet PowerBook */ - { "PowerBook1,1", FTR_CAN_SLEEP }, /* 101 (Lombard) PowerBook */ - { "PowerBook4,1", FTR_CAN_NAP|FTR_CAN_SLEEP| /* New polycarbonate iBook */ - 0/*FTR_HAS_FW_POWER*/ }, - { "PowerBook2,1", FTR_CAN_SLEEP }, /* iBook */ - { "PowerBook2,2", FTR_CAN_SLEEP /*| FTR_CAN_NAP*/ }, /* iBook FireWire */ - { "PowerBook3,1", FTR_CAN_SLEEP|FTR_CAN_NAP| /* PowerBook 2000 (Pismo) */ - FTR_HAS_FW_POWER }, - { "PowerBook3,2", FTR_CAN_NAP|FTR_CAN_SLEEP| /* PowerBook Titanium */ - 0/*FTR_HAS_FW_POWER*/ }, - { NULL, 0 } -}; - -extern unsigned long powersave_nap; - -void __init -feature_init(void) -{ - struct device_node *np; - u32 *rev; - int i; - char* model; - - if (_machine != _MACH_Pmac) - return; - - np = find_path_device("/"); - if (!np) { - printk(KERN_ERR "feature.c: Can't find device-tree root !\n"); - return; - } - model = (char*)get_property(np, "model", NULL); - if (model) { - printk("PowerMac model: %s\n", model); - /* Figure out motherboard type & options */ - for(i=0;board_features_datas[i].compatible;i++) { - if (!strcmp(board_features_datas[i].compatible, model)) { - board_features = board_features_datas[i].features; - break; - } - } - } - - /* Set default value of powersave_nap on machines that support it */ - if (board_features & FTR_CAN_NAP) - powersave_nap = 1; - - /* Track those poor mac-io's */ - np = find_devices("mac-io"); - while (np != NULL) { - /* KeyLargo contains several (5 ?) FCR registers in mac-io, - * plus some gpio's which could eventually be handled here. - */ - if (device_is_compatible(np, "Keylargo")) { - struct feature_controller* ctrler = - feature_add_controller(np, feature_bits_keylargo); - if (ctrler) { - keylargo = ctrler; - keylargo_base = ctrler->reg; - rev = (u32 *)get_property(ctrler->device, "revision-id", NULL); - if (rev) - keylargo_rev = *rev; - - rev = (u32 *)get_property(ctrler->device, "device-id", NULL); - if (rev && (*rev) == 0x0025) - keylargo_rev |= KL_PANGEA_REV; - } - } else if (device_is_compatible(np, "paddington")) { - feature_add_controller(np, feature_bits_paddington); - /* We disable the modem power bit on Yikes as it can - * do bad things (it's the nvram power) - */ - if (machine_is_compatible("PowerMac1,1") || - machine_is_compatible("PowerMac1,2")) { - feature_bits_paddington[FEATURE_Modem_power].mask = 0; - } - } else if (machine_is_compatible("AAPL,PowerBook1998")) { - feature_add_controller(np, feature_bits_wallstreet); - } else { - struct feature_controller* ctrler = - feature_add_controller(np, feature_bits_heathrow); - if (ctrler) - out_le32(FREG(ctrler,HEATHROW_FEATURE_REG), - in_le32(FREG(ctrler,HEATHROW_FEATURE_REG)) | HRW_DEFAULTS); - - } - np = np->next; - } - if (controller_count == 0) - { - np = find_devices("ohare"); - if (np) { - if (find_devices("via-pmu") != NULL) - feature_add_controller(np, feature_bits_ohare_pbook); - else - /* else not sure; maybe this is a Starmax? */ - feature_add_controller(np, NULL); - } - } - - /* Locate core99 Uni-N */ - np = find_devices("uni-n"); - if (np && np->n_addrs > 0) { - uninorth_base = ioremap(np->addrs[0].address, 0x1000); - uninorth_rev = in_be32(UN_REG(UNI_N_VERSION)); - printk("Uninorth at 0x%08x\n", np->addrs[0].address); - } - if (uninorth_base && keylargo_base) - printk("Uni-N revision: %d, KeyLargo revision: %d %s\n", - uninorth_rev, keylargo_rev, - (keylargo_rev & KL_PANGEA_REV) ? "(Pangea chipset)" : ""); - - if (uninorth_base) - uninorth_init(); - if (keylargo_base) - keylargo_init(); - - if (controller_count) - printk(KERN_INFO "Registered %d feature controller(s)\n", controller_count); - -#if defined(CONFIG_PMAC_PBOOK) && !defined(CONFIG_DMASOUND_AWACS) - /* On PowerBooks, we disable the sound chip when dmasound is a module - * or not used at all - */ - if (controller_count && find_devices("via-pmu") != NULL) { - feature_clear(controllers[0].device, FEATURE_Sound_power); - feature_clear(controllers[0].device, FEATURE_Sound_CLK_enable); - } -#endif - -#ifdef CONFIG_PMAC_PBOOK - /* On PowerBooks, we disable the serial ports by default, they - * will be re-enabled by the driver - */ -#ifndef CONFIG_XMON - if (controller_count && find_devices("via-pmu") != NULL) { - feature_set_modem_power(NULL, 0); - feature_clear(controllers[0].device, FEATURE_Serial_IO_A); - feature_clear(controllers[0].device, FEATURE_Serial_IO_B); - feature_clear(controllers[0].device, FEATURE_Serial_enable); - if (controller_count > 1) { - feature_clear(controllers[1].device, FEATURE_Serial_IO_A); - feature_clear(controllers[1].device, FEATURE_Serial_IO_B); - feature_clear(controllers[1].device, FEATURE_Serial_enable); - } - } -#endif -#endif -} - -static struct feature_controller __init * -feature_add_controller(struct device_node *controller_device, fbit* bits) -{ - struct feature_controller* controller; - - if (controller_count >= MAX_FEATURE_CONTROLLERS) { - printk(KERN_INFO "Feature controller %s skipped(MAX:%d)\n", - controller_device->full_name, MAX_FEATURE_CONTROLLERS); - return NULL; - } - controller = &controllers[controller_count]; - - controller->bits = bits; - controller->device = controller_device; - if (controller_device->n_addrs == 0) { - printk(KERN_ERR "No addresses for %s\n", - controller_device->full_name); - return NULL; - } - - /* We remap the entire mac-io here. Normally, this will just - * give us back our already existing BAT mapping - */ - controller->reg = (volatile u32 *)ioremap( - controller_device->addrs[0].address, - controller_device->addrs[0].size); - - if (bits == NULL) { - printk(KERN_INFO "Twiddling the magic ohare bits\n"); - out_le32(FREG(controller,OHARE_FEATURE_REG), STARMAX_FEATURES); - return NULL; - } - - spin_lock_init(&controller->lock); - - controller_count++; - - return controller; -} - -static struct feature_controller __pmac * -feature_lookup_controller(struct device_node *device) -{ - int i; - - if (device == NULL) - return NULL; - - while(device) - { - for (i=0; i<controller_count; i++) - if (device == controllers[i].device) - return &controllers[i]; - device = device->parent; - } - -#ifdef DEBUG_FEATURE - printk("feature: <%s> not found on any controller\n", - device->name); -#endif - - return NULL; -} - -int __pmac -feature_set(struct device_node* device, enum system_feature f) -{ - struct feature_controller* controller; - unsigned long flags; - unsigned long value; - fbit* bit; - - if (f >= FEATURE_last) - return -EINVAL; - - controller = feature_lookup_controller(device); - if (!controller) - return -ENODEV; - bit = &controller->bits[f]; - if (!bit->mask) - return -EINVAL; - -#ifdef DEBUG_FEATURE - printk("feature: <%s> setting feature %d in controller @0x%x\n", - device->name, (int)f, (unsigned int)controller->reg); -#endif - - spin_lock_irqsave(&controller->lock, flags); - value = in_le32(FREG(controller, bit->reg)); - value = bit->polarity ? (value & ~bit->mask) : (value | bit->mask); - out_le32(FREG(controller, bit->reg), value); - (void)in_le32(FREG(controller, bit->reg)); - spin_unlock_irqrestore(&controller->lock, flags); - - return 0; -} - -int __pmac -feature_clear(struct device_node* device, enum system_feature f) -{ - struct feature_controller* controller; - unsigned long flags; - unsigned long value; - fbit* bit; - - if (f >= FEATURE_last) - return -EINVAL; - - controller = feature_lookup_controller(device); - if (!controller) - return -ENODEV; - bit = &controller->bits[f]; - if (!bit->mask) - return -EINVAL; - -#ifdef DEBUG_FEATURE - printk("feature: <%s> clearing feature %d in controller @0x%x\n", - device->name, (int)f, (unsigned int)controller->reg); -#endif - - spin_lock_irqsave(&controller->lock, flags); - value = in_le32(FREG(controller, bit->reg)); - value = bit->polarity ? (value | bit->mask) : (value & ~bit->mask); - out_le32(FREG(controller, bit->reg), value); - (void)in_le32(FREG(controller, bit->reg)); - spin_unlock_irqrestore(&controller->lock, flags); - - return 0; -} - -int __pmac -feature_test(struct device_node* device, enum system_feature f) -{ - struct feature_controller* controller; - unsigned long value; - fbit* bit; - - if (f >= FEATURE_last) - return -EINVAL; - - controller = feature_lookup_controller(device); - if (!controller) - return -ENODEV; - bit = &controller->bits[f]; - if (!bit->mask) - return -EINVAL; - -#ifdef DEBUG_FEATURE - printk("feature: <%s> clearing feature %d in controller @0x%x\n", - device->name, (int)f, (unsigned int)controller->reg); -#endif - /* If one feature contains several bits, all of them must be set - * for value to be true, or all of them must be 0 if polarity is - * inverse - */ - value = (in_le32(FREG(controller, bit->reg)) & bit->mask); - return bit->polarity ? (value == 0) : (value == bit->mask); -} - -int __pmac -feature_can_sleep(void) -{ - return ((board_features & FTR_CAN_SLEEP) != 0); -} - -/* - * Core99 functions - * - * Note: We currently assume there is _one_ UniN chip and _one_ KeyLargo - * chip, which is the case on all Core99 machines so far - */ - -/* Only one GMAC is assumed */ -void __pmac -feature_set_gmac_power(struct device_node* device, int power) -{ - unsigned long flags; - - if (!uninorth_base || !keylargo) - return; - - /* TODO: Handle save/restore of PCI config space here - */ - - /* XXX We use the keylargo spinlock, but we never - * have uninorth without keylargo, so... - */ - KL_LOCK(); - if (power) - UN_BIS(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_GMAC); - else - UN_BIC(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_GMAC); - (void)UN_IN(UNI_N_CLOCK_CNTL); - KL_UNLOCK(); - udelay(20); -} - -void __pmac -feature_gmac_phy_reset(struct device_node* device) -{ - unsigned long flags; - - if (!keylargo_base || !keylargo) - return; - - KL_LOCK(); - KL_GPIO_OUT(KL_GPIO_ETH_PHY_RESET, KEYLARGO_GPIO_OUTPUT_ENABLE); - (void)KL_GPIO_IN(KL_GPIO_ETH_PHY_RESET); - KL_UNLOCK(); - mdelay(10); - KL_LOCK(); - KL_GPIO_OUT(KL_GPIO_ETH_PHY_RESET, - KEYLARGO_GPIO_OUTPUT_ENABLE | KEYLARGO_GPIO_OUTOUT_DATA); - (void)KL_GPIO_IN(KL_GPIO_ETH_PHY_RESET); - KL_UNLOCK(); - mdelay(10); -} - -/* Pass the node of the correct controller, please */ -void __pmac -feature_set_usb_power(struct device_node* device, int power) -{ - char* prop; - int number; - u32 reg; - - unsigned long flags; - - if (!keylargo_base || !keylargo) - return; - - prop = (char *)get_property(device, "AAPL,clock-id", NULL); - if (!prop) - return; - if (strncmp(prop, "usb0u048", strlen("usb0u048")) == 0) - number = 0; - else if (strncmp(prop, "usb1u148", strlen("usb1u148")) == 0) - number = 2; - else - return; - - KL_LOCK(); - if (power) { - /* Turn ON */ - - if (number == 0) { - KL_BIC(KEYLARGO_FCR0, (KL0_USB0_PAD_SUSPEND0 | KL0_USB0_PAD_SUSPEND1)); - (void)KL_IN(KEYLARGO_FCR0); - KL_UNLOCK(); - mdelay(1); - KL_LOCK(); - KL_BIS(KEYLARGO_FCR0, KL0_USB0_CELL_ENABLE); - } else { - KL_BIC(KEYLARGO_FCR0, (KL0_USB1_PAD_SUSPEND0 | KL0_USB1_PAD_SUSPEND1)); - KL_UNLOCK(); - (void)KL_IN(KEYLARGO_FCR0); - mdelay(1); - KL_LOCK(); - KL_BIS(KEYLARGO_FCR0, KL0_USB1_CELL_ENABLE); - } - reg = KL_IN(KEYLARGO_FCR4); - reg &= ~(KL4_SET_PORT_ENABLE(number) | KL4_SET_PORT_RESUME(number) | - KL4_SET_PORT_CONNECT(number) | KL4_SET_PORT_DISCONNECT(number)); - reg &= ~(KL4_SET_PORT_ENABLE(number+1) | KL4_SET_PORT_RESUME(number+1) | - KL4_SET_PORT_CONNECT(number+1) | KL4_SET_PORT_DISCONNECT(number+1)); - KL_OUT(KEYLARGO_FCR4, reg); - (void)KL_IN(KEYLARGO_FCR4); - udelay(10); - } else { - /* Turn OFF */ - - reg = KL_IN(KEYLARGO_FCR4); - reg |= KL4_SET_PORT_ENABLE(number) | KL4_SET_PORT_RESUME(number) | - KL4_SET_PORT_CONNECT(number) | KL4_SET_PORT_DISCONNECT(number); - reg |= KL4_SET_PORT_ENABLE(number+1) | KL4_SET_PORT_RESUME(number+1) | - KL4_SET_PORT_CONNECT(number+1) | KL4_SET_PORT_DISCONNECT(number+1); - KL_OUT(KEYLARGO_FCR4, reg); - (void)KL_IN(KEYLARGO_FCR4); - udelay(1); - if (number == 0) { - KL_BIC(KEYLARGO_FCR0, KL0_USB0_CELL_ENABLE); - (void)KL_IN(KEYLARGO_FCR0); - udelay(1); - KL_BIS(KEYLARGO_FCR0, (KL0_USB0_PAD_SUSPEND0 | KL0_USB0_PAD_SUSPEND1)); - (void)KL_IN(KEYLARGO_FCR0); - } else { - KL_BIC(KEYLARGO_FCR0, KL0_USB1_CELL_ENABLE); - (void)KL_IN(KEYLARGO_FCR0); - udelay(1); - KL_BIS(KEYLARGO_FCR0, (KL0_USB1_PAD_SUSPEND0 | KL0_USB1_PAD_SUSPEND1)); - (void)KL_IN(KEYLARGO_FCR0); - } - udelay(1); - } - KL_UNLOCK(); -} - -void __pmac -feature_set_firewire_power(struct device_node* device, int power) -{ - unsigned long flags; - - /* TODO: should probably handle save/restore of PCI config space here - */ - - if (!uninorth_fw || (device && uninorth_fw != device)) - return; - if (!uninorth_base) - return; - - /* XXX We use the keylargo spinlock, but we never - * have uninorth without keylargo, so... - */ - KL_LOCK(); - if (power) - UN_BIS(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_FW); - else - UN_BIC(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_FW); - (void)UN_IN(UNI_N_CLOCK_CNTL); - KL_UNLOCK(); - udelay(20); -} - -/* Warning: will kill the PHY.. */ -void __pmac -feature_set_firewire_cable_power(struct device_node* device, int power) -{ - unsigned long flags; - u8 gpioValue = power ? 0 : 4; - - if (!uninorth_fw || (device && uninorth_fw != device)) - return; - if (!keylargo_base || !(board_features & FTR_HAS_FW_POWER)) - return; - KL_LOCK(); - KL_GPIO_OUT(KL_GPIO_FW_CABLE_POWER, gpioValue); - (void)KL_GPIO_IN(KL_GPIO_FW_CABLE_POWER); - KL_UNLOCK(); -} - -void -feature_set_modem_power(struct device_node* device, int power) -{ - unsigned long flags; - - if (!device) { - device = find_devices("ch-a"); - while(device && !device_is_compatible(device, "cobalt")) - device = device->next; - if (!device) - return; - } - if (keylargo && (keylargo_rev & KL_PANGEA_REV)) { - KL_LOCK(); - if (power) { - /* Assert modem reset */ - KL_GPIO_OUT(KL_GPIO_MODEM_RESET, KEYLARGO_GPIO_OUTPUT_ENABLE); - (void)KL_GPIO_IN(KL_GPIO_MODEM_RESET); - udelay(10); - /* Power up modem */ - KL_GPIO_OUT(KL_GPIO_MODEM_POWER, KEYLARGO_GPIO_OUTPUT_ENABLE); - (void)KL_GPIO_IN(KL_GPIO_MODEM_POWER); - udelay(10); - /* Release modem reset */ - KL_GPIO_OUT(KL_GPIO_MODEM_RESET, - KEYLARGO_GPIO_OUTPUT_ENABLE | KEYLARGO_GPIO_OUTOUT_DATA); - (void)KL_GPIO_IN(KL_GPIO_MODEM_RESET); - } else { - /* Power down modem */ - KL_GPIO_OUT(KL_GPIO_MODEM_POWER, - KEYLARGO_GPIO_OUTPUT_ENABLE | KEYLARGO_GPIO_OUTOUT_DATA); - (void)KL_GPIO_IN(KL_GPIO_MODEM_POWER); - } - KL_UNLOCK(); - } else { - if (power) { - mdelay(300); - feature_set(device, FEATURE_Modem_power); - mdelay(5); - feature_clear(device, FEATURE_Modem_power); - mdelay(10); - feature_set(device, FEATURE_Modem_power); - } else { - feature_clear(device, FEATURE_Modem_power); - mdelay(10); - } - } -} - -#ifdef CONFIG_SMP -void __pmac -feature_core99_kick_cpu(int cpu_nr) -{ - const int reset_lines[] = { KL_GPIO_RESET_CPU0, - KL_GPIO_RESET_CPU1, - KL_GPIO_RESET_CPU2, - KL_GPIO_RESET_CPU3 }; - int reset_io; - unsigned long flags; - - if (!keylargo_base || cpu_nr > 3) - return; - reset_io = reset_lines[cpu_nr]; - - KL_LOCK(); - KL_GPIO_OUT(reset_io, KEYLARGO_GPIO_OUTPUT_ENABLE); - (void)KL_GPIO_IN(reset_io); - udelay(1); - KL_GPIO_OUT(reset_io, KEYLARGO_GPIO_OUTPUT_ENABLE | KEYLARGO_GPIO_OUTOUT_DATA); - (void)KL_GPIO_IN(reset_io); - KL_UNLOCK(); -} -#endif /* CONFIG_SMP */ - -void __pmac -feature_set_airport_power(struct device_node* device, int power) -{ - unsigned long flags; - - if (!keylargo_base || !airport_dev || airport_dev != device) - return; - if (airport_pwr_state == power) - return; - if (power) { - /* This code is a reproduction of OF enable-cardslot - * and init-wireless methods, slightly hacked until - * I got it working. - */ - KL_LOCK(); - KL_GPIO_OUT(KEYLARGO_GPIO_0+0xf, 5); - (void)KL_GPIO_IN(KEYLARGO_GPIO_0+0xf); - KL_UNLOCK(); - mdelay(10); - KL_LOCK(); - KL_GPIO_OUT(KEYLARGO_GPIO_0+0xf, 4); - (void)KL_GPIO_IN(KEYLARGO_GPIO_0+0xf); - KL_UNLOCK(); - - mdelay(10); - - KL_LOCK(); - KL_BIC(KEYLARGO_FCR2, KL2_AIRPORT_RESET_N); - (void)KL_IN(KEYLARGO_FCR2); - udelay(10); - KL_GPIO_OUT(KEYLARGO_GPIO_EXTINT_0+0xb, 0); - (void)KL_GPIO_IN(KEYLARGO_GPIO_EXTINT_0+0xb); - udelay(10); - KL_GPIO_OUT(KEYLARGO_GPIO_EXTINT_0+0xa, 0x28); - (void)KL_GPIO_IN(KEYLARGO_GPIO_EXTINT_0+0xa); - udelay(10); - KL_GPIO_OUT(KEYLARGO_GPIO_EXTINT_0+0xd, 0x28); - (void)KL_GPIO_IN(KEYLARGO_GPIO_EXTINT_0+0xd); - udelay(10); - KL_GPIO_OUT(KEYLARGO_GPIO_0+0xd, 0x28); - (void)KL_GPIO_IN(KEYLARGO_GPIO_0+0xd); - udelay(10); - KL_GPIO_OUT(KEYLARGO_GPIO_0+0xe, 0x28); - (void)KL_GPIO_IN(KEYLARGO_GPIO_0+0xe); - KL_UNLOCK(); - udelay(10); - KL_OUT(0x1c000, 0); - - mdelay(1); - out_8((volatile u8*)KL_FCR(0x1a3e0), 0x41); - (void)in_8((volatile u8*)KL_FCR(0x1a3e0)); - udelay(10); - KL_LOCK(); - KL_BIS(KEYLARGO_FCR2, KL2_AIRPORT_RESET_N); - (void)KL_IN(KEYLARGO_FCR2); - KL_UNLOCK(); - mdelay(100); - } else { - KL_LOCK(); - KL_BIC(KEYLARGO_FCR2, KL2_AIRPORT_RESET_N); - (void)KL_IN(KEYLARGO_FCR2); - KL_GPIO_OUT(KL_GPIO_AIRPORT_0, 0); - KL_GPIO_OUT(KL_GPIO_AIRPORT_1, 0); - KL_GPIO_OUT(KL_GPIO_AIRPORT_2, 0); - KL_GPIO_OUT(KL_GPIO_AIRPORT_3, 0); - KL_GPIO_OUT(KL_GPIO_AIRPORT_4, 0); - (void)KL_GPIO_IN(KL_GPIO_AIRPORT_4); - KL_UNLOCK(); - } - airport_pwr_state = power; -} - -/* Initialize the Core99 UniNorth host bridge and memory controller - */ -static void __init -uninorth_init(void) -{ - struct device_node* gmac, *fw; - unsigned long actrl; - - /* Set the arbitrer QAck delay according to what Apple does - */ - if (uninorth_rev < 0x10) { - actrl = UN_IN(UNI_N_ARB_CTRL) & ~UNI_N_ARB_CTRL_QACK_DELAY_MASK; - actrl |= ((uninorth_rev < 3) ? UNI_N_ARB_CTRL_QACK_DELAY105 : - UNI_N_ARB_CTRL_QACK_DELAY) << UNI_N_ARB_CTRL_QACK_DELAY_SHIFT; - UN_OUT(UNI_N_ARB_CTRL, actrl); - } - - /* Enable GMAC for now for PCI probing. It will be disabled - * later on after PCI probe - */ - gmac = find_devices("ethernet"); - while(gmac) { - if (device_is_compatible(gmac, "gmac")) - break; - gmac = gmac->next; - } - if (gmac) - feature_set_gmac_power(gmac, 1); - - /* Enable FW before PCI probe. Will be disabled later on - */ - fw = find_devices("firewire"); - if (fw && (device_is_compatible(fw, "pci106b,18") || - device_is_compatible(fw, "pci106b,30"))) { - uninorth_fw = fw; - feature_set_firewire_power(fw, 1); - } -} - -/* Initialize the Core99 KeyLargo ASIC. - */ -static void __init -keylargo_init(void) -{ - struct device_node* np; - - KL_BIS(KEYLARGO_FCR2, KL2_MPIC_ENABLE); - - /* Lookup for an airport card, and disable it if found - * to save power (will be re-enabled by driver if used) - */ - np = find_devices("radio"); - if (np && np->parent == keylargo->device) - airport_dev = np; - - if (airport_dev) { - airport_pwr_state = 1; - feature_set_airport_power(airport_dev, 0); - } - -} - -#ifdef CONFIG_PMAC_PBOOK -void __pmac -feature_prepare_for_sleep(void) -{ - /* We assume gatwick is second */ - struct feature_controller* ctrler = &controllers[0]; - - if (controller_count > 1 && - device_is_compatible(ctrler->device, "gatwick")) - ctrler = &controllers[1]; - - if (ctrler->bits == feature_bits_wallstreet || - ctrler->bits == feature_bits_paddington) { - heathrow_prepare_for_sleep(ctrler); - return; - } - if (ctrler->bits == feature_bits_keylargo) { - core99_prepare_for_sleep(ctrler); - return; - } -} - -void __pmac -feature_wake_up(void) -{ - struct feature_controller* ctrler = &controllers[0]; - - if (controller_count > 1 && - device_is_compatible(ctrler->device, "gatwick")) - ctrler = &controllers[1]; - - if (ctrler->bits == feature_bits_wallstreet || - ctrler->bits == feature_bits_paddington) { - heathrow_wakeup(ctrler); - return; - } - if (ctrler->bits == feature_bits_keylargo) { - core99_wake_up(ctrler); - return; - } -} - -static u32 save_fcr[5]; -static u32 save_mbcr; -static u32 save_gpio_levels[2]; -static u8 save_gpio_extint[KEYLARGO_GPIO_EXTINT_CNT]; -static u8 save_gpio_normal[KEYLARGO_GPIO_CNT]; -static u32 save_unin_clock_ctl; -static struct dbdma_regs save_dbdma[13]; - -static void __pmac -heathrow_prepare_for_sleep(struct feature_controller* ctrler) -{ - save_mbcr = in_le32(FREG(ctrler, 0x34)); - save_fcr[0] = in_le32(FREG(ctrler, 0x38)); - save_fcr[1] = in_le32(FREG(ctrler, 0x3c)); - - out_le32(FREG(ctrler, 0x38), save_fcr[0] & ~HRW_IOBUS_ENABLE); -} - -static void __pmac -heathrow_wakeup(struct feature_controller* ctrler) -{ - out_le32(FREG(ctrler, 0x38), save_fcr[0]); - out_le32(FREG(ctrler, 0x3c), save_fcr[1]); - out_le32(FREG(ctrler, 0x34), save_mbcr); - mdelay(1); - out_le32(FREG(ctrler, 0x38), save_fcr[0] | HRW_IOBUS_ENABLE); - mdelay(1); -} - -static void __pmac -turn_off_keylargo(void) -{ - u32 temp; - - mdelay(1); - KL_BIS(KEYLARGO_FCR0, KL0_USB_REF_SUSPEND); - (void)KL_IN(KEYLARGO_FCR0); - mdelay(100); - - KL_BIC(KEYLARGO_FCR0, KL0_SCCA_ENABLE | KL0_SCCB_ENABLE | - KL0_SCC_CELL_ENABLE | - KL0_IRDA_ENABLE | KL0_IRDA_CLK32_ENABLE | - KL0_IRDA_CLK19_ENABLE); - - (void)KL_IN(KEYLARGO_FCR0); udelay(10); - KL_BIS(KEYLARGO_MBCR, KL_MBCR_MB0_DEV_ENABLE); - (void)KL_IN(KEYLARGO_MBCR); udelay(10); - - KL_BIC(KEYLARGO_FCR1, - KL1_AUDIO_SEL_22MCLK | KL1_AUDIO_CLK_ENABLE_BIT | - KL1_AUDIO_CLK_OUT_ENABLE | KL1_AUDIO_CELL_ENABLE | - KL1_I2S0_CELL_ENABLE | KL1_I2S0_CLK_ENABLE_BIT | - KL1_I2S0_ENABLE | KL1_I2S1_CELL_ENABLE | - KL1_I2S1_CLK_ENABLE_BIT | KL1_I2S1_ENABLE | - KL1_EIDE0_ENABLE | KL1_EIDE0_RESET_N | - KL1_EIDE1_ENABLE | KL1_EIDE1_RESET_N | - KL1_UIDE_ENABLE); - (void)KL_IN(KEYLARGO_FCR1); udelay(10); - - KL_BIS(KEYLARGO_FCR2, KL2_MODEM_POWER_N); - udelay(10); - KL_BIC(KEYLARGO_FCR2, KL2_IOBUS_ENABLE); - udelay(10); - temp = KL_IN(KEYLARGO_FCR3); - if (keylargo_rev >= 2) - temp |= (KL3_SHUTDOWN_PLL2X | KL3_SHUTDOWN_PLL_TOTAL); - - temp |= KL3_SHUTDOWN_PLLKW6 | KL3_SHUTDOWN_PLLKW4 | - KL3_SHUTDOWN_PLLKW35 | KL3_SHUTDOWN_PLLKW12; - temp &= ~(KL3_CLK66_ENABLE | KL3_CLK49_ENABLE | KL3_CLK45_ENABLE - | KL3_CLK31_ENABLE | KL3_TIMER_CLK18_ENABLE | KL3_I2S1_CLK18_ENABLE - | KL3_I2S0_CLK18_ENABLE | KL3_VIA_CLK16_ENABLE); - KL_OUT(KEYLARGO_FCR3, temp); - (void)KL_IN(KEYLARGO_FCR3); udelay(10); -} - -static void __pmac -turn_off_pangea(void) -{ - u32 temp; - - KL_BIC(KEYLARGO_FCR0, KL0_SCCA_ENABLE | KL0_SCCB_ENABLE | - KL0_SCC_CELL_ENABLE | - KL0_USB0_CELL_ENABLE | KL0_USB1_CELL_ENABLE); - - (void)KL_IN(KEYLARGO_FCR0); udelay(10); - KL_BIS(KEYLARGO_MBCR, KL_MBCR_MB0_DEV_ENABLE); - (void)KL_IN(KEYLARGO_MBCR); udelay(10); - - KL_BIC(KEYLARGO_FCR1, - KL1_AUDIO_SEL_22MCLK | KL1_AUDIO_CLK_ENABLE_BIT | - KL1_AUDIO_CLK_OUT_ENABLE | KL1_AUDIO_CELL_ENABLE | - KL1_I2S0_CELL_ENABLE | KL1_I2S0_CLK_ENABLE_BIT | - KL1_I2S0_ENABLE | KL1_I2S1_CELL_ENABLE | - KL1_I2S1_CLK_ENABLE_BIT | KL1_I2S1_ENABLE | - KL1_UIDE_ENABLE); - (void)KL_IN(KEYLARGO_FCR1); udelay(10); - - KL_BIS(KEYLARGO_FCR2, KL2_MODEM_POWER_N); - udelay(10); - temp = KL_IN(KEYLARGO_FCR3); - temp |= KL3_SHUTDOWN_PLLKW6 | KL3_SHUTDOWN_PLLKW4 | - KL3_SHUTDOWN_PLLKW35; - temp &= ~(KL3_CLK49_ENABLE | KL3_CLK45_ENABLE - | KL3_CLK31_ENABLE | KL3_TIMER_CLK18_ENABLE | KL3_I2S1_CLK18_ENABLE - | KL3_I2S0_CLK18_ENABLE | KL3_VIA_CLK16_ENABLE); - KL_OUT(KEYLARGO_FCR3, temp); - (void)KL_IN(KEYLARGO_FCR3); udelay(10); -} - -static void __pmac -core99_prepare_for_sleep(struct feature_controller* ctrler) -{ - int i; - volatile u8* base8; - - /* - * Save various bits of KeyLargo - */ - - /* We power off the wireless slot in case it was not done - * by the driver. We don't power it on automatically however - */ - feature_set_airport_power(airport_dev, 0); - - /* We power off the FW cable. Should be done by the driver... */ - feature_set_firewire_power(NULL, 0); - feature_set_firewire_cable_power(NULL, 0); - - /* We make sure int. modem is off (in case driver lost it) */ - feature_set_modem_power(NULL, 0); - - /* Save the state of the various GPIOs */ - save_gpio_levels[0] = KL_IN(KEYLARGO_GPIO_LEVELS0); - save_gpio_levels[1] = KL_IN(KEYLARGO_GPIO_LEVELS1); - base8 = ((volatile u8 *)keylargo_base) + KEYLARGO_GPIO_EXTINT_0; - for (i=0; i<KEYLARGO_GPIO_EXTINT_CNT; i++) - save_gpio_extint[i] = in_8(base8+i); - base8 = ((volatile u8 *)keylargo_base) + KEYLARGO_GPIO_0; - for (i=0; i<KEYLARGO_GPIO_CNT; i++) - save_gpio_normal[i] = in_8(base8+i); - - /* Save the FCRs */ - save_mbcr = KL_IN(KEYLARGO_MBCR); - save_fcr[0] = KL_IN(KEYLARGO_FCR0); - save_fcr[1] = KL_IN(KEYLARGO_FCR1); - save_fcr[2] = KL_IN(KEYLARGO_FCR2); - save_fcr[3] = KL_IN(KEYLARGO_FCR3); - save_fcr[4] = KL_IN(KEYLARGO_FCR4); - - /* Save state & config of DBDMA channels */ - for (i=0; i<13; i++) { - volatile struct dbdma_regs* chan = (volatile struct dbdma_regs*) - (keylargo_base + ((0x8000+i*0x100)>>2)); - save_dbdma[i].cmdptr_hi = in_le32(&chan->cmdptr_hi); - save_dbdma[i].cmdptr = in_le32(&chan->cmdptr); - save_dbdma[i].intr_sel = in_le32(&chan->intr_sel); - save_dbdma[i].br_sel = in_le32(&chan->br_sel); - save_dbdma[i].wait_sel = in_le32(&chan->wait_sel); - } - - /* - * Turn off as much as we can - */ - if (keylargo_rev & KL_PANGEA_REV) - turn_off_pangea(); - else - turn_off_keylargo(); - - /* - * Put the host bridge to sleep - */ - - save_unin_clock_ctl = UN_IN(UNI_N_CLOCK_CNTL); - UN_OUT(UNI_N_CLOCK_CNTL, save_unin_clock_ctl & - ~(UNI_N_CLOCK_CNTL_GMAC|UNI_N_CLOCK_CNTL_FW/*|UNI_N_CLOCK_CNTL_PCI*/)); - udelay(100); - UN_OUT(UNI_N_HWINIT_STATE, UNI_N_HWINIT_STATE_SLEEPING); - UN_OUT(UNI_N_POWER_MGT, UNI_N_POWER_MGT_SLEEP); - - /* - * FIXME: A bit of black magic with OpenPIC (don't ask me why) - */ - if (board_features & FTR_NEED_OPENPIC_TWEAK) { - KL_BIS(0x506e0, 0x00400000); - KL_BIS(0x506e0, 0x80000000); - } -} - -static void __pmac -core99_wake_up(struct feature_controller* ctrler) -{ - int i; - volatile u8* base8; - - /* - * Wakeup the host bridge - */ - UN_OUT(UNI_N_POWER_MGT, UNI_N_POWER_MGT_NORMAL); - udelay(10); - UN_OUT(UNI_N_HWINIT_STATE, UNI_N_HWINIT_STATE_RUNNING); - udelay(10); - - /* - * Restore KeyLargo - */ - - KL_OUT(KEYLARGO_MBCR, save_mbcr); - (void)KL_IN(KEYLARGO_MBCR); udelay(10); - KL_OUT(KEYLARGO_FCR0, save_fcr[0]); - (void)KL_IN(KEYLARGO_FCR0); udelay(10); - KL_OUT(KEYLARGO_FCR1, save_fcr[1]); - (void)KL_IN(KEYLARGO_FCR1); udelay(10); - KL_OUT(KEYLARGO_FCR2, save_fcr[2]); - (void)KL_IN(KEYLARGO_FCR2); udelay(10); - KL_OUT(KEYLARGO_FCR3, save_fcr[3]); - (void)KL_IN(KEYLARGO_FCR3); udelay(10); - KL_OUT(KEYLARGO_FCR4, save_fcr[4]); - (void)KL_IN(KEYLARGO_FCR4); udelay(10); - - for (i=0; i<13; i++) { - volatile struct dbdma_regs* chan = (volatile struct dbdma_regs*) - (keylargo_base + ((0x8000+i*0x100)>>2)); - out_le32(&chan->control, (ACTIVE|DEAD|WAKE|FLUSH|PAUSE|RUN)<<16); - while (in_le32(&chan->status) & ACTIVE) - mb(); - out_le32(&chan->cmdptr_hi, save_dbdma[i].cmdptr_hi); - out_le32(&chan->cmdptr, save_dbdma[i].cmdptr); - out_le32(&chan->intr_sel, save_dbdma[i].intr_sel); - out_le32(&chan->br_sel, save_dbdma[i].br_sel); - out_le32(&chan->wait_sel, save_dbdma[i].wait_sel); - } - - KL_OUT(KEYLARGO_GPIO_LEVELS0, save_gpio_levels[0]); - KL_OUT(KEYLARGO_GPIO_LEVELS1, save_gpio_levels[1]); - base8 = ((volatile u8 *)keylargo_base) + KEYLARGO_GPIO_EXTINT_0; - for (i=0; i<KEYLARGO_GPIO_EXTINT_CNT; i++) - out_8(base8+i, save_gpio_extint[i]); - base8 = ((volatile u8 *)keylargo_base) + KEYLARGO_GPIO_0; - for (i=0; i<KEYLARGO_GPIO_CNT; i++) - out_8(base8+i, save_gpio_normal[i]); - - /* FIXME more black magic with OpenPIC ... */ - if (board_features & FTR_NEED_OPENPIC_TWEAK) { - KL_BIC(0x506e0, 0x00400000); - KL_BIC(0x506e0, 0x80000000); - } - - UN_OUT(UNI_N_CLOCK_CNTL, save_unin_clock_ctl); - udelay(100); -} -#endif /* CONFIG_PMAC_PBOOK */ diff --git a/arch/ppc/kernel/galaxy_pci.c b/arch/ppc/kernel/galaxy_pci.c index afe8ffbe1379..4326a2a76b92 100644 --- a/arch/ppc/kernel/galaxy_pci.c +++ b/arch/ppc/kernel/galaxy_pci.c @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.galaxy_pci.c 1.7 05/17/01 18:14:21 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * @@ -27,8 +27,7 @@ #include <asm/system.h> #include <asm/io.h> #include <asm/machdep.h> - -#include "pci.h" +#include <asm/pci-bridge.h> /* Preprocessor Defines */ diff --git a/arch/ppc/kernel/gt64260_common.c b/arch/ppc/kernel/gt64260_common.c new file mode 100644 index 000000000000..4dc0719366cd --- /dev/null +++ b/arch/ppc/kernel/gt64260_common.c @@ -0,0 +1,1666 @@ +/* + * arch/ppc/kernel/gt64260_common.c + * + * Common routines for the Marvell/Galileo GT64260 (Discovery) host bridge, + * interrupt controller, memory controller, serial controller, enet controller, + * etc. + * + * Author: Mark A. Greer <mgreer@mvista.com> + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +/* + * The GT64260 port is the result of hard work from many people from + * many companies. In particular, employees of Marvell/Galileo, Mission + * Critical Linux, Xyterra, and MontaVista Software were heavily involved. + */ + +/* + * At last count, the 64260-B-0 has 65 errata and 24 restrictions. The odds of + * you getting it to work well, under stress, for a long period of time are + * low. If nothing else, you will likely run into an interrupt controller + * bug. + * + * The newer 64260A-B-0 is much improved but has its own problems. + * Dave Wilhardt <dwilhardt@zyterra.com> has discovered that you must set + * up your PCI snoop regions to be prefetchable with 4-word bursts AND set the + * "Memory Write and Invalidate bit" (bit 4) in the cmd reg of each PCI device + * before coherency works between PCI and other devices. Many thanks to Dave. + * + * So far this code has been tested on Marvell/Galileo EV-64260-BP and + * an EV-64260A-BP uni-processor boards with 750 and 7400 processors. + * It has not yet been tested with a 7410 or 7450, or on an smp system. + * + * Note: I have not had any luck moving the base register address of the bridge + * with the gt64260_set_base() routine. I move it in the bootloader + * before starting the kernel. I haven't really looked into it so it + * may be an easy fix. -- MAG + */ +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/pci.h> +#include <linux/slab.h> + +#include <asm/byteorder.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/uaccess.h> +#include <asm/machdep.h> +#include <asm/pci-bridge.h> +#include <asm/gt64260.h> +#include <asm/delay.h> + + +u32 gt64260_base; /* Virtual base address of 64260's regs */ +u32 gt64260_revision; /* Revision of the chip */ +u8 gt64260_pci_exclude_bridge = TRUE; + + +/* + ***************************************************************************** + * + * Bridge Initialization Routines + * + ***************************************************************************** + */ +static void gt64260_check_errata(struct pci_controller *hose_a, + struct pci_controller *hose_b); + +/* + * Typical '_find_bridges()' routine for boards with a GT64260 bridge. + */ +int __init +gt64260_find_bridges(u32 phys_base_addr, gt64260_bridge_info_t *info, + int ((*map_irq)(struct pci_dev *, unsigned char, unsigned char))) +{ + struct pci_controller *hose_a, *hose_b; + u32 io_base_a, io_base_b; + int rc; + + + gt64260_base = (u32)ioremap(phys_base_addr,GT64260_INTERNAL_SPACE_SIZE); + + hose_a = pcibios_alloc_controller(); + if (!hose_a) + return -1; + + hose_b = pcibios_alloc_controller(); + if (!hose_b) + return -1; + + info->hose_a = hose_a; + info->hose_b = hose_b; + + /* Ends up mapping PCI Config addr/data pairs twice */ + setup_indirect_pci(hose_a, + phys_base_addr + GT64260_PCI_0_CONFIG_ADDR, + phys_base_addr + GT64260_PCI_0_CONFIG_DATA); + + setup_indirect_pci(hose_b, + phys_base_addr + GT64260_PCI_1_CONFIG_ADDR, + phys_base_addr + GT64260_PCI_1_CONFIG_DATA); + + if ((rc = gt64260_bridge_init(info)) != 0) { + iounmap((void *)hose_a->cfg_addr); + iounmap((void *)hose_a->cfg_data); + iounmap((void *)hose_b->cfg_addr); + iounmap((void *)hose_b->cfg_data); + iounmap((void *)gt64260_base); + return rc; + } + + /* ioremap PCI I/O regions */ + io_base_b = (u32)ioremap(info->pci_1_io_start_proc,info->pci_1_io_size); + io_base_a = (u32)ioremap(info->pci_0_io_start_proc,info->pci_0_io_size); + isa_io_base = io_base_a; + + hose_a->first_busno = 0; + hose_a->last_busno = 0xff; + + pci_init_resource(&hose_a->io_resource, + 0, /* really: io_base_a - isa_io_base */ + info->pci_0_io_size - 1, + IORESOURCE_IO, + "host bridge PCI bus 0"); + hose_a->io_space.start = info->pci_0_io_start_pci; + hose_a->io_space.end = info->pci_0_io_start_pci + + info->pci_0_io_size - 1; + hose_a->io_base_virt = (void *)isa_io_base; + + pci_init_resource(&hose_a->mem_resources[0], + info->pci_0_mem_start_proc, + info->pci_0_mem_start_proc + info->pci_0_mem_size - 1, + IORESOURCE_MEM, + "host bridge PCI bus 0"); + hose_a->mem_space.start = info->pci_0_mem_start_pci_lo; + hose_a->mem_space.end = info->pci_0_mem_start_pci_lo + + info->pci_0_mem_size - 1; + hose_a->pci_mem_offset = (info->pci_0_mem_start_proc - + info->pci_0_mem_start_pci_lo); + + hose_a->last_busno = pciauto_bus_scan(hose_a, hose_a->first_busno); + + + hose_b->first_busno = hose_a->last_busno + 1; + hose_b->bus_offset = hose_b->first_busno; + hose_b->last_busno = 0xff; + + pci_init_resource(&hose_b->io_resource, + io_base_b - isa_io_base, + io_base_b - isa_io_base + info->pci_1_io_size - 1, + IORESOURCE_IO, + "host bridge PCI bus 1"); + hose_b->io_space.start = info->pci_1_io_start_pci; + hose_b->io_space.end = info->pci_1_io_start_pci + + info->pci_1_io_size - 1; + hose_b->io_base_virt = (void *)isa_io_base; + + pci_init_resource(&hose_b->mem_resources[0], + info->pci_1_mem_start_proc, + info->pci_1_mem_start_proc + info->pci_1_mem_size - 1, + IORESOURCE_MEM, + "host bridge PCI bus 1"); + hose_b->mem_space.start = info->pci_1_mem_start_pci_lo; + hose_b->mem_space.end = info->pci_1_mem_start_pci_lo + + info->pci_1_mem_size - 1; + hose_b->pci_mem_offset = (info->pci_1_mem_start_proc - + info->pci_1_mem_start_pci_lo); + + hose_b->last_busno = pciauto_bus_scan(hose_b, hose_b->first_busno); + + + ppc_md.pci_exclude_device = gt64260_pci_exclude_device; + ppc_md.pci_swizzle = common_swizzle; + ppc_md.pci_map_irq = map_irq; + + return 0; +} /* gt64260_find_bridges() */ + +/* + * gt64260_bridge_init() + * + * Perform bridge initialization for a "typical" setup for a PPC system. + */ +int __init +gt64260_bridge_init(gt64260_bridge_info_t *info) +{ + int window; + u16 u16_val; + u32 u32_val; + int rc = 0; + u8 save_exclude; + + /* + * Count on firmware to set/clear other bits in this register. + * + * Set CPU CONFIG Reg bit: + * bit 13 - Pipeline + * bit 16 - RdOOO + * + * Clear CPU Config Reg bit: + * bit 12 - endianess + * bit 27 - RemapWrDis + */ + u32_val = gt_read(GT64260_CPU_CONFIG); + u32_val |= ((1<<13) | (1<<16)); + u32_val &= ~((1<<8) | (1<<12) | (1<<27)); + gt_write(GT64260_CPU_CONFIG, u32_val); + + /* PCI 0/1 Timeout and Retry limits */ + u32_val = gt_read(GT64260_PCI_0_TO_RETRY); + u32_val |= 0x0000ffff; + gt_write(GT64260_PCI_0_TO_RETRY, u32_val); + + u32_val = gt_read(GT64260_PCI_1_TO_RETRY); + u32_val |= 0x0000ffff; + gt_write(GT64260_PCI_1_TO_RETRY, u32_val); + + save_exclude = gt64260_pci_exclude_bridge; + gt64260_pci_exclude_bridge = FALSE; + + /* Set class code to indicate host bridge */ + early_read_config_dword(info->hose_a, + info->hose_a->first_busno, + PCI_DEVFN(0,0), + PCI_CLASS_REVISION, + &u32_val); + u32_val &= 0x000000ff; + gt64260_revision = u32_val; /* a 64260 or 64260A? */ + u32_val |= (PCI_CLASS_BRIDGE_HOST << 16); + early_write_config_dword(info->hose_a, + info->hose_a->first_busno, + PCI_DEVFN(0,0), + PCI_CLASS_REVISION, + u32_val); + + early_read_config_dword(info->hose_b, + info->hose_b->first_busno, + PCI_DEVFN(0,0), + PCI_CLASS_REVISION, + &u32_val); + u32_val &= 0x000000ff; + u32_val |= (PCI_CLASS_BRIDGE_HOST << 16); + early_write_config_dword(info->hose_b, + info->hose_b->first_busno, + PCI_DEVFN(0,0), + PCI_CLASS_REVISION, + u32_val); + + /* Enable 64260 to be PCI master & respond to PCI MEM cycles */ + early_read_config_word(info->hose_a, + info->hose_a->first_busno, + PCI_DEVFN(0,0), + PCI_COMMAND, + &u16_val); + u16_val |= (PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY); + early_write_config_word(info->hose_a, + info->hose_a->first_busno, + PCI_DEVFN(0,0), + PCI_COMMAND, + u16_val); + + early_read_config_word(info->hose_b, + info->hose_b->first_busno, + PCI_DEVFN(0,0), + PCI_COMMAND, + &u16_val); + u16_val |= (PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY); + early_write_config_word(info->hose_b, + info->hose_b->first_busno, + PCI_DEVFN(0,0), + PCI_COMMAND, + u16_val); + + gt64260_pci_exclude_bridge = save_exclude; + + /* + * Disable all CPU windows on the bridge except for SCS 0 which + * is covering all of system memory.: + */ + gt64260_cpu_disable_all_windows(); + + /* + * Set CPU snoop window to indicate all of system memory + * is covered with wirte-back cache. + */ + gt64260_cpu_snoop_set_window(0, + 0x00000000, + info->mem_size, + GT64260_CPU_SNOOP_WB); + + /* + * Set up CPU->PCI mappings (so CPU can get at PCI dev regs/mem). + * Will only use one of the four CPU->PCI MEM windows on each bus. + */ + gt64260_cpu_set_pci_io_window(0, + info->pci_0_io_start_proc, + info->pci_0_io_start_pci, + info->pci_0_io_size, + info->pci_0_io_swap); + + gt64260_cpu_set_pci_mem_window(0, + 0, + info->pci_0_mem_start_proc, + info->pci_0_mem_start_pci_hi, + info->pci_0_mem_start_pci_lo, + info->pci_0_mem_size, + info->pci_0_mem_swap); + + gt64260_cpu_set_pci_io_window(1, + info->pci_1_io_start_proc, + info->pci_1_io_start_pci, + info->pci_1_io_size, + info->pci_1_io_swap); + + gt64260_cpu_set_pci_mem_window(1, + 0, + info->pci_1_mem_start_proc, + info->pci_1_mem_start_pci_hi, + info->pci_1_mem_start_pci_lo, + info->pci_1_mem_size, + info->pci_1_mem_swap); + + /* + * Set up PCI MEM->system memory mapping (bridge slave PCI window). + * + * Set BAR enables to allow only the SCS0 slave window to respond + * to PCI read/write cycles. + */ + gt64260_pci_bar_enable(0, GT64260_PCI_SLAVE_BAR_REG_ENABLES_SCS_0); + gt64260_pci_bar_enable(1, GT64260_PCI_SLAVE_BAR_REG_ENABLES_SCS_0); + + /* + * For virt_to_bus & bus_to_virt to work correctly, this mapping + * must be the same on both PCI buses. + */ + gt64260_pci_slave_scs_set_window(info->hose_a, + 0, + 0x00000000, + 0x00000000, + info->mem_size); + + gt64260_pci_slave_scs_set_window(info->hose_b, + 0, + 0x00000000, + 0x00000000, + info->mem_size); + pci_dram_offset = 0; /* System mem at same addr on PCI & cpu bus */ + + /* Disable all the access control windows */ + for (window=0; window<GT64260_PCI_ACC_CNTL_WINDOWS; window++) { + gt64260_pci_acc_cntl_set_window(0, window, 0, 0, 0, 0); + gt64260_pci_acc_cntl_set_window(1, window, 0, 0, 0, 0); + } + + /* Disable all the PCI snoop regions */ + for (window=0; window<GT64260_PCI_SNOOP_WINDOWS; window++) { + gt64260_pci_snoop_set_window(0, window, 0, 0, 0, 0); + gt64260_pci_snoop_set_window(1, window, 0, 0, 0, 0); + } + + gt64260_pci_acc_cntl_set_window(0, + 0, + 0x00000000, + 0x00000000, + info->mem_size, + (GT64260_PCI_ACC_CNTL_PREFETCHEN | + GT64260_PCI_ACC_CNTL_MBURST_4_WORDS | + GT64260_PCI_ACC_CNTL_SWAP_BYTE)); + + gt64260_pci_acc_cntl_set_window(1, + 0, + 0x00000000, + 0x00000000, + info->mem_size, + (GT64260_PCI_ACC_CNTL_PREFETCHEN | + GT64260_PCI_ACC_CNTL_MBURST_4_WORDS | + GT64260_PCI_ACC_CNTL_SWAP_BYTE)); + + gt64260_pci_snoop_set_window(0, + 0, + 0x00000000, + 0x00000000, + info->mem_size, + GT64260_PCI_SNOOP_WB); + + gt64260_pci_snoop_set_window(1, + 0, + 0x00000000, + 0x00000000, + info->mem_size, + GT64260_PCI_SNOOP_WB); + + gt64260_check_errata(info->hose_a, info->hose_b); + + + /* Set latency timer (to 64) & cacheline size; clear BIST */ + gt64260_pci_exclude_bridge = FALSE; + u32_val = ((0x04 << 8) | (L1_CACHE_LINE_SIZE / 4)); + + early_write_config_dword(info->hose_a, + info->hose_a->first_busno, + PCI_DEVFN(0,0), + PCI_CACHE_LINE_SIZE, + u32_val); + early_write_config_dword(info->hose_b, + info->hose_b->first_busno, + PCI_DEVFN(0,0), + PCI_CACHE_LINE_SIZE, + u32_val); + gt64260_pci_exclude_bridge = TRUE; + + return rc; +} /* gt64260_bridge_init() */ + +/* + * gt64260_check_errata() + * + * Apply applicable errata and restrictions from 0.5 of the + * Errata and Restrictions document from Marvell/Galileo. + */ +static void __init +gt64260_check_errata(struct pci_controller *hose_a, + struct pci_controller *hose_b) +{ + u32 val; + u8 save_exclude; + + /* Currently 2 versions, 64260 and 64260A */ + if (gt64260_revision == GT64260) { + save_exclude = gt64260_pci_exclude_bridge; + gt64260_pci_exclude_bridge = FALSE; + + /* FEr#5, FEr#12 */ + early_read_config_dword(hose_a, + hose_a->first_busno, + PCI_DEVFN(0,0), + PCI_COMMAND, + &val); + val &= ~(PCI_COMMAND_INVALIDATE | PCI_COMMAND_PARITY); + early_write_config_dword(hose_a, + hose_a->first_busno, + PCI_DEVFN(0,0), + PCI_COMMAND, + val); + + early_read_config_dword(hose_b, + hose_b->first_busno, + PCI_DEVFN(0,0), + PCI_COMMAND, + &val); + val &= ~(PCI_COMMAND_INVALIDATE | PCI_COMMAND_PARITY); + early_write_config_dword(hose_b, + hose_b->first_busno, + PCI_DEVFN(0,0), + PCI_COMMAND, + val); + gt64260_pci_exclude_bridge = save_exclude; + + /* FEr#12, FEr#13 */ + gt_clr_bits(GT64260_PCI_0_CMD, ((1<<4) | (1<<5) | (1<<9))); + gt_clr_bits(GT64260_PCI_1_CMD, ((1<<4) | (1<<5) | (1<<9))); + + /* FEr#54 */ + gt_clr_bits(GT64260_CPU_SNOOP_BASE_0, 0xfffcf000); + gt_clr_bits(GT64260_CPU_SNOOP_BASE_1, 0xfffcf000); + gt_clr_bits(GT64260_CPU_SNOOP_BASE_2, 0xfffcf000); + gt_clr_bits(GT64260_CPU_SNOOP_BASE_3, 0xfffcf000); + + /* R#18 */ + gt_set_bits(GT64260_SDRAM_CONFIG, (1<<26)); + + } else if (gt64260_revision == GT64260A) { + /* R#18 */ + gt_set_bits(GT64260_SDRAM_CONFIG, (1<<26)); + + /* No longer errata so turn on */ + gt_set_bits(GT64260_PCI_0_CMD, ((1<<4) | (1<<5) | (1<<9))); + gt_set_bits(GT64260_PCI_1_CMD, ((1<<4) | (1<<5) | (1<<9))); + } +} /* gt64260_check_errata() */ + + +/* + ***************************************************************************** + * + * General Window Setting Routines + * + ***************************************************************************** + */ + +static int +gt64260_set_32bit_window(u32 base_addr, + u32 size, + u32 other_bits, + u32 bot_reg, + u32 top_reg) +{ + u32 val; + + if (size > 0) { + /* Set up the window on the CPU side */ + gt_write(bot_reg, (base_addr >> 20) | other_bits); + gt_write(top_reg, (base_addr + size - 1) >> 20); + } else { /* Disable window */ + gt_write(top_reg, 0x00000000); + gt_write(bot_reg, 0x00000fff | other_bits); + } + + val = gt_read(bot_reg); /* Flush FIFO */ + return 0; +} /* gt64260_set_32bit_window() */ + +static int +gt64260_set_64bit_window(u32 base_addr_hi, + u32 base_addr_lo, + u32 size, + u32 other_bits, + u32 bot_reg_hi, + u32 bot_reg_lo, + u32 top_reg) +{ + int rc; + + if ((rc = gt64260_set_32bit_window(base_addr_lo, + size, + other_bits, + bot_reg_lo, + top_reg)) == 0) { + + gt_write(bot_reg_hi, base_addr_hi); + base_addr_hi = gt_read(bot_reg_hi); /* Flush FIFO */ + } + + return rc; +} /* gt64260_set_64bit_window() */ + + +/* + ***************************************************************************** + * + * CPU Configuration Routines + * + ***************************************************************************** + */ + +int +gt64260_cpu_scs_set_window(u32 window, + u32 base_addr, + u32 size) +{ + static u32 + cpu_scs_windows[GT64260_CPU_SCS_DECODE_WINDOWS][2] = { + { GT64260_CPU_SCS_DECODE_0_BOT, GT64260_CPU_SCS_DECODE_0_TOP }, + { GT64260_CPU_SCS_DECODE_1_BOT, GT64260_CPU_SCS_DECODE_1_TOP }, + { GT64260_CPU_SCS_DECODE_2_BOT, GT64260_CPU_SCS_DECODE_2_TOP }, + { GT64260_CPU_SCS_DECODE_3_BOT, GT64260_CPU_SCS_DECODE_3_TOP }, + }; /* cpu_scs_windows[][] */ + int rc = -1; + + if (window < GT64260_CPU_SCS_DECODE_WINDOWS) { + rc = gt64260_set_32bit_window(base_addr, + size, + 0, + cpu_scs_windows[window][0], + cpu_scs_windows[window][1]); + } + + return rc; +} /* gt64260_cpu_scs_set_window() */ + +int +gt64260_cpu_cs_set_window(u32 window, + u32 base_addr, + u32 size) +{ + static u32 + cpu_cs_windows[GT64260_CPU_CS_DECODE_WINDOWS][2] = { + { GT64260_CPU_CS_DECODE_0_BOT, GT64260_CPU_CS_DECODE_0_TOP }, + { GT64260_CPU_CS_DECODE_1_BOT, GT64260_CPU_CS_DECODE_1_TOP }, + { GT64260_CPU_CS_DECODE_2_BOT, GT64260_CPU_CS_DECODE_2_TOP }, + { GT64260_CPU_CS_DECODE_3_BOT, GT64260_CPU_CS_DECODE_3_TOP }, + }; /* cpu_cs_windows[][] */ + int rc = -1; + + if (window < GT64260_CPU_CS_DECODE_WINDOWS) { + rc = gt64260_set_32bit_window(base_addr, + size, + 0, + cpu_cs_windows[window][0], + cpu_cs_windows[window][1]); + } + + return rc; +} /* gt64260_cpu_cs_set_window() */ + +int +gt64260_cpu_boot_set_window(u32 base_addr, + u32 size) +{ + int rc; + + rc = gt64260_set_32bit_window(base_addr, + size, + 0, + GT64260_CPU_BOOT_CS_DECODE_0_BOT, + GT64260_CPU_BOOT_CS_DECODE_0_TOP); + + return rc; +} /* gt64260_cpu_boot_set_window() */ + +/* + * gt64260_cpu_set_pci_io_window() + * + * Set up a CPU window into PCI I/O or MEM space. + * Always do Read/Modify/Write to window regs. + */ +static int +gt64260_cpu_pci_set_window(u32 cpu_base_addr, + u32 pci_base_addr, + u32 size, + u32 other_bits, + u32 bot_reg, + u32 top_reg, + u32 remap_reg) +{ + u32 val; + int rc; + + if ((rc = gt64260_set_32bit_window(cpu_base_addr, + size, + other_bits, + bot_reg, + top_reg)) == 0) { + + /* Set up CPU->PCI remapping (on lower 32 bits) */ + gt_write(remap_reg, pci_base_addr >> 20); + val = gt_read(bot_reg); /* Flush FIFO */ + } + + return rc; +} /* gt64260_cpu_pci_set_window() */ + + +/* + * gt64260_cpu_set_pci_io_window() + * + * Set up a CPU window into PCI I/O space. + * Always do Read/Modify/Write to window regs. + */ +int +gt64260_cpu_set_pci_io_window(u32 pci_bus, + u32 cpu_base_addr, + u32 pci_base_addr, + u32 size, + u32 swap) +{ + /* 2 PCI buses with 1 I/O window each (from CPU point of view) */ + static u32 + cpu_pci_io_windows[GT64260_PCI_BUSES][3] = { + { GT64260_CPU_PCI_0_IO_DECODE_BOT, + GT64260_CPU_PCI_0_IO_DECODE_TOP, + GT64260_CPU_PCI_0_IO_REMAP }, + + { GT64260_CPU_PCI_1_IO_DECODE_BOT, + GT64260_CPU_PCI_1_IO_DECODE_TOP, + GT64260_CPU_PCI_1_IO_REMAP }, + }; /* cpu_pci_io_windows[][] */ + int rc = -1; + + if (pci_bus < GT64260_PCI_BUSES) { + rc = gt64260_cpu_pci_set_window(cpu_base_addr, + pci_base_addr, + size, + swap, + cpu_pci_io_windows[pci_bus][0], + cpu_pci_io_windows[pci_bus][1], + cpu_pci_io_windows[pci_bus][2]); + } + + return rc; +} /* gt64260_cpu_set_pci_io_window() */ + +/* + * gt64260_cpu_set_pci_mem_window() + * + * Set up a CPU window into PCI MEM space (4 PCI MEM windows per PCI bus). + * Always do Read/Modify/Write to window regs. + */ +int +gt64260_cpu_set_pci_mem_window(u32 pci_bus, + u32 window, + u32 cpu_base_addr, + u32 pci_base_addr_hi, + u32 pci_base_addr_lo, + u32 size, + u32 swap_64bit) +{ + /* 2 PCI buses with 4 memory windows each (from CPU point of view) */ + static u32 + cpu_pci_mem_windows[GT64260_PCI_BUSES][GT64260_PCI_MEM_WINDOWS_PER_BUS][4] = { + { /* PCI 0 */ + { GT64260_CPU_PCI_0_MEM_0_DECODE_BOT, + GT64260_CPU_PCI_0_MEM_0_DECODE_TOP, + GT64260_CPU_PCI_0_MEM_0_REMAP_HI, + GT64260_CPU_PCI_0_MEM_0_REMAP_LO }, + + { GT64260_CPU_PCI_0_MEM_1_DECODE_BOT, + GT64260_CPU_PCI_0_MEM_1_DECODE_TOP, + GT64260_CPU_PCI_0_MEM_1_REMAP_HI, + GT64260_CPU_PCI_0_MEM_1_REMAP_LO }, + + { GT64260_CPU_PCI_0_MEM_2_DECODE_BOT, + GT64260_CPU_PCI_0_MEM_2_DECODE_TOP, + GT64260_CPU_PCI_0_MEM_2_REMAP_HI, + GT64260_CPU_PCI_0_MEM_2_REMAP_LO }, + + { GT64260_CPU_PCI_0_MEM_3_DECODE_BOT, + GT64260_CPU_PCI_0_MEM_3_DECODE_TOP, + GT64260_CPU_PCI_0_MEM_3_REMAP_HI, + GT64260_CPU_PCI_0_MEM_3_REMAP_LO } + }, + + { /* PCI 1 */ + { GT64260_CPU_PCI_1_MEM_0_DECODE_BOT, + GT64260_CPU_PCI_1_MEM_0_DECODE_TOP, + GT64260_CPU_PCI_1_MEM_0_REMAP_HI, + GT64260_CPU_PCI_1_MEM_0_REMAP_LO }, + + { GT64260_CPU_PCI_1_MEM_1_DECODE_BOT, + GT64260_CPU_PCI_1_MEM_1_DECODE_TOP, + GT64260_CPU_PCI_1_MEM_1_REMAP_HI, + GT64260_CPU_PCI_1_MEM_1_REMAP_LO }, + + { GT64260_CPU_PCI_1_MEM_2_DECODE_BOT, + GT64260_CPU_PCI_1_MEM_2_DECODE_TOP, + GT64260_CPU_PCI_1_MEM_2_REMAP_HI, + GT64260_CPU_PCI_1_MEM_2_REMAP_LO }, + + { GT64260_CPU_PCI_1_MEM_3_DECODE_BOT, + GT64260_CPU_PCI_1_MEM_3_DECODE_TOP, + GT64260_CPU_PCI_1_MEM_3_REMAP_HI, + GT64260_CPU_PCI_1_MEM_3_REMAP_LO }, + } + }; /* cpu_pci_mem_windows[][][] */ + u32 remap_reg, remap; + int rc = -1; + + if ((pci_bus < GT64260_PCI_BUSES) && + (window < GT64260_PCI_MEM_WINDOWS_PER_BUS)) { + + if (gt64260_cpu_pci_set_window( + cpu_base_addr, + pci_base_addr_lo, + size, + swap_64bit, + cpu_pci_mem_windows[pci_bus][window][0], + cpu_pci_mem_windows[pci_bus][window][1], + cpu_pci_mem_windows[pci_bus][window][3]) == 0) { + + remap_reg = cpu_pci_mem_windows[pci_bus][window][2]; + gt_write(remap_reg, pci_base_addr_hi); + + remap = gt_read(remap_reg); /* Flush FIFO */ + + rc = 0; + } + } + + return rc; +} /* gt64260_cpu_set_pci_mem_window() */ + +int +gt64260_cpu_prot_set_window(u32 window, + u32 base_addr, + u32 size, + u32 access_bits) +{ + static u32 + cpu_prot_windows[GT64260_CPU_PROT_WINDOWS][2] = { + { GT64260_CPU_PROT_BASE_0, GT64260_CPU_PROT_TOP_0 }, + { GT64260_CPU_PROT_BASE_1, GT64260_CPU_PROT_TOP_1 }, + { GT64260_CPU_PROT_BASE_2, GT64260_CPU_PROT_TOP_2 }, + { GT64260_CPU_PROT_BASE_3, GT64260_CPU_PROT_TOP_3 }, + { GT64260_CPU_PROT_BASE_4, GT64260_CPU_PROT_TOP_4 }, + { GT64260_CPU_PROT_BASE_5, GT64260_CPU_PROT_TOP_5 }, + { GT64260_CPU_PROT_BASE_6, GT64260_CPU_PROT_TOP_6 }, + { GT64260_CPU_PROT_BASE_7, GT64260_CPU_PROT_TOP_7 }, + }; /* cpu_prot_windows[][] */ + int rc = -1; + + if (window < GT64260_CPU_PROT_WINDOWS) { + rc = gt64260_set_32bit_window(base_addr, + size, + access_bits, + cpu_prot_windows[window][0], + cpu_prot_windows[window][1]); + } + + return rc; +} /* gt64260_cpu_prot_set_window() */ + +int +gt64260_cpu_snoop_set_window(u32 window, + u32 base_addr, + u32 size, + u32 snoop_type) +{ + static u32 + cpu_snoop_windows[GT64260_CPU_SNOOP_WINDOWS][2] = { + { GT64260_CPU_SNOOP_BASE_0, GT64260_CPU_SNOOP_TOP_0 }, + { GT64260_CPU_SNOOP_BASE_1, GT64260_CPU_SNOOP_TOP_1 }, + { GT64260_CPU_SNOOP_BASE_2, GT64260_CPU_SNOOP_TOP_2 }, + { GT64260_CPU_SNOOP_BASE_3, GT64260_CPU_SNOOP_TOP_3 }, + }; /* cpu_snoop_windows[][] */ + int rc = -1; + + if ((window < GT64260_CPU_SNOOP_WINDOWS) && + (snoop_type <= GT64260_CPU_SNOOP_WB)) { + + rc = gt64260_set_32bit_window(base_addr, + size, + snoop_type, + cpu_snoop_windows[window][0], + cpu_snoop_windows[window][1]); + } + + return rc; +} /* gt64260_cpu_snoop_set_window() */ + +void +gt64260_cpu_disable_all_windows(void) +{ + int pci_bus, window; + + /* Don't disable SCS windows b/c we need to access system memory */ + + for (window=0; window<GT64260_CPU_CS_DECODE_WINDOWS; window++) { + gt64260_cpu_cs_set_window(window, 0, 0); + } + + gt64260_cpu_boot_set_window(0, 0); + + for (pci_bus=0; pci_bus<GT64260_PCI_BUSES; pci_bus++) { + gt64260_cpu_set_pci_io_window(pci_bus, 0, 0, 0, 0); + + for (window=0;window<GT64260_PCI_MEM_WINDOWS_PER_BUS;window++) { + gt64260_cpu_set_pci_mem_window(pci_bus, + window, + 0, 0, 0, 0, 0); + } + } + + for (window=0; window<GT64260_CPU_PROT_WINDOWS; window++) { + gt64260_cpu_prot_set_window(window, 0, 0, 0); + } + + for (window=0; window<GT64260_CPU_SNOOP_WINDOWS; window++) { + gt64260_cpu_snoop_set_window(window, 0, 0, 0); + } + + return; +} /* gt64260_cpu_disable_all_windows() */ + + +/* + ***************************************************************************** + * + * PCI Slave Window Configuration Routines + * + ***************************************************************************** + */ + +int +gt64260_pci_bar_enable(u32 pci_bus, + u32 enable_bits) +{ + u32 reg, val; + int rc = -1; + + if (pci_bus < GT64260_PCI_BUSES) { + reg = (pci_bus == 0) ? GT64260_PCI_0_SLAVE_BAR_REG_ENABLES : + GT64260_PCI_1_SLAVE_BAR_REG_ENABLES; + + + /* Note: '0' enables, '1' disables */ + val = gt_read(reg); + val |= 0xffffffff; /* Disable everything by default */ + val &= ~enable_bits; + gt_write(reg, val); + + gt_read(reg); /* Flush FIFO */ + + rc = 0; + } + + return rc; +} /* gt64260_pci_bar_enable() */ + +static int +gt64260_pci_slave_set_window(struct pci_controller *hose, + u32 pci_base_addr, + u32 cpu_base_addr, + u32 bar_size, + u32 pci_cfg_fcn, + u32 pci_cfg_hdr_offset, + u32 bar_size_reg, + u32 remap_reg) +{ + u32 val; + int devfn; + u8 save_exclude; + + pci_base_addr &= 0xfffff000; + cpu_base_addr &= 0xfffff000; + bar_size &= 0xfffff000; + devfn = PCI_DEVFN(0, pci_cfg_fcn); + + gt_write(bar_size_reg, (bar_size - 1) & 0xfffff000); + gt_write(remap_reg, cpu_base_addr); + gt_read(remap_reg); /* Flush FIFO */ + + save_exclude = gt64260_pci_exclude_bridge; + gt64260_pci_exclude_bridge = FALSE; + early_read_config_dword(hose, + hose->first_busno, + devfn, + pci_cfg_hdr_offset, + &val); + val &= 0x0000000f; + early_write_config_dword(hose, + hose->first_busno, + devfn, + pci_cfg_hdr_offset, + pci_base_addr | val); + gt64260_pci_exclude_bridge = save_exclude; + + return 0; +} /* gt64260_pci_slave_set_window() */ + +int +gt64260_pci_slave_scs_set_window(struct pci_controller *hose, + u32 window, + u32 pci_base_addr, + u32 cpu_base_addr, + u32 size) +{ + static u32 + pci_scs_windows[GT64260_PCI_BUSES][GT64260_PCI_SCS_WINDOWS][4] = { + { /* PCI 0 */ + { 0, 0x10, + GT64260_PCI_0_SLAVE_SCS_0_SIZE, + GT64260_PCI_0_SLAVE_SCS_0_REMAP }, + { 0, 0x14, + GT64260_PCI_0_SLAVE_SCS_1_SIZE, + GT64260_PCI_0_SLAVE_SCS_1_REMAP }, + { 0, 0x18, + GT64260_PCI_0_SLAVE_SCS_2_SIZE, + GT64260_PCI_0_SLAVE_SCS_2_REMAP }, + { 0, 0x1c, + GT64260_PCI_0_SLAVE_SCS_3_SIZE, + GT64260_PCI_0_SLAVE_SCS_3_REMAP }, + }, + { /* PCI 1 */ + { 0, 0x10, + GT64260_PCI_1_SLAVE_SCS_0_SIZE, + GT64260_PCI_1_SLAVE_SCS_0_REMAP }, + { 0, 0x14, + GT64260_PCI_1_SLAVE_SCS_1_SIZE, + GT64260_PCI_1_SLAVE_SCS_1_REMAP }, + { 0, 0x18, + GT64260_PCI_1_SLAVE_SCS_2_SIZE, + GT64260_PCI_1_SLAVE_SCS_2_REMAP }, + { 0, 0x1c, + GT64260_PCI_1_SLAVE_SCS_3_SIZE, + GT64260_PCI_1_SLAVE_SCS_3_REMAP }, + } + }; /* pci_scs_windows[][][] */ + int pci_bus; + int rc = -1; + + if (window < GT64260_PCI_SCS_WINDOWS) { + pci_bus = (hose->first_busno == 0) ? 0 : 1; + + rc = gt64260_pci_slave_set_window( + hose, + pci_base_addr, + cpu_base_addr, + size, + pci_scs_windows[pci_bus][window][0], + pci_scs_windows[pci_bus][window][1], + pci_scs_windows[pci_bus][window][2], + pci_scs_windows[pci_bus][window][3]); + } + + return rc; +} /* gt64260_pci_slave_scs_set_window() */ + +int +gt64260_pci_slave_cs_set_window(struct pci_controller *hose, + u32 window, + u32 pci_base_addr, + u32 cpu_base_addr, + u32 size) +{ + static u32 + pci_cs_windows[GT64260_PCI_BUSES][GT64260_PCI_CS_WINDOWS][4] = { + { /* PCI 0 */ + { 1, 0x10, + GT64260_PCI_0_SLAVE_CS_0_SIZE, + GT64260_PCI_0_SLAVE_CS_0_REMAP }, + { 1, 0x14, + GT64260_PCI_0_SLAVE_CS_1_SIZE, + GT64260_PCI_0_SLAVE_CS_1_REMAP }, + { 1, 0x18, + GT64260_PCI_0_SLAVE_CS_2_SIZE, + GT64260_PCI_0_SLAVE_CS_2_REMAP }, + { 1, 0x1c, + GT64260_PCI_0_SLAVE_CS_3_SIZE, + GT64260_PCI_0_SLAVE_CS_3_REMAP }, + }, + { /* PCI 1 */ + { 1, 0x10, + GT64260_PCI_1_SLAVE_CS_0_SIZE, + GT64260_PCI_1_SLAVE_CS_0_REMAP }, + { 1, 0x14, + GT64260_PCI_1_SLAVE_CS_1_SIZE, + GT64260_PCI_1_SLAVE_CS_1_REMAP }, + { 1, 0x18, + GT64260_PCI_1_SLAVE_CS_2_SIZE, + GT64260_PCI_1_SLAVE_CS_2_REMAP }, + { 1, 0x1c, + GT64260_PCI_1_SLAVE_CS_3_SIZE, + GT64260_PCI_1_SLAVE_CS_3_REMAP }, + } + }; /* pci_cs_windows[][][] */ + int pci_bus; + int rc = -1; + + if (window < GT64260_PCI_CS_WINDOWS) { + pci_bus = (hose->first_busno == 0) ? 0 : 1; + + rc = gt64260_pci_slave_set_window( + hose, + pci_base_addr, + cpu_base_addr, + size, + pci_cs_windows[pci_bus][window][0], + pci_cs_windows[pci_bus][window][1], + pci_cs_windows[pci_bus][window][2], + pci_cs_windows[pci_bus][window][3]); + } + + return rc; +} /* gt64260_pci_slave_cs_set_window() */ + +int +gt64260_pci_slave_boot_set_window(struct pci_controller *hose, + u32 pci_base_addr, + u32 cpu_base_addr, + u32 size) +{ + int rc; + + rc = gt64260_pci_slave_set_window(hose, + pci_base_addr, + cpu_base_addr, + size, + 1, + 0x20, + GT64260_PCI_1_SLAVE_BOOT_SIZE, + GT64260_PCI_1_SLAVE_BOOT_REMAP); + + return rc; +} /* gt64260_pci_slave_boot_set_window() */ + +int +gt64260_pci_slave_p2p_mem_set_window(struct pci_controller *hose, + u32 window, + u32 pci_base_addr, + u32 other_bus_base_addr, + u32 size) +{ + static u32 + pci_p2p_mem_windows[GT64260_PCI_BUSES][GT64260_PCI_P2P_MEM_WINDOWS][4]={ + { /* PCI 0 */ + { 2, 0x10, + GT64260_PCI_0_SLAVE_P2P_MEM_0_SIZE, + GT64260_PCI_0_SLAVE_P2P_MEM_0_REMAP_LO }, + { 2, 0x14, + GT64260_PCI_0_SLAVE_P2P_MEM_1_SIZE, + GT64260_PCI_0_SLAVE_P2P_MEM_1_REMAP_LO }, + }, + { /* PCI 1 */ + { 2, 0x10, + GT64260_PCI_1_SLAVE_P2P_MEM_0_SIZE, + GT64260_PCI_1_SLAVE_P2P_MEM_0_REMAP_LO }, + { 2, 0x14, + GT64260_PCI_1_SLAVE_P2P_MEM_1_SIZE, + GT64260_PCI_1_SLAVE_P2P_MEM_1_REMAP_LO }, + } + }; /* pci_p2p_mem_windows[][][] */ + int pci_bus; + int rc = -1; + + if (window < GT64260_PCI_P2P_MEM_WINDOWS) { + pci_bus = (hose->first_busno == 0) ? 0 : 1; + + rc = gt64260_pci_slave_set_window( + hose, + pci_base_addr, + other_bus_base_addr, + size, + pci_p2p_mem_windows[pci_bus][window][0], + pci_p2p_mem_windows[pci_bus][window][1], + pci_p2p_mem_windows[pci_bus][window][2], + pci_p2p_mem_windows[pci_bus][window][3]); + } + + return rc; +} /* gt64260_pci_slave_p2p_mem_set_window() */ + +int +gt64260_pci_slave_p2p_io_set_window(struct pci_controller *hose, + u32 pci_base_addr, + u32 other_bus_base_addr, + u32 size) +{ + int rc; + + rc = gt64260_pci_slave_set_window(hose, + pci_base_addr, + other_bus_base_addr, + size, + 2, + 0x18, + GT64260_PCI_1_SLAVE_P2P_IO_SIZE, + GT64260_PCI_1_SLAVE_P2P_IO_REMAP); + + return rc; +} /* gt64260_pci_slave_p2p_io_set_window() */ + +int +gt64260_pci_slave_dac_scs_set_window(struct pci_controller *hose, + u32 window, + u32 pci_base_addr_hi, + u32 pci_base_addr_lo, + u32 cpu_base_addr, + u32 size) +{ + static u32 + pci_dac_scs_windows[GT64260_PCI_BUSES][GT64260_PCI_DAC_SCS_WINDOWS][5]={ + { /* PCI 0 */ + { 4, 0x10, 0x14, + GT64260_PCI_0_SLAVE_DAC_SCS_0_SIZE, + GT64260_PCI_0_SLAVE_DAC_SCS_0_REMAP }, + { 4, 0x18, 0x1c, + GT64260_PCI_0_SLAVE_DAC_SCS_1_SIZE, + GT64260_PCI_0_SLAVE_DAC_SCS_1_REMAP }, + { 5, 0x10, 0x14, + GT64260_PCI_0_SLAVE_DAC_SCS_2_SIZE, + GT64260_PCI_0_SLAVE_DAC_SCS_2_REMAP }, + { 5, 0x18, 0x1c, + GT64260_PCI_0_SLAVE_DAC_SCS_3_SIZE, + GT64260_PCI_0_SLAVE_DAC_SCS_3_REMAP }, + }, + { /* PCI 1 */ + { 4, 0x10, 0x14, + GT64260_PCI_1_SLAVE_DAC_SCS_0_SIZE, + GT64260_PCI_1_SLAVE_DAC_SCS_0_REMAP }, + { 4, 0x18, 0x1c, + GT64260_PCI_1_SLAVE_DAC_SCS_1_SIZE, + GT64260_PCI_1_SLAVE_DAC_SCS_1_REMAP }, + { 5, 0x10, 0x14, + GT64260_PCI_1_SLAVE_DAC_SCS_2_SIZE, + GT64260_PCI_1_SLAVE_DAC_SCS_2_REMAP }, + { 5, 0x18, 0x1c, + GT64260_PCI_1_SLAVE_DAC_SCS_3_SIZE, + GT64260_PCI_1_SLAVE_DAC_SCS_3_REMAP }, + } + }; /* pci_dac_scs_windows[][][] */ + int pci_bus; + int rc = -1; + + if (window < GT64260_PCI_DAC_SCS_WINDOWS) { + pci_bus = (hose->first_busno == 0) ? 0 : 1; + + rc = gt64260_pci_slave_set_window( + hose, + pci_base_addr_lo, + cpu_base_addr, + size, + pci_dac_scs_windows[pci_bus][window][0], + pci_dac_scs_windows[pci_bus][window][1], + pci_dac_scs_windows[pci_bus][window][3], + pci_dac_scs_windows[pci_bus][window][4]); + + early_write_config_dword( + hose, + hose->first_busno, + PCI_DEVFN(0, pci_dac_scs_windows[pci_bus][window][0]), + pci_dac_scs_windows[pci_bus][window][2], + pci_base_addr_hi); + } + + return rc; +} /* gt64260_pci_slave_dac_scs_set_window() */ + +int +gt64260_pci_slave_dac_cs_set_window(struct pci_controller *hose, + u32 window, + u32 pci_base_addr_hi, + u32 pci_base_addr_lo, + u32 cpu_base_addr, + u32 size) +{ + static u32 + pci_dac_cs_windows[GT64260_PCI_BUSES][GT64260_PCI_DAC_CS_WINDOWS][5] = { + { /* PCI 0 */ + { 6, 0x10, 0x14, + GT64260_PCI_0_SLAVE_DAC_CS_0_SIZE, + GT64260_PCI_0_SLAVE_DAC_CS_0_REMAP }, + { 6, 0x18, 0x1c, + GT64260_PCI_0_SLAVE_DAC_CS_1_SIZE, + GT64260_PCI_0_SLAVE_DAC_CS_1_REMAP }, + { 6, 0x20, 0x24, + GT64260_PCI_0_SLAVE_DAC_CS_2_SIZE, + GT64260_PCI_0_SLAVE_DAC_CS_2_REMAP }, + { 7, 0x10, 0x14, + GT64260_PCI_0_SLAVE_DAC_CS_3_SIZE, + GT64260_PCI_0_SLAVE_DAC_CS_3_REMAP }, + }, + { /* PCI 1 */ + { 6, 0x10, 0x14, + GT64260_PCI_1_SLAVE_DAC_CS_0_SIZE, + GT64260_PCI_1_SLAVE_DAC_CS_0_REMAP }, + { 6, 0x18, 0x1c, + GT64260_PCI_1_SLAVE_DAC_CS_1_SIZE, + GT64260_PCI_1_SLAVE_DAC_CS_1_REMAP }, + { 6, 0x20, 0x24, + GT64260_PCI_1_SLAVE_DAC_CS_2_SIZE, + GT64260_PCI_1_SLAVE_DAC_CS_2_REMAP }, + { 7, 0x10, 0x14, + GT64260_PCI_1_SLAVE_DAC_CS_3_SIZE, + GT64260_PCI_1_SLAVE_DAC_CS_3_REMAP }, + } + }; /* pci_dac_cs_windows[][][] */ + int pci_bus; + int rc = -1; + + if (window < GT64260_PCI_CS_WINDOWS) { + pci_bus = (hose->first_busno == 0) ? 0 : 1; + + rc = gt64260_pci_slave_set_window( + hose, + pci_base_addr_lo, + cpu_base_addr, + size, + pci_dac_cs_windows[pci_bus][window][0], + pci_dac_cs_windows[pci_bus][window][1], + pci_dac_cs_windows[pci_bus][window][3], + pci_dac_cs_windows[pci_bus][window][4]); + + early_write_config_dword( + hose, + hose->first_busno, + PCI_DEVFN(0, pci_dac_cs_windows[pci_bus][window][0]), + pci_dac_cs_windows[pci_bus][window][2], + pci_base_addr_hi); + } + + return rc; +} /* gt64260_pci_slave_dac_cs_set_window() */ + +int +gt64260_pci_slave_dac_boot_set_window(struct pci_controller *hose, + u32 pci_base_addr_hi, + u32 pci_base_addr_lo, + u32 cpu_base_addr, + u32 size) +{ + int rc; + + rc = gt64260_pci_slave_set_window(hose, + pci_base_addr_lo, + cpu_base_addr, + size, + 7, + 0x18, + GT64260_PCI_1_SLAVE_BOOT_SIZE, + GT64260_PCI_1_SLAVE_BOOT_REMAP); + + early_write_config_dword(hose, + hose->first_busno, + PCI_DEVFN(0, 7), + 0x1c, + pci_base_addr_hi); + + return rc; +} /* gt64260_pci_slave_dac_boot_set_window() */ + +int +gt64260_pci_slave_dac_p2p_mem_set_window(struct pci_controller *hose, + u32 window, + u32 pci_base_addr_hi, + u32 pci_base_addr_lo, + u32 other_bus_base_addr, + u32 size) +{ + static u32 + pci_dac_p2p_mem_windows[GT64260_PCI_BUSES][GT64260_PCI_DAC_P2P_MEM_WINDOWS][5] = { + { /* PCI 0 */ + { 4, 0x20, 0x24, + GT64260_PCI_0_SLAVE_DAC_P2P_MEM_0_SIZE, + GT64260_PCI_0_SLAVE_DAC_P2P_MEM_0_REMAP_LO }, + { 5, 0x20, 0x24, + GT64260_PCI_0_SLAVE_DAC_P2P_MEM_1_SIZE, + GT64260_PCI_0_SLAVE_DAC_P2P_MEM_1_REMAP_LO }, + }, + { /* PCI 1 */ + { 4, 0xa0, 0xa4, + GT64260_PCI_0_SLAVE_DAC_P2P_MEM_0_SIZE, + GT64260_PCI_0_SLAVE_DAC_P2P_MEM_0_REMAP_LO }, + { 5, 0xa0, 0xa4, + GT64260_PCI_0_SLAVE_DAC_P2P_MEM_1_SIZE, + GT64260_PCI_0_SLAVE_DAC_P2P_MEM_1_REMAP_LO }, + } + }; /* pci_dac_p2p_windows[][][] */ + int pci_bus; + int rc = -1; + + if (window < GT64260_PCI_P2P_MEM_WINDOWS) { + pci_bus = (hose->first_busno == 0) ? 0 : 1; + + rc = gt64260_pci_slave_set_window( + hose, + pci_base_addr_lo, + other_bus_base_addr, + size, + pci_dac_p2p_mem_windows[pci_bus][window][0], + pci_dac_p2p_mem_windows[pci_bus][window][1], + pci_dac_p2p_mem_windows[pci_bus][window][3], + pci_dac_p2p_mem_windows[pci_bus][window][4]); + + early_write_config_dword( + hose, + hose->first_busno, + PCI_DEVFN(0, pci_dac_p2p_mem_windows[pci_bus][window][0]), + pci_dac_p2p_mem_windows[pci_bus][window][2], + pci_base_addr_hi); + } + + return rc; +} /* gt64260_pci_slave_dac_p2p_mem_set_window() */ + + +/* + ***************************************************************************** + * + * PCI Control Configuration Routines + * + ***************************************************************************** + */ + + +int +gt64260_pci_acc_cntl_set_window(u32 pci_bus, + u32 window, + u32 base_addr_hi, + u32 base_addr_lo, + u32 size, + u32 features) +{ + static u32 + pci_acc_cntl_windows[GT64260_PCI_BUSES][GT64260_PCI_ACC_CNTL_WINDOWS][3] = { + { /* PCI 0 */ + { GT64260_PCI_0_ACC_CNTL_0_BASE_HI, + GT64260_PCI_0_ACC_CNTL_0_BASE_LO, + GT64260_PCI_0_ACC_CNTL_0_TOP }, + + { GT64260_PCI_0_ACC_CNTL_1_BASE_HI, + GT64260_PCI_0_ACC_CNTL_1_BASE_LO, + GT64260_PCI_0_ACC_CNTL_1_TOP }, + + { GT64260_PCI_0_ACC_CNTL_2_BASE_HI, + GT64260_PCI_0_ACC_CNTL_2_BASE_LO, + GT64260_PCI_0_ACC_CNTL_2_TOP }, + + { GT64260_PCI_0_ACC_CNTL_3_BASE_HI, + GT64260_PCI_0_ACC_CNTL_3_BASE_LO, + GT64260_PCI_0_ACC_CNTL_3_TOP }, + + { GT64260_PCI_0_ACC_CNTL_4_BASE_HI, + GT64260_PCI_0_ACC_CNTL_4_BASE_LO, + GT64260_PCI_0_ACC_CNTL_4_TOP }, + + { GT64260_PCI_0_ACC_CNTL_5_BASE_HI, + GT64260_PCI_0_ACC_CNTL_5_BASE_LO, + GT64260_PCI_0_ACC_CNTL_5_TOP }, + + { GT64260_PCI_0_ACC_CNTL_6_BASE_HI, + GT64260_PCI_0_ACC_CNTL_6_BASE_LO, + GT64260_PCI_0_ACC_CNTL_6_TOP }, + + { GT64260_PCI_0_ACC_CNTL_7_BASE_HI, + GT64260_PCI_0_ACC_CNTL_7_BASE_LO, + GT64260_PCI_0_ACC_CNTL_7_TOP }, + }, + { /* PCI 1 */ + { GT64260_PCI_1_ACC_CNTL_0_BASE_HI, + GT64260_PCI_1_ACC_CNTL_0_BASE_LO, + GT64260_PCI_1_ACC_CNTL_0_TOP }, + + { GT64260_PCI_1_ACC_CNTL_1_BASE_HI, + GT64260_PCI_1_ACC_CNTL_1_BASE_LO, + GT64260_PCI_1_ACC_CNTL_1_TOP }, + + { GT64260_PCI_1_ACC_CNTL_2_BASE_HI, + GT64260_PCI_1_ACC_CNTL_2_BASE_LO, + GT64260_PCI_1_ACC_CNTL_2_TOP }, + + { GT64260_PCI_1_ACC_CNTL_3_BASE_HI, + GT64260_PCI_1_ACC_CNTL_3_BASE_LO, + GT64260_PCI_1_ACC_CNTL_3_TOP }, + + { GT64260_PCI_1_ACC_CNTL_4_BASE_HI, + GT64260_PCI_1_ACC_CNTL_4_BASE_LO, + GT64260_PCI_1_ACC_CNTL_4_TOP }, + + { GT64260_PCI_1_ACC_CNTL_5_BASE_HI, + GT64260_PCI_1_ACC_CNTL_5_BASE_LO, + GT64260_PCI_1_ACC_CNTL_5_TOP }, + + { GT64260_PCI_1_ACC_CNTL_6_BASE_HI, + GT64260_PCI_1_ACC_CNTL_6_BASE_LO, + GT64260_PCI_1_ACC_CNTL_6_TOP }, + + { GT64260_PCI_1_ACC_CNTL_7_BASE_HI, + GT64260_PCI_1_ACC_CNTL_7_BASE_LO, + GT64260_PCI_1_ACC_CNTL_7_TOP }, + } + }; /* pci_acc_cntl_windows[][][] */ + int rc = -1; + + if ((pci_bus < GT64260_PCI_BUSES) && + (window < GT64260_PCI_ACC_CNTL_WINDOWS)) { + + rc = gt64260_set_64bit_window( + base_addr_hi, + base_addr_lo, + size, + features, + pci_acc_cntl_windows[pci_bus][window][0], + pci_acc_cntl_windows[pci_bus][window][1], + pci_acc_cntl_windows[pci_bus][window][2]); + } + + return rc; +} /* gt64260_pci_acc_cntl_set_window() */ + +int +gt64260_pci_snoop_set_window(u32 pci_bus, + u32 window, + u32 base_addr_hi, + u32 base_addr_lo, + u32 size, + u32 snoop_type) +{ + static u32 + pci_snoop_windows[GT64260_PCI_BUSES][GT64260_PCI_SNOOP_WINDOWS][3] = { + { /* PCI 0 */ + { GT64260_PCI_0_SNOOP_0_BASE_HI, + GT64260_PCI_0_SNOOP_0_BASE_LO, + GT64260_PCI_0_SNOOP_0_TOP }, + + { GT64260_PCI_0_SNOOP_1_BASE_HI, + GT64260_PCI_0_SNOOP_1_BASE_LO, + GT64260_PCI_0_SNOOP_1_TOP }, + + { GT64260_PCI_0_SNOOP_2_BASE_HI, + GT64260_PCI_0_SNOOP_2_BASE_LO, + GT64260_PCI_0_SNOOP_2_TOP }, + + { GT64260_PCI_0_SNOOP_3_BASE_HI, + GT64260_PCI_0_SNOOP_3_BASE_LO, + GT64260_PCI_0_SNOOP_3_TOP }, + }, + { /* PCI 1 */ + { GT64260_PCI_1_SNOOP_0_BASE_HI, + GT64260_PCI_1_SNOOP_0_BASE_LO, + GT64260_PCI_1_SNOOP_0_TOP }, + + { GT64260_PCI_1_SNOOP_1_BASE_HI, + GT64260_PCI_1_SNOOP_1_BASE_LO, + GT64260_PCI_1_SNOOP_1_TOP }, + + { GT64260_PCI_1_SNOOP_2_BASE_HI, + GT64260_PCI_1_SNOOP_2_BASE_LO, + GT64260_PCI_1_SNOOP_2_TOP }, + + { GT64260_PCI_1_SNOOP_3_BASE_HI, + GT64260_PCI_1_SNOOP_3_BASE_LO, + GT64260_PCI_1_SNOOP_3_TOP }, + }, + }; /* pci_snoop_windows[][][] */ + int rc = -1; + + if ((pci_bus < GT64260_PCI_BUSES) && + (window < GT64260_PCI_SNOOP_WINDOWS)) { + + rc = gt64260_set_64bit_window( + base_addr_hi, + base_addr_lo, + size, + snoop_type, + pci_snoop_windows[pci_bus][window][0], + pci_snoop_windows[pci_bus][window][1], + pci_snoop_windows[pci_bus][window][2]); + } + + return rc; +} /* gt64260_pci_snoop_set_window() */ + +/* + ***************************************************************************** + * + * 64260's Register Base Address Routines + * + ***************************************************************************** + */ + +/* + * gt64260_remap_bridge_regs() + * + * Move the bridge's register to the specified base address. + * Assume that there are no other windows overlapping this area and that + * all but the highest 3 nibbles are 0. + */ +int +gt64260_set_base(u32 new_base) +{ + u32 val; + int limit = 100000; + int rc = 0; + + val = gt_read(GT64260_INTERNAL_SPACE_DECODE); + val = (new_base >> 20) | (val & 0xffff0000); + gt_write(GT64260_INTERNAL_SPACE_DECODE, val); + + iounmap((void *)gt64260_base); + gt64260_base = (u32)ioremap((new_base & 0xfff00000), + GT64260_INTERNAL_SPACE_SIZE); + + do { /* Wait for bridge to move its regs */ + val = gt_read(GT64260_INTERNAL_SPACE_DECODE); + } while ((val != 0xffffffff) && (limit-- > 0)); + + if (limit <= 0) { + rc = -1; + } + + return rc; +} /* gt64260_remap_bridge_regs() */ + +/* + * gt64260_get_base() + * + * Return the current virtual base address of the 64260's registers. + */ +int +gt64260_get_base(u32 *base) +{ + *base = gt64260_base; + return 0; +} /* gt64260_remap_bridge_regs() */ + +/* + ***************************************************************************** + * + * Exclude PCI config space access to bridge itself + * + ***************************************************************************** + */ + +/* + * gt64260_exclude_pci_device() + * + * This routine causes the PCI subsystem to skip the PCI device in slot 0 + * (which is the 64260 itself) unless explicitly allowed. + */ +int +gt64260_pci_exclude_device(u8 bus, u8 devfn) +{ + struct pci_controller *hose; + + hose = pci_bus_to_hose(bus); + + /* Skip slot 0 and 1 on both hoses */ + if ((gt64260_pci_exclude_bridge == TRUE) && + (PCI_SLOT(devfn) == 0) && + (hose->first_busno == bus)) { + + return PCIBIOS_DEVICE_NOT_FOUND; + } + else { + return PCIBIOS_SUCCESSFUL; + } +} /* gt64260_pci_exclude_device() */ + +#if defined(CONFIG_SERIAL_TEXT_DEBUG) + +/* + * gt64260_putc() + * + * Dump a character out the MPSC port for gt64260_mpsc_progress + * this assumes the baud rate has already been set up and the + * MPSC initialized by the bootloader or firmware. + */ + +static inline void +gt_putc(char c){ + mb(); + gt_write(GT64260_MPSC_0_CHR_1, c); + mb(); + gt_write(GT64260_MPSC_0_CHR_2, 0x200); + mb(); + + udelay(10000); +} + +void +puthex(unsigned long val){ + + int i; + + for (i = 7; i >= 0; i--) { + gt_putc("0123456789ABCDEF"[(val>>28) & 0x0f]); + val <<= 4; + } + gt_putc('\r'); + gt_putc('\n'); + +} + + +void +gt64260_mpsc_progress(char *s, unsigned short hex){ + /* spit stuff out the 64260 mpsc */ + + volatile char c; + while ((c = *s++) != 0){ + gt_putc(c); + if ( c == '\n' ) gt_putc('\r'); + } + gt_putc('\n'); + gt_putc('\r'); + + return; +} + +#endif /* CONFIG_DEBUG_TEXT */ diff --git a/arch/ppc/kernel/gt64260_pic.c b/arch/ppc/kernel/gt64260_pic.c new file mode 100644 index 000000000000..e0b61032586b --- /dev/null +++ b/arch/ppc/kernel/gt64260_pic.c @@ -0,0 +1,245 @@ +/* + * arch/ppc/kernel/gt64260_pic.c + * + * Interrupt controller support for Galileo's GT64260. + * + * Author: Chris Zankel <chris@mvista.com> + * Modified by: Mark A. Greer <mgreer@mvista.com> + * + * Based on sources from Rabeeh Khoury / Galileo Technology + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +/* + * This file contains the specific functions to support the GT64260 + * interrupt controller. + * + * The GT64260 has two main interrupt registers (high and low) that + * summarizes the interrupts generated by the units of the GT64260. + * Each bit is assigned to an interrupt number, where the low register + * are assigned from IRQ0 to IRQ31 and the high cause register + * from IRQ32 to IRQ63 + * The GPP (General Purpose Port) interrupts are assigned from IRQ64 (GPP0) + * to IRQ95 (GPP31). + * get_irq() returns the lowest interrupt number that is currently asserted. + * + * Note: + * - This driver does not initialize the GPP when used as an interrupt + * input. + */ + +#include <linux/stddef.h> +#include <linux/init.h> +#include <linux/sched.h> +#include <linux/signal.h> +#include <linux/stddef.h> +#include <linux/delay.h> +#include <linux/irq.h> + +#include <asm/io.h> +#include <asm/processor.h> +#include <asm/system.h> +#include <asm/irq.h> +#include <asm/gt64260.h> + + +/* ========================== forward declaration ========================== */ + +static void gt64260_unmask_irq(unsigned int); +static void gt64260_mask_irq(unsigned int); + +/* ========================== local declarations =========================== */ + +struct hw_interrupt_type gt64260_pic = { + " GT64260_PIC ", /* typename */ + NULL, /* startup */ + NULL, /* shutdown */ + gt64260_unmask_irq, /* enable */ + gt64260_mask_irq, /* disable */ + gt64260_mask_irq, /* ack */ + NULL, /* end */ + NULL /* set_affinity */ +}; + +u32 gt64260_irq_base = 0; /* GT64260 handles the next 96 IRQs from here */ + +/* gt64260_init_irq() + * + * This function initializes the interrupt controller. It assigns + * all interrupts from IRQ0 to IRQ95 to the gt64260 interrupt controller. + * + * Input Variable(s): + * None. + * + * Outpu. Variable(s): + * None. + * + * Returns: + * void + * + * Note: + * We register all GPP inputs as interrupt source, but disable them. + */ + +__init void +gt64260_init_irq(void) +{ + int i; + + if ( ppc_md.progress ) ppc_md.progress("gt64260_init_irq: enter", 0x0); + + ppc_cached_irq_mask[0] = 0; + ppc_cached_irq_mask[1] = 0x0f000000; /* Enable GPP intrs */ + ppc_cached_irq_mask[2] = 0; + + /* disable all interrupts and clear current interrupts */ + gt_write(GT64260_GPP_INTR_MASK, ppc_cached_irq_mask[2]); + gt_write(GT64260_GPP_INTR_CAUSE,0); + gt_write(GT64260_IC_CPU_INTR_MASK_LO, ppc_cached_irq_mask[0]); + gt_write(GT64260_IC_CPU_INTR_MASK_HI, ppc_cached_irq_mask[1]); + + /* use the gt64260 for all (possible) interrupt sources */ + for( i = gt64260_irq_base; i < (gt64260_irq_base + 96); i++ ) { + irq_desc[i].handler = >64260_pic; + } + + if ( ppc_md.progress ) ppc_md.progress("gt64260_init_irq: exit", 0x0); +} + + +/* gt64260_get_irq() + * + * This function returns the lowest interrupt number of all interrupts that + * are currently asserted. + * + * Input Variable(s): + * struct pt_regs* not used + * + * Output Variable(s): + * None. + * + * Returns: + * int <interrupt number> or -2 (bogus interrupt) + * + */ +int +gt64260_get_irq(struct pt_regs *regs) +{ + int irq; + int irq_gpp; + + irq = gt_read(GT64260_IC_MAIN_CAUSE_LO); + irq = __ilog2((irq & 0x3dfffffe) & ppc_cached_irq_mask[0]); + + if (irq == -1) { + irq = gt_read(GT64260_IC_MAIN_CAUSE_HI); + irq = __ilog2((irq & 0x0f000db7) & ppc_cached_irq_mask[1]); + + if (irq == -1) { + irq = -2; /* bogus interrupt, should never happen */ + } else { + if (irq >= 24) { + irq_gpp = gt_read(GT64260_GPP_INTR_CAUSE); + irq_gpp = __ilog2(irq_gpp & + ppc_cached_irq_mask[2]); + + if (irq_gpp == -1) { + irq = -2; + } else { + irq = irq_gpp + 64; + gt_write(GT64260_GPP_INTR_CAUSE, ~(1<<(irq-64))); + } + } else { + irq += 32; + } + } + } + + if( irq < 0 ) { + return( irq ); + } else { + return( gt64260_irq_base + irq ); + } +} + +/* gt64260_unmask_irq() + * + * This function enables an interrupt. + * + * Input Variable(s): + * unsigned int interrupt number (IRQ0...IRQ95). + * + * Output Variable(s): + * None. + * + * Returns: + * void + */ + +static void +gt64260_unmask_irq(unsigned int irq) +{ + irq -= gt64260_irq_base; + if (irq > 31) { + if (irq > 63) { + /* unmask GPP irq */ + gt_write(GT64260_GPP_INTR_MASK, + ppc_cached_irq_mask[2] |= (1<<(irq-64))); + } else { + /* mask high interrupt register */ + gt_write(GT64260_IC_CPU_INTR_MASK_HI, + ppc_cached_irq_mask[1] |= (1<<(irq-32))); + } + } else { + /* mask low interrupt register */ + gt_write(GT64260_IC_CPU_INTR_MASK_LO, + ppc_cached_irq_mask[0] |= (1<<irq)); + } +} + + +/* gt64260_mask_irq() + * + * This funktion disables the requested interrupt. + * + * Input Variable(s): + * unsigned int interrupt number (IRQ0...IRQ95). + * + * Output Variable(s): + * None. + * + * Returns: + * void + */ + +static void +gt64260_mask_irq(unsigned int irq) +{ + irq -= gt64260_irq_base; + if (irq > 31) { + if (irq > 63) { + /* mask GPP irq */ + gt_write(GT64260_GPP_INTR_MASK, + ppc_cached_irq_mask[2] &= ~(1<<(irq-64))); + } else { + /* mask high interrupt register */ + gt_write(GT64260_IC_CPU_INTR_MASK_HI, + ppc_cached_irq_mask[1] &= ~(1<<(irq-32))); + } + } else { + /* mask low interrupt register */ + gt_write(GT64260_IC_CPU_INTR_MASK_LO, + ppc_cached_irq_mask[0] &= ~(1<<irq)); + } + + if (irq == 36) { /* Seems necessary for SDMA interrupts */ + udelay(1); + } +} + diff --git a/arch/ppc/kernel/harrier.c b/arch/ppc/kernel/harrier.c new file mode 100644 index 000000000000..343ada453eac --- /dev/null +++ b/arch/ppc/kernel/harrier.c @@ -0,0 +1,214 @@ +/* + * arch/ppc/kernel/harrier.c + * + * Motorola MCG Harrier northbridge/memory controller support + * + * Author: Dale Farnsworth + * dale.farnsworth@mvista.com + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/pci.h> + +#include <asm/byteorder.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/pci.h> +#include <asm/pci-bridge.h> +#include <asm/open_pic.h> +#include <asm/harrier.h> + +/* + * Initialize the Motorola MCG Harrier host bridge. + * + * This means setting up the PPC bus to PCI memory and I/O space mappings, + * setting the PCI memory space address of the MPIC (mapped straight + * through), and ioremap'ing the mpic registers. + * 'OpenPIC_Addr' will be set correctly by this routine. + * This routine will not change the PCI_CONFIG_ADDR or PCI_CONFIG_DATA + * addresses and assumes that the mapping of PCI memory space back to system + * memory is set up correctly by PPCBug. + */ +int __init +harrier_init(struct pci_controller *hose, + uint ppc_reg_base, + ulong processor_pci_mem_start, + ulong processor_pci_mem_end, + ulong processor_pci_io_start, + ulong processor_pci_io_end, + ulong processor_mpic_base) +{ + uint addr, offset; + + /* + * Some sanity checks... + */ + if (((processor_pci_mem_start&0xffff0000) != processor_pci_mem_start) || + ((processor_pci_io_start &0xffff0000) != processor_pci_io_start)) { + printk("harrier_init: %s\n", + "PPC to PCI mappings must start on 64 KB boundaries"); + return -1; + } + + if (((processor_pci_mem_end &0x0000ffff) != 0x0000ffff) || + ((processor_pci_io_end &0x0000ffff) != 0x0000ffff)) { + printk("harrier_init: PPC to PCI mappings %s\n", + "must end just before a 64 KB boundaries"); + return -1; + } + + if (((processor_pci_mem_end - processor_pci_mem_start) != + (hose->mem_space.end - hose->mem_space.start)) || + ((processor_pci_io_end - processor_pci_io_start) != + (hose->io_space.end - hose->io_space.start))) { + printk("harrier_init: %s\n", + "PPC and PCI memory or I/O space sizes don't match"); + return -1; + } + + if ((processor_mpic_base & 0xfffc0000) != processor_mpic_base) { + printk("harrier_init: %s\n", + "MPIC address must start on 256 KB boundary"); + return -1; + } + + if ((pci_dram_offset & 0xffff0000) != pci_dram_offset) { + printk("harrier_init: %s\n", + "pci_dram_offset must be multiple of 64 KB"); + return -1; + } + + /* + * Program the OTAD/OTOF registers to set up the PCI Mem & I/O + * space mappings. These are the mappings going from the processor to + * the PCI bus. + * + * Note: Don't need to 'AND' start/end addresses with 0xffff0000 + * because sanity check above ensures that they are properly + * aligned. + */ + + /* Set up PPC->PCI Mem mapping */ + addr = processor_pci_mem_start | (processor_pci_mem_end >> 16); + offset = (hose->mem_space.start - processor_pci_mem_start) | 0x92; + out_be32((uint *)(ppc_reg_base + HARRIER_OTAD0_OFF), addr); + out_be32((uint *)(ppc_reg_base + HARRIER_OTOF0_OFF), offset); + + /* Set up PPC->PCI I/O mapping -- Contiguous I/O space */ + addr = processor_pci_io_start | (processor_pci_io_end >> 16); + offset = (hose->io_space.start - processor_pci_io_start) | 0x80; + out_be32((uint *)(ppc_reg_base + HARRIER_OTAD1_OFF), addr); + out_be32((uint *)(ppc_reg_base + HARRIER_OTOF1_OFF), offset); + + /* Enable MPIC */ + OpenPIC_Addr = (void *)processor_mpic_base; + addr = (processor_mpic_base >> 16) | 1; + out_be16((ushort *)(ppc_reg_base + HARRIER_MBAR_OFF), addr); + out_8((u_char *)(ppc_reg_base + HARRIER_MPIC_CSR_OFF), + HARRIER_MPIC_OPI_ENABLE); + + return 0; +} + +/* + * Find the amount of RAM present. + * This assumes that PPCBug has initialized the memory controller (SMC) + * on the Harrier correctly (i.e., it does no sanity checking). + * It also assumes that the memory base registers are set to configure the + * memory as contigous starting with "RAM A BASE", "RAM B BASE", etc. + * however, RAM base registers can be skipped (e.g. A, B, C are set, + * D is skipped but E is set is okay). + */ +#define MB (1024*1024UL) + +static uint harrier_size_table[] __initdata = { + 0 * MB, /* 0 ==> 0 MB */ + 32 * MB, /* 1 ==> 32 MB */ + 64 * MB, /* 2 ==> 64 MB */ + 64 * MB, /* 3 ==> 64 MB */ + 128 * MB, /* 4 ==> 128 MB */ + 128 * MB, /* 5 ==> 128 MB */ + 128 * MB, /* 6 ==> 128 MB */ + 256 * MB, /* 7 ==> 256 MB */ + 256 * MB, /* 8 ==> 256 MB */ + 256 * MB, /* 9 ==> 256 MB */ + 512 * MB, /* a ==> 512 MB */ + 512 * MB, /* b ==> 512 MB */ + 512 * MB, /* c ==> 512 MB */ + 1024 * MB, /* d ==> 1024 MB */ + 1024 * MB, /* e ==> 1024 MB */ + 2048 * MB, /* f ==> 2048 MB */ +}; + +/* + * *** WARNING: You MUST have a BAT set up to map in the XCSR regs *** + * + * Read the memory controller's registers to determine the amount of system + * memory. Assumes that the memory controller registers are already mapped + * into virtual memory--too early to use ioremap(). + */ +unsigned long __init +harrier_get_mem_size(uint xcsr_base) +{ + ulong last_addr; + int i; + uint vend_dev_id; + uint *size_table; + uint val; + uint *csrp; + uint size; + int size_table_entries; + + vend_dev_id = in_be32((uint *)xcsr_base + PCI_VENDOR_ID); + + if (((vend_dev_id & 0xffff0000) >> 16) != PCI_VENDOR_ID_MOTOROLA) { + printk("harrier_get_mem_size: %s (0x%x)\n", + "Not a Motorola Memory Controller", vend_dev_id); + return 0; + } + + vend_dev_id &= 0x0000ffff; + + if (vend_dev_id == PCI_DEVICE_ID_MOTOROLA_HARRIER) { + size_table = harrier_size_table; + size_table_entries = sizeof(harrier_size_table) / + sizeof(harrier_size_table[0]); + } + else { + printk("harrier_get_mem_size: %s (0x%x)\n", + "Not a Harrier", vend_dev_id); + return 0; + } + + last_addr = 0; + + csrp = (uint *)(xcsr_base + HARRIER_SDBA_OFF); + for (i=0; i<8; i++) { + val = in_be32(csrp++); + + if (val & 0x100) { /* If enabled */ + size = val >> HARRIER_SDB_SIZE_SHIFT; + size &= HARRIER_SDB_SIZE_MASK; + if (size >= size_table_entries) { + break; /* Register not set correctly */ + } + size = size_table[size]; + + val &= ~(size-1); + val += size; + + if (val > last_addr) { + last_addr = val; + } + } + } + + return last_addr; +} diff --git a/arch/ppc/kernel/head.S b/arch/ppc/kernel/head.S index 5e13c0a9257d..6a57fa4dad53 100644 --- a/arch/ppc/kernel/head.S +++ b/arch/ppc/kernel/head.S @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.head.S 1.31 10/18/01 15:02:09 trini + * BK Id: %F% %I% %G% %U% %#% */ /* * PowerPC version @@ -22,17 +22,18 @@ * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. - * + * */ #include <linux/config.h> -#include "ppc_asm.h" #include <asm/processor.h> #include <asm/page.h> #include <asm/mmu.h> #include <asm/pgtable.h> #include <asm/cputable.h> #include <asm/cache.h> +#include <asm/ppc_asm.h> +#include "ppc_defs.h" #ifdef CONFIG_APUS #include <asm/amigappc.h> @@ -48,9 +49,9 @@ ld RB,(n*32)+24(reg); \ mtspr DBAT##n##U,RA; \ mtspr DBAT##n##L,RB; \ - + #else /* CONFIG_PPC64BRIDGE */ - + /* 601 only have IBAT; cr0.eq is set on 601 when using this macro */ #define LOAD_BAT(n, reg, RA, RB) \ /* see the comment for clear_bats() -- Cort */ \ @@ -66,10 +67,13 @@ lwz RB,(n*16)+12(reg); \ mtspr DBAT##n##U,RA; \ mtspr DBAT##n##L,RB; \ -1: +1: #endif /* CONFIG_PPC64BRIDGE */ .text + .stabs "arch/ppc/kernel/",N_SO,0,0,0f + .stabs "head.S",N_SO,0,0,0f +0: .globl _stext _stext: @@ -86,8 +90,8 @@ _start: * but we're always started by some kind of bootloader now. * -- Cort */ - nop - nop + nop /* used by __secondary_hold on prep (mtx) and chrp smp */ + nop /* used by __secondary_hold on prep (mtx) and chrp smp */ nop /* PMAC @@ -113,7 +117,7 @@ _start: * PREP * This is jumped to on prep systems right after the kernel is relocated * to its proper place in memory by the boot loader. The expected layout - * of the regs is: + * of the regs is: * r3: ptr to residual data * r4: initrd_start or if no initrd then 0 * r5: initrd_end - unused if r4 is 0 @@ -124,7 +128,7 @@ _start: * start_here() to do the real work. * -- Cort */ - + .globl __start __start: /* @@ -153,7 +157,6 @@ __start: bl fix_mem_constants #endif /* CONFIG_APUS */ -#ifndef CONFIG_GEMINI /* Switch MMU off, clear BATs and flush TLB. At this point, r3 contains * the physical address we are running at, returned by early_init() */ @@ -161,28 +164,11 @@ __start: __after_mmu_off: bl clear_bats bl flush_tlbs -#endif -#ifndef CONFIG_POWER4 - /* POWER4 doesn't have BATs */ bl initial_bats #if !defined(CONFIG_APUS) && defined(CONFIG_BOOTX_TEXT) bl setup_disp_bat #endif -#else /* CONFIG_POWER4 */ -/* - * Load up the SDR1 and segment register values now - * since we don't have the BATs. - */ - bl reloc_offset - addis r4,r3,_SDR1@ha /* get the value from _SDR1 */ - lwz r4,_SDR1@l(r4) /* assume hash table below 4GB */ - mtspr SDR1,r4 - slbia - lis r5,0x2000 /* set pseudo-segment reg 12 */ - ori r5,r5,0x0ccc - mtsr 12,r5 -#endif /* CONFIG_POWER4 */ #ifndef CONFIG_APUS /* @@ -217,11 +203,17 @@ turn_on_mmu: SYNC RFI /* enables MMU */ -#ifdef CONFIG_SMP +/* + * We need __secondary_hold as a place to hold the other cpus on + * an SMP machine, even when we are running a UP kernel. + */ + . = 0xc0 /* for prep bootloader */ + li r3,1 /* MTX only has 1 cpu */ .globl __secondary_hold __secondary_hold: /* tell the master we're here */ stw r3,4(0) +#ifdef CONFIG_SMP 100: lwz r4,0(0) /* wait until we're told to start */ cmpw 0,r4,r3 @@ -229,7 +221,9 @@ __secondary_hold: /* our cpu # was at addr 0 - go */ mr r24,r3 /* cpu # */ b __secondary_start -#endif +#else + b . +#endif /* CONFIG_SMP */ /* * Exception entry code. This code runs with address translation @@ -289,13 +283,11 @@ i##n: \ .long ret_from_except /* System reset */ -#ifdef CONFIG_SMP /* MVME/MTX and gemini start the secondary here */ -#ifdef CONFIG_GEMINI +/* core99 pmac starts the seconary here by changing the vector, and + putting it back to what it was (UnknownException) when done. */ +#if defined(CONFIG_GEMINI) && defined(CONFIG_SMP) . = 0x100 b __secondary_start_gemini -#else /* CONFIG_GEMINI */ - STD_EXCEPTION(0x100, Reset, __secondary_start_psurge) -#endif /* CONFIG_GEMINI */ #else STD_EXCEPTION(0x100, Reset, UnknownException) #endif @@ -388,16 +380,12 @@ HardwareInterrupt: EXCEPTION_PROLOG; addi r3,r1,STACK_FRAME_OVERHEAD li r20,MSR_KERNEL -#ifndef CONFIG_APUS li r4,0 bl transfer_to_handler .globl do_IRQ_intercept do_IRQ_intercept: .long do_IRQ; .long ret_from_intercept -#else - bl apus_interrupt_entry -#endif /* CONFIG_APUS */ /* Alignment exception */ . = 0x600 @@ -487,7 +475,7 @@ trap_0f_cont: Trap_0f: EXCEPTION_PROLOG b trap_0f_cont - + /* * Handle TLB miss for instruction on 603/603e. * Note: we get an alternate set of r0 - r3 to use automatically. @@ -636,7 +624,7 @@ DataAddressInvalid: mtcrf 0x80,r3 /* Restore CR0 */ mtmsr r0 b DataAccess - + /* * Handle TLB miss for DATA Store on 603/603e */ @@ -809,11 +797,11 @@ stack_ovf: RFI /* - * Disable FP for the task which had the FPU previously, + * This task wants to use the FPU now. + * On UP, disable FP for the task which had the FPU previously, * and save its floating-point registers in its thread_struct. - * Enables the FPU for use in the kernel on return. - * On SMP we know the fpu is free, since we give it up every - * switch. -- Cort + * Load up this task's FP registers from its thread_struct, + * enable the FPU for the current task and return to the task. */ load_up_fpu: mfmsr r5 @@ -830,14 +818,13 @@ load_up_fpu: * to another. Instead we call giveup_fpu in switch_to. */ #ifndef CONFIG_SMP - lis r6,0 /* get __pa constant */ - tophys(r6,r6) + tophys(r6,0) /* get __pa constant */ addis r3,r6,last_task_used_math@ha lwz r4,last_task_used_math@l(r3) cmpi 0,r4,0 beq 1f add r4,r4,r6 - addi r4,r4,THREAD /* want THREAD of last_task_used_math */ + addi r4,r4,THREAD /* want last_task_used_math->thread */ SAVE_32FPRS(0, r4) mffs fr0 stfd fr0,THREAD_FPSCR-4(r4) @@ -850,8 +837,10 @@ load_up_fpu: 1: #endif /* CONFIG_SMP */ /* enable use of FP after return */ - ori r23,r23,MSR_FP|MSR_FE0|MSR_FE1 mfspr r5,SPRG3 /* current task's THREAD (phys) */ + lwz r4,THREAD_FPEXC_MODE(r5) + ori r23,r23,MSR_FP /* enable FP for current */ + or r23,r23,r4 lfd fr0,THREAD_FPSCR-4(r5) mtfsf 0xff,fr0 REST_32FPRS(0, r5) @@ -875,7 +864,7 @@ load_up_fpu: lwz r21,GPR21(r21) SYNC RFI - + /* * FP unavailable trap from kernel - print a message, but let * the task use FP in the kernel until it returns to user mode. @@ -1020,7 +1009,7 @@ giveup_altivec: #endif /* CONFIG_SMP */ blr #endif /* CONFIG_ALTIVEC */ - + /* * giveup_fpu(tsk) * Disable FP for the task given as the argument, @@ -1031,9 +1020,10 @@ giveup_altivec: giveup_fpu: mfmsr r5 ori r5,r5,MSR_FP - SYNC + SYNC_601 + ISYNC_601 mtmsr r5 /* enable use of fpu now */ - SYNC + SYNC_601 isync cmpi 0,r3,0 beqlr- /* if no previous owner, done */ @@ -1172,62 +1162,6 @@ fix_mem_constants: sync /* additional sync needed on g4 */ isync /* No speculative loading until now */ blr - -apus_interrupt_entry: - /* This is horrible, but there's no way around it. Enable the - * data cache so the IRQ hardware register can be accessed - * without cache intervention. Then disable interrupts and get - * the current emulated m68k IPL value. - */ - - mfmsr 20 - xori r20,r20,MSR_DR - SYNC - mtmsr r20 - isync - - lis r4,APUS_IPL_EMU@h - - li r20,(IPLEMU_SETRESET|IPLEMU_DISABLEINT) - stb r20,APUS_IPL_EMU@l(r4) - eieio - - lbz r3,APUS_IPL_EMU@l(r4) - - li r2,IPLEMU_IPLMASK - rlwinm. r20,r3,32-3,29,31 - bne 2f - mr r20,r2 /* lvl7! Need to reset state machine. */ - b 3f -2: cmp 0,r20,r2 - beq 1f -3: eieio - stb r2,APUS_IPL_EMU@l(r4) - ori r20,r20,IPLEMU_SETRESET - eieio - stb r20,APUS_IPL_EMU@l(r4) -1: eieio - li r20,IPLEMU_DISABLEINT - stb r20,APUS_IPL_EMU@l(r4) - - /* At this point we could do some magic to avoid the overhead - * of calling the C interrupt handler in case of a spurious - * interrupt. Could not get a simple hack to work though. - */ - - mfmsr r20 - xori r20,r20,MSR_DR - SYNC - mtmsr r20 - isync - - stw r3,(_CCR+4)(r21); - - addi r3,r1,STACK_FRAME_OVERHEAD; - li r20,MSR_KERNEL; - bl transfer_to_handler; - .long do_IRQ; - .long ret_from_except /*********************************************************************** * Please note that on APUS the exception handlers are located at the @@ -1247,10 +1181,9 @@ __secondary_start_gemini: andc r4,r4,r3 mtspr HID0,r4 sync - bl prom_init + bl gemini_prom_init b __secondary_start #endif /* CONFIG_GEMINI */ - .globl __secondary_start_psurge __secondary_start_psurge: li r24,1 /* cpu # */ @@ -1310,7 +1243,6 @@ __secondary_start: mtspr SPRG3,r4 li r3,0 mtspr SPRG2,r3 /* 0 => r1 has kernel sp */ - stw r3,PT_REGS(r4) /* set thread.regs to 0 for kernel thread */ /* enable MMU and jump to start_secondary */ li r4,MSR_KERNEL @@ -1347,12 +1279,22 @@ _GLOBAL(__setup_cpu_7400) bl setup_750_7400_hid0 mtlr r4 blr +_GLOBAL(__setup_cpu_7410) + mflr r4 + bl setup_common_caches + bl setup_750_7400_hid0 + li r3,0 + mtspr SPRN_L2CR2,r3 + mtlr r4 + blr _GLOBAL(__setup_cpu_7450) + mflr r4 + bl setup_common_caches + bl setup_7450_hid0 + mtlr r4 blr _GLOBAL(__setup_cpu_power3) blr -_GLOBAL(__setup_cpu_power4) - blr _GLOBAL(__setup_cpu_generic) blr @@ -1407,6 +1349,47 @@ setup_750_7400_hid0: isync blr +/* 7450 + * Enable Store Gathering (SGE), Branch Folding (FOLD) + * Branch History Table (BHTE), Branch Target ICache (BTIC) + * Dynamic Power Management (DPM), Speculative (SPD) + * Ensure our data cache instructions really operate. + * Timebase has to be running or we wouldn't have made it here, + * just ensure we don't disable it. + * Clear Instruction cache throttling (ICTC) + */ +setup_7450_hid0: + /* We check for the presence of an L3 cache setup by + * the firmware. If any, we disable DOZE capability + */ + mfspr r11,SPRN_L3CR + andis. r11,r11,L3CR_L3E@h + beq 1f + li r7,CPU_FTR_CAN_DOZE + lwz r6,CPU_SPEC_FEATURES(r5) + andc r6,r6,r7 + stw r6,CPU_SPEC_FEATURES(r5) +1: + mfspr r11,HID0 + + /* All of the bits we have to set..... + */ + ori r11,r11,HID0_SGE | HID0_FOLD | HID0_BHTE | HID0_BTIC + oris r11,r11,HID0_DPM@h /* enable dynamic power mgmt */ + + /* All of the bits we have to clear.... + */ + li r3,HID0_SPD | HID0_NOPDST | HID0_NOPTI + andc r11,r11,r3 /* clear SPD: enable speculative */ + li r3,0 + + mtspr ICTC,r3 /* Instruction Cache Throttling off */ + isync + mtspr HID0,r11 + sync + isync + blr + /* * Load stuff into the MMU. Intended to be called with * IR=0 and DR=0. @@ -1417,7 +1400,7 @@ load_up_mmu: tophys(r6,r6) lwz r6,_SDR1@l(r6) mtspr SDR1,r6 -#ifdef CONFIG_PPC64BRIDGE +#ifdef CONFIG_PPC64BRIDGE /* clear the ASR so we only use the pseudo-segment registers. */ li r6,0 mtasr r6 @@ -1430,7 +1413,6 @@ load_up_mmu: addi r3,r3,0x111 /* increment VSID */ addis r4,r4,0x1000 /* address of next segment */ bdnz 3b -#ifndef CONFIG_POWER4 /* Load the BAT registers with the values set up by MMU_init. MMU_init takes care of whether we're on a 601 or not. */ mfpvr r3 @@ -1443,7 +1425,6 @@ load_up_mmu: LOAD_BAT(1,r3,r4,r5) LOAD_BAT(2,r3,r4,r5) LOAD_BAT(3,r3,r4,r5) -#endif /* CONFIG_POWER4 */ blr /* @@ -1519,6 +1500,19 @@ start_here: TLBSYNC /* ... on all CPUs */ bl load_up_mmu + + /* Add helper information for the Abatron bdiGDB debugger. + * We do this here because we know the mmu is disabled, and + * will be enabled for real in just a few instructions. + */ + lis r5, abatron_pteptrs@h + ori r5, r5, abatron_pteptrs@l + stw r5, 0xf0(r0) /* This much match your Abatron config */ + lis r6, swapper_pg_dir@h + ori r6, r6, swapper_pg_dir@l + tophys(r5, r5) + stw r6, 0(r5) + /* Now turn on the MMU for real! */ li r4,MSR_KERNEL FIX_SRR1(r4,r5) @@ -1538,6 +1532,15 @@ _GLOBAL(set_context) addis r3,r3,0x6000 /* Set Ks, Ku bits */ li r0,NUM_USER_SEGMENTS mtctr r0 + +#ifdef CONFIG_BDI_SWITCH + /* Context switch the PTE pointer for the Abatron BDI2000. + * The PGDIR is passed as second argument. + */ + lis r5, KERNELBASE@h + lwz r5, 0xf0(r5) + stw r4, 0x4(r5) +#endif li r4,0 3: #ifdef CONFIG_PPC64BRIDGE @@ -1561,22 +1564,21 @@ _GLOBAL(set_context) * -- Cort */ clear_bats: -#if !defined(CONFIG_GEMINI) li r20,0 mfspr r9,PVR rlwinm r9,r9,16,16,31 /* r9 = 1 for 601, 4 for 604 */ cmpwi r9, 1 beq 1f - + mtspr DBAT0U,r20 - mtspr DBAT0L,r20 + mtspr DBAT0L,r20 mtspr DBAT1U,r20 mtspr DBAT1L,r20 mtspr DBAT2U,r20 - mtspr DBAT2L,r20 + mtspr DBAT2L,r20 mtspr DBAT3U,r20 mtspr DBAT3L,r20 -1: +1: mtspr IBAT0U,r20 mtspr IBAT0L,r20 mtspr IBAT1U,r20 @@ -1585,10 +1587,8 @@ clear_bats: mtspr IBAT2L,r20 mtspr IBAT3U,r20 mtspr IBAT3L,r20 -#endif /* !defined(CONFIG_GEMINI) */ blr -#ifndef CONFIG_GEMINI flush_tlbs: lis r20, 0x40 1: addic. r20, r20, -0x1000 @@ -1607,9 +1607,7 @@ mmu_off: mtspr SRR1,r3 sync RFI -#endif -#ifndef CONFIG_POWER4 /* * Use the first pair of BAT registers to map the 1st 16MB * of RAM to KERNELBASE. From this point on we can't safely @@ -1645,7 +1643,7 @@ initial_bats: #else ori r11,r11,BL_256M<<2|0x2 /* set up BAT registers for 604 */ #endif /* CONFIG_APUS */ - + #ifdef CONFIG_PPC64BRIDGE /* clear out the high 32 bits in the BAT */ clrldi r11,r11,32 @@ -1682,7 +1680,6 @@ setup_disp_bat: blr #endif /* !defined(CONFIG_APUS) && defined(CONFIG_BOOTX_TEXT) */ -#endif /* CONFIG_POWER4 */ #ifdef CONFIG_8260 /* Jump into the system reset for the rom. @@ -1734,12 +1731,12 @@ empty_zero_page: .globl swapper_pg_dir swapper_pg_dir: - .space 4096 + .space 4096 /* * This space gets a copy of optional info passed to us by the bootstrap * Used to pass parameters into the kernel like root=/dev/sda1, etc. - */ + */ .globl cmd_line cmd_line: .space 512 @@ -1752,3 +1749,9 @@ intercept_table: .long 0, 0, 0, 0, 0, 0, 0, 0 .long 0, 0, 0, 0, 0, 0, 0, 0 .long 0, 0, 0, 0, 0, 0, 0, 0 + +/* Room for two PTE pointers, usually the kernel and current user pointers + * to their respective root page table. + */ +abatron_pteptrs: + .space 8 diff --git a/arch/ppc/kernel/head_4xx.S b/arch/ppc/kernel/head_4xx.S index 35e17f1df41c..39553b2363e4 100644 --- a/arch/ppc/kernel/head_4xx.S +++ b/arch/ppc/kernel/head_4xx.S @@ -1,7 +1,4 @@ /* - * BK Id: SCCS/s.head_4xx.S 1.6 05/21/01 11:50:00 paulus - */ -/* * Copyright (c) 1995-1996 Gary Thomas <gdt@linuxppc.org> * Initial PowerPC version. * Copyright (c) 1996 Cort Dougan <cort@cs.nmt.edu> @@ -14,6 +11,13 @@ * PowerPC 403GCX modifications. * Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu> * PowerPC 403GCX/405GP modifications. + * Copyright 2000 MontaVista Software Inc. + * PPC405 modifications + * PowerPC 403GCX/405GP modifications. + * Author: MontaVista Software, Inc. + * frank_rowand@mvista.com or source@mvista.com + * debbie_chu@mvista.com + * * * Module name: head_4xx.S * @@ -28,139 +32,91 @@ */ #include <linux/config.h> - #include <asm/processor.h> #include <asm/page.h> -#include <asm/pgtable.h> #include <asm/mmu.h> - -#include "ppc_asm.h" - +#include <asm/pgtable.h> +#include <asm/ibm4xx.h> +#include <asm/cputable.h> +#include <asm/ppc_asm.h> +#include "ppc_defs.h" /* Preprocessor Defines */ #define STND_EXC 0 #define CRIT_EXC 1 -### -### Check to make sure the right processor has been defined. -### - -#if !defined(CONFIG_4xx) -#error "This file is only appropriate for kernels supporting the PPC4xx." -#endif - -### -### Execution entry point. -### - -### -### As with the other PowerPC ports, it is expected that when code -### execution begins here, the following registers contain valid, yet -### optional, information: -### -### r3 - Board info structure pointer (DRAM, frequency, MAC address, etc.) -### r4 - Starting address of the init RAM disk -### r5 - Ending address of the init RAM disk -### r6 - Start of kernel command line string (e.g. "mem=96m") -### r7 - End of kernel command line string -### - +/* As with the other PowerPC ports, it is expected that when code + * execution begins here, the following registers contain valid, yet + * optional, information: + * + * r3 - Board info structure pointer (DRAM, frequency, MAC address, etc.) + * r4 - Starting address of the init RAM disk + * r5 - Ending address of the init RAM disk + * r6 - Start of kernel command line string (e.g. "mem=96m") + * r7 - End of kernel command line string + * + * This is all going to change RSN when we add bi_recs....... -- Dan + */ .text _GLOBAL(_stext) _GLOBAL(_start) - ## Save residual data, init RAM disk, and command line parameters - + + /* Save parameters we are passed. + */ mr r31,r3 mr r30,r4 mr r29,r5 mr r28,r6 mr r27,r7 + li r24,0 /* CPU number */ - ## Set the ID for this CPU - - li r24,0 - - ## Invalidate all TLB entries + /* We have to turn on the MMU right away so we get cache modes + * set correctly. + */ + bl initial_mmu - tlbia - - ## We should still be executing code at physical address 0x0000xxxx - ## at this point. However, start_here is at virtual address - ## 0xC000xxxx. So, set up a TLB mapping to cover this once - ## translation is enabled. - - lis r3,KERNELBASE@h # Load the kernel virtual address - ori r3,r3,KERNELBASE@l - tophys(r4,r3) # Load the kernel physical address - - ## Save the existing PID and load the kernel PID. - - mfspr r7,SPRN_PID # Save the old PID - li r0,0 - mtspr SPRN_PID,r0 # Load the kernel PID - - ## Configure and load entry into TLB slot 0. - - clrrwi r4,r4,10 # Mask off the real page number - ori r4,r4,(TLB_WR | TLB_EX) # Set the write and execute bits - - clrrwi r3,r3,10 # Mask off the effective page number - ori r3,r3,(TLB_VALID | TLB_PAGESZ(PAGESZ_16M)) - - tlbwe r4,r0,TLB_DATA # Load the data portion of the entry - tlbwe r3,r0,TLB_TAG # Load the tag portion of the entry - isync - - mtspr SPRN_PID,r7 # Restore the existing PID - - ## Establish the exception vector base - - lis r4,KERNELBASE@h # EVPR only uses the high 16-bits - tophys(r0,r4) # Use the physical address - mtspr SPRN_EVPR,r0 - - ## Enable the MMU and jump to the main PowerPC kernel start-up code - - mfmsr r0 # Get the machine state register - ori r0,r0,(MSR_DR | MSR_IR) # Enable data and instr. translation - mtspr SPRN_SRR1,r0 # Set up the new machine state register - lis r0,start_here@h - ori r0,r0,start_here@l - mtspr SPRN_SRR0,r0 # Set up the new instruction pointer - rfi # Jump to start_here w/ translation on - - -### -### Exception vector entry code. This code runs with address translation -### turned off (i.e. using physical addresses). We assume SPRG3 has the -### physical address of the current task thread_struct. -### - - ## Common exception code for all exception types. - -#define COMMON_PROLOG \ -0: mtspr SPRN_SPRG0,r20; /* We need r20, move it to SPRG0 */\ - mtspr SPRN_SPRG1,r21; /* We need r21, move it to SPRG1 */\ - mfcr r20; /* We need the CR, move it to r20 */\ - mfspr r21,SPRN_SPRG2; /* Exception stack to use */\ - cmpwi cr0,r21,0; /* From user mode or RTAS? */\ - bne 1f; /* Not RTAS, branch */\ - tophys(r21, r1); /* Convert vka in r1 to pka in r21 */\ - subi r21,r21,INT_FRAME_SIZE; /* Allocate an exception frame */\ -1: stw r20,_CCR(r21); /* Save CR on the stack */\ - stw r22,GPR22(r21); /* Save r22 on the stack */\ - stw r23,GPR23(r21); /* r23 Save on the stack */\ - mfspr r20,SPRN_SPRG0; /* Get r20 back out of SPRG0 */\ - stw r20,GPR20(r21); /* Save r20 on the stack */\ - mfspr r22,SPRN_SPRG1; /* Get r21 back out of SPRG0 */\ - stw r22,GPR21(r21); /* Save r21 on the stack */\ - mflr r20; \ - stw r20,_LINK(r21); /* Save LR on the stack */\ - mfctr r22; \ - stw r22,_CTR(r21); /* Save CTR on the stack */\ - mfspr r20,XER; \ - stw r20,_XER(r21); /* Save XER on the stack */ +/* We now have the lower 16 Meg mapped into TLB entries, and the caches + * ready to work. + */ +turn_on_mmu: + li r0,MSR_KERNEL + mtspr SRR1,r0 + lis r0,start_here@h + ori r0,r0,start_here@l + mtspr SRR0,r0 + SYNC + rfi /* enables MMU */ + +/* Exception vector entry code. This code runs with address translation + * turned off (i.e. using physical addresses). We assume SPRG3 has the + * physical address of the current task thread_struct. + */ + +#define COMMON_PROLOG(n) \ +0: mtspr SPRN_SPRG0,r20; /* We need r20, move it to SPRG0 */\ + mtspr SPRN_SPRG1,r21; /* We need r21, move it to SPRG1 */\ + mfcr r20; /* We need the CR, move it to r20 */\ + mfspr r21,SPRN_SPRG2; /* Exception stack to use */\ + cmpwi cr0,r21,0; /* From user mode or RTAS? */\ + bne 1f; /* Not RTAS, branch */\ + tophys(r21, r1); /* Convert vka in r1 to pka in r21 */\ + subi r21,r21,INT_FRAME_SIZE; /* Allocate an exception frame */\ +1: stw r20,_CCR(r21); /* Save CR on the stack */\ + stw r22,GPR22(r21); /* Save r22 on the stack */\ + stw r23,GPR23(r21); /* r23 Save on the stack */\ + mfspr r20,SPRN_SPRG0; /* Get r20 back out of SPRG0 */\ + stw r20,GPR20(r21); /* Save r20 on the stack */\ + mfspr r22,SPRN_SPRG1; /* Get r21 back out of SPRG0 */\ + stw r22,GPR21(r21); /* Save r21 on the stack */\ + mflr r20; \ + stw r20,_LINK(r21); /* Save LR on the stack */\ + mfctr r22; \ + stw r22,_CTR(r21); /* Save CTR on the stack */\ + mfspr r20,XER; \ + stw r20,_XER(r21); /* Save XER on the stack */\ + mfspr r20,SPRN_DBCR0; \ + stw r20,_DBCR0(r21); /* Save Debug Control on the stack */ #define COMMON_EPILOG \ stw r0,GPR0(r21); /* Save r0 on the stack */\ @@ -171,25 +127,22 @@ _GLOBAL(_start) SAVE_4GPRS(3, r21); /* Save r3 through r6 on the stack */\ SAVE_GPR(7, r21); /* Save r7 on the stack */ - ## Common exception code for standard (non-critical) exceptions. - -#define STND_EXCEPTION_PROLOG \ - COMMON_PROLOG; \ +#define STND_EXCEPTION_PROLOG(n) \ + COMMON_PROLOG(n); \ mfspr r22,SPRN_SRR0; /* Faulting instruction address */\ + lis r20,MSR_WE@h; \ mfspr r23,SPRN_SRR1; /* MSR at the time of fault */\ + andc r23,r23,r20; /* disable processor wait state */\ COMMON_EPILOG; - ## Common exception code for critical exceptions. - -#define CRIT_EXCEPTION_PROLOG \ - COMMON_PROLOG; \ +#define CRIT_EXCEPTION_PROLOG(n) \ + COMMON_PROLOG(n); \ mfspr r22,SPRN_SRR2; /* Faulting instruction address */\ + lis r20,MSR_WE@h; \ mfspr r23,SPRN_SRR3; /* MSR at the time of fault */\ + andc r23,r23,r20; /* disable processor wait state */\ COMMON_EPILOG; -### -### Macros for specific exception types -### #define START_EXCEPTION(n, label) \ . = n; \ @@ -200,68 +153,213 @@ label: bl transfer_to_handler; \ .long func; \ .long ret_from_except - - + + #define STND_EXCEPTION(n, label, func) \ START_EXCEPTION(n, label); \ - STND_EXCEPTION_PROLOG; \ + STND_EXCEPTION_PROLOG(n); \ addi r3,r1,STACK_FRAME_OVERHEAD; \ li r7,STND_EXC; \ li r20,MSR_KERNEL; \ FINISH_EXCEPTION(func) - + #define CRIT_EXCEPTION(n, label, func) \ START_EXCEPTION(n, label); \ - CRIT_EXCEPTION_PROLOG; \ + CRIT_EXCEPTION_PROLOG(n); \ addi r3,r1,STACK_FRAME_OVERHEAD; \ li r7,CRIT_EXC; \ li r20,MSR_KERNEL; \ FINISH_EXCEPTION(func) - -### -### Exception vectors. -### - -### 0x0100 - Critical Interrupt Exception +/* Exception vectors. +*/ + +/* 0x0100 - Critical Interrupt Exception +*/ CRIT_EXCEPTION(0x0100, CriticalInterrupt, UnknownException) -### 0x0200 - Machine Check Exception - +/* 0x0200 - Machine Check Exception +*/ +#if 0 CRIT_EXCEPTION(0x0200, MachineCheck, MachineCheckException) +#else + START_EXCEPTION(0x0200, MachineCheck) + CRIT_EXCEPTION_PROLOG(0x0200) + + /* + lis r4,0x0400 + mtdcr DCRN_POB0_BESR0,r4 + */ +#ifdef DCRN_POB0_BEAR + mfdcr r4,DCRN_POB0_BEAR + mfdcr r4,DCRN_POB0_BESR0 + mfdcr r4,DCRN_POB0_BESR1 +#endif -### 0x0300 - Data Storage Exception +#ifdef DCRN_PLB0_BEAR + mfdcr r4,DCRN_PLB0_ACR + mfdcr r4,DCRN_PLB0_BEAR + mfdcr r4,DCRN_PLB0_BESR +#endif - START_EXCEPTION(0x0300, DataAccess) - STND_EXCEPTION_PROLOG - mfspr r5,SPRN_ESR # Grab the ESR, save it, pass as arg3 - stw r5,_ESR(r21) - mfspr r4,SPRN_DEAR # Grab the DEAR, save it, pass as arg2 - stw r4,_DEAR(r21) addi r3,r1,STACK_FRAME_OVERHEAD - li r7,STND_EXC # This is a standard exception + li r7,CRIT_EXC li r20,MSR_KERNEL - rlwimi r20,r23,0,16,16 # Copy EE bit from the saved MSR - FINISH_EXCEPTION(do_page_fault) # do_page_fault(regs, ESR, DEAR) - -### 0x0400 - Instruction Storage Exception + FINISH_EXCEPTION(MachineCheckException) +#endif + +/* 0x0300 - Data Storage Exception + * This happens for just a few reasons. U0 set (but we don't do that), + * or zone protection fault (user violation, write to protected page). + * If this is just an update of modified status, we do that quickly + * and exit. Otherwise, we call heavywight functions to do the work. + */ + START_EXCEPTION(0x0300, DataStore) + mtspr SPRG0, r20 /* Save some working registers */ + mtspr SPRG1, r21 +#ifdef CONFIG_403GCX + stw r22, 0(r0) + stw r23, 4(r0) + mfcr r21 + mfspr r22, SPRN_PID + stw r21, 8(r0) + stw r22, 12(r0) +#else + mtspr SPRG4, r22 + mtspr SPRG5, r23 + mfcr r21 + mfspr r22, SPRN_PID + mtspr SPRG7, r21 + mtspr SPRG6, r22 +#endif + + /* First, check if it was a zone fault (which means a user + * tried to access a kernel or read-protected page - always + * a SEGV). All other faults here must be stores, so no + * need to check ESR_DST as well. */ + mfspr r20, SPRN_ESR + andis. r20, r20, ESR_DIZ@h + bne 2f + + mfspr r20, SPRN_DEAR /* Get faulting address */ + + /* If we are faulting a kernel address, we have to use the + * kernel page tables. + */ + andis. r21, r20, 0x8000 + beq 3f + lis r21, swapper_pg_dir@h + ori r21, r21, swapper_pg_dir@l + li r23, 0 + mtspr SPRN_PID, r23 /* TLB will have 0 TID */ + b 4f + + /* Get the PGD for the current thread. + */ +3: + mfspr r21,SPRG3 + lwz r21,PGDIR(r21) +4: + tophys(r21, r21) + rlwimi r21, r20, 12, 20, 29 /* Create L1 (pgdir/pmd) address */ + lwz r21, 0(r21) /* Get L1 entry */ + rlwinm. r22, r21, 0, 0, 19 /* Extract L2 (pte) base address */ + beq 2f /* Bail if no table */ + + tophys(r22, r22) + rlwimi r22, r20, 22, 20, 29 /* Compute PTE address */ + lwz r21, 0(r22) /* Get Linux PTE */ + + andi. r23, r21, _PAGE_RW /* Is it writeable? */ + beq 2f /* Bail if not */ + + /* Update 'changed'. + */ + ori r21, r21, _PAGE_DIRTY|_PAGE_ACCESSED|_PAGE_HWWRITE + stw r21, 0(r22) /* Update Linux page table */ + + /* Most of the Linux PTE is ready to load into the TLB LO. + * We set ZSEL, where only the LS-bit determines user access. + * We set execute, because we don't have the granularity to + * properly set this at the page level (Linux problem). + * If shared is set, we cause a zero PID->TID load. + * Many of these bits are software only. Bits we don't set + * here we (properly should) assume have the appropriate value. + */ + li r22, 0x0ce2 + andc r21, r21, r22 /* Make sure 20, 21 are zero */ + + /* find the TLB index that caused the fault. It has to be here. + */ + tlbsx r23, 0, r20 + + tlbwe r21, r23, TLB_DATA /* Load TLB LO */ + + /* Done...restore registers and get out of here. + */ +#ifdef CONFIG_403GCX + lwz r22, 12(r0) + lwz r21, 8(r0) + mtspr SPRN_PID, r22 + mtcr r21 + lwz r23, 4(r0) + lwz r22, 0(r0) +#else + mfspr r22, SPRG6 + mfspr r21, SPRG7 + mtspr SPRN_PID, r22 + mtcr r21 + mfspr r23, SPRG5 + mfspr r22, SPRG4 +#endif + mfspr r21, SPRG1 + mfspr r20, SPRG0 + PPC405_ERR77_SYNC + rfi /* Should sync shadow TLBs */ + +2: + /* The bailout. Restore registers to pre-exception conditions + * and call the heavyweights to help us out. + */ +#ifdef CONFIG_403GCX + lwz r22, 12(r0) + lwz r21, 8(r0) + mtspr SPRN_PID, r22 + mtcr r21 + lwz r23, 4(r0) + lwz r22, 0(r0) +#else + mfspr r22, SPRG6 + mfspr r21, SPRG7 + mtspr SPRN_PID, r22 + mtcr r21 + mfspr r23, SPRG5 + mfspr r22, SPRG4 +#endif + mfspr r21, SPRG1 + mfspr r20, SPRG0 + b DataAccess +/* 0x0400 - Instruction Storage Exception + * I don't know why it is called "Storage"....This is caused by a fetch + * from non-execute or guarded pages. + */ START_EXCEPTION(0x0400, InstructionAccess) - STND_EXCEPTION_PROLOG - mr r4,r22 # Pass SRR0 as arg2 - mr r5,r23 # Pass SRR1 as arg3 + STND_EXCEPTION_PROLOG(0x0400) + mr r4,r22 /* Pass SRR0 as arg2 */ + li r5,0 /* Pass zero as arg3 */ addi r3,r1,STACK_FRAME_OVERHEAD - li r7,STND_EXC # This is a standard exception + li r7,STND_EXC li r20,MSR_KERNEL - rlwimi r20,r23,0,16,16 # Copy EE bit from the saved MSR - FINISH_EXCEPTION(do_page_fault) # do_page_fault(regs, SRR0, SRR1) - -### 0x0500 - External Interrupt Exception + rlwimi r20,r23,0,16,16 /* Copy EE bit from the saved MSR */ + FINISH_EXCEPTION(do_page_fault) /* do_page_fault(regs, SRR0, SRR1) */ +/* 0x0500 - External Interrupt Exception +*/ START_EXCEPTION(0x0500, HardwareInterrupt) - STND_EXCEPTION_PROLOG + STND_EXCEPTION_PROLOG(0x0500) addi r3,r1,STACK_FRAME_OVERHEAD li r7,STND_EXC li r20,MSR_KERNEL @@ -271,54 +369,70 @@ _GLOBAL(do_IRQ_intercept) .long do_IRQ .long ret_from_intercept -### 0x0600 - Alignment Exception - +/* 0x0600 - Alignment Exception +*/ START_EXCEPTION(0x0600, Alignment) - STND_EXCEPTION_PROLOG - mfspr r4,SPRN_DEAR # Grab the DEAR and save it + STND_EXCEPTION_PROLOG(0x0600) + mfspr r4,SPRN_DEAR /* Grab the DEAR and save it */ stw r4,_DEAR(r21) addi r3,r1,STACK_FRAME_OVERHEAD - li r7,STND_EXC # This is a standard exception + li r7,STND_EXC li r20,MSR_KERNEL - rlwimi r20,r23,0,16,16 # Copy EE bit from the saved MSR + rlwimi r20,r23,0,16,16 /* Copy EE bit from the saved MSR */ FINISH_EXCEPTION(AlignmentException) -### 0x0700 - Program Exception - +/* 0x0700 - Program Exception +*/ START_EXCEPTION(0x0700, ProgramCheck) - STND_EXCEPTION_PROLOG + STND_EXCEPTION_PROLOG(0x0700) addi r3,r1,STACK_FRAME_OVERHEAD - li r7,STND_EXC # This is a standard exception + li r7,STND_EXC li r20,MSR_KERNEL - rlwimi r20,r23,0,16,16 # Copy EE bit from the saved MSR + rlwimi r20,r23,0,16,16 /* Copy EE bit from the saved MSR */ FINISH_EXCEPTION(ProgramCheckException) - - STND_EXCEPTION(0x0800, Trap_08, UnknownException) + + +/* I'm stealing this unused vector location to build a standard exception + * frame for Data TLB Access errors. The other Data TLB exceptions will bail + * out to this point if they can't resolve the lightweight TLB fault. + */ + START_EXCEPTION(0x0800, DataAccess) + STND_EXCEPTION_PROLOG(0x0800) + mfspr r5,SPRN_ESR /* Grab the ESR, save it, pass arg3 */ + stw r5,_ESR(r21) + mfspr r4,SPRN_DEAR /* Grab the DEAR, save it, pass arg2 */ + stw r4,_DEAR(r21) + addi r3,r1,STACK_FRAME_OVERHEAD + li r7,STND_EXC + li r20,MSR_KERNEL + rlwimi r20,r23,0,16,16 /* Copy EE bit from the saved MSR */ + FINISH_EXCEPTION(do_page_fault) /* do_page_fault(regs, ESR, DEAR) */ + STND_EXCEPTION(0x0900, Trap_09, UnknownException) STND_EXCEPTION(0x0A00, Trap_0A, UnknownException) - STND_EXCEPTION(0x0B00, Trap_0B, UnknownException) -### 0x0C00 - System Call Exception - + STND_EXCEPTION(0x0B00, Trap_0B, UnknownException) +/* 0x0C00 - System Call Exception +*/ START_EXCEPTION(0x0C00, SystemCall) - STND_EXCEPTION_PROLOG + STND_EXCEPTION_PROLOG(0x0C00) stw r3,ORIG_GPR3(r21) - li r7,STND_EXC # This is a standard exception + li r7,STND_EXC li r20,MSR_KERNEL - rlwimi r20,r23,0,16,16 # Copy EE bit from the saved MSR + rlwimi r20,r23,0,16,16 /* Copy EE bit from the saved MSR */ FINISH_EXCEPTION(DoSyscall) STND_EXCEPTION(0x0D00, Trap_0D, UnknownException) STND_EXCEPTION(0x0E00, Trap_0E, UnknownException) STND_EXCEPTION(0x0F00, Trap_0F, UnknownException) -### 0x1000 - Programmable Interval Timer (PIT) Exception - +/* 0x1000 - Programmable Interval Timer (PIT) Exception +*/ START_EXCEPTION(0x1000, Decrementer) - STND_EXCEPTION_PROLOG - lis r0,TSR_PIS@h # Set-up the PIT exception mask - mtspr SPRN_TSR,r0 # Clear the PIT exception + STND_EXCEPTION_PROLOG(0x1000) + lis r0,TSR_PIS@h /* Set-up the PIT exception mask */ + mtspr SPRN_TSR,r0 /* Clear the PIT exception */ addi r3,r1,STACK_FRAME_OVERHEAD - li r7,STND_EXC # This is a standard exception + li r7,STND_EXC li r20,MSR_KERNEL bl transfer_to_handler _GLOBAL(timer_interrupt_intercept) @@ -326,28 +440,239 @@ _GLOBAL(timer_interrupt_intercept) .long ret_from_intercept #if 0 -### 0x1010 - Fixed Interval Timer (FIT) Exception - +/* NOTE: + * FIT and WDT handlers are not implemented yet. + */ + +/* 0x1010 - Fixed Interval Timer (FIT) Exception +*/ STND_EXCEPTION(0x1010, FITException, UnknownException) -### 0x1020 - Watchdog Timer (WDT) Exception +/* 0x1020 - Watchdog Timer (WDT) Exception +*/ CRIT_EXCEPTION(0x1020, WDTException, UnknownException) #endif -### 0x1100 - Data TLB Miss Exception +/* 0x1100 - Data TLB Miss Exception + * As the name implies, translation is not in the MMU, so search the + * page tables and fix it. The only purpose of this function is to + * load TLB entries from the page table if they exist. + */ + START_EXCEPTION(0x1100, DTLBMiss) + mtspr SPRG0, r20 /* Save some working registers */ + mtspr SPRG1, r21 +#ifdef CONFIG_403GCX + stw r22, 0(r0) + stw r23, 4(r0) + mfcr r21 + mfspr r22, SPRN_PID + stw r21, 8(r0) + stw r22, 12(r0) +#else + mtspr SPRG4, r22 + mtspr SPRG5, r23 + mfcr r21 + mfspr r22, SPRN_PID + mtspr SPRG7, r21 + mtspr SPRG6, r22 +#endif + mfspr r20, SPRN_DEAR /* Get faulting address */ + + /* If we are faulting a kernel address, we have to use the + * kernel page tables. + */ + andis. r21, r20, 0x8000 + beq 3f + lis r21, swapper_pg_dir@h + ori r21, r21, swapper_pg_dir@l + li r23, 0 + mtspr SPRN_PID, r23 /* TLB will have 0 TID */ + b 4f + + /* Get the PGD for the current thread. + */ +3: + mfspr r21,SPRG3 + lwz r21,PGDIR(r21) +4: + tophys(r21, r21) + rlwimi r21, r20, 12, 20, 29 /* Create L1 (pgdir/pmd) address */ + lwz r21, 0(r21) /* Get L1 entry */ + rlwinm. r22, r21, 0, 0, 19 /* Extract L2 (pte) base address */ + beq 2f /* Bail if no table */ + + tophys(r22, r22) + rlwimi r22, r20, 22, 20, 29 /* Compute PTE address */ + lwz r21, 0(r22) /* Get Linux PTE */ + andi. r23, r21, _PAGE_PRESENT + beq 2f - STND_EXCEPTION(0x1100, DTLBMiss, PPC4xx_dtlb_miss) + ori r21, r21, _PAGE_ACCESSED + stw r21, 0(r22) + + /* Most of the Linux PTE is ready to load into the TLB LO. + * We set ZSEL, where only the LS-bit determines user access. + * We set execute, because we don't have the granularity to + * properly set this at the page level (Linux problem). + * If shared is set, we cause a zero PID->TID load. + * Many of these bits are software only. Bits we don't set + * here we (properly should) assume have the appropriate value. + */ + li r22, 0x0ce2 + andc r21, r21, r22 /* Make sure 20, 21 are zero */ + + b finish_tlb_load + + +2: + /* The bailout. Restore registers to pre-exception conditions + * and call the heavyweights to help us out. + */ +#ifdef CONFIG_403GCX + lwz r22, 12(r0) + lwz r21, 8(r0) + mtspr SPRN_PID, r22 + mtcr r21 + lwz r23, 4(r0) + lwz r22, 0(r0) +#else + mfspr r22, SPRG6 + mfspr r21, SPRG7 + mtspr SPRN_PID, r22 + mtcr r21 + mfspr r23, SPRG5 + mfspr r22, SPRG4 +#endif + mfspr r21, SPRG1 + mfspr r20, SPRG0 + b DataAccess -### 0x1200 - Instruction TLB Miss Exception +/* 0x1200 - Instruction TLB Miss Exception + * Nearly the same as above, except we get our information from different + * registers and bailout to a different point. + */ + START_EXCEPTION(0x1200, ITLBMiss) + mtspr SPRG0, r20 /* Save some working registers */ + mtspr SPRG1, r21 +#ifdef CONFIG_403GCX + stw r22, 0(r0) + stw r23, 4(r0) + mfcr r21 + mfspr r22, SPRN_PID + stw r21, 8(r0) + stw r22, 12(r0) +#else + mtspr SPRG4, r22 + mtspr SPRG5, r23 + mfcr r21 + mfspr r22, SPRN_PID + mtspr SPRG7, r21 + mtspr SPRG6, r22 +#endif + mfspr r20, SRR0 /* Get faulting address */ + + /* If we are faulting a kernel address, we have to use the + * kernel page tables. + */ + andis. r21, r20, 0x8000 + beq 3f + lis r21, swapper_pg_dir@h + ori r21, r21, swapper_pg_dir@l + li r23, 0 + mtspr SPRN_PID, r23 /* TLB will have 0 TID */ + b 4f + + /* Get the PGD for the current thread. + */ +3: + mfspr r21,SPRG3 + lwz r21,PGDIR(r21) +4: + tophys(r21, r21) + rlwimi r21, r20, 12, 20, 29 /* Create L1 (pgdir/pmd) address */ + lwz r21, 0(r21) /* Get L1 entry */ + rlwinm. r22, r21, 0, 0, 19 /* Extract L2 (pte) base address */ + beq 2f /* Bail if no table */ + + tophys(r22, r22) + rlwimi r22, r20, 22, 20, 29 /* Compute PTE address */ + lwz r21, 0(r22) /* Get Linux PTE */ + andi. r23, r21, _PAGE_PRESENT + beq 2f - STND_EXCEPTION(0x1200, ITLBMiss, PPC4xx_itlb_miss) + ori r21, r21, _PAGE_ACCESSED + stw r21, 0(r22) + + /* Most of the Linux PTE is ready to load into the TLB LO. + * We set ZSEL, where only the LS-bit determines user access. + * We set execute, because we don't have the granularity to + * properly set this at the page level (Linux problem). + * If shared is set, we cause a zero PID->TID load. + * Many of these bits are software only. Bits we don't set + * here we (properly should) assume have the appropriate value. + */ + li r22, 0x0ce2 + andc r21, r21, r22 /* Make sure 20, 21 are zero */ + + b finish_tlb_load + + /* Done...restore registers and get out of here. + */ +#ifdef CONFIG_403GCX + lwz r22, 12(r0) + lwz r21, 8(r0) + mtspr SPRN_PID, r22 + mtcr r21 + lwz r23, 4(r0) + lwz r22, 0(r0) +#else + mfspr r22, SPRG6 + mfspr r21, SPRG7 + mtspr SPRN_PID, r22 + mtcr r21 + mfspr r23, SPRG5 + mfspr r22, SPRG4 +#endif + mfspr r21, SPRG1 + mfspr r20, SPRG0 + PPC405_ERR77_SYNC + rfi /* Should sync shadow TLBs */ + +2: + /* The bailout. Restore registers to pre-exception conditions + * and call the heavyweights to help us out. + */ +#ifdef CONFIG_403GCX + lwz r22, 12(r0) + lwz r21, 8(r0) + mtspr SPRN_PID, r22 + mtcr r21 + lwz r23, 4(r0) + lwz r22, 0(r0) +#else + mfspr r22, SPRG6 + mfspr r21, SPRG7 + mtspr SPRN_PID, r22 + mtcr r21 + mfspr r23, SPRG5 + mfspr r22, SPRG4 +#endif + mfspr r21, SPRG1 + mfspr r20, SPRG0 + b InstructionAccess STND_EXCEPTION(0x1300, Trap_13, UnknownException) STND_EXCEPTION(0x1400, Trap_14, UnknownException) STND_EXCEPTION(0x1500, Trap_15, UnknownException) STND_EXCEPTION(0x1600, Trap_16, UnknownException) +#ifdef CONFIG_IBM405_ERR51 + /* 405GP errata 51 */ + START_EXCEPTION(0x1700, Trap_17) + b DTLBMiss +#else STND_EXCEPTION(0x1700, Trap_17, UnknownException) +#endif STND_EXCEPTION(0x1800, Trap_18, UnknownException) STND_EXCEPTION(0x1900, Trap_19, UnknownException) STND_EXCEPTION(0x1A00, Trap_1A, UnknownException) @@ -356,73 +681,217 @@ _GLOBAL(timer_interrupt_intercept) STND_EXCEPTION(0x1D00, Trap_1D, UnknownException) STND_EXCEPTION(0x1E00, Trap_1E, UnknownException) STND_EXCEPTION(0x1F00, Trap_1F, UnknownException) - -### 0x2000 - Debug Exception - - CRIT_EXCEPTION(0x2000, DebugTrap, UnknownException) -### -### Other PowerPC processors, namely those derived from the 6xx-series -### have vectors from 0x2100 through 0x2F00 defined, but marked as reserved. -### However, for the 4xx-series processors these are neither defined nor -### reserved. -### +/* 0x2000 - Debug Exception +*/ + START_EXCEPTION(0x2000, DebugTrap) + b check_single_step_in_exception +ret_to_debug_exception: + CRIT_EXCEPTION_PROLOG(0x2000) + addi r3,r1,STACK_FRAME_OVERHEAD + li r7,CRIT_EXC; + li r20,MSR_KERNEL + FINISH_EXCEPTION(DebugException) -### -### This code finishes saving the registers to the exception frame -### and jumps to the appropriate handler for the exception, turning -### on address translation. -### +/* Make sure the final interrupt handler has not spilled past the + * end of its allotted space. + */ + .=0x2100 +/* Check for a single step debug exception while in an exception + * handler before state has been saved. This is to catch the case + * where an instruction that we are trying to single step causes + * an exception (eg ITLB miss) and thus the first instruction of + * the exception handler generates a single step debug exception. + * + * If we get a debug trap on the first instruction of an exception handler, + * we reset the MSR_DE in the _exception handlers_ MSR (the debug trap is + * a critical exception, so we are using SPRN_SRR3 to manipulate the MSR). + * The exception handler was handling a non-critical interrupt, so it will + * save (and later restore) the MSR via SPRN_SRR1, which will still have + * the MSR_DE bit set. + */ +check_single_step_in_exception: + + /* This first instruction was already executed by the exception + * handler and must be the first instruction of every exception + * handler. + */ + mtspr SPRN_SPRG0,r20 /* Save some working registers... */ + mtspr SPRN_SPRG1,r21 + mfcr r20 /* ..and the cr because we change it */ + + mfspr r21,SPRN_SRR3 /* MSR at the time of fault */ + andi. r21,r21,MSR_PR + bne+ 2f /* trapped from problem state */ + + mfspr r21,SPRN_SRR2 /* Faulting instruction address */ + cmplwi r21,0x2100 + bgt+ 2f /* address above exception vectors */ + + lis r21,DBSR_IC@h /* Remove the trap status */ + mtspr SPRN_DBSR,r21 + + mfspr r21,SPRN_SRR3 + rlwinm r21,r21,0,23,21 /* clear MSR_DE */ + mtspr SPRN_SRR3, r21 /* restore MSR at rcfi without DE */ + + mtcrf 0xff,r20 /* restore registers */ + mfspr r21,SPRN_SPRG1 + mfspr r20,SPRN_SPRG0 + + sync + rfci /* return to the exception handler */ + +2: + mtcrf 0xff,r20 /* restore registers */ + mfspr r21,SPRN_SPRG1 + mfspr r20,SPRN_SPRG0 + b ret_to_debug_exception + +/* Other PowerPC processors, namely those derived from the 6xx-series + * have vectors from 0x2100 through 0x2F00 defined, but marked as reserved. + * However, for the 4xx-series processors these are neither defined nor + * reserved. + */ + + /* Damn, I came up one instruction too many to fit into the + * exception space :-). Both the instruction and data TLB + * miss get to this point to load the TLB. + * r20 - EA of fault + * r21 - TLB LO (info from Linux PTE) + * r22, r23 - avilable to use + * PID - loaded with proper value when we get here + * Upon exit, we reload everything and RFI. + * Actually, it will fit now, but oh well.....a common place + * to load the TLB. + */ +finish_tlb_load: + + /* Since it has a unified TLB, and we can take data faults on + * instruction pages by copying data, we have to check if the + * EPN is already in the TLB. + */ + tlbsx. r23, 0, r20 + beq 6f + + /* load the next available TLB index. + */ + lis r22, tlb_4xx_index@h + ori r22, r22, tlb_4xx_index@l + tophys(r22, r22) + lwz r23, 0(r22) + addi r23, r23, 1 +#ifdef CONFIG_PIN_TLB + cmpwi 0, r23, 61 /* reserve entries 62, 63 for kernel */ + ble 7f + li r23, 0 +7: +#else + andi. r23, r23, (PPC4XX_TLB_SIZE-1) +#endif + stw r23, 0(r22) + +6: + tlbwe r21, r23, TLB_DATA /* Load TLB LO */ + + /* Create EPN. This is the faulting address plus a static + * set of bits. These are size, valid, E, U0, and ensure + * bits 20 and 21 are zero. + */ + li r22, 0x00c0 + rlwimi r20, r22, 0, 20, 31 + tlbwe r20, r23, TLB_TAG /* Load TLB HI */ + + /* Done...restore registers and get out of here. + */ +#ifdef CONFIG_403GCX + lwz r22, 12(r0) + lwz r21, 8(r0) + mtspr SPRN_PID, r22 + mtcr r21 + lwz r23, 4(r0) + lwz r22, 0(r0) +#else + mfspr r22, SPRG6 + mfspr r21, SPRG7 + mtspr SPRN_PID, r22 + mtcr r21 + mfspr r23, SPRG5 + mfspr r22, SPRG4 +#endif + mfspr r21, SPRG1 + mfspr r20, SPRG0 + PPC405_ERR77_SYNC + rfi /* Should sync shadow TLBs */ + +/* This code finishes saving the registers to the exception frame + * and jumps to the appropriate handler for the exception, turning + * on address translation. + */ _GLOBAL(transfer_to_handler) - stw r22,_NIP(r21) # Save the faulting IP on the stack - stw r23,_MSR(r21) # Save the exception MSR on the stack - SAVE_4GPRS(8, r21) # Save r8 through r11 on the stack - SAVE_8GPRS(12, r21) # Save r12 through r19 on the stack - SAVE_8GPRS(24, r21) # Save r24 through r31 on the stack - andi. r23,r23,MSR_PR # Is this from user space? - mfspr r23,SPRN_SPRG3 # If from user, fix up THREAD.regs - beq 2f # No, it is from the kernel; branch. + stw r22,_NIP(r21) /* Save the faulting IP on the stack */ + stw r23,_MSR(r21) /* Save the exception MSR on stack */ + SAVE_4GPRS(8, r21) /* Save r8 through r11 on the stack */ + SAVE_8GPRS(12, r21) /* Save r12 through r19 on the stack */ + SAVE_8GPRS(24, r21) /* Save r24 through r31 on the stack */ + andi. r23,r23,MSR_PR /* Is this from user space? */ + mfspr r23,SPRN_SPRG3 /* If from user, fix up THREAD.regs */ + beq 2f /* No, it is from the kernel; branch. */ addi r24,r1,STACK_FRAME_OVERHEAD - stw r24,PT_REGS(r23) # -2: addi r2,r23,-THREAD # Set r2 to current thread + stw r24,PT_REGS(r23) +2: addi r2,r23,-THREAD /* Set r2 to current thread */ tovirt(r2,r2) mflr r23 - andi. r24,r23,0x3f00 # Get vector offset + andi. r24,r23,0x3f00 /* Get vector offset */ stw r24,TRAP(r21) + li r22,RESULT + /* No need to put an erratum #77 workaround here + because interrupts are currently disabled */ + stwcx. r22,r22,r21 /* Clear the reservation */ li r22,0 stw r22,RESULT(r21) - mtspr SPRN_SPRG2,r22 # r1 is now the kernel stack pointer - addi r24,r2,TASK_STRUCT_SIZE # Check for kernel stack overflow + mtspr SPRN_SPRG2,r22 /* r1 is now the kernel stack pointer */ + addi r24,r2,TASK_STRUCT_SIZE /* Check for kernel stack overflow */ cmplw cr0,r1,r2 cmplw cr1,r1,r24 crand cr1,cr1,cr4 - bgt- stack_ovf # If r2 < r1 < r2 + TASK_STRUCT_SIZE - lwz r24,0(r23) # Virtual address of the handler - lwz r23,4(r23) # Handler return pointer - cmpwi cr0,r7,STND_EXC # What type of exception is this? - bne 3f # It is a critical exception... - - ## Standard exception jump path - - mtspr SPRN_SRR0,r24 # Set up the instruction pointer - mtspr SPRN_SRR1,r20 # Set up the machine state register - mtlr r23 # Set up the return pointer + bgt- stack_ovf /* If r2 < r1 < r2 + TASK_STRUCT_SIZE */ + lwz r24,0(r23) /* Virtual address of the handler */ + lwz r23,4(r23) /* Handler return pointer */ + cmpwi cr0,r7,STND_EXC /* What type of exception is this? */ + bne 3f /* It is a critical exception... */ + + /* Standard exception jump path + */ + + /* We have to recover r7 from the register save stack. + * It was used to indicate standard/critical exception. In + * the case of a standard exception that is the system call + * trap, it may have originally contained one of the syscall + * parameters and we have to get it back now. + */ + lwz r7,GPR7(r21) + mtspr SPRN_SRR0,r24 /* Set up the instruction pointer */ + mtspr SPRN_SRR1,r20 /* Set up the machine state register */ + mtlr r23 /* Set up the return pointer */ SYNC - rfi # Enable the MMU, jump to the handler + /* We shouldn't need a 405 erratum #77 workaround here, because we're not + * actually returning to the interrupted instruction yet. */ + rfi - ## Critical exception jump path + /* Critical exception jump path + */ -3: mtspr SPRN_SRR2,r24 # Set up the instruction pointer - mtspr SPRN_SRR3,r20 # Set up the machine state register - mtlr r23 # Set up the return pointer +3: mtspr SPRN_SRR2,r24 /* Set up the instruction pointer */ + mtspr SPRN_SRR3,r20 /* Set up the machine state register */ + mtlr r23 /* Set up the return pointer */ SYNC - rfci # Enable the MMU, jump to the handler + rfci -### -### On kernel stack overlow, load up an initial stack pointer and call -### StackOverflow(regs), which should NOT return. -### +/* On kernel stack overlow, load up an initial stack pointer and call + * StackOverflow(regs), which should NOT return. + */ stack_ovf: addi r3,r1,STACK_FRAME_OVERHEAD @@ -432,143 +901,198 @@ stack_ovf: lis r24,StackOverflow@ha addi r24,r24,StackOverflow@l li r20,MSR_KERNEL - mtspr SPRN_SRR0,r24 # Set up the instruction pointer - mtspr SPRN_SRR1,r20 # Set up the machine state register + mtspr SPRN_SRR0,r24 + mtspr SPRN_SRR1,r20 SYNC - rfi # Enable the MMU, jump to StackOverflow - -### -### extern void giveup_altivec(struct task_struct *prev) -### -### The PowerPC 4xx family of processors do not have AltiVec capabilities, so -### this just returns. -### + rfi +/* extern void giveup_altivec(struct task_struct *prev) + * + * The PowerPC 4xx family of processors do not have AltiVec capabilities, so + * this just returns. + */ _GLOBAL(giveup_altivec) blr - -### -### extern void giveup_fpu(struct task_struct *prev) -### -### The PowerPC 4xx family of processors do not have an FPU, so this just -### returns. -### +/* extern void giveup_fpu(struct task_struct *prev) + * + * The PowerPC 4xx family of processors do not have an FPU, so this just + * returns. + */ _GLOBAL(giveup_fpu) blr -### -### extern void abort(void) -### -### At present, this routine just applies a system reset. -### - +/* extern void abort(void) + * + * At present, this routine just applies a system reset. + */ _GLOBAL(abort) - mfspr r13,SPRN_DBCR - oris r13,r13,DBCR_RST(DBCR_RST_SYSTEM)@h - mtspr SPRN_DBCR,r13 - + mfspr r13,SPRN_DBCR0 + oris r13,r13,DBCR_RST(DBCR_RST_SYSTEM)@h + mtspr SPRN_DBCR0,r13 -### -### This is where the main kernel code starts. -### +/* This is where the main kernel code starts. + */ start_here: - ## Establish a pointer to the current task - + + /* ptr to current */ lis r2,init_task_union@h ori r2,r2,init_task_union@l - - ## Clear out the BSS as per ANSI C requirements - - lis r7,_end@ha - addi r7,r7,_end@l - lis r8,__bss_start@ha - addi r8,r8,__bss_start@l - subf r7,r8,r7 - addi r7,r7,3 - srwi. r7,r7,2 - beq 2f - addi r8,r8,-4 - mtctr r7 - li r0,0 -3: stwu r0,4(r8) - bdnz 3b - ## Stack - -2: addi r1,r2,TASK_UNION_SIZE + /* ptr to phys current thread */ + tophys(r4,r2) + addi r4,r4,THREAD /* init task's THREAD */ + mtspr SPRG3,r4 + li r3,0 + mtspr SPRG2,r3 /* 0 => r1 has kernel sp */ + + /* stack */ + addi r1,r2,TASK_UNION_SIZE li r0,0 stwu r0,-STACK_FRAME_OVERHEAD(r1) - ## Determine what type of platform this is. + bl early_init /* We have to do this with MMU on */ +/* + * Decide what sort of machine this is and initialize the MMU. + */ mr r3,r31 mr r4,r30 mr r5,r29 mr r6,r28 mr r7,r27 - bl identify_machine - - ## Initialize the memory management unit. - + bl machine_init bl MMU_init - ## Go back to running unmapped so that we can change to our - ## exception vectors. - +/* Go back to running unmapped so we can load up new values + * and change to using our exception vectors. + * On the 4xx, all we have to do is invalidate the TLB to clear + * the old 16M byte TLB mappings. + */ lis r4,2f@h ori r4,r4,2f@l tophys(r4,r4) li r3,MSR_KERNEL & ~(MSR_IR|MSR_DR) - mtspr SPRN_SRR0,r4 # Set up the instruction pointer - mtspr SPRN_SRR1,r3 # Set up the machine state register + mtspr SRR0,r4 + mtspr SRR1,r3 rfi - ## Load up the kernel context - -2: SYNC # Force all PTE updates to finish -# tlbia # Clear all TLB entries -# sync # Wait for tlbia to finish... - - ## Set up for using our exception vectors - - tophys(r4,r2) # Pointer to physical current thread - addi r4,r4,THREAD # The init task thread - mtspr SPRN_SPRG3,r4 # Save it for exceptions later - li r3,0 # - mtspr SPRN_SPRG2,r3 # 0 implies r1 has kernel stack pointer - - ## Really turn on the MMU and jump into the kernel - - lis r4,MSR_KERNEL@h - ori r4,r4,MSR_KERNEL@l - lis r3,start_kernel@h - ori r3,r3,start_kernel@l - mtspr SPRN_SRR0,r3 # Set up the instruction pointer - mtspr SPRN_SRR1,r4 # Set up the machine state register - rfi # Enable the MMU, jump to the kernel +/* Load up the kernel context */ +2: + SYNC /* Force all PTE updates to finish */ +#ifndef CONFIG_PIN_TLB + tlbia /* Clear all TLB entries */ + sync /* wait for tlbia/tlbie to finish */ +#endif + + /* set up the PTE pointers for the Abatron bdiGDB. + */ + lis r6, swapper_pg_dir@h + ori r6, r6, swapper_pg_dir@l + lis r5, abatron_pteptrs@h + ori r5, r5, abatron_pteptrs@l + stw r5, 0xf0(r0) /* Must match your Abatron config file */ + tophys(r5,r5) + stw r6, 0(r5) + +/* Now turn on the MMU for real! */ + li r4,MSR_KERNEL + lis r3,start_kernel@h + ori r3,r3,start_kernel@l + mtspr SRR0,r3 + mtspr SRR1,r4 + rfi /* enable MMU and jump to start_kernel */ + +/* Set up the initial MMU state so we can do the first level of + * kernel initialization. This maps the first 16 MBytes of memory 1:1 + * virtual to physical and more importantly sets the cache mode. + */ +initial_mmu: + tlbia /* Invalidate all TLB entries */ + sync + + /* We should still be executing code at physical address 0x0000xxxx + * at this point. However, start_here is at virtual address + * 0xC000xxxx. So, set up a TLB mapping to cover this once + * translation is enabled. + */ + + lis r3,KERNELBASE@h /* Load the kernel virtual address */ + ori r3,r3,KERNELBASE@l + tophys(r4,r3) /* Load the kernel physical address */ + + /* Load the kernel PID. + */ + li r0,0 + mtspr SPRN_PID,r0 + sync + + /* Configure and load two entries into TLB slots 62 and 63. + * In case we are pinning TLBs, these are reserved in by the + * other TLB functions. If not reserving, then it doesn't + * matter where they are loaded. + */ + clrrwi r4,r4,10 /* Mask off the real page number */ + ori r4,r4,(TLB_WR | TLB_EX) /* Set the write and execute bits */ + + clrrwi r3,r3,10 /* Mask off the effective page number */ + ori r3,r3,(TLB_VALID | TLB_PAGESZ(PAGESZ_16M)) + + li r0,62 /* TLB slot 62 */ + + tlbwe r4,r0,TLB_DATA /* Load the data portion of the entry */ + tlbwe r3,r0,TLB_TAG /* Load the tag portion of the entry */ + + addis r4, r4, 0x0100 /* Map next 16 M entries */ + addis r3, r3, 0x0100 + + li r0,63 /* TLB slot 63 */ + + tlbwe r4,r0,TLB_DATA + tlbwe r3,r0,TLB_TAG + isync + + /* Establish the exception vector base + */ + lis r4,KERNELBASE@h /* EVPR only uses the high 16-bits */ + tophys(r0,r4) /* Use the physical address */ + mtspr SPRN_EVPR,r0 + + blr + _GLOBAL(set_context) + +#ifdef CONFIG_BDI_SWITCH + /* Context switch the PTE pointer for the Abatron BDI2000. + * The PGDIR is the second parameter. + */ + lis r5, KERNELBASE@h + lwz r5, 0xf0(r5) + stw r4, 0x4(r5) +#endif mtspr SPRN_PID,r3 blr -### -### We put a few things here that have to be page-aligned. This stuff -### goes at the beginning of the data segment, which is page-aligned. -### - +/* We put a few things here that have to be page-aligned. This stuff + * goes at the beginning of the data segment, which is page-aligned. + */ .data _GLOBAL(sdata) _GLOBAL(empty_zero_page) .space 4096 _GLOBAL(swapper_pg_dir) - .space 4096 - -### -### This space gets a copy of optional info passed to us by the bootstrap -### which is used to pass parameters into the kernel like root=/dev/sda1, etc. -### + .space 4096 +/* This space gets a copy of optional info passed to us by the bootstrap + * which is used to pass parameters into the kernel like root=/dev/sda1, etc. + */ _GLOBAL(cmd_line) .space 512 + +/* Room for two PTE pointers, usually the kernel and current user pointers + * to their respective root page table. + */ +abatron_pteptrs: + .space 8 diff --git a/arch/ppc/kernel/head_8xx.S b/arch/ppc/kernel/head_8xx.S index 542a2bc32dc4..766a59507e29 100644 --- a/arch/ppc/kernel/head_8xx.S +++ b/arch/ppc/kernel/head_8xx.S @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.head_8xx.S 1.23 09/16/01 19:32:54 trini + * BK Id: %F% %I% %G% %U% %#% */ /* * arch/ppc/kernel/except_8xx.S @@ -24,14 +24,15 @@ * */ -#include "ppc_asm.h" +#include <linux/config.h> #include <asm/processor.h> #include <asm/page.h> -#include <linux/config.h> #include <asm/mmu.h> #include <asm/cache.h> #include <asm/pgtable.h> #include <asm/cputable.h> +#include <asm/ppc_asm.h> +#include "ppc_defs.h" .text .globl _stext @@ -334,7 +335,7 @@ InstructionTLBMiss: beq 2f /* If zero, don't try to find a pte */ /* We have a pte table, so load the MI_TWC with the attributes - * for this page, which has only bit 31 set. + * for this "segment." */ tophys(r21,r21) ori r21,r21,1 /* Set valid bit */ @@ -343,7 +344,7 @@ InstructionTLBMiss: stw r3, 12(r0) lwz r3, 12(r0) #endif - mtspr MI_TWC, r21 /* Set page attributes */ + mtspr MI_TWC, r21 /* Set segment attributes */ #ifdef CONFIG_8xx_CPU6 li r3, 0x3b80 stw r3, 12(r0) @@ -362,8 +363,6 @@ InstructionTLBMiss: * set. All other Linux PTE bits control the behavior * of the MMU. */ - li r21, 0x0600 - andc r20, r20, r21 /* Clear 21, 22 */ li r21, 0x00f0 rlwimi r20, r21, 0, 24, 28 /* Set 24-27, clear 28 */ @@ -456,8 +455,6 @@ DataStoreTLBMiss: * set. All other Linux PTE bits control the behavior * of the MMU. */ - li r21, 0x0600 - andc r20, r20, r21 /* Clear 21, 22 */ li r21, 0x00f0 rlwimi r20, r21, 0, 24, 28 /* Set 24-27, clear 28 */ @@ -521,6 +518,34 @@ DataTLBError: andis. r21, r20, 0x0200 /* If set, indicates store op */ beq 2f + /* The EA of a data TLB miss is automatically stored in the MD_EPN + * register. The EA of a data TLB error is automatically stored in + * the DAR, but not the MD_EPN register. We must copy the 20 most + * significant bits of the EA from the DAR to MD_EPN before we + * start walking the page tables. We also need to copy the CASID + * value from the M_CASID register. + * Addendum: The EA of a data TLB error is _supposed_ to be stored + * in DAR, but it seems that this doesn't happen in some cases, such + * as when the error is due to a dcbi instruction to a page with a + * TLB that doesn't have the changed bit set. In such cases, there + * does not appear to be any way to recover the EA of the error + * since it is neither in DAR nor MD_EPN. As a workaround, the + * _PAGE_HWWRITE bit is set for all kernel data pages when the PTEs + * are initialized in mapin_ram(). This will avoid the problem, + * assuming we only use the dcbi instruction on kernel addresses. + */ + mfspr r20, DAR + rlwinm r21, r20, 0, 0, 19 + ori r21, r21, MD_EVALID + mfspr r20, M_CASID + rlwimi r21, r20, 0, 28, 31 +#ifdef CONFIG_8xx_CPU6 + li r3, 0x3780 + stw r3, 12(r0) + lwz r3, 12(r0) +#endif + mtspr MD_EPN, r21 + mfspr r20, M_TWB /* Get level 1 table entry address */ /* If we are faulting a kernel address, we have to use the @@ -564,8 +589,6 @@ DataTLBError: * set. All other Linux PTE bits control the behavior * of the MMU. */ - li r21, 0x0600 - andc r20, r20, r21 /* Clear 21, 22 */ li r21, 0x00f0 rlwimi r20, r21, 0, 24, 28 /* Set 24-27, clear 28 */ @@ -769,16 +792,31 @@ start_here: * kernel initialization. This maps the first 8 MBytes of memory 1:1 * virtual to physical. Also, set the cache mode since that is defined * by TLB entries and perform any additional mapping (like of the IMMR). + * If configured to pin some TLBs, we pin the first 8 Mbytes of kernel, + * 24 Mbytes of data, and the 8M IMMR space. Anything not covered by + * these mappings is mapped by page tables. */ initial_mmu: tlbia /* Invalidate all TLB entries */ +#ifdef CONFIG_PIN_TLB + lis r8, MI_RSV4I@h + ori r8, r8, 0x1c00 +#else li r8, 0 - mtspr MI_CTR, r8 /* Set instruction control to zero */ - lis r8, MD_RESETVAL@h +#endif + mtspr MI_CTR, r8 /* Set instruction MMU control */ + +#ifdef CONFIG_PIN_TLB + lis r10, (MD_RSV4I | MD_RESETVAL)@h + ori r10, r10, 0x1c00 + mr r8, r10 +#else + lis r10, MD_RESETVAL@h +#endif #ifndef CONFIG_8xx_COPYBACK - oris r8, r8, MD_WTDEF@h + oris r10, r10, MD_WTDEF@h #endif - mtspr MD_CTR, r8 /* Set data TLB control */ + mtspr MD_CTR, r10 /* Set data TLB control */ /* Now map the lower 8 Meg into the TLBs. For this quick hack, * we can load the instruction and data TLB registers with the @@ -802,6 +840,10 @@ initial_mmu: /* Map another 8 MByte at the IMMR to get the processor * internal registers (among other things). */ +#ifdef CONFIG_PIN_TLB + addi r10, r10, 0x0100 + mtspr MD_CTR, r10 +#endif mfspr r9, 638 /* Get current IMMR */ andis. r9, r9, 0xff80 /* Get 8Mbyte boundary */ @@ -815,6 +857,30 @@ initial_mmu: ori r8, r8, MI_BOOTINIT|0x2 /* Inhibit cache -- Cort */ mtspr MD_RPN, r8 +#ifdef CONFIG_PIN_TLB + /* Map two more 8M kernel data pages. + */ + addi r10, r10, 0x0100 + mtspr MD_CTR, r10 + + lis r8, KERNELBASE@h /* Create vaddr for TLB */ + addis r8, r8, 0x0080 /* Add 8M */ + ori r8, r8, MI_EVALID /* Mark it valid */ + mtspr MD_EPN, r8 + li r9, MI_PS8MEG /* Set 8M byte page */ + ori r9, r9, MI_SVALID /* Make it valid */ + mtspr MD_TWC, r9 + li r11, MI_BOOTINIT /* Create RPN for address 0 */ + addis r11, r11, 0x0080 /* Add 8M */ + mtspr MD_RPN, r8 + + addis r8, r8, 0x0080 /* Add 8M */ + mtspr MD_EPN, r8 + mtspr MD_TWC, r9 + addis r11, r11, 0x0080 /* Add 8M */ + mtspr MD_RPN, r8 +#endif + /* Since the cache is enabled according to the information we * just loaded into the TLB, invalidate and enable the caches here. * We should probably check/set other modes....later. diff --git a/arch/ppc/kernel/i8259.c b/arch/ppc/kernel/i8259.c index 3f5bed25ea58..bc9d5d069523 100644 --- a/arch/ppc/kernel/i8259.c +++ b/arch/ppc/kernel/i8259.c @@ -1,13 +1,17 @@ /* - * BK Id: SCCS/s.i8259.c 1.7 05/17/01 18:14:21 cort + * BK Id: %F% %I% %G% %U% %#% */ #include <linux/stddef.h> #include <linux/init.h> +#include <linux/irq.h> +#include <linux/ioport.h> #include <linux/sched.h> #include <linux/signal.h> #include <asm/io.h> -#include "i8259.h" +#include <asm/i8259.h> + +static volatile char *pci_intack; /* RO, gives us the irq vector */ unsigned char cached_8259[2] = { 0xff, 0xff }; #define cached_A1 (cached_8259[0]) @@ -17,32 +21,56 @@ static spinlock_t i8259_lock = SPIN_LOCK_UNLOCKED; int i8259_pic_irq_offset; -int i8259_irq(int cpu) +/* Acknowledge the irq using the PCI host bridge's interrupt acknowledge + * feature. (Polling is somehow broken on some IBM and Motorola PReP boxes.) + */ +int i8259_irq(void) { int irq; - + spin_lock/*_irqsave*/(&i8259_lock/*, flags*/); - /* - * Perform an interrupt acknowledge cycle on controller 1 - */ - outb(0x0C, 0x20); - irq = inb(0x20) & 7; - if (irq == 2) - { - /* - * Interrupt is cascaded so perform interrupt - * acknowledge on controller 2 - */ - outb(0x0C, 0xA0); - irq = (inb(0xA0) & 7) + 8; - } - else if (irq==7) - { - /* - * This may be a spurious interrupt - * - * Read the interrupt status register. If the most - * significant bit is not set then there is no valid + + irq = *pci_intack & 0xff; + if (irq==7) { + /* + * This may be a spurious interrupt. + * + * Read the interrupt status register (ISR). If the most + * significant bit is not set then there is no valid + * interrupt. + */ + if(~inb(0x20)&0x80) { + irq = -1; + } + } + spin_unlock/*_irqrestore*/(&i8259_lock/*, flags*/); + return irq; +} + +/* Poke the 8259's directly using poll commands. */ +int i8259_poll(void) +{ + int irq; + + spin_lock/*_irqsave*/(&i8259_lock/*, flags*/); + /* + * Perform an interrupt acknowledge cycle on controller 1 + */ + outb(0x0C, 0x20); /* prepare for poll */ + irq = inb(0x20) & 7; + if (irq == 2) { + /* + * Interrupt is cascaded so perform interrupt + * acknowledge on controller 2 + */ + outb(0x0C, 0xA0); /* prepare for poll */ + irq = (inb(0xA0) & 7) + 8; + } else if (irq==7) { + /* + * This may be a spurious interrupt + * + * Read the interrupt status register. If the most + * significant bit is not set then there is no valid * interrupt */ outb(0x0b, 0x20); @@ -58,44 +86,44 @@ int i8259_irq(int cpu) static void i8259_mask_and_ack_irq(unsigned int irq_nr) { unsigned long flags; - + spin_lock_irqsave(&i8259_lock, flags); - if ( irq_nr >= i8259_pic_irq_offset ) - irq_nr -= i8259_pic_irq_offset; - - if (irq_nr > 7) { - cached_A1 |= 1 << (irq_nr-8); - inb(0xA1); /* DUMMY */ - outb(cached_A1,0xA1); - outb(0x20,0xA0); /* Non-specific EOI */ - outb(0x20,0x20); /* Non-specific EOI to cascade */ - } else { - cached_21 |= 1 << irq_nr; - inb(0x21); /* DUMMY */ - outb(cached_21,0x21); - outb(0x20,0x20); /* Non-specific EOI */ - } + if ( irq_nr >= i8259_pic_irq_offset ) + irq_nr -= i8259_pic_irq_offset; + + if (irq_nr > 7) { + cached_A1 |= 1 << (irq_nr-8); + inb(0xA1); /* DUMMY */ + outb(cached_A1,0xA1); + outb(0x20,0xA0); /* Non-specific EOI */ + outb(0x20,0x20); /* Non-specific EOI to cascade */ + } else { + cached_21 |= 1 << irq_nr; + inb(0x21); /* DUMMY */ + outb(cached_21,0x21); + outb(0x20,0x20); /* Non-specific EOI */ + } spin_unlock_irqrestore(&i8259_lock, flags); } static void i8259_set_irq_mask(int irq_nr) { - outb(cached_A1,0xA1); - outb(cached_21,0x21); + outb(cached_A1,0xA1); + outb(cached_21,0x21); } - + static void i8259_mask_irq(unsigned int irq_nr) { unsigned long flags; spin_lock_irqsave(&i8259_lock, flags); - if ( irq_nr >= i8259_pic_irq_offset ) - irq_nr -= i8259_pic_irq_offset; - if ( irq_nr < 8 ) - cached_21 |= 1 << irq_nr; - else - cached_A1 |= 1 << (irq_nr-8); - i8259_set_irq_mask(irq_nr); + if ( irq_nr >= i8259_pic_irq_offset ) + irq_nr -= i8259_pic_irq_offset; + if ( irq_nr < 8 ) + cached_21 |= 1 << irq_nr; + else + cached_A1 |= 1 << (irq_nr-8); + i8259_set_irq_mask(irq_nr); spin_unlock_irqrestore(&i8259_lock, flags); } @@ -104,13 +132,13 @@ static void i8259_unmask_irq(unsigned int irq_nr) unsigned long flags; spin_lock_irqsave(&i8259_lock, flags); - if ( irq_nr >= i8259_pic_irq_offset ) - irq_nr -= i8259_pic_irq_offset; - if ( irq_nr < 8 ) - cached_21 &= ~(1 << irq_nr); - else - cached_A1 &= ~(1 << (irq_nr-8)); - i8259_set_irq_mask(irq_nr); + if ( irq_nr >= i8259_pic_irq_offset ) + irq_nr -= i8259_pic_irq_offset; + if ( irq_nr < 8 ) + cached_21 &= ~(1 << irq_nr); + else + cached_A1 &= ~(1 << (irq_nr-8)); + i8259_set_irq_mask(irq_nr); spin_unlock_irqrestore(&i8259_lock, flags); } @@ -121,36 +149,62 @@ static void i8259_end_irq(unsigned int irq) } struct hw_interrupt_type i8259_pic = { - " i8259 ", - NULL, - NULL, - i8259_unmask_irq, - i8259_mask_irq, - i8259_mask_and_ack_irq, - i8259_end_irq, - NULL + " i8259 ", + NULL, + NULL, + i8259_unmask_irq, + i8259_mask_irq, + i8259_mask_and_ack_irq, + i8259_end_irq, + NULL }; -void __init i8259_init(void) +static struct resource pic1_iores = { + "8259 (master)", 0x20, 0x21, IORESOURCE_BUSY +}; + +static struct resource pic2_iores = { + "8259 (slave)", 0xa0, 0xa1, IORESOURCE_BUSY +}; + +static struct resource pic_edgectrl_iores = { + "8259 edge control", 0x4d0, 0x4d1, IORESOURCE_BUSY +}; + +void __init i8259_init(long intack_addr) { unsigned long flags; - + spin_lock_irqsave(&i8259_lock, flags); - /* init master interrupt controller */ - outb(0x11, 0x20); /* Start init sequence */ - outb(0x00, 0x21); /* Vector base */ - outb(0x04, 0x21); /* edge tiggered, Cascade (slave) on IRQ2 */ - outb(0x01, 0x21); /* Select 8086 mode */ - outb(0xFF, 0x21); /* Mask all */ - /* init slave interrupt controller */ - outb(0x11, 0xA0); /* Start init sequence */ - outb(0x08, 0xA1); /* Vector base */ - outb(0x02, 0xA1); /* edge triggered, Cascade (slave) on IRQ2 */ - outb(0x01, 0xA1); /* Select 8086 mode */ - outb(0xFF, 0xA1); /* Mask all */ - outb(cached_A1, 0xA1); - outb(cached_21, 0x21); + /* init master interrupt controller */ + outb(0x11, 0x20); /* Start init sequence */ + outb(0x00, 0x21); /* Vector base */ + outb(0x04, 0x21); /* edge tiggered, Cascade (slave) on IRQ2 */ + outb(0x01, 0x21); /* Select 8086 mode */ + + /* init slave interrupt controller */ + outb(0x11, 0xA0); /* Start init sequence */ + outb(0x08, 0xA1); /* Vector base */ + outb(0x02, 0xA1); /* edge triggered, Cascade (slave) on IRQ2 */ + outb(0x01, 0xA1); /* Select 8086 mode */ + + /* always read ISR */ + outb(0x0B, 0x20); + outb(0x0B, 0xA0); + + /* Mask all interrupts */ + outb(cached_A1, 0xA1); + outb(cached_21, 0x21); + spin_unlock_irqrestore(&i8259_lock, flags); - request_irq( i8259_pic_irq_offset + 2, no_action, SA_INTERRUPT, - "82c59 secondary cascade", NULL ); + + /* reserve our resources */ + request_irq( i8259_pic_irq_offset + 2, no_action, SA_INTERRUPT, + "82c59 secondary cascade", NULL ); + request_resource(&ioport_resource, &pic1_iores); + request_resource(&ioport_resource, &pic2_iores); + request_resource(&ioport_resource, &pic_edgectrl_iores); + + if (intack_addr) + pci_intack = ioremap(intack_addr, 1); } diff --git a/arch/ppc/kernel/iSeries_asm.h b/arch/ppc/kernel/iSeries_asm.h new file mode 100644 index 000000000000..098a5980fa5a --- /dev/null +++ b/arch/ppc/kernel/iSeries_asm.h @@ -0,0 +1,62 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ +/* + * arch/ppc/kernel/iSeries_asm.h + * + * Definitions used by various bits of low-level assembly code on iSeries. + * + * Copyright (C) 2001 IBM Corp. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#define CHECKLPQUEUE(ra,rb,rc) \ + mfspr rb,SPRG1; /* Get Paca address */\ + lbz ra,PACALPPACA+LPPACAIPIINT(rb); /* Get IPI int flag */\ + cmpi 0,ra,0; /* IPI occurred in hypervisor ? */\ + bne 99f; /* If so, skip rest */\ + lwz ra,PACALPQUEUE(rb); /* Get LpQueue address */\ + cmpi 0,ra,0; /* Does LpQueue exist? */\ + beq 99f; /* If not skip rest */\ + lbz rb,LPQINUSEWORD(ra); /* Test for LpQueue recursion */\ + cmpi 0,rb,1; /* If we are about to recurse */\ + beq 99f; /* If so, skip rest */\ + lwz rb,LPQCUREVENTPTR(ra); /* Get current LpEvent */\ + lbz rb,LPEVENTFLAGS(rb); /* Get Valid bit */\ + lbz rc,LPQOVERFLOW(ra); /* Get LpQueue overflow */\ + andi. ra,rb,0x0080; /* Isolate Valid bit */\ + or. ra,ra,rc; /* 0 == no pending events */\ +99: + +#define CHECKDECR(ra,rb) \ + mfspr rb,SPRG1; /* Get Paca address */\ + lbz ra,PACALPPACA+LPPACADECRINT(rb); /* Get DECR int flag */\ + cmpi 0,ra,0; /* DECR occurred in hypervisor ? */\ + beq 99f; /* If not, skip rest */\ + xor ra,ra,ra; \ + stb ra,PACALPPACA+LPPACADECRINT(rb); /* Clear DECR int flag */\ +99: + +#define CHECKANYINT(ra,rb,rc) \ + mfspr rb,SPRG1; /* Get Paca address */\ + ld ra,PACALPPACA+LPPACAANYINT(rb); /* Get all interrupt flags */\ + /* Note use of ld, protected by soft/hard disabled */\ + cmpldi 0,ra,0; /* Any interrupt occurred while soft disabled? */\ + bne 99f; /* If so, skip rest */\ + lwz ra,PACALPQUEUE(rb); /* Get LpQueue address */\ + cmpi 0,ra,0; /* Does LpQueue exist? */\ + beq 99f; /* If not skip rest */\ + lwz rb,LPQINUSEWORD(ra); /* Test for LpQueue recursion */\ + cmpi 0,rb,1; /* If we are about to recurse */\ + beq 99f; /* If so, skip rest */\ + lwz rb,LPQCUREVENTPTR(ra); /* Get current LpEvent */\ + lbz rb,LPEVENTFLAGS(rb); /* Get Valid bit */\ + lbz rc,LPQOVERFLOW(ra); /* Get LpQueue overflow */\ + andi. ra,rb,0x0080; /* Isolate Valid bit */\ + or. ra,ra,rc; /* 0 == no pending events */\ +99: + diff --git a/arch/ppc/kernel/iSeries_head.S b/arch/ppc/kernel/iSeries_head.S new file mode 100644 index 000000000000..46765589e983 --- /dev/null +++ b/arch/ppc/kernel/iSeries_head.S @@ -0,0 +1,1512 @@ +/* + * arch/ppc/kernel/iSeries_head.S + * + * Adapted from arch/ppc/kernel/head.S + * + * PowerPC version + * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) + * + * Rewritten by Cort Dougan (cort@cs.nmt.edu) for PReP + * Copyright (C) 1996 Cort Dougan <cort@cs.nmt.edu> + * Adapted for Power Macintosh by Paul Mackerras. + * Low-level exception handlers and MMU support + * rewritten by Paul Mackerras. + * Copyright (C) 1996 Paul Mackerras. + * Adapted for iSeries by Mike Corrigan + * Updated by Dave Boutcher + * + * This file contains the low-level support and setup for the + * iSeries LPAR platform. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + */ + +#include <linux/config.h> +#include <asm/processor.h> +#include <asm/page.h> +#include <asm/mmu.h> +#include <asm/pgtable.h> +#include <asm/ppc_asm.h> +#include "ppc_defs.h" +#include "iSeries_asm.h" + + + .text + .globl _stext +_stext: + +/* iSeries LPAR + * + * In an iSeries partition, the operating system has no direct access + * to the hashed page table. The iSeries hypervisor manages the + * hashed page table, and is directed by the operating system in the + * partition. The partition, Linux in this case, always runs with + * MSR.IR and MSR.DR equal to 1. The hypervisor establishes + * addressibility for the first 64 MB of memory at 0xC0000000 by + * building a hashed page table and setting segment register 12. + * + * The partition memory is not physically contiguous, nor necessarily + * addressable with a 32-bit address. The hypervisor provides functions + * which the kernel can use to discover the layout of memory. The + * iSeries LPAR specific code in the kernel will build a table that maps + * contiguous pseudo-real addresses starting at zero to the actual + * physical addresses owned by this partition. In 32-bit mode we will + * restrict ourselves to no more than 768 MB (or maybe 1 GB) + * + * When Linux interrupt handlers get control, the hypervisor has + * already saved SRR0 and SRR1 into a control block shared between + * the hypervisor and Linux. This is know as the ItLpPaca. The values + * in the actual SRR0 and SRR1 are not valid. This requires a change in + * the way the SPRG registers are used. The definitions are: + * + * Register old definition new definition + * + * SPRG0 temp - used to save gpr reserved for hypervisor + * SPRG1 temp - used to save gpr addr of Paca + * SPRG2 0 or kernel stack frame temp - used to save gpr + * SPRG3 Linux thread Linux thread + * + * The Paca contains the address of the ItLpPaca. The Paca is known only + * to Linux, while the ItLpPaca is shared between Linux and the + * hypervisor. + * + * The value that used to be in SPRG2 will now be saved in the Paca, + * as will at least one GPR. + */ + + .globl __start +__start: + b start_here + + + . = 0x020 + + /* iSeries LPAR hypervisor expects a 64-bit offset of + the hvReleaseData structure (see HvReleaseData.h) + at offset 0x20. This is the base for all common + control blocks between the hypervisor and the kernel + */ + + .long 0 + .long hvReleaseData-KERNELBASE + .long 0 + .long msChunks-KERNELBASE + .long 0 + .long pidhash-KERNELBASE + /* Pointer to start of embedded System.map */ + .long 0 + .globl embedded_sysmap_start +embedded_sysmap_start: + .long 0 + /* Pointer to end of embedded System.map */ + .long 0 + .globl embedded_sysmap_end +embedded_sysmap_end: + .long 0 + + + . = 0x060 + + .globl ste_fault_count +ste_fault_count: + .long 0 + .globl set_context_count +set_context_count: + .long 0 + .globl yield_count +yield_count: + .long 0 + .globl update_times_count +update_times_count: + .long 0 + .globl update_wall_jiffies_count +update_wall_jiffies_count: + .long 0 + .globl update_wall_jiffies_ticks +update_wall_jiffies_ticks: + .long 0 + + +/* + * We assume SPRG1 has the address of the Paca and SPRG3 + * has the address of the task's thread_struct. + * SPRG2 is used as a scratch register (as required by the + * hypervisor). SPRG0 is reserved for the hypervisor. + * + * The ItLpPaca has the values of SRR0 and SRR1 that the + * hypervisor saved at the point of the actual interrupt. + * + * The Paca contains the value that the non-LPAR PPC Linux Kernel + * keeps in SPRG2, which is either zero (if the interrupt + * occurred in the kernel) or the address of the available + * space on the kernel stack (if the interrupt occurred + * in user code). +*/ +#define EXCEPTION_PROLOG_1 \ + mtspr SPRG2,r20; /* use SPRG2 as scratch reg */\ + mfspr r20,SPRG1; /* get Paca */\ + /* must do std not stw because soft disable protects \ + * 64-bit register use (in HvCall, maybe others) \ + */\ + std r21,PACAR21(r20); /* Save GPR21 in Paca */\ + std r22,PACAR22(r20); /* Save GPR22 in Paca */\ + mfcr r22 /* Get CR */ + +#define EXCEPTION_PROLOG_2 \ + lwz r21,PACAKSAVE(r20); /* exception stack to use */\ + cmpwi 0,r21,0; /* user mode or kernel */\ + bne 1f; /* 0 -> r1, else use PACAKSAVE */\ + subi r21,r1,INT_FRAME_SIZE; /* alloc exc. frame */\ +1: stw r1,GPR1(r21); \ + mr r1,r21; \ + stw r22,_CCR(r1); /* save CR in stackframe */ \ + mflr r22; \ + stw r22,_LINK(r1); /* Save LR in stackframe */ \ + bl save_regs; /* now save everything else */ \ + ld r22,PACALPPACA+LPPACASRR0(r20); /* Get SRR0 from ItLpPaca */\ + ld r23,PACALPPACA+LPPACASRR1(r20) /* Get SRR1 from ItLpPaca */ + +#define EXCEPTION_PROLOG_EXIT \ + mtcrf 0xff,r22; \ + ld r22,PACALPPACA+LPPACASRR0(r20); \ + ld r21,PACALPPACA+LPPACASRR1(r20); \ + mtspr SRR0,r22; \ + mtspr SRR1,r21; \ + ld r22,PACAR22(r20); \ + ld r21,PACAR21(r20); \ + mfspr r20,SPRG2; \ + RFI + +#define EXCEPTION_PROLOG \ + EXCEPTION_PROLOG_1; \ + EXCEPTION_PROLOG_2 + + +/* + * Note: code which follows this uses cr0.eq (set if from kernel), + * r21, r22 (SRR0), and r23 (SRR1). + */ + +/* + * Exception vectors. + */ +#define STD_EXCEPTION(n, label, hdlr) \ + . = n; \ +label: \ + EXCEPTION_PROLOG; \ + addi r3,r1,STACK_FRAME_OVERHEAD; \ + li r20,0; /* soft disabled */\ + bl transfer_to_handler; \ + .long hdlr; \ + .long ret_from_except + +/* System reset */ + . = 0x100 +SystemReset: + mfspr r3,SPRG3 /* Get Paca address */ + mtspr SPRG1,r3 /* Set Linux SPRG1 -> Paca */ + lhz r24,PACAPACAINDEX(r3) /* Get processor # */ + cmpi 0,r24,0 /* Are we processor 0? */ + beq start_here /* Start up the first processor */ + mfspr r4,CTRLF + li r5,RUNLATCH + andc r4,r4,r5 /* Turn off the run light */ + mtspr CTRLT,r4 +1: + HMT_LOW +#ifdef CONFIG_SMP + lbz r23,PACAPROCSTART(r3) /* Test if this processor + * should start */ + cmpi 0,r23,0 + bne secondary_start +secondary_smp_loop: + /* Let the Hypervisor know we are alive */ + /* 8002 is a call to HvCallCfg::getLps, a harmless Hypervisor function */ + lis r3,0x8002 + rldicr r0,r3,32,15 /* r0 = (r3 << 32) & 0xffff000000000000 */ + rldicl r3,r3,0,48 /* r3 = r3 & 0x000000000000ffff */ + or r3,r3,r0 /* r3 = r3 | r0 */ +#else /* CONFIG_SMP */ + /* Yield the processor. This is required for non-SMP kernels + which are running on multi-threaded machines. */ + lis r3,0x8000 + rldicr r3,r3,32,15 /* r3 = (r3 << 32) & 0xffff000000000000 */ + addi r3,r3,18 /* r3 = 0x8000000000000012 which is "yield" */ + li r4,0 /* "yield timed" */ + li r5,-1 /* "yield forever" */ +#endif /* CONFIG_SMP */ + li r0,-1 /* r0=-1 indicates a Hypervisor call */ + sc /* Invoke the hypervisor via a system call */ + mfspr r3,SPRG1 /* Put r3 back */ + b 1b /* If SMP not configured, secondaries + * loop forever */ + +/* Machine check */ + STD_EXCEPTION(0x200, MachineCheck, MachineCheckException) + +/* Data access exception. */ + . = 0x300 +DataAccess: + EXCEPTION_PROLOG + mfspr r4,DAR + stw r4,_DAR(r1) + mfspr r5,DSISR + stw r5,_DSISR(r1) + + andis. r0,r5,0x0020 /* Is this a segment fault? */ + bne ste_fault /* Yes - go reload segment regs */ + + /* This should and with 0xd7ff */ + andis. r0,r5,0xa470 /* Can we handle as little fault? */ + bne 1f /* */ + + rlwinm r3,r5,32-15,21,21 /* DSISR_STORE -> _PAGE_RW */ + + /* + * r3 contains the required access permissions + * r4 contains the faulting address + */ + + stw r22,_NIP(r1) /* Help with debug if dsi loop */ + bl hash_page /* Try to handle as hpte fault */ + lwz r4,_DAR(r1) /* Get original DAR */ + lwz r5,_DSISR(r1) /* and original DSISR */ + +1: addi r3,r1,STACK_FRAME_OVERHEAD + lwz r20,_SOFTE(r1) + bl transfer_to_handler + .long do_page_fault + .long ret_from_except + + +/* Instruction access exception. */ + . = 0x400 +InstructionAccess: + EXCEPTION_PROLOG + mr r4,r22 + mr r5,r23 + + andis. r0,r23,0x0020 /* Is this a segment fault? */ + bne ste_fault /* Yes - go reload segment regs */ + + andis. r0,r23,0x4000 /* no pte found? */ + beq 1f /* if so, try to put a PTE */ + + li r3,0 + bl hash_page /* Try to handle as hpte fault */ + mr r4,r22 + mr r5,r23 + +1: addi r3,r1,STACK_FRAME_OVERHEAD + lwz r20,_SOFTE(r1) + bl transfer_to_handler + .long do_page_fault + .long ret_from_except + +/* External interrupt */ + . = 0x500; +HardwareInterrupt: + EXCEPTION_PROLOG_1 + lbz r21,PACAPROCENABLED(r20) + cmpi 0,r21,0 + bne 1f + EXCEPTION_PROLOG_EXIT +1: EXCEPTION_PROLOG_2 +do_pending_int: + addi r3,r1,STACK_FRAME_OVERHEAD + li r4,0 + li r20,0 /* Soft disabled */ + bl transfer_to_handler + .globl do_IRQ_intercept +do_IRQ_intercept: + .long do_IRQ; + .long ret_from_intercept + +/* Alignment exception */ + . = 0x600 +Alignment: + EXCEPTION_PROLOG + mfspr r4,DAR + stw r4,_DAR(r1) + mfspr r5,DSISR + stw r5,_DSISR(r1) + addi r3,r1,STACK_FRAME_OVERHEAD + lbz r20,PACAPROCENABLED(r20) /* preserve soft en/disabled */ + bl transfer_to_handler + .long AlignmentException + .long ret_from_except + +/* Program check exception */ + . = 0x700 +ProgramCheck: + EXCEPTION_PROLOG + addi r3,r1,STACK_FRAME_OVERHEAD + lbz r20,PACAPROCENABLED(r20) /* preserve soft en/disabled */ + bl transfer_to_handler + .long ProgramCheckException + .long ret_from_except + +/* Floating-point unavailable */ + . = 0x800 +FPUnavailable: + EXCEPTION_PROLOG + lwz r3,PACAKSAVE(r20) + cmpwi 0,r3,0 + beq 1f + b load_up_fpu +1: + li r20,0 /* soft disabled */ + bl transfer_to_handler /* if from kernel, take a trap */ + .long KernelFP + .long ret_from_except + + . = 0x900 +Decrementer: + EXCEPTION_PROLOG_1 + lbz r21,PACAPROCENABLED(r20) + cmpi 0,r21,0 + bne 1f + + li r21,1 + stb r21,PACALPPACA+LPPACADECRINT(r20) + lwz r21,PACADEFAULTDECR(r20) + mtspr DEC,r21 + EXCEPTION_PROLOG_EXIT +1: EXCEPTION_PROLOG_2 + addi r3,r1,STACK_FRAME_OVERHEAD + li r20,0 /* Soft disabled */ + bl transfer_to_handler + .globl timer_interrupt_intercept +timer_interrupt_intercept: + .long timer_interrupt + .long ret_from_intercept + + STD_EXCEPTION(0xa00, Trap_0a, UnknownException) + STD_EXCEPTION(0xb00, Trap_0b, UnknownException) + +/* System call */ + . = 0xc00 +SystemCall: + EXCEPTION_PROLOG + /* Store r3 to the kernel stack */ + stw r3,ORIG_GPR3(r1) + lbz r20,PACAPROCENABLED(r20) /* preserve soft en/disabled */ + bl transfer_to_handler + .long DoSyscall + .long ret_from_except + +/* Single step - not used on 601 */ + STD_EXCEPTION(0xd00, SingleStep, SingleStepException) +/* + STD_EXCEPTION(0xe00, Trap_0e, UnknownException) + STD_EXCEPTION(0xf00, Trap_0f, UnknownException) +*/ + STD_EXCEPTION(0x1300, Trap_13, InstructionBreakpoint) +/* + STD_EXCEPTION(0x1400, SMI, SMIException) + STD_EXCEPTION(0x1500, Trap_15, UnknownException) + STD_EXCEPTION(0x1600, Trap_16, UnknownException) + STD_EXCEPTION(0x1700, Trap_17, TAUException) + STD_EXCEPTION(0x1800, Trap_18, UnknownException) + STD_EXCEPTION(0x1900, Trap_19, UnknownException) + STD_EXCEPTION(0x1a00, Trap_1a, UnknownException) + STD_EXCEPTION(0x1b00, Trap_1b, UnknownException) + STD_EXCEPTION(0x1c00, Trap_1c, UnknownException) + STD_EXCEPTION(0x1d00, Trap_1d, UnknownException) + STD_EXCEPTION(0x1e00, Trap_1e, UnknownException) + STD_EXCEPTION(0x1f00, Trap_1f, UnknownException) + STD_EXCEPTION(0x2000, RunMode, RunModeException) + STD_EXCEPTION(0x2100, Trap_21, UnknownException) + STD_EXCEPTION(0x2200, Trap_22, UnknownException) + STD_EXCEPTION(0x2300, Trap_23, UnknownException) + STD_EXCEPTION(0x2400, Trap_24, UnknownException) + STD_EXCEPTION(0x2500, Trap_25, UnknownException) + STD_EXCEPTION(0x2600, Trap_26, UnknownException) + STD_EXCEPTION(0x2700, Trap_27, UnknownException) + STD_EXCEPTION(0x2800, Trap_28, UnknownException) + STD_EXCEPTION(0x2900, Trap_29, UnknownException) + STD_EXCEPTION(0x2a00, Trap_2a, UnknownException) + STD_EXCEPTION(0x2b00, Trap_2b, UnknownException) + STD_EXCEPTION(0x2c00, Trap_2c, UnknownException) + STD_EXCEPTION(0x2d00, Trap_2d, UnknownException) + STD_EXCEPTION(0x2e00, Trap_2e, UnknownException) + STD_EXCEPTION(0x2f00, Trap_2f, UnknownException) +*/ + . = 0x3000 + + /* This code saves: CTR, XER, DAR, DSISR, SRR0, SRR1, */ + /* r0, r2-r13, r20-r24 */ + /* It uses R22 as a scratch register */ +save_regs: + ld r22,PACAR21(r20) /* Get GPR21 from Paca */ + stw r22,GPR21(r1) /* Save GPR21 in stackframe */ + ld r22,PACAR22(r20) /* Get GPR22 from Paca */ + stw r22,GPR22(r1) /* Save GPR22 in stackframe */ + stw r23,GPR23(r1) /* Save GPR23 in stackframe */ + stw r24,GPR24(r1) /* Save GPR24 in stackframe */ + mfspr r22,SPRG2 /* Get GPR20 from SPRG2 */ + stw r22,GPR20(r1) /* Save GPR20 in stackframe */ + mfctr r22 + stw r22,_CTR(r1) + mfspr r22,XER + stw r22,_XER(r1) + lbz r22,PACAPROCENABLED(r20)/* Get soft enabled/disabled */ + stw r22,_SOFTE(r1) + stw r0,GPR0(r1) + SAVE_8GPRS(2, r1) + SAVE_4GPRS(10, r1) + blr + +ste_fault: + bl set_kernel_segregs + + mfspr r3,SPRG1 + li r4,0 + stb r4,PACAPROCENABLED(r3) /* Soft disable prevents going to */ + /* do_pending_int on recursive fault */ + + lis r3,ste_fault_count@ha + lwz r4,ste_fault_count@l(r3) + addi r4,r4,1 + stw r4,ste_fault_count@l(r3) + + mfspr r3,SPRG3 /* get thread */ + addi r3,r3,-THREAD /* get 'current' */ + lwz r3,MM(r3) /* get mm */ + cmpi 0,r3,0 /* if no mm */ + beq 1f /* then use context 0 (kernel) */ + lwz r3,CONTEXT(r3) /* get context */ +1: + /* set_context kills r0, r3, r4 and CTR */ + bl set_context + + lwz r3,_SOFTE(r1) + cmpi 0,r3,0 + beq 5f /* skip checks if restoring disabled */ + + CHECKANYINT(r4,r5,r6) /* if pending interrupts, process them */ + bne- do_pending_int +5: + mfspr r4,SPRG1 + stb r3,PACAPROCENABLED(r4) /* Restore enabled/disabled */ + + b fault_exit + +/* + * This code finishes saving the registers to the exception frame + * and jumps to the appropriate handler for the exception, turning + * on address translation. + * + * At this point r0-r13, r20-r24, CCR, CTR, LINK, XER, DAR and DSISR + * are saved on a stack. SRR0 is in r22, SRR1 is in r23 + * r1 points to the stackframe, r1 points to the kernel stackframe + * We no longer have any dependency on data saved in the PACA, SRR0, SRR1 + * DAR or DSISR. We now copy the registers to the kernel stack (which + * might cause little faults). Any little fault will be handled without + * saving state. Thus when the little fault is completed, it will rfi + * back to the original faulting instruction. + */ + .globl transfer_to_handler +transfer_to_handler: + + mfspr r6,SPRG1 + li r7,0 + stw r7,PACAKSAVE(r6) /* Force new frame for recursive fault */ + + /* Restore the regs used above -- parameters to syscall */ + lwz r6,GPR6(r1) + lwz r7,GPR7(r1) + + stw r22,_NIP(r1) + stw r23,_MSR(r1) + SAVE_4GPRS(14, r1) + SAVE_2GPRS(18, r1) + SAVE_4GPRS(25, r1) + SAVE_2GPRS(29, r1) + SAVE_GPR(31, r1) + + andi. r23,r23,MSR_PR + mfspr r23,SPRG3 /* if from user, fix up THREAD.regs */ + beq 2f + addi r24,r1,STACK_FRAME_OVERHEAD + stw r24,PT_REGS(r23) +2: addi r2,r23,-THREAD /* set r2 to current */ + li r22,RESULT + stwcx. r22,r22,r1 /* to clear the reservation */ + li r22,0 + stw r22,RESULT(r1) + mfspr r23,SPRG1 /* Get Paca address */ + stb r20,PACAPROCENABLED(r23) /* soft enable or disabled */ + mflr r23 + andi. r24,r23,0x3f00 /* get vector offset */ + stw r24,TRAP(r1) + addi r24,r2,TASK_STRUCT_SIZE /* check for kernel stack overflow */ + cmplw 0,r1,r2 + cmplw 1,r1,r24 + crand 1,1,4 + bgt- stack_ovf /* if r2 < r1 < r2+TASK_STRUCT_SIZE */ + lwz r24,0(r23) /* virtual address of handler */ + lwz r23,4(r23) /* where to go when done */ + li r20,MSR_KERNEL + ori r20,r20,MSR_EE /* Always hard enabled */ + FIX_SRR1(r20,r22) + mtspr SRR0,r24 + mtspr SRR1,r20 + mtlr r23 + RFI /* jump to handler, enable MMU */ + +/* + * On kernel stack overflow, load up an initial stack pointer + * and call StackOverflow(regs), which should not return. + */ +stack_ovf: + addi r3,r1,STACK_FRAME_OVERHEAD + lis r1,init_task_union@ha + addi r1,r1,init_task_union@l + addi r1,r1,TASK_UNION_SIZE-STACK_FRAME_OVERHEAD + mfspr r24,SPRG1 + li r20,0 + stb r20,PACAPROCENABLED(r24) /* soft disable */ + lis r24,StackOverflow@ha + addi r24,r24,StackOverflow@l + li r20,MSR_KERNEL + ori r20,r20,MSR_EE /* Always hard enabled */ + FIX_SRR1(r20,r22) + mtspr SRR0,r24 + mtspr SRR1,r20 + RFI + +/* + * Disable FP for the task which had the FPU previously, + * and save its floating-point registers in its thread_struct. + * Enables the FPU for use in the kernel on return. + * On SMP we know the fpu is free, since we give it up every + * switch. -- Cort + * Assume r20 points to PACA on entry + */ +load_up_fpu: + mfmsr r5 + ori r5,r5,MSR_FP + SYNC + MTMSRD(r5) /* enable use of fpu now */ + isync +/* + * For SMP, we don't do lazy FPU switching because it just gets too + * horrendously complex, especially when a task switches from one CPU + * to another. Instead we call giveup_fpu in switch_to. + */ +#ifndef CONFIG_SMP + lis r3,last_task_used_math@ha + lwz r4,last_task_used_math@l(r3) + cmpi 0,r4,0 + beq 1f + addi r4,r4,THREAD /* want last_task_used_math->thread */ + SAVE_32FPRS(0, r4) + mffs fr0 + stfd fr0,THREAD_FPSCR-4(r4) + lwz r5,PT_REGS(r4) + lwz r4,_MSR-STACK_FRAME_OVERHEAD(r5) + li r20,MSR_FP|MSR_FE0|MSR_FE1 + andc r4,r4,r20 /* disable FP for previous task */ + stw r4,_MSR-STACK_FRAME_OVERHEAD(r5) +1: +#endif /* CONFIG_SMP */ + /* enable use of FP after return */ + ori r23,r23,MSR_FP|MSR_FE0|MSR_FE1 + mfspr r5,SPRG3 /* current task's THREAD (phys) */ + lfd fr0,THREAD_FPSCR-4(r5) + mtfsf 0xff,fr0 + REST_32FPRS(0, r5) +#ifndef CONFIG_SMP + subi r4,r5,THREAD + stw r4,last_task_used_math@l(r3) +#endif /* CONFIG_SMP */ + /* restore registers and return */ + lwz r3,_CCR(r21) + lwz r4,_LINK(r21) + mtcrf 0xff,r3 + mtlr r4 + REST_GPR(1, r21) + REST_4GPRS(3, r21) + /* we haven't used ctr or xer */ + mtspr SRR1,r23 + mtspr SRR0,r22 + + REST_GPR(20, r21) + REST_2GPRS(22, r21) + lwz r21,GPR21(r21) + SYNC + RFI + +/* + * FP unavailable trap from kernel - print a message, but let + * the task use FP in the kernel until it returns to user mode. + */ +KernelFP: + lwz r3,_MSR(r1) + ori r3,r3,MSR_FP + stw r3,_MSR(r1) /* enable use of FP after return */ + lis r3,86f@h + ori r3,r3,86f@l + mr r4,r2 /* current */ + lwz r5,_NIP(r1) + bl printk + b ret_from_except +86: .string "floating point used in kernel (task=%p, pc=%x)\n" + .align 4 + +/* + * giveup_fpu(tsk) + * Disable FP for the task given as the argument, + * and save the floating-point registers in its thread_struct. + * Enables the FPU for use in the kernel on return. + */ + .globl giveup_fpu +giveup_fpu: + mfmsr r5 + ori r5,r5,MSR_FP + mtmsr r5 /* enable use of fpu now */ + cmpi 0,r3,0 + beqlr- /* if no previous owner, done */ + addi r3,r3,THREAD /* want THREAD of task */ + lwz r5,PT_REGS(r3) + cmpi 0,r5,0 + SAVE_32FPRS(0, r3) + mffs fr0 + stfd fr0,THREAD_FPSCR-4(r3) + beq 1f + lwz r4,_MSR-STACK_FRAME_OVERHEAD(r5) + li r3,MSR_FP|MSR_FE0|MSR_FE1 + andc r4,r4,r3 /* disable FP for previous task */ + stw r4,_MSR-STACK_FRAME_OVERHEAD(r5) +1: +#ifndef CONFIG_SMP + li r5,0 + lis r4,last_task_used_math@ha + stw r5,last_task_used_math@l(r4) +#endif /* CONFIG_SMP */ + blr + +#ifdef CONFIG_SMP +secondary_start: + lis r3,0, + mr r4,r24 + bl identify_cpu + bl call_setup_cpu /* Call setup_cpu for this CPU */ + + /* get current */ + HMT_MEDIUM /* Set thread priority to MEDIUM */ + lis r2,current_set@h + ori r2,r2,current_set@l + slwi r24,r24,2 /* get current_set[cpu#] */ + lwzx r2,r2,r24 + + /* stack */ + addi r1,r2,TASK_UNION_SIZE-STACK_FRAME_OVERHEAD + li r0,0 + stw r0,0(r1) + + /* load up the MMU */ + bl load_up_mmu + + /* ptr to phys current thread */ + addi r4,r2,THREAD /* phys address of our thread_struct */ + rlwinm r4,r4,0,0,31 + mtspr SPRG3,r4 + + /* Set up address of Paca in current thread */ + lis r23,xPaca@ha + addi r23,r23,xPaca@l + /* r24 has CPU # * 4 at this point. The Paca is 2048 bytes + long so multiply r24 by 512 to index into the array of Pacas */ + slwi r24,r24,9 + add r23,r23,r24 + rlwinm r23,r23,0,0,31 + mtspr SPRG1,r23 + + li r3,0 + stw r3,PACAKSAVE(r23) /* 0 => r1 has kernel sp */ + + stb r3,PACAPROCENABLED(r23) /* Soft disabled */ + + /* enable MMU and jump to start_secondary */ + + li r4,MSR_KERNEL + ori r4,r4,MSR_EE /* Hard enabled */ + lis r3,start_secondary@h + ori r3,r3,start_secondary@l + mtspr SRR0,r3 + FIX_SRR1(r4,r3) + mtspr SRR1,r4 + RFI +#endif /* CONFIG_SMP */ + +/* + * Load stuff into the MMU. Intended to be called with + * IR=0 and DR=0. + */ +load_up_mmu: + li r0,16 /* load up segment register values */ + mtctr r0 /* for context 0 */ + lis r3,0x2000 /* Ku = 1, VSID = 0 */ + li r4,0 +3: mtsrin r3,r4 + addi r3,r3,0x111 /* increment VSID */ + addis r4,r4,0x1000 /* address of next segment */ + bdnz 3b + blr + +/* + * This is where the main kernel code starts. + */ +start_here: + + /* ptr to current */ + + lis r2,init_task_union@h + ori r2,r2,init_task_union@l + + /* Set up for using our exception vectors */ + + addi r4,r2,THREAD /* init task's THREAD */ + rlwinm r4,r4,0,0,31 + mtspr SPRG3,r4 + + /* Get address of Paca for processor 0 */ + lis r11,xPaca@ha + addi r11,r11,xPaca@l + rlwinm r11,r11,0,0,31 + mtspr SPRG1,r11 + + li r3,0 + stw r3,PACAKSAVE(r11) /* 0 => r1 has kernel sp */ + + stb r3,PACAPROCENABLED(r11) /* Soft disabled */ + + addi r1,r2,TASK_UNION_SIZE + li r0,0 + stwu r0,-STACK_FRAME_OVERHEAD(r1) + + /* fix klimit for system map */ + lis r6,embedded_sysmap_end@ha + lwz r7,embedded_sysmap_end@l(r6) + + cmpi 0,r7,0 + beq 5f + + lis r6, KERNELBASE@h + add r7,r7,r6 + addi r7,r7,4095 + li r6,0x0FFF + andc r7,r7,r6 + + lis r6,klimit@ha + stw r7,klimit@l(r6) +5: + +/* + * Decide what sort of machine this is and initialize the MMU. + */ + bl early_init /* We have to do this with MMU on */ + + mr r3,r31 + mr r4,r30 + mr r5,r29 + mr r6,r28 + mr r7,r27 + li r6,0 /* No cmdline parameters */ + bl platform_init + bl MMU_init + + bl load_up_mmu + + li r4,MSR_KERNEL + ori r4,r4,MSR_EE /* Hard enabled */ + FIX_SRR1(r4,r5) + lis r3,start_kernel@h + ori r3,r3,start_kernel@l + mtspr SRR0,r3 + mtspr SRR1,r4 + RFI /* ensure correct MSR and jump to + start_kernel */ +hash_page: + mflr r21 /* Save LR in r21 */ + + /* + * We hard enable here (but first soft disable) so that the hash_page + * code can spin on the hash_table_lock without problem on a shared + * processor + */ + li r0,0 + stb r0,PACAPROCENABLED(r20) /* Soft disable */ + + mfmsr r0 + ori r0,r0,MSR_EE + mtmsr r0 /* Hard enable */ + + bl create_hpte /* add the hash table entry */ + /* + * Now go back to hard disabled + */ + mfmsr r0 + li r4,0 + ori r4,r4,MSR_EE + andc r0,r0,r4 + mtmsr r0 /* Hard disable */ + + lwz r0,_SOFTE(r1) + mtlr r21 /* restore LR */ + mr r21,r1 /* restore r21 */ + + cmpi 0,r0,0 /* See if we will soft enable in */ + /* fault_exit */ + beq 5f /* if not, skip checks */ + + CHECKANYINT(r4,r5,r6) /* if pending interrupts, process them */ + bne- do_pending_int + +5: stb r0,PACAPROCENABLED(r20) /* Restore soft enable/disable */ + + cmpi 0,r3,0 /* check return code form create_hpte */ + bnelr + +/* + * htab_reloads counts the number of times we have to fault an + * HPTE into the hash table. This should only happen after a + * fork (because fork does a flush_tlb_mm) or a vmalloc or ioremap. + * Where a page is faulted into a process's address space, + * update_mmu_cache gets called to put the HPTE into the hash table + * and those are counted as preloads rather than reloads. + */ + lis r2,htab_reloads@ha + lwz r3,htab_reloads@l(r2) + addi r3,r3,1 + stw r3,htab_reloads@l(r2) + +fault_exit: + + lwz r3,_CCR(r1) + lwz r4,_LINK(r1) + lwz r5,_CTR(r1) + lwz r6,_XER(r1) + + mtcrf 0xff,r3 + mtlr r4 + mtctr r5 + mtspr XER,r6 + + lwz r0,GPR0(r1) + REST_8GPRS(2, r1) + REST_4GPRS(10, r1) + FIX_SRR1(r23,r20) + mtspr SRR1,r23 + mtspr SRR0,r22 + REST_4GPRS(20, r1) + + lwz r1,GPR1(r1) + RFI + +/* + * Set up the segment registers for a new context. + * context in r3 + */ +_GLOBAL(set_context) + mulli r3,r3,897 /* multiply context by skew factor */ + rlwinm r3,r3,4,8,27 /* VSID = (context & 0xfffff) << 4 */ + addis r3,r3,0x6000 /* Set Ks, Ku bits */ + li r0,NUM_USER_SEGMENTS + mtctr r0 + + li r4,0 +3: + mtsrin r3,r4 + addi r3,r3,0x111 /* next VSID */ + rlwinm r3,r3,0,8,3 /* clear out any overflow from VSID field */ + addis r4,r4,0x1000 /* address of next segment */ + bdnz 3b + isync + +set_kernel_segregs: + +/* + * Reload the last four segment registers because they + * might have been clobbered by the hypervisor if we + * are running on a shared processor + */ + lis r3,0x2000 /* Set Ku = 1 */ + addi r3,r3,0xCCC /* Set VSID = CCC */ + lis r4,0xC000 /* Set SR = C */ + li r0,4 /* Load regs C, D, E and F */ + mtctr r0 +4: mtsrin r3,r4 + addi r3,r3,0x111 /* increment VSID */ + addis r4,r4,0x1000 /* address of next segment */ + bdnz 4b + isync + + blr + + +/* Hypervisor call + * + * Invoke the iSeries hypervisor (PLIC) via the System Call instruction. + * Parameters are passed to this routine in registers r3 - r10 and are + * converted to 64-bit by combining registers. eg. r3 <- r3 + * r4 <- r5,r6, r5 <- r7,r8, r6 <- r9,r10 + * + * r3 contains the HV function to be called + * r5,r6 contain the first 64-bit operand + * r7,r8 contain the second 64-bit operand + * r9,r10 contain the third 64-bit operand + * caller's stack frame +8 contains the fourth 64-bit operand + * caller's stack frame +16 contains the fifth 64-bit operand + * caller's stack frame +24 contains the sixth 64-bit operand + * caller's stack frame +32 contains the seventh 64-bit operand + * + */ + +_GLOBAL(HvCall) +_GLOBAL(HvCall0) +_GLOBAL(HvCall1) +_GLOBAL(HvCall2) +_GLOBAL(HvCall3) +_GLOBAL(HvCall4) +_GLOBAL(HvCall5) +_GLOBAL(HvCall6) +_GLOBAL(HvCall7) + /* + * Stack a frame and save one reg so we can hang on to + * the old MSR + */ + stwu r1,-64(r1) + stw r31,60(r1) + + stw r22,24(r1) + stw r23,28(r1) + stw r24,32(r1) + stw r25,36(r1) + stw r26,40(r1) + stw r27,44(r1) + stw r28,48(r1) + stw r29,52(r1) + + /* + * The hypervisor assumes CR fields 0-4 are volatile, but + * gcc assumes CR fields 2-7 are non-volatile. + * We must save and restore the CR here + */ + mfcr r31 + stw r31,20(r1) + + /* Before we can convert to using 64-bit registers we must + * soft disable external interrupts as the interrupt handlers + * don't preserve the high half of the registers + */ + + mfspr r11,SPRG1 /* Get the Paca pointer */ + lbz r31,PACAPROCENABLED(r11) /* Get soft enable/disable flag */ + li r0,0 + stb r0,PACAPROCENABLED(r11) /* Soft disable */ + + /* Get parameters four through seven */ + + lwz r22,72(r1) + lwz r23,76(r1) + lwz r24,80(r1) + lwz r25,84(r1) + lwz r26,88(r1) + lwz r27,92(r1) + lwz r28,96(r1) + lwz r29,100(r1) + /* Now it is safe to operate on 64-bit registers + * + * Format the operands into the 64-bit registers + * + */ + rldicr r5,r5,32,31 /* r5 = r5 << 32 */ + rldicl r6,r6,0,32 /* r6 = r6 & 0x00000000ffffffff */ + or r4,r5,r6 /* r4 = r5 | r6 */ + rldicr r7,r7,32,31 /* r7 = r7 << 32 */ + rldicl r8,r8,0,32 /* r8 = r8 & 0x00000000ffffffff */ + or r5,r7,r8 /* r5 = r7 | r8 */ + rldicr r9,r9,32,31 /* r9 = r9 << 32 */ + rldicl r10,r10,0,32 /* r10 = r10 & 0x00000000ffffffff */ + or r6,r9,r10 /* r6 = r9 | r10 */ + rldicr r22,r22,32,31 /* r22 = r22 << 32 */ + rldicl r23,r23,0,32 /* r23 = r23 & 0x00000000ffffffff */ + or r7,r22,r23 /* r7 = r22 | r23 */ + rldicr r24,r24,32,31 /* r24 = r24 << 32 */ + rldicl r25,r25,0,32 /* r25 = r25 & 0x00000000ffffffff */ + or r8,r24,r25 /* r8 = r24 | r25 */ + rldicr r26,r26,32,31 /* r26 = r26 << 32 */ + rldicl r27,r27,0,32 /* r27 = r27 & 0x00000000ffffffff */ + or r9,r26,r27 /* r9 = r26 | r27 */ + rldicr r28,r28,32,31 /* r28 = r28 << 32 */ + rldicl r29,r29,0,32 /* r29 = r29 & 0x00000000ffffffff */ + or r10,r28,r29 /* r10 = r28 | r29 */ + + /* + * Extract the hypervisor function call number from R3 + * and format it into the 64-bit R3. + */ + rldicr r0,r3,32,15 /* r0 = (r3 << 32) & 0xffff000000000000 */ + rldicl r3,r3,0,48 /* r3 = r3 & 0x000000000000ffff */ + or r3,r3,r0 /* r3 = r3 | r0 */ + + /* + * r0 = 0xffffffffffffffff indicates a hypervisor call + */ + li r0,-1 /* r1 = 0xffffffffffffffff */ + + /* Invoke the hypervisor via the System Call instruction */ + + sc + + HMT_MEDIUM + + /* Return value in 64-bit R3 + * format it into R3 and R4 + */ + rldicl r4,r3,0,32 /* r4 = r3 & 0x00000000ffffffff */ + rldicl r3,r3,32,32 /* r3 = (r3 >> 32) & 0x00000000ffffffff */ + + /* We are now done with 64-bit registers it is safe to touch + * the stack again. + */ + lwz r22,24(r1) + lwz r23,28(r1) + lwz r24,32(r1) + lwz r25,36(r1) + lwz r26,40(r1) + lwz r27,44(r1) + lwz r28,48(r1) + lwz r29,52(r1) + + /* While we were running in the hypervisor, a decrementer or + * external interrupt may have occured. If we are about to + * enable here, we must check for these and process them + */ + + cmpi 0,r31,0 /* check if going to enable */ + beq 1f /* skip checks if staying disabled */ + + /* Save r3, r4 and LR */ + stw r3,52(r1) + stw r4,48(r1) + mflr r3 + stw r3,44(r1) + + /* enable and check for decrementers/lpEvents */ + mr r3,r31 + bl __restore_flags + + /* Restore r3, r4 and LR */ + lwz r3,44(r1) + mtlr r3 + lwz r3,52(r1) + lwz r4,48(r1) + +1: + /* + * Unstack the frame and restore r31 and the CR + */ + lwz r31,20(r1) + mtcrf 0xff,r31 + lwz r31,60(r1) + lwz r1,0(r1) + + blr + +/* Hypervisor call with return data + * + * Invoke the iSeries hypervisor (PLIC) via the System Call instruction. + * The Hv function ID is passed in r3 + * The address of the return data structure is passed in r4 + * Parameters are passed to this routine in registers r5 - r10 and are + * converted to 64-bit by combining registers. eg. r3 <- r3 + * r4 <- r5,r6, r5 <- r7,r8, r6 <- r9,r10 + * + * r3 contains the HV function to be called + * r4 contains the address of the return data structure + * r5,r6 contain the first 64-bit operand + * r7,r8 contain the second 64-bit operand + * r9,r10 contain the third 64-bit operand + * caller's stack frame +8 contains the fourth 64-bit operand + * caller's stack frame +16 contains the fifth 64-bit operand + * caller's stack frame +24 contains the sixth 64-bit operand + * caller's stack frame +32 contains the seventh 64-bit operand + * + */ + +_GLOBAL(HvCallRet16) +_GLOBAL(HvCall0Ret16) +_GLOBAL(HvCall1Ret16) +_GLOBAL(HvCall2Ret16) +_GLOBAL(HvCall3Ret16) +_GLOBAL(HvCall4Ret16) +_GLOBAL(HvCall5Ret16) +_GLOBAL(HvCall6Ret16) +_GLOBAL(HvCall7Ret16) + + /* + * Stack a frame and save some regs + */ + stwu r1,-64(r1) + stw r31,60(r1) + stw r30,56(r1) + + stw r22,24(r1) + stw r23,28(r1) + stw r24,32(r1) + stw r25,36(r1) + stw r26,40(r1) + stw r27,44(r1) + stw r28,48(r1) + stw r29,52(r1) + + mr r30,r4 /* Save return data address */ + + /* + * The hypervisor assumes CR fields 0-4 are volatile, but + * gcc assumes CR fields 2-7 are non-volatile. + * We must save and restore the CR here + */ + mfcr r31 + stw r31,20(r1) + + /* Before we can convert to using 64-bit registers we must + * soft disable external interrupts as the interrupt handlers + * don't preserve the high half of the registers + */ + + mfspr r11,SPRG1 /* Get the Paca pointer */ + lbz r31,PACAPROCENABLED(r11) /* Get soft enable/disable flag */ + li r0,0 + stb r0,PACAPROCENABLED(r11) /* Soft disable */ + + /* Get parameters four through seven */ + + lwz r22,76(r1) + lwz r23,80(r1) + lwz r24,84(r1) + lwz r25,88(r1) + lwz r26,92(r1) + lwz r27,96(r1) + lwz r28,100(r1) + lwz r29,104(r1) + + /* Now it is safe to operate on 64-bit registers + * + */ + + /* + * Format the operands into the 64-bit registers + */ + + rldicr r5,r5,32,31 /* r5 = r5 << 32 */ + rldicl r6,r6,0,32 /* r6 = r6 & 0x00000000ffffffff */ + or r4,r5,r6 /* r4 = r5 | r6 */ + rldicr r7,r7,32,31 /* r7 = r7 << 32 */ + rldicl r8,r8,0,32 /* r8 = r8 & 0x00000000ffffffff */ + or r5,r7,r8 /* r5 = r7 | r8 */ + rldicr r9,r9,32,31 /* r9 = r9 << 32 */ + rldicl r10,r10,0,32 /* r10 = r10 & 0x00000000ffffffff */ + or r6,r9,r10 /* r6 = r9 | r10 */ + rldicr r22,r22,32,31 /* r22 = r22 << 32 */ + rldicl r23,r23,0,32 /* r23 = r23 & 0x00000000ffffffff */ + or r7,r22,r23 /* r7 = r22 | r23 */ + rldicr r24,r24,32,31 /* r24 = r24 << 32 */ + rldicl r25,r25,0,32 /* r25 = r25 & 0x00000000ffffffff */ + or r8,r24,r25 /* r8 = r24 | r25 */ + rldicr r26,r26,32,31 /* r26 = r26 << 32 */ + rldicl r27,r27,0,32 /* r27 = r27 & 0x00000000ffffffff */ + or r9,r26,r27 /* r9 = r26 | r27 */ + rldicr r28,r28,32,31 /* r28 = r28 << 32 */ + rldicl r29,r29,0,32 /* r29 = r29 & 0x00000000ffffffff */ + or r10,r28,r29 /* r10 = r28 | r29 */ + /* + * Extract the hypervisor function call number from R3 + * and format it into the 64-bit R3. + */ + rldicr r0,r3,32,15 /* r4 = (r3 << 32) & 0xffff000000000000 */ + rldicl r3,r3,0,48 /* r3 = r3 & 0x000000000000ffff */ + or r3,r3,r0 /* r3 = r3 | r4 */ + + /* + * r0 = 0xffffffffffffffff indicates a hypervisor call + */ + li r0,-1 /* r1 = 0xffffffffffffffff */ + + /* Invoke the hypervisor via the System Call instruction */ + + sc + + HMT_MEDIUM + + /* Return values in 64-bit R3, R4, R5 and R6 + * place R3 and R4 into data structure, R5 into R3,R4 + */ + rldicl r6,r3,32,32 /* r6 = (r3 >> 32) & 0x00000000ffffffff */ + rldicl r7,r3,0,32 /* r7 = r3 & 0x00000000ffffffff */ + rldicl r8,r4,32,32 /* r8 = (r4 >> 32) & 0x00000000ffffffff */ + rldicl r9,r4,0,32 /* r9 = r4 & 0x00000000ffffffff */ + + rldicl r4,r5,0,32 /* r4 = r5 & 0x00000000ffffffff */ + rldicl r3,r5,32,32 /* r3 = (r5 >> 32) & 0x00000000ffffffff */ + + /* We are now done with 64-bit registers it is safe to touch + * the stack again. + */ + stw r6,0(r30) /* Save returned data */ + stw r7,4(r30) + stw r8,8(r30) + stw r9,12(r30) + + lwz r22,24(r1) + lwz r23,28(r1) + lwz r24,32(r1) + lwz r25,36(r1) + lwz r26,40(r1) + lwz r27,44(r1) + lwz r28,48(r1) + lwz r29,52(r1) + + /* While we were running in the hypervisor, a decrementer or + * external interrupt may have occured. If we are about to + * enable here, we must check for these and process them + */ + + cmpi 0,r31,0 /* check if going to enable */ + beq 1f /* skip checks if staying disabled */ + + /* Save r3, r4 and LR */ + stw r3,48(r1) + stw r4,44(r1) + mflr r3 + stw r3,40(r1) + + /* enable and check for decrementers/lpEvents */ + mr r3,r31 + bl __restore_flags + + lwz r3,40(r1) + mtlr r3 + lwz r3,48(r1) + lwz r4,44(r1) + +1: + /* + * Unstack the frame and restore r30, r31 and CR + */ + lwz r31,20(r1) + mtcrf 0xff,r31 + lwz r30,56(r1) + lwz r31,60(r1) + lwz r1,0(r1) + + blr + + +/* Hypervisor call (use no stack) + * + * These functions must be called with interrupts soft disabled. + * The caller is responsible for saving the non-volatile CR + * The operands should already be formatted into the 64-bit registers + * + * Invoke the iSeries hypervisor (PLIC) via the System Call instruction. + * + * r3 contains the HV function to be called + * r4 contains the first 64-bit operand + * r5 contains the second 64-bit operand + * r6 contains the third 64-bit operand + * r7 contains the fourth 64-bit operand + * r8 contains the fifth 64-bit operand + * r9 contains the sixth 64-bit operand + * r10 contains the seventh 64-bit operand + * + * data is returned in 64-bit registers r3-r6 + * + */ + +_GLOBAL(HvXCall) +_GLOBAL(HvXCall0) +_GLOBAL(HvXCall1) +_GLOBAL(HvXCall2) +_GLOBAL(HvXCall3) + /* + * Extract the hypervisor function call number from R3 + * and format it into the 64-bit R3. + */ + rldicr r0,r3,32,15 /* r0 = (r3 << 32) & 0xffff000000000000 */ + rldicl r3,r3,0,48 /* r3 = r3 & 0x000000000000ffff */ + or r3,r3,r0 /* r3 = r3 | r0 */ + + /* + * r0 = 0xffffffffffffffff indicates a hypervisor call + */ + li r0,-1 /* r1 = 0xffffffffffffffff */ + + /* Invoke the hypervisor via the System Call instruction */ + + sc + + blr + +_GLOBAL(__setup_cpu_power3) + blr +_GLOBAL(__setup_cpu_power4) + blr +_GLOBAL(__setup_cpu_generic) + blr + +_GLOBAL(iSeries_check_intr) + mflr r31 + lwz r5,_SOFTE(r1) + cmpi 0,r5,0 + beqlr + mfspr r5,SPRG1 + lbz r5,PACAPROCENABLED(r5) + cmpi 0,r5,0 + bnelr + /* Check for lost decrementer interrupts. + * (If decrementer popped while we were in the hypervisor) + * (calls timer_interrupt if so) + */ +3: CHECKDECR(r4,r5) + /* Check for pending interrupts. If no interrupts pending, + * then CR0 = "eq" and r4 == 0 + * (kills registers r5 and r6) + */ + beq+ 1f + addi r3,r1,STACK_FRAME_OVERHEAD + bl timer_interrupt +1: + CHECKLPQUEUE(r4,r5,r6) + beq+ 2f + addi r3,r1,STACK_FRAME_OVERHEAD + bl do_IRQ + b 3b + +2: mtlr r31 + blr + +/* + * Fake an interrupt from kernel mode. + * This is used when enable_irq loses an interrupt. + * We only fill in the stack frame minimally. + */ +_GLOBAL(fake_interrupt) + mflr r0 + stw r0,4(r1) + stwu r1,-INT_FRAME_SIZE(r1) + stw r0,_NIP(r1) + stw r0,_LINK(r1) + mfmsr r3 + stw r3,_MSR(r1) + li r0,0x0fac + stw r0,TRAP(r1) + addi r3,r1,STACK_FRAME_OVERHEAD + li r4,1 + bl do_IRQ + addi r1,r1,INT_FRAME_SIZE + lwz r0,4(r1) + + mtlr r0 + blr + +/* + * Fake a decrementer from kernel mode. + * This is used when the decrementer pops in + * the hypervisor. We only fill in the stack + * frame minimally + */ +_GLOBAL(fake_decrementer) + mflr r0 + stw r0,4(r1) + stwu r1,-INT_FRAME_SIZE(r1) + stw r0,_NIP(r1) + stw r0,_LINK(r1) + mfmsr r3 + stw r3,_MSR(r1) + li r0,0x0fac + stw r0,TRAP(r1) + addi r3,r1,STACK_FRAME_OVERHEAD + bl timer_interrupt + addi r1,r1,INT_FRAME_SIZE + lwz r0,4(r1) + + mtlr r0 + blr + +_GLOBAL(create_hpte) + stwu r1,-INT_FRAME_SIZE(r1) + stw r0,GPR0(r1) + lwz r0,0(r1) + stw r0,GPR1(r1) + /* r3-r13 are caller saved */ + stw r2,GPR2(r1) + SAVE_8GPRS(4, r1) + SAVE_2GPRS(12, r1) + SAVE_4GPRS(20,r1) + mfspr r20,XER + mfctr r22 + stw r20,_XER(r1) + stw r22,_CTR(r1) + mflr r20 + mfmsr r22 + stw r20,_NIP(r1) + stw r22,_MSR(r1) + stw r20,_LINK(r1) + bl iSeries_create_hpte + lwz r0,GPR0(r1) + lwz r2,GPR2(r1) + REST_8GPRS(4, r1) + REST_2GPRS(12, r1) + lwz r20,_NIP(r1) + lwz r22,_XER(r1) + mtlr r20 + mtspr XER,r22 + lwz r20,_CTR(r1) + mtctr r20 + + REST_4GPRS(20,r1) + addi r1,r1,INT_FRAME_SIZE + blr + +### +### extern void abort(void) +### +### Invoke the hypervisor to kill the partition. +### + +_GLOBAL(abort) + + +/* + * We put a few things here that have to be page-aligned. + * This stuff goes at the beginning of the data segment, + * which is page-aligned. + */ + .data + .globl sdata +sdata: + + .globl empty_zero_page +empty_zero_page: + .space 4096 + + .globl swapper_pg_dir +swapper_pg_dir: + .space 4096 + +/* + * This space gets a copy of optional info passed to us by the bootstrap + * Used to pass parameters into the kernel like root=/dev/sda1, etc. + */ + .globl cmd_line +cmd_line: + .space 512 diff --git a/arch/ppc/kernel/iSeries_misc.S b/arch/ppc/kernel/iSeries_misc.S new file mode 100644 index 000000000000..983611b80276 --- /dev/null +++ b/arch/ppc/kernel/iSeries_misc.S @@ -0,0 +1,469 @@ + /* + * This file contains miscellaneous low-level functions. + * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) + * + * Largely rewritten by Cort Dougan (cort@cs.nmt.edu) + * and Paul Mackerras. + * Adapted for iSeries by Mike Corrigan (mikejc@us.ibm.com) + * updated by Dave Boutcher (boutcher@us.ibm.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + */ + +#include <linux/config.h> +#include <linux/sys.h> +#include <asm/unistd.h> +#include <asm/errno.h> +#include <asm/processor.h> +#include <asm/page.h> +#include <asm/cache.h> +#include <asm/ppc_asm.h> +#include "ppc_defs.h" +#include "iSeries_asm.h" + + .text + .align 5 + +#ifdef CONFIG_SMP + .comm hash_table_lock,4 +#endif /* CONFIG_SMP */ + +_GLOBAL(is_msr_enabled) + mfmsr r3 + andi. r3,r3,MSR_EE + beqlr /* Return r3=0 indicating disabled */ + li r3,1 + blr /* Return r3=1 indicating enabled */ + +_GLOBAL(is_soft_enabled) + mfspr r3,SPRG1 + lbz r3,PACAPROCENABLED(r3) + blr + +_GLOBAL(get_tb64) + /* hard disable because we are using a 64-bit register + * and we don't want it to get trashed in an interrupt + * handler + */ + + mfmsr r5 + rlwinm r0,r5,0,17,15 /* clear MSR_EE in r0 */ + mtmsr r0 /* hard disable */ + + mftb r3 + rldicl r4,r3,0,32 + rldicl r3,r3,32,32 + + mtmsr r5 /* restore MSR_EE */ + blr + +/* void __save_flags(unsigned long *flags) */ +_GLOBAL(__save_flags_ptr) + mfspr r4,SPRG1 /* Get Paca pointer */ + lbz r4,PACAPROCENABLED(r4) + stw r4,0(r3) + blr +_GLOBAL(__save_flags_ptr_end) + +/* void __restore_flags(unsigned long flags) */ +_GLOBAL(__restore_flags) + cmpi 0,r3,0 /* Are we enabling? */ + beq 0f /* No - then skip interrupt checks */ + +3: + mfspr r4,SPRG1 + lbz r4,PACAPROCENABLED(r4) + cmpi 0,r4,0 /* Are we already enabled? */ + bne 0f /* Yes - then skip interrupt checks */ + + CHECKDECR(r4,r5) + bne- do_fake_decrementer + + CHECKLPQUEUE(r4,r5,r6) + bne- do_lost_interrupts +2: + mfmsr r0 + rlwinm r0,r0,0,17,15 /* hard disable */ + mtmsr r0 + + CHECKANYINT(r4,r5,r6) + ori r0,r0,MSR_EE + beq 1f + mtmsr r0 /* hard enable */ + b 3b /* process more interrupts */ +1: + mfspr r4,SPRG1 + stb r3,PACAPROCENABLED(r4) + mtmsr r0 /* hard enable */ + blr +0: + mfspr r4,SPRG1 + stb r3,PACAPROCENABLED(r4) + blr +_GLOBAL(__restore_flags_end) + +_GLOBAL(__cli) + mfspr r4,SPRG1 + li r3,0 + stb r3,PACAPROCENABLED(r4) + blr /* Done */ +_GLOBAL(__cli_end) + +_GLOBAL(__sti) + li r3,1 + b __restore_flags +_GLOBAL(__sti_end) + +/* + * We were about to enable interrupts but we have to simulate + * some interrupts that were lost by enable_irq first. + */ +_GLOBAL(do_lost_interrupts) + stwu r1,-32(r1) + mflr r0 + stw r0,36(r1) + stw r3,28(r1) +1: bl fake_interrupt + bl check_softirqs + mfmsr r0 + rlwinm r0,r0,0,17,15 /* hard disable */ + mtmsr r0 + + CHECKANYINT(r4,r5,r6) + ori r0,r0,MSR_EE + beq 2f + mtmsr r0 /* hard enable */ + b 1b /* process more interrupts */ + +2: lwz r3,28(r1) + mfspr r4,SPRG1 + stb r3,PACAPROCENABLED(r4) /* restore soft interrupt state */ + mtmsr r0 /* hard enable */ + lwz r0,36(r1) + mtlr r0 + + addi r1,r1,32 + blr + +/* + * Simulate a decrementer interrupt + */ +do_fake_decrementer: + stwu r1,-32(r1) + mflr r0 + stw r0,36(r1) + stw r3,28(r1) + bl fake_decrementer + bl check_softirqs + lwz r0,36(r1) + mtlr r0 + + lwz r3,28(r1) + addi r1,r1,32 + + mfmsr r0 /* hard disable */ + rlwinm r0,r0,0,17,15 + mtmsr r0 + + CHECKANYINT(r4,r5,r6) /* Check for any interrupts pending */ + ori r0,r0,MSR_EE + beq 1f + mtmsr r0 /* hard enable */ + b do_lost_interrupts /* Handle more interrupts */ + +1: mfspr r4,SPRG1 + stb r3,PACAPROCENABLED(r4) /* soft enable */ + mtmsr r0 /* hard enable */ + blr + +/* + * do softirqs if necessary + */ +check_softirqs: + stwu r1,-32(r1) + mflr r0 + stw r0,36(r1) + + lis r4,irq_stat@ha + addi r4,r4,irq_stat@l +#ifdef CONFIG_SMP + lwz r3,CPU(r2) + slwi r3,r3,7 + add r4,r4,r3 +#endif + lwz r5,0(r4) + lwz r4,4(r4) + and. r5,r5,r4 + beq+ 2f + bl do_softirq +2: + lwz r0,36(r1) + mtlr r0 + + addi r1,r1,32 + blr + + +/* + * Write any modified data cache blocks out to memory + * and invalidate the corresponding instruction cache blocks. + * + * flush_icache_range(unsigned long start, unsigned long stop) + */ + +_GLOBAL(flush_icache_range) + + +/* + * Flush the data cache to memory + * + * Different models of iSeries's have different cache line sizes + * and in some cases i-cache and d-cache line sizes differ from + * each other. + */ + + lis r7,iSeries_dcache_line_size@ha + lhz r7,iSeries_dcache_line_size@l(r7) + addi r5,r7,-1 + andc r6,r3,r5 /* round low to line bdy */ + subf r8,r6,r4 /* compute length */ + add r8,r8,r5 /* ensure we get enough */ + lis r9,iSeries_log_dcache_line_size@ha + lhz r9,iSeries_log_dcache_line_size@l(r9) + srw. r8,r8,r9 /* compute line count */ + beqlr /* nothing to do? */ + mtctr r8 +1: dcbst 0,r6 + add r6,r6,r7 + bdnz 1b + sync + +/* Now invalidate the instruction cache */ + + lis r7,iSeries_icache_line_size@ha + lhz r7,iSeries_icache_line_size@l(r7) + addi r5,r7,-1 + andc r6,r3,r5 /* round low to line bdy */ + subf r8,r6,r4 /* compute length */ + add r8,r8,r5 + lis r9,iSeries_log_icache_line_size@ha + lhz r9,iSeries_log_icache_line_size@l(r9) + srw. r8,r8,r9 /* compute line count */ + beqlr /* nothing to do? */ + mtctr r8 +2: icbi 0,r6 + add r6,r6,r7 + bdnz 2b + sync + isync + blr + + +/* + * Like above, but only do the D-cache. + * + * flush_dcache_range(unsigned long start, unsigned long stop) + */ +_GLOBAL(flush_dcache_range) + +/* + * Flush the data cache to memory + * + * Different models of iSeries's have different cache line sizes + */ + + lis r7,iSeries_dcache_line_size@ha + lhz r7,iSeries_dcache_line_size@l(r7) + addi r5,r7,-1 + andc r6,r3,r5 /* round low to line bdy */ + subf r8,r6,r4 /* compute length */ + add r8,r8,r5 /* ensure we get enough */ + lis r9,iSeries_log_dcache_line_size@ha + lhz r9,iSeries_log_dcache_line_size@l(r9) + srw. r8,r8,r9 /* compute line count */ + beqlr /* nothing to do? */ + mtctr r8 +0: dcbst 0,r6 + add r6,r6,r7 + bdnz 0b + sync + blr + + +/* + * Flush a particular page from the data cache to RAM. + * Note: this is necessary because the instruction cache does *not* + * snoop from the data cache. + * + * void __flush_page_to_ram(void *page) + * void __flush_dcache_icache(void *page) + */ +_GLOBAL(__flush_page_to_ram) +_GLOBAL(__flush_dcache_icache) + +/* + * Flush the data cache to memory + * + * Different models of iSeries's have different cache line sizes + */ + +/* Flush the dcache */ + + rlwinm r3,r3,0,0,19 /* Page align */ + lis r4,iSeries_dcache_lines_per_page@ha + lhz r4,iSeries_dcache_lines_per_page@l(r4) + lis r5,iSeries_dcache_line_size@ha + lhz r5,iSeries_dcache_line_size@l(r5) + mr r6,r3 + mtctr r4 +0: dcbst 0,r6 + add r6,r6,r5 + bdnz 0b + sync + +/* Now invalidate the icache */ + + lis r4,iSeries_icache_lines_per_page@ha + lhz r4,iSeries_icache_lines_per_page@l(r4) + lis r5,iSeries_icache_line_size@ha + lhz r5,iSeries_icache_line_size@l(r5) + mtctr r4 +1: icbi 0,r3 + add r3,r3,r5 + bdnz 1b + sync + isync + blr + + +/* + * Flush a particular page from the instruction cache. + * Note: this is necessary because the instruction cache does *not* + * snoop from the data cache. + * + * void __flush_icache_page(void *page) + */ +_GLOBAL(__flush_icache_page) + + +/* + * Different models of iSeries's have different cache line sizes + */ + +/* Invalidate the icache */ + + rlwinm r3,r3,0,0,19 /* Page align */ + lis r4,iSeries_icache_lines_per_page@ha + lhz r4,iSeries_icache_lines_per_page@l(r4) + lis r5,iSeries_icache_line_size@ha + lhz r5,iSeries_icache_line_size@l(r5) + mtctr r4 +1: icbi 0,r3 + add r3,r3,r5 + bdnz 1b + sync + isync + blr + +/* + * Clear a page using the dcbz instruction, which doesn't cause any + * memory traffic (except to write out any cache lines which get + * displaced). This only works on cacheable memory. + */ +_GLOBAL(clear_page) + + rlwinm r3,r3,0,0,19 /* Page align */ + lis r4,iSeries_dcache_lines_per_page@ha + lhz r4,iSeries_dcache_lines_per_page@l(r4) + lis r5,iSeries_dcache_line_size@ha + lhz r5,iSeries_dcache_line_size@l(r5) + mtctr r4 +0: dcbz 0,r3 + add r3,r3,r5 + bdnz 0b + blr + + +/* + * Copy a whole page. We use the dcbz instruction on the destination + * to reduce memory traffic (it eliminates the unnecessary reads of + * the destination into cache). This requires that the destination + * is cacheable. + */ +#define COPY_16_BYTES \ + lwz r6,4(r4); \ + lwz r7,8(r4); \ + lwz r8,12(r4); \ + lwzu r9,16(r4); \ + stw r6,4(r3); \ + stw r7,8(r3); \ + stw r8,12(r3); \ + stwu r9,16(r3) + +_GLOBAL(copy_page) + + rlwinm r3,r3,0,0,19 /* Page align */ + rlwinm r4,r4,0,0,19 + lis r5,iSeries_dcache_lines_per_page@ha + lhz r5,iSeries_dcache_lines_per_page@l(r5) + lis r6,iSeries_dcache_line_size@ha + lhz r0,iSeries_dcache_line_size@l(r6) + mtctr r5 + addi r3,r3,-4 + addi r4,r4,-4 + li r10,4 + + cmpi 0,r0,32 + beq do_32_byte_line + cmpi 0,r0,64 + beq do_64_byte_line + cmpi 0,r0,128 + beq do_128_byte_line + + /* We don't have code specifically for this cache line size */ + /* Assume that the cache line size is at least 16 (and of */ + /* course a multiple of 16) */ + /* This code will work for all power-of-2 cache line sizes */ + /* from 16 to 4096 */ + +1: mr r5,r0 + dcbz r10,r3 +0: COPY_16_BYTES + addi r5,r5,-16 + or. r5,r5,r5 + bne 0b + bdnz 1b + blr + +do_32_byte_line: + dcbz r10,r3 + COPY_16_BYTES + COPY_16_BYTES + bdnz do_32_byte_line + blr + +do_64_byte_line: + dcbz r10,r3 + COPY_16_BYTES + COPY_16_BYTES + COPY_16_BYTES + COPY_16_BYTES + bdnz do_64_byte_line + blr + +do_128_byte_line: + dcbz r10,r3 + COPY_16_BYTES + COPY_16_BYTES + COPY_16_BYTES + COPY_16_BYTES + COPY_16_BYTES + COPY_16_BYTES + COPY_16_BYTES + COPY_16_BYTES + bdnz do_128_byte_line + blr diff --git a/arch/ppc/kernel/idle.c b/arch/ppc/kernel/idle.c index 2d93e549ccea..e6f2230d835f 100644 --- a/arch/ppc/kernel/idle.c +++ b/arch/ppc/kernel/idle.c @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.idle.c 1.16 10/16/01 15:58:42 trini + * BK Id: %F% %I% %G% %U% %#% */ /* * Idle daemon for PowerPC. Idle daemon will handle any action @@ -32,6 +32,20 @@ #include <asm/mmu.h> #include <asm/cache.h> #include <asm/cputable.h> +#ifdef CONFIG_PPC_ISERIES +#include <asm/time.h> +#include <asm/iSeries/LparData.h> +#include <asm/iSeries/HvCall.h> +#include <asm/hardirq.h> + +static void yield_shared_processor(void); +static void run_light_on(int on); + +extern unsigned long yield_count; + +#else /* CONFIG_PPC_ISERIES */ +#define run_light_on(x) do { } while (0) +#endif /* CONFIG_PPC_ISERIES */ void zero_paged(void); void power_save(void); @@ -53,21 +67,27 @@ int idled(void) do_power_save = 1; /* endless loop with no priority at all */ - current->nice = 20; - init_idle(); for (;;) { +#ifdef CONFIG_PPC_ISERIES + if (!current->need_resched) { + /* Turn off the run light */ + run_light_on(0); + yield_shared_processor(); + } + HMT_low(); +#endif #ifdef CONFIG_SMP - if (!do_power_save) { /* * Deal with another CPU just having chosen a thread to * run here: */ - int oldval = xchg(¤t->need_resched, -1); + unsigned long oldval; - if (!oldval) { - while (need_resched()) - barrier(); /* Do Nothing */ + oldval = xchg(¤t->work, 0xff000000); + if (!(oldval & 0xff000000)) { + while (current->work.need_resched == -1) + barrier(); /* Do Nothing */ } } #endif @@ -75,9 +95,17 @@ int idled(void) power_save(); if (need_resched()) { + run_light_on(1); schedule(); check_pgt_cache(); } +#ifdef CONFIG_PPC_ISERIES + else { + run_light_on(0); + yield_shared_processor(); + HMT_low(); + } +#endif /* CONFIG_PPC_ISERIES */ } return 0; } @@ -108,6 +136,7 @@ unsigned long get_zero_page_fast(void) register unsigned long tmp; asm ( "101:lwarx %1,0,%3\n" /* reserve zero_cache */ " lwz %0,0(%1)\n" /* get next -- new zero_cache */ + PPC405_ERR77(0,%3) " stwcx. %0,0,%3\n" /* update zero_cache */ " bne- 101b\n" /* if lost reservation try again */ : "=&r" (tmp), "=&r" (page), "+m" (zero_cache) @@ -205,6 +234,7 @@ void zero_paged(void) #ifdef CONFIG_SMP " sync\n" /* let store settle */ #endif + PPC405_ERR77(0,%2) " stwcx. %3,0,%2\n" /* update zero_cache in mem */ " bne- 101b\n" /* if lost reservation try again */ : "=&r" (tmp), "+m" (zero_quicklist) @@ -228,6 +258,13 @@ void zero_paged(void) void power_save(void) { unsigned long hid0; + int nap = powersave_nap; + + /* 7450 has no DOZE mode mode, we return if powersave_nap + * isn't enabled + */ + if (!nap && cur_cpu_spec[smp_processor_id()]->cpu_features & CPU_FTR_SPEC7450) + return; /* * Disable interrupts to prevent a lost wakeup * when going to sleep. This is necessary even with @@ -255,3 +292,64 @@ void power_save(void) _nmask_and_or_msr(0, MSR_EE); } +#ifdef CONFIG_PPC_ISERIES + +extern void fake_interrupt(void); +extern u64 get_tb64(void); + +void run_light_on(int on) +{ + unsigned long CTRL; + + CTRL = mfspr(CTRLF); + CTRL = on? (CTRL | RUNLATCH): (CTRL & ~RUNLATCH); + mtspr(CTRLT, CTRL); +} + +void yield_shared_processor(void) +{ + struct Paca *paca; + u64 tb; + + /* Poll for I/O events */ + __cli(); + __sti(); + + paca = (struct Paca *)mfspr(SPRG1); + if ( paca->xLpPaca.xSharedProc ) { + HvCall_setEnabledInterrupts( HvCall_MaskIPI | + HvCall_MaskLpEvent | + HvCall_MaskLpProd | + HvCall_MaskTimeout ); + + /* + * Check here for any of the above pending... + * IPI and Decrementers are indicated in ItLpPaca + * LpEvents are indicated on the LpQueue + * + * Disabling/enabling will check for LpEvents, IPIs + * and decrementers + */ + __cli(); + __sti(); + + ++yield_count; + + /* Get current tb value */ + tb = get_tb64(); + /* Compute future tb value when yield will expire */ + tb += tb_ticks_per_jiffy; + HvCall_yieldProcessor( HvCall_YieldTimed, tb ); + + /* Check here for any of the above pending or timeout expired*/ + __cli(); + /* + * The decrementer stops during the yield. Just force + * a fake decrementer now and the timer_interrupt + * code will straighten it all out + */ + paca->xLpPaca.xDecrInt = 1; + __sti(); + } +} +#endif /* CONFIG_PPC_ISERIES */ diff --git a/arch/ppc/kernel/indirect_pci.c b/arch/ppc/kernel/indirect_pci.c index b79ceee3c5db..0addbd871bef 100644 --- a/arch/ppc/kernel/indirect_pci.c +++ b/arch/ppc/kernel/indirect_pci.c @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.indirect_pci.c 1.10 09/08/01 15:47:42 paulus + * BK Id: %F% %I% %G% %U% %#% */ /* * Support for indirect PCI bridges. @@ -24,8 +24,6 @@ #include <asm/pci-bridge.h> #include <asm/machdep.h> -#include "pci.h" - #define cfg_read(val, addr, type, op) *val = op((type)(addr)) #define cfg_write(val, addr, type, op) op((type *)(addr), (val)) @@ -35,9 +33,13 @@ indirect_##rw##_config_##size(struct pci_dev *dev, int offset, type val) \ { \ struct pci_controller *hose = dev->sysdata; \ \ + if (ppc_md.pci_exclude_device) \ + if (ppc_md.pci_exclude_device(dev->bus->number, dev->devfn)) \ + return PCIBIOS_DEVICE_NOT_FOUND; \ + \ out_be32(hose->cfg_addr, \ ((offset & 0xfc) << 24) | (dev->devfn << 16) \ - | (dev->bus->number << 8) | 0x80); \ + | ((dev->bus->number - hose->bus_offset) << 8) | 0x80); \ cfg_##rw(val, hose->cfg_data + (offset & mask), type, op); \ return PCIBIOS_SUCCESSFUL; \ } diff --git a/arch/ppc/kernel/irq.c b/arch/ppc/kernel/irq.c index c5f422016adf..5c5e37aabb0e 100644 --- a/arch/ppc/kernel/irq.c +++ b/arch/ppc/kernel/irq.c @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.irq.c 1.32 08/24/01 20:07:37 paulus + * BK Id: %F% %I% %G% %U% %#% */ /* * arch/ppc/kernel/irq.c @@ -51,20 +51,15 @@ #include <asm/uaccess.h> #include <asm/bitops.h> -#include <asm/hydra.h> #include <asm/system.h> #include <asm/io.h> #include <asm/pgtable.h> #include <asm/irq.h> -#include <asm/gg2.h> #include <asm/cache.h> #include <asm/prom.h> -#include <asm/amigaints.h> -#include <asm/amigahw.h> -#include <asm/amigappc.h> #include <asm/ptrace.h> -#include "local_irq.h" +#define NR_MASK_WORDS ((NR_IRQS + 31) / 32) extern atomic_t ipi_recv; extern atomic_t ipi_sent; @@ -190,9 +185,6 @@ setup_irq(unsigned int irq, struct irqaction * new) * now, this is what I need. -- Dan */ #define request_irq request_8xxirq -#elif defined(CONFIG_APUS) -#define request_irq request_sysirq -#define free_irq sys_free_irq #endif void free_irq(unsigned int irq, void* dev_id) @@ -374,15 +366,12 @@ void enable_irq(unsigned int irq) int show_interrupts(struct seq_file *p, void *v) { -#ifdef CONFIG_APUS - return show_apus_interrupts(p, v); -#else int i, j; struct irqaction * action; seq_puts(p, " "); for (j=0; j<smp_num_cpus; j++) - seq_printf(p, "CPU%d ",j); + seq_printf(p, "CPU%d ", j); seq_putc(p, '\n'); for (i = 0 ; i < NR_IRQS ; i++) { @@ -393,38 +382,35 @@ int show_interrupts(struct seq_file *p, void *v) #ifdef CONFIG_SMP for (j = 0; j < smp_num_cpus; j++) seq_printf(p, "%10u ", - kstat.irqs[cpu_logical_map(j)][i]); + kstat.irqs[cpu_logical_map(j)][i]); #else seq_printf(p, "%10u ", kstat_irqs(i)); #endif /* CONFIG_SMP */ - if ( irq_desc[i].handler ) - seq_printf(p, " %s ", irq_desc[i].handler->typename ); + if (irq_desc[i].handler) + seq_printf(p, " %s ", irq_desc[i].handler->typename); else seq_puts(p, " None "); seq_printf(p, "%s", (irq_desc[i].status & IRQ_LEVEL) ? "Level " : "Edge "); - seq_printf(p, " %s",action->name); - for (action=action->next; action; action = action->next) { + seq_printf(p, " %s", action->name); + for (action = action->next; action; action = action->next) seq_printf(p, ", %s", action->name); - } seq_putc(p, '\n'); } #ifdef CONFIG_TAU_INT if (tau_initialized){ seq_puts(p, "TAU: "); for (j = 0; j < smp_num_cpus; j++) - seq_printf(p, "%10u ", - tau_interrupts(j)); + seq_printf(p, "%10u ", tau_interrupts(j)); seq_puts(p, " PowerPC Thermal Assist (cpu temp)\n"); } #endif #ifdef CONFIG_SMP /* should this be per processor send/receive? */ seq_printf(p, "IPI (recv/sent): %10u/%u\n", - atomic_read(&ipi_recv), atomic_read(&ipi_sent)); + atomic_read(&ipi_recv), atomic_read(&ipi_sent)); #endif seq_printf(p, "BAD: %10u\n", ppc_spurious_interrupts); return 0; -#endif /* CONFIG_APUS */ } static inline void @@ -535,31 +521,35 @@ out: spin_unlock(&desc->lock); } +#ifndef CONFIG_PPC_ISERIES /* iSeries version is in iSeries_pic.c */ int do_IRQ(struct pt_regs *regs) { int cpu = smp_processor_id(); - int irq; - hardirq_enter(cpu); - - /* every arch is required to have a get_irq -- Cort */ - irq = ppc_md.get_irq(regs); - - if (irq >= 0) { - ppc_irq_dispatch_handler( regs, irq ); - } else if (irq != -2) { - /* -2 means ignore, already handled */ - if (ppc_spurious_interrupts < 10) - printk(KERN_DEBUG "Bogus interrupt %d from PC = %lx\n", - irq, regs->nip); + int irq, first = 1; + hardirq_enter( cpu ); + + /* + * Every platform is required to implement ppc_md.get_irq. + * This function will either return an irq number or -1 to + * indicate there are no more pending. But the first time + * through the loop this means there wasn't and IRQ pending. + * The value -2 is for buggy hardware and means that this IRQ + * has already been handled. -- Tom + */ + while ((irq = ppc_md.get_irq(regs)) >= 0) { + ppc_irq_dispatch_handler(regs, irq); + first = 0; + } + if (irq != -2 && first) /* That's not SMP safe ... but who cares ? */ ppc_spurious_interrupts++; - } hardirq_exit( cpu ); if (softirq_pending(cpu)) do_softirq(); return 1; /* lets ret_from_int know we can do checks */ } +#endif /* CONFIG_PPC_ISERIES */ unsigned long probe_irq_on (void) { @@ -591,7 +581,6 @@ void __init init_IRQ(void) #ifdef CONFIG_SMP unsigned char global_irq_holder = NO_PROC_ID; unsigned volatile long global_irq_lock; /* pendantic :long for set_bit--RR*/ -atomic_t global_irq_count; atomic_t global_bh_count; @@ -602,8 +591,7 @@ static void show(char * str) int cpu = smp_processor_id(); printk("\n%s, CPU %d:\n", str, cpu); - printk("irq: %d [%d %d]\n", - atomic_read(&global_irq_count), + printk("irq: [%d %d]\n", local_irq_count(0), local_irq_count(1)); printk("bh: %d [%d %d]\n", @@ -643,11 +631,9 @@ static inline void wait_on_irq(int cpu) * for bottom half handlers unless we're * already executing in one.. */ - if (!atomic_read(&global_irq_count)) { - if (local_bh_count(cpu) - || !atomic_read(&global_bh_count)) - break; - } + if (!irqs_running()) + if (local_bh_count(cpu) || !spin_is_locked(&global_bh_lock)) + break; /* Duh, we have to loop. Release the lock to avoid deadlocks */ clear_bit(0,&global_irq_lock); @@ -658,16 +644,19 @@ static inline void wait_on_irq(int cpu) count = ~0; } __sti(); - /* don't worry about the lock race Linus found - * on intel here. -- Cort + /* + * We have to allow irqs to arrive between __sti and __cli + * Some cpus apparently won't cause the interrupt + * for several instructions. We hope that isync will + * catch this --Troy */ + __asm__ __volatile__ ("isync"); __cli(); - if (atomic_read(&global_irq_count)) + if (irqs_running()) continue; if (global_irq_lock) continue; - if (!local_bh_count(cpu) - && atomic_read(&global_bh_count)) + if (!local_bh_count(cpu) && spin_is_locked(&global_bh_lock)) continue; if (!test_and_set_bit(0,&global_irq_lock)) break; @@ -698,7 +687,7 @@ void synchronize_bh(void) */ void synchronize_irq(void) { - if (atomic_read(&global_irq_count)) { + if (irqs_running()) { /* Stupid approach */ cli(); sti(); diff --git a/arch/ppc/kernel/l2cr.S b/arch/ppc/kernel/l2cr.S index d208577bca00..b3ec25cca703 100644 --- a/arch/ppc/kernel/l2cr.S +++ b/arch/ppc/kernel/l2cr.S @@ -30,13 +30,19 @@ *********** Thu, July 13, 2000. - Terry: Added isync to correct for an errata. + + 22 August 2001. + - DanM: Finally added the 7450 patch I've had for the past + several months. The L2CR is similar, but I'm going + to assume the user of this functions knows what they + are doing. Author: Terry Greeniaus (tgree@phys.ualberta.ca) Please e-mail updates to this file to me, thanks! */ #include <asm/processor.h> #include <asm/cputable.h> -#include "ppc_asm.h" +#include <asm/ppc_asm.h> /* Usage: @@ -71,6 +77,15 @@ features, such as L2DO which caches only data, or L2TS which causes cache pushes from the L1 cache to go to the L2 cache instead of to main memory. + +IMPORTANT: + Starting with the 7450, the bits in this register have moved + or behave differently. The Enable, Parity Enable, Size, + and L2 Invalidate are the only bits that have not moved. + The size is read-only for these processors with internal L2 + cache, and the invalidate is a control as well as status. + -- Dan + */ /* * Summary: this procedure ignores the L2I bit in the value passed in, @@ -115,6 +130,8 @@ END_FTR_SECTION_IFCLR(CPU_FTR_L2CR) /**** Might be a good idea to set L2DO here - to prevent instructions from getting into the cache. But since we invalidate the next time we enable the cache it doesn't really matter. + Don't do this unless you accomodate all processor variations. + The bit moved on the 7450..... ****/ lis r4,0x0002 @@ -159,12 +176,21 @@ END_FTR_SECTION_IFCLR(CPU_FTR_L2CR) sync isync /* For errata */ +BEGIN_FTR_SECTION + /* On the 7450, we wait for the L2I bit to clear...... + */ +10: mfspr r3,L2CR + andis. r4,r3,0x0020 + bne 10b + b 11f +END_FTR_SECTION_IFSET(CPU_FTR_SPEC7450) + /* Wait for the invalidation to complete */ 3: mfspr r3,L2CR rlwinm. r4,r3,0,31,31 bne 3b - rlwinm r3,r3,0,11,9 /* Turn off the L2I bit */ +11: rlwinm r3,r3,0,11,9 /* Turn off the L2I bit */ sync mtspr L2CR,r3 sync diff --git a/arch/ppc/kernel/local_irq.h b/arch/ppc/kernel/local_irq.h deleted file mode 100644 index 045e864a476d..000000000000 --- a/arch/ppc/kernel/local_irq.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * BK Id: SCCS/s.local_irq.h 1.7 05/17/01 18:14:21 cort - */ - -#ifndef _PPC_KERNEL_LOCAL_IRQ_H -#define _PPC_KERNEL_LOCAL_IRQ_H - -#include <linux/kernel_stat.h> -#include <linux/interrupt.h> -#include <linux/cache.h> -#include <linux/spinlock.h> -#include <linux/irq.h> - -void ppc_irq_dispatch_handler(struct pt_regs *regs, int irq); - -#define NR_MASK_WORDS ((NR_IRQS + 31) / 32) - -extern int ppc_spurious_interrupts; -extern int ppc_second_irq; -extern struct irqaction *ppc_irq_action[NR_IRQS]; - -#endif /* _PPC_KERNEL_LOCAL_IRQ_H */ diff --git a/arch/ppc/kernel/m8260_setup.c b/arch/ppc/kernel/m8260_setup.c index dfdfb004dadd..a05530474cfd 100644 --- a/arch/ppc/kernel/m8260_setup.c +++ b/arch/ppc/kernel/m8260_setup.c @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.m8260_setup.c 1.30 11/13/01 21:26:07 paulus + * BK Id: %F% %I% %G% %U% %#% */ /* * linux/arch/ppc/kernel/setup.c @@ -45,8 +45,9 @@ #include <asm/mpc8260.h> #include <asm/immap_8260.h> #include <asm/machdep.h> - +#include <asm/bootinfo.h> #include <asm/time.h> + #include "ppc8260_pic.h" static int m8260_set_rtc_time(unsigned long time); @@ -98,17 +99,25 @@ static uint rtc_time; static static int m8260_set_rtc_time(unsigned long time) { +#ifdef CONFIG_TQM8260 + ((immap_t *)IMAP_ADDR)->im_sit.sit_tmcnt = time; + ((immap_t *)IMAP_ADDR)->im_sit.sit_tmcntsc = 0x3; +#else rtc_time = time; +#endif return(0); } static unsigned long m8260_get_rtc_time(void) { - +#ifdef CONFIG_TQM8260 + return ((immap_t *)IMAP_ADDR)->im_sit.sit_tmcnt; +#else /* Get time from the RTC. */ return((unsigned long)rtc_time); +#endif } static void @@ -121,8 +130,11 @@ m8260_restart(char *cmd) * of the reset vector. If that doesn't work for you, change this * or the reboot program to send a proper address. */ +#ifdef CONFIG_TQM8260 + startaddr = 0x40000104; +#else startaddr = 0xff000104; - +#endif if (cmd != NULL) { if (!strncmp(cmd, "startaddr=", 10)) startaddr = simple_strtoul(&cmd[10], NULL, 0); @@ -150,14 +162,13 @@ m8260_show_percpuinfo(struct seq_file *m, int i) bd_t *bp; bp = (bd_t *)__res; - + seq_printf(m, "core clock\t: %d MHz\n" "CPM clock\t: %d MHz\n" "bus clock\t: %d MHz\n", bp->bi_intfreq / 1000000, bp->bi_cpmfreq / 1000000, bp->bi_busfreq / 1000000); - return 0; } @@ -178,7 +189,7 @@ m8260_init_IRQ(void) #endif for ( i = 0 ; i < NR_SIU_INTS ; i++ ) irq_desc[i].handler = &ppc8260_pic; - + /* Initialize the default interrupt mapping priorities, * in case the boot rom changed something on us. */ @@ -197,7 +208,7 @@ m8260_find_end_of_memory(void) { bd_t *binfo; extern unsigned char __res[]; - + binfo = (bd_t *)__res; return binfo->bi_memsize; @@ -219,22 +230,20 @@ void __init platform_init(unsigned long r3, unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7) { + parse_bootinfo(find_bootinfo()); if ( r3 ) memcpy( (void *)__res,(void *)(r3+KERNELBASE), sizeof(bd_t) ); - + #ifdef CONFIG_BLK_DEV_INITRD /* take care of initrd if we have one */ - if ( r4 ) - { + if ( r4 ) { initrd_start = r4 + KERNELBASE; initrd_end = r5 + KERNELBASE; } #endif /* CONFIG_BLK_DEV_INITRD */ /* take care of cmd line */ - if ( r6 ) - { - + if ( r6 ) { *(char *)(r7+KERNELBASE) = 0; strcpy(cmd_line, (char *)(r6+KERNELBASE)); } diff --git a/arch/ppc/kernel/m8xx_setup.c b/arch/ppc/kernel/m8xx_setup.c index ace85d3dcf69..dade12003a8a 100644 --- a/arch/ppc/kernel/m8xx_setup.c +++ b/arch/ppc/kernel/m8xx_setup.c @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.m8xx_setup.c 1.40 11/13/01 21:26:07 paulus + * BK Id: %F% %I% %G% %U% %#% * * linux/arch/ppc/kernel/setup.c * @@ -43,8 +43,9 @@ #include <asm/mpc8xx.h> #include <asm/8xx_immap.h> #include <asm/machdep.h> - +#include <asm/bootinfo.h> #include <asm/time.h> + #include "ppc8xx_pic.h" static int m8xx_set_rtc_time(unsigned long time); @@ -57,25 +58,30 @@ extern void m8xx_ide_init(void); extern unsigned long find_available_memory(void); extern void m8xx_cpm_reset(uint); +extern void rpxfb_alloc_pages(void); void __init m8xx_setup_arch(void) { int cpm_page; - + cpm_page = (int) alloc_bootmem_pages(PAGE_SIZE); - + /* Reset the Communication Processor Module. */ m8xx_cpm_reset(cpm_page); +#ifdef CONFIG_FB_RPX + rpxfb_alloc_pages(); +#endif + #ifdef notdef ROOT_DEV = to_kdev_t(0x0301); /* hda1 */ #endif - + #ifdef CONFIG_BLK_DEV_INITRD #if 0 - ROOT_DEV = to_kdev_t(0x0200); /* floppy */ + ROOT_DEV = to_kdev_t(0x0200); /* floppy */ rd_prompt = 1; rd_doload = 1; rd_image_start = 0; @@ -105,6 +111,9 @@ abort(void) xmon(0); #endif machine_restart(NULL); + + /* not reached */ + for (;;); } /* A place holder for time base interrupts, if they are ever enabled. */ @@ -217,7 +226,7 @@ m8xx_restart(char *cmd) __asm__("mtmsr %0" : : "r" (msr) ); dummy = ((immap_t *)IMAP_ADDR)->im_clkrst.res[0]; - printk("Restart failed\n"); + printk("Restart failed\n"); while(1); } @@ -240,9 +249,9 @@ m8xx_show_percpuinfo(struct seq_file *m, int i) bd_t *bp; bp = (bd_t *)__res; - - seq_printf(m, "clock\t\t: %ldMHz\n" - "bus clock\t: %ldMHz\n", + + seq_printf(m, "clock\t\t: %dMHz\n" + "bus clock\t: %dMHz\n", bp->bi_intfreq / 1000000, bp->bi_busfreq / 1000000); @@ -263,7 +272,7 @@ m8xx_init_IRQ(void) for ( i = 0 ; i < NR_SIU_INTS ; i++ ) irq_desc[i].handler = &ppc8xx_pic; - + /* We could probably incorporate the CPM into the multilevel * interrupt structure. */ @@ -296,7 +305,7 @@ m8xx_find_end_of_memory(void) { bd_t *binfo; extern unsigned char __res[]; - + binfo = (bd_t *)__res; return binfo->bi_memsize; @@ -343,9 +352,11 @@ void __init platform_init(unsigned long r3, unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7) { + parse_bootinfo(find_bootinfo()); + if ( r3 ) memcpy( (void *)__res,(void *)(r3+KERNELBASE), sizeof(bd_t) ); - + #ifdef CONFIG_PCI m8xx_setup_pci_ptrs(); #endif @@ -360,7 +371,7 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5, #endif /* CONFIG_BLK_DEV_INITRD */ /* take care of cmd line */ if ( r6 ) - { + { *(char *)(r7+KERNELBASE) = 0; strcpy(cmd_line, (char *)(r6+KERNELBASE)); } @@ -394,5 +405,5 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5, #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) m8xx_ide_init(); -#endif +#endif } diff --git a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S index 376fa23dc4b2..6e01a5c36d52 100644 --- a/arch/ppc/kernel/misc.S +++ b/arch/ppc/kernel/misc.S @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.misc.S 1.32 10/18/01 17:29:53 trini + * BK Id: %F% %I% %G% %U% %#% */ /* * This file contains miscellaneous low-level functions. @@ -23,7 +23,9 @@ #include <asm/page.h> #include <asm/cache.h> #include <asm/cputable.h> -#include "ppc_asm.h" +#include <asm/mmu.h> +#include <asm/ppc_asm.h> +#include "ppc_defs.h" .text @@ -39,7 +41,6 @@ _GLOBAL(__delay) * Returns (address we're running at) - (address we were linked at) * for use before the text and data are mapped to KERNELBASE. */ - _GLOBAL(reloc_offset) mflr r0 bl 1f @@ -51,6 +52,62 @@ _GLOBAL(reloc_offset) blr /* + * add_reloc_offset(x) returns x + reloc_offset(). + */ +_GLOBAL(add_reloc_offset) + mflr r0 + bl 1f +1: mflr r5 + lis r4,1b@ha + addi r4,r4,1b@l + subf r5,r4,r5 + add r3,r3,r5 + mtlr r0 + blr + +/* + * sub_reloc_offset(x) returns x - reloc_offset(). + */ +_GLOBAL(sub_reloc_offset) + mflr r0 + bl 1f +1: mflr r5 + lis r4,1b@ha + addi r4,r4,1b@l + subf r5,r4,r5 + subf r3,r5,r3 + mtlr r0 + blr + +/* + * reloc_got2 runs through the .got2 section adding an offset + * to each entry. + */ +_GLOBAL(reloc_got2) + mflr r11 + lis r7,__got2_start@ha + addi r7,r7,__got2_start@l + lis r8,__got2_end@ha + addi r8,r8,__got2_end@l + subf r8,r7,r8 + srwi. r8,r8,2 + beqlr + mtctr r8 + bl 1f +1: mflr r0 + lis r4,1b@ha + addi r4,r4,1b@l + subf r0,r4,r0 + add r7,r0,r7 +2: lwz r0,0(r7) + add r0,r0,r3 + stw r0,0(r7) + addi r7,r7,4 + bdnz 2b + mtlr r11 + blr + +/* * identify_cpu, * called with r3 = data offset and r4 = CPU number * doesn't change r3 @@ -81,6 +138,7 @@ _GLOBAL(identify_cpu) * r3 = data offset (not changed) */ _GLOBAL(do_cpu_ftr_fixups) +#ifndef CONFIG_PPC_ISERIES /* Get CPU 0 features */ addis r6,r3,cur_cpu_spec@ha addi r6,r6,cur_cpu_spec@l @@ -124,10 +182,16 @@ _GLOBAL(do_cpu_ftr_fixups) sync /* additional sync needed on g4 */ isync b 1b +#else /* CONFIG_PPC_ISERIES */ + blr +#endif /* CONFIG_PPC_ISERIES */ /* * call_setup_cpu - call the setup_cpu function for this cpu * r3 = data offset, r24 = cpu number + * + * Don't change register layout, the setup function may rely + * on r5 containing a relocated pointer to the current cpu spec. */ _GLOBAL(call_setup_cpu) addis r5,r3,cur_cpu_spec@ha @@ -141,6 +205,7 @@ _GLOBAL(call_setup_cpu) mr r3,r24 bctr +#ifndef CONFIG_PPC_ISERIES /* iSeries version is in iSeries_misc.S */ /* void __save_flags_ptr(unsigned long *flags) */ _GLOBAL(__save_flags_ptr) mfmsr r4 @@ -268,7 +333,7 @@ _GLOBAL(__sti) nop nop _GLOBAL(__sti_end) - +#endif /* CONFIG_PPC_ISERIES */ /* * complement mask on the msr then "or" some values on. @@ -288,6 +353,20 @@ _GLOBAL(_nmask_and_or_msr) * Flush MMU TLB */ _GLOBAL(_tlbia) +#if defined(CONFIG_4xx) && defined(CONFIG_PIN_TLB) + /* This needs to be coordinated with other pinning functions since + * we don't keep a memory location of number of entries to reduce + * cache pollution during these operations. + */ + lis r3, 0 + sync +1: + tlbwe r3, r3, TLB_TAG /* just ensure V is clear */ + addi r3, r3, 1 /* so r3 works fine for that */ + cmpwi 0, r3, 61 /* reserve last two entries */ + ble 1b + isync +#else #if defined(CONFIG_SMP) mfmsr r10 SYNC @@ -296,11 +375,12 @@ _GLOBAL(_tlbia) SYNC lis r9,hash_table_lock@h ori r9,r9,hash_table_lock@l - lwz r8,PROCESSOR(r2) + lwz r8,CPU(r2) oris r8,r8,10 10: lwarx r7,0,r9 cmpi 0,r7,0 bne- 10b + /* No 405 Erratum 77 fix needed here, because 4xx can't do SMP */ stwcx. r8,0,r9 bne- 10b #endif /* CONFIG_SMP */ @@ -314,12 +394,24 @@ _GLOBAL(_tlbia) mtmsr r10 SYNC #endif +#endif blr /* * Flush MMU TLB for a particular address */ _GLOBAL(_tlbie) +#ifdef CONFIG_4xx + tlbsx. r3, 0, r3 + bne 10f + sync + /* There are only 64 TLB entries, so r3 < 64, which means bit 25, is clear. + * Since 25 is the V bit in the TLB_TAG, loading this value will invalidate + * the TLB entry. */ + tlbwe r3, r3, TLB_TAG + isync +10: +#else #if defined(CONFIG_SMP) mfmsr r10 SYNC @@ -328,11 +420,12 @@ _GLOBAL(_tlbie) SYNC lis r9,hash_table_lock@h ori r9,r9,hash_table_lock@l - lwz r8,PROCESSOR(r2) + lwz r8,CPU(r2) oris r8,r8,11 10: lwarx r7,0,r9 cmpi 0,r7,0 bne- 10b + PPC405_ERR77(0,r9) stwcx. r8,0,r9 bne- 10b eieio @@ -346,6 +439,7 @@ _GLOBAL(_tlbie) mtmsr r10 SYNC #endif +#endif /* CONFIG_4xx */ blr /* @@ -358,8 +452,17 @@ _GLOBAL(flush_instruction_cache) lis r5, IDC_INVALL@h mtspr IC_CST, r5 #elif defined(CONFIG_4xx) +#ifdef CONFIG_403GCX + li r3, 512 + mtctr r3 + lis r4, KERNELBASE@h +1: iccci 0, r4 + addi r4, r4, 16 + bdnz 1b +#else lis r3, KERNELBASE@h iccci 0,r3 +#endif #else mfspr r3,PVR rlwinm r3,r3,16,16,31 @@ -369,10 +472,11 @@ _GLOBAL(flush_instruction_cache) mfspr r3,HID0 ori r3,r3,HID0_ICFI mtspr HID0,r3 -#endif /* CONFIG_8xx */ +#endif /* CONFIG_8xx/4xx */ isync blr +#ifndef CONFIG_PPC_ISERIES /* iSeries version is in iSeries_misc.S */ /* * Write any modified data cache blocks out to memory * and invalidate the corresponding instruction cache blocks. @@ -469,15 +573,40 @@ _GLOBAL(invalidate_dcache_range) sync /* wait for dcbi's to get to ram */ blr +#ifdef CONFIG_NOT_COHERENT_CACHE +/* This is a bad one....It is used by 'consistent_sync' functions when + * there isn't any handle on the virtual address needed by the usual + * cache flush instructions. On the MPC8xx, we can use the cache line + * flush command, on others all we can do is read enough data to completely + * reload the cache, flushing old data out. + */ + +/* Cache organization. The 4xx has a 8K (128 line) cache, and the 8xx + * has 1, 2, 4, 8K variants. For now, cover worst case. When we can + * deteremine actual size, we will use that later. + */ +#define CACHE_NWAYS 2 +#define CACHE_NLINES 128 + +_GLOBAL(flush_dcache_all) + li r4, (CACHE_NWAYS * CACHE_NLINES) + mtctr r4 + lis r5, KERNELBASE@h +1: lwz r3, 0(r5) /* Load one word from every line */ + addi r5, r5, L1_CACHE_LINE_SIZE + bdnz 1b + blr +#endif /* CONFIG_NOT_COHERENT_CACHE */ + /* * Flush a particular page from the data cache to RAM. * Note: this is necessary because the instruction cache does *not* * snoop from the data cache. * This is a no-op on the 601 which has a unified cache. * - * void __flush_page_to_ram(void *page) + * void __flush_dcache_icache(void *page) */ -_GLOBAL(__flush_page_to_ram) +_GLOBAL(__flush_dcache_icache) mfspr r5,PVR rlwinm r5,r5,16,16,31 cmpi 0,r5,1 @@ -497,28 +626,6 @@ _GLOBAL(__flush_page_to_ram) sync isync blr - -/* - * Flush a particular page from the instruction cache. - * Note: this is necessary because the instruction cache does *not* - * snoop from the data cache. - * This is a no-op on the 601 which has a unified cache. - * - * void __flush_icache_page(void *page) - */ -_GLOBAL(__flush_icache_page) - mfspr r5,PVR - rlwinm r5,r5,16,16,31 - cmpi 0,r5,1 - beqlr /* for 601, do nothing */ - li r4,4096/L1_CACHE_LINE_SIZE /* Number of lines in a page */ - mtctr r4 -1: icbi 0,r3 - addi r3,r3,L1_CACHE_LINE_SIZE - bdnz 1b - sync - isync - blr /* * Clear a page using the dcbz instruction, which doesn't cause any @@ -563,8 +670,8 @@ _GLOBAL(copy_page) li r5,4 #ifndef CONFIG_8xx -#if MAX_L1_COPY_PREFETCH > 1 - li r0,MAX_L1_COPY_PREFETCH +#if MAX_COPY_PREFETCH > 1 + li r0,MAX_COPY_PREFETCH li r11,4 mtctr r0 11: dcbt r11,r4 @@ -599,6 +706,7 @@ _GLOBAL(copy_page) #endif bdnz 1b blr +#endif /* CONFIG_PPC_ISERIES */ /* * Atomic [test&set] exchange @@ -610,6 +718,7 @@ _GLOBAL(copy_page) _GLOBAL(xchg_u32) mr r5,r3 /* Save pointer */ 10: lwarx r3,0,r5 /* Fetch old value & reserve */ + PPC405_ERR77(0,r5) stwcx. r4,0,r5 /* Update with new value */ bne- 10b /* Retry if "reservation" (i.e. lock) lost */ blr @@ -621,12 +730,14 @@ _GLOBAL(xchg_u32) _GLOBAL(atomic_clear_mask) 10: lwarx r5,0,r4 andc r5,r5,r3 + PPC405_ERR77(0,r4) stwcx. r5,0,r4 bne- 10b blr _GLOBAL(atomic_set_mask) 10: lwarx r5,0,r4 or r5,r5,r3 + PPC405_ERR77(0,r4) stwcx. r5,0,r4 bne- 10b blr @@ -866,10 +977,8 @@ _GLOBAL(kernel_thread) sc cmpi 0,r3,0 /* parent or child? */ bnelr /* return if parent */ - li r0,0 /* clear out p->thread.regs */ - stw r0,THREAD+PT_REGS(r2) /* since we don't have user ctx */ - addi r1,r2,TASK_UNION_SIZE-STACK_FRAME_OVERHEAD - stw r0,0(r1) + li r0,0 /* make top-level stack frame */ + stwu r0,-16(r1) mtlr r6 /* fn addr in lr */ mr r3,r4 /* load arg and call fn */ blrl diff --git a/arch/ppc/kernel/mk_defs.c b/arch/ppc/kernel/mk_defs.c index 2ff838e89c04..cdc35c4d363e 100644 --- a/arch/ppc/kernel/mk_defs.c +++ b/arch/ppc/kernel/mk_defs.c @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.mk_defs.c 1.11 08/19/01 22:43:23 paulus + * BK Id: %F% %I% %G% %U% %#% */ /* * This program is used to generate definitions needed by @@ -28,6 +28,13 @@ #include <asm/processor.h> #include <asm/cputable.h> +#ifdef CONFIG_PPC_ISERIES +#include <asm/iSeries/Paca.h> +#include <asm/iSeries/ItLpPaca.h> +#include <asm/iSeries/ItLpQueue.h> +#include <asm/iSeries/HvLpEvent.h> +#endif /* CONFIG_PPC_ISERIES */ + #define DEFINE(sym, val) \ asm volatile("\n#define\t" #sym "\t%0" : : "i" (val)) @@ -37,10 +44,8 @@ main(void) /*DEFINE(KERNELBASE, KERNELBASE);*/ DEFINE(STATE, offsetof(struct task_struct, state)); DEFINE(NEXT_TASK, offsetof(struct task_struct, next_task)); - DEFINE(COUNTER, offsetof(struct task_struct, counter)); - DEFINE(PROCESSOR, offsetof(struct task_struct, processor)); -#error DEFINE(SIGPENDING, offsetof(struct task_struct, sigpending)); DEFINE(THREAD, offsetof(struct task_struct, thread)); + DEFINE(CPU, offsetof(struct task_struct, cpu)); DEFINE(MM, offsetof(struct task_struct, mm)); DEFINE(ACTIVE_MM, offsetof(struct task_struct, active_mm)); DEFINE(TASK_STRUCT_SIZE, sizeof(struct task_struct)); @@ -48,10 +53,13 @@ main(void) DEFINE(PGDIR, offsetof(struct thread_struct, pgdir)); DEFINE(LAST_SYSCALL, offsetof(struct thread_struct, last_syscall)); DEFINE(PT_REGS, offsetof(struct thread_struct, regs)); - DEFINE(PT_TRACESYS, PT_TRACESYS); DEFINE(TASK_FLAGS, offsetof(struct task_struct, flags)); -#error DEFINE(TASK_PTRACE, offsetof(struct task_struct, ptrace)); -#error DEFINE(NEED_RESCHED, offsetof(struct task_struct, need_resched)); + DEFINE(TASK_WORK, offsetof(struct task_struct, work)); + DEFINE(NEED_RESCHED, offsetof(struct task_struct, work.need_resched)); + DEFINE(SYSCALL_TRACE, offsetof(struct task_struct, work.syscall_trace)); + DEFINE(SIGPENDING, offsetof(struct task_struct, work.sigpending)); + DEFINE(NOTIFY_RESUME, offsetof(struct task_struct, work.notify_resume)); + DEFINE(THREAD_FPEXC_MODE, offsetof(struct thread_struct, fpexc_mode)); DEFINE(THREAD_FPR0, offsetof(struct thread_struct, fpr[0])); DEFINE(THREAD_FPSCR, offsetof(struct thread_struct, fpscr)); #ifdef CONFIG_ALTIVEC @@ -127,6 +135,35 @@ main(void) DEFINE(CPU_SPEC_FEATURES, offsetof(struct cpu_spec, cpu_features)); DEFINE(CPU_SPEC_SETUP, offsetof(struct cpu_spec, cpu_setup)); +#ifdef CONFIG_PPC_ISERIES + DEFINE(PACAPROCENABLED, offsetof(struct Paca, xProcEnabled)); + DEFINE(PACAPACAINDEX, offsetof(struct Paca, xPacaIndex)); + DEFINE(PACAPROCSTART, offsetof(struct Paca, xProcStart)); + DEFINE(PACAKSAVE, offsetof(struct Paca, xKsave)); + DEFINE(PACASAVEDMSR, offsetof(struct Paca, xSavedMsr)); + DEFINE(PACASAVEDLR, offsetof(struct Paca, xSavedLr)); + DEFINE(PACACONTEXTOVERFLOW, offsetof(struct Paca, xContextOverflow)); + DEFINE(PACAR21, offsetof(struct Paca, xR21)); + DEFINE(PACAR22, offsetof(struct Paca, xR22)); + DEFINE(PACALPQUEUE, offsetof(struct Paca, lpQueuePtr)); + DEFINE(PACALPPACA, offsetof(struct Paca, xLpPaca)); + DEFINE(PACA_STRUCT_SIZE, sizeof(struct Paca)); + DEFINE(LPREGSAV, offsetof(struct Paca, xRegSav)); + DEFINE(PACADEFAULTDECR, offsetof(struct Paca, default_decr)); + DEFINE(LPPACAANYINT, offsetof(struct ItLpPaca, xRsvd)); + DEFINE(LPPACASRR0, offsetof(struct ItLpPaca, xSavedSrr0)); + DEFINE(LPPACASRR1, offsetof(struct ItLpPaca, xSavedSrr1)); + DEFINE(LPPACADECRINT, offsetof(struct ItLpPaca, xDecrInt)); + DEFINE(LPPACAIPIINT, offsetof(struct ItLpPaca, xIpiCnt)); + DEFINE(LPQCUREVENTPTR, offsetof(struct ItLpQueue, xSlicCurEventPtr)); + DEFINE(LPQOVERFLOW, offsetof(struct ItLpQueue, xPlicOverflowIntPending)); + DEFINE(LPQINUSEWORD, offsetof(struct ItLpQueue, xInUseWord)); + DEFINE(LPEVENTFLAGS, offsetof(struct HvLpEvent, xFlags)); + DEFINE(CONTEXT, offsetof(struct mm_struct, context)); + DEFINE(_SOFTE, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, mq)); + DEFINE(PACA_EXT_INTS, offsetof(struct Paca, ext_ints)); +#endif /* CONFIG_PPC_ISERIES */ + DEFINE(NUM_USER_SEGMENTS, TASK_SIZE>>28); return 0; } diff --git a/arch/ppc/kernel/mpc10x_common.c b/arch/ppc/kernel/mpc10x_common.c new file mode 100644 index 000000000000..facbf56019d7 --- /dev/null +++ b/arch/ppc/kernel/mpc10x_common.c @@ -0,0 +1,378 @@ + +/* + * arch/ppc/kernel/mpc10x_common.c + * + * Common routines for the Motorola SPS MPC106, MPC107 and MPC8240 Host bridge, + * Mem ctlr, EPIC, etc. + * + * Author: Mark A. Greer + * mgreer@mvista.com + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +/* + * *** WARNING - A BAT MUST be set to access the PCI config addr/data regs *** + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/pci.h> +#include <linux/slab.h> + +#include <asm/byteorder.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/uaccess.h> +#include <asm/machdep.h> +#include <asm/pci-bridge.h> +#include <asm/open_pic.h> +#include <asm/mpc10x.h> + + +/* Set resources to match bridge memory map */ +void __init +mpc10x_bridge_set_resources(int map, struct pci_controller *hose) +{ + + switch (map) { + case MPC10X_MEM_MAP_A: + pci_init_resource(&hose->io_resource, + 0x00000000, + 0x3f7fffff, + IORESOURCE_IO, + "PCI host bridge"); + + pci_init_resource (&hose->mem_resources[0], + 0xc0000000, + 0xfeffffff, + IORESOURCE_MEM, + "PCI host bridge"); + break; + case MPC10X_MEM_MAP_B: + pci_init_resource(&hose->io_resource, + 0x00000000, + 0x00bfffff, + IORESOURCE_IO, + "PCI host bridge"); + + pci_init_resource (&hose->mem_resources[0], + 0x80000000, + 0xfcffffff, + IORESOURCE_MEM, + "PCI host bridge"); + break; + default: + printk("mpc10x_bridge_set_resources: " + "Invalid map specified\n"); + if (ppc_md.progress) + ppc_md.progress("mpc10x:exit1", 0x100); + } +} +/* + * Do some initialization and put the EUMB registers at the specified address + * (also map the EPIC registers into virtual space--OpenPIC_Addr will be set). + * + * The EPIC is not on the 106, only the 8240 and 107. + */ +int __init +mpc10x_bridge_init(struct pci_controller *hose, + uint current_map, + uint new_map, + uint phys_eumb_base) +{ + int host_bridge, picr1, picr1_bit; + ulong pci_config_addr, pci_config_data; + u_char pir, byte; + + if (ppc_md.progress) ppc_md.progress("mpc10x:enter", 0x100); + + /* Set up for current map so we can get at config regs */ + switch (current_map) { + case MPC10X_MEM_MAP_A: + setup_indirect_pci(hose, + MPC10X_MAPA_CNFG_ADDR, + MPC10X_MAPA_CNFG_DATA); + break; + case MPC10X_MEM_MAP_B: + setup_indirect_pci(hose, + MPC10X_MAPB_CNFG_ADDR, + MPC10X_MAPB_CNFG_DATA); + break; + default: + printk("mpc10x_bridge_init: %s\n", + "Invalid current map specified"); + if (ppc_md.progress) + ppc_md.progress("mpc10x:exit1", 0x100); + return -1; + } + + /* Make sure its a supported bridge */ + early_read_config_dword(hose, + 0, + PCI_DEVFN(0,0), + PCI_VENDOR_ID, + &host_bridge); + + switch (host_bridge) { + case MPC10X_BRIDGE_106: + case MPC10X_BRIDGE_8240: + case MPC10X_BRIDGE_107: + case MPC10X_BRIDGE_8245: + break; + default: + if (ppc_md.progress) + ppc_md.progress("mpc10x:exit2", 0x100); + return -1; + } + + switch (new_map) { + case MPC10X_MEM_MAP_A: + MPC10X_SETUP_HOSE(hose, A); + pci_config_addr = MPC10X_MAPA_CNFG_ADDR; + pci_config_data = MPC10X_MAPA_CNFG_DATA; + picr1_bit = MPC10X_CFG_PICR1_ADDR_MAP_A; + break; + case MPC10X_MEM_MAP_B: + MPC10X_SETUP_HOSE(hose, B); + pci_config_addr = MPC10X_MAPB_CNFG_ADDR; + pci_config_data = MPC10X_MAPB_CNFG_DATA; + picr1_bit = MPC10X_CFG_PICR1_ADDR_MAP_B; + break; + default: + printk("mpc10x_bridge_init: %s\n", + "Invalid new map specified"); + if (ppc_md.progress) + ppc_md.progress("mpc10x:exit3", 0x100); + return -1; + } + + /* Make bridge use the 'new_map', if not already usng it */ + if (current_map != new_map) { + early_read_config_dword(hose, + 0, + PCI_DEVFN(0,0), + MPC10X_CFG_PICR1_REG, + &picr1); + + picr1 = (picr1 & ~MPC10X_CFG_PICR1_ADDR_MAP_MASK) | + picr1_bit; + + early_write_config_dword(hose, + 0, + PCI_DEVFN(0,0), + MPC10X_CFG_PICR1_REG, + picr1); + + asm volatile("sync"); + + /* Undo old mappings & map in new cfg data/addr regs */ + iounmap((void *)hose->cfg_addr); + iounmap((void *)hose->cfg_data); + + setup_indirect_pci(hose, + pci_config_addr, + pci_config_data); + } + + /* Setup resources to match map */ + mpc10x_bridge_set_resources(new_map, hose); + + /* + * Want processor accesses of 0xFDxxxxxx to be mapped + * to PCI memory space at 0x00000000. Do not want + * host bridge to respond to PCI memory accesses of + * 0xFDxxxxxx. Do not want host bridge to respond + * to PCI memory addresses 0xFD000000-0xFDFFFFFF; + * want processor accesses from 0x000A0000-0x000BFFFF + * to be forwarded to system memory. + * + * Only valid if not in agent mode and using MAP B. + */ + if (new_map == MPC10X_MEM_MAP_B) { + early_read_config_byte(hose, + 0, + PCI_DEVFN(0,0), + MPC10X_CFG_MAPB_OPTIONS_REG, + &byte); + + byte &= ~(MPC10X_CFG_MAPB_OPTIONS_PFAE | + MPC10X_CFG_MAPB_OPTIONS_PCICH | + MPC10X_CFG_MAPB_OPTIONS_PROCCH); + + if (host_bridge != MPC10X_BRIDGE_106) { + byte |= MPC10X_CFG_MAPB_OPTIONS_CFAE; + } + + early_write_config_byte(hose, + 0, + PCI_DEVFN(0,0), + MPC10X_CFG_MAPB_OPTIONS_REG, + byte); + } + + if (host_bridge != MPC10X_BRIDGE_106) { + early_read_config_byte(hose, + 0, + PCI_DEVFN(0,0), + MPC10X_CFG_PIR_REG, + &pir); + + if (pir != MPC10X_CFG_PIR_HOST_BRIDGE) { + printk("Host bridge in Agent mode\n"); + /* Read or Set LMBAR & PCSRBAR? */ + } + + /* Set base addr of the 8240/107 EUMB. */ + early_write_config_dword(hose, + 0, + PCI_DEVFN(0,0), + MPC10X_CFG_EUMBBAR, + phys_eumb_base); + + /* Map EPIC register part of EUMB into vitual memory */ + OpenPIC_Addr = + ioremap(phys_eumb_base + MPC10X_EUMB_EPIC_OFFSET, + MPC10X_EUMB_EPIC_SIZE); + } + +#ifdef CONFIG_MPC10X_STORE_GATHERING + mpc10x_enable_store_gathering(hose); +#endif + + if (ppc_md.progress) ppc_md.progress("mpc10x:exit", 0x100); + return 0; +} + +/* + * Need to make our own PCI config space access macros because + * mpc10x_get_mem_size() is called before the data structures are set up for + * the 'early_xxx' and 'indirect_xxx' routines to work. + * Assumes bus 0. + */ +#define MPC10X_CFG_read(val, addr, type, op) *val = op((type)(addr)) +#define MPC10X_CFG_write(val, addr, type, op) op((type *)(addr), (val)) + +#define MPC10X_PCI_OP(rw, size, type, op, mask) \ +static void \ +mpc10x_##rw##_config_##size(uint *cfg_addr, uint *cfg_data, int devfn, int offset, type val) \ +{ \ + out_be32(cfg_addr, \ + ((offset & 0xfc) << 24) | (devfn << 16) \ + | (0 << 8) | 0x80); \ + MPC10X_CFG_##rw(val, cfg_data + (offset & mask), type, op); \ + return; \ +} + +MPC10X_PCI_OP(read, byte, u8 *, in_8, 3) +MPC10X_PCI_OP(read, dword, u32 *, in_le32, 0) +#if 0 /* Not used */ +MPC10X_PCI_OP(write, byte, u8, out_8, 3) +MPC10X_PCI_OP(read, word, u16 *, in_le16, 2) +MPC10X_PCI_OP(write, word, u16, out_le16, 2) +MPC10X_PCI_OP(write, dword, u32, out_le32, 0) +#endif + +/* + * Read the memory controller registers to determine the amount of memory in + * the system. This assumes that the firmware has correctly set up the memory + * controller registers. + */ +unsigned long __init +mpc10x_get_mem_size(uint mem_map) +{ + uint *config_addr, *config_data, val; + ulong start, end, total, offset; + int i; + u_char bank_enables; + + switch (mem_map) { + case MPC10X_MEM_MAP_A: + config_addr = (uint *)MPC10X_MAPA_CNFG_ADDR; + config_data = (uint *)MPC10X_MAPA_CNFG_DATA; + break; + case MPC10X_MEM_MAP_B: + config_addr = (uint *)MPC10X_MAPB_CNFG_ADDR; + config_data = (uint *)MPC10X_MAPB_CNFG_DATA; + break; + default: + return 0; + } + + mpc10x_read_config_byte(config_addr, + config_data, + PCI_DEVFN(0,0), + MPC10X_MCTLR_MEM_BANK_ENABLES, + &bank_enables); + + total = 0; + + for (i=0; i<8; i++) { + if (bank_enables & (1 << i)) { + offset = MPC10X_MCTLR_MEM_START_1 + ((i > 3) ? 4 : 0); + mpc10x_read_config_dword(config_addr, + config_data, + PCI_DEVFN(0,0), + offset, + &val); + start = (val >> ((i & 3) << 3)) & 0xff; + + offset = MPC10X_MCTLR_EXT_MEM_START_1 + ((i>3) ? 4 : 0); + mpc10x_read_config_dword(config_addr, + config_data, + PCI_DEVFN(0,0), + offset, + &val); + val = (val >> ((i & 3) << 3)) & 0x03; + start = (val << 28) | (start << 20); + + offset = MPC10X_MCTLR_MEM_END_1 + ((i > 3) ? 4 : 0); + mpc10x_read_config_dword(config_addr, + config_data, + PCI_DEVFN(0,0), + offset, + &val); + end = (val >> ((i & 3) << 3)) & 0xff; + + offset = MPC10X_MCTLR_EXT_MEM_END_1 + ((i > 3) ? 4 : 0); + mpc10x_read_config_dword(config_addr, + config_data, + PCI_DEVFN(0,0), + offset, + &val); + val = (val >> ((i & 3) << 3)) & 0x03; + end = (val << 28) | (end << 20) | 0xfffff; + + total += (end - start + 1); + } + } + + return total; +} + +int __init +mpc10x_enable_store_gathering(struct pci_controller *hose) +{ + uint picr1; + + early_read_config_dword(hose, + 0, + PCI_DEVFN(0,0), + MPC10X_CFG_PICR1_REG, + &picr1); + + picr1 |= MPC10X_CFG_PICR1_ST_GATH_EN; + + early_write_config_dword(hose, + 0, + PCI_DEVFN(0,0), + MPC10X_CFG_PICR1_REG, + picr1); + + return 0; +} diff --git a/arch/ppc/kernel/open_pic.c b/arch/ppc/kernel/open_pic.c index c5c8a7e155f0..676d97101e9b 100644 --- a/arch/ppc/kernel/open_pic.c +++ b/arch/ppc/kernel/open_pic.c @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.open_pic.c 1.31 10/11/01 12:09:11 trini + * BK Id: %F% %I% %G% %U% %#% */ /* * arch/ppc/kernel/open_pic.c -- OpenPIC Interrupt Handling @@ -17,40 +17,40 @@ #include <linux/sched.h> #include <linux/init.h> #include <linux/irq.h> -#include <linux/init.h> #include <asm/ptrace.h> #include <asm/signal.h> #include <asm/io.h> #include <asm/irq.h> #include <asm/prom.h> #include <asm/sections.h> +#include <asm/open_pic.h> +#include <asm/i8259.h> -#include "local_irq.h" -#include "open_pic.h" #include "open_pic_defs.h" +#ifdef CONFIG_PRPMC800 +#define OPENPIC_BIG_ENDIAN +#endif + void* OpenPIC_Addr; static volatile struct OpenPIC *OpenPIC = NULL; u_int OpenPIC_NumInitSenses __initdata = 0; u_char *OpenPIC_InitSenses __initdata = NULL; extern int use_of_interrupt_tree; -void find_ISUs(void); - static u_int NumProcessors; static u_int NumSources; -#ifdef CONFIG_POWER3 -static int NumISUs; -#endif static int open_pic_irq_offset; static volatile unsigned char* chrp_int_ack_special; - -OpenPIC_SourcePtr ISU[OPENPIC_MAX_ISU]; +static volatile OpenPIC_Source *ISR[NR_IRQS]; /* Global Operations */ static void openpic_disable_8259_pass_through(void); static void openpic_set_priority(u_int pri); static void openpic_set_spurious(u_int vector); +static void openpic_enable_sie(void); +static void openpic_eicr_set_clk(u_int clkval); +static void openpic_eicr_set_clk(u_int clkval); #ifdef CONFIG_SMP /* Interprocessor Interrupts */ @@ -67,7 +67,7 @@ static void openpic_enable_irq(u_int irq); static void openpic_disable_irq(u_int irq); static void openpic_initirq(u_int irq, u_int pri, u_int vector, int polarity, int is_level); -static void openpic_mapirq(u_int irq, u_int cpumask); +static void openpic_mapirq(u_int irq, u_int cpumask, u_int keepmask); /* * These functions are not used but the code is kept here @@ -150,7 +150,8 @@ struct hw_interrupt_type open_pic_ipi = { */ extern unsigned long* _get_SP(void); #define check_arg_irq(irq) \ - if (irq < open_pic_irq_offset || irq >= (NumSources+open_pic_irq_offset)){ \ + if (irq < open_pic_irq_offset || irq >= NumSources+open_pic_irq_offset \ + || ISR[irq - open_pic_irq_offset] == 0) { \ printk("open_pic.c:%d: illegal irq %d\n", __LINE__, irq); \ print_backtrace(_get_SP()); } #define check_arg_cpu(cpu) \ @@ -166,23 +167,25 @@ extern unsigned long* _get_SP(void); #define check_arg_cpu(cpu) do {} while (0) #endif -#ifdef CONFIG_POWER3 - #define GET_ISU(source) ISU[(source) >> 4][(source) & 0xf] -#else - #define GET_ISU(source) ISU[0][(source)] -#endif - u_int openpic_read(volatile u_int *addr) { u_int val; +#ifdef OPENPIC_BIG_ENDIAN + val = in_be32(addr); +#else val = in_le32(addr); +#endif return val; } static inline void openpic_write(volatile u_int *addr, u_int val) { +#ifdef OPENPIC_BIG_ENDIAN + out_be32(addr, val); +#else out_le32(addr, val); +#endif } static inline u_int openpic_readfield(volatile u_int *addr, u_int mask) @@ -221,7 +224,7 @@ static void openpic_safe_writefield(volatile u_int *addr, u_int mask, u_int openpic_read_IPI(volatile u_int* addr) { u_int val = 0; -#ifdef CONFIG_POWER3 +#if defined(OPENPIC_BIG_ENDIAN) || defined(CONFIG_POWER3) val = in_be32(addr); #else val = in_le32(addr); @@ -260,6 +263,20 @@ static void openpic_safe_writefield_IPI(volatile u_int *addr, u_int mask, u_int } #endif /* CONFIG_SMP */ +void openpic_set_sources(int first_irq, int num_irqs, void *first_ISR) +{ + volatile OpenPIC_Source *src = first_ISR; + int i, last_irq; + + last_irq = first_irq + num_irqs; + if (last_irq > NumSources) + NumSources = last_irq; + if (src == 0) + src = &((struct OpenPIC *)OpenPIC_Addr)->Source[first_irq]; + for (i = first_irq; i < last_irq; ++i, ++src) + ISR[i] = src; +} + void __init openpic_init(int main_pic, int offset, unsigned char* chrp_ack, int programmer_switch_irq) { @@ -273,7 +290,13 @@ void __init openpic_init(int main_pic, int offset, unsigned char* chrp_ack, } OpenPIC = (volatile struct OpenPIC *)OpenPIC_Addr; - if ( ppc_md.progress ) ppc_md.progress("openpic enter",0x122); +#ifdef CONFIG_EPIC_SERIAL_MODE + /* Have to start from ground zero. + */ + openpic_reset(); +#endif + + if (ppc_md.progress) ppc_md.progress("openpic enter", 0x122); t = openpic_read(&OpenPIC->Global.Feature_Reporting0); switch (t & OPENPIC_FEATURE_VERSION_MASK) { @@ -292,8 +315,11 @@ void __init openpic_init(int main_pic, int offset, unsigned char* chrp_ack, } NumProcessors = ((t & OPENPIC_FEATURE_LAST_PROCESSOR_MASK) >> OPENPIC_FEATURE_LAST_PROCESSOR_SHIFT) + 1; - NumSources = ((t & OPENPIC_FEATURE_LAST_SOURCE_MASK) >> - OPENPIC_FEATURE_LAST_SOURCE_SHIFT) + 1; + if (NumSources == 0) + openpic_set_sources(0, + ((t & OPENPIC_FEATURE_LAST_SOURCE_MASK) >> + OPENPIC_FEATURE_LAST_SOURCE_SHIFT) + 1, + NULL); printk("OpenPIC Version %s (%d CPUs and %d IRQ sources) at %p\n", version, NumProcessors, NumSources, OpenPIC); timerfreq = openpic_read(&OpenPIC->Global.Timer_Frequency); @@ -328,8 +354,6 @@ void __init openpic_init(int main_pic, int offset, unsigned char* chrp_ack, } #endif - find_ISUs(); - /* Initialize external interrupts */ if (ppc_md.progress) ppc_md.progress("openpic ext",0x3bc); @@ -338,13 +362,16 @@ void __init openpic_init(int main_pic, int offset, unsigned char* chrp_ack, /* SIOint (8259 cascade) is special */ if (offset) { openpic_initirq(0, 8, offset, 1, 1); - openpic_mapirq(0, 1<<0); + openpic_mapirq(0, 1<<0, 0); } /* Init all external sources */ for (i = 1; i < NumSources; i++) { int pri, sense; + if (ISR[i] == 0) + continue; + /* the bootloader may have left it enabled (bad !) */ openpic_disable_irq(i+offset); @@ -356,7 +383,7 @@ void __init openpic_init(int main_pic, int offset, unsigned char* chrp_ack, /* Enabled, Priority 8 or 9 */ openpic_initirq(i, pri, i+offset, !sense, sense); /* Processor 0 */ - openpic_mapirq(i, 1<<0); + openpic_mapirq(i, 1<<0, 0); } /* Init descriptors */ @@ -373,43 +400,17 @@ void __init openpic_init(int main_pic, int offset, unsigned char* chrp_ack, "82c59 cascade", NULL)) printk("Unable to get OpenPIC IRQ 0 for cascade\n"); } +#ifdef CONFIG_EPIC_SERIAL_MODE + openpic_disable_8259_pass_through(); + openpic_eicr_set_clk(7); /* Slowest value until we know better */ + openpic_enable_sie(); openpic_set_priority(0); - openpic_disable_8259_pass_through(); - - if (ppc_md.progress) ppc_md.progress("openpic exit",0x222); -} - -#ifdef CONFIG_POWER3 -void openpic_setup_ISU(int isu_num, unsigned long addr) -{ - if (isu_num >= OPENPIC_MAX_ISU) - return; - ISU[isu_num] = (OpenPIC_SourcePtr) ioremap(addr, 0x400); - if (isu_num >= NumISUs) - NumISUs = isu_num + 1; -} -#endif - -void find_ISUs(void) -{ -#ifdef CONFIG_POWER3 - /* Use /interrupt-controller/reg and - * /interrupt-controller/interrupt-ranges from OF device tree - * the ISU array is setup in chrp_pci.c in ibm_add_bridges - * as a result - * -- tgall - */ - - /* basically each ISU is a bus, and this assumes that - * open_pic_isu_count interrupts per bus are possible - * ISU == Interrupt Source - */ - NumSources = NumISUs * 0x10; - #else - /* for non-distributed OpenPIC implementations it's in the IDU -- Cort */ - ISU[0] = (OpenPIC_Source *)OpenPIC->Source; + openpic_disable_8259_pass_through(); + openpic_set_priority(0); #endif + + if (ppc_md.progress) ppc_md.progress("openpic exit",0x222); } static void openpic_reset(void) @@ -421,6 +422,18 @@ static void openpic_reset(void) mb(); } +static void openpic_enable_sie(void) +{ + openpic_setfield(&OpenPIC->Global.Global_Configuration1, + OPENPIC_EICR_SIE); +} + +static void openpic_eicr_set_clk(u_int clkval) +{ + openpic_writefield(&OpenPIC->Global.Global_Configuration1, + OPENPIC_EICR_S_CLK_MASK, (clkval << 28)); +} + #ifdef notused static void openpic_enable_8259_pass_through(void) { @@ -602,8 +615,8 @@ void __init do_openpic_setup_cpu(void) * we should make sure we also change the default values of irq_affinity * in irq.c. */ - for (i = 0; i < NumSources ; i++) - openpic_mapirq(i, openpic_read(&GET_ISU(i).Destination) | msk); + for (i = 0; i < NumSources; i++) + openpic_mapirq(i, msk, ~0U); #endif /* CONFIG_IRQ_ALL_CPUS */ openpic_set_priority(0); @@ -653,26 +666,29 @@ static void __init openpic_maptimer(u_int timer, u_int cpumask) */ static void openpic_enable_irq(u_int irq) { + volatile u_int *vpp; + check_arg_irq(irq); - openpic_clearfield(&GET_ISU(irq - open_pic_irq_offset).Vector_Priority, OPENPIC_MASK); + vpp = &ISR[irq - open_pic_irq_offset]->Vector_Priority; + openpic_clearfield(vpp, OPENPIC_MASK); /* make sure mask gets to controller before we return to user */ do { mb(); /* sync is probably useless here */ - } while(openpic_readfield(&GET_ISU(irq - open_pic_irq_offset).Vector_Priority, - OPENPIC_MASK)); + } while (openpic_readfield(vpp, OPENPIC_MASK)); } static void openpic_disable_irq(u_int irq) { + volatile u_int *vpp; u32 vp; check_arg_irq(irq); - openpic_setfield(&GET_ISU(irq - open_pic_irq_offset).Vector_Priority, OPENPIC_MASK); + vpp = &ISR[irq - open_pic_irq_offset]->Vector_Priority; + openpic_setfield(vpp, OPENPIC_MASK); /* make sure mask gets to controller before we return to user */ do { mb(); /* sync is probably useless here */ - vp = openpic_readfield(&GET_ISU(irq - open_pic_irq_offset).Vector_Priority, - OPENPIC_MASK | OPENPIC_ACTIVITY); + vp = openpic_readfield(vpp, OPENPIC_MASK | OPENPIC_ACTIVITY); } while((vp & OPENPIC_ACTIVITY) && !(vp & OPENPIC_MASK)); } @@ -709,7 +725,7 @@ void openpic_disable_ipi(u_int irq) */ static void openpic_initirq(u_int irq, u_int pri, u_int vec, int pol, int sense) { - openpic_safe_writefield(&GET_ISU(irq).Vector_Priority, + openpic_safe_writefield(&ISR[irq]->Vector_Priority, OPENPIC_PRIORITY_MASK | OPENPIC_VECTOR_MASK | OPENPIC_SENSE_MASK | OPENPIC_POLARITY_MASK, (pri << OPENPIC_PRIORITY_SHIFT) | vec | @@ -721,9 +737,13 @@ static void openpic_initirq(u_int irq, u_int pri, u_int vec, int pol, int sense) /* * Map an interrupt source to one or more CPUs */ -static void openpic_mapirq(u_int irq, u_int physmask) +static void openpic_mapirq(u_int irq, u_int physmask, u_int keepmask) { - openpic_write(&GET_ISU(irq).Destination, physmask); + if (ISR[irq] == 0) + return; + if (keepmask != 0) + physmask |= openpic_read(&ISR[irq]->Destination) & keepmask; + openpic_write(&ISR[irq]->Destination, physmask); } #ifdef notused @@ -734,9 +754,10 @@ static void openpic_mapirq(u_int irq, u_int physmask) */ static void openpic_set_sense(u_int irq, int sense) { - openpic_safe_writefield(&GET_ISU(irq).Vector_Priority, - OPENPIC_SENSE_LEVEL, - (sense ? OPENPIC_SENSE_LEVEL : 0)); + if (ISR[irq] != 0) + openpic_safe_writefield(&ISR[irq]->Vector_Priority, + OPENPIC_SENSE_LEVEL, + (sense ? OPENPIC_SENSE_LEVEL : 0)); } #endif /* notused */ @@ -757,7 +778,7 @@ static void openpic_end_irq(unsigned int irq_nr) static void openpic_set_affinity(unsigned int irq_nr, unsigned long cpumask) { - openpic_mapirq(irq_nr - open_pic_irq_offset, physmask(cpumask)); + openpic_mapirq(irq_nr - open_pic_irq_offset, physmask(cpumask), 0); } #ifdef CONFIG_SMP @@ -784,9 +805,6 @@ openpic_get_irq(struct pt_regs *regs) /* * Clean up needed. -VAL */ -#ifndef CONFIG_GEMINI - extern int i8259_irq(int cpu); -#endif int irq = openpic_irq(); /* Management of the cascade should be moved out of here */ @@ -801,7 +819,7 @@ openpic_get_irq(struct pt_regs *regs) irq = *chrp_int_ack_special; #ifndef CONFIG_GEMINI else - irq = i8259_irq( smp_processor_id() ); + irq = i8259_poll(); #endif openpic_eoi(); } @@ -858,9 +876,11 @@ openpic_sleep_save_intrs(void) for (i=0; i<OPENPIC_NUM_IPI; i++) save_ipi_vp[i] = openpic_read(&OpenPIC->Global.IPI_Vector_Priority(i)); for (i=0; i<NumSources; i++) { - save_irq_src_vp[i] = openpic_read(&OpenPIC->Source[i].Vector_Priority) + if (ISR[i] == 0) + continue; + save_irq_src_vp[i] = openpic_read(&ISR[i]->Vector_Priority) & ~OPENPIC_ACTIVITY; - save_irq_src_dest[i] = openpic_read(&OpenPIC->Source[i].Destination); + save_irq_src_dest[i] = openpic_read(&ISR[i]->Destination); } spin_unlock_irqrestore(&openpic_setup_lock, flags); } @@ -876,15 +896,19 @@ openpic_sleep_restore_intrs(void) openpic_reset(); for (i=0; i<OPENPIC_NUM_IPI; i++) - openpic_write(&OpenPIC->Global.IPI_Vector_Priority(i), save_ipi_vp[i]); + openpic_write(&OpenPIC->Global.IPI_Vector_Priority(i), + save_ipi_vp[i]); for (i=0; i<NumSources; i++) { - openpic_write(&OpenPIC->Source[i].Vector_Priority, save_irq_src_vp[i]); - openpic_write(&OpenPIC->Source[i].Destination, save_irq_src_dest[i]); + if (ISR[i] == 0) + continue; + openpic_write(&ISR[i]->Vector_Priority, save_irq_src_vp[i]); + openpic_write(&ISR[i]->Destination, save_irq_src_dest[i]); } openpic_set_spurious(OPENPIC_VEC_SPURIOUS+open_pic_irq_offset); openpic_disable_8259_pass_through(); for (i=0; i<NumProcessors; i++) - openpic_write(&OpenPIC->Processor[i].Current_Task_Priority, save_cpu_task_pri[i]); + openpic_write(&OpenPIC->Processor[i].Current_Task_Priority, + save_cpu_task_pri[i]); spin_unlock_irqrestore(&openpic_setup_lock, flags); } diff --git a/arch/ppc/kernel/open_pic_defs.h b/arch/ppc/kernel/open_pic_defs.h index 56497f9579ac..753461a5e8e7 100644 --- a/arch/ppc/kernel/open_pic_defs.h +++ b/arch/ppc/kernel/open_pic_defs.h @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.open_pic_defs.h 1.8 08/20/01 22:33:28 paulus + * BK Id: %F% %I% %G% %U% %#% */ /* * linux/openpic.h -- OpenPIC definitions @@ -209,6 +209,14 @@ extern volatile struct OpenPIC *OpenPIC; #define OPENPIC_CONFIG_BASE_MASK 0x000fffff /* + * Global Configuration Register 1 + * This is the EICR on EPICs. + */ + +#define OPENPIC_EICR_S_CLK_MASK 0x70000000 +#define OPENPIC_EICR_SIE 0x08000000 + + /* * Vendor Identification Register */ diff --git a/arch/ppc/kernel/pci-dma.c b/arch/ppc/kernel/pci-dma.c index 1a7b56b89e82..2e37b3117585 100644 --- a/arch/ppc/kernel/pci-dma.c +++ b/arch/ppc/kernel/pci-dma.c @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.pci-dma.c 1.5 05/17/01 18:14:21 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * Copyright (C) 2000 Ani Joshi <ajoshi@unixbox.com> @@ -25,7 +25,11 @@ void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size, if (hwdev == NULL || hwdev->dma_mask != 0xffffffff) gfp |= GFP_DMA; +#ifdef CONFIG_NOT_COHERENT_CACHE + ret = consistent_alloc(gfp, size, dma_handle); +#else ret = (void *)__get_free_pages(gfp, get_order(size)); +#endif if (ret != NULL) { memset(ret, 0, size); @@ -37,5 +41,9 @@ void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size, void pci_free_consistent(struct pci_dev *hwdev, size_t size, void *vaddr, dma_addr_t dma_handle) { +#ifdef CONFIG_NOT_COHERENT_CACHE + consistent_free(vaddr); +#else free_pages((unsigned long)vaddr, get_order(size)); +#endif } diff --git a/arch/ppc/kernel/pci.c b/arch/ppc/kernel/pci.c index 57c4223a482f..77e1de956a6b 100644 --- a/arch/ppc/kernel/pci.c +++ b/arch/ppc/kernel/pci.c @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.pci.c 1.35 11/13/01 08:19:57 trini + * BK Id: %F% %I% %G% %U% %#% */ /* * Common pmac/prep/chrp pci routines. -- Cort @@ -19,16 +19,13 @@ #include <asm/processor.h> #include <asm/io.h> #include <asm/prom.h> +#include <asm/sections.h> #include <asm/pci-bridge.h> -#include <asm/residual.h> #include <asm/byteorder.h> #include <asm/irq.h> -#include <asm/gg2.h> #include <asm/uaccess.h> -#include "pci.h" - -#define DEBUG +#undef DEBUG #ifdef DEBUG #define DBG(x...) printk(x) @@ -42,8 +39,13 @@ unsigned long pci_dram_offset = 0; void pcibios_make_OF_bus_map(void); +static int pci_relocate_bridge_resource(struct pci_bus *bus, int i); +static int probe_resource(struct pci_bus *parent, struct resource *pr, + struct resource *res, struct resource **conflict); +static void update_bridge_base(struct pci_bus *bus, int i); static void pcibios_fixup_resources(struct pci_dev* dev); static void fixup_broken_pcnet32(struct pci_dev* dev); +static int reparent_resources(struct resource *parent, struct resource *res); static void fixup_rev1_53c810(struct pci_dev* dev); #ifdef CONFIG_ALL_PPC static void pcibios_fixup_cardbus(struct pci_dev* dev); @@ -66,7 +68,7 @@ struct pci_fixup pcibios_fixups[] = { { PCI_FIXUP_HEADER, PCI_ANY_ID, PCI_ANY_ID, pcibios_fixup_resources }, #ifdef CONFIG_ALL_PPC /* We should add per-machine fixup support in xxx_setup.c or xxx_pci.c */ - { PCI_FIXUP_FINAL, PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1211, pcibios_fixup_cardbus }, + { PCI_FIXUP_FINAL, PCI_VENDOR_ID_TI, PCI_ANY_ID, pcibios_fixup_cardbus }, #endif /* CONFIG_ALL_PPC */ { 0 } }; @@ -96,7 +98,7 @@ fixup_broken_pcnet32(struct pci_dev* dev) void pcibios_update_resource(struct pci_dev *dev, struct resource *root, - struct resource *res, int resource) + struct resource *res, int resource) { u32 new, check; int reg; @@ -104,6 +106,7 @@ pcibios_update_resource(struct pci_dev *dev, struct resource *root, unsigned long io_offset; new = res->start; + res->flags &= ~IORESOURCE_UNSET; if (hose && res->flags & IORESOURCE_IO) { io_offset = (unsigned long)hose->io_base_virt - isa_io_base; new -= io_offset; @@ -128,6 +131,9 @@ pcibios_update_resource(struct pci_dev *dev, struct resource *root, "%s/%d (%08x != %08x)\n", dev->slot_name, resource, new, check); } + printk(KERN_INFO "PCI: moved device %s resource %d (%lx) to %x\n", + dev->slot_name, resource, res->flags, + new & ~PCI_REGION_FLAG_MASK); } static void @@ -143,13 +149,14 @@ pcibios_fixup_resources(struct pci_dev *dev) } for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { struct resource *res = dev->resource + i; - if (!res->start || !res->flags) + if (!res->flags) continue; - if (res->end == 0xffffffff) { + if (!res->start || res->end == 0xffffffff) { DBG("PCI:%s Resource %d [%08lx-%08lx] is unassigned\n", dev->slot_name, i, res->start, res->end); res->end -= res->start; res->start = 0; + res->flags |= IORESOURCE_UNSET; continue; } offset = 0; @@ -169,24 +176,35 @@ pcibios_fixup_resources(struct pci_dev *dev) #endif } } + + /* Call machine specific resource fixup */ + if (ppc_md.pcibios_fixup_resources) + ppc_md.pcibios_fixup_resources(dev); } #ifdef CONFIG_ALL_PPC static void pcibios_fixup_cardbus(struct pci_dev* dev) { + if (_machine != _MACH_Pmac) + return; /* * Fix the interrupt routing on the TI1211 chip on the 1999 * G3 powerbook, which doesn't get initialized properly by OF. + * Same problem with the 1410 of the new titanium pbook which + * has the same register. */ if (dev->vendor == PCI_VENDOR_ID_TI - && dev->device == PCI_DEVICE_ID_TI_1211) { - u32 val; + && (dev->device == PCI_DEVICE_ID_TI_1211 || + dev->device == PCI_DEVICE_ID_TI_1410)) { + u8 val; /* 0x8c == TI122X_IRQMUX, 2 says to route the INTA signal out the MFUNC0 pin */ - if (pci_read_config_dword(dev, 0x8c, &val) == 0 - && val == 0) - pci_write_config_dword(dev, 0x8c, 2); + if (pci_read_config_byte(dev, 0x8c, &val) == 0) + pci_write_config_byte(dev, 0x8c, (val & ~0x0f) | 2); + /* Disable ISA interrupt mode */ + if (pci_read_config_byte(dev, 0x92, &val) == 0) + pci_write_config_byte(dev, 0x92, val & ~0x06); } } #endif /* CONFIG_ALL_PPC */ @@ -271,25 +289,245 @@ pcibios_allocate_bus_resources(struct list_head *bus_list) for (ln = bus_list->next; ln != bus_list; ln=ln->next) { bus = pci_bus_b(ln); for (i = 0; i < 4; ++i) { - if ((res = bus->resource[i]) == NULL || !res->flags) + if ((res = bus->resource[i]) == NULL || !res->flags + || res->start > res->end) continue; if (bus->parent == NULL) pr = (res->flags & IORESOURCE_IO)? &ioport_resource: &iomem_resource; - else + else { pr = pci_find_parent_resource(bus->self, res); + if (pr == res) { + /* this happens when the generic PCI + * code (wrongly) decides that this + * bridge is transparent -- paulus + */ + continue; + } + } - if (pr && request_resource(pr, res) == 0) - continue; + DBG("PCI: bridge rsrc %lx..%lx (%lx), parent %p\n", + res->start, res->end, res->flags, pr); + if (pr) { + if (request_resource(pr, res) == 0) + continue; + /* + * Must be a conflict with an existing entry. + * Move that entry (or entries) under the + * bridge resource and try again. + */ + if (reparent_resources(pr, res) == 0) + continue; + } printk(KERN_ERR "PCI: Cannot allocate resource region " "%d of PCI bridge %d\n", i, bus->number); - DBG("PCI: resource is %lx..%lx (%lx), parent %p\n", - res->start, res->end, res->flags, pr); + if (pci_relocate_bridge_resource(bus, i)) + bus->resource[i] = NULL; } pcibios_allocate_bus_resources(&bus->children); } } +/* + * Reparent resource children of pr that conflict with res + * under res, and make res replace those children. + */ +static int __init +reparent_resources(struct resource *parent, struct resource *res) +{ + struct resource *p, **pp; + struct resource **firstpp = NULL; + + for (pp = &parent->child; (p = *pp) != NULL; pp = &p->sibling) { + if (p->end < res->start) + continue; + if (res->end < p->start) + break; + if (p->start < res->start || p->end > res->end) + return -1; /* not completely contained */ + if (firstpp == NULL) + firstpp = pp; + } + if (firstpp == NULL) + return -1; /* didn't find any conflicting entries? */ + res->parent = parent; + res->child = *firstpp; + res->sibling = *pp; + *firstpp = res; + *pp = NULL; + for (p = res->child; p != NULL; p = p->sibling) { + p->parent = res; + DBG(KERN_INFO "PCI: reparented %s [%lx..%lx] under %s\n", + p->name, p->start, p->end, res->name); + } + return 0; +} + +/* + * A bridge has been allocated a range which is outside the range + * of its parent bridge, so it needs to be moved. + */ +static int __init +pci_relocate_bridge_resource(struct pci_bus *bus, int i) +{ + struct resource *res, *pr, *conflict; + unsigned long try, size; + int j; + struct pci_bus *parent = bus->parent; + + if (parent == NULL) { + /* shouldn't ever happen */ + printk(KERN_ERR "PCI: can't move host bridge resource\n"); + return -1; + } + res = bus->resource[i]; + pr = NULL; + for (j = 0; j < 4; j++) { + struct resource *r = parent->resource[j]; + if (!r) + continue; + if ((res->flags ^ r->flags) & (IORESOURCE_IO | IORESOURCE_MEM)) + continue; + if (!((res->flags ^ r->flags) & IORESOURCE_PREFETCH)) { + pr = r; + break; + } + if (res->flags & IORESOURCE_PREFETCH) + pr = r; + } + if (pr == NULL) + return -1; + size = res->end - res->start; + if (pr->start > pr->end || size > pr->end - pr->start) + return -1; + try = pr->end; + for (;;) { + res->start = try - size; + res->end = try; + if (probe_resource(bus->parent, pr, res, &conflict) == 0) + break; + if (conflict->start <= pr->start + size) + return -1; + try = conflict->start - 1; + } + if (request_resource(pr, res)) { + DBG(KERN_ERR "PCI: huh? couldn't move to %lx..%lx\n", + res->start, res->end); + return -1; /* "can't happen" */ + } + update_bridge_base(bus, i); + printk(KERN_INFO "PCI: bridge %d resource %d moved to %lx..%lx\n", + bus->number, i, res->start, res->end); + return 0; +} + +static int __init +probe_resource(struct pci_bus *parent, struct resource *pr, + struct resource *res, struct resource **conflict) +{ + struct pci_bus *bus; + struct pci_dev *dev; + struct resource *r; + struct list_head *ln; + int i; + + for (r = pr->child; r != NULL; r = r->sibling) { + if (r->end >= res->start && res->end >= r->start) { + *conflict = r; + return 1; + } + } + for (ln = parent->children.next; ln != &parent->children; + ln = ln->next) { + bus = pci_bus_b(ln); + for (i = 0; i < 4; ++i) { + if ((r = bus->resource[i]) == NULL) + continue; + if (!r->flags || r->start > r->end || r == res) + continue; + if (pci_find_parent_resource(bus->self, r) != pr) + continue; + if (r->end >= res->start && res->end >= r->start) { + *conflict = r; + return 1; + } + } + } + for (ln = parent->devices.next; ln != &parent->devices; ln=ln->next) { + dev = pci_dev_b(ln); + for (i = 0; i < 6; ++i) { + r = &dev->resource[i]; + if (!r->flags || (r->flags & IORESOURCE_UNSET)) + continue; + if (pci_find_parent_resource(bus->self, r) != pr) + continue; + if (r->end >= res->start && res->end >= r->start) { + *conflict = r; + return 1; + } + } + } + return 0; +} + +static void __init +update_bridge_base(struct pci_bus *bus, int i) +{ + struct resource *res = bus->resource[i]; + u8 io_base_lo, io_limit_lo; + u16 mem_base, mem_limit; + u16 cmd; + unsigned long start, end, off; + struct pci_dev *dev = bus->self; + struct pci_controller *hose = dev->sysdata; + + if (!hose) { + printk("update_bridge_base: no hose?\n"); + return; + } + pci_read_config_word(dev, PCI_COMMAND, &cmd); + pci_write_config_word(dev, PCI_COMMAND, + cmd & ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY)); + if (res->flags & IORESOURCE_IO) { + off = (unsigned long) hose->io_base_virt - isa_io_base; + start = res->start - off; + end = res->end - off; + io_base_lo = (start >> 8) & PCI_IO_RANGE_MASK; + io_limit_lo = (end >> 8) & PCI_IO_RANGE_MASK; + if (end > 0xffff) { + pci_write_config_word(dev, PCI_IO_BASE_UPPER16, + start >> 16); + pci_write_config_word(dev, PCI_IO_LIMIT_UPPER16, + end >> 16); + io_base_lo |= PCI_IO_RANGE_TYPE_32; + } else + io_base_lo |= PCI_IO_RANGE_TYPE_16; + pci_write_config_byte(dev, PCI_IO_BASE, io_base_lo); + pci_write_config_byte(dev, PCI_IO_LIMIT, io_limit_lo); + + } else if ((res->flags & (IORESOURCE_MEM | IORESOURCE_PREFETCH)) + == IORESOURCE_MEM) { + off = hose->pci_mem_offset; + mem_base = ((res->start - off) >> 16) & PCI_MEMORY_RANGE_MASK; + mem_limit = ((res->end - off) >> 16) & PCI_MEMORY_RANGE_MASK; + pci_write_config_word(dev, PCI_MEMORY_BASE, mem_base); + pci_write_config_word(dev, PCI_MEMORY_LIMIT, mem_limit); + + } else if ((res->flags & (IORESOURCE_MEM | IORESOURCE_PREFETCH)) + == (IORESOURCE_MEM | IORESOURCE_PREFETCH)) { + off = hose->pci_mem_offset; + mem_base = ((res->start - off) >> 16) & PCI_PREF_RANGE_MASK; + mem_limit = ((res->end - off) >> 16) & PCI_PREF_RANGE_MASK; + pci_write_config_word(dev, PCI_PREF_MEMORY_BASE, mem_base); + pci_write_config_word(dev, PCI_PREF_MEMORY_LIMIT, mem_limit); + + } else { + DBG(KERN_ERR "PCI: ugh, bridge %s res %d has flags=%lx\n", + dev->slot_name, i, res->flags); + } + pci_write_config_word(dev, PCI_COMMAND, cmd); +} + static inline void alloc_resource(struct pci_dev *dev, int idx) { struct resource *pr, *r = &dev->resource[idx]; @@ -304,6 +542,7 @@ static inline void alloc_resource(struct pci_dev *dev, int idx) DBG("PCI: parent is %p: %08lx-%08lx (f=%lx)\n", pr, pr->start, pr->end, pr->flags); /* We'll assign a new address later */ + r->flags |= IORESOURCE_UNSET; r->end -= r->start; r->start = 0; } @@ -323,8 +562,8 @@ pcibios_allocate_resources(int pass) r = &dev->resource[idx]; if (r->parent) /* Already allocated */ continue; - if (!r->start) /* Not assigned at all */ - continue; + if (!r->flags || (r->flags & IORESOURCE_UNSET)) + continue; /* Not assigned at all */ if (r->flags & IORESOURCE_IO) disabled = !(command & PCI_COMMAND_IO); else @@ -370,7 +609,7 @@ pcibios_assign_resources(void) * or because we have decided the old address was * unusable for some reason. */ - if (!r->start && r->end && + if ((r->flags & IORESOURCE_UNSET) && r->end && (!ppc_md.pcibios_enable_device_hook || !ppc_md.pcibios_enable_device_hook(dev, 1))) pci_assign_resource(dev, idx); @@ -396,9 +635,9 @@ pcibios_enable_resources(struct pci_dev *dev) pci_read_config_word(dev, PCI_COMMAND, &cmd); old_cmd = cmd; - for(idx=0; idx<6; idx++) { + for (idx=0; idx<6; idx++) { r = &dev->resource[idx]; - if (!r->start && r->end) { + if (r->flags & IORESOURCE_UNSET) { printk(KERN_ERR "PCI: Device %s not available because of resource collisions\n", dev->slot_name); return -EINVAL; } @@ -438,7 +677,7 @@ pcibios_alloc_controller(void) /* * Functions below are used on OpenFirmware machines. */ -static void +static void __openfirmware make_one_node_map(struct device_node* node, u8 pci_bus) { int *bus_range; @@ -449,7 +688,7 @@ make_one_node_map(struct device_node* node, u8 pci_bus) bus_range = (int *) get_property(node, "bus-range", &len); if (bus_range == NULL || len < 2 * sizeof(int)) { printk(KERN_WARNING "Can't get bus-range for %s\n", - node->full_name); + node->full_name); return; } pci_to_OF_bus_map[pci_bus] = bus_range[0]; @@ -472,7 +711,7 @@ make_one_node_map(struct device_node* node, u8 pci_bus) } } -void +void __openfirmware pcibios_make_OF_bus_map(void) { int i; @@ -512,17 +751,17 @@ pcibios_make_OF_bus_map(void) #endif } -static struct device_node* -scan_OF_childs_for_device(struct device_node* node, u8 bus, u8 dev_fn) +typedef int (*pci_OF_scan_iterator)(struct device_node* node, void* data); + +static struct device_node* __openfirmware +scan_OF_pci_childs(struct device_node* node, pci_OF_scan_iterator filter, void* data) { struct device_node* sub_node; for (; node != 0;node = node->sibling) { - unsigned int *class_code, *reg; + unsigned int *class_code; - reg = (unsigned int *) get_property(node, "reg", 0); - if (reg && ((reg[0] >> 8) & 0xff) == dev_fn - && ((reg[0] >> 16) & 0xff) == bus) + if (filter(node, data)) return node; /* For PCI<->PCI bridges or CardBus bridges, we go down @@ -535,13 +774,34 @@ scan_OF_childs_for_device(struct device_node* node, u8 bus, u8 dev_fn) (*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS)) && strcmp(node->name, "multifunc-device")) continue; - sub_node = scan_OF_childs_for_device(node->child, bus, dev_fn); + sub_node = scan_OF_pci_childs(node->child, filter, data); if (sub_node) return sub_node; } return NULL; } +static int +scan_OF_pci_childs_iterator(struct device_node* node, void* data) +{ + unsigned int *reg; + u8* fdata = (u8*)data; + + reg = (unsigned int *) get_property(node, "reg", 0); + if (reg && ((reg[0] >> 8) & 0xff) == fdata[1] + && ((reg[0] >> 16) & 0xff) == fdata[0]) + return 1; + return 0; +} + +static struct device_node* __openfirmware +scan_OF_childs_for_device(struct device_node* node, u8 bus, u8 dev_fn) +{ + u8 filter_data[2] = {bus, dev_fn}; + + return scan_OF_pci_childs(node, scan_OF_pci_childs_iterator, filter_data); +} + /* * Scans the OF tree for a device node matching a PCI device */ @@ -598,6 +858,12 @@ pci_find_hose_for_OF_device(struct device_node* node) return NULL; } +static int __openfirmware +find_OF_pci_device_filter(struct device_node* node, void* data) +{ + return ((void *)node == data); +} + /* * Returns the PCI device matching a given OF node */ @@ -605,21 +871,40 @@ int pci_device_from_OF_node(struct device_node* node, u8* bus, u8* devfn) { unsigned int *reg; - int i; + struct pci_controller* hose; + struct pci_dev* dev; if (!have_of) return -ENODEV; + /* Make sure it's really a PCI device */ + hose = pci_find_hose_for_OF_device(node); + if (!hose || !hose->arch_data) + return -ENODEV; + if (!scan_OF_pci_childs(((struct device_node*)hose->arch_data)->child, + find_OF_pci_device_filter, (void *)node)) + return -ENODEV; reg = (unsigned int *) get_property(node, "reg", 0); if (!reg) return -ENODEV; *bus = (reg[0] >> 16) & 0xff; - for (i=0; pci_to_OF_bus_map && i<pci_bus_count; i++) - if (pci_to_OF_bus_map[i] == *bus) { - *bus = i; - break; - } *devfn = ((reg[0] >> 8) & 0xff); - return 0; + + /* Ok, here we need some tweak. If we have already renumbered + * all busses, we can't rely on the OF bus number any more. + * the pci_to_OF_bus_map is not enough as several PCI busses + * may match the same OF bus number. + */ + if (!pci_to_OF_bus_map) + return 0; + pci_for_each_dev(dev) { + if (pci_to_OF_bus_map[dev->bus->number] != *bus) + continue; + if (dev->devfn != *devfn) + continue; + *bus = dev->bus->number; + return 0; + } + return -ENODEV; } void __init @@ -709,6 +994,24 @@ pci_process_bridge_OF_ranges(struct pci_controller *hose, ranges += np; } } + +/* We create the "pci-OF-bus-map" property now so it appears in the + * /proc device tree + */ +void __init +pci_create_OF_bus_map(void) +{ + struct property* of_prop; + + of_prop = (struct property*) alloc_bootmem(sizeof(struct property) + 256); + if (of_prop && find_path_device("/")) { + memset(of_prop, -1, sizeof(struct property) + 256); + of_prop->name = "pci-OF-bus-map"; + of_prop->length = 256; + of_prop->value = (unsigned char *)&of_prop[1]; + prom_add_property(find_path_device("/"), of_prop); + } +} #endif /* CONFIG_ALL_PPC */ void __init @@ -739,6 +1042,10 @@ pcibios_init(void) if (pci_assign_all_busses && have_of) pcibios_make_OF_bus_map(); + /* Do machine dependent PCI interrupt routing */ + if (ppc_md.pci_swizzle && ppc_md.pci_map_irq) + pci_fixup_irqs(ppc_md.pci_swizzle, ppc_md.pci_map_irq); + /* Call machine dependant fixup */ if (ppc_md.pcibios_fixup) ppc_md.pcibios_fixup(); @@ -754,10 +1061,23 @@ pcibios_init(void) ppc_md.pcibios_after_init(); } -int __init -pcibios_assign_all_busses(void) +unsigned char __init +common_swizzle(struct pci_dev *dev, unsigned char *pinp) { - return pci_assign_all_busses; + struct pci_controller *hose = dev->sysdata; + + if (dev->bus->number != hose->first_busno) { + u8 pin = *pinp; + do { + pin = bridge_swizzle(pin, PCI_SLOT(dev->devfn)); + /* Move up the chain of bridges. */ + dev = dev->bus->self; + } while (dev->bus->self); + *pinp = pin; + + /* The slot is the idsel of the last bridge. */ + } + return PCI_SLOT(dev->devfn); } void __init @@ -863,7 +1183,7 @@ int pcibios_enable_device(struct pci_dev *dev) old_cmd = cmd; for (idx=0; idx<6; idx++) { r = &dev->resource[idx]; - if (!r->start && r->end) { + if (r->flags & IORESOURCE_UNSET) { printk(KERN_ERR "PCI: Device %s not available because of resource collisions\n", dev->slot_name); return -EINVAL; } @@ -1152,6 +1472,19 @@ sys_pciconfig_iobase(long which, unsigned long bus, unsigned long devfn) return result; } +void __init +pci_init_resource(struct resource *res, unsigned long start, unsigned long end, + int flags, char *name) +{ + res->start = start; + res->end = end; + res->flags = flags; + res->name = name; + res->parent = NULL; + res->sibling = NULL; + res->child = NULL; +} + /* * Null PCI config access functions, for the case when we can't * find a hose. diff --git a/arch/ppc/kernel/pci.h b/arch/ppc/kernel/pci.h deleted file mode 100644 index 61b2e187c331..000000000000 --- a/arch/ppc/kernel/pci.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * BK Id: SCCS/s.pci.h 1.10 08/08/01 16:35:43 paulus - */ - -#ifndef __PPC_KERNEL_PCI_H__ -#define __PPC_KERNEL_PCI_H__ - -/* Configure those in your xxx_init() or xxx_setup_arch() function */ -extern unsigned long isa_io_base; -extern unsigned long isa_mem_base; -extern unsigned long pci_dram_offset; - -/* Set this to 1 if you want the kernel to re-assign all PCI - * bus numbers - */ -extern int pci_assign_all_busses; - - -extern struct pci_controller* pcibios_alloc_controller(void); -extern struct pci_controller* pci_find_hose_for_OF_device( - struct device_node* node); - -extern void setup_indirect_pci(struct pci_controller* hose, - u32 cfg_addr, u32 cfg_data); -extern void setup_grackle(struct pci_controller *hose); - -#endif /* __PPC_KERNEL_PCI_H__ */ diff --git a/arch/ppc/kernel/pci_auto.c b/arch/ppc/kernel/pci_auto.c new file mode 100644 index 000000000000..1f716f296802 --- /dev/null +++ b/arch/ppc/kernel/pci_auto.c @@ -0,0 +1,519 @@ +/* + * arch/ppc/kernel/pci_auto.c + * + * PCI autoconfiguration library + * + * Author: Matt Porter <mporter@mvista.com> + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +/* + * The CardBus support is very preliminary. Preallocating space is + * the way to go but will require some change in card services to + * make it useful. Eventually this will ensure that we can put + * multiple CB bridges behind multiple P2P bridges. For now, at + * least it ensures that we place the CB bridge BAR and assigned + * initial bus numbers. I definitely need to do something about + * the lack of 16-bit I/O support. -MDP + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/pci.h> + +#include <asm/pci-bridge.h> + +#define PCIAUTO_IDE_MODE_MASK 0x05 + +#undef DEBUG + +#ifdef DEBUG +#define DBG(x...) printk(x) +#else +#define DBG(x...) +#endif /* DEBUG */ + +static int pciauto_upper_iospc; +static int pciauto_upper_memspc; + +void __init pciauto_setup_bars(struct pci_controller *hose, + int current_bus, + int pci_devfn, + int bar_limit) +{ + int bar_response, bar_size, bar_value; + int bar, addr_mask; + int * upper_limit; + int found_mem64 = 0; + + DBG("PCI Autoconfig: Found Bus %d, Device %d, Function %d\n", + current_bus, PCI_SLOT(pci_devfn), PCI_FUNC(pci_devfn) ); + + for (bar = PCI_BASE_ADDRESS_0; bar <= bar_limit; bar+=4) { + /* Tickle the BAR and get the response */ + early_write_config_dword(hose, + current_bus, + pci_devfn, + bar, + 0xffffffff); + early_read_config_dword(hose, + current_bus, + pci_devfn, + bar, + &bar_response); + + /* If BAR is not implemented go to the next BAR */ + if (!bar_response) + continue; + + /* Check the BAR type and set our address mask */ + if (bar_response & PCI_BASE_ADDRESS_SPACE) { + addr_mask = PCI_BASE_ADDRESS_IO_MASK; + upper_limit = &pciauto_upper_iospc; + DBG("PCI Autoconfig: BAR 0x%x, I/O, ", bar); + } else { + if ( (bar_response & PCI_BASE_ADDRESS_MEM_TYPE_MASK) == + PCI_BASE_ADDRESS_MEM_TYPE_64) + found_mem64 = 1; + + addr_mask = PCI_BASE_ADDRESS_MEM_MASK; + upper_limit = &pciauto_upper_memspc; + DBG("PCI Autoconfig: BAR 0x%x, Mem ", bar); + } + + /* Calculate requested size */ + bar_size = ~(bar_response & addr_mask) + 1; + + /* Allocate a base address */ + bar_value = (*upper_limit - bar_size) & ~(bar_size - 1); + + /* Write it out and update our limit */ + early_write_config_dword(hose, + current_bus, + pci_devfn, + bar, + bar_value); + + *upper_limit = bar_value; + + /* + * If we are a 64-bit decoder then increment to the + * upper 32 bits of the bar and force it to locate + * in the lower 4GB of memory. + */ + if (found_mem64) { + bar += 4; + early_write_config_dword(hose, + current_bus, + pci_devfn, + bar, + 0x00000000); + found_mem64 = 0; + } + + DBG("size=0x%x, address=0x%x\n", + bar_size, bar_value); + } + +} + +void __init pciauto_prescan_setup_bridge(struct pci_controller *hose, + int current_bus, + int pci_devfn, + int sub_bus, + int *iosave, + int *memsave) +{ + /* Configure bus number registers */ + early_write_config_byte(hose, + current_bus, + pci_devfn, + PCI_PRIMARY_BUS, + current_bus); + early_write_config_byte(hose, + current_bus, + pci_devfn, + PCI_SECONDARY_BUS, + sub_bus + 1); + early_write_config_byte(hose, + current_bus, + pci_devfn, + PCI_SUBORDINATE_BUS, + 0xff); + + /* Round memory allocator to 1MB boundary */ + pciauto_upper_memspc &= ~(0x100000 - 1); + *memsave = pciauto_upper_memspc; + + /* Round I/O allocator to 4KB boundary */ + pciauto_upper_iospc &= ~(0x1000 - 1); + *iosave = pciauto_upper_iospc; + + /* Set up memory and I/O filter limits, assume 32-bit I/O space */ + early_write_config_word(hose, + current_bus, + pci_devfn, + PCI_MEMORY_LIMIT, + ((pciauto_upper_memspc - 1) & 0xfff00000) >> 16); + early_write_config_byte(hose, + current_bus, + pci_devfn, + PCI_IO_LIMIT, + ((pciauto_upper_iospc - 1) & 0x0000f000) >> 8); + early_write_config_word(hose, + current_bus, + pci_devfn, + PCI_IO_LIMIT_UPPER16, + ((pciauto_upper_iospc - 1) & 0xffff0000) >> 16); + + /* Zero upper 32 bits of prefetchable base/limit */ + early_write_config_dword(hose, + current_bus, + pci_devfn, + PCI_PREF_BASE_UPPER32, + 0); + early_write_config_dword(hose, + current_bus, + pci_devfn, + PCI_PREF_LIMIT_UPPER32, + 0); +} + +void __init pciauto_postscan_setup_bridge(struct pci_controller *hose, + int current_bus, + int pci_devfn, + int sub_bus, + int *iosave, + int *memsave) +{ + int cmdstat; + + /* Configure bus number registers */ + early_write_config_byte(hose, + current_bus, + pci_devfn, + PCI_SUBORDINATE_BUS, + sub_bus); + + /* + * Round memory allocator to 1MB boundary. + * If no space used, allocate minimum. + */ + pciauto_upper_memspc &= ~(0x100000 - 1); + if (*memsave == pciauto_upper_memspc) + pciauto_upper_memspc -= 0x00100000; + + early_write_config_word(hose, + current_bus, + pci_devfn, + PCI_MEMORY_BASE, + pciauto_upper_memspc >> 16); + + /* Allocate 1MB for pre-fretch */ + early_write_config_word(hose, + current_bus, + pci_devfn, + PCI_PREF_MEMORY_LIMIT, + ((pciauto_upper_memspc - 1) & 0xfff00000) >> 16); + + pciauto_upper_memspc -= 0x100000; + + early_write_config_word(hose, + current_bus, + pci_devfn, + PCI_PREF_MEMORY_BASE, + pciauto_upper_memspc >> 16); + + /* Round I/O allocator to 4KB boundary */ + pciauto_upper_iospc &= ~(0x1000 - 1); + if (*iosave == pciauto_upper_iospc) + pciauto_upper_iospc -= 0x1000; + + early_write_config_byte(hose, + current_bus, + pci_devfn, + PCI_IO_BASE, + (pciauto_upper_iospc & 0x0000f000) >> 8); + early_write_config_word(hose, + current_bus, + pci_devfn, + PCI_IO_BASE_UPPER16, + pciauto_upper_iospc >> 16); + + /* Enable memory and I/O accesses, enable bus master */ + early_read_config_dword(hose, + current_bus, + pci_devfn, + PCI_COMMAND, + &cmdstat); + early_write_config_dword(hose, + current_bus, + pci_devfn, + PCI_COMMAND, + cmdstat | + PCI_COMMAND_IO | + PCI_COMMAND_MEMORY | + PCI_COMMAND_MASTER); +} + +void __init pciauto_prescan_setup_cardbus_bridge(struct pci_controller *hose, + int current_bus, + int pci_devfn, + int sub_bus, + int *iosave, + int *memsave) +{ + /* Configure bus number registers */ + early_write_config_byte(hose, + current_bus, + pci_devfn, + PCI_PRIMARY_BUS, + current_bus); + early_write_config_byte(hose, + current_bus, + pci_devfn, + PCI_SECONDARY_BUS, + sub_bus + 1); + early_write_config_byte(hose, + current_bus, + pci_devfn, + PCI_SUBORDINATE_BUS, + 0xff); + + /* Round memory allocator to 4KB boundary */ + pciauto_upper_memspc &= ~(0x1000 - 1); + *memsave = pciauto_upper_memspc; + + /* Round I/O allocator to 4 byte boundary */ + pciauto_upper_iospc &= ~(0x4 - 1); + *iosave = pciauto_upper_iospc; + + /* Set up memory and I/O filter limits, assume 32-bit I/O space */ + early_write_config_dword(hose, + current_bus, + pci_devfn, + 0x20, + pciauto_upper_memspc - 1); + early_write_config_dword(hose, + current_bus, + pci_devfn, + 0x30, + pciauto_upper_iospc - 1); +} + +void __init pciauto_postscan_setup_cardbus_bridge(struct pci_controller *hose, + int current_bus, + int pci_devfn, + int sub_bus, + int *iosave, + int *memsave) +{ + int cmdstat; + + /* + * Configure subordinate bus number. The PCI subsystem + * bus scan will renumber buses (reserving three additional + * for this PCI<->CardBus bridge for the case where a CardBus + * adapter contains a P2P or CB2CB bridge. + */ + early_write_config_byte(hose, + current_bus, + pci_devfn, + PCI_SUBORDINATE_BUS, + sub_bus); + + /* + * Reserve an additional 4MB for mem space and 16KB for + * I/O space. This should cover any additional space + * requirement of unusual CardBus devices with + * additional bridges that can consume more address space. + * + * Although pcmcia-cs currently will reprogram bridge + * windows, the goal is to add an option to leave them + * alone and use the bridge window ranges as the regions + * that are searched for free resources upon hot-insertion + * of a device. This will allow a PCI<->CardBus bridge + * configured by this routine to happily live behind a + * P2P bridge in a system. + */ + pciauto_upper_memspc -= 0x00400000; + pciauto_upper_iospc -= 0x00004000; + + /* Round memory allocator to 4KB boundary */ + pciauto_upper_memspc &= ~(0x1000 - 1); + + early_write_config_dword(hose, + current_bus, + pci_devfn, + 0x1c, + pciauto_upper_memspc); + + /* Round I/O allocator to 4 byte boundary */ + pciauto_upper_iospc &= ~(0x4 - 1); + early_write_config_dword(hose, + current_bus, + pci_devfn, + 0x2c, + pciauto_upper_iospc); + + /* Enable memory and I/O accesses, enable bus master */ + early_read_config_dword(hose, + current_bus, + pci_devfn, + PCI_COMMAND, + &cmdstat); + early_write_config_dword(hose, + current_bus, + pci_devfn, + PCI_COMMAND, + cmdstat | + PCI_COMMAND_IO | + PCI_COMMAND_MEMORY | + PCI_COMMAND_MASTER); +} + +int __init pciauto_bus_scan(struct pci_controller *hose, int current_bus) +{ + int sub_bus, pci_devfn, pci_class, cmdstat, found_multi = 0; + unsigned short vid; + unsigned char header_type; + + /* + * Fetch our I/O and memory space upper boundaries used + * to allocated base addresses on this hose. + */ + if (current_bus == hose->first_busno) { + pciauto_upper_iospc = hose->io_space.end + 1; + pciauto_upper_memspc = hose->mem_space.end + 1; + } + + sub_bus = current_bus; + + for (pci_devfn = 0; pci_devfn < 0xff; pci_devfn++) { + /* Skip our host bridge */ + if ( (current_bus == hose->first_busno) && (pci_devfn == 0) ) + continue; + + if (PCI_FUNC(pci_devfn) && !found_multi) + continue; + + /* If config space read fails from this device, move on */ + if (early_read_config_byte(hose, + current_bus, + pci_devfn, + PCI_HEADER_TYPE, + &header_type)) + continue; + + if (!PCI_FUNC(pci_devfn)) + found_multi = header_type & 0x80; + + early_read_config_word(hose, + current_bus, + pci_devfn, + PCI_VENDOR_ID, + &vid); + + if (vid != 0xffff) { + early_read_config_dword(hose, + current_bus, + pci_devfn, + PCI_CLASS_REVISION, &pci_class); + if ( (pci_class >> 16) == PCI_CLASS_BRIDGE_PCI ) { + int iosave, memsave; + + DBG("PCI Autoconfig: Found P2P bridge, device %d\n", PCI_SLOT(pci_devfn)); + /* Allocate PCI I/O and/or memory space */ + pciauto_setup_bars(hose, + current_bus, + pci_devfn, + PCI_BASE_ADDRESS_1); + + pciauto_prescan_setup_bridge(hose, + current_bus, + pci_devfn, + sub_bus, + &iosave, + &memsave); + sub_bus = pciauto_bus_scan(hose, sub_bus+1); + pciauto_postscan_setup_bridge(hose, + current_bus, + pci_devfn, + sub_bus, + &iosave, + &memsave); + } else if ((pci_class >> 16) == PCI_CLASS_BRIDGE_CARDBUS) { + int iosave, memsave; + + DBG("PCI Autoconfig: Found CardBus bridge, device %d function %d\n", PCI_SLOT(pci_devfn), PCI_FUNC(pci_devfn)); + /* Place CardBus Socket/ExCA registers */ + pciauto_setup_bars(hose, + current_bus, + pci_devfn, + PCI_BASE_ADDRESS_0); + + pciauto_prescan_setup_cardbus_bridge(hose, + current_bus, + pci_devfn, + sub_bus, + &iosave, + &memsave); + sub_bus = pciauto_bus_scan(hose, sub_bus+1); + pciauto_postscan_setup_cardbus_bridge(hose, + current_bus, + pci_devfn, + sub_bus, + &iosave, + &memsave); + } else { + if ((pci_class >> 16) == PCI_CLASS_STORAGE_IDE) { + unsigned char prg_iface; + + early_read_config_byte(hose, + current_bus, + pci_devfn, + PCI_CLASS_PROG, + &prg_iface); + if (!(prg_iface & PCIAUTO_IDE_MODE_MASK)) { + DBG("PCI Autoconfig: Skipping legacy mode IDE controller\n"); + continue; + } + } + /* Allocate PCI I/O and/or memory space */ + pciauto_setup_bars(hose, + current_bus, + pci_devfn, + PCI_BASE_ADDRESS_5); + + /* + * Enable some standard settings + */ + early_read_config_dword(hose, + current_bus, + pci_devfn, + PCI_COMMAND, + &cmdstat); + early_write_config_dword(hose, + current_bus, + pci_devfn, + PCI_COMMAND, + cmdstat | + PCI_COMMAND_IO | + PCI_COMMAND_MEMORY | + PCI_COMMAND_MASTER); + early_write_config_byte(hose, + current_bus, + pci_devfn, + PCI_LATENCY_TIMER, + 0x80); + } + } + } + return sub_bus; +} diff --git a/arch/ppc/kernel/pmac_pic.h b/arch/ppc/kernel/pmac_pic.h deleted file mode 100644 index 2e27ea202b2b..000000000000 --- a/arch/ppc/kernel/pmac_pic.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * BK Id: SCCS/s.pmac_pic.h 1.9 08/19/01 22:23:04 paulus - */ -#ifndef _PPC_KERNEL_PMAC_PIC_H -#define _PPC_KERNEL_PMAC_PIC_H - -#include "local_irq.h" - -extern struct hw_interrupt_type pmac_pic; - -void pmac_pic_init(void); -int pmac_get_irq(struct pt_regs *regs); - -#endif /* _PPC_KERNEL_PMAC_PIC_H */ diff --git a/arch/ppc/kernel/ppc-stub.c b/arch/ppc/kernel/ppc-stub.c index 5ace6d58bc38..aa79ba92390b 100644 --- a/arch/ppc/kernel/ppc-stub.c +++ b/arch/ppc/kernel/ppc-stub.c @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.ppc-stub.c 1.6 05/17/01 18:14:21 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * ppc-stub.c: KGDB support for the Linux kernel. @@ -61,7 +61,7 @@ * * The following gdb commands are supported: * - * command function Return value + * command function Return value * * g return the value of the CPU registers hex data or ENN * G set the value of the CPU registers OK or ENN @@ -131,12 +131,16 @@ static int kgdb_started; static u_int fault_jmp_buf[100]; static int kdebug; + static const char hexchars[]="0123456789abcdef"; /* Place where we save old trap entries for restoration - sparc*/ /* struct tt_entry kgdb_savettable[256]; */ /* typedef void (*trapfunc_t)(void); */ +static void kgdb_fault_handler(struct pt_regs *regs); +static void handle_exception (struct pt_regs *regs); + #if 0 /* Install an exception handler for kgdb */ static void exceptionHandler(int tnum, unsigned int *tfunc) @@ -188,14 +192,45 @@ static unsigned char * mem2hex(char *mem, char *buf, int count) { unsigned char ch; + unsigned short tmp_s; + unsigned long tmp_l; if (kgdb_setjmp((long*)fault_jmp_buf) == 0) { debugger_fault_handler = kgdb_fault_handler; - while (count-- > 0) { - ch = *mem++; - *buf++ = hexchars[ch >> 4]; - *buf++ = hexchars[ch & 0xf]; + + /* Accessing 16 bit and 32 bit objects in a single + ** load instruction is required to avoid bad side + ** effects for some IO registers. + */ + + if ((count == 2) && (((long)mem & 1) == 0)) { + tmp_s = *(unsigned short *)mem; + mem += 2; + *buf++ = hexchars[(tmp_s >> 12) & 0xf]; + *buf++ = hexchars[(tmp_s >> 8) & 0xf]; + *buf++ = hexchars[(tmp_s >> 4) & 0xf]; + *buf++ = hexchars[tmp_s & 0xf]; + + } else if ((count == 4) && (((long)mem & 3) == 0)) { + tmp_l = *(unsigned int *)mem; + mem += 4; + *buf++ = hexchars[(tmp_l >> 28) & 0xf]; + *buf++ = hexchars[(tmp_l >> 24) & 0xf]; + *buf++ = hexchars[(tmp_l >> 20) & 0xf]; + *buf++ = hexchars[(tmp_l >> 16) & 0xf]; + *buf++ = hexchars[(tmp_l >> 12) & 0xf]; + *buf++ = hexchars[(tmp_l >> 8) & 0xf]; + *buf++ = hexchars[(tmp_l >> 4) & 0xf]; + *buf++ = hexchars[tmp_l & 0xf]; + + } else { + while (count-- > 0) { + ch = *mem++; + *buf++ = hexchars[ch >> 4]; + *buf++ = hexchars[ch & 0xf]; + } } + } else { /* error condition */ } @@ -210,17 +245,58 @@ mem2hex(char *mem, char *buf, int count) static char * hex2mem(char *buf, char *mem, int count) { - int i; unsigned char ch; + int i; + char *orig_mem; + unsigned short tmp_s; + unsigned long tmp_l; + + orig_mem = mem; if (kgdb_setjmp((long*)fault_jmp_buf) == 0) { debugger_fault_handler = kgdb_fault_handler; - for (i=0; i<count; i++) { - ch = hex(*buf++) << 4; - ch |= hex(*buf++); - *mem++ = ch; + + /* Accessing 16 bit and 32 bit objects in a single + ** store instruction is required to avoid bad side + ** effects for some IO registers. + */ + + if ((count == 2) && (((long)mem & 1) == 0)) { + tmp_s = hex(*buf++) << 12; + tmp_s |= hex(*buf++) << 8; + tmp_s |= hex(*buf++) << 4; + tmp_s |= hex(*buf++); + + *(unsigned short *)mem = tmp_s; + mem += 2; + + } else if ((count == 4) && (((long)mem & 3) == 0)) { + tmp_l = hex(*buf++) << 28; + tmp_l |= hex(*buf++) << 24; + tmp_l |= hex(*buf++) << 20; + tmp_l |= hex(*buf++) << 16; + tmp_l |= hex(*buf++) << 12; + tmp_l |= hex(*buf++) << 8; + tmp_l |= hex(*buf++) << 4; + tmp_l |= hex(*buf++); + + *(unsigned long *)mem = tmp_l; + mem += 4; + + } else { + for (i=0; i<count; i++) { + ch = hex(*buf++) << 4; + ch |= hex(*buf++); + *mem++ = ch; + } } - flush_icache_range((int)mem, (int)mem+count); + + + /* + ** Flush the data cache, invalidate the instruction cache. + */ + flush_icache_range((int)orig_mem, (int)orig_mem + count - 1); + } else { /* error condition */ } @@ -253,14 +329,14 @@ hexToInt(char **ptr, int *intValue) (*ptr)++; } } else { - /* error condition */ + /* error condition */ } debugger_fault_handler = 0; return (numChars); } -/* scan for the sequence $<data>#<checksum> */ +/* scan for the sequence $<data>#<checksum> */ static void getpacket(char *buffer) { @@ -316,14 +392,14 @@ getpacket(char *buffer) } while (checksum != xmitcsum); } -/* send the packet in buffer. */ +/* send the packet in buffer. */ static void putpacket(unsigned char *buffer) { unsigned char checksum; int count; unsigned char ch, recv; - /* $<packet info>#<checksum>. */ + /* $<packet info>#<checksum>. */ do { putDebugChar('$'); checksum = 0; @@ -428,7 +504,7 @@ int kgdb_dabr_match(struct pt_regs *regs) return 1; } -/* Convert the SPARC hardware trap type code to a unix signal number. */ +/* Convert the hardware trap type code to a unix signal number. */ /* * This table contains the mapping between PowerPC hardware trap types, and * signals, which are primarily what GDB understands. @@ -438,20 +514,47 @@ static struct hard_trap_info unsigned int tt; /* Trap type code for powerpc */ unsigned char signo; /* Signal that we map this trap into */ } hard_trap_info[] = { - { 0x200, SIGSEGV }, /* machine check */ - { 0x300, SIGSEGV }, /* address error (store) */ - { 0x400, SIGBUS }, /* instruction bus error */ - { 0x500, SIGINT }, /* interrupt */ - { 0x600, SIGBUS }, /* alingment */ - { 0x700, SIGTRAP }, /* breakpoint trap */ - { 0x800, SIGFPE }, /* fpu unavail */ - { 0x900, SIGALRM }, /* decrementer */ - { 0xa00, SIGILL }, /* reserved */ - { 0xb00, SIGILL }, /* reserved */ - { 0xc00, SIGCHLD }, /* syscall */ - { 0xd00, SIGTRAP }, /* single-step/watch */ - { 0xe00, SIGFPE }, /* fp assist */ +#if defined(CONFIG_4xx) + { 0x100, SIGINT }, /* critical input interrupt */ + { 0x200, SIGSEGV }, /* machine check */ + { 0x300, SIGSEGV }, /* data storage */ + { 0x400, SIGBUS }, /* instruction storage */ + { 0x500, SIGINT }, /* interrupt */ + { 0x600, SIGBUS }, /* alignment */ + { 0x700, SIGILL }, /* program */ + { 0x800, SIGILL }, /* reserved */ + { 0x900, SIGILL }, /* reserved */ + { 0xa00, SIGILL }, /* reserved */ + { 0xb00, SIGILL }, /* reserved */ + { 0xc00, SIGCHLD }, /* syscall */ + { 0xd00, SIGILL }, /* reserved */ + { 0xe00, SIGILL }, /* reserved */ + { 0xf00, SIGILL }, /* reserved */ + /* + ** 0x1000 PIT + ** 0x1010 FIT + ** 0x1020 watchdog + ** 0x1100 data TLB miss + ** 0x1200 instruction TLB miss + */ + { 0x2000, SIGTRAP}, /* debug */ +#else + { 0x200, SIGSEGV }, /* machine check */ + { 0x300, SIGSEGV }, /* address error (store) */ + { 0x400, SIGBUS }, /* instruction bus error */ + { 0x500, SIGINT }, /* interrupt */ + { 0x600, SIGBUS }, /* alingment */ + { 0x700, SIGTRAP }, /* breakpoint trap */ + { 0x800, SIGFPE }, /* fpu unavail */ + { 0x900, SIGALRM }, /* decrementer */ + { 0xa00, SIGILL }, /* reserved */ + { 0xb00, SIGILL }, /* reserved */ + { 0xc00, SIGCHLD }, /* syscall */ + { 0xd00, SIGTRAP }, /* single-step/watch */ + { 0xe00, SIGFPE }, /* fp assist */ +#endif { 0, 0} /* Must be last */ + }; static int computeSignal(unsigned int tt) @@ -462,7 +565,7 @@ static int computeSignal(unsigned int tt) if (ht->tt == tt) return ht->signo; - return SIGHUP; /* default for things we don't know about */ + return SIGHUP; /* default for things we don't know about */ } #define PC_REGNUM 64 @@ -493,7 +596,7 @@ handle_exception (struct pt_regs *regs) #ifdef KGDB_DEBUG printk("kgdb: entering handle_exception; trap [0x%x]\n", - (unsigned int)regs->trap); + (unsigned int)regs->trap); #endif kgdb_interruptible(0); @@ -510,7 +613,7 @@ handle_exception (struct pt_regs *regs) sigval = computeSignal(regs->trap); ptr = remcomOutBuffer; -#if 0 +#if defined(CONFIG_4xx) *ptr++ = 'S'; *ptr++ = hexchars[sigval >> 4]; *ptr++ = hexchars[sigval & 0xf]; @@ -533,6 +636,8 @@ handle_exception (struct pt_regs *regs) *ptr++ = 0; putpacket(remcomOutBuffer); + if (kdebug) + printk("remcomOutBuffer: %s\n", remcomOutBuffer); /* XXX We may want to add some features dealing with poking the * XXX page tables, ... (look at sparc-stub.c for more info) @@ -544,7 +649,7 @@ handle_exception (struct pt_regs *regs) getpacket(remcomInBuffer); switch (remcomInBuffer[0]) { - case '?': /* report most recent signal */ + case '?': /* report most recent signal */ remcomOutBuffer[0] = 'S'; remcomOutBuffer[1] = hexchars[sigval >> 4]; remcomOutBuffer[2] = hexchars[sigval & 0xf]; @@ -601,7 +706,7 @@ handle_exception (struct pt_regs *regs) } break; - case 'G': /* set the value of the CPU registers */ + case 'G': /* set the value of the CPU registers */ { ptr = &remcomInBuffer[1]; @@ -639,15 +744,14 @@ handle_exception (struct pt_regs *regs) ptr = &remcomInBuffer[1]; - if (hexToInt(&ptr, &addr) - && *ptr++ == ',' - && hexToInt(&ptr, &length)) { - if (mem2hex((char *)addr, remcomOutBuffer,length)) + if (hexToInt(&ptr, &addr) && *ptr++ == ',' + && hexToInt(&ptr, &length)) { + if (mem2hex((char *)addr, remcomOutBuffer, + length)) break; - strcpy (remcomOutBuffer, "E03"); - } else { - strcpy(remcomOutBuffer,"E01"); - } + strcpy(remcomOutBuffer, "E03"); + } else + strcpy(remcomOutBuffer, "E01"); break; case 'M': /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */ @@ -655,50 +759,63 @@ handle_exception (struct pt_regs *regs) ptr = &remcomInBuffer[1]; - if (hexToInt(&ptr, &addr) - && *ptr++ == ',' - && hexToInt(&ptr, &length) - && *ptr++ == ':') { - if (hex2mem(ptr, (char *)addr, length)) { + if (hexToInt(&ptr, &addr) && *ptr++ == ',' + && hexToInt(&ptr, &length) + && *ptr++ == ':') { + if (hex2mem(ptr, (char *)addr, length)) strcpy(remcomOutBuffer, "OK"); - } else { + else strcpy(remcomOutBuffer, "E03"); - } flush_icache_range(addr, addr+length); - } else { + } else strcpy(remcomOutBuffer, "E02"); - } break; - case 'k': /* kill the program, actually just continue */ - case 'c': /* cAA..AA Continue; address AA..AA optional */ + case 'k': /* kill the program, actually just continue */ + case 'c': /* cAA..AA Continue; address AA..AA optional */ /* try to read optional parameter, pc unchanged if no parm */ ptr = &remcomInBuffer[1]; - if (hexToInt(&ptr, &addr)) { + if (hexToInt(&ptr, &addr)) regs->nip = addr; - } /* Need to flush the instruction cache here, as we may have deposited a * breakpoint, and the icache probably has no way of knowing that a data ref to * some location may have changed something that is in the instruction cache. */ kgdb_flush_cache_all(); +#if defined(CONFIG_4xx) + strcpy(remcomOutBuffer, "OK"); + putpacket(remcomOutBuffer); +#endif set_msr(msr); + kgdb_interruptible(1); unlock_kernel(); kgdb_active = 0; + if (kdebug) { + printk("remcomInBuffer: %s\n", remcomInBuffer); + printk("remcomOutBuffer: %s\n", remcomOutBuffer); + } return; case 's': kgdb_flush_cache_all(); +#if defined(CONFIG_4xx) + regs->msr |= MSR_DE; + regs->dbcr0 |= (DBCR0_IDM | DBCR0_IC); + set_msr(msr); +#else regs->msr |= MSR_SE; -#if 0 set_msr(msr | MSR_SE); #endif unlock_kernel(); kgdb_active = 0; + if (kdebug) { + printk("remcomInBuffer: %s\n", remcomInBuffer); + printk("remcomOutBuffer: %s\n", remcomOutBuffer); + } return; case 'r': /* Reset (if user process..exit ???)*/ @@ -729,7 +846,7 @@ breakpoint(void) asm(" .globl breakinst breakinst: .long 0x7d821008 - "); + "); } /* Output string in GDB O-packet format if GDB has connected. If nothing @@ -739,24 +856,23 @@ kgdb_output_string (const char* s, unsigned int count) { char buffer[512]; - if (!kgdb_started) - return 0; + if (!kgdb_started) + return 0; - count = (count <= (sizeof(buffer) / 2 - 2)) + count = (count <= (sizeof(buffer) / 2 - 2)) ? count : (sizeof(buffer) / 2 - 2); buffer[0] = 'O'; mem2hex (s, &buffer[1], count); putpacket(buffer); - return 1; + return 1; } -#ifndef CONFIG_8xx +#if defined(CONFIG_6xx) || defined(CONFIG_POWER3) || defined(CONFIG_ISERIES) -/* I don't know why other platforms don't need this. The function for - * the 8xx is found in arch/ppc/8xx_io/uart.c. -- Dan - */ +/* This is used on arches which don't have a serial driver that maps + * the ports for us */ void kgdb_map_scc(void) { diff --git a/arch/ppc/kernel/ppc405_dma.c b/arch/ppc/kernel/ppc405_dma.c new file mode 100755 index 000000000000..8cec3683a926 --- /dev/null +++ b/arch/ppc/kernel/ppc405_dma.c @@ -0,0 +1,511 @@ +/* + * linux/arch/ppc/kernel/ppc405_dma.c + * + * BRIEF MODULE DESCRIPTION + * IBM 405 DMA Controller Functions + * + * Copyright 2000 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <linux/config.h> +#include <linux/kernel.h> +#include <asm/system.h> +#include <asm/io.h> +#include <linux/mm.h> +#include <linux/miscdevice.h> +#include <linux/init.h> +#include <linux/module.h> + +#include <asm/ppc405_dma.h> + + +/* + * Function prototypes + */ + +int hw_init_dma_channel(unsigned int, ppc_dma_ch_t *); +int init_dma_channel(unsigned int); +int get_channel_config(unsigned int, ppc_dma_ch_t *); +int set_channel_priority(unsigned int, unsigned int); +unsigned int get_peripheral_width(unsigned int); +int alloc_dma_handle(sgl_handle_t *, unsigned int, unsigned int); +void free_dma_handle(sgl_handle_t); + + +ppc_dma_ch_t dma_channels[MAX_405GP_DMA_CHANNELS]; + +/* + * Configures a DMA channel, including the peripheral bus width, if a + * peripheral is attached to the channel, the polarity of the DMAReq and + * DMAAck signals, etc. This information should really be setup by the boot + * code, since most likely the configuration won't change dynamically. + * If the kernel has to call this function, it's recommended that it's + * called from platform specific init code. The driver should not need to + * call this function. + */ +int hw_init_dma_channel(unsigned int dmanr, ppc_dma_ch_t *p_init) +{ + unsigned int polarity; + uint32_t control = 0; + ppc_dma_ch_t *p_dma_ch = &dma_channels[dmanr]; + +#ifdef DEBUG_405DMA + if (!p_init) { + printk("hw_init_dma_channel: NULL p_init\n"); + return DMA_STATUS_NULL_POINTER; + } + if (dmanr >= MAX_405GP_DMA_CHANNELS) { + printk("hw_init_dma_channel: bad channel %d\n", dmanr); + return DMA_STATUS_BAD_CHANNEL; + } +#endif + +#if DCRN_POL > 0 + polarity = mfdcr(DCRN_POL); +#else + polarity = 0; +#endif + + /* Setup the control register based on the values passed to + * us in p_init. Then, over-write the control register with this + * new value. + */ + + control |= ( + SET_DMA_CIE_ENABLE(p_init->int_enable) | /* interrupt enable */ + SET_DMA_BEN(p_init->buffer_enable) | /* buffer enable */ + SET_DMA_ETD(p_init->etd_output) | /* end of transfer pin */ + SET_DMA_TCE(p_init->tce_enable) | /* terminal count enable */ + SET_DMA_PL(p_init->pl) | /* peripheral location */ + SET_DMA_DAI(p_init->dai) | /* dest addr increment */ + SET_DMA_SAI(p_init->sai) | /* src addr increment */ + SET_DMA_PRIORITY(p_init->cp) | /* channel priority */ + SET_DMA_PW(p_init->pwidth) | /* peripheral/bus width */ + SET_DMA_PSC(p_init->psc) | /* peripheral setup cycles */ + SET_DMA_PWC(p_init->pwc) | /* peripheral wait cycles */ + SET_DMA_PHC(p_init->phc) | /* peripheral hold cycles */ + SET_DMA_PREFETCH(p_init->pf) /* read prefetch */ + ); + + switch (dmanr) { + case 0: + /* clear all polarity signals and then "or" in new signal levels */ + polarity &= ~(DMAReq0_ActiveLow | DMAAck0_ActiveLow | EOT0_ActiveLow); + polarity |= p_dma_ch->polarity; +#if DCRN_POL > 0 + mtdcr(DCRN_POL, polarity); +#endif + mtdcr(DCRN_DMACR0, control); + break; + case 1: + polarity &= ~(DMAReq1_ActiveLow | DMAAck1_ActiveLow | EOT1_ActiveLow); + polarity |= p_dma_ch->polarity; +#if DCRN_POL > 0 + mtdcr(DCRN_POL, polarity); +#endif + mtdcr(DCRN_DMACR1, control); + break; + case 2: + polarity &= ~(DMAReq2_ActiveLow | DMAAck2_ActiveLow | EOT2_ActiveLow); + polarity |= p_dma_ch->polarity; +#if DCRN_POL > 0 + mtdcr(DCRN_POL, polarity); +#endif + mtdcr(DCRN_DMACR2, control); + break; + case 3: + polarity &= ~(DMAReq3_ActiveLow | DMAAck3_ActiveLow | EOT3_ActiveLow); + polarity |= p_dma_ch->polarity; +#if DCRN_POL > 0 + mtdcr(DCRN_POL, polarity); +#endif + mtdcr(DCRN_DMACR3, control); + break; + default: + return DMA_STATUS_BAD_CHANNEL; + } + + /* save these values in our dma channel structure */ + memcpy(p_dma_ch, p_init, sizeof(ppc_dma_ch_t)); + + /* + * The peripheral width values written in the control register are: + * PW_8 0 + * PW_16 1 + * PW_32 2 + * PW_64 3 + * + * Since the DMA count register takes the number of "transfers", + * we need to divide the count sent to us in certain + * functions by the appropriate number. It so happens that our + * right shift value is equal to the peripheral width value. + */ + p_dma_ch->shift = p_init->pwidth; + + /* + * Save the control word for easy access. + */ + p_dma_ch->control = control; + + mtdcr(DCRN_DMASR, 0xffffffff); /* clear status register */ + return DMA_STATUS_GOOD; +} + + + + +/* + * This function returns the channel configuration. + */ +int get_channel_config(unsigned int dmanr, ppc_dma_ch_t *p_dma_ch) +{ + unsigned int polarity; + unsigned int control; + +#if DCRN_POL > 0 + polarity = mfdcr(DCRN_POL); +#else + polarity = 0; +#endif + + switch (dmanr) { + case 0: + p_dma_ch->polarity = + polarity & (DMAReq0_ActiveLow | DMAAck0_ActiveLow | EOT0_ActiveLow); + control = mfdcr(DCRN_DMACR0); + break; + case 1: + p_dma_ch->polarity = + polarity & (DMAReq1_ActiveLow | DMAAck1_ActiveLow | EOT1_ActiveLow); + control = mfdcr(DCRN_DMACR1); + break; + case 2: + p_dma_ch->polarity = + polarity & (DMAReq2_ActiveLow | DMAAck2_ActiveLow | EOT2_ActiveLow); + control = mfdcr(DCRN_DMACR2); + break; + case 3: + p_dma_ch->polarity = + polarity & (DMAReq3_ActiveLow | DMAAck3_ActiveLow | EOT3_ActiveLow); + control = mfdcr(DCRN_DMACR3); + break; + default: + return DMA_STATUS_BAD_CHANNEL; + } + + p_dma_ch->cp = GET_DMA_PRIORITY(control); + p_dma_ch->pwidth = GET_DMA_PW(control); + p_dma_ch->psc = GET_DMA_PSC(control); + p_dma_ch->pwc = GET_DMA_PWC(control); + p_dma_ch->phc = GET_DMA_PHC(control); + p_dma_ch->pf = GET_DMA_PREFETCH(control); + p_dma_ch->int_enable = GET_DMA_CIE_ENABLE(control); + p_dma_ch->shift = GET_DMA_PW(control); + + return DMA_STATUS_GOOD; +} + +/* + * Sets the priority for the DMA channel dmanr. + * Since this is setup by the hardware init function, this function + * can be used to dynamically change the priority of a channel. + * + * Acceptable priorities: + * + * PRIORITY_LOW + * PRIORITY_MID_LOW + * PRIORITY_MID_HIGH + * PRIORITY_HIGH + * + */ +int set_channel_priority(unsigned int dmanr, unsigned int priority) +{ + unsigned int control; + +#ifdef DEBUG_405DMA + if ( (priority != PRIORITY_LOW) && + (priority != PRIORITY_MID_LOW) && + (priority != PRIORITY_MID_HIGH) && + (priority != PRIORITY_HIGH)) { + printk("set_channel_priority: bad priority: 0x%x\n", priority); + } +#endif + + switch (dmanr) { + case 0: + control = mfdcr(DCRN_DMACR0); + control|= SET_DMA_PRIORITY(priority); + mtdcr(DCRN_DMACR0, control); + break; + case 1: + control = mfdcr(DCRN_DMACR1); + control|= SET_DMA_PRIORITY(priority); + mtdcr(DCRN_DMACR1, control); + break; + case 2: + control = mfdcr(DCRN_DMACR2); + control|= SET_DMA_PRIORITY(priority); + mtdcr(DCRN_DMACR2, control); + break; + case 3: + control = mfdcr(DCRN_DMACR3); + control|= SET_DMA_PRIORITY(priority); + mtdcr(DCRN_DMACR3, control); + break; + default: +#ifdef DEBUG_405DMA + printk("set_channel_priority: bad channel: %d\n", dmanr); +#endif + return DMA_STATUS_BAD_CHANNEL; + } + return DMA_STATUS_GOOD; +} + + + +/* + * Returns the width of the peripheral attached to this channel. This assumes + * that someone who knows the hardware configuration, boot code or some other + * init code, already set the width. + * + * The return value is one of: + * PW_8 + * PW_16 + * PW_32 + * PW_64 + * + * The function returns 0 on error. + */ +unsigned int get_peripheral_width(unsigned int dmanr) +{ + unsigned int control; + + switch (dmanr) { + case 0: + control = mfdcr(DCRN_DMACR0); + break; + case 1: + control = mfdcr(DCRN_DMACR1); + break; + case 2: + control = mfdcr(DCRN_DMACR2); + break; + case 3: + control = mfdcr(DCRN_DMACR3); + break; + default: +#ifdef DEBUG_405DMA + printk("get_peripheral_width: bad channel: %d\n", dmanr); +#endif + return 0; + } + return(GET_DMA_PW(control)); +} + + + + +/* + * Create a scatter/gather list handle. This is simply a structure which + * describes a scatter/gather list. + * + * A handle is returned in "handle" which the driver should save in order to + * be able to access this list later. A chunk of memory will be allocated + * to be used by the API for internal management purposes, including managing + * the sg list and allocating memory for the sgl descriptors. One page should + * be more than enough for that purpose. Perhaps it's a bit wasteful to use + * a whole page for a single sg list, but most likely there will be only one + * sg list per channel. + * + * Interrupt notes: + * Each sgl descriptor has a copy of the DMA control word which the DMA engine + * loads in the control register. The control word has a "global" interrupt + * enable bit for that channel. Interrupts are further qualified by a few bits + * in the sgl descriptor count register. In order to setup an sgl, we have to + * know ahead of time whether or not interrupts will be enabled at the completion + * of the transfers. Thus, enable_dma_interrupt()/disable_dma_interrupt() MUST + * be called before calling alloc_dma_handle(). If the interrupt mode will never + * change after powerup, then enable_dma_interrupt()/disable_dma_interrupt() + * do not have to be called -- interrupts will be enabled or disabled based + * on how the channel was configured after powerup by the hw_init_dma_channel() + * function. Each sgl descriptor will be setup to interrupt if an error occurs; + * however, only the last descriptor will be setup to interrupt. Thus, an + * interrupt will occur (if interrupts are enabled) only after the complete + * sgl transfer is done. + */ +int alloc_dma_handle(sgl_handle_t *phandle, unsigned int mode, unsigned int dmanr) +{ + sgl_list_info_t *psgl; + dma_addr_t dma_addr; + ppc_dma_ch_t *p_dma_ch = &dma_channels[dmanr]; + uint32_t sg_command; + void *ret; + +#ifdef DEBUG_405DMA + if (!phandle) { + printk("alloc_dma_handle: null handle pointer\n"); + return DMA_STATUS_NULL_POINTER; + } + switch (mode) { + case DMA_MODE_READ: + case DMA_MODE_WRITE: + case DMA_MODE_MM: + case DMA_MODE_MM_DEVATSRC: + case DMA_MODE_MM_DEVATDST: + break; + default: + printk("alloc_dma_handle: bad mode 0x%x\n", mode); + return DMA_STATUS_BAD_MODE; + } + if (dmanr >= MAX_405GP_DMA_CHANNELS) { + printk("alloc_dma_handle: invalid channel 0x%x\n", dmanr); + return DMA_STATUS_BAD_CHANNEL; + } +#endif + + /* Get a page of memory, which is zeroed out by pci_alloc_consistent() */ + +/* wrong not a pci device - armin */ + /* psgl = (sgl_list_info_t *) pci_alloc_consistent(NULL, SGL_LIST_SIZE, &dma_addr); +*/ + + ret = consistent_alloc(GFP_ATOMIC |GFP_DMA, SGL_LIST_SIZE, &dma_addr); + if (ret != NULL) { + memset(ret, 0,SGL_LIST_SIZE ); + psgl = (sgl_list_info_t *) ret; + } + + + if (psgl == NULL) { + *phandle = (sgl_handle_t)NULL; + return DMA_STATUS_OUT_OF_MEMORY; + } + + psgl->dma_addr = dma_addr; + psgl->dmanr = dmanr; + + /* + * Modify and save the control word. These word will get written to each sgl + * descriptor. The DMA engine then loads this control word into the control + * register every time it reads a new descriptor. + */ + psgl->control = p_dma_ch->control; + psgl->control &= ~(DMA_TM_MASK | DMA_TD); /* clear all "mode" bits first */ + psgl->control |= (mode | DMA_CH_ENABLE); /* save the control word along with the mode */ + + if (p_dma_ch->int_enable) { + psgl->control |= DMA_CIE_ENABLE; /* channel interrupt enabled */ + } + else { + psgl->control &= ~DMA_CIE_ENABLE; + } + +#if DCRN_ASGC > 0 + sg_command = mfdcr(DCRN_ASGC); + switch (dmanr) { + case 0: + sg_command |= SSG0_MASK_ENABLE; + break; + case 1: + sg_command |= SSG1_MASK_ENABLE; + break; + case 2: + sg_command |= SSG2_MASK_ENABLE; + break; + case 3: + sg_command |= SSG3_MASK_ENABLE; + break; + default: +#ifdef DEBUG_405DMA + printk("alloc_dma_handle: bad channel: %d\n", dmanr); +#endif + free_dma_handle((sgl_handle_t)psgl); + *phandle = (sgl_handle_t)NULL; + return DMA_STATUS_BAD_CHANNEL; + } + + mtdcr(DCRN_ASGC, sg_command); /* enable writing to this channel's sgl control bits */ +#else + (void)sg_command; +#endif + psgl->sgl_control = SG_ERI_ENABLE | SG_LINK; /* sgl descriptor control bits */ + + if (p_dma_ch->int_enable) { + if (p_dma_ch->tce_enable) + psgl->sgl_control |= SG_TCI_ENABLE; + else + psgl->sgl_control |= SG_ETI_ENABLE; + } + + *phandle = (sgl_handle_t)psgl; + return DMA_STATUS_GOOD; +} + + + +/* + * Destroy a scatter/gather list handle that was created by alloc_dma_handle(). + * The list must be empty (contain no elements). + */ +void free_dma_handle(sgl_handle_t handle) +{ + sgl_list_info_t *psgl = (sgl_list_info_t *)handle; + + if (!handle) { +#ifdef DEBUG_405DMA + printk("free_dma_handle: got NULL\n"); +#endif + return; + } + else if (psgl->phead) { +#ifdef DEBUG_405DMA + printk("free_dma_handle: list not empty\n"); +#endif + return; + } + else if (!psgl->dma_addr) { /* should never happen */ +#ifdef DEBUG_405DMA + printk("free_dma_handle: no dma address\n"); +#endif + return; + } + + /* wrong not a PCI device -armin */ + /* pci_free_consistent(NULL, SGL_LIST_SIZE, (void *)psgl, psgl->dma_addr); */ + // free_pages((unsigned long)psgl, get_order(SGL_LIST_SIZE)); + consistent_free((void *)psgl); + + +} + + +EXPORT_SYMBOL(hw_init_dma_channel); +EXPORT_SYMBOL(get_channel_config); +EXPORT_SYMBOL(set_channel_priority); +EXPORT_SYMBOL(get_peripheral_width); +EXPORT_SYMBOL(alloc_dma_handle); +EXPORT_SYMBOL(free_dma_handle); +EXPORT_SYMBOL(dma_channels); diff --git a/arch/ppc/kernel/ppc405_pci.c b/arch/ppc/kernel/ppc405_pci.c new file mode 100755 index 000000000000..2e0bd345f4c9 --- /dev/null +++ b/arch/ppc/kernel/ppc405_pci.c @@ -0,0 +1,207 @@ +/* + * FILE NAME: ppc405_pci.c + * + * BRIEF MODULE DESCRIPTION: + * Based on arch/ppc/kernel/indirect.c, Copyright (C) 1998 Gabriel Paubert. + * + * Author: MontaVista Software, Inc. <source@mvista.com> + * Frank Rowand <frank_rowand@mvista.com> + * Debbie Chu <debbie_chu@mvista.com> + * + * Copyright 2000 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <linux/pci.h> +#include <asm/io.h> +#include <asm/system.h> +#include <asm/machdep.h> +#include <linux/init.h> +#include <asm/ibm4xx.h> +#include <asm/pci-bridge.h> +#include <platforms/ibm_ocp.h> + +#ifdef CONFIG_DEBUG_BRINGUP +#define DBG(x...) printk(x) +#else +#define DBG(x...) +#endif + +extern void bios_fixup(struct pci_controller *, void *); +extern int ppc405_map_irq(struct pci_dev *dev, unsigned char idsel, + unsigned char pin); +extern struct pcil0_regs *PCIL_ADDR[]; + +void +ppc405_pcibios_fixup_resources(struct pci_dev *dev) +{ + int i; + unsigned long max_host_addr; + unsigned long min_host_addr; + struct resource *res; + + /* + * openbios puts some graphics cards in the same range as the host + * controller uses to map to SDRAM. Fix it. + */ + + min_host_addr = 0; + max_host_addr = PPC405_PCI_MEM_BASE - 1; + + for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { + res = dev->resource + i; + if (!res->start) + continue; + if ((res->flags & IORESOURCE_MEM) && + (((res->start >= min_host_addr) + && (res->start <= max_host_addr)) + || ((res->end >= min_host_addr) + && (res->end <= max_host_addr)) + || ((res->start < min_host_addr) + && (res->end > max_host_addr)) + ) + ) { + + DBG(KERN_ERR "PCI: 0x%lx <= resource[%d] <= 0x%lx" + ", bus 0x%x dev 0x%2.2x.%1.1x,\n" + KERN_ERR " %s\n" + KERN_ERR " fixup will be attempted later\n", + min_host_addr, i, max_host_addr, + dev->bus->number, PCI_SLOT(dev->devfn), + PCI_FUNC(dev->devfn), dev->name); + + /* force pcibios_assign_resources() to assign a new address */ + res->end -= res->start; + res->start = 0; + } + } +} + +static int +ppc4xx_exclude_device(unsigned char bus, unsigned char devfn) +{ + /* We prevent us from seeing ourselves to avoid having + * the kernel try to remap our BAR #1 and fuck up bus + * master from external PCI devices + */ + return (bus == 0 && devfn == 0); +} + +void +ppc4xx_find_bridges(void) +{ + struct pci_controller *hose_a; + struct pcil0_regs *pcip; + unsigned int tmp_addr; + unsigned int tmp_size; + unsigned int reg_index; + unsigned int new_pmm_max; + unsigned int new_pmm_min; + + isa_io_base = 0; + isa_mem_base = 0; + pci_dram_offset = 0; + + /* Check if running in slave mode */ + if ((mfdcr(DCRN_CHPSR) & PSR_PCI_ARBIT_EN) == 0) { + printk("Running as PCI slave, kernel PCI disabled !\n"); + return; + } + /* Setup PCI32 hose */ + hose_a = pcibios_alloc_controller(); + if (!hose_a) + return; + setup_indirect_pci(hose_a, PPC405_PCI_CONFIG_ADDR, + PPC405_PCI_CONFIG_DATA); + pcip = ioremap((unsigned long) PCIL_ADDR[0], PAGE_SIZE); + if (pcip != NULL) { + +#if defined(CONFIG_BIOS_FIXUP) + bios_fixup(hose_a, pcip); +#endif + new_pmm_min = 0xffffffff; + for (reg_index = 0; reg_index < 3; reg_index++) { + tmp_size = in_le32((void *) &(pcip->pmm[reg_index].ma)); // *_PMM0MA + if (tmp_size & 0x1) { + tmp_addr = in_le32((void *) &(pcip->pmm[reg_index].pcila)); // *_PMM0PCILA + if (tmp_addr < PPC405_PCI_PHY_MEM_BASE) { + printk(KERN_DEBUG + "Disabling mapping to PCI mem addr 0x%8.8x\n", + tmp_addr); + out_le32((void *) &(pcip->pmm[reg_index].ma), tmp_size & ~1); // *_PMMOMA + } else { + tmp_addr = in_le32((void *) &(pcip->pmm[reg_index].la)); // *_PMMOLA + if (tmp_addr < new_pmm_min) + new_pmm_min = tmp_addr; + tmp_addr = + tmp_addr + (0xffffffff - + (tmp_size & + 0xffffc000)); + if (tmp_addr > PPC405_PCI_UPPER_MEM) { + new_pmm_max = tmp_addr; // PPC405_PCI_UPPER_MEM + } else { + new_pmm_max = + PPC405_PCI_UPPER_MEM; + } + } + } + + } // for + + iounmap(pcip); + } + hose_a->first_busno = 0; + hose_a->last_busno = 0xff; + hose_a->pci_mem_offset = 0; + + /* Setup bridge memory/IO ranges & resources + * TODO: Handle firmwares setting up a legacy ISA mem base + */ + hose_a->io_space.start = PPC405_PCI_LOWER_IO; + hose_a->io_space.end = PPC405_PCI_UPPER_IO; + hose_a->mem_space.start = new_pmm_min; + hose_a->mem_space.end = new_pmm_max; + hose_a->io_base_phys = PPC405_PCI_PHY_IO_BASE; + hose_a->io_base_virt = ioremap(hose_a->io_base_phys, 0x10000); + hose_a->io_resource.start = 0; + hose_a->io_resource.end = PPC405_PCI_UPPER_IO-PPC405_PCI_LOWER_IO; + hose_a->io_resource.flags = IORESOURCE_IO; + hose_a->io_resource.name = "PCI I/O"; + hose_a->mem_resources[0].start = new_pmm_min; + hose_a->mem_resources[0].end = new_pmm_max; + hose_a->mem_resources[0].flags = IORESOURCE_MEM; + hose_a->mem_resources[0].name = "PCI Memory"; + isa_io_base = (int)hose_a->io_base_virt; + isa_mem_base = 0; /* ISA not implemented */ + ISA_DMA_THRESHOLD = 0x00ffffff; /* ??? ISA not implemented */ + + /* Scan busses & initial setup by pci_auto */ + hose_a->last_busno = pciauto_bus_scan(hose_a, hose_a->first_busno); + hose_a->last_busno = 0; + + /* Setup ppc_md */ + ppc_md.pcibios_fixup = NULL; + ppc_md.pci_exclude_device = ppc4xx_exclude_device; + ppc_md.pcibios_fixup_resources = ppc405_pcibios_fixup_resources; + ppc_md.pci_swizzle = common_swizzle; + ppc_md.pci_map_irq = ppc405_map_irq; +} diff --git a/arch/ppc/kernel/ppc4xx_kgdb.c b/arch/ppc/kernel/ppc4xx_kgdb.c new file mode 100644 index 000000000000..810a0310a1e8 --- /dev/null +++ b/arch/ppc/kernel/ppc4xx_kgdb.c @@ -0,0 +1,124 @@ +#include <linux/config.h> +#include <linux/types.h> +#include <asm/ibm4xx.h> +#include <linux/kernel.h> + + + +#define LSR_DR 0x01 /* Data ready */ +#define LSR_OE 0x02 /* Overrun */ +#define LSR_PE 0x04 /* Parity error */ +#define LSR_FE 0x08 /* Framing error */ +#define LSR_BI 0x10 /* Break */ +#define LSR_THRE 0x20 /* Xmit holding register empty */ +#define LSR_TEMT 0x40 /* Xmitter empty */ +#define LSR_ERR 0x80 /* Error */ + +#include <platforms/ibm_ocp.h> + +extern struct NS16550* COM_PORTS[]; +#ifndef NULL +#define NULL 0x00 +#endif + +static volatile struct NS16550 *kgdb_debugport = NULL; + +volatile struct NS16550 * +NS16550_init(int chan) +{ + volatile struct NS16550 *com_port; + int quot; +#ifdef BASE_BAUD + quot = BASE_BAUD / 9600; +#else + quot = 0x000c; /* 0xc = 9600 baud (on a pc) */ +#endif + + com_port = (struct NS16550 *) COM_PORTS[chan]; + + com_port->lcr = 0x00; + com_port->ier = 0xFF; + com_port->ier = 0x00; + com_port->lcr = com_port->lcr | 0x80; /* Access baud rate */ + com_port->dll = ( quot & 0x00ff ); /* 0xc = 9600 baud */ + com_port->dlm = ( quot & 0xff00 ) >> 8; + com_port->lcr = 0x03; /* 8 data, 1 stop, no parity */ + com_port->mcr = 0x00; /* RTS/DTR */ + com_port->fcr = 0x07; /* Clear & enable FIFOs */ + + return( com_port ); +} + + +void +NS16550_putc(volatile struct NS16550 *com_port, unsigned char c) +{ + while ((com_port->lsr & LSR_THRE) == 0) + ; + com_port->thr = c; + return; +} + +unsigned char +NS16550_getc(volatile struct NS16550 *com_port) +{ + while ((com_port->lsr & LSR_DR) == 0) + ; + return (com_port->rbr); +} + +unsigned char +NS16550_tstc(volatile struct NS16550 *com_port) +{ + return ((com_port->lsr & LSR_DR) != 0); +} + + +#if defined(CONFIG_KGDB_TTYS0) +#define KGDB_PORT 0 +#elif defined(CONFIG_KGDB_TTYS1) +#define KGDB_PORT 1 +#elif defined(CONFIG_KGDB_TTYS2) +#define KGDB_PORT 2 +#elif defined(CONFIG_KGDB_TTYS3) +#define KGDB_PORT 3 +#else +#error "invalid kgdb_tty port" +#endif + +void putDebugChar( unsigned char c ) +{ + if ( kgdb_debugport == NULL ) + kgdb_debugport = NS16550_init(KGDB_PORT); + NS16550_putc( kgdb_debugport, c ); +} + +int getDebugChar( void ) +{ + if (kgdb_debugport == NULL) + kgdb_debugport = NS16550_init(KGDB_PORT); + + return(NS16550_getc(kgdb_debugport)); +} + +void kgdb_interruptible(int enable) +{ + return; +} + +void putDebugString(char* str) +{ + while (*str != '\0') { + putDebugChar(*str); + str++; + } + putDebugChar('\r'); + return; +} + +void +kgdb_map_scc(void) +{ + printk("kgdb init \n"); + kgdb_debugport = NS16550_init(KGDB_PORT); +} diff --git a/arch/ppc/kernel/ppc4xx_pic.c b/arch/ppc/kernel/ppc4xx_pic.c index e4fcd971717f..ae96d1c722e9 100644 --- a/arch/ppc/kernel/ppc4xx_pic.c +++ b/arch/ppc/kernel/ppc4xx_pic.c @@ -1,7 +1,4 @@ /* - * BK Id: SCCS/s.ppc4xx_pic.c 1.5 05/17/01 18:14:21 cort - */ -/* * * Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu> * @@ -33,25 +30,29 @@ #include <asm/processor.h> #include <asm/system.h> #include <asm/irq.h> - -#include "local_irq.h" -#include "ppc4xx_pic.h" - +#include <asm/ibm4xx.h> +#include <asm/ppc4xx_pic.h> /* Global Variables */ struct hw_interrupt_type *ppc4xx_pic; +/* Six of one, half dozen of the other....#ifdefs, separate files, + * other tricks..... + * + * There are basically two types of interrupt controllers, the 403 AIC + * and the "others" with UIC. I just kept them both here separated + * with #ifdefs, but it seems to change depending upon how supporting + * files (like ppc4xx.h) change. -- Dan. + */ -/* Function Prototypes */ +#ifdef CONFIG_403 -static void ppc403_aic_enable(unsigned int irq); -static void ppc403_aic_disable(unsigned int irq); -static void ppc403_aic_disable_and_ack(unsigned int irq); +/* Function Prototypes */ -static void ppc405_uic_enable(unsigned int irq); -static void ppc405_uic_disable(unsigned int irq); -static void ppc405_uic_disable_and_ack(unsigned int irq); +static void ppc403_aic_enable(unsigned int irq); +static void ppc403_aic_disable(unsigned int irq); +static void ppc403_aic_disable_and_ack(unsigned int irq); static struct hw_interrupt_type ppc403_aic = { "403GC AIC", @@ -63,55 +64,11 @@ static struct hw_interrupt_type ppc403_aic = { 0 }; -static struct hw_interrupt_type ppc405_uic = { - "405GP UIC", - NULL, - NULL, - ppc405_uic_enable, - ppc405_uic_disable, - ppc405_uic_disable_and_ack, - 0 -}; - -/* - * Document me. - */ -void __init -ppc4xx_pic_init(void) -{ - unsigned long ver = PVR_VER(mfspr(SPRN_PVR)); - - switch (ver) { - - case PVR_VER(PVR_403GC): - /* - * Disable all external interrupts until they are - * explicity requested. - */ - ppc_cached_irq_mask[0] = 0; - mtdcr(DCRN_EXIER, 0); - - ppc4xx_pic = &ppc403_aic; - break; - - case PVR_VER(PVR_405GP): - ppc4xx_pic = &ppc405_uic; - break; - } - - return; -} - -/* - * XXX - Currently 403-specific! - * - * Document me. - */ int -ppc4xx_pic_get_irq(struct pt_regs *regs) +ppc403_pic_get_irq(struct pt_regs *regs) { int irq; - unsigned long bits, mask = (1 << 31); + unsigned long bits; /* * Only report the status of those interrupts that are actually @@ -123,19 +80,17 @@ ppc4xx_pic_get_irq(struct pt_regs *regs) /* * Walk through the interrupts from highest priority to lowest, and * report the first pending interrupt found. + * We want PPC, not C bit numbering, so just subtract the ffs() + * result from 32. */ + irq = 32 - ffs(bits); - for (irq = 0; irq < NR_IRQS; irq++, mask >>= 1) { - if (bits & mask) - break; - } + if (irq == NR_AIC_IRQS) + irq = -1; return (irq); } -/* - * Document me. - */ static void ppc403_aic_enable(unsigned int irq) { @@ -148,9 +103,6 @@ ppc403_aic_enable(unsigned int irq) mtdcr(DCRN_EXIER, ppc_cached_irq_mask[word]); } -/* - * Document me. - */ static void ppc403_aic_disable(unsigned int irq) { @@ -163,9 +115,6 @@ ppc403_aic_disable(unsigned int irq) mtdcr(DCRN_EXIER, ppc_cached_irq_mask[word]); } -/* - * Document me. - */ static void ppc403_aic_disable_and_ack(unsigned int irq) { @@ -179,29 +128,131 @@ ppc403_aic_disable_and_ack(unsigned int irq) mtdcr(DCRN_EXISR, (1 << (31 - bit))); } -/* - * Document me. - */ +#else /* !CONFIG_403 */ + static void ppc405_uic_enable(unsigned int irq) { - /* XXX - Implement me. */ + int bit, word; + + bit = irq & 0x1f; + word = irq >> 5; + + ppc_cached_irq_mask[word] |= 1 << (31 - bit); + mtdcr(DCRN_UIC0_ER, ppc_cached_irq_mask[word]); } -/* - * Document me. - */ static void ppc405_uic_disable(unsigned int irq) { - /* XXX - Implement me. */ + int bit, word; + + bit = irq & 0x1f; + word = irq >> 5; + + ppc_cached_irq_mask[word] &= ~(1 << (31 - bit)); + mtdcr(DCRN_UIC0_ER, ppc_cached_irq_mask[word]); } -/* - * Document me. - */ static void ppc405_uic_disable_and_ack(unsigned int irq) { - /* XXX - Implement me. */ + int bit, word; + + bit = irq & 0x1f; + word = irq >> 5; + + ppc_cached_irq_mask[word] &= ~(1 << (31 - bit)); + mtdcr(DCRN_UIC0_ER, ppc_cached_irq_mask[word]); + mtdcr(DCRN_UIC0_SR, (1 << (31 - bit))); +} + +static void +ppc405_uic_end(unsigned int irq) +{ + int bit, word; + unsigned int tr_bits; + + bit = irq & 0x1f; + word = irq >> 5; + + tr_bits = mfdcr(DCRN_UIC0_TR); + if ((tr_bits & (1 << (31 - bit))) == 0) { + /* level trigger */ + mtdcr(DCRN_UIC0_SR, 1 << (31 - bit)); + } + + if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) { + ppc_cached_irq_mask[word] |= 1 << (31 - bit); + mtdcr(DCRN_UIC0_ER, ppc_cached_irq_mask[word]); + } +} + +static struct hw_interrupt_type ppc405_uic = { +#if defined (CONFIG_405GP) + "405GP UIC", +#else + "NP405 UIC", +#endif + NULL, + NULL, + ppc405_uic_enable, + ppc405_uic_disable, + ppc405_uic_disable_and_ack, + ppc405_uic_end, + 0 +}; + +int +ppc405_pic_get_irq(struct pt_regs *regs) +{ + int irq; + unsigned long bits; + + /* + * Only report the status of those interrupts that are actually + * enabled. + */ + + bits = mfdcr(DCRN_UIC0_MSR); + + /* + * Walk through the interrupts from highest priority to lowest, and + * report the first pending interrupt found. + * We want PPC, not C bit numbering, so just subtract the ffs() + * result from 32. + */ + irq = 32 - ffs(bits); + + if (irq == NR_AIC_IRQS) + irq = -1; + + return (irq); +} +#endif + +void __init +ppc4xx_pic_init(void) +{ + /* + * Disable all external interrupts until they are + * explicity requested. + */ + ppc_cached_irq_mask[0] = 0; + +#ifdef CONFIG_403 + mtdcr(DCRN_EXIER, ppc_cached_irq_mask[0]); + + ppc4xx_pic = &ppc403_aic; + ppc_md.get_irq = ppc403_pic_get_irq; +#else + mtdcr(DCRN_UIC0_ER, ppc_cached_irq_mask[0]); + + /* Set all interrupts to non-critical. + */ + mtdcr(DCRN_UIC0_CR, 0); + + ppc4xx_pic = &ppc405_uic; + ppc_md.get_irq = ppc405_pic_get_irq; +#endif } diff --git a/arch/ppc/kernel/ppc4xx_pm.c b/arch/ppc/kernel/ppc4xx_pm.c new file mode 100644 index 000000000000..1f49c1f5e1f6 --- /dev/null +++ b/arch/ppc/kernel/ppc4xx_pm.c @@ -0,0 +1,75 @@ +/* + * file: ppc4xx_pm.c + * + * This an attempt to get Power Management going for the IBM 4xx processor. + * This was derived from the ppc4xx._setup.c file + * + * Armin Kuster akuster@mvista.com + * Jan 2002 + * + * + * Copyright 2002 MontaVista Softare Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Version 1.0 (02/14/01) - A. Kuster + * Initial version - moved pm code from ppc4xx_setup.c + * + * 1.1 02/21/01 - A. Kuster + * minor fixes, init value to 0 & += to &= + * added stb03 ifdef for 2nd i2c device + */ + +#include <linux/config.h> +#include <linux/init.h> + +#include <asm/ibm4xx.h> + +void __init +ppc4xx_pm_init(void) +{ + + unsigned int value = 0; + + /* turn off unused hardware to save power */ +#ifdef CONFIG_405GP + value |= CPM_DCP; /* CodePack */ +#endif + +#if !defined(CONFIG_IBM_OCP_GPIO) + value |= CPM_GPIO0; +#endif + +#if !defined(CONFIG_PPC405_I2C_ADAP) + value |= CPM_IIC0; +#ifdef CONFIG_STB03xxx + value |= CPM_IIC1; +#endif +#endif + + +#if !defined(CONFIG_405_DMA) + value |= CPM_DMA; +#endif + + mtdcr(DCRN_CPMFR, value); + +} diff --git a/arch/ppc/kernel/ppc4xx_serial.c b/arch/ppc/kernel/ppc4xx_serial.c new file mode 100755 index 000000000000..54defaf2a92c --- /dev/null +++ b/arch/ppc/kernel/ppc4xx_serial.c @@ -0,0 +1,190 @@ + +/* + * linux/arch/ppc/kernel/ppc405_serial.c + * + * This is a fairly standard 165xx type device that will eventually + * be merged with other similar processor/boards. -- Dan + * + * BRIEF MODULE DESCRIPTION + * Console I/O support for Early kernel bringup. + * + * Copyright 2000 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * frank_rowand@mvista.com or source@mvista.com + * debbie_chu@mvista.com + * + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <linux/config.h> + +#if defined(CONFIG_IBM405GP) || defined(CONFIG_IBM405CR) + +#ifdef CONFIG_KGDB +#include <asm/kgdb.h> +#include <linux/init.h> +#endif + +#ifdef CONFIG_DEBUG_BRINGUP + +#include <linux/console.h> + +extern void ftr_reset_preferred_console(void); + + +static int ppc405_sercons_setup(struct console *co, char *options) +{ +#ifdef CONFIG_UART0_DEBUG_CONSOLE + volatile unsigned char *uart_dll = (char *)0xef600300; + volatile unsigned char *uart_fcr = (char *)0xef600302; + volatile unsigned char *uart_lcr = (char *)0xef600303; +#endif + +#ifdef CONFIG_UART1_DEBUG_CONSOLE + volatile unsigned char *uart_dll = (char *)0xef600400; + volatile unsigned char *uart_fcr = (char *)0xef600402; + volatile unsigned char *uart_lcr = (char *)0xef600403; +#endif + + *uart_lcr = *uart_lcr | 0x80; /* DLAB on */ + +/* ftr revisit - there is no config option for this +** also see include/asm-ppc/ppc405_serial.h +** +** #define CONFIG_IBM405GP_INTERNAL_CLOCK +*/ + + +#ifdef CONFIG_IBM405GP_INTERNAL_CLOCK + /* ftr revisit + ** why is bit 19 of chcr0 (0x1000) being set? + */ + /* 0x2a results in data corruption, kgdb works with 0x28 */ + *uart_dll = 0x28; /* 9600 baud */ + _put_CHCR0((_get_CHCR0() & 0xffffe000) | 0x103e); +#else + *uart_dll = 0x48; /* 9600 baud */ +#endif + *uart_lcr = *uart_lcr & 0x7f; /* DLAB off */ + + return 0; +} + + +/* + * This is a bringup hack, writing directly to uart0 or uart1 + */ + +static void +ppc405_sercons_write(struct console *co, const char *ptr, + unsigned nb) +{ + int i; + +#ifdef CONFIG_UART0_DEBUG_CONSOLE + volatile unsigned char *uart_xmit = (char *)0xef600300; + volatile unsigned char *uart_lsr = (char *)0xef600305; +#endif + +#ifdef CONFIG_UART1_DEBUG_CONSOLE + volatile unsigned char *uart_xmit = (char *)0xef600400; + volatile unsigned char *uart_lsr = (char *)0xef600405; +#endif + + for (i = 0; i < nb; ++i) { + + /* wait for transmit reg (possibly fifo) to empty */ + while ((*uart_lsr & 0x40) == 0) + ; + + *uart_xmit = (ptr[i] & 0xff); + + if (ptr[i] == '\n') { + + /* add a carriage return */ + + /* wait for transmit reg (possibly fifo) to empty */ + while ((*uart_lsr & 0x40) == 0) + ; + + *uart_xmit = '\r'; + } + } + + return; +} + + +static int +ppc405_sercons_read(struct console *co, char *ptr, unsigned nb) +{ +#ifdef CONFIG_UART0_DEBUG_CONSOLE + volatile unsigned char *uart_rcv = (char *)0xef600300; + volatile unsigned char *uart_lsr = (char *)0xef600305; +#endif + +#ifdef CONFIG_UART1_DEBUG_CONSOLE + volatile unsigned char *uart_rcv = (char *)0xef600400; + volatile unsigned char *uart_lsr = (char *)0xef600405; +#endif + + + /* ftr revisit: not tested */ + + if (nb == 0) + return(0); + + if (!ptr) + return(-1); + + /* wait for receive reg (possibly fifo) to contain data */ + while ((*uart_lsr & 0x01) == 0) + ; + + *ptr = *uart_rcv; + + return(1); +} + +static struct console ppc405_sercons = { + name: "dbg_cons", + write: ppc405_console_write, + setup: ppc405_console_setup, + flags: CON_PRINTBUFFER, + index: -1, +}; + +void +register_debug_console(void) +{ + register_console(&ppc405_sercons); +} + +void +unregister_debug_console(void) +{ + unregister_console(&ppc405_sercons); +} + +#endif /* CONFIG_DEBUG_BRINGUP */ + +#endif /* #if defined(CONFIG_IBM405GP) || defined(CONFIG_IBM405CR) */ diff --git a/arch/ppc/kernel/ppc4xx_setup.c b/arch/ppc/kernel/ppc4xx_setup.c new file mode 100755 index 000000000000..f086c14e7907 --- /dev/null +++ b/arch/ppc/kernel/ppc4xx_setup.c @@ -0,0 +1,415 @@ +/* + * + * Copyright (c) 1999-2000 Grant Erickson <grant@lcse.umn.edu> + * + * Copyright 2000-2001 MontaVista Software Inc. + * Completed implementation. + * Author: MontaVista Software, Inc. <source@mvista.com> + * Frank Rowand <frank_rowand@mvista.com> + * Debbie Chu <debbie_chu@mvista.com> + * + * Module name: ppc4xx_setup.c + * + * Description: + * Architecture- / platform-specific boot-time initialization code for + * IBM PowerPC 4xx based boards. Adapted from original + * code by Gary Thomas, Cort Dougan <cort@fsmlabs.com>, and Dan Malek + * <dan@net4x.com>. + * + * History: 11/09/2001 - armin + * rename board_setup_nvram_access to board_init. board_init is + * used for all other board specific instructions needed during + * platform_init. + * moved RTC to board.c files + * moved VT/FB to board.c files + * moved r/w4 ide to redwood.c + * + */ + +#include <linux/config.h> +#include <linux/init.h> +#include <linux/smp.h> +#include <linux/threads.h> +#include <linux/spinlock.h> +#include <linux/irq.h> +#include <linux/reboot.h> +#include <linux/param.h> +#include <linux/string.h> +#include <linux/blk.h> +#include <linux/pci.h> +#include <linux/rtc.h> +#include <linux/console.h> +#include <linux/ide.h> +#include <linux/serial_reg.h> +#include <linux/seq_file.h> + +#include <asm/system.h> +#include <asm/processor.h> +#include <asm/machdep.h> +#include <asm/page.h> +#include <asm/kgdb.h> +#include <asm/ibm4xx.h> +#include <asm/time.h> +#include <asm/todc.h> +#include <asm/ppc4xx_pic.h> +#include <asm/pci-bridge.h> +#include <asm/bootinfo.h> + +/* Function Prototypes */ +extern void abort(void); +extern void ppc4xx_find_bridges(void); + +extern int pckbd_setkeycode(unsigned int scancode, unsigned int keycode); +extern int pckbd_getkeycode(unsigned int scancode); +extern int pckbd_pretranslate(unsigned char scancode, char raw_mode); +extern int pckbd_translate(unsigned char scancode, unsigned char *keycode, + char raw_mode); +extern char pckbd_unexpected_up(unsigned char keycode); +extern void pckbd_leds(unsigned char leds); +extern void pckbd_init_hw(void); + +extern int nonpci_ide_default_irq(ide_ioreg_t base); +extern void nonpci_ide_init_hwif_ports(hw_regs_t * hw, ide_ioreg_t data_port, + ide_ioreg_t ctrl_port, int *irq); + +extern void ppc4xx_wdt_heartbeat(void); +extern int wdt_enable; +extern unsigned long wdt_period; + +/* Board specific functions */ +extern void board_setup_arch(void); +extern void board_io_mapping(void); +extern void board_setup_irq(void); +extern void board_init(void); + +/* Global Variables */ +unsigned char __res[sizeof (bd_t)]; + +static void __init +ppc4xx_setup_arch(void) +{ + + /* Setup PCI host bridges */ + +#ifdef CONFIG_PCI + ppc4xx_find_bridges(); +#endif + +#if defined(CONFIG_FB) + conswitchp = &dummy_con; +#endif + + board_setup_arch(); +} + +/* + * This routine pretty-prints the platform's internal CPU clock + * frequencies into the buffer for usage in /proc/cpuinfo. + */ + +static int +ppc4xx_show_percpuinfo(struct seq_file *m, int i) +{ + bd_t *bip = (bd_t *) __res; + + seq_printf(m, "clock\t\t: %ldMHz\n", (long) bip->bi_intfreq / 1000000); + + return 0; +} + +/* + * This routine pretty-prints the platform's internal bus clock + * frequencies into the buffer for usage in /proc/cpuinfo. + */ +static int +ppc4xx_show_cpuinfo(struct seq_file *m) +{ + bd_t *bip = (bd_t *) __res; + + seq_printf(m, "machine\t\t: %s\n", PPC4xx_MACHINE_NAME); + seq_printf(m, "plb bus clock\t: %ldMHz\n", + (long) bip->bi_busfreq / 1000000); +#ifdef CONFIG_PCI + seq_printf(m, "pci bus clock\t: %dMHz\n", + bip->bi_pci_busfreq / 1000000); +#endif + + return 0; +} + +/* + * Return the virtual address representing the top of physical RAM. + */ +static unsigned long __init +ppc4xx_find_end_of_memory(void) +{ + bd_t *bip = (bd_t *) __res; + + return ((unsigned long) bip->bi_memsize); +} + +static void __init +m4xx_map_io(void) +{ + io_block_mapping(PPC4xx_ONB_IO_VADDR, + PPC4xx_ONB_IO_PADDR, PPC4xx_ONB_IO_SIZE, _PAGE_IO); +#ifdef CONFIG_PCI + io_block_mapping(PPC4xx_PCI_IO_VADDR, + PPC4xx_PCI_IO_PADDR, PPC4xx_PCI_IO_SIZE, _PAGE_IO); + io_block_mapping(PPC4xx_PCI_CFG_VADDR, + PPC4xx_PCI_CFG_PADDR, PPC4xx_PCI_CFG_SIZE, _PAGE_IO); + io_block_mapping(PPC4xx_PCI_LCFG_VADDR, + PPC4xx_PCI_LCFG_PADDR, PPC4xx_PCI_LCFG_SIZE, _PAGE_IO); +#endif + board_io_mapping(); +} + +static void __init +ppc4xx_init_IRQ(void) +{ + int i; + + ppc4xx_pic_init(); + + for (i = 0; i < NR_IRQS; i++) + irq_desc[i].handler = ppc4xx_pic; + + /* give board specific code a chance to setup things */ + board_setup_irq(); + return; +} + +static void +ppc4xx_restart(char *cmd) +{ + printk("%s\n", cmd); + abort(); +} + +static void +ppc4xx_power_off(void) +{ + printk("System Halted\n"); + __cli(); + while (1) ; +} + +static void +ppc4xx_halt(void) +{ + printk("System Halted\n"); + __cli(); + while (1) ; +} + +/* + * This routine retrieves the internal processor frequency from the board + * information structure, sets up the kernel timer decrementer based on + * that value, enables the 4xx programmable interval timer (PIT) and sets + * it up for auto-reload. + */ +static void __init +ppc4xx_calibrate_decr(void) +{ + unsigned int freq; + bd_t *bip = (bd_t *) __res; + +#if defined(CONFIG_WALNUT) || defined(CONFIG_CEDER) + /* Walnut boot rom sets DCR CHCR1 (aka CPC0_CR1) bit CETE to 1 */ + mtdcr(DCRN_CHCR1, mfdcr(DCRN_CHCR1) & ~CHR1_CETE); +#endif +#ifdef CONFIG_REDWOOD_5 + freq = bip->bi_tbfreq; +#else + freq = bip->bi_intfreq; + +#endif + + tb_ticks_per_jiffy = freq / HZ; + tb_to_us = mulhwu_scale_factor(freq, 1000000); + + /* Set the time base to zero. + ** At 200 Mhz, time base will rollover in ~2925 years. + */ + + mtspr(SPRN_TBWL, 0); + mtspr(SPRN_TBWU, 0); + + /* Clear any pending timer interrupts */ + + mtspr(SPRN_TSR, TSR_ENW | TSR_WIS | TSR_PIS | TSR_FIS); + mtspr(SPRN_TCR, TCR_PIE | TCR_ARE); + + /* Set the PIT reload value and just let it run. */ + mtspr(SPRN_PIT, tb_ticks_per_jiffy); +} + +#ifdef CONFIG_DEBUG_TEXT +static void +ppc4xx_progress(char *s, unsigned short hex) +{ + printk("%s\n\r", s); +} +#endif + +/* + * IDE stuff. + * should be generic for every IDE PCI chipset + */ +#if defined(CONFIG_BLK_DEV_IDE) +static int +ppc4xx_ide_check_region(ide_ioreg_t from, unsigned int extent) +{ + return check_region(from, extent); +} + +static void +ppc4xx_ide_request_region(ide_ioreg_t from, unsigned int extent, + const char *name) +{ + request_region(from, extent, name); + return; +} + +static void +ppc4xx_ide_release_region(ide_ioreg_t from, unsigned int extent) +{ + release_region(from, extent); + return; +} +#endif + +#if defined(CONFIG_BLK_DEV_IDEPCI) +static void +ppc4xx_ide_init_hwif_ports(hw_regs_t * hw, ide_ioreg_t data_port, + ide_ioreg_t ctrl_port, int *irq) +{ + int i; + + for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; ++i) + hw->io_ports[i] = data_port + i - IDE_DATA_OFFSET; + + hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port; +} +#endif + +TODC_ALLOC(); + +/* + * Input(s): + * r3 - Optional pointer to a board information structure. + * r4 - Optional pointer to the physical starting address of the init RAM + * disk. + * r5 - Optional pointer to the physical ending address of the init RAM + * disk. + * r6 - Optional pointer to the physical starting address of any kernel + * command-line parameters. + * r7 - Optional pointer to the physical ending address of any kernel + * command-line parameters. + */ +void __init +platform_init(unsigned long r3, unsigned long r4, unsigned long r5, + unsigned long r6, unsigned long r7) +{ + parse_bootinfo(find_bootinfo()); + + /* + * If we were passed in a board information, copy it into the + * residual data area. + */ + if (r3) { + memcpy((void *) __res, (void *) (r3 + KERNELBASE), + sizeof (bd_t)); + + } +#if defined(CONFIG_BLK_DEV_INITRD) + /* + * If the init RAM disk has been configured in, and there's a valid + * starting address for it, set it up. + */ + if (r4) { + initrd_start = r4 + KERNELBASE; + initrd_end = r5 + KERNELBASE; + } +#endif /* CONFIG_BLK_DEV_INITRD */ + + /* Copy the kernel command line arguments to a safe place. */ + + if (r6) { + *(char *) (r7 + KERNELBASE) = 0; + strcpy(cmd_line, (char *) (r6 + KERNELBASE)); + } +#if defined(CONFIG_PPC405_WDT) +/* Look for wdt= option on command line */ + if (strstr(cmd_line, "wdt=")) { + int valid_wdt = 0; + char *p, *q; + for (q = cmd_line; (p = strstr(q, "wdt=")) != 0;) { + q = p + 4; + if (p > cmd_line && p[-1] != ' ') + continue; + wdt_period = simple_strtoul(q, &q, 0); + valid_wdt = 1; + ++q; + } + wdt_enable = valid_wdt; + } +#endif + + /* Initialize machine-dependency vectors */ + + ppc_md.setup_arch = ppc4xx_setup_arch; + ppc_md.show_percpuinfo = ppc4xx_show_percpuinfo; + ppc_md.show_cpuinfo = ppc4xx_show_cpuinfo; + ppc_md.init_IRQ = ppc4xx_init_IRQ; + + ppc_md.restart = ppc4xx_restart; + ppc_md.power_off = ppc4xx_power_off; + ppc_md.halt = ppc4xx_halt; + + ppc_md.calibrate_decr = ppc4xx_calibrate_decr; + +#ifdef CONFIG_PPC405_WDT + ppc_md.heartbeat = ppc4xx_wdt_heartbeat; +#endif + ppc_md.heartbeat_count = 0; + + ppc_md.find_end_of_memory = ppc4xx_find_end_of_memory; + ppc_md.setup_io_mappings = m4xx_map_io; + +#ifdef CONFIG_DEBUG_TEXT + ppc_md.progress = ppc4xx_progress; +#endif + +#if defined(CONFIG_VT) && defined(CONFIG_PC_KEYBOARD) +#if defined(CONFIG_REDWOOD_4) && defined(CONFIG_STB_KB) + redwood_irkb_init(); +#else + ppc_md.kbd_setkeycode = pckbd_setkeycode; + ppc_md.kbd_getkeycode = pckbd_getkeycode; + ppc_md.kbd_translate = pckbd_translate; + ppc_md.kbd_unexpected_up = pckbd_unexpected_up; + ppc_md.kbd_leds = pckbd_leds; + ppc_md.kbd_init_hw = pckbd_init_hw; +#endif +#endif + +/* +** m8xx_setup.c, prep_setup.c use +** defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) +*/ +#if defined (CONFIG_IDE) + ppc_ide_md.ide_request_region = ppc4xx_ide_request_region; + ppc_ide_md.ide_release_region = ppc4xx_ide_release_region; + ppc_ide_md.ide_check_region = ppc4xx_ide_check_region; +#if defined(CONFIG_BLK_DEV_IDEPCI) + ppc_ide_md.ide_init_hwif = ppc4xx_ide_init_hwif_ports; +#elif defined (CONFIG_DMA_NONPCI) /* ON board IDE */ + ppc_ide_md.default_irq = nonpci_ide_default_irq; + ppc_ide_md.ide_init_hwif = nonpci_ide_init_hwif_ports; +#endif +#endif + board_init(); + + return; +} diff --git a/arch/ppc/kernel/ppc8260_pic.c b/arch/ppc/kernel/ppc8260_pic.c index b829116f78a0..b2ae5e951aef 100644 --- a/arch/ppc/kernel/ppc8260_pic.c +++ b/arch/ppc/kernel/ppc8260_pic.c @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.ppc8260_pic.c 1.5 05/17/01 18:14:21 cort + * BK Id: %F% %I% %G% %U% %#% */ #include <linux/stddef.h> @@ -85,6 +85,22 @@ static void m8260_mask_and_ack(unsigned int irq_nr) sipnr[word] = 1 << (31 - bit); } +static void m8260_end_irq(unsigned int irq_nr) +{ + int bit, word; + volatile uint *simr; + + if (!(irq_desc[irq_nr].status & (IRQ_DISABLED|IRQ_INPROGRESS))) { + + bit = irq_to_siubit[irq_nr]; + word = irq_to_siureg[irq_nr]; + + simr = &(immr->im_intctl.ic_simrh); + ppc_cached_irq_mask[word] |= (1 << (31 - bit)); + simr[word] = ppc_cached_irq_mask[word]; + } +} + struct hw_interrupt_type ppc8260_pic = { " 8260 SIU ", NULL, @@ -92,6 +108,7 @@ struct hw_interrupt_type ppc8260_pic = { m8260_unmask_irq, m8260_mask_irq, m8260_mask_and_ack, + m8260_end_irq, 0 }; @@ -106,6 +123,9 @@ m8260_get_irq(struct pt_regs *regs) * to get the irq number. */ bits = immr->im_intctl.ic_sivec; irq = bits >> 26; + + if (irq == 0) + return(-1); #if 0 irq += ppc8260_pic.irq_offset; #endif diff --git a/arch/ppc/kernel/ppc8260_pic.h b/arch/ppc/kernel/ppc8260_pic.h index dd415f4995bf..40e70f82a8b8 100644 --- a/arch/ppc/kernel/ppc8260_pic.h +++ b/arch/ppc/kernel/ppc8260_pic.h @@ -1,11 +1,11 @@ /* - * BK Id: SCCS/s.ppc8260_pic.h 1.7 05/17/01 18:14:21 cort + * BK Id: %F% %I% %G% %U% %#% */ #ifndef _PPC_KERNEL_PPC8260_H #define _PPC_KERNEL_PPC8260_H -#include "local_irq.h" +#include <linux/irq.h> extern struct hw_interrupt_type ppc8260_pic; diff --git a/arch/ppc/kernel/ppc8xx_pic.c b/arch/ppc/kernel/ppc8xx_pic.c index b01669fe60df..a952d85ea01a 100644 --- a/arch/ppc/kernel/ppc8xx_pic.c +++ b/arch/ppc/kernel/ppc8xx_pic.c @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.ppc8xx_pic.c 1.10 05/17/01 18:14:21 cort + * BK Id: %F% %I% %G% %U% %#% */ #include <linux/config.h> #include <linux/stddef.h> @@ -44,6 +44,21 @@ static void m8xx_unmask_irq(unsigned int irq_nr) ppc_cached_irq_mask[word]; } +static void m8xx_end_irq(unsigned int irq_nr) +{ + if (!(irq_desc[irq_nr].status & (IRQ_DISABLED|IRQ_INPROGRESS))) { + int bit, word; + + bit = irq_nr & 0x1f; + word = irq_nr >> 5; + + ppc_cached_irq_mask[word] |= (1 << (31-bit)); + ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_simask = + ppc_cached_irq_mask[word]; + } +} + + static void m8xx_mask_and_ack(unsigned int irq_nr) { int bit, word; @@ -64,6 +79,7 @@ struct hw_interrupt_type ppc8xx_pic = { m8xx_unmask_irq, m8xx_mask_irq, m8xx_mask_and_ack, + m8xx_end_irq, 0 }; @@ -97,19 +113,26 @@ m8xx_do_IRQ(struct pt_regs *regs, #endif +/* + * We either return a valid interrupt or -1 if there is nothing pending + */ int m8xx_get_irq(struct pt_regs *regs) { int irq; - unsigned long bits = 0; - /* For MPC8xx, read the SIVEC register and shift the bits down - * to get the irq number. */ - bits = ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_sivec; - irq = bits >> 26; -#if 0 - irq += ppc8xx_pic.irq_offset; -#endif + /* For MPC8xx, read the SIVEC register and shift the bits down + * to get the irq number. + */ + irq = ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_sivec >> 26; + + /* + * When we read the sivec without an interrupt to process, we will + * get back SIU_LEVEL7. In this case, return -1 + */ + if (irq == SIU_LEVEL7) + return -1; + return irq; } diff --git a/arch/ppc/kernel/ppc8xx_pic.h b/arch/ppc/kernel/ppc8xx_pic.h index 1253d31c28a3..9cbf0d6eec4a 100644 --- a/arch/ppc/kernel/ppc8xx_pic.h +++ b/arch/ppc/kernel/ppc8xx_pic.h @@ -1,11 +1,11 @@ /* - * BK Id: SCCS/s.ppc8xx_pic.h 1.7 05/17/01 18:14:21 cort + * BK Id: %F% %I% %G% %U% %#% */ #ifndef _PPC_KERNEL_PPC8xx_H #define _PPC_KERNEL_PPC8xx_H #include <linux/config.h> -#include "local_irq.h" +#include <linux/irq.h> extern struct hw_interrupt_type ppc8xx_pic; @@ -15,7 +15,7 @@ void m8xx_do_IRQ(struct pt_regs *regs, int m8xx_get_irq(struct pt_regs *regs); #ifdef CONFIG_MBX -#include "i8259.h" +#include <asm/i8259.h> #include <asm/io.h> void mbx_i8259_action(int cpl, void *dev_id, struct pt_regs *regs); #endif diff --git a/arch/ppc/kernel/ppc_asm.tmpl b/arch/ppc/kernel/ppc_asm.tmpl deleted file mode 100644 index c35192bb4fe6..000000000000 --- a/arch/ppc/kernel/ppc_asm.tmpl +++ /dev/null @@ -1,115 +0,0 @@ -/* Condition Register Bit Fields */ - -#define cr0 0 -#define cr1 1 -#define cr2 2 -#define cr3 3 -#define cr4 4 -#define cr5 5 -#define cr6 6 -#define cr7 7 - - -/* General Purpose Registers (GPRs) */ - -#define r0 0 -#define r1 1 -#define r2 2 -#define r3 3 -#define r4 4 -#define r5 5 -#define r6 6 -#define r7 7 -#define r8 8 -#define r9 9 -#define r10 10 -#define r11 11 -#define r12 12 -#define r13 13 -#define r14 14 -#define r15 15 -#define r16 16 -#define r17 17 -#define r18 18 -#define r19 19 -#define r20 20 -#define r21 21 -#define r22 22 -#define r23 23 -#define r24 24 -#define r25 25 -#define r26 26 -#define r27 27 -#define r28 28 -#define r29 29 -#define r30 30 -#define r31 31 - - -/* Floating Point Registers (FPRs) */ - -#define fr0 0 -#define fr1 1 -#define fr2 2 -#define fr3 3 -#define fr4 4 -#define fr5 5 -#define fr6 6 -#define fr7 7 -#define fr8 8 -#define fr9 9 -#define fr10 10 -#define fr11 11 -#define fr12 12 -#define fr13 13 -#define fr14 14 -#define fr15 15 -#define fr16 16 -#define fr17 17 -#define fr18 18 -#define fr19 19 -#define fr20 20 -#define fr21 21 -#define fr22 22 -#define fr23 23 -#define fr24 24 -#define fr25 25 -#define fr26 26 -#define fr27 27 -#define fr28 28 -#define fr29 29 -#define fr30 30 -#define fr31 31 - -#define vr0 0 -#define vr1 1 -#define vr2 2 -#define vr3 3 -#define vr4 4 -#define vr5 5 -#define vr6 6 -#define vr7 7 -#define vr8 8 -#define vr9 9 -#define vr10 10 -#define vr11 11 -#define vr12 12 -#define vr13 13 -#define vr14 14 -#define vr15 15 -#define vr16 16 -#define vr17 17 -#define vr18 18 -#define vr19 19 -#define vr20 20 -#define vr21 21 -#define vr22 22 -#define vr23 23 -#define vr24 24 -#define vr25 25 -#define vr26 26 -#define vr27 27 -#define vr28 28 -#define vr29 29 -#define vr30 30 -#define vr31 31 diff --git a/arch/ppc/kernel/ppc_ksyms.c b/arch/ppc/kernel/ppc_ksyms.c index 805c7fbd1383..2649b327c7f2 100644 --- a/arch/ppc/kernel/ppc_ksyms.c +++ b/arch/ppc/kernel/ppc_ksyms.c @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.ppc_ksyms.c 1.59 11/04/01 22:58:20 paulus + * BK Id: %F% %I% %G% %U% %#% */ #include <linux/config.h> #include <linux/module.h> @@ -12,18 +12,17 @@ #include <linux/tty.h> #include <linux/vt_kern.h> #include <linux/nvram.h> -#include <linux/spinlock.h> #include <linux/console.h> #include <linux/irq.h> #include <linux/pci.h> #include <linux/delay.h> +#include <linux/ide.h> #include <asm/page.h> #include <asm/semaphore.h> #include <asm/processor.h> #include <asm/uaccess.h> #include <asm/io.h> -#include <linux/ide.h> #include <asm/ide.h> #include <asm/atomic.h> #include <asm/bitops.h> @@ -36,7 +35,7 @@ #include <asm/system.h> #include <asm/pci-bridge.h> #include <asm/irq.h> -#include <asm/feature.h> +#include <asm/pmac_feature.h> #include <asm/dma.h> #include <asm/machdep.h> #include <asm/hw_irq.h> @@ -60,7 +59,7 @@ extern void ppc_generic_ide_fix_driveid(struct hd_driveid *id); extern void transfer_to_handler(void); -extern void syscall_trace(void); +extern void do_syscall_trace(void); extern void do_IRQ(struct pt_regs *regs); extern void MachineCheckException(struct pt_regs *regs); extern void AlignmentException(struct pt_regs *regs); @@ -82,7 +81,7 @@ extern unsigned long mm_ptov (unsigned long paddr); EXPORT_SYMBOL(clear_page); EXPORT_SYMBOL(do_signal); -EXPORT_SYMBOL(syscall_trace); +EXPORT_SYMBOL(do_syscall_trace); EXPORT_SYMBOL(transfer_to_handler); EXPORT_SYMBOL(do_IRQ); EXPORT_SYMBOL(MachineCheckException); @@ -161,14 +160,18 @@ EXPORT_SYMBOL(_insw_ns); EXPORT_SYMBOL(_outsw_ns); EXPORT_SYMBOL(_insl_ns); EXPORT_SYMBOL(_outsl_ns); +EXPORT_SYMBOL(iopa); +EXPORT_SYMBOL(mm_ptov); +#ifndef CONFIG_PPC_ISERIES EXPORT_SYMBOL(ioremap); EXPORT_SYMBOL(__ioremap); EXPORT_SYMBOL(iounmap); -EXPORT_SYMBOL(iopa); -EXPORT_SYMBOL(mm_ptov); +#endif +#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) EXPORT_SYMBOL(ppc_ide_md); EXPORT_SYMBOL(ppc_generic_ide_fix_driveid); +#endif #ifdef CONFIG_PCI EXPORT_SYMBOL_NOVERS(isa_io_base); @@ -176,19 +179,32 @@ EXPORT_SYMBOL_NOVERS(isa_mem_base); EXPORT_SYMBOL_NOVERS(pci_dram_offset); EXPORT_SYMBOL(pci_alloc_consistent); EXPORT_SYMBOL(pci_free_consistent); +EXPORT_SYMBOL(pci_bus_io_base); +EXPORT_SYMBOL(pci_bus_io_base_phys); +EXPORT_SYMBOL(pci_bus_mem_base_phys); +EXPORT_SYMBOL(pci_bus_to_hose); +EXPORT_SYMBOL(pci_resource_to_bus); +EXPORT_SYMBOL(pci_phys_to_bus); +EXPORT_SYMBOL(pci_bus_to_phys); #endif /* CONFIG_PCI */ +#ifdef CONFIG_NOT_COHERENT_CACHE +EXPORT_SYMBOL(consistent_alloc); +EXPORT_SYMBOL(consistent_free); +EXPORT_SYMBOL(consistent_sync); +#endif + EXPORT_SYMBOL(start_thread); EXPORT_SYMBOL(kernel_thread); -/*EXPORT_SYMBOL(__restore_flags);*/ -/*EXPORT_SYMBOL(_disable_interrupts); - EXPORT_SYMBOL(_enable_interrupts);*/ EXPORT_SYMBOL(flush_instruction_cache); EXPORT_SYMBOL(giveup_fpu); EXPORT_SYMBOL(enable_kernel_fp); EXPORT_SYMBOL(flush_icache_range); EXPORT_SYMBOL(flush_dcache_range); +EXPORT_SYMBOL(flush_icache_user_range); +EXPORT_SYMBOL(flush_icache_page); +EXPORT_SYMBOL(flush_dcache_page); EXPORT_SYMBOL(xchg_u32); #ifdef CONFIG_ALTIVEC EXPORT_SYMBOL(last_task_used_altivec); @@ -196,7 +212,6 @@ EXPORT_SYMBOL(giveup_altivec); #endif /* CONFIG_ALTIVEC */ #ifdef CONFIG_SMP EXPORT_SYMBOL(global_irq_lock); -EXPORT_SYMBOL(global_irq_count); EXPORT_SYMBOL(global_irq_holder); EXPORT_SYMBOL(__global_cli); EXPORT_SYMBOL(__global_sti); @@ -247,26 +262,11 @@ EXPORT_SYMBOL(device_is_compatible); EXPORT_SYMBOL(machine_is_compatible); EXPORT_SYMBOL(find_all_nodes); EXPORT_SYMBOL(get_property); -EXPORT_SYMBOL(pci_bus_io_base); -EXPORT_SYMBOL(pci_bus_io_base_phys); -EXPORT_SYMBOL(pci_bus_mem_base_phys); +EXPORT_SYMBOL(request_OF_resource); +EXPORT_SYMBOL(release_OF_resource); EXPORT_SYMBOL(pci_device_to_OF_node); EXPORT_SYMBOL(pci_device_from_OF_node); -EXPORT_SYMBOL(pci_bus_to_hose); -EXPORT_SYMBOL(pci_resource_to_bus); -EXPORT_SYMBOL(pci_phys_to_bus); -EXPORT_SYMBOL(pci_bus_to_phys); EXPORT_SYMBOL(pmac_newworld); -EXPORT_SYMBOL(feature_set); -EXPORT_SYMBOL(feature_clear); -EXPORT_SYMBOL(feature_test); -EXPORT_SYMBOL(feature_set_gmac_power); -EXPORT_SYMBOL(feature_gmac_phy_reset); -EXPORT_SYMBOL(feature_set_usb_power); -EXPORT_SYMBOL(feature_set_firewire_power); -EXPORT_SYMBOL(feature_set_firewire_cable_power); -EXPORT_SYMBOL(feature_set_modem_power); -EXPORT_SYMBOL(feature_set_airport_power); #endif /* defined(CONFIG_ALL_PPC) */ #if defined(CONFIG_BOOTX_TEXT) EXPORT_SYMBOL(btext_update_display); @@ -293,14 +293,16 @@ EXPORT_SYMBOL_NOVERS(memset); EXPORT_SYMBOL_NOVERS(memmove); EXPORT_SYMBOL_NOVERS(memscan); EXPORT_SYMBOL_NOVERS(memcmp); +EXPORT_SYMBOL_NOVERS(memchr); EXPORT_SYMBOL(abs); -#ifdef CONFIG_VGA_CONSOLE +#if defined(CONFIG_FB_VGA16_MODULE) EXPORT_SYMBOL(screen_info); #endif EXPORT_SYMBOL(__delay); +#ifndef INLINE_IRQS EXPORT_SYMBOL(__sti); EXPORT_SYMBOL(__sti_end); EXPORT_SYMBOL(__cli); @@ -309,6 +311,7 @@ EXPORT_SYMBOL(__save_flags_ptr); EXPORT_SYMBOL(__save_flags_ptr_end); EXPORT_SYMBOL(__restore_flags); EXPORT_SYMBOL(__restore_flags_end); +#endif EXPORT_SYMBOL(timer_interrupt_intercept); EXPORT_SYMBOL(timer_interrupt); EXPORT_SYMBOL(do_IRQ_intercept); @@ -319,7 +322,9 @@ EXPORT_SYMBOL(tb_ticks_per_jiffy); EXPORT_SYMBOL(get_wchan); EXPORT_SYMBOL(console_drivers); #ifdef CONFIG_XMON +extern void xmon_printf(char *fmt, ...); EXPORT_SYMBOL(xmon); +EXPORT_SYMBOL(xmon_printf); #endif EXPORT_SYMBOL(__up); EXPORT_SYMBOL(__down); @@ -343,10 +348,12 @@ EXPORT_SYMBOL(debugger_fault_handler); #ifdef CONFIG_8xx EXPORT_SYMBOL(__res); -EXPORT_SYMBOL(request_8xxirq); EXPORT_SYMBOL(cpm_install_handler); EXPORT_SYMBOL(cpm_free_handler); #endif /* CONFIG_8xx */ +#if defined(CONFIG_8xx) || defined(CONFIG_8260) +EXPORT_SYMBOL(request_8xxirq); +#endif EXPORT_SYMBOL(ret_to_user_hook); EXPORT_SYMBOL(next_mmu_context); @@ -361,3 +368,7 @@ EXPORT_SYMBOL(intercept_table); extern long *ret_from_intercept; EXPORT_SYMBOL(ret_from_intercept); EXPORT_SYMBOL(cur_cpu_spec); +#if defined(CONFIG_ALL_PPC) +extern unsigned long agp_special_page; +EXPORT_SYMBOL_NOVERS(agp_special_page); +#endif /* defined(CONFIG_ALL_PPC) */ diff --git a/arch/ppc/kernel/pplus_common.c b/arch/ppc/kernel/pplus_common.c new file mode 100644 index 000000000000..df3c2ca61f1d --- /dev/null +++ b/arch/ppc/kernel/pplus_common.c @@ -0,0 +1,317 @@ +/* + * arch/ppc/kernel/pplus_common.c + * + * Common Motorola PowerPlus Platform--really Falcon/Raven or HAWK. + * + * Author: Mark A. Greer + * mgreer@mvista.com + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/pci.h> + +#include <asm/byteorder.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/pci.h> +#include <asm/pci-bridge.h> +#include <asm/open_pic.h> +#include <asm/pplus.h> + +/* + * The Falcon/Raven and HAWK has 4 sets of registers: + * 1) PPC Registers which define the mappings from PPC bus to PCI bus, + * etc. + * 2) PCI Registers which define the mappings from PCI bus to PPC bus and the + * MPIC base address. + * 3) MPIC registers. + * 4) System Memory Controller (SMC) registers. + */ + +/* + * Initialize the Motorola MCG Raven or HAWK host bridge. + * + * This means setting up the PPC bus to PCI memory and I/O space mappings, + * setting the PCI memory space address of the MPIC (mapped straight + * through), and ioremap'ing the mpic registers. + * This routine will set the PCI_CONFIG_ADDR or PCI_CONFIG_DATA + * addresses based on the PCI I/O address that is passed in. + * 'OpenPIC_Addr' will be set correctly by this routine. + */ +int __init +pplus_init(struct pci_controller *hose, + uint ppc_reg_base, + ulong processor_pci_mem_start, + ulong processor_pci_mem_end, + ulong processor_pci_io_start, + ulong processor_pci_io_end, + ulong processor_mpic_base) +{ + uint addr, offset; + + /* + * Some sanity checks... + */ + if (((processor_pci_mem_start&0xffff0000) != processor_pci_mem_start) || + ((processor_pci_io_start &0xffff0000) != processor_pci_io_start)) { + printk("pplus_init: %s\n", + "PPC to PCI mappings must start on 64 KB boundaries"); + return -1; + } + + if (((processor_pci_mem_end &0x0000ffff) != 0x0000ffff) || + ((processor_pci_io_end &0x0000ffff) != 0x0000ffff)) { + printk("pplus_init: PPC to PCI mappings %s\n", + "must end just before a 64 KB boundaries"); + return -1; + } + + if (((processor_pci_mem_end - processor_pci_mem_start) != + (hose->mem_space.end - hose->mem_space.start)) || + ((processor_pci_io_end - processor_pci_io_start) != + (hose->io_space.end - hose->io_space.start))) { + printk("pplus_init: %s\n", + "PPC and PCI memory or I/O space sizes don't match"); + return -1; + } + + if ((processor_mpic_base & 0xfffc0000) != processor_mpic_base) { + printk("pplus_init: %s\n", + "MPIC address must start on 256 MB boundary"); + return -1; + } + + if ((pci_dram_offset & 0xffff0000) != pci_dram_offset) { + printk("pplus_init: %s\n", + "pci_dram_offset must be multiple of 64 KB"); + return -1; + } + + /* + * Disable previous PPC->PCI mappings. + */ + out_be32((uint *)(ppc_reg_base + PPLUS_PPC_XSOFF0_OFF), 0x00000000); + out_be32((uint *)(ppc_reg_base + PPLUS_PPC_XSOFF1_OFF), 0x00000000); + out_be32((uint *)(ppc_reg_base + PPLUS_PPC_XSOFF2_OFF), 0x00000000); + out_be32((uint *)(ppc_reg_base + PPLUS_PPC_XSOFF3_OFF), 0x00000000); + + /* + * Program the XSADD/XSOFF registers to set up the PCI Mem & I/O + * space mappings. These are the mappings going from the processor to + * the PCI bus. + * + * Note: Don't need to 'AND' start/end addresses with 0xffff0000 + * because sanity check above ensures that they are properly + * aligned. + */ + + /* Set up PPC->PCI Mem mapping */ + addr = processor_pci_mem_start | (processor_pci_mem_end >> 16); + offset = (hose->mem_space.start - processor_pci_mem_start) | 0xd2; + out_be32((uint *)(ppc_reg_base + PPLUS_PPC_XSADD0_OFF), addr); + out_be32((uint *)(ppc_reg_base + PPLUS_PPC_XSOFF0_OFF), offset); + + /* Set up PPC->MPIC mapping on the bridge */ + addr = processor_mpic_base | + (((processor_mpic_base + PPLUS_MPIC_SIZE) >> 16) - 1); + offset = 0xc2; /* No write posting for this PCI Mem space */ + out_be32((uint *)(ppc_reg_base + PPLUS_PPC_XSADD1_OFF), addr); + out_be32((uint *)(ppc_reg_base + PPLUS_PPC_XSOFF1_OFF), offset); + + /* Set up PPC->PCI I/O mapping -- Contiguous I/O space */ + addr = processor_pci_io_start | (processor_pci_io_end >> 16); + offset = (hose->io_space.start - processor_pci_io_start) | 0xc0; + out_be32((uint *)(ppc_reg_base + PPLUS_PPC_XSADD3_OFF), addr); + out_be32((uint *)(ppc_reg_base + PPLUS_PPC_XSOFF3_OFF), offset); + + hose->io_base_virt = (void *)ioremap(processor_pci_io_start, + (processor_pci_io_end - processor_pci_io_start + 1)); + + /* + * Set up the indirect method of accessing PCI config space. + * The PCI config addr/data pair based on start addr of PCI I/O space. + */ + setup_indirect_pci(hose, + processor_pci_io_start + PPLUS_PCI_CONFIG_ADDR_OFF, + processor_pci_io_start + PPLUS_PCI_CONFIG_DATA_OFF); + + /* + * Disable previous PCI->PPC mappings. + */ + + /* XXXX Put in mappings from PCI bus to processor bus XXXX */ + + /* + * Disable MPIC response to PCI I/O space (BAR 0). + * Make MPIC respond to PCI Mem space at specified address. + * (BAR 1). + */ + early_write_config_dword(hose, + 0, + PCI_DEVFN(0,0), + PCI_BASE_ADDRESS_0, + 0x00000000 | 0x1); + + early_write_config_dword(hose, + 0, + PCI_DEVFN(0,0), + PCI_BASE_ADDRESS_1, + processor_mpic_base | 0x0); + + /* Map MPIC into vitual memory */ + OpenPIC_Addr = ioremap(processor_mpic_base, PPLUS_MPIC_SIZE); + + return 0; +} + +/* + * Find the amount of RAM present. + * This assumes that PPCBug has initialized the memory controller (SMC) + * on the Falcon/HAWK correctly (i.e., it does no sanity checking). + * It also assumes that the memory base registers are set to configure the + * memory as contigous starting with "RAM A BASE", "RAM B BASE", etc. + * however, RAM base registers can be skipped (e.g. A, B, C are set, + * D is skipped but E is set is okay). + */ +#define MB (1024*1024) + +static uint reg_offset_table[] __initdata = { + PPLUS_SMC_RAM_A_SIZE_REG_OFF, + PPLUS_SMC_RAM_B_SIZE_REG_OFF, + PPLUS_SMC_RAM_C_SIZE_REG_OFF, + PPLUS_SMC_RAM_D_SIZE_REG_OFF, + PPLUS_SMC_RAM_E_SIZE_REG_OFF, + PPLUS_SMC_RAM_F_SIZE_REG_OFF, + PPLUS_SMC_RAM_G_SIZE_REG_OFF, + PPLUS_SMC_RAM_H_SIZE_REG_OFF +}; + +static uint falcon_size_table[] __initdata = { + 0 * MB, /* 0 ==> 0 MB */ + 16 * MB, /* 1 ==> 16 MB */ + 32 * MB, /* 2 ==> 32 MB */ + 64 * MB, /* 3 ==> 64 MB */ + 128 * MB, /* 4 ==> 128 MB */ + 256 * MB, /* 5 ==> 256 MB */ + 1024 * MB, /* 6 ==> 1024 MB (1 GB) */ +}; + +static uint hawk_size_table[] __initdata = { + 0 * MB, /* 0 ==> 0 MB */ + 32 * MB, /* 1 ==> 32 MB */ + 64 * MB, /* 2 ==> 64 MB */ + 64 * MB, /* 3 ==> 64 MB */ + 128 * MB, /* 4 ==> 128 MB */ + 128 * MB, /* 5 ==> 128 MB */ + 128 * MB, /* 6 ==> 128 MB */ + 256 * MB, /* 7 ==> 256 MB */ + 256 * MB, /* 8 ==> 256 MB */ + 512 * MB, /* 9 ==> 512 MB */ +}; + +/* + * *** WARNING: You MUST have a BAT set up to map in the SMC regs *** + * + * Read the memory controller's registers to determine the amount of system + * memory. Assumes that the memory controller registers are already mapped + * into virtual memory--too early to use ioremap(). + */ +unsigned long __init +pplus_get_mem_size(uint smc_base) +{ + unsigned long total; + int i, size_table_entries, reg_limit; + uint vend_dev_id; + uint *size_table; + u_char val; + + + vend_dev_id = in_be32((uint *)smc_base + PCI_VENDOR_ID); + + if (((vend_dev_id & 0xffff0000) >> 16) != PCI_VENDOR_ID_MOTOROLA) { + printk("pplus_get_mem_size: %s (0x%x)\n", + "Not a Motorola Memory Controller", vend_dev_id); + return 0; + } + + vend_dev_id &= 0x0000ffff; + + if (vend_dev_id == PCI_DEVICE_ID_MOTOROLA_FALCON) { + size_table = falcon_size_table; + size_table_entries = sizeof(falcon_size_table) / + sizeof(falcon_size_table[0]); + + reg_limit = PPLUS_FALCON_SMC_REG_COUNT; + } + else if (vend_dev_id == PCI_DEVICE_ID_MOTOROLA_HAWK) { + size_table = hawk_size_table; + size_table_entries = sizeof(hawk_size_table) / + sizeof(hawk_size_table[0]); + reg_limit = PPLUS_HAWK_SMC_REG_COUNT; + } + else { + printk("pplus_get_mem_size: %s (0x%x)\n", + "Not a Falcon or HAWK", vend_dev_id); + return 0; + } + + total = 0; + + /* Check every reg because PPCBug may skip some */ + for (i=0; i<reg_limit; i++) { + val = in_8((u_char *)(smc_base + reg_offset_table[i])); + + if (val & 0x80) { /* If enabled */ + val &= 0x0f; + + /* Don't go past end of size_table */ + if (val < size_table_entries) { + total += size_table[val]; + } + else { /* Register not set correctly */ + break; + } + } + } + + return total; +} + +int __init +pplus_mpic_init(unsigned int pci_mem_offset) +{ + unsigned short devid; + unsigned int pci_membase; + + /* Check the first PCI device to see if it is a Raven or Hawk. */ + early_read_config_word(0, 0, 0, PCI_DEVICE_ID, &devid); + + switch (devid) { + case PCI_DEVICE_ID_MOTOROLA_RAVEN: + case PCI_DEVICE_ID_MOTOROLA_HAWK: + break; + default: + OpenPIC_Addr = NULL; + return 1; + } + + /* Read the memory base register. */ + early_read_config_dword(0, 0, 0, PCI_BASE_ADDRESS_1, &pci_membase); + + if (pci_membase == 0) { + OpenPIC_Addr = NULL; + return 1; + } + + /* Map the MPIC registers to virtual memory. */ + OpenPIC_Addr = ioremap(pci_membase + pci_mem_offset, 0x22000); + + return 0; +} diff --git a/arch/ppc/kernel/process.c b/arch/ppc/kernel/process.c index eca832613eb8..9a00a0efb999 100644 --- a/arch/ppc/kernel/process.c +++ b/arch/ppc/kernel/process.c @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.process.c 1.31 10/02/01 09:51:41 paulus + * BK Id: %F% %I% %G% %U% %#% */ /* * linux/arch/ppc/kernel/process.c @@ -34,6 +34,8 @@ #include <linux/user.h> #include <linux/elf.h> #include <linux/init.h> +#include <linux/prctl.h> +#include <linux/init_task.h> #include <asm/pgtable.h> #include <asm/uaccess.h> @@ -42,20 +44,26 @@ #include <asm/processor.h> #include <asm/mmu.h> #include <asm/prom.h> +#ifdef CONFIG_PPC_ISERIES +#include <asm/iSeries/Paca.h> +#endif int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpregs); extern unsigned long _get_SP(void); struct task_struct *last_task_used_math = NULL; struct task_struct *last_task_used_altivec = NULL; + static struct fs_struct init_fs = INIT_FS; static struct files_struct init_files = INIT_FILES; static struct signal_struct init_signals = INIT_SIGNALS; struct mm_struct init_mm = INIT_MM(init_mm); + /* this is 16-byte aligned because it has a stack in it */ union task_union __attribute((aligned(16))) init_task_union = { INIT_TASK(init_task_union.task) }; + /* only used to get secondary processor up */ struct task_struct *current_set[NR_CPUS] = {&init_task, }; @@ -260,7 +268,7 @@ void show_regs(struct pt_regs * regs) printk("\nlast math %p last altivec %p", last_task_used_math, last_task_used_altivec); -#ifdef CONFIG_4xx +#if defined(CONFIG_4xx) && defined(DCRN_PLB0_BEAR) printk("\nPLB0: bear= 0x%8.8x acr= 0x%8.8x besr= 0x%8.8x\n", mfdcr(DCRN_POB0_BEAR), mfdcr(DCRN_PLB0_ACR), mfdcr(DCRN_PLB0_BESR)); @@ -336,9 +344,10 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long usp, /* for kernel thread, set `current' and stackptr in new task */ childregs->gpr[1] = sp + sizeof(struct pt_regs); childregs->gpr[2] = (unsigned long) p; - } + p->thread.regs = NULL; /* no user register state */ + } else + p->thread.regs = childregs; childregs->gpr[3] = 0; /* Result from fork() */ - p->thread.regs = childregs; sp -= STACK_FRAME_OVERHEAD; childframe = sp; @@ -355,6 +364,9 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long usp, sp -= STACK_FRAME_OVERHEAD; p->thread.ksp = sp; kregs->nip = (unsigned long)ret_from_fork; +#ifdef CONFIG_PPC_ISERIES + kregs->softEnable = ((struct Paca *)mfspr(SPRG1))->xProcEnabled; +#endif /* * copy fpu info - assume lazy fpu switch now always @@ -391,7 +403,10 @@ void start_thread(struct pt_regs *regs, unsigned long nip, unsigned long sp) { set_fs(USER_DS); memset(regs->gpr, 0, sizeof(regs->gpr)); - memset(®s->ctr, 0, 5 * sizeof(regs->ctr)); + regs->ctr = 0; + regs->link = 0; + regs->xer = 0; + regs->ccr = 0; regs->nip = nip; regs->gpr[1] = sp; regs->msr = MSR_USER; @@ -399,8 +414,29 @@ void start_thread(struct pt_regs *regs, unsigned long nip, unsigned long sp) last_task_used_math = 0; if (last_task_used_altivec == current) last_task_used_altivec = 0; + memset(current->thread.fpr, 0, sizeof(current->thread.fpr)); current->thread.fpscr = 0; +#ifdef CONFIG_ALTIVEC + memset(current->thread.vr, 0, sizeof(current->thread.vr)); + memset(¤t->thread.vscr, 0, sizeof(current->thread.vscr)); + current->thread.vrsave = 0; +#endif /* CONFIG_ALTIVEC */ +} + +#if 0 +int set_fpexc_mode(struct task_struct *tsk, unsigned int val) +{ + struct pt_regs *regs = tsk->thread.regs; + + if (val > PR_FP_EXC_PRECISE) + return -EINVAL; + tsk->thread.fpexc_mode = __pack_fe01(val); + if (regs != NULL && (regs->msr & MSR_FP) != 0) + regs->msr = (regs->msr & ~(MSR_FE0|MSR_FE1)) + | tsk->thread.fpexc_mode; + return 0; } +#endif int sys_clone(int p1, int p2, int p3, int p4, int p5, int p6, struct pt_regs *regs) @@ -465,6 +501,27 @@ print_backtrace(unsigned long *sp) printk("\n"); } +void show_trace_task(struct task_struct *tsk) +{ + unsigned long stack_top = (unsigned long) tsk + THREAD_SIZE; + unsigned long sp, prev_sp; + int count = 0; + + if (tsk == NULL) + return; + sp = (unsigned long) &tsk->thread.ksp; + do { + prev_sp = sp; + sp = *(unsigned long *)sp; + if (sp <= prev_sp || sp >= stack_top || (sp & 3) != 0) + break; + if (count > 0) + printk("[%08lx] ", *(unsigned long *)(sp + 4)); + } while (++count < 16); + if (count > 1) + printk("\n"); +} + #if 0 /* * Low level print for debugging - Cort diff --git a/arch/ppc/kernel/prom.c b/arch/ppc/kernel/prom.c index f0daf9d5f54a..f9c94da5cd2f 100644 --- a/arch/ppc/kernel/prom.c +++ b/arch/ppc/kernel/prom.c @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.prom.c 1.42 09/08/01 15:47:42 paulus + * BK Id: %F% %I% %G% %U% %#% */ /* * Procedures for interfacing to the Open Firmware PROM on @@ -19,6 +19,9 @@ #include <linux/version.h> #include <linux/threads.h> #include <linux/spinlock.h> +#include <linux/ioport.h> +#include <linux/pci.h> +#include <linux/slab.h> #include <asm/sections.h> #include <asm/prom.h> @@ -34,28 +37,13 @@ #include <asm/bitops.h> #include <asm/bootinfo.h> #include <asm/btext.h> -#include "open_pic.h" +#include <asm/pci-bridge.h> +#include <asm/open_pic.h> #ifdef CONFIG_FB #include <asm/linux_logo.h> #endif -/* - * Properties whose value is longer than this get excluded from our - * copy of the device tree. This way we don't waste space storing - * things like "driver,AAPL,MacOS,PowerPC" properties. But this value - * does need to be big enough to ensure that we don't lose things - * like the interrupt-map property on a PCI-PCI bridge. - */ -#define MAX_PROPERTY_LENGTH 4096 - -struct prom_args { - const char *service; - int nargs; - int nret; - void *args[10]; -}; - struct pci_address { unsigned a_hi; unsigned a_mid; @@ -68,26 +56,12 @@ struct pci_reg_property { unsigned size_lo; }; -struct pci_range { - struct pci_address addr; - unsigned phys; - unsigned size_hi; - unsigned size_lo; -}; - struct isa_reg_property { unsigned space; unsigned address; unsigned size; }; -struct pci_intr_map { - struct pci_address addr; - unsigned dunno; - phandle int_ctrler; - unsigned intr; -}; - typedef unsigned long interpret_func(struct device_node *, unsigned long, int, int); static interpret_func interpret_pci_props; @@ -96,27 +70,7 @@ static interpret_func interpret_isa_props; static interpret_func interpret_macio_props; static interpret_func interpret_root_props; -#ifndef FB_MAX /* avoid pulling in all of the fb stuff */ -#define FB_MAX 8 -#endif -char *prom_display_paths[FB_MAX] __initdata = { 0, }; -phandle prom_display_nodes[FB_MAX] __initdata; -unsigned int prom_num_displays __initdata = 0; -char *of_stdout_device __initdata = 0; -ihandle prom_disp_node __initdata = 0; - -prom_entry prom __initdata = 0; -ihandle prom_chosen __initdata = 0; -ihandle prom_stdout __initdata = 0; - extern char *klimit; -char *bootpath; -char *bootdevice; - -unsigned int rtas_data; /* physical pointer */ -unsigned int rtas_entry; /* physical pointer */ -unsigned int rtas_size; -unsigned int old_rtas; /* Set for a newworld or CHRP machine */ int use_of_interrupt_tree; @@ -125,553 +79,30 @@ int num_interrupt_controllers; int pmac_newworld; -static struct device_node *allnodes; +extern unsigned int rtas_entry; /* physical pointer */ + +extern struct device_node *allnodes; -static void *call_prom(const char *service, int nargs, int nret, ...); -static void prom_exit(void); -static unsigned long copy_device_tree(unsigned long, unsigned long); -static unsigned long inspect_node(phandle, struct device_node *, unsigned long, - unsigned long, struct device_node ***); static unsigned long finish_node(struct device_node *, unsigned long, interpret_func *, int, int); static unsigned long finish_node_interrupts(struct device_node *, unsigned long); -static unsigned long check_display(unsigned long); -static int prom_next_node(phandle *); -static void *early_get_property(unsigned long, unsigned long, char *); static struct device_node *find_phandle(phandle); -#ifdef CONFIG_BOOTX_TEXT -static void setup_disp_fake_bi(ihandle dp); -#endif - extern void enter_rtas(void *); void phys_call_rtas(int, int, int, ...); extern char cmd_line[512]; /* XXX */ -boot_infos_t *boot_infos; +extern boot_infos_t *boot_infos; unsigned long dev_tree_size; -#define ALIGN(x) (((x) + sizeof(unsigned long)-1) & -sizeof(unsigned long)) - -/* Is boot-info compatible ? */ -#define BOOT_INFO_IS_COMPATIBLE(bi) ((bi)->compatible_version <= BOOT_INFO_VERSION) -#define BOOT_INFO_IS_V2_COMPATIBLE(bi) ((bi)->version >= 2) -#define BOOT_INFO_IS_V4_COMPATIBLE(bi) ((bi)->version >= 4) - -/* - * Note that prom_init() and anything called from prom_init() must - * use the RELOC/PTRRELOC macros to access any static data in - * memory, since the kernel may be running at an address that is - * different from the address that it was linked at. - * (Note that strings count as static variables.) - */ - -static void __init -prom_exit() -{ - struct prom_args args; - unsigned long offset = reloc_offset(); - - args.service = "exit"; - args.nargs = 0; - args.nret = 0; - RELOC(prom)(&args); - for (;;) /* should never get here */ - ; -} - -void __init -prom_enter(void) -{ - struct prom_args args; - unsigned long offset = reloc_offset(); - - args.service = RELOC("enter"); - args.nargs = 0; - args.nret = 0; - RELOC(prom)(&args); -} - -static void * __init -call_prom(const char *service, int nargs, int nret, ...) -{ - va_list list; - int i; - unsigned long offset = reloc_offset(); - struct prom_args prom_args; - - prom_args.service = service; - prom_args.nargs = nargs; - prom_args.nret = nret; - va_start(list, nret); - for (i = 0; i < nargs; ++i) - prom_args.args[i] = va_arg(list, void *); - va_end(list); - for (i = 0; i < nret; ++i) - prom_args.args[i + nargs] = 0; - RELOC(prom)(&prom_args); - return prom_args.args[nargs]; -} - -void __init -prom_print(const char *msg) -{ - const char *p, *q; - unsigned long offset = reloc_offset(); - - if (RELOC(prom_stdout) == 0) - return; - - for (p = msg; *p != 0; p = q) { - for (q = p; *q != 0 && *q != '\n'; ++q) - ; - if (q > p) - call_prom(RELOC("write"), 3, 1, RELOC(prom_stdout), - p, q - p); - if (*q != 0) { - ++q; - call_prom(RELOC("write"), 3, 1, RELOC(prom_stdout), - RELOC("\r\n"), 2); - } - } -} - -static void __init -prom_print_hex(unsigned int v) -{ - char buf[16]; - int i, c; - - for (i = 0; i < 8; ++i) { - c = (v >> ((7-i)*4)) & 0xf; - c += (c >= 10)? ('a' - 10): '0'; - buf[i] = c; - } - buf[i] = ' '; - buf[i+1] = 0; - prom_print(buf); -} - -unsigned long smp_chrp_cpu_nr __initdata = 0; - -#ifdef CONFIG_SMP -/* - * With CHRP SMP we need to use the OF to start the other - * processors so we can't wait until smp_boot_cpus (the OF is - * trashed by then) so we have to put the processors into - * a holding pattern controlled by the kernel (not OF) before - * we destroy the OF. - * - * This uses a chunk of high memory, puts some holding pattern - * code there and sends the other processors off to there until - * smp_boot_cpus tells them to do something. We do that by using - * physical address 0x0. The holding pattern checks that address - * until its cpu # is there, when it is that cpu jumps to - * __secondary_start(). smp_boot_cpus() takes care of setting those - * values. - * - * We also use physical address 0x4 here to tell when a cpu - * is in its holding pattern code. - * - * -- Cort - */ -static void __init -prom_hold_cpus(unsigned long mem) -{ - extern void __secondary_hold(void); - unsigned long i; - int cpu; - phandle node; - unsigned long offset = reloc_offset(); - char type[16], *path; - unsigned int reg; - - /* - * XXX: hack to make sure we're chrp, assume that if we're - * chrp we have a device_type property -- Cort - */ - node = call_prom(RELOC("finddevice"), 1, 1, RELOC("/")); - if ( (int)call_prom(RELOC("getprop"), 4, 1, node, - RELOC("device_type"),type, sizeof(type)) <= 0) - return; - - /* copy the holding pattern code to someplace safe (0) */ - /* the holding pattern is now within the first 0x100 - bytes of the kernel image -- paulus */ - memcpy((void *)0, (void *)(KERNELBASE + offset), 0x100); - flush_icache_range(0, 0x100); - - /* look for cpus */ - *(unsigned long *)(0x0) = 0; - asm volatile("dcbf 0,%0": : "r" (0) : "memory"); - for (node = 0; prom_next_node(&node); ) { - type[0] = 0; - call_prom(RELOC("getprop"), 4, 1, node, RELOC("device_type"), - type, sizeof(type)); - if (strcmp(type, RELOC("cpu")) != 0) - continue; - path = (char *) mem; - memset(path, 0, 256); - if ((int) call_prom(RELOC("package-to-path"), 3, 1, - node, path, 255) < 0) - continue; - reg = -1; - call_prom(RELOC("getprop"), 4, 1, node, RELOC("reg"), - ®, sizeof(reg)); - cpu = RELOC(smp_chrp_cpu_nr)++; - RELOC(smp_hw_index)[cpu] = reg; - /* XXX: hack - don't start cpu 0, this cpu -- Cort */ - if (cpu == 0) - continue; - prom_print(RELOC("starting cpu ")); - prom_print(path); - *(ulong *)(0x4) = 0; - call_prom(RELOC("start-cpu"), 3, 0, node, - __pa(__secondary_hold), cpu); - prom_print(RELOC("...")); - for ( i = 0 ; (i < 10000) && (*(ulong *)(0x4) == 0); i++ ) - ; - if (*(ulong *)(0x4) == cpu) - prom_print(RELOC("ok\n")); - else { - prom_print(RELOC("failed: ")); - prom_print_hex(*(ulong *)0x4); - prom_print(RELOC("\n")); - } - } -} -#endif /* CONFIG_SMP */ - -void __init -bootx_init(unsigned long r4, unsigned long phys) -{ - boot_infos_t *bi = (boot_infos_t *) r4; - unsigned long space; - unsigned long ptr, x; - char *model; - unsigned long offset = reloc_offset(); - - RELOC(boot_infos) = PTRUNRELOC(bi); - if (!BOOT_INFO_IS_V2_COMPATIBLE(bi)) - bi->logicalDisplayBase = 0; - -#ifdef CONFIG_BOOTX_TEXT - btext_init(bi); - - /* - * Test if boot-info is compatible. Done only in config - * CONFIG_BOOTX_TEXT since there is nothing much we can do - * with an incompatible version, except display a message - * and eventually hang the processor... - * - * I'll try to keep enough of boot-info compatible in the - * future to always allow display of this message; - */ - if (!BOOT_INFO_IS_COMPATIBLE(bi)) { - btext_drawstring(RELOC(" !!! WARNING - Incompatible version of BootX !!!\n\n\n")); - btext_flushscreen(); - } -#endif /* CONFIG_BOOTX_TEXT */ - - /* New BootX enters kernel with MMU off, i/os are not allowed - here. This hack will have been done by the boostrap anyway. - */ - if (bi->version < 4) { - /* - * XXX If this is an iMac, turn off the USB controller. - */ - model = (char *) early_get_property - (r4 + bi->deviceTreeOffset, 4, RELOC("model")); - if (model - && (strcmp(model, RELOC("iMac,1")) == 0 - || strcmp(model, RELOC("PowerMac1,1")) == 0)) { - out_le32((unsigned *)0x80880008, 1); /* XXX */ - } - } - - /* Move klimit to enclose device tree, args, ramdisk, etc... */ - if (bi->version < 5) { - space = bi->deviceTreeOffset + bi->deviceTreeSize; - if (bi->ramDisk) - space = bi->ramDisk + bi->ramDiskSize; - } else - space = bi->totalParamsSize; - RELOC(klimit) = PTRUNRELOC((char *) bi + space); - - /* New BootX will have flushed all TLBs and enters kernel with - MMU switched OFF, so this should not be useful anymore. - */ - if (bi->version < 4) { - /* - * Touch each page to make sure the PTEs for them - * are in the hash table - the aim is to try to avoid - * getting DSI exceptions while copying the kernel image. - */ - for (ptr = (KERNELBASE + offset) & PAGE_MASK; - ptr < (unsigned long)bi + space; ptr += PAGE_SIZE) - x = *(volatile unsigned long *)ptr; - } - -#ifdef CONFIG_BOOTX_TEXT - /* - * Note that after we call prepare_disp_BAT, we can't do - * prom_draw*, flushscreen or clearscreen until we turn the MMU - * on, since prepare_disp_BAT sets disp_bi->logicalDisplayBase - * to a virtual address. - */ - btext_prepare_BAT(); -#endif -} - -#ifdef CONFIG_PPC64BRIDGE -/* - * Set up a hash table with a set of entries in it to map the - * first 64MB of RAM. This is used on 64-bit machines since - * some of them don't have BATs. - * We assume the PTE will fit in the primary PTEG. - */ - -static inline void make_pte(unsigned long htab, unsigned int hsize, - unsigned int va, unsigned int pa, int mode) -{ - unsigned int *pteg; - unsigned int hash, i, vsid; - - vsid = ((va >> 28) * 0x111) << 12; - hash = ((va ^ vsid) >> 5) & 0x7fff80; - pteg = (unsigned int *)(htab + (hash & (hsize - 1))); - for (i = 0; i < 8; ++i, pteg += 4) { - if ((pteg[1] & 1) == 0) { - pteg[1] = vsid | ((va >> 16) & 0xf80) | 1; - pteg[3] = pa | mode; - break; - } - } -} - -extern unsigned long _SDR1; -extern PTE *Hash; -extern unsigned long Hash_size; - -static void __init -prom_alloc_htab(void) -{ - unsigned int hsize; - unsigned long htab; - unsigned int addr; - unsigned long offset = reloc_offset(); - - /* - * Because of OF bugs we can't use the "claim" client - * interface to allocate memory for the hash table. - * This code is only used on 64-bit PPCs, and the only - * 64-bit PPCs at the moment are RS/6000s, and their - * OF is based at 0xc00000 (the 12M point), so we just - * arbitrarily use the 0x800000 - 0xc00000 region for the - * hash table. - * -- paulus. - */ -#ifdef CONFIG_POWER4 - hsize = 4 << 20; /* POWER4 has no BATs */ -#else - hsize = 2 << 20; -#endif /* CONFIG_POWER4 */ - htab = (8 << 20); - RELOC(Hash) = (void *)(htab + KERNELBASE); - RELOC(Hash_size) = hsize; - RELOC(_SDR1) = htab + __ilog2(hsize) - 18; - - /* - * Put in PTEs for the first 64MB of RAM - */ - cacheable_memzero((void *)htab, hsize); - for (addr = 0; addr < 0x4000000; addr += 0x1000) - make_pte(htab, hsize, addr + KERNELBASE, addr, - _PAGE_ACCESSED | _PAGE_COHERENT | PP_RWXX); -} -#endif /* CONFIG_PPC64BRIDGE */ - -static void __init -prom_instantiate_rtas(void) -{ - ihandle prom_rtas; - unsigned int i; - struct prom_args prom_args; - unsigned long offset = reloc_offset(); - - prom_rtas = call_prom(RELOC("finddevice"), 1, 1, RELOC("/rtas")); - if (prom_rtas == (void *) -1) - return; - - RELOC(rtas_size) = 0; - call_prom(RELOC("getprop"), 4, 1, prom_rtas, - RELOC("rtas-size"), &RELOC(rtas_size), sizeof(rtas_size)); - prom_print(RELOC("instantiating rtas")); - if (RELOC(rtas_size) == 0) { - RELOC(rtas_data) = 0; - } else { - /* - * Ask OF for some space for RTAS. - * Actually OF has bugs so we just arbitrarily - * use memory at the 6MB point. - */ - RELOC(rtas_data) = 6 << 20; - prom_print(RELOC(" at ")); - prom_print_hex(RELOC(rtas_data)); - } - - prom_rtas = call_prom(RELOC("open"), 1, 1, RELOC("/rtas")); - prom_print(RELOC("...")); - prom_args.service = RELOC("call-method"); - prom_args.nargs = 3; - prom_args.nret = 2; - prom_args.args[0] = RELOC("instantiate-rtas"); - prom_args.args[1] = prom_rtas; - prom_args.args[2] = (void *) RELOC(rtas_data); - RELOC(prom)(&prom_args); - i = 0; - if (prom_args.args[3] == 0) - i = (unsigned int)prom_args.args[4]; - RELOC(rtas_entry) = i; - if ((RELOC(rtas_entry) == -1) || (RELOC(rtas_entry) == 0)) - prom_print(RELOC(" failed\n")); - else - prom_print(RELOC(" done\n")); -} - -/* - * We enter here early on, when the Open Firmware prom is still - * handling exceptions and the MMU hash table for us. - */ -unsigned long __init -prom_init(int r3, int r4, prom_entry pp) -{ - unsigned long mem; - ihandle prom_mmu; - unsigned long offset = reloc_offset(); - int l; - char *p, *d; - unsigned long phys; - - /* Default */ - phys = offset + KERNELBASE; - - /* First get a handle for the stdout device */ - RELOC(prom) = pp; - RELOC(prom_chosen) = call_prom(RELOC("finddevice"), 1, 1, - RELOC("/chosen")); - if (RELOC(prom_chosen) == (void *)-1) - prom_exit(); - if ((int) call_prom(RELOC("getprop"), 4, 1, RELOC(prom_chosen), - RELOC("stdout"), &RELOC(prom_stdout), - sizeof(prom_stdout)) <= 0) - prom_exit(); - - /* Get the full OF pathname of the stdout device */ - mem = (unsigned long) RELOC(klimit) + offset; - p = (char *) mem; - memset(p, 0, 256); - call_prom(RELOC("instance-to-path"), 3, 1, RELOC(prom_stdout), p, 255); - RELOC(of_stdout_device) = PTRUNRELOC(p); - mem += strlen(p) + 1; - - /* Get the boot device and translate it to a full OF pathname. */ - p = (char *) mem; - l = (int) call_prom(RELOC("getprop"), 4, 1, RELOC(prom_chosen), - RELOC("bootpath"), p, 1<<20); - if (l > 0) { - p[l] = 0; /* should already be null-terminated */ - RELOC(bootpath) = PTRUNRELOC(p); - mem += l + 1; - d = (char *) mem; - *d = 0; - call_prom(RELOC("canon"), 3, 1, p, d, 1<<20); - RELOC(bootdevice) = PTRUNRELOC(d); - mem = ALIGN(mem + strlen(d) + 1); - } - - prom_instantiate_rtas(); - -#ifdef CONFIG_PPC64BRIDGE - /* - * Find out how much memory we have and allocate a - * suitably-sized hash table. - */ - prom_alloc_htab(); -#endif - - mem = check_display(mem); - - prom_print(RELOC("copying OF device tree...")); - mem = copy_device_tree(mem, mem + (1<<20)); - prom_print(RELOC("done\n")); - -#ifdef CONFIG_SMP - prom_hold_cpus(mem); -#endif - - RELOC(klimit) = (char *) (mem - offset); - - /* If we are already running at 0xc0000000, we assume we were loaded by - * an OF bootloader which did set a BAT for us. This breaks OF translate - * so we force phys to be 0 - */ - if (offset == 0) - phys = 0; - else { - if ((int) call_prom(RELOC("getprop"), 4, 1, RELOC(prom_chosen), - RELOC("mmu"), &prom_mmu, sizeof(prom_mmu)) <= 0) { - prom_print(RELOC(" no MMU found\n")); - } else { - int nargs; - struct prom_args prom_args; - nargs = 4; - prom_args.service = RELOC("call-method"); - prom_args.nargs = nargs; - prom_args.nret = 4; - prom_args.args[0] = RELOC("translate"); - prom_args.args[1] = prom_mmu; - prom_args.args[2] = (void *)(offset + KERNELBASE); - prom_args.args[3] = (void *)1; - RELOC(prom)(&prom_args); - - /* We assume the phys. address size is 3 cells */ - if (prom_args.args[nargs] != 0) - prom_print(RELOC(" (translate failed)\n")); - else - phys = (unsigned long)prom_args.args[nargs+3]; - } - } - -#ifdef CONFIG_BOOTX_TEXT - if (RELOC(prom_disp_node) != 0) - setup_disp_fake_bi(RELOC(prom_disp_node)); -#endif - - /* Use quiesce call to get OF to shut down any devices it's using */ - prom_print(RELOC("Calling quiesce ...\n")); - call_prom(RELOC("quiesce"), 0, 0); - -#ifdef CONFIG_BOOTX_TEXT - btext_prepare_BAT(); -#endif - - prom_print(RELOC("returning ")); - prom_print_hex(phys); - prom_print(RELOC(" from prom_init\n")); - RELOC(prom_stdout) = 0; - - return phys; -} - -void phys_call_rtas(int service, int nargs, int nret, ...) +void __openfirmware +phys_call_rtas(int service, int nargs, int nret, ...) { va_list list; union { unsigned long words[16]; double align; } u; - unsigned long offset = reloc_offset(); void (*rtas)(void *, unsigned long); int i; @@ -683,340 +114,8 @@ void phys_call_rtas(int service, int nargs, int nret, ...) u.words[i+3] = va_arg(list, unsigned long); va_end(list); - rtas = (void (*)(void *, unsigned long)) RELOC(rtas_entry); - rtas(&u, RELOC(rtas_data)); -} - -static int __init -prom_set_color(ihandle ih, int i, int r, int g, int b) -{ - struct prom_args prom_args; - unsigned long offset = reloc_offset(); - - prom_args.service = RELOC("call-method"); - prom_args.nargs = 6; - prom_args.nret = 1; - prom_args.args[0] = RELOC("color!"); - prom_args.args[1] = ih; - prom_args.args[2] = (void *) i; - prom_args.args[3] = (void *) b; - prom_args.args[4] = (void *) g; - prom_args.args[5] = (void *) r; - RELOC(prom)(&prom_args); - return (int) prom_args.args[6]; -} - -/* - * If we have a display that we don't know how to drive, - * we will want to try to execute OF's open method for it - * later. However, OF will probably fall over if we do that - * we've taken over the MMU. - * So we check whether we will need to open the display, - * and if so, open it now. - */ -static unsigned long __init -check_display(unsigned long mem) -{ - phandle node; - ihandle ih; - int i; - unsigned long offset = reloc_offset(); - char type[16], *path; - static unsigned char default_colors[] = { - 0x00, 0x00, 0x00, - 0x00, 0x00, 0xaa, - 0x00, 0xaa, 0x00, - 0x00, 0xaa, 0xaa, - 0xaa, 0x00, 0x00, - 0xaa, 0x00, 0xaa, - 0xaa, 0xaa, 0x00, - 0xaa, 0xaa, 0xaa, - 0x55, 0x55, 0x55, - 0x55, 0x55, 0xff, - 0x55, 0xff, 0x55, - 0x55, 0xff, 0xff, - 0xff, 0x55, 0x55, - 0xff, 0x55, 0xff, - 0xff, 0xff, 0x55, - 0xff, 0xff, 0xff - }; - - RELOC(prom_disp_node) = 0; - - for (node = 0; prom_next_node(&node); ) { - type[0] = 0; - call_prom(RELOC("getprop"), 4, 1, node, RELOC("device_type"), - type, sizeof(type)); - if (strcmp(type, RELOC("display")) != 0) - continue; - /* It seems OF doesn't null-terminate the path :-( */ - path = (char *) mem; - memset(path, 0, 256); - if ((int) call_prom(RELOC("package-to-path"), 3, 1, - node, path, 255) < 0) - continue; - - /* - * If this display is the device that OF is using for stdout, - * move it to the front of the list. - */ - mem += strlen(path) + 1; - i = RELOC(prom_num_displays)++; - if (RELOC(of_stdout_device) != 0 && i > 0 - && strcmp(PTRRELOC(RELOC(of_stdout_device)), path) == 0) { - for (; i > 0; --i) { - RELOC(prom_display_paths[i]) - = RELOC(prom_display_paths[i-1]); - RELOC(prom_display_nodes[i]) - = RELOC(prom_display_nodes[i-1]); - } - } - RELOC(prom_display_paths[i]) = PTRUNRELOC(path); - RELOC(prom_display_nodes[i]) = node; - if (i == 0) - RELOC(prom_disp_node) = node; - if (RELOC(prom_num_displays) >= FB_MAX) - break; - } - -try_again: - /* - * Open the first display and set its colormap. - */ - if (RELOC(prom_num_displays) > 0) { - path = PTRRELOC(RELOC(prom_display_paths[0])); - prom_print(RELOC("opening display ")); - prom_print(path); - ih = call_prom(RELOC("open"), 1, 1, path); - if (ih == 0 || ih == (ihandle) -1) { - prom_print(RELOC("... failed\n")); - for (i=1; i<RELOC(prom_num_displays); i++) { - RELOC(prom_display_paths[i-1]) = RELOC(prom_display_paths[i]); - RELOC(prom_display_nodes[i-1]) = RELOC(prom_display_nodes[i]); - } - if (--RELOC(prom_num_displays) > 0) - RELOC(prom_disp_node) = RELOC(prom_display_nodes[0]); - else - RELOC(prom_disp_node) = NULL; - goto try_again; - } else { - prom_print(RELOC("... ok\n")); - /* - * Setup a usable color table when the appropriate - * method is available. - * Should update this to use set-colors. - */ - for (i = 0; i < 32; i++) - if (prom_set_color(ih, i, RELOC(default_colors)[i*3], - RELOC(default_colors)[i*3+1], - RELOC(default_colors)[i*3+2]) != 0) - break; - -#ifdef CONFIG_FB - for (i = 0; i < LINUX_LOGO_COLORS; i++) - if (prom_set_color(ih, i + 32, - RELOC(linux_logo_red)[i], - RELOC(linux_logo_green)[i], - RELOC(linux_logo_blue)[i]) != 0) - break; -#endif /* CONFIG_FB */ - } - } - - return ALIGN(mem); -} - -/* This function will enable the early boot text when doing OF booting. This - * way, xmon output should work too - */ -#ifdef CONFIG_BOOTX_TEXT -static void __init -setup_disp_fake_bi(ihandle dp) -{ - int width = 640, height = 480, depth = 8, pitch; - unsigned address; - unsigned long offset = reloc_offset(); - struct pci_reg_property addrs[8]; - int i, naddrs; - char name[32]; - char *getprop = RELOC("getprop"); - - prom_print(RELOC("Initializing fake screen: ")); - - memset(name, 0, sizeof(name)); - call_prom(getprop, 4, 1, dp, RELOC("name"), name, sizeof(name)); - name[sizeof(name)-1] = 0; - prom_print(name); - prom_print(RELOC("\n")); - call_prom(getprop, 4, 1, dp, RELOC("width"), &width, sizeof(width)); - call_prom(getprop, 4, 1, dp, RELOC("height"), &height, sizeof(height)); - call_prom(getprop, 4, 1, dp, RELOC("depth"), &depth, sizeof(depth)); - pitch = width * ((depth + 7) / 8); - call_prom(getprop, 4, 1, dp, RELOC("linebytes"), - &pitch, sizeof(pitch)); - if (pitch == 1) - pitch = 0x1000; /* for strange IBM display */ - address = 0; - call_prom(getprop, 4, 1, dp, RELOC("address"), - &address, sizeof(address)); - if (address == 0) { - /* look for an assigned address with a size of >= 1MB */ - naddrs = (int) call_prom(getprop, 4, 1, dp, - RELOC("assigned-addresses"), - addrs, sizeof(addrs)); - naddrs /= sizeof(struct pci_reg_property); - for (i = 0; i < naddrs; ++i) { - if (addrs[i].size_lo >= (1 << 20)) { - address = addrs[i].addr.a_lo; - /* use the BE aperture if possible */ - if (addrs[i].size_lo >= (16 << 20)) - address += (8 << 20); - break; - } - } - if (address == 0) { - prom_print(RELOC("Failed to get address\n")); - return; - } - } - /* kludge for valkyrie */ - if (strcmp(name, RELOC("valkyrie")) == 0) - address += 0x1000; - - btext_setup_display(width, height, depth, pitch, address); -} -#endif - -static int __init -prom_next_node(phandle *nodep) -{ - phandle node; - unsigned long offset = reloc_offset(); - - if ((node = *nodep) != 0 - && (*nodep = call_prom(RELOC("child"), 1, 1, node)) != 0) - return 1; - if ((*nodep = call_prom(RELOC("peer"), 1, 1, node)) != 0) - return 1; - for (;;) { - if ((node = call_prom(RELOC("parent"), 1, 1, node)) == 0) - return 0; - if ((*nodep = call_prom(RELOC("peer"), 1, 1, node)) != 0) - return 1; - } -} - -/* - * Make a copy of the device tree from the PROM. - */ -static unsigned long __init -copy_device_tree(unsigned long mem_start, unsigned long mem_end) -{ - phandle root; - unsigned long new_start; - struct device_node **allnextp; - unsigned long offset = reloc_offset(); - - root = call_prom(RELOC("peer"), 1, 1, (phandle)0); - if (root == (phandle)0) { - prom_print(RELOC("couldn't get device tree root\n")); - prom_exit(); - } - allnextp = &RELOC(allnodes); - mem_start = ALIGN(mem_start); - new_start = inspect_node(root, 0, mem_start, mem_end, &allnextp); - *allnextp = 0; - return new_start; -} - -static unsigned long __init -inspect_node(phandle node, struct device_node *dad, - unsigned long mem_start, unsigned long mem_end, - struct device_node ***allnextpp) -{ - int l; - phandle child; - struct device_node *np; - struct property *pp, **prev_propp; - char *prev_name, *namep; - unsigned char *valp; - unsigned long offset = reloc_offset(); - - np = (struct device_node *) mem_start; - mem_start += sizeof(struct device_node); - memset(np, 0, sizeof(*np)); - np->node = node; - **allnextpp = PTRUNRELOC(np); - *allnextpp = &np->allnext; - if (dad != 0) { - np->parent = PTRUNRELOC(dad); - /* we temporarily use the `next' field as `last_child'. */ - if (dad->next == 0) - dad->child = PTRUNRELOC(np); - else - dad->next->sibling = PTRUNRELOC(np); - dad->next = np; - } - - /* get and store all properties */ - prev_propp = &np->properties; - prev_name = RELOC(""); - for (;;) { - pp = (struct property *) mem_start; - namep = (char *) (pp + 1); - pp->name = PTRUNRELOC(namep); - if ((int) call_prom(RELOC("nextprop"), 3, 1, node, prev_name, - namep) <= 0) - break; - mem_start = ALIGN((unsigned long)namep + strlen(namep) + 1); - prev_name = namep; - valp = (unsigned char *) mem_start; - pp->value = PTRUNRELOC(valp); - pp->length = (int) - call_prom(RELOC("getprop"), 4, 1, node, namep, - valp, mem_end - mem_start); - if (pp->length < 0) - continue; -#ifdef MAX_PROPERTY_LENGTH - if (pp->length > MAX_PROPERTY_LENGTH) - continue; /* ignore this property */ -#endif - mem_start = ALIGN(mem_start + pp->length); - *prev_propp = PTRUNRELOC(pp); - prev_propp = &pp->next; - } - if (np->node != NULL) { - /* Add a "linux,phandle" property" */ - pp = (struct property *) mem_start; - *prev_propp = PTRUNRELOC(pp); - prev_propp = &pp->next; - namep = (char *) (pp + 1); - pp->name = PTRUNRELOC(namep); - strcpy(namep, RELOC("linux,phandle")); - mem_start = ALIGN((unsigned long)namep + strlen(namep) + 1); - pp->value = (unsigned char *) PTRUNRELOC(&np->node); - pp->length = sizeof(np->node); - } - *prev_propp = NULL; - - /* get the node's full name */ - l = (int) call_prom(RELOC("package-to-path"), 3, 1, node, - (char *) mem_start, mem_end - mem_start); - if (l >= 0) { - np->full_name = PTRUNRELOC((char *) mem_start); - *(char *)(mem_start + l) = 0; - mem_start = ALIGN(mem_start + l + 1); - } - - /* do all our children */ - child = call_prom(RELOC("child"), 1, 1, node); - while (child != (void *)0) { - mem_start = inspect_node(child, np, mem_start, mem_end, - allnextpp); - child = call_prom(RELOC("peer"), 1, 1, child); - } - - return mem_start; + rtas = (void (*)(void *, unsigned long)) rtas_entry; + rtas(&u, rtas_data); } /* @@ -1081,26 +180,6 @@ finish_device_tree(void) klimit = (char *) mem; } -/* - * early_get_property is used to access the device tree image prepared - * by BootX very early on, before the pointers in it have been relocated. - */ -static void * __init -early_get_property(unsigned long base, unsigned long node, char *prop) -{ - struct device_node *np = (struct device_node *)(base + node); - struct property *pp; - - for (pp = np->properties; pp != 0; pp = pp->next) { - pp = (struct property *) (base + (unsigned long)pp); - if (strcmp((char *)((unsigned long)pp->name + base), - prop) == 0) { - return (void *)((unsigned long)pp->value + base); - } - } - return 0; -} - static unsigned long __init finish_node(struct device_node *np, unsigned long mem_start, interpret_func *ifunc, int naddrc, int nsizec) @@ -1111,10 +190,15 @@ finish_node(struct device_node *np, unsigned long mem_start, np->name = get_property(np, "name", 0); np->type = get_property(np, "device_type", 0); + if (!np->name) + np->name = "<NULL>"; + if (!np->type) + np->type = "<NULL>"; + /* get the device addresses and interrupts */ - if (ifunc != NULL) { + if (ifunc != NULL) mem_start = ifunc(np, mem_start, naddrc, nsizec); - } + if (use_of_interrupt_tree) mem_start = finish_node_interrupts(np, mem_start); @@ -1126,12 +210,6 @@ finish_node(struct device_node *np, unsigned long mem_start, if (ip != NULL) nsizec = *ip; - /* the f50 sets the name to 'display' and 'compatible' to what we - * expect for the name -- Cort - */ - if (!strcmp(np->name, "display")) - np->name = get_property(np, "compatible", 0); - if (np->parent == NULL) ifunc = interpret_root_props; else if (np->type == 0) @@ -1145,6 +223,8 @@ finish_node(struct device_node *np, unsigned long mem_start, ifunc = interpret_macio_props; else if (!strcmp(np->type, "isa")) ifunc = interpret_isa_props; + else if (!strcmp(np->name, "uni-n")) + ifunc = interpret_root_props; else if (!((ifunc == interpret_dbdma_props || ifunc == interpret_macio_props) && (!strcmp(np->type, "escc") @@ -1508,7 +588,7 @@ interpret_dbdma_props(struct device_node *np, unsigned long mem_start, i = 0; adr = (struct address_range *) mem_start; while ((l -= sizeof(struct reg_property)) >= 0) { - adr[i].space = 0; + adr[i].space = 2; adr[i].address = rp[i].address + base_address; adr[i].size = rp[i].size; ++i; @@ -1544,14 +624,13 @@ interpret_macio_props(struct device_node *np, unsigned long mem_start, struct reg_property *rp; struct address_range *adr; unsigned long base_address; - int i, l, keylargo, *ip; + int i, l, *ip; struct device_node *db; base_address = 0; for (db = np->parent; db != NULL; db = db->parent) { if (!strcmp(db->type, "mac-io") && db->n_addrs != 0) { base_address = db->addrs[0].address; - keylargo = device_is_compatible(db, "Keylargo"); break; } } @@ -1561,7 +640,7 @@ interpret_macio_props(struct device_node *np, unsigned long mem_start, i = 0; adr = (struct address_range *) mem_start; while ((l -= sizeof(struct reg_property)) >= 0) { - adr[i].space = 0; + adr[i].space = 2; adr[i].address = rp[i].address + base_address; adr[i].size = rp[i].size; ++i; @@ -1616,7 +695,7 @@ interpret_isa_props(struct device_node *np, unsigned long mem_start, if (use_of_interrupt_tree) return mem_start; - + ip = (int *) get_property(np, "interrupts", &l); if (ip != 0) { np->intrs = (struct interrupt_info *) mem_start; @@ -1645,7 +724,7 @@ interpret_root_props(struct device_node *np, unsigned long mem_start, i = 0; adr = (struct address_range *) mem_start; while ((l -= rpsize) >= 0) { - adr[i].space = (naddrc >= 2? rp[naddrc-2]: 0); + adr[i].space = (naddrc >= 2? rp[naddrc-2]: 2); adr[i].address = rp[naddrc - 1]; adr[i].size = rp[naddrc + nsizec - 1]; ++i; @@ -1786,7 +865,7 @@ int machine_is_compatible(const char *compat) { struct device_node *root; - + root = find_path_device("/"); if (root == 0) return 0; @@ -1870,12 +949,178 @@ prom_add_property(struct device_node* np, struct property* prop) { struct property **next = &np->properties; - prop->next = NULL; + prop->next = NULL; while (*next) next = &(*next)->next; *next = prop; } +/* I quickly hacked that one, check against spec ! */ +static inline unsigned long __openfirmware +bus_space_to_resource_flags(unsigned int bus_space) +{ + u8 space = (bus_space >> 24) & 0xf; + if (space == 0) + space = 0x02; + if (space == 0x02) + return IORESOURCE_MEM; + else if (space == 0x01) + return IORESOURCE_IO; + else { + printk(KERN_WARNING "prom.c: bus_space_to_resource_flags(), space: %x\n", + bus_space); + return 0; + } +} + +static struct resource* __openfirmware +find_parent_pci_resource(struct pci_dev* pdev, struct address_range *range) +{ + unsigned long mask; + int i; + + /* Check this one */ + mask = bus_space_to_resource_flags(range->space); + for (i=0; i<DEVICE_COUNT_RESOURCE; i++) { + if ((pdev->resource[i].flags & mask) == mask && + pdev->resource[i].start <= range->address && + pdev->resource[i].end > range->address) { + if ((range->address + range->size - 1) > pdev->resource[i].end) { + /* Add better message */ + printk(KERN_WARNING "PCI/OF resource overlap !\n"); + return NULL; + } + break; + } + } + if (i == DEVICE_COUNT_RESOURCE) + return NULL; + return &pdev->resource[i]; +} + +/* + * Request an OF device resource. Currently handles child of PCI devices, + * or other nodes attached to the root node. Ultimately, put some + * link to resources in the OF node. + * WARNING: out_resource->name should be initialized before calling this + * function. + */ +struct resource* __openfirmware +request_OF_resource(struct device_node* node, int index, const char* name_postfix) +{ + struct pci_dev* pcidev; + u8 pci_bus, pci_devfn; + unsigned long iomask; + struct device_node* nd; + struct resource* parent; + struct resource *res = NULL; + int nlen, plen; + + if (index >= node->n_addrs) + goto fail; + + /* Sanity check on bus space */ + iomask = bus_space_to_resource_flags(node->addrs[index].space); + if (iomask & IORESOURCE_MEM) + parent = &iomem_resource; + else if (iomask & IORESOURCE_IO) + parent = &ioport_resource; + else + goto fail; + + /* Find a PCI parent if any */ + nd = node; + pcidev = NULL; + while(nd) { + if (!pci_device_from_OF_node(nd, &pci_bus, &pci_devfn)) + pcidev = pci_find_slot(pci_bus, pci_devfn); + if (pcidev) break; + nd = nd->parent; + } + if (pcidev) + parent = find_parent_pci_resource(pcidev, &node->addrs[index]); + if (!parent) { + printk(KERN_WARNING "request_OF_resource(%s), parent not found\n", + node->name); + goto fail; + } + + res = __request_region(parent, node->addrs[index].address, node->addrs[index].size, NULL); + if (!res) + goto fail; + nlen = strlen(node->name); + plen = name_postfix ? strlen(name_postfix) : 0; + res->name = (const char *)kmalloc(nlen+plen+1, GFP_KERNEL); + if (res->name) { + strcpy((char *)res->name, node->name); + if (plen) + strcpy((char *)res->name+nlen, name_postfix); + } + return res; +fail: + return NULL; +} + +int __openfirmware +release_OF_resource(struct device_node* node, int index) +{ + struct pci_dev* pcidev; + u8 pci_bus, pci_devfn; + unsigned long iomask; + struct device_node* nd; + struct resource* parent; + struct resource *res = NULL; + + if (index >= node->n_addrs) + return -EINVAL; + + /* Sanity check on bus space */ + iomask = bus_space_to_resource_flags(node->addrs[index].space); + if (iomask & IORESOURCE_MEM) + parent = &iomem_resource; + else if (iomask & IORESOURCE_IO) + parent = &ioport_resource; + else + return -EINVAL; + + /* Find a PCI parent if any */ + nd = node; + pcidev = NULL; + while(nd) { + if (!pci_device_from_OF_node(nd, &pci_bus, &pci_devfn)) + pcidev = pci_find_slot(pci_bus, pci_devfn); + if (pcidev) break; + nd = nd->parent; + } + if (pcidev) + parent = find_parent_pci_resource(pcidev, &node->addrs[index]); + if (!parent) { + printk(KERN_WARNING "request_OF_resource(%s), parent not found\n", + node->name); + return -ENODEV; + } + + /* Find us in the parent */ + res = parent->child; + while (res) { + if (res->start == node->addrs[index].address && + res->end == (res->start + node->addrs[index].size - 1)) + break; + res = res->sibling; + } + if (!res) + return -ENODEV; + + if (res->name) { + kfree(res->name); + res->name = NULL; + } + release_resource(res); + kfree(res); + + return 0; +} + #if 0 void __openfirmware print_properties(struct device_node *np) @@ -1961,11 +1206,11 @@ call_rtas(const char *service, int nargs, int nret, u.words[i+3] = va_arg(list, unsigned long); va_end(list); - /* Shouldn't we enable kernel FP here ? enter_rtas will play - * with MSR_FE0|MSR_FE1|MSR_FP so I assume rtas might use - * floating points. If that's the case, then we need to make - * sure any lazy FP context is backed up - * --BenH + /* + * RTAS doesn't use floating point. + * Or at least, according to the CHRP spec we enter RTAS + * with FP disabled, and it doesn't change the FP registers. + * -- paulus. */ spin_lock_irqsave(&rtas_lock, s); enter_rtas((void *)__pa(&u)); @@ -1976,13 +1221,3 @@ call_rtas(const char *service, int nargs, int nret, outputs[i] = u.words[i+nargs+4]; return u.words[nargs+3]; } - -void __init -abort() -{ -#ifdef CONFIG_XMON - xmon(NULL); -#endif - for (;;) - prom_exit(); -} diff --git a/arch/ppc/kernel/prom_init.c b/arch/ppc/kernel/prom_init.c new file mode 100644 index 000000000000..fea41427aa29 --- /dev/null +++ b/arch/ppc/kernel/prom_init.c @@ -0,0 +1,899 @@ +/* + * Note that prom_init() and anything called from prom_init() + * may be running at an address that is different from the address + * that it was linked at. References to static data items are + * handled by compiling this file with -mrelocatable-lib. + */ + +#include <linux/config.h> +#include <linux/kernel.h> +#include <linux/string.h> +#include <linux/init.h> +#include <linux/version.h> +#include <linux/threads.h> +#include <linux/spinlock.h> +#include <linux/ioport.h> +#include <linux/pci.h> +#include <linux/slab.h> + +#include <asm/sections.h> +#include <asm/prom.h> +#include <asm/page.h> +#include <asm/processor.h> +#include <asm/irq.h> +#include <asm/io.h> +#include <asm/smp.h> +#include <asm/bootx.h> +#include <asm/system.h> +#include <asm/mmu.h> +#include <asm/pgtable.h> +#include <asm/bitops.h> +#include <asm/bootinfo.h> +#include <asm/btext.h> +#include <asm/pci-bridge.h> +#include <asm/open_pic.h> + +#ifdef CONFIG_FB +#include <asm/linux_logo.h> +#endif + +/* + * Properties whose value is longer than this get excluded from our + * copy of the device tree. This way we don't waste space storing + * things like "driver,AAPL,MacOS,PowerPC" properties. But this value + * does need to be big enough to ensure that we don't lose things + * like the interrupt-map property on a PCI-PCI bridge. + */ +#define MAX_PROPERTY_LENGTH 4096 + +#ifndef FB_MAX /* avoid pulling in all of the fb stuff */ +#define FB_MAX 8 +#endif + +#define ALIGN(x) (((x) + sizeof(unsigned long)-1) & -sizeof(unsigned long)) + +struct prom_args { + const char *service; + int nargs; + int nret; + void *args[10]; +}; + +struct pci_address { + unsigned a_hi; + unsigned a_mid; + unsigned a_lo; +}; + +struct pci_reg_property { + struct pci_address addr; + unsigned size_hi; + unsigned size_lo; +}; + +struct pci_range { + struct pci_address addr; + unsigned phys; + unsigned size_hi; + unsigned size_lo; +}; + +struct isa_reg_property { + unsigned space; + unsigned address; + unsigned size; +}; + +struct pci_intr_map { + struct pci_address addr; + unsigned dunno; + phandle int_ctrler; + unsigned intr; +}; + +static void prom_exit(void); +static void *call_prom(const char *service, int nargs, int nret, ...); +static void *call_prom_ret(const char *service, int nargs, int nret, + void **rets, ...); +static void prom_print_hex(unsigned int v); +static int prom_set_color(ihandle ih, int i, int r, int g, int b); +static int prom_next_node(phandle *nodep); +static unsigned long check_display(unsigned long mem); +static void setup_disp_fake_bi(ihandle dp); +static unsigned long copy_device_tree(unsigned long mem_start, + unsigned long mem_end); +static unsigned long inspect_node(phandle node, struct device_node *dad, + unsigned long mem_start, unsigned long mem_end, + struct device_node ***allnextpp); +static void prom_hold_cpus(unsigned long mem); +static void prom_instantiate_rtas(void); +static void * early_get_property(unsigned long base, unsigned long node, + char *prop); + +prom_entry prom __initdata = 0; +ihandle prom_chosen __initdata = 0; +ihandle prom_stdout __initdata = 0; + +char *prom_display_paths[FB_MAX] __initdata = { 0, }; +phandle prom_display_nodes[FB_MAX] __initdata; +unsigned int prom_num_displays __initdata = 0; +static char *of_stdout_device __initdata = 0; +static ihandle prom_disp_node __initdata = 0; + +unsigned int rtas_data; /* physical pointer */ +unsigned int rtas_entry; /* physical pointer */ +unsigned int rtas_size; +unsigned int old_rtas; + +boot_infos_t *boot_infos; +char *bootpath; +char *bootdevice; +struct device_node *allnodes; + +extern char *klimit; +extern char _stext; + +static void __init +prom_exit(void) +{ + struct prom_args args; + + args.service = "exit"; + args.nargs = 0; + args.nret = 0; + prom(&args); + for (;;) /* should never get here */ + ; +} + +static void * __init +call_prom(const char *service, int nargs, int nret, ...) +{ + va_list list; + int i; + struct prom_args prom_args; + + prom_args.service = service; + prom_args.nargs = nargs; + prom_args.nret = nret; + va_start(list, nret); + for (i = 0; i < nargs; ++i) + prom_args.args[i] = va_arg(list, void *); + va_end(list); + for (i = 0; i < nret; ++i) + prom_args.args[i + nargs] = 0; + prom(&prom_args); + return prom_args.args[nargs]; +} + +static void * __init +call_prom_ret(const char *service, int nargs, int nret, void **rets, ...) +{ + va_list list; + int i; + struct prom_args prom_args; + + prom_args.service = service; + prom_args.nargs = nargs; + prom_args.nret = nret; + va_start(list, rets); + for (i = 0; i < nargs; ++i) + prom_args.args[i] = va_arg(list, void *); + va_end(list); + for (i = 0; i < nret; ++i) + prom_args.args[i + nargs] = 0; + prom(&prom_args); + for (i = 1; i < nret; ++i) + rets[i-1] = prom_args.args[nargs + i]; + return prom_args.args[nargs]; +} + +void __init +prom_print(const char *msg) +{ + const char *p, *q; + + if (prom_stdout == 0) + return; + + for (p = msg; *p != 0; p = q) { + for (q = p; *q != 0 && *q != '\n'; ++q) + ; + if (q > p) + call_prom("write", 3, 1, prom_stdout, p, q - p); + if (*q != 0) { + ++q; + call_prom("write", 3, 1, prom_stdout, "\r\n", 2); + } + } +} + +static void __init +prom_print_hex(unsigned int v) +{ + char buf[16]; + int i, c; + + for (i = 0; i < 8; ++i) { + c = (v >> ((7-i)*4)) & 0xf; + c += (c >= 10)? ('a' - 10): '0'; + buf[i] = c; + } + buf[i] = ' '; + buf[i+1] = 0; + prom_print(buf); +} + +static int __init +prom_set_color(ihandle ih, int i, int r, int g, int b) +{ + struct prom_args prom_args; + + prom_args.service = "call-method"; + prom_args.nargs = 6; + prom_args.nret = 1; + prom_args.args[0] = "color!"; + prom_args.args[1] = ih; + prom_args.args[2] = (void *) i; + prom_args.args[3] = (void *) b; + prom_args.args[4] = (void *) g; + prom_args.args[5] = (void *) r; + prom(&prom_args); + return (int) prom_args.args[6]; +} + +static int __init +prom_next_node(phandle *nodep) +{ + phandle node; + + if ((node = *nodep) != 0 + && (*nodep = call_prom("child", 1, 1, node)) != 0) + return 1; + if ((*nodep = call_prom("peer", 1, 1, node)) != 0) + return 1; + for (;;) { + if ((node = call_prom("parent", 1, 1, node)) == 0) + return 0; + if ((*nodep = call_prom("peer", 1, 1, node)) != 0) + return 1; + } +} + +/* + * If we have a display that we don't know how to drive, + * we will want to try to execute OF's open method for it + * later. However, OF will probably fall over if we do that + * we've taken over the MMU. + * So we check whether we will need to open the display, + * and if so, open it now. + */ +static unsigned long __init +check_display(unsigned long mem) +{ + phandle node; + ihandle ih; + int i; + char type[16], *path; + static unsigned char default_colors[] = { + 0x00, 0x00, 0x00, + 0x00, 0x00, 0xaa, + 0x00, 0xaa, 0x00, + 0x00, 0xaa, 0xaa, + 0xaa, 0x00, 0x00, + 0xaa, 0x00, 0xaa, + 0xaa, 0xaa, 0x00, + 0xaa, 0xaa, 0xaa, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0xff, + 0x55, 0xff, 0x55, + 0x55, 0xff, 0xff, + 0xff, 0x55, 0x55, + 0xff, 0x55, 0xff, + 0xff, 0xff, 0x55, + 0xff, 0xff, 0xff + }; + + prom_disp_node = 0; + + for (node = 0; prom_next_node(&node); ) { + type[0] = 0; + call_prom("getprop", 4, 1, node, "device_type", + type, sizeof(type)); + if (strcmp(type, "display") != 0) + continue; + /* It seems OF doesn't null-terminate the path :-( */ + path = (char *) mem; + memset(path, 0, 256); + if ((int) call_prom("package-to-path", 3, 1, + node, path, 255) < 0) + continue; + + /* + * If this display is the device that OF is using for stdout, + * move it to the front of the list. + */ + mem += strlen(path) + 1; + i = prom_num_displays++; + if (of_stdout_device != 0 && i > 0 + && strcmp(of_stdout_device, path) == 0) { + for (; i > 0; --i) { + prom_display_paths[i] + = prom_display_paths[i-1]; + prom_display_nodes[i] + = prom_display_nodes[i-1]; + } + } + prom_display_paths[i] = path; + prom_display_nodes[i] = node; + if (i == 0) + prom_disp_node = node; + if (prom_num_displays >= FB_MAX) + break; + } + +try_again: + /* + * Open the first display and set its colormap. + */ + if (prom_num_displays > 0) { + path = prom_display_paths[0]; + prom_print("opening display "); + prom_print(path); + ih = call_prom("open", 1, 1, path); + if (ih == 0 || ih == (ihandle) -1) { + prom_print("... failed\n"); + for (i=1; i<prom_num_displays; i++) { + prom_display_paths[i-1] = prom_display_paths[i]; + prom_display_nodes[i-1] = prom_display_nodes[i]; + } + if (--prom_num_displays > 0) + prom_disp_node = prom_display_nodes[0]; + else + prom_disp_node = NULL; + goto try_again; + } else { + prom_print("... ok\n"); + /* + * Setup a usable color table when the appropriate + * method is available. + * Should update this to use set-colors. + */ + for (i = 0; i < 32; i++) + if (prom_set_color(ih, i, default_colors[i*3], + default_colors[i*3+1], + default_colors[i*3+2]) != 0) + break; + +#ifdef CONFIG_FB + for (i = 0; i < LINUX_LOGO_COLORS; i++) + if (prom_set_color(ih, i + 32, + linux_logo_red[i], + linux_logo_green[i], + linux_logo_blue[i]) != 0) + break; +#endif /* CONFIG_FB */ + } + } + + return ALIGN(mem); +} + +/* This function will enable the early boot text when doing OF booting. This + * way, xmon output should work too + */ +static void __init +setup_disp_fake_bi(ihandle dp) +{ +#ifdef CONFIG_BOOTX_TEXT + int width = 640, height = 480, depth = 8, pitch; + unsigned address; + struct pci_reg_property addrs[8]; + int i, naddrs; + char name[32]; + char *getprop = "getprop"; + + prom_print("Initializing fake screen: "); + + memset(name, 0, sizeof(name)); + call_prom(getprop, 4, 1, dp, "name", name, sizeof(name)); + name[sizeof(name)-1] = 0; + prom_print(name); + prom_print("\n"); + call_prom(getprop, 4, 1, dp, "width", &width, sizeof(width)); + call_prom(getprop, 4, 1, dp, "height", &height, sizeof(height)); + call_prom(getprop, 4, 1, dp, "depth", &depth, sizeof(depth)); + pitch = width * ((depth + 7) / 8); + call_prom(getprop, 4, 1, dp, "linebytes", + &pitch, sizeof(pitch)); + if (pitch == 1) + pitch = 0x1000; /* for strange IBM display */ + address = 0; + call_prom(getprop, 4, 1, dp, "address", + &address, sizeof(address)); + if (address == 0) { + /* look for an assigned address with a size of >= 1MB */ + naddrs = (int) call_prom(getprop, 4, 1, dp, + "assigned-addresses", + addrs, sizeof(addrs)); + naddrs /= sizeof(struct pci_reg_property); + for (i = 0; i < naddrs; ++i) { + if (addrs[i].size_lo >= (1 << 20)) { + address = addrs[i].addr.a_lo; + /* use the BE aperture if possible */ + if (addrs[i].size_lo >= (16 << 20)) + address += (8 << 20); + break; + } + } + if (address == 0) { + prom_print("Failed to get address\n"); + return; + } + } + /* kludge for valkyrie */ + if (strcmp(name, "valkyrie") == 0) + address += 0x1000; + + btext_setup_display(width, height, depth, pitch, address); + + btext_prepare_BAT(); +#endif /* CONFIG_BOOTX_TEXT */ +} + +/* + * Make a copy of the device tree from the PROM. + */ +static unsigned long __init +copy_device_tree(unsigned long mem_start, unsigned long mem_end) +{ + phandle root; + unsigned long new_start; + struct device_node **allnextp; + + root = call_prom("peer", 1, 1, (phandle)0); + if (root == (phandle)0) { + prom_print("couldn't get device tree root\n"); + prom_exit(); + } + allnextp = &allnodes; + mem_start = ALIGN(mem_start); + new_start = inspect_node(root, 0, mem_start, mem_end, &allnextp); + *allnextp = 0; + return new_start; +} + +static unsigned long __init +inspect_node(phandle node, struct device_node *dad, + unsigned long mem_start, unsigned long mem_end, + struct device_node ***allnextpp) +{ + int l; + phandle child; + struct device_node *np; + struct property *pp, **prev_propp; + char *prev_name, *namep; + unsigned char *valp; + + np = (struct device_node *) mem_start; + mem_start += sizeof(struct device_node); + memset(np, 0, sizeof(*np)); + np->node = node; + **allnextpp = PTRUNRELOC(np); + *allnextpp = &np->allnext; + if (dad != 0) { + np->parent = PTRUNRELOC(dad); + /* we temporarily use the `next' field as `last_child'. */ + if (dad->next == 0) + dad->child = PTRUNRELOC(np); + else + dad->next->sibling = PTRUNRELOC(np); + dad->next = np; + } + + /* get and store all properties */ + prev_propp = &np->properties; + prev_name = ""; + for (;;) { + pp = (struct property *) mem_start; + namep = (char *) (pp + 1); + pp->name = PTRUNRELOC(namep); + if ((int) call_prom("nextprop", 3, 1, node, prev_name, + namep) <= 0) + break; + mem_start = ALIGN((unsigned long)namep + strlen(namep) + 1); + prev_name = namep; + valp = (unsigned char *) mem_start; + pp->value = PTRUNRELOC(valp); + pp->length = (int) + call_prom("getprop", 4, 1, node, namep, + valp, mem_end - mem_start); + if (pp->length < 0) + continue; +#ifdef MAX_PROPERTY_LENGTH + if (pp->length > MAX_PROPERTY_LENGTH) + continue; /* ignore this property */ +#endif + mem_start = ALIGN(mem_start + pp->length); + *prev_propp = PTRUNRELOC(pp); + prev_propp = &pp->next; + } + if (np->node != NULL) { + /* Add a "linux,phandle" property" */ + pp = (struct property *) mem_start; + *prev_propp = PTRUNRELOC(pp); + prev_propp = &pp->next; + namep = (char *) (pp + 1); + pp->name = PTRUNRELOC(namep); + strcpy(namep, "linux,phandle"); + mem_start = ALIGN((unsigned long)namep + strlen(namep) + 1); + pp->value = (unsigned char *) PTRUNRELOC(&np->node); + pp->length = sizeof(np->node); + } + *prev_propp = NULL; + + /* get the node's full name */ + l = (int) call_prom("package-to-path", 3, 1, node, + (char *) mem_start, mem_end - mem_start); + if (l >= 0) { + np->full_name = PTRUNRELOC((char *) mem_start); + *(char *)(mem_start + l) = 0; + mem_start = ALIGN(mem_start + l + 1); + } + + /* do all our children */ + child = call_prom("child", 1, 1, node); + while (child != (void *)0) { + mem_start = inspect_node(child, np, mem_start, mem_end, + allnextpp); + child = call_prom("peer", 1, 1, child); + } + + return mem_start; +} + +unsigned long smp_chrp_cpu_nr __initdata = 0; + +/* + * With CHRP SMP we need to use the OF to start the other + * processors so we can't wait until smp_boot_cpus (the OF is + * trashed by then) so we have to put the processors into + * a holding pattern controlled by the kernel (not OF) before + * we destroy the OF. + * + * This uses a chunk of high memory, puts some holding pattern + * code there and sends the other processors off to there until + * smp_boot_cpus tells them to do something. We do that by using + * physical address 0x0. The holding pattern checks that address + * until its cpu # is there, when it is that cpu jumps to + * __secondary_start(). smp_boot_cpus() takes care of setting those + * values. + * + * We also use physical address 0x4 here to tell when a cpu + * is in its holding pattern code. + * + * -- Cort + * + * Note that we have to do this if we have more than one CPU, + * even if this is a UP kernel. Otherwise when we trash OF + * the other CPUs will start executing some random instructions + * and crash the system. -- paulus + */ +static void __init +prom_hold_cpus(unsigned long mem) +{ + extern void __secondary_hold(void); + unsigned long i; + int cpu; + phandle node; + char type[16], *path; + unsigned int reg; + + /* + * XXX: hack to make sure we're chrp, assume that if we're + * chrp we have a device_type property -- Cort + */ + node = call_prom("finddevice", 1, 1, "/"); + if ((int)call_prom("getprop", 4, 1, node, + "device_type",type, sizeof(type)) <= 0) + return; + + /* copy the holding pattern code to someplace safe (0) */ + /* the holding pattern is now within the first 0x100 + bytes of the kernel image -- paulus */ + memcpy((void *)0, &_stext, 0x100); + flush_icache_range(0, 0x100); + + /* look for cpus */ + *(unsigned long *)(0x0) = 0; + asm volatile("dcbf 0,%0": : "r" (0) : "memory"); + for (node = 0; prom_next_node(&node); ) { + type[0] = 0; + call_prom("getprop", 4, 1, node, "device_type", + type, sizeof(type)); + if (strcmp(type, "cpu") != 0) + continue; + path = (char *) mem; + memset(path, 0, 256); + if ((int) call_prom("package-to-path", 3, 1, + node, path, 255) < 0) + continue; + reg = -1; + call_prom("getprop", 4, 1, node, "reg", ®, sizeof(reg)); + cpu = smp_chrp_cpu_nr++; +#ifdef CONFIG_SMP + smp_hw_index[cpu] = reg; +#endif /* CONFIG_SMP */ + /* XXX: hack - don't start cpu 0, this cpu -- Cort */ + if (cpu == 0) + continue; + prom_print("starting cpu "); + prom_print(path); + *(ulong *)(0x4) = 0; + call_prom("start-cpu", 3, 0, node, + (char *)__secondary_hold - &_stext, cpu); + prom_print("..."); + for ( i = 0 ; (i < 10000) && (*(ulong *)(0x4) == 0); i++ ) + ; + if (*(ulong *)(0x4) == cpu) + prom_print("ok\n"); + else { + prom_print("failed: "); + prom_print_hex(*(ulong *)0x4); + prom_print("\n"); + } + } +} + +static void __init +prom_instantiate_rtas(void) +{ + ihandle prom_rtas; + unsigned int i; + struct prom_args prom_args; + + prom_rtas = call_prom("finddevice", 1, 1, "/rtas"); + if (prom_rtas == (void *) -1) + return; + + rtas_size = 0; + call_prom("getprop", 4, 1, prom_rtas, + "rtas-size", &rtas_size, sizeof(rtas_size)); + prom_print("instantiating rtas"); + if (rtas_size == 0) { + rtas_data = 0; + } else { + /* + * Ask OF for some space for RTAS. + * Actually OF has bugs so we just arbitrarily + * use memory at the 6MB point. + */ + rtas_data = 6 << 20; + prom_print(" at "); + prom_print_hex(rtas_data); + } + + prom_rtas = call_prom("open", 1, 1, "/rtas"); + prom_print("..."); + prom_args.service = "call-method"; + prom_args.nargs = 3; + prom_args.nret = 2; + prom_args.args[0] = "instantiate-rtas"; + prom_args.args[1] = prom_rtas; + prom_args.args[2] = (void *) rtas_data; + prom(&prom_args); + i = 0; + if (prom_args.args[3] == 0) + i = (unsigned int)prom_args.args[4]; + rtas_entry = i; + if ((rtas_entry == -1) || (rtas_entry == 0)) + prom_print(" failed\n"); + else + prom_print(" done\n"); +} + +/* + * We enter here early on, when the Open Firmware prom is still + * handling exceptions and the MMU hash table for us. + */ +unsigned long __init +prom_init(int r3, int r4, prom_entry pp) +{ + unsigned long mem; + ihandle prom_mmu; + unsigned long offset = reloc_offset(); + int i, l; + char *p, *d; + unsigned long phys; + void *result[3]; + + /* Default */ + phys = (unsigned long) &_stext; + + /* First get a handle for the stdout device */ + prom = pp; + prom_chosen = call_prom("finddevice", 1, 1, + "/chosen"); + if (prom_chosen == (void *)-1) + prom_exit(); + if ((int) call_prom("getprop", 4, 1, prom_chosen, + "stdout", &prom_stdout, + sizeof(prom_stdout)) <= 0) + prom_exit(); + + /* Get the full OF pathname of the stdout device */ + mem = (unsigned long) klimit + offset; + p = (char *) mem; + memset(p, 0, 256); + call_prom("instance-to-path", 3, 1, prom_stdout, p, 255); + of_stdout_device = p; + mem += strlen(p) + 1; + + /* Get the boot device and translate it to a full OF pathname. */ + p = (char *) mem; + l = (int) call_prom("getprop", 4, 1, prom_chosen, + "bootpath", p, 1<<20); + if (l > 0) { + p[l] = 0; /* should already be null-terminated */ + bootpath = PTRUNRELOC(p); + mem += l + 1; + d = (char *) mem; + *d = 0; + call_prom("canon", 3, 1, p, d, 1<<20); + bootdevice = PTRUNRELOC(d); + mem = ALIGN(mem + strlen(d) + 1); + } + + prom_instantiate_rtas(); + + mem = check_display(mem); + + prom_print("copying OF device tree..."); + mem = copy_device_tree(mem, mem + (1<<20)); + prom_print("done\n"); + + prom_hold_cpus(mem); + + klimit = (char *) (mem - offset); + + /* If we are already running at 0xc0000000, we assume we were + * loaded by an OF bootloader which did set a BAT for us. + * This breaks OF translate so we force phys to be 0. + */ + if (offset == 0) + phys = 0; + else if ((int) call_prom("getprop", 4, 1, prom_chosen, "mmu", + &prom_mmu, sizeof(prom_mmu)) <= 0) { + prom_print(" no MMU found\n"); + } else if ((int)call_prom_ret("call-method", 4, 4, result, "translate", + prom_mmu, &_stext, 1) != 0) { + prom_print(" (translate failed)\n"); + } else { + /* We assume the phys. address size is 3 cells */ + phys = (unsigned long)result[2]; + } + + if (prom_disp_node != 0) + setup_disp_fake_bi(prom_disp_node); + + /* Use quiesce call to get OF to shut down any devices it's using */ + prom_print("Calling quiesce ...\n"); + call_prom("quiesce", 0, 0); + + /* Relocate various pointers which will be used once the + kernel is running at the address it was linked at. */ + for (i = 0; i < prom_num_displays; ++i) + prom_display_paths[i] = PTRUNRELOC(prom_display_paths[i]); + + prom_print("returning 0x"); + prom_print_hex(phys); + prom_print("from prom_init\n"); + prom_stdout = 0; + + return phys; +} + +/* + * early_get_property is used to access the device tree image prepared + * by BootX very early on, before the pointers in it have been relocated. + */ +static void * __init +early_get_property(unsigned long base, unsigned long node, char *prop) +{ + struct device_node *np = (struct device_node *)(base + node); + struct property *pp; + + for (pp = np->properties; pp != 0; pp = pp->next) { + pp = (struct property *) (base + (unsigned long)pp); + if (strcmp((char *)((unsigned long)pp->name + base), + prop) == 0) { + return (void *)((unsigned long)pp->value + base); + } + } + return 0; +} + +/* Is boot-info compatible ? */ +#define BOOT_INFO_IS_COMPATIBLE(bi) ((bi)->compatible_version <= BOOT_INFO_VERSION) +#define BOOT_INFO_IS_V2_COMPATIBLE(bi) ((bi)->version >= 2) +#define BOOT_INFO_IS_V4_COMPATIBLE(bi) ((bi)->version >= 4) + +void __init +bootx_init(unsigned long r4, unsigned long phys) +{ + boot_infos_t *bi = (boot_infos_t *) r4; + unsigned long space; + unsigned long ptr, x; + char *model; + + boot_infos = PTRUNRELOC(bi); + if (!BOOT_INFO_IS_V2_COMPATIBLE(bi)) + bi->logicalDisplayBase = 0; + +#ifdef CONFIG_BOOTX_TEXT + btext_init(bi); + + /* + * Test if boot-info is compatible. Done only in config + * CONFIG_BOOTX_TEXT since there is nothing much we can do + * with an incompatible version, except display a message + * and eventually hang the processor... + * + * I'll try to keep enough of boot-info compatible in the + * future to always allow display of this message; + */ + if (!BOOT_INFO_IS_COMPATIBLE(bi)) { + btext_drawstring(" !!! WARNING - Incompatible version of BootX !!!\n\n\n"); + btext_flushscreen(); + } +#endif /* CONFIG_BOOTX_TEXT */ + + /* New BootX enters kernel with MMU off, i/os are not allowed + here. This hack will have been done by the boostrap anyway. + */ + if (bi->version < 4) { + /* + * XXX If this is an iMac, turn off the USB controller. + */ + model = (char *) early_get_property + (r4 + bi->deviceTreeOffset, 4, "model"); + if (model + && (strcmp(model, "iMac,1") == 0 + || strcmp(model, "PowerMac1,1") == 0)) { + out_le32((unsigned *)0x80880008, 1); /* XXX */ + } + } + + /* Move klimit to enclose device tree, args, ramdisk, etc... */ + if (bi->version < 5) { + space = bi->deviceTreeOffset + bi->deviceTreeSize; + if (bi->ramDisk) + space = bi->ramDisk + bi->ramDiskSize; + } else + space = bi->totalParamsSize; + klimit = PTRUNRELOC((char *) bi + space); + + /* New BootX will have flushed all TLBs and enters kernel with + MMU switched OFF, so this should not be useful anymore. + */ + if (bi->version < 4) { + /* + * Touch each page to make sure the PTEs for them + * are in the hash table - the aim is to try to avoid + * getting DSI exceptions while copying the kernel image. + */ + for (ptr = ((unsigned long) &_stext) & PAGE_MASK; + ptr < (unsigned long)bi + space; ptr += PAGE_SIZE) + x = *(volatile unsigned long *)ptr; + } + +#ifdef CONFIG_BOOTX_TEXT + /* + * Note that after we call btext_prepare_BAT, we can't do + * prom_draw*, flushscreen or clearscreen until we turn the MMU + * on, since btext_prepare_BAT sets disp_bi.logicalDisplayBase + * to a virtual address. + */ + btext_prepare_BAT(); +#endif +} diff --git a/arch/ppc/kernel/ptrace.c b/arch/ppc/kernel/ptrace.c index 993068c91ce2..f806de5d7184 100644 --- a/arch/ppc/kernel/ptrace.c +++ b/arch/ppc/kernel/ptrace.c @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.ptrace.c 1.8 07/07/01 17:00:08 paulus + * BK Id: %F% %I% %G% %U% %#% */ /* * linux/arch/ppc/kernel/ptrace.c @@ -71,6 +71,64 @@ static inline int put_reg(struct task_struct *task, int regno, return -EIO; } +#ifdef CONFIG_ALTIVEC +/* + * Get contents of AltiVec register state in task TASK + */ +static inline int get_vrregs(unsigned long *data, struct task_struct *task) +{ + int i, j; + + if (!access_ok(VERIFY_WRITE, data, 133 * sizeof(unsigned long))) + return -EFAULT; + + /* copy AltiVec registers VR[0] .. VR[31] */ + for (i = 0; i < 32; i++) + for (j = 0; j < 4; j++, data++) + if (__put_user(task->thread.vr[i].u[j], data)) + return -EFAULT; + + /* copy VSCR */ + for (i = 0; i < 4; i++, data++) + if (__put_user(task->thread.vscr.u[i], data)) + return -EFAULT; + + /* copy VRSAVE */ + if (__put_user(task->thread.vrsave, data)) + return -EFAULT; + + return 0; +} + +/* + * Write contents of AltiVec register state into task TASK. + */ +static inline int set_vrregs(struct task_struct *task, unsigned long *data) +{ + int i, j; + + if (!access_ok(VERIFY_READ, data, 133 * sizeof(unsigned long))) + return -EFAULT; + + /* copy AltiVec registers VR[0] .. VR[31] */ + for (i = 0; i < 32; i++) + for (j = 0; j < 4; j++, data++) + if (__get_user(task->thread.vr[i].u[j], data)) + return -EFAULT; + + /* copy VSCR */ + for (i = 0; i < 4; i++, data++) + if (__get_user(task->thread.vscr.u[i], data)) + return -EFAULT; + + /* copy VRSAVE */ + if (__get_user(task->thread.vrsave, data)) + return -EFAULT; + + return 0; +} +#endif + static inline void set_single_step(struct task_struct *task) { @@ -132,14 +190,9 @@ int sys_ptrace(long request, long pid, long addr, long data) ret = ptrace_attach(child); goto out_tsk; } - ret = -ESRCH; - if (!(child->ptrace & PT_PTRACED)) - goto out_tsk; - if (child->state != TASK_STOPPED) { - if (request != PTRACE_KILL) - goto out_tsk; - } - if (child->p_pptr != current) + + ret = ptrace_check_attach(child, request == PTRACE_KILL); + if (ret < 0) goto out_tsk; switch (request) { @@ -219,10 +272,17 @@ int sys_ptrace(long request, long pid, long addr, long data) ret = -EIO; if ((unsigned long) data > _NSIG) break; - if (request == PTRACE_SYSCALL) - child->ptrace |= PT_TRACESYS; - else - child->ptrace &= ~PT_TRACESYS; + if (request == PTRACE_SYSCALL) { + if (!(child->ptrace & PT_SYSCALLTRACE)) { + child->ptrace |= PT_SYSCALLTRACE; + child->work.syscall_trace++; + } + } else { + if (child->ptrace & PT_SYSCALLTRACE) { + child->ptrace &= ~PT_SYSCALLTRACE; + child->work.syscall_trace--; + } + } child->exit_code = data; /* make sure the single step bit is not set. */ clear_single_step(child); @@ -251,7 +311,10 @@ int sys_ptrace(long request, long pid, long addr, long data) ret = -EIO; if ((unsigned long) data > _NSIG) break; - child->ptrace &= ~PT_TRACESYS; + if (child->ptrace & PT_SYSCALLTRACE) { + child->ptrace &= ~PT_SYSCALLTRACE; + child->work.syscall_trace--; + } set_single_step(child); child->exit_code = data; /* give it a chance to run. */ @@ -264,6 +327,24 @@ int sys_ptrace(long request, long pid, long addr, long data) ret = ptrace_detach(child, data); break; +#ifdef CONFIG_ALTIVEC + case PTRACE_GETVRREGS: + /* Get the child altivec register state. */ + if (child->thread.regs->msr & MSR_VEC) + giveup_altivec(child); + ret = get_vrregs((unsigned long *)data, child); + break; + + case PTRACE_SETVRREGS: + /* Set the child altivec register state. */ + /* this is to clear the MSR_VEC bit to force a reload + * of register state from memory */ + if (child->thread.regs->msr & MSR_VEC) + giveup_altivec(child); + ret = set_vrregs(child, (unsigned long *)data); + break; +#endif + default: ret = -EIO; break; @@ -275,10 +356,10 @@ out: return ret; } -void syscall_trace(void) +void do_syscall_trace(void) { - if ((current->ptrace & (PT_PTRACED|PT_TRACESYS)) - != (PT_PTRACED|PT_TRACESYS)) + if ((current->ptrace & (PT_PTRACED|PT_SYSCALLTRACE)) + != (PT_PTRACED|PT_SYSCALLTRACE)) return; current->exit_code = SIGTRAP; current->state = TASK_STOPPED; diff --git a/arch/ppc/kernel/qspan_pci.c b/arch/ppc/kernel/qspan_pci.c index f5d19ff85a18..49dc9c04586b 100644 --- a/arch/ppc/kernel/qspan_pci.c +++ b/arch/ppc/kernel/qspan_pci.c @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.qspan_pci.c 1.5 05/17/01 18:14:22 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * QSpan pci routines. @@ -29,8 +29,7 @@ #include <asm/mpc8xx.h> #include <asm/system.h> #include <asm/machdep.h> - -#include "pci.h" +#include <asm/pci-bridge.h> /* diff --git a/arch/ppc/kernel/semaphore.c b/arch/ppc/kernel/semaphore.c index ac7589238ea2..5eb1ccbe4fae 100644 --- a/arch/ppc/kernel/semaphore.c +++ b/arch/ppc/kernel/semaphore.c @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.semaphore.c 1.12 05/17/01 18:14:22 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * PowerPC-specific semaphore code. @@ -39,6 +39,7 @@ static inline int __sem_update_count(struct semaphore *sem, int incr) " srawi %1,%0,31\n" " andc %1,%0,%1\n" " add %1,%1,%4\n" + PPC405_ERR77(0,%3) " stwcx. %1,0,%3\n" " bne 1b" : "=&r" (old_count), "=&r" (tmp), "=m" (sem->count) diff --git a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c index a8765201c99a..da82585918a1 100644 --- a/arch/ppc/kernel/setup.c +++ b/arch/ppc/kernel/setup.c @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.setup.c 1.65 11/18/01 20:57:25 trini + * BK Id: %F% %I% %G% %U% %#% */ /* * Common prep/pmac/chrp boot and setup code. @@ -29,35 +29,32 @@ #include <asm/smp.h> #include <asm/elf.h> #include <asm/cputable.h> -#ifdef CONFIG_8xx -#include <asm/mpc8xx.h> -#include <asm/8xx_immap.h> -#endif -#ifdef CONFIG_8260 -#include <asm/mpc8260.h> -#include <asm/immap_8260.h> -#endif -#ifdef CONFIG_4xx -#include <asm/ppc4xx.h> -#endif #include <asm/bootx.h> #include <asm/btext.h> #include <asm/machdep.h> -#include <asm/feature.h> #include <asm/uaccess.h> #include <asm/system.h> +#include <asm/pmac_feature.h> + +#if defined CONFIG_KGDB +#include <asm/kgdb.h> +#endif extern void platform_init(unsigned long r3, unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7); extern void bootx_init(unsigned long r4, unsigned long phys); -extern unsigned long reloc_offset(void); extern void identify_cpu(unsigned long offset, unsigned long cpu); extern void do_cpu_ftr_fixups(unsigned long offset); +extern void reloc_got2(unsigned long offset); #ifdef CONFIG_XMON extern void xmon_map_scc(void); #endif +#ifdef CONFIG_KGDB +extern void kgdb_map_scc(void); +#endif + extern boot_infos_t *boot_infos; char saved_command_line[256]; unsigned char aux_device_present; @@ -69,8 +66,6 @@ unsigned long sysmap_size; size value reported by the boot loader. */ unsigned int boot_mem_size; -int parse_bootinfo(void); - unsigned long ISA_DMA_THRESHOLD; unsigned long DMA_MODE_READ, DMA_MODE_WRITE; @@ -103,7 +98,8 @@ int dcache_bsize; int icache_bsize; int ucache_bsize; -#ifdef CONFIG_VGA_CONSOLE +#if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_FB_VGA16) || \ + defined(CONFIG_FB_VGA16_MODULE) || defined(CONFIG_FB_VESA) struct screen_info screen_info = { 0, 25, /* orig-x, orig-y */ 0, /* unused */ @@ -115,7 +111,7 @@ struct screen_info screen_info = { 1, /* orig-video-isVGA */ 16 /* orig-video-points */ }; -#endif /* CONFIG_VGA_CONSOLE */ +#endif /* CONFIG_VGA_CONSOLE || CONFIG_FB_VGA16 || CONFIG_FB_VESA */ void machine_restart(char *cmd) { @@ -291,22 +287,22 @@ early_init(int r3, int r4, int r5) do_cpu_ftr_fixups(offset); #if defined(CONFIG_ALL_PPC) + reloc_got2(offset); + /* If we came here from BootX, clear the screen, * set up some pointers and return. */ - if ((r3 == 0x426f6f58) && (r5 == 0)) { + if ((r3 == 0x426f6f58) && (r5 == 0)) bootx_init(r4, phys); - return phys; - } - - /* check if we're prep, return if we are */ - if ( *(unsigned long *)(0) == 0xdeadc0de ) - return phys; - /* + /* + * don't do anything on prep * for now, don't use bootinfo because it breaks yaboot 0.5 * and assume that if we didn't find a magic number, we have OF */ - phys = prom_init(r3, r4, (prom_entry)r5); + else if (*(unsigned long *)(0) != 0xdeadc0de) + phys = prom_init(r3, r4, (prom_entry)r5); + + reloc_got2(-offset); #endif return phys; @@ -343,14 +339,14 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7) { #ifdef CONFIG_BOOTX_TEXT - extern boot_infos_t *disp_bi; - - if (disp_bi) { + if (boot_text_mapped) { btext_clearscreen(); - btext_welcome(disp_bi); + btext_welcome(); } #endif + parse_bootinfo(find_bootinfo()); + /* if we didn't get any bootinfo telling us what we are... */ if (_machine == 0) { /* prep boot loader tells us if we're prep or not */ @@ -409,15 +405,14 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5, char *p; #ifdef CONFIG_BLK_DEV_INITRD - if (r3 && r4 && r4 != 0xdeadbeef) - { - if (r3 < KERNELBASE) - r3 += KERNELBASE; - initrd_start = r3; - initrd_end = r3 + r4; - ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); - initrd_below_start_ok = 1; - } + if (r3 && r4 && r4 != 0xdeadbeef) { + if (r3 < KERNELBASE) + r3 += KERNELBASE; + initrd_start = r3; + initrd_end = r3 + r4; + ROOT_DEV = mk_kdev(RAMDISK_MAJOR, 0); + initrd_below_start_ok = 1; + } #endif chosen = find_devices("chosen"); if (chosen != NULL) { @@ -429,6 +424,12 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5, } } cmd_line[sizeof(cmd_line) - 1] = 0; +#ifdef CONFIG_ADB + if (strstr(cmd_line, "adb_sync")) { + extern int __adb_probe_sync; + __adb_probe_sync = 1; + } +#endif /* CONFIG_ADB */ switch (_machine) { case _MACH_Pmac: @@ -441,7 +442,7 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5, } #endif /* CONFIG_ALL_PPC */ -int parse_bootinfo(void) +struct bi_record *find_bootinfo(void) { struct bi_record *rec; extern char __bss_start[]; @@ -455,11 +456,16 @@ int parse_bootinfo(void) */ rec = (struct bi_record *)_ALIGN((ulong)__bss_start+0x10000+(1<<20)-1,(1<<20)); if ( rec->tag != BI_FIRST ) - return -1; + return NULL; } - for ( ; rec->tag != BI_LAST ; - rec = (struct bi_record *)((ulong)rec + rec->size) ) - { + return rec; +} + +void parse_bootinfo(struct bi_record *rec) +{ + if (rec == NULL || rec->tag != BI_FIRST) + return; + while (rec->tag != BI_LAST) { ulong *data = rec->data; switch (rec->tag) { case BI_CMD_LINE: @@ -485,9 +491,8 @@ int parse_bootinfo(void) boot_mem_size = data[0]; break; } + rec = (struct bi_record *)((ulong)rec + rec->size); } - - return 0; } /* @@ -504,8 +509,6 @@ machine_init(unsigned long r3, unsigned long r4, unsigned long r5, strcpy(cmd_line, CONFIG_CMDLINE); #endif /* CONFIG_CMDLINE */ - parse_bootinfo(); - platform_init(r3, r4, r5, r6, r7); if (ppc_md.progress) @@ -525,7 +528,7 @@ int __init ppc_setup_l2cr(char *str) } __setup("l2cr=", ppc_setup_l2cr); -void __init ppc_init(void) +int __init ppc_init(void) { /* clear the progress line */ if ( ppc_md.progress ) ppc_md.progress(" ", 0xffff); @@ -533,9 +536,10 @@ void __init ppc_init(void) if (ppc_md.init != NULL) { ppc_md.init(); } + init_crc32(); } -subsys_initcall(ppc_init); +arch_initcall(ppc_init); /* Warning, IO base is not yet inited */ void __init setup_arch(char **cmdline_p) @@ -549,8 +553,13 @@ void __init setup_arch(char **cmdline_p) loops_per_jiffy = 500000000 / HZ; #ifdef CONFIG_ALL_PPC - feature_init(); -#endif + /* This could be called "early setup arch", it must be done + * now because xmon need it + */ + if (_machine == _MACH_Pmac) + pmac_feature_init(); /* New cool way */ +#endif /* CONFIG_ALL_PPC */ + #ifdef CONFIG_XMON xmon_map_scc(); if (strstr(cmd_line, "xmon")) @@ -561,7 +570,12 @@ void __init setup_arch(char **cmdline_p) #if defined(CONFIG_KGDB) kgdb_map_scc(); set_debug_traps(); - breakpoint(); + if (strstr(cmd_line, "nokgdb")) + printk("kgdb default breakpoint deactivated on command line\n"); + else { + printk("kgdb default breakpoint activated\n"); + breakpoint(); + } #endif /* @@ -596,24 +610,6 @@ void __init setup_arch(char **cmdline_p) ppc_md.setup_arch(); if ( ppc_md.progress ) ppc_md.progress("arch: exit", 0x3eab); -#if defined(CONFIG_PCI) && defined(CONFIG_ALL_PPC) - /* We create the "pci-OF-bus-map" property now so it appear in the - * /proc device tree - */ - if (have_of) { - struct property* of_prop; - - of_prop = (struct property*)alloc_bootmem(sizeof(struct property) + 256); - if (of_prop && find_path_device("/")) { - memset(of_prop, -1, sizeof(struct property) + 256); - of_prop->name = "pci-OF-bus-map"; - of_prop->length = 256; - of_prop->value = (unsigned char *)&of_prop[1]; - prom_add_property(find_path_device("/"), of_prop); - } - } -#endif /* CONFIG_PCI && CONFIG_ALL_PPC */ - paging_init(); sort_exception_table(); @@ -621,6 +617,7 @@ void __init setup_arch(char **cmdline_p) ppc_md.ppc_machine = _machine; } +#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) /* Convert the shorts/longs in hd_driveid from little to big endian; * chars are endian independant, of course, but strings need to be flipped. * (Despite what it says in drivers/block/ide.h, they come up as little @@ -715,3 +712,4 @@ void ppc_generic_ide_fix_driveid(struct hd_driveid *id) id->words206_254[i] = __le16_to_cpu(id->words206_254[i]); id->integrity_word = __le16_to_cpu(id->integrity_word); } +#endif diff --git a/arch/ppc/kernel/signal.c b/arch/ppc/kernel/signal.c index 58ad86fa0c53..394d8abb05dc 100644 --- a/arch/ppc/kernel/signal.c +++ b/arch/ppc/kernel/signal.c @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.signal.c 1.7 05/17/01 18:14:22 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * linux/arch/ppc/kernel/signal.c @@ -29,6 +29,7 @@ #include <linux/unistd.h> #include <linux/stddef.h> #include <linux/elf.h> +#include <linux/tty.h> #include <asm/ucontext.h> #include <asm/uaccess.h> #include <asm/pgtable.h> @@ -180,7 +181,7 @@ sys_sigaction(int sig, const struct old_sigaction *act, siginitset(&new_ka.sa.sa_mask, mask); } - ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); + ret = do_sigaction(sig, (act? &new_ka: NULL), (oact? &old_ka: NULL)); if (!ret && oact) { if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) || @@ -254,6 +255,8 @@ int sys_rt_sigreturn(struct pt_regs *regs) current->blocked = set; recalc_sigpending(current); spin_unlock_irq(¤t->sigmask_lock); + if (regs->msr & MSR_FP) + giveup_fpu(current); rt_sf++; /* Look at next rt_sigframe */ if (rt_sf == (struct rt_sigframe *)(sigctx.regs)) { @@ -263,8 +266,6 @@ int sys_rt_sigreturn(struct pt_regs *regs) * see handle_signal() */ sr = (struct sigregs *) sigctx.regs; - if (regs->msr & MSR_FP ) - giveup_fpu(current); if (copy_from_user(saved_regs, &sr->gp_regs, sizeof(sr->gp_regs))) goto badframe; @@ -298,6 +299,7 @@ int sys_rt_sigreturn(struct pt_regs *regs) if (get_user(prevsp, &sr->gp_regs[PT_R1]) || put_user(prevsp, (unsigned long *) regs->gpr[1])) goto badframe; + current->thread.fpscr = 0; } return ret; @@ -328,6 +330,7 @@ setup_rt_frame(struct pt_regs *regs, struct sigregs *frame, goto badframe; flush_icache_range((unsigned long) &frame->tramp[0], (unsigned long) &frame->tramp[2]); + current->thread.fpscr = 0; /* turn off all fp exceptions */ /* Retrieve rt_sigframe from stack and set up registers for signal handler @@ -379,13 +382,13 @@ int sys_sigreturn(struct pt_regs *regs) current->blocked = set; recalc_sigpending(current); spin_unlock_irq(¤t->sigmask_lock); + if (regs->msr & MSR_FP ) + giveup_fpu(current); sc++; /* Look at next sigcontext */ if (sc == (struct sigcontext_struct *)(sigctx.regs)) { /* Last stacked signal - restore registers */ sr = (struct sigregs *) sigctx.regs; - if (regs->msr & MSR_FP ) - giveup_fpu(current); if (copy_from_user(saved_regs, &sr->gp_regs, sizeof(sr->gp_regs))) goto badframe; @@ -413,6 +416,7 @@ int sys_sigreturn(struct pt_regs *regs) if (get_user(prevsp, &sr->gp_regs[PT_R1]) || put_user(prevsp, (unsigned long *) regs->gpr[1])) goto badframe; + current->thread.fpscr = 0; } return ret; @@ -431,8 +435,8 @@ setup_frame(struct pt_regs *regs, struct sigregs *frame, if (verify_area(VERIFY_WRITE, frame, sizeof(*frame))) goto badframe; - if (regs->msr & MSR_FP) - giveup_fpu(current); + if (regs->msr & MSR_FP) + giveup_fpu(current); if (__copy_to_user(&frame->gp_regs, regs, GP_REGS_SIZE) || __copy_to_user(&frame->fp_regs, current->thread.fpr, ELF_NFPREG * sizeof(double)) @@ -441,6 +445,7 @@ setup_frame(struct pt_regs *regs, struct sigregs *frame, goto badframe; flush_icache_range((unsigned long) &frame->tramp[0], (unsigned long) &frame->tramp[2]); + current->thread.fpscr = 0; /* turn off all fp exceptions */ newsp -= __SIGNAL_FRAMESIZE; if (put_user(regs->gpr[1], (unsigned long *)newsp) diff --git a/arch/ppc/kernel/smp.c b/arch/ppc/kernel/smp.c index e5e3247924d3..221fee33e251 100644 --- a/arch/ppc/kernel/smp.c +++ b/arch/ppc/kernel/smp.c @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.smp.c 1.34 10/11/01 12:06:01 trini + * BK Id: %F% %I% %G% %U% %#% */ /* * Smp support for ppc. @@ -38,8 +38,6 @@ #include <asm/residual.h> #include <asm/time.h> -#include "open_pic.h" - int smp_threads_ready; volatile int smp_commenced; int smp_num_cpus = 1; @@ -69,6 +67,10 @@ extern int cpu_idle(void *unused); void smp_call_function_interrupt(void); void smp_message_pass(int target, int msg, unsigned long data, int wait); +#ifdef CONFIG_PPC_ISERIES +extern void smp_iSeries_space_timers( unsigned nr ); +#endif + /* Since OpenPIC has only 4 IPIs, we use slightly different message numbers. * * Make sure this matches openpic_request_IPIs in open_pic.c, or what shows up @@ -290,9 +292,7 @@ void __init smp_boot_cpus(void) * cpu 0, the master -- Cort */ cpu_callin_map[0] = 1; - current->processor = 0; - - init_idle(); + current->cpu = 0; for (i = 0; i < NR_CPUS; i++) { prof_counter[i] = 1; @@ -320,37 +320,26 @@ void __init smp_boot_cpus(void) */ if (cpu_nr > max_cpus) cpu_nr = max_cpus; +#ifdef CONFIG_PPC_ISERIES + smp_iSeries_space_timers( cpu_nr ); +#endif for (i = 1; i < cpu_nr; i++) { int c; struct pt_regs regs; /* create a process for the processor */ - /* we don't care about the values in regs since we'll - never reschedule the forked task. */ - /* We DO care about one bit in the pt_regs we - pass to do_fork. That is the MSR_FP bit in - regs.msr. If that bit is on, then do_fork - (via copy_thread) will call giveup_fpu. - giveup_fpu will get a pointer to our (current's) - last register savearea via current->thread.regs - and using that pointer will turn off the MSR_FP, - MSR_FE0 and MSR_FE1 bits. At this point, this - pointer is pointing to some arbitrary point within - our stack. */ - + /* only regs.msr is actually used, and 0 is OK for it */ memset(®s, 0, sizeof(struct pt_regs)); - if (do_fork(CLONE_VM|CLONE_PID, 0, ®s, 0) < 0) panic("failed fork for CPU %d", i); p = init_task.prev_task; if (!p) panic("No idle task for CPU %d", i); - del_from_runqueue(p); + init_idle(p, i); unhash_process(p); - init_tasks[i] = p; - p->processor = i; - p->cpus_runnable = 1 << i; /* we schedule the first task manually */ + p->cpu = i; + p->cpus_allowed = 1 << i; /* we schedule the first task manually */ current_set[i] = p; /* @@ -507,8 +496,6 @@ void __init smp_callin(void) smp_ops->setup_cpu(cpu); - init_idle(); - /* * This cpu is now "online". Only set them online * before they enter the loop below since write access diff --git a/arch/ppc/kernel/softemu8xx.c b/arch/ppc/kernel/softemu8xx.c index f71da553e183..40a17dc20219 100644 --- a/arch/ppc/kernel/softemu8xx.c +++ b/arch/ppc/kernel/softemu8xx.c @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.softemu8xx.c 1.8 05/17/01 18:14:22 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * Software emulation of some PPC instructions for the 8xx core. @@ -35,6 +35,11 @@ #include <asm/io.h> #include <asm/processor.h> +extern void +print_8xx_pte(struct mm_struct *mm, unsigned long addr); +extern int +get_8xx_pte(struct mm_struct *mm, unsigned long addr); + /* Eventually we may need a look-up table, but this works for now. */ #define LFS 48 @@ -117,7 +122,7 @@ Soft_emulate_8xx(struct pt_regs *regs) default: retval = 1; printk("Bad emulation %s/%d\n" - " NIP: %08x instruction: %08x opcode: %x " + " NIP: %08lx instruction: %08x opcode: %x " "A: %x B: %x C: %x code: %x rc: %x\n", current->comm,current->pid, regs->nip, diff --git a/arch/ppc/kernel/time.c b/arch/ppc/kernel/time.c index 381f1833339c..260345226022 100644 --- a/arch/ppc/kernel/time.c +++ b/arch/ppc/kernel/time.c @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.time.c 1.26 10/05/01 08:29:42 trini + * BK Id: %F% %I% %G% %U% %#% */ /* * Common time routines among all ppc machines. @@ -87,6 +87,11 @@ unsigned tb_last_stamp; extern unsigned long wall_jiffies; +#ifdef CONFIG_PPC_ISERIES +extern u64 get_tb64(void); +extern u64 next_jiffy_update_tb[]; +#endif + static long time_offset; spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED; @@ -106,6 +111,8 @@ static inline int tb_delta(unsigned *jiffy_stamp) { return delta; } +#ifndef CONFIG_PPC_ISERIES /* iSeries version is in iSeries_time.c */ + extern unsigned long prof_cpu_mask; extern unsigned int * prof_buffer; extern unsigned long prof_len; @@ -181,7 +188,7 @@ int timer_interrupt(struct pt_regs * regs) * We should have an rtc call that only sets the minutes and * seconds like on Intel to avoid problems with non UTC clocks. */ - if ( (time_status & STA_UNSYNC) == 0 && + if ( ppc_md.set_rtc_time && (time_status & STA_UNSYNC) == 0 && xtime.tv_sec - last_rtc_update >= 659 && abs(xtime.tv_usec - (1000000-1000000/HZ)) < 500000/HZ && jiffies - wall_jiffies == 1) { @@ -211,6 +218,7 @@ int timer_interrupt(struct pt_regs * regs) return 1; /* lets ret_from_int know we can do checks */ } +#endif /* CONFIG_PPC_ISERIES */ /* * This version of gettimeofday has microsecond resolution. @@ -223,7 +231,11 @@ void do_gettimeofday(struct timeval *tv) read_lock_irqsave(&xtime_lock, flags); sec = xtime.tv_sec; usec = xtime.tv_usec; +#ifdef CONFIG_PPC_ISERIES + delta = tb_ticks_per_jiffy - ( next_jiffy_update_tb[0] - get_tb64() ); +#else delta = tb_ticks_since(tb_last_stamp); +#endif #ifdef CONFIG_SMP /* As long as timebases are not in sync, gettimeofday can only * have jiffy resolution on SMP. @@ -354,11 +366,10 @@ void __init time_init(void) } } -#define TICK_SIZE tick -#define FEBRUARY 2 -#define STARTOFTIME 1970 -#define SECDAY 86400L -#define SECYR (SECDAY * 365) +#define FEBRUARY 2 +#define STARTOFTIME 1970 +#define SECDAY 86400L +#define SECYR (SECDAY * 365) #define leapyear(year) ((year) % 4 == 0) #define days_in_year(a) (leapyear(a) ? 366 : 365) #define days_in_month(a) (month_days[(a) - 1]) @@ -367,55 +378,12 @@ static int month_days[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; -/* - * This only works for the Gregorian calendar - i.e. after 1752 (in the UK) - */ -void GregorianDay(struct rtc_time * tm) -{ - int leapsToDate; - int lastYear; - int day; - int MonthOffset[] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 }; - - lastYear=tm->tm_year-1; - - /* - * Number of leap corrections to apply up to end of last year - */ - leapsToDate = lastYear/4 - lastYear/100 + lastYear/400; - - /* - * This year is a leap year if it is divisible by 4 except when it is - * divisible by 100 unless it is divisible by 400 - * - * e.g. 1904 was a leap year, 1900 was not, 1996 is, and 2000 will be - */ - if((tm->tm_year%4==0) && - ((tm->tm_year%100!=0) || (tm->tm_year%400==0)) && - (tm->tm_mon>2)) - { - /* - * We are past Feb. 29 in a leap year - */ - day=1; - } - else - { - day=0; - } - - day += lastYear*365 + leapsToDate + MonthOffset[tm->tm_mon-1] + - tm->tm_mday; - - tm->tm_wday=day%7; -} - void to_tm(int tim, struct rtc_time * tm) { - register int i; - register long hms, day; + register int i; + register long hms, day, gday; - day = tim / SECDAY; + gday = day = tim / SECDAY; hms = tim % SECDAY; /* Hours, minutes, seconds are easy */ @@ -440,9 +408,9 @@ void to_tm(int tim, struct rtc_time * tm) tm->tm_mday = day + 1; /* - * Determine the day of week + * Determine the day of week. Jan. 1, 1970 was a Thursday. */ - GregorianDay(tm); + tm->tm_wday = (gday + 4) % 7; } /* Auxiliary function to compute scaling factors */ diff --git a/arch/ppc/kernel/todc_time.c b/arch/ppc/kernel/todc_time.c new file mode 100644 index 000000000000..9591c7ee0eef --- /dev/null +++ b/arch/ppc/kernel/todc_time.c @@ -0,0 +1,456 @@ +/* + * arch/ppc/kernel/todc_time.c + * + * Time of Day Clock support for the M48T35, M48T37, M48T59, and MC146818 + * Real Time Clocks/Timekeepers. + * + * Author: Mark A. Greer + * mgreer@mvista.com + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include <linux/errno.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/time.h> +#include <linux/timex.h> + +#include <asm/machdep.h> +#include <asm/io.h> +#include <asm/time.h> +#include <asm/todc.h> + +/* + * Depending on the hardware on your board and your board design, the + * RTC/NVRAM may be accessed either directly (like normal memory) or via + * address/data registers. If your board uses the direct method, set + * 'nvram_data' to the base address of your nvram and leave 'nvram_as0' and + * 'nvram_as1' NULL. If your board uses address/data regs to access nvram, + * set 'nvram_as0' to the address of the lower byte, set 'nvram_as1' to the + * address of the upper byte (leave NULL if using mv146818), and set + * 'nvram_data' to the address of the 8-bit data register. + * + * You also need to set 'ppc_md.nvram_read_val' and 'ppc_md.nvram_write_val' to + * the proper routines. There are standard ones defined further down in + * this file that you can use. + * + * There is a built in assumption that the RTC and NVRAM are accessed by the + * same mechanism (i.e., ppc_md.nvram_read_val, etc works for both). + * + * Note: Even though the documentation for the various RTC chips say that it + * take up to a second before it starts updating once the 'R' bit is + * cleared, they always seem to update even though we bang on it many + * times a second. This is true, except for the Dallas Semi 1746/1747 + * (possibly others). Those chips seem to have a real problem whenever + * we set the 'R' bit before reading them, they basically stop counting. + * --MAG + */ + +/* + * 'todc_info' should be initialized in your *_setup.c file to + * point to a fully initialized 'todc_info_t' structure. + * This structure holds all the register offsets for your particular + * TODC/RTC chip. + * TODC_ALLOC()/TODC_INIT() will allocate and initialize this table for you. + */ + +#ifdef RTC_FREQ_SELECT +#undef RTC_FREQ_SELECT +#define RTC_FREQ_SELECT control_b /* Register A */ +#endif + +#ifdef RTC_CONTROL +#undef RTC_CONTROL +#define RTC_CONTROL control_a /* Register B */ +#endif + +#ifdef RTC_INTR_FLAGS +#undef RTC_INTR_FLAGS +#define RTC_INTR_FLAGS watchdog /* Register C */ +#endif + +#ifdef RTC_VALID +#undef RTC_VALID +#define RTC_VALID interrupts /* Register D */ +#endif + +/* Access routines when RTC accessed directly (like normal memory) */ +u_char +todc_direct_read_val(int addr) +{ + return readb(todc_info->nvram_data + addr); +} + +void +todc_direct_write_val(int addr, unsigned char val) +{ + writeb(val, todc_info->nvram_data + addr); + return; +} + +/* Access routines for accessing m48txx type chips via addr/data regs */ +u_char +todc_m48txx_read_val(int addr) +{ + outb(addr, todc_info->nvram_as0); + outb(addr>>todc_info->as0_bits, todc_info->nvram_as1); + return inb(todc_info->nvram_data); +} + +void +todc_m48txx_write_val(int addr, unsigned char val) +{ + outb(addr, todc_info->nvram_as0); + outb(addr>>todc_info->as0_bits, todc_info->nvram_as1); + outb(val, todc_info->nvram_data); + return; +} + +/* Access routines for accessing mc146818 type chips via addr/data regs */ +u_char +todc_mc146818_read_val(int addr) +{ + outb(addr, todc_info->nvram_as0); + return inb(todc_info->nvram_data); +} + +void +todc_mc146818_write_val(int addr, unsigned char val) +{ + outb(addr, todc_info->nvram_as0); + outb(val, todc_info->nvram_data); + return; +} + +/* + * TODC routines + * + * There is some ugly stuff in that there are assumptions for the mc146818. + * + * Assumptions: + * - todc_info->control_a has the offset as mc146818 Register B reg + * - todc_info->control_b has the offset as mc146818 Register A reg + * - m48txx control reg's write enable or 'W' bit is same as + * mc146818 Register B 'SET' bit (i.e., 0x80) + * + * These assumptions were made to make the code simpler. + */ +long __init +todc_time_init(void) +{ + static u_char not_initialized = 1; + + /* Make sure clocks are running */ + if (not_initialized) { + u_char cntl_b; + + cntl_b = ppc_md.nvram_read_val(todc_info->control_b); + + if (todc_info->rtc_type == TODC_TYPE_MC146818) { + if ((cntl_b & 0x70) != 0x20) { + printk(KERN_INFO "TODC %s %s\n", + "real-time-clock was stopped.", + "Now starting..."); + cntl_b &= ~0x70; + cntl_b |= 0x20; + } + + ppc_md.nvram_write_val(todc_info->control_b, cntl_b); + } + else if (todc_info->rtc_type == TODC_TYPE_DS1501) { + u_char month; + + todc_info->enable_read = TODC_DS1501_CNTL_B_TE; + todc_info->enable_write = TODC_DS1501_CNTL_B_TE; + + month = ppc_md.nvram_read_val(todc_info->month); + + if ((month & 0x80) == 0x80) { + printk(KERN_INFO "TODC %s %s\n", + "real-time-clock was stopped.", + "Now starting..."); + month &= ~0x80; + ppc_md.nvram_write_val(todc_info->month, month); + } + + cntl_b &= ~TODC_DS1501_CNTL_B_TE; + ppc_md.nvram_write_val(todc_info->control_b, cntl_b); + } + else { /* must be a m48txx type */ + u_char cntl_a; + + todc_info->enable_read = TODC_MK48TXX_CNTL_A_R; + todc_info->enable_write = TODC_MK48TXX_CNTL_A_W; + + cntl_a = ppc_md.nvram_read_val(todc_info->control_a); + + /* Check & clear STOP bit in control B register */ + if (cntl_b & TODC_MK48TXX_DAY_CB) { + printk(KERN_INFO "TODC %s %s\n", + "real-time-clock was stopped.", + "Now starting..."); + + cntl_a |= todc_info->enable_write; + cntl_b &= ~TODC_MK48TXX_DAY_CB;/* Start Oscil */ + + ppc_md.nvram_write_val(todc_info->control_a, + cntl_a); + ppc_md.nvram_write_val(todc_info->control_b, + cntl_b); + } + + /* Make sure READ & WRITE bits are cleared. */ + cntl_a &= ~(todc_info->enable_write | + todc_info->enable_read); + ppc_md.nvram_write_val(todc_info->control_a, cntl_a); + } + + not_initialized = 0; + } + + + return 0; +} + +/* + * There is some ugly stuff in that there are assumptions that for a mc146818, + * the todc_info->control_a has the offset of the mc146818 Register B reg and + * that the register'ss 'SET' bit is the same as the m48txx's write enable + * bit in the control register of the m48txx (i.e., 0x80). + * + * It was done to make the code look simpler. + */ +ulong +todc_get_rtc_time(void) +{ + uint year, mon, day, hour, min, sec; + uint limit, i; + u_char save_control, uip; + + save_control = ppc_md.nvram_read_val(todc_info->control_a); + + if (todc_info->rtc_type != TODC_TYPE_MC146818) { + limit = 1; + + switch (todc_info->rtc_type) { + case TODC_TYPE_DS1557: + case TODC_TYPE_DS1746: /* XXXX BAD HACK -> FIX */ + case TODC_TYPE_DS1747: + break; + default: + ppc_md.nvram_write_val(todc_info->control_a, + (save_control | todc_info->enable_read)); + } + } + else { + limit = 100000000; + } + + for (i=0; i<limit; i++) { + if (todc_info->rtc_type == TODC_TYPE_MC146818) { + uip = ppc_md.nvram_read_val(todc_info->RTC_FREQ_SELECT); + } + + sec = ppc_md.nvram_read_val(todc_info->seconds) & 0x7f; + min = ppc_md.nvram_read_val(todc_info->minutes) & 0x7f; + hour = ppc_md.nvram_read_val(todc_info->hours) & 0x3f; + day = ppc_md.nvram_read_val(todc_info->day_of_month) & 0x3f; + mon = ppc_md.nvram_read_val(todc_info->month) & 0x1f; + year = ppc_md.nvram_read_val(todc_info->year) & 0xff; + + if (todc_info->rtc_type == TODC_TYPE_MC146818) { + uip |= ppc_md.nvram_read_val( + todc_info->RTC_FREQ_SELECT); + if ((uip & RTC_UIP) == 0) break; + } + } + + if (todc_info->rtc_type != TODC_TYPE_MC146818) { + switch (todc_info->rtc_type) { + case TODC_TYPE_DS1557: + case TODC_TYPE_DS1746: /* XXXX BAD HACK -> FIX */ + case TODC_TYPE_DS1747: + break; + default: + save_control &= ~(todc_info->enable_read); + ppc_md.nvram_write_val(todc_info->control_a, + save_control); + } + } + + if ((todc_info->rtc_type != TODC_TYPE_MC146818) || + ((save_control & RTC_DM_BINARY) == 0) || + RTC_ALWAYS_BCD) { + + BCD_TO_BIN(sec); + BCD_TO_BIN(min); + BCD_TO_BIN(hour); + BCD_TO_BIN(day); + BCD_TO_BIN(mon); + BCD_TO_BIN(year); + } + + year = year + 1900; + if (year < 1970) { + year += 100; + } + + return mktime(year, mon, day, hour, min, sec); +} + +int +todc_set_rtc_time(unsigned long nowtime) +{ + struct rtc_time tm; + u_char save_control, save_freq_select; + + to_tm(nowtime, &tm); + + save_control = ppc_md.nvram_read_val(todc_info->control_a); + + /* Assuming MK48T59_RTC_CA_WRITE & RTC_SET are equal */ + ppc_md.nvram_write_val(todc_info->control_a, + (save_control | todc_info->enable_write)); + save_control &= ~(todc_info->enable_write); /* in case it was set */ + + if (todc_info->rtc_type == TODC_TYPE_MC146818) { + save_freq_select = + ppc_md.nvram_read_val(todc_info->RTC_FREQ_SELECT); + ppc_md.nvram_write_val(todc_info->RTC_FREQ_SELECT, + save_freq_select | RTC_DIV_RESET2); + } + + + tm.tm_year = (tm.tm_year - 1900) % 100; + + if ((todc_info->rtc_type != TODC_TYPE_MC146818) || + ((save_control & RTC_DM_BINARY) == 0) || + RTC_ALWAYS_BCD) { + + BIN_TO_BCD(tm.tm_sec); + BIN_TO_BCD(tm.tm_min); + BIN_TO_BCD(tm.tm_hour); + BIN_TO_BCD(tm.tm_mon); + BIN_TO_BCD(tm.tm_mday); + BIN_TO_BCD(tm.tm_year); + } + + ppc_md.nvram_write_val(todc_info->seconds, tm.tm_sec); + ppc_md.nvram_write_val(todc_info->minutes, tm.tm_min); + ppc_md.nvram_write_val(todc_info->hours, tm.tm_hour); + ppc_md.nvram_write_val(todc_info->month, tm.tm_mon); + ppc_md.nvram_write_val(todc_info->day_of_month, tm.tm_mday); + ppc_md.nvram_write_val(todc_info->year, tm.tm_year); + + ppc_md.nvram_write_val(todc_info->control_a, save_control); + + if (todc_info->rtc_type == TODC_TYPE_MC146818) { + ppc_md.nvram_write_val(todc_info->RTC_FREQ_SELECT, + save_freq_select); + } + + return 0; +} + +/* + * Manipulates read bit to reliably read seconds at a high rate. + */ +static unsigned char __init todc_read_timereg(int addr) +{ + unsigned char save_control, val; + + switch (todc_info->rtc_type) { + case TODC_TYPE_DS1557: + case TODC_TYPE_DS1746: /* XXXX BAD HACK -> FIX */ + case TODC_TYPE_DS1747: + case TODC_TYPE_MC146818: + break; + default: + save_control = + ppc_md.nvram_read_val(todc_info->control_a); + ppc_md.nvram_write_val(todc_info->control_a, + (save_control | todc_info->enable_read)); + } + val = ppc_md.nvram_read_val(addr); + + switch (todc_info->rtc_type) { + case TODC_TYPE_DS1557: + case TODC_TYPE_DS1746: /* XXXX BAD HACK -> FIX */ + case TODC_TYPE_DS1747: + case TODC_TYPE_MC146818: + break; + default: + save_control &= ~(todc_info->enable_read); + ppc_md.nvram_write_val(todc_info->control_a, + save_control); + } + + return val; +} + +/* + * This was taken from prep_setup.c + * Use the NVRAM RTC to time a second to calibrate the decrementer. + */ +void __init +todc_calibrate_decr(void) +{ + ulong freq; + ulong tbl, tbu; + long i, loop_count; + u_char sec; + + todc_time_init(); + + /* + * Actually this is bad for precision, we should have a loop in + * which we only read the seconds counter. nvram_read_val writes + * the address bytes on every call and this takes a lot of time. + * Perhaps an nvram_wait_change method returning a time + * stamp with a loop count as parameter would be the solution. + */ + /* + * Need to make sure the tbl doesn't roll over so if tbu increments + * during this test, we need to do it again. + */ + loop_count = 0; + + sec = todc_read_timereg(todc_info->seconds) & 0x7f; + + do { + tbu = get_tbu(); + + for (i = 0 ; i < 10000000 ; i++) {/* may take up to 1 second */ + tbl = get_tbl(); + + if ((todc_read_timereg(todc_info->seconds) & 0x7f) != sec) { + break; + } + } + + sec = todc_read_timereg(todc_info->seconds) & 0x7f; + + for (i = 0 ; i < 10000000 ; i++) { /* Should take 1 second */ + freq = get_tbl(); + + if ((todc_read_timereg(todc_info->seconds) & 0x7f) != sec) { + break; + } + } + + freq -= tbl; + } while ((get_tbu() != tbu) && (++loop_count < 2)); + + printk("time_init: decrementer frequency = %lu.%.6lu MHz\n", + freq/1000000, freq%1000000); + + tb_ticks_per_jiffy = freq / HZ; + tb_to_us = mulhwu_scale_factor(freq, 1000000); + + return; +} diff --git a/arch/ppc/kernel/traps.c b/arch/ppc/kernel/traps.c index fdd5289bebbf..c2265a8afcc8 100644 --- a/arch/ppc/kernel/traps.c +++ b/arch/ppc/kernel/traps.c @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.traps.c 1.22 10/11/01 10:33:09 paulus + * BK Id: %F% %I% %G% %U% %#% */ /* * linux/arch/ppc/kernel/traps.c @@ -38,6 +38,9 @@ #include <asm/system.h> #include <asm/io.h> #include <asm/processor.h> +#ifdef CONFIG_PMAC_BACKLIGHT +#include <asm/backlight.h> +#endif extern int fix_alignment(struct pt_regs *); extern void bad_page_fault(struct pt_regs *, unsigned long, int sig); @@ -66,6 +69,13 @@ int (*debugger_sstep)(struct pt_regs *regs); int (*debugger_iabr_match)(struct pt_regs *regs); int (*debugger_dabr_match)(struct pt_regs *regs); void (*debugger_fault_handler)(struct pt_regs *regs); +#else +#define debugger(regs) do { } while (0) +#define debugger_bpt(regs) 0 +#define debugger_sstep(regs) 0 +#define debugger_iabr_match(regs) 0 +#define debugger_dabr_match(regs) 0 +#define debugger_fault_handler ((void (*)(struct pt_regs *))0) #endif #endif @@ -74,15 +84,19 @@ void (*debugger_fault_handler)(struct pt_regs *regs); */ -spinlock_t oops_lock = SPIN_LOCK_UNLOCKED; +spinlock_t die_lock = SPIN_LOCK_UNLOCKED; void die(const char * str, struct pt_regs * fp, long err) { console_verbose(); - spin_lock_irq(&oops_lock); + spin_lock_irq(&die_lock); +#ifdef CONFIG_PMAC_BACKLIGHT + set_backlight_enable(1); + set_backlight_level(BACKLIGHT_MAX); +#endif printk("Oops: %s, sig: %ld\n", str, err); show_regs(fp); - spin_unlock_irq(&oops_lock); + spin_unlock_irq(&die_lock); /* do_exit() should take care of panic'ing from an interrupt * context so we don't handle it here */ @@ -94,9 +108,7 @@ _exception(int signr, struct pt_regs *regs) { if (!user_mode(regs)) { -#if defined(CONFIG_XMON) || defined(CONFIG_KGDB) debugger(regs); -#endif die("Exception in kernel mode", regs, signr); } force_sig(signr, current); @@ -111,7 +123,7 @@ MachineCheckException(struct pt_regs *regs) unsigned long msr = regs->msr; if (user_mode(regs)) { - _exception(SIGSEGV, regs); + _exception(SIGSEGV, regs); return; } @@ -120,12 +132,10 @@ MachineCheckException(struct pt_regs *regs) bad_page_fault(regs, regs->dar, SIGBUS); return; #endif -#if defined(CONFIG_XMON) || defined(CONFIG_KGDB) if (debugger_fault_handler) { debugger_fault_handler(regs); return; } -#endif #ifdef CONFIG_ALL_PPC /* @@ -135,7 +145,7 @@ MachineCheckException(struct pt_regs *regs) * table. * Note that the 601 only takes a machine check on TEA * (transfer error ack) signal assertion, and does not - * set of the top 16 bits of SRR1. + * set any of the top 16 bits of SRR1. * -- paulus. */ if (((msr & 0xffff0000) == 0 || (msr & (0x80000 | 0x40000))) @@ -169,12 +179,13 @@ MachineCheckException(struct pt_regs *regs) #endif /* CONFIG_ALL_PPC */ printk("Machine check in kernel mode.\n"); printk("Caused by (from SRR1=%lx): ", msr); - switch (msr & 0xF0000) { + switch (msr & 0x601F0000) { case 0x80000: printk("Machine check signal\n"); break; case 0: /* for 601 */ case 0x40000: + case 0x140000: /* 7450 MSS error and TEA */ printk("Transfer error ack signal\n"); break; case 0x20000: @@ -183,26 +194,30 @@ MachineCheckException(struct pt_regs *regs) case 0x10000: printk("Address parity error signal\n"); break; + case 0x20000000: + printk("L1 Data Cache error\n"); + break; + case 0x40000000: + printk("L1 Instruction Cache error\n"); + break; + case 0x00100000: + printk("L2 data cache parity error\n"); + break; default: printk("Unknown values in msr\n"); } -#if defined(CONFIG_XMON) || defined(CONFIG_KGDB) debugger(regs); -#endif die("machine check", regs, SIGBUS); } void SMIException(struct pt_regs *regs) { -#if defined(CONFIG_XMON) || defined(CONFIG_KGDB) - { - debugger(regs); - return; - } -#endif + debugger(regs); +#if !(defined(CONFIG_XMON) || defined(CONFIG_KGDB)) show_regs(regs); panic("System Management Interrupt"); +#endif } void @@ -210,23 +225,21 @@ UnknownException(struct pt_regs *regs) { printk("Bad trap at PC: %lx, SR: %lx, vector=%lx %s\n", regs->nip, regs->msr, regs->trap, print_tainted()); - _exception(SIGTRAP, regs); + _exception(SIGTRAP, regs); } void InstructionBreakpoint(struct pt_regs *regs) { -#if defined(CONFIG_XMON) || defined(CONFIG_KGDB) if (debugger_iabr_match(regs)) return; -#endif _exception(SIGTRAP, regs); } void RunModeException(struct pt_regs *regs) { - _exception(SIGTRAP, regs); + _exception(SIGTRAP, regs); } /* Illegal instruction emulation support. Originally written to @@ -272,51 +285,54 @@ emulate_instruction(struct pt_regs *regs) void ProgramCheckException(struct pt_regs *regs) { + int errcode; + #if defined(CONFIG_4xx) unsigned int esr = mfspr(SPRN_ESR); + int isbpt = esr & ESR_PTR; + extern int do_mathemu(struct pt_regs *regs); + + if (isbpt) + mtspr(SPRN_DBSR, DBSR_TIE); +#ifdef CONFIG_MATH_EMULATION + if (!isbpt && do_mathemu(regs) == 0) + return; +#endif /* CONFIG_MATH_EMULATION */ + +#else /* ! CONFIG_4xx */ + int isbpt = regs->msr & 0x20000; - if (esr & ESR_PTR) { -#if defined(CONFIG_XMON) || defined(CONFIG_KGDB) - if (debugger_bpt(regs)) - return; -#endif - _exception(SIGTRAP, regs); - } else { - _exception(SIGILL, regs); - } -#else if (regs->msr & 0x100000) { /* IEEE FP exception */ _exception(SIGFPE, regs); - } else if (regs->msr & 0x20000) { + return; + } +#endif /* ! CONFIG_4xx */ + + if (isbpt) { /* trap exception */ -#if defined(CONFIG_XMON) || defined(CONFIG_KGDB) if (debugger_bpt(regs)) return; -#endif _exception(SIGTRAP, regs); - } else { - /* Try to emulate it if we should. */ - int errcode; - if ((errcode = emulate_instruction(regs))) { - if (errcode == -EFAULT) - _exception(SIGBUS, regs); - else - _exception(SIGILL, regs); - } + return; + } + + /* Try to emulate it if we should. */ + if ((errcode = emulate_instruction(regs))) { + if (errcode == -EFAULT) + _exception(SIGBUS, regs); + else + _exception(SIGILL, regs); } -#endif } void SingleStepException(struct pt_regs *regs) { regs->msr &= ~MSR_SE; /* Turn off 'trace' bit */ -#if defined(CONFIG_XMON) || defined(CONFIG_KGDB) if (debugger_sstep(regs)) return; -#endif - _exception(SIGTRAP, regs); + _exception(SIGTRAP, regs); } void @@ -337,7 +353,7 @@ AlignmentException(struct pt_regs *regs) bad_page_fault(regs, regs->dar, SIGSEGV); return; } - _exception(SIGBUS, regs); + _exception(SIGBUS, regs); } void @@ -345,9 +361,7 @@ StackOverflow(struct pt_regs *regs) { printk(KERN_CRIT "Kernel stack overflow in process %p, r1=%lx\n", current, regs->gpr[1]); -#if defined(CONFIG_XMON) || defined(CONFIG_KGDB) debugger(regs); -#endif show_regs(regs); panic("kernel stack overflow"); } @@ -365,20 +379,20 @@ void SoftwareEmulation(struct pt_regs *regs) { extern int do_mathemu(struct pt_regs *); + extern int Soft_emulate_8xx(struct pt_regs *); int errcode; if (!user_mode(regs)) { -#if defined(CONFIG_XMON) || defined(CONFIG_KGDB) debugger(regs); -#endif die("Kernel Mode Software FPU Emulation", regs, SIGFPE); } #ifdef CONFIG_MATH_EMULATION - if ((errcode = do_mathemu(regs))) { + errcode = do_mathemu(regs); #else - if ((errcode = Soft_emulate_8xx(regs))) { + errcode = Soft_emulate_8xx(regs); #endif + if (errcode) { if (errcode > 0) _exception(SIGFPE, regs); else if (errcode == -EFAULT) @@ -387,7 +401,36 @@ SoftwareEmulation(struct pt_regs *regs) _exception(SIGILL, regs); } } -#endif +#endif /* CONFIG_8xx */ + +#if defined(CONFIG_4xx) + +void DebugException(struct pt_regs *regs) +{ + unsigned long debug_status; + + debug_status = mfspr(SPRN_DBSR); + + regs->msr &= ~MSR_DE; /* Turn off 'debug' bit */ + if (debug_status & DBSR_TIE) { /* trap instruction*/ + + mtspr(SPRN_DBSR, DBSR_TIE); + + if (!user_mode(regs) && debugger_bpt(regs)) + return; + _exception(SIGTRAP, regs); + + } else if (debug_status & DBSR_IC) { /* instruction completion */ + + mtspr(SPRN_DBSR, DBSR_IC); + regs->dbcr0 &= ~DBCR0_IC; + + if (!user_mode(regs) && debugger_sstep(regs)) + return; + _exception(SIGTRAP, regs); + } +} +#endif /* CONFIG_4xx */ #if !defined(CONFIG_TAU_INT) void diff --git a/arch/ppc/kernel/walnut_setup.c b/arch/ppc/kernel/walnut_setup.c deleted file mode 100644 index 99bdcf7a38f1..000000000000 --- a/arch/ppc/kernel/walnut_setup.c +++ /dev/null @@ -1,292 +0,0 @@ -/* - * BK Id: SCCS/s.walnut_setup.c 1.10 11/13/01 21:26:07 paulus - */ -/* - * - * Copyright (c) 1999-2000 Grant Erickson <grant@lcse.umn.edu> - * - * Module name: walnut_setup.c - * - * Description: - * Architecture- / platform-specific boot-time initialization code for - * the IBM PowerPC 403GP "Walnut" evaluation board. Adapted from original - * code by Gary Thomas, Cort Dougan <cort@fsmlabs.com>, and Dan Malek - * <dan@net4x.com>. - * - */ - -#include <linux/config.h> -#include <linux/init.h> -#include <linux/smp.h> -#include <linux/threads.h> -#include <linux/interrupt.h> -#include <linux/param.h> -#include <linux/string.h> -#include <linux/blk.h> -#include <linux/seq_file.h> - -#include <asm/processor.h> -#include <asm/board.h> -#include <asm/machdep.h> -#include <asm/page.h> - -#include "local_irq.h" -#include "ppc4xx_pic.h" -#include <asm/time.h> -#include "walnut_setup.h" - - -/* Function Prototypes */ - -extern void abort(void); - -/* Global Variables */ - -unsigned char __res[sizeof(bd_t)]; - - -/* - * void __init walnut_init() - * - * Description: - * This routine... - * - * Input(s): - * r3 - Optional pointer to a board information structure. - * r4 - Optional pointer to the physical starting address of the init RAM - * disk. - * r5 - Optional pointer to the physical ending address of the init RAM - * disk. - * r6 - Optional pointer to the physical starting address of any kernel - * command-line parameters. - * r7 - Optional pointer to the physical ending address of any kernel - * command-line parameters. - * - * Output(s): - * N/A - * - * Returns: - * N/A - * - */ -void __init -walnut_init(unsigned long r3, unsigned long r4, unsigned long r5, - unsigned long r6, unsigned long r7) -{ - /* - * If we were passed in a board information, copy it into the - * residual data area. - */ - if (r3) { - memcpy((void *)__res, (void *)(r3 + KERNELBASE), sizeof(bd_t)); - } - -#if defined(CONFIG_BLK_DEV_INITRD) - /* - * If the init RAM disk has been configured in, and there's a valid - * starting address for it, set it up. - */ - if (r4) { - initrd_start = r4 + KERNELBASE; - initrd_end = r5 + KERNELBASE; - } -#endif /* CONFIG_BLK_DEV_INITRD */ - - /* Copy the kernel command line arguments to a safe place. */ - - if (r6) { - *(char *)(r7 + KERNELBASE) = 0; - strcpy(cmd_line, (char *)(r6 + KERNELBASE)); - } - - /* Initialize machine-dependency vectors */ - - ppc_md.setup_arch = walnut_setup_arch; - ppc_md.show_percpuinfo = walnut_show_percpuinfo; - ppc_md.irq_cannonicalize = NULL; - ppc_md.init_IRQ = walnut_init_IRQ; - ppc_md.get_irq = walnut_get_irq; - ppc_md.init = NULL; - - ppc_md.restart = walnut_restart; - ppc_md.power_off = walnut_power_off; - ppc_md.halt = walnut_halt; - - ppc_md.time_init = walnut_time_init; - ppc_md.set_rtc_time = walnut_set_rtc_time; - ppc_md.get_rtc_time = walnut_get_rtc_time; - ppc_md.calibrate_decr = walnut_calibrate_decr; - - ppc_md.kbd_setkeycode = NULL; - ppc_md.kbd_getkeycode = NULL; - ppc_md.kbd_translate = NULL; - ppc_md.kbd_unexpected_up = NULL; - ppc_md.kbd_leds = NULL; - ppc_md.kbd_init_hw = NULL; - ppc_md.ppc_kbd_sysrq_xlate = NULL; -} - -/* - * Document me. - */ -void __init -walnut_setup_arch(void) -{ - /* XXX - Implement me */ -} - -/* - * int walnut_show_percpuinfo() - * - * Description: - * This routine pretty-prints the platform's internal CPU and bus clock - * frequencies into the buffer for usage in /proc/cpuinfo. - * - * Input(s): - * *buffer - Buffer into which CPU and bus clock frequencies are to be - * printed. - * - * Output(s): - * *buffer - Buffer with the CPU and bus clock frequencies. - * - * Returns: - * The number of bytes copied into 'buffer' if OK, otherwise zero or less - * on error. - */ -int -walnut_show_percpuinfo(struct seq_file *m) -{ - bd_t *bp = (bd_t *)__res; - - seq_printf(m, "clock\t\t: %dMHz\n" - "bus clock\t\t: %dMHz\n", - bp->bi_intfreq / 1000000, - bp->bi_busfreq / 1000000); - - return 0; -} - -/* - * Document me. - */ -void __init -walnut_init_IRQ(void) -{ - int i; - - ppc4xx_pic_init(); - - for (i = 0; i < NR_IRQS; i++) { - irq_desc[i].handler = ppc4xx_pic; - } - - return; -} - -/* - * Document me. - */ -int -walnut_get_irq(struct pt_regs *regs) -{ - return (ppc4xx_pic_get_irq(regs)); -} - -/* - * Document me. - */ -void -walnut_restart(char *cmd) -{ - abort(); -} - -/* - * Document me. - */ -void -walnut_power_off(void) -{ - walnut_restart(NULL); -} - -/* - * Document me. - */ -void -walnut_halt(void) -{ - walnut_restart(NULL); -} - -/* - * Document me. - */ -long __init -walnut_time_init(void) -{ - /* XXX - Implement me */ - return 0; -} - -/* - * Document me. - */ -int __init -walnut_set_rtc_time(unsigned long time) -{ - /* XXX - Implement me */ - - return (0); -} - -/* - * Document me. - */ -unsigned long __init -walnut_get_rtc_time(void) -{ - /* XXX - Implement me */ - - return (0); -} - -/* - * void __init walnut_calibrate_decr() - * - * Description: - * This routine retrieves the internal processor frequency from the board - * information structure, sets up the kernel timer decrementer based on - * that value, enables the 403 programmable interval timer (PIT) and sets - * it up for auto-reload. - * - * Input(s): - * N/A - * - * Output(s): - * N/A - * - * Returns: - * N/A - * - */ -void __init -walnut_calibrate_decr(void) -{ - unsigned int freq; - bd_t *bip = (bd_t *)__res; - - freq = bip->bi_intfreq; - - decrementer_count = freq / HZ; - count_period_num = 1; - count_period_den = freq; - - /* Enable the PIT and set auto-reload of its value */ - - mtspr(SPRN_TCR, TCR_PIE | TCR_ARE); - - /* Clear any pending timer interrupts */ - - mtspr(SPRN_TSR, TSR_ENW | TSR_WIS | TSR_PIS | TSR_FIS); -} diff --git a/arch/ppc/kernel/walnut_setup.h b/arch/ppc/kernel/walnut_setup.h deleted file mode 100644 index 2c142f031ebd..000000000000 --- a/arch/ppc/kernel/walnut_setup.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * BK Id: SCCS/s.walnut_setup.h 1.5 05/17/01 18:14:22 cort - */ -/* - * - * Copyright (c) 1999-2000 Grant Erickson <grant@lcse.umn.edu> - * - * Module name: walnut_setup.c - * - * Description: - * Architecture- / platform-specific boot-time initialization code for - * the IBM PowerPC 405GP "Walnut" evaluation board. Adapted from original - * code by Gary Thomas, Cort Dougan <cort@cs.nmt.edu>, and Dan Malek - * <dan@netx4.com>. - * - */ - -#ifndef __WALNUT_SETUP_H__ -#define __WALNUT_SETUP_H__ - -#include <asm/ptrace.h> -#include <asm/board.h> - - -#ifdef __cplusplus -extern "C" { -#endif - -extern unsigned char __res[sizeof(bd_t)]; - -extern void walnut_init(unsigned long r3, - unsigned long ird_start, - unsigned long ird_end, - unsigned long cline_start, - unsigned long cline_end); -extern void walnut_setup_arch(void); -extern int walnut_setup_residual(char *buffer); -extern void walnut_init_IRQ(void); -extern int walnut_get_irq(struct pt_regs *regs); -extern void walnut_restart(char *cmd); -extern void walnut_power_off(void); -extern void walnut_halt(void); -extern void walnut_time_init(void); -extern int walnut_set_rtc_time(unsigned long now); -extern unsigned long walnut_get_rtc_time(void); -extern void walnut_calibrate_decr(void); - - -#ifdef __cplusplus -} -#endif - -#endif /* __WALNUT_SETUP_H__ */ diff --git a/arch/ppc/kernel/xics.c b/arch/ppc/kernel/xics.c deleted file mode 100644 index 7b3f047cccaf..000000000000 --- a/arch/ppc/kernel/xics.c +++ /dev/null @@ -1,217 +0,0 @@ -/* - * BK Id: SCCS/s.xics.c 1.5 05/17/01 18:14:22 cort - */ -/* - * arch/ppc/kernel/xics.c - * - * Copyright 2000 IBM Corporation. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ -#include <linux/config.h> -#include <linux/types.h> -#include <linux/threads.h> -#include <linux/kernel.h> -#include <linux/sched.h> -#include <asm/prom.h> -#include <asm/io.h> -#include "i8259.h" -#include "xics.h" - -void xics_enable_irq(u_int irq); -void xics_disable_irq(u_int irq); -void xics_mask_and_ack_irq(u_int irq); -void xics_end_irq(u_int irq); - -struct hw_interrupt_type xics_pic = { - " XICS ", - NULL, - NULL, - xics_enable_irq, - xics_disable_irq, - xics_mask_and_ack_irq, - xics_end_irq -}; - -struct hw_interrupt_type xics_8259_pic = { - " XICS/8259", - NULL, - NULL, - NULL, - NULL, - xics_mask_and_ack_irq, - NULL -}; - -#define XICS_IPI 2 -#define XICS_IRQ_8259_CASCADE 0x2c -#define XICS_IRQ_OFFSET 16 -#define XICS_IRQ_SPURIOUS 0 - -#define DEFAULT_SERVER 0 -#define DEFAULT_PRIORITY 0 - -struct xics_ipl { - union { - u32 word; - u8 bytes[4]; - } xirr_poll; - union { - u32 word; - u8 bytes[4]; - } xirr; - u32 dummy; - union { - u32 word; - u8 bytes[4]; - } qirr; -}; - -struct xics_info { - volatile struct xics_ipl * per_cpu[NR_CPUS]; -}; - -struct xics_info xics_info; - -#define xirr_info(n_cpu) (xics_info.per_cpu[n_cpu]->xirr.word) -#define cppr_info(n_cpu) (xics_info.per_cpu[n_cpu]->xirr.bytes[0]) -#define poll_info(n_cpu) (xics_info.per_cpu[n_cpu]->xirr_poll.word) -#define qirr_info(n_cpu) (xics_info.per_cpu[n_cpu]->qirr.bytes[0]) - -void -xics_enable_irq( - u_int irq - ) -{ - int status; - int call_status; - - irq -= XICS_IRQ_OFFSET; - if (irq == XICS_IPI) - return; - call_status = call_rtas("ibm,set-xive", 3, 1, (ulong*)&status, - irq, DEFAULT_SERVER, DEFAULT_PRIORITY); - if( call_status != 0 ) { - printk("xics_enable_irq: irq=%x: call_rtas failed; retn=%x, status=%x\n", - irq, call_status, status); - return; - } -} - -void -xics_disable_irq( - u_int irq - ) -{ - int status; - int call_status; - - irq -= XICS_IRQ_OFFSET; - call_status = call_rtas("ibm,int-off", 1, 1, (ulong*)&status, irq); - if( call_status != 0 ) { - printk("xics_disable_irq: irq=%x: call_rtas failed, retn=%x\n", - irq, call_status); - return; - } -} - -void -xics_end_irq( - u_int irq - ) -{ - int cpu = smp_processor_id(); - - cppr_info(cpu) = 0; /* actually the value overwritten by ack */ - xirr_info(cpu) = (0xff<<24) | (irq-XICS_IRQ_OFFSET); -} - -void -xics_mask_and_ack_irq( - u_int irq - ) -{ - int cpu = smp_processor_id(); - - if( irq < XICS_IRQ_OFFSET ) { - i8259_pic.ack(irq); - xirr_info(cpu) = (0xff<<24) | XICS_IRQ_8259_CASCADE; - } - else { - cppr_info(cpu) = 0xff; - } -} - -int -xics_get_irq(struct pt_regs *regs) -{ - u_int cpu = smp_processor_id(); - u_int vec; - int irq; - - vec = xirr_info(cpu); - /* (vec >> 24) == old priority */ - vec &= 0x00ffffff; - /* for sanity, this had better be < NR_IRQS - 16 */ - if( vec == XICS_IRQ_8259_CASCADE ) - irq = i8259_irq(cpu); - else if( vec == XICS_IRQ_SPURIOUS ) - irq = -1; - else - irq = vec + XICS_IRQ_OFFSET; - return irq; -} - -#ifdef CONFIG_SMP -void xics_ipi_action(int irq, void *dev_id, struct pt_regs *regs) -{ - qirr_info(smp_processor_id()) = 0xff; - smp_message_recv(MSG_RESCHEDULE, regs); -} - -void xics_cause_IPI(int cpu) -{ - qirr_info(cpu) = 0; -} - -void xics_setup_cpu(void) -{ - int cpu = smp_processor_id(); - - cppr_info(cpu) = 0xff; -} -#endif /* CONFIG_SMP */ - -void -xics_init_IRQ( void ) -{ - int i; - extern unsigned long smp_chrp_cpu_nr; - -#ifdef CONFIG_SMP - for (i = 0; i < smp_chrp_cpu_nr; ++i) - xics_info.per_cpu[i] = - ioremap(0xfe000000 + smp_hw_index[i] * 0x1000, 0x20); -#else - xics_info.per_cpu[0] = ioremap(0xfe000000, 0x20); -#endif /* CONFIG_SMP */ - xics_8259_pic.enable = i8259_pic.enable; - xics_8259_pic.disable = i8259_pic.disable; - for (i = 0; i < 16; ++i) - irq_desc[i].handler = &xics_8259_pic; - for (; i < NR_IRQS; ++i) - irq_desc[i].handler = &xics_pic; - - cppr_info(0) = 0xff; - if (request_irq(XICS_IRQ_8259_CASCADE + XICS_IRQ_OFFSET, no_action, - 0, "8259 cascade", 0)) - printk(KERN_ERR "xics_init_IRQ: couldn't get 8259 cascade\n"); - i8259_init(); - -#ifdef CONFIG_SMP - request_irq(XICS_IPI + XICS_IRQ_OFFSET, xics_ipi_action, 0, "IPI", 0); -#endif -} diff --git a/arch/ppc/kernel/xics.h b/arch/ppc/kernel/xics.h deleted file mode 100644 index dd0a591b834f..000000000000 --- a/arch/ppc/kernel/xics.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * BK Id: SCCS/s.xics.h 1.5 05/17/01 18:14:22 cort - */ -/* - * arch/ppc/kernel/xics.h - * - * Copyright 2000 IBM Corporation. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ - -#ifndef _PPC_KERNEL_XICS_H -#define _PPC_KERNEL_XICS_H - -#include "local_irq.h" - -extern struct hw_interrupt_type xics_pic; -extern struct hw_interrupt_type xics_8259_pic; - -void xics_init_IRQ(void); -int xics_get_irq(struct pt_regs *); - -#endif /* _PPC_KERNEL_XICS_H */ diff --git a/arch/ppc/lib/checksum.S b/arch/ppc/lib/checksum.S index 542679a38b67..23e78ed6ca6a 100644 --- a/arch/ppc/lib/checksum.S +++ b/arch/ppc/lib/checksum.S @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.checksum.S 1.8 08/20/01 22:09:34 paulus + * BK Id: %F% %I% %G% %U% %#% */ /* * This file contains assembly-language implementations @@ -18,7 +18,7 @@ #include <linux/sys.h> #include <asm/processor.h> #include <asm/errno.h> -#include "../kernel/ppc_asm.tmpl" +#include <asm/ppc_asm.h> .text diff --git a/arch/ppc/lib/locks.c b/arch/ppc/lib/locks.c index 91766ddf121a..1960cd7c0817 100644 --- a/arch/ppc/lib/locks.c +++ b/arch/ppc/lib/locks.c @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.locks.c 1.11 08/19/01 22:27:32 paulus + * BK Id: %F% %I% %G% %U% %#% */ /* * Locks for smp ppc @@ -35,8 +35,9 @@ static unsigned long __spin_trylock(volatile unsigned long *lock) __asm__ __volatile__ ("\n\ 1: lwarx %0,0,%1\n\ cmpwi 0,%0,0\n\ - bne 2f\n\ - stwcx. %2,0,%1\n\ + bne 2f\n" + PPC405_ERR77(0,%1) +" stwcx. %2,0,%1\n\ bne- 1b\n\ isync\n\ 2:" diff --git a/arch/ppc/lib/string.S b/arch/ppc/lib/string.S index 1b0ae15f1929..efab9d80b436 100644 --- a/arch/ppc/lib/string.S +++ b/arch/ppc/lib/string.S @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.string.S 1.9 10/25/01 10:08:51 trini + * BK Id: %F% %I% %G% %U% %#% */ /* * String handling functions for PowerPC. @@ -11,11 +11,11 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */ -#include "../kernel/ppc_asm.tmpl" #include <linux/config.h> #include <asm/processor.h> #include <asm/cache.h> #include <asm/errno.h> +#include <asm/ppc_asm.h> #define COPY_16_BYTES \ lwz r7,4(r4); \ @@ -65,13 +65,14 @@ .text .text + .stabs "arch/ppc/lib/",N_SO,0,0,0f + .stabs "string.S",N_SO,0,0,0f CACHELINE_BYTES = L1_CACHE_LINE_SIZE LG_CACHELINE_BYTES = LG_L1_CACHE_LINE_SIZE CACHELINE_MASK = (L1_CACHE_LINE_SIZE-1) - .globl strcpy -strcpy: +_GLOBAL(strcpy) addi r5,r3,-1 addi r4,r4,-1 1: lbzu r0,1(r4) @@ -80,8 +81,7 @@ strcpy: bne 1b blr - .globl strncpy -strncpy: +_GLOBAL(strncpy) cmpwi 0,r5,0 beqlr mtctr r5 @@ -93,8 +93,7 @@ strncpy: bdnzf 2,1b /* dec ctr, branch if ctr != 0 && !cr0.eq */ blr - .globl strcat -strcat: +_GLOBAL(strcat) addi r5,r3,-1 addi r4,r4,-1 1: lbzu r0,1(r5) @@ -107,8 +106,7 @@ strcat: bne 1b blr - .globl strcmp -strcmp: +_GLOBAL(strcmp) addi r5,r3,-1 addi r4,r4,-1 1: lbzu r3,1(r5) @@ -119,8 +117,7 @@ strcmp: beq 1b blr - .globl strlen -strlen: +_GLOBAL(strlen) addi r4,r3,-1 1: lbzu r0,1(r4) cmpwi 0,r0,0 @@ -133,8 +130,7 @@ strlen: * to set them to zero. This requires that the destination * area is cacheable. -- paulus */ - .globl cacheable_memzero -cacheable_memzero: +_GLOBAL(cacheable_memzero) mr r5,r4 li r4,0 addi r6,r3,-4 @@ -165,6 +161,12 @@ cacheable_memzero: stw r4, 8(r6) stw r4, 12(r6) stw r4, 16(r6) +#if CACHE_LINE_SIZE >= 32 + stw r4, 20(r6) + stw r4, 24(r6) + stw r4, 28(r6) + stw r4, 32(r6) +#endif /* CACHE_LINE_SIZE */ #endif addi r6,r6,CACHELINE_BYTES bdnz 10b @@ -184,8 +186,7 @@ cacheable_memzero: bdnz 8b blr - .globl memset -memset: +_GLOBAL(memset) rlwimi r4,r4,8,16,23 rlwimi r4,r4,16,0,15 addi r6,r3,-4 @@ -210,8 +211,7 @@ memset: bdnz 8b blr - .globl bcopy -bcopy: +_GLOBAL(bcopy) mr r6,r3 mr r3,r4 mr r4,r6 @@ -224,8 +224,7 @@ bcopy: * We only use this version if the source and dest don't overlap. * -- paulus. */ - .global cacheable_memcpy -cacheable_memcpy: +_GLOBAL(cacheable_memcpy) add r7,r3,r5 /* test if the src & dst overlap */ add r8,r4,r5 cmplw 0,r4,r7 @@ -299,14 +298,12 @@ cacheable_memcpy: bdnz 40b 65: blr - .globl memmove -memmove: +_GLOBAL(memmove) cmplw 0,r3,r4 bgt backwards_memcpy /* fall through */ - .globl memcpy -memcpy: +_GLOBAL(memcpy) srwi. r7,r5,3 addi r6,r3,-4 addi r4,r4,-4 @@ -347,8 +344,7 @@ memcpy: mtctr r7 b 1b - .globl backwards_memcpy -backwards_memcpy: +_GLOBAL(backwards_memcpy) rlwinm. r7,r5,32-3,3,31 /* r0 = r5 >> 3 */ add r6,r3,r5 add r4,r4,r5 @@ -383,9 +379,8 @@ backwards_memcpy: beq 2b mtctr r7 b 1b - - .globl memcmp -memcmp: + +_GLOBAL(memcmp) cmpwi 0,r5,0 ble- 2f mtctr r5 @@ -399,8 +394,7 @@ memcmp: 2: li r3,0 blr - .global memchr -memchr: +_GLOBAL(memchr) cmpwi 0,r5,0 ble- 2f mtctr r5 @@ -412,8 +406,7 @@ memchr: 2: li r3,0 blr - .globl __copy_tofrom_user -__copy_tofrom_user: +_GLOBAL(__copy_tofrom_user) addi r4,r4,-4 addi r6,r3,-4 neg r0,r3 @@ -445,23 +438,23 @@ __copy_tofrom_user: #if !defined(CONFIG_8xx) /* Here we decide how far ahead to prefetch the source */ -#if MAX_L1_COPY_PREFETCH > 1 +#if MAX_COPY_PREFETCH > 1 /* Heuristically, for large transfers we prefetch - MAX_L1_COPY_PREFETCH cachelines ahead. For small transfers + MAX_COPY_PREFETCH cachelines ahead. For small transfers we prefetch 1 cacheline ahead. */ - cmpwi r0,MAX_L1_COPY_PREFETCH + cmpwi r0,MAX_COPY_PREFETCH li r7,1 li r3,4 ble 111f - li r7,MAX_L1_COPY_PREFETCH + li r7,MAX_COPY_PREFETCH 111: mtctr r7 112: dcbt r3,r4 addi r3,r3,CACHELINE_BYTES bdnz 112b -#else /* MAX_L1_COPY_PREFETCH == 1 */ +#else /* MAX_COPY_PREFETCH == 1 */ li r3,CACHELINE_BYTES + 4 dcbt r11,r4 -#endif /* MAX_L1_COPY_PREFETCH */ +#endif /* MAX_COPY_PREFETCH */ #endif /* CONFIG_8xx */ mtctr r0 @@ -606,8 +599,7 @@ __copy_tofrom_user: .long 114b,120b .text - .globl __clear_user -__clear_user: +_GLOBAL(__clear_user) addi r6,r3,-4 li r3,0 li r5,0 @@ -644,8 +636,7 @@ __clear_user: .long 8b,99b .text - .globl __strncpy_from_user -__strncpy_from_user: +_GLOBAL(__strncpy_from_user) addi r6,r3,-1 addi r4,r4,-1 cmpwi 0,r5,0 @@ -668,8 +659,7 @@ __strncpy_from_user: .text /* r3 = str, r4 = len (> 0), r5 = top (highest addr) */ - .globl __strnlen_user -__strnlen_user: +_GLOBAL(__strnlen_user) addi r7,r3,-1 subf r6,r7,r5 /* top+1 - str */ cmplw 0,r4,r6 diff --git a/arch/ppc/mm/4xx_mmu.c b/arch/ppc/mm/4xx_mmu.c index 43484cd7e2fa..bed7823c620e 100644 --- a/arch/ppc/mm/4xx_mmu.c +++ b/arch/ppc/mm/4xx_mmu.c @@ -93,6 +93,6 @@ void __init MMU_init_hw(void) * vectors and the kernel live in real-mode. */ - mtspr(SPRN_DCCR, 0x80000000); /* 128 MB of data space at 0x0. */ - mtspr(SPRN_ICCR, 0x80000000); /* 128 MB of instr. space at 0x0. */ + mtspr(SPRN_DCCR, 0xF0000000); /* 512 MB of data space at 0x0. */ + mtspr(SPRN_ICCR, 0xF0000000); /* 512 MB of instr. space at 0x0. */ } diff --git a/arch/ppc/mm/4xx_tlb.c b/arch/ppc/mm/4xx_tlb.c deleted file mode 100644 index 115184826313..000000000000 --- a/arch/ppc/mm/4xx_tlb.c +++ /dev/null @@ -1,361 +0,0 @@ -/* - * BK Id: SCCS/s.4xx_tlb.c 1.5 05/17/01 18:14:23 cort - */ -/* - * - * Copyright (c) 1998-1999 TiVo, Inc. - * Original implementation. - * Copyright (c) 1999-2000 Grant Erickson <grant@lcse.umn.edu> - * Minor rework. - * - * Module name: 4xx_tlb.c - * - * Description: - * Routines for manipulating the TLB on PowerPC 400-class processors. - * - */ - -#include <linux/mm.h> - -#include <asm/processor.h> -#include <asm/io.h> -#include <asm/mmu.h> -#include <asm/pgtable.h> -#include <asm/system.h> - - -/* Preprocessor Defines */ - -#if !defined(TRUE) || TRUE != 1 -#define TRUE 1 -#endif - -#if !defined(FALSE) || FALSE != 0 -#define FALSE 0 -#endif - - -/* Global Variables */ - -static int pinned = 0; - - -/* Function Prototypes */ - -static int PPC4xx_tlb_miss(struct pt_regs *, unsigned long, int); - -extern void do_page_fault(struct pt_regs *, unsigned long, unsigned long); - - -/* - * () - * - * Description: - * This routine... - * - * Input(s): - * - * - * Output(s): - * - * - * Returns: - * - * - */ -static inline void -PPC4xx_tlb_write(unsigned long tag, unsigned long data, unsigned int index) -{ - asm("tlbwe %0,%1,1" : : "r" (data), "r" (index)); - asm("tlbwe %0,%1,0" : : "r" (tag), "r" (index)); -} - -/* - * () - * - * Description: - * This routine... - * - * Input(s): - * - * - * Output(s): - * - * - * Returns: - * - * - */ -void -PPC4xx_flush_tlb_all(void) -{ - int i; - unsigned long flags, pid; - - save_flags(flags); - cli(); - - pid = mfspr(SPRN_PID); - mtspr(SPRN_PID, 0); - - for (i = pinned; i < PPC4XX_TLB_SIZE; i++) { - PPC4xx_tlb_write(0, 0, i); - } - asm("sync;isync"); - - mtspr(SPRN_PID, pid); - restore_flags(flags); -} - -/* - * () - * - * Description: - * This routine... - * - * Input(s): - * - * - * Output(s): - * - * - * Returns: - * - * - */ -void -PPC4xx_dtlb_miss(struct pt_regs *regs) -{ - unsigned long addr = mfspr(SPRN_DEAR); - int write = mfspr(SPRN_ESR) & ESR_DST; - - if (PPC4xx_tlb_miss(regs, addr, write) < 0) { - sti(); - do_page_fault(regs, addr, write); - cli(); - } - -} - -/* - * () - * - * Description: - * This routine... - * - * Input(s): - * - * - * Output(s): - * - * - * Returns: - * - * - */ -void -PPC4xx_itlb_miss(struct pt_regs *regs) -{ - unsigned long addr = regs->nip; - - if (PPC4xx_tlb_miss(regs, addr, 0) < 0) { - sti(); - do_page_fault(regs, addr, 0); - cli(); - } -} - -/* - * () - * - * Description: - * This routine... - * - * Input(s): - * - * - * Output(s): - * - * - * Returns: - * - * - */ -void -PPC4xx_tlb_pin(unsigned long va, unsigned long pa, int pagesz, int cache) -{ - unsigned long tag, data; - unsigned long opid; - - if (pinned >= PPC4XX_TLB_SIZE) - return; - - opid = mfspr(SPRN_PID); - mtspr(SPRN_PID, 0); - - data = (pa & TLB_RPN_MASK) | TLB_WR; - - if (cache) - data |= (TLB_EX); - else - data |= (TLB_G | TLB_I); - - tag = (va & TLB_EPN_MASK) | TLB_VALID | pagesz; - - PPC4xx_tlb_write(tag, data, pinned++); - - mtspr(SPRN_PID, opid); - return; -} - -/* - * () - * - * Description: - * This routine... - * - * Input(s): - * - * - * Output(s): - * - * - * Returns: - * - * - */ -void -PPC4xx_tlb_unpin(unsigned long va, unsigned long pa, int size) -{ - /* XXX - To be implemented. */ -} - -/* - * () - * - * Description: - * This routine... - * - * Input(s): - * - * - * Output(s): - * - * - * Returns: - * - * - */ -static inline void -PPC4xx_tlb_update(unsigned long addr, pte_t *pte) -{ - unsigned long data, tag, rand; - int i, found = 1; - - /* Construct the hardware TLB entry from the Linux-style PTE */ - - tag = tag = (addr & PAGE_MASK) | TLB_VALID | TLB_PAGESZ(PAGESZ_4K); - data = data = (pte_val(*pte) & PAGE_MASK) | TLB_EX | TLB_WR; - -#if 0 - if (pte_val(*pte) & _PAGE_HWWRITE) - data |= TLB_WR; -#endif - - if (pte_val(*pte) & _PAGE_NO_CACHE) - data |= TLB_I; - - if (pte_val(*pte) & _PAGE_GUARDED) - data |= TLB_G; - - if (addr < KERNELBASE) - data |= TLB_ZSEL(1); - - /* Attempt to match the new tag to an existing entry in the TLB. */ - - asm("tlbsx. %0,0,%2;" - "beq 1f;" - "li %1,0;1:" : "=r" (i), "=r" (found) : "r" (tag)); - - /* - * If we found a match for the tag, reuse the entry index and update - * the tag and data portions. Otherwise, we did not find a match. Use - * the lower 5 bits of the lower time base register as a pseudo-random - * index into the TLB and replace the entry at that index. - */ - - if (found) { - PPC4xx_tlb_write(tag, data, i); - } else { - rand = mfspr(SPRN_TBLO) & (PPC4XX_TLB_SIZE - 1); - rand += pinned; - if (rand >= PPC4XX_TLB_SIZE) - rand -= pinned; - - PPC4xx_tlb_write(tag, data, rand); - asm("isync;sync"); - } -} - -/* - * () - * - * Description: - * This routine... - * - * Input(s): - * - * - * Output(s): - * - * - * Returns: - * - * - */ -static int -PPC4xx_tlb_miss(struct pt_regs *regs, unsigned long addr, int write) -{ - unsigned long spid, ospid; - struct mm_struct *mm; - pgd_t *pgd; - pmd_t *pmd; - pte_t *pte; - - if (!user_mode(regs) && (addr >= KERNELBASE)) { - mm = &init_mm; - spid = 0; - } else { - mm = current->mm; - spid = mfspr(SPRN_PID); - } - - pgd = pgd_offset(mm, addr); - if (pgd_none(*pgd)) - goto bad; - - pmd = pmd_offset(pgd, addr); - if (pmd_none(*pmd)) - goto bad; - - pte = pte_offset(pmd, addr); - if (pte_none(*pte) || !pte_present(*pte)) - goto bad; - - if (write) { - if (!pte_write(*pte)) - goto bad; - - set_pte(pte, pte_mkdirty(*pte)); - } - set_pte(pte, pte_mkyoung(*pte)); - - ospid = mfspr(SPRN_PID); - mtspr(SPRN_PID, spid); - PPC4xx_tlb_update(addr, pte); - mtspr(SPRN_PID, ospid); - - return (0); -bad: - return (-1); -} diff --git a/arch/ppc/mm/4xx_tlb.h b/arch/ppc/mm/4xx_tlb.h deleted file mode 100644 index 1b85222d19e2..000000000000 --- a/arch/ppc/mm/4xx_tlb.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * BK Id: SCCS/s.4xx_tlb.h 1.5 05/17/01 18:14:23 cort - */ -/* - * - * Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu> - * - * Module name: 4xx_tlb.h - * - * Description: - * Routines for manipulating the TLB on PowerPC 400-class processors. - * - */ - -#ifndef __4XX_TLB_H__ -#define __4XX_TLB_H__ - - -#ifdef __cplusplus -extern "C" { -#endif - - -/* Function Prototypes */ - -extern void PPC4xx_tlb_pin(unsigned long va, unsigned long pa, - int pagesz, int cache); -extern void PPC4xx_tlb_unpin(unsigned long va, unsigned long pa, - int size); -extern void PPC4xx_tlb_flush_all(void); -extern void PPC4xx_tlb_flush(unsigned long va, int pid); - - -#ifdef __cplusplus -} -#endif - -#endif /* __4XX_TLB_H__ */ diff --git a/arch/ppc/mm/Makefile b/arch/ppc/mm/Makefile index c485822e199c..bdc107709bd6 100644 --- a/arch/ppc/mm/Makefile +++ b/arch/ppc/mm/Makefile @@ -1,4 +1,4 @@ -# BK Id: SCCS/s.Makefile 1.8 08/16/01 17:25:47 paulus +# BK Id: %F% %I% %G% %U% %#% # # # Makefile for the linux ppc-specific parts of the memory manager. @@ -21,7 +21,7 @@ obj-y := fault.o init.o mem_pieces.o extable.o \ obj-$(CONFIG_PPC_STD_MMU) += hashtable.o ppc_mmu.o tlb.o obj-$(CONFIG_PPC_ISERIES) += iSeries_hashtable.o iSeries_mmu.o tlb.o -obj-$(CONFIG_4xx) += cachemap.o 4xx_mmu.o -obj-$(CONFIG_8xx) += cachemap.o +obj-$(CONFIG_4xx) += 4xx_mmu.o +obj-$(CONFIG_NOT_COHERENT_CACHE) += cachemap.o include $(TOPDIR)/Rules.make diff --git a/arch/ppc/mm/cachemap.c b/arch/ppc/mm/cachemap.c index b30e8ff560fd..7399f7e9d4b3 100644 --- a/arch/ppc/mm/cachemap.c +++ b/arch/ppc/mm/cachemap.c @@ -52,12 +52,19 @@ extern int get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t **ptep); +/* This function will allocate the requested contiguous pages and + * map them into the kernel's vmalloc() space. This is done so we + * get unique mapping for these pages, outside of the kernel's 1:1 + * virtual:physical mapping. This is necessary so we can cover large + * portions of the kernel with single large page TLB entries, and + * still get unique uncached pages for consistent DMA. + */ void *consistent_alloc(int gfp, size_t size, dma_addr_t *dma_handle) { - int order, rsize; - unsigned long page; - void *ret; - pte_t *pte; + int order, err, i; + unsigned long page, va, pa, flags; + struct vm_struct *area; + void *ret; if (in_interrupt()) BUG(); @@ -79,23 +86,29 @@ void *consistent_alloc(int gfp, size_t size, dma_addr_t *dma_handle) */ invalidate_dcache_range(page, page + size); - ret = (void *)page; - *dma_handle = virt_to_bus(ret); + /* Allocate some common virtual space to map the new pages. + */ + area = get_vm_area(size, VM_ALLOC); + if (area == 0) { + free_pages(page, order); + return NULL; + } + va = VMALLOC_VMADDR(area->addr); + ret = (void *)va; - /* Chase down all of the PTEs and mark them uncached. + /* This gives us the real physical address of the first page. */ - rsize = (int)size; - while (rsize > 0) { - if (get_pteptr(&init_mm, page, &pte)) { - pte_val(*pte) |= _PAGE_NO_CACHE | _PAGE_GUARDED; - flush_tlb_page(find_vma(&init_mm,page),page); - } - else { - BUG(); - return NULL; - } - page += PAGE_SIZE; - rsize -= PAGE_SIZE; + *dma_handle = pa = virt_to_bus(page); + + flags = _PAGE_KERNEL | _PAGE_NO_CACHE; + + err = 0; + for (i = 0; i < size && err == 0; i += PAGE_SIZE) + err = map_page(va+i, pa+i, flags); + + if (err) { + vfree((void *)va); + return NULL; } return ret; @@ -103,42 +116,12 @@ void *consistent_alloc(int gfp, size_t size, dma_addr_t *dma_handle) /* * free page(s) as defined by the above mapping. - * The caller has to tell us the size so we can free the proper number - * of pages. We can't vmalloc() a new space for these pages and simply - * call vfree() like some other architectures because we could end up - * with aliased cache lines (or at least a cache line with the wrong - * attributes). This can happen when the PowerPC speculative loads - * across page boundaries. */ -void consistent_free(void *vaddr, size_t size) +void consistent_free(void *vaddr) { - int order, rsize; - unsigned long addr; - pte_t *pte; - if (in_interrupt()) BUG(); - - size = PAGE_ALIGN(size); - order = get_order(size); - - /* Chase down all of the PTEs and mark them cached again. - */ - addr = (unsigned long)vaddr; - rsize = (int)size; - while (rsize > 0) { - if (get_pteptr(&init_mm, addr, &pte)) { - pte_val(*pte) &= ~(_PAGE_NO_CACHE | _PAGE_GUARDED); - flush_tlb_page(find_vma(&init_mm,addr),addr); - } - else { - BUG(); - return; - } - addr += PAGE_SIZE; - rsize -= PAGE_SIZE; - } - free_pages((unsigned long)vaddr, order); + vfree(vaddr); } /* @@ -163,3 +146,17 @@ void consistent_sync(void *vaddr, size_t size, int direction) break; } } + +/* + * consistent_sync_page make a page are consistent. identical + * to consistent_sync, but takes a struct page instead of a virtual address + */ + +void consistent_sync_page(struct page *page, unsigned long offset, +size_t size, int direction) +{ + unsigned long start; + + start = (unsigned long)(page->virtual) + offset; + consistent_sync(start, size, direction); +} diff --git a/arch/ppc/mm/fault.c b/arch/ppc/mm/fault.c index 9fee4ad0c33d..8a05e58ba965 100644 --- a/arch/ppc/mm/fault.c +++ b/arch/ppc/mm/fault.c @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.fault.c 1.15 09/24/01 16:35:10 paulus + * BK Id: %F% %I% %G% %U% %#% */ /* * arch/ppc/mm/fault.c @@ -29,6 +29,7 @@ #include <linux/mman.h> #include <linux/mm.h> #include <linux/interrupt.h> +#include <linux/highmem.h> #include <asm/page.h> #include <asm/pgtable.h> @@ -54,6 +55,7 @@ unsigned int probingmem; extern void die_if_kernel(char *, struct pt_regs *, long); void bad_page_fault(struct pt_regs *, unsigned long, int sig); void do_page_fault(struct pt_regs *, unsigned long, unsigned long); +extern int get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t **ptep); /* * For 600- and 800-family processors, the error_code parameter is DSISR @@ -136,6 +138,36 @@ good_area: if (is_write) { if (!(vma->vm_flags & VM_WRITE)) goto bad_area; +#if defined(CONFIG_4xx) + /* an exec - 4xx allows for per-page execute permission */ + } else if (regs->trap == 0x400) { + pte_t *ptep; + +#if 0 + /* It would be nice to actually enforce the VM execute + permission on CPUs which can do so, but far too + much stuff in userspace doesn't get the permissions + right, so we let any page be executed for now. */ + if (! (vma->vm_flags & VM_EXEC)) + goto bad_area; +#endif + + /* Since 4xx supports per-page execute permission, + * we lazily flush dcache to icache. */ + if (get_pteptr(mm, address, &ptep) && pte_present(*ptep)) { + struct page *page = pte_page(*ptep); + + if (! test_bit(PG_arch_1, &page->flags)) { + __flush_dcache_icache((unsigned long)kmap(page)); + kunmap(page); + set_bit(PG_arch_1, &page->flags); + } + pte_update(ptep, 0, _PAGE_HWEXEC); + _tlbie(address); + up_read(&mm->mmap_sem); + return; + } +#endif /* a read */ } else { /* protection fault */ @@ -197,8 +229,7 @@ bad_area: out_of_memory: up_read(&mm->mmap_sem); if (current->pid == 1) { - current->policy |= SCHED_YIELD; - schedule(); + yield(); down_read(&mm->mmap_sem); goto survive; } diff --git a/arch/ppc/mm/hashtable.S b/arch/ppc/mm/hashtable.S index 1e32cf5a2feb..2b934dc136c0 100644 --- a/arch/ppc/mm/hashtable.S +++ b/arch/ppc/mm/hashtable.S @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.hashtable.S 1.18 08/15/01 22:43:07 paulus + * BK Id: %F% %I% %G% %U% %#% */ /* * arch/ppc/kernel/hashtable.S @@ -27,11 +27,12 @@ */ #include <linux/config.h> -#include "../kernel/ppc_asm.h" #include <asm/processor.h> #include <asm/page.h> #include <asm/pgtable.h> #include <asm/cputable.h> +#include <asm/ppc_asm.h> +#include <kernel/ppc_defs.h> #ifdef CONFIG_SMP .comm hash_table_lock,4 @@ -63,7 +64,7 @@ hash_page: addis r2,r7,hash_table_lock@h ori r2,r2,hash_table_lock@l mfspr r5,SPRG3 - lwz r0,PROCESSOR-THREAD(r5) + lwz r0,CPU-THREAD(r5) oris r0,r0,0x0fff b 10f 11: lwz r6,0(r2) @@ -214,7 +215,7 @@ _GLOBAL(add_hash_page) #ifdef CONFIG_SMP lis r9,hash_table_lock@h ori r9,r9,hash_table_lock@l - lwz r8,PROCESSOR(r2) + lwz r8,CPU(r2) oris r8,r8,10 10: lwarx r7,0,r9 cmpi 0,r7,0 @@ -333,25 +334,6 @@ _GLOBAL(create_hpte) ori r8,r8,_PAGE_COHERENT /* set M (coherence required) */ #endif -#ifdef CONFIG_POWER4 - /* - * XXX hack hack hack - translate 32-bit "physical" addresses - * in the linux page tables to 42-bit real addresses in such - * a fashion that we can get at the I/O we need to access. - * -- paulus - */ - cmpwi r8,0 - rlwinm r0,r8,16,16,30 - bge 57f - cmplwi r0,0xfe00 - li r0,0x3fd - bne 56f - li r0,0x3ff -56: sldi r0,r0,32 - or r8,r8,r0 -57: -#endif - /* Construct the high word of the PPC-style PTE (r5) */ #ifndef CONFIG_PPC64BRIDGE rlwinm r5,r3,7,1,24 /* put VSID in 0x7fffff80 bits */ @@ -448,21 +430,6 @@ hash_page_patch_C: lwz r6,next_slot@l(r4) addi r6,r6,PTE_SIZE andi. r6,r6,7*PTE_SIZE -#ifdef CONFIG_POWER4 - /* - * Since we don't have BATs on POWER4, we rely on always having - * PTEs in the hash table to map the hash table and the code - * that manipulates it in virtual mode, namely flush_hash_page and - * flush_hash_segments. Otherwise we can get a DSI inside those - * routines which leads to a deadlock on the hash_table_lock on - * SMP machines. We avoid this by never overwriting the first - * PTE of each PTEG if it is already valid. - * -- paulus. - */ - bne 102f - li r6,PTE_SIZE -102: -#endif /* CONFIG_POWER4 */ stw r6,next_slot@l(r4) add r4,r3,r6 @@ -544,7 +511,7 @@ _GLOBAL(flush_hash_page) #ifdef CONFIG_SMP lis r9,hash_table_lock@h ori r9,r9,hash_table_lock@l - lwz r8,PROCESSOR(r2) + lwz r8,CPU(r2) oris r8,r8,9 10: lwarx r7,0,r9 cmpi 0,r7,0 diff --git a/arch/ppc/mm/iSeries_hashtable.c b/arch/ppc/mm/iSeries_hashtable.c new file mode 100644 index 000000000000..0d4a57cbd0c9 --- /dev/null +++ b/arch/ppc/mm/iSeries_hashtable.c @@ -0,0 +1,223 @@ +/* + * + * + * Copyright (c) 2000 Mike Corrigan <mikejc@us.ibm.com> IBM Corporation + * updated by Dave Boutcher (boutcher@us.ibm.com) + * + * Module name: iSeries_hashtable.c + * + * Description: + * Handles Hash Table faults for iSeries LPAR. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#include <asm/processor.h> +#include <asm/pgtable.h> +#include <linux/mm.h> +#include <asm/mmu_context.h> +#include <asm/page.h> +#include <asm/types.h> +#include <linux/spinlock.h> +#include <asm/iSeries/HvCallHpt.h> +#include <asm/iSeries/LparData.h> + +#include <asm/mmu_context.h> + +int iSeries_hpt_loaded; + +static spinlock_t hash_table_lock = SPIN_LOCK_UNLOCKED; + +extern unsigned long htab_reloads; // Defined in ppc/kernel/ppc_htab.c +extern unsigned long htab_evicts; +unsigned long htab_pp_update = 0; + +unsigned long flush_hash_page_count = 0; +unsigned long Hash_mask; + +unsigned long flush_hash_range_count = 0; +unsigned long flush_hash_range_hv_finds = 0; +unsigned long flush_hash_range_hv_evicts = 0; +extern int iSeries_max_kernel_hpt_slot; +static unsigned next_slot = 4; // good enough starting value + +extern void flush_hash_range( u64, u64, unsigned ); + +static inline u32 computeHptePP( unsigned long pte ) +{ + return ( ( pte & _PAGE_USER ) >> 1 ) | + ( ( ( pte & _PAGE_USER ) >> 2 ) & + ( (~pte & _PAGE_RW ) >> 10 ) ); +} + +static inline u32 computeHpteHash( unsigned long vsid, + unsigned long pid ) +{ + return ( vsid ^ pid ) & Hash_mask; +} + +/* + * Should be called with hash page lock + */ +static void __create_hpte(unsigned long vsid, unsigned long va, unsigned long newpte) +{ + PTE hpte; + u64 vpn; + u64 rtnIndex; + u64 *hpte0Ptr, *hpte1Ptr; + u32 newpp, gIndex; + vsid = vsid & 0x7ffffff; + vpn = ((u64)vsid << 16) | ((va >> 12) & 0xffff); + + hpte0Ptr = (u64 *)&hpte; + hpte1Ptr = hpte0Ptr + 1; + *hpte0Ptr = *hpte1Ptr = 0; + + rtnIndex = HvCallHpt_findValid( &hpte, vpn ); + + newpp = computeHptePP( newpte ); + + if ( hpte.v ) { + /* A matching valid entry was found + * Just update the pp bits + */ + ++htab_pp_update; + HvCallHpt_setPp( rtnIndex, newpp ); + } else { /* No matching entry was found Build new hpte */ + hpte.vsid = vsid; + hpte.api = (va >> 23) & 0x1f; + hpte.v = 1; + hpte.rpn = physRpn_to_absRpn(newpte>>12); + hpte.r = 1; + hpte.c = 1; + hpte.m = 1; + hpte.pp = newpp; + + if ( ( rtnIndex != ~0 ) && + ( rtnIndex != 0x00000000ffffffff ) ) { + /* Free entry was found */ + if ( ( rtnIndex >> 63 ) || + ( rtnIndex & 0x80000000 ) ) + hpte.h = 1; + HvCallHpt_addValidate( + rtnIndex, + hpte.h, + &hpte ); + } else { + /* No free entry was found */ + gIndex = computeHpteHash( vsid, vpn & 0xffff ); + rtnIndex = gIndex*8 + next_slot; + if ( ++next_slot > 7 ) + next_slot = iSeries_max_kernel_hpt_slot+1; + HvCallHpt_invalidateSetSwBitsGet( + rtnIndex, 0, 1 ); + HvCallHpt_addValidate( + rtnIndex, 0, &hpte ); + ++htab_evicts; + } + } +} + +int iSeries_create_hpte( unsigned long access, unsigned long va ) +{ + struct thread_struct *ts; + pgd_t * pg; + pmd_t * pm; + pte_t * pt; + u32 vsid; + unsigned flags; + + vsid = mfsrin( va ) & 0x07ffffff; + + if ( va >= KERNELBASE ) + pg = swapper_pg_dir; + else { + // Get the thread structure + ts = (struct thread_struct *)mfspr(SPRG3); + // Get the page directory + pg = ts->pgdir; + } + + pg = pg + pgd_index( va ); // offset into first level + pm = pmd_offset( pg, va ); // offset into second level + if ( pmd_none( *pm ) ) // if no third level + return 1; // indicate failure + pt = pte_offset( pm, va ); // offset into third level + + access |= _PAGE_PRESENT; // _PAGE_PRESENT also needed + + spin_lock( &hash_table_lock ); + // check if pte is in the required state + if ( ( access & ~(pte_val(*pt)) ) ) { + spin_unlock( &hash_table_lock ); + return 1; + } + + /* pte allows the access we are making */ + flags = _PAGE_ACCESSED | _PAGE_HASHPTE | _PAGE_COHERENT; + if ( access & _PAGE_RW ) /* If write access */ + flags |= _PAGE_RW; + + /* atomically update pte */ + pte_update( pt, 0, flags ); + __create_hpte(vsid, + va, + pte_val(*pt)); + + spin_unlock( &hash_table_lock ); + return 0; +} + +void add_hash_page(unsigned context, unsigned long va, pte_t *ptep) +{ + spin_lock( &hash_table_lock ); + pte_update(ptep,0,_PAGE_HASHPTE); + __create_hpte(CTX_TO_VSID(context, va), + va, + pte_val(*ptep)); + spin_unlock( &hash_table_lock ); +} + +int flush_hash_page(unsigned context, unsigned long va, pte_t *ptep) +{ + int rc; + PTE hpte; + u64 vpn; + unsigned long vsid; + u64 rtnIndex; + u64 *hpte0Ptr, *hpte1Ptr; + + vsid = CTX_TO_VSID(context, va); + + vpn = ((u64)vsid << 16) | ((va >> 12) & 0xffff); + + hpte0Ptr = (u64 *)&hpte; + hpte1Ptr = hpte0Ptr + 1; + *hpte0Ptr = *hpte1Ptr = 0; + + spin_lock( &hash_table_lock ); + rtnIndex = HvCallHpt_findValid( &hpte, vpn ); + + if ( hpte.v ) { + pte_update(ptep, _PAGE_HASHPTE, 0); + HvCallHpt_invalidateSetSwBitsGet(rtnIndex, 0, 1 ); + rc = 0; + } else + rc = 1; + spin_unlock( &hash_table_lock ); + return rc; +} + diff --git a/arch/ppc/mm/iSeries_mmu.c b/arch/ppc/mm/iSeries_mmu.c new file mode 100644 index 000000000000..4d1a4d2f997c --- /dev/null +++ b/arch/ppc/mm/iSeries_mmu.c @@ -0,0 +1,186 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ +/* + * Procedures for MMU handling on iSeries systems, where we + * have to call the hypervisor to change things in the hash + * table. + * + * Copyright (C) 2001 IBM Corp. + * updated by Dave Boutcher (boutcher@us.ibm.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ +#include <linux/config.h> +#include <linux/signal.h> +#include <linux/sched.h> +#include <linux/kernel.h> +#include <linux/errno.h> +#include <linux/string.h> +#include <linux/types.h> +#include <linux/ptrace.h> +#include <linux/mman.h> +#include <linux/mm.h> +#include <linux/swap.h> +#include <linux/stddef.h> +#include <linux/vmalloc.h> +#include <linux/init.h> +#include <linux/delay.h> +#include <linux/bootmem.h> +#include <linux/highmem.h> + +#include <asm/pgalloc.h> +#include <asm/prom.h> +#include <asm/io.h> +#include <asm/mmu_context.h> +#include <asm/pgtable.h> +#include <asm/mmu.h> +#include <asm/bootx.h> +#include <asm/machdep.h> +#include <asm/setup.h> +#include <asm/iSeries/LparData.h> +#include <asm/iSeries/HvCallHpt.h> +#include <linux/pci.h> +#include <asm/iSeries/iSeries_dma.h> +#include "mmu_decl.h" + +int iSeries_max_kernel_hpt_slot = 0; +extern unsigned maxPacas; +extern int iSeries_hpt_loaded; +PTE *Hash = 0; + +#ifdef CONFIG_PCI +extern int iSeries_Is_IoMmAddress(unsigned long address); + +/*********************************************************************/ +/* iSeries maps I/O space to device, just leave the address where is.*/ +/*********************************************************************/ +void* ioremap(unsigned long addr, unsigned long size) +{ + return (void*)addr; +} + +void* __ioremap(unsigned long addr, unsigned long size, unsigned long flags) +{ + return (void*)addr; +} + +/********************************************************************/ +/* iSeries did not remapped the space. */ +/********************************************************************/ +void iounmap(void *addr) +{ + return; +} +#endif /* CONFIG_PCI */ + +/* + * Map as much of memory as will fit into the first entry of each + * PPC HPTE Group. (These are the "bolted" entries which will + * never be cast out). The iSeries Hypervisor has already mapped + * the first 32 MB (specified in LparMap.h). Here we map as + * much more as we can. + */ + +void __init MMU_init_hw(void) +{ + PTE hpte; + u64 *hpte0Ptr, *hpte1Ptr; + u32 HptSizeGroups, msPages, rpn, vsid, ea; + u64 rtnIndex; + u32 hpteIndex; + u32 group; + unsigned long numAdded; + + if ( ppc_md.progress ) ppc_md.progress("hash:enter", 0x105); + + hpte0Ptr = (u64 *)&hpte; + hpte1Ptr = hpte0Ptr + 1; + + /* Get the number of Hpt groups */ + HptSizeGroups = (u32)HvCallHpt_getHptPages() * 32; + Hash_mask = HptSizeGroups - 1; + + /* Number of pages in memory */ + msPages = totalLpChunks << 6; + + /* For each virtual page in kernel space, add a hpte if there + isn't one already in slot 0 of the primary pteg. */ + + numAdded = 0; + + for ( ea = (u32)KERNELBASE; ea < (u32)high_memory; ea+= PAGE_SIZE) { + rpn = ea >> 12; + + vsid = ((ea >> 28) * 0x111); + + rtnIndex = HvCallHpt_findValid( &hpte, + (rpn & 0xffff) | (vsid << 16)); + hpteIndex = (u32)rtnIndex; + if ( hpte.v ) /* If valid entry found */ + continue; /* Already mapped, nothing to do */ + if ( rtnIndex == ~0 ) /* If no free entry found */ + BUG(); /* Can't map this page bolted */ + if ( rtnIndex >> 63 ) /* If first free slot is secondary */ + BUG(); /* Can't map this page bolted */ + if ( (hpteIndex & 7) > 2) /* Not in first 3 slots */ + BUG(); + /* + * If returned index is the first in the primary group + * then build an hpt entry for this page. + */ + *hpte0Ptr = *hpte1Ptr = 0; + hpte.vsid = vsid; + hpte.api = (rpn >> 11) & 0x1f; + hpte.h = 0; + hpte.v = 1; + hpte.rpn = physRpn_to_absRpn( rpn ); + hpte.r = 1; + hpte.c = 1; + hpte.m = 1; + hpte.w = 0; + hpte.i = 0; + hpte.g = 0; + hpte.pp = 0; + HvCallHpt_addValidate( hpteIndex, 0, &hpte ); + ++numAdded; + group = rtnIndex & 0x07; + if (group > iSeries_max_kernel_hpt_slot) + iSeries_max_kernel_hpt_slot = group; + } + + printk( "iSeries_hashinit: added %ld hptes to existing mapping. Max group %x\n", + numAdded, iSeries_max_kernel_hpt_slot ); + + if ( ppc_md.progress ) ppc_md.progress("hash:done", 0x205); + + iSeries_hpt_loaded = 1; + Hash = (void *)0xFFFFFFFF; +} + +/* + * This is called at the end of handling a user page fault, when the + * fault has been handled by updating a PTE in the linux page tables. + * We use it to preload an HPTE into the hash table corresponding to + * the updated linux PTE. + */ +void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, + pte_t pte) +{ + struct mm_struct *mm; + pmd_t *pmd; + pte_t *ptep; + static int nopreload; + + if (nopreload) + return; + mm = (address < TASK_SIZE)? vma->vm_mm: &init_mm; + pmd = pmd_offset(pgd_offset(mm, address), address); + if (!pmd_none(*pmd)) { + ptep = pte_offset(pmd, address); + add_hash_page(mm->context, address, ptep); + } +} diff --git a/arch/ppc/mm/init.c b/arch/ppc/mm/init.c index 2c8fb53a871c..6ee19803fe62 100644 --- a/arch/ppc/mm/init.c +++ b/arch/ppc/mm/init.c @@ -1,8 +1,8 @@ /* - * BK Id: SCCS/s.init.c 1.36 09/22/01 14:03:09 paulus + * BK Id: %F% %I% %G% %U% %#% */ /* - * PowerPC version + * PowerPC version * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) * * Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au) @@ -49,19 +49,32 @@ #include "mem_pieces.h" #include "mmu_decl.h" +#ifdef CONFIG_LOWMEM_SIZE_BOOL +#define MAX_LOW_MEM CONFIG_LOWMEM_SIZE +#else #define MAX_LOW_MEM (0xF0000000UL - KERNELBASE) +#endif /* CONFIG_LOWMEM_SIZE_BOOL */ + +#ifdef CONFIG_PPC_ISERIES +extern void create_virtual_bus_tce_table(void); +#endif mmu_gather_t mmu_gathers[NR_CPUS]; -void *end_of_DRAM; unsigned long total_memory; unsigned long total_lowmem; +unsigned long ppc_memstart; +unsigned long ppc_memoffset = PAGE_OFFSET; + int mem_init_done; int init_bootmem_done; int boot_mapsize; unsigned long totalram_pages; unsigned long totalhigh_pages; +#ifdef CONFIG_ALL_PPC +unsigned long agp_special_page; +#endif extern char _end[]; extern char etext[], _stext[]; @@ -85,7 +98,7 @@ extern struct task_struct *current_set[NR_CPUS]; char *klimit = _end; struct mem_pieces phys_avail; -extern char *sysmap; +extern char *sysmap; extern unsigned long sysmap_size; /* @@ -182,13 +195,13 @@ void show_mem(void) iscur = 1; printk("current"); } - + if ( p == last_task_used_math ) { if ( iscur ) printk(","); printk("last math"); - } + } #endif /* CONFIG_SMP */ printk("\n"); } @@ -319,7 +332,6 @@ void __init MMU_init(void) total_memory = total_lowmem; #endif /* CONFIG_HIGHMEM */ } - end_of_DRAM = __va(total_lowmem); set_phys_avail(total_lowmem); /* Initialize the MMU hardware */ @@ -352,9 +364,10 @@ void __init MMU_init(void) ppc_md.progress("MMU:exit", 0x211); #ifdef CONFIG_BOOTX_TEXT - /* Must be done last, or ppc_md.progress will die */ - if (have_of) - map_boot_text(); + /* By default, we are no longer mapped */ + boot_text_mapped = 0; + /* Must be done last, or ppc_md.progress will die. */ + map_boot_text(); #endif } @@ -401,8 +414,11 @@ void __init do_init_bootmem(void) } start = PAGE_ALIGN(start); - boot_mapsize = init_bootmem(start >> PAGE_SHIFT, - total_lowmem >> PAGE_SHIFT); + min_low_pfn = start >> PAGE_SHIFT; + max_low_pfn = (PPC_MEMSTART + total_lowmem) >> PAGE_SHIFT; + boot_mapsize = init_bootmem_node(&contig_page_data, min_low_pfn, + PPC_MEMSTART >> PAGE_SHIFT, + max_low_pfn); /* remove the bootmem bitmap from the available memory */ mem_pieces_remove(&phys_avail, start, boot_mapsize, 1); @@ -455,12 +471,10 @@ void __init mem_init(void) highmem_mapnr = total_lowmem >> PAGE_SHIFT; highmem_start_page = mem_map + highmem_mapnr; - max_mapnr = total_memory >> PAGE_SHIFT; -#else - max_mapnr = max_low_pfn; #endif /* CONFIG_HIGHMEM */ + max_mapnr = total_memory >> PAGE_SHIFT; - high_memory = (void *) __va(max_low_pfn * PAGE_SIZE); + high_memory = (void *) __va(PPC_MEMSTART + total_lowmem); num_physpages = max_mapnr; /* RAM is assumed contiguous */ totalram_pages += free_all_bootmem(); @@ -474,21 +488,23 @@ void __init mem_init(void) } #endif /* CONFIG_BLK_DEV_INITRD */ -#if defined(CONFIG_ALL_PPC) +#if defined(CONFIG_ALL_PPC) /* mark the RTAS pages as reserved */ if ( rtas_data ) for (addr = (ulong)__va(rtas_data); addr < PAGE_ALIGN((ulong)__va(rtas_data)+rtas_size) ; addr += PAGE_SIZE) SetPageReserved(virt_to_page(addr)); + if (agp_special_page) + SetPageReserved(virt_to_page(agp_special_page)); #endif /* defined(CONFIG_ALL_PPC) */ if ( sysmap ) for (addr = (unsigned long)sysmap; addr < PAGE_ALIGN((unsigned long)sysmap+sysmap_size) ; addr += PAGE_SIZE) SetPageReserved(virt_to_page(addr)); - - for (addr = PAGE_OFFSET; addr < (unsigned long)end_of_DRAM; + + for (addr = PAGE_OFFSET; addr < (unsigned long)high_memory; addr += PAGE_SIZE) { if (!PageReserved(virt_to_page(addr))) continue; @@ -526,6 +542,15 @@ void __init mem_init(void) if (sysmap) printk("System.map loaded at 0x%08x for debugger, size: %ld bytes\n", (unsigned int)sysmap, sysmap_size); +#if defined(CONFIG_ALL_PPC) + if (agp_special_page) + printk(KERN_INFO "AGP special page: 0x%08lx\n", agp_special_page); +#endif /* defined(CONFIG_ALL_PPC) */ +#ifdef CONFIG_PPC_ISERIES + + create_virtual_bus_tce_table(); + +#endif /* CONFIG_PPC_ISERIES */ mem_init_done = 1; } @@ -543,7 +568,7 @@ set_phys_avail(unsigned long total_memory) * physical memory. */ - phys_avail.regions[0].address = 0; + phys_avail.regions[0].address = PPC_MEMSTART; phys_avail.regions[0].size = total_memory; phys_avail.n_regions = 1; @@ -572,6 +597,20 @@ set_phys_avail(unsigned long total_memory) /* remove the sysmap pages from the available memory */ if (sysmap) mem_pieces_remove(&phys_avail, __pa(sysmap), sysmap_size, 1); + /* Because of some uninorth weirdness, we need a page of + * memory as high as possible (it must be outside of the + * bus address seen as the AGP aperture). It will be used + * by the r128 DRM driver + * + * FIXME: We need to make sure that page doesn't overlap any of the\ + * above. This could be done by improving mem_pieces_find to be able + * to do a backward search from the end of the list. + */ + if (_machine == _MACH_Pmac && find_devices("uni-north-agp")) { + agp_special_page = (total_memory - PAGE_SIZE); + mem_pieces_remove(&phys_avail, agp_special_page, PAGE_SIZE, 0); + agp_special_page = (unsigned long)__va(agp_special_page); + } #endif /* CONFIG_ALL_PPC */ } @@ -581,23 +620,43 @@ void __init reserve_phys_mem(unsigned long start, unsigned long size) mem_pieces_remove(&phys_avail, start, size, 1); } -void flush_page_to_ram(struct page *page) +/* + * This is called when a page has been modified by the kernel. + * It just marks the page as not i-cache clean. We do the i-cache + * flush later when the page is given to a user process, if necessary. + */ +void flush_dcache_page(struct page *page) +{ + clear_bit(PG_arch_1, &page->flags); +} + +void flush_icache_page(struct vm_area_struct *vma, struct page *page) { - unsigned long vaddr = (unsigned long) kmap(page); - __flush_page_to_ram(vaddr); - kunmap(page); + if (page->mapping && !PageReserved(page) + && !test_bit(PG_arch_1, &page->flags)) { + __flush_dcache_icache(kmap(page)); + kunmap(page); + set_bit(PG_arch_1, &page->flags); + } } -/* - * set_pte stores a linux PTE into the linux page table. - * On machines which use an MMU hash table we avoid changing the - * _PAGE_HASHPTE bit. - */ -void set_pte(pte_t *ptep, pte_t pte) +void clear_user_page(void *page, unsigned long vaddr) { -#if _PAGE_HASHPTE != 0 - pte_update(ptep, ~_PAGE_HASHPTE, pte_val(pte) & ~_PAGE_HASHPTE); -#else - *ptep = pte; -#endif + clear_page(page); +} + +void copy_user_page(void *vto, void *vfrom, unsigned long vaddr) +{ + copy_page(vto, vfrom); + __flush_dcache_icache(vto); +} + +void flush_icache_user_range(struct vm_area_struct *vma, struct page *page, + unsigned long addr, int len) +{ + unsigned long maddr; + + maddr = (unsigned long) kmap(page) + (addr & ~PAGE_MASK); + flush_icache_range(maddr, maddr + len); + kunmap(page); } diff --git a/arch/ppc/mm/mem_pieces.c b/arch/ppc/mm/mem_pieces.c index 572763714eed..222f90e8dd1b 100644 --- a/arch/ppc/mm/mem_pieces.c +++ b/arch/ppc/mm/mem_pieces.c @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.mem_pieces.c 1.5 05/17/01 18:14:23 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * Copyright (c) 1996 Paul Mackerras <paulus@cs.anu.edu.au> @@ -45,7 +45,7 @@ mem_pieces_find(unsigned int size, unsigned int align) a = (a + align - 1) & -align; if (a + size <= e) { mem_pieces_remove(mp, a, size, 1); - return __va(a); + return (void *) __va(a); } } panic("Couldn't find %u bytes at %u alignment\n", size, align); diff --git a/arch/ppc/mm/mmu_decl.h b/arch/ppc/mm/mmu_decl.h index b8dd3ce82e40..20e1a9712e5a 100644 --- a/arch/ppc/mm/mmu_decl.h +++ b/arch/ppc/mm/mmu_decl.h @@ -31,14 +31,12 @@ extern void setbat(int index, unsigned long virt, unsigned long phys, extern void reserve_phys_mem(unsigned long start, unsigned long size); extern int __map_without_bats; -extern void *end_of_DRAM; extern unsigned long ioremap_base; extern unsigned long ioremap_bot; extern unsigned int rtas_data, rtas_size; extern unsigned long total_memory; extern unsigned long total_lowmem; -extern unsigned long ram_phys_base; extern int mem_init_done; extern PTE *Hash, *Hash_end; diff --git a/arch/ppc/mm/pgtable.c b/arch/ppc/mm/pgtable.c index d3630a8c1491..d0725d847729 100644 --- a/arch/ppc/mm/pgtable.c +++ b/arch/ppc/mm/pgtable.c @@ -35,8 +35,6 @@ #include "mmu_decl.h" -unsigned long ram_phys_base; - unsigned long ioremap_base; unsigned long ioremap_bot; int io_bat_index; @@ -199,25 +197,25 @@ void __init mapin_ram(void) #endif /* HAVE_BATS */ v = KERNELBASE; - p = ram_phys_base; + p = PPC_MEMSTART; for (s = 0; s < total_lowmem; s += PAGE_SIZE) { /* On the MPC8xx, we want the page shared so we * don't get ASID compares on kernel space. */ - f = _PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_SHARED; + f = _PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_SHARED | _PAGE_HWEXEC; #if defined(CONFIG_KGDB) || defined(CONFIG_XMON) /* Allows stub to set breakpoints everywhere */ - f |= _PAGE_RW | _PAGE_DIRTY; -#else + f |= _PAGE_WRENABLE; +#else /* !CONFIG_KGDB && !CONFIG_XMON */ if ((char *) v < _stext || (char *) v >= etext) - f |= _PAGE_RW | _PAGE_DIRTY; + f |= _PAGE_WRENABLE; #ifdef CONFIG_PPC_STD_MMU else /* On the powerpc (not all), no user access forces R/W kernel access */ f |= _PAGE_USER; #endif /* CONFIG_PPC_STD_MMU */ -#endif /* CONFIG_KGDB */ +#endif /* CONFIG_KGDB || CONFIG_XMON */ map_page(v, p, f); v += PAGE_SIZE; p += PAGE_SIZE; diff --git a/arch/ppc/mm/ppc_mmu.c b/arch/ppc/mm/ppc_mmu.c index 834b79378c1c..ecfefdd78e80 100644 --- a/arch/ppc/mm/ppc_mmu.c +++ b/arch/ppc/mm/ppc_mmu.c @@ -51,7 +51,7 @@ union ubat { /* BAT register values to be loaded */ u64 word[2]; #else u32 word[2]; -#endif +#endif } BATS[4][2]; /* 4 pairs of IBAT, DBAT */ struct batrange { /* stores address ranges mapped by BATs */ @@ -96,8 +96,8 @@ void __init bat_mapin_ram(void) /* Make sure we don't map a block larger than the smallest alignment of the physical address. */ - /* alignment of ram_phys_base */ - align = ~(ram_phys_base-1) & ram_phys_base; + /* alignment of PPC_MEMSTART */ + align = ~(PPC_MEMSTART-1) & PPC_MEMSTART; /* set BAT block size to MIN(max_size, align) */ if (align && align < max_size) max_size = align; @@ -108,7 +108,7 @@ void __init bat_mapin_ram(void) break; } - setbat(2, KERNELBASE, ram_phys_base, bl, _PAGE_KERNEL); + setbat(2, KERNELBASE, PPC_MEMSTART, bl, _PAGE_KERNEL); done = (unsigned long)bat_addrs[2].limit - KERNELBASE + 1; if ((done < tot) && !bat_addrs[3].limit) { /* use BAT3 to cover a bit more */ @@ -116,7 +116,7 @@ void __init bat_mapin_ram(void) for (bl = 128<<10; bl < max_size; bl <<= 1) if (bl * 2 > tot) break; - setbat(3, KERNELBASE+done, ram_phys_base+done, bl, + setbat(3, KERNELBASE+done, PPC_MEMSTART+done, bl, _PAGE_KERNEL); } } @@ -179,111 +179,101 @@ void __init setbat(int index, unsigned long virt, unsigned long phys, */ void __init MMU_init_hw(void) { - int Hash_bits, mb, mb2; - unsigned int hmask; + unsigned int hmask, mb, mb2; + unsigned int n_hpteg, lg_n_hpteg; extern unsigned int hash_page_patch_A[]; extern unsigned int hash_page_patch_B[], hash_page_patch_C[]; extern unsigned int hash_page[]; extern unsigned int flush_hash_patch_A[], flush_hash_patch_B[]; -#ifdef CONFIG_PPC64BRIDGE - /* The hash table has already been allocated and initialized - in prom.c */ - Hash_mask = (Hash_size >> 7) - 1; - hmask = Hash_mask >> 9; - Hash_bits = __ilog2(Hash_size) - 7; - mb = 25 - Hash_bits; - if (Hash_bits > 16) - Hash_bits = 16; - mb2 = 25 - Hash_bits; - - /* Remove the hash table from the available memory */ - if (Hash) - reserve_phys_mem(__pa(Hash), Hash_size); - -#else /* CONFIG_PPC64BRIDGE */ - unsigned int h; - - if ((cur_cpu_spec[0]->cpu_features & CPU_FTR_HPTE_TABLE) == 0) + if ((cur_cpu_spec[0]->cpu_features & CPU_FTR_HPTE_TABLE) == 0) { + /* + * Put a blr (procedure return) instruction at the + * start of hash_page, since we can still get DSI + * exceptions on a 603. + */ + hash_page[0] = 0x4e800020; + flush_icache_range((unsigned long) &hash_page[0], + (unsigned long) &hash_page[1]); return; + } + if ( ppc_md.progress ) ppc_md.progress("hash:enter", 0x105); + +#ifdef CONFIG_PPC64BRIDGE +#define LG_HPTEG_SIZE 7 /* 128 bytes per HPTEG */ +#define SDR1_LOW_BITS (lg_n_hpteg - 11) +#define MIN_N_HPTEG 2048 /* min 256kB hash table */ +#else +#define LG_HPTEG_SIZE 6 /* 64 bytes per HPTEG */ +#define SDR1_LOW_BITS ((n_hpteg - 1) >> 10) +#define MIN_N_HPTEG 1024 /* min 64kB hash table */ +#endif + /* - * Allow 64k of hash table for every 16MB of memory, - * up to a maximum of 2MB. + * Allow 1 HPTE (1/8 HPTEG) for each page of memory. + * This is less than the recommended amount, but then + * Linux ain't AIX. */ - for (h = 64<<10; h < total_memory / 256 && h < (2<<20); h *= 2) - ; - Hash_size = h; - Hash_mask = (h >> 6) - 1; - hmask = Hash_mask >> 10; - Hash_bits = __ilog2(h) - 6; - mb = 26 - Hash_bits; - if (Hash_bits > 16) - Hash_bits = 16; - mb2 = 26 - Hash_bits; + n_hpteg = total_memory / (PAGE_SIZE * 8); + if (n_hpteg < MIN_N_HPTEG) + n_hpteg = MIN_N_HPTEG; + lg_n_hpteg = __ilog2(n_hpteg); + if (n_hpteg & (n_hpteg - 1)) { + ++lg_n_hpteg; /* round up if not power of 2 */ + n_hpteg = 1 << lg_n_hpteg; + } + Hash_size = n_hpteg << LG_HPTEG_SIZE; + Hash_mask = n_hpteg - 1; + hmask = Hash_mask >> (16 - LG_HPTEG_SIZE); + mb2 = mb = 32 - LG_HPTEG_SIZE - lg_n_hpteg; + if (lg_n_hpteg > 16) + mb2 = 16 - LG_HPTEG_SIZE; + + /* + * Find some memory for the hash table. + */ if ( ppc_md.progress ) ppc_md.progress("hash:find piece", 0x322); - /* Find some memory for the hash table. */ - if ( Hash_size ) { - Hash = mem_pieces_find(Hash_size, Hash_size); - cacheable_memzero(Hash, Hash_size); - _SDR1 = __pa(Hash) | (Hash_mask >> 10); - } else - Hash = 0; -#endif /* CONFIG_PPC64BRIDGE */ + Hash = mem_pieces_find(Hash_size, Hash_size); + cacheable_memzero(Hash, Hash_size); + _SDR1 = __pa(Hash) | SDR1_LOW_BITS; + Hash_end = (PTE *) ((unsigned long)Hash + Hash_size); printk("Total memory = %ldMB; using %ldkB for hash table (at %p)\n", total_memory >> 20, Hash_size >> 10, Hash); - if (Hash_size) { - if ( ppc_md.progress ) ppc_md.progress("hash:patch", 0x345); - Hash_end = (PTE *) ((unsigned long)Hash + Hash_size); - /* - * Patch up the instructions in hashtable.S:create_hpte - */ - hash_page_patch_A[0] = (hash_page_patch_A[0] & ~0xffff) - | ((unsigned int)(Hash) >> 16); - hash_page_patch_A[1] = (hash_page_patch_A[1] & ~0x7c0) - | (mb << 6); - hash_page_patch_A[2] = (hash_page_patch_A[2] & ~0x7c0) - | (mb2 << 6); - hash_page_patch_B[0] = (hash_page_patch_B[0] & ~0xffff) - | hmask; - hash_page_patch_C[0] = (hash_page_patch_C[0] & ~0xffff) - | hmask; - /* - * Ensure that the locations we've patched have been written - * out from the data cache and invalidated in the instruction - * cache, on those machines with split caches. - */ - flush_icache_range((unsigned long) &hash_page_patch_A[0], - (unsigned long) &hash_page_patch_C[1]); - /* - * Patch up the instructions in hashtable.S:flush_hash_page - */ - flush_hash_patch_A[0] = (flush_hash_patch_A[0] & ~0xffff) - | ((unsigned int)(Hash) >> 16); - flush_hash_patch_A[1] = (flush_hash_patch_A[1] & ~0x7c0) - | (mb << 6); - flush_hash_patch_A[2] = (flush_hash_patch_A[2] & ~0x7c0) - | (mb2 << 6); - flush_hash_patch_B[0] = (flush_hash_patch_B[0] & ~0xffff) - | hmask; - flush_icache_range((unsigned long) &flush_hash_patch_A[0], - (unsigned long) &flush_hash_patch_B[1]); - } - else { - Hash_end = 0; - /* - * Put a blr (procedure return) instruction at the - * start of hash_page, since we can still get DSI - * exceptions on a 603. - */ - hash_page[0] = 0x4e800020; - flush_icache_range((unsigned long) &hash_page[0], - (unsigned long) &hash_page[1]); - } + + /* + * Patch up the instructions in hashtable.S:create_hpte + */ + if ( ppc_md.progress ) ppc_md.progress("hash:patch", 0x345); + hash_page_patch_A[0] = (hash_page_patch_A[0] & ~0xffff) + | ((unsigned int)(Hash) >> 16); + hash_page_patch_A[1] = (hash_page_patch_A[1] & ~0x7c0) | (mb << 6); + hash_page_patch_A[2] = (hash_page_patch_A[2] & ~0x7c0) | (mb2 << 6); + hash_page_patch_B[0] = (hash_page_patch_B[0] & ~0xffff) | hmask; + hash_page_patch_C[0] = (hash_page_patch_C[0] & ~0xffff) | hmask; + + /* + * Ensure that the locations we've patched have been written + * out from the data cache and invalidated in the instruction + * cache, on those machines with split caches. + */ + flush_icache_range((unsigned long) &hash_page_patch_A[0], + (unsigned long) &hash_page_patch_C[1]); + + /* + * Patch up the instructions in hashtable.S:flush_hash_page + */ + flush_hash_patch_A[0] = (flush_hash_patch_A[0] & ~0xffff) + | ((unsigned int)(Hash) >> 16); + flush_hash_patch_A[1] = (flush_hash_patch_A[1] & ~0x7c0) | (mb << 6); + flush_hash_patch_A[2] = (flush_hash_patch_A[2] & ~0x7c0) | (mb2 << 6); + flush_hash_patch_B[0] = (flush_hash_patch_B[0] & ~0xffff) | hmask; + flush_icache_range((unsigned long) &flush_hash_patch_A[0], + (unsigned long) &flush_hash_patch_B[1]); if ( ppc_md.progress ) ppc_md.progress("hash:done", 0x205); } @@ -304,6 +294,9 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, if (Hash == 0 || nopreload) return; + /* We only want HPTEs for linux PTEs that have _PAGE_ACCESSED set */ + if (!pte_young(pte)) + return; mm = (address < TASK_SIZE)? vma->vm_mm: &init_mm; pmd = pmd_offset(pgd_offset(mm, address), address); if (!pmd_none(*pmd)) { diff --git a/arch/ppc/platforms/Makefile b/arch/ppc/platforms/Makefile new file mode 100644 index 000000000000..a01ce1786fdf --- /dev/null +++ b/arch/ppc/platforms/Makefile @@ -0,0 +1,76 @@ +# BK Id: %F% %I% %G% %U% %#% +# +# +# Makefile for the linux kernel. +# +# Note! Dependencies are done automagically by 'make dep', which also +# removes any old dependencies. DON'T put your own dependencies here +# unless it's something special (ie not a .c file). +# +# Note 2! The CFLAGS definitions are now in the main makefile... + +USE_STANDARD_AS_RULE := true + +ifdef CONFIG_PPC64BRIDGE +EXTRA_AFLAGS := -Wa,-mppc64bridge +endif +ifdef CONFIG_4xx +EXTRA_AFLAGS := -Wa,-m405 +endif + +# Extra CFLAGS so we don't have to do relative includes +CFLAGS_pmac_setup.o += -I$(TOPDIR)/arch/$(ARCH)/mm + +all: platform.o + +O_TARGET := platform.o + +export-objs := prep_setup.o + +obj-$(CONFIG_CEDER) += ceder.o ibmnp405l.o +obj-$(CONFIG_CPCI405) += cpci405.o ibm405gp.o +obj-$(CONFIG_EP405) += ep405.o ibm405gp.o +obj-$(CONFIG_REDWOOD_4) += redwood.o ibmstb3.o +obj-$(CONFIG_REDWOOD_5) += redwood5.o ibmstb4.o +obj-$(CONFIG_WALNUT) += walnut.o ibm405gp.o +obj-$(CONFIG_ASH) += ash.o ibmnp405h.o +obj-$(CONFIG_APUS) += apus_setup.o +ifeq ($(CONFIG_APUS),y) +obj-$(CONFIG_PCI) += apus_pci.o +endif +obj-$(CONFIG_ALL_PPC) += pmac_pic.o pmac_setup.o pmac_time.o \ + pmac_feature.o pmac_pci.o chrp_setup.o\ + chrp_time.o chrp_pci.o prep_pci.o \ + prep_time.o prep_nvram.o prep_setup.o +ifeq ($(CONFIG_ALL_PPC),y) +obj-$(CONFIG_NVRAM) += pmac_nvram.o +endif +obj-$(CONFIG_PMAC_BACKLIGHT) += pmac_backlight.o +obj-$(CONFIG_PMAC_PBOOK) += sleep.o +obj-$(CONFIG_PPC_RTAS) += error_log.o proc_rtas.o +obj-$(CONFIG_PREP_RESIDUAL) += residual.o +obj-$(CONFIG_ADIR) += adir_setup.o adir_pic.o adir_pci.o +obj-$(CONFIG_EV64260) += ev64260_setup.o +obj-$(CONFIG_GEMINI) += gemini_pci.o gemini_setup.o gemini_prom.o +obj-$(CONFIG_K2) += k2_setup.o k2_pci.o +obj-$(CONFIG_LOPEC) += lopec_setup.o lopec_pci.o +obj-$(CONFIG_MCPN765) += mcpn765_setup.o mcpn765_pci.o +obj-$(CONFIG_MENF1) += menf1_setup.o menf1_pci.o +obj-$(CONFIG_MVME5100) += mvme5100_setup.o mvme5100_pci.o +obj-$(CONFIG_PCORE) += pcore_setup.o pcore_pci.o +obj-$(CONFIG_POWERPMC250) += powerpmc250.o +obj-$(CONFIG_PPLUS) += pplus_pci.o pplus_setup.o prep_nvram.o +obj-$(CONFIG_PRPMC750) += prpmc750_setup.o prpmc750_pci.o +obj-$(CONFIG_PRPMC800) += prpmc800_setup.o prpmc800_pci.o +obj-$(CONFIG_SANDPOINT) += sandpoint_setup.o sandpoint_pci.o +obj-$(CONFIG_SPRUCE) += spruce_setup.o spruce_pci.o cpc700_pic.o +obj-$(CONFIG_ZX4500) += zx4500_setup.o zx4500_pci.o +obj-$(CONFIG_PPC_ISERIES) += iSeries_setup.o iSeries_time.o \ + iSeries_dma.o iSeries_pic.o + +ifeq ($(CONFIG_SMP),y) +obj-$(CONFIG_ALL_PPC) += pmac_smp.o chrp_smp.o +obj-$(CONFIG_PPC_ISERIES) += iSeries_smp.o +endif + +include $(TOPDIR)/Rules.make diff --git a/arch/ppc/platforms/adir.h b/arch/ppc/platforms/adir.h new file mode 100644 index 000000000000..19421be495e3 --- /dev/null +++ b/arch/ppc/platforms/adir.h @@ -0,0 +1,95 @@ +/* + * arch/ppc/platforms/adir.h + * + * Definitions for SBS Adirondack board support + * + * By Michael Sokolov <msokolov@ivan.Harhan.ORG> + */ + +#ifndef __PPC_PLATFORMS_ADIR_H +#define __PPC_PLATFORMS_ADIR_H + +/* + * SBS Adirondack definitions + */ + +/* PPC physical address space layout. We use the one set up by the firmware. */ +#define ADIR_PCI32_MEM_BASE 0x80000000 +#define ADIR_PCI32_MEM_SIZE 0x20000000 +#define ADIR_PCI64_MEM_BASE 0xA0000000 +#define ADIR_PCI64_MEM_SIZE 0x20000000 +#define ADIR_PCI32_IO_BASE 0xC0000000 +#define ADIR_PCI32_IO_SIZE 0x10000000 +#define ADIR_PCI64_IO_BASE 0xD0000000 +#define ADIR_PCI64_IO_SIZE 0x10000000 +#define ADIR_PCI64_PHB 0xFF400000 +#define ADIR_PCI32_PHB 0xFF500000 + +#define ADIR_PCI64_CONFIG_ADDR (ADIR_PCI64_PHB + 0x000f8000) +#define ADIR_PCI64_CONFIG_DATA (ADIR_PCI64_PHB + 0x000f8010) + +#define ADIR_PCI32_CONFIG_ADDR (ADIR_PCI32_PHB + 0x000f8000) +#define ADIR_PCI32_CONFIG_DATA (ADIR_PCI32_PHB + 0x000f8010) + +/* System memory as seen from PCI */ +#define ADIR_PCI_SYS_MEM_BASE 0x80000000 + +/* Static virtual mapping of PCI I/O */ +#define ADIR_PCI32_VIRT_IO_BASE 0xFE000000 +#define ADIR_PCI32_VIRT_IO_SIZE 0x01000000 +#define ADIR_PCI64_VIRT_IO_BASE 0xFF000000 +#define ADIR_PCI64_VIRT_IO_SIZE 0x01000000 + +/* Registers */ +#define ADIR_NVRAM_RTC_ADDR 0x74 +#define ADIR_NVRAM_RTC_DATA 0x75 + +#define ADIR_BOARD_ID_REG (ADIR_PCI32_VIRT_IO_BASE + 0x08FFF0) +#define ADIR_CPLD1REV_REG (ADIR_PCI32_VIRT_IO_BASE + 0x08FFF1) +#define ADIR_CPLD2REV_REG (ADIR_PCI32_VIRT_IO_BASE + 0x08FFF2) +#define ADIR_FLASHCTL_REG (ADIR_PCI32_VIRT_IO_BASE + 0x08FFF3) +#define ADIR_CPC710_STAT_REG (ADIR_PCI32_VIRT_IO_BASE + 0x08FFF4) +#define ADIR_CLOCK_REG (ADIR_PCI32_VIRT_IO_BASE + 0x08FFF5) +#define ADIR_GPIO_REG (ADIR_PCI32_VIRT_IO_BASE + 0x08FFF8) +#define ADIR_MISC_REG (ADIR_PCI32_VIRT_IO_BASE + 0x08FFF9) +#define ADIR_LED_REG (ADIR_PCI32_VIRT_IO_BASE + 0x08FFFA) + +#define ADIR_CLOCK_REG_PD 0x10 +#define ADIR_CLOCK_REG_SPREAD 0x08 +#define ADIR_CLOCK_REG_SEL133 0x04 +#define ADIR_CLOCK_REG_SEL1 0x02 +#define ADIR_CLOCK_REG_SEL0 0x01 + +#define ADIR_PROCA_INT_MASK (ADIR_PCI32_VIRT_IO_BASE + 0x0EFFF0) +#define ADIR_PROCB_INT_MASK (ADIR_PCI32_VIRT_IO_BASE + 0x0EFFF2) +#define ADIR_PROCA_INT_STAT (ADIR_PCI32_VIRT_IO_BASE + 0x0EFFF4) +#define ADIR_PROCB_INT_STAT (ADIR_PCI32_VIRT_IO_BASE + 0x0EFFF6) + +/* Linux IRQ numbers */ +#define ADIR_IRQ_NONE -1 +#define ADIR_IRQ_SERIAL2 3 +#define ADIR_IRQ_SERIAL1 4 +#define ADIR_IRQ_FDC 6 +#define ADIR_IRQ_PARALLEL 7 +#define ADIR_IRQ_VIA_AUDIO 10 +#define ADIR_IRQ_VIA_USB 11 +#define ADIR_IRQ_IDE0 14 +#define ADIR_IRQ_IDE1 15 +#define ADIR_IRQ_PCI0_INTA 16 +#define ADIR_IRQ_PCI0_INTB 17 +#define ADIR_IRQ_PCI0_INTC 18 +#define ADIR_IRQ_PCI0_INTD 19 +#define ADIR_IRQ_PCI1_INTA 20 +#define ADIR_IRQ_PCI1_INTB 21 +#define ADIR_IRQ_PCI1_INTC 22 +#define ADIR_IRQ_PCI1_INTD 23 +#define ADIR_IRQ_MBSCSI 24 /* motherboard SCSI */ +#define ADIR_IRQ_MBETH1 25 /* motherboard Ethernet 1 */ +#define ADIR_IRQ_MBETH0 26 /* motherboard Ethernet 0 */ +#define ADIR_IRQ_CPC710_INT1 27 +#define ADIR_IRQ_CPC710_INT2 28 +#define ADIR_IRQ_VT82C686_NMI 29 +#define ADIR_IRQ_VT82C686_INTR 30 +#define ADIR_IRQ_INTERPROC 31 + +#endif /* __PPC_PLATFORMS_ADIR_H */ diff --git a/arch/ppc/platforms/adir_pci.c b/arch/ppc/platforms/adir_pci.c new file mode 100644 index 000000000000..5309b0fd9103 --- /dev/null +++ b/arch/ppc/platforms/adir_pci.c @@ -0,0 +1,247 @@ +/* + * arch/ppc/platforms/adir_pci.c + * + * PCI support for SBS Adirondack + * + * By Michael Sokolov <msokolov@ivan.Harhan.ORG> + * based on the K2 version by Matt Porter <mporter@mvista.com> + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/pci.h> +#include <linux/slab.h> + +#include <asm/byteorder.h> +#include <asm/io.h> +#include <asm/uaccess.h> +#include <asm/machdep.h> +#include <asm/pci-bridge.h> + +#include "cpc710.h" +#include "adir.h" + +#undef DEBUG +#ifdef DEBUG +#define DBG(x...) printk(x) +#else +#define DBG(x...) +#endif /* DEBUG */ + +static inline int __init +adir_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) +{ +#define PCIIRQ(a,b,c,d) {ADIR_IRQ_##a,ADIR_IRQ_##b,ADIR_IRQ_##c,ADIR_IRQ_##d}, + struct pci_controller *hose = pci_bus_to_hose(dev->bus->number); + /* + * The three PCI devices on the motherboard have dedicated lines to the + * CPLD interrupt controller, bypassing the standard PCI INTA-D and the + * PC interrupt controller. All other PCI devices (slots) have usual + * staggered INTA-D lines, resulting in 8 lines total (PCI0 INTA-D and + * PCI1 INTA-D). All 8 go to the CPLD interrupt controller. PCI0 INTA-D + * also go to the south bridge, so we have the option of taking them + * via the CPLD interrupt controller or via the south bridge 8259 + * 8258 thingy. PCI1 INTA-D can only be taken via the CPLD interrupt + * controller. We take all PCI interrupts via the CPLD interrupt + * controller as recommended by SBS. + * + * We also have some monkey business with the PCI devices within the + * VT82C686B south bridge itself. This chip actually has 7 functions on + * its IDSEL. Function 0 is the actual south bridge, function 1 is IDE, + * and function 4 is some special stuff. The other 4 functions are just + * regular PCI devices bundled in the chip. 2 and 3 are USB UHCIs and 5 + * and 6 are audio (not supported on the Adirondack). + * + * This is where the monkey business begins. PCI devices are supposed + * to signal normal PCI interrupts. But the 4 functions in question are + * located in the south bridge chip, which is designed with the + * assumption that it will be fielding PCI INTA-D interrupts rather + * than generating them. Here's what it does. Each of the functions in + * question routes its interrupt to one of the IRQs on the 8259 thingy. + * Which one? It looks at the Interrupt Line register in the PCI config + * space, even though the PCI spec says it's for BIOS/OS interaction + * only. + * + * How do we deal with this? We take these interrupts via 8259 IRQs as + * we have to. We return the desired IRQ numbers from this routine when + * called for the functions in question. The PCI scan code will then + * stick our return value into the Interrupt Line register in the PCI + * config space, and the interrupt will actually go there. We identify + * these functions within the south bridge IDSEL by their interrupt pin + * numbers, as the VT82C686B has 04 in the Interrupt Pin register for + * USB and 03 for audio. + */ + if (!hose->index) { + static char pci_irq_table[][4] = + /* + * PCI IDSEL/INTPIN->INTLINE + * A B C D + */ + { + /* south bridge */ PCIIRQ(IDE0, NONE, VIA_AUDIO, VIA_USB) + /* Ethernet 0 */ PCIIRQ(MBETH0, MBETH0, MBETH0, MBETH0) + /* PCI0 slot 1 */ PCIIRQ(PCI0_INTB, PCI0_INTC, PCI0_INTD, PCI0_INTA) + /* PCI0 slot 2 */ PCIIRQ(PCI0_INTC, PCI0_INTD, PCI0_INTA, PCI0_INTB) + /* PCI0 slot 3 */ PCIIRQ(PCI0_INTD, PCI0_INTA, PCI0_INTB, PCI0_INTC) + }; + const long min_idsel = 3, max_idsel = 7, irqs_per_slot = 4; + return PCI_IRQ_TABLE_LOOKUP; + } else { + static char pci_irq_table[][4] = + /* + * PCI IDSEL/INTPIN->INTLINE + * A B C D + */ + { + /* Ethernet 1 */ PCIIRQ(MBETH1, MBETH1, MBETH1, MBETH1) + /* SCSI */ PCIIRQ(MBSCSI, MBSCSI, MBSCSI, MBSCSI) + /* PCI1 slot 1 */ PCIIRQ(PCI1_INTB, PCI1_INTC, PCI1_INTD, PCI1_INTA) + /* PCI1 slot 2 */ PCIIRQ(PCI1_INTC, PCI1_INTD, PCI1_INTA, PCI1_INTB) + /* PCI1 slot 3 */ PCIIRQ(PCI1_INTD, PCI1_INTA, PCI1_INTB, PCI1_INTC) + }; + const long min_idsel = 3, max_idsel = 7, irqs_per_slot = 4; + return PCI_IRQ_TABLE_LOOKUP; + } +#undef PCIIRQ +} + +static void +adir_pcibios_fixup_resources(struct pci_dev *dev) +{ + int i; + + if ((dev->vendor == PCI_VENDOR_ID_IBM) && + (dev->device == PCI_DEVICE_ID_IBM_CPC710_PCI64)) + { + DBG("Fixup CPC710 resources\n"); + for (i=0; i<DEVICE_COUNT_RESOURCE; i++) + { + dev->resource[i].start = 0; + dev->resource[i].end = 0; + } + } +} + +/* + * CPC710 DD3 has an errata causing it to hang the system if a type 0 config + * cycle is attempted on its PCI32 interface with a device number > 21. + * CPC710's PCI bridges map device numbers 1 through 21 to AD11 through AD31. + * Per the PCI spec it MUST accept all other device numbers and do nothing, and + * software MUST scan all device numbers without assuming how IDSELs are + * mapped. However, as the CPC710 DD3's errata causes such correct scanning + * procedure to hang the system, we have no choice but to introduce this hack + * of knowingly avoiding device numbers > 21 on PCI0, + */ +static int +adir_exclude_device(u_char bus, u_char devfn) +{ + if ((bus == 0) && (PCI_SLOT(devfn) > 21)) + return PCIBIOS_DEVICE_NOT_FOUND; + else + return PCIBIOS_SUCCESSFUL; +} + +void adir_find_bridges(void) +{ + struct pci_controller *hose_a, *hose_b; + + /* Setup PCI32 hose */ + hose_a = pcibios_alloc_controller(); + if (!hose_a) + return; + + hose_a->first_busno = 0; + hose_a->last_busno = 0xff; + hose_a->pci_mem_offset = ADIR_PCI32_MEM_BASE; + hose_a->io_space.start = 0; + hose_a->io_space.end = ADIR_PCI32_VIRT_IO_SIZE - 1; + hose_a->mem_space.start = 0; + hose_a->mem_space.end = ADIR_PCI32_MEM_SIZE - 1; + hose_a->io_resource.start = 0; + hose_a->io_resource.end = ADIR_PCI32_VIRT_IO_SIZE - 1; + hose_a->io_resource.flags = IORESOURCE_IO; + hose_a->mem_resources[0].start = ADIR_PCI32_MEM_BASE; + hose_a->mem_resources[0].end = ADIR_PCI32_MEM_BASE + + ADIR_PCI32_MEM_SIZE - 1; + hose_a->mem_resources[0].flags = IORESOURCE_MEM; + hose_a->io_base_phys = ADIR_PCI32_IO_BASE; + hose_a->io_base_virt = (void *) ADIR_PCI32_VIRT_IO_BASE; + + ppc_md.pci_exclude_device = adir_exclude_device; + setup_indirect_pci(hose_a, ADIR_PCI32_CONFIG_ADDR, + ADIR_PCI32_CONFIG_DATA); + + /* Initialize PCI32 bus registers */ + early_write_config_byte(hose_a, + hose_a->first_busno, + PCI_DEVFN(0, 0), + CPC710_BUS_NUMBER, + hose_a->first_busno); + early_write_config_byte(hose_a, + hose_a->first_busno, + PCI_DEVFN(0, 0), + CPC710_SUB_BUS_NUMBER, + hose_a->last_busno); + + hose_a->last_busno = pciauto_bus_scan(hose_a, hose_a->first_busno); + + /* Write out correct max subordinate bus number for hose A */ + early_write_config_byte(hose_a, + hose_a->first_busno, + PCI_DEVFN(0, 0), + CPC710_SUB_BUS_NUMBER, + hose_a->last_busno); + + /* Setup PCI64 hose */ + hose_b = pcibios_alloc_controller(); + if (!hose_b) + return; + + hose_b->first_busno = hose_a->last_busno + 1; + hose_b->last_busno = 0xff; + hose_b->pci_mem_offset = ADIR_PCI64_MEM_BASE; + hose_b->io_space.start = 0; + hose_b->io_space.end = ADIR_PCI64_VIRT_IO_SIZE - 1; + hose_b->mem_space.start = 0; + hose_b->mem_space.end = ADIR_PCI64_MEM_SIZE - 1; + hose_b->io_resource.start = 0; + hose_b->io_resource.end = ADIR_PCI64_VIRT_IO_SIZE - 1; + hose_b->io_resource.flags = IORESOURCE_IO; + hose_b->mem_resources[0].start = ADIR_PCI64_MEM_BASE; + hose_b->mem_resources[0].end = ADIR_PCI64_MEM_BASE + + ADIR_PCI64_MEM_SIZE - 1; + hose_b->mem_resources[0].flags = IORESOURCE_MEM; + hose_b->io_base_phys = ADIR_PCI64_IO_BASE; + hose_b->io_base_virt = (void *) ADIR_PCI64_VIRT_IO_BASE; + + setup_indirect_pci(hose_b, ADIR_PCI64_CONFIG_ADDR, + ADIR_PCI64_CONFIG_DATA); + + /* Initialize PCI64 bus registers */ + early_write_config_byte(hose_b, + 0, + PCI_DEVFN(0, 0), + CPC710_SUB_BUS_NUMBER, + 0xff); + + early_write_config_byte(hose_b, + 0, + PCI_DEVFN(0, 0), + CPC710_BUS_NUMBER, + hose_b->first_busno); + + hose_b->last_busno = pciauto_bus_scan(hose_b, + hose_b->first_busno); + + /* Write out correct max subordinate bus number for hose B */ + early_write_config_byte(hose_b, + hose_b->first_busno, + PCI_DEVFN(0, 0), + CPC710_SUB_BUS_NUMBER, + hose_b->last_busno); + + ppc_md.pcibios_fixup = NULL; + ppc_md.pcibios_fixup_resources = adir_pcibios_fixup_resources; + ppc_md.pci_swizzle = common_swizzle; + ppc_md.pci_map_irq = adir_map_irq; +} diff --git a/arch/ppc/platforms/adir_pic.c b/arch/ppc/platforms/adir_pic.c new file mode 100644 index 000000000000..59304abfe851 --- /dev/null +++ b/arch/ppc/platforms/adir_pic.c @@ -0,0 +1,132 @@ +/* + * arch/ppc/platforms/adir_pic.c + * + * Interrupt controller support for SBS Adirondack + * + * By Michael Sokolov <msokolov@ivan.Harhan.ORG> + * based on the K2 and SCM versions by Matt Porter <mporter@mvista.com> + */ + +#include <linux/stddef.h> +#include <linux/init.h> +#include <linux/sched.h> +#include <linux/pci.h> +#include <linux/irq.h> + +#include <asm/io.h> +#include <asm/i8259.h> +#include "adir.h" + +static void adir_onboard_pic_enable(unsigned int irq); +static void adir_onboard_pic_disable(unsigned int irq); + +static void +no_action(int cpl, void *dev_id, struct pt_regs *regs) +{ +} + +__init static void +adir_onboard_pic_init(void) +{ + volatile u_short *maskreg = (volatile u_short *) ADIR_PROCA_INT_MASK; + + /* Disable all Adirondack onboard interrupts */ + out_be16(maskreg, 0xFFFF); +} + +static int +adir_onboard_pic_get_irq(void) +{ + volatile u_short *statreg = (volatile u_short *) ADIR_PROCA_INT_STAT; + int irq; + u_short int_status, int_test; + + int_status = in_be16(statreg); + for (irq = 0, int_test = 1; irq < 16; irq++, int_test <<= 1) { + if (int_status & int_test) + break; + } + + if (irq == 16) + return -1; + + return (irq+16); +} + +static void +adir_onboard_pic_enable(unsigned int irq) +{ + volatile u_short *maskreg = (volatile u_short *) ADIR_PROCA_INT_MASK; + + /* Change irq to Adirondack onboard native value */ + irq -= 16; + + /* Enable requested irq number */ + out_be16(maskreg, in_be16(maskreg) & ~(1 << irq)); +} + +static void +adir_onboard_pic_disable(unsigned int irq) +{ + volatile u_short *maskreg = (volatile u_short *) ADIR_PROCA_INT_MASK; + + /* Change irq to Adirondack onboard native value */ + irq -= 16; + + /* Disable requested irq number */ + out_be16(maskreg, in_be16(maskreg) | (1 << irq)); +} + +static struct hw_interrupt_type adir_onboard_pic = { + " ADIR PIC ", + NULL, + NULL, + adir_onboard_pic_enable, /* unmask */ + adir_onboard_pic_disable, /* mask */ + adir_onboard_pic_disable, /* mask and ack */ + NULL, + NULL +}; + +/* + * Linux interrupt values are assigned as follows: + * + * 0-15 VT82C686 8259 interrupts + * 16-31 Adirondack CPLD interrupts + */ +__init void +adir_init_IRQ(void) +{ + int i; + + /* Initialize the cascaded 8259's on the VT82C686 */ + for (i=0; i<16; i++) + irq_desc[i].handler = &i8259_pic; + i8259_init(NULL); + + /* Initialize Adirondack CPLD PIC and enable 8259 interrupt cascade */ + for (i=16; i<32; i++) + irq_desc[i].handler = &adir_onboard_pic; + adir_onboard_pic_init(); + + /* Enable 8259 interrupt cascade */ + request_irq(ADIR_IRQ_VT82C686_INTR, + no_action, + SA_INTERRUPT, + "82c59 primary cascade", + NULL); +} + +int +adir_get_irq(void) +{ + int irq; + + if ((irq = adir_onboard_pic_get_irq()) < 0) + return irq; + + if (irq == ADIR_IRQ_VT82C686_INTR) + irq = i8259_poll(); + + return irq; +} diff --git a/arch/ppc/platforms/adir_setup.c b/arch/ppc/platforms/adir_setup.c new file mode 100644 index 000000000000..8d74eae75b7b --- /dev/null +++ b/arch/ppc/platforms/adir_setup.c @@ -0,0 +1,211 @@ +/* + * arch/ppc/platforms/adir_setup.c + * + * Board setup routines for SBS Adirondack + * + * By Michael Sokolov <msokolov@ivan.Harhan.ORG> + * based on the K2 version by Matt Porter <mporter@mvista.com> + */ + +#include <linux/config.h> +#include <linux/stddef.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/errno.h> +#include <linux/reboot.h> +#include <linux/pci.h> +#include <linux/kdev_t.h> +#include <linux/types.h> +#include <linux/major.h> +#include <linux/blk.h> +#include <linux/console.h> +#include <linux/delay.h> +#include <linux/ide.h> +#include <linux/seq_file.h> + +#include <asm/system.h> +#include <asm/pgtable.h> +#include <asm/page.h> +#include <asm/dma.h> +#include <asm/io.h> +#include <asm/machdep.h> +#include <asm/time.h> +#include <asm/todc.h> +#include <asm/bootinfo.h> + +#include "adir.h" + +extern void adir_init_IRQ(void); +extern int adir_get_irq(struct pt_regs *); +extern void adir_find_bridges(void); +extern unsigned long loops_per_jiffy; + +static unsigned int cpu_750cx[16] = { + 5, 15, 14, 0, 4, 13, 0, 9, 6, 11, 8, 10, 16, 12, 7, 0 +}; + +static int +adir_get_bus_speed(void) +{ + if (!(*((u_char *) ADIR_CLOCK_REG) & ADIR_CLOCK_REG_SEL133)) + return 100000000; + else + return 133333333; +} + +static int +adir_get_cpu_speed(void) +{ + unsigned long hid1; + int cpu_speed; + + hid1 = mfspr(HID1) >> 28; + + hid1 = cpu_750cx[hid1]; + + cpu_speed = adir_get_bus_speed()*hid1/2; + return cpu_speed; +} + +static void __init +adir_calibrate_decr(void) +{ + int freq, divisor = 4; + + /* determine processor bus speed */ + freq = adir_get_bus_speed(); + tb_ticks_per_jiffy = freq / HZ / divisor; + tb_to_us = mulhwu_scale_factor(freq/divisor, 1000000); +} + +static int +adir_show_cpuinfo(struct seq_file *m) +{ + seq_printf(m, "vendor\t\t: SBS\n"); + seq_printf(m, "machine\t\t: Adirondack\n"); + seq_printf(m, "cpu speed\t: %dMhz\n", adir_get_cpu_speed()/1000000); + seq_printf(m, "bus speed\t: %dMhz\n", adir_get_bus_speed()/1000000); + seq_printf(m, "memory type\t: SDRAM\n"); + + return 0; +} + +extern char cmd_line[]; + +TODC_ALLOC(); + +static void __init +adir_setup_arch(void) +{ + unsigned int cpu; + + /* Setup TODC access */ + TODC_INIT(TODC_TYPE_MC146818, ADIR_NVRAM_RTC_ADDR, 0, + ADIR_NVRAM_RTC_DATA, 8); + + /* init to some ~sane value until calibrate_delay() runs */ + loops_per_jiffy = 50000000/HZ; + + /* Setup PCI host bridges */ + adir_find_bridges(); + +#ifdef CONFIG_BLK_DEV_INITRD + if (initrd_start) + ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); /* /dev/ram */ + else +#endif +#ifdef CONFIG_ROOT_NFS + ROOT_DEV = to_kdev_t(0x00FF); /* /dev/nfs pseudo device */ +#else + ROOT_DEV = to_kdev_t(0x0801); /* /dev/sda1 */ +#endif + + /* Identify the system */ + printk("System Identification: SBS Adirondack - PowerPC 750CXe @ %d Mhz\n", adir_get_cpu_speed()/1000000); + printk("SBS Adirondack port (C) 2001 SBS Technologies, Inc.\n"); + + /* Identify the CPU manufacturer */ + cpu = mfspr(PVR); + printk("CPU manufacturer: IBM [rev=%04x]\n", (cpu & 0xffff)); +} + +static void +adir_restart(char *cmd) +{ + __cli(); + /* SRR0 has system reset vector, SRR1 has default MSR value */ + /* rfi restores MSR from SRR1 and sets the PC to the SRR0 value */ + __asm__ __volatile__ + ("lis 3,0xfff0\n\t" + "ori 3,3,0x0100\n\t" + "mtspr 26,3\n\t" + "li 3,0\n\t" + "mtspr 27,3\n\t" + "rfi\n\t"); + for(;;); +} + +static void +adir_power_off(void) +{ + for(;;); +} + +static void +adir_halt(void) +{ + adir_restart(NULL); +} + +extern unsigned int boot_mem_size; + +static unsigned long __init +adir_find_end_of_memory(void) +{ + return boot_mem_size; +} + +static void __init +adir_map_io(void) +{ + io_block_mapping(ADIR_PCI32_VIRT_IO_BASE, ADIR_PCI32_IO_BASE, + ADIR_PCI32_VIRT_IO_SIZE, _PAGE_IO); + io_block_mapping(ADIR_PCI64_VIRT_IO_BASE, ADIR_PCI64_IO_BASE, + ADIR_PCI64_VIRT_IO_SIZE, _PAGE_IO); +} + +void __init +platform_init(unsigned long r3, unsigned long r4, unsigned long r5, + unsigned long r6, unsigned long r7) +{ + /* + * On the Adirondack we use bi_recs and pass the pointer to them in R3. + */ + parse_bootinfo((struct bi_record *) (r3 + KERNELBASE)); + + /* Remember, isa_io_base is virtual but isa_mem_base is physical! */ + isa_io_base = ADIR_PCI32_VIRT_IO_BASE; + isa_mem_base = ADIR_PCI32_MEM_BASE; + pci_dram_offset = ADIR_PCI_SYS_MEM_BASE; + + ppc_md.setup_arch = adir_setup_arch; + ppc_md.show_cpuinfo = adir_show_cpuinfo; + ppc_md.irq_cannonicalize = NULL; + ppc_md.init_IRQ = adir_init_IRQ; + ppc_md.get_irq = adir_get_irq; + ppc_md.init = NULL; + + ppc_md.find_end_of_memory = adir_find_end_of_memory; + ppc_md.setup_io_mappings = adir_map_io; + + ppc_md.restart = adir_restart; + ppc_md.power_off = adir_power_off; + ppc_md.halt = adir_halt; + + ppc_md.time_init = todc_time_init; + ppc_md.set_rtc_time = todc_set_rtc_time; + ppc_md.get_rtc_time = todc_get_rtc_time; + ppc_md.nvram_read_val = todc_mc146818_read_val; + ppc_md.nvram_write_val = todc_mc146818_write_val; + ppc_md.calibrate_decr = adir_calibrate_decr; +} diff --git a/arch/ppc/kernel/apus_pci.c b/arch/ppc/platforms/apus_pci.c index 95367ff771f5..6f7641ed60eb 100644 --- a/arch/ppc/kernel/apus_pci.c +++ b/arch/ppc/platforms/apus_pci.c @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.apus_pci.c 1.5 09/08/01 15:47:42 paulus + * BK Id: %F% %I% %G% %U% %#% */ /* * Copyright (C) Michel Dänzer <michdaen@iiic.ethz.ch> @@ -20,6 +20,7 @@ #include <linux/pci.h> #include <linux/delay.h> #include <linux/string.h> +#include <linux/init.h> #include <asm/io.h> #include <asm/pci-bridge.h> diff --git a/arch/ppc/kernel/apus_pci.h b/arch/ppc/platforms/apus_pci.h index c245dcfce835..2b352b11cd2b 100644 --- a/arch/ppc/kernel/apus_pci.h +++ b/arch/ppc/platforms/apus_pci.h @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.apus_pci.h 1.4 05/17/01 18:14:21 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * Phase5 CybervisionPPC (TVP4020) definitions for the Permedia2 framebuffer @@ -16,9 +16,6 @@ #define APUS_PCI_H -#include "pci.h" - - #define CSPPC_PCI_BRIDGE 0xfffe0000 #define CSPPC_BRIDGE_ENDIAN 0x0000 #define CSPPC_BRIDGE_INT 0x0010 diff --git a/arch/ppc/kernel/apus_setup.c b/arch/ppc/platforms/apus_setup.c index c3fe77cde972..a7904e35fb4c 100644 --- a/arch/ppc/kernel/apus_setup.c +++ b/arch/ppc/platforms/apus_setup.c @@ -1,8 +1,8 @@ /* - * BK Id: SCCS/s.apus_setup.c 1.24 11/13/01 21:26:07 paulus + * BK Id: %F% %I% %G% %U% %#% */ /* - * linux/arch/ppc/kernel/apus_setup.c + * arch/ppc/platforms/apus_setup.c * * Copyright (C) 1998, 1999 Jesper Skov * @@ -17,74 +17,36 @@ */ #include <linux/config.h> -#include <linux/types.h> #include <linux/kernel.h> #include <linux/sched.h> -#include <linux/kd.h> #include <linux/init.h> -#include <linux/hdreg.h> #include <linux/blk.h> -#include <linux/pci.h> #include <linux/seq_file.h> -#ifdef CONFIG_APUS -#include <asm/logging.h> -#endif - /* Needs INITSERIAL call in head.S! */ #undef APUS_DEBUG - -#include <linux/ide.h> -#define T_CHAR (0x0000) /* char: don't touch */ -#define T_SHORT (0x4000) /* short: 12 -> 21 */ -#define T_INT (0x8000) /* int: 1234 -> 4321 */ -#define T_TEXT (0xc000) /* text: 12 -> 21 */ - -#define T_MASK_TYPE (0xc000) -#define T_MASK_COUNT (0x3fff) - -#define D_CHAR(cnt) (T_CHAR | (cnt)) -#define D_SHORT(cnt) (T_SHORT | (cnt)) -#define D_INT(cnt) (T_INT | (cnt)) -#define D_TEXT(cnt) (T_TEXT | (cnt)) - -static u_short driveid_types[] = { - D_SHORT(10), /* config - vendor2 */ - D_TEXT(20), /* serial_no */ - D_SHORT(3), /* buf_type, buf_size - ecc_bytes */ - D_TEXT(48), /* fw_rev - model */ - D_CHAR(2), /* max_multsect - vendor3 */ - D_SHORT(1), /* dword_io */ - D_CHAR(2), /* vendor4 - capability */ - D_SHORT(1), /* reserved50 */ - D_CHAR(4), /* vendor5 - tDMA */ - D_SHORT(4), /* field_valid - cur_sectors */ - D_INT(1), /* cur_capacity */ - D_CHAR(2), /* multsect - multsect_valid */ - D_INT(1), /* lba_capacity */ - D_SHORT(194) /* dma_1word - reservedyy */ -}; - -#define num_driveid_types (sizeof(driveid_types)/sizeof(*driveid_types)) - #include <asm/bootinfo.h> #include <asm/setup.h> #include <asm/amigahw.h> #include <asm/amigaints.h> #include <asm/amigappc.h> #include <asm/pgtable.h> -#include <asm/io.h> #include <asm/dma.h> #include <asm/machdep.h> - -#include "local_irq.h" +#include <asm/keyboard.h> +#include <asm/time.h> unsigned long m68k_machtype; char debug_device[6] = ""; extern void amiga_init_IRQ(void); +extern int amiga_kbd_translate(unsigned char keycode, unsigned char *keycodep, char raw_mode); +extern char amiga_sysrq_xlate[128]; + +extern void apus_setup_pci_ptrs(void); + void (*mach_sched_init) (void (*handler)(int, void *, struct pt_regs *)) __initdata = NULL; /* machine dependent keyboard functions */ int (*mach_keyb_init) (void) __initdata = NULL; @@ -135,7 +97,7 @@ static int __bus_speed = 0; static int __speed_test_failed = 0; /********************************************** COMPILE PROTECTION */ -/* Provide some stubs that links to Amiga specific functions. +/* Provide some stubs that links to Amiga specific functions. * This allows CONFIG_APUS to be removed from generic PPC files while * preventing link errors for other PPC targets. */ @@ -143,7 +105,7 @@ unsigned long apus_get_rtc_time(void) { #ifdef CONFIG_APUS extern unsigned long m68k_get_rtc_time(void); - + return m68k_get_rtc_time (); #else return 0; @@ -161,46 +123,6 @@ int apus_set_rtc_time(unsigned long nowtime) #endif } - - -/* Here some functions we don't support, but which the other ports reference */ -int pckbd_setkeycode(unsigned int scancode, unsigned int keycode) -{ - printk("Bogus call to " __FILE__ ":" __FUNCTION__ "\n"); - return 0; -} -int pckbd_getkeycode(unsigned int scancode) -{ - printk("Bogus call to " __FILE__ ":" __FUNCTION__ "\n"); - return 0; -} -int pckbd_translate(unsigned char scancode, unsigned char *keycode, - char raw_mode) -{ - printk("Bogus call to " __FILE__ ":" __FUNCTION__ "\n"); - return 0; -} -char pckbd_unexpected_up(unsigned char keycode) -{ - printk("Bogus call to " __FILE__ ":" __FUNCTION__ "\n"); - return 0; -} -void pckbd_leds(unsigned char leds) -{ - printk("Bogus call to " __FILE__ ":" __FUNCTION__ "\n"); -} -void pckbd_init_hw(void) -{ - printk("Bogus call to " __FILE__ ":" __FUNCTION__ "\n"); -} -unsigned char pckbd_sysrq_xlate[128]; - -struct pci_bus * __init pci_scan_peer_bridge(int bus) -{ - printk("Bogus call to " __FILE__ ":" __FUNCTION__ "\n"); - return NULL; -} - /*********************************************************** SETUP */ /* From arch/m68k/kernel/setup.c. */ void __init apus_setup_arch(void) @@ -224,7 +146,7 @@ void __init apus_setup_arch(void) if ((q = strchr( debug_device, ' ' ))) *q = 0; i = 1; } else if (!strncmp( p, "60nsram", 7 )) { - APUS_WRITE (APUS_REG_WAITSTATE, + APUS_WRITE (APUS_REG_WAITSTATE, REGWAITSTATE_SETRESET |REGWAITSTATE_PPCR |REGWAITSTATE_PPCW); @@ -288,7 +210,7 @@ static void get_current_tb(unsigned long long *time) " bne 1b \n\t" " stw 4,0(%0)\n\t" " stw 5,4(%0)\n\t" - : + : : "r" (time) : "r4", "r5", "r6"); } @@ -397,7 +319,7 @@ void kbd_reset_setup(char *str, int *ints) /*********************************************************** FLOPPY */ #if defined(CONFIG_AMIGA_FLOPPY) -__init +__init void floppy_setup(char *str, int *ints) { if (mach_floppy_setup) @@ -418,7 +340,7 @@ static __inline__ pte_t *my_find_pte(struct mm_struct *mm,unsigned long va) pte_t *pte = 0; va &= PAGE_MASK; - + dir = pgd_offset( mm, va ); if (dir) { @@ -449,11 +371,11 @@ void kernel_set_cachemode( unsigned long address, unsigned long size, flags = (_PAGE_NO_CACHE | _PAGE_GUARDED); break; default: - panic ("kernel_set_cachemode() doesn't support mode %d\n", + panic ("kernel_set_cachemode() doesn't support mode %d\n", cmode); break; } - + size /= PAGE_SIZE; address &= PAGE_MASK; while (size--) @@ -493,7 +415,7 @@ unsigned long mm_ptov (unsigned long paddr) goto exit; } } - + ret = (unsigned long) __va(paddr); } exit: @@ -545,7 +467,7 @@ void cache_clear(__u32 addr, int length) "icbi 0,%0 \n\t" "isync \n\t" : : "r" (addr)); - + addr += L1_CACHE_BYTES; length -= L1_CACHE_BYTES; @@ -572,11 +494,11 @@ apus_restart(char *cmd) { cli(); - APUS_WRITE(APUS_REG_LOCK, + APUS_WRITE(APUS_REG_LOCK, REGLOCK_BLACKMAGICK1|REGLOCK_BLACKMAGICK2); - APUS_WRITE(APUS_REG_LOCK, + APUS_WRITE(APUS_REG_LOCK, REGLOCK_BLACKMAGICK1|REGLOCK_BLACKMAGICK3); - APUS_WRITE(APUS_REG_LOCK, + APUS_WRITE(APUS_REG_LOCK, REGLOCK_BLACKMAGICK2|REGLOCK_BLACKMAGICK3); APUS_WRITE(APUS_REG_SHADOW, REGSHADOW_SELFRESET); APUS_WRITE(APUS_REG_RESET, REGRESET_AMIGARESET); @@ -595,180 +517,49 @@ apus_halt(void) apus_restart(NULL); } -/****************************************************** from setup.c/IDE */ -#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) -/* - * IDE stuff. - */ - -#if 0 /* no longer used -- paulus */ -void -apus_ide_fix_driveid(struct hd_driveid *id) -{ - u_char *p = (u_char *)id; - int i, j, cnt; - u_char t; - - if (!MACH_IS_AMIGA && !MACH_IS_MAC) - return; - for (i = 0; i < num_driveid_types; i++) { - cnt = driveid_types[i] & T_MASK_COUNT; - switch (driveid_types[i] & T_MASK_TYPE) { - case T_CHAR: - p += cnt; - break; - case T_SHORT: - for (j = 0; j < cnt; j++) { - t = p[0]; - p[0] = p[1]; - p[1] = t; - p += 2; - } - break; - case T_INT: - for (j = 0; j < cnt; j++) { - t = p[0]; - p[0] = p[3]; - p[3] = t; - t = p[1]; - p[1] = p[2]; - p[2] = t; - p += 4; - } - break; - case T_TEXT: - for (j = 0; j < cnt; j += 2) { - t = p[0]; - p[0] = p[1]; - p[1] = t; - p += 2; - } - break; - } - } -} -#endif /* 0 */ - -__init -void apus_ide_init_hwif_ports (hw_regs_t *hw, ide_ioreg_t data_port, - ide_ioreg_t ctrl_port, int *irq) -{ - if (data_port || ctrl_port) - printk("apus_ide_init_hwif_ports: must not be called\n"); -} -#endif /****************************************************** IRQ stuff */ -static unsigned int apus_irq_cannonicalize(unsigned int irq) -{ - return irq; -} - -int show_apus_interrupts(struct seq_file *p, void *v) -{ -#ifdef CONFIG_APUS - extern int show_amiga_interrupts(struct seq_file *p, void *v) - - return show_amiga_interrupts(p, v); -#else - return 0; -#endif -} +static unsigned char last_ipl[8]; -/* IPL must be between 0 and 7 */ -static inline void apus_set_IPL(unsigned long ipl) -{ - APUS_WRITE(APUS_IPL_EMU, IPLEMU_SETRESET | IPLEMU_DISABLEINT); - APUS_WRITE(APUS_IPL_EMU, IPLEMU_IPLMASK); - APUS_WRITE(APUS_IPL_EMU, IPLEMU_SETRESET | ((~ipl) & IPLEMU_IPLMASK)); - APUS_WRITE(APUS_IPL_EMU, IPLEMU_DISABLEINT); -} - -static inline unsigned long apus_get_IPL(void) -{ - /* This returns the present IPL emulation level. */ - unsigned long __f; - APUS_READ(APUS_IPL_EMU, __f); - return ((~__f) & IPLEMU_IPLMASK); -} - -static inline unsigned long apus_get_prev_IPL(struct pt_regs* regs) -{ - /* The value saved in mq is the IPL_EMU value at the time of - interrupt. The lower bits are the current interrupt level, - the upper bits the requested level. Thus, to restore the - IPL level to the post-interrupt state, we will need to use - the lower bits. */ - unsigned long __f = regs->mq; - return ((~__f) & IPLEMU_IPLMASK); -} - - -#ifdef CONFIG_APUS -void free_irq(unsigned int irq, void *dev_id) +int apus_get_irq(struct pt_regs* regs) { - extern void amiga_free_irq(unsigned int irq, void *dev_id); + unsigned char ipl_emu, mask; + unsigned int level; - amiga_free_irq (irq, dev_id); -} + APUS_READ(APUS_IPL_EMU, ipl_emu); + level = (ipl_emu >> 3) & IPLEMU_IPLMASK; + mask = IPLEMU_SETRESET|IPLEMU_DISABLEINT|level; + level ^= 7; -int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *), - unsigned long irqflags, const char * devname, void *dev_id) -{ - extern int amiga_request_irq(unsigned int irq, - void (*handler)(int, void *, - struct pt_regs *), - unsigned long flags, - const char *devname, - void *dev_id); - - return amiga_request_irq (irq, handler, irqflags, devname, dev_id); -} + /* Save previous IPL value */ + if (last_ipl[level]) + return -2; + last_ipl[level] = ipl_emu; -/* In Linux/m68k the sys_request_irq deals with vectors 0-7. That's what - callers expect - but on Linux/APUS we actually use the IRQ_AMIGA_AUTO - vectors (24-31), so we put this dummy function in between to adjust - the vector argument (rather have cruft here than in the generic irq.c). */ -int sys_request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *), - unsigned long irqflags, const char * devname, void *dev_id) -{ - extern int request_sysirq(unsigned int irq, - void (*handler)(int, void *, - struct pt_regs *), - unsigned long irqflags, - const char * devname, void *dev_id); - return request_sysirq(irq+IRQ_AMIGA_AUTO, handler, irqflags, - devname, dev_id); -} -#endif + /* Set to current IPL value */ + APUS_WRITE(APUS_IPL_EMU, mask); + APUS_WRITE(APUS_IPL_EMU, IPLEMU_DISABLEINT|level); -int apus_get_irq(struct pt_regs* regs) -{ -#ifdef CONFIG_APUS - int level = apus_get_IPL(); #ifdef __INTERRUPT_DEBUG - printk("<%d:%d>", level, apus_get_prev_IPL(regs)); + printk("<%d:%d>", level, ~ipl_emu & IPLEMU_IPLMASK); #endif - - if (0 == level) - return -8; - if (7 == level) - return -9; - return level + IRQ_AMIGA_AUTO; -#else - return 0; -#endif } -void apus_post_irq(struct pt_regs* regs, int level) +void apus_end_irq(unsigned int irq) { + unsigned char ipl_emu; + unsigned int level = irq - IRQ_AMIGA_AUTO; #ifdef __INTERRUPT_DEBUG - printk("{%d}", apus_get_prev_IPL(regs)); + printk("{%d}", ~last_ipl[level] & IPLEMU_IPLMASK); #endif /* Restore IPL to the previous value */ - apus_set_IPL(apus_get_prev_IPL(regs)); + ipl_emu = last_ipl[level] & IPLEMU_IPLMASK; + APUS_WRITE(APUS_IPL_EMU, IPLEMU_SETRESET|IPLEMU_DISABLEINT|ipl_emu); + last_ipl[level] = 0; + ipl_emu ^= 7; + APUS_WRITE(APUS_IPL_EMU, IPLEMU_DISABLEINT|ipl_emu); } /****************************************************** keyboard */ @@ -782,22 +573,11 @@ static int apus_kbd_getkeycode(unsigned int scancode) return scancode > 127 ? -EINVAL : scancode; } -static int apus_kbd_translate(unsigned char keycode, unsigned char *keycodep, - char raw_mode) -{ - *keycodep = keycode; - return 1; -} - static char apus_kbd_unexpected_up(unsigned char keycode) { return 0200; } -static void apus_kbd_leds(unsigned char leds) -{ -} - static void apus_kbd_init_hw(void) { #ifdef CONFIG_APUS @@ -853,9 +633,9 @@ unsigned char __debug_ser_in( void ) } int __debug_serinit( void ) -{ +{ unsigned long flags; - + save_flags (flags); cli(); @@ -873,7 +653,7 @@ int __debug_serinit( void ) */ ciab.ddra |= (SER_DTR | SER_RTS); /* outputs */ ciab.ddra &= ~(SER_DCD | SER_CTS | SER_DSR); /* inputs */ - + #ifdef CONFIG_KGDB /* turn Rx interrupts on for GDB */ custom.intena = IF_SETCLR | IF_RBF; @@ -915,40 +695,21 @@ static void apus_progress(char *s, unsigned short value) /* The number of spurious interrupts */ volatile unsigned int num_spurious; -#define NUM_IRQ_NODES 100 -static irq_node_t nodes[NUM_IRQ_NODES]; - -extern void (*amiga_default_handler[AUTO_IRQS])(int, void *, struct pt_regs *); +extern struct irqaction amiga_sys_irqaction[AUTO_IRQS]; -static const char *default_names[SYS_IRQS] = { - "spurious int", "int1 handler", "int2 handler", "int3 handler", - "int4 handler", "int5 handler", "int6 handler", "int7 handler" -}; - -irq_node_t *new_irq_node(void) -{ - irq_node_t *node; - short i; - - for (node = nodes, i = NUM_IRQ_NODES-1; i >= 0; node++, i--) - if (!node->handler) - return node; - - printk ("new_irq_node: out of nodes\n"); - return NULL; -} extern void amiga_enable_irq(unsigned int irq); extern void amiga_disable_irq(unsigned int irq); +struct hw_interrupt_type amiga_sys_irqctrl = { + typename: "Amiga IPL", + end: apus_end_irq, +}; + struct hw_interrupt_type amiga_irqctrl = { - " Amiga ", - NULL, - NULL, - amiga_enable_irq, - amiga_disable_irq, - 0, - 0 + typename: "Amiga ", + enable: amiga_enable_irq, + disable: amiga_disable_irq, }; #define HARDWARE_MAPPED_SIZE (512*1024) @@ -981,6 +742,8 @@ unsigned long __init apus_find_end_of_memory(void) memory[0].size = ((size+0x001fffff) & 0xffe00000); } + ppc_memstart = memory[0].addr; + ppc_memoffset = PAGE_OFFSET - PPC_MEMSTART; total = memory[0].size; /* Remove the memory chunks that are controlled by special @@ -1001,7 +764,6 @@ unsigned long __init apus_find_end_of_memory(void) the PowerUP board. Other system memory is horrible slow in comparison. The user can use other memory for swapping using the z2ram device. */ - ram_phys_base = memory[0].addr; return total; } @@ -1017,18 +779,23 @@ apus_map_io(void) __init void apus_init_IRQ(void) { + struct irqaction *action; int i; - for ( i = 0 ; i < NR_IRQS ; i++ ) - irq_desc[i].handler = &amiga_irqctrl; - - for (i = 0; i < NUM_IRQ_NODES; i++) - nodes[i].handler = NULL; +#ifdef CONFIG_PCI + apus_setup_pci_ptrs(); +#endif - for (i = 0; i < AUTO_IRQS; i++) { - if (amiga_default_handler[i] != NULL) - sys_request_irq(i, amiga_default_handler[i], - 0, default_names[i], NULL); + for ( i = 0 ; i < AMI_IRQS; i++ ) { + irq_desc[i].status = IRQ_LEVEL; + if (i < IRQ_AMIGA_AUTO) { + irq_desc[i].handler = &amiga_irqctrl; + } else { + irq_desc[i].handler = &amiga_sys_irqctrl; + action = &amiga_sys_irqaction[i-IRQ_AMIGA_AUTO]; + if (action->name) + setup_irq(i, action); + } } amiga_init_IRQ(); @@ -1041,7 +808,7 @@ void platform_init(unsigned long r3, unsigned long r4, unsigned long r5, { extern int parse_bootinfo(const struct bi_record *); extern char _end[]; - + /* Parse bootinfo. The bootinfo is located right after the kernel bss */ parse_bootinfo((const struct bi_record *)&_end); @@ -1051,7 +818,7 @@ void platform_init(unsigned long r3, unsigned long r4, unsigned long r5, registers when kernel is booted via a PPC reset. */ if ( ramdisk.addr ) { initrd_start = (unsigned long) __va(ramdisk.addr); - initrd_end = (unsigned long) + initrd_end = (unsigned long) __va(ramdisk.size + ramdisk.addr); } #endif /* CONFIG_BLK_DEV_INITRD */ @@ -1060,13 +827,9 @@ void platform_init(unsigned long r3, unsigned long r4, unsigned long r5, ppc_md.setup_arch = apus_setup_arch; ppc_md.show_cpuinfo = apus_show_cpuinfo; - ppc_md.irq_cannonicalize = apus_irq_cannonicalize; ppc_md.init_IRQ = apus_init_IRQ; ppc_md.get_irq = apus_get_irq; - -#error Should use the ->end() member of irq_desc[x]. -- Cort - /*ppc_md.post_irq = apus_post_irq;*/ - + #ifdef CONFIG_HEARTBEAT ppc_md.heartbeat = apus_heartbeat; ppc_md.heartbeat_count = 1; @@ -1089,25 +852,15 @@ void platform_init(unsigned long r3, unsigned long r4, unsigned long r5, ppc_md.find_end_of_memory = apus_find_end_of_memory; ppc_md.setup_io_mappings = apus_map_io; - ppc_md.nvram_read_val = NULL; - ppc_md.nvram_write_val = NULL; - /* These should not be used for the APUS yet, since it uses the M68K keyboard now. */ ppc_md.kbd_setkeycode = apus_kbd_setkeycode; ppc_md.kbd_getkeycode = apus_kbd_getkeycode; - ppc_md.kbd_translate = apus_kbd_translate; + ppc_md.kbd_translate = amiga_kbd_translate; ppc_md.kbd_unexpected_up = apus_kbd_unexpected_up; - ppc_md.kbd_leds = apus_kbd_leds; ppc_md.kbd_init_hw = apus_kbd_init_hw; - -#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) - ppc_ide_md.ide_init_hwif = apus_ide_init_hwif_ports; -#endif -} - - -/*************************************************** coexistence */ -void __init adbdev_init(void) -{ +#ifdef CONFIG_SYSRQ + ppc_md.ppc_kbd_sysrq_xlate = amiga_sysrq_xlate; + SYSRQ_KEY = 0xff; +#endif } diff --git a/arch/ppc/platforms/ash.c b/arch/ppc/platforms/ash.c new file mode 100644 index 000000000000..3575a65e2ed1 --- /dev/null +++ b/arch/ppc/platforms/ash.c @@ -0,0 +1,108 @@ +/* + * + * Copyright 2001 MontaVista Software Inc. + * <akuster@mvista.com> + * IBM NP405H ash eval board + * + */ +#include <linux/config.h> +#include <linux/init.h> +#include <linux/pagemap.h> +#include <linux/pci.h> + +#include <asm/machdep.h> +#include <asm/pci-bridge.h> +#include <asm/io.h> + +#ifdef CONFIG_PPC_RTC +#include <asm/todc.h> +#endif + +void *ash_rtc_base; + +/* Some IRQs unique to Walnut. + * Used by the generic 405 PCI setup functions in ppc4xx_pci.c + */ +int __init +ppc405_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) +{ + static char pci_irq_table[][4] = + /* + * PCI IDSEL/INTPIN->INTLINE + * A B C D + */ + { + {28, 28, 28, 28}, /* IDSEL 1 - PCI slot 1 */ + {29, 29, 29, 29}, /* IDSEL 2 - PCI slot 2 */ + {30, 30, 30, 30}, /* IDSEL 3 - PCI slot 3 */ + {31, 31, 31, 31}, /* IDSEL 4 - PCI slot 4 */ + }; + + const long min_idsel = 1, max_idsel = 4, irqs_per_slot = 4; + return PCI_IRQ_TABLE_LOOKUP; +}; + +void __init +board_setup_arch(void) +{ + + bd_t *bip = (bd_t *)__res; + +#ifdef CONFIG_PPC_RTC + /* RTC step for the walnut */ + ash_rtc_base = (void *) ASH_RTC_VADDR; + TODC_INIT(TODC_TYPE_DS1743, ash_rtc_base, ash_rtc_base,ash_rtc_base, 8); +#endif /* CONFIG_PPC_RTC */ +#define CONFIG_DEBUG_BRINGUP +#ifdef CONFIG_DEBUG_BRINGUP + printk("\n"); + printk("machine\t: %s\n", PPC4xx_MACHINE_NAME); + printk("\n"); + printk("bi_s_version\t %s\n", bip->bi_s_version); + printk("bi_r_version\t %s\n", bip->bi_r_version); + printk("bi_memsize\t 0x%8.8x\t %dMBytes\n", bip->bi_memsize,bip->bi_memsize/(1024*1000)); + printk("bi_enetaddr %d\t %2.2x%2.2x%2.2x-%2.2x%2.2x%2.2x\n", 0, + bip->bi_enetaddr[0][0], bip->bi_enetaddr[0][1], + bip->bi_enetaddr[0][2], bip->bi_enetaddr[0][3], + bip->bi_enetaddr[0][4], bip->bi_enetaddr[0][5]); + + printk("bi_enetaddr %d\t %2.2x%2.2x%2.2x-%2.2x%2.2x%2.2x\n", 1, + bip->bi_enetaddr[1][0], bip->bi_enetaddr[1][1], + bip->bi_enetaddr[1][2], bip->bi_enetaddr[1][3], + bip->bi_enetaddr[1][4], bip->bi_enetaddr[1][5]); + + printk("bi_intfreq\t 0x%8.8x\t clock:\t %dMhz\n", + bip->bi_intfreq, bip->bi_intfreq/ 1000000); + + printk("bi_busfreq\t 0x%8.8x\t plb bus clock:\t %dMHz\n", + bip->bi_busfreq, bip->bi_busfreq / 1000000 ); + printk("bi_pci_busfreq\t 0x%8.8x\t pci bus clock:\t %dMHz\n", + bip->bi_pci_busfreq, bip->bi_pci_busfreq/1000000); + + printk("\n"); +#endif +} + +void __init +board_io_mapping(void) +{ + io_block_mapping(ASH_RTC_VADDR, + ASH_RTC_PADDR, ASH_RTC_SIZE, _PAGE_IO); +} +void __init +board_setup_irq(void) +{ + +} + +void __init +board_init(void) +{ +#ifdef CONFIG_PPC_RTC + ppc_md.time_init = todc_time_init; + ppc_md.set_rtc_time = todc_set_rtc_time; + ppc_md.get_rtc_time = todc_get_rtc_time; + ppc_md.nvram_read_val = todc_direct_read_val; + ppc_md.nvram_write_val = todc_direct_write_val; +#endif +} diff --git a/arch/ppc/platforms/ash.h b/arch/ppc/platforms/ash.h new file mode 100644 index 000000000000..8c9b64b8b741 --- /dev/null +++ b/arch/ppc/platforms/ash.h @@ -0,0 +1,86 @@ +/* + * + * + * Copyright 2000 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * akuster@mvista.com or source@mvista.com + * + * Module name: ash.h + * + * Description: + * Macros, definitions, and data structures specific to the IBM PowerPC + * Ash eval board. + * + * + */ + +#ifdef __KERNEL__ +#ifndef __ASM_ASH_H__ +#define __ASM_ASH_H__ +#include <platforms/ibm_ocp.h> +#include <platforms/ibmnp405h.h> + +#ifndef __ASSEMBLY__ +/* + * Data structure defining board information maintained by the boot + * ROM on IBM's "Ash" evaluation board. An effort has been made to + * keep the field names consistent with the 8xx 'bd_t' board info + * structures. + */ + +typedef struct board_info { + unsigned char bi_s_version[4]; /* Version of this structure */ + unsigned char bi_r_version[30]; /* Version of the IBM ROM */ + unsigned int bi_memsize; /* DRAM installed, in bytes */ + unsigned char bi_enetaddr[EMAC_NUMS][6]; /* Local Ethernet MAC address */ + unsigned char bi_pci_enetaddr[6]; + unsigned int bi_intfreq; /* Processor speed, in Hz */ + unsigned int bi_busfreq; /* PLB Bus speed, in Hz */ + unsigned int bi_pci_busfreq; /* PCI speed in Hz */ +} bd_t; + +/* Some 4xx parts use a different timebase frequency from the internal clock. +*/ +#define bi_tbfreq bi_intfreq + +/* Memory map for the IBM "Ash" NP405H evaluation board. + */ + +extern void *ash_rtc_base; +#define ASH_RTC_PADDR ((uint)0xf0000000) +#define ASH_RTC_VADDR ASH_RTC_PADDR +#define ASH_RTC_SIZE ((uint)8*1024) + + +/* Early initialization address mapping for block_io. + * Standard 405GP map. + */ +#define PPC4xx_PCI_IO_PADDR ((uint)PPC405_PCI_PHY_IO_BASE) +#define PPC4xx_PCI_IO_VADDR PPC4xx_PCI_IO_PADDR +#define PPC4xx_PCI_IO_SIZE ((uint)64*1024) +#define PPC4xx_PCI_CFG_PADDR ((uint)PPC405_PCI_CONFIG_ADDR) +#define PPC4xx_PCI_CFG_VADDR PPC4xx_PCI_CFG_PADDR +#define PPC4xx_PCI_CFG_SIZE ((uint)4*1024) +#define PPC4xx_PCI_LCFG_PADDR ((uint)0xef400000) +#define PPC4xx_PCI_LCFG_VADDR PPC4xx_PCI_LCFG_PADDR +#define PPC4xx_PCI_LCFG_SIZE ((uint)4*1024) +#define PPC4xx_ONB_IO_PADDR ((uint)0xef600000) +#define PPC4xx_ONB_IO_VADDR PPC4xx_ONB_IO_PADDR +#define PPC4xx_ONB_IO_SIZE ((uint)4*1024) + +#define NR_BOARD_IRQS 32 + +#ifdef CONFIG_PPC405GP_INTERNAL_CLOCK +#define BASE_BAUD 201600 +#else +#define BASE_BAUD 691200 +#endif + +#define PPC4xx_MACHINE_NAME "IBM NP405H Ceder" + +extern char pci_irq_table[][4]; + + +#endif /* !__ASSEMBLY__ */ +#endif /* __ASM_ASH_H__ */ +#endif /* __KERNEL__ */ diff --git a/arch/ppc/platforms/bseip.h b/arch/ppc/platforms/bseip.h new file mode 100644 index 000000000000..01339f761085 --- /dev/null +++ b/arch/ppc/platforms/bseip.h @@ -0,0 +1,42 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ + +/* + * A collection of structures, addresses, and values associated with + * the Bright Star Engineering ip-Engine board. Copied from the MBX stuff. + * + * Copyright (c) 1998 Dan Malek (dmalek@jlc.net) + */ +#ifndef __MACH_BSEIP_DEFS +#define __MACH_BSEIP_DEFS + +#ifndef __ASSEMBLY__ +/* A Board Information structure that is given to a program when + * prom starts it up. + */ +typedef struct bd_info { + unsigned int bi_memstart; /* Memory start address */ + unsigned int bi_memsize; /* Memory (end) size in bytes */ + unsigned int bi_intfreq; /* Internal Freq, in Hz */ + unsigned int bi_busfreq; /* Bus Freq, in Hz */ + unsigned char bi_enetaddr[6]; + unsigned int bi_baudrate; +} bd_t; + +extern bd_t m8xx_board_info; + +/* Memory map is configured by the PROM startup. + * All we need to get started is the IMMR. + */ +#define IMAP_ADDR ((uint)0xff000000) +#define IMAP_SIZE ((uint)(64 * 1024)) +#define PCMCIA_MEM_ADDR ((uint)0x04000000) +#define PCMCIA_MEM_SIZE ((uint)(64 * 1024)) +#endif /* !__ASSEMBLY__ */ + +/* We don't use the 8259. +*/ +#define NR_8259_INTS 0 + +#endif diff --git a/arch/ppc/platforms/ccm.h b/arch/ppc/platforms/ccm.h new file mode 100644 index 000000000000..8b7f564e64d1 --- /dev/null +++ b/arch/ppc/platforms/ccm.h @@ -0,0 +1,28 @@ +/* + * Siemens Card Controller Module specific definitions + * + * Copyright (c) 2001 Wolfgang Denk (wd@denx.de) + */ + +#ifndef __MACH_CCM_H +#define __MACH_CCM_H + +#include <linux/config.h> + +#include <asm/ppcboot.h> + +#define CCM_IMMR_BASE 0xF0000000 /* phys. addr of IMMR */ +#define CCM_IMAP_SIZE (64 * 1024) /* size of mapped area */ + +#define IMAP_ADDR CCM_IMMR_BASE /* physical base address of IMMR area */ +#define IMAP_SIZE CCM_IMAP_SIZE /* mapped size of IMMR area */ + +#define FEC_INTERRUPT 15 /* = SIU_LEVEL7 */ +#define DEC_INTERRUPT 13 /* = SIU_LEVEL6 */ +#define CPM_INTERRUPT 11 /* = SIU_LEVEL5 (was: SIU_LEVEL2) */ + +/* We don't use the 8259. +*/ +#define NR_8259_INTS 0 + +#endif /* __MACH_CCM_H */ diff --git a/arch/ppc/platforms/ceder.c b/arch/ppc/platforms/ceder.c new file mode 100644 index 000000000000..d2fbe0f8ae38 --- /dev/null +++ b/arch/ppc/platforms/ceder.c @@ -0,0 +1,83 @@ +/* + * + * Copyright 2001 MontaVista Software Inc. + * <akuster@mvista.com> + * IBM NP405L ceder eval board + * + */ +#include <linux/config.h> +#include <linux/init.h> +#include <linux/pagemap.h> +#include <asm/machdep.h> + +#include <asm/io.h> + +#ifdef CONFIG_PPC_RTC +#include <asm/todc.h> +#endif + +void *ceder_rtc_base; + +void __init +board_setup_arch(void) +{ + + bd_t *bip = (bd_t *)__res; + +#ifdef CONFIG_PPC_RTC + /* RTC step for the walnut */ + ceder_rtc_base = (void *) CEDER_RTC_VADDR; + TODC_INIT(TODC_TYPE_DS1743, ceder_rtc_base, ceder_rtc_base,ceder_rtc_base, 8); +#endif /* CONFIG_PPC_RTC */ +#define CONFIG_DEBUG_BRINGUP +#ifdef CONFIG_DEBUG_BRINGUP + printk("\n"); + printk("machine\t: %s\n", PPC4xx_MACHINE_NAME); + printk("\n"); + printk("bi_s_version\t %s\n", bip->bi_s_version); + printk("bi_r_version\t %s\n", bip->bi_r_version); + printk("bi_memsize\t 0x%8.8x\t %dMBytes\n", bip->bi_memsize,bip->bi_memsize/(1024*1000)); + printk("bi_enetaddr %d\t %2.2x%2.2x%2.2x-%2.2x%2.2x%2.2x\n", 0, + bip->bi_enetaddr[0][0], bip->bi_enetaddr[0][1], + bip->bi_enetaddr[0][2], bip->bi_enetaddr[0][3], + bip->bi_enetaddr[0][4], bip->bi_enetaddr[0][5]); + + printk("bi_enetaddr %d\t %2.2x%2.2x%2.2x-%2.2x%2.2x%2.2x\n", 1, + bip->bi_enetaddr[1][0], bip->bi_enetaddr[1][1], + bip->bi_enetaddr[1][2], bip->bi_enetaddr[1][3], + bip->bi_enetaddr[1][4], bip->bi_enetaddr[1][5]); + + printk("bi_intfreq\t 0x%8.8x\t clock:\t %dMhz\n", + bip->bi_intfreq, bip->bi_intfreq/ 1000000); + + printk("bi_busfreq\t 0x%8.8x\t plb bus clock:\t %dMHz\n", + bip->bi_busfreq, bip->bi_busfreq / 1000000 ); + printk("bi_pci_busfreq\t 0x%8.8x\t pci bus clock:\t %dMHz\n", + bip->bi_pci_busfreq, bip->bi_pci_busfreq/1000000); + + printk("\n"); +#endif +} + +void __init +board_io_mapping(void) +{ + io_block_mapping(CEDER_RTC_VADDR, + CEDER_RTC_PADDR, CEDER_RTC_SIZE, _PAGE_IO); +} +void __init +board_setup_irq(void) +{ +} + +void __init +board_init(void) +{ +#ifdef CONFIG_PPC_RTC + ppc_md.time_init = todc_time_init; + ppc_md.set_rtc_time = todc_set_rtc_time; + ppc_md.get_rtc_time = todc_get_rtc_time; + ppc_md.nvram_read_val = todc_direct_read_val; + ppc_md.nvram_write_val = todc_direct_write_val; +#endif +} diff --git a/arch/ppc/platforms/ceder.h b/arch/ppc/platforms/ceder.h new file mode 100644 index 000000000000..7430e7247804 --- /dev/null +++ b/arch/ppc/platforms/ceder.h @@ -0,0 +1,85 @@ +/* + * + * + * Copyright 2000 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * akuster@mvista.com or source@mvista.com + * + * Module name: ceder.h + * + * Description: + * Macros, definitions, and data structures specific to the IBM PowerPC + * Ceder eval board. + * + * + */ + +#ifdef __KERNEL__ +#ifndef __ASM_CEDER_H__ +#define __ASM_CEDER_H__ +#include <platforms/ibmnp405l.h> + +#ifndef __ASSEMBLY__ +/* + * Data structure defining board information maintained by the boot + * ROM on IBM's "Ceder" evaluation board. An effort has been made to + * keep the field names consistent with the 8xx 'bd_t' board info + * structures. + */ + +typedef struct board_info { + unsigned char bi_s_version[4]; /* Version of this structure */ + unsigned char bi_r_version[30]; /* Version of the IBM ROM */ + unsigned int bi_memsize; /* DRAM installed, in bytes */ + unsigned char bi_enetaddr[EMAC_NUMS][6]; /* Local Ethernet MAC address */ + unsigned char bi_pci_mac[6]; + unsigned int bi_intfreq; /* Processor speed, in Hz */ + unsigned int bi_busfreq; /* PLB Bus speed, in Hz */ + unsigned int bi_pci_busfreq; /* PCI speed in Hz */ +} bd_t; + +/* Some 4xx parts use a different timebase frequency from the internal clock. +*/ +#define bi_tbfreq bi_intfreq + +/* Memory map for the IBM "Ceder" NP405 evaluation board. + */ + +extern void *ceder_rtc_base; +#define CEDER_RTC_PADDR ((uint)0xf0000000) +#define CEDER_RTC_VADDR CEDER_RTC_PADDR +#define CEDER_RTC_SIZE ((uint)8*1024) + + +/* Early initialization address mapping for block_io. + * Standard 405GP map. + */ +#define PPC4xx_PCI_IO_PADDR ((uint)PPC405_PCI_PHY_IO_BASE) +#define PPC4xx_PCI_IO_VADDR PPC4xx_PCI_IO_PADDR +#define PPC4xx_PCI_IO_SIZE ((uint)64*1024) +#define PPC4xx_PCI_CFG_PADDR ((uint)PPC405_PCI_CONFIG_ADDR) +#define PPC4xx_PCI_CFG_VADDR PPC4xx_PCI_CFG_PADDR +#define PPC4xx_PCI_CFG_SIZE ((uint)4*1024) +#define PPC4xx_PCI_LCFG_PADDR ((uint)0xef400000) +#define PPC4xx_PCI_LCFG_VADDR PPC4xx_PCI_LCFG_PADDR +#define PPC4xx_PCI_LCFG_SIZE ((uint)4*1024) +#define PPC4xx_ONB_IO_PADDR ((uint)0xef600000) +#define PPC4xx_ONB_IO_VADDR PPC4xx_ONB_IO_PADDR +#define PPC4xx_ONB_IO_SIZE ((uint)4*1024) + +#define NR_BOARD_IRQS 32 + +#ifdef CONFIG_PPC405GP_INTERNAL_CLOCK +#define BASE_BAUD 201600 +#else +#define BASE_BAUD 691200 +#endif + +#define PPC4xx_MACHINE_NAME "IBM NP405L Ceder" + +extern char pci_irq_table[][4]; + + +#endif /* !__ASSEMBLY__ */ +#endif /* __ASM_CEDER_H__ */ +#endif /* __KERNEL__ */ diff --git a/arch/ppc/kernel/chrp_pci.c b/arch/ppc/platforms/chrp_pci.c index fae4a2351bf5..61c728cb5f32 100644 --- a/arch/ppc/kernel/chrp_pci.c +++ b/arch/ppc/platforms/chrp_pci.c @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.chrp_pci.c 1.22 09/08/01 15:47:42 paulus + * BK Id: %F% %I% %G% %U% %#% */ /* * CHRP pci routines. @@ -23,9 +23,7 @@ #include <asm/machdep.h> #include <asm/sections.h> #include <asm/pci-bridge.h> - -#include "open_pic.h" -#include "pci.h" +#include <asm/open_pic.h> /* LongTrail */ unsigned long gg2_pci_config_base; @@ -160,39 +158,18 @@ static struct pci_ops rtas_pci_ops = rtas_write_config_dword }; - /* - * Temporary fixes for PCI devices. These should be replaced by OF query - * code -- Geert - */ - -static u_char hydra_openpic_initsenses[] __initdata = { - 1, /* HYDRA_INT_SIO */ - 0, /* HYDRA_INT_SCSI_DMA */ - 0, /* HYDRA_INT_SCCA_TX_DMA */ - 0, /* HYDRA_INT_SCCA_RX_DMA */ - 0, /* HYDRA_INT_SCCB_TX_DMA */ - 0, /* HYDRA_INT_SCCB_RX_DMA */ - 1, /* HYDRA_INT_SCSI */ - 1, /* HYDRA_INT_SCCA */ - 1, /* HYDRA_INT_SCCB */ - 1, /* HYDRA_INT_VIA */ - 1, /* HYDRA_INT_ADB */ - 0, /* HYDRA_INT_ADB_NMI */ - /* all others are 1 (= default) */ -}; - int __init hydra_init(void) { struct device_node *np; np = find_devices("mac-io"); - if (np == NULL || np->n_addrs == 0) { - printk(KERN_WARNING "Warning: no mac-io found\n"); + if (np == NULL || np->n_addrs == 0) return 0; - } Hydra = ioremap(np->addrs[0].address, np->addrs[0].size); printk("Hydra Mac I/O at %x\n", np->addrs[0].address); + printk("Hydra Feature_Control was %x", + in_le32(&Hydra->Feature_Control)); out_le32(&Hydra->Feature_Control, (HYDRA_FC_SCC_CELL_EN | HYDRA_FC_SCSI_CELL_EN | HYDRA_FC_SCCA_ENABLE | @@ -201,9 +178,7 @@ hydra_init(void) HYDRA_FC_MPIC_ENABLE | HYDRA_FC_SLOW_SCC_PCLK | HYDRA_FC_MPIC_IS_MASTER)); - OpenPIC_Addr = &Hydra->OpenPIC; - OpenPIC_InitSenses = hydra_openpic_initsenses; - OpenPIC_NumInitSenses = sizeof(hydra_openpic_initsenses); + printk(", now %x\n", in_le32(&Hydra->Feature_Control)); return 1; } @@ -222,6 +197,29 @@ chrp_pcibios_fixup(void) } } +#define PRG_CL_RESET_VALID 0x00010000 + +static void __init +setup_python(struct pci_controller *hose, struct device_node *dev) +{ + u32 *reg, val; + volatile unsigned char *cfg; + + hose->ops = &python_pci_ops; + cfg = ioremap(dev->addrs[0].address + 0xf8000, 0x20); + hose->cfg_addr = (volatile unsigned int *) cfg; + hose->cfg_data = cfg + 0x10; + + /* Clear the magic go-slow bit */ + reg = (u32 *) ioremap(dev->addrs[0].address + 0xf6000, 0x40); + val = in_be32(®[12]); + if (val & PRG_CL_RESET_VALID) { + out_be32(®[12], val & ~PRG_CL_RESET_VALID); + in_be32(®[12]); + } + iounmap(reg); +} + void __init chrp_find_bridges(void) { @@ -229,16 +227,10 @@ chrp_find_bridges(void) int *bus_range; int len, index = -1; struct pci_controller *hose; - volatile unsigned char *cfg; unsigned int *dma; char *model, *machine; int is_longtrail = 0, is_mot = 0; struct device_node *root = find_path_device("/"); -#ifdef CONFIG_POWER3 - unsigned int *opprop = (unsigned int *) - get_property(root, "platform-open-pic", NULL); - int i; -#endif /* * The PCI host bridge nodes on some machines don't have @@ -290,10 +282,7 @@ chrp_find_bridges(void) if (model == NULL) model = "<none>"; if (device_is_compatible(dev, "IBM,python")) { - hose->ops = &python_pci_ops; - cfg = ioremap(dev->addrs[0].address + 0xf8000, 0x20); - hose->cfg_addr = (volatile unsigned int *) cfg; - hose->cfg_data = cfg + 0x10; + setup_python(hose, dev); } else if (is_mot || strncmp(model, "Motorola, Grackle", 17) == 0) { setup_grackle(hose); @@ -309,13 +298,6 @@ chrp_find_bridges(void) pci_process_bridge_OF_ranges(hose, dev, index == 0); -#ifdef CONFIG_POWER3 - if (opprop != NULL) { - i = prom_n_addr_cells(root) * (index + 2) - 1; - openpic_setup_ISU(index, opprop[i]); - } -#endif /* CONFIG_POWER3 */ - /* check the first bridge for a property that we can use to set pci_dram_offset */ dma = (unsigned int *) diff --git a/arch/ppc/kernel/chrp_setup.c b/arch/ppc/platforms/chrp_setup.c index 6fd574cbae84..2c3f40d0b81d 100644 --- a/arch/ppc/kernel/chrp_setup.c +++ b/arch/ppc/platforms/chrp_setup.c @@ -1,8 +1,8 @@ /* - * BK Id: SCCS/s.chrp_setup.c 1.38 11/13/01 21:26:07 paulus + * BK Id: %F% %I% %G% %U% %#% */ /* - * linux/arch/ppc/kernel/setup.c + * arch/ppc/platforms/setup.c * * Copyright (C) 1995 Linus Torvalds * Adapted from 'alpha' version by Gary Thomas @@ -29,18 +29,16 @@ #include <linux/interrupt.h> #include <linux/reboot.h> #include <linux/init.h> -#include <linux/blk.h> -#include <linux/ioport.h> -#include <linux/console.h> #include <linux/pci.h> #include <linux/version.h> #include <linux/adb.h> #include <linux/module.h> #include <linux/delay.h> #include <linux/ide.h> +#include <linux/irq.h> +#include <linux/console.h> #include <linux/seq_file.h> -#include <asm/mmu.h> #include <asm/processor.h> #include <asm/io.h> #include <asm/pgtable.h> @@ -55,11 +53,8 @@ #include <asm/sections.h> #include <asm/time.h> #include <asm/btext.h> - -#include "local_irq.h" -#include "i8259.h" -#include "open_pic.h" -#include "xics.h" +#include <asm/i8259.h> +#include <asm/open_pic.h> unsigned long chrp_get_rtc_time(void); int chrp_set_rtc_time(unsigned long nowtime); @@ -94,7 +89,6 @@ static int max_width; #ifdef CONFIG_SMP extern struct smp_ops_t chrp_smp_ops; -extern struct smp_ops_t xics_smp_ops; #endif static const char *gg2_memtypes[4] = { @@ -128,11 +122,11 @@ chrp_show_cpuinfo(struct seq_file *m) if (!strncmp(model, "IBM,LongTrail", 13)) { /* VLSI VAS96011/12 `Golden Gate 2' */ /* Memory banks */ - sdramen = (in_le32((unsigned *)(GG2_PCI_CONFIG_BASE+ + sdramen = (in_le32((unsigned *)(gg2_pci_config_base+ GG2_PCI_DRAM_CTRL)) >>31) & 1; for (i = 0; i < (sdramen ? 4 : 6); i++) { - t = in_le32((unsigned *)(GG2_PCI_CONFIG_BASE+ + t = in_le32((unsigned *)(gg2_pci_config_base+ GG2_PCI_DRAM_BANK0+ i*4)); if (!(t & 1)) @@ -164,7 +158,7 @@ chrp_show_cpuinfo(struct seq_file *m) gg2_memtypes[sdramen ? 1 : ((t>>1) & 3)]); } /* L2 cache */ - t = in_le32((unsigned *)(GG2_PCI_CONFIG_BASE+GG2_PCI_CC_CTRL)); + t = in_le32((unsigned *)(gg2_pci_config_base+GG2_PCI_CC_CTRL)); seq_printf(m, "board l2\t: %s %s (%s)\n", gg2_cachesizes[(t>>7) & 3], gg2_cachetypes[(t>>2) & 3], @@ -238,7 +232,7 @@ chrp_setup_arch(void) initrd_below_start_ok = 1; if (initrd_start) - ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); + ROOT_DEV = mk_kdev(RAMDISK_MAJOR, 0); else #endif ROOT_DEV = to_kdev_t(0x0802); /* sda2 (sda1 is for the kernel) */ @@ -255,23 +249,6 @@ chrp_setup_arch(void) #endif /* CONFIG_PPC64BRIDGE */ - /* Some IBM machines don't have the hydra -- Cort */ - if (!OpenPIC_Addr) { - struct device_node *root; - unsigned long *opprop; - int n; - - root = find_path_device("/"); - opprop = (unsigned long *) get_property - (root, "platform-open-pic", NULL); - n = prom_n_addr_cells(root); - if (opprop != 0) { - printk("OpenPIC addrs: %lx %lx %lx\n", - opprop[n-1], opprop[2*n-1], opprop[3*n-1]); - OpenPIC_Addr = ioremap(opprop[n-1], 0x40000); - } - } - /* * Fix the Super I/O configuration */ @@ -302,6 +279,8 @@ chrp_setup_arch(void) *(unsigned long *)p->value, ppc_md.heartbeat_reset ); } } + + pci_create_OF_bus_map(); } void __chrp @@ -346,11 +325,67 @@ chrp_irq_cannonicalize(u_int irq) return irq; } +/* + * Finds the open-pic node and sets OpenPIC_Addr based on its reg property. + * Then checks if it has an interrupt-ranges property. If it does then + * we have a distributed open-pic, so call openpic_set_sources to tell + * the openpic code where to find the interrupt source registers. + */ +static void __init chrp_find_openpic(void) +{ + struct device_node *np; + int len, i; + unsigned int *iranges; + void *isu; + + np = find_type_devices("open-pic"); + if (np == NULL || np->n_addrs == 0) + return; + printk(KERN_INFO "OpenPIC at %x (size %x)\n", + np->addrs[0].address, np->addrs[0].size); + OpenPIC_Addr = ioremap(np->addrs[0].address, 0x40000); + if (OpenPIC_Addr == NULL) { + printk(KERN_ERR "Failed to map OpenPIC!\n"); + return; + } + + iranges = (unsigned int *) get_property(np, "interrupt-ranges", &len); + if (iranges == NULL || len < 2 * sizeof(unsigned int)) + return; /* not distributed */ + + /* + * The first pair of cells in interrupt-ranges refers to the + * IDU; subsequent pairs refer to the ISUs. + */ + len /= 2 * sizeof(unsigned int); + if (np->n_addrs < len) { + printk(KERN_ERR "Insufficient addresses for distributed" + " OpenPIC (%d < %d)\n", np->n_addrs, len); + return; + } + if (iranges[1] != 0) { + printk(KERN_INFO "OpenPIC irqs %d..%d in IDU\n", + iranges[0], iranges[0] + iranges[1] - 1); + openpic_set_sources(iranges[0], iranges[1], NULL); + } + for (i = 1; i < len; ++i) { + iranges += 2; + printk(KERN_INFO "OpenPIC irqs %d..%d in ISU at %x (%x)\n", + iranges[0], iranges[0] + iranges[1] - 1, + np->addrs[i].address, np->addrs[i].size); + isu = ioremap(np->addrs[i].address, np->addrs[i].size); + if (isu != NULL) + openpic_set_sources(iranges[0], iranges[1], isu); + else + printk(KERN_ERR "Failed to map OpenPIC ISU at %x!\n", + np->addrs[i].address); + } +} + void __init chrp_init_IRQ(void) { struct device_node *np; int i; - unsigned int *addrp; unsigned char* chrp_int_ack_special = 0; unsigned char init_senses[NR_IRQS - NUM_8259_INTERRUPTS]; int nmi_irq = -1; @@ -358,23 +393,30 @@ void __init chrp_init_IRQ(void) struct device_node *kbd; #endif - if (!(np = find_devices("pci")) - || !(addrp = (unsigned int *) - get_property(np, "8259-interrupt-acknowledge", NULL))) - printk("Cannot find pci to get ack address\n"); - else + for (np = find_devices("pci"); np != NULL; np = np->next) { + unsigned int *addrp = (unsigned int *) + get_property(np, "8259-interrupt-acknowledge", NULL); + if (addrp == NULL) + continue; chrp_int_ack_special = (unsigned char *) ioremap(addrp[prom_n_addr_cells(np)-1], 1); - /* hydra still sets OpenPIC_InitSenses to a static set of values */ - if (OpenPIC_InitSenses == NULL) { - prom_get_irq_senses(init_senses, NUM_8259_INTERRUPTS, NR_IRQS); - OpenPIC_InitSenses = init_senses; - OpenPIC_NumInitSenses = NR_IRQS - NUM_8259_INTERRUPTS; + break; } + if (np == NULL) + printk("Cannot find pci to get ack address\n"); + + chrp_find_openpic(); + + prom_get_irq_senses(init_senses, NUM_8259_INTERRUPTS, NR_IRQS); + OpenPIC_InitSenses = init_senses; + OpenPIC_NumInitSenses = NR_IRQS - NUM_8259_INTERRUPTS; + openpic_init(1, NUM_8259_INTERRUPTS, chrp_int_ack_special, nmi_irq); - for ( i = 0 ; i < NUM_8259_INTERRUPTS ; i++ ) + + for (i = 0; i < NUM_8259_INTERRUPTS; i++) irq_desc[i].handler = &i8259_pic; - i8259_init(); + i8259_init(0); + #if defined(CONFIG_VT) && defined(CONFIG_ADB_KEYBOARD) && defined(XMON) /* see if there is a keyboard in the device tree with a parent of type "adb" */ @@ -383,7 +425,7 @@ void __init chrp_init_IRQ(void) && strcmp(kbd->parent->type, "adb") == 0) break; if (kbd) - request_irq( HYDRA_INT_ADB_NMI, xmon_irq, 0, "XMON break", 0); + request_irq(HYDRA_INT_ADB_NMI, xmon_irq, 0, "XMON break", 0); #endif } @@ -446,19 +488,6 @@ chrp_ide_release_region(ide_ioreg_t from, { release_region(from, extent); } - -static void __chrp -chrp_ide_init_hwif_ports(hw_regs_t *hw, ide_ioreg_t data_port, ide_ioreg_t ctrl_port, int *irq) -{ - ide_ioreg_t reg = data_port; - int i; - - for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) { - hw->io_ports[i] = reg; - reg += 1; - } - hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port; -} #endif /* @@ -512,13 +541,8 @@ chrp_init(unsigned long r3, unsigned long r4, unsigned long r5, ppc_md.show_percpuinfo = of_show_percpuinfo; ppc_md.show_cpuinfo = chrp_show_cpuinfo; ppc_md.irq_cannonicalize = chrp_irq_cannonicalize; -#ifndef CONFIG_POWER4 ppc_md.init_IRQ = chrp_init_IRQ; ppc_md.get_irq = openpic_get_irq; -#else - ppc_md.init_IRQ = xics_init_IRQ; - ppc_md.get_irq = xics_get_irq; -#endif /* CONFIG_POWER4 */ ppc_md.init = chrp_init2; @@ -570,18 +594,13 @@ chrp_init(unsigned long r3, unsigned long r4, unsigned long r5, #endif #ifdef CONFIG_SMP -#ifndef CONFIG_POWER4 ppc_md.smp_ops = &chrp_smp_ops; -#else - ppc_md.smp_ops = &xics_smp_ops; -#endif /* CONFIG_POWER4 */ #endif /* CONFIG_SMP */ #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) ppc_ide_md.ide_check_region = chrp_ide_check_region; ppc_ide_md.ide_request_region = chrp_ide_request_region; ppc_ide_md.ide_release_region = chrp_ide_release_region; - ppc_ide_md.ide_init_hwif = chrp_ide_init_hwif_ports; #endif /* diff --git a/arch/ppc/kernel/chrp_smp.c b/arch/ppc/platforms/chrp_smp.c index 505e8587d341..1cf3977f3fc4 100644 --- a/arch/ppc/kernel/chrp_smp.c +++ b/arch/ppc/platforms/chrp_smp.c @@ -36,10 +36,8 @@ #include <asm/prom.h> #include <asm/smp.h> #include <asm/residual.h> -#include <asm/feature.h> #include <asm/time.h> - -#include "open_pic.h" +#include <asm/open_pic.h> extern unsigned long smp_chrp_cpu_nr; @@ -100,36 +98,6 @@ smp_chrp_setup_cpu(int cpu_nr) do_openpic_setup_cpu(); } -#ifdef CONFIG_POWER4 -static void __chrp -smp_xics_message_pass(int target, int msg, unsigned long data, int wait) -{ - /* for now, only do reschedule messages - since we only have one IPI */ - if (msg != PPC_MSG_RESCHEDULE) - return; - for (i = 0; i < smp_num_cpus; ++i) { - if (target == MSG_ALL || target == i - || (target == MSG_ALL_BUT_SELF - && i != smp_processor_id())) - xics_cause_IPI(i); - } -} - -static int __chrp -smp_xics_probe(void) -{ - return smp_chrp_cpu_nr; -} - -static void __chrp -smp_xics_setup_cpu(int cpu_nr) -{ - if (cpu_nr > 0) - xics_setup_cpu(); -} -#endif /* CONFIG_POWER4 */ - /* CHRP with openpic */ struct smp_ops_t chrp_smp_ops __chrpdata = { smp_openpic_message_pass, @@ -137,13 +105,3 @@ struct smp_ops_t chrp_smp_ops __chrpdata = { smp_chrp_kick_cpu, smp_chrp_setup_cpu, }; - -#ifdef CONFIG_POWER4 -/* CHRP with new XICS interrupt controller */ -struct smp_ops_t xics_smp_ops __chrpdata = { - smp_xics_message_pass, - smp_xics_probe, - smp_chrp_kick_cpu, - smp_xics_setup_cpu, -}; -#endif /* CONFIG_POWER4 */ diff --git a/arch/ppc/kernel/chrp_time.c b/arch/ppc/platforms/chrp_time.c index cb0d96071969..cc5a49ebdd07 100644 --- a/arch/ppc/kernel/chrp_time.c +++ b/arch/ppc/platforms/chrp_time.c @@ -1,14 +1,14 @@ /* - * BK Id: SCCS/s.chrp_time.c 1.10 09/08/01 15:47:42 paulus + * BK Id: %F% %I% %G% %U% %#% */ /* - * linux/arch/i386/kernel/time.c + * arch/ppc/platforms/chrp_time.c * * Copyright (C) 1991, 1992, 1995 Linus Torvalds * - * Adapted for PowerPC (PreP) by Gary Thomas - * Modified by Cort Dougan (cort@cs.nmt.edu) - * copied and modified from intel version + * Adapted for PowerPC (PReP) by Gary Thomas + * Modified by Cort Dougan (cort@cs.nmt.edu). + * Copied and modified from arch/i386/kernel/time.c * */ #include <linux/errno.h> @@ -50,7 +50,7 @@ long __init chrp_time_init(void) nvram_as1 = 0; nvram_as0 = base; nvram_data = base + 1; - + return 0; } @@ -87,7 +87,7 @@ int __chrp chrp_set_rtc_time(unsigned long nowtime) chrp_cmos_clock_write((save_control|RTC_SET), RTC_CONTROL); save_freq_select = chrp_cmos_clock_read(RTC_FREQ_SELECT); /* stop and reset prescaler */ - + chrp_cmos_clock_write((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT); tm.tm_year -= 1900; @@ -105,7 +105,7 @@ int __chrp chrp_set_rtc_time(unsigned long nowtime) chrp_cmos_clock_write(tm.tm_mon,RTC_MONTH); chrp_cmos_clock_write(tm.tm_mday,RTC_DAY_OF_MONTH); chrp_cmos_clock_write(tm.tm_year,RTC_YEAR); - + /* The following flags have to be released exactly in this order, * otherwise the DS12887 (popular MC146818A clone with integrated * battery and quartz) will not reset the oscillator and will not diff --git a/arch/ppc/platforms/cpc700.h b/arch/ppc/platforms/cpc700.h new file mode 100644 index 000000000000..5e8ede4c7d54 --- /dev/null +++ b/arch/ppc/platforms/cpc700.h @@ -0,0 +1,109 @@ +/* + * include/asm-ppc/cpc700.h + * + * Header file for IBM CPC700 Host Bridge, et. al. + * + * Author: Mark A. Greer + * mgreer@mvista.com + * + * Copyright 2000 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* + * This file contains the defines and macros for the IBM CPC700 host bridge, + * memory controller, PIC, UARTs, IIC, and Timers. + */ + +#ifndef _ASMPPC_CPC700_H +#define _ASMPPC_CPC700_H + +#include <linux/stddef.h> +#include <linux/types.h> +#include <linux/init.h> + +#define CPC700_OUT_32(a,d) (*(u_int *)a = d) +#define CPC700_IN_32(a) (*(u_int *)a) + +/* + * PCI Section + */ +#define CPC700_PCI_CONFIG_ADDR 0xfec00000 +#define CPC700_PCI_CONFIG_DATA 0xfec00004 + +#define CPC700_PMM0_LOCAL 0xff400000 +#define CPC700_PMM0_MASK_ATTR 0xff400004 +#define CPC700_PMM0_PCI_LOW 0xff400008 +#define CPC700_PMM0_PCI_HIGH 0xff40000c +#define CPC700_PMM1_LOCAL 0xff400010 +#define CPC700_PMM1_MASK_ATTR 0xff400014 +#define CPC700_PMM1_PCI_LOW 0xff400018 +#define CPC700_PMM1_PCI_HIGH 0xff40001c +#define CPC700_PMM2_LOCAL 0xff400020 +#define CPC700_PMM2_MASK_ATTR 0xff400024 +#define CPC700_PMM2_PCI_LOW 0xff400028 +#define CPC700_PMM2_PCI_HIGH 0xff40002c +#define CPC700_PTM1_MEMSIZE 0xff400030 +#define CPC700_PTM1_LOCAL 0xff400034 +#define CPC700_PTM2_MEMSIZE 0xff400038 +#define CPC700_PTM2_LOCAL 0xff40003c + +/* + * PIC Section + * + * IBM calls the CPC700's programmable interrupt controller the Universal + * Interrupt Controller or UIC. + */ + +/* + * UIC Register Addresses. + */ +#define CPC700_UIC_UICSR 0xff500880 /* Status Reg (Rd/Clr)*/ +#define CPC700_UIC_UICSRS 0xff500884 /* Status Reg (Set) */ +#define CPC700_UIC_UICER 0xff500888 /* Enable Reg */ +#define CPC700_UIC_UICCR 0xff50088c /* Critical Reg */ +#define CPC700_UIC_UICPR 0xff500890 /* Polarity Reg */ +#define CPC700_UIC_UICTR 0xff500894 /* Trigger Reg */ +#define CPC700_UIC_UICMSR 0xff500898 /* Masked Status Reg */ +#define CPC700_UIC_UICVR 0xff50089c /* Vector Reg */ +#define CPC700_UIC_UICVCR 0xff5008a0 /* Vector Config Reg */ + +#define CPC700_UIC_UICER_ENABLE 0x00000001 /* Enable an IRQ */ + +#define CPC700_UIC_UICVCR_31_HI 0x00000000 /* IRQ 31 hi priority */ +#define CPC700_UIC_UICVCR_0_HI 0x00000001 /* IRQ 0 hi priority */ +#define CPC700_UIC_UICVCR_BASE_MASK 0xfffffffc +#define CPC700_UIC_UICVCR_ORDER_MASK 0x00000001 + +/* Specify value of a bit for an IRQ. */ +#define CPC700_UIC_IRQ_BIT(i) ((0x00000001) << (31 - (i))) + +/* + * UIC Exports... + */ +extern struct hw_interrupt_type cpc700_pic; +extern unsigned int cpc700_irq_assigns[27][2]; + +extern void __init cpc700_init_IRQ(void); +extern int cpc700_get_irq(struct pt_regs *); + +#endif /* _ASMPPC_CPC700_H */ diff --git a/arch/ppc/platforms/cpc700_pic.c b/arch/ppc/platforms/cpc700_pic.c new file mode 100644 index 000000000000..771b215a8f70 --- /dev/null +++ b/arch/ppc/platforms/cpc700_pic.c @@ -0,0 +1,205 @@ +/* + * arch/ppc/platforms/cpc700_pic.c + * + * Interrupt controller support for IBM Spruce + * + * Authors: Mark Greer, Matt Porter, and Johnnie Peters + * mgreer@mvista.com + * mporter@mvista.com + * jpeters@mvista.com + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <linux/stddef.h> +#include <linux/init.h> +#include <linux/sched.h> +#include <linux/signal.h> +#include <linux/irq.h> + +#include <asm/io.h> +#include <asm/processor.h> +#include <asm/system.h> +#include <asm/irq.h> + +#include "cpc700.h" + +static void +cpc700_unmask_irq(unsigned int irq) +{ + unsigned int tr_bits; + + /* + * IRQ 31 is largest IRQ supported. + * IRQs 17-19 are reserved. + */ + if ((irq <= 31) && ((irq < 17) || (irq > 19))) { + tr_bits = CPC700_IN_32(CPC700_UIC_UICTR); + + if ((tr_bits & (1 << (31 - irq))) == 0) { + /* level trigger interrupt, clear bit in status + * register */ + CPC700_OUT_32(CPC700_UIC_UICSR, 1 << (31 - irq)); + } + + /* Know IRQ fits in entry 0 of ppc_cached_irq_mask[] */ + ppc_cached_irq_mask[0] |= CPC700_UIC_IRQ_BIT(irq); + + CPC700_OUT_32(CPC700_UIC_UICER, ppc_cached_irq_mask[0]); + } + return; +} + +static void +cpc700_mask_irq(unsigned int irq) +{ + /* + * IRQ 31 is largest IRQ supported. + * IRQs 17-19 are reserved. + */ + if ((irq <= 31) && ((irq < 17) || (irq > 19))) { + /* Know IRQ fits in entry 0 of ppc_cached_irq_mask[] */ + ppc_cached_irq_mask[0] &= + ~CPC700_UIC_IRQ_BIT(irq); + + CPC700_OUT_32(CPC700_UIC_UICER, ppc_cached_irq_mask[0]); + } + return; +} + +static void +cpc700_mask_and_ack_irq(unsigned int irq) +{ + u_int bit; + + /* + * IRQ 31 is largest IRQ supported. + * IRQs 17-19 are reserved. + */ + if ((irq <= 31) && ((irq < 17) || (irq > 19))) { + /* Know IRQ fits in entry 0 of ppc_cached_irq_mask[] */ + bit = CPC700_UIC_IRQ_BIT(irq); + + ppc_cached_irq_mask[0] &= ~bit; + CPC700_OUT_32(CPC700_UIC_UICER, ppc_cached_irq_mask[0]); + CPC700_OUT_32(CPC700_UIC_UICSR, bit); /* Write 1 clears IRQ */ + } + return; +} + +static struct hw_interrupt_type cpc700_pic = { + "CPC700 PIC", + NULL, + NULL, + cpc700_unmask_irq, + cpc700_mask_irq, + cpc700_mask_and_ack_irq, + NULL, + NULL +}; + +__init static void +cpc700_pic_init_irq(unsigned int irq) +{ + unsigned int tmp; + + /* Set interrupt sense */ + tmp = CPC700_IN_32(CPC700_UIC_UICTR); + if (cpc700_irq_assigns[irq][0] == 0) { + tmp &= ~CPC700_UIC_IRQ_BIT(irq); + } else { + tmp |= CPC700_UIC_IRQ_BIT(irq); + } + CPC700_OUT_32(CPC700_UIC_UICTR, tmp); + + /* Set interrupt polarity */ + tmp = CPC700_IN_32(CPC700_UIC_UICPR); + if (cpc700_irq_assigns[irq][1]) { + tmp |= CPC700_UIC_IRQ_BIT(irq); + } else { + tmp &= ~CPC700_UIC_IRQ_BIT(irq); + } + CPC700_OUT_32(CPC700_UIC_UICPR, tmp); + + /* Set interrupt critical */ + tmp = CPC700_IN_32(CPC700_UIC_UICCR); + tmp |= CPC700_UIC_IRQ_BIT(irq); + CPC700_OUT_32(CPC700_UIC_UICCR, tmp); + + return; +} + +__init void +cpc700_init_IRQ(void) +{ + int i; + + ppc_cached_irq_mask[0] = 0; + CPC700_OUT_32(CPC700_UIC_UICER, 0x00000000); /* Disable all irq's */ + CPC700_OUT_32(CPC700_UIC_UICSR, 0xffffffff); /* Clear cur intrs */ + CPC700_OUT_32(CPC700_UIC_UICCR, 0xffffffff); /* Gen INT not MCP */ + CPC700_OUT_32(CPC700_UIC_UICPR, 0x00000000); /* Active low */ + CPC700_OUT_32(CPC700_UIC_UICTR, 0x00000000); /* Level Sensitive */ + CPC700_OUT_32(CPC700_UIC_UICVR, CPC700_UIC_UICVCR_0_HI); + /* IRQ 0 is highest */ + + for (i = 0; i < 17; i++) { + irq_desc[i].handler = &cpc700_pic; + cpc700_pic_init_irq(i); + } + + for (i = 20; i < 27; i++) { + irq_desc[i].handler = &cpc700_pic; + cpc700_pic_init_irq(i); + } + + return; +} + + + +/* + * Find the highest IRQ that generating an interrupt, if any. + */ +int +cpc700_get_irq(struct pt_regs *regs) +{ + int irq = 0; + u_int irq_status, irq_test = 1; + + irq_status = CPC700_IN_32(CPC700_UIC_UICMSR); + + do + { + if (irq_status & irq_test) + break; + irq++; + irq_test <<= 1; + } while (irq < NR_IRQS); + + + if (irq == NR_IRQS) + irq = 33; + + return (31 - irq); +} diff --git a/arch/ppc/platforms/cpc710.h b/arch/ppc/platforms/cpc710.h new file mode 100644 index 000000000000..ede184e36b5e --- /dev/null +++ b/arch/ppc/platforms/cpc710.h @@ -0,0 +1,77 @@ +/* + * arch/ppc/platforms/cpc710.h + * + * Definitions for the IBM CPC710 PCI Host Bridge + * + * Author: Matt Porter <mporter@mvista.com> + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#ifndef __PPC_PLATFORMS_CPC710_H +#define __PPC_PLATFORMS_CPC710_H + +/* General bridge and memory controller registers */ +#define PIDR 0xff000008 +#define CNFR 0xff00000c +#define RSTR 0xff000010 +#define UCTL 0xff001000 +#define MPSR 0xff001010 +#define SIOC 0xff001020 +#define ABCNTL 0xff001030 +#define SRST 0xff001040 +#define ERRC 0xff001050 +#define SESR 0xff001060 +#define SEAR 0xff001070 +#define PGCHP 0xff001100 +#define GPDIR 0xff001130 +#define ATAS 0xff001160 +#define AVDG 0xff001170 +#define MCCR 0xff001200 +#define MESR 0xff001220 +#define MEAR 0xff001230 +#define MCER0 0xff001300 +#define MCER1 0xff001310 +#define MCER2 0xff001320 +#define MCER3 0xff001330 +#define MCER4 0xff001340 +#define MCER5 0xff001350 +#define MCER6 0xff001360 +#define MCER7 0xff001370 + +/* + * PCI32/64 configuration registers + * Given as offsets from their + * respective physical segment BAR + */ +#define PIBAR 0x000f7800 +#define PMBAR 0x000f7810 +#define MSIZE 0x000f7f40 +#define IOSIZE 0x000f7f60 +#define SMBAR 0x000f7f80 +#define SIBAR 0x000f7fc0 +#define PSSIZE 0x000f8100 +#define PPSIZE 0x000f8110 +#define BARPS 0x000f8120 +#define BARPP 0x000f8130 +#define PSBAR 0x000f8140 +#define PPBAR 0x000f8150 + +/* System standard configuration registers space */ +#define DCR 0xff200000 +#define DID 0xff200004 +#define BAR 0xff200018 + +/* Device specific configuration space */ +#define PCIENB 0xff201000 + +/* Configuration space registers */ +#define CPC710_BUS_NUMBER 0x40 +#define CPC710_SUB_BUS_NUMBER 0x41 + +#endif /* __PPC_PLATFORMS_CPC710_H */ diff --git a/arch/ppc/platforms/cpci405.c b/arch/ppc/platforms/cpci405.c new file mode 100644 index 000000000000..9c14b513d9e5 --- /dev/null +++ b/arch/ppc/platforms/cpci405.c @@ -0,0 +1,78 @@ +/* + * arch/ppc/platforms/cpci405.c + * + * Board setup routines for the esd CPCI-405 cPCI Board. + * + * Author: Stefan Roese + * stefan.roese@esd-electronics.com + * + * Copyright 2001 esd electronic system design - hannover germany + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * History: 11/09/2001 - armin + * added board_init to add in additional instuctions needed during platfrom_init + * + */ + +#include <linux/config.h> +#include <linux/init.h> +#include <linux/pci.h> +#include <asm/system.h> +#include <asm/pci-bridge.h> +#include <asm/machdep.h> +#include <asm/todc.h> + +/* + * Some IRQs unique to CPCI-405. + */ +int __init +ppc405_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) +{ + static char pci_irq_table[][4] = + /* + * PCI IDSEL/INTPIN->INTLINE + * A B C D + */ + { + {28, 28, 28, 28}, /* IDSEL 15 - cPCI slot 8 */ + {29, 29, 29, 29}, /* IDSEL 16 - cPCI slot 7 */ + {30, 30, 30, 30}, /* IDSEL 17 - cPCI slot 6 */ + {27, 27, 27, 27}, /* IDSEL 18 - cPCI slot 5 */ + {28, 28, 28, 28}, /* IDSEL 19 - cPCI slot 4 */ + {29, 29, 29, 29}, /* IDSEL 20 - cPCI slot 3 */ + {30, 30, 30, 30}, /* IDSEL 21 - cPCI slot 2 */ + }; + const long min_idsel = 15, max_idsel = 21, irqs_per_slot = 4; + return PCI_IRQ_TABLE_LOOKUP; +}; + +void __init +board_setup_arch(void) +{ +} + +void __init +board_io_mapping(void) +{ +} + +void __init +board_setup_irq(void) +{ +} + +void __init +board_init(void) +{ +#ifdef CONFIG_PPC_RTC + ppc_md.time_init = todc_time_init; + ppc_md.set_rtc_time = todc_set_rtc_time; + ppc_md.get_rtc_time = todc_get_rtc_time; + ppc_md.nvram_read_val = todc_direct_read_val; + ppc_md.nvram_write_val = todc_direct_write_val; +#endif +} diff --git a/arch/ppc/platforms/cpci405.h b/arch/ppc/platforms/cpci405.h new file mode 100644 index 000000000000..1f1ca4bbb9cb --- /dev/null +++ b/arch/ppc/platforms/cpci405.h @@ -0,0 +1,45 @@ +/* + * CPCI-405 board specific definitions + * + * Copyright (c) 2001 Stefan Roese (stefan.roese@esd-electronics.com) + */ + +#ifndef __ASM_CPCI405_H__ +#define __ASM_CPCI405_H__ + +#include <linux/config.h> + +/* We have a 405GP core */ +#include <platforms/ibm405gp.h> + +#include <asm/ppcboot.h> + +/* Some 4xx parts use a different timebase frequency from the internal clock. +*/ +#define bi_tbfreq bi_intfreq + +/* Early initialization address mapping for block_io. + * Standard 405GP map. + */ +#define PPC4xx_PCI_IO_PADDR ((uint)PPC405_PCI_PHY_IO_BASE) +#define PPC4xx_PCI_IO_VADDR PPC4xx_PCI_IO_PADDR +#define PPC4xx_PCI_IO_SIZE ((uint)64*1024) +#define PPC4xx_PCI_CFG_PADDR ((uint)PPC405_PCI_CONFIG_ADDR) +#define PPC4xx_PCI_CFG_VADDR PPC4xx_PCI_CFG_PADDR +#define PPC4xx_PCI_CFG_SIZE ((uint)4*1024) +#define PPC4xx_PCI_LCFG_PADDR ((uint)0xef400000) +#define PPC4xx_PCI_LCFG_VADDR PPC4xx_PCI_LCFG_PADDR +#define PPC4xx_PCI_LCFG_SIZE ((uint)4*1024) +#define PPC4xx_ONB_IO_PADDR ((uint)0xef600000) +#define PPC4xx_ONB_IO_VADDR PPC4xx_ONB_IO_PADDR +#define PPC4xx_ONB_IO_SIZE ((uint)4*1024) + +#ifdef CONFIG_PPC405GP_INTERNAL_CLOCK +#define BASE_BAUD 201600 +#else +#define BASE_BAUD 691200 +#endif + +#define PPC4xx_MACHINE_NAME "esd CPCI-405" + +#endif /* __ASM_CPCI405_H__ */ diff --git a/arch/ppc/platforms/ep405.c b/arch/ppc/platforms/ep405.c new file mode 100644 index 000000000000..84c645dc8114 --- /dev/null +++ b/arch/ppc/platforms/ep405.c @@ -0,0 +1,187 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + * + * Copyright 2001 MontaVista Software Inc. + * <mlocke@mvista.com> + * + * Not much needed for the Embedded Planet 405gp board + * + * History: 11/09/2001 - armin + * added board_init to add in additional instuctions needed during platfrom_init + * cleaned up map_irq. + * + * 1/22/2002 - Armin + * converted pci to ocp + * + + * + */ +#include <linux/config.h> +#include <linux/init.h> +#include <linux/pci.h> +#include <asm/system.h> +#include <asm/pci-bridge.h> +#include <asm/machdep.h> +#include <asm/todc.h> +#include <platforms/ibm_ocp.h> + +#undef DEBUG +#ifdef DEBUG +#define DBG(x...) printk(x) +#else +#define DBG(x...) +#endif + +void *ep405_bcsr; +void *ep405_nvram; + +int __init +ppc405_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) +{ + static char pci_irq_table[][4] = + /* + * PCI IDSEL/INTPIN->INTLINE + * A B C D + */ + { + {28, 28, 28, 28}, /* IDSEL 1 - PCI slot 1 */ + {29, 29, 29, 29}, /* IDSEL 2 - PCI slot 2 */ + {30, 30, 30, 30}, /* IDSEL 3 - PCI slot 3 */ + {31, 31, 31, 31}, /* IDSEL 4 - PCI slot 4 */ + }; + const long min_idsel = 1, max_idsel = 4, irqs_per_slot = 4; + return PCI_IRQ_TABLE_LOOKUP; +}; + +void __init +board_setup_arch(void) +{ +#ifdef CONFIG_PPC_RTC + /* FIXME: what if NVRAM size is not 512k */ + TODC_INIT(TODC_TYPE_DS1557, ep405_nvram, ep405_nvram, ep405_nvram, 8); +#endif /* CONFIG_PPC_RTC */ +} + +void __init +bios_fixup(struct pci_controller *hose, void *pcil0_base) +{ + + unsigned int bar_response, bar; + struct pcil0_regs *pcip; + /* + * Expected PCI mapping: + * + * PLB addr PCI memory addr + * --------------------- --------------------- + * 0000'0000 - 7fff'ffff <--- 0000'0000 - 7fff'ffff + * 8000'0000 - Bfff'ffff ---> 8000'0000 - Bfff'ffff + * + * PLB addr PCI io addr + * --------------------- --------------------- + * e800'0000 - e800'ffff ---> 0000'0000 - 0001'0000 + * + */ + +#ifdef DEBUG + int i; + pcip = (struct pcil0_regs *) pcil0_base; + + printk("ioremap PCLIO_BASE = 0x%x\n", pcip); + printk("PCI bridge regs before fixup \n"); + for (i = 0; i <= 3; i++) { + printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].ma))); + printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].la))); + printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].pcila))); + printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].pciha))); + } + printk(" ptm1ms\t0x%x\n", in_le32(&(pcip->ptm1ms))); + printk(" ptm1la\t0x%x\n", in_le32(&(pcip->ptm1la))); + printk(" ptm2ms\t0x%x\n", in_le32(&(pcip->ptm2ms))); + printk(" ptm2la\t0x%x\n", in_le32(&(pcip->ptm2la))); + +#else + pcip = (struct pcil0_regs *) pcil0_base; +#endif + /* added for IBM boot rom version 1.15 bios bar changes -AK */ + + /* Disable region first */ + out_le32((void *) &(pcip->pmm[0].ma), 0x00000000); + /* PLB starting addr, PCI: 0x80000000 */ + out_le32((void *) &(pcip->pmm[0].la), 0x80000000); + /* PCI start addr, 0x80000000 */ + out_le32((void *) &(pcip->pmm[0].pcila), PPC405_PCI_MEM_BASE); + /* 512MB range of PLB to PCI */ + out_le32((void *) &(pcip->pmm[0].pciha), 0x00000000); + /* Enable no pre-fetch, enable region */ + out_le32((void *) &(pcip->pmm[0].ma), ((0xffffffff - + (PPC405_PCI_UPPER_MEM - + PPC405_PCI_MEM_BASE)) | 0x01)); + + /* Disable region one */ + out_le32((void *) &(pcip->pmm[1].ma), 0x00000000); + out_le32((void *) &(pcip->pmm[1].la), 0x00000000); + out_le32((void *) &(pcip->pmm[1].pcila), 0x00000000); + out_le32((void *) &(pcip->pmm[1].pciha), 0x00000000); + out_le32((void *) &(pcip->pmm[1].ma), 0x00000000); + out_le32((void *) &(pcip->ptm1ms), 0x00000000); + + /* Disable region two */ + out_le32((void *) &(pcip->pmm[2].ma), 0x00000000); + out_le32((void *) &(pcip->pmm[2].la), 0x00000000); + out_le32((void *) &(pcip->pmm[2].pcila), 0x00000000); + out_le32((void *) &(pcip->pmm[2].pciha), 0x00000000); + out_le32((void *) &(pcip->pmm[2].ma), 0x00000000); + out_le32((void *) &(pcip->ptm2ms), 0x00000000); + + /* Zero config bars */ + for (bar = PCI_BASE_ADDRESS_1; bar <= PCI_BASE_ADDRESS_2; bar += 4) { + early_write_config_dword(hose, hose->first_busno, + PCI_FUNC(hose->first_busno), bar, + 0x00000000); + early_read_config_dword(hose, hose->first_busno, + PCI_FUNC(hose->first_busno), bar, + &bar_response); + DBG("BUS %d, device %d, Function %d bar 0x%8.8x is 0x%8.8x\n", + hose->first_busno, PCI_SLOT(hose->first_busno), + PCI_FUNC(hose->first_busno), bar, bar_response); + } + /* end work arround */ + +#ifdef DEBUG + printk("PCI bridge regs after fixup \n"); + for (i = 0; i <= 3; i++) { + printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].ma))); + printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].la))); + printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].pcila))); + printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].pciha))); + } + printk(" ptm1ms\t0x%x\n", in_le32(&(pcip->ptm1ms))); + printk(" ptm1la\t0x%x\n", in_le32(&(pcip->ptm1la))); + printk(" ptm2ms\t0x%x\n", in_le32(&(pcip->ptm2ms))); + printk(" ptm2la\t0x%x\n", in_le32(&(pcip->ptm2la))); +#endif +} + +void __init +board_io_mapping(void) +{ + ep405_bcsr = ioremap(EP405_BCSR_PADDR, EP405_BCSR_SIZE); + ep405_nvram = ioremap(EP405_NVRAM_PADDR, EP405_NVRAM_SIZE); +} + +void __init +board_setup_irq(void) +{ +} + +void __init +board_init(void) +{ +#ifdef CONFIG_PPC_RTC + ppc_md.time_init = todc_time_init; + ppc_md.set_rtc_time = todc_set_rtc_time; + ppc_md.get_rtc_time = todc_get_rtc_time; + ppc_md.nvram_read_val = todc_direct_read_val; + ppc_md.nvram_write_val = todc_direct_write_val; +#endif +} diff --git a/arch/ppc/platforms/ep405.h b/arch/ppc/platforms/ep405.h new file mode 100644 index 000000000000..a8cffc306477 --- /dev/null +++ b/arch/ppc/platforms/ep405.h @@ -0,0 +1,64 @@ +/* + * Copyright 2000 MontaVista Software Inc. + * http://www.mvista.com + * <mlocke@mvista.com> + * + * Embedded Planet 405GP board + * http://www.embeddedplanet.com + * + */ + +#ifdef __KERNEL__ +#ifndef __ASM_EP405_H__ +#define __ASM_EP405_H__ + +/* We have a 405GP core */ +#include <platforms/ibm405gp.h> + +#ifndef __ASSEMBLY__ +typedef struct board_info { + unsigned int bi_memsize; /* DRAM installed, in bytes */ + unsigned char bi_enetaddr[6]; /* Local Ethernet MAC address */ + unsigned int bi_intfreq; /* Processor speed, in Hz */ + unsigned int bi_busfreq; /* PLB Bus speed, in Hz */ + unsigned int bi_pci_busfreq; /* PCI Bus speed, in Hz */ +} bd_t; + +/* Some 4xx parts use a different timebase frequency from the internal clock. +*/ +#define bi_tbfreq bi_intfreq + +extern void *ep405_bcsr; +extern void *ep405_nvram; + +/* Map for the BCSR and NVRAM space */ +#define EP405_BCSR_PADDR ((uint)0xf4000000) +#define EP405_BCSR_SIZE ((uint)16) +#define EP405_NVRAM_PADDR ((uint)0xf4200000) +/* FIXME: what if the board has something other than 512k NVRAM */ +#define EP405_NVRAM_SIZE ((uint)512*1024) + +/* Early initialization address mapping for block_io. + * Standard 405GP map. + */ +#define PPC4xx_PCI_IO_PADDR ((uint)PPC405_PCI_PHY_IO_BASE) +#define PPC4xx_PCI_IO_VADDR PPC4xx_PCI_IO_PADDR +#define PPC4xx_PCI_IO_SIZE ((uint)64*1024) +#define PPC4xx_PCI_CFG_PADDR ((uint)PPC405_PCI_CONFIG_ADDR) +#define PPC4xx_PCI_CFG_VADDR PPC4xx_PCI_CFG_PADDR +#define PPC4xx_PCI_CFG_SIZE ((uint)4*1024) +#define PPC4xx_PCI_LCFG_PADDR ((uint)0xef400000) +#define PPC4xx_PCI_LCFG_VADDR PPC4xx_PCI_LCFG_PADDR +#define PPC4xx_PCI_LCFG_SIZE ((uint)4*1024) +#define PPC4xx_ONB_IO_PADDR ((uint)0xef600000) +#define PPC4xx_ONB_IO_VADDR PPC4xx_ONB_IO_PADDR +#define PPC4xx_ONB_IO_SIZE ((uint)4*1024) + +/* serial defines */ +#define BASE_BAUD 399193 + +#define PPC4xx_MACHINE_NAME "Embedded Planet 405GP" + +#endif /* !__ASSEMBLY__ */ +#endif /* __ASM_EP405_H__ */ +#endif /* __KERNEL__ */ diff --git a/arch/ppc/kernel/error_log.c b/arch/ppc/platforms/error_log.c index b414b27fb174..b414b27fb174 100644 --- a/arch/ppc/kernel/error_log.c +++ b/arch/ppc/platforms/error_log.c diff --git a/arch/ppc/kernel/error_log.h b/arch/ppc/platforms/error_log.h index bb162a592e3a..bb162a592e3a 100644 --- a/arch/ppc/kernel/error_log.h +++ b/arch/ppc/platforms/error_log.h diff --git a/include/asm-ppc/est8260.h b/arch/ppc/platforms/est8260.h index 1bfe42865cb0..1bfe42865cb0 100644 --- a/include/asm-ppc/est8260.h +++ b/arch/ppc/platforms/est8260.h diff --git a/arch/ppc/platforms/ev64260.h b/arch/ppc/platforms/ev64260.h new file mode 100644 index 000000000000..55ef60976d60 --- /dev/null +++ b/arch/ppc/platforms/ev64260.h @@ -0,0 +1,69 @@ +/* + * arch/ppc/platforms/ev64260.h + * + * Definitions for Marvell/Galileo EV-64260-BP Evaluation Board. + * + * Author: Mark A. Greer <mgreer@mvista.com> + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +/* + * The GT64260 has 2 PCI buses each with 1 window from the CPU bus to + * PCI I/O space and 4 windows from the CPU bus to PCI MEM space. + * We'll only use one PCI MEM window on each PCI bus. + */ + +#ifndef __PPC_PLATFORMS_EV64260_H +#define __PPC_PLATFORMS_EV64260_H + +#define EV64260_BRIDGE_REG_BASE 0xf8000000 +#define EV64260_BRIDGE_REG_BASE_TO_TOP 0x08000000U + +#define EV64260_TODC_BASE 0xfc800000 +#define EV64260_TODC_LEN 0x00800000 +#define EV64260_TODC_END (EV64260_TODC_BASE + \ + EV64260_TODC_LEN - 1) + +#define EV64260_UART_BASE 0xfd000000 +#define EV64260_UART_LEN 0x00800000 +#define EV64260_UART_END (EV64260_UART_BASE + \ + EV64260_UART_LEN - 1) +/* Serial driver setup. */ +#define EV64260_SERIAL_0 (EV64260_UART_BASE + 0x20) +#define EV64260_SERIAL_1 EV64260_UART_BASE + +#define BASE_BAUD ( 3686400 / 16 ) + +#ifdef CONFIG_SERIAL_MANY_PORTS +#define RS_TABLE_SIZE 64 +#else +#define RS_TABLE_SIZE 2 +#endif + +#ifdef CONFIG_SERIAL_DETECT_IRQ +#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF|ASYNC_SKIP_TEST|ASYNC_AUTO_IRQ) +#else +#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF|ASYNC_SKIP_TEST) +#endif + +#if !defined(CONFIG_GT64260_CONSOLE) +/* Required for bootloader's ns16550.c code */ +#define STD_SERIAL_PORT_DFNS \ + { 0, BASE_BAUD, EV64260_SERIAL_0, 85, STD_COM_FLAGS, /* ttyS0 */\ + iomem_base: (u8 *)EV64260_SERIAL_0, \ + iomem_reg_shift: 2, \ + io_type: SERIAL_IO_MEM }, + +#define SERIAL_PORT_DFNS \ + STD_SERIAL_PORT_DFNS +#else +#define SERIAL_PORT_DFNS +#endif + +#endif /* __PPC_PLATFORMS_EV64260_H */ diff --git a/arch/ppc/platforms/ev64260_setup.c b/arch/ppc/platforms/ev64260_setup.c new file mode 100644 index 000000000000..2fa96122e545 --- /dev/null +++ b/arch/ppc/platforms/ev64260_setup.c @@ -0,0 +1,477 @@ +/* + * arch/ppc/platforms/ev64260_setup.c + * + * Board setup routines for the Marvell/Galileo EV-64260-BP Evaluation Board. + * + * Author: Mark A. Greer <mgreer@mvista.com> + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +/* + * The EV-64260-BP port is the result of hard work from many people from + * many companies. In particular, employees of Marvell/Galileo, Mission + * Critical Linux, Xyterra, and MontaVista Software were heavily involved. + */ +#include <linux/config.h> +#include <linux/stddef.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/errno.h> +#include <linux/reboot.h> +#include <linux/pci.h> +#include <linux/kdev_t.h> +#include <linux/major.h> +#include <linux/blk.h> +#include <linux/console.h> +#include <linux/delay.h> +#include <linux/irq.h> +#include <linux/ide.h> +#include <linux/seq_file.h> +#if !defined(CONFIG_GT64260_CONSOLE) +#include <linux/serial.h> +#endif + +#include <asm/system.h> +#include <asm/pgtable.h> +#include <asm/page.h> +#include <asm/time.h> +#include <asm/dma.h> +#include <asm/io.h> +#include <asm/machdep.h> +#include <asm/prom.h> +#include <asm/smp.h> +#include <asm/todc.h> +#include <asm/bootinfo.h> +#include <asm/gt64260.h> +#include <platforms/ev64260.h> + + +extern char cmd_line[]; +unsigned long ev64260_find_end_of_memory(void); + +TODC_ALLOC(); + +/* + * Marvell/Galileo EV-64260-BP Evaluation Board PCI interrupt routing. + */ +static int __init +ev64260_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) +{ + struct pci_controller *hose = pci_bus_to_hose(dev->bus->number); + + if (hose->index == 0) { + static char pci_irq_table[][4] = + /* + * PCI IDSEL/INTPIN->INTLINE + * A B C D + */ + { + { 91, 0, 0, 0 }, /* IDSEL 7 - PCI bus 0 */ + { 91, 0, 0, 0 }, /* IDSEL 8 - PCI bus 0 */ + }; + + const long min_idsel = 7, max_idsel = 8, irqs_per_slot = 4; + return PCI_IRQ_TABLE_LOOKUP; + } + else { + static char pci_irq_table[][4] = + /* + * PCI IDSEL/INTPIN->INTLINE + * A B C D + */ + { + { 93, 0, 0, 0 }, /* IDSEL 7 - PCI bus 1 */ + { 93, 0, 0, 0 }, /* IDSEL 8 - PCI bus 1 */ + }; + + const long min_idsel = 7, max_idsel = 8, irqs_per_slot = 4; + return PCI_IRQ_TABLE_LOOKUP; + } +} + +static void __init +ev64260_setup_bridge(void) +{ + gt64260_bridge_info_t info; + int window; + + GT64260_BRIDGE_INFO_DEFAULT(&info, ev64260_find_end_of_memory()); + + /* Lookup PCI host bridges */ + if (gt64260_find_bridges(EV64260_BRIDGE_REG_BASE, + &info, + ev64260_map_irq)) { + printk("Bridge initialization failed.\n"); + } + + /* + * Enabling of PCI internal-vs-external arbitration + * is a platform- and errata-dependent decision. + */ + if(gt64260_revision == GT64260) { + /* FEr#35 */ + gt_clr_bits(GT64260_PCI_0_ARBITER_CNTL, (1<<31)); + gt_clr_bits(GT64260_PCI_1_ARBITER_CNTL, (1<<31)); + } else if( gt64260_revision == GT64260A ) { + gt_set_bits(GT64260_PCI_0_ARBITER_CNTL, (1<<31)); + gt_set_bits(GT64260_PCI_1_ARBITER_CNTL, (1<<31)); + /* Make external GPP interrupts level sensitive */ + gt_set_bits(GT64260_COMM_ARBITER_CNTL, (1<<10)); + /* Doc Change 9: > 100 MHz so must be set */ + gt_set_bits(GT64260_CPU_CONFIG, (1<<23)); + } + + gt_set_bits(GT64260_CPU_MASTER_CNTL, (1<<9)); /* Only 1 cpu */ + + /* SCS windows not disabled above, disable all but SCS 0 */ + for (window=1; window<GT64260_CPU_SCS_DECODE_WINDOWS; window++) { + gt64260_cpu_scs_set_window(window, 0, 0); + } + + /* Set up windows to RTC/TODC and DUART on device module (CS 1 & 2) */ + gt64260_cpu_cs_set_window(1, EV64260_TODC_BASE, EV64260_TODC_LEN); + gt64260_cpu_cs_set_window(2, EV64260_UART_BASE, EV64260_UART_LEN); + + /* + * The EV-64260-BP uses several Multi-Purpose Pins (MPP) on the 64260 + * bridge as interrupt inputs (via the General Purpose Ports (GPP) + * register). Need to route the MPP inputs to the GPP and set the + * polarity correctly. + * + * In MPP Control 2 Register + * MPP 21 -> GPP 21 (DUART channel A intr) + * MPP 22 -> GPP 22 (DUART channel B intr) + * + * In MPP Control 3 Register + * MPP 27 -> GPP 27 (PCI 0 INTA) + * MPP 29 -> GPP 29 (PCI 1 INTA) + */ + gt_clr_bits(GT64260_MPP_CNTL_2, + ((1<<20) | (1<<21) | (1<<22) | (1<<23) | + (1<<24) | (1<<25) | (1<<26) | (1<<27))); + + gt_clr_bits(GT64260_MPP_CNTL_3, + ((1<<12) | (1<<13) | (1<<14) | (1<<15) | + (1<<20) | (1<<21) | (1<<22) | (1<<23))); + + gt_write(GT64260_GPP_LEVEL_CNTL, 0x000002c6); + + /* DUART & PCI interrupts are active low */ + gt_set_bits(GT64260_GPP_LEVEL_CNTL, + ((1<<21) | (1<<22) | (1<<27) | (1<<29))); + + /* Clear any pending interrupts for these inputs and enable them. */ + gt_write(GT64260_GPP_INTR_CAUSE, + ~((1<<21) | (1<<22) | (1<<27) | (1<<29))); + gt_set_bits(GT64260_GPP_INTR_MASK, + ((1<<21) | (1<<22)| (1<<27) | (1<<29))); + gt_set_bits(GT64260_IC_CPU_INTR_MASK_HI, ((1<<26) | (1<<27))); + + /* Set MPSC Multiplex RMII */ + /* NOTE: ethernet driver modifies bit 0 and 1 */ + gt_write(GT64260_MPP_SERIAL_PORTS_MULTIPLEX, 0x00001102); + + return; +} + + +static void __init +ev64260_setup_arch(void) +{ +#if !defined(CONFIG_GT64260_CONSOLE) + struct serial_struct serial_req; +#endif + + if ( ppc_md.progress ) + ppc_md.progress("ev64260_setup_arch: enter", 0); + + loops_per_jiffy = 50000000 / HZ; + +#ifdef CONFIG_BLK_DEV_INITRD + if (initrd_start) + ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); + else +#endif +#ifdef CONFIG_ROOT_NFS + ROOT_DEV = to_kdev_t(0x00FF); /* /dev/nfs pseudo device */ +#else + ROOT_DEV = to_kdev_t(0x0802); /* /dev/sda2 SCSI disk */ +#endif + + if ( ppc_md.progress ) + ppc_md.progress("ev64260_setup_arch: find_bridges", 0); + + /* + * Set up the L2CR register. + * L2 cache was invalidated by bootloader. + */ + switch (PVR_VER(mfspr(PVR))) { + case PVR_VER(PVR_750): + _set_L2CR(0xfd100000); + break; + case PVR_VER(PVR_7400): + case PVR_VER(PVR_7410): + _set_L2CR(0xcd100000); + break; + /* case PVR_VER(PVR_7450): */ + /* XXXX WHAT VALUE?? FIXME */ + break; + } + + ev64260_setup_bridge(); + + TODC_INIT(TODC_TYPE_DS1501, 0, 0, ioremap(EV64260_TODC_BASE,0x20), 8); + +#if !defined(CONFIG_GT64260_CONSOLE) + memset(&serial_req, 0, sizeof(serial_req)); + serial_req.line = 0; + serial_req.baud_base = BASE_BAUD; + serial_req.port = 0; + serial_req.irq = 85; + serial_req.flags = STD_COM_FLAGS; + serial_req.io_type = SERIAL_IO_MEM; + serial_req.iomem_base = ioremap(EV64260_SERIAL_0, 0x20); + serial_req.iomem_reg_shift = 2; + + if (early_serial_setup(&serial_req) != 0) { + printk("Early serial init of port 0 failed\n"); + } + + /* Assume early_serial_setup() doesn't modify serial_req */ + serial_req.line = 1; + serial_req.port = 1; + serial_req.irq = 86; + serial_req.iomem_base = ioremap(EV64260_SERIAL_1, 0x20); + + if (early_serial_setup(&serial_req) != 0) { + printk("Early serial init of port 1 failed\n"); + } +#endif + + printk("Marvell/Galileo EV-64260-BP Evaluation Board\n"); + printk("EV-64260-BP port (C) 2001 MontaVista Software, Inc. (source@mvista.com)\n"); + + if ( ppc_md.progress ) + ppc_md.progress("ev64260_setup_arch: exit", 0); + + return; +} + +static void __init +ev64260_init_irq(void) +{ + gt64260_init_irq(); + + if(gt64260_revision != GT64260) { + /* XXXX Kludge--need to fix gt64260_init_irq() interface */ + /* Mark PCI intrs level sensitive */ + irq_desc[91].status |= IRQ_LEVEL; + irq_desc[93].status |= IRQ_LEVEL; + } +} + +unsigned long __init +ev64260_find_end_of_memory(void) +{ + return 32*1024*1024; /* XXXX FIXME */ +} + +static void +ev64260_reset_board(void) +{ + __cli(); + + /* Set exception prefix high - to the firmware */ + _nmask_and_or_msr(0, MSR_IP); + + /* XXX FIXME */ + printk("XXXX **** trying to reset board ****\n"); + return; +} + +static void +ev64260_restart(char *cmd) +{ + volatile ulong i = 10000000; + + ev64260_reset_board(); + + while (i-- > 0); + panic("restart failed\n"); +} + +static void +ev64260_halt(void) +{ + __cli(); + while (1); + /* NOTREACHED */ +} + +static void +ev64260_power_off(void) +{ + ev64260_halt(); + /* NOTREACHED */ +} + +static int +ev64260_show_cpuinfo(struct seq_file *m) +{ + uint pvid; + + pvid = mfspr(PVR); + seq_printf(m, "vendor\t\t: Marvell/Galileo\n"); + seq_printf(m, "machine\t\t: EV-64260-BP\n"); + seq_printf(m, "PVID\t\t: 0x%x, vendor: %s\n", + pvid, (pvid & (1<<15) ? "IBM" : "Motorola")); + + return 0; +} + +/* DS1501 RTC has too much variation to use RTC for calibration */ +static void __init +ev64260_calibrate_decr(void) +{ + ulong freq; + + freq = 100000000 / 4; + + printk("time_init: decrementer frequency = %lu.%.6lu MHz\n", + freq/1000000, freq%1000000); + + tb_ticks_per_jiffy = freq / HZ; + tb_to_us = mulhwu_scale_factor(freq, 1000000); + + return; +} + +#if defined(CONFIG_SERIAL_TEXT_DEBUG) +/* + * Set BAT 3 to map 0xf0000000 to end of physical memory space. + */ +static __inline__ void +ev64260_set_bat(void) +{ + unsigned long bat3u, bat3l; + static int mapping_set = 0; + + if (!mapping_set) { + + __asm__ __volatile__( + " lis %0,0xf000\n \ + ori %1,%0,0x002a\n \ + ori %0,%0,0x1ffe\n \ + mtspr 0x21e,%0\n \ + mtspr 0x21f,%1\n \ + isync\n \ + sync " + : "=r" (bat3u), "=r" (bat3l)); + + mapping_set = 1; + } + + return; +} + +#if !defined(CONFIG_GT64260_CONSOLE) +#include <linux/serialP.h> +#include <linux/serial_reg.h> +#include <asm/serial.h> + +static struct serial_state rs_table[RS_TABLE_SIZE] = { + SERIAL_PORT_DFNS /* Defined in <asm/serial.h> */ +}; + +static void +ev64260_16550_progress(char *s, unsigned short hex) +{ + volatile char c; + volatile unsigned long com_port; + u16 shift; + + com_port = rs_table[0].port; + shift = rs_table[0].iomem_reg_shift; + + while ((c = *s++) != 0) { + while ((*((volatile unsigned char *)com_port + + (UART_LSR << shift)) & UART_LSR_THRE) == 0) + ; + *(volatile unsigned char *)com_port = c; + + if (c == '\n') { + while ((*((volatile unsigned char *)com_port + + (UART_LSR << shift)) & UART_LSR_THRE) == 0) + ; + *(volatile unsigned char *)com_port = '\r'; + } + } + + /* Move to next line on */ + while ((*((volatile unsigned char *)com_port + + (UART_LSR << shift)) & UART_LSR_THRE) == 0) + ; + *(volatile unsigned char *)com_port = '\n'; + while ((*((volatile unsigned char *)com_port + + (UART_LSR << shift)) & UART_LSR_THRE) == 0) + ; + *(volatile unsigned char *)com_port = '\r'; + + return; +} +#endif /* !CONFIG_GT64260_CONSOLE */ +#endif /* CONFIG_SERIAL_TEXT_DEBUG */ + +void __init +platform_init(unsigned long r3, unsigned long r4, unsigned long r5, + unsigned long r6, unsigned long r7) +{ + parse_bootinfo(find_bootinfo()); + + isa_mem_base = 0; + + ppc_md.setup_arch = ev64260_setup_arch; + ppc_md.show_cpuinfo = ev64260_show_cpuinfo; + ppc_md.irq_cannonicalize = NULL; + ppc_md.init_IRQ = ev64260_init_irq; + ppc_md.get_irq = gt64260_get_irq; + ppc_md.init = NULL; + + ppc_md.restart = ev64260_restart; + ppc_md.power_off = ev64260_power_off; + ppc_md.halt = ev64260_halt; + + ppc_md.find_end_of_memory = ev64260_find_end_of_memory; + + ppc_md.time_init = todc_time_init; + ppc_md.set_rtc_time = todc_set_rtc_time; + ppc_md.get_rtc_time = todc_get_rtc_time; + ppc_md.calibrate_decr = ev64260_calibrate_decr; + + ppc_md.nvram_read_val = todc_direct_read_val; + ppc_md.nvram_write_val = todc_direct_write_val; + + ppc_md.heartbeat = NULL; + ppc_md.heartbeat_reset = 0; + ppc_md.heartbeat_count = 0; + +#ifdef CONFIG_SERIAL_TEXT_DEBUG + ev64260_set_bat(); +#ifdef CONFIG_GT64260_CONSOLE + gt64260_base = EV64260_BRIDGE_REG_BASE; + ppc_md.progress = gt64260_mpsc_progress; /* embedded UART */ +#else + ppc_md.progress = ev64260_16550_progress; /* Dev module DUART */ +#endif +#else /* !CONFIG_SERIAL_TEXT_DEBUG */ + ppc_md.progress = NULL; +#endif /* CONFIG_SERIAL_TEXT_DEBUG */ + + return; +} diff --git a/include/asm-ppc/fads.h b/arch/ppc/platforms/fads.h index 386024c9f286..386024c9f286 100644 --- a/include/asm-ppc/fads.h +++ b/arch/ppc/platforms/fads.h diff --git a/include/asm-ppc/gemini.h b/arch/ppc/platforms/gemini.h index 9c978322870d..f1dc4aa8a4c8 100644 --- a/include/asm-ppc/gemini.h +++ b/arch/ppc/platforms/gemini.h @@ -1,8 +1,8 @@ /* - * BK Id: SCCS/s.gemini.h 1.5 05/17/01 18:14:24 cort + * BK Id: %F% %I% %G% %U% %#% */ /* - * include/asm-ppc/gemini.h + * include/asm-ppc/platforms/gemini.h * * * Onboard registers and descriptions for Synergy Microsystems' diff --git a/arch/ppc/kernel/gemini_pci.c b/arch/ppc/platforms/gemini_pci.c index c3d93c483b4d..2572bcef7053 100644 --- a/arch/ppc/kernel/gemini_pci.c +++ b/arch/ppc/platforms/gemini_pci.c @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.gemini_pci.c 1.6 10/11/01 08:51:46 trini + * BK Id: %F% %I% %G% %U% %#% */ #include <linux/kernel.h> #include <linux/init.h> @@ -7,14 +7,12 @@ #include <linux/slab.h> #include <asm/machdep.h> -#include <asm/gemini.h> +#include <platforms/gemini.h> #include <asm/byteorder.h> #include <asm/io.h> #include <asm/uaccess.h> #include <asm/pci-bridge.h> -#include "pci.h" - #define pci_config_addr(bus,dev,offset) \ (0x80000000 | (bus<<16) | (dev<<8) | offset) diff --git a/arch/ppc/kernel/gemini_prom.S b/arch/ppc/platforms/gemini_prom.S index e2a09b9d89dc..c6c78055d233 100644 --- a/arch/ppc/kernel/gemini_prom.S +++ b/arch/ppc/platforms/gemini_prom.S @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.gemini_prom.S 1.5 05/17/01 18:14:21 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * arch/ppc/kernel/gemini_prom.S @@ -11,12 +11,11 @@ * ---Dan */ -#include "ppc_asm.tmpl" -#include "ppc_defs.h" #include <linux/config.h> #include <asm/processor.h> #include <asm/page.h> -#include <asm/gemini.h> +#include <platforms/gemini.h> +#include <asm/ppc_asm.h> #define HID0_ABE (1<<3) diff --git a/include/asm-ppc/gemini_serial.h b/arch/ppc/platforms/gemini_serial.h index 925024df4db8..a29d655f8425 100644 --- a/include/asm-ppc/gemini_serial.h +++ b/arch/ppc/platforms/gemini_serial.h @@ -1,12 +1,12 @@ /* - * BK Id: SCCS/s.gemini_serial.h 1.5 05/17/01 18:14:24 cort + * BK Id: %F% %I% %G% %U% %#% */ #ifdef __KERNEL__ #ifndef __ASMPPC_GEMINI_SERIAL_H #define __ASMPPC_GEMINI_SERIAL_H #include <linux/config.h> -#include <asm/gemini.h> +#include <platforms/gemini.h> #ifdef CONFIG_SERIAL_MANY_PORTS #define RS_TABLE_SIZE 64 diff --git a/arch/ppc/kernel/gemini_setup.c b/arch/ppc/platforms/gemini_setup.c index e390a83db0e4..efa4652d38ff 100644 --- a/arch/ppc/kernel/gemini_setup.c +++ b/arch/ppc/platforms/gemini_setup.c @@ -1,8 +1,8 @@ /* - * BK Id: SCCS/s.gemini_setup.c 1.14 10/18/01 11:16:28 trini + * BK Id: %F% %I% %G% %U% %#% */ /* - * linux/arch/ppc/kernel/setup.c + * arch/ppc/platforms/setup.c * * Copyright (C) 1995 Linus Torvalds * Adapted from 'alpha' version by Gary Thomas @@ -15,7 +15,7 @@ #include <linux/stddef.h> #include <linux/kernel.h> #include <linux/init.h> -#include <linux/errno.h> +#include <linux/errno.h> #include <linux/reboot.h> #include <linux/pci.h> #include <linux/time.h> @@ -24,6 +24,7 @@ #include <linux/major.h> #include <linux/blk.h> #include <linux/console.h> +#include <linux/irq.h> #include <linux/seq_file.h> #include <asm/system.h> @@ -32,11 +33,10 @@ #include <asm/dma.h> #include <asm/io.h> #include <asm/m48t35.h> -#include <asm/gemini.h> +#include <platforms/gemini.h> #include <asm/time.h> - -#include "local_irq.h" -#include "open_pic.h" +#include <asm/open_pic.h> +#include <asm/bootinfo.h> void gemini_find_bridges(void); static int gemini_get_clock_speed(void); @@ -100,7 +100,7 @@ gemini_show_cpuinfo(struct seq_file *m) reg = readb(GEMINI_BECO); - seq_printf(m, "machine\t\t: Gemini %s%d, rev %c, eco %d\n", + seq_printf(m, "machine\t\t: Gemini %s%d, rev %c, eco %d\n", family, type, (rev + 'A'), (reg & 0xf)); seq_printf(m, "board\t\t: Gemini %s", family); @@ -151,6 +151,7 @@ gemini_heartbeat(void) static unsigned long led = GEMINI_LEDBASE+(4*8); static char direction = 8; + /* We only want to do this on 1 CPU */ if (smp_processor_id()) return; @@ -186,7 +187,7 @@ void __init gemini_setup_arch(void) ppc_md.heartbeat = gemini_heartbeat; ppc_md.heartbeat_reset = HZ/8; ppc_md.heartbeat_count = 1; - + /* Lookup PCI hosts */ gemini_find_bridges(); /* take special pains to map the MPIC, since it isn't mapped yet */ @@ -216,11 +217,11 @@ gemini_get_clock_speed(void) default: clock = (hid1*100)/3; break; - + case 1: clock = (hid1*125)/3; break; - + case 2: clock = (hid1*50); break; @@ -274,7 +275,7 @@ void __init gemini_init_l2(void) case 12: { static unsigned long l2_size_val = 0; - + if (!l2_size_val) l2_size_val = _get_L2CR(); cache = l2_size_val; @@ -358,7 +359,7 @@ gemini_get_rtc_time(void) #ifdef DEBUG_RTC printk("get rtc: reg = %x\n", reg); #endif - + do { sec = gemini_rtc_read(M48T35_RTC_SECONDS); min = gemini_rtc_read(M48T35_RTC_MINUTES); @@ -368,7 +369,7 @@ gemini_get_rtc_time(void) year = gemini_rtc_read(M48T35_RTC_YEAR); } while( sec != gemini_rtc_read(M48T35_RTC_SECONDS)); #ifdef DEBUG_RTC - printk("get rtc: sec=%x, min=%x, hour=%x, day=%x, mon=%x, year=%x\n", + printk("get rtc: sec=%x, min=%x, hour=%x, day=%x, mon=%x, year=%x\n", sec, min, hour, day, mon, year); #endif @@ -384,7 +385,7 @@ gemini_get_rtc_time(void) if ((year += 1900) < 1970) year += 100; #ifdef DEBUG_RTC - printk("get rtc: sec=%x, min=%x, hour=%x, day=%x, mon=%x, year=%x\n", + printk("get rtc: sec=%x, min=%x, hour=%x, day=%x, mon=%x, year=%x\n", sec, min, hour, day, mon, year); #endif @@ -404,13 +405,13 @@ gemini_set_rtc_time( unsigned long now ) #if DEBUG_RTC printk("set rtc: reg = %x\n", reg); #endif - + gemini_rtc_write((reg|M48T35_RTC_SET), M48T35_RTC_CONTROL); #if DEBUG_RTC printk("set rtc: tm vals - sec=%x, min=%x, hour=%x, mon=%x, mday=%x, year=%x\n", tm.tm_sec, tm.tm_min, tm.tm_hour, tm.tm_mon, tm.tm_mday, tm.tm_year); #endif - + tm.tm_year -= 1900; BIN_TO_BCD(tm.tm_sec); BIN_TO_BCD(tm.tm_min); @@ -435,7 +436,7 @@ gemini_set_rtc_time( unsigned long now ) if ((time_state == TIME_ERROR) || (time_state == TIME_BAD)) time_state = TIME_OK; - + return 0; } @@ -534,9 +535,15 @@ void __init platform_init(unsigned long r3, unsigned long r4, unsigned long r5, { int i; + /* Restore BATs for now */ + mtspr(DBAT3U, 0xf0001fff); + mtspr(DBAT3L, 0xf000002a); + + parse_bootinfo(find_bootinfo()); + for(i = 0; i < GEMINI_LEDS; i++) gemini_led_off(i); - + ISA_DMA_THRESHOLD = 0; DMA_MODE_READ = 0; DMA_MODE_WRITE = 0; diff --git a/arch/ppc/platforms/hermes.h b/arch/ppc/platforms/hermes.h new file mode 100644 index 000000000000..2f4f2bcc3915 --- /dev/null +++ b/arch/ppc/platforms/hermes.h @@ -0,0 +1,27 @@ +/* + * Multidata HERMES-PRO ( / SL ) board specific definitions + * + * Copyright (c) 2000, 2001 Wolfgang Denk (wd@denx.de) + */ + +#ifndef __MACH_HERMES_H +#define __MACH_HERMES_H + +#include <linux/config.h> + +#include <asm/ppcboot.h> + +#define HERMES_IMMR_BASE 0xFF000000 /* phys. addr of IMMR */ +#define HERMES_IMAP_SIZE (64 * 1024) /* size of mapped area */ + +#define IMAP_ADDR HERMES_IMMR_BASE /* physical base address of IMMR area */ +#define IMAP_SIZE HERMES_IMAP_SIZE /* mapped size of IMMR area */ + +#define FEC_INTERRUPT 9 /* = SIU_LEVEL4 */ +#define CPM_INTERRUPT 11 /* = SIU_LEVEL5 (was: SIU_LEVEL2) */ + +/* We don't use the 8259. +*/ +#define NR_8259_INTS 0 + +#endif /* __MACH_HERMES_H */ diff --git a/arch/ppc/platforms/iSeries_dma.c b/arch/ppc/platforms/iSeries_dma.c new file mode 100644 index 000000000000..e6f8e2c6630b --- /dev/null +++ b/arch/ppc/platforms/iSeries_dma.c @@ -0,0 +1,1049 @@ +/* + * iSeries_dma.c + * Copyright (C) 2001 Mike Corrigan IBM Corporation + * + * Dynamic DMA mapping support. + * + * Manages the TCE space assigned to this partition + * + * modeled from pci-dma.c + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <linux/init.h> +#include <linux/types.h> +#include <linux/slab.h> +#include <linux/mm.h> +#include <linux/spinlock.h> +#include <linux/string.h> +#include <linux/pci.h> +#include <asm/io.h> +#include <asm/iSeries/HvCallXm.h> +#include <asm/iSeries/LparData.h> +#include <asm/iSeries/iSeries_dma.h> +#include <asm/iSeries/iSeries_pci.h> + +struct pci_dev * iSeries_veth_dev = NULL; +struct pci_dev * iSeries_vio_dev = NULL; + +struct TceTable virtBusTceTable; /* Tce table for virtual bus */ + +struct TceTable * tceTables[256]; // Tce tables for 256 busses + // Bus 255 is the virtual bus + // zero indicates no bus defined + // allocates a contiguous range of tces (power-of-2 size) +static long alloc_tce_range( struct TceTable *, + unsigned order ); + // allocates a contiguous range of tces (power-of-2 size) + // assumes lock already held +static long alloc_tce_range_nolock( struct TceTable *, + unsigned order ); + // frees a contiguous range of tces (power-of-2 size) +static void free_tce_range( struct TceTable *, + long tcenum, + unsigned order ); + // frees a contiguous rnage of tces (power-of-2 size) + // assumes lock already held +static void free_tce_range_nolock( struct TceTable *, + long tcenum, + unsigned order ); + // allocates a range of tces and sets them to the + // pages +static dma_addr_t get_tces( struct TceTable *, + unsigned order, + void *page, + unsigned numPages, + int tceType, + int direction ); +static void free_tces( struct TceTable *, + dma_addr_t tce, + unsigned order, + unsigned numPages ); +static long test_tce_range( struct TceTable *, + long tcenum, + unsigned order ); + +static unsigned fill_scatterlist_sg( struct scatterlist *sg, int nents, + dma_addr_t dma_addr, unsigned long numTces ); + +static unsigned long num_tces_sg( struct scatterlist *sg, + int nents ); + +static dma_addr_t create_tces_sg( struct TceTable *tbl, + struct scatterlist *sg, + int nents, + unsigned numTces, + int tceType, + int direction ); + +static unsigned __inline__ count_leading_zeros32( unsigned long x ) +{ + unsigned lz; + asm("cntlzw %0,%1" : "=r"(lz) : "r"(x)); + return lz; +} + +static void __inline__ build_tce( struct TceTable * tbl, long tcenum, + unsigned long uaddr, int tceType, int direction ) +{ + union Tce tce; + + tce.wholeTce = 0; + tce.tceBits.rpn = (virt_to_absolute(uaddr)) >> PAGE_SHIFT; + // If for virtual bus + if ( tceType == TCE_VB ) { + tce.tceBits.valid = 1; + tce.tceBits.allIo = 1; + if ( direction != PCI_DMA_TODEVICE ) + tce.tceBits.readWrite = 1; + } + // If for PCI bus + else { + tce.tceBits.readWrite = 1; // Read allowed + if ( direction != PCI_DMA_TODEVICE ) + tce.tceBits.pciWrite = 1; + } + HvCallXm_setTce( (u64)tbl->index, (u64)tcenum, tce.wholeTce ); + +} + + + +// Build a TceTable structure. This contains a multi-level bit map which +// is used to manage allocation of the tce space. + +struct TceTable * build_tce_table( struct HvTceTableManagerCB * tceTableParms, + struct TceTable * tbl ) +{ + unsigned long bits, bytes, totalBytes; + unsigned long numBits[NUM_TCE_LEVELS], numBytes[NUM_TCE_LEVELS]; + unsigned i, k, m; + unsigned char * pos, * p, b; + + tbl->size = tceTableParms->size; + tbl->busNumber = tceTableParms->busNumber; + tbl->startOffset = tceTableParms->startOffset; + tbl->index = tceTableParms->index; + spin_lock_init( &(tbl->lock) ); + + tbl->mlbm.maxLevel = 0; + + // Compute number of bits and bytes for each level of the + // multi-level bit map + // + totalBytes = 0; + bits = tbl->size * (PAGE_SIZE / sizeof( union Tce )); + + for ( i=0; i<NUM_TCE_LEVELS; ++i ) { + bytes = (bits+7)/8; +#ifdef DEBUG_TCE + printk("build_tce_table: level %d bits=%ld, bytes=%ld\n", i, bits, bytes ); +#endif + numBits[i] = bits; + numBytes[i] = bytes; + bits /= 2; + /* we need extra space at the end that's a multiple of 8 bytes */ + /* for the cntlzw algorithm to work correctly. */ + /* but we don't want the bits turned on or used, so we don't muck with numBytes[i] */ + totalBytes += (bytes + 7) & ~7; + } +#ifdef DEBUG_TCE + printk("build_tce_table: totalBytes=%ld\n", totalBytes ); +#endif + + pos = (char *)__get_free_pages( GFP_ATOMIC, get_order( totalBytes )); + if ( !pos ) + return NULL; + + memset( pos, 0, totalBytes ); + + // For each level, fill in the pointer to the bit map, + // and turn on the last bit in the bit map (if the + // number of bits in the map is odd). The highest + // level will get all of its bits turned on. + + for (i=0; i<NUM_TCE_LEVELS; ++i) { + if ( numBytes[i] ) { + tbl->mlbm.level[i].map = pos; + tbl->mlbm.maxLevel = i; + + if ( numBits[i] & 1 ) { + p = pos + numBytes[i] - 1; + m = (( numBits[i] % 8) - 1) & 7; + *p = 0x80 >> m; +#ifdef DEBUG_TCE + printk("build_tce_table: level %d last bit %x\n", i, 0x80>>m ); +#endif + } + } + else + tbl->mlbm.level[i].map = 0; + /* see the comment up above on the totalBytes calculation for why we do this. */ + pos += (numBytes[i] + 7) & ~7; + tbl->mlbm.level[i].numBits = numBits[i]; + tbl->mlbm.level[i].numBytes = numBytes[i]; + + } + + // For the highest level, turn on all the bits + + i = tbl->mlbm.maxLevel; + p = tbl->mlbm.level[i].map; + m = numBits[i]; +#ifdef DEBUG_TCE + printk("build_tce_table: highest level (%d) has all bits set\n", i); +#endif + for (k=0; k<numBytes[i]; ++k) { + if ( m >= 8 ) { + // handle full bytes + *p++ = 0xff; + m -= 8; + } + else { + // handle the last partial byte + b = 0x80; + *p = 0; + while (m) { + *p |= b; + b >>= 1; + --m; + } + } + } + + return tbl; + +} + +static long alloc_tce_range( struct TceTable *tbl, unsigned order ) +{ + long retval; + unsigned long flags; + + // Lock the tce allocation bitmap + spin_lock_irqsave( &(tbl->lock), flags ); + + // Do the actual work + retval = alloc_tce_range_nolock( tbl, order ); + + // Unlock the tce allocation bitmap + spin_unlock_irqrestore( &(tbl->lock), flags ); + + return retval; +} + +static long alloc_tce_range_nolock( struct TceTable *tbl, unsigned order ) +{ + unsigned long numBits, numBytes; + unsigned long i, bit, block, mask; + long tcenum; + u32 * map; + + // If the order (power of 2 size) requested is larger than our + // biggest, indicate failure + if ( order > tbl->mlbm.maxLevel ) { +#ifdef DEBUG_TCE + printk("alloc_tce_range_nolock: invalid order requested, order = %d\n", order ); +#endif + return -1; + } + + numBits = tbl->mlbm.level[order].numBits; + numBytes = tbl->mlbm.level[order].numBytes; + map = (u32 *)(tbl->mlbm.level[order].map); + + // Initialize return value to -1 (failure) + tcenum = -1; + + // Loop through the bytes of the bitmap + for (i=0; i<numBytes/4; ++i) { + if ( *map ) { + // A free block is found, compute the block + // number (of this size) + bit = count_leading_zeros32( *map ); + block = (i * 32) + bit; + // turn off the bit in the map to indicate + // that the block is now in use + mask = 0xffffffff ^ (0x80000000 >> bit); + *map &= mask; + // compute the index into our tce table for + // the first tce in the block +#ifdef DEBUG_TCE + printk("alloc_tce_range_nolock: allocating block %ld, (byte=%ld, bit=%ld) order %d\n", block, i, bit, order ); +#endif + tcenum = block << order; + break; + } + ++map; + } + +#ifdef DEBUG_TCE + if ( tcenum == -1 ) { + printk("alloc_tce_range_nolock: no available blocks of order = %d\n", order ); + if ( order < tbl->mlbm.maxLevel ) + printk("alloc_tce_range_nolock: trying next bigger size\n" ); + else + printk("alloc_tce_range_nolock: maximum size reached...failing\n"); + } +#endif + + // If no block of the requested size was found, try the next + // size bigger. If one of those is found, return the second + // half of the block to freespace and keep the first half + if ( ( tcenum == -1 ) && ( order < tbl->mlbm.maxLevel ) ) { + tcenum = alloc_tce_range_nolock( tbl, order+1 ); + if ( tcenum != -1 ) { + free_tce_range_nolock( tbl, tcenum+(1<<order), order ); + } + } + + // Return the index of the first tce in the block + // (or -1 if we failed) + return tcenum; + +} + +static void free_tce_range( struct TceTable *tbl, long tcenum, unsigned order ) +{ + unsigned long flags; + + // Lock the tce allocation bitmap + spin_lock_irqsave( &(tbl->lock), flags ); + + // Do the actual work + free_tce_range_nolock( tbl, tcenum, order ); + + // Unlock the tce allocation bitmap + spin_unlock_irqrestore( &(tbl->lock), flags ); + +} + +static void free_tce_range_nolock( struct TceTable *tbl, long tcenum, unsigned order ) +{ + unsigned long block; + unsigned byte, bit, mask, b; + unsigned char * map, * bytep; + + if ( order > tbl->mlbm.maxLevel ) { + printk("free_tce_range: order too large, order = %d\n", order ); + return; + } + + block = tcenum >> order; + if ( tcenum != (block << order ) ) { + printk("free_tce_range: tcenum %lx is not on appropriate boundary for order %x\n", tcenum, order ); + return; + } + if ( block >= tbl->mlbm.level[order].numBits ) { + printk("free_tce_range: tcenum %lx is outside the range of this map (order %x, numBits %lx\n", tcenum, order, tbl->mlbm.level[order].numBits ); + return; + } +#ifdef DEBUG_TCE + if ( test_tce_range( tbl, tcenum, order ) ) { + printk("free_tce_range: freeing range not completely allocated.\n"); + printk("free_tce_range: TceTable %p, tcenum %lx, order %x\n", tbl, tcenum, order ); + } +#endif + map = tbl->mlbm.level[order].map; + byte = block / 8; + bit = block % 8; + mask = 0x80 >> bit; + bytep = map + byte; +#ifdef DEBUG_TCE + printk("free_tce_range_nolock: freeing block %ld (byte=%d, bit=%d) of order %d\n",block, byte, bit, order); + if ( *bytep & mask ) + printk("free_tce_range: already free: TceTable %p, tcenum %lx, order %x\n", tbl, tcenum, order ); +#endif + *bytep |= mask; + + // If there is a higher level in the bit map than this we may be + // able to buddy up this block with its partner. + // If this is the highest level we can't buddy up + // If this level has an odd number of bits and + // we are freeing the last block we can't buddy up + // don't buddy up if it's in the first 1/4 of the bits + if ( ( order < tbl->mlbm.maxLevel ) && + ( ( 0 == ( tbl->mlbm.level[order].numBits & 1 ) ) || + ( block < tbl->mlbm.level[order].numBits-1 ) ) && + ( block > (tbl->mlbm.level[order].numBits/4) ) ) { + + // See if we can buddy up the block we just freed + bit &= 6; // get to the first of the buddy bits + mask = 0xc0 >> bit; // build two bit mask + b = *bytep & mask; // Get the two bits + if ( 0 == (b ^ mask) ) { // If both bits are on + // both of the buddy blocks are free we can combine them + *bytep ^= mask; // turn off the two bits + block = ( byte * 8 ) + bit; // block of first of buddies + tcenum = block << order; + // free the buddied block +#ifdef DEBUG_TCE + printk("free_tce_range: buddying up block %ld and block %ld\n", block, block+1); +#endif + free_tce_range_nolock( tbl, tcenum, order+1 ); + } + } +} + +static long test_tce_range( struct TceTable *tbl, long tcenum, unsigned order ) +{ + unsigned long block; + unsigned byte, bit, mask, b; + long retval, retLeft, retRight; + unsigned char * map; + + map = tbl->mlbm.level[order].map; + block = tcenum >> order; + byte = block / 8; // Byte within bitmap + bit = block % 8; // Bit within byte + mask = 0x80 >> bit; + b = (*(map+byte) & mask ); // 0 if block is allocated, else free + if ( b ) + retval = 1; // 1 == block is free + else + retval = 0; // 0 == block is allocated + // Test bits at all levels below this to ensure that all agree + + if (order) { + retLeft = test_tce_range( tbl, tcenum, order-1 ); + retRight = test_tce_range( tbl, tcenum+(1<<(order-1)), order-1 ); + if ( retLeft || retRight ) { + retval = 2; + } + } + + // Test bits at all levels above this to ensure that all agree + + return retval; +} + +static dma_addr_t get_tces( struct TceTable *tbl, unsigned order, void *page, unsigned numPages, int tceType, int direction ) +{ + long tcenum; + unsigned long uaddr; + unsigned i; + dma_addr_t retTce = NO_TCE; + + uaddr = (unsigned long)page & PAGE_MASK; + + // Allocate a range of tces + tcenum = alloc_tce_range( tbl, order ); + if ( tcenum != -1 ) { + // We got the tces we wanted + tcenum += tbl->startOffset; // Offset into real TCE table + retTce = tcenum << PAGE_SHIFT; // Set the return dma address + // Setup a tce for each page + for (i=0; i<numPages; ++i) { + build_tce( tbl, tcenum, uaddr, tceType, direction ); + ++tcenum; + uaddr += PAGE_SIZE; + } + } +#ifdef DEBUG_TCE + else + printk("alloc_tce_range failed\n"); +#endif + return retTce; +} + +static void free_tces( struct TceTable *tbl, dma_addr_t dma_addr, unsigned order, unsigned numPages ) +{ + long tcenum, freeTce, maxTcenum; + unsigned i; + union Tce tce; + + maxTcenum = (tbl->size * (PAGE_SIZE / sizeof(union Tce))) - 1; + + tcenum = dma_addr >> PAGE_SHIFT; + tcenum -= tbl->startOffset; + + if ( tcenum > maxTcenum ) { + printk("free_tces: tcenum > maxTcenum, tcenum = %ld, maxTcenum = %ld\n", + tcenum, maxTcenum ); + printk("free_tces: TCE Table at %16lx\n", (unsigned long)tbl ); + printk("free_tces: bus# %lu\n", (unsigned long)tbl->busNumber ); + printk("free_tces: size %lu\n", (unsigned long)tbl->size ); + printk("free_tces: startOff %lu\n", (unsigned long)tbl->startOffset ); + printk("free_tces: index %lu\n", (unsigned long)tbl->index ); + return; + } + + freeTce = tcenum; + + for (i=0; i<numPages; ++i) { + tce.wholeTce = 0; + HvCallXm_setTce( (u64)tbl->index, (u64)tcenum, tce.wholeTce ); + ++tcenum; + } + + free_tce_range( tbl, freeTce, order ); + +} + +void __init create_virtual_bus_tce_table(void) +{ + struct TceTable * t; + struct HvTceTableManagerCB virtBusTceTableParms; + u64 absParmsPtr; + + virtBusTceTableParms.busNumber = 255; /* Bus 255 is the virtual bus */ + virtBusTceTableParms.virtualBusFlag = 0xff; /* Ask for virtual bus */ + + absParmsPtr = virt_to_absolute( (u32)&virtBusTceTableParms ); + HvCallXm_getTceTableParms( absParmsPtr ); + + t = build_tce_table( &virtBusTceTableParms, &virtBusTceTable ); + if ( t ) { + tceTables[255] = t; + printk("Virtual Bus TCE table built successfully.\n"); + printk(" TCE table size = %ld entries\n", + (unsigned long)t->size*(PAGE_SIZE/sizeof(union Tce)) ); + printk(" TCE table token = %d\n", + (unsigned)t->index ); + printk(" TCE table start entry = 0x%lx\n", + (unsigned long)t->startOffset ); + } + else + printk("Virtual Bus TCE table failed.\n"); +} + +void __init create_pci_bus_tce_table( unsigned busNumber ) +{ + struct TceTable * t; + struct TceTable * newTceTable; + struct HvTceTableManagerCB pciBusTceTableParms; + u64 absParmsPtr; + unsigned i; + + if ( busNumber > 254 ) { + printk("PCI Bus TCE table failed.\n"); + printk(" Invalid bus number %u\n", busNumber ); + return; + } + + newTceTable = kmalloc( sizeof(struct TceTable), GFP_KERNEL ); + + pciBusTceTableParms.busNumber = busNumber; + pciBusTceTableParms.virtualBusFlag = 0; + + absParmsPtr = virt_to_absolute( (u32)&pciBusTceTableParms ); + HvCallXm_getTceTableParms( absParmsPtr ); + + // Determine if the table identified by the index and startOffset + // returned by the hypervisor for this bus has already been created. + + for ( i=0; i<255; ++i) { + t = tceTables[i]; + if ( t ) { + if ( ( t->index == pciBusTceTableParms.index ) && + ( t->startOffset == pciBusTceTableParms.startOffset ) ) { + if ( t->size != pciBusTceTableParms.size ) + printk("PCI Bus %d Shares a TCE table with Bus %d, but sizes differ\n", busNumber, i ); + else + printk("PCI Bus %d Shares a TCE table with bus %d\n", busNumber, i ); + tceTables[busNumber] = t; + break; + } + } + } + + if ( ! tceTables[busNumber] ) { + + t = build_tce_table( &pciBusTceTableParms, newTceTable ); + if ( t ) { + tceTables[busNumber] = t; + printk("PCI Bus %d TCE table built successfully.\n", busNumber); + printk(" TCE table size = %ld entries\n", + (unsigned long)t->size*(PAGE_SIZE/sizeof(union Tce)) ); + printk(" TCE table token = %d\n", + (unsigned)t->index ); + printk(" TCE table start entry = 0x%lx\n", + (unsigned long)t->startOffset ); + } + else { + kfree( newTceTable ); + printk("PCI Bus %d TCE table failed.\n", busNumber ); + } + } +} + + +// Allocates a contiguous real buffer and creates TCEs over it. +// Returns the virtual address of the buffer and sets dma_handle +// to the dma address (tce) of the first page. +void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size, + dma_addr_t *dma_handle) +{ + struct TceTable * tbl; + void *ret = NULL; + unsigned order, nPages, bus; + dma_addr_t tce; + int tceType; + + size = PAGE_ALIGN(size); + order = get_order(size); + nPages = 1 << order; + + // If no pci_dev then use virtual bus + if (hwdev == NULL ) { + bus = 255; + tceType = TCE_VB; + } + else { +#ifdef CONFIG_PCI + // Get the iSeries bus # to use as an index + // into the TCE table array + bus = ISERIES_GET_BUS( hwdev ); + tceType = TCE_PCI; +#else + BUG(); + return NULL; +#endif /* CONFIG_PCI */ + } + + tbl = tceTables[bus]; + if ( tbl ) { + // Alloc enough pages (and possibly more) + ret = (void *)__get_free_pages( GFP_ATOMIC, order ); + if ( ret ) { + // Page allocation succeeded + memset(ret, 0, nPages << PAGE_SHIFT); + // Set up tces to cover the allocated range + tce = get_tces( tbl, order, ret, nPages, tceType, + PCI_DMA_BIDIRECTIONAL ); + if ( tce == NO_TCE ) { +#ifdef DEBUG_TCE + printk("pci_alloc_consistent: get_tces failed\n" ); +#endif + free_pages( (unsigned long)ret, order ); + ret = NULL; + } + else + { + *dma_handle = tce; + } + } +#ifdef DEBUG_TCE + else + printk("pci_alloc_consistent: __get_free_pages failed for order = %d\n", order); +#endif + } + + return ret; +} + +void pci_free_consistent(struct pci_dev *hwdev, size_t size, + void *vaddr, dma_addr_t dma_handle) +{ + struct TceTable * tbl; + unsigned order, nPages, bus; + + size = PAGE_ALIGN(size); + order = get_order(size); + nPages = 1 << order; + + // If no pci_dev then use virtual bus + if (hwdev == NULL ) + bus = 255; + else { +#ifdef CONFIG_PCI + // Get the iSeries bus # to use as an index + // into the TCE table array + bus = ISERIES_GET_BUS( hwdev ); +#else + BUG(); + return; +#endif /* CONFIG_PCI */ + } + + if ( bus > 255 ) { + printk("pci_free_consistent: invalid bus # %d\n", bus ); + printk("pci_free_consistent: hwdev = %08lx\n", (unsigned long)hwdev ); + } + + tbl = tceTables[bus]; + + if ( tbl ) { + free_tces( tbl, dma_handle, order, nPages ); + free_pages( (unsigned long)vaddr, order ); + } +} + +// Creates TCEs for a user provided buffer. The user buffer must be +// contiguous real kernel storage (not vmalloc). The address of the buffer +// passed here is the kernel (virtual) address of the buffer. The buffer +// need not be page aligned, the dma_addr_t returned will point to the same +// byte within the page as vaddr. +dma_addr_t pci_map_single( struct pci_dev *hwdev, void *vaddr, size_t size, int direction ) +{ + struct TceTable * tbl; + dma_addr_t dma_handle; + unsigned long uaddr; + unsigned order, nPages, bus; + int tceType; + + if ( direction == PCI_DMA_NONE ) + BUG(); + + dma_handle = NO_TCE; + + uaddr = (unsigned long)vaddr; + nPages = PAGE_ALIGN( uaddr + size ) - ( uaddr & PAGE_MASK ); + order = get_order( nPages & PAGE_MASK ); + nPages >>= PAGE_SHIFT; + + // If no pci_dev then use virtual bus + if (hwdev == NULL ) { + bus = 255; + tceType = TCE_VB; + } + else { +#ifdef CONFIG_PCI + // Get the iSeries bus # to use as an index + // into the TCE table array + bus = ISERIES_GET_BUS( hwdev ); + tceType = TCE_PCI; +#else + BUG(); + return NO_TCE; +#endif /* CONFIG_PCI */ + + } + + tbl = tceTables[bus]; + + if ( tbl ) { + dma_handle = get_tces( tbl, order, vaddr, nPages, tceType, + direction ); + dma_handle |= ( uaddr & ~PAGE_MASK ); + } + + return dma_handle; +} + +void pci_unmap_single( struct pci_dev *hwdev, dma_addr_t dma_handle, size_t size, int direction ) +{ + struct TceTable * tbl; + unsigned order, nPages, bus; + + if ( direction == PCI_DMA_NONE ) + BUG(); + + nPages = PAGE_ALIGN( dma_handle + size ) - ( dma_handle & PAGE_MASK ); + order = get_order( nPages & PAGE_MASK ); + nPages >>= PAGE_SHIFT; + + // If no pci_dev then use virtual bus + if (hwdev == NULL ) + bus = 255; + else { +#ifdef CONFIG_PCI + // Get the iSeries bus # to use as an index + // into the TCE table array + bus = ISERIES_GET_BUS( hwdev ); +#else + BUG(); + return; +#endif /* CONFIG_PCI */ + } + + if ( bus > 255 ) { + printk("pci_unmap_single: invalid bus # %d\n", bus ); + printk("pci_unmap_single: hwdev = %08lx\n", (unsigned long)hwdev ); + } + + tbl = tceTables[bus]; + + if ( tbl ) + free_tces( tbl, dma_handle, order, nPages ); + +} + +// Figure out how many TCEs are actually going to be required +// to map this scatterlist. This code is not optimal. It +// takes into account the case where entry n ends in the same +// page in which entry n+1 starts. It does not handle the +// general case of entry n ending in the same page in which +// entry m starts. + +static unsigned long num_tces_sg( struct scatterlist *sg, int nents ) +{ + unsigned long nTces, numPages, startPage, endPage, prevEndPage; + unsigned i; + + prevEndPage = 0; + nTces = 0; + + for (i=0; i<nents; ++i) { + // Compute the starting page number and + // the ending page number for this entry + startPage = (unsigned long)sg->address >> PAGE_SHIFT; + endPage = ((unsigned long)sg->address + sg->length - 1) >> PAGE_SHIFT; + numPages = endPage - startPage + 1; + // Simple optimization: if the previous entry ended + // in the same page in which this entry starts + // then we can reduce the required pages by one. + // This matches assumptions in fill_scatterlist_sg and + // create_tces_sg + if ( startPage == prevEndPage ) + --numPages; + nTces += numPages; + prevEndPage = endPage; + sg++; + } + return nTces; +} + +// Fill in the dma data in the scatterlist +// return the number of dma sg entries created +static unsigned fill_scatterlist_sg( struct scatterlist *sg, int nents, + dma_addr_t dma_addr , unsigned long numTces) +{ + struct scatterlist *dma_sg; + u32 cur_start_dma; + unsigned long cur_len_dma, cur_end_virt, uaddr; + unsigned num_dma_ents; + + dma_sg = sg; + num_dma_ents = 1; + + // Process the first sg entry + cur_start_dma = dma_addr + ((unsigned long)sg->address & (~PAGE_MASK)); + cur_len_dma = sg->length; + // cur_end_virt holds the address of the byte immediately after the + // end of the current buffer. + cur_end_virt = (unsigned long)sg->address + cur_len_dma; + // Later code assumes that unused sg->dma_address and sg->dma_length + // fields will be zero. Other archs seem to assume that the user + // (device driver) guarantees that...I don't want to depend on that + sg->dma_address = sg->dma_length = 0; + + // Process the rest of the sg entries + while (--nents) { + ++sg; + // Clear possibly unused fields. Note: sg >= dma_sg so + // this can't be clearing a field we've already set + sg->dma_address = sg->dma_length = 0; + + // Check if it is possible to make this next entry + // contiguous (in dma space) with the previous entry. + + // The entries can be contiguous in dma space if + // the previous entry ends immediately before the + // start of the current entry (in virtual space) + // or if the previous entry ends at a page boundary + // and the current entry starts at a page boundary. + uaddr = (unsigned long)sg->address; + if ( ( uaddr != cur_end_virt ) && + ( ( ( uaddr | cur_end_virt ) & (~PAGE_MASK) ) || + ( ( uaddr & PAGE_MASK ) == ( ( cur_end_virt-1 ) & PAGE_MASK ) ) ) ) { + // This entry can not be contiguous in dma space. + // save the previous dma entry and start a new one + dma_sg->dma_address = cur_start_dma; + dma_sg->dma_length = cur_len_dma; + + ++dma_sg; + ++num_dma_ents; + + cur_start_dma += cur_len_dma-1; + // If the previous entry ends and this entry starts + // in the same page then they share a tce. In that + // case don't bump cur_start_dma to the next page + // in dma space. This matches assumptions made in + // num_tces_sg and create_tces_sg. + if ((uaddr & PAGE_MASK) == ((cur_end_virt-1) & PAGE_MASK)) + cur_start_dma &= PAGE_MASK; + else + cur_start_dma = PAGE_ALIGN(cur_start_dma+1); + cur_start_dma += ( uaddr & (~PAGE_MASK) ); + cur_len_dma = 0; + } + // Accumulate the length of this entry for the next + // dma entry + cur_len_dma += sg->length; + cur_end_virt = uaddr + sg->length; + } + // Fill in the last dma entry + dma_sg->dma_address = cur_start_dma; + dma_sg->dma_length = cur_len_dma; + + if ((((cur_start_dma +cur_len_dma - 1)>> PAGE_SHIFT) - (dma_addr >> PAGE_SHIFT) + 1) != numTces) + { + printk("fill_scatterlist_sg: numTces %ld, used tces %d\n", + numTces, + (unsigned)(((cur_start_dma + cur_len_dma - 1) >> PAGE_SHIFT) - (dma_addr >> PAGE_SHIFT) + 1)); + } + + + return num_dma_ents; +} + +// Call the hypervisor to create the TCE entries. +// return the number of TCEs created +static dma_addr_t create_tces_sg( struct TceTable *tbl, struct scatterlist *sg, + int nents, unsigned numTces, int tceType, int direction ) +{ + unsigned order, i, j; + unsigned long startPage, endPage, prevEndPage, numPages, uaddr; + long tcenum, starttcenum; + dma_addr_t dmaAddr; + + dmaAddr = NO_TCE; + + order = get_order( numTces << PAGE_SHIFT ); + // allocate a block of tces + tcenum = alloc_tce_range( tbl, order ); + if ( tcenum != -1 ) { + tcenum += tbl->startOffset; + starttcenum = tcenum; + dmaAddr = tcenum << PAGE_SHIFT; + prevEndPage = 0; + for (j=0; j<nents; ++j) { + startPage = (unsigned long)sg->address >> PAGE_SHIFT; + endPage = ((unsigned long)sg->address + sg->length - 1) >> PAGE_SHIFT; + numPages = endPage - startPage + 1; + + uaddr = (unsigned long)sg->address; + + // If the previous entry ended in the same page that + // the current page starts then they share that + // tce and we reduce the number of tces we need + // by one. This matches assumptions made in + // num_tces_sg and fill_scatterlist_sg + if ( startPage == prevEndPage ) { + --numPages; + uaddr += PAGE_SIZE; + } + + for (i=0; i<numPages; ++i) { + build_tce( tbl, tcenum, uaddr, tceType, + direction ); + ++tcenum; + uaddr += PAGE_SIZE; + } + + prevEndPage = endPage; + sg++; + } + if ((tcenum - starttcenum) != numTces) + printk("create_tces_sg: numTces %d, tces used %d\n", + numTces, (unsigned)(tcenum - starttcenum)); + + } + + return dmaAddr; +} + +int pci_map_sg( struct pci_dev *hwdev, struct scatterlist *sg, int nents, int direction ) +{ + struct TceTable * tbl; + unsigned bus, numTces; + int tceType, num_dma; + dma_addr_t dma_handle; + + // Fast path for a single entry scatterlist + if ( nents == 1 ) { + sg->dma_address = pci_map_single( hwdev, sg->address, + sg->length, direction ); + sg->dma_length = sg->length; + return 1; + } + + if ( direction == PCI_DMA_NONE ) + BUG(); + + // If no pci_dev then use virtual bus + if (hwdev == NULL ) { + bus = 255; + tceType = TCE_VB; + } + else { +#ifdef CONFIG_PCI + // Get the iSeries bus # to use as an index + // into the TCE table array + bus = ISERIES_GET_BUS( hwdev ); + tceType = TCE_PCI; +#else + BUG(); + return 0; +#endif /* CONFIG_PCI */ + } + + tbl = tceTables[bus]; + + if ( tbl ) { + // Compute the number of tces required + numTces = num_tces_sg( sg, nents ); + // Create the tces and get the dma address + dma_handle = create_tces_sg( tbl, sg, nents, numTces, + tceType, direction ); + + // Fill in the dma scatterlist + num_dma = fill_scatterlist_sg( sg, nents, dma_handle, numTces ); + } + + return num_dma; +} + +void pci_unmap_sg( struct pci_dev *hwdev, struct scatterlist *sg, int nelms, int direction ) +{ + struct TceTable * tbl; + unsigned order, numTces, bus, i; + dma_addr_t dma_end_page, dma_start_page; + + if ( direction == PCI_DMA_NONE ) + BUG(); + + dma_start_page = sg->dma_address & PAGE_MASK; + for ( i=nelms; i>0; --i ) { + unsigned k = i - 1; + if ( sg[k].dma_length ) { + dma_end_page = ( sg[k].dma_address + + sg[k].dma_length - 1 ) & PAGE_MASK; + break; + } + } + + numTces = ((dma_end_page - dma_start_page ) >> PAGE_SHIFT) + 1; + order = get_order( numTces << PAGE_SHIFT ); + + // If no pci_dev then use virtual bus + if (hwdev == NULL ) + bus = 255; + else { +#ifdef CONFIG_PCI + // Get the iSeries bus # to use as an index + // into the TCE table array + bus = ISERIES_GET_BUS( hwdev ); +#else + BUG(); + return; +#endif /* CONFIG_PCI */ + } + + if ( bus > 255 ) { + printk("pci_unmap_sg: invalid bus # %d\n", bus ); + printk("pci_unmap_sg: hwdev = %08lx\n", (unsigned long)hwdev ); + } + + + tbl = tceTables[bus]; + + if ( tbl ) + free_tces( tbl, dma_start_page, order, numTces ); + +} + diff --git a/arch/ppc/platforms/iSeries_pic.c b/arch/ppc/platforms/iSeries_pic.c new file mode 100644 index 000000000000..1c32a7d1d25a --- /dev/null +++ b/arch/ppc/platforms/iSeries_pic.c @@ -0,0 +1,85 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ +/* + * arch/ppc/platforms/iSeries_pic.c + * + */ + + +#include <linux/ptrace.h> +#include <linux/errno.h> +#include <linux/threads.h> +#include <linux/kernel_stat.h> +#include <linux/signal.h> +#include <linux/sched.h> +#include <linux/ioport.h> +#include <linux/interrupt.h> +#include <linux/timex.h> +#include <linux/config.h> +#include <linux/init.h> +#include <linux/slab.h> +#include <linux/pci.h> +#include <linux/delay.h> +#include <linux/irq.h> +#include <linux/proc_fs.h> +#include <linux/random.h> + +#include <asm/uaccess.h> +#include <asm/bitops.h> +#include <asm/system.h> +#include <asm/io.h> +#include <asm/pgtable.h> +#include <asm/irq.h> +#include <asm/cache.h> +#include <asm/prom.h> +#include <asm/ptrace.h> +#include <asm/iSeries/LparData.h> +extern void iSeries_smp_message_recv( struct pt_regs * ); +extern int is_soft_enabled(void); + +extern void __no_lpq_restore_flags(unsigned long flags); +extern void iSeries_smp_message_recv( struct pt_regs * ); +unsigned lpEvent_count = 0; + +int do_IRQ(struct pt_regs *regs) +{ + int cpu = smp_processor_id(); + unsigned long flags; + struct Paca * paca; + struct ItLpQueue *lpq; + + if ( is_soft_enabled() ) + BUG(); + + hardirq_enter( cpu ); + + paca = (struct Paca *)mfspr(SPRG1); + +#ifdef CONFIG_SMP + if ( paca->xLpPacaPtr->xIpiCnt ) { + paca->xLpPacaPtr->xIpiCnt = 0; + iSeries_smp_message_recv( regs ); + } +#endif /* CONFIG_SMP */ + + lpq = paca->lpQueuePtr; + if ( lpq ) { + __save_flags( flags ); + __cli(); + lpEvent_count += ItLpQueue_process( lpq, regs ); + __restore_flags( flags ); + } + + hardirq_exit( cpu ); + + if ( paca->xLpPacaPtr->xDecrInt ) { + paca->xLpPacaPtr->xDecrInt = 0; + /* Signal a fake decrementer interrupt */ + timer_interrupt( regs ); + } + + if (softirq_pending(cpu)) + do_softirq(); + return 1; /* lets ret_from_int know we can do checks */ +} diff --git a/arch/ppc/platforms/iSeries_setup.c b/arch/ppc/platforms/iSeries_setup.c new file mode 100644 index 000000000000..3a48d0ed0562 --- /dev/null +++ b/arch/ppc/platforms/iSeries_setup.c @@ -0,0 +1,822 @@ +/* + * + * + * Copyright (c) 2000 Mike Corrigan <mikejc@us.ibm.com> + * Copyright (c) 1999-2000 Grant Erickson <grant@lcse.umn.edu> + * + * Module name: iSeries_setup.c + * + * Description: + * Architecture- / platform-specific boot-time initialization code for + * the IBM iSeries LPAR. Adapted from original code by Grant Erickson and + * code by Gary Thomas, Cort Dougan <cort@fsmlabs.com>, and Dan Malek + * <dan@net4x.com>. + * + */ + +#include <linux/pci.h> +#include <linux/config.h> +#include <linux/init.h> +#include <linux/threads.h> +#include <linux/smp.h> +#include <linux/param.h> +#include <linux/string.h> +#include <linux/bootmem.h> +#include <linux/blk.h> +#include <linux/ide.h> +#include <linux/seq_file.h> + +#include <asm/processor.h> +#include <asm/machdep.h> +#include <asm/page.h> +#include <asm/bootinfo.h> + +#include <asm/time.h> +#include "iSeries_setup.h" +#include <asm/iSeries/LparData.h> +#include <asm/iSeries/HvCallHpt.h> +#include <asm/iSeries/HvLpConfig.h> +#include <asm/iSeries/HvCallEvent.h> +#include <asm/iSeries/HvCallSm.h> +#include <asm/iSeries/ItLpQueue.h> +#include <asm/iSeries/IoHriMainStore.h> +#include <asm/iSeries/iSeries_proc.h> +#include <asm/iSeries/pmc_proc.h> +#include <asm/iSeries/mf.h> +#include <asm/pci-bridge.h> +#include <asm/iSeries/HvCallXm.h> +#include <asm/iSeries/iSeries_fixup.h> +#include <asm/iSeries/HvReleaseData.h> + +/* Function Prototypes */ + +extern void abort(void); +static void build_iSeries_Memory_Map( void ); +static void setup_iSeries_cache_sizes( void ); +extern void iSeries_pci_Initialize(void); +static int iSeries_show_cpuinfo(struct seq_file *m); +static int iSeries_show_percpuinfo(struct seq_file *m, int i); +extern struct pci_ops iSeries_pci_ops; + +/* Global Variables */ + +unsigned short iSeries_icache_line_size = 0; +unsigned short iSeries_dcache_line_size = 0; +unsigned short iSeries_icache_lines_per_page = 0; +unsigned short iSeries_dcache_lines_per_page = 0; +unsigned short iSeries_log_icache_line_size = 0; +unsigned short iSeries_log_dcache_line_size = 0; + +unsigned long procFreqHz = 0; +unsigned long procFreqMhz = 0; +unsigned long procFreqMhzHundreths = 0; + +unsigned long tbFreqHz = 0; +unsigned long tbFreqMhz = 0; +unsigned long tbFreqMhzHundreths = 0; + +unsigned long decr_overclock = 8; +unsigned long decr_overclock_proc0 = 8; +unsigned long decr_overclock_set = 0; +unsigned long decr_overclock_proc0_set = 0; + +extern unsigned long embedded_sysmap_start; +extern unsigned long embedded_sysmap_end; + +extern unsigned long sysmap; +extern unsigned long sysmap_size; +extern unsigned long end_of_DRAM; // Defined in ppc/mm/init.c + +#ifdef CONFIG_SMP +extern struct smp_ops_t iSeries_smp_ops; +#endif /* CONFIG_SMP */ + +/* XXX for now... */ +#ifndef CONFIG_PCI +unsigned long isa_io_base; +#endif + +/* + * void __init platform_init() + * + * Description: + * This routine... + * + * Input(s): + * r3 - Optional pointer to a board information structure. + * r4 - Optional pointer to the physical starting address of the init RAM + * disk. + * r5 - Optional pointer to the physical ending address of the init RAM + * disk. + * r6 - Optional pointer to the physical starting address of any kernel + * command-line parameters. + * r7 - Optional pointer to the physical ending address of any kernel + * command-line parameters. + * + * Output(s): + * N/A + * + * Returns: + * N/A + * + */ + +extern int rd_size; // Defined in drivers/block/rd.c +extern u64 next_jiffy_update_tb[]; +extern u64 get_tb64(void); + +unsigned long __init iSeries_find_end_of_memory(void) +{ + /* totalLpChunks contains the size of memory (in units of 256K) */ + unsigned long memory_end = (totalLpChunks << 18); + + #ifndef CONFIG_HIGHMEM + /* Max memory if highmem is not configured is 768 MB */ + if (memory_end > (768 << 20)) + memory_end = 768 << 20; + #endif /* CONFIG_HIGHMEM */ + + return memory_end; +} + +void __init +platform_init(unsigned long r3, unsigned long r4, unsigned long r5, + unsigned long r6, unsigned long r7) +{ + parse_bootinfo(find_bootinfo()); + +#if defined(CONFIG_BLK_DEV_INITRD) + /* + * If the init RAM disk has been configured and there is + * a non-zero starting address for it, set it up + */ + if ( xNaca.xRamDisk ) { + initrd_start = xNaca.xRamDisk + KERNELBASE; + initrd_end = initrd_start + xNaca.xRamDiskSize * PAGE_SIZE; + initrd_below_start_ok = 1; // ramdisk in kernel space + ROOT_DEV = MKDEV( RAMDISK_MAJOR, 0 ); + + if ( ((rd_size*1024)/PAGE_SIZE) < xNaca.xRamDiskSize ) + rd_size = (xNaca.xRamDiskSize*PAGE_SIZE)/1024; + } else + +#endif /* CONFIG_BLK_DEV_INITRD */ +#if CONFIG_VIODASD_IDE + { + ROOT_DEV = MKDEV( IDE0_MAJOR, 1 ); + } +#elif defined(CONFIG_VIODASD) + { + ROOT_DEV = MKDEV( VIODASD_MAJOR, 1 ); + } +#endif /* CONFIG_VIODASD_IDE */ + + /* If an embedded System.map has been added to the kernel, + * set it up. + */ + if ( embedded_sysmap_start ) { + sysmap = embedded_sysmap_start + KERNELBASE; + sysmap_size = embedded_sysmap_end - embedded_sysmap_start; + } + + /* Copy the kernel command line arguments to a safe place. */ + + if (r6) { + *(char *)(r7 + KERNELBASE) = 0; + strcpy(cmd_line, (char *)(r6 + KERNELBASE)); + } + + /* Initialize the table which translate Linux physical addresses to + * iSeries absolute addresses + */ + + build_iSeries_Memory_Map(); + + setup_iSeries_cache_sizes(); + + /* Initialize machine-dependency vectors */ + + ppc_md.setup_arch = iSeries_setup_arch; + ppc_md.show_cpuinfo = iSeries_show_cpuinfo; + ppc_md.show_percpuinfo = iSeries_show_percpuinfo; + ppc_md.irq_cannonicalize = NULL; + ppc_md.init_IRQ = iSeries_init_IRQ; + ppc_md.get_irq = iSeries_get_irq; + ppc_md.init = NULL; + + ppc_md.restart = iSeries_restart; + ppc_md.power_off = iSeries_power_off; + ppc_md.halt = iSeries_halt; + + ppc_md.time_init = NULL; + ppc_md.set_rtc_time = iSeries_set_rtc_time; + ppc_md.get_rtc_time = iSeries_get_rtc_time; + ppc_md.calibrate_decr = iSeries_calibrate_decr; + ppc_md.progress = iSeries_progress; + ppc_md.find_end_of_memory = iSeries_find_end_of_memory; + + ppc_md.kbd_setkeycode = NULL; + ppc_md.kbd_getkeycode = NULL; + ppc_md.kbd_translate = NULL; + ppc_md.kbd_unexpected_up = NULL; + ppc_md.kbd_leds = NULL; + ppc_md.kbd_init_hw = NULL; +#ifdef CONFIG_PCI + ppc_md.pcibios_fixup_bus = iSeries_fixup_bus; + ppc_md.pcibios_fixup = iSeries_fixup; +#else + ppc_md.pcibios_fixup_bus = NULL; + ppc_md.pcibios_fixup = NULL; +#endif /* CONFIG_PCI */ + +#if defined(CONFIG_MAGIC_SYSRQ) + ppc_md.ppc_kbd_sysrq_xlate = NULL; +#endif + +#ifdef CONFIG_SMP + ppc_md.smp_ops = &iSeries_smp_ops; +#endif /* CONFIG_SMP */ + + // Associate Lp Event Queue 0 with processor 0 + HvCallEvent_setLpEventQueueInterruptProc( 0, 0 ); + + { + // copy the command line parameter from the primary VSP + char *p, *q; + HvCallEvent_dmaToSp( cmd_line, + 2*64*1024, + 256, + HvLpDma_Direction_RemoteToLocal ); + p = q = cmd_line + 255; + while( p > cmd_line ) { + if ((*p == 0) || (*p == ' ') || (*p == '\n')) + --p; + else + break; + } + if ( p < q ) + *(p+1) = 0; + } + + next_jiffy_update_tb[0] = get_tb64(); + + iSeries_proc_early_init(); + + mf_init(); + + iSeries_proc_callback( &pmc_proc_init ); + + return; +} + +/* + * The iSeries may have very large memories ( > 128 GB ) and a partition + * may get memory in "chunks" that may be anywhere in the 2**52 real + * address space. The chunks are 256K in size. To map this to the + * memory model Linux expects, the iSeries specific code builds a + * translation table to translate what Linux thinks are "physical" + * addresses to the actual real addresses. This allows us to make + * it appear to Linux that we have contiguous memory starting at + * physical address zero while in fact this could be far from the truth. + * To avoid confusion, I'll let the words physical and/or real address + * apply to the Linux addresses while I'll use "absolute address" to + * refer to the actual hardware real address. + * + * build_iSeries_Memory_Map gets information from the Hypervisor and + * looks at the Main Store VPD to determine the absolute addresses + * of the memory that has been assigned to our partition and builds + * a table used to translate Linux's physical addresses to these + * absolute addresses. Absolute addresses are needed when + * communicating with the hypervisor (e.g. to build HPT entries) + */ + +static void __init build_iSeries_Memory_Map(void) +{ + u32 loadAreaFirstChunk, loadAreaLastChunk, loadAreaSize; + u32 hptFirstChunk, hptLastChunk, hptSizeChunks; + u32 absAddrHi, absAddrLo; + u32 nextPhysChunk; + u32 holeFirstChunk, holeSizeChunks; + u32 totalChunks,moreChunks; + u32 currChunk, thisChunk, absChunk; + u32 currDword; + u32 chunkBit; + u64 holeStart, holeEnd, holeSize; + u64 map; + struct IoHriMainStoreSegment4 * msVpd; + + // Get absolute address of our load area + // and map it to physical address 0 + // This guarantees that the loadarea ends up at physical 0 + // otherwise, it might not be returned by PLIC as the first + // chunks + + loadAreaFirstChunk = (u32)(itLpNaca.xLoadAreaAddr >> 18); + loadAreaSize = itLpNaca.xLoadAreaChunks; + + loadAreaLastChunk = loadAreaFirstChunk + loadAreaSize - 1; + + // Get absolute address of our HPT and remember it so + // we won't map it to any physical address + + hptFirstChunk = (u32)(HvCallHpt_getHptAddress() >> 18 ); + hptSizeChunks = (u32)(HvCallHpt_getHptPages() >> 6 ); + hptLastChunk = hptFirstChunk + hptSizeChunks - 1; + + loadAreaLastChunk = loadAreaFirstChunk + loadAreaSize - 1; + + absAddrLo = loadAreaFirstChunk << 18; + absAddrHi = loadAreaFirstChunk >> 14; + + printk( "Mapping load area - physical addr = 0, absolute addr = %08x%08x\n", + absAddrHi, absAddrLo ); + printk( "Load area size %dK\n", loadAreaSize*256 ); + + nextPhysChunk = 0; + + for ( absChunk = loadAreaFirstChunk; absChunk <= loadAreaLastChunk; ++absChunk ) { + if ( ( absChunk < hptFirstChunk ) || + ( absChunk > hptLastChunk ) ) { + msChunks[nextPhysChunk] = absChunk; + ++nextPhysChunk; + } + } + // Get absolute address of our HPT and remember it so + // we won't map it to any physical address + hptFirstChunk = (u32)(HvCallHpt_getHptAddress() >> 18 ); + hptSizeChunks = (u32)(HvCallHpt_getHptPages() >> 6 ); + hptLastChunk = hptFirstChunk + hptSizeChunks - 1; + absAddrLo = hptFirstChunk << 18; + absAddrHi = hptFirstChunk >> 14; + + printk( "HPT absolute addr = %08x%08x, size = %dK\n", + absAddrHi, absAddrLo, hptSizeChunks*256 ); + + // Determine if absolute memory has any + // holes so that we can interpret the + // access map we get back from the hypervisor + // correctly. + + msVpd = (struct IoHriMainStoreSegment4 *)xMsVpd; + holeStart = msVpd->nonInterleavedBlocksStartAdr; + holeEnd = msVpd->nonInterleavedBlocksEndAdr; + holeSize = holeEnd - holeStart; + + if ( holeSize ) { + holeStart = holeStart & 0x000fffffffffffff; + holeStart = holeStart >> 18; + holeFirstChunk = (u32)holeStart; + holeSize = holeSize >> 18; + holeSizeChunks = (u32)holeSize; + printk( "Main store hole: start chunk = %0x, size = %0x chunks\n", + holeFirstChunk, holeSizeChunks ); + } + else { + holeFirstChunk = 0xffffffff; + holeSizeChunks = 0; + } + + // Process the main store access map from the hypervisor + // to build up our physical -> absolute translation table + + totalChunks = (u32)HvLpConfig_getMsChunks(); + + if ((totalChunks-hptSizeChunks) > 16384) { + panic("More than 4GB of memory assigned to this partition"); + } + + currChunk = 0; + currDword = 0; + moreChunks = totalChunks; + + while ( moreChunks ) { + map = HvCallSm_get64BitsOfAccessMap( itLpNaca.xLpIndex, + currDword ); + thisChunk = currChunk; + while ( map ) { + chunkBit = map >> 63; + map <<= 1; + if ( chunkBit ) { + --moreChunks; + absChunk = thisChunk; + if ( absChunk >= holeFirstChunk ) + absChunk += holeSizeChunks; + if ( ( ( absChunk < hptFirstChunk ) || + ( absChunk > hptLastChunk ) ) && + ( ( absChunk < loadAreaFirstChunk ) || + ( absChunk > loadAreaLastChunk ) ) ) { +// printk( "Mapping physical = %0x to absolute %0x for 256K\n", nextPhysChunk << 18, absChunk << 18 ); + msChunks[nextPhysChunk] = absChunk; + ++nextPhysChunk; + } + } + ++thisChunk; + } + ++currDword; + currChunk += 64; + } + + // main store size (in chunks) is + // totalChunks - hptSizeChunks + // which should be equal to + // nextPhysChunk + + totalLpChunks = nextPhysChunk; + +} + +/* + * Set up the variables that describe the cache line sizes + * for this machine. + */ + +static void __init setup_iSeries_cache_sizes(void) +{ + unsigned i,n; + iSeries_icache_line_size = xIoHriProcessorVpd[0].xInstCacheOperandSize; + iSeries_dcache_line_size = xIoHriProcessorVpd[0].xDataCacheOperandSize; + iSeries_icache_lines_per_page = PAGE_SIZE / iSeries_icache_line_size; + iSeries_dcache_lines_per_page = PAGE_SIZE / iSeries_dcache_line_size; + i = iSeries_icache_line_size; + n = 0; + while ((i=(i/2))) ++n; + iSeries_log_icache_line_size = n; + i = iSeries_dcache_line_size; + n = 0; + while ((i=(i/2))) ++n; + iSeries_log_dcache_line_size = n; + printk( "D-cache line size = %d (log = %d)\n", + (unsigned)iSeries_dcache_line_size, + (unsigned)iSeries_log_dcache_line_size ); + printk( "I-cache line size = %d (log = %d)\n", + (unsigned)iSeries_icache_line_size, + (unsigned)iSeries_log_icache_line_size ); + +} + + +int piranha_simulator = 0; + +/* + * Document me. + */ +void __init +iSeries_setup_arch(void) +{ + void * eventStack; + u32 procFreq; + u32 tbFreq; +// u32 evStackContigReal; +// u64 evStackReal; + + /* Setup the Lp Event Queue */ + + /* Associate Lp Event Queue 0 with processor 0 */ + +// HvCallEvent_setLpEventQueueInterruptProc( 0, 0 ); + + /* Allocate a page for the Event Stack + * The hypervisor wants the absolute real address, so + * we subtract out the KERNELBASE and add in the + * absolute real address of the kernel load area + */ + + eventStack = alloc_bootmem_pages( LpEventStackSize ); + + memset( eventStack, 0, LpEventStackSize ); + + /* Invoke the hypervisor to initialize the event stack */ + + HvCallEvent_setLpEventStack( 0, eventStack, LpEventStackSize ); + + /* Initialize fields in our Lp Event Queue */ + + xItLpQueue.xHSlicEventStackPtr = 0; + xItLpQueue.xSlicEventStackPtr = (char *)eventStack; + xItLpQueue.xHSlicCurEventPtr = 0; + xItLpQueue.xSlicCurEventPtr = (char *)eventStack; + xItLpQueue.xHSlicLastValidEventPtr = 0; + xItLpQueue.xSlicLastValidEventPtr = (char *)eventStack + + (LpEventStackSize - LpEventMaxSize); + xItLpQueue.xIndex = 0; + + if ( itLpNaca.xPirEnvironMode == 0 ) { + printk("Running on Piranha simulator\n"); + piranha_simulator = 1; + } + // Compute processor frequency + procFreq = ( 0x40000000 / (xIoHriProcessorVpd[0].xProcFreq / 1600) ); + procFreqHz = procFreq * 10000; + procFreqMhz = procFreq / 100; + procFreqMhzHundreths = procFreq - (procFreqMhz * 100 ); + + // Compute time base frequency + tbFreq = ( 0x40000000 / (xIoHriProcessorVpd[0].xTimeBaseFreq / 400) ); + tbFreqHz = tbFreq * 10000; + tbFreqMhz = tbFreq / 100; + tbFreqMhzHundreths = tbFreq - (tbFreqMhz * 100 ); + + printk("Max logical processors = %d\n", + itVpdAreas.xSlicMaxLogicalProcs ); + printk("Max physical processors = %d\n", + itVpdAreas.xSlicMaxPhysicalProcs ); + printk("Processor frequency = %lu.%02lu\n", + procFreqMhz, + procFreqMhzHundreths ); + printk("Time base frequency = %lu.%02lu\n", + tbFreqMhz, + tbFreqMhzHundreths ); + printk("Processor version = %x\n", + xIoHriProcessorVpd[0].xPVR ); + +#ifdef CONFIG_PCI + /* Initialize the flight recorder, global bus map and pci memory table */ + iSeries_pci_Initialize(); + + /* Setup the PCI controller list */ + iSeries_build_hose_list(); +#endif /* CONFIG_PCI */ +/* + // copy the command line parameter from the primary VSP + HvCallEvent_dmaToSp( cmd_line, + 2*64*1024, + 256, + HvLpDma_Direction_RemoteToLocal ); + + mf_init(); + viopath_init(); +*/ +} + +/* + * int iSeries_show_percpuinfo() + * + * Description: + * This routine pretty-prints CPU information gathered from the VPD + * for use in /proc/cpuinfo + * + * Input(s): + * *buffer - Buffer into which CPU data is to be printed. + * + * Output(s): + * *buffer - Buffer with CPU data. + * + * Returns: + * The number of bytes copied into 'buffer' if OK, otherwise zero or less + * on error. + */ +static int +iSeries_show_percpuinfo(struct seq_file *m, int i) +{ + seq_printf(m, "clock\t\t: %lu.%02luMhz\n", + procFreqMhz, procFreqMhzHundreths ); +// seq_printf(m, " processor clock\t\t: %ldMHz\n", +// ((unsigned long)xIoHriProcessorVpd[0].xProcFreq)/1000000); + seq_printf(m, "time base\t: %lu.%02luMHz\n", + tbFreqMhz, tbFreqMhzHundreths ); +// seq_printf(m, " time base freq\t\t: %ldMHz\n", +// ((unsigned long)xIoHriProcessorVpd[0].xTimeBaseFreq)/1000000); + seq_printf(m, "i-cache\t\t: %d\n", + iSeries_icache_line_size); + seq_printf(m, "d-cache\t\t: %d\n", + iSeries_dcache_line_size); + + return 0; +} + +static int iSeries_show_cpuinfo(struct seq_file *m) +{ + seq_printf(m, "machine\t\t: iSeries Logical Partition\n"); + + return 0; +} + +#ifndef CONFIG_PCI +/* + * Document me. + * and Implement me. + * If no Native I/O, do nothing routine. + */ + void __init +iSeries_init_IRQ(void) +{ + return; +} +#endif + +/* + * Document me. + * and Implement me. + */ +int +iSeries_get_irq(struct pt_regs *regs) +{ +/* + return (ppc4xx_pic_get_irq(regs)); +*/ + /* -2 means ignore this interrupt */ + return -2; +} + +/* + * Document me. + */ +void +iSeries_restart(char *cmd) +{ + mf_reboot(); +} + +/* + * Document me. + */ +void +iSeries_power_off(void) +{ + mf_powerOff(); +} + +/* + * Document me. + */ +void +iSeries_halt(void) +{ + mf_powerOff(); +} + +/* + * Nothing to do here. + */ +void __init +iSeries_time_init(void) +{ + /* Nothing to do */ +} + +/* + * Set the RTC in the virtual service processor + * This requires flowing LpEvents to the primary partition + */ +int iSeries_set_rtc_time(unsigned long time) +{ + mf_setRtcTime(time); + return 0; +} + +/* + * Get the RTC from the virtual service processor + * This requires flowing LpEvents to the primary partition + */ +unsigned long iSeries_get_rtc_time(void) +{ + /* XXX - Implement me */ + unsigned long time; + mf_getRtcTime(&time); + return (time); +} + +/* + * void __init iSeries_calibrate_decr() + * + * Description: + * This routine retrieves the internal processor frequency from the VPD, + * and sets up the kernel timer decrementer based on that value. + * + */ + +void __init +iSeries_calibrate_decr(void) +{ + u32 freq; + u32 tbf; + struct Paca * paca; + + /* Compute decrementer (and TB) frequency + * in cycles/sec + */ + + tbf = xIoHriProcessorVpd[0].xTimeBaseFreq / 16; + + freq = 0x010000000; + freq = freq / tbf; /* cycles / usec */ + freq = freq * 1000000; /* now in cycles/sec */ + + /* Set the amount to refresh the decrementer by. This + * is the number of decrementer ticks it takes for + * 1/HZ seconds. + */ + + /* decrementer_count = freq / HZ; + * count_period_num = 1; + * count_period_den = freq; */ + + if ( decr_overclock_set && !decr_overclock_proc0_set ) + decr_overclock_proc0 = decr_overclock; + + tb_ticks_per_jiffy = freq / HZ; + paca = (struct Paca *)mfspr(SPRG1); + paca->default_decr = tb_ticks_per_jiffy / decr_overclock_proc0; + tb_to_us = mulhwu_scale_factor(freq, 1000000); +} +void __init +iSeries_progress( char * st, unsigned short code ) +{ + printk( "Progress: [%04x] - %s\n", (unsigned)code, st ); + if (code != 0xffff) + mf_displayProgress( code ); + else + mf_clearSrc(); +} + +#ifdef CONFIG_PCI +/* + * unsigned int __init iSeries_build_hose_list() + * + * Description: + * This routine builds a list of the PCI host bridges that + * connect PCI buses either partially or fully owned by + * this guest partition + * + */ +unsigned int __init iSeries_build_hose_list ( ) { + struct pci_controller* hose; + struct iSeries_hose_arch_data* hose_data; + u64 hvRc; + u16 hvbusnum; + int LxBusNumber = 0; /* Linux Bus number for grins */ + + /* Check to make sure the device probing will work on this iSeries Release. */ + if(hvReleaseData.xVrmIndex !=3) { + printk("PCI: iSeries Lpar and Linux native PCI I/O code is incompatible.\n"); + printk("PCI: A newer version of the Linux kernel is need for this iSeries release.\n"); + return 0; + } + + + for (hvbusnum = 0; hvbusnum < 256; hvbusnum++) { /* All PCI buses which could be owned by this guest partition will be numbered by the hypervisor between 1 & 255 */ + hvRc = HvCallXm_testBus (hvbusnum); /* Call the system hypervisor to query guest partition ownership status of this bus */ + if (hvRc == 0) { /* This bus is partially/fully owned by this guest partition */ + hose = (struct pci_controller*)pcibios_alloc_controller(); // Create the hose for this PCI bus + hose->first_busno = LxBusNumber; /* This just for debug. pcibios will */ + hose->last_busno = 0xff; /* assign the bus numbers. */ + hose->ops = &iSeries_pci_ops; + /* Create the iSeries_arch_data for the hose and cache the HV bus number in it so that pci bios can build the global bus map */ + hose_data = (struct iSeries_hose_arch_data *) alloc_bootmem(sizeof(struct iSeries_hose_arch_data)); + memset(hose_data, 0, sizeof(*hose_data)); + hose->arch_data = (void *) hose_data; + ((struct iSeries_hose_arch_data *)(hose->arch_data))->hvBusNumber = hvbusnum; + LxBusNumber += 1; /* Keep track for debug */ + } + } + pci_assign_all_busses = 1; /* Let Linux assign the bus numbers in pcibios_init */ + return 0; +} +#endif /* CONFIG_PCI */ + +int iSeries_spread_lpevents( char * str ) +{ + /* The parameter is the number of processors to share in processing lp events */ + unsigned long i; + unsigned long val = simple_strtoul(str, NULL, 0 ); + if ( ( val > 0 ) && ( val <= maxPacas ) ) { + for( i=1; i<val; ++i ) + xPaca[i].lpQueuePtr = xPaca[0].lpQueuePtr; + } + else + printk("invalid spread_lpevents %ld\n", val); + return 1; +} + +int iSeries_decr_overclock_proc0( char * str ) +{ + unsigned long val = simple_strtoul(str, NULL, 0 ); + if ( ( val >= 1 ) && ( val <= 48 ) ) { + decr_overclock_proc0_set = 1; + decr_overclock_proc0 = val; + printk("proc 0 decrementer overclock factor of %ld\n", val); + } + else { + printk("invalid proc 0 decrementer overclock factor of %ld\n", val); + } + return 1; +} + +int iSeries_decr_overclock( char * str ) +{ + unsigned long val = simple_strtoul( str, NULL, 0 ); + if ( ( val >= 1 ) && ( val <= 48 ) ) { + decr_overclock_set = 1; + decr_overclock = val; + printk("decrementer overclock factor of %ld\n", val); + } + else { + printk("invalid decrementer overclock factor of %ld\n", val); + } + return 1; +} + +__setup("spread_lpevents=", iSeries_spread_lpevents ); +__setup("decr_overclock_proc0=", iSeries_decr_overclock_proc0 ); +__setup("decr_overclock=", iSeries_decr_overclock ); + diff --git a/arch/ppc/platforms/iSeries_setup.h b/arch/ppc/platforms/iSeries_setup.h new file mode 100644 index 000000000000..3dccb85e6952 --- /dev/null +++ b/arch/ppc/platforms/iSeries_setup.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2000 Mike Corrigan <mikejc@us.ibm.com> + * Copyright (c) 1999-2000 Grant Erickson <grant@lcse.umn.edu> + * + * Module name: iSeries_setup.h + * + * Description: + * Architecture- / platform-specific boot-time initialization code for + * the IBM iSeries LPAR. Adapted from original code by Grant Erickson and + * code by Gary Thomas, Cort Dougan <cort@cs.nmt.edu>, and Dan Malek + * <dan@netx4.com>. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __ISERIES_SETUP_H__ +#define __ISERIES_SETUP_H__ + + +#ifdef __cplusplus +extern "C" { +#endif + +extern void iSeries_init(unsigned long r3, + unsigned long ird_start, + unsigned long ird_end, + unsigned long cline_start, + unsigned long cline_end); +extern void iSeries_setup_arch(void); +extern int iSeries_setup_residual(char *buffer); +extern int iSeries_get_cpuinfo(char *buffer); +extern void iSeries_init_IRQ(void); +extern int iSeries_get_irq(struct pt_regs *regs); +extern void iSeries_restart(char *cmd); +extern void iSeries_power_off(void); +extern void iSeries_halt(void); +extern void iSeries_time_init(void); +extern int iSeries_set_rtc_time(unsigned long now); +extern unsigned long iSeries_get_rtc_time(void); +extern void iSeries_calibrate_decr(void); +extern void iSeries_progress( char *, unsigned short ); +extern unsigned int iSeries_build_hose_list(void); + + +#ifdef __cplusplus +} +#endif + +#endif /* __ISERIES_SETUP_H__ */ diff --git a/arch/ppc/platforms/iSeries_smp.c b/arch/ppc/platforms/iSeries_smp.c new file mode 100644 index 000000000000..a250b660707c --- /dev/null +++ b/arch/ppc/platforms/iSeries_smp.c @@ -0,0 +1,133 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ +/* + * SMP support for iSeries/LPAR. + * + * Copyright (C) 2001 IBM Corp. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include <linux/config.h> +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/smp.h> +#include <linux/smp_lock.h> +#include <linux/interrupt.h> +#include <linux/kernel_stat.h> +#include <linux/delay.h> +#define __KERNEL_SYSCALLS__ +#include <linux/unistd.h> +#include <linux/init.h> +#include <linux/spinlock.h> + +#include <asm/ptrace.h> +#include <asm/atomic.h> +#include <asm/irq.h> +#include <asm/page.h> +#include <asm/pgtable.h> +#include <asm/hardirq.h> +#include <asm/softirq.h> +#include <asm/io.h> +#include <asm/prom.h> +#include <asm/smp.h> +#include <asm/residual.h> +#include <asm/time.h> + +#include <asm/iSeries/LparData.h> +#include <asm/iSeries/HvCall.h> +extern u64 get_tb64(void); +extern u64 next_jiffy_update_tb[]; + +static unsigned long iSeries_smp_message[NR_CPUS]; + +void iSeries_smp_message_recv( struct pt_regs * regs ) +{ + int cpu = smp_processor_id(); + int msg; + + if ( smp_num_cpus < 2 ) + return; + + for ( msg = 0; msg < 4; ++msg ) + if ( test_and_clear_bit( msg, &iSeries_smp_message[cpu] ) ) + smp_message_recv( msg, regs ); + +} + +static void smp_iSeries_message_pass(int target, int msg, unsigned long data, int wait) +{ + int i; + for (i = 0; i < smp_num_cpus; ++i) { + if ( (target == MSG_ALL) || + (target == i) || + ((target == MSG_ALL_BUT_SELF) && (i != smp_processor_id())) ) { + set_bit( msg, &iSeries_smp_message[i] ); + HvCall_sendIPI(&(xPaca[i])); + } + } +} + +static int smp_iSeries_probe(void) +{ + unsigned i; + unsigned np; + struct ItLpPaca * lpPaca; + + np = 0; + for (i=0; i<maxPacas; ++i) { + lpPaca = xPaca[i].xLpPacaPtr; + if ( lpPaca->xDynProcStatus < 2 ) + ++np; + } + + smp_tb_synchronized = 1; + return np; +} + +extern unsigned long decr_overclock; +static void smp_iSeries_kick_cpu(int nr) +{ + struct ItLpPaca * lpPaca; + // Verify we have a Paca for processor nr + if ( ( nr <= 0 ) || + ( nr >= maxPacas ) ) + return; + // Verify that our partition has a processor nr + lpPaca = xPaca[nr].xLpPacaPtr; + if ( lpPaca->xDynProcStatus >= 2 ) + return; + xPaca[nr].default_decr = tb_ticks_per_jiffy / decr_overclock; + // The processor is currently spinning, waiting + // for the xProcStart field to become non-zero + // After we set xProcStart, the processor will + // continue on to secondary_start in iSeries_head.S + xPaca[nr].xProcStart = 1; +} + +static void smp_iSeries_setup_cpu(int nr) +{ + set_dec( xPaca[nr].default_decr ); +} + +void smp_iSeries_space_timers( unsigned nr ) +{ + unsigned offset,i; + + offset = tb_ticks_per_jiffy / nr; + for ( i=1; i<nr; ++i ) { + next_jiffy_update_tb[i] = next_jiffy_update_tb[i-1] + offset; + } +} + +struct smp_ops_t iSeries_smp_ops = { + smp_iSeries_message_pass, + smp_iSeries_probe, + smp_iSeries_kick_cpu, + smp_iSeries_setup_cpu +}; + diff --git a/arch/ppc/platforms/iSeries_time.c b/arch/ppc/platforms/iSeries_time.c new file mode 100644 index 000000000000..e5305877c25a --- /dev/null +++ b/arch/ppc/platforms/iSeries_time.c @@ -0,0 +1,157 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ +/* + * Time routes for iSeries LPAR. + * + * Copyright (C) 2001 IBM Corp. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include <linux/config.h> +#include <linux/errno.h> +#include <linux/sched.h> +#include <linux/kernel.h> +#include <linux/param.h> +#include <linux/string.h> +#include <linux/mm.h> +#include <linux/module.h> +#include <linux/interrupt.h> +#include <linux/timex.h> +#include <linux/kernel_stat.h> +#include <linux/mc146818rtc.h> +#include <linux/time.h> +#include <linux/init.h> + +#include <asm/segment.h> +#include <asm/io.h> +#include <asm/processor.h> +#include <asm/nvram.h> +#include <asm/cache.h> +#include <asm/8xx_immap.h> +#include <asm/machdep.h> +#include <asm/time.h> +#include <asm/iSeries/Paca.h> + +u64 next_jiffy_update_tb[NR_CPUS]; +extern u64 get_tb64(void); + +extern rwlock_t xtime_lock; +extern unsigned long wall_jiffies; + +extern unsigned long prof_cpu_mask; +extern unsigned int * prof_buffer; +extern unsigned long prof_len; +extern unsigned long prof_shift; +extern char _stext; + +extern int is_soft_enabled(void); + +static inline void ppc_do_profile (unsigned long nip) +{ + if (!prof_buffer) + return; + + /* + * Only measure the CPUs specified by /proc/irq/prof_cpu_mask. + * (default is all CPUs.) + */ + if (!((1<<smp_processor_id()) & prof_cpu_mask)) + return; + + nip -= (unsigned long) &_stext; + nip >>= prof_shift; + /* + * Don't ignore out-of-bounds EIP values silently, + * put them into the last histogram slot, so if + * present, they will show up as a sharp peak. + */ + if (nip > prof_len-1) + nip = prof_len-1; + atomic_inc((atomic_t *)&prof_buffer[nip]); +} + + /* + * For iSeries shared processors, we have to let the hypervisor + * set the hardware decrementer. We set a virtual decrementer + * in the ItLpPaca and call the hypervisor if the virtual + * decrementer is less than the current value in the hardware + * decrementer. (almost always the new decrementer value will + * be greater than the current hardware decementer so the hypervisor + * call will not be needed) + * + * When we yield the processor in idle.c (needed for shared processors) + * we cannot yield for too long or the 32-bit tbl may wrap and then + * we would lose jiffies. In addition, if we yield for too long, + * we might be pretty far off on timing for device drivers and such. + * When the hypervisor returns to us after a yield we need to + * determine whether decrementers might have been missed. If so + * we need to drive the timer_interrupt code to catch up (using + * the tb) + * + * For processors other than processor 0, there is no correction + * (in the code below) to next_dec so they're last_jiffy_stamp + * values are going to be way off. + * + */ +int timerRetEnabled = 0; +int timerRetDisabled = 0; + +extern unsigned long iSeries_dec_value; +int timer_interrupt(struct pt_regs * regs) +{ + long next_dec; + struct Paca * paca; + unsigned long cpu = smp_processor_id(); + paca = (struct Paca *)mfspr(SPRG1); + + if ( is_soft_enabled() ) + BUG(); + + if (regs->softEnable) + timerRetEnabled++; + else + timerRetDisabled++; + + hardirq_enter(cpu); + + if (!user_mode(regs)) + ppc_do_profile(instruction_pointer(regs)); + while ( next_jiffy_update_tb[cpu] < get_tb64() ) { +#ifdef CONFIG_SMP + smp_local_timer_interrupt(regs); +#endif + if ( cpu == 0 ) { + write_lock(&xtime_lock); + do_timer(regs); + if ( (time_status & STA_UNSYNC) == 0 && + xtime.tv_sec - last_rtc_update >= 659 && + abs(xtime.tv_usec - (1000000-1000000/HZ)) < 500000/HZ && + jiffies - wall_jiffies == 1) { + if (ppc_md.set_rtc_time(xtime.tv_sec+1 + time_offset) == 0) + last_rtc_update = xtime.tv_sec+1; + else + /* Try again one minute later */ + last_rtc_update += 60; + } + write_unlock(&xtime_lock); + + } + next_jiffy_update_tb[cpu] += tb_ticks_per_jiffy; + } + next_dec = next_jiffy_update_tb[cpu] - get_tb64(); + if ( next_dec > paca->default_decr ) + next_dec = paca->default_decr; + paca->xLpPacaPtr->xDecrInt = 0; + set_dec( (unsigned)next_dec ); + + hardirq_exit(cpu); + + if (softirq_pending(cpu)) + do_softirq(); + return 1; +} diff --git a/arch/ppc/platforms/ibm405.h b/arch/ppc/platforms/ibm405.h new file mode 100644 index 000000000000..2305ba61b892 --- /dev/null +++ b/arch/ppc/platforms/ibm405.h @@ -0,0 +1,333 @@ +/* + * ibm405.h + * + * This was derived from the ppc4xx.h and contains + * common 405 offsets + * + * Armin Kuster akuster@pacbell.net + * Jan, 2002 + * + * + * Copyright 2002 MontaVista Softare Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Version 1.0 (02/01/17) - A. Kuster + * Initial version - moved 405 specific out of the other core.h's + */ + +#ifdef __KERNEL__ +#ifndef __ASM_IBM405_H__ +#define __ASM_IBM405_H__ + +#ifdef DCRN_BE_BASE +#define DCRN_BEAR (DCRN_BE_BASE + 0x0) /* Bus Error Address Register */ +#define DCRN_BESR (DCRN_BE_BASE + 0x1) /* Bus Error Syndrome Register */ +#endif +/* DCRN_BESR */ +#define BESR_DSES 0x80000000 /* Data-Side Error Status */ +#define BESR_DMES 0x40000000 /* DMA Error Status */ +#define BESR_RWS 0x20000000 /* Read/Write Status */ +#define BESR_ETMASK 0x1C000000 /* Error Type */ +#define ET_PROT 0 +#define ET_PARITY 1 +#define ET_NCFG 2 +#define ET_BUSERR 4 +#define ET_BUSTO 6 + +#ifdef DCRN_CHCR_BASE +#define DCRN_CHCR0 (DCRN_CHCR_BASE + 0x0) /* Chip Control Register 1 */ +#define DCRN_CHCR1 (DCRN_CHCR_BASE + 0x1) /* Chip Control Register 2 */ +#endif +#define CHR1_CETE 0x00800000 /* CPU external timer enable */ +#define CHR1_PCIPW 0x00008000 /* PCI Int enable/Peripheral Write enable */ + +#ifdef DCRN_CHPSR_BASE +#define DCRN_CHPSR (DCRN_CHPSR_BASE + 0x0) /* Chip Pin Strapping */ +#endif + +#ifdef DCRN_CPMFR_BASE +#define DCRN_CPMFR (DCRN_CPMFR_BASE + 0x0) /* CPM Force */ +#endif + +#ifdef DCRN_CPMSR_BASE +#define DCRN_CPMSR (DCRN_CPMSR_BASE + 0x0) /* CPM Status */ +#define DCRN_CPMER (DCRN_CPMSR_BASE + 0x1) /* CPM Enable */ +#endif + +#ifdef DCRN_DCP0_BASE +/* Decompression Controller Address */ +#define DCRN_DCP0_CFGADDR (DCRN_DCP0_BASE + 0x0) +/* Decompression Controller Data */ +#define DCRN_DCP0_CFGDATA (DCRN_DCP0_BASE + 0x1) +#else +#define DCRN_DCP0_CFGADDR 0x0 +#define DCRN_DCP0_CFGDATA 0x0 +#endif + +#ifdef DCRN_DMA0_BASE +/* DMA Channel Control Register 0 */ +#define DCRN_DMACR0 (DCRN_DMA0_BASE + 0x0) +#define DCRN_DMACT0 (DCRN_DMA0_BASE + 0x1) /* DMA Count Register 0 */ +/* DMA Destination Address Register 0 */ +#define DCRN_DMADA0 (DCRN_DMA0_BASE + 0x2) +/* DMA Source Address Register 0 */ +#define DCRN_DMASA0 (DCRN_DMA0_BASE + 0x3) +#ifdef DCRNCAP_DMA_CC +/* DMA Chained Count Register 0 */ +#define DCRN_DMACC0 (DCRN_DMA0_BASE + 0x4) +#endif +#ifdef DCRNCAP_DMA_SG +/* DMA Scatter/Gather Descriptor Addr 0 */ +#define DCRN_ASG0 (DCRN_DMA0_BASE + 0x4) +#endif +#endif + +#ifdef DCRN_DMA1_BASE +/* DMA Channel Control Register 1 */ +#define DCRN_DMACR1 (DCRN_DMA1_BASE + 0x0) +#define DCRN_DMACT1 (DCRN_DMA1_BASE + 0x1) /* DMA Count Register 1 */ +/* DMA Destination Address Register 1 */ +#define DCRN_DMADA1 (DCRN_DMA1_BASE + 0x2) +/* DMA Source Address Register 1 */ +#define DCRN_DMASA1 (DCRN_DMA1_BASE + 0x3) /* DMA Source Address Register 1 */ +#ifdef DCRNCAP_DMA_CC +/* DMA Chained Count Register 1 */ +#define DCRN_DMACC1 (DCRN_DMA1_BASE + 0x4) +#endif +#ifdef DCRNCAP_DMA_SG +/* DMA Scatter/Gather Descriptor Addr 1 */ +#define DCRN_ASG1 (DCRN_DMA1_BASE + 0x4) +#endif +#endif + +#ifdef DCRN_DMA2_BASE +#define DCRN_DMACR2 (DCRN_DMA2_BASE + 0x0) /* DMA Channel Control Register 2 */ +#define DCRN_DMACT2 (DCRN_DMA2_BASE + 0x1) /* DMA Count Register 2 */ +#define DCRN_DMADA2 (DCRN_DMA2_BASE + 0x2) /* DMA Destination Address Register 2 */ +#define DCRN_DMASA2 (DCRN_DMA2_BASE + 0x3) /* DMA Source Address Register 2 */ +#ifdef DCRNCAP_DMA_CC +#define DCRN_DMACC2 (DCRN_DMA2_BASE + 0x4) /* DMA Chained Count Register 2 */ +#endif +#ifdef DCRNCAP_DMA_SG +#define DCRN_ASG2 (DCRN_DMA2_BASE + 0x4) /* DMA Scatter/Gather Descriptor Addr 2 */ +#endif +#endif + +#ifdef DCRN_DMA3_BASE +#define DCRN_DMACR3 (DCRN_DMA3_BASE + 0x0) /* DMA Channel Control Register 3 */ +#define DCRN_DMACT3 (DCRN_DMA3_BASE + 0x1) /* DMA Count Register 3 */ +#define DCRN_DMADA3 (DCRN_DMA3_BASE + 0x2) /* DMA Destination Address Register 3 */ +#define DCRN_DMASA3 (DCRN_DMA3_BASE + 0x3) /* DMA Source Address Register 3 */ +#ifdef DCRNCAP_DMA_CC +#define DCRN_DMACC3 (DCRN_DMA3_BASE + 0x4) /* DMA Chained Count Register 3 */ +#endif +#ifdef DCRNCAP_DMA_SG +#define DCRN_ASG3 (DCRN_DMA3_BASE + 0x4) /* DMA Scatter/Gather Descriptor Addr 3 */ +#endif +#endif + +#ifdef DCRN_DMASR_BASE +#define DCRN_DMASR (DCRN_DMASR_BASE + 0x0) /* DMA Status Register */ +#ifdef DCRNCAP_DMA_SG +#define DCRN_ASGC (DCRN_DMASR_BASE + 0x3) /* DMA Scatter/Gather Command */ +/* don't know if these two registers always exist if scatter/gather exists */ +#define DCRN_POL (DCRN_DMASR_BASE + 0x6) /* DMA Polarity Register */ +#define DCRN_SLP (DCRN_DMASR_BASE + 0x5) /* DMA Sleep Register */ +#endif +#endif + +#ifdef DCRN_EBC_BASE +#define DCRN_EBCCFGADR (DCRN_EBC_BASE + 0x0) /* Peripheral Controller Address */ +#define DCRN_EBCCFGDATA (DCRN_EBC_BASE + 0x1) /* Peripheral Controller Data */ +#endif + +#ifdef DCRN_EXIER_BASE +#define DCRN_EXIER (DCRN_EXIER_BASE + 0x0) /* External Interrupt Enable Register */ +#endif + +#ifdef DCRN_EXISR_BASE +#define DCRN_EXISR (DCRN_EXISR_BASE + 0x0) /* External Interrupt Status Register */ +#endif + +#define EXIER_CIE 0x80000000 /* Critical Interrupt Enable */ +#define EXIER_SRIE 0x08000000 /* Serial Port Rx Int. Enable */ +#define EXIER_STIE 0x04000000 /* Serial Port Tx Int. Enable */ +#define EXIER_JRIE 0x02000000 /* JTAG Serial Port Rx Int. Enable */ +#define EXIER_JTIE 0x01000000 /* JTAG Serial Port Tx Int. Enable */ +#define EXIER_D0IE 0x00800000 /* DMA Channel 0 Interrupt Enable */ +#define EXIER_D1IE 0x00400000 /* DMA Channel 1 Interrupt Enable */ +#define EXIER_D2IE 0x00200000 /* DMA Channel 2 Interrupt Enable */ +#define EXIER_D3IE 0x00100000 /* DMA Channel 3 Interrupt Enable */ +#define EXIER_E0IE 0x00000010 /* External Interrupt 0 Enable */ +#define EXIER_E1IE 0x00000008 /* External Interrupt 1 Enable */ +#define EXIER_E2IE 0x00000004 /* External Interrupt 2 Enable */ +#define EXIER_E3IE 0x00000002 /* External Interrupt 3 Enable */ +#define EXIER_E4IE 0x00000001 /* External Interrupt 4 Enable */ + +#ifdef DCRN_IOCR_BASE +#define DCRN_IOCR (DCRN_IOCR_BASE + 0x0) /* Input/Output Configuration Register */ +#endif +#define IOCR_E0TE 0x80000000 +#define IOCR_E0LP 0x40000000 +#define IOCR_E1TE 0x20000000 +#define IOCR_E1LP 0x10000000 +#define IOCR_E2TE 0x08000000 +#define IOCR_E2LP 0x04000000 +#define IOCR_E3TE 0x02000000 +#define IOCR_E3LP 0x01000000 +#define IOCR_E4TE 0x00800000 +#define IOCR_E4LP 0x00400000 +#define IOCR_EDT 0x00080000 +#define IOCR_SOR 0x00040000 +#define IOCR_EDO 0x00008000 +#define IOCR_2XC 0x00004000 +#define IOCR_ATC 0x00002000 +#define IOCR_SPD 0x00001000 +#define IOCR_BEM 0x00000800 +#define IOCR_PTD 0x00000400 +#define IOCR_ARE 0x00000080 +#define IOCR_DRC 0x00000020 +#define IOCR_RDM(x) (((x) & 0x3) << 3) +#define IOCR_TCS 0x00000004 +#define IOCR_SCS 0x00000002 +#define IOCR_SPC 0x00000001 + +#ifdef DCRN_MAL_BASE +#define DCRN_MALCR (DCRN_MAL_BASE + 0x0) /* MAL Configuration */ +#define DCRN_MALDBR (DCRN_MAL_BASE + 0x3) /* Debug Register */ +#define DCRN_MALESR (DCRN_MAL_BASE + 0x1) /* Error Status */ +#define DCRN_MALIER (DCRN_MAL_BASE + 0x2) /* Interrupt Enable */ +#define DCRN_MALTXCARR (DCRN_MAL_BASE + 0x5) /* TX Channed Active Reset Register */ +#define DCRN_MALTXCASR (DCRN_MAL_BASE + 0x4) /* TX Channel Active Set Register */ +#define DCRN_MALTXDEIR (DCRN_MAL_BASE + 0x7) /* Tx Descriptor Error Interrupt */ +#define DCRN_MALTXEOBISR (DCRN_MAL_BASE + 0x6) /* Tx End of Buffer Interrupt Status */ +#define DCRN_MALRXCARR (DCRN_MAL_BASE + 0x11) /* RX Channed Active Reset Register */ +#define DCRN_MALRXCASR (DCRN_MAL_BASE + 0x10) /* RX Channel Active Set Register */ +#define DCRN_MALRXDEIR (DCRN_MAL_BASE + 0x13) /* Rx Descriptor Error Interrupt */ +#define DCRN_MALRXEOBISR (DCRN_MAL_BASE + 0x12) /* Rx End of Buffer Interrupt Status */ +#define DCRN_MALRXCTP0R (DCRN_MAL_BASE + 0x40) /* Channel Rx 0 Channel Table Pointer */ +#define DCRN_MALTXCTP0R (DCRN_MAL_BASE + 0x20) /* Channel Tx 0 Channel Table Pointer */ +#define DCRN_MALTXCTP1R (DCRN_MAL_BASE + 0x21) /* Channel Tx 1 Channel Table Pointer */ +#define DCRN_MALRCBS0 (DCRN_MAL_BASE + 0x60) /* Channel Rx 0 Channel Buffer Size */ +#endif + /* DCRN_MALCR */ +#define MALCR_MMSR 0x80000000 /* MAL Software reset */ +#define MALCR_PLBP_1 0x00400000 /* MAL reqest priority: */ +#define MALCR_PLBP_2 0x00800000 /* lowsest is 00 */ +#define MALCR_PLBP_3 0x00C00000 /* highest */ +#define MALCR_GA 0x00200000 /* Guarded Active Bit */ +#define MALCR_OA 0x00100000 /* Ordered Active Bit */ +#define MALCR_PLBLE 0x00080000 /* PLB Lock Error Bit */ +#define MALCR_PLBLT_1 0x00040000 /* PLB Latency Timer */ +#define MALCR_PLBLT_2 0x00020000 +#define MALCR_PLBLT_3 0x00010000 +#define MALCR_PLBLT_4 0x00008000 +#define MALCR_PLBLT_DEFAULT 0x00078000 /* JSP: Is this a valid default?? */ +#define MALCR_PLBB 0x00004000 /* PLB Burst Deactivation Bit */ +#define MALCR_OPBBL 0x00000080 /* OPB Lock Bit */ +#define MALCR_EOPIE 0x00000004 /* End Of Packet Interrupt Enable */ +#define MALCR_LEA 0x00000002 /* Locked Error Active */ +#define MALCR_MSD 0x00000001 /* MAL Scroll Descriptor Bit */ +/* DCRN_MALESR */ +#define MALESR_EVB 0x80000000 /* Error Valid Bit */ +#define MALESR_CIDRX 0x40000000 /* Channel ID Receive */ +#define MALESR_DE 0x00100000 /* Descriptor Error */ +#define MALESR_OEN 0x00080000 /* OPB Non-Fullword Error */ +#define MALESR_OTE 0x00040000 /* OPB Timeout Error */ +#define MALESR_OSE 0x00020000 /* OPB Slave Error */ +#define MALESR_PEIN 0x00010000 /* PLB Bus Error Indication */ +#define MALESR_DEI 0x00000010 /* Descriptor Error Interrupt */ +#define MALESR_ONEI 0x00000008 /* OPB Non-Fullword Error Interrupt */ +#define MALESR_OTEI 0x00000004 /* OPB Timeout Error Interrupt */ +#define MALESR_OSEI 0x00000002 /* OPB Slace Error Interrupt */ +#define MALESR_PBEI 0x00000001 /* PLB Bus Error Interrupt */ +/* DCRN_MALIER */ +#define MALIER_DE 0x00000010 /* Descriptor Error Interrupt Enable */ +#define MALIER_NE 0x00000008 /* OPB Non-word Transfer Int Enable */ +#define MALIER_TE 0x00000004 /* OPB Time Out Error Interrupt Enable */ +#define MALIER_OPBE 0x00000002 /* OPB Slave Error Interrupt Enable */ +#define MALIER_PLBE 0x00000001 /* PLB Error Interrupt Enable */ +/* DCRN_MALTXEOBISR */ +#define MALOBISR_CH0 0x80000000 /* EOB channel 1 bit */ +#define MALOBISR_CH2 0x40000000 /* EOB channel 2 bit */ + +#ifdef DCRN_PLB0_BASE +#define DCRN_PLB0_BESR (DCRN_PLB0_BASE + 0x0) +#define DCRN_PLB0_BEAR (DCRN_PLB0_BASE + 0x2) +/* doesn't exist on stb03xxx? */ +#define DCRN_PLB0_ACR (DCRN_PLB0_BASE + 0x3) +#endif + +#ifdef DCRN_PLB1_BASE +#define DCRN_PLB1_BESR (DCRN_PLB1_BASE + 0x0) +#define DCRN_PLB1_BEAR (DCRN_PLB1_BASE + 0x1) +/* doesn't exist on stb03xxx? */ +#define DCRN_PLB1_ACR (DCRN_PLB1_BASE + 0x2) +#endif + +#ifdef DCRN_PLLMR_BASE +#define DCRN_PLLMR (DCRN_PLLMR_BASE + 0x0) /* PL1 Mode */ +#endif + +#ifdef DCRN_POB0_BASE +#define DCRN_POB0_BESR0 (DCRN_POB0_BASE + 0x0) +#define DCRN_POB0_BEAR (DCRN_POB0_BASE + 0x2) +#define DCRN_POB0_BESR1 (DCRN_POB0_BASE + 0x4) +#endif + +#ifdef DCRN_UIC0_BASE +#define DCRN_UIC0_SR (DCRN_UIC0_BASE + 0x0) +#define DCRN_UIC0_ER (DCRN_UIC0_BASE + 0x2) +#define DCRN_UIC0_CR (DCRN_UIC0_BASE + 0x3) +#define DCRN_UIC0_PR (DCRN_UIC0_BASE + 0x4) +#define DCRN_UIC0_TR (DCRN_UIC0_BASE + 0x5) +#define DCRN_UIC0_MSR (DCRN_UIC0_BASE + 0x6) +#define DCRN_UIC0_VR (DCRN_UIC0_BASE + 0x7) +#define DCRN_UIC0_VCR (DCRN_UIC0_BASE + 0x8) +#endif + +#ifdef DCRN_UIC1_BASE +#define DCRN_UIC1_SR (DCRN_UIC1_BASE + 0x0) +#define DCRN_UIC1_SRS (DCRN_UIC1_BASE + 0x1) +#define DCRN_UIC1_ER (DCRN_UIC1_BASE + 0x2) +#define DCRN_UIC1_CR (DCRN_UIC1_BASE + 0x3) +#define DCRN_UIC1_PR (DCRN_UIC1_BASE + 0x4) +#define DCRN_UIC1_TR (DCRN_UIC1_BASE + 0x5) +#define DCRN_UIC1_MSR (DCRN_UIC1_BASE + 0x6) +#define DCRN_UIC1_VR (DCRN_UIC1_BASE + 0x7) +#define DCRN_UIC1_VCR (DCRN_UIC1_BASE + 0x8) +#endif + +#ifdef DCRN_SDRAM0_BASE +#define DCRN_SDRAM0_CFGADDR (DCRN_SDRAM0_BASE + 0x0) /* Memory Controller Address */ +#define DCRN_SDRAM0_CFGDATA (DCRN_SDRAM0_BASE + 0x1) /* Memory Controller Data */ +#endif + +#ifdef DCRN_OCM0_BASE +#define DCRN_OCMISARC (DCRN_OCM0_BASE + 0x0) /* OCM Instr Side Addr Range Compare */ +#define DCRN_OCMISCR (DCRN_OCM0_BASE + 0x1) /* OCM Instr Side Control */ +#define DCRN_OCMDSARC (DCRN_OCM0_BASE + 0x2) /* OCM Data Side Addr Range Compare */ +#define DCRN_OCMDSCR (DCRN_OCM0_BASE + 0x3) /* OCM Data Side Control */ +#endif + +#endif /* __ASM_IBM405_H__ */ +#endif /* __KERNEL__ */ diff --git a/arch/ppc/platforms/ibm405gp.c b/arch/ppc/platforms/ibm405gp.c new file mode 100644 index 000000000000..0b309d76d1d2 --- /dev/null +++ b/arch/ppc/platforms/ibm405gp.c @@ -0,0 +1,63 @@ +/* + * + * Copyright 2000-2001 MontaVista Software Inc. + * Completed implementation. + * Current maintainer + * Armin Kuster akuster@mvista.com + * + * Module name: ibm405gp.c + * + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + * History: 12/26/2001 - armin + * initial release + * + */ + +#include <linux/config.h> +#include <linux/init.h> +#include <linux/smp.h> +#include <linux/threads.h> +#include <linux/param.h> +#include <linux/string.h> +#include <platforms/ibm405gp.h> + +const struct pcil0_regs *PCIL_ADDR[] = { + (struct pcil0_regs *) PCIL0_BASE, +}; + +const struct NS16550 *COM_PORTS[] = { + (struct NS16550 *) UART0_IO_BASE, + (struct NS16550 *) UART1_IO_BASE, +}; + +struct iic_regs *IIC_ADDR[] = { + (struct iic_regs *) IIC0_BASE, +}; + +const struct gpio_regs *GPIO_ADDR[] = { + (struct gpio_regs *) GPIO0_BASE, +}; + +const struct emac_regs *EMAC_ADDR[] = { + (struct emac_regs *) EMAC0_BASE, +}; diff --git a/arch/ppc/platforms/ibm405gp.h b/arch/ppc/platforms/ibm405gp.h new file mode 100644 index 000000000000..255906f93bec --- /dev/null +++ b/arch/ppc/platforms/ibm405gp.h @@ -0,0 +1,176 @@ +/* + * ibm405gp.h + * + * This was derived from the ppc4xx.h and all 405GP specific + * definition and board inclusions were moved here. + * + * Armin Kuster akuster@mvista.com + * Oct, 2001 + * + * + * Copyright 2001 MontaVista Softare Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Version 1.0 (01/10/10) - A. Kuster + * Initial version - moved 40GP specific out of ppc4xx.h + * - moved emac reg from ppc405_enet.h + * + * Version 1.1 02/01/17 - A. Kuster + * Moved offsets to ibm405.h + */ + +#ifdef __KERNEL__ +#ifndef __ASM_IBM405GP_H__ +#define __ASM_IBM405GP_H__ + +#include <linux/config.h> +#include <platforms/ibm_ocp.h> + +/* ibm405.h at bottom of this file */ + +/* PCI + * PCI Bridge config reg definitions + * see 17-19 of manual + */ + +#define PPC405_PCI_CONFIG_ADDR 0xeec00000 +#define PPC405_PCI_CONFIG_DATA 0xeec00004 + +#define PPC405_PCI_PHY_MEM_BASE 0x80000000 /* hose_a->pci_mem_offset */ + /* setbat */ +#define PPC405_PCI_MEM_BASE PPC405_PCI_PHY_MEM_BASE /* setbat */ +#define PPC405_PCI_PHY_IO_BASE 0xe8000000 /* setbat */ +#define PPC405_PCI_IO_BASE PPC405_PCI_PHY_IO_BASE /* setbat */ + +#define PPC405_PCI_LOWER_MEM 0x80000000 /* hose_a->mem_space.start */ +#define PPC405_PCI_UPPER_MEM 0xBfffffff /* hose_a->mem_space.end */ +#define PPC405_PCI_LOWER_IO 0x00000000 /* hose_a->io_space.start */ +#define PPC405_PCI_UPPER_IO 0x0000ffff /* hose_a->io_space.end */ + +#define PPC405_ISA_IO_BASE PPC405_PCI_IO_BASE + +#define PPC4xx_PCI_IO_PADDR ((uint)PPC405_PCI_PHY_IO_BASE) +#define PPC4xx_PCI_IO_VADDR PPC4xx_PCI_IO_PADDR +#define PPC4xx_PCI_IO_SIZE ((uint)64*1024) +#define PPC4xx_PCI_CFG_PADDR ((uint)PPC405_PCI_CONFIG_ADDR) +#define PPC4xx_PCI_CFG_VADDR PPC4xx_PCI_CFG_PADDR +#define PPC4xx_PCI_CFG_SIZE ((uint)4*1024) +#define PPC4xx_PCI_LCFG_PADDR ((uint)0xef400000) +#define PPC4xx_PCI_LCFG_VADDR PPC4xx_PCI_LCFG_PADDR +#define PPC4xx_PCI_LCFG_SIZE ((uint)4*1024) +#define PPC4xx_ONB_IO_PADDR ((uint)0xef600000) +#define PPC4xx_ONB_IO_VADDR PPC4xx_ONB_IO_PADDR +#define PPC4xx_ONB_IO_SIZE ((uint)4*1024) + +/* serial port defines */ +#define RS_TABLE_SIZE 2 + +#define UART0_INT 0 +#define UART1_INT 1 + +#define PCIL0_BASE 0xEF400000 +#define UART0_IO_BASE (u8 *) 0xEF600300 +#define UART1_IO_BASE (u8 *) 0xEF600400 +#define IIC0_BASE 0xEF600500 +#define OPB0_BASE 0xEF600600 +#define GPIO0_BASE 0xEF600700 +#define EMAC0_BASE 0xEF600800 + +#define EMAC_NUMS 1 +#define UART_NUMS 2 +#define BD_EMAC_ADDR(e,i) bi_enetaddr[i] + +#define STD_UART_OP(num) \ + { 0, BASE_BAUD, 0, UART##num##_INT, \ + (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST), \ + iomem_base: UART##num##_IO_BASE, \ + io_type: SERIAL_IO_MEM}, + +#if defined(CONFIG_UART0_TTYS0) +#define SERIAL_PORT_DFNS \ + STD_UART_OP(0) \ + STD_UART_OP(1) +#endif + +#if defined(CONFIG_UART0_TTYS1) +#define SERIAL_PORT_DFNS \ + STD_UART_OP(1) \ + STD_UART_OP(0) +#endif + +/* DCR defines */ +#define DCRN_CHCR_BASE 0x0B1 +#define DCRN_CHPSR_BASE 0x0B4 +#define DCRN_CPMSR_BASE 0x0B8 +#define DCRN_CPMFR_BASE 0x0BA + +#define DCRN_CHPSR_BASE 0x0B4 +#define PSR_PLL_FWD_MASK 0xC0000000 +#define PSR_PLL_FDBACK_MASK 0x30000000 +#define PSR_PLL_TUNING_MASK 0x0E000000 +#define PSR_PLB_CPU_MASK 0x01800000 +#define PSR_OPB_PLB_MASK 0x00600000 +#define PSR_PCI_PLB_MASK 0x00180000 +#define PSR_EB_PLB_MASK 0x00060000 +#define PSR_ROM_WIDTH_MASK 0x00018000 +#define PSR_ROM_LOC 0x00004000 +#define PSR_PCI_ASYNC_EN 0x00001000 +#define PSR_PCI_ARBIT_EN 0x00000400 + +#define CPM_IIC0 0x80000000 /* IIC interface */ +#define CPM_PCI 0x40000000 /* PCI bridge */ +#define CPM_CPU 0x20000000 /* processor core */ +#define CPM_DMA 0x10000000 /* DMA controller */ +#define CPM_BRG 0x08000000 /* PLB to OPB bridge */ +#define CPM_DCP 0x04000000 /* CodePack */ +#define CPM_EBC 0x02000000 /* ROM/SRAM peripheral controller */ +#define CPM_SDRAM0 0x01000000 /* SDRAM memory controller */ +#define CPM_PLB 0x00800000 /* PLB bus arbiter */ +#define CPM_GPIO0 0x00400000 /* General Purpose IO (??) */ +#define CPM_UART0 0x00200000 /* serial port 0 */ +#define CPM_UART1 0x00100000 /* serial port 1 */ +#define CPM_UIC 0x00080000 /* Universal Interrupt Controller */ +#define CPM_TMRCLK 0x00040000 /* CPU timers */ +#define CPM_EMAC_MM 0x00020000 /* on-chip ethernet MM unit */ +#define CPM_EMAC_RM 0x00010000 /* on-chip ethernet RM unit */ +#define CPM_EMAC_TM 0x00008000 /* on-chip ethernet TM unit */ + +#define DCRN_DMA0_BASE 0x100 +#define DCRN_DMA1_BASE 0x108 +#define DCRN_DMA2_BASE 0x110 +#define DCRN_DMA3_BASE 0x118 +#define DCRNCAP_DMA_SG 1 /* have DMA scatter/gather capability */ +#define DCRN_DMASR_BASE 0x120 +#define DCRN_EBC_BASE 0x012 +#define DCRN_DCP0_BASE 0x014 +#define DCRN_MAL_BASE 0x180 +#define DCRN_OCM0_BASE 0x018 +#define DCRN_PLB0_BASE 0x084 +#define DCRN_PLLMR_BASE 0x0B0 +#define DCRN_POB0_BASE 0x0A0 +#define DCRN_SDRAM0_BASE 0x010 +#define DCRN_UIC0_BASE 0x0C0 + +#include <platforms/ibm405.h> + +#endif /* __ASM_IBM405GP_H__ */ +#endif /* __KERNEL__ */ diff --git a/arch/ppc/platforms/ibm_ocp.h b/arch/ppc/platforms/ibm_ocp.h new file mode 100644 index 000000000000..15361601cddf --- /dev/null +++ b/arch/ppc/platforms/ibm_ocp.h @@ -0,0 +1,192 @@ +/* + * ibm_ips.h + * + * This was dirived from the ppc4xx.h and all 405GP specific definition and board + * inclusions where moved here. + * + * Current Maintainer + * Armin Kuster akuster@mvista.com + * Nov, 2001 + * + * + * Copyright 2001 MontaVista Softare Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Version 1.0 (01/11/26) - A. Kuster + * Initial version - + */ + +#ifdef __KERNEL__ +#ifndef __ASM_IBM_IPS_H__ +#define __ASM_IBM_IPS_H__ + +#ifndef __ASSEMBLY__ +#include <linux/types.h> + + /* PCI 32 */ + +struct pmm_regs { + u32 la; + u32 ma; + u32 pcila; + u32 pciha; +}; + +typedef struct pcil0_regs { + struct pmm_regs pmm[3]; + u32 ptm1ms; + u32 ptm1la; + u32 ptm2ms; + u32 ptm2la; +} pci0_t; + +/* Serial Ports */ + +#define thr rbr +#define iir fcr +#define dll rbr +#define dlm ier + +typedef struct NS16550 { + u8 rbr; /* 0 */ + u8 ier; /* 1 */ + u8 fcr; /* 2 */ + u8 lcr; /* 3 */ + u8 mcr; /* 4 */ + u8 lsr; /* 5 */ + u8 msr; /* 6 */ + u8 scr; /* 7 */ +} uart_t; + +/* I2c */ +typedef struct iic_regs { + u16 mdbuf; + u16 sbbuf; + u8 lmadr; + u8 hmadr; + u8 cntl; + u8 mdcntl; + u8 sts; + u8 extsts; + u8 lsadr; + u8 hsadr; + u8 clkdiv; + u8 intmsk; + u8 xfrcnt; + u8 xtcntlss; + u8 directcntl; +} iic_t; + +/* OPB arbiter */ +typedef struct opb { + u8 pr; + u8 cr; +} opb_t; + +/* General purpose i/o */ + +typedef struct gpio_regs { + u32 or; + u32 tcr; + u32 pad[4]; + u32 odr; + u32 ir; +} gpio_t; + +/* Emac */ +typedef struct emac_regs { + volatile u32 em0mr0; + volatile u32 em0mr1; + volatile u32 em0tmr0; + volatile u32 em0tmr1; + volatile u32 em0rmr; + volatile u32 em0isr; + volatile u32 em0iser; + volatile u32 em0iahr; + volatile u32 em0ialr; + volatile u32 em0vtpid; + volatile u32 em0vtci; + volatile u32 em0ptr; + volatile u32 em0iaht1; + volatile u32 em0iaht2; + volatile u32 em0iaht3; + volatile u32 em0iaht4; + volatile u32 em0gaht1; + volatile u32 em0gaht2; + volatile u32 em0gaht3; + volatile u32 em0gaht4; + volatile u32 em0lsal; + volatile u32 em0lsah; + volatile u32 em0ipgvr; + volatile u32 em0stacr; + volatile u32 em0trtr; + volatile u32 em0rwmr; +} emac_t; + +/* ZMII bridge */ +typedef struct zmii_regs { + u32 fer; /* Function enable reg */ + u32 ssr; /* Spedd select reg */ + u32 smiirs; /* SMII status reg */ +} zmii_t; + +/* Structure of the memory mapped IDE control. +*/ +typedef struct ide_regs { + unsigned int si_stat; /* IDE status */ + unsigned int si_intenable; /* IDE interrupt enable */ + unsigned int si_control; /* IDE control */ + unsigned int pad0[0x3d]; + unsigned int si_c0rt; /* Chan 0 Register transfer timing */ + unsigned int si_c0fpt; /* Chan 0 Fast PIO transfer timing */ + unsigned int si_c0timo; /* Chan 0 timeout */ + unsigned int pad1[2]; + unsigned int si_c0d0u; /* Chan 0 UDMA transfer timing */ +#define si_c0d0m si_c0d0u /* Chan 0 Multiword DMA timing */ + unsigned int pad2; + unsigned int si_c0d1u; /* Chan 0 dev 1 UDMA timing */ +#define si_c0d1m si_c0d1u /* Chan 0 dev 1 Multiword DMA timing */ + unsigned int si_c0c; /* Chan 0 Control */ + unsigned int si_c0s0; /* Chan 0 Status 0 */ + unsigned int si_c0ie; /* Chan 0 Interrupt Enable */ + unsigned int si_c0s1; /* Chan 0 Status 0 */ + unsigned int pad4[4]; + unsigned int si_c0dcm; /* Chan 0 DMA Command */ + unsigned int si_c0tb; /* Chan 0 PRD Table base address */ + unsigned int si_c0dct; /* Chan 0 DMA Count */ + unsigned int si_c0da; /* Chan 0 DMA Address */ + unsigned int si_c0sr; /* Chan 0 Slew Rate Output Control */ + unsigned char pad5[0xa2]; + unsigned short si_c0adc; /* Chan 0 Alt status/control */ + unsigned char si_c0d; /* Chan 0 data */ + unsigned char si_c0ef; /* Chan 0 error/features */ + unsigned char si_c0sct; /* Chan 0 sector count */ + unsigned char si_c0sn; /* Chan 0 sector number */ + unsigned char si_c0cl; /* Chan 0 cylinder low */ + unsigned char si_c0ch; /* Chan 0 cylinder high */ + unsigned char si_c0dh; /* Chan 0 device/head */ + unsigned char si_c0scm; /* Chan 0 status/command */ +} ide_t; + +#endif /* __ASSEMBLY__ */ +#endif /* __ASM_IBM_IPS_H__ */ +#endif /* __KERNEL__ */ diff --git a/arch/ppc/platforms/ibmnp405h.c b/arch/ppc/platforms/ibmnp405h.c new file mode 100644 index 000000000000..9b8f1dbacd02 --- /dev/null +++ b/arch/ppc/platforms/ibmnp405h.c @@ -0,0 +1,78 @@ +/* + * + * Copyright 2000-2002 MontaVista Software Inc. + * Completed implementation. + * Current maintainer + * Armin Kuster akuster@mvista.com + * + * Module name: ibmnp405h.c + * + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + * History: 01/02/2002 - armin + * initial release + * + */ + +#include <linux/config.h> +#include <linux/init.h> +#include <linux/smp.h> +#include <linux/threads.h> +#include <linux/param.h> +#include <linux/string.h> +#include <platforms/ibmnp405h.h> + +const struct NS16550* COM_PORTS[] = +{ + (struct NS16550*) UART0_IO_BASE, + (struct NS16550*) UART1_IO_BASE, +}; + +const struct pcil0_regs* PCIL0[]= +{ + (struct pcil0_regs*) PCIL0_BASE, +}; + + +const struct iic_regs* IIC_ADDR[]= +{ + (struct iic_regs*) IIC0_BASE, +}; + + +const struct gpio_regs* GPIO_ADDR[] = +{ + (struct gpio_regs*) GPIO0_BASE, +}; + +const struct emac_regs* EMAC_ADDR[]= +{ + (struct emac_regs*) EMAC0_BASE, + (struct emac_regs*) EMAC1_BASE, + (struct emac_regs*) EMAC2_BASE, + (struct emac_regs*) EMAC3_BASE +}; + +const struct zmii_regs* ZMII_ADDR[]= +{ + (zmii_t*) ZMII0_BASE, +}; diff --git a/arch/ppc/platforms/ibmnp405h.h b/arch/ppc/platforms/ibmnp405h.h new file mode 100644 index 000000000000..c469393344ac --- /dev/null +++ b/arch/ppc/platforms/ibmnp405h.h @@ -0,0 +1,172 @@ +/* + * ibmnp405h.h + * + * This was dirived from the ibm405gp.h and other previus works in ppc4xx.h + * + * Current maintainer + * Armin Kuster akuster@mvista.com + * Jan, 2002 + * + * + * Copyright 2002 MontaVista Softare Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Version 1.0 (02/01/03) - A. Kuster + * Initial version + * + * Version 1.1 02/01/17 - A. Kuster + * moved common ofsets to ibm405.h + */ + +#ifdef __KERNEL__ +#ifndef __ASM_IBMNP405H_H__ +#define __ASM_IBMNP405H_H__ + +#include <linux/config.h> +#include <platforms/ibm_ocp.h> + +/* ibm405.h at bottom of this file */ + +#define PPC405_PCI_CONFIG_ADDR 0xeec00000 +#define PPC405_PCI_CONFIG_DATA 0xeec00004 +#define PPC405_PCI_PHY_MEM_BASE 0x80000000 /* hose_a->pci_mem_offset */ + /* setbat */ +#define PPC405_PCI_MEM_BASE PPC405_PCI_PHY_MEM_BASE /* setbat */ +#define PPC405_PCI_PHY_IO_BASE 0xe8000000 /* setbat */ +#define PPC405_PCI_IO_BASE PPC405_PCI_PHY_IO_BASE /* setbat */ + +#define PPC405_PCI_LOWER_MEM 0x00000000 /* hose_a->mem_space.start */ +#define PPC405_PCI_UPPER_MEM 0xBfffffff /* hose_a->mem_space.end */ +#define PPC405_PCI_LOWER_IO 0x00000000 /* hose_a->io_space.start */ +#define PPC405_PCI_UPPER_IO 0x0000ffff /* hose_a->io_space.end */ + +#define PPC405_ISA_IO_BASE PPC405_PCI_IO_BASE + +#define PPC4xx_PCI_IO_ADDR ((uint)PPC405_PCI_PHY_IO_BASE) +#define PPC4xx_PCI_IO_SIZE ((uint)64*1024) +#define PPC4xx_PCI_CFG_ADDR ((uint)PPC405_PCI_CONFIG_ADDR) +#define PPC4xx_PCI_CFG_SIZE ((uint)4*1024) +#define PPC4xx_PCI_LCFG_ADDR ((uint)0xef400000) +#define PPC4xx_PCI_LCFG_SIZE ((uint)4*1024) +#define PPC4xx_ONB_IO_ADDR ((uint)0xef600000) +#define PPC4xx_ONB_IO_SIZE ((uint)4*1024) + +/* serial port defines */ +#define RS_TABLE_SIZE 4 + +#define UART0_INT 0 +#define UART1_INT 1 +#define PCIL0_BASE 0xEF400000 +#define UART0_IO_BASE 0xEF600300 +#define UART1_IO_BASE 0xEF600400 +#define IIC0_BASE 0xEF600500 +#define OPB0_BASE 0xEF600600 +#define GPIO0_BASE 0xEF600700 +#define EMAC0_BASE 0xEF600800 +#define EMAC1_BASE 0xEF600900 +#define EMAC2_BASE 0xEF600900 +#define EMAC3_BASE 0xEF600900 +#define ZMII0_BASE 0xEF600C10 + +#define EMAC_NUMS 4 +#define UART_NUMS 2 +#define ZMII_NUMS 1 +#define BD_EMAC_ADDR(e,i) bi_enetaddr[e][i] + +#define STD_UART_OP(num) \ + { 0, BASE_BAUD, 0, UART##num##_INT, \ + (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST), \ + iomem_base: UART##num##_IO_BASE, \ + io_type: SERIAL_IO_MEM}, + +#if defined(CONFIG_UART0_TTYS0) +#define SERIAL_PORT_DFNS \ + STD_UART_OP(0) \ + STD_UART_OP(1) +#endif + +#if defined(CONFIG_UART0_TTYS1) +#define SERIAL_PORT_DFNS \ + STD_UART_OP(1) \ + STD_UART_OP(0) +#endif + +/* DCR defines */ +/* ------------------------------------------------------------------------- */ + +#define DCRN_CHCR_BASE 0x0B1 +#define DCRN_CHPSR_BASE 0x0B4 +#define DCRN_CPMSR_BASE 0x0B8 +#define DCRN_CPMFR_BASE 0x0BA + +#define CPM_IIC0 0x80000000 /* IIC interface */ +#define CPM_PCI 0x40000000 /* PCI bridge */ +#define CPM_CPU 0x20000000 /* processor core */ +#define CPM_DMA 0x10000000 /* DMA controller */ +#define CPM_BRG 0x08000000 /* PLB to OPB bridge */ +#define CPM_DCP 0x04000000 /* CodePack */ +#define CPM_EBC 0x02000000 /* ROM/SRAM peripheral controller */ +#define CPM_SDRAM0 0x01000000 /* SDRAM memory controller */ +#define CPM_PLB 0x00800000 /* PLB bus arbiter */ +#define CPM_GPIO0 0x00400000 /* General Purpose IO (??) */ +#define CPM_UART0 0x00200000 /* serial port 0 */ +#define CPM_UART1 0x00100000 /* serial port 1 */ +#define CPM_UIC = 0x00080000 /* Universal Interrupt Controller */ +#define CPM_TMRCLK 0x00040000 /* CPU timers */ +#define CPM_EMAC_MM 0x00020000 /* on-chip ethernet MM unit */ +#define CPM_EMAC_RM 0x00010000 /* on-chip ethernet RM unit */ +#define CPM_EMAC_TM 0x00008000 /* on-chip ethernet TM unit */ + +#define DCRN_DMA0_BASE 0x100 +#define DCRN_DMA1_BASE 0x108 +#define DCRN_DMA2_BASE 0x110 +#define DCRN_DMA3_BASE 0x118 +#define DCRNCAP_DMA_SG 1 /* have DMA scatter/gather capability */ +#define DCRN_DMASR_BASE 0x120 +#define DCRN_EBC_BASE 0x012 +#define DCRN_DCP0_BASE 0x014 +#define DCRN_MAL_BASE 0x180 +#define DCRN_OCM0_BASE 0x018 +#define DCRN_PLB0_BASE 0x084 +#define DCRN_PLLMR_BASE 0x0B0 +#define DCRN_POB0_BASE 0x0A0 +#define DCRN_SDRAM0_BASE 0x010 +#define DCRN_UIC0_BASE 0x0C0 + +/* unique H offsets */ + +#ifdef DCRN_UIC1_BASE +#define DCRN_UIC1_SR (DCRN_UIC1_BASE + 0x0) +#define DCRN_UIC1_SRS (DCRN_UIC1_BASE + 0x1) +#define DCRN_UIC1_ER (DCRN_UIC1_BASE + 0x2) +#define DCRN_UIC1_CR (DCRN_UIC1_BASE + 0x3) +#define DCRN_UIC1_PR (DCRN_UIC1_BASE + 0x4) +#define DCRN_UIC1_TR (DCRN_UIC1_BASE + 0x5) +#define DCRN_UIC1_MSR (DCRN_UIC1_BASE + 0x6) +#define DCRN_UIC1_VR (DCRN_UIC1_BASE + 0x7) +#define DCRN_UIC1_VCR (DCRN_UIC1_BASE + 0x8) +#endif + +#include <platforms/ibm405.h> + +#endif /* __ASM_IBMNP405H_H__ */ +#endif /* __KERNEL__ */ diff --git a/arch/ppc/platforms/ibmnp405l.c b/arch/ppc/platforms/ibmnp405l.c new file mode 100644 index 000000000000..1bf1be86552b --- /dev/null +++ b/arch/ppc/platforms/ibmnp405l.c @@ -0,0 +1,70 @@ +/* + * + * Copyright 2000-2001 MontaVista Software Inc. + * Completed implementation. + * Current maintainer + * Armin Kuster akuster@mvista.com + * + * Module name: ibmnp405l.c + * + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + * History: 12/26/2001 - armin + * initial release + * + */ + +#include <linux/config.h> +#include <linux/init.h> +#include <linux/smp.h> +#include <linux/threads.h> +#include <linux/param.h> +#include <linux/string.h> +#include <platforms/ibmnp405l.h> + +const struct NS16550* COM_PORTS[] = +{ + (struct NS16550*) UART0_IO_BASE, + (struct NS16550*) UART1_IO_BASE, +}; + +const struct iic_regs* IIC_ADDR[]= +{ + (struct iic_regs*) IIC0_BASE, +}; + + +const struct gpio_regs* GPIO_ADDR[] = +{ + (struct gpio_regs*) GPIO0_BASE, +}; + +const struct emac_regs* EMAC_ADDR[]= +{ + (struct emac_regs*) EMAC0_BASE, + (struct emac_regs*) EMAC1_BASE +}; + +const struct zmii_regs* ZMII_ADDR[]= +{ + (zmii_t*) ZMII0_BASE, +}; diff --git a/arch/ppc/platforms/ibmnp405l.h b/arch/ppc/platforms/ibmnp405l.h new file mode 100644 index 000000000000..cbc8e7fbe721 --- /dev/null +++ b/arch/ppc/platforms/ibmnp405l.h @@ -0,0 +1,156 @@ +/* + * ibmnp405l.h + * + * This was dirived from the ibm405gp.h and other previus works in ppc4xx.h + * + * Current maintainer + * Armin Kuster akuster@mvista.com + * Oct, 2001 + * + * + * Copyright 2001 MontaVista Softare Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Version 1.0 (01/10/10) - A. Kuster + * Initial version + * + * Version 1.1 (02/01/16) - A. Kuster + * Cleaned out common 405B3 core stuff + */ + +#ifdef __KERNEL__ +#ifndef __ASM_IBMNP405L_H__ +#define __ASM_IBMNP405L_H__ + +#include <linux/config.h> +#include <platforms/ibm_ocp.h> + +/* ibm405.h at bottom of this file */ + +#define PPC4xx_PCI_IO_ADDR ((uint)PPC405_PCI_PHY_IO_BASE) +#define PPC4xx_PCI_IO_SIZE ((uint)64*1024) +#define PPC4xx_PCI_CFG_ADDR ((uint)PPC405_PCI_CONFIG_ADDR) +#define PPC4xx_PCI_CFG_SIZE ((uint)4*1024) +#define PPC4xx_PCI_LCFG_ADDR ((uint)0xef400000) +#define PPC4xx_PCI_LCFG_SIZE ((uint)4*1024) +#define PPC4xx_ONB_IO_ADDR ((uint)0xef600000) +#define PPC4xx_ONB_IO_SIZE ((uint)4*1024) + +/* serial port defines */ +#define RS_TABLE_SIZE 2 + +#define UART0_INT 0 +#define UART1_INT 1 + +#define UART0_IO_BASE (u8 *)0xEF600300 +#define UART1_IO_BASE (u8 *)0xEF600400 +#define IIC0_BASE 0xEF600500 +#define OPB0_BASE 0xEF600600 +#define GPIO0_BASE 0xEF600700 +#define EMAC0_BASE 0xEF600800 +#define EMAC1_BASE 0xEF600900 +#define ZMII0_BASE 0xEF600C10 + +#define EMAC_NUMS 2 +#define UART_NUMS 2 +#define ZMII_NUMS 1 +#define BD_EMAC_ADDR(e,i) bi_enetaddr[e][i] + +#define STD_UART_OP(num) \ + { 0, BASE_BAUD, 0, UART##num##_INT, \ + (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST), \ + iomem_base: UART##num##_IO_BASE, \ + io_type: SERIAL_IO_MEM}, + +#if defined(CONFIG_UART0_TTYS0) +#define SERIAL_PORT_DFNS \ + STD_UART_OP(0) \ + STD_UART_OP(1) +#endif + +#if defined(CONFIG_UART0_TTYS1) +#define SERIAL_PORT_DFNS \ + STD_UART_OP(1) \ + STD_UART_OP(0) +#endif + +/* DCR defines */ +/* ------------------------------------------------------------------------- */ + +#define DCRN_CHCR_BASE 0x0B1 +#define DCRN_CHPSR_BASE 0x0B4 +#define DCRN_CPMSR_BASE 0x0B8 +#define DCRN_CPMFR_BASE 0x0BA + +#define CPM_IIC0 0x80000000 /* IIC interface */ +#define CPM_PCI 0x40000000 /* PCI bridge */ +#define CPM_CPU 0x20000000 /* processor core */ +#define CPM_DMA 0x10000000 /* DMA controller */ +#define CPM_BRG 0x08000000 /* PLB to OPB bridge */ +#define CPM_DCP 0x04000000 /* CodePack */ +#define CPM_EBC 0x02000000 /* ROM/SRAM peripheral controller */ +#define CPM_SDRAM0 0x01000000 /* SDRAM memory controller */ +#define CPM_PLB 0x00800000 /* PLB bus arbiter */ +#define CPM_GPIO0 0x00400000 /* General Purpose IO (??) */ +#define CPM_UART0 0x00200000 /* serial port 0 */ +#define CPM_UART1 0x00100000 /* serial port 1 */ +#define CPM_UIC 0x00080000 /* Universal Interrupt Controller */ +#define CPM_TMRCLK 0x00040000 /* CPU timers */ +#define CPM_EMAC_MM 0x00020000 /* on-chip ethernet MM unit */ +#define CPM_EMAC_RM 0x00010000 /* on-chip ethernet RM unit */ +#define CPM_EMAC_TM 0x00008000 /* on-chip ethernet TM unit */ + +#define DCRN_DMA0_BASE 0x100 +#define DCRN_DMA1_BASE 0x108 +#define DCRN_DMA2_BASE 0x110 +#define DCRN_DMA3_BASE 0x118 +#define DCRNCAP_DMA_SG 1 /* have DMA scatter/gather capability */ +#define DCRN_DMASR_BASE 0x120 +#define DCRN_EBC_BASE 0x012 +#define DCRN_DCP0_BASE 0x014 +#define DCRN_MAL_BASE 0x180 +#define DCRN_OCM0_BASE 0x018 +#define DCRN_PLB0_BASE 0x084 +#define DCRN_PLLMR_BASE 0x0B0 +#define DCRN_POB0_BASE 0x0A0 +#define DCRN_SDRAM0_BASE 0x010 +#define DCRN_UIC0_BASE 0x0C0 +#define DCRN_UIC1_BASE 0x0C0 + +/* need to clean this up - armin */ + +#ifdef DCRN_UIC1_BASE +#define DCRN_UIC1_SR (DCRN_UIC1_BASE + 0x0) +#define DCRN_UIC1_SRS (DCRN_UIC1_BASE + 0x1) +#define DCRN_UIC1_ER (DCRN_UIC1_BASE + 0x2) +#define DCRN_UIC1_CR (DCRN_UIC1_BASE + 0x3) +#define DCRN_UIC1_PR (DCRN_UIC1_BASE + 0x4) +#define DCRN_UIC1_TR (DCRN_UIC1_BASE + 0x5) +#define DCRN_UIC1_MSR (DCRN_UIC1_BASE + 0x6) +#define DCRN_UIC1_VR (DCRN_UIC1_BASE + 0x7) +#define DCRN_UIC1_VCR (DCRN_UIC1_BASE + 0x8) +#endif + +#include <platforms/ibm405.h> + +#endif /* __ASM_IBMNP405L_H__ */ +#endif /* __KERNEL__ */ diff --git a/arch/ppc/platforms/ibmstb3.c b/arch/ppc/platforms/ibmstb3.c new file mode 100644 index 000000000000..75205fbc1555 --- /dev/null +++ b/arch/ppc/platforms/ibmstb3.c @@ -0,0 +1,53 @@ +/* + * + * Copyright 2000-2001 MontaVista Software Inc. + * Completed implementation. + * Current maintainer + * Armin Kuster akuster@mvista.com + * + * Module name: ibmstb3.c + * + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + * History: 01/08/2002 - armin + * initial release + * + */ + +#include <linux/config.h> +#include <platforms/ibmstb3.h> + +const struct NS16550* COM_PORTS[] = +{ + (struct NS16550*) UART0_IO_BASE, +}; + +const struct iic_regs* IIC_ADDR[]= +{ + (struct iic_regs*) IIC0_BASE, +}; + +const struct gpio_regs* GPIO_ADDR[] = +{ + (struct gpio_regs*) GPIO0_BASE, +}; + diff --git a/arch/ppc/platforms/ibmstb3.h b/arch/ppc/platforms/ibmstb3.h new file mode 100644 index 000000000000..dd4eb456b48c --- /dev/null +++ b/arch/ppc/platforms/ibmstb3.h @@ -0,0 +1,288 @@ +/* + * ibmstbx.h + * + * This was dirived from the ppc4xx.h and all stbx specific definitions + * are located here. + * + * Armin Kuster <akuster@mvista.com> + * Tom Rini <trini@mvista.com> + * Oct, 2001 + * + * + * + * Copyright 2001 MontaVista Softare Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Version 1.0 Oct 10, 2001 - A. Kuster + * Initial version - moved stbx specific out of ibm4xx.h + * + * Version 1.1 Oct 25, 2001 - T. Rini + * Lots of cleanups, and we get included by the board-specific file. + * + * Version 1.2 Jan 16, 2002 - A. Kuster + * Removed common dcr offests that are now in ibm405.h + * + */ + +#ifdef __KERNEL__ +#ifndef __ASM_IBMSTBX_H__ +#define __ASM_IBMSTBX_H__ + +#include <linux/config.h> +#include <platforms/ibm_ocp.h> + +/* ibm405.h at bottom of this file */ + +/* + * Memory map for the IBM "Redwood-4" STB03xxx evaluation board. + * + * The STB03xxx internal i/o addresses don't work for us 1:1, + * so we need to map them at a well know virtual address. + * + * 4000 000x uart1 -> 0xe000 000x + * 4001 00xx ppu + * 4002 00xx smart card + * 4003 000x iic + * 4004 000x uart0 + * 4005 0xxx timer + * 4006 00xx gpio + * 4007 00xx smart card + * 400b 000x iic + * 400c 000x scp + * 400d 000x modem + */ + +#define STB03xxx_IO_BASE ((uint)0xe0000000) +#define PPC4xx_ONB_IO_PADDR ((uint)0x40000000) +#define PPC4xx_ONB_IO_VADDR STB03xxx_IO_BASE +#define PPC4xx_ONB_IO_SIZE ((uint)14*64*1024) + +/* Since we're into address mapping hacks, at least try to hide + * it under a macro..... + */ +#define STB03xxx_MAP_IO_ADDR(a) (((uint)(a) & 0x000fffff) + PPC4xx_ONB_IO_VADDR) + +#define RS_TABLE_SIZE 1 +#define UART0_INT 20 +#ifdef __BOOTER__ +#define UART0_IO_BASE (u8 *)0x40040000 +#else +#define UART0_IO_BASE (u8 *)STB03xxx_MAP_IO_ADDR(0x40040000) +#endif + + /* UART 0 is duped here so when the SICC is the default console + * then ttys1 is configured properly - armin + */ + +#define UART1_INT 20 +#ifdef __BOOTER__ +#define UART1_IO_BASE (u8 *)0x40040000 +#else +#define UART1_IO_BASE (u8 *)STB03xxx_MAP_IO_ADDR(0x40040000) +#endif + +/* need to make this work in scheme - armin */ + +#define SICC0_INTRX 21 +#define SICC0_INTTX 22 +#define SICC0_IO_BASE ((uint* )0x40000000) + +#define IIC0_BASE 0x40030000 +#define IIC1_BASE 0x400b0000 +#define OPB0_BASE 0x40010000 +#define GPIO0_BASE 0x40060000 + +#define BD_EMAC_ADDR(e,i) bi_enetaddr[i] + +#define STD_UART_OP(num) \ + { 0, BASE_BAUD, 0, UART##num##_INT, \ + (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST), \ + iomem_base: UART##num##_IO_BASE, \ + io_type: SERIAL_IO_MEM}, + +#if defined(CONFIG_UART0_TTYS0) +#define SERIAL_PORT_DFNS \ + STD_UART_OP(0) +#endif + +#if defined(CONFIG_UART0_TTYS1) +#define SERIAL_PORT_DFNS \ + STD_UART_OP(1) +#endif + +/* ------------------------------------------------------------------------- */ + +#define DCRN_DCRX_BASE 0x020 +#define DCRN_CIC_BASE 0x030 +#define DCRN_UIC0_BASE 0x040 +#define DCRN_PLB0_BASE 0x054 +#define DCRN_PLB1_BASE 0x064 +#define DCRN_EBIMC_BASE 0x070 +#define DCRN_POB0_BASE 0x0B0 + +#define DCRN_BE_BASE 0x090 +#define DCRN_DMA0_BASE 0x0C0 +#define DCRN_DMA1_BASE 0x0C8 +#define DCRN_DMA2_BASE 0x0D0 +#define DCRN_DMA3_BASE 0x0D8 +#define DCRNCAP_DMA_CC 1 /* have DMA chained count capability */ +#define DCRN_DMASR_BASE 0x0E0 + +#define DCRN_CPMFR_BASE 0x102 +#define DCRN_SCCR_BASE 0x120 + +#define CPM_IIC0 0x80000000 /* IIC 0 interface */ +#define CPM_I1284 0x40000000 /* IEEE-1284 */ +#define CPM_IIC1 0x20000000 /* IIC 1 interface */ +#define CPM_CPU 0x10000000 /* PPC405B3 clock control */ +#define CPM_AUD 0x08000000 /* Audio Decoder */ +#define CPM_EBIU 0x04000000 /* External Bus Interface Unit */ +#define CPM_SDRAM1 0x02000000 /* SDRAM 1 memory controller */ +#define CPM_DMA 0x01000000 /* DMA controller */ +#define CPM_RES_1 0x00800000 /* reserved */ +#define CPM_RES_2 0x00400000 /* reserved */ +#define CPM_RES_3 0x00200000 /* reserved */ +#define CPM_UART1 0x00100000 /* Serial 1 / Infrared */ +#define CPM_UART0 0x00080000 /* Serial 0 / 16550 */ +#define CPM_DCRX 0x00040000 /* DCR Extension */ +#define CPM_SC0 0x00020000 /* Smart Card 0 */ +#define CPM_RES_4 0x00010000 /* reserved */ +#define CPM_SC1 0x00008000 /* Smart Card 1 */ +#define CPM_SDRAM0 0x00004000 /* SDRAM 0 memory controller */ +#define CPM_XPT54 0x00002000 /* Transport - 54 Mhz */ +#define CPM_CBS 0x00001000 /* Cross Bar Switch */ +#define CPM_GPT 0x00000800 /* GPTPWM */ +#define CPM_GPIO0 0x00000400 /* General Purpose IO 0 */ +#define CPM_DENC 0x00000200 /* Digital video Encoder */ +#define CPM_TMRCLK 0x00000100 /* CPU timers */ +#define CPM_XPT27 0x00000080 /* Transport - 27 Mhz */ +#define CPM_UIC 0x00000040 /* Universal Interrupt Controller */ +#define CPM_RES_5 0x00000020 /* reserved */ +#define CPM_MSI 0x00000010 /* Modem Serial Interface (SSP) */ +#define CPM_UART2 0x00000008 /* Serial Control Port */ +#define CPM_DSCR 0x00000004 /* Descrambler */ +#define CPM_VID2 0x00000002 /* Video Decoder clock domain 2 */ +#define CPM_RES_6 0x00000001 /* reserved */ + +/* 0x80000000 */ +#define UIC_XPORT 0x40000000 /* 1 Transport */ +#define UIC_AUDIO 0x20000000 /* 2 Audio Decoder */ +#define UIC_VIDEO 0x10000000 /* 3 Video Decoder */ +#define UIC_D0 0x08000000 /* 4 DMA Channel 0 */ +#define UIC_D1 0x04000000 /* 5 DMA Channel 1 */ +#define UIC_D2 0x02000000 /* 6 DMA Channel 2 */ +#define UIC_D3 0x01000000 /* 7 DMA Channel 3 */ +#define UIC_SC0 0x00800000 /* 8 SmartCard 0 Controller */ +#define UIC_IIC0 0x00400000 /* 9 IIC 0 */ +#define UIC_IIC1 0x00200000 /* 10 IIC 1 */ +#define UIC_PWM0 0x00100000 /* 11 GPT_PWM 0: Capture Timers */ +#define UIC_PWM1 0x00080000 /* 12 GPT_PWM 1: Compare Timers */ +#define UIC_SCP 0x00040000 /* 13 Serial Control Port */ +#define UIC_SSP 0x00020000 /* 14 Soft Modem/Synchronous Serial Port */ +#define UIC_PWM2 0x00010000 /* 15 GPT_PWM 2: Down Counters */ +#define UIC_SC1 0x00008000 /* 16 SmartCard 1 Controller */ +#define UIC_EIR7 0x00004000 /* 17 External IRQ 7 */ +#define UIC_EIR8 0x00002000 /* 18 External IRQ 8 */ +#define UIC_EIR9 0x00001000 /* 19 External IRQ 9 */ +#define UIC_U0 0x00000800 /* 20 UART0 */ +#define UIC_IR_RCV 0x00000400 /* 21 Serial 1 / Infrared UART Receive */ +#define UIC_IR_XMIT 0x00000200 /* 22 Serial 1 / Infrared UART Transmit */ +#define UIC_IEEE1284 0x00000100 /* 23 IEEE-1284 / PPU */ +#define UIC_DCRX 0x00000080 /* 24 DCRX */ +#define UIC_EIR0 0x00000040 /* 25 External IRQ 0 */ +#define UIC_EIR1 0x00000020 /* 26 External IRQ 1 */ +#define UIC_EIR2 0x00000010 /* 27 External IRQ 2 */ +#define UIC_EIR3 0x00000008 /* 28 External IRQ 3 */ +#define UIC_EIR4 0x00000004 /* 29 External IRQ 4 */ +#define UIC_EIR5 0x00000002 /* 30 External IRQ 5 */ +#define UIC_EIR6 0x00000001 /* 31 External IRQ 6 */ + +#ifdef DCRN_CIC_BASE +#define DCRN_CICCR (DCRN_CIC_BASE + 0x0) /* CIC Control Register */ +#define DCRN_DMAS1 (DCRN_CIC_BASE + 0x1) /* DMA Select1 Register */ +#define DCRN_DMAS2 (DCRN_CIC_BASE + 0x2) /* DMA Select2 Register */ +#define DCRN_CICVCR (DCRN_CIC_BASE + 0x3) /* CIC Video COntro Register */ +#define DCRN_CICSEL3 (DCRN_CIC_BASE + 0x5) /* CIC Select 3 Register */ +#define DCRN_SGPO (DCRN_CIC_BASE + 0x6) /* CIC GPIO Output Register */ +#define DCRN_SGPOD (DCRN_CIC_BASE + 0x7) /* CIC GPIO OD Register */ +#define DCRN_SGPTC (DCRN_CIC_BASE + 0x8) /* CIC GPIO Tristate Ctrl Reg */ +#define DCRN_SGPI (DCRN_CIC_BASE + 0x9) /* CIC GPIO Input Reg */ +#endif + +#ifdef DCRN_DCRX_BASE +#define DCRN_DCRXICR (DCRN_DCRX_BASE + 0x0) /* Internal Control Register */ +#define DCRN_DCRXISR (DCRN_DCRX_BASE + 0x1) /* Internal Status Register */ +#define DCRN_DCRXECR (DCRN_DCRX_BASE + 0x2) /* External Control Register */ +#define DCRN_DCRXESR (DCRN_DCRX_BASE + 0x3) /* External Status Register */ +#define DCRN_DCRXTAR (DCRN_DCRX_BASE + 0x4) /* Target Address Register */ +#define DCRN_DCRXTDR (DCRN_DCRX_BASE + 0x5) /* Target Data Register */ +#define DCRN_DCRXIGR (DCRN_DCRX_BASE + 0x6) /* Interrupt Generation Register */ +#define DCRN_DCRXBCR (DCRN_DCRX_BASE + 0x7) /* Line Buffer Control Register */ +#endif + +#ifdef DCRN_EBC_BASE +#define DCRN_EBCCFGADR (DCRN_EBC_BASE + 0x0) /* Peripheral Controller Address */ +#define DCRN_EBCCFGDATA (DCRN_EBC_BASE + 0x1) /* Peripheral Controller Data */ +#endif + +#ifdef DCRN_EBIMC_BASE +#define DCRN_BRCRH0 (DCRN_EBIMC_BASE + 0x0) /* Bus Region Config High 0 */ +#define DCRN_BRCRH1 (DCRN_EBIMC_BASE + 0x1) /* Bus Region Config High 1 */ +#define DCRN_BRCRH2 (DCRN_EBIMC_BASE + 0x2) /* Bus Region Config High 2 */ +#define DCRN_BRCRH3 (DCRN_EBIMC_BASE + 0x3) /* Bus Region Config High 3 */ +#define DCRN_BRCRH4 (DCRN_EBIMC_BASE + 0x4) /* Bus Region Config High 4 */ +#define DCRN_BRCRH5 (DCRN_EBIMC_BASE + 0x5) /* Bus Region Config High 5 */ +#define DCRN_BRCRH6 (DCRN_EBIMC_BASE + 0x6) /* Bus Region Config High 6 */ +#define DCRN_BRCRH7 (DCRN_EBIMC_BASE + 0x7) /* Bus Region Config High 7 */ +#define DCRN_BRCR0 (DCRN_EBIMC_BASE + 0x10) /* BRC 0 */ +#define DCRN_BRCR1 (DCRN_EBIMC_BASE + 0x11) /* BRC 1 */ +#define DCRN_BRCR2 (DCRN_EBIMC_BASE + 0x12) /* BRC 2 */ +#define DCRN_BRCR3 (DCRN_EBIMC_BASE + 0x13) /* BRC 3 */ +#define DCRN_BRCR4 (DCRN_EBIMC_BASE + 0x14) /* BRC 4 */ +#define DCRN_BRCR5 (DCRN_EBIMC_BASE + 0x15) /* BRC 5 */ +#define DCRN_BRCR6 (DCRN_EBIMC_BASE + 0x16) /* BRC 6 */ +#define DCRN_BRCR7 (DCRN_EBIMC_BASE + 0x17) /* BRC 7 */ +#define DCRN_BEAR0 (DCRN_EBIMC_BASE + 0x20) /* Bus Error Address Register */ +#define DCRN_BESR0 (DCRN_EBIMC_BASE + 0x21) /* Bus Error Status Register */ +#define DCRN_BIUCR (DCRN_EBIMC_BASE + 0x2A) /* Bus Interfac Unit Ctrl Reg */ +#endif + +#ifdef DCRN_SCCR_BASE +#define DCRN_SCCR (DCRN_SCCR_BASE + 0x0) +#endif + +#ifdef DCRN_SDRAM0_BASE +#define DCRN_SDRAM0_CFGADDR (DCRN_SDRAM0_BASE + 0x0) /* Memory Controller Address */ +#define DCRN_SDRAM0_CFGDATA (DCRN_SDRAM0_BASE + 0x1) /* Memory Controller Data */ +#endif + +#ifdef DCRN_OCM0_BASE +#define DCRN_OCMISARC (DCRN_OCM0_BASE + 0x0) /* OCM Instr Side Addr Range Compare */ +#define DCRN_OCMISCR (DCRN_OCM0_BASE + 0x1) /* OCM Instr Side Control */ +#define DCRN_OCMDSARC (DCRN_OCM0_BASE + 0x2) /* OCM Data Side Addr Range Compare */ +#define DCRN_OCMDSCR (DCRN_OCM0_BASE + 0x3) /* OCM Data Side Control */ +#endif + +#include <platforms/ibm405.h> + +#endif /* __ASM_IBMSTBX_H__ */ +#endif /* __KERNEL__ */ diff --git a/arch/ppc/platforms/ibmstb4.c b/arch/ppc/platforms/ibmstb4.c new file mode 100644 index 000000000000..ffa6d909bf23 --- /dev/null +++ b/arch/ppc/platforms/ibmstb4.c @@ -0,0 +1,61 @@ +/* + * + * Copyright 2000-2001 MontaVista Software Inc. + * Completed implementation. + * Current maintainer + * Armin Kuster akuster@mvista.com + * + * Module name: ibmstb4.c + * + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + * History: 12/26/2001 - armin + * initial release + * + */ + +#include <linux/config.h> +#include <platforms/ibmstb4.h> + +const struct NS16550* COM_PORTS[] = +{ + (struct NS16550*) UART0_IO_BASE, + (struct NS16550*) UART1_IO_BASE, + (struct NS16550*) UART2_IO_BASE, +}; + +const struct iic_regs* IIC_ADDR[]= +{ + (struct iic_regs*) IIC0_BASE, +}; + + +const struct gpio_regs* GPIO_ADDR[] = +{ + (struct gpio_regs*) GPIO0_BASE, +}; + +const struct ide_regs* IDE_ADDR[] = +{ + (struct ide_regs*) IDE0_IO_ADDR, + +}; diff --git a/arch/ppc/platforms/ibmstb4.h b/arch/ppc/platforms/ibmstb4.h new file mode 100644 index 000000000000..35779b6ed6a7 --- /dev/null +++ b/arch/ppc/platforms/ibmstb4.h @@ -0,0 +1,268 @@ +/* + * ibmstb4.h + * + * This was dirived from the ibm405gp.h and other previus works in ppc4xx.h + * + * Current maintainer + * Armin Kuster akuster@mvista.com + * DEC, 2001 + * + * + * Copyright 2001 MontaVista Softare Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Version 1.0 (01/10/10) - A. Kuster + * Initial version + * + * Version 1.1 02/01/17 - A. Kuster + * moved common offsets to ibm405.h + */ + +#ifdef __KERNEL__ +#ifndef __ASM_IBMSTB4_H__ +#define __ASM_IBMSTB4_H__ + +#include <linux/config.h> +#include <platforms/ibm_ocp.h> + +/* serial port defines */ +#define STB04xxx_IO_BASE ((uint)0xe0000000) +#define PPC4xx_PCI_IO_ADDR STB04xxx_IO_BASE +#define PPC4xx_ONB_IO_PADDR STB04xxx_IO_BASE +#define PPC4xx_ONB_IO_VADDR ((uint)0xe0000000) +#define PPC4xx_ONB_IO_SIZE ((uint)14*64*1024) + +/* + * map STB04xxx internal i/o address (0x400x00xx) to an address + * which is below the 2GB limit... + * + * 4000 000x uart1 -> 0xe000 000x + * 4001 00xx ppu + * 4002 00xx smart card + * 4003 000x iic + * 4004 000x uart0 + * 4005 0xxx timer + * 4006 00xx gpio + * 4007 00xx smart card + * 400b 000x iic + * 400c 000x scp + * 400d 000x modem + * 400e 000x uart2 +*/ +#define STB04xxx_MAP_IO_ADDR(a) (((uint)(a)) + (STB04xxx_IO_BASE - 0x40000000)) + +#define RS_TABLE_SIZE 3 +#define UART0_INT 20 +#define UART0_IO_BASE (u8 *)0x40040000 +#define UART1_INT 21 +#define UART1_IO_BASE (u8 *)0x40000000 +#define UART2_INT 31 +#define UART2_IO_BASE (u8 *)0x400e0000 + +#define IDE0_IO_ADDR 0x400F0000 +#define IDE0_IO_SIZE 0x200 + +#define IIC0_BASE 0x40030000 +#define IIC1_BASE 0x400b0000 +#define OPB0_BASE 0x40000000 +#define GPIO0_BASE 0x40060000 + +#define UART_NUMS 3 + +#define BD_EMAC_ADDR(e,i) bi_enetaddr[i] + +#define STD_UART_OP(num) \ + { 0, BASE_BAUD, 0, UART##num##_INT, \ + (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST), \ + iomem_base: UART##num##_IO_BASE, \ + io_type: SERIAL_IO_MEM}, + +#if defined(CONFIG_UART0_TTYS0) +#define SERIAL_PORT_DFNS \ + STD_UART_OP(0) \ + STD_UART_OP(1) \ + STD_UART_OP(2) +#endif + +#if defined(CONFIG_UART0_TTYS1) +#define SERIAL_PORT_DFNS \ + STD_UART_OP(1) \ + STD_UART_OP(0) \ + STD_UART_OP(2) +#endif + +#if defined(CONFIG_UART0_TTYS2) +#define SERIAL_PORT_DFNS \ + STD_UART_OP(2) \ + STD_UART_OP(0) \ + STD_UART_OP(1) +#endif + +#define DCRN_BE_BASE 0x090 +#define DCRN_DMA0_BASE 0x0C0 +#define DCRN_DMA1_BASE 0x0C8 +#define DCRN_DMA2_BASE 0x0D0 +#define DCRN_DMA3_BASE 0x0D8 +#define DCRNCAP_DMA_CC 1 /* have DMA chained count capability */ +#define DCRN_DMASR_BASE 0x0E0 +#define DCRN_PLB0_BASE 0x054 +#define DCRN_PLB1_BASE 0x064 +#define DCRN_POB0_BASE 0x0B0 +#define DCRN_SCCR_BASE 0x120 +#define DCRN_UIC0_BASE 0x040 +#define DCRN_BE_BASE 0x090 +#define DCRN_DMA0_BASE 0x0C0 +#define DCRN_DMA1_BASE 0x0C8 +#define DCRN_DMA2_BASE 0x0D0 +#define DCRN_DMA3_BASE 0x0D8 +#define DCRN_CIC_BASE 0x030 +#define DCRN_DMASR_BASE 0x0E0 +#define DCRN_EBIMC_BASE 0x070 +#define DCRN_DCRX_BASE 0x020 +#define DCRN_CPMFR_BASE 0x102 +#define DCRN_SCCR_BASE 0x120 + +#define CPM_IIC0 0x80000000 /* IIC 0 interface */ +#define CPM_I1284 0x40000000 /* IEEE-1284 */ +#define CPM_IIC1 0x20000000 /* IIC 1 interface */ +#define CPM_CPU 0x10000000 /* PPC405B3 clock control */ +#define CPM_AUD 0x08000000 /* Audio Decoder */ +#define CPM_EBIU 0x04000000 /* External Bus Interface Unit */ +#define CPM_SDRAM1 0x02000000 /* SDRAM 1 memory controller */ +#define CPM_DMA 0x01000000 /* DMA controller */ +#define CPM_RES_1 0x00800000 /* reserved */ +#define CPM_RES_2 0x00400000 /* reserved */ +#define CPM_RES_3 0x00200000 /* reserved */ +#define CPM_UART1 0x00100000 /* Serial 1 / Infrared */ +#define CPM_UART0 0x00080000 /* Serial 0 / 16550 */ +#define CPM_DCRX 0x00040000 /* DCR Extension */ +#define CPM_SC0 0x00020000 /* Smart Card 0 */ +#define CPM_RES_4 0x00010000 /* reserved */ +#define CPM_SC1 0x00008000 /* Smart Card 1 */ +#define CPM_SDRAM0 0x00004000 /* SDRAM 0 memory controller */ +#define CPM_XPT54 0x00002000 /* Transport - 54 Mhz */ +#define CPM_CBS 0x00001000 /* Cross Bar Switch */ +#define CPM_GPT 0x00000800 /* GPTPWM */ +#define CPM_GPIO0 0x00000400 /* General Purpose IO 0 */ +#define CPM_DENC 0x00000200 /* Digital video Encoder */ +#define CPM_TMRCLK 0x00000100 /* CPU timers */ +#define CPM_XPT27 0x00000080 /* Transport - 27 Mhz */ +#define CPM_UIC 0x00000040 /* Universal Interrupt Controller */ +#define CPM_RES_5 0x00000020 /* reserved */ +#define CPM_MSI 0x00000010 /* Modem Serial Interface (SSP) */ +#define CPM_UART2 0x00000008 /* Serial Control Port */ +#define CPM_DSCR 0x00000004 /* Descrambler */ +#define CPM_VID2 0x00000002 /* Video Decoder clock domain 2 */ +#define CPM_RES_6 0x00000001 /* reserved */ + +/* 0x80000000 */ +#define UIC_XPORT 0x40000000 /* 1 Transport */ +#define UIC_AUDIO 0x20000000 /* 2 Audio Decoder */ +#define UIC_VIDEO 0x10000000 /* 3 Video Decoder */ +#define UIC_D0 0x08000000 /* 4 DMA Channel 0 */ +#define UIC_D1 0x04000000 /* 5 DMA Channel 1 */ +#define UIC_D2 0x02000000 /* 6 DMA Channel 2 */ +#define UIC_D3 0x01000000 /* 7 DMA Channel 3 */ +#define UIC_SC0 0x00800000 /* 8 SmartCard 0 Controller */ +#define UIC_IIC0 0x00400000 /* 9 IIC 0 */ +#define UIC_IIC1 0x00200000 /* 10 IIC 1 */ +#define UIC_PWM0 0x00100000 /* 11 GPT_PWM 0: Capture Timers */ +#define UIC_PWM1 0x00080000 /* 12 GPT_PWM 1: Compare Timers */ +#define UIC_SCP 0x00040000 /* 13 Serial Control Port */ +#define UIC_SSP 0x00020000 /* 14 Soft Modem/Synchronous Serial Port */ +#define UIC_PWM2 0x00010000 /* 15 GPT_PWM 2: Down Counters */ +#define UIC_SC1 0x00008000 /* 16 SmartCard 1 Controller */ +#define UIC_EIR7 0x00004000 /* 17 External IRQ 7 */ +#define UIC_EIR8 0x00002000 /* 18 External IRQ 8 */ +#define UIC_EIR9 0x00001000 /* 19 External IRQ 9 */ +#define UIC_U0 0x00000800 /* 20 UART0 */ +#define UIC_IR_RCV 0x00000400 /* 21 Serial 1 / Infrared UART Receive */ +#define UIC_IR_XMIT 0x00000200 /* 22 Serial 1 / Infrared UART Transmit */ +#define UIC_IEEE1284 0x00000100 /* 23 IEEE-1284 / PPU */ +#define UIC_DCRX 0x00000080 /* 24 DCRX */ +#define UIC_EIR0 0x00000040 /* 25 External IRQ 0 */ +#define UIC_EIR1 0x00000020 /* 26 External IRQ 1 */ +#define UIC_EIR2 0x00000010 /* 27 External IRQ 2 */ +#define UIC_EIR3 0x00000008 /* 28 External IRQ 3 */ +#define UIC_EIR4 0x00000004 /* 29 External IRQ 4 */ +#define UIC_EIR5 0x00000002 /* 30 External IRQ 5 */ +#define UIC_EIR6 0x00000001 /* 31 External IRQ 6 */ + +#define DCRN_BEAR (DCRN_BE_BASE + 0x0) /* Bus Error Address Register */ +#define DCRN_BESR (DCRN_BE_BASE + 0x1) /* Bus Error Syndrome Register */ +/* DCRN_BESR */ +#define BESR_DSES 0x80000000 /* Data-Side Error Status */ +#define BESR_DMES 0x40000000 /* DMA Error Status */ +#define BESR_RWS 0x20000000 /* Read/Write Status */ +#define BESR_ETMASK 0x1C000000 /* Error Type */ +#define ET_PROT 0 +#define ET_PARITY 1 +#define ET_NCFG 2 +#define ET_BUSERR 4 +#define ET_BUSTO 6 + +#define CHR1_CETE 0x00800000 /* CPU external timer enable */ +#define CHR1_PCIPW 0x00008000 /* PCI Int enable/Peripheral Write enable */ + +#define DCRN_CICCR (DCRN_CIC_BASE + 0x0) /* CIC Control Register */ +#define DCRN_DMAS1 (DCRN_CIC_BASE + 0x1) /* DMA Select1 Register */ +#define DCRN_DMAS2 (DCRN_CIC_BASE + 0x2) /* DMA Select2 Register */ +#define DCRN_CICVCR (DCRN_CIC_BASE + 0x3) /* CIC Video COntro Register */ +#define DCRN_CICSEL3 (DCRN_CIC_BASE + 0x5) /* CIC Select 3 Register */ +#define DCRN_SGPO (DCRN_CIC_BASE + 0x6) /* CIC GPIO Output Register */ +#define DCRN_SGPOD (DCRN_CIC_BASE + 0x7) /* CIC GPIO OD Register */ +#define DCRN_SGPTC (DCRN_CIC_BASE + 0x8) /* CIC GPIO Tristate Ctrl Reg */ +#define DCRN_SGPI (DCRN_CIC_BASE + 0x9) /* CIC GPIO Input Reg */ + +#define DCRN_DCRXICR (DCRN_DCRX_BASE + 0x0) /* Internal Control Register */ +#define DCRN_DCRXISR (DCRN_DCRX_BASE + 0x1) /* Internal Status Register */ +#define DCRN_DCRXECR (DCRN_DCRX_BASE + 0x2) /* External Control Register */ +#define DCRN_DCRXESR (DCRN_DCRX_BASE + 0x3) /* External Status Register */ +#define DCRN_DCRXTAR (DCRN_DCRX_BASE + 0x4) /* Target Address Register */ +#define DCRN_DCRXTDR (DCRN_DCRX_BASE + 0x5) /* Target Data Register */ +#define DCRN_DCRXIGR (DCRN_DCRX_BASE + 0x6) /* Interrupt Generation Register */ +#define DCRN_DCRXBCR (DCRN_DCRX_BASE + 0x7) /* Line Buffer Control Register */ + +#define DCRN_BRCRH0 (DCRN_EBIMC_BASE + 0x0) /* Bus Region Config High 0 */ +#define DCRN_BRCRH1 (DCRN_EBIMC_BASE + 0x1) /* Bus Region Config High 1 */ +#define DCRN_BRCRH2 (DCRN_EBIMC_BASE + 0x2) /* Bus Region Config High 2 */ +#define DCRN_BRCRH3 (DCRN_EBIMC_BASE + 0x3) /* Bus Region Config High 3 */ +#define DCRN_BRCRH4 (DCRN_EBIMC_BASE + 0x4) /* Bus Region Config High 4 */ +#define DCRN_BRCRH5 (DCRN_EBIMC_BASE + 0x5) /* Bus Region Config High 5 */ +#define DCRN_BRCRH6 (DCRN_EBIMC_BASE + 0x6) /* Bus Region Config High 6 */ +#define DCRN_BRCRH7 (DCRN_EBIMC_BASE + 0x7) /* Bus Region Config High 7 */ +#define DCRN_BRCR0 (DCRN_EBIMC_BASE + 0x10) /* BRC 0 */ +#define DCRN_BRCR1 (DCRN_EBIMC_BASE + 0x11) /* BRC 1 */ +#define DCRN_BRCR2 (DCRN_EBIMC_BASE + 0x12) /* BRC 2 */ +#define DCRN_BRCR3 (DCRN_EBIMC_BASE + 0x13) /* BRC 3 */ +#define DCRN_BRCR4 (DCRN_EBIMC_BASE + 0x14) /* BRC 4 */ +#define DCRN_BRCR5 (DCRN_EBIMC_BASE + 0x15) /* BRC 5 */ +#define DCRN_BRCR6 (DCRN_EBIMC_BASE + 0x16) /* BRC 6 */ +#define DCRN_BRCR7 (DCRN_EBIMC_BASE + 0x17) /* BRC 7 */ +#define DCRN_BEAR0 (DCRN_EBIMC_BASE + 0x20) /* Bus Error Address Register */ +#define DCRN_BESR0 (DCRN_EBIMC_BASE + 0x21) /* Bus Error Status Register */ +#define DCRN_BIUCR (DCRN_EBIMC_BASE + 0x2A) /* Bus Interfac Unit Ctrl Reg */ + +#include <platforms/ibm405.h> + +#endif /* __ASM_IBMSTB4_H__ */ +#endif /* __KERNEL__ */ diff --git a/arch/ppc/platforms/ip860.h b/arch/ppc/platforms/ip860.h new file mode 100644 index 000000000000..951216d497a3 --- /dev/null +++ b/arch/ppc/platforms/ip860.h @@ -0,0 +1,36 @@ +/* + * MicroSys IP860 VMEBus board specific definitions + * + * Copyright (c) 2000, 2001 Wolfgang Denk (wd@denx.de) + */ + +#ifndef __MACH_IP860_H +#define __MACH_IP860_H + +#include <linux/config.h> + +#include <asm/ppcboot.h> + +#define IP860_IMMR_BASE 0xF1000000 /* phys. addr of IMMR */ +#define IP860_IMAP_SIZE (64 * 1024) /* size of mapped area */ + +#define IMAP_ADDR IP860_IMMR_BASE /* physical base address of IMMR area */ +#define IMAP_SIZE IP860_IMAP_SIZE /* mapped size of IMMR area */ + +/* + * MPC8xx Chip Select Usage + */ +#define IP860_BOOT_CS 0 /* Boot (VMEBus or Flash) Chip Select 0 */ +#define IP860_FLASH_CS 1 /* Flash is on Chip Select 1 */ +#define IP860_SDRAM_CS 2 /* SDRAM is on Chip Select 2 */ +#define IP860_SRAM_CS 3 /* SRAM is on Chip Select 3 */ +#define IP860_BCSR_CS 4 /* BCSR is on Chip Select 4 */ +#define IP860_IP_CS 5 /* IP Slots are on Chip Select 5 */ +#define IP860_VME_STD_CS 6 /* VME Standard I/O is on Chip Select 6 */ +#define IP860_VME_SHORT_CS 7 /* VME Short I/O is on Chip Select 7 */ + +/* We don't use the 8259. +*/ +#define NR_8259_INTS 0 + +#endif /* __MACH_IP860_H */ diff --git a/include/asm-ppc/ivms8.h b/arch/ppc/platforms/ivms8.h index 37c48cbc1c38..37c48cbc1c38 100644 --- a/include/asm-ppc/ivms8.h +++ b/arch/ppc/platforms/ivms8.h diff --git a/arch/ppc/platforms/k2.h b/arch/ppc/platforms/k2.h new file mode 100644 index 000000000000..d3b40c3355ec --- /dev/null +++ b/arch/ppc/platforms/k2.h @@ -0,0 +1,84 @@ +/* + * arch/ppc/platforms/k2.h + * + * Definitions for SBS K2 board support + * + * Author: Matt Porter <mporter@mvista.com> + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#ifndef __PPC_PLATFORMS_K2_H +#define __PPC_PLATFORMS_K2_H + +/* + * SBS K2 definitions + */ + +#define K2_PCI64_BAR 0xff400000 +#define K2_PCI32_BAR 0xff500000 + +#define K2_PCI64_CONFIG_ADDR (K2_PCI64_BAR + 0x000f8000) +#define K2_PCI64_CONFIG_DATA (K2_PCI64_BAR + 0x000f8010) + +#define K2_PCI32_CONFIG_ADDR (K2_PCI32_BAR + 0x000f8000) +#define K2_PCI32_CONFIG_DATA (K2_PCI32_BAR + 0x000f8010) + +#define K2_PCI64_MEM_BASE 0xd0000000 +#define K2_PCI64_IO_BASE 0x80100000 + +#define K2_PCI32_MEM_BASE 0xc0000000 +#define K2_PCI32_IO_BASE 0x80000000 + +#define K2_PCI32_SYS_MEM_BASE 0x80000000 +#define K2_PCI64_SYS_MEM_BASE K2_PCI32_SYS_MEM_BASE + +#define K2_PCI32_LOWER_MEM 0x00000000 +#define K2_PCI32_UPPER_MEM 0x0fffffff +#define K2_PCI32_LOWER_IO 0x00000000 +#define K2_PCI32_UPPER_IO 0x000fffff + +#define K2_PCI64_LOWER_MEM 0x10000000 +#define K2_PCI64_UPPER_MEM 0x1fffffff +#define K2_PCI64_LOWER_IO 0x00100000 +#define K2_PCI64_UPPER_IO 0x001fffff + +#define K2_ISA_IO_BASE K2_PCI32_IO_BASE +#define K2_ISA_MEM_BASE K2_PCI32_MEM_BASE + +#define K2_BOARD_ID_REG (K2_ISA_IO_BASE + 0x800) +#define K2_MISC_REG (K2_ISA_IO_BASE + 0x804) +#define K2_MSIZ_GEO_REG (K2_ISA_IO_BASE + 0x808) +#define K2_HOT_SWAP_REG (K2_ISA_IO_BASE + 0x80c) +#define K2_PLD2_REG (K2_ISA_IO_BASE + 0x80e) +#define K2_PLD3_REG (K2_ISA_IO_BASE + 0x80f) + +#define K2_BUS_SPD(board_id) (board_id >> 2) & 3 + +#define K2_RTC_BASE_OFFSET 0x90000 +#define K2_RTC_BASE_ADDRESS (K2_PCI32_MEM_BASE + K2_RTC_BASE_OFFSET) +#define K2_RTC_SIZE 0x8000 + +#define K2_MEM_SIZE_MASK 0xe0 +#define K2_MEM_SIZE(size_reg) (size_reg & K2_MEM_SIZE_MASK) >> 5 +#define K2_MEM_SIZE_1GB 0x40000000 +#define K2_MEM_SIZE_512MB 0x20000000 +#define K2_MEM_SIZE_256MB 0x10000000 +#define K2_MEM_SIZE_128MB 0x08000000 + +#define K2_L2CACHE_MASK 0x03 /* Mask for 2 L2 Cache bits */ +#define K2_L2CACHE_512KB 0x00 /* 512KB */ +#define K2_L2CACHE_256KB 0x01 /* 256KB */ +#define K2_L2CACHE_1MB 0x02 /* 1MB */ +#define K2_L2CACHE_NONE 0x03 /* None */ + +#define K2_GEO_ADR_MASK 0x1f + +#define K2_SYS_SLOT_MASK 0x08 + +#endif /* __PPC_PLATFORMS_K2_H */ diff --git a/arch/ppc/platforms/k2_pci.c b/arch/ppc/platforms/k2_pci.c new file mode 100644 index 000000000000..7f2b13cf87e9 --- /dev/null +++ b/arch/ppc/platforms/k2_pci.c @@ -0,0 +1,365 @@ +/* + * arch/ppc/platforms/k2_pci.c + * + * PCI support for SBS K2 + * + * Author: Matt Porter <mporter@mvista.com> + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/pci.h> +#include <linux/slab.h> + +#include <asm/byteorder.h> +#include <asm/io.h> +#include <asm/uaccess.h> +#include <asm/machdep.h> +#include <asm/pci-bridge.h> + +#include "cpc710.h" +#include "k2.h" + +#undef DEBUG +#ifdef DEBUG +#define DBG(x...) printk(x) +#else +#define DBG(x...) +#endif /* DEBUG */ + +static inline int __init +k2_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) +{ + struct pci_controller *hose = pci_bus_to_hose(dev->bus->number); + /* + * Check our hose index. If we are zero then we are on the + * local PCI hose, otherwise we are on the cPCI hose. + */ + if (!hose->index) + { + static char pci_irq_table[][4] = + /* + * PCI IDSEL/INTPIN->INTLINE + * A B C D + */ + { + {1, 0, 0, 0}, /* Ethernet */ + {5, 5, 5, 5}, /* PMC Site 1 */ + {6, 6, 6, 6}, /* PMC Site 2 */ + {0, 0, 0, 0}, /* unused */ + {0, 0, 0, 0}, /* unused */ + {0, 0, 0, 0}, /* PCI-ISA Bridge */ + {0, 0, 0, 0}, /* unused */ + {0, 0, 0, 0}, /* unused */ + {0, 0, 0, 0}, /* unused */ + {0, 0, 0, 0}, /* unused */ + {0, 0, 0, 0}, /* unused */ + {0, 0, 0, 0}, /* unused */ + {0, 0, 0, 0}, /* unused */ + {0, 0, 0, 0}, /* unused */ + {15, 0, 0, 0}, /* M5229 IDE */ + }; + const long min_idsel = 3, max_idsel = 17, irqs_per_slot = 4; + return PCI_IRQ_TABLE_LOOKUP; + } + else + { + static char pci_irq_table[][4] = + /* + * PCI IDSEL/INTPIN->INTLINE + * A B C D + */ + { + {10, 11, 12, 9}, /* cPCI slot 8 */ + {11, 12, 9, 10}, /* cPCI slot 7 */ + {12, 9, 10, 11}, /* cPCI slot 6 */ + {9, 10, 11, 12}, /* cPCI slot 5 */ + {10, 11, 12, 9}, /* cPCI slot 4 */ + {11, 12, 9, 10}, /* cPCI slot 3 */ + {12, 9, 10, 11}, /* cPCI slot 2 */ + }; + const long min_idsel = 15, max_idsel = 21, irqs_per_slot = 4; + return PCI_IRQ_TABLE_LOOKUP; + } +} + +void k2_pcibios_fixup(void) +{ +#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) + struct pci_dev *ide_dev; + + /* + * Enable DMA support on hdc + */ + ide_dev = pci_find_device(PCI_VENDOR_ID_AL, + PCI_DEVICE_ID_AL_M5229, + NULL); + + if (ide_dev) { + + unsigned long ide_dma_base; + + ide_dma_base = pci_resource_start(ide_dev, 4); + outb(0x00, ide_dma_base+0x2); + outb(0x20, ide_dma_base+0xa); + } +#endif +} + +void k2_pcibios_fixup_resources(struct pci_dev *dev) +{ + int i; + + if ((dev->vendor == PCI_VENDOR_ID_IBM) && + (dev->device == PCI_DEVICE_ID_IBM_CPC710_PCI64)) + { + DBG("Fixup CPC710 resources\n"); + for (i=0; i<DEVICE_COUNT_RESOURCE; i++) + { + dev->resource[i].start = 0; + dev->resource[i].end = 0; + } + } +} + +void k2_setup_hoses(void) +{ + struct pci_controller *hose_a, *hose_b; + + /* + * Reconfigure CPC710 memory map so + * we have some more PCI memory space. + */ + + /* Set FPHB mode */ + __raw_writel(0x808000e0, PGCHP); /* Set FPHB mode */ + + /* PCI32 mappings */ + __raw_writel(0x00000000, K2_PCI32_BAR+PIBAR); /* PCI I/O base */ + __raw_writel(0x00000000, K2_PCI32_BAR+PMBAR); /* PCI Mem base */ + __raw_writel(0xf0000000, K2_PCI32_BAR+MSIZE); /* 256MB */ + __raw_writel(0xfff00000, K2_PCI32_BAR+IOSIZE); /* 1MB */ + __raw_writel(0xc0000000, K2_PCI32_BAR+SMBAR); /* Base@0xc0000000 */ + __raw_writel(0x80000000, K2_PCI32_BAR+SIBAR); /* Base@0x80000000 */ + __raw_writel(0x000000c0, K2_PCI32_BAR+PSSIZE); /* 1GB space */ + __raw_writel(0x000000c0, K2_PCI32_BAR+PPSIZE); /* 1GB space */ + __raw_writel(0x00000000, K2_PCI32_BAR+BARPS); /* Base@0x00000000 */ + __raw_writel(0x00000000, K2_PCI32_BAR+BARPP); /* Base@0x00000000 */ + __raw_writel(0x00000080, K2_PCI32_BAR+PSBAR); /* Base@0x80 */ + __raw_writel(0x00000000, K2_PCI32_BAR+PPBAR); + + /* PCI64 mappings */ + __raw_writel(0x00100000, K2_PCI64_BAR+PIBAR); /* PCI I/O base */ + __raw_writel(0x10000000, K2_PCI64_BAR+PMBAR); /* PCI Mem base */ + __raw_writel(0xf0000000, K2_PCI64_BAR+MSIZE); /* 256MB */ + __raw_writel(0xfff00000, K2_PCI64_BAR+IOSIZE); /* 1MB */ + __raw_writel(0xd0000000, K2_PCI64_BAR+SMBAR); /* Base@0xd0000000 */ + __raw_writel(0x80100000, K2_PCI64_BAR+SIBAR); /* Base@0x80100000 */ + __raw_writel(0x000000c0, K2_PCI64_BAR+PSSIZE); /* 1GB space */ + __raw_writel(0x000000c0, K2_PCI64_BAR+PPSIZE); /* 1GB space */ + __raw_writel(0x00000000, K2_PCI64_BAR+BARPS); /* Base@0x00000000 */ + __raw_writel(0x00000000, K2_PCI64_BAR+BARPP); /* Base@0x00000000 */ + + /* Setup PCI32 hose */ + hose_a = pcibios_alloc_controller(); + if (!hose_a) + return; + + hose_a->first_busno = 0; + hose_a->last_busno = 0xff; + hose_a->pci_mem_offset = K2_PCI32_MEM_BASE; + + pci_init_resource(&hose_a->io_resource, + K2_PCI32_LOWER_IO, + K2_PCI32_UPPER_IO, + IORESOURCE_IO, + "PCI32 host bridge"); + + pci_init_resource(&hose_a->mem_resources[0], + K2_PCI32_LOWER_MEM + K2_PCI32_MEM_BASE, + K2_PCI32_UPPER_MEM + K2_PCI32_MEM_BASE, + IORESOURCE_MEM, + "PCI32 host bridge"); + + hose_a->io_space.start = K2_PCI32_LOWER_IO; + hose_a->io_space.end = K2_PCI32_UPPER_IO; + hose_a->mem_space.start = K2_PCI32_LOWER_MEM; + hose_a->mem_space.end = K2_PCI32_UPPER_MEM; + hose_a->io_base_virt = (void *)K2_ISA_IO_BASE; + + setup_indirect_pci(hose_a, K2_PCI32_CONFIG_ADDR, K2_PCI32_CONFIG_DATA); + + /* Initialize PCI32 bus registers */ + early_write_config_byte(hose_a, + hose_a->first_busno, + PCI_DEVFN(0, 0), + CPC710_BUS_NUMBER, + hose_a->first_busno); + + early_write_config_byte(hose_a, + hose_a->first_busno, + PCI_DEVFN(0, 0), + CPC710_SUB_BUS_NUMBER, + hose_a->last_busno); + + /* Enable PCI interrupt polling */ + early_write_config_byte(hose_a, + hose_a->first_busno, + PCI_DEVFN(8, 0), + 0x45, + 0x80); + + /* Route polled PCI interrupts */ + early_write_config_byte(hose_a, + hose_a->first_busno, + PCI_DEVFN(8, 0), + 0x48, + 0x58); + + early_write_config_byte(hose_a, + hose_a->first_busno, + PCI_DEVFN(8, 0), + 0x49, + 0x07); + + early_write_config_byte(hose_a, + hose_a->first_busno, + PCI_DEVFN(8, 0), + 0x4a, + 0x31); + + early_write_config_byte(hose_a, + hose_a->first_busno, + PCI_DEVFN(8, 0), + 0x4b, + 0xb9); + + /* route secondary IDE channel interrupt to IRQ 15 */ + early_write_config_byte(hose_a, + hose_a->first_busno, + PCI_DEVFN(8, 0), + 0x75, + 0x0f); + + /* enable IDE controller IDSEL */ + early_write_config_byte(hose_a, + hose_a->first_busno, + PCI_DEVFN(8, 0), + 0x58, + 0x48); + + /* Enable IDE function */ + early_write_config_byte(hose_a, + hose_a->first_busno, + PCI_DEVFN(17, 0), + 0x50, + 0x03); + + /* Set M5229 IDE controller to native mode */ + early_write_config_byte(hose_a, + hose_a->first_busno, + PCI_DEVFN(17, 0), + PCI_CLASS_PROG, + 0xdf); + + hose_a->last_busno = pciauto_bus_scan(hose_a, hose_a->first_busno); + + /* Write out correct max subordinate bus number for hose A */ + early_write_config_byte(hose_a, + hose_a->first_busno, + PCI_DEVFN(0, 0), + CPC710_SUB_BUS_NUMBER, + hose_a->last_busno); + + /* Only setup PCI64 hose if we are in the system slot */ + if (!(readb(K2_MISC_REG) & K2_SYS_SLOT_MASK)) + { + /* Setup PCI64 hose */ + hose_b = pcibios_alloc_controller(); + if (!hose_b) + return; + + hose_b->first_busno = hose_a->last_busno + 1; + hose_b->last_busno = 0xff; + + /* Reminder: quit changing the following, it is correct. */ + hose_b->pci_mem_offset = K2_PCI32_MEM_BASE; + + pci_init_resource(&hose_b->io_resource, + K2_PCI64_LOWER_IO, + K2_PCI64_UPPER_IO, + IORESOURCE_IO, + "PCI64 host bridge"); + + pci_init_resource(&hose_b->mem_resources[0], + K2_PCI64_LOWER_MEM + K2_PCI32_MEM_BASE, + K2_PCI64_UPPER_MEM + K2_PCI32_MEM_BASE, + IORESOURCE_MEM, + "PCI64 host bridge"); + + hose_b->io_space.start = K2_PCI64_LOWER_IO; + hose_b->io_space.end = K2_PCI64_UPPER_IO; + hose_b->mem_space.start = K2_PCI64_LOWER_MEM; + hose_b->mem_space.end = K2_PCI64_UPPER_MEM; + hose_b->io_base_virt = (void *)K2_ISA_IO_BASE; + + setup_indirect_pci(hose_b, + K2_PCI64_CONFIG_ADDR, + K2_PCI64_CONFIG_DATA); + + /* Initialize PCI64 bus registers */ + early_write_config_byte(hose_b, + 0, + PCI_DEVFN(0, 0), + CPC710_SUB_BUS_NUMBER, + 0xff); + + early_write_config_byte(hose_b, + 0, + PCI_DEVFN(0, 0), + CPC710_BUS_NUMBER, + hose_b->first_busno); + + hose_b->last_busno = pciauto_bus_scan(hose_b, + hose_b->first_busno); + + /* Write out correct max subordinate bus number for hose B */ + early_write_config_byte(hose_b, + hose_b->first_busno, + PCI_DEVFN(0, 0), + CPC710_SUB_BUS_NUMBER, + hose_b->last_busno); + + /* Configure PCI64 PSBAR */ + early_write_config_dword(hose_b, + hose_b->first_busno, + PCI_DEVFN(0, 0), + PCI_BASE_ADDRESS_0, + K2_PCI64_SYS_MEM_BASE); + } + + /* Configure i8259 level/edge settings */ + outb(0x62, 0x4d0); + outb(0xde, 0x4d1); + +#ifdef CONFIG_CPC710_DATA_GATHERING + { + unsigned int tmp; + tmp = __raw_readl(ABCNTL); + /* Enable data gathering on both PCI interfaces */ + __raw_writel(tmp | 0x05000000, ABCNTL); + } +#endif + + ppc_md.pcibios_fixup = k2_pcibios_fixup; + ppc_md.pcibios_fixup_resources = k2_pcibios_fixup_resources; + ppc_md.pci_swizzle = common_swizzle; + ppc_md.pci_map_irq = k2_map_irq; +} diff --git a/arch/ppc/platforms/k2_setup.c b/arch/ppc/platforms/k2_setup.c new file mode 100644 index 000000000000..3a03d0a8c25c --- /dev/null +++ b/arch/ppc/platforms/k2_setup.c @@ -0,0 +1,382 @@ +/* + * arch/ppc/platforms/k2_setup.c + * + * Board setup routines for SBS K2 + * + * Author: Matt Porter <mporter@mvista.com> + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include <linux/config.h> +#include <linux/stddef.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/errno.h> +#include <linux/reboot.h> +#include <linux/pci.h> +#include <linux/kdev_t.h> +#include <linux/types.h> +#include <linux/major.h> +#include <linux/blk.h> +#include <linux/console.h> +#include <linux/delay.h> +#include <linux/ide.h> +#include <linux/irq.h> +#include <linux/seq_file.h> + +#include <asm/system.h> +#include <asm/pgtable.h> +#include <asm/page.h> +#include <asm/dma.h> +#include <asm/io.h> +#include <asm/machdep.h> +#include <asm/time.h> +#include <asm/i8259.h> +#include <asm/todc.h> +#include <asm/bootinfo.h> + +#include "k2.h" + +extern void k2_setup_hoses(void); +extern unsigned long loops_per_jiffy; + +static unsigned int cpu_7xx[16] = { + 0, 15, 14, 0, 0, 13, 5, 9, 6, 11, 8, 10, 16, 12, 7, 0 +}; +static unsigned int cpu_6xx[16] = { + 0, 0, 14, 0, 0, 13, 5, 9, 6, 11, 8, 10, 0, 12, 7, 0 +}; + +#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) +/* IDE functions */ +static int +k2_ide_check_region(ide_ioreg_t from, unsigned int extent) +{ + return check_region(from, extent); +} + +static void +k2_ide_request_region(ide_ioreg_t from, unsigned int extent, + const char *name) +{ + request_region(from, extent, name); +} + +static void +k2_ide_release_region(ide_ioreg_t from, unsigned int extent) +{ + release_region(from, extent); +} + +static void __init +k2_ide_init_hwif_ports (hw_regs_t *hw, ide_ioreg_t data_port, + ide_ioreg_t ctrl_port, int *irq) +{ + ide_ioreg_t reg = data_port; + int i = 8; + + for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) { + hw->io_ports[i] = reg; + reg += 1; + } + if (ctrl_port) + hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port; + else + hw->io_ports[IDE_CONTROL_OFFSET] = + hw->io_ports[IDE_DATA_OFFSET] + 0x206; + + if (irq != NULL) + *irq = 0; +} +#endif + +static int +k2_get_bus_speed(void) +{ + int bus_speed; + unsigned char board_id; + + board_id = *(unsigned char *)K2_BOARD_ID_REG; + + switch( K2_BUS_SPD(board_id) ) { + + case 0: + default: + bus_speed = 100000000; + break; + + case 1: + bus_speed = 83333333; + break; + + case 2: + bus_speed = 75000000; + break; + + case 3: + bus_speed = 66666666; + break; + } + return bus_speed; +} + +static int +k2_get_cpu_speed(void) +{ + unsigned long hid1; + int cpu_speed; + + hid1 = mfspr(HID1) >> 28; + + if ((mfspr(PVR) >> 16) == 8) + hid1 = cpu_7xx[hid1]; + else + hid1 = cpu_6xx[hid1]; + + cpu_speed = k2_get_bus_speed()*hid1/2; + return cpu_speed; +} + +static void __init +k2_calibrate_decr(void) +{ + int freq, divisor = 4; + + /* determine processor bus speed */ + freq = k2_get_bus_speed(); + tb_ticks_per_jiffy = freq / HZ / divisor; + tb_to_us = mulhwu_scale_factor(freq/divisor, 1000000); +} + +static int +k2_show_cpuinfo(struct seq_file *m) +{ + unsigned char k2_geo_bits, k2_system_slot; + + seq_printf(m, "vendor\t\t: SBS\n"); + seq_printf(m, "machine\t\t: K2\n"); + seq_printf(m, "cpu speed\t: %dMhz\n", k2_get_cpu_speed()/1000000); + seq_printf(m, "bus speed\t: %dMhz\n", k2_get_bus_speed()/1000000); + seq_printf(m, "memory type\t: SDRAM\n"); + + k2_geo_bits = readb(K2_MSIZ_GEO_REG) & K2_GEO_ADR_MASK; + k2_system_slot = !(readb(K2_MISC_REG) & K2_SYS_SLOT_MASK); + seq_printf(m, "backplane\t: %s slot board", + k2_system_slot ? "System" : "Non system"); + seq_printf(m, "with geographical address %x\n", k2_geo_bits); + + return 0; +} + +extern char cmd_line[]; + +TODC_ALLOC(); + +static void __init +k2_setup_arch(void) +{ + unsigned int cpu; + + /* Setup TODC access */ + TODC_INIT(TODC_TYPE_MK48T37, 0, 0, + ioremap(K2_RTC_BASE_ADDRESS, K2_RTC_SIZE), + 8); + + /* init to some ~sane value until calibrate_delay() runs */ + loops_per_jiffy = 50000000/HZ; + + /* Setup PCI host bridges */ + k2_setup_hoses(); + +#ifdef CONFIG_BLK_DEV_INITRD + if (initrd_start) + ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); /* /dev/ram */ + else +#endif +#ifdef CONFIG_ROOT_NFS + ROOT_DEV = to_kdev_t(0x00FF); /* /dev/nfs pseudo device */ +#else + ROOT_DEV = to_kdev_t(0x1601); /* /dev/hdc1 */ +#endif + +#ifdef CONFIG_DUMMY_CONSOLE + conswitchp = &dummy_con; +#endif + + /* Identify the system */ + printk("System Identification: SBS K2 - PowerPC 750 @ %d Mhz\n", k2_get_cpu_speed()/1000000); + printk("SBS K2 port (C) 2001 MontaVista Software, Inc. (source@mvista.com)\n"); + + /* Identify the CPU manufacturer */ + cpu = PVR_REV(mfspr(PVR)); + printk("CPU manufacturer: %s [rev=%04x]\n", (cpu & (1<<15)) ? "IBM" : + "Motorola", cpu); +} + +static void +k2_restart(char *cmd) +{ + __cli(); + /* SRR0 has system reset vector, SRR1 has default MSR value */ + /* rfi restores MSR from SRR1 and sets the PC to the SRR0 value */ + __asm__ __volatile__ + ("lis 3,0xfff0\n\t" + "ori 3,3,0x0100\n\t" + "mtspr 26,3\n\t" + "li 3,0\n\t" + "mtspr 27,3\n\t" + "rfi\n\t"); + for(;;); +} + +static void +k2_power_off(void) +{ + for(;;); +} + +static void +k2_halt(void) +{ + k2_restart(NULL); +} + +/* + * Set BAT 3 to map PCI32 I/O space. + */ +static __inline__ void +k2_set_bat(void) +{ + unsigned long bat3u, bat3l; + static int mapping_set = 0; + + if (!mapping_set) + { + __asm__ __volatile__ + ("lis %0,0x8000\n\t" + "ori %1,%0,0x002a\n\t" + "ori %0,%0,0x1ffe\n\t" + "mtspr 0x21e,%0\n\t" + "mtspr 0x21f,%1\n\t" + "isync\n\t" + "sync\n\t" + : "=r" (bat3u), "=r" (bat3l)); + + mapping_set = 1; + } + return; +} + +static unsigned long __init +k2_find_end_of_memory(void) +{ + unsigned long total; + unsigned char msize = 7; /* Default to 128MB */ + + k2_set_bat(); + + msize = K2_MEM_SIZE(readb(K2_MSIZ_GEO_REG)); + + switch (msize) + { + case 2: + /* + * This will break without a lowered + * KERNELBASE or CONFIG_HIGHMEM on. + * It seems non 1GB builds exist yet, + * though. + */ + total = K2_MEM_SIZE_1GB; + break; + case 3: + case 4: + total = K2_MEM_SIZE_512MB; + break; + case 5: + case 6: + total = K2_MEM_SIZE_256MB; + break; + case 7: + total = K2_MEM_SIZE_128MB; + break; + default: + printk("K2: Invalid memory size detected, defaulting to 128MB\n"); + total = K2_MEM_SIZE_128MB; + break; + } + return total; +} + +static void __init +k2_map_io(void) +{ + io_block_mapping(K2_PCI32_IO_BASE, + K2_PCI32_IO_BASE, + 0x00200000, + _PAGE_IO); + io_block_mapping(0xff000000, + 0xff000000, + 0x01000000, + _PAGE_IO); +} + +static void __init +k2_init_irq(void) +{ + int i; + + for ( i = 0 ; i < 16 ; i++ ) + irq_desc[i].handler = &i8259_pic; + + i8259_init(NULL); +} + +static int +k2_get_irq(struct pt_regs *regs) +{ + return i8259_poll(); +} + +void __init platform_init(unsigned long r3, unsigned long r4, + unsigned long r5, unsigned long r6, unsigned long r7) +{ + parse_bootinfo((struct bi_record *) (r3 + KERNELBASE)); + + isa_io_base = K2_ISA_IO_BASE; + isa_mem_base = K2_ISA_MEM_BASE; + pci_dram_offset = K2_PCI32_SYS_MEM_BASE; + + ppc_md.setup_arch = k2_setup_arch; + ppc_md.show_cpuinfo = k2_show_cpuinfo; + ppc_md.init_IRQ = k2_init_irq; + ppc_md.get_irq = k2_get_irq; + + ppc_md.find_end_of_memory = k2_find_end_of_memory; + ppc_md.setup_io_mappings = k2_map_io; + + ppc_md.restart = k2_restart; + ppc_md.power_off = k2_power_off; + ppc_md.halt = k2_halt; + + ppc_md.time_init = todc_time_init; + ppc_md.set_rtc_time = todc_set_rtc_time; + ppc_md.get_rtc_time = todc_get_rtc_time; + ppc_md.calibrate_decr = k2_calibrate_decr; + + ppc_md.nvram_read_val = todc_direct_read_val; + ppc_md.nvram_write_val = todc_direct_write_val; + +#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) + ppc_ide_md.ide_check_region = k2_ide_check_region; + ppc_ide_md.ide_request_region = k2_ide_request_region; + ppc_ide_md.ide_release_region = k2_ide_release_region; + ppc_ide_md.ide_init_hwif = k2_ide_init_hwif_ports; +#endif +} + diff --git a/arch/ppc/platforms/lantec.h b/arch/ppc/platforms/lantec.h new file mode 100644 index 000000000000..ef3869fdc570 --- /dev/null +++ b/arch/ppc/platforms/lantec.h @@ -0,0 +1,21 @@ +/* + * LANTEC board specific definitions + * + * Copyright (c) 2001 Wolfgang Denk (wd@denx.de) + */ + +#ifndef __MACH_LANTEC_H +#define __MACH_LANTEC_H + +#include <linux/config.h> + +#include <asm/ppcboot.h> + +#define IMAP_ADDR 0xFFF00000 /* physical base address of IMMR area */ +#define IMAP_SIZE (64 * 1024) /* mapped size of IMMR area */ + +/* We don't use the 8259. +*/ +#define NR_8259_INTS 0 + +#endif /* __MACH_LANTEC_H */ diff --git a/arch/ppc/platforms/lopec_pci.c b/arch/ppc/platforms/lopec_pci.c new file mode 100644 index 000000000000..d5f4903c9414 --- /dev/null +++ b/arch/ppc/platforms/lopec_pci.c @@ -0,0 +1,108 @@ +/* + * arch/ppc/platforms/lopec_pci.c + * + * PCI setup routines for the Motorola LoPEC. + * + * Author: Dan Cox + * danc@mvista.com (or, alternately, source@mvista.com) + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/pci.h> +#include <linux/slab.h> + +#include <asm/machdep.h> +#include <asm/byteorder.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/uaccess.h> +#include <asm/pci-bridge.h> +#include <asm/open_pic.h> +#include <asm/mpc10x.h> + +static inline int __init +lopec_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) +{ + int irq; + static char pci_irq_table[][4] = { + {16, 0, 0, 0}, /* ID 11 - Winbond */ + {22, 0, 0, 0}, /* ID 12 - SCSI */ + {0, 0, 0, 0}, /* ID 13 - nothing */ + {17, 0, 0, 0}, /* ID 14 - 82559 Ethernet */ + {27, 0, 0, 0}, /* ID 15 - USB */ + {23, 0, 0, 0}, /* ID 16 - PMC slot 1 */ + {24, 0, 0, 0}, /* ID 17 - PMC slot 2 */ + {25, 0, 0, 0}, /* ID 18 - PCI slot */ + {0, 0, 0, 0}, /* ID 19 - nothing */ + {0, 0, 0, 0}, /* ID 20 - nothing */ + {0, 0, 0, 0}, /* ID 21 - nothing */ + {0, 0, 0, 0}, /* ID 22 - nothing */ + {0, 0, 0, 0}, /* ID 23 - nothing */ + {0, 0, 0, 0}, /* ID 24 - PMC slot 1b */ + {0, 0, 0, 0}, /* ID 25 - nothing */ + {0, 0, 0, 0} /* ID 26 - PMC Slot 2b */ + }; + const long min_idsel = 11, max_idsel = 26, irqs_per_slot = 4; + + irq = PCI_IRQ_TABLE_LOOKUP; + if (!irq) + return 0; + + return irq; +} + +void __init +lopec_setup_winbond_83553(struct pci_controller *hose) +{ + int devfn; + + devfn = PCI_DEVFN(11,0); + + /* IDE interrupt routing (primary 14, secondary 15) */ + early_write_config_byte(hose, 0, devfn, 0x43, 0xef); + /* PCI interrupt routing */ + early_write_config_word(hose, 0, devfn, 0x44, 0x0000); + + /* ISA-PCI address decoder */ + early_write_config_byte(hose, 0, devfn, 0x48, 0xf0); + + /* RTC, kb, not used in PPC */ + early_write_config_byte(hose, 0, devfn, 0x4d, 0x00); + early_write_config_byte(hose, 0, devfn, 0x4e, 0x04); + devfn = PCI_DEVFN(11, 1); + early_write_config_byte(hose, 0, devfn, 0x09, 0x8f); + early_write_config_dword(hose, 0, devfn, 0x40, 0x00ff0011); +} + +void __init +lopec_find_bridges(void) +{ + struct pci_controller *hose; + + hose = pcibios_alloc_controller(); + if (!hose) + return; + + hose->first_busno = 0; + hose->last_busno = 0xff; + + if (mpc10x_bridge_init(hose, + MPC10X_MEM_MAP_B, + MPC10X_MEM_MAP_B, + MPC10X_MAPB_EUMB_BASE) == 0) { + + hose->mem_resources[0].end = 0xffffffff; + lopec_setup_winbond_83553(hose); + hose->last_busno = pciauto_bus_scan(hose, hose->first_busno); + ppc_md.pci_swizzle = common_swizzle; + ppc_md.pci_map_irq = lopec_map_irq; + } +} diff --git a/arch/ppc/platforms/lopec_serial.h b/arch/ppc/platforms/lopec_serial.h new file mode 100644 index 000000000000..285ea3405ad5 --- /dev/null +++ b/arch/ppc/platforms/lopec_serial.h @@ -0,0 +1,41 @@ +/* + * include/asm-ppc/lopec_serial.h + * + * Definitions for Motorola LoPEC board. + * + * Author: Dan Cox + * danc@mvista.com (or, alternately, source@mvista.com) + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#ifndef __H_LOPEC_SERIAL +#define __H_LOPEC_SERIAL + +#define RS_TABLE_SIZE 3 + +#define BASE_BAUD (1843200 / 16) + +#ifdef CONFIG_SERIAL_DETECT_IRQ +#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF|ASYNC_SKIP_TEST|ASYNC_AUTO_IRQ) +#else +#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF|ASYNC_SKIP_TEST) +#endif + +#define SERIAL_PORT_DFNS \ + { 0, BASE_BAUD, 0xffe10000, 29, STD_COM_FLAGS, \ + iomem_base: (u8 *) 0xffe10000, \ + io_type: SERIAL_IO_MEM }, \ + { 0, BASE_BAUD, 0xffe11000, 20, STD_COM_FLAGS, \ + iomem_base: (u8 *) 0xffe11000, \ + io_type: SERIAL_IO_MEM }, \ + { 0, BASE_BAUD, 0xffe12000, 21, STD_COM_FLAGS, \ + iomem_base: (u8 *) 0xffe12000, \ + io_type: SERIAL_IO_MEM } + +#endif diff --git a/arch/ppc/platforms/lopec_setup.c b/arch/ppc/platforms/lopec_setup.c new file mode 100644 index 000000000000..848dc25d0b75 --- /dev/null +++ b/arch/ppc/platforms/lopec_setup.c @@ -0,0 +1,358 @@ +/* + * arch/ppc/platforms/lopec_setup.c + * + * Setup routines for the Motorola LoPEC. + * + * Author: Dan Cox + * danc@mvista.com + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include <linux/config.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/errno.h> +#include <linux/pci.h> +#include <linux/time.h> +#include <linux/types.h> +#include <linux/major.h> +#include <linux/kdev_t.h> +#include <linux/ide.h> +#include <linux/irq.h> +#include <linux/seq_file.h> +#include <linux/console.h> + +#include <asm/system.h> +#include <asm/pgtable.h> +#include <asm/machdep.h> +#include <asm/page.h> +#include <asm/dma.h> +#include <asm/io.h> +#include <asm/time.h> +#include <asm/delay.h> +#include <asm/irq.h> +#include <asm/open_pic.h> +#include <asm/i8259.h> +#include <asm/pci-bridge.h> +#include <asm/todc.h> +#include <asm/bootinfo.h> +#include <asm/mpc10x.h> + +#define LOPEC_SIO_IRQ 16 +#define LOPEC_SYSSTAT1 0xffe00000 + +extern void lopec_find_bridges(void); + +static u_char lopec_openpic_initsenses[32] __initdata = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1 +}; + + +static int +lopec_show_cpuinfo(struct seq_file *m) +{ + seq_printf(m, "machine\t\t: Motorola LoPec\n"); + return 0; +} + +static u32 +lopec_irq_cannonicalize(u32 irq) +{ + if (irq == 2) + return 9; + else + return irq; +} + +static void +lopec_restart(char *cmd) +{ + /* force a hard reset, if possible */ + unsigned char reg = *((unsigned char *) LOPEC_SYSSTAT1); + reg |= 0x80; + *((unsigned char *) LOPEC_SYSSTAT1) = reg; + + __cli(); + while(1); +} + +static void +lopec_halt(void) +{ + __cli(); + while(1); +} + +static void +lopec_power_off(void) +{ + lopec_halt(); +} + +static int +lopec_get_irq(struct pt_regs *regs) +{ + int irq, cascade_irq; + + irq = openpic_irq(); + + if (irq == LOPEC_SIO_IRQ) { + cascade_irq = i8259_poll(); + + if (cascade_irq != -1) { + irq = cascade_irq; + openpic_eoi(); + } + } + else if (irq == OPENPIC_VEC_SPURIOUS) + irq = -1; + + return irq; +} + +#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) +int lopec_ide_ports_known = 0; +static ide_ioreg_t lopec_ide_regbase[MAX_HWIFS]; +static ide_ioreg_t lopec_ide_ctl_regbase[MAX_HWIFS]; +static ide_ioreg_t lopec_idedma_regbase; + +static void +lopec_ide_probe(void) +{ + struct pci_dev *dev = pci_find_device(PCI_VENDOR_ID_WINBOND, + PCI_DEVICE_ID_WINBOND_82C105, + NULL); + lopec_ide_ports_known = 1; + + if (dev) { + lopec_ide_regbase[0] = dev->resource[0].start; + lopec_ide_regbase[1] = dev->resource[2].start; + lopec_ide_ctl_regbase[0] = dev->resource[1].start; + lopec_ide_ctl_regbase[1] = dev->resource[3].start; + lopec_idedma_regbase = dev->resource[4].start; + } +} + +static int +lopec_ide_default_irq(ide_ioreg_t base) +{ + if (lopec_ide_ports_known == 0) + lopec_ide_probe(); + + if (base == lopec_ide_regbase[0]) + return 14; + else if (base == lopec_ide_regbase[1]) + return 15; + else + return 0; +} + +static void +lopec_ide_request_region(ide_ioreg_t from, unsigned int to, + const char *name) +{ + request_region(from, to, name); +} + +static ide_ioreg_t +lopec_ide_default_io_base(int index) +{ + if (lopec_ide_ports_known == 0) + lopec_ide_probe(); + return lopec_ide_regbase[index]; +} + +static int +lopec_ide_check_region(ide_ioreg_t from, unsigned int to) +{ + return check_region(from, to); +} + +static void +lopec_ide_release_region(ide_ioreg_t from, unsigned int to) +{ + release_region(from, to); +} + + +static void __init +lopec_ide_init_hwif_ports(hw_regs_t *hw, ide_ioreg_t data, + ide_ioreg_t ctl, int *irq) +{ + ide_ioreg_t reg = data; + uint alt_status_base; + int i; + + for(i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) + hw->io_ports[i] = reg++; + + if (data == lopec_ide_regbase[0]) { + alt_status_base = lopec_ide_ctl_regbase[0] + 2; + hw->irq = 14; + } + else if (data == lopec_ide_regbase[1]) { + alt_status_base = lopec_ide_ctl_regbase[1] + 2; + hw->irq = 15; + } + else { + alt_status_base = 0; + hw->irq = 0; + } + + if (ctl) + hw->io_ports[IDE_CONTROL_OFFSET] = ctl; + else + hw->io_ports[IDE_CONTROL_OFFSET] = alt_status_base; + + if (irq != NULL) + *irq = hw->irq; + +} +#endif /* BLK_DEV_IDE */ + +static void __init +lopec_init_IRQ(void) +{ + int i; + + OpenPIC_InitSenses = lopec_openpic_initsenses; + OpenPIC_NumInitSenses = sizeof(lopec_openpic_initsenses); + openpic_init(1, 0, NULL, -1); + + for(i = 0; i < NUM_8259_INTERRUPTS; i++) + irq_desc[i].handler = &i8259_pic; + + if (request_irq(LOPEC_SIO_IRQ, no_action, SA_INTERRUPT, + "8259 cascade to EPIC", NULL)) { + printk("Unable to get EPIC %d for cascade.\n", + LOPEC_SIO_IRQ); + } + + i8259_init(NULL); +} + +static void __init +lopec_init2(void) +{ + outb(0x00, 0x4d0); + outb(0xc0, 0x4d1); + + request_region(0x00, 0x20, "dma1"); + request_region(0x20, 0x20, "pic1"); + request_region(0x40, 0x20, "timer"); + request_region(0x80, 0x10, "dma page reg"); + request_region(0xa0, 0x20, "pic2"); + request_region(0xc0, 0x20, "dma2"); +} + +static void __init +lopec_map_io(void) +{ + io_block_mapping(0xf0000000, 0xf0000000, 0x10000000, _PAGE_IO); + io_block_mapping(0xb0000000, 0xb0000000, 0x10000000, _PAGE_IO); +} + +static void __init +lopec_set_bat(void) +{ + unsigned long batu, batl; + + __asm__ __volatile__( + "lis %0,0xf800\n \ + ori %1,%0,0x002a\n \ + ori %0,%0,0x0ffe\n \ + mtspr 0x21e,%0\n \ + mtspr 0x21f,%1\n \ + isync\n \ + sync " + : "=r" (batu), "=r" (batl)); +} + +static unsigned long __init +lopec_find_end_of_memory(void) +{ + lopec_set_bat(); + return mpc10x_get_mem_size(MPC10X_MEM_MAP_B); +} + +TODC_ALLOC(); + +static void __init +lopec_setup_arch(void) +{ + + TODC_INIT(TODC_TYPE_MK48T37, 0, 0, + ioremap(0xffe80000, 0x8000), 8); + + loops_per_jiffy = 100000000/HZ; + + lopec_find_bridges(); + +#ifdef CONFIG_BLK_DEV_INITRD + if (initrd_start) + ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); + else +#elif defined(CONFIG_ROOT_NFS) + ROOT_DEV = to_kdev_t(0x00ff); +#elif defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_ID_MODULE) + ROOT_DEV = to_kdev_t(0x0301); +#else + ROOT_DEV = to_kdev_t(0x0801); +#endif + +#ifdef CONFIG_DUMMY_CONSOLE + conswitchp = &dummy_con; +#endif +} + +void __init +platform_init(unsigned long r3, unsigned long r4, unsigned long r5, + unsigned long r6, unsigned long r7) +{ + parse_bootinfo(find_bootinfo()); + + isa_io_base = MPC10X_MAPB_ISA_IO_BASE; + isa_mem_base = MPC10X_MAPB_ISA_MEM_BASE; + pci_dram_offset = MPC10X_MAPB_DRAM_OFFSET; + ISA_DMA_THRESHOLD = 0x00ffffff; + DMA_MODE_READ = 0x44; + DMA_MODE_WRITE = 0x48; + + ppc_md.setup_arch = lopec_setup_arch; + ppc_md.show_cpuinfo = lopec_show_cpuinfo; + ppc_md.irq_cannonicalize = lopec_irq_cannonicalize; + ppc_md.init_IRQ = lopec_init_IRQ; + ppc_md.get_irq = lopec_get_irq; + ppc_md.init = lopec_init2; + + ppc_md.restart = lopec_restart; + ppc_md.power_off = lopec_power_off; + ppc_md.halt = lopec_halt; + + ppc_md.find_end_of_memory = lopec_find_end_of_memory; + ppc_md.setup_io_mappings = lopec_map_io; + + ppc_md.time_init = todc_time_init; + ppc_md.set_rtc_time = todc_set_rtc_time; + ppc_md.get_rtc_time = todc_get_rtc_time; + ppc_md.calibrate_decr = todc_calibrate_decr; + + ppc_md.nvram_read_val = todc_direct_read_val; + ppc_md.nvram_write_val = todc_direct_write_val; + +#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_ID_MODULE) + ppc_ide_md.default_irq = lopec_ide_default_irq; + ppc_ide_md.default_io_base = lopec_ide_default_io_base; + ppc_ide_md.ide_request_region = lopec_ide_request_region; + ppc_ide_md.ide_check_region = lopec_ide_check_region; + ppc_ide_md.ide_release_region = lopec_ide_release_region; + ppc_ide_md.ide_init_hwif = lopec_ide_init_hwif_ports; +#endif +} diff --git a/arch/ppc/platforms/lwmon.h b/arch/ppc/platforms/lwmon.h new file mode 100644 index 000000000000..9306bf7dd832 --- /dev/null +++ b/arch/ppc/platforms/lwmon.h @@ -0,0 +1,60 @@ +/* + * Liebherr LWMON board specific definitions + * + * Copyright (c) 2001 Wolfgang Denk (wd@denx.de) + */ + +#ifndef __MACH_LWMON_H +#define __MACH_LWMON_H + +#include <linux/config.h> + +#include <asm/ppcboot.h> + +#define IMAP_ADDR 0xFFF00000 /* physical base address of IMMR area */ +#define IMAP_SIZE (64 * 1024) /* mapped size of IMMR area */ + +/*----------------------------------------------------------------------- + * PCMCIA stuff + *----------------------------------------------------------------------- + * + */ +#define PCMCIA_MEM_SIZE ( 64 << 20 ) + +#define MAX_HWIFS 1 /* overwrite default in include/asm-ppc/ide.h */ + +/* + * Definitions for IDE0 Interface + */ +#define IDE0_BASE_OFFSET 0 +#define IDE0_DATA_REG_OFFSET (PCMCIA_MEM_SIZE + 0x320) +#define IDE0_ERROR_REG_OFFSET (2 * PCMCIA_MEM_SIZE + 0x320 + 1) +#define IDE0_NSECTOR_REG_OFFSET (2 * PCMCIA_MEM_SIZE + 0x320 + 2) +#define IDE0_SECTOR_REG_OFFSET (2 * PCMCIA_MEM_SIZE + 0x320 + 3) +#define IDE0_LCYL_REG_OFFSET (2 * PCMCIA_MEM_SIZE + 0x320 + 4) +#define IDE0_HCYL_REG_OFFSET (2 * PCMCIA_MEM_SIZE + 0x320 + 5) +#define IDE0_SELECT_REG_OFFSET (2 * PCMCIA_MEM_SIZE + 0x320 + 6) +#define IDE0_STATUS_REG_OFFSET (2 * PCMCIA_MEM_SIZE + 0x320 + 7) +#define IDE0_CONTROL_REG_OFFSET 0x0106 +#define IDE0_IRQ_REG_OFFSET 0x000A /* not used */ + +#define IDE0_INTERRUPT 13 + +/* + * Definitions for I2C devices + */ +#define I2C_ADDR_AUDIO 0x28 /* Audio volume control */ +#define I2C_ADDR_SYSMON 0x2E /* LM87 System Monitor */ +#define I2C_ADDR_RTC 0x51 /* PCF8563 RTC */ +#define I2C_ADDR_POWER_A 0x52 /* PCMCIA/USB power switch, channel A */ +#define I2C_ADDR_POWER_B 0x53 /* PCMCIA/USB power switch, channel B */ +#define I2C_ADDR_KEYBD 0x56 /* PIC LWE keyboard */ +#define I2C_ADDR_PICIO 0x57 /* PIC IO Expander */ +#define I2C_ADDR_EEPROM 0x58 /* EEPROM AT24C164 */ + + +/* We don't use the 8259. +*/ +#define NR_8259_INTS 0 + +#endif /* __MACH_LWMON_H */ diff --git a/include/asm-ppc/mbx.h b/arch/ppc/platforms/mbx.h index e4896dd357f3..e4896dd357f3 100644 --- a/include/asm-ppc/mbx.h +++ b/arch/ppc/platforms/mbx.h diff --git a/arch/ppc/platforms/mcpn765.h b/arch/ppc/platforms/mcpn765.h new file mode 100644 index 000000000000..12fe0e9cfa32 --- /dev/null +++ b/arch/ppc/platforms/mcpn765.h @@ -0,0 +1,80 @@ +/* + * arch/ppc/platforms/mcpn765.h + * + * Definitions for Motorola MCG MCPN765 cPCI Board. + * + * Author: Mark A. Greer + * mgreer@mvista.com + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +/* + * From Processor to PCI: + * PCI Mem Space: 0x80000000 - 0xc0000000 -> 0x80000000 - 0xc0000000 (1 GB) + * PCI I/O Space: 0xfd800000 - 0xfe000000 -> 0x00000000 - 0x00800000 (8 MB) + * Note: Must skip 0xfe000000-0xfe400000 for CONFIG_HIGHMEM/PKMAP area + * MPIC in PCI Mem Space: 0xfe800000 - 0xfe830000 (not all used by MPIC) + * + * From PCI to Processor: + * System Memory: 0x00000000 -> 0x00000000 + */ + +#ifndef __PPC_PLATFORMS_MCPN765_H +#define __PPC_PLATFORMS_MCPN765_H + +/* PCI Memory space mapping info */ +#define MCPN765_PCI_MEM_SIZE 0x40000000U +#define MCPN765_PROC_PCI_MEM_START 0x80000000U +#define MCPN765_PROC_PCI_MEM_END (MCPN765_PROC_PCI_MEM_START + \ + MCPN765_PCI_MEM_SIZE - 1) +#define MCPN765_PCI_MEM_START 0x80000000U +#define MCPN765_PCI_MEM_END (MCPN765_PCI_MEM_START + \ + MCPN765_PCI_MEM_SIZE - 1) + +/* PCI I/O space mapping info */ +#define MCPN765_PCI_IO_SIZE 0x00800000U +#define MCPN765_PROC_PCI_IO_START 0xfd800000U +#define MCPN765_PROC_PCI_IO_END (MCPN765_PROC_PCI_IO_START + \ + MCPN765_PCI_IO_SIZE - 1) +#define MCPN765_PCI_IO_START 0x00000000U +#define MCPN765_PCI_IO_END (MCPN765_PCI_IO_START + \ + MCPN765_PCI_IO_SIZE - 1) + +/* System memory mapping info */ +#define MCPN765_PCI_DRAM_OFFSET 0x00000000U +#define MCPN765_PCI_PHY_MEM_OFFSET 0x00000000U + +#define MCPN765_ISA_MEM_BASE 0x00000000U +#define MCPN765_ISA_IO_BASE MCPN765_PROC_PCI_IO_START + +/* Define base addresses for important sets of registers */ +#define MCPN765_HAWK_MPIC_BASE 0xfe800000U +#define MCPN765_HAWK_SMC_BASE 0xfef80000U +#define MCPN765_HAWK_PPC_REG_BASE 0xfeff0000U + +/* Define MCPN765 board register addresses. */ +#define MCPN765_BOARD_STATUS_REG 0xfef88080U +#define MCPN765_BOARD_MODFAIL_REG 0xfef88090U +#define MCPN765_BOARD_MODRST_REG 0xfef880a0U +#define MCPN765_BOARD_TBEN_REG 0xfef880c0U +#define MCPN765_BOARD_GEOGRAPHICAL_REG 0xfef880e8U +#define MCPN765_BOARD_EXT_FEATURE_REG 0xfef880f0U +#define MCPN765_BOARD_LAST_RESET_REG 0xfef880f8U + +/* UART base addresses are defined in <asm-ppc/platforms/mcpn765_serial.h> */ + +/* Define the NVRAM/RTC address strobe & data registers */ +#define MCPN765_PHYS_NVRAM_AS0 0xfef880c8U +#define MCPN765_PHYS_NVRAM_AS1 0xfef880d0U +#define MCPN765_PHYS_NVRAM_DATA 0xfef880d8U + + +extern void mcpn765_find_bridges(void); + +#endif /* __PPC_PLATFORMS_MCPN765_H */ diff --git a/arch/ppc/platforms/mcpn765_pci.c b/arch/ppc/platforms/mcpn765_pci.c new file mode 100644 index 000000000000..be570bec173d --- /dev/null +++ b/arch/ppc/platforms/mcpn765_pci.c @@ -0,0 +1,109 @@ +/* + * arch/ppc/platforms/mcpn765_pci.c + * + * PCI setup routines for the Motorola MCG MCPN765 cPCI board. + * + * Author: Mark A. Greer + * mgreer@mvista.com + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/pci.h> +#include <linux/slab.h> + +#include <asm/byteorder.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/uaccess.h> +#include <asm/machdep.h> +#include <asm/pci-bridge.h> +#include <asm/pplus.h> + +#include "mcpn765.h" + + +/* + * Motorola MCG MCPN765 interrupt routing. + */ +static inline int +mcpn765_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) +{ + static char pci_irq_table[][4] = + /* + * PCI IDSEL/INTPIN->INTLINE + * A B C D + */ + { + { 14, 0, 0, 0 }, /* IDSEL 11 - have to manually set */ + { 0, 0, 0, 0 }, /* IDSEL 12 - unused */ + { 0, 0, 0, 0 }, /* IDSEL 13 - unused */ + { 18, 0, 0, 0 }, /* IDSEL 14 - Enet 0 */ + { 0, 0, 0, 0 }, /* IDSEL 15 - unused */ + { 25, 26, 27, 28 }, /* IDSEL 16 - PMC Slot 1 */ + { 28, 25, 26, 27 }, /* IDSEL 17 - PMC Slot 2 */ + { 0, 0, 0, 0 }, /* IDSEL 18 - PMC 2B Connector XXXX */ + { 29, 0, 0, 0 }, /* IDSEL 19 - Enet 1 */ + { 20, 0, 0, 0 }, /* IDSEL 20 - 21554 cPCI bridge */ + }; + + const long min_idsel = 11, max_idsel = 20, irqs_per_slot = 4; + return PCI_IRQ_TABLE_LOOKUP; +} + +void __init +mcpn765_find_bridges(void) +{ + struct pci_controller *hose; + + hose = pcibios_alloc_controller(); + + if (!hose) + return; + + hose->first_busno = 0; + hose->last_busno = 0xff; + hose->pci_mem_offset = MCPN765_PCI_PHY_MEM_OFFSET; + + pci_init_resource(&hose->io_resource, + MCPN765_PCI_IO_START, + MCPN765_PCI_IO_END, + IORESOURCE_IO, + "PCI host bridge"); + + pci_init_resource(&hose->mem_resources[0], + MCPN765_PCI_MEM_START, + MCPN765_PCI_MEM_END, + IORESOURCE_MEM, + "PCI host bridge"); + + hose->io_space.start = MCPN765_PCI_IO_START; + hose->io_space.end = MCPN765_PCI_IO_END; + hose->mem_space.start = MCPN765_PCI_MEM_START; + hose->mem_space.end = MCPN765_PCI_MEM_END - PPLUS_MPIC_SIZE; + + if (pplus_init(hose, + MCPN765_HAWK_PPC_REG_BASE, + MCPN765_PROC_PCI_MEM_START, + MCPN765_PROC_PCI_MEM_END - PPLUS_MPIC_SIZE, + MCPN765_PROC_PCI_IO_START, + MCPN765_PROC_PCI_IO_END, + MCPN765_PCI_MEM_END - PPLUS_MPIC_SIZE + 1) != 0) { + printk("Could not initialize HAWK bridge\n"); + } + + hose->last_busno = pciauto_bus_scan(hose, hose->first_busno); + + ppc_md.pcibios_fixup = NULL; + ppc_md.pcibios_fixup_bus = NULL; + ppc_md.pci_swizzle = common_swizzle; + ppc_md.pci_map_irq = mcpn765_map_irq; + + return; +} diff --git a/arch/ppc/platforms/mcpn765_serial.h b/arch/ppc/platforms/mcpn765_serial.h new file mode 100644 index 000000000000..5db8ce091b69 --- /dev/null +++ b/arch/ppc/platforms/mcpn765_serial.h @@ -0,0 +1,65 @@ +/* + * include/asm-ppc/mcpn765_serial.h + * + * Definitions for Motorola MCG MCPN765 cPCI board support + * + * Author: Mark A. Greer + * mgreer@mvista.com + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#ifndef __ASMPPC_MCPN765_SERIAL_H +#define __ASMPPC_MCPN765_SERIAL_H + +#include <linux/config.h> + +/* Define the UART base addresses */ +#define MCPN765_SERIAL_1 0xfef88000 +#define MCPN765_SERIAL_2 0xfef88200 +#define MCPN765_SERIAL_3 0xfef88400 +#define MCPN765_SERIAL_4 0xfef88600 + +#ifdef CONFIG_SERIAL_MANY_PORTS +#define RS_TABLE_SIZE 64 +#else +#define RS_TABLE_SIZE 4 +#endif + +/* Rate for the 1.8432 Mhz clock for the onboard serial chip */ +#define BASE_BAUD ( 1843200 / 16 ) + +#ifdef CONFIG_SERIAL_DETECT_IRQ +#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF|ASYNC_SKIP_TEST|ASYNC_AUTO_IRQ) +#else +#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF|ASYNC_SKIP_TEST) +#endif + +/* All UART IRQ's are wire-OR'd to IRQ 17 */ +#define STD_SERIAL_PORT_DFNS \ + { 0, BASE_BAUD, MCPN765_SERIAL_1, 17, STD_COM_FLAGS, /* ttyS0 */\ + iomem_base: (u8 *)MCPN765_SERIAL_1, \ + iomem_reg_shift: 4, \ + io_type: SERIAL_IO_MEM }, \ + { 0, BASE_BAUD, MCPN765_SERIAL_2, 17, STD_COM_FLAGS, /* ttyS1 */\ + iomem_base: (u8 *)MCPN765_SERIAL_2, \ + iomem_reg_shift: 4, \ + io_type: SERIAL_IO_MEM }, \ + { 0, BASE_BAUD, MCPN765_SERIAL_3, 17, STD_COM_FLAGS, /* ttyS2 */\ + iomem_base: (u8 *)MCPN765_SERIAL_3, \ + iomem_reg_shift: 4, \ + io_type: SERIAL_IO_MEM }, \ + { 0, BASE_BAUD, MCPN765_SERIAL_4, 17, STD_COM_FLAGS, /* ttyS3 */\ + iomem_base: (u8 *)MCPN765_SERIAL_4, \ + iomem_reg_shift: 4, \ + io_type: SERIAL_IO_MEM }, + +#define SERIAL_PORT_DFNS \ + STD_SERIAL_PORT_DFNS + +#endif /* __ASMPPC_MCPN765_SERIAL_H */ diff --git a/arch/ppc/platforms/mcpn765_setup.c b/arch/ppc/platforms/mcpn765_setup.c new file mode 100644 index 000000000000..64e542befb3b --- /dev/null +++ b/arch/ppc/platforms/mcpn765_setup.c @@ -0,0 +1,502 @@ +/* + * arch/ppc/platforms/mcpn765_setup.c + * + * Board setup routines for the Motorola MCG MCPN765 cPCI Board. + * + * Author: Mark A. Greer + * mgreer@mvista.com + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +/* + * This file adds support for the Motorola MCG MCPN765. + */ +#include <linux/config.h> +#include <linux/stddef.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/errno.h> +#include <linux/reboot.h> +#include <linux/pci.h> +#include <linux/kdev_t.h> +#include <linux/major.h> +#include <linux/blk.h> +#include <linux/console.h> +#include <linux/delay.h> +#include <linux/irq.h> +#include <linux/ide.h> +#include <linux/irq.h> +#include <linux/seq_file.h> + +#include <asm/system.h> +#include <asm/pgtable.h> +#include <asm/page.h> +#include <asm/time.h> +#include <asm/dma.h> +#include <asm/io.h> +#include <asm/machdep.h> +#include <asm/prom.h> +#include <asm/smp.h> +#include <asm/open_pic.h> +#include <asm/i8259.h> +#include <asm/todc.h> +#include <asm/pci-bridge.h> +#include <asm/bootinfo.h> +#include <asm/pplus.h> + +#include "mcpn765.h" + +static u_char mcpn765_openpic_initsenses[] __initdata = { + 0, /* 16: i8259 cascade (active high) */ + 1, /* 17: COM1,2,3,4 */ + 1, /* 18: Enet 1 (front panel) */ + 1, /* 19: HAWK WDT XXXX */ + 1, /* 20: 21554 PCI-PCI bridge */ + 1, /* 21: cPCI INTA# */ + 1, /* 22: cPCI INTB# */ + 1, /* 23: cPCI INTC# */ + 1, /* 24: cPCI INTD# */ + 1, /* 25: PMC1 INTA#, PMC2 INTB# */ + 1, /* 26: PMC1 INTB#, PMC2 INTC# */ + 1, /* 27: PMC1 INTC#, PMC2 INTD# */ + 1, /* 28: PMC1 INTD#, PMC2 INTA# */ + 1, /* 29: Enet 2 (connected to J3) */ + 1, /* 30: Abort Switch */ + 1, /* 31: RTC Alarm */ +}; + + +extern u_int openpic_irq(void); +extern char cmd_line[]; + +int use_of_interrupt_tree = 0; + +static void mcpn765_halt(void); + +TODC_ALLOC(); + +static void __init +mcpn765_setup_arch(void) +{ + struct pci_controller *hose; + + if ( ppc_md.progress ) + ppc_md.progress("mcpn765_setup_arch: enter", 0); + + loops_per_jiffy = 50000000 / HZ; + +#ifdef CONFIG_BLK_DEV_INITRD + if (initrd_start) + ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); + else +#endif +#ifdef CONFIG_ROOT_NFS + ROOT_DEV = to_kdev_t(0x00FF); /* /dev/nfs pseudo device */ +#else + ROOT_DEV = to_kdev_t(0x0802); /* /dev/sda2 SCSI disk */ +#endif + +#ifdef CONFIG_DUMMY_CONSOLE + conswitchp = &dummy_con; +#endif + + if ( ppc_md.progress ) + ppc_md.progress("mcpn765_setup_arch: find_bridges", 0); + + /* Lookup PCI host bridges */ + mcpn765_find_bridges(); + + hose = pci_bus_to_hose(0); + isa_io_base = (ulong)hose->io_base_virt; + + TODC_INIT(TODC_TYPE_MK48T37, + (MCPN765_PHYS_NVRAM_AS0 - isa_io_base), + (MCPN765_PHYS_NVRAM_AS1 - isa_io_base), + (MCPN765_PHYS_NVRAM_DATA - isa_io_base), + 8); + + OpenPIC_InitSenses = mcpn765_openpic_initsenses; + OpenPIC_NumInitSenses = sizeof(mcpn765_openpic_initsenses); + + printk("Motorola MCG MCPN765 cPCI Non-System Board\n"); + printk("MCPN765 port (C) 2001 MontaVista Software, Inc. (source@mvista.com)\n"); + + if ( ppc_md.progress ) + ppc_md.progress("mcpn765_setup_arch: exit", 0); + + return; +} + +/* + * Initialize the VIA 82c586b. + */ +static void __init +mcpn765_setup_via_82c586b(void) +{ + struct pci_dev *dev; + u_char c; + + if ((dev = pci_find_device(PCI_VENDOR_ID_VIA, + PCI_DEVICE_ID_VIA_82C586_1, + NULL)) == NULL) { + printk("No VIA ISA bridge found\n"); + mcpn765_halt(); + /* NOTREACHED */ + } + + /* + * PPCBug doesn't set the enable bits for the IDE device. + * Turn them on now. + */ + pcibios_read_config_byte(dev->bus->number, dev->devfn, 0x40, &c); + c |= 0x03; + pcibios_write_config_byte(dev->bus->number, dev->devfn, 0x40, c); + + return; +} + +static void __init +mcpn765_init2(void) +{ + /* Do MCPN765 board specific initialization. */ + mcpn765_setup_via_82c586b(); + + request_region(0x00,0x20,"dma1"); + request_region(0x20,0x20,"pic1"); + request_region(0x40,0x20,"timer"); + request_region(0x80,0x10,"dma page reg"); + request_region(0xa0,0x20,"pic2"); + request_region(0xc0,0x20,"dma2"); + + return; +} + +/* + * Interrupt setup and service. + * Have MPIC on HAWK and cascaded 8259s on VIA 82586 cascaded to MPIC. + */ +static void __init +mcpn765_init_IRQ(void) +{ + int i; + + if ( ppc_md.progress ) + ppc_md.progress("init_irq: enter", 0); + + openpic_init(1, NUM_8259_INTERRUPTS, NULL, -1); + + for(i=0; i < NUM_8259_INTERRUPTS; i++) + irq_desc[i].handler = &i8259_pic; + + i8259_init(NULL); + + if ( ppc_md.progress ) + ppc_md.progress("init_irq: exit", 0); + + return; +} + +static u32 +mcpn765_irq_cannonicalize(u32 irq) +{ + if (irq == 2) + return 9; + else + return irq; +} + +static unsigned long __init +mcpn765_find_end_of_memory(void) +{ + return pplus_get_mem_size(MCPN765_HAWK_SMC_BASE); +} + +static void __init +mcpn765_map_io(void) +{ + io_block_mapping(0xfe800000, 0xfe800000, 0x00800000, _PAGE_IO); +} + +static void +mcpn765_reset_board(void) +{ + __cli(); + + /* Set exception prefix high - to the firmware */ + _nmask_and_or_msr(0, MSR_IP); + + out_8((u_char *)MCPN765_BOARD_MODRST_REG, 0x01); + + return; +} + +static void +mcpn765_restart(char *cmd) +{ + volatile ulong i = 10000000; + + mcpn765_reset_board(); + + while (i-- > 0); + panic("restart failed\n"); +} + +static void +mcpn765_power_off(void) +{ + mcpn765_halt(); + /* NOTREACHED */ +} + +static void +mcpn765_halt(void) +{ + __cli(); + while (1); + /* NOTREACHED */ +} + +static int +mcpn765_show_cpuinfo(struct seq_file *m) +{ + seq_printf(m, "vendor\t\t: Motorola MCG\n"); + seq_printf(m, "machine\t\t: MCPN765\n"); + + return 0; +} + +#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) +/* + * IDE support. + */ +static int mcpn765_ide_ports_known = 0; +static ide_ioreg_t mcpn765_ide_regbase[MAX_HWIFS]; +static ide_ioreg_t mcpn765_ide_ctl_regbase[MAX_HWIFS]; +static ide_ioreg_t mcpn765_idedma_regbase; + +static void +mcpn765_ide_probe(void) +{ + struct pci_dev *pdev = pci_find_device(PCI_VENDOR_ID_VIA, + PCI_DEVICE_ID_VIA_82C586_1, + NULL); + + if(pdev) { + mcpn765_ide_regbase[0]=pdev->resource[0].start; + mcpn765_ide_regbase[1]=pdev->resource[2].start; + mcpn765_ide_ctl_regbase[0]=pdev->resource[1].start; + mcpn765_ide_ctl_regbase[1]=pdev->resource[3].start; + mcpn765_idedma_regbase=pdev->resource[4].start; + } + + mcpn765_ide_ports_known = 1; + return; +} + +static int +mcpn765_ide_default_irq(ide_ioreg_t base) +{ + if (mcpn765_ide_ports_known == 0) + mcpn765_ide_probe(); + + if (base == mcpn765_ide_regbase[0]) + return 14; + else if (base == mcpn765_ide_regbase[1]) + return 14; + else + return 0; +} + +static ide_ioreg_t +mcpn765_ide_default_io_base(int index) +{ + if (mcpn765_ide_ports_known == 0) + mcpn765_ide_probe(); + + return mcpn765_ide_regbase[index]; +} + +static int +mcpn765_ide_check_region(ide_ioreg_t from, unsigned int extent) +{ + return check_region(from, extent); +} + +static void +mcpn765_ide_request_region(ide_ioreg_t from, + unsigned int extent, + const char *name) +{ + request_region(from, extent, name); + return; +} + +static void +mcpn765_ide_release_region(ide_ioreg_t from, + unsigned int extent) +{ + release_region(from, extent); + return; +} + +static void __init +mcpn765_ide_init_hwif_ports(hw_regs_t *hw, ide_ioreg_t data_port, + ide_ioreg_t ctrl_port, int *irq) +{ + ide_ioreg_t reg = data_port; + uint alt_status_base; + int i; + + for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) { + hw->io_ports[i] = reg++; + } + + if (data_port == mcpn765_ide_regbase[0]) { + alt_status_base = mcpn765_ide_ctl_regbase[0] + 2; + hw->irq = 14; + } else if (data_port == mcpn765_ide_regbase[1]) { + alt_status_base = mcpn765_ide_ctl_regbase[1] + 2; + hw->irq = 14; + } else { + alt_status_base = 0; + hw->irq = 0; + } + + if (ctrl_port) + hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port; + else + hw->io_ports[IDE_CONTROL_OFFSET] = alt_status_base; + + if (irq != NULL) + *irq = hw->irq; + + return; +} +#endif + +/* + * Set BAT 3 to map 0xf0000000 to end of physical memory space. + */ +static __inline__ void +mcpn765_set_bat(void) +{ + unsigned long bat3u, bat3l; + static int mapping_set = 0; + + if (!mapping_set) { + + __asm__ __volatile__( + " lis %0,0xf000\n \ + ori %1,%0,0x002a\n \ + ori %0,%0,0x1ffe\n \ + mtspr 0x21e,%0\n \ + mtspr 0x21f,%1\n \ + isync\n \ + sync " + : "=r" (bat3u), "=r" (bat3l)); + + mapping_set = 1; + } + + return; +} + +#ifdef CONFIG_SERIAL_TEXT_DEBUG +#include <linux/serialP.h> +#include <linux/serial_reg.h> +#include <asm/serial.h> + +static struct serial_state rs_table[RS_TABLE_SIZE] = { + SERIAL_PORT_DFNS /* Defined in <asm/serial.h> */ +}; + +static void +mcpn765_progress(char *s, unsigned short hex) +{ + volatile char c; + volatile unsigned long com_port; + u16 shift; + + com_port = rs_table[0].port; + shift = rs_table[0].iomem_reg_shift; + + while ((c = *s++) != 0) { + while ((*((volatile unsigned char *)com_port + + (UART_LSR << shift)) & UART_LSR_THRE) == 0) + ; + *(volatile unsigned char *)com_port = c; + + if (c == '\n') { + while ((*((volatile unsigned char *)com_port + + (UART_LSR << shift)) & UART_LSR_THRE) == 0) + ; + *(volatile unsigned char *)com_port = '\r'; + } + } +} +#endif /* CONFIG_SERIAL_TEXT_DEBUG */ + +void __init +platform_init(unsigned long r3, unsigned long r4, unsigned long r5, + unsigned long r6, unsigned long r7) +{ + parse_bootinfo(find_bootinfo()); + + /* Map in board regs, etc. */ + mcpn765_set_bat(); + + isa_mem_base = MCPN765_ISA_MEM_BASE; + pci_dram_offset = MCPN765_PCI_DRAM_OFFSET; + ISA_DMA_THRESHOLD = 0x00ffffff; + DMA_MODE_READ = 0x44; + DMA_MODE_WRITE = 0x48; + + ppc_md.setup_arch = mcpn765_setup_arch; + ppc_md.show_cpuinfo = mcpn765_show_cpuinfo; + ppc_md.irq_cannonicalize = mcpn765_irq_cannonicalize; + ppc_md.init_IRQ = mcpn765_init_IRQ; + ppc_md.get_irq = openpic_get_irq; + ppc_md.init = mcpn765_init2; + + ppc_md.restart = mcpn765_restart; + ppc_md.power_off = mcpn765_power_off; + ppc_md.halt = mcpn765_halt; + + ppc_md.find_end_of_memory = mcpn765_find_end_of_memory; + ppc_md.setup_io_mappings = mcpn765_map_io; + + ppc_md.time_init = todc_time_init; + ppc_md.set_rtc_time = todc_set_rtc_time; + ppc_md.get_rtc_time = todc_get_rtc_time; + ppc_md.calibrate_decr = todc_calibrate_decr; + + ppc_md.nvram_read_val = todc_m48txx_read_val; + ppc_md.nvram_write_val = todc_m48txx_write_val; + + ppc_md.heartbeat = NULL; + ppc_md.heartbeat_reset = 0; + ppc_md.heartbeat_count = 0; + +#ifdef CONFIG_SERIAL_TEXT_DEBUG + ppc_md.progress = mcpn765_progress; +#else /* !CONFIG_SERIAL_TEXT_DEBUG */ + ppc_md.progress = NULL; +#endif /* CONFIG_SERIAL_TEXT_DEBUG */ + +#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) + ppc_ide_md.default_irq = mcpn765_ide_default_irq; + ppc_ide_md.default_io_base = mcpn765_ide_default_io_base; + ppc_ide_md.ide_check_region = mcpn765_ide_check_region; + ppc_ide_md.ide_request_region = mcpn765_ide_request_region; + ppc_ide_md.ide_release_region = mcpn765_ide_release_region; + ppc_ide_md.ide_init_hwif = mcpn765_ide_init_hwif_ports; +#endif + + return; +} diff --git a/arch/ppc/platforms/menf1.h b/arch/ppc/platforms/menf1.h new file mode 100644 index 000000000000..39406a7f3a28 --- /dev/null +++ b/arch/ppc/platforms/menf1.h @@ -0,0 +1,26 @@ +/* + * arch/ppc/platforms/menf1.h + * + * Definitions for MEN F1 board support + * + * Author: Matt Porter <mporter@mvista.com> + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#ifndef __PPC_PLATFORMS_MENF1_H +#define __PPC_PLATFORMS_MENF1_H + +#define MENF1_NVRAM_AS0 0x70 +#define MENF1_NVRAM_AS1 0x72 +#define MENF1_NVRAM_DATA 0x71 + +#define MENF1_IDE0_BASE_ADDR 0x1f0 +#define MENF1_IDE1_BASE_ADDR 0x170 + +#endif /* __PPC_PLATFORMS_MENF1_H */ diff --git a/arch/ppc/platforms/menf1_pci.c b/arch/ppc/platforms/menf1_pci.c new file mode 100644 index 000000000000..b0968eb37048 --- /dev/null +++ b/arch/ppc/platforms/menf1_pci.c @@ -0,0 +1,100 @@ +/* + * arch/ppc/platforms/menf1_pci.c + * + * PCI support for MEN F1 + * + * Author: Matt Porter <mporter@mvista.com> + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/pci.h> +#include <linux/slab.h> + +#include <asm/byteorder.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/uaccess.h> +#include <asm/machdep.h> +#include <asm/pci-bridge.h> +#include <asm/mpc10x.h> + +#include "menf1.h" + +#undef DEBUG +#ifdef DEBUG +#define DBG(x...) printk(x) +#else +#define DBG(x...) +#endif /* DEBUG */ + +static inline int __init +menf1_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) +{ + static char pci_irq_table[][4] = + /* + * PCI IDSEL/INTPIN->INTLINE + * A B C D + */ + { + {10, 11, 7, 9}, /* IDSEL 26 - PCMIP 0 */ + {0, 0, 0, 0}, /* IDSEL 27 - M5229 IDE */ + {0, 0, 0, 0}, /* IDSEL 28 - M7101 PMU */ + {9, 10, 11, 7}, /* IDSEL 29 - PCMIP 1 */ + {10, 11, 7, 9}, /* IDSEL 30 - P2P Bridge */ + }; + const long min_idsel = 26, max_idsel = 30, irqs_per_slot = 4; + return PCI_IRQ_TABLE_LOOKUP; +}; + +static int +menf1_exclude_device(u_char bus, u_char devfn) +{ + if ((bus == 0) && (devfn == 0xe0)) { + return PCIBIOS_DEVICE_NOT_FOUND; + } + else { + return PCIBIOS_SUCCESSFUL; + } +} + +void __init +menf1_find_bridges(void) +{ + struct pci_controller* hose; + + hose = pcibios_alloc_controller(); + if (!hose) + return; + + hose->first_busno = 0; + hose->last_busno = 0xff; + + ppc_md.pci_exclude_device = menf1_exclude_device; + + mpc10x_bridge_init(hose, + MPC10X_MEM_MAP_B, + MPC10X_MEM_MAP_B, + MPC10X_MAPB_EUMB_BASE); + + hose->last_busno = pciauto_bus_scan(hose, hose->first_busno); + + { + /* Add ISA bus wait states */ + unsigned char isa_control; + + early_read_config_byte(hose, 0, 0x90, 0x43, &isa_control); + isa_control |= 0x33; + early_write_config_byte(hose, 0, 0x90, 0x43, isa_control); + } + + ppc_md.pci_swizzle = common_swizzle; + ppc_md.pci_map_irq = menf1_map_irq; +} diff --git a/arch/ppc/platforms/menf1_setup.c b/arch/ppc/platforms/menf1_setup.c new file mode 100644 index 000000000000..298cd3d8af3d --- /dev/null +++ b/arch/ppc/platforms/menf1_setup.c @@ -0,0 +1,313 @@ +/* + * arch/ppc/platforms/menf1_setup.c + + * Board setup routines for MEN F1 + * + * Author: Matt Porter <mporter@mvista.com> + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include <linux/config.h> +#include <linux/stddef.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/errno.h> +#include <linux/reboot.h> +#include <linux/pci.h> +#include <linux/kdev_t.h> +#include <linux/types.h> +#include <linux/major.h> +#include <linux/blk.h> +#include <linux/console.h> +#include <linux/delay.h> +#include <linux/ide.h> +#include <linux/irq.h> +#include <linux/seq_file.h> + +#include <asm/system.h> +#include <asm/pgtable.h> +#include <asm/page.h> +#include <asm/dma.h> +#include <asm/io.h> +#include <asm/machdep.h> +#include <asm/time.h> +#include <asm/i8259.h> +#include <asm/mpc10x.h> +#include <asm/todc.h> +#include <asm/bootinfo.h> + +#include "menf1.h" + +extern void menf1_find_bridges(void); +extern unsigned long loops_per_jiffy; + +/* Dummy variable to satisfy mpc10x_common.o */ +void *OpenPIC_Addr; + +static int +menf1_show_cpuinfo(struct seq_file *m) +{ + seq_printf(m, "machine\t\t: MEN F1\n"); + + return 0; +} + +static void __init +menf1_setup_arch(void) +{ + /* init to some ~sane value until calibrate_delay() runs */ + loops_per_jiffy = 50000000/HZ; + + /* Lookup PCI host bridges */ + menf1_find_bridges(); + +#ifdef CONFIG_BLK_DEV_INITRD + if (initrd_start) + ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); + else +#endif +#ifdef CONFIG_ROOT_NFS + ROOT_DEV = to_kdev_t(0x00ff); /* /dev/nfs pseudo device */ +#else + ROOT_DEV = to_kdev_t(0x0302); /* /dev/hda2 */ +#endif + +#ifdef CONFIG_DUMMY_CONSOLE + conswitchp = &dummy_con; +#endif + + printk("MEN F1 port (C) 2001 MontaVista Software, Inc. (source@mvista.com)\n"); +} + +static void +menf1_restart(char *cmd) +{ + + int picr1; + struct pci_dev *pdev; + + __cli(); + + /* + * Firmware doesn't like re-entry using Map B (CHRP), so make sure the + * PCI bridge is using MAP A (PReP). + */ + + pdev = pci_find_slot(0, PCI_DEVFN(0,0)); + + while(pdev == NULL); /* paranoia */ + + pci_read_config_dword(pdev, MPC10X_CFG_PICR1_REG, &picr1); + + picr1 = (picr1 & ~MPC10X_CFG_PICR1_ADDR_MAP_MASK) | + MPC10X_CFG_PICR1_ADDR_MAP_A; + + pci_write_config_dword(pdev, MPC10X_CFG_PICR1_REG, picr1); + + asm volatile("sync"); + + /* SRR0 has system reset vector, SRR1 has default MSR value */ + /* rfi restores MSR from SRR1 and sets the PC to the SRR0 value */ + __asm__ __volatile__ + ("\n\ + lis 3,0xfff0 + ori 3,3,0x0100 + mtspr 26,3 + li 3,0 + mtspr 27,3 + rfi + "); + while(1); +} + +static void +menf1_halt(void) +{ + __cli(); + while (1); +} + +static void +menf1_power_off(void) +{ + menf1_halt(); +} + +static void __init +menf1_init_IRQ(void) +{ + int i; + + for ( i = 0 ; i < NUM_8259_INTERRUPTS ; i++ ) + irq_desc[i].handler = &i8259_pic; + i8259_init(NULL); +} + +static int menf1_get_irq(struct pt_regs *regs) +{ + return i8259_poll(); +} + +/* + * Set BAT 3 to map 0xF0000000. + */ +static __inline__ void +menf1_set_bat(void) +{ + static int mapping_set = 0; + + if (!mapping_set) + { + + /* wait for all outstanding memory accesses to complete */ + mb(); + + /* setup DBATs */ + mtspr(DBAT3U, 0xf0001ffe); + mtspr(DBAT3L, 0xf000002a); + + /* wait for updates */ + mb(); + + mapping_set = 1; + } + return; +} + +static unsigned long __init +menf1_find_end_of_memory(void) +{ + /* Cover the I/O with a BAT */ + menf1_set_bat(); + + /* Read the memory size from the MPC107 SMC */ + return mpc10x_get_mem_size(MPC10X_MEM_MAP_B); +} + +static void __init +menf1_map_io(void) +{ + io_block_mapping(0xfe000000, 0xfe000000, 0x02000000, _PAGE_IO); +} + +#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) +/* IDE functions */ + +static int +menf1_ide_check_region(ide_ioreg_t from, unsigned int extent) +{ + return check_region(from, extent); +} + +static void +menf1_ide_request_region(ide_ioreg_t from, + unsigned int extent, + const char *name) +{ + request_region(from, extent, name); +} + +static void +menf1_ide_release_region(ide_ioreg_t from, + unsigned int extent) +{ + release_region(from, extent); +} + +static void __init +menf1_ide_init_hwif_ports (hw_regs_t *hw, ide_ioreg_t data_port, + ide_ioreg_t ctrl_port, int *irq) +{ + ide_ioreg_t reg = data_port; + int i = 8; + + for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) { + hw->io_ports[i] = reg; + reg += 1; + } + if (ctrl_port) + hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port; + else + hw->io_ports[IDE_CONTROL_OFFSET] = + hw->io_ports[IDE_DATA_OFFSET] + 0x206; + + if (irq != NULL) + *irq = 0; +} + +static int +menf1_ide_default_irq(ide_ioreg_t base) +{ + if (base == MENF1_IDE0_BASE_ADDR) + return 14; + else if (base == MENF1_IDE1_BASE_ADDR) + return 15; + else + return 0; +} + +static ide_ioreg_t +menf1_ide_default_io_base(int index) +{ + if (index == 0) + return MENF1_IDE0_BASE_ADDR; + else if (index == 1) + return MENF1_IDE1_BASE_ADDR; + else + return 0; +} +#endif + +TODC_ALLOC(); + +void __init +platform_init(unsigned long r3, unsigned long r4, unsigned long r5, + unsigned long r6, unsigned long r7) +{ + parse_bootinfo(find_bootinfo()); + + isa_io_base = MPC10X_MAPB_ISA_IO_BASE; + isa_mem_base = MPC10X_MAPB_ISA_MEM_BASE; + pci_dram_offset = MPC10X_MAPB_DRAM_OFFSET; + + ppc_md.setup_arch = menf1_setup_arch; + ppc_md.show_cpuinfo = menf1_show_cpuinfo; + ppc_md.init_IRQ = menf1_init_IRQ; + ppc_md.get_irq = menf1_get_irq; + + ppc_md.find_end_of_memory = menf1_find_end_of_memory; + ppc_md.setup_io_mappings = menf1_map_io; + + ppc_md.restart = menf1_restart; + ppc_md.power_off = menf1_power_off; + ppc_md.halt = menf1_halt; + + TODC_INIT(TODC_TYPE_MK48T59, + MENF1_NVRAM_AS0, + MENF1_NVRAM_AS1, + MENF1_NVRAM_DATA, + 7); + + ppc_md.time_init = todc_time_init; + ppc_md.get_rtc_time = todc_get_rtc_time; + ppc_md.set_rtc_time = todc_set_rtc_time; + ppc_md.calibrate_decr = todc_calibrate_decr; + + ppc_md.nvram_read_val = todc_m48txx_read_val; + ppc_md.nvram_write_val = todc_m48txx_write_val; + +#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) + ppc_ide_md.default_io_base = menf1_ide_default_io_base; + ppc_ide_md.default_irq = menf1_ide_default_irq; + ppc_ide_md.ide_check_region = menf1_ide_check_region; + ppc_ide_md.ide_request_region = menf1_ide_request_region; + ppc_ide_md.ide_release_region = menf1_ide_release_region; + ppc_ide_md.ide_init_hwif = menf1_ide_init_hwif_ports; +#endif +} diff --git a/arch/ppc/platforms/mvme5100.h b/arch/ppc/platforms/mvme5100.h new file mode 100644 index 000000000000..0213d51edca6 --- /dev/null +++ b/arch/ppc/platforms/mvme5100.h @@ -0,0 +1,74 @@ +/* + * include/asm-ppc/platforms/mvme5100.h + * + * Definitions for Motorola MVME5100. + * + * Author: Matt Porter <mporter@mvista.com> + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#ifdef __KERNEL__ +#ifndef __ASM_MVME5100_H__ +#define __ASM_MVME5100_H__ + +#define MVME5100_HAWK_SMC_BASE 0xfef80000 + +#define MVME5100_PCI_CONFIG_ADDR 0xfe000cf8 +#define MVME5100_PCI_CONFIG_DATA 0xfe000cfc + +#define MVME5100_PCI_IO_BASE 0xfe000000 +#define MVME5100_PCI_MEM_BASE 0x80000000 + +#define MVME5100_PCI_MEM_OFFSET 0x00000000 + +#define MVME5100_PCI_DRAM_OFFSET 0x00000000 +#define MVME5100_ISA_MEM_BASE 0x00000000 +#define MVME5100_ISA_IO_BASE MVME5100_PCI_IO_BASE + +#define MVME5100_PCI_LOWER_MEM 0x80000000 +#define MVME5100_PCI_UPPER_MEM 0xf3f7ffff +#define MVME5100_PCI_LOWER_IO 0x00000000 +#define MVME5100_PCI_UPPER_IO 0x0077ffff + +/* MVME5100 board register addresses. */ +#define MVME5100_BOARD_STATUS_REG 0xfef88080 +#define MVME5100_BOARD_MODFAIL_REG 0xfef88090 +#define MVME5100_BOARD_MODRST_REG 0xfef880a0 +#define MVME5100_BOARD_TBEN_REG 0xfef880c0 +#define MVME5100_BOARD_SW_READ_REG 0xfef880e0 +#define MVME5100_BOARD_GEO_ADDR_REG 0xfef880e8 +#define MVME5100_BOARD_EXT_FEATURE1_REG 0xfef880f0 +#define MVME5100_BOARD_EXT_FEATURE2_REG 0xfef88100 + +/* Define the NVRAM/RTC address strobe & data registers */ +#define MVME5100_PHYS_NVRAM_AS0 0xfef880c8 +#define MVME5100_PHYS_NVRAM_AS1 0xfef880d0 +#define MVME5100_PHYS_NVRAM_DATA 0xfef880d8 + +#define MVME5100_NVRAM_AS0 (MVME5100_PHYS_NVRAM_AS0 - MVME5100_ISA_IO_BASE) +#define MVME5100_NVRAM_AS1 (MVME5100_PHYS_NVRAM_AS1 - MVME5100_ISA_IO_BASE) +#define MVME5100_NVRAM_DATA (MVME5100_PHYS_NVRAM_DATA - MVME5100_ISA_IO_BASE) + +/* UART clock, addresses, and irq */ +#define MVME5100_BASE_BAUD 1843200 +#define MVME5100_SERIAL_1 0xfef88000 +#define MVME5100_SERIAL_2 0xfef88200 +#ifdef CONFIG_MVME5100_IPMC761_PRESENT +#define MVME5100_SERIAL_IRQ 17 +#else +#define MVME5100_SERIAL_IRQ 1 +#endif + +#define MVME5100_WINBOND_DEVFN 0x58 +#define MVME5100_WINBOND_VIDDID 0x056510ad + +extern void mvme5100_setup_bridge(void); + +#endif /* __ASM_MVME5100_H__ */ +#endif /* __KERNEL__ */ diff --git a/arch/ppc/platforms/mvme5100_pci.c b/arch/ppc/platforms/mvme5100_pci.c new file mode 100644 index 000000000000..f44d49339769 --- /dev/null +++ b/arch/ppc/platforms/mvme5100_pci.c @@ -0,0 +1,123 @@ +/* + * arch/ppc/platforms/mvme5100_pci.c + * + * PCI setup routines for the Motorola MVME5100. + * + * Author: Matt Porter <mporter@mvista.com> + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/pci.h> +#include <linux/slab.h> + +#include <asm/byteorder.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/uaccess.h> +#include <asm/machdep.h> +#include <asm/pci-bridge.h> +#include <platforms/mvme5100.h> +#include <asm/pplus.h> + +static inline int +mvme5100_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) +{ + int irq; + + static char pci_irq_table[][4] = + /* + * PCI IDSEL/INTPIN->INTLINE + * A B C D + */ + { + { 0, 0, 0, 0 }, /* IDSEL 11 - Winbond */ + { 0, 0, 0, 0 }, /* IDSEL 12 - unused */ + { 21, 22, 23, 24 }, /* IDSEL 13 - Universe II */ + { 18, 0, 0, 0 }, /* IDSEL 14 - Enet 1 */ + { 0, 0, 0, 0 }, /* IDSEL 15 - unused */ + { 25, 26, 27, 28 }, /* IDSEL 16 - PMC Slot 1 */ + { 28, 25, 26, 27 }, /* IDSEL 17 - PMC Slot 2 */ + { 0, 0, 0, 0 }, /* IDSEL 18 - unused */ + { 29, 0, 0, 0 }, /* IDSEL 19 - Enet 2 */ + { 0, 0, 0, 0 }, /* IDSEL 20 - PMCSPAN */ + }; + + const long min_idsel = 11, max_idsel = 20, irqs_per_slot = 4; + irq = PCI_IRQ_TABLE_LOOKUP; + /* If lookup is zero, always return 0 */ + if (!irq) + return 0; + else +#ifdef CONFIG_MVME5100_IPMC761_PRESENT + /* If IPMC761 present, return table value */ + return irq; +#else + /* If IPMC761 not present, we don't have an i8259 so adjust */ + return (irq - NUM_8259_INTERRUPTS); +#endif +} + +static void +mvme5100_pcibios_fixup_resources(struct pci_dev *dev) +{ + int i; + + if ((dev->vendor == PCI_VENDOR_ID_MOTOROLA) && + (dev->device == PCI_DEVICE_ID_MOTOROLA_HAWK)) + for (i=0; i<DEVICE_COUNT_RESOURCE; i++) + { + dev->resource[i].start = 0; + dev->resource[i].end = 0; + } +} + +void __init +mvme5100_setup_bridge(void) +{ + struct pci_controller* hose; + + hose = pcibios_alloc_controller(); + + if (!hose) + return; + + hose->first_busno = 0; + hose->last_busno = 0xff; + hose->pci_mem_offset = MVME5100_PCI_MEM_OFFSET; + + pci_init_resource(&hose->io_resource, + MVME5100_PCI_LOWER_IO, + MVME5100_PCI_UPPER_IO, + IORESOURCE_IO, + "PCI host bridge"); + + pci_init_resource(&hose->mem_resources[0], + MVME5100_PCI_LOWER_MEM, + MVME5100_PCI_UPPER_MEM, + IORESOURCE_MEM, + "PCI host bridge"); + + hose->io_space.start = MVME5100_PCI_LOWER_IO; + hose->io_space.end = MVME5100_PCI_UPPER_IO; + hose->mem_space.start = MVME5100_PCI_LOWER_MEM; + hose->mem_space.end = MVME5100_PCI_UPPER_MEM; + hose->io_base_virt = (void *)MVME5100_ISA_IO_BASE; + + /* Use indirect method of Hawk */ + setup_indirect_pci(hose, + MVME5100_PCI_CONFIG_ADDR, + MVME5100_PCI_CONFIG_DATA); + + hose->last_busno = pciauto_bus_scan(hose, hose->first_busno); + + ppc_md.pcibios_fixup_resources = mvme5100_pcibios_fixup_resources; + ppc_md.pci_swizzle = common_swizzle; + ppc_md.pci_map_irq = mvme5100_map_irq; +} diff --git a/arch/ppc/platforms/mvme5100_serial.h b/arch/ppc/platforms/mvme5100_serial.h new file mode 100644 index 000000000000..d2ce5b43bdc8 --- /dev/null +++ b/arch/ppc/platforms/mvme5100_serial.h @@ -0,0 +1,56 @@ +/* + * include/asm-ppc/mvme5100_serial.h + * + * Definitions for Motorola MVME5100 support + * + * Author: Matt Porter <mporter@mvista.com> + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#ifdef __KERNEL__ +#ifndef __ASM_MVME5100_SERIAL_H__ +#define __ASM_MVME5100_SERIAL_H__ + +#include <linux/config.h> +#include <platforms/mvme5100.h> + +#ifdef CONFIG_SERIAL_MANY_PORTS +#define RS_TABLE_SIZE 64 +#else +#define RS_TABLE_SIZE 4 +#endif + +#define BASE_BAUD ( MVME5100_BASE_BAUD / 16 ) + +#ifdef CONFIG_SERIAL_DETECT_IRQ +#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF|ASYNC_SKIP_TEST|ASYNC_AUTO_IRQ) +#else +#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF|ASYNC_SKIP_TEST) +#endif + +/* All UART IRQ's are wire-OR'd to one MPIC IRQ */ +#define STD_SERIAL_PORT_DFNS \ + { 0, BASE_BAUD, MVME5100_SERIAL_1, \ + MVME5100_SERIAL_IRQ, \ + STD_COM_FLAGS, /* ttyS0 */ \ + iomem_base: (unsigned char *)MVME5100_SERIAL_1, \ + iomem_reg_shift: 4, \ + io_type: SERIAL_IO_MEM }, \ + { 0, BASE_BAUD, MVME5100_SERIAL_2, \ + MVME5100_SERIAL_IRQ, \ + STD_COM_FLAGS, /* ttyS1 */ \ + iomem_base: (unsigned char *)MVME5100_SERIAL_2, \ + iomem_reg_shift: 4, \ + io_type: SERIAL_IO_MEM }, + +#define SERIAL_PORT_DFNS \ + STD_SERIAL_PORT_DFNS + +#endif /* __ASM_MVME5100_SERIAL_H__ */ +#endif /* __KERNEL__ */ diff --git a/arch/ppc/platforms/mvme5100_setup.c b/arch/ppc/platforms/mvme5100_setup.c new file mode 100644 index 000000000000..b68e4679f99a --- /dev/null +++ b/arch/ppc/platforms/mvme5100_setup.c @@ -0,0 +1,284 @@ +/* + * arch/ppc/platforms/mvme5100_setup.c + * + * Board setup routines for the Motorola MVME5100. + * + * Author: Matt Porter <mporter@mvista.com> + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include <linux/config.h> +#include <linux/stddef.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/errno.h> +#include <linux/reboot.h> +#include <linux/pci.h> +#include <linux/kdev_t.h> +#include <linux/major.h> +#include <linux/blk.h> +#include <linux/console.h> +#include <linux/delay.h> +#include <linux/irq.h> +#include <linux/ide.h> +#include <linux/seq_file.h> + +#include <asm/system.h> +#include <asm/pgtable.h> +#include <asm/page.h> +#include <asm/time.h> +#include <asm/dma.h> +#include <asm/io.h> +#include <asm/machdep.h> +#include <asm/prom.h> +#include <asm/smp.h> +#include <asm/open_pic.h> +#include <asm/i8259.h> +#include <platforms/mvme5100.h> +#include <asm/todc.h> +#include <asm/pci-bridge.h> +#include <asm/bootinfo.h> +#include <asm/pplus.h> + +extern char cmd_line[]; + +static u_char mvme5100_openpic_initsenses[] __initdata = { + 0, /* 16: i8259 cascade (active high) */ + 1, /* 17: TL16C550 UART 1,2 */ + 1, /* 18: Enet 1 (front panel or P2) */ + 1, /* 19: Hawk Watchdog 1,2 */ + 1, /* 20: DS1621 thermal alarm */ + 1, /* 21: Universe II LINT0# */ + 1, /* 22: Universe II LINT1# */ + 1, /* 23: Universe II LINT2# */ + 1, /* 24: Universe II LINT3# */ + 1, /* 25: PMC1 INTA#, PMC2 INTB# */ + 1, /* 26: PMC1 INTB#, PMC2 INTC# */ + 1, /* 27: PMC1 INTC#, PMC2 INTD# */ + 1, /* 28: PMC1 INTD#, PMC2 INTA# */ + 1, /* 29: Enet 2 (front panel) */ + 1, /* 30: Abort Switch */ + 1, /* 31: RTC Alarm */ +}; + +static void __init +mvme5100_setup_arch(void) +{ + if ( ppc_md.progress ) + ppc_md.progress("mvme5100_setup_arch: enter", 0); + + loops_per_jiffy = 50000000 / HZ; + +#ifdef CONFIG_BLK_DEV_INITRD + if (initrd_start) + ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); /* /dev/ram */ + else +#endif +#ifdef CONFIG_ROOT_NFS + ROOT_DEV = to_kdev_t(0x00FF); /* /dev/nfs pseudo device */ +#else + ROOT_DEV = to_kdev_t(0x0802); /* /dev/sda2 */ +#endif + +#ifdef CONFIG_DUMMY_CONSOLE + conswitchp = &dummy_con; +#endif + + if ( ppc_md.progress ) + ppc_md.progress("mvme5100_setup_arch: find_bridges", 0); + + /* Setup PCI host bridge */ + mvme5100_setup_bridge(); + + /* Find and map our OpenPIC */ + pplus_mpic_init(MVME5100_PCI_MEM_OFFSET); + OpenPIC_InitSenses = mvme5100_openpic_initsenses; + OpenPIC_NumInitSenses = sizeof(mvme5100_openpic_initsenses); + + printk("MVME5100 port (C) 2001 MontaVista Software, Inc. (source@mvista.com)\n"); + + if ( ppc_md.progress ) + ppc_md.progress("mvme5100_setup_arch: exit", 0); + + return; +} + +static void __init +mvme5100_init2(void) +{ +#ifdef CONFIG_MVME5100_IPMC761_PRESENT + request_region(0x00,0x20,"dma1"); + request_region(0x20,0x20,"pic1"); + request_region(0x40,0x20,"timer"); + request_region(0x80,0x10,"dma page reg"); + request_region(0xa0,0x20,"pic2"); + request_region(0xc0,0x20,"dma2"); +#endif + return; +} + +/* + * Interrupt setup and service. + * Have MPIC on HAWK and cascaded 8259s on Winbond cascaded to MPIC. + */ +static void __init +mvme5100_init_IRQ(void) +{ +#ifdef CONFIG_MVME5100_IPMC761_PRESENT + int i; +#endif + + if ( ppc_md.progress ) + ppc_md.progress("init_irq: enter", 0); + +#ifdef CONFIG_MVME5100_IPMC761_PRESENT + openpic_init(1, NUM_8259_INTERRUPTS, NULL, -1); + + for(i=0; i < NUM_8259_INTERRUPTS; i++) + irq_desc[i].handler = &i8259_pic; + + i8259_init(NULL); +#else + openpic_init(1, 0, NULL, -1); +#endif + + if ( ppc_md.progress ) + ppc_md.progress("init_irq: exit", 0); + + return; +} + +/* + * Set BAT 3 to map 0xf0000000 to end of physical memory space. + */ +static __inline__ void +mvme5100_set_bat(void) +{ + unsigned long bat3u, bat3l; + static int mapping_set = 0; + + if (!mapping_set) { + + __asm__ __volatile__( + " lis %0,0xf000\n \ + ori %1,%0,0x002a\n \ + ori %0,%0,0x1ffe\n \ + mtspr 0x21e,%0\n \ + mtspr 0x21f,%1\n \ + isync\n \ + sync " + : "=r" (bat3u), "=r" (bat3l)); + + mapping_set = 1; + } + + return; +} + +static unsigned long __init +mvme5100_find_end_of_memory(void) +{ + mvme5100_set_bat(); + return pplus_get_mem_size(MVME5100_HAWK_SMC_BASE); +} + +static void __init +mvme5100_map_io(void) +{ + io_block_mapping(0xfe000000, 0xfe000000, 0x02000000, _PAGE_IO); + ioremap_base = 0xfe000000; +} + +static void +mvme5100_reset_board(void) +{ + __cli(); + + /* Set exception prefix high - to the firmware */ + _nmask_and_or_msr(0, MSR_IP); + + out_8((u_char *)MVME5100_BOARD_MODRST_REG, 0x01); + + return; +} + +static void +mvme5100_restart(char *cmd) +{ + volatile ulong i = 10000000; + + mvme5100_reset_board(); + + while (i-- > 0); + panic("restart failed\n"); +} + +static void +mvme5100_halt(void) +{ + __cli(); + while (1); +} + +static void +mvme5100_power_off(void) +{ + mvme5100_halt(); +} + +static int +mvme5100_show_cpuinfo(struct seq_file *m) +{ + seq_printf(m, "vendor\t\t: Motorola\n"); + seq_printf(m, "machine\t\t: MVME5100\n"); + + return 0; +} + +TODC_ALLOC(); + +void __init +platform_init(unsigned long r3, unsigned long r4, unsigned long r5, + unsigned long r6, unsigned long r7) +{ + parse_bootinfo(find_bootinfo()); + + isa_io_base = MVME5100_ISA_IO_BASE; + isa_mem_base = MVME5100_ISA_MEM_BASE; + pci_dram_offset = MVME5100_PCI_DRAM_OFFSET; + + ppc_md.setup_arch = mvme5100_setup_arch; + ppc_md.show_cpuinfo = mvme5100_show_cpuinfo; + ppc_md.init_IRQ = mvme5100_init_IRQ; + ppc_md.get_irq = openpic_get_irq; + ppc_md.init = mvme5100_init2; + + ppc_md.restart = mvme5100_restart; + ppc_md.power_off = mvme5100_power_off; + ppc_md.halt = mvme5100_halt; + + ppc_md.find_end_of_memory = mvme5100_find_end_of_memory; + ppc_md.setup_io_mappings = mvme5100_map_io; + + TODC_INIT(TODC_TYPE_MK48T37, + MVME5100_NVRAM_AS0, + MVME5100_NVRAM_AS1, + MVME5100_NVRAM_DATA, + 8); + + ppc_md.time_init = todc_time_init; + ppc_md.set_rtc_time = todc_set_rtc_time; + ppc_md.get_rtc_time = todc_get_rtc_time; + ppc_md.calibrate_decr = todc_calibrate_decr; + + ppc_md.nvram_read_val = todc_m48txx_read_val; + ppc_md.nvram_write_val = todc_m48txx_write_val; + + ppc_md.progress = NULL; +} diff --git a/include/asm-ppc/oak.h b/arch/ppc/platforms/oak.h index 713978ef2688..e520182fbf0d 100644 --- a/include/asm-ppc/oak.h +++ b/arch/ppc/platforms/oak.h @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.oak.h 1.12 10/11/01 13:05:07 trini + * BK Id: %F% %I% %G% %U% %#% */ /* * @@ -15,8 +15,11 @@ */ #ifdef __KERNEL__ -#ifndef __OAK_H__ -#define __OAK_H__ +#ifndef __ASM_OAK_H__ +#define __ASM_OAK_H__ + +/* We have an IBM 403G{A,B,C,CX} core */ +#include <asm/ibm403.h> #define _IO_BASE 0 #define _ISA_MEM_BASE 0 @@ -24,8 +27,8 @@ /* Memory map for the "Oak" evaluation board */ -#define PPC403SPU_IO_BASE 0x40000000 /* 403 On-chip serial port */ -#define PPC403SPU_IO_SIZE 0x00000008 +#define PPC403SPU_IO_BASE 0x40000000 /* 403 On-chip serial port */ +#define PPC403SPU_IO_SIZE 0x00000008 #define OAKSERIAL_IO_BASE 0x7E000000 /* NS16550DV serial port */ #define OAKSERIAL_IO_SIZE 0x00000008 #define OAKNET_IO_BASE 0xF4000000 /* NS83902AV Ethernet */ @@ -60,6 +63,12 @@ typedef struct board_info { unsigned int bi_busfreq; /* Bus speed, in Hz */ } bd_t; +/* Some 4xx parts use a different timebase frequency from the internal clock. +*/ +#define bi_tbfreq bi_intfreq + +#define PPC4xx_MACHINE_NAME "IBM Oak" + #endif /* !__ASSEMBLY__ */ -#endif /* __OAK_H__ */ +#endif /* __ASM_OAK_H__ */ #endif /* __KERNEL__ */ diff --git a/arch/ppc/kernel/oak_setup.c b/arch/ppc/platforms/oak_setup.c index 8d49dbbefff5..4ad64b9b6432 100644 --- a/arch/ppc/kernel/oak_setup.c +++ b/arch/ppc/platforms/oak_setup.c @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.oak_setup.c 1.12 11/13/01 21:26:07 paulus + * BK Id: %F% %I% %G% %U% %#% */ /* * @@ -19,27 +19,21 @@ #include <linux/init.h> #include <linux/smp.h> #include <linux/threads.h> -#include <linux/interrupt.h> #include <linux/param.h> #include <linux/string.h> #include <linux/blk.h> +#include <linux/irq.h> #include <linux/seq_file.h> #include <asm/processor.h> #include <asm/board.h> #include <asm/machdep.h> #include <asm/page.h> - -#include "local_irq.h" -#include "ppc4xx_pic.h" +#include <asm/bootinfo.h> +#include <asm/ppc4xx_pic.h> #include <asm/time.h> -#include "oak_setup.h" - - - - - +#include "oak_setup.h" /* Function Prototypes */ @@ -75,9 +69,11 @@ unsigned char __res[sizeof(bd_t)]; * */ void __init -platform_init(unsigned long r3, unsigned long r4, unsigned long r5, +platform_init(unsigned long r3, unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7) { + parse_bootinfo(find_bootinfo()); + /* * If we were passed in a board information, copy it into the * residual data area. diff --git a/arch/ppc/kernel/oak_setup.h b/arch/ppc/platforms/oak_setup.h index c51e15ec6b0c..c51e15ec6b0c 100644 --- a/arch/ppc/kernel/oak_setup.h +++ b/arch/ppc/platforms/oak_setup.h diff --git a/arch/ppc/platforms/pcore.h b/arch/ppc/platforms/pcore.h new file mode 100644 index 000000000000..8e1f3f32dba3 --- /dev/null +++ b/arch/ppc/platforms/pcore.h @@ -0,0 +1,41 @@ +/* + * arch/ppc/platforms/pcore.h + * + * Definitions for Force PowerCore board support + * + * Author: Matt Porter <mporter@mvista.com> + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#ifndef __PPC_PLATFORMS_PCORE_H +#define __PPC_PLATFORMS_PCORE_H + +#include <asm/mpc10x.h> + +#define PCORE_TYPE_6750 1 +#define PCORE_TYPE_680 2 + +#define PCORE_NVRAM_AS0 0x73 +#define PCORE_NVRAM_AS1 0x75 +#define PCORE_NVRAM_DATA 0x77 + +#define PCORE_DCCR_REG (MPC10X_MAPB_ISA_IO_BASE + 0x308) +#define PCORE_DCCR_L2_MASK 0xc0 +#define PCORE_DCCR_L2_0KB 0x00 +#define PCORE_DCCR_L2_256KB 0x40 +#define PCORE_DCCR_L2_512KB 0xc0 +#define PCORE_DCCR_L2_1MB 0x80 +#define PCORE_DCCR_L2_2MB 0x00 + +#define PCORE_WINBOND_IDE_INT 0x43 +#define PCORE_WINBOND_PCI_INT 0x44 +#define PCORE_WINBOND_PRI_EDG_LVL 0x4d0 +#define PCORE_WINBOND_SEC_EDG_LVL 0x4d1 + +#endif /* __PPC_PLATFORMS_PCORE_H */ diff --git a/arch/ppc/platforms/pcore_pci.c b/arch/ppc/platforms/pcore_pci.c new file mode 100644 index 000000000000..de68e1af70b8 --- /dev/null +++ b/arch/ppc/platforms/pcore_pci.c @@ -0,0 +1,144 @@ +/* + * arch/ppc/platforms/pcore_pci.c + * + * PCI support for Force PCORE boards + * + * Author: Matt Porter <mporter@mvista.com> + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/pci.h> +#include <linux/slab.h> + +#include <asm/byteorder.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/uaccess.h> +#include <asm/machdep.h> +#include <asm/pci-bridge.h> +#include <asm/mpc10x.h> + +#include "pcore.h" + +#undef DEBUG +#ifdef DEBUG +#define DBG(x...) printk(x) +#else +#define DBG(x...) +#endif /* DEBUG */ + +static inline int __init +pcore_6750_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) +{ + static char pci_irq_table[][4] = + /* + * PCI IDSEL/INTPIN->INTLINE + * A B C D + */ + { + {9, 10, 11, 12}, /* IDSEL 24 - DEC 21554 */ + {10, 0, 0, 0}, /* IDSEL 25 - DEC 21143 */ + {11, 12, 9, 10}, /* IDSEL 26 - PMC I */ + {12, 9, 10, 11}, /* IDSEL 27 - PMC II */ + {0, 0, 0, 0}, /* IDSEL 28 - unused */ + {0, 0, 9, 0}, /* IDSEL 29 - unused */ + {0, 0, 0, 0}, /* IDSEL 30 - Winbond */ + }; + const long min_idsel = 24, max_idsel = 30, irqs_per_slot = 4; + return PCI_IRQ_TABLE_LOOKUP; +}; + +static inline int __init +pcore_680_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) +{ + static char pci_irq_table[][4] = + /* + * PCI IDSEL/INTPIN->INTLINE + * A B C D + */ + { + {9, 10, 11, 12}, /* IDSEL 24 - Sentinel */ + {10, 0, 0, 0}, /* IDSEL 25 - i82559 #1 */ + {11, 12, 9, 10}, /* IDSEL 26 - PMC I */ + {12, 9, 10, 11}, /* IDSEL 27 - PMC II */ + {9, 0, 0, 0}, /* IDSEL 28 - i82559 #2 */ + {0, 0, 0, 0}, /* IDSEL 29 - unused */ + {0, 0, 0, 0}, /* IDSEL 30 - Winbond */ + }; + const long min_idsel = 24, max_idsel = 30, irqs_per_slot = 4; + return PCI_IRQ_TABLE_LOOKUP; +}; + +void __init +pcore_pcibios_fixup(void) +{ + struct pci_dev *dev; + + if ((dev = pci_find_device(PCI_VENDOR_ID_WINBOND, + PCI_DEVICE_ID_WINBOND_83C553, + 0))) + { + /* Reroute interrupts both IDE channels to 15 */ + pci_write_config_byte(dev, + PCORE_WINBOND_IDE_INT, + 0xff); + + /* Route INTA-D to IRQ9-12, respectively */ + pci_write_config_word(dev, + PCORE_WINBOND_PCI_INT, + 0x9abc); + + /* + * Set up 8259 edge/level triggering + */ + outb(0x00, PCORE_WINBOND_PRI_EDG_LVL); + outb(0x1e, PCORE_WINBOND_SEC_EDG_LVL); + } +} + +int __init +pcore_find_bridges(void) +{ + struct pci_controller* hose; + int host_bridge, board_type; + + hose = pcibios_alloc_controller(); + if (!hose) + return 0; + + mpc10x_bridge_init(hose, + MPC10X_MEM_MAP_B, + MPC10X_MEM_MAP_B, + MPC10X_MAPB_EUMB_BASE); + + /* Determine board type */ + early_read_config_dword(hose, + 0, + PCI_DEVFN(0,0), + PCI_VENDOR_ID, + &host_bridge); + if (host_bridge == MPC10X_BRIDGE_106) + board_type = PCORE_TYPE_6750; + else /* MPC10X_BRIDGE_107 */ + board_type = PCORE_TYPE_680; + + hose->last_busno = pciauto_bus_scan(hose, hose->first_busno); + + ppc_md.pcibios_fixup = pcore_pcibios_fixup; + ppc_md.pci_swizzle = common_swizzle; + + if (board_type == PCORE_TYPE_6750) + ppc_md.pci_map_irq = pcore_6750_map_irq; + else /* PCORE_TYPE_680 */ + ppc_md.pci_map_irq = pcore_680_map_irq; + + return board_type; +} diff --git a/arch/ppc/platforms/pcore_setup.c b/arch/ppc/platforms/pcore_setup.c new file mode 100644 index 000000000000..7531b7d041fa --- /dev/null +++ b/arch/ppc/platforms/pcore_setup.c @@ -0,0 +1,257 @@ +/* + * arch/ppc/platforms/pcore_setup.c + * + * Setup routines for Force PCORE boards + * + * Author: Matt Porter <mporter@mvista.com> + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include <linux/config.h> +#include <linux/stddef.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/errno.h> +#include <linux/reboot.h> +#include <linux/pci.h> +#include <linux/kdev_t.h> +#include <linux/types.h> +#include <linux/major.h> +#include <linux/blk.h> +#include <linux/console.h> +#include <linux/delay.h> +#include <linux/irq.h> +#include <linux/seq_file.h> +#include <linux/ide.h> + +#include <asm/system.h> +#include <asm/pgtable.h> +#include <asm/page.h> +#include <asm/dma.h> +#include <asm/io.h> +#include <asm/machdep.h> +#include <asm/time.h> +#include <asm/i8259.h> +#include <asm/mpc10x.h> +#include <asm/todc.h> +#include <asm/bootinfo.h> + +#include "pcore.h" + +extern int pcore_find_bridges(void); +extern unsigned long loops_per_jiffy; + +static int board_type; + +/* Dummy variable to satisfy mpc10x_common.o */ +void *OpenPIC_Addr; + +static int +pcore_show_cpuinfo(struct seq_file *m) +{ + seq_printf(m, "vendor\t\t: Force Computers\n"); + + if (board_type == PCORE_TYPE_6750) + seq_printf(m, "machine\t\t: PowerCore 6750\n"); + else /* PCORE_TYPE_680 */ + seq_printf(m, "machine\t\t: PowerCore 680\n"); + + seq_printf(m, "L2\t\t: " ); + if (board_type == PCORE_TYPE_6750) + switch (readb(PCORE_DCCR_REG) & PCORE_DCCR_L2_MASK) + { + case PCORE_DCCR_L2_0KB: + seq_printf(m, "nocache"); + break; + case PCORE_DCCR_L2_256KB: + seq_printf(m, "256KB"); + break; + case PCORE_DCCR_L2_1MB: + seq_printf(m, "1MB"); + break; + case PCORE_DCCR_L2_512KB: + seq_printf(m, "512KB"); + break; + default: + seq_printf(m, "error"); + break; + } + else /* PCORE_TYPE_680 */ + switch (readb(PCORE_DCCR_REG) & PCORE_DCCR_L2_MASK) + { + case PCORE_DCCR_L2_2MB: + seq_printf(m, "2MB"); + break; + case PCORE_DCCR_L2_256KB: + seq_printf(m, "reserved"); + break; + case PCORE_DCCR_L2_1MB: + seq_printf(m, "1MB"); + break; + case PCORE_DCCR_L2_512KB: + seq_printf(m, "512KB"); + break; + default: + seq_printf(m, "error"); + break; + } + + seq_printf(m, "\n"); + + return 0; +} + +static void __init +pcore_setup_arch(void) +{ + /* init to some ~sane value until calibrate_delay() runs */ + loops_per_jiffy = 50000000/HZ; + + /* Lookup PCI host bridges */ + board_type = pcore_find_bridges(); + +#ifdef CONFIG_BLK_DEV_INITRD + if (initrd_start) + ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); /* /dev/ram */ + else +#endif +#ifdef CONFIG_ROOT_NFS + ROOT_DEV = to_kdev_t(0x00ff); /* /dev/nfs pseudo device */ +#else + ROOT_DEV = to_kdev_t(0x0802); /* /dev/sda2 */ +#endif + +#ifdef CONFIG_DUMMY_CONSOLE + conswitchp = &dummy_con; +#endif + + printk("Force PCore port (C) 2001 MontaVista Software, Inc. (source@mvista.com)\n"); +} + +static void +pcore_restart(char *cmd) +{ + __cli(); + /* Hard reset */ + writeb(0x11, 0xfe000332); + while(1); +} + +static void +pcore_halt(void) +{ + __cli(); + /* Turn off user LEDs */ + writeb(0x00, 0xfe000300); + while (1); +} + +static void +pcore_power_off(void) +{ + pcore_halt(); +} + + +static void __init +pcore_init_IRQ(void) +{ + int i; + + for ( i = 0 ; i < 16 ; i++ ) + irq_desc[i].handler = &i8259_pic; + + i8259_init(NULL); +} + +static int +pcore_get_irq(struct pt_regs *regs) +{ + return i8259_poll(); +} + +/* + * Set BAT 3 to map 0xf0000000 to end of physical memory space. + */ +static __inline__ void +pcore_set_bat(void) +{ + unsigned long bat3u, bat3l; + static int mapping_set = 0; + + if (!mapping_set) { + __asm__ __volatile__( + " lis %0,0xf000\n \ + ori %1,%0,0x002a\n \ + ori %0,%0,0x1ffe\n \ + mtspr 0x21e,%0\n \ + mtspr 0x21f,%1\n \ + isync\n \ + sync " + : "=r" (bat3u), "=r" (bat3l)); + + mapping_set = 1; + } + return; +} + +static unsigned long __init +pcore_find_end_of_memory(void) +{ + /* Cover I/O space with a BAT */ + /* yuck, better hope your ram size is a power of 2 -- paulus */ + pcore_set_bat(); + + return mpc10x_get_mem_size(MPC10X_MEM_MAP_B); +} + +static void __init +pcore_map_io(void) +{ + io_block_mapping(0xfe000000, 0xfe000000, 0x02000000, _PAGE_IO); +} + +TODC_ALLOC(); + +void __init +platform_init(unsigned long r3, unsigned long r4, unsigned long r5, + unsigned long r6, unsigned long r7) +{ + parse_bootinfo(find_bootinfo()); + + isa_io_base = MPC10X_MAPB_ISA_IO_BASE; + isa_mem_base = MPC10X_MAPB_ISA_MEM_BASE; + pci_dram_offset = MPC10X_MAPB_DRAM_OFFSET; + + ppc_md.setup_arch = pcore_setup_arch; + ppc_md.show_cpuinfo = pcore_show_cpuinfo; + ppc_md.init_IRQ = pcore_init_IRQ; + ppc_md.get_irq = pcore_get_irq; + + ppc_md.find_end_of_memory = pcore_find_end_of_memory; + ppc_md.setup_io_mappings = pcore_map_io; + + ppc_md.restart = pcore_restart; + ppc_md.power_off = pcore_power_off; + ppc_md.halt = pcore_halt; + + TODC_INIT(TODC_TYPE_MK48T59, + PCORE_NVRAM_AS0, + PCORE_NVRAM_AS1, + PCORE_NVRAM_DATA, + 8); + + ppc_md.time_init = todc_time_init; + ppc_md.get_rtc_time = todc_get_rtc_time; + ppc_md.set_rtc_time = todc_set_rtc_time; + ppc_md.calibrate_decr = todc_calibrate_decr; + + ppc_md.nvram_read_val = todc_m48txx_read_val; + ppc_md.nvram_write_val = todc_m48txx_write_val; +} diff --git a/arch/ppc/platforms/pcu_e.h b/arch/ppc/platforms/pcu_e.h new file mode 100644 index 000000000000..dd9b85068259 --- /dev/null +++ b/arch/ppc/platforms/pcu_e.h @@ -0,0 +1,28 @@ +/* + * Siemens PCU E board specific definitions + * + * Copyright (c) 2001 Wolfgang Denk (wd@denx.de) + */ + +#ifndef __MACH_PCU_E_H +#define __MACH_PCU_E_H + +#include <linux/config.h> + +#include <asm/ppcboot.h> + +#define PCU_E_IMMR_BASE 0xFE000000 /* phys. addr of IMMR */ +#define PCU_E_IMAP_SIZE (64 * 1024) /* size of mapped area */ + +#define IMAP_ADDR PCU_E_IMMR_BASE /* physical base address of IMMR area */ +#define IMAP_SIZE PCU_E_IMAP_SIZE /* mapped size of IMMR area */ + +#define FEC_INTERRUPT 15 /* = SIU_LEVEL7 */ +#define DEC_INTERRUPT 13 /* = SIU_LEVEL6 */ +#define CPM_INTERRUPT 11 /* = SIU_LEVEL5 (was: SIU_LEVEL2) */ + +/* We don't use the 8259. +*/ +#define NR_8259_INTS 0 + +#endif /* __MACH_PCU_E_H */ diff --git a/arch/ppc/kernel/pmac_backlight.c b/arch/ppc/platforms/pmac_backlight.c index 63c8a8646e58..6b117bb9ac77 100644 --- a/arch/ppc/kernel/pmac_backlight.c +++ b/arch/ppc/platforms/pmac_backlight.c @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.pmac_backlight.c 1.8 09/08/01 15:47:42 paulus + * BK Id: %F% %I% %G% %U% %#% */ /* * Miscellaneous procedures for dealing with the PowerMac hardware. @@ -78,7 +78,7 @@ register_backlight_controller(struct backlight_controller *ctrler, void *data, c pmu_request(&req, NULL, 2, 0xd9, 0); while (!req.complete) pmu_poll(); - backlight_level = req.reply[1] >> 4; + backlight_level = req.reply[0] >> 4; } #endif if (!backlighter->set_enable(1, backlight_level, data)) diff --git a/arch/ppc/platforms/pmac_feature.c b/arch/ppc/platforms/pmac_feature.c new file mode 100644 index 000000000000..3a930be3e77d --- /dev/null +++ b/arch/ppc/platforms/pmac_feature.c @@ -0,0 +1,2126 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ +/* + * arch/ppc/platforms/pmac_feature.c + * + * Copyright (C) 1996-2001 Paul Mackerras (paulus@cs.anu.edu.au) + * Ben. Herrenschmidt (benh@kernel.crashing.org) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + * TODO: + * + * - Replace mdelay with some schedule loop if possible + * - Shorten some obfuscated delays on some routines (like modem + * power) + * + */ +#include <linux/config.h> +#include <linux/types.h> +#include <linux/init.h> +#include <linux/delay.h> +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/spinlock.h> +#include <linux/adb.h> +#include <linux/pmu.h> +#include <asm/sections.h> +#include <asm/errno.h> +#include <asm/ohare.h> +#include <asm/heathrow.h> +#include <asm/keylargo.h> +#include <asm/uninorth.h> +#include <asm/io.h> +#include <asm/prom.h> +#include <asm/machdep.h> +#include <asm/pmac_feature.h> +#include <asm/dbdma.h> + +#undef DEBUG_FEATURE + +#ifdef DEBUG_FEATURE +#define DBG(fmt,...) printk(KERN_DEBUG fmt) +#else +#define DBG(fmt,...) +#endif + +/* Exported from arch/ppc/kernel/idle.c */ +extern unsigned long powersave_nap; + +/* + * We use a single global lock to protect accesses. Each driver has + * to take care of it's own locking + */ +static spinlock_t feature_lock __pmacdata = SPIN_LOCK_UNLOCKED; + +#define LOCK(flags) spin_lock_irqsave(&feature_lock, flags); +#define UNLOCK(flags) spin_unlock_irqrestore(&feature_lock, flags); + +/* + * Helper functions regarding the various flavors of mac-io + */ + +#define MAX_MACIO_CHIPS 2 + +enum { + macio_unknown = 0, + macio_grand_central, + macio_ohare, + macio_ohareII, + macio_heathrow, + macio_gatwick, + macio_paddington, + macio_keylargo, + macio_pangea +}; + +static const char* macio_names[] __pmacdata = +{ + "Unknown", + "Grand Central", + "OHare", + "OHareII", + "Heathrow", + "Gatwick", + "Paddington", + "Keylargo", + "Pangea" +}; + +static struct macio_chip +{ + struct device_node* of_node; + int type; + int rev; + volatile u32* base; + unsigned long flags; +} macio_chips[MAX_MACIO_CHIPS] __pmacdata; + +#define MACIO_FLAG_SCCA_ON 0x00000001 +#define MACIO_FLAG_SCCB_ON 0x00000002 +#define MACIO_FLAG_SCC_LOCKED 0x00000004 +#define MACIO_FLAG_AIRPORT_ON 0x00000010 +#define MACIO_FLAG_FW_SUPPORTED 0x00000020 + +static struct macio_chip* __pmac +macio_find(struct device_node* child, int type) +{ + while(child) { + int i; + + for (i=0; i < MAX_MACIO_CHIPS && macio_chips[i].of_node; i++) + if (child == macio_chips[i].of_node && + (!type || macio_chips[i].type == type)) + return &macio_chips[i]; + child = child->parent; + } + return NULL; +} + +#define MACIO_FCR32(macio, r) ((macio)->base + ((r) >> 2)) +#define MACIO_FCR8(macio, r) (((volatile u8*)((macio)->base)) + (r)) + +#define MACIO_IN32(r) (in_le32(MACIO_FCR32(macio,r))) +#define MACIO_OUT32(r,v) (out_le32(MACIO_FCR32(macio,r), (v))) +#define MACIO_BIS(r,v) (MACIO_OUT32((r), MACIO_IN32(r) | (v))) +#define MACIO_BIC(r,v) (MACIO_OUT32((r), MACIO_IN32(r) & ~(v))) +#define MACIO_IN8(r) (in_8(MACIO_FCR8(macio,r))) +#define MACIO_OUT8(r,v) (out_8(MACIO_FCR8(macio,r), (v))) + +/* + * Uninorth reg. access. Note that Uni-N regs are big endian + */ + +#define UN_REG(r) (uninorth_base + ((r) >> 2)) +#define UN_IN(r) (in_be32(UN_REG(r))) +#define UN_OUT(r,v) (out_be32(UN_REG(r), (v))) +#define UN_BIS(r,v) (UN_OUT((r), UN_IN(r) | (v))) +#define UN_BIC(r,v) (UN_OUT((r), UN_IN(r) & ~(v))) + +static struct device_node* uninorth_node __pmacdata; +static u32* uninorth_base __pmacdata; +static u32 uninorth_rev __pmacdata; + + +/* + * For each motherboard family, we have a table of functions pointers + * that handle the various features. + */ + +typedef int (*feature_call)(struct device_node* node, int param, int value); + +struct feature_table_entry { + unsigned int selector; + feature_call function; +}; + +struct pmac_mb_def +{ + const char* model_string; + const char* model_name; + int model_id; + struct feature_table_entry* features; + unsigned long board_flags; +}; +static struct pmac_mb_def pmac_mb __pmacdata; + +/* + * Here are the chip specific feature functions + */ + +static inline int __pmac +simple_feature_tweak(struct device_node* node, int type, int reg, u32 mask, int value) +{ + struct macio_chip* macio; + unsigned long flags; + + macio = macio_find(node, type); + if (!macio) + return -ENODEV; + LOCK(flags); + if (value) + MACIO_BIS(reg, mask); + else + MACIO_BIC(reg, mask); + (void)MACIO_IN32(reg); + UNLOCK(flags); + + return 0; +} + +static int __pmac +generic_scc_enable(struct device_node* node, u32 enable_mask, u32 reset_mask, + int param, int value) +{ + struct macio_chip* macio; + unsigned long chan_mask; + unsigned long fcr; + unsigned long flags; + + macio = macio_find(node, 0); + if (!macio) + return -ENODEV; + if (!strcmp(node->name, "ch-a")) + chan_mask = MACIO_FLAG_SCCA_ON; + else if (!strcmp(node->name, "ch-b")) + chan_mask = MACIO_FLAG_SCCB_ON; + else + return -ENODEV; + + if (value) { + LOCK(flags); + fcr = MACIO_IN32(OHARE_FCR); + /* Check if scc cell need enabling */ + if (!(fcr & OH_SCC_ENABLE)) { + fcr |= enable_mask; + MACIO_OUT32(OHARE_FCR, fcr); + fcr |= reset_mask; + MACIO_OUT32(OHARE_FCR, fcr); + UNLOCK(flags); + (void)MACIO_IN32(OHARE_FCR); + mdelay(15); + LOCK(flags); + fcr &= ~reset_mask; + MACIO_OUT32(OHARE_FCR, fcr); + } + if (chan_mask & MACIO_FLAG_SCCA_ON) + fcr |= OH_SCCA_IO; + if (chan_mask & MACIO_FLAG_SCCB_ON) + fcr |= OH_SCCB_IO; + MACIO_OUT32(OHARE_FCR, fcr); + macio->flags |= chan_mask; + UNLOCK(flags); + if (param & PMAC_SCC_FLAG_XMON) + macio->flags |= MACIO_FLAG_SCC_LOCKED; + } else { + if (macio->flags & MACIO_FLAG_SCC_LOCKED) + return -EPERM; + LOCK(flags); + fcr = MACIO_IN32(OHARE_FCR); + if (chan_mask & MACIO_FLAG_SCCA_ON) + fcr &= ~OH_SCCA_IO; + if (chan_mask & MACIO_FLAG_SCCB_ON) + fcr &= ~OH_SCCB_IO; + MACIO_OUT32(OHARE_FCR, fcr); + if ((fcr & (OH_SCCA_IO | OH_SCCB_IO)) == 0) { + fcr &= ~enable_mask; + MACIO_OUT32(OHARE_FCR, fcr); + } + macio->flags &= ~(chan_mask); + UNLOCK(flags); + mdelay(10); + } + return 0; +} + +static int __pmac +ohare_scc_enable(struct device_node* node, int param, int value) +{ + int rc; + +#ifdef CONFIG_ADB_PMU + if (value && (param & 0xfff) == PMAC_SCC_IRDA) + pmu_enable_irled(1); +#endif /* CONFIG_ADB_PMU */ + rc = generic_scc_enable(node, OH_SCC_ENABLE, OH_SCC_RESET, param, value); +#ifdef CONFIG_ADB_PMU + if ((param & 0xfff) == PMAC_SCC_IRDA && (rc || !value)) + pmu_enable_irled(0); +#endif /* CONFIG_ADB_PMU */ + return rc; +} + +static int __pmac +ohare_floppy_enable(struct device_node* node, int param, int value) +{ + return simple_feature_tweak(node, macio_ohare, + OHARE_FCR, OH_FLOPPY_ENABLE, value); +} + +static int __pmac +ohare_mesh_enable(struct device_node* node, int param, int value) +{ + return simple_feature_tweak(node, macio_ohare, + OHARE_FCR, OH_MESH_ENABLE, value); +} + +static int __pmac +ohare_ide_enable(struct device_node* node, int param, int value) +{ + switch(param) { + case 0: + /* For some reason, setting the bit in set_initial_features() + * doesn't stick. I'm still investigating... --BenH. + */ + if (value) + simple_feature_tweak(node, macio_ohare, + OHARE_FCR, OH_IOBUS_ENABLE, 1); + return simple_feature_tweak(node, macio_ohare, + OHARE_FCR, OH_IDE0_ENABLE, value); + case 1: + return simple_feature_tweak(node, macio_ohare, + OHARE_FCR, OH_BAY_IDE_ENABLE, value); + default: + return -ENODEV; + } +} + +static int __pmac +ohare_ide_reset(struct device_node* node, int param, int value) +{ + switch(param) { + case 0: + return simple_feature_tweak(node, macio_ohare, + OHARE_FCR, OH_IDE0_RESET_N, !value); + case 1: + return simple_feature_tweak(node, macio_ohare, + OHARE_FCR, OH_IDE1_RESET_N, !value); + default: + return -ENODEV; + } +} + +static int __pmac +ohare_sleep_state(struct device_node* node, int param, int value) +{ + struct macio_chip* macio = &macio_chips[0]; + + if ((pmac_mb.board_flags & PMAC_MB_CAN_SLEEP) == 0) + return -EPERM; + if (value) { + MACIO_BIC(OHARE_FCR, OH_IOBUS_ENABLE); + } else { + MACIO_BIS(OHARE_FCR, OH_IOBUS_ENABLE); + } + + return 0; +} + +static int __pmac +heathrow_scc_enable(struct device_node* node, int param, int value) +{ + int rc; + +#ifdef CONFIG_ADB_PMU + if (value && param == PMAC_SCC_IRDA) + pmu_enable_irled(1); +#endif /* CONFIG_ADB_PMU */ + /* Fixme: It's possible that wallstreet (heathrow) is different + * than other paddington machines. I still have to figure that + * out exactly, for now, the paddington values are used + */ + rc = generic_scc_enable(node, HRW_SCC_ENABLE, PADD_RESET_SCC, param, value); +#ifdef CONFIG_ADB_PMU + if (param == PMAC_SCC_IRDA && (rc || !value)) + pmu_enable_irled(0); +#endif /* CONFIG_ADB_PMU */ + return rc; +} + +static int __pmac +heathrow_modem_enable(struct device_node* node, int param, int value) +{ + struct macio_chip* macio; + u8 gpio; + unsigned long flags; + + macio = macio_find(node, macio_unknown); + if (!macio) + return -ENODEV; + gpio = MACIO_IN8(HRW_GPIO_MODEM_RESET) & ~1; + if (!value) { + LOCK(flags); + MACIO_OUT8(HRW_GPIO_MODEM_RESET, gpio); + UNLOCK(flags); + (void)MACIO_IN8(HRW_GPIO_MODEM_RESET); + mdelay(250); + } + if (pmac_mb.model_id != PMAC_TYPE_YOSEMITE && + pmac_mb.model_id != PMAC_TYPE_YIKES) { + LOCK(flags); + /* We use the paddington values as they seem to work properly + * on the wallstreet (heathrow) as well. I can't tell why we + * had to flip them on older feature.c, the fact is that new + * code uses the paddington values which are also the ones used + * in Darwin, and that works on wallstreet ! + */ + if (value) + MACIO_BIC(HEATHROW_FCR, PADD_MODEM_POWER_N); + else + MACIO_BIS(HEATHROW_FCR, PADD_MODEM_POWER_N); + UNLOCK(flags); + (void)MACIO_IN32(HEATHROW_FCR); + mdelay(250); + } + if (value) { + LOCK(flags); + MACIO_OUT8(HRW_GPIO_MODEM_RESET, gpio | 1); + (void)MACIO_IN8(HRW_GPIO_MODEM_RESET); + UNLOCK(flags); mdelay(250); LOCK(flags); + MACIO_OUT8(HRW_GPIO_MODEM_RESET, gpio); + (void)MACIO_IN8(HRW_GPIO_MODEM_RESET); + UNLOCK(flags); mdelay(250); LOCK(flags); + MACIO_OUT8(HRW_GPIO_MODEM_RESET, gpio | 1); + (void)MACIO_IN8(HRW_GPIO_MODEM_RESET); + UNLOCK(flags); mdelay(250); LOCK(flags); + } + return 0; +} + +static int __pmac +heathrow_floppy_enable(struct device_node* node, int param, int value) +{ + return simple_feature_tweak(node, macio_unknown, + HEATHROW_FCR, + HRW_SWIM_ENABLE|HRW_BAY_FLOPPY_ENABLE, + value); +} + +static int __pmac +heathrow_mesh_enable(struct device_node* node, int param, int value) +{ + struct macio_chip* macio; + unsigned long flags; + + macio = macio_find(node, macio_unknown); + if (!macio) + return -ENODEV; + LOCK(flags); + /* Set clear mesh cell enable */ + if (value) + MACIO_BIS(HEATHROW_FCR, HRW_MESH_ENABLE); + else + MACIO_BIC(HEATHROW_FCR, HRW_MESH_ENABLE); + (void)MACIO_IN32(HEATHROW_FCR); + udelay(10); + /* Set/Clear termination power (todo: test ! the bit value + * used by Darwin doesn't seem to match what we used so + * far. If you experience problems, turn #if 1 into #if 0 + * and tell me about it --BenH. + */ +#if 1 + if (value) + MACIO_BIC(HEATHROW_MBCR, 0x00000004); + else + MACIO_BIS(HEATHROW_MBCR, 0x00000004); +#else + if (value) + MACIO_BIC(HEATHROW_MBCR, 0x00040000); + else + MACIO_BIS(HEATHROW_MBCR, 0x00040000); +#endif + (void)MACIO_IN32(HEATHROW_MBCR); + udelay(10); + UNLOCK(flags); + + return 0; +} + +static int __pmac +heathrow_ide_enable(struct device_node* node, int param, int value) +{ + switch(param) { + case 0: + return simple_feature_tweak(node, macio_unknown, + HEATHROW_FCR, HRW_IDE0_ENABLE, value); + case 1: + return simple_feature_tweak(node, macio_unknown, + HEATHROW_FCR, HRW_BAY_IDE_ENABLE, value); + default: + return -ENODEV; + } +} + +static int __pmac +heathrow_ide_reset(struct device_node* node, int param, int value) +{ + switch(param) { + case 0: + return simple_feature_tweak(node, macio_unknown, + HEATHROW_FCR, HRW_IDE0_RESET_N, !value); + case 1: + return simple_feature_tweak(node, macio_unknown, + HEATHROW_FCR, HRW_IDE1_RESET_N, !value); + default: + return -ENODEV; + } +} + +static int __pmac +heathrow_bmac_enable(struct device_node* node, int param, int value) +{ + struct macio_chip* macio; + unsigned long flags; + + macio = macio_find(node, 0); + if (!macio) + return -ENODEV; + if (value) { + LOCK(flags); + MACIO_BIS(HEATHROW_FCR, HRW_BMAC_IO_ENABLE); + MACIO_BIS(HEATHROW_FCR, HRW_BMAC_RESET); + UNLOCK(flags); + (void)MACIO_IN32(HEATHROW_FCR); + mdelay(10); + LOCK(flags); + MACIO_BIC(HEATHROW_FCR, HRW_BMAC_RESET); + UNLOCK(flags); + (void)MACIO_IN32(HEATHROW_FCR); + mdelay(10); + } else { + LOCK(flags); + MACIO_BIC(HEATHROW_FCR, HRW_BMAC_IO_ENABLE); + UNLOCK(flags); + } + return 0; +} + +static int __pmac +heathrow_sound_enable(struct device_node* node, int param, int value) +{ + struct macio_chip* macio; + unsigned long flags; + + /* B&W G3 and Yikes don't support that properly (the + * sound appear to never come back after beeing shut down). + */ + if (pmac_mb.model_id == PMAC_TYPE_YOSEMITE || + pmac_mb.model_id == PMAC_TYPE_YIKES) + return 0; + + macio = macio_find(node, 0); + if (!macio) + return -ENODEV; + if (value) { + LOCK(flags); + MACIO_BIS(HEATHROW_FCR, HRW_SOUND_CLK_ENABLE); + MACIO_BIC(HEATHROW_FCR, HRW_SOUND_POWER_N); + UNLOCK(flags); + (void)MACIO_IN32(HEATHROW_FCR); + } else { + LOCK(flags); + MACIO_BIS(HEATHROW_FCR, HRW_SOUND_POWER_N); + MACIO_BIC(HEATHROW_FCR, HRW_SOUND_CLK_ENABLE); + UNLOCK(flags); + } + return 0; +} + +static u32 save_fcr[5] __pmacdata; +static u32 save_mbcr __pmacdata; +static u32 save_gpio_levels[2] __pmacdata; +static u8 save_gpio_extint[KEYLARGO_GPIO_EXTINT_CNT] __pmacdata; +static u8 save_gpio_normal[KEYLARGO_GPIO_CNT] __pmacdata; +static u32 save_unin_clock_ctl __pmacdata; +static struct dbdma_regs save_dbdma[13] __pmacdata; +static struct dbdma_regs save_alt_dbdma[13] __pmacdata; + +static void __pmac +dbdma_save(struct macio_chip* macio, struct dbdma_regs* save) +{ + int i; + + /* Save state & config of DBDMA channels */ + for (i=0; i<13; i++) { + volatile struct dbdma_regs* chan = (volatile struct dbdma_regs*) + (macio->base + ((0x8000+i*0x100)>>2)); + save[i].cmdptr_hi = in_le32(&chan->cmdptr_hi); + save[i].cmdptr = in_le32(&chan->cmdptr); + save[i].intr_sel = in_le32(&chan->intr_sel); + save[i].br_sel = in_le32(&chan->br_sel); + save[i].wait_sel = in_le32(&chan->wait_sel); + } +} + +static void __pmac +dbdma_restore(struct macio_chip* macio, struct dbdma_regs* save) +{ + int i; + + /* Save state & config of DBDMA channels */ + for (i=0; i<13; i++) { + volatile struct dbdma_regs* chan = (volatile struct dbdma_regs*) + (macio->base + ((0x8000+i*0x100)>>2)); + out_le32(&chan->control, (ACTIVE|DEAD|WAKE|FLUSH|PAUSE|RUN)<<16); + while (in_le32(&chan->status) & ACTIVE) + mb(); + out_le32(&chan->cmdptr_hi, save[i].cmdptr_hi); + out_le32(&chan->cmdptr, save[i].cmdptr); + out_le32(&chan->intr_sel, save[i].intr_sel); + out_le32(&chan->br_sel, save[i].br_sel); + out_le32(&chan->wait_sel, save[i].wait_sel); + } +} + +static void __pmac +heathrow_sleep(struct macio_chip* macio, int secondary) +{ + if (secondary) { + dbdma_save(macio, save_alt_dbdma); + save_fcr[2] = MACIO_IN32(0x38); + save_fcr[3] = MACIO_IN32(0x3c); + } else { + dbdma_save(macio, save_dbdma); + save_fcr[0] = MACIO_IN32(0x38); + save_fcr[1] = MACIO_IN32(0x3c); + save_mbcr = MACIO_IN32(0x34); + /* Make sure sound is shut down */ + MACIO_BIS(HEATHROW_FCR, HRW_SOUND_POWER_N); + MACIO_BIC(HEATHROW_FCR, HRW_SOUND_CLK_ENABLE); + /* This seems to be necessary as well or the fan + * keeps coming up and battery drains fast */ + MACIO_BIC(HEATHROW_FCR, HRW_IOBUS_ENABLE); + } + /* Make sure modem is shut down */ + MACIO_OUT8(HRW_GPIO_MODEM_RESET, + MACIO_IN8(HRW_GPIO_MODEM_RESET) & ~1); + MACIO_BIS(HEATHROW_FCR, PADD_MODEM_POWER_N); + MACIO_BIC(HEATHROW_FCR, OH_SCCA_IO|OH_SCCB_IO|HRW_SCC_ENABLE); + + /* Let things settle */ + (void)MACIO_IN32(HEATHROW_FCR); + mdelay(1); +} + +static void __pmac +heathrow_wakeup(struct macio_chip* macio, int secondary) +{ + if (secondary) { + MACIO_OUT32(0x38, save_fcr[2]); + (void)MACIO_IN32(0x38); + mdelay(1); + MACIO_OUT32(0x3c, save_fcr[3]); + (void)MACIO_IN32(0x38); + mdelay(10); + dbdma_restore(macio, save_alt_dbdma); + } else { + MACIO_OUT32(0x38, save_fcr[0] | HRW_IOBUS_ENABLE); + (void)MACIO_IN32(0x38); + mdelay(1); + MACIO_OUT32(0x3c, save_fcr[1]); + (void)MACIO_IN32(0x38); + mdelay(1); + MACIO_OUT32(0x34, save_mbcr); + (void)MACIO_IN32(0x38); + mdelay(10); + dbdma_restore(macio, save_dbdma); + } +} + +static int __pmac +heathrow_sleep_state(struct device_node* node, int param, int value) +{ + if ((pmac_mb.board_flags & PMAC_MB_CAN_SLEEP) == 0) + return -EPERM; + if (value == 1) { + if (macio_chips[1].type == macio_gatwick) + heathrow_sleep(&macio_chips[0], 1); + heathrow_sleep(&macio_chips[0], 0); + } else if (value == 0) { + heathrow_wakeup(&macio_chips[0], 0); + if (macio_chips[1].type == macio_gatwick) + heathrow_wakeup(&macio_chips[0], 1); + } + return 0; +} + +static int __pmac +core99_scc_enable(struct device_node* node, int param, int value) +{ + struct macio_chip* macio; + unsigned long flags; + unsigned long chan_mask; + u32 fcr; + + macio = macio_find(node, 0); + if (!macio) + return -ENODEV; + if (!strcmp(node->name, "ch-a")) + chan_mask = MACIO_FLAG_SCCA_ON; + else if (!strcmp(node->name, "ch-b")) + chan_mask = MACIO_FLAG_SCCB_ON; + else + return -ENODEV; + + if (value) { + int need_reset_scc = 0; + int need_reset_irda = 0; + + LOCK(flags); + fcr = MACIO_IN32(KEYLARGO_FCR0); + /* Check if scc cell need enabling */ + if (!(fcr & KL0_SCC_CELL_ENABLE)) { + fcr |= KL0_SCC_CELL_ENABLE; + need_reset_scc = 1; + } + if (chan_mask & MACIO_FLAG_SCCA_ON) { + fcr |= KL0_SCCA_ENABLE; + /* Don't enable line drivers for I2S modem */ + if ((param & 0xfff) == PMAC_SCC_I2S1) + fcr &= ~KL0_SCC_A_INTF_ENABLE; + else + fcr |= KL0_SCC_A_INTF_ENABLE; + } + if (chan_mask & MACIO_FLAG_SCCB_ON) { + fcr |= KL0_SCCB_ENABLE; + /* Perform irda specific inits */ + if ((param & 0xfff) == PMAC_SCC_IRDA) { + fcr &= ~KL0_SCC_B_INTF_ENABLE; + fcr |= KL0_IRDA_ENABLE; + fcr |= KL0_IRDA_CLK32_ENABLE | KL0_IRDA_CLK19_ENABLE; + fcr |= KL0_IRDA_SOURCE1_SEL; + fcr &= ~(KL0_IRDA_FAST_CONNECT|KL0_IRDA_DEFAULT1|KL0_IRDA_DEFAULT0); + fcr &= ~(KL0_IRDA_SOURCE2_SEL|KL0_IRDA_HIGH_BAND); + need_reset_irda = 1; + } else + fcr |= KL0_SCC_B_INTF_ENABLE; + } + MACIO_OUT32(KEYLARGO_FCR0, fcr); + macio->flags |= chan_mask; + if (need_reset_scc) { + MACIO_BIS(KEYLARGO_FCR0, KL0_SCC_RESET); + (void)MACIO_IN32(KEYLARGO_FCR0); + UNLOCK(flags); + mdelay(15); + LOCK(flags); + MACIO_BIC(KEYLARGO_FCR0, KL0_SCC_RESET); + } + if (need_reset_irda) { + MACIO_BIS(KEYLARGO_FCR0, KL0_IRDA_RESET); + (void)MACIO_IN32(KEYLARGO_FCR0); + UNLOCK(flags); + mdelay(15); + LOCK(flags); + MACIO_BIC(KEYLARGO_FCR0, KL0_IRDA_RESET); + } + UNLOCK(flags); + if (param & PMAC_SCC_FLAG_XMON) + macio->flags |= MACIO_FLAG_SCC_LOCKED; + } else { + if (macio->flags & MACIO_FLAG_SCC_LOCKED) + return -EPERM; + LOCK(flags); + fcr = MACIO_IN32(KEYLARGO_FCR0); + if (chan_mask & MACIO_FLAG_SCCA_ON) + fcr &= ~KL0_SCCA_ENABLE; + if (chan_mask & MACIO_FLAG_SCCB_ON) { + fcr &= ~KL0_SCCB_ENABLE; + /* Perform irda specific clears */ + if ((param & 0xfff) == PMAC_SCC_IRDA) { + fcr &= ~KL0_IRDA_ENABLE; + fcr &= ~(KL0_IRDA_CLK32_ENABLE | KL0_IRDA_CLK19_ENABLE); + fcr &= ~(KL0_IRDA_FAST_CONNECT|KL0_IRDA_DEFAULT1|KL0_IRDA_DEFAULT0); + fcr &= ~(KL0_IRDA_SOURCE1_SEL|KL0_IRDA_SOURCE2_SEL|KL0_IRDA_HIGH_BAND); + } + } + MACIO_OUT32(KEYLARGO_FCR0, fcr); + if ((fcr & (KL0_SCCA_ENABLE | KL0_SCCB_ENABLE)) == 0) { + fcr &= ~KL0_SCC_CELL_ENABLE; + MACIO_OUT32(KEYLARGO_FCR0, fcr); + } + macio->flags &= ~(chan_mask); + UNLOCK(flags); + mdelay(10); + } + return 0; +} + +static int __pmac +core99_modem_enable(struct device_node* node, int param, int value) +{ + struct macio_chip* macio; + u8 gpio; + unsigned long flags; + + macio = macio_find(node, 0); + if (!macio) + return -ENODEV; + gpio = MACIO_IN8(KL_GPIO_MODEM_RESET); + gpio |= KEYLARGO_GPIO_OUTPUT_ENABLE; + gpio &= ~KEYLARGO_GPIO_OUTOUT_DATA; + + if (!value) { + LOCK(flags); + MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio); + UNLOCK(flags); + (void)MACIO_IN8(KL_GPIO_MODEM_RESET); + mdelay(250); + } + LOCK(flags); + if (value) { + MACIO_BIC(KEYLARGO_FCR2, KL2_ALT_DATA_OUT); + UNLOCK(flags); + (void)MACIO_IN32(KEYLARGO_FCR2); + mdelay(250); + } else { + MACIO_BIS(KEYLARGO_FCR2, KL2_ALT_DATA_OUT); + UNLOCK(flags); + } + if (value) { + LOCK(flags); + MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio | KEYLARGO_GPIO_OUTOUT_DATA); + (void)MACIO_IN8(KL_GPIO_MODEM_RESET); + UNLOCK(flags); mdelay(250); LOCK(flags); + MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio); + (void)MACIO_IN8(KL_GPIO_MODEM_RESET); + UNLOCK(flags); mdelay(250); LOCK(flags); + MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio | KEYLARGO_GPIO_OUTOUT_DATA); + (void)MACIO_IN8(KL_GPIO_MODEM_RESET); + UNLOCK(flags); mdelay(250); LOCK(flags); + } + return 0; +} + +static int __pmac +core99_ide_enable(struct device_node* node, int param, int value) +{ + switch(param) { + case 0: + return simple_feature_tweak(node, macio_unknown, + KEYLARGO_FCR1, KL1_EIDE0_ENABLE, value); + case 1: + return simple_feature_tweak(node, macio_unknown, + KEYLARGO_FCR1, KL1_EIDE1_ENABLE, value); + case 2: + return simple_feature_tweak(node, macio_unknown, + KEYLARGO_FCR1, KL1_UIDE_ENABLE, value); + default: + return -ENODEV; + } +} + +static int __pmac +core99_ide_reset(struct device_node* node, int param, int value) +{ + switch(param) { + case 0: + return simple_feature_tweak(node, macio_unknown, + KEYLARGO_FCR1, KL1_EIDE0_RESET_N, !value); + case 1: + return simple_feature_tweak(node, macio_unknown, + KEYLARGO_FCR1, KL1_EIDE1_RESET_N, !value); + case 2: + return simple_feature_tweak(node, macio_unknown, + KEYLARGO_FCR1, KL1_UIDE_RESET_N, !value); + default: + return -ENODEV; + } +} + +static int __pmac +core99_gmac_enable(struct device_node* node, int param, int value) +{ + unsigned long flags; + + LOCK(flags); + if (value) + UN_BIS(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_GMAC); + else + UN_BIC(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_GMAC); + (void)UN_IN(UNI_N_CLOCK_CNTL); + UNLOCK(flags); + udelay(20); + + return 0; +} + +static int __pmac +core99_gmac_phy_reset(struct device_node* node, int param, int value) +{ + unsigned long flags; + struct macio_chip* macio; + + macio = &macio_chips[0]; + if (macio->type != macio_keylargo && macio->type != macio_pangea) + return -ENODEV; + + LOCK(flags); + MACIO_OUT8(KL_GPIO_ETH_PHY_RESET, KEYLARGO_GPIO_OUTPUT_ENABLE); + (void)MACIO_IN8(KL_GPIO_ETH_PHY_RESET); + UNLOCK(flags); + mdelay(10); + LOCK(flags); + MACIO_OUT8(KL_GPIO_ETH_PHY_RESET, KEYLARGO_GPIO_OUTPUT_ENABLE + | KEYLARGO_GPIO_OUTOUT_DATA); + UNLOCK(flags); + mdelay(10); + + return 0; +} + +static int __pmac +core99_sound_chip_enable(struct device_node* node, int param, int value) +{ + struct macio_chip* macio; + unsigned long flags; + + macio = macio_find(node, 0); + if (!macio) + return -ENODEV; + + /* Do a better probe code, screamer G4 desktops & + * iMacs can do that too, add a recalibrate in + * the driver as well + */ + if (pmac_mb.model_id == PMAC_TYPE_PISMO || + pmac_mb.model_id == PMAC_TYPE_TITANIUM) { + LOCK(flags); + if (value) + MACIO_OUT8(KL_GPIO_SOUND_POWER, + KEYLARGO_GPIO_OUTPUT_ENABLE | + KEYLARGO_GPIO_OUTOUT_DATA); + else + MACIO_OUT8(KL_GPIO_SOUND_POWER, + KEYLARGO_GPIO_OUTPUT_ENABLE); + (void)MACIO_IN8(KL_GPIO_SOUND_POWER); + UNLOCK(flags); + } + return 0; +} + +static int __pmac +core99_airport_enable(struct device_node* node, int param, int value) +{ + struct macio_chip* macio; + unsigned long flags; + int state; + + macio = macio_find(node, 0); + if (!macio) + return -ENODEV; + + /* Hint: we allow passing of macio itself for the sake of the + * sleep code + */ + if (node != macio->of_node && + (!node->parent || node->parent != macio->of_node)) + return -ENODEV; + state = (macio->flags & MACIO_FLAG_AIRPORT_ON) != 0; + if (value == state) + return 0; + if (value) { + /* This code is a reproduction of OF enable-cardslot + * and init-wireless methods, slightly hacked until + * I got it working. + */ + LOCK(flags); + MACIO_OUT8(KEYLARGO_GPIO_0+0xf, 5); + (void)MACIO_IN8(KEYLARGO_GPIO_0+0xf); + UNLOCK(flags); + mdelay(10); + LOCK(flags); + MACIO_OUT8(KEYLARGO_GPIO_0+0xf, 4); + (void)MACIO_IN8(KEYLARGO_GPIO_0+0xf); + UNLOCK(flags); + + mdelay(10); + + LOCK(flags); + MACIO_BIC(KEYLARGO_FCR2, KL2_CARDSEL_16); + (void)MACIO_IN32(KEYLARGO_FCR2); + udelay(10); + MACIO_OUT8(KEYLARGO_GPIO_EXTINT_0+0xb, 0); + (void)MACIO_IN8(KEYLARGO_GPIO_EXTINT_0+0xb); + udelay(10); + MACIO_OUT8(KEYLARGO_GPIO_EXTINT_0+0xa, 0x28); + (void)MACIO_IN8(KEYLARGO_GPIO_EXTINT_0+0xa); + udelay(10); + MACIO_OUT8(KEYLARGO_GPIO_EXTINT_0+0xd, 0x28); + (void)MACIO_IN8(KEYLARGO_GPIO_EXTINT_0+0xd); + udelay(10); + MACIO_OUT8(KEYLARGO_GPIO_0+0xd, 0x28); + (void)MACIO_IN8(KEYLARGO_GPIO_0+0xd); + udelay(10); + MACIO_OUT8(KEYLARGO_GPIO_0+0xe, 0x28); + (void)MACIO_IN8(KEYLARGO_GPIO_0+0xe); + UNLOCK(flags); + udelay(10); + MACIO_OUT32(0x1c000, 0); + mdelay(1); + MACIO_OUT8(0x1a3e0, 0x41); + (void)MACIO_IN8(0x1a3e0); + udelay(10); + LOCK(flags); + MACIO_BIS(KEYLARGO_FCR2, KL2_CARDSEL_16); + (void)MACIO_IN32(KEYLARGO_FCR2); + UNLOCK(flags); + mdelay(100); + + macio->flags |= MACIO_FLAG_AIRPORT_ON; + } else { + LOCK(flags); + MACIO_BIC(KEYLARGO_FCR2, KL2_CARDSEL_16); + (void)MACIO_IN32(KEYLARGO_FCR2); + MACIO_OUT8(KL_GPIO_AIRPORT_0, 0); + MACIO_OUT8(KL_GPIO_AIRPORT_1, 0); + MACIO_OUT8(KL_GPIO_AIRPORT_2, 0); + MACIO_OUT8(KL_GPIO_AIRPORT_3, 0); + MACIO_OUT8(KL_GPIO_AIRPORT_4, 0); + (void)MACIO_IN8(KL_GPIO_AIRPORT_4); + UNLOCK(flags); + + macio->flags &= ~MACIO_FLAG_AIRPORT_ON; + } + return 0; +} + +#ifdef CONFIG_SMP +static int __pmac +core99_reset_cpu(struct device_node* node, int param, int value) +{ + const int reset_lines[] = { KL_GPIO_RESET_CPU0, + KL_GPIO_RESET_CPU1, + KL_GPIO_RESET_CPU2, + KL_GPIO_RESET_CPU3 }; + int reset_io; + unsigned long flags; + struct macio_chip* macio; + + macio = &macio_chips[0]; + if (macio->type != macio_keylargo && macio->type != macio_pangea) + return -ENODEV; + if (param > 3 || param < 0) + return -ENODEV; + + reset_io = reset_lines[param]; + + LOCK(flags); + MACIO_OUT8(reset_io, KEYLARGO_GPIO_OUTPUT_ENABLE); + (void)MACIO_IN8(reset_io); + udelay(1); + MACIO_OUT8(reset_io, KEYLARGO_GPIO_OUTPUT_ENABLE | KEYLARGO_GPIO_OUTOUT_DATA); + (void)MACIO_IN8(reset_io); + UNLOCK(flags); + + return 0; +} +#endif /* CONFIG_SMP */ + +static int __pmac +core99_usb_enable(struct device_node* node, int param, int value) +{ + struct macio_chip* macio; + unsigned long flags; + char* prop; + int number; + u32 reg; + + macio = &macio_chips[0]; + if (macio->type != macio_keylargo && macio->type != macio_pangea) + return -ENODEV; + + prop = (char *)get_property(node, "AAPL,clock-id", NULL); + if (!prop) + return -ENODEV; + if (strncmp(prop, "usb0u048", strlen("usb0u048")) == 0) + number = 0; + else if (strncmp(prop, "usb1u148", strlen("usb1u148")) == 0) + number = 2; + else + return -ENODEV; + + /* Sorry for the brute-force locking, but this is only used during + * sleep and the timing seem to be critical + */ + LOCK(flags); + if (value) { + /* Turn ON */ + if (number == 0) { + MACIO_BIC(KEYLARGO_FCR0, (KL0_USB0_PAD_SUSPEND0 | KL0_USB0_PAD_SUSPEND1)); + (void)MACIO_IN32(KEYLARGO_FCR0); + UNLOCK(flags); + mdelay(1); + LOCK(flags); + MACIO_BIS(KEYLARGO_FCR0, KL0_USB0_CELL_ENABLE); + } else { + MACIO_BIC(KEYLARGO_FCR0, (KL0_USB1_PAD_SUSPEND0 | KL0_USB1_PAD_SUSPEND1)); + UNLOCK(flags); + (void)MACIO_IN32(KEYLARGO_FCR0); + mdelay(1); + LOCK(flags); + MACIO_BIS(KEYLARGO_FCR0, KL0_USB1_CELL_ENABLE); + } + reg = MACIO_IN32(KEYLARGO_FCR4); + reg &= ~(KL4_PORT_WAKEUP_ENABLE(number) | KL4_PORT_RESUME_WAKE_EN(number) | + KL4_PORT_CONNECT_WAKE_EN(number) | KL4_PORT_DISCONNECT_WAKE_EN(number)); + reg &= ~(KL4_PORT_WAKEUP_ENABLE(number+1) | KL4_PORT_RESUME_WAKE_EN(number+1) | + KL4_PORT_CONNECT_WAKE_EN(number+1) | KL4_PORT_DISCONNECT_WAKE_EN(number+1)); + MACIO_OUT32(KEYLARGO_FCR4, reg); + (void)MACIO_IN32(KEYLARGO_FCR4); + udelay(10); + } else { + /* Turn OFF */ + reg = MACIO_IN32(KEYLARGO_FCR4); + reg |= KL4_PORT_WAKEUP_ENABLE(number) | KL4_PORT_RESUME_WAKE_EN(number) | + KL4_PORT_CONNECT_WAKE_EN(number) | KL4_PORT_DISCONNECT_WAKE_EN(number); + reg |= KL4_PORT_WAKEUP_ENABLE(number+1) | KL4_PORT_RESUME_WAKE_EN(number+1) | + KL4_PORT_CONNECT_WAKE_EN(number+1) | KL4_PORT_DISCONNECT_WAKE_EN(number+1); + MACIO_OUT32(KEYLARGO_FCR4, reg); + (void)MACIO_IN32(KEYLARGO_FCR4); + udelay(1); + if (number == 0) { + MACIO_BIC(KEYLARGO_FCR0, KL0_USB0_CELL_ENABLE); + (void)MACIO_IN32(KEYLARGO_FCR0); + udelay(1); + MACIO_BIS(KEYLARGO_FCR0, (KL0_USB0_PAD_SUSPEND0 | KL0_USB0_PAD_SUSPEND1)); + (void)MACIO_IN32(KEYLARGO_FCR0); + } else { + MACIO_BIC(KEYLARGO_FCR0, KL0_USB1_CELL_ENABLE); + (void)MACIO_IN32(KEYLARGO_FCR0); + udelay(1); + MACIO_BIS(KEYLARGO_FCR0, (KL0_USB1_PAD_SUSPEND0 | KL0_USB1_PAD_SUSPEND1)); + (void)MACIO_IN32(KEYLARGO_FCR0); + } + udelay(1); + } + UNLOCK(flags); + + return 0; +} + +static int __pmac +core99_firewire_enable(struct device_node* node, int param, int value) +{ + unsigned long flags; + struct macio_chip* macio; + + macio = &macio_chips[0]; + if (macio->type != macio_keylargo && macio->type != macio_pangea) + return -ENODEV; + if (!(macio->flags & MACIO_FLAG_FW_SUPPORTED)) + return -ENODEV; + + LOCK(flags); + if (value) { + UN_BIS(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_FW); + (void)UN_IN(UNI_N_CLOCK_CNTL); + } else { + UN_BIC(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_FW); + (void)UN_IN(UNI_N_CLOCK_CNTL); + } + UNLOCK(flags); + mdelay(1); + + return 0; +} + +static int __pmac +core99_firewire_cable_power(struct device_node* node, int param, int value) +{ + unsigned long flags; + struct macio_chip* macio; + + /* Trick: we allow NULL node */ + if ((pmac_mb.board_flags & PMAC_MB_HAS_FW_POWER) == 0) + return -ENODEV; + macio = &macio_chips[0]; + if (macio->type != macio_keylargo && macio->type != macio_pangea) + return -ENODEV; + if (!(macio->flags & MACIO_FLAG_FW_SUPPORTED)) + return -ENODEV; + + LOCK(flags); + if (value) { + MACIO_OUT8(KL_GPIO_FW_CABLE_POWER , 0); + MACIO_IN8(KL_GPIO_FW_CABLE_POWER); + udelay(10); + } else { + MACIO_OUT8(KL_GPIO_FW_CABLE_POWER , 4); + MACIO_IN8(KL_GPIO_FW_CABLE_POWER); udelay(10); + } + UNLOCK(flags); + mdelay(1); + + return 0; +} + +static int __pmac +core99_read_gpio(struct device_node* node, int param, int value) +{ + struct macio_chip* macio = &macio_chips[0]; + + return MACIO_IN8(param); +} + + +static int __pmac +core99_write_gpio(struct device_node* node, int param, int value) +{ + struct macio_chip* macio = &macio_chips[0]; + + MACIO_OUT8(param, (u8)(value & 0xff)); + return 0; +} + +static void __pmac +keylargo_shutdown(struct macio_chip* macio, int restart) +{ + u32 temp; + + mdelay(1); + MACIO_BIS(KEYLARGO_FCR0, KL0_USB_REF_SUSPEND); + (void)MACIO_IN32(KEYLARGO_FCR0); + mdelay(100); + + MACIO_BIC(KEYLARGO_FCR0,KL0_SCCA_ENABLE | KL0_SCCB_ENABLE | + KL0_SCC_CELL_ENABLE | + KL0_IRDA_ENABLE | KL0_IRDA_CLK32_ENABLE | + KL0_IRDA_CLK19_ENABLE); + + (void)MACIO_IN32(KEYLARGO_FCR0); udelay(10); + MACIO_BIC(KEYLARGO_MBCR, KL_MBCR_MB0_DEV_MASK); + (void)MACIO_IN32(KEYLARGO_MBCR); udelay(10); + + MACIO_BIC(KEYLARGO_FCR1, + KL1_AUDIO_SEL_22MCLK | KL1_AUDIO_CLK_ENABLE_BIT | + KL1_AUDIO_CLK_OUT_ENABLE | KL1_AUDIO_CELL_ENABLE | + KL1_I2S0_CELL_ENABLE | KL1_I2S0_CLK_ENABLE_BIT | + KL1_I2S0_ENABLE | KL1_I2S1_CELL_ENABLE | + KL1_I2S1_CLK_ENABLE_BIT | KL1_I2S1_ENABLE | + KL1_EIDE0_ENABLE | KL1_EIDE0_RESET_N | + KL1_EIDE1_ENABLE | KL1_EIDE1_RESET_N | + KL1_UIDE_ENABLE); + (void)MACIO_IN32(KEYLARGO_FCR1); udelay(10); + + MACIO_BIS(KEYLARGO_FCR2, KL2_ALT_DATA_OUT); + udelay(10); + MACIO_BIC(KEYLARGO_FCR2, KL2_IOBUS_ENABLE); + udelay(10); + temp = MACIO_IN32(KEYLARGO_FCR3); + if (macio->rev >= 2) + temp |= (KL3_SHUTDOWN_PLL2X | KL3_SHUTDOWN_PLL_TOTAL); + + temp |= KL3_SHUTDOWN_PLLKW6 | KL3_SHUTDOWN_PLLKW4 | + KL3_SHUTDOWN_PLLKW35 | KL3_SHUTDOWN_PLLKW12; + temp &= ~(KL3_CLK66_ENABLE | KL3_CLK49_ENABLE | KL3_CLK45_ENABLE + | KL3_CLK31_ENABLE | KL3_TIMER_CLK18_ENABLE | KL3_I2S1_CLK18_ENABLE + | KL3_I2S0_CLK18_ENABLE | KL3_VIA_CLK16_ENABLE); + MACIO_OUT32(KEYLARGO_FCR3, temp); + (void)MACIO_IN32(KEYLARGO_FCR3); udelay(10); +} + +static void __pmac +pangea_shutdown(struct macio_chip* macio, int restart) +{ + u32 temp; + + MACIO_BIC(KEYLARGO_FCR0,KL0_SCCA_ENABLE | KL0_SCCB_ENABLE | + KL0_SCC_CELL_ENABLE | + KL0_USB0_CELL_ENABLE | KL0_USB1_CELL_ENABLE); + + (void)MACIO_IN32(KEYLARGO_FCR0); udelay(10); + MACIO_BIC(KEYLARGO_MBCR, KL_MBCR_MB0_DEV_MASK); + (void)MACIO_IN32(KEYLARGO_MBCR); udelay(10); + + MACIO_BIC(KEYLARGO_FCR1, + KL1_AUDIO_SEL_22MCLK | KL1_AUDIO_CLK_ENABLE_BIT | + KL1_AUDIO_CLK_OUT_ENABLE | KL1_AUDIO_CELL_ENABLE | + KL1_I2S0_CELL_ENABLE | KL1_I2S0_CLK_ENABLE_BIT | + KL1_I2S0_ENABLE | KL1_I2S1_CELL_ENABLE | + KL1_I2S1_CLK_ENABLE_BIT | KL1_I2S1_ENABLE | + KL1_UIDE_ENABLE); + (void)MACIO_IN32(KEYLARGO_FCR1); udelay(10); + + MACIO_BIS(KEYLARGO_FCR2, KL2_ALT_DATA_OUT); + udelay(10); + temp = MACIO_IN32(KEYLARGO_FCR3); + temp |= KL3_SHUTDOWN_PLLKW6 | KL3_SHUTDOWN_PLLKW4 | + KL3_SHUTDOWN_PLLKW35; + temp &= ~(KL3_CLK49_ENABLE | KL3_CLK45_ENABLE + | KL3_CLK31_ENABLE | KL3_TIMER_CLK18_ENABLE | KL3_I2S1_CLK18_ENABLE + | KL3_I2S0_CLK18_ENABLE | KL3_VIA_CLK16_ENABLE); + MACIO_OUT32(KEYLARGO_FCR3, temp); + (void)MACIO_IN32(KEYLARGO_FCR3); udelay(10); +} + +static int __pmac +core99_sleep(void) +{ + struct macio_chip* macio; + int i; + + macio = &macio_chips[0]; + if (macio->type != macio_keylargo && macio->type != macio_pangea) + return -ENODEV; + + /* We power off the wireless slot in case it was not done + * by the driver. We don't power it on automatically however + */ + if (macio->flags & MACIO_FLAG_AIRPORT_ON) + core99_airport_enable(macio->of_node, 0, 0); + + /* We power off the FW cable. Should be done by the driver... */ + if (macio->flags & MACIO_FLAG_FW_SUPPORTED) { + core99_firewire_enable(NULL, 0, 0); + core99_firewire_cable_power(NULL, 0, 0); + } + + /* We make sure int. modem is off (in case driver lost it) */ + core99_modem_enable(macio->of_node, 0, 0); + /* We make sure the sound is off as well */ + core99_sound_chip_enable(macio->of_node, 0, 0); + + /* + * Save various bits of KeyLargo + */ + + /* Save the state of the various GPIOs */ + save_gpio_levels[0] = MACIO_IN32(KEYLARGO_GPIO_LEVELS0); + save_gpio_levels[1] = MACIO_IN32(KEYLARGO_GPIO_LEVELS1); + for (i=0; i<KEYLARGO_GPIO_EXTINT_CNT; i++) + save_gpio_extint[i] = MACIO_IN8(KEYLARGO_GPIO_EXTINT_0+i); + for (i=0; i<KEYLARGO_GPIO_CNT; i++) + save_gpio_normal[i] = MACIO_IN8(KEYLARGO_GPIO_0+i); + + /* Save the FCRs */ + save_mbcr = MACIO_IN32(KEYLARGO_MBCR); + save_fcr[0] = MACIO_IN32(KEYLARGO_FCR0); + save_fcr[1] = MACIO_IN32(KEYLARGO_FCR1); + save_fcr[2] = MACIO_IN32(KEYLARGO_FCR2); + save_fcr[3] = MACIO_IN32(KEYLARGO_FCR3); + save_fcr[4] = MACIO_IN32(KEYLARGO_FCR4); + + /* Save state & config of DBDMA channels */ + dbdma_save(macio, save_dbdma); + + /* + * Turn off as much as we can + */ + if (macio->type == macio_pangea) + pangea_shutdown(macio, 0); + else if (macio->type == macio_keylargo) + keylargo_shutdown(macio, 0); + + /* + * Put the host bridge to sleep + */ + + save_unin_clock_ctl = UN_IN(UNI_N_CLOCK_CNTL); + UN_OUT(UNI_N_CLOCK_CNTL, save_unin_clock_ctl & + ~(UNI_N_CLOCK_CNTL_GMAC|UNI_N_CLOCK_CNTL_FW/*|UNI_N_CLOCK_CNTL_PCI*/)); + udelay(100); + UN_OUT(UNI_N_HWINIT_STATE, UNI_N_HWINIT_STATE_SLEEPING); + UN_OUT(UNI_N_POWER_MGT, UNI_N_POWER_MGT_SLEEP); + + /* + * FIXME: A bit of black magic with OpenPIC (don't ask me why) + */ + if (pmac_mb.model_id == PMAC_TYPE_SAWTOOTH) { + MACIO_BIS(0x506e0, 0x00400000); + MACIO_BIS(0x506e0, 0x80000000); + } + return 0; +} + +static int __pmac +core99_wake_up(void) +{ + struct macio_chip* macio; + int i; + + macio = &macio_chips[0]; + if (macio->type != macio_keylargo && macio->type != macio_pangea) + return -ENODEV; + + /* + * Wakeup the host bridge + */ + UN_OUT(UNI_N_POWER_MGT, UNI_N_POWER_MGT_NORMAL); + udelay(10); + UN_OUT(UNI_N_HWINIT_STATE, UNI_N_HWINIT_STATE_RUNNING); + udelay(10); + + /* + * Restore KeyLargo + */ + + MACIO_OUT32(KEYLARGO_MBCR, save_mbcr); + (void)MACIO_IN32(KEYLARGO_MBCR); udelay(10); + MACIO_OUT32(KEYLARGO_FCR0, save_fcr[0]); + (void)MACIO_IN32(KEYLARGO_FCR0); udelay(10); + MACIO_OUT32(KEYLARGO_FCR1, save_fcr[1]); + (void)MACIO_IN32(KEYLARGO_FCR1); udelay(10); + MACIO_OUT32(KEYLARGO_FCR2, save_fcr[2]); + (void)MACIO_IN32(KEYLARGO_FCR2); udelay(10); + MACIO_OUT32(KEYLARGO_FCR3, save_fcr[3]); + (void)MACIO_IN32(KEYLARGO_FCR3); udelay(10); + MACIO_OUT32(KEYLARGO_FCR4, save_fcr[4]); + (void)MACIO_IN32(KEYLARGO_FCR4); udelay(10); + + dbdma_restore(macio, save_dbdma); + + MACIO_OUT32(KEYLARGO_GPIO_LEVELS0, save_gpio_levels[0]); + MACIO_OUT32(KEYLARGO_GPIO_LEVELS1, save_gpio_levels[1]); + for (i=0; i<KEYLARGO_GPIO_EXTINT_CNT; i++) + MACIO_OUT8(KEYLARGO_GPIO_EXTINT_0+i, save_gpio_extint[i]); + for (i=0; i<KEYLARGO_GPIO_CNT; i++) + MACIO_OUT8(KEYLARGO_GPIO_0+i, save_gpio_normal[i]); + + /* FIXME more black magic with OpenPIC ... */ + if (pmac_mb.model_id == PMAC_TYPE_SAWTOOTH) { + MACIO_BIC(0x506e0, 0x00400000); + MACIO_BIC(0x506e0, 0x80000000); + } + + UN_OUT(UNI_N_CLOCK_CNTL, save_unin_clock_ctl); + udelay(100); + + return 0; +} + +static int __pmac +core99_sleep_state(struct device_node* node, int param, int value) +{ + if ((pmac_mb.board_flags & PMAC_MB_CAN_SLEEP) == 0) + return -EPERM; + if (value == 1) + return core99_sleep(); + else if (value == 0) + return core99_wake_up(); + return 0; +} + +static int __pmac +pangea_modem_enable(struct device_node* node, int param, int value) +{ + struct macio_chip* macio; + u8 gpio; + unsigned long flags; + + macio = macio_find(node, 0); + if (!macio) + return -ENODEV; + gpio = MACIO_IN8(KL_GPIO_MODEM_RESET); + gpio |= KEYLARGO_GPIO_OUTPUT_ENABLE; + gpio &= ~KEYLARGO_GPIO_OUTOUT_DATA; + + if (!value) { + LOCK(flags); + MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio); + UNLOCK(flags); + (void)MACIO_IN8(KL_GPIO_MODEM_RESET); + mdelay(250); + } + LOCK(flags); + if (value) { + MACIO_OUT8(KL_GPIO_MODEM_POWER, + KEYLARGO_GPIO_OUTPUT_ENABLE); + UNLOCK(flags); + (void)MACIO_IN32(KEYLARGO_FCR2); + mdelay(250); + } else { + MACIO_OUT8(KL_GPIO_MODEM_POWER, + KEYLARGO_GPIO_OUTPUT_ENABLE | KEYLARGO_GPIO_OUTOUT_DATA); + UNLOCK(flags); + } + if (value) { + LOCK(flags); + MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio | KEYLARGO_GPIO_OUTOUT_DATA); + (void)MACIO_IN8(KL_GPIO_MODEM_RESET); + UNLOCK(flags); mdelay(250); LOCK(flags); + MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio); + (void)MACIO_IN8(KL_GPIO_MODEM_RESET); + UNLOCK(flags); mdelay(250); LOCK(flags); + MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio | KEYLARGO_GPIO_OUTOUT_DATA); + (void)MACIO_IN8(KL_GPIO_MODEM_RESET); + UNLOCK(flags); mdelay(250); LOCK(flags); + } + return 0; +} + + +static int __pmac +generic_get_mb_info(struct device_node* node, int param, int value) +{ + switch(param) { + case PMAC_MB_INFO_MODEL: + return pmac_mb.model_id; + case PMAC_MB_INFO_FLAGS: + return pmac_mb.board_flags; + case PMAC_MB_INFO_NAME: + /* hack hack hack... but should work */ + return (int)pmac_mb.model_name; + } + return 0; +} + + +/* + * Table definitions + */ + +/* Used on any machine + */ +static struct feature_table_entry any_features[] __pmacdata = { + { PMAC_FTR_GET_MB_INFO, generic_get_mb_info }, + { 0, NULL } +}; + +/* OHare based motherboards. Currently, we only use these on the + * 2400,3400 and 3500 series powerbooks. Some older desktops seem + * to have issues with turning on/off those asic cells + */ +static struct feature_table_entry ohare_features[] __pmacdata = { + { PMAC_FTR_SCC_ENABLE, ohare_scc_enable }, + { PMAC_FTR_SWIM3_ENABLE, ohare_floppy_enable }, + { PMAC_FTR_MESH_ENABLE, ohare_mesh_enable }, + { PMAC_FTR_IDE_ENABLE, ohare_ide_enable}, + { PMAC_FTR_IDE_RESET, ohare_ide_reset}, + { PMAC_FTR_SLEEP_STATE, ohare_sleep_state }, + { 0, NULL } +}; + +/* Heathrow desktop machines (Beige G3). + * Separated as some features couldn't be properly tested + * and the serial port control bits appear to confuse it. + */ +static struct feature_table_entry heathrow_desktop_features[] __pmacdata = { + { PMAC_FTR_SWIM3_ENABLE, heathrow_floppy_enable }, + { PMAC_FTR_MESH_ENABLE, heathrow_mesh_enable }, + { PMAC_FTR_IDE_ENABLE, heathrow_ide_enable }, + { PMAC_FTR_IDE_RESET, heathrow_ide_reset }, + { PMAC_FTR_BMAC_ENABLE, heathrow_bmac_enable }, + { 0, NULL } +}; + +/* Heathrow based laptop, that is the Wallstreet and mainstreet + * powerbooks. + */ +static struct feature_table_entry heathrow_laptop_features[] __pmacdata = { + { PMAC_FTR_SCC_ENABLE, heathrow_scc_enable }, + { PMAC_FTR_MODEM_ENABLE, heathrow_modem_enable }, + { PMAC_FTR_SWIM3_ENABLE, heathrow_floppy_enable }, + { PMAC_FTR_MESH_ENABLE, heathrow_mesh_enable }, + { PMAC_FTR_IDE_ENABLE, heathrow_ide_enable }, + { PMAC_FTR_IDE_RESET, heathrow_ide_reset }, + { PMAC_FTR_BMAC_ENABLE, heathrow_bmac_enable }, + { PMAC_FTR_SOUND_CHIP_ENABLE, heathrow_sound_enable }, + { PMAC_FTR_SLEEP_STATE, heathrow_sleep_state }, + { 0, NULL } +}; + +/* Paddington based machines + * The lombard (101) powerbook, first iMac models, B&W G3 and Yikes G4. + */ +static struct feature_table_entry paddington_features[] __pmacdata = { + { PMAC_FTR_SCC_ENABLE, heathrow_scc_enable }, + { PMAC_FTR_MODEM_ENABLE, heathrow_modem_enable }, + { PMAC_FTR_SWIM3_ENABLE, heathrow_floppy_enable }, + { PMAC_FTR_MESH_ENABLE, heathrow_mesh_enable }, + { PMAC_FTR_IDE_ENABLE, heathrow_ide_enable }, + { PMAC_FTR_IDE_RESET, heathrow_ide_reset }, + { PMAC_FTR_BMAC_ENABLE, heathrow_bmac_enable }, + { PMAC_FTR_SOUND_CHIP_ENABLE, heathrow_sound_enable }, + { PMAC_FTR_SLEEP_STATE, heathrow_sleep_state }, + { 0, NULL } +}; + +/* Core99 & MacRISC 2 machines (all machines released since the + * iBook (included), that is all AGP machines, except pangea + * chipset. The pangea chipset is the "combo" UniNorth/KeyLargo + * used on iBook2 & iMac "flow power". + */ +static struct feature_table_entry core99_features[] __pmacdata = { + { PMAC_FTR_SCC_ENABLE, core99_scc_enable }, + { PMAC_FTR_MODEM_ENABLE, core99_modem_enable }, + { PMAC_FTR_IDE_ENABLE, core99_ide_enable }, + { PMAC_FTR_IDE_RESET, core99_ide_reset }, + { PMAC_FTR_GMAC_ENABLE, core99_gmac_enable }, + { PMAC_FTR_GMAC_PHY_RESET, core99_gmac_phy_reset }, + { PMAC_FTR_SOUND_CHIP_ENABLE, core99_sound_chip_enable }, + { PMAC_FTR_AIRPORT_ENABLE, core99_airport_enable }, + { PMAC_FTR_USB_ENABLE, core99_usb_enable }, + { PMAC_FTR_1394_ENABLE, core99_firewire_enable }, + { PMAC_FTR_1394_CABLE_POWER, core99_firewire_cable_power }, + { PMAC_FTR_SLEEP_STATE, core99_sleep_state }, +#ifdef CONFIG_SMP + { PMAC_FTR_RESET_CPU, core99_reset_cpu }, +#endif /* CONFIG_SMP */ + { PMAC_FTR_READ_GPIO, core99_read_gpio }, + { PMAC_FTR_WRITE_GPIO, core99_write_gpio }, + { 0, NULL } +}; + +/* Pangea features + */ +static struct feature_table_entry pangea_features[] __pmacdata = { + { PMAC_FTR_SCC_ENABLE, core99_scc_enable }, + { PMAC_FTR_MODEM_ENABLE, pangea_modem_enable }, + { PMAC_FTR_IDE_ENABLE, core99_ide_enable }, + { PMAC_FTR_IDE_RESET, core99_ide_reset }, + { PMAC_FTR_GMAC_ENABLE, core99_gmac_enable }, + { PMAC_FTR_GMAC_PHY_RESET, core99_gmac_phy_reset }, + { PMAC_FTR_SOUND_CHIP_ENABLE, core99_sound_chip_enable }, + { PMAC_FTR_AIRPORT_ENABLE, core99_airport_enable }, + { PMAC_FTR_USB_ENABLE, core99_usb_enable }, + { PMAC_FTR_1394_ENABLE, core99_firewire_enable }, + { PMAC_FTR_1394_CABLE_POWER, core99_firewire_cable_power }, + { PMAC_FTR_SLEEP_STATE, core99_sleep_state }, + { PMAC_FTR_READ_GPIO, core99_read_gpio }, + { PMAC_FTR_WRITE_GPIO, core99_write_gpio }, + { 0, NULL } +}; + +static struct pmac_mb_def pmac_mb_defs[] __pmacdata = { + /* Warning: ordering is important as some models may claim + * beeing compatible with several types + */ + { "AAPL,8500", "PowerMac 8500/8600", + PMAC_TYPE_PSURGE, NULL, + 0 + }, + { "AAPL,9500", "PowerMac 9500/9600", + PMAC_TYPE_PSURGE, NULL, + 0 + }, + { "AAPL,7500", "PowerMac 7500", + PMAC_TYPE_PSURGE, NULL, + 0 + }, + { "AAPL,e407", "Alchemy", + PMAC_TYPE_ALCHEMY, NULL, + 0 + }, + { "AAPL,e411", "Gazelle", + PMAC_TYPE_GAZELLE, NULL, + 0 + }, + { "AAPL,3400/2400", "PowerBook 3400", + PMAC_TYPE_HOOPER, ohare_features, + PMAC_MB_CAN_SLEEP + }, + { "AAPL,3500", "PowerBook 3500", + PMAC_TYPE_KANGA, ohare_features, + PMAC_MB_CAN_SLEEP + }, + { "AAPL,Gossamer", "PowerMac G3 (Gossamer)", + PMAC_TYPE_GOSSAMER, heathrow_desktop_features, + 0 + }, + { "AAPL,PowerMac G3", "PowerMac G3 (Silk)", + PMAC_TYPE_SILK, heathrow_desktop_features, + 0 + }, + { "AAPL,PowerBook1998", "PowerBook Wallstreet", + PMAC_TYPE_WALLSTREET, heathrow_laptop_features, + PMAC_MB_CAN_SLEEP + }, + { "AAPL,PowerBook1,1", "PowerBook 101 (Lombard)", + PMAC_TYPE_101_PBOOK, paddington_features, + PMAC_MB_CAN_SLEEP + }, + { "iMac,1", "iMac (first generation)", + PMAC_TYPE_ORIG_IMAC, paddington_features, + 0 + }, + { "PowerMac4,1", "iMac \"Flower Power\"", + PMAC_TYPE_PANGEA_IMAC, pangea_features, + PMAC_MB_CAN_SLEEP + }, + { "PowerBook4,1", "iBook 2", + PMAC_TYPE_IBOOK2, pangea_features, + PMAC_MB_CAN_SLEEP | PMAC_MB_HAS_FW_POWER + }, + { "PowerMac4,2", "Flat panel iMac", + PMAC_TYPE_FLAT_PANEL_IMAC, pangea_features, + PMAC_MB_CAN_SLEEP + }, + { "PowerMac1,1", "Blue&White G3", + PMAC_TYPE_YOSEMITE, paddington_features, + 0 + }, + { "PowerMac1,2", "PowerMac G4 PCI Graphics", + PMAC_TYPE_YIKES, paddington_features, + 0 + }, + { "PowerBook2,1", "iBook (first generation)", + PMAC_TYPE_ORIG_IBOOK, core99_features, + PMAC_MB_CAN_SLEEP + }, + { "PowerMac3,1", "PowerMac G4 AGP Graphics", + PMAC_TYPE_SAWTOOTH, core99_features, + 0 + }, + { "PowerMac3,2", "PowerMac G4 AGP Graphics", + PMAC_TYPE_SAWTOOTH, core99_features, + 0 + }, + { "PowerMac3,3", "PowerMac G4 AGP Graphics", + PMAC_TYPE_SAWTOOTH, core99_features, + 0 + }, + { "PowerMac2,1", "iMac FireWire", + PMAC_TYPE_FW_IMAC, core99_features, + PMAC_MB_CAN_SLEEP + }, + { "PowerMac2,2", "iMac FireWire", + PMAC_TYPE_FW_IMAC, core99_features, + PMAC_MB_CAN_SLEEP + }, + { "PowerBook2,2", "iBook FireWire", + PMAC_TYPE_FW_IBOOK, core99_features, + PMAC_MB_CAN_SLEEP | PMAC_MB_HAS_FW_POWER + }, + { "PowerMac5,1", "PowerMac G4 Cube", + PMAC_TYPE_CUBE, core99_features, + }, + { "PowerMac3,4", "PowerMac G4 Silver", + PMAC_TYPE_QUICKSILVER, core99_features, + 0 + }, + { "PowerMac3,5", "PowerMac G4 Silver", + PMAC_TYPE_QUICKSILVER, core99_features, + 0 + }, + { "PowerBook3,1", "PowerBook Pismo", + PMAC_TYPE_PISMO, core99_features, + PMAC_MB_CAN_SLEEP | PMAC_MB_HAS_FW_POWER + }, + { "PowerBook3,2", "PowerBook Titanium", + PMAC_TYPE_TITANIUM, core99_features, + PMAC_MB_CAN_SLEEP | PMAC_MB_HAS_FW_POWER + }, + { "PowerBook3,3", "PowerBook Titanium II", + PMAC_TYPE_TITANIUM2, core99_features, + PMAC_MB_CAN_SLEEP | PMAC_MB_HAS_FW_POWER + }, +}; + +/* + * The toplevel feature_call callback + */ +int __pmac +pmac_do_feature_call(unsigned int selector, ...) +{ + struct device_node* node; + int param, value, i; + feature_call func = NULL; + va_list args; + + if (!pmac_mb.features) + return -ENODEV; + for (i=0; pmac_mb.features[i].function; i++) + if (pmac_mb.features[i].selector == selector) { + func = pmac_mb.features[i].function; + break; + } + if (!func) + for (i=0; any_features[i].function; i++) + if (any_features[i].selector == selector) { + func = any_features[i].function; + break; + } + if (!func) + return -ENODEV; + + va_start(args, selector); + node = (struct device_node*)va_arg(args, void*); + param = va_arg(args, int); + value = va_arg(args, int); + va_end(args); + + return func(node, param, value); +} + +static int __init +probe_motherboard(void) +{ + int i; + struct macio_chip* macio = &macio_chips[0]; + + /* Lookup known motherboard type in device-tree */ + for(i=0; i<(sizeof(pmac_mb_defs)/sizeof(struct pmac_mb_def)); i++) { + if (machine_is_compatible(pmac_mb_defs[i].model_string)) { + pmac_mb = pmac_mb_defs[i]; + goto found; + } + } + + /* Fallback to selection depending on mac-io chip type */ + switch(macio->type) { + case macio_grand_central: + pmac_mb.model_id = PMAC_TYPE_PSURGE; + pmac_mb.model_name = "Unknown PowerSurge"; + break; + case macio_ohare: + pmac_mb.model_id = PMAC_TYPE_UNKNOWN_OHARE; + pmac_mb.model_name = "Unknown OHare-based"; + break; + case macio_heathrow: + pmac_mb.model_id = PMAC_TYPE_UNKNOWN_HEATHROW; + pmac_mb.model_name = "Unknown Heathrow-based"; + pmac_mb.features = heathrow_desktop_features; + break; + case macio_paddington: + pmac_mb.model_id = PMAC_TYPE_UNKNOWN_PADDINGTON; + pmac_mb.model_name = "Unknown Paddington-based"; + pmac_mb.features = paddington_features; + break; + case macio_keylargo: + pmac_mb.model_id = PMAC_TYPE_UNKNOWN_CORE99; + pmac_mb.model_name = "Unknown Keylargo-based"; + pmac_mb.features = core99_features; + break; + case macio_pangea: + pmac_mb.model_id = PMAC_TYPE_UNKNOWN_PANGEA; + pmac_mb.model_name = "Unknown Pangea-based"; + pmac_mb.features = pangea_features; + break; + default: + return -ENODEV; + } +found: + /* Fixup Hooper vs. Comet */ + if (pmac_mb.model_id == PMAC_TYPE_HOOPER) { + u32* mach_id_ptr = (u32*)ioremap(0xf3000034, 4); + if (!mach_id_ptr) + return -ENODEV; + /* Here, I used to disable the media-bay on comet. It + * appears this is wrong, the floppy connector is actually + * a kind of media-bay and works with the current driver. + */ + if ((*mach_id_ptr) & 0x20000000UL) + pmac_mb.model_id = PMAC_TYPE_COMET; + iounmap(mach_id_ptr); + } + + /* Set default value of powersave_nap on machines that support it. + * It appears that uninorth rev 3 has a problem with it, we don't + * enable it on those. In theory, the flush-on-lock property is + * supposed to be set when not supported, but I'm not very confident + * that all Apple OF revs did it properly, I do it the paranoid way. + */ + while (uninorth_base && uninorth_rev > 3) { + struct device_node* np = find_path_device("/cpus"); + u32 pvr = mfspr(PVR); + if (!np || !np->child) { + printk(KERN_WARNING "Can't find CPU(s) in device tree !\n"); + break; + } + np = np->child; + /* Nap mode not supported on SMP */ + if (np->sibling) + break; + /* Nap mode not supported if flush-on-lock property is present */ + if (get_property(np, "flush-on-lock", NULL)) + break; + /* Some 7450 may have problem with NAP mode too ... */ + if (((pvr >> 16) == 0x8000) && ((pvr & 0xffff) < 0x0201)) + break; + powersave_nap = 1; + printk(KERN_INFO "Processor NAP mode on idle enabled.\n"); + break; + } + + printk(KERN_INFO "PowerMac motherboard: %s\n", pmac_mb.model_name); + return 0; +} + +/* Initialize the Core99 UniNorth host bridge and memory controller + */ +static void __init +probe_uninorth(void) +{ + unsigned long actrl; + + /* Locate core99 Uni-N */ + uninorth_node = find_devices("uni-n"); + if (uninorth_node && uninorth_node->n_addrs > 0) { + uninorth_base = ioremap(uninorth_node->addrs[0].address, 0x1000); + uninorth_rev = in_be32(UN_REG(UNI_N_VERSION)); + } else + uninorth_node = NULL; + + if (!uninorth_node) + return; + + printk(KERN_INFO "Found Uninorth memory controller & host bridge, revision: %d\n", + uninorth_rev); + + /* Set the arbitrer QAck delay according to what Apple does + */ + if (uninorth_rev < 0x10) { + actrl = UN_IN(UNI_N_ARB_CTRL) & ~UNI_N_ARB_CTRL_QACK_DELAY_MASK; + actrl |= ((uninorth_rev < 3) ? UNI_N_ARB_CTRL_QACK_DELAY105 : + UNI_N_ARB_CTRL_QACK_DELAY) << UNI_N_ARB_CTRL_QACK_DELAY_SHIFT; + UN_OUT(UNI_N_ARB_CTRL, actrl); + } +} + +static void __init +probe_one_macio(const char* name, const char* compat, int type) +{ + struct device_node* node; + int i; + volatile u32* base; + u32* revp; + + node = find_devices(name); + if (!node || !node->n_addrs) + return; + if (compat) + do { + if (device_is_compatible(node, compat)) + break; + node = node->next; + } while (node); + if (!node) + return; + for(i=0; i<MAX_MACIO_CHIPS; i++) { + if (!macio_chips[i].of_node) + break; + if (macio_chips[i].of_node == node) + return; + } + if (i >= MAX_MACIO_CHIPS) { + printk(KERN_ERR "pmac_feature: Please increase MAX_MACIO_CHIPS !\n"); + printk(KERN_ERR "pmac_feature: %s skipped\n", node->full_name); + return; + } + base = (volatile u32*)ioremap(node->addrs[0].address, node->addrs[0].size); + if (!base) { + printk(KERN_ERR "pmac_feature: Can't map mac-io chip !\n"); + return; + } + if (type == macio_keylargo) { + u32* did = (u32 *)get_property(node, "device-id", NULL); + if (*did == 0x00000025) + type = macio_pangea; + } + macio_chips[i].of_node = node; + macio_chips[i].type = type; + macio_chips[i].base = base; + macio_chips[i].flags = MACIO_FLAG_SCCB_ON | MACIO_FLAG_SCCB_ON; + revp = (u32 *)get_property(node, "revision-id", NULL); + if (revp) + macio_chips[i].rev = *revp; + printk(KERN_INFO "Found a %s mac-io controller, rev: %d, mapped at 0x%p\n", + macio_names[type], macio_chips[i].rev, macio_chips[i].base); +} + +static int __init +probe_macios(void) +{ + /* Warning, ordering is important */ + probe_one_macio("gc", NULL, macio_grand_central); + probe_one_macio("ohare", NULL, macio_ohare); + probe_one_macio("pci106b,7", NULL, macio_ohareII); + probe_one_macio("mac-io", "keylargo", macio_keylargo); + probe_one_macio("mac-io", "paddington", macio_paddington); + probe_one_macio("mac-io", "gatwick", macio_gatwick); + probe_one_macio("mac-io", "heathrow", macio_heathrow); + + /* Make sure the "main" macio chip appear first */ + if (macio_chips[0].type == macio_gatwick + && macio_chips[1].type == macio_heathrow) { + struct macio_chip temp = macio_chips[0]; + macio_chips[0] = macio_chips[1]; + macio_chips[1] = temp; + } + if (macio_chips[0].type == macio_ohareII + && macio_chips[1].type == macio_ohare) { + struct macio_chip temp = macio_chips[0]; + macio_chips[0] = macio_chips[1]; + macio_chips[1] = temp; + } + + return (macio_chips[0].of_node == NULL) ? -ENODEV : 0; +} + +static void __init +initial_serial_shutdown(struct device_node* np) +{ + int len; + struct slot_names_prop { + int count; + char name[1]; + } *slots; + char *conn; + int port_type = PMAC_SCC_ASYNC; + int modem = 0; + + slots = (struct slot_names_prop *)get_property(np, "slot-names", &len); + conn = get_property(np, "AAPL,connector", &len); + if (conn && (strcmp(conn, "infrared") == 0)) + port_type = PMAC_SCC_IRDA; + else if (device_is_compatible(np, "cobalt")) + modem = 1; + else if (slots && slots->count > 0) { + if (strcmp(slots->name, "IrDA") == 0) + port_type = PMAC_SCC_IRDA; + else if (strcmp(slots->name, "Modem") == 0) + modem = 1; + } + if (modem) + pmac_call_feature(PMAC_FTR_MODEM_ENABLE, np, 0, 0); + pmac_call_feature(PMAC_FTR_SCC_ENABLE, np, port_type, 0); +} + +static void __init +set_initial_features(void) +{ + struct device_node* np; + + /* That hack appears to be necessary for some StarMax motherboards + * but I'm not too sure it was audited for side-effects on other + * ohare based machines... + * Since I still have difficulties figuring the right way to + * differenciate them all and since that hack was there for a long + * time, I'll keep it around + */ + if (macio_chips[0].type == macio_ohare && !find_devices("via-pmu")) { + struct macio_chip* macio = &macio_chips[0]; + MACIO_OUT32(OHARE_FCR, STARMAX_FEATURES); + } else if (macio_chips[0].type == macio_ohare) { + struct macio_chip* macio = &macio_chips[0]; + MACIO_BIS(OHARE_FCR, OH_IOBUS_ENABLE); + } else if (macio_chips[1].type == macio_ohare) { + struct macio_chip* macio = &macio_chips[1]; + MACIO_BIS(OHARE_FCR, OH_IOBUS_ENABLE); + } + + if (macio_chips[0].type == macio_keylargo || + macio_chips[0].type == macio_pangea) { + /* Enable GMAC for now for PCI probing. It will be disabled + * later on after PCI probe + */ + np = find_devices("ethernet"); + while(np) { + if (np->parent + && device_is_compatible(np->parent, "uni-north") + && device_is_compatible(np, "gmac")) + core99_gmac_enable(np, 0, 1); + np = np->next; + } + + /* Enable FW before PCI probe. Will be disabled later on + * Note: We should have a batter way to check that we are + * dealing with uninorth internal cell and not a PCI cell + * on the external PCI. The code below works though. + */ + np = find_devices("firewire"); + while(np) { + if (np->parent + && device_is_compatible(np->parent, "uni-north") + && (device_is_compatible(np, "pci106b,18") || + device_is_compatible(np, "pci106b,30") || + device_is_compatible(np, "pci11c1,5811"))) { + macio_chips[0].flags |= MACIO_FLAG_FW_SUPPORTED; + core99_firewire_enable(np, 0, 1); + } + np = np->next; + } + + /* Switch airport off */ + np = find_devices("radio"); + while(np) { + if (np && np->parent == macio_chips[0].of_node) { + macio_chips[0].flags |= MACIO_FLAG_AIRPORT_ON; + core99_airport_enable(np, 0, 0); + } + np = np->next; + } + } + + /* On all machines, switch sound off */ + if (macio_chips[0].of_node) + pmac_do_feature_call(PMAC_FTR_SOUND_CHIP_ENABLE, + macio_chips[0].of_node, 0, 0); + + /* On all machines, switch modem & serial ports off */ + np = find_devices("ch-a"); + while(np) { + initial_serial_shutdown(np); + np = np->next; + } + np = find_devices("ch-b"); + while(np) { + initial_serial_shutdown(np); + np = np->next; + } + + /* Let hardware settle down */ + mdelay(10); +} + +void __init +pmac_feature_init(void) +{ + /* Detect the UniNorth memory controller */ + probe_uninorth(); + + /* Probe mac-io controllers */ + if (probe_macios()) { + printk(KERN_WARNING "No mac-io chip found\n"); + return; + } + + /* Probe machine type */ + if (probe_motherboard()) + printk(KERN_WARNING "Unknown PowerMac !\n"); + + /* Set some initial features (turn off some chips that will + * be later turned on) + */ + set_initial_features(); +} + +void __init +pmac_feature_late_init(void) +{ + struct device_node* np; + + /* Request some resources late */ + if (uninorth_node) + request_OF_resource(uninorth_node, 0, NULL); + np = find_devices("hammerhead"); + if (np) + request_OF_resource(np, 0, NULL); + np = find_devices("interrupt-controller"); + if (np) + request_OF_resource(np, 0, NULL); +} diff --git a/arch/ppc/kernel/pmac_nvram.c b/arch/ppc/platforms/pmac_nvram.c index 54c83ef97450..fc59a82f79b4 100644 --- a/arch/ppc/kernel/pmac_nvram.c +++ b/arch/ppc/platforms/pmac_nvram.c @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.pmac_nvram.c 1.15 09/08/01 15:47:42 paulus + * BK Id: %F% %I% %G% %U% %#% */ /* * Miscellaneous procedures for dealing with the PowerMac hardware. @@ -12,6 +12,7 @@ #include <linux/init.h> #include <linux/slab.h> #include <linux/delay.h> +#include <linux/errno.h> #include <asm/sections.h> #include <asm/io.h> #include <asm/system.h> @@ -326,7 +327,7 @@ nvram_read_byte(int addr) break; while (!req.complete) pmu_poll(); - return req.reply[1]; + return req.reply[0]; } #endif case 1: diff --git a/arch/ppc/kernel/pmac_pci.c b/arch/ppc/platforms/pmac_pci.c index 4693731798fe..33e6f4e54fb6 100644 --- a/arch/ppc/kernel/pmac_pci.c +++ b/arch/ppc/platforms/pmac_pci.c @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.pmac_pci.c 1.27 09/08/01 15:47:42 paulus + * BK Id: %F% %I% %G% %U% %#% */ /* * Support for PCI bridges found on Power Macintoshes. @@ -27,9 +27,7 @@ #include <asm/prom.h> #include <asm/pci-bridge.h> #include <asm/machdep.h> -#include <asm/feature.h> - -#include "pci.h" +#include <asm/pmac_feature.h> #undef DEBUG @@ -529,6 +527,7 @@ pmac_pci_enable_device_hook(struct pci_dev *dev, int initial) { struct device_node* node; int updatecfg = 0; + int uninorth_child; node = pci_device_to_OF_node(dev); @@ -538,20 +537,27 @@ pmac_pci_enable_device_hook(struct pci_dev *dev, int initial) if (dev->vendor == PCI_VENDOR_ID_APPLE && dev->device == PCI_DEVICE_ID_APPLE_KL_USB && !node) return -EINVAL; + + if (!node) + return 0; + + uninorth_child = node->parent && + device_is_compatible(node->parent, "uni-north"); /* Firewire & GMAC were disabled after PCI probe, the driver is * claiming them, we must re-enable them now. */ - if (node && !strcmp(node->name, "firewire") && + if (uninorth_child && !strcmp(node->name, "firewire") && (device_is_compatible(node, "pci106b,18") || - device_is_compatible(node, "pci106b,30"))) { - feature_set_firewire_cable_power(node, 1); - feature_set_firewire_power(node, 1); + device_is_compatible(node, "pci106b,30") || + device_is_compatible(node, "pci11c1,5811"))) { + pmac_call_feature(PMAC_FTR_1394_CABLE_POWER, node, 0, 1); + pmac_call_feature(PMAC_FTR_1394_ENABLE, node, 0, 1); updatecfg = 1; } - if (node && !strcmp(node->name, "ethernet") && + if (uninorth_child && !strcmp(node->name, "ethernet") && device_is_compatible(node, "gmac")) { - feature_set_gmac_power(node, 1); + pmac_call_feature(PMAC_FTR_GMAC_ENABLE, node, 0, 1); updatecfg = 1; } @@ -608,10 +614,11 @@ pmac_pcibios_after_init(void) nd = find_devices("firewire"); while (nd) { if (nd->parent && (device_is_compatible(nd, "pci106b,18") || - device_is_compatible(nd, "pci106b,30")) + device_is_compatible(nd, "pci106b,30") || + device_is_compatible(nd, "pci11c1,5811")) && device_is_compatible(nd->parent, "uni-north")) { - feature_set_firewire_power(nd, 0); - feature_set_firewire_cable_power(nd, 0); + pmac_call_feature(PMAC_FTR_1394_ENABLE, nd, 0, 0); + pmac_call_feature(PMAC_FTR_1394_CABLE_POWER, nd, 0, 0); } nd = nd->next; } @@ -619,7 +626,7 @@ pmac_pcibios_after_init(void) while (nd) { if (nd->parent && device_is_compatible(nd, "gmac") && device_is_compatible(nd->parent, "uni-north")) - feature_set_gmac_power(nd, 0); + pmac_call_feature(PMAC_FTR_GMAC_ENABLE, nd, 0, 0); nd = nd->next; } } diff --git a/arch/ppc/kernel/pmac_pic.c b/arch/ppc/platforms/pmac_pic.c index 295e4a44b870..ac30084b1a19 100644 --- a/arch/ppc/kernel/pmac_pic.c +++ b/arch/ppc/platforms/pmac_pic.c @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.pmac_pic.c 1.20 09/08/01 15:47:42 paulus + * BK Id: %F% %I% %G% %U% %#% */ #include <linux/config.h> #include <linux/stddef.h> @@ -14,48 +14,56 @@ #include <asm/prom.h> #include <asm/pci-bridge.h> #include <asm/time.h> +#include <asm/open_pic.h> #include "pmac_pic.h" -#include "open_pic.h" -/* pmac */struct pmac_irq_hw { - unsigned int flag; +struct pmac_irq_hw { + unsigned int event; unsigned int enable; unsigned int ack; unsigned int level; }; -/* XXX these addresses should be obtained from the device tree */ -static volatile struct pmac_irq_hw *pmac_irq_hw[4] = { +/* Default addresses */ +static volatile struct pmac_irq_hw *pmac_irq_hw[4] __pmacdata = { (struct pmac_irq_hw *) 0xf3000020, (struct pmac_irq_hw *) 0xf3000010, (struct pmac_irq_hw *) 0xf4000020, (struct pmac_irq_hw *) 0xf4000010, }; -static int max_irqs; -static int max_real_irqs; +#define GC_LEVEL_MASK 0x3ff00000 +#define OHARE_LEVEL_MASK 0x1ff00000 +#define HEATHROW_LEVEL_MASK 0x1ff00000 -static spinlock_t pmac_pic_lock = SPIN_LOCK_UNLOCKED; +static int max_irqs __pmacdata; +static int max_real_irqs __pmacdata; +static u32 level_mask[4] __pmacdata; + +static spinlock_t pmac_pic_lock __pmacdata = SPIN_LOCK_UNLOCKED; #define GATWICK_IRQ_POOL_SIZE 10 -static struct interrupt_info gatwick_int_pool[GATWICK_IRQ_POOL_SIZE]; +static struct interrupt_info gatwick_int_pool[GATWICK_IRQ_POOL_SIZE] __pmacdata; /* * Mark an irq as "lost". This is only used on the pmac * since it can lose interrupts (see pmac_set_irq_mask). * -- Cort */ -void __pmac __set_lost(unsigned long irq_nr) +void __pmac +__set_lost(unsigned long irq_nr, int nokick) { if (!test_and_set_bit(irq_nr, ppc_lost_interrupts)) { atomic_inc(&ppc_n_lost_interrupts); - set_dec(1); + if (!nokick) + set_dec(1); } } -static void __pmac pmac_mask_and_ack_irq(unsigned int irq_nr) +static void __pmac +pmac_mask_and_ack_irq(unsigned int irq_nr) { unsigned long bit = 1UL << (irq_nr & 0x1f); int i = irq_nr >> 5; @@ -68,18 +76,18 @@ static void __pmac pmac_mask_and_ack_irq(unsigned int irq_nr) if (test_and_clear_bit(irq_nr, ppc_lost_interrupts)) atomic_dec(&ppc_n_lost_interrupts); spin_lock_irqsave(&pmac_pic_lock, flags); - out_le32(&pmac_irq_hw[i]->ack, bit); out_le32(&pmac_irq_hw[i]->enable, ppc_cached_irq_mask[i]); out_le32(&pmac_irq_hw[i]->ack, bit); do { /* make sure ack gets to controller before we enable interrupts */ mb(); - } while(in_le32(&pmac_irq_hw[i]->flag) & bit); + } while((in_le32(&pmac_irq_hw[i]->enable) & bit) + != (ppc_cached_irq_mask[i] & bit)); spin_unlock_irqrestore(&pmac_pic_lock, flags); } -static void __pmac pmac_set_irq_mask(unsigned int irq_nr) +static void __pmac pmac_set_irq_mask(unsigned int irq_nr, int nokicklost) { unsigned long bit = 1UL << (irq_nr & 0x1f); int i = irq_nr >> 5; @@ -104,31 +112,29 @@ static void __pmac pmac_set_irq_mask(unsigned int irq_nr) * when the device interrupt is already on *doesn't* set * the bit in the flag register or request another interrupt. */ - if ((bit & ppc_cached_irq_mask[i]) - && (ld_le32(&pmac_irq_hw[i]->level) & bit) - && !(ld_le32(&pmac_irq_hw[i]->flag) & bit)) - __set_lost((ulong)irq_nr); + if (bit & ppc_cached_irq_mask[i] & in_le32(&pmac_irq_hw[i]->level)) + __set_lost((ulong)irq_nr, nokicklost); spin_unlock_irqrestore(&pmac_pic_lock, flags); } static void __pmac pmac_mask_irq(unsigned int irq_nr) { clear_bit(irq_nr, ppc_cached_irq_mask); - pmac_set_irq_mask(irq_nr); + pmac_set_irq_mask(irq_nr, 0); mb(); } static void __pmac pmac_unmask_irq(unsigned int irq_nr) { set_bit(irq_nr, ppc_cached_irq_mask); - pmac_set_irq_mask(irq_nr); + pmac_set_irq_mask(irq_nr, 0); } static void __pmac pmac_end_irq(unsigned int irq_nr) { if (!(irq_desc[irq_nr].status & (IRQ_DISABLED|IRQ_INPROGRESS))) { set_bit(irq_nr, ppc_cached_irq_mask); - pmac_set_irq_mask(irq_nr); + pmac_set_irq_mask(irq_nr, 1); } } @@ -161,8 +167,10 @@ static void gatwick_action(int cpl, void *dev_id, struct pt_regs *regs) for (irq = max_irqs; (irq -= 32) >= max_real_irqs; ) { int i = irq >> 5; - bits = ld_le32(&pmac_irq_hw[i]->flag) - | ppc_lost_interrupts[i]; + bits = in_le32(&pmac_irq_hw[i]->event) | ppc_lost_interrupts[i]; + /* We must read level interrupts from the level register */ + bits |= (in_le32(&pmac_irq_hw[i]->level) & level_mask[i]); + bits &= ppc_cached_irq_mask[i]; if (bits == 0) continue; irq += __ilog2(bits); @@ -195,8 +203,10 @@ pmac_get_irq(struct pt_regs *regs) #endif /* CONFIG_SMP */ for (irq = max_real_irqs; (irq -= 32) >= 0; ) { int i = irq >> 5; - bits = ld_le32(&pmac_irq_hw[i]->flag) - | ppc_lost_interrupts[i]; + bits = in_le32(&pmac_irq_hw[i]->event) | ppc_lost_interrupts[i]; + /* We must read level interrupts from the level register */ + bits |= (in_le32(&pmac_irq_hw[i]->level) & level_mask[i]); + bits &= ppc_cached_irq_mask[i]; if (bits == 0) continue; irq += __ilog2(bits); @@ -374,6 +384,24 @@ pmac_pic_init(void) irqctrler = NULL; } + /* Get the level/edge settings, assume if it's not + * a Grand Central nor an OHare, then it's an Heathrow + * (or Paddington). + */ + if (find_devices("gc")) + level_mask[0] = GC_LEVEL_MASK; + else if (find_devices("ohare")) { + level_mask[0] = OHARE_LEVEL_MASK; + /* We might have a second cascaded ohare */ + level_mask[1] = OHARE_LEVEL_MASK; + } else { + level_mask[0] = HEATHROW_LEVEL_MASK; + level_mask[1] = 0; + /* We might have a second cascaded heathrow */ + level_mask[2] = HEATHROW_LEVEL_MASK; + level_mask[3] = 0; + } + /* * G3 powermacs and 1999 G3 PowerBooks have 64 interrupts, * 1998 G3 Series PowerBooks have 128, @@ -433,6 +461,10 @@ pmac_pic_init(void) /* disable all interrupts in all controllers */ for (i = 0; i * 32 < max_irqs; ++i) out_le32(&pmac_irq_hw[i]->enable, 0); + /* mark level interrupts */ + for (i = 0; i < max_irqs; i++) + if (level_mask[i >> 5] & (1UL << (i & 0x1f))) + irq_desc[i].status = IRQ_LEVEL; /* get interrupt line of secondary interrupt controller */ if (irq_cascade >= 0) { @@ -474,7 +506,7 @@ pmac_sleep_save_intrs(int viaint) out_le32(&pmac_irq_hw[0]->enable, ppc_cached_irq_mask[0]); if (max_real_irqs > 32) out_le32(&pmac_irq_hw[1]->enable, ppc_cached_irq_mask[1]); - (void)in_le32(&pmac_irq_hw[0]->flag); + (void)in_le32(&pmac_irq_hw[0]->event); /* make sure mask gets to controller before we return to caller */ mb(); (void)in_le32(&pmac_irq_hw[0]->enable); diff --git a/arch/ppc/platforms/pmac_pic.h b/arch/ppc/platforms/pmac_pic.h new file mode 100644 index 000000000000..9c8d012104dc --- /dev/null +++ b/arch/ppc/platforms/pmac_pic.h @@ -0,0 +1,14 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ +#ifndef __PPC_PLATFORMS_PMAC_PIC_H +#define __PPC_PLATFORMS_PMAC_PIC_H + +#include <linux/irq.h> + +extern struct hw_interrupt_type pmac_pic; + +void pmac_pic_init(void); +int pmac_get_irq(struct pt_regs *regs); + +#endif /* __PPC_PLATFORMS_PMAC_PIC_H */ diff --git a/arch/ppc/kernel/pmac_setup.c b/arch/ppc/platforms/pmac_setup.c index ad11963bda86..b074071d63f9 100644 --- a/arch/ppc/kernel/pmac_setup.c +++ b/arch/ppc/platforms/pmac_setup.c @@ -1,8 +1,8 @@ /* - * BK Id: SCCS/s.pmac_setup.c 1.43 11/13/01 21:26:07 paulus + * BK Id: %F% %I% %G% %U% %#% */ /* - * linux/arch/ppc/kernel/setup.c + * arch/ppc/platforms/setup.c * * PowerPC version * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) @@ -49,6 +49,7 @@ #include <linux/adb.h> #include <linux/cuda.h> #include <linux/pmu.h> +#include <linux/irq.h> #include <linux/seq_file.h> #include <asm/processor.h> @@ -61,18 +62,16 @@ #include <asm/pci-bridge.h> #include <asm/ohare.h> #include <asm/mediabay.h> -#include <asm/feature.h> #include <asm/machdep.h> #include <asm/keyboard.h> #include <asm/dma.h> #include <asm/bootx.h> #include <asm/cputable.h> #include <asm/btext.h> - +#include <asm/pmac_feature.h> #include <asm/time.h> -#include "local_irq.h" #include "pmac_pic.h" -#include "../mm/mem_pieces.h" +#include "mem_pieces.h" #undef SHOW_GATWICK_IRQS @@ -83,6 +82,8 @@ extern void pmac_read_rtc_time(void); extern void pmac_calibrate_decr(void); extern void pmac_pcibios_fixup(void); extern void pmac_find_bridges(void); +extern int pmac_ide_check_base(ide_ioreg_t base); +extern ide_ioreg_t pmac_ide_get_base(int index); extern int mackbd_setkeycode(unsigned int scancode, unsigned int keycode); extern int mackbd_getkeycode(unsigned int scancode); @@ -109,6 +110,8 @@ extern void pmac_nvram_update(void); extern int pmac_pci_enable_device_hook(struct pci_dev *dev, int initial); extern void pmac_pcibios_after_init(void); +extern kdev_t sd_find_target(void *host, int tgt); + struct device_node *memory_node; unsigned char drive_info; @@ -271,16 +274,6 @@ pmac_show_cpuinfo(struct seq_file *m) return 0; } -#ifdef CONFIG_SCSI -/* Find the device number for the disk (if any) at target tgt - on host adaptor host. We just need to get the prototype from - sd.h */ -#include <linux/blkdev.h> -#include "../../../drivers/scsi/scsi.h" -#include "../../../drivers/scsi/sd.h" - -#endif - #ifdef CONFIG_VT /* * Dummy mksound function that does nothing. @@ -385,7 +378,7 @@ pmac_setup_arch(void) #endif #ifdef CONFIG_BLK_DEV_INITRD if (initrd_start) - ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); + ROOT_DEV = mk_kdev(RAMDISK_MAJOR, 0); else #endif ROOT_DEV = to_kdev_t(DEFAULT_ROOT_DEVICE); @@ -397,6 +390,8 @@ pmac_setup_arch(void) else ppc_md.smp_ops = &psurge_smp_ops; #endif /* CONFIG_SMP */ + + pci_create_OF_bus_map(); } static void __init ohare_init(void) @@ -436,7 +431,8 @@ pmac_init2(void) #endif #ifdef CONFIG_PMAC_PBOOK media_bay_init(); -#endif +#endif + pmac_feature_late_init(); } #ifdef CONFIG_SCSI @@ -495,7 +491,7 @@ find_boot_device(void) #if defined(CONFIG_SCSI) && defined(CONFIG_BLK_DEV_SD) if (boot_host != NULL) { boot_dev = sd_find_target(boot_host, boot_target); - if (boot_dev != 0) + if (!kdev_same(boot_dev, NODEV)) return; } #endif @@ -515,7 +511,7 @@ note_bootable_part(kdev_t dev, int part, int goodness) if (init_task.fs->rootmnt != NULL) return; if ((goodness <= current_root_goodness) && - (ROOT_DEV != to_kdev_t(DEFAULT_ROOT_DEVICE))) + !kdev_same(ROOT_DEV, to_kdev_t(DEFAULT_ROOT_DEVICE))) return; p = strstr(saved_command_line, "root="); if (p != NULL && (p == saved_command_line || p[-1] == ' ')) @@ -525,8 +521,8 @@ note_bootable_part(kdev_t dev, int part, int goodness) find_boot_device(); found_boot = 1; } - if (boot_dev == 0 || dev == boot_dev) { - ROOT_DEV = MKDEV(MAJOR(dev), MINOR(dev) + part); + if (kdev_same(boot_dev, NODEV) || kdev_same(dev, boot_dev)) { + ROOT_DEV = mk_kdev(major(dev), minor(dev) + part); boot_dev = NODEV; current_root_goodness = goodness; } @@ -604,14 +600,11 @@ pmac_halt(void) static int __pmac pmac_ide_check_region(ide_ioreg_t from, unsigned int extent) { - /* - * We only do the check_region if `from' looks like a genuine - * I/O port number. If it actually refers to a memory-mapped - * register, it should be OK. - */ - if (from < ~_IO_BASE) - return check_region(from, extent); - return 0; +#ifdef CONFIG_BLK_DEV_IDE_PMAC + if (pmac_ide_check_base(from) >= 0) + return 0; +#endif + return check_region(from, extent); } static void __pmac @@ -619,42 +612,30 @@ pmac_ide_request_region(ide_ioreg_t from, unsigned int extent, const char *name) { - if (from < ~_IO_BASE) - request_region(from, extent, name); +#ifdef CONFIG_BLK_DEV_IDE_PMAC + if (pmac_ide_check_base(from) >= 0) + return; +#endif + request_region(from, extent, name); } static void __pmac pmac_ide_release_region(ide_ioreg_t from, unsigned int extent) { - if (from < ~_IO_BASE) - release_region(from, extent); -} - -/* - * This is only used if we have a PCI IDE controller, not - * for the IDE controller in the ohare/paddington/heathrow/keylargo. - */ -static void __pmac -pmac_ide_init_hwif_ports(hw_regs_t *hw, ide_ioreg_t data_port, - ide_ioreg_t ctrl_port, int *irq) -{ - ide_ioreg_t reg = data_port; - int i; - - for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) { - hw->io_ports[i] = reg; - reg += 1; - } - hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port; -} +#ifdef CONFIG_BLK_DEV_IDE_PMAC + if (pmac_ide_check_base(from) >= 0) + return; #endif + release_region(from, extent); +} +#endif /* defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) */ /* * Read in a property describing some pieces of memory. */ -static void __init +static int __init get_mem_prop(char *name, struct mem_pieces *mp) { struct reg_property *rp; @@ -667,7 +648,7 @@ get_mem_prop(char *name, struct mem_pieces *mp) if (ip == NULL) { printk(KERN_ERR "error: couldn't get %s property on /memory\n", name); - abort(); + return 0; } s /= (nsc + nac) * 4; rp = mp->regions; @@ -686,6 +667,7 @@ get_mem_prop(char *name, struct mem_pieces *mp) /* Make sure the pieces are sorted. */ mem_pieces_sort(mp); mem_pieces_coalesce(mp); + return 1; } /* @@ -701,12 +683,6 @@ pmac_find_end_of_memory(void) unsigned long a, total; struct mem_pieces phys_mem; - memory_node = find_devices("memory"); - if (memory_node == NULL) { - printk(KERN_ERR "can't find memory node\n"); - abort(); - } - /* * Find out where physical memory is, and check that it * starts at 0 and is contiguous. It seems that RAM is @@ -717,8 +693,9 @@ pmac_find_end_of_memory(void) * more complicated (or else you end up wasting space * in mem_map). */ - get_mem_prop("reg", &phys_mem); - if (phys_mem.n_regions == 0) + memory_node = find_devices("memory"); + if (memory_node == NULL || !get_mem_prop("reg", &phys_mem) + || phys_mem.n_regions == 0) panic("No RAM??"); a = phys_mem.regions[0].address; if (a != 0) @@ -806,14 +783,15 @@ pmac_init(unsigned long r3, unsigned long r4, unsigned long r5, ppc_md.find_end_of_memory = pmac_find_end_of_memory; + ppc_md.feature_call = pmac_do_feature_call; + select_adb_keyboard(); -#if defined(CONFIG_BLK_DEV_IDE) && defined(CONFIG_BLK_DEV_IDE_PMAC) +#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) ppc_ide_md.ide_check_region = pmac_ide_check_region; ppc_ide_md.ide_request_region = pmac_ide_request_region; ppc_ide_md.ide_release_region = pmac_ide_release_region; - ppc_ide_md.ide_init_hwif = pmac_ide_init_hwif_ports; -#endif /* CONFIG_BLK_DEV_IDE && CONFIG_BLK_DEV_IDE_PMAC */ +#endif /* defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) */ #ifdef CONFIG_BOOTX_TEXT ppc_md.progress = pmac_progress; @@ -824,15 +802,12 @@ pmac_init(unsigned long r3, unsigned long r4, unsigned long r5, } #ifdef CONFIG_BOOTX_TEXT -extern void drawchar(char c); -extern void drawstring(const char *c); -extern boot_infos_t *disp_bi; void __init pmac_progress(char *s, unsigned short hex) { - if (disp_bi == 0) - return; - btext_drawstring(s); - btext_drawchar('\n'); + if (boot_text_mapped) { + btext_drawstring(s); + btext_drawchar('\n'); + } } #endif /* CONFIG_BOOTX_TEXT */ diff --git a/arch/ppc/kernel/pmac_smp.c b/arch/ppc/platforms/pmac_smp.c index 9c28cdde79ee..8fccbd5bf31f 100644 --- a/arch/ppc/kernel/pmac_smp.c +++ b/arch/ppc/platforms/pmac_smp.c @@ -43,11 +43,10 @@ #include <asm/prom.h> #include <asm/smp.h> #include <asm/residual.h> -#include <asm/feature.h> +#include <asm/machdep.h> +#include <asm/pmac_feature.h> #include <asm/time.h> -#include <asm/gemini.h> - -#include "open_pic.h" +#include <asm/open_pic.h> /* * Powersurge (old powermac SMP) support. @@ -442,7 +441,7 @@ smp_core99_kick_cpu(int nr) flush_icache_range((unsigned long) vector, (unsigned long) vector + 4); /* Put some life in our friend */ - feature_core99_kick_cpu(nr); + pmac_call_feature(PMAC_FTR_RESET_CPU, NULL, nr, 0); /* FIXME: We wait a bit for the CPU to take the exception, I should * instead wait for the entry code to set something for me. Well, diff --git a/arch/ppc/kernel/pmac_time.c b/arch/ppc/platforms/pmac_time.c index ba7260441eb2..650c3e6e23e8 100644 --- a/arch/ppc/kernel/pmac_time.c +++ b/arch/ppc/platforms/pmac_time.c @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.pmac_time.c 1.16 09/08/01 15:47:42 paulus + * BK Id: %F% %I% %G% %U% %#% */ /* * Support for periodic interrupts (100 per second) and for getting @@ -110,11 +110,11 @@ pmac_get_rtc_time(void) return 0; while (!req.complete) pmu_poll(); - if (req.reply_len != 5) + if (req.reply_len != 4) printk(KERN_ERR "pmac_get_rtc_time: got %d byte reply\n", req.reply_len); - now = (req.reply[1] << 24) + (req.reply[2] << 16) - + (req.reply[3] << 8) + req.reply[4]; + now = (req.reply[0] << 24) + (req.reply[1] << 16) + + (req.reply[2] << 8) + req.reply[3]; return now - RTC_OFFSET; #endif /* CONFIG_ADB_PMU */ default: ; @@ -228,10 +228,6 @@ time_sleep_notify(struct pmu_sleep_notifier *self, int when) case PBOOK_WAKE: write_lock_irqsave(&xtime_lock, flags); xtime.tv_sec = pmac_get_rtc_time() + time_diff; - set_dec(tb_ticks_per_jiffy); - /* No currently-supported powerbook has a 601, - so use get_tbl, not native */ - last_jiffy_stamp(0) = tb_last_stamp = get_tbl(); xtime.tv_usec = 0; last_rtc_update = xtime.tv_sec; write_unlock_irqrestore(&xtime_lock, flags); diff --git a/arch/ppc/platforms/powerpmc250.c b/arch/ppc/platforms/powerpmc250.c new file mode 100644 index 000000000000..633565bec696 --- /dev/null +++ b/arch/ppc/platforms/powerpmc250.c @@ -0,0 +1,390 @@ +/* + * arch/ppc/platforms/powerpmc250.c + * + * Board setup routines for Force PowerPMC-250 Processor PMC + * + * Author: Troy Benjegerdes <tbenjegerdes@mvista.com> + * Borrowed heavily from prpmc750_*.c by + * Matt Porter <mporter@mvista.com> + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include <linux/config.h> +#include <linux/stddef.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/errno.h> +#include <linux/reboot.h> +#include <linux/pci.h> +#include <linux/kdev_t.h> +#include <linux/types.h> +#include <linux/major.h> +#include <linux/blk.h> +#include <linux/console.h> +#include <linux/delay.h> +#include <linux/irq.h> +#include <linux/slab.h> +#include <linux/seq_file.h> +#include <linux/ide.h> + +#include <asm/byteorder.h> +#include <asm/system.h> +#include <asm/pgtable.h> +#include <asm/page.h> +#include <asm/dma.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/machdep.h> +#include <asm/time.h> +#include <platforms/powerpmc250.h> +#include <asm/open_pic.h> +#include <asm/pci-bridge.h> +#include <asm/mpc10x.h> +#include <asm/uaccess.h> +#include <asm/bootinfo.h> + +extern void powerpmc250_find_bridges(void); +extern unsigned long loops_per_jiffy; + +static u_char powerpmc250_openpic_initsenses[] __initdata = +{ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, /* PMC INTA (also MPC107 output interrupt INTA) */ + 1, /* PMC INTB (also I82559 Ethernet controller) */ + 1, /* PMC INTC */ + 1, /* PMC INTD */ + 0, /* DUART interrupt (active high) */ +}; + +static int +powerpmc250_show_cpuinfo(struct seq_file *m) +{ + seq_printf(m,"machine\t\t: Force PowerPMC250\n"); + + return 0; +} + +static void __init +powerpmc250_setup_arch(void) +{ + /* init to some ~sane value until calibrate_delay() runs */ + loops_per_jiffy = 50000000/HZ; + + /* Lookup PCI host bridges */ + powerpmc250_find_bridges(); + +#ifdef CONFIG_BLK_DEV_INITRD + if (initrd_start) + ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); /* /dev/ram */ + else +#endif +#ifdef CONFIG_ROOT_NFS + ROOT_DEV = to_kdev_t(0x00ff); /* /dev/nfs pseudo device */ +#else + ROOT_DEV = to_kdev_t(0x0802); /* /dev/sda2 */ +#endif + + printk("Force PowerPMC250 port (C) 2001 MontaVista Software, Inc. (source@mvista.com)\n"); +} + +#if 0 +/* + * Compute the PrPMC750's bus speed using the baud clock as a + * reference. + */ +unsigned long __init powerpmc250_get_bus_speed(void) +{ + unsigned long tbl_start, tbl_end; + unsigned long current_state, old_state, bus_speed; + unsigned char lcr, dll, dlm; + int baud_divisor, count; + + /* Read the UART's baud clock divisor */ + lcr = readb(PRPMC750_SERIAL_0_LCR); + writeb(lcr | UART_LCR_DLAB, PRPMC750_SERIAL_0_LCR); + dll = readb(PRPMC750_SERIAL_0_DLL); + dlm = readb(PRPMC750_SERIAL_0_DLM); + writeb(lcr & ~UART_LCR_DLAB, PRPMC750_SERIAL_0_LCR); + baud_divisor = (dlm << 8) | dll; + + /* + * Use the baud clock divisor and base baud clock + * to determine the baud rate and use that as + * the number of baud clock edges we use for + * the time base sample. Make it half the baud + * rate. + */ + count = PRPMC750_BASE_BAUD / (baud_divisor * 16); + + /* Find the first edge of the baud clock */ + old_state = readb(PRPMC750_STATUS_REG) & PRPMC750_BAUDOUT_MASK; + do { + current_state = readb(PRPMC750_STATUS_REG) & + PRPMC750_BAUDOUT_MASK; + } while(old_state == current_state); + + old_state = current_state; + + /* Get the starting time base value */ + tbl_start = get_tbl(); + + /* + * Loop until we have found a number of edges equal + * to half the count (half the baud rate) + */ + do { + do { + current_state = readb(PRPMC750_STATUS_REG) & + PRPMC750_BAUDOUT_MASK; + } while(old_state == current_state); + old_state = current_state; + } while (--count); + + /* Get the ending time base value */ + tbl_end = get_tbl(); + + /* Compute bus speed */ + bus_speed = (tbl_end-tbl_start)*128; + + return bus_speed; +} +#endif + +static void __init +powerpmc250_calibrate_decr(void) +{ + unsigned long freq; + int divisor = 4; + + //freq = powerpmc250_get_bus_speed(); +#warning hardcoded bus freq + freq = 100000000; + + tb_ticks_per_jiffy = freq / (HZ * divisor); + tb_to_us = mulhwu_scale_factor(freq/divisor, 1000000); +} + +static void +powerpmc250_restart(char *cmd) +{ + __cli(); + /* Hard reset */ + writeb(0x11, 0xfe000332); + while(1); +} + +static void +powerpmc250_halt(void) +{ + __cli(); + while (1); +} + +static void +powerpmc250_power_off(void) +{ + powerpmc250_halt(); +} + +/* Resolves the open_pic.c build without including i8259.c */ +int i8259_poll(void) +{ + return 0; +} + +static void __init +powerpmc250_init_IRQ(void) +{ + + OpenPIC_InitSenses = powerpmc250_openpic_initsenses; + OpenPIC_NumInitSenses = sizeof(powerpmc250_openpic_initsenses); + openpic_init(1, 0, 0, -1); +} + +/* + * Set BAT 3 to map 0xf0000000 to end of physical memory space. + */ +static __inline__ void +powerpmc250_set_bat(void) +{ + unsigned long bat3u, bat3l; + static int mapping_set = 0; + + if (!mapping_set) + { + __asm__ __volatile__( + " lis %0,0xf000\n \ + ori %1,%0,0x002a\n \ + ori %0,%0,0x1ffe\n \ + mtspr 0x21e,%0\n \ + mtspr 0x21f,%1\n \ + isync\n \ + sync " + : "=r" (bat3u), "=r" (bat3l)); + + mapping_set = 1; + } + return; +} + +static unsigned long __init +powerpmc250_find_end_of_memory(void) +{ + /* Cover I/O space with a BAT */ + /* yuck, better hope your ram size is a power of 2 -- paulus */ + powerpmc250_set_bat(); + + return mpc10x_get_mem_size(MPC10X_MEM_MAP_B); +} + +static void __init +powerpmc250_map_io(void) +{ + io_block_mapping(0xfe000000, 0xfe000000, 0x02000000, _PAGE_IO); +} + +void __init +platform_init(unsigned long r3, unsigned long r4, unsigned long r5, + unsigned long r6, unsigned long r7) +{ + parse_bootinfo(find_bootinfo()); + +#ifdef CONFIG_BLK_DEV_INITRD + if ( r4 ) + { + initrd_start = r4 + KERNELBASE; + initrd_end = r5 + KERNELBASE; + } +#endif + + /* Copy cmd_line parameters */ + if ( r6) + { + *(char *)(r7 + KERNELBASE) = 0; + strcpy(cmd_line, (char *)(r6 + KERNELBASE)); + } + + isa_io_base = MPC10X_MAPB_ISA_IO_BASE; + isa_mem_base = MPC10X_MAPB_ISA_MEM_BASE; + pci_dram_offset = MPC10X_MAPB_DRAM_OFFSET; + + ppc_md.setup_arch = powerpmc250_setup_arch; + ppc_md.show_cpuinfo = powerpmc250_show_cpuinfo; + ppc_md.init_IRQ = powerpmc250_init_IRQ; + ppc_md.get_irq = openpic_get_irq; + + ppc_md.find_end_of_memory = powerpmc250_find_end_of_memory; + ppc_md.setup_io_mappings = powerpmc250_map_io; + + ppc_md.restart = powerpmc250_restart; + ppc_md.power_off = powerpmc250_power_off; + ppc_md.halt = powerpmc250_halt; + + /* PowerPMC250 has no timekeeper part */ + ppc_md.time_init = NULL; + ppc_md.get_rtc_time = NULL; + ppc_md.set_rtc_time = NULL; + ppc_md.calibrate_decr = powerpmc250_calibrate_decr; +} + + +/* + * (This used to be arch/ppc/platforms/powerpmc250_pci.c) + * + * PCI support for Force PowerPMC250 + * + */ + +#undef DEBUG +#ifdef DEBUG +#define DBG(x...) printk(x) +#else +#define DBG(x...) +#endif /* DEBUG */ + +static inline int __init +powerpmc250_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) +{ + static char pci_irq_table[][4] = + /* + * PCI IDSEL/INTPIN->INTLINE + * A B C D + */ + { + {17, 0, 0, 0}, /* Device 11 - 82559 */ + {0, 0, 0, 0}, /* 12 */ + {0, 0, 0, 0}, /* 13 */ + {0, 0, 0, 0}, /* 14 */ + {0, 0, 0, 0}, /* 15 */ + {16, 17, 18, 19}, /* Device 16 - PMC A1?? */ + }; + const long min_idsel = 11, max_idsel = 16, irqs_per_slot = 4; + return PCI_IRQ_TABLE_LOOKUP; +}; + +static int +powerpmc250_exclude_device(u_char bus, u_char devfn) +{ + /* + * While doing PCI Scan the MPC107 will 'detect' itself as + * device on the PCI Bus, will create an incorrect response and + * later will respond incorrectly to Configuration read coming + * from another device. + * + * The work around is that when doing a PCI Scan one + * should skip its own device number in the scan. + * + * The top IDsel is AD13 and the middle is AD14. + * + * -- Note from force + */ + + if ((bus == 0) && (PCI_SLOT(devfn) == 13 || PCI_SLOT(devfn) == 14)) { + return PCIBIOS_DEVICE_NOT_FOUND; + } + else { + return PCIBIOS_SUCCESSFUL; + } +} + +void __init +powerpmc250_find_bridges(void) +{ + struct pci_controller* hose; + + hose = pcibios_alloc_controller(); + if (!hose){ + printk("Can't allocate PCI 'hose' structure!!!\n"); + return; + } + + hose->first_busno = 0; + hose->last_busno = 0xff; + + if (mpc10x_bridge_init(hose, + MPC10X_MEM_MAP_B, + MPC10X_MEM_MAP_B, + MPC10X_MAPB_EUMB_BASE) == 0) { + + hose->mem_resources[0].end = 0xffffffff; + + hose->last_busno = pciauto_bus_scan(hose, hose->first_busno); + + /* ppc_md.pcibios_fixup = pcore_pcibios_fixup; */ + ppc_md.pci_swizzle = common_swizzle; + + ppc_md.pci_exclude_device = powerpmc250_exclude_device; + ppc_md.pci_map_irq = powerpmc250_map_irq; + } else { + if (ppc_md.progress) + ppc_md.progress("Bridge init failed", 0x100); + printk("Host bridge init failed\n"); + } + +} diff --git a/arch/ppc/platforms/powerpmc250.h b/arch/ppc/platforms/powerpmc250.h new file mode 100644 index 000000000000..4a1162dd36e1 --- /dev/null +++ b/arch/ppc/platforms/powerpmc250.h @@ -0,0 +1,42 @@ +/* + * include/asm-ppc/platforms/powerpmc250.h + * + * Definitions for Force PowerPMC-250 board support + * + * Author: Troy Benjegerdes <tbenjegerdes@mvista.com> + * + * Borrowed heavily from prpmc750.h by Matt Porter <mporter@mvista.com> + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#ifndef __ASMPPC_POWERPMC250_H +#define __ASMPPC_POWERPMC250_H + +#include <linux/serial_reg.h> + +#define POWERPMC250_PCI_CONFIG_ADDR 0x80000cf8 +#define POWERPMC250_PCI_CONFIG_DATA 0x80000cfc + +#define POWERPMC250_PCI_PHY_MEM_BASE 0xc0000000 +#define POWERPMC250_PCI_MEM_BASE 0xf0000000 +#define POWERPMC250_PCI_IO_BASE 0x80000000 + +#define POWERPMC250_ISA_IO_BASE POWERPMC250_PCI_IO_BASE +#define POWERPMC250_ISA_MEM_BASE POWERPMC250_PCI_MEM_BASE +#define POWERPMC250_PCI_MEM_OFFSET POWERPMC250_PCI_PHY_MEM_BASE + +#define POWERPMC250_SYS_MEM_BASE 0x80000000 + +#define POWERPMC250_HAWK_SMC_BASE 0xfef80000 + +#define POWERPMC250_BASE_BAUD 12288000 +#define POWERPMC250_SERIAL 0xff000000 +#define POWERPMC250_SERIAL_IRQ 20 + +#endif /* __ASMPPC_POWERPMC250_H */ diff --git a/arch/ppc/platforms/powerpmc250_serial.h b/arch/ppc/platforms/powerpmc250_serial.h new file mode 100644 index 000000000000..5a02340a0cb1 --- /dev/null +++ b/arch/ppc/platforms/powerpmc250_serial.h @@ -0,0 +1,42 @@ +/* + * include/asm-ppc/platforms/powerpmc250_serial.h + * + * Motorola PrPMC750 serial support + * + * Author: Troy Benjegerdes <tbenjegerdes@mvista.com> + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#ifdef __KERNEL__ +#ifndef __ASMPPC_POWERPMC250_SERIAL_H +#define __ASMPPC_POWERPMC250_SERIAL_H + +#include <linux/config.h> +#include <platforms/powerpmc250.h> + +#define RS_TABLE_SIZE 1 + +#define BASE_BAUD (POWERPMC250_BASE_BAUD / 16) + +#ifdef CONFIG_SERIAL_DETECT_IRQ +#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF|ASYNC_SKIP_TEST|ASYNC_AUTO_IRQ) +#define STD_COM4_FLAGS (ASYNC_BOOT_AUTOCONF|ASYNC_AUTO_IRQ) +#else +#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF|ASYNC_SKIP_TEST) +#define STD_COM4_FLAGS (ASYNC_BOOT_AUTOCONF) +#endif + +#define SERIAL_PORT_DFNS \ +{ 0, BASE_BAUD, POWERPMC250_SERIAL, POWERPMC250_SERIAL_IRQ, STD_COM_FLAGS, /* ttyS0 */\ + iomem_base: (u8 *)POWERPMC250_SERIAL, \ + iomem_reg_shift: 0, \ + io_type: SERIAL_IO_MEM } + +#endif +#endif /* __KERNEL__ */ diff --git a/arch/ppc/platforms/pplus_pci.c b/arch/ppc/platforms/pplus_pci.c new file mode 100644 index 000000000000..4fbd547863b7 --- /dev/null +++ b/arch/ppc/platforms/pplus_pci.c @@ -0,0 +1,538 @@ +/* + * arch/ppc/platforms/pplus_pci.c + * + * PCI setup for MCG PowerPlus + * + * Author: Randy Vinson <rvinson@mvista.com> + * + * Derived from original PowerPlus PReP work by + * Cort Dougan, Johnnie Peters, Matt Porter, and + * Troy Benjegerdes. + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <linux/config.h> +#include <linux/types.h> +#include <linux/pci.h> +#include <linux/kernel.h> +#include <linux/init.h> + +#include <asm/sections.h> +#include <asm/byteorder.h> +#include <asm/io.h> +#include <asm/ptrace.h> +#include <asm/pci-bridge.h> +#include <asm/residual.h> +#include <asm/processor.h> +#include <asm/irq.h> +#include <asm/machdep.h> + +#include <asm/open_pic.h> +#include <asm/pplus.h> + +unsigned char *Motherboard_map_name; + +/* Tables for known hardware */ + +/* Motorola Mesquite */ +static inline int +mesquite_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) +{ + static char pci_irq_table[][4] = + /* + * MPIC interrupts for various IDSEL values (MPIC IRQ0 = + * Linux IRQ16 (to leave room for ISA IRQs at 0-15). + * PCI IDSEL/INTPIN->INTLINE + * A B C D + */ + { + { 18, 0, 0, 0 }, /* IDSEL 14 - Enet 0 */ + { 0, 0, 0, 0 }, /* IDSEL 15 - unused */ + { 19, 19, 19, 19 }, /* IDSEL 16 - PMC Slot 1 */ + { 0, 0, 0, 0 }, /* IDSEL 17 - unused */ + { 0, 0, 0, 0 }, /* IDSEL 18 - unused */ + { 0, 0, 0, 0 }, /* IDSEL 19 - unused */ + { 24, 25, 26, 27 }, /* IDSEL 20 - P2P bridge (to cPCI 1) */ + { 0, 0, 0, 0 }, /* IDSEL 21 - unused */ + { 28, 29, 30, 31 } /* IDSEL 22 - P2P bridge (to cPCI 2) */ + }; + + const long min_idsel = 14, max_idsel = 22, irqs_per_slot = 4; + return PCI_IRQ_TABLE_LOOKUP; +} + +/* Motorola Sitka */ +static inline int +sitka_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) +{ + static char pci_irq_table[][4] = + /* + * MPIC interrupts for various IDSEL values (MPIC IRQ0 = + * Linux IRQ16 (to leave room for ISA IRQs at 0-15). + * PCI IDSEL/INTPIN->INTLINE + * A B C D + */ + { + { 18, 0, 0, 0 }, /* IDSEL 14 - Enet 0 */ + { 0, 0, 0, 0 }, /* IDSEL 15 - unused */ + { 25, 26, 27, 28 }, /* IDSEL 16 - PMC Slot 1 */ + { 28, 25, 26, 27 }, /* IDSEL 17 - PMC Slot 2 */ + { 0, 0, 0, 0 }, /* IDSEL 18 - unused */ + { 0, 0, 0, 0 }, /* IDSEL 19 - unused */ + { 20, 0, 0, 0 } /* IDSEL 20 - P2P bridge (to cPCI) */ + }; + + const long min_idsel = 14, max_idsel = 20, irqs_per_slot = 4; + return PCI_IRQ_TABLE_LOOKUP; +} + +/* Motorola MTX */ +static inline int +MTX_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) +{ + static char pci_irq_table[][4] = + /* + * MPIC interrupts for various IDSEL values (MPIC IRQ0 = + * Linux IRQ16 (to leave room for ISA IRQs at 0-15). + * PCI IDSEL/INTPIN->INTLINE + * A B C D + */ + { + { 19, 0, 0, 0 }, /* IDSEL 12 - SCSI */ + { 0, 0, 0, 0 }, /* IDSEL 13 - unused */ + { 18, 0, 0, 0 }, /* IDSEL 14 - Enet */ + { 0, 0, 0, 0 }, /* IDSEL 15 - unused */ + { 25, 26, 27, 28 }, /* IDSEL 16 - PMC Slot 1 */ + { 26, 27, 28, 25 }, /* IDSEL 17 - PMC Slot 2 */ + { 27, 28, 25, 26 } /* IDSEL 18 - PCI Slot 3 */ + }; + + const long min_idsel = 12, max_idsel = 18, irqs_per_slot = 4; + return PCI_IRQ_TABLE_LOOKUP; +} + +/* Motorola MTX Plus */ +/* Secondary bus interrupt routing is not supported yet */ +static inline int +MTXplus_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) +{ + static char pci_irq_table[][4] = + /* + * MPIC interrupts for various IDSEL values (MPIC IRQ0 = + * Linux IRQ16 (to leave room for ISA IRQs at 0-15). + * PCI IDSEL/INTPIN->INTLINE + * A B C D + */ + { + { 19, 0, 0, 0 }, /* IDSEL 12 - SCSI */ + { 0, 0, 0, 0 }, /* IDSEL 13 - unused */ + { 18, 0, 0, 0 }, /* IDSEL 14 - Enet 1 */ + { 0, 0, 0, 0 }, /* IDSEL 15 - unused */ + { 25, 26, 27, 28 }, /* IDSEL 16 - PCI Slot 1P */ + { 26, 27, 28, 25 }, /* IDSEL 17 - PCI Slot 2P */ + { 27, 28, 25, 26 }, /* IDSEL 18 - PCI Slot 3P */ + { 26, 0, 0, 0 }, /* IDSEL 19 - Enet 2 */ + { 0, 0, 0, 0 } /* IDSEL 20 - P2P Bridge */ + }; + + const long min_idsel = 12, max_idsel = 20, irqs_per_slot = 4; + return PCI_IRQ_TABLE_LOOKUP; +} + +static inline int +Genesis2_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) +{ + /* 2600 + * Raven 31 + * ISA 11 + * SCSI 12 - IRQ3 + * Univ 13 + * eth 14 - IRQ2 + * VGA 15 - IRQ4 + * PMC1 16 - IRQ9,10,11,12 = PMC1 A-D + * PMC2 17 - IRQ12,9,10,11 = A-D + * SCSI2 18 - IRQ11 + * eth2 19 - IRQ10 + * PCIX 20 - IRQ9,10,11,12 = PCI A-D + */ + + /* 2400 + * Hawk 31 + * ISA 11 + * Univ 13 + * eth 14 - IRQ2 + * PMC1 16 - IRQ9,10,11,12 = PMC A-D + * PMC2 17 - IRQ12,9,10,11 = PMC A-D + * PCIX 20 - IRQ9,10,11,12 = PMC A-D + */ + + /* 2300 + * Raven 31 + * ISA 11 + * Univ 13 + * eth 14 - IRQ2 + * PMC1 16 - 9,10,11,12 = A-D + * PMC2 17 - 9,10,11,12 = B,C,D,A + */ + + static char pci_irq_table[][4] = + /* + * MPIC interrupts for various IDSEL values (MPIC IRQ0 = + * Linux IRQ16 (to leave room for ISA IRQs at 0-15). + * PCI IDSEL/INTPIN->INTLINE + * A B C D + */ + { + { 19, 0, 0, 0 }, /* IDSEL 12 - SCSI */ + { 0, 0, 0, 0 }, /* IDSEL 13 - Universe PCI - VME */ + { 18, 0, 0, 0 }, /* IDSEL 14 - Enet 1 */ + { 0, 0, 0, 0 }, /* IDSEL 15 - unused */ + { 25, 26, 27, 28 }, /* IDSEL 16 - PCI/PMC Slot 1P */ + { 28, 25, 26, 27 }, /* IDSEL 17 - PCI/PMC Slot 2P */ + { 27, 28, 25, 26 }, /* IDSEL 18 - PCI Slot 3P */ + { 26, 0, 0, 0 }, /* IDSEL 19 - Enet 2 */ + { 25, 26, 27, 28 } /* IDSEL 20 - P2P Bridge */ + }; + + const long min_idsel = 12, max_idsel = 20, irqs_per_slot = 4; + return PCI_IRQ_TABLE_LOOKUP; +} + +#define MOTOROLA_CPUTYPE_REG 0x800 +#define MOTOROLA_BASETYPE_REG 0x803 +#define MPIC_RAVEN_ID 0x48010000 +#define MPIC_HAWK_ID 0x48030000 +#define MOT_PROC2_BIT 0x800 + +static u_char pplus_openpic_initsenses[] __initdata = { + 1, /* MVME2600_INT_SIO */ + 0, /* MVME2600_INT_FALCN_ECC_ERR */ + 1, /* MVME2600_INT_PCI_ETHERNET */ + 1, /* MVME2600_INT_PCI_SCSI */ + 1, /* MVME2600_INT_PCI_GRAPHICS */ + 1, /* MVME2600_INT_PCI_VME0 */ + 1, /* MVME2600_INT_PCI_VME1 */ + 1, /* MVME2600_INT_PCI_VME2 */ + 1, /* MVME2600_INT_PCI_VME3 */ + 1, /* MVME2600_INT_PCI_INTA */ + 1, /* MVME2600_INT_PCI_INTB */ + 1, /* MVME2600_INT_PCI_INTC */ + 1, /* MVME2600_INT_PCI_INTD */ + 1, /* MVME2600_INT_LM_SIG0 */ + 1, /* MVME2600_INT_LM_SIG1 */ +}; + +int mot_entry = -1; +int prep_keybd_present = 1; +int mot_multi = 0; + +int __init raven_init(void) +{ + unsigned short devid; + unsigned char base_mod; + + /* set the MPIC base address */ + early_write_config_dword(0, 0, 0, PCI_BASE_ADDRESS_1, 0x3cfc0000); + + pplus_mpic_init(PREP_ISA_MEM_BASE); + + OpenPIC_InitSenses = pplus_openpic_initsenses; + OpenPIC_NumInitSenses = sizeof(pplus_openpic_initsenses); + + ppc_md.get_irq = openpic_get_irq; + + /* This is a hack. If this is a 2300 or 2400 mot board then there is + * no keyboard controller and we have to indicate that. + */ + + early_read_config_word(0, 0, 0, PCI_VENDOR_ID, &devid); + base_mod = inb(MOTOROLA_BASETYPE_REG); + if ((devid == PCI_DEVICE_ID_MOTOROLA_HAWK) || + (base_mod == 0xF9) || + (base_mod == 0xFA) || (base_mod == 0xE1)) + prep_keybd_present = 0; + + return 1; +} + +struct brd_info { + int cpu_type; /* 0x100 mask assumes for Raven and Hawk boards that the level/edge are set */ + /* 0x200 if this board has a Hawk chip. */ + int base_type; + int max_cpu; /* ored with 0x80 if this board should be checked for multi CPU */ + const char *name; + int (*map_irq)(struct pci_dev *, + unsigned char, + unsigned char); +}; +struct brd_info mot_info[] = { + {0x300, 0x00, 0x00, "MVME 2400", Genesis2_map_irq}, + {0x1E0, 0xE0, 0x00, "Mesquite cPCI (MCP750)", mesquite_map_irq}, + {0x1E0, 0xE1, 0x00, "Sitka cPCI (MCPN750)", sitka_map_irq}, + {0x1E0, 0xE2, 0x00, "Mesquite cPCI (MCP750) w/ HAC", mesquite_map_irq}, + {0x1E0, 0xF6, 0x80, "MTX Plus", MTXplus_map_irq}, + {0x1E0, 0xF6, 0x81, "Dual MTX Plus", MTXplus_map_irq}, + {0x1E0, 0xF7, 0x80, "MTX wo/ Parallel Port", MTX_map_irq}, + {0x1E0, 0xF7, 0x81, "Dual MTX wo/ Parallel Port", MTX_map_irq}, + {0x1E0, 0xF8, 0x80, "MTX w/ Parallel Port", MTX_map_irq}, + {0x1E0, 0xF8, 0x81, "Dual MTX w/ Parallel Port", MTX_map_irq}, + {0x1E0, 0xF9, 0x00, "MVME 2300", Genesis2_map_irq}, + {0x1E0, 0xFA, 0x00, "MVME 2300SC/2600", Genesis2_map_irq}, + {0x1E0, 0xFB, 0x00, "MVME 2600 with MVME712M", Genesis2_map_irq}, + {0x1E0, 0xFC, 0x00, "MVME 2600/2700 with MVME761", Genesis2_map_irq}, + {0x1E0, 0xFD, 0x80, "MVME 3600 with MVME712M", Genesis2_map_irq}, + {0x1E0, 0xFD, 0x81, "MVME 4600 with MVME712M", Genesis2_map_irq}, + {0x1E0, 0xFE, 0x80, "MVME 3600 with MVME761", Genesis2_map_irq}, + {0x1E0, 0xFE, 0x81, "MVME 4600 with MVME761", Genesis2_map_irq}, + {0x000, 0x00, 0x00, "", NULL} +}; + +void __init pplus_set_board_type(void) +{ + unsigned char cpu_type; + unsigned char base_mod; + int entry; + unsigned short devid; + unsigned long *ProcInfo = NULL; + + cpu_type = inb(MOTOROLA_CPUTYPE_REG) & 0xF0; + base_mod = inb(MOTOROLA_BASETYPE_REG); + early_read_config_word(0, 0, 0, PCI_VENDOR_ID, &devid); + + for (entry = 0; mot_info[entry].cpu_type != 0; entry++) { + + /* Check for Hawk chip */ + if (mot_info[entry].cpu_type & 0x200) { + if (devid != PCI_DEVICE_ID_MOTOROLA_HAWK) + continue; + } else { + /* store the system config register for later use. */ + ProcInfo = (unsigned long *)ioremap(0xfef80400, 4); + + /* Check non hawk boards */ + if ((mot_info[entry].cpu_type & 0xff) != cpu_type) + continue; + + if (mot_info[entry].base_type == 0) { + mot_entry = entry; + break; + } + + if (mot_info[entry].base_type != base_mod) + continue; + } + + if (!(mot_info[entry].max_cpu & 0x80)) { + mot_entry = entry; + break; + } + + /* processor 1 not present and max processor zero indicated */ + if ((*ProcInfo & MOT_PROC2_BIT) && !(mot_info[entry].max_cpu & 0x7f)) { + mot_entry = entry; + break; + } + + /* processor 1 present and max processor zero indicated */ + if (!(*ProcInfo & MOT_PROC2_BIT) && (mot_info[entry].max_cpu & 0x7f)) { + mot_entry = entry; + break; + } + + /* Indicate to system if this is a multiprocessor board */ + if (!(*ProcInfo & MOT_PROC2_BIT)) { + mot_multi = 1; + } + } + + if (mot_entry == -1) + + /* No particular cpu type found - assume Mesquite (MCP750) */ + mot_entry = 1; + + Motherboard_map_name = (unsigned char *)mot_info[mot_entry].name; + ppc_md.pci_map_irq = mot_info[mot_entry].map_irq; +} +void __init +pplus_pib_init(void) +{ + unsigned char reg; + unsigned short short_reg; + + struct pci_dev *dev = NULL; + + /* + * Perform specific configuration for the Via Tech or + * or Winbond PCI-ISA-Bridge part. + */ + if ((dev = pci_find_device(PCI_VENDOR_ID_VIA, + PCI_DEVICE_ID_VIA_82C586_1, dev))) { + /* + * PPCBUG does not set the enable bits + * for the IDE device. Force them on here. + */ + pci_read_config_byte(dev, 0x40, ®); + + reg |= 0x03; /* IDE: Chip Enable Bits */ + pci_write_config_byte(dev, 0x40, reg); + } + if ((dev = pci_find_device(PCI_VENDOR_ID_VIA, + PCI_DEVICE_ID_VIA_82C586_2, + dev)) && (dev->devfn = 0x5a)) { + /* Force correct USB interrupt */ + dev->irq = 11; + pci_write_config_byte(dev, + PCI_INTERRUPT_LINE, + dev->irq); + } + if ((dev = pci_find_device(PCI_VENDOR_ID_WINBOND, + PCI_DEVICE_ID_WINBOND_83C553, dev))) { + /* Clear PCI Interrupt Routing Control Register. */ + short_reg = 0x0000; + pci_write_config_word(dev, 0x44, short_reg); + /* Route IDE interrupts to IRQ 14 */ + reg = 0xEE; + pci_write_config_byte(dev, 0x43, reg); + } + + if ((dev = pci_find_device(PCI_VENDOR_ID_WINBOND, + PCI_DEVICE_ID_WINBOND_82C105, dev))){ + /* + * Disable LEGIRQ mode so PCI INTS are routed + * directly to the 8259 and enable both channels + */ + pci_write_config_dword(dev, 0x40, 0x10ff0033); + + /* Force correct IDE interrupt */ + dev->irq = 14; + pci_write_config_byte(dev, + PCI_INTERRUPT_LINE, + dev->irq); + } +} + +void __init +pplus_set_VIA_IDE_legacy(void) +{ + unsigned short vend, dev; + + early_read_config_word(0, 0, PCI_DEVFN(0xb, 1), PCI_VENDOR_ID, &vend); + early_read_config_word(0, 0, PCI_DEVFN(0xb, 1), PCI_DEVICE_ID, &dev); + + if ((vend == PCI_VENDOR_ID_VIA) && + (dev == PCI_DEVICE_ID_VIA_82C586_1)) { + + unsigned char temp; + + /* put back original "standard" port base addresses */ + early_write_config_dword(0, 0, PCI_DEVFN(0xb, 1), + PCI_BASE_ADDRESS_0, 0x1f1); + early_write_config_dword(0, 0, PCI_DEVFN(0xb, 1), + PCI_BASE_ADDRESS_1, 0x3f5); + early_write_config_dword(0, 0, PCI_DEVFN(0xb, 1), + PCI_BASE_ADDRESS_2, 0x171); + early_write_config_dword(0, 0, PCI_DEVFN(0xb, 1), + PCI_BASE_ADDRESS_3, 0x375); + early_write_config_dword(0, 0, PCI_DEVFN(0xb, 1), + PCI_BASE_ADDRESS_4, 0xcc01); + + /* put into legacy mode */ + early_read_config_byte(0, 0, PCI_DEVFN(0xb, 1), PCI_CLASS_PROG, + &temp); + temp &= ~0x05; + early_write_config_byte(0, 0, PCI_DEVFN(0xb, 1), PCI_CLASS_PROG, + temp); + } +} + +void +pplus_set_VIA_IDE_native(void) +{ + unsigned short vend, dev; + + early_read_config_word(0, 0, PCI_DEVFN(0xb, 1), PCI_VENDOR_ID, &vend); + early_read_config_word(0, 0, PCI_DEVFN(0xb, 1), PCI_DEVICE_ID, &dev); + + if ((vend == PCI_VENDOR_ID_VIA) && + (dev == PCI_DEVICE_ID_VIA_82C586_1)) { + + unsigned char temp; + + /* put into native mode */ + early_read_config_byte(0, 0, PCI_DEVFN(0xb, 1), PCI_CLASS_PROG, + &temp); + temp |= 0x05; + early_write_config_byte(0, 0, PCI_DEVFN(0xb, 1), PCI_CLASS_PROG, + temp); + } +} + +void __init +pplus_pcibios_fixup(void) +{ + + printk("Setting PCI interrupts for a \"%s\"\n", Motherboard_map_name); + + /* Setup the Winbond or Via PIB */ + pplus_pib_init(); +} + +static void __init +pplus_init_resource(struct resource *res, unsigned long start, + unsigned long end, int flags) +{ + res->flags = flags; + res->start = start; + res->end = end; + res->name = "PCI host bridge"; + res->parent = NULL; + res->sibling = NULL; + res->child = NULL; +} + +void __init +pplus_setup_hose(void) +{ + struct pci_controller* hose; + + hose = pcibios_alloc_controller(); + if (!hose) + return; + + hose->first_busno = 0; + hose->last_busno = 0xff; + + hose->pci_mem_offset = PREP_ISA_MEM_BASE; + hose->io_base_virt = (void *)PREP_ISA_IO_BASE; + + pplus_init_resource(&hose->io_resource, 0x00000000, 0x0fffffff, + IORESOURCE_IO); + pplus_init_resource(&hose->mem_resources[0], 0xc0000000, 0xfdffffff, + IORESOURCE_MEM); + + hose->io_space.start = 0x00000000; + hose->io_space.end = 0x0fffffff; + hose->mem_space.start = 0x00000000; + hose->mem_space.end = 0x3cfbffff; /* MPIC at 0x3cfc0000-0x3dffffff */ + + setup_indirect_pci(hose, 0x80000cf8, 0x80000cfc); + + pplus_set_VIA_IDE_legacy(); + + hose->last_busno = pciauto_bus_scan(hose, hose->first_busno); + + ppc_md.pcibios_fixup = pplus_pcibios_fixup; + ppc_md.pci_swizzle = common_swizzle; + pplus_set_board_type(); +} + diff --git a/arch/ppc/platforms/pplus_setup.c b/arch/ppc/platforms/pplus_setup.c new file mode 100644 index 000000000000..e79b90df1b62 --- /dev/null +++ b/arch/ppc/platforms/pplus_setup.c @@ -0,0 +1,553 @@ +/* + * arch/ppc/platforms/pplus_setup.c + * + * Board setup routines for MCG PowerPlus + * + * Author: Randy Vinson <rvinson@mvista.com> + * + * Derived from original PowerPlus PReP work by + * Cort Dougan, Johnnie Peters, Matt Porter, and + * Troy Benjegerdes. + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <linux/config.h> +#include <linux/delay.h> +#include <linux/module.h> +#include <linux/errno.h> +#include <linux/sched.h> +#include <linux/kernel.h> +#include <linux/mm.h> +#include <linux/stddef.h> +#include <linux/unistd.h> +#include <linux/ptrace.h> +#include <linux/slab.h> +#include <linux/user.h> +#include <linux/a.out.h> +#include <linux/tty.h> +#include <linux/major.h> +#include <linux/interrupt.h> +#include <linux/reboot.h> +#include <linux/init.h> +#include <linux/blk.h> +#include <linux/ioport.h> +#include <linux/console.h> +#include <linux/timex.h> +#include <linux/pci.h> +#include <linux/irq.h> +#include <linux/ide.h> +#include <linux/kdev_t.h> +#include <linux/seq_file.h> + +#include <asm/sections.h> +#include <asm/mmu.h> +#include <asm/processor.h> +#include <asm/system.h> +#include <asm/residual.h> +#include <asm/io.h> +#include <asm/pgtable.h> +#include <asm/cache.h> +#include <asm/dma.h> +#include <asm/machdep.h> +#include <asm/mk48t59.h> +#include <asm/prep_nvram.h> +#include <asm/raven.h> +#include <asm/keyboard.h> +#include <asm/vga.h> +#include <asm/time.h> + +#include <asm/i8259.h> +#include <asm/open_pic.h> +#include <asm/pplus.h> +#include <asm/todc.h> +#include <asm/bootinfo.h> + +#undef CONFIG_SERIAL_TEXT_DEBUG +#undef DUMP_DBATS + +TODC_ALLOC(); + +extern int pckbd_setkeycode(unsigned int scancode, unsigned int keycode); +extern int pckbd_getkeycode(unsigned int scancode); +extern int pckbd_translate(unsigned char scancode, unsigned char *keycode, + char raw_mode); +extern char pckbd_unexpected_up(unsigned char keycode); +extern void pckbd_leds(unsigned char leds); +extern void pckbd_init_hw(void); +extern unsigned char pckbd_sysrq_xlate[128]; + +extern void pplus_setup_hose(void); + +extern void pplus_set_VIA_IDE_native(void); + +extern unsigned long loops_per_jiffy; + +static int +pplus_show_cpuinfo(struct seq_file *m) +{ + extern char *Motherboard_map_name; + + seq_printf(m, "vendor\t\t: Motorola MCG\n"); + seq_printf(m, "machine\t\t: %s\n", Motherboard_map_name); + + return 0; +} + +static void __init +pplus_setup_arch(void) +{ + unsigned char reg; + + if ( ppc_md.progress ) + ppc_md.progress("pplus_setup_arch: enter\n", 0); + + /* init to some ~sane value until calibrate_delay() runs */ + loops_per_jiffy = 50000000; + + if ( ppc_md.progress ) + ppc_md.progress("pplus_setup_arch: find_bridges\n", 0); + + /* Setup PCI host bridge */ + pplus_setup_hose(); + + /* Set up floppy in PS/2 mode */ + outb(0x09, SIO_CONFIG_RA); + reg = inb(SIO_CONFIG_RD); + reg = (reg & 0x3F) | 0x40; + outb(reg, SIO_CONFIG_RD); + outb(reg, SIO_CONFIG_RD); /* Have to write twice to change! */ + + /* Enable L2. Assume we don't need to flush -- Cort*/ + *(unsigned char *)(0x8000081c) |= 3; + +#ifdef CONFIG_BLK_DEV_INITRD + if (initrd_start) + ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); /* /dev/ram */ + else +#endif +#ifdef CONFIG_ROOT_NFS + ROOT_DEV = to_kdev_t(0x00ff); /* /dev/nfs */ +#else + ROOT_DEV = to_kdev_t(0x0802); /* /dev/sda2 */ +#endif + + printk("PowerPlus port (C) 2001 MontaVista Software, Inc. (source@mvista.com)\n"); + + if ( ppc_md.progress ) + ppc_md.progress("pplus_setup_arch: raven_init\n", 0); + + raven_init(); + +#ifdef CONFIG_VGA_CONSOLE + /* remap the VGA memory */ + vgacon_remap_base = 0xf0000000; + conswitchp = &vga_con; +#elif defined(CONFIG_DUMMY_CONSOLE) + conswitchp = &dummy_con; +#endif + if ( ppc_md.progress ) + ppc_md.progress("pplus_setup_arch: exit\n", 0); +} + +static void +pplus_restart(char *cmd) +{ + unsigned long i = 10000; + + __cli(); + + /* set VIA IDE controller into native mode */ + pplus_set_VIA_IDE_native(); + + /* set exception prefix high - to the prom */ + _nmask_and_or_msr(0, MSR_IP); + + /* make sure bit 0 (reset) is a 0 */ + outb( inb(0x92) & ~1L , 0x92 ); + /* signal a reset to system control port A - soft reset */ + outb( inb(0x92) | 1 , 0x92 ); + + while ( i != 0 ) i++; + panic("restart failed\n"); +} + +static void +pplus_halt(void) +{ + unsigned long flags; + __cli(); + /* set exception prefix high - to the prom */ + save_flags( flags ); + restore_flags( flags|MSR_IP ); + + /* make sure bit 0 (reset) is a 0 */ + outb( inb(0x92) & ~1L , 0x92 ); + /* signal a reset to system control port A - soft reset */ + outb( inb(0x92) | 1 , 0x92 ); + + while ( 1 ) ; + /* + * Not reached + */ +} + +static void +pplus_power_off(void) +{ + pplus_halt(); +} + +static unsigned int +pplus_irq_cannonicalize(u_int irq) +{ + if (irq == 2) + { + return 9; + } + else + { + return irq; + } +} + +static int +pplus_get_irq(struct pt_regs *regs) +{ + return i8259_poll(); +} + +static void __init +pplus_init_IRQ(void) +{ + int i; + + if (OpenPIC_Addr != NULL) + openpic_init(1, NUM_8259_INTERRUPTS, 0, -1); + for ( i = 0 ; i < NUM_8259_INTERRUPTS ; i++ ) + irq_desc[i].handler = &i8259_pic; + i8259_init(NULL); +} + +#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) +/* + * IDE stuff. + */ +static int +pplus_ide_default_irq(ide_ioreg_t base) +{ + switch (base) { + case 0x1f0: return 14; + case 0x170: return 15; + default: return 0; + } +} + +static ide_ioreg_t +pplus_ide_default_io_base(int index) +{ + switch (index) { + case 0: return 0x1f0; + case 1: return 0x170; + default: + return 0; + } +} + +static int +pplus_ide_check_region(ide_ioreg_t from, unsigned int extent) +{ + return check_region(from, extent); +} + +static void +pplus_ide_request_region(ide_ioreg_t from, + unsigned int extent, + const char *name) +{ + request_region(from, extent, name); +} + +static void +pplus_ide_release_region(ide_ioreg_t from, + unsigned int extent) +{ + release_region(from, extent); +} + +static void __init +pplus_ide_init_hwif_ports (hw_regs_t *hw, ide_ioreg_t data_port, ide_ioreg_t ctrl_port, int *irq) +{ + ide_ioreg_t reg = data_port; + int i; + + for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) { + hw->io_ports[i] = reg; + reg += 1; + } + if (ctrl_port) { + hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port; + } else { + hw->io_ports[IDE_CONTROL_OFFSET] = hw->io_ports[IDE_DATA_OFFSET] + 0x206; + } + if (irq != NULL) + *irq = pplus_ide_default_irq(data_port); +} +#endif + +#ifdef CONFIG_SMP +/* PowerPlus (MTX) support */ +static int __init +smp_pplus_probe(void) +{ + extern int mot_multi; + + if (mot_multi) { + openpic_request_IPIs(); + smp_hw_index[1] = 1; + return 2; + } + + return 1; +} + +static void __init +smp_pplus_kick_cpu(int nr) +{ + *(unsigned long *)KERNELBASE = nr; + asm volatile("dcbf 0,%0"::"r"(KERNELBASE):"memory"); + printk("CPU1 reset, waiting\n"); +} + +static void __init +smp_pplus_setup_cpu(int cpu_nr) +{ + if (OpenPIC_Addr) + do_openpic_setup_cpu(); +} + +static struct smp_ops_t pplus_smp_ops = { + smp_openpic_message_pass, + smp_pplus_probe, + smp_pplus_kick_cpu, + smp_pplus_setup_cpu, +}; +#endif /* CONFIG_SMP */ + +#ifdef DUMP_DBATS +static void print_dbat(int idx, u32 bat) { + + char str[64]; + + sprintf(str, "DBAT%c%c = 0x%08x\n", + (char)((idx - DBAT0U) / 2) + '0', + (idx & 1) ? 'L' : 'U', bat); + ppc_md.progress(str, 0); +} + +#define DUMP_DBAT(x) \ + do { \ + u32 __temp = mfspr(x);\ + print_dbat(x, __temp); \ + } while (0) + +static void dump_dbats(void) { + + if (ppc_md.progress) { + DUMP_DBAT(DBAT0U); + DUMP_DBAT(DBAT0L); + DUMP_DBAT(DBAT1U); + DUMP_DBAT(DBAT1L); + DUMP_DBAT(DBAT2U); + DUMP_DBAT(DBAT2L); + DUMP_DBAT(DBAT3U); + DUMP_DBAT(DBAT3L); + } +} +#endif + +static unsigned long __init +pplus_find_end_of_memory(void) +{ + unsigned long total; + + if (ppc_md.progress) + ppc_md.progress("pplus_find_end_of_memory\n",0); + +#ifdef DUMP_DBATS + dump_dbats(); +#endif + + total = pplus_get_mem_size(0xfef80000); + return (total); +} + +static void __init +pplus_map_io(void) +{ + io_block_mapping(0x80000000, 0x80000000, 0x10000000, _PAGE_IO); + io_block_mapping(0xf0000000, 0xc0000000, 0x08000000, _PAGE_IO); +} + +static void __init +pplus_init2(void) +{ +#ifdef CONFIG_NVRAM + request_region(PREP_NVRAM_AS0, 0x8, "nvram"); +#endif + request_region(0x20,0x20,"pic1"); + request_region(0xa0,0x20,"pic2"); + request_region(0x00,0x20,"dma1"); + request_region(0x40,0x20,"timer"); + request_region(0x80,0x10,"dma page reg"); + request_region(0xc0,0x20,"dma2"); +} + +/* + * Set BAT 2 to access 0x8000000 so progress messages will work and set BAT 3 + * to 0xf0000000 to access Falcon/Raven or Hawk registers + */ +static __inline__ void +pplus_set_bat(void) +{ + static int mapping_set = 0; + + if (!mapping_set) { + + /* wait for all outstanding memory accesses to complete */ + mb(); + + /* setup DBATs */ + mtspr(DBAT2U, 0x80001ffe); + mtspr(DBAT2L, 0x8000002a); + mtspr(DBAT3U, 0xf0001ffe); + mtspr(DBAT3L, 0xf000002a); + + /* wait for updates */ + mb(); + + mapping_set = 1; + } + + return; +} + +#ifdef CONFIG_SERIAL_TEXT_DEBUG +#include <linux/serial.h> +#include <linux/serialP.h> +#include <linux/serial_reg.h> +#include <asm/serial.h> + +static struct serial_state rs_table[RS_TABLE_SIZE] = { + SERIAL_PORT_DFNS /* Defined in <asm/serial.h> */ +}; + + void +pplus_progress(char *s, unsigned short hex) +{ + volatile char c; + volatile unsigned long com_port; + u16 shift; + + com_port = rs_table[0].port + isa_io_base; + shift = rs_table[0].iomem_reg_shift; + + while ((c = *s++) != 0) { + while ((*((volatile unsigned char *)com_port + + (UART_LSR << shift)) & UART_LSR_THRE) == 0) + ; + *(volatile unsigned char *)com_port = c; + + if (c == '\n') { + while ((*((volatile unsigned char *)com_port + + (UART_LSR << shift)) & UART_LSR_THRE) == 0) + ; + *(volatile unsigned char *)com_port = '\r'; + } + } +} +#endif /* CONFIG_SERIAL_TEXT_DEBUG */ + +void __init +platform_init(unsigned long r3, unsigned long r4, unsigned long r5, + unsigned long r6, unsigned long r7) +{ + parse_bootinfo(find_bootinfo()); + + /* Map in board regs, etc. */ + pplus_set_bat(); + + isa_io_base = PREP_ISA_IO_BASE; + isa_mem_base = PREP_ISA_MEM_BASE; + pci_dram_offset = PREP_PCI_DRAM_OFFSET; + ISA_DMA_THRESHOLD = 0x00ffffff; + DMA_MODE_READ = 0x44; + DMA_MODE_WRITE = 0x48; + + ppc_md.setup_arch = pplus_setup_arch; + ppc_md.show_percpuinfo = NULL; + ppc_md.show_cpuinfo = pplus_show_cpuinfo; + ppc_md.irq_cannonicalize = pplus_irq_cannonicalize; + ppc_md.init_IRQ = pplus_init_IRQ; + /* this gets changed later on if we have an OpenPIC -- Cort */ + ppc_md.get_irq = pplus_get_irq; + ppc_md.init = pplus_init2; + + ppc_md.restart = pplus_restart; + ppc_md.power_off = pplus_power_off; + ppc_md.halt = pplus_halt; + + TODC_INIT(TODC_TYPE_MK48T59, PREP_NVRAM_AS0, PREP_NVRAM_AS1, + PREP_NVRAM_DATA, 8); + + ppc_md.time_init = todc_time_init; + ppc_md.set_rtc_time = todc_set_rtc_time; + ppc_md.get_rtc_time = todc_get_rtc_time; + ppc_md.calibrate_decr = todc_calibrate_decr; + ppc_md.nvram_read_val = todc_m48txx_read_val; + ppc_md.nvram_write_val = todc_m48txx_write_val; + + ppc_md.find_end_of_memory = pplus_find_end_of_memory; + ppc_md.setup_io_mappings = pplus_map_io; + +#ifdef CONFIG_SERIAL_TEXT_DEBUG + ppc_md.progress = pplus_progress; +#else /* !CONFIG_SERIAL_TEXT_DEBUG */ + ppc_md.progress = NULL; +#endif /* CONFIG_SERIAL_TEXT_DEBUG */ + +#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) + ppc_ide_md.default_irq = pplus_ide_default_irq; + ppc_ide_md.default_io_base = pplus_ide_default_io_base; + ppc_ide_md.ide_check_region = pplus_ide_check_region; + ppc_ide_md.ide_request_region = pplus_ide_request_region; + ppc_ide_md.ide_release_region = pplus_ide_release_region; + ppc_ide_md.ide_init_hwif = pplus_ide_init_hwif_ports; +#endif + +#ifdef CONFIG_VT + ppc_md.kbd_setkeycode = pckbd_setkeycode; + ppc_md.kbd_getkeycode = pckbd_getkeycode; + ppc_md.kbd_translate = pckbd_translate; + ppc_md.kbd_unexpected_up = pckbd_unexpected_up; + ppc_md.kbd_leds = pckbd_leds; + ppc_md.kbd_init_hw = pckbd_init_hw; +#ifdef CONFIG_MAGIC_SYSRQ + ppc_md.ppc_kbd_sysrq_xlate = pckbd_sysrq_xlate; + SYSRQ_KEY = 0x54; +#endif +#endif + +#ifdef CONFIG_SMP + ppc_md.smp_ops = &pplus_smp_ops; +#endif /* CONFIG_SMP */ +} diff --git a/arch/ppc/kernel/prep_nvram.c b/arch/ppc/platforms/prep_nvram.c index 0049e1b0ffb9..dad7771bdb2b 100644 --- a/arch/ppc/kernel/prep_nvram.c +++ b/arch/ppc/platforms/prep_nvram.c @@ -1,8 +1,8 @@ /* - * BK Id: SCCS/s.prep_nvram.c 1.12 09/08/01 15:47:42 paulus + * BK Id: %F% %I% %G% %U% %#% */ /* - * linux/arch/ppc/kernel/prep_nvram.c + * arch/ppc/platforms/prep_nvram.c * * Copyright (C) 1998 Corey Minyard * diff --git a/arch/ppc/kernel/prep_pci.c b/arch/ppc/platforms/prep_pci.c index 0db1fde7c06e..393e5fe341de 100644 --- a/arch/ppc/kernel/prep_pci.c +++ b/arch/ppc/platforms/prep_pci.c @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.prep_pci.c 1.31 10/05/01 17:48:18 trini + * BK Id: %F% %I% %G% %U% %#% */ /* * PReP pci functions. @@ -25,9 +25,7 @@ #include <asm/processor.h> #include <asm/irq.h> #include <asm/machdep.h> - -#include "pci.h" -#include "open_pic.h" +#include <asm/open_pic.h> #define MAX_DEVNR 22 @@ -1190,6 +1188,29 @@ prep_pcibios_fixup(void) } static void __init +prep_pcibios_after_init(void) +{ +#if 0 + struct pci_dev *dev; + + /* If there is a WD 90C, reset the IO BAR to 0x0 (it started that + * way, but the PCI layer relocated it because it thought 0x0 was + * invalid for a BAR). + * If you don't do this, the card's VGA base will be <IO BAR>+0xc0000 + * instead of 0xc0000. vgacon.c (for example) is completely unaware of + * this little quirk. + */ + dev = pci_find_device(PCI_VENDOR_ID_WD, PCI_DEVICE_ID_WD_90C, NULL); + if (dev) { + dev->resource[1].end -= dev->resource[1].start; + dev->resource[1].start = 0; + /* tell the hardware */ + pci_write_config_dword(dev, PCI_BASE_ADDRESS_1, 0x0); + } +#endif +} + +static void __init prep_init_resource(struct resource *res, unsigned long start, unsigned long end, int flags) { @@ -1216,13 +1237,14 @@ prep_find_bridges(void) hose->pci_mem_offset = PREP_ISA_MEM_BASE; hose->io_base_phys = PREP_ISA_IO_BASE; hose->io_base_virt = (void *)0x80000000; /* see prep_map_io() */ - prep_init_resource(&hose->io_resource, 0, 0x0fffffff, IORESOURCE_IO); + prep_init_resource(&hose->io_resource, 0, 0x00ffffff, IORESOURCE_IO); prep_init_resource(&hose->mem_resources[0], 0xc0000000, 0xfeffffff, IORESOURCE_MEM); - + hose->ops = &prep_pci_ops; + printk("PReP architecture\n"); - { #ifdef CONFIG_PREP_RESIDUAL + { PPC_DEVICE *hostbridge; hostbridge = residual_find_device(PROCESSORDEVICE, NULL, @@ -1238,12 +1260,13 @@ prep_find_bridges(void) setup_indirect_pci(hose, ld_le32((unsigned *) (p.PPCData)), ld_le32((unsigned *) (p.PPCData+8))); +#undef p } else setup_indirect_pci(hose, 0x80000cf8, 0x80000cfc); - } else -#endif /* CONFIG_PREP_RESIDUAL */ - hose->ops = &prep_pci_ops; + } } +#endif /* CONFIG_PREP_RESIDUAL */ ppc_md.pcibios_fixup = prep_pcibios_fixup; + ppc_md.pcibios_after_init = prep_pcibios_after_init; } diff --git a/arch/ppc/kernel/prep_setup.c b/arch/ppc/platforms/prep_setup.c index cf8ecaae9bcb..7bfcb4634bd0 100644 --- a/arch/ppc/kernel/prep_setup.c +++ b/arch/ppc/platforms/prep_setup.c @@ -1,8 +1,8 @@ /* - * BK Id: SCCS/s.prep_setup.c 1.44 11/13/01 21:26:07 paulus + * BK Id: %F% %I% %G% %U% %#% */ /* - * linux/arch/ppc/kernel/setup.c + * arch/ppc/platforms/setup.c * * Copyright (C) 1995 Linus Torvalds * Adapted from 'alpha' version by Gary Thomas @@ -57,15 +57,8 @@ #include <asm/keyboard.h> #include <asm/vga.h> #include <asm/time.h> - -#include "local_irq.h" -#include "i8259.h" -#include "open_pic.h" - -#if defined(CONFIG_SOUND) || defined(CONFIG_SOUND_MODULE) -#include <../drivers/sound/sound_config.h> -#include <../drivers/sound/dev_table.h> -#endif +#include <asm/i8259.h> +#include <asm/open_pic.h> unsigned char ucSystemType; unsigned char ucBoardRev; @@ -103,15 +96,17 @@ int _prep_type; /* for the mac fs */ kdev_t boot_dev; -/* used in nasty hack for sound - see prep_setup_arch() -- Cort */ + +#ifdef CONFIG_SOUND_CS4232 long ppc_cs4232_dma, ppc_cs4232_dma2; +#endif extern PTE *Hash, *Hash_end; extern unsigned long Hash_size, Hash_mask; extern int probingmem; extern unsigned long loops_per_jiffy; -#ifdef CONFIG_SOUND_MODULE +#ifdef CONFIG_SOUND_CS4232 EXPORT_SYMBOL(ppc_cs4232_dma); EXPORT_SYMBOL(ppc_cs4232_dma2); #endif @@ -183,7 +178,7 @@ prep_show_cpuinfo(struct seq_file *m) no_l2: #ifdef CONFIG_PREP_RESIDUAL - if (res->ResidualLength == 0) { + if (res->ResidualLength != 0) { /* print info about SIMMs */ seq_printf(m, "simms\t\t: "); for (i = 0; (res->ActualNumMemories) && (i < MAX_MEMS); i++) { @@ -203,15 +198,13 @@ no_l2: static int __prep prep_show_percpuinfo(struct seq_file *m, int i) { - int len = 0; - /* PREP's without residual data will give incorrect values here */ seq_printf(m, "clock\t\t: "); #ifdef CONFIG_PREP_RESIDUAL if (res->ResidualLength) seq_printf(m, "%ldMHz\n", (res->VitalProductData.ProcessorHz > 1024) ? - res->VitalProductData.ProcessorHz>>20 : + res->VitalProductData.ProcessorHz / 1000000 : res->VitalProductData.ProcessorHz); else #endif /* CONFIG_PREP_RESIDUAL */ @@ -220,14 +213,119 @@ prep_show_percpuinfo(struct seq_file *m, int i) return 0; } +#ifdef CONFIG_SOUND_CS4232 +static long __init masktoint(unsigned int i) +{ + int t = -1; + while (i >> ++t) + ; + return (t-1); +} + +/* + * ppc_cs4232_dma and ppc_cs4232_dma2 are used in include/asm/dma.h + * to distinguish sound dma-channels from others. This is because + * blocksize on 16 bit dma-channels 5,6,7 is 128k, but + * the cs4232.c uses 64k like on 8 bit dma-channels 0,1,2,3 + */ + +static void __init prep_init_sound(void) +{ + PPC_DEVICE *audiodevice = NULL; + + /* + * Get the needed resource informations from residual data. + * + */ +#ifdef CONFIG_PREP_RESIDUAL + audiodevice = residual_find_device(~0, NULL, MultimediaController, + AudioController, -1, 0); + if (audiodevice != NULL) { + PnP_TAG_PACKET *pkt; + + pkt = PnP_find_packet((unsigned char *)&res->DevicePnPHeap[audiodevice->AllocatedOffset], + S5_Packet, 0); + if (pkt != NULL) + ppc_cs4232_dma = masktoint(pkt->S5_Pack.DMAMask); + pkt = PnP_find_packet((unsigned char*)&res->DevicePnPHeap[audiodevice->AllocatedOffset], + S5_Packet, 1); + if (pkt != NULL) + ppc_cs4232_dma2 = masktoint(pkt->S5_Pack.DMAMask); + } +#endif + + /* + * These are the PReP specs' defaults for the cs4231. We use these + * as fallback incase we don't have residual data. + * At least the IBM Thinkpad 850 with IDE DMA Channels at 6 and 7 + * will use the other values. + */ + if (audiodevice == NULL) { + switch (_prep_type) { + case _PREP_IBM: + ppc_cs4232_dma = 1; + ppc_cs4232_dma2 = -1; + break; + default: + ppc_cs4232_dma = 6; + ppc_cs4232_dma2 = 7; + } + } + + /* + * Find a way to push these informations to the cs4232 driver + * Give it out with printk, when not in cmd_line? + * Append it to cmd_line and saved_command_line? + * Format is cs4232=io,irq,dma,dma2 + */ +} +#endif /* CONFIG_SOUND_CS4232 */ + +/* + * Fill out screen_info according to the residual data. This allows us to use + * at least vesafb. + */ +static void __init +prep_init_vesa(void) +{ +#if defined(CONFIG_PREP_RESIDUAL) && \ + (defined(CONFIG_FB_VGA16) || defined(CONFIG_FB_VGA_16_MODULE) || \ + defined(CONFIG_FB_VESA)) + PPC_DEVICE *vgadev; + + vgadev = residual_find_device(~0, NULL, DisplayController, SVGAController, + -1, 0); + if (vgadev != NULL) { + PnP_TAG_PACKET *pkt; + + pkt = PnP_find_large_vendor_packet( + (unsigned char *)&res->DevicePnPHeap[vgadev->AllocatedOffset], + 0x04, 0); /* 0x04 = Display Tag */ + if (pkt != NULL) { + unsigned char *ptr = (unsigned char *)pkt; + + if (ptr[4]) { + /* graphics mode */ + screen_info.orig_video_isVGA = VIDEO_TYPE_VLFB; + + screen_info.lfb_depth = ptr[4] * 8; + + screen_info.lfb_width = swab16(*(short *)(ptr+6)); + screen_info.lfb_height = swab16(*(short *)(ptr+8)); + screen_info.lfb_linelength = swab16(*(short *)(ptr+10)); + + screen_info.lfb_base = swab32(*(long *)(ptr+12)); + screen_info.lfb_size = swab32(*(long *)(ptr+20)) / 65536; + } + } + } +#endif /* CONFIG_PREP_RESIDUAL */ +} + static void __init prep_setup_arch(void) { unsigned char reg; -#if 0 /* unused?? */ - unsigned char ucMothMemType; - unsigned char ucEquipPres1; -#endif /* init to some ~sane value until calibrate_delay() runs */ loops_per_jiffy = 50000000; @@ -242,13 +340,6 @@ prep_setup_arch(void) outb(reg, SIO_CONFIG_RD); outb(reg, SIO_CONFIG_RD); /* Have to write twice to change! */ - /* - * We need to set up the NvRAM access routines early as prep_init - * has yet to be called - */ - ppc_md.nvram_read_val = prep_nvram_read_val; - ppc_md.nvram_write_val = prep_nvram_write_val; - /* we should determine this according to what we find! -- Cort */ switch ( _prep_type ) { @@ -262,7 +353,7 @@ prep_setup_arch(void) *(unsigned char *)(0x8000081c) |= 3; #ifdef CONFIG_BLK_DEV_INITRD if (initrd_start) - ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); /* /dev/ram */ + ROOT_DEV = mk_kdev(RAMDISK_MAJOR, 0); /* /dev/ram */ else #endif #ifdef CONFIG_ROOT_NFS @@ -287,46 +378,11 @@ prep_setup_arch(void) } } -#ifdef CONFIG_SOUND_CS4232 - /* - * setup proper values for the cs4232 driver so we don't have - * to recompile for the motorola or ibm workstations sound systems. - * This is a really nasty hack, but unless we change the driver - * it's the only way to support both addrs from one binary. - * -- Cort - */ - if ( _machine == _MACH_prep ) - { - extern struct card_info snd_installed_cards[]; - struct card_info *snd_ptr; - - for ( snd_ptr = snd_installed_cards; - snd_ptr < &snd_installed_cards[num_sound_cards]; - snd_ptr++ ) - { - if ( snd_ptr->card_type == SNDCARD_CS4232 ) - { - if ( _prep_type == _PREP_Motorola ) - { - snd_ptr->config.io_base = 0x830; - snd_ptr->config.irq = 10; - snd_ptr->config.dma = ppc_cs4232_dma = 6; - snd_ptr->config.dma2 = ppc_cs4232_dma2 = 7; - } - if ( _prep_type == _PREP_IBM ) - { - snd_ptr->config.io_base = 0x530; - snd_ptr->config.irq = 5; - snd_ptr->config.dma = ppc_cs4232_dma = 1; - /* this is wrong - but leave it for now */ - snd_ptr->config.dma2 = ppc_cs4232_dma2 = 7; - } - } - } - } -#endif /* CONFIG_SOUND_CS4232 */ +#ifdef CONFIG_SOUND_CS4232 + prep_init_sound(); +#endif /* CONFIG_SOUND_CS4232 */ - /*print_residual_device_info();*/ + prep_init_vesa(); switch (_prep_type) { case _PREP_Motorola: @@ -338,9 +394,8 @@ prep_setup_arch(void) } #ifdef CONFIG_VGA_CONSOLE - /* remap the VGA memory */ + /* vgacon.c needs to know where we mapped IO memory in io_block_mapping() */ vgacon_remap_base = 0xf0000000; - /*vgacon_remap_base = ioremap(0xc0000000, 0xba000);*/ conswitchp = &vga_con; #elif defined(CONFIG_DUMMY_CONSOLE) conswitchp = &dummy_con; @@ -602,12 +657,6 @@ static void __prep prep_power_off(void) { if ( _prep_type == _PREP_IBM) { - /* tested on: - * Carolina's: 7248-43P, 6070 (PowerSeries 850) - * should work on: - * Carolina: 6050 (PowerSeries 830) - * 7043-140 (Tiger 1) - */ unsigned long flags; __cli(); /* set exception prefix high - to the prom */ @@ -639,7 +688,7 @@ prep_irq_cannonicalize(u_int irq) static int __prep prep_get_irq(struct pt_regs *regs) { - return i8259_irq(smp_processor_id()); + return i8259_irq(); } static void __init @@ -651,7 +700,7 @@ prep_init_IRQ(void) openpic_init(1, NUM_8259_INTERRUPTS, 0, -1); for ( i = 0 ; i < NUM_8259_INTERRUPTS ; i++ ) irq_desc[i].handler = &i8259_pic; - i8259_init(); + i8259_init(0xbffffff0); /* PCI interrupt ack address for MPC105 and 106 */ } #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) @@ -705,25 +754,6 @@ prep_ide_release_region(ide_ioreg_t from, { release_region(from, extent); } - -static void __init -prep_ide_init_hwif_ports (hw_regs_t *hw, ide_ioreg_t data_port, ide_ioreg_t ctrl_port, int *irq) -{ - ide_ioreg_t reg = data_port; - int i; - - for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) { - hw->io_ports[i] = reg; - reg += 1; - } - if (ctrl_port) { - hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port; - } else { - hw->io_ports[IDE_CONTROL_OFFSET] = hw->io_ports[IDE_DATA_OFFSET] + 0x206; - } - if (irq != NULL) - *irq = 0; -} #endif #ifdef CONFIG_SMP @@ -814,8 +844,6 @@ prep_init2(void) #ifdef CONFIG_NVRAM request_region(PREP_NVRAM_AS0, 0x8, "nvram"); #endif - request_region(0x20,0x20,"pic1"); - request_region(0xa0,0x20,"pic2"); request_region(0x00,0x20,"dma1"); request_region(0x40,0x20,"timer"); request_region(0x80,0x10,"dma page reg"); @@ -834,21 +862,6 @@ prep_init(unsigned long r3, unsigned long r4, unsigned long r5, } #endif -#ifdef CONFIG_BLK_DEV_INITRD - if ( r4 ) - { - initrd_start = r4 + KERNELBASE; - initrd_end = r5 + KERNELBASE; - } -#endif /* CONFIG_BLK_DEV_INITRD */ - - /* Copy cmd_line parameters */ - if ( r6 ) - { - *(char *)(r7 + KERNELBASE) = 0; - strcpy(cmd_line, (char *)(r6 + KERNELBASE)); - } - isa_io_base = PREP_ISA_IO_BASE; isa_mem_base = PREP_ISA_MEM_BASE; pci_dram_offset = PREP_PCI_DRAM_OFFSET; @@ -858,14 +871,12 @@ prep_init(unsigned long r3, unsigned long r4, unsigned long r5, /* figure out what kind of prep workstation we are */ #ifdef CONFIG_PREP_RESIDUAL - if ( res->ResidualLength != 0 ) - { + if ( res->ResidualLength != 0 ) { if ( !strncmp(res->VitalProductData.PrintableModel,"IBM",3) ) _prep_type = _PREP_IBM; else _prep_type = _PREP_Motorola; - } - else /* assume motorola if no residual (netboot?) */ + } else /* assume motorola if no residual (netboot?) */ #endif { _prep_type = _PREP_Motorola; @@ -884,6 +895,9 @@ prep_init(unsigned long r3, unsigned long r4, unsigned long r5, ppc_md.power_off = prep_power_off; ppc_md.halt = prep_halt; + ppc_md.nvram_read_val = prep_nvram_read_val; + ppc_md.nvram_write_val = prep_nvram_write_val; + ppc_md.time_init = NULL; if (_prep_type == _PREP_IBM) { ppc_md.set_rtc_time = mc146818_set_rtc_time; @@ -905,7 +919,6 @@ prep_init(unsigned long r3, unsigned long r4, unsigned long r5, ppc_ide_md.ide_check_region = prep_ide_check_region; ppc_ide_md.ide_request_region = prep_ide_request_region; ppc_ide_md.ide_release_region = prep_ide_release_region; - ppc_ide_md.ide_init_hwif = prep_ide_init_hwif_ports; #endif #ifdef CONFIG_VT diff --git a/arch/ppc/kernel/prep_time.c b/arch/ppc/platforms/prep_time.c index 2e51b272ddf7..4846d9fd60bc 100644 --- a/arch/ppc/kernel/prep_time.c +++ b/arch/ppc/platforms/prep_time.c @@ -1,16 +1,16 @@ /* - * BK Id: SCCS/s.prep_time.c 1.10 09/08/01 15:47:42 paulus + * BK Id: %F% %I% %G% %U% %#% */ /* - * linux/arch/i386/kernel/time.c + * arch/ppc/platforms/prep_time.c * * Copyright (C) 1991, 1992, 1995 Linus Torvalds * - * Adapted for PowerPC (PreP) by Gary Thomas - * Modified by Cort Dougan (cort@cs.nmt.edu) - * copied and modified from intel version - * + * Adapted for PowerPC (PReP) by Gary Thomas + * Modified by Cort Dougan (cort@cs.nmt.edu). + * Copied and modified from arch/i386/kernel/time.c */ + #include <linux/errno.h> #include <linux/sched.h> #include <linux/kernel.h> @@ -65,14 +65,14 @@ int mc146818_set_rtc_time(unsigned long nowtime) /* tell the clock it's being set */ save_control = CMOS_READ(RTC_CONTROL); - + CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL); - + /* stop and reset prescaler */ save_freq_select = CMOS_READ(RTC_FREQ_SELECT); - + CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT); - + tm.tm_year = (tm.tm_year - 1900) % 100; if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { BIN_TO_BCD(tm.tm_sec); @@ -88,7 +88,7 @@ int mc146818_set_rtc_time(unsigned long nowtime) CMOS_WRITE(tm.tm_mon, RTC_MONTH); CMOS_WRITE(tm.tm_mday, RTC_DAY_OF_MONTH); CMOS_WRITE(tm.tm_year, RTC_YEAR); - + /* The following flags have to be released exactly in this order, * otherwise the DS12887 (popular MC146818A clone with integrated * battery and quartz) will not reset the oscillator and will not @@ -161,7 +161,7 @@ int mk48t59_set_rtc_time(unsigned long nowtime) /* tell the clock it's being written */ save_control = ppc_md.nvram_read_val(MK48T59_RTC_CONTROLA); - + ppc_md.nvram_write_val(MK48T59_RTC_CONTROLA, (save_control | MK48T59_RTC_CA_WRITE)); @@ -179,7 +179,7 @@ int mk48t59_set_rtc_time(unsigned long nowtime) ppc_md.nvram_write_val(MK48T59_RTC_MONTH, tm.tm_mon); ppc_md.nvram_write_val(MK48T59_RTC_DAY_OF_MONTH, tm.tm_mday); ppc_md.nvram_write_val(MK48T59_RTC_YEAR, tm.tm_year); - + /* Turn off the write bit. */ ppc_md.nvram_write_val(MK48T59_RTC_CONTROLA, save_control); spin_unlock(&rtc_lock); diff --git a/arch/ppc/kernel/proc_rtas.c b/arch/ppc/platforms/proc_rtas.c index b893044fdb5d..b893044fdb5d 100644 --- a/arch/ppc/kernel/proc_rtas.c +++ b/arch/ppc/platforms/proc_rtas.c diff --git a/arch/ppc/platforms/prpmc750.h b/arch/ppc/platforms/prpmc750.h new file mode 100644 index 000000000000..860466419828 --- /dev/null +++ b/arch/ppc/platforms/prpmc750.h @@ -0,0 +1,65 @@ +/* + * include/asm-ppc/platforms/prpmc750.h + * + * Definitions for Motorola PrPMC750 board support + * + * Author: Matt Porter <mporter@mvista.com> + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#ifdef __KERNEL__ +#ifndef __ASM_PRPMC750_H__ +#define __ASM_PRPMC750_H__ + +#include <linux/serial_reg.h> + +#define PRPMC750_PCI_CONFIG_ADDR 0x80000cf8 +#define PRPMC750_PCI_CONFIG_DATA 0x80000cfc + +#define PRPMC750_PCI_PHY_MEM_BASE 0xc0000000 +#define PRPMC750_PCI_MEM_BASE 0xf0000000 +#define PRPMC750_PCI_IO_BASE 0x80000000 + +#define PRPMC750_ISA_IO_BASE PRPMC750_PCI_IO_BASE +#define PRPMC750_ISA_MEM_BASE PRPMC750_PCI_MEM_BASE +#define PRPMC750_PCI_MEM_OFFSET PRPMC750_PCI_PHY_MEM_BASE + +#define PRPMC750_SYS_MEM_BASE 0x80000000 + +#define PRPMC750_PCI_LOWER_MEM 0x00000000 +#define PRPMC750_PCI_UPPER_MEM_AUTO 0x3bf7ffff +#define PRPMC750_PCI_UPPER_MEM 0x3bffffff +#define PRPMC750_PCI_LOWER_IO 0x00000000 +#define PRPMC750_PCI_UPPER_IO 0x0ff7ffff + +#define PRPMC750_HAWK_MPIC_BASE 0xfbf80000 +#define PRPMC750_HAWK_SMC_BASE 0xfef80000 + +#define PRPMC750_BASE_BAUD 1843200 +#define PRPMC750_SERIAL_0 0xfef88000 +#define PRPMC750_SERIAL_0_DLL (PRPMC750_SERIAL_0 + (UART_DLL << 4)) +#define PRPMC750_SERIAL_0_DLM (PRPMC750_SERIAL_0 + (UART_DLM << 4)) +#define PRPMC750_SERIAL_0_LCR (PRPMC750_SERIAL_0 + (UART_LCR << 4)) + +#define PRPMC750_STATUS_REG 0xfef88080 +#define PRPMC750_BAUDOUT_MASK 0x02 +#define PRPMC750_MONARCH_MASK 0x01 + +#define PRPMC750_MODRST_REG 0xfef880a0 +#define PRPMC750_MODRST_MASK 0x01 + +#define PRPMC750_PIRQ_REG 0xfef880b0 +#define PRPMC750_SEL1_MASK 0x02 +#define PRPMC750_SEL0_MASK 0x01 + +#define PRPMC750_TBEN_REG 0xfef880c0 +#define PRPMC750_TBEN_MASK 0x01 + +#endif /* __ASM_PRPMC750_H__ */ +#endif /* __KERNEL__ */ diff --git a/arch/ppc/platforms/prpmc750_pci.c b/arch/ppc/platforms/prpmc750_pci.c new file mode 100644 index 000000000000..2c3a95c0caa3 --- /dev/null +++ b/arch/ppc/platforms/prpmc750_pci.c @@ -0,0 +1,147 @@ +/* + * arch/ppc/platforms/prpmc750_pci.c + * + * PCI support for Motorola PrPMC750 + * + * Author: Matt Porter <mporter@mvista.com> + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/pci.h> +#include <linux/slab.h> + +#include <asm/byteorder.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/uaccess.h> +#include <asm/machdep.h> +#include <asm/pci-bridge.h> +#include <platforms/prpmc750.h> + +/* + * Motorola PrPMC750/PrPMC800 in PrPMCBASE or PrPMC-Carrier + * Combined irq tables. Only Base has IDSEL 14, only Carrier has 21 and 22. + */ +static inline int +prpmc_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) +{ + static char pci_irq_table[][4] = + /* + * PCI IDSEL/INTPIN->INTLINE + * A B C D + */ + { + {12, 0, 0, 0}, /* IDSEL 14 - Ethernet, base */ + {0, 0, 0, 0}, /* IDSEL 15 - unused */ + {10, 11, 12, 9}, /* IDSEL 16 - PMC A1, PMC1 */ + {10, 11, 12, 9}, /* IDSEL 17 - PrPMC-A-B, PMC2-B */ + {11, 12, 9, 10}, /* IDSEL 18 - PMC A1-B, PMC1-B */ + {0, 0, 0, 0}, /* IDSEL 19 - unused */ + {9, 10, 11, 12}, /* IDSEL 20 - P2P Bridge */ + {11, 12, 9, 10}, /* IDSEL 21 - PMC A2, carrier */ + {12, 9, 10, 11}, /* IDSEL 22 - PMC A2-B, carrier */ + }; + const long min_idsel = 14, max_idsel = 22, irqs_per_slot = 4; + return PCI_IRQ_TABLE_LOOKUP; +}; + +static void __init +prpmc750_pcibios_fixup(void) +{ + struct pci_dev *dev; + unsigned short wtmp; + + /* + * Kludge to clean up after PPC6BUG which doesn't + * configure the CL5446 VGA card. Also the + * resource subsystem doesn't fixup the + * PCI mem resources on the CL5446. + */ + if ((dev = pci_find_device(PCI_VENDOR_ID_CIRRUS, + PCI_DEVICE_ID_CIRRUS_5446, 0))) + { + dev->resource[0].start += PRPMC750_PCI_PHY_MEM_BASE; + dev->resource[0].end += PRPMC750_PCI_PHY_MEM_BASE; + pci_read_config_word(dev, + PCI_COMMAND, + &wtmp); + pci_write_config_word(dev, + PCI_COMMAND, + wtmp|3); + /* Enable Color mode in MISC reg */ + outb(0x03, 0x3c2); + /* Select DRAM config reg */ + outb(0x0f, 0x3c4); + /* Set proper DRAM config */ + outb(0xdf, 0x3c5); + } +} + +void __init +prpmc750_find_bridges(void) +{ + struct pci_controller* hose; + + hose = pcibios_alloc_controller(); + if (!hose) + return; + + hose->first_busno = 0; + hose->last_busno = 0xff; + hose->pci_mem_offset = PRPMC750_PCI_PHY_MEM_BASE; + + pci_init_resource(&hose->io_resource, + PRPMC750_PCI_LOWER_IO, + PRPMC750_PCI_UPPER_IO, + IORESOURCE_IO, + "PCI host bridge"); + + pci_init_resource(&hose->mem_resources[0], + PRPMC750_PCI_LOWER_MEM + PRPMC750_PCI_PHY_MEM_BASE, + PRPMC750_PCI_UPPER_MEM + PRPMC750_PCI_PHY_MEM_BASE, + IORESOURCE_MEM, + "PCI host bridge"); + + hose->io_space.start = PRPMC750_PCI_LOWER_IO; + hose->io_space.end = PRPMC750_PCI_UPPER_IO; + hose->mem_space.start = PRPMC750_PCI_LOWER_MEM; + hose->mem_space.end = PRPMC750_PCI_UPPER_MEM_AUTO; + + hose->io_base_virt = (void *)PRPMC750_ISA_IO_BASE; + + setup_indirect_pci(hose, + PRPMC750_PCI_CONFIG_ADDR, + PRPMC750_PCI_CONFIG_DATA); + + /* + * Disable MPIC response to PCI I/O space (BAR 0). + * Make MPIC respond to PCI Mem space at specified address. + * (BAR 1). + */ + early_write_config_dword(hose, + 0, + PCI_DEVFN(0,0), + PCI_BASE_ADDRESS_0, + 0x00000000 | 0x1); + + early_write_config_dword(hose, + 0, + PCI_DEVFN(0,0), + PCI_BASE_ADDRESS_1, + (PRPMC750_HAWK_MPIC_BASE - + PRPMC750_PCI_MEM_OFFSET) | 0x0); + + hose->last_busno = pciauto_bus_scan(hose, hose->first_busno); + + ppc_md.pcibios_fixup = prpmc750_pcibios_fixup; + ppc_md.pci_swizzle = common_swizzle; + ppc_md.pci_map_irq = prpmc_map_irq; +} diff --git a/arch/ppc/platforms/prpmc750_serial.h b/arch/ppc/platforms/prpmc750_serial.h new file mode 100644 index 000000000000..c2795c70c457 --- /dev/null +++ b/arch/ppc/platforms/prpmc750_serial.h @@ -0,0 +1,45 @@ +/* + * include/asm-ppc/platforms/prpmc750_serial.h + * + * Motorola PrPMC750 serial support + * + * Author: Matt Porter <mporter@mvista.com> + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#ifdef __KERNEL__ +#ifndef __ASM_PRPMC750_SERIAL_H__ +#define __ASM_PRPMC750_SERIAL_H__ + +#include <linux/config.h> +#include <platforms/prpmc750.h> + +#define RS_TABLE_SIZE 4 + +/* Rate for the 1.8432 Mhz clock for the onboard serial chip */ +#define BASE_BAUD (PRPMC750_BASE_BAUD / 16) + +#ifndef SERIAL_MAGIC_KEY +#define kernel_debugger ppc_kernel_debug +#endif + +#ifdef CONFIG_SERIAL_DETECT_IRQ +#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF|ASYNC_SKIP_TEST|ASYNC_AUTO_IRQ) +#else +#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF|ASYNC_SKIP_TEST) +#endif + +#define SERIAL_PORT_DFNS \ + { 0, BASE_BAUD, PRPMC750_SERIAL_0, 1, STD_COM_FLAGS, \ + iomem_base: (unsigned char *)PRPMC750_SERIAL_0, \ + iomem_reg_shift: 4, \ + io_type: SERIAL_IO_MEM } /* ttyS0 */ + +#endif /* __ASM_PRPMC750_SERIAL_H__ */ +#endif /* __KERNEL__ */ diff --git a/arch/ppc/platforms/prpmc750_setup.c b/arch/ppc/platforms/prpmc750_setup.c new file mode 100644 index 000000000000..1d1fda2405cb --- /dev/null +++ b/arch/ppc/platforms/prpmc750_setup.c @@ -0,0 +1,291 @@ +/* + * arch/ppc/platforms/prpmc750_setup.c + * + * Board setup routines for Motorola PrPMC750 + * + * Author: Matt Porter <mporter@mvista.com> + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include <linux/config.h> +#include <linux/stddef.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/errno.h> +#include <linux/reboot.h> +#include <linux/pci.h> +#include <linux/kdev_t.h> +#include <linux/types.h> +#include <linux/major.h> +#include <linux/blk.h> +#include <linux/console.h> +#include <linux/delay.h> +#include <linux/irq.h> +#include <linux/seq_file.h> +#include <linux/ide.h> + +#include <asm/system.h> +#include <asm/pgtable.h> +#include <asm/page.h> +#include <asm/dma.h> +#include <asm/io.h> +#include <asm/machdep.h> +#include <asm/time.h> +#include <platforms/prpmc750.h> +#include <asm/open_pic.h> +#include <asm/bootinfo.h> +#include <asm/pplus.h> + +extern void prpmc750_find_bridges(void); +extern int mpic_init(void); +extern unsigned long loops_per_jiffy; + +static u_char prpmc750_openpic_initsenses[] __initdata = +{ + 1, /* PRPMC750_INT_HOSTINT0 */ + 1, /* PRPMC750_INT_UART */ + 1, /* PRPMC750_INT_DEBUGINT */ + 1, /* PRPMC750_INT_HAWK_WDT */ + 1, /* PRPMC750_INT_UNUSED */ + 1, /* PRPMC750_INT_ABORT */ + 1, /* PRPMC750_INT_HOSTINT1 */ + 1, /* PRPMC750_INT_HOSTINT2 */ + 1, /* PRPMC750_INT_HOSTINT3 */ + 1, /* PRPMC750_INT_PMC_INTA */ + 1, /* PRPMC750_INT_PMC_INTB */ + 1, /* PRPMC750_INT_PMC_INTC */ + 1, /* PRPMC750_INT_PMC_INTD */ + 1, /* PRPMC750_INT_UNUSED */ + 1, /* PRPMC750_INT_UNUSED */ + 1, /* PRPMC750_INT_UNUSED */ +}; + +static int +prpmc750_show_cpuinfo(struct seq_file *m) +{ + seq_printf(m, "machine\t\t: PrPMC750\n"); + + return 0; +} + +static void __init +prpmc750_setup_arch(void) +{ + /* init to some ~sane value until calibrate_delay() runs */ + loops_per_jiffy = 50000000/HZ; + + /* Lookup PCI host bridges */ + prpmc750_find_bridges(); + +#ifdef CONFIG_BLK_DEV_INITRD + if (initrd_start) + ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); /* /dev/ram */ + else +#endif +#ifdef CONFIG_ROOT_NFS + ROOT_DEV = to_kdev_t(0x00ff); /* /dev/nfs pseudo device */ +#else + ROOT_DEV = to_kdev_t(0x0802); /* /dev/sda2 */ +#endif + +#ifdef CONFIG_DUMMY_CONSOLE + conswitchp = &dummy_con; +#endif + + /* Find and map our OpenPIC */ + pplus_mpic_init(PRPMC750_PCI_MEM_OFFSET); + OpenPIC_InitSenses = prpmc750_openpic_initsenses; + OpenPIC_NumInitSenses = sizeof(prpmc750_openpic_initsenses); + + printk("PrPMC750 port (C) 2001 MontaVista Software, Inc. (source@mvista.com)\n"); +} + +/* + * Compute the PrPMC750's bus speed using the baud clock as a + * reference. + */ +static unsigned long __init +prpmc750_get_bus_speed(void) +{ + unsigned long tbl_start, tbl_end; + unsigned long current_state, old_state, bus_speed; + unsigned char lcr, dll, dlm; + int baud_divisor, count; + + /* Read the UART's baud clock divisor */ + lcr = readb(PRPMC750_SERIAL_0_LCR); + writeb(lcr | UART_LCR_DLAB, PRPMC750_SERIAL_0_LCR); + dll = readb(PRPMC750_SERIAL_0_DLL); + dlm = readb(PRPMC750_SERIAL_0_DLM); + writeb(lcr & ~UART_LCR_DLAB, PRPMC750_SERIAL_0_LCR); + baud_divisor = (dlm << 8) | dll; + + /* + * Use the baud clock divisor and base baud clock + * to determine the baud rate and use that as + * the number of baud clock edges we use for + * the time base sample. Make it half the baud + * rate. + */ + count = PRPMC750_BASE_BAUD / (baud_divisor * 16); + + /* Find the first edge of the baud clock */ + old_state = readb(PRPMC750_STATUS_REG) & PRPMC750_BAUDOUT_MASK; + do { + current_state = readb(PRPMC750_STATUS_REG) & + PRPMC750_BAUDOUT_MASK; + } while(old_state == current_state); + + old_state = current_state; + + /* Get the starting time base value */ + tbl_start = get_tbl(); + + /* + * Loop until we have found a number of edges equal + * to half the count (half the baud rate) + */ + do { + do { + current_state = readb(PRPMC750_STATUS_REG) & + PRPMC750_BAUDOUT_MASK; + } while(old_state == current_state); + old_state = current_state; + } while (--count); + + /* Get the ending time base value */ + tbl_end = get_tbl(); + + /* Compute bus speed */ + bus_speed = (tbl_end-tbl_start)*128; + + return bus_speed; +} + +static void __init +prpmc750_calibrate_decr(void) +{ + unsigned long freq; + int divisor = 4; + + freq = prpmc750_get_bus_speed(); + + tb_ticks_per_jiffy = freq / (HZ * divisor); + tb_to_us = mulhwu_scale_factor(freq/divisor, 1000000); +} + +static void +prpmc750_restart(char *cmd) +{ + __cli(); + writeb(PRPMC750_MODRST_MASK, PRPMC750_MODRST_REG); + while(1); +} + +static void +prpmc750_halt(void) +{ + __cli(); + while (1); +} + +static void +prpmc750_power_off(void) +{ + prpmc750_halt(); +} + +/* Resolves the open_pic.c build without including i8259.c */ +int i8259_poll(void) +{ + return 0; +} + +static void __init +prpmc750_init_IRQ(void) +{ + openpic_init(1, 0, 0, -1); +} + +/* + * Set BAT 3 to map 0xf0000000 to end of physical memory space. + */ +static __inline__ void +prpmc750_set_bat(void) +{ + unsigned long bat3u, bat3l; + static int mapping_set = 0; + + if (!mapping_set) + { + __asm__ __volatile__( + " lis %0,0xf000\n \ + ori %1,%0,0x002a\n \ + ori %0,%0,0x1ffe\n \ + mtspr 0x21e,%0\n \ + mtspr 0x21f,%1\n \ + isync\n \ + sync " + : "=r" (bat3u), "=r" (bat3l)); + + mapping_set = 1; + } + return; +} + +/* + * We need to read the Falcon/Hawk memory controller + * to properly determine this value + */ +static unsigned long __init +prpmc750_find_end_of_memory(void) +{ + /* Cover the Hawk registers with a BAT */ + prpmc750_set_bat(); + + /* Read the memory size from the Hawk SMC */ + return pplus_get_mem_size(PRPMC750_HAWK_SMC_BASE); +} + +static void __init +prpmc750_map_io(void) +{ + io_block_mapping(0x80000000, 0x80000000, 0x10000000, _PAGE_IO); + io_block_mapping(0xf0000000, 0xc0000000, 0x08000000, _PAGE_IO); + io_block_mapping(0xf8000000, 0xf8000000, 0x08000000, _PAGE_IO); +} + +void __init +platform_init(unsigned long r3, unsigned long r4, unsigned long r5, + unsigned long r6, unsigned long r7) +{ + parse_bootinfo(find_bootinfo()); + + isa_io_base = PRPMC750_ISA_IO_BASE; + isa_mem_base = PRPMC750_ISA_MEM_BASE; + pci_dram_offset = PRPMC750_SYS_MEM_BASE; + + ppc_md.setup_arch = prpmc750_setup_arch; + ppc_md.show_cpuinfo = prpmc750_show_cpuinfo; + ppc_md.init_IRQ = prpmc750_init_IRQ; + ppc_md.get_irq = openpic_get_irq; + + ppc_md.find_end_of_memory = prpmc750_find_end_of_memory; + ppc_md.setup_io_mappings = prpmc750_map_io; + + ppc_md.restart = prpmc750_restart; + ppc_md.power_off = prpmc750_power_off; + ppc_md.halt = prpmc750_halt; + + /* PrPMC750 has no timekeeper part */ + ppc_md.time_init = NULL; + ppc_md.get_rtc_time = NULL; + ppc_md.set_rtc_time = NULL; + ppc_md.calibrate_decr = prpmc750_calibrate_decr; +} diff --git a/arch/ppc/platforms/prpmc800.h b/arch/ppc/platforms/prpmc800.h new file mode 100644 index 000000000000..98b73d1f5763 --- /dev/null +++ b/arch/ppc/platforms/prpmc800.h @@ -0,0 +1,56 @@ +/* + * include/asm-ppc/platforms/prpmc800.h + * + * Definitions for Motorola PrPMC800 board support + * + * Author: Dale Farnsworth <dale.farnsworth@mvista.com> + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + /* + * From Processor to PCI: + * PCI Mem Space: 0x80000000 - 0xa0000000 -> 0x80000000 - 0xa0000000 (512 MB) + * PCI I/O Space: 0xfe400000 - 0xfeef0000 -> 0x00000000 - 0x00b00000 (11 MB) + * Note: Must skip 0xfe000000-0xfe400000 for CONFIG_HIGHMEM/PKMAP area + * + * From PCI to Processor: + * System Memory: 0x00000000 -> 0x00000000 + */ + + +#ifndef __ASMPPC_PRPMC800_H +#define __ASMPPC_PRPMC800_H + +#define PRPMC800_PCI_CONFIG_ADDR 0xfe000cf8 +#define PRPMC800_PCI_CONFIG_DATA 0xfe000cfc + +#define PRPMC800_PROC_PCI_IO_START 0xfe400000U +#define PRPMC800_PROC_PCI_IO_END 0xfeefffffU +#define PRPMC800_PCI_IO_START 0x00000000U +#define PRPMC800_PCI_IO_END 0x00afffffU + +#define PRPMC800_PROC_PCI_MEM_START 0x80000000U +#define PRPMC800_PROC_PCI_MEM_END 0x9fffffffU +#define PRPMC800_PCI_MEM_START 0x80000000U +#define PRPMC800_PCI_MEM_END 0x9fffffffU + +#define PRPMC800_PCI_DRAM_OFFSET 0x00000000U +#define PRPMC800_PCI_PHY_MEM_OFFSET 0x00000000U + +#define PRPMC800_ISA_IO_BASE PRPMC800_PROC_PCI_IO_START +#define PRPMC800_ISA_MEM_BASE 0x00000000U + +#define PRPMC800_HARRIER_XCSR_BASE 0xfeff0000 +#define PRPMC800_HARRIER_MPIC_BASE 0xff000000 + +#define PRPMC800_SERIAL_1 0xfeff00c0 + +#define PRPMC800_BASE_BAUD 1843200 + + +#endif /* __ASMPPC_PRPMC800_H */ diff --git a/arch/ppc/platforms/prpmc800_pci.c b/arch/ppc/platforms/prpmc800_pci.c new file mode 100644 index 000000000000..e487b2c7ce3e --- /dev/null +++ b/arch/ppc/platforms/prpmc800_pci.c @@ -0,0 +1,122 @@ +/* + * arch/ppc/platforms/prpmc800_pci.c + * + * PCI support for Motorola PrPMC800 + * + * Author: Dale Farnsworth <dale.farnsworth@mvista.com> + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/pci.h> +#include <linux/slab.h> + +#include <asm/byteorder.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/uaccess.h> +#include <asm/machdep.h> +#include <asm/pci-bridge.h> +#include <platforms/prpmc800.h> +#include <asm/harrier.h> + +/* + * Motorola PrPMC750/PrPMC800 in PrPMCBASE or PrPMC-Carrier + * Combined irq tables. Only Base has IDSEL 14, only Carrier has 21 and 22. + */ +static inline int +prpmc_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) +{ + static char pci_irq_table[][4] = + /* + * PCI IDSEL/INTPIN->INTLINE + * A B C D + */ + { + {12, 0, 0, 0}, /* IDSEL 14 - Ethernet, base */ + {0, 0, 0, 0}, /* IDSEL 15 - unused */ + {10, 11, 12, 9}, /* IDSEL 16 - PMC A1, PMC1 */ + {10, 11, 12, 9}, /* IDSEL 17 - PrPMC-A-B, PMC2-B */ + {11, 12, 9, 10}, /* IDSEL 18 - PMC A1-B, PMC1-B */ + {0, 0, 0, 0}, /* IDSEL 19 - unused */ + {9, 10, 11, 12}, /* IDSEL 20 - P2P Bridge */ + {11, 12, 9, 10}, /* IDSEL 21 - PMC A2, carrier */ + {12, 9, 10, 11}, /* IDSEL 22 - PMC A2-B, carrier */ + }; + const long min_idsel = 14, max_idsel = 22, irqs_per_slot = 4; + return PCI_IRQ_TABLE_LOOKUP; +}; + +void __init +prpmc800_find_bridges(void) +{ + struct pci_controller* hose; + int host_bridge; + + hose = pcibios_alloc_controller(); + if (!hose) + return; + + hose->first_busno = 0; + hose->last_busno = 0xff; + hose->pci_mem_offset = PRPMC800_PCI_PHY_MEM_OFFSET; + + pci_init_resource(&hose->io_resource, + PRPMC800_PCI_IO_START, + PRPMC800_PCI_IO_END, + IORESOURCE_IO, + "PCI host bridge"); + + pci_init_resource(&hose->mem_resources[0], + PRPMC800_PCI_MEM_START, + PRPMC800_PCI_MEM_END, + IORESOURCE_MEM, + "PCI host bridge"); + + hose->io_space.start = PRPMC800_PCI_IO_START; + hose->io_space.end = PRPMC800_PCI_IO_END; + hose->mem_space.start = PRPMC800_PCI_MEM_START; + hose->mem_space.end = PRPMC800_PCI_MEM_END; + hose->io_base_virt = (void *)PRPMC800_ISA_IO_BASE; + + setup_indirect_pci(hose, + PRPMC800_PCI_CONFIG_ADDR, + PRPMC800_PCI_CONFIG_DATA); + + /* Get host bridge vendor/dev id */ + early_read_config_dword(hose, + 0, + PCI_DEVFN(0,0), + PCI_VENDOR_ID, + &host_bridge); + + switch (host_bridge) { + case HARRIER_VEND_DEV_ID: + if (harrier_init(hose, + PRPMC800_HARRIER_XCSR_BASE, + PRPMC800_PROC_PCI_MEM_START, + PRPMC800_PROC_PCI_MEM_END, + PRPMC800_PROC_PCI_IO_START, + PRPMC800_PROC_PCI_IO_END, + PRPMC800_HARRIER_MPIC_BASE) != 0) { + printk("Could not initialize HARRIER bridge\n"); + } + break; + default: + printk("Host bridge 0x%x not supported\n", host_bridge); + } + + hose->last_busno = pciauto_bus_scan(hose, hose->first_busno); + + ppc_md.pcibios_fixup = NULL; + ppc_md.pcibios_fixup_bus = NULL; + ppc_md.pci_swizzle = common_swizzle; + ppc_md.pci_map_irq = prpmc_map_irq; +} diff --git a/arch/ppc/platforms/prpmc800_serial.h b/arch/ppc/platforms/prpmc800_serial.h new file mode 100644 index 000000000000..5af47d324106 --- /dev/null +++ b/arch/ppc/platforms/prpmc800_serial.h @@ -0,0 +1,51 @@ +/* + * include/asm-ppc/platforms/prpmc800_serial.h + * + * Definitions for Motorola MCG PRPMC800 cPCI board support + * + * Author: Dale Farnsworth dale.farnsworth@mvista.com + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#ifndef __ASMPPC_PRPMC800_SERIAL_H +#define __ASMPPC_PRPMC800_SERIAL_H + +#include <linux/config.h> +#include <platforms/prpmc800.h> + +#ifdef CONFIG_SERIAL_MANY_PORTS +#define RS_TABLE_SIZE 64 +#else +#define RS_TABLE_SIZE 4 +#endif + +/* Rate for the 1.8432 Mhz clock for the onboard serial chip */ +#define BASE_BAUD (PRPMC800_BASE_BAUD / 16) + +#ifndef SERIAL_MAGIC_KEY +#define kernel_debugger ppc_kernel_debug +#endif + +#ifdef CONFIG_SERIAL_DETECT_IRQ +#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF|ASYNC_SKIP_TEST|ASYNC_AUTO_IRQ) +#else +#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF|ASYNC_SKIP_TEST) +#endif + +/* UARTS are at IRQ 16 */ +#define STD_SERIAL_PORT_DFNS \ + { 0, BASE_BAUD, PRPMC800_SERIAL_1, 16, STD_COM_FLAGS, /* ttyS0 */\ + iomem_base: (unsigned char *)PRPMC800_SERIAL_1, \ + iomem_reg_shift: 0, \ + io_type: SERIAL_IO_MEM }, + +#define SERIAL_PORT_DFNS \ + STD_SERIAL_PORT_DFNS + +#endif /* __ASMPPC_PRPMC800_SERIAL_H */ diff --git a/arch/ppc/platforms/prpmc800_setup.c b/arch/ppc/platforms/prpmc800_setup.c new file mode 100644 index 000000000000..a2a66ba39187 --- /dev/null +++ b/arch/ppc/platforms/prpmc800_setup.c @@ -0,0 +1,336 @@ +/* + * + * Author: Dale Farnsworth <dale.farnsworth@mvista.com> + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include <linux/config.h> +#include <linux/stddef.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/errno.h> +#include <linux/reboot.h> +#include <linux/pci.h> +#include <linux/kdev_t.h> +#include <linux/types.h> +#include <linux/major.h> +#include <linux/blk.h> +#include <linux/console.h> +#include <linux/delay.h> +#include <linux/irq.h> +#include <linux/seq_file.h> +#include <linux/ide.h> + +#include <asm/system.h> +#include <asm/pgtable.h> +#include <asm/page.h> +#include <asm/dma.h> +#include <asm/io.h> +#include <asm/machdep.h> +#include <asm/time.h> +#include <platforms/prpmc800.h> +#include <asm/open_pic.h> +#include <asm/bootinfo.h> +#include <asm/harrier.h> + +#define HARRIER_REVI_REG (PRPMC800_HARRIER_XCSR_BASE+HARRIER_REVI_OFF) +#define HARRIER_UCTL_REG (PRPMC800_HARRIER_XCSR_BASE+HARRIER_UCTL_OFF) +#define HARRIER_MISC_CSR_REG (PRPMC800_HARRIER_XCSR_BASE+HARRIER_MISC_CSR_OFF) +#define HARRIER_IFEVP_REG (PRPMC800_HARRIER_MPIC_BASE+HARRIER_MPIC_IFEVP_OFF) +#define HARRIER_IFEDE_REG (PRPMC800_HARRIER_MPIC_BASE+HARRIER_MPIC_IFEDE_OFF) +#define HARRIER_FEEN_REG (PRPMC800_HARRIER_XCSR_BASE+HARRIER_FEEN_OFF) +#define HARRIER_FEMA_REG (PRPMC800_HARRIER_XCSR_BASE+HARRIER_FEMA_OFF) + +extern void prpmc800_find_bridges(void); +extern int mpic_init(void); +extern unsigned long loops_per_jiffy; + +static u_char prpmc800_openpic_initsenses[] __initdata = +{ + 1, /* PRPMC800_INT_HOSTINT0 */ + 1, /* PRPMC800_INT_UNUSED */ + 1, /* PRPMC800_INT_DEBUGINT */ + 1, /* PRPMC800_INT_HARRIER_WDT */ + 1, /* PRPMC800_INT_UNUSED */ + 1, /* PRPMC800_INT_UNUSED */ + 1, /* PRPMC800_INT_HOSTINT1 */ + 1, /* PRPMC800_INT_HOSTINT2 */ + 1, /* PRPMC800_INT_HOSTINT3 */ + 1, /* PRPMC800_INT_PMC_INTA */ + 1, /* PRPMC800_INT_PMC_INTB */ + 1, /* PRPMC800_INT_PMC_INTC */ + 1, /* PRPMC800_INT_PMC_INTD */ + 1, /* PRPMC800_INT_UNUSED */ + 1, /* PRPMC800_INT_UNUSED */ + 1, /* PRPMC800_INT_UNUSED */ + 1, /* PRPMC800_INT_HARRIER_INT (UARTS, ABORT, DMA) */ +}; + +static int +prpmc800_show_cpuinfo(struct seq_file *m) +{ + seq_printf(m, "machine\t\t: PrPMC800\n"); + + return 0; +} + +static void __init +prpmc800_setup_arch(void) +{ + + /* init to some ~sane value until calibrate_delay() runs */ + loops_per_jiffy = 50000000/HZ; + + /* Lookup PCI host bridges */ + prpmc800_find_bridges(); + +#ifdef CONFIG_BLK_DEV_INITRD + if (initrd_start) + ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); /* /dev/ram */ + else +#endif +#ifdef CONFIG_ROOT_NFS + ROOT_DEV = to_kdev_t(0x00ff); /* /dev/nfs pseudo device */ +#else + ROOT_DEV = to_kdev_t(0x0802); /* /dev/sda2 */ +#endif + +#ifdef CONFIG_DUMMY_CONSOLE + conswitchp = &dummy_con; +#endif + + OpenPIC_InitSenses = prpmc800_openpic_initsenses; + OpenPIC_NumInitSenses = sizeof(prpmc800_openpic_initsenses); + + printk("PrPMC800 port (C) 2001 MontaVista Software, Inc. (source@mvista.com)\n"); +} + +/* + * Compute the PrPMC800's tbl frequency using the baud clock as a reference. + */ + +static void __init +prpmc800_calibrate_decr(void) +{ + unsigned long tbl_start, tbl_end; + unsigned long current_state, old_state, tb_ticks_per_second; + unsigned int count; + unsigned int harrier_revision; + + harrier_revision = readb(HARRIER_REVI_REG); + if (harrier_revision < 2) { + /* XTAL64 was broken in harrier revision 1 */ + printk("time_init: Harrier revision %d, assuming 100 Mhz bus\n", + harrier_revision); + tb_ticks_per_second = 100000000/4; + tb_ticks_per_jiffy = tb_ticks_per_second / HZ; + tb_to_us = mulhwu_scale_factor(tb_ticks_per_second, 1000000); + return; + } + + /* + * The XTAL64 bit oscillates at the 1/64 the base baud clock + * Set count to XTAL64 cycles per second. Since we'll count + * half-cycles, we'll reach the count in half a second. + */ + count = PRPMC800_BASE_BAUD / 64; + + /* Find the first edge of the baud clock */ + old_state = readb(HARRIER_UCTL_REG) & HARRIER_XTAL64_MASK; + do { + current_state = readb(HARRIER_UCTL_REG) & + HARRIER_XTAL64_MASK; + } while(old_state == current_state); + + old_state = current_state; + + /* Get the starting time base value */ + tbl_start = get_tbl(); + + /* + * Loop until we have found a number of edges (half-cycles) + * equal to the count (half a second) + */ + do { + do { + current_state = readb(HARRIER_UCTL_REG) & + HARRIER_XTAL64_MASK; + } while(old_state == current_state); + old_state = current_state; + } while (--count); + + /* Get the ending time base value */ + tbl_end = get_tbl(); + + /* We only counted for half a second, so double to get ticks/second */ + tb_ticks_per_second = (tbl_end - tbl_start) * 2; + tb_ticks_per_jiffy = tb_ticks_per_second / HZ; + tb_to_us = mulhwu_scale_factor(tb_ticks_per_second, 1000000); +} + +static void +prpmc800_restart(char *cmd) +{ + __cli(); + writeb(HARRIER_RSTOUT_MASK, HARRIER_MISC_CSR_REG); + while(1); +} + +static void +prpmc800_halt(void) +{ + __cli(); + while (1); +} + +static void +prpmc800_power_off(void) +{ + prpmc800_halt(); +} + +/* Resolves the open_pic.c build without including i8259.c */ +int i8259_poll() +{ + return 0; +} + +static void __init +prpmc800_init_IRQ(void) +{ + openpic_init(1, 0, 0, -1); + +#define PRIORITY 15 +#define VECTOR 16 +#define PROCESSOR 0 + /* initialize the harrier's internal interrupt priority 15, irq 1 */ + out_be32((u32 *)HARRIER_IFEVP_REG, (PRIORITY<<16) | VECTOR); + out_be32((u32 *)HARRIER_IFEDE_REG, (1<<PROCESSOR)); + + /* enable functional exceptions for uarts and abort */ + out_8((u8 *)HARRIER_FEEN_REG, (HARRIER_FE_UA0|HARRIER_FE_UA1)); + out_8((u8 *)HARRIER_FEMA_REG, ~(HARRIER_FE_UA0|HARRIER_FE_UA1)); +} + +/* + * Set BAT 3 to map 0xf0000000 to end of physical memory space. + */ +static __inline__ void +prpmc800_set_bat(void) +{ + unsigned long bat3u, bat3l; + static int mapping_set = 0; + + if (!mapping_set) + { + __asm__ __volatile__( + " lis %0,0xf000\n \ + ori %1,%0,0x002a\n \ + ori %0,%0,0x1ffe\n \ + mtspr 0x21e,%0\n \ + mtspr 0x21f,%1\n \ + isync\n \ + sync " + : "=r" (bat3u), "=r" (bat3l)); + + mapping_set = 1; + } + return; +} + +#ifdef CONFIG_SERIAL_TEXT_DEBUG +#include <linux/serial.h> +#include <linux/serialP.h> +#include <linux/serial_reg.h> +#include <asm/serial.h> + +static struct serial_state rs_table[RS_TABLE_SIZE] = { + SERIAL_PORT_DFNS /* Defined in <asm/serial.h> */ +}; + +void +prpmc800_progress(char *s, unsigned short hex) +{ + volatile char c; + volatile unsigned char *com_port; + volatile unsigned char *com_port_lsr; + + com_port = (volatile unsigned char *) rs_table[0].port; + com_port_lsr = com_port + UART_LSR; + + while ((c = *s++) != 0) { + while ((*com_port_lsr & UART_LSR_THRE) == 0) + ; + *com_port = c; + + if (c == '\n') { + while ((*com_port_lsr & UART_LSR_THRE) == 0) + ; + *com_port = '\r'; + } + } +} +#endif /* CONFIG_SERIAL_TEXT_DEBUG */ + +/* + * We need to read the Harrier memory controller + * to properly determine this value + */ +static unsigned long __init +prpmc800_find_end_of_memory(void) +{ + /* Cover the harrier registers with a BAT */ + prpmc800_set_bat(); + + /* Read the memory size from the Harrier XCSR */ + return harrier_get_mem_size(PRPMC800_HARRIER_XCSR_BASE); +} + +static void __init +prpmc800_map_io(void) +{ + io_block_mapping(0x80000000, 0x80000000, 0x10000000, _PAGE_IO); + io_block_mapping(0xf0000000, 0xf0000000, 0x10000000, _PAGE_IO); +} + +void __init +platform_init(unsigned long r3, unsigned long r4, unsigned long r5, + unsigned long r6, unsigned long r7) +{ + parse_bootinfo(find_bootinfo()); + + prpmc800_set_bat(); + + isa_io_base = PRPMC800_ISA_IO_BASE; + isa_mem_base = PRPMC800_ISA_MEM_BASE; + pci_dram_offset = PRPMC800_PCI_DRAM_OFFSET; + + ppc_md.setup_arch = prpmc800_setup_arch; + ppc_md.show_cpuinfo = prpmc800_show_cpuinfo; + ppc_md.init_IRQ = prpmc800_init_IRQ; + ppc_md.get_irq = openpic_get_irq; + + ppc_md.find_end_of_memory = prpmc800_find_end_of_memory; + ppc_md.setup_io_mappings = prpmc800_map_io; + + ppc_md.restart = prpmc800_restart; + ppc_md.power_off = prpmc800_power_off; + ppc_md.halt = prpmc800_halt; + + /* PrPMC800 has no timekeeper part */ + ppc_md.time_init = NULL; + ppc_md.get_rtc_time = NULL; + ppc_md.set_rtc_time = NULL; + ppc_md.calibrate_decr = prpmc800_calibrate_decr; +#ifdef CONFIG_SERIAL_TEXT_DEBUG + ppc_md.progress = prpmc800_progress; +#else /* !CONFIG_SERIAL_TEXT_DEBUG */ + ppc_md.progress = NULL; +#endif /* CONFIG_SERIAL_TEXT_DEBUG */ +} diff --git a/arch/ppc/platforms/redwood.c b/arch/ppc/platforms/redwood.c new file mode 100644 index 000000000000..39dcafab547b --- /dev/null +++ b/arch/ppc/platforms/redwood.c @@ -0,0 +1,66 @@ +/* + * + * Copyright 2000-2001 MontaVista Software Inc. + * Completed implementation. + * Author: MontaVista Software, Inc. <source@mvista.com> + * Frank Rowand <frank_rowand@mvista.com> + * + * Module name: redwood.c + * + * Description: + * + * History: 11/09/2001 - Armin + * added board_init to add in additional instuctions needed during platfrom_init + * + */ + +#include <linux/config.h> +#include <linux/init.h> +#include <asm/pgtable.h> +#include <asm/ibm4xx.h> +#include <asm/io.h> +#include <asm/machdep.h> + +void __init +board_setup_arch(void) +{ +} + +void __init +board_io_mapping(void) +{ + int i; + + io_block_mapping(OAKNET_IO_VADDR, + OAKNET_IO_PADDR, OAKNET_IO_SIZE, _PAGE_IO); + +} + +void __init +board_setup_irq(void) +{ +} + +void __init +board_init(void) +{ +} + +/* hack; blame me dan. -brad */ +#ifdef CONFIG_INPUT_KEYBDEV + +void +handle_scancode(unsigned char scancode, int down) +{ + printk("handle_scancode(scancode=0x%x, down=%d)\n", scancode, down); +} + +static void +kbd_bh(unsigned long dummy) +{ +} + +DECLARE_TASKLET_DISABLED(keyboard_tasklet, kbd_bh, 0); +void (*kbd_ledfunc) (unsigned int led); + +#endif diff --git a/arch/ppc/platforms/redwood.h b/arch/ppc/platforms/redwood.h new file mode 100644 index 000000000000..0920ce1f847b --- /dev/null +++ b/arch/ppc/platforms/redwood.h @@ -0,0 +1,51 @@ +/* + * Copyright 2001 MontaVista Software Inc. + * PPC405 modifications + * Author: MontaVista Software, Inc. + * frank_rowand@mvista.com or source@mvista.com + * + * Module name: redwood.h + * + * Description: + * Macros, definitions, and data structures specific to the IBM PowerPC + * STB03xxx "Redwood" evaluation board. + */ + +#ifdef __KERNEL__ +#ifndef __ASM_REDWOOD_H__ +#define __ASM_REDWOOD_H__ + +/* Redwoods have an STB03xxx or STB04xxx core */ +#include <platforms/ibmstb3.h> + +#ifndef __ASSEMBLY__ +typedef struct board_info { + unsigned char bi_s_version[4]; /* Version of this structure */ + unsigned char bi_r_version[30]; /* Version of the IBM ROM */ + unsigned int bi_memsize; /* DRAM installed, in bytes */ + unsigned int bi_dummy; /* field shouldn't exist */ + unsigned char bi_enetaddr[6]; /* Ethernet MAC address */ + unsigned int bi_intfreq; /* Processor speed, in Hz */ + unsigned int bi_busfreq; /* Bus speed, in Hz */ + unsigned int bi_tbfreq; /* Software timebase freq */ +} bd_t; +#endif /* !__ASSEMBLY__ */ + +#define OAKNET_IO_PADDR ((uint)0xf2000000) +#define OAKNET_IO_VADDR OAKNET_IO_PADDR +#define OAKNET_IO_BASE OAKNET_IO_VADDR + +/* ftr revisit- io size was 0xffff in old-line, is 0x40 in oak.h */ +#define OAKNET_IO_SIZE 0xffff +#define OAKNET_INT 26 /* EXTINT1 */ + +#define _IO_BASE 0 +#define _ISA_MEM_BASE 0 +#define PCI_DRAM_OFFSET 0 + +#define BASE_BAUD 1312500 + +#define PPC4xx_MACHINE_NAME "IBM Redwood" + +#endif /* __ASM_REDWOOD_H__ */ +#endif /* __KERNEL__ */ diff --git a/arch/ppc/platforms/redwood5.c b/arch/ppc/platforms/redwood5.c new file mode 100644 index 000000000000..c6b0ca290f8b --- /dev/null +++ b/arch/ppc/platforms/redwood5.c @@ -0,0 +1,82 @@ +/* + * + * Copyright 2000-2001 MontaVista Software Inc. + * Completed implementation. + * Author: Armin Kuster + * + * Module name: redwood5.c + * + * Description: + * IBM redwood5 eval board file + * + * History: 12/29/2001 - Armin + * initail release + * + */ + +#include <linux/config.h> +#include <linux/init.h> +#include <linux/pagemap.h> +#include <asm/io.h> +#include <asm/machdep.h> + +void __init +board_setup_arch(void) +{ + + bd_t *bip = (bd_t *)__res; + +#define CONFIG_DEBUG_BRINGUP +#ifdef CONFIG_DEBUG_BRINGUP + printk("\n"); + printk("machine\t: %s\n", PPC4xx_MACHINE_NAME); + printk("\n"); + printk("bi_s_version\t %s\n", bip->bi_s_version); + printk("bi_r_version\t %s\n", bip->bi_r_version); + printk("bi_memsize\t 0x%8.8x\t %dMBytes\n", bip->bi_memsize,bip->bi_memsize/(1024*1000)); + printk("bi_enetaddr %d\t %2.2x%2.2x%2.2x-%2.2x%2.2x%2.2x\n", 0, + bip->bi_enetaddr[0], bip->bi_enetaddr[1], + bip->bi_enetaddr[2], bip->bi_enetaddr[3], + bip->bi_enetaddr[4], bip->bi_enetaddr[5]); + + printk("bi_intfreq\t 0x%8.8x\t clock:\t %dMhz\n", + bip->bi_intfreq, bip->bi_intfreq/ 1000000); + + printk("bi_busfreq\t 0x%8.8x\t plb bus clock:\t %dMHz\n", + bip->bi_busfreq, bip->bi_busfreq / 1000000 ); + printk("bi_tbfreq\t 0x%8.8x\t TB freq:\t %dMHz\n", + bip->bi_tbfreq, bip->bi_tbfreq/1000000); + + printk("\n"); +#endif + +} + +void __init +board_io_mapping(void) +{ + int i; + + for (i = 0; i < 16; i++) { + unsigned long v, p; + + /* 0x400x0000 -> 0xe00x0000 */ + p = 0x40000000 | (i << 16); + v = STB04xxx_IO_BASE | (i << 16); + + io_block_mapping(v, p, PAGE_SIZE, + _PAGE_NO_CACHE | pgprot_val(PAGE_KERNEL) | _PAGE_GUARDED); + } + + +} + +void __init +board_setup_irq(void) +{ +} + +void __init +board_init(void) +{ +} diff --git a/arch/ppc/platforms/redwood5.h b/arch/ppc/platforms/redwood5.h new file mode 100644 index 000000000000..32acc7e0b316 --- /dev/null +++ b/arch/ppc/platforms/redwood5.h @@ -0,0 +1,54 @@ +/* + * Copyright 2001 MontaVista Software Inc. + * PPC405 modifications + * Author: MontaVista Software, Inc. + * Armin Kuster + * + * Module name: redwood5.h + * + * Description: + * Macros, definitions, and data structures specific to the IBM PowerPC + * STB03xxx "Redwood" evaluation board. + */ + +#ifdef __KERNEL__ +#ifndef __ASM_REDWOOD5_H__ +#define __ASM_REDWOOD5_H__ + +/* Redwood5 has an STB04xxx core */ +#include <platforms/ibmstb4.h> + +#ifndef __ASSEMBLY__ +typedef struct board_info { + unsigned char bi_s_version[4]; /* Version of this structure */ + unsigned char bi_r_version[30]; /* Version of the IBM ROM */ + unsigned int bi_memsize; /* DRAM installed, in bytes */ + unsigned int bi_dummy; /* field shouldn't exist */ + unsigned char bi_enetaddr[6]; /* Ethernet MAC address */ + unsigned int bi_intfreq; /* Processor speed, in Hz */ + unsigned int bi_busfreq; /* Bus speed, in Hz */ + unsigned int bi_tbfreq; /* Software timebase freq */ +} bd_t; +#endif /* !__ASSEMBLY__ */ + + +#define SMC91111_BASE_ADDR 0xf2000300 +#define SMC91111_IRQ 28 + +#ifdef MAX_HWIFS +#undef MAX_HWIFS +#endif +#define MAX_HWIFS 1 + +#define _IO_BASE 0 +#define _ISA_MEM_BASE 0 +#define PCI_DRAM_OFFSET 0 + +/* serail defines moved from ppc4xx_serial.h * + */ +#define BASE_BAUD 1267200 + +#define PPC4xx_MACHINE_NAME "IBM Redwood5" + +#endif /* __ASM_REDWOOD5_H__ */ +#endif /* __KERNEL__ */ diff --git a/arch/ppc/kernel/residual.c b/arch/ppc/platforms/residual.c index cae870a305ca..cae870a305ca 100644 --- a/arch/ppc/kernel/residual.c +++ b/arch/ppc/platforms/residual.c diff --git a/include/asm-ppc/rpxclassic.h b/arch/ppc/platforms/rpxclassic.h index ec65383b1c43..6fabcd4ae0d4 100644 --- a/include/asm-ppc/rpxclassic.h +++ b/arch/ppc/platforms/rpxclassic.h @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.rpxclassic.h 1.11 08/17/01 15:23:17 paulus + * BK Id: %F% %I% %G% %U% %#% */ /* @@ -75,7 +75,7 @@ extern bd_t m8xx_board_info; #define BCSR2_FETHLEDMODE ((uint)0x00000800) /* CLLF */ #if defined(CONFIG_HTDMSOUND) -#include <asm/rpxhiox.h> +#include <platforms/rpxhiox.h> #endif /* define IO_BASE for pcmcia, CLLF only */ diff --git a/include/asm-ppc/rpxhiox.h b/arch/ppc/platforms/rpxhiox.h index 848e4eb6fd1e..848e4eb6fd1e 100644 --- a/include/asm-ppc/rpxhiox.h +++ b/arch/ppc/platforms/rpxhiox.h diff --git a/include/asm-ppc/rpxlite.h b/arch/ppc/platforms/rpxlite.h index 2f24dcc74ab2..c07888f2e471 100644 --- a/include/asm-ppc/rpxlite.h +++ b/arch/ppc/platforms/rpxlite.h @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.rpxlite.h 1.11 08/17/01 15:23:17 paulus + * BK Id: %F% %I% %G% %U% %#% */ /* @@ -63,7 +63,7 @@ extern bd_t m8xx_board_info; #define BCSR1_PCVCTL7 ((uint)0x00010000) #if defined(CONFIG_HTDMSOUND) -#include <asm/rpxhiox.h> +#include <platforms/rpxhiox.h> #endif #endif /* !__ASSEMBLY__ */ diff --git a/arch/ppc/platforms/rpxsuper.h b/arch/ppc/platforms/rpxsuper.h new file mode 100644 index 000000000000..d767971e14d8 --- /dev/null +++ b/arch/ppc/platforms/rpxsuper.h @@ -0,0 +1,72 @@ +/* + * A collection of structures, addresses, and values associated with + * the Embedded Planet RPX6 (or RPX Super) MPC8260 board. + * Copied from the RPX-Classic and SBS8260 stuff. + * + * Copyright (c) 2001 Dan Malek <dan@embeddededge.com> + */ +#ifdef __KERNEL__ +#ifndef __ASM_PLATFORMS_RPXSUPER_H__ +#define __ASM_PLATFORMS_RPXSUPER_H__ + +/* A Board Information structure that is given to a program when + * prom starts it up. + */ +typedef struct bd_info { + unsigned int bi_memstart; /* Memory start address */ + unsigned int bi_memsize; /* Memory (end) size in bytes */ + unsigned int bi_nvsize; /* NVRAM size in bytes (can be 0) */ + unsigned int bi_intfreq; /* Internal Freq, in Hz */ + unsigned int bi_busfreq; /* Bus Freq, in MHz */ + unsigned int bi_cpmfreq; /* CPM Freq, in MHz */ + unsigned int bi_brgfreq; /* BRG Freq, in MHz */ + unsigned int bi_vco; /* VCO Out from PLL */ + unsigned int bi_baudrate; /* Default console baud rate */ + unsigned int bi_immr; /* IMMR when called from boot rom */ + unsigned char bi_enetaddr[6]; +} bd_t; + +extern bd_t m8xx_board_info; + +/* Memory map is configured by the PROM startup. + * We just map a few things we need. The CSR is actually 4 byte-wide + * registers that can be accessed as 8-, 16-, or 32-bit values. + */ +#define IMAP_ADDR ((uint)0xf0000000) +#define RPX_CSR_ADDR ((uint)0xfa000000) +#define RPX_CSR_SIZE ((uint)(512 * 1024)) +#define RPX_NVRTC_ADDR ((uint)0xfa080000) +#define RPX_NVRTC_SIZE ((uint)(512 * 1024)) + +/* The RPX6 has 16, byte wide control/status registers. + * Not all are used (yet). + */ +extern volatile u_char *rpx6_csr_addr; + +/* Things of interest in the CSR. +*/ +#define BCSR0_ID_MASK ((u_char)0xf0) /* Read only */ +#define BCSR0_SWITCH_MASK ((u_char)0x0f) /* Read only */ +#define BCSR1_XCVR_SMC1 ((u_char)0x80) +#define BCSR1_XCVR_SMC2 ((u_char)0x40) +#define BCSR2_FLASH_WENABLE ((u_char)0x20) +#define BCSR2_NVRAM_ENABLE ((u_char)0x10) +#define BCSR2_ALT_IRQ2 ((u_char)0x08) +#define BCSR2_ALT_IRQ3 ((u_char)0x04) +#define BCSR2_PRST ((u_char)0x02) /* Force reset */ +#define BCSR2_ENPRST ((u_char)0x01) /* Enable POR */ +#define BCSR3_MODCLK_MASK ((u_char)0xe0) +#define BCSR3_ENCLKHDR ((u_char)0x10) +#define BCSR3_LED5 ((u_char)0x04) /* 0 == on */ +#define BCSR3_LED6 ((u_char)0x02) /* 0 == on */ +#define BCSR3_LED7 ((u_char)0x01) /* 0 == on */ +#define BCSR4_EN_PHY ((u_char)0x80) /* Enable PHY */ +#define BCSR4_EN_MII ((u_char)0x40) /* Enable PHY */ +#define BCSR4_MII_READ ((u_char)0x04) +#define BCSR4_MII_MDC ((u_char)0x02) +#define BCSR4_MII_MDIO ((u_char)0x02) +#define BCSR13_FETH_IRQMASK ((u_char)0xf0) +#define BCSR15_FETH_IRQ ((u_char)0x20) + +#endif /* __ASM_PLATFORMS_RPXSUPER_H__ */ +#endif /* __KERNEL__ */ diff --git a/arch/ppc/platforms/sandpoint.h b/arch/ppc/platforms/sandpoint.h new file mode 100644 index 000000000000..2c768e63e082 --- /dev/null +++ b/arch/ppc/platforms/sandpoint.h @@ -0,0 +1,70 @@ +/* + * arch/ppc/platforms/sandpoint.h + * + * Definitions for Motorola SPS Sandpoint Test Platform + * + * Author: Mark A. Greer + * mgreer@mvista.com + * + * Copyright 2000, 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +/* + * Sandpoint uses the CHRP map (Map B). + */ + +#ifndef __PPC_PLATFORMS_SANDPOINT_H +#define __PPC_PLATFORMS_SANDPOINT_H + +#ifdef CONFIG_SANDPOINT_X3 +#define SANDPOINT_SIO_SLOT 0 /* Cascaded from EPIC IRQ 0 */ +#if 0 +/* The Sandpoint X3 allows the IDE interrupt to be directly connected + * from the Windbond (PCI INTC or INTD) to the serial EPIC. Someday + * we should try this, but it was easier to use the existing 83c553 + * initialization than change it to route the different interrupts :-). + * -- Dan + */ +#define SANDPOINT_IDE_INT0 23 /* EPIC 7 */ +#define SANDPOINT_IDE_INT1 24 /* EPIC 8 */ +#else +#define SANDPOINT_IDE_INT0 14 /* 8259 Test */ +#define SANDPOINT_IDE_INT1 15 /* 8259 Test */ +#endif +#else + /* + * Define the PCI slot that the 8259 is sharing interrupts with. + * Valid values are 1 (PCI slot 2) and 2 (PCI slot 3). + */ +#define SANDPOINT_SIO_SLOT 1 + +/* ...and for the IDE from the 8259.... +*/ +#define SANDPOINT_IDE_INT0 14 +#define SANDPOINT_IDE_INT1 15 +#endif + +#define SANDPOINT_SIO_IRQ (SANDPOINT_SIO_SLOT + NUM_8259_INTERRUPTS) + +/* + * The sandpoint boards have processor modules that either have an 8240 or + * an MPC107 host bridge on them. These bridges have an IDSEL line that allows + * them to respond to PCI transactions as if they were a normal PCI devices. + * However, the processor on the processor side of the bridge can not reach + * out onto the PCI bus and then select the bridge or bad things will happen + * (documented in the 8240 and 107 manuals). + * Because of this, we always skip the bridge PCI device when accessing the + * PCI bus. The PCI slot that the bridge occupies is defined by the macro + * below. + */ +#define SANDPOINT_HOST_BRIDGE_IDSEL 12 + + +void sandpoint_find_bridges(void); + +#endif /* __PPC_PLATFORMS_SANDPOINT_H */ diff --git a/arch/ppc/platforms/sandpoint_pci.c b/arch/ppc/platforms/sandpoint_pci.c new file mode 100644 index 000000000000..d4549472d5d5 --- /dev/null +++ b/arch/ppc/platforms/sandpoint_pci.c @@ -0,0 +1,183 @@ +/* + * arch/ppc/platforms/sandpoint_pci.c + * + * PCI setup routines for the Motorola SPS Sandpoint Test Platform + * + * Author: Mark A. Greer + * mgreer@mvista.com + * + * Copyright 2000, 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/pci.h> +#include <linux/slab.h> + +#include <asm/byteorder.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/uaccess.h> +#include <asm/machdep.h> +#include <asm/pci-bridge.h> +#include <asm/mpc10x.h> + +#include "sandpoint.h" + +/* + * Motorola SPS Sandpoint interrupt routing. + */ +static inline int +sandpoint_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) +{ + static char pci_irq_table[][4] = + /* + * PCI IDSEL/INTPIN->INTLINE + * A B C D + */ + { + { SANDPOINT_SIO_IRQ, + 0, 0, 0 }, /* IDSEL 11 - i8259 on Winbond */ + { 0, 0, 0, 0 }, /* IDSEL 12 - unused */ +#ifdef CONFIG_SANDPOINT_X3 +#if 0 /* This is what it _should_ look like -- Dan */ + { 17, 20, 19, 18 }, /* IDSEL 13 - PCI slot 1 */ + { 18, 17, 20, 19 }, /* IDSEL 14 - PCI slot 2 */ + { 19, 18, 17, 20 }, /* IDSEL 15 - PCI slot 3 */ + { 20, 19, 18, 17 }, /* IDSEL 16 - PCI slot 4 */ +#else + { 18, 21, 20, 19 }, /* IDSEL 13 - PCI slot 1 */ + { 19, 18, 21, 20 }, /* IDSEL 14 - PCI slot 2 */ + { 20, 19, 18, 21 }, /* IDSEL 15 - PCI slot 3 */ + { 21, 20, 19, 18 }, /* IDSEL 16 - PCI slot 4 */ +#endif +#else + { 16, 19, 18, 17 }, /* IDSEL 13 - PCI slot 1 */ + { 17, 16, 19, 18 }, /* IDSEL 14 - PCI slot 2 */ + { 18, 17, 16, 19 }, /* IDSEL 15 - PCI slot 3 */ + { 19, 18, 17, 16 }, /* IDSEL 16 - PCI slot 4 */ +#endif + }; + + const long min_idsel = 11, max_idsel = 16, irqs_per_slot = 4; + return PCI_IRQ_TABLE_LOOKUP; +} + +static void __init +sandpoint_setup_winbond_83553(struct pci_controller *hose) +{ + int devfn; + + /* + * Route IDE interrupts directly to the 8259's IRQ 14 & 15. + * We can't route the IDE interrupt to PCI INTC# or INTD# because those + * woule interfere with the PMC's INTC# and INTD# lines. + */ + /* + * Winbond Fcn 0 + */ + devfn = PCI_DEVFN(11,0); + + early_write_config_byte(hose, + 0, + devfn, + 0x43, /* IDE Interrupt Routing Control */ + 0xef); + early_write_config_word(hose, + 0, + devfn, + 0x44, /* PCI Interrupt Routing Control */ + 0x0000); + + /* Want ISA memory cycles to be forwarded to PCI bus */ + early_write_config_byte(hose, + 0, + devfn, + 0x48, /* ISA-to-PCI Addr Decoder Control */ + 0xf0); + + /* Enable RTC and Keyboard address locations. */ + early_write_config_byte(hose, + 0, + devfn, + 0x4d, /* Chip Select Control Register */ + 0x00); + + /* Enable Port 92. */ + early_write_config_byte(hose, + 0, + devfn, + 0x4e, /* AT System Control Register */ + 0x06); + /* + * Winbond Fcn 1 + */ + devfn = PCI_DEVFN(11,1); + + /* Put IDE controller into native mode. */ + early_write_config_byte(hose, + 0, + devfn, + 0x09, /* Programming interface Register */ + 0x8f); + + /* Init IRQ routing, enable both ports, disable fast 16 */ + early_write_config_dword(hose, + 0, + devfn, + 0x40, /* IDE Control/Status Register */ + 0x00ff0011); + return; +} + +static int +sandpoint_exclude_device(u_char bus, u_char devfn) +{ + if ((bus == 0) && (PCI_SLOT(devfn) == SANDPOINT_HOST_BRIDGE_IDSEL)) { + return PCIBIOS_DEVICE_NOT_FOUND; + } + else { + return PCIBIOS_SUCCESSFUL; + } +} + +void __init +sandpoint_find_bridges(void) +{ + struct pci_controller *hose; + + hose = pcibios_alloc_controller(); + + if (!hose) + return; + + hose->first_busno = 0; + hose->last_busno = 0xff; + + if (mpc10x_bridge_init(hose, + MPC10X_MEM_MAP_B, + MPC10X_MEM_MAP_B, + MPC10X_MAPB_EUMB_BASE) == 0) { + + /* Do early winbond init, then scan PCI bus */ + sandpoint_setup_winbond_83553(hose); + ppc_md.pci_exclude_device = sandpoint_exclude_device; + hose->last_busno = pciauto_bus_scan(hose, hose->first_busno); + + ppc_md.pcibios_fixup = NULL; + ppc_md.pcibios_fixup_bus = NULL; + ppc_md.pci_swizzle = common_swizzle; + ppc_md.pci_map_irq = sandpoint_map_irq; + } + else { + if (ppc_md.progress) + ppc_md.progress("Bridge init failed", 0x100); + printk("Host bridge init failed\n"); + } + + return; +} diff --git a/arch/ppc/platforms/sandpoint_serial.h b/arch/ppc/platforms/sandpoint_serial.h new file mode 100644 index 000000000000..fcfe565f98ad --- /dev/null +++ b/arch/ppc/platforms/sandpoint_serial.h @@ -0,0 +1,51 @@ +/* + * include/asm-ppc/sandpoint_serial.h + * + * Definitions for Motorola SPS Sandpoint Test Platform + * + * Author: Mark A. Greer + * mgreer@mvista.com + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#ifndef __ASMPPC_SANDPOINT_SERIAL_H +#define __ASMPPC_SANDPOINT_SERIAL_H + +#include <linux/config.h> + +#define SANDPOINT_SERIAL_0 0xfe0003f8 +#define SANDPOINT_SERIAL_1 0xfe0002f8 + +#ifdef CONFIG_SERIAL_MANY_PORTS +#define RS_TABLE_SIZE 64 +#else +#define RS_TABLE_SIZE 2 +#endif + +/* Rate for the 1.8432 Mhz clock for the onboard serial chip */ +#define BASE_BAUD ( 1843200 / 16 ) + +#ifdef CONFIG_SERIAL_DETECT_IRQ +#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF|ASYNC_SKIP_TEST|ASYNC_AUTO_IRQ) +#else +#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF|ASYNC_SKIP_TEST) +#endif + +#define STD_SERIAL_PORT_DFNS \ + { 0, BASE_BAUD, SANDPOINT_SERIAL_0, 4, STD_COM_FLAGS, /* ttyS0 */ \ + iomem_base: (u8 *)SANDPOINT_SERIAL_0, \ + io_type: SERIAL_IO_MEM }, \ + { 0, BASE_BAUD, SANDPOINT_SERIAL_1, 3, STD_COM_FLAGS, /* ttyS1 */ \ + iomem_base: (u8 *)SANDPOINT_SERIAL_1, \ + io_type: SERIAL_IO_MEM }, + +#define SERIAL_PORT_DFNS \ + STD_SERIAL_PORT_DFNS + +#endif /* __ASMPPC_SANDPOINT_SERIAL_H */ diff --git a/arch/ppc/platforms/sandpoint_setup.c b/arch/ppc/platforms/sandpoint_setup.c new file mode 100644 index 000000000000..3800b7c5cc45 --- /dev/null +++ b/arch/ppc/platforms/sandpoint_setup.c @@ -0,0 +1,694 @@ +/* + * arch/ppc/platforms/sandpoint_setup.c + * + * Board setup routines for the Motorola SPS Sandpoint Test Platform. + * + * Author: Mark A. Greer + * mgreer@mvista.com + * + * Copyright 2000, 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +/* + * This file adds support for the Motorola SPS Sandpoint Test Platform. + * These boards have a PPMC slot for the processor so any combination + * of cpu and host bridge can be attached. This port is for an 8240 PPMC + * module from Motorola SPS and other closely related cpu/host bridge + * combinations (e.g., 750/755/7400 with MPC107 host bridge). + * The sandpoint itself has a Windbond 83c553 (PCI-ISA bridge, 2 DMA ctlrs, 2 + * cascaded 8259 interrupt ctlrs, 8254 Timer/Counter, and an IDE ctlr), a + * National 87308 (RTC, 2 UARTs, Keyboard & mouse ctlrs, and a floppy ctlr), + * and 4 PCI slots (only 2 of which are usable; the other 2 are keyed for 3.3V + * but are really 5V). + * + * The firmware on the sandpoint is called DINK (not my acronym :). This port + * depends on DINK to do some basic initialization (e.g., initialize the memory + * ctlr) and to ensure that the processor is using MAP B (CHRP map). + * + * The switch settings for the Sandpoint board MUST be as follows: + * S3: down + * S4: up + * S5: up + * S6: down + * + * 'down' is in the direction from the PCI slots towards the PPMC slot; + * 'up' is in the direction from the PPMC slot towards the PCI slots. + * Be careful, the way the sandpoint board is installed in XT chasses will + * make the directions reversed. + * + * Since Motorola listened to our suggestions for improvement, we now have + * the Sandpoint X3 board. All of the PCI slots are available, it uses + * the serial interrupt interface (just a hardware thing we need to + * configure properly). + * + * Use the default X3 switch settings. The interrupts are then: + * EPIC Source + * 0 SIOINT (8259, active low) + * 1 PCI #1 + * 2 PCI #2 + * 3 PCI #3 + * 4 PCI #4 + * 7 Winbond INTC (IDE interrupt) + * 8 Winbond INTD (IDE interrupt) + * + */ +#include <linux/config.h> +#include <linux/stddef.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/errno.h> +#include <linux/reboot.h> +#include <linux/pci.h> +#include <linux/kdev_t.h> +#include <linux/major.h> +#include <linux/blk.h> +#include <linux/console.h> +#include <linux/delay.h> +#include <linux/irq.h> +#include <linux/ide.h> +#include <linux/irq.h> +#include <linux/seq_file.h> + +#include <asm/system.h> +#include <asm/pgtable.h> +#include <asm/page.h> +#include <asm/time.h> +#include <asm/dma.h> +#include <asm/io.h> +#include <asm/machdep.h> +#include <asm/prom.h> +#include <asm/smp.h> +#include <asm/keyboard.h> +#include <asm/vga.h> +#include <asm/open_pic.h> +#include <asm/i8259.h> +#include <asm/todc.h> +#include <asm/bootinfo.h> +#include <asm/mpc10x.h> +#include <asm/pci-bridge.h> + +#include "sandpoint.h" + +extern u_int openpic_irq(void); +extern void openpic_eoi(void); + +extern int pckbd_setkeycode(unsigned int scancode, unsigned int keycode); +extern int pckbd_getkeycode(unsigned int scancode); +extern int pckbd_translate(unsigned char scancode, unsigned char *keycode, + char raw_mode); +extern char pckbd_unexpected_up(unsigned char keycode); +extern void pckbd_leds(unsigned char leds); +extern void pckbd_init_hw(void); +extern unsigned char pckbd_sysrq_xlate[128]; + +static void sandpoint_halt(void); + + +/* + * *** IMPORTANT *** + * + * The first 16 entries of 'sandpoint_openpic_initsenses[]' are there and + * initialized to 0 on purpose. DO NOT REMOVE THEM as the 'offset' parameter + * of 'openpic_init()' does not work for the sandpoint because the 8259 + * interrupt is NOT routed to the EPIC's IRQ 0 AND the EPIC's IRQ 0's offset is + * the same as a normal openpic's IRQ 16 offset. + */ +static u_char sandpoint_openpic_initsenses[] __initdata = { + 0, /* 0-15 not used by EPCI but by 8259 (std PC-type IRQs) */ + 0, /* 1 */ + 0, /* 2 */ + 0, /* 3 */ + 0, /* 4 */ + 0, /* 5 */ + 0, /* 6 */ + 0, /* 7 */ + 0, /* 8 */ + 0, /* 9 */ + 0, /* 10 */ + 0, /* 11 */ + 0, /* 12 */ + 0, /* 13 */ + 0, /* 14 */ + 0, /* 15 */ +#ifdef CONFIG_SANDPOINT_X3 + 1, /* 16: EPIC IRQ 0: Active Low -- SIOINT (8259) */ + 0, /* AACK! Shouldn't need this.....see sandpoint_pci.c for more info */ + 1, /* 17: EPIC IRQ 1: Active Low -- PCI Slot 1 */ + 1, /* 18: EPIC IRQ 2: Active Low -- PCI Slot 2 */ + 1, /* 19: EPIC IRQ 3: Active Low -- PCI Slot 3 */ + 1, /* 20: EPIC IRQ 4: Active Low -- PCI Slot 4 */ + 0, /* 21 -- Unused */ + 0, /* 22 -- Unused */ + 1, /* 23 -- IDE (Winbond INT C) */ + 1, /* 24 -- IDE (Winbond INT D) */ + /* 35 - 31 (EPIC 9 - 15) Unused */ +#else + 1, /* 16: EPIC IRQ 0: Active Low -- PCI intrs */ + 1, /* 17: EPIC IRQ 1: Active Low -- PCI (possibly 8259) intrs */ + 1, /* 18: EPIC IRQ 2: Active Low -- PCI (possibly 8259) intrs */ + 1 /* 19: EPIC IRQ 3: Active Low -- PCI intrs */ + /* 20: EPIC IRQ 4: Not used */ +#endif +}; + +static void __init +sandpoint_setup_arch(void) +{ + loops_per_jiffy = 100000000 / HZ; + +#ifdef CONFIG_BLK_DEV_INITRD + if (initrd_start) + ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); + else +#endif +#ifdef CONFIG_ROOT_NFS + ROOT_DEV = to_kdev_t(0x00FF); /* /dev/nfs pseudo device */ +#else + ROOT_DEV = to_kdev_t(0x0301); /* /dev/hda1 IDE disk */ +#endif + + /* Lookup PCI host bridges */ + sandpoint_find_bridges(); + +#ifdef CONFIG_DUMMY_CONSOLE + conswitchp = &dummy_con; +#endif + + printk("Motorola SPS Sandpoint Test Platform\n"); + printk("Sandpoint port (C) 2000, 2001 MontaVista Software, Inc. (source@mvista.com)\n"); + + /* The Sandpoint rom doesn't enable any caches. Do that now. + * The 7450 portion will also set up the L3s once I get enough + * information do do so. If the processor running doesn't have + * and L2, the _set_L2CR is a no-op. + */ + if (cur_cpu_spec[0]->cpu_features & CPU_FTR_SPEC7450) { + /* Just enable L2, the bits are different from others. + */ + _set_L2CR(L2CR_L2E); + } + else { + /* The magic number for Sandpoint/74xx PrPMCs. + */ + _set_L2CR(0xbd014000); + } +} + +#define SANDPOINT_87308_CFG_ADDR 0x15c +#define SANDPOINT_87308_CFG_DATA 0x15d + +#define SANDPOINT_87308_CFG_INB(addr, byte) { \ + outb((addr), SANDPOINT_87308_CFG_ADDR); \ + (byte) = inb(SANDPOINT_87308_CFG_DATA); \ +} + +#define SANDPOINT_87308_CFG_OUTB(addr, byte) { \ + outb((addr), SANDPOINT_87308_CFG_ADDR); \ + outb((byte), SANDPOINT_87308_CFG_DATA); \ +} + +#define SANDPOINT_87308_SELECT_DEV(dev_num) { \ + SANDPOINT_87308_CFG_OUTB(0x07, (dev_num)); \ +} + +#define SANDPOINT_87308_DEV_ENABLE(dev_num) { \ + SANDPOINT_87308_SELECT_DEV(dev_num); \ + SANDPOINT_87308_CFG_OUTB(0x30, 0x01); \ +} + +/* + * Initialize the ISA devices on the Nat'l PC87308VUL SuperIO chip. + */ +static void __init +sandpoint_setup_natl_87308(void) +{ + u_char reg; + + /* + * Enable all the devices on the Super I/O chip. + */ + SANDPOINT_87308_SELECT_DEV(0x00); /* Select kbd logical device */ + SANDPOINT_87308_CFG_OUTB(0xf0, 0x00); /* Set KBC clock to 8 Mhz */ + SANDPOINT_87308_DEV_ENABLE(0x00); /* Enable keyboard */ + SANDPOINT_87308_DEV_ENABLE(0x01); /* Enable mouse */ + SANDPOINT_87308_DEV_ENABLE(0x02); /* Enable rtc */ + SANDPOINT_87308_DEV_ENABLE(0x03); /* Enable fdc (floppy) */ + SANDPOINT_87308_DEV_ENABLE(0x04); /* Enable parallel */ + SANDPOINT_87308_DEV_ENABLE(0x05); /* Enable UART 2 */ + SANDPOINT_87308_CFG_OUTB(0xf0, 0x82); /* Enable bank select regs */ + SANDPOINT_87308_DEV_ENABLE(0x06); /* Enable UART 1 */ + SANDPOINT_87308_CFG_OUTB(0xf0, 0x82); /* Enable bank select regs */ + + /* Set up floppy in PS/2 mode */ + outb(0x09, SIO_CONFIG_RA); + reg = inb(SIO_CONFIG_RD); + reg = (reg & 0x3F) | 0x40; + outb(reg, SIO_CONFIG_RD); + outb(reg, SIO_CONFIG_RD); /* Have to write twice to change! */ + + return; +} + +/* + * Fix IDE interrupts. + */ +static void __init +sandpoint_fix_winbond_83553(void) +{ + /* Make all 8259 interrupt level sensitive */ + outb(0xf8, 0x4d0); + outb(0xde, 0x4d1); + + return; +} + +static void __init +sandpoint_init2(void) +{ + /* Do Sandpoint board specific initialization. */ + sandpoint_fix_winbond_83553(); + sandpoint_setup_natl_87308(); + + request_region(0x00,0x20,"dma1"); + request_region(0x20,0x20,"pic1"); + request_region(0x40,0x20,"timer"); + request_region(0x80,0x10,"dma page reg"); + request_region(0xa0,0x20,"pic2"); + request_region(0xc0,0x20,"dma2"); + + return; +} + +/* + * Interrupt setup and service. Interrrupts on the Sandpoint come + * from the four PCI slots plus the 8259 in the Winbond Super I/O (SIO). + * These interrupts are sent to one of four IRQs on the EPIC. + * The SIO shares its interrupt with either slot 2 or slot 3 (INTA#). + * Slot numbering is confusing. Sometimes in the documentation they + * use 0,1,2,3 and others 1,2,3,4. We will use slots 1,2,3,4 and + * map this to IRQ 16, 17, 18, 19. + * For Sandpoint X3, this has been better designed. The 8259 is + * cascaded from EPIC IRQ0, IRQ1-4 map to PCI slots 1-4, IDE is on + * EPIC 7 and 8. + */ +static void __init +sandpoint_init_IRQ(void) +{ + int i; + + /* + * 3 things cause us to jump through some hoops: + * 1) the EPIC on the 8240 & 107 are not full-blown openpic pic's + * 2) the 8259 is NOT cascaded on the openpic IRQ 0 + * 3) the 8259 shares its interrupt line with some PCI interrupts. + * + * What we'll do is set up the 8259 to be level sensitive, active low + * just like a PCI device. Then, when an interrupt on the IRQ that is + * shared with the 8259 comes in, we'll take a peek at the 8259 to see + * it its generating an interrupt. If it is, we'll handle the 8259 + * interrupt. Otherwise, we'll handle it just like a normal PCI + * interrupt. This does give the 8259 interrupts a higher priority + * than the EPIC ones--hopefully, not a problem. + */ + OpenPIC_InitSenses = sandpoint_openpic_initsenses; + OpenPIC_NumInitSenses = sizeof(sandpoint_openpic_initsenses); + + openpic_init(1, 0, NULL, -1); + + /* + * openpic_init() has set up irq_desc[0-23] to be openpic + * interrupts. We need to set irq_desc[0-15] to be 8259 interrupts. + * We then need to request and enable the 8259 irq. + */ + for(i=0; i < NUM_8259_INTERRUPTS; i++) + irq_desc[i].handler = &i8259_pic; + + if (request_irq(SANDPOINT_SIO_IRQ, no_action, SA_INTERRUPT, + "8259 cascade to EPIC", NULL)) { + + printk("Unable to get OpenPIC IRQ %d for cascade\n", + SANDPOINT_SIO_IRQ); + } + + i8259_init(NULL); +} + +static int +sandpoint_get_irq(struct pt_regs *regs) +{ + int irq, cascade_irq; + + irq = openpic_irq(); + + if (irq == SANDPOINT_SIO_IRQ) { + cascade_irq = i8259_poll(); + + if (cascade_irq != -1) { + irq = cascade_irq; + openpic_eoi(); + } + } + else if (irq == OPENPIC_VEC_SPURIOUS) { + irq = -1; + } + + return irq; +} + +static u32 +sandpoint_irq_cannonicalize(u32 irq) +{ + if (irq == 2) + { + return 9; + } + else + { + return irq; + } +} + +static ulong __init +sandpoint_find_end_of_memory(void) +{ + ulong size = 0; + +#if 0 /* Leave out until DINK sets mem ctlr correctly */ + size = mpc10x_get_mem_size(MPC10X_MEM_MAP_B); +#else + size = 32*1024*1024; +#endif + + return size; +} + +static void __init +sandpoint_map_io(void) +{ + io_block_mapping(0xfe000000, 0xfe000000, 0x02000000, _PAGE_IO); +} + +/* + * Due to Sandpoint X2 errata, the Port 92 will not work. + */ +static void +sandpoint_restart(char *cmd) +{ + __cli(); + + /* Set exception prefix high - to the firmware */ + _nmask_and_or_msr(0, MSR_IP); + + /* Reset system via Port 92 */ + outb(0x00, 0x92); + outb(0x01, 0x92); + for(;;); /* Spin until reset happens */ +} + +static void +sandpoint_power_off(void) +{ + __cli(); + for(;;); /* No way to shut power off with software */ + /* NOTREACHED */ +} + +static void +sandpoint_halt(void) +{ + sandpoint_power_off(); + /* NOTREACHED */ +} + +static int +sandpoint_show_cpuinfo(struct seq_file *m) +{ + uint pvid; + + pvid = mfspr(PVR); + + seq_printf(m, "vendor\t\t: Motorola SPS\n"); + seq_printf(m, "machine\t\t: Sandpoint\n"); + seq_printf(m, "processor\t: PVID: 0x%x, vendor: %s\n", + pvid, (pvid & (1<<15) ? "IBM" : "Motorola")); + + return 0; +} + +#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) +/* + * IDE support. + */ +static int sandpoint_ide_ports_known = 0; +static ide_ioreg_t sandpoint_ide_regbase[MAX_HWIFS]; +static ide_ioreg_t sandpoint_ide_ctl_regbase[MAX_HWIFS]; +static ide_ioreg_t sandpoint_idedma_regbase; + +static void +sandpoint_ide_probe(void) +{ + struct pci_dev *pdev = pci_find_device(PCI_VENDOR_ID_WINBOND, + PCI_DEVICE_ID_WINBOND_82C105, + NULL); + + if(pdev) { + sandpoint_ide_regbase[0]=pdev->resource[0].start; + sandpoint_ide_regbase[1]=pdev->resource[2].start; + sandpoint_ide_ctl_regbase[0]=pdev->resource[1].start; + sandpoint_ide_ctl_regbase[1]=pdev->resource[3].start; + sandpoint_idedma_regbase=pdev->resource[4].start; + } + + sandpoint_ide_ports_known = 1; + return; +} + +static int +sandpoint_ide_default_irq(ide_ioreg_t base) +{ + if (sandpoint_ide_ports_known == 0) + sandpoint_ide_probe(); + + if (base == sandpoint_ide_regbase[0]) + return SANDPOINT_IDE_INT0; + else if (base == sandpoint_ide_regbase[1]) + return SANDPOINT_IDE_INT1; + else + return 0; +} + +static ide_ioreg_t +sandpoint_ide_default_io_base(int index) +{ + if (sandpoint_ide_ports_known == 0) + sandpoint_ide_probe(); + + return sandpoint_ide_regbase[index]; +} + +static int +sandpoint_ide_check_region(ide_ioreg_t from, unsigned int extent) +{ + return check_region(from, extent); +} + +static void +sandpoint_ide_request_region(ide_ioreg_t from, + unsigned int extent, + const char *name) +{ + request_region(from, extent, name); + return; +} + +static void +sandpoint_ide_release_region(ide_ioreg_t from, + unsigned int extent) +{ + release_region(from, extent); + return; +} + +static void __init +sandpoint_ide_init_hwif_ports(hw_regs_t *hw, ide_ioreg_t data_port, + ide_ioreg_t ctrl_port, int *irq) +{ + ide_ioreg_t reg = data_port; + uint alt_status_base; + int i; + + for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) { + hw->io_ports[i] = reg++; + } + + if (data_port == sandpoint_ide_regbase[0]) { + alt_status_base = sandpoint_ide_ctl_regbase[0] + 2; + hw->irq = 14; + } + else if (data_port == sandpoint_ide_regbase[1]) { + alt_status_base = sandpoint_ide_ctl_regbase[1] + 2; + hw->irq = 15; + } + else { + alt_status_base = 0; + hw->irq = 0; + } + + if (ctrl_port) { + hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port; + } else { + hw->io_ports[IDE_CONTROL_OFFSET] = alt_status_base; + } + + if (irq != NULL) { + *irq = hw->irq; + } + + return; +} +#endif + +/* + * Set BAT 3 to map 0xf8000000 to end of physical memory space 1-to-1. + */ +static __inline__ void +sandpoint_set_bat(void) +{ + unsigned long bat3u, bat3l; + static int mapping_set = 0; + + if (!mapping_set) { + + __asm__ __volatile__( + " lis %0,0xf800\n \ + ori %1,%0,0x002a\n \ + ori %0,%0,0x0ffe\n \ + mtspr 0x21e,%0\n \ + mtspr 0x21f,%1\n \ + isync\n \ + sync " + : "=r" (bat3u), "=r" (bat3l)); + + mapping_set = 1; + } + + return; +} + +#ifdef CONFIG_SERIAL_TEXT_DEBUG +#include <linux/serialP.h> +#include <linux/serial_reg.h> +#include <asm/serial.h> + +static struct serial_state rs_table[RS_TABLE_SIZE] = { + SERIAL_PORT_DFNS /* Defined in <asm/serial.h> */ +}; + +static void +sandpoint_progress(char *s, unsigned short hex) +{ + volatile char c; + volatile unsigned long com_port; + u16 shift; + + com_port = rs_table[0].port; + shift = rs_table[0].iomem_reg_shift; + + while ((c = *s++) != 0) { + while ((*((volatile unsigned char *)com_port + + (UART_LSR << shift)) & UART_LSR_THRE) == 0) + ; + *(volatile unsigned char *)com_port = c; + + if (c == '\n') { + while ((*((volatile unsigned char *)com_port + + (UART_LSR << shift)) & UART_LSR_THRE) == 0) + ; + *(volatile unsigned char *)com_port = '\r'; + } + } +} +#endif /* CONFIG_SERIAL_TEXT_DEBUG */ + +__init void sandpoint_setup_pci_ptrs(void); + +TODC_ALLOC(); + +void __init +platform_init(unsigned long r3, unsigned long r4, unsigned long r5, + unsigned long r6, unsigned long r7) +{ + parse_bootinfo(find_bootinfo()); + + /* Map in board regs, etc. */ + sandpoint_set_bat(); + + isa_io_base = MPC10X_MAPB_ISA_IO_BASE; + isa_mem_base = MPC10X_MAPB_ISA_MEM_BASE; + pci_dram_offset = MPC10X_MAPB_DRAM_OFFSET; + ISA_DMA_THRESHOLD = 0x00ffffff; + DMA_MODE_READ = 0x44; + DMA_MODE_WRITE = 0x48; + + ppc_md.setup_arch = sandpoint_setup_arch; + ppc_md.show_cpuinfo = sandpoint_show_cpuinfo; + ppc_md.irq_cannonicalize = sandpoint_irq_cannonicalize; + ppc_md.init_IRQ = sandpoint_init_IRQ; + ppc_md.get_irq = sandpoint_get_irq; + ppc_md.init = sandpoint_init2; + + ppc_md.restart = sandpoint_restart; + ppc_md.power_off = sandpoint_power_off; + ppc_md.halt = sandpoint_halt; + + ppc_md.find_end_of_memory = sandpoint_find_end_of_memory; + ppc_md.setup_io_mappings = sandpoint_map_io; + + TODC_INIT(TODC_TYPE_PC97307, 0x70, 0x00, 0x71, 8); + ppc_md.time_init = todc_time_init; + ppc_md.set_rtc_time = todc_set_rtc_time; + ppc_md.get_rtc_time = todc_get_rtc_time; + ppc_md.calibrate_decr = todc_calibrate_decr; + + ppc_md.nvram_read_val = todc_mc146818_read_val; + ppc_md.nvram_write_val = todc_mc146818_write_val; + + ppc_md.heartbeat = NULL; + ppc_md.heartbeat_reset = 0; + ppc_md.heartbeat_count = 0; + +#ifdef CONFIG_SERIAL_TEXT_DEBUG + ppc_md.progress = sandpoint_progress; +#else /* !CONFIG_SERIAL_TEXT_DEBUG */ + ppc_md.progress = NULL; +#endif /* CONFIG_SERIAL_TEXT_DEBUG */ + +#ifdef CONFIG_VT + ppc_md.kbd_setkeycode = pckbd_setkeycode; + ppc_md.kbd_getkeycode = pckbd_getkeycode; + ppc_md.kbd_translate = pckbd_translate; + ppc_md.kbd_unexpected_up = pckbd_unexpected_up; + ppc_md.kbd_leds = pckbd_leds; + ppc_md.kbd_init_hw = pckbd_init_hw; +#ifdef CONFIG_MAGIC_SYSRQ + ppc_md.ppc_kbd_sysrq_xlate = pckbd_sysrq_xlate; + SYSRQ_KEY = 0x54; +#endif +#endif + +#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) + ppc_ide_md.default_irq = sandpoint_ide_default_irq; + ppc_ide_md.default_io_base = sandpoint_ide_default_io_base; + ppc_ide_md.ide_check_region = sandpoint_ide_check_region; + ppc_ide_md.ide_request_region = sandpoint_ide_request_region; + ppc_ide_md.ide_release_region = sandpoint_ide_release_region; + ppc_ide_md.ide_init_hwif = sandpoint_ide_init_hwif_ports; +#endif + + return; +} diff --git a/arch/ppc/platforms/sbs8260.h b/arch/ppc/platforms/sbs8260.h new file mode 100644 index 000000000000..76632d0c0e37 --- /dev/null +++ b/arch/ppc/platforms/sbs8260.h @@ -0,0 +1,28 @@ +#ifndef __ASSEMBLY__ +/* Board information for various SBS 8260 cards, which should be generic for + * all 8260 boards. The IMMR is now given to us so the hard define + * will soon be removed. All of the clock values are computed from + * the configuration SCMR and the Power-On-Reset word. + */ + +#define IMAP_ADDR ((uint)0xfe000000) + + +/* A Board Information structure that is given to a program when + * prom starts it up. + */ +typedef struct bd_info { + unsigned int bi_memstart; /* Memory start address */ + unsigned int bi_memsize; /* Memory (end) size in bytes */ + unsigned int bi_intfreq; /* Internal Freq, in Hz */ + unsigned int bi_busfreq; /* Bus Freq, in MHz */ + unsigned int bi_cpmfreq; /* CPM Freq, in MHz */ + unsigned int bi_brgfreq; /* BRG Freq, in MHz */ + unsigned int bi_vco; /* VCO Out from PLL */ + unsigned int bi_baudrate; /* Default console baud rate */ + unsigned int bi_immr; /* IMMR when called from boot rom */ + unsigned char bi_enetaddr[6]; +} bd_t; + +extern bd_t m8xx_board_info; +#endif /* !__ASSEMBLY__ */ diff --git a/arch/ppc/kernel/sleep.S b/arch/ppc/platforms/sleep.S index 153e358c124a..4e97c04611e2 100644 --- a/arch/ppc/kernel/sleep.S +++ b/arch/ppc/platforms/sleep.S @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.sleep.S 1.13 08/19/01 22:23:04 paulus + * BK Id: %F% %I% %G% %U% %#% */ /* * This file contains sleep low-level functions for PowerBook G3. @@ -13,9 +13,10 @@ * */ -#include "ppc_asm.tmpl" #include <asm/processor.h> #include <asm/page.h> +#include <asm/ppc_asm.h> +#include <asm/cputable.h> #define MAGIC 0x4c617273 /* 'Lars' */ @@ -37,13 +38,17 @@ #define SL_IBAT3 0x58 #define SL_TB 0x60 #define SL_HID0 0x68 -#define SL_R2 0x6c -#define SL_R12 0x70 /* r12 to r31 */ +#define SL_HID1 0x6c +#define SL_MSSCR0 0x70 +#define SL_MSSSR0 0x74 +#define SL_ICTRL 0x78 +#define SL_LDSTCR 0x7c +#define SL_LDSTDB 0x80 +#define SL_R2 0x84 +#define SL_CR 0x88 +#define SL_R12 0x8c /* r12 to r31 */ #define SL_SIZE (SL_R12 + 80) -#define tophys(rd,rs) addis rd,rs,-KERNELBASE@h -#define tovirt(rd,rs) addis rd,rs,KERNELBASE@h - .text .align 5 @@ -56,6 +61,8 @@ _GLOBAL(low_sleep_handler) mflr r0 stw r0,4(r1) stwu r1,-SL_SIZE(r1) + mfcr r0 + stw r0,SL_CR(r1) stw r2,SL_R2(r1) stmw r12,SL_R12(r1) @@ -121,7 +128,31 @@ _GLOBAL(low_sleep_handler) /* Save HID0 */ mfspr r4,HID0 stw r4,SL_HID0(r1) - + + /* Save 7400/7410/7450 specific registers */ + mfspr r3,PVR + srwi r3,r3,16 + cmpli cr0,r3,0x8000 + cmpli cr1,r3,0x000c + cmpli cr2,r3,0x800c + cror 4*cr1+eq,4*cr1+eq,4*cr2+eq + cror 4*cr0+eq,4*cr0+eq,4*cr1+eq + bne 1f + mfspr r4,SPRN_MSSCR0 + stw r4,SL_MSSCR0(r1) + mfspr r4,SPRN_MSSSR0 + stw r4,SL_MSSSR0(r1) + /* Save 7450 specific registers */ + beq cr1,1f + mfspr r4,HID1 + stw r4,SL_HID1(r1) + mfspr r4,SPRN_ICTRL + stw r4,SL_ICTRL(r1) + mfspr r4,SPRN_LDSTCR + stw r4,SL_LDSTCR(r1) + mfspr r4,SPRN_LDSTDB + stw r4,SL_LDSTDB(r1) +1: /* The ROM can wake us up via 2 different vectors: * - On wallstreet & lombard, we must write a magic * value 'Lars' at address 4 and a pointer to a @@ -257,6 +288,19 @@ grackle_wake_up: mtspr HID0,r3 sync + /* Restore the kernel's segment registers before + * we do any r1 memory access as we are not sure they + * are in a sane state above the first 256Mb region + */ + li r0,16 /* load up segment register values */ + mtctr r0 /* for context 0 */ + lis r3,0x2000 /* Ku = 1, VSID = 0 */ + li r4,0 +3: mtsrin r3,r4 + addi r3,r3,0x111 /* increment VSID */ + addis r4,r4,0x1000 /* address of next segment */ + bdnz 3b + /* Restore the remaining bits of the HID0 register. */ subi r1,r1,SL_PC lwz r3,SL_HID0(r1) @@ -266,17 +310,52 @@ grackle_wake_up: sync isync - /* Restore the kernel's segment registers, the - BATs, and SDR1. Then we can turn on the MMU. */ - li r0,16 /* load up segment register values */ - mtctr r0 /* for context 0 */ - lis r3,0x2000 /* Ku = 1, VSID = 0 */ + /* Restore 7400/7410/7450 specific registers */ + mfspr r3,PVR + srwi r3,r3,16 + cmpli cr0,r3,0x8000 + cmpli cr1,r3,0x000c + cmpli cr2,r3,0x800c + cror 4*cr1+eq,4*cr1+eq,4*cr2+eq + cror 4*cr0+eq,4*cr0+eq,4*cr1+eq + bne 1f + lwz r4,SL_MSSCR0(r1) + sync + mtspr SPRN_MSSCR0,r4 + sync + isync + lwz r4,SL_MSSSR0(r1) + sync + mtspr SPRN_MSSSR0,r4 + sync + isync + bne cr2,1f li r4,0 -3: mtsrin r3,r4 - addi r3,r3,0x111 /* increment VSID */ - addis r4,r4,0x1000 /* address of next segment */ - bdnz 3b - + mtspr SPRN_L2CR2,r4 + /* Restore 7450 specific registers */ + beq cr1,1f + lwz r4,SL_HID1(r1) + sync + mtspr HID1,r4 + isync + sync + lwz r4,SPRN_ICTRL(r1) + sync + mtspr SPRN_ICTRL,r4 + isync + sync + lwz r4,SPRN_LDSTCR(r1) + sync + mtspr SPRN_LDSTCR,r4 + isync + sync + lwz r4,SL_LDSTDB(r1) + sync + mtspr SPRN_LDSTDB,r4 + isync + sync +1: + /* Restore the BATs, and SDR1. Then we can turn on the MMU. */ lwz r4,SL_SDR1(r1) mtsdr1 r4 lwz r4,SL_SPRG0(r1) @@ -344,6 +423,8 @@ grackle_wake_up: mttbl r4 /* Restore the callee-saved registers and return */ + lwz r0,SL_CR(r1) + mtcr r0 lwz r2,SL_R2(r1) lmw r12,SL_R12(r1) addi r1,r1,SL_SIZE diff --git a/include/asm-ppc/spd8xx.h b/arch/ppc/platforms/spd8xx.h index b6c93bdfd10f..b6c93bdfd10f 100644 --- a/include/asm-ppc/spd8xx.h +++ b/arch/ppc/platforms/spd8xx.h diff --git a/arch/ppc/platforms/spruce.h b/arch/ppc/platforms/spruce.h new file mode 100644 index 000000000000..5009c5f7d886 --- /dev/null +++ b/arch/ppc/platforms/spruce.h @@ -0,0 +1,73 @@ +/* + * include/asm-ppc/platforms/spruce.h + * + * Definitions for IBM Spruce reference board support + * + * Authors: Matt Porter and Johnnie Peters + * mporter@mvista.com + * jpeters@mvista.com + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifdef __KERNEL__ +#ifndef __ASM_SPRUCE_H__ +#define __ASM_SPRUCE_H__ + +#define SPRUCE_PCI_CONFIG_ADDR 0xfec00000 +#define SPRUCE_PCI_CONFIG_DATA 0xfec00004 + +#define SPRUCE_PCI_PHY_IO_BASE 0xf8000000 +#define SPRUCE_PCI_IO_BASE SPRUCE_PCI_PHY_IO_BASE + +#define SPRUCE_PCI_SYS_MEM_BASE 0x00000000 + +#define SPRUCE_PCI_LOWER_MEM 0x80000000 +#define SPRUCE_PCI_UPPER_MEM 0x9fffffff +#define SPRUCE_PCI_LOWER_IO 0x00000000 +#define SPRUCE_PCI_UPPER_IO 0x03ffffff + +#define SPRUCE_ISA_IO_BASE SPRUCE_PCI_IO_BASE + +#define SPRUCE_MEM_SIZE 0x04000000 +#define SPRUCE_BUS_SPEED 66666667 + +#define SPRUCE_SERIAL_1_ADDR 0xff600300 +#define SPRUCE_SERIAL_2_ADDR 0xff600400 + +#define SPRUCE_NVRAM_BASE_ADDR 0xff800000 +#define SPRUCE_RTC_BASE_ADDR SPRUCE_NVRAM_BASE_ADDR + +#define KEYBOARD_IRQ 22 +#define AUX_IRQ 21 + +unsigned char spruce_read_keyb_data(void); +unsigned char spruce_read_keyb_status(void); + +#define kbd_read_input spruce_read_keyb_data +#define kbd_read_status spruce_read_keyb_status +#define kbd_write_output(val) *((unsigned char *)0xff810000) = (char)val +#define kbd_write_command(val) *((unsigned char *)0xff810001) = (char)val + +#endif /* __ASM_SPRUCE_H__ */ +#endif /* __KERNEL__ */ diff --git a/arch/ppc/platforms/spruce_pci.c b/arch/ppc/platforms/spruce_pci.c new file mode 100644 index 000000000000..27a7887b2c44 --- /dev/null +++ b/arch/ppc/platforms/spruce_pci.c @@ -0,0 +1,104 @@ +/* + * arch/ppc/platforms/spruce_pci.c + * + * PCI support for IBM Spruce + * + * Author: Johnnie Peters + * jpeters@mvista.com + * + * Copyright 2000 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/pci.h> +#include <linux/slab.h> + +#include <asm/byteorder.h> +#include <asm/io.h> +#include <asm/uaccess.h> +#include <asm/machdep.h> +#include <asm/pci-bridge.h> +#include <platforms/spruce.h> + +#include "cpc700.h" + +static inline int +spruce_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) +{ + static char pci_irq_table[][4] = + /* + * PCI IDSEL/INTPIN->INTLINE + * A B C D + */ + { + {23, 24, 25, 26}, /* IDSEL 1 - PCI slot 3 */ + {24, 25, 26, 23}, /* IDSEL 2 - PCI slot 2 */ + {25, 26, 23, 24}, /* IDSEL 3 - PCI slot 1 */ + {26, 23, 24, 25}, /* IDSEL 4 - PCI slot 0 */ + }; + + const long min_idsel = 1, max_idsel = 4, irqs_per_slot = 4; + return PCI_IRQ_TABLE_LOOKUP; +} + +void __init +spruce_setup_hose(void) +{ + struct pci_controller *hose; + + /* Setup hose */ + hose = pcibios_alloc_controller(); + if (!hose) + return; + + hose->first_busno = 0; + hose->last_busno = 0xff; + + pci_init_resource(&hose->io_resource, + SPRUCE_PCI_LOWER_IO, + SPRUCE_PCI_UPPER_IO, + IORESOURCE_IO, + "PCI host bridge"); + + pci_init_resource(&hose->mem_resources[0], + SPRUCE_PCI_LOWER_MEM, + SPRUCE_PCI_UPPER_MEM, + IORESOURCE_MEM, + "PCI host bridge"); + + hose->io_space.start = SPRUCE_PCI_LOWER_IO; + hose->io_space.end = SPRUCE_PCI_UPPER_IO; + hose->mem_space.start = SPRUCE_PCI_LOWER_MEM; + hose->mem_space.end = SPRUCE_PCI_UPPER_MEM; + hose->io_base_virt = (void *)SPRUCE_ISA_IO_BASE; + + setup_indirect_pci(hose, + SPRUCE_PCI_CONFIG_ADDR, + SPRUCE_PCI_CONFIG_DATA); + + hose->last_busno = pciauto_bus_scan(hose, hose->first_busno); + + ppc_md.pci_swizzle = common_swizzle; + ppc_md.pci_map_irq = spruce_map_irq; +} diff --git a/arch/ppc/platforms/spruce_serial.h b/arch/ppc/platforms/spruce_serial.h new file mode 100644 index 000000000000..b59b61b11680 --- /dev/null +++ b/arch/ppc/platforms/spruce_serial.h @@ -0,0 +1,72 @@ +/* + * include/asm-ppc/spruce_serial.h + * + * Definitions for IBM Spruce reference board support + * + * Authors: Matt Porter and Johnnie Peters + * mporter@mvista.com + * jpeters@mvista.com + * + * Copyright 2000 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __ASMPPC_SPRUCE_SERIAL_H +#define __ASMPPC_SPRUCE_SERIAL_H + +#include <linux/config.h> + +/* This is where the serial ports exist */ +#define SPRUCE_SERIAL_1_ADDR 0xff600300 +#define SPRUCE_SERIAL_2_ADDR 0xff600400 + +#define RS_TABLE_SIZE 4 + +/* Rate for the baud clock for the onboard serial chip */ +#ifndef CONFIG_SPRUCE_BAUD_33M +#define BASE_BAUD (30000000 / 4 / 16) +#else +#define BASE_BAUD (33000000 / 4 / 16) +#endif + +#ifndef SERIAL_MAGIC_KEY +#define kernel_debugger ppc_kernel_debug +#endif + +#ifdef CONFIG_SERIAL_DETECT_IRQ +#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF|ASYNC_SKIP_TEST|ASYNC_AUTO_IRQ) +#else +#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF|ASYNC_SKIP_TEST) +#endif + +#define STD_SERIAL_PORT_DFNS \ + { 0, BASE_BAUD, SPRUCE_SERIAL_1_ADDR, 3, STD_COM_FLAGS, /* ttyS0 */ \ + iomem_base: (u8 *)SPRUCE_SERIAL_1_ADDR, \ + io_type: SERIAL_IO_MEM }, \ + { 0, BASE_BAUD, SPRUCE_SERIAL_2_ADDR, 4, STD_COM_FLAGS, /* ttyS1 */ \ + iomem_base: (u8 *)SPRUCE_SERIAL_2_ADDR, \ + io_type: SERIAL_IO_MEM }, + +#define SERIAL_PORT_DFNS \ + STD_SERIAL_PORT_DFNS + +#endif /* __ASMPPC_SPRUCE_SERIAL_H */ diff --git a/arch/ppc/platforms/spruce_setup.c b/arch/ppc/platforms/spruce_setup.c new file mode 100644 index 000000000000..2358c9ba441b --- /dev/null +++ b/arch/ppc/platforms/spruce_setup.c @@ -0,0 +1,295 @@ +/* + * arch/ppc/platforms/spruce_setup.c + * + * Board setup routines for IBM Spruce + * + * Authors: Johnnie Peters <jpeters@mvista.com> + * Matt Porter <mporter@mvista.com> + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <linux/config.h> +#include <linux/stddef.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/errno.h> +#include <linux/reboot.h> +#include <linux/pci.h> +#include <linux/kdev_t.h> +#include <linux/types.h> +#include <linux/major.h> +#include <linux/blk.h> +#include <linux/console.h> +#include <linux/delay.h> +#include <linux/seq_file.h> +#include <linux/ide.h> + +#include <asm/keyboard.h> +#include <asm/system.h> +#include <asm/pgtable.h> +#include <asm/page.h> +#include <asm/dma.h> +#include <asm/io.h> +#include <asm/machdep.h> +#include <asm/time.h> +#include <platforms/spruce.h> +#include <asm/todc.h> +#include <asm/bootinfo.h> + +#include "cpc700.h" + +extern void spruce_init_IRQ(void); +extern int spruce_get_irq(struct pt_regs *); +extern void spruce_setup_hose(void); + +extern int pckbd_setkeycode(unsigned int, unsigned int); +extern int pckbd_getkeycode(unsigned int); +extern int pckbd_translate(unsigned char, unsigned char *, char); +extern char pckbd_unexpected_up(unsigned char); +extern void pckbd_leds(unsigned char); +extern void pckbd_init_hw(void); +extern unsigned char pckbd_sysrq_xlate[128]; +extern char cmd_line[]; + +/* + * CPC700 PIC interrupt programming table + * + * First entry is the sensitivity (level/edge), second is the polarity. + */ +unsigned int cpc700_irq_assigns[27][2] = { + { 1, 1 }, /* IRQ 0: ECC Correctable Error - rising edge */ + { 1, 1 }, /* IRQ 1: PCI Write Mem Range - rising edge */ + { 0, 1 }, /* IRQ 2: PCI Write Command Reg - active high */ + { 0, 1 }, /* IRQ 3: UART 0 - active high */ + { 0, 1 }, /* IRQ 4: UART 1 - active high */ + { 0, 1 }, /* IRQ 5: ICC 0 - active high */ + { 0, 1 }, /* IRQ 6: ICC 1 - active high */ + { 0, 1 }, /* IRQ 7: GPT Compare 0 - active high */ + { 0, 1 }, /* IRQ 8: GPT Compare 1 - active high */ + { 0, 1 }, /* IRQ 9: GPT Compare 2 - active high */ + { 0, 1 }, /* IRQ 10: GPT Compare 3 - active high */ + { 0, 1 }, /* IRQ 11: GPT Compare 4 - active high */ + { 0, 1 }, /* IRQ 12: GPT Capture 0 - active high */ + { 0, 1 }, /* IRQ 13: GPT Capture 1 - active high */ + { 0, 1 }, /* IRQ 14: GPT Capture 2 - active high */ + { 0, 1 }, /* IRQ 15: GPT Capture 3 - active high */ + { 0, 1 }, /* IRQ 16: GPT Capture 4 - active high */ + { 0, 0 }, /* IRQ 17: Reserved */ + { 0, 0 }, /* IRQ 18: Reserved */ + { 0, 0 }, /* IRQ 19: Reserved */ + { 0, 1 }, /* IRQ 20: FPGA EXT_IRQ0 - active high */ + { 1, 1 }, /* IRQ 21: Mouse - rising edge */ + { 1, 1 }, /* IRQ 22: Keyboard - rising edge */ + { 0, 0 }, /* IRQ 23: PCI Slot 3 - active low */ + { 0, 0 }, /* IRQ 24: PCI Slot 2 - active low */ + { 0, 0 }, /* IRQ 25: PCI Slot 1 - active low */ + { 0, 0 }, /* IRQ 26: PCI Slot 0 - active low */ +}; + +static void __init +spruce_calibrate_decr(void) +{ + int freq, divisor = 4; + + /* determine processor bus speed */ + freq = SPRUCE_BUS_SPEED; + tb_ticks_per_jiffy = freq / HZ / divisor; + tb_to_us = mulhwu_scale_factor(freq/divisor, 1000000); +} + +static int +spruce_show_cpuinfo(struct seq_file *m) +{ + seq_printf(m, "vendor\t\t: IBM\n"); + seq_printf(m, "machine\t\t: Spruce\n"); + + return 0; +} + +TODC_ALLOC(); + +static void __init +spruce_setup_arch(void) +{ + /* Setup TODC access */ + TODC_INIT(TODC_TYPE_DS1643, 0, 0, SPRUCE_RTC_BASE_ADDR, 8); + + /* init to some ~sane value until calibrate_delay() runs */ + loops_per_jiffy = 50000000 / HZ; + + /* Setup PCI host bridge */ + spruce_setup_hose(); + +#ifdef CONFIG_BLK_DEV_INITRD + if (initrd_start) + ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); /* /dev/ram */ + else +#endif +#ifdef CONFIG_ROOT_NFS + ROOT_DEV = to_kdev_t(0x00FF); /* /dev/nfs pseudo device */ +#else + ROOT_DEV = to_kdev_t(0x0801); /* /dev/sda1 */ +#endif + +#ifdef CONFIG_DUMMY_CONSOLE + conswitchp = &dummy_con; +#endif + + /* Identify the system */ + printk("System Identification: IBM Spruce\n"); + printk("IBM Spruce port (C) 2001 MontaVista Software, Inc. (source@mvista.com)\n"); +} + +static void +spruce_restart(char *cmd) +{ + __cli(); + + /* SRR0 has system reset vector, SRR1 has default MSR value */ + /* rfi restores MSR from SRR1 and sets the PC to the SRR0 value */ + __asm__ __volatile__ + ("\n\ + lis 3,0xfff0 + ori 3,3,0x0100 + mtspr 26,3 + li 3,0 + mtspr 27,3 + rfi + "); + for(;;); +} + +static void +spruce_power_off(void) +{ + for(;;); +} + +static void +spruce_halt(void) +{ + spruce_restart(NULL); +} + +extern int boot_mem_size; + +static unsigned long __init +spruce_find_end_of_memory(void) +{ + return boot_mem_size; +} + +static void __init +spruce_map_io(void) +{ + io_block_mapping(SPRUCE_PCI_IO_BASE, SPRUCE_PCI_PHY_IO_BASE, + 0x08000000, _PAGE_IO); +} + +unsigned char spruce_read_keyb_status(void) +{ + unsigned long kbd_status; + + __raw_writel(0x00000088, 0xff500008); + eieio(); + + __raw_writel(0x03000000, 0xff50000c); + eieio(); + + asm volatile(" lis 7,0xff88 \n + ori 7,7,0x8 \n + lswi 6,7,0x8 \n + mr %0,6 \n" + : "=r" (kbd_status) :: "6", "7"); + + __raw_writel(0x00000000, 0xff50000c); + eieio(); + + return (unsigned char)(kbd_status >> 24); +} + +unsigned char spruce_read_keyb_data(void) +{ + unsigned long kbd_data; + + __raw_writel(0x00000088, 0xff500008); + eieio(); + + __raw_writel(0x03000000, 0xff50000c); + eieio(); + + asm volatile(" lis 7,0xff88 \n + lswi 6,7,0x8 \n + mr %0,6 \n" + : "=r" (kbd_data) :: "6", "7"); + + __raw_writel(0x00000000, 0xff50000c); + eieio(); + + return (unsigned char)(kbd_data >> 24); +} + +void __init +platform_init(unsigned long r3, unsigned long r4, unsigned long r5, + unsigned long r6, unsigned long r7) +{ + parse_bootinfo(find_bootinfo()); + + isa_io_base = SPRUCE_ISA_IO_BASE; + pci_dram_offset = SPRUCE_PCI_SYS_MEM_BASE; + + ppc_md.setup_arch = spruce_setup_arch; + ppc_md.show_cpuinfo = spruce_show_cpuinfo; + ppc_md.init_IRQ = cpc700_init_IRQ; + ppc_md.get_irq = cpc700_get_irq; + + ppc_md.find_end_of_memory = spruce_find_end_of_memory; + ppc_md.setup_io_mappings = spruce_map_io; + + ppc_md.restart = spruce_restart; + ppc_md.power_off = spruce_power_off; + ppc_md.halt = spruce_halt; + + ppc_md.time_init = todc_time_init; + ppc_md.set_rtc_time = todc_set_rtc_time; + ppc_md.get_rtc_time = todc_get_rtc_time; + ppc_md.calibrate_decr = spruce_calibrate_decr; + + ppc_md.nvram_read_val = todc_direct_read_val; + ppc_md.nvram_write_val = todc_direct_write_val; + +#ifdef CONFIG_VT + /* Spruce has a PS2 style keyboard */ + ppc_md.kbd_setkeycode = pckbd_setkeycode; + ppc_md.kbd_getkeycode = pckbd_getkeycode; + ppc_md.kbd_translate = pckbd_translate; + ppc_md.kbd_unexpected_up = pckbd_unexpected_up; + ppc_md.kbd_leds = pckbd_leds; + ppc_md.kbd_init_hw = pckbd_init_hw; +#ifdef CONFIG_MAGIC_SYSRQ + ppc_md.kbd_sysrq_xlate = pckbd_sysrq_xlate; + SYSRQ_KEY = 0x54; +#endif +#endif +} diff --git a/arch/ppc/platforms/tqm8260.h b/arch/ppc/platforms/tqm8260.h new file mode 100644 index 000000000000..c166f3e74115 --- /dev/null +++ b/arch/ppc/platforms/tqm8260.h @@ -0,0 +1,17 @@ +/* + * TQM8260 board specific definitions + * + * Copyright (c) 2001 Wolfgang Denk (wd@denx.de) + */ + +#ifndef __MACH_TQM8260_H +#define __MACH_TQM8260_H + +#include <linux/config.h> + +#include <asm/ppcboot.h> + +#define IMAP_ADDR ((uint)0xFFF00000) +#define PHY_INTERRUPT 25 + +#endif /* __MACH_TQM8260_H */ diff --git a/include/asm-ppc/tqm8xx.h b/arch/ppc/platforms/tqm8xx.h index fb5b4df54e8a..fb5b4df54e8a 100644 --- a/include/asm-ppc/tqm8xx.h +++ b/arch/ppc/platforms/tqm8xx.h diff --git a/arch/ppc/platforms/walnut.c b/arch/ppc/platforms/walnut.c new file mode 100755 index 000000000000..be520b8fd5c9 --- /dev/null +++ b/arch/ppc/platforms/walnut.c @@ -0,0 +1,261 @@ +/* + * + * Copyrigh t(c) 1999-2000 Grant Erickson <grant@lcse.umn.edu> + * + * Copyright 2000-2001 MontaVista Software Inc. + * Completed implementation. + * Author: MontaVista Software, Inc. <source@mvista.com> + * + * Module name: walnut.c + * + * Description: + * Architecture- / platform-specific boot-time initialization code for + * IBM PowerPC 4xx based boards. Adapted from original + * code by Gary Thomas, Cort Dougan <cort@fsmlabs.com>, and Dan Malek + * <dan@net4x.com>. + * + * History: 11/09/2001 - armin + * added board_init to add in additional instuctions needed during platfrom_init + * + * 01/22/2002 - Armin + * converted pci to ocp + * + * + */ +#include <linux/config.h> +#include <linux/init.h> +#include <linux/smp.h> +#include <linux/threads.h> +#include <linux/param.h> +#include <linux/string.h> +#include <linux/blk.h> +#include <linux/pci.h> +#include <linux/rtc.h> + +#include <asm/system.h> +#include <asm/pci-bridge.h> +#include <asm/processor.h> +#include <asm/machdep.h> +#include <asm/page.h> +#include <asm/time.h> +#include <asm/io.h> +#include <platforms/ibm_ocp.h> + +#ifdef CONFIG_PPC_RTC +#include <asm/todc.h> +#endif + +#undef DEBUG + +#ifdef DEBUG +#define DBG(x...) printk(x) +#else +#define DBG(x...) +#endif + +void *kb_cs; +void *kb_data; +void *walnut_rtc_base; + +/* Some IRQs unique to Walnut. + * Used by the generic 405 PCI setup functions in ppc4xx_pci.c + */ +int __init +ppc405_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) +{ + static char pci_irq_table[][4] = + /* + * PCI IDSEL/INTPIN->INTLINE + * A B C D + */ + { + {28, 28, 28, 28}, /* IDSEL 1 - PCI slot 1 */ + {29, 29, 29, 29}, /* IDSEL 2 - PCI slot 2 */ + {30, 30, 30, 30}, /* IDSEL 3 - PCI slot 3 */ + {31, 31, 31, 31}, /* IDSEL 4 - PCI slot 4 */ + }; + + const long min_idsel = 1, max_idsel = 4, irqs_per_slot = 4; + return PCI_IRQ_TABLE_LOOKUP; +}; + +void __init +board_setup_arch(void) +{ +#define WALNUT_PS2_BASE 0xF0100000 +#define WALNUT_FPGA_BASE 0xF0300000 + + void *fpga_brdc; + unsigned char fpga_brdc_data; + void *fpga_enable; + void *fpga_polarity; + void *fpga_status; + void *fpga_trigger; + + kb_data = ioremap(WALNUT_PS2_BASE, 8); + if (!kb_data) { + printk(KERN_CRIT + "walnut_setup_arch() kb_data ioremap failed\n"); + return; + } + + kb_cs = kb_data + 1; + + fpga_status = ioremap(WALNUT_FPGA_BASE, 8); + if (!fpga_status) { + printk(KERN_CRIT + "walnut_setup_arch() fpga_status ioremap failed\n"); + return; + } + + fpga_enable = fpga_status + 1; + fpga_polarity = fpga_status + 2; + fpga_trigger = fpga_status + 3; + fpga_brdc = fpga_status + 4; + + /* split the keyboard and mouse interrupts */ + fpga_brdc_data = readb(fpga_brdc); + fpga_brdc_data |= 0x80; + writeb(fpga_brdc_data, fpga_brdc); + + writeb(0x3, fpga_enable); + + writeb(0x3, fpga_polarity); + + writeb(0x3, fpga_trigger); + +#ifdef CONFIG_PPC_RTC + /* RTC step for the walnut */ + walnut_rtc_base = (void *) WALNUT_RTC_VADDR; + TODC_INIT(TODC_TYPE_DS1743, walnut_rtc_base, walnut_rtc_base, + walnut_rtc_base, 8); +#endif /* CONFIG_PPC_RTC */ +} + +void __init +bios_fixup(struct pci_controller *hose, void *pcil0_base) +{ + + unsigned int bar_response, bar; + struct pcil0_regs *pcip; + /* + * Expected PCI mapping: + * + * PLB addr PCI memory addr + * --------------------- --------------------- + * 0000'0000 - 7fff'ffff <--- 0000'0000 - 7fff'ffff + * 8000'0000 - Bfff'ffff ---> 8000'0000 - Bfff'ffff + * + * PLB addr PCI io addr + * --------------------- --------------------- + * e800'0000 - e800'ffff ---> 0000'0000 - 0001'0000 + * + * The following code is simplified by assuming that the bootrom + * has been well behaved in following this mapping. + */ + +#ifdef DEBUG + int i; + pcip = (struct pcil0_regs *) pcil0_base; + + printk("ioremap PCLIO_BASE = 0x%x\n", pcip); + printk("PCI bridge regs before fixup \n"); + for (i = 0; i <= 3; i++) { + printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].ma))); + printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].la))); + printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].pcila))); + printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].pciha))); + } + printk(" ptm1ms\t0x%x\n", in_le32(&(pcip->ptm1ms))); + printk(" ptm1la\t0x%x\n", in_le32(&(pcip->ptm1la))); + printk(" ptm2ms\t0x%x\n", in_le32(&(pcip->ptm2ms))); + printk(" ptm2la\t0x%x\n", in_le32(&(pcip->ptm2la))); + +#else + pcip = (struct pcil0_regs *) pcil0_base; +#endif + + /* added for IBM boot rom version 1.15 bios bar changes -AK */ + + /* Disable region first */ + out_le32((void *) &(pcip->pmm[0].ma), 0x00000000); + /* PLB starting addr, PCI: 0x80000000 */ + out_le32((void *) &(pcip->pmm[0].la), 0x80000000); + /* PCI start addr, 0x80000000 */ + out_le32((void *) &(pcip->pmm[0].pcila), PPC405_PCI_MEM_BASE); + /* 512MB range of PLB to PCI */ + out_le32((void *) &(pcip->pmm[0].pciha), 0x00000000); + /* Enable no pre-fetch, enable region */ + out_le32((void *) &(pcip->pmm[0].ma), ((0xffffffff - + (PPC405_PCI_UPPER_MEM - + PPC405_PCI_MEM_BASE)) | 0x01)); + + /* Disable region one */ + out_le32((void *) &(pcip->pmm[1].ma), 0x00000000); + out_le32((void *) &(pcip->pmm[1].la), 0x00000000); + out_le32((void *) &(pcip->pmm[1].pcila), 0x00000000); + out_le32((void *) &(pcip->pmm[1].pciha), 0x00000000); + out_le32((void *) &(pcip->pmm[1].ma), 0x00000000); + out_le32((void *) &(pcip->ptm1ms), 0x00000000); + + /* Disable region two */ + out_le32((void *) &(pcip->pmm[2].ma), 0x00000000); + out_le32((void *) &(pcip->pmm[2].la), 0x00000000); + out_le32((void *) &(pcip->pmm[2].pcila), 0x00000000); + out_le32((void *) &(pcip->pmm[2].pciha), 0x00000000); + out_le32((void *) &(pcip->pmm[2].ma), 0x00000000); + out_le32((void *) &(pcip->ptm2ms), 0x00000000); + + /* Zero config bars */ + for (bar = PCI_BASE_ADDRESS_1; bar <= PCI_BASE_ADDRESS_2; bar += 4) { + early_write_config_dword(hose, hose->first_busno, + PCI_FUNC(hose->first_busno), bar, + 0x00000000); + early_read_config_dword(hose, hose->first_busno, + PCI_FUNC(hose->first_busno), bar, + &bar_response); + DBG("BUS %d, device %d, Function %d bar 0x%8.8x is 0x%8.8x\n", + hose->first_busno, PCI_SLOT(hose->first_busno), + PCI_FUNC(hose->first_busno), bar, bar_response); + } + /* end work arround */ + +#ifdef DEBUG + printk("PCI bridge regs after fixup \n"); + for (i = 0; i <= 3; i++) { + printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].ma))); + printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].la))); + printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].pcila))); + printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].pciha))); + } + printk(" ptm1ms\t0x%x\n", in_le32(&(pcip->ptm1ms))); + printk(" ptm1la\t0x%x\n", in_le32(&(pcip->ptm1la))); + printk(" ptm2ms\t0x%x\n", in_le32(&(pcip->ptm2ms))); + printk(" ptm2la\t0x%x\n", in_le32(&(pcip->ptm2la))); + +#endif +} + +void __init +board_io_mapping(void) +{ + io_block_mapping(WALNUT_RTC_VADDR, + WALNUT_RTC_PADDR, WALNUT_RTC_SIZE, _PAGE_IO); +} + +void __init +board_setup_irq(void) +{ +} + +void __init +board_init(void) +{ +#ifdef CONFIG_PPC_RTC + ppc_md.time_init = todc_time_init; + ppc_md.set_rtc_time = todc_set_rtc_time; + ppc_md.get_rtc_time = todc_get_rtc_time; + ppc_md.nvram_read_val = todc_direct_read_val; + ppc_md.nvram_write_val = todc_direct_write_val; +#endif +} diff --git a/include/asm-ppc/walnut.h b/arch/ppc/platforms/walnut.h index 088e6ec9dc8c..ccf4c5cf732f 100644 --- a/include/asm-ppc/walnut.h +++ b/arch/ppc/platforms/walnut.h @@ -1,7 +1,4 @@ /* - * BK Id: SCCS/s.walnut.h 1.10 09/14/01 17:37:56 trini - */ -/* * * Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu> * @@ -24,8 +21,11 @@ */ #ifdef __KERNEL__ -#ifndef __WALNUT_H__ -#define __WALNUT_H__ +#ifndef __ASM_WALNUT_H__ +#define __ASM_WALNUT_H__ + +/* We have a 405GP core */ +#include <platforms/ibm405gp.h> #ifndef __ASSEMBLY__ /* @@ -41,18 +41,48 @@ typedef struct board_info { unsigned int bi_memsize; /* DRAM installed, in bytes */ unsigned char bi_enetaddr[6]; /* Local Ethernet MAC address */ unsigned char bi_pci_enetaddr[6]; /* PCI Ethernet MAC address */ - unsigned int bi_procfreq; /* Processor speed, in Hz */ - unsigned int bi_plb_busfreq; /* PLB Bus speed, in Hz */ + unsigned int bi_intfreq; /* Processor speed, in Hz */ + unsigned int bi_busfreq; /* PLB Bus speed, in Hz */ unsigned int bi_pci_busfreq; /* PCI Bus speed, in Hz */ } bd_t; -#endif /* !__ASSEMBLY__ */ +/* Some 4xx parts use a different timebase frequency from the internal clock. +*/ +#define bi_tbfreq bi_intfreq + /* Memory map for the IBM "Walnut" 405GP evaluation board. * Generic 4xx plus RTC. */ -#define WALNUT_RTC_ADDR ((uint)0xf0001000) -#define WALNUT_RTC_SIZE ((uint)4*1024) -#endif /* __WALNUT_H__ */ +extern void *walnut_rtc_base; +#define WALNUT_RTC_PADDR ((uint)0xf0000000) +#define WALNUT_RTC_VADDR WALNUT_RTC_PADDR +#define WALNUT_RTC_SIZE ((uint)8*1024) + +/* ps2 keyboard and mouse */ +#define KEYBOARD_IRQ 25 +#define AUX_IRQ 26 + +#ifdef CONFIG_PPC405GP_INTERNAL_CLOCK +#define BASE_BAUD 201600 +#else +#define BASE_BAUD 691200 +#endif + +#define WALNUT_PS2_BASE 0xF0100000 +#define WALNUT_FPGA_BASE 0xF0300000 + + +extern void *kb_cs; +extern void *kb_data; +#define kbd_read_input() readb(kb_data) +#define kbd_read_status() readb(kb_cs) +#define kbd_write_output(val) writeb(val, kb_data) +#define kbd_write_command(val) writeb(val, kb_cs) + +#define PPC4xx_MACHINE_NAME "IBM Walnut" + +#endif /* !__ASSEMBLY__ */ +#endif /* __ASM_WALNUT_H__ */ #endif /* __KERNEL__ */ diff --git a/arch/ppc/platforms/zx4500.h b/arch/ppc/platforms/zx4500.h new file mode 100644 index 000000000000..b4c31cde3f90 --- /dev/null +++ b/arch/ppc/platforms/zx4500.h @@ -0,0 +1,70 @@ +/* * arch/ppc/platforms/zx4500.h + * + * Board setup routines for Znyx ZX4500 cPCI board. + * + * Author: Mark A. Greer + * mgreer@mvista.com + * + * Copyright 2000, 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#ifndef __PPC_PLATFORMS_ZX4500_H_ +#define __PPC_PLATFORMS_ZX4500_H_ + +/* + * Define the addresses of CPLD registers in CLPD area. + */ +#define ZX4500_CPLD_BOARD_ID 0xff800001 +#define ZX4500_CPLD_REV 0xff800002 +#define ZX4500_CPLD_RESET 0xff800011 +#define ZX4500_CPLD_PHY1 0xff800014 +#define ZX4500_CPLD_PHY2 0xff800015 +#define ZX4500_CPLD_PHY3 0xff800016 +#define ZX4500_CPLD_SYSCTL 0xff800017 +#define ZX4500_CPLD_EXT_FLASH 0xff800018 +#define ZX4500_CPLD_DUAL1 0xff800019 +#define ZX4500_CPLD_DUAL2 0xff80001A +#define ZX4500_CPLD_STATUS 0xff800030 +#define ZX4500_CPLD_STREAM 0xff800032 +#define ZX4500_CPLD_PHY1_LED 0xff800034 +#define ZX4500_CPLD_PHY2_LED 0xff800035 +#define ZX4500_CPLD_PHY3_LED 0xff800036 +#define ZX4500_CPLD_PHY1_LNK 0xff80003C +#define ZX4500_CPLD_PHY2_LNK 0xff80003D +#define ZX4500_CPLD_PHY3_LNK 0xff80003E + +#define ZX4500_CPLD_RESET_SOFT 0x01 /* Soft Reset */ +#define ZX4500_CPLD_RESET_XBUS 0x40 /* Reset entire board */ + +#define ZX4500_CPLD_SYSCTL_PMC 0x01 /* Enable INTA/B/C/D from PMC */ +#define ZX4500_CPLD_SYSCTL_BCM 0x04 /* Enable INTA from BCM */ +#define ZX4500_CPLD_SYSCTL_SINTA 0x08 /* Enable SINTA from 21554 */ +#define ZX4500_CPLD_SYSCTL_WD 0x20 /* Enable Watchdog Timer */ +#define ZX4500_CPLD_SYSCTL_PMC_TRI 0x80 /* Tri-state PMC EREADY */ + +#define ZX4500_CPLD_DUAL2_LED_PULL 0x01 /* Pull LED */ +#define ZX4500_CPLD_DUAL2_LED_EXT_FAULT 0x02 /* External Fault LED */ +#define ZX4500_CPLD_DUAL2_LED_INT_FAULT 0x04 /* Internal Fault LED */ +#define ZX4500_CPLD_DUAL2_LED_OK 0x08 /* OK LED */ +#define ZX4500_CPLD_DUAL2_LED_CLK 0x10 /* CLK LED */ + +/* + * Defines related to boot string stored in flash. + */ +#define ZX4500_BOOT_STRING_ADDR 0xfff7f000 +#define ZX4500_BOOT_STRING_LEN 80 + +/* + * Define the IDSEL that the PCI bus side of the 8240 is connected to. + * This IDSEL must not be selected from the 8240 processor side. + */ +#define ZX4500_HOST_BRIDGE_IDSEL 20 + + +void zx4500_find_bridges(void); + +#endif /* __PPC_PLATFORMS_ZX4500_H_ */ diff --git a/arch/ppc/platforms/zx4500_pci.c b/arch/ppc/platforms/zx4500_pci.c new file mode 100644 index 000000000000..cf41eba60893 --- /dev/null +++ b/arch/ppc/platforms/zx4500_pci.c @@ -0,0 +1,140 @@ +/* + * arch/ppc/platforms/zx4500_pci.c + * + * PCI setup routines for Znyx ZX4500 cPCI boards. + * + * Author: Mark A. Greer + * mgreer@mvista.com + * + * Copyright 2000, 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/pci.h> +#include <linux/slab.h> + +#include <asm/byteorder.h> +#include <asm/io.h> +#include <asm/uaccess.h> +#include <asm/machdep.h> +#include <asm/mpc10x.h> +#include <asm/pci-bridge.h> + +#include "zx4500.h" + +/* + * Znyx ZX4500 interrupt routes. + */ +static inline int +zx4500_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) +{ + static char pci_irq_table[][4] = + /* + * PCI IDSEL/INTPIN->INTLINE + * A B C D + */ + { + { 19, 0, 0, 0 }, /* IDSEL 21 - 21554 PCI-cPCI bridge */ + { 18, 0, 0, 0 }, /* IDSEL 22 - BCM5600 INTA */ + { 16, 20, 16, 20 }, /* IDSEL 23 - PPMC Slot */ + }; + + const long min_idsel = 21, max_idsel = 23, irqs_per_slot = 4; + return PCI_IRQ_TABLE_LOOKUP; +} + +void __init +zx4500_board_init(struct pci_controller *hose) +{ + uint val; + u_char sysctl; + + /* + * CPLD Registers are mapped in by BAT 3 in zx4500_setup_arch(). + * + * Turn off all interrupts routed through the CPLD. + * Also, turn off watchdog timer and drive PMC EREADY low. + */ + sysctl = in_8((volatile u_char *)ZX4500_CPLD_SYSCTL); + sysctl &= ~(ZX4500_CPLD_SYSCTL_PMC | + ZX4500_CPLD_SYSCTL_BCM | + ZX4500_CPLD_SYSCTL_SINTA | + ZX4500_CPLD_SYSCTL_WD | + ZX4500_CPLD_SYSCTL_PMC_TRI); + out_8((volatile u_char *)ZX4500_CPLD_SYSCTL, sysctl); + + /* + * Kludge the size that BAR2 of the 21554 asks for + * (i.e., set Upstream I/O or Memory 0 Setup Register). + * Old versions of SROM wants 1 GB which is too large, make it ask + * for 256 MB. + */ + early_read_config_dword(hose, 0, PCI_DEVFN(21,0), 0xc4, &val); + + if (val != 0) { + early_write_config_dword(hose, + 0, + PCI_DEVFN(21,0), + 0xc4, + val | 0xf0000000); + } + + return; +} + +static int +zx4500_exclude_device(u_char bus, u_char devfn) +{ + if ((bus == 0) && (PCI_SLOT(devfn) == ZX4500_HOST_BRIDGE_IDSEL)) { + return PCIBIOS_DEVICE_NOT_FOUND; + } + else { + return PCIBIOS_SUCCESSFUL; + } +} + +void __init +zx4500_find_bridges(void) +{ + struct pci_controller *hose; + + hose = pcibios_alloc_controller(); + + if (!hose) + return; + + hose->first_busno = 0; + hose->last_busno = 0xff; + + if (mpc10x_bridge_init(hose, + MPC10X_MEM_MAP_B, + MPC10X_MEM_MAP_B, + MPC10X_MAPB_EUMB_BASE) == 0) { + + hose->mem_resources[0].end = 0xffffffff; + + /* Initialize the board */ + zx4500_board_init(hose); + + /* scan PCI bus */ + ppc_md.pci_exclude_device = zx4500_exclude_device; + hose->last_busno = pciauto_bus_scan(hose, hose->first_busno); + + ppc_md.pcibios_fixup = NULL; + ppc_md.pcibios_fixup_bus = NULL; + ppc_md.pci_swizzle = common_swizzle; + ppc_md.pci_map_irq = zx4500_map_irq; + } + else { + if (ppc_md.progress) + ppc_md.progress("Bridge init failed", 0x100); + printk("Host bridge init failed\n"); + } + + return; +} diff --git a/arch/ppc/platforms/zx4500_serial.h b/arch/ppc/platforms/zx4500_serial.h new file mode 100644 index 000000000000..58c8cf29613b --- /dev/null +++ b/arch/ppc/platforms/zx4500_serial.h @@ -0,0 +1,48 @@ +/* + * include/asm-ppc/zx4500_serial.h + * + * Definitions for Znyx ZX4500 board support + * + * Author: Mark A. Greer + * mgreer@mvista.com + * + * Copyright 2000, 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#ifndef __ASMPPC_ZX4500_SERIAL_H +#define __ASMPPC_ZX4500_SERIAL_H + +#include <linux/config.h> + +/* Define the UART base address (only 1 UART) */ +#define ZX4500_SERIAL_1 0xff880000 + +#ifdef CONFIG_SERIAL_MANY_PORTS +#define RS_TABLE_SIZE 64 +#else +#define RS_TABLE_SIZE 1 +#endif + +/* Rate for the 1.8432 Mhz clock for the onboard serial chip */ +#define BASE_BAUD ( 1843200 / 16 ) + +#ifdef CONFIG_SERIAL_DETECT_IRQ +#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF|ASYNC_SKIP_TEST|ASYNC_AUTO_IRQ) +#else +#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF|ASYNC_SKIP_TEST) +#endif + +#define STD_SERIAL_PORT_DFNS \ + { 0, BASE_BAUD, ZX4500_SERIAL_1, 17, STD_COM_FLAGS, /* ttyS0 */ \ + iomem_base: (u8 *)ZX4500_SERIAL_1, \ + io_type: SERIAL_IO_MEM }, + +#define SERIAL_PORT_DFNS \ + STD_SERIAL_PORT_DFNS + +#endif /* __ASMPPC_ZX4500_SERIAL_H */ diff --git a/arch/ppc/platforms/zx4500_setup.c b/arch/ppc/platforms/zx4500_setup.c new file mode 100644 index 000000000000..cf5ea1249e9d --- /dev/null +++ b/arch/ppc/platforms/zx4500_setup.c @@ -0,0 +1,360 @@ +/* + * arch/ppc/platforms/zx4500_setup.c + * + * Board setup routines for Znyx ZX4500 family of cPCI boards. + * + * Author: Mark A. Greer + * mgreer@mvista.com + * + * Copyright 2000, 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +/* + * This file adds support for the Znyx ZX4500 series of cPCI boards. + * These boards have an 8240, UART on the processor bus, a PPMC slot (for now + * the card in this slot can _not_ be a monarch), Broadcom BCM5600, and an + * Intel 21554 bridge. + * + * Currently, this port assumes that the 8240 is the master and performs PCI + * arbitration, etc. It is also assumed that the 8240 is wired to come up + * using memory MAP B (CHRP map). + * + * Note: This board port will not work properly as it is. You must apply the + * patch that is at ftp://ftp.mvista.com/pub/Area51/zx4500/zx_patch_2_5 + */ +#include <linux/config.h> +#include <linux/stddef.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/errno.h> +#include <linux/reboot.h> +#include <linux/pci.h> +#include <linux/kdev_t.h> +#include <linux/types.h> +#include <linux/major.h> +#include <linux/blk.h> +#include <linux/console.h> +#include <linux/delay.h> +#include <linux/irq.h> +#include <linux/seq_file.h> + +#include <asm/system.h> +#include <asm/pgtable.h> +#include <asm/page.h> +#include <asm/dma.h> +#include <asm/io.h> +#include <asm/machdep.h> +#include <asm/prom.h> +#include <asm/time.h> +#include <asm/open_pic.h> +#include <asm/mpc10x.h> +#include <asm/pci-bridge.h> +#include <asm/bootinfo.h> + +#include "zx4500.h" + +static u_char zx4500_openpic_initsenses[] __initdata = { + 0, /* 0-15 are not used on an 8240 EPIC */ + 0, /* 1 */ + 0, /* 2 */ + 0, /* 3 */ + 0, /* 4 */ + 0, /* 5 */ + 0, /* 6 */ + 0, /* 7 */ + 0, /* 8 */ + 0, /* 9 */ + 0, /* 10 */ + 0, /* 11 */ + 0, /* 12 */ + 0, /* 13 */ + 0, /* 14 */ + 0, /* 15 */ + 1, /* 16: EPIC IRQ 0: Active Low -- PMC #INTA & #INTC */ + 1, /* 17: EPIC IRQ 1: Active Low -- UART */ + 1, /* 18: EPIC IRQ 2: Active Low -- BCM5600 #INTA */ + 1, /* 19: EPIC IRQ 3: Active Low -- 21554 #SINTA */ + 1, /* 20: EPIC IRQ 4: Active Low -- PMC #INTB & #INTD */ +}; + + +static void __init +zx4500_setup_arch(void) +{ + char boot_string[ZX4500_BOOT_STRING_LEN + 1]; + char *boot_arg; + extern char cmd_line[]; + + + loops_per_jiffy = 50000000 / HZ; + +#ifdef CONFIG_BLK_DEV_INITRD + if (initrd_start) + ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); + else +#endif +#if defined(CONFIG_ROOT_NFS) + ROOT_DEV = to_kdev_t(0x00FF); /* /dev/nfs pseudo device */ +#else + ROOT_DEV = to_kdev_t(0x0801); /* /dev/sda1 SCSI disk */ +#endif + + /* Get boot string from flash */ + strncpy(boot_string, + (char *)ZX4500_BOOT_STRING_ADDR, + ZX4500_BOOT_STRING_LEN); + boot_string[ZX4500_BOOT_STRING_LEN] = '\0'; + + /* Can be delimited by 0xff */ + boot_arg = strchr(boot_string, 0xff); + + if (boot_arg != NULL) { + *boot_arg = '\0'; + } + + /* First 3 chars must be 'dev'. If not, ignore. */ + if (!strncmp(boot_string, "dev", 3)) { + /* skip 'dev?' and any blanks after it */ + boot_arg = strchr(boot_string, ' '); + + if (boot_arg != NULL) { + while (*boot_arg == ' ') boot_arg++; + strcat(cmd_line, " "); + strcat(cmd_line, boot_arg); + } + } + + /* nothing but serial consoles... */ + printk("Znyx ZX4500 Series High Performance Switch\n"); + printk("ZX4500 port (C) 2000, 2001 MontaVista Software, Inc. (source@mvista.com)\n"); + + /* Lookup PCI host bridge */ + zx4500_find_bridges(); + + printk("ZX4500 Board ID: 0x%x, Revision #: 0x%x\n", + in_8((volatile u_char *)ZX4500_CPLD_BOARD_ID), + in_8((volatile u_char *)ZX4500_CPLD_REV)); + + return; +} + +static ulong __init +zx4500_find_end_of_memory(void) +{ + return mpc10x_get_mem_size(MPC10X_MEM_MAP_B); +} + +static void __init +zx4500_map_io(void) +{ + io_block_mapping(0xfe000000, 0xfe000000, 0x02000000, _PAGE_IO); +} + +/* + * Enable interrupts routed thru CPLD to reach the 8240's EPIC. + * Need to enable all 4 PMC intrs, BCM INTA, and 21554 SINTA to 8240. + * UART intrs routed directly to 8240 (not thru CPLD). + */ +static void __init +zx4500_enable_cpld_intrs(void) +{ + u_char sysctl; + + sysctl = in_8((volatile u_char *)ZX4500_CPLD_SYSCTL); + sysctl |= (ZX4500_CPLD_SYSCTL_PMC | + ZX4500_CPLD_SYSCTL_BCM | + ZX4500_CPLD_SYSCTL_SINTA); + out_8((volatile u_char *)ZX4500_CPLD_SYSCTL, sysctl); + + return; +} + +static void __init +zx4500_init_IRQ(void) +{ + OpenPIC_InitSenses = zx4500_openpic_initsenses; + OpenPIC_NumInitSenses = sizeof(zx4500_openpic_initsenses); + + openpic_init(1, 0, NULL, -1); + + zx4500_enable_cpld_intrs(); /* Allow CPLD to route intrs to 8240 */ + + return; +} + +static void +zx4500_restart(char *cmd) +{ + __cli(); + + out_8((volatile u_char *)ZX4500_CPLD_RESET, ZX4500_CPLD_RESET_XBUS); + for (;;); + + panic("Restart failed.\n"); + /* NOTREACHED */ +} + +static void +zx4500_power_off(void) +{ + __cli(); + for(;;); /* No way to shut power off with software */ + /* NOTREACHED */ +} + +static void +zx4500_halt(void) +{ + zx4500_power_off(); + /* NOTREACHED */ +} + +static int +zx4500_get_bus_speed(void) +{ + int bus_speed; + + bus_speed = 100000000; + + return bus_speed; +} + +static int +zx4500_show_cpuinfo(struct seq_file *m) +{ + uint pvid; + + seq_printf(m, "vendor\t\t: Znyx\n"); + seq_printf(m, "machine\t\t: ZX4500\n"); + seq_printf(m, "processor\t: PVID: 0x%x, vendor: %s\n", + pvid, (pvid & (1<<15) ? "IBM" : "Motorola")); + seq_printf(m, "bus speed\t: %dMhz\n", + zx4500_get_bus_speed()/1000000); + + return 0; +} + +static void __init +zx4500_calibrate_decr(void) +{ + ulong freq; + + freq = zx4500_get_bus_speed() / 4; + + printk("time_init: decrementer frequency = %lu.%.6lu MHz\n", + freq/1000000, freq%1000000); + + tb_ticks_per_jiffy = freq / HZ; + tb_to_us = mulhwu_scale_factor(freq, 1000000); + + return; +} + +/* + * Set BAT 3 to map 0xf0000000 to end of physical memory space 1-1. + */ +static __inline__ void +zx4500_set_bat(void) +{ + unsigned long bat3u, bat3l; + static int mapping_set = 0; + + if (!mapping_set) { + + __asm__ __volatile__( + " lis %0,0xf800\n \ + ori %1,%0,0x002a\n \ + ori %0,%0,0x0ffe\n \ + mtspr 0x21e,%0\n \ + mtspr 0x21f,%1\n \ + isync\n \ + sync " + : "=r" (bat3u), "=r" (bat3l)); + + mapping_set = 1; + } + + return; +} + +#ifdef CONFIG_SERIAL_TEXT_DEBUG +#include <linux/serialP.h> +#include <linux/serial_reg.h> +#include <asm/serial.h> + +static struct serial_state rs_table[RS_TABLE_SIZE] = { + SERIAL_PORT_DFNS /* Defined in <asm/serial.h> */ +}; + +void +zx4500_progress(char *s, unsigned short hex) +{ + volatile char c; + volatile unsigned long com_port; + u16 shift; + + com_port = rs_table[0].port; + shift = rs_table[0].iomem_reg_shift; + + while ((c = *s++) != 0) { + while ((*((volatile unsigned char *)com_port + + (UART_LSR << shift)) & UART_LSR_THRE) == 0) + ; + *(volatile unsigned char *)com_port = c; + + if (c == '\n') { + while ((*((volatile unsigned char *)com_port + + (UART_LSR << shift)) & UART_LSR_THRE) == 0) + ; + *(volatile unsigned char *)com_port = '\r'; + } + } +} +#endif /* CONFIG_SERIAL_TEXT_DEBUG */ + +void __init +platform_init(unsigned long r3, unsigned long r4, unsigned long r5, + unsigned long r6, unsigned long r7) +{ + parse_bootinfo(find_bootinfo()); + + /* Map in board registers, etc. */ + zx4500_set_bat(); + + isa_io_base = MPC10X_MAPB_ISA_IO_BASE; + isa_mem_base = MPC10X_MAPB_ISA_MEM_BASE; + pci_dram_offset = MPC10X_MAPB_DRAM_OFFSET; + + ppc_md.setup_arch = zx4500_setup_arch; + ppc_md.show_cpuinfo = zx4500_show_cpuinfo; + ppc_md.irq_cannonicalize = NULL; + ppc_md.init_IRQ = zx4500_init_IRQ; + ppc_md.get_irq = openpic_get_irq; + ppc_md.init = NULL; + + ppc_md.restart = zx4500_restart; + ppc_md.power_off = zx4500_power_off; + ppc_md.halt = zx4500_halt; + + ppc_md.find_end_of_memory = zx4500_find_end_of_memory; + ppc_md.setup_io_mappings = zx4500_map_io; + + ppc_md.calibrate_decr = zx4500_calibrate_decr; + + ppc_md.heartbeat = NULL; + ppc_md.heartbeat_reset = 0; + ppc_md.heartbeat_count = 0; + +#ifdef CONFIG_SERIAL_TEXT_DEBUG + ppc_md.progress = zx4500_progress; +#else /* !CONFIG_SERIAL_TEXT_DEBUG */ + ppc_md.progress = NULL; +#endif /* CONFIG_SERIAL_TEXT_DEBUG */ + + return; +} diff --git a/arch/ppc/vmlinux.lds b/arch/ppc/vmlinux.lds index 3549b03f49fb..020569560a27 100644 --- a/arch/ppc/vmlinux.lds +++ b/arch/ppc/vmlinux.lds @@ -33,6 +33,9 @@ SECTIONS *(.text) *(.fixup) *(.got1) + __got2_start = .; + *(.got2) + __got2_end = .; } _etext = .; PROVIDE (etext = .); diff --git a/arch/ppc/xmon/nonstdio.h b/arch/ppc/xmon/nonstdio.h index fade4a399a70..ec088e54813c 100644 --- a/arch/ppc/xmon/nonstdio.h +++ b/arch/ppc/xmon/nonstdio.h @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.nonstdio.h 1.5 05/17/01 18:14:23 cort + * BK Id: %F% %I% %G% %U% %#% */ typedef int FILE; extern FILE *xmon_stdin, *xmon_stdout; @@ -21,5 +21,6 @@ extern char *fgets(char *, int, void *); extern void xmon_printf(const char *, ...); extern void xmon_fprintf(void *, const char *, ...); extern void xmon_sprintf(char *, const char *, ...); +extern void xmon_puts(char*); #define perror(s) printf("%s: no files!\n", (s)) diff --git a/arch/ppc/xmon/start.c b/arch/ppc/xmon/start.c index fe2abb190c31..808f3a88d301 100644 --- a/arch/ppc/xmon/start.c +++ b/arch/ppc/xmon/start.c @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.start.c 1.16 08/20/01 22:17:58 paulus + * BK Id: %F% %I% %G% %U% %#% */ /* * Copyright (C) 1996 Paul Mackerras. @@ -13,9 +13,13 @@ #include <linux/pmu.h> #include <linux/cuda.h> #include <linux/kernel.h> +#include <linux/errno.h> +#include <linux/sysrq.h> #include <asm/prom.h> #include <asm/bootx.h> -#include <asm/feature.h> +#include <asm/machdep.h> +#include <asm/errno.h> +#include <asm/pmac_feature.h> #include <asm/processor.h> #include <asm/delay.h> #include <asm/btext.h> @@ -24,15 +28,14 @@ #endif static volatile unsigned char *sccc, *sccd; -unsigned long TXRDY, RXRDY; +unsigned int TXRDY, RXRDY, DLAB; extern void xmon_printf(const char *fmt, ...); static int xmon_expect(const char *str, unsigned int timeout); -static int console; static int use_screen; static int via_modem; static int xmon_use_sccb; -static struct device_node *macio_node; +static struct device_node *channel_node; #define TB_SPEED 25000000 @@ -46,12 +49,65 @@ static inline unsigned int readtb(void) void buf_access(void) { - if ( _machine == _MACH_chrp ) - sccd[3] &= ~0x80; /* reset DLAB */ + if (DLAB) + sccd[3] &= ~DLAB; /* reset DLAB */ } extern int adb_init(void); +#ifdef CONFIG_ALL_PPC +/* + * This looks in the "ranges" property for the primary PCI host bridge + * to find the physical address of the start of PCI/ISA I/O space. + * It is basically a cut-down version of pci_process_bridge_OF_ranges. + */ +static unsigned long chrp_find_phys_io_base(void) +{ + struct device_node *node; + unsigned int *ranges; + unsigned long base = CHRP_ISA_IO_BASE; + int rlen = 0; + int np; + + node = find_devices("isa"); + if (node != NULL) { + node = node->parent; + if (node == NULL || node->type == NULL + || strcmp(node->type, "pci") != 0) + node = NULL; + } + if (node == NULL) + node = find_devices("pci"); + if (node == NULL) + return base; + + ranges = (unsigned int *) get_property(node, "ranges", &rlen); + np = prom_n_addr_cells(node) + 5; + while ((rlen -= np * sizeof(unsigned int)) >= 0) { + if ((ranges[0] >> 24) == 1 && ranges[2] == 0) { + /* I/O space starting at 0, grab the phys base */ + base = ranges[np - 3]; + break; + } + ranges += np; + } + return base; +} +#endif /* CONFIG_ALL_PPC */ + +static void sysrq_handle_xmon(int key, struct pt_regs *regs, + struct kbd_struct *kbd, struct tty_struct *tty) +{ + xmon(regs); +} + +static struct sysrq_key_op sysrq_xmon_op = +{ + handler: sysrq_handle_xmon, + help_msg: "Xmon", + action_msg: "Entering xmon\n", +}; + void xmon_map_scc(void) { @@ -65,8 +121,6 @@ xmon_map_scc(void) unsigned long addr; #ifdef CONFIG_BOOTX_TEXT if (!machine_is_compatible("iMac")) { - extern boot_infos_t *disp_bi; - /* see if there is a keyboard in the device tree with a parent of type "adb" */ for (np = find_devices("keyboard"); np; np = np->next) @@ -77,11 +131,11 @@ xmon_map_scc(void) /* needs to be hacked if xmon_printk is to be used from within find_via_pmu() */ #ifdef CONFIG_ADB_PMU - if (np != NULL && disp_bi && find_via_pmu()) + if (np != NULL && boot_text_mapped && find_via_pmu()) use_screen = 1; #endif #ifdef CONFIG_ADB_CUDA - if (np != NULL && disp_bi && find_via_cuda()) + if (np != NULL && boot_text_mapped && find_via_cuda()) use_screen = 1; #endif } @@ -99,6 +153,7 @@ xmon_map_scc(void) np = np->sibling; if (np != NULL) { /* XXX should parse this properly */ + channel_node = np; slots = get_property(np, "slot-names", &l); if (slots != NULL && l >= 10 && strcmp(slots+4, "Modem") == 0) @@ -126,25 +181,27 @@ xmon_map_scc(void) RXRDY = 1; np = find_devices("mac-io"); - if (np && np->n_addrs) { - macio_node = np; + if (np && np->n_addrs) addr = np->addrs[0].address + 0x13020; - } base = (volatile unsigned char *) ioremap(addr & PAGE_MASK, PAGE_SIZE); sccc = base + (addr & ~PAGE_MASK); sccd = sccc + 0x10; - } - else - { - /* should already be mapped by the kernel boot */ - sccc = (volatile unsigned char *) (isa_io_base + 0x3fd); - sccd = (volatile unsigned char *) (isa_io_base + 0x3f8); + + } else { + base = (volatile unsigned char *) isa_io_base; + if (_machine == _MACH_chrp) + base = (volatile unsigned char *) + ioremap(chrp_find_phys_io_base(), 0x1000); + + sccc = base + 0x3fd; + sccd = base + 0x3f8; if (xmon_use_sccb) { sccc -= 0x100; sccd -= 0x100; } TXRDY = 0x20; RXRDY = 1; + DLAB = 0x80; } #elif defined(CONFIG_GEMINI) /* should already be mapped by the kernel boot */ @@ -152,8 +209,16 @@ xmon_map_scc(void) sccd = (volatile unsigned char *) 0xffeffb08; TXRDY = 0x20; RXRDY = 1; - console = 1; + DLAB = 0x80; +#elif defined(CONFIG_405GP) + sccc = (volatile unsigned char *)0xef600305; + sccd = (volatile unsigned char *)0xef600300; + TXRDY = 0x20; + RXRDY = 1; + DLAB = 0x80; #endif /* platform */ + + __sysrq_put_key_op('x', &sysrq_xmon_op); } static int scc_initialized = 0; @@ -210,8 +275,6 @@ xmon_write(void *handle, void *ptr, int nb) ct = 1; --i; } else { - if (console) - printk("%c", c); ct = 0; } buf_access(); @@ -349,12 +412,19 @@ xmon_init_scc() { int i, x; - if (macio_node != 0) - feature_set(macio_node, FEATURE_Serial_enable); - if (via_modem && macio_node != 0) { + if (channel_node != 0) + pmac_call_feature( + PMAC_FTR_SCC_ENABLE, + channel_node, + PMAC_SCC_ASYNC | PMAC_SCC_FLAG_XMON, 1); + printk(KERN_INFO "Serial port locked ON by debugger !\n"); + if (via_modem && channel_node != 0) { unsigned int t0; - feature_set(macio_node, FEATURE_Modem_power); + pmac_call_feature( + PMAC_FTR_MODEM_ENABLE, + channel_node, 0, 1); + printk(KERN_INFO "Modem powered up by debugger !\n"); t0 = readtb(); while (readtb() - t0 < 3*TB_SPEED) eieio(); diff --git a/arch/ppc/xmon/subr_prf.c b/arch/ppc/xmon/subr_prf.c index 6de1f3caf528..2480ca85ee38 100644 --- a/arch/ppc/xmon/subr_prf.c +++ b/arch/ppc/xmon/subr_prf.c @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.subr_prf.c 1.5 05/17/01 18:14:23 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * Written by Cort Dougan to replace the version originally used @@ -51,3 +51,8 @@ xmon_fprintf(void *f, const char *fmt, ...) va_end(ap); } +void +xmon_puts(char *s) +{ + xmon_write(stdout, s, strlen(s)); +} diff --git a/arch/ppc/xmon/xmon.c b/arch/ppc/xmon/xmon.c index 3694c85ce8f0..891de6d8e4fc 100644 --- a/arch/ppc/xmon/xmon.c +++ b/arch/ppc/xmon/xmon.c @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.xmon.c 1.16 09/22/01 15:25:10 trini + * BK Id: %F% %I% %G% %U% %#% */ /* * Routines providing a simple monitor for use on the PowerMac. @@ -14,6 +14,10 @@ #include <asm/string.h> #include <asm/prom.h> #include <asm/bitops.h> +#include <asm/bootx.h> +#ifdef CONFIG_PMAC_BACKLIGHT +#include <asm/backlight.h> +#endif #include "nonstdio.h" #include "privinst.h" @@ -90,6 +94,7 @@ static unsigned read_spr(int); static void write_spr(int, unsigned); static void super_regs(void); static void print_sysmap(void); +static void sysmap_lookup(void); static void remove_bpts(void); static void insert_bpts(void); static struct bpt *at_breakpoint(unsigned pc); @@ -98,10 +103,7 @@ static void cacheflush(void); #ifdef CONFIG_SMP static void cpu_cmd(void); #endif /* CONFIG_SMP */ -#if 0 /* Makes compile with -Wall */ -static char *pretty_print_addr(unsigned long addr); -static char *lookup_name(unsigned long addr); -#endif +static int pretty_print_addr(unsigned long addr); static void csum(void); extern int print_insn_big_powerpc(FILE *, unsigned long, unsigned); @@ -112,6 +114,8 @@ extern void longjmp(u_int *, int); extern void xmon_enter(void); extern void xmon_leave(void); +extern char* xmon_find_symbol(unsigned long addr, unsigned long* saddr); +extern unsigned long xmon_symbol_to_addr(char* symbol); #define GETWORD(v) (((v)[0] << 24) + ((v)[1] << 16) + ((v)[2] << 8) + (v)[3]) @@ -121,6 +125,7 @@ extern void xmon_leave(void); #define isalnum(c) (('0' <= (c) && (c) <= '9') \ || ('a' <= (c) && (c) <= 'z') \ || ('A' <= (c) && (c) <= 'Z')) +#define isspace(c) (c == ' ' || c == '\t' || c == 10 || c == 13 || c == 0) static char *help_string = "\ Commands:\n\ @@ -138,6 +143,8 @@ Commands:\n\ r print registers\n\ S print special registers\n\ t print backtrace\n\ + la lookup address in system.map\n\ + ls lookup symbol in system.map\n\ x exit monitor\n\ "; @@ -147,6 +154,19 @@ static int xmon_trace[NR_CPUS]; static struct pt_regs *xmon_regs[NR_CPUS]; +extern inline void sync(void) +{ + asm volatile("sync; isync"); +} + +extern inline void __delay(unsigned int loops) +{ + if (loops != 0) + __asm__ __volatile__("mtctr %0; 1: bdnz 1b" : : + "r" (loops) : "ctr"); +} + + void xmon(struct pt_regs *excp) { @@ -187,6 +207,16 @@ xmon(struct pt_regs *excp) */ #endif /* CONFIG_SMP */ remove_bpts(); +#ifdef CONFIG_PMAC_BACKLIGHT + if( setjmp(bus_error_jmp) == 0 ) { + debugger_fault_handler = handle_fault; + sync(); + set_backlight_enable(1); + set_backlight_level(BACKLIGHT_MAX); + sync(); + } + debugger_fault_handler = 0; +#endif /* CONFIG_PMAC_BACKLIGHT */ cmd = cmds(excp); if (cmd == 's') { xmon_trace[smp_processor_id()] = SSTEP; @@ -318,7 +348,7 @@ insert_bpts() } store_inst((void *) bp->address); } -#if !defined(CONFIG_8xx) && !defined(CONFIG_POWER4) +#if !defined(CONFIG_8xx) if (dabr.enabled) set_dabr(dabr.address); if (iabr.enabled) @@ -333,7 +363,7 @@ remove_bpts() struct bpt *bp; unsigned instr; -#if !defined(CONFIG_8xx) && !defined(CONFIG_POWER4) +#if !defined(CONFIG_8xx) set_dabr(0); set_iabr(0); #endif @@ -398,6 +428,9 @@ cmds(struct pt_regs *excp) case 'd': dump(); break; + case 'l': + sysmap_lookup(); + break; case 'r': if (excp != NULL) prregs(excp); /* print regs */ @@ -464,8 +497,8 @@ static void cpu_cmd(void) if (cmd == 'i') { /* interrupt other cpu(s) */ cpu = MSG_ALL_BUT_SELF; - scanhex(&cpu); - smp_send_xmon_break(cpu); + if (scanhex(&cpu)) + smp_send_xmon_break(cpu); return; } termch = cmd; @@ -547,8 +580,10 @@ csum(void) unsigned short fcs; unsigned char v; - scanhex(&adrs); - scanhex(&ncsum); + if (!scanhex(&adrs)) + return; + if (!scanhex(&ncsum)) + return; fcs = 0xffff; for (i = 0; i < ncsum; ++i) { if (mread(adrs+i, &v, 1) == 0) { @@ -570,7 +605,7 @@ bpt_cmds(void) cmd = inchar(); switch (cmd) { -#if !defined(CONFIG_8xx) && !defined(CONFIG_POWER4) +#if !defined(CONFIG_8xx) case 'd': mode = 7; cmd = inchar(); @@ -580,6 +615,11 @@ bpt_cmds(void) mode = 6; else termch = cmd; + cmd = inchar(); + if (cmd == 'p') + mode &= ~4; + else + termch = cmd; dabr.address = 0; dabr.count = 0; dabr.enabled = scanhex(&dabr.address); @@ -588,11 +628,16 @@ bpt_cmds(void) dabr.address = (dabr.address & ~7) | mode; break; case 'i': + cmd = inchar(); + if (cmd == 'p') + mode = 2; + else + mode = 3; iabr.address = 0; iabr.count = 0; iabr.enabled = scanhex(&iabr.address); if (iabr.enabled) - iabr.address |= 3; + iabr.address |= mode; scanhex(&iabr.count); break; #endif @@ -625,6 +670,8 @@ bpt_cmds(void) printf("r"); if (dabr.address & 2) printf("w"); + if (dabr.address & 4) + printf("p"); printf("]\n"); } if (iabr.enabled) @@ -661,7 +708,7 @@ backtrace(struct pt_regs *excp) unsigned stack[2]; struct pt_regs regs; extern char ret_from_intercept, ret_from_syscall_1, ret_from_syscall_2; - extern char do_signal_ret, ret_from_except; + extern char ret_from_except; printf("backtrace:\n"); @@ -674,12 +721,12 @@ backtrace(struct pt_regs *excp) for (; sp != 0; sp = stack[0]) { if (mread(sp, stack, sizeof(stack)) != sizeof(stack)) break; - printf("%x ", stack[1]); + pretty_print_addr(stack[1]); + printf(" "); if (stack[1] == (unsigned) &ret_from_intercept || stack[1] == (unsigned) &ret_from_except || stack[1] == (unsigned) &ret_from_syscall_1 - || stack[1] == (unsigned) &ret_from_syscall_2 - || stack[1] == (unsigned) &do_signal_ret) { + || stack[1] == (unsigned) &ret_from_syscall_2) { if (mread(sp+16, ®s, sizeof(regs)) != sizeof(regs)) break; printf("\nexception:%x [%x] %x ", regs.trap, sp+16, @@ -688,8 +735,8 @@ backtrace(struct pt_regs *excp) if (mread(sp, stack, sizeof(stack)) != sizeof(stack)) break; } + printf("\n"); } - printf("\n"); } int @@ -707,10 +754,11 @@ excprint(struct pt_regs *fp) #ifdef CONFIG_SMP printf("cpu %d: ", smp_processor_id()); #endif /* CONFIG_SMP */ - printf("vector: %x at pc = %x", - fp->trap, fp->nip); - printf(", lr = %x, msr = %x, sp = %x [%x]\n", - fp->link, fp->msr, fp->gpr[1], fp); + printf("vector: %x at pc = ", fp->trap); + pretty_print_addr(fp->nip); + printf(", lr = "); + pretty_print_addr(fp->link); + printf("\nmsr = %x, sp = %x [%x]\n", fp->msr, fp->gpr[1], fp); if (fp->trap == 0x300 || fp->trap == 0x600) printf("dar = %x, dsisr = %x\n", fp->dar, fp->dsisr); if (current) @@ -795,8 +843,16 @@ void print_sysmap(void) { extern char *sysmap; - if ( sysmap ) - printf("System.map: \n%s", sysmap); + if ( sysmap ) { + printf("System.map: \n"); + if( setjmp(bus_error_jmp) == 0 ) { + debugger_fault_handler = handle_fault; + sync(); + xmon_puts(sysmap); + sync(); + } + debugger_fault_handler = 0; + } else printf("No System.map\n"); } @@ -878,6 +934,14 @@ openforth() } #endif +#ifndef CONFIG_PPC_STD_MMU +static void +dump_hash_table() +{ + printf("This CPU doesn't have a hash table.\n"); +} +#else + #ifndef CONFIG_PPC64BRIDGE static void dump_hash_table_seg(unsigned seg, unsigned start, unsigned end) @@ -1024,21 +1088,11 @@ dump_hash_table() seg_start = seg_end + 0x1000; } } +#endif /* CONFIG_PPC_STD_MMU */ /* * Stuff for reading and writing memory safely */ -extern inline void sync(void) -{ - asm volatile("sync; isync"); -} - -extern inline void __delay(unsigned int loops) -{ - if (loops != 0) - __asm__ __volatile__("mtctr %0; 1: bdnz 1b" : : - "r" (loops) : "ctr"); -} int mread(unsigned adrs, void *buf, int size) @@ -1565,6 +1619,24 @@ unsigned *vp; } printf("invalid register name '%%%s'\n", regname); return 0; + } else if (c == '$') { + static char symname[64]; + int i; + for (i=0; i<63; i++) { + c = inchar(); + if (isspace(c)) { + termch = c; + break; + } + symname[i] = c; + } + symname[i++] = 0; + *vp = xmon_symbol_to_addr(symname); + if (!(*vp)) { + printf("unknown symbol\n"); + return 0; + } + return 1; } d = hexdigit(c); @@ -1652,38 +1724,169 @@ char *str; lineptr = str; } -#if 0 /* Makes compile with -Wall */ -static char *pretty_print_addr(unsigned long addr) +void +sysmap_lookup(void) { + int type = inchar(); + unsigned addr; + static char tmp[64]; + char* cur; + + extern char *sysmap; + extern unsigned long sysmap_size; + if ( !sysmap || !sysmap_size ) + return; + + switch(type) { + case 'a': + if (scanhex(&addr)) { + pretty_print_addr(addr); + printf("\n"); + } + termch = 0; + break; + case 's': + getstring(tmp, 64); + if( setjmp(bus_error_jmp) == 0 ) { + debugger_fault_handler = handle_fault; + sync(); + cur = sysmap; + do { + cur = strstr(cur, tmp); + if (cur) { + static char res[64]; + char *p, *d; + p = cur; + while(p > sysmap && *p != 10) + p--; + if (*p == 10) p++; + d = res; + while(*p && p < (sysmap + sysmap_size) && *p != 10) + *(d++) = *(p++); + *(d++) = 0; + printf("%s\n", res); + cur++; + } + } while (cur); + sync(); + } + debugger_fault_handler = 0; + termch = 0; + break; + } +} + +static int +pretty_print_addr(unsigned long addr) +{ + char *sym; + unsigned long saddr; + printf("%08x", addr); - if ( lookup_name(addr) ) - printf(" %s", lookup_name(addr) ); - return NULL; + sym = xmon_find_symbol(addr, &saddr); + if (sym) + printf(" (%s+0x%x)", sym, addr-saddr); + return (sym != 0); } -#endif -#if 0 /* Makes compile with -Wall */ -static char *lookup_name(unsigned long addr) +char* +xmon_find_symbol(unsigned long addr, unsigned long* saddr) { + static char rbuffer[64]; + char *p, *ep, *limit; + unsigned long prev, next; + char* psym; + extern char *sysmap; extern unsigned long sysmap_size; - char *c = sysmap; - unsigned long cmp; if ( !sysmap || !sysmap_size ) return NULL; -return NULL; -#if 0 - cmp = simple_strtoul(c, &c, 8); - /* XXX crap, we don't want the whole of the rest of the map - paulus */ - strcpy( last, strsep( &c, "\n")); - while ( c < (sysmap+sysmap_size) ) - { - cmp = simple_strtoul(c, &c, 8); - if ( cmp < addr ) - break; - strcpy( last, strsep( &c, "\n")); + + prev = 0; + psym = NULL; + p = sysmap; + limit = p + sysmap_size; + if( setjmp(bus_error_jmp) == 0 ) { + debugger_fault_handler = handle_fault; + sync(); + do { + next = simple_strtoul(p, &p, 16); + if (next > addr && prev <= addr) { + if (!psym) + goto bail; + ep = rbuffer; + p = psym; + while(*p && p < limit && *p == 32) + p++; + while(*p && p < limit && *p != 10 && (ep - rbuffer) < 63) + *(ep++) = *(p++); + *(ep++) = 0; + if (saddr) + *saddr = prev; + debugger_fault_handler = 0; + return rbuffer; + } + prev = next; + psym = p; + while(*p && p < limit && *p != 10) + p++; + if (*p) p++; + } while(*p && p < limit && next); +bail: + sync(); } - return last; -#endif + debugger_fault_handler = 0; + return NULL; } -#endif + +unsigned long +xmon_symbol_to_addr(char* symbol) +{ + char *p, *cur; + char *match; + int goodness = 0; + int result = 0; + + extern char *sysmap; + extern unsigned long sysmap_size; + if ( !sysmap || !sysmap_size ) + return 0; + + if( setjmp(bus_error_jmp) == 0 ) { + debugger_fault_handler = handle_fault; + sync(); + cur = sysmap; + while(cur) { + cur = strstr(cur, symbol); + if (cur) { + int gd = 1; + + /* best match if equal, better match if + * begins with + */ + if (cur == sysmap || *(cur-1) == ' ') { + gd++; + if (cur[strlen(symbol)] == 10) + gd++; + } + if (gd > goodness) { + match = cur; + goodness = gd; + if (gd == 3) + break; + } + cur++; + } + } + if (goodness) { + p = match; + while(p > sysmap && *p != 10) + p--; + if (*p == 10) p++; + result = simple_strtoul(p, &p, 16); + } + sync(); + } + debugger_fault_handler = 0; + return result; +} diff --git a/include/asm-ppc/8xx_immap.h b/include/asm-ppc/8xx_immap.h index b0377a911d6f..731a24ffba6c 100644 --- a/include/asm-ppc/8xx_immap.h +++ b/include/asm-ppc/8xx_immap.h @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.8xx_immap.h 1.5 05/17/01 18:14:24 cort + * BK Id: %F% %I% %G% %U% %#% */ /* @@ -178,7 +178,7 @@ typedef struct cark { */ #define KAPWR_KEY ((unsigned int)0x55ccaa33) -/* LCD interface. MPC821 Only. +/* LCD interface. MPC821 and MPC823 Only. */ typedef struct lcd { ushort lcd_lcolr[16]; @@ -353,6 +353,12 @@ typedef struct fec { uint res9[0x1e]; } fec_t; +/* We need this as the fec and fb cmap use the same address space */ +union fec_lcd { + fec_t fl_un_fec; + u_char fl_un_cmap[0x200]; +}; + typedef struct comm_proc { /* General control and status registers. */ @@ -424,8 +430,12 @@ typedef struct comm_proc { /* The fast ethernet controller is not really part of the CPM, * but it resides in the address space. + * + * The colormap for the LCD controller is also located here */ - fec_t cp_fec; + union fec_lcd fl_un; +#define cp_fec fl_un.fl_un_fec +#define lcd_cmap fl_un.fl_un_cmap char res18[0x1000]; /* Dual Ported RAM follows. @@ -447,7 +457,7 @@ typedef struct immap { car8xx_t im_clkrst; /* Clocks and reset */ sitk8xx_t im_sitk; /* Sys int timer keys */ cark8xx_t im_clkrstk; /* Clocks and reset keys */ - lcd8xx_t im_lcd; /* LCD (821 only) */ + lcd8xx_t im_lcd; /* LCD (821 and 823 only) */ i2c8xx_t im_i2c; /* I2C control/status */ sdma8xx_t im_sdma; /* SDMA control/status */ cpic8xx_t im_cpic; /* CPM Interrupt Controller */ diff --git a/include/asm-ppc/amigaints.h b/include/asm-ppc/amigaints.h index 672491b10aa6..2e0077946d4c 100644 --- a/include/asm-ppc/amigaints.h +++ b/include/asm-ppc/amigaints.h @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.amigaints.h 1.5 05/17/01 18:14:24 cort + * BK Id: %F% %I% %G% %U% %#% */ /* ** amigaints.h -- Amiga Linux interrupt handling structs and prototypes @@ -110,12 +110,8 @@ #define IF_DSKBLK 0x0002 /* diskblock DMA finished */ #define IF_TBE 0x0001 /* serial transmit buffer empty interrupt */ -struct irq_server { - unsigned short count, reentrance; -}; - extern void amiga_do_irq(int irq, struct pt_regs *fp); -extern void amiga_do_irq_list(int irq, struct pt_regs *fp, struct irq_server *server); +extern void amiga_do_irq_list(int irq, struct pt_regs *fp); /* CIA interrupt control register bits */ diff --git a/include/asm-ppc/ans-lcd.h b/include/asm-ppc/ans-lcd.h new file mode 100644 index 000000000000..d795b9fd2db6 --- /dev/null +++ b/include/asm-ppc/ans-lcd.h @@ -0,0 +1,11 @@ +#ifndef _PPC_ANS_LCD_H +#define _PPC_ANS_LCD_H + +#define ANSLCD_MINOR 156 + +#define ANSLCD_CLEAR 0x01 +#define ANSLCD_SENDCTRL 0x02 +#define ANSLCD_SETSHORTDELAY 0x03 +#define ANSLCD_SETLONGDELAY 0x04 + +#endif diff --git a/include/asm-ppc/atomic.h b/include/asm-ppc/atomic.h index 2b4f9f06babe..63e194a43944 100644 --- a/include/asm-ppc/atomic.h +++ b/include/asm-ppc/atomic.h @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.atomic.h 1.15 10/28/01 10:37:22 trini + * BK Id: %F% %I% %G% %U% %#% */ /* * PowerPC atomic operations @@ -18,7 +18,6 @@ typedef struct { volatile int counter; } atomic_t; #define atomic_set(v,i) (((v)->counter) = (i)) extern void atomic_clear_mask(unsigned long mask, unsigned long *addr); -extern void atomic_set_mask(unsigned long mask, unsigned long *addr); #ifdef CONFIG_SMP #define SMP_ISYNC "\n\tisync" @@ -26,14 +25,24 @@ extern void atomic_set_mask(unsigned long mask, unsigned long *addr); #define SMP_ISYNC #endif +/* Erratum #77 on the 405 means we need a sync or dcbt before every stwcx. + * The old ATOMIC_SYNC_FIX covered some but not all of this. + */ +#ifdef CONFIG_IBM405_ERR77 +#define PPC405_ERR77(ra,rb) "dcbt " #ra "," #rb ";" +#else +#define PPC405_ERR77(ra,rb) +#endif + static __inline__ void atomic_add(int a, atomic_t *v) { int t; __asm__ __volatile__( "1: lwarx %0,0,%3 # atomic_add\n\ - add %0,%2,%0\n\ - stwcx. %0,0,%3\n\ + add %0,%2,%0\n" + PPC405_ERR77(0,%3) +" stwcx. %0,0,%3 \n\ bne- 1b" : "=&r" (t), "=m" (v->counter) : "r" (a), "r" (&v->counter), "m" (v->counter) @@ -46,8 +55,9 @@ static __inline__ int atomic_add_return(int a, atomic_t *v) __asm__ __volatile__( "1: lwarx %0,0,%2 # atomic_add_return\n\ - add %0,%1,%0\n\ - stwcx. %0,0,%2\n\ + add %0,%1,%0\n" + PPC405_ERR77(0,%2) +" stwcx. %0,0,%2 \n\ bne- 1b" SMP_ISYNC : "=&r" (t) @@ -63,8 +73,9 @@ static __inline__ void atomic_sub(int a, atomic_t *v) __asm__ __volatile__( "1: lwarx %0,0,%3 # atomic_sub\n\ - subf %0,%2,%0\n\ - stwcx. %0,0,%3\n\ + subf %0,%2,%0\n" + PPC405_ERR77(0,%3) +" stwcx. %0,0,%3 \n\ bne- 1b" : "=&r" (t), "=m" (v->counter) : "r" (a), "r" (&v->counter), "m" (v->counter) @@ -77,8 +88,9 @@ static __inline__ int atomic_sub_return(int a, atomic_t *v) __asm__ __volatile__( "1: lwarx %0,0,%2 # atomic_sub_return\n\ - subf %0,%1,%0\n\ - stwcx. %0,0,%2\n\ + subf %0,%1,%0\n" + PPC405_ERR77(0,%2) +" stwcx. %0,0,%2 \n\ bne- 1b" SMP_ISYNC : "=&r" (t) @@ -94,8 +106,9 @@ static __inline__ void atomic_inc(atomic_t *v) __asm__ __volatile__( "1: lwarx %0,0,%2 # atomic_inc\n\ - addic %0,%0,1\n\ - stwcx. %0,0,%2\n\ + addic %0,%0,1\n" + PPC405_ERR77(0,%2) +" stwcx. %0,0,%2 \n\ bne- 1b" : "=&r" (t), "=m" (v->counter) : "r" (&v->counter), "m" (v->counter) @@ -108,8 +121,9 @@ static __inline__ int atomic_inc_return(atomic_t *v) __asm__ __volatile__( "1: lwarx %0,0,%1 # atomic_inc_return\n\ - addic %0,%0,1\n\ - stwcx. %0,0,%1\n\ + addic %0,%0,1\n" + PPC405_ERR77(0,%1) +" stwcx. %0,0,%1 \n\ bne- 1b" SMP_ISYNC : "=&r" (t) @@ -125,8 +139,9 @@ static __inline__ void atomic_dec(atomic_t *v) __asm__ __volatile__( "1: lwarx %0,0,%2 # atomic_dec\n\ - addic %0,%0,-1\n\ - stwcx. %0,0,%2\n\ + addic %0,%0,-1\n" + PPC405_ERR77(0,%2)\ +" stwcx. %0,0,%2\n\ bne- 1b" : "=&r" (t), "=m" (v->counter) : "r" (&v->counter), "m" (v->counter) @@ -139,8 +154,9 @@ static __inline__ int atomic_dec_return(atomic_t *v) __asm__ __volatile__( "1: lwarx %0,0,%1 # atomic_dec_return\n\ - addic %0,%0,-1\n\ - stwcx. %0,0,%1\n\ + addic %0,%0,-1\n" + PPC405_ERR77(0,%1) +" stwcx. %0,0,%1\n\ bne- 1b" SMP_ISYNC : "=&r" (t) @@ -164,8 +180,9 @@ static __inline__ int atomic_dec_if_positive(atomic_t *v) __asm__ __volatile__( "1: lwarx %0,0,%1 # atomic_dec_if_positive\n\ addic. %0,%0,-1\n\ - blt- 2f\n\ - stwcx. %0,0,%1\n\ + blt- 2f\n" + PPC405_ERR77(0,%1) +" stwcx. %0,0,%1\n\ bne- 1b" SMP_ISYNC "\n\ diff --git a/include/asm-ppc/bitops.h b/include/asm-ppc/bitops.h index 3d93c47dd223..8dbd9c4ac057 100644 --- a/include/asm-ppc/bitops.h +++ b/include/asm-ppc/bitops.h @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.bitops.h 1.9 05/26/01 14:48:14 paulus + * BK Id: %F% %I% %G% %U% %#% */ /* * bitops.h: Bit string operations on the ppc @@ -11,6 +11,7 @@ #include <linux/config.h> #include <asm/byteorder.h> +#include <asm/atomic.h> /* * The test_and_*_bit operations are taken to imply a memory barrier @@ -36,8 +37,9 @@ static __inline__ void set_bit(int nr, volatile void * addr) __asm__ __volatile__("\n\ 1: lwarx %0,0,%3 \n\ - or %0,%0,%2 \n\ - stwcx. %0,0,%3 \n\ + or %0,%0,%2 \n" + PPC405_ERR77(0,%3) +" stwcx. %0,0,%3 \n\ bne- 1b" : "=&r" (old), "=m" (*p) : "r" (mask), "r" (p), "m" (*p) @@ -69,8 +71,9 @@ static __inline__ void clear_bit(int nr, volatile void *addr) __asm__ __volatile__("\n\ 1: lwarx %0,0,%3 \n\ - andc %0,%0,%2 \n\ - stwcx. %0,0,%3 \n\ + andc %0,%0,%2 \n" + PPC405_ERR77(0,%3) +" stwcx. %0,0,%3 \n\ bne- 1b" : "=&r" (old), "=m" (*p) : "r" (mask), "r" (p), "m" (*p) @@ -96,8 +99,9 @@ static __inline__ void change_bit(int nr, volatile void *addr) __asm__ __volatile__("\n\ 1: lwarx %0,0,%3 \n\ - xor %0,%0,%2 \n\ - stwcx. %0,0,%3 \n\ + xor %0,%0,%2 \n" + PPC405_ERR77(0,%3) +" stwcx. %0,0,%3 \n\ bne- 1b" : "=&r" (old), "=m" (*p) : "r" (mask), "r" (p), "m" (*p) @@ -126,8 +130,9 @@ static __inline__ int test_and_set_bit(int nr, volatile void *addr) __asm__ __volatile__(SMP_WMB "\n\ 1: lwarx %0,0,%4 \n\ - or %1,%0,%3 \n\ - stwcx. %1,0,%4 \n\ + or %1,%0,%3 \n" + PPC405_ERR77(0,%4) +" stwcx. %1,0,%4 \n\ bne 1b" SMP_MB : "=&r" (old), "=&r" (t), "=m" (*p) @@ -158,8 +163,9 @@ static __inline__ int test_and_clear_bit(int nr, volatile void *addr) __asm__ __volatile__(SMP_WMB "\n\ 1: lwarx %0,0,%4 \n\ - andc %1,%0,%3 \n\ - stwcx. %1,0,%4 \n\ + andc %1,%0,%3 \n" + PPC405_ERR77(0,%4) +" stwcx. %1,0,%4 \n\ bne 1b" SMP_MB : "=&r" (old), "=&r" (t), "=m" (*p) @@ -190,8 +196,9 @@ static __inline__ int test_and_change_bit(int nr, volatile void *addr) __asm__ __volatile__(SMP_WMB "\n\ 1: lwarx %0,0,%4 \n\ - xor %1,%0,%3 \n\ - stwcx. %1,0,%4 \n\ + xor %1,%0,%3 \n" + PPC405_ERR77(0,%4) +" stwcx. %1,0,%4 \n\ bne 1b" SMP_MB : "=&r" (old), "=&r" (t), "=m" (*p) @@ -239,6 +246,11 @@ static __inline__ int ffz(unsigned int x) #ifdef __KERNEL__ +static inline int __ffs(unsigned long x) +{ + return __ilog2(x & -x); +} + /* * ffs: find first bit set. This is defined the same way as * the libc and compiler builtin ffs routines, therefore diff --git a/include/asm-ppc/board.h b/include/asm-ppc/board.h deleted file mode 100644 index f10e17bf3a8a..000000000000 --- a/include/asm-ppc/board.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * BK Id: SCCS/s.board.h 1.5 05/17/01 18:14:24 cort - */ -/* - * - * Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu> - * - * Module name: board.h - * - * Description: - * A generic include file which pulls in appropriate include files - * for specific board types based on configuration settings. - * - */ - -#ifdef __KERNEL__ -#ifndef __BOARD_H__ -#define __BOARD_H__ - -#include <linux/config.h> - -#if defined(CONFIG_OAK) -#include <asm/oak.h> -#endif - -#if defined(CONFIG_WALNUT) -#include <asm/walnut.h> -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * The "residual" board information structure the boot loader passes - * into the kernel. - */ - -extern unsigned char __res[]; - - -#ifdef __cplusplus -} -#endif - -#endif /* __BOARD_H__ */ -#endif /* __KERNEL__ */ diff --git a/include/asm-ppc/bootinfo.h b/include/asm-ppc/bootinfo.h index 1eaf18c87c5c..8be46d7fd3fc 100644 --- a/include/asm-ppc/bootinfo.h +++ b/include/asm-ppc/bootinfo.h @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.bootinfo.h 1.11 08/17/01 15:23:17 paulus + * BK Id: %F% %I% %G% %U% %#% */ /* * Non-machine dependent bootinfo structure. Basic idea @@ -19,9 +19,9 @@ #else struct bi_record { - unsigned long tag; /* tag ID */ - unsigned long size; /* size of record (in bytes) */ - unsigned long data[0]; /* data */ + unsigned long tag; /* tag ID */ + unsigned long size; /* size of record (in bytes) */ + unsigned long data[0]; /* data */ }; #define BI_FIRST 0x1010 /* first record - marker */ @@ -33,6 +33,9 @@ struct bi_record { #define BI_MACHTYPE 0x1016 #define BI_MEMSIZE 0x1017 +extern struct bi_record *find_bootinfo(void); +extern void parse_bootinfo(struct bi_record *rec); + #endif /* CONFIG_APUS */ diff --git a/include/asm-ppc/btext.h b/include/asm-ppc/btext.h index efdea49d509c..7fc031e1641f 100644 --- a/include/asm-ppc/btext.h +++ b/include/asm-ppc/btext.h @@ -17,11 +17,11 @@ extern void btext_flushscreen(void); extern unsigned long disp_BAT[2]; -extern boot_infos_t *disp_bi; +extern boot_infos_t disp_bi; extern int boot_text_mapped; void btext_init(boot_infos_t *bi); -void btext_welcome(boot_infos_t* bi); +void btext_welcome(void); void btext_prepare_BAT(void); void btext_setup_display(int width, int height, int depth, int pitch, unsigned long address); diff --git a/include/asm-ppc/byteorder.h b/include/asm-ppc/byteorder.h index 1a5f6094882f..3d0b62e6d59c 100644 --- a/include/asm-ppc/byteorder.h +++ b/include/asm-ppc/byteorder.h @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.byteorder.h 1.8 10/11/01 13:02:49 trini + * BK Id: %F% %I% %G% %U% %#% */ #ifndef _PPC_BYTEORDER_H #define _PPC_BYTEORDER_H @@ -35,17 +35,11 @@ extern __inline__ void st_le32(volatile unsigned *addr, const unsigned val) __asm__ __volatile__ ("stwbrx %1,0,%2" : "=m" (*addr) : "r" (val), "r" (addr)); } -/* alas, egcs sounds like it has a bug in this code that doesn't use the - inline asm correctly, and can cause file corruption. Until I hear that - it's fixed, I can live without the extra speed. I hope. */ -#if 0 static __inline__ __const__ __u16 ___arch__swab16(__u16 value) { __u16 result; - __asm__("rlwimi %0,%1,8,16,23" - : "=r" (result) - : "r" (value), "0" (value >> 8)); + __asm__("rlwimi %0,%2,8,16,23" : "=&r" (result) : "0" (value >> 8), "r" (value)); return result; } @@ -53,16 +47,14 @@ static __inline__ __const__ __u32 ___arch__swab32(__u32 value) { __u32 result; - __asm__("rlwimi %0,%1,24,16,23\n\t" - "rlwimi %0,%1,8,8,15\n\t" - "rlwimi %0,%1,24,0,7" - : "=r" (result) - : "r" (value), "0" (value >> 24)); + __asm__("rlwimi %0,%2,24,16,23" : "=&r" (result) : "0" (value>>24), "r" (value)); + __asm__("rlwimi %0,%2,8,8,15" : "=&r" (result) : "0" (result), "r" (value)); + __asm__("rlwimi %0,%2,24,0,7" : "=&r" (result) : "0" (result), "r" (value)); + return result; } #define __arch__swab32(x) ___arch__swab32(x) #define __arch__swab16(x) ___arch__swab16(x) -#endif /* 0 */ /* The same, but returns converted value from the location pointer by addr. */ #define __arch__swab16p(addr) ld_le16(addr) diff --git a/include/asm-ppc/cache.h b/include/asm-ppc/cache.h index 3a0e34caf683..54c2d4c366ed 100644 --- a/include/asm-ppc/cache.h +++ b/include/asm-ppc/cache.h @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.cache.h 1.10 10/18/01 15:02:09 trini + * BK Id: %F% %I% %G% %U% %#% */ /* * include/asm-ppc/cache.h @@ -15,15 +15,15 @@ #if defined(CONFIG_8xx) || defined(CONFIG_403GCX) #define L1_CACHE_LINE_SIZE 16 #define LG_L1_CACHE_LINE_SIZE 4 -#define MAX_L1_COPY_PREFETCH 1 +#define MAX_COPY_PREFETCH 1 #elif defined(CONFIG_PPC64BRIDGE) #define L1_CACHE_LINE_SIZE 128 #define LG_L1_CACHE_LINE_SIZE 7 -#define MAX_L1_COPY_PREFETCH 1 +#define MAX_COPY_PREFETCH 1 #else #define L1_CACHE_LINE_SIZE 32 #define LG_L1_CACHE_LINE_SIZE 5 -#define MAX_L1_COPY_PREFETCH 4 +#define MAX_COPY_PREFETCH 4 #endif #define L1_CACHE_BYTES L1_CACHE_LINE_SIZE @@ -41,7 +41,10 @@ #endif #if defined(__KERNEL__) && !defined(__ASSEMBLY__) +extern void clean_dcache_range(unsigned long start, unsigned long stop); extern void flush_dcache_range(unsigned long start, unsigned long stop); +extern void invalidate_dcache_range(unsigned long start, unsigned long stop); +extern void flush_dcache_all(void); #endif /* __ASSEMBLY__ */ diff --git a/include/asm-ppc/dbdma.h b/include/asm-ppc/dbdma.h index 63b463c6a4f8..0a4d8a3e4b7d 100644 --- a/include/asm-ppc/dbdma.h +++ b/include/asm-ppc/dbdma.h @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.dbdma.h 1.5 05/17/01 18:14:24 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * Definitions for using the Apple Descriptor-Based DMA controller @@ -93,5 +93,13 @@ struct dbdma_cmd { /* Align an address for a DBDMA command structure */ #define DBDMA_ALIGN(x) (((unsigned)(x) + sizeof(struct dbdma_cmd) - 1) \ & -sizeof(struct dbdma_cmd)) + +/* Useful macros */ +#define DBDMA_DO_STOP(regs) do { \ + out_le32(&((regs)->control), (RUN|FLUSH)<<16); \ + while(in_le32(&((regs)->status)) & (ACTIVE|FLUSH)) \ + ; \ +} while(0) + #endif /* _ASM_DBDMA_H_ */ #endif /* __KERNEL__ */ diff --git a/include/asm-ppc/delay.h b/include/asm-ppc/delay.h index a43505c4ec38..72bfaa2c1f80 100644 --- a/include/asm-ppc/delay.h +++ b/include/asm-ppc/delay.h @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.delay.h 1.7 05/17/01 18:14:24 cort + * BK Id: %F% %I% %G% %U% %#% */ #ifdef __KERNEL__ #ifndef _PPC_DELAY_H @@ -18,35 +18,36 @@ extern unsigned long loops_per_jiffy; -/* maximum permitted argument to udelay */ -#define __MAX_UDELAY 1000000 - extern void __delay(unsigned int loops); -/* N.B. the `secs' parameter here is a fixed-point number with - the binary point to the left of the most-significant bit. */ -extern __inline__ void __const_udelay(unsigned int secs) -{ - unsigned int loops; - - __asm__("mulhwu %0,%1,%2" : "=r" (loops) : - "r" (secs), "r" (loops_per_jiffy)); - __delay(loops * HZ); -} - /* - * note that 4294 == 2^32 / 10^6, multiplying by 4294 converts from - * microseconds to a 32-bit fixed-point number of seconds. + * Note that 19 * 226 == 4294 ==~ 2^32 / 10^6, so + * loops = (4294 * usecs * loops_per_jiffy * HZ) / 2^32. + * + * The mulhwu instruction gives us loops = (a * b) / 2^32. + * We choose a = usecs * 19 * HZ and b = loops_per_jiffy * 226 + * because this lets us support a wide range of HZ and + * loops_per_jiffy values without either a or b overflowing 2^32. + * Thus we need usecs * HZ <= (2^32 - 1) / 19 = 226050910 and + * loops_per_jiffy <= (2^32 - 1) / 226 = 19004280 + * (which corresponds to ~3800 bogomips at HZ = 100). + * -- paulus */ +#define __MAX_UDELAY (226050910/HZ) /* maximum udelay argument */ + extern __inline__ void __udelay(unsigned int usecs) { - __const_udelay(usecs * 4294); + unsigned int loops; + + __asm__("mulhwu %0,%1,%2" : "=r" (loops) : + "r" (usecs * (19 * HZ)), "r" (loops_per_jiffy * 226)); + __delay(loops); } extern void __bad_udelay(void); /* deliberately undefined */ #define udelay(n) (__builtin_constant_p(n)? \ - ((n) > __MAX_UDELAY? __bad_udelay(): __const_udelay((n) * 4294u)) : \ + ((n) > __MAX_UDELAY? __bad_udelay(): __udelay((n))) : \ __udelay(n)) #endif /* defined(_PPC_DELAY_H) */ diff --git a/include/asm-ppc/dma.h b/include/asm-ppc/dma.h index e7e1655cc765..af24e03b564b 100644 --- a/include/asm-ppc/dma.h +++ b/include/asm-ppc/dma.h @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.dma.h 1.8 05/17/01 18:14:24 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * linux/include/asm/dma.h: Defines for using and allocating dma channels. @@ -27,7 +27,7 @@ * not valid for the PReP platform. Take what you read * with a grain of salt. */ - + #ifndef _ASM_DMA_H #define _ASM_DMA_H @@ -38,13 +38,12 @@ /* The maximum address that we can perform a DMA transfer to on this platform */ /* Doesn't really apply... */ -#define MAX_DMA_ADDRESS 0xFFFFFFFF +#define MAX_DMA_ADDRESS 0xFFFFFFFF /* in arch/ppc/kernel/setup.c -- Cort */ extern unsigned long DMA_MODE_WRITE, DMA_MODE_READ; extern unsigned long ISA_DMA_THRESHOLD; - #ifdef HAVE_REALLY_SLOW_DMA_CONTROLLER #define dma_outb outb_p #else @@ -69,7 +68,7 @@ extern unsigned long ISA_DMA_THRESHOLD; * - page registers for 5-7 don't use data bit 0, represent 128K pages * - page registers for 0-3 use bit 0, represent 64K pages * - * On PReP, DMA transfers are limited to the lower 16MB of _physical_ memory. + * On PReP, DMA transfers are limited to the lower 16MB of _physical_ memory. * On CHRP, the W83C553F (and VLSI Tollgate?) support full 32 bit addressing. * Note that addresses loaded into registers must be _physical_ addresses, * not logical addresses (which may differ if paging is active). @@ -80,7 +79,7 @@ extern unsigned long ISA_DMA_THRESHOLD; * | ... | | ... | | ... | * | ... | | ... | | ... | * | ... | | ... | | ... | - * P7 ... P0 A7 ... A0 A7 ... A0 + * P7 ... P0 A7 ... A0 A7 ... A0 * | Page | Addr MSB | Addr LSB | (DMA registers) * * Address mapping for channels 5-7: @@ -89,7 +88,7 @@ extern unsigned long ISA_DMA_THRESHOLD; * | ... | \ \ ... \ \ \ ... \ \ * | ... | \ \ ... \ \ \ ... \ (not used) * | ... | \ \ ... \ \ \ ... \ - * P7 ... P1 (0) A7 A6 ... A0 A7 A6 ... A0 + * P7 ... P1 (0) A7 A6 ... A0 A7 A6 ... A0 * | Page | Addr MSB | Addr LSB | (DMA registers) * * Again, channels 5-7 transfer _physical_ words (16 bits), so addresses @@ -98,23 +97,15 @@ extern unsigned long ISA_DMA_THRESHOLD; * * Transfer count (_not # bytes_) is limited to 64K, represented as actual * count - 1 : 64K => 0xFFFF, 1 => 0x0000. Thus, count is always 1 or more, - * and up to 128K bytes may be transferred on channels 5-7 in one operation. + * and up to 128K bytes may be transferred on channels 5-7 in one operation. * */ -/* used in nasty hack for sound - see prep_setup_arch() -- Cort */ +/* see prep_setup_arch() for detailed informations */ +#if defined(CONFIG_SOUND_CS4232) && defined(CONFIG_ALL_PPC) extern long ppc_cs4232_dma, ppc_cs4232_dma2; -#if defined(CONFIG_CS4232) -#if defined(CONFIG_ALL_PPC) #define SND_DMA1 ppc_cs4232_dma #define SND_DMA2 ppc_cs4232_dma2 -#else /* !CONFIG_ALL_PPC */ -#define SND_DMA1 -1 -#define SND_DMA2 -1 -#endif /* CONFIG_ALL_PPC */ -#elif defined(CONFIG_MSS) -#define SND_DMA1 CONFIG_MSS_DMA -#define SND_DMA2 CONFIG_MSS_DMA2 #else #define SND_DMA1 -1 #define SND_DMA2 -1 @@ -127,67 +118,67 @@ extern long ppc_cs4232_dma, ppc_cs4232_dma2; /* DMA controller registers */ #define DMA1_CMD_REG 0x08 /* command register (w) */ #define DMA1_STAT_REG 0x08 /* status register (r) */ -#define DMA1_REQ_REG 0x09 /* request register (w) */ +#define DMA1_REQ_REG 0x09 /* request register (w) */ #define DMA1_MASK_REG 0x0A /* single-channel mask (w) */ #define DMA1_MODE_REG 0x0B /* mode register (w) */ #define DMA1_CLEAR_FF_REG 0x0C /* clear pointer flip-flop (w) */ -#define DMA1_TEMP_REG 0x0D /* Temporary Register (r) */ +#define DMA1_TEMP_REG 0x0D /* Temporary Register (r) */ #define DMA1_RESET_REG 0x0D /* Master Clear (w) */ -#define DMA1_CLR_MASK_REG 0x0E /* Clear Mask */ -#define DMA1_MASK_ALL_REG 0x0F /* all-channels mask (w) */ +#define DMA1_CLR_MASK_REG 0x0E /* Clear Mask */ +#define DMA1_MASK_ALL_REG 0x0F /* all-channels mask (w) */ #define DMA2_CMD_REG 0xD0 /* command register (w) */ #define DMA2_STAT_REG 0xD0 /* status register (r) */ -#define DMA2_REQ_REG 0xD2 /* request register (w) */ +#define DMA2_REQ_REG 0xD2 /* request register (w) */ #define DMA2_MASK_REG 0xD4 /* single-channel mask (w) */ #define DMA2_MODE_REG 0xD6 /* mode register (w) */ #define DMA2_CLEAR_FF_REG 0xD8 /* clear pointer flip-flop (w) */ -#define DMA2_TEMP_REG 0xDA /* Temporary Register (r) */ +#define DMA2_TEMP_REG 0xDA /* Temporary Register (r) */ #define DMA2_RESET_REG 0xDA /* Master Clear (w) */ -#define DMA2_CLR_MASK_REG 0xDC /* Clear Mask */ -#define DMA2_MASK_ALL_REG 0xDE /* all-channels mask (w) */ - -#define DMA_ADDR_0 0x00 /* DMA address registers */ -#define DMA_ADDR_1 0x02 -#define DMA_ADDR_2 0x04 -#define DMA_ADDR_3 0x06 -#define DMA_ADDR_4 0xC0 -#define DMA_ADDR_5 0xC4 -#define DMA_ADDR_6 0xC8 -#define DMA_ADDR_7 0xCC - -#define DMA_CNT_0 0x01 /* DMA count registers */ -#define DMA_CNT_1 0x03 -#define DMA_CNT_2 0x05 -#define DMA_CNT_3 0x07 -#define DMA_CNT_4 0xC2 -#define DMA_CNT_5 0xC6 -#define DMA_CNT_6 0xCA -#define DMA_CNT_7 0xCE - -#define DMA_LO_PAGE_0 0x87 /* DMA page registers */ -#define DMA_LO_PAGE_1 0x83 -#define DMA_LO_PAGE_2 0x81 -#define DMA_LO_PAGE_3 0x82 -#define DMA_LO_PAGE_5 0x8B -#define DMA_LO_PAGE_6 0x89 -#define DMA_LO_PAGE_7 0x8A - -#define DMA_HI_PAGE_0 0x487 /* DMA page registers */ -#define DMA_HI_PAGE_1 0x483 -#define DMA_HI_PAGE_2 0x481 -#define DMA_HI_PAGE_3 0x482 -#define DMA_HI_PAGE_5 0x48B -#define DMA_HI_PAGE_6 0x489 -#define DMA_HI_PAGE_7 0x48A - -#define DMA1_EXT_REG 0x40B -#define DMA2_EXT_REG 0x4D6 - -#define DMA_MODE_CASCADE 0xC0 /* pass thru DREQ->HRQ, DACK<-HLDA only */ -#define DMA_AUTOINIT 0x10 - -extern spinlock_t dma_spin_lock; +#define DMA2_CLR_MASK_REG 0xDC /* Clear Mask */ +#define DMA2_MASK_ALL_REG 0xDE /* all-channels mask (w) */ + +#define DMA_ADDR_0 0x00 /* DMA address registers */ +#define DMA_ADDR_1 0x02 +#define DMA_ADDR_2 0x04 +#define DMA_ADDR_3 0x06 +#define DMA_ADDR_4 0xC0 +#define DMA_ADDR_5 0xC4 +#define DMA_ADDR_6 0xC8 +#define DMA_ADDR_7 0xCC + +#define DMA_CNT_0 0x01 /* DMA count registers */ +#define DMA_CNT_1 0x03 +#define DMA_CNT_2 0x05 +#define DMA_CNT_3 0x07 +#define DMA_CNT_4 0xC2 +#define DMA_CNT_5 0xC6 +#define DMA_CNT_6 0xCA +#define DMA_CNT_7 0xCE + +#define DMA_LO_PAGE_0 0x87 /* DMA page registers */ +#define DMA_LO_PAGE_1 0x83 +#define DMA_LO_PAGE_2 0x81 +#define DMA_LO_PAGE_3 0x82 +#define DMA_LO_PAGE_5 0x8B +#define DMA_LO_PAGE_6 0x89 +#define DMA_LO_PAGE_7 0x8A + +#define DMA_HI_PAGE_0 0x487 /* DMA page registers */ +#define DMA_HI_PAGE_1 0x483 +#define DMA_HI_PAGE_2 0x481 +#define DMA_HI_PAGE_3 0x482 +#define DMA_HI_PAGE_5 0x48B +#define DMA_HI_PAGE_6 0x489 +#define DMA_HI_PAGE_7 0x48A + +#define DMA1_EXT_REG 0x40B +#define DMA2_EXT_REG 0x4D6 + +#define DMA_MODE_CASCADE 0xC0 /* pass thru DREQ->HRQ, DACK<-HLDA only */ +#define DMA_AUTOINIT 0x10 + +extern spinlock_t dma_spin_lock; static __inline__ unsigned long claim_dma_lock(void) { @@ -206,27 +197,23 @@ static __inline__ void enable_dma(unsigned int dmanr) { unsigned char ucDmaCmd=0x00; - if (dmanr != 4) - { - dma_outb(0, DMA2_MASK_REG); /* This may not be enabled */ - dma_outb(ucDmaCmd, DMA2_CMD_REG); /* Enable group */ + if (dmanr != 4) { + dma_outb(0, DMA2_MASK_REG); /* This may not be enabled */ + dma_outb(ucDmaCmd, DMA2_CMD_REG); /* Enable group */ } - if (dmanr<=3) - { - dma_outb(dmanr, DMA1_MASK_REG); - dma_outb(ucDmaCmd, DMA1_CMD_REG); /* Enable group */ + if (dmanr <= 3) { + dma_outb(dmanr, DMA1_MASK_REG); + dma_outb(ucDmaCmd, DMA1_CMD_REG); /* Enable group */ } else - { - dma_outb(dmanr & 3, DMA2_MASK_REG); - } + dma_outb(dmanr & 3, DMA2_MASK_REG); } static __inline__ void disable_dma(unsigned int dmanr) { - if (dmanr<=3) - dma_outb(dmanr | 4, DMA1_MASK_REG); + if (dmanr <= 3) + dma_outb(dmanr | 4, DMA1_MASK_REG); else - dma_outb((dmanr & 3) | 4, DMA2_MASK_REG); + dma_outb((dmanr & 3) | 4, DMA2_MASK_REG); } /* Clear the 'DMA Pointer Flip Flop'. @@ -238,19 +225,19 @@ static __inline__ void disable_dma(unsigned int dmanr) */ static __inline__ void clear_dma_ff(unsigned int dmanr) { - if (dmanr<=3) - dma_outb(0, DMA1_CLEAR_FF_REG); + if (dmanr <= 3) + dma_outb(0, DMA1_CLEAR_FF_REG); else - dma_outb(0, DMA2_CLEAR_FF_REG); + dma_outb(0, DMA2_CLEAR_FF_REG); } /* set mode (above) for a specific DMA channel */ static __inline__ void set_dma_mode(unsigned int dmanr, char mode) { - if (dmanr<=3) - dma_outb(mode | dmanr, DMA1_MODE_REG); + if (dmanr <= 3) + dma_outb(mode | dmanr, DMA1_MODE_REG); else - dma_outb(mode | (dmanr&3), DMA2_MODE_REG); + dma_outb(mode | (dmanr & 3), DMA2_MODE_REG); } /* Set only the page register bits of the transfer address. @@ -263,41 +250,41 @@ static __inline__ void set_dma_page(unsigned int dmanr, int pagenr) switch(dmanr) { case 0: dma_outb(pagenr, DMA_LO_PAGE_0); - dma_outb(pagenr>>8, DMA_HI_PAGE_0); + dma_outb(pagenr >> 8, DMA_HI_PAGE_0); break; case 1: dma_outb(pagenr, DMA_LO_PAGE_1); - dma_outb(pagenr>>8, DMA_HI_PAGE_1); + dma_outb(pagenr >> 8, DMA_HI_PAGE_1); break; case 2: dma_outb(pagenr, DMA_LO_PAGE_2); - dma_outb(pagenr>>8, DMA_HI_PAGE_2); + dma_outb(pagenr >> 8, DMA_HI_PAGE_2); break; case 3: dma_outb(pagenr, DMA_LO_PAGE_3); - dma_outb(pagenr>>8, DMA_HI_PAGE_3); + dma_outb(pagenr >> 8, DMA_HI_PAGE_3); break; - case 5: - if (SND_DMA1 == 5 || SND_DMA2 == 5) + case 5: + if (SND_DMA1 == 5 || SND_DMA2 == 5) dma_outb(pagenr, DMA_LO_PAGE_5); else dma_outb(pagenr & 0xfe, DMA_LO_PAGE_5); - dma_outb(pagenr>>8, DMA_HI_PAGE_5); + dma_outb(pagenr >> 8, DMA_HI_PAGE_5); break; case 6: - if (SND_DMA1 == 6 || SND_DMA2 == 6) + if (SND_DMA1 == 6 || SND_DMA2 == 6) dma_outb(pagenr, DMA_LO_PAGE_6); else dma_outb(pagenr & 0xfe, DMA_LO_PAGE_6); - dma_outb(pagenr>>8, DMA_HI_PAGE_6); + dma_outb(pagenr >> 8, DMA_HI_PAGE_6); break; case 7: if (SND_DMA1 == 7 || SND_DMA2 == 7) dma_outb(pagenr, DMA_LO_PAGE_7); else dma_outb(pagenr & 0xfe, DMA_LO_PAGE_7); - dma_outb(pagenr>>8, DMA_HI_PAGE_7); - break; + dma_outb(pagenr >> 8, DMA_HI_PAGE_7); + break; } } @@ -307,20 +294,19 @@ static __inline__ void set_dma_page(unsigned int dmanr, int pagenr) */ static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int phys) { - if (dmanr <= 3) { - dma_outb( phys & 0xff, ((dmanr&3)<<1) + IO_DMA1_BASE ); - dma_outb( (phys>>8) & 0xff, ((dmanr&3)<<1) + IO_DMA1_BASE ); - } else { - if (dmanr == SND_DMA1 || dmanr == SND_DMA2) { - dma_outb( phys & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE ); - dma_outb( (phys>>8) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE ); - dma_outb( (dmanr&3), DMA2_EXT_REG); - } else { - dma_outb( (phys>>1) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE ); - dma_outb( (phys>>9) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE ); - } + if (dmanr <= 3) { + dma_outb(phys & 0xff, ((dmanr & 3) << 1) + IO_DMA1_BASE ); + dma_outb((phys >> 8) & 0xff, ((dmanr & 3) << 1) + IO_DMA1_BASE); + } else if (dmanr == SND_DMA1 || dmanr == SND_DMA2) { + dma_outb(phys & 0xff, ((dmanr & 3) << 2) + IO_DMA2_BASE ); + dma_outb((phys >> 8) & 0xff, ((dmanr & 3) << 2) + + IO_DMA2_BASE); + dma_outb((dmanr & 3), DMA2_EXT_REG); + } else { + dma_outb((phys >> 1) & 0xff, ((dmanr & 3) << 2) + IO_DMA2_BASE); + dma_outb((phys >> 9) & 0xff, ((dmanr & 3) << 2) + IO_DMA2_BASE); } - set_dma_page(dmanr, phys>>16); + set_dma_page(dmanr, phys >> 16); } @@ -334,22 +320,23 @@ static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int phys) */ static __inline__ void set_dma_count(unsigned int dmanr, unsigned int count) { - count--; - if (dmanr <= 3) { - dma_outb( count & 0xff, ((dmanr&3)<<1) + 1 + IO_DMA1_BASE ); - dma_outb( (count>>8) & 0xff, ((dmanr&3)<<1) + 1 + IO_DMA1_BASE ); - } else { - if (dmanr == SND_DMA1 || dmanr == SND_DMA2) { - dma_outb( count & 0xff, ((dmanr&3)<<2) + 2 + IO_DMA2_BASE ); - dma_outb( (count>>8) & 0xff, ((dmanr&3)<<2) + 2 + IO_DMA2_BASE ); - } else { - dma_outb( (count>>1) & 0xff, ((dmanr&3)<<2) + 2 + IO_DMA2_BASE ); - dma_outb( (count>>9) & 0xff, ((dmanr&3)<<2) + 2 + IO_DMA2_BASE ); - } - } + count--; + if (dmanr <= 3) { + dma_outb(count & 0xff, ((dmanr & 3) << 1) + 1 + IO_DMA1_BASE); + dma_outb((count >> 8) & 0xff, ((dmanr & 3) << 1) + 1 + + IO_DMA1_BASE); + } else if (dmanr == SND_DMA1 || dmanr == SND_DMA2) { + dma_outb( count & 0xff, ((dmanr & 3) << 2) + 2 + IO_DMA2_BASE); + dma_outb( (count >> 8) & 0xff, ((dmanr & 3) << 2) + 2 + + IO_DMA2_BASE); + } else { + dma_outb((count >> 1) & 0xff, ((dmanr & 3) << 2) + 2 + + IO_DMA2_BASE); + dma_outb((count >> 9) & 0xff, ((dmanr & 3) << 2) + 2 + + IO_DMA2_BASE); + } } - /* Get DMA residue count. After a DMA transfer, this * should return zero. Reading this while a DMA transfer is * still in progress will return unpredictable results. @@ -360,27 +347,32 @@ static __inline__ void set_dma_count(unsigned int dmanr, unsigned int count) */ static __inline__ int get_dma_residue(unsigned int dmanr) { - unsigned int io_port = (dmanr<=3)? ((dmanr&3)<<1) + 1 + IO_DMA1_BASE - : ((dmanr&3)<<2) + 2 + IO_DMA2_BASE; + unsigned int io_port = (dmanr <= 3) ? + ((dmanr & 3) << 1) + 1 + IO_DMA1_BASE + : ((dmanr & 3) << 2) + 2 + IO_DMA2_BASE; /* using short to get 16-bit wrap around */ unsigned short count; count = 1 + dma_inb(io_port); count += dma_inb(io_port) << 8; - + return (dmanr <= 3 || dmanr == SND_DMA1 || dmanr == SND_DMA2) - ? count : (count<<1); + ? count : (count<<1); + } /* These are in kernel/dma.c: */ -extern int request_dma(unsigned int dmanr, const char * device_id); /* reserve a DMA channel */ -extern void free_dma(unsigned int dmanr); /* release it again */ + +/* reserve a DMA channel */ +extern int request_dma(unsigned int dmanr, const char * device_id); +/* release it again */ +extern void free_dma(unsigned int dmanr); #ifdef CONFIG_PCI -extern int isa_dma_bridge_buggy; -#else -#define isa_dma_bridge_buggy (0) +extern int isa_dma_bridge_buggy; +#else +#define isa_dma_bridge_buggy (0) #endif #endif /* _ASM_DMA_H */ #endif /* __KERNEL__ */ diff --git a/include/asm-ppc/feature.h b/include/asm-ppc/feature.h deleted file mode 100644 index 3e7007bce88c..000000000000 --- a/include/asm-ppc/feature.h +++ /dev/null @@ -1,111 +0,0 @@ -/* - * BK Id: SCCS/s.feature.h 1.13 08/19/01 22:23:04 paulus - */ -/* - * Definitions for accessing the Feature Control Register (FCR) - * on Power Macintoshes and similar machines. The FCR lets us - * enable/disable, reset, and power up/down various peripherals. - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1998 Paul Mackerras & - * Ben. Herrenschmidt. - * - * - */ -#ifdef __KERNEL__ -#ifndef __ASM_PPC_FEATURE_H -#define __ASM_PPC_FEATURE_H - -/* - * The FCR selector for particular features vary somewhat between - * different machines. So we abstract a list of features here - * and let the feature_* routines map them to the actual bits. - */ -enum system_feature { - FEATURE_null, - FEATURE_Serial_reset, - FEATURE_Serial_enable, - FEATURE_Serial_IO_A, - FEATURE_Serial_IO_B, - FEATURE_SWIM3_enable, - FEATURE_MESH_enable, - FEATURE_IDE0_enable, /* Internal IDE */ - FEATURE_IDE0_reset, /* Internal IDE */ - FEATURE_IOBUS_enable, /* Internal IDE */ - FEATURE_Mediabay_reset, - FEATURE_Mediabay_power, - FEATURE_Mediabay_PCI_enable, - FEATURE_IDE1_enable, /* MediaBay IDE */ - FEATURE_IDE1_reset, /* MediaBay IDE */ - FEATURE_Mediabay_floppy_enable, - FEATURE_BMac_reset, - FEATURE_BMac_IO_enable, - FEATURE_Modem_power, - FEATURE_Slow_SCC_PCLK, - FEATURE_Sound_power, - FEATURE_Sound_CLK_enable, - FEATURE_IDE2_enable, - FEATURE_IDE2_reset, - FEATURE_Mediabay_IDE_switch, /* MB IDE bus switch */ - FEATURE_Mediabay_content, /* MB content indicator enable */ - FEATURE_Airport_reset, /* Is it actually a reset ? */ - FEATURE_last, -}; - -/* Note about the device parameter: Each device gives it's own entry. If NULL, - the feature function will just do nothing and return -EINVAL. - The feature management will walk up the device tree until in reaches a recognized - chip for which features can be changed and it will then apply the necessary - features to that chip. If it's not found, -ENODEV is returned. - Note also that feature_test/set/clear are interrupt-safe provided that they are - called _after_ feature_init() is completed. - */ - -/* Test whether a particular feature is enabled. May return -ENODEV*/ -extern int feature_test(struct device_node* device, enum system_feature f); - -/* Set a particular feature. Returns 0 or -ENODEV */ -extern int feature_set(struct device_node* device, enum system_feature f); - -/* Clear a particular feature */ -extern int feature_clear(struct device_node* device, enum system_feature f); - -/* Initialize feature stuff */ -extern void feature_init(void); - - -/* - * Additional functions related to Core99 machines. We should extend the - * feature mecanism to make those fit into it. For now, they are still - * separate functions. - */ -extern void feature_set_gmac_power(struct device_node* device, int power); - - /* use constants in KeyLargo.h for the reset parameter */ -extern void feature_gmac_phy_reset(struct device_node* device); - -extern void feature_set_usb_power(struct device_node* device, int power); - -extern void feature_set_firewire_power(struct device_node* device, int power); -extern void feature_set_firewire_cable_power(struct device_node* device, int power); - -extern void feature_set_modem_power(struct device_node* device, int power); - -extern void feature_set_airport_power(struct device_node* device, int power); - -extern void feature_core99_kick_cpu(int cpu_nr); - -/* - * Sleep related functions. At term, they should be high-priority notifiers, - * but this would require some changes to the current sleep scheme that won't - * be done in 2.4. - */ -extern void feature_prepare_for_sleep(void); -extern void feature_wake_up(void); -extern int feature_can_sleep(void); - -#endif /* __ASM_PPC_FEATURE_H */ -#endif /* __KERNEL__ */ diff --git a/include/asm-ppc/gg2.h b/include/asm-ppc/gg2.h index c7dab2ad5131..75bee9608e57 100644 --- a/include/asm-ppc/gg2.h +++ b/include/asm-ppc/gg2.h @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.gg2.h 1.5 05/17/01 18:14:24 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * asm-ppc/gg2.h -- VLSI VAS96011/12 `Golden Gate 2' register definitions @@ -37,6 +37,8 @@ * GG2 specific PCI Registers */ +extern unsigned long gg2_pci_config_base; /* kernel virtual address */ + #define GG2_PCI_BUSNO 0x40 /* Bus number */ #define GG2_PCI_SUBBUSNO 0x41 /* Subordinate bus number */ #define GG2_PCI_DISCCTR 0x42 /* Disconnect counter */ diff --git a/include/asm-ppc/gt64260.h b/include/asm-ppc/gt64260.h new file mode 100644 index 000000000000..90ddb3d457e3 --- /dev/null +++ b/include/asm-ppc/gt64260.h @@ -0,0 +1,324 @@ +/* + * include/asm-ppc/gt64260.h + * + * Prototypes, etc. for the Marvell/Galileo GT64260 host bridge routines. + * + * Author: Mark A. Greer <mgreer@mvista.com> + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#ifndef __ASMPPC_GT64260_H +#define __ASMPPC_GT64260_H + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/pci.h> +#include <linux/slab.h> + +#include <asm/byteorder.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/uaccess.h> +#include <asm/machdep.h> +#include <asm/pci-bridge.h> +#include <asm/gt64260_defs.h> + + +extern u32 gt64260_base; +extern u32 gt64260_irq_base; /* We handle the next 96 IRQs from here */ +extern u32 gt64260_revision; +extern u8 gt64260_pci_exclude_bridge; + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +/* IRQs defined by the 64260 */ +#define GT64260_IRQ_MPSC0 40 +#define GT64260_IRQ_MPSC1 42 +#define GT64260_IRQ_SDMA 36 + +/* + * Define a default physical memory map to be set up on the bridge. + * Also define a struct to pass that info from board-specific routines to + * GT64260 generic set up routines. By passing this info in, the board + * support developer can modify it at will. + */ + +/* + * This is the default memory map: + * CPU PCI + * --- --- + * PCI 0 I/O: 0xfa000000-0xfaffffff 0x00000000-0x00ffffff + * PCI 1 I/O: 0xfb000000-0xfbffffff 0x01000000-0x01ffffff + * PCI 0 MEM: 0x80000000-0x8fffffff 0x80000000-0x8fffffff + * PCI 1 MEM: 0x90000000-0x9fffffff 0x90000000-0x9fffffff + */ + +/* Default physical memory map for the GT64260 bridge */ + +/* + * PCI Bus 0 Definitions + */ +#define GT64260_PCI_0_IO_SIZE 0x01000000U +#define GT64260_PCI_0_MEM_SIZE 0x10000000U + +/* Processor Physical addresses */ +#define GT64260_PCI_0_IO_START_PROC 0xfa000000U +#define GT64260_PCI_0_IO_END_PROC (GT64260_PCI_0_IO_START_PROC + \ + GT64260_PCI_0_IO_SIZE - 1) + +/* PCI 0 addresses */ +#define GT64260_PCI_0_IO_START 0x00000000U +#define GT64260_PCI_0_IO_END (GT64260_PCI_0_IO_START + \ + GT64260_PCI_0_IO_SIZE - 1) + +/* Processor Physical addresses */ +#define GT64260_PCI_0_MEM_START_PROC 0x80000000U +#define GT64260_PCI_0_MEM_END_PROC (GT64260_PCI_0_MEM_START_PROC + \ + GT64260_PCI_0_MEM_SIZE - 1) + +/* PCI 0 addresses */ +#define GT64260_PCI_0_MEM_START 0x80000000U +#define GT64260_PCI_0_MEM_END (GT64260_PCI_0_MEM_START + \ + GT64260_PCI_0_MEM_SIZE - 1) + +/* + * PCI Bus 1 Definitions + */ +#define GT64260_PCI_1_IO_SIZE 0x01000000U +#define GT64260_PCI_1_MEM_SIZE 0x10000000U + +/* PCI 1 addresses */ +#define GT64260_PCI_1_IO_START 0x01000000U +#define GT64260_PCI_1_IO_END (GT64260_PCI_1_IO_START + \ + GT64260_PCI_1_IO_SIZE - 1) + +/* Processor Physical addresses */ +#define GT64260_PCI_1_IO_START_PROC 0xfb000000U +#define GT64260_PCI_1_IO_END_PROC (GT64260_PCI_1_IO_START_PROC + \ + GT64260_PCI_1_IO_SIZE - 1) + +/* PCI 1 addresses */ +#define GT64260_PCI_1_MEM_START 0x90000000U +#define GT64260_PCI_1_MEM_END (GT64260_PCI_1_MEM_START + \ + GT64260_PCI_1_MEM_SIZE - 1) + +/* Processor Physical addresses */ +#define GT64260_PCI_1_MEM_START_PROC 0x90000000U +#define GT64260_PCI_1_MEM_END_PROC (GT64260_PCI_1_MEM_START_PROC + \ + GT64260_PCI_1_MEM_SIZE - 1) + +/* Define struct to pass mem-map info into gt64260_common.c code */ +typedef struct { + struct pci_controller *hose_a; + struct pci_controller *hose_b; + + u32 mem_size; + + u32 pci_0_io_start_proc; + u32 pci_0_io_start_pci; + u32 pci_0_io_size; + u32 pci_0_io_swap; + + u32 pci_0_mem_start_proc; + u32 pci_0_mem_start_pci_hi; + u32 pci_0_mem_start_pci_lo; + u32 pci_0_mem_size; + u32 pci_0_mem_swap; + + u32 pci_1_io_start_proc; + u32 pci_1_io_start_pci; + u32 pci_1_io_size; + u32 pci_1_io_swap; + + u32 pci_1_mem_start_proc; + u32 pci_1_mem_start_pci_hi; + u32 pci_1_mem_start_pci_lo; + u32 pci_1_mem_size; + u32 pci_1_mem_swap; +} gt64260_bridge_info_t; + +#define GT64260_BRIDGE_INFO_DEFAULT(ip, ms) { \ + (ip)->mem_size = (ms); \ + \ + (ip)->pci_0_io_start_proc = GT64260_PCI_0_IO_START_PROC; \ + (ip)->pci_0_io_start_pci = GT64260_PCI_0_IO_START; \ + (ip)->pci_0_io_size = GT64260_PCI_0_IO_SIZE; \ + (ip)->pci_0_io_swap = GT64260_CPU_PCI_SWAP_NONE; \ + \ + (ip)->pci_0_mem_start_proc = GT64260_PCI_0_MEM_START_PROC; \ + (ip)->pci_0_mem_start_pci_hi = 0x00000000; \ + (ip)->pci_0_mem_start_pci_lo = GT64260_PCI_0_MEM_START; \ + (ip)->pci_0_mem_size = GT64260_PCI_0_MEM_SIZE; \ + (ip)->pci_0_mem_swap = GT64260_CPU_PCI_SWAP_NONE; \ + \ + (ip)->pci_1_io_start_proc = GT64260_PCI_1_IO_START_PROC; \ + (ip)->pci_1_io_start_pci = GT64260_PCI_1_IO_START; \ + (ip)->pci_1_io_size = GT64260_PCI_1_IO_SIZE; \ + (ip)->pci_1_io_swap = GT64260_CPU_PCI_SWAP_NONE; \ + \ + (ip)->pci_1_mem_start_proc = GT64260_PCI_1_MEM_START_PROC; \ + (ip)->pci_1_mem_start_pci_hi = 0x00000000; \ + (ip)->pci_1_mem_start_pci_lo = GT64260_PCI_1_MEM_START; \ + (ip)->pci_1_mem_size = GT64260_PCI_1_MEM_SIZE; \ + (ip)->pci_1_mem_swap = GT64260_CPU_PCI_SWAP_NONE; \ +} + +/* + ***************************************************************************** + * + * I/O macros to access the 64260's registers + * + ***************************************************************************** + */ + +extern inline uint32_t gt_read(uint32_t offs){ + return (in_le32((volatile uint *)(gt64260_base + offs))); +} +extern inline void gt_write(uint32_t offs, uint32_t d){ + out_le32((volatile uint *)(gt64260_base + offs), d); +} + +#if 0 /* paranoid SMP version */ +extern inline void gt_modify(u32 offs, u32 data, u32 mask) \ +{ + uint32_t reg; + spin_lock(>64260_lock); + reg = gt_read(offs) & (~mask); /* zero any bits we care about*/ + reg |= data & mask; /* set bits from the data */ + gt_write(offs, reg); + spin_unlock(>64260_lock); +} +#else +extern inline void gt_modify(uint32_t offs, uint32_t data, uint32_t mask) +{ + uint32_t reg; + reg = gt_read(offs) & (~(mask)); /* zero any bits we care about*/ + reg |= (data) & (mask); /* set bits from the data */ + gt_write(offs, reg); +} +#endif +#define gt_set_bits(offs, bits) gt_modify(offs, ~0, bits) + +#define gt_clr_bits(offs, bits) gt_modify(offs, 0, bits) + + +/* + ***************************************************************************** + * + * Function Prototypes + * + ***************************************************************************** + */ + +int gt64260_find_bridges(u32 phys_base_addr, gt64260_bridge_info_t *info, + int ((*map_irq)(struct pci_dev *, unsigned char, unsigned char))); +int gt64260_bridge_init(gt64260_bridge_info_t *info); +int gt64260_cpu_scs_set_window(u32 window, + u32 base_addr, + u32 size); +int gt64260_cpu_cs_set_window(u32 window, + u32 base_addr, + u32 size); +int gt64260_cpu_boot_set_window(u32 base_addr, + u32 size); +int gt64260_cpu_set_pci_io_window(u32 pci_bus, + u32 cpu_base_addr, + u32 pci_base_addr, + u32 size, + u32 swap); +int gt64260_cpu_set_pci_mem_window(u32 pci_bus, + u32 window, + u32 cpu_base_addr, + u32 pci_base_addr_hi, + u32 pci_base_addr_lo, + u32 size, + u32 swap_64bit); +int gt64260_cpu_prot_set_window(u32 window, + u32 base_addr, + u32 size, + u32 access_bits); +int gt64260_cpu_snoop_set_window(u32 window, + u32 base_addr, + u32 size, + u32 snoop_type); +void gt64260_cpu_disable_all_windows(void); +int gt64260_pci_bar_enable(u32 pci_bus, u32 enable_bits); +int gt64260_pci_slave_scs_set_window(struct pci_controller *hose, + u32 window, + u32 pci_base_addr, + u32 cpu_base_addr, + u32 size); +int gt64260_pci_slave_cs_set_window(struct pci_controller *hose, + u32 window, + u32 pci_base_addr, + u32 cpu_base_addr, + u32 size); +int gt64260_pci_slave_boot_set_window(struct pci_controller *hose, + u32 pci_base_addr, + u32 cpu_base_addr, + u32 size); +int gt64260_pci_slave_p2p_mem_set_window(struct pci_controller *hose, + u32 window, + u32 pci_base_addr, + u32 other_bus_base_addr, + u32 size); +int gt64260_pci_slave_p2p_io_set_window(struct pci_controller *hose, + u32 pci_base_addr, + u32 other_bus_base_addr, + u32 size); +int gt64260_pci_slave_dac_scs_set_window(struct pci_controller *hose, + u32 window, + u32 pci_base_addr_hi, + u32 pci_base_addr_lo, + u32 cpu_base_addr, + u32 size); +int gt64260_pci_slave_dac_cs_set_window(struct pci_controller *hose, + u32 window, + u32 pci_base_addr_hi, + u32 pci_base_addr_lo, + u32 cpu_base_addr, + u32 size); +int gt64260_pci_slave_dac_boot_set_window(struct pci_controller *hose, + u32 pci_base_addr_hi, + u32 pci_base_addr_lo, + u32 cpu_base_addr, + u32 size); +int gt64260_pci_slave_dac_p2p_mem_set_window(struct pci_controller *hose, + u32 window, + u32 pci_base_addr_hi, + u32 pci_base_addr_lo, + u32 other_bus_base_addr, + u32 size); +int gt64260_pci_acc_cntl_set_window(u32 pci_bus, + u32 window, + u32 base_addr_hi, + u32 base_addr_lo, + u32 size, + u32 features); +int gt64260_pci_snoop_set_window(u32 pci_bus, + u32 window, + u32 base_addr_hi, + u32 base_addr_lo, + u32 size, + u32 snoop_type); +int gt64260_set_base(u32 new_base); +int gt64260_get_base(u32 *base); +int gt64260_pci_exclude_device(u8 bus, u8 devfn); + +void gt64260_init_irq(void); +int gt64260_get_irq(struct pt_regs *regs); + +void gt64260_mpsc_progress(char *s, unsigned short hex); + +#endif /* __ASMPPC_GT64260_H */ diff --git a/include/asm-ppc/gt64260_defs.h b/include/asm-ppc/gt64260_defs.h new file mode 100644 index 000000000000..3ad58564be78 --- /dev/null +++ b/include/asm-ppc/gt64260_defs.h @@ -0,0 +1,1012 @@ +/* + * include/asm-ppc/gt64260_defs.h + * + * Register definitions for the Marvell/Galileo GT64260 host bridge. + * + * Author: Mark A. Greer <mgreer@mvista.com> + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#ifndef __ASMPPC_GT64260_DEFS_H +#define __ASMPPC_GT64260_DEFS_H + +/* + * Define a macro to represent the supported version of the 64260. + */ +#define GT64260 0x01 +#define GT64260A 0x10 + +/* + ***************************************************************************** + * + * CPU Interface Registers + * + ***************************************************************************** + */ + +/* CPU physical address of 64260's registers */ +#define GT64260_INTERNAL_SPACE_DECODE 0x0068 +#define GT64260_INTERNAL_SPACE_SIZE 0x10000 +#define GT64260_INTERNAL_SPACE_DEFAULT_ADDR 0x14000000 + +/* CPU Memory Controller Window Registers (4 windows) */ +#define GT64260_CPU_SCS_DECODE_WINDOWS 4 + +#define GT64260_CPU_SCS_DECODE_0_BOT 0x0008 +#define GT64260_CPU_SCS_DECODE_0_TOP 0x0010 +#define GT64260_CPU_SCS_DECODE_1_BOT 0x0208 +#define GT64260_CPU_SCS_DECODE_1_TOP 0x0210 +#define GT64260_CPU_SCS_DECODE_2_BOT 0x0018 +#define GT64260_CPU_SCS_DECODE_2_TOP 0x0020 +#define GT64260_CPU_SCS_DECODE_3_BOT 0x0218 +#define GT64260_CPU_SCS_DECODE_3_TOP 0x0220 + +/* CPU Device Controller Window Registers (4 windows) */ +#define GT64260_CPU_CS_DECODE_WINDOWS 4 + +#define GT64260_CPU_CS_DECODE_0_BOT 0x0028 +#define GT64260_CPU_CS_DECODE_0_TOP 0x0030 +#define GT64260_CPU_CS_DECODE_1_BOT 0x0228 +#define GT64260_CPU_CS_DECODE_1_TOP 0x0230 +#define GT64260_CPU_CS_DECODE_2_BOT 0x0248 +#define GT64260_CPU_CS_DECODE_2_TOP 0x0250 +#define GT64260_CPU_CS_DECODE_3_BOT 0x0038 +#define GT64260_CPU_CS_DECODE_3_TOP 0x0040 + +#define GT64260_CPU_BOOT_CS_DECODE_0_BOT 0x0238 +#define GT64260_CPU_BOOT_CS_DECODE_0_TOP 0x0240 + +/* CPU Windows to PCI space (2 PCI buses each w/ 1 I/O & 4 MEM windows) */ +#define GT64260_PCI_BUSES 2 +#define GT64260_PCI_IO_WINDOWS_PER_BUS 1 +#define GT64260_PCI_MEM_WINDOWS_PER_BUS 4 + +#define GT64260_CPU_PCI_SWAP_BYTE 0x00000000 +#define GT64260_CPU_PCI_SWAP_NONE 0x01000000 +#define GT64260_CPU_PCI_SWAP_BYTE_WORD 0x02000000 +#define GT64260_CPU_PCI_SWAP_WORD 0x03000000 +#define GT64260_CPU_PCI_SWAP_MASK 0x07000000 + +#define GT64260_CPU_PCI_MEM_REQ64 (1<<27) + +#define GT64260_CPU_PCI_0_IO_DECODE_BOT 0x0048 +#define GT64260_CPU_PCI_0_IO_DECODE_TOP 0x0050 +#define GT64260_CPU_PCI_0_MEM_0_DECODE_BOT 0x0058 +#define GT64260_CPU_PCI_0_MEM_0_DECODE_TOP 0x0060 +#define GT64260_CPU_PCI_0_MEM_1_DECODE_BOT 0x0080 +#define GT64260_CPU_PCI_0_MEM_1_DECODE_TOP 0x0088 +#define GT64260_CPU_PCI_0_MEM_2_DECODE_BOT 0x0258 +#define GT64260_CPU_PCI_0_MEM_2_DECODE_TOP 0x0260 +#define GT64260_CPU_PCI_0_MEM_3_DECODE_BOT 0x0280 +#define GT64260_CPU_PCI_0_MEM_3_DECODE_TOP 0x0288 + +#define GT64260_CPU_PCI_0_IO_REMAP 0x00f0 +#define GT64260_CPU_PCI_0_MEM_0_REMAP_LO 0x00f8 +#define GT64260_CPU_PCI_0_MEM_0_REMAP_HI 0x0320 +#define GT64260_CPU_PCI_0_MEM_1_REMAP_LO 0x0100 +#define GT64260_CPU_PCI_0_MEM_1_REMAP_HI 0x0328 +#define GT64260_CPU_PCI_0_MEM_2_REMAP_LO 0x02f8 +#define GT64260_CPU_PCI_0_MEM_2_REMAP_HI 0x0330 +#define GT64260_CPU_PCI_0_MEM_3_REMAP_LO 0x0300 +#define GT64260_CPU_PCI_0_MEM_3_REMAP_HI 0x0338 + +#define GT64260_CPU_PCI_1_IO_DECODE_BOT 0x0090 +#define GT64260_CPU_PCI_1_IO_DECODE_TOP 0x0098 +#define GT64260_CPU_PCI_1_MEM_0_DECODE_BOT 0x00a0 +#define GT64260_CPU_PCI_1_MEM_0_DECODE_TOP 0x00a8 +#define GT64260_CPU_PCI_1_MEM_1_DECODE_BOT 0x00b0 +#define GT64260_CPU_PCI_1_MEM_1_DECODE_TOP 0x00b8 +#define GT64260_CPU_PCI_1_MEM_2_DECODE_BOT 0x02a0 +#define GT64260_CPU_PCI_1_MEM_2_DECODE_TOP 0x02a8 +#define GT64260_CPU_PCI_1_MEM_3_DECODE_BOT 0x02b0 +#define GT64260_CPU_PCI_1_MEM_3_DECODE_TOP 0x02b8 + +#define GT64260_CPU_PCI_1_IO_REMAP 0x0108 +#define GT64260_CPU_PCI_1_MEM_0_REMAP_LO 0x0110 +#define GT64260_CPU_PCI_1_MEM_0_REMAP_HI 0x0340 +#define GT64260_CPU_PCI_1_MEM_1_REMAP_LO 0x0118 +#define GT64260_CPU_PCI_1_MEM_1_REMAP_HI 0x0348 +#define GT64260_CPU_PCI_1_MEM_2_REMAP_LO 0x0310 +#define GT64260_CPU_PCI_1_MEM_2_REMAP_HI 0x0350 +#define GT64260_CPU_PCI_1_MEM_3_REMAP_LO 0x0318 +#define GT64260_CPU_PCI_1_MEM_3_REMAP_HI 0x0358 + +/* CPU Control Registers */ +#define GT64260_CPU_CONFIG 0x0000 +#define GT64260_CPU_MODE 0x0120 +#define GT64260_CPU_MASTER_CNTL 0x0160 +#define GT64260_CPU_XBAR_CNTL_LO 0x0150 +#define GT64260_CPU_XBAR_CNTL_HI 0x0158 +#define GT64260_CPU_XBAR_TO 0x0168 +#define GT64260_CPU_RR_XBAR_CNTL_LO 0x0170 +#define GT64260_CPU_RR_XBAR_CNTL_HI 0x0178 + +/* CPU Sync Barrier Registers */ +#define GT64260_CPU_SYNC_BARRIER_PCI_0 0x00c0 +#define GT64260_CPU_SYNC_BARRIER_PCI_1 0x00c8 + +/* CPU Access Protection Registers */ +#define GT64260_CPU_PROT_WINDOWS 8 + +#define GT64260_CPU_PROT_ACCPROTECT (1<<16) +#define GT64260_CPU_PROT_WRPROTECT (1<<17) +#define GT64260_CPU_PROT_CACHEPROTECT (1<<18) + +#define GT64260_CPU_PROT_BASE_0 0x0180 +#define GT64260_CPU_PROT_TOP_0 0x0188 +#define GT64260_CPU_PROT_BASE_1 0x0190 +#define GT64260_CPU_PROT_TOP_1 0x0198 +#define GT64260_CPU_PROT_BASE_2 0x01a0 +#define GT64260_CPU_PROT_TOP_2 0x01a8 +#define GT64260_CPU_PROT_BASE_3 0x01b0 +#define GT64260_CPU_PROT_TOP_3 0x01b8 +#define GT64260_CPU_PROT_BASE_4 0x01c0 +#define GT64260_CPU_PROT_TOP_4 0x01c8 +#define GT64260_CPU_PROT_BASE_5 0x01d0 +#define GT64260_CPU_PROT_TOP_5 0x01d8 +#define GT64260_CPU_PROT_BASE_6 0x01e0 +#define GT64260_CPU_PROT_TOP_6 0x01e8 +#define GT64260_CPU_PROT_BASE_7 0x01f0 +#define GT64260_CPU_PROT_TOP_7 0x01f8 + +/* CPU Snoop Control Registers */ +#define GT64260_CPU_SNOOP_WINDOWS 4 + +#define GT64260_CPU_SNOOP_NONE 0x00000000 +#define GT64260_CPU_SNOOP_WT 0x00010000 +#define GT64260_CPU_SNOOP_WB 0x00020000 +#define GT64260_CPU_SNOOP_MASK 0x00030000 +#define GT64260_CPU_SNOOP_ALL_BITS GT64260_CPU_SNOOP_MASK + +#define GT64260_CPU_SNOOP_BASE_0 0x0380 +#define GT64260_CPU_SNOOP_TOP_0 0x0388 +#define GT64260_CPU_SNOOP_BASE_1 0x0390 +#define GT64260_CPU_SNOOP_TOP_1 0x0398 +#define GT64260_CPU_SNOOP_BASE_2 0x03a0 +#define GT64260_CPU_SNOOP_TOP_2 0x03a8 +#define GT64260_CPU_SNOOP_BASE_3 0x03b0 +#define GT64260_CPU_SNOOP_TOP_3 0x03b8 + +/* CPU Error Report Registers */ +#define GT64260_CPU_ERR_ADDR_LO 0x0070 +#define GT64260_CPU_ERR_ADDR_HI 0x0078 +#define GT64260_CPU_ERR_DATA_LO 0x0128 +#define GT64260_CPU_ERR_DATA_HI 0x0130 +#define GT64260_CPU_ERR_PARITY 0x0138 +#define GT64260_CPU_ERR_CAUSE 0x0140 +#define GT64260_CPU_ERR_MASK 0x0148 + + +/* + ***************************************************************************** + * + * SDRAM Cotnroller Registers + * + ***************************************************************************** + */ + +/* SDRAM Config Registers */ +#define GT64260_SDRAM_CONFIG 0x0448 +#define GT64260_SDRAM_OPERATION_MODE 0x0474 +#define GT64260_SDRAM_ADDR_CNTL 0x047c +#define GT64260_SDRAM_TIMING_PARAMS 0x04b4 +#define GT64260_SDRAM_UMA_CNTL 0x04a4 +#define GT64260_SDRAM_XBAR_CNTL_LO 0x04a8 +#define GT64260_SDRAM_XBAR_CNTL_HI 0x04ac +#define GT64260_SDRAM_XBAR_CNTL_TO 0x04b0 + +/* SDRAM Banks Parameters Registers */ +#define GT64260_SDRAM_BANK_PARAMS_0 0x044c +#define GT64260_SDRAM_BANK_PARAMS_1 0x0450 +#define GT64260_SDRAM_BANK_PARAMS_2 0x0454 +#define GT64260_SDRAM_BANK_PARAMS_3 0x0458 + +/* SDRAM Error Report Registers */ +#define GT64260_SDRAM_ERR_DATA_LO 0x0484 +#define GT64260_SDRAM_ERR_DATA_HI 0x0480 +#define GT64260_SDRAM_ERR_ADDR 0x0490 +#define GT64260_SDRAM_ERR_ECC_RCVD 0x0488 +#define GT64260_SDRAM_ERR_ECC_CALC 0x048c +#define GT64260_SDRAM_ERR_ECC_CNTL 0x0494 +#define GT64260_SDRAM_ERR_ECC_ERR_CNT 0x0498 + + +/* + ***************************************************************************** + * + * Device/BOOT Cotnroller Registers + * + ***************************************************************************** + */ + +/* Device Control Registers */ +#define GT64260_DEV_BANK_PARAMS_0 0x045c +#define GT64260_DEV_BANK_PARAMS_1 0x0460 +#define GT64260_DEV_BANK_PARAMS_2 0x0464 +#define GT64260_DEV_BANK_PARAMS_3 0x0468 +#define GT64260_DEV_BOOT_PARAMS 0x046c +#define GT64260_DEV_IF_CNTL 0x04c0 +#define GT64260_DEV_IF_XBAR_CNTL_LO 0x04c8 +#define GT64260_DEV_IF_XBAR_CNTL_HI 0x04cc +#define GT64260_DEV_IF_XBAR_CNTL_TO 0x04c4 + +/* Device Interrupt Registers */ +#define GT64260_DEV_INTR_CAUSE 0x04d0 +#define GT64260_DEV_INTR_MASK 0x04d4 +#define GT64260_DEV_INTR_ERR_ADDR 0x04d8 + + +/* + ***************************************************************************** + * + * PCI Bridge Interface Registers + * + ***************************************************************************** + */ + +/* PCI Configuration Access Registers */ +#define GT64260_PCI_0_CONFIG_ADDR 0x0cf8 +#define GT64260_PCI_0_CONFIG_DATA 0x0cfc +#define GT64260_PCI_0_IACK 0x0c34 + +#define GT64260_PCI_1_CONFIG_ADDR 0x0c78 +#define GT64260_PCI_1_CONFIG_DATA 0x0c7c +#define GT64260_PCI_1_IACK 0x0cb4 + +/* PCI Control Registers */ +#define GT64260_PCI_0_CMD 0x0c00 +#define GT64260_PCI_0_MODE 0x0d00 +#define GT64260_PCI_0_TO_RETRY 0x0c04 +#define GT64260_PCI_0_RD_BUF_DISCARD_TIMER 0x0d04 +#define GT64260_PCI_0_MSI_TRIGGER_TIMER 0x0c38 +#define GT64260_PCI_0_ARBITER_CNTL 0x1d00 +#define GT64260_PCI_0_XBAR_CNTL_LO 0x1d08 +#define GT64260_PCI_0_XBAR_CNTL_HI 0x1d0c +#define GT64260_PCI_0_XBAR_CNTL_TO 0x1d04 +#define GT64260_PCI_0_RD_RESP_XBAR_CNTL_LO 0x1d18 +#define GT64260_PCI_0_RD_RESP_XBAR_CNTL_HI 0x1d1c +#define GT64260_PCI_0_SYNC_BARRIER 0x1d10 +#define GT64260_PCI_0_P2P_CONFIG 0x1d14 +#define GT64260_PCI_0_P2P_SWAP_CNTL 0x1d54 + +#define GT64260_PCI_1_CMD 0x0c80 +#define GT64260_PCI_1_MODE 0x0d80 +#define GT64260_PCI_1_TO_RETRY 0x0c84 +#define GT64260_PCI_1_RD_BUF_DISCARD_TIMER 0x0d84 +#define GT64260_PCI_1_MSI_TRIGGER_TIMER 0x0cb8 +#define GT64260_PCI_1_ARBITER_CNTL 0x1d80 +#define GT64260_PCI_1_XBAR_CNTL_LO 0x1d88 +#define GT64260_PCI_1_XBAR_CNTL_HI 0x1d8c +#define GT64260_PCI_1_XBAR_CNTL_TO 0x1d84 +#define GT64260_PCI_1_RD_RESP_XBAR_CNTL_LO 0x1d98 +#define GT64260_PCI_1_RD_RESP_XBAR_CNTL_HI 0x1d9c +#define GT64260_PCI_1_SYNC_BARRIER 0x1d90 +#define GT64260_PCI_1_P2P_CONFIG 0x1d94 +#define GT64260_PCI_1_P2P_SWAP_CNTL 0x1dd4 + +/* PCI Access Control Regions Registers */ +#define GT64260_PCI_ACC_CNTL_WINDOWS 8 + +#define GT64260_PCI_ACC_CNTL_PREFETCHEN (1<<12) +#define GT64260_PCI_ACC_CNTL_DREADEN (1<<13) +#define GT64260_PCI_ACC_CNTL_RDPREFETCH (1<<16) +#define GT64260_PCI_ACC_CNTL_RDLINEPREFETCH (1<<17) +#define GT64260_PCI_ACC_CNTL_RDMULPREFETCH (1<<18) +#define GT64260_PCI_ACC_CNTL_MBURST_4_WORDS 0x00000000 +#define GT64260_PCI_ACC_CNTL_MBURST_8_WORDS 0x00100000 +#define GT64260_PCI_ACC_CNTL_MBURST_16_WORDS 0x00200000 +#define GT64260_PCI_ACC_CNTL_MBURST_MASK 0x00300000 +#define GT64260_PCI_ACC_CNTL_SWAP_BYTE 0x00000000 +#define GT64260_PCI_ACC_CNTL_SWAP_NONE 0x01000000 +#define GT64260_PCI_ACC_CNTL_SWAP_BYTE_WORD 0x02000000 +#define GT64260_PCI_ACC_CNTL_SWAP_WORD 0x03000000 +#define GT64260_PCI_ACC_CNTL_SWAP_MASK 0x03000000 +#define GT64260_PCI_ACC_CNTL_ACCPROT (1<<28) +#define GT64260_PCI_ACC_CNTL_WRPROT (1<<29) + +#define GT64260_PCI_ACC_CNTL_ALL_BITS (GT64260_PCI_ACC_CNTL_PREFETCHEN | \ + GT64260_PCI_ACC_CNTL_DREADEN | \ + GT64260_PCI_ACC_CNTL_RDPREFETCH | \ + GT64260_PCI_ACC_CNTL_RDLINEPREFETCH |\ + GT64260_PCI_ACC_CNTL_RDMULPREFETCH | \ + GT64260_PCI_ACC_CNTL_MBURST_MASK | \ + GT64260_PCI_ACC_CNTL_SWAP_MASK | \ + GT64260_PCI_ACC_CNTL_ACCPROT| \ + GT64260_PCI_ACC_CNTL_WRPROT) + +#define GT64260_PCI_0_ACC_CNTL_0_BASE_LO 0x1e00 +#define GT64260_PCI_0_ACC_CNTL_0_BASE_HI 0x1e04 +#define GT64260_PCI_0_ACC_CNTL_0_TOP 0x1e08 +#define GT64260_PCI_0_ACC_CNTL_1_BASE_LO 0x1e10 +#define GT64260_PCI_0_ACC_CNTL_1_BASE_HI 0x1e14 +#define GT64260_PCI_0_ACC_CNTL_1_TOP 0x1e18 +#define GT64260_PCI_0_ACC_CNTL_2_BASE_LO 0x1e20 +#define GT64260_PCI_0_ACC_CNTL_2_BASE_HI 0x1e24 +#define GT64260_PCI_0_ACC_CNTL_2_TOP 0x1e28 +#define GT64260_PCI_0_ACC_CNTL_3_BASE_LO 0x1e30 +#define GT64260_PCI_0_ACC_CNTL_3_BASE_HI 0x1e34 +#define GT64260_PCI_0_ACC_CNTL_3_TOP 0x1e38 +#define GT64260_PCI_0_ACC_CNTL_4_BASE_LO 0x1e40 +#define GT64260_PCI_0_ACC_CNTL_4_BASE_HI 0x1e44 +#define GT64260_PCI_0_ACC_CNTL_4_TOP 0x1e48 +#define GT64260_PCI_0_ACC_CNTL_5_BASE_LO 0x1e50 +#define GT64260_PCI_0_ACC_CNTL_5_BASE_HI 0x1e54 +#define GT64260_PCI_0_ACC_CNTL_5_TOP 0x1e58 +#define GT64260_PCI_0_ACC_CNTL_6_BASE_LO 0x1e60 +#define GT64260_PCI_0_ACC_CNTL_6_BASE_HI 0x1e64 +#define GT64260_PCI_0_ACC_CNTL_6_TOP 0x1e68 +#define GT64260_PCI_0_ACC_CNTL_7_BASE_LO 0x1e70 +#define GT64260_PCI_0_ACC_CNTL_7_BASE_HI 0x1e74 +#define GT64260_PCI_0_ACC_CNTL_7_TOP 0x1e78 + +#define GT64260_PCI_1_ACC_CNTL_0_BASE_LO 0x1e80 +#define GT64260_PCI_1_ACC_CNTL_0_BASE_HI 0x1e84 +#define GT64260_PCI_1_ACC_CNTL_0_TOP 0x1e88 +#define GT64260_PCI_1_ACC_CNTL_1_BASE_LO 0x1e90 +#define GT64260_PCI_1_ACC_CNTL_1_BASE_HI 0x1e94 +#define GT64260_PCI_1_ACC_CNTL_1_TOP 0x1e98 +#define GT64260_PCI_1_ACC_CNTL_2_BASE_LO 0x1ea0 +#define GT64260_PCI_1_ACC_CNTL_2_BASE_HI 0x1ea4 +#define GT64260_PCI_1_ACC_CNTL_2_TOP 0x1ea8 +#define GT64260_PCI_1_ACC_CNTL_3_BASE_LO 0x1eb0 +#define GT64260_PCI_1_ACC_CNTL_3_BASE_HI 0x1eb4 +#define GT64260_PCI_1_ACC_CNTL_3_TOP 0x1eb8 +#define GT64260_PCI_1_ACC_CNTL_4_BASE_LO 0x1ec0 +#define GT64260_PCI_1_ACC_CNTL_4_BASE_HI 0x1ec4 +#define GT64260_PCI_1_ACC_CNTL_4_TOP 0x1ec8 +#define GT64260_PCI_1_ACC_CNTL_5_BASE_LO 0x1ed0 +#define GT64260_PCI_1_ACC_CNTL_5_BASE_HI 0x1ed4 +#define GT64260_PCI_1_ACC_CNTL_5_TOP 0x1ed8 +#define GT64260_PCI_1_ACC_CNTL_6_BASE_LO 0x1ee0 +#define GT64260_PCI_1_ACC_CNTL_6_BASE_HI 0x1ee4 +#define GT64260_PCI_1_ACC_CNTL_6_TOP 0x1ee8 +#define GT64260_PCI_1_ACC_CNTL_7_BASE_LO 0x1ef0 +#define GT64260_PCI_1_ACC_CNTL_7_BASE_HI 0x1ef4 +#define GT64260_PCI_1_ACC_CNTL_7_TOP 0x1ef8 + +/* PCI Snoop Control Registers */ +#define GT64260_PCI_SNOOP_WINDOWS 4 + +#define GT64260_PCI_SNOOP_NONE 0x00000000 +#define GT64260_PCI_SNOOP_WT 0x00001000 +#define GT64260_PCI_SNOOP_WB 0x00002000 + +#define GT64260_PCI_0_SNOOP_0_BASE_LO 0x1f00 +#define GT64260_PCI_0_SNOOP_0_BASE_HI 0x1f04 +#define GT64260_PCI_0_SNOOP_0_TOP 0x1f08 +#define GT64260_PCI_0_SNOOP_1_BASE_LO 0x1f10 +#define GT64260_PCI_0_SNOOP_1_BASE_HI 0x1f14 +#define GT64260_PCI_0_SNOOP_1_TOP 0x1f18 +#define GT64260_PCI_0_SNOOP_2_BASE_LO 0x1f20 +#define GT64260_PCI_0_SNOOP_2_BASE_HI 0x1f24 +#define GT64260_PCI_0_SNOOP_2_TOP 0x1f28 +#define GT64260_PCI_0_SNOOP_3_BASE_LO 0x1f30 +#define GT64260_PCI_0_SNOOP_3_BASE_HI 0x1f34 +#define GT64260_PCI_0_SNOOP_3_TOP 0x1f38 + +#define GT64260_PCI_1_SNOOP_0_BASE_LO 0x1f80 +#define GT64260_PCI_1_SNOOP_0_BASE_HI 0x1f84 +#define GT64260_PCI_1_SNOOP_0_TOP 0x1f88 +#define GT64260_PCI_1_SNOOP_1_BASE_LO 0x1f90 +#define GT64260_PCI_1_SNOOP_1_BASE_HI 0x1f94 +#define GT64260_PCI_1_SNOOP_1_TOP 0x1f98 +#define GT64260_PCI_1_SNOOP_2_BASE_LO 0x1fa0 +#define GT64260_PCI_1_SNOOP_2_BASE_HI 0x1fa4 +#define GT64260_PCI_1_SNOOP_2_TOP 0x1fa8 +#define GT64260_PCI_1_SNOOP_3_BASE_LO 0x1fb0 +#define GT64260_PCI_1_SNOOP_3_BASE_HI 0x1fb4 +#define GT64260_PCI_1_SNOOP_3_TOP 0x1fb8 + +/* PCI Error Report Registers */ +#define GT64260_PCI_0_ERR_SERR_MASK 0x0c28 +#define GT64260_PCI_0_ERR_ADDR_LO 0x1d40 +#define GT64260_PCI_0_ERR_ADDR_HI 0x1d44 +#define GT64260_PCI_0_ERR_DATA_LO 0x1d48 +#define GT64260_PCI_0_ERR_DATA_HI 0x1d4c +#define GT64260_PCI_0_ERR_CMD 0x1d50 +#define GT64260_PCI_0_ERR_CAUSE 0x1d58 +#define GT64260_PCI_0_ERR_MASK 0x1d5c + +#define GT64260_PCI_1_ERR_SERR_MASK 0x0ca8 +#define GT64260_PCI_1_ERR_ADDR_LO 0x1dc0 +#define GT64260_PCI_1_ERR_ADDR_HI 0x1dc4 +#define GT64260_PCI_1_ERR_DATA_LO 0x1dc8 +#define GT64260_PCI_1_ERR_DATA_HI 0x1dcc +#define GT64260_PCI_1_ERR_CMD 0x1dd0 +#define GT64260_PCI_1_ERR_CAUSE 0x1dd8 +#define GT64260_PCI_1_ERR_MASK 0x1ddc + +/* PCI Slave Address Decoding Registers */ +#define GT64260_PCI_SCS_WINDOWS 4 +#define GT64260_PCI_CS_WINDOWS 4 +#define GT64260_PCI_BOOT_WINDOWS 1 +#define GT64260_PCI_P2P_MEM_WINDOWS 2 +#define GT64260_PCI_P2P_IO_WINDOWS 1 +#define GT64260_PCI_DAC_SCS_WINDOWS 4 +#define GT64260_PCI_DAC_CS_WINDOWS 4 +#define GT64260_PCI_DAC_BOOT_WINDOWS 1 +#define GT64260_PCI_DAC_P2P_MEM_WINDOWS 2 + +#define GT64260_PCI_0_SLAVE_SCS_0_SIZE 0x0c08 +#define GT64260_PCI_0_SLAVE_SCS_1_SIZE 0x0d08 +#define GT64260_PCI_0_SLAVE_SCS_2_SIZE 0x0c0c +#define GT64260_PCI_0_SLAVE_SCS_3_SIZE 0x0d0c +#define GT64260_PCI_0_SLAVE_CS_0_SIZE 0x0c10 +#define GT64260_PCI_0_SLAVE_CS_1_SIZE 0x0d10 +#define GT64260_PCI_0_SLAVE_CS_2_SIZE 0x0d18 +#define GT64260_PCI_0_SLAVE_CS_3_SIZE 0x0c14 +#define GT64260_PCI_0_SLAVE_BOOT_SIZE 0x0d14 +#define GT64260_PCI_0_SLAVE_P2P_MEM_0_SIZE 0x0d1c +#define GT64260_PCI_0_SLAVE_P2P_MEM_1_SIZE 0x0d20 +#define GT64260_PCI_0_SLAVE_P2P_IO_SIZE 0x0d24 +#define GT64260_PCI_0_SLAVE_CPU_SIZE 0x0d28 + +#define GT64260_PCI_0_SLAVE_DAC_SCS_0_SIZE 0x0e00 +#define GT64260_PCI_0_SLAVE_DAC_SCS_1_SIZE 0x0e04 +#define GT64260_PCI_0_SLAVE_DAC_SCS_2_SIZE 0x0e08 +#define GT64260_PCI_0_SLAVE_DAC_SCS_3_SIZE 0x0e0c +#define GT64260_PCI_0_SLAVE_DAC_CS_0_SIZE 0x0e10 +#define GT64260_PCI_0_SLAVE_DAC_CS_1_SIZE 0x0e14 +#define GT64260_PCI_0_SLAVE_DAC_CS_2_SIZE 0x0e18 +#define GT64260_PCI_0_SLAVE_DAC_CS_3_SIZE 0x0e1c +#define GT64260_PCI_0_SLAVE_DAC_BOOT_SIZE 0x0e20 +#define GT64260_PCI_0_SLAVE_DAC_P2P_MEM_0_SIZE 0x0e24 +#define GT64260_PCI_0_SLAVE_DAC_P2P_MEM_1_SIZE 0x0e28 +#define GT64260_PCI_0_SLAVE_DAC_CPU_SIZE 0x0e2c + +#define GT64260_PCI_0_SLAVE_EXP_ROM_SIZE 0x0d2c + +#define GT64260_PCI_SLAVE_BAR_REG_ENABLES_SCS_0 (1<<0) +#define GT64260_PCI_SLAVE_BAR_REG_ENABLES_SCS_1 (1<<1) +#define GT64260_PCI_SLAVE_BAR_REG_ENABLES_SCS_2 (1<<2) +#define GT64260_PCI_SLAVE_BAR_REG_ENABLES_SCS_3 (1<<3) +#define GT64260_PCI_SLAVE_BAR_REG_ENABLES_CS_0 (1<<4) +#define GT64260_PCI_SLAVE_BAR_REG_ENABLES_CS_1 (1<<5) +#define GT64260_PCI_SLAVE_BAR_REG_ENABLES_CS_2 (1<<6) +#define GT64260_PCI_SLAVE_BAR_REG_ENABLES_CS_3 (1<<7) +#define GT64260_PCI_SLAVE_BAR_REG_ENABLES_BOOT (1<<8) +#define GT64260_PCI_SLAVE_BAR_REG_ENABLES_REG_MEM (1<<9) +#define GT64260_PCI_SLAVE_BAR_REG_ENABLES_REG_IO (1<<10) +#define GT64260_PCI_SLAVE_BAR_REG_ENABLES_P2P_MEM_0 (1<<11) +#define GT64260_PCI_SLAVE_BAR_REG_ENABLES_P2P_MEM_1 (1<<12) +#define GT64260_PCI_SLAVE_BAR_REG_ENABLES_P2P_IO (1<<13) +#define GT64260_PCI_SLAVE_BAR_REG_ENABLES_CPU (1<<14) +#define GT64260_PCI_SLAVE_BAR_REG_ENABLES_DAC_SCS_0 (1<<15) +#define GT64260_PCI_SLAVE_BAR_REG_ENABLES_DAC_SCS_1 (1<<16) +#define GT64260_PCI_SLAVE_BAR_REG_ENABLES_DAC_SCS_2 (1<<17) +#define GT64260_PCI_SLAVE_BAR_REG_ENABLES_DAC_SCS_3 (1<<18) +#define GT64260_PCI_SLAVE_BAR_REG_ENABLES_DAC_CS_0 (1<<19) +#define GT64260_PCI_SLAVE_BAR_REG_ENABLES_DAC_CS_1 (1<<20) +#define GT64260_PCI_SLAVE_BAR_REG_ENABLES_DAC_CS_2 (1<<21) +#define GT64260_PCI_SLAVE_BAR_REG_ENABLES_DAC_CS_3 (1<<22) +#define GT64260_PCI_SLAVE_BAR_REG_ENABLES_DAC_BOOT (1<<23) +#define GT64260_PCI_SLAVE_BAR_REG_ENABLES_DAC_P2P_MEM_0 (1<<24) +#define GT64260_PCI_SLAVE_BAR_REG_ENABLES_DAC_P2P_MEM_1 (1<<25) +#define GT64260_PCI_SLAVE_BAR_REG_ENABLES_DAC_CPU (1<<26) + +#define GT64260_PCI_0_SLAVE_BAR_REG_ENABLES 0x0c3c +#define GT64260_PCI_0_SLAVE_SCS_0_REMAP 0x0c48 +#define GT64260_PCI_0_SLAVE_SCS_1_REMAP 0x0d48 +#define GT64260_PCI_0_SLAVE_SCS_2_REMAP 0x0c4c +#define GT64260_PCI_0_SLAVE_SCS_3_REMAP 0x0d4c +#define GT64260_PCI_0_SLAVE_CS_0_REMAP 0x0c50 +#define GT64260_PCI_0_SLAVE_CS_1_REMAP 0x0d50 +#define GT64260_PCI_0_SLAVE_CS_2_REMAP 0x0d58 +#define GT64260_PCI_0_SLAVE_CS_3_REMAP 0x0c54 +#define GT64260_PCI_0_SLAVE_BOOT_REMAP 0x0d54 +#define GT64260_PCI_0_SLAVE_P2P_MEM_0_REMAP_LO 0x0d5c +#define GT64260_PCI_0_SLAVE_P2P_MEM_0_REMAP_HI 0x0d60 +#define GT64260_PCI_0_SLAVE_P2P_MEM_1_REMAP_LO 0x0d64 +#define GT64260_PCI_0_SLAVE_P2P_MEM_1_REMAP_HI 0x0d68 +#define GT64260_PCI_0_SLAVE_P2P_IO_REMAP 0x0d6c +#define GT64260_PCI_0_SLAVE_CPU_REMAP 0x0d70 + +#define GT64260_PCI_0_SLAVE_DAC_SCS_0_REMAP 0x0f00 +#define GT64260_PCI_0_SLAVE_DAC_SCS_1_REMAP 0x0f04 +#define GT64260_PCI_0_SLAVE_DAC_SCS_2_REMAP 0x0f08 +#define GT64260_PCI_0_SLAVE_DAC_SCS_3_REMAP 0x0f0c +#define GT64260_PCI_0_SLAVE_DAC_CS_0_REMAP 0x0f10 +#define GT64260_PCI_0_SLAVE_DAC_CS_1_REMAP 0x0f14 +#define GT64260_PCI_0_SLAVE_DAC_CS_2_REMAP 0x0f18 +#define GT64260_PCI_0_SLAVE_DAC_CS_3_REMAP 0x0f1c +#define GT64260_PCI_0_SLAVE_DAC_BOOT_REMAP 0x0f20 +#define GT64260_PCI_0_SLAVE_DAC_P2P_MEM_0_REMAP_LO 0x0f24 +#define GT64260_PCI_0_SLAVE_DAC_P2P_MEM_0_REMAP_HI 0x0f28 +#define GT64260_PCI_0_SLAVE_DAC_P2P_MEM_1_REMAP_LO 0x0f2c +#define GT64260_PCI_0_SLAVE_DAC_P2P_MEM_1_REMAP_HI 0x0f30 +#define GT64260_PCI_0_SLAVE_DAC_CPU_REMAP 0x0f34 + +#define GT64260_PCI_0_SLAVE_EXP_ROM_REMAP 0x0f38 +#define GT64260_PCI_0_SLAVE_PCI_DECODE_CNTL 0x0d3c + +#define GT64260_PCI_1_SLAVE_SCS_0_SIZE 0x0c88 +#define GT64260_PCI_1_SLAVE_SCS_1_SIZE 0x0d88 +#define GT64260_PCI_1_SLAVE_SCS_2_SIZE 0x0c8c +#define GT64260_PCI_1_SLAVE_SCS_3_SIZE 0x0d8c +#define GT64260_PCI_1_SLAVE_CS_0_SIZE 0x0c90 +#define GT64260_PCI_1_SLAVE_CS_1_SIZE 0x0d90 +#define GT64260_PCI_1_SLAVE_CS_2_SIZE 0x0d98 +#define GT64260_PCI_1_SLAVE_CS_3_SIZE 0x0c94 +#define GT64260_PCI_1_SLAVE_BOOT_SIZE 0x0d94 +#define GT64260_PCI_1_SLAVE_P2P_MEM_0_SIZE 0x0d9c +#define GT64260_PCI_1_SLAVE_P2P_MEM_1_SIZE 0x0da0 +#define GT64260_PCI_1_SLAVE_P2P_IO_SIZE 0x0da4 +#define GT64260_PCI_1_SLAVE_CPU_SIZE 0x0da8 + +#define GT64260_PCI_1_SLAVE_DAC_SCS_0_SIZE 0x0e80 +#define GT64260_PCI_1_SLAVE_DAC_SCS_1_SIZE 0x0e84 +#define GT64260_PCI_1_SLAVE_DAC_SCS_2_SIZE 0x0e88 +#define GT64260_PCI_1_SLAVE_DAC_SCS_3_SIZE 0x0e8c +#define GT64260_PCI_1_SLAVE_DAC_CS_0_SIZE 0x0e90 +#define GT64260_PCI_1_SLAVE_DAC_CS_1_SIZE 0x0e94 +#define GT64260_PCI_1_SLAVE_DAC_CS_2_SIZE 0x0e98 +#define GT64260_PCI_1_SLAVE_DAC_CS_3_SIZE 0x0e9c +#define GT64260_PCI_1_SLAVE_DAC_BOOT_SIZE 0x0ea0 +#define GT64260_PCI_1_SLAVE_DAC_P2P_MEM_0_SIZE 0x0ea4 +#define GT64260_PCI_1_SLAVE_DAC_P2P_MEM_1_SIZE 0x0ea8 +#define GT64260_PCI_1_SLAVE_DAC_CPU_SIZE 0x0eac + +#define GT64260_PCI_1_SLAVE_EXP_ROM_SIZE 0x0dac + +#define GT64260_PCI_1_SLAVE_BAR_REG_ENABLES 0x0cbc +#define GT64260_PCI_1_SLAVE_SCS_0_REMAP 0x0cc8 +#define GT64260_PCI_1_SLAVE_SCS_1_REMAP 0x0dc8 +#define GT64260_PCI_1_SLAVE_SCS_2_REMAP 0x0ccc +#define GT64260_PCI_1_SLAVE_SCS_3_REMAP 0x0dcc +#define GT64260_PCI_1_SLAVE_CS_0_REMAP 0x0cd0 +#define GT64260_PCI_1_SLAVE_CS_1_REMAP 0x0dd0 +#define GT64260_PCI_1_SLAVE_CS_2_REMAP 0x0dd8 +#define GT64260_PCI_1_SLAVE_CS_3_REMAP 0x0cd4 +#define GT64260_PCI_1_SLAVE_BOOT_REMAP 0x0dd4 +#define GT64260_PCI_1_SLAVE_P2P_MEM_0_REMAP_LO 0x0ddc +#define GT64260_PCI_1_SLAVE_P2P_MEM_0_REMAP_HI 0x0de0 +#define GT64260_PCI_1_SLAVE_P2P_MEM_1_REMAP_LO 0x0de4 +#define GT64260_PCI_1_SLAVE_P2P_MEM_1_REMAP_HI 0x0de8 +#define GT64260_PCI_1_SLAVE_P2P_IO_REMAP 0x0dec +#define GT64260_PCI_1_SLAVE_CPU_REMAP 0x0df0 + +#define GT64260_PCI_1_SLAVE_DAC_SCS_0_REMAP 0x0f80 +#define GT64260_PCI_1_SLAVE_DAC_SCS_1_REMAP 0x0f84 +#define GT64260_PCI_1_SLAVE_DAC_SCS_2_REMAP 0x0f88 +#define GT64260_PCI_1_SLAVE_DAC_SCS_3_REMAP 0x0f8c +#define GT64260_PCI_1_SLAVE_DAC_CS_0_REMAP 0x0f90 +#define GT64260_PCI_1_SLAVE_DAC_CS_1_REMAP 0x0f94 +#define GT64260_PCI_1_SLAVE_DAC_CS_2_REMAP 0x0f98 +#define GT64260_PCI_1_SLAVE_DAC_CS_3_REMAP 0x0f9c +#define GT64260_PCI_1_SLAVE_DAC_BOOT_REMAP 0x0fa0 +#define GT64260_PCI_1_SLAVE_DAC_P2P_MEM_0_REMAP_LO 0x0fa4 +#define GT64260_PCI_1_SLAVE_DAC_P2P_MEM_0_REMAP_HI 0x0fa8 +#define GT64260_PCI_1_SLAVE_DAC_P2P_MEM_1_REMAP_LO 0x0fac +#define GT64260_PCI_1_SLAVE_DAC_P2P_MEM_1_REMAP_HI 0x0fb0 +#define GT64260_PCI_1_SLAVE_DAC_CPU_REMAP 0x0fb4 + +#define GT64260_PCI_1_SLAVE_EXP_ROM_REMAP 0x0fb8 +#define GT64260_PCI_1_SLAVE_PCI_DECODE_CNTL 0x0dbc + + +/* + ***************************************************************************** + * + * I2O Controller Interface Registers + * + ***************************************************************************** + */ + +/* FIXME: fill in */ + + + +/* + ***************************************************************************** + * + * DMA Controller Interface Registers + * + ***************************************************************************** + */ + +/* FIXME: fill in */ + + +/* + ***************************************************************************** + * + * Timer/Counter Interface Registers + * + ***************************************************************************** + */ + +/* FIXME: fill in */ + + +/* + ***************************************************************************** + * + * Communications Controller (Enet, Serial, etc.) Interface Registers + * + ***************************************************************************** + */ + +#define GT64260_ENET_0_CNTL_LO 0xf200 +#define GT64260_ENET_0_CNTL_HI 0xf204 +#define GT64260_ENET_0_RX_BUF_PCI_ADDR_HI 0xf208 +#define GT64260_ENET_0_TX_BUF_PCI_ADDR_HI 0xf20c +#define GT64260_ENET_0_RX_DESC_ADDR_HI 0xf210 +#define GT64260_ENET_0_TX_DESC_ADDR_HI 0xf214 +#define GT64260_ENET_0_HASH_TAB_PCI_ADDR_HI 0xf218 +#define GT64260_ENET_1_CNTL_LO 0xf220 +#define GT64260_ENET_1_CNTL_HI 0xf224 +#define GT64260_ENET_1_RX_BUF_PCI_ADDR_HI 0xf228 +#define GT64260_ENET_1_TX_BUF_PCI_ADDR_HI 0xf22c +#define GT64260_ENET_1_RX_DESC_ADDR_HI 0xf230 +#define GT64260_ENET_1_TX_DESC_ADDR_HI 0xf234 +#define GT64260_ENET_1_HASH_TAB_PCI_ADDR_HI 0xf238 +#define GT64260_ENET_2_CNTL_LO 0xf240 +#define GT64260_ENET_2_CNTL_HI 0xf244 +#define GT64260_ENET_2_RX_BUF_PCI_ADDR_HI 0xf248 +#define GT64260_ENET_2_TX_BUF_PCI_ADDR_HI 0xf24c +#define GT64260_ENET_2_RX_DESC_ADDR_HI 0xf250 +#define GT64260_ENET_2_TX_DESC_ADDR_HI 0xf254 +#define GT64260_ENET_2_HASH_TAB_PCI_ADDR_HI 0xf258 + +#define GT64260_MPSC_0_CNTL_LO 0xf280 +#define GT64260_MPSC_0_CNTL_HI 0xf284 +#define GT64260_MPSC_0_RX_BUF_PCI_ADDR_HI 0xf288 +#define GT64260_MPSC_0_TX_BUF_PCI_ADDR_HI 0xf28c +#define GT64260_MPSC_0_RX_DESC_ADDR_HI 0xf290 +#define GT64260_MPSC_0_TX_DESC_ADDR_HI 0xf294 +#define GT64260_MPSC_1_CNTL_LO 0xf2c0 +#define GT64260_MPSC_1_CNTL_HI 0xf2c4 +#define GT64260_MPSC_1_RX_BUF_PCI_ADDR_HI 0xf2c8 +#define GT64260_MPSC_1_TX_BUF_PCI_ADDR_HI 0xf2cc +#define GT64260_MPSC_1_RX_DESC_ADDR_HI 0xf2d0 +#define GT64260_MPSC_1_TX_DESC_ADDR_HI 0xf2d4 + +#define GT64260_SER_INIT_PCI_ADDR_HI 0xf320 +#define GT64260_SER_INIT_LAST_DATA 0xf324 +#define GT64260_SER_INIT_CONTROL 0xf328 +#define GT64260_SER_INIT_STATUS 0xf32c + +#define GT64260_COMM_ARBITER_CNTL 0xf300 +#define GT64260_COMM_CONFIG 0xb40c +#define GT64260_COMM_XBAR_TO 0xf304 +#define GT64260_COMM_INTR_CAUSE 0xf310 +#define GT64260_COMM_INTR_MASK 0xf314 +#define GT64260_COMM_ERR_ADDR 0xf318 + + +/* + ***************************************************************************** + * + * Fast Ethernet Controller Interface Registers + * + ***************************************************************************** + */ + +#define GT64260_ENET_PHY_ADDR 0x2000 +#define GT64260_ENET_ESMIR 0x2010 + +#define GT64260_ENET_E0PCR 0x2400 +#define GT64260_ENET_E0PCXR 0x2408 +#define GT64260_ENET_E0PCMR 0x2410 +#define GT64260_ENET_E0PSR 0x2418 +#define GT64260_ENET_E0SPR 0x2420 +#define GT64260_ENET_E0HTPR 0x2428 +#define GT64260_ENET_E0FCSAL 0x2430 +#define GT64260_ENET_E0FCSAH 0x2438 +#define GT64260_ENET_E0SDCR 0x2440 +#define GT64260_ENET_E0SDCMR 0x2448 +#define GT64260_ENET_E0ICR 0x2450 +#define GT64260_ENET_E0IMR 0x2458 +#define GT64260_ENET_E0FRDP0 0x2480 +#define GT64260_ENET_E0FRDP1 0x2484 +#define GT64260_ENET_E0FRDP2 0x2488 +#define GT64260_ENET_E0FRDP3 0x248c +#define GT64260_ENET_E0CRDP0 0x24a0 +#define GT64260_ENET_E0CRDP1 0x24a4 +#define GT64260_ENET_E0CRDP2 0x24a8 +#define GT64260_ENET_E0CRDP3 0x24ac +#define GT64260_ENET_E0CTDP0 0x24e0 +#define GT64260_ENET_E0CTDP1 0x24e4 +#define GT64260_ENET_0_DSCP2P0L 0x2460 +#define GT64260_ENET_0_DSCP2P0H 0x2464 +#define GT64260_ENET_0_DSCP2P1L 0x2468 +#define GT64260_ENET_0_DSCP2P1H 0x246c +#define GT64260_ENET_0_VPT2P 0x2470 +#define GT64260_ENET_0_MIB_CTRS 0x2500 + +#define GT64260_ENET_E1PCR 0x2800 +#define GT64260_ENET_E1PCXR 0x2808 +#define GT64260_ENET_E1PCMR 0x2810 +#define GT64260_ENET_E1PSR 0x2818 +#define GT64260_ENET_E1SPR 0x2820 +#define GT64260_ENET_E1HTPR 0x2828 +#define GT64260_ENET_E1FCSAL 0x2830 +#define GT64260_ENET_E1FCSAH 0x2838 +#define GT64260_ENET_E1SDCR 0x2840 +#define GT64260_ENET_E1SDCMR 0x2848 +#define GT64260_ENET_E1ICR 0x2850 +#define GT64260_ENET_E1IMR 0x2858 +#define GT64260_ENET_E1FRDP0 0x2880 +#define GT64260_ENET_E1FRDP1 0x2884 +#define GT64260_ENET_E1FRDP2 0x2888 +#define GT64260_ENET_E1FRDP3 0x288c +#define GT64260_ENET_E1CRDP0 0x28a0 +#define GT64260_ENET_E1CRDP1 0x28a4 +#define GT64260_ENET_E1CRDP2 0x28a8 +#define GT64260_ENET_E1CRDP3 0x28ac +#define GT64260_ENET_E1CTDP0 0x28e0 +#define GT64260_ENET_E1CTDP1 0x28e4 +#define GT64260_ENET_1_DSCP2P0L 0x2860 +#define GT64260_ENET_1_DSCP2P0H 0x2864 +#define GT64260_ENET_1_DSCP2P1L 0x2868 +#define GT64260_ENET_1_DSCP2P1H 0x286c +#define GT64260_ENET_1_VPT2P 0x2870 +#define GT64260_ENET_1_MIB_CTRS 0x2900 + +#define GT64260_ENET_E2PCR 0x2c00 +#define GT64260_ENET_E2PCXR 0x2c08 +#define GT64260_ENET_E2PCMR 0x2c10 +#define GT64260_ENET_E2PSR 0x2c18 +#define GT64260_ENET_E2SPR 0x2c20 +#define GT64260_ENET_E2HTPR 0x2c28 +#define GT64260_ENET_E2FCSAL 0x2c30 +#define GT64260_ENET_E2FCSAH 0x2c38 +#define GT64260_ENET_E2SDCR 0x2c40 +#define GT64260_ENET_E2SDCMR 0x2c48 +#define GT64260_ENET_E2ICR 0x2c50 +#define GT64260_ENET_E2IMR 0x2c58 +#define GT64260_ENET_E2FRDP0 0x2c80 +#define GT64260_ENET_E2FRDP1 0x2c84 +#define GT64260_ENET_E2FRDP2 0x2c88 +#define GT64260_ENET_E2FRDP3 0x2c8c +#define GT64260_ENET_E2CRDP0 0x2ca0 +#define GT64260_ENET_E2CRDP1 0x2ca4 +#define GT64260_ENET_E2CRDP2 0x2ca8 +#define GT64260_ENET_E2CRDP3 0x2cac +#define GT64260_ENET_E2CTDP0 0x2ce0 +#define GT64260_ENET_E2CTDP1 0x2ce4 +#define GT64260_ENET_2_DSCP2P0L 0x2c60 +#define GT64260_ENET_2_DSCP2P0H 0x2c64 +#define GT64260_ENET_2_DSCP2P1L 0x2c68 +#define GT64260_ENET_2_DSCP2P1H 0x2c6c +#define GT64260_ENET_2_VPT2P 0x2c70 +#define GT64260_ENET_2_MIB_CTRS 0x2d00 + + +/* + ***************************************************************************** + * + * Multi-Protocol Serial Controller Interface Registers + * + ***************************************************************************** + */ + +/* Signal Routing */ +#define GT64260_MPSC_MRR 0xb400 +#define GT64260_MPSC_RCRR 0xb404 +#define GT64260_MPSC_TCRR 0xb408 + +/* Main Configuratino Registers */ +#define GT64260_MPSC_0_MMCRL 0x8000 +#define GT64260_MPSC_0_MMCRH 0x8004 +#define GT64260_MPSC_0_MPCR 0x8008 +#define GT64260_MPSC_0_CHR_1 0x800c +#define GT64260_MPSC_0_CHR_2 0x8010 +#define GT64260_MPSC_0_CHR_3 0x8014 +#define GT64260_MPSC_0_CHR_4 0x8018 +#define GT64260_MPSC_0_CHR_5 0x801c +#define GT64260_MPSC_0_CHR_6 0x8020 +#define GT64260_MPSC_0_CHR_7 0x8024 +#define GT64260_MPSC_0_CHR_8 0x8028 +#define GT64260_MPSC_0_CHR_9 0x802c +#define GT64260_MPSC_0_CHR_10 0x8030 +#define GT64260_MPSC_0_CHR_11 0x8034 + +#define GT64260_MPSC_1_MMCRL 0x9000 +#define GT64260_MPSC_1_MMCRH 0x9004 +#define GT64260_MPSC_1_MPCR 0x9008 +#define GT64260_MPSC_1_CHR_1 0x900c +#define GT64260_MPSC_1_CHR_2 0x9010 +#define GT64260_MPSC_1_CHR_3 0x9014 +#define GT64260_MPSC_1_CHR_4 0x9018 +#define GT64260_MPSC_1_CHR_5 0x901c +#define GT64260_MPSC_1_CHR_6 0x9020 +#define GT64260_MPSC_1_CHR_7 0x9024 +#define GT64260_MPSC_1_CHR_8 0x9028 +#define GT64260_MPSC_1_CHR_9 0x902c +#define GT64260_MPSC_1_CHR_10 0x9030 +#define GT64260_MPSC_1_CHR_11 0x9034 + +#define GT64260_MPSC_0_INTR_CAUSE 0xb804 +#define GT64260_MPSC_0_INTR_MASK 0xb884 +#define GT64260_MPSC_1_INTR_CAUSE 0xb80c +#define GT64260_MPSC_1_INTR_MASK 0xb88c + +#define GT64260_MPSC_UART_CR_TEV (1<<1) +#define GT64260_MPSC_UART_CR_TA (1<<7) +#define GT64260_MPSC_UART_CR_TTCS (1<<9) +#define GT64260_MPSC_UART_CR_REV (1<<17) +#define GT64260_MPSC_UART_CR_RA (1<<23) +#define GT64260_MPSC_UART_CR_CRD (1<<25) +#define GT64260_MPSC_UART_CR_EH (1<<31) + +#define GT64260_MPSC_UART_ESR_CTS (1<<0) +#define GT64260_MPSC_UART_ESR_CD (1<<1) +#define GT64260_MPSC_UART_ESR_TIDLE (1<<3) +#define GT64260_MPSC_UART_ESR_RHS (1<<5) +#define GT64260_MPSC_UART_ESR_RLS (1<<7) +#define GT64260_MPSC_UART_ESR_RLIDL (1<<11) + + +/* + ***************************************************************************** + * + * Serial DMA Controller Interface Registers + * + ***************************************************************************** + */ + +#define GT64260_SDMA_0_SDC 0x4000 +#define GT64260_SDMA_0_SDCM 0x4008 +#define GT64260_SDMA_0_RX_DESC 0x4800 +#define GT64260_SDMA_0_RX_BUF_PTR 0x4808 +#define GT64260_SDMA_0_SCRDP 0x4810 +#define GT64260_SDMA_0_TX_DESC 0x4c00 +#define GT64260_SDMA_0_SCTDP 0x4c10 +#define GT64260_SDMA_0_SFTDP 0x4c14 + +#define GT64260_SDMA_1_SDC 0x6000 +#define GT64260_SDMA_1_SDCM 0x6008 +#define GT64260_SDMA_1_RX_DESC 0x6800 +#define GT64260_SDMA_1_RX_BUF_PTR 0x6808 +#define GT64260_SDMA_1_SCRDP 0x6810 +#define GT64260_SDMA_1_TX_DESC 0x6c00 +#define GT64260_SDMA_1_SCTDP 0x6c10 +#define GT64260_SDMA_1_SFTDP 0x6c14 + +#define GT64260_SDMA_INTR_CAUSE 0xb800 +#define GT64260_SDMA_INTR_MASK 0xb880 + +#define GT64260_SDMA_DESC_CMDSTAT_PE (1<<0) +#define GT64260_SDMA_DESC_CMDSTAT_CDL (1<<1) +#define GT64260_SDMA_DESC_CMDSTAT_FR (1<<3) +#define GT64260_SDMA_DESC_CMDSTAT_OR (1<<6) +#define GT64260_SDMA_DESC_CMDSTAT_BR (1<<9) +#define GT64260_SDMA_DESC_CMDSTAT_MI (1<<10) +#define GT64260_SDMA_DESC_CMDSTAT_A (1<<11) +#define GT64260_SDMA_DESC_CMDSTAT_AM (1<<12) +#define GT64260_SDMA_DESC_CMDSTAT_CT (1<<13) +#define GT64260_SDMA_DESC_CMDSTAT_C (1<<14) +#define GT64260_SDMA_DESC_CMDSTAT_ES (1<<15) +#define GT64260_SDMA_DESC_CMDSTAT_L (1<<16) +#define GT64260_SDMA_DESC_CMDSTAT_F (1<<17) +#define GT64260_SDMA_DESC_CMDSTAT_P (1<<18) +#define GT64260_SDMA_DESC_CMDSTAT_EI (1<<23) +#define GT64260_SDMA_DESC_CMDSTAT_O (1<<31) + +#define GT64260_SDMA_SDC_RFT (1<<0) +#define GT64260_SDMA_SDC_SFM (1<<1) +#define GT64260_SDMA_SDC_BLMR (1<<6) +#define GT64260_SDMA_SDC_BLMT (1<<7) +#define GT64260_SDMA_SDC_POVR (1<<8) +#define GT64260_SDMA_SDC_RIFB (1<<9) + +#define GT64260_SDMA_SDCM_ERD (1<<7) +#define GT64260_SDMA_SDCM_AR (1<<15) +#define GT64260_SDMA_SDCM_STD (1<<16) +#define GT64260_SDMA_SDCM_TXD (1<<23) +#define GT64260_SDMA_SDCM_AT (1<<31) + +#define GT64260_SDMA_0_CAUSE_RXBUF (1<<0) +#define GT64260_SDMA_0_CAUSE_RXERR (1<<1) +#define GT64260_SDMA_0_CAUSE_TXBUF (1<<2) +#define GT64260_SDMA_0_CAUSE_TXEND (1<<3) +#define GT64260_SDMA_1_CAUSE_RXBUF (1<<8) +#define GT64260_SDMA_1_CAUSE_RXERR (1<<9) +#define GT64260_SDMA_1_CAUSE_TXBUF (1<<10) +#define GT64260_SDMA_1_CAUSE_TXEND (1<<11) + + +/* + ***************************************************************************** + * + * Baud Rate Generator Interface Registers + * + ***************************************************************************** + */ + +#define GT64260_BRG_0_BCR 0xb200 +#define GT64260_BRG_0_BTR 0xb204 +#define GT64260_BRG_1_BCR 0xb208 +#define GT64260_BRG_1_BTR 0xb20c +#define GT64260_BRG_2_BCR 0xb210 +#define GT64260_BRG_2_BTR 0xb214 + +#define GT64260_BRG_INTR_CAUSE 0xb834 +#define GT64260_BRG_INTR_MASK 0xb8b4 + + +/* + ***************************************************************************** + * + * Watchdog Timer Interface Registers + * + ***************************************************************************** + */ + +#define GT64260_WDT_WDC 0xb410 +#define GT64260_WDT_WDV 0xb414 + + +/* + ***************************************************************************** + * + * General Purpose Pins Controller Interface Registers + * + ***************************************************************************** + */ + +#define GT64260_GPP_IO_CNTL 0xf100 +#define GT64260_GPP_LEVEL_CNTL 0xf110 +#define GT64260_GPP_VALUE 0xf104 +#define GT64260_GPP_INTR_CAUSE 0xf108 +#define GT64260_GPP_INTR_MASK 0xf10c + + +/* + ***************************************************************************** + * + * Multi-Purpose Pins Controller Interface Registers + * + ***************************************************************************** + */ + +#define GT64260_MPP_CNTL_0 0xf000 +#define GT64260_MPP_CNTL_1 0xf004 +#define GT64260_MPP_CNTL_2 0xf008 +#define GT64260_MPP_CNTL_3 0xf00c +#define GT64260_MPP_SERIAL_PORTS_MULTIPLEX 0xf010 + + +/* + ***************************************************************************** + * + * I2C Controller Interface Registers + * + ***************************************************************************** + */ + +/* FIXME: fill in */ + + +/* + ***************************************************************************** + * + * Interrupt Controller Interface Registers + * + ***************************************************************************** + */ + +#define GT64260_IC_MAIN_CAUSE_LO 0x0c18 +#define GT64260_IC_MAIN_CAUSE_HI 0x0c68 +#define GT64260_IC_CPU_INTR_MASK_LO 0x0c1c +#define GT64260_IC_CPU_INTR_MASK_HI 0x0c6c +#define GT64260_IC_CPU_SELECT_CAUSE 0x0c70 +#define GT64260_IC_PCI_0_INTR_MASK_LO 0x0c24 +#define GT64260_IC_PCI_0_INTR_MASK_HI 0x0c64 +#define GT64260_IC_PCI_0_SELECT_CAUSE 0x0c74 +#define GT64260_IC_PCI_1_INTR_MASK_LO 0x0ca4 +#define GT64260_IC_PCI_1_INTR_MASK_HI 0x0ce4 +#define GT64260_IC_PCI_1_SELECT_CAUSE 0x0cf4 +#define GT64260_IC_CPU_INT_0_MASK 0x0e60 +#define GT64260_IC_CPU_INT_1_MASK 0x0e64 +#define GT64260_IC_CPU_INT_2_MASK 0x0e68 +#define GT64260_IC_CPU_INT_3_MASK 0x0e6c + + +#endif /* __ASMPPC_GT64260_DEFS_H */ diff --git a/include/asm-ppc/hardirq.h b/include/asm-ppc/hardirq.h index 29522d2e0561..2c4aa69aafd4 100644 --- a/include/asm-ppc/hardirq.h +++ b/include/asm-ppc/hardirq.h @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.hardirq.h 1.12 07/10/01 11:26:58 trini + * BK Id: %F% %I% %G% %U% %#% */ #ifdef __KERNEL__ #ifndef __ASM_HARDIRQ_H @@ -51,7 +51,16 @@ typedef struct { extern unsigned char global_irq_holder; extern unsigned volatile long global_irq_lock; -extern atomic_t global_irq_count; + +static inline int irqs_running (void) +{ + int i; + + for (i = 0; i < smp_num_cpus; i++) + if (local_irq_count(i)) + return 1; + return 0; +} static inline void release_irqlock(int cpu) { @@ -67,7 +76,6 @@ static inline void hardirq_enter(int cpu) unsigned int loops = 10000000; ++local_irq_count(cpu); - atomic_inc(&global_irq_count); while (test_bit(0,&global_irq_lock)) { if (cpu == global_irq_holder) { printk("uh oh, interrupt while we hold global irq lock! (CPU %d)\n", cpu); @@ -87,13 +95,12 @@ static inline void hardirq_enter(int cpu) static inline void hardirq_exit(int cpu) { - atomic_dec(&global_irq_count); --local_irq_count(cpu); } static inline int hardirq_trylock(int cpu) { - return !atomic_read(&global_irq_count) && !test_bit(0,&global_irq_lock); + return !test_bit(0,&global_irq_lock); } #define hardirq_endlock(cpu) do { } while (0) diff --git a/include/asm-ppc/harrier.h b/include/asm-ppc/harrier.h new file mode 100644 index 000000000000..ec0f19901ff7 --- /dev/null +++ b/include/asm-ppc/harrier.h @@ -0,0 +1,102 @@ +/* + * arch/ppc/kernel/harrier.h + * + * Definitions for Motorola MCG Harrier North Bridge & Memory controller + * + * Author: Dale Farnsworth + * dale.farnsworth@mvista.com + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#ifndef __ASMPPC_HARRIER_H +#define __ASMPPC_HARRIER_H + +#include <asm/pci-bridge.h> + +#define HARRIER_VEND_DEV_ID 0x480b1057 + +/* + * Define outbound register offsets. + */ +#define HARRIER_OTAD0_OFF 0x220 +#define HARRIER_OTOF0_OFF 0x224 +#define HARRIER_OTAD1_OFF 0x228 +#define HARRIER_OTOF1_OFF 0x22c +#define HARRIER_OTAD2_OFF 0x230 +#define HARRIER_OTOF2_OFF 0x234 +#define HARRIER_OTAD3_OFF 0x238 +#define HARRIER_OTOF3_OFF 0x23c + +/* + * Define inbound register offsets. + */ +#define HARRIER_ITSZ0_OFF 0x348 +#define HARRIER_ITSZ1_OFF 0x350 +#define HARRIER_ITSZ2_OFF 0x358 +#define HARRIER_ITSZ3_OFF 0x360 + +/* + * Define the Memory Controller register offsets. + */ +#define HARRIER_SDBA_OFF 0x110 +#define HARRIER_SDBB_OFF 0x114 +#define HARRIER_SDBC_OFF 0x118 +#define HARRIER_SDBD_OFF 0x11c +#define HARRIER_SDBE_OFF 0x120 +#define HARRIER_SDBF_OFF 0x124 +#define HARRIER_SDBG_OFF 0x128 +#define HARRIER_SDBH_OFF 0x12c + +#define HARRIER_SDB_ENABLE 0x00000100 +#define HARRIER_SDB_SIZE_MASK 0xf +#define HARRIER_SDB_SIZE_SHIFT 16 +#define HARRIER_SDB_BASE_MASK 0xff +#define HARRIER_SDB_BASE_SHIFT 24 + +#define HARRIER_SERIAL_0_OFF 0xc0 + +#define HARRIER_REVI_OFF 0x05 +#define HARRIER_UCTL_OFF 0xd0 +#define HARRIER_XTAL64_MASK 0x02 + +#define HARRIER_MISC_CSR_OFF 0x1c +#define HARRIER_RSTOUT_MASK 0x01 + +#define HARRIER_MBAR_OFF 0xe0 +#define HARRIER_MPIC_CSR_OFF 0xe4 +#define HARRIER_MPIC_OPI_ENABLE 0x40 +#define HARRIER_MPIC_IFEVP_OFF 0x10200 +#define HARRIER_MPIC_IFEDE_OFF 0x10210 +#define HARRIER_FEEN_OFF 0x40 +#define HARRIER_FEST_OFF 0x44 +#define HARRIER_FEMA_OFF 0x48 + +#define HARRIER_FE_DMA 0x80 +#define HARRIER_FE_MIDB 0x40 +#define HARRIER_FE_MIM0 0x20 +#define HARRIER_FE_MIM1 0x10 +#define HARRIER_FE_MIP 0x08 +#define HARRIER_FE_UA0 0x04 +#define HARRIER_FE_UA1 0x02 +#define HARRIER_FE_ABT 0x01 + + +int harrier_init(struct pci_controller *hose, + uint ppc_reg_base, + ulong processor_pci_mem_start, + ulong processor_pci_mem_end, + ulong processor_pci_io_start, + ulong processor_pci_io_end, + ulong processor_mpic_base); + +unsigned long harrier_get_mem_size(uint smc_base); + +int harrier_mpic_init(unsigned int pci_mem_offset); + +#endif /* __ASMPPC_HARRIER_H */ diff --git a/include/asm-ppc/heathrow.h b/include/asm-ppc/heathrow.h index ba9fbbfbd114..9b202255e51f 100644 --- a/include/asm-ppc/heathrow.h +++ b/include/asm-ppc/heathrow.h @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.heathrow.h 1.7 05/17/01 18:14:24 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * heathrow.h: definitions for using the "Heathrow" I/O controller chip. @@ -17,7 +17,9 @@ #define HEATHROW_CONTRAST_CNTL 0x33 /* offset from ohare base for feature control register */ -#define HEATHROW_FEATURE_REG 0x38 +#define HEATHROW_MBCR 0x34 /* Media bay control */ +#define HEATHROW_FCR 0x38 /* Feature control */ +#define HEATHROW_AUX_CNTL_REG 0x3c /* Aux control */ /* * Bits in feature control register. @@ -30,6 +32,7 @@ #define HRW_BAY_FLOPPY_ENABLE 0x00000010 #define HRW_IDE0_ENABLE 0x00000020 #define HRW_IDE0_RESET_N 0x00000040 +#define HRW_BAY_DEV_MASK 0x0000001c #define HRW_BAY_RESET_N 0x00000080 #define HRW_IOBUS_ENABLE 0x00000100 /* Internal IDE ? */ #define HRW_SCC_ENABLE 0x00000200 @@ -45,7 +48,7 @@ #define HRW_SWIM_CLONE_FLOPPY 0x00080000 /* ??? (0) */ #define HRW_AUD_RUN22 0x00100000 /* ??? (1) */ #define HRW_SCSI_LINK_MODE 0x00200000 /* Read ??? (1) */ -#define HRW_ARB_BYPASS 0x00400000 /* ??? (0 on main, 1 on gatwick) */ +#define HRW_ARB_BYPASS 0x00400000 /* Disable internal PCI arbitrer */ #define HRW_IDE1_RESET_N 0x00800000 /* Media bay */ #define HRW_SLOW_SCC_PCLK 0x01000000 /* ??? (0) */ #define HRW_MODEM_POWER_N 0x02000000 /* Used by internal modem on wallstreet */ @@ -60,3 +63,7 @@ /* Those seem to be different on paddington */ #define PADD_MODEM_POWER_N 0x00000001 /* modem power on paddington */ #define PADD_RESET_SCC 0x02000000 /* check this please */ + +/* Looks like Heathrow has some sort of GPIOs as well... */ +#define HRW_GPIO_MODEM_RESET 0x6d + diff --git a/include/asm-ppc/highmem.h b/include/asm-ppc/highmem.h index c7d11722aa20..1e6efd66e4f7 100644 --- a/include/asm-ppc/highmem.h +++ b/include/asm-ppc/highmem.h @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.highmem.h 1.10 06/28/01 15:50:17 paulus + * BK Id: %F% %I% %G% %U% %#% */ /* * highmem.h: virtual kernel memory mappings for high memory @@ -44,13 +44,17 @@ extern void kmap_init(void) __init; * easily, subsequent pte tables have to be allocated in one physical * chunk of RAM. */ +#ifdef CONFIG_HIGHMEM_START_BOOL +#define PKMAP_BASE CONFIG_HIGHMEM_START +#else #define PKMAP_BASE (0xfe000000UL) +#endif /* CONFIG_HIGHMEM_START_BOOL */ #define LAST_PKMAP 1024 #define LAST_PKMAP_MASK (LAST_PKMAP-1) #define PKMAP_NR(virt) ((virt-PKMAP_BASE) >> PAGE_SHIFT) #define PKMAP_ADDR(nr) (PKMAP_BASE + ((nr) << PAGE_SHIFT)) -#define KMAP_FIX_BEGIN (0xfe400000UL) +#define KMAP_FIX_BEGIN (PKMAP_BASE + 0x00400000UL) extern void *kmap_high(struct page *page); extern void kunmap_high(struct page *page); diff --git a/include/asm-ppc/hw_irq.h b/include/asm-ppc/hw_irq.h index 7c9f14b63414..71112a54a79b 100644 --- a/include/asm-ppc/hw_irq.h +++ b/include/asm-ppc/hw_irq.h @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.hw_irq.h 1.10 05/17/01 18:14:24 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * Copyright (C) 1999 Cort Dougan <cort@cs.nmt.edu> @@ -10,7 +10,48 @@ extern unsigned long timer_interrupt_intercept; extern unsigned long do_IRQ_intercept; -int timer_interrupt(struct pt_regs *); +extern int timer_interrupt(struct pt_regs *); +extern void ppc_irq_dispatch_handler(struct pt_regs *regs, int irq); + +#define INLINE_IRQS + +#ifdef INLINE_IRQS + +#define mfmsr() ({unsigned int rval; \ + asm volatile("mfmsr %0" : "=r" (rval)); rval;}) +#define mtmsr(v) asm volatile("mtmsr %0" : : "r" (v)) + +#define __save_flags(flags) ((flags) = mfmsr()) +#define __restore_flags(flags) mtmsr(flags) + +static inline void __cli(void) +{ + unsigned long msr; + msr = mfmsr(); + mtmsr(msr & ~MSR_EE); + __asm__ __volatile__("": : :"memory"); +} + +static inline void __sti(void) +{ + unsigned long msr; + __asm__ __volatile__("": : :"memory"); + msr = mfmsr(); + mtmsr(msr | MSR_EE); +} + +static inline void __do_save_and_cli(unsigned long *flags) +{ + unsigned long msr; + msr = mfmsr(); + *flags = msr; + mtmsr(msr & ~MSR_EE); + __asm__ __volatile__("": : :"memory"); +} + +#define __save_and_cli(flags) __do_save_and_cli(&flags) + +#else extern void __sti(void); extern void __cli(void); @@ -21,6 +62,8 @@ extern unsigned long __sti_end, __cli_end, __restore_flags_end, __save_flags_ptr #define __save_flags(flags) __save_flags_ptr((unsigned long *)&flags) #define __save_and_cli(flags) ({__save_flags(flags);__cli();}) +#endif + extern void do_lost_interrupts(unsigned long); #define mask_irq(irq) ({if (irq_desc[irq].handler && irq_desc[irq].handler->disable) irq_desc[irq].handler->disable(irq);}) diff --git a/arch/ppc/kernel/i8259.h b/include/asm-ppc/i8259.h index c23eadfe3c95..77214fdfe1e3 100644 --- a/arch/ppc/kernel/i8259.h +++ b/include/asm-ppc/i8259.h @@ -1,15 +1,16 @@ /* - * BK Id: SCCS/s.i8259.h 1.5 05/17/01 18:14:21 cort + * BK Id: %F% %I% %G% %U% %#% */ #ifndef _PPC_KERNEL_i8259_H #define _PPC_KERNEL_i8259_H -#include "local_irq.h" +#include <linux/irq.h> extern struct hw_interrupt_type i8259_pic; -void i8259_init(void); -int i8259_irq(int); +void i8259_init(long); +int i8259_irq(void); +int i8259_poll(void); #endif /* _PPC_KERNEL_i8259_H */ diff --git a/include/asm-ppc/iSeries/HvCall.h b/include/asm-ppc/iSeries/HvCall.h new file mode 100644 index 000000000000..591c5bb8136a --- /dev/null +++ b/include/asm-ppc/iSeries/HvCall.h @@ -0,0 +1,209 @@ +/* + * HvCall.h + * Copyright (C) 2001 Mike Corrigan IBM Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +//=========================================================================== +// +// This file contains the "hypervisor call" interface which is used to +// drive the hypervisor from the OS. +// +//=========================================================================== + +//------------------------------------------------------------------- +// Standard Includes +//------------------------------------------------------------------- +#ifndef _HVCALLSC_H +#include "HvCallSc.h" +#endif + +#ifndef _HVTYPES_H +#include <asm/iSeries/HvTypes.h> +#endif + +#include <asm/iSeries/Paca.h> + +//------------------------------------------------------------------- +// Constants +//------------------------------------------------------------------- +#ifndef _HVCALL_H +#define _HVCALL_H +/* +enum HvCall_ReturnCode +{ + HvCall_Good = 0, + HvCall_Partial = 1, + HvCall_NotOwned = 2, + HvCall_NotFreed = 3, + HvCall_UnspecifiedError = 4 +}; + +enum HvCall_TypeOfSIT +{ + HvCall_ReduceOnly = 0, + HvCall_Unconditional = 1 +}; + +enum HvCall_TypeOfYield +{ + HvCall_YieldTimed = 0, // Yield until specified time + HvCall_YieldToActive = 1, // Yield until all active procs have run + HvCall_YieldToProc = 2 // Yield until the specified processor has run +}; + +enum HvCall_InterruptMasks +{ + HvCall_MaskIPI = 0x00000001, + HvCall_MaskLpEvent = 0x00000002, + HvCall_MaskLpProd = 0x00000004, + HvCall_MaskTimeout = 0x00000008 +}; + +enum HvCall_VaryOffChunkRc +{ + HvCall_VaryOffSucceeded = 0, + HvCall_VaryOffWithdrawn = 1, + HvCall_ChunkInLoadArea = 2, + HvCall_ChunkInHPT = 3, + HvCall_ChunkNotAccessible = 4, + HvCall_ChunkInUse = 5 +}; +*/ + +/* Type of yield for HvCallBaseYieldProcessor */ +#define HvCall_YieldTimed 0 // Yield until specified time (tb) +#define HvCall_YieldToActive 1 // Yield until all active procs have run +#define HvCall_YieldToProc 2 // Yield until the specified processor has run + +/* interrupt masks for setEnabledInterrupts */ +#define HvCall_MaskIPI 0x00000001 +#define HvCall_MaskLpEvent 0x00000002 +#define HvCall_MaskLpProd 0x00000004 +#define HvCall_MaskTimeout 0x00000008 + +/* Log buffer formats */ +#define HvCall_LogBuffer_ASCII 0 +#define HvCall_LogBuffer_EBCDIC 1 + +#define HvCallBaseAckDeferredInts HvCallBase + 0 +#define HvCallBaseCpmPowerOff HvCallBase + 1 +#define HvCallBaseGetHwPatch HvCallBase + 2 +#define HvCallBaseReIplSpAttn HvCallBase + 3 +#define HvCallBaseSetASR HvCallBase + 4 +#define HvCallBaseSetASRAndRfi HvCallBase + 5 +#define HvCallBaseSetIMR HvCallBase + 6 +#define HvCallBaseSendIPI HvCallBase + 7 +#define HvCallBaseTerminateMachine HvCallBase + 8 +#define HvCallBaseTerminateMachineSrc HvCallBase + 9 +#define HvCallBaseProcessPlicInterrupts HvCallBase + 10 +#define HvCallBaseIsPrimaryCpmOrMsdIpl HvCallBase + 11 +#define HvCallBaseSetVirtualSIT HvCallBase + 12 +#define HvCallBaseVaryOffThisProcessor HvCallBase + 13 +#define HvCallBaseVaryOffMemoryChunk HvCallBase + 14 +#define HvCallBaseVaryOffInteractivePercentage HvCallBase + 15 +#define HvCallBaseSendLpProd HvCallBase + 16 +#define HvCallBaseSetEnabledInterrupts HvCallBase + 17 +#define HvCallBaseYieldProcessor HvCallBase + 18 +#define HvCallBaseVaryOffSharedProcUnits HvCallBase + 19 +#define HvCallBaseSetVirtualDecr HvCallBase + 20 +#define HvCallBaseClearLogBuffer HvCallBase + 21 +#define HvCallBaseGetLogBufferCodePage HvCallBase + 22 +#define HvCallBaseGetLogBufferFormat HvCallBase + 23 +#define HvCallBaseGetLogBufferLength HvCallBase + 24 +#define HvCallBaseReadLogBuffer HvCallBase + 25 +#define HvCallBaseSetLogBufferFormatAndCodePage HvCallBase + 26 +#define HvCallBaseWriteLogBuffer HvCallBase + 27 +#define HvCallBaseRouter28 HvCallBase + 28 +#define HvCallBaseRouter29 HvCallBase + 29 +#define HvCallBaseRouter30 HvCallBase + 30 +//===================================================================================== +static inline void HvCall_setVirtualDecr(void) +{ + // Ignore any error return codes - most likely means that the target value for the + // LP has been increased and this vary off would bring us below the new target. + HvCall0(HvCallBaseSetVirtualDecr); + // getPaca()->adjustHmtForNoOfSpinLocksHeld(); +} +//===================================================================== +static inline void HvCall_yieldProcessor(unsigned typeOfYield, u64 yieldParm) +{ + HvCall2( HvCallBaseYieldProcessor, typeOfYield, yieldParm ); +} +//===================================================================== +static inline void HvCall_setEnabledInterrupts(u64 enabledInterrupts) +{ + HvCall1(HvCallBaseSetEnabledInterrupts,enabledInterrupts); + // getPaca()->adjustHmtForNoOfSpinLocksHeld(); +} + +//===================================================================== +static inline void HvCall_clearLogBuffer(HvLpIndex lpindex) +{ + HvCall1(HvCallBaseClearLogBuffer,lpindex); + // getPaca()->adjustHmtForNoOfSpinLocksHeld(); +} + +//===================================================================== +static inline u32 HvCall_getLogBufferCodePage(HvLpIndex lpindex) +{ + u32 retVal = HvCall1(HvCallBaseGetLogBufferCodePage,lpindex); + // getPaca()->adjustHmtForNoOfSpinLocksHeld(); + return retVal; +} + +//===================================================================== +static inline int HvCall_getLogBufferFormat(HvLpIndex lpindex) +{ + int retVal = HvCall1(HvCallBaseGetLogBufferFormat,lpindex); + // getPaca()->adjustHmtForNoOfSpinLocksHeld(); + return retVal; +} + +//===================================================================== +static inline u32 HvCall_getLogBufferLength(HvLpIndex lpindex) +{ + u32 retVal = HvCall1(HvCallBaseGetLogBufferLength,lpindex); + // getPaca()->adjustHmtForNoOfSpinLocksHeld(); + return retVal; +} + +//===================================================================== +static inline void HvCall_setLogBufferFormatAndCodepage(int format, u32 codePage) +{ + HvCall2(HvCallBaseSetLogBufferFormatAndCodePage,format, codePage); + // getPaca()->adjustHmtForNoOfSpinLocksHeld(); +} + +//===================================================================== +int HvCall_readLogBuffer(HvLpIndex lpindex, void *buffer, u64 bufLen); +void HvCall_writeLogBuffer(const void *buffer, u64 bufLen); + +//===================================================================== +static inline void HvCall_sendIPI(struct Paca * targetPaca) +{ + HvCall1( HvCallBaseSendIPI, targetPaca->xPacaIndex ); +} + +//===================================================================== +static inline void HvCall_terminateMachineSrc(void) +{ + HvCall0( HvCallBaseTerminateMachineSrc ); +} + + +#endif // _HVCALL_H + diff --git a/include/asm-ppc/iSeries/HvCallCfg.h b/include/asm-ppc/iSeries/HvCallCfg.h new file mode 100644 index 000000000000..45e047f1c19a --- /dev/null +++ b/include/asm-ppc/iSeries/HvCallCfg.h @@ -0,0 +1,219 @@ +/* + * HvCallCfg.h + * Copyright (C) 2001 Mike Corrigan IBM Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +//===================================================================================== +// +// This file contains the "hypervisor call" interface which is used to +// drive the hypervisor from the OS. +// +//===================================================================================== + +//------------------------------------------------------------------- +// Standard Includes +//------------------------------------------------------------------- +#ifndef _HVCALLSC_H +#include "HvCallSc.h" +#endif + +#ifndef _HVTYPES_H +#include <asm/iSeries/HvTypes.h> +#endif + +//------------------------------------------------------------------------------------- +// Constants +//------------------------------------------------------------------------------------- +#ifndef _HVCALLCFG_H +#define _HVCALLCFG_H + +enum HvCallCfg_ReqQual +{ + HvCallCfg_Cur = 0, + HvCallCfg_Init = 1, + HvCallCfg_Max = 2, + HvCallCfg_Min = 3 +}; + +#define HvCallCfgGetLps HvCallCfg + 0 +#define HvCallCfgGetActiveLpMap HvCallCfg + 1 +#define HvCallCfgGetLpVrmIndex HvCallCfg + 2 +#define HvCallCfgGetLpMinSupportedPlicVrmIndex HvCallCfg + 3 +#define HvCallCfgGetLpMinCompatablePlicVrmIndex HvCallCfg + 4 +#define HvCallCfgGetLpVrmName HvCallCfg + 5 +#define HvCallCfgGetSystemPhysicalProcessors HvCallCfg + 6 +#define HvCallCfgGetPhysicalProcessors HvCallCfg + 7 +#define HvCallCfgGetSystemMsChunks HvCallCfg + 8 +#define HvCallCfgGetMsChunks HvCallCfg + 9 +#define HvCallCfgGetInteractivePercentage HvCallCfg + 10 +#define HvCallCfgIsBusDedicated HvCallCfg + 11 +#define HvCallCfgGetBusOwner HvCallCfg + 12 +#define HvCallCfgGetBusAllocation HvCallCfg + 13 +#define HvCallCfgGetBusUnitOwner HvCallCfg + 14 +#define HvCallCfgGetBusUnitAllocation HvCallCfg + 15 +#define HvCallCfgGetVirtualBusPool HvCallCfg + 16 +#define HvCallCfgGetBusUnitInterruptProc HvCallCfg + 17 +#define HvCallCfgGetConfiguredBusUnitsForIntProc HvCallCfg + 18 +#define HvCallCfgGetRioSanBusPool HvCallCfg + 19 +#define HvCallCfgGetSharedPoolIndex HvCallCfg + 20 +#define HvCallCfgGetSharedProcUnits HvCallCfg + 21 +#define HvCallCfgGetNumProcsInSharedPool HvCallCfg + 22 +#define HvCallCfgRouter23 HvCallCfg + 23 +#define HvCallCfgRouter24 HvCallCfg + 24 +#define HvCallCfgRouter25 HvCallCfg + 25 +#define HvCallCfgRouter26 HvCallCfg + 26 +#define HvCallCfgRouter27 HvCallCfg + 27 +#define HvCallCfgGetMinRuntimeMsChunks HvCallCfg + 28 +#define HvCallCfgSetMinRuntimeMsChunks HvCallCfg + 29 +#define HvCallCfgGetVirtualLanIndexMap HvCallCfg + 30 +#define HvCallCfgGetLpExecutionMode HvCallCfg + 31 +#define HvCallCfgGetHostingLpIndex HvCallCfg + 32 + +//==================================================================== +static inline HvLpIndex HvCallCfg_getLps(void) +{ + HvLpIndex retVal = HvCall0(HvCallCfgGetLps); + // getPaca()->adjustHmtForNoOfSpinLocksHeld(); + return retVal; +} +//==================================================================== +static inline int HvCallCfg_isBusDedicated(u64 busIndex) +{ + int retVal = HvCall1(HvCallCfgIsBusDedicated,busIndex); + // getPaca()->adjustHmtForNoOfSpinLocksHeld(); + return retVal; +} +//==================================================================== +static inline HvLpIndex HvCallCfg_getBusOwner(u64 busIndex) +{ + HvLpIndex retVal = HvCall1(HvCallCfgGetBusOwner,busIndex); + // getPaca()->adjustHmtForNoOfSpinLocksHeld(); + return retVal; +} +//==================================================================== +static inline HvLpIndexMap HvCallCfg_getBusAllocation(u64 busIndex) +{ + HvLpIndexMap retVal = HvCall1(HvCallCfgGetBusAllocation,busIndex); + // getPaca()->adjustHmtForNoOfSpinLocksHeld(); + return retVal; +} +//==================================================================== +static inline HvLpIndexMap HvCallCfg_getActiveLpMap(void) +{ + HvLpIndexMap retVal = HvCall0(HvCallCfgGetActiveLpMap); + // getPaca()->adjustHmtForNoOfSpinLocksHeld(); + return retVal; +} +//==================================================================== +static inline HvLpVirtualLanIndexMap HvCallCfg_getVirtualLanIndexMap(HvLpIndex lp) +{ + // This is a new function in V5R1 so calls to this on older + // hypervisors will return -1 + u64 retVal = HvCall1(HvCallCfgGetVirtualLanIndexMap, lp); + if(retVal == -1) + retVal = 0; + // getPaca()->adjustHmtForNoOfSpinLocksHeld(); + return retVal; +} +//=================================================================== +static inline u64 HvCallCfg_getSystemMsChunks(void) +{ + u64 retVal = HvCall0(HvCallCfgGetSystemMsChunks); + // getPaca()->adjustHmtForNoOfSpinLocksHeld(); + return retVal; +} +//=================================================================== +static inline u64 HvCallCfg_getMsChunks(HvLpIndex lp,enum HvCallCfg_ReqQual qual) +{ + u64 retVal = HvCall2(HvCallCfgGetMsChunks,lp,qual); + // getPaca()->adjustHmtForNoOfSpinLocksHeld(); + return retVal; +} +//=================================================================== +static inline u64 HvCallCfg_getMinRuntimeMsChunks(HvLpIndex lp) +{ + // NOTE: This function was added in v5r1 so older hypervisors will return a -1 value + u64 retVal = HvCall1(HvCallCfgGetMinRuntimeMsChunks,lp); + // getPaca()->adjustHmtForNoOfSpinLocksHeld(); + return retVal; +} +//=================================================================== +static inline u64 HvCallCfg_setMinRuntimeMsChunks(u64 chunks) +{ + u64 retVal = HvCall1(HvCallCfgSetMinRuntimeMsChunks,chunks); + // getPaca()->adjustHmtForNoOfSpinLocksHeld(); + return retVal; +} +//=================================================================== +static inline u64 HvCallCfg_getSystemPhysicalProcessors(void) +{ + u64 retVal = HvCall0(HvCallCfgGetSystemPhysicalProcessors); + // getPaca()->adjustHmtForNoOfSpinLocksHeld(); + return retVal; +} +//=================================================================== +static inline u64 HvCallCfg_getPhysicalProcessors(HvLpIndex lp,enum HvCallCfg_ReqQual qual) +{ + u64 retVal = HvCall2(HvCallCfgGetPhysicalProcessors,lp,qual); + // getPaca()->adjustHmtForNoOfSpinLocksHeld(); + return retVal; +} +//=================================================================== +static inline u64 HvCallCfg_getConfiguredBusUnitsForInterruptProc(HvLpIndex lp, + u16 hvLogicalProcIndex) +{ + u64 retVal = HvCall2(HvCallCfgGetConfiguredBusUnitsForIntProc,lp,hvLogicalProcIndex); + // getPaca()->adjustHmtForNoOfSpinLocksHeld(); + return retVal; + +} +//================================================================== +static inline HvLpSharedPoolIndex HvCallCfg_getSharedPoolIndex(HvLpIndex lp) +{ + HvLpSharedPoolIndex retVal = + HvCall1(HvCallCfgGetSharedPoolIndex,lp); + // getPaca()->adjustHmtForNoOfSpinLocksHeld(); + return retVal; + +} +//================================================================== +static inline u64 HvCallCfg_getSharedProcUnits(HvLpIndex lp,enum HvCallCfg_ReqQual qual) +{ + u64 retVal = HvCall2(HvCallCfgGetSharedProcUnits,lp,qual); + // getPaca()->adjustHmtForNoOfSpinLocksHeld(); + return retVal; + +} +//================================================================== +static inline u64 HvCallCfg_getNumProcsInSharedPool(HvLpSharedPoolIndex sPI) +{ + u16 retVal = HvCall1(HvCallCfgGetNumProcsInSharedPool,sPI); + // getPaca()->adjustHmtForNoOfSpinLocksHeld(); + return retVal; + +} +//================================================================== +static inline HvLpIndex HvCallCfg_getHostingLpIndex(HvLpIndex lp) +{ + u64 retVal = HvCall1(HvCallCfgGetHostingLpIndex,lp); + // getPaca()->adjustHmtForNoOfSpinLocksHeld(); + return retVal; + +} + +#endif // _HVCALLCFG_H + diff --git a/include/asm-ppc/iSeries/HvCallEvent.h b/include/asm-ppc/iSeries/HvCallEvent.h new file mode 100644 index 000000000000..8efce370fea3 --- /dev/null +++ b/include/asm-ppc/iSeries/HvCallEvent.h @@ -0,0 +1,328 @@ +/* + * HvCallEvent.h + * Copyright (C) 2001 Mike Corrigan IBM Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +//================================================================== +// +// This file contains the "hypervisor call" interface which is used to +// drive the hypervisor from the OS. +// +//================================================================== + +//------------------------------------------------------------------- +// Standard Includes +//------------------------------------------------------------------- +#ifndef _HVCALLSC_H +#include <asm/iSeries/HvCallSc.h> +#endif + +#ifndef _HVTYPES_H +#include <asm/iSeries/HvTypes.h> +#endif + +#include <asm/iSeries/LparData.h> + +//------------------------------------------------------------------- +// Constants +//------------------------------------------------------------------- +#ifndef _HVCALLEVENT_H +#define _HVCALLEVENT_H + +struct HvLpEvent; + +typedef u8 HvLpEvent_Type; +typedef u8 HvLpEvent_AckInd; +typedef u8 HvLpEvent_AckType; + +struct HvCallEvent_PackedParms +{ + u8 xAckType:1; + u8 xAckInd:1; + u8 xRsvd:1; + u8 xTargetLp:5; + u8 xType; + u16 xSubtype; + HvLpInstanceId xSourceInstId; + HvLpInstanceId xTargetInstId; +}; + +typedef u8 HvLpDma_Direction; +typedef u8 HvLpDma_AddressType; + +struct HvCallEvent_PackedDmaParms +{ + u8 xDirection:1; + u8 xLocalAddrType:1; + u8 xRemoteAddrType:1; + u8 xRsvd1:5; + HvLpIndex xRemoteLp; + u8 xType; + u8 xRsvd2; + HvLpInstanceId xLocalInstId; + HvLpInstanceId xRemoteInstId; +}; + +typedef u64 HvLpEvent_Rc; +typedef u64 HvLpDma_Rc; + +#define HvCallEventAckLpEvent HvCallEvent + 0 +#define HvCallEventCancelLpEvent HvCallEvent + 1 +#define HvCallEventCloseLpEventPath HvCallEvent + 2 +#define HvCallEventDmaBufList HvCallEvent + 3 +#define HvCallEventDmaSingle HvCallEvent + 4 +#define HvCallEventDmaToSp HvCallEvent + 5 +#define HvCallEventGetOverflowLpEvents HvCallEvent + 6 +#define HvCallEventGetSourceLpInstanceId HvCallEvent + 7 +#define HvCallEventGetTargetLpInstanceId HvCallEvent + 8 +#define HvCallEventOpenLpEventPath HvCallEvent + 9 +#define HvCallEventSetLpEventStack HvCallEvent + 10 +#define HvCallEventSignalLpEvent HvCallEvent + 11 +#define HvCallEventSignalLpEventParms HvCallEvent + 12 +#define HvCallEventSetInterLpQueueIndex HvCallEvent + 13 +#define HvCallEventSetLpEventQueueInterruptProc HvCallEvent + 14 +#define HvCallEventRouter15 HvCallEvent + 15 + +//====================================================================== +static inline void HvCallEvent_getOverflowLpEvents(u8 queueIndex) +{ + HvCall1(HvCallEventGetOverflowLpEvents,queueIndex); + // getPaca()->adjustHmtForNoOfSpinLocksHeld(); +} +//====================================================================== +static inline void HvCallEvent_setInterLpQueueIndex(u8 queueIndex) +{ + HvCall1(HvCallEventSetInterLpQueueIndex,queueIndex); + // getPaca()->adjustHmtForNoOfSpinLocksHeld(); +} +//====================================================================== +static inline void HvCallEvent_setLpEventStack(u8 queueIndex, + char * eventStackAddr, + u32 eventStackSize) +{ + u64 abs_addr; + abs_addr = virt_to_absolute_outline( (unsigned long) eventStackAddr ); + + HvCall3(HvCallEventSetLpEventStack, queueIndex, abs_addr, eventStackSize); + // getPaca()->adjustHmtForNoOfSpinLocksHeld(); +} +//====================================================================== +static inline void HvCallEvent_setLpEventQueueInterruptProc(u8 queueIndex, + u16 lpLogicalProcIndex) +{ + HvCall2(HvCallEventSetLpEventQueueInterruptProc,queueIndex,lpLogicalProcIndex); + // getPaca()->adjustHmtForNoOfSpinLocksHeld(); +} +//===================================================================== +static inline HvLpEvent_Rc HvCallEvent_signalLpEvent(struct HvLpEvent* event) +{ + u64 abs_addr; + HvLpEvent_Rc retVal; + abs_addr = virt_to_absolute_outline( (unsigned long) event ); + retVal = (HvLpEvent_Rc)HvCall1(HvCallEventSignalLpEvent, abs_addr); + // getPaca()->adjustHmtForNoOfSpinLocksHeld(); + return retVal; +} +//===================================================================== +static inline HvLpEvent_Rc HvCallEvent_signalLpEventFast(HvLpIndex targetLp, + HvLpEvent_Type type, + u16 subtype, + HvLpEvent_AckInd ackInd, + HvLpEvent_AckType ackType, + HvLpInstanceId sourceInstanceId, + HvLpInstanceId targetInstanceId, + u64 correlationToken, + u64 eventData1, + u64 eventData2, + u64 eventData3, + u64 eventData4, + u64 eventData5) +{ + HvLpEvent_Rc retVal; + + // Pack the misc bits into a single Dword to pass to PLIC + union + { + struct HvCallEvent_PackedParms parms; + u64 dword; + } packed; + packed.parms.xAckType = ackType; + packed.parms.xAckInd = ackInd; + packed.parms.xRsvd = 0; + packed.parms.xTargetLp = targetLp; + packed.parms.xType = type; + packed.parms.xSubtype = subtype; + packed.parms.xSourceInstId = sourceInstanceId; + packed.parms.xTargetInstId = targetInstanceId; + + retVal = (HvLpEvent_Rc)HvCall7(HvCallEventSignalLpEventParms, + packed.dword, + correlationToken, + eventData1,eventData2, + eventData3,eventData4, + eventData5); + // getPaca()->adjustHmtForNoOfSpinLocksHeld(); + return retVal; +} +//==================================================================== +static inline HvLpEvent_Rc HvCallEvent_ackLpEvent(struct HvLpEvent* event) +{ + u64 abs_addr; + HvLpEvent_Rc retVal; + abs_addr = virt_to_absolute_outline( (unsigned long) event ); + + retVal = (HvLpEvent_Rc)HvCall1(HvCallEventAckLpEvent, abs_addr); + // getPaca()->adjustHmtForNoOfSpinLocksHeld(); + return retVal; +} +//==================================================================== +static inline HvLpEvent_Rc HvCallEvent_cancelLpEvent(struct HvLpEvent* event) +{ + u64 abs_addr; + HvLpEvent_Rc retVal; + abs_addr = virt_to_absolute_outline( (unsigned long) event ); + + retVal = (HvLpEvent_Rc)HvCall1(HvCallEventCancelLpEvent, abs_addr); + // getPaca()->adjustHmtForNoOfSpinLocksHeld(); + return retVal; +} +//=================================================================== +static inline HvLpInstanceId HvCallEvent_getSourceLpInstanceId(HvLpIndex targetLp, HvLpEvent_Type type) +{ + HvLpInstanceId retVal; + retVal = HvCall2(HvCallEventGetSourceLpInstanceId,targetLp,type); + // getPaca()->adjustHmtForNoOfSpinLocksHeld(); + return retVal; +} +//=================================================================== +static inline HvLpInstanceId HvCallEvent_getTargetLpInstanceId(HvLpIndex targetLp, HvLpEvent_Type type) +{ + HvLpInstanceId retVal; + retVal = HvCall2(HvCallEventGetTargetLpInstanceId,targetLp,type); + // getPaca()->adjustHmtForNoOfSpinLocksHeld(); + return retVal; +} +//=================================================================== +static inline void HvCallEvent_openLpEventPath(HvLpIndex targetLp, + HvLpEvent_Type type) +{ + HvCall2(HvCallEventOpenLpEventPath,targetLp,type); + // getPaca()->adjustHmtForNoOfSpinLocksHeld(); +} +//=================================================================== +static inline void HvCallEvent_closeLpEventPath(HvLpIndex targetLp, + HvLpEvent_Type type) +{ + HvCall2(HvCallEventCloseLpEventPath,targetLp,type); + // getPaca()->adjustHmtForNoOfSpinLocksHeld(); +} +//=================================================================== +static inline HvLpDma_Rc HvCallEvent_dmaBufList(HvLpEvent_Type type, + HvLpIndex remoteLp, + HvLpDma_Direction direction, + HvLpInstanceId localInstanceId, + HvLpInstanceId remoteInstanceId, + HvLpDma_AddressType localAddressType, + HvLpDma_AddressType remoteAddressType, + // Do these need to be converted to + // absolute addresses? + u64 localBufList, + u64 remoteBufList, + + u32 transferLength) +{ + HvLpDma_Rc retVal; + // Pack the misc bits into a single Dword to pass to PLIC + union + { + struct HvCallEvent_PackedDmaParms parms; + u64 dword; + } packed; + packed.parms.xDirection = direction; + packed.parms.xLocalAddrType = localAddressType; + packed.parms.xRemoteAddrType = remoteAddressType; + packed.parms.xRsvd1 = 0; + packed.parms.xRemoteLp = remoteLp; + packed.parms.xType = type; + packed.parms.xRsvd2 = 0; + packed.parms.xLocalInstId = localInstanceId; + packed.parms.xRemoteInstId = remoteInstanceId; + + retVal = (HvLpDma_Rc)HvCall4(HvCallEventDmaBufList, + packed.dword, + localBufList, + remoteBufList, + transferLength); + // getPaca()->adjustHmtForNoOfSpinLocksHeld(); + return retVal; +} +//================================================================= +static inline HvLpDma_Rc HvCallEvent_dmaSingle(HvLpEvent_Type type, + HvLpIndex remoteLp, + HvLpDma_Direction direction, + HvLpInstanceId localInstanceId, + HvLpInstanceId remoteInstanceId, + HvLpDma_AddressType localAddressType, + HvLpDma_AddressType remoteAddressType, + u64 localAddrOrTce, + u64 remoteAddrOrTce, + u32 transferLength) +{ + HvLpDma_Rc retVal; + // Pack the misc bits into a single Dword to pass to PLIC + union + { + struct HvCallEvent_PackedDmaParms parms; + u64 dword; + } packed; + packed.parms.xDirection = direction; + packed.parms.xLocalAddrType = localAddressType; + packed.parms.xRemoteAddrType = remoteAddressType; + packed.parms.xRsvd1 = 0; + packed.parms.xRemoteLp = remoteLp; + packed.parms.xType = type; + packed.parms.xRsvd2 = 0; + packed.parms.xLocalInstId = localInstanceId; + packed.parms.xRemoteInstId = remoteInstanceId; + + retVal = (HvLpDma_Rc)HvCall4(HvCallEventDmaSingle, + packed.dword, + localAddrOrTce, + remoteAddrOrTce, + transferLength); + // getPaca()->adjustHmtForNoOfSpinLocksHeld(); + return retVal; +} +//================================================================= +static inline HvLpDma_Rc HvCallEvent_dmaToSp(void* local, u32 remote, u32 length, HvLpDma_Direction dir) +{ + u64 abs_addr; + HvLpDma_Rc retVal; + abs_addr = virt_to_absolute_outline( (unsigned long) local ); + + retVal = (HvLpDma_Rc)HvCall4(HvCallEventDmaToSp, + abs_addr, + remote, + length, + dir); + // getPaca()->adjustHmtForNoOfSpinLocksHeld(); + return retVal; +} +//================================================================ + +#endif // _HVCALLEVENT_H + diff --git a/include/asm-ppc/iSeries/HvCallHpt.h b/include/asm-ppc/iSeries/HvCallHpt.h new file mode 100644 index 000000000000..29757bf6fe1f --- /dev/null +++ b/include/asm-ppc/iSeries/HvCallHpt.h @@ -0,0 +1,137 @@ +/* + * HvCallHpt.h + * Copyright (C) 2001 Mike Corrigan IBM Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +//============================================================================ +// +// This file contains the "hypervisor call" interface which is used to +// drive the hypervisor from the OS. +// +//============================================================================ + +//------------------------------------------------------------------- +// Standard Includes +//------------------------------------------------------------------- +#ifndef _HVCALLSC_H +#include "HvCallSc.h" +#endif + +#ifndef _HVTYPES_H +#include <asm/iSeries/HvTypes.h> +#endif + +//------------------------------------------------------------------- +// Other Includes +//------------------------------------------------------------------- + +#ifndef _PPC_MMU_H +#include <asm/mmu.h> +#endif + +//----------------------------------------------------------------------------- +// Constants +//----------------------------------------------------------------------------- +#ifndef _HVCALLHPT_H +#define _HVCALLHPT_H + +#define HvCallHptGetHptAddress HvCallHpt + 0 +#define HvCallHptGetHptPages HvCallHpt + 1 +#define HvCallHptSetPp HvCallHpt + 5 +#define HvCallHptUpdate HvCallHpt + 7 +#define HvCallHptInvalidateNoSyncICache HvCallHpt + 8 +#define HvCallHptGet HvCallHpt + 11 +#define HvCallHptFindNextValid HvCallHpt + 12 +#define HvCallHptFindValid HvCallHpt + 13 +#define HvCallHptAddValidate HvCallHpt + 16 +#define HvCallHptInvalidateSetSwBitsGet HvCallHpt + 18 + + + +//============================================================================ +static inline u64 HvCallHpt_getHptAddress(void) +{ + u64 retval = HvCall0(HvCallHptGetHptAddress); + // getPaca()->adjustHmtForNoOfSpinLocksHeld(); + return retval; +} +//============================================================================ +static inline u64 HvCallHpt_getHptPages(void) +{ + u64 retval = HvCall0(HvCallHptGetHptPages); + // getPaca()->adjustHmtForNoOfSpinLocksHeld(); + return retval; +} +//============================================================================= +static inline void HvCallHpt_setPp(u32 hpteIndex, u8 value) +{ + HvCall2( HvCallHptSetPp, hpteIndex, value ); + // getPaca()->adjustHmtForNoOfSpinLocksHeld(); +} +//============================================================================= +static inline void HvCallHpt_invalidateNoSyncICache(u32 hpteIndex) + +{ + HvCall1( HvCallHptInvalidateNoSyncICache, hpteIndex ); + // getPaca()->adjustHmtForNoOfSpinLocksHeld(); +} +//============================================================================= +static inline u64 HvCallHpt_invalidateSetSwBitsGet(u32 hpteIndex, u8 bitson, u8 bitsoff ) + +{ + u64 compressedStatus; + compressedStatus = HvCall4( HvCallHptInvalidateSetSwBitsGet, hpteIndex, bitson, bitsoff, 1 ); + // getPaca()->adjustHmtForNoOfSpinLocksHeld(); + return compressedStatus; +} +//============================================================================= +static inline u64 HvCallHpt_findValid( PTE *hpte, u64 vpn ) +{ + u64 retIndex = HvCall1Ret16( HvCallHptFindValid, hpte, vpn ); + // getPaca()->adjustHmtForNoOfSpinLocksHeld(); + return retIndex; +} +//============================================================================= +static inline u64 HvCallHpt_findNextValid( PTE *hpte, u32 hpteIndex, u8 bitson, u8 bitsoff ) +{ + u64 retIndex = HvCall3Ret16( HvCallHptFindNextValid, hpte, hpteIndex, bitson, bitsoff ); + // getPaca()->adjustHmtForNoOfSpinLocksHeld(); + return retIndex; +} +//============================================================================= +static inline void HvCallHpt_get( PTE *hpte, u32 hpteIndex ) +{ + HvCall2Ret16( HvCallHptFindValid, hpte, hpteIndex, 0 ); + // getPaca()->adjustHmtForNoOfSpinLocksHeld(); +} + +//============================================================================ +static inline void HvCallHpt_addValidate( u32 hpteIndex, + u32 hBit, + PTE *hpte ) + +{ + HvCall4( HvCallHptAddValidate, hpteIndex, + hBit, (*((u64 *)hpte)), (*(((u64 *)hpte)+1)) ); + // getPaca()->adjustHmtForNoOfSpinLocksHeld(); +} + + +//============================================================================= + +#endif // _HVCALLHPT_H + diff --git a/include/asm-ppc/iSeries/HvCallPci.h b/include/asm-ppc/iSeries/HvCallPci.h new file mode 100644 index 000000000000..0569bf09fb5f --- /dev/null +++ b/include/asm-ppc/iSeries/HvCallPci.h @@ -0,0 +1,689 @@ +/************************************************************************/ +/* Provides the Hypervisor PCI calls for iSeries Linux Parition. */ +/* Copyright (C) 20yy <Wayne G Holm> <IBM Corporation> */ +/* */ +/* This program is free software; you can redistribute it and/or modify */ +/* it under the terms of the GNU General Public License as published by */ +/* the Free Software Foundation; either version 2 of the License, or */ +/* (at your option) any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, */ +/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ +/* GNU General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU General Public License */ +/* along with this program; if not, write to the: */ +/* Free Software Foundation, Inc., */ +/* 59 Temple Place, Suite 330, */ +/* Boston, MA 02111-1307 USA */ +/************************************************************************/ +/* Change Activity: */ +/* Created, Jan 9, 2001 */ +/************************************************************************/ +//============================================================================ +// Header File Id +// Name______________: HvCallPci.H +// +// Description_______: +// +// This file contains the "hypervisor call" interface which is used to +// drive the hypervisor from SLIC. +// +//============================================================================ + +//------------------------------------------------------------------- +// Forward declarations +//------------------------------------------------------------------- + +//------------------------------------------------------------------- +// Standard Includes +//------------------------------------------------------------------- +#ifndef _HVCALLSC_H +#include "HvCallSc.h" +#endif + +#ifndef _HVTYPES_H +#include <asm/as400/HvTypes.h> +#endif + +//------------------------------------------------------------------- +// Other Includes +//------------------------------------------------------------------- + + +//----------------------------------------------------------------------------- +// Constants +//----------------------------------------------------------------------------- +#ifndef _HVCALLPCI_H +#define _HVCALLPCI_H + +struct HvCallPci_DsaAddr { // make sure this struct size is 64-bits total + u16 busNumber; + u8 subBusNumber; + u8 deviceId; + u8 barNumber; + u8 reserved[3]; +}; + +struct HvCallPci_LoadReturn { + u64 rc; + u64 value; +}; + +enum HvCallPci_DeviceType {HvCallPci_NodeDevice = 1, + HvCallPci_SpDevice = 2, + HvCallPci_IopDevice = 3, + HvCallPci_BridgeDevice = 4, + HvCallPci_MultiFunctionDevice = 5, + HvCallPci_IoaDevice = 6 +}; + + +struct HvCallPci_DeviceInfo { + u32 deviceType; // See DeviceType enum for values +}; + +struct HvCallPci_BusUnitInfo { + u32 sizeReturned; // length of data returned + u32 deviceType; // see DeviceType enum for values +}; + +struct HvCallPci_BridgeInfo { + struct HvCallPci_BusUnitInfo busUnitInfo; // Generic bus unit info + u8 subBusNumber; // Bus number of secondary bus + u8 maxAgents; // Max idsels on secondary bus +}; + + +// Maximum BusUnitInfo buffer size. Provided for clients so they can allocate +// a buffer big enough for any type of bus unit. Increase as needed. +enum {HvCallPci_MaxBusUnitInfoSize = 128}; + +struct HvCallPci_BarParms { + u64 vaddr; + u64 raddr; + u64 size; + u64 protectStart; + u64 protectEnd; + u64 relocationOffset; + u64 pciAddress; + u64 reserved[3]; +}; + +enum HvCallPci_VpdType { + HvCallPci_BusVpd = 1, + HvCallPci_BusAdapterVpd = 2 +}; + +#define HvCallPciConfigLoad8 HvCallPci + 0 +#define HvCallPciConfigLoad16 HvCallPci + 1 +#define HvCallPciConfigLoad32 HvCallPci + 2 +#define HvCallPciConfigStore8 HvCallPci + 3 +#define HvCallPciConfigStore16 HvCallPci + 4 +#define HvCallPciConfigStore32 HvCallPci + 5 +#define HvCallPciEoi HvCallPci + 16 +#define HvCallPciGetBarParms HvCallPci + 18 +#define HvCallPciMaskFisr HvCallPci + 20 +#define HvCallPciUnmaskFisr HvCallPci + 21 +#define HvCallPciSetSlotReset HvCallPci + 25 +#define HvCallPciGetDeviceInfo HvCallPci + 27 +#define HvCallPciGetCardVpd HvCallPci + 28 +#define HvCallPciBarLoad8 HvCallPci + 40 +#define HvCallPciBarLoad16 HvCallPci + 41 +#define HvCallPciBarLoad32 HvCallPci + 42 +#define HvCallPciBarLoad64 HvCallPci + 43 +#define HvCallPciBarStore8 HvCallPci + 44 +#define HvCallPciBarStore16 HvCallPci + 45 +#define HvCallPciBarStore32 HvCallPci + 46 +#define HvCallPciBarStore64 HvCallPci + 47 +#define HvCallPciMaskInterrupts HvCallPci + 48 +#define HvCallPciUnmaskInterrupts HvCallPci + 49 +#define HvCallPciGetBusUnitInfo HvCallPci + 50 + +//============================================================================ +static inline u64 HvCallPci_configLoad8(u16 busNumber, u8 subBusNumber, + u8 deviceId, u32 offset, + u8 *value) +{ + struct HvCallPci_DsaAddr dsa; + struct HvCallPci_LoadReturn retVal; + + *((u64*)&dsa) = 0; + + dsa.busNumber = busNumber; + dsa.subBusNumber = subBusNumber; + dsa.deviceId = deviceId; + + HvCall3Ret16(HvCallPciConfigLoad8, &retVal, *(u64 *)&dsa, offset, 0); + + // getPaca()->adjustHmtForNoOfSpinLocksHeld(); + + *value = retVal.value; + + return retVal.rc; +} +//============================================================================ +static inline u64 HvCallPci_configLoad16(u16 busNumber, u8 subBusNumber, + u8 deviceId, u32 offset, + u16 *value) +{ + struct HvCallPci_DsaAddr dsa; + struct HvCallPci_LoadReturn retVal; + + *((u64*)&dsa) = 0; + + dsa.busNumber = busNumber; + dsa.subBusNumber = subBusNumber; + dsa.deviceId = deviceId; + + HvCall3Ret16(HvCallPciConfigLoad16, &retVal, *(u64 *)&dsa, offset, 0); + + // getPaca()->adjustHmtForNoOfSpinLocksHeld(); + + *value = retVal.value; + + return retVal.rc; +} +//============================================================================ +static inline u64 HvCallPci_configLoad32(u16 busNumber, u8 subBusNumber, + u8 deviceId, u32 offset, + u32 *value) +{ + struct HvCallPci_DsaAddr dsa; + struct HvCallPci_LoadReturn retVal; + + *((u64*)&dsa) = 0; + + dsa.busNumber = busNumber; + dsa.subBusNumber = subBusNumber; + dsa.deviceId = deviceId; + + HvCall3Ret16(HvCallPciConfigLoad32, &retVal, *(u64 *)&dsa, offset, 0); + + // getPaca()->adjustHmtForNoOfSpinLocksHeld(); + + *value = retVal.value; + + return retVal.rc; +} +//============================================================================ +static inline u64 HvCallPci_configStore8(u16 busNumber, u8 subBusNumber, + u8 deviceId, u32 offset, + u8 value) +{ + struct HvCallPci_DsaAddr dsa; + u64 retVal; + + *((u64*)&dsa) = 0; + + dsa.busNumber = busNumber; + dsa.subBusNumber = subBusNumber; + dsa.deviceId = deviceId; + + retVal = HvCall4(HvCallPciConfigStore8, *(u64 *)&dsa, offset, value, 0); + + // getPaca()->adjustHmtForNoOfSpinLocksHeld(); + + return retVal; +} +//============================================================================ +static inline u64 HvCallPci_configStore16(u16 busNumber, u8 subBusNumber, + u8 deviceId, u32 offset, + u16 value) +{ + struct HvCallPci_DsaAddr dsa; + u64 retVal; + + *((u64*)&dsa) = 0; + + dsa.busNumber = busNumber; + dsa.subBusNumber = subBusNumber; + dsa.deviceId = deviceId; + + retVal = HvCall4(HvCallPciConfigStore16, *(u64 *)&dsa, offset, value, 0); + + // getPaca()->adjustHmtForNoOfSpinLocksHeld(); + + return retVal; +} +//============================================================================ +static inline u64 HvCallPci_configStore32(u16 busNumber, u8 subBusNumber, + u8 deviceId, u32 offset, + u32 value) +{ + struct HvCallPci_DsaAddr dsa; + u64 retVal; + + *((u64*)&dsa) = 0; + + dsa.busNumber = busNumber; + dsa.subBusNumber = subBusNumber; + dsa.deviceId = deviceId; + + retVal = HvCall4(HvCallPciConfigStore32, *(u64 *)&dsa, offset, value, 0); + + // getPaca()->adjustHmtForNoOfSpinLocksHeld(); + + return retVal; +} +//============================================================================ +static inline u64 HvCallPci_barLoad8(u16 busNumberParm, + u8 subBusParm, + u8 deviceIdParm, + u8 barNumberParm, + u64 offsetParm, + u8* valueParm) +{ + struct HvCallPci_DsaAddr dsa; + struct HvCallPci_LoadReturn retVal; + + *((u64*)&dsa) = 0; + + dsa.busNumber = busNumberParm; + dsa.subBusNumber = subBusParm; + dsa.deviceId = deviceIdParm; + dsa.barNumber = barNumberParm; + + HvCall3Ret16(HvCallPciBarLoad8, &retVal, *(u64 *)&dsa, offsetParm, 0); + + // getPaca()->adjustHmtForNoOfSpinLocksHeld(); + + *valueParm = retVal.value; + + return retVal.rc; +} +//============================================================================ +static inline u64 HvCallPci_barLoad16(u16 busNumberParm, + u8 subBusParm, + u8 deviceIdParm, + u8 barNumberParm, + u64 offsetParm, + u16* valueParm) +{ + struct HvCallPci_DsaAddr dsa; + struct HvCallPci_LoadReturn retVal; + + *((u64*)&dsa) = 0; + + dsa.busNumber = busNumberParm; + dsa.subBusNumber = subBusParm; + dsa.deviceId = deviceIdParm; + dsa.barNumber = barNumberParm; + + HvCall3Ret16(HvCallPciBarLoad16, &retVal, *(u64 *)&dsa, offsetParm, 0); + + // getPaca()->adjustHmtForNoOfSpinLocksHeld(); + + *valueParm = retVal.value; + + return retVal.rc; +} +//============================================================================ +static inline u64 HvCallPci_barLoad32(u16 busNumberParm, + u8 subBusParm, + u8 deviceIdParm, + u8 barNumberParm, + u64 offsetParm, + u32* valueParm) +{ + struct HvCallPci_DsaAddr dsa; + struct HvCallPci_LoadReturn retVal; + + *((u64*)&dsa) = 0; + + dsa.busNumber = busNumberParm; + dsa.subBusNumber = subBusParm; + dsa.deviceId = deviceIdParm; + dsa.barNumber = barNumberParm; + + HvCall3Ret16(HvCallPciBarLoad32, &retVal, *(u64 *)&dsa, offsetParm, 0); + + // getPaca()->adjustHmtForNoOfSpinLocksHeld(); + + *valueParm = retVal.value; + + return retVal.rc; +} +//============================================================================ +static inline u64 HvCallPci_barLoad64(u16 busNumberParm, + u8 subBusParm, + u8 deviceIdParm, + u8 barNumberParm, + u64 offsetParm, + u64* valueParm) +{ + struct HvCallPci_DsaAddr dsa; + struct HvCallPci_LoadReturn retVal; + + *((u64*)&dsa) = 0; + + dsa.busNumber = busNumberParm; + dsa.subBusNumber = subBusParm; + dsa.deviceId = deviceIdParm; + dsa.barNumber = barNumberParm; + + HvCall3Ret16(HvCallPciBarLoad64, &retVal, *(u64 *)&dsa, offsetParm, 0); + + // getPaca()->adjustHmtForNoOfSpinLocksHeld(); + + *valueParm = retVal.value; + + return retVal.rc; +} +//============================================================================ +static inline u64 HvCallPci_barStore8(u16 busNumberParm, + u8 subBusParm, + u8 deviceIdParm, + u8 barNumberParm, + u64 offsetParm, + u8 valueParm) +{ + struct HvCallPci_DsaAddr dsa; + u64 retVal; + + *((u64*)&dsa) = 0; + + dsa.busNumber = busNumberParm; + dsa.subBusNumber = subBusParm; + dsa.deviceId = deviceIdParm; + dsa.barNumber = barNumberParm; + + retVal = HvCall4(HvCallPciBarStore8, *(u64 *)&dsa, offsetParm, valueParm, 0); + + // getPaca()->adjustHmtForNoOfSpinLocksHeld(); + + return retVal; +} +//============================================================================ +static inline u64 HvCallPci_barStore16(u16 busNumberParm, + u8 subBusParm, + u8 deviceIdParm, + u8 barNumberParm, + u64 offsetParm, + u16 valueParm) +{ + struct HvCallPci_DsaAddr dsa; + u64 retVal; + + *((u64*)&dsa) = 0; + + dsa.busNumber = busNumberParm; + dsa.subBusNumber = subBusParm; + dsa.deviceId = deviceIdParm; + dsa.barNumber = barNumberParm; + + retVal = HvCall4(HvCallPciBarStore16, *(u64 *)&dsa, offsetParm, valueParm, 0); + + // getPaca()->adjustHmtForNoOfSpinLocksHeld(); + + return retVal; +} +//============================================================================ +static inline u64 HvCallPci_barStore32(u16 busNumberParm, + u8 subBusParm, + u8 deviceIdParm, + u8 barNumberParm, + u64 offsetParm, + u32 valueParm) +{ + struct HvCallPci_DsaAddr dsa; + u64 retVal; + + *((u64*)&dsa) = 0; + + dsa.busNumber = busNumberParm; + dsa.subBusNumber = subBusParm; + dsa.deviceId = deviceIdParm; + dsa.barNumber = barNumberParm; + + retVal = HvCall4(HvCallPciBarStore32, *(u64 *)&dsa, offsetParm, valueParm, 0); + + // getPaca()->adjustHmtForNoOfSpinLocksHeld(); + + return retVal; +} +//============================================================================ +static inline u64 HvCallPci_barStore64(u16 busNumberParm, + u8 subBusParm, + u8 deviceIdParm, + u8 barNumberParm, + u64 offsetParm, + u64 valueParm) +{ + struct HvCallPci_DsaAddr dsa; + u64 retVal; + + *((u64*)&dsa) = 0; + + dsa.busNumber = busNumberParm; + dsa.subBusNumber = subBusParm; + dsa.deviceId = deviceIdParm; + dsa.barNumber = barNumberParm; + + retVal = HvCall4(HvCallPciBarStore64, *(u64 *)&dsa, offsetParm, valueParm, 0); + + // getPaca()->adjustHmtForNoOfSpinLocksHeld(); + + return retVal; +} +//============================================================================ +static inline u64 HvCallPci_eoi(u16 busNumberParm, + u8 subBusParm, + u8 deviceIdParm) +{ + struct HvCallPci_DsaAddr dsa; + struct HvCallPci_LoadReturn retVal; + + *((u64*)&dsa) = 0; + + dsa.busNumber = busNumberParm; + dsa.subBusNumber = subBusParm; + dsa.deviceId = deviceIdParm; + + HvCall1Ret16(HvCallPciEoi, &retVal, *(u64*)&dsa); + + // getPaca()->adjustHmtForNoOfSpinLocksHeld(); + + return retVal.rc; +} +//============================================================================ +static inline u64 HvCallPci_getBarParms(u16 busNumberParm, + u8 subBusParm, + u8 deviceIdParm, + u8 barNumberParm, + u64 parms, + u32 sizeofParms) +{ + struct HvCallPci_DsaAddr dsa; + u64 retVal; + + *((u64*)&dsa) = 0; + + dsa.busNumber = busNumberParm; + dsa.subBusNumber = subBusParm; + dsa.deviceId = deviceIdParm; + dsa.barNumber = barNumberParm; + + retVal = HvCall3(HvCallPciGetBarParms, *(u64*)&dsa, parms, sizeofParms); + + // getPaca()->adjustHmtForNoOfSpinLocksHeld(); + + return retVal; +} +//============================================================================ +static inline u64 HvCallPci_maskFisr(u16 busNumberParm, + u8 subBusParm, + u8 deviceIdParm, + u64 fisrMask) +{ + struct HvCallPci_DsaAddr dsa; + u64 retVal; + + *((u64*)&dsa) = 0; + + dsa.busNumber = busNumberParm; + dsa.subBusNumber = subBusParm; + dsa.deviceId = deviceIdParm; + + retVal = HvCall2(HvCallPciMaskFisr, *(u64*)&dsa, fisrMask); + + // getPaca()->adjustHmtForNoOfSpinLocksHeld(); + + return retVal; +} +//============================================================================ +static inline u64 HvCallPci_unmaskFisr(u16 busNumberParm, + u8 subBusParm, + u8 deviceIdParm, + u64 fisrMask) +{ + struct HvCallPci_DsaAddr dsa; + u64 retVal; + + *((u64*)&dsa) = 0; + + dsa.busNumber = busNumberParm; + dsa.subBusNumber = subBusParm; + dsa.deviceId = deviceIdParm; + + retVal = HvCall2(HvCallPciUnmaskFisr, *(u64*)&dsa, fisrMask); + + // getPaca()->adjustHmtForNoOfSpinLocksHeld(); + + return retVal; +} +//============================================================================ +static inline u64 HvCallPci_setSlotReset(u16 busNumberParm, + u8 subBusParm, + u8 deviceIdParm, + u64 onNotOff) +{ + struct HvCallPci_DsaAddr dsa; + u64 retVal; + + *((u64*)&dsa) = 0; + + dsa.busNumber = busNumberParm; + dsa.subBusNumber = subBusParm; + dsa.deviceId = deviceIdParm; + + retVal = HvCall2(HvCallPciSetSlotReset, *(u64*)&dsa, onNotOff); + + // getPaca()->adjustHmtForNoOfSpinLocksHeld(); + + return retVal; +} +//============================================================================ +static inline u64 HvCallPci_getDeviceInfo(u16 busNumberParm, + u8 subBusParm, + u8 deviceNumberParm, + u64 parms, + u32 sizeofParms) +{ + struct HvCallPci_DsaAddr dsa; + u64 retVal; + + *((u64*)&dsa) = 0; + + dsa.busNumber = busNumberParm; + dsa.subBusNumber = subBusParm; + dsa.deviceId = deviceNumberParm << 4; + + retVal = HvCall3(HvCallPciGetDeviceInfo, *(u64*)&dsa, parms, sizeofParms); + + // getPaca()->adjustHmtForNoOfSpinLocksHeld(); + + return retVal; +} +//============================================================================ +static inline u64 HvCallPci_maskInterrupts(u16 busNumberParm, + u8 subBusParm, + u8 deviceIdParm, + u64 interruptMask) +{ + struct HvCallPci_DsaAddr dsa; + u64 retVal; + + *((u64*)&dsa) = 0; + + dsa.busNumber = busNumberParm; + dsa.subBusNumber = subBusParm; + dsa.deviceId = deviceIdParm; + + retVal = HvCall2(HvCallPciMaskInterrupts, *(u64*)&dsa, interruptMask); + + // getPaca()->adjustHmtForNoOfSpinLocksHeld(); + + return retVal; +} +//============================================================================ +static inline u64 HvCallPci_unmaskInterrupts(u16 busNumberParm, + u8 subBusParm, + u8 deviceIdParm, + u64 interruptMask) +{ + struct HvCallPci_DsaAddr dsa; + u64 retVal; + + *((u64*)&dsa) = 0; + + dsa.busNumber = busNumberParm; + dsa.subBusNumber = subBusParm; + dsa.deviceId = deviceIdParm; + + retVal = HvCall2(HvCallPciUnmaskInterrupts, *(u64*)&dsa, interruptMask); + + // getPaca()->adjustHmtForNoOfSpinLocksHeld(); + + return retVal; +} +//============================================================================ + +static inline u64 HvCallPci_getBusUnitInfo(u16 busNumberParm, + u8 subBusParm, + u8 deviceIdParm, + u64 parms, + u32 sizeofParms) +{ + struct HvCallPci_DsaAddr dsa; + u64 retVal; + + *((u64*)&dsa) = 0; + + dsa.busNumber = busNumberParm; + dsa.subBusNumber = subBusParm; + dsa.deviceId = deviceIdParm; + + retVal = HvCall3(HvCallPciGetBusUnitInfo, *(u64*)&dsa, parms, sizeofParms); + + // getPaca()->adjustHmtForNoOfSpinLocksHeld(); + + return retVal; +} +//============================================================================ + +static inline int HvCallPci_getBusVpd(u16 busNumParm, u64 destParm, u16 sizeParm) { + int xRetSize; + u64 xRc = HvCall4(HvCallPciGetCardVpd, busNumParm, destParm, sizeParm, HvCallPci_BusVpd); + // getPaca()->adjustHmtForNoOfSpinLocksHeld(); + if (xRc == -1) + xRetSize = -1; + else + xRetSize = xRc & 0xFFFF; + return xRetSize; +} +//============================================================================ + +static inline int HvCallPci_getBusAdapterVpd(u16 busNumParm, u64 destParm, u16 sizeParm) { + int xRetSize; + u64 xRc = HvCall4(HvCallPciGetCardVpd, busNumParm, destParm, sizeParm, HvCallPci_BusAdapterVpd); + // getPaca()->adjustHmtForNoOfSpinLocksHeld(); + if (xRc == -1) + xRetSize = -1; + else + xRetSize = xRc & 0xFFFF; + return xRetSize; +} +//============================================================================ +#endif // _HVCALLPCI_H diff --git a/include/asm-ppc/iSeries/HvCallSc.h b/include/asm-ppc/iSeries/HvCallSc.h new file mode 100644 index 000000000000..f51dce1d772c --- /dev/null +++ b/include/asm-ppc/iSeries/HvCallSc.h @@ -0,0 +1,53 @@ +/* + * HvCallSc.h + * Copyright (C) 2001 Mike Corrigan IBM Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _HVTYPES_H +#include <asm/iSeries/HvTypes.h> +#endif + +#ifndef _HVCALLSC_H +#define _HVCALLSC_H + +#define HvCallBase 0x80000000 +#define HvCallCfg 0x80020000 +#define HvCallEvent 0x80030000 +#define HvCallHpt 0x80040000 +#define HvCallPci 0x80050000 +#define HvCallSm 0x80070000 +#define HvCallXm 0x80090000 + +u64 HvCall0( u32 ); +u64 HvCall1( u32, u64 ); +u64 HvCall2( u32, u64, u64 ); +u64 HvCall3( u32, u64, u64, u64 ); +u64 HvCall4( u32, u64, u64, u64, u64 ); +u64 HvCall5( u32, u64, u64, u64, u64, u64 ); +u64 HvCall6( u32, u64, u64, u64, u64, u64, u64 ); +u64 HvCall7( u32, u64, u64, u64, u64, u64, u64, u64 ); + +u64 HvCall0Ret16( u32, void * ); +u64 HvCall1Ret16( u32, void *, u64 ); +u64 HvCall2Ret16( u32, void *, u64, u64 ); +u64 HvCall3Ret16( u32, void *, u64, u64, u64 ); +u64 HvCall4Ret16( u32, void *, u64, u64, u64, u64 ); +u64 HvCall5Ret16( u32, void *, u64, u64, u64, u64, u64 ); +u64 HvCall6Ret16( u32, void *, u64, u64, u64, u64, u64, u64 ); +u64 HvCall7Ret16( u32, void *, u64, u64 ,u64 ,u64 ,u64 ,u64 ,u64 ); + +#endif /* _HVCALLSC_H */ diff --git a/include/asm-ppc/iSeries/HvCallSm.h b/include/asm-ppc/iSeries/HvCallSm.h new file mode 100644 index 000000000000..7b47ee181d3a --- /dev/null +++ b/include/asm-ppc/iSeries/HvCallSm.h @@ -0,0 +1,58 @@ +/* + * HvCallSm.h + * Copyright (C) 2001 Mike Corrigan IBM Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +//============================================================================ +// +// This file contains the "hypervisor call" interface which is used to +// drive the hypervisor from the OS. +// +//============================================================================ + +//------------------------------------------------------------------- +// Standard Includes +//------------------------------------------------------------------- +#ifndef _HVCALLSC_H +#include "HvCallSc.h" +#endif + +#ifndef _HVTYPES_H +#include <asm/iSeries/HvTypes.h> +#endif + +//----------------------------------------------------------------------------- +// Constants +//----------------------------------------------------------------------------- +#ifndef _HVCALLSM_H +#define _HVCALLSM_H + +#define HvCallSmGet64BitsOfAccessMap HvCallSm + 11 + + +//============================================================================ +static inline u64 HvCallSm_get64BitsOfAccessMap( + HvLpIndex lpIndex, u64 indexIntoBitMap ) +{ + u64 retval = HvCall2(HvCallSmGet64BitsOfAccessMap, lpIndex, + indexIntoBitMap ); + // getPaca()->adjustHmtForNoOfSpinLocksHeld(); + return retval; +} +//============================================================================ +#endif // _HVCALLSM_H + diff --git a/include/asm-ppc/iSeries/HvCallXm.h b/include/asm-ppc/iSeries/HvCallXm.h new file mode 100644 index 000000000000..b4f55b74e240 --- /dev/null +++ b/include/asm-ppc/iSeries/HvCallXm.h @@ -0,0 +1,105 @@ +//============================================================================ +// Header File Id +// Name______________: HvCallXm.H +// +// Description_______: +// +// This file contains the "hypervisor call" interface which is used to +// drive the hypervisor from SLIC. +// +//============================================================================ + +//------------------------------------------------------------------- +// Forward declarations +//------------------------------------------------------------------- + +//------------------------------------------------------------------- +// Standard Includes +//------------------------------------------------------------------- +#ifndef _HVCALLSC_H +#include "HvCallSc.h" +#endif + +#ifndef _HVTYPES_H +#include <asm/iSeries/HvTypes.h> +#endif + +//------------------------------------------------------------------- +// Other Includes +//------------------------------------------------------------------- + + +//----------------------------------------------------------------------------- +// Constants +//----------------------------------------------------------------------------- +#ifndef _HVCALLXM_H +#define _HVCALLXM_H + +#define HvCallXmGetTceTableParms HvCallXm + 0 +#define HvCallXmTestBus HvCallXm + 1 +#define HvCallXmConnectBusUnit HvCallXm + 2 +#define HvCallXmLoadTod HvCallXm + 8 +#define HvCallXmTestBusUnit HvCallXm + 9 +#define HvCallXmSetTce HvCallXm + 11 +#define HvCallXmSetTces HvCallXm + 13 + + + +//============================================================================ +static inline void HvCallXm_getTceTableParms(u64 cb) +{ + HvCall1(HvCallXmGetTceTableParms, cb); + // getPaca()->adjustHmtForNoOfSpinLocksHeld(); +} +//============================================================================ +static inline u64 HvCallXm_setTce(u64 tceTableToken, u64 tceOffset, u64 tce) +{ + u64 retval = HvCall3(HvCallXmSetTce, tceTableToken, tceOffset, tce ); + // getPaca()->adjustHmtForNoOfSpinLocksHeld(); + return retval; +} +//============================================================================ +static inline u64 HvCallXm_setTces(u64 tceTableToken, u64 tceOffset, u64 numTces, u64 tce1, u64 tce2, u64 tce3, u64 tce4) +{ + u64 retval = HvCall7(HvCallXmSetTces, tceTableToken, tceOffset, numTces, + tce1, tce2, tce3, tce4 ); + // getPaca()->adjustHmtForNoOfSpinLocksHeld(); + return retval; +} +//============================================================================= +static inline u64 HvCallXm_testBus(u16 busNumber) +{ + u64 retVal = HvCall1(HvCallXmTestBus, busNumber); + // getPaca()->adjustHmtForNoOfSpinLocksHeld(); + return retVal; +} +//===================================================================================== +static inline u64 HvCallXm_testBusUnit(u16 busNumber, u8 subBusNumber, u8 deviceId) { + u64 busUnitNumber = (subBusNumber << 8) | deviceId; + u64 retVal = HvCall2(HvCallXmTestBusUnit, busNumber, busUnitNumber); + // getPaca()->adjustHmtForNoOfSpinLocksHeld(); + return retVal; +} +//===================================================================================== +static inline u64 HvCallXm_connectBusUnit(u16 busNumber, u8 subBusNumber, u8 deviceId, + u64 interruptToken) +{ + u64 busUnitNumber = (subBusNumber << 8) | deviceId; + u64 queueIndex = 0; // HvLpConfig::mapDsaToQueueIndex(HvLpDSA(busNumber, xBoard, xCard)); + + u64 retVal = HvCall5(HvCallXmConnectBusUnit, busNumber, busUnitNumber, + interruptToken, 0, queueIndex); + // getPaca()->adjustHmtForNoOfSpinLocksHeld(); + return retVal; +} +//===================================================================================== +static inline u64 HvCallXm_loadTod(void) +{ + u64 retVal = HvCall0(HvCallXmLoadTod); + // getPaca()->adjustHmtForNoOfSpinLocksHeld(); + return retVal; +} +//===================================================================================== + +#endif // _HVCALLXM_H + diff --git a/include/asm-ppc/iSeries/HvLpConfig.h b/include/asm-ppc/iSeries/HvLpConfig.h new file mode 100644 index 000000000000..ecf6cf92af03 --- /dev/null +++ b/include/asm-ppc/iSeries/HvLpConfig.h @@ -0,0 +1,292 @@ +/* + * HvLpConfig.h + * Copyright (C) 2001 Mike Corrigan IBM Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +//=========================================================================== +// +// This file contains the interface to the LPAR configuration data +// to determine which resources should be allocated to each partition. +// +//=========================================================================== + +#ifndef _HVCALLCFG_H +#include "HvCallCfg.h" +#endif + +#ifndef _HVTYPES_H +#include <asm/iSeries/HvTypes.h> +#endif + +#ifndef _ITLPNACA_H +#include <asm/iSeries/ItLpNaca.h> +#endif + +#ifndef _LPARDATA_H +#include <asm/iSeries/LparData.h> +#endif + +#ifndef _HVLPCONFIG_H +#define _HVLPCONFIG_H + +//------------------------------------------------------------------- +// Constants +//------------------------------------------------------------------- + +extern HvLpIndex HvLpConfig_getLpIndex_outline(void); + +//=================================================================== +static inline HvLpIndex HvLpConfig_getLpIndex(void) +{ + return itLpNaca.xLpIndex; +} +//=================================================================== +static inline HvLpIndex HvLpConfig_getPrimaryLpIndex(void) +{ + return itLpNaca.xPrimaryLpIndex; +} +//================================================================= +static inline HvLpIndex HvLpConfig_getLps(void) +{ + return HvCallCfg_getLps(); +} +//================================================================= +static inline HvLpIndexMap HvLpConfig_getActiveLpMap(void) +{ + return HvCallCfg_getActiveLpMap(); +} +//================================================================= +static inline u64 HvLpConfig_getSystemMsMegs(void) +{ + return HvCallCfg_getSystemMsChunks() / HvChunksPerMeg; +} +//================================================================= +static inline u64 HvLpConfig_getSystemMsChunks(void) +{ + return HvCallCfg_getSystemMsChunks(); +} +//================================================================= +static inline u64 HvLpConfig_getSystemMsPages(void) +{ + return HvCallCfg_getSystemMsChunks() * HvPagesPerChunk; +} +//================================================================ +static inline u64 HvLpConfig_getMsMegs(void) +{ + return HvCallCfg_getMsChunks(HvLpConfig_getLpIndex(),HvCallCfg_Cur) / HvChunksPerMeg; +} +//================================================================ +static inline u64 HvLpConfig_getMsChunks(void) +{ + return HvCallCfg_getMsChunks(HvLpConfig_getLpIndex(),HvCallCfg_Cur); +} +//================================================================ +static inline u64 HvLpConfig_getMsPages(void) +{ + return HvCallCfg_getMsChunks(HvLpConfig_getLpIndex(),HvCallCfg_Cur) * HvPagesPerChunk; +} +//================================================================ +static inline u64 HvLpConfig_getMinMsMegs(void) +{ + return HvCallCfg_getMsChunks(HvLpConfig_getLpIndex(),HvCallCfg_Min) / HvChunksPerMeg; +} +//================================================================ +static inline u64 HvLpConfig_getMinMsChunks(void) +{ + return HvCallCfg_getMsChunks(HvLpConfig_getLpIndex(),HvCallCfg_Min); +} +//================================================================ +static inline u64 HvLpConfig_getMinMsPages(void) +{ + return HvCallCfg_getMsChunks(HvLpConfig_getLpIndex(),HvCallCfg_Min) * HvPagesPerChunk; +} +//================================================================ +static inline u64 HvLpConfig_getMinRuntimeMsMegs(void) +{ + return HvCallCfg_getMinRuntimeMsChunks(HvLpConfig_getLpIndex()) / HvChunksPerMeg; +} +//=============================================================== +static inline u64 HvLpConfig_getMinRuntimeMsChunks(void) +{ + return HvCallCfg_getMinRuntimeMsChunks(HvLpConfig_getLpIndex()); +} +//=============================================================== +static inline u64 HvLpConfig_getMinRuntimeMsPages(void) +{ + return HvCallCfg_getMinRuntimeMsChunks(HvLpConfig_getLpIndex()) * HvPagesPerChunk; +} +//=============================================================== +static inline u64 HvLpConfig_getMaxMsMegs(void) +{ + return HvCallCfg_getMsChunks(HvLpConfig_getLpIndex(),HvCallCfg_Max) / HvChunksPerMeg; +} +//=============================================================== +static inline u64 HvLpConfig_getMaxMsChunks(void) +{ + return HvCallCfg_getMsChunks(HvLpConfig_getLpIndex(),HvCallCfg_Max); +} +//=============================================================== +static inline u64 HvLpConfig_getMaxMsPages(void) +{ + return HvCallCfg_getMsChunks(HvLpConfig_getLpIndex(),HvCallCfg_Max) * HvPagesPerChunk; +} +//=============================================================== +static inline u64 HvLpConfig_getInitMsMegs(void) +{ + return HvCallCfg_getMsChunks(HvLpConfig_getLpIndex(),HvCallCfg_Init) / HvChunksPerMeg; +} +//=============================================================== +static inline u64 HvLpConfig_getInitMsChunks(void) +{ + return HvCallCfg_getMsChunks(HvLpConfig_getLpIndex(),HvCallCfg_Init); +} +//=============================================================== +static inline u64 HvLpConfig_getInitMsPages(void) +{ return HvCallCfg_getMsChunks(HvLpConfig_getLpIndex(),HvCallCfg_Init) * HvPagesPerChunk; +} +//=============================================================== +static inline u64 HvLpConfig_getSystemPhysicalProcessors(void) +{ + return HvCallCfg_getSystemPhysicalProcessors(); +} +//=============================================================== +static inline u64 HvLpConfig_getSystemLogicalProcessors(void) +{ + return HvCallCfg_getSystemPhysicalProcessors() * (/*getPaca()->getSecondaryThreadCount() +*/ 1); +} +//=============================================================== +static inline u64 HvLpConfig_getNumProcsInSharedPool(HvLpSharedPoolIndex sPI) +{ + return HvCallCfg_getNumProcsInSharedPool(sPI); +} +//=============================================================== +static inline u64 HvLpConfig_getPhysicalProcessors(void) +{ + return HvCallCfg_getPhysicalProcessors(HvLpConfig_getLpIndex(),HvCallCfg_Cur); +} +//=============================================================== +static inline u64 HvLpConfig_getLogicalProcessors(void) +{ + return HvCallCfg_getPhysicalProcessors(HvLpConfig_getLpIndex(),HvCallCfg_Cur) * (/*getPaca()->getSecondaryThreadCount() +*/ 1); +} +//=============================================================== +static inline HvLpSharedPoolIndex HvLpConfig_getSharedPoolIndex(void) +{ + return HvCallCfg_getSharedPoolIndex(HvLpConfig_getLpIndex()); +} +//=============================================================== +static inline u64 HvLpConfig_getSharedProcUnits(void) +{ + return HvCallCfg_getSharedProcUnits(HvLpConfig_getLpIndex(),HvCallCfg_Cur); +} +//=============================================================== +static inline u64 HvLpConfig_getMinSharedProcUnits(void) +{ + return HvCallCfg_getSharedProcUnits(HvLpConfig_getLpIndex(),HvCallCfg_Min); +} +//=============================================================== +static inline u64 HvLpConfig_getMaxSharedProcUnits(void) +{ + return HvCallCfg_getSharedProcUnits(HvLpConfig_getLpIndex(),HvCallCfg_Max); +} +//=============================================================== +static inline u64 HvLpConfig_getMinPhysicalProcessors(void) +{ + return HvCallCfg_getPhysicalProcessors(HvLpConfig_getLpIndex(),HvCallCfg_Min); +} +//=============================================================== +static inline u64 HvLpConfig_getMinLogicalProcessors(void) +{ + return HvCallCfg_getPhysicalProcessors(HvLpConfig_getLpIndex(),HvCallCfg_Min) * (/*getPaca()->getSecondaryThreadCount() +*/ 1); +} +//=============================================================== +static inline u64 HvLpConfig_getMaxPhysicalProcessors(void) +{ + return HvCallCfg_getPhysicalProcessors(HvLpConfig_getLpIndex(),HvCallCfg_Max); +} +//=============================================================== +static inline u64 HvLpConfig_getMaxLogicalProcessors(void) +{ + return HvCallCfg_getPhysicalProcessors(HvLpConfig_getLpIndex(),HvCallCfg_Max) * (/*getPaca()->getSecondaryThreadCount() +*/ 1); +} +//=============================================================== +static inline u64 HvLpConfig_getInitPhysicalProcessors(void) +{ + return HvCallCfg_getPhysicalProcessors(HvLpConfig_getLpIndex(),HvCallCfg_Init); +} +//=============================================================== +static inline u64 HvLpConfig_getInitLogicalProcessors(void) +{ + return HvCallCfg_getPhysicalProcessors(HvLpConfig_getLpIndex(),HvCallCfg_Init) * (/*getPaca()->getSecondaryThreadCount() +*/ 1); +} +//================================================================ +static inline HvLpVirtualLanIndexMap HvLpConfig_getVirtualLanIndexMap(void) +{ + return HvCallCfg_getVirtualLanIndexMap(HvLpConfig_getLpIndex_outline()); +} +//=============================================================== +static inline HvLpVirtualLanIndexMap HvLpConfig_getVirtualLanIndexMapForLp(HvLpIndex lp) +{ + return HvCallCfg_getVirtualLanIndexMap(lp); +} +//================================================================ +static inline HvLpIndex HvLpConfig_getBusOwner(HvBusNumber busNumber) +{ + return HvCallCfg_getBusOwner(busNumber); +} +//=============================================================== +static inline int HvLpConfig_isBusDedicated(HvBusNumber busNumber) +{ + return HvCallCfg_isBusDedicated(busNumber); +} +//================================================================ +static inline HvLpIndexMap HvLpConfig_getBusAllocation(HvBusNumber busNumber) +{ + return HvCallCfg_getBusAllocation(busNumber); +} +//================================================================ +// returns the absolute real address of the load area +static inline u64 HvLpConfig_getLoadAddress(void) +{ + return itLpNaca.xLoadAreaAddr & 0x7fffffffffffffff; +} +//================================================================ +static inline u64 HvLpConfig_getLoadPages(void) +{ + return itLpNaca.xLoadAreaChunks * HvPagesPerChunk; +} +//================================================================ +static inline int HvLpConfig_isBusOwnedByThisLp(HvBusNumber busNumber) +{ + HvLpIndex busOwner = HvLpConfig_getBusOwner(busNumber); + return (busOwner == HvLpConfig_getLpIndex()); +} +//================================================================ +static inline int HvLpConfig_doLpsCommunicateOnVirtualLan(HvLpIndex lp1, HvLpIndex lp2) +{ + HvLpVirtualLanIndexMap virtualLanIndexMap1 = HvCallCfg_getVirtualLanIndexMap( lp1 ); + HvLpVirtualLanIndexMap virtualLanIndexMap2 = HvCallCfg_getVirtualLanIndexMap( lp2 ); + return ((virtualLanIndexMap1 & virtualLanIndexMap2) != 0); +} +//================================================================ +static inline HvLpIndex HvLpConfig_getHostingLpIndex(HvLpIndex lp) +{ + return HvCallCfg_getHostingLpIndex(lp); +} +//================================================================ + +#endif // _HVLPCONFIG_H diff --git a/include/asm-ppc/iSeries/HvLpEvent.h b/include/asm-ppc/iSeries/HvLpEvent.h new file mode 100644 index 000000000000..be2f08987efc --- /dev/null +++ b/include/asm-ppc/iSeries/HvLpEvent.h @@ -0,0 +1,144 @@ +/* + * HvLpEvent.h + * Copyright (C) 2001 Mike Corrigan IBM Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +//====================================================================== +// +// This file contains the class for HV events in the system. +// +//===================================================================== +#ifndef _HVLPEVENT_H +#define _HVLPEVENT_H + +#include <asm/types.h> +#include <asm/ptrace.h> +#include <asm/iSeries/HvTypes.h> +#ifndef _HVCALLEVENT_H +#include <asm/iSeries/HvCallEvent.h> +#endif + + +//===================================================================== +// +// HvLpEvent is the structure for Lp Event messages passed between +// partitions through PLIC. +// +//===================================================================== + +struct HvEventFlags +{ + u8 xValid:1; // Indicates a valid request x00-x00 + u8 xRsvd1:4; // Reserved ... + u8 xAckType:1; // Immediate or deferred ... + u8 xAckInd:1; // Indicates if ACK required ... + u8 xFunction:1; // Interrupt or Acknowledge ... +}; + + +struct HvLpEvent +{ + struct HvEventFlags xFlags; // Event flags x00-x00 + u8 xType; // Type of message x01-x01 + u16 xSubtype; // Subtype for event x02-x03 + u8 xSourceLp; // Source LP x04-x04 + u8 xTargetLp; // Target LP x05-x05 + u8 xSizeMinus1; // Size of Derived class - 1 x06-x06 + u8 xRc; // RC for Ack flows x07-x07 + u16 xSourceInstanceId; // Source sides instance id x08-x09 + u16 xTargetInstanceId; // Target sides instance id x0A-x0B + union { + u32 xSubtypeData; // Data usable by the subtype x0C-x0F + u16 xSubtypeDataShort[2]; // Data as 2 shorts + u8 xSubtypeDataChar[4]; // Data as 4 chars + } x; + + u64 xCorrelationToken; // Unique value for source/type x10-x17 +}; + +// Lp Event handler function +typedef void (*LpEventHandler)(struct HvLpEvent *, struct pt_regs *); + +// Register a handler for an event type +// returns 0 on success +extern int HvLpEvent_registerHandler( HvLpEvent_Type eventType, LpEventHandler hdlr); + +// Unregister a handler for an event type +// returns 0 on success +// Unregister will fail if there are any paths open for the type +extern int HvLpEvent_unregisterHandler( HvLpEvent_Type eventType ); + +// Open an Lp Event Path for an event type +// returns 0 on success +// openPath will fail if there is no handler registered for the event type. +// The lpIndex specified is the partition index for the target partition +// (for VirtualIo, VirtualLan and SessionMgr) other types specify zero) +extern int HvLpEvent_openPath( HvLpEvent_Type eventType, HvLpIndex lpIndex ); + + +// Close an Lp Event Path for a type and partition +// returns 0 on sucess +extern int HvLpEvent_closePath( HvLpEvent_Type eventType, HvLpIndex lpIndex ); + +#define HvLpEvent_Type_Hypervisor 0 +#define HvLpEvent_Type_MachineFac 1 +#define HvLpEvent_Type_SessionMgr 2 +#define HvLpEvent_Type_SpdIo 3 +#define HvLpEvent_Type_VirtualBus 4 +#define HvLpEvent_Type_PciIo 5 +#define HvLpEvent_Type_RioIo 6 +#define HvLpEvent_Type_VirtualLan 7 +#define HvLpEvent_Type_VirtualIo 8 +#define HvLpEvent_Type_NumTypes 9 + +#define HvLpEvent_Rc_Good 0 +#define HvLpEvent_Rc_BufferNotAvailable 1 +#define HvLpEvent_Rc_Cancelled 2 +#define HvLpEvent_Rc_GenericError 3 +#define HvLpEvent_Rc_InvalidAddress 4 +#define HvLpEvent_Rc_InvalidPartition 5 +#define HvLpEvent_Rc_InvalidSize 6 +#define HvLpEvent_Rc_InvalidSubtype 7 +#define HvLpEvent_Rc_InvalidSubtypeData 8 +#define HvLpEvent_Rc_InvalidType 9 +#define HvLpEvent_Rc_PartitionDead 10 +#define HvLpEvent_Rc_PathClosed 11 +#define HvLpEvent_Rc_SubtypeError 12 + +#define HvLpEvent_Function_Ack 0 +#define HvLpEvent_Function_Int 1 + +#define HvLpEvent_AckInd_NoAck 0 +#define HvLpEvent_AckInd_DoAck 1 + +#define HvLpEvent_AckType_ImmediateAck 0 +#define HvLpEvent_AckType_DeferredAck 1 + +#define HvLpDma_Direction_LocalToRemote 0 +#define HvLpDma_Direction_RemoteToLocal 1 + +#define HvLpDma_AddressType_TceIndex 0 +#define HvLpDma_AddressType_RealAddress 1 + +#define HvLpDma_Rc_Good 0 +#define HvLpDma_Rc_Error 1 +#define HvLpDma_Rc_PartitionDead 2 +#define HvLpDma_Rc_PathClosed 3 +#define HvLpDma_Rc_InvalidAddress 4 +#define HvLpDma_Rc_InvalidLength 5 + +#endif // _HVLPEVENT_H diff --git a/include/asm-ppc/iSeries/HvReleaseData.h b/include/asm-ppc/iSeries/HvReleaseData.h new file mode 100644 index 000000000000..aa82e18f6d13 --- /dev/null +++ b/include/asm-ppc/iSeries/HvReleaseData.h @@ -0,0 +1,71 @@ +/* + * HvReleaseData.h + * Copyright (C) 2001 Mike Corrigan IBM Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +//============================================================================= +// +// This control block contains the critical information about the +// release so that it can be changed in the future (ie, the virtual +// address of the OS's NACA). +// +//----------------------------------------------------------------------------- +// Standard Includes +//----------------------------------------------------------------------------- +#ifndef _PPC_TYPES_H +#include <asm/types.h> +#endif + +#ifndef _HVRELEASEDATA_H +#define _HVRELEASEDATA_H + +//============================================================================= +// +// When we IPL a secondary partition, we will check if if the +// secondary xMinPlicVrmIndex > the primary xVrmIndex. +// If it is then this tells PLIC that this secondary is not +// supported running on this "old" of a level of PLIC. +// +// Likewise, we will compare the primary xMinSlicVrmIndex to +// the secondary xVrmIndex. +// If the primary xMinSlicVrmDelta > secondary xVrmDelta then we +// know that this PLIC does not support running an OS "that old". +// +//============================================================================= + +struct HvReleaseData +{ + u32 xDesc; // Descriptor "HvRD" ebcdic x00-x03 + u16 xSize; // Size of this control block x04-x05 + u16 xVpdAreasPtrOffset; // Offset in NACA of ItVpdAreas x06-x07 + u32 xSlicNacaAddr64; // Virtual address of OS's NACA x08-x0F + struct Naca * xSlicNacaAddr; // Virtual address of OS's NACA x08-x0F + u32 xMsNucDataOffset; // Offset of Linux Mapping Data x10-x13 + u32 xRsvd1; // Reserved x14-x17 + u16 xTagsMode:1; // 0 == tags active, 1 == tags inactive + u16 xAddressSize:1; // 0 == 64-bit, 1 == 32-bit + u16 xNoSharedProcs:1; // 0 == shared procs, 1 == no shared + u16 xNoHMT:1; // 0 == allow HMT, 1 == no HMT + u16 xRsvd2:12; // Reserved x18-x19 + u16 xVrmIndex; // VRM Index of OS image x1A-x1B + u16 xMinSupportedPlicVrmIndex;// Min PLIC level (soft) x1C-x1D + u16 xMinCompatablePlicVrmIndex;// Min PLIC levelP (hard) x1E-x1F + char xVrmName[12]; // Displayable name x20-x2B + char xRsvd3[20]; // Reserved x2C-x3F +}; + +#endif // _HVRELEASEDATA_H diff --git a/include/asm-ppc/iSeries/HvTypes.h b/include/asm-ppc/iSeries/HvTypes.h new file mode 100644 index 000000000000..4c25828dacef --- /dev/null +++ b/include/asm-ppc/iSeries/HvTypes.h @@ -0,0 +1,161 @@ +/* + * HvTypes.h + * Copyright (C) 2001 Mike Corrigan IBM Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +//=========================================================================== +// Header File Id +// Name______________: HvTypes.H +// +// Description_______: +// +// General typedefs for the hypervisor. +// +// Declared Class(es): +// +//=========================================================================== + +#ifndef _PPC_TYPES_H +#include <asm/types.h> +#endif + + +#ifndef _HVTYPES_H +#define _HVTYPES_H + +//------------------------------------------------------------------- +// Typedefs +//------------------------------------------------------------------- +typedef u8 HvLpIndex; +typedef u16 HvLpInstanceId; +typedef u64 HvLpTOD; +typedef u64 HvLpSystemSerialNum; +typedef u8 HvLpDeviceSerialNum[12]; +typedef u16 HvLpSanHwSet; +typedef u16 HvLpBus; +typedef u16 HvLpBoard; +typedef u16 HvLpCard; +typedef u8 HvLpDeviceType[4]; +typedef u8 HvLpDeviceModel[3]; +typedef u64 HvIoToken; +typedef u8 HvLpName[8]; +typedef u32 HvIoId; +typedef u64 HvRealMemoryIndex; +typedef u32 HvLpIndexMap; // Must hold HvMaxArchitectedLps bits!!! +typedef u16 HvLpVrmIndex; +typedef u32 HvXmGenerationId; +typedef u8 HvLpBusPool; +typedef u8 HvLpSharedPoolIndex; +typedef u16 HvLpSharedProcUnitsX100; +typedef u8 HvLpVirtualLanIndex; +typedef u16 HvLpVirtualLanIndexMap; // Must hold HvMaxArchitectedVirtualLans bits!!! +typedef u16 HvBusNumber; // Hypervisor Bus Number +typedef u8 HvSubBusNumber; // Hypervisor SubBus Number +typedef u8 HvAgentId; // Hypervisor DevFn + + +#define HVMAXARCHITECTEDLPS 32 +#define HVCHUNKSIZE 256 * 1024 +#define HVPAGESIZE 4 * 1024 +#define HVLPMINMEGSPRIMARY 256 +#define HVLPMINMEGSSECONDARY 64 +#define HVCHUNKSPERMEG 4 +#define HVPAGESPERMEG 256 +#define HVPAGESPERCHUNK 64 + + +static const HvLpIndexMap HvLpIndexMapDefault = (1 << (sizeof(HvLpIndexMap) * 8 - 1)); +static const HvLpIndex HvHardcodedPrimaryLpIndex = 0; +static const HvLpIndex HvMaxArchitectedLps = HVMAXARCHITECTEDLPS; +static const HvLpVirtualLanIndex HvMaxArchitectedVirtualLans = 16; +static const HvLpSharedPoolIndex HvMaxArchitectedSharedPools = 16; +static const HvLpSharedPoolIndex HvMaxSupportedSharedPools = 1; +static const HvLpIndex HvMaxRuntimeLpsPreCondor = 12; +static const HvLpIndex HvMaxRuntimeLps = HVMAXARCHITECTEDLPS; +static const HvLpIndex HvLpIndexInvalid = 0xff; +static const u16 HvInvalidProcIndex = 0xffff; +static const u32 HvVirtualFlashSize = 0x200; +static const u32 HvMaxBusesPreCondor = 32; +static const u32 HvMaxBusesCondor = 256; +static const u32 HvMaxArchitectedBuses = 512; +static const HvLpBus HvCspBusNumber = 1; +static const u32 HvMaxSanHwSets = 16; +static const HvLpCard HvMaxSystemIops = 200; +static const HvLpCard HvMaxBusIops = 20; +static const u16 HvMaxUnitsPerIop = 100; +static const u64 HvPageSize = 4 * 1024; +static const u64 HvChunkSize = HVCHUNKSIZE; +static const u64 HvChunksPerMeg = HVCHUNKSPERMEG; +static const u64 HvPagesPerChunk = HVPAGESPERCHUNK; +static const u64 HvPagesPerMeg = HVPAGESPERMEG; +static const u64 HvLpMinMegsPrimary = HVLPMINMEGSPRIMARY; +static const u64 HvLpMinMegsSecondary = HVLPMINMEGSSECONDARY; +static const u64 HvLpMinChunksPrimary = HVLPMINMEGSPRIMARY * HVCHUNKSPERMEG; +static const u64 HvLpMinChunksSecondary = HVLPMINMEGSSECONDARY * HVCHUNKSPERMEG; +static const u64 HvLpMinPagesPrimary = HVLPMINMEGSPRIMARY * HVPAGESPERMEG; +static const u64 HvLpMinPagesSecondary = HVLPMINMEGSSECONDARY * HVPAGESPERMEG; +static const u8 HvLpMinProcs = 1; +static const u8 HvLpConfigMinInteract = 1; +static const u16 HvLpMinSharedProcUnitsX100 = 10; +static const u16 HvLpMaxSharedProcUnitsX100 = 100; +static const HvLpSharedPoolIndex HvLpSharedPoolIndexInvalid = 0xff; + + +//-------------------------------------------------------------------- +// Enums for the sub-components under PLIC +// Used in HvCall and HvPrimaryCall +//-------------------------------------------------------------------- +enum HvCallCompIds +{ + HvCallCompId = 0, + HvCallCpuCtlsCompId = 1, + HvCallCfgCompId = 2, + HvCallEventCompId = 3, + HvCallHptCompId = 4, + HvCallPciCompId = 5, + HvCallSlmCompId = 6, + HvCallSmCompId = 7, + HvCallSpdCompId = 8, + HvCallXmCompId = 9, + HvCallRioCompId = 10, + HvCallRsvd3CompId = 11, + HvCallRsvd2CompId = 12, + HvCallRsvd1CompId = 13, + HvCallMaxCompId = 14, + HvPrimaryCallCompId = 0, + HvPrimaryCallCfgCompId = 1, + HvPrimaryCallPciCompId = 2, + HvPrimaryCallSmCompId = 3, + HvPrimaryCallSpdCompId = 4, + HvPrimaryCallXmCompId = 5, + HvPrimaryCallRioCompId = 6, + HvPrimaryCallRsvd7CompId = 7, + HvPrimaryCallRsvd6CompId = 8, + HvPrimaryCallRsvd5CompId = 9, + HvPrimaryCallRsvd4CompId = 10, + HvPrimaryCallRsvd3CompId = 11, + HvPrimaryCallRsvd2CompId = 12, + HvPrimaryCallRsvd1CompId = 13, + HvPrimaryCallMaxCompId = HvCallMaxCompId +}; + +struct HvLpBufferList { + u64 addr; + u64 len; +}; + +#endif // _HVTYPES_H diff --git a/include/asm-ppc/iSeries/IoHriMainStore.h b/include/asm-ppc/iSeries/IoHriMainStore.h new file mode 100644 index 000000000000..76626e8af971 --- /dev/null +++ b/include/asm-ppc/iSeries/IoHriMainStore.h @@ -0,0 +1,65 @@ +/* + * IoHriMainStore.h + * Copyright (C) 2001 Mike Corrigan IBM Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _IOHRIMAINSTORE_H +#define _IOHRIMAINSTORE_H + +struct IoHriMainStoreSegment4 { + u8 msArea0Exists:1; + u8 msArea1Exists:1; + u8 msArea2Exists:1; + u8 msArea3Exists:1; + u8 reserved1:4; + u8 reserved2; + + u8 msArea0Functional:1; + u8 msArea1Functional:1; + u8 msArea2Functional:1; + u8 msArea3Functional:1; + u8 reserved3:4; + u8 reserved4; + + u32 totalMainStore; + + u64 msArea0Ptr; + u64 msArea1Ptr; + u64 msArea2Ptr; + u64 msArea3Ptr; + + u32 cardProductionLevel; + + u32 msAdrHole; + + u8 msArea0HasRiserVpd:1; + u8 msArea1HasRiserVpd:1; + u8 msArea2HasRiserVpd:1; + u8 msArea3HasRiserVpd:1; + u8 reserved5:4; + u8 reserved6; + u16 reserved7; + + u8 reserved8[28]; + + u64 nonInterleavedBlocksStartAdr; + u64 nonInterleavedBlocksEndAdr; +}; + + +#endif // _IOHRIMAINSTORE_H + diff --git a/include/asm-ppc/iSeries/IoHriProcessorVpd.h b/include/asm-ppc/iSeries/IoHriProcessorVpd.h new file mode 100644 index 000000000000..150d21204252 --- /dev/null +++ b/include/asm-ppc/iSeries/IoHriProcessorVpd.h @@ -0,0 +1,90 @@ +/* + * IoHriProcessorVpd.h + * Copyright (C) 2001 Mike Corrigan IBM Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +//=================================================================== +// +// This struct maps Processor Vpd that is DMAd to SLIC by CSP +// + +#ifndef _TYPES_H +#include <asm/types.h> +#endif + +#ifndef _IOHRIPROCESSORVPD_H +#define _IOHRIPROCESSORVPD_H + +struct IoHriProcessorVpd +{ + + u8 xFormat; // VPD format indicator x00-x00 + u8 xProcStatus:8; // Processor State x01-x01 + u8 xSecondaryThreadCount; // Secondary thread cnt x02-x02 + u8 xSrcType:1; // Src Type x03-x03 + u8 xSrcSoft:1; // Src stay soft ... + u8 xSrcParable:1; // Src parable ... + u8 xRsvd1:5; // Reserved ... + u16 xHvPhysicalProcIndex; // Hypervisor physical proc index04-x05 + u16 xRsvd2; // Reserved x06-x07 + u32 xHwNodeId; // Hardware node id x08-x0B + u32 xHwProcId; // Hardware processor id x0C-x0F + + u32 xTypeNum; // Card Type/CCIN number x10-x13 + u32 xModelNum; // Model/Feature number x14-x17 + u64 xSerialNum; // Serial number x18-x1F + char xPartNum[12]; // Book Part or FPU number x20-x2B + char xMfgID[4]; // Manufacturing ID x2C-x2F + + u32 xProcFreq; // Processor Frequency x30-x33 + u32 xTimeBaseFreq; // Time Base Frequency x34-x37 + + u32 xChipEcLevel; // Chip EC Levels x38-x3B + u32 xProcIdReg; // PIR SPR value x3C-x3F + u32 xPVR; // PVR value x40-x43 + u8 xRsvd3[12]; // Reserved x44-x4F + + u32 xInstCacheSize; // Instruction cache size in KB x50-x53 + u32 xInstBlockSize; // Instruction cache block size x54-x57 + u32 xDataCacheOperandSize; // Data cache operand size x58-x5B + u32 xInstCacheOperandSize; // Inst cache operand size x5C-x5F + + u32 xDataL1CacheSizeKB; // L1 data cache size in KB x60-x63 + u32 xDataL1CacheLineSize; // L1 data cache block size x64-x67 + u64 xRsvd4; // Reserved x68-x6F + + u32 xDataL2CacheSizeKB; // L2 data cache size in KB x70-x73 + u32 xDataL2CacheLineSize; // L2 data cache block size x74-x77 + u64 xRsvd5; // Reserved x78-x7F + + u32 xDataL3CacheSizeKB; // L3 data cache size in KB x80-x83 + u32 xDataL3CacheLineSize; // L3 data cache block size x84-x87 + u64 xRsvd6; // Reserved x88-x8F + + u64 xFruLabel; // Card Location Label x90-x97 + u8 xSlotsOnCard; // Slots on card (0=no slots) x98-x98 + u8 xPartLocFlag; // Location flag (0-pluggable 1-imbedded) x99-x99 + u16 xSlotMapIndex; // Index in slot map table x9A-x9B + u8 xSmartCardPortNo; // Smart card port number x9C-x9C + u8 xRsvd7; // Reserved x9D-x9D + u16 xFrameIdAndRackUnit; // Frame ID and rack unit adr x9E-x9F + + u8 xRsvd8[24]; // Reserved xA0-xB7 + + char xProcSrc[72]; // CSP format SRC xB8-xFF +}; +#endif // _IOHRIPROCESSORVPD_H diff --git a/include/asm-ppc/iSeries/ItIplParmsReal.h b/include/asm-ppc/iSeries/ItIplParmsReal.h new file mode 100644 index 000000000000..dd7c772c5004 --- /dev/null +++ b/include/asm-ppc/iSeries/ItIplParmsReal.h @@ -0,0 +1,78 @@ +/* + * ItIplParmsReal.h + * Copyright (C) 2001 Mike Corrigan IBM Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +//============================================================================== +// +// This struct maps the IPL Parameters DMA'd from the SP. +// +// Warning: +// This data must map in exactly 64 bytes and match the architecture for +// the IPL parms +// +//============================================================================= + + +//------------------------------------------------------------------- +// Standard Includes +//------------------------------------------------------------------- +#ifndef _PPC_TYPES_H +#include <asm/types.h> +#endif + +#ifndef _ITIPLPARMSREAL_H +#define _ITIPLPARMSREAL_H + +struct ItIplParmsReal +{ + u8 xFormat; // Defines format of IplParms x00-x00 + u8 xRsvd01:6; // Reserved x01-x01 + u8 xAlternateSearch:1; // Alternate search indicator ... + u8 xUaSupplied:1; // UA Supplied on programmed IPL ... + u8 xLsUaFormat; // Format byte for UA x02-x02 + u8 xRsvd02; // Reserved x03-x03 + u32 xLsUa; // LS UA x04-x07 + u32 xUnusedLsLid; // First OS LID to load x08-x0B + u16 xLsBusNumber; // LS Bus Number x0C-x0D + u8 xLsCardAdr; // LS Card Address x0E-x0E + u8 xLsBoardAdr; // LS Board Address x0F-x0F + u32 xRsvd03; // Reserved x10-x13 + u8 xSpcnPresent:1; // SPCN present x14-x14 + u8 xCpmPresent:1; // CPM present ... + u8 xRsvd04:6; // Reserved ... + u8 xRsvd05:4; // Reserved x15-x15 + u8 xKeyLock:4; // Keylock setting ... + u8 xRsvd06:6; // Reserved x16-x16 + u8 xIplMode:2; // Ipl mode (A|B|C|D) ... + u8 xHwIplType; // Fast v slow v slow EC HW IPL x17-x17 + u16 xCpmEnabledIpl:1; // CPM in effect when IPL initiated x18-x19 + u16 xPowerOnResetIpl:1; // Indicate POR condition ... + u16 xMainStorePreserved:1; // Main Storage is preserved ... + u16 xRsvd07:13; // Reserved ... + u16 xIplSource:16; // Ipl source x1A-x1B + u8 xIplReason:8; // Reason for this IPL x1C-x1C + u8 xRsvd08; // Reserved x1D-x1D + u16 xRsvd09; // Reserved x1E-x1F + u16 xSysBoxType; // System Box Type x20-x21 + u16 xSysProcType; // System Processor Type x22-x23 + u32 xRsvd10; // Reserved x24-x27 + u64 xRsvd11; // Reserved x28-x2F + u64 xRsvd12; // Reserved x30-x37 + u64 xRsvd13; // Reserved x38-x3F +}; +#endif // _ITIPLPARMSREAL_H diff --git a/include/asm-ppc/iSeries/ItLpNaca.h b/include/asm-ppc/iSeries/ItLpNaca.h new file mode 100644 index 000000000000..ebaa08fb7482 --- /dev/null +++ b/include/asm-ppc/iSeries/ItLpNaca.h @@ -0,0 +1,87 @@ +/* + * ItLpNaca.h + * Copyright (C) 2001 Mike Corrigan IBM Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +//============================================================================= +// +// This control block contains the data that is shared between the +// hypervisor (PLIC) and the OS. +// +//============================================================================= + + +#ifndef _ITLPNACA_H +#define _ITLPNACA_H + +struct ItLpNaca +{ +//============================================================================= +// CACHE_LINE_1 0x0000 - 0x007F Contains read-only data +//============================================================================= + u32 xDesc; // Eye catcher x00-x03 + u16 xSize; // Size of this class x04-x05 + u16 xIntHdlrOffset; // Offset to IntHdlr array x06-x07 + u8 xMaxIntHdlrEntries; // Number of entries in array x08-x08 + u8 xPrimaryLpIndex; // LP Index of Primary x09-x09 + u8 xServiceLpIndex; // LP Ind of Service Focal Pointx0A-x0A + u8 xLpIndex; // LP Index x0B-x0B + u16 xMaxLpQueues; // Number of allocated queues x0C-x0D + u16 xLpQueueOffset; // Offset to start of LP queues x0E-x0F + u8 xPirEnvironMode:8; // Piranha or hardware x10-x10 + u8 xPirConsoleMode:8; // Piranha console indicator x11-x11 + u8 xPirDasdMode:8; // Piranha dasd indicator x12-x12 + u8 xRsvd1_0[5]; // Reserved for Piranha related x13-x17 + u8 xLparInstalled:1; // Is LPAR installed on system x18-x1F + u8 xSysPartitioned:1; // Is the system partitioned ... + u8 xHwSyncedTBs:1; // Hardware synced TBs ... + u8 xIntProcUtilHmt:1; // Utilize HMT for interrupts ... + u8 xRsvd1_1:4; // Reserved ... + u8 xSpVpdFormat:8; // VPD areas are in CSP format ... + u8 xIntProcRatio:8; // Ratio of int procs to procs ... + u8 xRsvd1_2[5]; // Reserved ... + u16 xRsvd1_3; // Reserved x20-x21 + u16 xPlicVrmIndex; // VRM index of PLIC x22-x23 + u16 xMinSupportedSlicVrmInd;// Min supported OS VRM index x24-x25 + u16 xMinCompatableSlicVrmInd;// Min compatable OS VRM index x26-x27 + u64 xLoadAreaAddr; // ER address of load area x28-x2F + u32 xLoadAreaChunks; // Chunks for the load area x30-x33 + u32 xRsvd1_4; // x34-x37 + u8 xRsvd1_5[72]; // x38-x7F + +//============================================================================= +// CACHE_LINE_2 0x0080 - 0x00FF Contains local read-write data +//============================================================================= + u8 xRsvd2_0[128]; // Reserved x00-x7F + +//============================================================================= +// CACHE_LINE_3-6 0x0100 - 0x02FF Contains LP Queue indicators +// NB: Padding required to keep xInterrruptHdlr at x300 which is required +// for v4r4 PLIC. +//============================================================================= + u8 xOldLpQueue[128]; // LP Queue needed for v4r4 100-17F + u8 xRsvd3_0[384]; // Reserved 180-2FF +//============================================================================= +// CACHE_LINE_7-8 0x0300 - 0x03FF Contains the address of the OS interrupt +// handlers +//============================================================================= + u64 xInterruptHdlr[32]; // Interrupt handlers 300-x3FF +}; + +//============================================================================= + +#endif // _ITLPNACA_H diff --git a/include/asm-ppc/iSeries/ItLpPaca.h b/include/asm-ppc/iSeries/ItLpPaca.h new file mode 100644 index 000000000000..e5556b2f3070 --- /dev/null +++ b/include/asm-ppc/iSeries/ItLpPaca.h @@ -0,0 +1,122 @@ +/* + * ItLpPaca.h + * Copyright (C) 2001 Mike Corrigan IBM Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +//============================================================================= +// +// This control block contains the data that is shared between the +// hypervisor (PLIC) and the OS. +// +// +//---------------------------------------------------------------------------- +#ifndef _PPC_TYPES_H +#include <asm/types.h> +#endif + +#ifndef _ITLPPACA_H +#define _ITLPPACA_H + + +struct ItLpPaca +{ +//============================================================================= +// CACHE_LINE_1 0x0000 - 0x007F Contains read-only data +// NOTE: The xDynXyz fields are fields that will be dynamically changed by +// PLIC when preparing to bring a processor online or when dispatching a +// virtual processor! +//============================================================================= + u32 xDesc; // Eye catcher 0xD397D781 x00-x03 + u16 xSize; // Size of this struct x04-x05 + u16 xRsvd1_0; // Reserved x06-x07 + u16 xRsvd1_1:14; // Reserved x08-x09 + u8 xSharedProc:1; // Shared processor indicator ... + u8 xSecondaryThread:1; // Secondary thread indicator ... + volatile u8 xDynProcStatus:8; // Dynamic Status of this proc x0A-x0A + u8 xSecondaryThreadCnt; // Secondary thread count x0B-x0B + volatile u16 xDynHvPhysicalProcIndex;// Dynamic HV Physical Proc Index0C-x0D + volatile u16 xDynHvLogicalProcIndex;// Dynamic HV Logical Proc Indexx0E-x0F + u32 xDecrVal; // Value for Decr programming x10-x13 + u32 xPMCVal; // Value for PMC regs x14-x17 + volatile u32 xDynHwNodeId; // Dynamic Hardware Node id x18-x1B + volatile u32 xDynHwProcId; // Dynamic Hardware Proc Id x1C-x1F + volatile u32 xDynPIR; // Dynamic ProcIdReg value x20-x23 + u32 xDseiData; // DSEI data x24-x27 + u64 xSPRG3; // SPRG3 value x28-x2F + u8 xRsvd1_3[80]; // Reserved x30-x7F + +//============================================================================= +// CACHE_LINE_2 0x0080 - 0x00FF Contains local read-write data +//============================================================================= + // This Dword contains a byte for each type of interrupt that can occur. + // The IPI is a count while the others are just a binary 1 or 0. + + u16 xRsvd; // Reserved - cleared by #mpasmbl + u8 xXirrInt; // Indicates xXirrValue is valid or Immed IO + u8 xIpiCnt; // IPI Count + u8 xDecrInt; // DECR interrupt occurred + u8 xPdcInt; // PDC interrupt occurred + u8 xQuantumInt; // Interrupt quantum reached + u8 xOldPlicDeferredExtInt; // Old PLIC has deferred XIRR pending + + u64 xPlicDeferIntsArea; + + // Used to pass the real SRR0/1 from PLIC to the OS as well as to + // pass the target SRR0/1 from the OS to PLIC on a SetAsrAndRfid. + u64 xSavedSrr0; // Saved SRR0 x10-x17 + u64 xSavedSrr1; // Saved SRR1 x18-x1F + + // Used to pass parms from the OS to PLIC for SetAsrAndRfid + u64 xSavedGpr3; // Saved GPR3 x20-x27 + u64 xSavedGpr4; // Saved GPR4 x28-x2F + u64 xSavedGpr5; // Saved GPR5 x30-x37 + + u8 xRsvd2_1; // Reserved x38-x38 + u8 xCpuCtlsTaskAttributes; // Task attributes for cpuctls x39-x39 + u8 xFPRegsInUse; // FP regs in use x3A-x3A + u8 xPMCRegsInUse; // PMC regs in use x3B-x3B + volatile u32 xSavedDecr; // Saved Decr Value x3C-x3F + volatile u64 xEmulatedTimeBase; // Emulated TB for this thread x40-x47 + volatile u64 xCurPLICLatency; // Unaccounted PLIC latency x48-x4F + u64 xTotPLICLatency; // Accumulated PLIC latency x50-x57 + u64 xWaitStateCycles; // Wait cycles for this proc x58-x5F + u64 xEndOfQuantum; // TB at end of quantum x60-x67 + u64 xPDCSavedSPRG1; // Saved SPRG1 for PMC int x68-x6F + u64 xPDCSavedSRR0; // Saved SRR0 for PMC int x70-x77 + volatile u32 xVirtualDecr; // Virtual DECR for shared procsx78-x7B + u32 xRsvd2_2; // Reserved x7C-x7F + +//============================================================================= +// CACHE_LINE_3 0x0100 - 0x007F: This line is shared with other processors +//============================================================================= + // This is the xYieldCount. An "odd" value (low bit on) means that + // the processor is yielded (either because of an OS yield or a PLIC + // preempt). An even value implies that the processor is currently + // executing. + // NOTE: This value will ALWAYS be zero for dedicated processors and + // will NEVER be zero for shared processors (ie, initialized to a 1). + volatile u32 xYieldCount; // PLIC increments each dispatchx00-x03 + u8 xRsvd3_0[124]; // Reserved x04-x7F + +//============================================================================= +// CACHE_LINE_4-5 0x0100 - 0x01FF Contains PMC interrupt data +//============================================================================= + u8 xPmcSaveArea[256]; // PMC interrupt Area x00-xFF + + +}; +#endif // _ITLPPACA_H diff --git a/include/asm-ppc/iSeries/ItLpQueue.h b/include/asm-ppc/iSeries/ItLpQueue.h new file mode 100644 index 000000000000..a9af28b6fe52 --- /dev/null +++ b/include/asm-ppc/iSeries/ItLpQueue.h @@ -0,0 +1,94 @@ +/* + * ItLpQueue.h + * Copyright (C) 2001 Mike Corrigan IBM Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +//============================================================================= +// +// This control block defines the simple LP queue structure that is +// shared between the hypervisor (PLIC) and the OS in order to send +// events to an LP. +// + +#ifndef _PPC_TYPES_H +#include <asm/types.h> +#endif +#include <asm/ptrace.h> + + +struct HvLpEvent; + + +#ifndef _ITLPQUEUE_H +#define _ITLPQUEUE_H + +#define ITMaxLpQueues 8 + +#define NotUsed 0 // Queue will not be used by PLIC +#define DedicatedIo 1 // Queue dedicated to IO processor specified +#define DedicatedLp 2 // Queue dedicated to LP specified +#define Shared 3 // Queue shared for both IO and LP + +#define LpEventStackSize 4096 +#define LpEventMaxSize 256 +#define LpEventAlign 64 + +struct ItLpQueue +{ +// +// The xSlicCurEventPtr is the pointer to the next event stack entry that will +// become valid. The OS must peek at this entry to determine if it is valid. +// PLIC will set the valid indicator as the very last store into that entry. +// +// When the OS has completed processing of the event then it will mark the event +// as invalid so that PLIC knows it can store into that event location again. +// +// If the event stack fills and there are overflow events, then PLIC will set +// the xPlicOverflowIntPending flag in which case the OS will have to fetch the +// additional LP events once they have drained the event stack. +// +// The first 16-bytes are known by both the OS and PLIC. The remainder of the +// cache line is for use by the OS. +// +//============================================================================= + u8 xPlicOverflowIntPending; // 0x00 Overflow events are pending + u8 xPlicStatus; // 0x01 DedicatedIo or DedicatedLp or NotUsed + u16 xSlicLogicalProcIndex; // 0x02 Logical Proc Index for correlation + u8 xPlicRsvd[12]; // 0x04 + u32 xHSlicCurEventPtr; // 0x10 High 32 bits of ptr + char* xSlicCurEventPtr; // 0x14 Low 32 bits of ptr + u32 xHSlicLastValidEventPtr; // 0x18 High 32 bits of ptr + char* xSlicLastValidEventPtr; // 0x1C Low 32 bits of ptr + u32 xHSlicEventStackPtr; // 0x20 High 32 bits of ptr + char* xSlicEventStackPtr; // 0x24 Low 32 bits of ptr + u8 xIndex; // 0x28 unique sequential index. + u8 xSlicRsvd[3]; // 0x29-2B + u32 xInUseWord; // 0x2C + u64 xLpIntCount; // 0x30 Total Lp Int msgs processed + u64 xLpIntCountByType[9]; // 0x38-0x7F Event counts by type +}; + +extern struct ItLpQueue xItLpQueue; + +extern struct HvLpEvent * ItLpQueue_getNextLpEvent( struct ItLpQueue * ); +extern int ItLpQueue_isLpIntPending( struct ItLpQueue * ); +extern unsigned ItLpQueue_process( struct ItLpQueue *, struct pt_regs * ); +extern void ItLpQueue_clearValid( struct HvLpEvent * ); + + +//============================================================================= +#endif // _ITLPQUEUE_H diff --git a/include/asm-ppc/iSeries/ItLpRegSave.h b/include/asm-ppc/iSeries/ItLpRegSave.h new file mode 100644 index 000000000000..e836f65ab7e9 --- /dev/null +++ b/include/asm-ppc/iSeries/ItLpRegSave.h @@ -0,0 +1,87 @@ +/* + * ItLpRegSave.h + * Copyright (C) 2001 Mike Corrigan IBM Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +//===================================================================================== +// +// This control block contains the data that is shared between PLIC +// and the OS +// +// + +#ifndef _ITLPREGSAVE_H +#define _ITLPREGSAVE_H + +struct ItLpRegSave +{ + u32 xDesc; // Eye catcher "LpRS" ebcdic 000-003 + u16 xSize; // Size of this class 004-005 + u8 xInUse; // Area is live 006-007 + u8 xRsvd1[9]; // Reserved 007-00F + + u8 xFixedRegSave[352]; // Fixed Register Save Area 010-16F + u32 xCTRL; // Control Register 170-173 + u32 xDEC; // Decrementer 174-177 + u32 xFPSCR; // FP Status and Control Reg 178-17B + u32 xPVR; // Processor Version Number 17C-17F + + u64 xMMCR0; // Monitor Mode Control Reg 0 180-187 + u32 xPMC1; // Perf Monitor Counter 1 188-18B + u32 xPMC2; // Perf Monitor Counter 2 18C-18F + u32 xPMC3; // Perf Monitor Counter 3 190-193 + u32 xPMC4; // Perf Monitor Counter 4 194-197 + u32 xPIR; // Processor ID Reg 198-19B + + u32 xMMCR1; // Monitor Mode Control Reg 1 19C-19F + u32 xMMCRA; // Monitor Mode Control Reg A 1A0-1A3 + u32 xPMC5; // Perf Monitor Counter 5 1A4-1A7 + u32 xPMC6; // Perf Monitor Counter 6 1A8-1AB + u32 xPMC7; // Perf Monitor Counter 7 1AC-1AF + u32 xPMC8; // Perf Monitor Counter 8 1B0-1B3 + u32 xTSC; // Thread Switch Control 1B4-1B7 + u32 xTST; // Thread Switch Timeout 1B8-1BB + u32 xRsvd; // Reserved 1BC-1BF + + u64 xACCR; // Address Compare Control Reg 1C0-1C7 + u64 xIMR; // Instruction Match Register 1C8-1CF + u64 xSDR1; // Storage Description Reg 1 1D0-1D7 + u64 xSPRG0; // Special Purpose Reg General0 1D8-1DF + u64 xSPRG1; // Special Purpose Reg General1 1E0-1E7 + u64 xSPRG2; // Special Purpose Reg General2 1E8-1EF + u64 xSPRG3; // Special Purpose Reg General3 1F0-1F7 + u64 xTB; // Time Base Register 1F8-1FF + + u64 xFPR[32]; // Floating Point Registers 200-2FF + + u64 xMSR; // Machine State Register 300-307 + u64 xNIA; // Next Instruction Address 308-30F + + u64 xDABR; // Data Address Breakpoint Reg 310-317 + u64 xIABR; // Inst Address Breakpoint Reg 318-31F + + u64 xHID0; // HW Implementation Dependent0 320-327 + + u64 xHID4; // HW Implementation Dependent4 328-32F + u64 xSCOMd; // SCON Data Reg (SPRG4) 330-337 + u64 xSCOMc; // SCON Command Reg (SPRG5) 338-33F + u64 xSDAR; // Sample Data Address Register 340-347 + u64 xSIAR; // Sample Inst Address Register 348-34F + + u8 xRsvd3[176]; // Reserved 350-3FF +}; +#endif // _ITLPREGSAVE_H diff --git a/include/asm-ppc/iSeries/ItSpCommArea.h b/include/asm-ppc/iSeries/ItSpCommArea.h new file mode 100644 index 000000000000..475d3ecb309e --- /dev/null +++ b/include/asm-ppc/iSeries/ItSpCommArea.h @@ -0,0 +1,39 @@ +/* + * ItSpCommArea.h + * Copyright (C) 2001 Mike Corrigan IBM Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#ifndef _ITSPCOMMAREA_H +#define _ITSPCOMMAREA_H + + +struct SpCommArea +{ + u32 xDesc; // Descriptor (only in new formats) 000-003 + u8 xFormat; // Format (only in new formats) 004-004 + u8 xRsvd1[11]; // Reserved 005-00F + u64 xRawTbAtIplStart; // Raw HW TB value when IPL is started 010-017 + u64 xRawTodAtIplStart; // Raw HW TOD value when IPL is started 018-01F + u64 xBcdTimeAtIplStart; // BCD time when IPL is started 020-027 + u64 xBcdTimeAtOsStart; // BCD time when OS passed control 028-02F + u8 xRsvd2[80]; // Reserved 030-07F +}; + +extern struct SpCommArea xSpCommArea; + +#endif /* _ITSPCOMMAREA_H */ diff --git a/include/asm-ppc/iSeries/ItVpdAreas.h b/include/asm-ppc/iSeries/ItVpdAreas.h new file mode 100644 index 000000000000..8958a0ca8ff6 --- /dev/null +++ b/include/asm-ppc/iSeries/ItVpdAreas.h @@ -0,0 +1,100 @@ +/* + * ItVpdAreas.h + * Copyright (C) 2001 Mike Corrigan IBM Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +//===================================================================================== +// +// This file defines the address and length of all of the VPD area passed to +// the OS from PLIC (most of which start from the SP). +// + +#ifndef _PPC_TYPES_H +#include <asm/types.h> +#endif + + +#ifndef _ITVPDAREAS_H +#define _ITVPDAREAS_H + +// VPD Entry index is carved in stone - cannot be changed (easily). +#define ItVpdCecVpd 0 +#define ItVpdDynamicSpace 1 +#define ItVpdExtVpd 2 +#define ItVpdExtVpdOnPanel 3 +#define ItVpdFirstPaca 4 +#define ItVpdIoVpd 5 +#define ItVpdIplParms 6 +#define ItVpdMsVpd 7 +#define ItVpdPanelVpd 8 +#define ItVpdLpNaca 9 +#define ItVpdBackplaneAndMaybeClockCardVpd 10 +#define ItVpdRecoveryLogBuffer 11 +#define ItVpdSpCommArea 12 +#define ItVpdSpLogBuffer 13 +#define ItVpdSpLogBufferSave 14 +#define ItVpdSpCardVpd 15 +#define ItVpdFirstProcVpd 16 +#define ItVpdApModelVpd 17 +#define ItVpdClockCardVpd 18 +#define ItVpdBusExtCardVpd 19 +#define ItVpdProcCapacityVpd 20 +#define ItVpdInteractiveCapacityVpd 21 +#define ItVpdFirstSlotLabel 22 +#define ItVpdFirstLpQueue 23 +#define ItVpdFirstL3CacheVpd 24 +#define ItVpdFirstProcFruVpd 25 + +#define ItVpdMaxEntries 26 + + +#define ItDmaMaxEntries 10 + +#define ItVpdAreasMaxSlotLabels 192 + + +struct SlicVpdAdrs { + u32 pad1; + void * vpdAddr; +}; + + +struct ItVpdAreas +{ + u32 xSlicDesc; // Descriptor 000-003 + u16 xSlicSize; // Size of this control block 004-005 + u16 xPlicAdjustVpdLens:1; // Flag to indicate new interface 006-007 + u16 xRsvd1:15; // Reserved bits ... + u16 xSlicVpdEntries; // Number of VPD entries 008-009 + u16 xSlicDmaEntries; // Number of DMA entries 00A-00B + u16 xSlicMaxLogicalProcs; // Maximum logical processors 00C-00D + u16 xSlicMaxPhysicalProcs; // Maximum physical processors 00E-00F + u16 xSlicDmaToksOffset; // Offset into this of array 010-011 + u16 xSlicVpdAdrsOffset; // Offset into this of array 012-013 + u16 xSlicDmaLensOffset; // Offset into this of array 014-015 + u16 xSlicVpdLensOffset; // Offset into this of array 016-017 + u16 xSlicMaxSlotLabels; // Maximum number of slot labels 018-019 + u16 xSlicMaxLpQueues; // Maximum number of LP Queues 01A-01B + u8 xRsvd2[4]; // Reserved 01C-01F + u64 xRsvd3[12]; // Reserved 020-07F + u32 xPlicDmaLens[ItDmaMaxEntries];// Array of DMA lengths 080-0A7 + u32 xPlicDmaToks[ItDmaMaxEntries];// Array of DMA tokens 0A8-0CF + u32 xSlicVpdLens[ItVpdMaxEntries];// Array of VPD lengths 0D0-12F + struct SlicVpdAdrs xSlicVpdAdrs[ItVpdMaxEntries];// Array of VPD buffers 130-1EF +}; + +#endif // _ITVPDAREAS_H diff --git a/include/asm-ppc/iSeries/LparData.h b/include/asm-ppc/iSeries/LparData.h new file mode 100644 index 000000000000..63ed9a84955b --- /dev/null +++ b/include/asm-ppc/iSeries/LparData.h @@ -0,0 +1,75 @@ +/* + * LparData.h + * Copyright (C) 2001 Mike Corrigan IBM Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _PPC_TYPES_H +#include <asm/types.h> +#endif + +#ifndef _LPARDATA_H +#define _LPARDATA_H + +#include <asm/page.h> + +extern u32 msChunks[]; + +#define phys_to_absolute( x ) (((u64)msChunks[((x)>>18)])<<18)+((u64)((x)&0x3ffff)) + +#define physRpn_to_absRpn( x ) (((u64)msChunks[((x)>>6)])<<6)+((u64)((x)&0x3f)) + +#define virt_to_absolute( x ) (((u64)msChunks[(((x)-KERNELBASE)>>18)])<<18)+((u64)((x)&0x3ffff)) + +extern u64 virt_to_absolute_outline(u32 address); + + +#include <asm/iSeries/Naca.h> +#include <asm/iSeries/ItLpNaca.h> +#include <asm/iSeries/ItLpPaca.h> +#include <asm/iSeries/ItLpRegSave.h> +#include <asm/iSeries/Paca.h> +#include <asm/iSeries/HvReleaseData.h> +#include <asm/iSeries/LparMap.h> +#include <asm/iSeries/ItVpdAreas.h> +#include <asm/iSeries/ItIplParmsReal.h> +#include <asm/iSeries/ItLpQueue.h> +#include <asm/iSeries/IoHriProcessorVpd.h> +#include <asm/page.h> + +extern struct LparMap xLparMap; +extern struct Naca xNaca; +extern struct Paca xPaca[]; +extern struct HvReleaseData hvReleaseData; +extern struct ItLpNaca itLpNaca; +extern struct ItIplParmsReal xItIplParmsReal; +extern struct IoHriProcessorVpd xIoHriProcessorVpd[]; +extern struct ItLpQueue xItLpQueue; +extern struct ItVpdAreas itVpdAreas; +extern u64 xMsVpd[]; +extern u32 msChunks[]; +extern u32 totalLpChunks; +extern unsigned maxPacas; + +/* +#define phys_to_absolute( x ) (((u64)msChunks[((x)>>18)])<<18)+((u64)((x)&0x3ffff)) + +#define physRpn_to_absRpn( x ) (((u64)msChunks[((x)>>6)])<<6)+((u64)((x)&0x3f)) + +#define virt_to_absolute( x ) (((u64)msChunks[(((x)-KERNELBASE)>>18)])<<18)+((u64)((x)&0x3ffff)) +*/ + +#endif /* _LPAR_DATA_H */ diff --git a/include/asm-ppc/iSeries/LparMap.h b/include/asm-ppc/iSeries/LparMap.h new file mode 100644 index 000000000000..179ab2c7209c --- /dev/null +++ b/include/asm-ppc/iSeries/LparMap.h @@ -0,0 +1,76 @@ +/* + * LparMap.h + * Copyright (C) 2001 Mike Corrigan IBM Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _PPC_TYPES_H +#include <asm/types.h> +#endif + +#ifndef _LPARMAP_H +#define _LPARMAP_H + +/* The iSeries hypervisor will set up mapping for one or more + * ESID/VSID pairs (in SLB/segment registers) and will set up + * mappings of one or more ranges of pages to VAs. + * We will have the hypervisor set up the ESID->VSID mapping + * for the four kernel segments (C-F). With shared processors, + * the hypervisor will clear all segment registers and reload + * these four whenever the processor is switched from one + * partition to another. + */ + +/* The Vsid and Esid identified below will be used by the hypervisor + * to set up a memory mapping for part of the load area before giving + * control to the Linux kernel. The load area is 64 MB, but this must + * not attempt to map the whole load area. The Hashed Page Table may + * need to be located within the load area (if the total partition size + * is 64 MB), but cannot be mapped. Typically, this should specify + * to map half (32 MB) of the load area. + * + * The hypervisor will set up page table entries for the number of + * pages specified. + * + * In 32-bit mode, the hypervisor will load all four of the + * segment registers (identified by the low-order four bits of the + * Esid field. In 64-bit mode, the hypervisor will load one SLB + * entry to map the Esid to the Vsid. +*/ + +// Hypervisor initially maps 32MB of the load area +#define HvPagesToMap 8192 + +struct LparMap +{ + u64 xNumberEsids; // Number of ESID/VSID pairs (4) + u64 xNumberRanges; // Number of VA ranges to map (1) + u64 xSegmentTableOffs; // Page number within load area of seg table (0) + u64 xRsvd[5]; // Reserved (0) + u64 xKernelEsidC; // Esid used to map kernel load (0x0C) + u64 xKernelVsidC; // Vsid used to map kernel load (0x0C) + u64 xKernelEsidD; // Esid used to map kernel load (0x0D) + u64 xKernelVsidD; // Vsid used to map kernel load (0x0D) + u64 xKernelEsidE; // Esid used to map kernel load (0x0E) + u64 xKernelVsidE; // Vsid used to map kernel load (0x0E) + u64 xKernelEsidF; // Esid used to map kernel load (0x0F) + u64 xKernelVsidF; // Vsid used to map kernel load (0x0F) + u64 xPages; // Number of pages to be mapped (8192) + u64 xOffset; // Offset from start of load area (0) + u64 xVPN; // Virtual Page Number (0x00000000000C0000) +}; + +#endif /* _LPARMAP_H */ diff --git a/include/asm-ppc/iSeries/Naca.h b/include/asm-ppc/iSeries/Naca.h new file mode 100644 index 000000000000..c34294288717 --- /dev/null +++ b/include/asm-ppc/iSeries/Naca.h @@ -0,0 +1,38 @@ +/* + * Naca.h + * Copyright (C) 2001 Mike Corrigan IBM Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _PPC_TYPES_H +#include <asm/types.h> +#endif + +#ifndef _NACA_H +#define _NACA_H + + +struct Naca +{ + u32 xItVpdAreas64; // Address of ItVpdAreas + void * xItVpdAreas; + u32 xRamDisk64; // Address of initial Ramdisk + u32 xRamDisk; + u32 xRamDiskSize64; // Size of initial Ramdisk + u32 xRamDiskSize; // in pages +}; + +#endif /* _NACA_H */ diff --git a/include/asm-ppc/iSeries/Paca.h b/include/asm-ppc/iSeries/Paca.h new file mode 100644 index 000000000000..f9ff68a97e91 --- /dev/null +++ b/include/asm-ppc/iSeries/Paca.h @@ -0,0 +1,137 @@ +/* + * Paca.h + * Copyright (C) 2001 Mike Corrigan IBM Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +//============================================================================ +// +// This control block defines the OS's PACA which defines the processor +// specific data for each logical processor on the system. +// There are some pointers defined that are utilized by PLIC. +// + +#ifndef _PPC_TYPES_H +#include <asm/types.h> +#endif + +//----------------------------------------------------------------------------- +// Other Includes +//----------------------------------------------------------------------------- +#ifndef _ITLPPACA_H +#include <asm/iSeries/ItLpPaca.h> +#endif + +#ifndef _ITLPREGSAVE_H +#include <asm/iSeries/ItLpRegSave.h> +#endif + +#ifndef _ITLPQUEUE_H +#include <asm/iSeries/ItLpQueue.h> +#endif + + +#ifndef _PACA_H +#define _PACA_H + +/* + * The bolted stack structure is at the head of each bolted stack + * and is simply a singly linked list + */ + +//============================================================================ +// +// Defines the layout of the Paca. +// +// This structure is not directly accessed by PLIC or the SP except +// for the first two pointers that point to the ItLpPaca area and the +// ItLpRegSave area for this processor. +// +//============================================================================ +struct Paca +{ +//=========================================================================== +// Following two fields are read by PLIC to find the LpPaca and LpRegSave area +//=========================================================================== + + u32 pad1; // Pointer to LpPaca for proc + struct ItLpPaca * xLpPacaPtr; // Pointer to LpPaca for proc + u32 pad2; // Pointer to LpRegSave for proc + struct ItLpRegSave * xLpRegSavePtr; // Pointer to LpRegSave for proc + + u64 xR21; // Savearea for GPR21 + u64 xR22; // Savearea for GPR22 + u64 xKsave; // Saved Kernel stack addr or zero + + u16 xPacaIndex; // Index into Paca array of this + // Paca. This is processor number + u8 xProcStart; // At startup, processor spins until + // xProcStart becomes non-zero. + u8 xProcEnabled; // 1 - soft enabled, 0 - soft disabled + u32 xrsvd2; // was bolted stacks + u32 xSavedMsr; // old msr saved here by HvCall + // and flush_hash_page. + // HvCall uses 64-bit registers + // so it must disable external + // interrupts to avoid the high + // half of the regs getting lost + // It can't stack a frame because + // some of the callers can't + // tolerate hpt faults (which might + // occur on the stack) + u32 xSavedLr; // link register saved here by + // flush_hash_page + u8 xContextOverflow; // 1 - context overflow - use temporary + // context = processor# + 1 + u8 rsvd4; + u16 rsvd5; + u32 xSRR0; // Used as bolted copies of stack fields + u32 xSRR1; + u32 xGPR0; + u32 xGPR2; + u32 default_decr; // Default decrementer value + u32 ext_ints; // ext ints processed + u32 rsvd6; + u64 rsvd1[5]; // Rest of cache line reserved + +//=========================================================================== +// CACHE_LINE_2-3 0x0080 - 0x0180 +//=========================================================================== + + struct ItLpQueue * lpQueuePtr; // LpQueue handled by this processor + u32 breakpoint_loop; // Loop until this field is set + // non-zero by user. Then set it + // back to zero before continuing + + u64 debug_regs; // Pointer to pt_regs at breakpoint + u64 rsvd3[30]; // To be used by Linux + +//=========================================================================== +// CACHE_LINE_4-8 0x0180 - 0x03FF Contains ItLpPaca +//=========================================================================== + + struct ItLpPaca xLpPaca; // Space for ItLpPaca + +//=========================================================================== +// CACHE_LINE_9-16 0x0400 - 0x07FF Contains ItLpRegSave +//=========================================================================== + + struct ItLpRegSave xRegSav; // Register save for proc + +}; + +#endif /* _PACA_H */ diff --git a/include/asm-ppc/iSeries/XmPciLpEvent.h b/include/asm-ppc/iSeries/XmPciLpEvent.h new file mode 100644 index 000000000000..a3d27f116e49 --- /dev/null +++ b/include/asm-ppc/iSeries/XmPciLpEvent.h @@ -0,0 +1,18 @@ + +#ifndef __XMPCILPEVENT_H__ +#define __XMPCILPEVENT_H__ + + +#ifdef __cplusplus +extern "C" { +#endif + +int XmPciLpEvent_init(void); +void ppc_irq_dispatch_handler(struct pt_regs *regs, int irq); + + +#ifdef __cplusplus +} +#endif + +#endif /* __XMPCILPEVENT_H__ */ diff --git a/include/asm-ppc/iSeries/iSeries_FlightRecorder.h b/include/asm-ppc/iSeries/iSeries_FlightRecorder.h new file mode 100644 index 000000000000..5cc1d7e7d876 --- /dev/null +++ b/include/asm-ppc/iSeries/iSeries_FlightRecorder.h @@ -0,0 +1,85 @@ +#ifndef _ISERIES_FLIGHTRECORDER_H +#define _ISERIES_FLIGHTRECORDER_H +/************************************************************************/ +/* File iSeries_FlightRecorder.h created by Allan Trautman Jan 22 2001. */ +/************************************************************************/ +/* This code supports the pci interface on the IBM iSeries systems. */ +/* Copyright (C) 20yy <Allan H Trautman> <IBM Corp> */ +/* */ +/* This program is free software; you can redistribute it and/or modify */ +/* it under the terms of the GNU General Public License as published by */ +/* the Free Software Foundation; either version 2 of the License, or */ +/* (at your option) any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, */ +/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ +/* GNU General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU General Public License */ +/* along with this program; if not, write to the: */ +/* Free Software Foundation, Inc., */ +/* 59 Temple Place, Suite 330, */ +/* Boston, MA 02111-1307 USA */ +/************************************************************************/ +/* Change Activity: */ +/* Created, Jan 22, 2001 */ +/* Added Time stamp methods. Apr 12, 2001 */ +/* End Change Activity */ +/************************************************************************/ +/* This is a generic Flight Recorder, simply stuffs line entries into a */ +/* buffer for debug purposes. */ +/* */ +/* To use, */ +/* 1. Create one, make it global so it isn't on the stack. */ +/* FlightRecorder PciFlightRecorder; */ +/* */ +/* 2. Optionally create a pointer to it, just makes it easier to use. */ +/* FlightRecorder* PciFr = &PciFlightRecorder; */ +/* */ +/* 3. Initialize with you signature. */ +/* iSeries_Fr_Initialize(PciFr, "Pci Flight Recorder"); */ +/* */ +/* 4. Log entries. */ +/* PciFr->logEntry(PciFr,"In Main"); */ +/* */ +/* 5. Later, you can find the Flight Recorder by looking in the */ +/* System.map */ +/************************************************************************/ +struct iSeries_FlightRecorder; /* Forward declares */ +struct rtc_time; +void logEntry(struct iSeries_FlightRecorder*, char* Text); +void logTime( struct iSeries_FlightRecorder*, char* Text); +void logDate( struct iSeries_FlightRecorder*, char* Text); +#define FlightRecorderSize 4096 + +/************************************************************************/ +/* Generic Flight Recorder Structure */ +/************************************************************************/ +struct iSeries_FlightRecorder { /* Structure Defination */ + char Signature[16]; /* Eye Catcher */ + char* StartingPointer; /* Buffer Starting Address */ + char* CurrentPointer; /* Next Entry Address */ + int WrapCount; /* Number of Buffer Wraps */ + void (*logEntry)(struct iSeries_FlightRecorder*,char*); + void (*logTime) (struct iSeries_FlightRecorder*,char*); + void (*logDate) (struct iSeries_FlightRecorder*,char*); + char Buffer[FlightRecorderSize]; +}; + +typedef struct iSeries_FlightRecorder FlightRecorder; /* Short Name */ +extern void iSeries_Fr_Initialize(FlightRecorder*, char* Signature); +/************************************************************************/ +/* extern void iSeries_LogFr_Entry( FlightRecorder*, char* Text); */ +/* extern void iSeries_LogFr_Date( FlightRecorder*, char* Text); */ +/* extern void iSeries_LogFr_Time( FlightRecorder*, char* Text); */ +/************************************************************************/ +/* PCI Flight Recorder Helpers */ +/************************************************************************/ +extern FlightRecorder* PciFr; /* Ptr to Pci Fr */ +extern char* PciFrBuffer; /* Ptr to Fr Work Buffer */ +#define ISERIES_PCI_FR(buffer) PciFr->logEntry(PciFr,buffer); +#define ISERIES_PCI_FR_TIME(buffer) PciFr->logTime(PciFr,buffer); +#define ISERIES_PCI_FR_DATE(buffer) PciFr->logDate(PciFr,buffer); + +#endif /* _ISERIES_FLIGHTRECORDER_H */ diff --git a/include/asm-ppc/iSeries/iSeries_VpdInfo.h b/include/asm-ppc/iSeries/iSeries_VpdInfo.h new file mode 100644 index 000000000000..ed6b8e72762f --- /dev/null +++ b/include/asm-ppc/iSeries/iSeries_VpdInfo.h @@ -0,0 +1,56 @@ +#ifndef _ISERIES_VPDINFO_H +#define _ISERIES_VPDINFO_H +/************************************************************************/ +/* File iSeries_VpdInfo.h created by Allan Trautman Feb 08 2001. */ +/************************************************************************/ +/* This code supports the location data fon on the IBM iSeries systems. */ +/* Copyright (C) 20yy <Allan H Trautman> <IBM Corp> */ +/* */ +/* This program is free software; you can redistribute it and/or modify */ +/* it under the terms of the GNU General Public License as published by */ +/* the Free Software Foundation; either version 2 of the License, or */ +/* (at your option) any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, */ +/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ +/* GNU General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU General Public License */ +/* along with this program; if not, write to the: */ +/* Free Software Foundation, Inc., */ +/* 59 Temple Place, Suite 330, */ +/* Boston, MA 02111-1307 USA */ +/************************************************************************/ +/* Change Activity: */ +/* Created, Feg 8, 2001 */ +/* Reformated for Card, March 8, 2001 */ +/* End Change Activity */ +/************************************************************************/ + +struct pci_dev; /* Forward Declare */ +/************************************************************************/ +/* Location Data extracted from the VPD list and device info. */ +/************************************************************************/ +struct LocationDataStruct { /* Location data structure for device */ + u16 Bus; /* iSeries Bus Number 0x00*/ + u16 Board; /* iSeries Board 0x02*/ + u8 FrameId; /* iSeries spcn Frame Id 0x04*/ + u8 PhbId; /* iSeries Phb Location 0x05*/ + u16 Card; /* iSeries Card Slot 0x06*/ + char CardLocation[4]; /* Char format of planar vpd 0x08*/ + u8 AgentId; /* iSeries AgentId 0x0C*/ + u8 SecondaryAgentId; /* iSeries Secondary Agent Id 0x0D*/ + u8 LinuxBus; /* Linux Bus Number 0x0E*/ + u8 LinuxDevFn; /* Linux Device Function 0x0F*/ +}; +typedef struct LocationDataStruct LocationData; +#define LOCATION_DATA_SIZE 16 + +/************************************************************************/ +/* Protypes */ +/************************************************************************/ +extern LocationData* iSeries_GetLocationData(struct pci_dev* PciDev); +extern int iSeries_Device_Information(struct pci_dev*,char*, int); + +#endif /* _ISERIES_VPDINFO_H */ diff --git a/include/asm-ppc/iSeries/iSeries_dma.h b/include/asm-ppc/iSeries/iSeries_dma.h new file mode 100644 index 000000000000..8b1ad755ae82 --- /dev/null +++ b/include/asm-ppc/iSeries/iSeries_dma.h @@ -0,0 +1,97 @@ +/* + * iSeries_dma.h + * Copyright (C) 2001 Mike Corrigan IBM Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _ISERIES_DMA_H +#define _ISERIES_DMA_H + +#include <asm/types.h> +#ifndef __LINUX_SPINLOCK_H +#include <linux/spinlock.h> +#endif + +// NUM_TCE_LEVELS defines the largest contiguous block +// of dma (tce) space we can get. NUM_TCE_LEVELS = 10 +// allows up to 2**9 pages (512 * 4096) = 2 MB +#define NUM_TCE_LEVELS 10 + +#define NO_TCE ((dma_addr_t)-1) + +// Tces come in two formats, one for the virtual bus and a different +// format for PCI +#define TCE_VB 0 +#define TCE_PCI 1 + + +union Tce { + u64 wholeTce; + struct { + u64 cacheBits :6; /* Cache hash bits - not used */ + u64 rsvd :6; + u64 rpn :40; /* Absolute page number */ + u64 valid :1; /* Tce is valid (vb only) */ + u64 allIo :1; /* Tce is valid for all lps (vb only) */ + u64 lpIndex :8; /* LpIndex for user of TCE (vb only) */ + u64 pciWrite :1; /* Write allowed (pci only) */ + u64 readWrite :1; /* Read allowed (pci), Write allowed + (vb) */ + } tceBits; +}; + +struct Bitmap { + unsigned long numBits; + unsigned long numBytes; + unsigned char * map; +}; + +struct MultiLevelBitmap { + unsigned long maxLevel; + struct Bitmap level[NUM_TCE_LEVELS]; +}; + +struct TceTable { + u64 busNumber; + u64 size; + u64 startOffset; + u64 index; + spinlock_t lock; + struct MultiLevelBitmap mlbm; +}; + +struct HvTceTableManagerCB { + u64 busNumber; /* Bus number for this tce table */ + u64 start; /* Will be NULL for secondary */ + u64 totalSize; /* Size (in pages) of whole table */ + u64 startOffset; /* Index into real tce table of the + start of our section */ + u64 size; /* Size (in pages) of our section */ + u64 index; /* Index of this tce table (token?) */ + u16 maxTceTableIndex; /* Max number of tables for partition */ + u8 virtualBusFlag; /* Flag to indicate virtual bus */ + u8 rsvd[5]; +}; + +extern struct TceTable virtBusTceTable; /* Tce table for virtual bus */ + +extern struct TceTable * build_tce_table( struct HvTceTableManagerCB *, + struct TceTable *); +extern void create_virtual_bus_tce_table( void ); + +extern void create_pci_bus_tce_table( unsigned busNumber ); + +#endif // _ISERIES_DMA_H diff --git a/include/asm-ppc/iSeries/iSeries_fixup.h b/include/asm-ppc/iSeries/iSeries_fixup.h new file mode 100644 index 000000000000..5d1d33f16ba7 --- /dev/null +++ b/include/asm-ppc/iSeries/iSeries_fixup.h @@ -0,0 +1,25 @@ + +#ifndef __ISERIES_FIXUP_H__ +#define __ISERIES_FIXUP_H__ +#include <linux/pci.h> + +#ifdef __cplusplus +extern "C" { +#endif + +void iSeries_fixup (void); +void iSeries_fixup_bus (struct pci_bus*); +unsigned int iSeries_scan_slot (struct pci_dev*, u16, u8, u8); + + +/* Need to store information related to the PHB bucc and make it accessible to the hose */ +struct iSeries_hose_arch_data { + u32 hvBusNumber; +}; + + +#ifdef __cplusplus +} +#endif + +#endif /* __ISERIES_FIXUP_H__ */ diff --git a/include/asm-ppc/iSeries/iSeries_io.h b/include/asm-ppc/iSeries/iSeries_io.h new file mode 100644 index 000000000000..0199ad4241d3 --- /dev/null +++ b/include/asm-ppc/iSeries/iSeries_io.h @@ -0,0 +1,42 @@ +#ifdef CONFIG_PPC_ISERIES +#ifndef _ISERIES_IO_H +#define _ISERIES_IO_H +/************************************************************************/ +/* File iSeries_io.h created by Allan Trautman on Thu Dec 28 2000. */ +/************************************************************************/ +/* Remaps the io.h for the iSeries Io */ +/* Copyright (C) 20yy Allan H Trautman, IBM Corporation */ +/* */ +/* This program is free software; you can redistribute it and/or modify */ +/* it under the terms of the GNU General Public License as published by */ +/* the Free Software Foundation; either version 2 of the License, or */ +/* (at your option) any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, */ +/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ +/* GNU General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU General Public License */ +/* along with this program; if not, write to the: */ +/* Free Software Foundation, Inc., */ +/* 59 Temple Place, Suite 330, */ +/* Boston, MA 02111-1307 USA */ +/************************************************************************/ +/* Change Activity: */ +/* Created December 28, 2000 */ +/* End Change Activity */ +/************************************************************************/ +extern u8 iSeries_Readb(u32* IoAddress); +extern u16 iSeries_Readw(u32* IoAddress); +extern u32 iSeries_Readl(u32* IoAddress); +extern void iSeries_Writeb(u8 IoData,u32* IoAddress); +extern void iSeries_Writew(u16 IoData,u32* IoAddress); +extern void iSeries_Writel(u32 IoData,u32* IoAddress); + +extern void* iSeries_memcpy_toio(void *dest, void *source, int n); +extern void* iSeries_memcpy_fromio(void *dest, void *source, int n); + +#endif /* _ISERIES_IO_H */ +#endif /* CONFIG_PPC_ISERIES */ + diff --git a/include/asm-ppc/iSeries/iSeries_irq.h b/include/asm-ppc/iSeries/iSeries_irq.h new file mode 100644 index 000000000000..a2af15e44c87 --- /dev/null +++ b/include/asm-ppc/iSeries/iSeries_irq.h @@ -0,0 +1,26 @@ + +#ifndef __ISERIES_IRQ_H__ +#define __ISERIES_IRQ_H__ + + +#ifdef __cplusplus +extern "C" { +#endif + +unsigned int iSeries_startup_IRQ(unsigned int); +void iSeries_shutdown_IRQ(unsigned int); +void iSeries_enable_IRQ(unsigned int); +void iSeries_disable_IRQ(unsigned int); +void iSeries_end_IRQ(unsigned int); +void iSeries_init_IRQ(void); +void iSeries_init_irqMap(int); +int iSeries_allocate_IRQ(HvBusNumber, HvSubBusNumber, HvAgentId); +int iSeries_assign_IRQ(int, HvBusNumber, HvSubBusNumber, HvAgentId); +void iSeries_activate_IRQs(void); + + +#ifdef __cplusplus +} +#endif + +#endif /* __ISERIES_IRQ_H__ */ diff --git a/include/asm-ppc/iSeries/iSeries_pci.h b/include/asm-ppc/iSeries/iSeries_pci.h new file mode 100644 index 000000000000..b85c597df959 --- /dev/null +++ b/include/asm-ppc/iSeries/iSeries_pci.h @@ -0,0 +1,123 @@ +#ifndef _ISERIES_32_PCI_H +#define _ISERIES_32_PCI_H +/************************************************************************/ +/* File iSeries_pci.h created by Allan Trautman on Tue Feb 20, 2001. */ +/************************************************************************/ +/* Define some useful macros for the iSeries pci routines. */ +/* Copyright (C) 20yy Allan H Trautman, IBM Corporation */ +/* */ +/* This program is free software; you can redistribute it and/or modify */ +/* it under the terms of the GNU General Public License as published by */ +/* the Free Software Foundation; either version 2 of the License, or */ +/* (at your option) any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, */ +/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ +/* GNU General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU General Public License */ +/* along with this program; if not, write to the: */ +/* Free Software Foundation, Inc., */ +/* 59 Temple Place, Suite 330, */ +/* Boston, MA 02111-1307 USA */ +/************************************************************************/ +/* Change Activity: */ +/* Created Feb 20, 2001 */ +/* Added device reset, March 22, 2001 */ +/* End Change Activity */ +/************************************************************************/ +#include <linux/config.h> +#include <asm/iSeries/HvCallPci.h> + +struct pci_dev; /* For Reference */ +/************************************************************************/ +/* Gets iSeries Bus, SubBus, of DevFn using pci_dev* structure */ +/************************************************************************/ +#define ISERIES_GET_BUS(DevPtr) iSeries_Get_Bus(DevPtr) +#define ISERIES_GET_SUBBUS(DevPtr) iSeries_Get_SubBus(DevPtr) +#define ISERIES_GET_DEVFUN(DevPtr) iSeries_Get_DevFn(DevPtr) +/************************************************************************/ +/* Functions */ +/************************************************************************/ +extern u8 iSeries_Get_Bus(struct pci_dev*); +extern u8 iSeries_Get_SubBus(struct pci_dev*); +extern u8 iSeries_Get_DevFn(struct pci_dev*); +/************************************************************************/ +/* Global Bus map */ +/************************************************************************/ +extern u8 iSeries_GlobalBusMap[256][2]; /* Global iSeries Bus Map */ + +/************************************************************************/ +/* iSeries Device Information */ +/************************************************************************/ +struct iSeries_Device_Struct { + struct pci_dev* PciDevPtr; /* Pointer to pci_dev structure */ + HvBusNumber BusNumber; /* Hypervisor Bus Number */ + HvSubBusNumber SubBus; /* Hypervisor SubBus Number */ + HvAgentId DevFn; /* Hypervisor DevFn */ + u8 BarNumber; /* Bar number on Xlates */ + u32 BarOffset; /* Offset within Bar on Xlates */ + int RCode; /* Return Code Holder */ +}; +typedef struct iSeries_Device_Struct iSeries_Device; +extern void build_iSeries_Device(iSeries_Device* Device, struct pci_dev* DevPtr); + +/************************************************************************/ +/* Formatting device information. */ +/************************************************************************/ +extern int iSeries_Device_Information(struct pci_dev*,char*,int ); + +/************************************************************************/ +/* Flight Recorder tracing */ +/************************************************************************/ +extern void iSeries_Set_PciFilter(struct pci_dev*); +extern int iSeries_Set_PciTraceFlag(int TraceFlag); +extern int iSeries_Get_PciTraceFlag(void); +extern int iSeries_Set_PciErpFlag(int ErpFlag); + +/************************************************************************/ +/* Structure to hold the data for PCI Register Save/Restore functions. */ +/************************************************************************/ +struct pci_config_reg_save_area { /* */ + u16 Flags; /* Control & Info Flags */ + u16 ByteCount; /* Number of Register Bytes to S*/ + struct pci_dev* PciDev; /* Pointer to device */ + u32 RCode; /* Holder for possible errors */ + u32 FailReg; /* Failing Register on error */ + u8 Regs[64]; /* Save Area */ +}; +typedef struct pci_config_reg_save_area PciReqsSaveArea; +/************************************************************************/ +/* Various flavors of reset device functions. */ +/************************************************************************/ +/* */ +/* iSeries_Device_Reset_NoIrq */ +/* IRQ is not disabled and default timings are used. */ +/* iSeries_Device_Reset_Generic */ +/* A generic reset, IRQ is disable and re-enabled. The assert and */ +/* wait timings will be the pci defaults. */ +/* iSeries_Device_Reset */ +/* A device Reset interface that client can control the timing of */ +/* the reset and wait delays. */ +/* */ +/* Parameters: */ +/* pci_dev = Device to reset. */ +/* AssertTime = Time in .1 seconds to hold the reset down. The */ +/* default (and minimum) is .5 seconds. */ +/* DelayTime = Time in .1 seconds to wait for device to come ready */ +/* after the reset. The default is 3 seconds. */ +/* IrgDisable = A non-zero will skip irq disable & enable. */ +/* */ +/* Return: */ +/* Zero return, reset is successful. */ +/* Non-zero return code indicates failure. */ +/************************************************************************/ +extern int iSeries_Device_Reset_NoIrq(struct pci_dev* PciDev); +extern int iSeries_Device_Reset_Generic(struct pci_dev* PciDev); +extern int iSeries_Device_Reset(struct pci_dev* PciDev, int AssertTime, int DelayTime, int IrqDisable); +extern int iSeries_Device_ToggleReset(struct pci_dev* PciDev, int AssertTime, int DelayTime); +extern int iSeries_Device_RestoreConfigRegs(PciReqsSaveArea* SaveArea); +extern PciReqsSaveArea* iSeries_Device_SaveConfigRegs(struct pci_dev* DevPtr); + +#endif /* _ISERIES_32_PCI_H */ diff --git a/include/asm-ppc/iSeries/iSeries_proc.h b/include/asm-ppc/iSeries/iSeries_proc.h new file mode 100644 index 000000000000..a1e146cb0cd1 --- /dev/null +++ b/include/asm-ppc/iSeries/iSeries_proc.h @@ -0,0 +1,37 @@ +/* + * iSeries_proc.h + * Copyright (C) 2001 Kyle A. Lucke IBM Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +/* Change Activity: */ +/* End Change Activity */ + +#ifndef _ISERIES_PROC_H +#define _ISERIES_PROC_H + +#include <linux/proc_fs.h> + +extern void iSeries_proc_early_init(void); +extern void iSeries_proc_create(void); + +typedef void (*iSeriesProcFunction)(struct proc_dir_entry *iSeries_proc); + +extern void iSeries_proc_callback(iSeriesProcFunction initFunction); + +#endif /* _iSeries_PROC_H */ + diff --git a/include/asm-ppc/iSeries/mf.h b/include/asm-ppc/iSeries/mf.h new file mode 100644 index 000000000000..262936967622 --- /dev/null +++ b/include/asm-ppc/iSeries/mf.h @@ -0,0 +1,83 @@ +/* + * mf.h + * Copyright (C) 2001 Troy D. Armstrong IBM Corporation + * + * This modules exists as an interface between a Linux secondary partition + * running on an iSeries and the primary partition's Virtual Service + * Processor (VSP) object. The VSP has final authority over powering on/off + * all partitions in the iSeries. It also provides miscellaneous low-level + * machine facility type operations. + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MF_H_INCLUDED +#define MF_H_INCLUDED + +#include <asm/iSeries/HvTypes.h> +#include <asm/iSeries/HvLpEvent.h> + +struct rtc_time; + +typedef void (*MFCompleteHandler)( void * clientToken, int returnCode ); + +extern void mf_allocateLpEvents( HvLpIndex targetLp, + HvLpEvent_Type type, + unsigned size, + unsigned amount, + MFCompleteHandler hdlr, + void * userToken ); + +extern void mf_deallocateLpEvents( HvLpIndex targetLp, + HvLpEvent_Type type, + unsigned count, + MFCompleteHandler hdlr, + void * userToken ); + +extern void mf_powerOff( void ); + +extern void mf_reboot( void ); + +extern void mf_displaySrc( u32 word ); +extern void mf_displayProgress( u16 value ); + +extern void mf_clearSrc( void ); + +extern void mf_init( void ); + +extern void mf_setSide(char side); + +extern char mf_getSide(void); + +extern void mf_setCmdLine(const char *cmdline, int size, u64 side); + +extern int mf_getCmdLine(char *cmdline, int *size, u64 side); + +extern void mf_getSrcHistory(char *buffer, int size); + +extern int mf_setVmlinuxChunk(const char *buffer, int size, int offset, u64 side); + +extern int mf_getVmlinuxChunk(char *buffer, int *size, int offset, u64 side); + +extern int mf_setRtcTime(unsigned long time); + +extern int mf_getRtcTime(unsigned long *time); + +extern int mf_getRtc( struct rtc_time * tm ); + +extern int mf_setRtc( struct rtc_time * tm ); + +#endif /* MF_H_INCLUDED */ diff --git a/include/asm-ppc/iSeries/mf_proc.h b/include/asm-ppc/iSeries/mf_proc.h new file mode 100644 index 000000000000..1e205cf49f85 --- /dev/null +++ b/include/asm-ppc/iSeries/mf_proc.h @@ -0,0 +1,33 @@ +/* + * mf_proc.h + * Copyright (C) 2001 Kyle A. Lucke IBM Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +/* Change Activity: */ +/* End Change Activity */ + +#ifndef _MF_PROC_H +#define _MF_PROC_H + +#include <linux/proc_fs.h> + +void mf_proc_init(struct proc_dir_entry *iSeries_proc); + + +#endif /* _MF_PROC_H */ + diff --git a/include/asm-ppc/iSeries/pmc_proc.h b/include/asm-ppc/iSeries/pmc_proc.h new file mode 100644 index 000000000000..31d3b6a085da --- /dev/null +++ b/include/asm-ppc/iSeries/pmc_proc.h @@ -0,0 +1,33 @@ +/* + * pmc_proc.h + * Copyright (C) 2001 Mike Corrigan IBM Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +/* Change Activity: */ +/* End Change Activity */ + +#ifndef _PMC_PROC_H +#define _PMC_PROC_H + +#include <linux/proc_fs.h> + +void pmc_proc_init(struct proc_dir_entry *iSeries_proc); + + +#endif /* _PMC_PROC_H */ + diff --git a/include/asm-ppc/iSeries/veth-proc.h b/include/asm-ppc/iSeries/veth-proc.h new file mode 100644 index 000000000000..c019ffd2b56e --- /dev/null +++ b/include/asm-ppc/iSeries/veth-proc.h @@ -0,0 +1,32 @@ +/* + * veth-proc.h + * Copyright (C) 2001 Kyle A. Lucke IBM Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +/* Change Activity: */ +/* End Change Activity */ + +#ifndef _VETH_PROC_H +#define _VETH_PROC_H + +#include <linux/proc_fs.h> + +void veth_proc_init(struct proc_dir_entry *iSeries_proc); + +#endif /* _VETH-PROC_H */ + diff --git a/include/asm-ppc/ibm403.h b/include/asm-ppc/ibm403.h new file mode 100644 index 000000000000..7845871bdc08 --- /dev/null +++ b/include/asm-ppc/ibm403.h @@ -0,0 +1,509 @@ +/* + * ibm403.h + * + * This was dirived from the ibm4xx.h and all 403 specific definitions + * where moved here. + * + * Armin Kuster <akuster@mvista.com> + * Tom Rini <trini@mvista.com> + * Oct, 2001 + * + * + * Copyright 2001 MontaVista Softare Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Version 1.0 Oct 10, 2001 - A. Kuster + * Initial version - moved 403 specific out of ibm4xx.h + * Version 1.1 Oct 25, 2001 - T. Rini + * Lots of cleanups. + */ + + +#ifdef __KERNEL__ +#ifndef __ASM_IBM403_H__ +#define __ASM_IBM403_H__ + +#include <linux/config.h> + +#if defined(CONFIG_403GCX) + +#define DCRN_BE_BASE 0x090 +#define DCRN_DMA0_BASE 0x0C0 +#define DCRN_DMA1_BASE 0x0C8 +#define DCRN_DMA2_BASE 0x0D0 +#define DCRN_DMA3_BASE 0x0D8 +#define DCRNCAP_DMA_CC 1 /* have DMA chained count capability */ +#define DCRN_DMASR_BASE 0x0E0 + +#define DCRN_EXIER_BASE 0x042 +#define DCRN_EXISR_BASE 0x040 +#define DCRN_IOCR_BASE 0x0A0 + + +/* ------------------------------------------------------------------------- */ +#endif + + + +#ifdef DCRN_BE_BASE +#define DCRN_BEAR (DCRN_BE_BASE + 0x0) /* Bus Error Address Register */ +#define DCRN_BESR (DCRN_BE_BASE + 0x1) /* Bus Error Syndrome Register*/ +#endif +/* DCRN_BESR */ +#define BESR_DSES 0x80000000 /* Data-Side Error Status */ +#define BESR_DMES 0x40000000 /* DMA Error Status */ +#define BESR_RWS 0x20000000 /* Read/Write Status */ +#define BESR_ETMASK 0x1C000000 /* Error Type */ +#define ET_PROT 0 +#define ET_PARITY 1 +#define ET_NCFG 2 +#define ET_BUSERR 4 +#define ET_BUSTO 6 + +#ifdef DCRN_CHCR_BASE +#define DCRN_CHCR0 (DCRN_CHCR_BASE + 0x0) /* Chip Control Register 1 */ +#define DCRN_CHCR1 (DCRN_CHCR_BASE + 0x1) /* Chip Control Register 2 */ +#endif +#define CHR1_CETE 0x00800000 /* CPU external timer enable */ +#define CHR1_PCIPW 0x00008000 /* PCI Int enable/Peripheral Write enable */ + +#ifdef DCRN_CHPSR_BASE +#define DCRN_CHPSR (DCRN_CHPSR_BASE + 0x0) /* Chip Pin Strapping */ +#endif + +#ifdef DCRN_CIC_BASE +#define DCRN_CICCR (DCRN_CIC_BASE + 0x0) /* CIC Control Register */ +#define DCRN_DMAS1 (DCRN_CIC_BASE + 0x1) /* DMA Select1 Register */ +#define DCRN_DMAS2 (DCRN_CIC_BASE + 0x2) /* DMA Select2 Register */ +#define DCRN_CICVCR (DCRN_CIC_BASE + 0x3) /* CIC Video COntro Register */ +#define DCRN_CICSEL3 (DCRN_CIC_BASE + 0x5) /* CIC Select 3 Register */ +#define DCRN_SGPO (DCRN_CIC_BASE + 0x6) /* CIC GPIO Output Register */ +#define DCRN_SGPOD (DCRN_CIC_BASE + 0x7) /* CIC GPIO OD Register */ +#define DCRN_SGPTC (DCRN_CIC_BASE + 0x8) /* CIC GPIO Tristate Ctrl Reg */ +#define DCRN_SGPI (DCRN_CIC_BASE + 0x9) /* CIC GPIO Input Reg */ +#endif + +#ifdef DCRN_CPMFR_BASE +#define DCRN_CPMFR (DCRN_CPMFR_BASE + 0x0) /* CPM Force */ +#endif + +#ifndef CPM_AUD +#define CPM_AUD 0x00000000 +#endif +#ifndef CPM_BRG +#define CPM_BRG 0x00000000 +#endif +#ifndef CPM_CBS +#define CPM_CBS 0x00000000 +#endif +#ifndef CPM_CPU +#define CPM_CPU 0x00000000 +#endif +#ifndef CPM_DCP +#define CPM_DCP 0x00000000 +#endif +#ifndef CPM_DCRX +#define CPM_DCRX 0x00000000 +#endif +#ifndef CPM_DENC +#define CPM_DENC 0x00000000 +#endif +#ifndef CPM_DMA +#define CPM_DMA 0x00000000 +#endif +#ifndef CPM_DSCR +#define CPM_DSCR 0x00000000 +#endif +#ifndef CPM_EBC +#define CPM_EBC 0x00000000 +#endif +#ifndef CPM_EBIU +#define CPM_EBIU 0x00000000 +#endif +#ifndef CPM_EMAC_MM +#define CPM_EMAC_MM 0x00000000 +#endif +#ifndef CPM_EMAC_RM +#define CPM_EMAC_RM 0x00000000 +#endif +#ifndef CPM_EMAC_TM +#define CPM_EMAC_TM 0x00000000 +#endif +#ifndef CPM_GPIO0 +#define CPM_GPIO0 0x00000000 +#endif +#ifndef CPM_GPT +#define CPM_GPT 0x00000000 +#endif +#ifndef CPM_I1284 +#define CPM_I1284 0x00000000 +#endif +#ifndef CPM_IIC0 +#define CPM_IIC0 0x00000000 +#endif +#ifndef CPM_IIC1 +#define CPM_IIC1 0x00000000 +#endif +#ifndef CPM_MSI +#define CPM_MSI 0x00000000 +#endif +#ifndef CPM_PCI +#define CPM_PCI 0x00000000 +#endif +#ifndef CPM_PLB +#define CPM_PLB 0x00000000 +#endif +#ifndef CPM_SC0 +#define CPM_SC0 0x00000000 +#endif +#ifndef CPM_SC1 +#define CPM_SC1 0x00000000 +#endif +#ifndef CPM_SDRAM0 +#define CPM_SDRAM0 0x00000000 +#endif +#ifndef CPM_SDRAM1 +#define CPM_SDRAM1 0x00000000 +#endif +#ifndef CPM_TMRCLK +#define CPM_TMRCLK 0x00000000 +#endif +#ifndef CPM_UART0 +#define CPM_UART0 0x00000000 +#endif +#ifndef CPM_UART1 +#define CPM_UART1 0x00000000 +#endif +#ifndef CPM_UART2 +#define CPM_UART2 0x00000000 +#endif +#ifndef CPM_UIC +#define CPM_UIC 0x00000000 +#endif +#ifndef CPM_VID2 +#define CPM_VID2 0x00000000 +#endif +#ifndef CPM_XPT27 +#define CPM_XPT27 0x00000000 +#endif +#ifndef CPM_XPT54 +#define CPM_XPT54 0x00000000 +#endif + +#ifdef DCRN_CPMSR_BASE +#define DCRN_CPMSR (DCRN_CPMSR_BASE + 0x0) /* CPM Status */ +#define DCRN_CPMER (DCRN_CPMSR_BASE + 0x1) /* CPM Enable */ +#endif + +#ifdef DCRN_DCP0_BASE +#define DCRN_DCP0_CFGADDR (DCRN_DCP0_BASE + 0x0) /* Decompression Controller Address */ +#define DCRN_DCP0_CFGDATA (DCRN_DCP0_BASE + 0x1) /* Decompression Controller Data */ +#endif + +#ifdef DCRN_DCRX_BASE +#define DCRN_DCRXICR (DCRN_DCRX_BASE + 0x0) /* Internal Control Register */ +#define DCRN_DCRXISR (DCRN_DCRX_BASE + 0x1) /* Internal Status Register */ +#define DCRN_DCRXECR (DCRN_DCRX_BASE + 0x2) /* External Control Register */ +#define DCRN_DCRXESR (DCRN_DCRX_BASE + 0x3) /* External Status Register */ +#define DCRN_DCRXTAR (DCRN_DCRX_BASE + 0x4) /* Target Address Register */ +#define DCRN_DCRXTDR (DCRN_DCRX_BASE + 0x5) /* Target Data Register */ +#define DCRN_DCRXIGR (DCRN_DCRX_BASE + 0x6) /* Interrupt Generation Register */ +#define DCRN_DCRXBCR (DCRN_DCRX_BASE + 0x7) /* Line Buffer Control Register */ +#endif + +#ifdef DCRN_DMA0_BASE +#define DCRN_DMACR0 (DCRN_DMA0_BASE + 0x0) /* DMA Channel Control Register 0 */ +#define DCRN_DMACT0 (DCRN_DMA0_BASE + 0x1) /* DMA Count Register 0 */ +#define DCRN_DMADA0 (DCRN_DMA0_BASE + 0x2) /* DMA Destination Address Register 0 */ +#define DCRN_DMASA0 (DCRN_DMA0_BASE + 0x3) /* DMA Source Address Register 0 */ +#ifdef DCRNCAP_DMA_CC +#define DCRN_DMACC0 (DCRN_DMA0_BASE + 0x4) /* DMA Chained Count Register 0 */ +#endif + +#ifdef DCRNCAP_DMA_SG +#define DCRN_ASG0 (DCRN_DMA0_BASE + 0x4) /* DMA Scatter/Gather Descriptor Addr 0 */ +#endif +#endif + +#ifdef DCRN_DMA1_BASE +#define DCRN_DMACR1 (DCRN_DMA1_BASE + 0x0) /* DMA Channel Control Register 1 */ +#define DCRN_DMACT1 (DCRN_DMA1_BASE + 0x1) /* DMA Count Register 1 */ +#define DCRN_DMADA1 (DCRN_DMA1_BASE + 0x2) /* DMA Destination Address Register 1 */ +#define DCRN_DMASA1 (DCRN_DMA1_BASE + 0x3) /* DMA Source Address Register 1 */ + +#ifdef DCRNCAP_DMA_CC +#define DCRN_DMACC1 (DCRN_DMA1_BASE + 0x4) /* DMA Chained Count Register 1 */ +#endif +#ifdef DCRNCAP_DMA_SG +#define DCRN_ASG1 (DCRN_DMA1_BASE + 0x4) /* DMA Scatter/Gather Descriptor Addr 1 */ +#endif +#endif + +#ifdef DCRN_DMA2_BASE +#define DCRN_DMACR2 (DCRN_DMA2_BASE + 0x0) /* DMA Channel Control Register 2 */ +#define DCRN_DMACT2 (DCRN_DMA2_BASE + 0x1) /* DMA Count Register 2 */ +#define DCRN_DMADA2 (DCRN_DMA2_BASE + 0x2) /* DMA Destination Address Register 2 */ +#define DCRN_DMASA2 (DCRN_DMA2_BASE + 0x3) /* DMA Source Address Register 2 */ +#ifdef DCRNCAP_DMA_CC +#define DCRN_DMACC2 (DCRN_DMA2_BASE + 0x4) /* DMA Chained Count Register 2 */ +#endif +#ifdef DCRNCAP_DMA_SG +#define DCRN_ASG2 (DCRN_DMA2_BASE + 0x4) /* DMA Scatter/Gather Descriptor Addr 2 */ +#endif +#endif + +#ifdef DCRN_DMA3_BASE +#define DCRN_DMACR3 (DCRN_DMA3_BASE + 0x0) /* DMA Channel Control Register 3 */ +#define DCRN_DMACT3 (DCRN_DMA3_BASE + 0x1) /* DMA Count Register 3 */ +#define DCRN_DMADA3 (DCRN_DMA3_BASE + 0x2) /* DMA Destination Address Register 3 */ +#define DCRN_DMASA3 (DCRN_DMA3_BASE + 0x3) /* DMA Source Address Register 3 */ +#ifdef DCRNCAP_DMA_CC +#define DCRN_DMACC3 (DCRN_DMA3_BASE + 0x4) /* DMA Chained Count Register 3 */ +#endif +#ifdef DCRNCAP_DMA_SG +#define DCRN_ASG3 (DCRN_DMA3_BASE + 0x4) /* DMA Scatter/Gather Descriptor Addr 3 */ +#endif +#endif + +#ifdef DCRN_DMASR_BASE +#define DCRN_DMASR (DCRN_DMASR_BASE + 0x0) /* DMA Status Register */ +#ifdef DCRNCAP_DMA_SG +#define DCRN_ASGC (DCRN_DMASR_BASE + 0x3) /* DMA Scatter/Gather Command */ +/* don't know if these two registers always exist if scatter/gather exists */ +#define DCRN_POL (DCRN_DMASR_BASE + 0x6) /* DMA Polarity Register */ +#define DCRN_SLP (DCRN_DMASR_BASE + 0x5) /* DMA Sleep Register */ +#endif +#endif + +#ifdef DCRN_EBC_BASE +#define DCRN_EBCCFGADR (DCRN_EBC_BASE + 0x0) /* Peripheral Controller Address */ +#define DCRN_EBCCFGDATA (DCRN_EBC_BASE + 0x1) /* Peripheral Controller Data */ +#endif + +#ifdef DCRN_EXIER_BASE +#define DCRN_EXIER (DCRN_EXIER_BASE + 0x0) /* External Interrupt Enable Register */ +#endif + +#ifdef DCRN_EBIMC_BASE +#define DCRN_BRCRH0 (DCRN_EBIMC_BASE + 0x0) /* Bus Region Config High 0 */ +#define DCRN_BRCRH1 (DCRN_EBIMC_BASE + 0x1) /* Bus Region Config High 1 */ +#define DCRN_BRCRH2 (DCRN_EBIMC_BASE + 0x2) /* Bus Region Config High 2 */ +#define DCRN_BRCRH3 (DCRN_EBIMC_BASE + 0x3) /* Bus Region Config High 3 */ +#define DCRN_BRCRH4 (DCRN_EBIMC_BASE + 0x4) /* Bus Region Config High 4 */ +#define DCRN_BRCRH5 (DCRN_EBIMC_BASE + 0x5) /* Bus Region Config High 5 */ +#define DCRN_BRCRH6 (DCRN_EBIMC_BASE + 0x6) /* Bus Region Config High 6 */ +#define DCRN_BRCRH7 (DCRN_EBIMC_BASE + 0x7) /* Bus Region Config High 7 */ +#define DCRN_BRCR0 (DCRN_EBIMC_BASE + 0x10)/* BRC 0 */ +#define DCRN_BRCR1 (DCRN_EBIMC_BASE + 0x11)/* BRC 1 */ +#define DCRN_BRCR2 (DCRN_EBIMC_BASE + 0x12)/* BRC 2 */ +#define DCRN_BRCR3 (DCRN_EBIMC_BASE + 0x13)/* BRC 3 */ +#define DCRN_BRCR4 (DCRN_EBIMC_BASE + 0x14)/* BRC 4 */ +#define DCRN_BRCR5 (DCRN_EBIMC_BASE + 0x15)/* BRC 5 */ +#define DCRN_BRCR6 (DCRN_EBIMC_BASE + 0x16)/* BRC 6 */ +#define DCRN_BRCR7 (DCRN_EBIMC_BASE + 0x17)/* BRC 7 */ +#define DCRN_BEAR0 (DCRN_EBIMC_BASE + 0x20)/* Bus Error Address Register */ +#define DCRN_BESR0 (DCRN_EBIMC_BASE + 0x21)/* Bus Error Status Register */ +#define DCRN_BIUCR (DCRN_EBIMC_BASE + 0x2A)/* Bus Interfac Unit Ctrl Reg */ +#endif + +#ifdef DCRN_EXISR_BASE +#define DCRN_EXISR (DCRN_EXISR_BASE + 0x0) /* External Interrupt Status Register */ +#endif +#define EXIER_CIE 0x80000000 /* Critical Interrupt Enable */ +#define EXIER_SRIE 0x08000000 /* Serial Port Rx Int. Enable */ +#define EXIER_STIE 0x04000000 /* Serial Port Tx Int. Enable */ +#define EXIER_JRIE 0x02000000 /* JTAG Serial Port Rx Int. Enable */ +#define EXIER_JTIE 0x01000000 /* JTAG Serial Port Tx Int. Enable */ +#define EXIER_D0IE 0x00800000 /* DMA Channel 0 Interrupt Enable */ +#define EXIER_D1IE 0x00400000 /* DMA Channel 1 Interrupt Enable */ +#define EXIER_D2IE 0x00200000 /* DMA Channel 2 Interrupt Enable */ +#define EXIER_D3IE 0x00100000 /* DMA Channel 3 Interrupt Enable */ +#define EXIER_E0IE 0x00000010 /* External Interrupt 0 Enable */ +#define EXIER_E1IE 0x00000008 /* External Interrupt 1 Enable */ +#define EXIER_E2IE 0x00000004 /* External Interrupt 2 Enable */ +#define EXIER_E3IE 0x00000002 /* External Interrupt 3 Enable */ +#define EXIER_E4IE 0x00000001 /* External Interrupt 4 Enable */ + +#ifdef DCRN_IOCR_BASE +#define DCRN_IOCR (DCRN_IOCR_BASE + 0x0) /* Input/Output Configuration Register */ +#endif +#define IOCR_E0TE 0x80000000 +#define IOCR_E0LP 0x40000000 +#define IOCR_E1TE 0x20000000 +#define IOCR_E1LP 0x10000000 +#define IOCR_E2TE 0x08000000 +#define IOCR_E2LP 0x04000000 +#define IOCR_E3TE 0x02000000 +#define IOCR_E3LP 0x01000000 +#define IOCR_E4TE 0x00800000 +#define IOCR_E4LP 0x00400000 +#define IOCR_EDT 0x00080000 +#define IOCR_SOR 0x00040000 +#define IOCR_EDO 0x00008000 +#define IOCR_2XC 0x00004000 +#define IOCR_ATC 0x00002000 +#define IOCR_SPD 0x00001000 +#define IOCR_BEM 0x00000800 +#define IOCR_PTD 0x00000400 +#define IOCR_ARE 0x00000080 +#define IOCR_DRC 0x00000020 +#define IOCR_RDM(x) (((x) & 0x3) << 3) +#define IOCR_TCS 0x00000004 +#define IOCR_SCS 0x00000002 +#define IOCR_SPC 0x00000001 + +#ifdef DCRN_MAL_BASE +#define DCRN_MALCR (DCRN_MAL_BASE + 0x0) /* MAL Configuration */ +#define DCRN_MALDBR (DCRN_MAL_BASE + 0x3) /* Debug Register */ +#define DCRN_MALESR (DCRN_MAL_BASE + 0x1) /* Error Status */ +#define DCRN_MALIER (DCRN_MAL_BASE + 0x2) /* Interrupt Enable */ +#define DCRN_MALTXCARR (DCRN_MAL_BASE + 0x5) /* TX Channed Active Reset Register */ +#define DCRN_MALTXCASR (DCRN_MAL_BASE + 0x4) /* TX Channel Active Set Register */ +#define DCRN_MALTXDEIR (DCRN_MAL_BASE + 0x7) /* Tx Descriptor Error Interrupt */ +#define DCRN_MALTXEOBISR (DCRN_MAL_BASE + 0x6) /* Tx End of Buffer Interrupt Status */ +#define DCRN_MALRXCARR (DCRN_MAL_BASE + 0x11) /* RX Channed Active Reset Register */ +#define DCRN_MALRXCASR (DCRN_MAL_BASE + 0x10) /* RX Channel Active Set Register */ +#define DCRN_MALRXDEIR (DCRN_MAL_BASE + 0x13) /* Rx Descriptor Error Interrupt */ +#define DCRN_MALRXEOBISR (DCRN_MAL_BASE + 0x12) /* Rx End of Buffer Interrupt Status */ +#define DCRN_MALRXCTP0R (DCRN_MAL_BASE + 0x40) /* Channel Rx 0 Channel Table Pointer */ +#define DCRN_MALTXCTP0R (DCRN_MAL_BASE + 0x20) /* Channel Tx 0 Channel Table Pointer */ +#define DCRN_MALTXCTP1R (DCRN_MAL_BASE + 0x21) /* Channel Tx 1 Channel Table Pointer */ +#define DCRN_MALRCBS0 (DCRN_MAL_BASE + 0x60) /* Channel Rx 0 Channel Buffer Size */ +#endif +/* DCRN_MALCR */ +#define MALCR_MMSR 0x80000000/* MAL Software reset */ +#define MALCR_PLBP_1 0x00400000 /* MAL reqest priority: */ +#define MALCR_PLBP_2 0x00800000 /* lowsest is 00 */ +#define MALCR_PLBP_3 0x00C00000 /* highest */ +#define MALCR_GA 0x00200000 /* Guarded Active Bit */ +#define MALCR_OA 0x00100000 /* Ordered Active Bit */ +#define MALCR_PLBLE 0x00080000 /* PLB Lock Error Bit */ +#define MALCR_PLBLT_1 0x00040000 /* PLB Latency Timer */ +#define MALCR_PLBLT_2 0x00020000 +#define MALCR_PLBLT_3 0x00010000 +#define MALCR_PLBLT_4 0x00008000 +#define MALCR_PLBLT_DEFAULT 0x00078000 /* JSP: Is this a valid default?? */ +#define MALCR_PLBB 0x00004000 /* PLB Burst Deactivation Bit */ +#define MALCR_OPBBL 0x00000080 /* OPB Lock Bit */ +#define MALCR_EOPIE 0x00000004 /* End Of Packet Interrupt Enable */ +#define MALCR_LEA 0x00000002 /* Locked Error Active */ +#define MALCR_MSD 0x00000001 /* MAL Scroll Descriptor Bit */ +/* DCRN_MALESR */ +#define MALESR_EVB 0x80000000 /* Error Valid Bit */ +#define MALESR_CIDRX 0x40000000 /* Channel ID Receive */ +#define MALESR_DE 0x00100000 /* Descriptor Error */ +#define MALESR_OEN 0x00080000 /* OPB Non-Fullword Error */ +#define MALESR_OTE 0x00040000 /* OPB Timeout Error */ +#define MALESR_OSE 0x00020000 /* OPB Slave Error */ +#define MALESR_PEIN 0x00010000 /* PLB Bus Error Indication */ +#define MALESR_DEI 0x00000010 /* Descriptor Error Interrupt */ +#define MALESR_ONEI 0x00000008 /* OPB Non-Fullword Error Interrupt */ +#define MALESR_OTEI 0x00000004 /* OPB Timeout Error Interrupt */ +#define MALESR_OSEI 0x00000002 /* OPB Slace Error Interrupt */ +#define MALESR_PBEI 0x00000001 /* PLB Bus Error Interrupt */ +/* DCRN_MALIER */ +#define MALIER_DE 0x00000010 /* Descriptor Error Interrupt Enable */ +#define MALIER_NE 0x00000008 /* OPB Non-word Transfer Int Enable */ +#define MALIER_TE 0x00000004 /* OPB Time Out Error Interrupt Enable */ +#define MALIER_OPBE 0x00000002 /* OPB Slave Error Interrupt Enable */ +#define MALIER_PLBE 0x00000001 /* PLB Error Interrupt Enable */ +/* DCRN_MALTXEOBISR */ +#define MALOBISR_CH0 0x80000000 /* EOB channel 1 bit */ +#define MALOBISR_CH2 0x40000000 /* EOB channel 2 bit */ + +#ifdef DCRN_OCM0_BASE +#define DCRN_OCMISARC (DCRN_OCM0_BASE + 0x0) /* OCM Instr Side Addr Range Compare */ +#define DCRN_OCMISCR (DCRN_OCM0_BASE + 0x1) /* OCM Instr Side Control */ +#define DCRN_OCMDSARC (DCRN_OCM0_BASE + 0x2) /* OCM Data Side Addr Range Compare */ +#define DCRN_OCMDSCR (DCRN_OCM0_BASE + 0x3) /* OCM Data Side Control */ +#endif + +#ifdef DCRN_PLB0_BASE +#define DCRN_PLB0_BESR (DCRN_PLB0_BASE + 0x0) +#define DCRN_PLB0_BEAR (DCRN_PLB0_BASE + 0x2) +/* doesn't exist on stb03xxx? */ +#define DCRN_PLB0_ACR (DCRN_PLB0_BASE + 0x3) +#endif + +#ifdef DCRN_PLB1_BASE +#define DCRN_PLB1_BESR (DCRN_PLB1_BASE + 0x0) +#define DCRN_PLB1_BEAR (DCRN_PLB1_BASE + 0x1) +/* doesn't exist on stb03xxx? */ +#define DCRN_PLB1_ACR (DCRN_PLB1_BASE + 0x2) +#endif + +#ifdef DCRN_PLLMR_BASE +#define DCRN_PLLMR (DCRN_PLLMR_BASE + 0x0) /* PL1 Mode */ +#endif + +#ifdef DCRN_POB0_BASE +#define DCRN_POB0_BESR0 (DCRN_POB0_BASE + 0x0) +#define DCRN_POB0_BEAR (DCRN_POB0_BASE + 0x2) +#define DCRN_POB0_BESR1 (DCRN_POB0_BASE + 0x4) +#endif + +#ifdef DCRN_SCCR_BASE +#define DCRN_SCCR (DCRN_SCCR_BASE + 0x0) +#endif + +#ifdef DCRN_SDRAM0_BASE +#define DCRN_SDRAM0_CFGADDR (DCRN_SDRAM0_BASE + 0x0) /* Mem Ctrlr Address */ +#define DCRN_SDRAM0_CFGDATA (DCRN_SDRAM0_BASE + 0x1) /* Mem Ctrlr Data */ +#endif + +#ifdef DCRN_UIC0_BASE +#define DCRN_UIC0_SR (DCRN_UIC0_BASE + 0x0) +#define DCRN_UIC0_ER (DCRN_UIC0_BASE + 0x2) +#define DCRN_UIC0_CR (DCRN_UIC0_BASE + 0x3) +#define DCRN_UIC0_PR (DCRN_UIC0_BASE + 0x4) +#define DCRN_UIC0_TR (DCRN_UIC0_BASE + 0x5) +#define DCRN_UIC0_MSR (DCRN_UIC0_BASE + 0x6) +#define DCRN_UIC0_VR (DCRN_UIC0_BASE + 0x7) +#define DCRN_UIC0_VCR (DCRN_UIC0_BASE + 0x8) +#endif + +#ifdef DCRN_UIC1_BASE +#define DCRN_UIC1_SR (DCRN_UIC1_BASE + 0x0) +#define DCRN_UIC1_SRS (DCRN_UIC1_BASE + 0x1) +#define DCRN_UIC1_ER (DCRN_UIC1_BASE + 0x2) +#define DCRN_UIC1_CR (DCRN_UIC1_BASE + 0x3) +#define DCRN_UIC1_PR (DCRN_UIC1_BASE + 0x4) +#define DCRN_UIC1_TR (DCRN_UIC1_BASE + 0x5) +#define DCRN_UIC1_MSR (DCRN_UIC1_BASE + 0x6) +#define DCRN_UIC1_VR (DCRN_UIC1_BASE + 0x7) +#define DCRN_UIC1_VCR (DCRN_UIC1_BASE + 0x8) +#endif + +#ifdef DCRN_SDRAM0_BASE +#define DCRN_SDRAM0_CFGADDR (DCRN_SDRAM0_BASE + 0x0) /* Memory Controller Address */ +#define DCRN_SDRAM0_CFGDATA (DCRN_SDRAM0_BASE + 0x1) /* Memory Controller Data */ +#endif + +#ifdef DCRN_OCM0_BASE +#define DCRN_OCMISARC (DCRN_OCM0_BASE + 0x0) /* OCM Instr Side Addr Range Compare */ +#define DCRN_OCMISCR (DCRN_OCM0_BASE + 0x1) /* OCM Instr Side Control */ +#define DCRN_OCMDSARC (DCRN_OCM0_BASE + 0x2) /* OCM Data Side Addr Range Compare */ +#define DCRN_OCMDSCR (DCRN_OCM0_BASE + 0x3) /* OCM Data Side Control */ +#endif + +#endif /* __ASM_IBM403_H__ */ +#endif /* __KERNEL__ */ diff --git a/include/asm-ppc/ibm4xx.h b/include/asm-ppc/ibm4xx.h new file mode 100644 index 000000000000..587e13328212 --- /dev/null +++ b/include/asm-ppc/ibm4xx.h @@ -0,0 +1,100 @@ +/* + * + * Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu> + * + * Module name: ibm4xx.h + * + * Description: + * A generic include file which pulls in appropriate include files + * for specific board types based on configuration settings. + * + */ + +#ifdef __KERNEL__ +#ifndef __ASM_IBM4XX_H__ +#define __ASM_IBM4XX_H__ + +#include <linux/config.h> + +#ifdef CONFIG_4xx + +#if defined(CONFIG_ASH) +#include <platforms/ash.h> +#endif + +#if defined (CONFIG_CEDER) +#include <platforms/ceder.h> +#endif + +#if defined(CONFIG_CPCI405) +#include <platforms/cpci405.h> +#endif + +#if defined(CONFIG_EP405) +#include <platforms/ep405.h> +#endif + +#if defined(CONFIG_OAK) +#include <platforms/oak.h> +#endif + +#if defined(CONFIG_REDWOOD_4) +#include <platforms/redwood.h> +#endif + +#if defined(CONFIG_REDWOOD_5) +#include <platforms/redwood5.h> +#endif + +#if defined(CONFIG_WALNUT) +#include <platforms/walnut.h> +#endif + +#ifndef PPC4xx_MACHINE_NAME +#define PPC4xx_MACHINE_NAME "Unidentified 4xx class" +#endif + +#ifndef NR_BOARD_IRQS +#define NR_BOARD_IRQS 0 +#endif + +/* IO_BASE is for PCI I/O. + * ISA not supported, just here to resolve copilation. + */ + +#ifndef _IO_BASE +#define _IO_BASE 0xe8000000 /* The PCI address window */ +#define _ISA_MEM_BASE 0 +#define PCI_DRAM_OFFSET 0 +#endif + +/* + * The "residual" board information structure the boot loader passes + * into the kernel. + */ +#ifndef __ASSEMBLY__ +extern unsigned char __res[]; + +/* Device Control Registers */ + +#define stringify(s) tostring(s) +#define tostring(s) #s + +#define mfdcr(rn) mfdcr_or_dflt(rn, 0) + +#define mfdcr_or_dflt(rn,default_rval) \ + ({unsigned int rval; \ + if (rn == 0) \ + rval = default_rval; \ + else \ + asm volatile("mfdcr %0," stringify(rn) : "=r" (rval)); \ + rval;}) + +#define mtdcr(rn, v) \ + {if (rn != 0) \ + asm volatile("mtdcr " stringify(rn) ",%0" : : "r" (v));} + +#endif /* __ASSEMBLY__ */ +#endif /* CONFIG_4xx */ +#endif /* __ASM_IBM4XX_H__ */ +#endif /* __KERNEL__ */ diff --git a/include/asm-ppc/ide.h b/include/asm-ppc/ide.h index 4906bffc816d..6b0daa2d0d99 100644 --- a/include/asm-ppc/ide.h +++ b/include/asm-ppc/ide.h @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.ide.h 1.16 09/28/01 07:54:24 trini + * BK Id: %F% %I% %G% %U% %#% */ /* * linux/include/asm-ppc/ide.h @@ -73,10 +73,29 @@ static __inline__ ide_ioreg_t ide_default_io_base(int index) return 0; } +/* + * This is only used for PC-style IDE controllers (e.g. as on PReP) + * or for PCI IDE devices, not for other types of IDE interface such + * as the pmac IDE interfaces. + */ static __inline__ void ide_init_hwif_ports(hw_regs_t *hw, ide_ioreg_t data_port, ide_ioreg_t ctrl_port, int *irq) { + ide_ioreg_t reg = data_port; + int i; + + for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) + hw->io_ports[i] = reg++; + if (ctrl_port) { + hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port; + } else { + hw->io_ports[IDE_CONTROL_OFFSET] = + hw->io_ports[IDE_DATA_OFFSET] + 0x206; + } + if (irq != NULL) + *irq = 0; + hw->io_ports[IDE_IRQ_OFFSET] = 0; if (ppc_ide_md.ide_init_hwif != NULL) ppc_ide_md.ide_init_hwif(hw, data_port, ctrl_port, irq); } diff --git a/include/asm-ppc/io.h b/include/asm-ppc/io.h index a5cba1f1bb99..5df8a80aa626 100644 --- a/include/asm-ppc/io.h +++ b/include/asm-ppc/io.h @@ -1,12 +1,14 @@ /* - * BK Id: SCCS/s.io.h 1.14 10/16/01 15:58:42 trini + * BK Id: %F% %I% %G% %U% %#% */ + #ifdef __KERNEL__ #ifndef _PPC_IO_H #define _PPC_IO_H #include <linux/config.h> #include <linux/types.h> + #include <asm/page.h> #include <asm/byteorder.h> @@ -25,24 +27,40 @@ #define PREP_PCI_DRAM_OFFSET 0x80000000 #if defined(CONFIG_4xx) -#include <asm/ppc4xx.h> +#include <asm/ibm4xx.h> #elif defined(CONFIG_8xx) #include <asm/mpc8xx.h> #elif defined(CONFIG_8260) #include <asm/mpc8260.h> #elif defined(CONFIG_APUS) -#define _IO_BASE 0 -#define _ISA_MEM_BASE 0 +#define _IO_BASE 0 +#define _ISA_MEM_BASE 0 #define PCI_DRAM_OFFSET 0 #else /* Everyone else */ -extern unsigned long isa_io_base; -extern unsigned long isa_mem_base; -extern unsigned long pci_dram_offset; #define _IO_BASE isa_io_base #define _ISA_MEM_BASE isa_mem_base #define PCI_DRAM_OFFSET pci_dram_offset #endif /* Platform-dependant I/O */ +extern unsigned long isa_io_base; +extern unsigned long isa_mem_base; +extern unsigned long pci_dram_offset; + +#if defined(CONFIG_PPC_ISERIES) +#include <asm/iSeries.h> +#if defined(CONFIG_PCI) + #include <asm/iSeries/iSeries_io.h> + #endif /* defined(CONFIG_PCI) */ +#endif /* CONFIG_PPC_ISERIES */ + +#if defined(CONFIG_PPC_ISERIES) && defined(CONFIG_PCI) +#define readb(addr) iSeries_Readb((u32*)(addr)) +#define readw(addr) iSeries_Readw((u32*)(addr)) +#define readl(addr) iSeries_Readl((u32*)(addr)) +#define writeb(data, addr) iSeries_Writeb(data,(u32*)(addr)) +#define writew(data, addr) iSeries_Writew(data,(u32*)(addr)) +#define writel(data, addr) iSeries_Writel(data,(u32*)(addr)) +#else #define readb(addr) in_8((volatile u8 *)(addr)) #define writeb(b,addr) out_8((volatile u8 *)(addr), (b)) #if defined(CONFIG_APUS) @@ -56,6 +74,7 @@ extern unsigned long pci_dram_offset; #define writew(b,addr) out_le16((volatile u16 *)(addr),(b)) #define writel(b,addr) out_le32((volatile u32 *)(addr),(b)) #endif +#endif /* CONFIG_PPC_ISERIES && defined(CONFIG_PCI) */ #define __raw_readb(addr) (*(volatile unsigned char *)(addr)) @@ -80,9 +99,22 @@ extern unsigned long pci_dram_offset; #ifdef CONFIG_ALL_PPC /* - * We have to handle possible machine checks here on powermacs - * and potentially some CHRPs -- paulus. + * On powermacs, we will get a machine check exception if we + * try to read data from a non-existent I/O port. Because the + * machine check is an asynchronous exception, it isn't + * well-defined which instruction SRR0 will point to when the + * exception occurs. + * With the sequence below (twi; isync; nop), we have found that + * the machine check occurs on one of the three instructions on + * all PPC implementations tested so far. The twi and isync are + * needed on the 601 (in fact twi; sync works too), the isync and + * nop are needed on 604[e|r], and any of twi, sync or isync will + * work on 603[e], 750, 74x0. + * The twi creates an explicit data dependency on the returned + * value which seems to be needed to make the 601 wait for the + * load to finish. */ + #define __do_in_asm(name, op) \ extern __inline__ unsigned int name(unsigned int port) \ { \ @@ -137,6 +169,14 @@ __do_out_asm(outl, "stwbrx") #define inl(port) in_be32((u32 *)((port)+_IO_BASE)) #define outl(val, port) out_be32((u32 *)((port)+_IO_BASE), (val)) +#elif defined(CONFIG_PPC_ISERIES) && defined(CONFIG_PCI) +#define inb(addr) iSeries_Readb((u32*)(addr)) +#define inw(addr) iSeries_Readw((u32*)(addr)) +#define inl(addr) iSeries_Readl((u32*)(addr)) +#define outb(data,addr) iSeries_Writeb(data,(u32*)(addr)) +#define outw(data,addr) iSeries_Writew(data,(u32*)(addr)) +#define outl(data,addr) iSeries_Writel(data,(u32*)(addr)) + #else /* not APUS or ALL_PPC */ #define inb(port) in_8((u8 *)((port)+_IO_BASE)) #define outb(val, port) out_8((u8 *)((port)+_IO_BASE), (val)) @@ -178,8 +218,13 @@ extern void _outsl_ns(volatile u32 *port, const void *buf, int nl); #define IO_SPACE_LIMIT ~0 #define memset_io(a,b,c) memset((void *)(a),(b),(c)) +#ifdef CONFIG_PPC_ISERIES +#define memcpy_fromio(a,b,c) iSeries_memcpy_fromio((void *)(a), (void *)(b), (c)) +#define memcpy_toio(a,b,c) iSeries_memcpy_toio((void *)(a), (void *)(b), (c)) +#else #define memcpy_fromio(a,b,c) memcpy((a),(void *)(b),(c)) #define memcpy_toio(a,b,c) memcpy((void *)(a),(b),(c)) +#endif #ifdef __KERNEL__ /* @@ -265,7 +310,7 @@ extern inline void eieio(void) __asm__ __volatile__ ("eieio" : : : "memory"); } -/* Enforce in-order execution of data I/O. +/* Enforce in-order execution of data I/O. * No distinction between read/write on PPC; use eieio for all three. */ #define iobarrier_rw() eieio() diff --git a/include/asm-ppc/irq.h b/include/asm-ppc/irq.h index fdfc96e8aa0d..bfff1e29f847 100644 --- a/include/asm-ppc/irq.h +++ b/include/asm-ppc/irq.h @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.irq.h 1.9 05/17/01 18:14:24 cort + * BK Id: %F% %I% %G% %U% %#% */ #ifdef __KERNEL__ #ifndef _ASM_IRQ_H @@ -14,7 +14,7 @@ extern void disable_irq_nosync(unsigned int); extern void enable_irq(unsigned int); #if defined(CONFIG_4xx) - +#include <asm/ibm4xx.h> /* * The PowerPC 403 cores' Asynchronous Interrupt Controller (AIC) has * 32 possible interrupts, a majority of which are not implemented on @@ -29,23 +29,19 @@ extern void enable_irq(unsigned int); * */ -#define NR_IRQS 32 +#define NR_AIC_IRQS 32 +#define NR_IRQS (NR_AIC_IRQS + NR_BOARD_IRQS) -#define AIC_INT0 (0) -#define AIC_INT4 (4) -#define AIC_INT5 (5) -#define AIC_INT6 (6) -#define AIC_INT7 (7) -#define AIC_INT8 (8) -#define AIC_INT9 (9) -#define AIC_INT10 (10) -#define AIC_INT11 (11) -#define AIC_INT27 (27) -#define AIC_INT28 (28) -#define AIC_INT29 (29) -#define AIC_INT30 (30) -#define AIC_INT31 (31) +static __inline__ int +irq_cannonicalize(int irq) +{ + return (irq); +} +#elif defined (CONFIG_NP405) + +#define NR_AIC_IRQS 32 +#define NR_IRQS (NR_AIC_IRQS + NR_BOARD_IRQS) static __inline__ int irq_cannonicalize(int irq) @@ -124,48 +120,6 @@ static __inline__ int irq_cannonicalize(int irq) } #else /* CONFIG_4xx + CONFIG_8xx */ - -#if defined(CONFIG_APUS) -/* - * This structure is used to chain together the ISRs for a particular - * interrupt source (if it supports chaining). - */ -typedef struct irq_node { - void (*handler)(int, void *, struct pt_regs *); - unsigned long flags; - void *dev_id; - const char *devname; - struct irq_node *next; -} irq_node_t; - -/* - * This structure has only 4 elements for speed reasons - */ -typedef struct irq_handler { - void (*handler)(int, void *, struct pt_regs *); - unsigned long flags; - void *dev_id; - const char *devname; -} irq_handler_t; - -/* count of spurious interrupts */ -extern volatile unsigned int num_spurious; - -extern int sys_request_irq(unsigned int, - void (*)(int, void *, struct pt_regs *), - unsigned long, const char *, void *); -extern void sys_free_irq(unsigned int, void *); - -/* - * This function returns a new irq_node_t - */ -extern irq_node_t *new_irq_node(void); - -/* Number of m68k interrupts */ -#define SYS_IRQS 8 - -#endif /* CONFIG_APUS */ - /* * this is the # irq's for all ppc arch's (pmac/chrp/prep) * so it is the max of them all @@ -211,19 +165,14 @@ extern irq_node_t *new_irq_node(void); static __inline__ int irq_cannonicalize(int irq) { if (ppc_md.irq_cannonicalize) - { return ppc_md.irq_cannonicalize(irq); - } - else - { - return irq; - } + return irq; } #endif #define NR_MASK_WORDS ((NR_IRQS + 31) / 32) -/* pendatic: these are long because they are used with set_bit --RR */ +/* pedantic: these are long because they are used with set_bit --RR */ extern unsigned long ppc_cached_irq_mask[NR_MASK_WORDS]; extern unsigned long ppc_lost_interrupts[NR_MASK_WORDS]; extern atomic_t ppc_n_lost_interrupts; diff --git a/include/asm-ppc/keyboard.h b/include/asm-ppc/keyboard.h index d8e414c84cb3..4d6b0aab4ddb 100644 --- a/include/asm-ppc/keyboard.h +++ b/include/asm-ppc/keyboard.h @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.keyboard.h 1.11 08/29/01 10:07:29 paulus + * BK Id: %F% %I% %G% %U% %#% */ /* * linux/include/asm-ppc/keyboard.h @@ -13,8 +13,8 @@ * like the intel pc for prep systems, different for power macs. */ -#ifndef __ASMPPC_KEYBOARD_H -#define __ASMPPC_KEYBOARD_H +#ifndef __ASM_KEYBOARD_H__ +#define __ASM_KEYBOARD_H__ #ifdef __KERNEL__ @@ -25,8 +25,14 @@ #include <linux/ioport.h> #include <linux/kd.h> #include <asm/io.h> +/* IBM Spruce platform is different. */ +#ifdef CONFIG_SPRUCE +#include <platforms/spruce.h> +#endif +#ifndef KEYBOARD_IRQ #define KEYBOARD_IRQ 1 +#endif #define DISABLE_KBD_DURING_INTERRUPTS 0 #define INIT_KBD @@ -85,10 +91,12 @@ extern unsigned long SYSRQ_KEY; "keyboard", NULL) /* How to access the keyboard macros on this platform. */ +#ifndef kbd_read_input #define kbd_read_input() inb(KBD_DATA_REG) #define kbd_read_status() inb(KBD_STATUS_REG) #define kbd_write_output(val) outb(val, KBD_DATA_REG) #define kbd_write_command(val) outb(val, KBD_CNTL_REG) +#endif /* Some stoneage hardware needs delays after some operations. */ #define kbd_pause() do { } while(0) @@ -97,7 +105,9 @@ extern unsigned long SYSRQ_KEY; * Machine specific bits for the PS/2 driver */ +#ifndef AUX_IRQ #define AUX_IRQ 12 +#endif #define aux_request_irq(hand, dev_id) \ request_irq(AUX_IRQ, hand, SA_SHIRQ, "PS/2 Mouse", dev_id) @@ -105,5 +115,4 @@ extern unsigned long SYSRQ_KEY; #define aux_free_irq(dev_id) free_irq(AUX_IRQ, dev_id) #endif /* __KERNEL__ */ - -#endif /* __ASMPPC_KEYBOARD_H */ +#endif /* __ASM_KEYBOARD_H__ */ diff --git a/include/asm-ppc/keylargo.h b/include/asm-ppc/keylargo.h index c07b525f5a98..a0bd3eb6fcbe 100644 --- a/include/asm-ppc/keylargo.h +++ b/include/asm-ppc/keylargo.h @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.keylargo.h 1.13 08/19/01 22:23:04 paulus + * BK Id: %F% %I% %G% %U% %#% */ /* * keylargo.h: definitions for using the "KeyLargo" I/O controller chip. @@ -27,14 +27,18 @@ #define KEYLARGO_GPIO_EXTINT_CNT 18 #define KEYLARGO_GPIO_0 0x6A #define KEYLARGO_GPIO_CNT 17 +#define KEYLARGO_GPIO_EXTINT_DUAL_EDGE 0x80 #define KEYLARGO_GPIO_OUTPUT_ENABLE 0x04 #define KEYLARGO_GPIO_OUTOUT_DATA 0x01 +#define KEYLARGO_GPIO_INPUT_DATA 0x02 /* Specific GPIO regs */ -#define KL_GPIO_MODEM_RESET (KEYLARGO_GPIO_0+0x03) /* Pangea */ +#define KL_GPIO_MODEM_RESET (KEYLARGO_GPIO_0+0x03) #define KL_GPIO_MODEM_POWER (KEYLARGO_GPIO_0+0x02) /* Pangea */ +#define KL_GPIO_SOUND_POWER (KEYLARGO_GPIO_0+0x05) + /* Hrm... this one is only to be used on Pismo. It seeem to also * control the timebase enable on other machines. Still to be * experimented... --BenH. @@ -54,7 +58,9 @@ #define KL_GPIO_RESET_CPU3 (KEYLARGO_GPIO_EXTINT_0+0x10) #define KL_GPIO_PMU_MESSAGE_IRQ (KEYLARGO_GPIO_EXTINT_0+0x09) -#define KL_GPIO_PMU_MESSAGE_BIT 0x02 +#define KL_GPIO_PMU_MESSAGE_BIT KEYLARGO_GPIO_INPUT_DATA + +#define KL_GPIO_MEDIABAY_IRQ (KEYLARGO_GPIO_EXTINT_0+0x0e) #define KL_GPIO_AIRPORT_0 (KEYLARGO_GPIO_EXTINT_0+0x0a) #define KL_GPIO_AIRPORT_1 (KEYLARGO_GPIO_EXTINT_0+0x0d) @@ -65,43 +71,47 @@ /* * Bits in feature control register */ -#define KL_MBCR_MB0_DEV_ENABLE 0x00001000 +#define KL_MBCR_MB0_PCI_ENABLE 0x00000800 /* exist ? */ +#define KL_MBCR_MB0_IDE_ENABLE 0x00001000 +#define KL_MBCR_MB0_FLOPPY_ENABLE 0x00002000 /* exist ? */ +#define KL_MBCR_MB0_SOUND_ENABLE 0x00004000 /* hrm... */ +#define KL_MBCR_MB0_DEV_MASK 0x00007800 #define KL_MBCR_MB0_DEV_POWER 0x00000400 #define KL_MBCR_MB0_DEV_RESET 0x00000200 #define KL_MBCR_MB0_ENABLE 0x00000100 -#define KL_MBCR_MB1_DEV_ENABLE 0x10000000 +#define KL_MBCR_MB1_PCI_ENABLE 0x08000000 /* exist ? */ +#define KL_MBCR_MB1_IDE_ENABLE 0x10000000 +#define KL_MBCR_MB1_FLOPPY_ENABLE 0x20000000 /* exist ? */ +#define KL_MBCR_MB1_SOUND_ENABLE 0x40000000 /* hrm... */ +#define KL_MBCR_MB1_DEV_MASK 0x78000000 #define KL_MBCR_MB1_DEV_POWER 0x04000000 #define KL_MBCR_MB1_DEV_RESET 0x02000000 #define KL_MBCR_MB1_ENABLE 0x01000000 -#define KL0_SCC_B_INTF_ENABLE 0x00000001 /* ??? */ -#define KL0_SCC_A_INTF_ENABLE 0x00000002 /* ??? */ +#define KL0_SCC_B_INTF_ENABLE 0x00000001 +#define KL0_SCC_A_INTF_ENABLE 0x00000002 #define KL0_SCC_SLOWPCLK 0x00000004 #define KL0_SCC_RESET 0x00000008 #define KL0_SCCA_ENABLE 0x00000010 #define KL0_SCCB_ENABLE 0x00000020 #define KL0_SCC_CELL_ENABLE 0x00000040 +#define KL0_IRDA_HIGH_BAND 0x00000100 +#define KL0_IRDA_SOURCE2_SEL 0x00000200 +#define KL0_IRDA_SOURCE1_SEL 0x00000400 +#define KL0_IRDA_RESET 0x00000800 +#define KL0_IRDA_DEFAULT1 0x00001000 +#define KL0_IRDA_DEFAULT0 0x00002000 +#define KL0_IRDA_FAST_CONNECT 0x00004000 +#define KL0_IRDA_ENABLE 0x00008000 +#define KL0_IRDA_CLK32_ENABLE 0x00010000 +#define KL0_IRDA_CLK19_ENABLE 0x00020000 #define KL0_USB0_PAD_SUSPEND0 0x00040000 #define KL0_USB0_PAD_SUSPEND1 0x00080000 #define KL0_USB0_CELL_ENABLE 0x00100000 #define KL0_USB1_PAD_SUSPEND0 0x00400000 #define KL0_USB1_PAD_SUSPEND1 0x00800000 #define KL0_USB1_CELL_ENABLE 0x01000000 -/* KL id 0x22 only */ #define KL0_USB_REF_SUSPEND 0x10000000 -#define KL0_IRDA_ENABLE 0x00008000 -#define KL0_IRDA_CLK32_ENABLE 0x00010000 -#define KL0_IRDA_CLK19_ENABLE 0x00020000 -/* KL id 0x25 (pangea) only */ -#define KL0_USB1_PAD_SUSPEND_SEL 0x00020000 -#define KL0_USB1_REF_SUSPEND 0x00010000 -#define KL0_USB1_REF_SUSPEND_SEL 0x00008000 -#define KL0_USB1_PMI 0x00004000 -#define KL0_USB0_PAD_SUSPEND_SEL 0x00002000 -#define KL0_USB0_REF_SUSPEND 0x00001000 -#define KL0_USB0_REF_SUSPEND_SEL 0x00000800 -#define KL0_USB0_PMI 0x00000400 - #define KL0_SERIAL_ENABLE (KL0_SCC_B_INTF_ENABLE | \ KL0_SCC_SLOWPCLK | \ @@ -128,8 +138,9 @@ #define KL2_IOBUS_ENABLE 0x00000002 #define KL2_SLEEP_STATE_BIT 0x00000100 #define KL2_MPIC_ENABLE 0x00020000 -#define KL2_MODEM_POWER_N 0x02000000 -#define KL2_AIRPORT_RESET_N 0x08000000 /* Or power ? */ +#define KL2_ALT_DATA_OUT 0x02000000 +#define KL2_MEM_IS_BIG 0x04000000 +#define KL2_CARDSEL_16 0x08000000 #define KL3_SHUTDOWN_PLL_TOTAL 0x00000001 #define KL3_SHUTDOWN_PLLKW6 0x00000002 @@ -149,11 +160,11 @@ #define KL3_STOPPING33_ENABLED 0x00080000 /* Port 0,1 : bus 0, port 2,3 : bus 1 */ -#define KL4_SET_PORT_ENABLE(p) (0x00000008 << ((p)<<3)) -#define KL4_SET_PORT_RESUME(p) (0x00000004 << ((p)<<3)) -#define KL4_SET_PORT_CONNECT(p) (0x00000002 << ((p)<<3)) -#define KL4_SET_PORT_DISCONNECT(p) (0x00000001 << ((p)<<3)) -#define KL4_GET_PORT_RESUME(p) (0x00000040 << ((p)<<3)) -#define KL4_GET_PORT_CONNECT(p) (0x00000020 << ((p)<<3)) -#define KL4_GET_PORT_DISCONNECT(p) (0x00000010 << ((p)<<3)) +#define KL4_PORT_WAKEUP_ENABLE(p) (0x00000008 << ((p)<<3)) +#define KL4_PORT_RESUME_WAKE_EN(p) (0x00000004 << ((p)<<3)) +#define KL4_PORT_CONNECT_WAKE_EN(p) (0x00000002 << ((p)<<3)) +#define KL4_PORT_DISCONNECT_WAKE_EN(p) (0x00000001 << ((p)<<3)) +#define KL4_PORT_RESUME_STAT(p) (0x00000040 << ((p)<<3)) +#define KL4_PORT_CONNECT_STAT(p) (0x00000020 << ((p)<<3)) +#define KL4_PORT_DISCONNECT_STAT(p) (0x00000010 << ((p)<<3)) diff --git a/include/asm-ppc/kgdb.h b/include/asm-ppc/kgdb.h index 04bb95b621dc..9ac89318acca 100644 --- a/include/asm-ppc/kgdb.h +++ b/include/asm-ppc/kgdb.h @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.kgdb.h 1.5 05/17/01 18:14:24 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * kgdb.h: Defines and declarations for serial line source level @@ -38,8 +38,6 @@ int kgdb_sstep(struct pt_regs *regs); void kgdb(struct pt_regs *regs); int kgdb_iabr_match(struct pt_regs *regs); int kgdb_dabr_match(struct pt_regs *regs); -static void kgdb_fault_handler(struct pt_regs *regs); -static void handle_exception (struct pt_regs *regs); /* * external low-level support routines (ie macserial.c) diff --git a/include/asm-ppc/machdep.h b/include/asm-ppc/machdep.h index 184e7cc8d1af..6dd6a1ee526f 100644 --- a/include/asm-ppc/machdep.h +++ b/include/asm-ppc/machdep.h @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.machdep.h 1.25 11/13/01 21:26:07 paulus + * BK Id: %F% %I% %G% %U% %#% */ #ifdef __KERNEL__ #ifndef _PPC_MACHDEP_H @@ -16,6 +16,11 @@ struct pci_bus; struct pci_dev; struct seq_file; +/* We export this macro for external modules like Alsa to know if + * ppc_md.feature_call is implemented or not + */ +#define CONFIG_PPC_HAS_FEATURE_CALLS + struct machdep_calls { void (*setup_arch)(void); /* Optional, may be NULL. */ @@ -95,6 +100,12 @@ struct machdep_calls { /* this is for modules, since _machine can be a define -- Cort */ int ppc_machine; + /* Motherboard/chipset features. This is a kind of general purpose + * hook used to control some machine specific features (like reset + * lines, chip power control, etc...). + */ + int (*feature_call)(unsigned int feature, ...); + #ifdef CONFIG_SMP /* functions for dealing with other cpus */ struct smp_ops_t *smp_ops; diff --git a/include/asm-ppc/mediabay.h b/include/asm-ppc/mediabay.h index 26e9bd5663be..ee700af0ede3 100644 --- a/include/asm-ppc/mediabay.h +++ b/include/asm-ppc/mediabay.h @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.mediabay.h 1.5 05/17/01 18:14:25 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * mediabay.h: definitions for using the media bay @@ -12,10 +12,13 @@ #ifdef __KERNEL__ -#define MB_FD 0 /* media bay contains floppy drive */ -#define MB_FD1 1 /* media bay contains floppy drive */ -#define MB_CD 3 /* media bay contains ATA drive such as CD */ -#define MB_NO 7 /* media bay contains nothing */ +#define MB_FD 0 /* media bay contains floppy drive (automatic eject ?) */ +#define MB_FD1 1 /* media bay contains floppy drive (manual eject ?) */ +#define MB_SOUND 2 /* sound device ? */ +#define MB_CD 3 /* media bay contains ATA drive such as CD or ZIP */ +#define MB_PCI 5 /* media bay contains a PCI device */ +#define MB_POWER 6 /* media bay contains a Power device (???) */ +#define MB_NO 7 /* media bay contains nothing */ void media_bay_init(void); int check_media_bay(struct device_node *which_bay, int what); diff --git a/include/asm-ppc/mmu.h b/include/asm-ppc/mmu.h index d89f9d16c96c..16d5497aa597 100644 --- a/include/asm-ppc/mmu.h +++ b/include/asm-ppc/mmu.h @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.mmu.h 1.10 06/28/01 15:50:17 paulus + * BK Id: %F% %I% %G% %U% %#% */ /* * PowerPC memory management structures @@ -115,9 +115,6 @@ typedef struct _P601_BAT { P601_BATL batl; /* Lower register */ } P601_BAT; -extern void _tlbie(unsigned long va); /* invalidate a TLB entry */ -extern void _tlbia(void); /* invalidate all TLB entries */ - #endif /* __ASSEMBLY__ */ /* Block size masks */ diff --git a/include/asm-ppc/mmu_context.h b/include/asm-ppc/mmu_context.h index 58b4d6179855..f6628d78af92 100644 --- a/include/asm-ppc/mmu_context.h +++ b/include/asm-ppc/mmu_context.h @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.mmu_context.h 1.18 09/26/01 16:02:49 paulus + * BK Id: %F% %I% %G% %U% %#% */ #ifdef __KERNEL__ #ifndef __PPC_MMU_CONTEXT_H @@ -10,6 +10,25 @@ #include <asm/bitops.h> #include <asm/mmu.h> +#if MAX_RT_PRIO != 128 || MAX_PRIO != 168 +# error update this function. +#endif + +static inline int sched_find_first_bit(unsigned long *b) +{ + if (unlikely(b[0])) + return __ffs(b[0]); + if (unlikely(b[1])) + return __ffs(b[1]) + 32; + if (unlikely(b[2])) + return __ffs(b[2]) + 64; + if (unlikely(b[3])) + return __ffs(b[3]) + 96; + if (b[4]) + return __ffs(b[4]) + 128; + return __ffs(b[5]) + 32 + 128; +} + /* * On 32-bit PowerPC 6xx/7xx/7xxx CPUs, we use a set of 16 VSIDs * (virtual segment identifiers) for each context. Although the diff --git a/include/asm-ppc/mpc10x.h b/include/asm-ppc/mpc10x.h new file mode 100644 index 000000000000..d04367d673a3 --- /dev/null +++ b/include/asm-ppc/mpc10x.h @@ -0,0 +1,166 @@ +/* + * arch/ppc/kernel/mpc10x.h + * + * Common routines for the Motorola SPS MPC106/8240/107 Host bridge/Mem + * ctlr/EPIC/etc. + * + * Author: Mark A. Greer + * mgreer@mvista.com + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#ifndef __PPC_KERNEL_MPC10X_H +#define __PPC_KERNEL_MPC10X_H + +#include <linux/pci_ids.h> +#include <asm/pci-bridge.h> + +/* + * The values here don't completely map everything but should work in most + * cases. + * + * MAP A (PReP Map) + * Processor: 0x80000000 - 0x807fffff -> PCI I/O: 0x00000000 - 0x007fffff + * Processor: 0xc0000000 - 0xdfffffff -> PCI MEM: 0x00000000 - 0x1fffffff + * PCI MEM: 0x80000000 -> Processor System Memory: 0x00000000 + * EUMB mapped to: ioremap_base - 0x00100000 (ioremap_base - 1 MB) + * + * MAP B (CHRP Map) + * Processor: 0xfe000000 - 0xfebfffff -> PCI I/O: 0x00000000 - 0x00bfffff + * Processor: 0x80000000 - 0xbfffffff -> PCI MEM: 0x80000000 - 0xbfffffff + * PCI MEM: 0x00000000 -> Processor System Memory: 0x00000000 + * EUMB mapped to: ioremap_base - 0x00100000 (ioremap_base - 1 MB) + */ + +/* + * Define the vendor/device IDs for the various bridges--should be added to + * <linux/pci_ids.h> + */ +#define MPC10X_BRIDGE_106 ((PCI_DEVICE_ID_MOTOROLA_MPC106 << 16) | \ + PCI_VENDOR_ID_MOTOROLA) +#define MPC10X_BRIDGE_8240 ((0x0003 << 16) | PCI_VENDOR_ID_MOTOROLA) +#define MPC10X_BRIDGE_107 ((0x0004 << 16) | PCI_VENDOR_ID_MOTOROLA) +#define MPC10X_BRIDGE_8245 ((0x0006 << 16) | PCI_VENDOR_ID_MOTOROLA) + +/* Define the type of map to use */ +#define MPC10X_MEM_MAP_A 1 +#define MPC10X_MEM_MAP_B 2 + +/* Map A (PReP Map) Defines */ +#define MPC10X_MAPA_CNFG_ADDR 0x80000cf8 +#define MPC10X_MAPA_CNFG_DATA 0x80000cfc + +#define MPC10X_MAPA_ISA_IO_BASE 0x80000000 +#define MPC10X_MAPA_ISA_MEM_BASE 0xc0000000 +#define MPC10X_MAPA_DRAM_OFFSET 0x80000000 + +#define MPC10X_MAPA_PCI_IO_START 0x00000000 +#define MPC10X_MAPA_PCI_IO_END (0x00800000 - 1) +#define MPC10X_MAPA_PCI_MEM_START 0x00000000 +#define MPC10X_MAPA_PCI_MEM_END (0x20000000 - 1) + +#define MPC10X_MAPA_PCI_MEM_OFFSET (MPC10X_MAPA_ISA_MEM_BASE - \ + MPC10X_MAPA_PCI_MEM_START) + +/* Map B (CHRP Map) Defines */ +#define MPC10X_MAPB_CNFG_ADDR 0xfec00000 +#define MPC10X_MAPB_CNFG_DATA 0xfee00000 + +#define MPC10X_MAPB_ISA_IO_BASE 0xfe000000 +#define MPC10X_MAPB_ISA_MEM_BASE 0x80000000 +#define MPC10X_MAPB_DRAM_OFFSET 0x00000000 + +#define MPC10X_MAPB_PCI_IO_START 0x00000000 +#define MPC10X_MAPB_PCI_IO_END (0x00c00000 - 1) +#define MPC10X_MAPB_PCI_MEM_START 0x80000000 +#define MPC10X_MAPB_PCI_MEM_END (0xc0000000 - 1) + +#define MPC10X_MAPB_PCI_MEM_OFFSET (MPC10X_MAPB_ISA_MEM_BASE - \ + MPC10X_MAPB_PCI_MEM_START) + +/* Set hose members to values appropriate for the mem map used */ +#define MPC10X_SETUP_HOSE(hose, map) { \ + (hose)->pci_mem_offset = MPC10X_MAP##map##_PCI_MEM_OFFSET; \ + (hose)->io_space.start = MPC10X_MAP##map##_PCI_IO_START; \ + (hose)->io_space.end = MPC10X_MAP##map##_PCI_IO_END; \ + (hose)->mem_space.start = MPC10X_MAP##map##_PCI_MEM_START; \ + (hose)->mem_space.end = MPC10X_MAP##map##_PCI_MEM_END; \ + (hose)->io_base_virt = (void *)MPC10X_MAP##map##_ISA_IO_BASE; \ +} + + +/* Miscellaneous Configuration register offsets */ +#define MPC10X_CFG_PIR_REG 0x09 +#define MPC10X_CFG_PIR_HOST_BRIDGE 0x00 +#define MPC10X_CFG_PIR_AGENT 0x01 + +#define MPC10X_CFG_EUMBBAR 0x78 + +#define MPC10X_CFG_PICR1_REG 0xa8 +#define MPC10X_CFG_PICR1_ADDR_MAP_MASK 0x00010000 +#define MPC10X_CFG_PICR1_ADDR_MAP_A 0x00010000 +#define MPC10X_CFG_PICR1_ADDR_MAP_B 0x00000000 +#define MPC10X_CFG_PICR1_ST_GATH_EN 0x00000040 + +#define MPC10X_CFG_MAPB_OPTIONS_REG 0xe0 +#define MPC10X_CFG_MAPB_OPTIONS_CFAE 0x80 /* CPU_FD_ALIAS_EN */ +#define MPC10X_CFG_MAPB_OPTIONS_PFAE 0x40 /* PCI_FD_ALIAS_EN */ +#define MPC10X_CFG_MAPB_OPTIONS_DR 0x20 /* DLL_RESET */ +#define MPC10X_CFG_MAPB_OPTIONS_PCICH 0x80 /* PCI_COMPATIBILITY_HOLE */ +#define MPC10X_CFG_MAPB_OPTIONS_PROCCH 0x40 /* PROC_COMPATIBILITY_HOLE */ + +/* Define offsets for the memory controller registers in the config space */ +#define MPC10X_MCTLR_MEM_START_1 0x80 /* Banks 0-3 */ +#define MPC10X_MCTLR_MEM_START_2 0x84 /* Banks 4-7 */ +#define MPC10X_MCTLR_EXT_MEM_START_1 0x88 /* Banks 0-3 */ +#define MPC10X_MCTLR_EXT_MEM_START_2 0x8c /* Banks 4-7 */ + +#define MPC10X_MCTLR_MEM_END_1 0x90 /* Banks 0-3 */ +#define MPC10X_MCTLR_MEM_END_2i 0x94 /* Banks 4-7 */ +#define MPC10X_MCTLR_EXT_MEM_END_1 0x98 /* Banks 0-3 */ +#define MPC10X_MCTLR_EXT_MEM_END_2 0x9c /* Banks 4-7 */ + +#define MPC10X_MCTLR_MEM_BANK_ENABLES 0xa0 + +/* Define some offset in the EUMB */ +#define MPC10X_EUMB_SIZE 0x00100000 /* Total EUMB size (1MB) */ + +#define MPC10X_EUMB_MU_OFFSET 0x00000000 /* Msg Unit reg offset */ +#define MPC10X_EUMB_MU_SIZE 0x00001000 /* Msg Unit reg size */ +#define MPC10X_EUMB_DMA_OFFSET 0x00001000 /* DMA Unit reg offset */ +#define MPC10X_EUMB_DMA_SIZE 0x00001000 /* DMA Unit reg size */ +#define MPC10X_EUMB_ATU_OFFSET 0x00002000 /* Addr xlate reg offset */ +#define MPC10X_EUMB_ATU_SIZE 0x00001000 /* Addr xlate reg size */ +#define MPC10X_EUMB_I2C_OFFSET 0x00003000 /* I2C Unit reg offset */ +#define MPC10X_EUMB_I2C_SIZE 0x00001000 /* I2C Unit reg size */ +#define MPC10X_EUMB_DUART_OFFSET 0x00004000 /* DUART Unit reg offset (8245) */ +#define MPC10X_EUMB_DUART_SIZE 0x00001000 /* DUART Unit reg size (8245) */ +#define MPC10X_EUMB_EPIC_OFFSET 0x00040000 /* EPIC offset in EUMB */ +#define MPC10X_EUMB_EPIC_SIZE 0x00030000 /* EPIC size */ +#define MPC10X_EUMB_PM_OFFSET 0x000fe000 /* Performance Monitor reg offset (8245) */ +#define MPC10X_EUMB_PM_SIZE 0x00001000 /* Performance Monitor reg size (8245) */ +#define MPC10X_EUMB_WP_OFFSET 0x000ff000 /* Data path diagnostic, watchpoint reg offset */ +#define MPC10X_EUMB_WP_SIZE 0x00001000 /* Data path diagnostic, watchpoint reg size */ + +/* + * Define some recommended places to put the EUMB regs. + * For both maps, recommend putting the EUMB from 0xeff00000 to 0xefffffff. + */ +extern unsigned long ioremap_base; +#define MPC10X_MAPA_EUMB_BASE (ioremap_base - MPC10X_EUMB_SIZE) +#define MPC10X_MAPB_EUMB_BASE MPC10X_MAPA_EUMB_BASE + + +int mpc10x_bridge_init(struct pci_controller *hose, + uint current_map, + uint new_map, + uint phys_eumb_base); +unsigned long mpc10x_get_mem_size(uint mem_map); +int mpc10x_enable_store_gathering(struct pci_controller *hose); + +#endif /* __PPC_KERNEL_MPC10X_H */ diff --git a/include/asm-ppc/mpc8260.h b/include/asm-ppc/mpc8260.h index 17bd1350611a..46e37c8c1cec 100644 --- a/include/asm-ppc/mpc8260.h +++ b/include/asm-ppc/mpc8260.h @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.mpc8260.h 1.5 05/17/01 18:14:25 cort + * BK Id: %F% %I% %G% %U% %#% */ /* This is the single file included by all MPC8260 build options. @@ -17,7 +17,23 @@ #ifdef CONFIG_8260 #ifdef CONFIG_EST8260 -#include <asm/est8260.h> +#include <platforms/est8260.h> +#endif + +#ifdef CONFIG_SBS8260 +#include <platforms/sbs8260.h> +#endif + +#ifdef CONFIG_RPX6 +#include <platforms/rpxsuper.h> +#endif + +#ifdef CONFIG_WILLOW +#include <platforms/willow.h> +#endif + +#ifdef CONFIG_TQM8260 +#include <platforms/tqm8260.h> #endif /* I don't yet have the ISA or PCI stuff done....no 8260 with @@ -43,5 +59,5 @@ extern int request_8xxirq(unsigned int irq, void *dev_id); #endif /* CONFIG_8260 */ -#endif +#endif /* !__CONFIG_8260_DEFS */ #endif /* __KERNEL__ */ diff --git a/include/asm-ppc/mpc8xx.h b/include/asm-ppc/mpc8xx.h index 4006d56fb3a0..c0022d65fd10 100644 --- a/include/asm-ppc/mpc8xx.h +++ b/include/asm-ppc/mpc8xx.h @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.mpc8xx.h 1.15 11/01/01 12:48:53 trini + * BK Id: %F% %I% %G% %U% %#% */ /* This is the single file included by all MPC8xx build options. @@ -17,40 +17,60 @@ #ifdef CONFIG_8xx #ifdef CONFIG_MBX -#include <asm/mbx.h> +#include <platforms/mbx.h> #endif #ifdef CONFIG_FADS -#include <asm/fads.h> +#include <platforms/fads.h> #endif #ifdef CONFIG_RPXLITE -#include <asm/rpxlite.h> +#include <platforms/rpxlite.h> #endif #ifdef CONFIG_BSEIP -#include <asm/bseip.h> +#include <platforms/bseip.h> #endif #ifdef CONFIG_RPXCLASSIC -#include <asm/rpxclassic.h> +#include <platforms/rpxclassic.h> #endif #if defined(CONFIG_TQM8xxL) -#include <asm/tqm8xx.h> +#include <platforms/tqm8xx.h> #endif #if defined(CONFIG_SPD823TS) -#include <asm/spd8xx.h> +#include <platforms/spd8xx.h> #endif #if defined(CONFIG_IVMS8) || defined(CONFIG_IVML24) -#include <asm/ivms8.h> +#include <platforms/ivms8.h> #endif -/* I need this to get pt_regs....... -*/ -#include <asm/ptrace.h> +#if defined(CONFIG_HERMES_PRO) +#include <platforms/hermes.h> +#endif + +#if defined(CONFIG_IP860) +#include <platforms/ip860.h> +#endif + +#if defined(CONFIG_LWMON) +#include <platforms/lwmon.h> +#endif + +#if defined(CONFIG_PCU_E) +#include <platforms/pcu_e.h> +#endif + +#if defined(CONFIG_CCM) +#include <platforms/ccm.h> +#endif + +#if defined(CONFIG_LANTEC) +#include <platforms/lantec.h> +#endif /* Currently, all 8xx boards that support a processor to PCI/ISA bridge * use the same memory map. @@ -74,15 +94,12 @@ #endif #ifndef __ASSEMBLY__ -extern unsigned long isa_io_base; -extern unsigned long isa_mem_base; -extern unsigned long pci_dram_offset; - /* The "residual" data board information structure the boot loader * hands to us. */ extern unsigned char __res[]; +struct pt_regs; extern int request_8xxirq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *), unsigned long flags, @@ -90,5 +107,5 @@ extern int request_8xxirq(unsigned int irq, void *dev_id); #endif /* !__ASSEMBLY__ */ #endif /* CONFIG_8xx */ -#endif +#endif /* __CONFIG_8xx_DEFS */ #endif /* __KERNEL__ */ diff --git a/include/asm-ppc/ohare.h b/include/asm-ppc/ohare.h index 0f3b01ae1163..daf5789c7323 100644 --- a/include/asm-ppc/ohare.h +++ b/include/asm-ppc/ohare.h @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.ohare.h 1.5 05/17/01 18:14:25 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * ohare.h: definitions for using the "O'Hare" I/O controller chip. @@ -11,7 +11,8 @@ */ /* offset from ohare base for feature control register */ -#define OHARE_FEATURE_REG 0x38 +#define OHARE_MBCR 0x34 +#define OHARE_FCR 0x38 /* * Bits in feature control register. @@ -25,6 +26,7 @@ #define OH_BAY_FLOPPY_ENABLE 0x10 #define OH_IDE0_ENABLE 0x20 #define OH_IDE0_RESET_N 0x40 /* a guess */ +#define OH_BAY_DEV_MASK 0x1c #define OH_BAY_RESET_N 0x80 #define OH_IOBUS_ENABLE 0x100 /* IOBUS seems to be IDE */ #define OH_SCC_ENABLE 0x200 diff --git a/arch/ppc/kernel/open_pic.h b/include/asm-ppc/open_pic.h index 0e236c0b3848..b042d29875a2 100644 --- a/arch/ppc/kernel/open_pic.h +++ b/include/asm-ppc/open_pic.h @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.open_pic.h 1.14 10/11/01 12:09:12 trini + * BK Id: %F% %I% %G% %U% %#% */ /* * arch/ppc/kernel/open_pic.h -- OpenPIC Interrupt Handling @@ -16,6 +16,7 @@ #define _PPC_KERNEL_OPEN_PIC_H #include <linux/config.h> +#include <linux/irq.h> #define OPENPIC_SIZE 0x40000 @@ -40,6 +41,7 @@ extern u_char *OpenPIC_InitSenses; extern void* OpenPIC_Addr; /* Exported functions */ +extern void openpic_set_sources(int first_irq, int num_irqs, void *isr); extern void openpic_init(int, int, unsigned char *, int); extern u_int openpic_irq(void); extern void openpic_eoi(void); diff --git a/include/asm-ppc/page.h b/include/asm-ppc/page.h index 3da22a960ce0..76456dfdc8d7 100644 --- a/include/asm-ppc/page.h +++ b/include/asm-ppc/page.h @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.page.h 1.8 08/19/01 20:06:47 paulus + * BK Id: %F% %I% %G% %U% %#% */ #ifndef _PPC_PAGE_H #define _PPC_PAGE_H @@ -13,7 +13,11 @@ #include <linux/config.h> /* Be sure to change arch/ppc/Makefile to match */ +#ifdef CONFIG_KERNEL_START_BOOL +#define PAGE_OFFSET CONFIG_KERNEL_START +#else #define PAGE_OFFSET 0xc0000000 +#endif /* CONFIG_KERNEL_START_BOOL */ #define KERNELBASE PAGE_OFFSET #ifndef __ASSEMBLY__ @@ -83,9 +87,20 @@ typedef unsigned long pgprot_t; extern void clear_page(void *page); extern void copy_page(void *to, void *from); -#define clear_user_page(page, vaddr) clear_page(page) -#define copy_user_page(to, from, vaddr) copy_page(to, from) +extern void clear_user_page(void *page, unsigned long vaddr); +extern void copy_user_page(void *to, void *from, unsigned long vaddr); + +extern unsigned long ppc_memstart; +extern unsigned long ppc_memoffset; +#ifndef CONFIG_APUS +#define PPC_MEMSTART 0 +#define PPC_MEMOFFSET PAGE_OFFSET +#else +#define PPC_MEMSTART ppc_memstart +#define PPC_MEMOFFSET ppc_memoffset +#endif +#if defined(CONFIG_APUS) && !defined(MODULE) /* map phys->virtual and virtual->phys for RAM pages */ static inline unsigned long ___pa(unsigned long v) { @@ -113,8 +128,13 @@ static inline void* ___va(unsigned long p) return (void*) v; } -#define __pa(x) ___pa ((unsigned long)(x)) -#define __va(x) ___va ((unsigned long)(x)) +#else +#define ___pa(vaddr) ((vaddr)-PPC_MEMOFFSET) +#define ___va(paddr) ((paddr)+PPC_MEMOFFSET) +#endif + +#define __pa(x) ___pa((unsigned long)(x)) +#define __va(x) ((void *)(___va((unsigned long)(x)))) #define MAP_PAGE_RESERVED (1<<15) #define virt_to_page(kaddr) (mem_map + (((unsigned long)kaddr-PAGE_OFFSET) >> PAGE_SHIFT)) diff --git a/include/asm-ppc/pc_serial.h b/include/asm-ppc/pc_serial.h new file mode 100644 index 000000000000..61020a34f930 --- /dev/null +++ b/include/asm-ppc/pc_serial.h @@ -0,0 +1,129 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + * + * include/asm-ppc/pc_serial.h + * + * This is basically a copy of include/asm-i386/serial.h. + * It is used on platforms which have an ISA bus and thus are likely + * to have PC-style serial ports at the legacy I/O port addresses. + * It also includes the definitions for the fourport, accent, boca + * and hub6 multiport serial cards, although I have never heard of + * anyone using any of those on a PPC platform. -- paulus + */ + +#include <linux/config.h> + +/* + * This assumes you have a 1.8432 MHz clock for your UART. + * + * It'd be nice if someone built a serial card with a 24.576 MHz + * clock, since the 16550A is capable of handling a top speed of 1.5 + * megabits/second; but this requires the faster clock. + */ +#define BASE_BAUD ( 1843200 / 16 ) + +#ifdef CONFIG_SERIAL_MANY_PORTS +#define RS_TABLE_SIZE 64 +#else +#define RS_TABLE_SIZE 4 +#endif + +/* Standard COM flags (except for COM4, because of the 8514 problem) */ +#ifdef CONFIG_SERIAL_DETECT_IRQ +#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ) +#define STD_COM4_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_AUTO_IRQ) +#else +#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST) +#define STD_COM4_FLAGS ASYNC_BOOT_AUTOCONF +#endif + +#ifdef CONFIG_SERIAL_MANY_PORTS +#define FOURPORT_FLAGS ASYNC_FOURPORT +#define ACCENT_FLAGS 0 +#define BOCA_FLAGS 0 +#define HUB6_FLAGS 0 +#endif + +/* + * The following define the access methods for the HUB6 card. All + * access is through two ports for all 24 possible chips. The card is + * selected through the high 2 bits, the port on that card with the + * "middle" 3 bits, and the register on that port with the bottom + * 3 bits. + * + * While the access port and interrupt is configurable, the default + * port locations are 0x302 for the port control register, and 0x303 + * for the data read/write register. Normally, the interrupt is at irq3 + * but can be anything from 3 to 7 inclusive. Note that using 3 will + * require disabling com2. + */ + +#define C_P(card,port) (((card)<<6|(port)<<3) + 1) + +#define STD_SERIAL_PORT_DEFNS \ + /* UART CLK PORT IRQ FLAGS */ \ + { 0, BASE_BAUD, 0x3F8, 4, STD_COM_FLAGS }, /* ttyS0 */ \ + { 0, BASE_BAUD, 0x2F8, 3, STD_COM_FLAGS }, /* ttyS1 */ \ + { 0, BASE_BAUD, 0x3E8, 4, STD_COM_FLAGS }, /* ttyS2 */ \ + { 0, BASE_BAUD, 0x2E8, 3, STD_COM4_FLAGS }, /* ttyS3 */ + + +#ifdef CONFIG_SERIAL_MANY_PORTS +#define EXTRA_SERIAL_PORT_DEFNS \ + { 0, BASE_BAUD, 0x1A0, 9, FOURPORT_FLAGS }, /* ttyS4 */ \ + { 0, BASE_BAUD, 0x1A8, 9, FOURPORT_FLAGS }, /* ttyS5 */ \ + { 0, BASE_BAUD, 0x1B0, 9, FOURPORT_FLAGS }, /* ttyS6 */ \ + { 0, BASE_BAUD, 0x1B8, 9, FOURPORT_FLAGS }, /* ttyS7 */ \ + { 0, BASE_BAUD, 0x2A0, 5, FOURPORT_FLAGS }, /* ttyS8 */ \ + { 0, BASE_BAUD, 0x2A8, 5, FOURPORT_FLAGS }, /* ttyS9 */ \ + { 0, BASE_BAUD, 0x2B0, 5, FOURPORT_FLAGS }, /* ttyS10 */ \ + { 0, BASE_BAUD, 0x2B8, 5, FOURPORT_FLAGS }, /* ttyS11 */ \ + { 0, BASE_BAUD, 0x330, 4, ACCENT_FLAGS }, /* ttyS12 */ \ + { 0, BASE_BAUD, 0x338, 4, ACCENT_FLAGS }, /* ttyS13 */ \ + { 0, BASE_BAUD, 0x000, 0, 0 }, /* ttyS14 (spare) */ \ + { 0, BASE_BAUD, 0x000, 0, 0 }, /* ttyS15 (spare) */ \ + { 0, BASE_BAUD, 0x100, 12, BOCA_FLAGS }, /* ttyS16 */ \ + { 0, BASE_BAUD, 0x108, 12, BOCA_FLAGS }, /* ttyS17 */ \ + { 0, BASE_BAUD, 0x110, 12, BOCA_FLAGS }, /* ttyS18 */ \ + { 0, BASE_BAUD, 0x118, 12, BOCA_FLAGS }, /* ttyS19 */ \ + { 0, BASE_BAUD, 0x120, 12, BOCA_FLAGS }, /* ttyS20 */ \ + { 0, BASE_BAUD, 0x128, 12, BOCA_FLAGS }, /* ttyS21 */ \ + { 0, BASE_BAUD, 0x130, 12, BOCA_FLAGS }, /* ttyS22 */ \ + { 0, BASE_BAUD, 0x138, 12, BOCA_FLAGS }, /* ttyS23 */ \ + { 0, BASE_BAUD, 0x140, 12, BOCA_FLAGS }, /* ttyS24 */ \ + { 0, BASE_BAUD, 0x148, 12, BOCA_FLAGS }, /* ttyS25 */ \ + { 0, BASE_BAUD, 0x150, 12, BOCA_FLAGS }, /* ttyS26 */ \ + { 0, BASE_BAUD, 0x158, 12, BOCA_FLAGS }, /* ttyS27 */ \ + { 0, BASE_BAUD, 0x160, 12, BOCA_FLAGS }, /* ttyS28 */ \ + { 0, BASE_BAUD, 0x168, 12, BOCA_FLAGS }, /* ttyS29 */ \ + { 0, BASE_BAUD, 0x170, 12, BOCA_FLAGS }, /* ttyS30 */ \ + { 0, BASE_BAUD, 0x178, 12, BOCA_FLAGS }, /* ttyS31 */ +#else +#define EXTRA_SERIAL_PORT_DEFNS +#endif + +/* You can have up to four HUB6's in the system, but I've only + * included two cards here for a total of twelve ports. + */ +#if (defined(CONFIG_HUB6) && defined(CONFIG_SERIAL_MANY_PORTS)) +#define HUB6_SERIAL_PORT_DFNS \ + { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,0) }, /* ttyS32 */ \ + { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,1) }, /* ttyS33 */ \ + { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,2) }, /* ttyS34 */ \ + { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,3) }, /* ttyS35 */ \ + { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,4) }, /* ttyS36 */ \ + { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,5) }, /* ttyS37 */ \ + { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,0) }, /* ttyS38 */ \ + { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,1) }, /* ttyS39 */ \ + { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,2) }, /* ttyS40 */ \ + { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,3) }, /* ttyS41 */ \ + { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,4) }, /* ttyS42 */ \ + { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,5) }, /* ttyS43 */ +#else +#define HUB6_SERIAL_PORT_DFNS +#endif + +#define SERIAL_PORT_DFNS \ + STD_SERIAL_PORT_DEFNS \ + EXTRA_SERIAL_PORT_DEFNS \ + HUB6_SERIAL_PORT_DFNS diff --git a/include/asm-ppc/pci-bridge.h b/include/asm-ppc/pci-bridge.h index 659789948d49..b97852c0a8bc 100644 --- a/include/asm-ppc/pci-bridge.h +++ b/include/asm-ppc/pci-bridge.h @@ -1,10 +1,13 @@ /* - * BK Id: SCCS/s.pci-bridge.h 1.11 05/21/01 01:31:30 cort + * BK Id: %F% %I% %G% %U% %#% */ #ifdef __KERNEL__ #ifndef _ASM_PCI_BRIDGE_H #define _ASM_PCI_BRIDGE_H +#include <linux/ioport.h> +#include <linux/pci.h> + struct device_node; struct pci_controller; @@ -16,12 +19,20 @@ extern void *pci_bus_io_base(unsigned int bus); extern unsigned long pci_bus_io_base_phys(unsigned int bus); extern unsigned long pci_bus_mem_base_phys(unsigned int bus); +/* Allocate a new PCI host bridge structure */ +extern struct pci_controller* pcibios_alloc_controller(void); + +/* Helper function for setting up resources */ +extern void pci_init_resource(struct resource *res, unsigned long start, + unsigned long end, int flags, char *name); + /* * PCI <-> OF matching functions */ extern int pci_device_from_OF_node(struct device_node *node, u8* bus, u8* devfn); extern struct device_node* pci_device_to_OF_node(struct pci_dev *); +extern void pci_create_OF_bus_map(void); /* Get the PCI host controller for a bus */ extern struct pci_controller* pci_bus_to_hose(int bus); @@ -46,6 +57,7 @@ struct pci_controller { int first_busno; int last_busno; + int bus_offset; void *io_base_virt; unsigned long io_base_phys; @@ -65,16 +77,64 @@ struct pci_controller { struct resource io_resource; struct resource mem_resources[3]; int mem_resource_count; + + /* Host bridge I/O and Memory space + * Used for BAR placement algorithms + */ + struct resource io_space; + struct resource mem_space; }; /* These are used for config access before all the PCI probing has been done. */ -int early_read_config_byte(struct pci_controller *hose, int bus, int dev_fn, int where, u8 *val); -int early_read_config_word(struct pci_controller *hose, int bus, int dev_fn, int where, u16 *val); -int early_read_config_dword(struct pci_controller *hose, int bus, int dev_fn, int where, u32 *val); -int early_write_config_byte(struct pci_controller *hose, int bus, int dev_fn, int where, u8 val); -int early_write_config_word(struct pci_controller *hose, int bus, int dev_fn, int where, u16 val); -int early_write_config_dword(struct pci_controller *hose, int bus, int dev_fn, int where, u32 val); +int early_read_config_byte(struct pci_controller *hose, int bus, int dev_fn, + int where, u8 *val); +int early_read_config_word(struct pci_controller *hose, int bus, int dev_fn, + int where, u16 *val); +int early_read_config_dword(struct pci_controller *hose, int bus, int dev_fn, + int where, u32 *val); +int early_write_config_byte(struct pci_controller *hose, int bus, int dev_fn, + int where, u8 val); +int early_write_config_word(struct pci_controller *hose, int bus, int dev_fn, + int where, u16 val); +int early_write_config_dword(struct pci_controller *hose, int bus, int dev_fn, + int where, u32 val); + +extern void setup_indirect_pci(struct pci_controller* hose, + u32 cfg_addr, u32 cfg_data); +extern void setup_grackle(struct pci_controller *hose); + +extern unsigned char common_swizzle(struct pci_dev *, unsigned char *); + +/* + * The following code swizzles for exactly one bridge. The routine + * common_swizzle below handles multiple bridges. But there are a + * some boards that don't follow the PCI spec's suggestion so we + * break this piece out separately. + */ +static inline unsigned char bridge_swizzle(unsigned char pin, + unsigned char idsel) +{ + return (((pin-1) + idsel) % 4) + 1; +} + +/* + * The following macro is used to lookup irqs in a standard table + * format for those PPC systems that do not already have PCI + * interrupts properly routed. + */ +/* FIXME - double check this */ +#define PCI_IRQ_TABLE_LOOKUP \ +({ long _ctl_ = -1; \ + if (idsel >= min_idsel && idsel <= max_idsel && pin <= irqs_per_slot) \ + _ctl_ = pci_irq_table[idsel - min_idsel][pin-1]; \ + _ctl_; }) + +/* + * Scan the buses below a given PCI host bridge and assign suitable + * resources to all devices found. + */ +extern int pciauto_bus_scan(struct pci_controller *, int); #endif #endif /* __KERNEL__ */ diff --git a/include/asm-ppc/pci.h b/include/asm-ppc/pci.h index 7a28e8bad5ac..4a843c6be601 100644 --- a/include/asm-ppc/pci.h +++ b/include/asm-ppc/pci.h @@ -1,10 +1,19 @@ /* - * BK Id: SCCS/s.pci.h 1.16 10/15/01 22:51:33 paulus + * BK Id: %F% %I% %G% %U% %#% */ #ifndef __PPC_PCI_H #define __PPC_PCI_H #ifdef __KERNEL__ +#include <linux/types.h> +#include <linux/slab.h> +#include <linux/string.h> +#include <linux/mm.h> +#include <asm/scatterlist.h> +#include <asm/io.h> + +struct pci_dev; + /* Values for the `which' argument to sys_pciconfig_iobase syscall. */ #define IOBASE_BRIDGE_NUMBER 0 #define IOBASE_MEMORY 1 @@ -12,8 +21,13 @@ #define IOBASE_ISA_IO 3 #define IOBASE_ISA_MEM 4 +/* + * Set this to 1 if you want the kernel to re-assign all PCI + * bus numbers + */ +extern int pci_assign_all_busses; -extern int pcibios_assign_all_busses(void); +#define pcibios_assign_all_busses() (pci_assign_all_busses) #define PCIBIOS_MIN_IO 0x1000 #define PCIBIOS_MIN_MEM 0x10000000 @@ -157,10 +171,15 @@ static inline int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg, * temporary 2.4 hack */ for (i = 0; i < nents; i++) { - if (!sg[i].page) + if (sg[i].address && sg[i].page) + BUG(); + else if (!sg[i].address && !sg[i].page) BUG(); - sg[i].dma_address = page_to_bus(sg[i].page) + sg[i].offset; + if (sg[i].address) + sg[i].dma_address = virt_to_bus(sg[i].address); + else + sg[i].dma_address = page_to_bus(sg[i].page) + sg[i].offset; } return nents; @@ -251,14 +270,6 @@ pci_dac_dma_sync_single(struct pci_dev *pdev, dma64_addr_t dma_addr, size_t len, /* Nothing to do. */ } -/* These macros should be used after a pci_map_sg call has been done - * to get bus addresses of each of the SG entries and their lengths. - * You should only work with the number of sg entries pci_map_sg - * returns. - */ -#define sg_dma_address(sg) ((sg)->dma_address) -#define sg_dma_len(sg) ((sg)->length) - /* Return the index of the PCI controller for device PDEV. */ extern int pci_controller_num(struct pci_dev *pdev); diff --git a/include/asm-ppc/pgtable.h b/include/asm-ppc/pgtable.h index 8093049039f4..e92aaf0f0661 100644 --- a/include/asm-ppc/pgtable.h +++ b/include/asm-ppc/pgtable.h @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.pgtable.h 1.15 09/22/01 11:26:52 trini + * BK Id: %F% %I% %G% %U% %#% */ #ifdef __KERNEL__ #ifndef _PPC_PGTABLE_H @@ -14,16 +14,26 @@ #include <asm/mmu.h> #include <asm/page.h> +extern void _tlbie(unsigned long address); +extern void _tlbia(void); + #if defined(CONFIG_4xx) -extern void local_flush_tlb_all(void); -extern void local_flush_tlb_mm(struct mm_struct *mm); -extern void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr); -extern void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, - unsigned long end); +#define __tlbia() asm volatile ("tlbia; sync" : : : "memory") + +static inline void local_flush_tlb_all(void) + { __tlbia(); } +static inline void local_flush_tlb_mm(struct mm_struct *mm) + { __tlbia(); } +static inline void local_flush_tlb_page(struct vm_area_struct *vma, + unsigned long vmaddr) + { _tlbie(vmaddr); } +static inline void local_flush_tlb_range(struct mm_struct *mm, + unsigned long start, unsigned long end) + { __tlbia(); } #define update_mmu_cache(vma, addr, pte) do { } while (0) #elif defined(CONFIG_8xx) -#define __tlbia() asm volatile ("tlbia" : : ) +#define __tlbia() asm volatile ("tlbia; sync" : : : "memory") static inline void local_flush_tlb_all(void) { __tlbia(); } @@ -31,8 +41,8 @@ static inline void local_flush_tlb_mm(struct mm_struct *mm) { __tlbia(); } static inline void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr) - { __tlbia(); } -static inline void local_flush_tlb_range(struct vm_area_struct *vma, + { _tlbie(vmaddr); } +static inline void local_flush_tlb_range(struct mm_struct *mm, unsigned long start, unsigned long end) { __tlbia(); } #define update_mmu_cache(vma, addr, pte) do { } while (0) @@ -82,13 +92,14 @@ static inline void flush_tlb_pgtables(struct mm_struct *mm, #define flush_cache_mm(mm) do { } while (0) #define flush_cache_range(vma, a, b) do { } while (0) #define flush_cache_page(vma, p) do { } while (0) -#define flush_icache_page(vma, page) do { } while (0) +#define flush_page_to_ram(page) do { } while (0) +extern void flush_icache_user_range(struct vm_area_struct *vma, + struct page *page, unsigned long addr, int len); extern void flush_icache_range(unsigned long, unsigned long); -extern void __flush_page_to_ram(unsigned long page_va); -extern void flush_page_to_ram(struct page *page); - -#define flush_dcache_page(page) do { } while (0) +extern void __flush_dcache_icache(void *page_va); +extern void flush_dcache_page(struct page *page); +extern void flush_icache_page(struct vm_area_struct *vma, struct page *page); extern unsigned long va_to_phys(unsigned long address); extern pte_t *va_to_pte(unsigned long address); @@ -126,6 +137,12 @@ extern unsigned long ioremap_bot, ioremap_base; * that is where it exists in the MD_TWC, and bit 26 for writethrough. * These will get masked from the level 2 descriptor at TLB load time, and * copied to the MD_TWC before it gets loaded. + * Large page sizes added. We currently support two sizes, 4K and 8M. + * This also allows a TLB hander optimization because we can directly + * load the PMD into MD_TWC. The 8M pages are only used for kernel + * mapping of well known areas. The PMD (PGD) entries contain control + * flags in addition to the address, so care must be taken that the + * software no longer assumes these are only pointers. */ /* @@ -196,17 +213,44 @@ extern unsigned long ioremap_bot, ioremap_base; */ #if defined(CONFIG_4xx) + +/* There are several potential gotchas here. The 4xx hardware TLBLO + field looks like this: + + 0 1 2 3 4 ... 18 19 20 21 22 23 24 25 26 27 28 29 30 31 + RPN..................... 0 0 EX WR ZSEL....... W I M G + + Where possible we make the Linux PTE bits match up with this + + - bits 20 and 21 must be cleared, because we use 4k pages (4xx can + support down to 1k pages), this is done in the TLBMiss exception + handler. + - We use only zones 0 (for kernel pages) and 1 (for user pages) + of the 16 available. Bit 24-26 of the TLB are cleared in the TLB + miss handler. Bit 27 is PAGE_USER, thus selecting the correct + zone. + - PRESENT *must* be in the bottom two bits because swap cache + entries use the top 30 bits. Because 4xx doesn't support SMP + anyway, M is irrelevant so we borrow it for PAGE_PRESENT. Bit 30 + is cleared in the TLB miss handler before the TLB entry is loaded. + - All other bits of the PTE are loaded into TLBLO without + modification, leaving us only the bits 20, 21, 24, 25, 26, 30 for + software PTE bits. We actually use use bits 20, 24, 25, 26, and + 30 respectively for the software bits: ACCESSED, DIRTY, RW, EXEC, + PRESENT. +*/ + /* Definitions for 4xx embedded chips. */ #define _PAGE_GUARDED 0x001 /* G: page is guarded from prefetch */ -#define _PAGE_COHERENT 0x002 /* M: enforece memory coherence */ +#define _PAGE_PRESENT 0x002 /* software: PTE contains a translation */ #define _PAGE_NO_CACHE 0x004 /* I: caching is inhibited */ #define _PAGE_WRITETHRU 0x008 /* W: caching is write-through */ #define _PAGE_USER 0x010 /* matches one of the zone permission bits */ -#define _PAGE_EXEC 0x020 /* software: i-cache coherency required */ -#define _PAGE_PRESENT 0x040 /* software: PTE contains a translation */ -#define _PAGE_DIRTY 0x100 /* C: page changed */ -#define _PAGE_RW 0x200 /* Writes permitted */ -#define _PAGE_ACCESSED 0x400 /* R: page referenced */ +#define _PAGE_RW 0x040 /* software: Writes permitted */ +#define _PAGE_DIRTY 0x080 /* software: dirty page */ +#define _PAGE_HWWRITE 0x100 /* hardware: Dirty & RW, set in exception */ +#define _PAGE_HWEXEC 0x200 /* hardware: EX permission */ +#define _PAGE_ACCESSED 0x400 /* software: R: page referenced */ #elif defined(CONFIG_8xx) /* Definitions for 8xx embedded chips. */ @@ -219,14 +263,21 @@ extern unsigned long ioremap_bot, ioremap_base; */ #define _PAGE_EXEC 0x0008 /* software: i-cache coherency required */ #define _PAGE_GUARDED 0x0010 /* software: guarded access */ -#define _PAGE_WRITETHRU 0x0020 /* software: use writethrough cache */ +#define _PAGE_DIRTY 0x0020 /* software: page changed */ #define _PAGE_RW 0x0040 /* software: user write access allowed */ #define _PAGE_ACCESSED 0x0080 /* software: page referenced */ +/* Setting any bits in the nibble with the follow two controls will + * require a TLB exception handler change. It is assumed unused bits + * are always zero. + */ #define _PAGE_HWWRITE 0x0100 /* h/w write enable: never set in Linux PTE */ -#define _PAGE_DIRTY 0x0200 /* software: page changed */ #define _PAGE_USER 0x0800 /* One of the PP bits, the other is USER&~RW */ +#define _PMD_PRESENT 0x0001 +#define _PMD_PAGE_MASK 0x000c +#define _PMD_PAGE_8M 0x000c + #else /* CONFIG_6xx */ /* Definitions for 60x, 740/750, etc. */ #define _PAGE_PRESENT 0x001 /* software: pte contains a translation */ @@ -262,14 +313,11 @@ extern unsigned long ioremap_bot, ioremap_base; #ifndef _PAGE_HWWRITE #define _PAGE_HWWRITE 0 #endif - -/* We can't use _PAGE_HWWRITE on any SMP due to the lack of ability - * to atomically manage _PAGE_HWWRITE and it's coordination flags, - * _PAGE_DIRTY or _PAGE_RW. The SMP systems must manage HWWRITE - * or its logical equivalent in the MMU management software. - */ -#if CONFIG_SMP && _PAGE_HWWRITE -#error "You can't configure SMP and HWWRITE" +#ifndef _PAGE_HWEXEC +#define _PAGE_HWEXEC 0 +#endif +#ifndef _PAGE_EXEC +#define _PAGE_EXEC 0 #endif #define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY) @@ -281,9 +329,9 @@ extern unsigned long ioremap_bot, ioremap_base; * another purpose. -- paulus. */ #define _PAGE_BASE _PAGE_PRESENT | _PAGE_ACCESSED -#define _PAGE_WRENABLE _PAGE_RW | _PAGE_DIRTY +#define _PAGE_WRENABLE _PAGE_RW | _PAGE_DIRTY | _PAGE_HWWRITE -#define _PAGE_KERNEL _PAGE_BASE | _PAGE_WRENABLE | _PAGE_SHARED +#define _PAGE_KERNEL _PAGE_BASE | _PAGE_WRENABLE | _PAGE_SHARED | _PAGE_HWEXEC #define _PAGE_IO _PAGE_KERNEL | _PAGE_NO_CACHE | _PAGE_GUARDED #define PAGE_NONE __pgprot(_PAGE_BASE) @@ -345,7 +393,7 @@ extern unsigned long empty_zero_page[1024]; * Permanent address of a page. */ #define page_address(page) ((page)->virtual) -#define pte_page(x) (mem_map+(unsigned long)((pte_val(x) >> PAGE_SHIFT))) +#define pte_page(x) (mem_map+(unsigned long)((pte_val(x)-PPC_MEMSTART) >> PAGE_SHIFT)) #ifndef __ASSEMBLY__ /* @@ -411,7 +459,7 @@ static inline pte_t mk_pte_phys(unsigned long physpage, pgprot_t pgprot) #define mk_pte(page,pgprot) \ ({ \ pte_t pte; \ - pte_val(pte) = ((page - mem_map) << PAGE_SHIFT) | pgprot_val(pgprot); \ + pte_val(pte) = (((page - mem_map) << PAGE_SHIFT) + PPC_MEMSTART) | pgprot_val(pgprot); \ pte; \ }) @@ -435,8 +483,9 @@ static inline unsigned long pte_update(pte_t *p, unsigned long clr, __asm__ __volatile__("\ 1: lwarx %0,0,%3\n\ andc %1,%0,%4\n\ - or %1,%1,%5\n\ - stwcx. %1,0,%3\n\ + or %1,%1,%5\n" + PPC405_ERR77(0,%3) +" stwcx. %1,0,%3\n\ bne- 1b" : "=&r" (old), "=&r" (tmp), "=m" (*p) : "r" (p), "r" (clr), "r" (set), "m" (*p) @@ -445,10 +494,18 @@ static inline unsigned long pte_update(pte_t *p, unsigned long clr, } /* - * Writing a new value into the PTE doesn't disturb the state of the - * _PAGE_HASHPTE bit, on those machines which use an MMU hash table. + * set_pte stores a linux PTE into the linux page table. + * On machines which use an MMU hash table we avoid changing the + * _PAGE_HASHPTE bit. */ -extern void set_pte(pte_t *ptep, pte_t pte); +static inline void set_pte(pte_t *ptep, pte_t pte) +{ +#if _PAGE_HASHPTE != 0 + pte_update(ptep, ~_PAGE_HASHPTE, pte_val(pte) & ~_PAGE_HASHPTE); +#else + *ptep = pte; +#endif +} static inline int ptep_test_and_clear_young(pte_t *ptep) { @@ -477,7 +534,7 @@ static inline void ptep_mkdirty(pte_t *ptep) #define pte_same(A,B) (((pte_val(A) ^ pte_val(B)) & ~_PAGE_HASHPTE) == 0) -#define pmd_page(pmd) (pmd_val(pmd)) +#define pmd_page(pmd) (pmd_val(pmd) & PAGE_MASK) /* to find an entry in a kernel page-table-directory */ #define pgd_offset_k(address) pgd_offset(&init_mm, address) diff --git a/include/asm-ppc/pmac_feature.h b/include/asm-ppc/pmac_feature.h new file mode 100644 index 000000000000..3670cde23854 --- /dev/null +++ b/include/asm-ppc/pmac_feature.h @@ -0,0 +1,253 @@ +/* + * Definition of platform feature hooks for PowerMacs + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1998 Paul Mackerras & + * Ben. Herrenschmidt. + * + * + * Note: I removed media-bay details from the feature stuff, I beleive it's + * not worth it, the media-bay driver can directly use the mac-io + * ASIC registers. + * + * Implementation note: Currently, none of these functions will block. + * However, they may internally protect themselves with a spinlock + * for way too long. Be prepared for at least some of these to block + * in the future. + * + * Unless specifically defined, the result code is assumed to be an + * error when negative, 0 is the default success result. Some functions + * may return additional positive result values. + * + * To keep implementation simple, all feature calls are assumed to have + * the prototype parameters (struct device_node* node, int value). + * When either is not used, pass 0. + */ + +#ifdef __KERNEL__ +#ifndef __PPC_ASM_PMAC_FEATURE_H +#define __PPC_ASM_PMAC_FEATURE_H + +/* + * Known Mac motherboard models + * + * Please, report any error here to benh@kernel.crashing.org, thanks ! + */ + +/* PowerSurge are the first generation of PCI Pmacs. This include + * all of the Grand-Central based machines + */ +#define PMAC_TYPE_PSURGE 0x10 /* PowerSurge */ + +/* Here is the infamous serie of OHare based machines + */ +#define PMAC_TYPE_COMET 0x20 /* Beleived to be PowerBook 2400 */ +#define PMAC_TYPE_HOOPER 0x21 /* Beleived to be PowerBook 3400 */ +#define PMAC_TYPE_KANGA 0x22 /* PowerBook 3500 (first G3) */ +#define PMAC_TYPE_ALCHEMY 0x23 /* Alchemy motherboard base */ +#define PMAC_TYPE_GAZELLE 0x24 /* Spartacus, some 5xxx/6xxx */ +#define PMAC_TYPE_UNKNOWN_OHARE 0x2f /* Unknown, but OHare based */ + +/* Here are the Heathrow based machines + * FIXME: Differenciate wallstreet,mainstreet,wallstreetII + */ +#define PMAC_TYPE_GOSSAMER 0x30 /* Gossamer motherboard */ +#define PMAC_TYPE_SILK 0x31 /* Desktop PowerMac G3 */ +#define PMAC_TYPE_WALLSTREET 0x32 /* Wallstreet/Mainstreet PowerBook*/ +#define PMAC_TYPE_UNKNOWN_HEATHROW 0x3f /* Unknown but heathrow based */ + +/* Here are newworld machines based on Paddington (heathrow derivative) + */ +#define PMAC_TYPE_101_PBOOK 0x40 /* 101 PowerBook (aka Lombard) */ +#define PMAC_TYPE_ORIG_IMAC 0x41 /* First generation iMac */ +#define PMAC_TYPE_YOSEMITE 0x42 /* B&W G3 */ +#define PMAC_TYPE_YIKES 0x43 /* Yikes G4 (PCI graphics) */ +#define PMAC_TYPE_UNKNOWN_PADDINGTON 0x4f /* Unknown but paddington based */ + +/* Core99 machines based on UniNorth 1.0 and 1.5 + * + * Note: A single entry here may cover several actual models according + * to the device-tree. (Sawtooth is most tower G4s, FW_IMAC is most + * FireWire based iMacs, etc...). Those machines are too similar to be + * distinguished here, when they need to be differencied, use the + * device-tree "model" or "compatible" property. + */ +#define PMAC_TYPE_ORIG_IBOOK 0x40 /* First iBook model (no firewire) */ +#define PMAC_TYPE_SAWTOOTH 0x41 /* Desktop G4s */ +#define PMAC_TYPE_FW_IMAC 0x42 /* FireWire iMacs (except Pangea based) */ +#define PMAC_TYPE_FW_IBOOK 0x43 /* FireWire iBooks (except iBook2) */ +#define PMAC_TYPE_CUBE 0x44 /* Cube PowerMac */ +#define PMAC_TYPE_QUICKSILVER 0x45 /* QuickSilver G4s */ +#define PMAC_TYPE_PISMO 0x46 /* Pismo PowerBook */ +#define PMAC_TYPE_TITANIUM 0x47 /* Titanium PowerBook */ +#define PMAC_TYPE_TITANIUM2 0x48 /* Titanium II PowerBook */ +#define PMAC_TYPE_UNKNOWN_CORE99 0x5f + +/* MacRISC2 machines based on the Pangea chipset + */ +#define PMAC_TYPE_PANGEA_IMAC 0x100 /* Flower Power iMac */ +#define PMAC_TYPE_IBOOK2 0x101 /* iBook2 (polycarbonate) */ +#define PMAC_TYPE_FLAT_PANEL_IMAC 0x102 /* Flat panel iMac */ +#define PMAC_TYPE_UNKNOWN_PANGEA 0x10f + +/* + * Motherboard flags + */ + +#define PMAC_MB_CAN_SLEEP 0x00000001 +#define PMAC_MB_HAS_FW_POWER 0x00000002 + +/* + * Feature calls supported on pmac + * + */ + +/* + * Use this inline wrapper + */ +struct device_node; + +static inline int pmac_call_feature(int selector, struct device_node* node, + int param, int value) +{ + if (!ppc_md.feature_call) + return -ENODEV; + return ppc_md.feature_call(selector, node, param, value); +} + +/* PMAC_FTR_SERIAL_ENABLE (struct device_node* node, int param, int value) + * enable/disable an SCC side. Pass the node corresponding to the + * channel side as a parameter. + * param is the type of port + * if param is ored with PMAC_SCC_FLAG_XMON, then the SCC is locked enabled + * for use by xmon. + */ +#define PMAC_FTR_SCC_ENABLE PMAC_FTR_DEF(0) + #define PMAC_SCC_ASYNC 0 + #define PMAC_SCC_IRDA 1 + #define PMAC_SCC_I2S1 2 + #define PMAC_SCC_FLAG_XMON 0x00001000 + +/* PMAC_FTR_MODEM_ENABLE (struct device_node* node, 0, int value) + * enable/disable the internal modem. + */ +#define PMAC_FTR_MODEM_ENABLE PMAC_FTR_DEF(1) + +/* PMAC_FTR_SWIM3_ENABLE (struct device_node* node, 0,int value) + * enable/disable the swim3 (floppy) cell of a mac-io ASIC + */ +#define PMAC_FTR_SWIM3_ENABLE PMAC_FTR_DEF(2) + +/* PMAC_FTR_MESH_ENABLE (struct device_node* node, 0, int value) + * enable/disable the mesh (scsi) cell of a mac-io ASIC + */ +#define PMAC_FTR_MESH_ENABLE PMAC_FTR_DEF(3) + +/* PMAC_FTR_IDE_ENABLE (struct device_node* node, int busID, int value) + * enable/disable an IDE port of a mac-io ASIC + * pass the busID parameter + */ +#define PMAC_FTR_IDE_ENABLE PMAC_FTR_DEF(4) + +/* PMAC_FTR_IDE_RESET (struct device_node* node, int busID, int value) + * assert(1)/release(0) an IDE reset line (mac-io IDE only) + */ +#define PMAC_FTR_IDE_RESET PMAC_FTR_DEF(5) + +/* PMAC_FTR_BMAC_ENABLE (struct device_node* node, 0, int value) + * enable/disable the bmac (ethernet) cell of a mac-io ASIC, also drive + * it's reset line + */ +#define PMAC_FTR_BMAC_ENABLE PMAC_FTR_DEF(6) + +/* PMAC_FTR_GMAC_ENABLE (struct device_node* node, 0, int value) + * enable/disable the gmac (ethernet) cell of an uninorth ASIC. This + * control the cell's clock. + */ +#define PMAC_FTR_GMAC_ENABLE PMAC_FTR_DEF(7) + +/* PMAC_FTR_GMAC_PHY_RESET (struct device_node* node, 0, 0) + * Perform a HW reset of the PHY connected to a gmac controller. + * Pass the gmac device node, not the PHY node. + */ +#define PMAC_FTR_GMAC_PHY_RESET PMAC_FTR_DEF(8) + +/* PMAC_FTR_SOUND_CHIP_ENABLE (struct device_node* node, 0, int value) + * enable/disable the sound chip, whatever it is and provided it can + * acually be controlled + */ +#define PMAC_FTR_SOUND_CHIP_ENABLE PMAC_FTR_DEF(9) + +/* -- add various tweaks related to sound routing -- */ + +/* PMAC_FTR_AIRPORT_ENABLE (struct device_node* node, 0, int value) + * enable/disable the airport card + */ +#define PMAC_FTR_AIRPORT_ENABLE PMAC_FTR_DEF(10) + +/* PMAC_FTR_RESET_CPU (NULL, int cpu_nr, 0) + * toggle the reset line of a CPU on an uninorth-based SMP machine + */ +#define PMAC_FTR_RESET_CPU PMAC_FTR_DEF(11) + +/* PMAC_FTR_USB_ENABLE (struct device_node* node, 0, int value) + * enable/disable an USB cell, along with the power of the USB "pad" + * on keylargo based machines + */ +#define PMAC_FTR_USB_ENABLE PMAC_FTR_DEF(12) + +/* PMAC_FTR_1394_ENABLE (struct device_node* node, 0, int value) + * enable/disable the firewire cell of an uninorth ASIC. + */ +#define PMAC_FTR_1394_ENABLE PMAC_FTR_DEF(13) + +/* PMAC_FTR_1394_CABLE_POWER (struct device_node* node, 0, int value) + * enable/disable the firewire cable power supply of the uninorth + * firewire cell + */ +#define PMAC_FTR_1394_CABLE_POWER PMAC_FTR_DEF(14) + +/* PMAC_FTR_SLEEP_STATE (struct device_node* node, 0, int value) + * set the sleep state of the motherboard. + * Pass -1 as value to query for sleep capability + */ +#define PMAC_FTR_SLEEP_STATE PMAC_FTR_DEF(15) + +/* PMAC_FTR_GET_MB_INFO (NULL, selector, 0) + * + * returns some motherboard infos. + * selector: 0 - model id + * 1 - model flags (capabilities) + * 2 - model name (cast to const char *) + */ +#define PMAC_FTR_GET_MB_INFO PMAC_FTR_DEF(16) +#define PMAC_MB_INFO_MODEL 0 +#define PMAC_MB_INFO_FLAGS 1 +#define PMAC_MB_INFO_NAME 2 + +/* PMAC_FTR_READ_GPIO (NULL, int index, 0) + * + * read a GPIO from a mac-io controller of type KeyLargo or Pangea. + * the value returned is a byte (positive), or a negative error code + */ +#define PMAC_FTR_READ_GPIO PMAC_FTR_DEF(17) + +/* PMAC_FTR_WRITE_GPIO (NULL, int index, int value) + * + * write a GPIO of a mac-io controller of type KeyLargo or Pangea. + */ +#define PMAC_FTR_WRITE_GPIO PMAC_FTR_DEF(18) + + +/* Don't use those directly, they are for the sake of pmac_setup.c */ +extern int pmac_do_feature_call(unsigned int selector, ...); +extern void pmac_feature_init(void); +extern void pmac_feature_late_init(void); + +#define PMAC_FTR_DEF(x) ((_MACH_Pmac << 16) | (x)) + +#endif /* __PPC_ASM_PMAC_FEATURE_H */ +#endif /* __KERNEL__ */ diff --git a/include/asm-ppc/posix_types.h b/include/asm-ppc/posix_types.h index 23571b92fb1a..0a44935561ee 100644 --- a/include/asm-ppc/posix_types.h +++ b/include/asm-ppc/posix_types.h @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.posix_types.h 1.5 05/17/01 18:14:25 cort + * BK Id: %F% %I% %G% %U% %#% */ #ifndef _PPC_POSIX_TYPES_H #define _PPC_POSIX_TYPES_H @@ -11,7 +11,7 @@ */ typedef unsigned int __kernel_dev_t; -typedef unsigned int __kernel_ino_t; +typedef unsigned long __kernel_ino_t; typedef unsigned int __kernel_mode_t; typedef unsigned short __kernel_nlink_t; typedef long __kernel_off_t; diff --git a/include/asm-ppc/ppc405_dma.h b/include/asm-ppc/ppc405_dma.h new file mode 100755 index 000000000000..eabdb2502e4a --- /dev/null +++ b/include/asm-ppc/ppc405_dma.h @@ -0,0 +1,1275 @@ +/* + * + * Copyright 2000 MontaVista Software Inc. + * PPC405 modifications + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * + * Module name: ppc405_dma.h + * + * Description: + * Data structures specific to the IBM PowerPC 405 on-chip DMA controller + * and API. + * + */ + +#ifdef __KERNEL__ +#ifndef __ASMPPC_405_DMA_H +#define __ASMPPC_405_DMA_H + +#include <linux/types.h> + +/* #define DEBUG_405DMA */ + +#define TRUE 1 +#define FALSE 0 + +#define SGL_LIST_SIZE 4096 +/* #define PCI_ALLOC_IS_NONCONSISTENT */ + +#define MAX_405GP_DMA_CHANNELS 4 + +/* The maximum address that we can perform a DMA transfer to on this platform */ +/* Doesn't really apply... */ +#define MAX_DMA_ADDRESS 0xFFFFFFFF + +extern unsigned long ISA_DMA_THRESHOLD; + +#define dma_outb outb +#define dma_inb inb + + +/* + * Function return status codes + * These values are used to indicate whether or not the function + * call was successful, or a bad/invalid parameter was passed. + */ +#define DMA_STATUS_GOOD 0 +#define DMA_STATUS_BAD_CHANNEL 1 +#define DMA_STATUS_BAD_HANDLE 2 +#define DMA_STATUS_BAD_MODE 3 +#define DMA_STATUS_NULL_POINTER 4 +#define DMA_STATUS_OUT_OF_MEMORY 5 +#define DMA_STATUS_SGL_LIST_EMPTY 6 +#define DMA_STATUS_GENERAL_ERROR 7 + + +/* + * These indicate status as returned from the DMA Status Register. + */ +#define DMA_STATUS_NO_ERROR 0 +#define DMA_STATUS_CS 1 /* Count Status */ +#define DMA_STATUS_TS 2 /* Transfer Status */ +#define DMA_STATUS_DMA_ERROR 3 /* DMA Error Occurred */ +#define DMA_STATUS_DMA_BUSY 4 /* The channel is busy */ + + +/* + * Transfer Modes + * These modes are defined in a way that makes it possible to + * simply "or" in the value in the control register. + */ +#define DMA_MODE_READ DMA_TD /* Peripheral to Memory */ +#define DMA_MODE_WRITE 0 /* Memory to Peripheral */ +#define DMA_MODE_MM (SET_DMA_TM(TM_S_MM)) /* memory to memory */ + + /* Device-paced memory to memory, */ + /* device is at source address */ +#define DMA_MODE_MM_DEVATSRC (DMA_TD | SET_DMA_TM(TM_D_MM)) + + /* Device-paced memory to memory, */ + /* device is at destination address */ +#define DMA_MODE_MM_DEVATDST (SET_DMA_TM(TM_D_MM)) + + +/* + * DMA Polarity Configuration Register + */ +#define DMAReq0_ActiveLow (1<<31) +#define DMAAck0_ActiveLow (1<<30) +#define EOT0_ActiveLow (1<<29) /* End of Transfer */ + +#define DMAReq1_ActiveLow (1<<28) +#define DMAAck1_ActiveLow (1<<27) +#define EOT1_ActiveLow (1<<26) + +#define DMAReq2_ActiveLow (1<<25) +#define DMAAck2_ActiveLow (1<<24) +#define EOT2_ActiveLow (1<<23) + +#define DMAReq3_ActiveLow (1<<22) +#define DMAAck3_ActiveLow (1<<21) +#define EOT3_ActiveLow (1<<20) + +/* + * DMA Sleep Mode Register + */ +#define SLEEP_MODE_ENABLE (1<<21) + + +/* + * DMA Status Register + */ +#define DMA_CS0 (1<<31) /* Terminal Count has been reached */ +#define DMA_CS1 (1<<30) +#define DMA_CS2 (1<<29) +#define DMA_CS3 (1<<28) + +#define DMA_TS0 (1<<27) /* End of Transfer has been requested */ +#define DMA_TS1 (1<<26) +#define DMA_TS2 (1<<25) +#define DMA_TS3 (1<<24) + +#define DMA_CH0_ERR (1<<23) /* DMA Chanel 0 Error */ +#define DMA_CH1_ERR (1<<22) +#define DMA_CH2_ERR (1<<21) +#define DMA_CH3_ERR (1<<20) + +#define DMA_IN_DMA_REQ0 (1<<19) /* Internal DMA Request is pending */ +#define DMA_IN_DMA_REQ1 (1<<18) +#define DMA_IN_DMA_REQ2 (1<<17) +#define DMA_IN_DMA_REQ3 (1<<16) + +#define DMA_EXT_DMA_REQ0 (1<<15) /* External DMA Request is pending */ +#define DMA_EXT_DMA_REQ1 (1<<14) +#define DMA_EXT_DMA_REQ2 (1<<13) +#define DMA_EXT_DMA_REQ3 (1<<12) + +#define DMA_CH0_BUSY (1<<11) /* DMA Channel 0 Busy */ +#define DMA_CH1_BUSY (1<<10) +#define DMA_CH2_BUSY (1<<9) +#define DMA_CH3_BUSY (1<<8) + +#define DMA_SG0 (1<<7) /* DMA Channel 0 Scatter/Gather in progress */ +#define DMA_SG1 (1<<6) +#define DMA_SG2 (1<<5) +#define DMA_SG3 (1<<4) + + + +/* + * DMA Channel Control Registers + */ +#define DMA_CH_ENABLE (1<<31) /* DMA Channel Enable */ +#define SET_DMA_CH_ENABLE(x) (((x)&0x1)<<31) +#define GET_DMA_CH_ENABLE(x) (((x)&DMA_CH_ENABLE)>>31) + +#define DMA_CIE_ENABLE (1<<30) /* DMA Channel Interrupt Enable */ +#define SET_DMA_CIE_ENABLE(x) (((x)&0x1)<<30) +#define GET_DMA_CIE_ENABLE(x) (((x)&DMA_CIE_ENABLE)>>30) + +#define DMA_TD (1<<29) +#define SET_DMA_TD(x) (((x)&0x1)<<29) +#define GET_DMA_TD(x) (((x)&DMA_TD)>>29) + +#define DMA_PL (1<<28) /* Peripheral Location */ +#define SET_DMA_PL(x) (((x)&0x1)<<28) +#define GET_DMA_PL(x) (((x)&DMA_PL)>>28) + +#define EXTERNAL_PERIPHERAL 0 +#define INTERNAL_PERIPHERAL 1 + + +#define SET_DMA_PW(x) (((x)&0x3)<<26) /* Peripheral Width */ +#define DMA_PW_MASK SET_DMA_PW(3) +#define PW_8 0 +#define PW_16 1 +#define PW_32 2 +#define PW_64 3 +#define GET_DMA_PW(x) (((x)&DMA_PW_MASK)>>26) + +#define DMA_DAI (1<<25) /* Destination Address Increment */ +#define SET_DMA_DAI(x) (((x)&0x1)<<25) + +#define DMA_SAI (1<<24) /* Source Address Increment */ +#define SET_DMA_SAI(x) (((x)&0x1)<<24) + +#define DMA_BEN (1<<23) /* Buffer Enable */ +#define SET_DMA_BEN(x) (((x)&0x1)<<23) + +#define SET_DMA_TM(x) (((x)&0x3)<<21) /* Transfer Mode */ +#define DMA_TM_MASK SET_DMA_TM(3) +#define TM_PERIPHERAL 0 /* Peripheral */ +#define TM_RESERVED 1 /* Reserved */ +#define TM_S_MM 2 /* Memory to Memory */ +#define TM_D_MM 3 /* Device Paced Memory to Memory */ +#define GET_DMA_TM(x) (((x)&DMA_TM_MASK)>>21) + +#define SET_DMA_PSC(x) (((x)&0x3)<<19) /* Peripheral Setup Cycles */ +#define DMA_PSC_MASK SET_DMA_PSC(3) +#define GET_DMA_PSC(x) (((x)&DMA_PSC_MASK)>>19) + +#define SET_DMA_PWC(x) (((x)&0x3F)<<13) /* Peripheral Wait Cycles */ +#define DMA_PWC_MASK SET_DMA_PWC(0x3F) +#define GET_DMA_PWC(x) (((x)&DMA_PWC_MASK)>>13) + +#define SET_DMA_PHC(x) (((x)&0x7)<<10) /* Peripheral Hold Cycles */ +#define DMA_PHC_MASK SET_DMA_PHC(0x7) +#define GET_DMA_PHC(x) (((x)&DMA_PHC_MASK)>>10) + +#define DMA_ETD_OUTPUT (1<<9) /* EOT pin is a TC output */ +#define SET_DMA_ETD(x) (((x)&0x1)<<9) + +#define DMA_TCE_ENABLE (1<<8) +#define SET_DMA_TCE(x) (((x)&0x1)<<8) + +#define SET_DMA_PRIORITY(x) (((x)&0x3)<<6) /* DMA Channel Priority */ +#define DMA_PRIORITY_MASK SET_DMA_PRIORITY(3) +#define PRIORITY_LOW 0 +#define PRIORITY_MID_LOW 1 +#define PRIORITY_MID_HIGH 2 +#define PRIORITY_HIGH 3 +#define GET_DMA_PRIORITY(x) (((x)&DMA_PRIORITY_MASK)>>6) + +#define SET_DMA_PREFETCH(x) (((x)&0x3)<<4) /* Memory Read Prefetch */ +#define DMA_PREFETCH_MASK SET_DMA_PREFETCH(3) +#define PREFETCH_1 0 /* Prefetch 1 Double Word */ +#define PREFETCH_2 1 +#define PREFETCH_4 2 +#define GET_DMA_PREFETCH(x) (((x)&DMA_PREFETCH_MASK)>>4) + +#define DMA_PCE (1<<3) /* Parity Check Enable */ +#define SET_DMA_PCE(x) (((x)&0x1)<<3) +#define GET_DMA_PCE(x) (((x)&DMA_PCE)>>3) + +#define DMA_DEC (1<<2) /* Address Decrement */ +#define SET_DMA_DEC(x) (((x)&0x1)<<2) +#define GET_DMA_DEC(x) (((x)&DMA_DEC)>>2) + +/* + * DMA SG Command Register + */ +#define SSG0_ENABLE (1<<31) /* Start Scatter Gather */ +#define SSG1_ENABLE (1<<30) +#define SSG2_ENABLE (1<<29) +#define SSG3_ENABLE (1<<28) +#define SSG0_MASK_ENABLE (1<<15) /* Enable writing to SSG0 bit */ +#define SSG1_MASK_ENABLE (1<<14) +#define SSG2_MASK_ENABLE (1<<13) +#define SSG3_MASK_ENABLE (1<<12) + + +/* + * DMA Scatter/Gather Descriptor Bit fields + */ +#define SG_LINK (1<<31) /* Link */ +#define SG_TCI_ENABLE (1<<29) /* Enable Terminal Count Interrupt */ +#define SG_ETI_ENABLE (1<<28) /* Enable End of Transfer Interrupt */ +#define SG_ERI_ENABLE (1<<27) /* Enable Error Interrupt */ +#define SG_COUNT_MASK 0xFFFF /* Count Field */ + + + + +typedef uint32_t sgl_handle_t; + +typedef struct { + + /* + * Valid polarity settings: + * DMAReq0_ActiveLow + * DMAAck0_ActiveLow + * EOT0_ActiveLow + * + * DMAReq1_ActiveLow + * DMAAck1_ActiveLow + * EOT1_ActiveLow + * + * DMAReq2_ActiveLow + * DMAAck2_ActiveLow + * EOT2_ActiveLow + * + * DMAReq3_ActiveLow + * DMAAck3_ActiveLow + * EOT3_ActiveLow + */ + unsigned int polarity; + + char buffer_enable; /* Boolean: buffer enable */ + char tce_enable; /* Boolean: terminal count enable */ + char etd_output; /* Boolean: eot pin is a tc output */ + char pce; /* Boolean: parity check enable */ + + /* + * Peripheral location: + * INTERNAL_PERIPHERAL (UART0 on the 405GP) + * EXTERNAL_PERIPHERAL + */ + char pl; /* internal/external peripheral */ + + /* + * Valid pwidth settings: + * PW_8 + * PW_16 + * PW_32 + * PW_64 + */ + unsigned int pwidth; + + char dai; /* Boolean: dst address increment */ + char sai; /* Boolean: src address increment */ + + /* + * Valid psc settings: 0-3 + */ + unsigned int psc; /* Peripheral Setup Cycles */ + + /* + * Valid pwc settings: + * 0-63 + */ + unsigned int pwc; /* Peripheral Wait Cycles */ + + /* + * Valid phc settings: + * 0-7 + */ + unsigned int phc; /* Peripheral Hold Cycles */ + + /* + * Valid cp (channel priority) settings: + * PRIORITY_LOW + * PRIORITY_MID_LOW + * PRIORITY_MID_HIGH + * PRIORITY_HIGH + */ + unsigned int cp; /* channel priority */ + + /* + * Valid pf (memory read prefetch) settings: + * + * PREFETCH_1 + * PREFETCH_2 + * PREFETCH_4 + */ + unsigned int pf; /* memory read prefetch */ + + /* + * Boolean: channel interrupt enable + * NOTE: for sgl transfers, only the last descriptor will be setup to + * interrupt. + */ + char int_enable; + + char shift; /* easy access to byte_count shift, based on */ + /* the width of the channel */ + + uint32_t control; /* channel control word */ + + + /* These variabled are used ONLY in single dma transfers */ + unsigned int mode; /* transfer mode */ + dma_addr_t addr; + +} ppc_dma_ch_t; + + +typedef struct { + uint32_t control; + uint32_t src_addr; + uint32_t dst_addr; + uint32_t control_count; + uint32_t next; +} ppc_sgl_t; + + + +typedef struct { + unsigned int dmanr; + uint32_t control; /* channel ctrl word; loaded from each descrptr */ + uint32_t sgl_control; /* LK, TCI, ETI, and ERI bits in sgl descriptor */ + dma_addr_t dma_addr; /* dma (physical) address of this list */ + ppc_sgl_t *phead; + ppc_sgl_t *ptail; + +} sgl_list_info_t; + + +typedef struct { + unsigned int *src_addr; + unsigned int *dst_addr; + dma_addr_t dma_src_addr; + dma_addr_t dma_dst_addr; +} pci_alloc_desc_t; + + +extern ppc_dma_ch_t dma_channels[]; + +/* + * + * DMA API inline functions + * These functions are implemented here as inline functions for + * performance reasons. + * + */ + +static __inline__ int get_405gp_dma_status(void) +{ + return (mfdcr(DCRN_DMASR)); +} + + +static __inline__ int enable_405gp_dma(unsigned int dmanr) +{ + unsigned int control; + ppc_dma_ch_t *p_dma_ch = &dma_channels[dmanr]; + +#ifdef DEBUG_405DMA + if (dmanr >= MAX_405GP_DMA_CHANNELS) { + printk("enable_dma: bad channel: %d\n", dmanr); + return DMA_STATUS_BAD_CHANNEL; + } +#endif + + + switch (dmanr) { + case 0: + if (p_dma_ch->mode == DMA_MODE_READ) { + /* peripheral to memory */ + mtdcr(DCRN_DMASA0, NULL); + mtdcr(DCRN_DMADA0, p_dma_ch->addr); + } + else if (p_dma_ch->mode == DMA_MODE_WRITE) { + /* memory to peripheral */ + mtdcr(DCRN_DMASA0, p_dma_ch->addr); + mtdcr(DCRN_DMADA0, NULL); + } + /* for other xfer modes, the addresses are already set */ + control = mfdcr(DCRN_DMACR0); + control &= ~(DMA_TM_MASK | DMA_TD); /* clear all mode bits */ + control |= (p_dma_ch->mode | DMA_CH_ENABLE); + mtdcr(DCRN_DMACR0, control); + break; + case 1: + if (p_dma_ch->mode == DMA_MODE_READ) { + mtdcr(DCRN_DMASA1, NULL); + mtdcr(DCRN_DMADA1, p_dma_ch->addr); + } else if (p_dma_ch->mode == DMA_MODE_WRITE) { + mtdcr(DCRN_DMASA1, p_dma_ch->addr); + mtdcr(DCRN_DMADA1, NULL); + } + control = mfdcr(DCRN_DMACR1); + control &= ~(DMA_TM_MASK | DMA_TD); + control |= (p_dma_ch->mode | DMA_CH_ENABLE); + mtdcr(DCRN_DMACR1, control); + break; + case 2: + if (p_dma_ch->mode == DMA_MODE_READ) { + mtdcr(DCRN_DMASA2, NULL); + mtdcr(DCRN_DMADA2, p_dma_ch->addr); + } else if (p_dma_ch->mode == DMA_MODE_WRITE) { + mtdcr(DCRN_DMASA2, p_dma_ch->addr); + mtdcr(DCRN_DMADA2, NULL); + } + control = mfdcr(DCRN_DMACR2); + control &= ~(DMA_TM_MASK | DMA_TD); + control |= (p_dma_ch->mode | DMA_CH_ENABLE); + mtdcr(DCRN_DMACR2, control); + break; + case 3: + if (p_dma_ch->mode == DMA_MODE_READ) { + mtdcr(DCRN_DMASA3, NULL); + mtdcr(DCRN_DMADA3, p_dma_ch->addr); + } else if (p_dma_ch->mode == DMA_MODE_WRITE) { + mtdcr(DCRN_DMASA3, p_dma_ch->addr); + mtdcr(DCRN_DMADA3, NULL); + } + control = mfdcr(DCRN_DMACR3); + control &= ~(DMA_TM_MASK | DMA_TD); + control |= (p_dma_ch->mode | DMA_CH_ENABLE); + mtdcr(DCRN_DMACR3, control); + break; + default: + return DMA_STATUS_BAD_CHANNEL; + } + return DMA_STATUS_GOOD; +} + + + +static __inline__ void disable_405gp_dma(unsigned int dmanr) +{ + unsigned int control; + + switch (dmanr) { + case 0: + control = mfdcr(DCRN_DMACR0); + control &= ~DMA_CH_ENABLE; + mtdcr(DCRN_DMACR0, control); + break; + case 1: + control = mfdcr(DCRN_DMACR1); + control &= ~DMA_CH_ENABLE; + mtdcr(DCRN_DMACR1, control); + break; + case 2: + control = mfdcr(DCRN_DMACR2); + control &= ~DMA_CH_ENABLE; + mtdcr(DCRN_DMACR2, control); + break; + case 3: + control = mfdcr(DCRN_DMACR3); + control &= ~DMA_CH_ENABLE; + mtdcr(DCRN_DMACR3, control); + break; + default: +#ifdef DEBUG_405DMA + printk("disable_dma: bad channel: %d\n", dmanr); +#endif + } +} + + + +/* + * Sets the dma mode for single DMA transfers only. + * For scatter/gather transfers, the mode is passed to the + * alloc_dma_handle() function as one of the parameters. + * + * The mode is simply saved and used later. This allows + * the driver to call set_dma_mode() and set_dma_addr() in + * any order. + * + * Valid mode values are: + * + * DMA_MODE_READ peripheral to memory + * DMA_MODE_WRITE memory to peripheral + * DMA_MODE_MM memory to memory + * DMA_MODE_MM_DEVATSRC device-paced memory to memory, device at src + * DMA_MODE_MM_DEVATDST device-paced memory to memory, device at dst + */ +static __inline__ int set_405gp_dma_mode(unsigned int dmanr, unsigned int mode) +{ + ppc_dma_ch_t *p_dma_ch = &dma_channels[dmanr]; + +#ifdef DEBUG_405DMA + switch (mode) { + case DMA_MODE_READ: + case DMA_MODE_WRITE: + case DMA_MODE_MM: + case DMA_MODE_MM_DEVATSRC: + case DMA_MODE_MM_DEVATDST: + break; + default: + printk("set_dma_mode: bad mode 0x%x\n", mode); + return DMA_STATUS_BAD_MODE; + } + if (dmanr >= MAX_405GP_DMA_CHANNELS) { + printk("set_dma_mode: bad channel 0x%x\n", dmanr); + return DMA_STATUS_BAD_CHANNEL; + } +#endif + + p_dma_ch->mode = mode; + return DMA_STATUS_GOOD; +} + + + +/* + * Sets the DMA Count register. Note that 'count' is in bytes. + * However, the DMA Count register counts the number of "transfers", + * where each transfer is equal to the bus width. Thus, count + * MUST be a multiple of the bus width. + */ +static __inline__ void +set_405gp_dma_count(unsigned int dmanr, unsigned int count) +{ + ppc_dma_ch_t *p_dma_ch = &dma_channels[dmanr]; + +#ifdef DEBUG_405DMA + { + int error = 0; + switch(p_dma_ch->pwidth) { + case PW_8: + break; + case PW_16: + if (count & 0x1) + error = 1; + break; + case PW_32: + if (count & 0x3) + error = 1; + break; + case PW_64: + if (count & 0x7) + error = 1; + break; + default: + printk("set_dma_count: invalid bus width: 0x%x\n", + p_dma_ch->pwidth); + return; + } + if (error) + printk("Warning: set_dma_count count 0x%x bus width %d\n", + count, p_dma_ch->pwidth); + } +#endif + + count = count >> p_dma_ch->shift; + switch (dmanr) { + case 0: + mtdcr(DCRN_DMACT0, count); + break; + case 1: + mtdcr(DCRN_DMACT1, count); + break; + case 2: + mtdcr(DCRN_DMACT2, count); + break; + case 3: + mtdcr(DCRN_DMACT3, count); + break; + default: +#ifdef DEBUG_405DMA + printk("set_dma_count: bad channel: %d\n", dmanr); +#endif + } +} + + + +/* + * Returns the number of bytes left to be transfered. + * After a DMA transfer, this should return zero. + * Reading this while a DMA transfer is still in progress will return + * unpredictable results. + */ +static __inline__ int get_405gp_dma_residue(unsigned int dmanr) +{ + unsigned int count; + ppc_dma_ch_t *p_dma_ch = &dma_channels[dmanr]; + + switch (dmanr) { + case 0: + count = mfdcr(DCRN_DMACT0); + break; + case 1: + count = mfdcr(DCRN_DMACT1); + break; + case 2: + count = mfdcr(DCRN_DMACT2); + break; + case 3: + count = mfdcr(DCRN_DMACT3); + break; + default: +#ifdef DEBUG_405DMA + printk("get_dma_residue: bad channel: %d\n", dmanr); +#endif + return 0; + } + + return (count << p_dma_ch->shift); +} + + + +/* + * Sets the DMA address for a memory to peripheral or peripheral + * to memory transfer. The address is just saved in the channel + * structure for now and used later in enable_dma(). + */ +static __inline__ void set_405gp_dma_addr(unsigned int dmanr, dma_addr_t addr) +{ + ppc_dma_ch_t *p_dma_ch = &dma_channels[dmanr]; +#ifdef DEBUG_405DMA + { + int error = 0; + switch(p_dma_ch->pwidth) { + case PW_8: + break; + case PW_16: + if ((unsigned)addr & 0x1) + error = 1; + break; + case PW_32: + if ((unsigned)addr & 0x3) + error = 1; + break; + case PW_64: + if ((unsigned)addr & 0x7) + error = 1; + break; + default: + printk("set_dma_addr: invalid bus width: 0x%x\n", + p_dma_ch->pwidth); + return; + } + if (error) + printk("Warning: set_dma_addr addr 0x%x bus width %d\n", + addr, p_dma_ch->pwidth); + } +#endif + + /* save dma address and program it later after we know the xfer mode */ + p_dma_ch->addr = addr; +} + + + + +/* + * Sets both DMA addresses for a memory to memory transfer. + * For memory to peripheral or peripheral to memory transfers + * the function set_dma_addr() should be used instead. + */ +static __inline__ void +set_405gp_dma_addr2(unsigned int dmanr, dma_addr_t src_dma_addr, + dma_addr_t dst_dma_addr) +{ +#ifdef DEBUG_405DMA + { + ppc_dma_ch_t *p_dma_ch = &dma_channels[dmanr]; + int error = 0; + switch(p_dma_ch->pwidth) { + case PW_8: + break; + case PW_16: + if (((unsigned)src_dma_addr & 0x1) || + ((unsigned)dst_dma_addr & 0x1) + ) + error = 1; + break; + case PW_32: + if (((unsigned)src_dma_addr & 0x3) || + ((unsigned)dst_dma_addr & 0x3) + ) + error = 1; + break; + case PW_64: + if (((unsigned)src_dma_addr & 0x7) || + ((unsigned)dst_dma_addr & 0x7) + ) + error = 1; + break; + default: + printk("set_dma_addr2: invalid bus width: 0x%x\n", + p_dma_ch->pwidth); + return; + } + if (error) + printk("Warning: set_dma_addr2 src 0x%x dst 0x%x bus width %d\n", + src_dma_addr, dst_dma_addr, p_dma_ch->pwidth); + } +#endif + + switch (dmanr) { + case 0: + mtdcr(DCRN_DMASA0, src_dma_addr); + mtdcr(DCRN_DMADA0, dst_dma_addr); + break; + case 1: + mtdcr(DCRN_DMASA1, src_dma_addr); + mtdcr(DCRN_DMADA1, dst_dma_addr); + break; + case 2: + mtdcr(DCRN_DMASA2, src_dma_addr); + mtdcr(DCRN_DMADA2, dst_dma_addr); + break; + case 3: + mtdcr(DCRN_DMASA3, src_dma_addr); + mtdcr(DCRN_DMADA3, dst_dma_addr); + break; + default: +#ifdef DEBUG_405DMA + printk("set_dma_addr2: bad channel: %d\n", dmanr); +#endif + } +} + + + +/* + * Enables the channel interrupt. + * + * If performing a scatter/gatter transfer, this function + * MUST be called before calling alloc_dma_handle() and building + * the sgl list. Otherwise, interrupts will not be enabled, if + * they were previously disabled. + */ +static __inline__ int +enable_405gp_dma_interrupt(unsigned int dmanr) +{ + unsigned int control; + ppc_dma_ch_t *p_dma_ch = &dma_channels[dmanr]; + + p_dma_ch->int_enable = TRUE; + switch (dmanr) { + case 0: + control = mfdcr(DCRN_DMACR0); + control|= DMA_CIE_ENABLE; /* Channel Interrupt Enable */ + mtdcr(DCRN_DMACR0, control); + break; + case 1: + control = mfdcr(DCRN_DMACR1); + control|= DMA_CIE_ENABLE; + mtdcr(DCRN_DMACR1, control); + break; + case 2: + control = mfdcr(DCRN_DMACR2); + control|= DMA_CIE_ENABLE; + mtdcr(DCRN_DMACR2, control); + break; + case 3: + control = mfdcr(DCRN_DMACR3); + control|= DMA_CIE_ENABLE; + mtdcr(DCRN_DMACR3, control); + break; + default: +#ifdef DEBUG_405DMA + printk("enable_dma_interrupt: bad channel: %d\n", dmanr); +#endif + return DMA_STATUS_BAD_CHANNEL; + } + return DMA_STATUS_GOOD; +} + + + +/* + * Disables the channel interrupt. + * + * If performing a scatter/gatter transfer, this function + * MUST be called before calling alloc_dma_handle() and building + * the sgl list. Otherwise, interrupts will not be disabled, if + * they were previously enabled. + */ +static __inline__ int +disable_405gp_dma_interrupt(unsigned int dmanr) +{ + unsigned int control; + ppc_dma_ch_t *p_dma_ch = &dma_channels[dmanr]; + + p_dma_ch->int_enable = TRUE; + switch (dmanr) { + case 0: + control = mfdcr(DCRN_DMACR0); + control &= ~DMA_CIE_ENABLE; /* Channel Interrupt Enable */ + mtdcr(DCRN_DMACR0, control); + break; + case 1: + control = mfdcr(DCRN_DMACR1); + control &= ~DMA_CIE_ENABLE; + mtdcr(DCRN_DMACR1, control); + break; + case 2: + control = mfdcr(DCRN_DMACR2); + control &= ~DMA_CIE_ENABLE; + mtdcr(DCRN_DMACR2, control); + break; + case 3: + control = mfdcr(DCRN_DMACR3); + control &= ~DMA_CIE_ENABLE; + mtdcr(DCRN_DMACR3, control); + break; + default: +#ifdef DEBUG_405DMA + printk("enable_dma_interrupt: bad channel: %d\n", dmanr); +#endif + return DMA_STATUS_BAD_CHANNEL; + } + return DMA_STATUS_GOOD; +} + + +#ifdef DCRNCAP_DMA_SG + +/* + * Add a new sgl descriptor to the end of a scatter/gather list + * which was created by alloc_dma_handle(). + * + * For a memory to memory transfer, both dma addresses must be + * valid. For a peripheral to memory transfer, one of the addresses + * must be set to NULL, depending on the direction of the transfer: + * memory to peripheral: set dst_addr to NULL, + * peripheral to memory: set src_addr to NULL. + */ +static __inline__ int +add_405gp_dma_sgl(sgl_handle_t handle, dma_addr_t src_addr, dma_addr_t dst_addr, + unsigned int count) +{ + sgl_list_info_t *psgl = (sgl_list_info_t *)handle; + ppc_dma_ch_t *p_dma_ch; + + if (!handle) { +#ifdef DEBUG_405DMA + printk("add_dma_sgl: null handle\n"); +#endif + return DMA_STATUS_BAD_HANDLE; + } + +#ifdef DEBUG_405DMA + if (psgl->dmanr >= MAX_405GP_DMA_CHANNELS) { + printk("add_dma_sgl error: psgl->dmanr == %d\n", psgl->dmanr); + return DMA_STATUS_BAD_CHANNEL; + } +#endif + + p_dma_ch = &dma_channels[psgl->dmanr]; + +#ifdef DEBUG_405DMA + { + int error = 0; + unsigned int aligned = (unsigned)src_addr | (unsigned)dst_addr | count; + switch(p_dma_ch->pwidth) { + case PW_8: + break; + case PW_16: + if (aligned & 0x1) + error = 1; + break; + case PW_32: + if (aligned & 0x3) + error = 1; + break; + case PW_64: + if (aligned & 0x7) + error = 1; + break; + default: + printk("add_dma_sgl: invalid bus width: 0x%x\n", + p_dma_ch->pwidth); + return DMA_STATUS_GENERAL_ERROR; + } + if (error) + printk("Alignment warning: add_dma_sgl src 0x%x dst 0x%x count 0x%x bus width var %d\n", + src_addr, dst_addr, count, p_dma_ch->pwidth); + + } +#endif + + if ((unsigned)(psgl->ptail + 1) >= ((unsigned)psgl + SGL_LIST_SIZE)) { +#ifdef DEBUG_405DMA + printk("sgl handle out of memory \n"); +#endif + return DMA_STATUS_OUT_OF_MEMORY; + } + + + if (!psgl->ptail) { + psgl->phead = (ppc_sgl_t *) + ((unsigned)psgl + sizeof(sgl_list_info_t)); + psgl->ptail = psgl->phead; + } else { + psgl->ptail->next = virt_to_bus(psgl->ptail + 1); + psgl->ptail++; + } + + psgl->ptail->control = psgl->control; + psgl->ptail->src_addr = src_addr; + psgl->ptail->dst_addr = dst_addr; + psgl->ptail->control_count = (count >> p_dma_ch->shift) | + psgl->sgl_control; + psgl->ptail->next = (uint32_t)NULL; + + return DMA_STATUS_GOOD; +} + + + +/* + * Enable (start) the DMA described by the sgl handle. + */ +static __inline__ void enable_405gp_dma_sgl(sgl_handle_t handle) +{ + sgl_list_info_t *psgl = (sgl_list_info_t *)handle; + ppc_dma_ch_t *p_dma_ch; + uint32_t sg_command; + +#ifdef DEBUG_405DMA + if (!handle) { + printk("enable_dma_sgl: null handle\n"); + return; + } else if (psgl->dmanr > (MAX_405GP_DMA_CHANNELS - 1)) { + printk("enable_dma_sgl: bad channel in handle %d\n", + psgl->dmanr); + return; + } else if (!psgl->phead) { + printk("enable_dma_sgl: sg list empty\n"); + return; + } +#endif + + p_dma_ch = &dma_channels[psgl->dmanr]; + psgl->ptail->control_count &= ~SG_LINK; /* make this the last dscrptr */ + sg_command = mfdcr(DCRN_ASGC); + + switch(psgl->dmanr) { + case 0: + mtdcr(DCRN_ASG0, virt_to_bus(psgl->phead)); + sg_command |= SSG0_ENABLE; + break; + case 1: + mtdcr(DCRN_ASG1, virt_to_bus(psgl->phead)); + sg_command |= SSG1_ENABLE; + break; + case 2: + mtdcr(DCRN_ASG2, virt_to_bus(psgl->phead)); + sg_command |= SSG2_ENABLE; + break; + case 3: + mtdcr(DCRN_ASG3, virt_to_bus(psgl->phead)); + sg_command |= SSG3_ENABLE; + break; + default: +#ifdef DEBUG_405DMA + printk("enable_dma_sgl: bad channel: %d\n", psgl->dmanr); +#endif + } + +#if 0 /* debug */ + printk("\n\nenable_dma_sgl at dma_addr 0x%x\n", + virt_to_bus(psgl->phead)); + { + ppc_sgl_t *pnext, *sgl_addr; + + pnext = psgl->phead; + while (pnext) { + printk("dma descriptor at 0x%x, dma addr 0x%x\n", + (unsigned)pnext, (unsigned)virt_to_bus(pnext)); + printk("control 0x%x src 0x%x dst 0x%x c_count 0x%x, next 0x%x\n", + (unsigned)pnext->control, (unsigned)pnext->src_addr, + (unsigned)pnext->dst_addr, + (unsigned)pnext->control_count, (unsigned)pnext->next); + + (unsigned)pnext = bus_to_virt(pnext->next); + } + printk("sg_command 0x%x\n", sg_command); + } +#endif + +#ifdef PCI_ALLOC_IS_NONCONSISTENT + /* + * This is temporary only, until pci_alloc_consistent() really does + * return "consistent" memory. + */ + flush_dcache_range((unsigned)handle, (unsigned)handle + SGL_LIST_SIZE); +#endif + + mtdcr(DCRN_ASGC, sg_command); /* start transfer */ +} + + + +/* + * Halt an active scatter/gather DMA operation. + */ +static __inline__ void disable_405gp_dma_sgl(sgl_handle_t handle) +{ + sgl_list_info_t *psgl = (sgl_list_info_t *)handle; + uint32_t sg_command; + +#ifdef DEBUG_405DMA + if (!handle) { + printk("enable_dma_sgl: null handle\n"); + return; + } else if (psgl->dmanr > (MAX_405GP_DMA_CHANNELS - 1)) { + printk("enable_dma_sgl: bad channel in handle %d\n", + psgl->dmanr); + return; + } +#endif + sg_command = mfdcr(DCRN_ASGC); + switch(psgl->dmanr) { + case 0: + sg_command &= ~SSG0_ENABLE; + break; + case 1: + sg_command &= ~SSG1_ENABLE; + break; + case 2: + sg_command &= ~SSG2_ENABLE; + break; + case 3: + sg_command &= ~SSG3_ENABLE; + break; + default: +#ifdef DEBUG_405DMA + printk("enable_dma_sgl: bad channel: %d\n", psgl->dmanr); +#endif + } + + mtdcr(DCRN_ASGC, sg_command); /* stop transfer */ +} + + + +/* + * Returns number of bytes left to be transferred from the entire sgl list. + * *src_addr and *dst_addr get set to the source/destination address of + * the sgl descriptor where the DMA stopped. + * + * An sgl transfer must NOT be active when this function is called. + */ +static __inline__ int +get_405gp_dma_sgl_residue(sgl_handle_t handle, dma_addr_t *src_addr, + dma_addr_t *dst_addr) +{ + sgl_list_info_t *psgl = (sgl_list_info_t *)handle; + ppc_dma_ch_t *p_dma_ch; + ppc_sgl_t *pnext, *sgl_addr; + uint32_t count_left; + +#ifdef DEBUG_405DMA + if (!handle) { + printk("get_dma_sgl_residue: null handle\n"); + return DMA_STATUS_BAD_HANDLE; + } else if (psgl->dmanr > (MAX_405GP_DMA_CHANNELS - 1)) { + printk("get_dma_sgl_residue: bad channel in handle %d\n", + psgl->dmanr); + return DMA_STATUS_BAD_CHANNEL; + } +#endif + + switch(psgl->dmanr) { + case 0: + sgl_addr = (ppc_sgl_t *)bus_to_virt(mfdcr(DCRN_ASG0)); + count_left = mfdcr(DCRN_DMACT0); + break; + case 1: + sgl_addr = (ppc_sgl_t *)bus_to_virt(mfdcr(DCRN_ASG1)); + count_left = mfdcr(DCRN_DMACT1); + break; + case 2: + sgl_addr = (ppc_sgl_t *)bus_to_virt(mfdcr(DCRN_ASG2)); + count_left = mfdcr(DCRN_DMACT2); + break; + case 3: + sgl_addr = (ppc_sgl_t *)bus_to_virt(mfdcr(DCRN_ASG3)); + count_left = mfdcr(DCRN_DMACT3); + break; + default: +#ifdef DEBUG_405DMA + printk("get_dma_sgl_residue: bad channel: %d\n", psgl->dmanr); +#endif + goto error; + } + + if (!sgl_addr) { +#ifdef DEBUG_405DMA + printk("get_dma_sgl_residue: sgl addr register is null\n"); +#endif + goto error; + } + + pnext = psgl->phead; + while (pnext && + ((unsigned)pnext < ((unsigned)psgl + SGL_LIST_SIZE) && + (pnext != sgl_addr)) + ) { + pnext = pnext++; + } + + if (pnext == sgl_addr) { /* found the sgl descriptor */ + + *src_addr = pnext->src_addr; + *dst_addr = pnext->dst_addr; + + /* + * Now search the remaining descriptors and add their count. + * We already have the remaining count from this descriptor in + * count_left. + */ + pnext++; + + while ((pnext != psgl->ptail) && + ((unsigned)pnext < ((unsigned)psgl + SGL_LIST_SIZE)) + ) { + count_left += pnext->control_count & SG_COUNT_MASK; + } + + if (pnext != psgl->ptail) { /* should never happen */ +#ifdef DEBUG_405DMA + printk("get_dma_sgl_residue error (1) psgl->ptail 0x%x handle 0x%x\n", + (unsigned int)psgl->ptail, + (unsigned int)handle); +#endif + goto error; + } + + /* success */ + p_dma_ch = &dma_channels[psgl->dmanr]; + return (count_left << p_dma_ch->shift); /* count in bytes */ + + } else { + /* this shouldn't happen */ +#ifdef DEBUG_405DMA + printk("get_dma_sgl_residue, unable to match current address 0x%x, handle 0x%x\n", + (unsigned int)sgl_addr, (unsigned int)handle); + +#endif + } + + +error: + *src_addr = (dma_addr_t)NULL; + *dst_addr = (dma_addr_t)NULL; + return 0; +} + + + + +/* + * Returns the address(es) of the buffer(s) contained in the head element of + * the scatter/gather list. The element is removed from the scatter/gather + * list and the next element becomes the head. + * + * This function should only be called when the DMA is not active. + */ +static __inline__ int +delete_405gp_dma_sgl_element(sgl_handle_t handle, dma_addr_t *src_dma_addr, + dma_addr_t *dst_dma_addr) +{ + sgl_list_info_t *psgl = (sgl_list_info_t *)handle; + +#ifdef DEBUG_405DMA + if (!handle) { + printk("delete_sgl_element: null handle\n"); + return DMA_STATUS_BAD_HANDLE; + } else if (psgl->dmanr > (MAX_405GP_DMA_CHANNELS - 1)) { + printk("delete_sgl_element: bad channel in handle %d\n", + psgl->dmanr); + return DMA_STATUS_BAD_CHANNEL; + } +#endif + + if (!psgl->phead) { +#ifdef DEBUG_405DMA + printk("delete_sgl_element: sgl list empty\n"); +#endif + *src_dma_addr = (dma_addr_t)NULL; + *dst_dma_addr = (dma_addr_t)NULL; + return DMA_STATUS_SGL_LIST_EMPTY; + } + + *src_dma_addr = (dma_addr_t)psgl->phead->src_addr; + *dst_dma_addr = (dma_addr_t)psgl->phead->dst_addr; + + if (psgl->phead == psgl->ptail) { + /* last descriptor on the list */ + psgl->phead = NULL; + psgl->ptail = NULL; + } else { + psgl->phead++; + } + + return DMA_STATUS_GOOD; +} + +#endif /* DCRNCAP_DMA_SG */ + +/* + * The rest of the DMA API, in ppc405_dma.c + */ +extern int hw_init_dma_channel(unsigned int, ppc_dma_ch_t *); +extern int get_channel_config(unsigned int, ppc_dma_ch_t *); +extern int set_channel_priority(unsigned int, unsigned int); +extern unsigned int get_peripheral_width(unsigned int); +extern int alloc_dma_handle(sgl_handle_t *, unsigned int, unsigned int); +extern void free_dma_handle(sgl_handle_t); + +#endif +#endif /* __KERNEL__ */ diff --git a/include/asm-ppc/ppc4xx.h b/include/asm-ppc/ppc4xx.h deleted file mode 100644 index b5cbfc203037..000000000000 --- a/include/asm-ppc/ppc4xx.h +++ /dev/null @@ -1,285 +0,0 @@ -/* - * BK Id: SCCS/s.ppc4xx.h 1.3 05/17/01 18:14:25 cort - */ -/* - * - * Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu> - * - * Module name: ppc4xx.h - * - * Description: - * A generic include file which pulls in appropriate include files - * for specific board types based on configuration settings. - * - */ - -#ifdef __KERNEL__ -#ifndef __PPC4XX_H__ -#define __PPC4XX_H__ - -#include <linux/config.h> - -#ifndef __ASSEMBLY__ - -#if defined(CONFIG_OAK) -#include <asm/oak.h> -#endif - -#if defined(CONFIG_WALNUT) -#include <asm/walnut.h> -#endif - -/* IO_BASE is for PCI I/O. - * ISA not supported, just here to resolve copilation. - */ - -#define _IO_BASE 0xe8000000 /* The PCI address window */ -#define _ISA_MEM_BASE 0 -#define PCI_DRAM_OFFSET 0 - -extern unsigned long isa_io_base; - -/* - * The "residual" board information structure the boot loader passes - * into the kernel. - */ -extern unsigned char __res[]; - -/* I don't know if this is general to 4xx, or unique to a specific - * processor or board. In any case it is easy to move. - */ -#define PPC4xx_PCI_IO_ADDR ((uint)0xe8000000) -#define PPC4xx_PCI_IO_SIZE ((uint)64*1024) -#define PPC4xx_PCI_CFG_ADDR ((uint)0xeec00000) -#define PPC4xx_PCI_CFG_SIZE ((uint)4*1024) -#define PPC4xx_PCI_LCFG_ADDR ((uint)0xef400000) -#define PPC4xx_PCI_LCFG_SIZE ((uint)4*1024) -#define PPC4xx_ONB_IO_ADDR ((uint)0xef600000) -#define PPC4xx_ONB_IO_SIZE ((uint)4*1024) - -#endif /* __ASSEMBLY__ */ - -/* Device Control Registers unique to 4xx */ - -#define DCRN_BEAR 0x090 /* Bus Error Address Register */ -#define DCRN_BESR 0x091 /* Bus Error Syndrome Register */ -#define BESR_DSES 0x80000000 /* Data-Side Error Status */ -#define BESR_DMES 0x40000000 /* DMA Error Status */ -#define BESR_RWS 0x20000000 /* Read/Write Status */ -#define BESR_ETMASK 0x1C000000 /* Error Type */ -#define ET_PROT 0 -#define ET_PARITY 1 -#define ET_NCFG 2 -#define ET_BUSERR 4 -#define ET_BUSTO 6 -#define DCRN_CHCR0 0x0B1 /* Chip Control Register 1 */ -#define DCRN_CHCR1 0x0B2 /* Chip Control Register 2 */ -#define DCRN_CHPSR 0x0B4 /* Chip Pin Strapping */ -#define DCRN_CPMER 0x0B9 /* CPM Enable */ -#define DCRN_CPMFR 0x0BA /* CPM Force */ -#define CPM_IIC 0x80000000 /* IIC interface */ -#define CPM_PCI 0x40000000 /* PCI bridge */ -#define CPM_CPU 0x20000000 /* processor core */ -#define CPM_DMA 0x10000000 /* DMA controller */ -#define CPM_BRG 0x08000000 /* PLB to OPB bridge */ -#define CPM_DCP 0x04000000 /* CodePack */ -#define CPM_EBC 0x02000000 /* ROM/SRAM peripheral controller */ -#define CPM_SDRAM 0x01000000 /* SDRAM memory controller */ -#define CPM_PLB 0x00800000 /* PLB bus arbiter */ -#define CPM_GPIO 0x00400000 /* General Purpose IO (??) */ -#define CPM_UART0 0x00200000 /* serial port 0 */ -#define CPM_UART1 0x00100000 /* serial port 1 */ -#define CPM_UIC 0x00080000 /* Universal Interrupt Controller */ -#define CPM_TMRCLK 0x00040000 /* CPU timers */ -#define CPM_EMAC_MM 0x00020000 /* on-chip ethernet MM unit */ -#define CPM_EMAC_RM 0x00010000 /* on-chip ethernet RM unit */ -#define CPM_EMAC_TM 0x00008000 /* on-chip ethernet TM unit */ -#define DCRN_CPMSR 0x0B8 /* CPM Status */ - -#define DCRN_DMACR0 0x100 /* DMA Channel Control Register 0 */ -#define DCRN_DMACT0 0x101 /* DMA Count Register 0 */ -#define DCRN_DMADA0 0x102 /* DMA Destination Address Register 0 */ -#define DCRN_DMASA0 0x103 /* DMA Source Address Register 0 */ -#define DCRN_ASG0 0x104 /* DMA Scatter/Gather Descriptor Addr 0 */ - -#define DCRN_DMACR1 0x108 /* DMA Channel Control Register 1 */ -#define DCRN_DMACT1 0x109 /* DMA Count Register 1 */ -#define DCRN_DMADA1 0x10A /* DMA Destination Address Register 1 */ -#define DCRN_DMASA1 0x10B /* DMA Source Address Register 1 */ -#define DCRN_ASG1 0x10C /* DMA Scatter/Gather Descriptor Addr 1 */ - -#define DCRN_DMACR2 0x110 /* DMA Channel Control Register 2 */ -#define DCRN_DMACT2 0x111 /* DMA Count Register 2 */ -#define DCRN_DMADA2 0x112 /* DMA Destination Address Register 2 */ -#define DCRN_DMASA2 0x113 /* DMA Source Address Register 2 */ -#define DCRN_ASG2 0x114 /* DMA Scatter/Gather Descriptor Addr 2 */ - -#define DCRN_DMACR3 0x118 /* DMA Channel Control Register 3 */ -#define DCRN_DMACT3 0x119 /* DMA Count Register 3 */ -#define DCRN_DMADA3 0x11A /* DMA Destination Address Register 3 */ -#define DCRN_DMASA3 0x11B /* DMA Source Address Register 3 */ -#define DCRN_ASG3 0x11C /* DMA Scatter/Gather Descriptor Addr 3 */ - -#define DCRN_DMASR 0x120 /* DMA Status Register */ -#define DCRN_ASGC 0x123 /* DMA Scatter/Gather Command */ -#define DCRN_ADR 0x124 /* DMA Address Decode */ - -#define DCRN_SLP 0x125 /* DMA Sleep Register */ -#define DCRN_POL 0x126 /* DMA Polarity Register */ - - -#define DCRN_EBCCFGADR 0x012 /* Peripheral Controller Address */ -#define DCRN_EBCCFGDATA 0x013 /* Peripheral Controller Data */ -#define DCRN_EXISR 0x040 /* External Interrupt Status Register */ -#define DCRN_EXIER 0x042 /* External Interrupt Enable Register */ -#define EXIER_CIE 0x80000000 /* Critical Interrupt Enable */ -#define EXIER_SRIE 0x08000000 /* Serial Port Rx Int. Enable */ -#define EXIER_STIE 0x04000000 /* Serial Port Tx Int. Enable */ -#define EXIER_JRIE 0x02000000 /* JTAG Serial Port Rx Int. Enable */ -#define EXIER_JTIE 0x01000000 /* JTAG Serial Port Tx Int. Enable */ -#define EXIER_D0IE 0x00800000 /* DMA Channel 0 Interrupt Enable */ -#define EXIER_D1IE 0x00400000 /* DMA Channel 1 Interrupt Enable */ -#define EXIER_D2IE 0x00200000 /* DMA Channel 2 Interrupt Enable */ -#define EXIER_D3IE 0x00100000 /* DMA Channel 3 Interrupt Enable */ -#define EXIER_E0IE 0x00000010 /* External Interrupt 0 Enable */ -#define EXIER_E1IE 0x00000008 /* External Interrupt 1 Enable */ -#define EXIER_E2IE 0x00000004 /* External Interrupt 2 Enable */ -#define EXIER_E3IE 0x00000002 /* External Interrupt 3 Enable */ -#define EXIER_E4IE 0x00000001 /* External Interrupt 4 Enable */ -#define DCRN_IOCR 0x0A0 /* Input/Output Configuration Register */ -#define IOCR_E0TE 0x80000000 -#define IOCR_E0LP 0x40000000 -#define IOCR_E1TE 0x20000000 -#define IOCR_E1LP 0x10000000 -#define IOCR_E2TE 0x08000000 -#define IOCR_E2LP 0x04000000 -#define IOCR_E3TE 0x02000000 -#define IOCR_E3LP 0x01000000 -#define IOCR_E4TE 0x00800000 -#define IOCR_E4LP 0x00400000 -#define IOCR_EDT 0x00080000 -#define IOCR_SOR 0x00040000 -#define IOCR_EDO 0x00008000 -#define IOCR_2XC 0x00004000 -#define IOCR_ATC 0x00002000 -#define IOCR_SPD 0x00001000 -#define IOCR_BEM 0x00000800 -#define IOCR_PTD 0x00000400 -#define IOCR_ARE 0x00000080 -#define IOCR_DRC 0x00000020 -#define IOCR_RDM(x) (((x) & 0x3) << 3) -#define IOCR_TCS 0x00000004 -#define IOCR_SCS 0x00000002 -#define IOCR_SPC 0x00000001 -#define DCRN_KIAR 0x014 /* Decompression Controller Address */ -#define DCRN_KIDR 0x015 /* Decompression Controller Data */ -#define DCRN_MALCR 0x180 /* MAL Configuration */ -#define MALCR_MMSR 0x80000000 /* MAL Software reset */ -#define MALCR_PLBP_1 0x00400000 /* MAL reqest priority: */ -#define MALCR_PLBP_2 0x00800000 /* lowsest is 00 */ -#define MALCR_PLBP_3 0x00C00000 /* highest */ -#define MALCR_GA 0x00200000 /* Guarded Active Bit */ -#define MALCR_OA 0x00100000 /* Ordered Active Bit */ -#define MALCR_PLBLE 0x00080000 /* PLB Lock Error Bit */ -#define MALCR_PLBLT_1 0x00040000 /* PLB Latency Timer */ -#define MALCR_PLBLT_2 0x00020000 -#define MALCR_PLBLT_3 0x00010000 -#define MALCR_PLBLT_4 0x00008000 -#define MALCR_PLBLT_DEFAULT 0x00078000 /* JSP: Is this a valid default?? */ -#define MALCR_PLBB 0x00004000 /* PLB Burst Deactivation Bit */ -#define MALCR_OPBBL 0x00000080 /* OPB Lock Bit */ -#define MALCR_EOPIE 0x00000004 /* End Of Packet Interrupt Enable */ -#define MALCR_LEA 0x00000002 /* Locked Error Active */ -#define MALCR_MSD 0x00000001 /* MAL Scroll Descriptor Bit */ -#define DCRN_MALDBR 0x183 /* Debug Register */ -#define DCRN_MALESR 0x181 /* Error Status */ -#define MALESR_EVB 0x80000000 /* Error Valid Bit */ -#define MALESR_CID 0x40000000 /* Channel ID Bit for channel 0 */ -#define MALESR_DE 0x00100000 /* Descriptor Error */ -#define MALESR_OEN 0x00080000 /* OPB Non-Fullword Error */ -#define MALESR_OTE 0x00040000 /* OPB Timeout Error */ -#define MALESR_OSE 0x00020000 /* OPB Slave Error */ -#define MALESR_PEIN 0x00010000 /* PLB Bus Error Indication */ -#define MALESR_DEI 0x00000010 /* Descriptor Error Interrupt */ -#define MALESR_ONEI 0x00000008 /* OPB Non-Fullword Error Interrupt */ -#define MALESR_OTEI 0x00000004 /* OPB Timeout Error Interrupt */ -#define MALESR_OSEI 0x00000002 /* OPB Slace Error Interrupt */ -#define MALESR_PBEI 0x00000001 /* PLB Bus Error Interrupt */ -#define DCRN_MALIER 0x182 /* Interrupt Enable */ -#define MALIER_DE 0x00000010 /* Descriptor Error Interrupt Enable */ -#define MALIER_NE 0x00000008 /* OPB Non-word Transfer Int Enable */ -#define MALIER_TE 0x00000004 /* OPB Time Out Error Interrupt Enable */ -#define MALIER_OPBE 0x00000002 /* OPB Slave Error Interrupt Enable */ -#define MALIER_PLBE 0x00000001 /* PLB Error Interrupt Enable */ -#define DCRN_MALTXCARR 0x185 /* TX Channed Active Reset Register */ -#define DCRN_MALTXCASR 0x184 /* TX Channel Active Set Register */ -#define DCRN_MALTXDEIR 0x187 /* Tx Descriptor Error Interrupt */ -#define DCRN_MALTXEOBISR 0x186 /* Tx End of Buffer Interrupt Status */ -#define MALOBISR_CH0 0x80000000 /* EOB channel 1 bit */ -#define MALOBISR_CH2 0x40000000 /* EOB channel 2 bit */ -#define DCRN_MALRXCARR 0x191 /* RX Channed Active Reset Register */ -#define DCRN_MALRXCASR 0x190 /* RX Channel Active Set Register */ -#define DCRN_MALRXDEIR 0x193 /* Rx Descriptor Error Interrupt */ -#define DCRN_MALRXEOBISR 0x192 /* Rx End of Buffer Interrupt Status */ -#define DCRN_MALRXCTP0R 0x1C0 /* Channel Rx 0 Channel Table Pointer */ -#define DCRN_MALTXCTP0R 0x1A0 /* Channel Tx 0 Channel Table Pointer */ -#define DCRN_MALTXCTP1R 0x1A1 /* Channel Tx 1 Channel Table Pointer */ -#define DCRN_MALRCBS0 0x1E0 /* Channel Rx 0 Channel Buffer Size */ -#define DCRN_MEMCFGADR 0x010 /* Memory Controller Address */ -#define DCRN_MEMCFGDATA 0x011 /* Memory Controller Data */ -#define DCRN_OCMISARC 0x018 /* OCM Instr Side Addr Range Compare */ -#define DCRN_OCMISCR 0x019 /* OCM Instr Side Control */ -#define DCRN_OCMDSARC 0x01A /* OCM Data Side Addr Range Compare */ -#define DCRN_OCMDSCR 0x01B /* OCM Data Side Control */ -#define DCRN_PLB0_ACR 0x087 /* PLB Arbiter Control */ -#define DCRN_PLB0_BEAR 0x086 /* PLB Error Address */ -#define DCRN_PLB0_BESR 0x084 /* PLB Error Status */ -#define DCRN_PLLMR 0x0B0 /* PLL Mode */ -#define DCRN_POB0_BEAR 0x0A2 /* PLB to OPB Error Address */ -#define DCRN_POB0_BESR0 0x0A0 /* PLB to OPB Error Status Register 1 */ -#define DCRN_POB0_BESR1 0x0A4 /* PLB to OPB Error Status Register 1 */ -#define DCRN_UICCR 0x0C3 /* UIC Critical */ -#define DCRN_UICER 0x0C2 /* UIC Enable */ -#define DCRN_UICPR 0x0C4 /* UIC Polarity */ -#define DCRN_UICSR 0x0C0 /* UIC Status */ -#define DCRN_UICTR 0x0C5 /* UIC Triggering */ -#define DCRN_UICMSR 0x0C6 /* UIC Masked Status */ -#define DCRN_UICVR 0x0C7 /* UIC Vector */ -#define DCRN_UICVCR 0x0C8 /* UIC Vector Configuration */ -#define UIC_U0 0x80000000 /* UART0 */ -#define UIC_U1 0x40000000 /* UART1 */ -#define UIC_IIC 0x20000000 /* IIC */ -#define UIC_EM 0x10000000 /* External Master */ -#define UIC_PCI 0x08000000 /* PCI */ -#define UIC_D0 0x04000000 /* DMA Channel 0 */ -#define UIC_D1 0x02000000 /* DMA Channel 1 */ -#define UIC_D2 0x01000000 /* DMA Channel 2 */ -#define UIC_D3 0x00800000 /* DMA Channel 3 */ -#define UIC_EW 0x00400000 /* Ethernet Wake-up */ -#define UIC_MS 0x00200000 /* MAL SERR */ -#define UIC_MTE 0x00100000 /* MAL TX EOB */ -#define UIC_MRE 0x00080000 /* MAL RX EOB */ -#define UIC_MTD 0x00040000 /* MAL TX DE */ -#define UIC_MRD 0x00020000 /* MAL RX DE */ -#define UIC_E 0x00010000 /* Ethernet */ -#define UIC_EPS 0x00008000 /* External PCI SERR */ -#define UIC_EC 0x00004000 /* ECC Correctable Error */ -#define UIC_PPM 0x00002000 /* PCI Power Management */ -/* -** 0x00001000 reserved -** 0x00000800 reserved -** 0x00000400 reserved -** 0x00000200 reserved -** 0x00000100 reserved -** 0x00000080 reserved -*/ -#define UIC_EIR0 0x00000040 /* External IRQ 0 */ -#define UIC_EIR1 0x00000020 /* External IRQ 0 */ -#define UIC_EIR2 0x00000010 /* External IRQ 0 */ -#define UIC_EIR3 0x00000008 /* External IRQ 0 */ -#define UIC_EIR4 0x00000004 /* External IRQ 0 */ -#define UIC_EIR5 0x00000002 /* External IRQ 0 */ -#define UIC_EIR6 0x00000001 /* External IRQ 0 */ - -#endif /* __PPC4XX_H__ */ -#endif /* __KERNEL__ */ diff --git a/arch/ppc/kernel/ppc4xx_pic.h b/include/asm-ppc/ppc4xx_pic.h index ebb63a7f36d4..f572b180a4b8 100644 --- a/arch/ppc/kernel/ppc4xx_pic.h +++ b/include/asm-ppc/ppc4xx_pic.h @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.ppc4xx_pic.h 1.8 06/15/01 13:56:56 paulus + * BK Id: %F% %I% %G% %U% %#% */ /* * @@ -15,7 +15,7 @@ #define __PPC4XX_PIC_H__ #include <linux/config.h> -#include "local_irq.h" +#include <linux/irq.h> /* External Global Variables */ diff --git a/include/asm-ppc/ppc4xx_serial.h b/include/asm-ppc/ppc4xx_serial.h deleted file mode 100644 index 718775c8e47f..000000000000 --- a/include/asm-ppc/ppc4xx_serial.h +++ /dev/null @@ -1,104 +0,0 @@ -/* - * BK Id: SCCS/s.ppc4xx_serial.h 1.3 05/17/01 18:14:25 cort - */ -/* - * Copyright 2000 MontaVista Software Inc. - * PPC405GP modifications - * Author: MontaVista Software, Inc. - * frank_rowand@mvista.com or source@mvista.com - * debbie_chu@mvista.com - * - * Module name: ppc405_serial.h - * - * Description: - * Macros, definitions, and data structures specific to the IBM PowerPC - * 405 on-chip serial port devices. - */ - -#ifdef __KERNEL__ -#ifndef __ASMPPC_PPC4xx_SERIAL_H -#define __ASMPPC_PPC4xx_SERIAL_H - -#include <linux/config.h> - -#ifdef CONFIG_SERIAL_MANY_PORTS -#define RS_TABLE_SIZE 64 -#else -#define RS_TABLE_SIZE 4 -#endif - -#define PPC405GP_UART0_INT 0 -#define PPC405GP_UART1_INT 1 - -/* -** 405GP UARTs are *not* PCI devices, so need to specify a non-pci memory -** address and an io_type of SERIAL_IO_MEM. -*/ - -#define PPC405GP_UART0_IO_BASE (u8 *) 0xef600300 -#define PPC405GP_UART1_IO_BASE (u8 *) 0xef600400 - -/* -** - there is no config option for this -** - this name could be more informative -** - also see arch/ppc/kernel/ppc405_serial.c -** -** #define CONFIG_PPC405GP_INTERNAL_CLOCK -*/ -#ifdef CONFIG_PPC405GP_INTERNAL_CLOCK -#define BASE_BAUD 201600 -#else -#define BASE_BAUD 691200 -#endif - - -#ifdef CONFIG_SERIAL_DETECT_IRQ -#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ) -#define STD_COM4_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_AUTO_IRQ) -#else -#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST) -#define STD_COM4_FLAGS (ASYNC_BOOT_AUTOCONF) -#endif - - -#ifdef CONFIG_STB03XXX - -#define UART0_IO_BASE 0x40040000 -#define UART0_INT 20 - -#define STD_SERIAL_PORT_DFNS \ - /* ttyS0 */ \ - { 0, BASE_BAUD, 0, UART0_INT, STD_COM_FLAGS, 0, 0, 0, 0, 0, 0, 0, \ - UART0_IO_BASE, 0, 0, 0, {}, {}, {}, SERIAL_IO_MEM, NULL }, - -#elif defined(CONFIG_UART1_DFLT_CONSOLE) - -#define STD_SERIAL_PORT_DFNS \ - /* ttyS1 */ \ - { 0, BASE_BAUD, 0, PPC405GP_UART1_INT, STD_COM_FLAGS, 0, 0, 0, 0, 0, 0, 0, \ - PPC405GP_UART1_IO_BASE, 0, 0, 0, {}, {}, {}, SERIAL_IO_MEM, NULL }, \ - /* ttyS0 */ \ - { 0, BASE_BAUD, 0, PPC405GP_UART0_INT, STD_COM_FLAGS, 0, 0, 0, 0, 0, 0, 0, \ - PPC405GP_UART0_IO_BASE, 0, 0, 0, {}, {}, {}, SERIAL_IO_MEM, NULL }, - -#else - -#define STD_SERIAL_PORT_DFNS \ - /* ttyS0 */ \ - { 0, BASE_BAUD, 0, PPC405GP_UART0_INT, STD_COM_FLAGS, 0, 0, 0, 0, 0, 0, 0, \ - PPC405GP_UART0_IO_BASE, 0, 0, 0, {}, {}, {}, SERIAL_IO_MEM, NULL }, \ - /* ttyS1 */ \ - { 0, BASE_BAUD, 0, PPC405GP_UART1_INT, STD_COM_FLAGS, 0, 0, 0, 0, 0, 0, 0, \ - PPC405GP_UART1_IO_BASE, 0, 0, 0, {}, {}, {}, SERIAL_IO_MEM, NULL }, - -#endif - - -#define SERIAL_PORT_DFNS \ - STD_SERIAL_PORT_DFNS \ - {} - - - -#endif /* __ASMPPC_PPC4xx_SERIAL_H */ -#endif /* __KERNEL__ */ diff --git a/arch/ppc/kernel/ppc_asm.h b/include/asm-ppc/ppc_asm.h index ea28f75d9acc..d80c6ea8081a 100644 --- a/arch/ppc/kernel/ppc_asm.h +++ b/include/asm-ppc/ppc_asm.h @@ -1,8 +1,8 @@ /* - * BK Id: SCCS/s.ppc_asm.h 1.18 10/18/01 15:02:09 trini + * BK Id: %F% %I% %G% %U% %#% */ /* - * arch/ppc/kernel/ppc_asm.h + * include/asm-ppc/ppc_asm.h * * Definitions used by various bits of low-level assembly code on PowerPC. * @@ -16,9 +16,6 @@ #include <linux/config.h> -#include "ppc_asm.tmpl" -#include "ppc_defs.h" - /* * Macros for storing registers into and loading registers from * exception frames. @@ -117,6 +114,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_601) bdnz 0b #endif +#ifndef CONFIG_PPC_ISERIES /* * On APUS (Amiga PowerPC cpu upgrade board), we don't know the * physical base address of RAM at compile time. @@ -134,6 +132,20 @@ END_FTR_SECTION_IFCLR(CPU_FTR_601) .align 1; \ .long 0b; \ .previous +#else /* CONFIG_PPC_ISERIES */ + +#define tophys(rd,rs) \ + mr rd,rs + +#define tovirt(rd,rs) \ + mr rd,rs + +/* Macros to adjust thread priority for iSeries hardware multi-threading */ +#define HMT_LOW or 1,1,1 +#define HMT_MEDIUM or 2,2,2 +#define HMT_HIGH or 3,3,3 + +#endif /* CONFIG_PPC_ISERIES */ /* * On 64-bit cpus, we use the rfid instruction instead of rfi, but @@ -156,3 +168,146 @@ END_FTR_SECTION_IFCLR(CPU_FTR_601) #define MTMSRD(r) mtmsr r #define CLR_TOP32(r) #endif /* CONFIG_PPC64BRIDGE */ + +#ifdef CONFIG_PPC_ISERIES +#define HMT_LOW or 1,1,1 +#define HMT_MEDIUM or 2,2,2 +#define HMT_HIGH or 3,3,3 +#else /* CONFIG_PPC_ISERIES */ +#define HMT_LOW /* nothing */ +#define HMT_MEDIUM /* nothing */ +#define HMT_HIGH /* nothing */ + +#endif /* CONFIG_PPC_ISERIES */ + +#ifdef CONFIG_IBM405_ERR77 +#define PPC405_ERR77(ra,rb) dcbt ra, rb; +#define PPC405_ERR77_SYNC sync; +#else +#define PPC405_ERR77(ra,rb) +#define PPC405_ERR77_SYNC +#endif + +/* The boring bits... */ + +/* Condition Register Bit Fields */ + +#define cr0 0 +#define cr1 1 +#define cr2 2 +#define cr3 3 +#define cr4 4 +#define cr5 5 +#define cr6 6 +#define cr7 7 + + +/* General Purpose Registers (GPRs) */ + +#define r0 0 +#define r1 1 +#define r2 2 +#define r3 3 +#define r4 4 +#define r5 5 +#define r6 6 +#define r7 7 +#define r8 8 +#define r9 9 +#define r10 10 +#define r11 11 +#define r12 12 +#define r13 13 +#define r14 14 +#define r15 15 +#define r16 16 +#define r17 17 +#define r18 18 +#define r19 19 +#define r20 20 +#define r21 21 +#define r22 22 +#define r23 23 +#define r24 24 +#define r25 25 +#define r26 26 +#define r27 27 +#define r28 28 +#define r29 29 +#define r30 30 +#define r31 31 + + +/* Floating Point Registers (FPRs) */ + +#define fr0 0 +#define fr1 1 +#define fr2 2 +#define fr3 3 +#define fr4 4 +#define fr5 5 +#define fr6 6 +#define fr7 7 +#define fr8 8 +#define fr9 9 +#define fr10 10 +#define fr11 11 +#define fr12 12 +#define fr13 13 +#define fr14 14 +#define fr15 15 +#define fr16 16 +#define fr17 17 +#define fr18 18 +#define fr19 19 +#define fr20 20 +#define fr21 21 +#define fr22 22 +#define fr23 23 +#define fr24 24 +#define fr25 25 +#define fr26 26 +#define fr27 27 +#define fr28 28 +#define fr29 29 +#define fr30 30 +#define fr31 31 + +#define vr0 0 +#define vr1 1 +#define vr2 2 +#define vr3 3 +#define vr4 4 +#define vr5 5 +#define vr6 6 +#define vr7 7 +#define vr8 8 +#define vr9 9 +#define vr10 10 +#define vr11 11 +#define vr12 12 +#define vr13 13 +#define vr14 14 +#define vr15 15 +#define vr16 16 +#define vr17 17 +#define vr18 18 +#define vr19 19 +#define vr20 20 +#define vr21 21 +#define vr22 22 +#define vr23 23 +#define vr24 24 +#define vr25 25 +#define vr26 26 +#define vr27 27 +#define vr28 28 +#define vr29 29 +#define vr30 30 +#define vr31 31 + +/* some stab codes */ +#define N_FUN 36 +#define N_RSYM 64 +#define N_SLINE 68 +#define N_SO 100 diff --git a/include/asm-ppc/pplus.h b/include/asm-ppc/pplus.h new file mode 100644 index 000000000000..fd2bb02d7af1 --- /dev/null +++ b/include/asm-ppc/pplus.h @@ -0,0 +1,94 @@ +/* + * arch/ppc/kernel/pplus.h + * + * Definitions for Motorola MCG Falcon/Raven & HAWK North Bridge & Memory ctlr. + * + * Author: Mark A. Greer + * mgreer@mvista.com + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#ifndef __ASMPPC_PPLUS_H +#define __ASMPPC_PPLUS_H + +#include <asm/pci-bridge.h> + +/* + * The Falcon/Raven and HAWK have 4 sets of registers: + * 1) PPC Registers which define the mappings from PPC bus to PCI bus, + * etc. + * 2) PCI Registers which define the mappings from PCI bus to PPC bus and the + * MPIC base address. + * 3) MPIC registers + * 4) System Memory Controller (SMC) registers. + */ + +#define PPLUS_RAVEN_VEND_DEV_ID 0x48011057 +#define PPLUS_HAWK_VEND_DEV_ID 0x48031057 + +#define PPLUS_PCI_CONFIG_ADDR_OFF 0x00000cf8 +#define PPLUS_PCI_CONFIG_DATA_OFF 0x00000cfc + +#define PPLUS_MPIC_SIZE 0x00040000U +#define PPLUS_SMC_SIZE 0x00001000U + +/* + * Define PPC register offsets. + */ +#define PPLUS_PPC_XSADD0_OFF 0x40 +#define PPLUS_PPC_XSOFF0_OFF 0x44 +#define PPLUS_PPC_XSADD1_OFF 0x48 +#define PPLUS_PPC_XSOFF1_OFF 0x4c +#define PPLUS_PPC_XSADD2_OFF 0x50 +#define PPLUS_PPC_XSOFF2_OFF 0x54 +#define PPLUS_PPC_XSADD3_OFF 0x58 +#define PPLUS_PPC_XSOFF3_OFF 0x5c + +/* + * Define PCI register offsets. + */ +#define PPLUS_PCI_PSADD0_OFF 0x80 +#define PPLUS_PCI_PSOFF0_OFF 0x84 +#define PPLUS_PCI_PSADD1_OFF 0x88 +#define PPLUS_PCI_PSOFF1_OFF 0x8c +#define PPLUS_PCI_PSADD2_OFF 0x90 +#define PPLUS_PCI_PSOFF2_OFF 0x94 +#define PPLUS_PCI_PSADD3_OFF 0x98 +#define PPLUS_PCI_PSOFF3_OFF 0x9c + +/* + * Define the System Memory Controller (SMC) register offsets. + */ +#define PPLUS_SMC_RAM_A_SIZE_REG_OFF 0x10 +#define PPLUS_SMC_RAM_B_SIZE_REG_OFF 0x11 +#define PPLUS_SMC_RAM_C_SIZE_REG_OFF 0x12 +#define PPLUS_SMC_RAM_D_SIZE_REG_OFF 0x13 +#define PPLUS_SMC_RAM_E_SIZE_REG_OFF 0xc0 /* HAWK Only */ +#define PPLUS_SMC_RAM_F_SIZE_REG_OFF 0xc1 /* HAWK Only */ +#define PPLUS_SMC_RAM_G_SIZE_REG_OFF 0xc2 /* HAWK Only */ +#define PPLUS_SMC_RAM_H_SIZE_REG_OFF 0xc3 /* HAWK Only */ + +#define PPLUS_FALCON_SMC_REG_COUNT 4 +#define PPLUS_HAWK_SMC_REG_COUNT 8 + + + +int pplus_init(struct pci_controller *hose, + uint ppc_reg_base, + ulong processor_pci_mem_start, + ulong processor_pci_mem_end, + ulong processor_pci_io_start, + ulong processor_pci_io_end, + ulong processor_mpic_base); + +unsigned long pplus_get_mem_size(uint smc_base); + +int pplus_mpic_init(unsigned int pci_mem_offset); + +#endif /* __ASMPPC_PPLUS_H */ diff --git a/include/asm-ppc/processor.h b/include/asm-ppc/processor.h index f5b55b80e247..843b81218ed4 100644 --- a/include/asm-ppc/processor.h +++ b/include/asm-ppc/processor.h @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.processor.h 1.31 10/05/01 16:26:22 paulus + * BK Id: %F% %I% %G% %U% %#% */ #ifdef __KERNEL__ #ifndef __ASM_PPC_PROCESSOR_H @@ -136,10 +136,32 @@ #define DBCR_JOI 0x00000002 /* JTAG Serial Outbound Int. Enable */ #define DBCR_JII 0x00000001 /* JTAG Serial Inbound Int. Enable */ #define SPRN_DBCR0 0x3F2 /* Debug Control Register 0 */ -#define SPRN_DBCR1 0x3BD /* Debug Control Register 1 */ -#define SPRN_DBSR 0x3F0 /* Debug Status Register */ -#define DBSR_IC 0x80000000 /* Instruction Completion */ -#define DBSR_TIE 0x10000000 /* Trap Instruction debug Event */ +#define DBCR0_EDM 0x80000000 /* External Debug Mode */ +#define DBCR0_IDM 0x40000000 /* Internal Debug Mode */ +#define DBCR0_RST 0x30000000 /* all the bits in the RST field */ +#define DBCR0_RST_SYSTEM 0x30000000 /* System Reset */ +#define DBCR0_RST_CHIP 0x20000000 /* Chip Reset */ +#define DBCR0_RST_CORE 0x10000000 /* Core Reset */ +#define DBCR0_RST_NONE 0x00000000 /* No Reset */ +#define DBCR0_IC 0x08000000 /* Instruction Completion */ +#define DBCR0_BT 0x04000000 /* Branch Taken */ +#define DBCR0_EDE 0x02000000 /* Exception Debug Event */ +#define DBCR0_TDE 0x01000000 /* TRAP Debug Event */ +#define DBCR0_IA1 0x00800000 /* Instr Addr compare 1 enable */ +#define DBCR0_IA2 0x00400000 /* Instr Addr compare 2 enable */ +#define DBCR0_IA12 0x00200000 /* Instr Addr 1-2 range enable */ +#define DBCR0_IA12X 0x00100000 /* Instr Addr 1-2 range eXclusive */ +#define DBCR0_IA3 0x00080000 /* Instr Addr compare 3 enable */ +#define DBCR0_IA4 0x00040000 /* Instr Addr compare 4 enable */ +#define DBCR0_IA34 0x00020000 /* Instr Addr 3-4 range Enable */ +#define DBCR0_IA34X 0x00010000 /* Instr Addr 3-4 range eXclusive */ +#define DBCR0_IA12T 0x00008000 /* Instr Addr 1-2 range Toggle */ +#define DBCR0_IA34T 0x00004000 /* Instr Addr 3-4 range Toggle */ +#define DBCR0_FT 0x00000001 /* Freeze Timers on debug event */ +#define SPRN_DBCR1 0x3BD /* Debug Control Register 1 */ +#define SPRN_DBSR 0x3F0 /* Debug Status Register */ +#define DBSR_IC 0x80000000 /* Instruction Completion */ +#define DBSR_TIE 0x10000000 /* Trap Instruction debug Event */ #define SPRN_DCCR 0x3FA /* Data Cache Cacheability Register */ #define DCCR_NOCACHE 0 /* Noncacheable */ #define DCCR_CACHE 1 /* Cacheable */ @@ -191,12 +213,17 @@ #define HID0_EBD (1<<28) /* Enable Bus Data Parity */ #define HID0_SBCLK (1<<27) #define HID0_EICE (1<<26) +#define HID0_TBEN (1<<26) /* Timebase enable - 7450 */ #define HID0_ECLK (1<<25) #define HID0_PAR (1<<24) +#define HID0_STEN (1<<24) /* S/W Tablewalk enable - 7450 */ #define HID0_DOZE (1<<23) #define HID0_NAP (1<<22) #define HID0_SLEEP (1<<21) #define HID0_DPM (1<<20) +#define HID0_BHTCLR (1<<18) /* Clear branch history table - 7450 */ +#define HID0_XAEN (1<<17) /* Extended addressing enable - 7450 */ +#define HID0_NHR (1<<16) /* Not hard reset (software bit-7450)*/ #define HID0_ICE (1<<15) /* Instruction Cache Enable */ #define HID0_DCE (1<<14) /* Data Cache Enable */ #define HID0_ILOCK (1<<13) /* Instruction Cache Lock */ @@ -207,11 +234,23 @@ #define HID0_SGE (1<<7) /* Store Gathering Enable */ #define HID0_SIED (1<<7) /* Serial Instr. Execution [Disable] */ #define HID0_DFCA (1<<6) /* Data Cache Flush Assist */ -#define HID0_BTIC (1<<5) /* Branch Target Instruction Cache Enable */ +#define HID0_BTIC (1<<5) /* Branch Target Instr Cache Enable */ +#define HID0_LRSTK (1<<4) /* Link Stack enable - 7450 */ #define HID0_ABE (1<<3) /* Address Broadcast Enable */ +#define HID0_FOLD (1<<3) /* Branch Folding enable - 7450 */ #define HID0_BHTE (1<<2) /* Branch History Table Enable */ #define HID0_BTCD (1<<1) /* Branch target cache disable */ +#define HID0_NOPDST (1<<1) /* No-op dst, dstt, etc. instr. */ +#define HID0_NOPTI (1<<0) /* No-op dcbt and dcbst instr. */ + #define SPRN_HID1 0x3F1 /* Hardware Implementation Register 1 */ +#define HID1_EMCP (1<<31) /* 7450 Machine Check Pin Enable */ +#define HID1_PC0 (1<<16) /* 7450 PLL_CFG[0] */ +#define HID1_PC1 (1<<15) /* 7450 PLL_CFG[1] */ +#define HID1_PC2 (1<<14) /* 7450 PLL_CFG[2] */ +#define HID1_PC3 (1<<13) /* 7450 PLL_CFG[3] */ +#define HID1_SYNCBE (1<<11) /* 7450 ABE for sync, eieio */ +#define HID1_ABE (1<<10) /* 7450 Address Broadcast Enable */ #define SPRN_IABR 0x3F2 /* Instruction Address Breakpoint Register */ #define SPRN_IAC1 0x3F4 /* Instruction Address Compare 1 */ #define SPRN_IAC2 0x3F5 /* Instruction Address Compare 2 */ @@ -229,6 +268,10 @@ #define SPRN_ICDBDR 0x3D3 /* Instruction Cache Debug Data Register */ #define SPRN_ICMP 0x3D5 /* Instruction TLB Compare Register */ #define SPRN_ICTC 0x3FB /* Instruction Cache Throttling Control Reg */ +#define SPRN_ICTRL 0x3F3 /* 1011 7450 icache and interrupt ctrl */ +#define ICTRL_EICE 0x08000000 /* enable icache parity errs */ +#define ICTRL_EDCE 0x04000000 /* enable dcache parity errs */ +#define ICTRL_EICP 0x00000100 /* enable icache par. check */ #define SPRN_IMISS 0x3D4 /* Instruction TLB Miss Register */ #define SPRN_IMMR 0x27E /* Internal Memory Map Register */ #define SPRN_L2CR 0x3F9 /* Level 2 Cache Control Regsiter */ @@ -261,6 +304,13 @@ #define L2CR_L2DF 0x00004000 /* L2 differential clock */ #define L2CR_L2BYP 0x00002000 /* L2 DLL bypass */ #define L2CR_L2IP 0x00000001 /* L2 GI in progress */ +#define SPRN_L2CR2 0x3f8 +#define SPRN_L3CR 0x3FA /* Level 3 Cache Control Regsiter (7450) */ +#define L3CR_L3E 0x80000000 /* L3 enable */ +#define SPRN_MSSCR0 0x3f6 /* Memory Subsystem Control Register 0 */ +#define SPRN_MSSSR0 0x3f7 /* Memory Subsystem Status Register 1 */ +#define SPRN_LDSTCR 0x3f8 /* Load/Store control register */ +#define SPRN_LDSTDB 0x3f4 /* */ #define SPRN_LR 0x008 /* Link Register */ #define SPRN_MMCR0 0x3B8 /* Monitor Mode Control Register 0 */ #define SPRN_MMCR1 0x3BC /* Monitor Mode Control Register 1 */ @@ -275,6 +325,8 @@ #define SPRN_PMC2 0x3BA /* Performance Counter Register 2 */ #define SPRN_PMC3 0x3BD /* Performance Counter Register 3 */ #define SPRN_PMC4 0x3BE /* Performance Counter Register 4 */ +#define SPRN_PTEHI 0x3D5 /* 981 7450 PTE HI word (S/W TLB load) */ +#define SPRN_PTELO 0x3D6 /* 982 7450 PTE LO word (S/W TLB load) */ #define SPRN_PVR 0x11F /* Processor Version Register */ #define SPRN_RPA 0x3D6 /* Required Physical Address Register */ #define SPRN_SDA 0x3BF /* Sampled Data Address Register */ @@ -295,17 +347,23 @@ #define SPRN_SRR1 0x01B /* Save/Restore Register 1 */ #define SPRN_SRR2 0x3DE /* Save/Restore Register 2 */ #define SPRN_SRR3 0x3DF /* Save/Restore Register 3 */ +#define SPRN_TBHI 0x3DC /* Time Base High (4xx) */ +#define SPRN_TBHU 0x3CC /* Time Base High User-mode (4xx) */ +#define SPRN_TBLO 0x3DD /* Time Base Low (4xx) */ +#define SPRN_TBLU 0x3CD /* Time Base Low User-mode (4xx) */ #define SPRN_TBRL 0x10C /* Time Base Read Lower Register (user, R/O) */ #define SPRN_TBRU 0x10D /* Time Base Read Upper Register (user, R/O) */ -#define SPRN_TBWL 0x11C /* Time Base Lower Register (supervisor, R/W) */ -#define SPRN_TBWU 0x11D /* Time Base Upper Register (supervisor, R/W) */ +#define SPRN_TBWL 0x11C /* Time Base Lower Register (super, R/W) */ +#define SPRN_TBWU 0x11D /* Time Base Upper Register (super, R/W) */ #define SPRN_TCR 0x3DA /* Timer Control Register */ #define TCR_WP(x) (((x)&0x3)<<30) /* WDT Period */ +#define TCR_WP_MASK TCR_WP(3) #define WP_2_17 0 /* 2^17 clocks */ #define WP_2_21 1 /* 2^21 clocks */ #define WP_2_25 2 /* 2^25 clocks */ #define WP_2_29 3 /* 2^29 clocks */ #define TCR_WRC(x) (((x)&0x3)<<28) /* WDT Reset Control */ +#define TCR_WRC_MASK TCR_WRC(3) #define WRC_NONE 0 /* No reset will occur */ #define WRC_CORE 1 /* Core reset will occur */ #define WRC_CHIP 2 /* Chip reset will occur */ @@ -313,6 +371,7 @@ #define TCR_WIE 0x08000000 /* WDT Interrupt Enable */ #define TCR_PIE 0x04000000 /* PIT Interrupt Enable */ #define TCR_FP(x) (((x)&0x3)<<24) /* FIT Period */ +#define TCR_FP_MASK TCR_FP(3) #define FP_2_9 0 /* 2^9 clocks */ #define FP_2_13 1 /* 2^13 clocks */ #define FP_2_17 2 /* 2^17 clocks */ @@ -331,6 +390,7 @@ #define SPRN_THRM2 0x3FD /* Thermal Management Register 2 */ #define SPRN_THRM3 0x3FE /* Thermal Management Register 3 */ #define THRM3_E (1<<0) +#define SPRN_TLBMISS 0x3D4 /* 980 7450 TLB Miss Register */ #define SPRN_TSR 0x3D8 /* Timer Status Register */ #define TSR_ENW 0x80000000 /* Enable Next Watchdog */ #define TSR_WIS 0x40000000 /* WDT Interrupt Status */ @@ -387,6 +447,7 @@ #define IMISS SPRN_IMISS /* Instruction TLB Miss Register */ #define IMMR SPRN_IMMR /* PPC 860/821 Internal Memory Map Register */ #define L2CR SPRN_L2CR /* PPC 750 L2 control register */ +#define L3CR SPRN_L3CR /* PPC 7450 L3 Cache control register */ #define LR SPRN_LR #define PVR SPRN_PVR /* Processor Version */ #define RPA SPRN_RPA /* Required Physical Address Register */ @@ -445,7 +506,9 @@ #define PVR_403GC 0x00200200 #define PVR_403GCX 0x00201400 #define PVR_405GP 0x40110000 -#define PVR_STB03XXX 0x40310000 +#define PVR_STB03XXX 0x40310000 +#define PVR_NP405H 0x41410000 +#define PVR_NP405L 0x41610000 #define PVR_601 0x00010000 #define PVR_602 0x00050000 #define PVR_603 0x00030000 @@ -462,6 +525,7 @@ #define PVR_750P PVR_740P #define PVR_7400 0x000C0000 #define PVR_7410 0x800C0000 +#define PVR_7450 0x80000000 /* * For the 8xx processors, all of them report the same PVR family for * the PowerPC core. The various versions of these processors must be @@ -473,6 +537,7 @@ #define PVR_850 PVR_821 #define PVR_860 PVR_821 #define PVR_8240 0x00810100 +#define PVR_8245 0x80811014 #define PVR_8260 PVR_8240 /* We only need to define a new _MACH_xxx for machines which are part of @@ -493,7 +558,9 @@ #define _CHRP_Motorola 0x04 /* motorola chrp, the cobra */ #define _CHRP_IBM 0x05 /* IBM chrp, the longtrail and longtrail 2 */ +#define __stringify(a) #a #define _GLOBAL(n)\ + .stabs __stringify(n:F-1),N_FUN,0,0,n;\ .globl n;\ n: @@ -502,11 +569,6 @@ n: #define stringify(s) tostring(s) #define tostring(s) #s -#define mfdcr(rn) ({unsigned int rval; \ - asm volatile("mfdcr %0," stringify(rn) \ - : "=r" (rval)); rval;}) -#define mtdcr(rn, v) asm volatile("mtdcr " stringify(rn) ",%0" : : "r" (v)) - #define mfmsr() ({unsigned int rval; \ asm volatile("mfmsr %0" : "=r" (rval)); rval;}) #define mtmsr(v) asm volatile("mtmsr %0" : : "r" (v)) @@ -516,6 +578,35 @@ n: : "=r" (rval)); rval;}) #define mtspr(rn, v) asm volatile("mtspr " stringify(rn) ",%0" : : "r" (v)) +#define mfsrin(v) ({unsigned int rval; \ + asm volatile("mfsrin %0,%1" : "=r" (rval) : "r" (v)); \ + rval;}) + +#define proc_trap() asm volatile("trap") + +#ifdef CONFIG_PPC_ISERIES +/* Macros for adjusting thread priority (hardware multi-threading) */ +#define HMT_PRIO_LOW "or 1,1,1\n" /* low prio, used for spin loops */ +#define HMT_PRIO_MED "or 2,2,2\n" /* medium prio, for normal code */ +#define HMT_PRIO_HIGH "or 3,3,3\n" /* high priority */ + +#define HMT_low() asm volatile("or 1,1,1") +#define HMT_medium() asm volatile("or 2,2,2") +#define HMT_high() asm volatile("or 3,3,3") + +/* iSeries CTRL register (for runlatch) */ + +#define CTRLT 0x098 +#define CTRLF 0x088 +#define RUNLATCH 0x0001 + +#else /* !CONFIG_PPC_ISERIES */ +#define HMT_PRIO_LOW +#define HMT_PRIO_MED +#define HMT_PRIO_HIGH + +#endif /* CONFIG_PPC_ISERIES */ + /* Segment Registers */ #define SR0 0 @@ -580,7 +671,11 @@ extern struct task_struct *last_task_used_altivec; * as soon as I get around to remapping the io areas with the BATs * to match the mac we can raise this. -- Cort */ +#ifdef CONFIG_TASK_SIZE_BOOL +#define TASK_SIZE CONFIG_TASK_SIZE +#else #define TASK_SIZE (0x80000000UL) +#endif /* This decides where the kernel will search for a free chunk of vm * space during mmap's. @@ -593,10 +688,10 @@ typedef struct { struct thread_struct { unsigned long ksp; /* Kernel stack pointer */ - unsigned long wchan; /* Event task is sleeping on */ struct pt_regs *regs; /* Pointer to saved register state */ mm_segment_t fs; /* for get_fs() validation */ void *pgdir; /* root of page-table tree */ + int fpexc_mode; /* floating-point exception mode */ signed long last_syscall; double fpr[32]; /* Complete floating point set */ unsigned long fpscr_pad; /* fpr ... fpscr must be contiguous */ @@ -611,13 +706,9 @@ struct thread_struct { #define INIT_SP (sizeof(init_stack) + (unsigned long) &init_stack) #define INIT_THREAD { \ - INIT_SP, /* ksp */ \ - 0, /* wchan */ \ - 0, /* regs */ \ - KERNEL_DS, /*fs*/ \ - swapper_pg_dir, /* pgdir */ \ - 0, /* last_syscall */ \ - {0}, 0, 0 \ + ksp: INIT_SP, \ + fs: KERNEL_DS, \ + pgdir: swapper_pg_dir, \ } /* @@ -636,6 +727,22 @@ unsigned long get_wchan(struct task_struct *p); #define KSTK_EIP(tsk) ((tsk)->thread.regs? (tsk)->thread.regs->nip: 0) #define KSTK_ESP(tsk) ((tsk)->thread.regs? (tsk)->thread.regs->gpr[1]: 0) +/* Get/set floating-point exception mode */ +#define GET_FP_EXC_MODE(tsk) __unpack_fe01((tsk)->thread.fpexc_mode) +#define SET_FP_EXC_MODE(tsk, val) set_fpexc_mode((tsk), (val)) + +extern int set_fpexc_mode(struct task_struct *tsk, unsigned int val); + +static inline unsigned int __unpack_fe01(unsigned int msr_bits) +{ + return ((msr_bits & MSR_FE0) >> 10) | ((msr_bits & MSR_FE1) >> 8); +} + +static inline unsigned int __pack_fe01(unsigned int fpmode) +{ + return ((fpmode << 10) & MSR_FE0) | ((fpmode << 8) & MSR_FE1); +} + /* * NOTE! The task struct and the stack go together */ @@ -655,6 +762,8 @@ void ll_puts(const char *); /* In misc.c */ void _nmask_and_or_msr(unsigned long nmask, unsigned long or_val); +#define have_of (_machine == _MACH_chrp || _machine == _MACH_Pmac) + #define cpu_relax() do { } while (0) /* @@ -678,7 +787,5 @@ extern inline void prefetchw(const void *x) #endif /* !__ASSEMBLY__ */ -#define have_of (_machine == _MACH_chrp || _machine == _MACH_Pmac) - #endif /* __ASM_PPC_PROCESSOR_H */ #endif /* __KERNEL__ */ diff --git a/include/asm-ppc/prom.h b/include/asm-ppc/prom.h index c27ff56c059a..99a9980d3cfe 100644 --- a/include/asm-ppc/prom.h +++ b/include/asm-ppc/prom.h @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.prom.h 1.19 08/17/01 15:23:17 paulus + * BK Id: %F% %I% %G% %U% %#% */ /* * Definitions for talking to the Open Firmware PROM on @@ -86,6 +86,10 @@ extern void prom_get_irq_senses(unsigned char *, int, int); extern int prom_n_addr_cells(struct device_node* np); extern int prom_n_size_cells(struct device_node* np); +extern struct resource* +request_OF_resource(struct device_node* node, int index, const char* name_postfix); +extern int release_OF_resource(struct device_node* node, int index); + extern void print_properties(struct device_node *node); extern int call_rtas(const char *service, int nargs, int nret, unsigned long *outputs, ...); @@ -103,10 +107,11 @@ extern int call_rtas(const char *service, int nargs, int nret, * pointer values. See arch/ppc/kernel/prom.c for how these are used. */ extern unsigned long reloc_offset(void); +extern unsigned long add_reloc_offset(unsigned long); +extern unsigned long sub_reloc_offset(unsigned long); -#define PTRRELOC(x) ((typeof(x))((unsigned long)(x) + offset)) -#define PTRUNRELOC(x) ((typeof(x))((unsigned long)(x) - offset)) -#define RELOC(x) (*PTRRELOC(&(x))) +#define PTRRELOC(x) ((typeof(x))add_reloc_offset((unsigned long)(x))) +#define PTRUNRELOC(x) ((typeof(x))sub_reloc_offset((unsigned long)(x))) #endif /* _PPC_PROM_H */ #endif /* __KERNEL__ */ diff --git a/include/asm-ppc/ptrace.h b/include/asm-ppc/ptrace.h index f2eddc88dce7..e8e7aa3d0b99 100644 --- a/include/asm-ppc/ptrace.h +++ b/include/asm-ppc/ptrace.h @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.ptrace.h 1.5 05/17/01 18:14:25 cort + * BK Id: %F% %I% %G% %U% %#% */ #ifndef _PPC_PTRACE_H #define _PPC_PTRACE_H @@ -39,6 +39,9 @@ struct pt_regs { }; #endif +/* iSeries uses mq field for soft enable flag */ +#define softEnable mq + #ifdef __KERNEL__ #define STACK_FRAME_OVERHEAD 16 /* size of minimum stack frame */ @@ -103,5 +106,8 @@ struct pt_regs { #define PT_FPR31 (PT_FPR0 + 2*31) #define PT_FPSCR (PT_FPR0 + 2*32 + 1) -#endif +/* Get/set all the altivec registers vr0..vr31, vscr, vrsave, in one go */ +#define PTRACE_GETVRREGS 18 +#define PTRACE_SETVRREGS 19 +#endif diff --git a/include/asm-ppc/serial.h b/include/asm-ppc/serial.h index f130fba59516..321294003be3 100644 --- a/include/asm-ppc/serial.h +++ b/include/asm-ppc/serial.h @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.serial.h 1.15 10/23/01 08:09:35 trini + * BK Id: %F% %I% %G% %U% %#% */ /* * include/asm-ppc/serial.h @@ -11,130 +11,43 @@ #include <linux/config.h> -#ifdef CONFIG_GEMINI -#include <asm/gemini_serial.h> +#if defined(CONFIG_EV64260) +#include <platforms/ev64260.h> +#elif defined(CONFIG_GEMINI) +#include <platforms/gemini_serial.h> +#elif defined(CONFIG_POWERPMC250) +#include <platforms/powerpmc250_serial.h> +#elif defined(CONFIG_LOPEC) +#include <platforms/lopec_serial.h> +#elif defined(CONFIG_MCPN765) +#include <platforms/mcpn765_serial.h> +#elif defined(CONFIG_MVME5100) +#include <platforms/mvme5100_serial.h> +#elif defined(CONFIG_PRPMC750) +#include <platforms/prpmc750_serial.h> +#elif defined(CONFIG_PRPMC800) +#include <platforms/prpmc800_serial.h> +#elif defined(CONFIG_SANDPOINT) +#include <platforms/sandpoint_serial.h> +#elif defined(CONFIG_SPRUCE) +#include <platforms/spruce_serial.h> +#elif defined(CONFIG_ZX4500) +#include <platforms/zx4500_serial.h> #elif defined(CONFIG_4xx) -#include <asm/ppc4xx_serial.h> +#include <asm/ibm4xx.h> #else /* - * This assumes you have a 1.8432 MHz clock for your UART. - * - * It'd be nice if someone built a serial card with a 24.576 MHz - * clock, since the 16550A is capable of handling a top speed of 1.5 - * megabits/second; but this requires the faster clock. + * XXX Assume for now it has PC-style ISA serial ports. + * This is true for PReP and CHRP at least. */ -#define BASE_BAUD ( 1843200 / 16 ) +#include <asm/pc_serial.h> +#include <asm/processor.h> -#ifdef CONFIG_SERIAL_MANY_PORTS -#define RS_TABLE_SIZE 64 -#else -#define RS_TABLE_SIZE 4 -#endif - -/* Standard COM flags (except for COM4, because of the 8514 problem) */ -#ifdef CONFIG_SERIAL_DETECT_IRQ -#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ) -#define STD_COM4_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_AUTO_IRQ) -#else -#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST) -#define STD_COM4_FLAGS ASYNC_BOOT_AUTOCONF -#endif - -#ifdef CONFIG_SERIAL_MANY_PORTS -#define FOURPORT_FLAGS ASYNC_FOURPORT -#define ACCENT_FLAGS 0 -#define BOCA_FLAGS 0 -#define HUB6_FLAGS 0 -#endif - -/* - * The following define the access methods for the HUB6 card. All - * access is through two ports for all 24 possible chips. The card is - * selected through the high 2 bits, the port on that card with the - * "middle" 3 bits, and the register on that port with the bottom - * 3 bits. - * - * While the access port and interrupt is configurable, the default - * port locations are 0x302 for the port control register, and 0x303 - * for the data read/write register. Normally, the interrupt is at irq3 - * but can be anything from 3 to 7 inclusive. Note that using 3 will - * require disabling com2. - */ - -#define C_P(card,port) (((card)<<6|(port)<<3) + 1) - -#define STD_SERIAL_PORT_DEFNS \ - /* UART CLK PORT IRQ FLAGS */ \ - { 0, BASE_BAUD, 0x3F8, 4, STD_COM_FLAGS }, /* ttyS0 */ \ - { 0, BASE_BAUD, 0x2F8, 3, STD_COM_FLAGS }, /* ttyS1 */ \ - { 0, BASE_BAUD, 0x3E8, 4, STD_COM_FLAGS }, /* ttyS2 */ \ - { 0, BASE_BAUD, 0x2E8, 3, STD_COM4_FLAGS }, /* ttyS3 */ - - -#ifdef CONFIG_SERIAL_MANY_PORTS -#define EXTRA_SERIAL_PORT_DEFNS \ - { 0, BASE_BAUD, 0x1A0, 9, FOURPORT_FLAGS }, /* ttyS4 */ \ - { 0, BASE_BAUD, 0x1A8, 9, FOURPORT_FLAGS }, /* ttyS5 */ \ - { 0, BASE_BAUD, 0x1B0, 9, FOURPORT_FLAGS }, /* ttyS6 */ \ - { 0, BASE_BAUD, 0x1B8, 9, FOURPORT_FLAGS }, /* ttyS7 */ \ - { 0, BASE_BAUD, 0x2A0, 5, FOURPORT_FLAGS }, /* ttyS8 */ \ - { 0, BASE_BAUD, 0x2A8, 5, FOURPORT_FLAGS }, /* ttyS9 */ \ - { 0, BASE_BAUD, 0x2B0, 5, FOURPORT_FLAGS }, /* ttyS10 */ \ - { 0, BASE_BAUD, 0x2B8, 5, FOURPORT_FLAGS }, /* ttyS11 */ \ - { 0, BASE_BAUD, 0x330, 4, ACCENT_FLAGS }, /* ttyS12 */ \ - { 0, BASE_BAUD, 0x338, 4, ACCENT_FLAGS }, /* ttyS13 */ \ - { 0, BASE_BAUD, 0x000, 0, 0 }, /* ttyS14 (spare) */ \ - { 0, BASE_BAUD, 0x000, 0, 0 }, /* ttyS15 (spare) */ \ - { 0, BASE_BAUD, 0x100, 12, BOCA_FLAGS }, /* ttyS16 */ \ - { 0, BASE_BAUD, 0x108, 12, BOCA_FLAGS }, /* ttyS17 */ \ - { 0, BASE_BAUD, 0x110, 12, BOCA_FLAGS }, /* ttyS18 */ \ - { 0, BASE_BAUD, 0x118, 12, BOCA_FLAGS }, /* ttyS19 */ \ - { 0, BASE_BAUD, 0x120, 12, BOCA_FLAGS }, /* ttyS20 */ \ - { 0, BASE_BAUD, 0x128, 12, BOCA_FLAGS }, /* ttyS21 */ \ - { 0, BASE_BAUD, 0x130, 12, BOCA_FLAGS }, /* ttyS22 */ \ - { 0, BASE_BAUD, 0x138, 12, BOCA_FLAGS }, /* ttyS23 */ \ - { 0, BASE_BAUD, 0x140, 12, BOCA_FLAGS }, /* ttyS24 */ \ - { 0, BASE_BAUD, 0x148, 12, BOCA_FLAGS }, /* ttyS25 */ \ - { 0, BASE_BAUD, 0x150, 12, BOCA_FLAGS }, /* ttyS26 */ \ - { 0, BASE_BAUD, 0x158, 12, BOCA_FLAGS }, /* ttyS27 */ \ - { 0, BASE_BAUD, 0x160, 12, BOCA_FLAGS }, /* ttyS28 */ \ - { 0, BASE_BAUD, 0x168, 12, BOCA_FLAGS }, /* ttyS29 */ \ - { 0, BASE_BAUD, 0x170, 12, BOCA_FLAGS }, /* ttyS30 */ \ - { 0, BASE_BAUD, 0x178, 12, BOCA_FLAGS }, /* ttyS31 */ -#else -#define EXTRA_SERIAL_PORT_DEFNS -#endif - -/* You can have up to four HUB6's in the system, but I've only - * included two cards here for a total of twelve ports. - */ -#if (defined(CONFIG_HUB6) && defined(CONFIG_SERIAL_MANY_PORTS)) -#define HUB6_SERIAL_PORT_DFNS \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,0) }, /* ttyS32 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,1) }, /* ttyS33 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,2) }, /* ttyS34 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,3) }, /* ttyS35 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,4) }, /* ttyS36 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,5) }, /* ttyS37 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,0) }, /* ttyS38 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,1) }, /* ttyS39 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,2) }, /* ttyS40 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,3) }, /* ttyS41 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,4) }, /* ttyS42 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,5) }, /* ttyS43 */ -#else -#define HUB6_SERIAL_PORT_DFNS +#if defined(CONFIG_MAC_SERIAL) +#define SERIAL_DEV_OFFSET ((_machine == _MACH_prep || _machine == _MACH_chrp) ? 0 : 2) #endif -#define MCA_SERIAL_PORT_DFNS - -#define SERIAL_PORT_DFNS \ - STD_SERIAL_PORT_DEFNS \ - EXTRA_SERIAL_PORT_DEFNS \ - HUB6_SERIAL_PORT_DFNS \ - MCA_SERIAL_PORT_DFNS - #endif /* !CONFIG_GEMINI and others */ #endif /* __ASM_SERIAL_H__ */ #endif /* __KERNEL__ */ diff --git a/include/asm-ppc/smp.h b/include/asm-ppc/smp.h index 2454352aba27..9de96607a428 100644 --- a/include/asm-ppc/smp.h +++ b/include/asm-ppc/smp.h @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.smp.h 1.12 08/16/01 07:49:31 paulus + * BK Id: %F% %I% %G% %U% %#% */ /* smp.h: PPC specific SMP stuff. * @@ -48,7 +48,7 @@ extern void smp_local_timer_interrupt(struct pt_regs *); #define cpu_logical_map(cpu) (cpu) #define cpu_number_map(x) (x) -#define smp_processor_id() (current->processor) +#define smp_processor_id() (current->cpu) extern int smp_hw_index[NR_CPUS]; #define hard_smp_processor_id() (smp_hw_index[smp_processor_id()]) diff --git a/include/asm-ppc/spinlock.h b/include/asm-ppc/spinlock.h index 10d82555a428..7c18ccfe1552 100644 --- a/include/asm-ppc/spinlock.h +++ b/include/asm-ppc/spinlock.h @@ -1,10 +1,11 @@ /* - * BK Id: SCCS/s.spinlock.h 1.9 08/21/01 16:07:48 trini + * BK Id: %F% %I% %G% %U% %#% */ #ifndef __ASM_SPINLOCK_H #define __ASM_SPINLOCK_H #include <asm/system.h> +#include <asm/processor.h> #undef SPINLOCK_DEBUG @@ -40,14 +41,17 @@ static inline void spin_lock(spinlock_t *lock) unsigned long tmp; __asm__ __volatile__( - "b 1f # spin_lock\n\ -2: lwzx %0,0,%1\n\ + "b 1f # spin_lock\n\ +2:" HMT_PRIO_LOW +" lwzx %0,0,%1\n\ cmpwi 0,%0,0\n\ - bne+ 2b\n\ -1: lwarx %0,0,%1\n\ + bne+ 2b\n" + HMT_PRIO_MED +"1: lwarx %0,0,%1\n\ cmpwi 0,%0,0\n\ - bne- 2b\n\ - stwcx. %2,0,%1\n\ + bne- 2b\n" + PPC405_ERR77(0,%1) +" stwcx. %2,0,%1\n\ bne- 2b\n\ isync" : "=&r"(tmp) @@ -108,15 +112,18 @@ static __inline__ void read_lock(rwlock_t *rw) unsigned int tmp; __asm__ __volatile__( - "b 2f # read_lock\n\ -1: lwzx %0,0,%1\n\ - cmpwi 0,%0,0\n\ - blt+ 1b\n\ -2: lwarx %0,0,%1\n\ - addic. %0,%0,1\n\ - ble- 1b\n\ - stwcx. %0,0,%1\n\ - bne- 2b\n\ + "b 2f # read_lock\n\ +1:" HMT_PRIO_LOW +" lwzx %0,0,%1\n\ + cmpwi 0,%0,0\n\ + blt+ 1b\n" + HMT_PRIO_MED +"2: lwarx %0,0,%1\n\ + addic. %0,%0,1\n\ + ble- 1b\n" + PPC405_ERR77(0,%1) +" stwcx. %0,0,%1\n\ + bne- 2b\n\ isync" : "=&r"(tmp) : "r"(&rw->lock) @@ -128,11 +135,12 @@ static __inline__ void read_unlock(rwlock_t *rw) unsigned int tmp; __asm__ __volatile__( - "eieio # read_unlock\n\ -1: lwarx %0,0,%1\n\ - addic %0,%0,-1\n\ - stwcx. %0,0,%1\n\ - bne- 1b" + "eieio # read_unlock\n\ +1: lwarx %0,0,%1\n\ + addic %0,%0,-1\n" + PPC405_ERR77(0,%1) +" stwcx. %0,0,%1\n\ + bne- 1b" : "=&r"(tmp) : "r"(&rw->lock) : "cr0", "memory"); @@ -143,15 +151,18 @@ static __inline__ void write_lock(rwlock_t *rw) unsigned int tmp; __asm__ __volatile__( - "b 2f # write_lock\n\ -1: lwzx %0,0,%1\n\ - cmpwi 0,%0,0\n\ - bne+ 1b\n\ -2: lwarx %0,0,%1\n\ - cmpwi 0,%0,0\n\ - bne- 1b\n\ - stwcx. %2,0,%1\n\ - bne- 2b\n\ + "b 2f # write_lock\n\ +1:" HMT_PRIO_LOW +" lwzx %0,0,%1\n\ + cmpwi 0,%0,0\n\ + bne+ 1b\n" + HMT_PRIO_MED +"2: lwarx %0,0,%1\n\ + cmpwi 0,%0,0\n\ + bne- 1b\n" + PPC405_ERR77(0,%1) +" stwcx. %2,0,%1\n\ + bne- 2b\n\ isync" : "=&r"(tmp) : "r"(&rw->lock), "r"(-1) diff --git a/include/asm-ppc/system.h b/include/asm-ppc/system.h index 95f2d4ede8af..a99c75adf062 100644 --- a/include/asm-ppc/system.h +++ b/include/asm-ppc/system.h @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.system.h 1.14 08/20/01 14:34:41 paulus + * BK Id: %F% %I% %G% %U% %#% */ /* * Copyright (C) 1999 Cort Dougan <cort@cs.nmt.edu> @@ -59,7 +59,7 @@ extern void poweroff_now(void); extern long _get_L2CR(void); extern void _set_L2CR(unsigned long); #else -#define _get_L2CR() 0 +#define _get_L2CR() 0L #define _set_L2CR(val) do { } while(0) #endif extern void via_cuda_init(void); @@ -120,18 +120,15 @@ extern void __global_restore_flags(unsigned long); #define local_irq_save(flags) __save_and_cli(flags) #define local_irq_restore(flags) __restore_flags(flags) -#endif /* __KERNEL__ */ - -#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr)))) - static __inline__ unsigned long xchg_u32(volatile void *p, unsigned long val) { unsigned long prev; __asm__ __volatile__ ("\n\ -1: lwarx %0,0,%2 \n\ - stwcx. %3,0,%2 \n\ +1: lwarx %0,0,%2 \n" + PPC405_ERR77(0,%2) +" stwcx. %3,0,%2 \n\ bne- 1b" : "=&r" (prev), "=m" (*(volatile unsigned long *)p) : "r" (p), "r" (val), "m" (*(volatile unsigned long *)p) @@ -181,8 +178,9 @@ __cmpxchg_u32(volatile int *p, int old, int new) __asm__ __volatile__ ("\n\ 1: lwarx %0,0,%2 \n\ cmpw 0,%0,%3 \n\ - bne 2f \n\ - stwcx. %4,0,%2 \n\ + bne 2f \n" + PPC405_ERR77(0,%2) +" stwcx. %4,0,%2 \n\ bne- 1b\n" #ifdef CONFIG_SMP " sync\n" @@ -222,4 +220,5 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size) (unsigned long)_n_, sizeof(*(ptr))); \ }) +#endif /* __KERNEL__ */ #endif /* __PPC_SYSTEM_H */ diff --git a/include/asm-ppc/time.h b/include/asm-ppc/time.h index a1d7a4100fb4..f4398a47f352 100644 --- a/include/asm-ppc/time.h +++ b/include/asm-ppc/time.h @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.time.h 1.17 10/23/01 08:09:35 trini + * BK Id: %F% %I% %G% %U% %#% */ /* * Common time prototypes and such for all ppc machines. @@ -16,6 +16,10 @@ #include <linux/mc146818rtc.h> #include <linux/threads.h> +#ifdef CONFIG_PPC_ISERIES +#include <asm/iSeries/Paca.h> +#include <asm/iSeries/HvCall.h> +#endif #include <asm/processor.h> /* time.c */ @@ -52,6 +56,24 @@ static __inline__ void set_dec(unsigned int val) return; /* Have to let it auto-reload */ #elif defined(CONFIG_8xx_CPU6) set_dec_cpu6(val); +#elif defined(CONFIG_PPC_ISERIES) +/* + * Add code here to set the virtual decrementer in + * ItLpPaca if we have shared processors and to + * invoke the hypervisor as needed. + */ + struct Paca * paca; + int cur_dec; + + paca = (struct Paca *)mfspr(SPRG1); + if ( paca->xLpPaca.xSharedProc ) { + paca->xLpPaca.xVirtualDecr = val; + cur_dec = get_dec(); + if ( cur_dec > val ) + HvCall_setVirtualDecr(); + } + else + mtspr(SPRN_DEC, val); #else mtspr(SPRN_DEC, val); #endif @@ -69,13 +91,21 @@ extern __inline__ int const __USE_RTC(void) { extern __inline__ unsigned long get_tbl(void) { unsigned long tbl; +#if defined(CONFIG_403GCX) + asm volatile("mfspr %0, 0x3dd" : "=r" (tbl)); +#else asm volatile("mftb %0" : "=r" (tbl)); +#endif return tbl; } extern __inline__ unsigned long get_tbu(void) { unsigned long tbl; +#if defined(CONFIG_403GCX) + asm volatile("mfspr %0, 0x3dc" : "=r" (tbl)); +#else asm volatile("mftbu %0" : "=r" (tbl)); +#endif return tbl; } diff --git a/include/asm-ppc/todc.h b/include/asm-ppc/todc.h new file mode 100644 index 000000000000..9b4d58e9efeb --- /dev/null +++ b/include/asm-ppc/todc.h @@ -0,0 +1,380 @@ +/* + * include/asm-ppc/todc.h + * + * Definitions for the M48Txx and mc146818 series of Time of day/Real Time + * Clock chips. + * + * Author: Mark A. Greer + * mgreer@mvista.com + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +/* + * Support for the M48T37/M48T59/.../mc146818 Real Time Clock chips. + * Purpose is to make one generic file that handles all of these chips instead + * of every platform implementing the same code over & over again. + */ + +#ifndef __PPC_KERNEL_TODC_H +#define __PPC_KERNEL_TODC_H + +typedef struct { + uint rtc_type; /* your particular chip */ + + /* + * Following are the addresses of the AS0, AS1, and DATA registers + * of these chips. Note that these are board-specific. + */ + unsigned char *nvram_as0; + unsigned char *nvram_as1; + unsigned char *nvram_data; + + /* + * Define bits to stop external set of regs from changing so + * the chip can be read/written reliably. + */ + unsigned char enable_read; + unsigned char enable_write; + + /* + * Following is the number of AS0 address bits. This is normally + * 8 but some bad hardware routes address lines incorrectly. + */ + int as0_bits; + + /* Following are the register offsets for the particular chip */ + int year; + int month; + int day_of_month; + int day_of_week; + int hours; + int minutes; + int seconds; + int control_b; + int control_a; + int watchdog; + int interrupts; + int alarm_date; + int alarm_hour; + int alarm_minutes; + int alarm_seconds; + int century; + int flags; +} todc_info_t; + +/* + * Define the types of TODC/RTC variants that are supported in + * arch/ppc/kernel/todc_time.c + * Make a new one of these for any chip somehow differs from what's already + * defined. That way, if you ever need to put in code to touch those + * bits/registers in todc_time.c, you can put it inside an + * 'if (todc_info->rtc_type == TODC_TYPE_XXX)' so you won't break + * anyone else. + */ +#define TODC_TYPE_MK48T35 1 +#define TODC_TYPE_MK48T37 2 +#define TODC_TYPE_MK48T59 3 +#define TODC_TYPE_DS1693 4 /* Dallas DS1693 RTC */ +#define TODC_TYPE_DS1743 5 /* Dallas DS1743 RTC */ +#define TODC_TYPE_DS1746 6 /* Dallas DS1746 RTC */ +#define TODC_TYPE_DS1747 7 /* Dallas DS1747 RTC */ +#define TODC_TYPE_DS1501 8 /* Dallas DS1501 RTC */ +#define TODC_TYPE_DS1643 9 /* Dallas DS1643 RTC */ +#define TODC_TYPE_PC97307 10 /* PC97307 internal RTC */ +#define TODC_TYPE_DS1557 11 /* Dallas DS1557 RTC */ +#define TODC_TYPE_MC146818 100 /* Leave room for more m48txx's */ + +/* + * Bit to clear/set to enable reads/writes to the chip + */ +#define TODC_MK48TXX_CNTL_A_R 0x40 +#define TODC_MK48TXX_CNTL_A_W 0x80 +#define TODC_MK48TXX_DAY_CB 0x80 + +#define TODC_DS1501_CNTL_B_TE 0x80 + +/* + * Define the values for the various RTC's that should to into the todc_info + * table. + */ +#define TODC_TYPE_MK48T35_YEAR 0x7fff +#define TODC_TYPE_MK48T35_MONTH 0x7ffe +#define TODC_TYPE_MK48T35_DOM 0x7ffd /* Day of Month */ +#define TODC_TYPE_MK48T35_DOW 0x7ffc /* Day of Week */ +#define TODC_TYPE_MK48T35_HOURS 0x7ffb +#define TODC_TYPE_MK48T35_MINUTES 0x7ffa +#define TODC_TYPE_MK48T35_SECONDS 0x7ff9 +#define TODC_TYPE_MK48T35_CNTL_B 0x7ff9 +#define TODC_TYPE_MK48T35_CNTL_A 0x7ff8 +#define TODC_TYPE_MK48T35_WATCHDOG 0x0000 +#define TODC_TYPE_MK48T35_INTERRUPTS 0x0000 +#define TODC_TYPE_MK48T35_ALARM_DATE 0x0000 +#define TODC_TYPE_MK48T35_ALARM_HOUR 0x0000 +#define TODC_TYPE_MK48T35_ALARM_MINUTES 0x0000 +#define TODC_TYPE_MK48T35_ALARM_SECONDS 0x0000 +#define TODC_TYPE_MK48T35_CENTURY 0x0000 +#define TODC_TYPE_MK48T35_FLAGS 0x0000 + +#define TODC_TYPE_MK48T37_YEAR 0x7fff +#define TODC_TYPE_MK48T37_MONTH 0x7ffe +#define TODC_TYPE_MK48T37_DOM 0x7ffd /* Day of Month */ +#define TODC_TYPE_MK48T37_DOW 0x7ffc /* Day of Week */ +#define TODC_TYPE_MK48T37_HOURS 0x7ffb +#define TODC_TYPE_MK48T37_MINUTES 0x7ffa +#define TODC_TYPE_MK48T37_SECONDS 0x7ff9 +#define TODC_TYPE_MK48T37_CNTL_B 0x7ff9 +#define TODC_TYPE_MK48T37_CNTL_A 0x7ff8 +#define TODC_TYPE_MK48T37_WATCHDOG 0x7ff7 +#define TODC_TYPE_MK48T37_INTERRUPTS 0x7ff6 +#define TODC_TYPE_MK48T37_ALARM_DATE 0x7ff5 +#define TODC_TYPE_MK48T37_ALARM_HOUR 0x7ff4 +#define TODC_TYPE_MK48T37_ALARM_MINUTES 0x7ff3 +#define TODC_TYPE_MK48T37_ALARM_SECONDS 0x7ff2 +#define TODC_TYPE_MK48T37_CENTURY 0x7ff1 +#define TODC_TYPE_MK48T37_FLAGS 0x7ff0 + +#define TODC_TYPE_MK48T59_YEAR 0x1fff +#define TODC_TYPE_MK48T59_MONTH 0x1ffe +#define TODC_TYPE_MK48T59_DOM 0x1ffd /* Day of Month */ +#define TODC_TYPE_MK48T59_DOW 0x1ffc /* Day of Week */ +#define TODC_TYPE_MK48T59_HOURS 0x1ffb +#define TODC_TYPE_MK48T59_MINUTES 0x1ffa +#define TODC_TYPE_MK48T59_SECONDS 0x1ff9 +#define TODC_TYPE_MK48T59_CNTL_B 0x1ff9 +#define TODC_TYPE_MK48T59_CNTL_A 0x1ff8 +#define TODC_TYPE_MK48T59_WATCHDOG 0x1fff +#define TODC_TYPE_MK48T59_INTERRUPTS 0x1fff +#define TODC_TYPE_MK48T59_ALARM_DATE 0x1fff +#define TODC_TYPE_MK48T59_ALARM_HOUR 0x1fff +#define TODC_TYPE_MK48T59_ALARM_MINUTES 0x1fff +#define TODC_TYPE_MK48T59_ALARM_SECONDS 0x1fff +#define TODC_TYPE_MK48T59_CENTURY 0x1fff +#define TODC_TYPE_MK48T59_FLAGS 0x1fff + +#define TODC_TYPE_DS1501_YEAR 0x06 +#define TODC_TYPE_DS1501_MONTH 0x05 +#define TODC_TYPE_DS1501_DOM 0x04 /* Day of Month */ +#define TODC_TYPE_DS1501_DOW 0x03 /* Day of Week */ +#define TODC_TYPE_DS1501_HOURS 0x02 +#define TODC_TYPE_DS1501_MINUTES 0x01 +#define TODC_TYPE_DS1501_SECONDS 0x00 +#define TODC_TYPE_DS1501_CNTL_B 0x0f +#define TODC_TYPE_DS1501_CNTL_A 0x0f +#define TODC_TYPE_DS1501_WATCHDOG 0xff +#define TODC_TYPE_DS1501_INTERRUPTS 0xff +#define TODC_TYPE_DS1501_ALARM_DATE 0x0b +#define TODC_TYPE_DS1501_ALARM_HOUR 0x0a +#define TODC_TYPE_DS1501_ALARM_MINUTES 0x09 +#define TODC_TYPE_DS1501_ALARM_SECONDS 0x08 +#define TODC_TYPE_DS1501_CENTURY 0x07 +#define TODC_TYPE_DS1501_FLAGS 0xff + +#define TODC_TYPE_DS1557_YEAR 0x7ffff +#define TODC_TYPE_DS1557_MONTH 0x7fffe +#define TODC_TYPE_DS1557_DOM 0x7fffd /* Day of Month */ +#define TODC_TYPE_DS1557_DOW 0x7fffc /* Day of Week */ +#define TODC_TYPE_DS1557_HOURS 0x7fffb +#define TODC_TYPE_DS1557_MINUTES 0x7fffa +#define TODC_TYPE_DS1557_SECONDS 0x7fff9 +#define TODC_TYPE_DS1557_CNTL_B 0x7fff9 +#define TODC_TYPE_DS1557_CNTL_A 0x7fff8 /* control_a R/W regs */ +#define TODC_TYPE_DS1557_WATCHDOG 0x7fff7 +#define TODC_TYPE_DS1557_INTERRUPTS 0x7fff6 +#define TODC_TYPE_DS1557_ALARM_DATE 0x7fff5 +#define TODC_TYPE_DS1557_ALARM_HOUR 0x7fff4 +#define TODC_TYPE_DS1557_ALARM_MINUTES 0x7fff3 +#define TODC_TYPE_DS1557_ALARM_SECONDS 0x7fff2 +#define TODC_TYPE_DS1557_CENTURY 0x7fff8 +#define TODC_TYPE_DS1557_FLAGS 0x7fff0 + +#define TODC_TYPE_DS1643_YEAR 0x1fff +#define TODC_TYPE_DS1643_MONTH 0x1ffe +#define TODC_TYPE_DS1643_DOM 0x1ffd /* Day of Month */ +#define TODC_TYPE_DS1643_DOW 0x1ffc /* Day of Week */ +#define TODC_TYPE_DS1643_HOURS 0x1ffb +#define TODC_TYPE_DS1643_MINUTES 0x1ffa +#define TODC_TYPE_DS1643_SECONDS 0x1ff9 +#define TODC_TYPE_DS1643_CNTL_B 0x1ff9 +#define TODC_TYPE_DS1643_CNTL_A 0x1ff8 /* control_a R/W regs */ +#define TODC_TYPE_DS1643_WATCHDOG 0x1fff +#define TODC_TYPE_DS1643_INTERRUPTS 0x1fff +#define TODC_TYPE_DS1643_ALARM_DATE 0x1fff +#define TODC_TYPE_DS1643_ALARM_HOUR 0x1fff +#define TODC_TYPE_DS1643_ALARM_MINUTES 0x1fff +#define TODC_TYPE_DS1643_ALARM_SECONDS 0x1fff +#define TODC_TYPE_DS1643_CENTURY 0x1ff8 +#define TODC_TYPE_DS1643_FLAGS 0x1fff + +#define TODC_TYPE_DS1693_YEAR 0x09 +#define TODC_TYPE_DS1693_MONTH 0x08 +#define TODC_TYPE_DS1693_DOM 0x07 /* Day of Month */ +#define TODC_TYPE_DS1693_DOW 0x06 /* Day of Week */ +#define TODC_TYPE_DS1693_HOURS 0x04 +#define TODC_TYPE_DS1693_MINUTES 0x02 +#define TODC_TYPE_DS1693_SECONDS 0x00 +#define TODC_TYPE_DS1693_CNTL_B 0x0b +#define TODC_TYPE_DS1693_CNTL_A 0x0a +#define TODC_TYPE_DS1693_WATCHDOG 0xff +#define TODC_TYPE_DS1693_INTERRUPTS 0xff +#define TODC_TYPE_DS1693_ALARM_DATE 0x49 +#define TODC_TYPE_DS1693_ALARM_HOUR 0x05 +#define TODC_TYPE_DS1693_ALARM_MINUTES 0x03 +#define TODC_TYPE_DS1693_ALARM_SECONDS 0x01 +#define TODC_TYPE_DS1693_CENTURY 0x48 +#define TODC_TYPE_DS1693_FLAGS 0xff + +#define TODC_TYPE_DS1743_YEAR 0x1fff +#define TODC_TYPE_DS1743_MONTH 0x1ffe +#define TODC_TYPE_DS1743_DOM 0x1ffd /* Day of Month */ +#define TODC_TYPE_DS1743_DOW 0x1ffc /* Day of Week */ +#define TODC_TYPE_DS1743_HOURS 0x1ffb +#define TODC_TYPE_DS1743_MINUTES 0x1ffa +#define TODC_TYPE_DS1743_SECONDS 0x1ff9 +#define TODC_TYPE_DS1743_CNTL_B 0x1ff9 +#define TODC_TYPE_DS1743_CNTL_A 0x1ff8 /* control_a R/W regs */ +#define TODC_TYPE_DS1743_WATCHDOG 0x1fff +#define TODC_TYPE_DS1743_INTERRUPTS 0x1fff +#define TODC_TYPE_DS1743_ALARM_DATE 0x1fff +#define TODC_TYPE_DS1743_ALARM_HOUR 0x1fff +#define TODC_TYPE_DS1743_ALARM_MINUTES 0x1fff +#define TODC_TYPE_DS1743_ALARM_SECONDS 0x1fff +#define TODC_TYPE_DS1743_CENTURY 0x1ff8 +#define TODC_TYPE_DS1743_FLAGS 0x1fff + +#define TODC_TYPE_DS1746_YEAR 0x1ffff +#define TODC_TYPE_DS1746_MONTH 0x1fffe +#define TODC_TYPE_DS1746_DOM 0x1fffd /* Day of Month */ +#define TODC_TYPE_DS1746_DOW 0x1fffc /* Day of Week */ +#define TODC_TYPE_DS1746_HOURS 0x1fffb +#define TODC_TYPE_DS1746_MINUTES 0x1fffa +#define TODC_TYPE_DS1746_SECONDS 0x1fff9 +#define TODC_TYPE_DS1746_CNTL_B 0x1fff9 +#define TODC_TYPE_DS1746_CNTL_A 0x1fff8 /* control_a R/W regs */ +#define TODC_TYPE_DS1746_WATCHDOG 0x00000 +#define TODC_TYPE_DS1746_INTERRUPTS 0x00000 +#define TODC_TYPE_DS1746_ALARM_DATE 0x00000 +#define TODC_TYPE_DS1746_ALARM_HOUR 0x00000 +#define TODC_TYPE_DS1746_ALARM_MINUTES 0x00000 +#define TODC_TYPE_DS1746_ALARM_SECONDS 0x00000 +#define TODC_TYPE_DS1746_CENTURY 0x00000 +#define TODC_TYPE_DS1746_FLAGS 0x00000 + +#define TODC_TYPE_DS1747_YEAR 0x1ffff +#define TODC_TYPE_DS1747_MONTH 0x1fffe +#define TODC_TYPE_DS1747_DOM 0x1fffd /* Day of Month */ +#define TODC_TYPE_DS1747_DOW 0x1fffc /* Day of Week */ +#define TODC_TYPE_DS1747_HOURS 0x1fffb +#define TODC_TYPE_DS1747_MINUTES 0x1fffa +#define TODC_TYPE_DS1747_SECONDS 0x1fff9 +#define TODC_TYPE_DS1747_CNTL_B 0x1fff9 +#define TODC_TYPE_DS1747_CNTL_A 0x1fff8 /* control_a R/W regs */ +#define TODC_TYPE_DS1747_WATCHDOG 0x00000 +#define TODC_TYPE_DS1747_INTERRUPTS 0x00000 +#define TODC_TYPE_DS1747_ALARM_DATE 0x00000 +#define TODC_TYPE_DS1747_ALARM_HOUR 0x00000 +#define TODC_TYPE_DS1747_ALARM_MINUTES 0x00000 +#define TODC_TYPE_DS1747_ALARM_SECONDS 0x00000 +#define TODC_TYPE_DS1747_CENTURY 0x00000 +#define TODC_TYPE_DS1747_FLAGS 0x00000 + +#define TODC_TYPE_MC146818_YEAR 0x09 +#define TODC_TYPE_MC146818_MONTH 0x08 +#define TODC_TYPE_MC146818_DOM 0x07 /* Day of Month */ +#define TODC_TYPE_MC146818_DOW 0x06 /* Day of Week */ +#define TODC_TYPE_MC146818_HOURS 0x04 +#define TODC_TYPE_MC146818_MINUTES 0x02 +#define TODC_TYPE_MC146818_SECONDS 0x00 +#define TODC_TYPE_MC146818_CNTL_B 0x0a +#define TODC_TYPE_MC146818_CNTL_A 0x0b /* control_a R/W regs */ +#define TODC_TYPE_MC146818_WATCHDOG 0x0c +#define TODC_TYPE_MC146818_INTERRUPTS 0x0d +#define TODC_TYPE_MC146818_ALARM_DATE 0xff +#define TODC_TYPE_MC146818_ALARM_HOUR 0x05 +#define TODC_TYPE_MC146818_ALARM_MINUTES 0x03 +#define TODC_TYPE_MC146818_ALARM_SECONDS 0x01 +#define TODC_TYPE_MC146818_CENTURY 0xff +#define TODC_TYPE_MC146818_FLAGS 0xff + +#define TODC_TYPE_PC97307_YEAR 0x09 +#define TODC_TYPE_PC97307_MONTH 0x08 +#define TODC_TYPE_PC97307_DOM 0x07 /* Day of Month */ +#define TODC_TYPE_PC97307_DOW 0x06 /* Day of Week */ +#define TODC_TYPE_PC97307_HOURS 0x04 +#define TODC_TYPE_PC97307_MINUTES 0x02 +#define TODC_TYPE_PC97307_SECONDS 0x00 +#define TODC_TYPE_PC97307_CNTL_B 0x0a +#define TODC_TYPE_PC97307_CNTL_A 0x0b /* control_a R/W regs */ +#define TODC_TYPE_PC97307_WATCHDOG 0x0c +#define TODC_TYPE_PC97307_INTERRUPTS 0x0d +#define TODC_TYPE_PC97307_ALARM_DATE 0xff +#define TODC_TYPE_PC97307_ALARM_HOUR 0x05 +#define TODC_TYPE_PC97307_ALARM_MINUTES 0x03 +#define TODC_TYPE_PC97307_ALARM_SECONDS 0x01 +#define TODC_TYPE_PC97307_CENTURY 0xff +#define TODC_TYPE_PC97307_FLAGS 0xff + +/* + * Define macros to allocate and init the todc_info_t table that will + * be used by the todc_time.c routines. + */ +#define TODC_ALLOC() \ + static todc_info_t todc_info_alloc; \ + todc_info_t *todc_info = &todc_info_alloc; + +#define TODC_INIT(clock_type, as0, as1, data, bits) { \ + todc_info->rtc_type = clock_type; \ + \ + todc_info->nvram_as0 = (unsigned char *)(as0); \ + todc_info->nvram_as1 = (unsigned char *)(as1); \ + todc_info->nvram_data = (unsigned char *)(data); \ + \ + todc_info->as0_bits = (bits); \ + \ + todc_info->year = clock_type ##_YEAR; \ + todc_info->month = clock_type ##_MONTH; \ + todc_info->day_of_month = clock_type ##_DOM; \ + todc_info->day_of_week = clock_type ##_DOW; \ + todc_info->hours = clock_type ##_HOURS; \ + todc_info->minutes = clock_type ##_MINUTES; \ + todc_info->seconds = clock_type ##_SECONDS; \ + todc_info->control_b = clock_type ##_CNTL_B; \ + todc_info->control_a = clock_type ##_CNTL_A; \ + todc_info->watchdog = clock_type ##_WATCHDOG; \ + todc_info->interrupts = clock_type ##_INTERRUPTS; \ + todc_info->alarm_date = clock_type ##_ALARM_DATE; \ + todc_info->alarm_hour = clock_type ##_ALARM_HOUR; \ + todc_info->alarm_minutes = clock_type ##_ALARM_MINUTES; \ + todc_info->alarm_seconds = clock_type ##_ALARM_SECONDS; \ + todc_info->century = clock_type ##_CENTURY; \ + todc_info->flags = clock_type ##_FLAGS; \ +} + +#ifndef BCD_TO_BIN +#define BCD_TO_BIN(val) ((val)=((val)&15) + ((val)>>4)*10) +#endif + +#ifndef BIN_TO_BCD +#define BIN_TO_BCD(val) ((val)=(((val)/10)<<4) + (val)%10) +#endif + +extern todc_info_t *todc_info; + +unsigned char todc_direct_read_val(int addr); +void todc_direct_write_val(int addr, unsigned char val); +unsigned char todc_m48txx_read_val(int addr); +void todc_m48txx_write_val(int addr, unsigned char val); +unsigned char todc_mc146818_read_val(int addr); +void todc_mc146818_write_val(int addr, unsigned char val); + +long todc_time_init(void); +unsigned long todc_get_rtc_time(void); +int todc_set_rtc_time(unsigned long nowtime); +void todc_calibrate_decr(void); + +#endif /* __PPC_KERNEL_TODC_H */ |
