diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-01-26 00:07:44 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-01-26 00:07:44 +0000 |
commit | 38f0dc890f23f8de14abe63f60a9f9bf3be40271 (patch) | |
tree | 99c5b1e021cc51f059d55c7efa4b74f3f4d8a80d /arch/mips | |
parent | 07ebee0bea931f0d373e40205c932cae6b00a86d (diff) |
Support for the NEC DDB Vrc-5074 evaluation board. Patches by
Geert Uytterhoeven (geert@linux-m68k.org).
Diffstat (limited to 'arch/mips')
-rw-r--r-- | arch/mips/Makefile | 13 | ||||
-rw-r--r-- | arch/mips/config.in | 9 | ||||
-rw-r--r-- | arch/mips/ddb5074/.cvsignore | 2 | ||||
-rw-r--r-- | arch/mips/ddb5074/Makefile | 22 | ||||
-rw-r--r-- | arch/mips/ddb5074/int-handler.S | 122 | ||||
-rw-r--r-- | arch/mips/ddb5074/irq.c | 230 | ||||
-rw-r--r-- | arch/mips/ddb5074/nile4.c | 294 | ||||
-rw-r--r-- | arch/mips/ddb5074/pci.c | 320 | ||||
-rw-r--r-- | arch/mips/ddb5074/prom.c | 40 | ||||
-rw-r--r-- | arch/mips/ddb5074/setup.c | 239 | ||||
-rw-r--r-- | arch/mips/ddb5074/time.c | 35 | ||||
-rw-r--r-- | arch/mips/kernel/Makefile | 5 | ||||
-rw-r--r-- | arch/mips/kernel/irq.c | 14 | ||||
-rw-r--r-- | arch/mips/kernel/proc.c | 4 | ||||
-rw-r--r-- | arch/mips/kernel/setup.c | 8 | ||||
-rw-r--r-- | arch/mips/kernel/time.c | 21 | ||||
-rw-r--r-- | arch/mips/mm/init.c | 5 |
17 files changed, 1368 insertions, 15 deletions
diff --git a/arch/mips/Makefile b/arch/mips/Makefile index f839b134f..41c3c7ffa 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.20 1999/08/20 21:59:01 ralf Exp $ +# $Id: Makefile,v 1.21 1999/09/28 22:25:44 ralf Exp $ # # 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 @@ -37,7 +37,7 @@ endif # crossformat linking we rely on the elf2ecoff tool for format conversion. # CFLAGS += -G 0 -mno-abicalls -fno-pic -LINKFLAGS += -static -G 0 -N +LINKFLAGS += -static -G 0 MODFLAGS += -mlong-calls ifdef CONFIG_REMOTE_DEBUG @@ -128,6 +128,15 @@ LIBS += arch/mips/baget/baget.a arch/mips/baget/prom/bagetlib.a endif # +# NEC DDB Vrc-5074 +# +ifdef CONFIG_DDB5074 +SUBDIRS += arch/mips/ddb5074 +LIBS += arch/mips/ddb5074/ddb5074.a +LOADADDR += 0x80080000 +endif + +# # Choosing incompatible machines durings configuration will result in # error messages during linking. Select a default linkscript if # none has been choosen above. diff --git a/arch/mips/config.in b/arch/mips/config.in index 72a4b4cd9..9fc20b48e 100644 --- a/arch/mips/config.in +++ b/arch/mips/config.in @@ -1,4 +1,4 @@ -# $Id: config.in,v 1.33 1999/12/04 03:58:59 ralf Exp $ +# $Id: config.in,v 1.34 2000/01/23 21:12:56 ralf Exp $ # For a description of the syntax of this configuration file, # see the Configure script. # @@ -16,6 +16,7 @@ if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then bool 'Support for Algorithmics P4032 (EXPERIMENTAL)' CONFIG_ALGOR_P4032 bool 'Support for BAGET MIPS series (EXPERIMENTAL)' CONFIG_BAGET_MIPS bool 'Support for DECstations (EXPERIMENTAL)' CONFIG_DECSTATION + bool 'Support for NEC DDB Vrc-5074 (EXPERIMENTAL)' CONFIG_DDB5074 fi bool 'Support for Mips Magnum 4000' CONFIG_MIPS_MAGNUM_4000 bool 'Support for Olivetti M700-10' CONFIG_OLIVETTI_M700 @@ -51,6 +52,10 @@ if [ "$CONFIG_SNI_RM200_PCI" = "y" ]; then define_bool CONFIG_HAVE_IO_PORTS y define_bool CONFIG_PCI y fi +if [ "$CONFIG_DDB5074" = "y" ]; then + define_bool CONFIG_PCI y + define_bool CONFIG_HAVE_IO_PORTS y +fi endmenu mainmenu_option next_comment @@ -99,7 +104,7 @@ endmenu mainmenu_option next_comment comment 'General setup' -if [ "$CONFIG_DECSTATION" = "y" ]; then +if [ "$CONFIG_DECSTATION" = "y" -o "$CONFIG_DDB5074" = "y" ]; then define_bool CONFIG_CPU_LITTLE_ENDIAN y else bool 'Generate little endian code' CONFIG_CPU_LITTLE_ENDIAN diff --git a/arch/mips/ddb5074/.cvsignore b/arch/mips/ddb5074/.cvsignore new file mode 100644 index 000000000..857dd22e9 --- /dev/null +++ b/arch/mips/ddb5074/.cvsignore @@ -0,0 +1,2 @@ +.depend +.*.flags diff --git a/arch/mips/ddb5074/Makefile b/arch/mips/ddb5074/Makefile new file mode 100644 index 000000000..d041acef5 --- /dev/null +++ b/arch/mips/ddb5074/Makefile @@ -0,0 +1,22 @@ +# +# Makefile for the NEC DDB Vrc-5074 specific kernel interface routines +# under Linux. +# +# 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... +# +# $Id$ +# + +.S.s: + $(CPP) $(CFLAGS) $< -o $*.s +.S.o: + $(CC) $(CFLAGS) -c $< -o $*.o + +O_TARGET = ddb5074.a +O_OBJS = setup.o irq.o time.o prom.o pci.o int-handler.o nile4.o + +include $(TOPDIR)/Rules.make diff --git a/arch/mips/ddb5074/int-handler.S b/arch/mips/ddb5074/int-handler.S new file mode 100644 index 000000000..07d091953 --- /dev/null +++ b/arch/mips/ddb5074/int-handler.S @@ -0,0 +1,122 @@ +/* + * arch/mips/ddb5074/int-handler.S -- NEC DDB Vrc-5074 interrupt handler + * + * Based on arch/mips/sgi/kernel/indyIRQ.S + * + * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com> + * + * $Id$ + */ + +#include <asm/asm.h> +#include <asm/mipsregs.h> +#include <asm/regdef.h> +#include <asm/stackframe.h> + + /* A lot of complication here is taken away because: + * + * 1) We handle one interrupt and return, sitting in a loop + * and moving across all the pending IRQ bits in the cause + * register is _NOT_ the answer, the common case is one + * pending IRQ so optimize in that direction. + * + * 2) We need not check against bits in the status register + * IRQ mask, that would make this routine slow as hell. + * + * 3) Linux only thinks in terms of all IRQs on or all IRQs + * off, nothing in between like BSD spl() brain-damage. + * + * Furthermore, the IRQs on the INDY look basically (barring + * software IRQs which we don't use at all) like: + * + * MIPS IRQ Source + * -------- ------ + * 0 Software (ignored) + * 1 Software (ignored) + * 2 Local IRQ level zero + * 3 Local IRQ level one + * 4 8254 Timer zero + * 5 8254 Timer one + * 6 Bus Error + * 7 R4k timer (what we use) + * + * We handle the IRQ according to _our_ priority which is: + * + * Highest ---- R4k Timer + * Local IRQ zero + * Local IRQ one + * Bus Error + * 8254 Timer zero + * Lowest ---- 8254 Timer one + * + * then we just return, if multiple IRQs are pending then + * we will just take another exception, big deal. + */ + + .text + .set noreorder + .set noat + .align 5 + NESTED(ddbIRQ, PT_SIZE, sp) + SAVE_ALL + CLI + .set at + mfc0 s0, CP0_CAUSE # get irq mask + +#if 1 + mfc0 t2,CP0_STATUS # get enabled interrupts + and s0,t2 # isolate allowed ones +#endif + /* First we check for r4k counter/timer IRQ. */ + andi a0, s0, CAUSEF_IP2 # delay slot, check local level zero + beq a0, zero, 1f + andi a0, s0, CAUSEF_IP3 # delay slot, check local level one + + /* Wheee, local level zero interrupt. */ + jal ddb_local0_irqdispatch + move a0, sp # delay slot + + j ret_from_irq + nop # delay slot + +1: + beq a0, zero, 1f + andi a0, s0, CAUSEF_IP6 # delay slot, check bus error + + /* Wheee, local level one interrupt. */ + move a0, sp + jal ddb_local1_irqdispatch + nop + + j ret_from_irq + nop + +1: + beq a0, zero, 1f + nop + + /* Wheee, an asynchronous bus error... */ + move a0, sp + jal ddb_buserror_irq + nop + + j ret_from_irq + nop + +1: + /* Here by mistake? This is possible, what can happen + * is that by the time we take the exception the IRQ + * pin goes low, so just leave if this is the case. + */ + andi a0, s0, (CAUSEF_IP4 | CAUSEF_IP5) + beq a0, zero, 1f + + /* Must be one of the 8254 timers... */ + move a0, sp + jal ddb_8254timer_irq + nop +1: + j ret_from_irq + nop + END(ddbIRQ) diff --git a/arch/mips/ddb5074/irq.c b/arch/mips/ddb5074/irq.c new file mode 100644 index 000000000..1faba4c5c --- /dev/null +++ b/arch/mips/ddb5074/irq.c @@ -0,0 +1,230 @@ +/* + * arch/mips/ddb5074/irq.c -- NEC DDB Vrc-5074 interrupt routines + * + * Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com> + * Sony Suprastructure Center Europe (SUPC-E), Brussels + * + * $Id$ + */ + +#include <linux/init.h> +#include <linux/signal.h> +#include <linux/sched.h> +#include <linux/types.h> +#include <linux/interrupt.h> +#include <linux/ioport.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/ptrace.h> +#include <asm/nile4.h> +#include <asm/ddb5074.h> + + +extern void __init i8259_init(void); +extern void i8259_disable_irq(unsigned int irq_nr); +extern void i8259_enable_irq(unsigned int irq_nr); + +extern asmlinkage void ddbIRQ(void); +extern asmlinkage void i8259_do_irq(int irq, struct pt_regs *regs); +extern asmlinkage void do_IRQ(int irq, struct pt_regs * regs); + + +static void no_action(int cpl, void *dev_id, struct pt_regs *regs) +{ +} + + +#define M1543_PNP_CONFIG 0x03f0 /* PnP Config Port */ +#define M1543_PNP_INDEX 0x03f0 /* PnP Index Port */ +#define M1543_PNP_DATA 0x03f1 /* PnP Data Port */ + +#define M1543_PNP_ALT_CONFIG 0x0370 /* Alternative PnP Config Port */ +#define M1543_PNP_ALT_INDEX 0x0370 /* Alternative PnP Index Port */ +#define M1543_PNP_ALT_DATA 0x0371 /* Alternative PnP Data Port */ + +#define M1543_INT1_MASTER_CTRL 0x0020 /* INT_1 (master) Control Register */ +#define M1543_INT1_MASTER_MASK 0x0021 /* INT_1 (master) Mask Register */ + +#define M1543_INT1_SLAVE_CTRL 0x00a0 /* INT_1 (slave) Control Register */ +#define M1543_INT1_SLAVE_MASK 0x00a1 /* INT_1 (slave) Mask Register */ + +#define M1543_INT1_MASTER_ELCR 0x04d0 /* INT_1 (master) Edge/Level Control */ +#define M1543_INT1_SLAVE_ELCR 0x04d1 /* INT_1 (slave) Edge/Level Control */ + + +static void m1543_irq_setup(void) +{ + /* + * The ALI M1543 has 13 interrupt inputs, IRQ1..IRQ13. Not all + * the possible IO sources in the M1543 are in use by us. We will + * use the following mapping: + * + * IRQ1 - keyboard (default set by M1543) + * IRQ3 - reserved for UART B (default set by M1543) (note that + * the schematics for the DDB Vrc-5074 board seem to + * indicate that IRQ3 is connected to the DS1386 + * watchdog timer interrupt output so we might have + * a conflict) + * IRQ4 - reserved for UART A (default set by M1543) + * IRQ5 - parallel (default set by M1543) + * IRQ8 - DS1386 time of day (RTC) interrupt + * IRQ12 - mouse + */ + + /* + * Assing mouse interrupt to IRQ12 + */ + + /* Enter configuration mode */ + outb(0x51, M1543_PNP_CONFIG); + outb(0x23, M1543_PNP_CONFIG); + + /* Select logical device 7 (Keyboard) */ + outb(0x07, M1543_PNP_INDEX); + outb(0x07, M1543_PNP_DATA); + + /* Select IRQ12 */ + outb(0x72, M1543_PNP_INDEX); + outb(0x0c, M1543_PNP_DATA); + + /* Leave configration mode */ + outb(0xbb, M1543_PNP_CONFIG); + + + /* Initialize the 8259 PIC in the M1543 */ + i8259_init(); + + /* Enable the interrupt cascade */ + nile4_enable_irq(NILE4_INT_INTE); + + request_region(M1543_PNP_CONFIG, 2, "M1543 config"); + request_region(M1543_INT1_MASTER_ELCR, 2, "pic ELCR"); +} + +static void nile4_irq_setup(void) +{ + int i; + + /* Map all interrupts to CPU int #0 */ + nile4_map_irq_all(0); + + /* PCI INTA#-E# must be level triggered */ + nile4_set_pci_irq_level_or_edge(0, 1); + nile4_set_pci_irq_level_or_edge(1, 1); + nile4_set_pci_irq_level_or_edge(2, 1); + nile4_set_pci_irq_level_or_edge(3, 1); + nile4_set_pci_irq_level_or_edge(4, 1); + + /* PCI INTA#-D# must be active low, INTE# must be active high */ + nile4_set_pci_irq_polarity(0, 0); + nile4_set_pci_irq_polarity(1, 0); + nile4_set_pci_irq_polarity(2, 0); + nile4_set_pci_irq_polarity(3, 0); + nile4_set_pci_irq_polarity(4, 1); + + for (i = 0; i < 16; i++) + nile4_clear_irq(i); + + /* Enable CPU int #0 */ + nile4_enable_irq_output(0); + + request_mem_region(NILE4_BASE, NILE4_SIZE, "Nile 4"); +} + + +/* + * IRQ2 is cascade interrupt to second interrupt controller + */ + +static struct irqaction irq2 = { no_action, 0, 0, "cascade", NULL, NULL }; + + +void disable_irq(unsigned int irq_nr) +{ + if (is_i8259_irq(irq_nr)) + i8259_disable_irq(irq_nr); + else + nile4_disable_irq(irq_to_nile4(irq_nr)); +} + +void enable_irq(unsigned int irq_nr) +{ + if (is_i8259_irq(irq_nr)) + i8259_enable_irq(irq_nr); + else + nile4_enable_irq(irq_to_nile4(irq_nr)); +} + +int table[16] = { 0, }; + +void ddb_local0_irqdispatch(struct pt_regs *regs) +{ + u32 mask; + int nile4_irq; +#if 1 + volatile static int nesting = 0; + if (nesting++ == 0) + ddb5074_led_d3(1); + ddb5074_led_hex(nesting < 16 ? nesting : 15); +#endif + + mask = nile4_get_irq_stat(0); + nile4_clear_irq_mask(mask); + + /* Handle the timer interrupt first */ + if (mask & (1<<NILE4_INT_GPT)) { + nile4_disable_irq(NILE4_INT_GPT); + do_IRQ(nile4_to_irq(NILE4_INT_GPT), regs); + nile4_enable_irq(NILE4_INT_GPT); + mask &= ~(1<<NILE4_INT_GPT); + } + for (nile4_irq = 0; mask; nile4_irq++, mask >>= 1) + if (mask & 1) { + nile4_disable_irq(nile4_irq); + if (nile4_irq == NILE4_INT_INTE) { + int i8259_irq = nile4_i8259_iack(); + i8259_do_irq(i8259_irq, regs); + } else + do_IRQ(nile4_to_irq(nile4_irq), regs); + nile4_enable_irq(nile4_irq); + } + +#if 1 + if (--nesting == 0) + ddb5074_led_d3(0); + ddb5074_led_hex(nesting < 16 ? nesting : 15); +#endif +} + +void ddb_local1_irqdispatch(void) +{ + printk("ddb_local1_irqdispatch called\n"); +} + +void ddb_buserror_irq(void) +{ + printk("ddb_buserror_irq called\n"); +} + +void ddb_8254timer_irq(void) +{ + printk("ddb_8254timer_irq called\n"); +} + +void __init ddb_irq_setup(void) +{ +#ifdef CONFIG_REMOTE_DEBUG + if (remote_debug) + set_debug_traps(); + breakpoint(); /* you may move this line to whereever you want :-) */ +#endif + request_region(0x20, 0x20, "pic1"); + request_region(0xa0, 0x20, "pic2"); + i8259_setup_irq(2, &irq2); + + nile4_irq_setup(); + m1543_irq_setup(); + + set_except_vector(0, ddbIRQ); +} + diff --git a/arch/mips/ddb5074/nile4.c b/arch/mips/ddb5074/nile4.c new file mode 100644 index 000000000..b670e78f2 --- /dev/null +++ b/arch/mips/ddb5074/nile4.c @@ -0,0 +1,294 @@ +/* + * arch/mips/ddb5074/nile4.c -- NEC Vrc-5074 Nile 4 support routines + * + * Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com> + * Sony Suprastructure Center Europe (SUPC-E), Brussels + * + * $Id$ + */ + +#include <linux/kernel.h> +#include <linux/types.h> +#include <asm/nile4.h> + + + /* + * Physical Device Address Registers + * + * Note: 32 bit addressing only! + */ + +void nile4_set_pdar(u32 pdar, u32 phys, u32 size, int width, int on_memory_bus, + int visible) +{ + u32 maskbits; + u32 widthbits; + + if (pdar > NILE4_BOOTCS || (pdar & 7)) { + printk("nile4_set_pdar: invalid pdar %d\n", pdar); + return; + } + if (pdar == NILE4_INTCS && size != 0x00200000) { + printk("nile4_set_pdar: INTCS size must be 2 MB\n"); + return; + } + switch (size) { +#if 0 /* We don't support 4 GB yet */ + case 0x100000000: /* 4 GB */ + maskbits = 4; + break; +#endif + case 0x80000000: /* 2 GB */ + maskbits = 5; + break; + case 0x40000000: /* 1 GB */ + maskbits = 6; + break; + case 0x20000000: /* 512 MB */ + maskbits = 7; + break; + case 0x10000000: /* 256 MB */ + maskbits = 8; + break; + case 0x08000000: /* 128 MB */ + maskbits = 9; + break; + case 0x04000000: /* 64 MB */ + maskbits = 10; + break; + case 0x02000000: /* 32 MB */ + maskbits = 11; + break; + case 0x01000000: /* 16 MB */ + maskbits = 12; + break; + case 0x00800000: /* 8 MB */ + maskbits = 13; + break; + case 0x00400000: /* 4 MB */ + maskbits = 14; + break; + case 0x00200000: /* 2 MB */ + maskbits = 15; + break; + case 0: /* OFF */ + maskbits = 0; + break; + default: + printk("nile4_set_pdar: unsupported size %p\n", (void *)size); + return; + } + switch (width) { + case 8: + widthbits = 0; + break; + case 16: + widthbits = 1; + break; + case 32: + widthbits = 2; + break; + case 64: + widthbits = 3; + break; + default: + printk("nile4_set_pdar: unsupported width %d\n", width); + return; + } + nile4_out32(pdar, maskbits | (on_memory_bus ? 0x10 : 0) | + (visible ? 0x20 : 0) | (widthbits << 6) | + (phys & 0xffe00000)); + nile4_out32(pdar+4, 0); + /* + * When programming a PDAR, the register should be read immediately after + * writing it. This ensures that address decoders are properly configured. + */ + (void)nile4_in32(pdar); + (void)nile4_in32(pdar+4); +} + + + /* + * PCI Master Registers + * + * Note: 32 bit addressing only! + */ + +void nile4_set_pmr(u32 pmr, u32 type, u32 addr) +{ + if (pmr != NILE4_PCIINIT0 && pmr != NILE4_PCIINIT1) { + printk("nile4_set_pmr: invalid pmr %d\n", pmr); + return; + } + switch (type) { + case NILE4_PCICMD_IACK: /* PCI Interrupt Acknowledge */ + case NILE4_PCICMD_IO: /* PCI I/O Space */ + case NILE4_PCICMD_MEM: /* PCI Memory Space */ + case NILE4_PCICMD_CFG: /* PCI Configuration Space */ + break; + default: + printk("nile4_set_pmr: invalid type %d\n", type); + return; + } + nile4_out32(pmr, (type << 1) | 0x10 | (addr & 0xffe00000)); + nile4_out32(pmr+4, 0); +} + + + /* + * Interrupt Programming + */ + +void nile4_map_irq(int nile4_irq, int cpu_irq) +{ + u32 offset, t; + + offset = NILE4_INTCTRL; + if (nile4_irq >= 8) { + offset += 4; + nile4_irq -= 8; + } + t = nile4_in32(offset); + t &= ~(7 << (nile4_irq*4)); + t |= cpu_irq << (nile4_irq*4); + nile4_out32(offset, t); +} + +void nile4_map_irq_all(int cpu_irq) +{ + u32 all, t; + + all = cpu_irq; + all |= all << 4; + all |= all << 8; + all |= all << 16; + t = nile4_in32(NILE4_INTCTRL); + t &= 0x88888888; + t |= all; + nile4_out32(NILE4_INTCTRL, t); + t = nile4_in32(NILE4_INTCTRL+4); + t &= 0x88888888; + t |= all; + nile4_out32(NILE4_INTCTRL+4, t); +} + +void nile4_enable_irq(int nile4_irq) +{ + u32 offset, t; + + offset = NILE4_INTCTRL; + if (nile4_irq >= 8) { + offset += 4; + nile4_irq -= 8; + } + t = nile4_in32(offset); + t |= 8 << (nile4_irq*4); + nile4_out32(offset, t); +} + +void nile4_disable_irq(int nile4_irq) +{ + u32 offset, t; + + offset = NILE4_INTCTRL; + if (nile4_irq >= 8) { + offset += 4; + nile4_irq -= 8; + } + t = nile4_in32(offset); + t &= ~(8 << (nile4_irq*4)); + nile4_out32(offset, t); +} + +void nile4_disable_irq_all(void) +{ + nile4_out32(NILE4_INTCTRL, 0); + nile4_out32(NILE4_INTCTRL+4, 0); +} + +u16 nile4_get_irq_stat(int cpu_irq) +{ + return nile4_in16(NILE4_INTSTAT0+cpu_irq*2); +} + +void nile4_enable_irq_output(int cpu_irq) +{ + u32 t; + + t = nile4_in32(NILE4_INTSTAT1+4); + t |= 1 << (16+cpu_irq); + nile4_out32(NILE4_INTSTAT1, t); +} + +void nile4_disable_irq_output(int cpu_irq) +{ + u32 t; + + t = nile4_in32(NILE4_INTSTAT1+4); + t &= ~(1 << (16+cpu_irq)); + nile4_out32(NILE4_INTSTAT1, t); +} + +void nile4_set_pci_irq_polarity(int pci_irq, int high) +{ + u32 t; + + t = nile4_in32(NILE4_INTPPES); + if (high) + t &= ~(1 << (pci_irq*2)); + else + t |= 1 << (pci_irq*2); + nile4_out32(NILE4_INTPPES, t); +} + +void nile4_set_pci_irq_level_or_edge(int pci_irq, int level) +{ + u32 t; + + t = nile4_in32(NILE4_INTPPES); + if (level) + t |= 2 << (pci_irq*2); + else + t &= ~(2 << (pci_irq*2)); + nile4_out32(NILE4_INTPPES, t); +} + +void nile4_clear_irq(int nile4_irq) +{ + nile4_out32(NILE4_INTCLR, 1 << nile4_irq); +} + +void nile4_clear_irq_mask(u32 mask) +{ + nile4_out32(NILE4_INTCLR, mask); +} + +u8 nile4_i8259_iack(void) +{ + u8 irq; + + /* Set window 0 for interrupt acknowledge */ + nile4_set_pmr(NILE4_PCIINIT0, NILE4_PCICMD_IACK, 0); + irq = *(volatile u8 *)NILE4_PCI_IACK_BASE; + /* Set window 0 for PCI I/O space */ + nile4_set_pmr(NILE4_PCIINIT0, NILE4_PCICMD_IO, 0); + return irq; +} + +#if 0 +void nile4_dump_irq_status(void) +{ + printk("CPUSTAT = %p:%p\n", (void *)nile4_in32(NILE4_CPUSTAT+4), + (void *)nile4_in32(NILE4_CPUSTAT)); + printk("INTCTRL = %p:%p\n", (void *)nile4_in32(NILE4_INTCTRL+4), + (void *)nile4_in32(NILE4_INTCTRL)); + printk("INTSTAT0 = %p:%p\n", (void *)nile4_in32(NILE4_INTSTAT0+4), + (void *)nile4_in32(NILE4_INTSTAT0)); + printk("INTSTAT1 = %p:%p\n", (void *)nile4_in32(NILE4_INTSTAT1+4), + (void *)nile4_in32(NILE4_INTSTAT1)); + printk("INTCLR = %p:%p\n", (void *)nile4_in32(NILE4_INTCLR+4), + (void *)nile4_in32(NILE4_INTCLR)); + printk("INTPPES = %p:%p\n", (void *)nile4_in32(NILE4_INTPPES+4), + (void *)nile4_in32(NILE4_INTPPES)); +} +#endif diff --git a/arch/mips/ddb5074/pci.c b/arch/mips/ddb5074/pci.c new file mode 100644 index 000000000..2fcd3fbf7 --- /dev/null +++ b/arch/mips/ddb5074/pci.c @@ -0,0 +1,320 @@ +/* + * arch/mips/ddb5074/pci.c -- NEC DDB Vrc-5074 PCI access routines + * + * Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com> + * Albert Dorofeev <albert@sonycom.com> + * Sony Suprastructure Center Europe (SUPC-E), Brussels + * + * $Id$ + */ + +#include <linux/init.h> +#include <linux/config.h> +#include <linux/kernel.h> +#include <linux/pci.h> +#include <linux/types.h> +#include <linux/sched.h> +#include <linux/pci.h> +#include <linux/ioport.h> +#include <asm-mips/nile4.h> + + +static u32 nile4_pre_pci_access0(int slot_num) +{ + u32 pci_addr = 0; + u32 virt_addr = NILE4_PCI_CFG_BASE; + + /* Set window 1 address 8000000 - 64 bit - 2 MB (PCI config space) */ + nile4_set_pdar(NILE4_PCIW1, PHYSADDR(virt_addr), 0x00200000, 64, 0, 0); + if (slot_num > 2) + pci_addr = 0x00040000 << slot_num; + else + virt_addr += 0x00040000 << slot_num; + nile4_set_pmr(NILE4_PCIINIT1, NILE4_PCICMD_CFG, pci_addr); + return virt_addr; +} + +static void nile4_post_pci_access0(void) +{ + /* Set window 1 back to address 8000000 - 64 bit - 128 MB (PCI IO space) */ + nile4_set_pdar(NILE4_PCIW1, PHYSADDR(NILE4_PCI_MEM_BASE), 0x08000000, 64, + 1, 1); + nile4_set_pmr(NILE4_PCIINIT1, NILE4_PCICMD_MEM, 0); +} + + +static int nile4_pci_read_config_dword( struct pci_dev *dev, + int where, u32 *val) +{ + int slot_num, func_num; + u32 base; + + /* + * For starters let's do configuration cycle 0 only (one bus only) + */ + if (dev->bus->number) + return PCIBIOS_FUNC_NOT_SUPPORTED; + + slot_num = PCI_SLOT(dev->devfn); + func_num = PCI_FUNC(dev->devfn); + if (slot_num == 5) { + /* + * This is Nile 4 and it will crash if we access it like other + * devices + */ + *val = nile4_in32(NILE4_PCI_BASE + where); + return PCIBIOS_SUCCESSFUL; + } + base = nile4_pre_pci_access0(slot_num); + *val = *((volatile u32 *)(base + (func_num << 8) + (where & 0xfc))); + nile4_post_pci_access0(); + return PCIBIOS_SUCCESSFUL; +} + +static int nile4_pci_write_config_dword(struct pci_dev *dev, int where, + u32 val) +{ + int slot_num, func_num; + u32 base; + + /* + * For starters let's do configuration cycle 0 only (one bus only) + */ + if (dev->bus->number) + return PCIBIOS_FUNC_NOT_SUPPORTED; + + slot_num = PCI_SLOT(dev->devfn); + func_num = PCI_FUNC(dev->devfn); + if (slot_num == 5) { + /* + * This is Nile 4 and it will crash if we access it like other + * devices + */ + nile4_out32(NILE4_PCI_BASE + where, val); + return PCIBIOS_SUCCESSFUL; + } + base = nile4_pre_pci_access0(slot_num); + *((volatile u32 *)(base + (func_num << 8) + (where & 0xfc))) = val; + nile4_post_pci_access0(); + return PCIBIOS_SUCCESSFUL; +} + +static int nile4_pci_read_config_word(struct pci_dev *dev, int where, u16 *val) +{ + int status; + u32 result; + + status = nile4_pci_read_config_dword(dev, where, &result); + if (status != PCIBIOS_SUCCESSFUL) + return status; + if (where & 2) + result >>= 16; + *val = result & 0xffff; + return PCIBIOS_SUCCESSFUL; +} + +static int nile4_pci_read_config_byte(struct pci_dev *dev, int where, u8 *val) +{ + int status; + u32 result; + + status = nile4_pci_read_config_dword(dev, where, &result); + if (status != PCIBIOS_SUCCESSFUL) + return status; + if (where & 1) + result >>= 8; + if (where & 2) + result >>= 16; + *val = result & 0xff; + return PCIBIOS_SUCCESSFUL; +} + +static int nile4_pci_write_config_word(struct pci_dev *dev, int where, u16 val) +{ + int status, shift = 0; + u32 result; + + status = nile4_pci_read_config_dword(dev, where, &result); + if (status != PCIBIOS_SUCCESSFUL) + return status; + if (where & 2) + shift += 16; + result &= ~(0xffff << shift); + result |= val << shift; + return nile4_pci_write_config_dword(dev, where, result); +} + +static int nile4_pci_write_config_byte( struct pci_dev *dev, int where, u8 val) +{ + int status, shift = 0; + u32 result; + + status = nile4_pci_read_config_dword(dev, where, &result); + if (status != PCIBIOS_SUCCESSFUL) + return status; + if (where & 2) + shift += 16; + if (where & 1) + shift += 8; + result &= ~(0xff << shift); + result |= val << shift; + return nile4_pci_write_config_dword(dev, where, result); +} + +struct pci_ops nile4_pci_ops = { + nile4_pci_read_config_byte, + nile4_pci_read_config_word, + nile4_pci_read_config_dword, + nile4_pci_write_config_byte, + nile4_pci_write_config_word, + nile4_pci_write_config_dword +}; + + +static void __init pcibios_claim_resources(struct pci_bus *bus) +{ + struct pci_dev *dev; + int idx; + + while (bus) { + for (dev=bus->devices; dev; dev=dev->sibling) { + for (idx = 0; idx < PCI_NUM_RESOURCES; idx++) { + struct resource *r = &dev->resource[idx]; + struct resource *pr; + if (!r->start) + continue; + pr = pci_find_parent_resource(dev, r); + if (!pr || request_resource(pr, r) < 0) { + printk(KERN_ERR "PCI: Address space collision on region %d of device %s\n", idx, dev->name); + /* We probably should disable the region, shouldn't we? */ + } + } + } + if (bus->children) + pcibios_claim_resources(bus->children); + bus = bus->next; + } +} + + +void pcibios_init(void) +{ + printk("PCI: Probing PCI hardware\n"); + ioport_resource.end = 0x1ffffff; + pci_scan_bus(0, &nile4_pci_ops, NULL); + pcibios_claim_resources(pci_root); + +#if 0 + { + char buf[PAGE_SIZE]; + printk("*** PCI Devices ***\n"); + get_pci_list(buf); + printk(buf); + printk("*** PCI I/O Space ***\n"); + buf[0] = '\0'; + get_ioport_list(buf); + printk(buf); + printk("*** PCI Memory ***\n"); + buf[0] = '\0'; + get_mem_list(buf); + printk(buf); + } +#endif +} + +void pcibios_fixup_bus(struct pci_bus *bus) +{ + struct pci_dev *dev; + extern struct pci_dev *pci_pmu; /* for LEDs D2 and D3 */ + u8 t8; + + /* + * FIXME: PMON doesn't autoconfigure the PCI devices + * For now we just hardcode them for our configuration + */ + for (dev = bus->devices; dev; dev = dev->sibling) { + int slot_num, func_num; + + slot_num = PCI_SLOT(dev->devfn); + func_num = PCI_FUNC(dev->devfn); + printk(" Device %2d: ", slot_num); + switch (slot_num) { + case 0: + printk("[onboard] Acer Labs M1533 Aladdin IV\n"); + dev->irq = nile4_to_irq(NILE4_INT_INTE); + break; + case 1: + printk("[onboard] DEC DC21140\n"); + dev->irq = nile4_to_irq(NILE4_INT_INTA); + dev->resource[0].start = 0x100000; + dev->resource[0].end = dev->resource[0].start+0x7f; + nile4_pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, + dev->resource[0].start); + dev->resource[1].start = 0x1000000; + dev->resource[1].end = dev->resource[1].start+0x7f; + nile4_pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, + dev->resource[1].start); + break; + case 2: + printk("[slot 1] Realtek 8029\n"); + dev->irq = nile4_to_irq(NILE4_INT_INTA); + dev->resource[0].start = 0x800000; + dev->resource[0].end = dev->resource[0].start+0x1f; + nile4_pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, + dev->resource[0].start); + break; + case 3: + printk("[slot 2] DEC DC21140 (#2)\n"); + dev->irq = nile4_to_irq(NILE4_INT_INTB); + dev->resource[0].start = 0x1000000; + dev->resource[0].end = dev->resource[0].start+0x7f; + nile4_pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, + dev->resource[0].start); + dev->resource[1].start = 0x4000000; + dev->resource[1].end = dev->resource[1].start+0x7f; + nile4_pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, + dev->resource[1].start); + break; + case 4: + printk("[slot 3] Promise Technology IDE UltraDMA/33"); + printk(" Or 3Com 3c905 :-)\n"); + dev->irq = nile4_to_irq(NILE4_INT_INTC); + dev->resource[0].start = 0x1800000; + dev->resource[0].end = dev->resource[0].start+0x7fffff; + nile4_pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, + dev->resource[0].start); + break; + case 10: + printk("[onboard] Acer Labs M7101 PMU\n"); + pci_pmu = dev; + /* Program the lines for LEDs D2 and D3 to output */ + nile4_pci_read_config_byte(dev, 0x7d, &t8); + t8 |= 0xc0; + nile4_pci_write_config_byte(dev, 0x7d, t8); + /* Turn LEDs D2 and D3 off */ + nile4_pci_read_config_byte(dev, 0x7e, &t8); + t8 |= 0xc0; + nile4_pci_write_config_byte(dev, 0x7e, t8); + break; + case 13: + printk("[onboard] Acer Labs M5237 USB\n"); + dev->irq = nile4_to_irq(NILE4_INT_INTE); + dev->resource[0].start = 0x1001000; + dev->resource[0].end = dev->resource[0].start+0xfff; + nile4_pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, + dev->resource[0].start); + break; + default: + printk("\n"); + break; + } + } +} + +char *pcibios_setup (char *str) +{ + return str; +} + +struct pci_fixup pcibios_fixups[] = {}; + diff --git a/arch/mips/ddb5074/prom.c b/arch/mips/ddb5074/prom.c new file mode 100644 index 000000000..277d37630 --- /dev/null +++ b/arch/mips/ddb5074/prom.c @@ -0,0 +1,40 @@ +/* + * arch/mips/ddb5074/prom.c -- NEC DDB Vrc-5074 PROM routines + * + * Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com> + * Sony Suprastructure Center Europe (SUPC-E), Brussels + * + * $Id$ + */ + +#include <linux/init.h> +#include <asm/addrspace.h> +#include <asm/bootinfo.h> + + +char arcs_cmdline[CL_SIZE]; + +void __init prom_init(const char *s) +{ + int i = 0; + +// _serinit(); + + if (s != (void *)-1) + while (*s && i < sizeof(arcs_cmdline)-1) + arcs_cmdline[i++] = *s++; + arcs_cmdline[i] = '\0'; + + mips_machgroup = MACH_GROUP_NEC_DDB; + mips_machtype = MACH_NEC_DDB5074; + /* 64 MB non-upgradable */ + mips_memory_upper = KSEG0+64*1024*1024; +} + +void __init prom_fixup_mem_map(unsigned long start, unsigned long end) +{ +} + +void __init prom_free_prom_memory(void) +{ +} diff --git a/arch/mips/ddb5074/setup.c b/arch/mips/ddb5074/setup.c new file mode 100644 index 000000000..69a455e30 --- /dev/null +++ b/arch/mips/ddb5074/setup.c @@ -0,0 +1,239 @@ +/* + * arch/mips/ddb5074/setup.c -- NEC DDB Vrc-5074 setup routines + * + * Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com> + * Sony Suprastructure Center Europe (SUPC-E), Brussels + * + * $Id$ + */ + +#include <linux/config.h> +#include <linux/init.h> +#include <linux/kbd_ll.h> +#include <linux/kernel.h> +#include <linux/kdev_t.h> +#include <linux/types.h> +#include <linux/console.h> +#include <linux/sched.h> +#include <linux/mc146818rtc.h> +#include <linux/pc_keyb.h> +#include <linux/pci.h> + +#include <asm/addrspace.h> +#include <asm/bcache.h> +#include <asm/keyboard.h> +#include <asm/irq.h> +#include <asm/reboot.h> +#include <asm/gdb-stub.h> +#include <asm/nile4.h> +#include <asm/ddb5074.h> + + +#ifdef CONFIG_REMOTE_DEBUG +extern void rs_kgdb_hook(int); +extern void breakpoint(void); +#endif + +#if defined(CONFIG_SERIAL_CONSOLE) +extern void console_setup(char *); +#endif + +extern struct rtc_ops ddb_rtc_ops; + +static void ddb_machine_restart(char *command) +{ + u32 t; + + // FIXME: This doesn't seem to work... + printk("Restarting DDB Vrc-5074..."); + /* PCI cold reset */ + t = nile4_in32(NILE4_PCICTRL+4); + t |= 0x40000000; + nile4_out32(NILE4_PCICTRL+4, t); + /* CPU cold reset */ + t = nile4_in32(NILE4_CPUSTAT); + t |= 1; + nile4_out32(NILE4_CPUSTAT, t); + printk("Restart failed!\n"); + do {} while (1); +} + +static void ddb_machine_halt(void) +{ + printk("DDB Vrc-5074 halted.\n"); + do {} while (1); +} + +static void ddb_machine_power_off(void) +{ + printk("DDB Vrc-5074 halted. Please turn off the power.\n"); + do {} while (1); +} + +extern void ddb_irq_setup(void); + +void (*board_time_init)(struct irqaction *irq); + + +static void __init ddb_time_init(struct irqaction *irq) +{ + /* set the clock to 1 Hz */ + nile4_out32(NILE4_T2CTRL, 1000000); + /* enable the General-Purpose Timer */ + nile4_out32(NILE4_T2CTRL+4, 0x00000001); + /* reset timer */ + nile4_out32(NILE4_T2CNTR, 0); + /* enable interrupt */ + nile4_enable_irq(NILE4_INT_GPT); + i8259_setup_irq(nile4_to_irq(NILE4_INT_GPT), irq); + set_cp0_status(ST0_IM, IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4); +} + +void __init ddb_setup(void) +{ + irq_setup = ddb_irq_setup; + mips_io_port_base = NILE4_PCI_IO_BASE; + isa_slot_offset = NILE4_PCI_MEM_BASE; + request_region(0x00, 0x20, "dma1"); + request_region(0x40, 0x20, "timer"); + request_region(0x70, 0x10, "rtc"); + request_region(0x80, 0x10, "dma page reg"); + request_region(0xc0, 0x20, "dma2"); + board_time_init = ddb_time_init; + + _machine_restart = ddb_machine_restart; + _machine_halt = ddb_machine_halt; + _machine_power_off = ddb_machine_power_off; + + rtc_ops = &ddb_rtc_ops; +} + + +#define USE_NILE4_SERIAL 0 + +#if USE_NILE4_SERIAL +#define ns16550_in(reg) nile4_in8((reg)*8) +#define ns16550_out(reg, val) nile4_out8((reg)*8, (val)) +#else +#define NS16550_BASE (NILE4_PCI_IO_BASE+0x03f8) +static inline u8 ns16550_in(u32 reg) +{ + return *(volatile u8 *)(NS16550_BASE+reg); +} + +static inline void ns16550_out(u32 reg, u8 val) +{ + *(volatile u8 *)(NS16550_BASE+reg) = val; +} +#endif + +#define NS16550_RBR 0 +#define NS16550_THR 0 +#define NS16550_DLL 0 +#define NS16550_IER 1 +#define NS16550_DLM 1 +#define NS16550_FCR 2 +#define NS16550_IIR 2 +#define NS16550_LCR 3 +#define NS16550_MCR 4 +#define NS16550_LSR 5 +#define NS16550_MSR 6 +#define NS16550_SCR 7 + +#define NS16550_LSR_DR 0x01 /* Data ready */ +#define NS16550_LSR_OE 0x02 /* Overrun */ +#define NS16550_LSR_PE 0x04 /* Parity error */ +#define NS16550_LSR_FE 0x08 /* Framing error */ +#define NS16550_LSR_BI 0x10 /* Break */ +#define NS16550_LSR_THRE 0x20 /* Xmit holding register empty */ +#define NS16550_LSR_TEMT 0x40 /* Xmitter empty */ +#define NS16550_LSR_ERR 0x80 /* Error */ + + +void _serinit(void) +{ +#if USE_NILE4_SERIAL + ns16550_out(NS16550_LCR, 0x80); + ns16550_out(NS16550_DLM, 0x00); + ns16550_out(NS16550_DLL, 0x36); /* 9600 baud */ + ns16550_out(NS16550_LCR, 0x00); + ns16550_out(NS16550_LCR, 0x03); + ns16550_out(NS16550_FCR, 0x47); +#else + /* done by PMON */ +#endif +} + +void _putc(char c) +{ + while (!(ns16550_in(NS16550_LSR) & NS16550_LSR_THRE)); + ns16550_out(NS16550_THR, c); + if (c == '\n') { + while (!(ns16550_in(NS16550_LSR) & NS16550_LSR_THRE)); + ns16550_out(NS16550_THR, '\r'); + } +} + +void _puts(const char *s) +{ + char c; + while ((c = *s++)) + _putc(c); +} + +char _getc(void) +{ + while (!(ns16550_in(NS16550_LSR) & NS16550_LSR_DR)); + return ns16550_in(NS16550_RBR); +} + +int _testc(void) +{ + return (ns16550_in(NS16550_LSR) & NS16550_LSR_DR) != 0; +} + + + /* + * Hexadecimal 7-segment LED + */ + +void ddb5074_led_hex(int hex) +{ + outb(hex, 0x80); +} + + + /* + * LEDs D2 and D3, connected to the GPIO pins of the PMU in the ALi M1543 + */ + +struct pci_dev *pci_pmu = NULL; + +void ddb5074_led_d2(int on) +{ + u8 t; + + if (pci_pmu) { + pci_read_config_byte(pci_pmu, 0x7e, &t); + if (on) + t &= 0x7f; + else + t |= 0x80; + pci_write_config_byte(pci_pmu, 0x7e, t); + } +} + +void ddb5074_led_d3(int on) +{ + u8 t; + + if (pci_pmu) { + pci_read_config_byte(pci_pmu, 0x7e, &t); + if (on) + t &= 0xbf; + else + t |= 0x40; + pci_write_config_byte(pci_pmu, 0x7e, t); + } +} + diff --git a/arch/mips/ddb5074/time.c b/arch/mips/ddb5074/time.c new file mode 100644 index 000000000..7cc61eea5 --- /dev/null +++ b/arch/mips/ddb5074/time.c @@ -0,0 +1,35 @@ +/* + * arch.mips/ddb5074/time.c -- Timer routines + * + * Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com> + * Sony Suprastructure Center Europe (SUPC-E), Brussels + * + * $Id* + */ + +#include <linux/init.h> +#include <asm/mc146818rtc.h> + +static unsigned char ddb_rtc_read_data(unsigned long addr) +{ + outb_p(addr, RTC_PORT(0)); + return inb_p(RTC_PORT(1)); +} + +static void ddb_rtc_write_data(unsigned char data, unsigned long addr) +{ + outb_p(addr, RTC_PORT(0)); + outb_p(data, RTC_PORT(1)); +} + +static int ddb_rtc_bcd_mode(void) +{ + return 1; +} + +struct rtc_ops ddb_rtc_ops = { + ddb_rtc_read_data, + ddb_rtc_write_data, + ddb_rtc_bcd_mode +}; + diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile index 4281d1641..9ef5ecbb2 100644 --- a/arch/mips/kernel/Makefile +++ b/arch/mips/kernel/Makefile @@ -1,4 +1,4 @@ -# $Id$ +# $Id: Makefile,v 1.14 1999/10/09 00:00:58 ralf Exp $ # # Makefile for the Linux/MIPS kernel. # @@ -39,7 +39,8 @@ endif ifndef CONFIG_SGI_IP22 ifndef CONFIG_DECSTATION ifndef CONFIG_BAGET_MIPS - O_OBJS += irq.o time.o + O_OBJS += time.o + OX_OBJS += irq.o endif endif endif diff --git a/arch/mips/kernel/irq.c b/arch/mips/kernel/irq.c index c592503ff..88cdb7bf5 100644 --- a/arch/mips/kernel/irq.c +++ b/arch/mips/kernel/irq.c @@ -1,4 +1,4 @@ -/* $Id: irq.c,v 1.16 1999/09/28 22:25:46 ralf Exp $ +/* $Id: irq.c,v 1.17 1999/12/04 03:59:00 ralf Exp $ * * 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 @@ -29,6 +29,7 @@ #include <asm/mipsregs.h> #include <asm/system.h> #include <asm/sni.h> +#include <asm/nile4.h> /* * This contains the irq mask for both 8259A irq controllers, it's an @@ -72,7 +73,7 @@ static inline void unmask_irq(unsigned int irq) } } -void disable_irq(unsigned int irq_nr) +void i8259_disable_irq(unsigned int irq_nr) { unsigned long flags; @@ -81,7 +82,7 @@ void disable_irq(unsigned int irq_nr) restore_flags(flags); } -void enable_irq(unsigned int irq_nr) +void i8259_enable_irq(unsigned int irq_nr) { unsigned long flags; save_and_cli(flags); @@ -243,7 +244,10 @@ int i8259_setup_irq(int irq, struct irqaction * new) *p = new; if (!shared) { - unmask_irq(irq); + if (is_i8259_irq(irq)) + unmask_irq(irq); + else + nile4_enable_irq(irq_to_nile4(irq)); } restore_flags(flags); return 0; @@ -354,7 +358,7 @@ static int i8259_irq_cannonicalize(int irq) return ((irq == 2) ? 9 : irq); } -static void __init i8259_init(void) +void __init i8259_init(void) { /* Init master interrupt controller */ outb(0x11, 0x20); /* Start init sequence */ diff --git a/arch/mips/kernel/proc.c b/arch/mips/kernel/proc.c index a93fae0fe..c2ee57b86 100644 --- a/arch/mips/kernel/proc.c +++ b/arch/mips/kernel/proc.c @@ -33,6 +33,7 @@ int get_cpuinfo(char *buffer) const char *mach_acn_names[] = GROUP_ACN_NAMES; const char *mach_sgi_names[] = GROUP_SGI_NAMES; const char *mach_cobalt_names[] = GROUP_COBALT_NAMES; + const char *mach_nec_ddb_names[] = GROUP_NEC_DDB_NAMES; const char **mach_group_to_name[] = { mach_unknown_names, mach_jazz_names, mach_dec_names, @@ -40,7 +41,8 @@ int get_cpuinfo(char *buffer) mach_sni_rm_names, mach_acn_names, mach_sgi_names, - mach_cobalt_names }; + mach_cobalt_names, + mach_nec_ddb_names }; unsigned int version = read_32bit_cp0_register(CP0_PRID); int len; diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c index 9f4b5164a..c1c556e1c 100644 --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c @@ -1,4 +1,4 @@ -/* $Id: setup.c,v 1.19 1999/09/28 22:25:47 ralf Exp $ +/* $Id: setup.c,v 1.20 1999/10/09 00:00:58 ralf Exp $ * * 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 @@ -146,6 +146,7 @@ void __init setup_arch(char **cmdline_p, void jazz_setup(void); void sni_rm200_pci_setup(void); void sgi_setup(void); + void ddb_setup(void); /* Save defaults for configuration-dependent routines. */ irq_setup = default_irq_setup; @@ -194,6 +195,11 @@ void __init setup_arch(char **cmdline_p, sni_rm200_pci_setup(); break; #endif +#ifdef CONFIG_DDB5074 + case MACH_GROUP_NEC_DDB: + ddb_setup(); + break; +#endif default: panic("Unsupported architecture"); } diff --git a/arch/mips/kernel/time.c b/arch/mips/kernel/time.c index 1a45ce783..a35da14d2 100644 --- a/arch/mips/kernel/time.c +++ b/arch/mips/kernel/time.c @@ -1,4 +1,4 @@ -/* $Id: time.c,v 1.12 1999/06/13 16:30:34 ralf Exp $ +/* $Id: time.c,v 1.13 1999/10/09 00:00:58 ralf Exp $ * * Copyright (C) 1991, 1992, 1995 Linus Torvalds * Copyright (C) 1996, 1997, 1998 Ralf Baechle @@ -19,6 +19,7 @@ #include <asm/mipsregs.h> #include <asm/io.h> #include <asm/irq.h> +#include <asm/ddb5074.h> #include <linux/mc146818rtc.h> #include <linux/timex.h> @@ -335,6 +336,24 @@ static long last_rtc_update = 0; static void inline timer_interrupt(int irq, void *dev_id, struct pt_regs * regs) { +#ifdef CONFIG_DDB5074 + static unsigned cnt = 0, period = 0, dist = 0; + + if (cnt == 0 || cnt == dist) + ddb5074_led_d2(1); + else if (cnt == 7 || cnt == dist+7) + ddb5074_led_d2(0); + + if (++cnt > period) { + cnt = 0; + /* The hyperbolic function below modifies the heartbeat period + * length in dependency of the current (5min) load. It goes + * through the points f(0)=126, f(1)=86, f(5)=51, + * f(inf)->30. */ + period = ((672<<FSHIFT)/(5*avenrun[0]+(7<<FSHIFT))) + 30; + dist = period / 4; + } +#endif #ifdef CONFIG_PROFILE if(!user_mode(regs)) { if (prof_buffer && current->pid) { diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c index e4f6fffd7..bf77a7998 100644 --- a/arch/mips/mm/init.c +++ b/arch/mips/mm/init.c @@ -1,4 +1,4 @@ -/* $Id: init.c,v 1.18 1999/08/21 22:19:12 ralf Exp $ +/* $Id: init.c,v 1.19 1999/10/09 00:00:58 ralf Exp $ * * 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 @@ -38,6 +38,9 @@ static unsigned long totalram = 0; extern void show_net_buffers(void); +extern void prom_fixup_mem_map(unsigned long start, unsigned long end); +extern void prom_free_prom_memory(void); + void __bad_pte_kernel(pmd_t *pmd) { |