Commit 2a8d04d7 authored by Ralf Bächle's avatar Ralf Bächle Committed by Linus Torvalds

[PATCH] Add support for SGI IP32

This adds support for SGI's O2 workstation aka IP32.
parent 17017b3a
......@@ -3,11 +3,7 @@
# under Linux.
#
extra-y := ip32-irq-glue.o
obj-y += ip32-irq.o ip32-rtc.o ip32-setup.o ip32-irq-glue.o \
ip32-berr.o ip32-timer.o crime.o
obj-$(CONFIG_PCI) += ip32-pci.o ip32-pci-dma.o
obj-y += ip32-berr.o ip32-rtc.o ip32-setup.o ip32-irq.o ip32-irq-glue.o \
ip32-timer.o crime.o ip32-reset.o
EXTRA_AFLAGS := $(CFLAGS)
......@@ -10,7 +10,6 @@
#include <linux/kernel.h>
#include <asm/ip32/crime.h>
#include <asm/ptrace.h>
#include <asm/promlib.h>
void __init crime_init (void)
{
......@@ -29,7 +28,7 @@ void crime_memerr_intr (unsigned int irq, void *dev_id, struct pt_regs *regs)
u64 memerr = crime_read_64 (CRIME_MEM_ERROR_STAT);
u64 addr = crime_read_64 (CRIME_MEM_ERROR_ADDR);
memerr &= CRIME_MEM_ERROR_STAT_MASK;
printk ("CRIME memory error at physaddr 0x%08lx status %08lx\n",
addr << 2, memerr);
......
/*
* 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, 1995, 1996, 1999, 2000 by Ralf Baechle
* Copyright (C) 1999, 2000 by Silicon Graphics
* Copyright (C) 2002 Maciej W. Rozycki
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <asm/traps.h>
#include <asm/uaccess.h>
#include <asm/addrspace.h>
#include <asm/ptrace.h>
#include <asm/tlbdebug.h>
int ip32_be_handler(struct pt_regs *regs, int is_fixup)
{
int data = regs->cp0_cause & 4;
if (is_fixup)
return MIPS_BE_FIXUP;
printk("Got %cbe at 0x%lx\n", data ? 'd' : 'i', regs->cp0_epc);
show_regs(regs);
dump_tlb_all();
while(1);
force_sig(SIGBUS, current);
}
void __init ip32_be_init(void)
{
board_be_handler = ip32_be_handler;
}
......@@ -14,6 +14,11 @@
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/bitops.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/random.h>
#include <linux/sched.h>
#include <asm/bitops.h>
#include <asm/mipsregs.h>
......@@ -110,30 +115,30 @@ struct irqaction cpuerr_irq = { crime_cpuerr_intr, SA_INTERRUPT,
0, "CRIME CPU error", NULL,
NULL };
unsigned long spurious_count = 0;
extern void ip32_handle_int (void);
extern void do_IRQ (unsigned int irq, struct pt_regs *regs);
/* For interrupts wired from a single device to the CPU. Only the clock
/*
* For interrupts wired from a single device to the CPU. Only the clock
* uses this it seems, which is IRQ 0 and IP7.
*/
static void enable_cpu_irq (unsigned int irq)
static void enable_cpu_irq(unsigned int irq)
{
set_cp0_status (STATUSF_IP7);
set_c0_status(STATUSF_IP7);
}
static unsigned int startup_cpu_irq (unsigned int irq) {
enable_cpu_irq (irq);
static unsigned int startup_cpu_irq(unsigned int irq)
{
enable_cpu_irq(irq);
return 0;
}
static void disable_cpu_irq (unsigned int irq)
static void disable_cpu_irq(unsigned int irq)
{
clear_cp0_status (STATUSF_IP7);
clear_c0_status(STATUSF_IP7);
}
static void end_cpu_irq (unsigned int irq)
static void end_cpu_irq(unsigned int irq)
{
if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
enable_cpu_irq (irq);
......@@ -158,34 +163,34 @@ static struct hw_interrupt_type ip32_cpu_interrupt = {
* We get to split the register in half and do faster lookups.
*/
static void enable_crime_irq (unsigned int irq)
static void enable_crime_irq(unsigned int irq)
{
u64 crime_mask;
unsigned long flags;
save_and_cli (flags);
crime_mask = crime_read_64 (CRIME_INT_MASK);
local_irq_save(flags);
crime_mask = crime_read_64(CRIME_INT_MASK);
crime_mask |= 1 << (irq - 1);
crime_write_64 (CRIME_INT_MASK, crime_mask);
restore_flags (flags);
crime_write_64(CRIME_INT_MASK, crime_mask);
local_irq_restore(flags);
}
static unsigned int startup_crime_irq (unsigned int irq)
static unsigned int startup_crime_irq(unsigned int irq)
{
enable_crime_irq (irq);
enable_crime_irq(irq);
return 0; /* This is probably not right; we could have pending irqs */
}
static void disable_crime_irq (unsigned int irq)
static void disable_crime_irq(unsigned int irq)
{
u64 crime_mask;
unsigned long flags;
save_and_cli (flags);
crime_mask = crime_read_64 (CRIME_INT_MASK);
local_irq_save(flags);
crime_mask = crime_read_64(CRIME_INT_MASK);
crime_mask &= ~(1 << (irq - 1));
crime_write_64 (CRIME_INT_MASK, crime_mask);
restore_flags (flags);
crime_write_64(CRIME_INT_MASK, crime_mask);
local_irq_restore(flags);
}
static void mask_and_ack_crime_irq (unsigned int irq)
......@@ -194,19 +199,19 @@ static void mask_and_ack_crime_irq (unsigned int irq)
unsigned long flags;
/* Edge triggered interrupts must be cleared. */
if ((irq <= CRIME_GBE0_IRQ && irq >= CRIME_GBE3_IRQ)
|| (irq <= CRIME_RE_EMPTY_E_IRQ && irq >= CRIME_RE_IDLE_E_IRQ)
|| (irq <= CRIME_SOFT0_IRQ && irq >= CRIME_SOFT2_IRQ)) {
save_and_cli (flags);
crime_mask = crime_read_64 (CRIME_HARD_INT);
if ((irq >= CRIME_GBE0_IRQ && irq <= CRIME_GBE3_IRQ)
|| (irq >= CRIME_RE_EMPTY_E_IRQ && irq <= CRIME_RE_IDLE_E_IRQ)
|| (irq >= CRIME_SOFT0_IRQ && irq <= CRIME_SOFT2_IRQ)) {
local_irq_save(flags);
crime_mask = crime_read_64(CRIME_HARD_INT);
crime_mask &= ~(1 << (irq - 1));
crime_write_64 (CRIME_HARD_INT, crime_mask);
restore_flags (flags);
crime_write_64(CRIME_HARD_INT, crime_mask);
local_irq_restore(flags);
}
disable_crime_irq (irq);
disable_crime_irq(irq);
}
static void end_crime_irq (unsigned int irq)
static void end_crime_irq(unsigned int irq)
{
if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
enable_crime_irq (irq);
......@@ -225,48 +230,52 @@ static struct hw_interrupt_type ip32_crime_interrupt = {
NULL
};
/* This is for MACE PCI interrupts. We can decrease bus traffic by masking
/*
* This is for MACE PCI interrupts. We can decrease bus traffic by masking
* as close to the source as possible. This also means we can take the
* next chunk of the CRIME register in one piece.
*/
static void enable_macepci_irq (unsigned int irq)
static void enable_macepci_irq(unsigned int irq)
{
u32 mace_mask;
u64 crime_mask;
unsigned long flags;
save_and_cli (flags);
mace_mask = mace_read_32 (MACEPCI_CONTROL);
mace_mask |= MACEPCI_CONTROL_INT (irq - 9);
mace_write_32 (MACEPCI_CONTROL, mace_mask);
/* In case the CRIME interrupt isn't enabled, we must enable it;
local_irq_save(flags);
mace_mask = mace_read_32(MACEPCI_CONTROL);
mace_mask |= MACEPCI_CONTROL_INT(irq - 9);
mace_write_32(MACEPCI_CONTROL, mace_mask);
/*
* In case the CRIME interrupt isn't enabled, we must enable it;
* however, we never disable interrupts at that level.
*/
crime_mask = crime_read_64 (CRIME_INT_MASK);
crime_mask = crime_read_64(CRIME_INT_MASK);
crime_mask |= 1 << (irq - 1);
crime_write_64 (CRIME_INT_MASK, crime_mask);
restore_flags (flags);
crime_write_64(CRIME_INT_MASK, crime_mask);
local_irq_restore(flags);
}
static unsigned int startup_macepci_irq (unsigned int irq) {
static unsigned int startup_macepci_irq(unsigned int irq)
{
enable_macepci_irq (irq);
return 0; /* XXX */
}
static void disable_macepci_irq (unsigned int irq)
static void disable_macepci_irq(unsigned int irq)
{
u32 mace_mask;
unsigned long flags;
save_and_cli (flags);
mace_mask = mace_read_32 (MACEPCI_CONTROL);
mace_mask &= ~MACEPCI_CONTROL_INT (irq - 9);
mace_write_32 (MACEPCI_CONTROL, mace_mask);
restore_flags (flags);
local_irq_save(flags);
mace_mask = mace_read_32(MACEPCI_CONTROL);
mace_mask &= ~MACEPCI_CONTROL_INT(irq - 9);
mace_write_32(MACEPCI_CONTROL, mace_mask);
local_irq_restore(flags);
}
static void end_macepci_irq (unsigned int irq)
static void end_macepci_irq(unsigned int irq)
{
if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
enable_macepci_irq (irq);
......@@ -298,7 +307,7 @@ static void enable_maceisa_irq (unsigned int irq)
unsigned long flags;
DBG ("maceisa enable: %u\n", irq);
switch (irq) {
case MACEISA_AUDIO_SW_IRQ ... MACEISA_AUDIO3_MERR_IRQ:
crime_int = MACE_AUDIO_INT;
......@@ -311,34 +320,35 @@ static void enable_maceisa_irq (unsigned int irq)
break;
}
DBG ("crime_int %016lx enabled\n", crime_int);
save_and_cli (flags);
crime_mask = crime_read_64 (CRIME_INT_MASK);
local_irq_save(flags);
crime_mask = crime_read_64(CRIME_INT_MASK);
crime_mask |= crime_int;
crime_write_64 (CRIME_INT_MASK, crime_mask);
mace_mask = mace_read_32 (MACEISA_INT_MASK);
crime_write_64(CRIME_INT_MASK, crime_mask);
mace_mask = mace_read_32(MACEISA_INT_MASK);
mace_mask |= 1 << (irq - 33);
mace_write_32 (MACEISA_INT_MASK, mace_mask);
restore_flags (flags);
mace_write_32(MACEISA_INT_MASK, mace_mask);
local_irq_restore(flags);
}
static unsigned int startup_maceisa_irq (unsigned int irq) {
enable_maceisa_irq (irq);
static unsigned int startup_maceisa_irq (unsigned int irq)
{
enable_maceisa_irq(irq);
return 0;
}
static void disable_maceisa_irq (unsigned int irq)
static void disable_maceisa_irq(unsigned int irq)
{
u32 mace_mask;
unsigned long flags;
save_and_cli (flags);
mace_mask = mace_read_32 (MACEISA_INT_MASK);
local_irq_save(flags);
mace_mask = mace_read_32(MACEISA_INT_MASK);
mace_mask &= ~(1 << (irq - 33));
mace_write_32 (MACEISA_INT_MASK, mace_mask);
restore_flags (flags);
mace_write_32(MACEISA_INT_MASK, mace_mask);
local_irq_restore(flags);
}
static void mask_and_ack_maceisa_irq (unsigned int irq)
static void mask_and_ack_maceisa_irq(unsigned int irq)
{
u32 mace_mask;
unsigned long flags;
......@@ -347,17 +357,17 @@ static void mask_and_ack_maceisa_irq (unsigned int irq)
case MACEISA_PARALLEL_IRQ:
case MACEISA_SERIAL1_TDMAPR_IRQ:
case MACEISA_SERIAL2_TDMAPR_IRQ:
save_and_cli (flags);
mace_mask = mace_read_32 (MACEISA_INT_STAT);
local_irq_save(flags);
mace_mask = mace_read_32(MACEISA_INT_STAT);
mace_mask &= ~(1 << (irq - 33));
mace_write_32 (MACEISA_INT_STAT, mace_mask);
restore_flags (flags);
mace_write_32(MACEISA_INT_STAT, mace_mask);
local_irq_restore(flags);
break;
}
disable_maceisa_irq (irq);
disable_maceisa_irq(irq);
}
static void end_maceisa_irq (unsigned irq)
static void end_maceisa_irq(unsigned irq)
{
if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
enable_maceisa_irq (irq);
......@@ -380,37 +390,37 @@ static struct hw_interrupt_type ip32_maceisa_interrupt = {
* bits 0-3 and 7 in the CRIME register.
*/
static void enable_mace_irq (unsigned int irq)
static void enable_mace_irq(unsigned int irq)
{
u64 crime_mask;
unsigned long flags;
save_and_cli (flags);
local_irq_save(flags);
crime_mask = crime_read_64 (CRIME_INT_MASK);
crime_mask |= 1 << (irq - 1);
crime_write_64 (CRIME_INT_MASK, crime_mask);
restore_flags (flags);
local_irq_restore (flags);
}
static unsigned int startup_mace_irq (unsigned int irq)
static unsigned int startup_mace_irq(unsigned int irq)
{
enable_mace_irq (irq);
enable_mace_irq(irq);
return 0;
}
static void disable_mace_irq (unsigned int irq)
static void disable_mace_irq(unsigned int irq)
{
u64 crime_mask;
unsigned long flags;
save_and_cli (flags);
local_irq_save(flags);
crime_mask = crime_read_64 (CRIME_INT_MASK);
crime_mask &= ~(1 << (irq - 1));
crime_write_64 (CRIME_INT_MASK, crime_mask);
restore_flags (flags);
local_irq_restore(flags);
}
static void end_mace_irq (unsigned int irq)
static void end_mace_irq(unsigned int irq)
{
if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
enable_mace_irq (irq);
......@@ -434,11 +444,11 @@ static void ip32_unknown_interrupt (struct pt_regs *regs)
{
u64 crime;
u32 mace;
printk ("Unknown interrupt occurred!\n");
printk ("cp0_status: %08x\tcp0_cause: %08x\n",
read_32bit_cp0_register (CP0_STATUS),
read_32bit_cp0_register (CP0_CAUSE));
read_c0_status(),
read_c0_cause());
crime = crime_read_64 (CRIME_INT_MASK);
printk ("CRIME interrupt mask: %016lx\n", crime);
crime = crime_read_64 (CRIME_INT_STAT);
......@@ -452,60 +462,29 @@ static void ip32_unknown_interrupt (struct pt_regs *regs)
mace = mace_read_32 (MACEPCI_CONTROL);
printk ("MACE PCI control register: %08x\n", mace);
printk ("Register dump:\n");
show_regs (regs);
printk("Register dump:\n");
show_regs(regs);
printk ("Please mail this report to linux-mips@oss.sgi.com\n");
printk ("Spinning...");
while (1) ;
printk("Please mail this report to linux-mips@oss.sgi.com\n");
printk("Spinning...");
while(1) ;
}
void __init ip32_irq_init(void)
/* CRIME 1.1 appears to deliver all interrupts to this one pin. */
void ip32_irq0(struct pt_regs *regs)
{
unsigned int irq;
extern void init_generic_irq (void);
/* Install our interrupt handler, then clear and disable all
* CRIME and MACE interrupts.
*/
crime_write_64 (CRIME_INT_MASK, 0);
crime_write_64 (CRIME_HARD_INT, 0);
crime_write_64 (CRIME_SOFT_INT, 0);
mace_write_32 (MACEISA_INT_STAT, 0);
mace_write_32 (MACEISA_INT_MASK, 0);
set_except_vector(0, ip32_handle_int);
init_generic_irq ();
u64 crime_int;
u64 crime_mask;
int irq = 0;
unsigned long flags;
for (irq = 0; irq <= IP32_IRQ_MAX; irq++) {
hw_irq_controller *controller;
local_irq_save(flags);
/* disable crime interrupts */
crime_mask = crime_read_64(CRIME_INT_MASK);
crime_write_64(CRIME_INT_MASK, 0);
if (irq == CLOCK_IRQ)
controller = &ip32_cpu_interrupt;
else if (irq <= MACE_PCI_BRIDGE_IRQ && irq >= MACE_VID_IN1_IRQ)
controller = &ip32_mace_interrupt;
else if (irq <= MACEPCI_SHARED2_IRQ && irq >= MACEPCI_SCSI0_IRQ)
controller = &ip32_macepci_interrupt;
else if (irq <= CRIME_VICE_IRQ && irq >= CRIME_GBE0_IRQ)
controller = &ip32_crime_interrupt;
else
controller = &ip32_maceisa_interrupt;
crime_int = crime_read_64(CRIME_INT_STAT);
irq_desc[irq].status = IRQ_DISABLED;
irq_desc[irq].action = 0;
irq_desc[irq].depth = 0;
irq_desc[irq].handler = controller;
}
setup_irq (CRIME_MEMERR_IRQ, &memerr_irq);
setup_irq (CRIME_CPUERR_IRQ, &cpuerr_irq);
}
/* CRIME 1.1 appears to deliver all interrupts to this one pin. */
void ip32_irq0 (struct pt_regs *regs)
{
u64 crime_int = crime_read_64 (CRIME_INT_STAT);
int irq = 0;
if (crime_int & CRIME_MACE_INT_MASK) {
crime_int &= CRIME_MACE_INT_MASK;
irq = ffs (crime_int);
......@@ -525,32 +504,81 @@ void ip32_irq0 (struct pt_regs *regs)
irq = ffs (crime_int) + 16;
}
if (irq == 0)
ip32_unknown_interrupt (regs);
DBG ("*irq %u*\n", irq);
do_IRQ (irq, regs);
ip32_unknown_interrupt(regs);
DBG("*irq %u*\n", irq);
do_IRQ(irq, regs);
/* enable crime interrupts */
crime_write_64(CRIME_INT_MASK, crime_mask);
local_irq_restore (flags);
}
void ip32_irq1 (struct pt_regs *regs)
void ip32_irq1(struct pt_regs *regs)
{
ip32_unknown_interrupt (regs);
}
void ip32_irq2 (struct pt_regs *regs)
void ip32_irq2(struct pt_regs *regs)
{
ip32_unknown_interrupt (regs);
}
void ip32_irq3 (struct pt_regs *regs)
void ip32_irq3(struct pt_regs *regs)
{
ip32_unknown_interrupt (regs);
}
void ip32_irq4 (struct pt_regs *regs)
void ip32_irq4(struct pt_regs *regs)
{
ip32_unknown_interrupt (regs);
}
void ip32_irq5 (struct pt_regs *regs)
void ip32_irq5(struct pt_regs *regs)
{
do_IRQ (CLOCK_IRQ, regs);
}
void __init init_IRQ(void)
{
unsigned int irq;
int i;
/* Install our interrupt handler, then clear and disable all
* CRIME and MACE interrupts.
*/
crime_write_64(CRIME_INT_MASK, 0);
crime_write_64(CRIME_HARD_INT, 0);
crime_write_64(CRIME_SOFT_INT, 0);
mace_write_32(MACEISA_INT_STAT, 0);
mace_write_32(MACEISA_INT_MASK, 0);
set_except_vector(0, ip32_handle_int);
for (i = 0; i < NR_IRQS; i++) {
irq_desc[i].status = IRQ_DISABLED;
irq_desc[i].action = NULL;
irq_desc[i].depth = 1;
irq_desc[i].handler = &no_irq_type;
}
for (irq = 0; irq <= IP32_IRQ_MAX; irq++) {
hw_irq_controller *controller;
if (irq == CLOCK_IRQ)
controller = &ip32_cpu_interrupt;
else if (irq <= MACE_PCI_BRIDGE_IRQ && irq >= MACE_VID_IN1_IRQ)
controller = &ip32_mace_interrupt;
else if (irq <= MACEPCI_SHARED2_IRQ && irq >= MACEPCI_SCSI0_IRQ)
controller = &ip32_macepci_interrupt;
else if (irq <= CRIME_VICE_IRQ && irq >= CRIME_GBE0_IRQ)
controller = &ip32_crime_interrupt;
else
controller = &ip32_maceisa_interrupt;
irq_desc[irq].status = IRQ_DISABLED;
irq_desc[irq].action = 0;
irq_desc[irq].depth = 0;
irq_desc[irq].handler = controller;
}
setup_irq(CRIME_MEMERR_IRQ, &memerr_irq);
setup_irq(CRIME_CPUERR_IRQ, &cpuerr_irq);
}
/*
* 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) 2001 Keith M Wesolowski
* Copyright (C) 2001 Paul Mundt
* Copyright (C) 2003 Guido Guenther <agx@sigxcpu.org>
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/notifier.h>
#include <linux/delay.h>
#include <linux/ds17287rtc.h>
#include <asm/irq.h>
#include <asm/reboot.h>
#include <asm/sgialib.h>
#include <asm/addrspace.h>
#include <asm/types.h>
#include <asm/system.h>
#include <asm/wbflush.h>
#include <asm/ip32/ip32_ints.h>
#define POWERDOWN_TIMEOUT 120
/*
* Blink frequency during reboot grace period and when paniced.
*/
#define POWERDOWN_FREQ (HZ / 4)
#define PANIC_FREQ (HZ / 8)
static struct timer_list power_timer, blink_timer, debounce_timer;
static int shuting_down = 0, has_paniced = 0;
static void ip32_machine_restart(char *command) __attribute__((noreturn));
static void ip32_machine_halt(void) __attribute__((noreturn));
static void ip32_machine_power_off(void) __attribute__((noreturn));
static void ip32_machine_restart(char *cmd)
{
if (shuting_down)
ip32_machine_power_off();
ArcReboot();
}
static inline void ip32_machine_halt(void)
{
if (shuting_down)
ip32_machine_power_off();
ArcEnterInteractiveMode();
}
static void ip32_machine_power_off(void)
{
volatile unsigned char reg_a, xctrl_a, xctrl_b;
disable_irq(MACEISA_RTC_IRQ);
reg_a = CMOS_READ(RTC_REG_A);
/* setup for kickstart & wake-up (DS12287 Ref. Man. p. 19) */
reg_a &= ~DS_REGA_DV2;
reg_a |= DS_REGA_DV1;
CMOS_WRITE(reg_a | DS_REGA_DV0, RTC_REG_A);
wbflush();
xctrl_b = CMOS_READ(DS_B1_XCTRL4B)
| DS_XCTRL4B_ABE | DS_XCTRL4B_KFE;
CMOS_WRITE(xctrl_b, DS_B1_XCTRL4B);
xctrl_a = CMOS_READ(DS_B1_XCTRL4A) & ~DS_XCTRL4A_IFS;
CMOS_WRITE(xctrl_a, DS_B1_XCTRL4A);
wbflush();
/* adios amigos... */
CMOS_WRITE(xctrl_a | DS_XCTRL4A_PAB, DS_B1_XCTRL4A);
CMOS_WRITE(reg_a, RTC_REG_A);
wbflush();
while(1) {
printk(KERN_DEBUG "Power off!\n");
}
}
static void power_timeout(unsigned long data)
{
ip32_machine_power_off();
}
static void blink_timeout(unsigned long data)
{
u64 mc_led = mace_read_64(MACEISA_FLASH_NIC_REG);
mc_led ^= MACEISA_LED_RED;
mace_write_64(MACEISA_FLASH_NIC_REG, mc_led);
mod_timer(&blink_timer, jiffies+data);
}
static void debounce(unsigned long data)
{
volatile unsigned char reg_a,reg_c,xctrl_a;
reg_c = CMOS_READ(RTC_INTR_FLAGS);
CMOS_WRITE(reg_a | DS_REGA_DV0, RTC_REG_A);
wbflush();
xctrl_a = CMOS_READ(DS_B1_XCTRL4A);
if( (xctrl_a & DS_XCTRL4A_IFS ) || ( reg_c & RTC_IRQF ) ) {
/* Interrupt still being sent. */
debounce_timer.expires = jiffies + 50;
add_timer(&debounce_timer);
/* clear interrupt source */
CMOS_WRITE( xctrl_a & ~DS_XCTRL4A_IFS, DS_B1_XCTRL4A);
CMOS_WRITE(reg_a & ~DS_REGA_DV0, RTC_REG_A);
return;
}
CMOS_WRITE(reg_a & ~DS_REGA_DV0, RTC_REG_A);
if (has_paniced)
ArcReboot();
enable_irq(MACEISA_RTC_IRQ);
}
static inline void ip32_power_button(void)
{
if (has_paniced)
return;
if (shuting_down || kill_proc(1, SIGINT, 1)) {
/* No init process or button pressed twice. */
ip32_machine_power_off();
}
shuting_down = 1;
blink_timer.data = POWERDOWN_FREQ;
blink_timeout(POWERDOWN_FREQ);
init_timer(&power_timer);
power_timer.function = power_timeout;
power_timer.expires = jiffies + POWERDOWN_TIMEOUT * HZ;
add_timer(&power_timer);
}
static void ip32_rtc_int(int irq, void *dev_id, struct pt_regs *regs)
{
volatile unsigned char reg_c;
reg_c = CMOS_READ(RTC_INTR_FLAGS);
if( ! (reg_c & RTC_IRQF) ) {
printk(KERN_WARNING
"%s: RTC IRQ without RTC_IRQF\n", __FUNCTION__);
}
/* Wait until interrupt goes away */
disable_irq(MACEISA_RTC_IRQ);
init_timer(&debounce_timer);
debounce_timer.function = debounce;
debounce_timer.expires = jiffies + 50;
add_timer(&debounce_timer);
printk(KERN_DEBUG "Power button pressed\n");
ip32_power_button();
}
static int panic_event(struct notifier_block *this, unsigned long event,
void *ptr)
{
u64 mc_led;
if (has_paniced)
return NOTIFY_DONE;
has_paniced = 1;
/* turn off the green LED */
mc_led = mace_read_64(MACEISA_FLASH_NIC_REG);
mc_led |= MACEISA_LED_GREEN;
mace_write_64(MACEISA_FLASH_NIC_REG, mc_led);
blink_timer.data = PANIC_FREQ;
blink_timeout(PANIC_FREQ);
return NOTIFY_DONE;
}
static struct notifier_block panic_block = {
.notifier_call = panic_event,
};
static __init int ip32_reboot_setup(void)
{
u64 mc_led = mace_read_64(MACEISA_FLASH_NIC_REG);
_machine_restart = ip32_machine_restart;
_machine_halt = ip32_machine_halt;
_machine_power_off = ip32_machine_power_off;
request_irq(MACEISA_RTC_IRQ, ip32_rtc_int, 0, "rtc", NULL);
init_timer(&blink_timer);
blink_timer.function = blink_timeout;
notifier_chain_register(&panic_notifier_list, &panic_block);
/* turn on the green led only */
mc_led |= MACEISA_LED_RED;
mc_led &= ~MACEISA_LED_GREEN;
mace_write_64(MACEISA_FLASH_NIC_REG, mc_led);
return 0;
}
subsys_initcall(ip32_reboot_setup);
......@@ -7,27 +7,60 @@
*
* Copyright (C) 2000 Harald Koerfgen
*/
#include <linux/config.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/mc146818rtc.h>
#include <linux/param.h>
#include <linux/init.h>
#include <linux/irq.h>
#include <asm/time.h>
#include <asm/mipsregs.h>
#include <asm/bootinfo.h>
#include <asm/irq.h>
#include <asm/mmu_context.h>
#include <asm/ip32/crime.h>
#include <asm/ip32/mace.h>
#include <asm/ip32/ip32_ints.h>
#include <asm/sgialib.h>
#include <asm/traps.h>
extern struct rtc_ops ip32_rtc_ops;
extern u32 cc_interval;
void __init ip32_init (int argc, char **argv, char **envp) {
arc_meminit ();
#ifdef CONFIG_SGI_O2MACE_ETH
/*
* This is taken care of in here 'cause they say using Arc later on is
* problematic
*/
extern char o2meth_eaddr[8];
static inline unsigned char str2hexnum(unsigned char c)
{
if (c >= '0' && c <= '9')
return c - '0';
if (c >= 'a' && c <= 'f')
return c - 'a' + 10;
return 0; /* foo */
}
static inline void str2eaddr(unsigned char *ea, unsigned char *str)
{
int i;
for (i = 0; i < 6; i++) {
unsigned char num;
if(*str == ':')
str++;
num = str2hexnum(*str++) << 4;
num |= (str2hexnum(*str++));
ea[i] = num;
}
}
#endif
extern void ip32_time_init(void);
extern void ip32_reboot_setup(void);
void __init ip32_setup(void)
{
......@@ -36,6 +69,8 @@ void __init ip32_setup(void)
#endif
TLBMISS_HANDLER_SETUP ();
mips_io_port_base = UNCACHEDADDR(MACEPCI_HI_IO);;
#ifdef CONFIG_SERIAL_CONSOLE
ctype = ArcGetEnvironmentVariable("console");
if (*ctype == 'd') {
......@@ -45,12 +80,20 @@ void __init ip32_setup(void)
console_setup ("ttyS0");
}
#endif
#ifdef CONFIG_SGI_O2MACE_ETH
{
char *mac=ArcGetEnvironmentVariable("eaddr");
str2eaddr(o2meth_eaddr, mac);
}
#endif
#ifdef CONFIG_VT
conswitchp = &dummy_con;
#endif
rtc_ops = &ip32_rtc_ops;
board_be_init = ip32_be_init;
board_time_init = ip32_time_init;
crime_init ();
}
......
/*
* IP32 timer calibration
*
* 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) 2001 Keith M Wesolowski
*/
#include <linux/bcd.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/param.h>
#include <linux/string.h>
#include <linux/interrupt.h>
#include <linux/kernel_stat.h>
#include <linux/mc146818rtc.h>
#include <linux/timex.h>
#include <asm/mipsregs.h>
#include <asm/param.h>
#include <asm/ip32/crime.h>
#include <asm/ip32/ip32_ints.h>
#include <asm/bootinfo.h>
#include <asm/cpu.h>
#include <asm/mipsregs.h>
#include <asm/io.h>
#include <asm/irq.h>
extern volatile unsigned long wall_jiffies;
u32 cc_interval;
/* Cycle counter value at the previous timer interrupt.. */
static unsigned int timerhi, timerlo;
/* An arbitrary time; this can be decreased if reliability looks good */
#define WAIT_MS 10
#define PER_MHZ (1000000 / 2 / HZ)
/*
* Change this if you have some constant time drift
*/
#define USECS_PER_JIFFY (1000000/HZ)
void __init ip32_timer_setup (struct irqaction *irq)
{
u64 crime_time;
u32 cc_tick;
printk("Calibrating system timer... ");
crime_time = crime_read_64 (CRIME_TIME) & CRIME_TIME_MASK;
cc_tick = read_c0_count();
while ((crime_read_64 (CRIME_TIME) & CRIME_TIME_MASK) - crime_time
< WAIT_MS * 1000000 / CRIME_NS_PER_TICK)
;
cc_tick = read_c0_count() - cc_tick;
cc_interval = cc_tick / HZ * (1000 / WAIT_MS);
/* The round-off seems unnecessary; in testing, the error of the
* above procedure is < 100 ticks, which means it gets filtered
* out by the HZ adjustment.
*/
cc_interval = (cc_interval / PER_MHZ) * PER_MHZ;
printk("%d MHz CPU detected\n", (int) (cc_interval / PER_MHZ));
setup_irq (CLOCK_IRQ, irq);
}
struct irqaction irq0 = { NULL, SA_INTERRUPT, 0,
"timer", NULL, NULL};
void cc_timer_interrupt(int irq, void *dev_id, struct pt_regs * regs)
{
u32 count;
/*
* The cycle counter is only 32 bit which is good for about
* a minute at current count rates of upto 150MHz or so.
*/
count = read_c0_count();
timerhi += (count < timerlo); /* Wrap around */
timerlo = count;
write_c0_compare(
(u32) (count + cc_interval));
kstat_cpu(0).irqs[irq]++;
do_timer (regs);
if (!jiffies)
{
/*
* If jiffies has overflowed in this timer_interrupt we must
* update the timer[hi]/[lo] to make do_fast_gettimeoffset()
* quotient calc still valid. -arca
*/
timerhi = timerlo = 0;
}
}
/*
* On MIPS only R4000 and better have a cycle counter.
*
* FIXME: Does playing with the RP bit in c0_status interfere with this code?
*/
static unsigned long do_gettimeoffset(void)
{
u32 count;
unsigned long res, tmp;
/* Last jiffy when do_fast_gettimeoffset() was called. */
static unsigned long last_jiffies;
u32 quotient;
/*
* Cached "1/(clocks per usec)*2^32" value.
* It has to be recalculated once each jiffy.
*/
static u32 cached_quotient;
tmp = jiffies;
quotient = cached_quotient;
if (tmp && last_jiffies != tmp) {
last_jiffies = tmp;
__asm__(".set\tnoreorder\n\t"
".set\tnoat\n\t"
".set\tmips3\n\t"
"lwu\t%0,%2\n\t"
"dsll32\t$1,%1,0\n\t"
"or\t$1,$1,%0\n\t"
"ddivu\t$0,$1,%3\n\t"
"mflo\t$1\n\t"
"dsll32\t%0,%4,0\n\t"
"nop\n\t"
"ddivu\t$0,%0,$1\n\t"
"mflo\t%0\n\t"
".set\tmips0\n\t"
".set\tat\n\t"
".set\treorder"
:"=&r" (quotient)
:"r" (timerhi),
"m" (timerlo),
"r" (tmp),
"r" (USECS_PER_JIFFY)
:"$1");
cached_quotient = quotient;
}
/* Get last timer tick in absolute kernel time */
count = read_c0_count();
/* .. relative to previous jiffy (32 bits is enough) */
count -= timerlo;
__asm__("multu\t%1,%2\n\t"
"mfhi\t%0"
:"=r" (res)
:"r" (count),
"r" (quotient));
/*
* Due to possible jiffies inconsistencies, we need to check
* the result so that we'll get a timer that is monotonic.
*/
if (res >= USECS_PER_JIFFY)
res = USECS_PER_JIFFY-1;
return res;
}
void __init ip32_time_init(void)
{
unsigned int epoch = 0, year, mon, day, hour, min, sec;
int i;
/* The Linux interpretation of the CMOS clock register contents:
* When the Update-In-Progress (UIP) flag goes from 1 to 0, the
* RTC registers show the second which has precisely just started.
* Let's hope other operating systems interpret the RTC the same way.
*/
/* read RTC exactly on falling edge of update flag */
for (i = 0 ; i < 1000000 ; i++) /* may take up to 1 second... */
if (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP)
break;
for (i = 0 ; i < 1000000 ; i++) /* must try at least 2.228 ms */
if (!(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP))
break;
do { /* Isn't this overkill ? UIP above should guarantee consistency */
sec = CMOS_READ(RTC_SECONDS);
min = CMOS_READ(RTC_MINUTES);
hour = CMOS_READ(RTC_HOURS);
day = CMOS_READ(RTC_DAY_OF_MONTH);
mon = CMOS_READ(RTC_MONTH);
year = CMOS_READ(RTC_YEAR);
} while (sec != CMOS_READ(RTC_SECONDS));
if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
sec = BCD2BIN(sec);
min = BCD2BIN(min);
hour = BCD2BIN(hour);
day = BCD2BIN(day);
mon = BCD2BIN(mon);
year = BCD2BIN(year);
}
/* Attempt to guess the epoch. This is the same heuristic as in
* rtc.c so no stupid things will happen to timekeeping. Who knows,
* maybe Ultrix also uses 1952 as epoch ...
*/
if (year > 10 && year < 44)
epoch = 1980;
else if (year < 96)
epoch = 1952;
year += epoch;
write_seqlock_irq(&xtime_lock);
xtime.tv_sec = mktime(year, mon, day, hour, min, sec);
xtime.tv_nsec = 0;
write_sequnlock_irq(&xtime_lock);
write_c0_count(0);
irq0.handler = cc_timer_interrupt;
ip32_timer_setup (&irq0);
#define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5)
/* Set ourselves up for future interrupts */
write_c0_compare(
read_c0_count()
+ cc_interval);
change_c0_status(ST0_IM, ALLINTS);
sti ();
}
#
# Automatically generated make config: don't edit
#
CONFIG_MIPS=y
# CONFIG_MIPS32 is not set
CONFIG_MIPS64=y
#
# Code maturity level options
#
CONFIG_EXPERIMENTAL=y
#
# General setup
#
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
CONFIG_BSD_PROCESS_ACCT=y
CONFIG_SYSCTL=y
CONFIG_LOG_BUF_SHIFT=14
# CONFIG_EMBEDDED is not set
CONFIG_FUTEX=y
CONFIG_EPOLL=y
#
# Loadable module support
#
# CONFIG_MODULES is not set
#
# Machine selection
#
# CONFIG_ACER_PICA_61 is not set
# CONFIG_CASIO_E55 is not set
# CONFIG_MIPS_COBALT is not set
# CONFIG_DECSTATION is not set
# CONFIG_MIPS_EV64120 is not set
# CONFIG_MIPS_EV96100 is not set
# CONFIG_MIPS_IVR is not set
# CONFIG_LASAT is not set
# CONFIG_HP_LASERJET is not set
# CONFIG_IBM_WORKPAD is not set
# CONFIG_MIPS_ITE8172 is not set
# CONFIG_MIPS_ATLAS is not set
# CONFIG_MIPS_MAGNUM_4000 is not set
# CONFIG_MIPS_MALTA is not set
# CONFIG_MIPS_SEAD is not set
# CONFIG_MOMENCO_OCELOT is not set
# CONFIG_MOMENCO_OCELOT_G is not set
# CONFIG_MOMENCO_OCELOT_C is not set
# CONFIG_DDB5074 is not set
# CONFIG_DDB5476 is not set
# CONFIG_DDB5477 is not set
# CONFIG_NEC_OSPREY is not set
# CONFIG_NEC_EAGLE is not set
# CONFIG_OLIVETTI_M700 is not set
# CONFIG_SGI_IP22 is not set
# CONFIG_SGI_IP27 is not set
CONFIG_SGI_IP32=y
# CONFIG_SIBYTE_SB1xxx_SOC is not set
# CONFIG_SNI_RM200_PCI is not set
# CONFIG_TANBAC_TB0226 is not set
# CONFIG_TANBAC_TB0229 is not set
# CONFIG_VICTOR_MPC30X is not set
# CONFIG_ZAO_CAPCELLA is not set
CONFIG_RWSEM_GENERIC_SPINLOCK=y
# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
CONFIG_ARC=y
CONFIG_GENERIC_ISA_DMA=y
CONFIG_NONCOHERENT_IO=y
# CONFIG_CPU_LITTLE_ENDIAN is not set
CONFIG_BOOT_ELF32=y
CONFIG_L1_CACHE_SHIFT=5
CONFIG_ARC32=y
CONFIG_PC_KEYB=y
CONFIG_PCI=y
# CONFIG_FB is not set
CONFIG_ARC_MEMORY=y
CONFIG_L1_CACHE_SHIFT=5
# CONFIG_ISA is not set
# CONFIG_EISA is not set
# CONFIG_MCA is not set
# CONFIG_SBUS is not set
CONFIG_ARC_PROMLIB=y
CONFIG_BOARD_SCACHE=y
#
# CPU selection
#
# CONFIG_CPU_MIPS32 is not set
# CONFIG_CPU_MIPS64 is not set
# CONFIG_CPU_R3000 is not set
# CONFIG_CPU_TX39XX is not set
# CONFIG_CPU_VR41XX is not set
# CONFIG_CPU_R4300 is not set
# CONFIG_CPU_R4X00 is not set
# CONFIG_CPU_TX49XX is not set
CONFIG_CPU_R5000=y
# CONFIG_CPU_R5432 is not set
# CONFIG_CPU_R6000 is not set
# CONFIG_CPU_NEVADA is not set
# CONFIG_CPU_R8000 is not set
# CONFIG_CPU_R10000 is not set
# CONFIG_CPU_RM7000 is not set
# CONFIG_CPU_SB1 is not set
CONFIG_R5000_CPU_SCACHE=y
CONFIG_CPU_HAS_LLSC=y
CONFIG_CPU_HAS_LLDSCD=y
CONFIG_CPU_HAS_SYNC=y
# CONFIG_PREEMPT is not set
CONFIG_KALLSYMS=y
# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
#
# General setup
# Bus options (PCI, PCMCIA, EISA, ISA, TC)
#
# CONFIG_CPU_LITTLE_ENDIAN is not set
# CONFIG_MIPS_FPU_EMULATOR is not set
CONFIG_NET=y
CONFIG_PCI=y
CONFIG_PCI_LEGACY_PROC=y
CONFIG_PCI_NAMES=y
CONFIG_MMU=y
# CONFIG_HOTPLUG is not set
# CONFIG_PCMCIA is not set
CONFIG_SYSVIPC=y
CONFIG_BSD_PROCESS_ACCT=y
CONFIG_SYSCTL=y
# CONFIG_PROM_CONSOLE is not set
CONFIG_BINFMT_ELF=y
CONFIG_MIPS32_COMPAT=y
CONFIG_BINFMT_ELF32=y
CONFIG_BINFMT_MISC=y
#
# Loadable module support
# Executable file formats
#
# CONFIG_MODULES is not set
CONFIG_PCI_NAMES=y
CONFIG_KCORE_ELF=y
CONFIG_BINFMT_ELF=y
CONFIG_BINFMT_MISC=y
CONFIG_MIPS32_COMPAT=y
CONFIG_COMPAT=y
CONFIG_MIPS32_O32=y
# CONFIG_MIPS32_N32 is not set
CONFIG_BINFMT_ELF32=y
#
# Memory Technology Devices (MTD)
......@@ -70,91 +134,36 @@ CONFIG_PCI_NAMES=y
#
# CONFIG_PARPORT is not set
#
# Plug and Play support
#
# CONFIG_PNP is not set
#
# Generic Driver Options
#
# CONFIG_FW_LOADER 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_UMEM 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_BLK_DEV_LVM is not set
#
# Networking options
#
CONFIG_PACKET=y
CONFIG_PACKET_MMAP=y
# CONFIG_NETLINK 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
#
# Telephony Support
#
# CONFIG_PHONE is not set
# CONFIG_PHONE_IXJ is not set
#
# ATA/IDE/MFM/RLL support
# ATA/ATAPI/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
# SCSI device support
#
CONFIG_SCSI=y
......@@ -162,19 +171,17 @@ 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=y
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=y
CONFIG_SCSI_MULTI_LUN=y
# CONFIG_SCSI_REPORT_LUNS is not set
CONFIG_SCSI_CONSTANTS=y
CONFIG_SCSI_LOGGING=y
......@@ -182,63 +189,122 @@ CONFIG_SCSI_LOGGING=y
# 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_AACRAID is not set
CONFIG_SCSI_AIC7XXX=y
CONFIG_AIC7XXX_CMDS_PER_DEVICE=8
CONFIG_AIC7XXX_RESET_DELAY_MS=15000
# CONFIG_AIC7XXX_PROBE_EISA_VL is not set
# CONFIG_AIC7XXX_BUILD_FIRMWARE is not set
CONFIG_AIC7XXX_DEBUG_ENABLE=y
CONFIG_AIC7XXX_DEBUG_MASK=0
CONFIG_AIC7XXX_REG_PRETTY_PRINT=y
# CONFIG_SCSI_AIC7XXX_OLD is not set
# CONFIG_SCSI_AIC79XX 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 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_DC395x is not set
# CONFIG_SCSI_DC390T is not set
# CONFIG_SCSI_T128 is not set
# CONFIG_SCSI_U14_34F is not set
# CONFIG_SCSI_NSP32 is not set
# CONFIG_SCSI_DEBUG is not set
#
# Multi-device support (RAID and LVM)
#
# CONFIG_MD is not set
#
# Fusion MPT device support
#
# CONFIG_FUSION 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
# Networking support
#
CONFIG_NET=y
#
# Networking options
#
CONFIG_PACKET=y
CONFIG_PACKET_MMAP=y
CONFIG_NETLINK_DEV=y
# CONFIG_NETFILTER is not set
CONFIG_UNIX=y
CONFIG_NET_KEY=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_ARPD is not set
# CONFIG_INET_ECN is not set
# CONFIG_SYN_COOKIES is not set
# CONFIG_INET_AH is not set
# CONFIG_INET_ESP is not set
# CONFIG_INET_IPCOMP is not set
# CONFIG_IPV6 is not set
# CONFIG_XFRM_USER is not set
#
# SCTP Configuration (EXPERIMENTAL)
#
CONFIG_IPV6_SCTP__=y
# CONFIG_IP_SCTP is not set
# CONFIG_ATM is not set
# CONFIG_VLAN_8021Q is not set
# CONFIG_LLC is not set
# CONFIG_DECNET is not set
# CONFIG_BRIDGE is not set
# CONFIG_X25 is not set
# CONFIG_LAPB 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
#
# Network testing
#
# CONFIG_NET_PKTGEN is not set
CONFIG_NETDEVICES=y
#
......@@ -249,58 +315,42 @@ CONFIG_NETDEVICES=y
# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
# CONFIG_NET_SB1000 is not set
# CONFIG_ETHERTAP is not set
#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
# CONFIG_MII is not set
CONFIG_SGI_O2MACE_ETH=y
# CONFIG_HAPPYMEAL 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_AT1700 is not set
# CONFIG_DEPCA is not set
#
# Tulip family network device support
#
# CONFIG_NET_TULIP 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_LAN_SAA9730 is not set
# CONFIG_NET_POCKET is not set
# CONFIG_NET_PCI is not set
#
# Ethernet (1000 Mbit)
#
# CONFIG_ACENIC is not set
# CONFIG_DL2K is not set
# CONFIG_E1000 is not set
# CONFIG_NS83820 is not set
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
# CONFIG_R8169 is not set
# CONFIG_SK98LIN is not set
# CONFIG_TIGON3 is not set
#
# Ethernet (10000 Mbit)
#
# CONFIG_IXGB is not set
# CONFIG_FDDI is not set
# CONFIG_HIPPI is not set
# CONFIG_PPP is not set
......@@ -312,9 +362,8 @@ CONFIG_EEPRO100=y
# CONFIG_NET_RADIO is not set
#
# Token Ring devices
# Token Ring devices (depends on LLC=y)
#
# CONFIG_TR is not set
# CONFIG_NET_FC is not set
# CONFIG_RCPCI is not set
# CONFIG_SHAPER is not set
......@@ -337,21 +386,65 @@ CONFIG_EEPRO100=y
#
# ISDN subsystem
#
# CONFIG_ISDN is not set
# CONFIG_ISDN_BOOL is not set
#
# Telephony Support
#
# CONFIG_PHONE is not set
#
# Old CD-ROM drivers (not SCSI, not IDE)
# Input device support
#
# CONFIG_CD_NO_IDESCSI is not set
CONFIG_INPUT=y
#
# Userland interfaces
#
# CONFIG_INPUT_MOUSEDEV is not set
# CONFIG_INPUT_JOYDEV is not set
# CONFIG_INPUT_TSDEV is not set
# CONFIG_INPUT_EVDEV is not set
# CONFIG_INPUT_EVBUG is not set
#
# Input I/O drivers
#
# CONFIG_GAMEPORT is not set
CONFIG_SOUND_GAMEPORT=y
CONFIG_SERIO=y
# CONFIG_SERIO_I8042 is not set
CONFIG_SERIO_SERPORT=y
# CONFIG_SERIO_CT82C710 is not set
# CONFIG_SERIO_PCIPS2 is not set
#
# Input Device Drivers
#
# CONFIG_INPUT_KEYBOARD is not set
# CONFIG_INPUT_MOUSE is not set
# CONFIG_INPUT_JOYSTICK is not set
# CONFIG_INPUT_TOUCHSCREEN is not set
# CONFIG_INPUT_MISC is not set
#
# 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
#
# Serial drivers
#
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
# CONFIG_SERIAL_8250_EXTENDED is not set
#
# Non-8250 serial port support
#
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
CONFIG_UNIX98_PTYS=y
CONFIG_UNIX98_PTY_COUNT=256
......@@ -361,31 +454,32 @@ CONFIG_UNIX98_PTY_COUNT=256
# CONFIG_I2C is not set
#
# Mice
# I2C Hardware Sensors Mainboard support
#
# CONFIG_BUSMOUSE is not set
CONFIG_MOUSE=y
CONFIG_PSMOUSE=y
# CONFIG_82C710_MOUSE is not set
# CONFIG_PC110_PAD is not set
#
# Joysticks
# I2C Hardware Sensors Chip support
#
# CONFIG_JOYSTICK is not set
# CONFIG_I2C_SENSOR is not set
#
# Input core support is needed for joysticks
# Mice
#
# CONFIG_BUSMOUSE is not set
# CONFIG_QIC02_TAPE is not set
#
# IPMI
#
# CONFIG_IPMI_HANDLER 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_GEN_RTC is not set
# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
......@@ -396,80 +490,93 @@ CONFIG_PSMOUSE=y
# CONFIG_FTAPE is not set
# CONFIG_AGP is not set
# CONFIG_DRM is not set
# CONFIG_RAW_DRIVER is not set
# CONFIG_HANGCHECK_TIMER is not set
#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
#
# Digital Video Broadcasting Devices
#
# CONFIG_DVB is not set
#
# File systems
#
CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
# CONFIG_EXT3_FS is not set
# CONFIG_JBD is not set
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
# CONFIG_XFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
# 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
#
# CD-ROM/DVD Filesystems
#
# CONFIG_ISO9660_FS is not set
# CONFIG_UDF_FS is not set
#
# DOS/FAT/NT Filesystems
#
# CONFIG_FAT_FS is not set
# CONFIG_NTFS_FS is not set
#
# Pseudo filesystems
#
CONFIG_PROC_FS=y
# CONFIG_DEVFS_FS is not set
CONFIG_DEVPTS_FS=y
CONFIG_DEVPTS_FS_XATTR=y
CONFIG_DEVPTS_FS_SECURITY=y
CONFIG_TMPFS=y
CONFIG_RAMFS=y
#
# Miscellaneous filesystems
#
# 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_BEFS_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_DEBUG 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=y
CONFIG_ROOT_NFS=y
# CONFIG_NFS_V4 is not set
# CONFIG_NFSD is not set
# CONFIG_NFSD_V3 is not set
CONFIG_SUNRPC=y
CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
CONFIG_LOCKD_V4=y
# CONFIG_EXPORTFS is not set
CONFIG_SUNRPC=y
# CONFIG_SUNRPC_GSS is not set
# CONFIG_SMB_FS is not set
# CONFIG_CIFS 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_CODA_FS is not set
# CONFIG_INTERMEZZO_FS is not set
# CONFIG_AFS_FS is not set
#
# Partition Types
......@@ -481,12 +588,16 @@ CONFIG_PARTITION_ADVANCED=y
# 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_NEC98_PARTITION is not set
CONFIG_SGI_PARTITION=y
# CONFIG_ULTRIX_PARTITION is not set
# CONFIG_SUN_PARTITION is not set
# CONFIG_SMB_NLS is not set
# CONFIG_NLS is not set
CONFIG_KCORE_ELF=y
# CONFIG_EFI_PARTITION is not set
#
# Graphics support
#
#
# Sound
......@@ -497,16 +608,30 @@ CONFIG_KCORE_ELF=y
# USB support
#
# CONFIG_USB is not set
# CONFIG_USB_GADGET is not set
#
# Input core support
# Bluetooth support
#
# CONFIG_INPUT is not set
# CONFIG_BT is not set
#
# Kernel hacking
#
CONFIG_CROSSCOMPILE=y
# CONFIG_REMOTE_DEBUG is not set
CONFIG_MAGIC_SYSRQ=y
CONFIG_MIPS_UNCACHED=y
# CONFIG_DEBUG_KERNEL is not set
#
# Security options
#
# CONFIG_SECURITY is not set
#
# Cryptographic options
#
# CONFIG_CRYPTO is not set
#
# Library routines
#
# CONFIG_CRC32 is not set
/*
* 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, 1995, 1996, 1999, 2000 by Ralf Baechle
* Copyright (C) 1999, 2000 by Silicon Graphics
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <asm/uaccess.h>
#include <asm/paccess.h>
#include <asm/addrspace.h>
#include <asm/ptrace.h>
/* XXX I have no idea what this does --kmw */
extern asmlinkage void handle_ibe(void);
extern asmlinkage void handle_dbe(void);
extern const struct exception_table_entry __start___dbe_table[];
extern const struct exception_table_entry __stop___dbe_table[];
static inline unsigned long
search_one_table(const struct exception_table_entry *first,
const struct exception_table_entry *last,
unsigned long value)
{
while (first <= last) {
const struct exception_table_entry *mid;
long diff;
mid = (last - first) / 2 + first;
diff = mid->insn - value;
if (diff == 0)
return mid->nextinsn;
else if (diff < 0)
first = mid+1;
else
last = mid-1;
}
return 0;
}
static inline unsigned long
search_dbe_table(unsigned long addr)
{
unsigned long ret;
/* There is only the kernel to search. */
ret = search_one_table(__start___dbe_table, __stop___dbe_table-1, addr);
if (ret) return ret;
return 0;
}
void do_ibe(struct pt_regs *regs)
{
printk("Got ibe at 0x%lx\n", regs->cp0_epc);
show_regs(regs);
dump_tlb_addr(regs->cp0_epc);
force_sig(SIGBUS, current);
while(1);
}
void do_dbe(struct pt_regs *regs)
{
unsigned long fixup;
fixup = search_dbe_table(regs->cp0_epc);
if (fixup) {
long new_epc;
new_epc = fixup_exception(dpf_reg, fixup, regs->cp0_epc);
regs->cp0_epc = new_epc;
return;
}
printk("Got dbe at 0x%lx\n", regs->cp0_epc);
show_regs(regs);
dump_tlb_all();
while(1);
force_sig(SIGBUS, current);
}
void __init
bus_error_init(void)
{
int dummy;
set_except_vector(6, handle_ibe);
set_except_vector(7, handle_dbe);
/* At this time nothing uses the DBE protection mechanism on the
O2, so this here is needed to make the kernel link. */
get_dbe(dummy, (int *)KSEG0);
}
/*
* 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) 2000 Ani Joshi <ajoshi@unixbox.com>
* Copyright (C) 2000 Ralf Baechle <ralf@gnu.org>
* swiped from i386, and cloned for MIPS by Geert, polished by Ralf.
*/
#include <linux/types.h>
#include <linux/mm.h>
#include <linux/string.h>
#include <linux/pci.h>
#include <asm/io.h>
#include <asm/addrspace.h>
#include <asm/ip32/mace.h>
void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
dma_addr_t * dma_handle)
{
void *ret;
int gfp = GFP_ATOMIC;
if (hwdev == NULL || hwdev->dma_mask != 0xffffffff)
gfp |= GFP_DMA;
ret = (void *) __get_free_pages(gfp, get_order(size));
if (ret != NULL) {
memset(ret, 0, size);
dma_cache_wback_inv((unsigned long) ret, size);
*dma_handle = virt_to_bus(ret);
}
return ret;
}
void pci_free_consistent(struct pci_dev *hwdev, size_t size,
void *vaddr, dma_addr_t dma_handle)
{
free_pages((unsigned long) vaddr, get_order(size));
}
/*
* 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) 2000, 2001 Keith M Wesolowski
*/
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/types.h>
#include <asm/pci.h>
#include <asm/ip32/mace.h>
#include <asm/ip32/crime.h>
#include <asm/ip32/ip32_ints.h>
#include <linux/delay.h>
#undef DEBUG_MACE_PCI
/*
* O2 has up to 5 PCI devices connected into the MACE bridge. The device
* map looks like this:
*
* 0 aic7xxx 0
* 1 aic7xxx 1
* 2 expansion slot
* 3 N/C
* 4 N/C
*/
#define chkslot(dev) \
do { \
if ((dev)->bus->number > 0 || PCI_SLOT ((dev)->devfn) < 1 \
|| PCI_SLOT ((dev)->devfn) > 3) \
return PCIBIOS_DEVICE_NOT_FOUND; \
} while (0)
#define mkaddr(dev, where) \
((((dev)->devfn & 0xffUL) << 8) | ((where) & 0xfcUL))
void macepci_error (int irq, void *dev, struct pt_regs *regs);
static int macepci_read_config_byte (struct pci_dev *dev, int where,
u8 *val)
{
*val = 0xff;
chkslot (dev);
mace_write_32 (MACEPCI_CONFIG_ADDR, mkaddr (dev, where));
*val = mace_read_8 (MACEPCI_CONFIG_DATA + ((where & 3UL) ^ 3UL));
return PCIBIOS_SUCCESSFUL;
}
static int macepci_read_config_word (struct pci_dev *dev, int where,
u16 *val)
{
*val = 0xffff;
chkslot (dev);
if (where & 1)
return PCIBIOS_BAD_REGISTER_NUMBER;
mace_write_32 (MACEPCI_CONFIG_ADDR, mkaddr (dev, where));
*val = mace_read_16 (MACEPCI_CONFIG_DATA + ((where & 2UL) ^ 2UL));
return PCIBIOS_SUCCESSFUL;
}
static int macepci_read_config_dword (struct pci_dev *dev, int where,
u32 *val)
{
*val = 0xffffffff;
chkslot (dev);
if (where & 3)
return PCIBIOS_BAD_REGISTER_NUMBER;
mace_write_32 (MACEPCI_CONFIG_ADDR, mkaddr (dev, where));
*val = mace_read_32 (MACEPCI_CONFIG_DATA);
return PCIBIOS_SUCCESSFUL;
}
static int macepci_write_config_byte (struct pci_dev *dev, int where,
u8 val)
{
chkslot (dev);
mace_write_32 (MACEPCI_CONFIG_ADDR, mkaddr (dev, where));
mace_write_8 (MACEPCI_CONFIG_DATA + ((where & 3UL) ^ 3UL), val);
return PCIBIOS_SUCCESSFUL;
}
static int macepci_write_config_word (struct pci_dev *dev, int where,
u16 val)
{
chkslot (dev);
if (where & 1)
return PCIBIOS_BAD_REGISTER_NUMBER;
mace_write_32 (MACEPCI_CONFIG_ADDR, mkaddr (dev, where));
mace_write_16 (MACEPCI_CONFIG_DATA + ((where & 2UL) ^ 2UL), val);
return PCIBIOS_SUCCESSFUL;
}
static int macepci_write_config_dword (struct pci_dev *dev, int where,
u32 val)
{
chkslot (dev);
if (where & 3)
return PCIBIOS_BAD_REGISTER_NUMBER;
mace_write_32 (MACEPCI_CONFIG_ADDR, mkaddr (dev, where));
mace_write_32 (MACEPCI_CONFIG_DATA, val);
return PCIBIOS_SUCCESSFUL;
}
static struct pci_ops macepci_ops = {
macepci_read_config_byte,
macepci_read_config_word,
macepci_read_config_dword,
macepci_write_config_byte,
macepci_write_config_word,
macepci_write_config_dword
};
struct pci_fixup pcibios_fixups[] = { { 0 } };
void __init pcibios_init (void)
{
struct pci_dev *dev = NULL;
u32 start, size;
u16 cmd;
u32 base_io = 0x3000; /* The first i/o address to assign after SCSI */
u32 base_mem = 0x80100000; /* Likewise */
u32 rev = mace_read_32 (MACEPCI_REV);
int i;
printk ("MACE: PCI rev %d detected at %016lx\n", rev,
(u64) MACE_BASE + MACE_PCI);
/* These are *bus* addresses */
ioport_resource.start = 0;
ioport_resource.end = 0xffffffffUL;
iomem_resource.start = 0x80000000UL;
iomem_resource.end = 0xffffffffUL;
/* Clear any outstanding errors and enable interrupts */
mace_write_32 (MACEPCI_ERROR_ADDR, 0);
mace_write_32 (MACEPCI_ERROR_FLAGS, 0);
mace_write_32 (MACEPCI_CONTROL, 0xff008500);
crime_write_64 (CRIME_HARD_INT, 0UL);
crime_write_64 (CRIME_SOFT_INT, 0UL);
crime_write_64 (CRIME_INT_STAT, 0x000000000000ff00UL);
if (request_irq (MACE_PCI_BRIDGE_IRQ, macepci_error, 0,
"MACE PCI error", NULL))
panic ("PCI bridge can't get interrupt; can't happen.\n");
pci_scan_bus (0, &macepci_ops, NULL);
#ifdef DEBUG_MACE_PCI
while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
printk ("Device: %d/%d/%d ARCS-assigned bus resource map\n",
dev->bus->number, PCI_SLOT (dev->devfn),
PCI_FUNC (dev->devfn));
for (i=0; i < DEVICE_COUNT_RESOURCE; i++) {
if (dev->resource[i].start == 0)
continue;
printk ("%d: %016lx - %016lx (flags %04lx)\n",
i, dev->resource[i].start,
dev->resource[i].end, dev->resource[i].flags);
}
}
#endif
/*
* Assign sane resources to and enable all devices. The requirement
* for the SCSI controllers is well-known: a 256-byte I/O region
* which we must assign, and a 1-page memory region which is
* assigned by the system firmware.
*/
dev = NULL;
while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
switch (PCI_SLOT (dev->devfn)) {
case 1: /* SCSI bus 0 */
dev->resource[0].start = 0x1000UL;
dev->resource[0].end = 0x10ffUL;
break;
case 2: /* SCSI bus 1 */
dev->resource[0].start = 0x2000UL;
dev->resource[0].end = 0x20ffUL;
break;
default: /* Slots - I guess we have only 1 */
for (i=0; i < 6; i++) {
size = dev->resource[i].end
- dev->resource[i].start;
if (!size
|| !(dev->resource[i].flags
& (IORESOURCE_IO|IORESOURCE_MEM))) {
dev->resource[i].start
= dev->resource[i].end = 0UL;
continue;
}
if (dev->resource[i].flags & IORESOURCE_IO) {
dev->resource[i].start = base_io;
base_io += PAGE_ALIGN (size);
} else {
dev->resource[i].start = base_mem;
base_mem += 0x100000UL;
}
dev->resource[i].end =
dev->resource[i].start + size;
}
break;
}
for (i=0; i < 6; i++) {
if (dev->resource[i].start == 0)
continue;
start = dev->resource[i].start;
if (dev->resource[i].flags & IORESOURCE_IO)
start |= 1;
pci_write_config_dword (dev,
PCI_BASE_ADDRESS_0 + (i << 2), (u32) start);
}
pci_write_config_byte (dev, PCI_CACHE_LINE_SIZE, 0x20);
pci_write_config_byte (dev, PCI_LATENCY_TIMER, 0x30);
pci_read_config_word (dev, PCI_COMMAND, &cmd);
cmd |= (PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_PARITY);
pci_write_config_word (dev, PCI_COMMAND, cmd);
pci_set_master (dev);
}
#ifdef DEBUG_MACE_PCI
printk ("Triggering PCI bridge interrupt...\n");
mace_write_32 (MACEPCI_ERROR_FLAGS, MACEPCI_ERROR_INTERRUPT_TEST);
dev = NULL;
while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
printk ("Device: %d/%d/%d final bus resource map\n",
dev->bus->number, PCI_SLOT (dev->devfn),
PCI_FUNC (dev->devfn));
for (i=0; i < DEVICE_COUNT_RESOURCE; i++) {
if (dev->resource[i].start == 0)
continue;
printk ("%d: %016lx - %016lx (flags %04lx)\n",
i, dev->resource[i].start,
dev->resource[i].end, dev->resource[i].flags);
}
}
#endif
}
/*
* Given a PCI slot number (a la PCI_SLOT(...)) and the interrupt pin of
* the device (1-4 => A-D), tell what irq to use. Note that we don't
* in theory have slots 4 and 5, and we never normally use the shared
* irqs. I suppose a device without a pin A will thank us for doing it
* right if there exists such a broken piece of crap.
*/
static int __init macepci_map_irq (struct pci_dev *dev, u8 slot, u8 pin)
{
chkslot (dev);
if (pin == 0)
pin = 1;
switch (slot) {
case 1:
return MACEPCI_SCSI0_IRQ;
case 2:
return MACEPCI_SCSI1_IRQ;
case 3:
switch (pin) {
case 2:
return MACEPCI_SHARED0_IRQ;
case 3:
return MACEPCI_SHARED1_IRQ;
case 4:
return MACEPCI_SHARED2_IRQ;
case 1:
default:
return MACEPCI_SLOT0_IRQ;
}
case 4:
switch (pin) {
case 2:
return MACEPCI_SHARED2_IRQ;
case 3:
return MACEPCI_SHARED0_IRQ;
case 4:
return MACEPCI_SHARED1_IRQ;
case 1:
default:
return MACEPCI_SLOT1_IRQ;
}
return MACEPCI_SLOT1_IRQ;
case 5:
switch (pin) {
case 2:
return MACEPCI_SHARED1_IRQ;
case 3:
return MACEPCI_SHARED2_IRQ;
case 4:
return MACEPCI_SHARED0_IRQ;
case 1:
default:
return MACEPCI_SLOT2_IRQ;
}
default:
return 0;
}
}
/*
* It's not entirely clear what this does in a system with no bridges.
* In any case, bridges are not supported by Linux in O2.
*/
static u8 __init macepci_swizzle (struct pci_dev *dev, u8 *pinp)
{
if (PCI_SLOT (dev->devfn) == 2)
*pinp = 2;
else
*pinp = 1;
return PCI_SLOT (dev->devfn);
}
/* All devices are enabled during initialization. */
int pcibios_enable_device (struct pci_dev *dev)
{
return PCIBIOS_SUCCESSFUL;
}
char * __init pcibios_setup (char *str)
{
return str;
}
void __init pcibios_align_resource (void *data, struct resource *res,
unsigned long size, unsigned long align)
{
}
void __init pcibios_update_irq (struct pci_dev *dev, int irq)
{
pci_write_config_byte (dev, PCI_INTERRUPT_LINE, irq);
}
void __init pcibios_fixup_bus (struct pci_bus *b)
{
pci_fixup_irqs (macepci_swizzle, macepci_map_irq);
}
/*
* Handle errors from the bridge. This includes master and target aborts,
* various command and address errors, and the interrupt test. This gets
* registered on the bridge error irq. It's conceivable that some of these
* conditions warrant a panic. Anybody care to say which ones?
*/
void macepci_error (int irq, void *dev, struct pt_regs *regs) {
u32 flags, error_addr;
char space;
flags = mace_read_32 (MACEPCI_ERROR_FLAGS);
error_addr = mace_read_32 (MACEPCI_ERROR_ADDR);
if (flags & MACEPCI_ERROR_MEMORY_ADDR)
space = 'M';
else if (flags & MACEPCI_ERROR_CONFIG_ADDR)
space = 'C';
else space = 'X';
if (flags & MACEPCI_ERROR_MASTER_ABORT) {
printk ("MACEPCI: Master abort at 0x%08x (%c)\n", error_addr,
space);
mace_write_32 (MACEPCI_ERROR_FLAGS, flags
& ~MACEPCI_ERROR_MASTER_ABORT);
}
if (flags & MACEPCI_ERROR_TARGET_ABORT) {
printk ("MACEPCI: Target abort at 0x%08x (%c)\n", error_addr,
space);
mace_write_32 (MACEPCI_ERROR_FLAGS, flags
& ~MACEPCI_ERROR_TARGET_ABORT);
}
if (flags & MACEPCI_ERROR_DATA_PARITY_ERR) {
printk ("MACEPCI: Data parity error at 0x%08x (%c)\n",
error_addr, space);
mace_write_32 (MACEPCI_ERROR_FLAGS, flags
& ~MACEPCI_ERROR_DATA_PARITY_ERR);
}
if (flags & MACEPCI_ERROR_RETRY_ERR) {
printk ("MACEPCI: Retry error at 0x%08x (%c)\n", error_addr,
space);
mace_write_32 (MACEPCI_ERROR_FLAGS, flags
& ~MACEPCI_ERROR_RETRY_ERR);
}
if (flags & MACEPCI_ERROR_ILLEGAL_CMD) {
printk ("MACEPCI: Illegal command at 0x%08x (%c)\n",
error_addr, space);
mace_write_32 (MACEPCI_ERROR_FLAGS,
flags & ~MACEPCI_ERROR_ILLEGAL_CMD);
}
if (flags & MACEPCI_ERROR_SYSTEM_ERR) {
printk ("MACEPCI: System error at 0x%08x (%c)\n",
error_addr, space);
mace_write_32 (MACEPCI_ERROR_FLAGS, flags
& ~MACEPCI_ERROR_SYSTEM_ERR);
}
if (flags & MACEPCI_ERROR_PARITY_ERR) {
printk ("MACEPCI: Parity error at 0x%08x (%c)\n", error_addr,
space);
mace_write_32 (MACEPCI_ERROR_FLAGS, flags
& ~MACEPCI_ERROR_PARITY_ERR);
}
if (flags & MACEPCI_ERROR_OVERRUN) {
printk ("MACEPCI: Overrun error at 0x%08x (%c)\n",
error_addr, space);
mace_write_32 (MACEPCI_ERROR_FLAGS, flags
& ~MACEPCI_ERROR_OVERRUN);
}
if (flags & MACEPCI_ERROR_SIG_TABORT) {
printk ("MACEPCI: Signaled target abort (clearing)\n");
mace_write_32 (MACEPCI_ERROR_FLAGS, flags
& ~MACEPCI_ERROR_SIG_TABORT);
}
if (flags & MACEPCI_ERROR_INTERRUPT_TEST) {
printk ("MACEPCI: Interrupt test triggered (clearing)\n");
mace_write_32 (MACEPCI_ERROR_FLAGS, flags
& ~MACEPCI_ERROR_INTERRUPT_TEST);
}
}
/*
* IP32 timer calibration
*
* 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) 2001 Keith M Wesolowski
*/
#include <linux/irq.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <asm/mipsregs.h>
#include <asm/param.h>
#include <asm/ip32/crime.h>
#include <asm/ip32/ip32_ints.h>
extern u32 cc_interval;
/* An arbitrary time; this can be decreased if reliability looks good */
#define WAIT_MS 10
#define PER_MHZ (1000000 / 2 / HZ)
void __init ip32_timer_setup (struct irqaction *irq) {
u64 crime_time;
u32 cc_tick;
printk("Calibrating system timer... ");
crime_time = crime_read_64 (CRIME_TIME) & CRIME_TIME_MASK;
cc_tick = read_32bit_cp0_register (CP0_COUNT);
while ((crime_read_64 (CRIME_TIME) & CRIME_TIME_MASK) - crime_time
< WAIT_MS * 1000000 / CRIME_NS_PER_TICK)
;
cc_tick = read_32bit_cp0_register (CP0_COUNT) - cc_tick;
cc_interval = cc_tick / HZ * (1000 / WAIT_MS);
/* The round-off seems unnecessary; in testing, the error of the
* above procedure is < 100 ticks, which means it gets filtered
* out by the HZ adjustment.
*/
cc_interval = (cc_interval / PER_MHZ) * PER_MHZ;
printk("%d MHz CPU detected\n", (int) (cc_interval / PER_MHZ));
setup_irq (CLOCK_IRQ, irq);
}
/*
* Definitions for the SGI O2 Crime chip.
*
* 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) 2000 Harald Koerfgen
*/
#ifndef __ASM_CRIME_H__
#define __ASM_CRIME_H__
#include <asm/addrspace.h>
/*
* Address map
*/
#ifndef __ASSEMBLY__
#define CRIME_BASE KSEG1ADDR(0x14000000)
#else
#define CRIME_BASE 0xffffffffb4000000
#endif
#ifndef __ASSEMBLY__
static inline u64 crime_read_64 (unsigned long __offset) {
return *((volatile u64 *) (CRIME_BASE + __offset));
}
static inline void crime_write_64 (unsigned long __offset, u64 __val) {
*((volatile u64 *) (CRIME_BASE + __offset)) = __val;
}
#endif
#undef BIT
#define BIT(x) (1UL << (x))
/* All CRIME registers are 64 bits */
#define CRIME_ID 0
#define CRIME_ID_MASK 0xff
#define CRIME_ID_IDBITS 0xf0
#define CRIME_ID_IDVALUE 0xa0
#define CRIME_ID_REV 0x0f
#define CRIME_REV_PETTY 0x00
#define CRIME_REV_11 0x11
#define CRIME_REV_13 0x13
#define CRIME_REV_14 0x14
#define CRIME_CONTROL (0x00000008)
#define CRIME_CONTROL_MASK 0x3fff /* 14-bit registers */
/* CRIME_CONTROL register bits */
#define CRIME_CONTROL_TRITON_SYSADC 0x2000
#define CRIME_CONTROL_CRIME_SYSADC 0x1000
#define CRIME_CONTROL_HARD_RESET 0x0800
#define CRIME_CONTROL_SOFT_RESET 0x0400
#define CRIME_CONTROL_DOG_ENA 0x0200
#define CRIME_CONTROL_ENDIANESS 0x0100
#define CRIME_CONTROL_ENDIAN_BIG 0x0100
#define CRIME_CONTROL_ENDIAN_LITTLE 0x0000
#define CRIME_CONTROL_CQUEUE_HWM 0x000f
#define CRIME_CONTROL_CQUEUE_SHFT 0
#define CRIME_CONTROL_WBUF_HWM 0x00f0
#define CRIME_CONTROL_WBUF_SHFT 8
#define CRIME_INT_STAT (0x00000010)
#define CRIME_INT_MASK (0x00000018)
#define CRIME_SOFT_INT (0x00000020)
#define CRIME_HARD_INT (0x00000028)
/* Bits in CRIME_INT_XXX and CRIME_HARD_INT */
#define MACE_VID_IN1_INT BIT (0)
#define MACE_VID_IN2_INT BIT (1)
#define MACE_VID_OUT_INT BIT (2)
#define MACE_ETHERNET_INT BIT (3)
#define MACE_SUPERIO_INT BIT (4)
#define MACE_MISC_INT BIT (5)
#define MACE_AUDIO_INT BIT (6)
#define MACE_PCI_BRIDGE_INT BIT (7)
#define MACEPCI_SCSI0_INT BIT (8)
#define MACEPCI_SCSI1_INT BIT (9)
#define MACEPCI_SLOT0_INT BIT (10)
#define MACEPCI_SLOT1_INT BIT (11)
#define MACEPCI_SLOT2_INT BIT (12)
#define MACEPCI_SHARED0_INT BIT (13)
#define MACEPCI_SHARED1_INT BIT (14)
#define MACEPCI_SHARED2_INT BIT (15)
#define CRIME_GBE0_INT BIT (16)
#define CRIME_GBE1_INT BIT (17)
#define CRIME_GBE2_INT BIT (18)
#define CRIME_GBE3_INT BIT (19)
#define CRIME_CPUERR_INT BIT (20)
#define CRIME_MEMERR_INT BIT (21)
#define CRIME_RE_EMPTY_E_INT BIT (22)
#define CRIME_RE_FULL_E_INT BIT (23)
#define CRIME_RE_IDLE_E_INT BIT (24)
#define CRIME_RE_EMPTY_L_INT BIT (25)
#define CRIME_RE_FULL_L_INT BIT (26)
#define CRIME_RE_IDLE_L_INT BIT (27)
#define CRIME_SOFT0_INT BIT (28)
#define CRIME_SOFT1_INT BIT (29)
#define CRIME_SOFT2_INT BIT (30)
#define CRIME_SYSCORERR_INT CRIME_SOFT2_INT
#define CRIME_VICE_INT BIT (31)
/* Masks for deciding who handles the interrupt */
#define CRIME_MACE_INT_MASK 0x8f
#define CRIME_MACEISA_INT_MASK 0x70
#define CRIME_MACEPCI_INT_MASK 0xff00
#define CRIME_CRIME_INT_MASK 0xffff0000
/*
* XXX Todo
*/
#define CRIME_DOG (0x00000030)
/* We are word-play compatible but not misspelling compatible */
#define MC_GRUFF CRIME_DOG
#define CRIME_DOG_MASK (0x001fffff)
/* CRIME_DOG register bits */
#define CRIME_DOG_POWER_ON_RESET (0x00010000)
#define CRIME_DOG_WARM_RESET (0x00080000)
#define CRIME_DOG_TIMEOUT (CRIME_DOG_POWER_ON_RESET|CRIME_DOG_WARM_RESET)
#define CRIME_DOG_VALUE (0x00007fff) /* ??? */
#define CRIME_TIME (0x00000038)
#define CRIME_TIME_MASK (0x0000ffffffffffff)
#ifdef MASTER_FREQ
#undef MASTER_FREQ
#endif
#define CRIME_MASTER_FREQ 66666500 /* Crime upcounter frequency */
#define CRIME_NS_PER_TICK 15 /* for delay_calibrate */
#define CRIME_CPU_ERROR_ADDR (0x00000040)
#define CRIME_CPU_ERROR_ADDR_MASK (0x3ffffffff)
#define CRIME_CPU_ERROR_STAT (0x00000048)
/* REV_PETTY only! */
#define CRIME_CPU_ERROR_ENA (0x00000050)
/*
* bit definitions for CRIME/VICE error status and enable registers
*/
#define CRIME_CPU_ERROR_MASK 0x7UL /* cpu error stat is 3 bits */
#define CRIME_CPU_ERROR_CPU_ILL_ADDR 0x4
#define CRIME_CPU_ERROR_VICE_WRT_PRTY 0x2
#define CRIME_CPU_ERROR_CPU_WRT_PRTY 0x1
/*
* these are the definitions for the error status/enable register in
* petty crime. Note that the enable register does not exist in crime
* rev 1 and above.
*/
#define CRIME_CPU_ERROR_MASK_REV0 0x3ff /* cpu error stat is 9 bits */
#define CRIME_CPU_ERROR_CPU_INV_ADDR_RD 0x200
#define CRIME_CPU_ERROR_VICE_II 0x100
#define CRIME_CPU_ERROR_VICE_SYSAD 0x80
#define CRIME_CPU_ERROR_VICE_SYSCMD 0x40
#define CRIME_CPU_ERROR_VICE_INV_ADDR 0x20
#define CRIME_CPU_ERROR_CPU_II 0x10
#define CRIME_CPU_ERROR_CPU_SYSAD 0x8
#define CRIME_CPU_ERROR_CPU_SYSCMD 0x4
#define CRIME_CPU_ERROR_CPU_INV_ADDR_WR 0x2
#define CRIME_CPU_ERROR_CPU_INV_REG_ADDR 0x1
#define CRIME_VICE_ERROR_ADDR (0x00000058)
#define CRIME_VICE_ERROR_ADDR_MASK (0x3fffffff)
#define CRIME_MEM_CONTROL (0x00000200)
#define CRIME_MEM_CONTROL_MASK 0x3 /* 25 cent register */
#define CRIME_MEM_CONTROL_ECC_ENA 0x1
#define CRIME_MEM_CONTROL_USE_ECC_REPL 0x2
/*
* macros for CRIME memory bank control registers.
*/
#define CRIME_MEM_BANK_CONTROL(__bank) (0x00000208 + ((__bank) << 3))
#define CRIME_MEM_BANK_CONTROL_MSK 0x11f /* 9 bits 7:5 reserved */
#define CRIME_MEM_BANK_CONTROL_ADDR 0x01f
#define CRIME_MEM_BANK_CONTROL_SDRAM_SIZE 0x100
#define CRIME_MEM_BANK_CONTROL_BANK_TO_ADDR(__bank) \
(((__bank) & CRIME_MEM_BANK_CONTROL_ADDR) << 25)
#define CRIME_MEM_REFRESH_COUNTER (0x00000248)
#define CRIME_MEM_REFRESH_COUNTER_MASK 0x7ff /* 11-bit register */
#define CRIME_MAXBANKS 8
/*
* CRIME Memory error status register bit definitions
*/
#define CRIME_MEM_ERROR_STAT (0x00000250)
#define CRIME_MEM_ERROR_STAT_MASK 0x0ff7ffff /* 28-bit register */
#define CRIME_MEM_ERROR_MACE_ID 0x0000007f
#define CRIME_MEM_ERROR_MACE_ACCESS 0x00000080
#define CRIME_MEM_ERROR_RE_ID 0x00007f00
#define CRIME_MEM_ERROR_RE_ACCESS 0x00008000
#define CRIME_MEM_ERROR_GBE_ACCESS 0x00010000
#define CRIME_MEM_ERROR_VICE_ACCESS 0x00020000
#define CRIME_MEM_ERROR_CPU_ACCESS 0x00040000
#define CRIME_MEM_ERROR_RESERVED 0x00080000
#define CRIME_MEM_ERROR_SOFT_ERR 0x00100000
#define CRIME_MEM_ERROR_HARD_ERR 0x00200000
#define CRIME_MEM_ERROR_MULTIPLE 0x00400000
#define CRIME_MEM_ERROR_MEM_ECC_RD 0x00800000
#define CRIME_MEM_ERROR_MEM_ECC_RMW 0x01000000
#define CRIME_MEM_ERROR_INV_MEM_ADDR_RD 0x02000000
#define CRIME_MEM_ERROR_INV_MEM_ADDR_WR 0x04000000
#define CRIME_MEM_ERROR_INV_MEM_ADDR_RMW 0x08000000
#define CRIME_MEM_ERROR_ADDR (0x00000258)
#define CRIME_MEM_ERROR_ADDR_MASK 0x3fffffff
#define CRIME_MEM_ERROR_ECC_SYN (0x00000260)
#define CRIME_MEM_ERROR_ECC_SYN_MASK 0xffffffff
#define CRIME_MEM_ERROR_ECC_CHK (0x00000268)
#define CRIME_MEM_ERROR_ECC_CHK_MASK 0xffffffff
#define CRIME_MEM_ERROR_ECC_REPL (0x00000270)
#define CRIME_MEM_ERROR_ECC_REPL_MASK 0xffffffff
#endif /* __ASM_CRIME_H__ */
#ifndef __ASM_IP32_IO_H__
#define __ASM_IP32_IO_H__
#include <asm/ip32/mace.h>
/*#ifdef CONFIG_MIPS_UNCACHED*/
#define UNCACHEDADDR(x) (0x9000000000000000UL | (u64)(x))
/*#else
#define UNCACHEDADDR(x) (x)
#endif*/
/*#define UNCACHEDADDR(x) (KSEG1ADDR (x)) */
#define IO_SPACE_BASE UNCACHEDADDR (MACEPCI_HI_MEMORY)
#define IO_SPACE_LIMIT 0xffffffffUL
#endif
/*
* 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) 2000 Harald Koerfgen
*/
#ifndef __ASM_IP32_INTS_H
#define __ASM_IP32_INTS_H
/*
* This list reflects the assignment of interrupt numbers to
* interrupting events. Order is fairly irrelevant to handling
* priority. This differs from irix.
*/
/* CPU */
#define CLOCK_IRQ 0
/* MACE */
#define MACE_VID_IN1_IRQ 1
#define MACE_VID_IN2_IRQ 2
#define MACE_VID_OUT_IRQ 3
#define MACE_ETHERNET_IRQ 4
/* SUPERIO, MISC, and AUDIO are MACEISA */
#define MACE_PCI_BRIDGE_IRQ 8
/* MACEPCI */
#define MACEPCI_SCSI0_IRQ 9
#define MACEPCI_SCSI1_IRQ 10
#define MACEPCI_SLOT0_IRQ 11
#define MACEPCI_SLOT1_IRQ 12
#define MACEPCI_SLOT2_IRQ 13
#define MACEPCI_SHARED0_IRQ 14
#define MACEPCI_SHARED1_IRQ 15
#define MACEPCI_SHARED2_IRQ 16
/* CRIME */
#define CRIME_GBE0_IRQ 17
#define CRIME_GBE1_IRQ 18
#define CRIME_GBE2_IRQ 19
#define CRIME_GBE3_IRQ 20
#define CRIME_CPUERR_IRQ 21
#define CRIME_MEMERR_IRQ 22
#define CRIME_RE_EMPTY_E_IRQ 23
#define CRIME_RE_FULL_E_IRQ 24
#define CRIME_RE_IDLE_E_IRQ 25
#define CRIME_RE_EMPTY_L_IRQ 26
#define CRIME_RE_FULL_L_IRQ 27
#define CRIME_RE_IDLE_L_IRQ 28
#define CRIME_SOFT0_IRQ 29
#define CRIME_SOFT1_IRQ 30
#define CRIME_SOFT2_IRQ 31
#define CRIME_SYSCORERR_IRQ CRIME_SOFT2_IRQ
#define CRIME_VICE_IRQ 32
/* MACEISA */
#define MACEISA_AUDIO_SW_IRQ 33
#define MACEISA_AUDIO_SC_IRQ 34
#define MACEISA_AUDIO1_DMAT_IRQ 35
#define MACEISA_AUDIO1_OF_IRQ 36
#define MACEISA_AUDIO2_DMAT_IRQ 37
#define MACEISA_AUDIO2_MERR_IRQ 38
#define MACEISA_AUDIO3_DMAT_IRQ 39
#define MACEISA_AUDIO3_MERR_IRQ 40
#define MACEISA_RTC_IRQ 41
#define MACEISA_KEYB_IRQ 42
/* MACEISA_KEYB_POLL is not an IRQ */
#define MACEISA_MOUSE_IRQ 44
/* MACEISA_MOUSE_POLL is not an IRQ */
#define MACEISA_TIMER0_IRQ 46
#define MACEISA_TIMER1_IRQ 47
#define MACEISA_TIMER2_IRQ 48
#define MACEISA_PARALLEL_IRQ 49
#define MACEISA_PAR_CTXA_IRQ 50
#define MACEISA_PAR_CTXB_IRQ 51
#define MACEISA_PAR_MERR_IRQ 52
#define MACEISA_SERIAL1_IRQ 53
#define MACEISA_SERIAL1_TDMAT_IRQ 54
#define MACEISA_SERIAL1_TDMAPR_IRQ 55
#define MACEISA_SERIAL1_TDMAME_IRQ 56
#define MACEISA_SERIAL1_RDMAT_IRQ 57
#define MACEISA_SERIAL1_RDMAOR_IRQ 58
#define MACEISA_SERIAL2_IRQ 59
#define MACEISA_SERIAL2_TDMAT_IRQ 60
#define MACEISA_SERIAL2_TDMAPR_IRQ 61
#define MACEISA_SERIAL2_TDMAME_IRQ 62
#define MACEISA_SERIAL2_RDMAT_IRQ 63
#define MACEISA_SERIAL2_RDMAOR_IRQ 64
#define IP32_IRQ_MAX MACEISA_SERIAL2_RDMAOR_IRQ
#endif /* __ASM_IP32_INTS_H */
/*
* Definitions for the SGI O2 Mace chip.
*
* 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) 2000 Harald Koerfgen
*/
#ifndef __ASM_MACE_H__
#define __ASM_MACE_H__
#include <asm/addrspace.h>
/*
* Address map
*/
#define MACE_BASE KSEG1ADDR(0x1f000000)
#define MACE_PCI (0x00080000)
#define MACE_VIN1 (0x00100000)
#define MACE_VIN2 (0x00180000)
#define MACE_VOUT (0x00200000)
#define MACE_ENET (0x00280000)
#define MACE_PERIF (0x00300000)
#define MACE_ISA_EXT (0x00380000)
#define MACE_AUDIO_BASE (MACE_PERIF )
#define MACE_ISA_BASE (MACE_PERIF + 0x00010000)
#define MACE_KBDMS_BASE (MACE_PERIF + 0x00020000)
#define MACE_I2C_BASE (MACE_PERIF + 0x00030000)
#define MACE_UST_BASE (MACE_PERIF + 0x00040000)
#undef BIT
#define BIT(__bit_offset) (1UL << (__bit_offset))
/*
* Mace MACEPCI interface, 32 bit regs
*/
#define MACEPCI_ERROR_ADDR (MACE_PCI )
#define MACEPCI_ERROR_FLAGS (MACE_PCI + 0x00000004)
#define MACEPCI_CONTROL (MACE_PCI + 0x00000008)
#define MACEPCI_REV (MACE_PCI + 0x0000000c)
#define MACEPCI_WFLUSH (MACE_PCI + 0x0000000c) /* ??? --IV !!! It's for flushing read buffers on PCI MEMORY accesses!!! */
#define MACEPCI_CONFIG_ADDR (MACE_PCI + 0x00000cf8)
#define MACEPCI_CONFIG_DATA (MACE_PCI + 0x00000cfc)
#define MACEPCI_LOW_MEMORY 0x1a000000
#define MACEPCI_LOW_IO 0x18000000
#define MACEPCI_SWAPPED_VIEW 0
#define MACEPCI_NATIVE_VIEW 0x40000000
#define MACEPCI_IO 0x80000000
/*#define MACEPCI_HI_MEMORY 0x0000000280000000UL * This mipght be just 0x0000000200000000UL 2G more :) (or maybe it is different between 1.1 & 1.5 */
#define MACEPCI_HI_MEMORY 0x0000000200000000UL /* This mipght be just 0x0000000200000000UL 2G more :) (or maybe it is different between 1.1 & 1.5 */
#define MACEPCI_HI_IO 0x0000000100000000UL
/*
* Bits in the MACEPCI_CONTROL register
*/
#define MACEPCI_CONTROL_INT(x) BIT(x)
#define MACEPCI_CONTROL_INT_MASK 0xff
#define MACEPCI_CONTROL_SERR_ENA BIT(8)
#define MACEPCI_CONTROL_ARB_N6 BIT(9)
#define MACEPCI_CONTROL_PARITY_ERR BIT(10)
#define MACEPCI_CONTROL_MRMRA_ENA BIT(11)
#define MACEPCI_CONTROL_ARB_N3 BIT(12)
#define MACEPCI_CONTROL_ARB_N4 BIT(13)
#define MACEPCI_CONTROL_ARB_N5 BIT(14)
#define MACEPCI_CONTROL_PARK_LIU BIT(15)
#define MACEPCI_CONTROL_INV_INT(x) BIT(16+x)
#define MACEPCI_CONTROL_INV_INT_MASK 0x00ff0000
#define MACEPCI_CONTROL_OVERRUN_INT BIT(24)
#define MACEPCI_CONTROL_PARITY_INT BIT(25)
#define MACEPCI_CONTROL_SERR_INT BIT(26)
#define MACEPCI_CONTROL_IT_INT BIT(27)
#define MACEPCI_CONTROL_RE_INT BIT(28)
#define MACEPCI_CONTROL_DPED_INT BIT(29)
#define MACEPCI_CONTROL_TAR_INT BIT(30)
#define MACEPCI_CONTROL_MAR_INT BIT(31)
/*
* Bits in the MACE_PCI error register
*/
#define MACEPCI_ERROR_MASTER_ABORT BIT(31)
#define MACEPCI_ERROR_TARGET_ABORT BIT(30)
#define MACEPCI_ERROR_DATA_PARITY_ERR BIT(29)
#define MACEPCI_ERROR_RETRY_ERR BIT(28)
#define MACEPCI_ERROR_ILLEGAL_CMD BIT(27)
#define MACEPCI_ERROR_SYSTEM_ERR BIT(26)
#define MACEPCI_ERROR_INTERRUPT_TEST BIT(25)
#define MACEPCI_ERROR_PARITY_ERR BIT(24)
#define MACEPCI_ERROR_OVERRUN BIT(23)
#define MACEPCI_ERROR_RSVD BIT(22)
#define MACEPCI_ERROR_MEMORY_ADDR BIT(21)
#define MACEPCI_ERROR_CONFIG_ADDR BIT(20)
#define MACEPCI_ERROR_MASTER_ABORT_ADDR_VALID BIT(19)
#define MACEPCI_ERROR_TARGET_ABORT_ADDR_VALID BIT(18)
#define MACEPCI_ERROR_DATA_PARITY_ADDR_VALID BIT(17)
#define MACEPCI_ERROR_RETRY_ADDR_VALID BIT(16)
#define MACEPCI_ERROR_SIG_TABORT BIT(4)
#define MACEPCI_ERROR_DEVSEL_MASK 0xc0
#define MACEPCI_ERROR_DEVSEL_FAST 0
#define MACEPCI_ERROR_DEVSEL_MED 0x40
#define MACEPCI_ERROR_DEVSEL_SLOW 0x80
#define MACEPCI_ERROR_FBB BIT(1)
#define MACEPCI_ERROR_66MHZ BIT(0)
/*
* Mace timer registers - 64 bit regs (63:32 are UST, 31:0 are MSC)
*/
#define MSC_PART(__reg) ((__reg) & 0x00000000ffffffff)
#define UST_PART(__reg) (((__reg) & 0xffffffff00000000) >> 32)
#define MACE_UST_UST (MACE_UST_BASE ) /* Universial system time */
#define MACE_UST_COMPARE1 (MACE_UST_BASE + 0x00000008) /* Interrupt compare reg 1 */
#define MACE_UST_COMPARE2 (MACE_UST_BASE + 0x00000010) /* Interrupt compare reg 2 */
#define MACE_UST_COMPARE3 (MACE_UST_BASE + 0x00000018) /* Interrupt compare reg 3 */
#define MACE_UST_PERIOD_NS 960 /* UST Period in ns */
#define MACE_UST_AIN_MSC (MACE_UST_BASE + 0x00000020) /* Audio in MSC/UST pair */
#define MACE_UST_AOUT1_MSC (MACE_UST_BASE + 0x00000028) /* Audio out 1 MSC/UST pair */
#define MACE_UST_AOUT2_MSC (MACE_UST_BASE + 0x00000030) /* Audio out 2 MSC/UST pair */
#define MACE_VIN1_MSC_UST (MACE_UST_BASE + 0x00000038) /* Video In 1 MSC/UST pair */
#define MACE_VIN2_MSC_UST (MACE_UST_BASE + 0x00000040) /* Video In 2 MSC/UST pair */
#define MACE_VOUT_MSC_UST (MACE_UST_BASE + 0x00000048) /* Video out MSC/UST pair */
/*
* Mace "ISA" peripherals
*/
#define MACEISA_EPP_BASE (MACE_ISA_EXT )
#define MACEISA_ECP_BASE (MACE_ISA_EXT + 0x00008000)
#define MACEISA_SER1_BASE (MACE_ISA_EXT + 0x00010000)
#define MACEISA_SER2_BASE (MACE_ISA_EXT + 0x00018000)
#define MACEISA_RTC_BASE (MACE_ISA_EXT + 0x00020000)
#define MACEISA_GAME_BASE (MACE_ISA_EXT + 0x00030000)
/*
* Ringbase address and reset register - 64 bits
*/
#define MACEISA_RINGBASE MACE_ISA_BASE
/*
* Flash-ROM/LED/DP-RAM/NIC Controller Register - 64 bits (?)
*/
#define MACEISA_FLASH_NIC_REG (MACE_ISA_BASE + 0x00000008)
/*
* Bit definitions for that
*/
#define MACEISA_FLASH_WE BIT(0) /* 1=> Enable FLASH writes */
#define MACEISA_PWD_CLEAR BIT(1) /* 1=> PWD CLEAR jumper detected */
#define MACEISA_NIC_DEASSERT BIT(2)
#define MACEISA_NIC_DATA BIT(3)
#define MACEISA_LED_RED BIT(4) /* 0=> Illuminate RED LED */
#define MACEISA_LED_GREEN BIT(5) /* 0=> Illuminate GREEN LED */
#define MACEISA_DP_RAM_ENABLE BIT(6)
/*
* ISA interrupt and status registers - 32 bit
*/
#define MACEISA_INT_STAT (MACE_ISA_BASE + 0x00000014)
#define MACEISA_INT_MASK (MACE_ISA_BASE + 0x0000001c)
/*
* Bits in the status/mask registers
*/
#define MACEISA_AUDIO_SW_INT BIT (0)
#define MACEISA_AUDIO_SC_INT BIT (1)
#define MACEISA_AUDIO1_DMAT_INT BIT (2)
#define MACEISA_AUDIO1_OF_INT BIT (3)
#define MACEISA_AUDIO2_DMAT_INT BIT (4)
#define MACEISA_AUDIO2_MERR_INT BIT (5)
#define MACEISA_AUDIO3_DMAT_INT BIT (6)
#define MACEISA_AUDIO3_MERR_INT BIT (7)
#define MACEISA_RTC_INT BIT (8)
#define MACEISA_KEYB_INT BIT (9)
#define MACEISA_KEYB_POLL_INT BIT (10)
#define MACEISA_MOUSE_INT BIT (11)
#define MACEISA_MOUSE_POLL_INT BIT (12)
#define MACEISA_TIMER0_INT BIT (13)
#define MACEISA_TIMER1_INT BIT (14)
#define MACEISA_TIMER2_INT BIT (15)
#define MACEISA_PARALLEL_INT BIT (16)
#define MACEISA_PAR_CTXA_INT BIT (17)
#define MACEISA_PAR_CTXB_INT BIT (18)
#define MACEISA_PAR_MERR_INT BIT (19)
#define MACEISA_SERIAL1_INT BIT (20)
#define MACEISA_SERIAL1_TDMAT_INT BIT (21)
#define MACEISA_SERIAL1_TDMAPR_INT BIT (22)
#define MACEISA_SERIAL1_TDMAME_INT BIT (23)
#define MACEISA_SERIAL1_RDMAT_INT BIT (24)
#define MACEISA_SERIAL1_RDMAOR_INT BIT (25)
#define MACEISA_SERIAL2_INT BIT (26)
#define MACEISA_SERIAL2_TDMAT_INT BIT (27)
#define MACEISA_SERIAL2_TDMAPR_INT BIT (28)
#define MACEISA_SERIAL2_TDMAME_INT BIT (29)
#define MACEISA_SERIAL2_RDMAT_INT BIT (30)
#define MACEISA_SERIAL2_RDMAOR_INT BIT (31)
#ifndef __ASSEMBLY__
#include <asm/types.h>
/*
* XXX Some of these are probably not needed (or even legal?)
*/
static inline u8 mace_read_8 (unsigned long __offset)
{
return *((volatile u8 *) (MACE_BASE + __offset));
}
static inline u16 mace_read_16 (unsigned long __offset)
{
return *((volatile u16 *) (MACE_BASE + __offset));
}
static inline u32 mace_read_32 (unsigned long __offset)
{
return *((volatile u32 *) (MACE_BASE + __offset));
}
static inline u64 mace_read_64 (unsigned long __offset)
{
return *((volatile u64 *) (MACE_BASE + __offset));
}
static inline void mace_write_8 (unsigned long __offset, u8 __val)
{
*((volatile u8 *) (MACE_BASE + __offset)) = __val;
}
static inline void mace_write_16 (unsigned long __offset, u16 __val)
{
*((volatile u16 *) (MACE_BASE + __offset)) = __val;
}
static inline void mace_write_32 (unsigned long __offset, u32 __val)
{
*((volatile u32 *) (MACE_BASE + __offset)) = __val;
}
static inline void mace_write_64 (unsigned long __offset, u64 __val)
{
*((volatile u64 *) (MACE_BASE + __offset)) = __val;
}
/* Call it whenever device needs to read data from main memory coherently */
static inline void mace_inv_read_buffers(void)
{
/* mace_write_32(MACEPCI_WFLUSH,0xffffffff);*/
}
#endif /* !__ASSEMBLY__ */
#endif /* __ASM_MACE_H__ */
/*
* machine.h -- Machine/group probing for ip32
*
* Copyright (C) 2001 Keith M Wesolowski
*
* 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 _ASM_IP32_MACHINE_H
#define _ASM_IP32_MACHINE_H
#include <linux/config.h>
#ifdef CONFIG_SGI_IP32
#define SGI_MACH_O2 0x3201
#endif /* CONFIG_SGI_IP32 */
#endif /* _ASM_SGI_MACHINE_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment