diff -3prN linux.org/Makefile linux.rt/Makefile *** linux.org/Makefile Wed Feb 9 09:53:03 2000 --- linux.rt/Makefile Wed Feb 9 21:46:17 2000 *************** BOARD = ucsimm *** 19,24 **** --- 19,27 ---- # SMP profiling options # SMP_PROF = 1 + # For RT-kernel set this + # RT = 1 (moved to config.in, kwonsk) + .EXPORT_ALL_VARIABLES: CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \ *************** ifdef SMP_PROF *** 111,116 **** --- 114,123 ---- CFLAGS += -D__SMP_PROF__ AFLAGS += -D__SMP_PROF__ endif + endif + + ifdef RT + CFLAGS += -D__RT__ endif # diff -3prN linux.org/arch/m68knommu/config.in linux.rt/arch/m68knommu/config.in *** linux.org/arch/m68knommu/config.in Wed Feb 9 09:53:03 2000 --- linux.rt/arch/m68knommu/config.in Wed Feb 9 21:46:17 2000 *************** if [ "$CONFIG_M68EZ328" = "y" ]; then *** 48,53 **** --- 48,54 ---- fi bool 'ALMA Electronics Answering Machine support' CONFIG_ALMA_ANS bool 'uCsimm module support' CONFIG_UCSIMM + bool 'Hard realtime support for uClinux 2.0.38' RT fi if [ "$CONFIG_M68332" = "y" ]; then diff -3prN linux.org/arch/m68knommu/kernel/Makefile linux.rt/arch/m68knommu/kernel/Makefile *** linux.org/arch/m68knommu/kernel/Makefile Wed Feb 9 09:53:04 2000 --- linux.rt/arch/m68knommu/kernel/Makefile Wed Feb 9 21:46:17 2000 *************** *** 7,14 **** --- 7,20 ---- # # Note 2! The CFLAGS definitions are now in the main makefile... + ifdef RT + .S.o: + $(CC) -D__RT__ -D__ASSEMBLY__ $(AFLAGS) -traditional -c $< -o $*.o + else .S.o: $(CC) -D__ASSEMBLY__ $(AFLAGS) -traditional -c $< -o $*.o + endif + all: kernel.o O_TARGET := kernel.o diff -3prN linux.org/arch/m68knommu/kernel/ksyms.c linux.rt/arch/m68knommu/kernel/ksyms.c *** linux.org/arch/m68knommu/kernel/ksyms.c Wed Feb 9 09:53:04 2000 --- linux.rt/arch/m68knommu/kernel/ksyms.c Wed Feb 9 21:46:17 2000 *************** *** 11,16 **** --- 11,17 ---- #include #include #include + #include asmlinkage long long __ashrdi3 (long long, int); extern char m68k_debug_device[]; *************** static struct symbol_table arch_symbol_t *** 29,34 **** --- 30,38 ---- X(dump_thread), X(strnlen), X(strstr), + #ifdef __RT__ + X(rtf_init), + #endif /* The following are special because they're not called explicitly (the C compiler generates them). Fortunately, diff -3prN linux.org/arch/m68knommu/kernel/rtl/.depend linux.rt/arch/m68knommu/kernel/rtl/.depend *** linux.org/arch/m68knommu/kernel/rtl/.depend Thu Jan 1 09:00:00 1970 --- linux.rt/arch/m68knommu/kernel/rtl/.depend Wed Feb 9 21:46:17 2000 *************** *** 0 **** --- 1,34 ---- + rt_time.o: \ + /home/kwonsk/uClinux/testing/linux/include/asm/io.h \ + /home/kwonsk/uClinux/testing/linux/include/linux/errno.h \ + /home/kwonsk/uClinux/testing/linux/include/asm/system.h \ + /home/kwonsk/uClinux/testing/linux/include/asm/rt_time.h \ + /home/kwonsk/uClinux/testing/linux/include/asm/rt_irq.h \ + /home/kwonsk/uClinux/testing/linux/include/linux/sched.h \ + /home/kwonsk/uClinux/testing/linux/include/linux/timex.h \ + /home/kwonsk/uClinux/testing/linux/include/asm/MC68EZ328.h \ + /home/kwonsk/uClinux/testing/linux/include/linux/cons.h + rtl_fifo.o: \ + /home/kwonsk/uClinux/testing/linux/include/linux/major.h \ + /home/kwonsk/uClinux/testing/linux/include/linux/kernel.h \ + /home/kwonsk/uClinux/testing/linux/include/linux/errno.h \ + /home/kwonsk/uClinux/testing/linux/include/linux/malloc.h \ + /home/kwonsk/uClinux/testing/linux/include/rtl/rtl_fifo.h \ + /home/kwonsk/uClinux/testing/linux/include/asm/system.h \ + /home/kwonsk/uClinux/testing/linux/include/rtl/rtl_sync.h + rtl_sched.o: \ + /home/kwonsk/uClinux/testing/linux/include/linux/kernel.h \ + /home/kwonsk/uClinux/testing/linux/include/linux/version.h \ + /home/kwonsk/uClinux/testing/linux/include/linux/errno.h \ + /home/kwonsk/uClinux/testing/linux/include/linux/malloc.h \ + /home/kwonsk/uClinux/testing/linux/include/asm/system.h \ + /home/kwonsk/uClinux/testing/linux/include/linux/timex.h \ + /home/kwonsk/uClinux/testing/linux/include/asm/rt_time.h \ + /home/kwonsk/uClinux/testing/linux/include/asm/rt_irq.h \ + /home/kwonsk/uClinux/testing/linux/include/rtl/rtl_sync.h \ + /home/kwonsk/uClinux/testing/linux/include/linux/kernel.h \ + /home/kwonsk/uClinux/testing/linux/include/rtl/rtl_sched.h \ + /home/kwonsk/uClinux/testing/linux/include/linux/cons.h \ + /home/kwonsk/uClinux/testing/linux/include/asm/segment.h \ + /home/kwonsk/uClinux/testing/linux/include/rtl/switch.h \ + /home/kwonsk/uClinux/testing/linux/include/asm/MC68EZ328.h diff -3prN linux.org/arch/m68knommu/kernel/rtl/Makefile linux.rt/arch/m68knommu/kernel/rtl/Makefile *** linux.org/arch/m68knommu/kernel/rtl/Makefile Thu Jan 1 09:00:00 1970 --- linux.rt/arch/m68knommu/kernel/rtl/Makefile Wed Feb 9 21:46:17 2000 *************** *** 0 **** --- 1,26 ---- + # + # Makefile for Linux arch/m68knommu/kernel/rtl source directory + # + # Note! Dependencies are done automagically by 'make dep', which also + # removes any old dependencies. DON'T put your own dependencies here + # unless it's something special (ie not a .c file). + # + + L_TARGET = rtl.a + L_OBJS = rtl_fifo.o rtl_sched.o rt_time.o + M_OBJS = + + all: rtl_app.o rtl.a + O_TARGET := rtl_app.o + + # !!!!!!!!!!!!!!!!!!!!!!! + # done forget delete rtl_app.o when you change application + # !!!!!!!!!!!!!!!!!!!!!!! + + # rtl-fifo test + # O_OBJS := examples/frank/frank_module.o + + # real time toggle test + O_OBJS := examples/parallel/rectangle.o + + include $(TOPDIR)/Rules.make diff -3prN linux.org/arch/m68knommu/kernel/rtl/examples/frank/Makefile linux.rt/arch/m68knommu/kernel/rtl/examples/frank/Makefile *** linux.org/arch/m68knommu/kernel/rtl/examples/frank/Makefile Thu Jan 1 09:00:00 1970 --- linux.rt/arch/m68knommu/kernel/rtl/examples/frank/Makefile Wed Feb 9 21:46:17 2000 *************** *** 0 **** --- 1,16 ---- + CROSS = m68k-pic-coff- + + CC = $(CROSS)gcc + AR = $(CROSS)ar + LD = $(CROSS)ld + NM = $(CROSS)nm + RANLIB = $(CROSS)ranlib + CFLAGS = -O2 -fomit-frame-pointer -Wall + + all: frank_app + + frank_app: frank_app.c + $(CC) ${CFLAGS} -o frank_app frank_app.c + + clean: + rm -f frank_app diff -3prN linux.org/arch/m68knommu/kernel/rtl/examples/frank/README linux.rt/arch/m68knommu/kernel/rtl/examples/frank/README *** linux.org/arch/m68knommu/kernel/rtl/examples/frank/README Thu Jan 1 09:00:00 1970 --- linux.rt/arch/m68knommu/kernel/rtl/examples/frank/README Wed Feb 9 21:46:17 2000 *************** *** 0 **** --- 1,21 ---- + #include "../README" + + This example features two real-time tasks that can potentially perform some + real work, e.g. data collection. Here they simply write strings into FIFOs. + + The real-time part creates three RT-FIFOs: two for data passing, and one for + control. Then it creates two real-time tasks and registers a handler with the + control FIFO. + + Real-time and non-real-time parts both agree on the format of control messages + (see file control.h). Whenever Linux tasks writes to the control FIFO, the + handler is invoked. In the handler the RT-tasks are started and stopped. + + The real-time tasks are almost identical. They keep writing strings into FIFOs. + In the end of each loop each of them makes a request to deschedule itself + until the beginning of the next period. + + The Linux program (app) opens RT-FIFO devices, starts RT-tasks and enters the + loop in which it reads and prints the data produced by RT-tasks. + + To run type `make; make test' diff -3prN linux.org/arch/m68knommu/kernel/rtl/examples/frank/control.h linux.rt/arch/m68knommu/kernel/rtl/examples/frank/control.h *** linux.org/arch/m68knommu/kernel/rtl/examples/frank/control.h Thu Jan 1 09:00:00 1970 --- linux.rt/arch/m68knommu/kernel/rtl/examples/frank/control.h Wed Feb 9 21:46:17 2000 *************** *** 0 **** --- 1,8 ---- + #define START_TASK 1 + #define STOP_TASK 2 + + struct my_msg_struct { + int command; + int task; + int period; + }; diff -3prN linux.org/arch/m68knommu/kernel/rtl/examples/frank/frank_app.c linux.rt/arch/m68knommu/kernel/rtl/examples/frank/frank_app.c *** linux.org/arch/m68knommu/kernel/rtl/examples/frank/frank_app.c Thu Jan 1 09:00:00 1970 --- linux.rt/arch/m68knommu/kernel/rtl/examples/frank/frank_app.c Wed Feb 9 21:46:17 2000 *************** *** 0 **** --- 1,96 ---- + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include "control.h" + + + #define BUFSIZE 70 + + char buf[BUFSIZE]; + + int main() + { + fd_set rfds; + struct timeval tv; + int retval; + int fd0, fd1, ctl; + int n; + int i; + struct my_msg_struct msg; + + if ((fd0 = open("/dev/rtf1", O_RDONLY)) < 0) { + fprintf(stderr, "Error opening /dev/rtf1\n"); + exit(1); + } + + if ((fd1 = open("/dev/rtf2", O_RDONLY)) < 0) { + fprintf(stderr, "Error opening /dev/rtf2\n"); + exit(1); + } + + if ((ctl = open("/dev/rtf3", O_WRONLY)) < 0) { + fprintf(stderr, "Error opening /dev/rtf3\n"); + exit(1); + } + + /* now start the tasks */ + msg.command = START_TASK; + msg.task = 0; + msg.period = (RT_TICKS_PER_SEC * 5000000) / 1000000; + if (write(ctl, (void *) &msg, sizeof(msg)) < 0) { + fprintf(stderr, "Can't send a command to RT-task\n"); + exit(1); + } + msg.task = 1; + msg.period = (RT_TICKS_PER_SEC * 2000000) / 1000000; + if (write(ctl, (void *) &msg, sizeof(msg)) < 0) { + fprintf(stderr, "Can't send a command to RT-task\n"); + exit(1); + } + + for (i = 0; i < 10; i++) { + FD_ZERO(&rfds); + FD_SET(fd0, &rfds); + FD_SET(fd1, &rfds); + tv.tv_sec = 1; + tv.tv_usec = 0; + + retval = select(FD_SETSIZE, &rfds, NULL, NULL, &tv); + if (retval > 0) { + if (FD_ISSET(fd0, &rfds)) { + n = read(fd0, buf, BUFSIZE - 1); + buf[n] = 0; + printf("FIFO 1: %s\n", buf); + fflush(stdout); + } + if (FD_ISSET(fd1, &rfds)) { + n = read(fd1, buf, BUFSIZE - 1); + buf[n] = 0; + printf("FIFO 2: %s\n", buf); + fflush(stdout); + } + } + + + } + + /* stop the tasks */ + msg.command = STOP_TASK; + msg.task = 0; + if (write(ctl, (void *) &msg, sizeof(msg)) < 0) { + fprintf(stderr, "Can't send a command to RT-task\n"); + exit(1); + } + msg.task = 1; + if (write(ctl, (void *) &msg, sizeof(msg)) < 0) { + fprintf(stderr, "Can't send a command to RT-task\n"); + exit(1); + } + return 0; + } diff -3prN linux.org/arch/m68knommu/kernel/rtl/examples/frank/frank_module.c linux.rt/arch/m68knommu/kernel/rtl/examples/frank/frank_module.c *** linux.org/arch/m68knommu/kernel/rtl/examples/frank/frank_module.c Thu Jan 1 09:00:00 1970 --- linux.rt/arch/m68knommu/kernel/rtl/examples/frank/frank_module.c Wed Feb 9 21:46:17 2000 *************** *** 0 **** --- 1,66 ---- + #include + #include + #include + + #include + #include + #include "control.h" + + RT_TASK tasks[2]; + + static char *data[] = {"Frank ", "Zappa "}; + + /* t -- the fifo number */ + void fun(int t) { + while (1) { + rtf_put(t, data[t - 1], 6); + rt_task_wait(); + } + } + + + int my_handler(unsigned int fifo) + { + struct my_msg_struct msg; + int err; + RTIME now; + + while ((err = rtf_get(3, &msg, sizeof(msg))) == sizeof(msg)) { + switch (msg.command) { + case START_TASK: + now = rt_get_time(); + rt_task_make_periodic(&tasks[msg.task], now, msg.period); + break; + case STOP_TASK: + rt_task_suspend(&tasks[msg.task]); + break; + default: + return -EINVAL; + } + } + if (err != 0) { + return -EINVAL; + } + return 0; + } + + + void rtl_application_init(void) + { + rtf_create(1, 4000); + rtf_create(2, 4000); + rtf_create(3, 100); /* input control channel */ + rt_task_init(&tasks[0], fun, 1, 3000, 4); + rt_task_init(&tasks[1], fun, 2, 3000, 5); + rtf_create_handler(3, &my_handler); + } + + + void rtl_application_cleanup(void) + { + rtf_destroy(1); + rtf_destroy(2); + rtf_destroy(3); + rt_task_delete(&tasks[0]); + rt_task_delete(&tasks[1]); + } diff -3prN linux.org/arch/m68knommu/kernel/rtl/examples/parallel/rectangle.c linux.rt/arch/m68knommu/kernel/rtl/examples/parallel/rectangle.c *** linux.org/arch/m68knommu/kernel/rtl/examples/parallel/rectangle.c Thu Jan 1 09:00:00 1970 --- linux.rt/arch/m68knommu/kernel/rtl/examples/parallel/rectangle.c Wed Feb 9 21:46:17 2000 *************** *** 0 **** --- 1,51 ---- + #include + #include + #include + + #include + #include + #include + + static RT_TASK tasks[2]; + + static unsigned long data; + + void fun(int t) { + while (1) { + if (t==0) { + data ^= 0x01; + } else { + data ^= 0x02; + } + + PDDATA = data; + rt_task_wait(); + } + } + + void rtl_application_init(void) + { + RTIME now; + + data = 0; + now = rt_get_time(); + + PDSEL |= 0x03; /* select I/O functions for PD0 */ + PDDIR |= 0x03; /* set PD0 to output */ + + rt_task_init(&tasks[0], fun, 0, 3000, 4); + rt_task_init(&tasks[1], fun, 1, 3000, 5); + + /* about 4 msec */ + rt_task_make_periodic(&tasks[0], now+10000, 4000); + + /* about 8 msec */ + rt_task_make_periodic(&tasks[1], now+10000, 8000); + } + + + void rtl_application_cleanup(void) + { + rt_task_delete(&tasks[0]); + rt_task_delete(&tasks[1]); + } diff -3prN linux.org/arch/m68knommu/kernel/rtl/rt_time.c linux.rt/arch/m68knommu/kernel/rtl/rt_time.c *** linux.org/arch/m68knommu/kernel/rtl/rt_time.c Thu Jan 1 09:00:00 1970 --- linux.rt/arch/m68knommu/kernel/rtl/rt_time.c Wed Feb 9 21:46:17 2000 *************** *** 0 **** --- 1,207 ---- + /* + * arch/i386/kernel/rt_time.c + * + * 1995-1998, Michael Barabanov + * + * Real Time support for uClinux by Kwon Seok Kuon 02/03/2000 + * Do not use printk between r_save_flags/r_cli and r_restore_flags! + * (printk will enable interrupt when excuting sti()). + */ + + + #include + #include + #include + #include + #include + #include + #include + #include + #include + + extern unsigned long SFREQ; + + #define rt_get_time rt_get_time_MC68EZ328 + + static RTIME rt_callback_time; /* time to invoke the supplied procedure */ + enum rtl_timer_modes {PERIODIC, ONESHOT} rtl_timer_mode; + + static void (*rt_timer_handler)(void); + + RTIME rt_linux_clock; /* time to generate the next linux interrupt */ + + RTIME rt_base_time; /* for the real rtime */ + RTIME rt_intr_time; /* next interrupt time */ + static int clock_diff; + + RTIME rt_get_time_MC68EZ328(void) + { + int flags; + RTIME time; + + r_save_flags(flags); + r_cli(); + time = rt_base_time + TCN; + r_restore_flags(flags); + return time; + } + + + static void rt_reset_timer(void) + { + int flags; + int tcn; + + r_save_flags(flags); + r_cli(); + + // rt_intr_time = rt_get_time(); + /*-----------------------------------------------------*/ + /* fast setup rt_intr_time, interrupt already disabled */ + /*-----------------------------------------------------*/ + tcn = TCN; + rt_intr_time = rt_base_time + tcn; + + if (rt_linux_clock + 300 < rt_callback_time) { /* there's no RT-callback within 300 time units from the linux clock */ + clock_diff = rt_linux_clock - rt_intr_time; + } + else { + clock_diff = rt_callback_time - rt_intr_time; + } + + /* could we setup TCMP within 20 usec? + * probably sure, following code must not consume 20 instruction :) + * - kwonsk + */ + + if (clock_diff < 500) { + clock_diff = 500; + } + + /* setup timer counter */ + /* TCMP clock diff must be TCN+clock_diff */ + TCMP = clock_diff+tcn; + rt_intr_time += clock_diff; + + /* enable next timer interrupt */ + TSTAT &= 0; + IMR &= ~(1<= rt_linux_clock) { + rt_linux_clock += LATCH; + + SFREQ |= 1<= rt_linux_clock) { + conpr("lost jiffies "); + rt_linux_clock = rt_intr_time; + } + } + + if (rt_intr_time >= rt_callback_time) { + (*rt_timer_handler)(); + } else { + rt_reset_timer(); + } + + } + + void rt_set_timer(RTIME when) + { + rt_callback_time = when; + rt_reset_timer(); + } + + + void rt_no_timer(void) + { + rt_callback_time = RT_TIME_END; + rt_reset_timer(); + } + + + int rt_request_timer(void (*fn)(void)) + { + if (!fn) { + return -EINVAL; + } + if (rt_timer_handler) { + return -EBUSY; + } + + rt_timer_handler = fn; + return 0; + } + + + void rt_free_timer(void) + { + rt_timer_handler = 0; + rt_no_timer(); + } + + void rt_time_init(void) + { + int flags; + + r_save_flags(flags); + r_cli(); + + rt_timer_handler = 0; + rt_callback_time = RT_TIME_END; + rt_base_time = 0; + + /* program general purpose timer of MC68EZ328 + * for auto running and compare event mode + */ + + /* tick/sec = SYSCLK/16 = (32.768K * 506)/16 = 1036288 */ + TCTL = 0; + TSTAT &= 0; + TCTL = TCTL_OM | TCTL_IRQEN | TCTL_CLKSOURCE_SYSCLK | TCTL_TEN; + TPRER = 16; + TCMP = 0xFFFF; + IMR &= ~(1< + #include + #include + #include + #include + + #include + #include + + #define RTF_NO 64 + + struct rt_fifo_struct { + int open; + int user_open; + int sleeps; + char *base; + int bufsize; + int start; + int len; + int (*user_handler) (unsigned int fifo); + struct wait_queue *wait; + struct tq_struct wake_up_task; + }; + + static struct rt_fifo_struct fifoes[RTF_NO]; + + #define RTF_ADDR(minor) (&fifoes[minor]) + + #define RTF_OPEN(minor) (RTF_ADDR(minor)->open) + #define RTF_USER_OPEN(minor) (RTF_ADDR(minor)->user_open) + #define RTF_BASE(minor) (RTF_ADDR(minor)->base) + #define RTF_BUF(minor) (RTF_ADDR(minor)->bufsize) + #define RTF_START(minor) (RTF_ADDR(minor)->start) + #define RTF_HANDLER(minor) (RTF_ADDR(minor)->user_handler) + #define RTF_LEN(minor) (RTF_ADDR(minor)->len) + #define RTF_FREE(minor) (RTF_BUF(minor) - RTF_LEN(minor)) + #define RTF_WAIT(minor) (RTF_ADDR(minor)->wait) + #define RTF_SLEEPS(minor) (RTF_ADDR(minor)->sleeps) + #define RTF_WAKE_UP_TASK(minor) (RTF_ADDR(minor)->wake_up_task) + + #define RTF_WRAP(minor,pos) ((pos) < RTF_BUF(minor)? (pos) : (pos) - RTF_BUF(minor)) + #define RTF_END(minor) RTF_WRAP(minor, RTF_START(minor)+RTF_LEN(minor)) + #define RTF_EMPTY(minor) (RTF_LEN(minor)==0) + #define RTF_FULL(minor) (RTF_FREE(minor)==0) + #define RTF_MAX_RCHUNK(minor) (RTF_BUF(minor) - RTF_START(minor)) + #define RTF_MAX_WCHUNK(minor) (RTF_BUF(minor) - RTF_END(minor)) + + + static void rtf_wake_up(void *p) + { + struct rt_fifo_struct *fifo_ptr = (struct rt_fifo_struct *) p; + wake_up_interruptible(&(fifo_ptr->wait)); + } + + + /* These are for use in real-time processes */ + + int rtf_resize(unsigned int minor, int size) + { + void *mem; + void *old; + long interrupt_state; + + if (minor >= RTF_NO) { + return -ENODEV; + } + mem = kmalloc(size, GFP_KERNEL); + if (!mem) { + return -ENOMEM; + } + old = RTF_BASE(minor); + + rtl_no_interrupts(interrupt_state); + + RTF_BASE(minor) = mem; + RTF_BUF(minor) = size; + RTF_START(minor) = 0; + RTF_LEN(minor) = 0; + + rtl_restore_interrupts(interrupt_state); + + if (RTF_OPEN(minor)) { + kfree(old); + } + return size; + } + + + int rtf_create(unsigned int minor, int size) + { + int result; + + if (minor >= RTF_NO) { + return -ENODEV; + } + if (RTF_OPEN(minor)) { + return -EBUSY; + } + if ((result = rtf_resize(minor, size)) < 0) { + return result; + } + RTF_OPEN(minor) = 1; + RTF_SLEEPS(minor) = 0; + RTF_USER_OPEN(minor) = 0; + RTF_HANDLER(minor) = 0; + + RTF_WAKE_UP_TASK(minor).next = 0; + RTF_WAKE_UP_TASK(minor).sync = 0; + RTF_WAKE_UP_TASK(minor).data = RTF_ADDR(minor); + RTF_WAKE_UP_TASK(minor).routine = &rtf_wake_up; + + RTF_WAIT(minor) = 0; + + return 0; + } + + + int rtf_destroy(unsigned int minor) + { + if (minor >= RTF_NO) { + return -ENODEV; + } + if (RTF_USER_OPEN(minor)) { + return -EINVAL; + } + if (!RTF_OPEN(minor)) { + return -EINVAL; + } + RTF_OPEN(minor) = 0; + kfree(RTF_BASE(minor)); + return 0; + } + + + int rtf_create_handler(unsigned int minor, int (*handler) (unsigned int fifo)) + { + if (minor >= RTF_NO || !RTF_OPEN(minor) || !handler) { + return -EINVAL; + } + RTF_HANDLER(minor) = handler; + return 0; + } + + + int rtf_put(unsigned int minor, void *buf, int count) + { + long interrupt_state; + int chars = 0, free = 0, written = 0; + char *pipebuf; + + if (minor >= RTF_NO) { + return -ENODEV; + } + if (!RTF_OPEN(minor)) + return -EINVAL; + + rtl_no_interrupts(interrupt_state); + if (RTF_FREE(minor) < count) { + rtl_restore_interrupts(interrupt_state); + return -ENOSPC; + } + while (count > 0 && (free = RTF_FREE(minor))) { + chars = RTF_MAX_WCHUNK(minor); + if (chars > count) + chars = count; + if (chars > free) + chars = free; + pipebuf = RTF_BASE(minor) + RTF_END(minor); + written += chars; + RTF_LEN(minor) += chars; + count -= chars; + memcpy(pipebuf, buf, chars); + buf += chars; + } + rtl_restore_interrupts(interrupt_state); + if (clear_bit(1, &RTF_SLEEPS(minor))) { + queue_task_rt(&RTF_WAKE_UP_TASK(minor), &tq_rt); + } + return count; + } + + + int rtf_get(unsigned int minor, void *buf, int count) + { + long interrupt_state; + int chars = 0, size = 0, read = 0; + char *pipebuf; + + if (minor >= RTF_NO) { + return -ENODEV; + } + if (!RTF_OPEN(minor)) + return -EINVAL; + + rtl_no_interrupts(interrupt_state); + while (count > 0 && (size = RTF_LEN(minor))) { + chars = RTF_MAX_RCHUNK(minor); + if (chars > count) + chars = count; + if (chars > size) + chars = size; + + read += chars; + pipebuf = RTF_BASE(minor) + RTF_START(minor); + RTF_START(minor) += chars; + RTF_START(minor) = RTF_WRAP(minor, RTF_START(minor)); + RTF_LEN(minor) -= chars; + count -= chars; + memcpy(buf, pipebuf, chars); + buf += chars; + } + rtl_restore_interrupts(interrupt_state); + if (clear_bit(1, &RTF_SLEEPS(minor))) { + queue_task_rt(&RTF_WAKE_UP_TASK(minor), &tq_rt); + } + return read; + } + + + /* + * these are file_operations functions + */ + + static int rtf_open(struct inode *inode, struct file *filp) + { + unsigned int minor = MINOR(inode->i_rdev); + + if (minor >= RTF_NO) + return -ENODEV; + + if (!RTF_OPEN(minor)) { + return -EINVAL; + } + if (RTF_USER_OPEN(minor)) { + return -EBUSY; + } + RTF_USER_OPEN(minor) = 1; + + // MOD_INC_USE_COUNT; + return 0; + } + + + static void rtf_release(struct inode *inode, struct file *file) + { + unsigned int minor = MINOR(inode->i_rdev); + + if (!RTF_USER_OPEN(minor)) { + printk("rtf: release on a not opened descriptor\n"); + return; + } + RTF_SLEEPS(minor) = 0; + RTF_USER_OPEN(minor) = 0; + // MOD_DEC_USE_COUNT; + } + + + static int rtf_lseek(struct inode *inode, struct file *file, off_t offset, int origin) + { + return -ESPIPE; + } + + + static int rtf_read(struct inode *inode, struct file *filp, char *buf, int count) + { + unsigned int minor = MINOR(inode->i_rdev); + long interrupt_state; + int result; + + int chars = 0, size = 0, read = 0; + char *pipebuf; + + if (filp->f_flags & O_NONBLOCK) { + /* if (RTF_LOCK(minor)) + return -EAGAIN; + */ + if (RTF_EMPTY(minor)) + return 0; + } else + while (RTF_EMPTY(minor) /* || RTF_LOCK(minor) */ ) { + if (current->signal & ~current->blocked) + return -ERESTARTSYS; + set_bit(1, &RTF_SLEEPS(minor)); + interruptible_sleep_on(&RTF_WAIT(minor)); + } + /* RTF_LOCK(minor)++; */ + while (count > 0 && (size = RTF_LEN(minor))) { + chars = RTF_MAX_RCHUNK(minor); + if (chars > count) + chars = count; + if (chars > size) + chars = size; + + read += chars; + pipebuf = RTF_BASE(minor) + RTF_START(minor); + count -= chars; + memcpy_tofs(buf, pipebuf, chars); + rtl_no_interrupts(interrupt_state); + RTF_START(minor) += chars; + RTF_START(minor) = RTF_WRAP(minor, RTF_START(minor)); + RTF_LEN(minor) -= chars; + rtl_restore_interrupts(interrupt_state); + buf += chars; + } + /* RTF_LOCK(minor)--; */ + if (read) { + inode->i_atime = CURRENT_TIME; + if (RTF_HANDLER(minor)) { + if ((result = (*RTF_HANDLER(minor)) (minor)) < 0) { + return result; + } + } + return read; + } + return 0; + } + + + static int rtf_write(struct inode *inode, struct file *filp, const char *buf, int count) + { + unsigned int minor = MINOR(inode->i_rdev); + long interrupt_state; + int chars = 0, free = 0, written = 0; + char *pipebuf; + int result; + + if (count <= RTF_BUF(minor)) + free = count; + else + free = 1; + + while (count > 0) { + while ((RTF_FREE(minor) < free) /* || RTF_LOCK(minor) */ ) { + if (current->signal & ~current->blocked) + return written ? : -ERESTARTSYS; + if (filp->f_flags & O_NONBLOCK) + return written ? : -EAGAIN; + set_bit(1, &RTF_SLEEPS(minor)); + interruptible_sleep_on(&RTF_WAIT(minor)); + } + /* RTF_LOCK(minor)++; */ + while (count > 0 && (free = RTF_FREE(minor))) { + chars = RTF_MAX_WCHUNK(minor); + if (chars > count) + chars = count; + if (chars > free) + chars = free; + rtl_no_interrupts(interrupt_state); + pipebuf = RTF_BASE(minor) + RTF_END(minor); + rtl_restore_interrupts(interrupt_state); + count -= chars; + written += chars; + + memcpy_fromfs(pipebuf, buf, chars); + + rtl_no_interrupts(interrupt_state); + RTF_LEN(minor) += chars; + rtl_restore_interrupts(interrupt_state); + buf += chars; + } + /* RTF_LOCK(minor)--; */ + free = 1; + } + inode->i_ctime = inode->i_mtime = CURRENT_TIME; + if (RTF_HANDLER(minor)) { + if ((result = (*RTF_HANDLER(minor)) (minor)) < 0) { + return result; + } + } + return written; + } + + static int rtf_select(struct inode *inode, struct file *filp, int sel_type, select_table * wait) + { + unsigned int minor = MINOR(inode->i_rdev); + switch (sel_type) { + case SEL_IN: + if (!RTF_EMPTY(minor)) + return 1; + set_bit(1,&RTF_SLEEPS(minor)); + select_wait(&RTF_WAIT(minor), wait); + return 0; + case SEL_OUT: + if (RTF_EMPTY(minor)) + return 1; + set_bit(1, &RTF_SLEEPS(minor)); + select_wait(&RTF_WAIT(minor), wait); + return 0; + } + return 0; + } + + + static struct file_operations rtf_fops = + { + rtf_lseek, + rtf_read, + rtf_write, + NULL, + rtf_select, + NULL, + NULL, + rtf_open, + rtf_release + }; + + + + int rtf_init(void) + { + int i; + + if (register_chrdev(RTF_MAJOR, "rtf", &rtf_fops)) { + printk("RT-FIFO: unable to get major %d\n", RTF_MAJOR); + return -EIO; + } else { + printk("RT-FIFO for uClinux: RTL release 0.9J\n"); + } + + for (i = 0; i < RTF_NO; i++) { + RTF_OPEN(i) = 0; + } + + return 0; + } diff -3prN linux.org/arch/m68knommu/kernel/rtl/rtl_sched.c linux.rt/arch/m68knommu/kernel/rtl/rtl_sched.c *** linux.org/arch/m68knommu/kernel/rtl/rtl_sched.c Thu Jan 1 09:00:00 1970 --- linux.rt/arch/m68knommu/kernel/rtl/rtl_sched.c Wed Feb 9 21:56:38 2000 *************** *** 0 **** --- 1,383 ---- + /* a primitive real-time scheduler + copyright Victor Yodaiken, Michael Barabanov + History: Barabanov + modified Oleg Subbotin, Ramesh Nalluri, April 1998 + modified Victor Yodaiken, August 1998 + Added compatability macros + changed search loop + replaced old style r_cli with rtl_no_interrupt + removed x86 code + 10.23.98 modified by Michael Barabanov. Periodic mode works. + 12.22.98 merged fp and non-fp schedulers again; + implemented delayed FPU context switching + + 02.03.00 Real time supprot for uClinux, Kwon Seok Kuon + Thansks to works by Burnhard Kuhn + */ + + + /* This is the interrupt latency + scheduler latency, + The user needs to determine this and hardcode it accordingly */ + + + #define ADJUSTUP 50 /*if time to run is no more than this time ahead, run*/ + #define ADJUSTDOWN 50 /*set timer to interrupt this time less than requested*/ + + #include + #include + #include + #include + + #include + #include + #include + #include + #include + + static int linux_irq_state; + static int rtl_active = 0; + #define rtl_make_unrtactive() { SFIF = linux_irq_state; rtl_active=0;} + #define rtl_make_rtactive() { if (!rtl_active) {linux_irq_state = SFIF; SFIF = 0; rtl_active=1;}} + #define rtl_is_rtactive() (rtl_active) + + + #include + #include + #include + + + #ifdef RTL_DEBUG + void debug_resched(RT_TASK * ,RTIME ); + #endif + + #include + #include + #include + + + + #define GETTIME() rt_get_time() + + RT_TASK *rtl_tasks; + static RT_TASK *rtl_zombies; + + RT_TASK *rtl_current; + + RT_TASK rtl_linux_task; + + int rtl_startup(void (*fn)(int), int data) + { + r_sti(); + (*fn)(data); + rt_task_delete(rtl_current); + + /* should never reach this line */ + return 0; + } + + + int rt_task_init(RT_TASK *task, void (*fn)(int), int data, int stack_size, + int priority) + { + int *st; + long interrupt_state; + + if (task->magic == RT_TASK_MAGIC) { + return -EINVAL; + } + + st = (int *) task->fixed_stack; + if (!st) { + return -ENOMEM; + } + + task->priority = priority; + task->magic = RT_TASK_MAGIC; + task->state = RT_TASK_DORMANT; + task->stack_bottom = st; + task->stack = st + 4000 / sizeof(int); /* why do we divide by sizeof(int) ? */ + MC68EZ328_init_stack(fn,data,rtl_startup); + rtl_no_interrupts(interrupt_state); + task->next = rtl_tasks; + rtl_tasks = task; + rtl_restore_interrupts(interrupt_state); + return 0; + } + + + /* this function should only be called in the Linux context */ + + static int rtl_delete_zombies(void) + { + RT_TASK *task; + long interrupt_state; + + rtl_no_interrupts(interrupt_state); + + while (rtl_zombies) { + task = rtl_zombies; + rtl_zombies = task -> next; + + rtl_restore_interrupts (interrupt_state); + + kfree (task->stack_bottom); + /* we can deallocate the task structure here if needed */ + + rtl_no_interrupts (interrupt_state); + } + + rtl_restore_interrupts (interrupt_state); + return 0; + } + + int rtl_set_oneshot_mode(void) + { + unsigned long interrupt_state; + rtl_no_interrupts(interrupt_state); + MC68EZ328_make_oneshot(0); + rtl_restore_interrupts(interrupt_state); + return 0; + } + + + extern RTIME rt_base_time; + void rtl_schedule(void) + { + RTIME now; + RT_TASK *t; + RT_TASK *newt = 0; /* new task to run, if any */ + RT_TASK *nextt = 0; /* task that will preempt, if any */ + unsigned long interrupt_state; + + rtl_no_interrupts(interrupt_state); + + // now = GETTIME(); + /*----------------------------------------------*/ + /* fast get_rt_time, interrupt already disabled */ + /*----------------------------------------------*/ + now = rt_base_time + TCN; + + /* find a task that can be run */ + for (t = rtl_tasks; t; t = t->next) { + if( (t->state == RT_TASK_DELAYED)&& + ( t->resume_time < now + ADJUSTUP)){ + t->state = RT_TASK_READY; + } + if(t->state == RT_TASK_READY) + if (!newt || (t->priority < newt->priority)) { + newt = t; + } + } + /* find the pre-empting task */ + for (t = rtl_tasks; t; t = t->next) { + if( (t->state == RT_TASK_DELAYED) && + (!newt || (t->priority < newt->priority)) && + (!nextt ||(t->resume_time < nextt->resume_time)) + ) + nextt = t; + } + + + + /* DEBUG */ + { + static int nolinux = 0; + if(newt) nolinux++; + else nolinux = 0; + if(nolinux > 100000){ + conpr("HELP NO LINUX EVER!!!"); + nolinux = 0; + newt->resume_time = now+100000; + } + } + /* END DEBUG */ + + + /* if nextt there is a preemptor so set timer to preempt + if !nextt + if there is a rt task, turn off the timer + if there is no rt task, linux needs a clock interrupt + */ + if (nextt) { + rt_set_timer(nextt->resume_time - ADJUSTDOWN ); + } else{ + /* linux clock interrupt will be treated in + * rt_time.c if there are no rt tasks + * then do we need this if/else statement? + * + * how about callback time if i do not anything? + */ + if(newt) { rt_no_timer(); } + else { rt_set_timer(now+LATCH);} + } + + /* if there is no rt task to run, then run linux */ + if (!newt){ + newt = &rtl_linux_task; + rtl_make_unrtactive(); + } + else { + rtl_make_rtactive(); + } + /* if the new task is the current task nothing to do */ + if (newt == rtl_current) { + rtl_restore_interrupts(interrupt_state); + return; + } + /*else switch out old, switch in new */ + { + rtl_switch_to(newt); /* switch the integer registers and the control flow */ + + rtl_restore_interrupts(interrupt_state); + } + + /*--------------------------------------*/ + /* let zombies live for uClinux, kwonsk */ + /*--------------------------------------*/ + // if (rtl_is_linux_task (rtl_current)) { + /* it is safe to do if we require that rt_task_delete() is called from Linux */ + /* but it's probably better to use task queues anyway */ + + // rtl_delete_zombies(); + // } + } + + + /* should be called from a place where it is safe to use kfree() + * just like rt_task_init(); + * + * if this restriction is a problem, we can use task queues */ + + int rt_task_delete(RT_TASK *task) + { + RT_TASK *t; + int found = 0; + + long interrupt_state; + + if (task->magic != RT_TASK_MAGIC) { + return -EINVAL; + } + + rtl_no_interrupts (interrupt_state); + + if (task != rtl_tasks) { + for (t = rtl_tasks; t; t = t->next) { + if (t->next == task) { + t->next = task->next; + found = 1; + break; + } + } + if (!found) { + rtl_restore_interrupts(interrupt_state); + return -EINVAL; + } + } else { + rtl_tasks = task->next; + } + + task->state = RT_TASK_ZOMBIE; + task->next = rtl_zombies; + rtl_zombies = task; + + rtl_restore_interrupts (interrupt_state); + + /*--------------------------------------*/ + /* let zombies live for uClinux, kwonsk */ + /*--------------------------------------*/ + /* + * if (rtl_is_linux_task (rtl_current)) { + * rtl_delete_zombies(); + * } + */ + + return 0; + } + + + int rt_task_suspend(RT_TASK *task) + { + task->state = RT_TASK_DORMANT; + rtl_schedule(); + return 0; + } + + + int rt_task_wakeup(RT_TASK *task) + { + task->state = RT_TASK_READY; + rtl_schedule(); + return 0; + } + + + int rt_task_wait(void) + { + long interrupt_state; + rtl_no_interrupts (interrupt_state); + rtl_current->state = RT_TASK_DELAYED; + rtl_current->resume_time += rtl_current->period; + rtl_schedule(); + rtl_restore_interrupts (interrupt_state); + return 0; + } + + int rt_task_make_periodic(RT_TASK *task, RTIME start_time, RTIME period) + { + long interrupt_state; + if (task->magic != RT_TASK_MAGIC) { + return -EINVAL; + } + rtl_no_interrupts(interrupt_state); + task->resume_time = start_time; + task->period = period; + task->state = RT_TASK_DELAYED; + rt_set_timer (GETTIME()); + rtl_restore_interrupts(interrupt_state); + return 0; + } + + int rtl_schedule_init(void) + { + long interrupt_state; + printk("rtl_scheduler for uClinux based on RTL release 0.9J \n"); + rtl_no_interrupts(interrupt_state); + rt_no_timer(); + rtl_tasks = 0; + rtl_zombies = 0; + rtl_current = &rtl_linux_task; + rtl_linux_task . priority = RT_LOWEST_PRIORITY; + rtl_linux_task . next = 0; + rtl_linux_task . state = RT_TASK_READY; + + rtl_set_oneshot_mode (); + rt_request_timer (&rtl_schedule); + rtl_restore_interrupts (interrupt_state); + + return 0; + } + + + void rtl_schedule_cleanup(void) + { + RT_TASK *t; + RT_TASK *next_t; + rt_free_timer(); + + /* actually if rtl_tasks is non-zero at this point, + * chances are the system has crashed already */ + for (t = rtl_tasks; t; t = next_t) { + next_t = t->next; + if (t != &rtl_linux_task) { + rt_task_delete(t); + } + } + + /*--------------------------------------*/ + /* let zombies live for uClinux, kwonsk */ + /*--------------------------------------*/ + // rtl_delete_zombies(); + } + + diff -3prN linux.org/arch/m68knommu/kernel/traps.c linux.rt/arch/m68knommu/kernel/traps.c *** linux.org/arch/m68knommu/kernel/traps.c Wed Feb 9 09:53:04 2000 --- linux.rt/arch/m68knommu/kernel/traps.c Wed Feb 9 21:46:17 2000 *************** void trap_init (void) *** 204,211 **** _ramvec[13] = trap13; _ramvec[14] = trap14; _ramvec[15] = trap15; - #if 0 _ramvec[33] = trap33; _ramvec[34] = trap34; _ramvec[35] = trap35; _ramvec[36] = trap36; --- 204,211 ---- _ramvec[13] = trap13; _ramvec[14] = trap14; _ramvec[15] = trap15; _ramvec[33] = trap33; + #if 0 _ramvec[34] = trap34; _ramvec[35] = trap35; _ramvec[36] = trap36; *************** void trap_init (void) *** 223,228 **** --- 223,238 ---- #endif _ramvec[32] = system_call; _ramvec[64] = bad_interrupt; + + #ifdef __RT__ + _ramvec[65] = inthandler; + _ramvec[66] = inthandler; + _ramvec[67] = inthandler; + _ramvec[68] = inthandler; + _ramvec[69] = inthandler; + _ramvec[70] = inthandler; + _ramvec[71] = inthandler; + #else _ramvec[65] = inthandler1; _ramvec[66] = inthandler2; _ramvec[67] = inthandler3; *************** void trap_init (void) *** 230,235 **** --- 240,246 ---- _ramvec[69] = inthandler5; _ramvec[70] = inthandler6; _ramvec[71] = inthandler7; + #endif /* __RT__ */ IVR = 0x40; /* Set DragonBall IVR (interrupt base) to 64 */ *************** asmlinkage void trap_c(int vector, struc *** 475,481 **** case VEC_LINE10: case VEC_LINE11: case VEC_COPROC: - case VEC_TRAP1: case VEC_TRAP2: case VEC_TRAP3: case VEC_TRAP4: --- 486,491 ---- *************** asmlinkage void trap_c(int vector, struc *** 521,526 **** --- 531,540 ---- case VEC_TRAP15: /* breakpoint */ sig = SIGTRAP; break; + case VEC_TRAP1: + /* kwonsk: support for gdbserver */ + fp->ptregs.pc -= 2; + sig = SIGTRAP; default: sig = SIGILL; break; diff -3prN linux.org/arch/m68knommu/platform/68EZ328/Makefile linux.rt/arch/m68knommu/platform/68EZ328/Makefile *** linux.org/arch/m68knommu/platform/68EZ328/Makefile Wed Feb 9 09:53:04 2000 --- linux.rt/arch/m68knommu/platform/68EZ328/Makefile Wed Feb 9 21:46:17 2000 *************** *** 7,14 **** --- 7,19 ---- # # Note 2! The CFLAGS definitions are now in the main makefile... + ifdef RT + .S.o: + $(CC) -D__RT__ -D__ASSEMBLY__ $(AFLAGS) -traditional -c $< -o $*.o + else .S.o: $(CC) -D__ASSEMBLY__ $(AFLAGS) -traditional -c $< -o $*.o + endif all: $(BOARD)-head.o entry.o platform.o O_TARGET := platform.o diff -3prN linux.org/arch/m68knommu/platform/68EZ328/Rules.make linux.rt/arch/m68knommu/platform/68EZ328/Rules.make *** linux.org/arch/m68knommu/platform/68EZ328/Rules.make Wed Feb 9 09:53:04 2000 --- linux.rt/arch/m68knommu/platform/68EZ328/Rules.make Wed Feb 9 21:46:17 2000 *************** SUBDIRS := $(SUBDIRS) arch/$(ARCH)/conso *** 35,40 **** --- 35,46 ---- ARCHIVES := $(ARCHIVES) arch/$(ARCH)/console/console.a endif + ifdef RT + SUBDIRS := $(SUBDIRS) arch/$(ARCH)/kernel/rtl + ARCHIVES := $(ARCHIVES) arch/$(ARCH)/kernel/rtl/rtl.a \ + arch/$(ARCH)/kernel/rtl/rtl_app.o + endif + MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot romfs.s19: romfs.img arch/$(ARCH)/empty.o diff -3prN linux.org/arch/m68knommu/platform/68EZ328/config.c linux.rt/arch/m68knommu/platform/68EZ328/config.c *** linux.org/arch/m68knommu/platform/68EZ328/config.c Wed Feb 9 09:53:04 2000 --- linux.rt/arch/m68knommu/platform/68EZ328/config.c Wed Feb 9 21:46:17 2000 *************** *** 7,12 **** --- 7,15 ---- * This file is subject to the terms and conditions of the GNU General Public * License. See the file COPYING in the main directory of this archive * for more details. + * + * Real Time support for uClinux by Kwon Seok Kuon 02/03/2000 + * */ #include *************** *** 23,44 **** #include #include #include "bootstd.h" extern void register_console(void (*proc)(const char *)); void BSP_sched_init(void (*timer_routine)(int, void *, struct pt_regs *)) { - /* start timer */ - (*((volatile unsigned short*)0xFFFFF604)) = /*0x1000;*/ 0xd7e4; - (*((volatile unsigned short*)0xFFFFF600)) = 0x33; /* Reset */ - (*((volatile unsigned short*)0xFFFFF602)) = 0x2; /* divider */ ! request_irq(IRQ_MACHSPEC | 1, timer_routine, IRQ_FLG_LOCK, "timer", NULL); } void BSP_tick(void) { /* Reset Timer1 */ ! (*((volatile unsigned short*)0xFFFFF60A)) &= 0; } unsigned long BSP_gettimeoffset (void) --- 26,62 ---- #include #include #include "bootstd.h" + + #include + extern void register_console(void (*proc)(const char *)); void BSP_sched_init(void (*timer_routine)(int, void *, struct pt_regs *)) { ! #ifdef __RT__ ! request_irq(IRQ_MACHSPEC | TMR_IRQ_NUM, timer_routine, IRQ_FLG_LOCK, "timer", NULL); ! #else ! printk("setup TMR for none __RT__\n"); ! /* Restart mode, Enable int, 32KHz, Enable timer */ ! TCTL = TCTL_OM | TCTL_IRQEN | TCTL_CLKSOURCE_32KHZ | TCTL_TEN; ! /* Set prescaler (Divide 32KHz by 32)*/ ! TPRER = 31; ! /* Set compare register 32.768Khz / 32 /10 ~100 Hz */ ! TCMP = 10; ! ! request_irq(IRQ_MACHSPEC | TMR_IRQ_NUM, timer_routine, IRQ_FLG_LOCK, "timer", NULL); ! #endif /* __RT__ */ } void BSP_tick(void) { + #ifdef __RT__ + /* Reset Timer1, already cleared by RT */ + #else /* Reset Timer1 */ ! TSTAT &= 0; ! #endif /* __RT__ */ } unsigned long BSP_gettimeoffset (void) diff -3prN linux.org/arch/m68knommu/platform/68EZ328/entry.S linux.rt/arch/m68knommu/platform/68EZ328/entry.S *** linux.org/arch/m68knommu/platform/68EZ328/entry.S Wed Feb 9 09:53:04 2000 --- linux.rt/arch/m68knommu/platform/68EZ328/entry.S Wed Feb 9 21:55:32 2000 *************** *** 2,7 **** --- 2,10 ---- * * linux/arch/m68knommu/kernel/entry.S * + * Real Time support for uClinux by Kwon Seok Kuon 02/03/2000 + * Thansk to works of Burnhard Kuhn + * * Copyright (C) 1998 D. Jeff Dionne , * Kenneth Albanowski , * The Silver Hammer Group, Ltd. *************** LD0 = 0x1C *** 83,88 **** --- 86,92 ---- LORIG_D0 = 0x20 LSR = 0x28 LFORMATVEC = 0x2E + LTRAPPC = 0x2A /* * This defines the normal kernel pt-regs layout. *************** LFORMATVEC = 0x2E *** 90,110 **** * regs are a2-a6 and d6-d7 preserved by C code * the kernel doesn't mess with usp unless it needs to */ #define SAVE_ALL \ clrl %sp@-; /* stk_adj */ \ movel %d0,%sp@-; /* orig d0 */ \ movel %d0,%sp@-; /* d0 */ \ moveml %d1-%d5/%a0-%a1,%sp@- - /* moveml %sp@+,%a0-%a1/%d1-%d5; */ - #define RESTORE_ALL \ moveml %sp@+,%d1-%d5/%a0-%a1; \ movel %sp@+,%d0; \ addql #4,%sp; /* orig d0 */ \ ! addl %sp@+,%sp; /* stk adj */ \ rte #define SWITCH_STACK_SIZE (7*4+4) /* includes return address */ #define SAVE_SWITCH_STACK \ --- 94,129 ---- * regs are a2-a6 and d6-d7 preserved by C code * the kernel doesn't mess with usp unless it needs to */ + #ifdef __RT__ + #define SF_PUSH \ + moveml %d0-%d1/%a0-%a1,%sp@- + + #define SF_POP \ + moveml %sp@+,%d0-%d1/%a0-%a1 + + #define SF_RESTORE_ALL \ + moveml %sp@+,%d1-%d5/%a0-%a1; \ + movel %sp@+,%d0; \ + addql #4,%sp; /* orig d0 */ \ + addl %sp@+,%sp; /* stk adj */ \ + bra check_iret; + + #endif /* __RT__ */ + #define SAVE_ALL \ clrl %sp@-; /* stk_adj */ \ movel %d0,%sp@-; /* orig d0 */ \ movel %d0,%sp@-; /* d0 */ \ moveml %d1-%d5/%a0-%a1,%sp@- #define RESTORE_ALL \ moveml %sp@+,%d1-%d5/%a0-%a1; \ movel %sp@+,%d0; \ addql #4,%sp; /* orig d0 */ \ ! addl %sp@+,%sp; /* stk adj */ \ rte + #define SWITCH_STACK_SIZE (7*4+4) /* includes return address */ #define SAVE_SWITCH_STACK \ *************** LFORMATVEC = 0x2E *** 120,127 **** .globl SYMBOL_NAME(trap4) .globl SYMBOL_NAME(trap5) .globl SYMBOL_NAME(inthandler1) - .globl SYMBOL_NAME(inthandler1) - .globl SYMBOL_NAME(inthandler1) .globl SYMBOL_NAME(inthandler2) .globl SYMBOL_NAME(inthandler3) .globl SYMBOL_NAME(inthandler4) --- 139,144 ---- *************** LFORMATVEC = 0x2E *** 137,151 **** .globl SYMBOL_NAME(sys_fork), SYMBOL_NAME(sys_clone) .globl SYMBOL_NAME(ret_from_interrupt), SYMBOL_NAME(bad_interrupt) .text ENTRY(buserr) SAVE_ALL moveq #-1,%d0 ! movel %d0,%sp@(LORIG_D0) | a -1 in the ORIG_D0 field ! | signifies that the stack frame ! | is NOT for syscall ! movel %sp,%sp@- | stack frame pointer argument jsr SYMBOL_NAME(buserr_c) addql #4,%sp jra SYMBOL_NAME(ret_from_exception) --- 154,208 ---- .globl SYMBOL_NAME(sys_fork), SYMBOL_NAME(sys_clone) .globl SYMBOL_NAME(ret_from_interrupt), SYMBOL_NAME(bad_interrupt) + #ifdef __RT__ + .globl SYMBOL_NAME(s_sti) + .globl SYMBOL_NAME(SF_inthandler) + .globl SYMBOL_NAME(SF_ret_from_interrupt) + .globl SYMBOL_NAME(SF_reschedule) + #endif + .text + #ifdef __RT__ + ENTRY(s_sti) + /*-----------------------------------------------------*/ + /* linux want interrupt enable */ + /* emulate stack frame for rte (return from exception) */ + /*-----------------------------------------------------*/ + andiw #0xf8ff,%sr + pea 1f + movew %sr,%sp@- + + check_iret: + /* disalbe interrupt, will be cleared when rte */ + /* make scratch register %d0,%d1 */ + oriw #0x0700,%sr + + /* check if pending interrupt, SFIF is not cleared yet */ + movel %d0,%sp@- + movel SYMBOL_NAME(SFREQ),%d0 + andl SYMBOL_NAME(SFMASK),%d0 + jeq 2f + + movel #0, SYMBOL_NAME(SFIF) + andiw #0xf8ff,%sr + bra SYMBOL_NAME(SF_inthandler) + + 1: rts + + 2: movel #1, SYMBOL_NAME(SFIF) + andiw #0xf8ff,%sr + movel %sp@+,%d0 + rte + #endif /* __RT__ */ + ENTRY(buserr) SAVE_ALL moveq #-1,%d0 ! movel %d0,%sp@(LORIG_D0) /* a -1 in the ORIG_D0 field */ ! /* signifies that the stack frame */ ! /* is NOT for syscall */ ! movel %sp,%sp@- /* stack frame pointer argument */ jsr SYMBOL_NAME(buserr_c) addql #4,%sp jra SYMBOL_NAME(ret_from_exception) *************** ENTRY(buserr) *** 153,167 **** ENTRY(trap) SAVE_ALL moveq #-1,%d0 ! movel %d0,%sp@(LORIG_D0) | a -1 in the ORIG_D0 field ! | signifies that the stack frame ! | is NOT for syscall movew %sp@(LFORMATVEC),%d0 lsrl #2, %d0 andl #0x3ff,%d0 ! movel %sp,%sp@- | stack frame pointer argument movel %d0,%sp@- moveq #-1,%d0 --- 210,224 ---- ENTRY(trap) SAVE_ALL moveq #-1,%d0 ! movel %d0,%sp@(LORIG_D0) /* a -1 in the ORIG_D0 field */ ! /* signifies that the stack frame */ ! /* is NOT for syscall */ movew %sp@(LFORMATVEC),%d0 lsrl #2, %d0 andl #0x3ff,%d0 ! movel %sp,%sp@- /* stack frame pointer argument */ movel %d0,%sp@- moveq #-1,%d0 *************** ENTRY(trap) *** 173,182 **** ENTRY(trap3) SAVE_ALL moveq #-1,%d0 ! movel %d0,%sp@(LORIG_D0) | a -1 in the ORIG_D0 field ! | signifies that the stack frame ! | is NOT for syscall ! movel %sp,%sp@- | stack frame pointer argument movel #3,%sp@- jsr SYMBOL_NAME(trap_c) addql #8,%sp --- 230,239 ---- ENTRY(trap3) SAVE_ALL moveq #-1,%d0 ! movel %d0,%sp@(LORIG_D0) /* a -1 in the ORIG_D0 field */ ! /* signifies that the stack frame */ ! /* is NOT for syscall */ ! movel %sp,%sp@- /* stack frame pointer argument */ movel #3,%sp@- jsr SYMBOL_NAME(trap_c) addql #8,%sp *************** ENTRY(trap3) *** 185,194 **** ENTRY(trap4) SAVE_ALL moveq #-1,%d0 ! movel %d0,%sp@(LORIG_D0) | a -1 in the ORIG_D0 field ! | signifies that the stack frame ! | is NOT for syscall ! movel %sp,%sp@- | stack frame pointer argument movel #4,%sp@- jsr SYMBOL_NAME(trap_c) addql #8,%sp --- 242,251 ---- ENTRY(trap4) SAVE_ALL moveq #-1,%d0 ! movel %d0,%sp@(LORIG_D0) /* a -1 in the ORIG_D0 field */ ! /* signifies that the stack frame */ ! /* is NOT for syscall */ ! movel %sp,%sp@- /* stack frame pointer argument */ movel #4,%sp@- jsr SYMBOL_NAME(trap_c) addql #8,%sp *************** ENTRY(trap4) *** 197,206 **** ENTRY(trap5) SAVE_ALL moveq #-1,%d0 ! movel %d0,%sp@(LORIG_D0) | a -1 in the ORIG_D0 field ! | signifies that the stack frame ! | is NOT for syscall ! movel %sp,%sp@- | stack frame pointer argument movel #5,%sp@- jsr SYMBOL_NAME(trap_c) addql #8,%sp --- 254,263 ---- ENTRY(trap5) SAVE_ALL moveq #-1,%d0 ! movel %d0,%sp@(LORIG_D0) /* a -1 in the ORIG_D0 field */ ! /* signifies that the stack frame */ ! /* is NOT for syscall */ ! movel %sp,%sp@- /* stack frame pointer argument */ movel #5,%sp@- jsr SYMBOL_NAME(trap_c) addql #8,%sp *************** ENTRY(trap5) *** 209,218 **** ENTRY(trap6) SAVE_ALL moveq #-1,%d0 ! movel %d0,%sp@(LORIG_D0) | a -1 in the ORIG_D0 field ! | signifies that the stack frame ! | is NOT for syscall ! movel %sp,%sp@- | stack frame pointer argument movel #6,%sp@- jsr SYMBOL_NAME(trap_c) addql #8,%sp --- 266,275 ---- ENTRY(trap6) SAVE_ALL moveq #-1,%d0 ! movel %d0,%sp@(LORIG_D0) /* a -1 in the ORIG_D0 field */ ! /* signifies that the stack frame */ ! /* is NOT for syscall */ ! movel %sp,%sp@- /* stack frame pointer argument */ movel #6,%sp@- jsr SYMBOL_NAME(trap_c) addql #8,%sp *************** ENTRY(trap6) *** 221,230 **** ENTRY(trap7) SAVE_ALL moveq #-1,%d0 ! movel %d0,%sp@(LORIG_D0) | a -1 in the ORIG_D0 field ! | signifies that the stack frame ! | is NOT for syscall ! movel %sp,%sp@- | stack frame pointer argument movel #7,%sp@- jsr SYMBOL_NAME(trap_c) addql #8,%sp --- 278,287 ---- ENTRY(trap7) SAVE_ALL moveq #-1,%d0 ! movel %d0,%sp@(LORIG_D0) /* a -1 in the ORIG_D0 field */ ! /* signifies that the stack frame */ ! /* is NOT for syscall */ ! movel %sp,%sp@- /* stack frame pointer argument */ movel #7,%sp@- jsr SYMBOL_NAME(trap_c) addql #8,%sp *************** ENTRY(trap7) *** 233,242 **** ENTRY(trap8) SAVE_ALL moveq #-1,%d0 ! movel %d0,%sp@(LORIG_D0) | a -1 in the ORIG_D0 field ! | signifies that the stack frame ! | is NOT for syscall ! movel %sp,%sp@- | stack frame pointer argument movel #8,%sp@- jsr SYMBOL_NAME(trap_c) addql #8,%sp --- 290,299 ---- ENTRY(trap8) SAVE_ALL moveq #-1,%d0 ! movel %d0,%sp@(LORIG_D0) /* a -1 in the ORIG_D0 field */ ! /* signifies that the stack frame */ ! /* is NOT for syscall */ ! movel %sp,%sp@- /* stack frame pointer argument */ movel #8,%sp@- jsr SYMBOL_NAME(trap_c) addql #8,%sp *************** ENTRY(trap8) *** 245,254 **** ENTRY(trap9) SAVE_ALL moveq #-1,%d0 ! movel %d0,%sp@(LORIG_D0) | a -1 in the ORIG_D0 field ! | signifies that the stack frame ! | is NOT for syscall ! movel %sp,%sp@- | stack frame pointer argument movel #9,%sp@- jsr SYMBOL_NAME(trap_c) addql #8,%sp --- 302,311 ---- ENTRY(trap9) SAVE_ALL moveq #-1,%d0 ! movel %d0,%sp@(LORIG_D0) /* a -1 in the ORIG_D0 field */ ! /* signifies that the stack frame */ ! /* is NOT for syscall */ ! movel %sp,%sp@- /* stack frame pointer argument */ movel #9,%sp@- jsr SYMBOL_NAME(trap_c) addql #8,%sp *************** ENTRY(trap9) *** 258,267 **** ENTRY(trap10) SAVE_ALL moveq #-1,%d0 ! movel %d0,%sp@(LORIG_D0) | a -1 in the ORIG_D0 field ! | signifies that the stack frame ! | is NOT for syscall ! movel %sp,%sp@- | stack frame pointer argument movel #10,%sp@- jsr SYMBOL_NAME(trap_c) addql #8,%sp --- 315,324 ---- ENTRY(trap10) SAVE_ALL moveq #-1,%d0 ! movel %d0,%sp@(LORIG_D0) /* a -1 in the ORIG_D0 field */ ! /* signifies that the stack frame */ ! /* is NOT for syscall */ ! movel %sp,%sp@- /* stack frame pointer argument */ movel #10,%sp@- jsr SYMBOL_NAME(trap_c) addql #8,%sp *************** ENTRY(trap10) *** 270,279 **** ENTRY(trap11) SAVE_ALL moveq #-1,%d0 ! movel %d0,%sp@(LORIG_D0) | a -1 in the ORIG_D0 field ! | signifies that the stack frame ! | is NOT for syscall ! movel %sp,%sp@- | stack frame pointer argument movel #11,%sp@- jsr SYMBOL_NAME(trap_c) addql #8,%sp --- 327,336 ---- ENTRY(trap11) SAVE_ALL moveq #-1,%d0 ! movel %d0,%sp@(LORIG_D0) /* a -1 in the ORIG_D0 field */ ! /* signifies that the stack frame */ ! /* is NOT for syscall */ ! movel %sp,%sp@- /* stack frame pointer argument */ movel #11,%sp@- jsr SYMBOL_NAME(trap_c) addql #8,%sp *************** ENTRY(trap11) *** 282,291 **** ENTRY(trap12) SAVE_ALL moveq #-1,%d0 ! movel %d0,%sp@(LORIG_D0) | a -1 in the ORIG_D0 field ! | signifies that the stack frame ! | is NOT for syscall ! movel %sp,%sp@- | stack frame pointer argument movel #12,%sp@- jsr SYMBOL_NAME(trap_c) addql #8,%sp --- 339,348 ---- ENTRY(trap12) SAVE_ALL moveq #-1,%d0 ! movel %d0,%sp@(LORIG_D0) /* a -1 in the ORIG_D0 field */ ! /* signifies that the stack frame */ ! /* is NOT for syscall */ ! movel %sp,%sp@- /* stack frame pointer argument */ movel #12,%sp@- jsr SYMBOL_NAME(trap_c) addql #8,%sp *************** ENTRY(trap12) *** 295,304 **** ENTRY(trap13) SAVE_ALL moveq #-1,%d0 ! movel %d0,%sp@(LORIG_D0) | a -1 in the ORIG_D0 field ! | signifies that the stack frame ! | is NOT for syscall ! movel %sp,%sp@- | stack frame pointer argument movel #13,%sp@- jsr SYMBOL_NAME(trap_c) addql #8,%sp --- 352,361 ---- ENTRY(trap13) SAVE_ALL moveq #-1,%d0 ! movel %d0,%sp@(LORIG_D0) /* a -1 in the ORIG_D0 field */ ! /* signifies that the stack frame */ ! /* is NOT for syscall */ ! movel %sp,%sp@- /* stack frame pointer argument */ movel #13,%sp@- jsr SYMBOL_NAME(trap_c) addql #8,%sp *************** ENTRY(trap13) *** 308,317 **** ENTRY(trap14) SAVE_ALL moveq #-1,%d0 ! movel %d0,%sp@(LORIG_D0) | a -1 in the ORIG_D0 field ! | signifies that the stack frame ! | is NOT for syscall ! movel %sp,%sp@- | stack frame pointer argument movel #14,%sp@- jsr SYMBOL_NAME(trap_c) addql #8,%sp --- 365,374 ---- ENTRY(trap14) SAVE_ALL moveq #-1,%d0 ! movel %d0,%sp@(LORIG_D0) /* a -1 in the ORIG_D0 field */ ! /* signifies that the stack frame */ ! /* is NOT for syscall */ ! movel %sp,%sp@- /* stack frame pointer argument */ movel #14,%sp@- jsr SYMBOL_NAME(trap_c) addql #8,%sp *************** ENTRY(trap14) *** 321,330 **** ENTRY(trap15) SAVE_ALL moveq #-1,%d0 ! movel %d0,%sp@(LORIG_D0) | a -1 in the ORIG_D0 field ! | signifies that the stack frame ! | is NOT for syscall ! movel %sp,%sp@- | stack frame pointer argument movel #15,%sp@- jsr SYMBOL_NAME(trap_c) addql #8,%sp --- 378,387 ---- ENTRY(trap15) SAVE_ALL moveq #-1,%d0 ! movel %d0,%sp@(LORIG_D0) /* a -1 in the ORIG_D0 field */ ! /* signifies that the stack frame */ ! /* is NOT for syscall */ ! movel %sp,%sp@- /* stack frame pointer argument */ movel #15,%sp@- jsr SYMBOL_NAME(trap_c) addql #8,%sp *************** ENTRY(trap15) *** 334,343 **** ENTRY(trap33) SAVE_ALL moveq #-1,%d0 ! movel %d0,%sp@(LORIG_D0) | a -1 in the ORIG_D0 field ! | signifies that the stack frame ! | is NOT for syscall ! movel %sp,%sp@- | stack frame pointer argument movel #33,%sp@- jsr SYMBOL_NAME(trap_c) addql #8,%sp --- 391,400 ---- ENTRY(trap33) SAVE_ALL moveq #-1,%d0 ! movel %d0,%sp@(LORIG_D0) /* a -1 in the ORIG_D0 field */ ! /* signifies that the stack frame */ ! /* is NOT for syscall */ ! movel %sp,%sp@- /* stack frame pointer argument */ movel #33,%sp@- jsr SYMBOL_NAME(trap_c) addql #8,%sp *************** ENTRY(trap33) *** 346,355 **** ENTRY(trap34) SAVE_ALL moveq #-1,%d0 ! movel %d0,%sp@(LORIG_D0) | a -1 in the ORIG_D0 field ! | signifies that the stack frame ! | is NOT for syscall ! movel %sp,%sp@- | stack frame pointer argument movel #34,%sp@- jsr SYMBOL_NAME(trap_c) addql #8,%sp --- 403,412 ---- ENTRY(trap34) SAVE_ALL moveq #-1,%d0 ! movel %d0,%sp@(LORIG_D0) /* a -1 in the ORIG_D0 field */ ! /* signifies that the stack frame */ ! /* is NOT for syscall */ ! movel %sp,%sp@- /* stack frame pointer argument */ movel #34,%sp@- jsr SYMBOL_NAME(trap_c) addql #8,%sp *************** ENTRY(trap34) *** 359,368 **** ENTRY(trap35) SAVE_ALL moveq #-1,%d0 ! movel %d0,%sp@(LORIG_D0) | a -1 in the ORIG_D0 field ! | signifies that the stack frame ! | is NOT for syscall ! movel %sp,%sp@- | stack frame pointer argument movel #35,%sp@- jsr SYMBOL_NAME(trap_c) addql #8,%sp --- 416,425 ---- ENTRY(trap35) SAVE_ALL moveq #-1,%d0 ! movel %d0,%sp@(LORIG_D0) /* a -1 in the ORIG_D0 field */ ! /* signifies that the stack frame */ ! /* is NOT for syscall */ ! movel %sp,%sp@- /* stack frame pointer argument */ movel #35,%sp@- jsr SYMBOL_NAME(trap_c) addql #8,%sp *************** ENTRY(trap35) *** 371,380 **** ENTRY(trap36) SAVE_ALL moveq #-1,%d0 ! movel %d0,%sp@(LORIG_D0) | a -1 in the ORIG_D0 field ! | signifies that the stack frame ! | is NOT for syscall ! movel %sp,%sp@- | stack frame pointer argument movel #36,%sp@- jsr SYMBOL_NAME(trap_c) addql #8,%sp --- 428,437 ---- ENTRY(trap36) SAVE_ALL moveq #-1,%d0 ! movel %d0,%sp@(LORIG_D0) /* a -1 in the ORIG_D0 field */ ! /* signifies that the stack frame */ ! /* is NOT for syscall */ ! movel %sp,%sp@- /* stack frame pointer argument */ movel #36,%sp@- jsr SYMBOL_NAME(trap_c) addql #8,%sp *************** ENTRY(trap36) *** 383,392 **** ENTRY(trap37) SAVE_ALL moveq #-1,%d0 ! movel %d0,%sp@(LORIG_D0) | a -1 in the ORIG_D0 field ! | signifies that the stack frame ! | is NOT for syscall ! movel %sp,%sp@- | stack frame pointer argument movel #37,%sp@- jsr SYMBOL_NAME(trap_c) addql #8,%sp --- 440,449 ---- ENTRY(trap37) SAVE_ALL moveq #-1,%d0 ! movel %d0,%sp@(LORIG_D0) /* a -1 in the ORIG_D0 field */ ! /* signifies that the stack frame */ ! /* is NOT for syscall */ ! movel %sp,%sp@- /* stack frame pointer argument */ movel #37,%sp@- jsr SYMBOL_NAME(trap_c) addql #8,%sp *************** ENTRY(trap37) *** 395,404 **** ENTRY(trap38) SAVE_ALL moveq #-1,%d0 ! movel %d0,%sp@(LORIG_D0) | a -1 in the ORIG_D0 field ! | signifies that the stack frame ! | is NOT for syscall ! movel %sp,%sp@- | stack frame pointer argument movel #38,%sp@- jsr SYMBOL_NAME(trap_c) addql #8,%sp --- 452,461 ---- ENTRY(trap38) SAVE_ALL moveq #-1,%d0 ! movel %d0,%sp@(LORIG_D0) /* a -1 in the ORIG_D0 field */ ! /* signifies that the stack frame */ ! /* is NOT for syscall */ ! movel %sp,%sp@- /* stack frame pointer argument */ movel #38,%sp@- jsr SYMBOL_NAME(trap_c) addql #8,%sp *************** ENTRY(trap38) *** 407,416 **** ENTRY(trap39) SAVE_ALL moveq #-1,%d0 ! movel %d0,%sp@(LORIG_D0) | a -1 in the ORIG_D0 field ! | signifies that the stack frame ! | is NOT for syscall ! movel %sp,%sp@- | stack frame pointer argument movel #39,%sp@- jsr SYMBOL_NAME(trap_c) addql #8,%sp --- 464,473 ---- ENTRY(trap39) SAVE_ALL moveq #-1,%d0 ! movel %d0,%sp@(LORIG_D0) /* a -1 in the ORIG_D0 field */ ! /* signifies that the stack frame */ ! /* is NOT for syscall */ ! movel %sp,%sp@- /* stack frame pointer argument */ movel #39,%sp@- jsr SYMBOL_NAME(trap_c) addql #8,%sp *************** ENTRY(trap39) *** 419,428 **** ENTRY(trap40) SAVE_ALL moveq #-1,%d0 ! movel %d0,%sp@(LORIG_D0) | a -1 in the ORIG_D0 field ! | signifies that the stack frame ! | is NOT for syscall ! movel %sp,%sp@- | stack frame pointer argument movel #40,%sp@- jsr SYMBOL_NAME(trap_c) addql #8,%sp --- 476,485 ---- ENTRY(trap40) SAVE_ALL moveq #-1,%d0 ! movel %d0,%sp@(LORIG_D0) /* a -1 in the ORIG_D0 field */ ! /* signifies that the stack frame */ ! /* is NOT for syscall */ ! movel %sp,%sp@- /* stack frame pointer argument */ movel #40,%sp@- jsr SYMBOL_NAME(trap_c) addql #8,%sp *************** ENTRY(trap40) *** 431,440 **** ENTRY(trap41) SAVE_ALL moveq #-1,%d0 ! movel %d0,%sp@(LORIG_D0) | a -1 in the ORIG_D0 field ! | signifies that the stack frame ! | is NOT for syscall ! movel %sp,%sp@- | stack frame pointer argument movel #41,%sp@- jsr SYMBOL_NAME(trap_c) addql #8,%sp --- 488,497 ---- ENTRY(trap41) SAVE_ALL moveq #-1,%d0 ! movel %d0,%sp@(LORIG_D0) /* a -1 in the ORIG_D0 field */ ! /* signifies that the stack frame */ ! /* is NOT for syscall */ ! movel %sp,%sp@- /* stack frame pointer argument */ movel #41,%sp@- jsr SYMBOL_NAME(trap_c) addql #8,%sp *************** ENTRY(trap41) *** 443,452 **** ENTRY(trap42) SAVE_ALL moveq #-1,%d0 ! movel %d0,%sp@(LORIG_D0) | a -1 in the ORIG_D0 field ! | signifies that the stack frame ! | is NOT for syscall ! movel %sp,%sp@- | stack frame pointer argument movel #42,%sp@- jsr SYMBOL_NAME(trap_c) addql #8,%sp --- 500,509 ---- ENTRY(trap42) SAVE_ALL moveq #-1,%d0 ! movel %d0,%sp@(LORIG_D0) /* a -1 in the ORIG_D0 field */ ! /* signifies that the stack frame */ ! /* is NOT for syscall */ ! movel %sp,%sp@- /* stack frame pointer argument */ movel #42,%sp@- jsr SYMBOL_NAME(trap_c) addql #8,%sp *************** ENTRY(trap42) *** 455,464 **** ENTRY(trap43) SAVE_ALL moveq #-1,%d0 ! movel %d0,%sp@(LORIG_D0) | a -1 in the ORIG_D0 field ! | signifies that the stack frame ! | is NOT for syscall ! movel %sp,%sp@- | stack frame pointer argument movel #43,%sp@- jsr SYMBOL_NAME(trap_c) addql #8,%sp --- 512,521 ---- ENTRY(trap43) SAVE_ALL moveq #-1,%d0 ! movel %d0,%sp@(LORIG_D0) /* a -1 in the ORIG_D0 field */ ! /* signifies that the stack frame */ ! /* is NOT for syscall */ ! movel %sp,%sp@- /* stack frame pointer argument */ movel #43,%sp@- jsr SYMBOL_NAME(trap_c) addql #8,%sp *************** ENTRY(trap43) *** 467,476 **** ENTRY(trap44) SAVE_ALL moveq #-1,%d0 ! movel %d0,%sp@(LORIG_D0) | a -1 in the ORIG_D0 field ! | signifies that the stack frame ! | is NOT for syscall ! movel %sp,%sp@- | stack frame pointer argument movel #44,%sp@- jsr SYMBOL_NAME(trap_c) addql #8,%sp --- 524,533 ---- ENTRY(trap44) SAVE_ALL moveq #-1,%d0 ! movel %d0,%sp@(LORIG_D0) /* a -1 in the ORIG_D0 field */ ! /* signifies that the stack frame */ ! /* is NOT for syscall */ ! movel %sp,%sp@- /* stack frame pointer argument */ movel #44,%sp@- jsr SYMBOL_NAME(trap_c) addql #8,%sp *************** ENTRY(trap44) *** 479,488 **** ENTRY(trap45) SAVE_ALL moveq #-1,%d0 ! movel %d0,%sp@(LORIG_D0) | a -1 in the ORIG_D0 field ! | signifies that the stack frame ! | is NOT for syscall ! movel %sp,%sp@- | stack frame pointer argument movel #45,%sp@- jsr SYMBOL_NAME(trap_c) addql #8,%sp --- 536,545 ---- ENTRY(trap45) SAVE_ALL moveq #-1,%d0 ! movel %d0,%sp@(LORIG_D0) /* a -1 in the ORIG_D0 field */ ! /* signifies that the stack frame */ ! /* is NOT for syscall */ ! movel %sp,%sp@- /* stack frame pointer argument */ movel #45,%sp@- jsr SYMBOL_NAME(trap_c) addql #8,%sp *************** ENTRY(trap45) *** 491,500 **** ENTRY(trap46) SAVE_ALL moveq #-1,%d0 ! movel %d0,%sp@(LORIG_D0) | a -1 in the ORIG_D0 field ! | signifies that the stack frame ! | is NOT for syscall ! movel %sp,%sp@- | stack frame pointer argument movel #46,%sp@- jsr SYMBOL_NAME(trap_c) addql #8,%sp --- 548,557 ---- ENTRY(trap46) SAVE_ALL moveq #-1,%d0 ! movel %d0,%sp@(LORIG_D0) /* a -1 in the ORIG_D0 field */ ! /* signifies that the stack frame */ ! /* is NOT for syscall */ ! movel %sp,%sp@- /* stack frame pointer argument */ movel #46,%sp@- jsr SYMBOL_NAME(trap_c) addql #8,%sp *************** ENTRY(trap46) *** 503,519 **** ENTRY(trap47) SAVE_ALL moveq #-1,%d0 ! movel %d0,%sp@(LORIG_D0) | a -1 in the ORIG_D0 field ! | signifies that the stack frame ! | is NOT for syscall ! movel %sp,%sp@- | stack frame pointer argument movel #47,%sp@- jsr SYMBOL_NAME(trap_c) addql #8,%sp jra SYMBOL_NAME(ret_from_exception) ENTRY(reschedule) ! | save top of frame pea %sp@ jbsr SYMBOL_NAME(set_esp0) addql #4,%sp --- 560,576 ---- ENTRY(trap47) SAVE_ALL moveq #-1,%d0 ! movel %d0,%sp@(LORIG_D0) /* a -1 in the ORIG_D0 field */ ! /* signifies that the stack frame */ ! /* is NOT for syscall */ ! movel %sp,%sp@- /* stack frame pointer argument */ movel #47,%sp@- jsr SYMBOL_NAME(trap_c) addql #8,%sp jra SYMBOL_NAME(ret_from_exception) ENTRY(reschedule) ! /* save top of frame */ pea %sp@ jbsr SYMBOL_NAME(set_esp0) addql #4,%sp *************** ENTRY(reschedule) *** 521,533 **** pea SYMBOL_NAME(ret_from_exception) jmp SYMBOL_NAME(schedule) ENTRY(system_call) SAVE_ALL ! movel #-LENOSYS,LD0(%sp) | default return value in d0 ! | original D0 is in orig_d0 movel %d0,%d2 ! | save top of frame pea %sp@ jbsr SYMBOL_NAME(set_esp0) addql #4,%sp --- 578,602 ---- pea SYMBOL_NAME(ret_from_exception) jmp SYMBOL_NAME(schedule) + #ifdef __RT__ + ENTRY(SF_reschedule) + /* save top of frame */ + pea %sp@ + jbsr SYMBOL_NAME(set_esp0) + addql #4,%sp + + pea SYMBOL_NAME(SF_ret_from_exception) + jmp SYMBOL_NAME(schedule) + #endif /* __RT__ */ + ENTRY(system_call) SAVE_ALL ! ! movel #-LENOSYS,LD0(%sp) /* default return value in d0 */ ! /* original D0 is in orig_d0 */ movel %d0,%d2 ! /* save top of frame */ pea %sp@ jbsr SYMBOL_NAME(set_esp0) addql #4,%sp *************** ENTRY(system_call) *** 535,550 **** cmpl #NR_syscalls,%d2 jcc SYMBOL_NAME(ret_from_exception) lea SYMBOL_NAME(sys_call_table),%a0 ! lsl #2,%d2 | movel %a0@(%d2:l:4),%d3 movel %a0@(%d2),%d3 jeq SYMBOL_NAME(ret_from_exception) lsr #2,%d2 movel SYMBOL_NAME(current_set),%a0 ! btst #5,%a0@(LTASK_FLAGS+3) | PF_TRACESYS bnes 1f movel %d3,%a0 jbsr %a0@ ! movel %d0,%sp@(LD0) | save the return value jra SYMBOL_NAME(ret_from_exception) 1: subql #4,%sp --- 604,619 ---- cmpl #NR_syscalls,%d2 jcc SYMBOL_NAME(ret_from_exception) lea SYMBOL_NAME(sys_call_table),%a0 ! lsl #2,%d2 /* movel %a0@(%d2:l:4),%d3 */ movel %a0@(%d2),%d3 jeq SYMBOL_NAME(ret_from_exception) lsr #2,%d2 movel SYMBOL_NAME(current_set),%a0 ! btst #5,%a0@(LTASK_FLAGS+3) /* PF_TRACESYS */ bnes 1f movel %d3,%a0 jbsr %a0@ ! movel %d0,%sp@(LD0) /* save the return value */ jra SYMBOL_NAME(ret_from_exception) 1: subql #4,%sp *************** ENTRY(system_call) *** 554,561 **** addql #4,%sp movel %d3,%a0 jbsr %a0@ ! movel %d0,%sp@(LD0) | save the return value ! subql #4,%sp | dummy return address SAVE_SWITCH_STACK jbsr SYMBOL_NAME(syscall_trace) --- 623,630 ---- addql #4,%sp movel %d3,%a0 jbsr %a0@ ! movel %d0,%sp@(LD0) /* save the return value */ ! subql #4,%sp /* dummy return address */ SAVE_SWITCH_STACK jbsr SYMBOL_NAME(syscall_trace) *************** SYMBOL_NAME_LABEL(ret_from_signal) *** 564,580 **** addql #4,%sp SYMBOL_NAME_LABEL(ret_from_exception) ! btst #5,%sp@(LSR) | check if returning to kernel ! bnes 2f | if so, skip resched, signals tstl SYMBOL_NAME(need_resched) jne SYMBOL_NAME(reschedule) movel SYMBOL_NAME(current_set),%a0 ! cmpl #SYMBOL_NAME(task),%a0 | task[0] cannot have signals jeq 2f ! bclr #5,%a0@(LTASK_FLAGS+1) | check for delayed trace jeq 1f ! bclr #7,%sp@(LSR) | clear trace bit in SR ! pea 1 | send SIGTRAP movel %a0,%sp@- pea 5 jbsr SYMBOL_NAME(send_sig) --- 633,649 ---- addql #4,%sp SYMBOL_NAME_LABEL(ret_from_exception) ! btst #5,%sp@(LSR) /* check if returning to kernel */ ! bnes 2f /* if so, skip resched, signals */ tstl SYMBOL_NAME(need_resched) jne SYMBOL_NAME(reschedule) movel SYMBOL_NAME(current_set),%a0 ! cmpl #SYMBOL_NAME(task),%a0 /* task[0] cannot have signals */ jeq 2f ! bclr #5,%a0@(LTASK_FLAGS+1) /* check for delayed trace */ jeq 1f ! bclr #7,%sp@(LSR) /* clear trace bit in SR */ ! pea 1 /* send SIGTRAP */ movel %a0,%sp@- pea 5 jbsr SYMBOL_NAME(send_sig) *************** SYMBOL_NAME_LABEL(ret_from_exception) *** 583,605 **** movel SYMBOL_NAME(current_set),%a0 1: ! tstl %a0@(LTASK_STATE) | state jne SYMBOL_NAME(reschedule) ! tstl %a0@(LTASK_COUNTER) | counter jeq SYMBOL_NAME(reschedule) movel %a0@(LTASK_BLOCKED),%d0 ! movel %d0,%d1 | save blocked in d1 for sig handling notl %d0 ! btst #4,%a0@(LTASK_FLAGS+3) | PF_PTRACED jeq 1f ! moveq #-1,%d0 | let the debugger see all signals 1: andl %a0@(LTASK_SIGNAL),%d0 jne Lsignal_return ! 2: RESTORE_ALL | Does RTE Lsignal_return: ! subql #4,%sp | dummy return address SAVE_SWITCH_STACK pea %sp@(SWITCH_STACK_SIZE) movel %d1,%sp@- --- 652,674 ---- movel SYMBOL_NAME(current_set),%a0 1: ! tstl %a0@(LTASK_STATE) /* state */ jne SYMBOL_NAME(reschedule) ! tstl %a0@(LTASK_COUNTER) /* counter */ jeq SYMBOL_NAME(reschedule) movel %a0@(LTASK_BLOCKED),%d0 ! movel %d0,%d1 /* save blocked in d1 for sig handling */ notl %d0 ! btst #4,%a0@(LTASK_FLAGS+3) /* PF_PTRACED */ jeq 1f ! moveq #-1,%d0 /* let the debugger see all signals */ 1: andl %a0@(LTASK_SIGNAL),%d0 jne Lsignal_return ! 2: RESTORE_ALL /* Does RTE */ Lsignal_return: ! subql #4,%sp /* dummy return address */ SAVE_SWITCH_STACK pea %sp@(SWITCH_STACK_SIZE) movel %d1,%sp@- *************** Lsignal_return: *** 610,615 **** --- 679,733 ---- RESTORE_ALL + #ifdef __RT__ + SYMBOL_NAME_LABEL(SF_ret_from_exception) + btst #5,%sp@(LSR) /* check if returning to kernel */ + bnes 2f /* if so, skip resched, signals */ + tstl SYMBOL_NAME(need_resched) + jne SYMBOL_NAME(SF_reschedule) + movel SYMBOL_NAME(current_set),%a0 + cmpl #SYMBOL_NAME(task),%a0 /* task[0] cannot have signals */ + jeq 2f + bclr #5,%a0@(LTASK_FLAGS+1) /* check for delayed trace */ + jeq 1f + bclr #7,%sp@(LSR) /* clear trace bit in SR */ + pea 1 /* send SIGTRAP */ + movel %a0,%sp@- + pea 5 + jbsr SYMBOL_NAME(send_sig) + addql #8,%sp + addql #4,%sp + movel SYMBOL_NAME(current_set),%a0 + + 1: + tstl %a0@(LTASK_STATE) /* state */ + jne SYMBOL_NAME(SF_reschedule) + tstl %a0@(LTASK_COUNTER) /* counter */ + jeq SYMBOL_NAME(SF_reschedule) + + movel %a0@(LTASK_BLOCKED),%d0 + movel %d0,%d1 /* save blocked in d1 for sig handling */ + notl %d0 + btst #4,%a0@(LTASK_FLAGS+3) /* PF_PTRACED */ + jeq 1f + moveq #-1,%d0 /* let the debugger see all signals */ + 1: andl %a0@(LTASK_SIGNAL),%d0 + jne SF_Lsignal_return + 2: SF_RESTORE_ALL /* Does RTE */ + + SF_Lsignal_return: + subql #4,%sp /* dummy return address */ + SAVE_SWITCH_STACK + pea %sp@(SWITCH_STACK_SIZE) + movel %d1,%sp@- + jsr SYMBOL_NAME(do_signal) + addql #8,%sp + RESTORE_SWITCH_STACK + addql #4,%sp + SF_RESTORE_ALL + #endif /* __RT__ */ + + /* ** This is the main interrupt handler, responsible for calling process_int() */ *************** SYMBOL_NAME_LABEL(timerhandler) *** 618,639 **** oriw #0x700,%sr moveq #-1,%d0 ! movel %d0,%sp@(LORIG_D0) | a -1 in the ORIG_D0 field ! | signifies that the stack frame ! | is NOT for syscall addql #1,SYMBOL_NAME(intr_count) ! | put exception # in d0 ! |movel %sp@(LFORMATVEC),%d0 ! |lsr #4,%d0 movew %sp@(LFORMATVEC),%d0 and #0x3ff,%d0 - | bfextu %sp@(LFORMATVEC){#4,#10},%d0 movel %sp,%sp@- ! movel #0x40,%sp@- | put vector # on stack (was %d0) ! jbsr SYMBOL_NAME(process_int)| process the IRQ ! addql #8,%sp | pop parameters off stack ! bra ret_from_interrupt | this was fallthrough /* ** This is the main interrupt handler, responsible for calling process_int() --- 736,754 ---- oriw #0x700,%sr moveq #-1,%d0 ! movel %d0,%sp@(LORIG_D0) /* a -1 in the ORIG_D0 field */ ! /* signifies that the stack frame */ ! /* is NOT for syscall */ addql #1,SYMBOL_NAME(intr_count) ! /* put exception # in d0 */ movew %sp@(LFORMATVEC),%d0 and #0x3ff,%d0 movel %sp,%sp@- ! movel #0x40,%sp@- /* put vector # on stack (was %d0) */ ! jbsr SYMBOL_NAME(process_int)/* process the IRQ */ ! addql #8,%sp /* pop parameters off stack */ ! bra ret_from_interrupt /* this was fallthrough */ /* ** This is the main interrupt handler, responsible for calling process_int() *************** SYMBOL_NAME_LABEL(serialhandler) *** 643,664 **** oriw #0x700,%sr moveq #-1,%d0 ! movel %d0,%sp@(LORIG_D0) | a -1 in the ORIG_D0 field ! | signifies that the stack frame ! | is NOT for syscall addql #1,SYMBOL_NAME(intr_count) ! | put exception # in d0 ! |movel %sp@(LFORMATVEC),%d0 ! |lsr #4,%d0 movew %sp@(LFORMATVEC),%d0 and #0x3ff,%d0 - | bfextu %sp@(LFORMATVEC){#4,#10},%d0 movel %sp,%sp@- ! movel #0x42,%sp@- | put vector # on stack (was %d0) ! jbsr SYMBOL_NAME(process_int)| process the IRQ ! addql #8,%sp | pop parameters off stack ! bra ret_from_interrupt | this was fallthrough /* ** This is the main interrupt handler, responsible for calling process_int() --- 758,776 ---- oriw #0x700,%sr moveq #-1,%d0 ! movel %d0,%sp@(LORIG_D0) /* a -1 in the ORIG_D0 field */ ! /* signifies that the stack frame */ ! /* is NOT for syscall */ addql #1,SYMBOL_NAME(intr_count) ! /* put exception # in d0 */ movew %sp@(LFORMATVEC),%d0 and #0x3ff,%d0 movel %sp,%sp@- ! movel #0x42,%sp@- /* put vector # on stack (was %d0) */ ! jbsr SYMBOL_NAME(process_int)/* process the IRQ */ ! addql #8,%sp /* pop parameters off stack */ ! bra ret_from_interrupt /* this was fallthrough */ /* ** This is the main interrupt handler, responsible for calling process_int() *************** SYMBOL_NAME_LABEL(inthandler1) *** 668,689 **** oriw #0x700,%sr moveq #-1,%d0 ! movel %d0,%sp@(LORIG_D0) | a -1 in the ORIG_D0 field ! | signifies that the stack frame ! | is NOT for syscall addql #1,SYMBOL_NAME(intr_count) - | put exception # in d0 - |movel %sp@(LFORMATVEC),%d0 - |lsr #4,%d0 - movew %sp@(LFORMATVEC),%d0 - and #0x3ff,%d0 - | bfextu %sp@(LFORMATVEC){#4,#10},%d0 movel %sp,%sp@- ! movel #65,%sp@- | put vector # on stack (was %d0) ! jbsr SYMBOL_NAME(process_int)| process the IRQ ! addql #8,%sp | pop parameters off stack ! bra ret_from_interrupt | this was fallthrough /* ** This is the main interrupt handler, responsible for calling process_int() --- 780,795 ---- oriw #0x700,%sr moveq #-1,%d0 ! movel %d0,%sp@(LORIG_D0) /* a -1 in the ORIG_D0 field */ ! /* signifies that the stack frame */ ! /* is NOT for syscall */ addql #1,SYMBOL_NAME(intr_count) movel %sp,%sp@- ! movel #65,%sp@- /* put vector # on stack (was %d0) */ ! jbsr SYMBOL_NAME(process_int)/* process the IRQ */ ! addql #8,%sp /* pop parameters off stack */ ! bra ret_from_interrupt /* this was fallthrough */ /* ** This is the main interrupt handler, responsible for calling process_int() *************** SYMBOL_NAME_LABEL(inthandler2) *** 693,714 **** oriw #0x700,%sr moveq #-1,%d0 ! movel %d0,%sp@(LORIG_D0) | a -1 in the ORIG_D0 field ! | signifies that the stack frame ! | is NOT for syscall addql #1,SYMBOL_NAME(intr_count) - | put exception # in d0 - |movel %sp@(LFORMATVEC),%d0 - |lsr #4,%d0 - movew %sp@(LFORMATVEC),%d0 - and #0x3ff,%d0 - | bfextu %sp@(LFORMATVEC){#4,#10},%d0 movel %sp,%sp@- ! movel #66,%sp@- | put vector # on stack (was %d0) ! jbsr SYMBOL_NAME(process_int)| process the IRQ ! addql #8,%sp | pop parameters off stack ! bra ret_from_interrupt | this was fallthrough /* ** This is the main interrupt handler, responsible for calling process_int() --- 799,814 ---- oriw #0x700,%sr moveq #-1,%d0 ! movel %d0,%sp@(LORIG_D0) /* a -1 in the ORIG_D0 field */ ! /* signifies that the stack frame */ ! /* is NOT for syscall */ addql #1,SYMBOL_NAME(intr_count) movel %sp,%sp@- ! movel #66,%sp@- /* put vector # on stack (was %d0) */ ! jbsr SYMBOL_NAME(process_int)/* process the IRQ */ ! addql #8,%sp /* pop parameters off stack */ ! bra ret_from_interrupt /* this was fallthrough */ /* ** This is the main interrupt handler, responsible for calling process_int() *************** SYMBOL_NAME_LABEL(inthandler3) *** 718,739 **** oriw #0x700,%sr moveq #-1,%d0 ! movel %d0,%sp@(LORIG_D0) | a -1 in the ORIG_D0 field ! | signifies that the stack frame ! | is NOT for syscall addql #1,SYMBOL_NAME(intr_count) - | put exception # in d0 - |movel %sp@(LFORMATVEC),%d0 - |lsr #4,%d0 - movew %sp@(LFORMATVEC),%d0 - and #0x3ff,%d0 - | bfextu %sp@(LFORMATVEC){#4,#10},%d0 movel %sp,%sp@- ! movel #67,%sp@- | put vector # on stack (was %d0) ! jbsr SYMBOL_NAME(process_int)| process the IRQ ! addql #8,%sp | pop parameters off stack ! bra ret_from_interrupt | this was fallthrough /* ** This is the main interrupt handler, responsible for calling process_int() --- 818,833 ---- oriw #0x700,%sr moveq #-1,%d0 ! movel %d0,%sp@(LORIG_D0) /* a -1 in the ORIG_D0 field */ ! /* signifies that the stack frame */ ! /* is NOT for syscall */ addql #1,SYMBOL_NAME(intr_count) movel %sp,%sp@- ! movel #67,%sp@- /* put vector # on stack (was %d0) */ ! jbsr SYMBOL_NAME(process_int)/* process the IRQ */ ! addql #8,%sp /* pop parameters off stack */ ! bra ret_from_interrupt /* this was fallthrough */ /* ** This is the main interrupt handler, responsible for calling process_int() *************** SYMBOL_NAME_LABEL(inthandler4) *** 743,764 **** oriw #0x700,%sr moveq #-1,%d0 ! movel %d0,%sp@(LORIG_D0) | a -1 in the ORIG_D0 field ! | signifies that the stack frame ! | is NOT for syscall addql #1,SYMBOL_NAME(intr_count) - | put exception # in d0 - |movel %sp@(LFORMATVEC),%d0 - |lsr #4,%d0 - movew %sp@(LFORMATVEC),%d0 - and #0x3ff,%d0 - | bfextu %sp@(LFORMATVEC){#4,#10},%d0 movel %sp,%sp@- ! movel #68,%sp@- | put vector # on stack (was %d0) ! jbsr SYMBOL_NAME(process_int)| process the IRQ ! addql #8,%sp | pop parameters off stack ! bra ret_from_interrupt | this was fallthrough /* ** This is the main interrupt handler, responsible for calling process_int() --- 837,852 ---- oriw #0x700,%sr moveq #-1,%d0 ! movel %d0,%sp@(LORIG_D0) /* a -1 in the ORIG_D0 field */ ! /* signifies that the stack frame */ ! /* is NOT for syscall */ addql #1,SYMBOL_NAME(intr_count) movel %sp,%sp@- ! movel #68,%sp@- /* put vector # on stack (was %d0) */ ! jbsr SYMBOL_NAME(process_int)/* process the IRQ */ ! addql #8,%sp /* pop parameters off stack */ ! bra ret_from_interrupt /* this was fallthrough */ /* ** This is the main interrupt handler, responsible for calling process_int() *************** SYMBOL_NAME_LABEL(inthandler5) *** 768,789 **** oriw #0x700,%sr moveq #-1,%d0 ! movel %d0,%sp@(LORIG_D0) | a -1 in the ORIG_D0 field ! | signifies that the stack frame ! | is NOT for syscall addql #1,SYMBOL_NAME(intr_count) - | put exception # in d0 - |movel %sp@(LFORMATVEC),%d0 - |lsr #4,%d0 - movew %sp@(LFORMATVEC),%d0 - and #0x3ff,%d0 - | bfextu %sp@(LFORMATVEC){#4,#10},%d0 movel %sp,%sp@- ! movel #69,%sp@- | put vector # on stack (was %d0) ! jbsr SYMBOL_NAME(process_int)| process the IRQ ! addql #8,%sp | pop parameters off stack ! bra ret_from_interrupt | this was fallthrough /* ** This is the main interrupt handler, responsible for calling process_int() --- 856,871 ---- oriw #0x700,%sr moveq #-1,%d0 ! movel %d0,%sp@(LORIG_D0) /* a -1 in the ORIG_D0 field */ ! /* signifies that the stack frame */ ! /* is NOT for syscall */ addql #1,SYMBOL_NAME(intr_count) movel %sp,%sp@- ! movel #69,%sp@- /* put vector # on stack (was %d0) */ ! jbsr SYMBOL_NAME(process_int)/* process the IRQ */ ! addql #8,%sp /* pop parameters off stack */ ! bra ret_from_interrupt /* this was fallthrough */ /* ** This is the main interrupt handler, responsible for calling process_int() *************** SYMBOL_NAME_LABEL(inthandler6) *** 793,814 **** oriw #0x700,%sr moveq #-1,%d0 ! movel %d0,%sp@(LORIG_D0) | a -1 in the ORIG_D0 field ! | signifies that the stack frame ! | is NOT for syscall addql #1,SYMBOL_NAME(intr_count) - | put exception # in d0 - |movel %sp@(LFORMATVEC),%d0 - |lsr #4,%d0 - movew %sp@(LFORMATVEC),%d0 - and #0x3ff,%d0 - | bfextu %sp@(LFORMATVEC){#4,#10},%d0 movel %sp,%sp@- ! movel #70,%sp@- | put vector # on stack (was %d0) ! jbsr SYMBOL_NAME(process_int)| process the IRQ ! addql #8,%sp | pop parameters off stack ! bra ret_from_interrupt | this was fallthrough /* ** This is the main interrupt handler, responsible for calling process_int() --- 875,890 ---- oriw #0x700,%sr moveq #-1,%d0 ! movel %d0,%sp@(LORIG_D0) /* a -1 in the ORIG_D0 field */ ! /* signifies that the stack frame */ ! /* is NOT for syscall */ addql #1,SYMBOL_NAME(intr_count) movel %sp,%sp@- ! movel #70,%sp@- /* put vector # on stack (was %d0) */ ! jbsr SYMBOL_NAME(process_int)/* process the IRQ */ ! addql #8,%sp /* pop parameters off stack */ ! bra ret_from_interrupt /* this was fallthrough */ /* ** This is the main interrupt handler, responsible for calling process_int() *************** SYMBOL_NAME_LABEL(inthandler7) *** 818,936 **** oriw #0x700,%sr moveq #-1,%d0 ! movel %d0,%sp@(LORIG_D0) | a -1 in the ORIG_D0 field ! | signifies that the stack frame ! | is NOT for syscall addql #1,SYMBOL_NAME(intr_count) - | put exception # in d0 - |movel %sp@(LFORMATVEC),%d0 - |lsr #4,%d0 - movew %sp@(LFORMATVEC),%d0 - and #0x3ff,%d0 - | bfextu %sp@(LFORMATVEC){#4,#10},%d0 movel %sp,%sp@- ! movel #71,%sp@- | put vector # on stack (was %d0) ! jbsr SYMBOL_NAME(process_int)| process the IRQ ! addql #8,%sp | pop parameters off stack ! bra ret_from_interrupt | this was fallthrough /* ** This is the main interrupt handler, responsible for calling process_int() */ ! SYMBOL_NAME_LABEL(inthandler8) SAVE_ALL - oriw #0x700,%sr - - moveq #-1,%d0 - movel %d0,%sp@(LORIG_D0) | a -1 in the ORIG_D0 field - | signifies that the stack frame - | is NOT for syscall - addql #1,SYMBOL_NAME(intr_count) - | put exception # in d0 - |movel %sp@(LFORMATVEC),%d0 - |lsr #4,%d0 - movew %sp@(LFORMATVEC),%d0 - and #0x3ff,%d0 - | bfextu %sp@(LFORMATVEC){#4,#10},%d0 ! movel %sp,%sp@- ! movel #72,%sp@- | put vector # on stack (was %d0) ! jbsr SYMBOL_NAME(process_int)| process the IRQ ! addql #8,%sp | pop parameters off stack ! bra ret_from_interrupt | this was fallthrough ! ! /* ! ** This is the main interrupt handler, responsible for calling process_int() ! */ ! SYMBOL_NAME_LABEL(inthandler_wrap) ! SAVE_ALL ! oriw #0x700,%sr moveq #-1,%d0 ! movel %d0,%sp@(LORIG_D0) | a -1 in the ORIG_D0 field ! | signifies that the stack frame ! | is NOT for syscall addql #1,SYMBOL_NAME(intr_count) - | put exception # in d0 - |movel %sp@(LFORMATVEC),%d0 - |lsr #4,%d0 - - movew %sp@(LFORMATVEC),%d0 - lsrl #2, %d0 - andl #0x3ff,%d0 - - || bfextu %sp@(LFORMATVEC){#4,#10},%d0 movel %sp,%sp@- ! movel %d0 /*#31*/ ,%sp@- | put vector # on stack ! jbsr SYMBOL_NAME(process_int)| process the IRQ ! addql #8,%sp | pop parameters off stack ! bra ret_from_interrupt | this was fallthrough ! ! /* ! ** This is the main interrupt handler, responsible for calling process_int() ! */ SYMBOL_NAME_LABEL(inthandler) ! SAVE_ALL ! oriw #0x700,%sr ! ! moveq #-1,%d0 ! movel %d0,%sp@(LORIG_D0) | a -1 in the ORIG_D0 field ! | signifies that the stack frame ! | is NOT for syscall ! addql #1,SYMBOL_NAME(intr_count) ! | put exception # in d0 ! |movel %sp@(LFORMATVEC),%d0 ! |lsr #4,%d0 ! movew %sp@(LFORMATVEC),%d0 ! lsrl #2, %d0 ! andl #0x3ff,%d0 ! || bfextu %sp@(LFORMATVEC){#4,#10},%d0 ! movel %sp,%sp@- ! movel %d0,%sp@- | put vector # on stack ! jbsr SYMBOL_NAME(process_int)| process the IRQ ! addql #8,%sp | pop parameters off stack SYMBOL_NAME_LABEL(ret_from_interrupt) /* check if we need to do software interrupts */ 1: movel SYMBOL_NAME(intr_count),%d1 subql #1,%d1 jne 4f ! |movel %sp@(LSR),%d0 ! |lsr #5,%d0 moveb %sp@(LSR),%d0 and #0x7,%d0 - |bfextu %sp@(LSR){#5,#3},%d0 | Check for nested interrupt. - #if MAX_NOINT_IPL > 0 - cmpiw #MAX_NOINT_IPL,%d0 - #endif jhi 4f --- 894,1015 ---- oriw #0x700,%sr moveq #-1,%d0 ! movel %d0,%sp@(LORIG_D0) /* a -1 in the ORIG_D0 field */ ! /* signifies that the stack frame */ ! /* is NOT for syscall */ addql #1,SYMBOL_NAME(intr_count) movel %sp,%sp@- ! movel #71,%sp@- /* put vector # on stack (was %d0) */ ! jbsr SYMBOL_NAME(process_int)/* process the IRQ */ ! addql #8,%sp /* pop parameters off stack */ ! bra ret_from_interrupt /* this was fallthrough */ + #ifdef __RT__ /* ** This is the main interrupt handler, responsible for calling process_int() */ ! SYMBOL_NAME_LABEL(SF_inthandler) ! movel %sp@+,%d0 SAVE_ALL ! /*-------------------------*/ ! /* disable linux interrupt */ ! /*-------------------------*/ ! oriw #0x0700,%sr ! movel SFREQ,%d0 ! movel %d0,%d2 ! notl %d0 ! andl %d0,SFMASK ! clrl SFREQ ! andiw #0xf8ff,%sr ! moveq #-1,%d0 ! movel %d0,%sp@(LORIG_D0) /* a -1 in the ORIG_D0 field */ ! /* signifies that the stack frame */ ! /* is NOT for syscall */ addql #1,SYMBOL_NAME(intr_count) movel %sp,%sp@- ! movel %d2,%sp@- /* put vector # on stack (was %d0) */ ! jbsr SYMBOL_NAME(process_int)/* process the IRQ */ ! addql #8,%sp /* pop parameters off stack */ ! ! /*------------------------*/ ! /* enable linux interrupt */ ! /*------------------------*/ ! oriw #0x0700,%sr ! movel %d2,%d0 ! orl %d0,SFMASK ! bclrl #1,%d0 ! notl %d0 ! andl %d0,0xfffff304 ! andiw #0xf8ff,%sr ! bra ret_from_interrupt /* this was fallthrough */ ! ! SYMBOL_NAME_LABEL(inthandler) ! /*----------------------------------*/ ! /* mark new linux interrupt request */ ! /*----------------------------------*/ ! oriw #0x0700,%sr ! SF_PUSH ! /* need this disable interrupt?, i'm not clear yet ! * kwonsk ! * -> we must disable interrupt here, because ! * there could be task switching in the rtl_sched. ! * -> no, rasing priority is temporarily here ! * some day this will be changed. ! * rtl_sched has di/ei code, and this is because ! * of enabling higher rt interrupt ! * but do not enable higher interrupt yet! ! */ ! /*----------------------*/ ! /* get interrupt source */ ! /*----------------------*/ ! movel 0xfffff30c,%d0 ! ! /*-------------------*/ ! /* disable interrupt */ ! /*-------------------*/ ! orl %d0,0xfffff304 ! /* mark interrupt request for linux if rt handler is installed ! * then timer interrupt bit of SFREQ will be set/reset correctly ! * and IMR bit of timer is cleared in the RThandler ! */ ! orl %d0,SFREQ ! bclrl #1,SFREQ ! movel %d0,%sp@- /* put vector # on stack (was %d0) */ ! jbsr SYMBOL_NAME(process_rt)/* process the IRQ */ ! addql #4,%sp /* pop parameters off stack */ + SF_POP + + tstl SYMBOL_NAME(SFIF) + jne 1f + rte + 1: + andiw #0xf8ff,%sr + bra check_iret + #endif /* __RT__ */ + SYMBOL_NAME_LABEL(ret_from_interrupt) /* check if we need to do software interrupts */ + /* if intr_cnt>0 then somebody is already donging s/w int */ + /* if intr_cnt==0 then this is the fast chance ? */ 1: movel SYMBOL_NAME(intr_count),%d1 subql #1,%d1 jne 4f ! /* check interrupted state (from trap or normal) */ moveb %sp@(LSR),%d0 and #0x7,%d0 jhi 4f *************** SYMBOL_NAME_LABEL(ret_from_interrupt) *** 939,952 **** andl SYMBOL_NAME(bh_mask),%d0 jne 3f ! clrl SYMBOL_NAME(intr_count) | deliver signals, reschedule etc.. jra SYMBOL_NAME(ret_from_exception) 3: jbsr SYMBOL_NAME(do_bottom_half) ! jbra 2b 4: movel %d1,SYMBOL_NAME(intr_count) RESTORE_ALL /* Handler for uninitialized and spurious interrupts */ --- 1018,1040 ---- andl SYMBOL_NAME(bh_mask),%d0 jne 3f ! clrl SYMBOL_NAME(intr_count) ! #ifdef __RT__ ! jra SYMBOL_NAME(SF_ret_from_exception) ! #else jra SYMBOL_NAME(ret_from_exception) + #endif /* __RT__ */ 3: jbsr SYMBOL_NAME(do_bottom_half) ! bra 2b ! 4: movel %d1,SYMBOL_NAME(intr_count) + #ifdef __RT__ + SF_RESTORE_ALL + #else RESTORE_ALL + #endif /* __RT__ */ /* Handler for uninitialized and spurious interrupts */ *************** SYMBOL_NAME_LABEL(resume) *** 1027,1037 **** movel %usp,%a2 /* usp */ movel %a2,%a0@(LTSS_USP) - #if 0 - /* busted */ - movel %usp,%d0 /* usp */ - movel %d0,%a0@(LTSS_USP) - #endif /* save current kernel stack pointer */ movel %sp,%a0@(LTSS_KSP) --- 1115,1120 ---- *************** SYMBOL_NAME_LABEL(resume) *** 1040,1051 **** movel %a1,SYMBOL_NAME(current_set) addl %d1,%a1 - /* Skip address space switching if they are the same. */ - /* FIXME: what did we hack out of here, this does nothing! */ - #if 0 - tstb %d2 - jne 4f - #endif 2: 4: /* restore floating point context */ --- 1123,1128 ---- diff -3prN linux.org/arch/m68knommu/platform/68EZ328/ints.c linux.rt/arch/m68knommu/platform/68EZ328/ints.c *** linux.org/arch/m68knommu/platform/68EZ328/ints.c Wed Feb 9 09:53:04 2000 --- linux.rt/arch/m68knommu/platform/68EZ328/ints.c Wed Feb 9 21:46:17 2000 *************** *** 13,18 **** --- 13,19 ---- #include #include #include + #include #include #include *************** *** 20,25 **** --- 21,31 ---- #include #include #include + #include + + #ifdef __RT__ + #include + #endif #define INTERNAL_IRQS (32) *************** static irq_node_t *int_irq_list[INTERNAL *** 29,34 **** --- 35,142 ---- static int int_irq_count[INTERNAL_IRQS]; static short int_irq_ablecount[INTERNAL_IRQS]; + #ifdef __RT__ + /* definitions for interrupt emulation codes */ + /* SFMASK: interrupt enable mask */ + unsigned long SFREQ=0; + unsigned long SFIF=0; + unsigned long SFMASK=0; + + void (*RTaction[INTERNAL_IRQS])(void); + static int rt_irq_status[INTERNAL_IRQS]; + #endif + + static void mask_irq(unsigned int irq) + { + /* disable this irq */ + #ifdef __RT__ + unsigned long flags; + + r_save_flags(flags); + r_cli(); + SFMASK &= ~(1 << irq); + IMR |= 1<= INTERNAL_IRQS) + return -EINVAL; + + if (rt_irq_status[irq]) + return -EBUSY; + + r_save_flags(flags); + r_cli(); + rt_irq_status[irq] = 1; + RTaction[irq] = handler; + unmask_irq(irq); + r_restore_flags(flags); + return 0; + } + + void free_RTirq(unsigned int irq) + { + unsigned long flags; + + if (irq >= INTERNAL_IRQS ) { + printk("Trying to free IRQ%d\n",irq); + return; + } + + if (!rt_irq_status[irq]) { + return; + } + + r_save_flags(flags); + r_cli(); + rt_irq_status[irq] = 0; + mask_irq(irq); + r_restore_flags(flags); + } + + #endif + static void int_badint(int irq, void *dev_id, struct pt_regs *fp) { num_spurious += 1; *************** void M68EZ328_init_IRQ(void) *** 50,70 **** int_irq_ablecount[i] = 0; int_irq_count[i] = 0; } /* turn off all interrupts */ ! *(unsigned volatile long *)0xfffff304 = 0xffffffff; } void M68EZ328_insert_irq(irq_node_t **list, irq_node_t *node) { unsigned long flags; irq_node_t *cur; if (!node->dev_id) printk("%s: Warning: dev_id of %s is zero\n", __FUNCTION__, node->devname); ! save_flags(flags); ! cli(); cur = *list; --- 158,193 ---- int_irq_ablecount[i] = 0; int_irq_count[i] = 0; } + /* turn off all interrupts */ ! #ifdef __RT__ ! SFIF = 0; ! SFMASK = 0; ! SFREQ = 0; ! ! for (i = 0; i < INTERNAL_IRQS; i++) { ! rt_irq_status[i] = 0; ! RTaction[i] = NULL; ! } ! #endif ! IMR = ~0; } void M68EZ328_insert_irq(irq_node_t **list, irq_node_t *node) { + #ifdef __RT__ unsigned long flags; + #endif irq_node_t *cur; if (!node->dev_id) printk("%s: Warning: dev_id of %s is zero\n", __FUNCTION__, node->devname); ! #ifdef __RT__ ! r_save_flags(flags); ! r_cli(); ! #endif cur = *list; *************** void M68EZ328_insert_irq(irq_node_t **li *** 76,102 **** node->next = cur; *list = node; ! restore_flags(flags); } void M68EZ328_delete_irq(irq_node_t **list, void *dev_id) { unsigned long flags; irq_node_t *node; ! save_flags(flags); ! cli(); for (node = *list; node; list = &node->next, node = *list) { if (node->dev_id == dev_id) { *list = node->next; /* Mark it as free. */ node->handler = NULL; ! restore_flags(flags); return; } } ! restore_flags(flags); printk ("%s: tried to remove invalid irq\n", __FUNCTION__); } --- 199,235 ---- node->next = cur; *list = node; ! #ifdef __RT__ ! r_restore_flags(flags); ! #endif } void M68EZ328_delete_irq(irq_node_t **list, void *dev_id) { + #ifdef __RT__ unsigned long flags; + #endif irq_node_t *node; ! #ifdef __RT__ ! r_save_flags(flags); ! r_cli(); ! #endif for (node = *list; node; list = &node->next, node = *list) { if (node->dev_id == dev_id) { *list = node->next; /* Mark it as free. */ node->handler = NULL; ! #ifdef __RT__ ! r_restore_flags(flags); ! #endif return; } } ! #ifdef __RT__ ! r_restore_flags(flags); ! #endif printk ("%s: tried to remove invalid irq\n", __FUNCTION__); } *************** int M68EZ328_request_irq(unsigned int ir *** 132,138 **** /* enable in the IMR */ if (!int_irq_ablecount[irq]) ! *(volatile unsigned long *)0xfffff304 &= ~(1<dev_id = NULL; int_irq_list[irq]->devname = NULL; ! *(volatile unsigned long *)0xfffff304 |= 1<dev_id = NULL; int_irq_list[irq]->devname = NULL; ! mask_irq(irq); } /* *************** void M68EZ328_free_irq(unsigned int irq, *** 165,170 **** --- 298,305 ---- void M68EZ328_enable_irq(unsigned int irq) { + unsigned long flags; + if (irq >= INTERNAL_IRQS) { printk("%s: Unknown IRQ %d\n", __FUNCTION__, irq); return; *************** void M68EZ328_enable_irq(unsigned int ir *** 174,184 **** return; /* enable the interrupt */ ! *(volatile unsigned long *)0xfffff304 &= ~(1<= INTERNAL_IRQS) { printk("%s: Unknown IRQ %d\n", __FUNCTION__, irq); return; --- 309,327 ---- return; /* enable the interrupt */ ! #ifdef __RT__ ! unmask_irq(irq); ! #else ! save_flags(flags); ! cli(); ! unmask_irq(irq); ! restore_flags(flags); ! #endif } void M68EZ328_disable_irq(unsigned int irq) { + unsigned long flags; if (irq >= INTERNAL_IRQS) { printk("%s: Unknown IRQ %d\n", __FUNCTION__, irq); return; *************** void M68EZ328_disable_irq(unsigned int i *** 188,194 **** return; /* disable the interrupt */ ! *(volatile unsigned long *)0xfffff304 |= 1<handler) { int_irq_list[irq]->handler(irq | IRQ_MACHSPEC, int_irq_list[irq]->dev_id, fp); int_irq_count[irq]++; } else { ! printk("unregistered interrupt %d!\nTurning it off in the IMR...\n"); ! *(volatile unsigned long *)0xfffff304 |= mask; } pend &= ~mask; } --- 398,413 ---- } while (! (mask & pend)) { ! mask <<=1; ! irq++; } if (int_irq_list[irq] && int_irq_list[irq]->handler) { int_irq_list[irq]->handler(irq | IRQ_MACHSPEC, int_irq_list[irq]->dev_id, fp); int_irq_count[irq]++; } else { ! printk("unregistered interrupt %d!\nTurning it off in the IMR...\n", irq); ! mask_irq(irq); } pend &= ~mask; } diff -3prN linux.org/drivers/char/68328serial.c linux.rt/drivers/char/68328serial.c *** linux.org/drivers/char/68328serial.c Wed Feb 9 09:53:05 2000 --- linux.rt/drivers/char/68328serial.c Wed Feb 9 21:46:17 2000 *************** static struct termios *serial_termios_lo *** 87,93 **** * buffer across all the serial ports, since it significantly saves * memory if large numbers of serial ports are open. */ ! static unsigned char tmp_buf[4096]; /* This is cheating */ static struct semaphore tmp_buf_sem = MUTEX; static inline int serial_paranoia_check(struct m68k_serial *info, --- 87,93 ---- * buffer across all the serial ports, since it significantly saves * memory if large numbers of serial ports are open. */ ! static unsigned char tmp_buf[SERIAL_XMIT_SIZE]; /* This is cheating */ static struct semaphore tmp_buf_sem = MUTEX; static inline int serial_paranoia_check(struct m68k_serial *info, *************** static inline int get_baud(struct m68k_s *** 134,141 **** { unsigned long result = 115200; unsigned short int baud = UBAUD; ! if (UBAUD_PRESCALE(baud) == 0x38) result = 38400; ! result >>= UBAUD_GETDIV(baud); return result; } --- 134,141 ---- { unsigned long result = 115200; unsigned short int baud = UBAUD; ! if (GET_FIELD(baud, UBAUD_PRESCALER) == 0x38) result = 38400; ! result >>= GET_FIELD(baud, UBAUD_DIVIDE); return result; } *************** static void rs_stop(struct tty_struct *t *** 163,173 **** static void rs_put_char(char ch) { ! int flags, loops = 0; save_flags(flags); cli(); ! while (!(UTX & UTX_FIFO_EMPTY) && (loops < 1000)) { loops++; udelay(5); } --- 163,174 ---- static void rs_put_char(char ch) { ! int loops = 0; ! unsigned long flags; save_flags(flags); cli(); ! while (!(UTX & UTX_TX_AVAIL) && (loops < 1000)) { loops++; udelay(5); } *************** static void rs_start(struct tty_struct * *** 188,195 **** save_flags(flags); cli(); if (info->xmit_cnt && info->xmit_buf && !(USTCNT & USTCNT_TXEN)) { #ifdef USE_INTS ! USTCNT |= USTCNT_TXEN ! |USTCNT_TXEMPTYEN |USTCNT_TXHALFEN |USTCNT_TXAVAILEN; #else USTCNT |= USTCNT_TXEN; #endif --- 189,195 ---- save_flags(flags); cli(); if (info->xmit_cnt && info->xmit_buf && !(USTCNT & USTCNT_TXEN)) { #ifdef USE_INTS ! USTCNT |= USTCNT_TXEN | USTCNT_TX_INTR_MASK; #else USTCNT |= USTCNT_TXEN; #endif *************** static void batten_down_hatches(void) *** 205,210 **** --- 205,237 ---- /* Drop into the debugger */ } + static _INLINE_ void status_handle(struct m68k_serial *info, unsigned short status) + { + #if 0 + if(status & DCD) { + if((info->tty->termios->c_cflag & CRTSCTS) && + ((info->curregs[3] & AUTO_ENAB)==0)) { + info->curregs[3] |= AUTO_ENAB; + info->pendregs[3] |= AUTO_ENAB; + write_zsreg(info->m68k_channel, 3, info->curregs[3]); + } + } else { + if((info->curregs[3] & AUTO_ENAB)) { + info->curregs[3] &= ~AUTO_ENAB; + info->pendregs[3] &= ~AUTO_ENAB; + write_zsreg(info->m68k_channel, 3, info->curregs[3]); + } + } + #endif + /* If this is console input and this is a + * 'break asserted' status change interrupt + * see if we can drop into the debugger + */ + if((status & URX_BREAK) && info->break_abort) + batten_down_hatches(); + return; + } + /* * This routine is used by the interrupt handler to schedule * processing in the software interrupt portion of the driver. *************** static _INLINE_ void receive_chars(struc *** 223,238 **** unsigned char ch; /* ! * This do { } while() lopo will get ALL chars out of Rx FIFO */ #ifndef CONFIG_XCOPILOT_BUGS do { #endif ! ch = rx & 0xff; if(info->is_cons) { if(URX_BREAK & rx) { /* whee, break received */ ! batten_down_hatches(); return; } else if (ch == 0x10) { /* ^P */ show_state(); --- 250,265 ---- unsigned char ch; /* ! * This do { } while() loop will get ALL chars out of Rx FIFO */ #ifndef CONFIG_XCOPILOT_BUGS do { #endif ! ch = GET_FIELD(rx, URX_RXDATA); if(info->is_cons) { if(URX_BREAK & rx) { /* whee, break received */ ! status_handle(info, rx); return; } else if (ch == 0x10) { /* ^P */ show_state(); *************** static _INLINE_ void receive_chars(struc *** 250,268 **** if(!tty) goto clear_and_exit; ! ! if (tty->flip.count >= TTY_FLIPBUF_SIZE) queue_task_irq_off(&tty->flip.tqueue, &tq_timer); ! tty->flip.count++; ! if(rx & URX_PARITY_ERROR) *tty->flip.flag_buf_ptr++ = TTY_PARITY; ! else if(rx & URX_OVRUN) *tty->flip.flag_buf_ptr++ = TTY_OVERRUN; ! else if(rx & URX_FRAME_ERROR) *tty->flip.flag_buf_ptr++ = TTY_FRAME; ! else *tty->flip.flag_buf_ptr++ = 0; /* XXX */ ! *tty->flip.char_buf_ptr++ = ch; #ifndef CONFIG_XCOPILOT_BUGS } while((rx = URX) & URX_DATA_READY); #endif --- 277,306 ---- if(!tty) goto clear_and_exit; ! ! /* ! * Make sure that we do not overflow the buffer ! */ ! if (tty->flip.count >= TTY_FLIPBUF_SIZE) { queue_task_irq_off(&tty->flip.tqueue, &tq_timer); ! return; ! } ! ! if(rx & URX_PARITY_ERROR) { *tty->flip.flag_buf_ptr++ = TTY_PARITY; ! status_handle(info, rx); ! } else if(rx & URX_OVRUN) { *tty->flip.flag_buf_ptr++ = TTY_OVERRUN; ! status_handle(info, rx); ! } else if(rx & URX_FRAME_ERROR) { *tty->flip.flag_buf_ptr++ = TTY_FRAME; ! status_handle(info, rx); ! } else { *tty->flip.flag_buf_ptr++ = 0; /* XXX */ ! } ! *tty->flip.char_buf_ptr++ = ch; ! tty->flip.count++; ! #ifndef CONFIG_XCOPILOT_BUGS } while((rx = URX) & URX_DATA_READY); #endif *************** static _INLINE_ void transmit_chars(stru *** 284,290 **** if((info->xmit_cnt <= 0) || info->tty->stopped) { /* That's peculiar... TX ints off */ ! USTCNT &= ~ (USTCNT_TXEMPTYEN |USTCNT_TXHALFEN |USTCNT_TXAVAILEN); goto clear_and_return; } --- 322,328 ---- if((info->xmit_cnt <= 0) || info->tty->stopped) { /* That's peculiar... TX ints off */ ! USTCNT &= ~USTCNT_TX_INTR_MASK; goto clear_and_return; } *************** static _INLINE_ void transmit_chars(stru *** 298,304 **** if(info->xmit_cnt <= 0) { /* All done for now... TX ints off */ ! USTCNT &= ~ (USTCNT_TXEMPTYEN |USTCNT_TXHALFEN |USTCNT_TXAVAILEN); goto clear_and_return; } --- 336,342 ---- if(info->xmit_cnt <= 0) { /* All done for now... TX ints off */ ! USTCNT &= ~USTCNT_TX_INTR_MASK; goto clear_and_return; } *************** clear_and_return: *** 307,339 **** return; } - static _INLINE_ void status_handle(struct m68k_serial *info, unsigned short status) - { - #if 0 - if(status & DCD) { - if((info->tty->termios->c_cflag & CRTSCTS) && - ((info->curregs[3] & AUTO_ENAB)==0)) { - info->curregs[3] |= AUTO_ENAB; - info->pendregs[3] |= AUTO_ENAB; - write_zsreg(info->m68k_channel, 3, info->curregs[3]); - } - } else { - if((info->curregs[3] & AUTO_ENAB)) { - info->curregs[3] &= ~AUTO_ENAB; - info->pendregs[3] &= ~AUTO_ENAB; - write_zsreg(info->m68k_channel, 3, info->curregs[3]); - } - } - #endif - /* If this is console input and this is a - * 'break asserted' status change interrupt - * see if we can drop into the debugger - */ - if((status & URX_BREAK) && info->break_abort) - batten_down_hatches(); - return; - } - /* * This is the serial driver's generic interrupt routine */ --- 345,350 ---- *************** void rs_interrupt(int irq, void *dev_id, *** 344,357 **** #ifdef USE_INTS unsigned short tx = UTX; ! if (tx & UTX_TX_AVAIL) transmit_chars(info); ! if (rx & URX_DATA_READY) #endif - receive_chars(info, regs, rx); - if (rx & - (URX_OVRUN |URX_FRAME_ERROR |URX_BREAK |URX_PARITY_ERROR)) - status_handle(info, rx); - return; } --- 355,365 ---- #ifdef USE_INTS unsigned short tx = UTX; ! if (rx & URX_DATA_READY) receive_chars(info, regs, rx); ! if (tx & UTX_TX_AVAIL) transmit_chars(info); ! #else ! receive_chars(info, regs, rx); #endif return; } *************** static int startup(struct m68k_serial * *** 448,454 **** /* * Finally, enable sequencing and interrupts */ ! USTCNT = USTCNT_UEN | USTCNT_RXEN | USTCNT_RXREADYEN; if (info->tty) clear_bit(TTY_IO_ERROR, &info->tty->flags); --- 456,467 ---- /* * Finally, enable sequencing and interrupts */ ! #ifdef USE_INTS ! USTCNT = USTCNT_UEN | USTCNT_RXEN | ! USTCNT_RX_INTR_MASK | USTCNT_TX_INTR_MASK; ! #else ! USTCNT = USTCNT_UEN | USTCNT_RXEN | USTCNT_RX_INTR_MASK; ! #endif if (info->tty) clear_bit(TTY_IO_ERROR, &info->tty->flags); *************** static void change_speed(struct m68k_ser *** 541,547 **** } info->baud = baud_table[i]; ! UBAUD = UBAUD_SETDIV(hw_baud_table[i].divisor) | UBAUD_PRESCALE(hw_baud_table[i].prescale); ustcnt &= ~(USTCNT_PARITYEN | USTCNT_ODD_EVEN | USTCNT_STOP | USTCNT_8_7); --- 554,561 ---- } info->baud = baud_table[i]; ! UBAUD = PUT_FIELD(UBAUD_DIVIDE, hw_baud_table[i].divisor) | ! PUT_FIELD(UBAUD_PRESCALER, hw_baud_table[i].prescale); ustcnt &= ~(USTCNT_PARITYEN | USTCNT_ODD_EVEN | USTCNT_STOP | USTCNT_8_7); *************** static void change_speed(struct m68k_ser *** 556,562 **** if (cflag & PARODD) ustcnt |= USTCNT_ODD_EVEN; ! #ifdef USE_RTSCTS if (cflag & CRTSCTS) { UTX &= ~ UTX_NOCTS; } else { --- 570,576 ---- if (cflag & PARODD) ustcnt |= USTCNT_ODD_EVEN; ! #ifdef CONFIG_68328_SERIAL_RTS_CTS if (cflag & CRTSCTS) { UTX &= ~ UTX_NOCTS; } else { *************** static void rs_flush_chars(struct tty_st *** 653,666 **** save_flags(flags); cli(); #ifdef USE_INTS ! USTCNT |= USTCNT_TXEN ! |USTCNT_TXEMPTYEN |USTCNT_TXHALFEN |USTCNT_TXAVAILEN; #else USTCNT |= USTCNT_TXEN; #endif #ifdef USE_INTS ! if (UTX & UTX_FIFO_EMPTY) { #else if (1) { #endif --- 667,679 ---- save_flags(flags); cli(); #ifdef USE_INTS ! USTCNT |= USTCNT_TXEN | USTCNT_TX_INTR_MASK; #else USTCNT |= USTCNT_TXEN; #endif #ifdef USE_INTS ! if (UTX & UTX_TX_AVAIL) { #else if (1) { #endif *************** static void rs_flush_chars(struct tty_st *** 671,677 **** } #ifndef USE_INTS ! while (!(UTX & UTX_FIFO_EMPTY)) udelay(5); } #endif restore_flags(flags); --- 684,690 ---- } #ifndef USE_INTS ! while (!(UTX & UTX_TX_AVAIL)) udelay(5); } #endif restore_flags(flags); *************** static int rs_write(struct tty_struct * *** 726,736 **** USTCNT |= USTCNT_TXEN; #ifdef USE_INTS ! USTCNT |= USTCNT_TXEMPTYEN | USTCNT_TXHALFEN | USTCNT_TXAVAILEN ; #else ! while (!(UTX & UTX_FIFO_EMPTY)) udelay(5); #endif ! if (UTX & UTX_FIFO_EMPTY) { UTX_TXDATA = info->xmit_buf[info->xmit_tail++]; info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE-1); info->xmit_cnt--; --- 739,749 ---- USTCNT |= USTCNT_TXEN; #ifdef USE_INTS ! USTCNT |= USTCNT_TX_INTR_MASK; #else ! while (!(UTX & UTX_TX_AVAIL)) udelay(5); #endif ! if (UTX & UTX_TX_AVAIL) { UTX_TXDATA = info->xmit_buf[info->xmit_tail++]; info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE-1); info->xmit_cnt--; *************** static int get_lsr_info(struct m68k_seri *** 907,913 **** unsigned char status; cli(); ! #ifdef USE_RTSCTS status = (UTX & UTX_CTS_STAT) ? 1 : 0; #else status = 0; --- 920,926 ---- unsigned char status; cli(); ! #ifdef CONFIG_68328_SERIAL_RTS_CTS status = (UTX & UTX_CTS_STAT) ? 1 : 0; #else status = 0; *************** static void rs_close(struct tty_struct * *** 1100,1107 **** * line status register. */ ! USTCNT |= ~USTCNT_RXEN; ! USTCNT |= ~(USTCNT_RXEN | USTCNT_RXFULLEN | USTCNT_RXHALFEN | USTCNT_RXREADYEN); shutdown(info); if (tty->driver.flush_buffer) --- 1113,1120 ---- * line status register. */ ! USTCNT &= ~USTCNT_RXEN; ! USTCNT &= ~(USTCNT_RXEN | USTCNT_RX_INTR_MASK); shutdown(info); if (tty->driver.flush_buffer) *************** volatile int test_done; *** 1335,1341 **** /* rs_init inits the driver */ int rs68328_init(void) { ! int flags; struct m68k_serial *info; /* Setup base handler, and timer table. */ --- 1348,1354 ---- /* rs_init inits the driver */ int rs68328_init(void) { ! unsigned long flags; struct m68k_serial *info; /* Setup base handler, and timer table. */ *************** int rs68328_init(void) *** 1358,1365 **** serial_driver.subtype = SERIAL_TYPE_NORMAL; serial_driver.init_termios = tty_std_termios; ! serial_driver.init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; serial_driver.flags = TTY_DRIVER_REAL_RAW; serial_driver.refcount = &serial_refcount; serial_driver.table = serial_table; --- 1371,1390 ---- serial_driver.subtype = SERIAL_TYPE_NORMAL; serial_driver.init_termios = tty_std_termios; ! ! serial_driver.init_termios.c_cflag = ! #if defined(CONFIG_PILOT) ! B9600 | CS8 | CREAD | HUPCL | CLOCAL; ! #elif defined(CONFIG_UCSIMM) B9600 | CS8 | CREAD | HUPCL | CLOCAL; + #elif defined(CONFIG_M68EZ328ADS) + B115200 | CS8 | CREAD | HUPCL | CLOCAL; + #elif defined(CONFIG_ALMA_ANS) + B115200 | CS8 | CREAD | HUPCL | CLOCAL; + #else + #error Please, define the default console settings for your board + #endif + serial_driver.flags = TTY_DRIVER_REAL_RAW; serial_driver.refcount = &serial_refcount; serial_driver.table = serial_table; *************** int rs68328_init(void) *** 1425,1435 **** info->port, info->irq); printk(" is a builtin MC68328 UART\n"); ! if (request_irq(IRQ_MACHSPEC | 2, rs_interrupt, IRQ_FLG_STD, "M68328_UART", NULL)) ! panic("Unable to attach 68328 intr\n"); restore_flags(flags); return 0; } --- 1450,1460 ---- info->port, info->irq); printk(" is a builtin MC68328 UART\n"); ! if (request_irq(IRQ_MACHSPEC | UART_IRQ_NUM, rs_interrupt, IRQ_FLG_STD, "M68328_UART", NULL)) ! panic("Unable to attach 68328 serial interrupt\n"); restore_flags(flags); return 0; } diff -3prN linux.org/drivers/char/68328serial.h linux.rt/drivers/char/68328serial.h *** linux.org/drivers/char/68328serial.h Wed Feb 9 09:53:05 2000 --- linux.rt/drivers/char/68328serial.h Wed Feb 9 21:46:17 2000 *************** struct serial_struct { *** 73,89 **** /* Software state per channel */ #ifdef __KERNEL__ /* ! * some convienence macros */ - #undef UBAUD_PRESCALEMASK - #undef UBAUD_DIVMASK ! #define UBAUD_DIVMASK (0x7 << 8) ! #define UBAUD_GETDIV(X) ((0x7 & (X)) >> 8) ! #define UBAUD_SETDIV(X) ((0x7 & (X)) << 8) ! #define UBAUD_PRESCALEMASK (0x3f << 0) ! #define UBAUD_PRESCALE(X) ((0x3f & (X)) << 0) /* * This is our internal structure for each serial port's state. --- 73,115 ---- /* Software state per channel */ #ifdef __KERNEL__ + + /* + * I believe this is the optimal setting that reduces the number of interrupts. + * At high speeds the output might become a little "bursted" (use USTCNT_TXHE + * if that bothers you), but in most cases it will not, since we try to + * transmit characters every time rs_interrupt is called. Thus, quite often + * you'll see that a receive interrupt occures before the transmit one. + * -- Vladimir Gurevich + */ + #define USTCNT_TX_INTR_MASK (USTCNT_TXEE) + /* ! * 68328 and 68EZ328 UARTS are a little bit different. EZ328 has special ! * "Old data interrupt" which occures whenever the data stay in the FIFO ! * longer than 30 bits time. This allows us to use FIFO without compromising ! * latency. '328 does not have this feature and without the real 328-based ! * board I would assume that RXRE is the safest setting. ! * ! * For EZ328 I use RXHE (Half empty) interrupt to reduce the number of ! * interrupts. RXFE (receive queue full) causes the system to loose data ! * at least at 115200 baud ! * ! * If your board is busy doing other stuff, you might consider to use ! * RXRE (data ready intrrupt) instead. ! * ! * The other option is to make these INTR masks run-time configurable, so ! * that people can dynamically adapt them according to the current usage. ! * -- Vladimir Gurevich */ ! #if defined(CONFIG_M68EZ328) ! #define USTCNT_RX_INTR_MASK (USTCNT_RXHE | USTCNT_ODEN) ! #elif defined(CONFIG_M68328) ! #define USTCNT_RX_INTR_MASK (USTCNT_RXRE) ! #else ! #error Please, define the Rx interrupt events for your CPU ! #endif /* * This is our internal structure for each serial port's state. diff -3prN linux.org/drivers/char/mem.c linux.rt/drivers/char/mem.c *** linux.org/drivers/char/mem.c Wed Feb 9 09:53:05 2000 --- linux.rt/drivers/char/mem.c Wed Feb 9 21:46:17 2000 *************** *** 30,35 **** --- 30,39 ---- #include #include + #ifdef __RT__ + extern int rtf_init(void); + #endif + #ifdef CONFIG_SOUND void soundcard_init(void); #endif *************** int chr_dev_init(void) *** 431,436 **** --- 435,443 ---- #endif #ifdef CONFIG_FTAPE ftape_init(); + #endif + #ifdef __RT__ + rtf_init(); #endif return 0; } diff -3prN linux.org/fs/proc/root.c linux.rt/fs/proc/root.c *** linux.org/fs/proc/root.c Wed Feb 9 09:53:06 2000 --- linux.rt/fs/proc/root.c Wed Feb 9 21:46:17 2000 *************** struct proc_dir_entry pde_locks = { *** 352,357 **** --- 352,364 ---- S_IFREG | S_IRUGO, 1, 0, 0, }; + #ifdef __RT__ + struct proc_dir_entry pde_rtlinux = { + PROC_RTLINUX, 7, "rtlinux", + S_IFREG | S_IRUGO, 1, 0, 0, + }; + #endif + struct proc_dir_entry pde_mounts = { PROC_MTAB, 6, "mounts", S_IFREG | S_IRUGO, 1, 0, 0, }; *************** void proc_root_init(void) *** 406,411 **** --- 413,421 ---- proc_register(&proc_root, &pde_rtc); #endif proc_register(&proc_root, &pde_locks); + #ifdef __RT__ + proc_register(&proc_root, &pde_rtlinux); + #endif proc_register( &proc_root, &pde_mounts); diff -3prN linux.org/include/asm-m68knommu/MC68EZ328.h linux.rt/include/asm-m68knommu/MC68EZ328.h *** linux.org/include/asm-m68knommu/MC68EZ328.h Wed Feb 9 09:53:06 2000 --- linux.rt/include/asm-m68knommu/MC68EZ328.h Wed Feb 9 21:46:17 2000 *************** *** 244,249 **** --- 244,276 ---- #define IMR_MSPIM IMR_MSPI #define IMR_MTMR1 IMR_MTMR + /* + * Define the names for bit positions first. This is useful for + * request_irq + */ + #define SPI_IRQ_NUM 0 /* SPI interrupt */ + #define TMR_IRQ_NUM 1 /* Timer interrupt */ + #define UART_IRQ_NUM 2 /* UART interrupt */ + #define WDT_IRQ_NUM 3 /* Watchdog Timer interrupt */ + #define RTC_IRQ_NUM 4 /* RTC interrupt */ + #define KB_IRQ_NUM 6 /* Keyboard Interrupt */ + #define PWM_IRQ_NUM 7 /* Pulse-Width Modulator int. */ + #define INT0_IRQ_NUM 8 /* External INT0 */ + #define INT1_IRQ_NUM 9 /* External INT1 */ + #define INT2_IRQ_NUM 10 /* External INT2 */ + #define INT3_IRQ_NUM 11 /* External INT3 */ + #define IRQ1_IRQ_NUM 16 /* IRQ1 */ + #define IRQ2_IRQ_NUM 17 /* IRQ2 */ + #define IRQ3_IRQ_NUM 18 /* IRQ3 */ + #define IRQ6_IRQ_NUM 19 /* IRQ6 */ + #define IRQ5_IRQ_NUM 20 /* IRQ5 */ + #define SAM_IRQ_NUM 22 /* Sampling Timer for RTC */ + #define EMIQ_IRQ_NUM 23 /* Emulator Interrupt */ + + /* '328-compatible definitions */ + #define SPIM_IRQ_NUM SPI_IRQ_NUM + #define TMR1_IRQ_NUM TMR_IRQ_NUM + /* * Interrupt Status Register */ diff -3prN linux.org/include/asm-m68knommu/rt_irq.h linux.rt/include/asm-m68knommu/rt_irq.h *** linux.org/include/asm-m68knommu/rt_irq.h Thu Jan 1 09:00:00 1970 --- linux.rt/include/asm-m68knommu/rt_irq.h Wed Feb 9 21:46:17 2000 *************** *** 0 **** --- 1,24 ---- + /* + * include/asm-m68knommu/rt_irq.h + * + * Written by Michael Barabanov + * Copyright VJY Associates + * Released under the terms of the LGPL + * + * Real Time support for uClinux by Kwon Seok Kuon 02/03/2000 + */ + + #ifndef __RTIRQ__ + #define __RTIRQ__ + + extern int request_RTirq(unsigned int irq, void (*handler)(void) ); + extern void free_RTirq(unsigned int irq); + extern void process_rt(unsigned long mask); + + extern unsigned long SFIF; + extern unsigned long SFREQ; + extern void s_cli(void); + extern void s_sti(void); + + + #endif diff -3prN linux.org/include/asm-m68knommu/rt_time.h linux.rt/include/asm-m68knommu/rt_time.h *** linux.org/include/asm-m68knommu/rt_time.h Thu Jan 1 09:00:00 1970 --- linux.rt/include/asm-m68knommu/rt_time.h Wed Feb 9 21:46:17 2000 *************** *** 0 **** --- 1,55 ---- + #ifndef __RT_TIME_H__ + #define __RT_TIME_H__ + + /* + * linux/include/asm/rt_time.h + * + * low-level time-related routines + * + * Written by Michael Barabanov + * Copyright VJY Associates + * Released under the terms of the LGPL + * + * + * Real Time support for uClinux by Kwon Seok Kuon 02/03/2000 + */ + + #ifdef __KERNEL__ + + #include + #include + + #endif + + + #define RT_TICKS_PER_SEC 1036288LL + #define RT_TIME_END 0x7fffFfffFfffFfffLL + + /* for larger periods we will have problems with jiffies */ + #define RT_MAX_PERIOD 10000 + + typedef long long RTIME; + + extern RTIME rt_linux_clock; + extern RTIME rt_base_time; + + + extern RTIME rt_get_time_MC68EZ328(void); + + static inline RTIME rt_get_time(void) + { + return rt_get_time_MC68EZ328(); + } + + extern int rt_request_timer(void (*fn)(void)); + extern void rt_free_timer(void); + extern void rt_set_timer(RTIME when); + extern void rt_no_timer(void); + + static inline RTIME rt_ts_to_rtime(struct timespec *res) + { + return res->tv_sec * RT_TICKS_PER_SEC + res->tv_nsec * RT_TICKS_PER_SEC / 1000000000LL; + } + + extern void MC68EZ328_make_oneshot(unsigned int); + #endif diff -3prN linux.org/include/asm-m68knommu/system.h linux.rt/include/asm-m68knommu/system.h *** linux.org/include/asm-m68knommu/system.h Wed Feb 9 09:53:07 2000 --- linux.rt/include/asm-m68knommu/system.h Wed Feb 9 21:46:17 2000 *************** asmlinkage void resume(void); *** 86,108 **** struct __xchg_dummy { unsigned long a[100]; }; #define __xg(x) ((volatile struct __xchg_dummy *)(x)) ! #if defined(CONFIG_ATARI) && !defined(CONFIG_AMIGA) && !defined(CONFIG_MAC) ! /* block out HSYNC on the atari */ ! #define sti() __asm__ __volatile__ ("andiw #0xfbff,%/sr": : : "memory") ! #else /* portable version */ ! #define sti() __asm__ __volatile__ ("andiw #0xf8ff,%/sr": : : "memory") ! #endif /* machine compilation types */ #define cli() __asm__ __volatile__ ("oriw #0x0700,%/sr": : : "memory") - #define nop() __asm__ __volatile__ ("nop"::) - #define mb() __asm__ __volatile__ ("" : : :"memory") #define save_flags(x) \ __asm__ __volatile__("movew %/sr,%0":"=d" (x) : /* no input */ :"memory") - #define restore_flags(x) \ __asm__ __volatile__("movew %0,%/sr": /* no outputs */ :"d" (x) : "memory") ! #define iret() __asm__ __volatile__ ("rte": : :"memory", "sp", "cc") #ifndef CONFIG_RMW_INSNS static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size) --- 86,125 ---- struct __xchg_dummy { unsigned long a[100]; }; #define __xg(x) ((volatile struct __xchg_dummy *)(x)) ! #ifdef __RT__ ! #define r_sti() __asm__ __volatile__ ("andiw #0xf8ff,%/sr": : : "memory") ! #define r_cli() __asm__ __volatile__ ("oriw #0x0700,%/sr": : : "memory") ! ! #define r_save_flags(x) \ ! __asm__ __volatile__("movew %/sr,%0":"=d" (x) : /* no input */ :"memory") ! #define r_restore_flags(x) \ ! __asm__ __volatile__("movew %0,%/sr": /* no outputs */ :"d" (x) : "memory") ! ! extern void s_sti(void); ! extern void s_cli(void); ! ! extern unsigned long SFIF; ! ! #define sti() s_sti() ! #define cli() SFIF=0 ! ! #define save_flags(x) x=SFIF ! #define restore_flags(x) if(x) sti(); else cli() ! ! #else ! ! #define sti() __asm__ __volatile__ ("andiw #0xf8ff,%/sr": : : "memory") #define cli() __asm__ __volatile__ ("oriw #0x0700,%/sr": : : "memory") #define save_flags(x) \ __asm__ __volatile__("movew %/sr,%0":"=d" (x) : /* no input */ :"memory") #define restore_flags(x) \ __asm__ __volatile__("movew %0,%/sr": /* no outputs */ :"d" (x) : "memory") ! #endif /* __RT__ */ ! ! #define nop() __asm__ __volatile__ ("nop"::) ! #define mb() __asm__ __volatile__ ("" : : :"memory") #ifndef CONFIG_RMW_INSNS static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size) diff -3prN linux.org/include/linux/cons.h linux.rt/include/linux/cons.h *** linux.org/include/linux/cons.h Thu Jan 1 09:00:00 1970 --- linux.rt/include/linux/cons.h Wed Feb 9 21:46:17 2000 *************** *** 0 **** --- 1,46 ---- + /* + * debugging routines for RT-Linux + * + * Written by Michael Barabanov + * Copyright VJY Associates + * Released under the terms of the LGPL + * + */ + + #include + + extern void console_print_68328(const char * b); + extern int sprintf(char * buf, const char * fmt, ...); + + + #define conpr(s) \ + { \ + console_print_68328(s); \ + } + + + static inline void conprn(unsigned int n) + { + int i; + int d; + char s[10]; + s[9] = 0; + s[8] = ' '; + for (i=7; i>=0; i--) { + d = n % 16; + if (d < 10) { + d += '0'; + } else { + d += 'a' - 10; + } + s[i] = d; + n = n / 16; + } + conpr(s); + } + + extern inline void conf(void) { + int i; + for ( i=0; i< 10000000; i++); + } + diff -3prN linux.org/include/linux/major.h linux.rt/include/linux/major.h *** linux.org/include/linux/major.h Wed Feb 9 09:53:07 2000 --- linux.rt/include/linux/major.h Wed Feb 9 21:46:17 2000 *************** *** 84,89 **** --- 84,93 ---- #define SPECIALIX_NORMAL_MAJOR 75 #define SPECIALIX_CALLOUT_MAJOR 76 + #ifdef __RT__ + #define RTF_MAJOR 63 /* RT-FIFOs */ + #endif + /* * Tests for SCSI devices. */ diff -3prN linux.org/include/linux/proc_fs.h linux.rt/include/linux/proc_fs.h *** linux.org/include/linux/proc_fs.h Wed Feb 9 09:53:07 2000 --- linux.rt/include/linux/proc_fs.h Wed Feb 9 21:46:17 2000 *************** enum root_directory_inos { *** 43,49 **** PROC_MTAB, PROC_MD, PROC_RTC, ! PROC_LOCKS }; enum pid_directory_inos { --- 43,50 ---- PROC_MTAB, PROC_MD, PROC_RTC, ! PROC_LOCKS, ! PROC_RTLINUX }; enum pid_directory_inos { diff -3prN linux.org/include/linux/rt_time.h linux.rt/include/linux/rt_time.h *** linux.org/include/linux/rt_time.h Thu Jan 1 09:00:00 1970 --- linux.rt/include/linux/rt_time.h Wed Feb 9 21:46:17 2000 *************** *** 0 **** --- 1,6 ---- + #ifndef __RT_LINUX_TIME_H__ + #define __RT_LINUX_TIME_H__ + + #include + + #endif diff -3prN linux.org/include/linux/rtl_version.h linux.rt/include/linux/rtl_version.h *** linux.org/include/linux/rtl_version.h Thu Jan 1 09:00:00 1970 --- linux.rt/include/linux/rtl_version.h Wed Feb 9 21:46:17 2000 *************** *** 0 **** --- 1,2 ---- + extern int get_rtl_status(char *); + #define rtl_version_string "RTLinux Release 9J for uClinux 2.0.38 Feb 2000\n" diff -3prN linux.org/include/linux/timex.h linux.rt/include/linux/timex.h *** linux.org/include/linux/timex.h Sat Nov 8 03:06:21 1997 --- linux.rt/include/linux/timex.h Wed Feb 9 21:46:17 2000 *************** *** 130,136 **** * This definitively is wrong for the Alpha and none of the * kernel code seems to reference this anymore. */ ! #define CLOCK_TICK_RATE 1193180 /* Underlying HZ */ #define CLOCK_TICK_FACTOR 20 /* Factor of both 1000000 and CLOCK_TICK_RATE */ #define LATCH ((CLOCK_TICK_RATE + HZ/2) / HZ) /* For divider */ --- 130,136 ---- * This definitively is wrong for the Alpha and none of the * kernel code seems to reference this anymore. */ ! #define CLOCK_TICK_RATE 1036288 /* Underlying HZ */ #define CLOCK_TICK_FACTOR 20 /* Factor of both 1000000 and CLOCK_TICK_RATE */ #define LATCH ((CLOCK_TICK_RATE + HZ/2) / HZ) /* For divider */ diff -3prN linux.org/include/