summaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2000-09-05 21:30:08 +0000
committerRalf Baechle <ralf@linux-mips.org>2000-09-05 21:30:08 +0000
commit73c5c49c4d59b104dd3fc00a3e23ec73fc1a9e9c (patch)
tree9aa42e87ed13ed5b8943c72831b73ba7b675419b /arch
parentcd6236bd58e553626c20d99234566a4dbbf1734a (diff)
- adjtimex(2) emulation.
- set_rtc_mmss was crashing the machine. This went unnoticed so far only because it only happens one the machine is time synchronized. The machine now synchronizes with NTP quite well. - Better personality(2) emulation. This code is taken from Sparc64 which seems to do the right thing but I still wonder how it's supposed to work there. Uname(2) returning sparc64 or mips64 instead of sparc or mips is breaking alot of configuration scripts but on the other side returning the arch name without the 64 would prevent easy detection of the architecture by autoconf style scripts. I also don't see how the personality of 32-bit processes is ever being set to PER_LINUX32.
Diffstat (limited to 'arch')
-rw-r--r--arch/mips64/kernel/linux32.c89
-rw-r--r--arch/mips64/kernel/scall_o32.S4
-rw-r--r--arch/mips64/sgi-ip27/ip27-timer.c88
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)