Commit dd263728 authored by Richard Henderson's avatar Richard Henderson

Merge kanga.twiddle.home:/home/rth/work/linux/linus-2.5

into kanga.twiddle.home:/home/rth/work/linux/axp-2.5
parents 03e4e085 0f6f2c78
......@@ -556,6 +556,24 @@ config ALPHA_LARGE_VMALLOC
config VERBOSE_MCHECK
bool "Verbose Machine Checks"
config VERBOSE_MCHECK_ON
int "Verbose Printing Mode (0=off, 1=on, 2=all)"
depends on VERBOSE_MCHECK
default 1
---help---
This option allows the default printing mode to be set, and then
possibly overridden by a boot command argument.
For example, if one wanted the option of printing verbose
machine checks, but wanted the default to be as if verbose
machine check printing was turned off, then one would choose
the printing mode to be 0. Then, upon reboot, one could add
the boot command line "verbose_mcheck=1" to get the normal
verbose machine check printing, or "verbose_mcheck=2" to get
the maximum information available.
Take the default (1) unless you want more control or more info.
source "drivers/pci/Kconfig"
source "drivers/eisa/Kconfig"
......
......@@ -29,8 +29,17 @@
/* FIXME FIXME FIXME */
/*
WARNING NOTE
It is very possible that turning on additional messages may cause
kernel image corruption due to stack usage to do the printing.
*/
#undef DEBUG_CHECK_RANGE
#define DEBUG_ADDRESSES
#undef DEBUG_ADDRESSES
#undef DEBUG_LAST_STEPS
#define DEBUG_SP(x) \
{register long sp asm("30"); srm_printk("%s (sp=%lx)\n", x, sp);}
......@@ -433,15 +442,25 @@ start_kernel(void)
}
/* Clear the zero page, then move the argument list in. */
#ifdef DEBUG_LAST_STEPS
srm_printk("Preparing ZERO_PGE...\n");
#endif
memset((char*)ZERO_PGE, 0, PAGE_SIZE);
strcpy((char*)ZERO_PGE, envval);
#ifdef INITRD_IMAGE_SIZE
#ifdef DEBUG_LAST_STEPS
srm_printk("Preparing INITRD info...\n");
#endif
/* Finally, set the INITRD paramenters for the kernel. */
((long *)(ZERO_PGE+256))[0] = initrd_image_start;
((long *)(ZERO_PGE+256))[1] = INITRD_IMAGE_SIZE;
#endif /* INITRD_IMAGE_SIZE */
#ifdef DEBUG_LAST_STEPS
srm_printk("Doing 'runkernel()'...\n");
#endif
runkernel();
}
......@@ -47,15 +47,6 @@
#define vip volatile int *
/* Save CIA configuration data as the console had it set up. */
struct
{
unsigned int w_base;
unsigned int w_mask;
unsigned int t_base;
} saved_config[4] __attribute((common));
/*
* Given a bus, device, and function number, compute resulting
* configuration space address. It is therefore not safe to have
......@@ -566,6 +557,77 @@ verify_tb_operation(void)
alpha_mv.mv_pci_tbi = NULL;
goto exit;
}
#if defined(ALPHA_RESTORE_SRM_SETUP)
/* Save CIA configuration data as the console had it set up. */
struct
{
unsigned int hae_mem;
unsigned int hae_io;
unsigned int pci_dac_offset;
unsigned int err_mask;
unsigned int cia_ctrl;
unsigned int cia_cnfg;
struct {
unsigned int w_base;
unsigned int w_mask;
unsigned int t_base;
} window[4];
} saved_config __attribute((common));
void
cia_save_srm_settings(int is_pyxis)
{
int i;
/* Save some important registers. */
saved_config.err_mask = *(vip)CIA_IOC_ERR_MASK;
saved_config.cia_ctrl = *(vip)CIA_IOC_CIA_CTRL;
saved_config.hae_mem = *(vip)CIA_IOC_HAE_MEM;
saved_config.hae_io = *(vip)CIA_IOC_HAE_IO;
saved_config.pci_dac_offset = *(vip)CIA_IOC_PCI_W_DAC;
if (is_pyxis)
saved_config.cia_cnfg = *(vip)CIA_IOC_CIA_CNFG;
else
saved_config.cia_cnfg = 0;
/* Save DMA windows configuration. */
for (i = 0; i < 4; i++) {
saved_config.window[i].w_base = *(vip)CIA_IOC_PCI_Wn_BASE(i);
saved_config.window[i].w_mask = *(vip)CIA_IOC_PCI_Wn_MASK(i);
saved_config.window[i].t_base = *(vip)CIA_IOC_PCI_Tn_BASE(i);
}
mb();
}
void
cia_restore_srm_settings(void)
{
int i;
for (i = 0; i < 4; i++) {
*(vip)CIA_IOC_PCI_Wn_BASE(i) = saved_config.window[i].w_base;
*(vip)CIA_IOC_PCI_Wn_MASK(i) = saved_config.window[i].w_mask;
*(vip)CIA_IOC_PCI_Tn_BASE(i) = saved_config.window[i].t_base;
}
*(vip)CIA_IOC_HAE_MEM = saved_config.hae_mem;
*(vip)CIA_IOC_HAE_IO = saved_config.hae_io;
*(vip)CIA_IOC_PCI_W_DAC = saved_config.pci_dac_offset;
*(vip)CIA_IOC_ERR_MASK = saved_config.err_mask;
*(vip)CIA_IOC_CIA_CTRL = saved_config.cia_ctrl;
if (saved_config.cia_cnfg) /* Must be pyxis. */
*(vip)CIA_IOC_CIA_CNFG = saved_config.cia_cnfg;
mb();
}
#else /* ALPHA_RESTORE_SRM_SETUP */
#define cia_save_srm_settings(p) do {} while (0)
#define cia_restore_srm_settings() do {} while (0)
#endif /* ALPHA_RESTORE_SRM_SETUP */
static void __init
do_init_arch(int is_pyxis)
......@@ -577,6 +639,9 @@ do_init_arch(int is_pyxis)
printk("pci: cia revision %d%s\n",
cia_rev, is_pyxis ? " (pyxis)" : "");
if (alpha_using_srm)
cia_save_srm_settings(is_pyxis);
/* Set up error reporting. */
temp = *(vip)CIA_IOC_ERR_MASK;
temp &= ~(CIA_ERR_CPU_PE | CIA_ERR_MEM_NEM | CIA_ERR_PA_PTE_INV
......@@ -646,24 +711,6 @@ do_init_arch(int is_pyxis)
hose->dense_io_base = CIA_BW_IO - IDENT_ADDR;
}
/* Save CIA configuration data as the console had it set up. */
saved_config[0].w_base = *(vip)CIA_IOC_PCI_W0_BASE;
saved_config[0].w_mask = *(vip)CIA_IOC_PCI_W0_MASK;
saved_config[0].t_base = *(vip)CIA_IOC_PCI_T0_BASE;
saved_config[1].w_base = *(vip)CIA_IOC_PCI_W1_BASE;
saved_config[1].w_mask = *(vip)CIA_IOC_PCI_W1_MASK;
saved_config[1].t_base = *(vip)CIA_IOC_PCI_T1_BASE;
saved_config[2].w_base = *(vip)CIA_IOC_PCI_W2_BASE;
saved_config[2].w_mask = *(vip)CIA_IOC_PCI_W2_MASK;
saved_config[2].t_base = *(vip)CIA_IOC_PCI_T2_BASE;
saved_config[3].w_base = *(vip)CIA_IOC_PCI_W3_BASE;
saved_config[3].w_mask = *(vip)CIA_IOC_PCI_W3_MASK;
saved_config[3].t_base = *(vip)CIA_IOC_PCI_T3_BASE;
/*
* Set up the PCI to main memory translation windows.
*
......@@ -761,21 +808,8 @@ pyxis_init_arch(void)
void
cia_kill_arch(int mode)
{
*(vip)CIA_IOC_PCI_W0_BASE = saved_config[0].w_base;
*(vip)CIA_IOC_PCI_W0_MASK = saved_config[0].w_mask;
*(vip)CIA_IOC_PCI_T0_BASE = saved_config[0].t_base;
*(vip)CIA_IOC_PCI_W1_BASE = saved_config[1].w_base;
*(vip)CIA_IOC_PCI_W1_MASK = saved_config[1].w_mask;
*(vip)CIA_IOC_PCI_T1_BASE = saved_config[1].t_base;
*(vip)CIA_IOC_PCI_W2_BASE = saved_config[2].w_base;
*(vip)CIA_IOC_PCI_W2_MASK = saved_config[2].w_mask;
*(vip)CIA_IOC_PCI_T2_BASE = saved_config[2].t_base;
*(vip)CIA_IOC_PCI_W3_BASE = saved_config[3].w_base;
*(vip)CIA_IOC_PCI_W3_MASK = saved_config[3].w_mask;
*(vip)CIA_IOC_PCI_T3_BASE = saved_config[3].t_base;
if (alpha_using_srm)
cia_restore_srm_settings();
}
void __init
......@@ -1065,7 +1099,8 @@ cia_decode_parity_error(struct el_CIA_sysdata_mcheck *cia)
printk(KERN_CRIT " Command: %s, Parity bit: %d\n", cmd, par);
printk(KERN_CRIT " Address: %#010lx, Mask: %#lx\n", addr, mask);
}
#endif
#endif /* CONFIG_VERBOSE_MCHECK */
static int
cia_decode_mchk(unsigned long la_ptr)
......@@ -1080,6 +1115,9 @@ cia_decode_mchk(unsigned long la_ptr)
return 0;
#ifdef CONFIG_VERBOSE_MCHECK
if (!alpha_verbose_mcheck)
return 1;
switch (ffs(cia->cia_err & 0xfff) - 1) {
case 0: /* CIA_ERR_COR_ERR */
cia_decode_ecc_error(cia, "Corrected ECC error");
......@@ -1152,7 +1190,7 @@ cia_decode_mchk(unsigned long la_ptr)
if (cia->cia_err & CIA_ERR_LOST_IOA_TIMEOUT)
printk(KERN_CRIT "CIA lost machine check: "
"I/O timeout\n");
#endif
#endif /* CONFIG_VERBOSE_MCHECK */
return 1;
}
......
......@@ -242,7 +242,7 @@ void
lca_pci_tbi(struct pci_controller *hose, dma_addr_t start, dma_addr_t end)
{
wmb();
*(vip)LCA_IOC_TBIA = 0;
*(vulp)LCA_IOC_TBIA = 0;
mb();
}
......@@ -268,21 +268,25 @@ lca_init_arch(void)
/*
* Set up the PCI to main memory translation windows.
*
* Window 0 is direct access 1GB at 1GB
* Window 1 is scatter-gather 8MB at 8MB (for isa)
* Mimic the SRM settings for the direct-map window.
* Window 0 is scatter-gather 8MB at 8MB (for isa).
* Window 1 is direct access 1GB at 1GB.
*
* Note that we do not try to save any of the DMA window CSRs
* before setting them, since we cannot read those CSRs on LCA.
*/
hose->sg_isa = iommu_arena_new(hose, 0x00800000, 0x00800000, 0);
hose->sg_pci = NULL;
__direct_map_base = 0x40000000;
__direct_map_size = 0x40000000;
*(vulp)LCA_IOC_W_BASE0 = __direct_map_base | (2UL << 32);
*(vulp)LCA_IOC_W_MASK0 = (__direct_map_size - 1) & 0xfff00000;
*(vulp)LCA_IOC_T_BASE0 = 0;
*(vulp)LCA_IOC_W_BASE0 = hose->sg_isa->dma_base | (3UL << 32);
*(vulp)LCA_IOC_W_MASK0 = (hose->sg_isa->size - 1) & 0xfff00000;
*(vulp)LCA_IOC_T_BASE0 = virt_to_phys(hose->sg_isa->ptes);
*(vulp)LCA_IOC_W_BASE1 = hose->sg_isa->dma_base | (3UL << 32);
*(vulp)LCA_IOC_W_MASK1 = (hose->sg_isa->size - 1) & 0xfff00000;
*(vulp)LCA_IOC_T_BASE1 = virt_to_phys(hose->sg_isa->ptes);
*(vulp)LCA_IOC_W_BASE1 = __direct_map_base | (2UL << 32);
*(vulp)LCA_IOC_W_MASK1 = (__direct_map_size - 1) & 0xfff00000;
*(vulp)LCA_IOC_T_BASE1 = 0;
*(vulp)LCA_IOC_TB_ENA = 0x80;
......@@ -294,6 +298,15 @@ lca_init_arch(void)
* data parity errors.
*/
*(vulp)LCA_IOC_PAR_DIS = 1UL<<5;
/*
* Finally, set up for restoring the correct HAE if using SRM.
* Again, since we cannot read many of the CSRs on the LCA,
* one of which happens to be the HAE, we save the value that
* the SRM will expect...
*/
if (alpha_using_srm)
srm_hae = 0x80000000UL;
}
/*
......@@ -447,8 +460,8 @@ lca_machine_check(unsigned long vector, unsigned long la_ptr,
}
/* Dump the logout area to give all info. */
#if DEBUG_MCHECK > 1
{
#ifdef CONFIG_VERBOSE_MCHECK
if (alpha_verbose_mcheck > 1) {
unsigned long * ptr = (unsigned long *) la_ptr;
long i;
for (i = 0; i < el.c->size / sizeof(long); i += 2) {
......@@ -456,7 +469,7 @@ lca_machine_check(unsigned long vector, unsigned long la_ptr,
i*sizeof(long), ptr[i], ptr[i+1]);
}
}
#endif
#endif /* CONFIG_VERBOSE_MCHECK */
}
/*
......
......@@ -524,7 +524,7 @@ mk_conf_addr(struct pci_bus *pbus, unsigned int devfn, int where)
if (!io7_port->enabled)
return addr;
if (hose->bus == pbus) {
if (!pbus->parent) { /* No parent means peer PCI bus. */
/* Don't support idsel > 20 on primary bus. */
if (devfn >= PCI_DEVFN(21, 0))
return addr;
......
......@@ -185,7 +185,7 @@ mk_conf_addr(struct pci_bus *pbus, unsigned int devfn, int where,
/* Type 1 configuration cycle for *ALL* busses. */
*type1 = 1;
if (hose->bus == pbus)
if (!pbus->parent) /* No parent means peer PCI bus. */
bus = 0;
addr = (bus << 16) | (devfn << 8) | (where);
addr <<= 5; /* swizzle for SPARSE */
......
......@@ -557,9 +557,9 @@ t2_machine_check(unsigned long vector, unsigned long la_ptr,
struct pt_regs * regs)
{
int cpu = smp_processor_id();
#if DEBUG_MCHECK > 0
#ifdef CONFIG_VERBOSE_MCHECK
struct el_common *mchk_header = (struct el_common *)la_ptr;
#endif /* DEBUG_MCHECK */
#endif
/* Clear the error before any reporting. */
mb();
......@@ -580,39 +580,45 @@ t2_machine_check(unsigned long vector, unsigned long la_ptr,
*
* Just dismiss it for now on this CPU...
*/
#if DEBUG_MCHECK > 0
printk("t2_machine_check(cpu%d): any_expected 0x%x -"
" (assumed) spurious -"
" code 0x%x\n", cpu, t2_mcheck_any_expected,
(unsigned int)mchk_header->code);
#endif /* DEBUG_MCHECK */
#ifdef CONFIG_VERBOSE_MCHECK
if (alpha_verbose_mcheck > 1) {
printk("t2_machine_check(cpu%d): any_expected 0x%x -"
" (assumed) spurious -"
" code 0x%x\n", cpu, t2_mcheck_any_expected,
(unsigned int)mchk_header->code);
}
#endif
return;
}
if (!mcheck_expected(cpu) && !t2_mcheck_any_expected) {
if (t2_mcheck_last_taken & (1 << cpu)) {
#if DEBUG_MCHECK > 0
#ifdef CONFIG_VERBOSE_MCHECK
if (alpha_verbose_mcheck > 1) {
printk("t2_machine_check(cpu%d): last_taken 0x%x - "
"unexpected mcheck - code 0x%x\n",
cpu, t2_mcheck_last_taken,
(unsigned int)mchk_header->code);
#endif /* DEBUG_MCHECK */
t2_mcheck_last_taken = 0;
mb();
return;
}
#endif
t2_mcheck_last_taken = 0;
mb();
return;
} else {
t2_mcheck_last_taken = 0;
mb();
}
}
#if DEBUG_MCHECK > 0
printk("%s t2_mcheck(cpu%d): last_taken 0x%x - "
"any_expected 0x%x - code 0x%x\n",
(mcheck_expected(cpu) ? "EX" : "UN"), cpu,
t2_mcheck_last_taken, t2_mcheck_any_expected,
(unsigned int)mchk_header->code);
#endif /* DEBUG_MCHECK */
#ifdef CONFIG_VERBOSE_MCHECK
if (alpha_verbose_mcheck > 1) {
printk("%s t2_mcheck(cpu%d): last_taken 0x%x - "
"any_expected 0x%x - code 0x%x\n",
(mcheck_expected(cpu) ? "EX" : "UN"), cpu,
t2_mcheck_last_taken, t2_mcheck_any_expected,
(unsigned int)mchk_header->code);
}
#endif
process_mcheck_info(vector, la_ptr, regs, "T2", mcheck_expected(cpu));
}
......@@ -43,7 +43,6 @@ struct
* BIOS32-style PCI interface:
*/
#define DEBUG_MCHECK 0 /* 0 = minimum, 1 = debug, 2 = dump+dump */
#define DEBUG_CONFIG 0
#if DEBUG_CONFIG
......@@ -123,7 +122,7 @@ mk_conf_addr(struct pci_bus *pbus, unsigned int device_fn, int where,
"pci_addr=0x%p, type1=0x%p)\n",
bus, device_fn, where, pci_addr, type1));
if (hose->bus == pbus)
if (!pbus->parent) /* No parent means peer PCI bus. */
bus = 0;
*type1 = (bus != 0);
......
......@@ -45,7 +45,6 @@ struct
* BIOS32-style PCI interface:
*/
#define DEBUG_MCHECK 0 /* 0 = minimal, 1 = debug, 2 = debug+dump. */
#define DEBUG_CONFIG 0
#if DEBUG_CONFIG
......@@ -100,8 +99,8 @@ mk_conf_addr(struct pci_bus *pbus, unsigned int device_fn, int where,
DBG_CFG(("mk_conf_addr(bus=%d ,device_fn=0x%x, where=0x%x, "
"pci_addr=0x%p, type1=0x%p)\n",
bus, device_fn, where, pci_addr, type1));
if (hose->bus == pbus)
if (!pbus->parent) /* No parent means peer PCI bus. */
bus = 0;
*type1 = (bus != 0);
......
......@@ -24,7 +24,6 @@
#include "proto.h"
#include "pci_impl.h"
#define DEBUG_MCHECK 0 /* 0 = minimal, 1 = debug, 2 = debug+dump. */
#define DEBUG_CONFIG 0
#define DEBUG_DUMP_REGS 0
#define DEBUG_DUMP_CONFIG 1
......@@ -367,7 +366,7 @@ mk_conf_addr(struct pci_bus *pbus, unsigned int device_fn, int where,
"pci_addr=0x%p, type1=0x%p)\n",
bus, device_fn, where, pci_addr, type1));
if (hose->bus == pbus)
if (!pbus->parent) /* No parent means peer PCI bus. */
bus = 0;
*type1 = (bus != 0);
......
......@@ -438,8 +438,9 @@ titan_machine_check(u64 vector, u64 la_ptr, struct pt_regs *regs)
(unsigned int)vector, (int)smp_processor_id());
#ifdef CONFIG_VERBOSE_MCHECK
titan_process_logout_frame(mchk_header, 1);
dik_show_regs(regs, NULL);
titan_process_logout_frame(mchk_header, alpha_verbose_mcheck);
if (alpha_verbose_mcheck)
dik_show_regs(regs, NULL);
#endif /* CONFIG_VERBOSE_MCHECK */
err_print_prefix = saved_err_prefix;
......
......@@ -130,9 +130,11 @@ process_mcheck_info(unsigned long vector, unsigned long la_ptr,
* ignore it.
*/
#if DEBUG_MCHECK > 0
printk(KERN_CRIT "%s machine check %s\n", machine,
expected ? "expected." : "NOT expected!!!");
#ifdef CONFIG_VERBOSE_MCHECK
if (alpha_verbose_mcheck > 1) {
printk(KERN_CRIT "%s machine check %s\n", machine,
expected ? "expected." : "NOT expected!!!");
}
#endif
if (expected) {
......@@ -188,8 +190,8 @@ process_mcheck_info(unsigned long vector, unsigned long la_ptr,
dik_show_regs(regs, NULL);
#if DEBUG_MCHECK > 1
{
#ifdef CONFIG_VERBOSE_MCHECK
if (alpha_verbose_mcheck > 1) {
/* Dump the logout area to give all info. */
unsigned long *ptr = (unsigned long *)la_ptr;
long i;
......@@ -198,7 +200,7 @@ process_mcheck_info(unsigned long vector, unsigned long la_ptr,
i*sizeof(long), ptr[i], ptr[i+1]);
}
}
#endif
#endif /* CONFIG_VERBOSE_MCHECK */
}
/*
......
......@@ -21,6 +21,7 @@
#include <linux/bootmem.h>
#include <linux/module.h>
#include <linux/cache.h>
#include <linux/slab.h>
#include <asm/machvec.h>
#include "proto.h"
......@@ -44,7 +45,11 @@ const char *const pci_mem_names[] = {
const char pci_hae0_name[] = "HAE0";
/* Indicate whether we respect the PCI setup left by console. */
int __initdata pci_probe_only;
/*
* Make this long-lived so that we know when shutting down
* whether we probed only or not.
*/
int pci_probe_only;
/*
* The PCI controller list.
......@@ -202,6 +207,52 @@ pcibios_setup(char *str)
return str;
}
#ifdef ALPHA_RESTORE_SRM_SETUP
static struct pdev_srm_saved_conf *srm_saved_configs;
void __init
pdev_save_srm_config(struct pci_dev *dev)
{
struct pdev_srm_saved_conf *tmp;
static int printed = 0;
if (!alpha_using_srm || pci_probe_only)
return;
if (!printed) {
printk(KERN_INFO "pci: enabling save/restore of SRM state\n");
printed = 1;
}
tmp = kmalloc(sizeof(*tmp), GFP_KERNEL);
if (!tmp) {
printk(KERN_ERR "%s: kmalloc() failed!\n", __FUNCTION__);
return;
}
tmp->next = srm_saved_configs;
tmp->dev = dev;
pci_save_state(dev, tmp->regs);
srm_saved_configs = tmp;
}
void
pci_restore_srm_config(void)
{
struct pdev_srm_saved_conf *tmp;
/* No need to restore if probed only. */
if (pci_probe_only)
return;
/* Restore SRM config. */
for (tmp = srm_saved_configs; tmp; tmp = tmp->next) {
pci_restore_state(tmp->dev, tmp->regs);
}
}
#endif
void __init
pcibios_fixup_resource(struct resource *res, struct resource *root)
{
......@@ -260,6 +311,8 @@ pcibios_fixup_bus(struct pci_bus *bus)
for (ln = bus->devices.next; ln != &bus->devices; ln = ln->next) {
struct pci_dev *dev = pci_dev_b(ln);
pdev_save_srm_config(dev);
if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI)
pcibios_fixup_device_resources(dev, bus);
}
......@@ -269,8 +322,6 @@ void __init
pcibios_update_irq(struct pci_dev *dev, int irq)
{
pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
/* ??? FIXME -- record old value for shutdown. */
}
/* Most Alphas have straight-forward swizzling needs. */
......@@ -278,20 +329,16 @@ pcibios_update_irq(struct pci_dev *dev, int irq)
u8 __init
common_swizzle(struct pci_dev *dev, u8 *pinp)
{
struct pci_controller *hose = dev->sysdata;
if (dev->bus != hose->bus) {
u8 pin = *pinp;
do {
pin = bridge_swizzle(pin, PCI_SLOT(dev->devfn));
/* Move up the chain of bridges. */
dev = dev->bus->self;
} while (dev->bus->parent);
*pinp = pin;
u8 pin = *pinp;
/* The slot is the slot of the last bridge. */
}
while (dev->bus->parent) {
pin = bridge_swizzle(pin, PCI_SLOT(dev->devfn));
/* Move up the chain of bridges. */
dev = dev->bus->self;
}
*pinp = pin;
/* The slot is the slot of the last bridge. */
return PCI_SLOT(dev->devfn);
}
......
......@@ -147,6 +147,33 @@ struct pci_iommu_arena
unsigned int align_entry;
};
#if defined(CONFIG_ALPHA_SRM) && \
(defined(CONFIG_ALPHA_CIA) || defined(CONFIG_ALPHA_LCA))
# define NEED_SRM_SAVE_RESTORE
#else
# undef NEED_SRM_SAVE_RESTORE
#endif
#if defined(CONFIG_ALPHA_GENERIC) || defined(NEED_SRM_SAVE_RESTORE)
# define ALPHA_RESTORE_SRM_SETUP
#else
# undef ALPHA_RESTORE_SRM_SETUP
#endif
#ifdef ALPHA_RESTORE_SRM_SETUP
/* Store PCI device configuration left by SRM here. */
struct pdev_srm_saved_conf
{
struct pdev_srm_saved_conf *next;
struct pci_dev *dev;
u32 regs[16];
};
extern void pci_restore_srm_config(void);
#else
#define pdev_save_srm_config(dev) do {} while (0)
#define pci_restore_srm_config() do {} while (0)
#endif
/* The hose list. */
extern struct pci_controller *hose_head, **hose_tail;
......
......@@ -129,7 +129,7 @@ common_shutdown_1(void *generic_ptr)
/* This has the effect of resetting the VGA video origin. */
take_over_console(&dummy_con, 0, MAX_NR_CONSOLES-1, 1);
#endif
/* reset_for_srm(); */
pci_restore_srm_config();
set_hae(srm_hae);
}
......
......@@ -110,6 +110,9 @@ extern unsigned long wildfire_node_mem_size(int);
/* setup.c */
extern unsigned long srm_hae;
extern int boot_cpuid;
#ifdef CONFIG_VERBOSE_MCHECK
extern unsigned long alpha_verbose_mcheck;
#endif
/* srmcons.c */
#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_SRM)
......@@ -205,8 +208,6 @@ extern struct mcheck_info
#define mcheck_extra(cpu) ((void)(cpu), __mcheck_info.extra)
#endif
#define DEBUG_MCHECK 0 /* 0 = minimal, 1 = debug, 2 = debug+dump. */
extern void process_mcheck_info(unsigned long vector, unsigned long la_ptr,
struct pt_regs *regs, const char *machine,
int expected);
......@@ -63,6 +63,12 @@ static struct notifier_block alpha_panic_block = {
struct hwrpb_struct *hwrpb;
unsigned long srm_hae;
#ifdef CONFIG_VERBOSE_MCHECK
/* 0=minimum, 1=verbose, 2=all */
/* These can be overridden via the command line, ie "verbose_mcheck=2") */
unsigned long alpha_verbose_mcheck = CONFIG_VERBOSE_MCHECK_ON;
#endif
/* Which processor we booted from. */
int boot_cpuid;
......@@ -538,6 +544,12 @@ setup_arch(char **cmdline_p)
get_mem_size_limit(p+9) << PAGE_SHIFT;
continue;
}
#ifdef CONFIG_VERBOSE_MCHECK
if (strncmp(p, "verbose_mcheck=", 15) == 0) {
alpha_verbose_mcheck = simple_strtol(p+15, NULL, 0);
continue;
}
#endif
}
/* Replace the command line, now that we've killed it with strsep. */
......@@ -597,6 +609,38 @@ setup_arch(char **cmdline_p)
var_name, alpha_mv.vector_name,
(alpha_using_srm ? "SRM" : "MILO"));
printk("Major Options: "
#ifdef CONFIG_SMP
"SMP "
#endif
#ifdef CONFIG_ALPHA_EV56
"EV56 "
#endif
#ifdef CONFIG_ALPHA_EV67
"EV67 "
#endif
#ifdef CONFIG_ALPHA_LEGACY_START_ADDRESS
"LEGACY_START "
#endif
#ifdef CONFIG_VERBOSE_MCHECK
"VERBOSE_MCHECK "
#endif
#ifdef CONFIG_DISCONTIGMEM
"DISCONTIGMEM "
#ifdef CONFIG_NUMA
"NUMA "
#endif
#endif
#ifdef CONFIG_DEBUG_SPINLOCK
"DEBUG_SPINLOCK "
#endif
#ifdef CONFIG_MAGIC_SYSRQ
"MAGIC_SYSRQ "
#endif
"\n");
printk("Command line: %s\n", command_line);
/*
......
......@@ -223,6 +223,7 @@ alcor_kill_arch(int mode)
{
cia_kill_arch(mode);
#ifndef ALPHA_RESTORE_SRM_SETUP
switch(mode) {
case LINUX_REBOOT_CMD_RESTART:
/* Who said DEC engineer's have no sense of humor? ;-) */
......@@ -238,6 +239,29 @@ alcor_kill_arch(int mode)
}
halt();
#endif
}
static void __init
alcor_init_pci(void)
{
struct pci_dev *dev;
cia_init_pci();
/*
* Now we can look to see if we are really running on an XLT-type
* motherboard, by looking for a 21040 TULIP in slot 6, which is
* built into XLT and BRET/MAVERICK, but not available on ALCOR.
*/
dev = pci_find_device(PCI_VENDOR_ID_DEC,
PCI_DEVICE_ID_DEC_TULIP,
NULL);
if (dev && dev->devfn == PCI_DEVFN(6,0)) {
alpha_mv.sys.cia.gru_int_req_bits = XLT_GRU_INT_REQ_BITS;
printk(KERN_INFO "%s: Detected AS500 or XLT motherboard.\n",
__FUNCTION__);
}
}
......@@ -262,7 +286,7 @@ struct alpha_machine_vector alcor_mv __initmv = {
.init_arch = cia_init_arch,
.init_irq = alcor_init_irq,
.init_rtc = common_init_rtc,
.init_pci = cia_init_pci,
.init_pci = alcor_init_pci,
.kill_arch = alcor_kill_arch,
.pci_map_irq = alcor_map_irq,
.pci_swizzle = common_swizzle,
......@@ -290,7 +314,7 @@ struct alpha_machine_vector xlt_mv __initmv = {
.init_arch = cia_init_arch,
.init_irq = alcor_init_irq,
.init_rtc = common_init_rtc,
.init_pci = cia_init_pci,
.init_pci = alcor_init_pci,
.kill_arch = alcor_kill_arch,
.pci_map_irq = alcor_map_irq,
.pci_swizzle = common_swizzle,
......
......@@ -463,7 +463,7 @@ monet_swizzle(struct pci_dev *dev, u8 *pinp)
struct pci_controller *hose = dev->sysdata;
int slot, pin = *pinp;
if (hose->bus == dev->bus) {
if (!dev->bus->parent) {
slot = PCI_SLOT(dev->devfn);
}
/* Check for the built-in bridge on hose 1. */
......
......@@ -240,6 +240,7 @@ miata_kill_arch(int mode)
{
cia_kill_arch(mode);
#ifndef ALPHA_RESTORE_SRM_SETUP
switch(mode) {
case LINUX_REBOOT_CMD_RESTART:
/* Who said DEC engineers have no sense of humor? ;-) */
......@@ -255,6 +256,7 @@ miata_kill_arch(int mode)
}
halt();
#endif
}
......
......@@ -218,7 +218,7 @@ noritake_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{ 16+2, 16+2, 16+3, 32+2, 32+3}, /* IdSel 22, slot 0 */
{ 16+4, 16+4, 16+5, 32+4, 32+5}, /* IdSel 23, slot 1 */
{ 16+6, 16+6, 16+7, 32+6, 32+7}, /* IdSel 24, slot 2 */
{ 16+8, 16+8, 16+9, 32+8, 32+9}, /* IdSel 25, slot 3 */
{ 16+8, 16+8, 16+9, 32+8, 32+9}, /* IdSel 25, slot 3 */
/* The following 5 are actually on PCI bus 1, which is
across the built-in bridge of the NORITAKE only. */
{ 16+1, 16+1, 16+1, 16+1, 16+1}, /* IdSel 16, QLOGIC */
......
......@@ -36,6 +36,14 @@
#include "pci_impl.h"
#include "machvec_impl.h"
#if defined(ALPHA_RESTORE_SRM_SETUP)
/* Save LCA configuration data as the console had it set up. */
struct
{
unsigned int orig_route_tab; /* for SAVE/RESTORE */
} saved_config __attribute((common));
#endif
static void __init
sio_init_irq(void)
......@@ -77,6 +85,15 @@ alphabook1_init_arch(void)
static void __init
sio_pci_route(void)
{
#if defined(ALPHA_RESTORE_SRM_SETUP)
/* First, read and save the original setting. */
pci_bus_read_config_dword(pci_isa_hose->bus, PCI_DEVFN(7, 0), 0x60,
&saved_config.orig_route_tab);
printk("%s: PIRQ original 0x%x new 0x%x\n", __FUNCTION__,
saved_config.orig_route_tab, alpha_mv.sys.sio.route_tab);
#endif
/* Now override with desired setting. */
pci_bus_write_config_dword(pci_isa_hose->bus, PCI_DEVFN(7, 0), 0x60,
alpha_mv.sys.sio.route_tab);
}
......@@ -245,6 +262,21 @@ alphabook1_init_pci(void)
outb(0x0f, 0x3ce); outb(orig, 0x3cf); /* (re)lock PR0-4 */
}
void
sio_kill_arch(int mode)
{
#if defined(ALPHA_RESTORE_SRM_SETUP)
/* Since we cannot read the PCI DMA Window CSRs, we
* cannot restore them here.
*
* However, we CAN read the PIRQ route register, so restore it
* now...
*/
pci_bus_write_config_dword(pci_isa_hose->bus, PCI_DEVFN(7, 0), 0x60,
saved_config.orig_route_tab);
#endif
}
/*
* The System Vectors
......@@ -269,7 +301,7 @@ struct alpha_machine_vector alphabook1_mv __initmv = {
.init_irq = sio_init_irq,
.init_rtc = common_init_rtc,
.init_pci = alphabook1_init_pci,
.kill_arch = NULL,
.kill_arch = sio_kill_arch,
.pci_map_irq = noname_map_irq,
.pci_swizzle = common_swizzle,
......@@ -300,6 +332,7 @@ struct alpha_machine_vector avanti_mv __initmv = {
.init_irq = sio_init_irq,
.init_rtc = common_init_rtc,
.init_pci = noname_init_pci,
.kill_arch = sio_kill_arch,
.pci_map_irq = noname_map_irq,
.pci_swizzle = common_swizzle,
......@@ -329,6 +362,7 @@ struct alpha_machine_vector noname_mv __initmv = {
.init_irq = sio_init_irq,
.init_rtc = common_init_rtc,
.init_pci = noname_init_pci,
.kill_arch = sio_kill_arch,
.pci_map_irq = noname_map_irq,
.pci_swizzle = common_swizzle,
......@@ -367,6 +401,7 @@ struct alpha_machine_vector p2k_mv __initmv = {
.init_irq = sio_init_irq,
.init_rtc = common_init_rtc,
.init_pci = noname_init_pci,
.kill_arch = sio_kill_arch,
.pci_map_irq = p2k_map_irq,
.pci_swizzle = common_swizzle,
......@@ -396,6 +431,7 @@ struct alpha_machine_vector xl_mv __initmv = {
.init_irq = sio_init_irq,
.init_rtc = common_init_rtc,
.init_pci = noname_init_pci,
.kill_arch = sio_kill_arch,
.pci_map_irq = noname_map_irq,
.pci_swizzle = common_swizzle,
......
......@@ -203,6 +203,11 @@ pci_setup_bridge(struct pci_bus *bus)
Enable ISA in either case (FIXME!). */
l = (bus->resource[0]->flags & IORESOURCE_BUS_HAS_VGA) ? 0x0c : 0x04;
pci_write_config_word(bridge, PCI_BRIDGE_CONTROL, l);
/* Make sure the bridge COMMAND register has the appropriate
bits set, just in case...
*/
pcibios_enable_device(bridge, 0xfff);
}
/* Check whether the bridge supports optional I/O and
......
......@@ -42,9 +42,10 @@ pci_update_resource(struct pci_dev *dev, struct resource *res, int resno)
pcibios_resource_to_bus(dev, &region, res);
DBGC((KERN_ERR " got res [%lx:%lx] bus [%lx:%lx] for "
"resource %d of %s\n", res->start, res->end,
region.start, region.end, resno, dev->dev.name));
DBGC((KERN_ERR " got res [%lx:%lx] bus [%lx:%lx] flags %lx for "
"BAR %d of %s\n", res->start, res->end,
region.start, region.end, res->flags,
resno, dev->dev.name));
new = region.start | (res->flags & PCI_REGION_FLAG_MASK);
if (res->flags & IORESOURCE_IO)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment