Commit 7d5ab07d authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

Merge kroah.com:/home/linux/linux/BK/bleed-2.5

into kroah.com:/home/linux/linux/BK/gregkh-2.5
parents 25da53aa 4ede0350
......@@ -247,6 +247,19 @@ ChangeLog
Note, a technical ChangeLog aimed at kernel hackers is in fs/ntfs/ChangeLog.
2.1.4:
- Minor update allowing compilation with all gcc versions (well, the
ones the kernel can be compiled with anyway).
2.1.3:
- Major bug fixes for reading files and volumes in corner cases which
were being hit by Windows 2k/XP users.
2.1.2:
- Major bug fixes aleviating the hangs in statfs experienced by some
users.
2.1.1:
- Update handling of compressed files so people no longer get the
frequently reported warning messages about initialized_size !=
data_size.
2.1.0:
- Add configuration option for developmental write support.
- Initial implementation of file overwriting. (Writes to resident files
......
......@@ -273,6 +273,13 @@ config MVIAC3_2
endchoice
config X86_GENERIC
bool "Generic x86 support"
help
Including some tuning for non selected x86 CPUs too.
when it has moderate overhead. This is intended for generic
distributions kernels.
#
# Define implied options from the CPU selection here
#
......@@ -288,10 +295,10 @@ config X86_XADD
config X86_L1_CACHE_SHIFT
int
default "7" if MPENTIUM4 || X86_GENERIC
default "4" if MELAN || M486 || M386
default "5" if MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCRUSOE || MCYRIXIII || MK6 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || MVIAC3_2
default "6" if MK7 || MK8
default "7" if MPENTIUM4
config RWSEM_GENERIC_SPINLOCK
bool
......@@ -363,16 +370,6 @@ config X86_OOSTORE
depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6
default y
config X86_PREFETCH
bool
depends on MPENTIUMIII || MPENTIUM4 || MVIAC3_2
default y
config X86_SSE2
bool
depends on MK8 || MPENTIUM4
default y
config HUGETLB_PAGE
bool "Huge TLB Page Support"
help
......@@ -413,6 +410,18 @@ config SMP
If you don't know what to do here, say N.
config NR_CPUS
int "Maximum number of CPUs (2-32)"
depends on SMP
default "32"
help
This allows you to specify the maximum number of CPUs which this
kernel will support. The maximum supported value is 32 and the
minimum value which makes sense is 2.
This is purely to save memory - each supported CPU adds
approximately eight kilobytes to the kernel image.
config PREEMPT
bool "Preemptible Kernel"
help
......@@ -465,18 +474,6 @@ config X86_IO_APIC
depends on !SMP && X86_UP_IOAPIC
default y
config NR_CPUS
int "Maximum number of CPUs (2-32)"
depends on SMP
default "32"
help
This allows you to specify the maximum number of CPUs which this
kernel will support. The maximum supported value is 32 and the
minimum value which makes sense is 2.
This is purely to save memory - each supported CPU adds
approximately eight kilobytes to the kernel image.
config X86_TSC
bool
depends on (MWINCHIP3D || MWINCHIP2 || MCRUSOE || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2) && !X86_NUMAQ
......@@ -989,6 +986,11 @@ config X86_LOCAL_APIC
depends on (X86_VISWS || SMP) && !X86_VOYAGER
default y
config X86_IO_APIC
bool
depends on SMP && !(X86_VISWS || X86_VOYAGER)
default y
config PCI
bool "PCI support" if !X86_VISWS
depends on !X86_VOYAGER
......@@ -1004,11 +1006,6 @@ config PCI
information about which PCI hardware does work under Linux and which
doesn't.
config X86_IO_APIC
bool
depends on SMP && !(X86_VISWS || X86_VOYAGER)
default y
choice
prompt "PCI access mode"
depends on PCI && !X86_VISWS
......@@ -1048,18 +1045,6 @@ config PCI_DIRECT
depends on PCI && ((PCI_GODIRECT || PCI_GOANY) || X86_VISWS)
default y
config SCx200
tristate "NatSemi SCx200 support"
depends on !X86_VOYAGER
help
This provides basic support for the National Semiconductor SCx200
processor. Right now this is just a driver for the GPIO pins.
If you don't know what to do here, say N.
This support is also available as a module. If compiled as a
module, it will be called scx200.
source "drivers/pci/Kconfig"
config ISA
......@@ -1105,6 +1090,18 @@ config MCA
source "drivers/mca/Kconfig"
config SCx200
tristate "NatSemi SCx200 support"
depends on !X86_VOYAGER
help
This provides basic support for the National Semiconductor SCx200
processor. Right now this is just a driver for the GPIO pins.
If you don't know what to do here, say N.
This support is also available as a module. If compiled as a
module, it will be called scx200.
config HOTPLUG
bool "Support for hot-pluggable devices"
---help---
......
......@@ -1205,7 +1205,17 @@ static int suspend(int vetoable)
spin_lock(&i8253_lock);
get_time_diff();
/*
* Irq spinlock must be dropped around set_system_power_state.
* We'll undo any timer changes due to interrupts below.
*/
spin_unlock(&i8253_lock);
write_sequnlock_irq(&xtime_lock);
err = set_system_power_state(APM_STATE_SUSPEND);
write_seqlock_irq(&xtime_lock);
spin_lock(&i8253_lock);
reinit_timer();
set_time();
ignore_normal_resume = 1;
......
......@@ -178,6 +178,15 @@ static void __init init_amd(struct cpuinfo_x86 *c)
break;
}
switch (c->x86) {
case 15:
set_bit(X86_FEATURE_K8, c->x86_capability);
break;
case 6:
set_bit(X86_FEATURE_K7, c->x86_capability);
break;
}
display_cacheinfo(c);
}
......
......@@ -353,6 +353,11 @@ static void __init init_intel(struct cpuinfo_x86 *c)
break;
}
#endif
if (c->x86 == 15)
set_bit(X86_FEATURE_P4, c->x86_capability);
if (c->x86 == 6)
set_bit(X86_FEATURE_P3, c->x86_capability);
}
......
......@@ -65,7 +65,6 @@
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/miscdevice.h>
#include <linux/devfs_fs_kernel.h>
#include <linux/spinlock.h>
#include <linux/mm.h>
......@@ -116,9 +115,10 @@ static struct file_operations microcode_fops = {
};
static struct miscdevice microcode_dev = {
.minor = MICROCODE_MINOR,
.name = "microcode",
.fops = &microcode_fops,
.minor = MICROCODE_MINOR,
.name = "microcode",
.devfs_name = "cpu/microcode",
.fops = &microcode_fops,
};
static int __init microcode_init(void)
......@@ -127,26 +127,17 @@ static int __init microcode_init(void)
error = misc_register(&microcode_dev);
if (error)
goto fail;
error = devfs_mk_symlink("cpu/microcode", "../misc/microcode");
if (error)
goto fail_deregister;
return error;
printk(KERN_INFO
"IA-32 Microcode Update Driver: v%s <tigran@veritas.com>\n",
MICROCODE_VERSION);
return 0;
fail_deregister:
misc_deregister(&microcode_dev);
fail:
return error;
}
static void __exit microcode_exit(void)
{
misc_deregister(&microcode_dev);
devfs_remove("cpu/microcode");
kfree(mc_applied);
printk(KERN_INFO "IA-32 Microcode Update Driver v%s unregistered\n",
MICROCODE_VERSION);
......
......@@ -795,41 +795,91 @@ static void __init register_memory(unsigned long max_low_pfn)
pci_mem_start = low_mem_size;
}
/* Use inline assembly to define this because the nops are defined
as inline assembly strings in the include files and we cannot
get them easily into strings. */
asm("intelnops: "
GENERIC_NOP1 GENERIC_NOP2 GENERIC_NOP3 GENERIC_NOP4 GENERIC_NOP5 GENERIC_NOP6
GENERIC_NOP7 GENERIC_NOP8);
asm("k8nops: "
K8_NOP1 K8_NOP2 K8_NOP3 K8_NOP4 K8_NOP5 K8_NOP6
K8_NOP7 K8_NOP8);
asm("k7nops: "
K7_NOP1 K7_NOP2 K7_NOP3 K7_NOP4 K7_NOP5 K7_NOP6
K7_NOP7 K7_NOP8);
extern unsigned char intelnops[], k8nops[], k7nops[];
static unsigned char *intel_nops[ASM_NOP_MAX+1] = {
NULL,
intelnops,
intelnops + 1,
intelnops + 1 + 2,
intelnops + 1 + 2 + 3,
intelnops + 1 + 2 + 3 + 4,
intelnops + 1 + 2 + 3 + 4 + 5,
intelnops + 1 + 2 + 3 + 4 + 5 + 6,
intelnops + 1 + 2 + 3 + 4 + 5 + 6 + 7,
};
static unsigned char *k8_nops[ASM_NOP_MAX+1] = {
NULL,
k8nops,
k8nops + 1,
k8nops + 1 + 2,
k8nops + 1 + 2 + 3,
k8nops + 1 + 2 + 3 + 4,
k8nops + 1 + 2 + 3 + 4 + 5,
k8nops + 1 + 2 + 3 + 4 + 5 + 6,
k8nops + 1 + 2 + 3 + 4 + 5 + 6 + 7,
};
static unsigned char *k7_nops[ASM_NOP_MAX+1] = {
NULL,
k7nops,
k7nops + 1,
k7nops + 1 + 2,
k7nops + 1 + 2 + 3,
k7nops + 1 + 2 + 3 + 4,
k7nops + 1 + 2 + 3 + 4 + 5,
k7nops + 1 + 2 + 3 + 4 + 5 + 6,
k7nops + 1 + 2 + 3 + 4 + 5 + 6 + 7,
};
static struct nop {
int cpuid;
unsigned char **noptable;
} noptypes[] = {
{ X86_FEATURE_K8, k8_nops },
{ X86_FEATURE_K7, k7_nops },
{ -1, 0 }
};
/* Replace instructions with better alternatives for this CPU type.
This runs before SMP is initialized to avoid SMP problems with
self modifying code. This implies that assymetric systems where
APs have less capabilities than the boot processor are not handled.
In this case boot with "noreplacement". */
void apply_alternatives(void *start, void *end)
{
struct alt_instr *a;
int diff, i, k;
for (a = start; a < (struct alt_instr *)end;
a = (void *)ALIGN((unsigned long)(a + 1) + a->instrlen, 4)) {
unsigned char **noptable = intel_nops;
for (i = 0; noptypes[i].cpuid >= 0; i++) {
if (boot_cpu_has(noptypes[i].cpuid)) {
noptable = noptypes[i].noptable;
break;
}
}
for (a = start; (void *)a < end; a++) {
if (!boot_cpu_has(a->cpuid))
continue;
BUG_ON(a->replacementlen > a->instrlen);
memcpy(a->instr, a->replacement, a->replacementlen);
diff = a->instrlen - a->replacementlen;
/* Pad the rest with nops */
for (i = a->replacementlen; diff > 0; diff -= k, i += k) {
static const char *nops[] = {
0,
"\x90",
#if CONFIG_MK7 || CONFIG_MK8
"\x66\x90",
"\x66\x66\x90",
"\x66\x66\x66\x90",
#else
"\x89\xf6",
"\x8d\x76\x00",
"\x8d\x74\x26\x00",
#endif
};
k = min_t(int, diff, ARRAY_SIZE(nops));
memcpy(a->instr + i, nops[k], k);
k = diff;
if (k > ASM_NOP_MAX)
k = ASM_NOP_MAX;
memcpy(a->instr + i, noptable[k], k);
}
}
}
......
......@@ -67,11 +67,11 @@ static void mark_offset_cyclone(void)
/* lost tick compensation */
delta = last_cyclone_low - delta;
delta /=(CYCLONE_TIMER_FREQ/1000000);
delta /= (CYCLONE_TIMER_FREQ/1000000);
delta += delay_at_last_interrupt;
lost = delta/(1000000/HZ);
delay = delta%(1000000/HZ);
if(lost >= 2)
if (lost >= 2)
jiffies += lost-1;
/* update the monotonic base value */
......@@ -83,10 +83,12 @@ static void mark_offset_cyclone(void)
count = ((LATCH-1) - count) * TICK_SIZE;
delay_at_last_interrupt = (count + LATCH/2) / LATCH;
/* catch corner case where tick rollover
* occured between cyclone and pit reads
/* catch corner case where tick rollover occured
* between cyclone and pit reads (as noted when
* usec delta is > 90% # of usecs/tick)
*/
if(abs(delay - delay_at_last_interrupt) > 900)
if (abs(delay - delay_at_last_interrupt) > (900000/HZ))
jiffies++;
}
......
......@@ -178,7 +178,7 @@ static void mark_offset_tsc(void)
delta += delay_at_last_interrupt;
lost = delta/(1000000/HZ);
delay = delta%(1000000/HZ);
if(lost >= 2)
if (lost >= 2)
jiffies += lost-1;
/* update the monotonic base value */
......@@ -190,10 +190,11 @@ static void mark_offset_tsc(void)
count = ((LATCH-1) - count) * TICK_SIZE;
delay_at_last_interrupt = (count + LATCH/2) / LATCH;
/* catch corner case where tick rollover
* occured between tsc and pit reads
/* catch corner case where tick rollover occured
* between tsc and pit reads (as noted when
* usec delta is > 90% # of usecs/tick)
*/
if(abs(delay - delay_at_last_interrupt) > 900)
if (abs(delay - delay_at_last_interrupt) > (900000/HZ))
jiffies++;
}
......
......@@ -85,6 +85,7 @@ SECTIONS
__alt_instructions = .;
.altinstructions : { *(.altinstructions) }
__alt_instructions_end = .;
.altinstr_replacement : { *(.altinstr_replacement) }
. = ALIGN(4096);
__initramfs_start = .;
.init.ramfs : { *(.init.ramfs) }
......
......@@ -252,7 +252,7 @@ ia32_syscall_table:
data8 sys_acct
data8 sys_umount /* recycled never used phys( */
data8 sys32_ni_syscall /* old lock syscall holder */
data8 sys32_ioctl
data8 compat_sys_ioctl
data8 compat_sys_fcntl /* 55 */
data8 sys32_ni_syscall /* old mpx syscall holder */
data8 sys_setpgid
......
......@@ -293,221 +293,3 @@ static int sg_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
}
return err;
}
asmlinkage long
sys32_ioctl (unsigned int fd, unsigned int cmd, unsigned int arg)
{
long ret;
switch (IOCTL_NR(cmd)) {
case IOCTL_NR(VFAT_IOCTL_READDIR_SHORT):
case IOCTL_NR(VFAT_IOCTL_READDIR_BOTH): {
struct linux32_dirent *d32 = P(arg);
struct dirent d[2];
ret = DO_IOCTL(fd, _IOR('r', _IOC_NR(cmd),
struct dirent [2]),
(unsigned long) d);
if (ret < 0)
return ret;
if (put_dirent32(d, d32) || put_dirent32(d + 1, d32 + 1))
return -EFAULT;
return ret;
}
case IOCTL_NR(SIOCGIFCONF):
{
struct ifconf32 {
int ifc_len;
unsigned int ifc_ptr;
} ifconf32;
struct ifconf ifconf;
int i, n;
char *p32, *p64;
char buf[32]; /* sizeof IA32 ifreq structure */
if (copy_from_user(&ifconf32, P(arg), sizeof(ifconf32)))
return -EFAULT;
ifconf.ifc_len = ifconf32.ifc_len;
ifconf.ifc_req = P(ifconf32.ifc_ptr);
ret = DO_IOCTL(fd, SIOCGIFCONF, &ifconf);
ifconf32.ifc_len = ifconf.ifc_len;
if (copy_to_user(P(arg), &ifconf32, sizeof(ifconf32)))
return -EFAULT;
n = ifconf.ifc_len / sizeof(struct ifreq);
p32 = P(ifconf32.ifc_ptr);
p64 = P(ifconf32.ifc_ptr);
for (i = 0; i < n; i++) {
if (copy_from_user(buf, p64, sizeof(struct ifreq)))
return -EFAULT;
if (copy_to_user(p32, buf, sizeof(buf)))
return -EFAULT;
p32 += sizeof(buf);
p64 += sizeof(struct ifreq);
}
return ret;
}
case IOCTL_NR(DRM_IOCTL_VERSION):
{
drm_version_t ver;
struct {
int version_major;
int version_minor;
int version_patchlevel;
unsigned int name_len;
unsigned int name; /* pointer */
unsigned int date_len;
unsigned int date; /* pointer */
unsigned int desc_len;
unsigned int desc; /* pointer */
} ver32;
if (copy_from_user(&ver32, P(arg), sizeof(ver32)))
return -EFAULT;
ver.name_len = ver32.name_len;
ver.name = P(ver32.name);
ver.date_len = ver32.date_len;
ver.date = P(ver32.date);
ver.desc_len = ver32.desc_len;
ver.desc = P(ver32.desc);
ret = DO_IOCTL(fd, DRM_IOCTL_VERSION, &ver);
if (ret >= 0) {
ver32.version_major = ver.version_major;
ver32.version_minor = ver.version_minor;
ver32.version_patchlevel = ver.version_patchlevel;
ver32.name_len = ver.name_len;
ver32.date_len = ver.date_len;
ver32.desc_len = ver.desc_len;
if (copy_to_user(P(arg), &ver32, sizeof(ver32)))
return -EFAULT;
}
return ret;
}
case IOCTL_NR(DRM_IOCTL_GET_UNIQUE):
{
drm_unique_t un;
struct {
unsigned int unique_len;
unsigned int unique;
} un32;
if (copy_from_user(&un32, P(arg), sizeof(un32)))
return -EFAULT;
un.unique_len = un32.unique_len;
un.unique = P(un32.unique);
ret = DO_IOCTL(fd, DRM_IOCTL_GET_UNIQUE, &un);
if (ret >= 0) {
un32.unique_len = un.unique_len;
if (copy_to_user(P(arg), &un32, sizeof(un32)))
return -EFAULT;
}
return ret;
}
case IOCTL_NR(DRM_IOCTL_SET_UNIQUE):
case IOCTL_NR(DRM_IOCTL_ADD_MAP):
case IOCTL_NR(DRM_IOCTL_ADD_BUFS):
case IOCTL_NR(DRM_IOCTL_MARK_BUFS):
case IOCTL_NR(DRM_IOCTL_INFO_BUFS):
case IOCTL_NR(DRM_IOCTL_MAP_BUFS):
case IOCTL_NR(DRM_IOCTL_FREE_BUFS):
case IOCTL_NR(DRM_IOCTL_ADD_CTX):
case IOCTL_NR(DRM_IOCTL_RM_CTX):
case IOCTL_NR(DRM_IOCTL_MOD_CTX):
case IOCTL_NR(DRM_IOCTL_GET_CTX):
case IOCTL_NR(DRM_IOCTL_SWITCH_CTX):
case IOCTL_NR(DRM_IOCTL_NEW_CTX):
case IOCTL_NR(DRM_IOCTL_RES_CTX):
case IOCTL_NR(DRM_IOCTL_AGP_ACQUIRE):
case IOCTL_NR(DRM_IOCTL_AGP_RELEASE):
case IOCTL_NR(DRM_IOCTL_AGP_ENABLE):
case IOCTL_NR(DRM_IOCTL_AGP_INFO):
case IOCTL_NR(DRM_IOCTL_AGP_ALLOC):
case IOCTL_NR(DRM_IOCTL_AGP_FREE):
case IOCTL_NR(DRM_IOCTL_AGP_BIND):
case IOCTL_NR(DRM_IOCTL_AGP_UNBIND):
/* Mga specific ioctls */
case IOCTL_NR(DRM_IOCTL_MGA_INIT):
/* I810 specific ioctls */
case IOCTL_NR(DRM_IOCTL_I810_GETBUF):
case IOCTL_NR(DRM_IOCTL_I810_COPY):
case IOCTL_NR(MTIOCGET):
case IOCTL_NR(MTIOCPOS):
case IOCTL_NR(MTIOCGETCONFIG):
case IOCTL_NR(MTIOCSETCONFIG):
case IOCTL_NR(PPPIOCSCOMPRESS):
case IOCTL_NR(PPPIOCGIDLE):
case IOCTL_NR(NCP_IOC_GET_FS_INFO_V2):
case IOCTL_NR(NCP_IOC_GETOBJECTNAME):
case IOCTL_NR(NCP_IOC_SETOBJECTNAME):
case IOCTL_NR(NCP_IOC_GETPRIVATEDATA):
case IOCTL_NR(NCP_IOC_SETPRIVATEDATA):
case IOCTL_NR(NCP_IOC_GETMOUNTUID2):
case IOCTL_NR(CAPI_MANUFACTURER_CMD):
case IOCTL_NR(VIDIOCGTUNER):
case IOCTL_NR(VIDIOCSTUNER):
case IOCTL_NR(VIDIOCGWIN):
case IOCTL_NR(VIDIOCSWIN):
case IOCTL_NR(VIDIOCGFBUF):
case IOCTL_NR(VIDIOCSFBUF):
case IOCTL_NR(MGSL_IOCSPARAMS):
case IOCTL_NR(MGSL_IOCGPARAMS):
case IOCTL_NR(ATM_GETNAMES):
case IOCTL_NR(ATM_GETLINKRATE):
case IOCTL_NR(ATM_GETTYPE):
case IOCTL_NR(ATM_GETESI):
case IOCTL_NR(ATM_GETADDR):
case IOCTL_NR(ATM_RSTADDR):
case IOCTL_NR(ATM_ADDADDR):
case IOCTL_NR(ATM_DELADDR):
case IOCTL_NR(ATM_GETCIRANGE):
case IOCTL_NR(ATM_SETCIRANGE):
case IOCTL_NR(ATM_SETESI):
case IOCTL_NR(ATM_SETESIF):
case IOCTL_NR(ATM_GETSTAT):
case IOCTL_NR(ATM_GETSTATZ):
case IOCTL_NR(ATM_GETLOOP):
case IOCTL_NR(ATM_SETLOOP):
case IOCTL_NR(ATM_QUERYLOOP):
case IOCTL_NR(ENI_SETMULT):
case IOCTL_NR(NS_GETPSTAT):
/* case IOCTL_NR(NS_SETBUFLEV): This is a duplicate case with ZATM_GETPOOLZ */
case IOCTL_NR(ZATM_GETPOOLZ):
case IOCTL_NR(ZATM_GETPOOL):
case IOCTL_NR(ZATM_SETPOOL):
case IOCTL_NR(ZATM_GETTHIST):
case IOCTL_NR(IDT77105_GETSTAT):
case IOCTL_NR(IDT77105_GETSTATZ):
case IOCTL_NR(IXJCTL_TONE_CADENCE):
case IOCTL_NR(IXJCTL_FRAMES_READ):
case IOCTL_NR(IXJCTL_FRAMES_WRITTEN):
case IOCTL_NR(IXJCTL_READ_WAIT):
case IOCTL_NR(IXJCTL_WRITE_WAIT):
case IOCTL_NR(IXJCTL_DRYBUFFER_READ):
case IOCTL_NR(I2OHRTGET):
case IOCTL_NR(I2OLCTGET):
case IOCTL_NR(I2OPARMSET):
case IOCTL_NR(I2OPARMGET):
case IOCTL_NR(I2OSWDL):
case IOCTL_NR(I2OSWUL):
case IOCTL_NR(I2OSWDEL):
case IOCTL_NR(I2OHTML):
break;
default:
return sys_ioctl(fd, cmd, (unsigned long)arg);
case IOCTL_NR(SG_IO):
return(sg_ioctl_trans(fd, cmd, arg));
}
printk(KERN_ERR "%x:unimplemented IA32 ioctl system call\n", cmd);
return -EINVAL;
}
......@@ -822,70 +822,3 @@ static struct ioctl32_list ioctl32_handler_table[] = {
#define NR_IOCTL32_HANDLERS (sizeof(ioctl32_handler_table) / \
sizeof(ioctl32_handler_table[0]))
static struct ioctl32_list *ioctl32_hash_table[1024];
static inline int ioctl32_hash(unsigned int cmd)
{
return ((cmd >> 6) ^ (cmd >> 4) ^ cmd) & 0x3ff;
}
int sys32_ioctl(unsigned int fd, unsigned int cmd, unsigned int arg)
{
int (*handler)(unsigned int, unsigned int, unsigned long, struct file * filp);
struct file *filp;
struct ioctl32_list *l;
int error;
l = ioctl32_hash_table[ioctl32_hash(cmd)];
error = -EBADF;
filp = fget(fd);
if (!filp)
return error;
if (!filp->f_op || !filp->f_op->ioctl) {
error = sys_ioctl (fd, cmd, arg);
goto out;
}
while (l && l->handler.cmd != cmd)
l = l->next;
if (l) {
handler = (void *)l->handler.function;
error = handler(fd, cmd, arg, filp);
} else {
error = -EINVAL;
printk("unknown ioctl: %08x\n", cmd);
}
out:
fput(filp);
return error;
}
static void ioctl32_insert(struct ioctl32_list *entry)
{
int hash = ioctl32_hash(entry->handler.cmd);
if (!ioctl32_hash_table[hash])
ioctl32_hash_table[hash] = entry;
else {
struct ioctl32_list *l;
l = ioctl32_hash_table[hash];
while (l->next)
l = l->next;
l->next = entry;
entry->next = 0;
}
}
static int __init init_ioctl32(void)
{
int i;
for (i = 0; i < NR_IOCTL32_HANDLERS; i++)
ioctl32_insert(&ioctl32_handler_table[i]);
return 0;
}
__initcall(init_ioctl32);
......@@ -287,7 +287,7 @@ illegal_syscall:
sys sys_acct 0
sys sys_umount 2
sys sys_ni_syscall 0
sys sys32_ioctl 3
sys compat_sys_ioctl 3
sys sys32_fcntl 3 /* 4055 */
sys sys_ni_syscall 2
sys sys_setpgid 2
......
This diff is collapsed.
......@@ -407,8 +407,7 @@ sys_call_table:
ENTRY_SAME(umount)
/* struct sockaddr... */
ENTRY_SAME(getpeername)
/* This one's a huge ugly mess */
ENTRY_DIFF(ioctl)
ENTRY_COMP(ioctl)
ENTRY_COMP(fcntl) /* 55 */
ENTRY_SAME(socketpair)
ENTRY_SAME(setpgid)
......
......@@ -431,11 +431,7 @@ static void siccuart_event(struct SICC_info *info, int event)
}
static void
#ifdef SUPPORT_SYSRQ
siccuart_rx_chars(struct SICC_info *info, struct pt_regs *regs)
#else
siccuart_rx_chars(struct SICC_info *info)
#endif
{
struct tty_struct *tty = info->tty;
unsigned int status, ch, rsr, flg, ignored = 0;
......@@ -574,25 +570,19 @@ static void siccuart_tx_chars(struct SICC_info *info)
}
static void siccuart_int_rx(int irq, void *dev_id, struct pt_regs *regs)
static irqreturn_t siccuart_int_rx(int irq, void *dev_id, struct pt_regs *regs)
{
struct SICC_info *info = dev_id;
#ifdef SUPPORT_SYSRQ
siccuart_rx_chars(info, regs);
#else
siccuart_rx_chars(info);
#endif
//powerpcClearUicsrBits(0x00000400);
siccuart_rx_chars(info, regs);
return IRQ_HANDLED;
}
static void siccuart_int_tx(int irq, void *dev_id, struct pt_regs *regs)
static irqreturn_t siccuart_int_tx(int irq, void *dev_id, struct pt_regs *regs)
{
struct SICC_info *info = dev_id;
siccuart_tx_chars(info);
return IRQ_HANDLED;
}
static void siccuart_tasklet_action(unsigned long data)
......
......@@ -122,7 +122,7 @@ struct scc_enet_private {
static int scc_enet_open(struct net_device *dev);
static int scc_enet_start_xmit(struct sk_buff *skb, struct net_device *dev);
static int scc_enet_rx(struct net_device *dev);
static void scc_enet_interrupt(int irq, void * dev_id, struct pt_regs * regs);
static irqreturn_t scc_enet_interrupt(int irq, void *dev_id, struct pt_regs *);
static int scc_enet_close(struct net_device *dev);
static struct net_device_stats *scc_enet_get_stats(struct net_device *dev);
static void set_multicast_list(struct net_device *dev);
......@@ -272,7 +272,7 @@ scc_enet_timeout(struct net_device *dev)
/* The interrupt handler.
* This is called from the CPM handler, not the MPC core interrupt.
*/
static void
static irqreturn_t
scc_enet_interrupt(int irq, void * dev_id, struct pt_regs * regs)
{
struct net_device *dev = dev_id;
......@@ -403,7 +403,7 @@ scc_enet_interrupt(int irq, void * dev_id, struct pt_regs * regs)
printk("SCC ENET: BSY can't happen.\n");
}
return;
return IRQ_HANDLED;
}
/* During a receive, the cur_rx points to the current incoming buffer.
......
......@@ -126,7 +126,7 @@ typedef struct {
static int fcc_enet_open(struct net_device *dev);
static int fcc_enet_start_xmit(struct sk_buff *skb, struct net_device *dev);
static int fcc_enet_rx(struct net_device *dev);
static void fcc_enet_interrupt(int irq, void * dev_id, struct pt_regs * regs);
static irqreturn_t fcc_enet_interrupt(int irq, void *dev_id, struct pt_regs *);
static int fcc_enet_close(struct net_device *dev);
static struct net_device_stats *fcc_enet_get_stats(struct net_device *dev);
static void set_multicast_list(struct net_device *dev);
......@@ -452,7 +452,7 @@ fcc_enet_timeout(struct net_device *dev)
}
/* The interrupt handler. */
static void
static irqreturn_t
fcc_enet_interrupt(int irq, void * dev_id, struct pt_regs * regs)
{
struct net_device *dev = dev_id;
......@@ -583,7 +583,7 @@ fcc_enet_interrupt(int irq, void * dev_id, struct pt_regs * regs)
if (int_events & FCC_ENET_BSY) {
cep->stats.rx_dropped++;
}
return;
return IRQ_HANDLED;
}
/* During a receive, the cur_rx points to the current incoming buffer.
......@@ -1203,7 +1203,7 @@ mii_discover_phy(uint mii_reg, struct net_device *dev)
}
/* This interrupt occurs when the PHY detects a link change. */
static void
static irqreturn_t
mii_link_interrupt(int irq, void * dev_id, struct pt_regs * regs)
{
struct net_device *dev = dev_id;
......@@ -1211,6 +1211,7 @@ mii_link_interrupt(int irq, void * dev_id, struct pt_regs * regs)
mii_do_cmd(dev, fep->phy->ack_int);
mii_do_cmd(dev, phy_cmd_relink); /* restart and display status */
return IRQ_HANDLED;
}
#endif /* CONFIG_USE_MDIO */
......
......@@ -570,7 +570,7 @@ static _INLINE_ void check_modem_status(struct async_struct *info)
/*
* This is the serial driver's interrupt routine for a single port
*/
static void rs_8xx_interrupt(int irq, void * dev_id, struct pt_regs * regs)
static irqreturn_t rs_8xx_interrupt(int irq, void * dev_id, struct pt_regs * regs)
{
u_char events;
int idx;
......@@ -610,6 +610,7 @@ static void rs_8xx_interrupt(int irq, void * dev_id, struct pt_regs * regs)
#ifdef SERIAL_DEBUG_INTR
printk("end.\n");
#endif
return IRQ_HANDLED;
}
......
......@@ -55,10 +55,6 @@
#include <asm/amigappc.h>
#endif
extern int cia_request_irq(int irq,
void (*handler)(int, void *, struct pt_regs *),
unsigned long flags, const char *devname, void *dev_id);
extern void cia_free_irq(unsigned int irq, void *dev_id);
extern void cia_init_IRQ(struct ciabase *base);
unsigned short ami_intena_vals[AMI_STD_IRQS] = {
......
......@@ -71,7 +71,7 @@ static char amiga_model_name[13] = "Amiga ";
extern char m68k_debug_device[];
static void amiga_sched_init(void (*handler)(int, void *, struct pt_regs *));
static void amiga_sched_init(irqreturn_t (*handler)(int, void *, struct pt_regs *));
/* amiga specific irq functions */
extern void amiga_init_IRQ (void);
extern void (*amiga_default_handler[]) (int, void *, struct pt_regs *);
......@@ -478,8 +478,8 @@ void __init config_amiga(void)
static unsigned short jiffy_ticks;
static void __init amiga_sched_init(void (*timer_routine)(int, void *,
struct pt_regs *))
static void __init amiga_sched_init(irqreturn_t (*timer_routine)(int, void *,
struct pt_regs *))
{
static struct resource sched_res = {
"timer", 0x00bfd400, 0x00bfd5ff,
......
......@@ -16,6 +16,7 @@
#include <asm/cputable.h>
#include <asm/ppc_asm.h>
#include <asm/offsets.h>
#include <asm/cache.h>
_GLOBAL(__setup_cpu_601)
blr
......@@ -63,13 +64,7 @@ _GLOBAL(__setup_cpu_7410)
mtspr SPRN_L2CR2,r3
mtlr r4
blr
_GLOBAL(__setup_cpu_7450)
mflr r4
bl setup_common_caches
bl setup_745x_specifics
mtlr r4
blr
_GLOBAL(__setup_cpu_7455)
_GLOBAL(__setup_cpu_745x)
mflr r4
bl setup_common_caches
bl setup_745x_specifics
......@@ -265,9 +260,10 @@ END_FTR_SECTION_IFCLR(CPU_FTR_NO_DPM)
#define CS_SIZE 28
.data
.balign 4
.balign L1_CACHE_LINE_SIZE
cpu_state_storage:
.space CS_SIZE
.balign L1_CACHE_LINE_SIZE,0
.text
/* Called in normal context to backup CPU 0 state. This
......@@ -277,6 +273,9 @@ cpu_state_storage:
* like HID0, HID1, MSSCR0, etc...
*/
_GLOBAL(__save_cpu_setup)
/* Some CR fields are volatile, we back it up all */
mfcr r7
/* Get storage ptr */
lis r5,cpu_state_storage@h
ori r5,r5,cpu_state_storage@l
......@@ -322,6 +321,7 @@ _GLOBAL(__save_cpu_setup)
mfspr r4,SPRN_HID1
stw r4,CS_HID1(r5)
1:
mtcr r7
blr
/* Called with no MMU context (typically MSR:IR/DR off) to
......@@ -329,6 +329,9 @@ _GLOBAL(__save_cpu_setup)
* function. This does not include cache setting
*/
_GLOBAL(__restore_cpu_setup)
/* Some CR fields are volatile, we back it up all */
mfcr r7
/* Get storage ptr */
lis r5,(cpu_state_storage-KERNELBASE)@h
ori r5,r5,cpu_state_storage@l
......@@ -411,5 +414,6 @@ _GLOBAL(__restore_cpu_setup)
/* Setup final PLL */
mtspr SPRN_HID1,r4
1:
mtcr r7
blr
......@@ -26,8 +26,7 @@ extern void __setup_cpu_750cx(unsigned long offset, int cpu_nr, struct cpu_spec*
extern void __setup_cpu_750fx(unsigned long offset, int cpu_nr, struct cpu_spec* spec);
extern void __setup_cpu_7400(unsigned long offset, int cpu_nr, struct cpu_spec* spec);
extern void __setup_cpu_7410(unsigned long offset, int cpu_nr, struct cpu_spec* spec);
extern void __setup_cpu_7450(unsigned long offset, int cpu_nr, struct cpu_spec* spec);
extern void __setup_cpu_7455(unsigned long offset, int cpu_nr, struct cpu_spec* spec);
extern void __setup_cpu_745x(unsigned long offset, int cpu_nr, struct cpu_spec* spec);
extern void __setup_cpu_power3(unsigned long offset, int cpu_nr, struct cpu_spec* spec);
extern void __setup_cpu_8xx(unsigned long offset, int cpu_nr, struct cpu_spec* spec);
extern void __setup_cpu_generic(unsigned long offset, int cpu_nr, struct cpu_spec* spec);
......@@ -168,7 +167,7 @@ struct cpu_spec cpu_specs[] = {
0xffff0000, 0x70000000, "750FX",
CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB |
CPU_FTR_L2CR | CPU_FTR_TAU | CPU_FTR_HPTE_TABLE | CPU_FTR_CAN_NAP |
CPU_FTR_DUAL_PLL_750FX,
CPU_FTR_DUAL_PLL_750FX | CPU_FTR_HAS_HIGH_BATS,
COMMON_PPC,
32, 32,
__setup_cpu_750fx
......@@ -216,7 +215,7 @@ struct cpu_spec cpu_specs[] = {
CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450,
COMMON_PPC | PPC_FEATURE_HAS_ALTIVEC,
32, 32,
__setup_cpu_7450
__setup_cpu_745x
},
{ /* 7450 2.1 */
0xffffffff, 0x80000201, "7450",
......@@ -226,7 +225,7 @@ struct cpu_spec cpu_specs[] = {
CPU_FTR_L3_DISABLE_NAP,
COMMON_PPC | PPC_FEATURE_HAS_ALTIVEC,
32, 32,
__setup_cpu_7450
__setup_cpu_745x
},
{ /* 7450 2.3 and newer */
0xffff0000, 0x80000000, "7450",
......@@ -235,35 +234,46 @@ struct cpu_spec cpu_specs[] = {
CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | CPU_FTR_NAP_DISABLE_L2_PR,
COMMON_PPC | PPC_FEATURE_HAS_ALTIVEC,
32, 32,
__setup_cpu_7450
__setup_cpu_745x
},
{ /* 7455 rev 1.x */
0xffffff00, 0x80010100, "7455",
CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | CPU_FTR_L3CR |
CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450,
CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | CPU_FTR_HAS_HIGH_BATS,
COMMON_PPC | PPC_FEATURE_HAS_ALTIVEC,
32, 32,
__setup_cpu_7455
__setup_cpu_745x
},
{ /* 7455 rev 2.0 */
0xffffffff, 0x80010200, "7455",
CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_CAN_NAP |
CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | CPU_FTR_L3CR |
CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | CPU_FTR_NAP_DISABLE_L2_PR |
CPU_FTR_L3_DISABLE_NAP,
CPU_FTR_L3_DISABLE_NAP | CPU_FTR_HAS_HIGH_BATS,
COMMON_PPC | PPC_FEATURE_HAS_ALTIVEC,
32, 32,
__setup_cpu_7455
__setup_cpu_745x
},
{ /* 7455 others */
0xffff0000, 0x80010000, "7455",
CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_CAN_NAP |
CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | CPU_FTR_L3CR |
CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | CPU_FTR_NAP_DISABLE_L2_PR,
CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | CPU_FTR_NAP_DISABLE_L2_PR |
CPU_FTR_HAS_HIGH_BATS,
COMMON_PPC | PPC_FEATURE_HAS_ALTIVEC,
32, 32,
__setup_cpu_745x
},
{ /* 7457 */
0xffff0000, 0x80020000, "7457",
CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_CAN_NAP |
CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | CPU_FTR_L3CR |
CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | CPU_FTR_NAP_DISABLE_L2_PR |
CPU_FTR_HAS_HIGH_BATS,
COMMON_PPC | PPC_FEATURE_HAS_ALTIVEC,
32, 32,
__setup_cpu_7455
__setup_cpu_745x
},
{ /* 82xx (8240, 8245, 8260 are all 603e cores) */
0x7fff0000, 0x00810000, "82xx",
......
......@@ -1451,6 +1451,30 @@ clear_bats:
mtspr IBAT2L,r10
mtspr IBAT3U,r10
mtspr IBAT3L,r10
BEGIN_FTR_SECTION
/* Here's a tweak: at this point, CPU setup have
* not been called yet, so HIGH_BAT_EN may not be
* set in HID0 for the 745x processors. However, it
* seems that doesn't affect our ability to actually
* write to these SPRs.
*/
mtspr SPRN_DBAT4U,r20
mtspr SPRN_DBAT4L,r20
mtspr SPRN_DBAT5U,r20
mtspr SPRN_DBAT5L,r20
mtspr SPRN_DBAT6U,r20
mtspr SPRN_DBAT6L,r20
mtspr SPRN_DBAT7U,r20
mtspr SPRN_DBAT7L,r20
mtspr SPRN_IBAT4U,r20
mtspr SPRN_IBAT4L,r20
mtspr SPRN_IBAT5U,r20
mtspr SPRN_IBAT5L,r20
mtspr SPRN_IBAT6U,r20
mtspr SPRN_IBAT6L,r20
mtspr SPRN_IBAT7U,r20
mtspr SPRN_IBAT7L,r20
END_FTR_SECTION_IFSET(CPU_FTR_HAS_HIGH_BATS)
blr
flush_tlbs:
......
......@@ -210,7 +210,8 @@ void free_irq(unsigned int irq, void* dev_id)
return;
}
int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
int request_irq(unsigned int irq,
irqreturn_t (*handler)(int, void *, struct pt_regs *),
unsigned long irqflags, const char * devname, void *dev_id)
{
struct irqaction *action;
......@@ -218,16 +219,9 @@ int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *)
if (irq >= NR_IRQS)
return -EINVAL;
if (!handler)
{
/*
* free_irq() used to be implemented as a call to
* request_irq() with handler being NULL. Now we have
* a real free_irq() but need to allow the old behavior
* for old code that hasn't caught up yet.
* -- Cort <cort@fsmlabs.com>
*/
free_irq(irq, dev_id);
if (!handler) {
printk(KERN_ERR "request_irq called with NULL handler!\n");
dump_stack();
return 0;
}
......@@ -246,8 +240,7 @@ int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *)
action->next = NULL;
retval = setup_irq(irq, action);
if (retval)
{
if (retval) {
kfree(action);
return retval;
}
......@@ -732,6 +725,7 @@ void init_irq_proc (void)
}
}
void no_action(int irq, void *dev, struct pt_regs *regs)
irqreturn_t no_action(int irq, void *dev, struct pt_regs *regs)
{
return IRQ_NONE;
}
......@@ -40,9 +40,11 @@
Author: Terry Greeniaus (tgree@phys.ualberta.ca)
Please e-mail updates to this file to me, thanks!
*/
#include <linux/config.h>
#include <asm/processor.h>
#include <asm/cputable.h>
#include <asm/ppc_asm.h>
#include <asm/cache.h>
/* Usage:
......@@ -101,6 +103,8 @@ BEGIN_FTR_SECTION
blr
END_FTR_SECTION_IFCLR(CPU_FTR_L2CR)
mflr r9
/* Stop DST streams */
BEGIN_FTR_SECTION
DSSALL
......@@ -115,6 +119,22 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
mtmsr r4
isync
/* Before we perform the global invalidation, we must disable dynamic
* power management via HID0[DPM] to work around a processor bug where
* DPM can possibly interfere with the state machine in the processor
* that invalidates the L2 cache tags.
*/
mfspr r8,HID0 /* Save HID0 in r8 */
rlwinm r4,r8,0,12,10 /* Turn off HID0[DPM] */
sync
mtspr HID0,r4 /* Disable DPM */
sync
/* Flush & disable L1 */
mr r5,r3
bl __flush_disable_L1
mr r3,r5
/* Get the current enable bit of the L2CR into r4 */
mfspr r4,L2CR
......@@ -136,27 +156,28 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
/**** Might be a good idea to set L2DO here - to prevent instructions
from getting into the cache. But since we invalidate
the next time we enable the cache it doesn't really matter.
Don't do this unless you accommodate all processor variations.
Don't do this unless you accomodate all processor variations.
The bit moved on the 7450.....
****/
/* TODO: use HW flush assist when available */
lis r4,0x0004
lis r4,0x0002
mtctr r4
li r4,0
1:
lwzx r0,r0,r4
addi r4,r4,32 /* Go to start of next cache line */
bdnz 1b
isync
/* Now, flush the first 4MB of memory */
lis r4,0x0004
lis r4,0x0002
mtctr r4
li r4,0
sync
1:
dcbf r0,r4
dcbf 0,r4
addi r4,r4,32 /* Go to start of next cache line */
bdnz 1b
......@@ -166,25 +187,19 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
* L1 icache
*/
b 20f
21:
.balign L1_CACHE_LINE_SIZE
22:
sync
mtspr L2CR,r3
sync
b 22f
b 23f
20:
b 21b
22:
/* Before we perform the global invalidation, we must disable dynamic
* power management via HID0[DPM] to work around a processor bug where
* DPM can possibly interfere with the state machine in the processor
* that invalidates the L2 cache tags.
*/
mfspr r8,HID0 /* Save HID0 in r8 */
rlwinm r4,r8,0,12,10 /* Turn off HID0[DPM] */
sync
mtspr HID0,r4 /* Disable DPM */
sync
b 21f
21: sync
isync
b 22b
23:
/* Perform a global invalidation */
oris r3,r3,0x0020
sync
......@@ -211,11 +226,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_SPEC7450)
mtspr L2CR,r3
sync
/* Restore HID0[DPM] to whatever it was before */
sync
mtspr 1008,r8
sync
/* See if we need to enable the cache */
cmplwi r5,0
beq 4f
......@@ -225,10 +235,20 @@ END_FTR_SECTION_IFSET(CPU_FTR_SPEC7450)
mtspr L2CR,r3
sync
4:
bl __inval_enable_L1
/* Restore HID0[DPM] to whatever it was before */
sync
mtspr 1008,r8
sync
/* Restore MSR (restores EE and DR bits to original state) */
4: SYNC
SYNC
mtmsr r7
isync
mtlr r9
blr
_GLOBAL(_get_L2CR)
......@@ -286,7 +306,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_L3CR)
li r4,0
1:
lwzx r0,r0,r4
dcbf r0,r4
dcbf 0,r4
addi r4,r4,32 /* Go to start of next cache line */
bdnz 1b
......@@ -360,3 +380,73 @@ END_FTR_SECTION_IFSET(CPU_FTR_L3CR)
/* --- End of PowerLogix code ---
*/
/* flush_disable_L1() - Flush and disable L1 cache
*
* clobbers r0, r3, ctr, cr0
*
*/
.globl __flush_disable_L1
__flush_disable_L1:
/* Stop pending alitvec streams and memory accesses */
BEGIN_FTR_SECTION
DSSALL
END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
sync
/* Load counter to 0x1000 cache lines (128k) and
* load cache with datas
*/
lis r3,0x0002
// li r3,0x1000 /* 128kB / 32B */
mtctr r3
li r3, 0
1:
lwz r0,0(r3)
addi r3,r3,0x0020 /* Go to start of next cache line */
bdnz 1b
isync
sync
/* Now flush those cache lines */
lis r3,0x0002
// li r3,0x1000 /* 128kB / 32B */
mtctr r3
li r3, 0
1:
dcbf 0,r3
addi r3,r3,0x0020 /* Go to start of next cache line */
bdnz 1b
sync
/* We can now disable the L1 cache (HID0:DCE, HID0:ICE) */
mfspr r3,SPRN_HID0
rlwinm r3,r3,0,18,15
mtspr SPRN_HID0,r3
sync
isync
blr
/* inval_enable_L1 - Invalidate and enable L1 cache
*
* Assumes L1 is already disabled and MSR:EE is off
*
* clobbers r3
*/
.globl __inval_enable_L1
__inval_enable_L1:
/* Enable and then Flash inval the instruction & data cache */
mfspr r3,SPRN_HID0
ori r3,r3, HID0_ICE|HID0_ICFI|HID0_DCE|HID0_DCI
sync
isync
mtspr SPRN_HID0,r3
xori r3,r3, HID0_ICFI|HID0_DCI
mtspr SPRN_HID0,r3
sync
blr
......@@ -46,6 +46,7 @@
#include <asm/cputable.h>
#include <asm/btext.h>
#include <asm/div64.h>
#include <asm/xmon.h>
#ifdef CONFIG_8xx
#include <asm/commproc.h>
......@@ -306,7 +307,6 @@ EXPORT_SYMBOL(tb_ticks_per_jiffy);
EXPORT_SYMBOL(get_wchan);
EXPORT_SYMBOL(console_drivers);
#ifdef CONFIG_XMON
extern void xmon_printf(char *fmt, ...);
EXPORT_SYMBOL(xmon);
EXPORT_SYMBOL(xmon_printf);
#endif
......
......@@ -34,6 +34,7 @@
#include <asm/system.h>
#include <asm/pmac_feature.h>
#include <asm/sections.h>
#include <asm/xmon.h>
#if defined CONFIG_KGDB
#include <asm/kgdb.h>
......@@ -46,9 +47,6 @@ extern void identify_cpu(unsigned long offset, unsigned long cpu);
extern void do_cpu_ftr_fixups(unsigned long offset);
extern void reloc_got2(unsigned long offset);
#ifdef CONFIG_XMON
extern void xmon_map_scc(void);
#endif
#ifdef CONFIG_KGDB
extern void kgdb_map_scc(void);
......
......@@ -35,6 +35,7 @@
#include <asm/time.h>
#include <asm/thread_info.h>
#include <asm/tlbflush.h>
#include <asm/xmon.h>
int smp_threads_ready;
volatile int smp_commenced;
......
......@@ -36,6 +36,7 @@
#include <asm/system.h>
#include <asm/io.h>
#include <asm/processor.h>
#include <asm/xmon.h>
#ifdef CONFIG_PMAC_BACKLIGHT
#include <asm/backlight.h>
#endif
......@@ -43,15 +44,6 @@
extern int fix_alignment(struct pt_regs *);
extern void bad_page_fault(struct pt_regs *, unsigned long, int sig);
#ifdef CONFIG_XMON
extern void xmon(struct pt_regs *regs);
extern int xmon_bpt(struct pt_regs *regs);
extern int xmon_sstep(struct pt_regs *regs);
extern int xmon_iabr_match(struct pt_regs *regs);
extern int xmon_dabr_match(struct pt_regs *regs);
extern void (*xmon_fault_handler)(struct pt_regs *regs);
#endif
#ifdef CONFIG_XMON
void (*debugger)(struct pt_regs *regs) = xmon;
int (*debugger_bpt)(struct pt_regs *regs) = xmon_bpt;
......
......@@ -49,7 +49,7 @@ typedef struct board_info {
#define _ISA_MEM_BASE 0
#define PCI_DRAM_OFFSET 0
#define BASE_BAUD 1312500
#define BASE_BAUD (378000000 / 18 / 16)
#define PPC4xx_MACHINE_NAME "IBM Redwood"
......
......@@ -45,9 +45,7 @@ typedef struct board_info {
#define _ISA_MEM_BASE 0
#define PCI_DRAM_OFFSET 0
/* serail defines moved from ppc4xx_serial.h *
*/
#define BASE_BAUD 1267200
#define BASE_BAUD (378000000 / 18 / 16)
#define PPC4xx_MACHINE_NAME "IBM Redwood5"
......
......@@ -46,7 +46,7 @@ typedef struct board_info {
#define _ISA_MEM_BASE 0
#define PCI_DRAM_OFFSET 0
#define BASE_BAUD 1267200
#define BASE_BAUD (378000000 / 18 / 16)
#define PPC4xx_MACHINE_NAME "IBM Redwood6"
......
......@@ -36,6 +36,7 @@
#include <linux/console.h>
#include <linux/seq_file.h>
#include <linux/root_dev.h>
#include <linux/initrd.h>
#include <asm/processor.h>
#include <asm/io.h>
......@@ -52,6 +53,7 @@
#include <asm/btext.h>
#include <asm/i8259.h>
#include <asm/open_pic.h>
#include <asm/xmon.h>
unsigned long chrp_get_rtc_time(void);
int chrp_set_rtc_time(unsigned long nowtime);
......@@ -67,6 +69,13 @@ void btext_progress(char *, unsigned short);
extern unsigned long pmac_find_end_of_memory(void);
extern int of_show_percpuinfo(struct seq_file *, int);
/*
* XXX this should be in xmon.h, but putting it there means xmon.h
* has to include <linux/interrupt.h> (to get irqreturn_t), which
* causes all sorts of problems. -- paulus
*/
extern irqreturn_t xmon_irq(int, void *, struct pt_regs *);
extern dev_t boot_dev;
extern PTE *Hash, *Hash_end;
......
......@@ -262,13 +262,19 @@ pmac_cpufreq_setup(void)
goto out;
cur_freq = (*value) / 1000;
/* Check for tibook 800Mhz or 1Ghz */
if (machine_is_compatible("PowerBook3,4") || machine_is_compatible("PowerBook3,5")) {
/* Check for newer machines */
if (machine_is_compatible("PowerBook3,4") ||
machine_is_compatible("PowerBook3,5") ||
machine_is_compatible("MacRISC3")) {
value = (u32 *)get_property(cpunode, "min-clock-frequency", NULL);
if (!value)
goto out;
low_freq = (*value) / 1000;
/* The PowerBook G4 12" (PowerBook6,1) has an error in the device-tree
* here */
if (low_freq < 100000)
low_freq *= 10;
value = (u32 *)get_property(cpunode, "max-clock-frequency", NULL);
if (!value)
goto out;
......
......@@ -52,8 +52,8 @@
#endif
/* Exported from arch/ppc/kernel/idle.c */
extern int powersave_nap;
extern int powersave_lowspeed;
extern int powersave_nap;
/*
* We use a single global lock to protect accesses. Each driver has
......@@ -1894,10 +1894,22 @@ static struct pmac_mb_def pmac_mb_defs[] __pmacdata = {
PMAC_TYPE_RACKMAC, rackmac_features,
0,
},
{ "RackMac1,2", "XServe rev. 2",
PMAC_TYPE_RACKMAC, rackmac_features,
0,
},
{ "PowerMac3,6", "PowerMac G4 Windtunnel",
PMAC_TYPE_WINDTUNNEL, rackmac_features,
0,
},
{ "PowerBook5,1", "PowerBook G4 17\"",
PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
},
{ "PowerBook6,1", "PowerBook G4 12\"",
PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
},
};
/*
......@@ -1994,8 +2006,8 @@ probe_motherboard(void)
pmac_mb.features = pangea_features;
break;
case macio_intrepid:
pmac_mb.model_id = PMAC_TYPE_UNKNOWN_PANGEA;
pmac_mb.model_name = "Unknown Pangea-based";
pmac_mb.model_id = PMAC_TYPE_UNKNOWN_INTREPID;
pmac_mb.model_name = "Unknown Intrepid-based";
pmac_mb.features = intrepid_features;
break;
default:
......
......@@ -30,9 +30,17 @@
#include <asm/pci-bridge.h>
#include <asm/time.h>
#include <asm/open_pic.h>
#include <asm/xmon.h>
#include "pmac_pic.h"
/*
* XXX this should be in xmon.h, but putting it there means xmon.h
* has to include <linux/interrupt.h> (to get irqreturn_t), which
* causes all sorts of problems. -- paulus
*/
extern irqreturn_t xmon_irq(int, void *, struct pt_regs *);
struct pmac_irq_hw {
unsigned int event;
unsigned int enable;
......@@ -177,7 +185,7 @@ struct hw_interrupt_type gatwick_pic = {
NULL
};
static void gatwick_action(int cpl, void *dev_id, struct pt_regs *regs)
static irqreturn_t gatwick_action(int cpl, void *dev_id, struct pt_regs *regs)
{
int irq, bits;
......@@ -190,16 +198,11 @@ static void gatwick_action(int cpl, void *dev_id, struct pt_regs *regs)
if (bits == 0)
continue;
irq += __ilog2(bits);
break;
ppc_irq_dispatch_handler(regs, irq);
return IRQ_HANDLED;
}
/* The previous version of this code allowed for this case, we
* don't. Put this here to check for it.
* -- Cort
*/
if ( irq_desc[irq].handler != &gatwick_pic )
printk("gatwick irq not from gatwick pic\n");
else
ppc_irq_dispatch_handler( regs, irq );
printk("gatwick irq not from gatwick pic\n");
return IRQ_NONE;
}
int
......@@ -393,7 +396,7 @@ pmac_pic_init(void)
nmi_irq = pswitch->intrs[0].line;
openpic_init_nmi_irq(nmi_irq);
request_irq(nmi_irq, xmon_irq, 0,
"NMI - XMON", 0);
"NMI - XMON", 0);
}
}
#endif /* CONFIG_XMON */
......
......@@ -15,6 +15,7 @@
#include <asm/page.h>
#include <asm/ppc_asm.h>
#include <asm/cputable.h>
#include <asm/cache.h>
#include <asm/thread_info.h>
#include <asm/offsets.h>
......@@ -157,33 +158,22 @@ _GLOBAL(low_sleep_handler)
addi r3,r3,sleep_storage@l
stw r5,0(r3)
BEGIN_FTR_SECTION
DSSALL
/* Disable DPM during cache flush */
mfspr r3, SPRN_HID0
rlwinm r3,r3,0,12,10
sync
END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
/*
* Flush the L1 data cache by reading the first 128kB of RAM
* and then flushing the same area with the dcbf instruction.
* The L2 cache has already been disabled.
*/
li r4,0x1000 /* 128kB / 32B */
mtctr r4
lis r4,KERNELBASE@h
1:
lwz r0,0(r4)
addi r4,r4,0x0020 /* Go to start of next cache line */
bdnz 1b
mtspr SPRN_HID0,r3
sync
li r4,0x1000 /* 128kB / 32B */
mtctr r4
lis r4,KERNELBASE@h
1:
dcbf r0,r4
addi r4,r4,0x0020 /* Go to start of next cache line */
bdnz 1b
/* Turn off data relocation. */
mfmsr r3 /* Save MSR in r7 */
rlwinm r3,r3,0,28,26 /* Turn off DR bit */
sync
mtmsr r3
isync
/* Flush & disable L1 cache */
bl __flush_disable_L1
/*
* Set the HID0 and MSR for sleep.
......@@ -192,6 +182,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
rlwinm r2,r2,0,10,7 /* clear doze, nap */
oris r2,r2,HID0_SLEEP@h
sync
isync
mtspr HID0,r2
sync
......@@ -252,16 +243,11 @@ _GLOBAL(core99_wake_up)
*/
grackle_wake_up:
/* Enable and then Flash inval the instruction & data cache */
mfspr r3,HID0
ori r3,r3, HID0_ICE|HID0_ICFI|HID0_DCE|HID0_DCI
sync
isync
mtspr HID0,r3
xori r3,r3, HID0_ICFI|HID0_DCI
mtspr HID0,r3
sync
/* Invalidate & enable L1 cache, we don't care about
* whatever the ROM may have tried to write to memory
*/
bl __inval_enable_L1
/* Restore the kernel's segment registers before
* we do any r1 memory access as we are not sure they
* are in a sane state above the first 256Mb region
......@@ -274,6 +260,8 @@ grackle_wake_up:
addi r3,r3,0x111 /* increment VSID */
addis r4,r4,0x1000 /* address of next segment */
bdnz 3b
sync
isync
subi r1,r1,SL_PC
......@@ -325,6 +313,26 @@ grackle_wake_up:
lwz r4,SL_IBAT3+4(r1)
mtibatl 3,r4
BEGIN_FTR_SECTION
li r4,0
mtspr SPRN_DBAT4U,r4
mtspr SPRN_DBAT4L,r4
mtspr SPRN_DBAT5U,r4
mtspr SPRN_DBAT5L,r4
mtspr SPRN_DBAT6U,r4
mtspr SPRN_DBAT6L,r4
mtspr SPRN_DBAT7U,r4
mtspr SPRN_DBAT7L,r4
mtspr SPRN_IBAT4U,r4
mtspr SPRN_IBAT4L,r4
mtspr SPRN_IBAT5U,r4
mtspr SPRN_IBAT5L,r4
mtspr SPRN_IBAT6U,r4
mtspr SPRN_IBAT6L,r4
mtspr SPRN_IBAT7U,r4
mtspr SPRN_IBAT7L,r4
END_FTR_SECTION_IFSET(CPU_FTR_HAS_HIGH_BATS)
/* Flush all TLBs */
lis r4,0x1000
1: addic. r4,r4,-0x1000
......@@ -368,8 +376,9 @@ turn_on_mmu:
#endif /* defined(CONFIG_PMAC_PBOOK) || defined(CONFIG_CPU_FREQ) */
.data
.globl sleep_storage
.section .data
.balign L1_CACHE_LINE_SIZE
sleep_storage:
.long 0
.balign L1_CACHE_LINE_SIZE, 0
.section .text
......@@ -3,6 +3,12 @@
*
* We support both the old "powersurge" SMP architecture
* and the current Core99 (G4 PowerMac) machines.
*
* Note that we don't support the very first rev. of
* Apple/DayStar 2 CPUs board, the one with the funky
* watchdog. Hopefully, none of these should be there except
* maybe internally to Apple. I should probably still add some
* code to detect this card though and disable SMP. --BenH.
*
* Support Macintosh G4 SMP by Troy Benjegerdes (hozer@drgw.net)
* and Ben Herrenschmidt <benh@kernel.crashing.org>.
......@@ -92,25 +98,22 @@ static volatile u32 *psurge_pri_intr;
static volatile u8 *psurge_sec_intr;
static volatile u32 *psurge_start;
/* what sort of powersurge board we have */
static int psurge_type;
/* values for psurge_type */
#define PSURGE_NONE -1
#define PSURGE_DUAL 0
#define PSURGE_QUAD_OKEE 1
#define PSURGE_QUAD_COTTON 2
#define PSURGE_QUAD_ICEGRASS 3
/* what sort of powersurge board we have */
static int psurge_type = PSURGE_NONE;
volatile static long int core99_l2_cache;
volatile static long int core99_l3_cache;
static void __init
core99_init_caches(int cpu)
{
/* Check cache presence on cpu 0, we assume all CPUs have
* same features here. We also assume that if we don't have
* L2CR, we don't have L3CR neither
*/
if (!(cur_cpu_spec[0]->cpu_features & CPU_FTR_L2CR))
return;
......@@ -143,6 +146,8 @@ core99_init_caches(int cpu)
*/
static inline void psurge_set_ipi(int cpu)
{
if (psurge_type == PSURGE_NONE)
return;
if (cpu == 0)
in_be32(psurge_pri_intr);
else if (psurge_type == PSURGE_DUAL)
......@@ -154,10 +159,14 @@ static inline void psurge_set_ipi(int cpu)
static inline void psurge_clr_ipi(int cpu)
{
if (cpu > 0) {
if (psurge_type == PSURGE_DUAL)
switch(psurge_type) {
case PSURGE_DUAL:
out_8(psurge_sec_intr, ~0);
else
case PSURGE_NONE:
break;
default:
PSURGE_QUAD_OUT(PSURGE_QUAD_IRQ_CLR, 1 << cpu);
}
}
}
......@@ -189,10 +198,11 @@ psurge_smp_message_recv(struct pt_regs *regs)
smp_message_recv(msg, regs);
}
void __pmac
irqreturn_t __pmac
psurge_primary_intr(int irq, void *d, struct pt_regs *regs)
{
psurge_smp_message_recv(regs);
return IRQ_HANDLED;
}
static void __pmac
......@@ -311,6 +321,7 @@ static int __init smp_psurge_probe(void)
if ((in_8(hhead_base + HHEAD_CONFIG) & 0x02) == 0) {
/* not a dual-cpu card */
iounmap((void *) hhead_base);
psurge_type = PSURGE_NONE;
return 1;
}
ncpus = 2;
......
......@@ -850,7 +850,7 @@ prep_res_calibrate_decr(void)
static volatile int calibrate_steps __initdata = 3;
static unsigned tbstamp __initdata = 0;
static void __init
static irqreturn_t __init
prep_calibrate_decr_handler(int irq, void *dev, struct pt_regs *regs)
{
unsigned long t, freq;
......@@ -866,6 +866,7 @@ prep_calibrate_decr_handler(int irq, void *dev, struct pt_regs *regs)
tb_ticks_per_jiffy = freq / HZ;
tb_to_us = mulhwu_scale_factor(freq, 1000000);
}
return IRQ_HANDLED;
}
static void __init
......
......@@ -44,6 +44,7 @@
#include <asm/machdep.h>
#include <asm/bootinfo.h>
#include <asm/time.h>
#include <asm/xmon.h>
#include "ppc8xx_pic.h"
......
......@@ -821,9 +821,10 @@ static void openpic_end_ipi(unsigned int irq_nr)
{
}
static void openpic_ipi_action(int cpl, void *dev_id, struct pt_regs *regs)
static irqreturn_t openpic_ipi_action(int cpl, void *dev_id, struct pt_regs *regs)
{
smp_message_recv(cpl-OPENPIC_VEC_IPI-open_pic_irq_offset, regs);
return IRQ_HANDLED;
}
#endif /* CONFIG_SMP */
......
......@@ -168,7 +168,8 @@ void mbx_i8259_action(int cpl, void *dev_id, struct pt_regs *regs)
* drivers that may mess up the internal interrupt controllers, and also
* allow them to run without modification on the MBX.
*/
int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
int request_irq(unsigned int irq,
irqreturn_t (*handler)(int, void *, struct pt_regs *),
unsigned long irqflags, const char * devname, void *dev_id)
{
......
......@@ -15,7 +15,6 @@ extern FILE *xmon_stdin, *xmon_stdout;
#define fflush(f) do {} while (0)
#define fclose(f) do {} while (0)
extern char *fgets(char *, int, void *);
extern void xmon_printf(const char *, ...);
extern void xmon_fprintf(void *, const char *, ...);
extern void xmon_sprintf(char *, const char *, ...);
extern void xmon_puts(char*);
......
......@@ -26,7 +26,6 @@
static volatile unsigned char *sccc, *sccd;
unsigned int TXRDY, RXRDY, DLAB;
extern void xmon_printf(const char *fmt, ...);
static int xmon_expect(const char *str, unsigned int timeout);
static int use_serial;
......
......@@ -7,12 +7,14 @@
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/smp.h>
#include <linux/interrupt.h>
#include <asm/ptrace.h>
#include <asm/string.h>
#include <asm/prom.h>
#include <asm/bitops.h>
#include <asm/bootx.h>
#include <asm/machdep.h>
#include <asm/xmon.h>
#ifdef CONFIG_PMAC_BACKLIGHT
#include <asm/backlight.h>
#endif
......@@ -103,7 +105,12 @@ static void cpu_cmd(void);
#endif /* CONFIG_SMP */
static int pretty_print_addr(unsigned long addr);
static void csum(void);
#ifdef CONFIG_BOOTX_TEXT
static void vidcmds(void);
#endif
static void bootcmds(void);
static void proccall(void);
static void printtime(void);
extern int print_insn_big_powerpc(FILE *, unsigned long, unsigned);
extern void printf(const char *fmt, ...);
......@@ -116,6 +123,9 @@ extern void xmon_leave(void);
extern char* xmon_find_symbol(unsigned long addr, unsigned long* saddr);
extern unsigned long xmon_symbol_to_addr(char* symbol);
static unsigned start_tb[NR_CPUS][2];
static unsigned stop_tb[NR_CPUS][2];
#define GETWORD(v) (((v)[0] << 24) + ((v)[1] << 16) + ((v)[2] << 8) + (v)[3])
#define isxdigit(c) (('0' <= (c) && (c) <= '9') \
......@@ -165,6 +175,20 @@ extern inline void __delay(unsigned int loops)
"r" (loops) : "ctr");
}
static void get_tb(unsigned *p)
{
unsigned hi, lo, hiagain;
if ((get_pvr() >> 16) == 1)
return;
do {
asm volatile("mftbu %0; mftb %1; mftbu %2"
: "=r" (hi), "=r" (lo), "=r" (hiagain));
} while (hi != hiagain);
p[0] = hi;
p[1] = lo;
}
void
xmon(struct pt_regs *excp)
......@@ -172,6 +196,7 @@ xmon(struct pt_regs *excp)
struct pt_regs regs;
int msr, cmd;
get_tb(stop_tb[smp_processor_id()]);
if (excp == NULL) {
asm volatile ("stw 0,0(%0)\n\
lwz 0,0(1)\n\
......@@ -234,17 +259,18 @@ xmon(struct pt_regs *excp)
clear_bit(smp_processor_id(), &cpus_in_xmon);
#endif /* CONFIG_SMP */
set_msr(msr); /* restore interrupt enable */
get_tb(start_tb[smp_processor_id()]);
}
void
irqreturn_t
xmon_irq(int irq, void *d, struct pt_regs *regs)
{
unsigned long flags;
local_save_flags(flags);
local_irq_disable();
local_irq_save(flags);
printf("Keyboard interrupt\n");
xmon(regs);
local_irq_restore(flags);
return IRQ_HANDLED;
}
int
......@@ -481,13 +507,39 @@ cmds(struct pt_regs *excp)
cpu_cmd();
break;
#endif /* CONFIG_SMP */
#ifdef CONFIG_BOOTX_TEXT
case 'v':
vidcmds();
break;
#endif
case 'z':
bootcmds();
break;
case 'p':
proccall();
break;
case 'T':
printtime();
break;
}
}
}
extern unsigned tb_to_us;
#define mulhwu(x,y) \
({unsigned z; asm ("mulhwu %0,%1,%2" : "=r" (z) : "r" (x), "r" (y)); z;})
static void printtime(void)
{
unsigned int delta;
delta = stop_tb[smp_processor_id()][1]
- start_tb[smp_processor_id()][1];
delta = mulhwu(tb_to_us, delta);
printf("%u.%06u seconds\n", delta / 1000000, delta % 1000000);
}
static void bootcmds(void)
{
int cmd;
......@@ -551,6 +603,44 @@ static void cpu_cmd(void)
}
#endif /* CONFIG_SMP */
#ifdef CONFIG_BOOTX_TEXT
extern boot_infos_t disp_bi;
static void vidcmds(void)
{
int c = inchar();
unsigned int val, w;
extern int boot_text_mapped;
if (!boot_text_mapped)
return;
if (c != '\n' && scanhex(&val)) {
switch (c) {
case 'd':
w = disp_bi.dispDeviceRowBytes
/ (disp_bi.dispDeviceDepth >> 3);
disp_bi.dispDeviceDepth = val;
disp_bi.dispDeviceRowBytes = w * (val >> 3);
return;
case 'p':
disp_bi.dispDeviceRowBytes = val;
return;
case 'w':
disp_bi.dispDeviceRect[2] = val;
return;
case 'h':
disp_bi.dispDeviceRect[3] = val;
return;
}
}
printf("W = %d (0x%x) H = %d (0x%x) D = %d (0x%x) P = %d (0x%x)\n",
disp_bi.dispDeviceRect[2], disp_bi.dispDeviceRect[2],
disp_bi.dispDeviceRect[3], disp_bi.dispDeviceRect[3],
disp_bi.dispDeviceDepth, disp_bi.dispDeviceDepth,
disp_bi.dispDeviceRowBytes, disp_bi.dispDeviceRowBytes);
}
#endif /* CONFIG_BOOTX_TEXT */
static unsigned short fcstab[256] = {
0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
......@@ -927,34 +1017,6 @@ super_regs()
scannl();
}
#if 0
static void
openforth()
{
int c;
char *p;
char cmd[1024];
int args[5];
extern int (*prom_entry)(int *);
p = cmd;
c = skipbl();
while (c != '\n') {
*p++ = c;
c = inchar();
}
*p = 0;
args[0] = (int) "interpret";
args[1] = 1;
args[2] = 1;
args[3] = (int) cmd;
(*prom_entry)(args);
printf("\n");
if (args[4] != 0)
printf("error %x\n", args[4]);
}
#endif
#ifndef CONFIG_PPC_STD_MMU
static void
dump_hash_table()
......@@ -1176,11 +1238,13 @@ mwrite(unsigned adrs, void *buf, int size)
}
static int fault_type;
static int fault_except;
static char *fault_chars[] = { "--", "**", "##" };
static void
handle_fault(struct pt_regs *regs)
{
fault_except = TRAP(regs);
fault_type = TRAP(regs) == 0x200? 0: TRAP(regs) == 0x300? 1: 2;
longjmp(bus_error_jmp, 1);
}
......@@ -1578,6 +1642,41 @@ memzcan()
printf("%.8x\n", a - mskip);
}
void proccall(void)
{
unsigned int args[8];
unsigned int ret;
int i;
typedef unsigned int (*callfunc_t)(unsigned int, unsigned int,
unsigned int, unsigned int, unsigned int,
unsigned int, unsigned int, unsigned int);
callfunc_t func;
scanhex(&adrs);
if (termch != '\n')
termch = 0;
for (i = 0; i < 8; ++i)
args[i] = 0;
for (i = 0; i < 8; ++i) {
if (!scanhex(&args[i]) || termch == '\n')
break;
termch = 0;
}
func = (callfunc_t) adrs;
ret = 0;
if (setjmp(bus_error_jmp) == 0) {
debugger_fault_handler = handle_fault;
sync();
ret = func(args[0], args[1], args[2], args[3],
args[4], args[5], args[6], args[7]);
sync();
printf("return value is %x\n", ret);
} else {
printf("*** %x exception occurred\n", fault_except);
}
debugger_fault_handler = 0;
}
/* Input scanning routines */
int
skipbl()
......
This diff is collapsed.
......@@ -556,8 +556,8 @@ _GLOBAL(sys_call_table32)
.llong .sys_acct
.llong .sys32_umount
.llong .sys_ni_syscall /* old lock syscall */
.llong .sys32_ioctl
.llong .compat_sys_fcntl /* 55 */
.llong .compat_sys_ioctl
.llong .compat_sys_fcntl /* 55 */
.llong .sys_ni_syscall /* old mpx syscall */
.llong .sys32_setpgid
.llong .sys_ni_syscall /* old ulimit syscall */
......
......@@ -972,113 +972,3 @@ static struct ioctl32_list ioctl32_handler_table[] = {
#define NR_IOCTL32_HANDLERS (sizeof(ioctl32_handler_table) / \
sizeof(ioctl32_handler_table[0]))
static struct ioctl32_list *ioctl32_hash_table[1024];
static inline int ioctl32_hash(unsigned int cmd)
{
return ((cmd >> 6) ^ (cmd >> 4) ^ cmd) & 0x3ff;
}
int sys32_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
{
int (*handler)(unsigned int, unsigned int, unsigned long, struct file * filp);
struct file *filp;
struct ioctl32_list *l;
int error;
l = ioctl32_hash_table[ioctl32_hash(cmd)];
error = -EBADF;
filp = fget(fd);
if (!filp)
return error;
if (!filp->f_op || !filp->f_op->ioctl) {
error = sys_ioctl (fd, cmd, arg);
goto out;
}
while (l && l->handler.cmd != cmd)
l = l->next;
if (l) {
handler = (void *)l->handler.function;
error = handler(fd, cmd, arg, filp);
} else {
error = -EINVAL;
printk("unknown ioctl: %08x\n", cmd);
}
out:
fput(filp);
return error;
}
static void ioctl32_insert(struct ioctl32_list *entry)
{
int hash = ioctl32_hash(entry->handler.cmd);
entry->next = 0;
if (!ioctl32_hash_table[hash])
ioctl32_hash_table[hash] = entry;
else {
struct ioctl32_list *l;
l = ioctl32_hash_table[hash];
while (l->next)
l = l->next;
l->next = entry;
}
}
int register_ioctl32_conversion(unsigned int cmd,
int (*handler)(unsigned int, unsigned int,
unsigned long, struct file *))
{
struct ioctl32_list *l, *new;
int hash;
hash = ioctl32_hash(cmd);
for (l = ioctl32_hash_table[hash]; l != NULL; l = l->next)
if (l->handler.cmd == cmd)
return -EBUSY;
new = kmalloc(sizeof(struct ioctl32_list), GFP_KERNEL);
if (new == NULL)
return -ENOMEM;
new->handler.cmd = cmd;
new->handler.function = (void *) handler;
ioctl32_insert(new);
return 0;
}
int unregister_ioctl32_conversion(unsigned int cmd)
{
struct ioctl32_list *p, *l;
int hash;
hash = ioctl32_hash(cmd);
p = NULL;
for (l = ioctl32_hash_table[hash]; l != NULL; l = l->next) {
if (l->handler.cmd == cmd)
break;
p = l;
}
if (l == NULL)
return -ENOENT;
if (p == NULL)
ioctl32_hash_table[hash] = l->next;
else
p->next = l->next;
kfree(l);
return 0;
}
static int __init init_ioctl32(void)
{
int i;
for (i = 0; i < NR_IOCTL32_HANDLERS; i++)
ioctl32_insert(&ioctl32_handler_table[i]);
return 0;
}
__initcall(init_ioctl32);
This diff is collapsed.
......@@ -10,4 +10,4 @@ obj-y := mul.o rem.o sdiv.o udiv.o umul.o urem.o ashrdi3.o memcpy.o memset.o \
strlen.o checksum.o blockops.o memscan.o memcmp.o strncmp.o \
strncpy_from_user.o divdi3.o udivdi3.o strlen_user.o \
copy_user.o locks.o atomic.o bitops.o debuglocks.o lshrdi3.o \
ashldi3.o rwsem.o muldi3.o
ashldi3.o rwsem.o muldi3.o bitext.o
/*
* bitext.c: kernel little helper (of bit shuffling variety).
*
* Copyright (C) 2002 Pete Zaitcev <zaitcev@yahoo.com>
*
* The algorithm to search a zero bit string is geared towards its application.
* We expect a couple of fixed sizes of requests, so a rotating counter, reset
* by align size, should provide fast enough search while maintaining low
* fragmentation.
*/
#include <linux/smp_lock.h>
#include <asm/bitext.h>
#include <asm/bitops.h>
/**
* bit_map_string_get - find and set a bit string in bit map.
* @t: the bit map.
* @len: requested string length
* @align: requested alignment
*
* Returns offset in the map or -1 if out of space.
*
* Not safe to call from an interrupt (uses spin_lock).
*/
int bit_map_string_get(struct bit_map *t, int len, int align)
{
int offset, count; /* siamese twins */
int off_new;
int align1;
int i;
if (align == 0)
align = 1;
align1 = align - 1;
if ((align & align1) != 0)
BUG();
if (align < 0 || align >= t->size)
BUG();
if (len <= 0 || len > t->size)
BUG();
spin_lock(&t->lock);
offset = t->last_off & ~align1;
count = 0;
for (;;) {
off_new = find_next_zero_bit(t->map, t->size, offset);
off_new = (off_new + align1) & ~align1;
count += off_new - offset;
offset = off_new;
if (offset >= t->size)
offset = 0;
if (count + len > t->size) {
spin_unlock(&t->lock);
/* P3 */ printk(KERN_ERR
"bitmap out: size %d used %d off %d len %d align %d count %d\n",
t->size, t->used, offset, len, align, count);
return -1;
}
if (offset + len > t->size) {
offset = 0;
count += t->size - offset;
continue;
}
i = 0;
while (test_bit(offset + i, t->map) == 0) {
i++;
if (i == len) {
for (i = 0; i < len; i++)
__set_bit(offset + i, t->map);
if ((t->last_off = offset + len) >= t->size)
t->last_off = 0;
t->used += len;
spin_unlock(&t->lock);
return offset;
}
}
count += i + 1;
if ((offset += i + 1) >= t->size)
offset = 0;
}
}
void bit_map_clear(struct bit_map *t, int offset, int len)
{
int i;
if (t->used < len)
BUG(); /* Much too late to do any good, but alas... */
spin_lock(&t->lock);
for (i = 0; i < len; i++) {
if (test_bit(offset + i, t->map) == 0)
BUG();
__clear_bit(offset + i, t->map);
}
t->used -= len;
spin_unlock(&t->lock);
}
void bit_map_init(struct bit_map *t, unsigned long *map, int size)
{
if ((size & 07) != 0)
BUG();
memset(map, 0, size>>3);
memset(t, 0, sizeof *t);
spin_lock_init(&t->lock);
t->map = map;
t->size = size;
}
......@@ -88,8 +88,6 @@ void show_mem(void)
#endif
}
extern pgprot_t protection_map[16];
void __init sparc_context_init(int numctx)
{
int ctx;
......
......@@ -176,13 +176,15 @@ static void iounit_release_scsi_sgl(struct scatterlist *sg, int sz, struct sbus_
}
#ifdef CONFIG_SBUS
static void iounit_map_dma_area(unsigned long va, __u32 addr, int len)
static int iounit_map_dma_area(dma_addr_t *pba, unsigned long va, __u32 addr, int len)
{
unsigned long page, end;
pgprot_t dvma_prot;
iopte_t *iopte;
struct sbus_bus *sbus;
*pba = addr;
dvma_prot = __pgprot(SRMMU_CACHE | SRMMU_ET_PTE | SRMMU_PRIV);
end = PAGE_ALIGN((addr + len));
while(addr < end) {
......@@ -213,6 +215,8 @@ static void iounit_map_dma_area(unsigned long va, __u32 addr, int len)
}
flush_cache_all();
flush_tlb_all();
return 0;
}
static void iounit_unmap_dma_area(unsigned long addr, int len)
......@@ -221,7 +225,7 @@ static void iounit_unmap_dma_area(unsigned long addr, int len)
}
/* XXX We do not pass sbus device here, bad. */
static unsigned long iounit_translate_dvma(unsigned long addr)
static struct page *iounit_translate_dvma(unsigned long addr)
{
struct sbus_bus *sbus = sbus_root; /* They are all the same */
struct iounit_struct *iounit = (struct iounit_struct *)sbus->iommu;
......@@ -230,7 +234,7 @@ static unsigned long iounit_translate_dvma(unsigned long addr)
i = ((addr - IOUNIT_DMA_BASE) >> PAGE_SHIFT);
iopte = (iopte_t *)(iounit->page_table + i);
return (iopte_val(*iopte) & 0xFFFFFFF0) << 4; /* XXX sun4d guru, help */
return pfn_to_page(iopte_val(*iopte) >> (PAGE_SHIFT-4)); /* XXX sun4d guru, help */
}
#endif
......
This diff is collapsed.
......@@ -26,7 +26,6 @@ unsigned int pg_iobits;
extern void ld_mmu_sun4c(void);
extern void ld_mmu_srmmu(void);
extern void ioport_init(void);
void __init load_mmu(void)
{
......@@ -44,5 +43,4 @@ void __init load_mmu(void)
prom_halt();
}
btfixup();
ioport_init();
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -91,7 +91,7 @@ extern int sys_getgid(void);
extern int svr4_getcontext(svr4_ucontext_t *uc, struct pt_regs *regs);
extern int svr4_setcontext(svr4_ucontext_t *uc, struct pt_regs *regs);
extern int sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg);
extern int sys32_ioctl(unsigned int fd, unsigned int cmd, u32 arg);
extern int compat_sys_ioctl(unsigned int fd, unsigned int cmd, u32 arg);
extern int (*handle_mathemu)(struct pt_regs *, struct fpustate *);
extern long sparc32_open(const char * filename, int flags, int mode);
extern int register_ioctl32_conversion(unsigned int cmd, int (*handler)(unsigned int, unsigned int, unsigned long, struct file *));
......@@ -319,7 +319,7 @@ EXPORT_SYMBOL(svr4_getcontext);
EXPORT_SYMBOL(svr4_setcontext);
EXPORT_SYMBOL(prom_cpu_nodes);
EXPORT_SYMBOL(sys_ioctl);
EXPORT_SYMBOL(sys32_ioctl);
EXPORT_SYMBOL(compat_sys_ioctl);
EXPORT_SYMBOL(sparc32_open);
#endif
......
This diff is collapsed.
......@@ -29,7 +29,7 @@ sys_call_table32:
.word sys_chown, sys_sync, sys_kill, compat_sys_newstat, sys32_sendfile
/*40*/ .word compat_sys_newlstat, sys_dup, sys_pipe, compat_sys_times, sys_getuid
.word sys_umount, sys32_setgid16, sys32_getgid16, sys_signal, sys32_geteuid16
/*50*/ .word sys32_getegid16, sys_acct, sys_nis_syscall, sys_getgid, sys32_ioctl
/*50*/ .word sys32_getegid16, sys_acct, sys_nis_syscall, sys_getgid, compat_sys_ioctl
.word sys_reboot, sys32_mmap2, sys_symlink, sys_readlink, sys32_execve
/*60*/ .word sys_umask, sys_chroot, compat_sys_newfstat, sys_fstat64, sys_getpagesize
.word sys_msync, sys_vfork, sys32_pread64, sys32_pwrite64, sys_geteuid
......
This diff is collapsed.
......@@ -29,8 +29,6 @@
extern asmlinkage int sys_ioctl(unsigned int fd, unsigned int cmd,
unsigned long arg);
extern asmlinkage int sys32_ioctl(unsigned int fd, unsigned int cmd,
u32 arg);
asmlinkage int solaris_ioctl(unsigned int fd, unsigned int cmd, u32 arg);
static spinlock_t timod_pagelock = SPIN_LOCK_UNLOCKED;
......
This diff is collapsed.
......@@ -258,7 +258,7 @@ ia32_sys_call_table:
.quad sys_acct
.quad sys_umount /* new_umount */
.quad ni_syscall /* old lock syscall holder */
.quad sys32_ioctl
.quad compat_sys_ioctl
.quad compat_sys_fcntl64 /* 55 */
.quad ni_syscall /* old mpx syscall holder */
.quad sys_setpgid
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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