summaryrefslogtreecommitdiffstats
path: root/arch/alpha
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2000-07-03 21:46:06 +0000
committerRalf Baechle <ralf@linux-mips.org>2000-07-03 21:46:06 +0000
commit3e414096429d55fbc8116171bba3487647bbe638 (patch)
tree2b5fcfd9d16fa3a32c829fc2076f6e3785b43374 /arch/alpha
parent20b23bfcf36fcb2d16d8b844501072541970637c (diff)
Merge with Linux 2.4.0-test3-pre2.
Diffstat (limited to 'arch/alpha')
-rw-r--r--arch/alpha/Makefile8
-rw-r--r--arch/alpha/config.in4
-rw-r--r--arch/alpha/kernel/core_cia.c20
-rw-r--r--arch/alpha/kernel/pci.c16
-rw-r--r--arch/alpha/kernel/setup.c56
-rw-r--r--arch/alpha/kernel/sys_sx164.c33
-rw-r--r--arch/alpha/vmlinux.lds.in96
7 files changed, 207 insertions, 26 deletions
diff --git a/arch/alpha/Makefile b/arch/alpha/Makefile
index 36f4d4e6d..3daa2c73c 100644
--- a/arch/alpha/Makefile
+++ b/arch/alpha/Makefile
@@ -10,7 +10,7 @@
NM := nm -B
-LINKFLAGS = -static -T arch/alpha/vmlinux.lds #-N -relax
+LINKFLAGS = -static -T arch/alpha/vmlinux.lds -N #-relax
CFLAGS := $(CFLAGS) -pipe -mno-fp-regs -ffixed-8
# Determine if we can use the BWX instructions with GAS.
@@ -90,7 +90,7 @@ endif
LIBS := $(TOPDIR)/arch/alpha/lib/lib.a $(LIBS) $(TOPDIR)/arch/alpha/lib/lib.a
-MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
+MAKEBOOT = $(MAKE) -C arch/alpha/boot
rawboot:
@$(MAKEBOOT) rawboot
@@ -109,13 +109,15 @@ srmboot:
@$(MAKEBOOT) srmboot
archclean:
- @$(MAKE) -C arch/$(ARCH)/kernel clean
+ @$(MAKE) -C arch/alpha/kernel clean
@$(MAKEBOOT) clean
+ rm -f arch/alpha/vmlinux.lds
archmrproper:
archdep:
@$(MAKEBOOT) dep
+ $(CPP) $(CPPFLAGS) -xc -P arch/alpha/vmlinux.lds.in -o arch/alpha/vmlinux.lds
bootpfile:
@$(MAKEBOOT) bootpfile
diff --git a/arch/alpha/config.in b/arch/alpha/config.in
index 5f344e0f5..7441083b6 100644
--- a/arch/alpha/config.in
+++ b/arch/alpha/config.in
@@ -331,7 +331,6 @@ source drivers/usb/Config.in
mainmenu_option next_comment
comment 'Kernel hacking'
-#bool 'Debug kmalloc/kfree' CONFIG_DEBUG_MALLOC
if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
tristate 'Kernel FP software completion' CONFIG_MATHEMU
else
@@ -339,4 +338,7 @@ else
fi
bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ
+
+bool 'Legacy kernel start address' CONFIG_ALPHA_LEGACY_START_ADDRESS
+
endmenu
diff --git a/arch/alpha/kernel/core_cia.c b/arch/alpha/kernel/core_cia.c
index 88c88a4e6..348bd843f 100644
--- a/arch/alpha/kernel/core_cia.c
+++ b/arch/alpha/kernel/core_cia.c
@@ -19,6 +19,7 @@
#include <asm/system.h>
#include <asm/ptrace.h>
+#include <asm/hwrpb.h>
#define __EXTERN_INLINE inline
#include <asm/io.h>
@@ -712,6 +713,25 @@ cia_init_arch(void)
void __init
pyxis_init_arch(void)
{
+ /* On pyxis machines we can precisely calculate the
+ CPU clock frequency using pyxis real time counter.
+ It's especially useful for SX164 with broken RTC.
+
+ Both CPU and chipset are driven by the single 16.666M
+ or 16.667M crystal oscillator. PYXIS_RT_COUNT clock is
+ 66.66 MHz. -ink */
+
+ unsigned int cc0, cc1;
+ unsigned long pyxis_cc;
+
+ __asm__ __volatile__ ("rpcc %0" : "=r"(cc0));
+ pyxis_cc = *(vulp)PYXIS_RT_COUNT;
+ do { } while(*(vulp)PYXIS_RT_COUNT - pyxis_cc < 4096);
+ __asm__ __volatile__ ("rpcc %0" : "=r"(cc1));
+ cc1 -= cc0;
+ hwrpb->cycle_freq = ((cc1 >> 11) * 100000000UL) / 3;
+ hwrpb_update_checksum(hwrpb);
+
do_init_arch(1);
}
diff --git a/arch/alpha/kernel/pci.c b/arch/alpha/kernel/pci.c
index 7a916ad08..2dc6f00dd 100644
--- a/arch/alpha/kernel/pci.c
+++ b/arch/alpha/kernel/pci.c
@@ -369,6 +369,22 @@ pcibios_enable_device(struct pci_dev *dev)
return 0;
}
+/*
+ * If we set up a device for bus mastering, we need to check the latency
+ * timer as certain firmware forgets to set it properly, as seen
+ * on SX164 and LX164 with SRM.
+ */
+void
+pcibios_set_master(struct pci_dev *dev)
+{
+ u8 lat;
+ pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
+ if (lat >= 16) return;
+ printk("PCI: Setting latency timer of device %s to 64\n",
+ dev->slot_name);
+ pci_write_config_byte(dev, PCI_LATENCY_TIMER, 64);
+}
+
#define ROUND_UP(x, a) (((x) + (a) - 1) & ~((a) - 1))
static void __init
diff --git a/arch/alpha/kernel/setup.c b/arch/alpha/kernel/setup.c
index 988c3cbec..073ee5381 100644
--- a/arch/alpha/kernel/setup.c
+++ b/arch/alpha/kernel/setup.c
@@ -246,11 +246,12 @@ get_mem_size_limit(char *s)
}
static void __init
-setup_memory(void * kernel_end)
+setup_memory(void *kernel_end)
{
struct memclust_struct * cluster;
struct memdesc_struct * memdesc;
- unsigned long start_pfn, bootmap_size, bootmap_pages, bootmap_start;
+ unsigned long start_kernel_pfn, end_kernel_pfn;
+ unsigned long bootmap_size, bootmap_pages, bootmap_start;
unsigned long start, end;
int i;
@@ -282,12 +283,13 @@ setup_memory(void * kernel_end)
max_low_pfn = mem_size_limit;
}
- /* Find the end of the memory used by the kernel. */
- start_pfn = PFN_UP(virt_to_phys(kernel_end));
+ /* Find the bounds of kernel memory. */
+ start_kernel_pfn = PFN_DOWN(KERNEL_START_PHYS);
+ end_kernel_pfn = PFN_UP(virt_to_phys(kernel_end));
bootmap_start = -1;
try_again:
- if (max_low_pfn <= start_pfn)
+ if (max_low_pfn <= end_kernel_pfn)
panic("not enough memory to boot");
/* We need to know how many physically contiguous pages
@@ -301,14 +303,19 @@ setup_memory(void * kernel_end)
start = cluster->start_pfn;
end = start + cluster->numpages;
- if (end <= start_pfn)
- continue;
if (start >= max_low_pfn)
continue;
- if (start < start_pfn)
- start = start_pfn;
if (end > max_low_pfn)
end = max_low_pfn;
+ if (start < start_kernel_pfn) {
+ if (end > end_kernel_pfn
+ && end - end_kernel_pfn >= bootmap_pages) {
+ bootmap_start = end_kernel_pfn;
+ break;
+ } else if (end > start_kernel_pfn)
+ end = start_kernel_pfn;
+ } else if (start < end_kernel_pfn)
+ start = end_kernel_pfn;
if (end - start >= bootmap_pages) {
bootmap_start = start;
break;
@@ -329,22 +336,28 @@ setup_memory(void * kernel_end)
continue;
start = cluster->start_pfn;
- if (start < start_pfn)
- start = start_pfn;
-
end = cluster->start_pfn + cluster->numpages;
+ if (start >= max_low_pfn)
+ continue;
if (end > max_low_pfn)
end = max_low_pfn;
-
+ if (start < start_kernel_pfn) {
+ if (end > end_kernel_pfn) {
+ free_bootmem(PFN_PHYS(start),
+ (PFN_PHYS(start_kernel_pfn)
+ - PFN_PHYS(start)));
+ printk("freeing pages %ld:%ld\n",
+ start, start_kernel_pfn);
+ start = end_kernel_pfn;
+ } else if (end > start_kernel_pfn)
+ end = start_kernel_pfn;
+ } else if (start < end_kernel_pfn)
+ start = end_kernel_pfn;
if (start >= end)
continue;
- start = PFN_PHYS(start);
- end = PFN_PHYS(end);
-
- free_bootmem(start, end - start);
- printk("freeing pages %ld:%ld\n",
- PFN_UP(start), PFN_DOWN(end));
+ free_bootmem(PFN_PHYS(start), PFN_PHYS(end) - PFN_PHYS(start));
+ printk("freeing pages %ld:%ld\n", start, end);
}
/* Reserve the bootmap memory. */
@@ -461,11 +474,12 @@ void __init unregister_srm_console(void)
void __init
setup_arch(char **cmdline_p)
{
+ extern char _end[];
+
struct alpha_machine_vector *vec = NULL;
struct percpu_struct *cpu;
char *type_name, *var_name, *p;
- extern char _end;
- void * kernel_end = &_end; /* end of kernel */
+ void *kernel_end = _end; /* end of kernel */
hwrpb = (struct hwrpb_struct*) __va(INIT_HWRPB->phys_addr);
boot_cpuid = hard_smp_processor_id();
diff --git a/arch/alpha/kernel/sys_sx164.c b/arch/alpha/kernel/sys_sx164.c
index b98e46028..19abbb6c3 100644
--- a/arch/alpha/kernel/sys_sx164.c
+++ b/arch/alpha/kernel/sys_sx164.c
@@ -24,6 +24,7 @@
#include <asm/io.h>
#include <asm/pgtable.h>
#include <asm/core_cia.h>
+#include <asm/hwrpb.h>
#include "proto.h"
#include "irq_impl.h"
@@ -114,6 +115,36 @@ sx164_init_pci(void)
SMC669_Init(0);
}
+static void __init
+sx164_init_arch(void)
+{
+ /*
+ * OSF palcode v1.23 forgets to enable PCA56 Motion Video
+ * Instructions. Let's enable it.
+ * We have to check palcode revision because CSERVE interface
+ * is subject to change without notice. For example, it
+ * has been changed completely since v1.16 (found in MILO
+ * distribution). -ink
+ */
+ struct percpu_struct *cpu = (struct percpu_struct*)
+ ((char*)hwrpb + hwrpb->processor_offset);
+
+ if (alpha_using_srm && (cpu->pal_revision & 0xffff) == 0x117) {
+ __asm__ __volatile__(
+ "lda $16,8($31)\n"
+ "call_pal 9\n" /* Allow PALRES insns in kernel mode */
+ ".long 0x64000118\n\n" /* hw_mfpr $0,icsr */
+ "ldah $16,(1<<(19-16))($31)\n"
+ "or $0,$16,$0\n" /* set MVE bit */
+ ".long 0x74000118\n" /* hw_mtpr $0,icsr */
+ "lda $16,9($31)\n"
+ "call_pal 9" /* Disable PALRES insns */
+ : : : "$0", "$16");
+ printk("PCA56 MVI set enabled\n");
+ }
+
+ pyxis_init_arch();
+}
/*
* The System Vector
@@ -133,7 +164,7 @@ struct alpha_machine_vector sx164_mv __initmv = {
nr_irqs: 48,
device_interrupt: pyxis_device_interrupt,
- init_arch: pyxis_init_arch,
+ init_arch: sx164_init_arch,
init_irq: sx164_init_irq,
init_rtc: common_init_rtc,
init_pci: sx164_init_pci,
diff --git a/arch/alpha/vmlinux.lds.in b/arch/alpha/vmlinux.lds.in
new file mode 100644
index 000000000..a153e5bd1
--- /dev/null
+++ b/arch/alpha/vmlinux.lds.in
@@ -0,0 +1,96 @@
+#include <linux/config.h>
+
+OUTPUT_FORMAT("elf64-alpha")
+ENTRY(__start)
+PHDRS { kernel PT_LOAD ; }
+SECTIONS
+{
+#ifdef CONFIG_ALPHA_LEGACY_START_ADDRESS
+ . = 0xfffffc0000310000;
+#else
+ . = 0xfffffc0000810000;
+#endif
+
+ _text = .;
+ .text : { *(.text) } :kernel
+ _etext = .;
+
+ /* Exception table */
+ . = ALIGN(16);
+ __start___ex_table = .;
+ __ex_table : { *(__ex_table) }
+ __stop___ex_table = .;
+
+ /* Kernel symbol table */
+ . = ALIGN(8);
+ __start___ksymtab = .;
+ __ksymtab : { *(__ksymtab) }
+ __stop___ksymtab = .;
+ .kstrtab : { *(.kstrtab) }
+
+ /* Startup code */
+ . = ALIGN(8192);
+ __init_begin = .;
+ .text.init : { *(.text.init) }
+ .data.init : { *(.data.init) }
+
+ . = ALIGN(16);
+ __setup_start = .;
+ .setup.init : { *(.setup.init) }
+ __setup_end = .;
+
+ . = ALIGN(8);
+ __initcall_start = .;
+ .initcall.init : { *(.initcall.init) }
+ __initcall_end = .;
+
+ . = ALIGN(2*8192); /* Align double page for init_task_union */
+ __init_end = .;
+
+ /* The initial task and kernel stack */
+ init_task : { *(init_task) }
+
+ /* Global data */
+ _data = .;
+ .data.cacheline_aligned : { *(.data.cacheline_aligned) }
+ .rodata : { *(.rodata) }
+ .data : { *(.data) CONSTRUCTORS }
+ .got : { *(.got) }
+ .sdata : { *(.sdata) }
+ _edata = .;
+
+ __bss_start = .;
+ .sbss : { *(.sbss) *(.scommon) }
+ .bss : { *(.bss) *(COMMON) }
+ __bss_stop = .;
+ _end = .;
+
+ .mdebug 0 : { *(.mdebug) }
+ .note 0 : { *(.note) }
+ .comment 0 : { *(.comment) }
+
+ /* DWARF 1 */
+ .debug 0 : { *(.debug) }
+ .line 0 : { *(.line) }
+ /* GNU DWARF 1 extensions */
+ .debug_srcinfo 0 : { *(.debug_srcinfo) }
+ .debug_sfnames 0 : { *(.debug_sfnames) }
+ /* DWARF 1.1 and DWARF 2 */
+ .debug_aranges 0 : { *(.debug_aranges) }
+ .debug_pubnames 0 : { *(.debug_pubnames) }
+ /* DWARF 2 */
+ .debug_info 0 : { *(.debug_info) }
+ .debug_abbrev 0 : { *(.debug_abbrev) }
+ .debug_line 0 : { *(.debug_line) }
+ .debug_frame 0 : { *(.debug_frame) }
+ .debug_str 0 : { *(.debug_str) }
+ .debug_loc 0 : { *(.debug_loc) }
+ .debug_macinfo 0 : { *(.debug_macinfo) }
+ /* SGI/MIPS DWARF 2 extensions */
+ .debug_weaknames 0 : { *(.debug_weaknames) }
+ .debug_funcnames 0 : { *(.debug_funcnames) }
+ .debug_typenames 0 : { *(.debug_typenames) }
+ .debug_varnames 0 : { *(.debug_varnames) }
+
+ /DISCARD/ : { *(.text.exit) *(.data.exit) }
+}