diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-03-07 15:45:24 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-03-07 15:45:24 +0000 |
commit | 9f9f3e6e8548a596697778337110a423c384b6f3 (patch) | |
tree | 5dd4b290ef532cf5ecb058e1a92cd3435afeac8c /arch/alpha/kernel/core_pyxis.c | |
parent | d5c9a365ee7d2fded249aa5abfc5e89587583029 (diff) |
Merge with Linux 2.3.49.
Diffstat (limited to 'arch/alpha/kernel/core_pyxis.c')
-rw-r--r-- | arch/alpha/kernel/core_pyxis.c | 130 |
1 files changed, 71 insertions, 59 deletions
diff --git a/arch/alpha/kernel/core_pyxis.c b/arch/alpha/kernel/core_pyxis.c index 80ee8ba7f..f6106c475 100644 --- a/arch/alpha/kernel/core_pyxis.c +++ b/arch/alpha/kernel/core_pyxis.c @@ -36,7 +36,6 @@ */ #define DEBUG_CONFIG 0 - #if DEBUG_CONFIG # define DBG_CNF(args) printk args #else @@ -304,7 +303,7 @@ pyxis_enable_irq(unsigned int irq) pyxis_update_irq_hw(cached_irq_mask |= 1UL << (irq - 16)); } -static inline void +static void pyxis_disable_irq(unsigned int irq) { pyxis_update_irq_hw(cached_irq_mask &= ~(1UL << (irq - 16))); @@ -318,6 +317,13 @@ pyxis_startup_irq(unsigned int irq) } static void +pyxis_end_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + pyxis_enable_irq(irq); +} + +static void pyxis_mask_and_ack_irq(unsigned int irq) { unsigned long bit = 1UL << (irq - 16); @@ -340,7 +346,7 @@ static struct hw_interrupt_type pyxis_irq_type = { enable: pyxis_enable_irq, disable: pyxis_disable_irq, ack: pyxis_mask_and_ack_irq, - end: pyxis_enable_irq, + end: pyxis_end_irq, }; void @@ -382,7 +388,7 @@ init_pyxis_irqs(unsigned long ignore_mask) for (i = 16; i < 48; ++i) { if ((ignore_mask >> i) & 1) continue; - irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; irq_desc[i].handler = &pyxis_irq_type; } @@ -427,6 +433,8 @@ pyxis_broken_pci_tbi(struct pci_controler *hose, ctrl = *(vuip)PYXIS_CTRL; *(vuip)PYXIS_CTRL = ctrl | 4; mb(); + *(vuip)PYXIS_CTRL; + mb(); /* Read from PCI dense memory space at TBI_ADDR, skipping 64k on each read. This forces SG TLB misses. It appears that @@ -441,6 +449,8 @@ pyxis_broken_pci_tbi(struct pci_controler *hose, mb(); *(vuip)PYXIS_CTRL = ctrl; mb(); + *(vuip)PYXIS_CTRL; + mb(); __restore_flags(flags); } @@ -473,31 +483,31 @@ pyxis_init_arch(void) struct pci_controler *hose; unsigned int temp; -#if 0 - printk("pyxis_init: PYXIS_ERR_MASK 0x%x\n", *(vuip)PYXIS_ERR_MASK); - printk("pyxis_init: PYXIS_ERR 0x%x\n", *(vuip)PYXIS_ERR); - printk("pyxis_init: PYXIS_INT_REQ 0x%lx\n", *(vulp)PYXIS_INT_REQ); - printk("pyxis_init: PYXIS_INT_MASK 0x%lx\n", *(vulp)PYXIS_INT_MASK); - printk("pyxis_init: PYXIS_INT_ROUTE 0x%lx\n", *(vulp)PYXIS_INT_ROUTE); - printk("pyxis_init: PYXIS_INT_HILO 0x%lx\n", *(vulp)PYXIS_INT_HILO); - printk("pyxis_init: PYXIS_INT_CNFG 0x%x\n", *(vuip)PYXIS_INT_CNFG); - printk("pyxis_init: PYXIS_RT_COUNT 0x%lx\n", *(vulp)PYXIS_RT_COUNT); -#endif - - /* - * Set up error reporting. Make sure CPU_PE is OFF in the mask. - */ + /* Set up error reporting. Make sure CPU_PE is OFF in the mask. */ temp = *(vuip)PYXIS_ERR_MASK; - temp &= ~4; - *(vuip)PYXIS_ERR_MASK = temp; - mb(); - *(vuip)PYXIS_ERR_MASK; /* re-read to force write */ + *(vuip)PYXIS_ERR_MASK = temp & ~4; + /* Enable master/target abort. */ temp = *(vuip)PYXIS_ERR; - temp |= 0x180; /* master/target abort */ - *(vuip)PYXIS_ERR = temp; + *(vuip)PYXIS_ERR = temp | 0x180; + + /* Clear the PYXIS_CFG register, which gets used for PCI Config + Space accesses. That is the way we want to use it, and we do + not want to depend on what ARC or SRM might have left behind. */ + *(vuip)PYXIS_CFG = 0; + + /* Zero the HAEs. */ + *(vuip)PYXIS_HAE_MEM = 0; + *(vuip)PYXIS_HAE_IO = 0; + + /* Finally, check that the PYXIS_CTRL1 has IOA_BEN set for + enabling byte/word PCI bus space(s) access. */ + temp = *(vuip)PYXIS_CTRL1; + *(vuip)PYXIS_CTRL1 = temp | 1; + + /* Syncronize with all previous changes. */ mb(); - *(vuip)PYXIS_ERR; /* re-read to force write */ + *(vuip)PYXIS_REV; /* * Create our single hose. @@ -524,10 +534,41 @@ pyxis_init_arch(void) * address range. */ - /* NetBSD hints that page tables must be aligned to 32K due - to a hardware bug. No description of what models affected. */ - hose->sg_isa = iommu_arena_new(0x00800000, 0x00800000, 32768); - hose->sg_pci = iommu_arena_new(0xc0000000, 0x08000000, 32768); +#if 1 + /* ??? There's some bit of syncronization wrt writing new tlb + entries that's missing. Sometimes it works, sometimes invalid + tlb machine checks, sometimes hard lockup. And this just within + the boot sequence. + + I've tried extra memory barriers, extra alignment, pyxis + register reads, tlb flushes, and loopback tlb accesses. + + I guess the pyxis revision in the sx164 is just too buggy... */ + + hose->sg_isa = hose->sg_pci = NULL; + __direct_map_base = 0x40000000; + __direct_map_size = 0x80000000; + + *(vuip)PYXIS_W0_BASE = 0x40000000 | 1; + *(vuip)PYXIS_W0_MASK = (0x40000000 - 1) & 0xfff00000; + *(vuip)PYXIS_T0_BASE = 0; + + *(vuip)PYXIS_W1_BASE = 0x80000000 | 1; + *(vuip)PYXIS_W1_MASK = (0x40000000 - 1) & 0xfff00000; + *(vuip)PYXIS_T1_BASE = 0; + + *(vuip)PYXIS_W2_BASE = 0; + *(vuip)PYXIS_W3_BASE = 0; + + alpha_mv.mv_pci_tbi = NULL; + mb(); +#else + /* ??? NetBSD hints that page tables must be aligned to 32K, + possibly due to a hardware bug. This is over-aligned + from the 8K alignment one would expect for an 8MB window. + No description of what CIA revisions affected. */ + hose->sg_isa = iommu_arena_new(hose, 0x00800000, 0x00800000, 0x08000); + hose->sg_pci = iommu_arena_new(hose, 0xc0000000, 0x08000000, 0x20000); __direct_map_base = 0x40000000; __direct_map_size = 0x80000000; @@ -553,36 +594,7 @@ pyxis_init_arch(void) pyxis_enable_broken_tbi(hose->sg_pci); alpha_mv.mv_pci_tbi(hose, 0, -1); - - /* - * Next, clear the PYXIS_CFG register, which gets used - * for PCI Config Space accesses. That is the way - * we want to use it, and we do not want to depend on - * what ARC or SRM might have left behind... - */ - temp = *(vuip)PYXIS_CFG; - if (temp != 0) { - *(vuip)PYXIS_CFG = 0; - mb(); - *(vuip)PYXIS_CFG; /* re-read to force write */ - } - - /* Zero the HAE. */ - *(vuip)PYXIS_HAE_MEM = 0U; mb(); - *(vuip)PYXIS_HAE_MEM; /* re-read to force write */ - *(vuip)PYXIS_HAE_IO = 0; mb(); - *(vuip)PYXIS_HAE_IO; /* re-read to force write */ - - /* - * Finally, check that the PYXIS_CTRL1 has IOA_BEN set for - * enabling byte/word PCI bus space(s) access. - */ - temp = *(vuip) PYXIS_CTRL1; - if (!(temp & 1)) { - *(vuip)PYXIS_CTRL1 = temp | 1; - mb(); - *(vuip)PYXIS_CTRL1; /* re-read */ - } +#endif } static inline void |