From ac7d5ef06a6d6e8d84abbd1f0b82162725f98326 Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Thu, 11 May 1995 17:39:37 +0000 Subject: Initial revision --- c/src/lib/include/clockdrv.h | 58 +++ c/src/lib/include/console.h | 40 ++ c/src/lib/include/iosupp.h | 44 ++ c/src/lib/include/rtems/libcsupport.h | 47 ++ c/src/lib/include/spurious.h | 38 ++ c/src/lib/include/timerdrv.h | 40 ++ c/src/lib/include/vmeintr.h | 58 +++ c/src/lib/libbsp/README | 46 ++ c/src/lib/libbsp/hppa1.1/simhppa/include/bsp.h | 93 ++++ c/src/lib/libbsp/hppa1.1/simhppa/include/coverhd.h | 104 ++++ c/src/lib/libbsp/hppa1.1/simhppa/shmsupp/README | 9 + .../lib/libbsp/hppa1.1/simhppa/shmsupp/addrconv.c | 30 ++ c/src/lib/libbsp/hppa1.1/simhppa/shmsupp/getcfg.c | 84 ++++ c/src/lib/libbsp/hppa1.1/simhppa/shmsupp/intr.c | 64 +++ c/src/lib/libbsp/hppa1.1/simhppa/shmsupp/lock.c | 75 +++ c/src/lib/libbsp/hppa1.1/simhppa/shmsupp/mpisr.c | 27 + .../lib/libbsp/hppa1.1/simhppa/startup/bspclean.c | 36 ++ .../lib/libbsp/hppa1.1/simhppa/startup/bspstart.c | 387 +++++++++++++++ c/src/lib/libbsp/hppa1.1/simhppa/startup/setvec.c | 66 +++ .../lib/libbsp/hppa1.1/simhppa/tools/print_dump.c | 332 +++++++++++++ c/src/lib/libbsp/i386/force386/clock/ckinit.c | 75 +++ c/src/lib/libbsp/i386/force386/console/console.c | 219 +++++++++ c/src/lib/libbsp/i386/force386/include/bsp.h | 156 ++++++ c/src/lib/libbsp/i386/force386/include/coverhd.h | 104 ++++ c/src/lib/libbsp/i386/force386/shmsupp/addrconv.c | 32 ++ c/src/lib/libbsp/i386/force386/shmsupp/getcfg.c | 73 +++ c/src/lib/libbsp/i386/force386/shmsupp/lock.c | 83 ++++ c/src/lib/libbsp/i386/force386/shmsupp/mpisr.c | 31 ++ c/src/lib/libbsp/i386/force386/startup/bspstart.c | 144 ++++++ c/src/lib/libbsp/i386/force386/startup/exit.c | 29 ++ c/src/lib/libbsp/i386/force386/startup/ldsegs.s | 86 ++++ c/src/lib/libbsp/i386/force386/startup/linkcmds | 44 ++ c/src/lib/libbsp/i386/force386/startup/setvec.c | 59 +++ c/src/lib/libbsp/i386/force386/timer/timer.c | 96 ++++ c/src/lib/libbsp/i386/force386/timer/timerisr.s | 34 ++ c/src/lib/libbsp/i960/cvme961/clock/ckinit.c | 77 +++ c/src/lib/libbsp/i960/cvme961/console/console.c | 147 ++++++ c/src/lib/libbsp/i960/cvme961/include/bsp.h | 129 +++++ c/src/lib/libbsp/i960/cvme961/include/coverhd.h | 104 ++++ c/src/lib/libbsp/i960/cvme961/shmsupp/addrconv.c | 37 ++ c/src/lib/libbsp/i960/cvme961/shmsupp/getcfg.c | 98 ++++ c/src/lib/libbsp/i960/cvme961/shmsupp/lock.c | 77 +++ c/src/lib/libbsp/i960/cvme961/shmsupp/mpisr.c | 70 +++ c/src/lib/libbsp/i960/cvme961/startup/bspclean.c | 32 ++ c/src/lib/libbsp/i960/cvme961/startup/bspstart.c | 163 +++++++ c/src/lib/libbsp/i960/cvme961/startup/exit.c | 38 ++ c/src/lib/libbsp/i960/cvme961/startup/linkcmds | 48 ++ c/src/lib/libbsp/i960/cvme961/startup/setvec.c | 145 ++++++ c/src/lib/libbsp/i960/cvme961/timer/timer.c | 107 ++++ c/src/lib/libbsp/i960/cvme961/timer/timerisr.s | 59 +++ c/src/lib/libbsp/m68k/dmv152/clock/ckinit.c | 101 ++++ c/src/lib/libbsp/m68k/dmv152/console/console.c | 186 +++++++ c/src/lib/libbsp/m68k/dmv152/include/bsp.h | 169 +++++++ c/src/lib/libbsp/m68k/dmv152/include/coverhd.h | 104 ++++ c/src/lib/libbsp/m68k/dmv152/spurious/spinit.c | 46 ++ c/src/lib/libbsp/m68k/dmv152/startup/bspstart.c | 171 +++++++ c/src/lib/libbsp/m68k/dmv152/startup/linkcmds | 48 ++ c/src/lib/libbsp/m68k/dmv152/startup/vmeintr.c | 60 +++ c/src/lib/libbsp/m68k/dmv152/timer/timer.c | 105 ++++ c/src/lib/libbsp/m68k/dmv152/timer/timerisr.s | 38 ++ c/src/lib/libbsp/m68k/idp/README | 31 ++ c/src/lib/libbsp/m68k/idp/clock/ckinit.c | 126 +++++ c/src/lib/libbsp/m68k/idp/console/console.c | 216 ++++++++ c/src/lib/libbsp/m68k/idp/console/duart.c | 170 +++++++ c/src/lib/libbsp/m68k/idp/console/leds.c | 80 +++ c/src/lib/libbsp/m68k/idp/console/mc68ec.c | 18 + c/src/lib/libbsp/m68k/idp/include/README | 13 + c/src/lib/libbsp/m68k/idp/include/bsp.h | 79 +++ c/src/lib/libbsp/m68k/idp/include/coverhd.h | 106 ++++ c/src/lib/libbsp/m68k/idp/include/leds.h | 25 + c/src/lib/libbsp/m68k/idp/startup/bspstart.c | 175 +++++++ c/src/lib/libbsp/m68k/idp/startup/linkcmds | 44 ++ c/src/lib/libbsp/m68k/idp/timer/timer.c | 121 +++++ c/src/lib/libbsp/m68k/idp/timer/timerisr.s | 38 ++ c/src/lib/libbsp/m68k/mvme136/clock/ckinit.c | 111 +++++ c/src/lib/libbsp/m68k/mvme136/console/console.c | 159 ++++++ c/src/lib/libbsp/m68k/mvme136/include/bsp.h | 142 ++++++ c/src/lib/libbsp/m68k/mvme136/include/coverhd.h | 104 ++++ c/src/lib/libbsp/m68k/mvme136/shmsupp/addrconv.c | 32 ++ c/src/lib/libbsp/m68k/mvme136/shmsupp/getcfg.c | 85 ++++ c/src/lib/libbsp/m68k/mvme136/shmsupp/lock.c | 75 +++ c/src/lib/libbsp/m68k/mvme136/shmsupp/mpisr.c | 42 ++ c/src/lib/libbsp/m68k/mvme136/startup/bspclean.c | 46 ++ c/src/lib/libbsp/m68k/mvme136/startup/bspstart.c | 156 ++++++ c/src/lib/libbsp/m68k/mvme136/startup/linkcmds | 48 ++ c/src/lib/libbsp/m68k/mvme136/timer/timer.c | 108 ++++ c/src/lib/libbsp/m68k/mvme136/timer/timerisr.s | 39 ++ c/src/lib/libbsp/m68k/mvme162/README | 124 +++++ c/src/lib/libbsp/m68k/mvme162/clock/ckinit.c | 91 ++++ c/src/lib/libbsp/m68k/mvme162/console/console.c | 193 ++++++++ c/src/lib/libbsp/m68k/mvme162/include/bsp.h | 225 +++++++++ c/src/lib/libbsp/m68k/mvme162/include/coverhd.h | 104 ++++ c/src/lib/libbsp/m68k/mvme162/startup/bspclean.c | 53 ++ c/src/lib/libbsp/m68k/mvme162/startup/bspstart.c | 171 +++++++ c/src/lib/libbsp/m68k/mvme162/startup/linkcmds | 50 ++ c/src/lib/libbsp/m68k/mvme162/timer/timer.c | 91 ++++ c/src/lib/libbsp/m68k/mvme162/timer/timerisr.s | 46 ++ c/src/lib/libbsp/m68k/mvme162/tools/sload.c | 542 +++++++++++++++++++++ c/src/lib/libbsp/no_cpu/no_bsp/README | 69 +++ c/src/lib/libbsp/no_cpu/no_bsp/clock/ckinit.c | 143 ++++++ c/src/lib/libbsp/no_cpu/no_bsp/console/console.c | 158 ++++++ c/src/lib/libbsp/no_cpu/no_bsp/include/bsp.h | 85 ++++ c/src/lib/libbsp/no_cpu/no_bsp/include/coverhd.h | 115 +++++ c/src/lib/libbsp/no_cpu/no_bsp/shmsupp/addrconv.c | 31 ++ c/src/lib/libbsp/no_cpu/no_bsp/shmsupp/getcfg.c | 77 +++ c/src/lib/libbsp/no_cpu/no_bsp/shmsupp/lock.c | 86 ++++ c/src/lib/libbsp/no_cpu/no_bsp/shmsupp/mpisr.c | 47 ++ c/src/lib/libbsp/no_cpu/no_bsp/startup/bspclean.c | 26 + c/src/lib/libbsp/no_cpu/no_bsp/startup/bspstart.c | 164 +++++++ c/src/lib/libbsp/no_cpu/no_bsp/startup/linkcmds | 46 ++ c/src/lib/libbsp/no_cpu/no_bsp/startup/main.c | 33 ++ c/src/lib/libbsp/no_cpu/no_bsp/startup/setvec.c | 44 ++ c/src/lib/libbsp/no_cpu/no_bsp/timer/timer.c | 105 ++++ c/src/lib/libbsp/no_cpu/no_bsp/timer/timerisr.c | 37 ++ c/src/lib/libbsp/shmdr/README | 9 + c/src/lib/libbsp/shmdr/addlq.c | 43 ++ c/src/lib/libbsp/shmdr/cnvpkt.c | 42 ++ c/src/lib/libbsp/shmdr/dump.c | 50 ++ c/src/lib/libbsp/shmdr/fatal.c | 37 ++ c/src/lib/libbsp/shmdr/getlq.c | 46 ++ c/src/lib/libbsp/shmdr/getpkt.c | 36 ++ c/src/lib/libbsp/shmdr/init.c | 248 ++++++++++ c/src/lib/libbsp/shmdr/initlq.c | 35 ++ c/src/lib/libbsp/shmdr/intr.c | 58 +++ c/src/lib/libbsp/shmdr/mpci.h | 59 +++ c/src/lib/libbsp/shmdr/mpisr.c | 23 + c/src/lib/libbsp/shmdr/poll.c | 40 ++ c/src/lib/libbsp/shmdr/receive.c | 44 ++ c/src/lib/libbsp/shmdr/retpkt.c | 32 ++ c/src/lib/libbsp/shmdr/send.c | 61 +++ c/src/lib/libbsp/shmdr/setckvec.c | 28 ++ c/src/lib/libbsp/shmdr/shm.h | 542 +++++++++++++++++++++ c/src/lib/libbsp/shmdr/shm_driver.h | 542 +++++++++++++++++++++ c/src/lib/libc/README | 37 ++ c/src/lib/libc/__brk.c | 40 ++ c/src/lib/libc/__gettod.c | 84 ++++ c/src/lib/libc/__times.c | 65 +++ c/src/lib/libc/internal.h | 41 ++ c/src/lib/libc/libcsupport.h | 47 ++ c/src/lib/libc/malloc.c | 280 +++++++++++ c/src/lib/libc/newlibc.c | 292 +++++++++++ c/src/lib/libc/no_libc.c | 45 ++ c/src/lib/libc/support.c | 44 ++ c/src/lib/libc/syscalls.c | 77 +++ c/src/lib/libc/unixlibc.c | 7 + c/src/lib/libcpu/README | 14 + c/src/lib/libcpu/hppa1.1/clock/clock.c | 220 +++++++++ c/src/lib/libcpu/hppa1.1/runway/runway.h | 37 ++ c/src/lib/libcpu/hppa1.1/semaphore/semaphore.c | 308 ++++++++++++ c/src/lib/libcpu/hppa1.1/semaphore/semaphore.h | 84 ++++ c/src/lib/libcpu/hppa1.1/timer/timer.c | 62 +++ c/src/lib/libmisc/README | 16 + c/src/lib/libmisc/monitor/README | 7 + c/src/lib/libmisc/monitor/mon-monitor.c | 307 ++++++++++++ c/src/lib/libmisc/monitor/mon-symbols.c | 327 +++++++++++++ c/src/lib/libmisc/monitor/monitor.h | 38 ++ c/src/lib/libmisc/monitor/symbols.h | 80 +++ c/src/lib/libmisc/stackchk/README | 41 ++ c/src/lib/libmisc/stackchk/check.c | 439 +++++++++++++++++ c/src/lib/libmisc/stackchk/internal.h | 94 ++++ c/src/lib/libmisc/stackchk/stackchk.h | 41 ++ c/src/lib/start/README | 10 + c/src/lib/start/i960/start.s | 105 ++++ c/src/lib/start/m68k/start.s | 160 ++++++ 164 files changed, 16071 insertions(+) create mode 100644 c/src/lib/include/clockdrv.h create mode 100644 c/src/lib/include/console.h create mode 100644 c/src/lib/include/iosupp.h create mode 100644 c/src/lib/include/rtems/libcsupport.h create mode 100644 c/src/lib/include/spurious.h create mode 100644 c/src/lib/include/timerdrv.h create mode 100644 c/src/lib/include/vmeintr.h create mode 100644 c/src/lib/libbsp/README create mode 100644 c/src/lib/libbsp/hppa1.1/simhppa/include/bsp.h create mode 100644 c/src/lib/libbsp/hppa1.1/simhppa/include/coverhd.h create mode 100644 c/src/lib/libbsp/hppa1.1/simhppa/shmsupp/README create mode 100644 c/src/lib/libbsp/hppa1.1/simhppa/shmsupp/addrconv.c create mode 100644 c/src/lib/libbsp/hppa1.1/simhppa/shmsupp/getcfg.c create mode 100644 c/src/lib/libbsp/hppa1.1/simhppa/shmsupp/intr.c create mode 100644 c/src/lib/libbsp/hppa1.1/simhppa/shmsupp/lock.c create mode 100644 c/src/lib/libbsp/hppa1.1/simhppa/shmsupp/mpisr.c create mode 100644 c/src/lib/libbsp/hppa1.1/simhppa/startup/bspclean.c create mode 100644 c/src/lib/libbsp/hppa1.1/simhppa/startup/bspstart.c create mode 100644 c/src/lib/libbsp/hppa1.1/simhppa/startup/setvec.c create mode 100644 c/src/lib/libbsp/hppa1.1/simhppa/tools/print_dump.c create mode 100644 c/src/lib/libbsp/i386/force386/clock/ckinit.c create mode 100644 c/src/lib/libbsp/i386/force386/console/console.c create mode 100644 c/src/lib/libbsp/i386/force386/include/bsp.h create mode 100644 c/src/lib/libbsp/i386/force386/include/coverhd.h create mode 100644 c/src/lib/libbsp/i386/force386/shmsupp/addrconv.c create mode 100644 c/src/lib/libbsp/i386/force386/shmsupp/getcfg.c create mode 100644 c/src/lib/libbsp/i386/force386/shmsupp/lock.c create mode 100644 c/src/lib/libbsp/i386/force386/shmsupp/mpisr.c create mode 100644 c/src/lib/libbsp/i386/force386/startup/bspstart.c create mode 100644 c/src/lib/libbsp/i386/force386/startup/exit.c create mode 100644 c/src/lib/libbsp/i386/force386/startup/ldsegs.s create mode 100644 c/src/lib/libbsp/i386/force386/startup/linkcmds create mode 100644 c/src/lib/libbsp/i386/force386/startup/setvec.c create mode 100644 c/src/lib/libbsp/i386/force386/timer/timer.c create mode 100644 c/src/lib/libbsp/i386/force386/timer/timerisr.s create mode 100644 c/src/lib/libbsp/i960/cvme961/clock/ckinit.c create mode 100644 c/src/lib/libbsp/i960/cvme961/console/console.c create mode 100644 c/src/lib/libbsp/i960/cvme961/include/bsp.h create mode 100644 c/src/lib/libbsp/i960/cvme961/include/coverhd.h create mode 100644 c/src/lib/libbsp/i960/cvme961/shmsupp/addrconv.c create mode 100644 c/src/lib/libbsp/i960/cvme961/shmsupp/getcfg.c create mode 100644 c/src/lib/libbsp/i960/cvme961/shmsupp/lock.c create mode 100644 c/src/lib/libbsp/i960/cvme961/shmsupp/mpisr.c create mode 100644 c/src/lib/libbsp/i960/cvme961/startup/bspclean.c create mode 100644 c/src/lib/libbsp/i960/cvme961/startup/bspstart.c create mode 100644 c/src/lib/libbsp/i960/cvme961/startup/exit.c create mode 100644 c/src/lib/libbsp/i960/cvme961/startup/linkcmds create mode 100644 c/src/lib/libbsp/i960/cvme961/startup/setvec.c create mode 100644 c/src/lib/libbsp/i960/cvme961/timer/timer.c create mode 100644 c/src/lib/libbsp/i960/cvme961/timer/timerisr.s create mode 100644 c/src/lib/libbsp/m68k/dmv152/clock/ckinit.c create mode 100644 c/src/lib/libbsp/m68k/dmv152/console/console.c create mode 100644 c/src/lib/libbsp/m68k/dmv152/include/bsp.h create mode 100644 c/src/lib/libbsp/m68k/dmv152/include/coverhd.h create mode 100644 c/src/lib/libbsp/m68k/dmv152/spurious/spinit.c create mode 100644 c/src/lib/libbsp/m68k/dmv152/startup/bspstart.c create mode 100644 c/src/lib/libbsp/m68k/dmv152/startup/linkcmds create mode 100644 c/src/lib/libbsp/m68k/dmv152/startup/vmeintr.c create mode 100644 c/src/lib/libbsp/m68k/dmv152/timer/timer.c create mode 100644 c/src/lib/libbsp/m68k/dmv152/timer/timerisr.s create mode 100644 c/src/lib/libbsp/m68k/idp/README create mode 100644 c/src/lib/libbsp/m68k/idp/clock/ckinit.c create mode 100644 c/src/lib/libbsp/m68k/idp/console/console.c create mode 100644 c/src/lib/libbsp/m68k/idp/console/duart.c create mode 100644 c/src/lib/libbsp/m68k/idp/console/leds.c create mode 100644 c/src/lib/libbsp/m68k/idp/console/mc68ec.c create mode 100644 c/src/lib/libbsp/m68k/idp/include/README create mode 100644 c/src/lib/libbsp/m68k/idp/include/bsp.h create mode 100644 c/src/lib/libbsp/m68k/idp/include/coverhd.h create mode 100644 c/src/lib/libbsp/m68k/idp/include/leds.h create mode 100644 c/src/lib/libbsp/m68k/idp/startup/bspstart.c create mode 100644 c/src/lib/libbsp/m68k/idp/startup/linkcmds create mode 100644 c/src/lib/libbsp/m68k/idp/timer/timer.c create mode 100644 c/src/lib/libbsp/m68k/idp/timer/timerisr.s create mode 100644 c/src/lib/libbsp/m68k/mvme136/clock/ckinit.c create mode 100644 c/src/lib/libbsp/m68k/mvme136/console/console.c create mode 100644 c/src/lib/libbsp/m68k/mvme136/include/bsp.h create mode 100644 c/src/lib/libbsp/m68k/mvme136/include/coverhd.h create mode 100644 c/src/lib/libbsp/m68k/mvme136/shmsupp/addrconv.c create mode 100644 c/src/lib/libbsp/m68k/mvme136/shmsupp/getcfg.c create mode 100644 c/src/lib/libbsp/m68k/mvme136/shmsupp/lock.c create mode 100644 c/src/lib/libbsp/m68k/mvme136/shmsupp/mpisr.c create mode 100644 c/src/lib/libbsp/m68k/mvme136/startup/bspclean.c create mode 100644 c/src/lib/libbsp/m68k/mvme136/startup/bspstart.c create mode 100644 c/src/lib/libbsp/m68k/mvme136/startup/linkcmds create mode 100644 c/src/lib/libbsp/m68k/mvme136/timer/timer.c create mode 100644 c/src/lib/libbsp/m68k/mvme136/timer/timerisr.s create mode 100644 c/src/lib/libbsp/m68k/mvme162/README create mode 100644 c/src/lib/libbsp/m68k/mvme162/clock/ckinit.c create mode 100644 c/src/lib/libbsp/m68k/mvme162/console/console.c create mode 100644 c/src/lib/libbsp/m68k/mvme162/include/bsp.h create mode 100644 c/src/lib/libbsp/m68k/mvme162/include/coverhd.h create mode 100644 c/src/lib/libbsp/m68k/mvme162/startup/bspclean.c create mode 100644 c/src/lib/libbsp/m68k/mvme162/startup/bspstart.c create mode 100644 c/src/lib/libbsp/m68k/mvme162/startup/linkcmds create mode 100644 c/src/lib/libbsp/m68k/mvme162/timer/timer.c create mode 100644 c/src/lib/libbsp/m68k/mvme162/timer/timerisr.s create mode 100644 c/src/lib/libbsp/m68k/mvme162/tools/sload.c create mode 100644 c/src/lib/libbsp/no_cpu/no_bsp/README create mode 100644 c/src/lib/libbsp/no_cpu/no_bsp/clock/ckinit.c create mode 100644 c/src/lib/libbsp/no_cpu/no_bsp/console/console.c create mode 100644 c/src/lib/libbsp/no_cpu/no_bsp/include/bsp.h create mode 100644 c/src/lib/libbsp/no_cpu/no_bsp/include/coverhd.h create mode 100644 c/src/lib/libbsp/no_cpu/no_bsp/shmsupp/addrconv.c create mode 100644 c/src/lib/libbsp/no_cpu/no_bsp/shmsupp/getcfg.c create mode 100644 c/src/lib/libbsp/no_cpu/no_bsp/shmsupp/lock.c create mode 100644 c/src/lib/libbsp/no_cpu/no_bsp/shmsupp/mpisr.c create mode 100644 c/src/lib/libbsp/no_cpu/no_bsp/startup/bspclean.c create mode 100644 c/src/lib/libbsp/no_cpu/no_bsp/startup/bspstart.c create mode 100644 c/src/lib/libbsp/no_cpu/no_bsp/startup/linkcmds create mode 100644 c/src/lib/libbsp/no_cpu/no_bsp/startup/main.c create mode 100644 c/src/lib/libbsp/no_cpu/no_bsp/startup/setvec.c create mode 100644 c/src/lib/libbsp/no_cpu/no_bsp/timer/timer.c create mode 100644 c/src/lib/libbsp/no_cpu/no_bsp/timer/timerisr.c create mode 100644 c/src/lib/libbsp/shmdr/README create mode 100644 c/src/lib/libbsp/shmdr/addlq.c create mode 100644 c/src/lib/libbsp/shmdr/cnvpkt.c create mode 100644 c/src/lib/libbsp/shmdr/dump.c create mode 100644 c/src/lib/libbsp/shmdr/fatal.c create mode 100644 c/src/lib/libbsp/shmdr/getlq.c create mode 100644 c/src/lib/libbsp/shmdr/getpkt.c create mode 100644 c/src/lib/libbsp/shmdr/init.c create mode 100644 c/src/lib/libbsp/shmdr/initlq.c create mode 100644 c/src/lib/libbsp/shmdr/intr.c create mode 100644 c/src/lib/libbsp/shmdr/mpci.h create mode 100644 c/src/lib/libbsp/shmdr/mpisr.c create mode 100644 c/src/lib/libbsp/shmdr/poll.c create mode 100644 c/src/lib/libbsp/shmdr/receive.c create mode 100644 c/src/lib/libbsp/shmdr/retpkt.c create mode 100644 c/src/lib/libbsp/shmdr/send.c create mode 100644 c/src/lib/libbsp/shmdr/setckvec.c create mode 100644 c/src/lib/libbsp/shmdr/shm.h create mode 100644 c/src/lib/libbsp/shmdr/shm_driver.h create mode 100644 c/src/lib/libc/README create mode 100644 c/src/lib/libc/__brk.c create mode 100644 c/src/lib/libc/__gettod.c create mode 100644 c/src/lib/libc/__times.c create mode 100644 c/src/lib/libc/internal.h create mode 100644 c/src/lib/libc/libcsupport.h create mode 100644 c/src/lib/libc/malloc.c create mode 100644 c/src/lib/libc/newlibc.c create mode 100644 c/src/lib/libc/no_libc.c create mode 100644 c/src/lib/libc/support.c create mode 100644 c/src/lib/libc/syscalls.c create mode 100644 c/src/lib/libc/unixlibc.c create mode 100644 c/src/lib/libcpu/README create mode 100644 c/src/lib/libcpu/hppa1.1/clock/clock.c create mode 100644 c/src/lib/libcpu/hppa1.1/runway/runway.h create mode 100644 c/src/lib/libcpu/hppa1.1/semaphore/semaphore.c create mode 100644 c/src/lib/libcpu/hppa1.1/semaphore/semaphore.h create mode 100644 c/src/lib/libcpu/hppa1.1/timer/timer.c create mode 100644 c/src/lib/libmisc/README create mode 100644 c/src/lib/libmisc/monitor/README create mode 100644 c/src/lib/libmisc/monitor/mon-monitor.c create mode 100644 c/src/lib/libmisc/monitor/mon-symbols.c create mode 100644 c/src/lib/libmisc/monitor/monitor.h create mode 100644 c/src/lib/libmisc/monitor/symbols.h create mode 100644 c/src/lib/libmisc/stackchk/README create mode 100644 c/src/lib/libmisc/stackchk/check.c create mode 100644 c/src/lib/libmisc/stackchk/internal.h create mode 100644 c/src/lib/libmisc/stackchk/stackchk.h create mode 100644 c/src/lib/start/README create mode 100644 c/src/lib/start/i960/start.s create mode 100644 c/src/lib/start/m68k/start.s (limited to 'c/src/lib') diff --git a/c/src/lib/include/clockdrv.h b/c/src/lib/include/clockdrv.h new file mode 100644 index 0000000000..aad9bd6d3b --- /dev/null +++ b/c/src/lib/include/clockdrv.h @@ -0,0 +1,58 @@ +/* clock.h + * + * This file describes the Clock Driver for all boards. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __CLOCK_DRIVER_h +#define __CLOCK_DRIVER_h + +#ifdef __cplusplus +extern "C" { +#endif + +/* variables */ + +extern volatile rtems_unsigned32 Clock_driver_ticks; + +/* functions */ + +rtems_task Exit_task(); +void exit_task_init(); + +void Install_clock( rtems_isr_entry ); +void ReInstall_clock( rtems_isr_entry ); +void Clock_exit(); + +rtems_isr Clock_isr( + rtems_vector_number +); + +/* driver entries */ + +#define CLOCK_DRIVER_TABLE_ENTRY \ + { Clock_initialize, NULL, NULL, NULL, NULL, NULL } + +rtems_device_driver Clock_initialize( + rtems_device_major_number, + rtems_device_minor_number, + void *, + rtems_id, + rtems_unsigned32 * +); + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/c/src/lib/include/console.h b/c/src/lib/include/console.h new file mode 100644 index 0000000000..d102c6a1b1 --- /dev/null +++ b/c/src/lib/include/console.h @@ -0,0 +1,40 @@ +/* console.h + * + * This file describes the Console Device Driver for all boards. + * This driver provides support for the standard C Library. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef _CONSOLE_DRIVER_h +#define _CONSOLE_DRIVER_h + +#ifdef __cplusplus +extern "C" { +#endif + +#define CONSOLE_DRIVER_TABLE_ENTRY \ + { console_initialize, NULL, NULL, NULL, NULL, NULL } + +rtems_device_driver console_initialize( + rtems_device_major_number, + rtems_device_minor_number, + void *, + rtems_id, + rtems_unsigned32 * +); + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/c/src/lib/include/iosupp.h b/c/src/lib/include/iosupp.h new file mode 100644 index 0000000000..5f4a83b8ca --- /dev/null +++ b/c/src/lib/include/iosupp.h @@ -0,0 +1,44 @@ +/* iosupp.h + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __IOSUPP_h +#define __IOSUPP_h + +#ifdef __cplusplus +extern "C" { +#endif + +/* character constants */ + +#define BS 0x08 /* backspace */ +#define LF 0x0a /* line feed */ +#define CR 0x0d /* carriage return */ +#define XON 0x11 /* control-Q */ +#define XOFF 0x13 /* control-S */ + +/* structures */ + +#ifdef IOSUPP_INIT +#define IOSUPP_EXTERN +#else +#undef IOSUPP_EXTERN +#define IOSUPP_EXTERN extern +#endif + +/* functions */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/c/src/lib/include/rtems/libcsupport.h b/c/src/lib/include/rtems/libcsupport.h new file mode 100644 index 0000000000..2b199707f8 --- /dev/null +++ b/c/src/lib/include/rtems/libcsupport.h @@ -0,0 +1,47 @@ +/* libcsupport.h + * + * This include file contains the information regarding the + * RTEMS specific support for the standard C library. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __LIBC_SUPPORT_h +#define __LIBC_SUPPORT_h + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +void RTEMS_Malloc_Initialize( + void *start, + size_t length, + size_t sbrk_amount +); + +extern void libc_init(int reentrant); + +#ifdef __cplusplus +} +#endif + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/c/src/lib/include/spurious.h b/c/src/lib/include/spurious.h new file mode 100644 index 0000000000..428e826164 --- /dev/null +++ b/c/src/lib/include/spurious.h @@ -0,0 +1,38 @@ +/* spurious.h + * + * This file describes the Spurious Interrupt Driver for all boards. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993. + * On-Line Applications Research Corporation (OAR). + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __SPURIOUS_h +#define __SPURIOUS_h + +#ifdef __cplusplus +extern "C" { +#endif + +#define SPURIOUS_DRIVER_TABLE_ENTRY \ + { Spurious_Initialize, NULL, NULL, NULL, NULL, NULL } + +rtems_device_driver Spurious_Initialize( + rtems_device_major_number, + rtems_device_minor_number, + void *, + rtems_id, + rtems_unsigned32 * +); + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/c/src/lib/include/timerdrv.h b/c/src/lib/include/timerdrv.h new file mode 100644 index 0000000000..d091b62410 --- /dev/null +++ b/c/src/lib/include/timerdrv.h @@ -0,0 +1,40 @@ +/* timerdrv.h + * + * This file describes the Timer Driver for all boards. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __TIMER_DRIVER_h +#define __TIMER_DRIVER_h + +#ifdef __cplusplus +extern "C" { +#endif + +/* functions */ + +void Timer_initialize( void ); + +rtems_unsigned32 Read_timer( void ); + +rtems_status_code Empty_function( void ); + +void Set_find_average_overhead( + rtems_boolean find_flag +); + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/c/src/lib/include/vmeintr.h b/c/src/lib/include/vmeintr.h new file mode 100644 index 0000000000..6148114ce8 --- /dev/null +++ b/c/src/lib/include/vmeintr.h @@ -0,0 +1,58 @@ +/* + * vmeintr.h + * + * This file is the specification for the VMEbus interface library + * which should be provided by all BSPs for VMEbus Single Board + * Computers but currently only a few do so. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __VME_INTERRUPT_h +#define __VME_INTERRUPT_h + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * This defines the mask which is used to determine which + * interrupt levels are affected by a call to this package. + * The LSB corresponds to VME interrupt 0 and the MSB + * to VME interrupt 7. + * + */ + +typedef rtems_unsigned8 VME_interrupt_Mask; + +/* + * VME_interrupt_Disable + * + */ + +void VME_interrupt_Disable ( + VME_interrupt_Mask mask /* IN */ +); + +/* + * VME_interrupt_Disable + * + */ + +void VME_interrupt_Enable ( + VME_interrupt_Mask mask /* IN */ +); + +#ifdef __cplusplus +} +#endif + +#endif /* end of include file */ diff --git a/c/src/lib/libbsp/README b/c/src/lib/libbsp/README new file mode 100644 index 0000000000..c3b978b6cb --- /dev/null +++ b/c/src/lib/libbsp/README @@ -0,0 +1,46 @@ +# +# $Id$ +# + +Board Support Package library + +This directory contains the source for the libbsp.a library. +For each supported board $(RTEMS_BSP) there is a standard +set of functions which must be provided in the BSP: + + + start up initialization + + exit support + + set vector + + console IO support + + drivers + +In addition, the BSP also determines the memory usage by providing +any necessary linker scripts. + +There are also "generic" drivers in this directory. Currently +they are shmdr and stubdr. + +Some of the supplied generic drivers (for example, shared memory) require +target board specific support routines. + +NOTE: The library libbsp.a is actually built by $(RTEMS_BSP)/wrapup/Makefile. + +To execute all of the test in the RTEMS Tests Suites the following +device drivers must be supplied: + + + Clock Tick + + IO Driver Support + + Timer + + Shared Memory Driver Support + +The Timer Driver is used only by the Timing Test Suite (c/src/tests/tmtests/*). +These tests are used to generate the execution times for RTEMS found in the +flyers. It is recommended that these tests be run to verify a port to a new +CPU or with a newly developed BSP. Looking at the times as compared to a +known CPU and target can yield insights into potential performance problems +in either the port, the BSP, or the target hardware. + +The Shared Memory Support is only required to execute the Multiprocessor +Test Suite (c/src/tests/mptests/*). Multiprocessing is not a required part +of a BSP. + diff --git a/c/src/lib/libbsp/hppa1.1/simhppa/include/bsp.h b/c/src/lib/libbsp/hppa1.1/simhppa/include/bsp.h new file mode 100644 index 0000000000..c3759739b5 --- /dev/null +++ b/c/src/lib/libbsp/hppa1.1/simhppa/include/bsp.h @@ -0,0 +1,93 @@ +/* bsp.h + * + * This include file contains all HP PA-RISC simulator definitions. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __SIMHPPA_h +#define __SIMHPPA_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +/* + * Define the time limits for RTEMS Test Suite test durations. + * Long test and short test duration limits are provided. These + * values are in seconds and need to be converted to ticks for the + * application. + * + */ + +#define MAX_LONG_TEST_DURATION 3 /* 3 seconds */ +#define MAX_SHORT_TEST_DURATION 3 /* 3 seconds */ + +/* + * Define the interrupt mechanism for Time Test 27 + */ + +#define MUST_WAIT_FOR_INTERRUPT 1 + +#define Install_tm27_vector( handler ) \ + ( void ) set_vector( handler, HPPA_INTERRUPT_EXTERNAL_INTERVAL_TIMER, 1 ); + +#define Cause_tm27_intr() \ + set_itimer( get_itimer() + 20 ) + +#define Clear_tm27_intr() \ + set_eirr( 0x80000000 ) + +#define Lower_tm27_intr() \ + { \ + register unsigned32 ignored; \ + HPPA_ASM_SSM( HPPA_PSW_I, ignored ); \ + } + +/* + * Simple spin delay in microsecond units for device drivers. + * This is very dependent on the clock speed of the target. + */ + +extern void Clock_delay(rtems_unsigned32 microseconds); +#define delay( microseconds ) \ + Clock_delay(microseconds); + +/* + * We printf() to a buffer if multiprocessing, *or* if this is set. + * ref: src/lib/libbsp/hppa/simhppa/iosupp/consupp.c + */ + +extern int use_print_buffer; + +#define HPPA_INTERRUPT_EXTERNAL_MPCI HPPA_INTERRUPT_EXTERNAL_10 + +void bsp_start( void ); +void bsp_cleanup( void ); + +/* miscellaneous stuff assumed to exist */ + +extern rtems_configuration_table BSP_Configuration; /* owned by BSP */ +extern rtems_cpu_table Cpu_table; /* owned by BSP */ + +extern rtems_unsigned32 bsp_isr_level; + +extern int cpu_number; /* from 0; cpu number in a multi cpu system */ + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/c/src/lib/libbsp/hppa1.1/simhppa/include/coverhd.h b/c/src/lib/libbsp/hppa1.1/simhppa/include/coverhd.h new file mode 100644 index 0000000000..1f5e3a3d5a --- /dev/null +++ b/c/src/lib/libbsp/hppa1.1/simhppa/include/coverhd.h @@ -0,0 +1,104 @@ +/* coverhd.h + * + * This include file has defines to represent the overhead associated + * with calling a particular directive from C for this target. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __COVERHD_h +#define __COVERHD_h + +#ifdef __cplusplus +extern "C" { +#endif + +#define CALLING_OVERHEAD_INITIALIZE_EXECUTIVE 0 +#define CALLING_OVERHEAD_SHUTDOWN_EXECUTIVE 0 +#define CALLING_OVERHEAD_TASK_CREATE 0 +#define CALLING_OVERHEAD_TASK_IDENT 0 +#define CALLING_OVERHEAD_TASK_START 0 +#define CALLING_OVERHEAD_TASK_RESTART 0 +#define CALLING_OVERHEAD_TASK_DELETE 0 +#define CALLING_OVERHEAD_TASK_SUSPEND 0 +#define CALLING_OVERHEAD_TASK_RESUME 0 +#define CALLING_OVERHEAD_TASK_SET_PRIORITY 0 +#define CALLING_OVERHEAD_TASK_MODE 0 +#define CALLING_OVERHEAD_TASK_GET_NOTE 0 +#define CALLING_OVERHEAD_TASK_SET_NOTE 0 +#define CALLING_OVERHEAD_TASK_WAKE_WHEN 0 +#define CALLING_OVERHEAD_TASK_WAKE_AFTER 0 +#define CALLING_OVERHEAD_INTERRUPT_CATCH 0 +#define CALLING_OVERHEAD_CLOCK_GET 0 +#define CALLING_OVERHEAD_CLOCK_SET 0 +#define CALLING_OVERHEAD_CLOCK_TICK 0 + +#define CALLING_OVERHEAD_TIMER_CREATE 0 +#define CALLING_OVERHEAD_TIMER_IDENT 0 +#define CALLING_OVERHEAD_TIMER_DELETE 0 +#define CALLING_OVERHEAD_TIMER_FIRE_AFTER 0 +#define CALLING_OVERHEAD_TIMER_FIRE_WHEN 0 +#define CALLING_OVERHEAD_TIMER_RESET 0 +#define CALLING_OVERHEAD_TIMER_CANCEL 0 +#define CALLING_OVERHEAD_SEMAPHORE_CREATE 0 +#define CALLING_OVERHEAD_SEMAPHORE_IDENT 0 +#define CALLING_OVERHEAD_SEMAPHORE_DELETE 0 +#define CALLING_OVERHEAD_SEMAPHORE_OBTAIN 0 +#define CALLING_OVERHEAD_SEMAPHORE_RELEASE 0 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_CREATE 0 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_IDENT 0 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_DELETE 0 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_SEND 0 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_URGENT 0 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_BROADCAST 0 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_RECEIVE 0 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_FLUSH 0 + +#define CALLING_OVERHEAD_EVENT_SEND 0 +#define CALLING_OVERHEAD_EVENT_RECEIVE 0 +#define CALLING_OVERHEAD_SIGNAL_CATCH 0 +#define CALLING_OVERHEAD_SIGNAL_SEND 0 +#define CALLING_OVERHEAD_PARTITION_CREATE 0 +#define CALLING_OVERHEAD_PARTITION_IDENT 0 +#define CALLING_OVERHEAD_PARTITION_DELETE 0 +#define CALLING_OVERHEAD_PARTITION_GET_BUFFER 0 +#define CALLING_OVERHEAD_PARTITION_RETURN_BUFFER 0 +#define CALLING_OVERHEAD_REGION_CREATE 0 +#define CALLING_OVERHEAD_REGION_IDENT 0 +#define CALLING_OVERHEAD_REGION_DELETE 0 +#define CALLING_OVERHEAD_REGION_GET_SEGMENT 0 +#define CALLING_OVERHEAD_REGION_RETURN_SEGMENT 0 +#define CALLING_OVERHEAD_PORT_CREATE 0 +#define CALLING_OVERHEAD_PORT_IDENT 0 +#define CALLING_OVERHEAD_PORT_DELETE 0 +#define CALLING_OVERHEAD_PORT_EXTERNAL_TO_INTERNAL 0 +#define CALLING_OVERHEAD_PORT_INTERNAL_TO_EXTERNAL 0 + +#define CALLING_OVERHEAD_IO_INITIALIZE 0 +#define CALLING_OVERHEAD_IO_OPEN 0 +#define CALLING_OVERHEAD_IO_CLOSE 0 +#define CALLING_OVERHEAD_IO_READ 0 +#define CALLING_OVERHEAD_IO_WRITE 0 +#define CALLING_OVERHEAD_IO_CONTROL 0 +#define CALLING_OVERHEAD_FATAL_ERROR_OCCURRED 0 +#define CALLING_OVERHEAD_RATE_MONOTONIC_CREATE 0 +#define CALLING_OVERHEAD_RATE_MONOTONIC_IDENT 0 +#define CALLING_OVERHEAD_RATE_MONOTONIC_DELETE 0 +#define CALLING_OVERHEAD_RATE_MONOTONIC_CANCEL 0 +#define CALLING_OVERHEAD_RATE_MONOTONIC_PERIOD 0 +#define CALLING_OVERHEAD_MULTIPROCESSING_ANNOUNCE 0 + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/c/src/lib/libbsp/hppa1.1/simhppa/shmsupp/README b/c/src/lib/libbsp/hppa1.1/simhppa/shmsupp/README new file mode 100644 index 0000000000..cf60698ca4 --- /dev/null +++ b/c/src/lib/libbsp/hppa1.1/simhppa/shmsupp/README @@ -0,0 +1,9 @@ +# +# $Id$ +# + +This directory contains the SHM driver support files for the +HP PA-RISC simulator for the 72000 processor. + +WARNING: The interrupt support in this directory currently will + only work in a homogeneous system. diff --git a/c/src/lib/libbsp/hppa1.1/simhppa/shmsupp/addrconv.c b/c/src/lib/libbsp/hppa1.1/simhppa/shmsupp/addrconv.c new file mode 100644 index 0000000000..0d67bba2a6 --- /dev/null +++ b/c/src/lib/libbsp/hppa1.1/simhppa/shmsupp/addrconv.c @@ -0,0 +1,30 @@ +/* Shm_Convert_address + * + * No address range conversion is required. + * + * Input parameters: + * address - address to convert + * + * Output parameters: + * returns - converted address + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include + +void *Shm_Convert_address( + void *address +) +{ + return ( address ); +} diff --git a/c/src/lib/libbsp/hppa1.1/simhppa/shmsupp/getcfg.c b/c/src/lib/libbsp/hppa1.1/simhppa/shmsupp/getcfg.c new file mode 100644 index 0000000000..e21e62f55d --- /dev/null +++ b/c/src/lib/libbsp/hppa1.1/simhppa/shmsupp/getcfg.c @@ -0,0 +1,84 @@ +/* void Shm_Get_configuration( localnode, &shmcfg ) + * + * This routine initializes, if necessary, and returns a pointer + * to the Shared Memory Configuration Table for the HP PA-RISC + * simulator. + * + * INPUT PARAMETERS: + * localnode - local node number + * shmcfg - address of pointer to SHM Config Table + * + * OUTPUT PARAMETERS: + * *shmcfg - pointer to SHM Config Table + * + * NOTES: The MP interrupt used is the Runway bus' ability to directly + * address the control registers of up to four CPUs and cause + * interrupts on them. + * + * The following table illustrates the configuration limitations: + * + * BUS MAX + * MODE ENDIAN NODES + * ========= ====== ======= + * POLLED BIG 2+ + * INTERRUPT BIG 2..4 (on Runway) + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include + +#include "shm.h" + +#define INTERRUPT 0 /* can be interrupt or polling */ +#define POLLING 1 + +shm_config_table BSP_shm_cfgtbl; + +void Shm_Cause_interrupt_simhppa( + rtems_unsigned32 node +); + +void Shm_Get_configuration( + rtems_unsigned32 localnode, + shm_config_table **shmcfg +) +{ + BSP_shm_cfgtbl.base = (vol_u32 *) 0x44000000; + BSP_shm_cfgtbl.length = 16 * KILOBYTE; + BSP_shm_cfgtbl.format = SHM_BIG; + + BSP_shm_cfgtbl.cause_intr = Shm_Cause_interrupt_simhppa; + +#ifdef NEUTRAL_BIG + BSP_shm_cfgtbl.convert = NULL_CONVERT; +#else + BSP_shm_cfgtbl.convert = CPU_swap_u32; +#endif + +#if ( POLLING == 1 ) + BSP_shm_cfgtbl.poll_intr = POLLED_MODE; + BSP_shm_cfgtbl.Intr.address = NO_INTERRUPT; + BSP_shm_cfgtbl.Intr.value = NO_INTERRUPT; + BSP_shm_cfgtbl.Intr.length = NO_INTERRUPT; +#else + BSP_shm_cfgtbl.poll_intr = INTR_MODE; + BSP_shm_cfgtbl.Intr.address = + (vol_u32 *) (HPPA_RUNWAY_HPA( localnode - 1) + + HPPA_RUNWAY_REG_IO_EIR_OFFSET); + BSP_shm_cfgtbl.Intr.value = HPPA_INTERRUPT_EXTERNAL_MPCI; + BSP_shm_cfgtbl.Intr.length = LONG; +#endif + + *shmcfg = &BSP_shm_cfgtbl; +} + diff --git a/c/src/lib/libbsp/hppa1.1/simhppa/shmsupp/intr.c b/c/src/lib/libbsp/hppa1.1/simhppa/shmsupp/intr.c new file mode 100644 index 0000000000..6af0c6ace6 --- /dev/null +++ b/c/src/lib/libbsp/hppa1.1/simhppa/shmsupp/intr.c @@ -0,0 +1,64 @@ +/* void Shm_Cause_interrupt_simhppa( node ) + * + * This routine is the shared memory driver routine which + * generates interrupts to other CPUs. + * + * Input parameters: + * node - destination of this packet (0 = broadcast) + * + * Output parameters: NONE + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include "stdio.h" + +#include +#include "shm.h" + +void Shm_Cause_interrupt_simhppa( + rtems_unsigned32 node +) +{ + Shm_Interrupt_information *intr; + rtems_unsigned8 *u8; + rtems_unsigned16 *u16; + rtems_unsigned32 *u32; + rtems_unsigned32 value; + + intr = &Shm_Interrupt_table[node]; + value = intr->value; + + switch ( intr->length ) { + case NO_INTERRUPT: + break; + case BYTE: + u8 = (rtems_unsigned8 *)intr->address; + fprintf( + stderr, + "Shm_Cause_interrupt_simhppa: Writes of unsigned8 not supported!!!\n" + ); + rtems_shutdown_executive( 0 ); + break; + case WORD: + u16 = (rtems_unsigned16 *)intr->address; + fprintf( + stderr, + "Shm_Cause_interrupt_simhppa: Writes of unsigned8 not supported!!!\n" + ); + rtems_shutdown_executive( 0 ); + break; + case LONG: + u32 = (rtems_unsigned32 *)intr->address; + HPPA_ASM_STWAS( value, 0, u32 ); + break; + } +} diff --git a/c/src/lib/libbsp/hppa1.1/simhppa/shmsupp/lock.c b/c/src/lib/libbsp/hppa1.1/simhppa/shmsupp/lock.c new file mode 100644 index 0000000000..724758b8b8 --- /dev/null +++ b/c/src/lib/libbsp/hppa1.1/simhppa/shmsupp/lock.c @@ -0,0 +1,75 @@ +/* Shared Memory Lock Routines + * + * This shared memory locked queue support routine need to be + * able to lock the specified locked queue. Interrupts are + * disabled while the queue is locked to prevent preemption + * and deadlock when two tasks poll for the same lock. + * previous level. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include + +/* + * Shm_Initialize_lock + * + * Initialize the lock for the specified locked queue. + */ + +void Shm_Initialize_lock( + Shm_Locked_queue_Control *lq_cb +) +{ + lq_cb->lock = LQ_UNLOCKED; +} + +/* Shm_Lock( &lq_cb ) + * + * This shared memory locked queue support routine locks the + * specified locked queue. It disables interrupts to prevent + * a deadlock condition. + */ + +void Shm_Lock( + Shm_Locked_queue_Control *lq_cb +) +{ + rtems_unsigned32 isr_level; + vol_u32 *lockptr = &lq_cb->lock; + rtems_unsigned32 lock_value; + + rtems_interrupt_disable( isr_level ); + + Shm_isrstat = isr_level; + + do { + HPPA_ASM_LDCWS( 0, 0, lockptr, lock_value ); + } while (lock_value == SHM_LOCK_VALUE); +} + +/* + * Shm_Unlock + * + * Unlock the lock for the specified locked queue. + */ + +void Shm_Unlock( + Shm_Locked_queue_Control *lq_cb +) +{ + rtems_unsigned32 isr_level; + + lq_cb->lock = SHM_UNLOCK_VALUE; + isr_level = Shm_isrstat; + rtems_interrupt_enable( isr_level ); +} diff --git a/c/src/lib/libbsp/hppa1.1/simhppa/shmsupp/mpisr.c b/c/src/lib/libbsp/hppa1.1/simhppa/shmsupp/mpisr.c new file mode 100644 index 0000000000..29e897d781 --- /dev/null +++ b/c/src/lib/libbsp/hppa1.1/simhppa/shmsupp/mpisr.c @@ -0,0 +1,27 @@ +/* Shm_setvec + * + * This driver routine sets the SHM interrupt vector to point to the + * driver's SHM interrupt service routine. + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include + +void Shm_setvec( void ) +{ + set_vector( Shm_isr, HPPA_INTERRUPT_EXTERNAL_MPCI, 1 ); +} diff --git a/c/src/lib/libbsp/hppa1.1/simhppa/startup/bspclean.c b/c/src/lib/libbsp/hppa1.1/simhppa/startup/bspclean.c new file mode 100644 index 0000000000..fe2aa75fc4 --- /dev/null +++ b/c/src/lib/libbsp/hppa1.1/simhppa/startup/bspclean.c @@ -0,0 +1,36 @@ +/* bsp_cleanup() + * + * This routine normally is part of start.s and returns + * control to a monitor but on the HP PA-RISC simulator + * we do that directly from main.c. + * + * INPUT: NONE + * + * OUTPUT: NONE + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include + +/* + * The app has "exited" (called rtems_shutdown_executive) + */ + +void bsp_cleanup( void ) +{ + /* + * Invoke any fatal error extension and "halt" + * By definition, rtems_fatal_error_occurred does not return. + */ + + rtems_fatal_error_occurred(0); +} diff --git a/c/src/lib/libbsp/hppa1.1/simhppa/startup/bspstart.c b/c/src/lib/libbsp/hppa1.1/simhppa/startup/bspstart.c new file mode 100644 index 0000000000..765e60c62c --- /dev/null +++ b/c/src/lib/libbsp/hppa1.1/simhppa/startup/bspstart.c @@ -0,0 +1,387 @@ +/* + * @(#)bspstart.c 1.13 - 95/04/25 + * + */ + +/* bsp_start() + * + * This routine starts the application. It includes application, + * board, and monitor specific initialization and configuration. + * The generic CPU dependent initialization has been performed + * before this routine is invoked. + * + * Called by RTEMS::RTEMS constructor in startup-ctor.cc + * + * INPUT: NONE + * + * OUTPUT: NONE + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include + +#include + +#ifdef STACK_CHECKER_ON +#include +#endif + +extern rtems_configuration_table Configuration; + +rtems_configuration_table BSP_Configuration; +rtems_cpu_table Cpu_table; +rtems_unsigned32 bsp_isr_level; + +#define WORKSPACE_SIZE (1024 * 1024) +rtems_unsigned8 MY_WORK_SPACE[ WORKSPACE_SIZE ]; + +/* + * Amount to increment itimer by each pass + * It is a variable instead of a #define to allow the 'looptest' + * script to bump it without recompiling rtems + */ + +rtems_unsigned32 CPU_HPPA_CLICKS_PER_TICK; + +#if SIMHPPA_FAST_IDLE + +/* + * Many of the tests are very slow on the simulator because they have + * have 5 second delays hardwired in. + * Try to speed those tests up by speeding up the clock when in idle + */ + +rtems_extension +fast_idle_switch_hook(rtems_tcb *current_task, + rtems_tcb *heir_task) +{ + static rtems_unsigned32 normal_clock = ~0; + static rtems_unsigned32 fast_clock; + + /* init our params on first call */ + if (normal_clock == ~0) + { + normal_clock = CPU_HPPA_CLICKS_PER_TICK; + fast_clock = CPU_HPPA_CLICKS_PER_TICK / 0x100; + if (fast_clock == 0) /* who? me? pathological? never! */ + fast_clock++; + } + + /* + * Checking for 'name' field of 'IDLE' is not the best/safest, + * but its the best we could think of at the moment. + */ + + if (heir_task->name == rtems_build_name('I', 'D', 'L', 'E')) + CPU_HPPA_CLICKS_PER_TICK = fast_clock; + else if (current_task->name == rtems_build_name('I', 'D', 'L', 'E')) + CPU_HPPA_CLICKS_PER_TICK = normal_clock; +} + +#endif + +/* + * Function: bsp_libc_init + * Created: 94/12/6 + * + * Description: + * Initialize whatever libc we are using + * called from bsp_postdriver_hook + * + * + * Parameters: + * none + * + * Returns: + * none. + * + * Side Effects: + * + * + * Notes: + * + * Deficiencies/ToDo: + * + * + */ + +void +bsp_libc_init(void) +{ + extern int end; + rtems_unsigned32 heap_start; + + heap_start = (rtems_unsigned32) &end; + if (heap_start & (CPU_ALIGNMENT-1)) + heap_start = (heap_start + CPU_ALIGNMENT) & ~(CPU_ALIGNMENT-1); + + RTEMS_Malloc_Initialize((void *) heap_start, 64 * 1024, 0); + + /* + * Set up for the libc handling. + */ + + if (BSP_Configuration.ticks_per_timeslice > 0) + libc_init(1); /* reentrant if possible */ + else + libc_init(0); /* non-reentrant */ + + /* + * on MP systems, always use the print buffer + * instead of the (broken) system calls + */ + + if (BSP_Configuration.User_multiprocessing_table) + use_print_buffer = 1; + +#ifdef SIMHPPA_ROM + use_print_buffer = 1; +#endif +} + + +/* + * Function: bsp_pretasking_hook + * Created: 95/03/10 + * + * Description: + * BSP pretasking hook. Called just before drivers are initialized. + * Used to setup libc and install any BSP extensions. + * + * Parameters: + * none + * + * Returns: + * nada + * + * Side Effects: + * installs a few extensions + * + * Notes: + * Must not use libc (to do io) from here, since drivers are + * not yet initialized. + * + * Deficiencies/ToDo: + * + * + */ + +void +bsp_pretasking_hook(void) +{ + bsp_libc_init(); + +#if SIMHPPA_FAST_IDLE + /* + * Install the fast idle task switch extension + * + * on MP systems, might now want to do this; it confuses at least + * one test (mp06) + */ + +#if 0 + if (BSP_Configuration.User_multiprocessing_table == 0) +#endif + { + rtems_extensions_table fast_idle_extension; + rtems_id extension_id; + rtems_status_code rc; + + memset(&fast_idle_extension, 0, sizeof(fast_idle_extension)); + + fast_idle_extension.task_switch = fast_idle_switch_hook; + + rc = rtems_extension_create(rtems_build_name('F', 'D', 'L', 'E'), + &fast_idle_extension, &extension_id); + if (rc != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred(rc); + } +#endif + + +#ifdef STACK_CHECKER_ON + /* + * Initialize the stack bounds checker + * We can either turn it on here or from the app. + */ + + Stack_check_Initialize(); +#endif +} + +/* + * Function: bsp_start + * Created: 94/12/6 + * + * Description: + * called by crt0 as our "main" equivalent + * + * + * + * Parameters: + * + * + * Returns: + * + * + * Side Effects: + * + * + * Notes: + * + * + * Deficiencies/ToDo: + * + * + */ + + +void +bsp_start(void) +{ + /* + * Set cpu_number to accurately reflect our cpu number + */ + +#ifdef hppa7200 + /* + * Use DR0 if supported + */ + { + int dr0; + HPPA_ASM_MFCPU(DR0, dr0); + cpu_number = (dr0 >> 4) & 0x7; + } +#else + if (Configuration.User_multiprocessing_table) + cpu_number = Configuration.User_multiprocessing_table->node - 1; + else + cpu_number = 0; +#endif + + /* + * Copy the table + */ + + BSP_Configuration = Configuration; + + BSP_Configuration.work_space_start = (void *)MY_WORK_SPACE; + if (BSP_Configuration.work_space_size) + BSP_Configuration.work_space_size = WORKSPACE_SIZE; + + /* + * Set up our hooks + * Make sure libc_init is done before drivers init'd so that + * they can use atexit() + */ + + Cpu_table.pretasking_hook = bsp_pretasking_hook; /* init libc, etc. */ + + Cpu_table.predriver_hook = NULL; + + Cpu_table.postdriver_hook = NULL; + + Cpu_table.idle_task = NULL; /* do not override system IDLE task */ + + /* + * Don't zero out the workspace. The simulator did it for us. + */ + + Cpu_table.do_zero_of_workspace = FALSE; + + Cpu_table.interrupt_stack_size = (12 * 1024); + + Cpu_table.extra_system_initialization_stack = 0; + + /* + * Set this artificially low for the simulator + */ + + Cpu_table.itimer_clicks_per_microsecond = 1; + + /* + * Determine the external interrupt processing order + * the external interrupt handler walks thru this table, in + * order checking for posted interrupts. + */ + + Cpu_table.external_interrupts = 0; + + Cpu_table.external_interrupt[ Cpu_table.external_interrupts ] = + HPPA_INTERRUPT_EXTERNAL_INTERVAL_TIMER - HPPA_INTERRUPT_EXTERNAL_BASE; + Cpu_table.external_interrupts++; + + if ( Configuration.User_multiprocessing_table ) { + Cpu_table.external_interrupt[ Cpu_table.external_interrupts ] = + HPPA_INTERRUPT_EXTERNAL_10 - HPPA_INTERRUPT_EXTERNAL_BASE; + Cpu_table.external_interrupts++; + } + + /* + * Add 1 region for RTEMS Malloc + */ + + BSP_Configuration.maximum_regions++; + +#ifdef RTEMS_NEWLIB + /* + * Add 1 extension for newlib libc + */ + + BSP_Configuration.maximum_extensions++; +#endif + +#ifdef STACK_CHECKER_ON + /* + * Add 1 extension for stack checker + */ + + BSP_Configuration.maximum_extensions++; +#endif + +#if SIMHPPA_FAST_IDLE + /* + * Add 1 extension for fast idle + */ + + BSP_Configuration.maximum_extensions++; +#endif + + /* + * Add 1 extension for MPCI_fatal + */ + + if (BSP_Configuration.User_multiprocessing_table) + BSP_Configuration.maximum_extensions++; + + /* + * Set the "clicks per tick" for the simulator + * used by libcpu/hppa/clock/clock.c to schedule interrupts + * + * Set it only if 0 to allow for simulator setting it via script + * on test startup. + */ + + if (CPU_HPPA_CLICKS_PER_TICK == 0) + CPU_HPPA_CLICKS_PER_TICK = 0x4000; + + /* + * Start most of RTEMS + * main() will start the rest + */ + + bsp_isr_level = rtems_initialize_executive_early( + &BSP_Configuration, + &Cpu_table + ); +} diff --git a/c/src/lib/libbsp/hppa1.1/simhppa/startup/setvec.c b/c/src/lib/libbsp/hppa1.1/simhppa/startup/setvec.c new file mode 100644 index 0000000000..4597e8f088 --- /dev/null +++ b/c/src/lib/libbsp/hppa1.1/simhppa/startup/setvec.c @@ -0,0 +1,66 @@ +/* set_vector + * + * This routine installs an interrupt vector on the HP PA-RISC simulator. + * + * INPUT: + * handler - interrupt handler entry point + * vector - vector number + * type - 0 indicates raw hardware connect + * 1 indicates RTEMS interrupt connect + * + * NOTE 'type' is ignored on hppa; all interrupts are owned by RTEMS + * + * RETURNS: + * address of previous interrupt handler + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include + +/* + * Install an interrupt handler in the right place + * given its vector number from cpu/hppa.h + * There are 2 places an interrupt can be installed + * _ISR_Vector_table + * bsp interrupt XXX: nyi + * + * We decide which based on the vector number + */ + +rtems_isr_entry +set_vector( /* returns old vector */ + rtems_isr_entry handler, /* isr routine */ + rtems_vector_number vector, /* vector number */ + int type /* RTEMS or RAW intr */ +) +{ + rtems_isr_entry previous_isr; + + /* is it an on chip interrupt? */ + /* XXX this should say CPU_INTERRUPT_NUMBER_OF_VECTORS */ + if (vector < HPPA_INTERRUPT_MAX) + { + rtems_interrupt_catch(handler, vector, &previous_isr); + } +#if 0 /* XXX */ + else if ((vector >= HPPA_INTERRUPT_BSP_BASE) && + (vector < (HPPA_INTERRUPT_BSP_BASE + HPPA_BSP_INTERRUPTS))) + { + simhppa_interrupt_install(handler, + vector - HPPA_INTERRUPT_BSP_BASE, + (rtems_isr_entry *) &previous_isr); + } +#endif + + return previous_isr; +} + diff --git a/c/src/lib/libbsp/hppa1.1/simhppa/tools/print_dump.c b/c/src/lib/libbsp/hppa1.1/simhppa/tools/print_dump.c new file mode 100644 index 0000000000..8b4313166a --- /dev/null +++ b/c/src/lib/libbsp/hppa1.1/simhppa/tools/print_dump.c @@ -0,0 +1,332 @@ +/* + * print_dump + * + * $Id$ + * + * COPYRIGHT (c) 1994 by Division Incorporated + * + * To anyone who acknowledges that this file is provided "AS IS" + * without any express or implied warranty: + * permission to use, copy, modify, and distribute this file + * for any purpose is hereby granted without fee, provided that + * the above copyright notice and this notice appears in all + * copies, and that the name of Division Incorporated not be + * used in advertising or publicity pertaining to distribution + * of the software without specific, written prior permission. + * Division Incorporated makes no representations about the + * suitability of this software for any purpose. + */ + +#define GETOPTARGS "v" + +char *USAGE = "\ +usage: print_dump [ -v ] \n\ + -v -- verbose\n\ + Reads HP simulator 'memdump' output of 'print_buffer' structure + on stdin. Dumps it out in vanilla ASCII. +"; + +#include +#include +#include +#include +#include +#include +#include +#include + +#define Failed(x) (((int) (x)) == -1) +#define TRUE 1 +#define FALSE 0 +#define STREQ(a,b) (strcmp(a,b) == 0) +#define NUMELEMS(arr) (sizeof(arr) / sizeof(arr[0])) + +/* + * Definitions for unsigned "ints"; especially for use in data structures + * that will be shared among (potentially) different cpu's (we punt on + * byte ordering problems tho) + */ + +typedef unsigned char u8; +typedef unsigned short u16; +typedef unsigned int u32; + +typedef union uval { + u8 uv_chars[4]; + u16 uv_words[2]; + u32 uv_long; + void *uv_ptr[sizeof(long) / sizeof(void *)]; +} uval_t; + + +/* + * vars controlled by command line options + */ + +int verbose = FALSE; /* be verbose */ + +extern char *optarg; /* getopt(3) control vars */ +extern int optind, opterr; +extern int errno; + +char *progname; /* for error() */ + +void error(int errn, ...); + +#define ERR_ERRNO (1<<((sizeof(int) * 8) - 2)) /* hi bit; use 'errno' */ +#define ERR_FATAL (ERR_ERRNO / 2) /* error is fatal; no return */ +#define ERR_ABORT (ERR_ERRNO / 4) /* error is fatal; abort */ +#define ERR_MASK (ERR_ERRNO | ERR_FATAL | ERR_ABORT) /* all */ + +int process(void); +void prchar(unsigned int ch); + + +int +main(int argc, char **argv, char **env) +{ + register int c; + int showusage = FALSE; /* usage error? */ + + /* + * figure out invocation leaf-name + */ + + if ((progname = strrchr(argv[0], '/')) == (char *) NULL) + progname = argv[0]; + else + progname++; + + argv[0] = progname; /* for getopt err reporting */ + + /* + * Check options and arguments. + */ + + opterr = 0; /* we'll report all errors */ + while ((c = getopt(argc, argv, GETOPTARGS)) != EOF) + switch (c) + { + case 'v': /* toggle verbose */ + verbose = ! verbose; + break; + + case '?': + showusage = TRUE; + } + + if (showusage) + { + (void) fprintf(stderr, "%s", USAGE); + exit(1); + } + + return process(); +} + + +/* + * process(arg) + * + * Input looks like this + * + * Starting address: 00000001.480035a0 + * ----------------------------------- + ++0000 / 0d0a0d0a 2a2a2a20 53454d20 54455354 202d2d20 4e4f4445 2032202a 2a2a0d0a ++0020 / 73703a20 30783433 30303030 31300d0a 30783438 30613161 38383a20 676f7420 + .... ++0b40 / xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx + + * + * The 'xxxxxxxxx' shows up if the page has not been allocated. + */ + +int +process(void) +{ + uval_t b[8]; + u32 ignore; + char *p; + int i; + int failed_once; + + char line[1024]; + +#define PRINT_BUFFER_SIZE (16 * 1024) + struct { + int index; + int size; + u8 buffer[PRINT_BUFFER_SIZE]; + } print_buffer; + + /* we stuff the data into print_buffer using memcpy() */ + p = (char *) &print_buffer; + + failed_once = 0; + + while (gets(line)) + { + char *cp; + + /* hack; deal with the 'xxxxxxxx' problem noted above */ + for (cp=line; *cp; cp++) + if (*cp == 'x') + *cp = '0'; + + if (*line != '+') + continue; + if (sscanf(line, "+%x / %x %x %x %x %x %x %x %x\n", + &ignore, + &b[0].uv_long, + &b[1].uv_long, + &b[2].uv_long, + &b[3].uv_long, + &b[4].uv_long, + &b[5].uv_long, + &b[6].uv_long, + &b[7].uv_long) != 9) + { + if (failed_once) + error(ERR_FATAL, "2nd format problem; giving up"); + error(0, "format problem in line: `%s`", line); + failed_once = 1; + } + + memcpy((void *) p, (void *) b, sizeof(b)); + p += sizeof(b); + } + + if (verbose) + printf("buffer size: %d\n", print_buffer.size); + + if (print_buffer.size < 0) + error(ERR_FATAL, "size is too small"); + + if (print_buffer.size != sizeof(print_buffer.buffer)) + { + error(ERR_FATAL, "buffer size mismatch, expected %d", + sizeof(print_buffer.buffer)); + /* XXX we really should just dynamically allocate the buffer */ + } + + i = print_buffer.index + 1; + while (i != print_buffer.index) + { + unsigned int c; + c = print_buffer.buffer[i++]; + if (c && (c != '\r')) + prchar(c); + i %= print_buffer.size; + } + printf("\n"); + return 0; +} + +/* de-controlify */ +char *de_control[] = { + "^@", "^A", "^B", "^C", "^D", "^E", "^F", "^G", "^H", "^I", "^J", "^K", + "^L", "^M", "^N", "^O", "^P", "^Q", "^R", "^S", "^T", "^U", "^V", "^W", + "^X", "^Y", "^Z", "^[", "^\\", "^]", "^~", "^_", + " ", "!", "\"", "#", "$", "%", "&", "'", "(", ")", "*", "+", ",", "-", + ".", "/", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", ":", ";", + "<", "=", ">", "?", "@", "A", "B", "C", "D", "E", "F", "G", "H", "I", + "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", + "X", "Y", "Z", "[", "\\", "]", "^", "_", "`", "a", "b", "c", "d", "e", + "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", + "t", "u", "v", "w", "x", "y", "z", "{", "|", "}", "~", "^?", + "M-^@", "M-^A", "M-^B", "M-^C", "M-^D", "M-^E", "M-^F", "M-^G", + "M-^H", "M-^I", "M-^J", "M-^K", "M-^L", "M-^M", "M-^N", "M-^O", + "M-^P", "M-^Q", "M-^R", "M-^S", "M-^T", "M-^U", "M-^V", "M-^W", + "M-^X", "M-^Y", "M-^Z", "M-^[", "M-^\\", "M-^]", "M-^~", "M-^_", + "M- ", "M-!", "M-\"", "M-#", "M-$", "M-%", "M-&", "M-'", + "M-(", "M-)", "M-*", "M-+", "M-,", "M--", "M-.", "M-/", + "M-0", "M-1", "M-2", "M-3", "M-4", "M-5", "M-6", "M-7", + "M-8", "M-9", "M-:", "M-;", "M-<", "M-=", "M->", "M-?", + "M-@", "M-A", "M-B", "M-C", "M-D", "M-E", "M-F", "M-G", + "M-H", "M-I", "M-J", "M-K", "M-L", "M-M", "M-N", "M-O", + "M-P", "M-Q", "M-R", "M-S", "M-T", "M-U", "M-V", "M-W", + "M-X", "M-Y", "M-Z", "M-[", "M-\\", "M-]", "M-^", "M-_", + "M-`", "M-a", "M-b", "M-c", "M-d", "M-e", "M-f", "M-g", + "M-h", "M-i", "M-j", "M-k", "M-l", "M-m", "M-n", "M-o", + "M-p", "M-q", "M-r", "M-s", "M-t", "M-u", "M-v", "M-w", + "M-x", "M-y", "M-z", "M-{", "M-|", "M-}", "M-~", "M-^?" +}; + +/* + * prchar(ch); print ch in a readable format, ie ^X or X or ~^X or DEL, etc. + */ + +void +prchar(unsigned int ch) +{ + if (isprint(ch) || isspace(ch)) + putchar(ch); + else + printf("%s", de_control[ch]); +} + + +/* + * error(errn, arglist) + * report an error to stderr using printf(3) conventions. + * Any output is preceded by ': ' + * + * Uses ERR_EXIT bit to request exit(errn) + * ERR_ABORT to request abort() + * ERR_ERRNO to indicate use of errno instead of argument. + * + * If resulting 'errn' is non-zero, it is assumed to be an 'errno' and its + * associated error message is appended to the output. + */ + +/*VARARGS*/ + +void +error(int error_flag, ...) +{ + va_list arglist; + register char *format; + extern char *sys_errlist[]; + extern int sys_nerr; + int local_errno; + + extern int errno; + + (void) fflush(stdout); /* in case stdout/stderr same */ + + local_errno = error_flag & ~ERR_MASK; + if (error_flag & ERR_ERRNO) /* use errno? */ + local_errno = errno; + + va_start(arglist, error_flag); + format = va_arg(arglist, char *); + (void) fprintf(stderr, "%s: ", progname); + (void) vfprintf(stderr, format, arglist); + va_end(arglist); + + if (local_errno) + if ((local_errno > 0) && (local_errno < sys_nerr)) + (void) fprintf(stderr, " (%s)\n", sys_errlist[local_errno]); + else + (void) fprintf(stderr, " (unknown errno=%d)\n", local_errno); + else + (void) fprintf(stderr, "\n"); + + (void) fflush(stderr); + + if (error_flag & (ERR_FATAL | ERR_ABORT)) + { + if (error_flag & ERR_FATAL) + { + error(0, local_errno ? "fatal error, exiting" : "exiting"); + exit(local_errno); + } + else + { + error(0, "fatal error, aborting"); + abort(); + } + } +} + diff --git a/c/src/lib/libbsp/i386/force386/clock/ckinit.c b/c/src/lib/libbsp/i386/force386/clock/ckinit.c new file mode 100644 index 0000000000..45400dbd49 --- /dev/null +++ b/c/src/lib/libbsp/i386/force386/clock/ckinit.c @@ -0,0 +1,75 @@ +/* Clock_initialize + * + * This routine initializes the Motorola MFP 68901 on the + * FORCE CPU386 board. The tick frequency is 1 millisecond. + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include +#include + +volatile rtems_unsigned32 Clock_driver_ticks; +rtems_unsigned32 Clock_isrs; /* ISRs until next tick */ +rtems_isr_entry Old_ticker; + +rtems_device_driver Clock_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *pargp, + rtems_id tid, + rtems_unsigned32 *rval +) +{ + Install_clock( Clock_isr ); +} + +void ReInstall_clock( + rtems_isr_entry clock_isr +) +{ + rtems_unsigned32 isrlevel = 0; + + rtems_interrupt_disable( isrlevel ); + (void) set_vector( clock_isr, 0x38, 1 ); + rtems_interrupt_enable( isrlevel ); +} + +void Install_clock( + rtems_isr_entry clock_isr +) +{ + Clock_driver_ticks = 0; + Clock_isrs = BSP_Configuration.microseconds_per_tick / 1000; + + if ( BSP_Configuration.ticks_per_timeslice ) { + Old_ticker = ( rtems_isr_entry ) set_vector( clock_isr, 0x38, 1 ); + outport_byte( TBCR, 0x14 ); /* reset it, delay mode, 50X */ + outport_byte( TBDR, 0x50 ); /* 1 millisecond */ + outport_byte( IERA, 0x41 ); /* enable interrupt for B */ + } + atexit( Clock_exit ); +} + +void Clock_exit( void ) +{ + if ( BSP_Configuration.ticks_per_timeslice ) { + outport_byte( TBCR, 0x00 ); /* initial value */ + outport_byte( IERA, 0x40 ); /* disable interrupt */ + /* ??? Is "do not restore old vector" causing problems? */ + } +} + diff --git a/c/src/lib/libbsp/i386/force386/console/console.c b/c/src/lib/libbsp/i386/force386/console/console.c new file mode 100644 index 0000000000..f1f019c487 --- /dev/null +++ b/c/src/lib/libbsp/i386/force386/console/console.c @@ -0,0 +1,219 @@ +/* + * This file contains the Force CPU386 console IO package. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#define F386_INIT + +#include + +#include +#include "console.h" +#include "bsp.h" + +/* console_cleanup + * + * This routine is called at exit to clean up the console hardware. + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * Return values: + */ + +void console_cleanup( void ) +{ + register rtems_unsigned8 ignored; + /* + * FORCE technical support mentioned that it may be necessary to + * read the DUSCC RX_BUFFER port four times to remove all junk. + * This code is a little more paranoid. + */ + + inport_byte( RX_BUFFER, ignored ); + inport_byte( RX_BUFFER, ignored ); + inport_byte( RX_BUFFER, ignored ); + inport_byte( RX_BUFFER, ignored ); + inport_byte( RX_BUFFER, ignored ); +} + +/* console_initialize + * + * This routine initializes the console IO driver. + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * Return values: + */ + +rtems_device_driver console_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg, + rtems_id self, + rtems_unsigned32 *status +) +{ + /* + * flush the console now and at exit. Just in case. + */ + + console_cleanup(); + + atexit( console_cleanup ); +} + + +/* is_character_ready + * + * This routine returns TRUE if a character is available. + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * Return values: + */ + +rtems_boolean is_character_ready( + char *ch +) +{ + register rtems_unsigned8 status; + + inport_byte( RX_STATUS, status ); + + if ( Is_rx_ready( status ) ) { + inport_byte( RX_BUFFER, status ); + *ch = status; + return TRUE; + } + return FALSE; +} + +/* inbyte + * + * This routine reads a character from the UART. + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * Return values: + * character read from UART + */ + +char inbyte( void ) +{ + register rtems_unsigned8 status; + char ch; + + do { + inport_byte( RX_STATUS, status ); + } while ( !Is_rx_ready( status ) ); + +#if ( PORTB == 1 ) + /* + * Force example code resets the Channel B Receiver here. + * It appears to cause XON's to be lost. + */ + + /* outport_byte( RX_STATUS, 0x10 ); */ +#endif + + inport_byte( RX_BUFFER, ch ); + + return ch; +} + +/* outbyte + * + * This routine transmits a character out the port. It supports + * XON/XOFF flow control. + * + * Input parameters: + * ch - character to be transmitted + * + * Output parameters: NONE + */ + +void outbyte( + char ch +) +{ + rtems_unsigned8 status; + + do { + inport_byte( TX_STATUS, status ); + } while ( !Is_tx_ready( status ) ); + +#if 0 + while ( is_character_ready( &status ) == TRUE ) { /* must be an XOFF */ + if ( status == XOFF ) + do { + while ( is_character_ready( &status ) == FALSE ) ; + } while ( status != XON ); + } +#endif + + outport_byte( TX_BUFFER, ch ); +} + +/* + * __read -- read bytes from the serial port. Ignore fd, since + * we only have stdin. + */ + +int __read( + int fd, + char *buf, + int nbytes +) +{ + int i = 0; + + for (i = 0; i < nbytes; i++) { + *(buf + i) = inbyte(); + if ((*(buf + i) == '\n') || (*(buf + i) == '\r')) { + (*(buf + i++)) = '\n'; + (*(buf + i)) = 0; + break; + } + } + return (i); +} + +/* + * __write -- write bytes to the serial port. Ignore fd, since + * stdout and stderr are the same. Since we have no filesystem, + * open will only return an error. + */ + +int __write( + int fd, + char *buf, + int nbytes +) +{ + int i; + + for (i = 0; i < nbytes; i++) { + if (*(buf + i) == '\n') { + outbyte ('\r'); + } + outbyte (*(buf + i)); + } + return (nbytes); +} diff --git a/c/src/lib/libbsp/i386/force386/include/bsp.h b/c/src/lib/libbsp/i386/force386/include/bsp.h new file mode 100644 index 0000000000..b9b050b3c6 --- /dev/null +++ b/c/src/lib/libbsp/i386/force386/include/bsp.h @@ -0,0 +1,156 @@ +/* bsp.h + * + * This include file definitions related to the Force CPU-386 board. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __FORCE386_h +#define __FORCE386_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +/* + * Define the time limits for RTEMS Test Suite test durations. + * Long test and short test duration limits are provided. These + * values are in seconds and need to be converted to ticks for the + * application. + * + */ + +#define MAX_LONG_TEST_DURATION 300 /* 5 minutes = 300 seconds */ +#define MAX_SHORT_TEST_DURATION 3 /* 3 seconds */ + +/* + * Define the interrupt mechanism for Time Test 27 + * + * NOTE: Use a software interrupt for the i386. + */ + +#define MUST_WAIT_FOR_INTERRUTPT 0 + +#define Install_tm27_vector( handler ) set_vector( (handler), 0x90, 1 ) + +#define Cause_tm27_intr() asm volatile( "int $0x90" : : ); + +#define Clear_tm27_intr() + +#define Lower_tm27_intr() + +/* + * Simple spin delay in microsecond units for device drivers. + * This is very dependent on the clock speed of the target. + */ + +#define delay( _microseconds ) \ + { \ + rtems_unsigned32 _counter; \ + \ + _counter = (_microseconds); \ + \ + asm volatile ( "0: nop;" \ + " mov %0,%0 ;" \ + " loop 0b" : "=c" (_counter) \ + : "0" (_counter) \ + ); \ + \ + } + +/* Constants */ + +#define RAM_START 0 +#define RAM_END 0x100000 + +/* I/O addressing */ + +/* + * The following determines whether Port B or the Console should + * be used for test I/O. Setting ONE (and only ONE) of these to 1 + * enables I/O on that port. + * + * PORT A - DUSCC MC68562 Channel A + * PORT B - DUSCC MC68562 Channel B + * PORT C - MFP MC68901 Channel (*** FORCEbug console ***) + */ + +#define PORTB 1 /* use port b as test port */ +#define PORTC 0 /* use console port as test port */ + +#if ( PORTB == 1 ) +#define TX_STATUS 0x1b6 /* DUSCC General Status Register */ +#define RX_STATUS 0x1b6 /* DUSCC General Status Register */ +#define TX_BUFFER 0x1e0 /* DUSCC Transmitter Channel B */ +#define RX_BUFFER 0x1e8 /* DUSCC Receiver Channel B */ +#define Is_tx_ready( _status ) ( (_status) & 0x20 ) +#define Is_rx_ready( _status ) ( (_status) & 0x10 ) +#endif + +#if ( PORTC == 1 ) +#define TX_STATUS 0x12c /* MFP Transmit Status Register */ +#define RX_STATUS 0x12a /* MFP Receive Status Register */ +#define TX_BUFFER 0x12e /* MFP Transmitter Channel */ +#define RX_BUFFER 0x12e /* MFP Receiver Channel */ +#define Is_tx_ready( _status ) ( (_status) & 0x80 ) +#define Is_rx_ready( _status ) ( (_status) & 0x80 ) +#endif + +/* Timer constants */ + +#define IERA 0x106 /* Interrupt Enable Register A */ +#define IMRA 0x112 /* Interrupt Mask Register A */ +#define TACR 0x118 /* Timer A Control Register */ +#define TADR 0x11e /* Timer A Data Register */ + +#define IERB 0x108 /* Interrupt Enable Register B */ +#define TBCR 0x11a /* Timer B Control Register */ +#define TBDR 0x120 /* Timer B Data Register */ + +/* Structures */ + +#ifdef F386_INIT +#undef BSP_EXTERN +#define BSP_EXTERN +#else +#undef BSP_EXTERN +#define BSP_EXTERN extern +#endif + +/* miscellaneous stuff assumed to exist */ + +extern rtems_configuration_table BSP_Configuration; + +extern i386_IDT_slot Interrupt_descriptor_table[ 256 ]; +extern i386_GDT_slot Global_descriptor_table[ 8192 ]; + +BSP_EXTERN unsigned short Idt[3]; /* Interrupt Descriptor Table Address */ +BSP_EXTERN unsigned short Gdt[3]; /* Global Descriptor Table Address */ +BSP_EXTERN unsigned int Idt_base; +BSP_EXTERN unsigned int Gdt_base; + +/* routines */ + +i386_isr set_vector( + rtems_isr_entry handler, + rtems_vector_number vector, + int type +); + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/c/src/lib/libbsp/i386/force386/include/coverhd.h b/c/src/lib/libbsp/i386/force386/include/coverhd.h new file mode 100644 index 0000000000..7ec7cb2ebc --- /dev/null +++ b/c/src/lib/libbsp/i386/force386/include/coverhd.h @@ -0,0 +1,104 @@ +/* coverhd.h + * + * This include file has defines to represent the overhead associated + * with calling a particular directive from C on this target. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __COVERHD_h +#define __COVERHD_h + +#ifdef __cplusplus +extern "C" { +#endif + +#define CALLING_OVERHEAD_INITIALIZE_EXECUTIVE 3 +#define CALLING_OVERHEAD_SHUTDOWN_EXECUTIVE 3 +#define CALLING_OVERHEAD_TASK_CREATE 4 +#define CALLING_OVERHEAD_TASK_IDENT 4 +#define CALLING_OVERHEAD_TASK_START 4 +#define CALLING_OVERHEAD_TASK_RESTART 3 +#define CALLING_OVERHEAD_TASK_DELETE 3 +#define CALLING_OVERHEAD_TASK_SUSPEND 3 +#define CALLING_OVERHEAD_TASK_RESUME 3 +#define CALLING_OVERHEAD_TASK_SET_PRIORITY 4 +#define CALLING_OVERHEAD_TASK_MODE 4 +#define CALLING_OVERHEAD_TASK_GET_NOTE 4 +#define CALLING_OVERHEAD_TASK_SET_NOTE 4 +#define CALLING_OVERHEAD_TASK_WAKE_WHEN 7 +#define CALLING_OVERHEAD_TASK_WAKE_AFTER 3 +#define CALLING_OVERHEAD_INTERRUPT_CATCH 4 +#define CALLING_OVERHEAD_CLOCK_GET 7 +#define CALLING_OVERHEAD_CLOCK_SET 7 +#define CALLING_OVERHEAD_CLOCK_TICK 2 + +#define CALLING_OVERHEAD_TIMER_CREATE 3 +#define CALLING_OVERHEAD_TIMER_IDENT 3 +#define CALLING_OVERHEAD_TIMER_DELETE 3 +#define CALLING_OVERHEAD_TIMER_FIRE_AFTER 4 +#define CALLING_OVERHEAD_TIMER_FIRE_WHEN 8 +#define CALLING_OVERHEAD_TIMER_RESET 3 +#define CALLING_OVERHEAD_TIMER_CANCEL 3 +#define CALLING_OVERHEAD_SEMAPHORE_CREATE 4 +#define CALLING_OVERHEAD_SEMAPHORE_DELETE 3 +#define CALLING_OVERHEAD_SEMAPHORE_IDENT 4 +#define CALLING_OVERHEAD_SEMAPHORE_OBTAIN 4 +#define CALLING_OVERHEAD_SEMAPHORE_RELEASE 3 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_CREATE 4 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_IDENT 4 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_DELETE 3 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_SEND 3 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_URGENT 3 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_BROADCAST 4 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_RECEIVE 4 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_FLUSH 3 + +#define CALLING_OVERHEAD_EVENT_SEND 4 +#define CALLING_OVERHEAD_EVENT_RECEIVE 4 +#define CALLING_OVERHEAD_SIGNAL_CATCH 3 +#define CALLING_OVERHEAD_SIGNAL_SEND 3 +#define CALLING_OVERHEAD_PARTITION_CREATE 4 +#define CALLING_OVERHEAD_PARTITION_IDENT 4 +#define CALLING_OVERHEAD_PARTITION_DELETE 3 +#define CALLING_OVERHEAD_PARTITION_GET_BUFFER 4 +#define CALLING_OVERHEAD_PARTITION_RETURN_BUFFER 4 +#define CALLING_OVERHEAD_REGION_CREATE 4 +#define CALLING_OVERHEAD_REGION_IDENT 3 +#define CALLING_OVERHEAD_REGION_DELETE 3 +#define CALLING_OVERHEAD_REGION_GET_SEGMENT 4 +#define CALLING_OVERHEAD_REGION_RETURN_SEGMENT 4 +#define CALLING_OVERHEAD_PORT_CREATE 4 +#define CALLING_OVERHEAD_PORT_IDENT 3 +#define CALLING_OVERHEAD_PORT_DELETE 3 +#define CALLING_OVERHEAD_PORT_EXTERNAL_TO_INTERNAL 4 +#define CALLING_OVERHEAD_PORT_INTERNAL_TO_EXTERNAL 4 + +#define CALLING_OVERHEAD_IO_INITIALIZE 4 +#define CALLING_OVERHEAD_IO_OPEN 4 +#define CALLING_OVERHEAD_IO_CLOSE 4 +#define CALLING_OVERHEAD_IO_READ 4 +#define CALLING_OVERHEAD_IO_WRITE 4 +#define CALLING_OVERHEAD_IO_CONTROL 4 +#define CALLING_OVERHEAD_FATAL_ERROR_OCCURRED 3 +#define CALLING_OVERHEAD_RATE_MONOTONIC_CREATE 3 +#define CALLING_OVERHEAD_RATE_MONOTONIC_IDENT 3 +#define CALLING_OVERHEAD_RATE_MONOTONIC_DELETE 3 +#define CALLING_OVERHEAD_RATE_MONOTONIC_CANCEL 3 +#define CALLING_OVERHEAD_RATE_MONOTONIC_PERIOD 3 +#define CALLING_OVERHEAD_MULTIPROCESSING_ANNOUNCE 2 + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/c/src/lib/libbsp/i386/force386/shmsupp/addrconv.c b/c/src/lib/libbsp/i386/force386/shmsupp/addrconv.c new file mode 100644 index 0000000000..49d27200a0 --- /dev/null +++ b/c/src/lib/libbsp/i386/force386/shmsupp/addrconv.c @@ -0,0 +1,32 @@ +/* Shm_Convert_address + * + * The CPU386 has a "normal" view of the VME address space. + * No address range conversion is required. + * + * Input parameters: + * address - address to convert + * + * Output parameters: + * returns - converted address + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include +#include + +void *Shm_Convert_address( + void *address +) +{ + return ( address ); +} diff --git a/c/src/lib/libbsp/i386/force386/shmsupp/getcfg.c b/c/src/lib/libbsp/i386/force386/shmsupp/getcfg.c new file mode 100644 index 0000000000..8a05cdf641 --- /dev/null +++ b/c/src/lib/libbsp/i386/force386/shmsupp/getcfg.c @@ -0,0 +1,73 @@ +/* void Shm_Get_configuration( localnode, &shmcfg ) + * + * This routine initializes, if necessary, and returns a pointer + * to the Shared Memory Configuration Table for the FORCE CPU-386 + * + * INPUT PARAMETERS: + * localnode - local node number + * shmcfg - address of pointer to SHM Config Table + * + * OUTPUT PARAMETERS: + * *shmcfg - pointer to SHM Config Table + * + * NOTES: The FORCE CPU-386 does not have an interprocessor interrupt. + * + * The following table illustrates the configuration limitations: + * + * BUS MAX + * MODE ENDIAN NODES + * ========= ====== ======= + * POLLED BIG 2+ + * INTERRUPT **** NOT SUPPORTED **** + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include +#include + +#define INTERRUPT 0 +#define POLLING 1 /* FORCE CPU-386 target is polling ONLY!!! */ + + +shm_config_table BSP_shm_cfgtbl; + +void Shm_Get_configuration( + rtems_unsigned32 localnode, + shm_config_table **shmcfg +) +{ + set_segment( get_ds(), 0x00002000, 0xffffd000 ); + + BSP_shm_cfgtbl.base = i386_Physical_to_logical( + get_ds(), + (void *) 0x20000000 + ); + + BSP_shm_cfgtbl.length = 1 * MEGABYTE; + BSP_shm_cfgtbl.format = SHM_BIG; + + BSP_shm_cfgtbl.cause_intr = Shm_Cause_interrupt; + +#ifdef NEUTRAL_BIG + BSP_shm_cfgtbl.convert = NULL_CONVERT; +#else + BSP_shm_cfgtbl.convert = CPU_swap_u32; +#endif + + BSP_shm_cfgtbl.poll_intr = POLLED_MODE; + BSP_shm_cfgtbl.Intr.address = NO_INTERRUPT; + BSP_shm_cfgtbl.Intr.value = NO_INTERRUPT; + BSP_shm_cfgtbl.Intr.length = NO_INTERRUPT; + + *shmcfg = &BSP_shm_cfgtbl; +} diff --git a/c/src/lib/libbsp/i386/force386/shmsupp/lock.c b/c/src/lib/libbsp/i386/force386/shmsupp/lock.c new file mode 100644 index 0000000000..7e1b7874d1 --- /dev/null +++ b/c/src/lib/libbsp/i386/force386/shmsupp/lock.c @@ -0,0 +1,83 @@ +/* Shared Memory Lock Routines + * + * This shared memory locked queue support routine need to be + * able to lock the specified locked queue. Interrupts are + * disabled while the queue is locked to prevent preemption + * and deadlock when two tasks poll for the same lock. + * previous level. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include +#include + +/* + * Shm_Initialize_lock + * + * Initialize the lock for the specified locked queue. + */ + +void Shm_Initialize_lock( + Shm_Locked_queue_Control *lq_cb +) +{ + lq_cb->lock = LQ_UNLOCKED; +} + +/* void _Shm_Lock( &lq_cb ) + * + * This shared memory locked queue support routine locks the + * specified locked queue. It disables interrupts to prevent + * a deadlock condition. + */ + +void Shm_Lock( + Shm_Locked_queue_Control *lq_cb +) +{ + rtems_unsigned32 isr_level; + volatile rtems_unsigned32 *lockptr = &lq_cb->lock; + rtems_unsigned32 lock_value; + + lock_value = SHM_LOCK_VALUE; + rtems_interrupt_disable( isr_level ); + + Shm_isrstat = isr_level; + while ( 1 ) { + asm volatile( "lock ; xchg (%0),%1" + : "=r" (lockptr), "=r" (lock_value) + : "0" (lockptr), "1" (lock_value) + ); + if ( lock_value == SHM_UNLOCK_VALUE ) + break; + delay( 10 ); /* approximately 10 microseconds */ + } +} + +/* + * Shm_Unlock + * + * Unlock the lock for the specified locked queue. + */ + +void Shm_Unlock( + Shm_Locked_queue_Control *lq_cb +) +{ + rtems_unsigned32 isr_level; + + lq_cb->lock = SHM_UNLOCK_VALUE; + isr_level = Shm_isrstat; + rtems_interrupt_enable( isr_level ); +} + diff --git a/c/src/lib/libbsp/i386/force386/shmsupp/mpisr.c b/c/src/lib/libbsp/i386/force386/shmsupp/mpisr.c new file mode 100644 index 0000000000..dc6f8433e6 --- /dev/null +++ b/c/src/lib/libbsp/i386/force386/shmsupp/mpisr.c @@ -0,0 +1,31 @@ +/* Shm_setvec + * + * This driver routine sets the SHM interrupt vector to point to the + * driver's SHM interrupt service routine. + * + * NOTE: This routine is not used by the FORCE CPU-386 because it + * only supports polling mode. + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include +#include + +void Shm_setvec() +{ + /* NOT USED ON FORCE CPU-386!!! */ +} diff --git a/c/src/lib/libbsp/i386/force386/startup/bspstart.c b/c/src/lib/libbsp/i386/force386/startup/bspstart.c new file mode 100644 index 0000000000..78def6375c --- /dev/null +++ b/c/src/lib/libbsp/i386/force386/startup/bspstart.c @@ -0,0 +1,144 @@ +/* bsp_start() + * + * This routine starts the application. It includes application, + * board, and monitor specific initialization and configuration. + * The generic CPU dependent initialization has been performed + * before this routine is invoked. + * + * INPUT: NONE + * + * OUTPUT: NONE + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include +#include + +#include + +/* + * The original table from the application and our copy of it with + * some changes. + */ + +extern rtems_configuration_table Configuration; +rtems_configuration_table BSP_Configuration; + +rtems_cpu_table Cpu_table; + +/* Initialize whatever libc we are using + * called from postdriver hook + */ + +void bsp_libc_init() +{ + extern int end; + rtems_unsigned32 heap_start; + + heap_start = (rtems_unsigned32) &end; + if (heap_start & (CPU_ALIGNMENT-1)) + heap_start = (heap_start + CPU_ALIGNMENT) & ~(CPU_ALIGNMENT-1); + + RTEMS_Malloc_Initialize((void *) heap_start, 64 * 1024, 0); + + /* + * Set up for the libc handling. + */ + + if (BSP_Configuration.ticks_per_timeslice > 0) + libc_init(1); /* reentrant if possible */ + else + libc_init(0); /* non-reentrant */ + + /* + * Initialize the stack bounds checker + */ + +#ifdef STACK_CHECKER_ON + Stack_check_Initialize(); +#endif + +} + +int bsp_start( + int argc, + char **argv, + char **environp +) +{ + /* + * FORCE documentation incorrectly states that the bus request + * level is initialized to 3. It is actually initialized by + * FORCEbug to 0. + */ + + outport_byte( 0x00, 0x3f ); /* resets VMEbus request level */ + + /* + * we do not use the pretasking_hook. + */ + + Cpu_table.pretasking_hook = NULL; + + Cpu_table.predriver_hook = bsp_libc_init; /* RTEMS resources available */ + + Cpu_table.postdriver_hook = NULL; /* Call our main() for constructors */ + + Cpu_table.idle_task = NULL; /* do not override system IDLE task */ + + Cpu_table.do_zero_of_workspace = TRUE; + + Cpu_table.interrupt_table_segment = get_ds(); + + Cpu_table.interrupt_table_offset = (void *)Interrupt_descriptor_table; + + Cpu_table.interrupt_stack_size = 4096; + + Cpu_table.extra_system_initialization_stack = 0; + + /* + * Copy the table + */ + + BSP_Configuration = Configuration; + + BSP_Configuration.work_space_start = (void *) + RAM_END - BSP_Configuration.work_space_size; + + /* + * Add 1 region for Malloc in libc_low + */ + + BSP_Configuration.maximum_regions++; + + /* + * Add 1 extension for newlib libc + */ + +#ifdef RTEMS_NEWLIB + BSP_Configuration.maximum_extensions++; +#endif + + /* + * Add another extension if using the stack checker + */ + +#ifdef STACK_CHECKER_ON + BSP_Configuration.maximum_extensions++; +#endif + + rtems_initialize_executive( &BSP_Configuration, &Cpu_table ); + /* does not return */ + /* no cleanup necessary for Force CPU-386 */ + return 0; +} diff --git a/c/src/lib/libbsp/i386/force386/startup/exit.c b/c/src/lib/libbsp/i386/force386/startup/exit.c new file mode 100644 index 0000000000..717972cec0 --- /dev/null +++ b/c/src/lib/libbsp/i386/force386/startup/exit.c @@ -0,0 +1,29 @@ +/* + * exit + * + * This routine returns control to FORCEbug. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include +#include +#include + +void _exit( ) +{ + /* Clock or Timer cleanup is run by at_exit() */ + + Io_cleanup(); + + bsp_cleanup(); +} diff --git a/c/src/lib/libbsp/i386/force386/startup/ldsegs.s b/c/src/lib/libbsp/i386/force386/startup/ldsegs.s new file mode 100644 index 0000000000..063c1eccc7 --- /dev/null +++ b/c/src/lib/libbsp/i386/force386/startup/ldsegs.s @@ -0,0 +1,86 @@ +/* _load_segments + * + * This file assists the board independent startup code by + * loading the proper segment register values. The values + * loaded are board dependent. + * + * NOTE: No stack has been established when this routine + * is invoked. It returns by jumping back to bspentry. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include "asm.h" + +BEGIN_CODE + +/* + * FORCEBUG loads us into a virtual address space which + * really starts at PHYSICAL_ADDRESS_BASE. + */ + +.set PHYSICAL_ADDRESS_BASE, 0x00002000 + +/* + * At reset time, FORCEBUG normally has the segment selectors preloaded. + * If a human resets the instruction pointer, this will not have occurred. + * However, no guarantee can be made of the other registers if cs:ip was + * modified to restart the program. Because of this, the BSP reloads all + * segment registers (except cs) with the values they have following + * a reset. + */ + + +.set RESET_SS, 0x40 # initial value of stack segment register +.set RESET_DS, 0x40 # initial value of data segment register +.set RESET_ES, 0x40 # initial value of extra segment register +.set RESET_FS, 0x40 # initial value of "f" segment register +.set RESET_GS, 0x30 # initial value of "g" segment register + + +#define LOAD_SEGMENTS(_value,_segment) \ + movw $ ## _value, ax ; \ + movw _segment, ax + + EXTERN (establish_stack) + + PUBLIC (_load_segments) +SYM (_load_segments): + LOAD_SEGMENTS( RESET_SS, ss ) + LOAD_SEGMENTS( RESET_DS, ds ) + LOAD_SEGMENTS( RESET_ES, es ) + LOAD_SEGMENTS( RESET_FS, fs ) + LOAD_SEGMENTS( RESET_GS, gs ) + + jmp SYM (_establish_stack) # return to the bsp entry code + + PUBLIC (_return_to_monitor) +SYM (_return_to_monitor): + + call SYM (Clock_exit) + movb $0,al + int $0x20 # restart FORCEbug + jmp SYM (start) # FORCEbug does not reset PC + +END_CODE + +BEGIN_DATA + + PUBLIC (_Do_Load_IDT) +SYM (_Do_Load_IDT): + .byte 1 + + PUBLIC (_Do_Load_GDT) +SYM (_Do_Load_GDT): + .byte 0 + +END_DATA +END diff --git a/c/src/lib/libbsp/i386/force386/startup/linkcmds b/c/src/lib/libbsp/i386/force386/startup/linkcmds new file mode 100644 index 0000000000..a8e0877e56 --- /dev/null +++ b/c/src/lib/libbsp/i386/force386/startup/linkcmds @@ -0,0 +1,44 @@ +/* + * This file contains directives for the GNU linker which are specific + * to the FORCE CPU386 board. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +MEMORY + { + ram : org = 0x0, l = 1M + } + +SECTIONS +{ + .text 0x0 : + { + _text_start = . ; + *(.text) + _etext = ALIGN( 0x10 ) ; + } + .data ADDR( .text ) + SIZEOF( .text ): + { + _data_start = . ; + *(.data) + _edata = ALIGN( 0x10 ) ; + } + .bss ADDR( .data ) + SIZEOF( .data ): + { + _bss_start = . ; + *(.bss) + *(COMMON) + end = . ; + _end = . ; + __end = . ; + } +} diff --git a/c/src/lib/libbsp/i386/force386/startup/setvec.c b/c/src/lib/libbsp/i386/force386/startup/setvec.c new file mode 100644 index 0000000000..370178a8f5 --- /dev/null +++ b/c/src/lib/libbsp/i386/force386/startup/setvec.c @@ -0,0 +1,59 @@ +/* set_vector + * + * This routine installs an interrupt vector on the Force CPU-386. + * + * INPUT: + * handler - interrupt handler entry point + * vector - vector number + * type - 0 indicates raw hardware connect + * 1 indicates RTEMS interrupt connect + * + * RETURNS: + * address of previous interrupt handler + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include + +i386_isr set_vector( /* returns old vector */ + rtems_isr_entry handler, /* isr routine */ + rtems_vector_number vector, /* vector number */ + int type /* RTEMS or RAW intr */ +) +{ + i386_isr previous_isr; + i386_IDT_slot idt; + + if ( type ) + rtems_interrupt_catch( handler, vector, (rtems_isr_entry *) &previous_isr ); + else { + /* get the address of the old handler */ + + idt = Interrupt_descriptor_table[ vector ]; + + previous_isr = (i386_isr) + ((idt.offset_16_31 << 16) | idt.offset_0_15); + + /* build the IDT entry */ + idt.offset_0_15 = ((rtems_unsigned32) handler) & 0xffff; + idt.segment_selector = get_cs(); + idt.reserved = 0x00; + idt.p_dpl = 0x8e; /* present, ISR */ + idt.offset_16_31 = ((rtems_unsigned32) handler) >> 16; + + /* install the IDT entry */ + Interrupt_descriptor_table[ vector ] = idt; + } + return previous_isr; +} + diff --git a/c/src/lib/libbsp/i386/force386/timer/timer.c b/c/src/lib/libbsp/i386/force386/timer/timer.c new file mode 100644 index 0000000000..1896e15a23 --- /dev/null +++ b/c/src/lib/libbsp/i386/force386/timer/timer.c @@ -0,0 +1,96 @@ +/* Timer_init() + * + * This routine initializes the timer on the FORCE CPU-386 board. + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * NOTE: This routine will not work if the optimizer is enabled + * for some compilers. The multiple writes to the Z8036 + * may be optimized away. + * + * It is important that the timer start/stop overhead be + * determined when porting or modifying this code. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + + +#include +#include + +int Ttimer_val; +rtems_boolean Timer_driver_Find_average_overhead; + +rtems_isr timerisr(); + +void Timer_initialize() +{ + + (void) set_vector( timerisr, 0x38, 0 ); /* install ISR */ + + Ttimer_val = 0; /* clear timer ISR count */ + + outport_byte( IERA, 0x40 ); /* disable interrupt */ + outport_byte( TBCR, 0x40 ); /* stop the timer */ + outport_byte( TBDR, 250 ); /* 250 units */ + + outport_byte( TBCR, 0x11 ); /* reset it, delay mode, 4X */ +#if 0 + outport_byte( TBCR, 0x13 ); /* reset it, delay mode, 16X */ +#endif + + outport_byte( IERA, 0x41 ); /* enable interrupt */ + +} + +#define AVG_OVERHEAD 3 /* It typically takes 3.0 microseconds */ + /* (3 ticks) to start/stop the timer. */ +#define LEAST_VALID 4 /* Don't trust a value lower than this */ + +int Read_timer() +{ + register rtems_unsigned32 clicks; + register rtems_unsigned32 total; + + outport_byte( TBCR, 0x00 ); /* stop the timer */ + + inport_byte( TBDR, clicks ); + + total = Ttimer_val + 250 - clicks; + + outport_byte( TBCR, 0x00 ); /* initial value */ + outport_byte( IERA, 0x40 ); /* disable interrupt */ + + /* ??? Is "do not restore old vector" causing problems? */ + + if ( Timer_driver_Find_average_overhead == 1 ) + return total; /* in one microsecond units */ + + else { + if ( total < LEAST_VALID ) + return 0; /* below timer resolution */ + return (total - AVG_OVERHEAD); + } +} + +rtems_status_code Empty_function( void ) +{ + return RTEMS_SUCCESSFUL; +} + +void Set_find_average_overhead( + rtems_boolean find_flag +) +{ + Timer_driver_Find_average_overhead = find_flag; +} diff --git a/c/src/lib/libbsp/i386/force386/timer/timerisr.s b/c/src/lib/libbsp/i386/force386/timer/timerisr.s new file mode 100644 index 0000000000..bda3056ade --- /dev/null +++ b/c/src/lib/libbsp/i386/force386/timer/timerisr.s @@ -0,0 +1,34 @@ +/* timer_isr() + * + * This routine provides the ISR for the Z8036 timer on the MVME136 + * board. The timer is set up to generate an interrupt at maximum + * intervals. + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include "asm.h" + + BEGIN_CODE + + EXTERN (Ttimer_val) + + PUBLIC (timerisr) +SYM (timerisr): + addl $250, SYM (Ttimer_val) # another 250 microseconds + iret + +END_CODE +END diff --git a/c/src/lib/libbsp/i960/cvme961/clock/ckinit.c b/c/src/lib/libbsp/i960/cvme961/clock/ckinit.c new file mode 100644 index 0000000000..315e02cdbb --- /dev/null +++ b/c/src/lib/libbsp/i960/cvme961/clock/ckinit.c @@ -0,0 +1,77 @@ +/* Clock_init() + * + * This routine initializes the timer on the VIC chip on the CVME961. + * The tick frequency is 1 millisecond. + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include + +#include +#include +#include + +rtems_unsigned32 Clock_isrs; /* ISRs until next tick */ +i960_isr Old_ticker; +volatile rtems_unsigned32 Clock_driver_ticks; + /* ticks since initialization */ + +rtems_device_driver Clock_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *pargp, + rtems_id id, + rtems_unsigned32 *rval ) +{ + Install_clock( Clock_isr ); + atexit( Clock_exit ); +} + +void ReInstall_clock( + rtems_isr_entry clock_isr +) +{ + (void) set_vector( clock_isr, 5, 1 ); +} + +void Install_clock( + rtems_isr_entry clock_isr +) +{ + volatile unsigned char *victimer; + + Clock_driver_ticks = 0; + Clock_isrs = BSP_Configuration.microseconds_per_tick / 1000; + + if ( BSP_Configuration.ticks_per_timeslice ) { + Old_ticker = set_vector( clock_isr, 5, 1 ); + victimer = (volatile unsigned char *) 0xa00000c3; + *victimer = 0x12; + *victimer = 0x92; /* 1000 HZ */ + } +} + +void Clock_exit() +{ + unsigned char *victimer; + + if ( BSP_Configuration.ticks_per_timeslice ) { + victimer = (unsigned char *) 0xa00000c3; + *victimer = 0x12; + i960_mask_intr( 5 ); + /* do not restore old vector */ + } +} diff --git a/c/src/lib/libbsp/i960/cvme961/console/console.c b/c/src/lib/libbsp/i960/cvme961/console/console.c new file mode 100644 index 0000000000..8ba0352304 --- /dev/null +++ b/c/src/lib/libbsp/i960/cvme961/console/console.c @@ -0,0 +1,147 @@ +/* + * This file contains the MVME136 console IO package. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#define C961_INIT + +#include +#include "console.h" +#include "bsp.h" + +/* console_initialize + * + * This routine initializes the console IO driver. + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * Return values: + */ + +rtems_device_driver console_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg, + rtems_id self, + rtems_unsigned32 *status +) +{ + *status = RTEMS_SUCCESSFUL; +} + +/* + * NINDY_IO( ... ) + * + * Interface to NINDY. + */ + +#define NINDY_INPUT 0 +#define NINDY_OUTPUT 1 + +void NINDY_IO(); + +void ___NINDY_IO_WRAPPER( void ) /* never called */ +{ + asm volatile ( " .text" ); + asm volatile ( " .align 4" ); + asm volatile ( " .globl _NINDY_IO" ); + asm volatile ( "_NINDY_IO:" ); + asm volatile ( " calls 0 /* call console routines */" ); + asm volatile ( " ret" ); +} + +/* inbyte + * + * This routine reads a character from the console using NINDY. + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * Return values: + * character read from UART + */ + +char inbyte( void ) +{ + char ch; + + NINDY_IO( NINDY_INPUT, &ch ); + return ch; +} + + +/* outbyte + * + * This routine transmits a character out the console using NINDY. + * + * Input parameters: + * ch - character to be transmitted + * + * Output parameters: NONE + */ + +void outbyte( + char ch +) +{ + NINDY_IO( NINDY_OUTPUT, ch ); +} + +/* + * __read -- read bytes from the serial port. Ignore fd, since + * we only have stdin. + */ + +int __read( + int fd, + char *buf, + int nbytes +) +{ + int i = 0; + + for (i = 0; i < nbytes; i++) { + *(buf + i) = inbyte(); + if ((*(buf + i) == '\n') || (*(buf + i) == '\r')) { + (*(buf + i++)) = '\n'; + (*(buf + i)) = 0; + break; + } + } + return (i); +} + +/* + * __write -- write bytes to the serial port. Ignore fd, since + * stdout and stderr are the same. Since we have no filesystem, + * open will only return an error. + */ + +int __write( + int fd, + char *buf, + int nbytes +) +{ + int i; + + for (i = 0; i < nbytes; i++) { + if (*(buf + i) == '\n') { + outbyte ('\r'); + } + outbyte (*(buf + i)); + } + return (nbytes); +} diff --git a/c/src/lib/libbsp/i960/cvme961/include/bsp.h b/c/src/lib/libbsp/i960/cvme961/include/bsp.h new file mode 100644 index 0000000000..4dd907449f --- /dev/null +++ b/c/src/lib/libbsp/i960/cvme961/include/bsp.h @@ -0,0 +1,129 @@ +/* bsp.h + * + * This include file contains some definitions specific to the + * Cyclone CVME960 and CVME961 boards. These boards are the + * same except the 960 uses SRAM and the 961 DRAM. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __CVME961_h +#define __CVME961_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +/* + * Define the time limits for RTEMS Test Suite test durations. + * Long test and short test duration limits are provided. These + * values are in seconds and need to be converted to ticks for the + * application. + * + */ + +#define MAX_LONG_TEST_DURATION 300 /* 5 minutes = 300 seconds */ +#define MAX_SHORT_TEST_DURATION 3 /* 3 seconds */ + +/* + * Define the interrupt mechanism for Time Test 27 + * + * NOTE: Following are for i960CA and are board independent + * + */ + +#define MUST_WAIT_FOR_INTERRUPT 0 + +#define Install_tm27_vector( handler ) set_vector( (handler), 6, 1 ) + +#define Cause_tm27_intr() i960_cause_intr( 0x62 ) + +#define Clear_tm27_intr() i960_clear_intr( 6 ) + +#define Lower_tm27_intr() + +/* + * Simple spin delay in microsecond units for device drivers. + * This is very dependent on the clock speed of the target. + */ + +#define delay( microseconds ) \ + { register rtems_unsigned32 _delay=(microseconds); \ + register rtems_unsigned32 _tmp; \ + asm volatile( "0: \ + remo 3,31,%0 ; \ + cmpo 0,%0 ; \ + subo 1,%1,%1 ; \ + cmpobne.t 0,%1,0b " \ + : "=d" (_tmp), "=d" (_delay) \ + : "0" (_tmp), "1" (_delay) ); \ + } + +/* Constants */ + +#define RAM_START 0 +#define RAM_END 0x100000 + +/* NINDY console I/O requests: + * CO sends a single character to stdout, + * CI reads one. + */ + +#define NINDY_INPUT 0 +#define NINDY_OUTPUT 1 + +/* + * get_prcb + * + * Returns the PRCB pointer. + */ + +static inline i960ca_PRCB *get_prcb( void ) +{ + register i960ca_PRCB *_prcb = 0; + + asm volatile( "calls 5; \ + mov g0,%0" \ + : "=d" (_prcb) \ + : "0" (_prcb) ); + return ( _prcb ); +} + +#ifdef C961_INIT +#undef BSP_EXTERN +#define BSP_EXTERN +#else +#undef BSP_EXTERN +#define BSP_EXTERN extern +#endif + +/* miscellaneous stuff assumed to exist */ + +extern rtems_configuration_table BSP_Configuration; + +BSP_EXTERN i960ca_PRCB *Prcb; +BSP_EXTERN i960ca_control_table *Ctl_tbl; + +/* functions */ + +void bsp_cleanup( void ); + +i960_isr set_vector( rtems_isr_entry, unsigned int, unsigned int ); + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/c/src/lib/libbsp/i960/cvme961/include/coverhd.h b/c/src/lib/libbsp/i960/cvme961/include/coverhd.h new file mode 100644 index 0000000000..9d6b26111a --- /dev/null +++ b/c/src/lib/libbsp/i960/cvme961/include/coverhd.h @@ -0,0 +1,104 @@ +/* coverhd.h + * + * This include file has defines to represent the overhead associated + * with calling a particular directive from C on this target. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __COVERHD_h +#define __COVERHD_h + +#ifdef __cplusplus +extern "C" { +#endif + +#define CALLING_OVERHEAD_INITIALIZE_EXECUTIVE 0 +#define CALLING_OVERHEAD_SHUTDOWN_EXECUTIVE 0 +#define CALLING_OVERHEAD_TASK_CREATE 0 +#define CALLING_OVERHEAD_TASK_IDENT 0 +#define CALLING_OVERHEAD_TASK_START 0 +#define CALLING_OVERHEAD_TASK_RESTART 0 +#define CALLING_OVERHEAD_TASK_DELETE 0 +#define CALLING_OVERHEAD_TASK_SUSPEND 0 +#define CALLING_OVERHEAD_TASK_RESUME 0 +#define CALLING_OVERHEAD_TASK_SET_PRIORITY 0 +#define CALLING_OVERHEAD_TASK_MODE 0 +#define CALLING_OVERHEAD_TASK_GET_NOTE 0 +#define CALLING_OVERHEAD_TASK_SET_NOTE 0 +#define CALLING_OVERHEAD_TASK_WAKE_WHEN 3 +#define CALLING_OVERHEAD_TASK_WAKE_AFTER 0 +#define CALLING_OVERHEAD_INTERRUPT_CATCH 0 +#define CALLING_OVERHEAD_CLOCK_GET 3 +#define CALLING_OVERHEAD_CLOCK_SET 3 +#define CALLING_OVERHEAD_CLOCK_TICK 0 + +#define CALLING_OVERHEAD_TIMER_CREATE 0 +#define CALLING_OVERHEAD_TIMER_IDENT 0 +#define CALLING_OVERHEAD_TIMER_DELETE 0 +#define CALLING_OVERHEAD_TIMER_FIRE_AFTER 0 +#define CALLING_OVERHEAD_TIMER_FIRE_WHEN 6 +#define CALLING_OVERHEAD_TIMER_RESET 0 +#define CALLING_OVERHEAD_TIMER_CANCEL 0 +#define CALLING_OVERHEAD_SEMAPHORE_CREATE 0 +#define CALLING_OVERHEAD_SEMAPHORE_IDENT 0 +#define CALLING_OVERHEAD_SEMAPHORE_DELETE 0 +#define CALLING_OVERHEAD_SEMAPHORE_OBTAIN 0 +#define CALLING_OVERHEAD_SEMAPHORE_RELEASE 0 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_CREATE 0 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_IDENT 0 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_DELETE 0 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_SEND 0 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_URGENT 0 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_BROADCAST 0 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_RECEIVE 0 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_FLUSH 0 + +#define CALLING_OVERHEAD_EVENT_SEND 0 +#define CALLING_OVERHEAD_EVENT_RECEIVE 0 +#define CALLING_OVERHEAD_SIGNAL_CATCH 0 +#define CALLING_OVERHEAD_SIGNAL_SEND 0 +#define CALLING_OVERHEAD_PARTITION_CREATE 0 +#define CALLING_OVERHEAD_PARTITION_IDENT 0 +#define CALLING_OVERHEAD_PARTITION_DELETE 0 +#define CALLING_OVERHEAD_PARTITION_GET_BUFFER 0 +#define CALLING_OVERHEAD_PARTITION_RETURN_BUFFER 0 +#define CALLING_OVERHEAD_REGION_CREATE 0 +#define CALLING_OVERHEAD_REGION_IDENT 0 +#define CALLING_OVERHEAD_REGION_DELETE 0 +#define CALLING_OVERHEAD_REGION_GET_SEGMENT 0 +#define CALLING_OVERHEAD_REGION_RETURN_SEGMENT 0 +#define CALLING_OVERHEAD_PORT_CREATE 0 +#define CALLING_OVERHEAD_PORT_IDENT 0 +#define CALLING_OVERHEAD_PORT_DELETE 0 +#define CALLING_OVERHEAD_PORT_EXTERNAL_TO_INTERNAL 0 +#define CALLING_OVERHEAD_PORT_INTERNAL_TO_EXTERNAL 0 + +#define CALLING_OVERHEAD_IO_INITIALIZE 0 +#define CALLING_OVERHEAD_IO_OPEN 0 +#define CALLING_OVERHEAD_IO_CLOSE 0 +#define CALLING_OVERHEAD_IO_READ 0 +#define CALLING_OVERHEAD_IO_WRITE 0 +#define CALLING_OVERHEAD_IO_CONTROL 0 +#define CALLING_OVERHEAD_FATAL_ERROR_OCCURRED 0 +#define CALLING_OVERHEAD_RATE_MONOTONIC_CREATE 0 +#define CALLING_OVERHEAD_RATE_MONOTONIC_IDENT 0 +#define CALLING_OVERHEAD_RATE_MONOTONIC_DELETE 0 +#define CALLING_OVERHEAD_RATE_MONOTONIC_CANCEL 0 +#define CALLING_OVERHEAD_RATE_MONOTONIC_PERIOD 0 +#define CALLING_OVERHEAD_MULTIPROCESSING_ANNOUNCE 0 + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/c/src/lib/libbsp/i960/cvme961/shmsupp/addrconv.c b/c/src/lib/libbsp/i960/cvme961/shmsupp/addrconv.c new file mode 100644 index 0000000000..7702d22e67 --- /dev/null +++ b/c/src/lib/libbsp/i960/cvme961/shmsupp/addrconv.c @@ -0,0 +1,37 @@ +/* Shm_Convert_address + * + * This routine takes into account the peculiar short VME address + * of the CVME961 board. The CVME961 maps short address space + * 0xffffxxxx to 0xb400xxxx. + * + * Input parameters: + * address - address to convert + * + * Output parameters: + * returns - converted address + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include +#include "shm.h" + +void *Shm_Convert_address( + void *address +) +{ + rtems_unsigned32 workaddr = (rtems_unsigned32) address; + + if ( workaddr >= 0xffff0000 ) + workaddr = (workaddr & 0xffff) | 0xb4000000; + return ( (rtems_unsigned32 *)workaddr ); +} diff --git a/c/src/lib/libbsp/i960/cvme961/shmsupp/getcfg.c b/c/src/lib/libbsp/i960/cvme961/shmsupp/getcfg.c new file mode 100644 index 0000000000..f72e715b6f --- /dev/null +++ b/c/src/lib/libbsp/i960/cvme961/shmsupp/getcfg.c @@ -0,0 +1,98 @@ +/* void Shm_Get_configuration( localnode, &shmcfg ) + * + * This routine initializes, if necessary, and returns a pointer + * to the Shared Memory Configuration Table for the Cyclone CVME961. + * + * INPUT PARAMETERS: + * localnode - local node number + * shmcfg - address of pointer to SHM Config Table + * + * OUTPUT PARAMETERS: + * *shmcfg - pointer to SHM Config Table + * + * NOTES: CVME961 target system has onboard dual-ported memory. This + * file uses the USE_ONBOARD_RAM macro to determine if this + * RAM is to be used as the SHM. If so (i.e. USE_ONBOARD_RAM + * is set to 1), it is assumed that the master node's dual + * ported memory will be used and that it is configured + * correctly. The node owning the memory CANNOT access it + * using a local address. The "if" insures that the MASTER + * node uses a local address to access the dual-ported memory. + * + * The interprocessor interrupt used on the CVME961 is generated + * by the VIC068. The ICMS capablities of the VIC068 are used + * to generate interprocessor interrupts for up to eight nodes. + * + * The following table illustrates the configuration limitations: + * + * BUS MAX + * MODE ENDIAN NODES + * ========= ====== ======= + * POLLED LITTLE 2+ + * INTERRUPT LITTLE 2-8 + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include "shm.h" + +#define USE_ONBOARD_RAM 0 /* use onboard (1) or VME RAM */ + /* for SHM communications */ + +#define INTERRUPT 1 /* CVME961 target supports both */ +#define POLLING 0 /* polling and interrupt modes */ + + +shm_config_table BSP_shm_cfgtbl; + +void Shm_Get_configuration( + rtems_unsigned32 localnode, + shm_config_table **shmcfg +) +{ +#if ( USE_ONBOARD_RAM == 1 ) + if ( Shm_RTEMS_MP_Configuration->node == MASTER ) + BSP_shm_cfgtbl.base = (rtems_unsigned32 *)0x00300000; + else + BSP_shm_cfgtbl.base = (rtems_unsigned32 *)0x10300000; +#else + BSP_shm_cfgtbl.base = (rtems_unsigned32 *)0x20000000; +#endif + + BSP_shm_cfgtbl.length = 1 * MEGABYTE; + BSP_shm_cfgtbl.format = SHM_LITTLE; + + BSP_shm_cfgtbl.cause_intr = Shm_Cause_interrupt; + +#ifdef NEUTRAL_BIG + BSP_shm_cfgtbl.convert = (void *)CPU_swap_u32; +#else + BSP_shm_cfgtbl.convert = NULL_CONVERT; +#endif + +#if (POLLING==1) + BSP_shm_cfgtbl.poll_intr = POLLED_MODE; + BSP_shm_cfgtbl.Intr.address = NO_INTERRUPT; + BSP_shm_cfgtbl.Intr.value = NO_INTERRUPT; + BSP_shm_cfgtbl.Intr.length = NO_INTERRUPT; +#else + BSP_shm_cfgtbl.poll_intr = INTR_MODE; + BSP_shm_cfgtbl.Intr.address = + (rtems_unsigned32 *) (0xffff0021|((localnode-1) << 12)); + /* use ICMS0 */ + BSP_shm_cfgtbl.Intr.value = 1; + BSP_shm_cfgtbl.Intr.length = BYTE; +#endif + + *shmcfg = &BSP_shm_cfgtbl; + +} diff --git a/c/src/lib/libbsp/i960/cvme961/shmsupp/lock.c b/c/src/lib/libbsp/i960/cvme961/shmsupp/lock.c new file mode 100644 index 0000000000..de62ec670d --- /dev/null +++ b/c/src/lib/libbsp/i960/cvme961/shmsupp/lock.c @@ -0,0 +1,77 @@ +/* Shared Memory Lock Routines + * + * This shared memory locked queue support routine need to be + * able to lock the specified locked queue. Interrupts are + * disabled while the queue is locked to prevent preemption + * and deadlock when two tasks poll for the same lock. + * previous level. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include "cpu.h" +#include "bsp.h" +#include "shm.h" + +/* + * Shm_Initialize_lock + * + * Initialize the lock for the specified locked queue. + */ + +void Shm_Initialize_lock( + Shm_Locked_queue_Control *lq_cb +) +{ + lq_cb->lock = LQ_UNLOCKED; +} + +/* void _Shm_Lock( &lq_cb ) + * + * This shared memory locked queue support routine locks the + * specified locked queue. It disables interrupts to prevent + * a deadlock condition. + */ + +void Shm_Lock( + Shm_Locked_queue_Control *lq_cb +) +{ + rtems_unsigned32 isr_level, oldlock; + + rtems_interrupt_disable( isr_level ); + Shm_isrstat = isr_level; + while ( 1 ) { + atomic_modify( SHM_LOCK_VALUE, &lq_cb->lock, oldlock ); + if ( !(oldlock & SHM_LOCK_VALUE) ) + return; + delay( 28 ); /* delay 28 microseconds */ + } +} + +/* + * Shm_Unlock + * + * Unlock the lock for the specified locked queue. + */ + +void Shm_Unlock( + Shm_Locked_queue_Control *lq_cb +) +{ + rtems_unsigned32 isr_level; + + lq_cb->lock = SHM_UNLOCK_VALUE; + isr_level = Shm_isrstat; + rtems_interrupt_enable( isr_level ); +} + diff --git a/c/src/lib/libbsp/i960/cvme961/shmsupp/mpisr.c b/c/src/lib/libbsp/i960/cvme961/shmsupp/mpisr.c new file mode 100644 index 0000000000..827c5e4adb --- /dev/null +++ b/c/src/lib/libbsp/i960/cvme961/shmsupp/mpisr.c @@ -0,0 +1,70 @@ +/* Shm_isr_cvme961() + * + * NOTE: This routine is not used when in polling mode. Either + * this routine OR Shm_clockisr is used in a particular system. + * + * There must be sufficient time after the IACK (read at + * 0xb600000x) for the VIC068 to clear the interrupt request + * before the interrupt request is cleared from IPND (sf0). + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include +#include "shm.h" + +rtems_isr Shm_isr_cvme961( + rtems_vector_number vector +) +{ + rtems_unsigned32 vic_vector; + + /* enable_tracing(); */ + vic_vector = (*(volatile rtems_unsigned8 *)0xb6000007); + /* reset intr by reading */ + /* vector at IPL=3 */ + Shm_Interrupt_count += 1; + rtems_multiprocessing_announce(); + (*(volatile rtems_unsigned8 *)0xa000005f) = 0; /* clear ICMS0 */ + i960_clear_intr( 6 ); + +} + +/* void _Shm_setvec( ) + * + * This driver routine sets the SHM interrupt vector to point to the + * driver's SHM interrupt service routine. + * + * NOTE: See pp. 21-22, 36-39 of the CVME961 Manual for more info. + * + * Input parameters: NONE + * + * Output parameters: NONE + */ + +void Shm_setvec() +{ + rtems_unsigned32 isrlevel; + + rtems_interrupt_disable( isrlevel ); + /* set SQSIO4 CTL REG for */ + /* VME slave address */ + (*(rtems_unsigned8 *)0xc00000b0) = + (Shm_RTEMS_MP_Configuration->node - 1) | 0x10; + set_vector( Shm_isr_cvme961, 6, 1 ); + /* set ICMS Bector Base Register */ + (*(rtems_unsigned8 *)0xa0000053) = 0x60; /* XINT6 vector is 0x62 */ + /* set ICMS Intr Control Reg */ + (*(rtems_unsigned8 *)0xa0000047) = 0xeb; /* ICMS0 enabled, IPL=0 */ + (*(rtems_unsigned8 *)0xa000005f) = 0; /* clear ICMS0 */ + rtems_interrupt_enable( isrlevel ); +} diff --git a/c/src/lib/libbsp/i960/cvme961/startup/bspclean.c b/c/src/lib/libbsp/i960/cvme961/startup/bspclean.c new file mode 100644 index 0000000000..fb35e206be --- /dev/null +++ b/c/src/lib/libbsp/i960/cvme961/startup/bspclean.c @@ -0,0 +1,32 @@ +/* + * This routine is used to return control to the NINDY monitor + * and is automatically invoked at shutdown. + * + * NOTES: DOES NOT RETURN!!! + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include "bsp.h" + +void bsp_cleanup( void ) +{ + asm volatile( "mov 0,g0; \ + fmark ; \ + syncf ; \ + .word 0xfeedface ; \ + bx start" : : ); + /* The constant 0xfeedface is a magic word for break which + * is defined by NINDY. The branch extended restarts the + * application if the user types "go". + */ +} diff --git a/c/src/lib/libbsp/i960/cvme961/startup/bspstart.c b/c/src/lib/libbsp/i960/cvme961/startup/bspstart.c new file mode 100644 index 0000000000..afb9b7e733 --- /dev/null +++ b/c/src/lib/libbsp/i960/cvme961/startup/bspstart.c @@ -0,0 +1,163 @@ +/* bsp_start() + * + * This routine starts the application. It includes application, + * board, and monitor specific initialization and configuration. + * The generic CPU dependent initialization has been performed + * before this routine is invoked. + * + * INPUT: NONE + * + * OUTPUT: NONE + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include +#include "libcsupport.h" + + +#include "stackchk.h" + +/* + * The original table from the application and our copy of it with + * some changes. + */ + +extern rtems_configuration_table Configuration; + +rtems_configuration_table BSP_Configuration; + +rtems_cpu_table Cpu_table; + +/* Initialize whatever libc we are using + * called from postdriver hook + */ + +void bsp_libc_init() +{ + extern int end; + rtems_unsigned32 heap_start; + + heap_start = (rtems_unsigned32) &end; + if (heap_start & (CPU_ALIGNMENT-1)) + heap_start = (heap_start + CPU_ALIGNMENT) & ~(CPU_ALIGNMENT-1); + + RTEMS_Malloc_Initialize((void *) heap_start, 64 * 1024, 0); + + /* + * Set up for the libc handling. + */ + + if (BSP_Configuration.ticks_per_timeslice > 0) + libc_init(1); /* reentrant if possible */ + else + libc_init(0); /* non-reentrant */ + /* + * Initialize the stack bounds checker + */ + +#ifdef STACK_CHECKER_ON + Stack_check_Initialize(); +#endif +} + +int bsp_start( + int argc, + char **argv, + char **environp +) +{ + /* set node number in SQSIO4 CTL REG */ + + *((rtems_unsigned32 *)0xc00000b0) = + (Configuration.User_multiprocessing_table) ? + Configuration.User_multiprocessing_table->node : 0; + + Prcb = get_prcb(); + Ctl_tbl = Prcb->control_tbl; + + /* following configures the data breakpoint (which must be set + * before this is executed) to break on writes only. + */ + + Ctl_tbl->bpcon &= ~0x00cc0000; + i960_reload_ctl_group( 6 ); + + /* bit 31 of the Register Cache Control can be set to + * enable an alternative caching algorithm. It does + * not appear to help RTEMS. + */ + + /* Configure Number of Register Caches */ + + Prcb->reg_cache_cfg = 8; + i960_soft_reset( Prcb ); + + /* + * we do not use the pretasking_hook. + */ + + Cpu_table.pretasking_hook = NULL; + + Cpu_table.predriver_hook = bsp_libc_init; /* RTEMS resources available */ + + Cpu_table.postdriver_hook = NULL; /* Call our main() for constructors */ + + Cpu_table.idle_task = NULL; /* do not override system IDLE task */ + + Cpu_table.do_zero_of_workspace = TRUE; + + Cpu_table.interrupt_stack_size = 4096; + + Cpu_table.extra_system_initialization_stack = 0; + + Cpu_table.Prcb = Prcb; + + /* + * Copy the table + */ + + BSP_Configuration = Configuration; + + /* + * Add 1 region for the RTEMS Malloc + */ + + BSP_Configuration.maximum_regions++; + + /* + * Add 1 extension for newlib libc + */ + +#ifdef RTEMS_NEWLIB + BSP_Configuration.maximum_extensions++; +#endif + + /* + * Add another extension if using the stack checker + */ + +#ifdef STACK_CHECKER_ON + BSP_Configuration.maximum_extensions++; +#endif + + BSP_Configuration.work_space_start = (void *) + (RAM_END - BSP_Configuration.work_space_size); + + rtems_initialize_executive( &BSP_Configuration, &Cpu_table ); + /* does not return */ + + bsp_cleanup(); + + return 0; + +} diff --git a/c/src/lib/libbsp/i960/cvme961/startup/exit.c b/c/src/lib/libbsp/i960/cvme961/startup/exit.c new file mode 100644 index 0000000000..c412cad281 --- /dev/null +++ b/c/src/lib/libbsp/i960/cvme961/startup/exit.c @@ -0,0 +1,38 @@ +/* exit + * + * This routine is used to return control to the NINDY monitor + * and is automatically invoked by the STDIO exit() routine. + * + * INPUT: + * status - exit status + * + * OUTPUT: NONE + * + * NOTES: DOES NOT RETURN!!! + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include "bsp.h" + +void _exit( ) +{ + asm volatile( "mov 0,g0; \ + fmark ; \ + syncf ; \ + .word 0xfeedface ; \ + bx start" : : ); + /* The constant 0xfeedface is a magic word for break which + * is defined by NINDY. The branch extended restarts the + * application if the user types "go". + */ +} diff --git a/c/src/lib/libbsp/i960/cvme961/startup/linkcmds b/c/src/lib/libbsp/i960/cvme961/startup/linkcmds new file mode 100644 index 0000000000..5acbf22283 --- /dev/null +++ b/c/src/lib/libbsp/i960/cvme961/startup/linkcmds @@ -0,0 +1,48 @@ +/* + * This file contains directives for the GNU linker which are specific + * to the Cyclone CVME960/CVME961 boards. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +MEMORY + { + ram : org = 0x0, l = 1M + } + +SECTIONS +{ + .text 0x10000 : + { + text_start = . ; + _text_start = . ; + *(.text) + etext = ALIGN( 0x10 ) ; +/* _etext = .; */ + } + .data ADDR( .text ) + SIZEOF( .text ): + { + data_start = . ; + _data_start = .; + *(.data) + edata = ALIGN( 0x10 ) ; +/* _edata = .; */ + } + .bss ADDR( .data ) + SIZEOF( .data ): + { + bss_start = . ; +/* _bss_start = . ; */ + *(.bss) + *(COMMON) + end = . ; + _end = . ; + } +} diff --git a/c/src/lib/libbsp/i960/cvme961/startup/setvec.c b/c/src/lib/libbsp/i960/cvme961/startup/setvec.c new file mode 100644 index 0000000000..ea3706c3b3 --- /dev/null +++ b/c/src/lib/libbsp/i960/cvme961/startup/setvec.c @@ -0,0 +1,145 @@ +/* set_vector + * + * This routine attempts to perform all "generic" interrupt initialization + * for the specified XINT line. It is specific to the Cyclone CVME961 in + * that it knows which interrupts are initialized by the monitor, the + * characteristics of XINT5 (VIC068 clock tick), and that it assumes the + * i960 is processing interrupts in dedicated mode. It attempts to map + * XINTs to interrupt vectors in a fairly straght forward way. + * + * XINT USE VECTOR INTR TBL INDEX TRIGGERED + * ==== ============= ====== ============== ========= + * 0 VMEbus ERROR 0x02 0x03 EDGE + * 1 DRAM PARITY 0x12 0x13 EDGE + * 2 Z8530 0x22 0x23 LEVEL + * 3 SQUALL 0 0x52 0x53 ---- + * 4 Z8536 (SQSIO4) 0x72 0x73 LEVEL + * 5 TICK 0x32 0x33 EDGE + * 6 VIC068 0x62 0x63 LEVEL + * 7 UNUSED 0x42 0x43 LEVEL + * + * The interrupt handler is installed in both the cached and memory + * resident interrupt tables. The appropriate IMAP register is updated to + * reflect the vector selected by this routine. Global interrupts are + * enabled. If XINT5 is being installed, places it in trigger mode. + * Finally, set_vector_support() is invoked to install the new IMAP and + * ICON, unmask the XINT in IMASK, and lower the i960's interrupt + * level to 0. + * + * INPUT: + * func - interrupt handler entry point + * xint - external interrupt line + * type - 0 indicates raw hardware connect + * 1 indicates RTEMS interrupt connect + * + * RETURNS: + * address of previous interrupt handler + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include + +#include + +void print_prcb(); +void print_intr_info(); +void print_ipnd_imsk(); + +unsigned int Xint_2_Group_Map[8] = { 0, 1, 2, 5, 7, 3, 6, 4 }; + +i960_isr set_vector( /* returns old vector */ + rtems_isr_entry func, /* isr routine */ + unsigned int xint, /* XINT number */ + unsigned int type /* RTEMS or RAW */ +) +{ + i960_isr *intr_tbl, *cached_intr_tbl; + i960_isr saved_intr; + unsigned int vector, group, nibble; + unsigned int *imap; + + if ( xint > 7 ) + exit( 0x80 ); + + cached_intr_tbl = (i960_isr *) 0; + intr_tbl = (i960_isr *) Prcb->intr_tbl; + group = Xint_2_Group_Map[xint]; /* remap XINT to group */ + vector = (group << 4) + 2; /* direct vector num */ + + if ( type ) + rtems_interrupt_catch( func, vector, (rtems_isr_entry *) &saved_intr ); + else { + saved_intr = (i960_isr) intr_tbl[ vector ]; + /* return old vector */ + intr_tbl[ vector + 1 ] = /* normal vector table */ + cached_intr_tbl[ group ] = (i960_isr) func; /* cached vector */ + } + + if ( xint <= 3 ) imap = &Ctl_tbl->imap0; /* updating IMAP0 */ + else imap = &Ctl_tbl->imap1; /* updating IMAP1 */ + nibble = (xint % 4) * 4; + *imap &= ~(0xf << nibble); + *imap |= group << nibble; + + Ctl_tbl->icon &= ~0x00000400; /* enable global interrupts */ + Ctl_tbl->icon |= 0x00004000; /* fast sampling mode */ + switch ( xint ) { + case 0: Ctl_tbl->icon |= 0x00000004; break; + case 1: Ctl_tbl->icon |= 0x00000008; break; + case 2: Ctl_tbl->icon &= ~0x00000010; break; + case 4: Ctl_tbl->icon &= ~0x00000040; break; + case 5: Ctl_tbl->icon |= 0x00000080; break; + case 6: Ctl_tbl->icon &= ~0x00000100; break; + default: exit( 0x81 ); break; /* unsupported */ + } + + if ( xint == 4 ) { /* reprogram MCON for SQSIO4 */ + Ctl_tbl->mcon12 = 0x00002012; /* MCON12 - 0xCxxxxxxx */ + Ctl_tbl->mcon13 = 0x00000000; /* MCON13 - 0xDxxxxxxx */ + i960_reload_ctl_group( 5 ); /* update MCON12-MCON15 */ + } + + i960_unmask_intr( xint ); /* update IMSK */ + i960_reload_ctl_group( 1 ); /* update IMAP?/ICON */ + return( saved_intr ); /* return old vector */ +} + +void print_prcb() +{ + printf( "fault_table =0x%p\n", Prcb->fault_tbl ); + printf( "control_tbl =0x%p\n", Prcb->control_tbl ); + printf( "AC mask ov =0x%x\n", Prcb->initial_ac ); + printf( "fltconfig =0x%x\n", Prcb->fault_config ); + printf( "intr tbl =0x%p\n", Prcb->intr_tbl ); + printf( "systable =0x%p\n", Prcb->sys_proc_tbl ); + printf( "reserved =0x%x\n", Prcb->reserved ); + printf( "isr stk =0x%p\n", Prcb->intr_stack ); + printf( "ins cache =0x%x\n", Prcb->ins_cache_cfg ); + printf( "reg cache =0x%x\n", Prcb->reg_cache_cfg ); +} + +void print_intr_info() +{ + printf( "prcb =0x%p\n", Prcb ); + printf( "ctl_tbl =0x%p\n", Ctl_tbl ); + printf( "intr_tbl=0x%p\n", Prcb->intr_tbl ); + printf( "IMAP0 = 0x%x\n", Ctl_tbl->imap0 ); + printf( "IMAP1 = 0x%x\n", Ctl_tbl->imap1 ); + print_ipnd_imsk(); +} + +void print_ipnd_imsk() +{ + printf(" IPEND = 0x%x\n", i960_pend_intrs() ); + printf(" IMASK = 0x%x\n", i960_mask_intrs() ); +} diff --git a/c/src/lib/libbsp/i960/cvme961/timer/timer.c b/c/src/lib/libbsp/i960/cvme961/timer/timer.c new file mode 100644 index 0000000000..0a91d12a93 --- /dev/null +++ b/c/src/lib/libbsp/i960/cvme961/timer/timer.c @@ -0,0 +1,107 @@ +/* Timer_init() + * + * This routine initializes the Z8536 timer on the SQSIO4 SQUALL + * board for the CVME961 board. The timer is setup to provide a + * tick every 1 millisecond. + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * NOTE: This routine will not work if the optimizer is enabled + * for most compilers. The multiple writes to the Z8536 + * will be optimized away. + * + * It is important that the timer start/stop overhead be + * determined when porting or modifying this code. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + + +#include +#include +#include "z8536.h" + +#define TIMER 0xc00000a0 + +int Ttimer_val; +rtems_boolean Timer_driver_Find_average_overhead; + +void flush_reg(); +rtems_isr timerisr(); + +void Timer_initialize() +{ + set_vector( timerisr, 4, 0 ); /* install ISR */ + + i960_mask_intr( 5 ); /* disable VIC068 tick */ + flush_reg(); /* timed code starts clean */ + Ttimer_val = 0; /* clear timer ISR count */ + Z8x36_WRITE( TIMER, MASTER_INTR, 0x01 ); /* reset */ + Z8x36_WRITE( TIMER, MASTER_INTR, 0x00 ); /* clear reset */ + Z8x36_WRITE( TIMER, MASTER_CFG, 0x00 ); /* disable everything */ + Z8x36_WRITE( TIMER, CNT_TMR_VECTOR, 0x72 ); /* clear intr vector */ + Z8x36_WRITE( TIMER, MASTER_CFG, 0x20 ); /* clear intr info */ + Z8x36_WRITE( TIMER, MASTER_CFG, 0xe0 ); /* disable interrupts */ + Z8x36_WRITE( TIMER, MASTER_CFG, 0x20 ); /* clear intr info */ + Z8x36_WRITE( TIMER, MASTER_CFG, 0xe0 ); /* disable interrupts */ + Z8x36_WRITE( TIMER, MASTER_INTR, 0xe2 ); /* disable lower chain, */ + /* no vector, set right */ + /* justified addr and */ + /* master int enable */ + Z8x36_WRITE( TIMER, CT1_MODE_SPEC, 0x80 ); /* T1 continuous, and */ + /* cycle/pulse output */ + Z8x36_WRITE( TIMER, CT1_TIME_CONST_MSB, 0x00 ); + Z8x36_WRITE( TIMER, CT1_TIME_CONST_LSB, 0x00 ); + Z8x36_WRITE( TIMER, CT1_CMD_STATUS, 0xc0 ); /* set INTR enable (IE) */ + Z8x36_WRITE( TIMER, MASTER_CFG, 0x40 ); /* enable timer1 */ + Z8x36_WRITE( TIMER, CT1_CMD_STATUS, 0x06 ); /* set trigger command */ + /* (TCB) and gate */ + /* command (GCB) bits */ +} + +#define AVG_OVERHEAD 11 /* It typically takes 5.5 microseconds */ + /* (11 countdowns) to start/stop the timer. */ +#define LEAST_VALID 15 /* Don't trust a value lower than this */ + +int Read_timer() +{ + rtems_unsigned8 msb, lsb; + rtems_unsigned32 remaining, total; + + Z8x36_WRITE( TIMER, CT1_CMD_STATUS, 0xce ); /* read the counter value */ + Z8x36_READ( TIMER, CT1_CUR_CNT_MSB, msb ); + Z8x36_READ( TIMER, CT1_CUR_CNT_LSB, lsb ); + + remaining = 0xffff - ((msb << 8) + lsb); + total = (Ttimer_val * 0x10000) + remaining; + + if ( Timer_driver_Find_average_overhead == 1 ) + return total; /* in one-half microsecond units */ + else { + if ( total < LEAST_VALID ) + return 0; /* below timer resolution */ + return (total-AVG_OVERHEAD) >> 1; + } +} + +rtems_status_code Empty_function( void ) +{ + return RTEMS_SUCCESSFUL; +} + +void Set_find_average_overhead( + rtems_boolean find_flag +) +{ + Timer_driver_Find_average_overhead = find_flag; +} diff --git a/c/src/lib/libbsp/i960/cvme961/timer/timerisr.s b/c/src/lib/libbsp/i960/cvme961/timer/timerisr.s new file mode 100644 index 0000000000..02dc23cd5c --- /dev/null +++ b/c/src/lib/libbsp/i960/cvme961/timer/timerisr.s @@ -0,0 +1,59 @@ +/* timer_isr() + * + * This routine initializes the Z8536 timer on the SQSIO4 SQUALL + * board for the CVME961 board. The timer is setup to provide a + * tick every 0x10000 / 2 milliseconds. This is used to time + * executing code. + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include "asm.h" + +.set PORT_A, 0xc00000a8 # port A +.set PORT_B, 0xc00000a4 # port B +.set PORT_C, 0xc00000a0 # port C +.set CTL_PORT, 0xc00000ac # control port + +.set T1CSR, 0x0a # T1 command/status reg +.set RELOAD, 0x24 # clr IP & IUS,allow countdown + + PUBLIC(_timerisr) +SYM (_timerisr): + #ldconst 1,r4 + #modpc 0,r4,r4 # enable tracing + + ld _Ttimer_val,r6 # r6 = test timer + + ldconst T1CSR,r4 # r4 = T1 control status reg + stob r4,CTL_PORT # select T1CSR + ldconst RELOAD,r5 # r5 = reset value + stob r5,CTL_PORT # reset countdown + addo 1,r6,r6 + st r6,_Ttimer_val # increment test timer +loop_til_cleared: + clrbit 4,sf0,sf0 + bbs 4,sf0,loop_til_cleared +leaf: ret + + .leafproc _flush_reg, flush_reg.lf + .globl _flush_reg, flush_reg.lf +_flush_reg: + lda leaf,g14 # g14 = exit address +flush_reg.lf: + flushreg + mov g14,g0 # g0 = exit address + ldconst 0,g14 # set g14 for non-leaf + bx (g0) diff --git a/c/src/lib/libbsp/m68k/dmv152/clock/ckinit.c b/c/src/lib/libbsp/m68k/dmv152/clock/ckinit.c new file mode 100644 index 0000000000..d5f0f5e023 --- /dev/null +++ b/c/src/lib/libbsp/m68k/dmv152/clock/ckinit.c @@ -0,0 +1,101 @@ +/* Clock_init() + * + * This routine initializes the Z80386 1 on the MVME136 board. + * The tick frequency is 1 millisecond. + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include + +#include +#include +#include + +rtems_unsigned32 Clock_isrs; /* ISRs until next tick */ +volatile rtems_unsigned32 Clock_driver_ticks; + /* ticks since initialization */ +rtems_isr_entry Old_ticker; + +rtems_device_driver Clock_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *pargp, + rtems_id tid, + rtems_unsigned32 *rval +) +{ + Install_clock( Clock_isr ); +} + +void ReInstall_clock( + rtems_isr_entry clock_isr +) +{ + rtems_unsigned32 isrlevel = 0 ; + + rtems_interrupt_disable( isrlevel ); + (void) set_vector( clock_isr, TIMER_VECTOR, 1 ); + rtems_interrupt_enable( isrlevel ); +} + +void Install_clock( + rtems_isr_entry clock_isr +) +{ + rtems_unsigned8 data; + + Clock_driver_ticks = 0; + Clock_isrs = BSP_Configuration.microseconds_per_tick / 1000; + + if ( BSP_Configuration.ticks_per_timeslice ) { + Old_ticker = (rtems_isr_entry) set_vector( clock_isr, TIMER_VECTOR, 1 ); + + Z8x36_WRITE( TIMER, MASTER_CFG, 0xd4 ); + Z8x36_READ ( TIMER, MASTER_INTR, data ); + Z8x36_WRITE( TIMER, MASTER_INTR, (data & 0x7E) ); + Z8x36_WRITE( TIMER, CT1_TIME_CONST_MSB, 0x04 ); + Z8x36_WRITE( TIMER, CT1_TIME_CONST_LSB, 0xCE ); + Z8x36_WRITE( TIMER, CT1_MODE_SPEC, 0x83 ); + Z8x36_WRITE( TIMER, CNT_TMR_VECTOR, TIMER_VECTOR ); + Z8x36_WRITE( TIMER, CT1_CMD_STATUS, 0x20 ); + Z8x36_READ ( TIMER, MASTER_INTR, data ); + Z8x36_WRITE( TIMER, MASTER_INTR, (data & 0xDA) | 0x80 ); + + /* + * ACC_IC54 - interrupt 5 will be vectored and mapped to level 6 + */ + + data = (*(rtems_unsigned8 *)0x0D00000B); + (*(rtems_unsigned8 *)0x0D00000B) = (data & 0x7F) | 0x60; + + Z8x36_WRITE( TIMER, CT1_CMD_STATUS, 0xC6 ); + + atexit( Clock_exit ); + } +} + +void Clock_exit( void ) +{ + rtems_unsigned8 data; + + if ( BSP_Configuration.ticks_per_timeslice ) { + + Z8x36_READ ( TIMER, MASTER_INTR, data ); + Z8x36_WRITE( TIMER, MASTER_INTR, (data & 0x01) ); + /* do not restore old vector */ + + } +} diff --git a/c/src/lib/libbsp/m68k/dmv152/console/console.c b/c/src/lib/libbsp/m68k/dmv152/console/console.c new file mode 100644 index 0000000000..bb0f365b9c --- /dev/null +++ b/c/src/lib/libbsp/m68k/dmv152/console/console.c @@ -0,0 +1,186 @@ +/* + * This file contains the DMV152 console IO package. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#define D152_INIT + +#include +#include "console.h" +#include "bsp.h" + +/* console_initialize + * + * This routine initializes the console IO driver. + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * Return values: + */ + +rtems_device_driver console_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg, + rtems_id self, + rtems_unsigned32 *status +) +{ + *status = RTEMS_SUCCESSFUL; +} + + +/* is_character_ready + * + * This routine returns TRUE if a character is available. + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * Return values: + */ + +rtems_boolean is_character_ready( + char *ch +) +{ + rtems_unsigned8 rr_0; + + for ( ; ; ) { + Z8x30_READ_CONTROL( CONSOLE_CONTROL, RR_0, rr_0 ); + if ( !(rr_0 & RR_0_RX_DATA_AVAILABLE) ) + return( FALSE ); + + Z8x30_READ_DATA( CONSOLE_DATA, *ch ); + return( TRUE ); + } +} + +/* inbyte + * + * This routine reads a character from the SCC. + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * Return values: + * character read from SCC + */ + +char inbyte( void ) +{ + rtems_unsigned8 rr_0; + char ch; + + for ( ; ; ) { + Z8x30_READ_CONTROL( CONSOLE_CONTROL, RR_0, rr_0 ); + if ( (rr_0 & RR_0_RX_DATA_AVAILABLE) != 0 ) + break; + } + + Z8x30_READ_DATA( CONSOLE_DATA, ch ); + return ( ch ); +} + +/* outbyte + * + * This routine transmits a character out the SCC. It supports + * XON/XOFF flow control. + * + * Input parameters: + * ch - character to be transmitted + * + * Output parameters: NONE + */ + +void outbyte( + char ch +) +{ + rtems_unsigned8 rr_0; + char flow_control; + + for ( ; ; ) { + Z8x30_READ_CONTROL( CONSOLE_CONTROL, RR_0, rr_0 ); + if ( (rr_0 & RR_0_TX_BUFFER_EMPTY) != 0 ) + break; + } + + for ( ; ; ) { + Z8x30_READ_CONTROL( CONSOLE_CONTROL, RR_0, rr_0 ); + if ( (rr_0 & RR_0_RX_DATA_AVAILABLE) == 0 ) + break; + + Z8x30_READ_DATA( CONSOLE_DATA, flow_control ); + + if ( flow_control == XOFF ) + do { + do { + Z8x30_READ_CONTROL( CONSOLE_CONTROL, RR_0, rr_0 ); + } while ( (rr_0 & RR_0_RX_DATA_AVAILABLE) == 0 ); + Z8x30_READ_DATA( CONSOLE_DATA, flow_control ); + } while ( flow_control != XON ); + } + + Z8x30_WRITE_DATA( CONSOLE_DATA, ch ); +} + +/* + * __read -- read bytes from the serial port. Ignore fd, since + * we only have stdin. + */ + +int __read( + int fd, + char *buf, + int nbytes +) +{ + int i = 0; + + for (i = 0; i < nbytes; i++) { + *(buf + i) = inbyte(); + if ((*(buf + i) == '\n') || (*(buf + i) == '\r')) { + (*(buf + i++)) = '\n'; + (*(buf + i)) = 0; + break; + } + } + return (i); +} + +/* + * __write -- write bytes to the serial port. Ignore fd, since + * stdout and stderr are the same. Since we have no filesystem, + * open will only return an error. + */ + +int __write( + int fd, + char *buf, + int nbytes +) +{ + int i; + + for (i = 0; i < nbytes; i++) { + if (*(buf + i) == '\n') { + outbyte ('\r'); + } + outbyte (*(buf + i)); + } + return (nbytes); +} diff --git a/c/src/lib/libbsp/m68k/dmv152/include/bsp.h b/c/src/lib/libbsp/m68k/dmv152/include/bsp.h new file mode 100644 index 0000000000..7e4f423102 --- /dev/null +++ b/c/src/lib/libbsp/m68k/dmv152/include/bsp.h @@ -0,0 +1,169 @@ +/* bsp.h + * + * This include file contains all DMV152 board IO definitions. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __DMV152_h +#define __DMV152_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include + +/* + * Define the time limits for RTEMS Test Suite test durations. + * Long test and short test duration limits are provided. These + * values are in seconds and need to be converted to ticks for the + * application. + * + */ + +#define MAX_LONG_TEST_DURATION 300 /* 5 minutes = 300 seconds */ +#define MAX_SHORT_TEST_DURATION 3 /* 3 seconds */ + +/* + * Define the interrupt mechanism for Time Test 27 + */ + +/* use a VMEbus interrupt */ + +#define MUST_WAIT_FOR_INTERRUPT 1 + +#define Install_tm27_vector( handler ) \ + { \ + set_vector( (handler), 0x50, 1 ); \ + (*(volatile rtems_unsigned32 *)0x0d800024) = 0x50; /* set IVECT reg */ \ + (*(volatile rtems_unsigned8 *)0x0d00000c) = 0x40; /* set VIE reg */ \ + } + +#define Cause_tm27_intr() \ + (*(volatile rtems_unsigned8 *)0x0d000003) = 0x0f /* set VINT */ + +#define Clear_tm27_intr() /* no operation necessary */ + +#define Lower_tm27_intr() + +/* + * Simple spin delay in microsecond units for device drivers. + * This is very dependent on the clock speed of the target. + */ + +#define delay( microseconds ) \ + { register rtems_unsigned32 _delay=(microseconds); \ + register rtems_unsigned32 _tmp=123; \ + asm volatile( "0: \ + nbcd %0 ; \ + nbcd %0 ; \ + dbf %1,0b" \ + : "=d" (_tmp), "=d" (_delay) \ + : "0" (_tmp), "1" (_delay) ); \ + } + +/* macros */ + +#undef Z8x36_STATE0 +#undef Z8x36_WRITE +#undef Z8x36_READ + +#define Z8x36_STATE0 ( z8536 ) \ + { char *garbage; \ + (garbage) = *(VOL8(z8536+0x7)) \ + } + +#define Z8x36_WRITE( z8536, reg, data ) \ + *(VOL8(z8536+0x7)) = (reg); \ + *(VOL8(z8536+0x7)) = (data) + +#define Z8x36_READ( z8536, reg, data ) \ + *(VOL8(z8536+0x7)) = (reg); \ + (data) = *(VOL8(z8536+0x7)) + +/* + * ACC Register Addresses + */ + +#define ACC_BASE 0x0D000000 + +#define ACC_STAT0 ((volatile rtems_unsigned8 *) (ACC_BASE + 0x00)) +#define ACC_STAT1 ((volatile rtems_unsigned8 *) (ACC_BASE + 0x01)) +#define ACC_GENCTL ((volatile rtems_unsigned8 *) (ACC_BASE + 0x02)) +#define ACC_VINT ((volatile rtems_unsigned8 *) (ACC_BASE + 0x03)) +#define ACC_VREQ ((volatile rtems_unsigned8 *) (ACC_BASE + 0x04)) +#define ACC_VARB ((volatile rtems_unsigned8 *) (ACC_BASE + 0x05)) +#define ACC_ID ((volatile rtems_unsigned8 *) (ACC_BASE + 0x06)) +#define ACC_CTL2 ((volatile rtems_unsigned8 *) (ACC_BASE + 0x07)) +#define ACC_7IS ((volatile rtems_unsigned8 *) (ACC_BASE + 0x08)) +#define ACC_LIS ((volatile rtems_unsigned8 *) (ACC_BASE + 0x09)) +#define ACC_7IE ((volatile rtems_unsigned8 *) (ACC_BASE + 0x0A)) +#define ACC_LIE ((volatile rtems_unsigned8 *) (ACC_BASE + 0x0B)) +#define ACC_VIE ((volatile rtems_unsigned8 *) (ACC_BASE + 0x0C)) +#define ACC_IC10 ((volatile rtems_unsigned8 *) (ACC_BASE + 0x0D)) +#define ACC_IC32 ((volatile rtems_unsigned8 *) (ACC_BASE + 0x0E)) +#define ACC_IC54 ((volatile rtems_unsigned8 *) (ACC_BASE + 0x0F)) + +/* constants */ + +#define RAM_START 0 +#define RAM_END 0x100000 + +#define USE_CHANNEL_A 0 /* 1 = use channel A for console */ +#define USE_CHANNEL_B 1 /* 1 = use channel B for console */ + +#define TIMER 0x0c000000 +#define TIMER_VECTOR 0x4D + +#if (USE_CHANNEL_A == 1) +#define CONSOLE_CONTROL 0x0C800007 +#define CONSOLE_DATA 0x0C800005 +#elif (USE_CHANNEL_B == 1) +#define CONSOLE_CONTROL 0x0C800001 +#define CONSOLE_DATA 0x0C800003 +#endif + +/* Structures */ + +#ifdef D152_INIT +#undef EXTERN +#define EXTERN +#else +#undef EXTERN +#define EXTERN extern +#endif + +/* miscellaneous stuff assumed to exist */ + +extern rtems_configuration_table BSP_Configuration; + +extern m68k_isr M68Kvec[]; /* vector table address */ + +/* functions */ + +void bsp_cleanup( void ); + +m68k_isr set_vector( + rtems_isr_entry handler, + rtems_vector_number vector, + int type +); + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/c/src/lib/libbsp/m68k/dmv152/include/coverhd.h b/c/src/lib/libbsp/m68k/dmv152/include/coverhd.h new file mode 100644 index 0000000000..0033a50502 --- /dev/null +++ b/c/src/lib/libbsp/m68k/dmv152/include/coverhd.h @@ -0,0 +1,104 @@ +/* coverhd.h + * + * This include file has defines to represent the overhead associated + * with calling a particular directive from C on this target. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __COVERHD_h +#define __COVERHD_h + +#ifdef __cplusplus +extern "C" { +#endif + +#define CALLING_OVERHEAD_INITIALIZE_EXECUTIVE 2 +#define CALLING_OVERHEAD_SHUTDOWN_EXECUTIVE 1 +#define CALLING_OVERHEAD_TASK_CREATE 3 +#define CALLING_OVERHEAD_TASK_IDENT 2 +#define CALLING_OVERHEAD_TASK_START 2 +#define CALLING_OVERHEAD_TASK_RESTART 2 +#define CALLING_OVERHEAD_TASK_DELETE 1 +#define CALLING_OVERHEAD_TASK_SUSPEND 1 +#define CALLING_OVERHEAD_TASK_RESUME 2 +#define CALLING_OVERHEAD_TASK_SET_PRIORITY 2 +#define CALLING_OVERHEAD_TASK_MODE 2 +#define CALLING_OVERHEAD_TASK_GET_NOTE 2 +#define CALLING_OVERHEAD_TASK_SET_NOTE 2 +#define CALLING_OVERHEAD_TASK_WAKE_WHEN 4 +#define CALLING_OVERHEAD_TASK_WAKE_AFTER 1 +#define CALLING_OVERHEAD_INTERRUPT_CATCH 2 +#define CALLING_OVERHEAD_CLOCK_GET 4 +#define CALLING_OVERHEAD_CLOCK_SET 4 +#define CALLING_OVERHEAD_CLOCK_TICK 1 + +#define CALLING_OVERHEAD_TIMER_CREATE 2 +#define CALLING_OVERHEAD_TIMER_IDENT 1 +#define CALLING_OVERHEAD_TIMER_DELETE 2 +#define CALLING_OVERHEAD_TIMER_FIRE_AFTER 2 +#define CALLING_OVERHEAD_TIMER_FIRE_WHEN 5 +#define CALLING_OVERHEAD_TIMER_RESET 1 +#define CALLING_OVERHEAD_TIMER_CANCEL 1 +#define CALLING_OVERHEAD_SEMAPHORE_CREATE 2 +#define CALLING_OVERHEAD_SEMAPHORE_IDENT 1 +#define CALLING_OVERHEAD_SEMAPHORE_DELETE 2 +#define CALLING_OVERHEAD_SEMAPHORE_OBTAIN 2 +#define CALLING_OVERHEAD_SEMAPHORE_RELEASE 1 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_CREATE 2 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_IDENT 2 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_DELETE 1 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_SEND 2 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_URGENT 2 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_BROADCAST 2 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_RECEIVE 2 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_FLUSH 2 + +#define CALLING_OVERHEAD_EVENT_SEND 2 +#define CALLING_OVERHEAD_EVENT_RECEIVE 2 +#define CALLING_OVERHEAD_SIGNAL_CATCH 2 +#define CALLING_OVERHEAD_SIGNAL_SEND 2 +#define CALLING_OVERHEAD_PARTITION_CREATE 3 +#define CALLING_OVERHEAD_PARTITION_IDENT 2 +#define CALLING_OVERHEAD_PARTITION_DELETE 2 +#define CALLING_OVERHEAD_PARTITION_GET_BUFFER 2 +#define CALLING_OVERHEAD_PARTITION_RETURN_BUFFER 2 +#define CALLING_OVERHEAD_REGION_CREATE 3 +#define CALLING_OVERHEAD_REGION_IDENT 2 +#define CALLING_OVERHEAD_REGION_DELETE 1 +#define CALLING_OVERHEAD_REGION_GET_SEGMENT 3 +#define CALLING_OVERHEAD_REGION_RETURN_SEGMENT 2 +#define CALLING_OVERHEAD_PORT_CREATE 3 +#define CALLING_OVERHEAD_PORT_IDENT 2 +#define CALLING_OVERHEAD_PORT_DELETE 2 +#define CALLING_OVERHEAD_PORT_EXTERNAL_TO_INTERNAL 2 +#define CALLING_OVERHEAD_PORT_INTERNAL_TO_EXTERNAL 2 + +#define CALLING_OVERHEAD_IO_INITIALIZE 3 +#define CALLING_OVERHEAD_IO_OPEN 2 +#define CALLING_OVERHEAD_IO_CLOSE 2 +#define CALLING_OVERHEAD_IO_READ 2 +#define CALLING_OVERHEAD_IO_WRITE 2 +#define CALLING_OVERHEAD_IO_CONTROL 2 +#define CALLING_OVERHEAD_FATAL_ERROR_OCCURRED 1 +#define CALLING_OVERHEAD_RATE_MONOTONIC_CREATE 2 +#define CALLING_OVERHEAD_RATE_MONOTONIC_IDENT 2 +#define CALLING_OVERHEAD_RATE_MONOTONIC_DELETE 1 +#define CALLING_OVERHEAD_RATE_MONOTONIC_CANCEL 1 +#define CALLING_OVERHEAD_RATE_MONOTONIC_PERIOD 2 +#define CALLING_OVERHEAD_MULTIPROCESSING_ANNOUNCE 1 + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/c/src/lib/libbsp/m68k/dmv152/spurious/spinit.c b/c/src/lib/libbsp/m68k/dmv152/spurious/spinit.c new file mode 100644 index 0000000000..47f6e7c0be --- /dev/null +++ b/c/src/lib/libbsp/m68k/dmv152/spurious/spinit.c @@ -0,0 +1,46 @@ +/* Spurious_driver + * + * This routine installs spurious interrupt handlers for the DMV152. + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993. + * On-Line Applications Research Corporation (OAR). + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include +#include + +rtems_isr Spurious_Isr( + rtems_vector_number vector +) +{ + void *sp = 0; + + asm volatile ( "movea.l %%sp,%0 " : "=a" (sp) : "0" (sp) ); + + fprintf( stderr, "Vector 0x%x sp=0x%p\n", vector, sp ); +} + +rtems_device_driver Spurious_Initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *pargp, + rtems_id tid, + rtems_unsigned32 *rval +) +{ + rtems_vector_number vector; + + for ( vector = 0x40 ; vector <= 0xFF ; vector++ ) + (void) set_vector( Spurious_Isr, vector, 1 ); +} diff --git a/c/src/lib/libbsp/m68k/dmv152/startup/bspstart.c b/c/src/lib/libbsp/m68k/dmv152/startup/bspstart.c new file mode 100644 index 0000000000..a0ec9b7e71 --- /dev/null +++ b/c/src/lib/libbsp/m68k/dmv152/startup/bspstart.c @@ -0,0 +1,171 @@ +#define STACK_CHECKER_ON +/* bsp_start() + * + * This routine starts the application. It includes application, + * board, and monitor specific initialization and configuration. + * The generic CPU dependent initialization has been performed + * before this routine is invoked. + * + * INPUT: NONE + * + * OUTPUT: NONE + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include +#include +#include + +/* + * The original table from the application and our copy of it with + * some changes. + */ + +extern rtems_configuration_table Configuration; +rtems_configuration_table BSP_Configuration; + +rtems_cpu_table Cpu_table; + +/* Initialize whatever libc we are using + * called from postdriver hook + */ + +void bsp_libc_init() +{ + extern int end; + rtems_unsigned32 heap_start; + + heap_start = (rtems_unsigned32) &end; + if (heap_start & (CPU_ALIGNMENT-1)) + heap_start = (heap_start + CPU_ALIGNMENT) & ~(CPU_ALIGNMENT-1); + + RTEMS_Malloc_Initialize((void *) heap_start, 64 * 1024, 0); + + /* + * Set up for the libc handling. + */ + + if (BSP_Configuration.ticks_per_timeslice > 0) + libc_init(1); /* reentrant if possible */ + else + libc_init(0); /* non-reentrant */ + + /* + * Initialize the stack bounds checker + */ + +#ifdef STACK_CHECKER_ON + Stack_check_Initialize(); +#endif +} + +int bsp_start( + int argc, + char **argv, + char **environp +) +{ + m68k_isr *monitors_vector_table; + int index; + void *vbr; + + monitors_vector_table = (m68k_isr *)0; /* Monitor Vectors are at 0 */ + m68k_set_vbr( monitors_vector_table ); + + for ( index=2 ; index<=255 ; index++ ) + M68Kvec[ index ] = monitors_vector_table[ 32 ]; + + M68Kvec[ 2 ] = monitors_vector_table[ 2 ]; /* bus error vector */ + M68Kvec[ 4 ] = monitors_vector_table[ 4 ]; /* breakpoints vector */ + M68Kvec[ 9 ] = monitors_vector_table[ 9 ]; /* trace vector */ + + /* + * Uncommenting this seems to confuse/break the monitor on this board. + * It probably assumes the vector table is at 0. + */ + + /* m68k_set_vbr( &M68Kvec ); */ + + /* + * Adjust the VMEbus mode to round-robin. + */ + + /* + * This is only apparent with the shared memory driver which has not + * yet been supported on this target. + */ + + m68k_enable_caching(); + + /* + * we only use a hook to get the C library initialized. + */ + + Cpu_table.pretasking_hook = NULL; + + Cpu_table.predriver_hook = bsp_libc_init; /* RTEMS resources available */ + + Cpu_table.postdriver_hook = NULL; /* Call our main() for constructors */ + + Cpu_table.idle_task = NULL; /* do not override system IDLE task */ + + Cpu_table.do_zero_of_workspace = TRUE; + + m68k_get_vbr( vbr ); + Cpu_table.interrupt_vector_table = vbr; + + Cpu_table.interrupt_stack_size = 4096; + + Cpu_table.extra_system_initialization_stack = 0; + + /* + * Copy the table + */ + + BSP_Configuration = Configuration; + + BSP_Configuration.work_space_start = (void *) + (RAM_END - BSP_Configuration.work_space_size); + + /* + * Add 1 region for Malloc in libc_low + */ + + BSP_Configuration.maximum_regions++; + + /* + * Add 1 extension for newlib libc + */ + +#ifdef RTEMS_NEWLIB + BSP_Configuration.maximum_extensions++; +#endif + + /* + * Add another extension if using the stack checker + */ + +#ifdef STACK_CHECKER_ON + BSP_Configuration.maximum_extensions++; +#endif + + rtems_initialize_executive( &BSP_Configuration, &Cpu_table ); + /* does not return */ + + /* Clock_exit is done as an atexit() function */ + + VME_interrupt_Disable( 0xff ); + + /* return like a "normal" subroutine to the monitor */ + return 0; +} diff --git a/c/src/lib/libbsp/m68k/dmv152/startup/linkcmds b/c/src/lib/libbsp/m68k/dmv152/startup/linkcmds new file mode 100644 index 0000000000..76f43eec97 --- /dev/null +++ b/c/src/lib/libbsp/m68k/dmv152/startup/linkcmds @@ -0,0 +1,48 @@ +/* + * This file contains directives for the GNU linker which are specific + * to the DY-4 DMV152/SVME153 boards. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +MEMORY + { + ram : org = 0x12800, l = 1M + } + +SECTIONS +{ + .text 0x12800 : + { + text_start = . ; + _text_start = . ; + *(.text) + etext = ALIGN( 0x10 ) ; + _etext = .; + } + .data ADDR( .text ) + SIZEOF( .text ): + { + data_start = . ; + _data_start = . ; + *(.data) + edata = ALIGN( 0x10 ) ; + _edata = .; + } + .bss ADDR( .data ) + SIZEOF( .data ): + { + bss_start = . ; + _bss_start = . ; + *(.bss) + *(COMMON) + end = . ; + _end = . ; + } +} diff --git a/c/src/lib/libbsp/m68k/dmv152/startup/vmeintr.c b/c/src/lib/libbsp/m68k/dmv152/startup/vmeintr.c new file mode 100644 index 0000000000..700b06776d --- /dev/null +++ b/c/src/lib/libbsp/m68k/dmv152/startup/vmeintr.c @@ -0,0 +1,60 @@ +/* vmeintr.c + * + * VMEbus support routines for the DMV152. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include +#include + +/*PAGE + * + * VME_interrupt_Disable + * + */ + +void VME_interrupt_Disable ( + VME_interrupt_Mask mask /* IN */ +) +{ + volatile rtems_unsigned8 *VME_interrupt_enable; + rtems_unsigned8 value; + + VME_interrupt_enable = ACC_VIE; + value = *VME_interrupt_enable; + + value &= ~mask; /* turn off interrupts for all levels in mask */ + + *VME_interrupt_enable = value; +} + +/*PAGE + * + * VME_interrupt_Enable + * + */ + +void VME_interrupt_Enable ( + VME_interrupt_Mask mask /* IN */ +) +{ + volatile rtems_unsigned8 *VME_interrupt_enable; + rtems_unsigned8 value; + + VME_interrupt_enable = ACC_VIE; + value = *VME_interrupt_enable; + + value |= mask; /* turn on interrupts for all levels in mask */ + + *VME_interrupt_enable = value; +} diff --git a/c/src/lib/libbsp/m68k/dmv152/timer/timer.c b/c/src/lib/libbsp/m68k/dmv152/timer/timer.c new file mode 100644 index 0000000000..2e91a671df --- /dev/null +++ b/c/src/lib/libbsp/m68k/dmv152/timer/timer.c @@ -0,0 +1,105 @@ +/* timer.c + * + * NOTE: These routines will not work if the optimizer is enabled + * for some compilers. The multiple writes to the Z8036 + * may be optimized away. + * + * It is important that the timer start/stop overhead be + * determined when porting or modifying this code. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + + +#include +#include + +int Ttimer_val; +rtems_boolean Timer_driver_Find_average_overhead; + +rtems_isr timerisr(); + +void Timer_initialize() +{ + rtems_unsigned8 data; + + (void) set_vector( timerisr, TIMER_VECTOR, 0 ); /* install ISR */ + + Ttimer_val = 0; /* clear timer ISR count */ + Z8x36_READ ( TIMER, MASTER_INTR, data ); + Z8x36_WRITE( TIMER, MASTER_INTR, (data & 0x01) ); + + Z8x36_WRITE( TIMER, MASTER_CFG, 0xd4 ); + Z8x36_READ ( TIMER, MASTER_INTR, data ); + Z8x36_WRITE( TIMER, MASTER_INTR, (data & 0x7E) ); + Z8x36_WRITE( TIMER, CT1_TIME_CONST_MSB, 0x00 ); + Z8x36_WRITE( TIMER, CT1_TIME_CONST_LSB, 0x00 ); + Z8x36_WRITE( TIMER, CT1_MODE_SPEC, 0x87 ); + Z8x36_WRITE( TIMER, CNT_TMR_VECTOR, TIMER_VECTOR ); + Z8x36_WRITE( TIMER, CT1_CMD_STATUS, 0x20 ); + Z8x36_WRITE( TIMER, CT1_CMD_STATUS, 0x26 ); + Z8x36_READ ( TIMER, MASTER_INTR, data ); + Z8x36_WRITE( TIMER, MASTER_INTR, (data & 0xDA) | 0x80 ); + + Z8x36_WRITE( TIMER, CT1_CMD_STATUS, 0xC6 ); + + /* + * ACC_IC54 - interrupt 5 will be vectored and mapped to level 6 + */ + + data = (*(rtems_unsigned8 *)0x0D00000B); + (*(rtems_unsigned8 *)0x0D00000B) = (data & 0x0F) | 0x60; + +} + +#define AVG_OVERHEAD 9 /* It typically takes 3.65 microseconds */ + /* (9 countdowns) to start/stop the timer. */ +#define LEAST_VALID 10 /* Don't trust a value lower than this */ + +int Read_timer() +{ + rtems_unsigned8 data; + rtems_unsigned8 msb, lsb; + rtems_unsigned32 remaining, total; + + Z8x36_WRITE( TIMER, CT1_CMD_STATUS, 0xce ); /* read the counter value */ + Z8x36_READ( TIMER, CT1_CUR_CNT_MSB, msb ); + Z8x36_READ( TIMER, CT1_CUR_CNT_LSB, lsb ); + + remaining = 0x10000 - ((msb << 8) + lsb); + total = (Ttimer_val * 0x10000) + remaining; + + Z8x36_READ ( TIMER, MASTER_INTR, data ); + Z8x36_WRITE( TIMER, MASTER_INTR, (data & 0x01) ); + + /* do not restore old vector */ + if ( Timer_driver_Find_average_overhead == 1 ) + return total; /* in countdown units */ + + if ( total < LEAST_VALID ) + return 0; /* below timer resolution */ + + /* Clocked at 2.4615 Mhz */ + + return (int)(((float)(total-AVG_OVERHEAD)) / 2.4615 * 2.0); +} + +rtems_status_code Empty_function( void ) +{ + return RTEMS_SUCCESSFUL; +} + +void Set_find_average_overhead( + rtems_boolean find_flag +) +{ + Timer_driver_Find_average_overhead = find_flag; +} diff --git a/c/src/lib/libbsp/m68k/dmv152/timer/timerisr.s b/c/src/lib/libbsp/m68k/dmv152/timer/timerisr.s new file mode 100644 index 0000000000..d7ec593c62 --- /dev/null +++ b/c/src/lib/libbsp/m68k/dmv152/timer/timerisr.s @@ -0,0 +1,38 @@ +/* timer_isr() + * + * This routine provides the ISR for the Z8536 timer on the DMV152 + * board. The timer is set up to generate an interrupt at maximum + * intervals. + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include "asm.h" + +BEGIN_CODE + +.set TIMER, 0x0c000007 | port A +.set CT1_CMD_STATUS, 0x0a | command status register +.set RELOAD, 0x26 | clr IP & IUS,allow countdown + + PUBLIC(timerisr) +SYM (timerisr): + movb #CT1_CMD_STATUS,TIMER | set pointer to cmd status reg + movb #RELOAD,TIMER | reload countdown + addql #1, SYM (Ttimer_val) | increment timer value + rte + +END_CODE +END diff --git a/c/src/lib/libbsp/m68k/idp/README b/c/src/lib/libbsp/m68k/idp/README new file mode 100644 index 0000000000..5479acf383 --- /dev/null +++ b/c/src/lib/libbsp/m68k/idp/README @@ -0,0 +1,31 @@ +This board support package has not been tested with multiprocessor +or the timing support. The uniprocessor IDP package was tested though +with a fairly large application (although bugs may exist). The +$RTEMS_ROOT/src/tests/Makefile should therefore have the samples and +the tests directories compiled first with the tmtests (timing) and +multiprocessor directories optional. + +Let me know if you have any problems or bug fixes. Bug fixes are greatly +appreciated. I do not work for RTEMS or am a member of the RTEMS support +group in any way, however. I am just one of many that appreciate +"free" software and enjoy contributing when possible :). You can do it too! + + -- doug mcbride + mcbride@rodin.colorado.edu + +============================================================== +Notes: Make sure that -msoft-float is defined when compiling in the +newlib-beta-rtems/newlib/msoft-float directory subtree. You also probably +want to add the following line to line 413 of +newlib-beta-rtems/newlib/msoft-float/libc/stdio/vfprintf.c: + +#define INTEGER_ONLY + +That allows you to pass most of the paranoia test in the samples +directory of RTEMS although you can't see the floating point values actually +printed (software floating point tends to make that difficult anyway). +In order to pass the whole paranoia test (with one flaw), however, I had to +comment out the following line in milestone 140 (why?): + +/* printf ("Testing X^((X + 1) / (X - 1)) vs. exp(2) = %.17e as X -> 1.\n", + Exp2); */ diff --git a/c/src/lib/libbsp/m68k/idp/clock/ckinit.c b/c/src/lib/libbsp/m68k/idp/clock/ckinit.c new file mode 100644 index 0000000000..abee1418cc --- /dev/null +++ b/c/src/lib/libbsp/m68k/idp/clock/ckinit.c @@ -0,0 +1,126 @@ +/* Clock_init() + * + * + * This is modified by Doug McBride to get it to work for the MC68EC040 + * IDP board. The below comments are kept to show that some prior work + * was done in the area and the modifications performed was application + * specific for the IDP board to port it to. + * + * This routine initializes the mc68230 on the MC68EC040 board. + * The tick frequency is 40 milliseconds. + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include + +#include "rtems.h" +#include "clockdrv.h" +#include "bsp.h" +#include "cpu.h" + +rtems_unsigned32 Clock_isrs; /* ISRs until next tick */ +volatile rtems_unsigned32 Clock_driver_ticks; + /* ticks since initialization */ +rtems_isr_entry Old_ticker; + +extern rtems_configuration_table Configuration; +extern void led_putnum(); +void Disable_clock(); + +#define TIMER_VECTOR 0x4D + +rtems_device_driver Clock_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *pargp, + rtems_id tid, + rtems_unsigned32 *rval +) +{ + Install_clock( Clock_isr ); +} + +void ReInstall_clock( clock_isr ) +rtems_isr_entry clock_isr; +{ + rtems_unsigned32 isrlevel = 0 ; + + rtems_interrupt_disable( isrlevel ); + (void) set_vector( clock_isr, TIMER_VECTOR, 1 ); + rtems_interrupt_enable( isrlevel ); +} + +/* The following was added for debugging purposes */ +void Disable_clock() +{ + /* Disable timer */ + MC68230_WRITE (TCR, 0x00); +} + +void Install_clock( clock_isr ) +rtems_isr_entry clock_isr; +{ + Clock_driver_ticks = 0; + Clock_isrs = (int)(Configuration.microseconds_per_tick / 1000); + + if ( Configuration.ticks_per_timeslice ) { +/* led_putnum('c'); * for debugging purposes */ + Old_ticker = (rtems_isr_entry) set_vector( clock_isr, TIMER_VECTOR, 1 ); + + /* Disable timer for initialization */ + MC68230_WRITE (TCR, 0x00); + + /* some PI/T initialization stuff here -- see comment in the ckisr.c + file in this directory to understand why I use the values that I do */ + /* Set up the interrupt vector on the MC68230 chip: + TIVR = TIMER_VECTOR; */ + MC68230_WRITE (TIVR, TIMER_VECTOR); + + /* Set CPRH through CPRL to 193 (not 203) decimal for countdown--see ckisr.c + CPRH = 0x00; + CPRM = 0x00; + CPRL = 0xC1; */ + MC68230_WRITE (CPRH, 0x00); + MC68230_WRITE (CPRM, 0x00); + MC68230_WRITE (CPRL, 0xC1); + + /* Enable timer and use it as an external periodic interrupt generator + TCR = 0xA1; */ +/* led_putnum('a'); * for debugging purposes */ + MC68230_WRITE (TCR, 0xA1); + + /* + * Schedule the clock cleanup routine to execute if the application exits. + */ + atexit( Clock_exit ); + } +} + +void Clock_exit( void ) +{ + rtems_unsigned8 data; + + if ( Configuration.ticks_per_timeslice ) { + + /* disable timer + data = TCR; + TCR = (data & 0xFE); */ + MC68230_READ (TCR, data); + MC68230_WRITE (TCR, (data & 0xFE)); + + /* do not restore old vector */ + } +} diff --git a/c/src/lib/libbsp/m68k/idp/console/console.c b/c/src/lib/libbsp/m68k/idp/console/console.c new file mode 100644 index 0000000000..7bb720c120 --- /dev/null +++ b/c/src/lib/libbsp/m68k/idp/console/console.c @@ -0,0 +1,216 @@ +/* + * This file contains the Motorola IDP console IO package. + * + * Written by Doug McBride, Colorado Space Grant College + * Based off of the board support packages of RTEMS + * + * Updated to RTEMS 3.2.0 by Joel Sherrill. + * + * $Id$ + */ + +#define MIDP_INIT + +#include "rtems.h" +#include "console.h" +#include "bsp.h" + +#include "ringbuf.h" + +Ring_buffer_t Buffer[ 2 ]; + +rtems_isr C_Receive_ISR(rtems_vector_number vector); + + +/* console_initialize + * + * This routine initializes the console IO driver. + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * Return values: + */ + +rtems_device_driver console_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg, + rtems_id self, + rtems_unsigned32 *status +) +{ + + Ring_buffer_Initialize( &Buffer[ 0 ] ); + Ring_buffer_Initialize( &Buffer[ 1 ] ); + + init_pit(); + + *status = RTEMS_SUCCESSFUL; +} + + +/* is_character_ready + * + * This routine returns TRUE if a character is available. + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * Return values: + */ + +rtems_boolean is_character_ready( + char *ch, + int port +) +{ + if ( Ring_buffer_Is_empty( &Buffer[ port ] ) ) + return FALSE; + + Ring_buffer_Remove_character( &Buffer[ port ], *ch ); + return TRUE; +} + +/* quick_char_check + * + * This routine returns TRUE if a character is available. + * It is different from above because it does not disturb the ring buffer + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * Return values: + */ + +rtems_boolean quick_char_check( + int port +) +{ + if ( Ring_buffer_Is_empty( &Buffer[ port ] ) ) + return FALSE; + + return TRUE; +} + +/* inbyte + * + * This routine reads a character from the UART through a buffer. + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * Return values: + * character read from UART + */ + +char inbyte( + int port +) +{ + unsigned char tmp_char; + + /* If you come into this routine without checking is_character_ready() first + and you want nonblocking code, then it's your own fault */ + + while ( !is_character_ready( &tmp_char, port ) ); + + return tmp_char; +} + + +/* outbyte + * + * This routine transmits a character out the M68681. It supports + * XON/XOFF flow control. + * + * Input parameters: + * ch - character to be transmitted + * + * Output parameters: NONE + */ + +void outbyte( + char ch, + int port +) +{ + switch ( port ) { + case 0: + transmit_char( ch ); + break; + case 1: + transmit_char_portb( ch ); + break; + } + +} + +/* + * __read -- read bytes from the serial port. Ignore fd, since + * we only have stdin. + */ + +int __read( + int fd, + char *buf, + int nbytes +) +{ + int i = 0; + int port; + + /* + * Map port A to stdin, stdout, and stderr. + * Map everything else to port B. + */ + + if ( fd <= 2 ) port = 0; + else port = 1; + + for (i = 0; i < nbytes; i++) { + *(buf + i) = inbyte( port ); + if ((*(buf + i) == '\n') || (*(buf + i) == '\r')) { + (*(buf + i++)) = '\n'; + (*(buf + i)) = 0; + break; + } + } + return (i); +} + +/* + * __write -- write bytes to the serial port. Ignore fd, since + * stdout and stderr are the same. Since we have no filesystem, + * open will only return an error. + */ + +int __write( + int fd, + char *buf, + int nbytes +) +{ + int i; + int port; + + /* + * Map port A to stdin, stdout, and stderr. + * Map everything else to port B. + */ + + if ( fd <= 2 ) port = 0; + else port = 1; + + for (i = 0; i < nbytes; i++) { + if (*(buf + i) == '\n') { + outbyte ('\r', port ); + } + outbyte (*(buf + i), port ); + } + return (nbytes); +} diff --git a/c/src/lib/libbsp/m68k/idp/console/duart.c b/c/src/lib/libbsp/m68k/idp/console/duart.c new file mode 100644 index 0000000000..c3ee92b75b --- /dev/null +++ b/c/src/lib/libbsp/m68k/idp/console/duart.c @@ -0,0 +1,170 @@ +/*######################################################### +# +# This code is a modified version of what you will find at the +# end of the IDP User's manual. The original code is copyrighted +# by Motorola and Motorola Semiconductor Products as well as +# Motorola Software products group. +# +# Modifications to the original IDP code by Doug McBride, Colorado +# Space Grant College. Modifications include a means of accessing +# port B of the duart as well as port A as well as modifications for +# buffering and RTEMS support. Modifications are provided +# as is and may not be correct. +# +# Rob Savoye provided the format for the mc68681 header file +# +# Joel Sherrill provided inspiration for recoding my original assembly +# for this file into C (a good idea) +# +##########################################################*/ + +#include "mc68230.h" +#include "mc68681.h" +#include "ringbuf.h" +#include "rtems.h" +#include "bsp.h" + +rtems_isr C_Receive_ISR(rtems_vector_number vector); +extern Ring_buffer_t Buffer[]; + +extern unsigned char inbuf[]; +extern unsigned char inbuf_portb[]; +extern unsigned tail; +extern unsigned tail_portb; +unsigned char Pit_initialized = 0; + +/*##################################################################### +# The volatile routine to initialize the duart -- port a and port b +######################################################################*/ +volatile void init_pit() +{ + /* Disable ports A & B while configuring PIT */ + MC68681_WRITE(DUART_IMR, 0x00); /* disable imr */ + MC68681_WRITE(DUART_CRA, 0x08); /* disable port a transmitter */ + MC68681_WRITE(DUART_CRA, 0x02); /* disable port a receiver */ + MC68681_WRITE(DUART_CRB, 0x08); /* disable port b transmitter */ + MC68681_WRITE(DUART_CRB, 0x02); /* disable port b receiver */ + + /* install ISR for ports A and B */ + set_vector(C_Receive_ISR, (VECT+H3VECT), 1); + + /* initialize pit */ + MC68230_WRITE(PGCR, 0x00); /* set mode to 0 -- disable all ports */ + MC68230_WRITE(PSRR, 0x18); /* set up pirq and piack */ + MC68230_WRITE(PBDDR, 0x00); /* all pins on port b are input */ + MC68230_WRITE(PBCR, 0x82); /* submode 1x, h3 interrupt enabled */ + MC68230_WRITE(PIVR, VECT); /* setup pivr */ + MC68230_WRITE(PGCR, 0x20); /* turn on all ports */ + + /* For some reason, the reset of receiver/transmitter only works for + the first time around -- it garbles the output otherwise (e.g., sp21) */ + if (!Pit_initialized) + { + /* now initialize the duart registers on port b */ + /* WARNING:OPTIMIZER MAY ONLY EXECUTE THIRD STATEMENT IF NOT VOLATILE */ + MC68681_WRITE(DUART_CRB, 0x30); /* reset tx, channel b */ + MC68681_WRITE(DUART_CRB, 0x20); /* reset rx, channel b */ + MC68681_WRITE(DUART_CRB, 0x10); /* reset mr pointer, channel b */ + + /* now initialize the duart registers on port a */ + /* WARNING:OPTIMIZER MAY ONLY EXECUTE THIRD STATEMENT IF NOT VOLATILE */ + MC68681_WRITE(DUART_CRA, 0x30); /* reset tx, channel a */ + MC68681_WRITE(DUART_CRA, 0x20); /* reset rx, channel a */ + MC68681_WRITE(DUART_CRA, 0x10); /* reset mr pointer, channel a */ + Pit_initialized = 1; + } + + /* init the general registers of the duart */ + MC68681_WRITE(DUART_IVR, 0x0f); /* init ivr */ + MC68681_WRITE(DUART_IMR, 0x22); /* init imr */ + MC68681_WRITE(DUART_ACR, 0x00); /* init acr */ + MC68681_WRITE(DUART_CTUR, 0x00); /* init ctur */ + MC68681_WRITE(DUART_CTLR, 0x02); /* init ctlr */ + MC68681_WRITE(DUART_OPCR, 0x00); /* init opcr */ + MC68681_WRITE(DUART_OPRSET, 0x01); /* init cts */ + + /* init the actual serial port for port a */ + MC68681_WRITE(DUART_CSRA, 0xbb); /* init csra -- 9600 baud */ + MC68681_WRITE(DUART_MR1A, 0x13); /* init mr1a */ + MC68681_WRITE(DUART_MR2A, 0x07); /* init mr2a */ + MC68681_WRITE(DUART_CRA, 0x05); /* init cra */ + + /* init the actual serial port for port b */ + MC68681_WRITE(DUART_CSRB, 0xbb); /* init csrb -- 9600 baud */ +#define EIGHT_BITS_NO_PARITY +#ifdef EIGHT_BITS_NO_PARITY + MC68681_WRITE(DUART_MR1B, 0x13); /* init mr1b */ +#else /* 7 bits, even parity */ + MC68681_WRITE(DUART_MR1B, 0x02); /* init mr1b */ +#endif + MC68681_WRITE(DUART_MR2B, 0x07); /* init mr2b -- one stop bit */ + MC68681_WRITE(DUART_CRB, 0x05); /* init crb */ +} + +/*##################################################################### +# interrupt handler for receive of character from duart on ports A & B +#####################################################################*/ +rtems_isr C_Receive_ISR(rtems_vector_number vector) +{ + volatile unsigned char *_addr; + + _addr = (unsigned char *) (PIT_ADDR + PITSR); + *_addr = 0x04; /* clear pit interrupt */ + + /* Let's check port A first for input */ + _addr = (unsigned char *) (DUART_ADDR + DUART_SRA); + if (*_addr & 0x01) /* extract rcvrdy on port A */ + { + /* Read input on port A */ + _addr = (unsigned char *) (DUART_ADDR + DUART_RBA); + Ring_buffer_Add_character( &Buffer[ 0 ], *_addr ); + } + else /* If not on port A, let's check port B */ + { + _addr = (unsigned char *) (DUART_ADDR + DUART_SRB); + if (*_addr & 0x01) /* extract rcvrdy on port B */ + { + /* Read input on port B */ + _addr = (unsigned char *) (DUART_ADDR + DUART_RBB); + Ring_buffer_Add_character( &Buffer[ 1 ], *_addr ); + } + /* if not ready on port A or port B, must be an error */ + /* if error, get out so that fifo is undisturbed */ + } +} + +/*##################################################################### +# This is the routine that actually transmits a character one at a time +# This routine transmits on port A of the IDP board +#####################################################################*/ +void transmit_char(char ch) +{ + volatile unsigned char *_addr; + + /* Get SRA (extract txrdy) */ + _addr = (unsigned char *) (DUART_ADDR + DUART_SRA); + while (!(*_addr & 0x04)) + { + } + + /* transmit character over port A */ + MC68681_WRITE(DUART_TBA, ch); +} + +/*##################################################################### +# This is the routine that actually transmits a character one at a time +# This routine transmits on port B of the IDP board +#####################################################################*/ +void transmit_char_portb(char ch) +{ + volatile unsigned char *_addr; + + /* Get SRB (extract txrdy) */ + _addr = (unsigned char *) (DUART_ADDR + DUART_SRB); + while (!(*_addr & 0x04)) + { + } + + /* transmit character over port B */ + MC68681_WRITE(DUART_TBB, ch); +} diff --git a/c/src/lib/libbsp/m68k/idp/console/leds.c b/c/src/lib/libbsp/m68k/idp/console/leds.c new file mode 100644 index 0000000000..4d7abaf93d --- /dev/null +++ b/c/src/lib/libbsp/m68k/idp/console/leds.c @@ -0,0 +1,80 @@ +/* + * leds.c -- control the led's on a Motorola mc68ec0x0 board. + * Written by rob@cygnus.com (Rob Savoye) + */ +#include "leds.h" + +void zylons(); +void led_putnum(); +void clear_leds(); + +/* + * led_putnum -- print a hex number on the LED. the value of num must be a char with + * the ascii value. ie... number 0 is '0', a is 'a', ' ' (null) clears + * the led display. + * Setting the bit to 0 turns it on, 1 turns it off. + * the LED's are controlled by setting the right bit mask in the base + * address. + * The bits are: + * [d.p | g | f | e | d | c | b | a ] is the byte. + * + * The locations are: + * + * a + * ----- + * f | | b + * | g | + * ----- + * | | + * e | | c + * ----- + * d . d.p (decimal point) + */ +void +led_putnum ( num ) +char num; +{ + static unsigned char *leds = (unsigned char *)LED_ADDR; + static unsigned char num_bits [18] = { + 0xff, /* clear all */ + 0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x98, /* numbers 0-9 */ + 0x98, 0x20, 0x3, 0x27, 0x21, 0x4, 0xe /* letters a-f */ + }; + + if (num >= '0' && num <= '9') + num = (num - '0') + 1; + + if (num >= 'a' && num <= 'f') + num = (num - 'a') + 12; + + if (num == ' ') + num = 0; + + *leds = num_bits[(int)num]; +} + +/* This procedure added by Doug McBride, Colorado Space Grant College -- + Probably should be a macro instead */ +void +clear_leds ( ) +{ + static unsigned char *leds = (unsigned char *)LED_ADDR; + *leds = 0xFF; +} + +/* + * zylons -- draw a rotating pattern. NOTE: this function never returns. + */ +void +zylons() +{ + unsigned char *leds = (unsigned char *)LED_ADDR; + unsigned char curled = 0xfe; + + while (1) + { + *leds = curled; + curled = (curled >> 1) | (curled << 7); + delay ( 8000 ); + } +} diff --git a/c/src/lib/libbsp/m68k/idp/console/mc68ec.c b/c/src/lib/libbsp/m68k/idp/console/mc68ec.c new file mode 100644 index 0000000000..dd6956c3e9 --- /dev/null +++ b/c/src/lib/libbsp/m68k/idp/console/mc68ec.c @@ -0,0 +1,18 @@ +/* + * mc68ec.c -- Low level support for the Motorola mc68ec0x0 board. + * Written by rob@cygnus.com (Rob Savoye) + */ +#include "leds.h" + +/* + * delay -- delay execution. This is an ugly hack. It should + * use the timer, but I'm waiting for docs. (sigh) + */ +void delay(num) +int num; +{ + while (num--) + { + asm ("nop"); + } +} diff --git a/c/src/lib/libbsp/m68k/idp/include/README b/c/src/lib/libbsp/m68k/idp/include/README new file mode 100644 index 0000000000..940cadb13d --- /dev/null +++ b/c/src/lib/libbsp/m68k/idp/include/README @@ -0,0 +1,13 @@ +# +# $Id$ +# + +The following files really should be made generic and allowed to +be shared between BSPs: + + mc68230.h + mc68681.h + ringbuf.h + +However at the moment the BSP is not tested under 3.2.0 so it is +dangerous to do so. diff --git a/c/src/lib/libbsp/m68k/idp/include/bsp.h b/c/src/lib/libbsp/m68k/idp/include/bsp.h new file mode 100644 index 0000000000..ec8221f1f9 --- /dev/null +++ b/c/src/lib/libbsp/m68k/idp/include/bsp.h @@ -0,0 +1,79 @@ +/* bsp.h + * + * This include file contains all Motorola 680x0 IDP board IO definitions. + * + * $Id$ + */ + +#ifndef __IDP_BSP_H +#define __IDP_BSP_H + +#include "rtems.h" +#include "cpu.h" +#include "console.h" +#include "mc68230.h" +#include "mc68681.h" + +/* + * Define the time limits for RTEMS Test Suite test durations. + * Long test and short test duration limits are provided. These + * values are in seconds and need to be converted to ticks for the + * application. + */ + +#define MAX_LONG_TEST_DURATION 300 /* 5 minutes = 300 seconds */ +#define MAX_SHORT_TEST_DURATION 3 /* 3 seconds */ + +/* + * Define the interrupt mechanism for Time Test 27 + * + * NOTE: tm27 apparently not supported. + */ + +#define MUST_WAIT_FOR_INTERRUPT 0 + +#define Install_tm27_vector( handler ) + +#define Cause_tm27_intr() + +#define Clear_tm27_intr() + +#define Lower_tm27_intr() + +/* Constants */ + +#define RAM_START 0 +#define RAM_END 0x200000 + +#ifdef MIDP_INIT +#undef EXTERN +#define EXTERN +#else +#undef EXTERN +#define EXTERN extern +#endif + +/* miscellaneous stuff assumed to exist */ + +extern rtems_configuration_table BSP_Configuration; + +extern m68k_isr M68Kvec[]; /* vector table address */ + +/* functions */ + +void bsp_cleanup( void ); + +m68k_isr set_vector( + rtems_isr_entry handler, + rtems_vector_number vector, + int type +); + +void init_pit( void ); + +void transmit_char( char ch ); + +void transmit_char_portb( char ch ); + +#endif +/* end of include file */ diff --git a/c/src/lib/libbsp/m68k/idp/include/coverhd.h b/c/src/lib/libbsp/m68k/idp/include/coverhd.h new file mode 100644 index 0000000000..671f20d197 --- /dev/null +++ b/c/src/lib/libbsp/m68k/idp/include/coverhd.h @@ -0,0 +1,106 @@ +/* coverhd.h + * + * This include file has defines to represent the overhead associated + * with calling a particular directive from C. These are used in the + * Timing Test Suite to ignore the overhead required to pass arguments + * to directives. On some CPUs and/or target boards, this overhead + * is significant and makes it difficult to distinguish internal + * RTEMS execution time from that used to call the directive. + * This file should be updated after running the C overhead timing + * test. Once this update has been performed, the RTEMS Time Test + * Suite should be rebuilt to account for these overhead times in the + * timing results. + * + * NOTE: If these are all zero, then the times reported include all + * all calling overhead including passing of arguments. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __COVERHD_h +#define __COVERHD_h + +#define CALLING_OVERHEAD_INITIALIZE_EXECUTIVE 0 +#define CALLING_OVERHEAD_SHUTDOWN_EXECUTIVE 0 +#define CALLING_OVERHEAD_TASK_CREATE 0 +#define CALLING_OVERHEAD_TASK_IDENT 0 +#define CALLING_OVERHEAD_TASK_START 0 +#define CALLING_OVERHEAD_TASK_RESTART 0 +#define CALLING_OVERHEAD_TASK_DELETE 0 +#define CALLING_OVERHEAD_TASK_SUSPEND 0 +#define CALLING_OVERHEAD_TASK_RESUME 0 +#define CALLING_OVERHEAD_TASK_SET_PRIORITY 0 +#define CALLING_OVERHEAD_TASK_MODE 0 +#define CALLING_OVERHEAD_TASK_GET_NOTE 0 +#define CALLING_OVERHEAD_TASK_SET_NOTE 0 +#define CALLING_OVERHEAD_TASK_WAKE_WHEN 0 +#define CALLING_OVERHEAD_TASK_WAKE_AFTER 0 +#define CALLING_OVERHEAD_INTERRUPT_CATCH 0 +#define CALLING_OVERHEAD_CLOCK_GET 0 +#define CALLING_OVERHEAD_CLOCK_SET 0 +#define CALLING_OVERHEAD_CLOCK_TICK 0 + +#define CALLING_OVERHEAD_TIMER_CREATE 0 +#define CALLING_OVERHEAD_TIMER_IDENT 0 +#define CALLING_OVERHEAD_TIMER_DELETE 0 +#define CALLING_OVERHEAD_TIMER_FIRE_AFTER 0 +#define CALLING_OVERHEAD_TIMER_FIRE_WHEN 0 +#define CALLING_OVERHEAD_TIMER_RESET 0 +#define CALLING_OVERHEAD_TIMER_CANCEL 0 +#define CALLING_OVERHEAD_SEMAPHORE_CREATE 0 +#define CALLING_OVERHEAD_SEMAPHORE_IDENT 0 +#define CALLING_OVERHEAD_SEMAPHORE_DELETE 0 +#define CALLING_OVERHEAD_SEMAPHORE_OBTAIN 0 +#define CALLING_OVERHEAD_SEMAPHORE_RELEASE 0 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_CREATE 0 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_IDENT 0 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_DELETE 0 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_SEND 0 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_URGENT 0 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_BROADCAST 0 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_RECEIVE 0 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_FLUSH 0 + +#define CALLING_OVERHEAD_EVENT_SEND 0 +#define CALLING_OVERHEAD_EVENT_RECEIVE 0 +#define CALLING_OVERHEAD_SIGNAL_CATCH 0 +#define CALLING_OVERHEAD_SIGNAL_SEND 0 +#define CALLING_OVERHEAD_PARTITION_CREATE 0 +#define CALLING_OVERHEAD_PARTITION_IDENT 0 +#define CALLING_OVERHEAD_PARTITION_DELETE 0 +#define CALLING_OVERHEAD_PARTITION_GET_BUFFER 0 +#define CALLING_OVERHEAD_PARTITION_RETURN_BUFFER 0 +#define CALLING_OVERHEAD_REGION_CREATE 0 +#define CALLING_OVERHEAD_REGION_IDENT 0 +#define CALLING_OVERHEAD_REGION_DELETE 0 +#define CALLING_OVERHEAD_REGION_GET_SEGMENT 0 +#define CALLING_OVERHEAD_REGION_RETURN_SEGMENT 0 +#define CALLING_OVERHEAD_PORT_CREATE 0 +#define CALLING_OVERHEAD_PORT_IDENT 0 +#define CALLING_OVERHEAD_PORT_DELETE 0 +#define CALLING_OVERHEAD_PORT_EXTERNAL_TO_INTERNAL 0 +#define CALLING_OVERHEAD_PORT_INTERNAL_TO_EXTERNAL 0 + +#define CALLING_OVERHEAD_IO_INITIALIZE 0 +#define CALLING_OVERHEAD_IO_OPEN 0 +#define CALLING_OVERHEAD_IO_CLOSE 0 +#define CALLING_OVERHEAD_IO_READ 0 +#define CALLING_OVERHEAD_IO_WRITE 0 +#define CALLING_OVERHEAD_IO_CONTROL 0 +#define CALLING_OVERHEAD_FATAL_ERROR_OCCURRED 0 +#define CALLING_OVERHEAD_RATE_MONOTONIC_CREATE 0 +#define CALLING_OVERHEAD_RATE_MONOTONIC_IDENT 0 +#define CALLING_OVERHEAD_RATE_MONOTONIC_DELETE 0 +#define CALLING_OVERHEAD_RATE_MONOTONIC_CANCEL 0 +#define CALLING_OVERHEAD_RATE_MONOTONIC_PERIOD 0 +#define CALLING_OVERHEAD_MULTIPROCESSING_ANNOUNCE 0 + +#endif diff --git a/c/src/lib/libbsp/m68k/idp/include/leds.h b/c/src/lib/libbsp/m68k/idp/include/leds.h new file mode 100644 index 0000000000..79df8488d8 --- /dev/null +++ b/c/src/lib/libbsp/m68k/idp/include/leds.h @@ -0,0 +1,25 @@ +/* + * leds.c -- control the led's on a Motorola mc68ec0x0 board. + * Written by rob@cygnus.com (Rob Savoye) + */ + +#ifndef __LEDS_H__ +#define __LEDS_H__ + +#define LED_ADDR 0xd00003 +#define LED_0 ~0x1 +#define LED_1 ~0x2 +#define LED_2 ~0x4 +#define LED_3 ~0x8 +#define LED_4 ~0x10 +#define LED_5 ~0x20 +#define LED_6 ~0x40 +#define LED_7 ~0x80 +#define LEDS_OFF 0xff +#define LEDS_ON 0x0 + +#define FUDGE(x) ((x >= 0xa && x <= 0xf) ? (x + 'a') & 0x7f : (x + '0') & 0x7f) + +extern void led_putnum( char ); + +#endif /* __LEDS_H__ */ diff --git a/c/src/lib/libbsp/m68k/idp/startup/bspstart.c b/c/src/lib/libbsp/m68k/idp/startup/bspstart.c new file mode 100644 index 0000000000..843a137485 --- /dev/null +++ b/c/src/lib/libbsp/m68k/idp/startup/bspstart.c @@ -0,0 +1,175 @@ +/* bsp_start() + * + * This routine starts the application. It includes application, + * board, and monitor specific initialization and configuration. + * The generic CPU dependent initialization has been performed + * before this routine is invoked. + * + * INPUT: NONE + * + * OUTPUT: NONE + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include "rtems.h" +#include "bsp.h" +#include "cpu.h" +#include "libcsupport.h" + +unsigned char *duart_base; +extern struct duart_regs duart_info; + +#define DELAY 5000 + +void led_putnum(); + +/* + * The original table from the application and our copy of it with + * some changes. + */ + +extern rtems_configuration_table Configuration; +rtems_configuration_table BSP_Configuration; + +rtems_cpu_table Cpu_table; + +/* Initialize whatever libc we are using + * called from postdriver hook + */ + +void bsp_libc_init() +{ + extern int end; + rtems_unsigned32 heap_start; + + heap_start = (rtems_unsigned32) &end; + if (heap_start & (CPU_ALIGNMENT-1)) + heap_start = (heap_start + CPU_ALIGNMENT) & ~(CPU_ALIGNMENT-1); + + /* Create 64 KByte memory region for RTEMS executive */ + RTEMS_Malloc_Initialize((void *) heap_start, 64 * 1024, 0); + + /* + * Set up for the libc handling. + */ + + if (BSP_Configuration.ticks_per_timeslice > 0) + libc_init(1); /* reentrant if possible */ + else + libc_init(0); /* non-reentrant */ + + /* + * Initialize the stack bounds checker + */ + +#ifdef STACK_CHECKER_ON + Stack_check_Initialize(); +#endif +} + + +int bsp_start( + int argc, + char **argv, + char **environp +) +{ + m68k_isr *monitors_vector_table; + int index; + + duart_base = (unsigned char *)DUART_ADDR; + + /* + * Set the VBR here to the monitor's default. + */ + + monitors_vector_table = (m68k_isr *)0; /* This is where + you set vector base + register = 0 */ + m68k_set_vbr( monitors_vector_table ); + + /* The vector interrupt table for the 680x0 is in appendix B-2 + of the M68000 Family Programmer's reference table */ + for ( index=2 ; index<=255 ; index++ ) + M68Kvec[ index ] = monitors_vector_table[ 32 ]; + + + M68Kvec[ 2 ] = monitors_vector_table[ 2 ]; /* bus error vector */ + M68Kvec[ 4 ] = monitors_vector_table[ 4 ]; /* breakpoints vector */ + M68Kvec[ 9 ] = monitors_vector_table[ 9 ]; /* trace vector */ + + /* + * Set the VBR here if you do not want to use the monitor's vector table. + */ + + m68k_set_vbr( &M68Kvec ); + + m68k_enable_caching(); + + /* + * we only use a hook to get the C library initialized. + */ + + Cpu_table.pretasking_hook = NULL; + + Cpu_table.predriver_hook = bsp_libc_init; /* RTEMS resources available */ + + Cpu_table.postdriver_hook = NULL; + + Cpu_table.idle_task = NULL; /* do not override system IDLE task */ + + Cpu_table.do_zero_of_workspace = TRUE; + + Cpu_table.interrupt_vector_table = (m68k_isr *) &M68Kvec; + + Cpu_table.interrupt_stack_size = 4096; + + Cpu_table.extra_system_initialization_stack = 0; + + /* + * Copy the table + */ + + BSP_Configuration = Configuration; + + BSP_Configuration.work_space_start = (void *) + (RAM_END - BSP_Configuration.work_space_size); + + /* + * Add 1 region for the RTEMS Malloc + */ + + BSP_Configuration.maximum_regions++; + + /* + * Add 1 extension for newlib libc + */ + +#ifdef RTEMS_NEWLIB + BSP_Configuration.maximum_extensions++; +#endif + + /* + * Add another extension if using the stack checker + */ + +#ifdef STACK_CHECKER_ON + BSP_Configuration.maximum_extensions++; +#endif + +/* led_putnum('e'); * for debugging purposes only */ + rtems_initialize_executive( &BSP_Configuration, &Cpu_table );/* does not return */ + + /* Clock_exit is done as an atexit() function */ + + return 0; +} diff --git a/c/src/lib/libbsp/m68k/idp/startup/linkcmds b/c/src/lib/libbsp/m68k/idp/startup/linkcmds new file mode 100644 index 0000000000..be546b11f5 --- /dev/null +++ b/c/src/lib/libbsp/m68k/idp/startup/linkcmds @@ -0,0 +1,44 @@ +/* This file is a derivation of that found with the newlib-1.6 distribution + * for the idp.ld file. That file, it appears, was originally written by + * Rob Savoye. Other ideas came from Joel Sherrill for the RTEMS linkcmds + * file (this is basically a mixture of the two). + */ + +/* + * Setup the memory map of the MC68ec0x0 Board (IDP) + * stack grows up towards high memory. This works for + * both the rom68k and the mon68k monitors. + */ +MEMORY +{ + ram : org = 0x10000, l = 2M +} + +SECTIONS +{ + .text 0x10000: + { + text_start = . ; + _text_start = . ; + *(.text) + etext = ALIGN( 0x10 ) ; + _etext = .; + } + .data ADDR( .text ) + SIZEOF( .text ): + { + data_start = . ; + _data_start = .; + *(.data) + edata = ALIGN( 0x10 ) ; + _edata = .; + } + .bss ADDR( .data ) + SIZEOF( .data ): + { + bss_start = . ; + _bss_start = . ; + *(.bss) + *(COMMON) + end = . ; + _end = . ; + } +} diff --git a/c/src/lib/libbsp/m68k/idp/timer/timer.c b/c/src/lib/libbsp/m68k/idp/timer/timer.c new file mode 100644 index 0000000000..176f393e45 --- /dev/null +++ b/c/src/lib/libbsp/m68k/idp/timer/timer.c @@ -0,0 +1,121 @@ +/* Timer_init() + * + * This routine initializes the MC68230 timer on the Motorola IDP board. + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * NOTE: This routine will not work if the optimizer is enabled + * for some compilers. The multiple writes to the MC68230 + * may be optimized away. + * + * It is important that the timer start/stop overhead be + * determined when porting or modifying this code. + * + * Code Modified for the MC68230 by Doug McBride, Colorado Space Grant College + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + + +#include "rtems.h" +#include "cpu.h" +#include "bsp.h" +#include "mc68230.h" + +#define TIMER_VECTOR 0x4D + +int Ttimer_val; +rtems_boolean Timer_driver_Find_average_overhead; + +rtems_isr timerisr(); + +void Timer_initialize() +{ + (void) set_vector( timerisr, TIMER_VECTOR, 0 ); /* install ISR */ + + Ttimer_val = 0; /* clear timer ISR count */ + + /* some PI/T initialization stuff here */ + /* Set up the interrupt vector on the MC68230 chip: + TIVR = TIMER_VECTOR; */ + MC68230_WRITE (TIVR, TIMER_VECTOR); + + /* Set CPRH through CPRL to maximum count to reduce interrupt overhead + CPRH = 0xFF; + CPRM = 0xFF; + CPRL = 0xFF; */ + MC68230_WRITE (CPRH, 0xFF); + MC68230_WRITE (CPRM, 0xFF); + MC68230_WRITE (CPRL, 0xFF); + + /* Enable timer and use it as an external periodic interrupt generator + TCR = 0xA1; */ + MC68230_WRITE (TCR, 0xA1); + +} + +#define AVG_OVERHEAD 9 /* may not be right -- do this later */ +#define LEAST_VALID 10 /* Don't trust a value lower than this */ + +int Read_timer() +{ + rtems_unsigned8 data; + rtems_unsigned8 msb, osb, lsb; + rtems_unsigned32 remaining, total; + + /* Disable timer so that timer can be read + data = TCR; + TCR = (data & 0xFE); */ + MC68230_READ (TCR, data); + MC68230_WRITE (TCR, (data & 0xFE)); + + /* Read the counter value + msb = CNTRH; + osb = CNTRM; + lsb = CNTRL; */ + MC68230_READ (CNTRH, msb); + MC68230_READ (CNTRM, osb); + MC68230_READ (CNTRL, lsb); + + /* Calculate the time so far */ + remaining = 0x1000000 - ((msb << 16) + (osb << 8) + lsb); + total = (Ttimer_val * 0x1000000) + remaining; + + /* Enable timer so that timer can continue + TCR = 0xA1; */ + MC68230_WRITE (TCR, 0xA1); + + /* do not restore old vector */ + if ( Timer_driver_Find_average_overhead == 1 ) + return total; /* in countdown units */ + + if ( total < LEAST_VALID ) + return 0; /* below timer resolution */ + + /* Clocked at 6.5 Mhz */ + /* Avoid floating point problems, be lazy, and return the total minus + the average overhead */ + return (total - AVG_OVERHEAD); +} + +rtems_status_code Empty_function( void ) +{ + return RTEMS_SUCCESSFUL; +} + +void Set_find_average_overhead( + rtems_boolean find_flag +) +{ + Timer_driver_Find_average_overhead = find_flag; +} diff --git a/c/src/lib/libbsp/m68k/idp/timer/timerisr.s b/c/src/lib/libbsp/m68k/idp/timer/timerisr.s new file mode 100644 index 0000000000..cd8173be52 --- /dev/null +++ b/c/src/lib/libbsp/m68k/idp/timer/timerisr.s @@ -0,0 +1,38 @@ +/* timer_isr() + * + * This routine provides the ISR for the MC68230 timer on the Motorola + * IDP board. The timer is set up to generate an interrupt at maximum + * intervals. + * + * Code modified by Doug McBride, Colorado Space Grant College + * countdown should be loaded automatically + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include "asm.h" + +BEGIN_CODE + +.set TSR, 0x00c0106B | base address of PIT register "TSR" + + PUBLIC (timerisr) +SYM (timerisr): + movb #1,TSR | acknowledge interrupt + addql #1, SYM (Ttimer_val) | increment timer value + rte + +END_CODE +END diff --git a/c/src/lib/libbsp/m68k/mvme136/clock/ckinit.c b/c/src/lib/libbsp/m68k/mvme136/clock/ckinit.c new file mode 100644 index 0000000000..de88fe9252 --- /dev/null +++ b/c/src/lib/libbsp/m68k/mvme136/clock/ckinit.c @@ -0,0 +1,111 @@ +/* Clock_init() + * + * This routine initializes the Z80386 1 on the MVME136 board. + * The tick frequency is 1 millisecond. + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include + +#include +#include +#include +#include + +#define MICRVAL 0xe2 /* disable lower chain, no vec */ + /* set right justified addr */ + /* and master int enable */ +#define MCCRVAL 0xc4 /* enable T1 and port B */ + /* timers independent */ +#define MS_COUNT 0x07d0 /* T1's countdown constant (1 ms) */ +#define T1MSRVAL 0x80 /* T1 cont. cycle/pulse output */ +#define T1CSRVAL 0xc6 /* enable interrupt, allow and */ + /* and trigger countdown */ + +rtems_unsigned32 Clock_isrs; /* ISRs until next tick */ +volatile rtems_unsigned32 Clock_driver_ticks; + /* ticks since initialization */ +rtems_isr_entry Old_ticker; + +rtems_device_driver Clock_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *pargp, + rtems_id tid, + rtems_unsigned32 *rval +) +{ + Install_clock( Clock_isr ); +} + +void ReInstall_clock( + rtems_isr_entry clock_isr +) +{ + rtems_unsigned32 isrlevel; + + rtems_interrupt_disable( isrlevel ); + (void) set_vector( clock_isr, 66, 1 ); + rtems_interrupt_enable( isrlevel ); +} + +void Install_clock( + rtems_isr_entry clock_isr +) +{ + volatile struct z8036_map *timer; + + Clock_driver_ticks = 0; + Clock_isrs = BSP_Configuration.microseconds_per_tick / 1000; + + if ( BSP_Configuration.ticks_per_timeslice ) { + Old_ticker = (rtems_isr_entry) set_vector( clock_isr, 66, 1 ); + timer = (struct z8036_map *) 0xfffb0000; + timer->MASTER_INTR = MICRVAL; + timer->CT1_MODE_SPEC = T1MSRVAL; + + *((rtems_unsigned16 *)0xfffb0016) = MS_COUNT; /* write countdown value */ +/* + timer->CT1_TIME_CONST_MSB = (MS_COUNT >> 8); + timer->CT1_TIME_CONST_LSB = (MS_COUNT & 0xff); +*/ + timer->MASTER_CFG = MCCRVAL; + timer->CT1_CMD_STATUS = T1CSRVAL; + +/* + * Enable interrupt via VME interrupt mask register + */ + (*(rtems_unsigned8 *)0xfffb0038) &= 0xfd; + + + atexit( Clock_exit ); + } + +} + +void Clock_exit( void ) +{ + volatile struct z8036_map *timer; + + if ( BSP_Configuration.ticks_per_timeslice ) { + timer = (struct z8036_map *) 0xfffb0000; + timer->MASTER_INTR = 0x62; + timer->CT1_MODE_SPEC = 0x00; + timer->MASTER_CFG = 0xf4; + timer->CT1_CMD_STATUS = 0x00; + /* do not restore old vector */ + } +} diff --git a/c/src/lib/libbsp/m68k/mvme136/console/console.c b/c/src/lib/libbsp/m68k/mvme136/console/console.c new file mode 100644 index 0000000000..6bfcf84481 --- /dev/null +++ b/c/src/lib/libbsp/m68k/mvme136/console/console.c @@ -0,0 +1,159 @@ +/* + * This file contains the MVME136 console IO package. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#define M136_INIT + +#include +#include "console.h" +#include "bsp.h" + +/* console_initialize + * + * This routine initializes the console IO driver. + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * Return values: + */ + +rtems_device_driver console_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg, + rtems_id self, + rtems_unsigned32 *status +) +{ + _Write_m681 = ( struct w_m681_info * ) M681ADDR; + _Read_m681 = ( struct r_m681_info * ) M681ADDR; + *status = RTEMS_SUCCESSFUL; +} + + +/* is_character_ready + * + * This routine returns TRUE if a character is available. + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * Return values: + */ + +rtems_boolean is_character_ready( + char *ch +) +{ + if ( !(_Read_m681->srb & RXRDYB) ) + return(FALSE); + + *ch = _Read_m681->rbb; + return(TRUE); +} + +/* inbyte + * + * This routine reads a character from the UART. + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * Return values: + * character read from UART + */ + +char inbyte( void ) +{ + while ( !(_Read_m681->srb & RXRDYB) ); + return _Read_m681->rbb; +} + + +/* outbyte + * + * This routine transmits a character out the M68681. It supports + * XON/XOFF flow control. + * + * Input parameters: + * ch - character to be transmitted + * + * Output parameters: NONE + */ + +void outbyte( + char ch +) +{ + while ( ! (_Read_m681->srb & TXRDYB) ) ; + while ( _Read_m681->srb & RXRDYB ) /* must be an XOFF */ + if ( _Read_m681->rbb == XOFF ) + do { + while ( ! (_Read_m681->srb & RXRDYB) ) ; + } while ( _Read_m681->rbb != XON ); + + _Write_m681->tbb = ch; + if ( ch == '\n' ) + outbyte( CR ); +} + +/* + * __read -- read bytes from the serial port. Ignore fd, since + * we only have stdin. + */ + +int __read( + int fd, + char *buf, + int nbytes +) +{ + int i = 0; + + for (i = 0; i < nbytes; i++) { + *(buf + i) = inbyte(); + if ((*(buf + i) == '\n') || (*(buf + i) == '\r')) { + (*(buf + i++)) = '\n'; + (*(buf + i)) = 0; + break; + } + } + return (i); +} + +/* + * __write -- write bytes to the serial port. Ignore fd, since + * stdout and stderr are the same. Since we have no filesystem, + * open will only return an error. + */ + +int __write( + int fd, + char *buf, + int nbytes +) +{ + int i; + + for (i = 0; i < nbytes; i++) { + if (*(buf + i) == '\n') { + outbyte ('\r'); + } + outbyte (*(buf + i)); + } + return (nbytes); +} diff --git a/c/src/lib/libbsp/m68k/mvme136/include/bsp.h b/c/src/lib/libbsp/m68k/mvme136/include/bsp.h new file mode 100644 index 0000000000..f89a1b0461 --- /dev/null +++ b/c/src/lib/libbsp/m68k/mvme136/include/bsp.h @@ -0,0 +1,142 @@ +/* bsp.h + * + * This include file contains all MVME136 board IO definitions. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __MVME136_h +#define __MVME136_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +/* + * Define the time limits for RTEMS Test Suite test durations. + * Long test and short test duration limits are provided. These + * values are in seconds and need to be converted to ticks for the + * application. + * + */ + +#define MAX_LONG_TEST_DURATION 300 /* 5 minutes = 300 seconds */ +#define MAX_SHORT_TEST_DURATION 3 /* 3 seconds */ + +/* + * Define the interrupt mechanism for Time Test 27 + * + * NOTE: Use the MPCSR vector for the MVME136 + */ + +#define MUST_WAIT_FOR_INTERRUPT 0 + +#define Install_tm27_vector( handler ) set_vector( (handler), 75, 1 ) + +#define Cause_tm27_intr() (*(volatile rtems_unsigned8 *)0xfffb006b) = 0x80 + +#define Clear_tm27_intr() (*(volatile rtems_unsigned8 *)0xfffb006b) = 0x00 + +#define Lower_tm27_intr() + +/* + * Simple spin delay in microsecond units for device drivers. + * This is very dependent on the clock speed of the target. + */ + +#define delay( microseconds ) \ + { register rtems_unsigned32 _delay=(microseconds); \ + register rtems_unsigned32 _tmp=123; \ + asm volatile( "0: \ + nbcd %0 ; \ + nbcd %0 ; \ + dbf %1,0b" \ + : "=d" (_tmp), "=d" (_delay) \ + : "0" (_tmp), "1" (_delay) ); \ + } + +/* Constants */ + +#define RAM_START 0 +#define RAM_END 0x100000 + +#define M681ADDR 0xfffb0040 /* address of the M68681 chip */ +#define RXRDYB 0x01 /* status reg recv ready mask */ +#define TXRDYB 0x04 /* status reg trans ready mask */ +#define PARITYERR 0x20 /* status reg parity error mask */ +#define FRAMEERR 0x40 /* status reg frame error mask */ + + +#define FOREVER 1 /* infinite loop */ + +/* Structures */ + +struct r_m681_info { + char fill1[ 5 ]; /* channel A regs ( not used ) */ + char isr; /* interrupt status reg */ + char fill2[ 2 ]; /* counter regs (not used) */ + char mr1mr2b; /* MR1B and MR2B regs */ + char srb; /* status reg channel B */ + char fill3; /* do not access */ + char rbb; /* receive buffer channel B */ + char ivr; /* interrupt vector register */ +}; + +struct w_m681_info { + char fill1[ 4 ]; /* channel A regs (not used) */ + char acr; /* auxillary control reg */ + char imr; /* interrupt mask reg */ + char fill2[ 2 ]; /* counter regs (not used) */ + char mr1mr2b; /* MR1B and MR2B regs */ + char csrb; /* clock select reg */ + char crb; /* command reg */ + char tbb; /* transmit buffer channel B */ + char ivr; /* interrupt vector register */ +}; + +#ifdef M136_INIT +#undef EXTERN +#define EXTERN +#else +#undef EXTERN +#define EXTERN extern +#endif + +/* miscellaneous stuff assumed to exist */ + +extern rtems_configuration_table BSP_Configuration; + +/* M68681 DUART chip register variables */ + +EXTERN volatile struct r_m681_info *_Read_m681; /* M68681 read registers */ +EXTERN volatile struct w_m681_info *_Write_m681; /* M68681 write registers */ + +extern m68k_isr M68Kvec[]; /* vector table address */ + +/* functions */ + +void bsp_cleanup( void ); + +m68k_isr set_vector( + rtems_isr_entry handler, + rtems_vector_number vector, + int type +); + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/c/src/lib/libbsp/m68k/mvme136/include/coverhd.h b/c/src/lib/libbsp/m68k/mvme136/include/coverhd.h new file mode 100644 index 0000000000..7497514e97 --- /dev/null +++ b/c/src/lib/libbsp/m68k/mvme136/include/coverhd.h @@ -0,0 +1,104 @@ +/* coverhd.h + * + * This include file has defines to represent the overhead associated + * with calling a particular directive from C on this target. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __COVERHD_h +#define __COVERHD_h + +#ifdef __cplusplus +extern "C" { +#endif + +#define CALLING_OVERHEAD_INITIALIZE_EXECUTIVE 2 +#define CALLING_OVERHEAD_SHUTDOWN_EXECUTIVE 1 +#define CALLING_OVERHEAD_TASK_CREATE 3 +#define CALLING_OVERHEAD_TASK_IDENT 2 +#define CALLING_OVERHEAD_TASK_START 2 +#define CALLING_OVERHEAD_TASK_RESTART 2 +#define CALLING_OVERHEAD_TASK_DELETE 1 +#define CALLING_OVERHEAD_TASK_SUSPEND 1 +#define CALLING_OVERHEAD_TASK_RESUME 2 +#define CALLING_OVERHEAD_TASK_SET_PRIORITY 2 +#define CALLING_OVERHEAD_TASK_MODE 2 +#define CALLING_OVERHEAD_TASK_GET_NOTE 2 +#define CALLING_OVERHEAD_TASK_SET_NOTE 2 +#define CALLING_OVERHEAD_TASK_WAKE_WHEN 4 +#define CALLING_OVERHEAD_TASK_WAKE_AFTER 1 +#define CALLING_OVERHEAD_INTERRUPT_CATCH 2 +#define CALLING_OVERHEAD_CLOCK_GET 5 +#define CALLING_OVERHEAD_CLOCK_SET 4 +#define CALLING_OVERHEAD_CLOCK_TICK 1 + +#define CALLING_OVERHEAD_TIMER_CREATE 2 +#define CALLING_OVERHEAD_TIMER_IDENT 1 +#define CALLING_OVERHEAD_TIMER_DELETE 2 +#define CALLING_OVERHEAD_TIMER_FIRE_AFTER 2 +#define CALLING_OVERHEAD_TIMER_FIRE_WHEN 5 +#define CALLING_OVERHEAD_TIMER_RESET 1 +#define CALLING_OVERHEAD_TIMER_CANCEL 1 +#define CALLING_OVERHEAD_SEMAPHORE_CREATE 3 +#define CALLING_OVERHEAD_SEMAPHORE_DELETE 1 +#define CALLING_OVERHEAD_SEMAPHORE_IDENT 2 +#define CALLING_OVERHEAD_SEMAPHORE_OBTAIN 2 +#define CALLING_OVERHEAD_SEMAPHORE_RELEASE 1 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_CREATE 2 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_IDENT 2 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_DELETE 1 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_SEND 2 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_URGENT 2 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_BROADCAST 2 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_RECEIVE 3 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_FLUSH 2 + +#define CALLING_OVERHEAD_EVENT_SEND 2 +#define CALLING_OVERHEAD_EVENT_RECEIVE 2 +#define CALLING_OVERHEAD_SIGNAL_CATCH 2 +#define CALLING_OVERHEAD_SIGNAL_SEND 2 +#define CALLING_OVERHEAD_PARTITION_CREATE 3 +#define CALLING_OVERHEAD_PARTITION_IDENT 2 +#define CALLING_OVERHEAD_PARTITION_DELETE 1 +#define CALLING_OVERHEAD_PARTITION_GET_BUFFER 2 +#define CALLING_OVERHEAD_PARTITION_RETURN_BUFFER 2 +#define CALLING_OVERHEAD_REGION_CREATE 3 +#define CALLING_OVERHEAD_REGION_IDENT 2 +#define CALLING_OVERHEAD_REGION_DELETE 2 +#define CALLING_OVERHEAD_REGION_GET_SEGMENT 3 +#define CALLING_OVERHEAD_REGION_RETURN_SEGMENT 2 +#define CALLING_OVERHEAD_PORT_CREATE 3 +#define CALLING_OVERHEAD_PORT_IDENT 2 +#define CALLING_OVERHEAD_PORT_DELETE 1 +#define CALLING_OVERHEAD_PORT_EXTERNAL_TO_INTERNAL 2 +#define CALLING_OVERHEAD_PORT_INTERNAL_TO_EXTERNAL 2 + +#define CALLING_OVERHEAD_IO_INITIALIZE 2 +#define CALLING_OVERHEAD_IO_OPEN 2 +#define CALLING_OVERHEAD_IO_CLOSE 3 +#define CALLING_OVERHEAD_IO_READ 2 +#define CALLING_OVERHEAD_IO_WRITE 2 +#define CALLING_OVERHEAD_IO_CONTROL 2 +#define CALLING_OVERHEAD_FATAL_ERROR_OCCURRED 1 +#define CALLING_OVERHEAD_RATE_MONOTONIC_CREATE 2 +#define CALLING_OVERHEAD_RATE_MONOTONIC_IDENT 2 +#define CALLING_OVERHEAD_RATE_MONOTONIC_DELETE 1 +#define CALLING_OVERHEAD_RATE_MONOTONIC_CANCEL 1 +#define CALLING_OVERHEAD_RATE_MONOTONIC_PERIOD 2 +#define CALLING_OVERHEAD_MULTIPROCESSING_ANNOUNCE 1 + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/c/src/lib/libbsp/m68k/mvme136/shmsupp/addrconv.c b/c/src/lib/libbsp/m68k/mvme136/shmsupp/addrconv.c new file mode 100644 index 0000000000..8e1502f789 --- /dev/null +++ b/c/src/lib/libbsp/m68k/mvme136/shmsupp/addrconv.c @@ -0,0 +1,32 @@ +/* Shm_Convert_address + * + * This MVME136 has a "normal" view of the VME address space. + * No address range conversion is required. + * + * Input parameters: + * address - address to convert + * + * Output parameters: + * returns - converted address + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include +#include + +void *Shm_Convert_address( + void *address +) +{ + return ( address ); +} diff --git a/c/src/lib/libbsp/m68k/mvme136/shmsupp/getcfg.c b/c/src/lib/libbsp/m68k/mvme136/shmsupp/getcfg.c new file mode 100644 index 0000000000..d4db200ad2 --- /dev/null +++ b/c/src/lib/libbsp/m68k/mvme136/shmsupp/getcfg.c @@ -0,0 +1,85 @@ +/* void Shm_Get_configuration( localnode, &shmcfg ) + * + * This routine initializes, if necessary, and returns a pointer + * to the Shared Memory Configuration Table for the Cyclone CVME961. + * + * INPUT PARAMETERS: + * localnode - local node number + * shmcfg - address of pointer to SHM Config Table + * + * OUTPUT PARAMETERS: + * *shmcfg - pointer to SHM Config Table + * + * NOTES: The MPCSR interrupt on the MVME136 is used as an interprocessor + * interrupt. The capablities of the MPCSR are used to generate + * interprocessor interrupts for up to eight nodes. + * + * The following table illustrates the configuration limitations: + * + * BUS MAX + * MODE ENDIAN NODES + * ========= ====== ======= + * POLLED LITTLE 2+ + * INTERRUPT LITTLE 2-8 + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include "shm.h" + +#define INTERRUPT 1 /* MVME136 target supports both */ +#define POLLING 0 /* polling and interrupt modes */ + +shm_config_table BSP_shm_cfgtbl; + +rtems_unsigned32 *BSP_int_address() +{ + rtems_unsigned32 id, offset; + + id = (rtems_unsigned32) *(rtems_unsigned8 *)0xfffb0061; + offset = ((id & 0x1f) << 5) | ((id & 0xe0) << 8); + offset |= 0xffff000b; + return( (rtems_unsigned32 * ) offset ); +} + +void Shm_Get_configuration( + rtems_unsigned32 localnode, + shm_config_table **shmcfg +) +{ + BSP_shm_cfgtbl.base = (rtems_unsigned32 *)0x20000000; + BSP_shm_cfgtbl.length = 1 * MEGABYTE; + BSP_shm_cfgtbl.format = SHM_BIG; + + BSP_shm_cfgtbl.cause_intr = Shm_Cause_interrupt; + +#ifdef NEUTRAL_BIG + BSP_shm_cfgtbl.convert = NULL_CONVERT; +#else + BSP_shm_cfgtbl.convert = CPU_swap_u32; +#endif + +#if (POLLING==1) + BSP_shm_cfgtbl.poll_intr = POLLED_MODE; + BSP_shm_cfgtbl.Intr.address = NO_INTERRUPT; + BSP_shm_cfgtbl.Intr.value = NO_INTERRUPT; + BSP_shm_cfgtbl.Intr.length = NO_INTERRUPT; +#else + BSP_shm_cfgtbl.poll_intr = INTR_MODE; + BSP_shm_cfgtbl.Intr.address = BSP_int_address(); + BSP_shm_cfgtbl.Intr.value = 0x80; + BSP_shm_cfgtbl.Intr.length = BYTE; +#endif + + *shmcfg = &BSP_shm_cfgtbl; + +} diff --git a/c/src/lib/libbsp/m68k/mvme136/shmsupp/lock.c b/c/src/lib/libbsp/m68k/mvme136/shmsupp/lock.c new file mode 100644 index 0000000000..5ccc406af5 --- /dev/null +++ b/c/src/lib/libbsp/m68k/mvme136/shmsupp/lock.c @@ -0,0 +1,75 @@ +/* Shared Memory Lock Routines + * + * This shared memory locked queue support routine need to be + * able to lock the specified locked queue. Interrupts are + * disabled while the queue is locked to prevent preemption + * and deadlock when two tasks poll for the same lock. + * previous level. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include +#include + +/* + * Shm_Initialize_lock + * + * Initialize the lock for the specified locked queue. + */ + +void Shm_Initialize_lock( + Shm_Locked_queue_Control *lq_cb +) +{ + lq_cb->lock = LQ_UNLOCKED; +} + +/* void _Shm_Lock( &lq_cb ) + * + * This shared memory locked queue support routine locks the + * specified locked queue. It disables interrupts to prevent + * a deadlock condition. + */ + +void Shm_Lock( + Shm_Locked_queue_Control *lq_cb +) +{ + rtems_unsigned32 isr_level; + rtems_unsigned32 *lockptr = (rtems_unsigned32 *)&lq_cb->lock; + + rtems_interrupt_disable( isr_level ); + Shm_isrstat = isr_level; + asm volatile( "lockit:" : : ); + asm volatile( "tas %0@" : "=a" (lockptr) : "0" (lockptr) ); + asm volatile( "bne lockit" : : ); +/* should delay */ +} + +/* + * Shm_Unlock + * + * Unlock the lock for the specified locked queue. + */ + +void Shm_Unlock( + Shm_Locked_queue_Control *lq_cb +) +{ + rtems_unsigned32 isr_level; + + lq_cb->lock = SHM_UNLOCK_VALUE; + isr_level = Shm_isrstat; + rtems_interrupt_enable( isr_level ); +} + diff --git a/c/src/lib/libbsp/m68k/mvme136/shmsupp/mpisr.c b/c/src/lib/libbsp/m68k/mvme136/shmsupp/mpisr.c new file mode 100644 index 0000000000..6591d28a11 --- /dev/null +++ b/c/src/lib/libbsp/m68k/mvme136/shmsupp/mpisr.c @@ -0,0 +1,42 @@ +/* Shm_isr_mvme136() + * + * NOTE: This routine is not used when in polling mode. Either + * this routine OR Shm_clockisr is used in a particular system. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include +#include + +rtems_isr Shm_isr_mvme136() +{ + Shm_Interrupt_count += 1; + rtems_multiprocessing_announce(); + (*(volatile rtems_unsigned8 *)0xfffb006b) = 0; /* clear MPCSR intr */ +} + +/* void _Shm_setvec( ) + * + * This driver routine sets the SHM interrupt vector to point to the + * driver's SHM interrupt service routine. + * + * Input parameters: NONE + * + * Output parameters: NONE + */ + +void Shm_setvec() +{ + /* may need to disable intr */ + set_vector( Shm_isr_mvme136, 75, 1 ); +} diff --git a/c/src/lib/libbsp/m68k/mvme136/startup/bspclean.c b/c/src/lib/libbsp/m68k/mvme136/startup/bspclean.c new file mode 100644 index 0000000000..4366603a55 --- /dev/null +++ b/c/src/lib/libbsp/m68k/mvme136/startup/bspclean.c @@ -0,0 +1,46 @@ +/* + * This routine returns control to 135Bug. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include +#include +#include + +void bsp_return_to_monitor_trap() +{ + extern void start( void ); + + register volatile void *start_addr; + + m68k_set_vbr( 0 ); /* restore 135Bug vectors */ + asm volatile( "trap #15" ); /* trap to 135Bug */ + asm volatile( ".short 0x63" ); /* return to 135Bug (.RETURN) */ + /* restart program */ + start_addr = start; + + asm volatile ( "jmp %0@" : "=a" (start_addr) : "0" (start_addr) ); +} + +#define TIMER 0xfffb0000 + +void bsp_cleanup( void ) +{ + Z8x36_WRITE( TIMER, MASTER_INTR, 0x62 ); /* redo timer */ + Z8x36_WRITE( TIMER, CT1_MODE_SPEC, 0x00 ); + Z8x36_WRITE( TIMER, MASTER_CFG, 0xf4 ); + Z8x36_WRITE( TIMER, CT1_CMD_STATUS, 0x00 ); + + M68Kvec[ 45 ] = bsp_return_to_monitor_trap; /* install handler */ + asm volatile( "trap #13" ); /* insures SUPV mode */ +} diff --git a/c/src/lib/libbsp/m68k/mvme136/startup/bspstart.c b/c/src/lib/libbsp/m68k/mvme136/startup/bspstart.c new file mode 100644 index 0000000000..514340d9ea --- /dev/null +++ b/c/src/lib/libbsp/m68k/mvme136/startup/bspstart.c @@ -0,0 +1,156 @@ +/* bsp_start() + * + * This routine starts the application. It includes application, + * board, and monitor specific initialization and configuration. + * The generic CPU dependent initialization has been performed + * before this routine is invoked. + * + * INPUT: NONE + * + * OUTPUT: NONE + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include +#include +#include + +#include "stackchk.h" + +/* + * The original table from the application and our copy of it with + * some changes. + */ + +extern rtems_configuration_table Configuration; +rtems_configuration_table BSP_Configuration; + +rtems_cpu_table Cpu_table; + +/* Initialize whatever libc we are using + * called from postdriver hook + */ + +void bsp_libc_init() +{ + extern int end; + rtems_unsigned32 heap_start; + + heap_start = (rtems_unsigned32) &end; + if (heap_start & (CPU_ALIGNMENT-1)) + heap_start = (heap_start + CPU_ALIGNMENT) & ~(CPU_ALIGNMENT-1); + + RTEMS_Malloc_Initialize((void *) heap_start, 64 * 1024, 0); + + /* + * Set up for the libc handling. + */ + + if (BSP_Configuration.ticks_per_timeslice > 0) + libc_init(1); /* reentrant if possible */ + else + libc_init(0); /* non-reentrant */ + + /* + * Initialize the stack bounds checker + */ + +#ifdef STACK_CHECKER_ON + Stack_check_Initialize(); +#endif +} + +int bsp_start( + int argc, + char **argv, + char **environp +) +{ + m68k_isr *monitors_vector_table; + int index; + + monitors_vector_table = (m68k_isr *)0; /* 135Bug Vectors are at 0 */ + m68k_set_vbr( monitors_vector_table ); + + for ( index=2 ; index<=255 ; index++ ) + M68Kvec[ index ] = monitors_vector_table[ 32 ]; + + M68Kvec[ 2 ] = monitors_vector_table[ 2 ]; /* bus error vector */ + M68Kvec[ 4 ] = monitors_vector_table[ 4 ]; /* breakpoints vector */ + M68Kvec[ 9 ] = monitors_vector_table[ 9 ]; /* trace vector */ + M68Kvec[ 47 ] = monitors_vector_table[ 47 ]; /* system call vector */ + + m68k_set_vbr( &M68Kvec ); + + (*(rtems_unsigned8 *)0xfffb0067) = 0x7f; /* make VME access round-robin */ + + m68k_enable_caching(); + + /* + * we only use a hook to get the C library initialized. + */ + + Cpu_table.pretasking_hook = NULL; + + Cpu_table.predriver_hook = bsp_libc_init; /* RTEMS resources available */ + + Cpu_table.postdriver_hook = NULL; + + Cpu_table.idle_task = NULL; /* do not override system IDLE task */ + + Cpu_table.do_zero_of_workspace = TRUE; + + Cpu_table.interrupt_vector_table = (m68k_isr *) &M68Kvec; + + Cpu_table.interrupt_stack_size = 4096; + + Cpu_table.extra_system_initialization_stack = 0; + + /* + * Copy the table + */ + + BSP_Configuration = Configuration; + + BSP_Configuration.work_space_start = (void *) + (RAM_END - BSP_Configuration.work_space_size); + + /* + * Add 1 region for the RTEMS Malloc + */ + + BSP_Configuration.maximum_regions++; + + /* + * Add 1 extension for newlib libc + */ + +#ifdef RTEMS_NEWLIB + BSP_Configuration.maximum_extensions++; +#endif + + /* + * Add another extension if using the stack checker + */ + +#ifdef STACK_CHECKER_ON + BSP_Configuration.maximum_extensions++; +#endif + + rtems_initialize_executive( &BSP_Configuration, &Cpu_table ); + /* does not return */ + + bsp_cleanup(); + + return 0; +} diff --git a/c/src/lib/libbsp/m68k/mvme136/startup/linkcmds b/c/src/lib/libbsp/m68k/mvme136/startup/linkcmds new file mode 100644 index 0000000000..13317a724e --- /dev/null +++ b/c/src/lib/libbsp/m68k/mvme136/startup/linkcmds @@ -0,0 +1,48 @@ +/* + * This file contains directives for the GNU linker which are specific + * to the Motorola MVME136/MVME135 boards. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +MEMORY + { + ram : org = 0x3000, l = 1M + } + +SECTIONS +{ + .text 0x3000 : + { + text_start = . ; + _text_start = . ; + *(.text) + etext = ALIGN( 0x10 ) ; + _etext = .; + } + .data ADDR( .text ) + SIZEOF( .text ): + { + data_start = . ; + _data_start = .; + *(.data) + edata = ALIGN( 0x10 ) ; + _edata = .; + } + .bss ADDR( .data ) + SIZEOF( .data ): + { + bss_start = . ; + _bss_start = . ; + *(.bss) + *(COMMON) + end = . ; + _end = . ; + } +} diff --git a/c/src/lib/libbsp/m68k/mvme136/timer/timer.c b/c/src/lib/libbsp/m68k/mvme136/timer/timer.c new file mode 100644 index 0000000000..8c3ecd45f2 --- /dev/null +++ b/c/src/lib/libbsp/m68k/mvme136/timer/timer.c @@ -0,0 +1,108 @@ +/* Timer_init() + * + * This routine initializes the Z8036 timer on the MVME136 board. + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * NOTE: This routine will not work if the optimizer is enabled + * for some compilers. The multiple writes to the Z8036 + * may be optimized away. + * + * It is important that the timer start/stop overhead be + * determined when porting or modifying this code. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + + +#include +#include +#include + +#define TIMER 0xfffb0000 /* address of Z8036 on MVME136 */ + +int Ttimer_val; +rtems_boolean Timer_driver_Find_average_overhead; + +rtems_isr timerisr(); + +void Timer_initialize() +{ + (void) set_vector( timerisr, 66, 0 ); /* install ISR */ + + Ttimer_val = 0; /* clear timer ISR count */ + Z8x36_WRITE( TIMER, MASTER_INTR, 0x01 ); /* reset */ + Z8x36_WRITE( TIMER, MASTER_INTR, 0x00 ); /* clear reset */ + Z8x36_WRITE( TIMER, MASTER_INTR, 0xe2 ); /* disable lower chain, no vec */ + /* set right justified addr */ + /* and master int enable */ + Z8x36_WRITE( TIMER, CT1_MODE_SPEC, 0x80 ); /* T1 continuous, and */ + /* cycle/pulse output */ + + *((rtems_unsigned16 *)0xfffb0016) = 0x0000; /* write countdown value */ +/* + Z8x36_WRITE( TIMER, CT1_TIME_CONST_MSB, 0x00 ); + Z8x36_WRITE( TIMER, CT1_TIME_CONST_LSB, 0x00 ); +*/ + Z8x36_WRITE( TIMER, MASTER_CFG, 0xc4 ); /* enable timer1 */ + + Z8x36_WRITE( TIMER, CT1_CMD_STATUS, 0xc6 ); /* set INTR enable (IE), */ + /* trigger command */ + /* (TCB) and gate */ + /* command (GCB) bits */ + *((rtems_unsigned8 *)0xfffb0038) &= 0xfd; /* enable timer INTR on */ + /* VME controller */ +} + +#define AVG_OVERHEAD 6 /* It typically takes 3.0 microseconds */ + /* (6 countdowns) to start/stop the timer. */ +#define LEAST_VALID 10 /* Don't trust a value lower than this */ + +int Read_timer() +{ +/* + rtems_unsigned8 msb, lsb; +*/ + rtems_unsigned32 remaining, total; + + Z8x36_WRITE( TIMER, CT1_CMD_STATUS, 0xce ); /* read the counter value */ +remaining = 0xffff - *((rtems_unsigned16 *) 0xfffb0010); +/* + Z8x36_READ( TIMER, CT1_CUR_CNT_MSB, msb ); + Z8x36_READ( TIMER, CT1_CUR_CNT_LSB, lsb ); + + remaining = 0xffff - ((msb << 8) + lsb); +*/ + total = (Ttimer_val * 0x10000) + remaining; + + if ( Timer_driver_Find_average_overhead == 1 ) + return total; /* in one-half microsecond units */ + + else { + if ( total < LEAST_VALID ) + return 0; /* below timer resolution */ + return (total-AVG_OVERHEAD) >> 1; + } +} + +rtems_status_code Empty_function( void ) +{ + return RTEMS_SUCCESSFUL; +} + +void Set_find_average_overhead( + rtems_boolean find_flag +) +{ + Timer_driver_Find_average_overhead = find_flag; +} diff --git a/c/src/lib/libbsp/m68k/mvme136/timer/timerisr.s b/c/src/lib/libbsp/m68k/mvme136/timer/timerisr.s new file mode 100644 index 0000000000..a8f7e7b212 --- /dev/null +++ b/c/src/lib/libbsp/m68k/mvme136/timer/timerisr.s @@ -0,0 +1,39 @@ +# timer_isr() +# +# This routine provides the ISR for the Z8036 timer on the MVME136 +# board. The timer is set up to generate an interrupt at maximum +# intervals. +# +# Input parameters: NONE +# +# Output parameters: NONE +# +# COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. +# On-Line Applications Research Corporation (OAR). +# All rights assigned to U.S. Government, 1994. +# +# This material may be reproduced by or for the U.S. Government pursuant +# to the copyright license under the clause at DFARS 252.227-7013. This +# notice must appear in all copies of this file and its derivatives. +# +# $Id$ +# + +#include "asm.h" + +BEGIN_CODE + +.set CT1_CMD_STATUS, 0xfffb000a | port A +.set RELOAD, 0x24 | clr IP & IUS,allow countdown + + PUBLIC (timerisr) +SYM (timerisr): + movl a0,a7@- | save a0 + movl #CT1_CMD_STATUS,a0 | a0 = addr of cmd status reg + movb #RELOAD,a0@ | reload countdown + addql #1, SYM (Ttimer_val) | increment timer value + movl a7@+,a0 | save a0 + rte + +END_CODE +END diff --git a/c/src/lib/libbsp/m68k/mvme162/README b/c/src/lib/libbsp/m68k/mvme162/README new file mode 100644 index 0000000000..cdb1f28348 --- /dev/null +++ b/c/src/lib/libbsp/m68k/mvme162/README @@ -0,0 +1,124 @@ +-- +-- EISCAT Scientific Association. M.Savitski +-- +-- This material is a part of the MVME162 Board Support Package +-- for the RTEMS executive. Its licensing policies are those of the +-- RTEMS distribution. +-- +-- Updated by Joel Sherrill (jsherril@redstone.army.mil) after +-- inclusion in the standard release. +-- +-- $Id$ +-- + +This is a README file for the MVME162 port of RTEMS. + +Disclaimer +---------- +This is my first attempt at porting RTEMS. The resulting code obviously +contains bugs (know and unknown) and limitations. I assume no +responsibility for quality and support of the software in question. + +Now on more optimistic note: + +I have run most of the standard RTEMS sptests, and neither of them +failed. My present (short) experience of developing RTEMS applications +is essentially positive and suggestive of a long-term commitment. In +any case I am ready to answer questions regarding the port and intend +to follow the future RTEMS versions. I will do my best to provide +whatever support I can afford time-wise. + +Installation +------------ +Nothing unique to the MVME162. It has been incorporated into the +standard release. + +Port Description +---------------- +The port was done using already existing ports to the M68020 boards, +DMV152 and MVME136. + +The host system was SUN/Solaris 2.3, and the cross-development +environment consisted of Free Software Foundation (FSF)'s GNU C +compiler (version 2.6), GNU Assembler (version 2.3) and GNU binary +utilities binutils version 2.5.2, built with m68k as a target. The +recent/latest versions of other GNU programs (flex, make, etc) were +also used at the build stage. + +In all subdirectories of the RTEMS distribution tree, the directories +mvme136 were duplicated as mvme162. + +Essential modifications are detailed below: + +- the MVME162-specific hardware registers were described in bsp.h + +- timer and clock routines were made to use the MVME162's Tick Timers 1 +and 2, respectively + +- shared memory support was replaced by stubs for the time being + +- console IO was lifted entirely from the DMV152 support code, thanks +to the fact that Z8530 SCC used in DMV152 is upwards compatible with +the Z85230 SCC of the MVME162. (Only the memory mapping of the SCC +registers had to be changed.) + +- symbols in several *.s files were prepended with underscores to +comply with the xgcc configuration used (it prepends underscores to all +symbols defined in c code) + +- linkcmds file was modified to place the linked code into the memory +configured for the board in use + +- bspstart.c was modified as follows: + + monitors_vector_table = (m68k_isr *)0xFFE00000; + +was made to point to the power-up location of MVME162 interrupt vector +table. + +- The shutdown is a temporary solution. To exit cleanly, it has to disable +all enabled interrupts and restore the board to its power-up status. +Presently this is not done satisfactorily, as a result, the board needs +a hardware reset from the external VMEbus master or from the front +panel to ensure correct operation for subsequent downloads. + +Host System +----------- +The VMEbus master used to externally control and download the MVME162 +is a FORCE CPU-2CE board running Solaris 2.3. A simple program to load +s-records and start/reset the MVME162 was written. The code is in the +file tools/sload.c + +This code depends on the external VMEbus master's vme driver and is +provided as an example, without the Makefile. The bulk of the program +which parses the s-records is courtesy of Kym Newbery, +(8918927y@lux.levels.unisa.edu.au). + +In general, apart from x-gcc, the tools most often used while building +RTEMS for MVME162 were: find, grep, diff, and, of course + +MVME162 Embedded Controller Programmer's Reference Guide, +Motorola, MVME162PG/D1. + +Thanks +------ +- to On-Line Applications Research Corporation (OAR) for developing +RTEMS and making it available on a Technology Transfer basis; +- to Joel Sherril, the leader of the RTEMS development group for +stimulating and helpful discussions; +- to Kym Newbery (8918927y@lux.levels.unisa.edu.au) for his s-record +parser; +- to Gerd Truschinski (gt@first.gmd.de) for creating and running the +crossgcc mailing list +- to FSF and Cygnus Support for great free software; + + ++----------------------------------+-------------------------------+ +| Dr. Mikhail (Misha) Savitski | Voice : +46-980-79162 | +| Software Systems Engineer | Fax : +46-980-79161 | +| EISCAT Svalbard Radar Project | E-mail: mms@eiscathq.irf.se | +| EISCAT Scientific Association |----------- /\_/\ -----------| +| Box 812 S-98128 Kiruna, Sweden | EIS { o o } CAT | ++----------------------------------+-------oQQQ--(>I<)--QQQo-------+ + + diff --git a/c/src/lib/libbsp/m68k/mvme162/clock/ckinit.c b/c/src/lib/libbsp/m68k/mvme162/clock/ckinit.c new file mode 100644 index 0000000000..95e35e5f66 --- /dev/null +++ b/c/src/lib/libbsp/m68k/mvme162/clock/ckinit.c @@ -0,0 +1,91 @@ +/* Clock_init() + * + * This routine initializes the Tick Timer 2 on the MVME162 board. + * The tick frequency is 1 millisecond. + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * Modifications of respective RTEMS file: COPYRIGHT (c) 1994. + * EISCAT Scientific Association. M.Savitski + * + * This material is a part of the MVME162 Board Support Package + * for the RTEMS executive. Its licensing policies are those of the + * RTEMS above. + * + * $Id$ + */ + +#include + +#include +#include +#include + +#define MS_COUNT 1000 /* T2's countdown constant (1 ms) */ +#define CLOCK_INT_LEVEL 6 /* T2's interrupt level */ + +rtems_unsigned32 Clock_isrs; /* ISRs until next tick */ +volatile rtems_unsigned32 Clock_driver_ticks; + /* ticks since initialization */ +rtems_isr_entry Old_ticker; + +rtems_device_driver Clock_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *pargp, + rtems_id tid, + rtems_unsigned32 *rval +) +{ + Install_clock( Clock_isr ); +} + +void ReInstall_clock( clock_isr ) +rtems_isr_entry clock_isr; +{ + rtems_unsigned32 isrlevel; + + rtems_interrupt_disable( isrlevel ); + (void) set_vector( clock_isr, (VECTOR_BASE >> 28) * 0x10 + 0x9, 1 ); + rtems_interrupt_enable( isrlevel ); +} + +void Install_clock( clock_isr ) +rtems_isr_entry clock_isr; +{ + + Clock_driver_ticks = 0; + Clock_isrs = BSP_Configuration.microseconds_per_tick / 1000; + + if ( BSP_Configuration.ticks_per_timeslice ) { + Old_ticker = (rtems_isr_entry) + set_vector( clock_isr, (VECTOR_BASE >> 28) * 0x10 + 0x9, 1 ); + + lcsr->vector_base = 0x67800000; /* set vb, enable interrupts */ + lcsr->to_ctl = 0xE7; /* prescaler to 1 MHz (see Appendix A1) */ + lcsr->timer_cmp_2 = MS_COUNT; + lcsr->timer_cnt_2 = 0; /* clear counter */ + lcsr->board_ctl |= 0x700; /* increment, reset-on-compare, clear-ovfl-cnt */ + + lcsr->intr_level[0] |= CLOCK_INT_LEVEL * 0x10; /* set int level */ + lcsr->intr_ena |= 0x02000000; /* enable tick timer 2 interrupt */ + + atexit( Clock_exit ); + } + +} + +void Clock_exit( void ) +{ +/* Dummy for now. See other m68k BSP's for code examples */ +} diff --git a/c/src/lib/libbsp/m68k/mvme162/console/console.c b/c/src/lib/libbsp/m68k/mvme162/console/console.c new file mode 100644 index 0000000000..7e8f5132f9 --- /dev/null +++ b/c/src/lib/libbsp/m68k/mvme162/console/console.c @@ -0,0 +1,193 @@ +/* + * This file contains the MVME162 console IO package. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * Modifications of respective RTEMS file: COPYRIGHT (c) 1994. + * EISCAT Scientific Association. M.Savitski + * + * This material is a part of the MVME162 Board Support Package + * for the RTEMS executive. Its licensing policies are those of the + * RTEMS above. + * + * $Id$ + */ + +#define M162_INIT + +#include +#include "console.h" +#include "bsp.h" + +/* console_initialize + * + * This routine initializes the console IO driver. + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * Return values: + */ + +rtems_device_driver console_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg, + rtems_id self, + rtems_unsigned32 *status +) +{ + *status = RTEMS_SUCCESSFUL; +} + + +/* is_character_ready + * + * This routine returns TRUE if a character is available. + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * Return values: + */ + +rtems_boolean is_character_ready( + char *ch +) +{ + rtems_unsigned8 rr_0; + + Z8x30_READ_CONTROL( CONSOLE_CONTROL, RR_0, rr_0 ); + if ( !(rr_0 & RR_0_RX_DATA_AVAILABLE) ) + return( FALSE ); + + Z8x30_READ_DATA( CONSOLE_DATA, *ch ); + + return(TRUE); +} + +/* inbyte + * + * This routine reads a character from the SCC. + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * Return values: + * character read from SCC + */ + +char inbyte( void ) +{ + rtems_unsigned8 rr_0; + char ch; + + while ( 1 ) { + Z8x30_READ_CONTROL( CONSOLE_CONTROL, RR_0, rr_0 ); + if ( (rr_0 & RR_0_RX_DATA_AVAILABLE) != 0 ) + break; + } + + Z8x30_READ_DATA( CONSOLE_DATA, ch ); + return ch; +} + + +/* outbyte + * + * This routine transmits a character out the SCC. It supports + * XON/XOFF flow control. + * + * Input parameters: + * ch - character to be transmitted + * + * Output parameters: NONE + */ + +void outbyte( + char ch +) +{ + rtems_unsigned8 rr_0; + char flow_control; + + while ( 1 ) { + Z8x30_READ_CONTROL( CONSOLE_CONTROL, RR_0, rr_0 ); + if ( (rr_0 & RR_0_TX_BUFFER_EMPTY) != 0 ) + break; + } + + while ( 1 ) { + Z8x30_READ_CONTROL( CONSOLE_CONTROL, RR_0, rr_0 ); + if ( (rr_0 & RR_0_RX_DATA_AVAILABLE) == 0 ) + break; + + Z8x30_READ_DATA( CONSOLE_DATA, flow_control ); + + if ( flow_control == XOFF ) + do { + do { + Z8x30_READ_CONTROL( CONSOLE_CONTROL, RR_0, rr_0 ); + } while ( (rr_0 & RR_0_RX_DATA_AVAILABLE) == 0 ); + Z8x30_READ_DATA( CONSOLE_DATA, flow_control ); + } while ( flow_control != XON ); + } + + Z8x30_WRITE_DATA( CONSOLE_DATA, ch ); +} + +/* + * __read -- read bytes from the serial port. Ignore fd, since + * we only have stdin. + */ + +int __read( + int fd, + char *buf, + int nbytes +) +{ + int i = 0; + + for (i = 0; i < nbytes; i++) { + *(buf + i) = inbyte(); + if ((*(buf + i) == '\n') || (*(buf + i) == '\r')) { + (*(buf + i++)) = '\n'; + (*(buf + i)) = 0; + break; + } + } + return (i); +} + +/* + * __write -- write bytes to the serial port. Ignore fd, since + * stdout and stderr are the same. Since we have no filesystem, + * open will only return an error. + */ + +int __write( + int fd, + char *buf, + int nbytes +) +{ + int i; + + for (i = 0; i < nbytes; i++) { + if (*(buf + i) == '\n') { + outbyte ('\r'); + } + outbyte (*(buf + i)); + } + return (nbytes); +} diff --git a/c/src/lib/libbsp/m68k/mvme162/include/bsp.h b/c/src/lib/libbsp/m68k/mvme162/include/bsp.h new file mode 100644 index 0000000000..0b3a7d76d8 --- /dev/null +++ b/c/src/lib/libbsp/m68k/mvme162/include/bsp.h @@ -0,0 +1,225 @@ +/* bsp.h + * + * This include file contains all MVME162 board IO definitions. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * Modifications of respective RTEMS file: COPYRIGHT (c) 1994. + * EISCAT Scientific Association. M.Savitski + * + * This material is a part of the MVME162 Board Support Package + * for the RTEMS executive. Its licensing policies are those of the + * RTEMS above. + * + * $Id$ + */ + +#ifndef __MVME162_h +#define __MVME162_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +/* +// Following defines must reflect the setup of the particular MVME162 +//----------------------------------- +*/ +#define GROUP_BASE_ADDRESS 0x0000F200 +#define BOARD_BASE_ADDRESS 0x00000000 +/* Base for local interrupters' vectors (with enable bit set) */ +#define VECTOR_BASE 0x67800000 +/* RAM limits */ +#define RAM_START 0x00100000 +#define RAM_END 0x00200000 +/* +//----------------------------------- +*/ +static volatile struct lcsr { + unsigned long slave_adr[2]; + unsigned long slave_trn[2]; + unsigned long slave_ctl; + unsigned long mastr_adr[4]; + unsigned long mastr_trn; + unsigned long mastr_att; + unsigned long mastr_ctl; + unsigned long dma_ctl_1; + unsigned long dma_ctl_2; + unsigned long dma_loc_cnt; + unsigned long dma_vme_cnt; + unsigned long dma_byte_cnt; + unsigned long dma_adr_cnt; + unsigned long dma_status; + unsigned long to_ctl; + unsigned long timer_cmp_1; + unsigned long timer_cnt_1; + unsigned long timer_cmp_2; + unsigned long timer_cnt_2; + unsigned long board_ctl; + unsigned long prescaler_cnt; + unsigned long intr_stat; + unsigned long intr_ena; + unsigned long intr_soft_set; + unsigned long intr_clear; + unsigned long intr_level[4]; + unsigned long vector_base; +} *lcsr = (void *) 0xFFF40000; + +#define USE_CHANNEL_A 1 /* 1 = use channel A for console */ +#define USE_CHANNEL_B 0 /* 1 = use channel B for console */ + +/* Constants */ + +#if (USE_CHANNEL_A == 1) + #define CONSOLE_CONTROL 0xFFF45005 + #define CONSOLE_DATA 0xFFF45007 +#elif (USE_CHANNEL_B == 1) + #define CONSOLE_CONTROL 0xFFF45001 + #define CONSOLE_DATA 0xFFF45003 +#endif + +/* +// The following registers are located in the VMEbus short +// IO space and respond to address modifier codes $29 and $2D. +// On FORCE SPARC CPU use address gcsr_vme and device /dev/vme16d32. +*/ +static volatile struct gcsr { + unsigned char chip_revision; + unsigned char chip_id; + unsigned char lmsig; + unsigned char board_scr; + unsigned short gpr[6]; +} *gcsr_vme = (void *) (GROUP_BASE_ADDRESS + BOARD_BASE_ADDRESS), + *gcsr = (void *) 0xFFF40100; + +static volatile unsigned short *ipio[6] = { (unsigned short *) 0xFFF58000, + (unsigned short *) 0xFFF58100, + (unsigned short *) 0xFFF58200, + (unsigned short *) 0xFFF58300, + (unsigned short *) 0xFFF58400, + (unsigned short *) 0xFFF58500 + }; + +static volatile unsigned short *ipid[6] = { (unsigned short *) 0xFFF58080, + (unsigned short *) 0xFFF58180, + (unsigned short *) 0xFFF58280, + (unsigned short *) 0xFFF58380, + (unsigned short *) 0xFFF58080, + (unsigned short *) 0xFFF58280 + }; + +static volatile struct ipic_space { + struct sing { + unsigned short io_space[64]; + unsigned short id_space[32]; + unsigned short id_reptd[32]; + } single[4]; + struct twin { + unsigned short io_space[128]; + unsigned short io_reptd[128]; + } twin[2]; +} *ipic_space = (void *) 0xFFF58000; + +static volatile struct ipic_csr { + unsigned char chip_id; + unsigned char chip_rev; + unsigned char res[2]; + unsigned short a_31_16_base; + unsigned short b_31_16_base; + unsigned short c_31_16_base; + unsigned short d_31_16_base; + unsigned char a_23_16_size; + unsigned char b_23_16_size; + unsigned char c_23_16_size; + unsigned char d_23_16_size; + unsigned short a_intr_cnt; + unsigned short b_intr_cnt; + unsigned short c_intr_cnt; + unsigned short d_intr_cnt; +} *ipic_csr = (void *) 0xFFFBC000; + +/* + * Define the time limits for RTEMS Test Suite test durations. + * Long test and short test duration limits are provided. These + * values are in seconds and need to be converted to ticks for the + * application. + * + */ + +#define MAX_LONG_TEST_DURATION 300 /* 5 minutes = 300 seconds */ +#define MAX_SHORT_TEST_DURATION 3 /* 3 seconds */ + +/* + * Define the interrupt mechanism for Time Test 27 + * + * NOTE: Not implemented + */ + +#define MUST_WAIT_FOR_INTERRUPT 0 + +#define Install_tm27_vector( handler ) + +#define Cause_tm27_intr() + +#define Clear_tm27_intr() + +#define Lower_tm27_intr() + +/* + * Simple spin delay in microsecond units for device drivers. + * This is very dependent on the clock speed of the target. + */ + +#define delay( microseconds ) \ + { register rtems_unsigned32 _delay=(microseconds); \ + register rtems_unsigned32 _tmp=123; \ + asm volatile( "0: \ + nbcd %0 ; \ + nbcd %0 ; \ + dbf %1,0b" \ + : "=d" (_tmp), "=d" (_delay) \ + : "0" (_tmp), "1" (_delay) ); \ + } + +/* Constants */ + +#ifdef 1626_INIT +#undef EXTERN +#define EXTERN +#else +#undef EXTERN +#define EXTERN extern +#endif + +/* miscellaneous stuff assumed to exist */ + +extern rtems_configuration_table BSP_Configuration; + +extern m68k_isr M68Kvec[]; /* vector table address */ + +/* functions */ + +void bsp_cleanup( void ); + +m68k_isr set_vector( + rtems_isr_entry handler, + rtems_vector_number vector, + int type +); + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/c/src/lib/libbsp/m68k/mvme162/include/coverhd.h b/c/src/lib/libbsp/m68k/mvme162/include/coverhd.h new file mode 100644 index 0000000000..0033a50502 --- /dev/null +++ b/c/src/lib/libbsp/m68k/mvme162/include/coverhd.h @@ -0,0 +1,104 @@ +/* coverhd.h + * + * This include file has defines to represent the overhead associated + * with calling a particular directive from C on this target. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __COVERHD_h +#define __COVERHD_h + +#ifdef __cplusplus +extern "C" { +#endif + +#define CALLING_OVERHEAD_INITIALIZE_EXECUTIVE 2 +#define CALLING_OVERHEAD_SHUTDOWN_EXECUTIVE 1 +#define CALLING_OVERHEAD_TASK_CREATE 3 +#define CALLING_OVERHEAD_TASK_IDENT 2 +#define CALLING_OVERHEAD_TASK_START 2 +#define CALLING_OVERHEAD_TASK_RESTART 2 +#define CALLING_OVERHEAD_TASK_DELETE 1 +#define CALLING_OVERHEAD_TASK_SUSPEND 1 +#define CALLING_OVERHEAD_TASK_RESUME 2 +#define CALLING_OVERHEAD_TASK_SET_PRIORITY 2 +#define CALLING_OVERHEAD_TASK_MODE 2 +#define CALLING_OVERHEAD_TASK_GET_NOTE 2 +#define CALLING_OVERHEAD_TASK_SET_NOTE 2 +#define CALLING_OVERHEAD_TASK_WAKE_WHEN 4 +#define CALLING_OVERHEAD_TASK_WAKE_AFTER 1 +#define CALLING_OVERHEAD_INTERRUPT_CATCH 2 +#define CALLING_OVERHEAD_CLOCK_GET 4 +#define CALLING_OVERHEAD_CLOCK_SET 4 +#define CALLING_OVERHEAD_CLOCK_TICK 1 + +#define CALLING_OVERHEAD_TIMER_CREATE 2 +#define CALLING_OVERHEAD_TIMER_IDENT 1 +#define CALLING_OVERHEAD_TIMER_DELETE 2 +#define CALLING_OVERHEAD_TIMER_FIRE_AFTER 2 +#define CALLING_OVERHEAD_TIMER_FIRE_WHEN 5 +#define CALLING_OVERHEAD_TIMER_RESET 1 +#define CALLING_OVERHEAD_TIMER_CANCEL 1 +#define CALLING_OVERHEAD_SEMAPHORE_CREATE 2 +#define CALLING_OVERHEAD_SEMAPHORE_IDENT 1 +#define CALLING_OVERHEAD_SEMAPHORE_DELETE 2 +#define CALLING_OVERHEAD_SEMAPHORE_OBTAIN 2 +#define CALLING_OVERHEAD_SEMAPHORE_RELEASE 1 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_CREATE 2 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_IDENT 2 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_DELETE 1 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_SEND 2 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_URGENT 2 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_BROADCAST 2 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_RECEIVE 2 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_FLUSH 2 + +#define CALLING_OVERHEAD_EVENT_SEND 2 +#define CALLING_OVERHEAD_EVENT_RECEIVE 2 +#define CALLING_OVERHEAD_SIGNAL_CATCH 2 +#define CALLING_OVERHEAD_SIGNAL_SEND 2 +#define CALLING_OVERHEAD_PARTITION_CREATE 3 +#define CALLING_OVERHEAD_PARTITION_IDENT 2 +#define CALLING_OVERHEAD_PARTITION_DELETE 2 +#define CALLING_OVERHEAD_PARTITION_GET_BUFFER 2 +#define CALLING_OVERHEAD_PARTITION_RETURN_BUFFER 2 +#define CALLING_OVERHEAD_REGION_CREATE 3 +#define CALLING_OVERHEAD_REGION_IDENT 2 +#define CALLING_OVERHEAD_REGION_DELETE 1 +#define CALLING_OVERHEAD_REGION_GET_SEGMENT 3 +#define CALLING_OVERHEAD_REGION_RETURN_SEGMENT 2 +#define CALLING_OVERHEAD_PORT_CREATE 3 +#define CALLING_OVERHEAD_PORT_IDENT 2 +#define CALLING_OVERHEAD_PORT_DELETE 2 +#define CALLING_OVERHEAD_PORT_EXTERNAL_TO_INTERNAL 2 +#define CALLING_OVERHEAD_PORT_INTERNAL_TO_EXTERNAL 2 + +#define CALLING_OVERHEAD_IO_INITIALIZE 3 +#define CALLING_OVERHEAD_IO_OPEN 2 +#define CALLING_OVERHEAD_IO_CLOSE 2 +#define CALLING_OVERHEAD_IO_READ 2 +#define CALLING_OVERHEAD_IO_WRITE 2 +#define CALLING_OVERHEAD_IO_CONTROL 2 +#define CALLING_OVERHEAD_FATAL_ERROR_OCCURRED 1 +#define CALLING_OVERHEAD_RATE_MONOTONIC_CREATE 2 +#define CALLING_OVERHEAD_RATE_MONOTONIC_IDENT 2 +#define CALLING_OVERHEAD_RATE_MONOTONIC_DELETE 1 +#define CALLING_OVERHEAD_RATE_MONOTONIC_CANCEL 1 +#define CALLING_OVERHEAD_RATE_MONOTONIC_PERIOD 2 +#define CALLING_OVERHEAD_MULTIPROCESSING_ANNOUNCE 1 + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/c/src/lib/libbsp/m68k/mvme162/startup/bspclean.c b/c/src/lib/libbsp/m68k/mvme162/startup/bspclean.c new file mode 100644 index 0000000000..215a53cc46 --- /dev/null +++ b/c/src/lib/libbsp/m68k/mvme162/startup/bspclean.c @@ -0,0 +1,53 @@ +/* + * This routine returns control to 162Bug. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * + * Modifications of respective RTEMS file: COPYRIGHT (c) 1994. + * EISCAT Scientific Association. M.Savitski + * + * This material is a part of the MVME162 Board Support Package + * for the RTEMS executive. Its licensing policies are those of the + * RTEMS above. + * + * $Id$ + */ + +#include +#include +#include + +void bsp_return_to_monitor_trap() +{ + extern void start( void ); + + lcsr->intr_ena = 0; /* disable interrupts */ + m68k_set_vbr(0xFFE00000); /* restore 162Bug vectors */ + asm volatile( "trap #15" ); /* trap to 162Bug */ + asm volatile( ".short 0x63" ); /* return to 162Bug (.RETURN) */ + /* restart program */ + /* + * This does not work on the 162.... + */ +#if 0 + { register volatile void *start_addr; + + start_addr = start; + + asm volatile ( "jmp %0@" : "=a" (start_addr) : "0" (start_addr) ); + } +#endif +} + +void bsp_cleanup( void ) +{ + M68Kvec[ 45 ] = bsp_return_to_monitor_trap; /* install handler */ + asm volatile( "trap #13" ); /* insures SUPV mode */ +} diff --git a/c/src/lib/libbsp/m68k/mvme162/startup/bspstart.c b/c/src/lib/libbsp/m68k/mvme162/startup/bspstart.c new file mode 100644 index 0000000000..fb137f7ebc --- /dev/null +++ b/c/src/lib/libbsp/m68k/mvme162/startup/bspstart.c @@ -0,0 +1,171 @@ +/* bsp_start() + * + * This routine starts the application. It includes application, + * board, and monitor specific initialization and configuration. + * The generic CPU dependent initialization has been performed + * before this routine is invoked. + * + * INPUT: NONE + * + * OUTPUT: NONE + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * Modifications of respective RTEMS file: COPYRIGHT (c) 1994. + * EISCAT Scientific Association. M.Savitski + * + * This material is a part of the MVME162 Board Support Package + * for the RTEMS executive. Its licensing policies are those of the + * RTEMS above. + * + * $Id$ + */ + +#include +#include +#include +#include + +/* + * The original table from the application and our copy of it with + * some changes. + */ + +extern rtems_configuration_table Configuration; +rtems_configuration_table BSP_Configuration; + +rtems_cpu_table Cpu_table; + +/* Initialize whatever libc we are using + * called from postdriver hook + */ + +void bsp_libc_init() +{ + extern int end; + rtems_unsigned32 heap_start; + + heap_start = (rtems_unsigned32) &end; + if (heap_start & (CPU_ALIGNMENT-1)) + heap_start = (heap_start + CPU_ALIGNMENT) & ~(CPU_ALIGNMENT-1); + + RTEMS_Malloc_Initialize((void *) heap_start, 64 * 1024, 0); + + /* + * Set up for the libc handling. + */ + + if (BSP_Configuration.ticks_per_timeslice > 0) + libc_init(1); /* reentrant if possible */ + else + libc_init(0); /* non-reentrant */ + + /* + * Initialize the stack bounds checker + */ + +#ifdef STACK_CHECKER_ON + Stack_check_Initialize(); +#endif +} + +int bsp_start( + int argc, + char **argv, + char **environp +) +{ + m68k_isr *monitors_vector_table; + int index; + + /* + * 162Bug Vectors are at 0xFFE00000 + */ + + monitors_vector_table = (m68k_isr *)0xFFE00000; + + m68k_set_vbr( monitors_vector_table ); + + for ( index=2 ; index<=255 ; index++ ) + M68Kvec[ index ] = monitors_vector_table[ 32 ]; + + M68Kvec[ 2 ] = monitors_vector_table[ 2 ]; /* bus error vector */ + M68Kvec[ 4 ] = monitors_vector_table[ 4 ]; /* breakpoints vector */ + M68Kvec[ 9 ] = monitors_vector_table[ 9 ]; /* trace vector */ + M68Kvec[ 47 ] = monitors_vector_table[ 47 ]; /* system call vector */ + + m68k_set_vbr( &M68Kvec ); + + /* + * You may wish to make VME access round-robin here, currently + * we leave it as it is. + */ + + lcsr->vector_base = VECTOR_BASE; /* set the vector base register */ + + m68k_enable_caching(); + + /* + * we only use a hook to get the C library initialized. + */ + + Cpu_table.pretasking_hook = NULL; + + Cpu_table.predriver_hook = bsp_libc_init; /* RTEMS resources available */ + + Cpu_table.postdriver_hook = NULL; /* Call our main() for constructors */ + + Cpu_table.idle_task = NULL; /* do not override system IDLE task */ + + Cpu_table.do_zero_of_workspace = TRUE; + + Cpu_table.interrupt_vector_table = (m68k_isr *) &M68Kvec; + + Cpu_table.interrupt_stack_size = 4096; + + Cpu_table.extra_system_initialization_stack = 0; + + /* + * Copy the table + */ + + BSP_Configuration = Configuration; + + /* + * Add 1 region for the RTEMS Malloc + */ + + BSP_Configuration.maximum_regions++; + + /* + * Add 1 extension for newlib libc + */ + +#ifdef RTEMS_NEWLIB + BSP_Configuration.maximum_extensions++; +#endif + + /* + * Add another extension if using the stack checker + */ + +#ifdef STACK_CHECKER_ON + BSP_Configuration.maximum_extensions++; +#endif + + BSP_Configuration.work_space_start = (void *) + (RAM_END - BSP_Configuration.work_space_size); + + rtems_initialize_executive( &BSP_Configuration, &Cpu_table ); + /* does not return */ + + bsp_cleanup(); + + return 0; +} diff --git a/c/src/lib/libbsp/m68k/mvme162/startup/linkcmds b/c/src/lib/libbsp/m68k/mvme162/startup/linkcmds new file mode 100644 index 0000000000..21a844ca88 --- /dev/null +++ b/c/src/lib/libbsp/m68k/mvme162/startup/linkcmds @@ -0,0 +1,50 @@ +/* + * This file contains directives for the GNU linker which are specific + * to the Motorola MVME162 board. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * Modifications of respective RTEMS file: COPYRIGHT (c) 1994. + * EISCAT Scientific Association. M.Savitski + * + * This material is a part of the MVME162 Board Support Package + * for the RTEMS executive. Its licensing policies are those of the + * RTEMS above. + * + * $Id$ + */ + +MEMORY + { + ram : org = 0x100000, l = 1M + } + +SECTIONS +{ + .text 0x100000 : + { + text_start = . ; + *(.text) + etext = ALIGN( 0x10 ) ; + } + .data ADDR( .text ) + SIZEOF( .text ): + { + data_start = . ; + *(.data) + edata = ALIGN( 0x10 ) ; + } + .bss ADDR( .data ) + SIZEOF( .data ): + { + bss_start = . ; + *(.bss) + *(COMMON) + end = . ; + _end = . ; + } +} diff --git a/c/src/lib/libbsp/m68k/mvme162/timer/timer.c b/c/src/lib/libbsp/m68k/mvme162/timer/timer.c new file mode 100644 index 0000000000..c000fadd28 --- /dev/null +++ b/c/src/lib/libbsp/m68k/mvme162/timer/timer.c @@ -0,0 +1,91 @@ +/* Timer_init() + * + * This routine initializes the Tick Timer 1 on the MVME162 board. + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * NOTE: This routine will not work if the optimizer is enabled + * for some compilers. The multiple writes + * may be optimized away. + * + * It is important that the timer start/stop overhead be + * determined when porting or modifying this code. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * Modifications of respective RTEMS file: COPYRIGHT (c) 1994. + * EISCAT Scientific Association. M.Savitski + * + * This material is a part of the MVME162 Board Support Package + * for the RTEMS executive. Its licensing policies are those of the + * RTEMS above. + * + * $Id$ + */ + + +#include +#include + +/* Periodic tick interval */ +#define TICK_INTERVAL 0x10000 +#define TIMER_INT_LEVEL 6 + +int Ttimer_val; +rtems_boolean Timer_driver_Find_average_overhead; + +rtems_isr timerisr(); + +void Timer_initialize() +{ + (void) set_vector( timerisr, (VECTOR_BASE >> 28) * 0x10 + 0x8, 0 ); + + Ttimer_val = 0; /* clear timer ISR count */ + lcsr->vector_base = 0x67800000; /* set vb, enable interrupts */ + lcsr->to_ctl = 0xE7; /* prescaler to 1 MHz (see Appendix A1) */ + lcsr->timer_cmp_1 = TICK_INTERVAL; + lcsr->timer_cnt_1 = 0; /* clear counter */ + lcsr->board_ctl |= 7; /* increment, reset-on-compare, clear-ovfl-cnt */ + + lcsr->intr_level[0] |= TIMER_INT_LEVEL; /* set int level */ + lcsr->intr_ena |= 0x01000000; /* enable tick timer 1 interrupt */ +} + +#define AVG_OVERHEAD 6 /* It typically takes 3.0 microseconds */ + /* (6 countdowns) to start/stop the timer. */ +#define LEAST_VALID 10 /* Don't trust a value lower than this */ + +int Read_timer() +{ + unsigned long total; + + total = (Ttimer_val * TICK_INTERVAL) + lcsr->timer_cnt_1; + + if ( Timer_driver_Find_average_overhead == 1 ) + return total; /* in one-half microsecond units */ + + if ( total < LEAST_VALID ) + return 0; /* below timer resolution */ + + return (total-AVG_OVERHEAD); /* in musec units */ +} + +rtems_status_code Empty_function( void ) +{ + return RTEMS_SUCCESSFUL; +} + +void Set_find_average_overhead( + rtems_boolean find_flag +) +{ + Timer_driver_Find_average_overhead = find_flag; +} diff --git a/c/src/lib/libbsp/m68k/mvme162/timer/timerisr.s b/c/src/lib/libbsp/m68k/mvme162/timer/timerisr.s new file mode 100644 index 0000000000..af31e4276b --- /dev/null +++ b/c/src/lib/libbsp/m68k/mvme162/timer/timerisr.s @@ -0,0 +1,46 @@ +/* timer_isr() + * + * This routine provides the ISR for the Z8036 timer on the MVME136 + * board. The timer is set up to generate an interrupt at maximum + * intervals. + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * Modifications of respective RTEMS file: COPYRIGHT (c) 1994. + * EISCAT Scientific Association. M.Savitski + * + * This material is a part of the MVME162 Board Support Package + * for the RTEMS executive. Its licensing policies are those of the + * RTEMS above. + * + * $Id$ + */ + +#include "asm.h" + +BEGIN_CODE + +.set INTR_CLEAR_REG, 0xfff40074 | interrupt clear register +.set RELOAD, 0x01000000 | clear tick 1 interrupt + + PUBLIC (timerisr) +SYM (timerisr): + move.l a0, -(a7) | save a0 + movea.l #INTR_CLEAR_REG, a0 | a0 = addr of cmd status reg + ori.l #RELOAD, (a0) | reload countdown + addq.l #1, SYM (Ttimer_val) | increment timer value + move.l (a7)+, a0 | restore a0 + rte + +END_CODE +END diff --git a/c/src/lib/libbsp/m68k/mvme162/tools/sload.c b/c/src/lib/libbsp/m68k/mvme162/tools/sload.c new file mode 100644 index 0000000000..8ce44d7a4b --- /dev/null +++ b/c/src/lib/libbsp/m68k/mvme162/tools/sload.c @@ -0,0 +1,542 @@ +/* + * + * Copyright (c) 1994 by EISCAT Scientific Association. + * All Rights Reserved. + * M.Savitski + * + * S-record code - courtesy of Kym Newbery + * 8918927y@lux.levels.unisa.edu.au + * + * Loading S-records into the VMEbus memory. + * + * Loads an executable in s-record format into the MVME dual-ported + * memory and directs the MVME CPU to start execution. + * VMEbus access is done via the FORCE CPU-2CE vmeplus driver in + * read/write mode for loading and in mmap mode for accessing MVME registers. + * See mvme162.h for #define's dependent on the MVME162 setup. + * + * $Id$ + * + */ + +#include +#include +#include + + +#include +#include +#include +#include +#include +#include + +#include "../include/bsp.h" + +#define FALSE 0 +#define TRUE 1 + +#define DATA19 0 +#define DATA28 1 +#define DATA37 3 +#define HEADER 4 +#define TERMINATOR 5 +#define NONE 6 + +unsigned int ahdtoi(unsigned char digit); +int issrec(char *str); +int validrec(char *str); +void hdr2str(char *sstr, char *pstr); +unsigned long getaddr(char *str); +unsigned int datasize(char *str); +void usage (void); +int MVMEControl(u_long entry, int reset, int go); + +unsigned int ahdtoi(unsigned char digit) +/* converts a hexadecimal char to an integer + * + * entry : digit = character to convert + * : 0..15 = result + * : -1 = char is not a digit + */ +{ +/* check digit */ + if (!isxdigit(digit)) + return(-1); + + switch (toupper(digit)) { + case 'A' : return(0xA); + case 'B' : return(0xB); + case 'C' : return(0xC); + case 'D' : return(0xD); + case 'E' : return(0xE); + case 'F' : return(0xF); + default : return(digit - 0x30); + } +} + +int issrec(char *str) +/* attempts to identify the type of Srecord string passed + * + * entry : str = pointer to null terminated string + * returns : 0,1,2,3,5,7,8,9 for S0..S9 except S6 & S4 + * : -1 = invalid header or header not found + * : -2 = invalid header number + */ +{ +/* Check first character for S */ + if ((isupper(str[0]) && (str[0] == 'S')) || + (islower(str[0]) && (str[0] == 's'))) + { + /* check for valid header number */ + switch (str[1]) { + case '0' : return 0; /* header record */ + case '1' : return 1; /* data record, 2byte addr */ + case '2' : return 2; /* " " , 3byte addr */ + case '3' : return 3; /* " " , 4byte addr */ + case '5' : return 5; /* number of S1,S2,S3 blocks */ + case '7' : return 7; /* S3 terminator */ + case '8' : return 8; /* S2 terminator */ + case '9' : return 9; /* S1 terminator */ + default : return -2; /* all others are invalid */ + } + } + return(-1); +} + +int validrec(char *str) +/* Tests for a valid srecord. tests checksum & for nondigit characters + * doesn't rely on any other srecord routines. + * + * entry : str = pointer to null terminated string + * returns : -1 = srecord contains invalid characters + * : -2 = srecord checksum is invalid + * : -3 = srecord record length is invalid + * : 0 = srecord is valid + */ +{ + int cn = 1, rlen=0; + int mchksum=0, rchksum=0; + +/* first check if there are any non-digit characters except S */ + while (str[cn]!=0) + if (!isxdigit(str[cn++])) + return(-1); + +/* test number of data bytes */ + rlen = ahdtoi(str[2])* 0x10 + ahdtoi(str[3]); + if (((strlen(str)-4)/2U) != rlen) return(-3); + +/* get checksum from string */ + rchksum = ahdtoi(str[rlen*2+2])*0x10 + ahdtoi(str[rlen*2+3]); + /* string chksum */ + +/* now calculate my own checksum */ + for (cn=2; cn <= rlen*2; ) + mchksum += ahdtoi(str[cn++])*0x10 + ahdtoi(str[cn++]); + mchksum = ~mchksum & 0xFF; + if (mchksum != rchksum) return(-2); /* return -2 in not equal */ + +/* return OK if we didn't fail any of these tests */ + return(0); +} + +void hdr2str(char *sstr, char *pstr) +/* converts header record (S0) string into a plain string + * + * entry : sstr = pointer to S0 string record + * exit : pstr = pointer to string long enough to hold string + * (caller must allocate enough space for string) + */ +{ + int rlen, cn, pn=0; + + rlen = ahdtoi(sstr[2])*0x10 + ahdtoi(sstr[3]); + for (cn=8; cn <= rlen*2; ) + pstr[pn++] = ahdtoi(sstr[cn++])*0x10 + ahdtoi(sstr[cn++]); + pstr[pn]=0; +} + +unsigned long getaddr(char *str) +/* returns the address of the srecord in str. assumes record is valid. + * + * entry : str = pointer to srecord string + * exit : address of data, word or long. + */ +{ + unsigned long addr=0; + + switch (issrec(str)) { + case 0 : + case 1 : + case 5 : + case 9 : + addr = ahdtoi(str[4])*0x1000 + ahdtoi(str[5])*0x100 + + ahdtoi(str[6])*0x10 + ahdtoi(str[7]); + return(addr); + case 2 : + case 8 : + addr = ahdtoi(str[4])*0x100000 + ahdtoi(str[5])*0x10000 + + ahdtoi(str[6])*0x1000 + ahdtoi(str[7])*0x100 + + ahdtoi(str[8])*0x10 + ahdtoi(str[9]); + return(addr); + case 3 : + case 7 : + addr = ahdtoi(str[4])*0x10000000 + ahdtoi(str[5])*0x1000000 + + ahdtoi(str[6])*0x100000 + ahdtoi(str[7])*0x10000 + + ahdtoi(str[8])*0x1000 + ahdtoi(str[9])*0x100 + + ahdtoi(str[10])*0x10 + ahdtoi(str[11]); + return(addr); + default : return(-1); + } +} + +unsigned int datasize(char *str) +/* + * returns the number of data bytes in the srecord. assumes record is valid. + * + * entry : str = pointer to srecord string + * exit : number of bytes of data in the data field. + */ +{ + unsigned int size=0; + + switch (issrec(str)) { + case 0 : + case 1 : + case 5 : + case 7 : + case 8 : + case 9 : size = ahdtoi(str[2])*0x10 + ahdtoi(str[3]); + return(size-3); + case 2 : size = ahdtoi(str[2])*0x10 + ahdtoi(str[3]); + return(size-4); + case 3 : size = ahdtoi(str[2])*0x10 + ahdtoi(str[3]); + return(size-5); + default : return(-1); + } +} + +void usage (void) +/* + * prints correct usage on stdout + */ +{ + printf("\nUSAGE : sload [-v][-g][-r] [file]\n"); + printf(" file is an s-record file\n"); + printf(" -v for verbose summary of s-records loaded\n"); + printf(" -g to start execution\n"); + printf(" -r to reset MVME162\n\n"); +} + +int MVMEControl(u_long entry, int reset, int go) +/* Controls MVME-162 from other VME master: + * if entry != 0, loads it as start address + * if go != 0, starts program execution from entry + * if reset != 0, resets mvme162's local bus + * Depends upon #define'ed GROUP_BASE_ADDRESS and BOARD_BASE_ADDRESS + * which in turn are set by the 162-BUG's ENV command. + */ +{ + int vme; + char vmedev[32] = "/dev/vme16d32"; /* d32 is important !!! */ + u_long pagesize; + struct gcsr *gcsr_map; + + pagesize = sysconf(_SC_PAGESIZE); /* mmap likes to be page-aligned */ + + if ((vme = open(vmedev, O_RDWR)) == -1) { + perror("open"); + fprintf(stderr, "Cannot open vme as %s to access GCSR\n", vmedev); + return 1; + } + +/* "MAP_SHARED" is important here */ + gcsr_map = (struct gcsr *) + mmap(0, 0x1000, PROT_WRITE|PROT_READ, MAP_SHARED, + vme, (u_long)gcsr_vme / pagesize * pagesize); + if (gcsr_map == (struct gcsr *) - 1) { + perror("mmap"); + fprintf(stderr, "Cannot mmap() to remote bus address 0x%08X\n", + (u_long)gcsr_vme / pagesize * pagesize); + return 1; + } + +/* + * use GCSR to start execution in MVME162 + * adjust pointer to compensate for page alignement + */ + gcsr_map = (struct gcsr *)((u_long)gcsr_map + + (u_long)gcsr_vme % pagesize); + + if (reset) { /* reset the local bus... */ + gcsr_map->board_scr |= 0x80; + } + if (entry) { /* ...load start address... */ + gcsr_map->gpr[0] = entry >> 16U; + gcsr_map->gpr[1] = entry & 0x0000FFFF; + } + if (go) { /* ... and kick it in the ass! */ + gcsr_map->lmsig = 0x1; + } +} + +/*=================================================================== */ +main(int argc, char *argv[]) +{ + char inpstr[256]; + u_char image[256]; + char hdrstr[64]; + int i, j, k, result, size, line=0, lastrec=0; + long addr, tsize=0, naddr=0, blksize=0, blknum=1; + FILE *in; + char infile[256] = ""; + char vmedev[32] = "/dev/vme32d32"; /* Assume "/dev/vme32d32" */ + int vme, verbose = 0, go = 0, reset = 0, havefile = 0; + +/* Parse the command line */ + + --argc; + + while (argv++, argc--) { + if (**argv != '-') { + strcpy(infile, *argv); + havefile = 1; + } else if (!strcmp(*argv, "-v")) { + verbose = 1; + } else if (!strcmp(*argv, "-g")) { + go = 1; + } else if (!strcmp(*argv, "-r")) { + reset = 1; +/* } else if (!strcmp(*argv, "-vme32")) { */ +/* strcpy(vmedev, "/dev/vme32d32"); */ +/* } else if (!strcmp(*argv, "-vme24")) { */ +/* strcpy(vmedev, "/dev/vme24d32"); */ +/* } else if (!strcmp(*argv, "-vme16")) { */ +/* strcpy(vmedev, "/dev/vme16d32"); */ + } else if (!strcmp(*argv, "-")) { + usage(); + exit(0); + } else { + usage(); + exit(0); + } + } + + if (!havefile) { + if (!reset && !go) { + usage(); + } + else { + MVMEControl(0, reset, go); + } + exit(0); + } + + if ((in = fopen(infile, "r")) == NULL) { + perror("open"); + fprintf(stderr, "Cannot open input file %s\n", infile); + exit(1); + } + + if ((vme = open(vmedev, O_RDWR)) == -1) { + fprintf(stderr, "Cannot open vme as %s\n", vmedev); + } + + while (fscanf(in, "%s", &inpstr) != EOF) { + line++; + if (validrec(inpstr) == 0) { + switch (issrec(inpstr)) { + case 0 : + hdr2str(inpstr, hdrstr); + if (verbose) printf("HEADER string = `%s'\n", hdrstr); + lastrec=HEADER; + break; + case 1 : + addr = getaddr(inpstr); + size = datasize(inpstr); + if (blksize == 0) { + blksize+=size; + naddr=addr+size; + if (verbose) printf("DATA\tS19\t$%04lX", addr); + lastrec=DATA19; + } + else if ((blksize!=0) && (addr==naddr)) { + blksize+=size; + naddr=addr+size; + } + else { + if (verbose) printf("\t$%04lX\t%lu", naddr-1, blksize); + if (verbose) printf("\t%d\n", blknum); + blknum+=1; + naddr=addr+size; + blksize=size; + if (verbose) printf("DATA\tS19\t$%04lX", addr); + lastrec=DATA19; + } + tsize += size; + if (vme == -1) break; + for (i = 0, j = 8, k = size; k-- > 0; i += 1, j += 2) { + image[i] = ahdtoi(inpstr[j])*0x10 + ahdtoi(inpstr[j+1]); + } + if (lseek(vme, addr, SEEK_SET) == -1) { + fprintf(stderr, "lseek() to vme address %08X failed\n", addr); + } + else { + if (write(vme, (u_char *)image, size) != size) { + fprintf(stderr, "Write to vme address %08X failed\n", addr); + } + } + break; + case 2 : + addr = getaddr(inpstr); + size = datasize(inpstr); + if (blksize == 0) { + blksize+=size; + naddr=addr+size; + if (verbose) printf("DATA\tS28\t$%06lX",addr); + lastrec=DATA28; + } + else if ((blksize!=0) && (addr==naddr)) { + blksize+=size; + naddr=addr+size; + } + else { + if (verbose) printf("\t$%06lX\t%lu",naddr-1,blksize); + if (verbose) printf("\t%d\n",blknum); + blknum+=1; + naddr=addr+size; + blksize=size; + if (verbose) printf("DATA\tS28\t$%06lX",addr); + lastrec=DATA28; + } + tsize += size; + if (vme == -1) break; + for (i = 0, j = 10, k = size; k-- > 0; i += 1, j += 2) { + image[i] = ahdtoi(inpstr[j])*0x10 + ahdtoi(inpstr[j+1]); + } + if (lseek(vme, addr, SEEK_SET) == -1) { + fprintf(stderr, "lseek() to vme address %08X failed\n", addr); + } + else { + if (write(vme, (u_char *)image, size) != size) { + fprintf(stderr, "Write to vme address %08X failed\n", addr); + } + } + break; + case 3 : + addr = getaddr(inpstr); + size = datasize(inpstr); + if (blksize == 0) { + blksize+=size; + naddr=addr+size; + if (verbose) printf("DATA\tS37\t$%08lX",addr); + lastrec=DATA37; + } + else if ((blksize!=0) && (addr==naddr)) { + blksize+=size; + naddr=addr+size; + } + else { + if (verbose) printf("\t$%08lX\t%lu",naddr-1,blksize); + if (verbose) printf("\t%d\n",blknum); + blknum+=1; + naddr=addr+size; + blksize=size; + if (verbose) printf("DATA\tS37\t$%08lX",addr); + lastrec=DATA37; + } + tsize += size; + if (vme == -1) break; + for (i = 0, j = 12, k = size; k-- > 0; i += 1, j += 2) { + image[i] = ahdtoi(inpstr[j])*0x10 + ahdtoi(inpstr[j+1]); + } + if (lseek(vme, addr, SEEK_SET) == -1) { + fprintf(stderr, "lseek() to vme address %08X failed\n", addr); + } + else { + if (write(vme, (u_char *)image, size) != size) { + fprintf(stderr, "Write to vme address %08X failed\n", addr); + } + } + break; + case 7 : + if (lastrec==DATA19){ + if (verbose) printf("\t$%04lX\t%lu",naddr-1,blksize); + } + if (lastrec==DATA28){ + if (verbose) printf("\t$%06lX\t%lu",naddr-1,blksize); + } + if (lastrec==DATA37){ + if (verbose) printf("\t$%08lX\t%lu",naddr-1,blksize); + } + if (verbose) printf("\t%d\n",blknum); + addr = getaddr(inpstr); + if (verbose) printf("TERM\tS37"); + printf("\nExecution address = $%08lX\n", addr); + lastrec=TERMINATOR; + break; + case 8 : + if (lastrec==DATA19){ + if (verbose) printf("\t$%04lX\t%lu",naddr-1,blksize); + } + if (lastrec==DATA28){ + if (verbose) printf("\t$%06lX\t%lu",naddr-1,blksize); + } + if (lastrec==DATA37){ + if (verbose) printf("\t$%08lX\t%lu",naddr-1,blksize); + } + if (verbose) printf("\t%d\n",blknum); + addr = getaddr(inpstr); + if (verbose) printf("TERM\tS28"); + printf("\nExecution address = $%06lX\n", addr); + lastrec=TERMINATOR; + break; + case 9 : + if (lastrec==DATA19){ + if (verbose) printf("\t$%04lX\t%lu",naddr-1,blksize); + } + if (lastrec==DATA28){ + if (verbose) printf("\t$%06lX\t%lu",naddr-1,blksize); + } + if (lastrec==DATA37){ + if (verbose) printf("\t$%08lX\t%lu",naddr-1,blksize); + } + if (verbose) printf("\t%d\n",blknum); + addr = getaddr(inpstr); + if (verbose) printf("TERM\tS19"); + printf("\nExecution address = $%04lX\n", addr); + lastrec=TERMINATOR; + break; + } + } + else { + printf("\nError on line %d. ",line); + switch (validrec(inpstr)) { + case -1 : {printf("SRecord contains invalid characters.\n"); break; } + case -2 : {printf("SRecord checksum is invalid.\n"); break;} + case -3 : {printf("SRecord length is invalid.\n"); break;} + } + exit(1); + } + } + + if ((lastrec==DATA19) || (lastrec==DATA28) || (lastrec==DATA37)) { + if (lastrec==DATA19){ + if (verbose) printf("\t$%04lX\t%lu",naddr-1,blksize); + } + if (lastrec==DATA28){ + if (verbose) printf("\t$%06lX\t%lu",naddr-1,blksize); + } + if (lastrec==DATA37){ + if (verbose) printf("\t$%08lX\t%lu",naddr-1,blksize); + } + if (verbose) printf("\t%d\n",blknum); + printf("ERROR: terminator record not found.\n"); + } + else { + for (i = 0x000FFFF; i-- > 0;) ; /* mystique delay... */ + MVMEControl(addr, reset, go); + } + if (verbose) printf("total data size = %lu bytes\n", tsize); +} diff --git a/c/src/lib/libbsp/no_cpu/no_bsp/README b/c/src/lib/libbsp/no_cpu/no_bsp/README new file mode 100644 index 0000000000..8ed80e29f8 --- /dev/null +++ b/c/src/lib/libbsp/no_cpu/no_bsp/README @@ -0,0 +1,69 @@ +# +# $Id$ +# +# This is a sample hardware description file for a BSP. This comment +# block does not have to appear in a real one. The intention of this +# file is to provide a central place to look when searching for +# information about a board when starting a new BSP. For example, +# you may want to find an existing timer driver for the chip you are +# using on your board. It is easier to grep for the chip name in +# all of the HARDWARE files than to peruse the source tree. Hopefully, +# making the HARDDWARE files accurate will also alleviate the common +# problem of not knowing anything about a board based on its BSP +# name. +# +# NOTE: If you have a class of peripheral chip on board which +# is not in this list please add it to this file so +# others will also use the same name. +# +# Timer resolution is the way it is configured in this BSP. +# On a counting timer, this is the length of time which +# corresponds to 1 count. +# + +BSP NAME: fastsbc1 +BOARD: Fasssst Computers, Fast SBC-1 +BUS: SchoolBus +CPU FAMILY: i386 +CPU: Intel Hexium +COPROCESSORS: Witch Hex87 +MODE: 32 bit mode + +DEBUG MONITOR: HexBug + +PERIPHERALS +=========== +TIMERS: Intel i8254 + RESOLUTION: .0001 microseconds +SERIAL PORTS: Zilog Z8530 (with 2 ports) +REAL-TIME CLOCK: RTC-4 +DMA: Intel i8259 +VIDEO: none +SCSI: none +NETWORKING: none + +DRIVER INFORMATION +================== +CLOCK DRIVER: RTC-4 +IOSUPP DRIVER: Zilog Z8530 port A +SHMSUPP: polled and interrupts +TIMER DRIVER: Intel i8254 +TTY DRIVER: stub only + +STDIO +===== +PORT: Console port 0 +ELECTRICAL: RS-232 +BAUD: 9600 +BITS PER CHARACTER: 8 +PARITY: None +STOP BITS: 1 + +NOTES +===== + +(1) 900 Mhz and 950 Mhz versions. + +(2) 1 Gb or 2 Gb RAM. + +(3) PC compatible if HexBug not enabled. diff --git a/c/src/lib/libbsp/no_cpu/no_bsp/clock/ckinit.c b/c/src/lib/libbsp/no_cpu/no_bsp/clock/ckinit.c new file mode 100644 index 0000000000..426b55137b --- /dev/null +++ b/c/src/lib/libbsp/no_cpu/no_bsp/clock/ckinit.c @@ -0,0 +1,143 @@ +/* ckinit.c + * + * This file provides a template for the clock device driver initialization. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include + +#include +#include +#include + +/* + * The interrupt vector number associated with the clock tick device + * driver. + */ + +#define CLOCK_VECTOR 4 + +/* + * Clock_driver_ticks is a monotonically increasing counter of the + * number of clock ticks since the driver was initialized. + */ +volatile rtems_unsigned32 Clock_driver_ticks; + +/* + * Clock_isrs is the number of clock ISRs until the next invocation of + * the RTEMS clock tick routine. The clock tick device driver + * gets an interrupt once a millisecond and counts down until the + * length of time between the user configured microseconds per tick + * has passed. + */ + +rtems_unsigned32 Clock_isrs; /* ISRs until next tick */ + +/* + * The previous ISR on this clock tick interrupt vector. + */ + +rtems_isr_entry Old_ticker; + +/* + * Clock_initialize + * + * Device driver entry point for clock tick driver initialization. + */ + +rtems_device_driver Clock_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *pargp, + rtems_id tid, + rtems_unsigned32 *rval +) +{ + Install_clock( Clock_isr ); +} + +/* + * Reinstall_clock + * + * Install a clock tick handler without reprogramming the chip. This + * is used by the polling shared memory device driver. + */ + +void ReInstall_clock( + rtems_isr_entry clock_isr +) +{ + rtems_unsigned32 isrlevel = 0; + + /* + * Disable interrupts and install the clock ISR vector using the + * BSP dependent set_vector routine. In the below example, the clock + * ISR is on vector 4 and is an RTEMS interrupt. + */ + + rtems_interrupt_disable( isrlevel ); + (void) set_vector( clock_isr, CLOCK_VECTOR, 1 ); + rtems_interrupt_enable( isrlevel ); +} + +/* + * Install_clock + * + * Install a clock tick handler and reprograms the chip. This + * is used to initially establish the clock tick. + */ + +void Install_clock( + rtems_isr_entry clock_isr +) +{ + /* + * Initialize the clock tick device driver variables + */ + + Clock_driver_ticks = 0; + Clock_isrs = BSP_Configuration.microseconds_per_tick / 1000; + + /* + * If ticks_per_timeslice is configured as non-zero, then the user + * wants a clock tick. + */ + + if ( BSP_Configuration.ticks_per_timeslice ) { + Old_ticker = ( rtems_isr_entry ) set_vector( clock_isr, CLOCK_VECTOR, 1 ); + /* + * Hardware specific initialize goes here + */ + + /* XXX */ + } + + /* + * Schedule the clock cleanup routine to execute if the application exits. + */ + + atexit( Clock_exit ); +} + +/* + * Clean up before the application exits + */ + +void Clock_exit( void ) +{ + if ( BSP_Configuration.ticks_per_timeslice ) { + + /* XXX: turn off the timer interrupts */ + + /* XXX: If necessary, restore the old vector */ + } +} diff --git a/c/src/lib/libbsp/no_cpu/no_bsp/console/console.c b/c/src/lib/libbsp/no_cpu/no_bsp/console/console.c new file mode 100644 index 0000000000..c115e256a3 --- /dev/null +++ b/c/src/lib/libbsp/no_cpu/no_bsp/console/console.c @@ -0,0 +1,158 @@ +/* + * This file contains the template for a console IO package. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#define NO_BSP_INIT + +#include +#include "console.h" +#include "bsp.h" + +/* console_initialize + * + * This routine initializes the console IO driver. + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * Return values: + */ + +rtems_device_driver console_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg, + rtems_id self, + rtems_unsigned32 *status +) +{ + *status = RTEMS_SUCCESSFUL; +} + + +/* is_character_ready + * + * This routine returns TRUE if a character is available. + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * Return values: + */ + +rtems_boolean is_character_ready( + char *ch +) +{ + *ch = '\0'; /* return NULL for no particular reason */ + return(TRUE); +} + +/* inbyte + * + * This routine reads a character from the SOURCE. + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * Return values: + * character read from SOURCE + */ + +char inbyte( void ) +{ + /* + * If polling, wait until a character is available. + */ + + return '\0'; +} + +/* outbyte + * + * This routine transmits a character out the SOURCE. It may support + * XON/XOFF flow control. + * + * Input parameters: + * ch - character to be transmitted + * + * Output parameters: NONE + */ + +void outbyte( + char ch +) +{ + /* + * If polling, wait for the transmitter to be ready. + * Check for flow control requests and process. + * Then output the character. + */ + + /* + * Carriage Return/New line translation. + */ + + if ( ch == '\n' ) + outbyte( '\r' ); +} + +/* + * __read -- read bytes from the serial port. Ignore fd, since + * we only have stdin. + */ + +int __read( + int fd, + char *buf, + int nbytes +) +{ + int i = 0; + + for (i = 0; i < nbytes; i++) { + *(buf + i) = inbyte(); + if ((*(buf + i) == '\n') || (*(buf + i) == '\r')) { + (*(buf + i++)) = '\n'; + (*(buf + i)) = 0; + break; + } + } + return (i); +} + +/* + * __write -- write bytes to the serial port. Ignore fd, since + * stdout and stderr are the same. Since we have no filesystem, + * open will only return an error. + */ + +int __write( + int fd, + char *buf, + int nbytes +) +{ + int i; + + for (i = 0; i < nbytes; i++) { + if (*(buf + i) == '\n') { + outbyte ('\r'); + } + outbyte (*(buf + i)); + } + return (nbytes); +} diff --git a/c/src/lib/libbsp/no_cpu/no_bsp/include/bsp.h b/c/src/lib/libbsp/no_cpu/no_bsp/include/bsp.h new file mode 100644 index 0000000000..0f1c94caf4 --- /dev/null +++ b/c/src/lib/libbsp/no_cpu/no_bsp/include/bsp.h @@ -0,0 +1,85 @@ +/* bsp.h + * + * This include file contains all board IO definitions. + * + * XXX : put yours in here + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __NO_BSP_h +#define __NO_BSP_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/* + * Define the time limits for RTEMS Test Suite test durations. + * Long test and short test duration limits are provided. These + * values are in seconds and need to be converted to ticks for the + * application. + * + */ + +#define MAX_LONG_TEST_DURATION 300 /* 5 minutes = 300 seconds */ +#define MAX_SHORT_TEST_DURATION 3 /* 3 seconds */ + +/* + * Stuff for Time Test 27 + */ + +#define MUST_WAIT_FOR_INTERRUPT 0 + +#define Install_tm27_vector( handler ) set_vector( (handler), 0, 1 ) + +#define Cause_tm27_intr() + +#define Clear_tm27_intr() + +#define Lower_tm27_intr() + +/* + * Simple spin delay in microsecond units for device drivers. + * This is very dependent on the clock speed of the target. + */ + +#define delay( microseconds ) \ + { \ + } + +/* Constants */ + +#define RAM_START 0 +#define RAM_END 0x100000 + +/* miscellaneous stuff assumed to exist */ + +extern rtems_configuration_table BSP_Configuration; + +/* functions */ + +void bsp_cleanup( void ); + +no_cpu_isr_entry set_vector( /* returns old vector */ + rtems_isr_entry handler, /* isr routine */ + rtems_vector_number vector, /* vector number */ + int type /* RTEMS or RAW intr */ +); + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/c/src/lib/libbsp/no_cpu/no_bsp/include/coverhd.h b/c/src/lib/libbsp/no_cpu/no_bsp/include/coverhd.h new file mode 100644 index 0000000000..88435c5348 --- /dev/null +++ b/c/src/lib/libbsp/no_cpu/no_bsp/include/coverhd.h @@ -0,0 +1,115 @@ +/* coverhd.h + * + * This include file has defines to represent the overhead associated + * with calling a particular directive from C. These are used in the + * Timing Test Suite to ignore the overhead required to pass arguments + * to directives. On some CPUs and/or target boards, this overhead + * is significant and makes it difficult to distinguish internal + * RTEMS execution time from that used to call the directive. + * This file should be updated after running the C overhead timing + * test. Once this update has been performed, the RTEMS Time Test + * Suite should be rebuilt to account for these overhead times in the + * timing results. + * + * NOTE: If these are all zero, then the times reported include all + * all calling overhead including passing of arguments. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __COVERHD_h +#define __COVERHD_h + +#ifdef __cplusplus +extern "C" { +#endif + +#define CALLING_OVERHEAD_INITIALIZE_EXECUTIVE 0 +#define CALLING_OVERHEAD_SHUTDOWN_EXECUTIVE 0 +#define CALLING_OVERHEAD_TASK_CREATE 0 +#define CALLING_OVERHEAD_TASK_IDENT 0 +#define CALLING_OVERHEAD_TASK_START 0 +#define CALLING_OVERHEAD_TASK_RESTART 0 +#define CALLING_OVERHEAD_TASK_DELETE 0 +#define CALLING_OVERHEAD_TASK_SUSPEND 0 +#define CALLING_OVERHEAD_TASK_RESUME 0 +#define CALLING_OVERHEAD_TASK_SET_PRIORITY 0 +#define CALLING_OVERHEAD_TASK_MODE 0 +#define CALLING_OVERHEAD_TASK_GET_NOTE 0 +#define CALLING_OVERHEAD_TASK_SET_NOTE 0 +#define CALLING_OVERHEAD_TASK_WAKE_WHEN 0 +#define CALLING_OVERHEAD_TASK_WAKE_AFTER 0 +#define CALLING_OVERHEAD_INTERRUPT_CATCH 0 +#define CALLING_OVERHEAD_CLOCK_GET 0 +#define CALLING_OVERHEAD_CLOCK_SET 0 +#define CALLING_OVERHEAD_CLOCK_TICK 0 + +#define CALLING_OVERHEAD_TIMER_CREATE 0 +#define CALLING_OVERHEAD_TIMER_IDENT 0 +#define CALLING_OVERHEAD_TIMER_DELETE 0 +#define CALLING_OVERHEAD_TIMER_FIRE_AFTER 0 +#define CALLING_OVERHEAD_TIMER_FIRE_WHEN 0 +#define CALLING_OVERHEAD_TIMER_RESET 0 +#define CALLING_OVERHEAD_TIMER_CANCEL 0 +#define CALLING_OVERHEAD_SEMAPHORE_CREATE 0 +#define CALLING_OVERHEAD_SEMAPHORE_IDENT 0 +#define CALLING_OVERHEAD_SEMAPHORE_DELETE 0 +#define CALLING_OVERHEAD_SEMAPHORE_OBTAIN 0 +#define CALLING_OVERHEAD_SEMAPHORE_RELEASE 0 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_CREATE 0 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_IDENT 0 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_DELETE 0 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_SEND 0 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_URGENT 0 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_BROADCAST 0 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_RECEIVE 0 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_FLUSH 0 + +#define CALLING_OVERHEAD_EVENT_SEND 0 +#define CALLING_OVERHEAD_EVENT_RECEIVE 0 +#define CALLING_OVERHEAD_SIGNAL_CATCH 0 +#define CALLING_OVERHEAD_SIGNAL_SEND 0 +#define CALLING_OVERHEAD_PARTITION_CREATE 0 +#define CALLING_OVERHEAD_PARTITION_IDENT 0 +#define CALLING_OVERHEAD_PARTITION_DELETE 0 +#define CALLING_OVERHEAD_PARTITION_GET_BUFFER 0 +#define CALLING_OVERHEAD_PARTITION_RETURN_BUFFER 0 +#define CALLING_OVERHEAD_REGION_CREATE 0 +#define CALLING_OVERHEAD_REGION_IDENT 0 +#define CALLING_OVERHEAD_REGION_DELETE 0 +#define CALLING_OVERHEAD_REGION_GET_SEGMENT 0 +#define CALLING_OVERHEAD_REGION_RETURN_SEGMENT 0 +#define CALLING_OVERHEAD_PORT_CREATE 0 +#define CALLING_OVERHEAD_PORT_IDENT 0 +#define CALLING_OVERHEAD_PORT_DELETE 0 +#define CALLING_OVERHEAD_PORT_EXTERNAL_TO_INTERNAL 0 +#define CALLING_OVERHEAD_PORT_INTERNAL_TO_EXTERNAL 0 + +#define CALLING_OVERHEAD_IO_INITIALIZE 0 +#define CALLING_OVERHEAD_IO_OPEN 0 +#define CALLING_OVERHEAD_IO_CLOSE 0 +#define CALLING_OVERHEAD_IO_READ 0 +#define CALLING_OVERHEAD_IO_WRITE 0 +#define CALLING_OVERHEAD_IO_CONTROL 0 +#define CALLING_OVERHEAD_FATAL_ERROR_OCCURRED 0 +#define CALLING_OVERHEAD_RATE_MONOTONIC_CREATE 0 +#define CALLING_OVERHEAD_RATE_MONOTONIC_IDENT 0 +#define CALLING_OVERHEAD_RATE_MONOTONIC_DELETE 0 +#define CALLING_OVERHEAD_RATE_MONOTONIC_CANCEL 0 +#define CALLING_OVERHEAD_RATE_MONOTONIC_PERIOD 0 +#define CALLING_OVERHEAD_MULTIPROCESSING_ANNOUNCE 0 + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/c/src/lib/libbsp/no_cpu/no_bsp/shmsupp/addrconv.c b/c/src/lib/libbsp/no_cpu/no_bsp/shmsupp/addrconv.c new file mode 100644 index 0000000000..0e188fc941 --- /dev/null +++ b/c/src/lib/libbsp/no_cpu/no_bsp/shmsupp/addrconv.c @@ -0,0 +1,31 @@ +/* Shm_Convert_address + * + * No address range conversion is required. + * + * Input parameters: + * address - address to convert + * + * Output parameters: + * returns - converted address + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include +#include + +void *Shm_Convert_address( + void *address +) +{ + return ( address ); +} diff --git a/c/src/lib/libbsp/no_cpu/no_bsp/shmsupp/getcfg.c b/c/src/lib/libbsp/no_cpu/no_bsp/shmsupp/getcfg.c new file mode 100644 index 0000000000..ca8409a3f0 --- /dev/null +++ b/c/src/lib/libbsp/no_cpu/no_bsp/shmsupp/getcfg.c @@ -0,0 +1,77 @@ +/* void Shm_Get_configuration( localnode, &shmcfg ) + * + * This routine initializes, if necessary, and returns a pointer + * to the Shared Memory Configuration Table for the XXX target. + * + * INPUT PARAMETERS: + * localnode - local node number + * shmcfg - address of pointer to SHM Config Table + * + * OUTPUT PARAMETERS: + * *shmcfg - pointer to SHM Config Table + * +XXX: FIX THE COMMENTS BELOW WHEN THE CPU IS KNOWN + * NOTES: The XYZ does not have an interprocessor interrupt. + * + * The following table illustrates the configuration limitations: + * + * BUS MAX + * MODE ENDIAN NODES + * ========= ====== ======= + * POLLED BIG 2+ + * INTERRUPT **** NOT SUPPORTED **** + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include +#include + +/* + * configured if currently polling of interrupt driven + */ + +#define INTERRUPT 0 /* XXX: */ +#define POLLING 1 /* XXX: fix me -- is polling ONLY!!! */ + + +shm_config_table BSP_shm_cfgtbl; + +void Shm_Get_configuration( + rtems_unsigned32 localnode, + shm_config_table **shmcfg +) +{ + BSP_shm_cfgtbl.base = 0x0; + BSP_shm_cfgtbl.length = 1 * MEGABYTE; + BSP_shm_cfgtbl.format = SHM_BIG; + + /* + * Override cause_intr or shm_isr if your target has + * special requirements. + */ + + BSP_shm_cfgtbl.cause_intr = Shm_Cause_interrupt; + +#ifdef NEUTRAL_BIG + BSP_shm_cfgtbl.convert = NULL_CONVERT; +#else + BSP_shm_cfgtbl.convert = CPU_swap_u32; +#endif + + BSP_shm_cfgtbl.poll_intr = POLLED_MODE; + BSP_shm_cfgtbl.Intr.address = NO_INTERRUPT; + BSP_shm_cfgtbl.Intr.value = NO_INTERRUPT; + BSP_shm_cfgtbl.Intr.length = NO_INTERRUPT; + + *shmcfg = &BSP_shm_cfgtbl; +} diff --git a/c/src/lib/libbsp/no_cpu/no_bsp/shmsupp/lock.c b/c/src/lib/libbsp/no_cpu/no_bsp/shmsupp/lock.c new file mode 100644 index 0000000000..acdc8b7b48 --- /dev/null +++ b/c/src/lib/libbsp/no_cpu/no_bsp/shmsupp/lock.c @@ -0,0 +1,86 @@ +/* Shared Memory Lock Routines + * + * This shared memory locked queue support routine need to be + * able to lock the specified locked queue. Interrupts are + * disabled while the queue is locked to prevent preemption + * and deadlock when two tasks poll for the same lock. + * previous level. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include +#include + +/* + * Shm_Initialize_lock + * + * Initialize the lock for the specified locked queue. + */ + +void Shm_Initialize_lock( + Shm_Locked_queue_Control *lq_cb +) +{ + lq_cb->lock = LQ_UNLOCKED; +} + +/* void _Shm_Lock( &lq_cb ) + * + * This shared memory locked queue support routine locks the + * specified locked queue. It disables interrupts to prevent + * a deadlock condition. + */ + +void Shm_Lock( + Shm_Locked_queue_Control *lq_cb +) +{ + rtems_unsigned32 isr_level; + rtems_unsigned32 *lockptr = &lq_cb->lock; + rtems_unsigned32 lock_value; + + lock_value = 0x80000000; + rtems_interrupt_disable( isr_level ); + + Shm_isrstat = isr_level; + while ( lock_value ) { + asm volatile( "" + : "=r" (lockptr), "=r" (lock_value) + : "0" (lockptr), "1" (lock_value) + ); + /* + * If not available, then may want to delay to reduce load on lock. + */ + + if ( lock_value ) + delay( 10 ); /* approximately 10 microseconds */ + } +} + +/* + * Shm_Unlock + * + * Unlock the lock for the specified locked queue. + */ + +void Shm_Unlock( + Shm_Locked_queue_Control *lq_cb +) +{ + rtems_unsigned32 isr_level; + + lq_cb->lock = SHM_UNLOCK_VALUE; + isr_level = Shm_isrstat; + rtems_interrupt_enable( isr_level ); +} + diff --git a/c/src/lib/libbsp/no_cpu/no_bsp/shmsupp/mpisr.c b/c/src/lib/libbsp/no_cpu/no_bsp/shmsupp/mpisr.c new file mode 100644 index 0000000000..592c0cfcc5 --- /dev/null +++ b/c/src/lib/libbsp/no_cpu/no_bsp/shmsupp/mpisr.c @@ -0,0 +1,47 @@ +/* Shm_isr_nobsp() + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include +#include + +rtems_isr Shm_isr_nobsp( void ) +{ + /* + * If this routine has to do anything other than the mpisr.c + * found in the generic driver, then copy the contents of the generic + * mpisr.c and augment it to satisfy this particular board. Typically, + * you need to have a board specific mpisr.c when the interrupt + * must be cleared. + * + * If the generic mpisr.c satisifies your requirements, then + * remove this routine from your target's shmsupp/mpisb.c file. + * Then simply install the generic Shm_isr in the Shm_setvec + * routine below. + */ +} + +/* Shm_setvec + * + * This driver routine sets the SHM interrupt vector to point to the + * driver's SHM interrupt service routine. + * + * Input parameters: NONE + * + * Output parameters: NONE + */ + +void Shm_setvec( void ) +{ + /* XXX: FIX ME!!! */ +} diff --git a/c/src/lib/libbsp/no_cpu/no_bsp/startup/bspclean.c b/c/src/lib/libbsp/no_cpu/no_bsp/startup/bspclean.c new file mode 100644 index 0000000000..ca498e7806 --- /dev/null +++ b/c/src/lib/libbsp/no_cpu/no_bsp/startup/bspclean.c @@ -0,0 +1,26 @@ +/* bsp_cleanup() + * + * This routine normally is part of start.s and usually returns + * control to a monitor. + * + * INPUT: NONE + * + * OUTPUT: NONE + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include + +void bsp_cleanup( void ) +{ +} diff --git a/c/src/lib/libbsp/no_cpu/no_bsp/startup/bspstart.c b/c/src/lib/libbsp/no_cpu/no_bsp/startup/bspstart.c new file mode 100644 index 0000000000..4d3d3a7175 --- /dev/null +++ b/c/src/lib/libbsp/no_cpu/no_bsp/startup/bspstart.c @@ -0,0 +1,164 @@ +/* bsp_start() + * + * This routine starts the application. It includes application, + * board, and monitor specific initialization and configuration. + * The generic CPU dependent initialization has been performed + * before this routine is invoked. + * + * INPUT: NONE + * + * OUTPUT: NONE + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include +#include +#include + +/* + * The original table from the application and our copy of it with + * some changes. + */ + +extern rtems_configuration_table Configuration; + +rtems_configuration_table BSP_Configuration; + +rtems_cpu_table Cpu_table; + +/* Initialize whatever libc we are using + * called from postdriver hook + */ + +void bsp_libc_init() +{ + extern int end; + rtems_unsigned32 heap_start; + + heap_start = (rtems_unsigned32) &end; + if (heap_start & (CPU_ALIGNMENT-1)) + heap_start = (heap_start + CPU_ALIGNMENT) & ~(CPU_ALIGNMENT-1); + + /* + * The last parameter to RTEMS_Malloc_Initialize is the "chunk" + * size which a multiple of will be requested on each sbrk() + * call by malloc(). A value of 0 indicates that sbrk() should + * not be called to extend the heap. + */ + + RTEMS_Malloc_Initialize((void *) heap_start, 64 * 1024, 0); + + /* + * Set up for the libc handling. + */ + + if (BSP_Configuration.ticks_per_timeslice > 0) + libc_init(1); /* reentrant if possible */ + else + libc_init(0); /* non-reentrant */ + + /* + * Initialize the stack bounds checker + */ + +#ifdef STACK_CHECKER_ON + Stack_check_Initialize(); +#endif +} + +int bsp_start( + int argc, + char **argv, + char **environp +) +{ + /* + * Allocate the memory for the RTEMS Work Space. This can come from + * a variety of places: hard coded address, malloc'ed from outside + * RTEMS world (e.g. simulator or primitive memory manager), or (as + * typically done by stock BSPs) by subtracting the required amount + * of work space from the last physical address on the CPU board. + */ + + /* + * Copy the Configuration Table .. so we can change it + */ + + BSP_Configuration = Configuration; + + /* + * Add 1 region for the RTEMS Malloc + */ + + BSP_Configuration.maximum_regions++; + + /* + * Add 1 extension for newlib libc + */ + +#ifdef RTEMS_NEWLIB + BSP_Configuration.maximum_extensions++; +#endif + + /* + * Add 1 extension for newlib libc + */ + +#ifdef RTEMS_NEWLIB + BSP_Configuration.maximum_extensions++; +#endif + + /* + * Need to "allocate" the memory for the RTEMS Workspace and + * tell the RTEMS configuration where it is. This memory is + * not malloc'ed. It is just "pulled from the air". + */ + + BSP_Configuration.work_space_start = (void *) 0; + + /* + * initialize the CPU table for this BSP + */ + + /* + * we do not use the pretasking_hook + */ + + Cpu_table.pretasking_hook = NULL; + + Cpu_table.predriver_hook = bsp_libc_init; /* RTEMS resources available */ + + Cpu_table.postdriver_hook = NULL; + + Cpu_table.idle_task = NULL; /* do not override system IDLE task */ + + Cpu_table.do_zero_of_workspace = TRUE; + + Cpu_table.interrupt_stack_size = 4096; + + Cpu_table.extra_system_initialization_stack = 0; + + /* + * Don't forget the other CPU Table entries. + */ + + /* + * Start RTEMS + */ + + rtems_initialize_executive( &BSP_Configuration, &Cpu_table ); + + bsp_cleanup(); + + return 0; +} diff --git a/c/src/lib/libbsp/no_cpu/no_bsp/startup/linkcmds b/c/src/lib/libbsp/no_cpu/no_bsp/startup/linkcmds new file mode 100644 index 0000000000..144b9e68a0 --- /dev/null +++ b/c/src/lib/libbsp/no_cpu/no_bsp/startup/linkcmds @@ -0,0 +1,46 @@ +/* + * This file contains directives for the GNU linker which are specific + * to the FORCE CPU386 board. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +MEMORY + { + ram : org = 0x0, l = 1M + } + +SECTIONS +{ + .text 0x0 : + { + text_start = . ; + _text_start = . ; + *(.text) + _etext = ALIGN( 0x10 ) ; + } + .data ADDR( .text ) + SIZEOF( .text ): + { + data_start = . ; + _data_start = . ; + *(.data) + _edata = ALIGN( 0x10 ) ; + } + .bss ADDR( .data ) + SIZEOF( .data ): + { + bss_start = . ; + _bss_start = . ; + *(.bss) + *(COMMON) + end = . ; + __end = . ; + } +} diff --git a/c/src/lib/libbsp/no_cpu/no_bsp/startup/main.c b/c/src/lib/libbsp/no_cpu/no_bsp/startup/main.c new file mode 100644 index 0000000000..622edb1ad7 --- /dev/null +++ b/c/src/lib/libbsp/no_cpu/no_bsp/startup/main.c @@ -0,0 +1,33 @@ +/* main() + * + * This is the entry point for the application. It calls + * the bsp_start routine to the actual dirty work. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include + +int main( + int argc, + char **argv +) +{ + bsp_start(); + + /* + * May be able to return to the "crt/start.s" code but also + * may not be able to. Do something here which is board dependent. + */ + + rtems_fatal_error_occurred( 0 ); +} diff --git a/c/src/lib/libbsp/no_cpu/no_bsp/startup/setvec.c b/c/src/lib/libbsp/no_cpu/no_bsp/startup/setvec.c new file mode 100644 index 0000000000..0f556a4d5e --- /dev/null +++ b/c/src/lib/libbsp/no_cpu/no_bsp/startup/setvec.c @@ -0,0 +1,44 @@ +/* set_vector + * + * This routine installs an interrupt vector on the target Board/CPU. + * This routine is allowed to be as board dependent as necessary. + * + * INPUT: + * handler - interrupt handler entry point + * vector - vector number + * type - 0 indicates raw hardware connect + * 1 indicates RTEMS interrupt connect + * + * RETURNS: + * address of previous interrupt handler + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include + +no_cpu_isr_entry set_vector( /* returns old vector */ + rtems_isr_entry handler, /* isr routine */ + rtems_vector_number vector, /* vector number */ + int type /* RTEMS or RAW intr */ +) +{ + no_cpu_isr_entry previous_isr; + + if ( type ) + rtems_interrupt_catch( handler, vector, (rtems_isr_entry *) &previous_isr ); + else { + /* XXX: install non-RTEMS ISR as "raw" interupt */ + } + return previous_isr; +} + diff --git a/c/src/lib/libbsp/no_cpu/no_bsp/timer/timer.c b/c/src/lib/libbsp/no_cpu/no_bsp/timer/timer.c new file mode 100644 index 0000000000..a3b8775444 --- /dev/null +++ b/c/src/lib/libbsp/no_cpu/no_bsp/timer/timer.c @@ -0,0 +1,105 @@ +/* timer.c + * + * This file manages the benchmark timer used by the RTEMS Timing Test + * Suite. Each measured time period is demarcated by calls to + * Timer_initialize() and Read_timer(). Read_timer() usually returns + * the number of microseconds since Timer_initialize() exitted. + * + * NOTE: It is important that the timer start/stop overhead be + * determined when porting or modifying this code. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include + +rtems_unsigned32 Timer_interrupts; +rtems_boolean Timer_driver_Find_average_overhead; + +void Timer_initialize( void ) +{ + + /* + * Timer has never overflowed. This may not be necessary on some + * implemenations of timer but .... + */ + + Timer_interrupts = 0; + + /* + * Somehow start the timer + */ +} + +/* + * The following controls the behavior of Read_timer(). + * + * AVG_OVEREHAD is the overhead for starting and stopping the timer. It + * is usually deducted from the number returned. + * + * LEAST_VALID is the lowest number this routine should trust. Numbers + * below this are "noise" and zero is returned. + */ + +#define AVG_OVERHEAD 0 /* It typically takes X.X microseconds */ + /* (Y countdowns) to start/stop the timer. */ + /* This value is in microseconds. */ +#define LEAST_VALID 1 /* Don't trust a clicks value lower than this */ + +int Read_timer( void ) +{ + rtems_unsigned32 clicks; + rtems_unsigned32 total; + + /* + * Read the timer and see how many clicks it has been since we started. + */ + + clicks = 0; /* XXX: read some HW here */ + + /* + * Total is calculated by taking into account the number of timer overflow + * interrupts since the timer was initialized and clicks since the last + * interrupts. + */ + + total = clicks * 0; + + if ( Timer_driver_Find_average_overhead == 1 ) + return total; /* in XXX microsecond units */ + else { + if ( total < LEAST_VALID ) + return 0; /* below timer resolution */ + /* + * Somehow convert total into microseconds + */ + return (total - AVG_OVERHEAD); + } +} + +/* + * Empty function call used in loops to measure basic cost of looping + * in Timing Test Suite. + */ + +rtems_status_code Empty_function( void ) +{ + return RTEMS_SUCCESSFUL; +} + +void Set_find_average_overhead( + rtems_boolean find_flag +) +{ + Timer_driver_Find_average_overhead = find_flag; +} + diff --git a/c/src/lib/libbsp/no_cpu/no_bsp/timer/timerisr.c b/c/src/lib/libbsp/no_cpu/no_bsp/timer/timerisr.c new file mode 100644 index 0000000000..f52774b75e --- /dev/null +++ b/c/src/lib/libbsp/no_cpu/no_bsp/timer/timerisr.c @@ -0,0 +1,37 @@ +/* timerisr.s + * + * If required this ISR is used to bump a count of interval "overflow" + * interrupts which have occurred since the timer was started. The + * number of overflows is taken into account in the Read_timer() + * routine if necessary. + * + * To reduce overhead this is best to be the "rawest" hardware interupt + * handler you can write. This should be the only interrupt which can + * occur during the measured time period. + * + * NOTE: This file is USUALLY in assembly and is LEAN AND MEAN. + * Any code in this isr is pure overhead which can perturb + * the accuracy of the Timing Test Suite. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include + +extern rtems_unsigned32 _Timer_interrupts; + +void timerisr( void ) +{ + /* + * _Timer_interrupts += TIMER_BETWEEN_OVERFLOWS (usually in microseconds) + * return from interrupt + */ +} diff --git a/c/src/lib/libbsp/shmdr/README b/c/src/lib/libbsp/shmdr/README new file mode 100644 index 0000000000..5ed9e861b0 --- /dev/null +++ b/c/src/lib/libbsp/shmdr/README @@ -0,0 +1,9 @@ +# +# $Id$ +# + +The mpci.h file provided in here is too simple for an MPCI with +multiple ways to get to a node. + +This version of the shm driver needs to be reorganized to follow +the better model of the Ada version. diff --git a/c/src/lib/libbsp/shmdr/addlq.c b/c/src/lib/libbsp/shmdr/addlq.c new file mode 100644 index 0000000000..2c2529c834 --- /dev/null +++ b/c/src/lib/libbsp/shmdr/addlq.c @@ -0,0 +1,43 @@ +/* void Shm_Locked_queue_Add( lq_cb, ecb ) + * + * This routine adds an envelope control block to a shared memory queue. + * + * Input parameters: + * lq_cb - pointer to a locked queue control block + * ecb - pointer to an envelope control block + * + * Output parameters: NONE + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include "shm.h" + +void Shm_Locked_queue_Add( + Shm_Locked_queue_Control *lq_cb, + Shm_Envelope_control *ecb +) +{ + rtems_unsigned32 index; + + ecb->next = Shm_Locked_queue_End_of_list; + ecb->queue = lq_cb->owner; + index = ecb->index; + + Shm_Lock( lq_cb ); + if ( Shm_Convert(lq_cb->front) != Shm_Locked_queue_End_of_list ) + Shm_Envelopes[ Shm_Convert(lq_cb->rear) ].next = index; + else + lq_cb->front = index; + lq_cb->rear = index; + Shm_Unlock( lq_cb ); +} diff --git a/c/src/lib/libbsp/shmdr/cnvpkt.c b/c/src/lib/libbsp/shmdr/cnvpkt.c new file mode 100644 index 0000000000..2c3a144167 --- /dev/null +++ b/c/src/lib/libbsp/shmdr/cnvpkt.c @@ -0,0 +1,42 @@ +/* void Shm_Convert_packet( &packet ) + * + * This routine is the shared memory locked queue MPCI driver routine + * used to convert the RTEMS's information in a packet from non-native + * format to processor native format. + * + * Input parameters: + * packet - pointer to a packet + * + * Output parameters: + * *packet - packet in native format + * + * NOTE: Message buffers are not manipulated. + * Endian conversion is currently the only conversion. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include "shm.h" + +void Shm_Convert_packet( + rtems_packet_prefix *packet +) +{ + rtems_unsigned32 *pkt, i; + + pkt = (rtems_unsigned32 *) packet; + for ( i=RTEMS_MINIMUN_HETERO_CONVERSION ; i ; i--, pkt++ ) + *pkt = CPU_swap_u32( *pkt ); + + for ( i=packet->to_convert ; i ; i--, pkt++ ) + *pkt = CPU_swap_u32( *pkt ); +} diff --git a/c/src/lib/libbsp/shmdr/dump.c b/c/src/lib/libbsp/shmdr/dump.c new file mode 100644 index 0000000000..e028ab4204 --- /dev/null +++ b/c/src/lib/libbsp/shmdr/dump.c @@ -0,0 +1,50 @@ +/* + * This routine is invoked following a reset to report the statistics + * gathered during the previous execution. + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include +#include + +#include "shm.h" + +void +Shm_Print_statistics(void) +{ + rtems_unsigned32 ticks; + rtems_unsigned32 ticks_per_second; + rtems_unsigned32 seconds; + int packets_per_second; + + (void) rtems_clock_get( RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &ticks ); + (void) rtems_clock_get( RTEMS_CLOCK_GET_TICKS_PER_SECOND, &ticks_per_second ); + + seconds = ticks / ticks_per_second; + + packets_per_second = Shm_Receive_message_count / seconds; + if ( (Shm_Receive_message_count % seconds) >= (seconds / 2) ) + packets_per_second++; + + printf( "\n\nSHMDR STATISTICS (NODE %d)\n", Shm_Local_node ); + printf( "TICKS SINCE BOOT = %d\n", ticks ); + printf( "TICKS PER SECOND = %d\n", ticks_per_second ); + printf( "ISRs=%d\n", Shm_Interrupt_count ); + printf( "RECV=%d\n", Shm_Receive_message_count ); + printf( "NULL=%d\n", Shm_Null_message_count ); + printf( "PKTS/SEC=%d\n", packets_per_second ); +} diff --git a/c/src/lib/libbsp/shmdr/fatal.c b/c/src/lib/libbsp/shmdr/fatal.c new file mode 100644 index 0000000000..fc1e9f8624 --- /dev/null +++ b/c/src/lib/libbsp/shmdr/fatal.c @@ -0,0 +1,37 @@ +/* void MPCI_Fatal( error ) + * + * This routine is the shared memory driver fatal error handler. + * + * Input parameters: + * error - fatal error code + * + * Output parameters: NEVER RETURNS + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include "shm.h" + +void MPCI_Fatal( + rtems_unsigned32 error +) +{ + /* Eventually need to attempt to broadcast a K_FATAL message + * without checking for all possible errors (do not want to + * recurse). + * + * Also need to avoid using Shm_Node_statuses if the driver has not been + * initialized. + */ + + Shm_Local_node_status->error = Shm_Convert(error); +} diff --git a/c/src/lib/libbsp/shmdr/getlq.c b/c/src/lib/libbsp/shmdr/getlq.c new file mode 100644 index 0000000000..180c33ef00 --- /dev/null +++ b/c/src/lib/libbsp/shmdr/getlq.c @@ -0,0 +1,46 @@ +/* Shm_Envelope_control *Shm_Locked_queue_Get( lq_cb ) + * + * This routine returns an envelope control block from a shared + * memory queue. + * + * Input parameters: + * lq_cb - pointer to a locked queue control block + * + * Output parameters: + * returns - pointer to an envelope control block + * - NULL if no envelopes on specified queue + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include "shm.h" + +Shm_Envelope_control *Shm_Locked_queue_Get( + Shm_Locked_queue_Control *lq_cb +) +{ + Shm_Envelope_control *tmp_ecb; + rtems_unsigned32 tmpfront; + + tmp_ecb = NULL; + Shm_Lock( lq_cb ); + tmpfront = Shm_Convert(lq_cb->front); + if ( tmpfront != Shm_Locked_queue_End_of_list ) { + tmp_ecb = &Shm_Envelopes[ tmpfront ]; + lq_cb->front = tmp_ecb->next; + if ( tmp_ecb->next == Shm_Locked_queue_End_of_list ) + lq_cb->rear = Shm_Locked_queue_End_of_list; + tmp_ecb->next = Shm_Locked_queue_Not_on_list; + } + Shm_Unlock( lq_cb ); + return( tmp_ecb ); +} diff --git a/c/src/lib/libbsp/shmdr/getpkt.c b/c/src/lib/libbsp/shmdr/getpkt.c new file mode 100644 index 0000000000..c80b3ed282 --- /dev/null +++ b/c/src/lib/libbsp/shmdr/getpkt.c @@ -0,0 +1,36 @@ +/* Shm_Get_packet + * + * This routine is the shared memory locked queue MPCI driver + * routine used to obtain an empty message packet. + * + * Input parameters: + * packet - address of pointer to packet + * + * Output parameters: + * *(cpb->get_packet) - address of allocated packet + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include "shm.h" + +rtems_mpci_entry Shm_Get_packet( + rtems_packet_prefix **packet +) +{ + Shm_Envelope_control *ecb; + + ecb = Shm_Allocate_envelope(); + if ( !ecb ) + rtems_fatal_error_occurred ( SHM_NO_FREE_PKTS ); + *packet = Shm_Envelope_control_to_packet_prefix_pointer( ecb ); +} diff --git a/c/src/lib/libbsp/shmdr/init.c b/c/src/lib/libbsp/shmdr/init.c new file mode 100644 index 0000000000..b9de91d449 --- /dev/null +++ b/c/src/lib/libbsp/shmdr/init.c @@ -0,0 +1,248 @@ +/* Shm_Initialization + * + * This routine is the shared memory communications initerface + * driver initialization routine. + * + * Input parameters: + * configuration - address of configuration table + * + * Output parameters: NONE + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#define _SHM_INIT + +#include +#include "shm.h" + +/* + * Need a user extension control to install MPCI_Fatal as + * a fatal error handler extension + */ + +rtems_extensions_table MPCI_Shm_extensions; + +rtems_mpci_entry Shm_Initialization( + rtems_configuration_table *configuration, + rtems_cpu_table *cpu_configuration, + rtems_multiprocessing_table *mp_configuration + +) +{ + rtems_unsigned32 i, *u32_ptr, *endshm, all_initialized; + rtems_unsigned32 interrupt_cause, interrupt_value; + void *interrupt_address; + Shm_Node_status_control *nscb; + rtems_unsigned32 extension_id; /* for installation of MPCI_Fatal */ + rtems_unsigned32 remaining_memory; + + Shm_RTEMS_Configuration = configuration; + Shm_RTEMS_MP_Configuration = mp_configuration; + + Shm_Local_node = Shm_RTEMS_MP_Configuration->node; + Shm_Maximum_nodes = Shm_RTEMS_MP_Configuration->maximum_nodes; + + Shm_Get_configuration( Shm_Local_node ,&Shm_Configuration ); + + Shm_Receive_message_count = 0; + Shm_Null_message_count = 0; + Shm_Interrupt_count = 0; + + /* + * Set the Node Status indicators + */ + +#define PEND Shm_Convert(rtems_build_name( 'P', 'E', 'N', 'D' )) +#define COMP Shm_Convert(rtems_build_name( 'C', 'O', 'M', 'P' )) +#define ACTV Shm_Convert(rtems_build_name( 'A', 'C', 'T', 'V' )) + + Shm_Pending_initialization = PEND; + Shm_Initialization_complete = COMP; + Shm_Active_node = ACTV; + + /* + * Initialize the constants used by the Locked Queue code. + */ + + Shm_Locked_queue_End_of_list = Shm_Convert( 0xffffffff ); + Shm_Locked_queue_Not_on_list = Shm_Convert( 0xfffffffe ); + + /* + * Set the base addresses for the: + * + Node Status Table + * + Free Pool and Receive Queues + * + Envelopes + */ + + Shm_Node_statuses = (Shm_Node_status_control *) START_NS_CBS; + Shm_Locked_queues = (Shm_Locked_queue_Control *) START_LQ_CBS; + Shm_Envelopes = (Shm_Envelope_control *) START_ENVELOPES; + + /* + * Calculate the maximum number of envelopes which can be + * placed the remaining shared memory. + */ + + remaining_memory = + ((void *)Shm_Configuration->base + Shm_Configuration->length) - + ((void *)Shm_Envelopes); + + Shm_Maximum_envelopes = remaining_memory / sizeof( Shm_Envelope_control ); + Shm_Maximum_envelopes -= 1; + + /* + * Set the pointer to the receive queue for the local node. + * When we receive a node, we will get it from here before + * processing it. + */ + + Shm_Local_receive_queue = &Shm_Locked_queues[ Shm_Local_node ]; + Shm_Local_node_status = &Shm_Node_statuses[ Shm_Local_node ]; + + /* + * Convert local interrupt cause information into the + * neutral format so other nodes will be able to + * understand it. + */ + + interrupt_address = + (void *) Shm_Convert( (rtems_unsigned32)Shm_Configuration->Intr.address ); + interrupt_value = Shm_Convert( Shm_Configuration->Intr.value ); + interrupt_cause = Shm_Convert( Shm_Configuration->Intr.length ); + + if ( Shm_Configuration->poll_intr == POLLED_MODE ) Shm_setclockvec(); + else Shm_setvec(); + + if ( Shm_Is_master_node() ) { + + /* + * Zero out the shared memory area. + */ + + for ( u32_ptr = (rtems_unsigned32 *)Shm_Configuration->base, + endshm = (rtems_unsigned32 *)END_SHARED_MEM ; + u32_ptr < endshm ; ) + *u32_ptr++ = 0; + + /* + * Initialize all of the locked queues (the free envelope + * pool and a receive queue per node) and set all of the + * node's status so they will be waiting to initialization + * to complete. + */ + + Shm_Locked_queue_Initialize( FREE_ENV_CB, FREE_ENV_POOL ); + + for ( i=SHM_FIRST_NODE ; i<=Shm_Maximum_nodes ; i++ ) { + Shm_Initialize_receive_queue( i ); + + Shm_Node_statuses[ i ].status = Shm_Pending_initialization; + Shm_Node_statuses[ i ].error = 0; + } + + /* + * Initialize all of the envelopes and place them in the + * free pool. + */ + + for ( i=0 ; iint_address = (rtems_unsigned32) interrupt_address; + Shm_Local_node_status->int_value = interrupt_value; + Shm_Local_node_status->int_length = interrupt_cause; + + Shm_Local_node_status->status = Shm_Initialization_complete; + + /* + * Loop until all nodes have completed initialization. + */ + + all_initialized = 0; + + for ( ; ; ) { + + if ( all_initialized == 1 ) break; + + all_initialized = 1; + + for ( i = SHM_FIRST_NODE ; i <= Shm_Maximum_nodes ; i++ ) + if ( Shm_Node_statuses[ i ].status != Shm_Initialization_complete ) + all_initialized = 0; + } + + /* + * Tell the other nodes we think that the system is up. + */ + + for ( i = SHM_FIRST_NODE ; i <= Shm_Maximum_nodes ; i++ ) + Shm_Node_statuses[ i ].status = Shm_Active_node; + + } else { /* is not MASTER node */ + + /* + * Initialize the node status for the non-master nodes. + * Because the master node zeroes out memory, it is + * necessary for them to keep putting their values in + * the node status area until the master says they + * should become active. + */ + + Shm_Local_node_status->status = Shm_Pending_initialization; + + do { + + if ( Shm_Local_node_status->status == Shm_Pending_initialization ) { + + /* + * Initialize this node's interrupt information in the + * shared area so other nodes can interrupt us. + */ + + Shm_Local_node_status->int_address = + (rtems_unsigned32) interrupt_address; + Shm_Local_node_status->int_value = interrupt_value; + Shm_Local_node_status->int_length = interrupt_cause; + + Shm_Local_node_status->status = Shm_Initialization_complete; + } + } while ( Shm_Local_node_status->status != Shm_Active_node ) ; + } + + /* + * Initialize the Interrupt Information Table + */ + + for ( i = SHM_FIRST_NODE ; i <= Shm_Maximum_nodes ; i++ ) { + nscb = &Shm_Node_statuses[ i ]; + + Shm_Interrupt_table[i].address = Shm_Convert_address( + (void *)Shm_Convert(((vol_u32) nscb->int_address)) + ); + Shm_Interrupt_table[i].value = Shm_Convert( nscb->int_value ); + Shm_Interrupt_table[i].length = Shm_Convert( nscb->int_length ); + } + + MPCI_Shm_extensions.fatal = MPCI_Fatal; + (void) rtems_extension_create( + rtems_build_name( 'M', 'P', 'E', 'X' ), + &MPCI_Shm_extensions, + &extension_id + ); +} diff --git a/c/src/lib/libbsp/shmdr/initlq.c b/c/src/lib/libbsp/shmdr/initlq.c new file mode 100644 index 0000000000..3f44cf577d --- /dev/null +++ b/c/src/lib/libbsp/shmdr/initlq.c @@ -0,0 +1,35 @@ +/* void Shm_Locked_queue_Initialize( lq_cb, owner ) + * + * This routine initializes a shared memory locked queue. + * + * Input parameters: + * lq_cb - pointer to the control block of the queue + * to be initialized + * owner - unique idenitifier of who owns this queue. + * + * Output parameters: NONE + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include "shm.h" + +void Shm_Locked_queue_Initialize( + Shm_Locked_queue_Control *lq_cb, + rtems_unsigned32 owner +) +{ + Shm_Initialize_lock( lq_cb ); + lq_cb->front = Shm_Locked_queue_End_of_list; + lq_cb->rear = Shm_Locked_queue_End_of_list; + lq_cb->owner = Shm_Convert(owner); +} diff --git a/c/src/lib/libbsp/shmdr/intr.c b/c/src/lib/libbsp/shmdr/intr.c new file mode 100644 index 0000000000..8982103227 --- /dev/null +++ b/c/src/lib/libbsp/shmdr/intr.c @@ -0,0 +1,58 @@ +/* void Shm_Cause_interrupt( node ) + * + * This routine is the shared memory driver routine which + * generates interrupts to other CPUs. + * + * It uses the information placed in the node status control + * block by each node. For example, when used with the Motorola + * MVME136 board, the MPCSR is used. + * + * Input parameters: + * node - destination of this packet (0 = broadcast) + * + * Output parameters: NONE + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include "shm.h" + +void Shm_Cause_interrupt( + rtems_unsigned32 node +) +{ + Shm_Interrupt_information *intr; + rtems_unsigned8 *u8; + rtems_unsigned16 *u16; + rtems_unsigned32 *u32; + rtems_unsigned32 value; + + intr = &Shm_Interrupt_table[node]; + value = intr->value; + + switch ( intr->length ) { + case NO_INTERRUPT: + break; + case BYTE: + u8 = (rtems_unsigned8 *)intr->address; + *u8 = (rtems_unsigned8) value; + break; + case WORD: + u16 = (rtems_unsigned16 *)intr->address; + *u16 = (rtems_unsigned16) value; + break; + case LONG: + u32 = (rtems_unsigned32 *)intr->address; + *u32 = (rtems_unsigned32) value; + break; + } +} diff --git a/c/src/lib/libbsp/shmdr/mpci.h b/c/src/lib/libbsp/shmdr/mpci.h new file mode 100644 index 0000000000..819349f96f --- /dev/null +++ b/c/src/lib/libbsp/shmdr/mpci.h @@ -0,0 +1,59 @@ +/* mpci.h + * + * This include file contains all the renaming necessary to + * have an application use the Shared Memory Driver as its + * sole mechanism for MPCI. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __MPCI_h +#define __MPCI_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include "shm.h" + +#define MPCI_Initialization( _configuration ) \ + Shm_Initialization( _configuration ) + +#define MPCI_Get_packet( _the_packet ) \ + Shm_Get_packet( _the_packet ) + +#define MPCI_Return_packet( _the_packet ) \ + Shm_Return_packet( _the_packet ) + +#define MPCI_Receive_packet( _the_packet ) \ + Shm_Receive_packet( _the_packet ) + +#define MPCI_Send_packet( _destination, _the_packet ) \ + Shm_Send_packet( _destination, _the_packet ) + +/* Unnecessary... mapped in shm.h +#define MPCI_Fatal( _the_error ) \ + Shm_Fatal( _the_error ) +*/ + +#define MPCI_Enable_statistics() + +#define MPCI_Print_statistics() \ + Shm_Print_statistics() + +/* no need to rename the MPCI_Table either */ + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/c/src/lib/libbsp/shmdr/mpisr.c b/c/src/lib/libbsp/shmdr/mpisr.c new file mode 100644 index 0000000000..93ced3d351 --- /dev/null +++ b/c/src/lib/libbsp/shmdr/mpisr.c @@ -0,0 +1,23 @@ +/* _Shm_isr() + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include "shm.h" + +rtems_isr Shm_isr( + rtems_vector_number vector +) +{ + Shm_Interrupt_count += 1; + rtems_multiprocessing_announce(); +} diff --git a/c/src/lib/libbsp/shmdr/poll.c b/c/src/lib/libbsp/shmdr/poll.c new file mode 100644 index 0000000000..43f6711ff9 --- /dev/null +++ b/c/src/lib/libbsp/shmdr/poll.c @@ -0,0 +1,40 @@ +/* void Shm_Poll() + * + * This routine polls to see if a packet has arrived. If one + * has it informs the executive. It is typically called from + * the clock tick interrupt service routine. + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include "shm.h" +#include "clockdrv.h" + +void Shm_Poll() +{ + rtems_unsigned32 tmpfront; + + Clock_isr( 0 ); /* invoke standard clock ISR */ + + /* enable_tracing(); */ + /* ticks += 1; */ + Shm_Lock( Shm_Local_receive_queue ); + tmpfront = Shm_Local_receive_queue->front; + Shm_Unlock( Shm_Local_receive_queue ); + if ( Shm_Convert(tmpfront) == Shm_Locked_queue_End_of_list ) return; + rtems_multiprocessing_announce(); + Shm_Interrupt_count++; +} diff --git a/c/src/lib/libbsp/shmdr/receive.c b/c/src/lib/libbsp/shmdr/receive.c new file mode 100644 index 0000000000..e094a2df6b --- /dev/null +++ b/c/src/lib/libbsp/shmdr/receive.c @@ -0,0 +1,44 @@ +/* Shm_Receive_packet + * + * This routine is the shared memory locked queue MPCI driver routine + * used to obtain a packet containing a message from this node's + * receive queue. + * + * Input parameters: + * packet - address of a pointer to a packet + * + * Output parameters: + * *(rpb->packet) - pointer to packet + * NULL if no packet currently available + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include "shm.h" + +rtems_mpci_entry Shm_Receive_packet( + rtems_packet_prefix **packet +) +{ + Shm_Envelope_control *ecb; + + ecb = Shm_Locked_queue_Get( Shm_Local_receive_queue ); + if ( ecb ) { + *(packet) = Shm_Envelope_control_to_packet_prefix_pointer( ecb ); + if ( ecb->Preamble.endian != Shm_Configuration->format ) + Shm_Convert_packet( *packet ); + Shm_Receive_message_count++; + } else { + *(packet) = NULL; + Shm_Null_message_count++; + } +} diff --git a/c/src/lib/libbsp/shmdr/retpkt.c b/c/src/lib/libbsp/shmdr/retpkt.c new file mode 100644 index 0000000000..973b84ab0d --- /dev/null +++ b/c/src/lib/libbsp/shmdr/retpkt.c @@ -0,0 +1,32 @@ +/* Shm_Return_packet + * + * This routine is the shared memory locked queue MPCI driver + * routine used to return a message packet to a free envelope + * pool accessible by this node. + * + * Input parameters: + * packet - address of pointer to packet + * + * Output parameters: NONE + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include "shm.h" + +rtems_mpci_entry Shm_Return_packet( + rtems_packet_prefix *packet +) +{ + Shm_Free_envelope( Shm_Packet_prefix_to_envelope_control_pointer(packet) ); +} + diff --git a/c/src/lib/libbsp/shmdr/send.c b/c/src/lib/libbsp/shmdr/send.c new file mode 100644 index 0000000000..58a5bb93b9 --- /dev/null +++ b/c/src/lib/libbsp/shmdr/send.c @@ -0,0 +1,61 @@ +/* Shm_Send_packet + * + * This routine is the shared memory driver locked queue write + * MPCI driver routine. This routine sends the specified packet + * to the destination specified by "node". A "node" value of + * zero designates that this packet is to be broadcasted. + * + * Input parameters: + * node - destination of this packet (0 = broadcast) + * packet - address of packet + * + * Output parameters: NONE + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include "shm.h" + +struct pkt_cpy { + rtems_unsigned32 packet[MAX_PACKET_SIZE/4]; +}; + +rtems_mpci_entry Shm_Send_packet( + rtems_unsigned32 node, + rtems_packet_prefix *packet +) +{ + Shm_Envelope_control *ecb, *tmp_ecb; + rtems_unsigned32 nnum; + + ecb = Shm_Packet_prefix_to_envelope_control_pointer( packet ); + if ( node ) { + Shm_Build_preamble( ecb, node ); + Shm_Build_postamble( ecb ); + Shm_Append_to_receive_queue( node, ecb ); + (*Shm_Configuration->cause_intr)( node ); + } + else { + for( nnum = SHM_FIRST_NODE ; nnum <= Shm_Maximum_nodes ; nnum++ ) + if ( Shm_Local_node != nnum ) { + tmp_ecb = Shm_Allocate_envelope(); + if ( !tmp_ecb ) + rtems_fatal_error_occurred( SHM_NO_FREE_PKTS ); + Shm_Build_preamble( tmp_ecb, nnum ); + *((struct pkt_cpy *)tmp_ecb->packet) = *((struct pkt_cpy *)packet); + Shm_Build_postamble( tmp_ecb ); + Shm_Append_to_receive_queue( nnum, tmp_ecb ); + (*Shm_Configuration->cause_intr)( nnum ); + } + Shm_Free_envelope( ecb ); + } +} diff --git a/c/src/lib/libbsp/shmdr/setckvec.c b/c/src/lib/libbsp/shmdr/setckvec.c new file mode 100644 index 0000000000..0b5e306dab --- /dev/null +++ b/c/src/lib/libbsp/shmdr/setckvec.c @@ -0,0 +1,28 @@ +/* Shm_setclockvec + * + * This routines installs the shared memory clock interrupt handler + * used when the driver is used in polling mode. + * + * INPUT PARAMETERS: NONE + * + * OUTPUT PARAMETERS: NONE + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include "shm.h" +#include "clockdrv.h" + +rtems_isr Shm_setclockvec() +{ + ReInstall_clock( Shm_Poll ); +} diff --git a/c/src/lib/libbsp/shmdr/shm.h b/c/src/lib/libbsp/shmdr/shm.h new file mode 100644 index 0000000000..bee930138c --- /dev/null +++ b/c/src/lib/libbsp/shmdr/shm.h @@ -0,0 +1,542 @@ +/* shm.h + * + * This include file contains all the constants, structures, + * and global variables for this RTEMS based shared memory + * communications interface driver. + * + * Processor board dependencies are in other files. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __SHM_h +#define __SHM_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/* The information contained in the Node Status, Locked Queue, and + * Envelope Control Blocks must be maintained in a NEUTRAL format. + * Currently the neutral format may be selected as big or little + * endian by simply defining either NEUTRAL_BIG or NEUTRAL_LITTLE. + * + * It is CRITICAL to note that the neutral format can ONLY be + * changed by modifying this file and recompiling the ENTIRE + * SHM driver including ALL target specific support files. + * + * The following table details the memory contents for the endian + * field of the Node Status Control Block in the various + * data format configurations (data is in hexadecimal): + * + * NEUTRAL NATIVE BYTE 0 BYTE 1 BYTE 2 BYTE 3 + * ======= ====== ====== ====== ====== ====== + * BIG BIG 00 00 00 01 + * BIG LITTLE 10 00 00 00 + * LITTLE BIG 01 00 00 00 + * LITTLE LITTLE 00 00 00 10 + * + * + * NOTE: XXX + * PORTABILITY OF LOCKING INSTRUCTIONS + * =================================== + * The locking mechanism described below is not + * general enough. Where the hardware supports + * it we should use "atomic swap" instructions + * so the values in the lock can be tailored to + * support a CPU with only weak atomic memory + * instructions. There are combinations of + * CPUs with inflexible atomic memory instructions + * which appear to be incompatible. For example, + * the SPARClite instruction uses a byte which is + * 0xFF when locked. The PA-RISC uses 1 to indicate + * locked and 0 when unlocked. These CPUs appear to + * have incompatible lock instructions. But + * they could be used in a heterogenous system + * with does not mix SPARCs and PA-RISCs. For + * example, the i386 and SPARC or i386 and SPARC + * could work together. The bottom line is that + * not every CPU will work together using this + * locking scheme. There are supposed to be + * algorithms to do this without hardware assist + * and one of these should be incorporated into + * the shared memory driver. + * + * The most flexible scheme using the instructions + * of the various CPUs for efficiency would be to use + * "atomic swaps" wherever possible. Make the lock + * and unlock configurable much like BIG vs LITTLE + * endian use of shared memory is now. The values + * of the lock could then reflect the "worst" + * CPU in a system. This still results in mixes + * of CPUs which are incompatible. + * + * The current locking mechanism is based upon the MC68020 + * "tas" instruction which is atomic. All ports to other CPUs + * comply with the restrictive placement of lock bit by this + * instruction. The lock bit is the most significant bit in a + * big-endian rtems_unsigned32. On other processors, the lock is + * typically implemented via an atomic swap or atomic modify + * bits type instruction. + */ + +#define NEUTRAL_BIG + +#ifdef NEUTRAL_BIG +#define SHM_BIG 0x00000001 +#define SHM_LITTLE 0x10000000 +#endif + +#ifdef NEUTRAL_LITTLE +#define SHM_BIG 0x01000000 +#define SHM_LITTLE 0x00000010 +#endif + +/* + * The following are the values used to fill in the lock field. Some CPUs + * are able to write only a single value into field. By making the + * lock and unlock values configurable, CPUs which support "atomic swap" + * instructions can generally be made to work in any heterogeneous + * configuration. However, it is possible for two CPUs to be incompatible + * in regards to the lock field values. This occurs when two CPUs + * which write only a single value to the field are used in a system + * but the two CPUs write different incompatible values. + * + * NOTE: The following is a first attempt at defining values which + * have a chance at working together. The m68k should use + * chk2 instead of tas to be less restrictive. Target endian + * problems (like the Force CPU386 which has (broken) big endian + * view of the VMEbus address space) are not addressed yet. + */ + +#if defined(i960) +#define SHM_LOCK_VALUE 0x00000080 +#define SHM_UNLOCK_VALUE 0 +#elif defined(m68k) +#define SHM_LOCK_VALUE 0x80000000 +#define SHM_UNLOCK_VALUE 0 +#define SHM_LOCK_VALUE 0x80000000 +#define SHM_UNLOCK_VALUE 0 +#elif defined(i386) +#define SHM_LOCK_VALUE 0x80000000 +#define SHM_UNLOCK_VALUE 0 +#elif defined(hppa1_1) +#define SHM_LOCK_VALUE 0 +#define SHM_UNLOCK_VALUE 1 +#elif defined(unix) +#define SHM_LOCK_VALUE 0 +#define SHM_UNLOCK_VALUE 1 +#elif defined(no_cpu) /* for this values are irrelevant */ +#define SHM_LOCK_VALUE 1 +#define SHM_UNLOCK_VALUE 0 +#endif + +#define Shm_Convert( value ) \ + ((Shm_Configuration->convert) ? \ + (*Shm_Configuration->convert)(value) : (value)) + +/* constants */ + +#define SHM_MASTER 1 /* master initialization node */ +#define SHM_FIRST_NODE 1 + +/* size constants */ + +#define KILOBYTE (1024) +#define MEGABYTE (1024*1024) + +/* inter-node interrupt values */ + +#define NO_INTERRUPT 0 /* used for polled nodes */ +#define BYTE 1 +#define WORD 2 +#define LONG 4 + +/* operational mode constants -- used in SHM Configuration Table */ +#define POLLED_MODE 0 +#define INTR_MODE 1 + +/* error codes */ + +#define NO_ERROR 0 +#define SHM_NO_FREE_PKTS 0xf0000 + +/* null pointers of different types */ + +#define NULL_ENV_CB ((Shm_Envelope_control *) 0) +#define NULL_SHM_INFO ((struct shm_info *) 0) +#define NULL_CONVERT 0 +#if 0 +#define NULL_CONVERT (((rtems_unsigned32 *)())0) /* we want this */ +#endif + +/* The following is adjusted so envelopes are 0x80 bytes long. */ +/* It should be >= MIN_PKT_SIZE in rtems.h */ + +#define MAX_PACKET_SIZE (80) + +/* constants pertinent to Locked Queue routines */ + +#define LQ_UNLOCKED SHM_UNLOCK_VALUE +#define LQ_LOCKED SHM_LOCK_VALUE + +/* constants related to the Free Envelope Pool */ + +#define FREE_ENV_POOL 0 +#define FREE_ENV_CB (&Shm_Locked_queues[ FREE_ENV_POOL ]) + +/* The following are important when dealing with + * the shared memory communications interface area. + * + * NOTE: The starting address and length of the shared memory + * is defined in a system dependent file. + */ + +#if 0 +#define START_NS_CBS ( (rtems_unsigned8 *) START_SHARED_MEM ) +#define START_LQ_CBS ( ((rtems_unsigned8 *) START_NS_CBS) + \ + ( (sizeof (Shm_Node_status_control)) * (Shm_Maximum_nodes + 1) ) ) +#define START_ENVELOPES ( ((rtems_unsigned8 *) START_LQ_CBS) + \ + ( (sizeof (Shm_Locked_queue_Control)) * (Shm_Maximum_nodes + 1) ) ) +#define END_SHMCI_AREA ( (rtems_unsigned8 *) START_ENVELOPES + \ + ( (sizeof (Shm_Envelope_control)) * Shm_Maximum_envelopes ) ) +#define END_SHARED_MEM ((rtems_unsigned32)START_SHARED_MEM+SHARED_MEM_LEN) +#endif + +#define START_NS_CBS ((void *)Shm_Configuration->base) +#define START_LQ_CBS ((START_NS_CBS) + \ + ( (sizeof (Shm_Node_status_control)) * (Shm_Maximum_nodes + 1) ) ) +#define START_ENVELOPES ( ((void *) START_LQ_CBS) + \ + ( (sizeof (Shm_Locked_queue_Control)) * (Shm_Maximum_nodes + 1) ) ) +#define END_SHMCI_AREA ( (void *) START_ENVELOPES + \ + ( (sizeof (Shm_Envelope_control)) * Shm_Maximum_envelopes ) ) +#define END_SHARED_MEM (START_NS_CBS+Shm_Configuration->length) + +/* macros */ + +#define Shm_Is_master_node() \ + ( SHM_MASTER == Shm_Local_node ) + +#define Shm_Free_envelope( ecb ) \ + Shm_Locked_queue_Add( FREE_ENV_CB, (ecb) ) +#define Shm_Allocate_envelope() \ + Shm_Locked_queue_Get(FREE_ENV_CB) + +#define Shm_Initialize_receive_queue(node) \ + Shm_Locked_queue_Initialize( &Shm_Locked_queues[node], node ) + +#define Shm_Append_to_receive_queue(node, ecb) \ + Shm_Locked_queue_Add( &Shm_Locked_queues[node], (ecb) ) + +#define Shm_Envelope_control_to_packet_prefix_pointer(ecb) \ + ((void *)(ecb)->packet) + +#define Shm_Packet_prefix_to_envelope_control_pointer( pkt ) \ + ((Shm_Envelope_control *)((rtems_unsigned8 *)(pkt) - \ + (sizeof(Shm_Envelope_preamble) + 4*sizeof(vol_u32)))) + +#define Shm_Build_preamble(ecb, node) \ + (ecb)->Preamble.endian = Shm_Configuration->format + +#define Shm_Build_postamble( ecb ) + +/* structures */ + +typedef volatile rtems_unsigned8 vol_u8; +typedef volatile rtems_unsigned32 vol_u32; + +/* shm control information */ + +struct shm_info { + vol_u32 not_currently_used_0; + vol_u32 not_currently_used_1; + vol_u32 not_currently_used_2; + vol_u32 not_currently_used_3; +}; + +typedef struct { + /*byte start_of_text;*/ + vol_u32 endian; + vol_u32 not_currently_used_0; + vol_u32 not_currently_used_1; + vol_u32 not_currently_used_2; +} Shm_Envelope_preamble; + +typedef struct { + vol_u32 not_currently_used_0; + vol_u32 not_currently_used_1; + vol_u32 not_currently_used_2; + vol_u32 not_currently_used_3; + /*byte end_of_text;*/ +} Shm_Envelope_postable; + +/* WARNING! If you change this structure, don't forget to change + * Shm_Envelope_control_to_packet_prefix_pointer() and + * Shm_Packet_prefix_to_envelope_control_pointer() above. + */ + +/* This comment block describes the contents of each field + * of the Envelope Control Block: + * + * next - The index of the next envelope on this queue. + * queue - The index of the queue this envelope is on. + * index - The index of this envelope. + * Preamble - Generic packet preamble. One day this structure + * could be enhanced to contain routing information. + * packet - RTEMS MPCI packet. Untouched by SHM Driver + * other than copying and format conversion as + * documented in the RTEMS User's Guide. + * Postamble - Generic packet postamble. One day this structure + * could be enhanced to contain checksum information. + */ + +typedef struct { + vol_u32 next; /* next envelope on queue */ + vol_u32 queue; /* queue on which this resides */ + vol_u32 index; /* index into array of envelopes*/ + vol_u32 pad0; /* insure the next one is aligned */ + Shm_Envelope_preamble Preamble; /* header information */ + vol_u8 packet[MAX_PACKET_SIZE]; /* RTEMS INFO */ + Shm_Envelope_postable Postamble;/* trailer information */ +} Shm_Envelope_control; + +/* This comment block describes the contents of each field + * of the Locked Queue Control Block: + * + * lock - Lock used to insure mutually exclusive access. + * front - Index of first envelope on queue. This field + * is used to remove head of queue (receive). + * rear - Index of last envelope on queue. This field + * is used to add evelope to queue (send). + * owner - The node number of the recipient (owning) node. + * RTEMS does not use the node number zero (0). + * The zero node is used by the SHM Driver for the + * Free Envelope Queue shared by all nodes. + */ + +typedef struct { + vol_u32 lock; /* lock field for this queue */ + vol_u32 front; /* first envelope on queue */ + vol_u32 rear; /* last envelope on queue */ + vol_u32 owner; /* receiving (i.e. owning) node */ +} Shm_Locked_queue_Control; + +/* This comment block describes the contents of each field + * of the Node Status Control Block: + * + * status - Node status. Current values are Pending Initialization, + * Initialization Complete, and Active Node. Other values + * could be added to enhance fault tolerance. + * error - Zero if the node has not failed. Otherwise, + * this field contains a status indicating the + * failure reason. + * int_address, int_value, and int_length + * - These field are the Interrupt Information table + * for this node in neutral format. This is how + * each node knows how to generate interrupts. + */ + +typedef struct { + vol_u32 status; /* node status information */ + vol_u32 error; /* fatal error code */ + vol_u32 int_address; /* write here for interrupt */ + vol_u32 int_value; /* this value causes interrupt */ + vol_u32 int_length; /* for this length (0,1,2,4) */ + vol_u32 not_currently_used_0; + vol_u32 not_currently_used_1; + vol_u32 not_currently_used_2; +} Shm_Node_status_control; + +/* This comment block describes the contents of each field + * of the Interrupt Information Table. This table describes + * how another node can generate an interrupt to this node. + * This information is target board dependent. If the + * SHM Driver is in POLLED_MODE, then all fields should + * be initialized to NO_INTERRUPT. + * + * address - The address to which another node should + * write to cause an interrupt. + * value - The value which must be written + * length - The size of the value to write. Valid + * values are BYTE, WORD, and LONG. + * + * NOTE: The Node Status Control Block contains this + * information in neutral format and not in a + * structure to avoid potential alignment problems. + */ + +typedef struct { + vol_u32 *address; /* write here for interrupt */ + vol_u32 value; /* this value causes interrupt */ + vol_u32 length; /* for this length (0,1,2,4) */ +} Shm_Interrupt_information; + +/* SHM Configuration Table + * + * This comment block describes the contents of each field + * of the SHM Configuration Table. + * + * base - The base address of the shared memory. This + * address may be specific to this node. + * length - The length of the shared memory in bytes. + * format - The natural format for rtems_unsigned32's in the + * shared memory. Valid values are currently + * only SHM_LITTLE and SHM_BIG. + * convert - The address of the routine which converts + * between neutral and local format. + * poll_intr - The operational mode of the driver. Some + * target boards may not provide hardware for + * an interprocessor interrupt. If POLLED_MODE + * is selected, the SHM driver will install a + * wrapper around the Clock_isr() to poll for + * incoming packets. Throughput is dependent + * on the time between clock interrupts. + * Valid values are POLLED_MODE and INTR_MODE. + * cause_intr - This is the address of the routine used to + * write to a particular address and cause an + * interrupt on another node. This routine + * may need to be target dependent if something + * other than a normal write from C does not work. + * Intr - This structure describes the operation required + * to cause an interrupt to this node. The actual + * contents of this structure are described above. + */ + +struct shm_config_info { + vol_u32 *base; /* base address of SHM */ + vol_u32 length; /* length (in bytes) of SHM */ + vol_u32 format; /* SHM is big or little endian */ + vol_u32 (*convert)();/* neutral conversion routine */ + vol_u32 poll_intr;/* POLLED or INTR driven mode */ + void (*cause_intr)( rtems_unsigned32 ); + Shm_Interrupt_information Intr; /* cause intr information */ +}; + +typedef struct shm_config_info shm_config_table; + +/* global variables */ + +#ifdef _SHM_INIT +#define SHM_EXTERN +#else +#define SHM_EXTERN extern +#endif + +SHM_EXTERN shm_config_table *Shm_Configuration; +SHM_EXTERN Shm_Interrupt_information Shm_Interrupt_table[16]; +SHM_EXTERN Shm_Node_status_control *Shm_Node_statuses; +SHM_EXTERN Shm_Locked_queue_Control *Shm_Locked_queues; +SHM_EXTERN Shm_Envelope_control *Shm_Envelopes; +SHM_EXTERN rtems_configuration_table *Shm_RTEMS_Configuration; +SHM_EXTERN rtems_multiprocessing_table *Shm_RTEMS_MP_Configuration; +SHM_EXTERN rtems_unsigned32 Shm_Receive_message_count; +SHM_EXTERN rtems_unsigned32 Shm_Null_message_count; +SHM_EXTERN rtems_unsigned32 Shm_Interrupt_count; +SHM_EXTERN rtems_unsigned32 Shm_Local_node; +SHM_EXTERN Shm_Locked_queue_Control *Shm_Local_receive_queue; +SHM_EXTERN Shm_Node_status_control *Shm_Local_node_status; +SHM_EXTERN rtems_unsigned32 Shm_isrstat; + /* reported by shmdr */ + +SHM_EXTERN rtems_unsigned32 Shm_Pending_initialization; +SHM_EXTERN rtems_unsigned32 Shm_Initialization_complete; +SHM_EXTERN rtems_unsigned32 Shm_Active_node; + +SHM_EXTERN rtems_unsigned32 Shm_Maximum_nodes; +SHM_EXTERN rtems_unsigned32 Shm_Maximum_envelopes; + +SHM_EXTERN rtems_unsigned32 Shm_Locked_queue_End_of_list; +SHM_EXTERN rtems_unsigned32 Shm_Locked_queue_Not_on_list; + +/* functions */ + +/* locked queue routines */ +void Shm_Locked_queue_Add( + Shm_Locked_queue_Control *, Shm_Envelope_control * ); +Shm_Envelope_control *Shm_Locked_queue_Get( Shm_Locked_queue_Control * ); +void Shm_Locked_queue_Initialize( + Shm_Locked_queue_Control *, rtems_unsigned32 ); + /* Shm_Initialize_lock is CPU dependent */ + /* Shm_Lock is CPU dependent */ + /* Shm_Unlock is CPU dependent */ + +/* portable routines */ +void Init_env_pool(); +void Shm_Print_statistics( void ); +void MPCI_Fatal( rtems_unsigned32 ); +rtems_task Shm_Cause_interrupt( rtems_unsigned32 ); +void Shm_Poll(); +void Shm_setclockvec(); +void Shm_Convert_packet( rtems_packet_prefix * ); + +/* CPU specific routines are inlined in shmcpu.h */ + +/* target specific routines */ +void *Shm_Convert_address( void * ); +void Shm_Get_configuration( rtems_unsigned32, shm_config_table ** ); +void Shm_isr(); +void Shm_setvec( void ); + +void Shm_Initialize_lock( Shm_Locked_queue_Control * ); +void Shm_Lock( Shm_Locked_queue_Control * ); +void Shm_Unlock( Shm_Locked_queue_Control * ); + +/* MPCI entry points */ +rtems_mpci_entry Shm_Get_packet( + rtems_packet_prefix ** +); + +rtems_mpci_entry Shm_Initialization( + rtems_configuration_table *configuration, + rtems_cpu_table *cpu_configuration, + rtems_multiprocessing_table *mp_configuration +); + +rtems_mpci_entry Shm_Receive_packet( + rtems_packet_prefix ** +); + +rtems_mpci_entry Shm_Return_packet( + rtems_packet_prefix * +); + +rtems_mpci_entry Shm_Send_packet( + rtems_unsigned32, + rtems_packet_prefix * +); + +#ifdef _SHM_INIT + +/* multiprocessor communications interface (MPCI) table */ + +rtems_mpci_table MPCI_table = { + 100000, /* default timeout value in ticks */ + Shm_Initialization, /* initialization procedure */ + Shm_Get_packet, /* get packet procedure */ + Shm_Return_packet, /* return packet procedure */ + Shm_Send_packet, /* packet send procedure */ + Shm_Receive_packet /* packet receive procedure */ +}; + +#else + +extern rtems_mpci_table MPCI_table; + +#endif + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/c/src/lib/libbsp/shmdr/shm_driver.h b/c/src/lib/libbsp/shmdr/shm_driver.h new file mode 100644 index 0000000000..bee930138c --- /dev/null +++ b/c/src/lib/libbsp/shmdr/shm_driver.h @@ -0,0 +1,542 @@ +/* shm.h + * + * This include file contains all the constants, structures, + * and global variables for this RTEMS based shared memory + * communications interface driver. + * + * Processor board dependencies are in other files. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __SHM_h +#define __SHM_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/* The information contained in the Node Status, Locked Queue, and + * Envelope Control Blocks must be maintained in a NEUTRAL format. + * Currently the neutral format may be selected as big or little + * endian by simply defining either NEUTRAL_BIG or NEUTRAL_LITTLE. + * + * It is CRITICAL to note that the neutral format can ONLY be + * changed by modifying this file and recompiling the ENTIRE + * SHM driver including ALL target specific support files. + * + * The following table details the memory contents for the endian + * field of the Node Status Control Block in the various + * data format configurations (data is in hexadecimal): + * + * NEUTRAL NATIVE BYTE 0 BYTE 1 BYTE 2 BYTE 3 + * ======= ====== ====== ====== ====== ====== + * BIG BIG 00 00 00 01 + * BIG LITTLE 10 00 00 00 + * LITTLE BIG 01 00 00 00 + * LITTLE LITTLE 00 00 00 10 + * + * + * NOTE: XXX + * PORTABILITY OF LOCKING INSTRUCTIONS + * =================================== + * The locking mechanism described below is not + * general enough. Where the hardware supports + * it we should use "atomic swap" instructions + * so the values in the lock can be tailored to + * support a CPU with only weak atomic memory + * instructions. There are combinations of + * CPUs with inflexible atomic memory instructions + * which appear to be incompatible. For example, + * the SPARClite instruction uses a byte which is + * 0xFF when locked. The PA-RISC uses 1 to indicate + * locked and 0 when unlocked. These CPUs appear to + * have incompatible lock instructions. But + * they could be used in a heterogenous system + * with does not mix SPARCs and PA-RISCs. For + * example, the i386 and SPARC or i386 and SPARC + * could work together. The bottom line is that + * not every CPU will work together using this + * locking scheme. There are supposed to be + * algorithms to do this without hardware assist + * and one of these should be incorporated into + * the shared memory driver. + * + * The most flexible scheme using the instructions + * of the various CPUs for efficiency would be to use + * "atomic swaps" wherever possible. Make the lock + * and unlock configurable much like BIG vs LITTLE + * endian use of shared memory is now. The values + * of the lock could then reflect the "worst" + * CPU in a system. This still results in mixes + * of CPUs which are incompatible. + * + * The current locking mechanism is based upon the MC68020 + * "tas" instruction which is atomic. All ports to other CPUs + * comply with the restrictive placement of lock bit by this + * instruction. The lock bit is the most significant bit in a + * big-endian rtems_unsigned32. On other processors, the lock is + * typically implemented via an atomic swap or atomic modify + * bits type instruction. + */ + +#define NEUTRAL_BIG + +#ifdef NEUTRAL_BIG +#define SHM_BIG 0x00000001 +#define SHM_LITTLE 0x10000000 +#endif + +#ifdef NEUTRAL_LITTLE +#define SHM_BIG 0x01000000 +#define SHM_LITTLE 0x00000010 +#endif + +/* + * The following are the values used to fill in the lock field. Some CPUs + * are able to write only a single value into field. By making the + * lock and unlock values configurable, CPUs which support "atomic swap" + * instructions can generally be made to work in any heterogeneous + * configuration. However, it is possible for two CPUs to be incompatible + * in regards to the lock field values. This occurs when two CPUs + * which write only a single value to the field are used in a system + * but the two CPUs write different incompatible values. + * + * NOTE: The following is a first attempt at defining values which + * have a chance at working together. The m68k should use + * chk2 instead of tas to be less restrictive. Target endian + * problems (like the Force CPU386 which has (broken) big endian + * view of the VMEbus address space) are not addressed yet. + */ + +#if defined(i960) +#define SHM_LOCK_VALUE 0x00000080 +#define SHM_UNLOCK_VALUE 0 +#elif defined(m68k) +#define SHM_LOCK_VALUE 0x80000000 +#define SHM_UNLOCK_VALUE 0 +#define SHM_LOCK_VALUE 0x80000000 +#define SHM_UNLOCK_VALUE 0 +#elif defined(i386) +#define SHM_LOCK_VALUE 0x80000000 +#define SHM_UNLOCK_VALUE 0 +#elif defined(hppa1_1) +#define SHM_LOCK_VALUE 0 +#define SHM_UNLOCK_VALUE 1 +#elif defined(unix) +#define SHM_LOCK_VALUE 0 +#define SHM_UNLOCK_VALUE 1 +#elif defined(no_cpu) /* for this values are irrelevant */ +#define SHM_LOCK_VALUE 1 +#define SHM_UNLOCK_VALUE 0 +#endif + +#define Shm_Convert( value ) \ + ((Shm_Configuration->convert) ? \ + (*Shm_Configuration->convert)(value) : (value)) + +/* constants */ + +#define SHM_MASTER 1 /* master initialization node */ +#define SHM_FIRST_NODE 1 + +/* size constants */ + +#define KILOBYTE (1024) +#define MEGABYTE (1024*1024) + +/* inter-node interrupt values */ + +#define NO_INTERRUPT 0 /* used for polled nodes */ +#define BYTE 1 +#define WORD 2 +#define LONG 4 + +/* operational mode constants -- used in SHM Configuration Table */ +#define POLLED_MODE 0 +#define INTR_MODE 1 + +/* error codes */ + +#define NO_ERROR 0 +#define SHM_NO_FREE_PKTS 0xf0000 + +/* null pointers of different types */ + +#define NULL_ENV_CB ((Shm_Envelope_control *) 0) +#define NULL_SHM_INFO ((struct shm_info *) 0) +#define NULL_CONVERT 0 +#if 0 +#define NULL_CONVERT (((rtems_unsigned32 *)())0) /* we want this */ +#endif + +/* The following is adjusted so envelopes are 0x80 bytes long. */ +/* It should be >= MIN_PKT_SIZE in rtems.h */ + +#define MAX_PACKET_SIZE (80) + +/* constants pertinent to Locked Queue routines */ + +#define LQ_UNLOCKED SHM_UNLOCK_VALUE +#define LQ_LOCKED SHM_LOCK_VALUE + +/* constants related to the Free Envelope Pool */ + +#define FREE_ENV_POOL 0 +#define FREE_ENV_CB (&Shm_Locked_queues[ FREE_ENV_POOL ]) + +/* The following are important when dealing with + * the shared memory communications interface area. + * + * NOTE: The starting address and length of the shared memory + * is defined in a system dependent file. + */ + +#if 0 +#define START_NS_CBS ( (rtems_unsigned8 *) START_SHARED_MEM ) +#define START_LQ_CBS ( ((rtems_unsigned8 *) START_NS_CBS) + \ + ( (sizeof (Shm_Node_status_control)) * (Shm_Maximum_nodes + 1) ) ) +#define START_ENVELOPES ( ((rtems_unsigned8 *) START_LQ_CBS) + \ + ( (sizeof (Shm_Locked_queue_Control)) * (Shm_Maximum_nodes + 1) ) ) +#define END_SHMCI_AREA ( (rtems_unsigned8 *) START_ENVELOPES + \ + ( (sizeof (Shm_Envelope_control)) * Shm_Maximum_envelopes ) ) +#define END_SHARED_MEM ((rtems_unsigned32)START_SHARED_MEM+SHARED_MEM_LEN) +#endif + +#define START_NS_CBS ((void *)Shm_Configuration->base) +#define START_LQ_CBS ((START_NS_CBS) + \ + ( (sizeof (Shm_Node_status_control)) * (Shm_Maximum_nodes + 1) ) ) +#define START_ENVELOPES ( ((void *) START_LQ_CBS) + \ + ( (sizeof (Shm_Locked_queue_Control)) * (Shm_Maximum_nodes + 1) ) ) +#define END_SHMCI_AREA ( (void *) START_ENVELOPES + \ + ( (sizeof (Shm_Envelope_control)) * Shm_Maximum_envelopes ) ) +#define END_SHARED_MEM (START_NS_CBS+Shm_Configuration->length) + +/* macros */ + +#define Shm_Is_master_node() \ + ( SHM_MASTER == Shm_Local_node ) + +#define Shm_Free_envelope( ecb ) \ + Shm_Locked_queue_Add( FREE_ENV_CB, (ecb) ) +#define Shm_Allocate_envelope() \ + Shm_Locked_queue_Get(FREE_ENV_CB) + +#define Shm_Initialize_receive_queue(node) \ + Shm_Locked_queue_Initialize( &Shm_Locked_queues[node], node ) + +#define Shm_Append_to_receive_queue(node, ecb) \ + Shm_Locked_queue_Add( &Shm_Locked_queues[node], (ecb) ) + +#define Shm_Envelope_control_to_packet_prefix_pointer(ecb) \ + ((void *)(ecb)->packet) + +#define Shm_Packet_prefix_to_envelope_control_pointer( pkt ) \ + ((Shm_Envelope_control *)((rtems_unsigned8 *)(pkt) - \ + (sizeof(Shm_Envelope_preamble) + 4*sizeof(vol_u32)))) + +#define Shm_Build_preamble(ecb, node) \ + (ecb)->Preamble.endian = Shm_Configuration->format + +#define Shm_Build_postamble( ecb ) + +/* structures */ + +typedef volatile rtems_unsigned8 vol_u8; +typedef volatile rtems_unsigned32 vol_u32; + +/* shm control information */ + +struct shm_info { + vol_u32 not_currently_used_0; + vol_u32 not_currently_used_1; + vol_u32 not_currently_used_2; + vol_u32 not_currently_used_3; +}; + +typedef struct { + /*byte start_of_text;*/ + vol_u32 endian; + vol_u32 not_currently_used_0; + vol_u32 not_currently_used_1; + vol_u32 not_currently_used_2; +} Shm_Envelope_preamble; + +typedef struct { + vol_u32 not_currently_used_0; + vol_u32 not_currently_used_1; + vol_u32 not_currently_used_2; + vol_u32 not_currently_used_3; + /*byte end_of_text;*/ +} Shm_Envelope_postable; + +/* WARNING! If you change this structure, don't forget to change + * Shm_Envelope_control_to_packet_prefix_pointer() and + * Shm_Packet_prefix_to_envelope_control_pointer() above. + */ + +/* This comment block describes the contents of each field + * of the Envelope Control Block: + * + * next - The index of the next envelope on this queue. + * queue - The index of the queue this envelope is on. + * index - The index of this envelope. + * Preamble - Generic packet preamble. One day this structure + * could be enhanced to contain routing information. + * packet - RTEMS MPCI packet. Untouched by SHM Driver + * other than copying and format conversion as + * documented in the RTEMS User's Guide. + * Postamble - Generic packet postamble. One day this structure + * could be enhanced to contain checksum information. + */ + +typedef struct { + vol_u32 next; /* next envelope on queue */ + vol_u32 queue; /* queue on which this resides */ + vol_u32 index; /* index into array of envelopes*/ + vol_u32 pad0; /* insure the next one is aligned */ + Shm_Envelope_preamble Preamble; /* header information */ + vol_u8 packet[MAX_PACKET_SIZE]; /* RTEMS INFO */ + Shm_Envelope_postable Postamble;/* trailer information */ +} Shm_Envelope_control; + +/* This comment block describes the contents of each field + * of the Locked Queue Control Block: + * + * lock - Lock used to insure mutually exclusive access. + * front - Index of first envelope on queue. This field + * is used to remove head of queue (receive). + * rear - Index of last envelope on queue. This field + * is used to add evelope to queue (send). + * owner - The node number of the recipient (owning) node. + * RTEMS does not use the node number zero (0). + * The zero node is used by the SHM Driver for the + * Free Envelope Queue shared by all nodes. + */ + +typedef struct { + vol_u32 lock; /* lock field for this queue */ + vol_u32 front; /* first envelope on queue */ + vol_u32 rear; /* last envelope on queue */ + vol_u32 owner; /* receiving (i.e. owning) node */ +} Shm_Locked_queue_Control; + +/* This comment block describes the contents of each field + * of the Node Status Control Block: + * + * status - Node status. Current values are Pending Initialization, + * Initialization Complete, and Active Node. Other values + * could be added to enhance fault tolerance. + * error - Zero if the node has not failed. Otherwise, + * this field contains a status indicating the + * failure reason. + * int_address, int_value, and int_length + * - These field are the Interrupt Information table + * for this node in neutral format. This is how + * each node knows how to generate interrupts. + */ + +typedef struct { + vol_u32 status; /* node status information */ + vol_u32 error; /* fatal error code */ + vol_u32 int_address; /* write here for interrupt */ + vol_u32 int_value; /* this value causes interrupt */ + vol_u32 int_length; /* for this length (0,1,2,4) */ + vol_u32 not_currently_used_0; + vol_u32 not_currently_used_1; + vol_u32 not_currently_used_2; +} Shm_Node_status_control; + +/* This comment block describes the contents of each field + * of the Interrupt Information Table. This table describes + * how another node can generate an interrupt to this node. + * This information is target board dependent. If the + * SHM Driver is in POLLED_MODE, then all fields should + * be initialized to NO_INTERRUPT. + * + * address - The address to which another node should + * write to cause an interrupt. + * value - The value which must be written + * length - The size of the value to write. Valid + * values are BYTE, WORD, and LONG. + * + * NOTE: The Node Status Control Block contains this + * information in neutral format and not in a + * structure to avoid potential alignment problems. + */ + +typedef struct { + vol_u32 *address; /* write here for interrupt */ + vol_u32 value; /* this value causes interrupt */ + vol_u32 length; /* for this length (0,1,2,4) */ +} Shm_Interrupt_information; + +/* SHM Configuration Table + * + * This comment block describes the contents of each field + * of the SHM Configuration Table. + * + * base - The base address of the shared memory. This + * address may be specific to this node. + * length - The length of the shared memory in bytes. + * format - The natural format for rtems_unsigned32's in the + * shared memory. Valid values are currently + * only SHM_LITTLE and SHM_BIG. + * convert - The address of the routine which converts + * between neutral and local format. + * poll_intr - The operational mode of the driver. Some + * target boards may not provide hardware for + * an interprocessor interrupt. If POLLED_MODE + * is selected, the SHM driver will install a + * wrapper around the Clock_isr() to poll for + * incoming packets. Throughput is dependent + * on the time between clock interrupts. + * Valid values are POLLED_MODE and INTR_MODE. + * cause_intr - This is the address of the routine used to + * write to a particular address and cause an + * interrupt on another node. This routine + * may need to be target dependent if something + * other than a normal write from C does not work. + * Intr - This structure describes the operation required + * to cause an interrupt to this node. The actual + * contents of this structure are described above. + */ + +struct shm_config_info { + vol_u32 *base; /* base address of SHM */ + vol_u32 length; /* length (in bytes) of SHM */ + vol_u32 format; /* SHM is big or little endian */ + vol_u32 (*convert)();/* neutral conversion routine */ + vol_u32 poll_intr;/* POLLED or INTR driven mode */ + void (*cause_intr)( rtems_unsigned32 ); + Shm_Interrupt_information Intr; /* cause intr information */ +}; + +typedef struct shm_config_info shm_config_table; + +/* global variables */ + +#ifdef _SHM_INIT +#define SHM_EXTERN +#else +#define SHM_EXTERN extern +#endif + +SHM_EXTERN shm_config_table *Shm_Configuration; +SHM_EXTERN Shm_Interrupt_information Shm_Interrupt_table[16]; +SHM_EXTERN Shm_Node_status_control *Shm_Node_statuses; +SHM_EXTERN Shm_Locked_queue_Control *Shm_Locked_queues; +SHM_EXTERN Shm_Envelope_control *Shm_Envelopes; +SHM_EXTERN rtems_configuration_table *Shm_RTEMS_Configuration; +SHM_EXTERN rtems_multiprocessing_table *Shm_RTEMS_MP_Configuration; +SHM_EXTERN rtems_unsigned32 Shm_Receive_message_count; +SHM_EXTERN rtems_unsigned32 Shm_Null_message_count; +SHM_EXTERN rtems_unsigned32 Shm_Interrupt_count; +SHM_EXTERN rtems_unsigned32 Shm_Local_node; +SHM_EXTERN Shm_Locked_queue_Control *Shm_Local_receive_queue; +SHM_EXTERN Shm_Node_status_control *Shm_Local_node_status; +SHM_EXTERN rtems_unsigned32 Shm_isrstat; + /* reported by shmdr */ + +SHM_EXTERN rtems_unsigned32 Shm_Pending_initialization; +SHM_EXTERN rtems_unsigned32 Shm_Initialization_complete; +SHM_EXTERN rtems_unsigned32 Shm_Active_node; + +SHM_EXTERN rtems_unsigned32 Shm_Maximum_nodes; +SHM_EXTERN rtems_unsigned32 Shm_Maximum_envelopes; + +SHM_EXTERN rtems_unsigned32 Shm_Locked_queue_End_of_list; +SHM_EXTERN rtems_unsigned32 Shm_Locked_queue_Not_on_list; + +/* functions */ + +/* locked queue routines */ +void Shm_Locked_queue_Add( + Shm_Locked_queue_Control *, Shm_Envelope_control * ); +Shm_Envelope_control *Shm_Locked_queue_Get( Shm_Locked_queue_Control * ); +void Shm_Locked_queue_Initialize( + Shm_Locked_queue_Control *, rtems_unsigned32 ); + /* Shm_Initialize_lock is CPU dependent */ + /* Shm_Lock is CPU dependent */ + /* Shm_Unlock is CPU dependent */ + +/* portable routines */ +void Init_env_pool(); +void Shm_Print_statistics( void ); +void MPCI_Fatal( rtems_unsigned32 ); +rtems_task Shm_Cause_interrupt( rtems_unsigned32 ); +void Shm_Poll(); +void Shm_setclockvec(); +void Shm_Convert_packet( rtems_packet_prefix * ); + +/* CPU specific routines are inlined in shmcpu.h */ + +/* target specific routines */ +void *Shm_Convert_address( void * ); +void Shm_Get_configuration( rtems_unsigned32, shm_config_table ** ); +void Shm_isr(); +void Shm_setvec( void ); + +void Shm_Initialize_lock( Shm_Locked_queue_Control * ); +void Shm_Lock( Shm_Locked_queue_Control * ); +void Shm_Unlock( Shm_Locked_queue_Control * ); + +/* MPCI entry points */ +rtems_mpci_entry Shm_Get_packet( + rtems_packet_prefix ** +); + +rtems_mpci_entry Shm_Initialization( + rtems_configuration_table *configuration, + rtems_cpu_table *cpu_configuration, + rtems_multiprocessing_table *mp_configuration +); + +rtems_mpci_entry Shm_Receive_packet( + rtems_packet_prefix ** +); + +rtems_mpci_entry Shm_Return_packet( + rtems_packet_prefix * +); + +rtems_mpci_entry Shm_Send_packet( + rtems_unsigned32, + rtems_packet_prefix * +); + +#ifdef _SHM_INIT + +/* multiprocessor communications interface (MPCI) table */ + +rtems_mpci_table MPCI_table = { + 100000, /* default timeout value in ticks */ + Shm_Initialization, /* initialization procedure */ + Shm_Get_packet, /* get packet procedure */ + Shm_Return_packet, /* return packet procedure */ + Shm_Send_packet, /* packet send procedure */ + Shm_Receive_packet /* packet receive procedure */ +}; + +#else + +extern rtems_mpci_table MPCI_table; + +#endif + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/c/src/lib/libc/README b/c/src/lib/libc/README new file mode 100644 index 0000000000..ee7a90501e --- /dev/null +++ b/c/src/lib/libc/README @@ -0,0 +1,37 @@ +-- +-- $Id$ +-- + +Overview of newlib support (newlib is from CYGNUS) + Each task can have its own libc state including: + open stdio files + strtok + multi precision arithmetic state + etc. + + This is implemented by a reentrancy data structure for each task. + + When a task is "started" (in RTEMS sense) the reentrancy structure + is allocated. Its address is stored in notepad[NOTEPAD_LAST]. + + When task is switched to, the value of global variable _impure_ptr + is changed to the value of the new tasks reentrancy structure. + + When a task is deleted + atexit() processing (for that task) happens + task's stdio buffers are flushed + + When exit(3) is called + calling task's atexit processing done + global libc state atexit processing done + (this will include any atexit routines installed by drivers) + executive is shutdown + causes a context switch back to bsp land + + +NOTE: + libc extension are installed by bsp_libc_init() + iff we are using clock interrupts. + This hack is necessary to allow the tmtests to avoid + timing the extensions. + diff --git a/c/src/lib/libc/__brk.c b/c/src/lib/libc/__brk.c new file mode 100644 index 0000000000..6fb15342fe --- /dev/null +++ b/c/src/lib/libc/__brk.c @@ -0,0 +1,40 @@ +/* + * RTEMS "Broken" __brk/__sbrk Implementation + * + * NOTE: sbrk is BSP provided. + * + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include + +#include +#include +#include +#ifdef RTEMS_NEWLIB +#include +#endif +#include + +/* we use RTEMS for memory management. We don't need sbrk */ + +void * __sbrk(int incr) +{ + errno = EINVAL; + return (void *)0; +} + +int __brk( const void *endds ) +{ + errno = EINVAL; + return -1; +} diff --git a/c/src/lib/libc/__gettod.c b/c/src/lib/libc/__gettod.c new file mode 100644 index 0000000000..a1ab9776c8 --- /dev/null +++ b/c/src/lib/libc/__gettod.c @@ -0,0 +1,84 @@ +#if !defined(RTEMS_UNIX) +/* + * RTEMS gettimeofday Implementation + * + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include + +#ifdef RTEMS_NEWLIB +#include +#endif +#include +#include +#include +#include + +/* + * NOTE: The solaris gettimeofday does not have a second parameter. + */ + +int gettimeofday( + struct timeval *tp, + struct timezone *tzp +) +{ + rtems_status_code status; + rtems_clock_time_value time; + + if ( !tp || !tzp ) { + errno = EFAULT; + return -1; + } + + /* "POSIX" does not seem to allow for not having a TOD */ + status = rtems_clock_get( RTEMS_CLOCK_GET_TIME_VALUE, &time ); + if ( status != RTEMS_SUCCESSFUL ) { + assert( 0 ); + return -1; + } + + tp->tv_sec = time.seconds; + tp->tv_usec = time.microseconds; + +#if 0 + tzp->minuteswest = timezone / 60; /* from seconds to minutes */ + tzp->dsttime = daylight; +#endif + + /* + * newlib does not have timezone and daylight savings time + * yet. When it does this needs to be fixed. + */ + + tzp->tz_minuteswest = 0; /* at UTC */ + tzp->tz_dsttime = 0; /* no daylight savings */ + return 0; +} + +/* + * "Reentrant" versions of the above routines implemented above. + */ + +#if 0 +int _gettimeofday_r( + struct _reent *ignored_reentrancy_stuff, + struct timeval *tp, + struct timezone *tzp +) +{ + return gettimeofday( tp, tzp ); +} +#endif + +#endif diff --git a/c/src/lib/libc/__times.c b/c/src/lib/libc/__times.c new file mode 100644 index 0000000000..12fd9241fe --- /dev/null +++ b/c/src/lib/libc/__times.c @@ -0,0 +1,65 @@ +/* + * RTEMS _times Implementation + * + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include + +#include +#include +#include +#include +#include + +clock_t _times( + struct tms *ptms +) +{ + rtems_status_code status; + rtems_interval ticks_since_boot; + + if ( !ptms ) { + errno = EFAULT; + return -1; + } + + /* "POSIX" does not seem to allow for not having a TOD */ + status = rtems_clock_get( + RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, + &ticks_since_boot + ); + if ( status != RTEMS_SUCCESSFUL ) { + assert( 0 ); + return -1; + } + + /* + * RTEMS has no notion of system versus user time and does + * not (as of 3.2.0) keep track of CPU usage on a per task basis. + */ + + ptms->tms_utime = ticks_since_boot; + ptms->tms_stime = 0; + ptms->tms_cutime = 0; + ptms->tms_cstime = 0; + + return 0; +} + +clock_t times( + struct tms *ptms +) +{ + return _times( ptms ); +} + diff --git a/c/src/lib/libc/internal.h b/c/src/lib/libc/internal.h new file mode 100644 index 0000000000..8ca6c8ed48 --- /dev/null +++ b/c/src/lib/libc/internal.h @@ -0,0 +1,41 @@ +/* internal.h + * + * This include file contains internal information + * for the RTEMS C library support which is needed across + * files. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __INTERNAL_LIBC_h +#define __INTERNAL_LIBC_h + +#ifdef __cplusplus +extern "C" { +#endif + +void MY_task_set_note( + rtems_tcb *tcb, + rtems_unsigned32 notepad, + rtems_unsigned32 note +); + +rtems_unsigned32 MY_task_get_note( + rtems_tcb *tcb, + rtems_unsigned32 notepad +); + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/c/src/lib/libc/libcsupport.h b/c/src/lib/libc/libcsupport.h new file mode 100644 index 0000000000..2b199707f8 --- /dev/null +++ b/c/src/lib/libc/libcsupport.h @@ -0,0 +1,47 @@ +/* libcsupport.h + * + * This include file contains the information regarding the + * RTEMS specific support for the standard C library. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __LIBC_SUPPORT_h +#define __LIBC_SUPPORT_h + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +void RTEMS_Malloc_Initialize( + void *start, + size_t length, + size_t sbrk_amount +); + +extern void libc_init(int reentrant); + +#ifdef __cplusplus +} +#endif + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/c/src/lib/libc/malloc.c b/c/src/lib/libc/malloc.c new file mode 100644 index 0000000000..7d0ba04143 --- /dev/null +++ b/c/src/lib/libc/malloc.c @@ -0,0 +1,280 @@ +/* + * RTEMS Malloc Family Implementation + * + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#ifdef RTEMS_LIBC +#include +#endif +#include "libcsupport.h" +#ifdef RTEMS_NEWLIB +#include +#endif + +#include +#include +#include +#include +#include +#include + +/* + * XXX: Do we really need to duplicate these? It appears that they + * only cause typing problems. + */ + +#if 0 +void *malloc(size_t); +void *calloc(size_t, size_t); +void *realloc(void *, size_t); +void free(void *); +void *sbrk(size_t); +#endif + +rtems_id RTEMS_Malloc_Heap; +size_t RTEMS_Malloc_Sbrk_amount; + +void RTEMS_Malloc_Initialize( + void *start, + size_t length, + size_t sbrk_amount +) +{ + rtems_status_code status; + void *starting_address; + rtems_unsigned32 u32_address; + + /* + * If the starting address is 0 then we are to attempt to + * get length worth of memory using sbrk. Make sure we + * align the address that we get back. + */ + + starting_address = start; + + if (!starting_address) { + u32_address = (unsigned int)sbrk(length); + + if (u32_address == -1) { + rtems_fatal_error_occurred( RTEMS_NO_MEMORY ); + /* DOES NOT RETURN!!! */ + } + + if (u32_address & (CPU_ALIGNMENT-1)) { + u32_address = (u32_address + CPU_ALIGNMENT) & ~(CPU_ALIGNMENT-1); + /* XXX: if we do any alignment .. then length should be shortened */ + } + + starting_address = (void *)u32_address; + } + + /* + * Unfortunately we cannot use assert if this fails because if this + * has failed we do not have a heap and if we do not have a heap + * STDIO cannot work because there will be no buffers. + */ + + status = rtems_region_create( + rtems_build_name( 'H', 'E', 'A', 'P' ), + starting_address, + length, + 8, /* XXX : use CPU dependent RTEMS constant */ + RTEMS_DEFAULT_ATTRIBUTES, + &RTEMS_Malloc_Heap + ); + if ( status != RTEMS_SUCCESSFUL ) + rtems_fatal_error_occurred( status ); +} + +void *malloc( + size_t size +) +{ + void *return_this; + void *starting_address; + rtems_unsigned32 the_size; + rtems_unsigned32 sbrk_amount; + rtems_status_code status; + + if ( !size ) + return (void *) 0; + + /* + * Try to give a segment in the current region if there is not + * enough space then try to grow the region using rtems_region_extend(). + * If this fails then return a NULL pointer. + */ + + status = rtems_region_get_segment( + RTEMS_Malloc_Heap, + size, + RTEMS_NO_WAIT, + RTEMS_NO_TIMEOUT, + &return_this + ); + + if ( status != RTEMS_SUCCESSFUL ) { + /* + * Round to the "requested sbrk amount" so hopefully we won't have + * to grow again for a while. This effectively does sbrk() calls + * in "page" amounts. + */ + + sbrk_amount = RTEMS_Malloc_Sbrk_amount; + + if ( sbrk_amount == 0 ) + return (void *) 0; + + the_size = ((size + sbrk_amount) / sbrk_amount * sbrk_amount); + + if (((rtems_unsigned32)starting_address = sbrk(the_size)) == -1) + return (void *) 0; + + /* + fprintf(stderr, "Extended the C heap starting at 0x%x for %d bytes\n", + (unsigned32)starting_address, the_size); + */ + + status = rtems_region_extend( + RTEMS_Malloc_Heap, + starting_address, + the_size + ); + if ( status != RTEMS_SUCCESSFUL ) { + sbrk(-the_size); + return(FALSE); + errno = ENOMEM; + return (void *) 0; + } + status = rtems_region_get_segment( + RTEMS_Malloc_Heap, + size, + RTEMS_NO_WAIT, + RTEMS_NO_TIMEOUT, + &return_this + ); + if ( status != RTEMS_SUCCESSFUL ) { + errno = ENOMEM; + return (void *) 0; + } + } + + return return_this; +} + +void *calloc( + size_t nelem, + size_t elsize +) +{ + register char *cptr; + int length; + + length = nelem * elsize; + cptr = malloc( length ); + if ( cptr ) + memset( cptr, '\0', length ); + + return cptr; +} + +void *realloc( + void *ptr, + size_t size +) +{ + rtems_unsigned32 old_size; + rtems_status_code status; + char *new_area; + + if ( !ptr ) + return malloc( size ); + + if ( !size ) { + free( ptr ); + return (void *) 0; + } + + status = rtems_region_get_segment_size( RTEMS_Malloc_Heap, ptr, &old_size ); + if ( status != RTEMS_SUCCESSFUL ) { + errno = EINVAL; + return (void *) 0; + } + + new_area = malloc( size ); + if ( !new_area ) { + free( ptr ); + return (void *) 0; + } + + memcpy( new_area, ptr, (size < old_size) ? size : old_size ); + free( ptr ); + + return new_area; + +} + +void free( + void *ptr +) +{ + rtems_status_code status; + + if ( !ptr ) + return; + + status = rtems_region_return_segment( RTEMS_Malloc_Heap, ptr ); + if ( status != RTEMS_SUCCESSFUL ) { + errno = EINVAL; + assert( 0 ); + } +} + +/* + * "Reentrant" versions of the above routines implemented above. + */ + +#ifdef RTEMS_NEWLIB +void *malloc_r( + struct _reent *ignored, + size_t size +) +{ + return malloc( size ); +} + +void *calloc_r( + size_t nelem, + size_t elsize +) +{ + return calloc( nelem, elsize ); +} + +void *realloc_r( + void *ptr, + size_t size +) +{ + return realloc_r( ptr, size ); +} + +void free_r( + void *ptr +) +{ + free( ptr ); +} +#endif + diff --git a/c/src/lib/libc/newlibc.c b/c/src/lib/libc/newlibc.c new file mode 100644 index 0000000000..3c5e58b67c --- /dev/null +++ b/c/src/lib/libc/newlibc.c @@ -0,0 +1,292 @@ +/* + * @(#)newlibc.c 1.8 - 95/04/25 + * + */ + +#if defined(RTEMS_NEWLIB) + +/* + * File: $RCSfile$ + * Project: PixelFlow + * Created: 94/12/7 + * Revision: $Revision$ + * Last Mod: $Date$ + * + * COPYRIGHT (c) 1994 by Division Incorporated + * + * To anyone who acknowledges that this file is provided "AS IS" + * without any express or implied warranty: + * permission to use, copy, modify, and distribute this file + * for any purpose is hereby granted without fee, provided that + * the above copyright notice and this notice appears in all + * copies, and that the name of Division Incorporated not be + * used in advertising or publicity pertaining to distribution + * of the software without specific, written prior permission. + * Division Incorporated makes no representations about the + * suitability of this software for any purpose. + * + * Description: + * Implementation of hooks for the CYGNUS newlib libc + * These hooks set things up so that: + * '_REENT' is switched at task switch time. + * + * + * TODO: + * + * NOTE: + * + * $Id$ + * + */ + +#include +#include +#include /* for free() */ +#include /* for memset() */ + +#include /* for extern of _REENT (aka _impure_ptr) */ + +#include "internal.h" + +#define LIBC_NOTEPAD RTEMS_NOTEPAD_LAST + + +int libc_reentrant; /* do we think we are reentrant? */ +struct _reent libc_global_reent = _REENT_INIT(libc_global_reent);; + +/* + * CYGNUS newlib routine that does atexit() processing and flushes + * stdio streams + * undocumented + */ + +extern void _wrapup_reent(struct _reent *); +extern void _reclaim_reent(struct _reent *); + +void +libc_wrapup(void) +{ + _wrapup_reent(0); + if (_REENT != &libc_global_reent) + { + _wrapup_reent(&libc_global_reent); +#if 0 + /* don't reclaim this one, just in case we do printfs */ + /* on our way out to ROM */ + _reclaim_reent(&libc_global_reent); +#endif + _REENT = &libc_global_reent; + } +} + + +rtems_extension +libc_create_hook(rtems_tcb *current_task, + rtems_tcb *creating_task) +{ + MY_task_set_note(creating_task, LIBC_NOTEPAD, 0); +} + +/* + * Called for all user TASKS (system tasks are SYSI and IDLE) + */ + +rtems_extension +libc_start_hook(rtems_tcb *current_task, + rtems_tcb *starting_task) +{ + struct _reent *ptr; + + /* NOTE: our malloc is reentrant without a reent ptr since + * it is based on region manager + */ + + ptr = (struct _reent *) malloc(sizeof(struct _reent)); + + /* GCC extension: structure constants */ + *ptr = (struct _reent) _REENT_INIT((*ptr)); + + MY_task_set_note(starting_task, LIBC_NOTEPAD, (rtems_unsigned32) ptr); +} + +rtems_extension +libc_switch_hook(rtems_tcb *current_task, + rtems_tcb *heir_task) +{ + rtems_unsigned32 impure_value; + + /* XXX We can't use rtems_task_set_note() here since SYSI task has a + * tid of 0, which is treated specially (optimized, actually) + * by rtems_task_set_note + */ + + impure_value = (rtems_unsigned32) _REENT; + MY_task_set_note(current_task, LIBC_NOTEPAD, impure_value); + + _REENT = (struct _reent *) MY_task_get_note(heir_task, LIBC_NOTEPAD); + +} + +/* + * Function: libc_delete_hook + * Created: 94/12/10 + * + * Description: + * Called when a task is deleted. + * Must restore the new lib reentrancy state for the new current + * task. + * + * Parameters: + * + * + * Returns: + * + * + * Side Effects: + * + * Notes: + * + * + * Deficiencies/ToDo: + * + * + */ +rtems_extension +libc_delete_hook(rtems_tcb *current_task, + rtems_tcb *deleted_task) +{ + struct _reent *ptr; + + /* + * The reentrancy structure was allocated by newlib using malloc() + */ + + if (current_task == deleted_task) + { + ptr = _REENT; + } + else + { + ptr = (struct _reent *) MY_task_get_note(deleted_task, LIBC_NOTEPAD); + } + + if (ptr) + { + _wrapup_reent(ptr); + _reclaim_reent(ptr); + } + + MY_task_set_note(deleted_task, LIBC_NOTEPAD, 0); + + /* + * Require the switch back to another task to install its own + */ + + if (current_task == deleted_task) + { + _REENT = 0; + } +} + +/* + * Function: libc_init + * Created: 94/12/10 + * + * Description: + * Init libc for CYGNUS newlib + * Set up _REENT to use our global libc_global_reent. + * (newlib provides a global of its own, but we prefer our + * own name for it) + * + * If reentrancy is desired (which it should be), then + * we install the task extension hooks to maintain the + * newlib reentrancy global variable _REENT on task + * create, delete, switch, exit, etc. + * + * Parameters: + * reentrant non-zero if reentrant library desired. + * + * Returns: + * + * Side Effects: + * installs libc extensions if reentrant. + * + * Notes: + * + * + * Deficiencies/ToDo: + * + */ + +void +libc_init(int reentrant) +{ + rtems_extensions_table libc_extension; + rtems_id extension_id; + rtems_status_code rc; + + _REENT = &libc_global_reent; + + if (reentrant) + { + memset(&libc_extension, 0, sizeof(libc_extension)); + + libc_extension.rtems_task_create = libc_create_hook; + libc_extension.rtems_task_start = libc_start_hook; + libc_extension.task_switch = libc_switch_hook; + libc_extension.rtems_task_delete = libc_delete_hook; + + rc = rtems_extension_create(rtems_build_name('L', 'I', 'B', 'C'), + &libc_extension, &extension_id); + if (rc != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred(rc); + + libc_reentrant = reentrant; + } +} + + +void +exit(int status) +{ + libc_wrapup(); + rtems_shutdown_executive(status); +} + + +/* + * Function: _exit + * Created: 94/12/10 + * + * Description: + * Called from exit() after it does atexit() processing and stdio fflush's + * + * called from bottom of exit() to really delete the task. + * If we are using reentrant libc, then let the delete extension + * do all the work, otherwise if a shutdown is in progress, + * then just do it. + * + * Parameters: + * exit status + * + * Returns: + * does not return + * + * Side Effects: + * + * Notes: + * + * + * Deficiencies/ToDo: + * + * + */ + +#ifndef RTEMS_UNIX +void _exit(int status) +{ + rtems_shutdown_executive(status); +} +#endif + +#endif diff --git a/c/src/lib/libc/no_libc.c b/c/src/lib/libc/no_libc.c new file mode 100644 index 0000000000..43a91eb30e --- /dev/null +++ b/c/src/lib/libc/no_libc.c @@ -0,0 +1,45 @@ +#if !defined(RTEMS_LIBC) && !defined(RTEMS_NEWLIB) && !defined(RTEMS_UNIX) + +/* no_libc.h + * + * This file contains stubs for the reentrancy hooks when + * an unknown C library is used. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + + +#include + +#include "libcsupport.h" +#include "internal.h" + +#include /* for free() */ + +void +libc_init(int reentrant) +{ +} + +void libc_suspend_main(void) +{ +} + + +void libc_global_exit(rtems_unsigned32 code) +{ +} + +void _exit(int status) +{ +} + +#endif diff --git a/c/src/lib/libc/support.c b/c/src/lib/libc/support.c new file mode 100644 index 0000000000..ac7b06963d --- /dev/null +++ b/c/src/lib/libc/support.c @@ -0,0 +1,44 @@ +/* + * Routines to Access Internal RTEMS Resources + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + * + */ + +#include +#include + +void MY_task_set_note( + Thread_Control *the_thread, + unsigned32 notepad, + unsigned32 note +) +{ + the_thread->Notepads[ notepad ] = note; +} + + +unsigned32 MY_task_get_note( + Thread_Control *the_thread, + unsigned32 notepad +) +{ + return the_thread->Notepads[ notepad ]; +} + +void *MY_CPU_Context_FP_start( + void *base, + unsigned32 offset +) +{ + return _CPU_Context_Fp_start( base, offset ); +} + diff --git a/c/src/lib/libc/syscalls.c b/c/src/lib/libc/syscalls.c new file mode 100644 index 0000000000..41eedb40d0 --- /dev/null +++ b/c/src/lib/libc/syscalls.c @@ -0,0 +1,77 @@ +#if !defined(RTEMS_UNIX) + +/* + * RTEMS Fake System Calls + * + * This file contains "fake" versions of the system call routines + * which are reference by many libc implementations. Once a routine + * has been implemented in terms of RTEMS services, it should be + * taken out of this file. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + * + */ + +#include +#include + +int +__fstat(int _fd, struct stat* _sbuf) +{ + return -1; +} + +int +__isatty(int _fd) +{ + return 1; +} + +int +__close(int _fd) +{ + /* return value usually ignored anyhow */ + return 0; +} + +int +__open(const char *filename) +{ + /* always fail */ + return -1; +} + +int +__lseek(int _fd, off_t offset, int whence) +{ + /* nothing is ever seekable */ + return -1; +} + +int stat( const char *path, struct stat *buf ) +{ + /* always fail */ + return -1; +} + +int link( const char *existing, const char *new ) +{ + /* always fail */ + return -1; +} + +int unlink( const char *path ) +{ + /* always fail */ + return -1; +} + +#endif diff --git a/c/src/lib/libc/unixlibc.c b/c/src/lib/libc/unixlibc.c new file mode 100644 index 0000000000..74b4eea360 --- /dev/null +++ b/c/src/lib/libc/unixlibc.c @@ -0,0 +1,7 @@ +#if defined(RTEMS_UNIXLIB) + +void libc_init(int reentrant) +{ +} + +#endif diff --git a/c/src/lib/libcpu/README b/c/src/lib/libcpu/README new file mode 100644 index 0000000000..e7e293660c --- /dev/null +++ b/c/src/lib/libcpu/README @@ -0,0 +1,14 @@ +# +# $Id$ +# + +This is the README file for libcpu. + +This directory contains reusable libraries which are CPU dependent but not +target board dependent. For example, the HPPA has an on chip interval timer +which may be used by all HPPA bsp's. + +Another example might be the Intel i960CA has on-chip DMA which could be +supported in a library and placed in lib/libcpu/i960. This level of support +will make it easier for others developing embedded applications on a given +CPU. diff --git a/c/src/lib/libcpu/hppa1.1/clock/clock.c b/c/src/lib/libcpu/hppa1.1/clock/clock.c new file mode 100644 index 0000000000..62bb8e2826 --- /dev/null +++ b/c/src/lib/libcpu/hppa1.1/clock/clock.c @@ -0,0 +1,220 @@ +/* Clock + * + * This routine initializes the interval timer on the + * PA-RISC CPU. The tick frequency is specified by the bsp. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include +#include + +#include /* for atexit() */ + +extern rtems_cpu_table Cpu_table; /* owned by BSP */ + +typedef unsigned long long hppa_click_count_t; + +/* + * CPU_HPPA_CLICKS_PER_TICK is either a #define or an rtems_unsigned32 + * allocated and set by bsp_start() + */ + +#ifndef CPU_HPPA_CLICKS_PER_TICK +extern rtems_unsigned32 CPU_HPPA_CLICKS_PER_TICK; +#endif + +volatile rtems_unsigned32 Clock_driver_ticks; +rtems_unsigned32 Clock_isrs; /* ISRs until next tick */ + +rtems_unsigned32 most_recent_itimer_value; + +rtems_unsigned64 Clock_clicks; /* running total of cycles */ + +rtems_unsigned32 Clock_clicks_interrupt; + +rtems_device_driver Clock_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *pargp, + rtems_id tid, + rtems_unsigned32 *rval +) +{ + Install_clock(Clock_isr); +} + +void +ReInstall_clock(rtems_isr_entry new_clock_isr) +{ + rtems_unsigned32 isrlevel = 0; + + rtems_interrupt_disable(isrlevel); + (void) set_vector( + new_clock_isr, + HPPA_INTERRUPT_EXTERNAL_INTERVAL_TIMER, + 1 + ); + rtems_interrupt_enable(isrlevel); +} + +/* + * read itimer and update Clock_clicks as appropriate + */ + +rtems_unsigned32 +Clock_read_itimer() +{ + rtems_unsigned32 isrlevel; + rtems_unsigned32 itimer_value; + rtems_unsigned32 wrap_count; + rtems_unsigned32 recent_count; + + rtems_interrupt_disable(isrlevel); + + wrap_count = (Clock_clicks & 0xFFFFFFFF00000000ULL) >> 32; + recent_count = (rtems_unsigned32) Clock_clicks; + + itimer_value = get_itimer(); + + if (itimer_value < recent_count) + wrap_count++; + Clock_clicks = (((rtems_unsigned64) wrap_count) << 32) + itimer_value; + + rtems_interrupt_enable(isrlevel); + + return itimer_value; +} + + +void Install_clock(rtems_isr_entry clock_isr) +{ + Clock_driver_ticks = 0; + Clock_clicks_interrupt = 0; + Clock_clicks = 0; + + Clock_isrs = BSP_Configuration.microseconds_per_tick / 1000; + + if (BSP_Configuration.ticks_per_timeslice) + { + /* + * initialize the interval here + * First tick is set to right amount of time in the future + * Future ticks will be incremented over last value set + * in order to provide consistent clicks in the face of + * interrupt overhead + */ + + Clock_clicks_interrupt = Clock_read_itimer() + CPU_HPPA_CLICKS_PER_TICK; + set_itimer((rtems_unsigned32) Clock_clicks_interrupt); + + (void) set_vector(clock_isr, HPPA_INTERRUPT_EXTERNAL_INTERVAL_TIMER, 1); + } + atexit(Clock_exit); +} + +rtems_isr +Clock_isr(rtems_vector_number vector) +{ + rtems_unsigned32 clicks_til_next_interrupt; + rtems_unsigned32 itimer_value; + + /* + * setup for next interrupt; making sure the new value is reasonably + * in the future.... in case we lost out on an interrupt somehow + */ + + itimer_value = Clock_read_itimer(); + Clock_clicks_interrupt += CPU_HPPA_CLICKS_PER_TICK; + + /* + * how far away is next interrupt *really* + * It may be a long time; this subtraction works even if + * Clock_clicks_interrupt < Clock_clicks_low_order via + * the miracle of unsigned math. + */ + clicks_til_next_interrupt = Clock_clicks_interrupt - itimer_value; + + /* + * If it is too soon then bump it up. + * This should only happen if CPU_HPPA_CLICKS_PER_TICK is too small. + * But setting it low is useful for debug, so... + */ + + if (clicks_til_next_interrupt < 400) + { + Clock_clicks_interrupt = itimer_value + 1000; + /* XXX: count these! this should be rare */ + } + + /* + * If it is too late, that means we missed the interrupt somehow. + * Rather than wait 35-50s for a wrap, we just fudge it here. + */ + + if (clicks_til_next_interrupt > CPU_HPPA_CLICKS_PER_TICK) + { + Clock_clicks_interrupt = itimer_value + 1000; + /* XXX: count these! this should never happen :-) */ + } + + set_itimer((rtems_unsigned32) Clock_clicks_interrupt); + + Clock_driver_ticks++; + + if (Clock_isrs == 1) + { + rtems_clock_tick(); + Clock_isrs = BSP_Configuration.microseconds_per_tick / 10000; + if (Clock_isrs == 0) + Clock_isrs = 1; + } + else + Clock_isrs--; +} + +/* + * Called via atexit() + * Remove the clock interrupt handler by setting handler to NULL + */ + +void +Clock_exit(void) +{ + if ( BSP_Configuration.ticks_per_timeslice ) + { + (void) set_vector(0, HPPA_INTERRUPT_EXTERNAL_INTERVAL_TIMER, 1); + } +} + +/* + * spin delay for specified number of microseconds + * used by RTEMS delay macro + */ + +void +Clock_delay(rtems_unsigned32 microseconds) +{ + rtems_unsigned64 future_time; + + (void) Clock_read_itimer(); + future_time = Clock_clicks + + ((rtems_unsigned64) microseconds) * + Cpu_table.itimer_clicks_per_microsecond; + + for (;;) + { + (void) Clock_read_itimer(); + if (future_time <= Clock_clicks) + break; + } +} + diff --git a/c/src/lib/libcpu/hppa1.1/runway/runway.h b/c/src/lib/libcpu/hppa1.1/runway/runway.h new file mode 100644 index 0000000000..41aafe26ef --- /dev/null +++ b/c/src/lib/libcpu/hppa1.1/runway/runway.h @@ -0,0 +1,37 @@ +/* + * File: $RCSfile$ + * Project: PixelFlow + * Created: 94/11/29 + * RespEngr: tony bennett + * Revision: $Revision$ + * Last Mod: $Date$ + * + * Description: + * definitions specific to the runway bus + * + * TODO: + * Add lots more. + * + * $Id$ + */ + +#ifndef _INCLUDE_RUNWAY_H +#define _INCLUDE_RUNWAY_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define HPPA_RUNWAY_PROC_HPA_BASE ((void *) 0xFFFA0000) + +/* given a processor number, where is its HPA? */ +#define HPPA_RUNWAY_HPA(cpu) \ + ((rtems_unsigned32) (HPPA_RUNWAY_PROC_HPA_BASE + ((cpu) * 0x2000))) + +#define HPPA_RUNWAY_REG_IO_EIR_OFFSET 0x000 + +#ifdef __cplusplus +} +#endif + +#endif /* ! _INCLUDE_RUNWAY_H */ diff --git a/c/src/lib/libcpu/hppa1.1/semaphore/semaphore.c b/c/src/lib/libcpu/hppa1.1/semaphore/semaphore.c new file mode 100644 index 0000000000..aa8b768b3a --- /dev/null +++ b/c/src/lib/libcpu/hppa1.1/semaphore/semaphore.c @@ -0,0 +1,308 @@ +/* + * File: $RCSfile$ + * Project: PixelFlow + * Created: 94/11/29 + * RespEngr: tony bennett + * Revision: $Revision$ + * Last Mod: $Date$ + * + * COPYRIGHT (c) 1994 by Division Incorporated + * + * To anyone who acknowledges that this file is provided "AS IS" + * without any express or implied warranty: + * permission to use, copy, modify, and distribute this file + * for any purpose is hereby granted without fee, provided that + * the above copyright notice and this notice appears in all + * copies, and that the name of Division Incorporated not be + * used in advertising or publicity pertaining to distribution + * of the software without specific, written prior permission. + * Division Incorporated makes no representations about the + * suitability of this software for any purpose. + * + * Description: + * HPPA fast spinlock semaphores based on LDCWX instruction. + * These semaphores are not known to RTEMS. + * + * TODO: + * Put node number in high 16 bits of flag?? + * XXX: Need h_s_deallocate + * + * $Id$ + */ + +#include + +#include "semaphore.h" + +/* + * Report fatal semaphore error + */ + +#define SEM_FATAL_ERROR(sp) rtems_fatal_error_occurred((rtems_unsigned32) sp) + +#define SEM_CHECK(sp) do { \ + if (((sp) == 0) || (int) (sp) & 0xf) \ + { \ + SEM_FATAL_ERROR(sp); \ + } \ + } while (0) + +/* + * Init a semaphore to be free + */ + +#define SEM_FREE_INIT(sp) \ + do { \ + (sp)->lock = 1; \ + (sp)->flags = 0; \ + (sp)->owner_tcb = 0; \ + } while (0) + +/* + * Grab a semaphore recording its owner. + */ + +#define SEM_MARK_GRABBED(sp) \ + do { \ + (sp)->owner_tcb = _Thread_Executing; \ + } while (0) + +/* + * Mark the semaphore busy + */ + +#define SEM_MARK_BUSY(sp) ((sp)->flags |= HPPA_SEM_IN_USE) + +/* + * Is a semaphore available? + */ + +#define SEM_IS_AVAILABLE(sp) ((sp)->owner_tcb == 0) + +/* + * The pool control semaphore is the first in the pool + */ + +#define SEM_CONTROL (&hppa_semaphore_pool[0]) +#define SEM_FIRST (&hppa_semaphore_pool[1]) + +#define SEM_PRIVATE(cookie) rtems_interrupt_disable(cookie) + +#define SEM_PUBLIC(cookie) rtems_interrupt_enable(cookie) + + +/* + * Control variables for the pool + */ + +hppa_semaphore_t *hppa_semaphore_pool; /* ptr to first */ +int hppa_semaphores; +int hppa_semaphores_available; + +void +hppa_semaphore_pool_initialize(void *pool_base, + int pool_size) +{ + hppa_semaphore_t *sp; + int align_factor; + rtems_unsigned32 isr_level; + + /* + * round pool_base up to be a multiple of SEM_ALIGN + */ + + align_factor = SEM_ALIGN - (((int) pool_base) & (SEM_ALIGN-1)); + if (align_factor != SEM_ALIGN) + { + pool_base += align_factor; + pool_size -= align_factor; + } + + /* + * How many can the pool hold? + * Assumes the semaphores are SEM_ALIGN bytes each + */ + + if (sizeof(hppa_semaphore_t) != SEM_ALIGN) + rtems_fatal_error_occurred(RTEMS_INVALID_SIZE); + + pool_size &= ~(SEM_ALIGN - 1); + + SEM_PRIVATE(isr_level); + + hppa_semaphore_pool = pool_base; + hppa_semaphores = pool_size / SEM_ALIGN; + + /* + * If we are node0, then init all in the pool + */ + + if (cpu_number == 0) + { + /* + * Tell other cpus we are not done, jic + */ + SEM_CONTROL->user = rtems_build_name('!', 'D', 'N', 'E'); + + for (sp=SEM_FIRST; sp < &hppa_semaphore_pool[hppa_semaphores]; sp++) + SEM_FREE_INIT(sp); + SEM_FREE_INIT(SEM_CONTROL); + } + + /* + * Tell other cpus we are done, or wait for it to be done if on another cpu + */ + + if (cpu_number == 0) + SEM_CONTROL->user = rtems_build_name('D', 'O', 'N', 'E'); + else + while (SEM_CONTROL->user != rtems_build_name('D', 'O', 'N', 'E')) + ; + + hppa_semaphores_available = hppa_semaphores; + + SEM_PUBLIC(isr_level); +} + +/* + * Function: hppa_semaphore_acquire + * Created: 94/11/29 + * RespEngr: tony bennett + * + * Description: + * Acquire a semaphore. Will spin on the semaphore unless + * 'flag' says not to. + * + * Parameters: + * + * + * Returns: + * 0 -- if did not acquire + * non-zero -- if acquired semaphore + * (actually this is the spin count) + * + * Notes: + * There is no requirement that the semaphore be within the pool + * + * Deficiencies/ToDo: + * + */ + + +rtems_unsigned32 +hppa_semaphore_acquire(hppa_semaphore_t *sp, + int flag) +{ + rtems_unsigned32 lock_value; + rtems_unsigned32 spin_count = 1; + + SEM_CHECK(sp); + + for (;;) + { + HPPA_ASM_LDCWS(0, 0, sp, lock_value); + + if (lock_value) /* we now own the lock */ + { + SEM_MARK_GRABBED(sp); + return spin_count ? spin_count : ~0; /* jic */ + } + + if (flag & HPPA_SEM_NO_SPIN) + return 0; + + spin_count++; + } +} + +void +hppa_semaphore_release(hppa_semaphore_t *sp) +{ + SEM_CHECK(sp); + + if (sp->owner_tcb != _Thread_Executing) + SEM_FATAL_ERROR("owner mismatch"); + + sp->lock = 1; +} + + +/* + * Function: hppa_semaphore_allocate + * Created: 94/11/29 + * RespEngr: tony bennett + * + * Description: + * Get a pointer to a semaphore. + * + * Parameters: + * which -- if 0, then allocate a free semaphore from the pool + * if non-zero, then return pointer to that one, even + * if it is already busy. + * + * Returns: + * successful -- pointer to semaphore + * NULL otherwise + * + * Notes: + * + * + * Deficiencies/ToDo: + * + * + */ + +hppa_semaphore_t * +hppa_semaphore_allocate(rtems_unsigned32 which, + int flag) +{ + hppa_semaphore_t *sp = 0; + + /* + * grab the control semaphore + */ + + if (hppa_semaphore_acquire(SEM_CONTROL, 0) == 0) + SEM_FATAL_ERROR("could not grab control semaphore"); + + /* + * Find a free one and init it + */ + + if (which) + { + if (which >= hppa_semaphores) + SEM_FATAL_ERROR("requested non-existent semaphore"); + sp = &hppa_semaphore_pool[which]; + + /* + * if it is "free", then mark it claimed now. + * If it is not free then we are done. + */ + + if (SEM_IS_AVAILABLE(sp)) + goto allmine; + } + else for (sp = SEM_FIRST; + sp < &hppa_semaphore_pool[hppa_semaphores]; + sp++) + { + if (SEM_IS_AVAILABLE(sp)) + { +allmine: SEM_FREE_INIT(sp); + SEM_MARK_BUSY(sp); + if ( ! (flag & HPPA_SEM_INITIALLY_FREE)) + SEM_MARK_GRABBED(sp); + break; + } + } + + /* + * Free up the control semaphore + */ + + hppa_semaphore_release(SEM_CONTROL); + + return sp; +} + diff --git a/c/src/lib/libcpu/hppa1.1/semaphore/semaphore.h b/c/src/lib/libcpu/hppa1.1/semaphore/semaphore.h new file mode 100644 index 0000000000..04f709cf64 --- /dev/null +++ b/c/src/lib/libcpu/hppa1.1/semaphore/semaphore.h @@ -0,0 +1,84 @@ +/* + * File: $RCSfile$ + * Project: PixelFlow + * Created: 94/11/29 + * RespEngr: tony e bennett + * Revision: $Revision$ + * Last Mod: $Date$ + * + * COPYRIGHT (c) 1994 by Division Incorporated + * + * To anyone who acknowledges that this file is provided "AS IS" + * without any express or implied warranty: + * permission to use, copy, modify, and distribute this file + * for any purpose is hereby granted without fee, provided that + * the above copyright notice and this notice appears in all + * copies, and that the name of Division Incorporated not be + * used in advertising or publicity pertaining to distribution + * of the software without specific, written prior permission. + * Division Incorporated makes no representations about the + * suitability of this software for any purpose. + * + * Description: + * HPPA fast spinlock semaphores based on LDCWX instruction. + * These semaphores are not known to RTEMS. + * + * TODO: + * + * $Id$ + */ + +#ifndef _INCLUDE_SEMAPHORE_H +#define _INCLUDE_SEMAPHORE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * This structure has hardware requirements. + * LDCWX opcode requires 16byte alignment for the lock + * 'lock' must be first member of structure. + */ + +#define SEM_ALIGN 16 + +typedef volatile struct { + + rtems_unsigned32 lock __attribute__ ((aligned (SEM_ALIGN))); + + rtems_unsigned32 flags; + + void *owner_tcb; /* for debug/commentary only */ + + rtems_unsigned32 user; /* for use by user */ + +} hppa_semaphore_t; + +/* + * Values for flags + */ + +#define HPPA_SEM_IN_USE 0x0001 /* semaphore owned by somebody */ +#define HPPA_SEM_NO_SPIN 0x0002 /* don't spin if unavailable */ +#define HPPA_SEM_INITIALLY_FREE 0x0004 /* init it to be free */ + +/* + * Caller specifiable flags + */ + +#define HPPA_SEM_CALLER_FLAGS (HPPA_SEM_NO_SPIN | HPPA_SEM_INITIALLY_FREE) + +void hppa_semaphore_pool_initialize(void *pool_base, int pool_size); + +rtems_unsigned32 hppa_semaphore_acquire(hppa_semaphore_t *sp, int flag); + +void hppa_semaphore_release(hppa_semaphore_t *sp); + +hppa_semaphore_t *hppa_semaphore_allocate(rtems_unsigned32 which, int flag); + +#ifdef __cplusplus +} +#endif + +#endif /* ! _INCLUDE_SEMAPHORE_H */ diff --git a/c/src/lib/libcpu/hppa1.1/timer/timer.c b/c/src/lib/libcpu/hppa1.1/timer/timer.c new file mode 100644 index 0000000000..caa04bd282 --- /dev/null +++ b/c/src/lib/libcpu/hppa1.1/timer/timer.c @@ -0,0 +1,62 @@ +/* timer.c + * + * This file manages the interval timer on the PA-RISC. + * + * NOTE: It is important that the timer start/stop overhead be + * determined when porting or modifying this code. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include + +volatile rtems_unsigned32 Timer_starting; +rtems_boolean Timer_driver_Find_average_overhead; + +void Timer_initialize() +{ + Timer_starting = get_itimer(); +} + +#define AVG_OVERHEAD 0 /* It typically takes 3.0 microseconds */ + /* (6 countdowns) to start/stop the timer. */ +#define LEAST_VALID 1 /* Don't trust a value lower than this */ + +int Read_timer() +{ + rtems_unsigned32 clicks; + rtems_unsigned32 total; + + clicks = get_itimer(); + + total = clicks - Timer_starting; + + if ( Timer_driver_Find_average_overhead == 1 ) + return total; /* in XXX microsecond units */ + + else { + if ( total < LEAST_VALID ) + return 0; /* below timer resolution */ + return (total - AVG_OVERHEAD); + } +} + +rtems_status_code Empty_function( void ) +{ + return RTEMS_SUCCESSFUL; +} + +void Set_find_average_overhead( + rtems_boolean find_flag +) +{ + Timer_driver_Find_average_overhead = find_flag; +} diff --git a/c/src/lib/libmisc/README b/c/src/lib/libmisc/README new file mode 100644 index 0000000000..6825898121 --- /dev/null +++ b/c/src/lib/libmisc/README @@ -0,0 +1,16 @@ +# +# $Id$ +# + +This directory contains for the "miscellaneous" library. Currently +the only item in this library is a user extension set which checks +for a task "blowing" it's stack. + +The following ideas have been mentioned for items which could go +in this library, but this list is not all inclusive: + + + Workspace Consistency Checker + + Task Execution Time Monitor + +The intent of this library is to provide a home for useful utility routines +which are dependent upon RTEMS. diff --git a/c/src/lib/libmisc/monitor/README b/c/src/lib/libmisc/monitor/README new file mode 100644 index 0000000000..cae39d593c --- /dev/null +++ b/c/src/lib/libmisc/monitor/README @@ -0,0 +1,7 @@ +# +# $Id$ +# + +This is a snapshot of a work in process. It is the beginnings of a +debug monitor task and trap handler which is tasking aware. + diff --git a/c/src/lib/libmisc/monitor/mon-monitor.c b/c/src/lib/libmisc/monitor/mon-monitor.c new file mode 100644 index 0000000000..aa466143f9 --- /dev/null +++ b/c/src/lib/libmisc/monitor/mon-monitor.c @@ -0,0 +1,307 @@ +/* + * @(#)monitor.c 1.6 - 95/04/24 + * + */ + +/* + * mon-task.c + * + * Description: + * RTEMS monitor task + * + * + * + * TODO: + * add pause command (monitor sleeps for 'n' ticks, then wakes up) + * + */ + +#include +/* #include */ + +#include "symbols.h" +#include "monitor.h" + +#include +#include +#include +#include + +#define STREQ(a,b) (strcmp(a,b) == 0) + +/* set by trap handler */ +extern rtems_tcb *debugger_interrupted_task; +extern rtems_context *debugger_interrupted_task_context; +extern rtems_unsigned32 debugger_trap; + +/* our task id needs to be public so any debugger can resume us */ +rtems_unsigned32 rtems_monitor_task_id; + + +rtems_symbol_table_t *rtems_monitor_symbols; + + +#ifndef MONITOR_PROMPT +#define MONITOR_PROMPT "rtems> " +#endif + +#define MONITOR_WAKEUP_EVENT RTEMS_EVENT_0 + +/* + * Function: rtems_monitor_init + * + * Description: + * Create the RTEMS monitor task + * + * Parameters: + * 'monitor_suspend' arg is passed as initial arg to monitor task + * If TRUE, monitor will suspend itself as it starts up. Otherwise + * it will begin its command loop. + * + * Returns: + * + * + * Side Effects: + * + * + * Notes: + * + * + * Deficiencies/ToDo: + * + * + */ + +/* + * make_argv(cp): token-count + * Break up the command line in 'cp' into global argv[] and argc (return + * value). + */ + +int +rtems_monitor_make_argv( + char *cp, + int *argc_p, + char **argv) +{ + int argc = 0; + + while ((cp = strtok(cp, " \t\n\r"))) + { + argv[argc++] = cp; + cp = (char *) NULL; + } + argv[argc] = (char *) NULL; /* end of argv */ + + return *argc_p = argc; +} + +void +rtems_monitor_init(rtems_boolean monitor_suspend) +{ + rtems_status_code status; + + status = rtems_task_create(rtems_build_name('R', 'M', 'O', 'N'), + 1, 0/*stack*/, RTEMS_NO_PREEMPT | RTEMS_INTERRUPT_LEVEL(0), RTEMS_DEFAULT_ATTRIBUTES, &rtems_monitor_task_id); + if (status != RTEMS_SUCCESSFUL) + { + printf("could not create monitor task\n"); + goto done; + } + + rtems_monitor_symbols_loadup(); + + status = rtems_task_start(rtems_monitor_task_id, rtems_monitor_task, monitor_suspend); + if (status != RTEMS_SUCCESSFUL) + { + printf("could not start monitor!\n"); + goto done; + } + +done: +} + +rtems_status_code +rtems_monitor_suspend(rtems_interval timeout) +{ + rtems_event_set event_set; + rtems_status_code status; + + status = rtems_event_receive(MONITOR_WAKEUP_EVENT, RTEMS_DEFAULT_OPTIONS, timeout, &event_set); + return status; +} + +void +rtems_monitor_wakeup(void) +{ + rtems_status_code status; + + status = rtems_event_send(rtems_monitor_task_id, MONITOR_WAKEUP_EVENT); +} + + +/* + * Read and break up a monitor command + * + * We have to loop on the gets call, since it will return NULL under UNIX + * RTEMS when we get a signal (eg: SIGALRM). + */ + +int +rtems_monitor_read_command(char *command, + int *argc, + char **argv) +{ + printf("%s", MONITOR_PROMPT); fflush(stdout); + while (gets(command) == (char *) 0) + ; + return rtems_monitor_make_argv(command, argc, argv); +} + +void +rtems_monitor_task(rtems_task_argument monitor_suspend) +{ + rtems_tcb *debugee = 0; + char command[513]; + rtems_context *rp; + rtems_context_fp *fp; + char *cp; + int argc; + char *argv[64]; + + if ((rtems_boolean) monitor_suspend) + (void) rtems_monitor_suspend(RTEMS_NO_TIMEOUT); + + for (;;) + { + extern rtems_tcb * _Thread_Executing; + debugee = _Thread_Executing; + rp = &debugee->Registers; + fp = (rtems_context_fp *) debugee->fp_context; /* possibly 0 */ + + if (0 == rtems_monitor_read_command(command, &argc, argv)) + continue; + + if (STREQ(argv[0], "quit")) + rtems_monitor_suspend(RTEMS_NO_TIMEOUT); + else if (STREQ(argv[0], "pause")) + rtems_monitor_suspend(1); + +#ifdef CPU_INVOKE_DEBUGGER + else if (STREQ(argv[0], "debug")) + { + CPU_INVOKE_DEBUGGER; + } +#endif + else if (STREQ(argv[0], "symbol")) + { + char *symbol; + char *value; + + if (argc != 3) + { + printf("usage: symbol symname symvalue\n"); + continue; + } + + symbol = argv[1]; + value = argv[2]; + if (symbol && value) + { + rtems_symbol_t *sp; + sp = rtems_symbol_create(rtems_monitor_symbols, + symbol, + (rtems_unsigned32) strtoul(value, 0, 16)); + if (sp) + printf("symbol defined is at %p\n", sp); + else + printf("could not define symbol\n"); + } + else + printf("parsing error\n"); + } + else + { + printf("Unrecognized command: '%s'\n", argv[0]); + } + } +} + +/* + * Function: rtems_monitor_symbols_loadup + * + * Description: + * Create and load the monitor's symbol table. + * We are reading the output format of 'gnm' which looks like this: + * + * 400a7068 ? _Rate_monotonic_Information + * 400a708c ? _Thread_Dispatch_disable_level + * 400a7090 ? _Configuration_Table + * + * + * We ignore the type field. + * + * Parameters: + * + * + * Returns: + * + * + * Side Effects: + * Creates and fills in 'rtems_monitor_symbols' table + * + * Notes: + * + * + * Deficiencies/ToDo: + * Someday this should know BFD + * Maybe we could get objcopy to just copy the symbol areas + * and copy that down. + * + */ + +void +rtems_monitor_symbols_loadup(void) +{ + FILE *fp; + char buffer[128]; + + rtems_monitor_symbols = rtems_symbol_table_create(10); + if (rtems_monitor_symbols == 0) + return; + + fp = fdopen(8, "r"); + if (fp == 0) + return; + + while (fgets(buffer, sizeof(buffer) - 1, fp)) + { + char *symbol; + char *value; + char *ignored_type; + + value = strtok(buffer, " \t\n"); + ignored_type = strtok(0, " \t\n"); + symbol = strtok(0, " \t\n"); + + if (symbol && ignored_type && value) + { + rtems_symbol_t *sp; + sp = rtems_symbol_create(rtems_monitor_symbols, + symbol, + (rtems_unsigned32) strtoul(value, 0, 16)); + if (sp == 0) + { + printf("could not define symbol\n"); + goto done; + } + } + else + { + printf("parsing error\n"); + goto done; + } + } + +done: +} diff --git a/c/src/lib/libmisc/monitor/mon-symbols.c b/c/src/lib/libmisc/monitor/mon-symbols.c new file mode 100644 index 0000000000..58d35befa1 --- /dev/null +++ b/c/src/lib/libmisc/monitor/mon-symbols.c @@ -0,0 +1,327 @@ +/* + * @(#)symbols.c 1.3 - 95/04/24 + * + */ + +/* #define qsort _quicksort */ + +/* + * File: symbols.c + * + * Description: + * Symbol table manager for the RTEMS monitor. + * These routines may be used by other system resources also. + * + * + * TODO: + */ + +#include +#include +#include +#include + +#include "symbols.h" + +extern rtems_symbol_table_t *rtems_monitor_symbols; + +#ifdef RTEMS_DEBUG +#define CHK_ADR_PTR(p) \ +do { \ + if (((p) < rtems_monitor_symbols->addresses) || \ + ((p) >= (rtems_monitor_symbols->addresses + rtems_monitor_symbols->next))) \ + { \ + printf("bad address pointer %p\n", (p)); \ + rtems_fatal_error_occurred(RTEMS_INVALID_ADDRESS); \ + } \ +} while (0) + +#define CHK_NAME_PTR(p) \ +do { \ + if (((p) < rtems_monitor_symbols->symbols) || \ + ((p) >= (rtems_monitor_symbols->symbols + rtems_monitor_symbols->next))) \ + { \ + printf("bad symbol pointer %p\n", (p)); \ + rtems_fatal_error_occurred(RTEMS_INVALID_ADDRESS); \ + } \ +} while (0) +#else +#define CHK_ADR_PTR(p) +#define CHK_NAME_PTR(p) +#endif + +rtems_symbol_table_t * +rtems_symbol_table_create() +{ + rtems_symbol_table_t *table; + + table = (rtems_symbol_table_t *) malloc(sizeof(rtems_symbol_table_t)); + memset((void *) table, 0, sizeof(*table)); + + table->growth_factor = 30; /* 30 percent */ + + return table; +} + +void +rtems_symbol_table_destroy(rtems_symbol_table_t *table) +{ + rtems_symbol_string_block_t *p, *pnext; + + if (table) + { + if (table->addresses) + (void) free(table->addresses); + table->addresses = 0; + + if (table->symbols) + (void) free(table->symbols); + table->symbols = 0; + + p = table->string_buffer_head; + while (p) + { + pnext = p->next; + free(p); + p = pnext; + } + table->string_buffer_head = 0; + table->string_buffer_current = 0; + + free(table); + } +} + +rtems_symbol_t * +rtems_symbol_create( + rtems_symbol_table_t *table, + char *name, + rtems_unsigned32 value + ) +{ + int symbol_length; + size_t newsize; + rtems_symbol_t *sp; + + symbol_length = strlen(name) + 1; /* include '\000' in length */ + + /* need to grow the table? */ + if (table->next >= table->size) + { + if (table->size == 0) + newsize = 100; + else + newsize = table->size + (table->size / (100 / table->growth_factor)); + + table->addresses = (rtems_symbol_t *) realloc((void *) table->addresses, newsize * sizeof(rtems_symbol_t)); + if (table->addresses == 0) /* blew it; lost orig */ + goto failed; + + table->symbols = (rtems_symbol_t *) realloc((void *) table->symbols, newsize * sizeof(rtems_symbol_t)); + if (table->symbols == 0) /* blew it; lost orig */ + goto failed; + + table->size = newsize; + } + + sp = &table->addresses[table->next]; + sp->value = value; + + /* Have to add it to string pool */ + /* need to grow pool? */ + + if ((table->string_buffer_head == 0) || + (table->strings_next + symbol_length) >= SYMBOL_STRING_BLOCK_SIZE) + { + rtems_symbol_string_block_t *p; + + p = (rtems_symbol_string_block_t *) malloc(sizeof(rtems_symbol_string_block_t)); + if (p == 0) + goto failed; + p->next = 0; + if (table->string_buffer_head == 0) + table->string_buffer_head = p; + else + table->string_buffer_current->next = p; + table->string_buffer_current = p; + + table->strings_next = 0; + } + + sp->name = table->string_buffer_current->buffer + table->strings_next; + (void) strcpy(sp->name, name); + + table->strings_next += symbol_length; + + table->symbols[table->next] = *sp; + + table->sorted = 0; + table->next++; + + return sp; + +/* XXX Not sure what to do here. We've possibly destroyed the initial + symbol table due to realloc failure */ +failed: + return 0; +} + +/* + * Qsort entry point for compare by address + */ + +int +rtems_symbol_compare(const void *e1, + const void *e2) +{ + rtems_symbol_t *s1, *s2; + s1 = (rtems_symbol_t *) e1; + s2 = (rtems_symbol_t *) e2; + + CHK_ADR_PTR(s1); + CHK_ADR_PTR(s2); + + if (s1->value < s2->value) + return -1; + if (s1->value > s2->value) + return 1; + return 0; +} + +/* + * Qsort entry point for compare by string name (case independent) + */ + +int +rtems_symbol_string_compare(const void *e1, + const void *e2) +{ + rtems_symbol_t *s1, *s2; + s1 = (rtems_symbol_t *) e1; + s2 = (rtems_symbol_t *) e2; + + CHK_NAME_PTR(s1); + CHK_NAME_PTR(s2); + + return strcasecmp(s1->name, s2->name); +} + + +/* + * Sort the symbol table using qsort + */ + +void +rtems_symbol_sort(rtems_symbol_table_t *table) +{ +#ifdef simhppa + printf("Sorting symbols ... "); /* so slow we need a msg */ + fflush(stdout); +#endif + + qsort((void *) table->addresses, (size_t) table->next, + sizeof(rtems_symbol_t), rtems_symbol_compare); + + qsort((void *) table->symbols, (size_t) table->next, + sizeof(rtems_symbol_t), rtems_symbol_string_compare); + +#ifdef simhppa + /* so slow we need a msg */ + printf("done\n"); +#endif + + table->sorted = 1; +} + +/* + * Search the symbol table by address + * This code based on CYGNUS newlib bsearch, but changed + * to allow for finding closest symbol <= key + */ + +rtems_symbol_t * +rtems_symbol_value_lookup( + rtems_symbol_table_t *table, + rtems_unsigned32 value + ) +{ + rtems_symbol_t *sp; + rtems_symbol_t *base; + rtems_symbol_t *best = 0; + rtems_unsigned32 distance; + rtems_unsigned32 best_distance = ~0; + rtems_unsigned32 elements; + + if ((table == 0) || (table->size == 0)) + return 0; + + if (table->sorted == 0) + rtems_symbol_sort(table); + + base = table->addresses; + elements = table->next; + + while (elements) + { + sp = base + (elements / 2); + if (value < sp->value) + elements /= 2; + else if (value > sp->value) + { + distance = value - sp->value; + if (distance < best_distance) + { + best_distance = distance; + best = sp; + } + base = sp + 1; + elements = (elements / 2) - (elements % 2 ? 0 : 1); + } + else + return sp; + } + + if (value == base->value) + return base; + + return best; +} + +/* + * Search the symbol table by string name (case independent) + */ + +rtems_symbol_t * +rtems_symbol_name_lookup( + rtems_symbol_table_t *table, + char *name + ) +{ + rtems_symbol_t *sp = 0; + rtems_symbol_t key; + + if ((table == 0) || (name == 0)) + goto done; + + if (table->sorted == 0) + { + rtems_symbol_sort(table); + } + + /* + * dummy up one for bsearch() + */ + + key.name = name; + key.value = 0; + + sp = (rtems_symbol_t *) bsearch((const void *) &key, + (const void *) table->symbols, + (size_t) table->next, + sizeof(rtems_symbol_t), + rtems_symbol_string_compare); + +done: + return sp; +} + diff --git a/c/src/lib/libmisc/monitor/monitor.h b/c/src/lib/libmisc/monitor/monitor.h new file mode 100644 index 0000000000..195aa73695 --- /dev/null +++ b/c/src/lib/libmisc/monitor/monitor.h @@ -0,0 +1,38 @@ +/* + * @(#)monitor.h 1.2 - 95/04/24 + * + */ + +/* + * File: monitor.h + * + * Description: + * The RTEMS monitor task include file. + * + * + * + * TODO: + * + */ + +#ifndef __MONITOR_H +#define __MONITOR_H + +#ifdef __cplusplus +extern "C" { +#endif + +void rtems_monitor_init(rtems_boolean monitor_suspend); +void rtems_monitor_wakeup(void); +void rtems_monitor_task(rtems_task_argument monitor_suspend); +void rtems_monitor_symbols_loadup(void); + +extern rtems_unsigned32 rtems_monitor_task_id; + +extern rtems_symbol_table_t *rtems_monitor_symbols; + +#ifdef __cplusplus +} +#endif + +#endif /* ! __MONITOR_H */ diff --git a/c/src/lib/libmisc/monitor/symbols.h b/c/src/lib/libmisc/monitor/symbols.h new file mode 100644 index 0000000000..680ac6d2cf --- /dev/null +++ b/c/src/lib/libmisc/monitor/symbols.h @@ -0,0 +1,80 @@ +/* + * File: symbols.h + * + * Description: + * Entry points for symbol table routines. + * + * + * + * TODO: + * + */ + +#ifndef _INCLUDE_SYMBOLS_H +#define _INCLUDE_SYMBOLS_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + rtems_unsigned32 value; + char *name; +} rtems_symbol_t; + +#define SYMBOL_STRING_BLOCK_SIZE 4080 +typedef struct rtems_symbol_string_block_s { + struct rtems_symbol_string_block_s *next; + char buffer[SYMBOL_STRING_BLOCK_SIZE]; +} rtems_symbol_string_block_t; + +typedef struct { + + rtems_unsigned32 sorted; /* are symbols sorted right now? */ + + rtems_unsigned32 growth_factor; /* % to grow by when needed */ + + rtems_unsigned32 next; /* next symbol slot to use when adding */ + rtems_unsigned32 size; /* max # of symbols */ + + /* + * Symbol list -- sorted by address (when we do a lookup) + */ + + rtems_symbol_t *addresses; /* symbol array by address */ + + /* + * String list -- sorted by name (when we do a lookup) + * This is a duplicate of the info in table->addresses, but it's + * pretty small, so I don't worry about it. + */ + + rtems_symbol_t *symbols; /* symbol array */ + + /* + * String pool, unsorted, a list of blocks of string data + */ + + rtems_symbol_string_block_t *string_buffer_head; + rtems_symbol_string_block_t *string_buffer_current; + rtems_unsigned32 strings_next; /* next byte to use in this block */ + +} rtems_symbol_table_t; + +void rtems_symbol_table_destroy(rtems_symbol_table_t *table); +rtems_symbol_table_t *rtems_symbol_table_create(); +rtems_symbol_t *rtems_symbol_create(rtems_symbol_table_t *, + char *, rtems_unsigned32); +rtems_symbol_t *rtems_symbol_value_lookup(rtems_symbol_table_t *, + rtems_unsigned32); +rtems_symbol_t *rtems_symbol_name_lookup(rtems_symbol_table_t *, + char *); + +#define rtems_symbol_name(sp) ((sp)->name) +#define rtems_symbol_value(sp) ((sp)->value) + +#ifdef __cplusplus +} +#endif + +#endif /* ! _INCLUDE_SYMBOLS_H */ diff --git a/c/src/lib/libmisc/stackchk/README b/c/src/lib/libmisc/stackchk/README new file mode 100644 index 0000000000..20e76f07bc --- /dev/null +++ b/c/src/lib/libmisc/stackchk/README @@ -0,0 +1,41 @@ +# +# $Id$ +# + +This directory contains a stack bounds checker. It provides two +primary features: + + + check for stack overflow at each context switch + + provides an educated guess at each task's stack usage + +The stack overflow check at context switch works by looking for +a 16 byte pattern at the logical end of the stack to be corrupted. +The "guesser" assumes that the entire stack was prefilled with a known +pattern and assumes that the pattern is still in place if the memory +has not been used as a stack. + +Both of these can be fooled by pushing large holes onto the stack +and not writing to them... or (much more unlikely) writing the +magic patterns into memory. + +This code has not been extensively tested. It is provided as a tool +for RTEMS users to catch the most common mistake in multitasking +systems ... too little stack space. Suggestions and comments are appreciated. + +NOTES: + +1. Stack usage information is questionable on CPUs which push + large holes on stack. + +2. The stack checker has a tendency to generate a fault when + trying to print the helpful diagnostic message. If it comes + out, congratulations. If not, then the variable Stack_check_Blown_task + contains a pointer to the TCB of the offending task. This + is usually enough to go on. + +FUTURE: + +1. Determine how/if gcc will generate stack probe calls and support that. + +2. Get accurate stack usage numbers on i960.. it pushes very large + holes on the stack. diff --git a/c/src/lib/libmisc/stackchk/check.c b/c/src/lib/libmisc/stackchk/check.c new file mode 100644 index 0000000000..8b923f5c02 --- /dev/null +++ b/c/src/lib/libmisc/stackchk/check.c @@ -0,0 +1,439 @@ +/* + * Stack Overflow Check User Extension Set + * + * NOTE: This extension set automatically determines at + * initialization time whether the stack for this + * CPU grows up or down and installs the correct + * extension routines for that direction. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + * + */ + +#include +#include +#include +#include +#include +#include +#ifdef XXX_RTEMS_H_FIXED +#include +#else +#include +extern rtems_configuration_table BSP_Configuration; +#endif + +#include +#include +#include +#include + +#include "stackchk.h" +#include "internal.h" + +/* + * This variable contains the name of the task which "blew" the stack. + * It is NULL if the system is all right. + */ + +Thread_Control *Stack_check_Blown_task; + +/* + * The extension table for the stack checker. + */ + +rtems_extensions_table Stack_check_Extension_table = { + Stack_check_Create_extension, /* rtems_task_create */ + 0, /* rtems_task_start */ + 0, /* rtems_task_restart */ + 0, /* rtems_task_delete */ + Stack_check_Switch_extension, /* task_switch */ + Stack_check_Begin_extension, /* task_begin */ + 0, /* task_exitted */ + Stack_check_Fatal_extension, /* fatal */ +}; + +/* + * The "magic pattern" used to mark the end of the stack. + */ + +Stack_check_Control Stack_check_Pattern; + +/* + * Where the pattern goes in the stack area is dependent upon + * whether the stack grow to the high or low area of the memory. + * + */ + +#if ( CPU_STACK_GROWS_UP == TRUE ) + +#define Stack_check_Get_pattern_area( _the_stack ) \ + ((Stack_check_Control *) \ + ((_the_stack)->area + (_the_stack)->size - sizeof( Stack_check_Control ) )) + +#define Stack_check_Calculate_used( _low, _size, _high_water ) \ + ((_high_water) - (_low)) + +#define Stack_check_usable_stack_start(_the_stack) \ + ((_the_stack)->area) + +#else + +#define Stack_check_Get_pattern_area( _the_stack ) \ + ((Stack_check_Control *) ((_the_stack)->area + HEAP_OVERHEAD)) + +#define Stack_check_Calculate_used( _low, _size, _high_water) \ + ( ((_low) + (_size)) - (_high_water) ) + +#define Stack_check_usable_stack_start(_the_stack) \ + ((_the_stack)->area + sizeof(Stack_check_Control)) + +#endif + +#define Stack_check_usable_stack_size(_the_stack) \ + ((_the_stack)->size - sizeof(Stack_check_Control)) + + +/* + * Do we have an interrupt stack? + * XXX it would sure be nice if the interrupt stack were also + * stored in a "stack" structure! + */ + + +Stack_Control stack_check_interrupt_stack; + +/* + * Fill an entire stack area with BYTE_PATTERN. + * This will be used by a Fatal extension to check for + * amount of actual stack used + */ + +void +stack_check_dope_stack(Stack_Control *stack) +{ + memset(stack->area, BYTE_PATTERN, stack->size); +} + + +/*PAGE + * + * Stack_check_Initialize + */ + +unsigned32 stack_check_initialized = 0; + +void Stack_check_Initialize( void ) +{ + rtems_status_code status; + Objects_Id id_ignored; + unsigned32 *p; + + if (stack_check_initialized) + return; + + /* + * Dope the pattern and fill areas + */ + + for ( p = Stack_check_Pattern.pattern; + p < &Stack_check_Pattern.pattern[PATTERN_SIZE_WORDS]; + p += 4 + ) + { + p[0] = 0xFEEDF00D; /* FEED FOOD to BAD DOG */ + p[1] = 0x0BAD0D06; + p[2] = 0xDEADF00D; /* DEAD FOOD GOOD DOG */ + p[3] = 0x600D0D06; + }; + + status = rtems_extension_create( + rtems_build_name( 'S', 'T', 'C', 'K' ), + &Stack_check_Extension_table, + &id_ignored + ); + assert ( status == RTEMS_SUCCESSFUL ); + + Stack_check_Blown_task = 0; + + /* + * If installed by a task, that task will not get setup properly + * since it missed out on the create hook. This will cause a + * failure on first switch out of that task. + * So pretend here that we actually ran create and begin extensions. + */ + + if (_Thread_Executing) + { + Stack_check_Create_extension(_Thread_Executing, _Thread_Executing); + } + + /* + * If appropriate, setup the interrupt stack for high water testing + * also. + */ + if (_CPU_Interrupt_stack_low && _CPU_Interrupt_stack_high) + { + stack_check_interrupt_stack.area = _CPU_Interrupt_stack_low; + stack_check_interrupt_stack.size = _CPU_Interrupt_stack_high - + _CPU_Interrupt_stack_low; + + stack_check_dope_stack(&stack_check_interrupt_stack); + } + + stack_check_initialized = 1; +} + +/*PAGE + * + * Stack_check_Create_extension + */ + +void Stack_check_Create_extension( + Thread_Control *running, + Thread_Control *the_thread +) +{ + if (the_thread && (the_thread != _Thread_Executing)) + stack_check_dope_stack(&the_thread->Start.Initial_stack); +} + +/*PAGE + * + * Stack_check_Begin_extension + */ + +void Stack_check_Begin_extension( + Thread_Control *the_thread +) +{ + Stack_check_Control *the_pattern; + + if ( the_thread->Object.id == 0 ) /* skip system tasks */ + return; + + the_pattern = Stack_check_Get_pattern_area(&the_thread->Start.Initial_stack); + + *the_pattern = Stack_check_Pattern; +} + +/*PAGE + * + * Stack_check_report_blown_task + * Report a blown stack. Needs to be a separate routine + * so that interrupt handlers can use this too. + * + * Caller must have set the Stack_check_Blown_task. + * + * NOTE: The system is in a questionable state... we may not get + * the following message out. + */ + +void Stack_check_report_blown_task(void) +{ + Stack_Control *stack; + Thread_Control *running; + + running = Stack_check_Blown_task; + stack = &running->Start.Initial_stack; + + fprintf( + stderr, + "BLOWN STACK!!! Offending task(%p): id=0x%08x; name=0x%08x", + running, + running->Object.id, + running->name); + fflush(stderr); + + if (BSP_Configuration.User_multiprocessing_table) + fprintf( + stderr, + "; node=%d\n", + BSP_Configuration.User_multiprocessing_table->node + ); + else + fprintf(stderr, "\n"); + fflush(stderr); + + fprintf( + stderr, + " stack covers range 0x%08x - 0x%08x (%d bytes)\n", + (unsigned32) stack->area, + (unsigned32) stack->area + stack->size - 1, + (unsigned32) stack->size); + fflush(stderr); + + fprintf( + stderr, + " Damaged pattern begins at 0x%08x and is %d bytes long\n", + (unsigned32) Stack_check_Get_pattern_area(stack), PATTERN_SIZE_BYTES); + fflush(stderr); + + rtems_fatal_error_occurred( (unsigned32) "STACK BLOWN" ); +} + +/*PAGE + * + * Stack_check_Switch_extension + */ + +void Stack_check_Switch_extension( + Thread_Control *running, + Thread_Control *heir +) +{ + if ( running->Object.id == 0 ) /* skip system tasks */ + return; + + if (0 != memcmp( (void *) Stack_check_Get_pattern_area( &running->Start.Initial_stack)->pattern, + (void *) Stack_check_Pattern.pattern, + PATTERN_SIZE_BYTES)) + { + Stack_check_Blown_task = running; + Stack_check_report_blown_task(); + } +} + +void *Stack_check_find_high_water_mark( + const void *s, + size_t n +) +{ + const unsigned32 *base, *ebase; + unsigned32 length; + + base = s; + length = n/4; + +#if ( CPU_STACK_GROWS_UP == TRUE ) + /* + * start at higher memory and find first word that does not + * match pattern + */ + + base += length - 1; + for (ebase = s; base > ebase; base--) + if (*base != U32_PATTERN) + return (void *) base; +#else + /* + * start at lower memory and find first word that does not + * match pattern + */ + + for (ebase = base + length; base < ebase; base++) + if (*base != U32_PATTERN) + return (void *) base; +#endif + + return (void *)0; +} + +/*PAGE + * + * Stack_check_Dump_threads_usage + * Try to print out how much stack was actually used by the task. + * + */ + +void Stack_check_Dump_threads_usage( + Thread_Control *the_thread +) +{ + unsigned32 size, used; + void *low; + void *high_water_mark; + Stack_Control *stack; + + if ( !the_thread ) + return; + + /* + * XXX HACK to get to interrupt stack + */ + + if (the_thread == (Thread_Control *) -1) + { + if (stack_check_interrupt_stack.area) + { + stack = &stack_check_interrupt_stack; + the_thread = 0; + } + else + return; + } + else + stack = &the_thread->Start.Initial_stack; + + low = Stack_check_usable_stack_start(stack); + size = Stack_check_usable_stack_size(stack); + + high_water_mark = Stack_check_find_high_water_mark(low, size); + + if ( high_water_mark ) + used = Stack_check_Calculate_used( low, size, high_water_mark ); + else + used = 0; + + printf( "0x%08x 0x%08x 0x%08x 0x%08x %8d %8d\n", + the_thread ? the_thread->Object.id : ~0, + the_thread ? the_thread->name : + rtems_build_name('I', 'N', 'T', 'R'), + (unsigned32) stack->area, + (unsigned32) stack->area + (unsigned32) stack->size - 1, + size, + used + ); +} + +/*PAGE + * + * Stack_check_Fatal_extension + */ + +void Stack_check_Fatal_extension( unsigned32 status ) +{ + if (status == 0) + Stack_check_Dump_usage(); +} + + +/*PAGE + * + * Stack_check_Dump_usage + */ + +void Stack_check_Dump_usage( void ) +{ + unsigned32 i; + Thread_Control *the_thread; + unsigned32 hit_running = 0; + + if (stack_check_initialized == 0) + return; + + printf( + " ID NAME LOW HIGH AVAILABLE USED\n" + ); + for ( i=1 ; i<_Thread_Information.maximum ; i++ ) { + the_thread = (Thread_Control *)_Thread_Information.local_table[ i ]; + Stack_check_Dump_threads_usage( the_thread ); + if ( the_thread == _Thread_Executing ) + hit_running = 1; + } + + if ( !hit_running ) + Stack_check_Dump_threads_usage( _Thread_Executing ); + + /* dump interrupt stack info if any */ + Stack_check_Dump_threads_usage((Thread_Control *) -1); +} + diff --git a/c/src/lib/libmisc/stackchk/internal.h b/c/src/lib/libmisc/stackchk/internal.h new file mode 100644 index 0000000000..19c9f5e267 --- /dev/null +++ b/c/src/lib/libmisc/stackchk/internal.h @@ -0,0 +1,94 @@ +/* internal.h + * + * This include file contains internal information + * for the RTEMS stack checker. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __INTERNAL_STACK_CHECK_h +#define __INTERNAL_STACK_CHECK_h + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * This structure is used to fill in and compare the "end of stack" + * marker pattern. + * pattern area must be a multiple of 4 words. + */ + +#ifdef CPU_STACK_CHECK_SIZE +#define PATTERN_SIZE_WORDS (((CPU_STACK_CHECK_SIZE / 4) + 3) & ~0x3) +#else +#define PATTERN_SIZE_WORDS 4 +#endif + +#define PATTERN_SIZE_BYTES (PATTERN_SIZE_WORDS * 4) + +typedef struct { + unsigned32 pattern[ PATTERN_SIZE_WORDS ]; +} Stack_check_Control; + +/* + * The pattern used to fill the entire stack. + */ + +#define BYTE_PATTERN 0xA5 +#define U32_PATTERN 0xA5A5A5A5 + +/* + * Stack_check_Create_extension + */ + +void Stack_check_Create_extension( + Thread_Control *running, + Thread_Control *the_thread +); + +/* + * Stack_check_Begin_extension + */ + +void Stack_check_Begin_extension( + Thread_Control *the_thread +); + +/* + * Stack_check_Switch_extension + */ + +void Stack_check_Switch_extension( + Thread_Control *running, + Thread_Control *heir +); + +/* + * Stack_check_Fatal_extension + */ + +void Stack_check_Fatal_extension( + unsigned32 +); + +/* + * Stack_check_Dump_usage + */ + +void Stack_check_Dump_usage( void ); + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/c/src/lib/libmisc/stackchk/stackchk.h b/c/src/lib/libmisc/stackchk/stackchk.h new file mode 100644 index 0000000000..f3281c63fe --- /dev/null +++ b/c/src/lib/libmisc/stackchk/stackchk.h @@ -0,0 +1,41 @@ +/* stackchk.h + * + * This include file contains information necessary to utilize + * and install the stack checker mechanism. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __STACK_CHECK_h +#define __STACK_CHECK_h + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Stack_check_Initialize + */ + +void Stack_check_Initialize( void ); + +/* + * Stack_check_Dump_usage + */ + +void Stack_check_Dump_usage( void ); + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/c/src/lib/start/README b/c/src/lib/start/README new file mode 100644 index 0000000000..bec0349374 --- /dev/null +++ b/c/src/lib/start/README @@ -0,0 +1,10 @@ +$Id$ + +For each processor there may be some start up code +(like crt.o) in the appropriate entry subdirectory. This +entry code transfers control to target board specific +code). + +For some processors this code exists in some external (to RTEMS) +library such as libgloss or the host system (for example the hppa1_1 +and UNIX cpu's) diff --git a/c/src/lib/start/i960/start.s b/c/src/lib/start/i960/start.s new file mode 100644 index 0000000000..8db45011b1 --- /dev/null +++ b/c/src/lib/start/i960/start.s @@ -0,0 +1,105 @@ +/* entry.s + * + * This file contains the entry point for the application. + * The name of this entry point is compiler dependent. + * It jumps to the BSP which is responsible for performing + * all initialization. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include "asm.h" + + BEGIN_CODE + PUBLIC(start) # GNU960 default entry point + +start: + mov 3, r12 + modpc r12, r12, r12 # enable tracing/trace faults + mov g5, g5 # NOP + mov 0, g14 # initialize constant for C + + /* + * zero out uninitialized data area + */ +zerobss: + lda _end, r4 /* find end of .bss */ + lda _bss_start, r5 /* find beginning of .bss */ + ldconst 0, r6 + +loop: st r6, (r5) /* to zero out uninitialized */ + addo 4, r5, r5 /* data area */ + cmpobl r5, r4, loop /* loop until _end reached */ + +/* set up stack pointer: + * The heap will begin at '_end'; its length is 'heap_size' + * bytes. The stack will begin at the first 64-byte-aligned + * block after the heap. + * + * A default value of 'heap_size' is set by linking with libnindy.a + * The default can be overridden by redefining this symbol at link + * time (with a line of the form 'heap_size=XXXX;' in the lnk960 + * linker specification file; or one of the form + * "-defsym heap_size=XXXX" on the gld960 invocation line). + */ + + ldconst _end, sp /* set sp = address of end of heap */ + lda heap_size(sp),sp + lda 64(sp), sp /* Now round up to 64-byte boundary */ + ldconst 0xffffffc0, r12 + and r12, sp, sp + st sp, _stack_start /* Save for brk() routine */ + + call init_frames + ret /* return to monitor */ + +init_frames: + mov 0, g14 /* initialize constant for C */ + ldconst 0x3b001000, g0 + ldconst 0x00009107, g1 + modac g1, g0, g0 /* set AC controls */ + + /* + * remember the frame, so that we can set it up if necessary + */ + + st fp, _start_frame + + /* + * Call application mainline. + * Someday, real values of argc and argv will be set up. + * For now, they are set to 0. + */ + ldconst 0,g0 + ldconst 0,g1 + call _bsp_start + ret + +END_CODE + + BEGIN_DATA + + PUBLIC(_start_frame) +SYM (_start_frame): + .word 0 # addr of first user frame: for gdb960 + +SYM (_stack_start): + PUBLIC(_stack_start) + .word 0 # addr of first user frame: for gdb960 + +END_DATA + +BEGIN_BSS + PUBLIC(heap_size) + .set heap_size,0x2000 +END_BSS + +END diff --git a/c/src/lib/start/m68k/start.s b/c/src/lib/start/m68k/start.s new file mode 100644 index 0000000000..0bbb0a851f --- /dev/null +++ b/c/src/lib/start/m68k/start.s @@ -0,0 +1,160 @@ +/* entry.s + * + * This file contains the entry point for the application. + * The name of this entry point is compiler dependent. + * It jumps to the BSP which is responsible for performing + * all initialization. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include "asm.h" + +BEGIN_CODE + | Default entry points for: + PUBLIC (start) | GNU + PUBLIC (M68Kvec) | Vector Table + +SYM (start): +SYM (M68Kvec): | standard location for vectors + nop | for linkers with problem + | location zero + jmp SYM (start_around) + + /* + * We can use the following space as our vector table + * if the CPU has a VBR or we can save vector table in it + * if the CPU does not. + */ + + .space 4088 | to avoid initial intr stack + | from 135BUG on MVME13? + | and start code at 0x4000 +SYM (vectors): + .space 1016 | reserve space for rest of vectors + +#if ( M68K_HAS_SEPARATE_STACKS == 1 ) +SYM (lowintstack): + .space 4092 | reserve for interrupt stack +SYM (hiintstack): + .space 4 | end of interrupt stack +#endif + + PUBLIC (start_around) +SYM (start_around): + move.w sr, SYM (initial_sr) +#if ( M68K_HAS_SEPARATE_STACKS == 1 ) + movec isp,a0 + move.l a0, SYM (initial_isp) + movec usp,a0 + move.l a0, SYM (initial_usp) + movec msp,a0 + move.l a0, SYM (initial_msp) +#else + move.l a7, SYM (initial_msp) +#endif + oriw #0x0700,sr | INTERRUPTS OFF!!! + + + + | + | zero out uninitialized data area + | +zerobss: + moveal # SYM (end),a0 | find end of .bss + moveal # SYM (bss_start),a1 | find beginning of .bss + movel #0,d0 + +loop: movel #0,a1@+ | to zero out uninitialized + cmpal a0,a1 + jlt loop | loop until _end reached + + movel # SYM (end),d0 | d0 = end of bss/start of heap + addl # SYM (heap_size),d0 | d0 = end of heap + movel d0, SYM (stack_start) | Save for brk() routine + addl # SYM (stack_size),d0 | make room for stack + andl #0xffffffc0,d0 | align it on 16 byte boundary + movw #0x3700,sr | SUPV MODE,INTERRUPTS OFF!!! + movel d0,a7 | set master stack pointer + movel d0,a6 | set base pointer + + /* + * RTEMS should maintiain a separate interrupt stack on CPUs + * without one in hardware. This is currently not supported + * on versions of the m68k without a HW intr stack. + */ + +#if ( M68K_HAS_SEPARATE_STACKS == 1 ) + lea SYM (hiintstack),a0 | a0 = high end of intr stack + movec a0,isp | set interrupt stack +#endif + + jsr SYM (bsp_start) +#if ( M68K_HAS_SEPARATE_STACKS == 1 ) + move.l SYM (initial_isp),a0 + movec a0,isp + move.l SYM (initial_usp),a0 + movec a0,usp + move.l SYM (initial_msp),a0 + movec a0,msp +#else + movea.l SYM (initial_msp),a7 +#endif + move.w SYM (initial_sr),sr + rts + +END_CODE + +BEGIN_DATA + + PUBLIC (start_frame) +SYM (start_frame): + .space 4,0 + + PUBLIC (stack_start) +SYM (stack_start): + .space 4,0 +END_DATA + +BEGIN_BSS + + PUBLIC (environ) + .align 2 +SYM (environ): + .long 0 + + PUBLIC (initial_isp) +SYM (initial_isp): + .space 4 + + PUBLIC (initial_msp) +SYM (initial_msp): + .space 4 + + PUBLIC (initial_usp) +SYM (initial_usp): + .space 4 + + PUBLIC (initial_sr) +SYM (initial_sr): + .space 2 + + PUBLIC (heap_size) + .set SYM (heap_size),0x2000 + + PUBLIC (stack_size) + .set SYM (stack_size),0x1000 + + +END_DATA +END + + -- cgit v1.2.3