summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@home.transmeta.com>2003-02-04 18:24:02 -0800
committerLinus Torvalds <torvalds@home.transmeta.com>2003-02-04 18:24:02 -0800
commitcf5ba9c8989c8451afd1364e46168c180efee124 (patch)
tree84473f2573ae65122ab6a3bc8fb81bb4346b568a
parentc4fbc32d25f905b1ef78f913a5ac84bfd12ce26a (diff)
parent35231647d2ef533fe0e0f8fa0aae5fe223332af5 (diff)
Merge bk://are.twiddle.net/axp-2.5
into home.transmeta.com:/home/torvalds/v2.5/linux
-rw-r--r--arch/alpha/Kconfig5
-rw-r--r--arch/alpha/kernel/Makefile5
-rw-r--r--arch/alpha/kernel/alpha_ksyms.c5
-rw-r--r--arch/alpha/kernel/core_irongate.c330
-rw-r--r--arch/alpha/kernel/core_marvel.c22
-rw-r--r--arch/alpha/kernel/core_titan.c7
-rw-r--r--arch/alpha/kernel/irq.c2
-rw-r--r--arch/alpha/kernel/pci_impl.h4
-rw-r--r--arch/alpha/kernel/process.c79
-rw-r--r--arch/alpha/kernel/proto.h9
-rw-r--r--arch/alpha/kernel/ptrace.c4
-rw-r--r--arch/alpha/kernel/setup.c95
-rw-r--r--arch/alpha/kernel/smp.c7
-rw-r--r--arch/alpha/kernel/srmcons.c361
-rw-r--r--arch/alpha/kernel/sys_nautilus.c69
-rw-r--r--arch/alpha/kernel/time.c15
-rw-r--r--include/asm-alpha/core_irongate.h11
-rw-r--r--include/asm-alpha/elf.h66
-rw-r--r--include/asm-alpha/topology.h3
19 files changed, 695 insertions, 404 deletions
diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig
index f8a3ad80f5cc..66049f3804e4 100644
--- a/arch/alpha/Kconfig
+++ b/arch/alpha/Kconfig
@@ -458,6 +458,11 @@ config ALPHA_SRM
If unsure, say N.
+config EARLY_PRINTK
+ bool
+ depends on ALPHA_GENERIC || ALPHA_SRM
+ default y
+
config ALPHA_EISA
bool
depends on ALPHA_ALCOR || ALPHA_MIKASA || ALPHA_SABLE || ALPHA_NORITAKE || ALPHA_RAWHIDE
diff --git a/arch/alpha/kernel/Makefile b/arch/alpha/kernel/Makefile
index 8f3eeba5160b..73ee17261de8 100644
--- a/arch/alpha/kernel/Makefile
+++ b/arch/alpha/kernel/Makefile
@@ -33,8 +33,13 @@ obj-y += err_titan.o err_marvel.o
obj-y += es1888.o smc37c669.o smc37c93x.o ns87312.o gct.o
+obj-y += srmcons.o
+
else
+# Misc support
+obj-$(CONFIG_ALPHA_SRM) += srmcons.o
+
# Core logic support
obj-$(CONFIG_ALPHA_APECS) += core_apecs.o
obj-$(CONFIG_ALPHA_CIA) += core_cia.o
diff --git a/arch/alpha/kernel/alpha_ksyms.c b/arch/alpha/kernel/alpha_ksyms.c
index 0689cfcca9d3..ec9ed49c79fe 100644
--- a/arch/alpha/kernel/alpha_ksyms.c
+++ b/arch/alpha/kernel/alpha_ksyms.c
@@ -40,7 +40,6 @@
extern struct hwrpb_struct *hwrpb;
extern void dump_thread(struct pt_regs *, struct user *);
-extern int dump_fpu(struct pt_regs *, elf_fpregset_t *);
extern spinlock_t rtc_lock;
/* these are C runtime functions with special calling conventions: */
@@ -144,7 +143,9 @@ EXPORT_SYMBOL(pci_dac_dma_to_offset);
#endif
EXPORT_SYMBOL(dump_thread);
-EXPORT_SYMBOL(dump_fpu);
+EXPORT_SYMBOL(dump_elf_thread);
+EXPORT_SYMBOL(dump_elf_task);
+EXPORT_SYMBOL(dump_elf_task_fp);
EXPORT_SYMBOL(hwrpb);
EXPORT_SYMBOL(start_thread);
EXPORT_SYMBOL(alpha_read_fp_reg);
diff --git a/arch/alpha/kernel/core_irongate.c b/arch/alpha/kernel/core_irongate.c
index 1709838729a6..4aabddb49485 100644
--- a/arch/alpha/kernel/core_irongate.c
+++ b/arch/alpha/kernel/core_irongate.c
@@ -27,13 +27,11 @@
#include <asm/core_irongate.h>
#undef __EXTERN_INLINE
+#include <linux/bootmem.h>
+
#include "proto.h"
#include "pci_impl.h"
-#undef DEBUG_IRONGATE /* define to enable verbose Irongate debug */
-
-#define IRONGATE_DEFAULT_AGP_APER_SIZE (256*1024*1024) /* 256MB */
-
/*
* BIOS32-style PCI interface:
*/
@@ -46,6 +44,7 @@
# define DBG_CFG(args)
#endif
+igcsr32 *IronECC;
/*
* Given a bus, device, and function number, compute resulting
@@ -165,143 +164,6 @@ struct pci_ops irongate_pci_ops =
.write = irongate_write_config,
};
-#ifdef DEBUG_IRONGATE
-static void
-irongate_register_dump(const char *function_name)
-{
- printk("%s: Irongate registers:\n"
- "\tFunction 0:\n"
- "\tdev_vendor\t0x%08x\n"
- "\tstat_cmd\t0x%08x\n"
- "\tclass\t\t0x%08x\n"
- "\tlatency\t\t0x%08x\n"
- "\tbar0\t\t0x%08x\n"
- "\tbar1\t\t0x%08x\n"
- "\tbar2\t\t0x%08x\n"
- "\trsrvd0[0]\t0x%08x\n"
- "\trsrvd0[1]\t0x%08x\n"
- "\trsrvd0[2]\t0x%08x\n"
- "\trsrvd0[3]\t0x%08x\n"
- "\trsrvd0[4]\t0x%08x\n"
- "\trsrvd0[5]\t0x%08x\n"
- "\tcapptr\t\t0x%08x\n"
- "\trsrvd1[0]\t0x%08x\n"
- "\trsrvd1[1]\t0x%08x\n"
- "\tbacsr10\t\t0x%08x\n"
- "\tbacsr32\t\t0x%08x\n"
- "\tbacsr54\t\t0x%08x\n"
- "\trsrvd2[0]\t0x%08x\n"
- "\tdrammap\t\t0x%08x\n"
- "\tdramtm\t\t0x%08x\n"
- "\tdramms\t\t0x%08x\n"
- "\trsrvd3[0]\t0x%08x\n"
- "\tbiu0\t\t0x%08x\n"
- "\tbiusip\t\t0x%08x\n"
- "\trsrvd4[0]\t0x%08x\n"
- "\trsrvd4[1]\t0x%08x\n"
- "\tmro\t\t0x%08x\n"
- "\trsrvd5[0]\t0x%08x\n"
- "\trsrvd5[1]\t0x%08x\n"
- "\trsrvd5[2]\t0x%08x\n"
- "\twhami\t\t0x%08x\n"
- "\tpciarb\t\t0x%08x\n"
- "\tpcicfg\t\t0x%08x\n"
- "\trsrvd6[0]\t0x%08x\n"
- "\trsrvd6[1]\t0x%08x\n"
- "\trsrvd6[2]\t0x%08x\n"
- "\trsrvd6[3]\t0x%08x\n"
- "\trsrvd6[4]\t0x%08x\n"
- "\tagpcap\t\t0x%08x\n"
- "\tagpstat\t\t0x%08x\n"
- "\tagpcmd\t\t0x%08x\n"
- "\tagpva\t\t0x%08x\n"
- "\tagpmode\t\t0x%08x\n"
-
- "\n\tFunction 1:\n"
- "\tdev_vendor:\t0x%08x\n"
- "\tcmd_status:\t0x%08x\n"
- "\trevid_etc :\t0x%08x\n"
- "\thtype_etc :\t0x%08x\n"
- "\trsrvd0[0] :\t0x%08x\n"
- "\trsrvd0[1] :\t0x%08x\n"
- "\tbus_nmbers:\t0x%08x\n"
- "\tio_baselim:\t0x%08x\n"
- "\tmem_bselim:\t0x%08x\n"
- "\tpf_baselib:\t0x%08x\n"
- "\trsrvd1[0] :\t0x%08x\n"
- "\trsrvd1[1] :\t0x%08x\n"
- "\tio_baselim:\t0x%08x\n"
- "\trsrvd2[0] :\t0x%08x\n"
- "\trsrvd2[1] :\t0x%08x\n"
- "\tinterrupt :\t0x%08x\n",
-
- function_name,
- IRONGATE0->dev_vendor,
- IRONGATE0->stat_cmd,
- IRONGATE0->class,
- IRONGATE0->latency,
- IRONGATE0->bar0,
- IRONGATE0->bar1,
- IRONGATE0->bar2,
- IRONGATE0->rsrvd0[0],
- IRONGATE0->rsrvd0[1],
- IRONGATE0->rsrvd0[2],
- IRONGATE0->rsrvd0[3],
- IRONGATE0->rsrvd0[4],
- IRONGATE0->rsrvd0[5],
- IRONGATE0->capptr,
- IRONGATE0->rsrvd1[0],
- IRONGATE0->rsrvd1[1],
- IRONGATE0->bacsr10,
- IRONGATE0->bacsr32,
- IRONGATE0->bacsr54,
- IRONGATE0->rsrvd2[0],
- IRONGATE0->drammap,
- IRONGATE0->dramtm,
- IRONGATE0->dramms,
- IRONGATE0->rsrvd3[0],
- IRONGATE0->biu0,
- IRONGATE0->biusip,
- IRONGATE0->rsrvd4[0],
- IRONGATE0->rsrvd4[1],
- IRONGATE0->mro,
- IRONGATE0->rsrvd5[0],
- IRONGATE0->rsrvd5[1],
- IRONGATE0->rsrvd5[2],
- IRONGATE0->whami,
- IRONGATE0->pciarb,
- IRONGATE0->pcicfg,
- IRONGATE0->rsrvd6[0],
- IRONGATE0->rsrvd6[1],
- IRONGATE0->rsrvd6[2],
- IRONGATE0->rsrvd6[3],
- IRONGATE0->rsrvd6[4],
- IRONGATE0->agpcap,
- IRONGATE0->agpstat,
- IRONGATE0->agpcmd,
- IRONGATE0->agpva,
- IRONGATE0->agpmode,
- IRONGATE1->dev_vendor,
- IRONGATE1->stat_cmd,
- IRONGATE1->class,
- IRONGATE1->htype,
- IRONGATE1->rsrvd0[0],
- IRONGATE1->rsrvd0[1],
- IRONGATE1->busnos,
- IRONGATE1->io_baselim_regs,
- IRONGATE1->mem_baselim,
- IRONGATE1->pfmem_baselim,
- IRONGATE1->rsrvd1[0],
- IRONGATE1->rsrvd1[1],
- IRONGATE1->io_baselim,
- IRONGATE1->rsrvd2[0],
- IRONGATE1->rsrvd2[1],
- IRONGATE1->interrupt );
-}
-#else
-#define irongate_register_dump(x)
-#endif
-
int
irongate_pci_clr_err(void)
{
@@ -315,11 +177,11 @@ again:
mb();
IRONGATE_jd = IRONGATE0->stat_cmd; /* re-read to force write */
- IRONGATE_jd = IRONGATE0->dramms;
- printk("Iron dramms %x\n", IRONGATE_jd);
- IRONGATE0->dramms = IRONGATE_jd; /* write again clears error bits */
+ IRONGATE_jd = *IronECC;
+ printk("Iron ECC %x\n", IRONGATE_jd);
+ *IronECC = IRONGATE_jd; /* write again clears error bits */
mb();
- IRONGATE_jd = IRONGATE0->dramms; /* re-read to force write */
+ IRONGATE_jd = *IronECC; /* re-read to force write */
/* Clear ALI NMI */
nmi_ctl = inb(0x61);
@@ -328,28 +190,88 @@ again:
nmi_ctl &= ~0x0c;
outb(nmi_ctl, 0x61);
- IRONGATE_jd = IRONGATE0->dramms;
+ IRONGATE_jd = *IronECC;
if (IRONGATE_jd & 0x300) goto again;
return 0;
}
+#define IRONGATE_3GB 0xc0000000UL
+
+/* On Albacore (aka UP1500) with 4Gb of RAM we have to reserve some
+ memory for PCI. At this point we just reserve memory above 3Gb. Most
+ of this memory will be freed after PCI setup is done. */
+static void __init
+albacore_init_arch(void)
+{
+ unsigned long memtop = max_low_pfn << PAGE_SHIFT;
+ unsigned long pci_mem = (memtop + 0x1000000UL) & ~0xffffffUL;
+ struct percpu_struct *cpu;
+ int pal_rev, pal_var;
+
+ cpu = (struct percpu_struct*)((char*)hwrpb + hwrpb->processor_offset);
+ pal_rev = cpu->pal_revision & 0xffff;
+ pal_var = (cpu->pal_revision >> 16) & 0xff;
+
+ /* Consoles earlier than A5.6-18 (OSF PALcode v1.62-2) set up
+ the CPU incorrectly (leave speculative stores enabled),
+ which causes memory corruption under certain conditions.
+ Issue a warning for such consoles. */
+ if (alpha_using_srm &&
+ (pal_rev < 0x13e || (pal_rev == 0x13e && pal_var < 2)))
+ printk(KERN_WARNING "WARNING! Upgrade to SRM A5.6-19 "
+ "or later\n");
+
+ if (pci_mem > IRONGATE_3GB)
+ pci_mem = IRONGATE_3GB;
+ IRONGATE0->pci_mem = pci_mem;
+ alpha_mv.min_mem_address = pci_mem;
+ if (memtop > pci_mem) {
+#ifdef CONFIG_BLK_DEV_INITRD
+ extern unsigned long initrd_start, initrd_end;
+ extern void *move_initrd(unsigned long);
+
+ /* Move the initrd out of the way. */
+ if (initrd_end && __pa(initrd_end) > pci_mem) {
+ unsigned long size;
+
+ size = initrd_end - initrd_start;
+ free_bootmem(__pa(initrd_start), PAGE_ALIGN(size));
+ if (!move_initrd(pci_mem))
+ printk("irongate_init_arch: initrd too big "
+ "(%ldK)\ndisabling initrd\n",
+ size / 1024);
+ }
+#endif
+ reserve_bootmem(pci_mem, memtop - pci_mem);
+ printk("irongate_init_arch: temporarily reserving "
+ "region %08lx-%08lx for PCI\n", pci_mem, memtop - 1);
+ }
+}
+
+static void __init
+irongate_setup_agp(void)
+{
+ /* Disable the GART window. AGPGART doesn't work due to yet
+ unresolved memory coherency issues... */
+ IRONGATE0->agpva = IRONGATE0->agpva & ~0xf;
+ alpha_agpgart_size = 0;
+}
+
void __init
irongate_init_arch(void)
{
struct pci_controller *hose;
+ int amd761 = (IRONGATE0->dev_vendor >> 16) > 0x7006; /* Albacore? */
+
+ IronECC = amd761 ? &IRONGATE0->bacsr54_eccms761 : &IRONGATE0->dramms;
- IRONGATE0->stat_cmd = IRONGATE0->stat_cmd & ~0x100;
irongate_pci_clr_err();
- irongate_register_dump(__FUNCTION__);
- /*
- * HACK: set AGP aperture size to 256MB.
- * This should really be changed during PCI probe, when the
- * size of the aperture the AGP card wants is known.
- */
- printk("irongate_init_arch: AGPVA was 0x%x\n", IRONGATE0->agpva);
- IRONGATE0->agpva = (IRONGATE0->agpva & ~0x0000000f) | 0x00000007;
+ if (amd761)
+ albacore_init_arch();
+
+ irongate_setup_agp();
/*
* Create our single hose.
@@ -380,89 +302,9 @@ irongate_init_arch(void)
* IO map and AGP support
*/
#include <linux/vmalloc.h>
-#include <asm/pgalloc.h>
-
-static inline void
-irongate_remap_area_pte(pte_t * pte, unsigned long address, unsigned long size,
- unsigned long phys_addr, unsigned long flags)
-{
- unsigned long end;
- unsigned long pfn;
-
- address &= ~PMD_MASK;
- end = address + size;
- if (end > PMD_SIZE)
- end = PMD_SIZE;
- if (address >= end)
- BUG();
- pfn = phys_addr >> PAGE_SHIFT;
- do {
- if (!pte_none(*pte)) {
- printk("irongate_remap_area_pte: page already exists\n");
- BUG();
- }
- set_pte(pte, pfn_pte(pfn,
- __pgprot(_PAGE_VALID | _PAGE_ASM |
- _PAGE_KRE | _PAGE_KWE | flags)));
- address += PAGE_SIZE;
- pfn++;
- pte++;
- } while (address && (address < end));
-}
-
-static inline int
-irongate_remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size,
- unsigned long phys_addr, unsigned long flags)
-{
- unsigned long end;
-
- address &= ~PGDIR_MASK;
- end = address + size;
- if (end > PGDIR_SIZE)
- end = PGDIR_SIZE;
- phys_addr -= address;
- if (address >= end)
- BUG();
- do {
- pte_t * pte = pte_alloc_kernel(&init_mm, pmd, address);
- if (!pte)
- return -ENOMEM;
- irongate_remap_area_pte(pte, address, end - address,
- address + phys_addr, flags);
- address = (address + PMD_SIZE) & PMD_MASK;
- pmd++;
- } while (address && (address < end));
- return 0;
-}
-
-static int
-irongate_remap_area_pages(unsigned long address, unsigned long phys_addr,
- unsigned long size, unsigned long flags)
-{
- pgd_t * dir;
- unsigned long end = address + size;
-
- phys_addr -= address;
- dir = pgd_offset(&init_mm, address);
- flush_cache_all();
- if (address >= end)
- BUG();
- do {
- pmd_t *pmd;
- pmd = pmd_alloc(&init_mm, dir, address);
- if (!pmd)
- return -ENOMEM;
- if (irongate_remap_area_pmd(pmd, address, end - address,
- phys_addr + address, flags))
- return -ENOMEM;
- address = (address + PGDIR_SIZE) & PGDIR_MASK;
- dir++;
- } while (address && (address < end));
- return 0;
-}
-
#include <linux/agp_backend.h>
#include <linux/agpgart.h>
+#include <asm/pgalloc.h>
#define GET_PAGE_DIR_OFF(addr) (addr >> 22)
#define GET_PAGE_DIR_IDX(addr) (GET_PAGE_DIR_OFF(addr))
@@ -477,15 +319,13 @@ irongate_ioremap(unsigned long addr, unsigned long size)
unsigned long vaddr;
unsigned long baddr, last;
u32 *mmio_regs, *gatt_pages, *cur_gatt, pte;
- unsigned long gart_bus_addr, gart_aper_size;
+ unsigned long gart_bus_addr;
- gart_bus_addr = (unsigned long)IRONGATE0->bar0 &
- PCI_BASE_ADDRESS_MEM_MASK;
-
- if (!gart_bus_addr) /* FIXME - there must be a better way!!! */
+ if (!alpha_agpgart_size)
return addr + IRONGATE_MEM;
- gart_aper_size = IRONGATE_DEFAULT_AGP_APER_SIZE; /* FIXME */
+ gart_bus_addr = (unsigned long)IRONGATE0->bar0 &
+ PCI_BASE_ADDRESS_MEM_MASK;
/*
* Check for within the AGP aperture...
@@ -495,7 +335,7 @@ irongate_ioremap(unsigned long addr, unsigned long size)
* Check the AGP area
*/
if (addr >= gart_bus_addr && addr + size - 1 <
- gart_bus_addr + gart_aper_size)
+ gart_bus_addr + alpha_agpgart_size)
break;
/*
@@ -549,8 +389,8 @@ irongate_ioremap(unsigned long addr, unsigned long size)
cur_gatt = phys_to_virt(GET_GATT(baddr) & ~1);
pte = cur_gatt[GET_GATT_OFF(baddr)] & ~1;
- if (irongate_remap_area_pages(VMALLOC_VMADDR(vaddr),
- pte, PAGE_SIZE, 0)) {
+ if (__alpha_remap_area_pages(VMALLOC_VMADDR(vaddr),
+ pte, PAGE_SIZE, 0)) {
printk("AGP ioremap: FAILED to map...\n");
vfree(area->addr);
return (unsigned long)NULL;
diff --git a/arch/alpha/kernel/core_marvel.c b/arch/alpha/kernel/core_marvel.c
index 075ed7631122..0ecfee1a2ddd 100644
--- a/arch/alpha/kernel/core_marvel.c
+++ b/arch/alpha/kernel/core_marvel.c
@@ -732,21 +732,6 @@ marvel_iounmap(unsigned long addr)
EXPORT_SYMBOL(marvel_ioremap);
EXPORT_SYMBOL(marvel_iounmap);
#endif
-
-/*
- * SRMCons support
- *
- * Marvel doesn't have a real serial console -- it's either graphics or
- * server management based. If we're running on the server management based
- * console, allow the srmcons callback driver to be a console device.
- */
-int
-marvel_srmcons_allowed(void)
-{
- u64 *pu64 = (u64 *)((u64)hwrpb + hwrpb->ctbt_offset);
-
- return (pu64[7] == 2);
-}
/*
@@ -874,8 +859,6 @@ marvel_node_mem_size(int nid)
#include <linux/slab.h>
#include <linux/delay.h>
-#define MARVEL_AGP_APER_SIZE (64 * 1024 * 1024)
-
struct marvel_agp_aperture {
struct pci_iommu_arena *arena;
long pg_start;
@@ -887,11 +870,14 @@ marvel_agp_setup(alpha_agp_info *agp)
{
struct marvel_agp_aperture *aper;
+ if (!alpha_agpgart_size)
+ return -ENOMEM;
+
aper = kmalloc(sizeof(*aper), GFP_KERNEL);
if (aper == NULL) return -ENOMEM;
aper->arena = agp->hose->sg_pci;
- aper->pg_count = MARVEL_AGP_APER_SIZE / PAGE_SIZE;
+ aper->pg_count = alpha_agpgart_size / PAGE_SIZE;
aper->pg_start = iommu_reserve(aper->arena, aper->pg_count,
aper->pg_count - 1);
diff --git a/arch/alpha/kernel/core_titan.c b/arch/alpha/kernel/core_titan.c
index d5619bbc4add..f16036455fa9 100644
--- a/arch/alpha/kernel/core_titan.c
+++ b/arch/alpha/kernel/core_titan.c
@@ -580,8 +580,6 @@ EXPORT_SYMBOL(titan_iounmap);
#include <linux/slab.h>
#include <linux/delay.h>
-#define TITAN_AGP_APER_SIZE (64 * 1024 * 1024)
-
struct titan_agp_aperture {
struct pci_iommu_arena *arena;
long pg_start;
@@ -593,12 +591,15 @@ titan_agp_setup(alpha_agp_info *agp)
{
struct titan_agp_aperture *aper;
+ if (!alpha_agpgart_size)
+ return -ENOMEM;
+
aper = kmalloc(sizeof(struct titan_agp_aperture), GFP_KERNEL);
if (aper == NULL)
return -ENOMEM;
aper->arena = agp->hose->sg_pci;
- aper->pg_count = TITAN_AGP_APER_SIZE / PAGE_SIZE;
+ aper->pg_count = alpha_agpgart_size / PAGE_SIZE;
aper->pg_start = iommu_reserve(aper->arena, aper->pg_count,
aper->pg_count - 1);
if (aper->pg_start < 0) {
diff --git a/arch/alpha/kernel/irq.c b/arch/alpha/kernel/irq.c
index cd9d6454c6d2..b10ae89943dd 100644
--- a/arch/alpha/kernel/irq.c
+++ b/arch/alpha/kernel/irq.c
@@ -534,7 +534,7 @@ show_interrupts(struct seq_file *p, void *v)
#else
for (j = 0; j < NR_CPUS; j++)
if (cpu_online(j))
- seq_printf(p, "%10u ", kstat_cpu(i).irqs[j]);
+ seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
#endif
seq_printf(p, " %14s", irq_desc[i].handler->typename);
seq_printf(p, " %c%s",
diff --git a/arch/alpha/kernel/pci_impl.h b/arch/alpha/kernel/pci_impl.h
index eadf77848709..68448627b226 100644
--- a/arch/alpha/kernel/pci_impl.h
+++ b/arch/alpha/kernel/pci_impl.h
@@ -71,6 +71,8 @@ struct pci_iommu_arena;
#define IRONGATE_DEFAULT_MEM_BASE ((256*8-16)*1024*1024)
+#define DEFAULT_AGP_APER_SIZE (64*1024*1024)
+
/*
* A small note about bridges and interrupts. The DECchip 21050 (and
* later) adheres to the PCI-PCI bridge specification. This says that
@@ -153,6 +155,8 @@ extern struct pci_controller *pci_isa_hose;
/* Indicate that we trust the console to configure things properly. */
extern int pci_probe_only;
+extern unsigned long alpha_agpgart_size;
+
extern void common_init_pci(void);
extern u8 common_swizzle(struct pci_dev *, u8 *);
extern struct pci_controller *alloc_pci_controller(void);
diff --git a/arch/alpha/kernel/process.c b/arch/alpha/kernel/process.c
index 196a016657ed..85b45eee2868 100644
--- a/arch/alpha/kernel/process.c
+++ b/arch/alpha/kernel/process.c
@@ -313,7 +313,7 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
}
/*
- * fill in the user structure for a core dump..
+ * Fill in the user structure for an ECOFF core dump.
*/
void
dump_thread(struct pt_regs * pt, struct user * dump)
@@ -373,12 +373,81 @@ dump_thread(struct pt_regs * pt, struct user * dump)
memcpy((char *)dump->regs + EF_SIZE, sw->fp, 32 * 8);
}
-int
-dump_fpu(struct pt_regs * regs, elf_fpregset_t *r)
+/*
+ * Fill in the user structure for a ELF core dump.
+ */
+void
+dump_elf_thread(elf_greg_t *dest, struct pt_regs *pt, struct thread_info *ti)
{
/* switch stack follows right below pt_regs: */
- struct switch_stack * sw = ((struct switch_stack *) regs) - 1;
- memcpy(r, sw->fp, 32 * 8);
+ struct switch_stack * sw = ((struct switch_stack *) pt) - 1;
+
+ dest[ 0] = pt->r0;
+ dest[ 1] = pt->r1;
+ dest[ 2] = pt->r2;
+ dest[ 3] = pt->r3;
+ dest[ 4] = pt->r4;
+ dest[ 5] = pt->r5;
+ dest[ 6] = pt->r6;
+ dest[ 7] = pt->r7;
+ dest[ 8] = pt->r8;
+ dest[ 9] = sw->r9;
+ dest[10] = sw->r10;
+ dest[11] = sw->r11;
+ dest[12] = sw->r12;
+ dest[13] = sw->r13;
+ dest[14] = sw->r14;
+ dest[15] = sw->r15;
+ dest[16] = pt->r16;
+ dest[17] = pt->r17;
+ dest[18] = pt->r18;
+ dest[19] = pt->r19;
+ dest[20] = pt->r20;
+ dest[21] = pt->r21;
+ dest[22] = pt->r22;
+ dest[23] = pt->r23;
+ dest[24] = pt->r24;
+ dest[25] = pt->r25;
+ dest[26] = pt->r26;
+ dest[27] = pt->r27;
+ dest[28] = pt->r28;
+ dest[29] = pt->gp;
+ dest[30] = rdusp();
+ dest[31] = pt->pc;
+
+ /* Once upon a time this was the PS value. Which is stupid
+ since that is always 8 for usermode. Usurped for the more
+ useful value of the thread's UNIQUE field. */
+ dest[32] = ti->pcb.unique;
+}
+
+int
+dump_elf_task(elf_greg_t *dest, struct task_struct *task)
+{
+ struct thread_info *ti;
+ struct pt_regs *pt;
+
+ ti = task->thread_info;
+ pt = (struct pt_regs *)((unsigned long)ti + 2*PAGE_SIZE) - 1;
+
+ dump_elf_thread(dest, pt, ti);
+
+ return 1;
+}
+
+int
+dump_elf_task_fp(elf_fpreg_t *dest, struct task_struct *task)
+{
+ struct thread_info *ti;
+ struct pt_regs *pt;
+ struct switch_stack *sw;
+
+ ti = task->thread_info;
+ pt = (struct pt_regs *)((unsigned long)ti + 2*PAGE_SIZE) - 1;
+ sw = (struct switch_stack *)pt - 1;
+
+ memcpy(dest, sw->fp, 32 * 8);
+
return 1;
}
diff --git a/arch/alpha/kernel/proto.h b/arch/alpha/kernel/proto.h
index bb0adcbcb317..d67cf07ffdec 100644
--- a/arch/alpha/kernel/proto.h
+++ b/arch/alpha/kernel/proto.h
@@ -53,7 +53,6 @@ extern int marvel_pa_to_nid(unsigned long);
extern int marvel_cpuid_to_nid(int);
extern unsigned long marvel_node_mem_start(int);
extern unsigned long marvel_node_mem_size(int);
-extern int marvel_srmcons_allowed(void);
extern struct _alpha_agp_info *marvel_agp_info(void);
struct io7 *marvel_find_io7(int pe);
struct io7 *marvel_next_io7(struct io7 *prev);
@@ -109,9 +108,15 @@ extern unsigned long wildfire_node_mem_size(int);
/* setup.c */
extern unsigned long srm_hae;
extern int boot_cpuid;
-extern int srmcons_output;
+
+/* srmcons.c */
+#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_SRM)
extern void register_srm_console(void);
extern void unregister_srm_console(void);
+#else
+#define register_srm_console()
+#define unregister_srm_console()
+#endif
/* smp.c */
extern void setup_smp(void);
diff --git a/arch/alpha/kernel/ptrace.c b/arch/alpha/kernel/ptrace.c
index dbc762fd43e3..496e1355a057 100644
--- a/arch/alpha/kernel/ptrace.c
+++ b/arch/alpha/kernel/ptrace.c
@@ -102,7 +102,9 @@ get_reg_addr(struct task_struct * task, unsigned long regno)
if (regno == 30) {
addr = &task->thread_info->pcb.usp;
- } else if (regno == 31 || regno > 64) {
+ } else if (regno == 65) {
+ addr = &task->thread_info->pcb.unique;
+ } else if (regno == 31 || regno > 65) {
zero = 0;
addr = &zero;
} else {
diff --git a/arch/alpha/kernel/setup.c b/arch/alpha/kernel/setup.c
index e8719e356065..ededddb6551c 100644
--- a/arch/alpha/kernel/setup.c
+++ b/arch/alpha/kernel/setup.c
@@ -77,18 +77,25 @@ int boot_cpuid;
* "srmcons" specified in the boot command arguments allows us to
* see kernel messages during the period of time before the true
- * console device is "registered" during console_init(). As of this
- * version (2.4.10), time_init() is the last Alpha-specific code
- * called before console_init(), so we put "unregister" code
- * there to prevent schizophrenic console behavior later... ;-}
+ * console device is "registered" during console_init().
+ * As of this version (2.5.59), console_init() will call
+ * disable_early_printk() as the last action before initializing
+ * the console drivers. That's the last possible time srmcons can be
+ * unregistered without interfering with console behavior.
*
- * By default, OFF; set it with a bootcommand arg of "srmcons".
+ * By default, OFF; set it with a bootcommand arg of "srmcons" or
+ * "console=srm". The meaning of these two args is:
+ * "srmcons" - early callback prints
+ * "console=srm" - full callback based console, including early prints
*/
int srmcons_output = 0;
/* Enforce a memory size limit; useful for testing. By default, none. */
unsigned long mem_size_limit = 0;
+/* Set AGP GART window size (0 means disabled). */
+unsigned long alpha_agpgart_size = DEFAULT_AGP_APER_SIZE;
+
#ifdef CONFIG_ALPHA_GENERIC
struct alpha_machine_vector alpha_mv;
int alpha_using_srm;
@@ -461,57 +468,6 @@ page_is_ram(unsigned long pfn)
#undef PFN_PHYS
#undef PFN_MAX
-#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_SRM)
-/*
- * Manage the SRM callbacks as a "console".
- */
-static struct console srmcons;
-
-void __init register_srm_console(void)
-{
- register_console(&srmcons);
-}
-
-void __init unregister_srm_console(void)
-{
- unregister_console(&srmcons);
-}
-
-static void srm_console_write(struct console *co, const char *s,
- unsigned count)
-{
- srm_printk(s);
-}
-
-static kdev_t srm_console_device(struct console *c)
-{
- /* Huh? */
- return mk_kdev(TTY_MAJOR, 64 + c->index);
-}
-
-static int __init srm_console_setup(struct console *co, char *options)
-{
- return 1;
-}
-
-static struct console srmcons = {
- .name = "srm0",
- .write = srm_console_write,
- .device = srm_console_device,
- .setup = srm_console_setup,
- .flags = CON_PRINTBUFFER | CON_ENABLED, /* fake it out */
- .index = -1,
-};
-
-#else
-void __init register_srm_console(void)
-{
-}
-void __init unregister_srm_console(void)
-{
-}
-#endif
-
void __init
setup_arch(char **cmdline_p)
{
@@ -574,7 +530,16 @@ setup_arch(char **cmdline_p)
continue;
}
if (strncmp(p, "srmcons", 7) == 0) {
- srmcons_output = 1;
+ srmcons_output |= 1;
+ continue;
+ }
+ if (strncmp(p, "console=srm", 11) == 0) {
+ srmcons_output |= 2;
+ continue;
+ }
+ if (strncmp(p, "gartsize=", 9) == 0) {
+ alpha_agpgart_size =
+ get_mem_size_limit(p+9) << PAGE_SHIFT;
continue;
}
}
@@ -585,6 +550,13 @@ setup_arch(char **cmdline_p)
/* If we want SRM console printk echoing early, do it now. */
if (alpha_using_srm && srmcons_output) {
register_srm_console();
+
+ /*
+ * If "console=srm" was specified, clear the srmcons_output
+ * flag now so that time.c won't unregister_srm_console
+ */
+ if (srmcons_output & 2)
+ srmcons_output = 0;
}
#ifdef CONFIG_MAGIC_SYSRQ
@@ -688,6 +660,15 @@ setup_arch(char **cmdline_p)
paging_init();
}
+void __init
+disable_early_printk(void)
+{
+ if (alpha_using_srm && srmcons_output) {
+ unregister_srm_console();
+ srmcons_output = 0;
+ }
+}
+
static char sys_unknown[] = "Unknown";
static char systype_names[][16] = {
"0",
diff --git a/arch/alpha/kernel/smp.c b/arch/alpha/kernel/smp.c
index 46eff5eeb857..a1ed17628934 100644
--- a/arch/alpha/kernel/smp.c
+++ b/arch/alpha/kernel/smp.c
@@ -544,9 +544,6 @@ smp_prepare_cpus(unsigned int max_cpus)
smp_tune_scheduling(boot_cpuid);
smp_setup_percpu_timer(boot_cpuid);
- /* We have already have the boot CPU online.. */
- set_bit(boot_cpuid, &cpu_online_map);
-
/* Nothing to do on a UP box, or when told not to. */
if (smp_num_probed == 1 || max_cpus == 0) {
cpu_present_mask = 1UL << boot_cpuid;
@@ -574,7 +571,11 @@ smp_prepare_cpus(unsigned int max_cpus)
void __devinit
smp_prepare_boot_cpu(void)
{
+ /*
+ * Mark the boot cpu (current cpu) as both present and online
+ */
set_bit(smp_processor_id(), &cpu_present_mask);
+ set_bit(smp_processor_id(), &cpu_online_map);
}
int __devinit
diff --git a/arch/alpha/kernel/srmcons.c b/arch/alpha/kernel/srmcons.c
new file mode 100644
index 000000000000..29c5a04414b7
--- /dev/null
+++ b/arch/alpha/kernel/srmcons.c
@@ -0,0 +1,361 @@
+/*
+ * linux/arch/alpha/kernel/srmcons.c
+ *
+ * Callback based driver for SRM Console console device.
+ * (TTY driver and console driver)
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/console.h>
+#include <linux/delay.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/timer.h>
+#include <linux/tty.h>
+#include <linux/tty_driver.h>
+#include <linux/tty_flip.h>
+
+#include <asm/console.h>
+#include <asm/uaccess.h>
+
+
+static spinlock_t srmcons_callback_lock = SPIN_LOCK_UNLOCKED;
+static int srm_is_registered_console = 0;
+
+/*
+ * The TTY driver
+ */
+#define MAX_SRM_CONSOLE_DEVICES 1 /* only support 1 console device */
+
+static int srmcons_refcount;
+static struct tty_struct *srmcons_table[MAX_SRM_CONSOLE_DEVICES];
+static struct termios *srmcons_termios[MAX_SRM_CONSOLE_DEVICES];
+static struct termios *srmcons_termios_locked[MAX_SRM_CONSOLE_DEVICES];
+
+struct srmcons_private {
+ struct tty_struct *tty;
+ struct timer_list timer;
+ spinlock_t lock;
+};
+
+typedef union _srmcons_result {
+ struct {
+ unsigned long c :61;
+ unsigned long status :3;
+ } bits;
+ long as_long;
+} srmcons_result;
+
+/* called with callback_lock held */
+static int
+srmcons_do_receive_chars(struct tty_struct *tty)
+{
+ srmcons_result result;
+ int count = 0, loops = 0;
+
+ do {
+ result.as_long = callback_getc(0);
+ if (result.bits.status < 2) {
+ tty_insert_flip_char(tty, (char)result.bits.c, 0);
+ count++;
+ }
+ } while((result.bits.status & 1) && (++loops < 10));
+
+ if (count)
+ tty_schedule_flip(tty);
+
+ return count;
+}
+
+static void
+srmcons_receive_chars(unsigned long data)
+{
+ struct srmcons_private *srmconsp = (struct srmcons_private *)data;
+ unsigned long flags;
+ int incr = 10;
+
+ local_irq_save(flags);
+ if (spin_trylock(&srmcons_callback_lock)) {
+ if (!srmcons_do_receive_chars(srmconsp->tty))
+ incr = 100;
+ spin_unlock(&srmcons_callback_lock);
+ }
+
+ spin_lock(&srmconsp->lock);
+ if (srmconsp->tty) {
+ srmconsp->timer.expires = jiffies + incr;
+ add_timer(&srmconsp->timer);
+ }
+ spin_unlock(&srmconsp->lock);
+
+ local_irq_restore(flags);
+}
+
+/* called with callback_lock held */
+static int
+srmcons_do_write(struct tty_struct *tty, const unsigned char *buf, int count)
+{
+ unsigned char *str_cr = "\r";
+ long c, remaining = count;
+ srmcons_result result;
+ unsigned char *cur;
+ int need_cr;
+
+ for (cur = (unsigned char *)buf; remaining > 0; ) {
+ need_cr = 0;
+ /*
+ * Break it up into reasonable size chunks to allow a chance
+ * for input to get in
+ */
+ for (c = 0; c < min_t(long, 128L, remaining) && !need_cr; c++)
+ if (cur[c] == '\n')
+ need_cr = 1;
+
+ while (c > 0) {
+ result.as_long = callback_puts(0, cur, c);
+ c -= result.bits.c;
+ remaining -= result.bits.c;
+ cur += result.bits.c;
+
+ /*
+ * Check for pending input iff a tty was provided
+ */
+ if (tty)
+ srmcons_do_receive_chars(tty);
+ }
+
+ while (need_cr) {
+ result.as_long = callback_puts(0, str_cr, 1);
+ if (result.bits.c > 0)
+ need_cr = 0;
+ }
+ }
+ return count;
+}
+
+static int
+srmcons_write(struct tty_struct *tty, int from_user,
+ const unsigned char *buf, int count)
+{
+ unsigned long flags;
+
+ if (from_user) {
+ unsigned char tmp[512];
+ int ret = 0;
+ size_t c;
+
+ while ((c = count) > 0) {
+ if (c > sizeof(tmp))
+ c = sizeof(tmp);
+
+ c -= copy_from_user(tmp, buf, c);
+
+ if (!c) {
+ printk("%s: EFAULT (count %d)\n",
+ __FUNCTION__, count);
+ return -EFAULT;
+ }
+
+ spin_lock_irqsave(&srmcons_callback_lock, flags);
+ srmcons_do_write(tty, tmp, c);
+ spin_unlock_irqrestore(&srmcons_callback_lock, flags);
+
+ buf += c;
+ count -= c;
+ ret += c;
+ }
+
+ return ret;
+ }
+
+ spin_lock_irqsave(&srmcons_callback_lock, flags);
+ srmcons_do_write(tty, buf, count);
+ spin_unlock_irqrestore(&srmcons_callback_lock, flags);
+
+ return count;
+}
+
+static int
+srmcons_write_room(struct tty_struct *tty)
+{
+ return 512;
+}
+
+static int
+srmcons_chars_in_buffer(struct tty_struct *tty)
+{
+ return 0;
+}
+
+static int
+srmcons_get_private_struct(struct srmcons_private **ps)
+{
+ static struct srmcons_private *srmconsp = NULL;
+ static spinlock_t srmconsp_lock = SPIN_LOCK_UNLOCKED;
+ unsigned long flags;
+ int retval = 0;
+
+ spin_lock_irqsave(&srmconsp_lock, flags);
+
+ do {
+ if (srmconsp != NULL) {
+ *ps = srmconsp;
+ break;
+ }
+
+ srmconsp = kmalloc(sizeof(*srmconsp), GFP_KERNEL);
+ if (srmconsp == NULL) {
+ retval = -ENOMEM;
+ break;
+ }
+
+ srmconsp->tty = NULL;
+ srmconsp->lock = SPIN_LOCK_UNLOCKED;
+ init_timer(&srmconsp->timer);
+
+ *ps = srmconsp;
+ } while(0);
+
+ spin_unlock_irqrestore(&srmconsp_lock, flags);
+
+ return retval;
+}
+
+static int
+srmcons_open(struct tty_struct *tty, struct file *filp)
+{
+ struct srmcons_private *srmconsp;
+ unsigned long flags;
+ int retval;
+
+ retval = srmcons_get_private_struct(&srmconsp);
+ if (retval)
+ return retval;
+
+ spin_lock_irqsave(&srmconsp->lock, flags);
+
+ if (!srmconsp->tty) {
+ tty->driver_data = srmconsp;
+
+ srmconsp->tty = tty;
+ srmconsp->timer.function = srmcons_receive_chars;
+ srmconsp->timer.data = (unsigned long)srmconsp;
+ srmconsp->timer.expires = jiffies + 10;
+ add_timer(&srmconsp->timer);
+ }
+
+ spin_unlock_irqrestore(&srmconsp->lock, flags);
+
+ return 0;
+}
+
+static void
+srmcons_close(struct tty_struct *tty, struct file *filp)
+{
+ struct srmcons_private *srmconsp = tty->driver_data;
+ unsigned long flags;
+
+ spin_lock_irqsave(&srmconsp->lock, flags);
+
+ if (tty->count == 1) {
+ srmconsp->tty = NULL;
+ del_timer(&srmconsp->timer);
+ }
+
+ spin_unlock_irqrestore(&srmconsp->lock, flags);
+}
+
+
+static struct tty_driver srmcons_driver = {
+ .driver_name = "srm",
+ .name = "srm",
+ .magic = TTY_DRIVER_MAGIC,
+ .major = 0, /* dynamic */
+ .minor_start = 0,
+ .num = MAX_SRM_CONSOLE_DEVICES,
+ .type = TTY_DRIVER_TYPE_SYSTEM,
+ .subtype = SYSTEM_TYPE_SYSCONS,
+
+ .table = srmcons_table,
+ .termios = srmcons_termios,
+ .termios_locked = srmcons_termios_locked,
+ .refcount = &srmcons_refcount,
+
+ .open = srmcons_open,
+ .close = srmcons_close,
+ .write = srmcons_write,
+ .write_room = srmcons_write_room,
+ .chars_in_buffer= srmcons_chars_in_buffer,
+};
+
+static int __init
+srmcons_init(void)
+{
+ if (srm_is_registered_console) {
+ srmcons_driver.init_termios = tty_std_termios;
+ return tty_register_driver(&srmcons_driver);
+ }
+
+ return -ENODEV;
+}
+
+module_init(srmcons_init);
+
+
+/*
+ * The console driver
+ */
+static void
+srm_console_write(struct console *co, const char *s, unsigned count)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&srmcons_callback_lock, flags);
+ srmcons_do_write(NULL, s, count);
+ spin_unlock_irqrestore(&srmcons_callback_lock, flags);
+}
+
+static kdev_t
+srm_console_device(struct console *co)
+{
+ return mk_kdev(srmcons_driver.major,
+ srmcons_driver.minor_start + co->index);
+}
+
+static int __init
+srm_console_setup(struct console *co, char *options)
+{
+ return 0;
+}
+
+static struct console srmcons = {
+ .name = "srm",
+ .write = srm_console_write,
+ .device = srm_console_device,
+ .setup = srm_console_setup,
+ .flags = CON_PRINTBUFFER,
+ .index = -1,
+};
+
+void __init
+register_srm_console(void)
+{
+ if (!srm_is_registered_console) {
+ callback_open_console();
+ register_console(&srmcons);
+ srm_is_registered_console = 1;
+ }
+}
+
+void __init
+unregister_srm_console(void)
+{
+ if (srm_is_registered_console) {
+ callback_close_console();
+ unregister_console(&srmcons);
+ srm_is_registered_console = 0;
+ }
+}
diff --git a/arch/alpha/kernel/sys_nautilus.c b/arch/alpha/kernel/sys_nautilus.c
index 4bdd7fc94920..030f9b216fa9 100644
--- a/arch/alpha/kernel/sys_nautilus.c
+++ b/arch/alpha/kernel/sys_nautilus.c
@@ -31,6 +31,7 @@
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/reboot.h>
+#include <linux/bootmem.h>
#include <asm/ptrace.h>
#include <asm/system.h>
@@ -163,7 +164,7 @@ nautilus_machine_check(unsigned long vector, unsigned long la_ptr,
}
printk(KERN_CRIT "NAUTILUS Machine check 0x%lx "
- "[%s System Machine Check (NMI)]\n",
+ "[%s System Machine Check (NMI)]\n",
vector, mchk_class);
naut_sys_machine_check(vector, la_ptr, regs);
@@ -174,6 +175,70 @@ nautilus_machine_check(unsigned long vector, unsigned long la_ptr,
mb();
}
+extern void free_reserved_mem(void *, void *);
+
+void __init
+nautilus_init_pci(void)
+{
+ struct pci_controller *hose = hose_head;
+ struct pci_bus *bus;
+ struct pci_dev *irongate;
+ unsigned long saved_io_start, saved_io_end;
+ unsigned long saved_mem_start, saved_mem_end;
+ unsigned long bus_align, bus_size, pci_mem;
+ unsigned long memtop = max_low_pfn << PAGE_SHIFT;
+
+ /* Scan our single hose. */
+ bus = pci_scan_bus(0, alpha_mv.pci_ops, hose);
+ hose->bus = bus;
+ hose->last_busno = bus->subordinate;
+
+ /* We're going to size the root bus, so we must
+ - have a non-NULL PCI device associated with the bus
+ - preserve hose resources. */
+ irongate = pci_find_slot(0, 0);
+ bus->self = irongate;
+ saved_io_start = bus->resource[0]->start;
+ saved_io_end = bus->resource[0]->end;
+ saved_mem_start = bus->resource[1]->start;
+ saved_mem_end = bus->resource[1]->end;
+
+ pci_bus_size_bridges(bus);
+
+ /* Don't care about IO. */
+ bus->resource[0]->start = saved_io_start;
+ bus->resource[0]->end = saved_io_end;
+
+ bus_align = bus->resource[1]->start;
+ bus_size = bus->resource[1]->end + 1 - bus_align;
+ /* Align to 16Mb. */
+ if (bus_align < 0x1000000UL)
+ bus_align = 0x1000000UL;
+
+ /* Restore hose MEM resource. */
+ bus->resource[1]->start = saved_mem_start;
+ bus->resource[1]->end = saved_mem_end;
+
+ pci_mem = (0x100000000UL - bus_size) & -bus_align;
+
+ if (pci_mem < memtop && pci_mem > alpha_mv.min_mem_address) {
+ free_reserved_mem(__va(alpha_mv.min_mem_address),
+ __va(pci_mem));
+ printk("nautilus_init_arch: %ldk freed\n",
+ (pci_mem - alpha_mv.min_mem_address) >> 10);
+ }
+
+ alpha_mv.min_mem_address = pci_mem;
+ if ((IRONGATE0->dev_vendor >> 16) > 0x7006) /* Albacore? */
+ IRONGATE0->pci_mem = pci_mem;
+
+ pci_bus_assign_resources(bus);
+
+ /* To break the loop in common_swizzle() */
+ bus->self = NULL;
+
+ pci_fixup_irqs(alpha_mv.pci_swizzle, alpha_mv.pci_map_irq);
+}
/*
* The System Vectors
@@ -196,7 +261,7 @@ struct alpha_machine_vector nautilus_mv __initmv = {
.init_arch = irongate_init_arch,
.init_irq = nautilus_init_irq,
.init_rtc = common_init_rtc,
- .init_pci = common_init_pci,
+ .init_pci = nautilus_init_pci,
.kill_arch = nautilus_kill_arch,
.pci_map_irq = nautilus_map_irq,
.pci_swizzle = common_swizzle,
diff --git a/arch/alpha/kernel/time.c b/arch/alpha/kernel/time.c
index 03fed82384dd..1525d25de0e3 100644
--- a/arch/alpha/kernel/time.c
+++ b/arch/alpha/kernel/time.c
@@ -383,21 +383,6 @@ time_init(void)
/* Startup the timer source. */
alpha_mv.init_rtc();
-
- /*
- * If we had wanted SRM console printk echoing early, undo it now.
- *
- * "srmcons" specified in the boot command arguments allows us to
- * see kernel messages during the period of time before the true
- * console device is "registered" during console_init(). As of this
- * version (2.4.10), time_init() is the last Alpha-specific code
- * called before console_init(), so we put this "unregister" code
- * here to prevent schizophrenic console behavior later... ;-}
- */
- if (alpha_using_srm && srmcons_output) {
- unregister_srm_console();
- srmcons_output = 0;
- }
}
/*
diff --git a/include/asm-alpha/core_irongate.h b/include/asm-alpha/core_irongate.h
index 4a4e6fa4c0e8..9b9a49feb51b 100644
--- a/include/asm-alpha/core_irongate.h
+++ b/include/asm-alpha/core_irongate.h
@@ -50,13 +50,14 @@ typedef struct {
igcsr32 bacsr10; /* 0x40 - base address chip selects */
igcsr32 bacsr32; /* 0x44 - base address chip selects */
- igcsr32 bacsr54; /* 0x48 - base address chip selects */
+ igcsr32 bacsr54_eccms761; /* 0x48 - 751: base addr. chip selects
+ 761: ECC, mode/status */
igcsr32 rsrvd2[1]; /* 0x4C-0x4F reserved */
igcsr32 drammap; /* 0x50 - address mapping control */
igcsr32 dramtm; /* 0x54 - timing, driver strength */
- igcsr32 dramms; /* 0x58 - ECC, mode/status */
+ igcsr32 dramms; /* 0x58 - DRAM mode/status */
igcsr32 rsrvd3[1]; /* 0x5C-0x5F reserved */
@@ -73,7 +74,10 @@ typedef struct {
igcsr32 pciarb; /* 0x84 - PCI arbitration control */
igcsr32 pcicfg; /* 0x88 - PCI config status */
- igcsr32 rsrvd6[5]; /* 0x8C-0x9F reserved */
+ igcsr32 rsrvd6[4]; /* 0x8C-0x9B reserved */
+
+ igcsr32 pci_mem; /* 0x9C - PCI top of memory,
+ 761 only */
/* AGP (bus 1) control registers */
igcsr32 agpcap; /* 0xA0 - AGP Capability Identifier */
@@ -102,6 +106,7 @@ typedef struct {
} Irongate1;
+extern igcsr32 *IronECC;
/*
* Memory spaces:
diff --git a/include/asm-alpha/elf.h b/include/asm-alpha/elf.h
index 9513f35aa8a1..033597e3e0ab 100644
--- a/include/asm-alpha/elf.h
+++ b/include/asm-alpha/elf.h
@@ -52,53 +52,25 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
#define ELF_PLAT_INIT(_r) _r->r0 = 0
-/* Use the same format as the OSF/1 procfs interface. The register
- layout is sane. However, since dump_thread() creates the funky
- layout that ECOFF coredumps want, we need to undo that layout here.
- Eventually, it would be nice if the ECOFF core-dump had to do the
- translation, then ELF_CORE_COPY_REGS() would become trivial and
- faster. */
-
-#define ELF_CORE_COPY_REGS(_dest,_regs) \
-{ \
- extern void dump_thread(struct pt_regs *, struct user *); \
- struct user _dump; \
- \
- dump_thread(_regs, &_dump); \
- _dest[ 0] = _dump.regs[EF_V0]; \
- _dest[ 1] = _dump.regs[EF_T0]; \
- _dest[ 2] = _dump.regs[EF_T1]; \
- _dest[ 3] = _dump.regs[EF_T2]; \
- _dest[ 4] = _dump.regs[EF_T3]; \
- _dest[ 5] = _dump.regs[EF_T4]; \
- _dest[ 6] = _dump.regs[EF_T5]; \
- _dest[ 7] = _dump.regs[EF_T6]; \
- _dest[ 8] = _dump.regs[EF_T7]; \
- _dest[ 9] = _dump.regs[EF_S0]; \
- _dest[10] = _dump.regs[EF_S1]; \
- _dest[11] = _dump.regs[EF_S2]; \
- _dest[12] = _dump.regs[EF_S3]; \
- _dest[13] = _dump.regs[EF_S4]; \
- _dest[14] = _dump.regs[EF_S5]; \
- _dest[15] = _dump.regs[EF_S6]; \
- _dest[16] = _dump.regs[EF_A0]; \
- _dest[17] = _dump.regs[EF_A1]; \
- _dest[18] = _dump.regs[EF_A2]; \
- _dest[19] = _dump.regs[EF_A3]; \
- _dest[20] = _dump.regs[EF_A4]; \
- _dest[21] = _dump.regs[EF_A5]; \
- _dest[22] = _dump.regs[EF_T8]; \
- _dest[23] = _dump.regs[EF_T9]; \
- _dest[24] = _dump.regs[EF_T10]; \
- _dest[25] = _dump.regs[EF_T11]; \
- _dest[26] = _dump.regs[EF_RA]; \
- _dest[27] = _dump.regs[EF_T12]; \
- _dest[28] = _dump.regs[EF_AT]; \
- _dest[29] = _dump.regs[EF_GP]; \
- _dest[30] = _dump.regs[EF_SP]; \
- _dest[31] = _dump.regs[EF_PC]; /* store PC here */ \
- _dest[32] = _dump.regs[EF_PS]; \
-}
+/* The registers are layed out in pt_regs for PAL and syscall
+ convenience. Re-order them for the linear elf_gregset_t. */
+
+extern void dump_elf_thread(elf_greg_t *dest, struct pt_regs *pt,
+ struct thread_info *ti);
+#define ELF_CORE_COPY_REGS(DEST, REGS) \
+ dump_elf_thread(DEST, REGS, current_thread_info());
+
+/* Similar, but for a thread other than current. */
+
+extern int dump_elf_task(elf_greg_t *dest, struct task_struct *task);
+#define ELF_CORE_COPY_TASK_REGS(TASK, DEST) \
+ dump_elf_task(*(DEST), TASK)
+
+/* Similar, but for the FP registers. */
+
+extern int dump_elf_task_fp(elf_fpreg_t *dest, struct task_struct *task);
+#define ELF_CORE_COPY_FPREGS(TASK, DEST) \
+ dump_elf_task_fp(*(DEST), TASK)
/* This yields a mask that user programs can use to figure out what
instruction set this CPU supports. This is trivial on Alpha,
diff --git a/include/asm-alpha/topology.h b/include/asm-alpha/topology.h
index fe77fb5b4105..742b68802fd0 100644
--- a/include/asm-alpha/topology.h
+++ b/include/asm-alpha/topology.h
@@ -43,6 +43,9 @@ static inline int node_to_cpumask(int node)
# define node_to_memblk(node) (node)
# define memblk_to_node(memblk) (memblk)
+/* Cross-node load balancing interval. */
+# define NODE_BALANCE_RATE 10
+
#else /* CONFIG_NUMA */
# include <asm-generic/topology.h>
#endif /* !CONFIG_NUMA */