0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028 #include <linux/kernel.h>
0029 #include <linux/types.h>
0030 #include <linux/mm.h>
0031 #include <linux/sched.h>
0032 #include <linux/pci.h>
0033 #include <linux/init.h>
0034 #include <linux/reboot.h>
0035 #include <linux/memblock.h>
0036 #include <linux/bitops.h>
0037
0038 #include <asm/ptrace.h>
0039 #include <asm/dma.h>
0040 #include <asm/irq.h>
0041 #include <asm/mmu_context.h>
0042 #include <asm/io.h>
0043 #include <asm/core_irongate.h>
0044 #include <asm/hwrpb.h>
0045 #include <asm/tlbflush.h>
0046
0047 #include "proto.h"
0048 #include "err_impl.h"
0049 #include "irq_impl.h"
0050 #include "pci_impl.h"
0051 #include "machvec_impl.h"
0052
0053
0054 static void __init
0055 nautilus_init_irq(void)
0056 {
0057 if (alpha_using_srm) {
0058 alpha_mv.device_interrupt = srm_device_interrupt;
0059 }
0060
0061 init_i8259a_irqs();
0062 common_init_isa_dma();
0063 }
0064
0065 static int
0066 nautilus_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
0067 {
0068
0069
0070 u8 irq;
0071
0072
0073
0074 if (slot == 1 && pin == 2 &&
0075 dev->bus->self && dev->bus->self->device == 0x700f)
0076 return 5;
0077 pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq);
0078 return irq;
0079 }
0080
0081 void
0082 nautilus_kill_arch(int mode)
0083 {
0084 struct pci_bus *bus = pci_isa_hose->bus;
0085 u32 pmuport;
0086 int off;
0087
0088 switch (mode) {
0089 case LINUX_REBOOT_CMD_RESTART:
0090 if (! alpha_using_srm) {
0091 u8 t8;
0092 pci_bus_read_config_byte(bus, 0x38, 0x43, &t8);
0093 pci_bus_write_config_byte(bus, 0x38, 0x43, t8 | 0x80);
0094 outb(1, 0x92);
0095 outb(0, 0x92);
0096
0097 }
0098 break;
0099
0100 case LINUX_REBOOT_CMD_POWER_OFF:
0101
0102 off = 0x2000;
0103 pci_bus_read_config_dword(bus, 0x88, 0x10, &pmuport);
0104 if (!pmuport) {
0105
0106 off = 0x3400;
0107 pci_bus_read_config_dword(bus, 0x88, 0xe0, &pmuport);
0108 }
0109 pmuport &= 0xfffe;
0110 outw(0xffff, pmuport);
0111 outw(off, pmuport + 4);
0112
0113 break;
0114 }
0115 }
0116
0117
0118
0119 static void
0120 naut_sys_machine_check(unsigned long vector, unsigned long la_ptr,
0121 struct pt_regs *regs)
0122 {
0123 printk("PC %lx RA %lx\n", regs->pc, regs->r26);
0124 irongate_pci_clr_err();
0125 }
0126
0127
0128
0129
0130 void
0131 nautilus_machine_check(unsigned long vector, unsigned long la_ptr)
0132 {
0133 char *mchk_class;
0134
0135
0136
0137
0138
0139 if (vector == SCB_Q_SYSMCHK
0140 && ((IRONGATE0->dramms & 0x300) == 0x300)) {
0141 unsigned long nmi_ctl;
0142
0143
0144 nmi_ctl = inb(0x61);
0145 nmi_ctl |= 0x0c;
0146 outb(nmi_ctl, 0x61);
0147 nmi_ctl &= ~0x0c;
0148 outb(nmi_ctl, 0x61);
0149
0150
0151 IRONGATE0->stat_cmd = IRONGATE0->stat_cmd & ~0x100;
0152 mb();
0153 IRONGATE0->stat_cmd;
0154
0155
0156 IRONGATE0->dramms = IRONGATE0->dramms;
0157 mb();
0158 IRONGATE0->dramms;
0159
0160 draina();
0161 wrmces(0x7);
0162 mb();
0163 return;
0164 }
0165
0166 if (vector == SCB_Q_SYSERR)
0167 mchk_class = "Correctable";
0168 else if (vector == SCB_Q_SYSMCHK)
0169 mchk_class = "Fatal";
0170 else {
0171 ev6_machine_check(vector, la_ptr);
0172 return;
0173 }
0174
0175 printk(KERN_CRIT "NAUTILUS Machine check 0x%lx "
0176 "[%s System Machine Check (NMI)]\n",
0177 vector, mchk_class);
0178
0179 naut_sys_machine_check(vector, la_ptr, get_irq_regs());
0180
0181
0182 draina();
0183 wrmces(0x7);
0184 mb();
0185 }
0186
0187 extern void pcibios_claim_one_bus(struct pci_bus *);
0188
0189 static struct resource irongate_mem = {
0190 .name = "Irongate PCI MEM",
0191 .flags = IORESOURCE_MEM,
0192 };
0193 static struct resource busn_resource = {
0194 .name = "PCI busn",
0195 .start = 0,
0196 .end = 255,
0197 .flags = IORESOURCE_BUS,
0198 };
0199
0200 void __init
0201 nautilus_init_pci(void)
0202 {
0203 struct pci_controller *hose = hose_head;
0204 struct pci_host_bridge *bridge;
0205 struct pci_bus *bus;
0206 unsigned long bus_align, bus_size, pci_mem;
0207 unsigned long memtop = max_low_pfn << PAGE_SHIFT;
0208
0209 bridge = pci_alloc_host_bridge(0);
0210 if (!bridge)
0211 return;
0212
0213
0214 pci_add_resource(&bridge->windows, &ioport_resource);
0215
0216
0217 pci_add_resource(&bridge->windows, &irongate_mem);
0218
0219 pci_add_resource(&bridge->windows, &busn_resource);
0220 bridge->dev.parent = NULL;
0221 bridge->sysdata = hose;
0222 bridge->busnr = 0;
0223 bridge->ops = alpha_mv.pci_ops;
0224 bridge->swizzle_irq = alpha_mv.pci_swizzle;
0225 bridge->map_irq = alpha_mv.pci_map_irq;
0226 bridge->size_windows = 1;
0227
0228
0229 if (pci_scan_root_bus_bridge(bridge)) {
0230 pci_free_host_bridge(bridge);
0231 return;
0232 }
0233 bus = hose->bus = bridge->bus;
0234 pcibios_claim_one_bus(bus);
0235
0236 pci_bus_size_bridges(bus);
0237
0238
0239
0240
0241 bus_align = irongate_mem.start;
0242 bus_size = irongate_mem.end + 1 - bus_align;
0243 if (bus_align < 0x1000000UL)
0244 bus_align = 0x1000000UL;
0245
0246 pci_mem = (0x100000000UL - bus_size) & -bus_align;
0247 irongate_mem.start = pci_mem;
0248 irongate_mem.end = 0xffffffffUL;
0249
0250
0251
0252 if (request_resource(&iomem_resource, &irongate_mem) < 0)
0253 printk(KERN_ERR "Failed to request MEM on hose 0\n");
0254
0255 printk(KERN_INFO "Irongate pci_mem %pR\n", &irongate_mem);
0256
0257 if (pci_mem < memtop)
0258 memtop = pci_mem;
0259 if (memtop > alpha_mv.min_mem_address) {
0260 free_reserved_area(__va(alpha_mv.min_mem_address),
0261 __va(memtop), -1, NULL);
0262 printk(KERN_INFO "nautilus_init_pci: %ldk freed\n",
0263 (memtop - alpha_mv.min_mem_address) >> 10);
0264 }
0265 if ((IRONGATE0->dev_vendor >> 16) > 0x7006)
0266 IRONGATE0->pci_mem = pci_mem;
0267
0268 pci_bus_assign_resources(bus);
0269 pci_bus_add_devices(bus);
0270 }
0271
0272
0273
0274
0275
0276 struct alpha_machine_vector nautilus_mv __initmv = {
0277 .vector_name = "Nautilus",
0278 DO_EV6_MMU,
0279 DO_DEFAULT_RTC,
0280 DO_IRONGATE_IO,
0281 .machine_check = nautilus_machine_check,
0282 .max_isa_dma_address = ALPHA_MAX_ISA_DMA_ADDRESS,
0283 .min_io_address = DEFAULT_IO_BASE,
0284 .min_mem_address = IRONGATE_DEFAULT_MEM_BASE,
0285
0286 .nr_irqs = 16,
0287 .device_interrupt = isa_device_interrupt,
0288
0289 .init_arch = irongate_init_arch,
0290 .init_irq = nautilus_init_irq,
0291 .init_rtc = common_init_rtc,
0292 .init_pci = nautilus_init_pci,
0293 .kill_arch = nautilus_kill_arch,
0294 .pci_map_irq = nautilus_map_irq,
0295 .pci_swizzle = common_swizzle,
0296 };
0297 ALIAS_MV(nautilus)