Commit 35231647 authored by Richard Henderson's avatar Richard Henderson

Merge

parents 5ad0c942 2192cb52
...@@ -458,6 +458,11 @@ config ALPHA_SRM ...@@ -458,6 +458,11 @@ config ALPHA_SRM
If unsure, say N. If unsure, say N.
config EARLY_PRINTK
bool
depends on ALPHA_GENERIC || ALPHA_SRM
default y
config ALPHA_EISA config ALPHA_EISA
bool bool
depends on ALPHA_ALCOR || ALPHA_MIKASA || ALPHA_SABLE || ALPHA_NORITAKE || ALPHA_RAWHIDE depends on ALPHA_ALCOR || ALPHA_MIKASA || ALPHA_SABLE || ALPHA_NORITAKE || ALPHA_RAWHIDE
......
...@@ -33,8 +33,13 @@ obj-y += err_titan.o err_marvel.o ...@@ -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 += es1888.o smc37c669.o smc37c93x.o ns87312.o gct.o
obj-y += srmcons.o
else else
# Misc support
obj-$(CONFIG_ALPHA_SRM) += srmcons.o
# Core logic support # Core logic support
obj-$(CONFIG_ALPHA_APECS) += core_apecs.o obj-$(CONFIG_ALPHA_APECS) += core_apecs.o
obj-$(CONFIG_ALPHA_CIA) += core_cia.o obj-$(CONFIG_ALPHA_CIA) += core_cia.o
......
...@@ -40,7 +40,6 @@ ...@@ -40,7 +40,6 @@
extern struct hwrpb_struct *hwrpb; extern struct hwrpb_struct *hwrpb;
extern void dump_thread(struct pt_regs *, struct user *); extern void dump_thread(struct pt_regs *, struct user *);
extern int dump_fpu(struct pt_regs *, elf_fpregset_t *);
extern spinlock_t rtc_lock; extern spinlock_t rtc_lock;
/* these are C runtime functions with special calling conventions: */ /* these are C runtime functions with special calling conventions: */
...@@ -144,7 +143,9 @@ EXPORT_SYMBOL(pci_dac_dma_to_offset); ...@@ -144,7 +143,9 @@ EXPORT_SYMBOL(pci_dac_dma_to_offset);
#endif #endif
EXPORT_SYMBOL(dump_thread); 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(hwrpb);
EXPORT_SYMBOL(start_thread); EXPORT_SYMBOL(start_thread);
EXPORT_SYMBOL(alpha_read_fp_reg); EXPORT_SYMBOL(alpha_read_fp_reg);
......
This diff is collapsed.
...@@ -732,21 +732,6 @@ marvel_iounmap(unsigned long addr) ...@@ -732,21 +732,6 @@ marvel_iounmap(unsigned long addr)
EXPORT_SYMBOL(marvel_ioremap); EXPORT_SYMBOL(marvel_ioremap);
EXPORT_SYMBOL(marvel_iounmap); EXPORT_SYMBOL(marvel_iounmap);
#endif #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) ...@@ -874,8 +859,6 @@ marvel_node_mem_size(int nid)
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/delay.h> #include <linux/delay.h>
#define MARVEL_AGP_APER_SIZE (64 * 1024 * 1024)
struct marvel_agp_aperture { struct marvel_agp_aperture {
struct pci_iommu_arena *arena; struct pci_iommu_arena *arena;
long pg_start; long pg_start;
...@@ -887,11 +870,14 @@ marvel_agp_setup(alpha_agp_info *agp) ...@@ -887,11 +870,14 @@ marvel_agp_setup(alpha_agp_info *agp)
{ {
struct marvel_agp_aperture *aper; struct marvel_agp_aperture *aper;
if (!alpha_agpgart_size)
return -ENOMEM;
aper = kmalloc(sizeof(*aper), GFP_KERNEL); aper = kmalloc(sizeof(*aper), GFP_KERNEL);
if (aper == NULL) return -ENOMEM; if (aper == NULL) return -ENOMEM;
aper->arena = agp->hose->sg_pci; 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_start = iommu_reserve(aper->arena, aper->pg_count,
aper->pg_count - 1); aper->pg_count - 1);
......
...@@ -580,8 +580,6 @@ EXPORT_SYMBOL(titan_iounmap); ...@@ -580,8 +580,6 @@ EXPORT_SYMBOL(titan_iounmap);
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/delay.h> #include <linux/delay.h>
#define TITAN_AGP_APER_SIZE (64 * 1024 * 1024)
struct titan_agp_aperture { struct titan_agp_aperture {
struct pci_iommu_arena *arena; struct pci_iommu_arena *arena;
long pg_start; long pg_start;
...@@ -593,12 +591,15 @@ titan_agp_setup(alpha_agp_info *agp) ...@@ -593,12 +591,15 @@ titan_agp_setup(alpha_agp_info *agp)
{ {
struct titan_agp_aperture *aper; struct titan_agp_aperture *aper;
if (!alpha_agpgart_size)
return -ENOMEM;
aper = kmalloc(sizeof(struct titan_agp_aperture), GFP_KERNEL); aper = kmalloc(sizeof(struct titan_agp_aperture), GFP_KERNEL);
if (aper == NULL) if (aper == NULL)
return -ENOMEM; return -ENOMEM;
aper->arena = agp->hose->sg_pci; 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_start = iommu_reserve(aper->arena, aper->pg_count,
aper->pg_count - 1); aper->pg_count - 1);
if (aper->pg_start < 0) { if (aper->pg_start < 0) {
......
...@@ -534,7 +534,7 @@ show_interrupts(struct seq_file *p, void *v) ...@@ -534,7 +534,7 @@ show_interrupts(struct seq_file *p, void *v)
#else #else
for (j = 0; j < NR_CPUS; j++) for (j = 0; j < NR_CPUS; j++)
if (cpu_online(j)) if (cpu_online(j))
seq_printf(p, "%10u ", kstat_cpu(i).irqs[j]); seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
#endif #endif
seq_printf(p, " %14s", irq_desc[i].handler->typename); seq_printf(p, " %14s", irq_desc[i].handler->typename);
seq_printf(p, " %c%s", seq_printf(p, " %c%s",
......
...@@ -71,6 +71,8 @@ struct pci_iommu_arena; ...@@ -71,6 +71,8 @@ struct pci_iommu_arena;
#define IRONGATE_DEFAULT_MEM_BASE ((256*8-16)*1024*1024) #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 * A small note about bridges and interrupts. The DECchip 21050 (and
* later) adheres to the PCI-PCI bridge specification. This says that * later) adheres to the PCI-PCI bridge specification. This says that
...@@ -153,6 +155,8 @@ extern struct pci_controller *pci_isa_hose; ...@@ -153,6 +155,8 @@ extern struct pci_controller *pci_isa_hose;
/* Indicate that we trust the console to configure things properly. */ /* Indicate that we trust the console to configure things properly. */
extern int pci_probe_only; extern int pci_probe_only;
extern unsigned long alpha_agpgart_size;
extern void common_init_pci(void); extern void common_init_pci(void);
extern u8 common_swizzle(struct pci_dev *, u8 *); extern u8 common_swizzle(struct pci_dev *, u8 *);
extern struct pci_controller *alloc_pci_controller(void); extern struct pci_controller *alloc_pci_controller(void);
......
...@@ -313,7 +313,7 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long usp, ...@@ -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 void
dump_thread(struct pt_regs * pt, struct user * dump) dump_thread(struct pt_regs * pt, struct user * dump)
...@@ -373,12 +373,81 @@ 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); 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: */ /* switch stack follows right below pt_regs: */
struct switch_stack * sw = ((struct switch_stack *) regs) - 1; struct switch_stack * sw = ((struct switch_stack *) pt) - 1;
memcpy(r, sw->fp, 32 * 8);
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; return 1;
} }
......
...@@ -53,7 +53,6 @@ extern int marvel_pa_to_nid(unsigned long); ...@@ -53,7 +53,6 @@ extern int marvel_pa_to_nid(unsigned long);
extern int marvel_cpuid_to_nid(int); extern int marvel_cpuid_to_nid(int);
extern unsigned long marvel_node_mem_start(int); extern unsigned long marvel_node_mem_start(int);
extern unsigned long marvel_node_mem_size(int); extern unsigned long marvel_node_mem_size(int);
extern int marvel_srmcons_allowed(void);
extern struct _alpha_agp_info *marvel_agp_info(void); extern struct _alpha_agp_info *marvel_agp_info(void);
struct io7 *marvel_find_io7(int pe); struct io7 *marvel_find_io7(int pe);
struct io7 *marvel_next_io7(struct io7 *prev); struct io7 *marvel_next_io7(struct io7 *prev);
...@@ -109,9 +108,15 @@ extern unsigned long wildfire_node_mem_size(int); ...@@ -109,9 +108,15 @@ extern unsigned long wildfire_node_mem_size(int);
/* setup.c */ /* setup.c */
extern unsigned long srm_hae; extern unsigned long srm_hae;
extern int boot_cpuid; 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 register_srm_console(void);
extern void unregister_srm_console(void); extern void unregister_srm_console(void);
#else
#define register_srm_console()
#define unregister_srm_console()
#endif
/* smp.c */ /* smp.c */
extern void setup_smp(void); extern void setup_smp(void);
......
...@@ -102,7 +102,9 @@ get_reg_addr(struct task_struct * task, unsigned long regno) ...@@ -102,7 +102,9 @@ get_reg_addr(struct task_struct * task, unsigned long regno)
if (regno == 30) { if (regno == 30) {
addr = &task->thread_info->pcb.usp; 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; zero = 0;
addr = &zero; addr = &zero;
} else { } else {
......
...@@ -77,18 +77,25 @@ int boot_cpuid; ...@@ -77,18 +77,25 @@ int boot_cpuid;
* "srmcons" specified in the boot command arguments allows us to * "srmcons" specified in the boot command arguments allows us to
* see kernel messages during the period of time before the true * see kernel messages during the period of time before the true
* console device is "registered" during console_init(). As of this * console device is "registered" during console_init().
* version (2.4.10), time_init() is the last Alpha-specific code * As of this version (2.5.59), console_init() will call
* called before console_init(), so we put "unregister" code * disable_early_printk() as the last action before initializing
* there to prevent schizophrenic console behavior later... ;-} * 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; int srmcons_output = 0;
/* Enforce a memory size limit; useful for testing. By default, none. */ /* Enforce a memory size limit; useful for testing. By default, none. */
unsigned long mem_size_limit = 0; 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 #ifdef CONFIG_ALPHA_GENERIC
struct alpha_machine_vector alpha_mv; struct alpha_machine_vector alpha_mv;
int alpha_using_srm; int alpha_using_srm;
...@@ -461,57 +468,6 @@ page_is_ram(unsigned long pfn) ...@@ -461,57 +468,6 @@ page_is_ram(unsigned long pfn)
#undef PFN_PHYS #undef PFN_PHYS
#undef PFN_MAX #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 void __init
setup_arch(char **cmdline_p) setup_arch(char **cmdline_p)
{ {
...@@ -574,7 +530,16 @@ setup_arch(char **cmdline_p) ...@@ -574,7 +530,16 @@ setup_arch(char **cmdline_p)
continue; continue;
} }
if (strncmp(p, "srmcons", 7) == 0) { 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; continue;
} }
} }
...@@ -585,6 +550,13 @@ setup_arch(char **cmdline_p) ...@@ -585,6 +550,13 @@ setup_arch(char **cmdline_p)
/* If we want SRM console printk echoing early, do it now. */ /* If we want SRM console printk echoing early, do it now. */
if (alpha_using_srm && srmcons_output) { if (alpha_using_srm && srmcons_output) {
register_srm_console(); 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 #ifdef CONFIG_MAGIC_SYSRQ
...@@ -688,6 +660,15 @@ setup_arch(char **cmdline_p) ...@@ -688,6 +660,15 @@ setup_arch(char **cmdline_p)
paging_init(); 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 sys_unknown[] = "Unknown";
static char systype_names[][16] = { static char systype_names[][16] = {
"0", "0",
......
...@@ -544,9 +544,6 @@ smp_prepare_cpus(unsigned int max_cpus) ...@@ -544,9 +544,6 @@ smp_prepare_cpus(unsigned int max_cpus)
smp_tune_scheduling(boot_cpuid); smp_tune_scheduling(boot_cpuid);
smp_setup_percpu_timer(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. */ /* Nothing to do on a UP box, or when told not to. */
if (smp_num_probed == 1 || max_cpus == 0) { if (smp_num_probed == 1 || max_cpus == 0) {
cpu_present_mask = 1UL << boot_cpuid; cpu_present_mask = 1UL << boot_cpuid;
...@@ -574,7 +571,11 @@ smp_prepare_cpus(unsigned int max_cpus) ...@@ -574,7 +571,11 @@ smp_prepare_cpus(unsigned int max_cpus)
void __devinit void __devinit
smp_prepare_boot_cpu(void) 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_present_mask);
set_bit(smp_processor_id(), &cpu_online_map);
} }
int __devinit int __devinit
......
/*
* 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;
}
}
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/reboot.h> #include <linux/reboot.h>
#include <linux/bootmem.h>
#include <asm/ptrace.h> #include <asm/ptrace.h>
#include <asm/system.h> #include <asm/system.h>
...@@ -163,7 +164,7 @@ nautilus_machine_check(unsigned long vector, unsigned long la_ptr, ...@@ -163,7 +164,7 @@ nautilus_machine_check(unsigned long vector, unsigned long la_ptr,
} }
printk(KERN_CRIT "NAUTILUS Machine check 0x%lx " printk(KERN_CRIT "NAUTILUS Machine check 0x%lx "
"[%s System Machine Check (NMI)]\n", "[%s System Machine Check (NMI)]\n",
vector, mchk_class); vector, mchk_class);
naut_sys_machine_check(vector, la_ptr, regs); naut_sys_machine_check(vector, la_ptr, regs);
...@@ -174,6 +175,70 @@ nautilus_machine_check(unsigned long vector, unsigned long la_ptr, ...@@ -174,6 +175,70 @@ nautilus_machine_check(unsigned long vector, unsigned long la_ptr,
mb(); 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 * The System Vectors
...@@ -196,7 +261,7 @@ struct alpha_machine_vector nautilus_mv __initmv = { ...@@ -196,7 +261,7 @@ struct alpha_machine_vector nautilus_mv __initmv = {
.init_arch = irongate_init_arch, .init_arch = irongate_init_arch,
.init_irq = nautilus_init_irq, .init_irq = nautilus_init_irq,
.init_rtc = common_init_rtc, .init_rtc = common_init_rtc,
.init_pci = common_init_pci, .init_pci = nautilus_init_pci,
.kill_arch = nautilus_kill_arch, .kill_arch = nautilus_kill_arch,
.pci_map_irq = nautilus_map_irq, .pci_map_irq = nautilus_map_irq,
.pci_swizzle = common_swizzle, .pci_swizzle = common_swizzle,
......
...@@ -383,21 +383,6 @@ time_init(void) ...@@ -383,21 +383,6 @@ time_init(void)
/* Startup the timer source. */ /* Startup the timer source. */
alpha_mv.init_rtc(); 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;
}
} }
/* /*
......
...@@ -50,13 +50,14 @@ typedef struct { ...@@ -50,13 +50,14 @@ typedef struct {
igcsr32 bacsr10; /* 0x40 - base address chip selects */ igcsr32 bacsr10; /* 0x40 - base address chip selects */
igcsr32 bacsr32; /* 0x44 - 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 rsrvd2[1]; /* 0x4C-0x4F reserved */
igcsr32 drammap; /* 0x50 - address mapping control */ igcsr32 drammap; /* 0x50 - address mapping control */
igcsr32 dramtm; /* 0x54 - timing, driver strength */ igcsr32 dramtm; /* 0x54 - timing, driver strength */
igcsr32 dramms; /* 0x58 - ECC, mode/status */ igcsr32 dramms; /* 0x58 - DRAM mode/status */
igcsr32 rsrvd3[1]; /* 0x5C-0x5F reserved */ igcsr32 rsrvd3[1]; /* 0x5C-0x5F reserved */
...@@ -73,7 +74,10 @@ typedef struct { ...@@ -73,7 +74,10 @@ typedef struct {
igcsr32 pciarb; /* 0x84 - PCI arbitration control */ igcsr32 pciarb; /* 0x84 - PCI arbitration control */
igcsr32 pcicfg; /* 0x88 - PCI config status */ 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 */ /* AGP (bus 1) control registers */
igcsr32 agpcap; /* 0xA0 - AGP Capability Identifier */ igcsr32 agpcap; /* 0xA0 - AGP Capability Identifier */
...@@ -102,6 +106,7 @@ typedef struct { ...@@ -102,6 +106,7 @@ typedef struct {
} Irongate1; } Irongate1;
extern igcsr32 *IronECC;
/* /*
* Memory spaces: * Memory spaces:
......
...@@ -52,53 +52,25 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; ...@@ -52,53 +52,25 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
#define ELF_PLAT_INIT(_r) _r->r0 = 0 #define ELF_PLAT_INIT(_r) _r->r0 = 0
/* Use the same format as the OSF/1 procfs interface. The register /* The registers are layed out in pt_regs for PAL and syscall
layout is sane. However, since dump_thread() creates the funky convenience. Re-order them for the linear elf_gregset_t. */
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 extern void dump_elf_thread(elf_greg_t *dest, struct pt_regs *pt,
translation, then ELF_CORE_COPY_REGS() would become trivial and struct thread_info *ti);
faster. */ #define ELF_CORE_COPY_REGS(DEST, REGS) \
dump_elf_thread(DEST, REGS, current_thread_info());
#define ELF_CORE_COPY_REGS(_dest,_regs) \
{ \ /* Similar, but for a thread other than current. */
extern void dump_thread(struct pt_regs *, struct user *); \
struct user _dump; \ extern int dump_elf_task(elf_greg_t *dest, struct task_struct *task);
\ #define ELF_CORE_COPY_TASK_REGS(TASK, DEST) \
dump_thread(_regs, &_dump); \ dump_elf_task(*(DEST), TASK)
_dest[ 0] = _dump.regs[EF_V0]; \
_dest[ 1] = _dump.regs[EF_T0]; \ /* Similar, but for the FP registers. */
_dest[ 2] = _dump.regs[EF_T1]; \
_dest[ 3] = _dump.regs[EF_T2]; \ extern int dump_elf_task_fp(elf_fpreg_t *dest, struct task_struct *task);
_dest[ 4] = _dump.regs[EF_T3]; \ #define ELF_CORE_COPY_FPREGS(TASK, DEST) \
_dest[ 5] = _dump.regs[EF_T4]; \ dump_elf_task_fp(*(DEST), TASK)
_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]; \
}
/* This yields a mask that user programs can use to figure out what /* This yields a mask that user programs can use to figure out what
instruction set this CPU supports. This is trivial on Alpha, instruction set this CPU supports. This is trivial on Alpha,
......
...@@ -43,6 +43,9 @@ static inline int node_to_cpumask(int node) ...@@ -43,6 +43,9 @@ static inline int node_to_cpumask(int node)
# define node_to_memblk(node) (node) # define node_to_memblk(node) (node)
# define memblk_to_node(memblk) (memblk) # define memblk_to_node(memblk) (memblk)
/* Cross-node load balancing interval. */
# define NODE_BALANCE_RATE 10
#else /* CONFIG_NUMA */ #else /* CONFIG_NUMA */
# include <asm-generic/topology.h> # include <asm-generic/topology.h>
#endif /* !CONFIG_NUMA */ #endif /* !CONFIG_NUMA */
......
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