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 /arch/ppc | |
| parent | 0dc68d77428413d0f417df3a378f857a2e798ebf (diff) | |
Import arch/ppc and include/asm-ppc changes from linuxppc_2_5 tree
Diffstat (limited to 'arch/ppc')
389 files changed, 66425 insertions, 10843 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/i8259.h b/arch/ppc/kernel/i8259.h deleted file mode 100644 index c23eadfe3c95..000000000000 --- a/arch/ppc/kernel/i8259.h +++ /dev/null @@ -1,15 +0,0 @@ -/* - * BK Id: SCCS/s.i8259.h 1.5 05/17/01 18:14:21 cort - */ - -#ifndef _PPC_KERNEL_i8259_H -#define _PPC_KERNEL_i8259_H - -#include "local_irq.h" - -extern struct hw_interrupt_type i8259_pic; - -void i8259_init(void); -int i8259_irq(int); - -#endif /* _PPC_KERNEL_i8259_H */ 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.h b/arch/ppc/kernel/open_pic.h deleted file mode 100644 index 0e236c0b3848..000000000000 --- a/arch/ppc/kernel/open_pic.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * BK Id: SCCS/s.open_pic.h 1.14 10/11/01 12:09:12 trini - */ -/* - * arch/ppc/kernel/open_pic.h -- OpenPIC Interrupt Handling - * - * Copyright (C) 1997 Geert Uytterhoeven - * - * 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. - * - */ - -#ifndef _PPC_KERNEL_OPEN_PIC_H -#define _PPC_KERNEL_OPEN_PIC_H - -#include <linux/config.h> - -#define OPENPIC_SIZE 0x40000 - -/* - * Non-offset'ed vector numbers - */ - -#define OPENPIC_VEC_TIMER 64 /* and up */ -#define OPENPIC_VEC_IPI 72 /* and up */ -#define OPENPIC_VEC_SPURIOUS 127 - -/* OpenPIC IRQ controller structure */ -extern struct hw_interrupt_type open_pic; - -/* OpenPIC IPI controller structure */ -#ifdef CONFIG_SMP -extern struct hw_interrupt_type open_pic_ipi; -#endif /* CONFIG_SMP */ - -extern u_int OpenPIC_NumInitSenses; -extern u_char *OpenPIC_InitSenses; -extern void* OpenPIC_Addr; - -/* Exported functions */ -extern void openpic_init(int, int, unsigned char *, int); -extern u_int openpic_irq(void); -extern void openpic_eoi(void); -extern void openpic_request_IPIs(void); -extern void do_openpic_setup_cpu(void); -extern int openpic_get_irq(struct pt_regs *regs); -extern void openpic_reset_processor_phys(u_int cpumask); -extern void openpic_setup_ISU(int isu_num, unsigned long addr); -extern void openpic_cause_IPI(u_int ipi, u_int cpumask); -extern void smp_openpic_message_pass(int target, int msg, unsigned long data, - int wait); - -extern inline int openpic_to_irq(int irq) -{ - /* IRQ 0 usually means 'disabled'.. don't mess with it - * exceptions to this (sandpoint maybe?) - * shouldn't use openpic_to_irq - */ - if (irq != 0){ - return irq += NUM_8259_INTERRUPTS; - } else { - return 0; - } -} -/*extern int open_pic_irq_offset;*/ -#endif /* _PPC_KERNEL_OPEN_PIC_H */ 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_pic.h b/arch/ppc/kernel/ppc4xx_pic.h deleted file mode 100644 index ebb63a7f36d4..000000000000 --- a/arch/ppc/kernel/ppc4xx_pic.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * BK Id: SCCS/s.ppc4xx_pic.h 1.8 06/15/01 13:56:56 paulus - */ -/* - * - * Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu> - * - * Module name: ppc4xx_pic.h - * - * Description: - * Interrupt controller driver for PowerPC 4xx-based processors. - */ - -#ifndef __PPC4XX_PIC_H__ -#define __PPC4XX_PIC_H__ - -#include <linux/config.h> -#include "local_irq.h" - -/* External Global Variables */ - -extern struct hw_interrupt_type *ppc4xx_pic; - - -/* Function Prototypes */ - -extern void ppc4xx_pic_init(void); -extern int ppc4xx_pic_get_irq(struct pt_regs *regs); - -#endif /* __PPC4XX_PIC_H__ */ 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.h b/arch/ppc/kernel/ppc_asm.h deleted file mode 100644 index ea28f75d9acc..000000000000 --- a/arch/ppc/kernel/ppc_asm.h +++ /dev/null @@ -1,158 +0,0 @@ -/* - * BK Id: SCCS/s.ppc_asm.h 1.18 10/18/01 15:02:09 trini - */ -/* - * arch/ppc/kernel/ppc_asm.h - * - * Definitions used by various bits of low-level assembly code on PowerPC. - * - * Copyright (C) 1995-1999 Gary Thomas, Paul Mackerras, Cort Dougan. - * - * 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 "ppc_asm.tmpl" -#include "ppc_defs.h" - -/* - * Macros for storing registers into and loading registers from - * exception frames. - */ -#define SAVE_GPR(n, base) stw n,GPR0+4*(n)(base) -#define SAVE_2GPRS(n, base) SAVE_GPR(n, base); SAVE_GPR(n+1, base) -#define SAVE_4GPRS(n, base) SAVE_2GPRS(n, base); SAVE_2GPRS(n+2, base) -#define SAVE_8GPRS(n, base) SAVE_4GPRS(n, base); SAVE_4GPRS(n+4, base) -#define SAVE_10GPRS(n, base) SAVE_8GPRS(n, base); SAVE_2GPRS(n+8, base) -#define REST_GPR(n, base) lwz n,GPR0+4*(n)(base) -#define REST_2GPRS(n, base) REST_GPR(n, base); REST_GPR(n+1, base) -#define REST_4GPRS(n, base) REST_2GPRS(n, base); REST_2GPRS(n+2, base) -#define REST_8GPRS(n, base) REST_4GPRS(n, base); REST_4GPRS(n+4, base) -#define REST_10GPRS(n, base) REST_8GPRS(n, base); REST_2GPRS(n+8, base) - -#define SAVE_FPR(n, base) stfd n,THREAD_FPR0+8*(n)(base) -#define SAVE_2FPRS(n, base) SAVE_FPR(n, base); SAVE_FPR(n+1, base) -#define SAVE_4FPRS(n, base) SAVE_2FPRS(n, base); SAVE_2FPRS(n+2, base) -#define SAVE_8FPRS(n, base) SAVE_4FPRS(n, base); SAVE_4FPRS(n+4, base) -#define SAVE_16FPRS(n, base) SAVE_8FPRS(n, base); SAVE_8FPRS(n+8, base) -#define SAVE_32FPRS(n, base) SAVE_16FPRS(n, base); SAVE_16FPRS(n+16, base) -#define REST_FPR(n, base) lfd n,THREAD_FPR0+8*(n)(base) -#define REST_2FPRS(n, base) REST_FPR(n, base); REST_FPR(n+1, base) -#define REST_4FPRS(n, base) REST_2FPRS(n, base); REST_2FPRS(n+2, base) -#define REST_8FPRS(n, base) REST_4FPRS(n, base); REST_4FPRS(n+4, base) -#define REST_16FPRS(n, base) REST_8FPRS(n, base); REST_8FPRS(n+8, base) -#define REST_32FPRS(n, base) REST_16FPRS(n, base); REST_16FPRS(n+16, base) - -/* - * Once a version of gas that understands the AltiVec instructions - * is freely available, we can do this the normal way... - paulus - */ -#define LVX(r,a,b) .long (31<<26)+((r)<<21)+((a)<<16)+((b)<<11)+(103<<1) -#define STVX(r,a,b) .long (31<<26)+((r)<<21)+((a)<<16)+((b)<<11)+(231<<1) -#define MFVSCR(r) .long (4<<26)+((r)<<21)+(770<<1) -#define MTVSCR(r) .long (4<<26)+((r)<<11)+(802<<1) - -#define SAVE_VR(n,b,base) li b,THREAD_VR0+(16*(n)); STVX(n,b,base) -#define SAVE_2VR(n,b,base) SAVE_VR(n,b,base); SAVE_VR(n+1,b,base) -#define SAVE_4VR(n,b,base) SAVE_2VR(n,b,base); SAVE_2VR(n+2,b,base) -#define SAVE_8VR(n,b,base) SAVE_4VR(n,b,base); SAVE_4VR(n+4,b,base) -#define SAVE_16VR(n,b,base) SAVE_8VR(n,b,base); SAVE_8VR(n+8,b,base) -#define SAVE_32VR(n,b,base) SAVE_16VR(n,b,base); SAVE_16VR(n+16,b,base) -#define REST_VR(n,b,base) li b,THREAD_VR0+(16*(n)); LVX(n,b,base) -#define REST_2VR(n,b,base) REST_VR(n,b,base); REST_VR(n+1,b,base) -#define REST_4VR(n,b,base) REST_2VR(n,b,base); REST_2VR(n+2,b,base) -#define REST_8VR(n,b,base) REST_4VR(n,b,base); REST_4VR(n+4,b,base) -#define REST_16VR(n,b,base) REST_8VR(n,b,base); REST_8VR(n+8,b,base) -#define REST_32VR(n,b,base) REST_16VR(n,b,base); REST_16VR(n+16,b,base) - -#ifdef CONFIG_PPC601_SYNC_FIX -#define SYNC \ -BEGIN_FTR_SECTION \ - sync; \ - isync; \ -END_FTR_SECTION_IFSET(CPU_FTR_601) -#define SYNC_601 \ -BEGIN_FTR_SECTION \ - sync; \ -END_FTR_SECTION_IFSET(CPU_FTR_601) -#define ISYNC_601 \ -BEGIN_FTR_SECTION \ - isync; \ -END_FTR_SECTION_IFSET(CPU_FTR_601) -#else -#define SYNC -#define SYNC_601 -#define ISYNC_601 -#endif - -#ifndef CONFIG_SMP -#define TLBSYNC -#else /* CONFIG_SMP */ -/* tlbsync is not implemented on 601 */ -#define TLBSYNC \ -BEGIN_FTR_SECTION \ - tlbsync; \ - sync; \ -END_FTR_SECTION_IFCLR(CPU_FTR_601) -#endif - -/* - * This instruction is not implemented on the PPC 603 or 601; however, on - * the 403GCX and 405GP tlbia IS defined and tlbie is not. - * All of these instructions exist in the 8xx, they have magical powers, - * and they must be used. - */ - -#if !defined(CONFIG_4xx) && !defined(CONFIG_8xx) -#define tlbia \ - li r4,1024; \ - mtctr r4; \ - lis r4,KERNELBASE@h; \ -0: tlbie r4; \ - addi r4,r4,0x1000; \ - bdnz 0b -#endif - -/* - * On APUS (Amiga PowerPC cpu upgrade board), we don't know the - * physical base address of RAM at compile time. - */ -#define tophys(rd,rs) \ -0: addis rd,rs,-KERNELBASE@h; \ - .section ".vtop_fixup","aw"; \ - .align 1; \ - .long 0b; \ - .previous - -#define tovirt(rd,rs) \ -0: addis rd,rs,KERNELBASE@h; \ - .section ".ptov_fixup","aw"; \ - .align 1; \ - .long 0b; \ - .previous - -/* - * On 64-bit cpus, we use the rfid instruction instead of rfi, but - * we then have to make sure we preserve the top 32 bits except for - * the 64-bit mode bit, which we clear. - */ -#ifdef CONFIG_PPC64BRIDGE -#define FIX_SRR1(ra, rb) \ - mr rb,ra; \ - mfmsr ra; \ - clrldi ra,ra,1; /* turn off 64-bit mode */ \ - rldimi ra,rb,0,32 -#define RFI .long 0x4c000024 /* rfid instruction */ -#define MTMSRD(r) .long (0x7c000164 + ((r) << 21)) /* mtmsrd */ -#define CLR_TOP32(r) rlwinm (r),(r),0,0,31 /* clear top 32 bits */ - -#else -#define FIX_SRR1(ra, rb) -#define RFI rfi -#define MTMSRD(r) mtmsr r -#define CLR_TOP32(r) -#endif /* CONFIG_PPC64BRIDGE */ 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/arch/ppc/platforms/est8260.h b/arch/ppc/platforms/est8260.h new file mode 100644 index 000000000000..1bfe42865cb0 --- /dev/null +++ b/arch/ppc/platforms/est8260.h @@ -0,0 +1,31 @@ +/* + * BK Id: SCCS/s.est8260.h 1.5 05/17/01 18:14:24 cort + */ + +/* Board information for the EST8260, 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)0xf0000000) + + +/* 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; + 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/arch/ppc/platforms/fads.h b/arch/ppc/platforms/fads.h new file mode 100644 index 000000000000..386024c9f286 --- /dev/null +++ b/arch/ppc/platforms/fads.h @@ -0,0 +1,61 @@ +/* + * BK Id: SCCS/s.fads.h 1.14 10/26/01 10:14:09 trini + */ + +/* + * A collection of structures, addresses, and values associated with + * the Motorola 860T FADS board. Copied from the MBX stuff. + * + * Copyright (c) 1998 Dan Malek (dmalek@jlc.net) + */ +#ifdef __KERNEL__ +#ifndef __ASM_FADS_H__ +#define __ASM_FADS_H__ + +#include <linux/config.h> + +#include <asm/ppcboot.h> + +/* Memory map is configured by the PROM startup. + * I tried to follow the FADS manual, although the startup PROM + * dictates this and we simply have to move some of the physical + * addresses for Linux. + */ +#define BCSR_ADDR ((uint)0xff010000) +#define BCSR_SIZE ((uint)(64 * 1024)) +#define BCSR0 ((uint)0xff010000) +#define BCSR1 ((uint)0xff010004) +#define BCSR2 ((uint)0xff010008) +#define BCSR3 ((uint)0xff01000c) +#define BCSR4 ((uint)0xff010010) + +#define IMAP_ADDR ((uint)0xff000000) +#define IMAP_SIZE ((uint)(64 * 1024)) + +#define PCMCIA_MEM_ADDR ((uint)0xff020000) +#define PCMCIA_MEM_SIZE ((uint)(64 * 1024)) + +/* Bits of interest in the BCSRs. + */ +#define BCSR1_ETHEN ((uint)0x20000000) +#define BCSR1_RS232EN_1 ((uint)0x01000000) +#define BCSR1_RS232EN_2 ((uint)0x00040000) +#define BCSR4_ETHLOOP ((uint)0x80000000) /* EEST Loopback */ +#define BCSR4_EEFDX ((uint)0x40000000) /* EEST FDX enable */ +#define BCSR4_FETH_EN ((uint)0x08000000) /* PHY enable */ +#define BCSR4_FETHCFG0 ((uint)0x04000000) /* PHY autoneg mode */ +#define BCSR4_FETHCFG1 ((uint)0x00400000) /* PHY autoneg mode */ +#define BCSR4_FETHFDE ((uint)0x02000000) /* PHY FDX advertise */ +#define BCSR4_FETHRST ((uint)0x00200000) /* PHY Reset */ + +/* Interrupt level assignments. + */ +#define FEC_INTERRUPT SIU_LEVEL1 /* FEC interrupt */ +#define PHY_INTERRUPT SIU_IRQ2 /* PHY link change interrupt */ + +/* We don't use the 8259. + */ +#define NR_8259_INTS 0 + +#endif /* __ASM_FADS_H__ */ +#endif /* __KERNEL__ */ diff --git a/arch/ppc/platforms/gemini.h b/arch/ppc/platforms/gemini.h new file mode 100644 index 000000000000..f1dc4aa8a4c8 --- /dev/null +++ b/arch/ppc/platforms/gemini.h @@ -0,0 +1,171 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ +/* + * include/asm-ppc/platforms/gemini.h + * + * + * Onboard registers and descriptions for Synergy Microsystems' + * "Gemini" boards. + * + */ +#ifdef __KERNEL__ +#ifndef __PPC_GEMINI_H +#define __PPC_GEMINI_H + +/* Registers */ + +#define GEMINI_SERIAL_B (0xffeffb00) +#define GEMINI_SERIAL_A (0xffeffb08) +#define GEMINI_USWITCH (0xffeffd00) +#define GEMINI_BREV (0xffeffe00) +#define GEMINI_BECO (0xffeffe08) +#define GEMINI_FEAT (0xffeffe10) +#define GEMINI_BSTAT (0xffeffe18) +#define GEMINI_CPUSTAT (0xffeffe20) +#define GEMINI_L2CFG (0xffeffe30) +#define GEMINI_MEMCFG (0xffeffe38) +#define GEMINI_FLROM (0xffeffe40) +#define GEMINI_P0PCI (0xffeffe48) +#define GEMINI_FLWIN (0xffeffe50) +#define GEMINI_P0INTMASK (0xffeffe60) +#define GEMINI_P0INTAP (0xffeffe68) +#define GEMINI_PCIERR (0xffeffe70) +#define GEMINI_LEDBASE (0xffeffe80) +#define GEMINI_RTC (0xffe9fff8) +#define GEMINI_LEDS 8 +#define GEMINI_SWITCHES 8 + + +/* Flash ROM bit definitions */ +#define GEMINI_FLS_WEN (1<<0) +#define GEMINI_FLS_JMP (1<<6) +#define GEMINI_FLS_BOOT (1<<7) + +/* Memory bit definitions */ +#define GEMINI_MEM_TYPE_MASK 0xc0 +#define GEMINI_MEM_SIZE_MASK 0x38 +#define GEMINI_MEM_BANK_MASK 0x07 + +/* L2 cache bit definitions */ +#define GEMINI_L2_SIZE_MASK 0xc0 +#define GEMINI_L2_RATIO_MASK 0x03 + +/* Timebase register bit definitons */ +#define GEMINI_TIMEB0_EN (1<<0) +#define GEMINI_TIMEB1_EN (1<<1) +#define GEMINI_TIMEB2_EN (1<<2) +#define GEMINI_TIMEB3_EN (1<<3) + +/* CPU status bit definitions */ +#define GEMINI_CPU_ID_MASK 0x03 +#define GEMINI_CPU_COUNT_MASK 0x0c +#define GEMINI_CPU0_HALTED (1<<4) +#define GEMINI_CPU1_HALTED (1<<5) +#define GEMINI_CPU2_HALTED (1<<6) +#define GEMINI_CPU3_HALTED (1<<7) + +/* Board status bit definitions */ +#define GEMINI_BRD_FAIL (1<<0) /* FAIL led is lit */ +#define GEMINI_BRD_BUS_MASK 0x0c /* PowerPC bus speed */ + +/* Board family/feature bit descriptions */ +#define GEMINI_FEAT_HAS_FLASH (1<<0) +#define GEMINI_FEAT_HAS_ETH (1<<1) +#define GEMINI_FEAT_HAS_SCSI (1<<2) +#define GEMINI_FEAT_HAS_P0 (1<<3) +#define GEMINI_FEAT_FAM_MASK 0xf0 + +/* Mod/ECO bit definitions */ +#define GEMINI_ECO_LEVEL_MASK 0x0f +#define GEMINI_MOD_MASK 0xf0 + +/* Type/revision bit definitions */ +#define GEMINI_REV_MASK 0x0f +#define GEMINI_TYPE_MASK 0xf0 + +/* User switch definitions */ +#define GEMINI_SWITCH_VERBOSE 1 /* adds "debug" to boot cmd line */ +#define GEMINI_SWITCH_SINGLE_USER 7 /* boots into "single-user" mode */ + +#define SGS_RTC_CONTROL 0 +#define SGS_RTC_SECONDS 1 +#define SGS_RTC_MINUTES 2 +#define SGS_RTC_HOURS 3 +#define SGS_RTC_DAY 4 +#define SGS_RTC_DAY_OF_MONTH 5 +#define SGS_RTC_MONTH 6 +#define SGS_RTC_YEAR 7 + +#define SGS_RTC_SET 0x80 +#define SGS_RTC_IS_STOPPED 0x80 + +#define GRACKLE_CONFIG_ADDR_ADDR (0xfec00000) +#define GRACKLE_CONFIG_DATA_ADDR (0xfee00000) + +#define GEMINI_BOOT_INIT (0xfff00100) + +#ifndef __ASSEMBLY__ + +static inline void grackle_write( unsigned long addr, unsigned long data ) +{ + __asm__ __volatile__( + " stwbrx %1, 0, %0\n \ + sync\n \ + stwbrx %3, 0, %2\n \ + sync " + : /* no output */ + : "r" (GRACKLE_CONFIG_ADDR_ADDR), "r" (addr), + "r" (GRACKLE_CONFIG_DATA_ADDR), "r" (data)); +} + +static inline unsigned long grackle_read( unsigned long addr ) +{ + unsigned long val; + + __asm__ __volatile__( + " stwbrx %1, 0, %2\n \ + sync\n \ + lwbrx %0, 0, %3\n \ + sync " + : "=r" (val) + : "r" (addr), "r" (GRACKLE_CONFIG_ADDR_ADDR), + "r" (GRACKLE_CONFIG_DATA_ADDR)); + + return val; +} + +static inline void gemini_led_on( int led ) +{ + if (led >= 0 && led < GEMINI_LEDS) + *(unsigned char *)(GEMINI_LEDBASE + (led<<3)) = 1; +} + +static inline void gemini_led_off(int led) +{ + if (led >= 0 && led < GEMINI_LEDS) + *(unsigned char *)(GEMINI_LEDBASE + (led<<3)) = 0; +} + +static inline int gemini_led_val(int led) +{ + int val = 0; + if (led >= 0 && led < GEMINI_LEDS) + val = *(unsigned char *)(GEMINI_LEDBASE + (led<<3)); + return (val & 0x1); +} + +/* returns processor id from the board */ +static inline int gemini_processor(void) +{ + unsigned char cpu = *(unsigned char *)(GEMINI_CPUSTAT); + return (int) ((cpu == 0) ? 4 : (cpu & GEMINI_CPU_ID_MASK)); +} + + +extern void _gemini_reboot(void); +extern void gemini_prom_init(void); +extern void gemini_init_l2(void); +#endif /* __ASSEMBLY__ */ +#endif +#endif /* __KERNEL__ */ 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/arch/ppc/platforms/gemini_serial.h b/arch/ppc/platforms/gemini_serial.h new file mode 100644 index 000000000000..a29d655f8425 --- /dev/null +++ b/arch/ppc/platforms/gemini_serial.h @@ -0,0 +1,44 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ +#ifdef __KERNEL__ +#ifndef __ASMPPC_GEMINI_SERIAL_H +#define __ASMPPC_GEMINI_SERIAL_H + +#include <linux/config.h> +#include <platforms/gemini.h> + +#ifdef CONFIG_SERIAL_MANY_PORTS +#define RS_TABLE_SIZE 64 +#else +#define RS_TABLE_SIZE 4 +#endif + +/* Rate for the 24.576 Mhz clock for the onboard serial chip */ +#define BASE_BAUD (24576000 / 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 STD_SERIAL_PORT_DEFNS \ + { 0, BASE_BAUD, GEMINI_SERIAL_A, 15, STD_COM_FLAGS }, /* ttyS0 */ \ + { 0, BASE_BAUD, GEMINI_SERIAL_B, 14, STD_COM_FLAGS }, /* ttyS1 */ \ + +#ifdef CONFIG_GEMINI_PU32 +#define PU32_SERIAL_PORT_DEFNS \ + { 0, BASE_BAUD, NULL, 0, STD_COM_FLAGS }, +#else +#define PU32_SERIAL_PORT_DEFNS +#endif + +#define SERIAL_PORT_DFNS \ + STD_SERIAL_PORT_DEFNS \ + PU32_SERIAL_PORT_DEFNS + +#endif +#endif /* __KERNEL__ */ 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/arch/ppc/platforms/ivms8.h b/arch/ppc/platforms/ivms8.h new file mode 100644 index 000000000000..37c48cbc1c38 --- /dev/null +++ b/arch/ppc/platforms/ivms8.h @@ -0,0 +1,59 @@ +/* + * BK Id: SCCS/s.ivms8.h 1.8 10/26/01 10:14:09 trini + */ +/* + * Speech Design Integrated Voicemail board specific definitions + * - IVMS8 (small, 8 channels) + * - IVML24 (large, 24 channels) + * + * In 2.5 when we force a new bootloader, we can merge these two, and add + * in _MACH_'s for them. -- Tom + * + * Copyright (c) 2000, 2001 Wolfgang Denk (wd@denx.de) + */ + +#ifdef __KERNEL__ +#ifndef __ASM_IVMS8_H__ +#define __ASM_IVMS8_H__ + +#include <linux/config.h> + +#include <asm/ppcboot.h> + +#define IVMS_IMMR_BASE 0xFFF00000 /* phys. addr of IMMR */ +#define IVMS_IMAP_SIZE (64 * 1024) /* size of mapped area */ + +#define IMAP_ADDR IVMS_IMMR_BASE /* phys. base address of IMMR area */ +#define IMAP_SIZE IVMS_IMAP_SIZE /* mapped size of IMMR area */ + +#define PCMCIA_MEM_ADDR ((uint)0xFE100000) +#define PCMCIA_MEM_SIZE ((uint)(64 * 1024)) + +#define FEC_INTERRUPT 9 /* = SIU_LEVEL4 */ +#define IDE0_INTERRUPT 10 /* = IRQ5 */ +#define CPM_INTERRUPT 11 /* = SIU_LEVEL5 (was: SIU_LEVEL2) */ +#define PHY_INTERRUPT 12 /* = IRQ6 */ + +/* override the default number of IDE hardware interfaces */ +#define MAX_HWIFS 1 + +/* + * Definitions for IDE0 Interface + */ +#define IDE0_BASE_OFFSET 0x0000 /* Offset in PCMCIA memory */ +#define IDE0_DATA_REG_OFFSET 0x0000 +#define IDE0_ERROR_REG_OFFSET 0x0081 +#define IDE0_NSECTOR_REG_OFFSET 0x0082 +#define IDE0_SECTOR_REG_OFFSET 0x0083 +#define IDE0_LCYL_REG_OFFSET 0x0084 +#define IDE0_HCYL_REG_OFFSET 0x0085 +#define IDE0_SELECT_REG_OFFSET 0x0086 +#define IDE0_STATUS_REG_OFFSET 0x0087 +#define IDE0_CONTROL_REG_OFFSET 0x0106 +#define IDE0_IRQ_REG_OFFSET 0x000A /* not used */ + +/* We don't use the 8259. */ +#define NR_8259_INTS 0 + +#endif /* __ASM_IVMS8_H__ */ +#endif /* __KERNEL__ */ 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/arch/ppc/platforms/mbx.h b/arch/ppc/platforms/mbx.h new file mode 100644 index 000000000000..e4896dd357f3 --- /dev/null +++ b/arch/ppc/platforms/mbx.h @@ -0,0 +1,98 @@ +/* + * BK Id: SCCS/s.mbx.h 1.11 08/17/01 15:23:17 paulus + */ +/* + * A collection of structures, addresses, and values associated with + * the Motorola MBX boards. This was originally created for the + * MBX860, and probably needs revisions for other boards (like the 821). + * When this file gets out of control, we can split it up into more + * meaningful pieces. + * + * Copyright (c) 1997 Dan Malek (dmalek@jlc.net) + */ +#ifdef __KERNEL__ +#ifndef __MACH_MBX_DEFS +#define __MACH_MBX_DEFS + +#ifndef __ASSEMBLY__ +/* A Board Information structure that is given to a program when + * EPPC-Bug starts it up. + */ +typedef struct bd_info { + unsigned int bi_tag; /* Should be 0x42444944 "BDID" */ + unsigned int bi_size; /* Size of this structure */ + unsigned int bi_revision; /* revision of this structure */ + unsigned int bi_bdate; /* EPPCbug date, i.e. 0x11061997 */ + 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 int bi_clun; /* Boot device controller */ + unsigned int bi_dlun; /* Boot device logical dev */ + + /* These fields are not part of the board information structure + * provided by the boot rom. They are filled in by embed_config.c + * so we have the information consistent with other platforms. + */ + unsigned char bi_enetaddr[6]; + unsigned int bi_baudrate; +} bd_t; + +/* Memory map for the MBX as configured by EPPC-Bug. We could reprogram + * The SIU and PCI bridge, and try to use larger MMU pages, but the + * performance gain is not measureable and it certainly complicates the + * generic MMU model. + * + * In a effort to minimize memory usage for embedded applications, any + * PCI driver or ISA driver must request or map the region required by + * the device. For convenience (and since we can map up to 4 Mbytes with + * a single page table page), the MMU initialization will map the + * NVRAM, Status/Control registers, CPM Dual Port RAM, and the PCI + * Bridge CSRs 1:1 into the kernel address space. + */ +#define PCI_ISA_IO_ADDR ((unsigned)0x80000000) +#define PCI_ISA_IO_SIZE ((uint)(512 * 1024 * 1024)) +#define PCI_IDE_ADDR ((unsigned)0x81000000) +#define PCI_ISA_MEM_ADDR ((unsigned)0xc0000000) +#define PCI_ISA_MEM_SIZE ((uint)(512 * 1024 * 1024)) +#define PCMCIA_MEM_ADDR ((uint)0xe0000000) +#define PCMCIA_MEM_SIZE ((uint)(64 * 1024 * 1024)) +#define PCMCIA_DMA_ADDR ((uint)0xe4000000) +#define PCMCIA_DMA_SIZE ((uint)(64 * 1024 * 1024)) +#define PCMCIA_ATTRB_ADDR ((uint)0xe8000000) +#define PCMCIA_ATTRB_SIZE ((uint)(64 * 1024 * 1024)) +#define PCMCIA_IO_ADDR ((uint)0xec000000) +#define PCMCIA_IO_SIZE ((uint)(64 * 1024 * 1024)) +#define NVRAM_ADDR ((uint)0xfa000000) +#define NVRAM_SIZE ((uint)(1 * 1024 * 1024)) +#define MBX_CSR_ADDR ((uint)0xfa100000) +#define MBX_CSR_SIZE ((uint)(1 * 1024 * 1024)) +#define IMAP_ADDR ((uint)0xfa200000) +#define IMAP_SIZE ((uint)(64 * 1024)) +#define PCI_CSR_ADDR ((uint)0xfa210000) +#define PCI_CSR_SIZE ((uint)(64 * 1024)) + +/* Map additional physical space into well known virtual addresses. Due + * to virtual address mapping, these physical addresses are not accessible + * in a 1:1 virtual to physical mapping. + */ +#define ISA_IO_VIRT_ADDR ((uint)0xfa220000) +#define ISA_IO_VIRT_SIZE ((uint)64 * 1024) + +/* Interrupt assignments. + * These are defined (and fixed) by the MBX hardware implementation. + */ +#define POWER_FAIL_INT SIU_IRQ0 /* Power fail */ +#define TEMP_HILO_INT SIU_IRQ1 /* Temperature sensor */ +#define QSPAN_INT SIU_IRQ2 /* PCI Bridge (DMA CTLR?) */ +#define ISA_BRIDGE_INT SIU_IRQ3 /* All those PC things */ +#define COMM_L_INT SIU_IRQ6 /* MBX Comm expansion connector pin */ +#define STOP_ABRT_INT SIU_IRQ7 /* Stop/Abort header pin */ +#endif /* !__ASSEMBLY__ */ + +/* The MBX uses the 8259. +*/ +#define NR_8259_INTS 16 + +#endif +#endif /* __KERNEL__ */ 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/arch/ppc/platforms/oak.h b/arch/ppc/platforms/oak.h new file mode 100644 index 000000000000..e520182fbf0d --- /dev/null +++ b/arch/ppc/platforms/oak.h @@ -0,0 +1,74 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ +/* + * + * Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu> + * + * Module name: oak.h + * + * Description: + * Macros, definitions, and data structures specific to the IBM PowerPC + * 403G{A,B,C,CX} "Oak" evaluation board. Anything specific to the pro- + * cessor itself is defined elsewhere. + * + */ + +#ifdef __KERNEL__ +#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 +#define PCI_DRAM_OFFSET 0 + +/* Memory map for the "Oak" evaluation board */ + +#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 */ +#define OAKNET_IO_SIZE 0x00000040 +#define OAKPROM_IO_BASE 0xFFFE0000 /* AMD 29F010 Flash ROM */ +#define OAKPROM_IO_SIZE 0x00020000 + + +/* Interrupt assignments fixed by the hardware implementation */ + +/* This is annoying kbuild-2.4 problem. -- Tom */ + +#define PPC403SPU_RX_INT 4 /* AIC_INT4 */ +#define PPC403SPU_TX_INT 5 /* AIC_INT5 */ +#define OAKNET_INT 27 /* AIC_INT27 */ +#define OAKSERIAL_INT 28 /* AIC_INT28 */ + +#ifndef __ASSEMBLY__ +/* + * Data structure defining board information maintained by the boot + * ROM on IBM's "Oak" 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[6]; /* Ethernet MAC address */ + unsigned int bi_intfreq; /* Processor speed, in Hz */ + 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 /* __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/arch/ppc/platforms/rpxclassic.h b/arch/ppc/platforms/rpxclassic.h new file mode 100644 index 000000000000..6fabcd4ae0d4 --- /dev/null +++ b/arch/ppc/platforms/rpxclassic.h @@ -0,0 +1,104 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ + +/* + * A collection of structures, addresses, and values associated with + * the RPCG RPX-Classic board. Copied from the RPX-Lite stuff. + * + * Copyright (c) 1998 Dan Malek (dmalek@jlc.net) + */ +#ifdef __KERNEL__ +#ifndef __MACH_RPX_DEFS +#define __MACH_RPX_DEFS + +#include <linux/config.h> + +#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. + * 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 PCI_ISA_IO_ADDR ((unsigned)0x80000000) +#define PCI_ISA_IO_SIZE ((uint)(512 * 1024 * 1024)) +#define PCI_ISA_MEM_ADDR ((unsigned)0xc0000000) +#define PCI_ISA_MEM_SIZE ((uint)(512 * 1024 * 1024)) +#define RPX_CSR_ADDR ((uint)0xfa400000) +#define RPX_CSR_SIZE ((uint)(4 * 1024)) +#define IMAP_ADDR ((uint)0xfa200000) +#define IMAP_SIZE ((uint)(64 * 1024)) +#define PCI_CSR_ADDR ((uint)0x80000000) +#define PCI_CSR_SIZE ((uint)(64 * 1024)) +#define PCMCIA_MEM_ADDR ((uint)0xe0000000) +#define PCMCIA_MEM_SIZE ((uint)(64 * 1024)) +#define PCMCIA_IO_ADDR ((uint)0xe4000000) +#define PCMCIA_IO_SIZE ((uint)(4 * 1024)) +#define PCMCIA_ATTRB_ADDR ((uint)0xe8000000) +#define PCMCIA_ATTRB_SIZE ((uint)(4 * 1024)) + +/* Things of interest in the CSR. +*/ +#define BCSR0_ETHEN ((uint)0x80000000) +#define BCSR0_ETHLPBK ((uint)0x40000000) +#define BCSR0_COLTESTDIS ((uint)0x20000000) +#define BCSR0_FULLDPLXDIS ((uint)0x10000000) +#define BCSR0_ENFLSHSEL ((uint)0x04000000) +#define BCSR0_FLASH_SEL ((uint)0x02000000) +#define BCSR0_ENMONXCVR ((uint)0x01000000) + +#define BCSR0_PCMCIAVOLT ((uint)0x000f0000) /* CLLF */ +#define BCSR0_PCMCIA3VOLT ((uint)0x000a0000) /* CLLF */ +#define BCSR0_PCMCIA5VOLT ((uint)0x00060000) /* CLLF */ + +#define BCSR1_IPB5SEL ((uint)0x00100000) +#define BCSR1_PCVCTL4 ((uint)0x00080000) +#define BCSR1_PCVCTL5 ((uint)0x00040000) +#define BCSR1_PCVCTL6 ((uint)0x00020000) +#define BCSR1_PCVCTL7 ((uint)0x00010000) + +#define BCSR2_EN232XCVR ((uint)0x00008000) +#define BCSR2_QSPACESEL ((uint)0x00004000) +#define BCSR2_FETHLEDMODE ((uint)0x00000800) /* CLLF */ + +#if defined(CONFIG_HTDMSOUND) +#include <platforms/rpxhiox.h> +#endif + +/* define IO_BASE for pcmcia, CLLF only */ +#if !defined(CONFIG_PCI) +#define _IO_BASE 0x80000000 +#define _IO_BASE_SIZE 0x1000 + +/* for pcmcia sandisk */ +#ifdef CONFIG_IDE +#define MAX_HWIFS 1 +#define ide_request_irq(irq,hand,flg,dev,id) request_8xxirq((irq),(hand),(flg),(dev),(id)) +#endif +#endif + +/* Interrupt level assignments. +*/ +#define FEC_INTERRUPT SIU_LEVEL1 /* FEC interrupt */ + +#endif /* !__ASSEMBLY__ */ + +/* We don't use the 8259. +*/ +#define NR_8259_INTS 0 + +#endif +#endif /* __KERNEL__ */ diff --git a/arch/ppc/platforms/rpxhiox.h b/arch/ppc/platforms/rpxhiox.h new file mode 100644 index 000000000000..848e4eb6fd1e --- /dev/null +++ b/arch/ppc/platforms/rpxhiox.h @@ -0,0 +1,45 @@ +/* + * BK Id: SCCS/s.rpxhiox.h 1.3 05/17/01 18:14:25 cort + */ + +/* + * The Embedded Planet HIOX expansion card definitions. + * There were a few different versions of these cards, but only + * the one that escaped real production is defined here. + * + * Copyright (c) 2000 Dan Malek (dmalek@jlc.net) + */ +#ifndef __MACH_RPX_HIOX_DEFS +#define __MACH_RPX_HIOX_DEFS + +#define HIOX_CSR_ADDR ((uint)0xfac00000) +#define HIOX_CSR_SIZE ((uint)(4 * 1024)) +#define HIOX_CSR0_ADDR HIOX_CSR_ADDR +#define HIOX_CSR4_ADDR ((uint)0xfac00004) + +#define HIOX_CSR0_DEFAULT ((uint)0x380f3c00) +#define HIOX_CSR0_ENSCC2 ((uint)0x80000000) +#define HIOX_CSR0_ENSMC2 ((uint)0x04000000) +#define HIOX_CSR0_ENVDOCLK ((uint)0x02000000) +#define HIOX_CSR0_VDORST_HL ((uint)0x01000000) +#define HIOX_CSR0_RS232SEL ((uint)0x0000c000) +#define HIOX_CSR0_SCC3SEL ((uint)0x0000c000) +#define HIOX_CSR0_SMC1SEL ((uint)0x00008000) +#define HIOX_CSR0_SCC1SEL ((uint)0x00004000) +#define HIOX_CSR0_ENTOUCH ((uint)0x00000080) +#define HIOX_CSR0_PDOWN100 ((uint)0x00000060) +#define HIOX_CSR0_PDOWN10 ((uint)0x00000040) +#define HIOX_CSR0_PDOWN1 ((uint)0x00000020) +#define HIOX_CSR0_TSELSPI ((uint)0x00000010) +#define HIOX_CSR0_TIRQSTAT ((uint)0x00000008) +#define HIOX_CSR4_DEFAULT ((uint)0x00000000) +#define HIOX_CSR4_ENTIRQ2 ((uint)0x20000000) +#define HIOX_CSR4_ENTIRQ3 ((uint)0x10000000) +#define HIOX_CSR4_ENAUDIO ((uint)0x00000080) +#define HIOX_CSR4_RSTAUDIO ((uint)0x00000040) /* 0 == reset */ +#define HIOX_CSR4_AUDCLKHI ((uint)0x00000020) +#define HIOX_CSR4_AUDSPISEL ((uint)0x00000010) +#define HIOX_CSR4_AUDIRQSTAT ((uint)0x00000008) +#define HIOX_CSR4_AUDCLKSEL ((uint)0x00000007) + +#endif diff --git a/arch/ppc/platforms/rpxlite.h b/arch/ppc/platforms/rpxlite.h new file mode 100644 index 000000000000..c07888f2e471 --- /dev/null +++ b/arch/ppc/platforms/rpxlite.h @@ -0,0 +1,84 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ + +/* + * A collection of structures, addresses, and values associated with + * the RPCG RPX-Lite board. Copied from the MBX stuff. + * + * Copyright (c) 1998 Dan Malek (dmalek@jlc.net) + */ +#ifdef __KERNEL__ +#ifndef __MACH_RPX_DEFS +#define __MACH_RPX_DEFS + +#include <linux/config.h> + +#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. + * 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 RPX_CSR_ADDR ((uint)0xfa400000) +#define RPX_CSR_SIZE ((uint)(4 * 1024)) +#define IMAP_ADDR ((uint)0xfa200000) +#define IMAP_SIZE ((uint)(64 * 1024)) +#define PCMCIA_MEM_ADDR ((uint)0x04000000) +#define PCMCIA_MEM_SIZE ((uint)(64 * 1024)) +#define PCMCIA_IO_ADDR ((uint)0x04400000) +#define PCMCIA_IO_SIZE ((uint)(4 * 1024)) + +/* Things of interest in the CSR. +*/ +#define BCSR0_ETHEN ((uint)0x80000000) +#define BCSR0_ETHLPBK ((uint)0x40000000) +#define BCSR0_COLTESTDIS ((uint)0x20000000) +#define BCSR0_FULLDPLXDIS ((uint)0x10000000) +#define BCSR0_LEDOFF ((uint)0x08000000) +#define BCSR0_USBDISABLE ((uint)0x04000000) +#define BCSR0_USBHISPEED ((uint)0x02000000) +#define BCSR0_USBPWREN ((uint)0x01000000) +#define BCSR0_PCMCIAVOLT ((uint)0x000f0000) +#define BCSR0_PCMCIA3VOLT ((uint)0x000a0000) +#define BCSR0_PCMCIA5VOLT ((uint)0x00060000) + +#define BCSR1_IPB5SEL ((uint)0x00100000) +#define BCSR1_PCVCTL4 ((uint)0x00080000) +#define BCSR1_PCVCTL5 ((uint)0x00040000) +#define BCSR1_PCVCTL6 ((uint)0x00020000) +#define BCSR1_PCVCTL7 ((uint)0x00010000) + +#if defined(CONFIG_HTDMSOUND) +#include <platforms/rpxhiox.h> +#endif +#endif /* !__ASSEMBLY__ */ + +/* define IO_BASE for pcmcia */ +#define _IO_BASE 0x80000000 +#define _IO_BASE_SIZE 0x1000 + +#ifdef CONFIG_IDE +#define MAX_HWIFS 1 +#define ide_request_irq(irq,hand,flg,dev,id) request_8xxirq((irq),(hand),(flg),(dev),(id)) +#endif + +/* We don't use the 8259. +*/ +#define NR_8259_INTS 0 + +#endif +#endif /* __KERNEL__ */ 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/arch/ppc/platforms/spd8xx.h b/arch/ppc/platforms/spd8xx.h new file mode 100644 index 000000000000..b6c93bdfd10f --- /dev/null +++ b/arch/ppc/platforms/spd8xx.h @@ -0,0 +1,69 @@ +/* + * BK Id: SCCS/s.spd8xx.h 1.8 10/27/01 13:39:41 trini + */ +/* + * Speech Design SPD8xxTS board specific definitions + * + * Copyright (c) 2000,2001 Wolfgang Denk (wd@denx.de) + */ + +#ifdef __KERNEL__ +#ifndef __ASM_SPD8XX_H__ +#define __ASM_SPD8XX_H__ + +#include <linux/config.h> + +#include <asm/ppcboot.h> + +#define SPD_IMMR_BASE 0xFFF00000 /* phys. addr of IMMR */ +#define SPD_IMAP_SIZE (64 * 1024) /* size of mapped area */ + +#define IMAP_ADDR SPD_IMMR_BASE /* physical base address of IMMR area */ +#define IMAP_SIZE SPD_IMAP_SIZE /* mapped size of IMMR area */ + +#define PCMCIA_MEM_ADDR ((uint)0xFE100000) +#define PCMCIA_MEM_SIZE ((uint)(64 * 1024)) + +#define IDE0_INTERRUPT 10 /* = IRQ5 */ +#define IDE1_INTERRUPT 12 /* = IRQ6 */ +#define CPM_INTERRUPT 13 /* = SIU_LEVEL6 (was: SIU_LEVEL2) */ + +/* override the default number of IDE hardware interfaces */ +#define MAX_HWIFS 2 + +/* + * Definitions for IDE0 Interface + */ +#define IDE0_BASE_OFFSET 0x0000 /* Offset in PCMCIA memory */ +#define IDE0_DATA_REG_OFFSET 0x0000 +#define IDE0_ERROR_REG_OFFSET 0x0081 +#define IDE0_NSECTOR_REG_OFFSET 0x0082 +#define IDE0_SECTOR_REG_OFFSET 0x0083 +#define IDE0_LCYL_REG_OFFSET 0x0084 +#define IDE0_HCYL_REG_OFFSET 0x0085 +#define IDE0_SELECT_REG_OFFSET 0x0086 +#define IDE0_STATUS_REG_OFFSET 0x0087 +#define IDE0_CONTROL_REG_OFFSET 0x0106 +#define IDE0_IRQ_REG_OFFSET 0x000A /* not used */ + +/* + * Definitions for IDE1 Interface + */ +#define IDE1_BASE_OFFSET 0x0C00 /* Offset in PCMCIA memory */ +#define IDE1_DATA_REG_OFFSET 0x0000 +#define IDE1_ERROR_REG_OFFSET 0x0081 +#define IDE1_NSECTOR_REG_OFFSET 0x0082 +#define IDE1_SECTOR_REG_OFFSET 0x0083 +#define IDE1_LCYL_REG_OFFSET 0x0084 +#define IDE1_HCYL_REG_OFFSET 0x0085 +#define IDE1_SELECT_REG_OFFSET 0x0086 +#define IDE1_STATUS_REG_OFFSET 0x0087 +#define IDE1_CONTROL_REG_OFFSET 0x0106 +#define IDE1_IRQ_REG_OFFSET 0x000A /* not used */ + +/* We don't use the 8259. +*/ +#define NR_8259_INTS 0 + +#endif /* __ASM_SPD8XX_H__ */ +#endif /* __KERNEL__ */ 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/arch/ppc/platforms/tqm8xx.h b/arch/ppc/platforms/tqm8xx.h new file mode 100644 index 000000000000..fb5b4df54e8a --- /dev/null +++ b/arch/ppc/platforms/tqm8xx.h @@ -0,0 +1,54 @@ +/* + * BK Id: SCCS/s.tqm8xx.h 1.8 08/30/01 09:01:04 trini + */ +/* + * TQM8xx(L) board specific definitions + * + * Copyright (c) 1999,2000,2001 Wolfgang Denk (wd@denx.de) + */ + +#ifndef __MACH_TQM8xx_H +#define __MACH_TQM8xx_H + +#include <linux/config.h> + +#include <asm/ppcboot.h> + +#define TQM_IMMR_BASE 0xFFF00000 /* phys. addr of IMMR */ +#define TQM_IMAP_SIZE (64 * 1024) /* size of mapped area */ + +#define IMAP_ADDR TQM_IMMR_BASE /* physical base address of IMMR area */ +#define IMAP_SIZE TQM_IMAP_SIZE /* 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 + + +/* We don't use the 8259. +*/ +#define NR_8259_INTS 0 + +#endif /* __MACH_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/arch/ppc/platforms/walnut.h b/arch/ppc/platforms/walnut.h new file mode 100644 index 000000000000..ccf4c5cf732f --- /dev/null +++ b/arch/ppc/platforms/walnut.h @@ -0,0 +1,88 @@ +/* + * + * Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu> + * + * Copyright 2000 MontaVista Software Inc. + * PPC405 modifications + * Author: MontaVista Software, Inc. + * frank_rowand@mvista.com or source@mvista.com + * debbie_chu@mvista.com + * + * Module name: ppc405.h + * + * Description: + * Macros, definitions, and data structures specific to the IBM PowerPC + * based boards. + * + * This includes: + * + * 405GP "Walnut" evaluation board + * + */ + +#ifdef __KERNEL__ +#ifndef __ASM_WALNUT_H__ +#define __ASM_WALNUT_H__ + +/* We have a 405GP core */ +#include <platforms/ibm405gp.h> + +#ifndef __ASSEMBLY__ +/* + * Data structure defining board information maintained by the boot + * ROM on IBM's "Walnut" 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[6]; /* Local Ethernet MAC address */ + unsigned char bi_pci_enetaddr[6]; /* PCI 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 + + +/* Memory map for the IBM "Walnut" 405GP evaluation board. + * Generic 4xx plus RTC. + */ + +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; +} |
