Commit 0f4d7d65 authored by Paul Mackerras's avatar Paul Mackerras

Merge samba.org:/home/paulus/kernel/linux-2.5

into samba.org:/home/paulus/kernel/for-linus-ppc
parents e9cdd788 9a692aef
...@@ -75,7 +75,7 @@ static int _cvt(unsigned long val, char *buf, long radix, char *digits); ...@@ -75,7 +75,7 @@ static int _cvt(unsigned long val, char *buf, long radix, char *digits);
void _vprintk(void(*putc)(const char), const char *fmt0, va_list ap); void _vprintk(void(*putc)(const char), const char *fmt0, va_list ap);
unsigned char *ISA_io = NULL; unsigned char *ISA_io = NULL;
#if defined(CONFIG_SERIAL_CONSOLE) #if defined(CONFIG_SERIAL_CONSOLE) || defined(CONFIG_SERIAL_8250_CONSOLE)
extern unsigned long com_port; extern unsigned long com_port;
extern int serial_tstc(unsigned long com_port); extern int serial_tstc(unsigned long com_port);
...@@ -96,7 +96,7 @@ void exit(void) ...@@ -96,7 +96,7 @@ void exit(void)
int tstc(void) int tstc(void)
{ {
#if defined(CONFIG_SERIAL_CONSOLE) #if defined(CONFIG_SERIAL_CONSOLE) || defined(CONFIG_SERIAL_8250_CONSOLE)
if(keyb_present) if(keyb_present)
return (CRT_tstc() || serial_tstc(com_port)); return (CRT_tstc() || serial_tstc(com_port));
else else
...@@ -109,10 +109,10 @@ int tstc(void) ...@@ -109,10 +109,10 @@ int tstc(void)
int getc(void) int getc(void)
{ {
while (1) { while (1) {
#if defined(CONFIG_SERIAL_CONSOLE) #if defined(CONFIG_SERIAL_CONSOLE) || defined(CONFIG_SERIAL_8250_CONSOLE)
if (serial_tstc(com_port)) if (serial_tstc(com_port))
return (serial_getc(com_port)); return (serial_getc(com_port));
#endif /* CONFIG_SERIAL_CONSOLE */ #endif /* serial console */
if (keyb_present) if (keyb_present)
if(CRT_tstc()) if(CRT_tstc())
return (CRT_getc()); return (CRT_getc());
...@@ -124,11 +124,11 @@ putc(const char c) ...@@ -124,11 +124,11 @@ putc(const char c)
{ {
int x,y; int x,y;
#if defined(CONFIG_SERIAL_CONSOLE) #if defined(CONFIG_SERIAL_CONSOLE) || defined(CONFIG_SERIAL_8250_CONSOLE)
serial_putc(com_port, c); serial_putc(com_port, c);
if ( c == '\n' ) if ( c == '\n' )
serial_putc(com_port, '\r'); serial_putc(com_port, '\r');
#endif /* CONFIG_SERIAL_CONSOLE */ #endif /* serial console */
x = orig_x; x = orig_x;
y = orig_y; y = orig_y;
...@@ -171,10 +171,10 @@ void puts(const char *s) ...@@ -171,10 +171,10 @@ void puts(const char *s)
y = orig_y; y = orig_y;
while ( ( c = *s++ ) != '\0' ) { while ( ( c = *s++ ) != '\0' ) {
#if defined(CONFIG_SERIAL_CONSOLE) #if defined(CONFIG_SERIAL_CONSOLE) || defined(CONFIG_SERIAL_8250_CONSOLE)
serial_putc(com_port, c); serial_putc(com_port, c);
if ( c == '\n' ) serial_putc(com_port, '\r'); if ( c == '\n' ) serial_putc(com_port, '\r');
#endif /* CONFIG_SERIAL_CONSOLE */ #endif /* serial console */
if ( c == '\n' ) { if ( c == '\n' ) {
x = 0; x = 0;
......
...@@ -27,7 +27,7 @@ boot-y := head.o ../simple/legacy.o misc.o of1275.o \ ...@@ -27,7 +27,7 @@ boot-y := head.o ../simple/legacy.o misc.o of1275.o \
OBJCOPY_ARGS = -O elf32-powerpc OBJCOPY_ARGS = -O elf32-powerpc
LIBS = ../lib/zlib.a LIBS = ../lib/zlib.a
boot-$(CONFIG_SERIAL_CONSOLE) += ../common/ns16550.o boot-$($CONFIG_SERIAL_8250_CONSOLE) += ../common/ns16550.o
boot-$(CONFIG_VGA_CONSOLE) += vreset.o kbd.o boot-$(CONFIG_VGA_CONSOLE) += vreset.o kbd.o
EXTRA_TARGETS := $(boot-y) EXTRA_TARGETS := $(boot-y)
......
...@@ -56,9 +56,9 @@ unsigned long orig_MSR; ...@@ -56,9 +56,9 @@ unsigned long orig_MSR;
char *zimage_start; char *zimage_start;
int zimage_size; int zimage_size;
#if defined(CONFIG_SERIAL_CONSOLE) #if defined(CONFIG_SERIAL_8250_CONSOLE)
unsigned long com_port; unsigned long com_port;
#endif /* CONFIG_SERIAL_CONSOLE */ #endif /* CONFIG_SERIAL_8250_CONSOLE */
#ifdef CONFIG_VGA_CONSOLE #ifdef CONFIG_VGA_CONSOLE
char *vidmem = (char *)0xC00B8000; char *vidmem = (char *)0xC00B8000;
int lines = 25, cols = 80; int lines = 25, cols = 80;
...@@ -135,9 +135,9 @@ decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum, ...@@ -135,9 +135,9 @@ decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum,
unsigned int pci_viddid, pci_did, tulip_pci_base, tulip_base; unsigned int pci_viddid, pci_did, tulip_pci_base, tulip_base;
serial_fixups(); serial_fixups();
#if defined(CONFIG_SERIAL_CONSOLE) #if defined(CONFIG_SERIAL_8250_CONSOLE)
com_port = serial_init(0, NULL); com_port = serial_init(0, NULL);
#endif /* CONFIG_SERIAL_CONSOLE */ #endif /* CONFIG_SERIAL_8250_CONSOLE */
#if defined(CONFIG_VGA_CONSOLE) #if defined(CONFIG_VGA_CONSOLE)
vga_init((unsigned char *)0xC0000000); vga_init((unsigned char *)0xC0000000);
#endif /* CONFIG_VGA_CONSOLE */ #endif /* CONFIG_VGA_CONSOLE */
......
...@@ -136,9 +136,9 @@ boot-$(CONFIG_RPXLITE) += iic.o ...@@ -136,9 +136,9 @@ boot-$(CONFIG_RPXLITE) += iic.o
ifeq ($(CONFIG_SERIAL_CONSOLE),y) ifeq ($(CONFIG_SERIAL_CONSOLE),y)
boot-$(CONFIG_8xx) += m8xx_tty.o boot-$(CONFIG_8xx) += m8xx_tty.o
boot-$(CONFIG_8260) += m8260_tty.o boot-$(CONFIG_8260) += m8260_tty.o
boot-$(CONFIG_GT64260_CONSOLE) += gt64260_tty.o boot-$(CONFIG_GT64260_CONSOLE) += gt64260_tty.o
boot-$(CONFIG_SERIAL) += ../common/ns16550.o
endif endif
boot-$(CONFIG_SERIAL_8250_CONSOLE) += ../common/ns16550.o
EXTRA_TARGETS := $(boot-y) EXTRA_TARGETS := $(boot-y)
LIBS := ../lib/zlib.a LIBS := ../lib/zlib.a
......
...@@ -189,7 +189,7 @@ decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum) ...@@ -189,7 +189,7 @@ decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum)
unsigned char header_type; unsigned char header_type;
unsigned int bar0; unsigned int bar0;
#ifdef CONFIG_SERIAL_CONSOLE #ifdef CONFIG_SERIAL_8250_CONSOLE
/* Initialize the serial console port */ /* Initialize the serial console port */
com_port = serial_init(0, NULL); com_port = serial_init(0, NULL);
#endif #endif
......
...@@ -365,6 +365,10 @@ if [ "$CONFIG_ALL_PPC" = "y" ]; then ...@@ -365,6 +365,10 @@ if [ "$CONFIG_ALL_PPC" = "y" ]; then
bool 'Support for RTAS (RunTime Abstraction Services) in /proc' CONFIG_PPC_RTAS bool 'Support for RTAS (RunTime Abstraction Services) in /proc' CONFIG_PPC_RTAS
bool 'Support for PReP Residual Data' CONFIG_PREP_RESIDUAL bool 'Support for PReP Residual Data' CONFIG_PREP_RESIDUAL
dep_bool ' Support for reading of PReP Residual Data in /proc' CONFIG_PROC_PREPRESIDUAL $CONFIG_PREP_RESIDUAL dep_bool ' Support for reading of PReP Residual Data in /proc' CONFIG_PROC_PREPRESIDUAL $CONFIG_PREP_RESIDUAL
define_bool CONFIG_PPCBUG_NVRAM y
fi
if [ "$CONFIG_PPLUS" = "y" -o "$CONFIG_LOPEC" = "y" ]; then
bool 'Enable reading PPCBUG NVRAM during boot' CONFIG_PPCBUG_NVRAM
fi fi
bool 'Default bootloader kernel arguments' CONFIG_CMDLINE_BOOL bool 'Default bootloader kernel arguments' CONFIG_CMDLINE_BOOL
......
...@@ -35,6 +35,7 @@ obj-$(CONFIG_PCI) += pci.o ...@@ -35,6 +35,7 @@ obj-$(CONFIG_PCI) += pci.o
ifneq ($(CONFIG_PPC_ISERIES),y) ifneq ($(CONFIG_PPC_ISERIES),y)
obj-$(CONFIG_PCI) += pci-dma.o obj-$(CONFIG_PCI) += pci-dma.o
endif endif
obj-$(CONFIG_PPCBUG_NVRAM) += prep_nvram.o
obj-$(CONFIG_KGDB) += ppc-stub.o obj-$(CONFIG_KGDB) += ppc-stub.o
obj-$(CONFIG_SMP) += smp.o obj-$(CONFIG_SMP) += smp.o
obj-$(CONFIG_TAU) += temp.o obj-$(CONFIG_TAU) += temp.o
......
...@@ -178,15 +178,6 @@ setup_irq(unsigned int irq, struct irqaction * new) ...@@ -178,15 +178,6 @@ setup_irq(unsigned int irq, struct irqaction * new)
return 0; return 0;
} }
#if (defined(CONFIG_8xx) || defined(CONFIG_8260))
/* Name change so we can catch standard drivers that potentially mess up
* the internal interrupt controller on 8xx and 8260. Just bear with me,
* I don't like this either and I am searching a better solution. For
* now, this is what I need. -- Dan
*/
#define request_irq request_8xxirq
#endif
void free_irq(unsigned int irq, void* dev_id) void free_irq(unsigned int irq, void* dev_id)
{ {
irq_desc_t *desc; irq_desc_t *desc;
...@@ -212,11 +203,7 @@ void free_irq(unsigned int irq, void* dev_id) ...@@ -212,11 +203,7 @@ void free_irq(unsigned int irq, void* dev_id)
} }
spin_unlock_irqrestore(&desc->lock,flags); spin_unlock_irqrestore(&desc->lock,flags);
#ifdef CONFIG_SMP synchronize_irq(irq);
/* Wait to make sure it's not being used on another CPU */
while (desc->status & IRQ_INPROGRESS)
barrier();
#endif
irq_kfree(action); irq_kfree(action);
return; return;
} }
...@@ -289,8 +276,8 @@ int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *) ...@@ -289,8 +276,8 @@ int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *)
* *
* This function may be called from IRQ context. * This function may be called from IRQ context.
*/ */
void disable_irq_nosync(unsigned int irq) void disable_irq_nosync(unsigned int irq)
{ {
irq_desc_t *desc = irq_desc + irq; irq_desc_t *desc = irq_desc + irq;
unsigned long flags; unsigned long flags;
...@@ -320,12 +307,7 @@ int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *) ...@@ -320,12 +307,7 @@ int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *)
void disable_irq(unsigned int irq) void disable_irq(unsigned int irq)
{ {
disable_irq_nosync(irq); disable_irq_nosync(irq);
synchronize_irq(irq);
if (!local_irq_count(smp_processor_id())) {
do {
barrier();
} while (irq_desc[irq].status & IRQ_INPROGRESS);
}
} }
/** /**
...@@ -525,11 +507,10 @@ void ppc_irq_dispatch_handler(struct pt_regs *regs, int irq) ...@@ -525,11 +507,10 @@ void ppc_irq_dispatch_handler(struct pt_regs *regs, int irq)
} }
#ifndef CONFIG_PPC_ISERIES /* iSeries version is in iSeries_pic.c */ #ifndef CONFIG_PPC_ISERIES /* iSeries version is in iSeries_pic.c */
int do_IRQ(struct pt_regs *regs) void do_IRQ(struct pt_regs *regs)
{ {
int cpu = smp_processor_id();
int irq, first = 1; int irq, first = 1;
hardirq_enter( cpu ); irq_enter();
/* /*
* Every platform is required to implement ppc_md.get_irq. * Every platform is required to implement ppc_md.get_irq.
...@@ -546,11 +527,7 @@ int do_IRQ(struct pt_regs *regs) ...@@ -546,11 +527,7 @@ int do_IRQ(struct pt_regs *regs)
if (irq != -2 && first) if (irq != -2 && first)
/* That's not SMP safe ... but who cares ? */ /* That's not SMP safe ... but who cares ? */
ppc_spurious_interrupts++; ppc_spurious_interrupts++;
hardirq_exit( cpu ); irq_exit();
if (softirq_pending(cpu))
do_softirq();
return 1; /* lets ret_from_int know we can do checks */
} }
#endif /* CONFIG_PPC_ISERIES */ #endif /* CONFIG_PPC_ISERIES */
...@@ -582,262 +559,14 @@ void __init init_IRQ(void) ...@@ -582,262 +559,14 @@ void __init init_IRQ(void)
} }
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
unsigned char global_irq_holder = NO_PROC_ID; void synchronize_irq(unsigned int irq)
unsigned volatile long global_irq_lock; /* pendantic :long for set_bit--RR*/
atomic_t global_bh_count;
static void show(char * str)
{
int cpu = smp_processor_id();
printk("\n%s, CPU %d:\n", str, cpu);
printk("irq: [%d %d]\n",
local_irq_count(0),
local_irq_count(1));
printk("bh: %d [%d %d]\n",
atomic_read(&global_bh_count),
local_bh_count(0),
local_bh_count(1));
}
static inline void wait_on_bh(void)
{
int count = MAXCOUNT;
do {
if (!--count) {
show("wait_on_bh");
count = ~0;
}
/* nothing .. wait for the other bh's to go away */
} while (atomic_read(&global_bh_count) != 0);
}
static inline void wait_on_irq(int cpu)
{
int count = MAXCOUNT;
for (;;) {
/*
* Wait until all interrupts are gone. Wait
* for bottom half handlers unless we're
* already executing in one..
*/
if (!irqs_running())
if (local_bh_count(cpu) || !spin_is_locked(&global_bh_lock))
break;
/* Duh, we have to loop. Release the lock to avoid deadlocks */
clear_bit(0,&global_irq_lock);
for (;;) {
if (!--count) {
show("wait_on_irq");
count = ~0;
}
local_irq_enable();
/*
* We have to allow irqs to arrive between local_irq_enable and local_irq_disable
* Some cpus apparently won't cause the interrupt
* for several instructions. We hope that isync will
* catch this --Troy
*/
__asm__ __volatile__ ("isync");
local_irq_disable();
if (irqs_running())
continue;
if (global_irq_lock)
continue;
if (!local_bh_count(cpu) && spin_is_locked(&global_bh_lock))
continue;
if (!test_and_set_bit(0,&global_irq_lock))
break;
}
}
}
/*
* This is called when we want to synchronize with
* bottom half handlers. We need to wait until
* no other CPU is executing any bottom half handler.
*
* Don't wait if we're already running in an interrupt
* context or are inside a bh handler.
*/
void synchronize_bh(void)
{ {
if (atomic_read(&global_bh_count) && !in_interrupt()) /* is there anything to synchronize with? */
wait_on_bh(); if (!irq_desc[irq].action)
} return;
/*
* This is called when we want to synchronize with
* interrupts. We may for example tell a device to
* stop sending interrupts: but to make sure there
* are no interrupts that are executing on another
* CPU we need to call this function.
*/
void synchronize_irq(void)
{
if (irqs_running()) {
/* Stupid approach */
cli();
sti();
}
}
static inline void get_irqlock(int cpu)
{
unsigned int loops = MAXCOUNT;
if (test_and_set_bit(0,&global_irq_lock)) {
/* do we already hold the lock? */
if ((unsigned char) cpu == global_irq_holder)
return;
/* Uhhuh.. Somebody else got it. Wait.. */
do {
do {
if (loops-- == 0) {
printk("get_irqlock(%d) waiting, global_irq_holder=%d\n", cpu, global_irq_holder);
#ifdef CONFIG_XMON
xmon(0);
#endif
}
} while (test_bit(0,&global_irq_lock));
} while (test_and_set_bit(0,&global_irq_lock));
}
/*
* We also need to make sure that nobody else is running
* in an interrupt context.
*/
wait_on_irq(cpu);
/*
* Ok, finally..
*/
global_irq_holder = cpu;
}
/*
* A global "cli()" while in an interrupt context
* turns into just a local cli(). Interrupts
* should use spinlocks for the (very unlikely)
* case that they ever want to protect against
* each other.
*
* If we already have local interrupts disabled,
* this will not turn a local disable into a
* global one (problems with spinlocks: this makes
* save_flags+cli+sti usable inside a spinlock).
*/
void __global_cli(void)
{
unsigned long flags;
local_save_flags(flags);
if (flags & (1 << 15)) {
int cpu = smp_processor_id();
local_irq_disable();
if (!local_irq_count(cpu))
get_irqlock(cpu);
}
}
void __global_sti(void)
{
int cpu = smp_processor_id();
if (!local_irq_count(cpu))
release_irqlock(cpu);
local_irq_enable();
}
/*
* SMP flags value to restore to:
* 0 - global cli
* 1 - global sti
* 2 - local cli
* 3 - local sti
*/
unsigned long __global_save_flags(void)
{
int retval;
int local_enabled;
unsigned long flags;
local_save_flags(flags);
local_enabled = (flags >> 15) & 1;
/* default to local */
retval = 2 + local_enabled;
/* check for global flags if we're not in an interrupt */
if (!local_irq_count(smp_processor_id())) {
if (local_enabled)
retval = 1;
if (global_irq_holder == (unsigned char) smp_processor_id())
retval = 0;
}
return retval;
}
int
tb(long vals[],
int max_size)
{
register unsigned long *orig_sp __asm__ ("r1");
register unsigned long lr __asm__ ("r3");
unsigned long *sp;
int i;
asm volatile ("mflr 3");
vals[0] = lr;
sp = (unsigned long *) *orig_sp;
sp = (unsigned long *) *sp;
for (i=1; i<max_size; i++) {
if (sp == 0) {
break;
}
vals[i] = *(sp+1);
sp = (unsigned long *) *sp;
}
return i;
}
void __global_restore_flags(unsigned long flags) while (irq_desc[irq].status & IRQ_INPROGRESS)
{ barrier();
switch (flags) {
case 0:
__global_cli();
break;
case 1:
__global_sti();
break;
case 2:
local_irq_disable();
break;
case 3:
local_irq_enable();
break;
default:
{
unsigned long trace[5];
int count;
int i;
printk("global_restore_flags: %08lx (%08lx)\n",
flags, (&flags)[-1]);
count = tb(trace, 5);
printk("tb:");
for(i=0; i<count; i++) {
printk(" %8.8lx", trace[i]);
}
printk("\n");
}
}
} }
#endif /* CONFIG_SMP */ #endif /* CONFIG_SMP */
......
...@@ -381,47 +381,6 @@ static ssize_t ppc_htab_write(struct file * file, const char * buffer, ...@@ -381,47 +381,6 @@ static ssize_t ppc_htab_write(struct file * file, const char * buffer,
} }
} }
return count;
#if 0 /* resizing htab is a bit difficult right now -- Cort */
unsigned long size;
extern void reset_SDR1(void);
/* only know how to set size right now */
if ( strncmp( buffer, "size ", 5) )
return -EINVAL;
size = simple_strtoul( &buffer[5], NULL, 10 );
/* only allow to shrink */
if ( size >= Hash_size>>10 )
return -EINVAL;
/* minimum size of htab */
if ( size < 64 )
return -EINVAL;
/* make sure it's a multiple of 64k */
if ( size % 64 )
return -EINVAL;
printk("Hash table resize to %luk\n", size);
/*
* We need to rehash all kernel entries for the new htab size.
* Kernel only since we do a flush_tlb_all(). Since it's kernel
* we only need to bother with vsids 0-15. To avoid problems of
* clobbering un-rehashed values we put the htab at a new spot
* and put everything there.
* -- Cort
*/
Hash_size = size<<10;
Hash_mask = (Hash_size >> 6) - 1;
_SDR1 = __pa(Hash) | (Hash_mask >> 10);
flush_tlb_all();
reset_SDR1();
#endif
return count; return count;
#else /* CONFIG_PPC_STD_MMU */ #else /* CONFIG_PPC_STD_MMU */
return 0; return 0;
......
...@@ -207,12 +207,6 @@ EXPORT_SYMBOL(last_task_used_altivec); ...@@ -207,12 +207,6 @@ EXPORT_SYMBOL(last_task_used_altivec);
EXPORT_SYMBOL(giveup_altivec); EXPORT_SYMBOL(giveup_altivec);
#endif /* CONFIG_ALTIVEC */ #endif /* CONFIG_ALTIVEC */
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
EXPORT_SYMBOL(global_irq_lock);
EXPORT_SYMBOL(global_irq_holder);
EXPORT_SYMBOL(__global_cli);
EXPORT_SYMBOL(__global_sti);
EXPORT_SYMBOL(__global_save_flags);
EXPORT_SYMBOL(__global_restore_flags);
#ifdef CONFIG_DEBUG_SPINLOCK #ifdef CONFIG_DEBUG_SPINLOCK
EXPORT_SYMBOL(_raw_spin_lock); EXPORT_SYMBOL(_raw_spin_lock);
EXPORT_SYMBOL(_raw_spin_unlock); EXPORT_SYMBOL(_raw_spin_unlock);
......
...@@ -2,9 +2,14 @@ ...@@ -2,9 +2,14 @@
* BK Id: %F% %I% %G% %U% %#% * BK Id: %F% %I% %G% %U% %#%
*/ */
/* /*
* arch/ppc/platforms/prep_nvram.c * arch/ppc/kernel/prep_nvram.c
* *
* Copyright (C) 1998 Corey Minyard * Copyright (C) 1998 Corey Minyard
*
* This reads the NvRAM on PReP compliant machines (generally from IBM or
* Motorola). Motorola kept the format of NvRAM in their ROM, PPCBUG, the
* same, long after they had stopped producing PReP compliant machines. So
* this code is useful in those cases as well.
* *
*/ */
#include <linux/init.h> #include <linux/init.h>
......
...@@ -202,8 +202,7 @@ void __switch_to(struct task_struct *prev, struct task_struct *new) ...@@ -202,8 +202,7 @@ void __switch_to(struct task_struct *prev, struct task_struct *new)
struct thread_struct *new_thread, *old_thread; struct thread_struct *new_thread, *old_thread;
unsigned long s; unsigned long s;
local_save_flags(s); local_irq_save(s);
local_irq_disable();
#if CHECK_STACK #if CHECK_STACK
check_stack(prev); check_stack(prev);
check_stack(new); check_stack(new);
......
...@@ -124,27 +124,27 @@ void TAUupdate(int cpu) ...@@ -124,27 +124,27 @@ void TAUupdate(int cpu)
void TAUException(struct pt_regs * regs) void TAUException(struct pt_regs * regs)
{ {
unsigned long cpu = smp_processor_id(); int cpu = smp_processor_id();
hardirq_enter(cpu); irq_enter();
tau[cpu].interrupts++; tau[cpu].interrupts++;
TAUupdate(cpu); TAUupdate(cpu);
hardirq_exit(cpu); irq_exit();
return;
} }
#endif /* CONFIG_TAU_INT */ #endif /* CONFIG_TAU_INT */
static void tau_timeout(void * info) static void tau_timeout(void * info)
{ {
unsigned long cpu = smp_processor_id(); int cpu;
unsigned long flags; unsigned long flags;
int size; int size;
int shrink; int shrink;
/* disabling interrupts *should* be okay */ /* disabling interrupts *should* be okay */
save_flags(flags); cli(); local_irq_save(flags);
cpu = smp_processor_id();
#ifndef CONFIG_TAU_INT #ifndef CONFIG_TAU_INT
TAUupdate(cpu); TAUupdate(cpu);
...@@ -186,7 +186,7 @@ static void tau_timeout(void * info) ...@@ -186,7 +186,7 @@ static void tau_timeout(void * info)
*/ */
mtspr(SPRN_THRM3, THRM3_SITV(500*60) | THRM3_E); mtspr(SPRN_THRM3, THRM3_SITV(500*60) | THRM3_E);
restore_flags(flags); local_irq_restore(flags);
} }
static void tau_timeout_smp(unsigned long unused) static void tau_timeout_smp(unsigned long unused)
......
...@@ -75,7 +75,7 @@ u64 jiffies_64; ...@@ -75,7 +75,7 @@ u64 jiffies_64;
unsigned long disarm_decr[NR_CPUS]; unsigned long disarm_decr[NR_CPUS];
extern int do_sys_settimeofday(struct timeval *tv, struct timezone *tz); extern struct timezone sys_tz;
/* keep track of when we need to update the rtc */ /* keep track of when we need to update the rtc */
time_t last_rtc_update; time_t last_rtc_update;
...@@ -151,7 +151,7 @@ static inline void ppc_do_profile (unsigned long nip) ...@@ -151,7 +151,7 @@ static inline void ppc_do_profile (unsigned long nip)
* with interrupts disabled. * with interrupts disabled.
* We set it up to overflow again in 1/HZ seconds. * We set it up to overflow again in 1/HZ seconds.
*/ */
int timer_interrupt(struct pt_regs * regs) void timer_interrupt(struct pt_regs * regs)
{ {
int next_dec; int next_dec;
unsigned long cpu = smp_processor_id(); unsigned long cpu = smp_processor_id();
...@@ -161,7 +161,7 @@ int timer_interrupt(struct pt_regs * regs) ...@@ -161,7 +161,7 @@ int timer_interrupt(struct pt_regs * regs)
if (atomic_read(&ppc_n_lost_interrupts) != 0) if (atomic_read(&ppc_n_lost_interrupts) != 0)
do_IRQ(regs); do_IRQ(regs);
hardirq_enter(cpu); irq_enter();
while ((next_dec = tb_ticks_per_jiffy - tb_delta(&jiffy_stamp)) < 0) { while ((next_dec = tb_ticks_per_jiffy - tb_delta(&jiffy_stamp)) < 0) {
jiffy_stamp += tb_ticks_per_jiffy; jiffy_stamp += tb_ticks_per_jiffy;
...@@ -214,12 +214,7 @@ int timer_interrupt(struct pt_regs * regs) ...@@ -214,12 +214,7 @@ int timer_interrupt(struct pt_regs * regs)
if (ppc_md.heartbeat && !ppc_md.heartbeat_count--) if (ppc_md.heartbeat && !ppc_md.heartbeat_count--)
ppc_md.heartbeat(); ppc_md.heartbeat();
hardirq_exit(cpu); irq_exit();
if (softirq_pending(cpu))
do_softirq();
return 1; /* lets ret_from_int know we can do checks */
} }
#endif /* CONFIG_PPC_ISERIES */ #endif /* CONFIG_PPC_ISERIES */
...@@ -358,14 +353,11 @@ void __init time_init(void) ...@@ -358,14 +353,11 @@ void __init time_init(void)
/* Not exact, but the timer interrupt takes care of this */ /* Not exact, but the timer interrupt takes care of this */
set_dec(tb_ticks_per_jiffy); set_dec(tb_ticks_per_jiffy);
/* If platform provided a timezone (pmac), we correct the time /* If platform provided a timezone (pmac), we correct the time */
* using do_sys_settimeofday() which in turn calls warp_clock()
*/
if (time_offset) { if (time_offset) {
struct timezone tz; sys_tz.tz_minuteswest = -time_offset / 60;
tz.tz_minuteswest = -time_offset / 60; sys_tz.tz_dsttime = 0;
tz.tz_dsttime = 0; xtime.tv_sec -= time_offset;
do_sys_settimeofday(NULL, &tz);
} }
} }
...@@ -373,6 +365,11 @@ void __init time_init(void) ...@@ -373,6 +365,11 @@ void __init time_init(void)
#define STARTOFTIME 1970 #define STARTOFTIME 1970
#define SECDAY 86400L #define SECDAY 86400L
#define SECYR (SECDAY * 365) #define SECYR (SECDAY * 365)
/*
* Note: this is wrong for 2100, but our signed 32-bit time_t will
* have overflowed long before that, so who cares. -- paulus
*/
#define leapyear(year) ((year) % 4 == 0) #define leapyear(year) ((year) % 4 == 0)
#define days_in_year(a) (leapyear(a) ? 366 : 365) #define days_in_year(a) (leapyear(a) ? 366 : 365)
#define days_in_month(a) (month_days[(a) - 1]) #define days_in_month(a) (month_days[(a) - 1])
......
...@@ -189,16 +189,18 @@ void do_page_fault(struct pt_regs *regs, unsigned long address, ...@@ -189,16 +189,18 @@ void do_page_fault(struct pt_regs *regs, unsigned long address,
*/ */
survive: survive:
switch (handle_mm_fault(mm, vma, address, is_write)) { switch (handle_mm_fault(mm, vma, address, is_write)) {
case 1: case VM_FAULT_MINOR:
current->min_flt++; current->min_flt++;
break; break;
case 2: case VM_FAULT_MAJOR:
current->maj_flt++; current->maj_flt++;
break; break;
case 0: case VM_FAULT_SIGBUS:
goto do_sigbus; goto do_sigbus;
default: case VM_FAULT_OOM:
goto out_of_memory; goto out_of_memory;
default:
BUG();
} }
up_read(&mm->mmap_sem); up_read(&mm->mmap_sem);
......
...@@ -25,7 +25,6 @@ ...@@ -25,7 +25,6 @@
#include <asm/tlbflush.h> #include <asm/tlbflush.h>
extern void mapin_ram(void); extern void mapin_ram(void);
extern void bat_mapin_ram(void);
extern int map_page(unsigned long va, unsigned long pa, int flags); extern int map_page(unsigned long va, unsigned long pa, int flags);
extern void setbat(int index, unsigned long virt, unsigned long phys, extern void setbat(int index, unsigned long virt, unsigned long phys,
unsigned int size, int flags); unsigned int size, int flags);
...@@ -49,14 +48,17 @@ extern unsigned long Hash_size, Hash_mask; ...@@ -49,14 +48,17 @@ extern unsigned long Hash_size, Hash_mask;
#if defined(CONFIG_8xx) #if defined(CONFIG_8xx)
#define flush_HPTE(X, va, pg) _tlbie(va) #define flush_HPTE(X, va, pg) _tlbie(va)
#define MMU_init_hw() do { } while(0) #define MMU_init_hw() do { } while(0)
#define mmu_mapin_ram() (0UL)
#elif defined(CONFIG_4xx) #elif defined(CONFIG_4xx)
#define flush_HPTE(X, va, pg) _tlbie(va) #define flush_HPTE(X, va, pg) _tlbie(va)
extern void MMU_init_hw(void); extern void MMU_init_hw(void);
#define mmu_mapin_ram() (0UL)
#else #else
/* anything except 4xx or 8xx */ /* anything except 4xx or 8xx */
extern void MMU_init_hw(void); extern void MMU_init_hw(void);
extern unsigned long mmu_mapin_ram(void);
/* Be careful....this needs to be updated if we ever encounter 603 SMPs, /* Be careful....this needs to be updated if we ever encounter 603 SMPs,
* which includes all new 82xx processors. We need tlbie/tlbsync here * which includes all new 82xx processors. We need tlbie/tlbsync here
......
...@@ -252,31 +252,14 @@ void __init mapin_ram(void) ...@@ -252,31 +252,14 @@ void __init mapin_ram(void)
{ {
unsigned long v, p, s, f; unsigned long v, p, s, f;
#ifdef HAVE_BATS s = mmu_mapin_ram();
if (!__map_without_bats) v = KERNELBASE + s;
bat_mapin_ram(); p = PPC_MEMSTART + s;
#endif /* HAVE_BATS */ for (; s < total_lowmem; s += PAGE_SIZE) {
if ((char *) v >= _stext && (char *) v < etext)
v = KERNELBASE; f = _PAGE_RAM_TEXT;
p = PPC_MEMSTART;
for (s = 0; s < total_lowmem; s += PAGE_SIZE) {
/* On the MPC8xx, we want the page shared so we
* don't get ASID compares on kernel space.
*/
f = _PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_SHARED | _PAGE_HWEXEC;
#if defined(CONFIG_KGDB) || defined(CONFIG_XMON)
/* Allows stub to set breakpoints everywhere */
f |= _PAGE_WRENABLE;
#else /* !CONFIG_KGDB && !CONFIG_XMON */
if ((char *) v < _stext || (char *) v >= etext)
f |= _PAGE_WRENABLE;
#ifdef CONFIG_PPC_STD_MMU
else else
/* On the powerpc (not all), no user access f = _PAGE_RAM;
forces R/W kernel access */
f |= _PAGE_USER;
#endif /* CONFIG_PPC_STD_MMU */
#endif /* CONFIG_KGDB || CONFIG_XMON */
map_page(v, p, f); map_page(v, p, f);
v += PAGE_SIZE; v += PAGE_SIZE;
p += PAGE_SIZE; p += PAGE_SIZE;
......
...@@ -87,12 +87,15 @@ unsigned long p_mapped_by_bats(unsigned long pa) ...@@ -87,12 +87,15 @@ unsigned long p_mapped_by_bats(unsigned long pa)
return 0; return 0;
} }
void __init bat_mapin_ram(void) unsigned long __init mmu_mapin_ram(void)
{ {
unsigned long tot, bl, done; unsigned long tot, bl, done;
unsigned long max_size = (256<<20); unsigned long max_size = (256<<20);
unsigned long align; unsigned long align;
if (__map_without_bats)
return 0;
/* Set up BAT2 and if necessary BAT3 to cover RAM. */ /* Set up BAT2 and if necessary BAT3 to cover RAM. */
/* Make sure we don't map a block larger than the /* Make sure we don't map a block larger than the
...@@ -119,7 +122,10 @@ void __init bat_mapin_ram(void) ...@@ -119,7 +122,10 @@ void __init bat_mapin_ram(void)
break; break;
setbat(3, KERNELBASE+done, PPC_MEMSTART+done, bl, setbat(3, KERNELBASE+done, PPC_MEMSTART+done, bl,
_PAGE_KERNEL); _PAGE_KERNEL);
done = (unsigned long)bat_addrs[3].limit - KERNELBASE + 1;
} }
return done;
} }
/* /*
......
...@@ -31,13 +31,42 @@ ...@@ -31,13 +31,42 @@
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/highmem.h> #include <linux/highmem.h>
#include <asm/tlbflush.h>
#include <asm/tlb.h>
#include "mmu_decl.h" #include "mmu_decl.h"
/*
* Called when unmapping pages to flush entries from the TLB/hash table.
*/
void flush_hash_entry(struct mm_struct *mm, pte_t *ptep, unsigned long addr)
{
unsigned long ptephys;
if (Hash != 0) {
ptephys = __pa(ptep) & PAGE_MASK;
flush_hash_pages(mm->context, addr, ptephys, 1);
}
}
/*
* Called at the end of a mmu_gather operation to make sure the
* TLB flush is completely done.
*/
void tlb_flush(mmu_gather_t *tlb)
{
if (Hash == 0) {
/*
* 603 needs to flush the whole TLB here since
* it doesn't use a hash table.
*/
_tlbia();
}
}
/* /*
* TLB flushing: * TLB flushing:
* *
* - flush_tlb_all() flushes all processes TLBs
* - flush_tlb_mm(mm) flushes the specified mm context TLB's * - flush_tlb_mm(mm) flushes the specified mm context TLB's
* - flush_tlb_page(vma, vmaddr) flushes one page * - flush_tlb_page(vma, vmaddr) flushes one page
* - flush_tlb_range(vma, start, end) flushes a range of pages * - flush_tlb_range(vma, start, end) flushes a range of pages
...@@ -91,29 +120,6 @@ static void flush_range(struct mm_struct *mm, unsigned long start, ...@@ -91,29 +120,6 @@ static void flush_range(struct mm_struct *mm, unsigned long start,
} }
} }
/*
* Flush all tlb/hash table entries (except perhaps for those
* mapping RAM starting at PAGE_OFFSET, since they never change).
*/
void
flush_tlb_all(void)
{
/*
* Just flush the kernel part of the address space, that's
* all that the current callers of this require.
* Eventually I hope to persuade the powers that be that
* we can and should dispense with flush_tlb_all().
* -- paulus.
*
* In fact this should never get called now that we
* have flush_tlb_kernel_range. -- paulus
*/
printk(KERN_ERR "flush_tlb_all called from %p\n",
__builtin_return_address(0));
flush_range(&init_mm, TASK_SIZE, ~0UL);
FINISH_FLUSH;
}
/* /*
* Flush kernel TLB entries in the given range * Flush kernel TLB entries in the given range
*/ */
...@@ -124,24 +130,19 @@ void flush_tlb_kernel_range(unsigned long start, unsigned long end) ...@@ -124,24 +130,19 @@ void flush_tlb_kernel_range(unsigned long start, unsigned long end)
} }
/* /*
* Flush all the (user) entries for the address space described * Flush all the (user) entries for the address space described by mm.
* by mm. We can't rely on mm->mmap describing all the entries
* that might be in the hash table.
*/ */
void flush_tlb_mm(struct mm_struct *mm) void flush_tlb_mm(struct mm_struct *mm)
{ {
struct vm_area_struct *mp;
if (Hash == 0) { if (Hash == 0) {
_tlbia(); _tlbia();
return; return;
} }
if (mm->map_count) { for (mp = mm->mmap; mp != NULL; mp = mp->vm_next)
struct vm_area_struct *mp; flush_range(mp->vm_mm, mp->vm_start, mp->vm_end);
for (mp = mm->mmap; mp != NULL; mp = mp->vm_next)
flush_range(mp->vm_mm, mp->vm_start, mp->vm_end);
} else {
flush_range(mm, 0, TASK_SIZE);
}
FINISH_FLUSH; FINISH_FLUSH;
} }
...@@ -161,7 +162,6 @@ void flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr) ...@@ -161,7 +162,6 @@ void flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr)
FINISH_FLUSH; FINISH_FLUSH;
} }
/* /*
* For each address in the range, find the pte for the address * For each address in the range, find the pte for the address
* and check _PAGE_HASHPTE bit; if it is set, find and destroy * and check _PAGE_HASHPTE bit; if it is set, find and destroy
......
...@@ -32,7 +32,7 @@ endif ...@@ -32,7 +32,7 @@ endif
obj-$(CONFIG_ALL_PPC) += pmac_pic.o pmac_setup.o pmac_time.o \ obj-$(CONFIG_ALL_PPC) += pmac_pic.o pmac_setup.o pmac_time.o \
pmac_feature.o pmac_pci.o chrp_setup.o\ pmac_feature.o pmac_pci.o chrp_setup.o\
chrp_time.o chrp_pci.o prep_pci.o \ chrp_time.o chrp_pci.o prep_pci.o \
prep_time.o prep_nvram.o prep_setup.o prep_time.o prep_setup.o
ifeq ($(CONFIG_ALL_PPC),y) ifeq ($(CONFIG_ALL_PPC),y)
obj-$(CONFIG_NVRAM) += pmac_nvram.o obj-$(CONFIG_NVRAM) += pmac_nvram.o
endif endif
...@@ -50,7 +50,7 @@ obj-$(CONFIG_MENF1) += menf1_setup.o menf1_pci.o ...@@ -50,7 +50,7 @@ obj-$(CONFIG_MENF1) += menf1_setup.o menf1_pci.o
obj-$(CONFIG_MVME5100) += mvme5100_setup.o mvme5100_pci.o obj-$(CONFIG_MVME5100) += mvme5100_setup.o mvme5100_pci.o
obj-$(CONFIG_PCORE) += pcore_setup.o pcore_pci.o obj-$(CONFIG_PCORE) += pcore_setup.o pcore_pci.o
obj-$(CONFIG_POWERPMC250) += powerpmc250.o obj-$(CONFIG_POWERPMC250) += powerpmc250.o
obj-$(CONFIG_PPLUS) += pplus_pci.o pplus_setup.o prep_nvram.o obj-$(CONFIG_PPLUS) += pplus_pci.o pplus_setup.o
obj-$(CONFIG_PRPMC750) += prpmc750_setup.o prpmc750_pci.o obj-$(CONFIG_PRPMC750) += prpmc750_setup.o prpmc750_pci.o
obj-$(CONFIG_PRPMC800) += prpmc800_setup.o prpmc800_pci.o obj-$(CONFIG_PRPMC800) += prpmc800_setup.o prpmc800_pci.o
obj-$(CONFIG_SANDPOINT) += sandpoint_setup.o sandpoint_pci.o obj-$(CONFIG_SANDPOINT) += sandpoint_setup.o sandpoint_pci.o
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Author: Mark A. Greer * Author: Mark A. Greer
* mgreer@mvista.com * mgreer@mvista.com
* *
* Copyright 2000 MontaVista Software Inc. * Copyright 2000-2002 MontaVista Software Inc.
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the * under the terms of the GNU General Public License as published by the
...@@ -101,7 +101,7 @@ ...@@ -101,7 +101,7 @@
* UIC Exports... * UIC Exports...
*/ */
extern struct hw_interrupt_type cpc700_pic; extern struct hw_interrupt_type cpc700_pic;
extern unsigned int cpc700_irq_assigns[27][2]; extern unsigned int cpc700_irq_assigns[32][2];
extern void __init cpc700_init_IRQ(void); extern void __init cpc700_init_IRQ(void);
extern int cpc700_get_irq(struct pt_regs *); extern int cpc700_get_irq(struct pt_regs *);
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* mporter@mvista.com * mporter@mvista.com
* jpeters@mvista.com * jpeters@mvista.com
* *
* Copyright 2001 MontaVista Software Inc. * Copyright 2001-2002 MontaVista Software Inc.
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the * under the terms of the GNU General Public License as published by the
...@@ -168,7 +168,7 @@ cpc700_init_IRQ(void) ...@@ -168,7 +168,7 @@ cpc700_init_IRQ(void)
cpc700_pic_init_irq(i); cpc700_pic_init_irq(i);
} }
for (i = 20; i < 27; i++) { for (i = 20; i < 32; i++) {
irq_desc[i].handler = &cpc700_pic; irq_desc[i].handler = &cpc700_pic;
cpc700_pic_init_irq(i); cpc700_pic_init_irq(i);
} }
......
...@@ -42,7 +42,7 @@ extern void __no_lpq_restore_flags(unsigned long flags); ...@@ -42,7 +42,7 @@ extern void __no_lpq_restore_flags(unsigned long flags);
extern void iSeries_smp_message_recv( struct pt_regs * ); extern void iSeries_smp_message_recv( struct pt_regs * );
unsigned lpEvent_count = 0; unsigned lpEvent_count = 0;
int do_IRQ(struct pt_regs *regs) void do_IRQ(struct pt_regs *regs)
{ {
int cpu = smp_processor_id(); int cpu = smp_processor_id();
unsigned long flags; unsigned long flags;
...@@ -52,7 +52,7 @@ int do_IRQ(struct pt_regs *regs) ...@@ -52,7 +52,7 @@ int do_IRQ(struct pt_regs *regs)
if ( is_soft_enabled() ) if ( is_soft_enabled() )
BUG(); BUG();
hardirq_enter( cpu ); irq_enter();
paca = (struct Paca *)mfspr(SPRG1); paca = (struct Paca *)mfspr(SPRG1);
...@@ -65,21 +65,16 @@ int do_IRQ(struct pt_regs *regs) ...@@ -65,21 +65,16 @@ int do_IRQ(struct pt_regs *regs)
lpq = paca->lpQueuePtr; lpq = paca->lpQueuePtr;
if ( lpq ) { if ( lpq ) {
local_save_flags( flags ); local_irq_save(flags);
local_irq_disable();
lpEvent_count += ItLpQueue_process( lpq, regs ); lpEvent_count += ItLpQueue_process( lpq, regs );
local_irq_restore( flags ); local_irq_restore( flags );
} }
hardirq_exit( cpu ); irq_exit();
if ( paca->xLpPacaPtr->xDecrInt ) { if ( paca->xLpPacaPtr->xDecrInt ) {
paca->xLpPacaPtr->xDecrInt = 0; paca->xLpPacaPtr->xDecrInt = 0;
/* Signal a fake decrementer interrupt */ /* Signal a fake decrementer interrupt */
timer_interrupt( regs ); timer_interrupt( regs );
} }
if (softirq_pending(cpu))
do_softirq();
return 1; /* lets ret_from_int know we can do checks */
} }
...@@ -102,7 +102,7 @@ int timerRetEnabled = 0; ...@@ -102,7 +102,7 @@ int timerRetEnabled = 0;
int timerRetDisabled = 0; int timerRetDisabled = 0;
extern unsigned long iSeries_dec_value; extern unsigned long iSeries_dec_value;
int timer_interrupt(struct pt_regs * regs) void timer_interrupt(struct pt_regs * regs)
{ {
long next_dec; long next_dec;
struct Paca * paca; struct Paca * paca;
...@@ -117,7 +117,7 @@ int timer_interrupt(struct pt_regs * regs) ...@@ -117,7 +117,7 @@ int timer_interrupt(struct pt_regs * regs)
else else
timerRetDisabled++; timerRetDisabled++;
hardirq_enter(cpu); irq_enter();
if (!user_mode(regs)) if (!user_mode(regs))
ppc_do_profile(instruction_pointer(regs)); ppc_do_profile(instruction_pointer(regs));
...@@ -149,9 +149,5 @@ int timer_interrupt(struct pt_regs * regs) ...@@ -149,9 +149,5 @@ int timer_interrupt(struct pt_regs * regs)
paca->xLpPacaPtr->xDecrInt = 0; paca->xLpPacaPtr->xDecrInt = 0;
set_dec( (unsigned)next_dec ); set_dec( (unsigned)next_dec );
hardirq_exit(cpu); irq_exit();
if (softirq_pending(cpu))
do_softirq();
return 1;
} }
...@@ -33,8 +33,15 @@ ...@@ -33,8 +33,15 @@
#include <asm/bootinfo.h> #include <asm/bootinfo.h>
#include <asm/mpc10x.h> #include <asm/mpc10x.h>
#include <asm/hw_irq.h> #include <asm/hw_irq.h>
#include <asm/prep_nvram.h>
#include <asm/keyboard.h>
extern char saved_command_line[];
extern void lopec_find_bridges(void); extern void lopec_find_bridges(void);
extern int pckbd_translate(unsigned char scancode, unsigned char *keycode,
char raw_mode);
extern char pckbd_unexpected_up(unsigned char keycode);
extern unsigned char pckbd_sysrq_xlate[128];
/* /*
* Define all of the IRQ senses and polarities. Taken from the * Define all of the IRQ senses and polarities. Taken from the
...@@ -333,6 +340,21 @@ lopec_setup_arch(void) ...@@ -333,6 +340,21 @@ lopec_setup_arch(void)
#ifdef CONFIG_DUMMY_CONSOLE #ifdef CONFIG_DUMMY_CONSOLE
conswitchp = &dummy_con; conswitchp = &dummy_con;
#endif #endif
#ifdef CONFIG_PPCBUG_NVRAM
/* Read in NVRAM data */
init_prep_nvram();
/* if no bootargs, look in NVRAM */
if ( cmd_line[0] == '\0' ) {
char *bootargs;
bootargs = prep_nvram_get_var("bootargs");
if (bootargs != NULL) {
strcpy(cmd_line, bootargs);
/* again.. */
strcpy(saved_command_line, cmd_line);
}
}
#endif
} }
void __init void __init
...@@ -362,6 +384,14 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5, ...@@ -362,6 +384,14 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
ppc_md.find_end_of_memory = lopec_find_end_of_memory; ppc_md.find_end_of_memory = lopec_find_end_of_memory;
ppc_md.setup_io_mappings = lopec_map_io; ppc_md.setup_io_mappings = lopec_map_io;
#ifdef CONFIG_VT
ppc_md.kbd_translate = pckbd_translate;
ppc_md.kbd_unexpected_up = pckbd_unexpected_up;
#ifdef CONFIG_MAGIC_SYSRQ
ppc_md.ppc_kbd_sysrq_xlate = pckbd_sysrq_xlate;
#endif /* CONFIG_MAGIC_SYSRQ */
#endif /* CONFIG_VT */
ppc_md.time_init = todc_time_init; ppc_md.time_init = todc_time_init;
ppc_md.set_rtc_time = todc_set_rtc_time; ppc_md.set_rtc_time = todc_set_rtc_time;
ppc_md.get_rtc_time = todc_get_rtc_time; ppc_md.get_rtc_time = todc_get_rtc_time;
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* Cort Dougan, Johnnie Peters, Matt Porter, and * Cort Dougan, Johnnie Peters, Matt Porter, and
* Troy Benjegerdes. * Troy Benjegerdes.
* *
* Copyright 2001 MontaVista Software Inc. * Copyright 2001-2002 MontaVista Software Inc.
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the * under the terms of the GNU General Public License as published by the
...@@ -76,8 +76,9 @@ ...@@ -76,8 +76,9 @@
TODC_ALLOC(); TODC_ALLOC();
extern void pplus_setup_hose(void); extern char saved_command_line[];
extern void pplus_setup_hose(void);
extern void pplus_set_VIA_IDE_native(void); extern void pplus_set_VIA_IDE_native(void);
extern unsigned long loops_per_jiffy; extern unsigned long loops_per_jiffy;
...@@ -131,7 +132,8 @@ pplus_setup_arch(void) ...@@ -131,7 +132,8 @@ pplus_setup_arch(void)
ROOT_DEV = Root_SDA2; ROOT_DEV = Root_SDA2;
#endif #endif
printk("PowerPlus port (C) 2001 MontaVista Software, Inc. (source@mvista.com)\n"); printk(KERN_INFO "Motorola PowerPlus Platform\n");
printk(KERN_INFO "Port by MontaVista Software, Inc. (source@mvista.com)\n");
if ( ppc_md.progress ) if ( ppc_md.progress )
ppc_md.progress("pplus_setup_arch: raven_init\n", 0); ppc_md.progress("pplus_setup_arch: raven_init\n", 0);
...@@ -144,6 +146,21 @@ pplus_setup_arch(void) ...@@ -144,6 +146,21 @@ pplus_setup_arch(void)
conswitchp = &vga_con; conswitchp = &vga_con;
#elif defined(CONFIG_DUMMY_CONSOLE) #elif defined(CONFIG_DUMMY_CONSOLE)
conswitchp = &dummy_con; conswitchp = &dummy_con;
#endif
#ifdef CONFIG_PPCBUG_NVRAM
/* Read in NVRAM data */
init_prep_nvram();
/* if no bootargs, look in NVRAM */
if ( cmd_line[0] == '\0' ) {
char *bootargs;
bootargs = prep_nvram_get_var("bootargs");
if (bootargs != NULL) {
strcpy(cmd_line, bootargs);
/* again.. */
strcpy(saved_command_line, cmd_line);
}
}
#endif #endif
if ( ppc_md.progress ) if ( ppc_md.progress )
ppc_md.progress("pplus_setup_arch: exit\n", 0); ppc_md.progress("pplus_setup_arch: exit\n", 0);
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Authors: Johnnie Peters <jpeters@mvista.com> * Authors: Johnnie Peters <jpeters@mvista.com>
* Matt Porter <mporter@mvista.com> * Matt Porter <mporter@mvista.com>
* *
* Copyright 2001 MontaVista Software Inc. * Copyright 2001-2002 MontaVista Software Inc.
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the * under the terms of the GNU General Public License as published by the
...@@ -70,7 +70,7 @@ extern char cmd_line[]; ...@@ -70,7 +70,7 @@ extern char cmd_line[];
* *
* First entry is the sensitivity (level/edge), second is the polarity. * First entry is the sensitivity (level/edge), second is the polarity.
*/ */
unsigned int cpc700_irq_assigns[27][2] = { unsigned int cpc700_irq_assigns[32][2] = {
{ 1, 1 }, /* IRQ 0: ECC Correctable Error - rising edge */ { 1, 1 }, /* IRQ 0: ECC Correctable Error - rising edge */
{ 1, 1 }, /* IRQ 1: PCI Write Mem Range - rising edge */ { 1, 1 }, /* IRQ 1: PCI Write Mem Range - rising edge */
{ 0, 1 }, /* IRQ 2: PCI Write Command Reg - active high */ { 0, 1 }, /* IRQ 2: PCI Write Command Reg - active high */
......
...@@ -15,8 +15,6 @@ ...@@ -15,8 +15,6 @@
*/ */
typedef struct { typedef struct {
unsigned long __softirq_pending; /* set_bit is used on this */ unsigned long __softirq_pending; /* set_bit is used on this */
unsigned int __local_irq_count;
unsigned int __local_bh_count;
unsigned int __syscall_count; unsigned int __syscall_count;
struct task_struct * __ksoftirqd_task; struct task_struct * __ksoftirqd_task;
unsigned int __last_jiffy_stamp; unsigned int __last_jiffy_stamp;
...@@ -25,91 +23,87 @@ typedef struct { ...@@ -25,91 +23,87 @@ typedef struct {
#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */ #include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */
#define last_jiffy_stamp(cpu) __IRQ_STAT((cpu), __last_jiffy_stamp) #define last_jiffy_stamp(cpu) __IRQ_STAT((cpu), __last_jiffy_stamp)
/* /*
* Are we in an interrupt context? Either doing bottom half * We put the hardirq and softirq counter into the preemption
* or hardware interrupt processing? * counter. The bitmask has the following meaning:
*
* - bits 0-7 are the preemption count (max preemption depth: 256)
* - bits 8-15 are the softirq count (max # of softirqs: 256)
* - bits 16-23 are the hardirq count (max # of hardirqs: 256)
*
* - ( bit 26 is the PREEMPT_ACTIVE flag. )
*
* PREEMPT_MASK: 0x000000ff
* HARDIRQ_MASK: 0x0000ff00
* SOFTIRQ_MASK: 0x00ff0000
*/ */
#define in_interrupt() ({ int __cpu = smp_processor_id(); \
(local_irq_count(__cpu) + local_bh_count(__cpu) != 0); })
#define in_irq() (local_irq_count(smp_processor_id()) != 0)
#ifndef CONFIG_SMP #define PREEMPT_BITS 8
#define SOFTIRQ_BITS 8
#define HARDIRQ_BITS 8
#define hardirq_trylock(cpu) (local_irq_count(cpu) == 0) #define PREEMPT_SHIFT 0
#define hardirq_endlock(cpu) do { } while (0) #define SOFTIRQ_SHIFT (PREEMPT_SHIFT + PREEMPT_BITS)
#define HARDIRQ_SHIFT (SOFTIRQ_SHIFT + SOFTIRQ_BITS)
#define hardirq_enter(cpu) do { preempt_disable(); local_irq_count(cpu)++; } while (0) #define __MASK(x) ((1UL << (x))-1)
#define hardirq_exit(cpu) do { local_irq_count(cpu)--; preempt_enable(); } while (0)
#define synchronize_irq() do { } while (0) #define PREEMPT_MASK (__MASK(PREEMPT_BITS) << PREEMPT_SHIFT)
#define release_irqlock(cpu) do { } while (0) #define HARDIRQ_MASK (__MASK(HARDIRQ_BITS) << HARDIRQ_SHIFT)
#define SOFTIRQ_MASK (__MASK(SOFTIRQ_BITS) << SOFTIRQ_SHIFT)
#else /* CONFIG_SMP */ #define hardirq_count() (preempt_count() & HARDIRQ_MASK)
#define softirq_count() (preempt_count() & SOFTIRQ_MASK)
#define irq_count() (preempt_count() & (HARDIRQ_MASK | SOFTIRQ_MASK))
#include <asm/atomic.h> #define PREEMPT_OFFSET (1UL << PREEMPT_SHIFT)
#define SOFTIRQ_OFFSET (1UL << SOFTIRQ_SHIFT)
#define HARDIRQ_OFFSET (1UL << HARDIRQ_SHIFT)
extern unsigned char global_irq_holder; /*
extern unsigned volatile long global_irq_lock; * The hardirq mask has to be large enough to have
* space for potentially all IRQ sources in the system
* nesting on a single CPU:
*/
#if (1 << HARDIRQ_BITS) < NR_IRQS
# error HARDIRQ_BITS is too low!
#endif
static inline int irqs_running (void) /*
{ * Are we doing bottom half or hardware interrupt processing?
int i; * Are we in a softirq context? Interrupt context?
*/
#define in_irq() (hardirq_count())
#define in_softirq() (softirq_count())
#define in_interrupt() (irq_count())
for (i = 0; i < NR_CPUS; i++)
if (local_irq_count(i))
return 1;
return 0;
}
static inline void release_irqlock(int cpu) #define hardirq_trylock() (!in_interrupt())
{ #define hardirq_endlock() do { } while (0)
/* if we didn't own the irq lock, just ignore.. */
if (global_irq_holder == (unsigned char) cpu) {
global_irq_holder = NO_PROC_ID;
clear_bit(0,&global_irq_lock);
}
}
static inline void hardirq_enter(int cpu) #define irq_enter() (preempt_count() += HARDIRQ_OFFSET)
{
unsigned int loops = 10000000;
preempt_disable(); #if CONFIG_PREEMPT
++local_irq_count(cpu); # define IRQ_EXIT_OFFSET (HARDIRQ_OFFSET-1)
while (test_bit(0,&global_irq_lock)) { #else
if (cpu == global_irq_holder) { # define IRQ_EXIT_OFFSET HARDIRQ_OFFSET
printk("uh oh, interrupt while we hold global irq lock! (CPU %d)\n", cpu);
#ifdef CONFIG_XMON
xmon(0);
#endif #endif
break; #define irq_exit() \
} do { \
if (loops-- == 0) { preempt_count() -= IRQ_EXIT_OFFSET; \
printk("do_IRQ waiting for irq lock (holder=%d)\n", global_irq_holder); if (!in_interrupt() && softirq_pending(smp_processor_id())) \
#ifdef CONFIG_XMON do_softirq(); \
xmon(0); preempt_enable_no_resched(); \
#endif } while (0)
}
}
}
static inline void hardirq_exit(int cpu)
{
--local_irq_count(cpu);
preempt_enable();
}
static inline int hardirq_trylock(int cpu)
{
return !test_bit(0,&global_irq_lock);
}
#define hardirq_endlock(cpu) do { } while (0)
extern void synchronize_irq(void);
#ifndef CONFIG_SMP
# define synchronize_irq(irq) barrier()
#else
extern void synchronize_irq(unsigned int irq);
#endif /* CONFIG_SMP */ #endif /* CONFIG_SMP */
extern void show_stack(unsigned long *sp);
#endif /* __ASM_HARDIRQ_H */ #endif /* __ASM_HARDIRQ_H */
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */
...@@ -8,21 +8,18 @@ ...@@ -8,21 +8,18 @@
#ifndef _PPC_HW_IRQ_H #ifndef _PPC_HW_IRQ_H
#define _PPC_HW_IRQ_H #define _PPC_HW_IRQ_H
extern unsigned long timer_interrupt_intercept; extern void timer_interrupt(struct pt_regs *);
extern unsigned long do_IRQ_intercept;
extern int timer_interrupt(struct pt_regs *);
extern void ppc_irq_dispatch_handler(struct pt_regs *regs, int irq); extern void ppc_irq_dispatch_handler(struct pt_regs *regs, int irq);
#define INLINE_IRQS #define INLINE_IRQS
#ifdef INLINE_IRQS
#define mfmsr() ({unsigned int rval; \ #define mfmsr() ({unsigned int rval; \
asm volatile("mfmsr %0" : "=r" (rval)); rval;}) asm volatile("mfmsr %0" : "=r" (rval)); rval;})
#define mtmsr(v) asm volatile("mtmsr %0" : : "r" (v)) #define mtmsr(v) asm volatile("mtmsr %0" : : "r" (v))
#define local_save_flags(flags) ((flags) = mfmsr()) #define irqs_disabled() ((mfmsr() & MSR_EE) == 0)
#define local_irq_restore(flags) mtmsr(flags)
#ifdef INLINE_IRQS
static inline void local_irq_disable(void) static inline void local_irq_disable(void)
{ {
...@@ -40,7 +37,7 @@ static inline void local_irq_enable(void) ...@@ -40,7 +37,7 @@ static inline void local_irq_enable(void)
mtmsr(msr | MSR_EE); mtmsr(msr | MSR_EE);
} }
static inline void __do_save_and_cli(unsigned long *flags) static inline void local_irq_save_ptr(unsigned long *flags)
{ {
unsigned long msr; unsigned long msr;
msr = mfmsr(); msr = mfmsr();
...@@ -49,7 +46,9 @@ static inline void __do_save_and_cli(unsigned long *flags) ...@@ -49,7 +46,9 @@ static inline void __do_save_and_cli(unsigned long *flags)
__asm__ __volatile__("": : :"memory"); __asm__ __volatile__("": : :"memory");
} }
#define local_irq_save(flags) __do_save_and_cli(&flags) #define local_save_flags(flags) ((flags) = mfmsr())
#define local_irq_save(flags) local_irq_save_ptr(&flags)
#define local_irq_restore(flags) mtmsr(flags)
#else #else
...@@ -57,9 +56,8 @@ extern void local_irq_enable(void); ...@@ -57,9 +56,8 @@ extern void local_irq_enable(void);
extern void local_irq_disable(void); extern void local_irq_disable(void);
extern void local_irq_restore(unsigned long); extern void local_irq_restore(unsigned long);
extern void local_save_flags_ptr(unsigned long *); extern void local_save_flags_ptr(unsigned long *);
extern unsigned long local_irq_enable_end, local_irq_disable_end, local_irq_restore_end, local_save_flags_ptr_end;
#define local_save_flags(flags) local_save_flags_ptr((unsigned long *)&flags) #define local_save_flags(flags) local_save_flags_ptr(&flags)
#define local_irq_save(flags) ({local_save_flags(flags);local_irq_disable();}) #define local_irq_save(flags) ({local_save_flags(flags);local_irq_disable();})
#endif #endif
......
...@@ -246,6 +246,23 @@ extern unsigned long ioremap_bot, ioremap_base; ...@@ -246,6 +246,23 @@ extern unsigned long ioremap_bot, ioremap_base;
#define _PAGE_KERNEL _PAGE_BASE | _PAGE_WRENABLE | _PAGE_SHARED | _PAGE_HWEXEC #define _PAGE_KERNEL _PAGE_BASE | _PAGE_WRENABLE | _PAGE_SHARED | _PAGE_HWEXEC
#define _PAGE_IO _PAGE_KERNEL | _PAGE_NO_CACHE | _PAGE_GUARDED #define _PAGE_IO _PAGE_KERNEL | _PAGE_NO_CACHE | _PAGE_GUARDED
#define _PAGE_RAM _PAGE_KERNEL
#if defined(CONFIG_KGDB) || defined(CONFIG_XMON)
/* We want the debuggers to be able to set breakpoints anywhere, so
* don't write protect the kernel text */
#define _PAGE_RAM_TEXT _PAGE_RAM
#else
#ifdef CONFIG_PPC_STD_MMU
/* On standard PPC MMU, no user access implies kernel read/write
* access, so to write-protect the kernel text we must turn on user
* access */
#define _PAGE_RAM_TEXT (_PAGE_RAM & ~_PAGE_WRENABLE) | _PAGE_USER
#else
#define _PAGE_RAM_TEXT (_PAGE_RAM & ~_PAGE_WRENABLE)
#endif
#endif
#define PAGE_NONE __pgprot(_PAGE_BASE) #define PAGE_NONE __pgprot(_PAGE_BASE)
#define PAGE_READONLY __pgprot(_PAGE_BASE | _PAGE_USER) #define PAGE_READONLY __pgprot(_PAGE_BASE | _PAGE_USER)
#define PAGE_READONLY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC) #define PAGE_READONLY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
......
/* /*
* BK Id: SCCS/s.rwsem.h 1.6 05/17/01 18:14:25 cort * BK Id: %F% %I% %G% %U% %#%
*/ */
/* /*
* include/asm-ppc/rwsem.h: R/W semaphores for PPC using the stuff * include/asm-ppc/rwsem.h: R/W semaphores for PPC using the stuff
...@@ -55,6 +55,7 @@ struct rw_semaphore { ...@@ -55,6 +55,7 @@ struct rw_semaphore {
extern struct rw_semaphore *rwsem_down_read_failed(struct rw_semaphore *sem); extern struct rw_semaphore *rwsem_down_read_failed(struct rw_semaphore *sem);
extern struct rw_semaphore *rwsem_down_write_failed(struct rw_semaphore *sem); extern struct rw_semaphore *rwsem_down_write_failed(struct rw_semaphore *sem);
extern struct rw_semaphore *rwsem_wake(struct rw_semaphore *sem); extern struct rw_semaphore *rwsem_wake(struct rw_semaphore *sem);
extern struct rw_semaphore *rwsem_downgrade_wake(struct rw_semaphore *sem);
static inline void init_rwsem(struct rw_semaphore *sem) static inline void init_rwsem(struct rw_semaphore *sem)
{ {
...@@ -124,6 +125,19 @@ static inline void rwsem_atomic_add(int delta, struct rw_semaphore *sem) ...@@ -124,6 +125,19 @@ static inline void rwsem_atomic_add(int delta, struct rw_semaphore *sem)
atomic_add(delta, (atomic_t *)(&sem->count)); atomic_add(delta, (atomic_t *)(&sem->count));
} }
/*
* downgrade write lock to read lock
*/
static inline void __downgrade_write(struct rw_semaphore *sem)
{
int tmp;
smp_wmb();
tmp = atomic_add_return(-RWSEM_WAITING_BIAS, (atomic_t *)(&sem->count));
if (tmp < 0)
rwsem_downgrade_wake(sem);
}
/* /*
* implement exchange and add functionality * implement exchange and add functionality
*/ */
......
...@@ -18,7 +18,7 @@ extern spinlock_t kernel_flag; ...@@ -18,7 +18,7 @@ extern spinlock_t kernel_flag;
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
#define kernel_locked() spin_is_locked(&kernel_flag) #define kernel_locked() spin_is_locked(&kernel_flag)
#elif defined(CONFIG_PREEMPT) #elif defined(CONFIG_PREEMPT)
#define kernel_locked() preempt_get_count() #define kernel_locked() preempt_count()
#endif #endif
/* /*
......
...@@ -5,34 +5,30 @@ ...@@ -5,34 +5,30 @@
#ifndef __ASM_SOFTIRQ_H #ifndef __ASM_SOFTIRQ_H
#define __ASM_SOFTIRQ_H #define __ASM_SOFTIRQ_H
#include <asm/atomic.h> #include <linux/preempt.h>
#include <asm/hardirq.h> #include <asm/hardirq.h>
#define local_bh_disable() \ #define local_bh_disable() \
do { \ do { \
preempt_disable(); \ preempt_count() += SOFTIRQ_OFFSET; \
local_bh_count(smp_processor_id())++; \
barrier(); \ barrier(); \
} while (0) } while (0)
#define __local_bh_enable() \ #define __local_bh_enable() \
do { \ do { \
barrier(); \ barrier(); \
local_bh_count(smp_processor_id())--; \ preempt_count() -= SOFTIRQ_OFFSET; \
preempt_enable(); \
} while (0) } while (0)
#define local_bh_enable() \ #define local_bh_enable() \
do { \ do { \
barrier(); \ __local_bh_enable(); \
if (!--local_bh_count(smp_processor_id()) \ if (unlikely(!in_interrupt() \
&& softirq_pending(smp_processor_id())) { \ && softirq_pending(smp_processor_id()))) \
do_softirq(); \ do_softirq(); \
} \ if (preempt_count() == 0) \
preempt_enable(); \ preempt_check_resched(); \
} while (0) } while (0)
#define in_softirq() (local_bh_count(smp_processor_id()) != 0)
#endif /* __ASM_SOFTIRQ_H */ #endif /* __ASM_SOFTIRQ_H */
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */
...@@ -96,27 +96,6 @@ extern unsigned int rtas_data; ...@@ -96,27 +96,6 @@ extern unsigned int rtas_data;
struct pt_regs; struct pt_regs;
extern void dump_regs(struct pt_regs *); extern void dump_regs(struct pt_regs *);
#ifndef CONFIG_SMP
#define cli() local_irq_disable()
#define sti() local_irq_enable()
#define save_flags(flags) local_save_flags(flags)
#define restore_flags(flags) local_irq_restore(flags)
#define save_and_cli(flags) local_irq_save(flags)
#else /* CONFIG_SMP */
extern void __global_cli(void);
extern void __global_sti(void);
extern unsigned long __global_save_flags(void);
extern void __global_restore_flags(unsigned long);
#define cli() __global_cli()
#define sti() __global_sti()
#define save_flags(x) ((x)=__global_save_flags())
#define restore_flags(x) __global_restore_flags(x)
#endif /* !CONFIG_SMP */
static __inline__ unsigned long static __inline__ unsigned long
xchg_u32(volatile void *p, unsigned long val) xchg_u32(volatile void *p, unsigned long val)
{ {
......
...@@ -22,25 +22,25 @@ struct thread_info { ...@@ -22,25 +22,25 @@ struct thread_info {
struct exec_domain *exec_domain; /* execution domain */ struct exec_domain *exec_domain; /* execution domain */
unsigned long flags; /* low level flags */ unsigned long flags; /* low level flags */
int cpu; /* cpu we're on */ int cpu; /* cpu we're on */
int preempt_count; /* not used at present */ int preempt_count;
int softirq_count;
int hardirq_count;
}; };
/*
* macros/functions for gaining access to the thread information structure
*/
#define INIT_THREAD_INFO(tsk) \ #define INIT_THREAD_INFO(tsk) \
{ \ { \
task: &tsk, \ .task = &tsk, \
exec_domain: &default_exec_domain, \ .exec_domain = &default_exec_domain, \
flags: 0, \ .flags = 0, \
cpu: 0, \ .cpu = 0, \
.preempt_count = 1 \
} }
#define init_thread_info (init_thread_union.thread_info) #define init_thread_info (init_thread_union.thread_info)
#define init_stack (init_thread_union.stack) #define init_stack (init_thread_union.stack)
/*
* macros/functions for gaining access to the thread information structure
*/
/* how to get the thread information struct from C */ /* how to get the thread information struct from C */
static inline struct thread_info *current_thread_info(void) static inline struct thread_info *current_thread_info(void)
{ {
......
/* /*
* BK Id: SCCS/s.tlb.h 1.5 05/17/01 18:14:26 cort * TLB shootdown specifics for PPC
*
* Copyright (C) 2002 Paul Mackerras, IBM Corp.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/ */
#ifndef _PPC_TLB_H
#define _PPC_TLB_H
#include <linux/config.h>
#include <asm/pgtable.h>
#include <asm/pgalloc.h>
#include <asm/tlbflush.h>
#include <asm/page.h>
#include <asm/mmu.h>
#ifdef CONFIG_PPC_STD_MMU
/* Classic PPC with hash-table based MMU... */
struct free_pte_ctx;
extern void tlb_flush(struct free_pte_ctx *tlb);
/* Get the generic bits... */
#include <asm-generic/tlb.h> #include <asm-generic/tlb.h>
/* Nothing needed here in fact... */
#define tlb_start_vma(tlb, vma) do { } while (0)
#define tlb_end_vma(tlb, vma) do { } while (0)
extern void flush_hash_entry(struct mm_struct *mm, pte_t *ptep,
unsigned long address);
static inline void tlb_remove_tlb_entry(mmu_gather_t *tlb, pte_t *ptep,
unsigned long address)
{
if (pte_val(*ptep) & _PAGE_HASHPTE)
flush_hash_entry(tlb->mm, ptep, address);
}
#else
/* Embedded PPC with software-loaded TLB, very simple... */
struct flush_tlb_arch { };
#define tlb_init_arch(tlb, full_flush) do { } while (0)
#define tlb_finish_arch(tlb) do { } while (0)
#define tlb_start_vma(tlb, vma) do { } while (0)
#define tlb_end_vma(tlb, vma) do { } while (0)
#define tlb_remove_tlb_entry(tlb, pte, address) do { } while (0)
#define tlb_flush(tlb) flush_tlb_mm((tlb)->mm)
/* Get the generic bits... */
#include <asm-generic/tlb.h>
#endif /* CONFIG_PPC_STD_MMU */
#endif /* __PPC_TLB_H */
...@@ -22,8 +22,6 @@ extern void _tlbia(void); ...@@ -22,8 +22,6 @@ extern void _tlbia(void);
#if defined(CONFIG_4xx) #if defined(CONFIG_4xx)
static inline void flush_tlb_all(void)
{ _tlbia(); }
static inline void flush_tlb_mm(struct mm_struct *mm) static inline void flush_tlb_mm(struct mm_struct *mm)
{ _tlbia(); } { _tlbia(); }
static inline void flush_tlb_page(struct vm_area_struct *vma, static inline void flush_tlb_page(struct vm_area_struct *vma,
...@@ -40,8 +38,6 @@ static inline void flush_tlb_kernel_range(unsigned long start, ...@@ -40,8 +38,6 @@ static inline void flush_tlb_kernel_range(unsigned long start,
#elif defined(CONFIG_8xx) #elif defined(CONFIG_8xx)
#define __tlbia() asm volatile ("tlbia; sync" : : : "memory") #define __tlbia() asm volatile ("tlbia; sync" : : : "memory")
static inline void flush_tlb_all(void)
{ __tlbia(); }
static inline void flush_tlb_mm(struct mm_struct *mm) static inline void flush_tlb_mm(struct mm_struct *mm)
{ __tlbia(); } { __tlbia(); }
static inline void flush_tlb_page(struct vm_area_struct *vma, static inline void flush_tlb_page(struct vm_area_struct *vma,
...@@ -58,7 +54,6 @@ static inline void flush_tlb_kernel_range(unsigned long start, ...@@ -58,7 +54,6 @@ static inline void flush_tlb_kernel_range(unsigned long start,
#else /* 6xx, 7xx, 7xxx cpus */ #else /* 6xx, 7xx, 7xxx cpus */
struct mm_struct; struct mm_struct;
struct vm_area_struct; struct vm_area_struct;
extern void flush_tlb_all(void);
extern void flush_tlb_mm(struct mm_struct *mm); extern void flush_tlb_mm(struct mm_struct *mm);
extern void flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr); extern void flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr);
extern void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, extern void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
......
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