Update of /cvsroot/linux-vax/kernel-2.4/arch/m68k/kernel
In directory usw-pr-cvs1:/tmp/cvs-serv13561/m68k/kernel
Modified Files:
bios32.c head.S ints.c process.c ptrace.c semaphore.c setup.c
sys_m68k.c traps.c
Log Message:
synch 2.4.15 commit 37
Index: bios32.c
===================================================================
RCS file: /cvsroot/linux-vax/kernel-2.4/arch/m68k/kernel/bios32.c,v
retrieving revision 1.1.1.2
retrieving revision 1.2
diff -u -r1.1.1.2 -r1.2
--- bios32.c 25 Feb 2001 23:15:19 -0000 1.1.1.2
+++ bios32.c 10 Apr 2002 14:34:35 -0000 1.2
@@ -444,7 +444,7 @@
* dev - device.
* i - resource.
*
- * Result: 0 if successfull.
+ * Result: 0 if successful.
*/
int __init pcibios_assign_resource(struct pci_dev *dev, int i)
Index: head.S
===================================================================
RCS file: /cvsroot/linux-vax/kernel-2.4/arch/m68k/kernel/head.S,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -r1.1.1.1 -r1.2
--- head.S 14 Jan 2001 19:39:56 -0000 1.1.1.1
+++ head.S 10 Apr 2002 14:34:35 -0000 1.2
@@ -840,7 +840,7 @@
#ifdef CONFIG_MVME16x
is_not_mvme16x(L(gvtdone))
- /* Need to get the BRD_ID info to diferentiate between 162, 167,
+ /* Need to get the BRD_ID info to differentiate between 162, 167,
* etc. This is available as a BI_VME_BRDINFO tag with later
* versions of VMELILO and TFTPLILO, otherwise we call the Bug.
*/
@@ -1178,8 +1178,45 @@
#ifdef CONFIG_SUN3X
is_not_sun3x(L(notsun3x))
+ /* oh, the pain.. We're gonna want the prom code after
+ * starting the MMU, so we copy the mappings, translating
+ * from 8k -> 4k pages as we go.
+ */
+
+ /* copy maps from 0xfee00000 to 0xff000000 */
+ movel #0xfee00000, %d0
+ moveq #ROOT_INDEX_SHIFT, %d1
+ lsrl %d1,%d0
+ mmu_get_root_table_entry %d0
+
+ movel #0xfee00000, %d0
+ moveq #PTR_INDEX_SHIFT, %d1
+ lsrl %d1,%d0
+ andl #PTR_TABLE_SIZE-1, %d0
+ mmu_get_ptr_table_entry %a0,%d0
+
+ movel #0xfee00000, %d0
+ moveq #PAGE_INDEX_SHIFT, %d1
+ lsrl %d1,%d0
+ andl #PAGE_TABLE_SIZE-1, %d0
+ mmu_get_page_table_entry %a0,%d0
+
+ /* this is where the prom page table lives */
+ movel 0xfefe00d4, %a1
+ movel %a1@, %a1
+
+ movel #((0x200000 >> 13)-1), %d1
+
+1:
+ movel %a1@+, %d3
+ movel %d3,%a0@+
+ addl #0x1000,%d3
+ movel %d3,%a0@+
+
+ dbra %d1,1b
+
/* setup tt1 for I/O */
- mmu_map_tt #1,#0x40000000,#0x40000000,#_PAGE_NOCACHE_S
+ mmu_map_tt #1,#0x40000000,#0x40000000,#_PAGE_NOCACHE_S
jbra L(mmu_init_done)
L(notsun3x):
@@ -1363,7 +1400,7 @@
is_not_sun3x(1f)
/* enable copro */
- oriw #0x4000,0x61000000
+ oriw #0x4000,0x61000000
1:
#endif
@@ -3061,6 +3098,16 @@
2:
#endif
+#ifdef CONFIG_SUN3X
+ is_not_sun3x(2f)
+ movel %d0,-(%sp)
+ movel 0xFEFE0018,%a1
+ jbsr (%a1)
+ addq #4,%sp
+ jbra L(serial_putc_done)
+2:
+#endif
+
#ifdef CONFIG_Q40
is_not_q40(2f)
tst.l %pc@(L(q40_do_debug)) /* only debug if requested */
Index: ints.c
===================================================================
RCS file: /cvsroot/linux-vax/kernel-2.4/arch/m68k/kernel/ints.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -r1.1.1.1 -r1.2
--- ints.c 14 Jan 2001 19:39:57 -0000 1.1.1.1
+++ ints.c 10 Apr 2002 14:34:35 -0000 1.2
@@ -184,7 +184,7 @@
/*
* Do we need these probe functions on the m68k?
*
- * ... may be usefull with ISA devices
+ * ... may be useful with ISA devices
*/
unsigned long probe_irq_on (void)
{
Index: process.c
===================================================================
RCS file: /cvsroot/linux-vax/kernel-2.4/arch/m68k/kernel/process.c,v
retrieving revision 1.1.1.2
retrieving revision 1.2
diff -u -r1.1.1.2 -r1.2
--- process.c 25 Feb 2001 23:15:19 -0000 1.1.1.2
+++ process.c 10 Apr 2002 14:34:35 -0000 1.2
@@ -38,7 +38,6 @@
* alignment requirements and potentially different initial
* setup.
*/
-static struct vm_area_struct init_mmap = INIT_MMAP;
static struct fs_struct init_fs = INIT_FS;
static struct files_struct init_files = INIT_FILES;
static struct signal_struct init_signals = INIT_SIGNALS;
@@ -110,8 +109,8 @@
void show_regs(struct pt_regs * regs)
{
printk("\n");
- printk("Format %02x Vector: %04x PC: %08lx Status: %04x\n",
- regs->format, regs->vector, regs->pc, regs->sr);
+ printk("Format %02x Vector: %04x PC: %08lx Status: %04x %s\n",
+ regs->format, regs->vector, regs->pc, regs->sr, print_tainted());
printk("ORIG_D0: %08lx D0: %08lx A2: %08lx A1: %08lx\n",
regs->orig_d0, regs->d0, regs->a2, regs->a1);
printk("A0: %08lx D5: %08lx D4: %08lx\n",
Index: ptrace.c
===================================================================
RCS file: /cvsroot/linux-vax/kernel-2.4/arch/m68k/kernel/ptrace.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -r1.1.1.1 -r1.2
--- ptrace.c 14 Jan 2001 19:40:00 -0000 1.1.1.1
+++ ptrace.c 10 Apr 2002 14:34:35 -0000 1.2
@@ -87,6 +87,19 @@
return 0;
}
+/*
+ * Called by kernel/ptrace.c when detaching..
+ *
+ * Make sure the single step bit is not set.
+ */
+void ptrace_disable(struct task_struct *child)
+{
+ unsigned long tmp;
+ /* make sure the single step bit is not set. */
+ tmp = get_reg(child, PT_SR) & ~(TRACE_BITS << 16);
+ put_reg(child, PT_SR, tmp);
+}
+
asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
{
struct task_struct *child;
@@ -107,50 +120,29 @@
ret = -ESRCH;
read_lock(&tasklist_lock);
child = find_task_by_pid(pid);
- read_unlock(&tasklist_lock); /* FIXME!!! */
+ if (child)
+ get_task_struct(child);
+ read_unlock(&tasklist_lock);
if (!child)
goto out;
+
ret = -EPERM;
if (pid == 1) /* you may not mess with init */
- goto out;
- if (request == PTRACE_ATTACH) {
- if (child == current)
- goto out;
- if ((!child->dumpable ||
- (current->uid != child->euid) ||
- (current->uid != child->suid) ||
- (current->uid != child->uid) ||
- (current->gid != child->egid) ||
- (current->gid != child->sgid) ||
- (!cap_issubset(child->cap_permitted, current->cap_permitted)) ||
- (current->gid != child->gid)) && !capable(CAP_SYS_PTRACE))
- goto out;
- /* the same process cannot be attached many times */
- if (child->ptrace & PT_PTRACED)
- goto out;
- child->ptrace |= PT_PTRACED;
+ goto out_tsk;
- write_lock_irqsave(&tasklist_lock, flags);
- if (child->p_pptr != current) {
- REMOVE_LINKS(child);
- child->p_pptr = current;
- SET_LINKS(child);
- }
- write_unlock_irqrestore(&tasklist_lock, flags);
-
- send_sig(SIGSTOP, child, 1);
- ret = 0;
- goto out;
+ if (request == PTRACE_ATTACH) {
+ ret = ptrace_attach(child);
+ goto out_tsk;
}
ret = -ESRCH;
if (!(child->ptrace & PT_PTRACED))
- goto out;
+ goto out_tsk;
if (child->state != TASK_STOPPED) {
if (request != PTRACE_KILL)
- goto out;
+ goto out_tsk;
}
if (child->p_pptr != current)
- goto out;
+ goto out_tsk;
switch (request) {
/* when I and D space are separate, these will need to be fixed. */
@@ -162,9 +154,9 @@
copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
ret = -EIO;
if (copied != sizeof(tmp))
- goto out;
+ break;
ret = put_user(tmp,(unsigned long *) data);
- goto out;
+ break;
}
/* read the word at location addr in the USER area. */
@@ -172,8 +164,9 @@
unsigned long tmp;
ret = -EIO;
- if ((addr & 3) || addr < 0 || addr >= sizeof(struct user))
- goto out;
+ if ((addr & 3) || addr < 0 ||
+ addr > sizeof(struct user) - 3)
+ break;
tmp = 0; /* Default return condition */
addr = addr >> 2; /* temporary hack. */
@@ -193,9 +186,9 @@
((tmp & 0x0000ffff) << 16);
#endif
} else
- goto out;
+ break;
ret = put_user(tmp,(unsigned long *) data);
- goto out;
+ break;
}
/* when I and D space are separate, this will have to be fixed. */
@@ -203,14 +196,15 @@
case PTRACE_POKEDATA:
ret = 0;
if (access_process_vm(child, addr, &data, sizeof(data), 1) == sizeof(data))
- goto out;
+ break;
ret = -EIO;
- goto out;
+ break;
case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
ret = -EIO;
- if ((addr & 3) || addr < 0 || addr >= sizeof(struct user))
- goto out;
+ if ((addr & 3) || addr < 0 ||
+ addr > sizeof(struct user) - 3)
+ break;
addr = addr >> 2; /* temporary hack. */
@@ -221,9 +215,9 @@
}
if (addr < 19) {
if (put_reg(child, addr, data))
- goto out;
+ break;
ret = 0;
- goto out;
+ break;
}
if (addr >= 21 && addr < 48)
{
@@ -240,7 +234,7 @@
child->thread.fp[addr - 21] = data;
ret = 0;
}
- goto out;
+ break;
case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
case PTRACE_CONT: { /* restart after signal. */
@@ -248,7 +242,7 @@
ret = -EIO;
if ((unsigned long) data > _NSIG)
- goto out;
+ break;
if (request == PTRACE_SYSCALL)
child->ptrace |= PT_TRACESYS;
else
@@ -259,7 +253,7 @@
put_reg(child, PT_SR, tmp);
wake_up_process(child);
ret = 0;
- goto out;
+ break;
}
/*
@@ -272,13 +266,13 @@
ret = 0;
if (child->state == TASK_ZOMBIE) /* already dead */
- goto out;
+ break;
child->exit_code = SIGKILL;
/* make sure the single step bit is not set. */
tmp = get_reg(child, PT_SR) & ~(TRACE_BITS << 16);
put_reg(child, PT_SR, tmp);
wake_up_process(child);
- goto out;
+ break;
}
case PTRACE_SINGLESTEP: { /* set the trap flag. */
@@ -286,7 +280,7 @@
ret = -EIO;
if ((unsigned long) data > _NSIG)
- goto out;
+ break;
child->ptrace &= ~PT_TRACESYS;
tmp = get_reg(child, PT_SR) | (TRACE_BITS << 16);
put_reg(child, PT_SR, tmp);
@@ -295,29 +289,12 @@
/* give it a chance to run. */
wake_up_process(child);
ret = 0;
- goto out;
+ break;
}
- case PTRACE_DETACH: { /* detach a process that was attached. */
- long tmp;
-
- ret = -EIO;
- if ((unsigned long) data > _NSIG)
- goto out;
- child->ptrace &= ~(PT_PTRACED|PT_TRACESYS);
- child->exit_code = data;
- write_lock_irqsave(&tasklist_lock, flags);
- REMOVE_LINKS(child);
- child->p_pptr = child->p_opptr;
- SET_LINKS(child);
- write_unlock_irqrestore(&tasklist_lock, flags);
- /* make sure the single step bit is not set. */
- tmp = get_reg(child, PT_SR) & ~(TRACE_BITS << 16);
- put_reg(child, PT_SR, tmp);
- wake_up_process(child);
- ret = 0;
- goto out;
- }
+ case PTRACE_DETACH: /* detach a process that was attached. */
+ ret = ptrace_detach(child, data);
+ break;
case PTRACE_GETREGS: { /* Get all gp regs from the child. */
int i;
@@ -328,12 +305,12 @@
tmp >>= 16;
if (put_user(tmp, (unsigned long *) data)) {
ret = -EFAULT;
- goto out;
+ break;
}
data += sizeof(long);
}
ret = 0;
- goto out;
+ break;
}
case PTRACE_SETREGS: { /* Set all gp regs in the child. */
@@ -342,7 +319,7 @@
for (i = 0; i < 19; i++) {
if (get_user(tmp, (unsigned long *) data)) {
ret = -EFAULT;
- goto out;
+ break;
}
if (i == PT_SR) {
tmp &= SR_MASK;
@@ -353,7 +330,7 @@
data += sizeof(long);
}
ret = 0;
- goto out;
+ break;
}
case PTRACE_GETFPREGS: { /* Get the child FPU state. */
@@ -361,7 +338,7 @@
if (copy_to_user((void *)data, &child->thread.fp,
sizeof(struct user_m68kfp_struct)))
ret = -EFAULT;
- goto out;
+ break;
}
case PTRACE_SETFPREGS: { /* Set the child FPU state. */
@@ -369,13 +346,15 @@
if (copy_from_user(&child->thread.fp, (void *)data,
sizeof(struct user_m68kfp_struct)))
ret = -EFAULT;
- goto out;
+ break;
}
default:
ret = -EIO;
- goto out;
+ break;
}
+out_tsk:
+ free_task_struct(child);
out:
unlock_kernel();
return ret;
@@ -383,10 +362,9 @@
asmlinkage void syscall_trace(void)
{
- lock_kernel();
if ((current->ptrace & (PT_PTRACED|PT_TRACESYS))
!= (PT_PTRACED|PT_TRACESYS))
- goto out;
+ return;
current->exit_code = SIGTRAP;
current->state = TASK_STOPPED;
notify_parent(current, SIGCHLD);
@@ -400,6 +378,4 @@
send_sig(current->exit_code, current, 1);
current->exit_code = 0;
}
-out:
- unlock_kernel();
}
Index: semaphore.c
===================================================================
RCS file: /cvsroot/linux-vax/kernel-2.4/arch/m68k/kernel/semaphore.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -r1.1.1.1 -r1.2
--- semaphore.c 14 Jan 2001 19:40:15 -0000 1.1.1.1
+++ semaphore.c 10 Apr 2002 14:34:35 -0000 1.2
@@ -130,111 +130,3 @@
{
return waking_non_zero_trylock(sem);
}
-
-
-/* Wait for the lock to become unbiased. Readers
- * are non-exclusive. =)
- */
-void down_read_failed(struct rw_semaphore *sem)
-{
- DECLARE_WAITQUEUE(wait, current);
-
- __up_read(sem); /* this takes care of granting the lock */
-
- add_wait_queue(&sem->wait, &wait);
-
- while (atomic_read(&sem->count) < 0) {
- set_task_state(current, TASK_UNINTERRUPTIBLE);
- if (atomic_read(&sem->count) >= 0)
- break;
- schedule();
- }
-
- remove_wait_queue(&sem->wait, &wait);
- current->state = TASK_RUNNING;
-}
-
-void down_read_failed_biased(struct rw_semaphore *sem)
-{
- DECLARE_WAITQUEUE(wait, current);
-
- add_wait_queue(&sem->wait, &wait); /* put ourselves at the head of the list */
-
- for (;;) {
- if (sem->read_bias_granted && xchg(&sem->read_bias_granted, 0))
- break;
- set_task_state(current, TASK_UNINTERRUPTIBLE);
- if (!sem->read_bias_granted)
- schedule();
- }
-
- remove_wait_queue(&sem->wait, &wait);
- current->state = TASK_RUNNING;
-}
-
-
-/* Wait for the lock to become unbiased. Since we're
- * a writer, we'll make ourselves exclusive.
- */
-void down_write_failed(struct rw_semaphore *sem)
-{
- DECLARE_WAITQUEUE(wait, current);
-
- __up_write(sem); /* this takes care of granting the lock */
-
- add_wait_queue_exclusive(&sem->wait, &wait);
-
- while (atomic_read(&sem->count) < 0) {
- set_task_state(current, TASK_UNINTERRUPTIBLE);
- if (atomic_read(&sem->count) >= 0)
- break; /* we must attempt to acquire or bias the lock */
- schedule();
- }
-
- remove_wait_queue(&sem->wait, &wait);
- current->state = TASK_RUNNING;
-}
-
-void down_write_failed_biased(struct rw_semaphore *sem)
-{
- DECLARE_WAITQUEUE(wait, current);
-
- add_wait_queue_exclusive(&sem->write_bias_wait, &wait); /* put ourselves at the end of the list */
-
- for (;;) {
- if (sem->write_bias_granted && xchg(&sem->write_bias_granted, 0))
- break;
- set_task_state(current, TASK_UNINTERRUPTIBLE);
- if (!sem->write_bias_granted)
- schedule();
- }
-
- remove_wait_queue(&sem->write_bias_wait, &wait);
- current->state = TASK_RUNNING;
-
- /* if the lock is currently unbiased, awaken the sleepers
- * FIXME: this wakes up the readers early in a bit of a
- * stampede -> bad!
- */
- if (atomic_read(&sem->count) >= 0)
- wake_up(&sem->wait);
-}
-
-
-/* Called when someone has done an up that transitioned from
- * negative to non-negative, meaning that the lock has been
- * granted to whomever owned the bias.
- */
-void rwsem_wake_readers(struct rw_semaphore *sem)
-{
- if (xchg(&sem->read_bias_granted, 1))
- BUG();
- wake_up(&sem->wait);
-}
-
-void rwsem_wake_writer(struct rw_semaphore *sem)
-{
- if (xchg(&sem->write_bias_granted, 1))
- BUG();
- wake_up(&sem->write_bias_wait);
-}
Index: setup.c
===================================================================
RCS file: /cvsroot/linux-vax/kernel-2.4/arch/m68k/kernel/setup.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -r1.1.1.1 -r1.2
--- setup.c 14 Jan 2001 19:40:02 -0000 1.1.1.1
+++ setup.c 10 Apr 2002 14:34:35 -0000 1.2
@@ -34,15 +34,15 @@
#ifdef CONFIG_ATARI
#include <asm/atarihw.h>
#endif
+#ifdef CONFIG_SUN3X
+#include <asm/dvma.h>
+extern void sun_serial_setup(void);
+#endif
#ifdef CONFIG_BLK_DEV_INITRD
#include <linux/blk.h>
#endif
-#ifndef CONFIG_AMIGA
-#define dbprintf printk
-#endif
-
unsigned long m68k_machtype;
unsigned long m68k_cputype;
unsigned long m68k_fputype;
@@ -110,6 +110,11 @@
char *mach_sysrq_xlate = NULL;
#endif
+#if defined(CONFIG_ISA)
+int isa_type;
+int isa_sex;
+#endif
+
extern int amiga_parse_bootinfo(const struct bi_record *);
extern int atari_parse_bootinfo(const struct bi_record *);
extern int mac_parse_bootinfo(const struct bi_record *);
@@ -141,7 +146,7 @@
{
while (record->tag != BI_LAST) {
int unknown = 0;
- const u_long *data = record->data;
+ const unsigned long *data = record->data;
switch (record->tag) {
case BI_MACHTYPE:
case BI_CPUTYPE:
@@ -190,7 +195,7 @@
if (unknown)
printk("m68k_parse_bootinfo: unknown tag 0x%04x ignored\n",
record->tag);
- record = (struct bi_record *)((u_long)record+record->size);
+ record = (struct bi_record *)((unsigned long)record+record->size);
}
m68k_realnum_memory = m68k_num_memory;
@@ -369,14 +374,44 @@
if (MACH_IS_ATARI)
atari_stram_reserve_pages(availmem);
#endif
+#ifdef CONFIG_SUN3X
+ if (MACH_IS_SUN3X) {
+ dvma_init();
+#ifdef CONFIG_SUN3X_ZS
+ sun_serial_setup();
+#endif
+ }
+#endif
+
#endif /* !CONFIG_SUN3 */
+
paging_init();
+
+/* set ISA defs early as possible */
+#if defined(CONFIG_ISA)
+#if defined(CONFIG_Q40)
+ if (MACH_IS_Q40) {
+ isa_type = Q40_ISA;
+ isa_sex = 0;
+ }
+#elif defined(CONFIG_GG2)
+ if (MACH_IS_AMIGA && AMIGAHW_PRESENT(GG2_ISA)){
+ isa_type = GG2_ISA;
+ isa_sex = 0;
+ }
+#elif defined(CONFIG_AMIGA_PCMCIA)
+ if (MACH_IS_AMIGA && AMIGAHW_PRESENT(PCMCIA)){
+ isa_type = AG_ISA;
+ isa_sex = 1;
+ }
+#endif
+#endif
}
int get_cpuinfo(char * buffer)
{
const char *cpu, *mmu, *fpu;
- u_long clockfreq, clockfactor;
+ unsigned long clockfreq, clockfactor;
#define LOOP_CYCLES_68020 (8)
#define LOOP_CYCLES_68030 (8)
@@ -451,7 +486,7 @@
{
int len = 0;
char model[80];
- u_long mem;
+ unsigned long mem;
int i;
if (mach_get_model)
Index: sys_m68k.c
===================================================================
RCS file: /cvsroot/linux-vax/kernel-2.4/arch/m68k/kernel/sys_m68k.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -r1.1.1.1 -r1.2
--- sys_m68k.c 14 Jan 2001 19:40:08 -0000 1.1.1.1
+++ sys_m68k.c 10 Apr 2002 14:34:35 -0000 1.2
@@ -59,9 +59,9 @@
goto out;
}
- down(¤t->mm->mmap_sem);
+ down_write(¤t->mm->mmap_sem);
error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
- up(¤t->mm->mmap_sem);
+ up_write(¤t->mm->mmap_sem);
if (file)
fput(file);
@@ -146,9 +146,9 @@
}
a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
- down(¤t->mm->mmap_sem);
+ down_write(¤t->mm->mmap_sem);
error = do_mmap_pgoff(file, a.addr, a.len, a.prot, a.flags, pgoff);
- up(¤t->mm->mmap_sem);
+ up_write(¤t->mm->mmap_sem);
if (file)
fput(file);
out:
@@ -267,7 +267,8 @@
return -ENOSYS;
}
-/* Convert virtual address VADDR to physical address PADDR */
+
+/* Convert virtual (user) address VADDR to physical address PADDR */
#define virt_to_phys_040(vaddr) \
({ \
unsigned long _mmusr, _paddr; \
@@ -447,6 +448,12 @@
{
unsigned long paddr, i;
+ /*
+ * 68060 manual says:
+ * cpush %dc : flush DC, remains valid (with our %cacr setup)
+ * cpush %ic : invalidate IC
+ * cpush %bc : flush DC + invalidate IC
+ */
switch (scope)
{
case FLUSH_SCOPE_ALL:
@@ -455,20 +462,17 @@
case FLUSH_CACHE_DATA:
__asm__ __volatile__ (".chip 68060\n\t"
"cpusha %dc\n\t"
- "cinva %dc\n\t"
".chip 68k");
break;
case FLUSH_CACHE_INSN:
__asm__ __volatile__ (".chip 68060\n\t"
"cpusha %ic\n\t"
- "cinva %ic\n\t"
".chip 68k");
break;
default:
case FLUSH_CACHE_BOTH:
__asm__ __volatile__ (".chip 68060\n\t"
"cpusha %bc\n\t"
- "cinva %bc\n\t"
".chip 68k");
break;
}
@@ -506,14 +510,12 @@
case FLUSH_CACHE_DATA:
__asm__ __volatile__ (".chip 68060\n\t"
"cpushl %%dc,(%0)\n\t"
- "cinvl %%dc,(%0)\n\t"
".chip 68k"
: : "a" (paddr));
break;
case FLUSH_CACHE_INSN:
__asm__ __volatile__ (".chip 68060\n\t"
"cpushl %%ic,(%0)\n\t"
- "cinvl %%ic,(%0)\n\t"
".chip 68k"
: : "a" (paddr));
break;
@@ -521,7 +523,6 @@
case FLUSH_CACHE_BOTH:
__asm__ __volatile__ (".chip 68060\n\t"
"cpushl %%bc,(%0)\n\t"
- "cinvl %%bc,(%0)\n\t"
".chip 68k"
: : "a" (paddr));
break;
@@ -568,14 +569,12 @@
case FLUSH_CACHE_DATA:
__asm__ __volatile__ (".chip 68060\n\t"
"cpushp %%dc,(%0)\n\t"
- "cinvp %%dc,(%0)\n\t"
".chip 68k"
: : "a" (paddr));
break;
case FLUSH_CACHE_INSN:
__asm__ __volatile__ (".chip 68060\n\t"
"cpushp %%ic,(%0)\n\t"
- "cinvp %%ic,(%0)\n\t"
".chip 68k"
: : "a" (paddr));
break;
@@ -583,7 +582,6 @@
case FLUSH_CACHE_BOTH:
__asm__ __volatile__ (".chip 68060\n\t"
"cpushp %%bc,(%0)\n\t"
- "cinvp %%bc,(%0)\n\t"
".chip 68k"
: : "a" (paddr));
break;
@@ -607,13 +605,14 @@
goto out;
if (scope == FLUSH_SCOPE_ALL) {
- /* Only the superuser may flush the whole cache. */
+ /* Only the superuser may explicitly flush the whole cache. */
ret = -EPERM;
if (!capable(CAP_SYS_ADMIN))
goto out;
} else {
- /* Verify that the specified address region actually belongs to
- * this process.
+ /*
+ * Verify that the specified address region actually belongs
+ * to this process.
*/
vma = find_vma (current->mm, addr);
ret = -EINVAL;
@@ -652,10 +651,21 @@
}
ret = 0;
goto out;
- } else if (CPU_IS_040) {
+ } else {
+ /*
+ * 040 or 060: don't blindly trust 'scope', someone could
+ * try to flush a few megs of memory.
+ */
+
+ if (len>=3*PAGE_SIZE && scope<FLUSH_SCOPE_PAGE)
+ scope=FLUSH_SCOPE_PAGE;
+ if (len>=10*PAGE_SIZE && scope<FLUSH_SCOPE_ALL)
+ scope=FLUSH_SCOPE_ALL;
+ if (CPU_IS_040) {
ret = cache_flush_040 (addr, scope, cache, len);
- } else if (CPU_IS_060) {
+ } else if (CPU_IS_060) {
ret = cache_flush_060 (addr, scope, cache, len);
+ }
}
out:
unlock_kernel();
Index: traps.c
===================================================================
RCS file: /cvsroot/linux-vax/kernel-2.4/arch/m68k/kernel/traps.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -r1.1.1.1 -r1.2
--- traps.c 14 Jan 2001 19:40:12 -0000 1.1.1.1
+++ traps.c 10 Apr 2002 14:34:35 -0000 1.2
@@ -72,6 +72,12 @@
*/
void __init base_trap_init(void)
{
+ if(MACH_IS_SUN3X) {
+ extern e_vector *sun3x_prom_vbr;
+
+ __asm__ volatile ("movec %%vbr, %0" : "=r" ((void*)sun3x_prom_vbr));
+ }
+
/* setup the exception vector table */
__asm__ volatile ("movec %0,%%vbr" : : "r" ((void*)vectors));
@@ -245,9 +251,12 @@
#endif /* CONFIG_M68060 */
#if defined (CONFIG_M68040)
-static inline unsigned long probe040(int iswrite, unsigned long addr)
+static inline unsigned long probe040(int iswrite, unsigned long addr, int wbs)
{
unsigned long mmusr;
+ mm_segment_t old_fs = get_fs();
+
+ set_fs(MAKE_MM_SEG(wbs));
asm volatile (".chip 68040");
@@ -260,6 +269,8 @@
asm volatile (".chip 68k");
+ set_fs(old_fs);
+
return mmusr;
}
@@ -267,7 +278,9 @@
unsigned long wbd)
{
int res = 0;
+ mm_segment_t old_fs = get_fs();
+ /* set_fs can not be moved, otherwise put_user() may oops */
set_fs(MAKE_MM_SEG(wbs));
switch (wbs & WBSIZ_040) {
@@ -282,6 +295,10 @@
break;
}
+ /* set_fs can not be moved, otherwise put_user() may oops */
+ set_fs(old_fs);
+
+
#ifdef DEBUG
printk("do_040writeback1, res=%d\n",res);
#endif
@@ -293,10 +310,12 @@
* to that exception is discarded, set a few bits in the old frame
* to simulate what it should look like
*/
-static inline void fix_xframe040(struct frame *fp, unsigned short wbs)
+static inline void fix_xframe040(struct frame *fp, unsigned long wba, unsigned short wbs)
{
- fp->un.fmt7.faddr = current->thread.faddr;
+ fp->un.fmt7.faddr = wba;
fp->un.fmt7.ssw = wbs & 0xff;
+ if (wba != current->thread.faddr)
+ fp->un.fmt7.ssw |= MA_040;
}
static inline void do_040writebacks(struct frame *fp)
@@ -312,7 +331,7 @@
res = do_040writeback1(fp->un.fmt7.wb2s, fp->un.fmt7.wb2a,
fp->un.fmt7.wb2d);
if (res)
- fix_xframe040(fp, fp->un.fmt7.wb2s);
+ fix_xframe040(fp, fp->un.fmt7.wb2a, fp->un.fmt7.wb2s);
else
fp->un.fmt7.wb2s = 0;
}
@@ -322,7 +341,14 @@
res = do_040writeback1(fp->un.fmt7.wb3s, fp->un.fmt7.wb3a,
fp->un.fmt7.wb3d);
if (res)
- fix_xframe040(fp, fp->un.fmt7.wb3s);
+ {
+ fix_xframe040(fp, fp->un.fmt7.wb3a, fp->un.fmt7.wb3s);
+
+ fp->un.fmt7.wb2s = fp->un.fmt7.wb3s;
+ fp->un.fmt7.wb3s &= (~WBV_040);
+ fp->un.fmt7.wb2a = fp->un.fmt7.wb3a;
+ fp->un.fmt7.wb2d = fp->un.fmt7.wb3d;
+ }
else
fp->un.fmt7.wb3s = 0;
}
@@ -339,19 +365,15 @@
*/
asmlinkage void berr_040cleanup(struct frame *fp)
{
- mm_segment_t old_fs = get_fs();
-
fp->un.fmt7.wb2s &= ~4;
fp->un.fmt7.wb3s &= ~4;
do_040writebacks(fp);
- set_fs(old_fs);
}
static inline void access_error040(struct frame *fp)
{
unsigned short ssw = fp->un.fmt7.ssw;
- mm_segment_t old_fs = get_fs();
unsigned long mmusr;
#ifdef DEBUG
@@ -374,9 +396,8 @@
if (ssw & MA_040)
addr = (addr + 7) & -8;
- set_fs(MAKE_MM_SEG(ssw));
/* MMU error, get the MMUSR info for this access */
- mmusr = probe040(!(ssw & RW_040), addr);
+ mmusr = probe040(!(ssw & RW_040), addr, ssw);
#ifdef DEBUG
printk("mmusr = %lx\n", mmusr);
#endif
@@ -386,8 +407,12 @@
__flush_tlb040_one(addr);
errorcode = 0;
}
- if (!(ssw & RW_040))
+
+ /* despite what documentation seems to say, RMW
+ * accesses have always both the LK and RW bits set */
+ if (!(ssw & RW_040) || (ssw & LK_040))
errorcode |= 2;
+
if (do_page_fault(&fp->ptregs, addr, errorcode)) {
#ifdef DEBUG
printk("do_page_fault() !=0 \n");
@@ -415,7 +440,6 @@
}
do_040writebacks(fp);
- set_fs(old_fs);
}
#endif /* CONFIG_M68040 */
|