diff options
-rw-r--r-- | arch/mips64/kernel/linux32.c | 89 | ||||
-rw-r--r-- | arch/mips64/kernel/scall_o32.S | 4 | ||||
-rw-r--r-- | arch/mips64/sgi-ip27/ip27-timer.c | 88 |
3 files changed, 131 insertions, 50 deletions
diff --git a/arch/mips64/kernel/linux32.c b/arch/mips64/kernel/linux32.c index f7e2f41cb..9c6643f81 100644 --- a/arch/mips64/kernel/linux32.c +++ b/arch/mips64/kernel/linux32.c @@ -5,7 +5,6 @@ * Written by Ulf Carlsson (ulfc@engr.sgi.com) * sys32_execve from ia64/ia32 code, Feb 2000, Kanoj Sarcar (kanoj@sgi.com) */ - #include <linux/mm.h> #include <linux/errno.h> #include <linux/file.h> @@ -24,6 +23,8 @@ #include <linux/msg.h> #include <linux/sysctl.h> #include <linux/utsname.h> +#include <linux/personality.h> +#include <linux/timex.h> #include <asm/uaccess.h> #include <asm/mman.h> @@ -1884,3 +1885,89 @@ asmlinkage long sys32_newuname(struct new_utsname * name) return ret; } + +extern asmlinkage long sys_personality(unsigned long); + +asmlinkage int sys32_personality(unsigned long personality) +{ + int ret; + if (current->personality == PER_LINUX32 && personality == PER_LINUX) + personality = PER_LINUX32; + ret = sys_personality(personality); + if (ret == PER_LINUX32) + ret = PER_LINUX; + return ret; +} + +/* Handle adjtimex compatability. */ + +struct timex32 { + u32 modes; + s32 offset, freq, maxerror, esterror; + s32 status, constant, precision, tolerance; + struct timeval32 time; + s32 tick; + s32 ppsfreq, jitter, shift, stabil; + s32 jitcnt, calcnt, errcnt, stbcnt; + s32 :32; s32 :32; s32 :32; s32 :32; + s32 :32; s32 :32; s32 :32; s32 :32; + s32 :32; s32 :32; s32 :32; s32 :32; +}; + +extern int do_adjtimex(struct timex *); + +asmlinkage int sys32_adjtimex(struct timex32 *utp) +{ + struct timex txc; + int ret; + + memset(&txc, 0, sizeof(struct timex)); + + if(get_user(txc.modes, &utp->modes) || + __get_user(txc.offset, &utp->offset) || + __get_user(txc.freq, &utp->freq) || + __get_user(txc.maxerror, &utp->maxerror) || + __get_user(txc.esterror, &utp->esterror) || + __get_user(txc.status, &utp->status) || + __get_user(txc.constant, &utp->constant) || + __get_user(txc.precision, &utp->precision) || + __get_user(txc.tolerance, &utp->tolerance) || + __get_user(txc.time.tv_sec, &utp->time.tv_sec) || + __get_user(txc.time.tv_usec, &utp->time.tv_usec) || + __get_user(txc.tick, &utp->tick) || + __get_user(txc.ppsfreq, &utp->ppsfreq) || + __get_user(txc.jitter, &utp->jitter) || + __get_user(txc.shift, &utp->shift) || + __get_user(txc.stabil, &utp->stabil) || + __get_user(txc.jitcnt, &utp->jitcnt) || + __get_user(txc.calcnt, &utp->calcnt) || + __get_user(txc.errcnt, &utp->errcnt) || + __get_user(txc.stbcnt, &utp->stbcnt)) + return -EFAULT; + + ret = do_adjtimex(&txc); + + if(put_user(txc.modes, &utp->modes) || + __put_user(txc.offset, &utp->offset) || + __put_user(txc.freq, &utp->freq) || + __put_user(txc.maxerror, &utp->maxerror) || + __put_user(txc.esterror, &utp->esterror) || + __put_user(txc.status, &utp->status) || + __put_user(txc.constant, &utp->constant) || + __put_user(txc.precision, &utp->precision) || + __put_user(txc.tolerance, &utp->tolerance) || + __put_user(txc.time.tv_sec, &utp->time.tv_sec) || + __put_user(txc.time.tv_usec, &utp->time.tv_usec) || + __put_user(txc.tick, &utp->tick) || + __put_user(txc.ppsfreq, &utp->ppsfreq) || + __put_user(txc.jitter, &utp->jitter) || + __put_user(txc.shift, &utp->shift) || + __put_user(txc.stabil, &utp->stabil) || + __put_user(txc.jitcnt, &utp->jitcnt) || + __put_user(txc.calcnt, &utp->calcnt) || + __put_user(txc.errcnt, &utp->errcnt) || + __put_user(txc.stbcnt, &utp->stbcnt)) + ret = -EFAULT; + + return ret; +} diff --git a/arch/mips64/kernel/scall_o32.S b/arch/mips64/kernel/scall_o32.S index 6d3f211d7..4d1450a6b 100644 --- a/arch/mips64/kernel/scall_o32.S +++ b/arch/mips64/kernel/scall_o32.S @@ -325,7 +325,7 @@ illegal_syscall: sys sys_setdomainname 2 sys sys32_newuname 1 sys sys_ni_syscall 0 /* sys_modify_ldt */ - sys sys_adjtimex 1 + sys sys32_adjtimex 1 sys sys_mprotect 3 /* 4125 */ sys sys32_sigprocmask 3 sys sys_create_module 2 @@ -337,7 +337,7 @@ illegal_syscall: sys sys_fchdir 1 sys sys_bdflush 2 sys sys_sysfs 3 /* 4135 */ - sys sys_personality 1 + sys sys32_personality 1 sys sys_ni_syscall 0 /* for afs_syscall */ sys sys_setfsuid 1 sys sys_setfsgid 1 diff --git a/arch/mips64/sgi-ip27/ip27-timer.c b/arch/mips64/sgi-ip27/ip27-timer.c index 0682ea3e6..90b3e3e75 100644 --- a/arch/mips64/sgi-ip27/ip27-timer.c +++ b/arch/mips64/sgi-ip27/ip27-timer.c @@ -23,7 +23,8 @@ #include <asm/sn/sn0/ip27.h> #include <asm/sn/sn0/hub.h> -/* This is a hack; we really need to figure these values out dynamically +/* + * This is a hack; we really need to figure these values out dynamically * * Since 800 ns works very well with various HUB frequencies, such as * 360, 380, 390 and 400 MHZ, we use 800 ns rtc cycle time. @@ -43,49 +44,47 @@ extern volatile unsigned long wall_jiffies; static int set_rtc_mmss(unsigned long nowtime) -{ - int retval = 0; - int real_seconds, real_minutes, cmos_minutes; +{ + int retval = 0; + int real_seconds, real_minutes, cmos_minutes; struct m48t35_rtc *rtc; nasid_t nid; nid = get_nasid(); - rtc = (struct m48t35_rtc *) - KL_CONFIG_CH_CONS_INFO(nid)->memory_base + IOC3_BYTEBUS_DEV0; - + rtc = (struct m48t35_rtc *)(KL_CONFIG_CH_CONS_INFO(nid)->memory_base + + IOC3_BYTEBUS_DEV0); + rtc->control |= M48T35_RTC_READ; cmos_minutes = rtc->min; BCD_TO_BIN(cmos_minutes); rtc->control &= ~M48T35_RTC_READ; - - /* - * Since we're only adjusting minutes and seconds, - * don't interfere with hour overflow. This avoids - * messing with unknown time zones but requires your - * RTC not to be off by more than 15 minutes - */ - real_seconds = nowtime % 60; - real_minutes = nowtime / 60; - if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1) - real_minutes += 30; /* correct for half hour time zone */ - real_minutes %= 60; - - if (abs(real_minutes - cmos_minutes) < 30) { + + /* + * Since we're only adjusting minutes and seconds, don't interfere with + * hour overflow. This avoids messing with unknown time zones but + * requires your RTC not to be off by more than 15 minutes + */ + real_seconds = nowtime % 60; + real_minutes = nowtime / 60; + if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1) + real_minutes += 30; /* correct for half hour time zone */ + real_minutes %= 60; + + if (abs(real_minutes - cmos_minutes) < 30) { BIN_TO_BCD(real_seconds); BIN_TO_BCD(real_minutes); rtc->control |= M48T35_RTC_SET; - rtc->sec = real_seconds; - rtc->min = real_minutes; + rtc->sec = real_seconds; + rtc->min = real_minutes; rtc->control &= ~M48T35_RTC_SET; - } else { - printk(KERN_WARNING - "set_rtc_mmss: can't update from %d to %d\n", - cmos_minutes, real_minutes); - retval = -1; - } + } else { + printk(KERN_WARNING + "set_rtc_mmss: can't update from %d to %d\n", + cmos_minutes, real_minutes); + retval = -1; + } - - return retval; + return retval; } void rt_timer_interrupt(struct pt_regs *regs) @@ -125,14 +124,13 @@ again: } #endif /* CONFIG_SMP */ - /* - * If we have an externally synchronized Linux clock, then update - * RTC clock accordingly every ~11 minutes. Set_rtc_mmss() has to be - * called as close as possible to when a second starts. - */ - - if ((time_status & STA_UNSYNC) == 0 && - xtime.tv_sec > last_rtc_update + 660) { + /* + * If we have an externally synchronized Linux clock, then update + * RTC clock accordingly every ~11 minutes. Set_rtc_mmss() has to be + * called as close as possible to when a second starts. + */ + if ((time_status & STA_UNSYNC) == 0 && + xtime.tv_sec > last_rtc_update + 660) { if (xtime.tv_usec >= 1000000 - ((unsigned) tick) / 2) { if (set_rtc_mmss(xtime.tv_sec + 1) == 0) last_rtc_update = xtime.tv_sec; @@ -238,10 +236,8 @@ static inline unsigned long mktime(unsigned int year, unsigned int mon, )*60 + sec; /* finally seconds */ } -#define DEBUG_RTC - -static unsigned long __init get_m48t35_time(void) -{ +static __init unsigned long get_m48t35_time(void) +{ unsigned int year, month, date, hour, min, sec; struct m48t35_rtc *rtc; nasid_t nid; @@ -250,7 +246,7 @@ static unsigned long __init get_m48t35_time(void) rtc = (struct m48t35_rtc *)(KL_CONFIG_CH_CONS_INFO(nid)->memory_base + IOC3_BYTEBUS_DEV0); - rtc->control |= M48T35_RTC_READ; + rtc->control |= M48T35_RTC_READ; sec = rtc->sec; min = rtc->min; hour = rtc->hour; @@ -271,8 +267,6 @@ static unsigned long __init get_m48t35_time(void) return mktime(year, month, date, hour, min, sec); } -extern void ioc3_eth_init(void); - void __init time_init(void) { xtime.tv_sec = get_m48t35_time(); @@ -284,7 +278,7 @@ void __init cpu_time_init(void) lboard_t *board; klcpu_t *cpu; int cpuid; - + /* Don't use ARCS. ARCS is fragile. Klconfig is simple and sane. */ board = find_lboard(KL_CONFIG_INFO(get_nasid()), KLTYPE_IP27); if (!board) |