Update of /cvsroot/linux-mips/linux/arch/mips/jmr3927/rbhma3100 In directory usw-pr-cvs1:/tmp/cvs-serv22117/jmr3927/rbhma3100 Added Files: Makefile init.c int-handler.S irq.c kgdb_io.c pci_fixup.c pci_ops.c rtc.c setup.c Log Message: Imported support for JMR-TX3927 by Alice Hennessy. Thank you. --- NEW FILE: Makefile --- # # Makefile for TOSHIBA JMR-TX3927 board # # 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). # .S.s: $(CPP) $(CFLAGS) $< -o $*.s .S.o: $(CC) $(CFLAGS) -c $< -o $*.o O_TARGET:= jmr3927.o obj-y += init.o int-handler.o irq.o setup.o rtc.o pci_fixup.o pci_ops.o obj-$(CONFIG_LL_DEBUG) += debug.o obj-$(CONFIG_REMOTE_DEBUG) += kgdb_io.o include $(TOPDIR)/Rules.make --- NEW FILE: init.c --- /*********************************************************************** * * Copyright 2001 MontaVista Software Inc. * Author: MontaVista Software, Inc. * ahe...@mv... * * arch/mips/jmr3927/common/init.c * * Copyright (C) 2000-2001 Toshiba Corporation * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. * *********************************************************************** */ #include <linux/config.h> #include <linux/init.h> #include <linux/mm.h> #include <linux/sched.h> #include <linux/bootmem.h> #include <asm/addrspace.h> #include <asm/bootinfo.h> #include <asm/mipsregs.h> #include <asm/jmr3927/jmr3927.h> int prom_argc; char **prom_argv, **prom_envp; extern void __init prom_init_cmdline(void); extern char *prom_getenv(char *envname); unsigned long mips_nofpu = 0; extern void puts(unsigned char *cp); int __init prom_init(int argc, char **argv, char **envp, int *prom_vec) { #ifdef CONFIG_TOSHIBA_JMR3927 /* CCFG */ if ((tx3927_ccfgptr->ccfg & TX3927_CCFG_TLBOFF) == 0) puts("Warning: TX3927 TLB off\n"); #endif prom_argc = argc; prom_argv = argv; prom_envp = envp; mips_machgroup = MACH_GROUP_TOSHIBA; #ifdef CONFIG_TOSHIBA_JMR3927 mips_machtype = MACH_TOSHIBA_JMR3927; #endif prom_init_cmdline(); add_memory_region(0, JMR3927_SDRAM_SIZE, BOOT_MEM_RAM); return 0; } --- NEW FILE: int-handler.S --- /* * Copyright 2001 MontaVista Software Inc. * Author: MontaVista Software, Inc. * ahe...@mv... * * Based on arch/mips/tsdb/kernel/int-handler.S * * Copyright (C) 2000-2001 Toshiba Corporation * * $Id: int-handler.S,v 1.1 2001/11/10 03:56:05 jsimmons Exp $ * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ #include <asm/asm.h> #include <asm/mipsregs.h> #include <asm/regdef.h> #include <asm/stackframe.h> #include <asm/jmr3927/jmr3927.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. * */ /* Flush write buffer (needed?) * NOTE: TX39xx performs "non-blocking load", so explicitly use the target * register of LBU to flush immediately. */ #define FLUSH_WB(tmp) \ la tmp, JMR3927_IOC_REV_ADDR; \ lbu tmp, (tmp); \ move tmp, zero; .text .set noreorder .set noat .align 5 NESTED(jmr3927_IRQ, PT_SIZE, sp) SAVE_ALL CLI .set at jal jmr3927_irc_irqdispatch move a0, sp FLUSH_WB(t0) j ret_from_irq nop END(jmr3927_IRQ) --- NEW FILE: irq.c --- /* * Copyright 2001 MontaVista Software Inc. * Author: MontaVista Software, Inc. * ahe...@mv... * * 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 Toshiba Corporation * * $Id: irq.c,v 1.1 2001/11/10 03:56:05 jsimmons Exp $ * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ #include <linux/config.h> #include <linux/init.h> #include <linux/errno.h> #include <linux/kernel_stat.h> #include <linux/signal.h> #include <linux/sched.h> #include <linux/types.h> #include <linux/interrupt.h> #include <linux/ioport.h> #include <linux/timex.h> #include <linux/malloc.h> #include <linux/random.h> #include <linux/smp.h> #include <linux/smp_lock.h> #include <linux/irq.h> #include <asm/bitops.h> #include <asm/io.h> #include <asm/irq.h> #include <asm/mipsregs.h> #include <asm/system.h> #include <asm/ptrace.h> #include <asm/processor.h> #include <asm/jmr3927/irq.h> #include <asm/debug.h> #include <asm/jmr3927/jmr3927.h> #if JMR3927_IRQ_END > NR_IRQS #error JMR3927_IRQ_END > NR_IRQS #endif struct tb_irq_space* tb_irq_spaces; unsigned int local_bh_count[NR_CPUS]; unsigned int local_irq_count[NR_CPUS]; static int jmr3927_irq_base=-1; #ifdef CONFIG_PCI static int jmr3927_gen_iack(void) { /* generate ACK cycle */ #ifdef __BIG_ENDIAN return (tx3927_pcicptr->iiadp >> 24) & 0xff; #else return tx3927_pcicptr->iiadp & 0xff; #endif } #endif extern asmlinkage void jmr3927_IRQ(void); #define irc_dlevel 0 #define irc_elevel 1 static unsigned char irc_level[TX3927_NUM_IR] = { 5, 5, 5, 5, 5, 5, /* INT[5:0] */ 7, 7, /* SIO */ 5, 5, 5, 0, 0, /* DMA, PIO, PCI */ 6, 6, 6 /* TMR */ }; static inline void mask_irq(unsigned int irq_nr) { struct tb_irq_space* sp; for (sp = tb_irq_spaces; sp; sp = sp->next) { if (sp->start_irqno <= irq_nr && irq_nr < sp->start_irqno + sp->nr_irqs) { if (sp->mask_func) sp->mask_func(irq_nr - sp->start_irqno, sp->space_id); break; } } } static inline void unmask_irq(unsigned int irq_nr) { struct tb_irq_space* sp; for (sp = tb_irq_spaces; sp; sp = sp->next) { if (sp->start_irqno <= irq_nr && irq_nr < sp->start_irqno + sp->nr_irqs) { if (sp->unmask_func) sp->unmask_func(irq_nr - sp->start_irqno, sp->space_id); break; } } } static void jmr3927_irq_disable(unsigned int irq_nr); static void jmr3927_irq_enable(unsigned int irq_nr); static unsigned int jmr3927_irq_startup(unsigned int irq) { jmr3927_irq_enable(irq); return 0; } #define jmr3927_irq_shutdown jmr3927_irq_disable static void jmr3927_irq_ack(unsigned int irq) { db_assert(jmr3927_irq_base != -1); db_assert(irq >= jmr3927_irq_base); db_assert(irq < jmr3927_irq_base + JMR3927_NR_IRQ_IRC + JMR3927_NR_IRQ_IOC); if (irq == JMR3927_IRQ_IRC_TMR0) { jmr3927_tmrptr->tisr = 0; /* ack interrupt */ } jmr3927_irq_disable(irq); } static void jmr3927_irq_end(unsigned int irq) { db_assert(jmr3927_irq_base != -1); db_assert(irq >= jmr3927_irq_base); db_assert(irq < jmr3927_irq_base + JMR3927_NR_IRQ_IRC + JMR3927_NR_IRQ_IOC); jmr3927_irq_enable(irq); } static void jmr3927_irq_disable(unsigned int irq_nr) { unsigned long flags; db_assert(jmr3927_irq_base != -1); db_assert(irq >= jmr3927_irq_base); db_assert(irq < jmr3927_irq_base + JMR3927_NR_IRQ_IRC + JMR3927_NR_IRQ_IOC); save_and_cli(flags); mask_irq(irq_nr); restore_flags(flags); } static void jmr3927_irq_enable(unsigned int irq_nr) { unsigned long flags; db_assert(jmr3927_irq_base != -1); db_assert(irq >= jmr3927_irq_base); db_assert(irq < jmr3927_irq_base + JMR3927_NR_IRQ_IRC + JMR3927_NR_IRQ_IOC); save_and_cli(flags); unmask_irq(irq_nr); restore_flags(flags); } /* * CP0_STATUS is a thread's resource (saved/restored on context switch). * So disable_irq/enable_irq MUST handle IOC/ISAC/IRC registers. */ static void mask_irq_isac(int irq_nr, int space_id) { /* 0: mask */ unsigned char imask = jmr3927_isac_reg_in(JMR3927_ISAC_INTM_ADDR); unsigned int bit = 1 << irq_nr; jmr3927_isac_reg_out(imask & ~bit, JMR3927_ISAC_INTM_ADDR); /* flush write buffer */ (void)jmr3927_ioc_reg_in(JMR3927_IOC_REV_ADDR); } static void unmask_irq_isac(int irq_nr, int space_id) { /* 0: mask */ unsigned char imask = jmr3927_isac_reg_in(JMR3927_ISAC_INTM_ADDR); unsigned int bit = 1 << irq_nr; jmr3927_isac_reg_out(imask | bit, JMR3927_ISAC_INTM_ADDR); /* flush write buffer */ (void)jmr3927_ioc_reg_in(JMR3927_IOC_REV_ADDR); } static void mask_irq_ioc(int irq_nr, int space_id) { /* 0: mask */ unsigned char imask = jmr3927_ioc_reg_in(JMR3927_IOC_INTM_ADDR); unsigned int bit = 1 << irq_nr; jmr3927_ioc_reg_out(imask & ~bit, JMR3927_IOC_INTM_ADDR); /* flush write buffer */ (void)jmr3927_ioc_reg_in(JMR3927_IOC_REV_ADDR); } static void unmask_irq_ioc(int irq_nr, int space_id) { /* 0: mask */ unsigned char imask = jmr3927_ioc_reg_in(JMR3927_IOC_INTM_ADDR); unsigned int bit = 1 << irq_nr; jmr3927_ioc_reg_out(imask | bit, JMR3927_IOC_INTM_ADDR); /* flush write buffer */ (void)jmr3927_ioc_reg_in(JMR3927_IOC_REV_ADDR); } static void mask_irq_irc(int irq_nr, int space_id) { volatile unsigned long *ilrp = &tx3927_ircptr->ilr[irq_nr / 2]; if (irq_nr & 1) *ilrp = (*ilrp & 0x00ff) | (irc_dlevel << 8); else *ilrp = (*ilrp & 0xff00) | irc_dlevel; /* update IRCSR */ tx3927_ircptr->imr = 0; tx3927_ircptr->imr = irc_elevel; } static void unmask_irq_irc(int irq_nr, int space_id) { volatile unsigned long *ilrp = &tx3927_ircptr->ilr[irq_nr / 2]; if (irq_nr & 1) *ilrp = (*ilrp & 0x00ff) | (irc_level[irq_nr] << 8); else *ilrp = (*ilrp & 0xff00) | irc_level[irq_nr]; /* update IRCSR */ tx3927_ircptr->imr = 0; tx3927_ircptr->imr = irc_elevel; } struct tb_irq_space jmr3927_isac_irqspace = { next: NULL, start_irqno: JMR3927_IRQ_ISAC, nr_irqs : JMR3927_NR_IRQ_ISAC, mask_func: mask_irq_isac, unmask_func: unmask_irq_isac, name: "ISAC", space_id: 0, can_share : 0 }; struct tb_irq_space jmr3927_ioc_irqspace = { next: NULL, start_irqno: JMR3927_IRQ_IOC, nr_irqs : JMR3927_NR_IRQ_IOC, mask_func: mask_irq_ioc, unmask_func: unmask_irq_ioc, name: "IOC", space_id: 0, can_share : 1 }; struct tb_irq_space jmr3927_irc_irqspace = { next: NULL, start_irqno: JMR3927_IRQ_IRC, nr_irqs : JMR3927_NR_IRQ_IRC, mask_func: mask_irq_irc, unmask_func: unmask_irq_irc, name: "on-chip", space_id: 0, can_share : 0 }; void jmr3927_spurious(struct pt_regs *regs) { #ifdef CONFIG_TX_BRANCH_LIKELY_BUG_WORKAROUND tx_branch_likely_bug_fixup(regs); #endif printk(KERN_WARNING "spurious interrupt (cause 0x%lx, pc 0x%lx, ra 0x%lx).\n", regs->cp0_cause, regs->cp0_epc, regs->regs[31]); } extern asmlinkage void do_IRQ(int irq, struct pt_regs *regs); void jmr3927_irc_irqdispatch(struct pt_regs *regs) { int irq; #ifdef CONFIG_TX_BRANCH_LIKELY_BUG_WORKAROUND tx_branch_likely_bug_fixup(regs); #endif if ((regs->cp0_cause & CAUSEF_IP7) == 0) { #if 0 jmr3927_spurious(regs); #endif return; } irq = (regs->cp0_cause >> CAUSEB_IP2) & 0x0f; do_IRQ(irq + JMR3927_IRQ_IRC, regs); } static void jmr3927_ioc_interrupt(int irq, void *dev_id, struct pt_regs *regs) { unsigned char istat = jmr3927_ioc_reg_in(JMR3927_IOC_INTS2_ADDR); int i; for (i = 0; i < JMR3927_NR_IRQ_IOC; i++) { if (istat & (1 << i)) { irq = JMR3927_IRQ_IOC + i; do_IRQ(irq, regs); } } } static struct irqaction ioc_action = { jmr3927_ioc_interrupt, 0, 0, "IOC", NULL, NULL, }; static void jmr3927_isac_interrupt(int irq, void *dev_id, struct pt_regs *regs) { unsigned char istat = jmr3927_isac_reg_in(JMR3927_ISAC_INTS2_ADDR); int i; for (i = 0; i < JMR3927_NR_IRQ_ISAC; i++) { if (istat & (1 << i)) { irq = JMR3927_IRQ_ISAC + i; do_IRQ(irq, regs); } } } static struct irqaction isac_action = { jmr3927_isac_interrupt, 0, 0, "ISAC", NULL, NULL, }; static void jmr3927_isaerr_interrupt(int irq, void * dev_id, struct pt_regs * regs) { printk(KERN_WARNING "ISA error interrupt (irq 0x%x).\n", irq); } static struct irqaction isaerr_action = { jmr3927_isaerr_interrupt, 0, 0, "ISA error", NULL, NULL, }; static void jmr3927_pcierr_interrupt(int irq, void * dev_id, struct pt_regs * regs) { printk(KERN_WARNING "PCI error interrupt (irq 0x%x).\n", irq); printk(KERN_WARNING "pcistat:%02x, lbstat:%04lx\n", tx3927_pcicptr->pcistat, tx3927_pcicptr->lbstat); } static struct irqaction pcierr_action = { jmr3927_pcierr_interrupt, 0, 0, "PCI error", NULL, NULL, }; int jmr3927_ether1_irq = 0; void jmr3927_irq_init(u32 irq_base); void jmr3927_irq_setup(void) { /* look for io board's presence */ int have_isac = jmr3927_have_isac(); /* Now, interrupt control disabled, */ /* all IRC interrupts are masked, */ /* all IRC interrupt mode are Low Active. */ if (have_isac) { /* ETHER1 (NE2000 compatible 10M-Ether) parameter setup */ /* temporary enable interrupt control */ tx3927_ircptr->cer = 1; /* ETHER1 Int. Is High-Active. */ if (tx3927_ircptr->ssr & (1 << 0)) jmr3927_ether1_irq = JMR3927_IRQ_IRC_INT0; #if 0 /* INT3 may be asserted by ether0 (even after reboot...) */ else if (tx3927_ircptr->ssr & (1 << 3)) jmr3927_ether1_irq = JMR3927_IRQ_IRC_INT3; #endif /* disable interrupt control */ tx3927_ircptr->cer = 0; /* Ether1: High Active */ if (jmr3927_ether1_irq) { int ether1_irc = jmr3927_ether1_irq - JMR3927_IRQ_IRC; tx3927_ircptr->cr[ether1_irc / 8] |= TX3927_IRCR_HIGH << ((ether1_irc % 8) * 2); } } /* mask all IOC interrupts */ jmr3927_ioc_reg_out(0, JMR3927_IOC_INTM_ADDR); /* setup IOC interrupt mode (SOFT:High Active, Others:Low Active) */ jmr3927_ioc_reg_out(JMR3927_IOC_INTF_SOFT, JMR3927_IOC_INTP_ADDR); if (have_isac) { /* mask all ISAC interrupts */ jmr3927_isac_reg_out(0, JMR3927_ISAC_INTM_ADDR); /* setup ISAC interrupt mode (ISAIRQ3,ISAIRQ5:Low Active ???) */ jmr3927_isac_reg_out(JMR3927_ISAC_INTF_IRQ3|JMR3927_ISAC_INTF_IRQ5, JMR3927_ISAC_INTP_ADDR); } /* clear PCI Soft interrupts */ jmr3927_ioc_reg_out(0, JMR3927_IOC_INTS1_ADDR); /* clear PCI Reset interrupts */ jmr3927_ioc_reg_out(0, JMR3927_IOC_RESET_ADDR); /* enable interrupt control */ tx3927_ircptr->cer = TX3927_IRCER_ICE; tx3927_ircptr->imr = irc_elevel; jmr3927_irq_init(NR_ISA_IRQS); set_except_vector(0, jmr3927_IRQ); /* setup irq space */ add_tb_irq_space(&jmr3927_isac_irqspace); add_tb_irq_space(&jmr3927_ioc_irqspace); add_tb_irq_space(&jmr3927_irc_irqspace); /* setup IOC interrupt 1 (PCI, MODEM) */ setup_irq(JMR3927_IRQ_IOCINT, &ioc_action); if (have_isac) { setup_irq(JMR3927_IRQ_ISACINT, &isac_action); setup_irq(JMR3927_IRQ_ISAC_ISAER, &isaerr_action); } #ifdef CONFIG_PCI setup_irq(JMR3927_IRQ_IRC_PCI, &pcierr_action); #endif /* enable all CPU interrupt bits. */ set_cp0_status(ST0_IM); /* IE bit is still 0. */ } void (*irq_setup)(void); void __init init_IRQ(void) { #ifdef CONFIG_REMOTE_DEBUG extern void breakpoint(void); extern void set_debug_traps(void); puts("Wait for gdb client connection ...\n"); set_debug_traps(); breakpoint(); #endif /* invoke board-specific irq setup */ irq_setup(); } hw_irq_controller jmr3927_irq_controller = { "jmr3927_irq", jmr3927_irq_startup, jmr3927_irq_shutdown, jmr3927_irq_enable, jmr3927_irq_disable, jmr3927_irq_ack, jmr3927_irq_end, NULL /* no affinity stuff for UP */ }; void jmr3927_irq_init(u32 irq_base) { extern irq_desc_t irq_desc[]; u32 i; for (i= irq_base; i< irq_base + JMR3927_NR_IRQ_IRC + JMR3927_NR_IRQ_IOC; i++) { irq_desc[i].status = IRQ_DISABLED; irq_desc[i].action = NULL; irq_desc[i].depth = 1; irq_desc[i].handler = &jmr3927_irq_controller; } jmr3927_irq_base = irq_base; } #ifdef CONFIG_TX_BRANCH_LIKELY_BUG_WORKAROUND static int tx_branch_likely_bug_count = 0; static int have_tx_branch_likely_bug = 0; void tx_branch_likely_bug_fixup(struct pt_regs *regs) { /* TX39/49-BUG: Under this condition, the insn in delay slot of the branch likely insn is executed (not nullified) even the branch condition is false. */ if (!have_tx_branch_likely_bug) return; if ((regs->cp0_epc & 0xfff) == 0xffc && KSEGX(regs->cp0_epc) != KSEG0 && KSEGX(regs->cp0_epc) != KSEG1) { unsigned int insn = *(unsigned int*)(regs->cp0_epc - 4); /* beql,bnel,blezl,bgtzl */ /* bltzl,bgezl,blezall,bgezall */ /* bczfl, bcztl */ if ((insn & 0xf0000000) == 0x50000000 || (insn & 0xfc0e0000) == 0x04020000 || (insn & 0xf3fe0000) == 0x41020000) { regs->cp0_epc -= 4; tx_branch_likely_bug_count++; printk(KERN_INFO "fix branch-likery bug in %s (insn %08x)\n", current->comm, insn); } } } #endif --- NEW FILE: kgdb_io.c --- /* * BRIEF MODULE DESCRIPTION * Low level uart routines to directly access a TX[34]927 SIO. * * Copyright 2001 MontaVista Software Inc. * Author: MontaVista Software, Inc. * ahe...@mv... or so...@mv... * * Based on arch/mips/ddb5xxx/ddb5477/kgdb_io.c * * Copyright (C) 2000-2001 Toshiba Corporation * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ #include <linux/types.h> #include <asm/jmr3927/txx927.h> #include <asm/jmr3927/tx3927.h> #include <asm/jmr3927/jmr3927.h> #define TIMEOUT 0xffffff #define SLOW_DOWN static const char digits[16] = "0123456789abcdef"; #ifdef SLOW_DOWN #define slow_down() { int k; for (k=0; k<10000; k++); } #else #define slow_down() #endif static int remoteDebugInitialized = 0; int putDebugChar(unsigned char c) { int i = 0; if (!remoteDebugInitialized) { remoteDebugInitialized = 1; debugInit(38400); } do { slow_down(); i++; if (i>TIMEOUT) { break; } } while (!(tx3927_sioptr(0)->cisr & TXx927_SICISR_TXALS)); tx3927_sioptr(0)->tfifo = c; return 1; } unsigned char getDebugChar(void) { int i = 0; int dicr; char c; if (!remoteDebugInitialized) { remoteDebugInitialized = 1; debugInit(38400); } /* diable RX int. */ dicr = tx3927_sioptr(0)->dicr; tx3927_sioptr(0)->dicr = 0; do { slow_down(); i++; if (i>TIMEOUT) { break; } } while (tx3927_sioptr(0)->disr & TXx927_SIDISR_UVALID) ; c = tx3927_sioptr(0)->rfifo; /* clear RX int. status */ tx3927_sioptr(0)->disr &= ~TXx927_SIDISR_RDIS; /* enable RX int. */ tx3927_sioptr(0)->dicr = dicr; return c; } void debugInit(int baud) { /* volatile unsigned long lcr; volatile unsigned long dicr; volatile unsigned long disr; volatile unsigned long cisr; volatile unsigned long fcr; volatile unsigned long flcr; volatile unsigned long bgr; volatile unsigned long tfifo; volatile unsigned long rfifo; */ tx3927_sioptr(0)->lcr = 0x020; tx3927_sioptr(0)->dicr = 0; tx3927_sioptr(0)->disr = 0x4100; tx3927_sioptr(0)->cisr = 0x014; tx3927_sioptr(0)->fcr = 0; tx3927_sioptr(0)->flcr = 0x02; tx3927_sioptr(0)->bgr = ((JMR3927_BASE_BAUD + baud / 2) / baud) | TXx927_SIBGR_BCLK_T0; #if 0 /* * Reset the UART. */ tx3927_sioptr(0)->fcr = TXx927_SIFCR_SWRST; while (tx3927_sioptr(0)->fcr & TXx927_SIFCR_SWRST) ; /* * and set the speed of the serial port * (currently hardwired to 9600 8N1 */ tx3927_sioptr(0)->lcr = TXx927_SILCR_UMODE_8BIT | TXx927_SILCR_USBL_1BIT | TXx927_SILCR_SCS_IMCLK_BG; tx3927_sioptr(0)->bgr = ((JMR3927_BASE_BAUD + baud / 2) / baud) | TXx927_SIBGR_BCLK_T0; /* HW RTS/CTS control */ if (ser->flags & ASYNC_HAVE_CTS_LINE) tx3927_sioptr(0)->flcr = TXx927_SIFLCR_RCS | TXx927_SIFLCR_TES | TXx927_SIFLCR_RTSTL_MAX /* 15 */; /* Enable RX/TX */ tx3927_sioptr(0)->flcr &= ~(TXx927_SIFLCR_RSDE | TXx927_SIFLCR_TSDE); #endif } --- NEW FILE: pci_fixup.c --- /* * * BRIEF MODULE DESCRIPTION * Board specific pci fixups. * * Copyright 2001 MontaVista Software Inc. * Author: MontaVista Software, Inc. * pp...@mv... or so...@mv... * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ #include <linux/config.h> #ifdef CONFIG_PCI #include <linux/types.h> #include <linux/pci.h> #include <linux/kernel.h> #include <linux/init.h> #include <asm/jmr3927/jmr3927.h> #undef DEBUG #ifdef DEBUG #define DBG(x...) printk(x) #else #define DBG(x...) #endif void __init pcibios_fixup_resources(struct pci_dev *dev) { /* will need to fixup IO resources */ } void __init pcibios_fixup(void) { /* nothing to do here */ } int pci_get_irq(struct pci_dev *dev, int pin) { unsigned char irq = pin; /* IRQ rotation (PICMG) */ irq--; /* 0-3 */ if (dev->bus->parent == NULL && PCI_SLOT(dev->devfn) == TX3927_PCIC_IDSEL_AD_TO_SLOT(23)) { /* PCI CardSlot (IDSEL=A23, DevNu=12) */ /* PCIA => PCIC (IDSEL=A23) */ /* NOTE: JMR3927 JP1 must be set to OPEN */ irq = (irq + 2) % 4; } else if (dev->bus->parent == NULL && PCI_SLOT(dev->devfn) == TX3927_PCIC_IDSEL_AD_TO_SLOT(22)) { /* PCI CardSlot (IDSEL=A22, DevNu=11) */ /* PCIA => PCIA (IDSEL=A22) */ /* NOTE: JMR3927 JP1 must be set to OPEN */ irq = (irq + 0) % 4; } else { /* PCI Backplane */ irq = (irq + 3 + PCI_SLOT(dev->devfn)) % 4; #if 0 /* ??? */ for (bus = dev->bus; bus->parent != NULL; bus = bus->parent) { irq = (irq + 3 + PCI_SLOT(bus->self->devfn)) % 4; } #endif } irq++; /* 1-4 */ switch (irq) { case 1: irq = JMR3927_IRQ_IOC_PCIA; break; case 2: // wrong for backplane irq = JMR3927_IRQ_IOC_PCIB; irq = JMR3927_IRQ_IOC_PCID; break; case 3: irq = JMR3927_IRQ_IOC_PCIC; break; case 4: // wrong for backplane irq = JMR3927_IRQ_IOC_PCID; irq = JMR3927_IRQ_IOC_PCIB; break; } /* Check OnBoard Ethernet (IDSEL=A24, DevNu=13) */ if (dev->bus->parent == NULL && PCI_SLOT(dev->devfn) == TX3927_PCIC_IDSEL_AD_TO_SLOT(24)) { extern int jmr3927_ether1_irq; /* check this irq line was reserved for ether1 */ if (jmr3927_ether1_irq != JMR3927_IRQ_ETHER0) irq = JMR3927_IRQ_ETHER0; else irq = 0; /* disable */ } return irq; } void __init pcibios_fixup_irqs(void) { unsigned char irq; struct pci_dev *dev; pci_for_each_dev(dev) { pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &irq); if (irq == 0) return; /* SMSC SLC90E66 IDE uses irq 14, 15 (default) */ if (!(dev->vendor == PCI_VENDOR_ID_EFAR && dev->device == PCI_DEVICE_ID_EFAR_SLC90E66_1)) { irq = pci_get_irq(dev, irq); pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); } pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq); printk(KERN_INFO "PCI: %02x:%02x IRQ %02x\n", dev->bus->number, dev->devfn, irq); dev->irq = irq; } } #endif --- NEW FILE: pci_ops.c --- /*********************************************************************** * Copyright 2001 MontaVista Software Inc. * Author: MontaVista Software, Inc. * ahe...@mv... * * Copyright (C) 2000-2001 Toshiba Corporation * * Based on arch/mips/ddb5xxx/ddb5477/pci_ops.c * * Define the pci_ops for JMR3927. * * Much of the code is derived from the original DDB5074 port by * Geert Uytterhoeven <ge...@so...> * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. *********************************************************************** */ #include <linux/types.h> #include <linux/pci.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/config.h> #include <asm/addrspace.h> #include <asm/pci_channel.h> #include <asm/jmr3927/jmr3927.h> #include <asm/debug.h> struct resource pci_io_resource = { "pci IO space", 0x1000, /* reserve regacy I/O space */ 0x1000 + JMR3927_PCIIO_SIZE -1, IORESOURCE_IO}; struct resource pci_mem_resource = { "pci memory space", JMR3927_PCIMEM, JMR3927_PCIMEM + JMR3927_PCIMEM_SIZE -1, IORESOURCE_MEM}; extern struct pci_ops jmr3927_pci_ops; struct pci_channel mips_pci_channels[] = { { &jmr3927_pci_ops, &pci_io_resource, &pci_mem_resource, 0, 0xff }, { NULL, NULL, NULL, NULL, NULL} }; unsigned int pcibios_assign_all_busses(void) { return 1; } static int mkaddr(unsigned char bus, unsigned char dev_fn, unsigned char where, int *flagsp) { if (bus == 0 && dev_fn >= PCI_DEVFN(TX3927_PCIC_MAX_DEVNU, 0)) return -1; tx3927_pcicptr->ica = ((bus & 0xff) << 0x10) | ((dev_fn & 0xff) << 0x08) | (where & 0xfc); /* clear M_ABORT and Disable M_ABORT Int. */ tx3927_pcicptr->pcistat |= PCI_STATUS_REC_MASTER_ABORT; tx3927_pcicptr->pcistatim &= ~PCI_STATUS_REC_MASTER_ABORT; return 0; } static int check_abort(int flags) { int code = PCIBIOS_SUCCESSFUL; if (tx3927_pcicptr->pcistat & PCI_STATUS_REC_MASTER_ABORT) { tx3927_pcicptr->pcistat |= PCI_STATUS_REC_MASTER_ABORT; tx3927_pcicptr->pcistatim |= PCI_STATUS_REC_MASTER_ABORT; code =PCIBIOS_DEVICE_NOT_FOUND; } return code; } /* * We can't address 8 and 16 bit words directly. Instead we have to * read/write a 32bit word and mask/modify the data we actually want. */ static int jmr3927_pcibios_read_config_byte (struct pci_dev *dev, int where, unsigned char *val) { int flags; unsigned char bus, func_num; db_assert((where & 3) == 0); db_assert(where < (1 << 8)); /* check if the bus is top-level */ if (dev->bus->parent != NULL) { bus = dev->bus->number; db_assert(bus != 0); } else { bus = 0; } func_num = PCI_FUNC(dev->devfn); if (mkaddr(bus, dev->devfn, where, &flags)) return -1; *val = *(volatile u8 *)((ulong)&tx3927_pcicptr->icd | (where&3)); return check_abort(flags); } static int jmr3927_pcibios_read_config_word (struct pci_dev *dev, int where, unsigned short *val) { int flags; unsigned char bus, func_num; if (where & 1) return PCIBIOS_BAD_REGISTER_NUMBER; db_assert((where & 3) == 0); db_assert(where < (1 << 8)); /* check if the bus is top-level */ if (dev->bus->parent != NULL) { bus = dev->bus->number; db_assert(bus != 0); } else { bus = 0; } func_num = PCI_FUNC(dev->devfn); if (mkaddr(bus, dev->devfn, where, &flags)) return -1; *val = le16_to_cpu(*(volatile u16 *)((ulong)&tx3927_pcicptr->icd | (where&3))); return check_abort(flags); } static int jmr3927_pcibios_read_config_dword (struct pci_dev *dev, int where, unsigned int *val) { int flags; unsigned char bus, func_num; if (where & 3) return PCIBIOS_BAD_REGISTER_NUMBER; db_assert((where & 3) == 0); db_assert(where < (1 << 8)); /* check if the bus is top-level */ if (dev->bus->parent != NULL) { bus = dev->bus->number; db_assert(bus != 0); } else { bus = 0; } func_num = PCI_FUNC(dev->devfn); if (mkaddr(bus, dev->devfn, where, &flags)) return -1; *val = le32_to_cpu(tx3927_pcicptr->icd); return check_abort(flags); } static int jmr3927_pcibios_write_config_byte (struct pci_dev *dev, int where, unsigned char val) { int flags; unsigned char bus, func_num; /* check if the bus is top-level */ if (dev->bus->parent != NULL) { bus = dev->bus->number; db_assert(bus != 0); } else { bus = 0; } func_num = PCI_FUNC(dev->devfn); if (mkaddr(bus, dev->devfn, where, &flags)) return -1; *(volatile u8 *)((ulong)&tx3927_pcicptr->icd | (where&3)) = val; return check_abort(flags); } static int jmr3927_pcibios_write_config_word (struct pci_dev *dev, int where, unsigned short val) { int flags; unsigned char bus, func_num; if (where & 1) return PCIBIOS_BAD_REGISTER_NUMBER; /* check if the bus is top-level */ if (dev->bus->parent != NULL) { bus = dev->bus->number; db_assert(bus != 0); } else { bus = 0; } func_num = PCI_FUNC(dev->devfn); if (mkaddr(bus, dev->devfn, where, &flags)) return -1; *(volatile u16 *)((ulong)&tx3927_pcicptr->icd | (where&3)) = cpu_to_le16(val); return check_abort(flags); } static int jmr3927_pcibios_write_config_dword (struct pci_dev *dev, int where, unsigned int val) { int flags; unsigned char bus, func_num; if (where & 3) return PCIBIOS_BAD_REGISTER_NUMBER; /* check if the bus is top-level */ if (dev->bus->parent != NULL) { bus = dev->bus->number; db_assert(bus != 0); } else { bus = 0; } func_num = PCI_FUNC(dev->devfn); if (mkaddr(bus, dev->devfn, where, &flags)) return -1; tx3927_pcicptr->icd = cpu_to_le32(val); return check_abort(flags); } struct pci_ops jmr3927_pci_ops = { jmr3927_pcibios_read_config_byte, jmr3927_pcibios_read_config_word, jmr3927_pcibios_read_config_dword, jmr3927_pcibios_write_config_byte, jmr3927_pcibios_write_config_word, jmr3927_pcibios_write_config_dword }; #ifndef JMR3927_INIT_INDIRECT_PCI inline unsigned long tc_readl(volatile __u32 *addr) { return readl(addr); } inline void tc_writel(unsigned long data, volatile __u32 *addr) { writel(data, addr); } #else unsigned long tc_readl(volatile __u32 *addr) { unsigned long val; addr = PHYSADDR(addr); *(volatile u32 *)(ulong)&tx3927_pcicptr->ipciaddr = (unsigned long)addr; *(volatile u32 *)(ulong)&tx3927_pcicptr->ipcibe = (PCI_IPCIBE_ICMD_MEMREAD << PCI_IPCIBE_ICMD_SHIFT) | PCI_IPCIBE_IBE_LONG; while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC)) ; val = le32_to_cpu(*(volatile u32 *)(ulong)&tx3927_pcicptr->ipcidata); /* clear by setting */ tx3927_pcicptr->istat |= PCI_ISTAT_IDICC; return val; } void tc_writel(unsigned long data, volatile __u32 *addr) { addr = PHYSADDR(addr); *(volatile u32 *)(ulong)&tx3927_pcicptr->ipcidata = cpu_to_le32(data); *(volatile u32 *)(ulong)&tx3927_pcicptr->ipciaddr = (unsigned long)addr; *(volatile u32 *)(ulong)&tx3927_pcicptr->ipcibe = (PCI_IPCIBE_ICMD_MEMWRITE << PCI_IPCIBE_ICMD_SHIFT) | PCI_IPCIBE_IBE_LONG; while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC)) ; /* clear by setting */ tx3927_pcicptr->istat |= PCI_ISTAT_IDICC; } unsigned char tx_ioinb(unsigned char *addr) { unsigned long val; __u32 ioaddr; int offset; int byte; ioaddr = (unsigned long)addr; offset = ioaddr & 0x3; if (offset == 0) byte = 0x7; else if (offset == 1) byte = 0xb; else if (offset == 2) byte = 0xd; else if (offset == 3) byte = 0xe; *(volatile u32 *)(ulong)&tx3927_pcicptr->ipciaddr = (unsigned long)ioaddr; *(volatile u32 *)(ulong)&tx3927_pcicptr->ipcibe = (PCI_IPCIBE_ICMD_IOREAD << PCI_IPCIBE_ICMD_SHIFT) | byte; while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC)) ; val = le32_to_cpu(*(volatile u32 *)(ulong)&tx3927_pcicptr->ipcidata); val = val & 0xff; /* clear by setting */ tx3927_pcicptr->istat |= PCI_ISTAT_IDICC; return val; } void tx_iooutb(unsigned long data, unsigned char *addr) { __u32 ioaddr; int offset; int byte; data = data | (data << 8) | (data << 16) | (data << 24); ioaddr = (unsigned long)addr; offset = ioaddr & 0x3; if (offset == 0) byte = 0x7; else if (offset == 1) byte = 0xb; else if (offset == 2) byte = 0xd; else if (offset == 3) byte = 0xe; *(volatile u32 *)(ulong)&tx3927_pcicptr->ipcidata = data; *(volatile u32 *)(ulong)&tx3927_pcicptr->ipciaddr = (unsigned long)ioaddr; *(volatile u32 *)(ulong)&tx3927_pcicptr->ipcibe = (PCI_IPCIBE_ICMD_IOWRITE << PCI_IPCIBE_ICMD_SHIFT) | byte; while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC)) ; /* clear by setting */ tx3927_pcicptr->istat |= PCI_ISTAT_IDICC; } unsigned short tx_ioinw(unsigned short *addr) { unsigned long val; __u32 ioaddr; int offset; int byte; ioaddr = (unsigned long)addr; offset = ioaddr & 0x3; if (offset == 0) byte = 0x3; else if (offset == 2) byte = 0xc; *(volatile u32 *)(ulong)&tx3927_pcicptr->ipciaddr = (unsigned long)ioaddr; *(volatile u32 *)(ulong)&tx3927_pcicptr->ipcibe = (PCI_IPCIBE_ICMD_IOREAD << PCI_IPCIBE_ICMD_SHIFT) | byte; while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC)) ; val = le32_to_cpu(*(volatile u32 *)(ulong)&tx3927_pcicptr->ipcidata); val = val & 0xffff; /* clear by setting */ tx3927_pcicptr->istat |= PCI_ISTAT_IDICC; return val; } void tx_iooutw(unsigned long data, unsigned short *addr) { __u32 ioaddr; int offset; int byte; data = data | (data << 16); ioaddr = (unsigned long)addr; offset = ioaddr & 0x3; if (offset == 0) byte = 0x3; else if (offset == 2) byte = 0xc; *(volatile u32 *)(ulong)&tx3927_pcicptr->ipcidata = data; *(volatile u32 *)(ulong)&tx3927_pcicptr->ipciaddr = (unsigned long)ioaddr; *(volatile u32 *)(ulong)&tx3927_pcicptr->ipcibe = (PCI_IPCIBE_ICMD_IOWRITE << PCI_IPCIBE_ICMD_SHIFT) | byte; while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC)) ; /* clear by setting */ tx3927_pcicptr->istat |= PCI_ISTAT_IDICC; } unsigned long tx_ioinl(unsigned int *addr) { unsigned long val; __u32 ioaddr; ioaddr = (unsigned long)addr; *(volatile u32 *)(ulong)&tx3927_pcicptr->ipciaddr = (unsigned long)ioaddr; *(volatile u32 *)(ulong)&tx3927_pcicptr->ipcibe = (PCI_IPCIBE_ICMD_IOREAD << PCI_IPCIBE_ICMD_SHIFT) | PCI_IPCIBE_IBE_LONG; while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC)) ; val = le32_to_cpu(*(volatile u32 *)(ulong)&tx3927_pcicptr->ipcidata); /* clear by setting */ tx3927_pcicptr->istat |= PCI_ISTAT_IDICC; return val; } void tx_iooutl(unsigned long data, unsigned int *addr) { __u32 ioaddr; ioaddr = (unsigned long)addr; *(volatile u32 *)(ulong)&tx3927_pcicptr->ipcidata = cpu_to_le32(data); *(volatile u32 *)(ulong)&tx3927_pcicptr->ipciaddr = (unsigned long)ioaddr; *(volatile u32 *)(ulong)&tx3927_pcicptr->ipcibe = (PCI_IPCIBE_ICMD_IOWRITE << PCI_IPCIBE_ICMD_SHIFT) | PCI_IPCIBE_IBE_LONG; while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC)) ; /* clear by setting */ tx3927_pcicptr->istat |= PCI_ISTAT_IDICC; } void tx_insbyte(unsigned char *addr,void *buffer,unsigned int count) { unsigned char *ptr = (unsigned char *) buffer; while (count--) { *ptr++ = tx_ioinb(addr); } } void tx_insword(unsigned short *addr,void *buffer,unsigned int count) { unsigned short *ptr = (unsigned short *) buffer; while (count--) { *ptr++ = tx_ioinw(addr); } } void tx_inslong(unsigned int *addr,void *buffer,unsigned int count) { unsigned long *ptr = (unsigned long *) buffer; while (count--) { *ptr++ = tx_ioinl(addr); } } void tx_outsbyte(unsigned char *addr,void *buffer,unsigned int count) { unsigned char *ptr = (unsigned char *) buffer; while (count--) { tx_iooutb(*ptr++,addr); } } void tx_outsword(unsigned short *addr,void *buffer,unsigned int count) { unsigned short *ptr = (unsigned short *) buffer; while (count--) { tx_iooutw(*ptr++,addr); } } void tx_outslong(unsigned int *addr,void *buffer,unsigned int count) { unsigned long *ptr = (unsigned long *) buffer; while (count--) { tx_iooutl(*ptr++,addr); } } #endif --- NEW FILE: rtc.c --- /* * Copyright 2001 MontaVista Software Inc. * Author: MontaVista Software, Inc. * ahe...@mv... * * $Id: rtc.c,v 1.1 2001/11/10 03:56:05 jsimmons Exp $ * * RTC routines for Dallas 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) 200-2001 Toshiba Corporation * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ #include <asm/mc146818rtc.h> /* bad name... */ #include <asm/jmr3927/jmr3927.h> static unsigned char jmr3927_rtc_read_data(unsigned long addr) { return jmr3927_nvram_in(addr); } static void jmr3927_rtc_write_data(unsigned char data, unsigned long addr) { jmr3927_nvram_out(data, addr); } static int jmr3927_rtc_bcd_mode(void) { return 1; } struct rtc_ops jmr3927_rtc_ops = { &jmr3927_rtc_read_data, &jmr3927_rtc_write_data, &jmr3927_rtc_bcd_mode }; --- NEW FILE: setup.c --- /*********************************************************************** * * Copyright 2001 MontaVista Software Inc. * Author: MontaVista Software, Inc. * ahe...@mv... * * Based on arch/mips/ddb5xxx/ddb5477/setup.c * * Setup file for JMR3927. * * Copyright (C) 2000-2001 Toshiba Corporation * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. * *********************************************************************** */ #include <linux/config.h> #include <linux/init.h> #include <linux/kernel.h> #include <linux/kdev_t.h> #include <linux/types.h> #include <linux/console.h> #include <linux/sched.h> #include <linux/pci.h> #include <linux/ide.h> #include <linux/fs.h> /* for ROOT_DEV */ #include <linux/ioport.h> #include <linux/param.h> /* for HZ */ #include <linux/delay.h> #include <asm/addrspace.h> #include <asm/time.h> #include <asm/bcache.h> #include <asm/irq.h> #include <asm/reboot.h> #include <asm/gdb-stub.h> #include <asm/jmr3927/jmr3927.h> #include <asm/mipsregs.h> /* Tick Timer divider */ #define JMR3927_TIMER_CCD 0 /* 1/2 */ #define JMR3927_TIMER_CLK (JMR3927_IMCLK / (2 << JMR3927_TIMER_CCD)) unsigned char led_state = 0xf; struct { struct resource ram0; struct resource ram1; struct resource pcimem; struct resource iob; struct resource ioc; struct resource pciio; struct resource jmy1394; struct resource rom1; struct resource rom0; struct resource sio0; struct resource sio1; } jmr3927_resources = { { "RAM0", 0, 0x01FFFFFF, IORESOURCE_MEM }, { "RAM1", 0x02000000, 0x03FFFFFF, IORESOURCE_MEM }, { "PCIMEM", 0x08000000, 0x07FFFFFF, IORESOURCE_MEM }, { "IOB", 0x10000000, 0x13FFFFFF }, { "IOC", 0x14000000, 0x14FFFFFF }, { "PCIIO", 0x15000000, 0x15FFFFFF }, { "JMY1394", 0x1D000000, 0x1D3FFFFF }, { "ROM1", 0x1E000000, 0x1E3FFFFF }, { "ROM0", 0x1FC00000, 0x1FFFFFFF }, { "SIO0", 0xFFFEF300, 0xFFFEF3FF }, { "SIO1", 0xFFFEF400, 0xFFFEF4FF }, }; /* don't enable - see errata */ int jmr3927_ccfg_toeon = 0; static inline void do_reset(void) { #ifdef CONFIG_TC35815 extern void tc35815_killall(void); tc35815_killall(); #endif #if 1 /* Resetting PCI bus */ jmr3927_ioc_reg_out(0, JMR3927_IOC_RESET_ADDR); jmr3927_ioc_reg_out(JMR3927_IOC_RESET_PCI, JMR3927_IOC_RESET_ADDR); (void)jmr3927_ioc_reg_in(JMR3927_IOC_RESET_ADDR); /* flush WB */ mdelay(1); jmr3927_ioc_reg_out(0, JMR3927_IOC_RESET_ADDR); #endif jmr3927_ioc_reg_out(JMR3927_IOC_RESET_CPU, JMR3927_IOC_RESET_ADDR); } static void jmr3927_machine_restart(char *command) { cli(); puts("Rebooting..."); do_reset(); } static void jmr3927_machine_halt(void) { puts("JMR-TX3927 halted.\n"); while (1); } static void jmr3927_machine_power_off(void) { puts("JMR-TX3927 halted. Please turn off the power.\n"); while (1); } #define USE_RTC_DS1742 #ifdef USE_RTC_DS1742 extern void rtc_ds1742_init(unsigned long base); #endif static void __init jmr3927_time_init(void) { #ifdef USE_RTC_DS1742 if (jmr3927_have_nvram()) { rtc_ds1742_init(JMR3927_IOC_NVRAMB_ADDR); } #endif } unsigned long jmr3927_do_gettimeoffset(void); extern int setup_irq(unsigned int irq, struct irqaction *irqaction); static void __init jmr3927_timer_setup(struct irqaction *irq) { do_gettimeoffset = jmr3927_do_gettimeoffset; jmr3927_tmrptr->cpra = JMR3927_TIMER_CLK / HZ; jmr3927_tmrptr->itmr = TXx927_TMTITMR_TIIE | TXx927_TMTITMR_TZCE; jmr3927_tmrptr->ccdr = JMR3927_TIMER_CCD; jmr3927_tmrptr->tcr = TXx927_TMTCR_TCE | TXx927_TMTCR_CCDE | TXx927_TMTCR_TMODE_ITVL; setup_irq(JMR3927_IRQ_TICK, irq); } #define USECS_PER_JIFFY (1000000/HZ) unsigned long jmr3927_do_gettimeoffset(void) { unsigned long count; unsigned long res = 0; /* MUST read TRR before TISR. */ count = jmr3927_tmrptr->trr; if (jmr3927_tmrptr->tisr & TXx927_TMTISR_TIIS) { /* timer interrupt is pending. use Max value. */ res = USECS_PER_JIFFY - 1; } else { /* convert to usec */ /* res = count / (JMR3927_TIMER_CLK / 1000000); */ res = (count << 7) / ((JMR3927_TIMER_CLK << 7) / 1000000); /* * 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; } #if defined(CONFIG_BLK_DEV_INITRD) extern unsigned long __rd_start, __rd_end, initrd_start, initrd_end; #endif //#undef DO_WRITE_THROUGH #define DO_WRITE_THROUGH #define DO_ENABLE_CACHE extern char * __init prom_getcmdline(void); static void jmr3927_board_init(void); extern void jmr3927_irq_setup(void); extern struct resource pci_io_resource; extern struct resource pci_mem_resource; void __init jmr3927_setup(void) { extern int panic_timeout; char *argptr; irq_setup = jmr3927_irq_setup; mips_io_port_base = JMR3927_PORT_BASE + JMR3927_PCIIO; board_time_init = jmr3927_time_init; board_timer_setup = jmr3927_timer_setup; _machine_restart = jmr3927_machine_restart; _machine_halt = jmr3927_machine_halt; _machine_power_off = jmr3927_machine_power_off; /* * IO/MEM resources. */ ioport_resource.start = 0; ioport_resource.end = 0xffffffff; iomem_resource.start = 0; iomem_resource.end = 0xffffffff; /* Reboot on panic */ panic_timeout = 180; { unsigned int conf; conf = read_32bit_cp0_register(CP0_CONF); } #if 1 /* cache setup */ { unsigned int conf; #ifdef DO_ENABLE_CACHE int mips_ic_disable = 0, mips_dc_disable = 0; #else int mips_ic_disable = 1, mips_dc_disable = 1; #endif #ifdef DO_WRITE_THROUGH int mips_config_cwfon = 0; int mips_config_wbon = 0; #else int mips_config_cwfon = 1; int mips_config_wbon = 1; #endif clear_cp0_status(ST0_BEV); conf = read_32bit_cp0_register(CP0_CONF); conf &= ~(TX39_CONF_ICE | TX39_CONF_DCE | TX39_CONF_WBON | TX39_CONF_CWFON); conf |= mips_ic_disable ? 0 : TX39_CONF_ICE; conf |= mips_dc_disable ? 0 : TX39_CONF_DCE; conf |= mips_config_wbon ? TX39_CONF_WBON : 0; conf |= mips_config_cwfon ? TX39_CONF_CWFON : 0; write_32bit_cp0_register(CP0_CONF, conf); write_32bit_cp0_register(CP0_TX39_CACHE, 0); } #endif /* initialize board */ jmr3927_board_init(); argptr = prom_getcmdline(); if ((argptr = strstr(argptr, "toeon")) != NULL) { jmr3927_ccfg_toeon = 1; } argptr = prom_getcmdline(); if ((argptr = strstr(argptr, "ip=")) == NULL) { argptr = prom_getcmdline(); strcat(argptr, " ip=bootp"); } #ifdef CONFIG_TXX927_SERIAL_CONSOLE argptr = prom_getcmdline(); if ((argptr = strstr(argptr, "console=")) == NULL) { argptr = prom_getcmdline(); strcat(argptr, " console=ttyS1,115200"); } #endif } static void tx3927_setup(void); #ifdef CONFIG_PCI unsigned long mips_pci_io_base; unsigned long mips_pci_io_size; unsigned long mips_pci_mem_base; unsigned long mips_pci_mem_size; /* for legacy I/O, PCI I/O PCI Bus address must be 0 */ unsigned long mips_pci_io_pciaddr = 0; #endif extern struct rtc_ops *rtc_ops; extern struct rtc_ops jmr3927_rtc_ops; static void jmr3927_board_init() { char *argptr; #ifdef CONFIG_PCI mips_pci_io_base = JMR3927_PCIIO; mips_pci_io_size = JMR3927_PCIIO_SIZE; mips_pci_mem_base = JMR3927_PCIMEM; mips_pci_mem_size = JMR3927_PCIMEM_SIZE; #endif tx3927_setup(); #ifdef CONFIG_VT conswitchp = &dummy_con; #endif if (jmr3927_have_isac()) { #ifdef CONFIG_FB_E1355 argptr = prom_getcmdline(); if ((argptr = strstr(argptr, "video=")) == NULL) { argptr = prom_getcmdline(); strcat(argptr, " video=e1355fb:crt16h"); } #endif #ifdef CONFIG_BLK_DEV_IDE /* overrides PCI-IDE */ #endif #ifdef CONFIG_PC_KEYB //not yet kbd_ops = &jmr3927_kbd_ops; #endif } #ifdef USE_RTC_DS1742 if (jmr3927_have_nvram()) { rtc_ops = &jmr3927_rtc_ops; } #endif /* SIO0 DTR on */ jmr3927_ioc_reg_out(0, JMR3927_IOC_DTR_ADDR); jmr3927_led_set(0); if (jmr3927_have_isac()) jmr3927_io_led_set(0); printk("JMR-TX3927 (Rev %d) --- IOC(Rev %d) DIPSW:%d,%d,%d,%d\n", jmr3927_ioc_reg_in(JMR3927_IOC_BREV_ADDR) & JMR3927_REV_MASK, jmr3927_ioc_reg_in(JMR3927_IOC_REV_ADDR) & JMR3927_REV_MASK, jmr3927_dipsw1(), jmr3927_dipsw2(), jmr3927_dipsw3(), jmr3927_dipsw4()); if (jmr3927_have_isac()) printk("JMI-3927IO2 --- ISAC(Rev %d) DIPSW:%01x\n", jmr3927_isac_reg_in(JMR3927_ISAC_REV_ADDR) & JMR3927_REV_MASK, jmr3927_io_dipsw()); } static void tx3927_setup(void) { int i; /* SDRAMC are configured by PROM */ /* ROMC */ tx3927_romcptr->cr[1] = JMR3927_ROMCE1 | 0x00030048; tx3927_romcptr->cr[2] = JMR3927_ROMCE2 | 0x000064c8; tx3927_romcptr->cr[3] = JMR3927_ROMCE3 | 0x0003f698; tx3927_romcptr->cr[5] = JMR3927_ROMCE5 | 0x0000f218; /* CCFG */ /* enable Timeout BusError */ if (jmr3927_ccfg_toeon) tx3927_ccfgptr->ccfg |= TX3927_CCFG_TOE; /* clear BusErrorOnWrite flag */ tx3927_ccfgptr->ccfg &= ~TX3927_CCFG_BEOW; /* Disable PCI snoop */ tx3927_ccfgptr->ccfg &= ~TX3927_CCFG_PSNP; #ifdef DO_WRITE_THROUGH /* Enable PCI SNOOP - with write through only */ tx3927_ccfgptr->ccfg |= TX3927_CCFG_PSNP; #endif /* Pin selection */ tx3927_ccfgptr->pcfg &= ~TX3927_PCFG_SELALL; tx3927_ccfgptr->pcfg |= TX3927_PCFG_SELSIOC(0) | TX3927_PCFG_SELSIO_ALL | (TX3927_PCFG_SELDMA_ALL & ~TX3927_PCFG_SELDMA(1)); printk("TX3927 -- CRIR:%08lx CCFG:%08lx PCFG:%08lx\n", tx3927_ccfgptr->crir, tx3927_ccfgptr->ccfg, tx3927_ccfgptr->pcfg); /* IRC */ /* disable interrupt control */ tx3927_ircptr->cer = 0; /* mask all IRC interrupts */ tx3927_ircptr->imr = 0; for (i = 0; i < TX3927_NUM_IR / 2; i++) { tx3927_ircptr->ilr[i] = 0; } /* setup IRC interrupt mode (Low Active) */ for (i = 0; i < TX3927_NUM_IR / 8; i++) { tx3927_ircptr->cr[i] = 0; } /* TMR */ /* disable all timers */ for (i = 0; i < TX3927_NR_TMR; i++) { tx3927_tmrptr(i)->tcr = TXx927_TMTCR_CRE; tx3927_tmrptr(i)->tisr = 0; tx3927_tmrptr(i)->cpra = 0xffffffff; tx3927_tmrptr(i)->itmr = 0; tx3927_tmrptr(i)->ccdr = 0; tx3927_tmrptr(i)->pgmr = 0; } /* DMA */ tx3927_dmaptr->mcr = 0; for (i = 0; i < sizeof(tx3927_dmaptr->ch) / sizeof(tx3927_dmaptr->ch[0]); i++) { /* reset channel */ tx3927_dmaptr->ch[i].ccr = TX3927_DMA_CCR_CHRST; tx3927_dmaptr->ch[i].ccr = 0; } /* enable DMA */ #ifdef __BIG_ENDIAN tx3927_dmaptr->mcr = TX3927_DMA_MCR_MSTEN; #else tx3927_dmaptr->mcr = TX3927_DMA_MCR_MSTEN | TX3927_DMA_MCR_LE; #endif #ifdef CONFIG_PCI /* PCIC */ printk("TX3927 PCIC -- DID:%04x VID:%04x RID:%02x Arbiter:", tx3927_pcicptr->did, tx3927_pcicptr->vid, tx3927_pcicptr->rid); if (!(tx3927_ccfgptr->ccfg & TX3927_CCFG_PCIXARB)) { printk("External\n"); /* XXX */ } else { printk("Internal\n"); /* Reset PCI Bus */ jmr3927_ioc_reg_out(0, JMR3927_IOC_RESET_ADDR); udelay(100); jmr3927_ioc_reg_out(JMR3927_IOC_RESET_PCI, JMR3927_IOC_RESET_ADDR); udelay(100); jmr3927_ioc_reg_out(0, JMR3927_IOC_RESET_ADDR); /* Disable External PCI Config. Access */ tx3927_pcicptr->lbc = TX3927_PCIC_LBC_EPCAD; #ifdef __BIG_ENDIAN tx3927_pcicptr->lbc |= TX3927_PCIC_LBC_IBSE | TX3927_PCIC_LBC_TIBSE | TX3927_PCIC_LBC_TMFBSE | TX3927_PCIC_LBC_MSDSE; #endif /* LB->PCI mappings */ tx3927_pcicptr->iomas = ~(mips_pci_io_size - 1); tx3927_pcicptr->ilbioma = mips_pci_io_base; tx3927_pcicptr->ipbioma = mips_pci_io_pciaddr; tx3927_pcicptr->mmas = ~(mips_pci_mem_size - 1); tx3927_pcicptr->ilbmma = mips_pci_mem_base; tx3927_pcicptr->ipbmma = mips_pci_mem_base; /* PCI->LB mappings */ tx3927_pcicptr->iobas = 0xffffffff; tx3927_pcicptr->ioba = 0; tx3927_pcicptr->tlbioma = 0; tx3927_pcicptr->mbas = ~(mips_pci_mem_size - 1); tx3927_pcicptr->mba = 0; tx3927_pcicptr->tlbmma = 0; #ifndef JMR3927_INIT_INDIRECT_PCI /* Enable Direct mapping Address Space Decoder */ tx3927_pcicptr->lbc |= TX3927_PCIC_LBC_ILMDE | TX3927_PCIC_LBC_ILIDE; #endif /* Clear All Local Bus Status */ tx3927_pcicptr->lbstat = TX3927_PCIC_LBIM_ALL; /* Enable All Local Bus Interrupts */ tx3927_pcicptr->lbim = TX3927_PCIC_LBIM_ALL; /* Clear All PCI Status Error */ tx3927_pcicptr->pcistat = TX3927_PCIC_PCISTATIM_ALL; /* Enable All PCI Status Error Interrupts */ tx3927_pcicptr->pcistatim = TX3927_PCIC_PCISTATIM_ALL; /* PCIC Int => IRC IRQ10 */ tx3927_pcicptr->il = TX3927_IR_PCI; #if 1 /* Target Control (per errata) */ tx3927_pcicptr->tc = TX3927_PCIC_TC_OF8E | TX3927_PCIC_TC_IF8E; #endif /* Enable Bus Arbiter */ #if 0 tx3927_pcicptr->req_trace = 0x73737373; #endif tx3927_pcicptr->pbapmc = TX3927_PCIC_PBAPMC_PBAEN; tx3927_pcicptr->pcicmd = PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | #if 1 PCI_COMMAND_IO | #endif PCI_COMMAND_PARITY | PCI_COMMAND_SERR; } #endif /* CONFIG_PCI */ /* PIO */ /* PIO[15:12] connected to LEDs */ tx3927_pioptr->dir = 0x0000f000; tx3927_pioptr->maskcpu = 0; tx3927_pioptr->maskext = 0; { unsigned int conf; conf = read_32bit_cp0_register(CP0_CONF); if (!(conf & TX39_CONF_ICE)) printk("TX3927 I-Cache disabled.\n"); if (!(conf & TX39_CONF_DCE)) printk("TX3927 D-Cache disabled.\n"); else if (!(conf & TX39_CONF_WBON)) printk("TX3927 D-Cache WriteThrough.\n"); else if (!(conf & TX39_CONF_CWFON)) printk("TX3927 D-Cache WriteBack.\n"); else printk("TX3927 D-Cache WriteBack (CWF) .\n"); } } |