From 0074691a67f857c9b3f880fb581e0af1d5673337 Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Thu, 31 Jul 1997 22:13:29 +0000 Subject: Merged very large and much appreciated patch from Chris Johns . This patch includes the ods68302 bsp, the RTEMS++ class library, and the rtems++ test. --- c/src/lib/include/rtems++/rtemsEvent.h | 127 +++ c/src/lib/include/rtems++/rtemsInterrupt.h | 105 ++ c/src/lib/include/rtems++/rtemsMessageQueue.h | 176 ++++ c/src/lib/include/rtems++/rtemsSemaphore.h | 145 +++ c/src/lib/include/rtems++/rtemsStatusCode.h | 57 + c/src/lib/include/rtems++/rtemsTask.h | 171 +++ c/src/lib/include/rtems++/rtemsTaskMode.h | 210 ++++ c/src/lib/include/rtems++/rtemsTimer.h | 145 +++ c/src/lib/libbsp/m68k/ods68302/Makefile.in | 19 + c/src/lib/libbsp/m68k/ods68302/README | 81 ++ c/src/lib/libbsp/m68k/ods68302/bsp_specs | 34 + c/src/lib/libbsp/m68k/ods68302/clock/Makefile.in | 53 + c/src/lib/libbsp/m68k/ods68302/clock/ckinit.c | 162 +++ c/src/lib/libbsp/m68k/ods68302/console/Makefile.in | 53 + c/src/lib/libbsp/m68k/ods68302/console/console.c | 221 ++++ c/src/lib/libbsp/m68k/ods68302/include/Makefile.in | 35 + c/src/lib/libbsp/m68k/ods68302/include/bare.h | 246 +++++ c/src/lib/libbsp/m68k/ods68302/include/bsp.h | 139 +++ c/src/lib/libbsp/m68k/ods68302/include/coverhd.h | 115 +++ c/src/lib/libbsp/m68k/ods68302/include/crc.h | 26 + c/src/lib/libbsp/m68k/ods68302/include/debugport.h | 42 + c/src/lib/libbsp/m68k/ods68302/include/m68302scc.h | 34 + c/src/lib/libbsp/m68k/ods68302/start/Makefile.in | 68 ++ c/src/lib/libbsp/m68k/ods68302/start/cpuboot.c | 133 +++ c/src/lib/libbsp/m68k/ods68302/start/debugreset.S | 107 ++ c/src/lib/libbsp/m68k/ods68302/start/reset.S | 881 ++++++++++++++++ .../lib/libbsp/m68k/ods68302/start302/Makefile.in | 68 ++ c/src/lib/libbsp/m68k/ods68302/start302/cpuboot.c | 133 +++ .../lib/libbsp/m68k/ods68302/start302/debugreset.S | 107 ++ c/src/lib/libbsp/m68k/ods68302/start302/reset.S | 881 ++++++++++++++++ c/src/lib/libbsp/m68k/ods68302/startup/Makefile.in | 59 ++ c/src/lib/libbsp/m68k/ods68302/startup/bspclean.c | 26 + c/src/lib/libbsp/m68k/ods68302/startup/bspstart.c | 263 +++++ c/src/lib/libbsp/m68k/ods68302/startup/cpuboot.c | 133 +++ c/src/lib/libbsp/m68k/ods68302/startup/crc.c | 88 ++ c/src/lib/libbsp/m68k/ods68302/startup/debugger | 54 + c/src/lib/libbsp/m68k/ods68302/startup/debugport.c | 163 +++ c/src/lib/libbsp/m68k/ods68302/startup/gdb-hooks.c | 76 ++ c/src/lib/libbsp/m68k/ods68302/startup/linkcmds | 55 + c/src/lib/libbsp/m68k/ods68302/startup/m68302scc.c | 159 +++ c/src/lib/libbsp/m68k/ods68302/startup/m68k-stub.c | 1084 ++++++++++++++++++++ c/src/lib/libbsp/m68k/ods68302/startup/memcheck.c | 33 + c/src/lib/libbsp/m68k/ods68302/startup/rom | 56 + c/src/lib/libbsp/m68k/ods68302/startup/trace.c | 175 ++++ c/src/lib/libbsp/m68k/ods68302/timer/Makefile.in | 58 ++ c/src/lib/libbsp/m68k/ods68302/timer/timer.c | 130 +++ c/src/lib/libbsp/m68k/ods68302/timer/timerisr.s | 28 + c/src/lib/libbsp/m68k/ods68302/wrapup/Makefile.in | 48 + c/src/lib/librtems++/Makefile.in | 49 + c/src/lib/librtems++/README | 266 +++++ c/src/lib/librtems++/rtemsEvent.cc | 75 ++ c/src/lib/librtems++/rtemsInterrupt.cc | 110 ++ c/src/lib/librtems++/rtemsMessageQueue.cc | 164 +++ c/src/lib/librtems++/rtemsSemaphore.cc | 174 ++++ c/src/lib/librtems++/rtemsStatusCode.cc | 77 ++ c/src/lib/librtems++/rtemsTask.cc | 287 ++++++ c/src/lib/librtems++/rtemsTimer.cc | 100 ++ 57 files changed, 8764 insertions(+) create mode 100644 c/src/lib/include/rtems++/rtemsEvent.h create mode 100644 c/src/lib/include/rtems++/rtemsInterrupt.h create mode 100644 c/src/lib/include/rtems++/rtemsMessageQueue.h create mode 100644 c/src/lib/include/rtems++/rtemsSemaphore.h create mode 100644 c/src/lib/include/rtems++/rtemsStatusCode.h create mode 100644 c/src/lib/include/rtems++/rtemsTask.h create mode 100644 c/src/lib/include/rtems++/rtemsTaskMode.h create mode 100644 c/src/lib/include/rtems++/rtemsTimer.h create mode 100644 c/src/lib/libbsp/m68k/ods68302/Makefile.in create mode 100644 c/src/lib/libbsp/m68k/ods68302/README create mode 100644 c/src/lib/libbsp/m68k/ods68302/bsp_specs create mode 100644 c/src/lib/libbsp/m68k/ods68302/clock/Makefile.in create mode 100644 c/src/lib/libbsp/m68k/ods68302/clock/ckinit.c create mode 100644 c/src/lib/libbsp/m68k/ods68302/console/Makefile.in create mode 100644 c/src/lib/libbsp/m68k/ods68302/console/console.c create mode 100644 c/src/lib/libbsp/m68k/ods68302/include/Makefile.in create mode 100644 c/src/lib/libbsp/m68k/ods68302/include/bare.h create mode 100644 c/src/lib/libbsp/m68k/ods68302/include/bsp.h create mode 100644 c/src/lib/libbsp/m68k/ods68302/include/coverhd.h create mode 100644 c/src/lib/libbsp/m68k/ods68302/include/crc.h create mode 100644 c/src/lib/libbsp/m68k/ods68302/include/debugport.h create mode 100644 c/src/lib/libbsp/m68k/ods68302/include/m68302scc.h create mode 100644 c/src/lib/libbsp/m68k/ods68302/start/Makefile.in create mode 100644 c/src/lib/libbsp/m68k/ods68302/start/cpuboot.c create mode 100644 c/src/lib/libbsp/m68k/ods68302/start/debugreset.S create mode 100644 c/src/lib/libbsp/m68k/ods68302/start/reset.S create mode 100644 c/src/lib/libbsp/m68k/ods68302/start302/Makefile.in create mode 100644 c/src/lib/libbsp/m68k/ods68302/start302/cpuboot.c create mode 100644 c/src/lib/libbsp/m68k/ods68302/start302/debugreset.S create mode 100644 c/src/lib/libbsp/m68k/ods68302/start302/reset.S create mode 100644 c/src/lib/libbsp/m68k/ods68302/startup/Makefile.in create mode 100644 c/src/lib/libbsp/m68k/ods68302/startup/bspclean.c create mode 100644 c/src/lib/libbsp/m68k/ods68302/startup/bspstart.c create mode 100644 c/src/lib/libbsp/m68k/ods68302/startup/cpuboot.c create mode 100644 c/src/lib/libbsp/m68k/ods68302/startup/crc.c create mode 100644 c/src/lib/libbsp/m68k/ods68302/startup/debugger create mode 100644 c/src/lib/libbsp/m68k/ods68302/startup/debugport.c create mode 100644 c/src/lib/libbsp/m68k/ods68302/startup/gdb-hooks.c create mode 100644 c/src/lib/libbsp/m68k/ods68302/startup/linkcmds create mode 100644 c/src/lib/libbsp/m68k/ods68302/startup/m68302scc.c create mode 100644 c/src/lib/libbsp/m68k/ods68302/startup/m68k-stub.c create mode 100644 c/src/lib/libbsp/m68k/ods68302/startup/memcheck.c create mode 100644 c/src/lib/libbsp/m68k/ods68302/startup/rom create mode 100644 c/src/lib/libbsp/m68k/ods68302/startup/trace.c create mode 100644 c/src/lib/libbsp/m68k/ods68302/timer/Makefile.in create mode 100644 c/src/lib/libbsp/m68k/ods68302/timer/timer.c create mode 100644 c/src/lib/libbsp/m68k/ods68302/timer/timerisr.s create mode 100644 c/src/lib/libbsp/m68k/ods68302/wrapup/Makefile.in create mode 100644 c/src/lib/librtems++/Makefile.in create mode 100644 c/src/lib/librtems++/README create mode 100644 c/src/lib/librtems++/rtemsEvent.cc create mode 100644 c/src/lib/librtems++/rtemsInterrupt.cc create mode 100644 c/src/lib/librtems++/rtemsMessageQueue.cc create mode 100644 c/src/lib/librtems++/rtemsSemaphore.cc create mode 100644 c/src/lib/librtems++/rtemsStatusCode.cc create mode 100644 c/src/lib/librtems++/rtemsTask.cc create mode 100644 c/src/lib/librtems++/rtemsTimer.cc (limited to 'c/src/lib') diff --git a/c/src/lib/include/rtems++/rtemsEvent.h b/c/src/lib/include/rtems++/rtemsEvent.h new file mode 100644 index 0000000000..3cc19eeb32 --- /dev/null +++ b/c/src/lib/include/rtems++/rtemsEvent.h @@ -0,0 +1,127 @@ +/* + ------------------------------------------------------------------------ + $Id$ + ------------------------------------------------------------------------ + + COPYRIGHT (c) 1997 + Objective Design Systems Ltd Pty (ODS) + All rights reserved (R) Objective Design Systems Ltd Pty + + The license and distribution terms for this file may be found in the + file LICENSE in this distribution or at + http://www.OARcorp.com/rtems/license.html. + + ------------------------------------------------------------------------ + + rtemsEvent class. + + This class allows the user to send and receive RTEMS events to a task. + + ------------------------------------------------------------------------ */ + +#if !defined(_rtemsEvent_h_) +#define _rtemsEvent_h_ + +#include +#include + +/* ---- + rtemsEvent +*/ + +class rtemsEvent + : public rtemsStatusCode +{ +public: + // attribute a task can have + + enum WaitMode { wait = RTEMS_WAIT, + no_wait = RTEMS_NO_WAIT}; + enum Condition { any = RTEMS_EVENT_ANY, + all = RTEMS_EVENT_ALL}; + + // only the first 4 characters of the name are taken + + // connect to a task + rtemsEvent(const char* name, rtems_unsigned32 node = RTEMS_SEARCH_ALL_NODES); + + // copy and default constructors + rtemsEvent(const rtemsEvent& event); + rtemsEvent(); + + virtual ~rtemsEvent(); + + // connect to an existing task object, will not be the owner + const rtemsEvent& operator=(const rtemsEvent& event); + virtual const rtems_status_code connect(const char *name, + const rtems_unsigned32 node = RTEMS_SEARCH_ALL_NODES); + + // send an event + inline const rtems_status_code send(const rtems_id task, + const rtems_event_set events); + inline const rtems_status_code send(const rtemsTask& task, + const rtems_event_set events) ; + inline const rtems_status_code send(const rtems_event_set events); + + // receive an event, can block a task if no events waiting + inline const rtems_status_code receive(const rtems_event_set event_in, + rtems_event_set& event_out, + const rtems_interval micro_secs = 0, + const WaitMode wait = wait, + const Condition condition = any); + + // object id, and name + const rtems_id task_id_is() const { return id; } + const rtems_name task_name_is() const { return name; } + +private: + // task name + rtems_name name; + + // the rtems task id, object handle + rtems_id id; + +}; + +const rtems_status_code rtemsEvent::send(const rtems_id task, + const rtems_event_set events) +{ + set_status_code(rtems_event_send(task, events)); + return last_status_code(); +} + +const rtems_status_code rtemsEvent::send(const rtemsTask& task, + const rtems_event_set events) +{ + set_status_code(rtems_event_send(task.id_is(), events)); + return last_status_code(); +} + +const rtems_status_code rtemsEvent::send(const rtems_event_set events) +{ + set_status_code(rtems_event_send(id, events)); + return last_status_code(); +} + +const rtems_status_code rtemsEvent::receive(const rtems_event_set event_in, + rtems_event_set& event_out, + const rtems_interval micro_secs, + const WaitMode wait, + const Condition condition) +{ + rtems_interval usecs = + micro_secs && (micro_secs < _TOD_Microseconds_per_tick) ? + _TOD_Microseconds_per_tick : micro_secs; + set_status_code(rtems_event_receive(event_in, + wait | condition, + TOD_MICROSECONDS_TO_TICKS(usecs), + &event_out)); + return last_status_code(); +} + +#endif // _rtemsEvent_h_ + + + + + diff --git a/c/src/lib/include/rtems++/rtemsInterrupt.h b/c/src/lib/include/rtems++/rtemsInterrupt.h new file mode 100644 index 0000000000..0dc6a20d5e --- /dev/null +++ b/c/src/lib/include/rtems++/rtemsInterrupt.h @@ -0,0 +1,105 @@ +/* + ------------------------------------------------------------------------ + $Id$ + ------------------------------------------------------------------------ + + COPYRIGHT (c) 1997 + Objective Design Systems Ltd Pty (ODS) + All rights reserved (R) Objective Design Systems Ltd Pty + + The license and distribution terms for this file may be found in the + file LICENSE in this distribution or at + http://www.OARcorp.com/rtems/license.html. + + ------------------------------------------------------------------------ + + rtemsInterrupt class. + + This class catches an interrupt and passes control to the user's + derived class throught the handler method. + + The interrupt is released back to the previous handler when this + object destructs. + + The old handler can be chained to after the interrupt is + caught. Watch the stack usage! + + More than one instance of this class can catch the same vector. The + application will have to chain to the other objects if required. If + the old handler is not an instance of this class the chain is passed + as "void (*)(void)". If it is an instance of this class, the handler + method is directly called. + + The isr catch extends the documented return codes with : + + RTEMS_RESOURCE_IN_USE = interrupt already caught + + ------------------------------------------------------------------------ */ + +#if !defined(_rtemsInterrupt_h_) +#define _rtemsInterrupt_h_ + +#include + +/* ---- + rtemsInterrupt +*/ + +class rtemsInterrupt + : public rtemsStatusCode +{ +public: + rtemsInterrupt(); + virtual ~rtemsInterrupt(); + + // catch the interrupt + virtual const rtems_status_code isr_catch(const rtems_vector_number vector); + + // release the interrupt back to the previous handle + virtual const rtems_status_code release(); + + // the old handler + const rtems_isr_entry old_isr_handler() const { return old_handler; } + +protected: + + // called after the interrupt is caught and it goes off + virtual void handler() = 0; + + // chain to the previous handler, + inline void chain() const; + +private: + const rtemsInterrupt& operator=(const rtemsInterrupt& ); + Interrupt(const rtemsInterrupt& ); + + // the vector caught + rtems_vector_number vector; + + // true when the interrupt is caught + bool caught; + + // returned when catching the interrupt + rtems_isr_entry old_handler; + + // old interrupt table entry + rtemsInterrupt *old_interrupt; + + // common handler to redirect the interrupts + static void redirector(rtems_vector_number vector); +}; + +void rtemsInterrupt::chain() const +{ + if (old_interrupt) + old_interrupt->handler(); + else if (old_handler) + ((void(*)()) old_handler)(); +} + +#endif // _rtemsInterrupt_h_ + + + + + diff --git a/c/src/lib/include/rtems++/rtemsMessageQueue.h b/c/src/lib/include/rtems++/rtemsMessageQueue.h new file mode 100644 index 0000000000..910c7279f7 --- /dev/null +++ b/c/src/lib/include/rtems++/rtemsMessageQueue.h @@ -0,0 +1,176 @@ +/* + ------------------------------------------------------------------------ + $Id$ + ------------------------------------------------------------------------ + + COPYRIGHT (c) 1997 + Objective Design Systems Ltd Pty (ODS) + All rights reserved (R) Objective Design Systems Ltd Pty + + The license and distribution terms for this file may be found in the + file LICENSE in this distribution or at + http://www.OARcorp.com/rtems/license.html. + + ------------------------------------------------------------------------ + + rtemsMessageQueue class. + + This class allows the user to create a RTEMS message queue, or to + access and manage an already existing message queue. + + The first constructor with the message queue parameters creates a + RTEMS message queue object. The destructor of this object also + deletes the message queue object. The last status code should be + checked after construction to see if the create completed + successfully. + + The second constructor connects to an existing message queue + object. The last status code should be checked after construction to + see if the message queue existed. + + The third constructor is a copy constructor. Connects to an existing + object which is in scope. + + The fourth constructor allows for the message queue to be created + after construction, or to connect to a message queue later. + + ------------------------------------------------------------------------ */ + +#if !defined(_rtemsMessageQueue_h_) +#define _rtemsMessageQueue_h_ + +#include + +/* ---- + rtemsMessageQueue +*/ + +class rtemsMessageQueue + : public rtemsStatusCode +{ +public: + // attribute a message queue can have + enum WaitMode { wait_by_fifo = RTEMS_FIFO, + wait_by_priority = RTEMS_PRIORITY }; + enum Scope { local = RTEMS_LOCAL, + global = RTEMS_GLOBAL }; + + // only the first 4 characters of the name are taken + + // creates a message queue + rtemsMessageQueue(const char* name, + const rtems_unsigned32 count, + const rtems_unsigned32 max_message_size, + const WaitMode wait_mode = wait_by_fifo, + const Scope scope = local); + + // connects to a message queue + rtemsMessageQueue(const char *name, const rtems_unsigned32 node = RTEMS_SEARCH_ALL_NODES); + + // copy and default constructors + rtemsMessageQueue(const rtemsMessageQueue& message_queue); + rtemsMessageQueue(); + + // only the creator's destructor will delete the actual object + virtual ~rtemsMessageQueue(); + + // create or destroy (delete) the message queue + virtual const rtems_status_code create(const char* name, + const rtems_unsigned32 count, + const rtems_unsigned32 max_message_size, + const WaitMode wait_mode = wait_by_fifo, + const Scope scope = local); + virtual const rtems_status_code destroy(); + + // connect to an existing message queue object, will not be the owner + const rtemsMessageQueue& operator=(const rtemsMessageQueue& message_queue); + virtual const rtems_status_code connect(const char *name, + const rtems_unsigned32 node = RTEMS_SEARCH_ALL_NODES); + + // send a message of size from the buffer + inline const rtems_status_code send(const void *buffer, + const rtems_unsigned32 size); + inline const rtems_status_code urgent(const void *buffer, + const rtems_unsigned32 size); + inline const rtems_status_code broadcast(const void *buffer, + const rtems_unsigned32 size, + rtems_unsigned32& count); + + // receive a message of size, the timeout is in micro-secs + inline const rtems_status_code receive(const void *buffer, + rtems_unsigned32& size, + rtems_interval micro_secs = RTEMS_NO_TIMEOUT, + bool wait = true); + + // flush a message queue, returning the number of messages dropped + inline const rtems_status_code flush(rtems_unsigned32& size); + + // object id, and name + const rtems_id id_is() const { return id; } + const rtems_name name_is() const { return name; } + const char *name_string() const { return name_str; } + +private: + + // make this object reference an invalid RTEMS object + void make_invalid(); + + // message queue name + rtems_name name; + char name_str[5]; + + // owner, true if this object owns the message queue + // will delete the message queue when it destructs + bool owner; + + // the rtems id, object handle + rtems_id id; +}; + +const rtems_status_code rtemsMessageQueue::send(const void *buffer, + const rtems_unsigned32 size) +{ + return set_status_code(rtems_message_queue_send(id, (void*) buffer, size)); +} + +const rtems_status_code rtemsMessageQueue::urgent(const void *buffer, + const rtems_unsigned32 size) +{ + return set_status_code(rtems_message_queue_urgent(id, (void*) buffer, size)); +} + +const rtems_status_code rtemsMessageQueue::broadcast(const void *buffer, + const rtems_unsigned32 size, + rtems_unsigned32& count) +{ + return set_status_code(rtems_message_queue_broadcast(id, + (void*) buffer, + size, + &count)); +} + +const rtems_status_code rtemsMessageQueue::receive(const void *buffer, + rtems_unsigned32& size, + rtems_interval micro_secs, + bool wait) +{ + rtems_interval usecs = + micro_secs && (micro_secs < _TOD_Microseconds_per_tick) ? + _TOD_Microseconds_per_tick : micro_secs; + return set_status_code(rtems_message_queue_receive(id, + (void*) buffer, + &size, + wait ? RTEMS_WAIT : RTEMS_NO_WAIT, + TOD_MICROSECONDS_TO_TICKS(usecs))); +} + +const rtems_status_code rtemsMessageQueue::flush(rtems_unsigned32& count) +{ + return set_status_code(rtems_message_queue_flush(id, &count)); +} + +#endif // _rtemsMessageQueue_h_ + + + + diff --git a/c/src/lib/include/rtems++/rtemsSemaphore.h b/c/src/lib/include/rtems++/rtemsSemaphore.h new file mode 100644 index 0000000000..9d4fdbeb58 --- /dev/null +++ b/c/src/lib/include/rtems++/rtemsSemaphore.h @@ -0,0 +1,145 @@ +/* + ------------------------------------------------------------------------ + $Id$ + ------------------------------------------------------------------------ + + COPYRIGHT (c) 1997 + Objective Design Systems Ltd Pty (ODS) + All rights reserved (R) Objective Design Systems Ltd Pty + + The license and distribution terms for this file may be found in the + file LICENSE in this distribution or at + http://www.OARcorp.com/rtems/license.html. + + ------------------------------------------------------------------------ + + rtemsSemaphore class. + + This class allows the user to create a RTEMS semaphore, or to use an + already existing semaphore. The type of semaphore is decitated by + the constructor used. + + The first constructor with the semaphore parameters creates a RTEMS + semaphore object. The destructor of this object also deletes the + semaphore object. The last status code should be checked after + construction to see if the semaphore create was successfull. + + The second constructor connects to an existing. The last status code + should be checked after construction to see if the semaphore + existed. + + The third constructor is a copy constructor. Connects to an existing + object which is in scope. + + ------------------------------------------------------------------------ */ + +#if !defined(_rtemsSemaphore_h_) +#define _rtemsSemaphore_h_ + +#include + +/* ---- + rtemsSemaphore +*/ + +class rtemsSemaphore + : public rtemsStatusCode +{ +public: + // attribute a semaphore can have + enum WaitMode { wait_by_fifo = RTEMS_FIFO, + wait_by_priority = RTEMS_PRIORITY }; + enum Type { binary = RTEMS_BINARY_SEMAPHORE, + counting = RTEMS_COUNTING_SEMAPHORE }; + enum Priority { no_priority_inherit = RTEMS_NO_INHERIT_PRIORITY, + inherit_priority = RTEMS_INHERIT_PRIORITY }; + enum Ceiling { no_priority_ceiling = RTEMS_NO_PRIORITY_CEILING, + priority_ceiling = RTEMS_PRIORITY_CEILING }; + enum Scope { local = RTEMS_LOCAL, + global = RTEMS_GLOBAL }; + + // only the first 4 characters of the name are taken, + // the counter must be set to 1 for binary semaphores + + // create a semaphore object + rtemsSemaphore(const char* name, + const Scope scope = local, + const rtems_unsigned32 counter = 1, + const WaitMode wait_mode = wait_by_fifo, + const Type type = binary, + const Priority priority = no_priority_inherit, + const Ceiling ceiling = no_priority_ceiling, + const rtems_task_priority priority_ceiling = 0); + + // connect to an existing semaphore object by name + rtemsSemaphore(const char *name, const rtems_unsigned32 node); + + // attach this object to an other objects semaphore + rtemsSemaphore(const rtemsSemaphore& semaphore); + rtemsSemaphore(); + + // only the creator's destructor will delete the actual object + virtual ~rtemsSemaphore(); + + // create or destroy (delete) a semaphore + virtual const rtems_status_code create(const char* name, + const Scope scope = local, + const rtems_unsigned32 counter = 1, + const WaitMode wait_mode = wait_by_fifo, + const Type type = binary, + const Priority priority = no_priority_inherit, + const Ceiling ceiling = no_priority_ceiling, + const rtems_task_priority priority_ceiling = 0); + virtual const rtems_status_code destroy(); + + // connect to an existing semaphore object, will not be the owner + const rtemsSemaphore& operator=(const rtemsSemaphore& semaphore); + virtual const rtems_status_code connect(const char *name, rtems_unsigned32 node); + + // obtain the semaphore, timeout is in micro-seconds + inline const rtems_status_code obtain(bool wait = true, + const rtems_unsigned32 micro_secs = RTEMS_NO_TIMEOUT); + + // release the semaphore, blocks threads eligble + inline const rtems_status_code release(); + + // object id, and name + const rtems_id id_is() const { return id; } + const rtems_name name_is() const { return name; } + const char *name_string() const { return name_str; } + +private: + + // make the object reference no valid RTEMS object + void make_invalid(); + + // semaphore name + rtems_name name; + char name_str[5]; + + // owner, true if this object owns the semaphore + // will delete the semaphore when it destructs + bool owner; + + // the rtems id, object handle + rtems_id id; +}; + +const rtems_status_code rtemsSemaphore::obtain(const bool wait, + const rtems_unsigned32 micro_secs) +{ + rtems_interval usecs = + micro_secs && (micro_secs < _TOD_Microseconds_per_tick) ? + _TOD_Microseconds_per_tick : micro_secs; + return + set_status_code(rtems_semaphore_obtain(id, + wait ? RTEMS_WAIT : RTEMS_NO_WAIT, + TOD_MICROSECONDS_TO_TICKS(usecs))); +} + +const rtems_status_code rtemsSemaphore::release(void) +{ + return set_status_code(rtems_semaphore_release(id)); +} + +#endif // _rtemsSemaphore_h_ diff --git a/c/src/lib/include/rtems++/rtemsStatusCode.h b/c/src/lib/include/rtems++/rtemsStatusCode.h new file mode 100644 index 0000000000..fee230868b --- /dev/null +++ b/c/src/lib/include/rtems++/rtemsStatusCode.h @@ -0,0 +1,57 @@ +/* + ------------------------------------------------------------------------ + $Id$ + ------------------------------------------------------------------------ + + COPYRIGHT (c) 1997 + Objective Design Systems Ltd Pty (ODS) + All rights reserved (R) Objective Design Systems Ltd Pty + + The license and distribution terms for this file may be found in the + file LICENSE in this distribution or at + http://www.OARcorp.com/rtems/license.html. + + ------------------------------------------------------------------------ + + rtemsStatusCode controls and manages status codes from the RTEMS kernel. + + ------------------------------------------------------------------------ +*/ + +#if !defined(_rtemsStatusCode_h_) +#define _rtemsStatusCode_h_ + +#include + +/* ---- + rtemsStatusCode +*/ + +class rtemsStatusCode +{ +public: + + rtemsStatusCode() { last_status = RTEMS_NOT_CONFIGURED; } + + const bool successful() { return last_status == RTEMS_SUCCESSFUL; } + const bool unsuccessful() { return last_status != RTEMS_SUCCESSFUL; } + + // return the last status code + const rtems_status_code last_status_code() { return last_status; } + + // return the last status as a string + const char *last_status_string(); + + const char *status_string(rtems_status_code status_code); + +protected: + const rtems_status_code set_status_code(const rtems_status_code status) + { return (last_status = status); } + +private: + + // public at the moment, this might change + rtems_status_code last_status; +}; + +#endif // _rtemsStatusCode_h_ diff --git a/c/src/lib/include/rtems++/rtemsTask.h b/c/src/lib/include/rtems++/rtemsTask.h new file mode 100644 index 0000000000..08156428fb --- /dev/null +++ b/c/src/lib/include/rtems++/rtemsTask.h @@ -0,0 +1,171 @@ +/* + ------------------------------------------------------------------------ + $Id$ + ------------------------------------------------------------------------ + + COPYRIGHT (c) 1997 + Objective Design Systems Ltd Pty (ODS) + All rights reserved (R) Objective Design Systems Ltd Pty + + The license and distribution terms for this file may be found in the + file LICENSE in this distribution or at + http://www.OARcorp.com/rtems/license.html. + + ------------------------------------------------------------------------ + + rtemsTask class. + + This class allows the user to create a RTEMS task, or to access and + manage an already existing task. + + The first constructor with the task parameters creates a RTEMS task + object. The destructor of this object also deletes the task + object. The last status code should be checked after construction to + see if the create completed successfully. + + The second constructor connects to an existing task object. The last + status code should be checked after construction to see if the + task existed. + + The third constructor is a copy constructor. Connects to an existing + object which is in scope. + + The RTEMS id is set to self in the default construction. + + The creation of the task object can be defered until after + construction. This allows for static task objects to be created. + + RTEMS should be initialised before static constructors run, how-ever + threads will will not. You need to watch the start-order. + + A task object can change state from an owner of a task to being + connected to a task. + + Task objects connected to another task do not receive notification + when the task connected to changes state. + + The sleep methods operate on the current thread not the task + reference by this object. + + Mode control is through the rtemsTaskMode class. + + The rtemsTask class reserved notepad register 31. + + ------------------------------------------------------------------------ */ + +#if !defined(_rtemsTask_h_) +#define _rtemsTask_h_ + +#include + +/* ---- + rtemsTask +*/ + +class rtemsTask + : public rtemsStatusCode +{ +public: + enum FloatingPoint { fpoff = RTEMS_NO_FLOATING_POINT, + fpon = RTEMS_FLOATING_POINT }; + enum Scope { local = RTEMS_LOCAL, + global = RTEMS_GLOBAL }; + + // only the first 4 characters of the name are taken + + // creates a task + rtemsTask(const char* name, + const rtems_task_priority initial_priority, + const rtems_unsigned32 stack_size, + const rtems_mode preemption = RTEMS_NO_PREEMPT, + const rtems_mode timeslice = RTEMS_NO_TIMESLICE, + const rtems_mode asr = RTEMS_NO_ASR, + const rtems_interrupt_level interrupt_level = 0, + const FloatingPoint floating_point = fpoff, + const Scope scope = local); + + // connects to a task + rtemsTask(const char *name, const rtems_unsigned32 node = RTEMS_SEARCH_ALL_NODES); + + // copy and default constructors + rtemsTask(const rtemsTask& task); + rtemsTask(); + + // only the creator's destructor will delete the actual object + virtual ~rtemsTask(); + + // create or destroy (delete) the task + virtual const rtems_status_code create(const char* name, + const rtems_task_priority initial_priority, + const rtems_unsigned32 stack_size, + const rtems_mode preemption = RTEMS_NO_PREEMPT, + const rtems_mode timeslice = RTEMS_NO_TIMESLICE, + const rtems_mode asr = RTEMS_NO_ASR, + const rtems_interrupt_level interrupt_level = 0, + const FloatingPoint floating_point = fpoff, + const Scope scope = local); + virtual const rtems_status_code destroy(); + + // connect to an existing task object, will not be the owner + const rtemsTask& operator=(const rtemsTask& task); + virtual const rtems_status_code connect(const char *name, + const rtems_unsigned32 node = RTEMS_SEARCH_ALL_NODES); + + // run control + virtual const rtems_status_code start(const rtems_task_argument argument); + virtual const rtems_status_code restart(const rtems_task_argument argument); + virtual const rtems_status_code suspend(); + virtual const rtems_status_code resume(); + + // sleep control, the timeout is in micro-seconds + virtual const rtems_status_code wake_after(const rtems_interval micro_secs); + virtual const rtems_status_code wake_when(const rtems_time_of_day& tod); + + // priority control + const rtems_status_code get_priority(rtems_task_priority& priority); + const rtems_status_code set_priority(const rtems_task_priority priority); + const rtems_status_code set_priority(const rtems_task_priority priority, + rtems_task_priority& old_priority); + + // notepad control + const rtems_status_code get_note(const rtems_unsigned32 notepad, + rtems_unsigned32& note); + const rtems_status_code set_note(const rtems_unsigned32 notepad, + const rtems_unsigned32 note); + + // object id, and name + const rtems_id id_is() const { return id; } + const rtems_name name_is() const { return name; } + const char *name_string() const { return name_str; } + +protected: + + // task entry point + virtual void body(rtems_task_argument argument); + +private: + + // make the object to point to RTEMS_SELF + void make_self(); + + // task name + rtems_name name; + char name_str[5]; + + // owner, true if this object owns the task + // will delete the task when it destructs + bool owner; + + // the rtems id, object handle + rtems_id id; + + // the argument for the task, this class uses the actual argument + // passed to RTEMS + rtems_task_argument argument; + + // common entry point to the task + static rtems_task origin(rtems_task_argument argument); +}; + +#endif // _rtemsTask_h_ + diff --git a/c/src/lib/include/rtems++/rtemsTaskMode.h b/c/src/lib/include/rtems++/rtemsTaskMode.h new file mode 100644 index 0000000000..6d32897cc0 --- /dev/null +++ b/c/src/lib/include/rtems++/rtemsTaskMode.h @@ -0,0 +1,210 @@ +/* + ------------------------------------------------------------------------ + $Id$ + ------------------------------------------------------------------------ + + COPYRIGHT (c) 1997 + Objective Design Systems Ltd Pty (ODS) + All rights reserved (R) Objective Design Systems Ltd Pty + + The license and distribution terms for this file may be found in the + file LICENSE in this distribution or at + http://www.OARcorp.com/rtems/license.html. + + ------------------------------------------------------------------------ + + rtemsTaskMode class. + + This class allows the user to query or change the mode of an RTEMS + task. + + This object only operates on the currently executing task. + + The standard flags defined in RTEMS are used. + + Methods are provided to operate on a group of modes which are + required to be changed in a single operation. The mode and mask is + specified by ORing the required flags. + + Methods are provided for accessing and controlling a specific + mode. The returned value will only contain the requested mode's flags, + and only the that mode will be changed when setting a mode. + + ------------------------------------------------------------------------ */ + +#if !defined(_rtemsTaskMode_h_) +#define _rtemsTaskMode_h_ + +#include + +/* ---- + rtemsTaskMode +*/ + +class rtemsTaskMode + : public rtemsStatusCode +{ +public: + + rtemsTaskMode() {}; + + // group mode control, OR the values together + inline const rtems_status_code get_mode(rtems_mode& mode); + inline const rtems_status_code set_mode(const rtems_mode mode, + const rtems_mode mask); + inline const rtems_status_code set_mode(const rtems_mode mode, + const rtems_mode mask, + rtems_mode& old_mode); + + // preemption control + inline const rtems_status_code get_preemption_state(rtems_mode& preemption); + inline const rtems_status_code set_preemption_state(const rtems_mode preemption); + inline const rtems_status_code set_preemption_state(const rtems_mode preemption, + rtems_mode& old_preemption); + inline const boolean preemption_set(const rtems_mode preemption); + + // timeslice control + inline const rtems_status_code get_timeslice_state(rtems_mode& timeslice); + inline const rtems_status_code set_timeslice_state(const rtems_mode timeslice); + inline const rtems_status_code set_timeslice_state(const rtems_mode timeslice, + rtems_mode& old_timeslice); + inline const boolean timeslice_set(const rtems_mode preemption); + + // async-sub-routine control + inline const rtems_status_code get_asr_state(rtems_mode& asr); + inline const rtems_status_code set_asr_state(const rtems_mode asr); + inline const rtems_status_code set_asr_state(const rtems_mode asr, + rtems_mode& old_asr); + inline const boolean asr_set(const rtems_mode preemption); + + // interrupt mask control + inline const rtems_status_code get_interrupt_level(rtems_interrupt_level& level); + inline const rtems_status_code set_interrupt_level(const rtems_interrupt_level level); + inline const rtems_status_code set_interrupt_level(const rtems_interrupt_level level, + rtems_interrupt_level& old_level); +}; + +const rtems_status_code rtemsTaskMode::get_mode(rtems_mode& mode) +{ + return set_status_code(rtems_task_mode(0, RTEMS_CURRENT_MODE, &mode)); +} + +const rtems_status_code rtemsTaskMode::set_mode(const rtems_mode mode, + const rtems_mode mask) +{ + rtems_mode old_mode; + return set_status_code(rtems_task_mode(mode, mask, &old_mode)); +} + +const rtems_status_code rtemsTaskMode::set_mode(const rtems_mode mode, + const rtems_mode mask, + rtems_mode& old_mode) +{ + return set_status_code(rtems_task_mode(mode, mask, &old_mode)); +} + +const rtems_status_code rtemsTaskMode::get_preemption_state(rtems_mode& preemption) +{ + set_status_code(rtems_task_mode(0, RTEMS_CURRENT_MODE, &preemption)); + preemption &= RTEMS_PREEMPT_MASK; + return last_status_code(); +} + +const rtems_status_code rtemsTaskMode::set_preemption_state(const rtems_mode preemption) +{ + rtems_mode old_mode; + return set_status_code(rtems_task_mode(preemption, RTEMS_PREEMPT_MASK, &old_mode)); +} + +const rtems_status_code rtemsTaskMode::set_preemption_state(const rtems_mode preemption, + rtems_mode& old_preemption) +{ + set_status_code(rtems_task_mode(preemption, RTEMS_PREEMPT_MASK, &old_preemption)); + old_preemption &= RTEMS_PREEMPT_MASK; + return last_status_code(); +} + +const boolean rtemsTaskMode::preemption_set(const rtems_mode preemption) +{ + return (preemption & RTEMS_PREEMPT_MASK) ? false : true; +} + +const rtems_status_code rtemsTaskMode::get_timeslice_state(rtems_mode& timeslice) +{ + set_status_code(rtems_task_mode(0, RTEMS_CURRENT_MODE, ×lice)); + timeslice &= RTEMS_TIMESLICE_MASK; + return last_status_code(); +} + +const rtems_status_code rtemsTaskMode::set_timeslice_state(const rtems_mode timeslice) +{ + rtems_mode old_mode; + return set_status_code(rtems_task_mode(timeslice, RTEMS_TIMESLICE_MASK, &old_mode)); +} + +const rtems_status_code rtemsTaskMode::set_timeslice_state(const rtems_mode timeslice, + rtems_mode& old_timeslice) +{ + set_status_code(rtems_task_mode(timeslice, RTEMS_TIMESLICE_MASK, &old_timeslice)); + old_timeslice &= RTEMS_TIMESLICE_MASK; + return last_status_code(); +} + +const boolean rtemsTaskMode::timeslice_set(const rtems_mode timeslice) +{ + return (timeslice & RTEMS_TIMESLICE_MASK) ? true : false; +} + +const rtems_status_code rtemsTaskMode::get_asr_state(rtems_mode& asr) +{ + set_status_code(rtems_task_mode(0, RTEMS_CURRENT_MODE, &asr)); + asr &= RTEMS_ASR_MASK; + return last_status_code(); +} + +const rtems_status_code rtemsTaskMode::set_asr_state(const rtems_mode asr) +{ + rtems_mode old_mode; + return set_status_code(rtems_task_mode(asr, RTEMS_ASR_MASK, &old_mode)); +} + +const rtems_status_code rtemsTaskMode::set_asr_state(const rtems_mode asr, + rtems_mode& old_asr) +{ + set_status_code(rtems_task_mode(asr, RTEMS_ASR_MASK, &old_asr)); + old_asr &= RTEMS_ASR_MASK; + return last_status_code(); +} + +const boolean rtemsTaskMode::asr_set(const rtems_mode asr) +{ + return (asr & RTEMS_ASR_MASK) ? true : false; +} + +const rtems_status_code rtemsTaskMode::get_interrupt_level(rtems_interrupt_level& level) +{ + rtems_mode mode; + set_status_code(rtems_task_mode(0, RTEMS_CURRENT_MODE, &mode)); + level = mode & RTEMS_INTERRUPT_MASK; + return last_status_code(); +} + +const rtems_status_code rtemsTaskMode::set_interrupt_level(const rtems_interrupt_level level) +{ + rtems_mode old_mode; + return set_status_code(rtems_task_mode(level, RTEMS_INTERRUPT_MASK, &old_mode)); +} + +const rtems_status_code rtemsTaskMode::set_interrupt_level(rtems_interrupt_level level, + rtems_interrupt_level& old_level) +{ + set_status_code(rtems_task_mode(level, RTEMS_INTERRUPT_MASK, &old_level)); + old_level = old_level & RTEMS_INTERRUPT_MASK; + return last_status_code(); +} + +#endif // _rtemsTaskMode_h_ + + + + diff --git a/c/src/lib/include/rtems++/rtemsTimer.h b/c/src/lib/include/rtems++/rtemsTimer.h new file mode 100644 index 0000000000..43401bab73 --- /dev/null +++ b/c/src/lib/include/rtems++/rtemsTimer.h @@ -0,0 +1,145 @@ +/* + ------------------------------------------------------------------------ + $Id$ + ------------------------------------------------------------------------ + + COPYRIGHT (c) 1997 + Objective Design Systems Ltd Pty (ODS) + All rights reserved (R) Objective Design Systems Ltd Pty + + The license and distribution terms for this file may be found in the + file LICENSE in this distribution or at + http://www.OARcorp.com/rtems/license.html. + + ------------------------------------------------------------------------ + + rtemsTimer class. + + This class allows the user to create a RTEMS timer. + + The trigger method is called when the timer expires. The method is + called using the thread which calls the RTEMS 'rtems_clock_tick' + method. + + Timers are always local to a node. + + ------------------------------------------------------------------------ */ + +#if !defined(_rtemsTimer_h_) +#define _rtemsTimer_h_ + +#include + +/* ---- + rtemsTimer +*/ + +class rtemsTimer + : public rtemsStatusCode +{ +public: + // only the first 4 characters of the name are taken, + + // create a timer object + rtemsTimer(const char* name); + rtemsTimer(); + + // destroies the actual object + virtual ~rtemsTimer(); + + // create or destroy (delete) the timer + virtual const rtems_status_code create(const char* name); + virtual const rtems_status_code destroy(); + + // timer control + inline const rtems_status_code fire_after(const rtems_interval micro_secs); + inline const rtems_status_code repeat_fire_at(const rtems_interval micro_secs); + inline const rtems_status_code fire_when(const rtems_time_of_day& when); + + inline const rtems_status_code cancel(); + inline const rtems_status_code reset(); + + // object id, and name + const rtems_id id_is() const { return id; } + const rtems_name name_is() const { return name; } + const char *name_string() const { return name_str; } + +protected: + + // triggered method is called when the timer fires + virtual void triggered() = 0; + +private: + // not permitted + rtemsTimer(const rtemsTimer& timer); + rtemsTimer& operator=(const rtemsTimer& timer); + + // make this object reference an invalid RTEMS object + void make_invalid(); + + // semaphore name + rtems_name name; + char name_str[5]; + + // repeat true restart the timer when it fires + bool repeat; + + // the rtems id, object handle + rtems_id id; + + // common timer handler + static void common_handler(rtems_id id, void *user_data); +}; + +const rtems_status_code rtemsTimer::fire_after(const rtems_interval micro_secs) +{ + repeat = false; + rtems_interval usecs = + micro_secs && (micro_secs < _TOD_Microseconds_per_tick) ? + _TOD_Microseconds_per_tick : micro_secs; + return set_status_code(rtems_timer_fire_after(id, + TOD_MICROSECONDS_TO_TICKS(usecs), + common_handler, + this)); +} + +const rtems_status_code rtemsTimer::repeat_fire_at(const rtems_interval micro_secs) +{ + repeat = true; + rtems_interval usecs = + micro_secs && (micro_secs < _TOD_Microseconds_per_tick) ? + _TOD_Microseconds_per_tick : micro_secs; + return set_status_code(rtems_timer_fire_after(id, + TOD_MICROSECONDS_TO_TICKS(usecs), + common_handler, + this)); +} + +const rtems_status_code rtemsTimer::fire_when(const rtems_time_of_day& when) +{ + return set_status_code(rtems_timer_fire_when(id, + (rtems_time_of_day*) &when, + common_handler, + this)); +} + +const rtems_status_code rtemsTimer::cancel() +{ + repeat = false; + return set_status_code(rtems_timer_cancel(id)); +} + +const rtems_status_code rtemsTimer::reset() +{ + return set_status_code(rtems_timer_reset(id)); +} + +#endif // _rtemsTimer_h_ + + + + + + + + diff --git a/c/src/lib/libbsp/m68k/ods68302/Makefile.in b/c/src/lib/libbsp/m68k/ods68302/Makefile.in new file mode 100644 index 0000000000..bd7ff1f784 --- /dev/null +++ b/c/src/lib/libbsp/m68k/ods68302/Makefile.in @@ -0,0 +1,19 @@ +# +# $Id$ +# + +@SET_MAKE@ +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH=@srcdir@ + +include $(RTEMS_CUSTOM) +include $(PROJECT_ROOT)/make/directory.cfg + +SRCS=README + +all: $(SRCS) + +# wrapup is the one that actually builds and installs the library +# from the individual .rel files built in other directories +SUB_DIRS=include start302 startup clock console timer wrapup diff --git a/c/src/lib/libbsp/m68k/ods68302/README b/c/src/lib/libbsp/m68k/ods68302/README new file mode 100644 index 0000000000..59e36b0953 --- /dev/null +++ b/c/src/lib/libbsp/m68k/ods68302/README @@ -0,0 +1,81 @@ +# +# $Id$ +# + +BSP NAME: ods68302 +BOARD: proprietary (see below for relevant information) +BUS: none +CPU FAMILY: MC68000 +COPROCESSORS: 68302 communications co-processor +MODE: not applicable + +DEBUG MONITOR: gdb + +PERIPHERALS +=========== +TIMERS: two 68302 timers, one 68302 watchdog timer + RESOLUTION: ? +SERIAL PORTS: three 68302 SCCs +REAL-TIME CLOCK: +DMA: built-in 68302, not used +VIDEO: none +SCSI: none +NETWORKING: none + +DRIVER INFORMATION +================== +CLOCK DRIVER: 68302 (TIMER1) +IOSUPP DRIVER: 68302 SCC2 +SHMSUPP: none +TIMER DRIVER: 68302 TIMER2 + +STDIO +===== +PORT: SCC3 for ROM build, SCC1 for DEGUB build +ELECTRICAL: EIA-232 +BAUD: 9600 +BITS PER CHARACTER: 8 +PARITY: None +STOP BITS: 1 + +DEBUG MONITOR +============= +PORT: SCC3 +ELECTRICAL: EIA-232 +BAUD: 57600 +BITS PER CHARACTER: 8 +PARITY: None +STOP BITS: 1 + +NOTES +===== + +This BSP is based on the gen68302. The main differences are C code for +boot parameters, the gdb monitor, and variant support. + +The boot code which changes is written in C and the parameters used to +control the configuration of the chip select registers and parallel +ports are held in variant specific header files. These file also +control the other hardware specific definitions such the processor +freqency. + +The gdb monitor currently uses two serial ports. One for the debugger +and one for stdio. This is costly in terms of the 68302 processor. + +The build configuration contains the memory map. The bsp code does not +contain any memory map parameters. That is the ods68302.cfg contains +the link addresses. + +To build a version to download via gdb use the command line parameters +to make or "RTEMS_DEBUGGER=yes". This will change the memory map to +place the code, and data above the RAM used by the gdb stub. + +TODO +==== + +1) Lower the set size of the gdb monitor. This can be made to be about +10K or RAM. The code is about 14K. + +2) Add the production memory test code. This will be C and asm +code. The asm will be a faster version of the C. + diff --git a/c/src/lib/libbsp/m68k/ods68302/bsp_specs b/c/src/lib/libbsp/m68k/ods68302/bsp_specs new file mode 100644 index 0000000000..5b49fcc79b --- /dev/null +++ b/c/src/lib/libbsp/m68k/ods68302/bsp_specs @@ -0,0 +1,34 @@ + +predefines: +-D__embedded__ -Asystem(embedded) + +startfile: replace +mrtems: +pg: reset.o%s +{!pg: +g: reset.o%s +{!g: +p: reset.o%s +!p: reset.o%s +}} +{!mrtems: +pg: pgcrt0%O +{!pg: +g: gcrt0%O +{!g: +p: pcrt0%O +!p: crt0%O +}}} + + +link: replace +mrtems: -dc -dp -N -T linkcmds%s -e start + +lib: replace +mrtems: -( -lc -lrtemsall -lgcc -) + + +libgcc: replace + + + diff --git a/c/src/lib/libbsp/m68k/ods68302/clock/Makefile.in b/c/src/lib/libbsp/m68k/ods68302/clock/Makefile.in new file mode 100644 index 0000000000..8e325402ca --- /dev/null +++ b/c/src/lib/libbsp/m68k/ods68302/clock/Makefile.in @@ -0,0 +1,53 @@ +# +# $Id$ +# + +@SET_MAKE@ +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH=@srcdir@ + +PGM=${ARCH}/clock.rel + +# C source names, if any, go here -- minus the .c +C_PIECES=ckinit +C_FILES=$(C_PIECES:%=%.c) +C_O_FILES=$(C_PIECES:%=${ARCH}/%.o) + +H_FILES= + +SRCS=$(C_FILES) $(H_FILES) +OBJS=$(C_O_FILES) + +include $(RTEMS_CUSTOM) +include $(PROJECT_ROOT)/make/leaf.cfg + +# +# (OPTIONAL) Add local stuff here using += +# + +DEFINES += +CPPFLAGS += +CFLAGS += + +LD_PATHS += +LD_LIBS += +LDFLAGS += + +# +# Add your list of files to delete here. The config files +# already know how to delete some stuff, so you may want +# to just run 'make clean' first to see what gets missed. +# 'make clobber' already includes 'make clean' +# + +CLEAN_ADDITIONS += +CLOBBER_ADDITIONS += + +${PGM}: ${SRCS} ${OBJS} + $(make-rel) + +all: ${ARCH} $(SRCS) $(PGM) + +# the .rel file built here will be put into libbsp.a by ../wrapup/Makefile +install: all diff --git a/c/src/lib/libbsp/m68k/ods68302/clock/ckinit.c b/c/src/lib/libbsp/m68k/ods68302/clock/ckinit.c new file mode 100644 index 0000000000..f5745821f4 --- /dev/null +++ b/c/src/lib/libbsp/m68k/ods68302/clock/ckinit.c @@ -0,0 +1,162 @@ +/* Clock_init() + * + * This routine initializes Timer 1 for an MC68302. + * The tick frequency is 1 millisecond. + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * COPYRIGHT (c) 1989-1997. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may in + * the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + +#include /* for atexit() */ + +#include +#include + +#include "m68302.h" + +#define CLOCK_VECTOR 137 + +#define TMR1_VAL ( RBIT_TMR_RST /* software reset the timer */\ + | RBIT_TMR_ICLK_MASTER16 /* master clock divided by 16 */\ + | RBIT_TMR_FRR /* restart timer after ref reached */\ + | RBIT_TMR_ORI) /* enable interrupt when ref reached */ +#define TRR1_VAL 1000 /* 1000 ticks @ 16MHz/16 + * = 1 millisecond tick. + */ + +/* + * 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; + +void Clock_exit( void ); + +/* + * These are set by clock driver during its init + */ + +rtems_device_major_number rtems_clock_major = ~0; +rtems_device_minor_number rtems_clock_minor; + +/* + * ISR Handler + */ + +rtems_isr Clock_isr( + rtems_vector_number vector +) +{ + Clock_driver_ticks += 1; + + m302.reg.isr = RBIT_ISR_TIMER1; /* clear in-service bit */ + m302.reg.ter1 = (RBIT_TER_REF | RBIT_TER_CAP); /* clear timer intr request */ + + if ( Clock_isrs == 1 ) { + rtems_clock_tick(); + Clock_isrs = BSP_Configuration.microseconds_per_tick / 1000; + } + else + Clock_isrs -= 1; +} + +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 ) { + set_vector( clock_isr, CLOCK_VECTOR, 1 ); + + m302.reg.trr1 = TRR1_VAL; /* set timer reference register */ + m302.reg.tmr1 = TMR1_VAL; /* set timer mode register & enable */ + /* + * Enable TIMER1 interrupts only. + */ + m302.reg.imr = RBIT_IMR_TIMER1; /* set 68302 int-mask to allow ints */ + + atexit( Clock_exit ); + } +} + +void Clock_exit( void ) +{ + if ( BSP_Configuration.ticks_per_timeslice ) { + /* TODO: figure out what to do here */ + /* do not restore old vector */ + } +} + +rtems_device_driver Clock_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *pargp +) +{ + Install_clock( Clock_isr ); + + /* + * make major/minor avail to others such as shared memory driver + */ + + rtems_clock_major = major; + rtems_clock_minor = minor; + + return RTEMS_SUCCESSFUL; +} + +rtems_device_driver Clock_control( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *pargp +) +{ + rtems_unsigned32 isrlevel; + rtems_libio_ioctl_args_t *args = pargp; + + if (args == 0) + goto done; + + /* + * This is hokey, but until we get a defined interface + * to do this, it will just be this simple... + */ + + if (args->command == rtems_build_name('I', 'S', 'R', ' ')) + { + Clock_isr( CLOCK_VECTOR); + } + else if (args->command == rtems_build_name('N', 'E', 'W', ' ')) + { + rtems_interrupt_disable( isrlevel ); + (void) set_vector( args->buffer, CLOCK_VECTOR, 1 ); + rtems_interrupt_enable( isrlevel ); + } + +done: + return RTEMS_SUCCESSFUL; +} + diff --git a/c/src/lib/libbsp/m68k/ods68302/console/Makefile.in b/c/src/lib/libbsp/m68k/ods68302/console/Makefile.in new file mode 100644 index 0000000000..ff608c8496 --- /dev/null +++ b/c/src/lib/libbsp/m68k/ods68302/console/Makefile.in @@ -0,0 +1,53 @@ +# +# $Id$ +# + +@SET_MAKE@ +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH=@srcdir@ + +PGM=${ARCH}/console.rel + +# C source names, if any, go here -- minus the .c +C_PIECES=console +C_FILES=$(C_PIECES:%=%.c) +C_O_FILES=$(C_PIECES:%=${ARCH}/%.o) + +H_FILES= + +SRCS=$(C_FILES) $(H_FILES) +OBJS=$(C_O_FILES) + +include $(RTEMS_CUSTOM) +include $(PROJECT_ROOT)/make/leaf.cfg + +# +# (OPTIONAL) Add local stuff here using += +# + +DEFINES += +CPPFLAGS += +CFLAGS += + +LD_PATHS += +LD_LIBS += +LDFLAGS += + +# +# Add your list of files to delete here. The config files +# already know how to delete some stuff, so you may want +# to just run 'make clean' first to see what gets missed. +# 'make clobber' already includes 'make clean' +# + +CLEAN_ADDITIONS += +CLOBBER_ADDITIONS += + +${PGM}: ${SRCS} ${OBJS} + $(make-rel) + +all: ${ARCH} $(SRCS) $(PGM) + +# the .rel file built here will be put into libbsp.a by ../wrapup/Makefile +install: all diff --git a/c/src/lib/libbsp/m68k/ods68302/console/console.c b/c/src/lib/libbsp/m68k/ods68302/console/console.c new file mode 100644 index 0000000000..bc33925f81 --- /dev/null +++ b/c/src/lib/libbsp/m68k/ods68302/console/console.c @@ -0,0 +1,221 @@ +/* + * Initialize the MC68302 SCC2 for console IO board support package. + * + * COPYRIGHT (c) 1989-1997. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may in + * the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + +#define GEN68302_INIT + +#include +#include +#include + +/* 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_status_code status; + +/* debug_port_initialise(); */ + + status = rtems_io_register_name( + "/dev/console", + major, + (rtems_device_minor_number) 0 + ); + + if (status != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred(status); + + return RTEMS_SUCCESSFUL; + +} + +/* is_character_ready + * + * Check to see if a character is available on the MC68302's SCC2. If so, + * then return a TRUE (along with the character). Otherwise return FALSE. + * + * Input parameters: pointer to location in which to return character + * + * Output parameters: character (if available) + * + * Return values: TRUE - character available + * FALSE - no character available + */ + +rtems_boolean is_character_ready( + char *ch /* -> character */ +) +{ + if (debug_port_status(0)) + { + ch = debug_port_in(); + return TRUE; + } + return FALSE; +} + + +/* inbyte + * + * Receive a character from the MC68302's SCC2. + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * Return values: character read + */ + +char inbyte( void ) +{ + char ch; + + while (!is_character_ready(&ch)); + + return ch; +} + + +/* outbyte + * + * Transmit a character out on the MC68302's SCC2. + * It may support XON/XOFF flow control. + * + * Input parameters: + * ch - character to be transmitted + * + * Output parameters: NONE + */ + +void outbyte( + char ch +) +{ + debug_port_out(ch); +} + +/* + * Open entry point + */ + +rtems_device_driver console_open( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + return RTEMS_SUCCESSFUL; +} + +/* + * Close entry point + */ + +rtems_device_driver console_close( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + return RTEMS_SUCCESSFUL; +} + +/* + * read bytes from the serial port. We only have stdin. + */ + +rtems_device_driver console_read( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + rtems_libio_rw_args_t *rw_args; + char *buffer; + int maximum; + int count = 0; + + rw_args = (rtems_libio_rw_args_t *) arg; + + buffer = rw_args->buffer; + maximum = rw_args->count; + + for (count = 0; count < maximum; count++) { + buffer[ count ] = inbyte(); + if (buffer[ count ] == '\n' || buffer[ count ] == '\r') { + buffer[ count++ ] = '\n'; + buffer[ count ] = 0; + break; + } + } + + rw_args->bytes_moved = count; + return (count >= 0) ? RTEMS_SUCCESSFUL : RTEMS_UNSATISFIED; +} + +/* + * write bytes to the serial port. Stdout and stderr are the same. + */ + +rtems_device_driver console_write( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + int count; + int maximum; + rtems_libio_rw_args_t *rw_args; + char *buffer; + + rw_args = (rtems_libio_rw_args_t *) arg; + + buffer = rw_args->buffer; + maximum = rw_args->count; + + for (count = 0; count < maximum; count++) { + if ( buffer[ count ] == '\n') { + outbyte('\r'); + } + outbyte( buffer[ count ] ); + } + + rw_args->bytes_moved = maximum; + return 0; +} + +/* + * IO Control entry point + */ + +rtems_device_driver console_control( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + return RTEMS_SUCCESSFUL; +} diff --git a/c/src/lib/libbsp/m68k/ods68302/include/Makefile.in b/c/src/lib/libbsp/m68k/ods68302/include/Makefile.in new file mode 100644 index 0000000000..a999dff621 --- /dev/null +++ b/c/src/lib/libbsp/m68k/ods68302/include/Makefile.in @@ -0,0 +1,35 @@ +# +# $Id$ +# + +@SET_MAKE@ +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH=@srcdir@ + +H_FILES = $(srcdir)/bare.h $(srcdir)/bsp.h \ + $(srcdir)/coverhd.h $(srcdir)/crc.h \ + $(srcdir)/debugport.h \ + $(srcdir)/m68302scc.h + +# +# Equate files are for including from assembly preprocessed by +# gm4 or gasp. No examples are provided except for those for +# other CPUs. The best way to generate them would be to +# provide a program which generates the constants used based +# on the C equivalents. +# + +EQ_FILES = + +SRCS=$(H_FILES) $(EQ_FILES) + +include $(RTEMS_CUSTOM) +include $(PROJECT_ROOT)/make/leaf.cfg + +CLEAN_ADDITIONS += +CLOBBER_ADDITIONS += + +all: $(SRCS) + $(INSTALL) -m 444 $(H_FILES) ${PROJECT_RELEASE}/include + $(INSTALL) -m 444 $(EQ_FILES) ${PROJECT_RELEASE}/include diff --git a/c/src/lib/libbsp/m68k/ods68302/include/bare.h b/c/src/lib/libbsp/m68k/ods68302/include/bare.h new file mode 100644 index 0000000000..7632b27ded --- /dev/null +++ b/c/src/lib/libbsp/m68k/ods68302/include/bare.h @@ -0,0 +1,246 @@ +/*****************************************************************************/ +/* + $Id$ + + Card Definition for a bare board. + + This is an example file which actually builds a BSP for a 68302 card + called an MVF (Multi-Voice-Frequency). The card is one of a range + which run in a 100Mbit voice/video/data switch used for high end + applications such as Air Traffic Control. The transport is + FDDI-2. Yes it alive and well and working in real systems. + + Chip selects are programmed as required. Three are controlled in the + boot code. They are RAM, ROM, and peripherals. You can optionally + configure the other two chip selects. + + SYSTEM_CLOCK - You must defined this. It is used for setting the + baud rate. + + CSEL_ROM, CSEL_RAM - Must be defined, and made to be a single number + with brackets. + + ROM_WAIT_STATES, RAM_WAIT_STATES - Must be defined. This sets the + speed for the ROM and RAM. + + ROM and RAM size is passed on the command line. The makefile holds + them. This allows a single place to defined it. The makefile allows + them to be passed to the linker. + + CSEL_1, CSEL_2 - If defined the other macros needed to define the + chip select must be defined. If not defined they are not programmed + and registers are left in the reset state. + + Card Specific Devices - The MVF card uses a chip select to address a + range of peripherials (CSEL_2). These include front panel leds, and + 4 digit diagnostic display device. Put what ever you need. + + LED_CONTROL - If defined the boot code will set leds as it goes. + + UPDATE_DISPLAY - A four digit display device will also be updated to + show the boot state. + + CARD_PA, CARD_PB - The default configuration, data direction and + data must be specified. + + This file allows a range of common parameters which vary from one + variant of card to another to placed in a central file. + +*/ +/*****************************************************************************/ + +#ifndef _BARE_H_ +#define _BARE_H_ + +#if __cplusplus +extern "C" +{ +#endif + +/* name of the card */ +#define CARD_ID "m68302-odsbare" + +/* speed of the processor */ +#define SYSTEM_CLOCK (15360000) + +#define SCR_DEFAULT (RBIT_SCR_IPA | RBIT_SCR_HWT | RBIT_SCR_WPV | RBIT_SCR_ADC | \ + RBIT_SCR_HWDEN | RBIT_SCR_HWDCN1 | RBIT_SCR_EMWS) + +/* define the chip selects */ +#define CSEL_ROM 0 /* token pasted so no brackets */ +#define ROM_WAIT_STATES (OR_DTACK_1) /* 100nsec at 16MHz */ +#define CSEL_RAM 3 +#define RAM_WAIT_STATES (OR_DTACK_0) /* 70nsec at 16MHz */ + +/* The remaining chip selects are called 1 and 2 */ +/* +#define CSEL_1 1 +#define CSEL_1_BASE (0x00?00000) +#define CSEL_1_SIZE (0x00?00000) +#define CSEL_1_WAIT_STATES (OR_DTACK_1) +*/ +#define CSEL_2 2 +#define CSEL_2_BASE (0x00800000) +#define CSEL_2_SIZE (0x00040000) +#define CSEL_2_WAIT_STATES (OR_DTACK_EXT) + +/* + * Need to define a watchdog period + */ +#define WATCHDOG_TIMEOUT_PERIOD (3000 * 2) + +/* + * Console and debug port allocation, 0=SCC1, 2=SCC3 + */ + +#define CONSOLE_PORT 1 +#define CONSOLE_BAUD SCC_9600 +#define DEBUG_PORT 2 +#define DEBUG_BAUD SCC_57600 + +/* ---- + Parallel Port Configuration, and default data directions + + PORT BITS - NAME , WHO , DEFAULT WHAT + ------------------------------------------------------------ + PPA:: 1: 0 - Serial , PERIPHERAL, - + PPA:: 7: 2 - MVF_PPA:7:2 , IO , INPUTS + PPA:: 9: 8 - Serial , PERIPHERAL, - + PPA::15:10 - MVF_PPB:15:10 , IO , INPUTS + + PPB:: 1: 0 - Setup , IO , INPUTS + PPB:: 3: 2 - SYNC_HIGHWAY_1:2 , IO , INPUTS + - SYNC_HIGHWAY_2:3 , IO , INPUTS + PPB:: 4: 4 - HARDWARE_RESET:4 , IO , OUTPUT + PPB:: 6: 5 - SOFTWARE_OVERRIDE_1:6, IO , OUTPUT + - SOFTWARE_OVERRIDE_2:5, IO , OUTPUT + PPB:: 7: 7 - Watchdog , PERIPHERAL, - + PPB::11: 8 - Interrupt , PERIPHERAL, - + PPB::15:12 - Not implemented on the 68302 + + 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 + ------------------------------------------------------ + PACNT 0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 1 = 0x0303 + PBCNT - - - - - - - - 1 0 0 0 0 0 0 0 = 0x0080 + + PADDR 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 = 0x0000 + PBDDR 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 = 0x0070 + + PADAT 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 = 0x0000 + + */ +#define CARD_PA_CONFIGURATION 0x0303 +#define CARD_PB_CONFIGURATION 0x0080 + +#define CARD_PA_DEFAULT_DIRECTIONS 0x0000 +#define CARD_PB_DEFAULT_DIRECTIONS 0x0070 + +#define CARD_PA_DEFAULT_DATA 0x0000 +#define CARD_PB_DEFAULT_DATA (HARDWARE_RESET_DISABLE | \ + SOFTWARE_OVERRIDE_1_DISABLE | \ + SOFTWARE_OVERRIDE_2_DISABLE) + +/* these are specific to the card and are not required */ +#define HARDWARE_RESET_ENABLE 0x0000 +#define HARDWARE_RESET_DISABLE 0x0010 + +#define SOFTWARE_OVERRIDE_1_ENABLE 0x0000 +#define SOFTWARE_OVERRIDE_1_DISABLE 0x0040 +#define SOFTWARE_OVERRIDE_2_ENABLE 0x0000 +#define SOFTWARE_OVERRIDE_2_DISABLE 0x0020 + +/* + * Card Specific Devices, these are not required. Add what ever you + * like here. + */ + +/* Write */ +#define WRITE_REGISTER_8(address, data) \ + *((rtems_unsigned8 *) (address)) = ((rtems_unsigned8) (data)) +#define WRITE_REGISTER_16(address, data) \ + *((rtems_unsigned16 *) (address)) = ((rtems_unsigned16) (data)) +#define WRITE_REGISTER_32(address, data) \ + *((rtems_unsigned32 *) (address)) = ((rtems_unsigned32) (data)) +/* Read */ +#define READ_REGISTER_8(address, data) data = *((rtems_unsigned8 *) (address)) +#define READ_REGISTER_16(address, data) data = *((rtems_unsigned16 *) (address)) +#define READ_REGISTER_32(address, data) data = *((rtems_unsigned32 *) (address)) + +/* CS2 : Peripherials */ +#define PERIPHERIALS_BASE (CSEL_2_BASE) + +#define STATUS_REGISTER_BASE (PERIPHERIALS_BASE + 0x00000000) + +#define PERIPHERIALS_SIZE (0x00040000) + +#define LEDS_BASE (PERIPHERIALS_BASE + 0x00004000) +#define MSC_BASE (PERIPHERIALS_BASE + 0x00008000) +#define SPARE_1_BASE (PERIPHERIALS_BASE + 0x0000C000) +#define DISPLAY_BASE (PERIPHERIALS_BASE + 0x00010000) +#define PIO_INT_BASE (PERIPHERIALS_BASE + 0x00014000) +#define UART_BASE (PERIPHERIALS_BASE + 0x00018000) +#define PIA_BASE (PERIPHERIALS_BASE + 0x0001C000) + +#define LED_1 0x0002 +#define LED_1_GREEN 0xFFFD +#define LED_1_RED 0xFFFF +#define LED_1_OFF 0xFFFC + +#define LED_2 0x0001 +#define LED_2_GREEN 0xFFFE +#define LED_2_RED 0xFFFF +#define LED_2_OFF 0xFFFC + +#define LED_3 0x0000 +#define LED_3_GREEN 0xFFFC +#define LED_3_RED 0xFFFC +#define LED_3_OFF 0xFFFC + +#define LED_4 0x0000 +#define LED_4_GREEN 0xFFFC +#define LED_4_RED 0xFFFC +#define LED_4_OFF 0xFFFC + +#define LED_5 0x0000 +#define LED_5_GREEN 0xFFFC +#define LED_5_RED 0xFFFC +#define LED_5_OFF 0xFFFC + +#define LED_6 0x0000 +#define LED_6_GREEN 0xFFFC +#define LED_6_RED 0xFFFC +#define LED_6_OFF 0xFFFC + +#define LED_7 0x0000 +#define LED_7_GREEN 0xFFFC +#define LED_7_RED 0xFFFC +#define LED_7_OFF 0xFFFC + +#define LED_8 0x0000 +#define LED_8_GREEN 0xFFFC +#define LED_8_RED 0xFFFC +#define LED_8_OFF 0xFFFC + +#define MAKE_LED(L1, L2, L3, L4) ((L1 & LED_1) | (L2 & LED_2) | (L3 & LED_3) | (L4 & LED_4)) + +#define LED_CONTROL(L1, L2, L3, L4, L5, L6, L7, L8) \ + WRITE_REGISTER_16(LEDS_BASE, MAKE_LED(L1, L2, L3, L4)) + + /* update the display, needs a long word */ +#define UPDATE_DISPLAY(LongWordPtr) \ + ( WRITE_REGISTER_16(DISPLAY_BASE, *(((rtems_unsigned8 *) LongWordPtr) + 3)), \ + WRITE_REGISTER_16(DISPLAY_BASE + 2, *(((rtems_unsigned8 *) LongWordPtr) + 2)), \ + WRITE_REGISTER_16(DISPLAY_BASE + 4, *(((rtems_unsigned8 *) LongWordPtr) + 1)), \ + WRITE_REGISTER_16(DISPLAY_BASE + 6, *((rtems_unsigned8 *) LongWordPtr)) ) + +/* make a better test, say switches */ +#if defined(GDB_MONITOR_ACTIVE) +#define GDB_RUN_MONITOR() (1 == 1) +#else +#define GDB_RUN_MONITOR() (1 == 0) +#endif + +#if __cplusplus +} +#endif +#endif diff --git a/c/src/lib/libbsp/m68k/ods68302/include/bsp.h b/c/src/lib/libbsp/m68k/ods68302/include/bsp.h new file mode 100644 index 0000000000..f2d2ec397b --- /dev/null +++ b/c/src/lib/libbsp/m68k/ods68302/include/bsp.h @@ -0,0 +1,139 @@ +/* bsp.h + * + * This include file contains all board IO definitions. + * + * XXX : put yours in here + * + * COPYRIGHT (c) 1989-1997. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may in + * the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + +#ifndef __GEN68302_BSP_h +#define __GEN68302_BSP_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include +#include + +#if defined(VARIANT) + +#define __bsp_cat(x, y) x ## y +#define __bsp_xcat(x, y) __bsp_cat(x, y) +#define __bsp_str(s) #s +#define __bsp_xstr(s) __bsp_str(s) + +#define __BSP_HEADER_FILE__ __bsp_xcat(VARIANT, .h) +#define __BSP_HEADER_FILE_STR__ __bsp_xstr(__BSP_HEADER_FILE__) + +#include __BSP_HEADER_FILE_STR__ +#endif + +/* + * 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 ) \ + { 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 RAM_BASE +#define RAM_END (RAM_BASE + RAM_SIZE) + +/* Structures */ + +#ifdef GEN68302_INIT +#undef EXTERN +#define EXTERN +#else +#undef EXTERN +#define EXTERN extern +#endif + +/* + * Device Driver Table Entries + */ + +/* + * NOTE: Use the standard Console driver entry + */ + +/* + * NOTE: Use the standard Clock driver entry + */ + +/* + * How many libio files we want + */ + +#define BSP_LIBIO_MAX_FDS 20 + +/* miscellaneous stuff assumed to exist */ + +extern rtems_configuration_table BSP_Configuration; + +extern m68k_isr_entry M68Kvec[]; /* vector table address */ + +/* functions */ + +void bsp_cleanup( void ); + +m68k_isr_entry 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/ods68302/include/coverhd.h b/c/src/lib/libbsp/m68k/ods68302/include/coverhd.h new file mode 100644 index 0000000000..7b69ec046b --- /dev/null +++ b/c/src/lib/libbsp/m68k/ods68302/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-1997. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may in + * the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + +#ifndef __COVERHD_h +#define __COVERHD_h + +#ifdef __cplusplus +extern "C" { +#endif + +#define CALLING_OVERHEAD_INITIALIZE_EXECUTIVE 14 +#define CALLING_OVERHEAD_SHUTDOWN_EXECUTIVE 11 +#define CALLING_OVERHEAD_TASK_CREATE 22 +#define CALLING_OVERHEAD_TASK_IDENT 17 +#define CALLING_OVERHEAD_TASK_START 18 +#define CALLING_OVERHEAD_TASK_RESTART 15 +#define CALLING_OVERHEAD_TASK_DELETE 12 +#define CALLING_OVERHEAD_TASK_SUSPEND 12 +#define CALLING_OVERHEAD_TASK_RESUME 12 +#define CALLING_OVERHEAD_TASK_SET_PRIORITY 16 +#define CALLING_OVERHEAD_TASK_MODE 15 +#define CALLING_OVERHEAD_TASK_GET_NOTE 16 +#define CALLING_OVERHEAD_TASK_SET_NOTE 16 +#define CALLING_OVERHEAD_TASK_WAKE_WHEN 31 +#define CALLING_OVERHEAD_TASK_WAKE_AFTER 11 +#define CALLING_OVERHEAD_INTERRUPT_CATCH 17 +#define CALLING_OVERHEAD_CLOCK_GET 32 +#define CALLING_OVERHEAD_CLOCK_SET 31 +#define CALLING_OVERHEAD_CLOCK_TICK 8 + +#define CALLING_OVERHEAD_TIMER_CREATE 13 +#define CALLING_OVERHEAD_TIMER_IDENT 12 +#define CALLING_OVERHEAD_TIMER_DELETE 14 +#define CALLING_OVERHEAD_TIMER_FIRE_AFTER 19 +#define CALLING_OVERHEAD_TIMER_FIRE_WHEN 39 +#define CALLING_OVERHEAD_TIMER_RESET 12 +#define CALLING_OVERHEAD_TIMER_CANCEL 12 +#define CALLING_OVERHEAD_SEMAPHORE_CREATE 18 +#define CALLING_OVERHEAD_SEMAPHORE_IDENT 12 +#define CALLING_OVERHEAD_SEMAPHORE_DELETE 17 +#define CALLING_OVERHEAD_SEMAPHORE_OBTAIN 17 +#define CALLING_OVERHEAD_SEMAPHORE_RELEASE 12 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_CREATE 18 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_IDENT 17 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_DELETE 12 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_SEND 14 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_URGENT 14 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_BROADCAST 17 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_RECEIVE 19 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_FLUSH 14 + +#define CALLING_OVERHEAD_EVENT_SEND 15 +#define CALLING_OVERHEAD_EVENT_RECEIVE 18 +#define CALLING_OVERHEAD_SIGNAL_CATCH 14 +#define CALLING_OVERHEAD_SIGNAL_SEND 14 +#define CALLING_OVERHEAD_PARTITION_CREATE 23 +#define CALLING_OVERHEAD_PARTITION_IDENT 17 +#define CALLING_OVERHEAD_PARTITION_DELETE 12 +#define CALLING_OVERHEAD_PARTITION_GET_BUFFER 15 +#define CALLING_OVERHEAD_PARTITION_RETURN_BUFFER 15 +#define CALLING_OVERHEAD_REGION_CREATE 23 +#define CALLING_OVERHEAD_REGION_IDENT 14 +#define CALLING_OVERHEAD_REGION_DELETE 12 +#define CALLING_OVERHEAD_REGION_GET_SEGMENT 21 +#define CALLING_OVERHEAD_REGION_RETURN_SEGMENT 15 +#define CALLING_OVERHEAD_PORT_CREATE 20 +#define CALLING_OVERHEAD_PORT_IDENT 14 +#define CALLING_OVERHEAD_PORT_DELETE 12 +#define CALLING_OVERHEAD_PORT_EXTERNAL_TO_INTERNAL 18 +#define CALLING_OVERHEAD_PORT_INTERNAL_TO_EXTERNAL 18 + +#define CALLING_OVERHEAD_IO_INITIALIZE 18 +#define CALLING_OVERHEAD_IO_OPEN 18 +#define CALLING_OVERHEAD_IO_CLOSE 18 +#define CALLING_OVERHEAD_IO_READ 18 +#define CALLING_OVERHEAD_IO_WRITE 18 +#define CALLING_OVERHEAD_IO_CONTROL 18 +#define CALLING_OVERHEAD_FATAL_ERROR_OCCURRED 11 +#define CALLING_OVERHEAD_RATE_MONOTONIC_CREATE 13 +#define CALLING_OVERHEAD_RATE_MONOTONIC_IDENT 14 +#define CALLING_OVERHEAD_RATE_MONOTONIC_DELETE 12 +#define CALLING_OVERHEAD_RATE_MONOTONIC_CANCEL 12 +#define CALLING_OVERHEAD_RATE_MONOTONIC_PERIOD 14 +#define CALLING_OVERHEAD_MULTIPROCESSING_ANNOUNCE 8 + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/c/src/lib/libbsp/m68k/ods68302/include/crc.h b/c/src/lib/libbsp/m68k/ods68302/include/crc.h new file mode 100644 index 0000000000..6d307599f0 --- /dev/null +++ b/c/src/lib/libbsp/m68k/ods68302/include/crc.h @@ -0,0 +1,26 @@ +/*****************************************************************************/ +/* + $Id$ + + CRC 16 Calculate Interface + +*/ +/*****************************************************************************/ + +#ifndef _CRC_H_ +#define _CRC_H_ + + /* ---- + F U N C T I O N S + */ +#if __cplusplus +extern "C" +{ +#endif + +rtems_unsigned16 calc_crc(void *data, rtems_unsigned32 count); + +#if __cplusplus +} +#endif +#endif diff --git a/c/src/lib/libbsp/m68k/ods68302/include/debugport.h b/c/src/lib/libbsp/m68k/ods68302/include/debugport.h new file mode 100644 index 0000000000..a54756e514 --- /dev/null +++ b/c/src/lib/libbsp/m68k/ods68302/include/debugport.h @@ -0,0 +1,42 @@ +/*****************************************************************************/ +/* + $Id$ + + Debug Port Support + +*/ +/*****************************************************************************/ + +#if !defined(_DEBUGPORT_H_) + #define _DEBUGPORT_H_ + +#if __cplusplus +extern "C" +{ +#endif + + /* normall automatic, only need when re-initialising */ + void debug_port_initialise(void); + + unsigned char debug_port_status(const unsigned char status); + unsigned char debug_port_in(void); + void debug_port_out(const unsigned char character); + + void debug_port_write(const char *buffer); + void debug_port_write_buffer(const char *buffer, unsigned int size); + + void debug_port_write_hex_uint(const unsigned int value); + void debug_port_write_hex_ulong(const unsigned long value); + + /* + * special banner message for CPU specific boot code, + * initialises the debug port + */ + void debug_port_banner(void); + void debug_port_printf(const char *format, ...); + +#if __cplusplus +} +#endif + +#endif diff --git a/c/src/lib/libbsp/m68k/ods68302/include/m68302scc.h b/c/src/lib/libbsp/m68k/ods68302/include/m68302scc.h new file mode 100644 index 0000000000..d6eb37ccda --- /dev/null +++ b/c/src/lib/libbsp/m68k/ods68302/include/m68302scc.h @@ -0,0 +1,34 @@ +/*****************************************************************************/ +/* + $Id$ + + M68302 Scc Polled Uart Support + + */ +/*****************************************************************************/ + +#if !defined(_M68302SCC_H_) +#define _M68302SCC_H_ + +#if __cplusplus +extern "C" +{ +#endif + +#define SCC_4800 (0) +#define SCC_9600 (1) +#define SCC_19200 (2) +#define SCC_38400 (3) +#define SCC_57600 (4) +#define SCC_115700 (5) + +void scc_initialise(int channel, int baud_rate, int lf_translate); +unsigned char scc_status(int channel, const unsigned char status); +unsigned char scc_in(int channel); +void scc_out(int channel, const unsigned char character); + +#if __cplusplus +} +#endif + +#endif diff --git a/c/src/lib/libbsp/m68k/ods68302/start/Makefile.in b/c/src/lib/libbsp/m68k/ods68302/start/Makefile.in new file mode 100644 index 0000000000..bb2586c4c3 --- /dev/null +++ b/c/src/lib/libbsp/m68k/ods68302/start/Makefile.in @@ -0,0 +1,68 @@ +# +# $Id$ +# + +@SET_MAKE@ +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH=@srcdir@ + +PGM=${ARCH}/start302.o + +ifeq ($(RTEMS_DEBUGGER),yes) +RESET_SRC = debugreset +else +RESET_SRC = reset +CFLAGS += -DGDB_MONITOR_ACTIVE +endif + +# C source names, if any, go here -- minus the .c +C_PIECES=cpuboot +C_FILES=$(C_PIECES:%=%.c) +C_O_FILES=$(C_PIECES:%=${ARCH}/%.o) + +H_FILES= + +# Assembly source names, if any, go here -- minus the .s +S_PIECES=$(RESET_SRC) +S_FILES=$(S_PIECES:%=%.s) +S_O_FILES=$(S_FILES:%.s=${ARCH}/%.o) + +SRCS=$(C_FILES) $(H_FILES) $(S_FILES) +OBJS=$(S_O_FILES) $(C_O_FILES) + +include $(RTEMS_CUSTOM) +include $(PROJECT_ROOT)/make/leaf.cfg + +# +# (OPTIONAL) Add local stuff here using += +# + +DEFINES += +CPPFLAGS += +CFLAGS += + +LD_PATHS += +LD_LIBS += +LDFLAGS += + +# +# Add your list of files to delete here. The config files +# already know how to delete some stuff, so you may want +# to just run 'make clean' first to see what gets missed. +# 'make clobber' already includes 'make clean' +# + +CLEAN_ADDITIONS += +CLOBBER_ADDITIONS += + +${PGM}: ${OBJS} + $(make-rel) + +all: ${ARCH} $(SRCS) $(OBJS) $(PGM) + $(INSTALL_VARIANT) -m 555 ${PGM} ${PROJECT_RELEASE}/lib + +# Install the program(s), appending _g or _p as appropriate. +# for include files, just use $(INSTALL) + + diff --git a/c/src/lib/libbsp/m68k/ods68302/start/cpuboot.c b/c/src/lib/libbsp/m68k/ods68302/start/cpuboot.c new file mode 100644 index 0000000000..1a8f9bd2cf --- /dev/null +++ b/c/src/lib/libbsp/m68k/ods68302/start/cpuboot.c @@ -0,0 +1,133 @@ +/*****************************************************************************/ +/* + Boot the CPU. + + Occurs in 3 phases for a 68302. + + Phase 1. + + Called as soon as able after reset. The BAR has been programed, and + a small stack exists in the DPRAM. All interrupts are masked, and + the processor is running in supervisor mode. No other hardware or + chip selects are active. + + This phase programs the chip select registers, the parallel ports + are set into default configurations, and basic registers cleared or + reset. The leds are programmed to show the end of phase 1. + + Phase 2. + + This is a piece of code which is copied to DPRAM and executed. It + should not do any more thann is currently present. The return to ROM + is managed by modifing the return address. Again leds show the status. + + Phase 3. + + This code executes with a valid C environment. That is the data + section has been intialised and the bss section set to 0. This phase + performs any special card initialisation and then calls boot card. + + $Id$ + +*/ +/*****************************************************************************/ + +#include +#include +#include +#include + +/* + Open the address, reset all registers + */ + +void boot_phase_1() +{ + M302_SCR = SCR_DEFAULT; + + WRITE_OR(CSEL_ROM, ROM_SIZE, ROM_WAIT_STATES, OR_MASK_RW, OR_MASK_FC); + WRITE_BR(CSEL_ROM, RAM_BASE, BR_READ_ONLY, BR_FC_NULL, BR_ENABLED); + WRITE_OR(CSEL_RAM, RAM_SIZE, RAM_WAIT_STATES, OR_MASK_RW, OR_MASK_FC); + WRITE_BR(CSEL_RAM, ROM_BASE, BR_READ_WRITE, BR_FC_NULL, BR_ENABLED); + +#if defined(CSEL_1) + WRITE_OR(CSEL_1, CSEL_1_SIZE, CSEL_1_WAIT_STATES, OR_MASK_RW, OR_MASK_FC); + WRITE_BR(CSEL_1, CSEL_1_BASE, BR_READ_WRITE, BR_FC_NULL, BR_ENABLED); +#endif + +#if defined(CSEL_2) + WRITE_OR(CSEL_2, CSEL_2_SIZE, CSEL_2_WAIT_STATES, OR_MASK_RW, OR_MASK_FC); + WRITE_BR(CSEL_2, CSEL_2_BASE, BR_READ_WRITE, BR_FC_NULL, BR_ENABLED); +#endif + + m302.reg.gimr = m302.reg.ipr = m302.reg.imr = m302.reg.isr = 0; + + m302.reg.simode = 0; + + m302.reg.pacnt = CARD_PA_CONFIGURATION; + m302.reg.paddr = CARD_PA_DEFAULT_DIRECTIONS; + m302.reg.padat = CARD_PA_DEFAULT_DATA; + + m302.reg.pbcnt = CARD_PB_CONFIGURATION; + m302.reg.pbddr = CARD_PB_DEFAULT_DIRECTIONS; + m302.reg.pbdat = CARD_PB_DEFAULT_DATA; + + m302.reg.wrr = WATCHDOG_TIMEOUT_PERIOD | WATCHDOG_ENABLE; + +#if defined(LED_CONTROL) + LED_CONTROL(LED_1_RED, LED_2_OFF, LED_3_OFF, LED_4_OFF, + LED_5_OFF, LED_6_OFF, LED_7_OFF, LED_8_OFF); +#endif +} + +/* + Swap the chip select mapping for ROM and RAM + */ + +void boot_phase_2(void) +{ + rtems_unsigned32 stack; + +#if defined(LED_CONTROL) + LED_CONTROL(LED_1_RED, LED_2_RED, LED_3_OFF, LED_4_OFF, + LED_5_OFF, LED_6_OFF, LED_7_OFF, LED_8_OFF); +#endif + + WRITE_BR(CSEL_ROM, ROM_BASE, BR_READ_ONLY, BR_FC_NULL, BR_ENABLED); + WRITE_BR(CSEL_RAM, RAM_BASE, BR_READ_WRITE, BR_FC_NULL, BR_ENABLED); + +#if defined(LED_CONTROL) + LED_CONTROL(LED_1_GREEN, LED_2_RED, LED_3_OFF, LED_4_OFF, + LED_5_OFF, LED_6_OFF, LED_7_OFF, LED_8_OFF); +#endif + + /* seems to want 2, looked at assember code output */ + *(&stack + 2) |= ROM_BASE; +} + +/* + Any pre-main initialisation, the C environment is setup, how-ever C++ + static constructors have not been called, and RTEMS is not initialised. + */ + +void boot_bsp(); +void set_debug_traps(); +void breakpoint(); + +void boot_phase_3(void) +{ + if (GDB_RUN_MONITOR()) + { + set_debug_traps(); + breakpoint(); + } + + debug_port_banner(); + + /* FIXME : add RAM and ROM checks */ + + /* boot the bsp, what ever this means */ + boot_bsp(); + + WATCHDOG_TRIGGER(); +} diff --git a/c/src/lib/libbsp/m68k/ods68302/start/debugreset.S b/c/src/lib/libbsp/m68k/ods68302/start/debugreset.S new file mode 100644 index 0000000000..74049191c4 --- /dev/null +++ b/c/src/lib/libbsp/m68k/ods68302/start/debugreset.S @@ -0,0 +1,107 @@ +/* + * $Id$ + * + * Re-written the gen68302 start-up code. + * + * Uses gas syntax only, removed the OAR asm.h. + * + * Supplies a complete vector table in ROM. + * + * Manages all vectors with seperate handlers to trap unhandled + * execptions. + * + * Uses the target specific header file to get the runtime + * configuration + * + * COPYRIGHT (c) 1996 + * Objective Design Systems Pty Ltd (ODS) + * + * 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. + * + */ + +| +| Entry from debugger +| + .sect .text + +| +| Start +| +| Entered from a hardware reset. +| + + .global start | Default entry point for GNU +start: + + move.w #0x2700,%sr | Disable all interrupts + + | + | zero out uninitialized data area + | + +zerobss: + moveal #end,%a0 | find end of .bss + moveal #bss_start,%a1 | find beginning of .bss + moveq #0,%d0 + +zerobss_loop: + + movel %d0,%a1@+ | to zero out uninitialized + cmpal %a0,%a1 + jlt zerobss_loop | loop until _end reached + + movel #end,%d0 | d0 = end of bss/start of heap + addl #heap_size,%d0 | d0 = end of heap + + movel %d0,stack_start | Save for brk() routine + addl #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 + + jsr boot_phase_3 + +| +| Initialised data +| + + .sect .data + + .global start_frame + +start_frame: + .space 4,0 + + .global stack_start + +stack_start: + .space 4,0 + +| +| Uninitialised data +| + + .sect .bss + + .global environ + .align 2 + +environ: + .long 0 + + .global heap_size + .set heap_size,0x2000 + + .global stack_size + .set stack_size,0x1000 + + diff --git a/c/src/lib/libbsp/m68k/ods68302/start/reset.S b/c/src/lib/libbsp/m68k/ods68302/start/reset.S new file mode 100644 index 0000000000..71d1071243 --- /dev/null +++ b/c/src/lib/libbsp/m68k/ods68302/start/reset.S @@ -0,0 +1,881 @@ +/* + * $Id$ + * + * Re-written the gen68302 start-up code. + * + * Uses gas syntax only, removed the OAR asm.h. + * + * Supplies a complete vector table in ROM. + * + * Manages all vectors with seperate handlers to trap unhandled + * execptions. + * + * Uses the target specific header file to get the runtime + * configuration + * + * COPYRIGHT (c) 1996 + * Objective Design Systems Pty Ltd (ODS) + * + * 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. + * + */ + +| +| some basic defined, this is that is required +| +#define MC68302_BAR 0x000000F2 +#define MC68302_BAR_FC_CFC 0x0000 +#define MC68302_SYS_RAM_SIZE 0x240 + +| +| Boot boot code in a special section, ld postions +| +| Initial stack pointer is in the dual ported RAM +| + .sect .text + + .global M68Kvec | Vector Table + +M68Kvec: | standard location for vectors + +| +| Make relative, can have the code positioned any where +| + +V___ISSP: .long MC68302_BASE + MC68302_SYS_RAM_SIZE +V____IPC: .long start - V___ISSP + +| +| Create the rest of the vector table to point to the unhandled expection +| handler +| +| Lots of macros, how-ever it creates a simple ROM vector table +| + +exception_handler = unhandled_exception - V___ISSP +#define MAKE_EXCEPTION_VECTOR(n) V___##n: .long (exception_handler + (n * 8)) + +MAKE_EXCEPTION_VECTOR(2) +MAKE_EXCEPTION_VECTOR(3) +MAKE_EXCEPTION_VECTOR(4) +MAKE_EXCEPTION_VECTOR(5) +MAKE_EXCEPTION_VECTOR(6) +MAKE_EXCEPTION_VECTOR(7) +MAKE_EXCEPTION_VECTOR(8) +MAKE_EXCEPTION_VECTOR(9) + +MAKE_EXCEPTION_VECTOR(10) +MAKE_EXCEPTION_VECTOR(11) +MAKE_EXCEPTION_VECTOR(12) +MAKE_EXCEPTION_VECTOR(13) +MAKE_EXCEPTION_VECTOR(14) +MAKE_EXCEPTION_VECTOR(15) +MAKE_EXCEPTION_VECTOR(16) +MAKE_EXCEPTION_VECTOR(17) +MAKE_EXCEPTION_VECTOR(18) +MAKE_EXCEPTION_VECTOR(19) + +MAKE_EXCEPTION_VECTOR(20) +MAKE_EXCEPTION_VECTOR(21) +MAKE_EXCEPTION_VECTOR(22) +MAKE_EXCEPTION_VECTOR(23) +MAKE_EXCEPTION_VECTOR(24) +MAKE_EXCEPTION_VECTOR(25) +MAKE_EXCEPTION_VECTOR(26) +MAKE_EXCEPTION_VECTOR(27) +MAKE_EXCEPTION_VECTOR(28) +MAKE_EXCEPTION_VECTOR(29) + +MAKE_EXCEPTION_VECTOR(30) +MAKE_EXCEPTION_VECTOR(31) +MAKE_EXCEPTION_VECTOR(32) +MAKE_EXCEPTION_VECTOR(33) +MAKE_EXCEPTION_VECTOR(34) +MAKE_EXCEPTION_VECTOR(35) +MAKE_EXCEPTION_VECTOR(36) +MAKE_EXCEPTION_VECTOR(37) +MAKE_EXCEPTION_VECTOR(38) +MAKE_EXCEPTION_VECTOR(39) + +MAKE_EXCEPTION_VECTOR(40) +MAKE_EXCEPTION_VECTOR(41) +MAKE_EXCEPTION_VECTOR(42) +MAKE_EXCEPTION_VECTOR(43) +MAKE_EXCEPTION_VECTOR(44) +MAKE_EXCEPTION_VECTOR(45) +MAKE_EXCEPTION_VECTOR(46) +MAKE_EXCEPTION_VECTOR(47) +MAKE_EXCEPTION_VECTOR(48) +MAKE_EXCEPTION_VECTOR(49) + +MAKE_EXCEPTION_VECTOR(50) +MAKE_EXCEPTION_VECTOR(51) +MAKE_EXCEPTION_VECTOR(52) +MAKE_EXCEPTION_VECTOR(53) +MAKE_EXCEPTION_VECTOR(54) +MAKE_EXCEPTION_VECTOR(55) +MAKE_EXCEPTION_VECTOR(56) +MAKE_EXCEPTION_VECTOR(57) +MAKE_EXCEPTION_VECTOR(58) +MAKE_EXCEPTION_VECTOR(59) + +MAKE_EXCEPTION_VECTOR(60) +MAKE_EXCEPTION_VECTOR(61) +MAKE_EXCEPTION_VECTOR(62) +MAKE_EXCEPTION_VECTOR(63) +MAKE_EXCEPTION_VECTOR(64) +MAKE_EXCEPTION_VECTOR(65) +MAKE_EXCEPTION_VECTOR(66) +MAKE_EXCEPTION_VECTOR(67) +MAKE_EXCEPTION_VECTOR(68) +MAKE_EXCEPTION_VECTOR(69) + +MAKE_EXCEPTION_VECTOR(70) +MAKE_EXCEPTION_VECTOR(71) +MAKE_EXCEPTION_VECTOR(72) +MAKE_EXCEPTION_VECTOR(73) +MAKE_EXCEPTION_VECTOR(74) +MAKE_EXCEPTION_VECTOR(75) +MAKE_EXCEPTION_VECTOR(76) +MAKE_EXCEPTION_VECTOR(77) +MAKE_EXCEPTION_VECTOR(78) +MAKE_EXCEPTION_VECTOR(79) + +MAKE_EXCEPTION_VECTOR(80) +MAKE_EXCEPTION_VECTOR(81) +MAKE_EXCEPTION_VECTOR(82) +MAKE_EXCEPTION_VECTOR(83) +MAKE_EXCEPTION_VECTOR(84) +MAKE_EXCEPTION_VECTOR(85) +MAKE_EXCEPTION_VECTOR(86) +MAKE_EXCEPTION_VECTOR(87) +MAKE_EXCEPTION_VECTOR(88) +MAKE_EXCEPTION_VECTOR(89) + +MAKE_EXCEPTION_VECTOR(90) +MAKE_EXCEPTION_VECTOR(91) +MAKE_EXCEPTION_VECTOR(92) +MAKE_EXCEPTION_VECTOR(93) +MAKE_EXCEPTION_VECTOR(94) +MAKE_EXCEPTION_VECTOR(95) +MAKE_EXCEPTION_VECTOR(96) +MAKE_EXCEPTION_VECTOR(97) +MAKE_EXCEPTION_VECTOR(98) +MAKE_EXCEPTION_VECTOR(99) + +MAKE_EXCEPTION_VECTOR(100) +MAKE_EXCEPTION_VECTOR(101) +MAKE_EXCEPTION_VECTOR(102) +MAKE_EXCEPTION_VECTOR(103) +MAKE_EXCEPTION_VECTOR(104) +MAKE_EXCEPTION_VECTOR(105) +MAKE_EXCEPTION_VECTOR(106) +MAKE_EXCEPTION_VECTOR(107) +MAKE_EXCEPTION_VECTOR(108) +MAKE_EXCEPTION_VECTOR(109) + +MAKE_EXCEPTION_VECTOR(110) +MAKE_EXCEPTION_VECTOR(111) +MAKE_EXCEPTION_VECTOR(112) +MAKE_EXCEPTION_VECTOR(113) +MAKE_EXCEPTION_VECTOR(114) +MAKE_EXCEPTION_VECTOR(115) +MAKE_EXCEPTION_VECTOR(116) +MAKE_EXCEPTION_VECTOR(117) +MAKE_EXCEPTION_VECTOR(118) +MAKE_EXCEPTION_VECTOR(119) + +MAKE_EXCEPTION_VECTOR(120) +MAKE_EXCEPTION_VECTOR(121) +MAKE_EXCEPTION_VECTOR(122) +MAKE_EXCEPTION_VECTOR(123) +MAKE_EXCEPTION_VECTOR(124) +MAKE_EXCEPTION_VECTOR(125) +MAKE_EXCEPTION_VECTOR(126) +MAKE_EXCEPTION_VECTOR(127) +MAKE_EXCEPTION_VECTOR(128) +MAKE_EXCEPTION_VECTOR(129) + +MAKE_EXCEPTION_VECTOR(130) +MAKE_EXCEPTION_VECTOR(131) +MAKE_EXCEPTION_VECTOR(132) +MAKE_EXCEPTION_VECTOR(133) +MAKE_EXCEPTION_VECTOR(134) +MAKE_EXCEPTION_VECTOR(135) +MAKE_EXCEPTION_VECTOR(136) +MAKE_EXCEPTION_VECTOR(137) +MAKE_EXCEPTION_VECTOR(138) +MAKE_EXCEPTION_VECTOR(139) + +MAKE_EXCEPTION_VECTOR(140) +MAKE_EXCEPTION_VECTOR(141) +MAKE_EXCEPTION_VECTOR(142) +MAKE_EXCEPTION_VECTOR(143) +MAKE_EXCEPTION_VECTOR(144) +MAKE_EXCEPTION_VECTOR(145) +MAKE_EXCEPTION_VECTOR(146) +MAKE_EXCEPTION_VECTOR(147) +MAKE_EXCEPTION_VECTOR(148) +MAKE_EXCEPTION_VECTOR(149) + +MAKE_EXCEPTION_VECTOR(150) +MAKE_EXCEPTION_VECTOR(151) +MAKE_EXCEPTION_VECTOR(152) +MAKE_EXCEPTION_VECTOR(153) +MAKE_EXCEPTION_VECTOR(154) +MAKE_EXCEPTION_VECTOR(155) +MAKE_EXCEPTION_VECTOR(156) +MAKE_EXCEPTION_VECTOR(157) +MAKE_EXCEPTION_VECTOR(158) +MAKE_EXCEPTION_VECTOR(159) + +MAKE_EXCEPTION_VECTOR(160) +MAKE_EXCEPTION_VECTOR(161) +MAKE_EXCEPTION_VECTOR(162) +MAKE_EXCEPTION_VECTOR(163) +MAKE_EXCEPTION_VECTOR(164) +MAKE_EXCEPTION_VECTOR(165) +MAKE_EXCEPTION_VECTOR(166) +MAKE_EXCEPTION_VECTOR(167) +MAKE_EXCEPTION_VECTOR(168) +MAKE_EXCEPTION_VECTOR(169) + +MAKE_EXCEPTION_VECTOR(170) +MAKE_EXCEPTION_VECTOR(171) +MAKE_EXCEPTION_VECTOR(172) +MAKE_EXCEPTION_VECTOR(173) +MAKE_EXCEPTION_VECTOR(174) +MAKE_EXCEPTION_VECTOR(175) +MAKE_EXCEPTION_VECTOR(176) +MAKE_EXCEPTION_VECTOR(177) +MAKE_EXCEPTION_VECTOR(178) +MAKE_EXCEPTION_VECTOR(179) + +MAKE_EXCEPTION_VECTOR(180) +MAKE_EXCEPTION_VECTOR(181) +MAKE_EXCEPTION_VECTOR(182) +MAKE_EXCEPTION_VECTOR(183) +MAKE_EXCEPTION_VECTOR(184) +MAKE_EXCEPTION_VECTOR(185) +MAKE_EXCEPTION_VECTOR(186) +MAKE_EXCEPTION_VECTOR(187) +MAKE_EXCEPTION_VECTOR(188) +MAKE_EXCEPTION_VECTOR(189) + +MAKE_EXCEPTION_VECTOR(190) +MAKE_EXCEPTION_VECTOR(191) +MAKE_EXCEPTION_VECTOR(192) +MAKE_EXCEPTION_VECTOR(193) +MAKE_EXCEPTION_VECTOR(194) +MAKE_EXCEPTION_VECTOR(195) +MAKE_EXCEPTION_VECTOR(196) +MAKE_EXCEPTION_VECTOR(197) +MAKE_EXCEPTION_VECTOR(198) +MAKE_EXCEPTION_VECTOR(199) + +MAKE_EXCEPTION_VECTOR(200) +MAKE_EXCEPTION_VECTOR(201) +MAKE_EXCEPTION_VECTOR(202) +MAKE_EXCEPTION_VECTOR(203) +MAKE_EXCEPTION_VECTOR(204) +MAKE_EXCEPTION_VECTOR(205) +MAKE_EXCEPTION_VECTOR(206) +MAKE_EXCEPTION_VECTOR(207) +MAKE_EXCEPTION_VECTOR(208) +MAKE_EXCEPTION_VECTOR(209) + +MAKE_EXCEPTION_VECTOR(210) +MAKE_EXCEPTION_VECTOR(211) +MAKE_EXCEPTION_VECTOR(212) +MAKE_EXCEPTION_VECTOR(213) +MAKE_EXCEPTION_VECTOR(214) +MAKE_EXCEPTION_VECTOR(215) +MAKE_EXCEPTION_VECTOR(216) +MAKE_EXCEPTION_VECTOR(217) +MAKE_EXCEPTION_VECTOR(218) +MAKE_EXCEPTION_VECTOR(219) + +MAKE_EXCEPTION_VECTOR(220) +MAKE_EXCEPTION_VECTOR(221) +MAKE_EXCEPTION_VECTOR(222) +MAKE_EXCEPTION_VECTOR(223) +MAKE_EXCEPTION_VECTOR(224) +MAKE_EXCEPTION_VECTOR(225) +MAKE_EXCEPTION_VECTOR(226) +MAKE_EXCEPTION_VECTOR(227) +MAKE_EXCEPTION_VECTOR(228) +MAKE_EXCEPTION_VECTOR(229) + +MAKE_EXCEPTION_VECTOR(230) +MAKE_EXCEPTION_VECTOR(231) +MAKE_EXCEPTION_VECTOR(232) +MAKE_EXCEPTION_VECTOR(233) +MAKE_EXCEPTION_VECTOR(234) +MAKE_EXCEPTION_VECTOR(235) +MAKE_EXCEPTION_VECTOR(236) +MAKE_EXCEPTION_VECTOR(237) +MAKE_EXCEPTION_VECTOR(238) +MAKE_EXCEPTION_VECTOR(239) + +MAKE_EXCEPTION_VECTOR(240) +MAKE_EXCEPTION_VECTOR(241) +MAKE_EXCEPTION_VECTOR(242) +MAKE_EXCEPTION_VECTOR(243) +MAKE_EXCEPTION_VECTOR(244) +MAKE_EXCEPTION_VECTOR(245) +MAKE_EXCEPTION_VECTOR(246) +MAKE_EXCEPTION_VECTOR(247) +MAKE_EXCEPTION_VECTOR(248) +MAKE_EXCEPTION_VECTOR(249) + +MAKE_EXCEPTION_VECTOR(250) +MAKE_EXCEPTION_VECTOR(251) +MAKE_EXCEPTION_VECTOR(252) +MAKE_EXCEPTION_VECTOR(253) +MAKE_EXCEPTION_VECTOR(254) +MAKE_EXCEPTION_VECTOR(255) + +| +| Start +| +| Entered from a hardware reset. +| + + .global start | Default entry point for GNU +start: + + move.w #0x2700,%sr | Disable all interrupts + + | + | Program the BAR, give us a stack !! + | + + moveq #0,%d0 + move.w #(MC68302_BASE >> 12),%d0 + or.w #(MC68302_BAR_FC_CFC << 12),%d0 + move.l #MC68302_BAR,%a0 + move.w %d0,%a0@(0) + + | + | watch for sign extended maths with the linker on (boot_phase_1-V___ISSP) + | manage the address with code, limited address of 2K at reset for CS0 + | + + move.l #boot_phase_1,%d0 + and.l #0x1FFF,%d0 + move.l %d0,%a0 + jsr %a0@(0) | programs all basic 302 registers + + | + | Map to the 68302 registers + | + + move.l #MC68302_BASE,%a5 + + | + | Make a vector table in RAM + | + + move.l #RAM_BASE,%a0 | a0 -> rom vector table + moveal #ROM_BASE,%a1 | d1 -> start of tmp SRAM + + move.l #255,%d0 + +copy_vec_table: + + move.l (%a0)+,%d1 + or.l #ROM_BASE,%d1 + move.l %d1,(%a1)+ + subq.l #1,%d0 + bne copy_vec_table + +#if defined(SYSTEM_TABLE_ANCHOR_OFFSET) + | + | Clear the system table + | + + move.l #SYSTEM_TABLE_ANCHOR_OFFSET,%a0 + move.l #0,(%a0) +#endif + + | + | Copy the chip select swap code to DPRAM and run it + | + + move.l #boot_phase_2,%d0 + and.l #(ROM_SIZE - 1),%d0 + move.l %d0,%a0 | a0 -> remap code + lea %a5@(0),%a1 | a1 -> internal system RAM + + move.l #boot_phase_3,%d0 + and.l #(ROM_SIZE - 1),%d0 + sub.l %a0,%d0 + +copy_remap: + move.b (%a0)+,(%a1)+ | copy + dbra %d0,copy_remap + + | + | Jump to the remap code in the 68302''s internal system RAM. + | + + jsr %a5@(0) | execute the swap code + + | + | Map to the 68302 registers + | + + move.l #MC68302_BASE,%a5 + + | + | Copy initialized data area from ROM to RAM + | + +copy_data: + moveal #etext,%a0 | find the end of .text + moveal #data_start,%a1 | find the beginning of .data + moveal #edata,%a2 | find the end of .data + +copy_data_loop: + + movel %a0@+,%a1@+ | copy the data + cmpal %a2,%a1 + jlt copy_data_loop | loop until edata reached + + | + | zero out uninitialized data area + | + +zerobss: + moveal #end,%a0 | find end of .bss + moveal #bss_start,%a1 | find beginning of .bss + moveq #0,%d0 + +zerobss_loop: + + movel %d0,%a1@+ | to zero out uninitialized + cmpal %a0,%a1 + jlt zerobss_loop | loop until _end reached + + movel #end,%d0 | d0 = end of bss/start of heap + addl #heap_size,%d0 | d0 = end of heap + + movel %d0,stack_start | Save for brk() routine + addl #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 + + jsr boot_phase_3 + +| +| Create an unhandled exception jump table. The table has an entry for +| each vector in the vector table. The entry pushes the vector number onto +| the stack and then calls a common exception handler using PIC. +| +| The macros are to create the labels and format vectors. +| + +#define cat(x, y) x ## y +#define FORMAT_ID(n) (n << 2) +#define EXCEPTION_HANDLER(h, n) EH__##n: move.w cat(h, FORMAT_ID(n)),-(%sp) ; \ + bra common_exception_handler + +unhandled_exception: + +EXCEPTION_HANDLER(#, 0) +EXCEPTION_HANDLER(#, 1) +EXCEPTION_HANDLER(#, 2) +EXCEPTION_HANDLER(#, 3) +EXCEPTION_HANDLER(#, 4) +EXCEPTION_HANDLER(#, 5) +EXCEPTION_HANDLER(#, 6) +EXCEPTION_HANDLER(#, 7) +EXCEPTION_HANDLER(#, 8) +EXCEPTION_HANDLER(#, 9) + +EXCEPTION_HANDLER(#, 10) +EXCEPTION_HANDLER(#, 11) +EXCEPTION_HANDLER(#, 12) +EXCEPTION_HANDLER(#, 13) +EXCEPTION_HANDLER(#, 14) +EXCEPTION_HANDLER(#, 15) +EXCEPTION_HANDLER(#, 16) +EXCEPTION_HANDLER(#, 17) +EXCEPTION_HANDLER(#, 18) +EXCEPTION_HANDLER(#, 19) + +EXCEPTION_HANDLER(#, 20) +EXCEPTION_HANDLER(#, 21) +EXCEPTION_HANDLER(#, 22) +EXCEPTION_HANDLER(#, 23) +EXCEPTION_HANDLER(#, 24) +EXCEPTION_HANDLER(#, 25) +EXCEPTION_HANDLER(#, 26) +EXCEPTION_HANDLER(#, 27) +EXCEPTION_HANDLER(#, 28) +EXCEPTION_HANDLER(#, 29) + +EXCEPTION_HANDLER(#, 30) +EXCEPTION_HANDLER(#, 31) +EXCEPTION_HANDLER(#, 32) +EXCEPTION_HANDLER(#, 33) +EXCEPTION_HANDLER(#, 34) +EXCEPTION_HANDLER(#, 35) +EXCEPTION_HANDLER(#, 36) +EXCEPTION_HANDLER(#, 37) +EXCEPTION_HANDLER(#, 38) +EXCEPTION_HANDLER(#, 39) + +EXCEPTION_HANDLER(#, 40) +EXCEPTION_HANDLER(#, 41) +EXCEPTION_HANDLER(#, 42) +EXCEPTION_HANDLER(#, 43) +EXCEPTION_HANDLER(#, 44) +EXCEPTION_HANDLER(#, 45) +EXCEPTION_HANDLER(#, 46) +EXCEPTION_HANDLER(#, 47) +EXCEPTION_HANDLER(#, 48) +EXCEPTION_HANDLER(#, 49) + +EXCEPTION_HANDLER(#, 50) +EXCEPTION_HANDLER(#, 51) +EXCEPTION_HANDLER(#, 52) +EXCEPTION_HANDLER(#, 53) +EXCEPTION_HANDLER(#, 54) +EXCEPTION_HANDLER(#, 55) +EXCEPTION_HANDLER(#, 56) +EXCEPTION_HANDLER(#, 57) +EXCEPTION_HANDLER(#, 58) +EXCEPTION_HANDLER(#, 59) + +EXCEPTION_HANDLER(#, 60) +EXCEPTION_HANDLER(#, 61) +EXCEPTION_HANDLER(#, 62) +EXCEPTION_HANDLER(#, 63) +EXCEPTION_HANDLER(#, 64) +EXCEPTION_HANDLER(#, 65) +EXCEPTION_HANDLER(#, 66) +EXCEPTION_HANDLER(#, 67) +EXCEPTION_HANDLER(#, 68) +EXCEPTION_HANDLER(#, 69) + +EXCEPTION_HANDLER(#, 70) +EXCEPTION_HANDLER(#, 71) +EXCEPTION_HANDLER(#, 72) +EXCEPTION_HANDLER(#, 73) +EXCEPTION_HANDLER(#, 74) +EXCEPTION_HANDLER(#, 75) +EXCEPTION_HANDLER(#, 76) +EXCEPTION_HANDLER(#, 77) +EXCEPTION_HANDLER(#, 78) +EXCEPTION_HANDLER(#, 79) + +EXCEPTION_HANDLER(#, 80) +EXCEPTION_HANDLER(#, 81) +EXCEPTION_HANDLER(#, 82) +EXCEPTION_HANDLER(#, 83) +EXCEPTION_HANDLER(#, 84) +EXCEPTION_HANDLER(#, 85) +EXCEPTION_HANDLER(#, 86) +EXCEPTION_HANDLER(#, 87) +EXCEPTION_HANDLER(#, 88) +EXCEPTION_HANDLER(#, 89) + +EXCEPTION_HANDLER(#, 90) +EXCEPTION_HANDLER(#, 91) +EXCEPTION_HANDLER(#, 92) +EXCEPTION_HANDLER(#, 93) +EXCEPTION_HANDLER(#, 94) +EXCEPTION_HANDLER(#, 95) +EXCEPTION_HANDLER(#, 96) +EXCEPTION_HANDLER(#, 97) +EXCEPTION_HANDLER(#, 98) +EXCEPTION_HANDLER(#, 99) + +EXCEPTION_HANDLER(#, 100) +EXCEPTION_HANDLER(#, 101) +EXCEPTION_HANDLER(#, 102) +EXCEPTION_HANDLER(#, 103) +EXCEPTION_HANDLER(#, 104) +EXCEPTION_HANDLER(#, 105) +EXCEPTION_HANDLER(#, 106) +EXCEPTION_HANDLER(#, 107) +EXCEPTION_HANDLER(#, 108) +EXCEPTION_HANDLER(#, 109) + +EXCEPTION_HANDLER(#, 110) +EXCEPTION_HANDLER(#, 111) +EXCEPTION_HANDLER(#, 112) +EXCEPTION_HANDLER(#, 113) +EXCEPTION_HANDLER(#, 114) +EXCEPTION_HANDLER(#, 115) +EXCEPTION_HANDLER(#, 116) +EXCEPTION_HANDLER(#, 117) +EXCEPTION_HANDLER(#, 118) +EXCEPTION_HANDLER(#, 119) + +EXCEPTION_HANDLER(#, 120) +EXCEPTION_HANDLER(#, 121) +EXCEPTION_HANDLER(#, 122) +EXCEPTION_HANDLER(#, 123) +EXCEPTION_HANDLER(#, 124) +EXCEPTION_HANDLER(#, 125) +EXCEPTION_HANDLER(#, 126) +EXCEPTION_HANDLER(#, 127) +EXCEPTION_HANDLER(#, 128) +EXCEPTION_HANDLER(#, 129) + +EXCEPTION_HANDLER(#, 130) +EXCEPTION_HANDLER(#, 131) +EXCEPTION_HANDLER(#, 132) +EXCEPTION_HANDLER(#, 133) +EXCEPTION_HANDLER(#, 134) +EXCEPTION_HANDLER(#, 135) +EXCEPTION_HANDLER(#, 136) +EXCEPTION_HANDLER(#, 137) +EXCEPTION_HANDLER(#, 138) +EXCEPTION_HANDLER(#, 139) + +EXCEPTION_HANDLER(#, 140) +EXCEPTION_HANDLER(#, 141) +EXCEPTION_HANDLER(#, 142) +EXCEPTION_HANDLER(#, 143) +EXCEPTION_HANDLER(#, 144) +EXCEPTION_HANDLER(#, 145) +EXCEPTION_HANDLER(#, 146) +EXCEPTION_HANDLER(#, 147) +EXCEPTION_HANDLER(#, 148) +EXCEPTION_HANDLER(#, 149) + +EXCEPTION_HANDLER(#, 150) +EXCEPTION_HANDLER(#, 151) +EXCEPTION_HANDLER(#, 152) +EXCEPTION_HANDLER(#, 153) +EXCEPTION_HANDLER(#, 154) +EXCEPTION_HANDLER(#, 155) +EXCEPTION_HANDLER(#, 156) +EXCEPTION_HANDLER(#, 157) +EXCEPTION_HANDLER(#, 158) +EXCEPTION_HANDLER(#, 159) + +EXCEPTION_HANDLER(#, 160) +EXCEPTION_HANDLER(#, 161) +EXCEPTION_HANDLER(#, 162) +EXCEPTION_HANDLER(#, 163) +EXCEPTION_HANDLER(#, 164) +EXCEPTION_HANDLER(#, 165) +EXCEPTION_HANDLER(#, 166) +EXCEPTION_HANDLER(#, 167) +EXCEPTION_HANDLER(#, 168) +EXCEPTION_HANDLER(#, 169) + +EXCEPTION_HANDLER(#, 170) +EXCEPTION_HANDLER(#, 171) +EXCEPTION_HANDLER(#, 172) +EXCEPTION_HANDLER(#, 173) +EXCEPTION_HANDLER(#, 174) +EXCEPTION_HANDLER(#, 175) +EXCEPTION_HANDLER(#, 176) +EXCEPTION_HANDLER(#, 177) +EXCEPTION_HANDLER(#, 178) +EXCEPTION_HANDLER(#, 179) + +EXCEPTION_HANDLER(#, 180) +EXCEPTION_HANDLER(#, 181) +EXCEPTION_HANDLER(#, 182) +EXCEPTION_HANDLER(#, 183) +EXCEPTION_HANDLER(#, 184) +EXCEPTION_HANDLER(#, 185) +EXCEPTION_HANDLER(#, 186) +EXCEPTION_HANDLER(#, 187) +EXCEPTION_HANDLER(#, 188) +EXCEPTION_HANDLER(#, 189) + +EXCEPTION_HANDLER(#, 190) +EXCEPTION_HANDLER(#, 191) +EXCEPTION_HANDLER(#, 192) +EXCEPTION_HANDLER(#, 193) +EXCEPTION_HANDLER(#, 194) +EXCEPTION_HANDLER(#, 195) +EXCEPTION_HANDLER(#, 196) +EXCEPTION_HANDLER(#, 197) +EXCEPTION_HANDLER(#, 198) +EXCEPTION_HANDLER(#, 199) + +EXCEPTION_HANDLER(#, 200) +EXCEPTION_HANDLER(#, 201) +EXCEPTION_HANDLER(#, 202) +EXCEPTION_HANDLER(#, 203) +EXCEPTION_HANDLER(#, 204) +EXCEPTION_HANDLER(#, 205) +EXCEPTION_HANDLER(#, 206) +EXCEPTION_HANDLER(#, 207) +EXCEPTION_HANDLER(#, 208) +EXCEPTION_HANDLER(#, 209) + +EXCEPTION_HANDLER(#, 210) +EXCEPTION_HANDLER(#, 211) +EXCEPTION_HANDLER(#, 212) +EXCEPTION_HANDLER(#, 213) +EXCEPTION_HANDLER(#, 214) +EXCEPTION_HANDLER(#, 215) +EXCEPTION_HANDLER(#, 216) +EXCEPTION_HANDLER(#, 217) +EXCEPTION_HANDLER(#, 218) +EXCEPTION_HANDLER(#, 219) + +EXCEPTION_HANDLER(#, 220) +EXCEPTION_HANDLER(#, 221) +EXCEPTION_HANDLER(#, 222) +EXCEPTION_HANDLER(#, 223) +EXCEPTION_HANDLER(#, 224) +EXCEPTION_HANDLER(#, 225) +EXCEPTION_HANDLER(#, 226) +EXCEPTION_HANDLER(#, 227) +EXCEPTION_HANDLER(#, 228) +EXCEPTION_HANDLER(#, 229) + +EXCEPTION_HANDLER(#, 230) +EXCEPTION_HANDLER(#, 231) +EXCEPTION_HANDLER(#, 232) +EXCEPTION_HANDLER(#, 233) +EXCEPTION_HANDLER(#, 234) +EXCEPTION_HANDLER(#, 235) +EXCEPTION_HANDLER(#, 236) +EXCEPTION_HANDLER(#, 237) +EXCEPTION_HANDLER(#, 238) +EXCEPTION_HANDLER(#, 239) + +EXCEPTION_HANDLER(#, 240) +EXCEPTION_HANDLER(#, 241) +EXCEPTION_HANDLER(#, 242) +EXCEPTION_HANDLER(#, 243) +EXCEPTION_HANDLER(#, 244) +EXCEPTION_HANDLER(#, 245) +EXCEPTION_HANDLER(#, 246) +EXCEPTION_HANDLER(#, 247) +EXCEPTION_HANDLER(#, 248) +EXCEPTION_HANDLER(#, 249) + +EXCEPTION_HANDLER(#, 250) +EXCEPTION_HANDLER(#, 251) +EXCEPTION_HANDLER(#, 252) +EXCEPTION_HANDLER(#, 253) +EXCEPTION_HANDLER(#, 254) +EXCEPTION_HANDLER(#, 255) + + +common_exception_handler: + + | + | Need to put the format/vector above the PC and status register + | + + move.l %d0,-(%sp) | free a register + move.w 4(%sp),%d0 | get the format/vector id + + | + | If a bus error or address error then trash the extra + | data saved on the stack + | + + cmp.w #0x0008,%d0 + beq ceh_10 + + cmp.w #0x000C,%d0 + beq ceh_10 + + bra ceh_20 + +ceh_10: + + move.w %d0,12(%sp) | need to move the format/id + move.l (%sp)+,%d0 | recover d0 + addq #8,%sp | trash the stack + move.l %d0,-(%sp) | free a register, again + move.w 4(%sp),%d0 | get the format/vector id + +ceh_20: + + move.w 6(%sp),4(%sp) + move.w 8(%sp),6(%sp) + move.w 10(%sp),8(%sp) + move.w %d0,10(%sp) | put the format/vector id + move.l (%sp)+,%d0 + + | + | Save all the registers, pass control to a dump trace routine + | + + movem.l %d0-%d7/%a0-%a7,%sp@- + + | + | check to see if ROM is mapped to zero + | + + move.l #trace_exception,%d1 | get the linked address + and.l #(ROM_SIZE - 1),%d1 | obtain the offset into the ROM + lea.l %pc@(0),%a0 | were are we currently + move.l %a0,%d0 | need to use a data register + and.l #~(ROM_SIZE - 1),%d0 | keep the top part of the address + or.l %d1,%d0 | apply it to the trace exception offset + move.l %d0,%a0 | need an address register for jumping + jsr %a0@(0) + +ceh_30: + jmp ceh_30 +| +| The RAM based vector table +| + + .sect .vtable + + .global vector_table + +vector_table: + .space (256 * 4),0 + +| +| Initialised data +| + + .sect .data + + .global start_frame + +start_frame: + .space 4,0 + + .global stack_start + +stack_start: + .space 4,0 + +| +| Uninitialised data +| + + .sect .bss + + .global environ + .align 2 + +environ: + .long 0 + + .global heap_size + .set heap_size,0x2000 + + .global stack_size + .set stack_size,0x1000 + + diff --git a/c/src/lib/libbsp/m68k/ods68302/start302/Makefile.in b/c/src/lib/libbsp/m68k/ods68302/start302/Makefile.in new file mode 100644 index 0000000000..bb2586c4c3 --- /dev/null +++ b/c/src/lib/libbsp/m68k/ods68302/start302/Makefile.in @@ -0,0 +1,68 @@ +# +# $Id$ +# + +@SET_MAKE@ +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH=@srcdir@ + +PGM=${ARCH}/start302.o + +ifeq ($(RTEMS_DEBUGGER),yes) +RESET_SRC = debugreset +else +RESET_SRC = reset +CFLAGS += -DGDB_MONITOR_ACTIVE +endif + +# C source names, if any, go here -- minus the .c +C_PIECES=cpuboot +C_FILES=$(C_PIECES:%=%.c) +C_O_FILES=$(C_PIECES:%=${ARCH}/%.o) + +H_FILES= + +# Assembly source names, if any, go here -- minus the .s +S_PIECES=$(RESET_SRC) +S_FILES=$(S_PIECES:%=%.s) +S_O_FILES=$(S_FILES:%.s=${ARCH}/%.o) + +SRCS=$(C_FILES) $(H_FILES) $(S_FILES) +OBJS=$(S_O_FILES) $(C_O_FILES) + +include $(RTEMS_CUSTOM) +include $(PROJECT_ROOT)/make/leaf.cfg + +# +# (OPTIONAL) Add local stuff here using += +# + +DEFINES += +CPPFLAGS += +CFLAGS += + +LD_PATHS += +LD_LIBS += +LDFLAGS += + +# +# Add your list of files to delete here. The config files +# already know how to delete some stuff, so you may want +# to just run 'make clean' first to see what gets missed. +# 'make clobber' already includes 'make clean' +# + +CLEAN_ADDITIONS += +CLOBBER_ADDITIONS += + +${PGM}: ${OBJS} + $(make-rel) + +all: ${ARCH} $(SRCS) $(OBJS) $(PGM) + $(INSTALL_VARIANT) -m 555 ${PGM} ${PROJECT_RELEASE}/lib + +# Install the program(s), appending _g or _p as appropriate. +# for include files, just use $(INSTALL) + + diff --git a/c/src/lib/libbsp/m68k/ods68302/start302/cpuboot.c b/c/src/lib/libbsp/m68k/ods68302/start302/cpuboot.c new file mode 100644 index 0000000000..1a8f9bd2cf --- /dev/null +++ b/c/src/lib/libbsp/m68k/ods68302/start302/cpuboot.c @@ -0,0 +1,133 @@ +/*****************************************************************************/ +/* + Boot the CPU. + + Occurs in 3 phases for a 68302. + + Phase 1. + + Called as soon as able after reset. The BAR has been programed, and + a small stack exists in the DPRAM. All interrupts are masked, and + the processor is running in supervisor mode. No other hardware or + chip selects are active. + + This phase programs the chip select registers, the parallel ports + are set into default configurations, and basic registers cleared or + reset. The leds are programmed to show the end of phase 1. + + Phase 2. + + This is a piece of code which is copied to DPRAM and executed. It + should not do any more thann is currently present. The return to ROM + is managed by modifing the return address. Again leds show the status. + + Phase 3. + + This code executes with a valid C environment. That is the data + section has been intialised and the bss section set to 0. This phase + performs any special card initialisation and then calls boot card. + + $Id$ + +*/ +/*****************************************************************************/ + +#include +#include +#include +#include + +/* + Open the address, reset all registers + */ + +void boot_phase_1() +{ + M302_SCR = SCR_DEFAULT; + + WRITE_OR(CSEL_ROM, ROM_SIZE, ROM_WAIT_STATES, OR_MASK_RW, OR_MASK_FC); + WRITE_BR(CSEL_ROM, RAM_BASE, BR_READ_ONLY, BR_FC_NULL, BR_ENABLED); + WRITE_OR(CSEL_RAM, RAM_SIZE, RAM_WAIT_STATES, OR_MASK_RW, OR_MASK_FC); + WRITE_BR(CSEL_RAM, ROM_BASE, BR_READ_WRITE, BR_FC_NULL, BR_ENABLED); + +#if defined(CSEL_1) + WRITE_OR(CSEL_1, CSEL_1_SIZE, CSEL_1_WAIT_STATES, OR_MASK_RW, OR_MASK_FC); + WRITE_BR(CSEL_1, CSEL_1_BASE, BR_READ_WRITE, BR_FC_NULL, BR_ENABLED); +#endif + +#if defined(CSEL_2) + WRITE_OR(CSEL_2, CSEL_2_SIZE, CSEL_2_WAIT_STATES, OR_MASK_RW, OR_MASK_FC); + WRITE_BR(CSEL_2, CSEL_2_BASE, BR_READ_WRITE, BR_FC_NULL, BR_ENABLED); +#endif + + m302.reg.gimr = m302.reg.ipr = m302.reg.imr = m302.reg.isr = 0; + + m302.reg.simode = 0; + + m302.reg.pacnt = CARD_PA_CONFIGURATION; + m302.reg.paddr = CARD_PA_DEFAULT_DIRECTIONS; + m302.reg.padat = CARD_PA_DEFAULT_DATA; + + m302.reg.pbcnt = CARD_PB_CONFIGURATION; + m302.reg.pbddr = CARD_PB_DEFAULT_DIRECTIONS; + m302.reg.pbdat = CARD_PB_DEFAULT_DATA; + + m302.reg.wrr = WATCHDOG_TIMEOUT_PERIOD | WATCHDOG_ENABLE; + +#if defined(LED_CONTROL) + LED_CONTROL(LED_1_RED, LED_2_OFF, LED_3_OFF, LED_4_OFF, + LED_5_OFF, LED_6_OFF, LED_7_OFF, LED_8_OFF); +#endif +} + +/* + Swap the chip select mapping for ROM and RAM + */ + +void boot_phase_2(void) +{ + rtems_unsigned32 stack; + +#if defined(LED_CONTROL) + LED_CONTROL(LED_1_RED, LED_2_RED, LED_3_OFF, LED_4_OFF, + LED_5_OFF, LED_6_OFF, LED_7_OFF, LED_8_OFF); +#endif + + WRITE_BR(CSEL_ROM, ROM_BASE, BR_READ_ONLY, BR_FC_NULL, BR_ENABLED); + WRITE_BR(CSEL_RAM, RAM_BASE, BR_READ_WRITE, BR_FC_NULL, BR_ENABLED); + +#if defined(LED_CONTROL) + LED_CONTROL(LED_1_GREEN, LED_2_RED, LED_3_OFF, LED_4_OFF, + LED_5_OFF, LED_6_OFF, LED_7_OFF, LED_8_OFF); +#endif + + /* seems to want 2, looked at assember code output */ + *(&stack + 2) |= ROM_BASE; +} + +/* + Any pre-main initialisation, the C environment is setup, how-ever C++ + static constructors have not been called, and RTEMS is not initialised. + */ + +void boot_bsp(); +void set_debug_traps(); +void breakpoint(); + +void boot_phase_3(void) +{ + if (GDB_RUN_MONITOR()) + { + set_debug_traps(); + breakpoint(); + } + + debug_port_banner(); + + /* FIXME : add RAM and ROM checks */ + + /* boot the bsp, what ever this means */ + boot_bsp(); + + WATCHDOG_TRIGGER(); +} diff --git a/c/src/lib/libbsp/m68k/ods68302/start302/debugreset.S b/c/src/lib/libbsp/m68k/ods68302/start302/debugreset.S new file mode 100644 index 0000000000..74049191c4 --- /dev/null +++ b/c/src/lib/libbsp/m68k/ods68302/start302/debugreset.S @@ -0,0 +1,107 @@ +/* + * $Id$ + * + * Re-written the gen68302 start-up code. + * + * Uses gas syntax only, removed the OAR asm.h. + * + * Supplies a complete vector table in ROM. + * + * Manages all vectors with seperate handlers to trap unhandled + * execptions. + * + * Uses the target specific header file to get the runtime + * configuration + * + * COPYRIGHT (c) 1996 + * Objective Design Systems Pty Ltd (ODS) + * + * 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. + * + */ + +| +| Entry from debugger +| + .sect .text + +| +| Start +| +| Entered from a hardware reset. +| + + .global start | Default entry point for GNU +start: + + move.w #0x2700,%sr | Disable all interrupts + + | + | zero out uninitialized data area + | + +zerobss: + moveal #end,%a0 | find end of .bss + moveal #bss_start,%a1 | find beginning of .bss + moveq #0,%d0 + +zerobss_loop: + + movel %d0,%a1@+ | to zero out uninitialized + cmpal %a0,%a1 + jlt zerobss_loop | loop until _end reached + + movel #end,%d0 | d0 = end of bss/start of heap + addl #heap_size,%d0 | d0 = end of heap + + movel %d0,stack_start | Save for brk() routine + addl #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 + + jsr boot_phase_3 + +| +| Initialised data +| + + .sect .data + + .global start_frame + +start_frame: + .space 4,0 + + .global stack_start + +stack_start: + .space 4,0 + +| +| Uninitialised data +| + + .sect .bss + + .global environ + .align 2 + +environ: + .long 0 + + .global heap_size + .set heap_size,0x2000 + + .global stack_size + .set stack_size,0x1000 + + diff --git a/c/src/lib/libbsp/m68k/ods68302/start302/reset.S b/c/src/lib/libbsp/m68k/ods68302/start302/reset.S new file mode 100644 index 0000000000..71d1071243 --- /dev/null +++ b/c/src/lib/libbsp/m68k/ods68302/start302/reset.S @@ -0,0 +1,881 @@ +/* + * $Id$ + * + * Re-written the gen68302 start-up code. + * + * Uses gas syntax only, removed the OAR asm.h. + * + * Supplies a complete vector table in ROM. + * + * Manages all vectors with seperate handlers to trap unhandled + * execptions. + * + * Uses the target specific header file to get the runtime + * configuration + * + * COPYRIGHT (c) 1996 + * Objective Design Systems Pty Ltd (ODS) + * + * 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. + * + */ + +| +| some basic defined, this is that is required +| +#define MC68302_BAR 0x000000F2 +#define MC68302_BAR_FC_CFC 0x0000 +#define MC68302_SYS_RAM_SIZE 0x240 + +| +| Boot boot code in a special section, ld postions +| +| Initial stack pointer is in the dual ported RAM +| + .sect .text + + .global M68Kvec | Vector Table + +M68Kvec: | standard location for vectors + +| +| Make relative, can have the code positioned any where +| + +V___ISSP: .long MC68302_BASE + MC68302_SYS_RAM_SIZE +V____IPC: .long start - V___ISSP + +| +| Create the rest of the vector table to point to the unhandled expection +| handler +| +| Lots of macros, how-ever it creates a simple ROM vector table +| + +exception_handler = unhandled_exception - V___ISSP +#define MAKE_EXCEPTION_VECTOR(n) V___##n: .long (exception_handler + (n * 8)) + +MAKE_EXCEPTION_VECTOR(2) +MAKE_EXCEPTION_VECTOR(3) +MAKE_EXCEPTION_VECTOR(4) +MAKE_EXCEPTION_VECTOR(5) +MAKE_EXCEPTION_VECTOR(6) +MAKE_EXCEPTION_VECTOR(7) +MAKE_EXCEPTION_VECTOR(8) +MAKE_EXCEPTION_VECTOR(9) + +MAKE_EXCEPTION_VECTOR(10) +MAKE_EXCEPTION_VECTOR(11) +MAKE_EXCEPTION_VECTOR(12) +MAKE_EXCEPTION_VECTOR(13) +MAKE_EXCEPTION_VECTOR(14) +MAKE_EXCEPTION_VECTOR(15) +MAKE_EXCEPTION_VECTOR(16) +MAKE_EXCEPTION_VECTOR(17) +MAKE_EXCEPTION_VECTOR(18) +MAKE_EXCEPTION_VECTOR(19) + +MAKE_EXCEPTION_VECTOR(20) +MAKE_EXCEPTION_VECTOR(21) +MAKE_EXCEPTION_VECTOR(22) +MAKE_EXCEPTION_VECTOR(23) +MAKE_EXCEPTION_VECTOR(24) +MAKE_EXCEPTION_VECTOR(25) +MAKE_EXCEPTION_VECTOR(26) +MAKE_EXCEPTION_VECTOR(27) +MAKE_EXCEPTION_VECTOR(28) +MAKE_EXCEPTION_VECTOR(29) + +MAKE_EXCEPTION_VECTOR(30) +MAKE_EXCEPTION_VECTOR(31) +MAKE_EXCEPTION_VECTOR(32) +MAKE_EXCEPTION_VECTOR(33) +MAKE_EXCEPTION_VECTOR(34) +MAKE_EXCEPTION_VECTOR(35) +MAKE_EXCEPTION_VECTOR(36) +MAKE_EXCEPTION_VECTOR(37) +MAKE_EXCEPTION_VECTOR(38) +MAKE_EXCEPTION_VECTOR(39) + +MAKE_EXCEPTION_VECTOR(40) +MAKE_EXCEPTION_VECTOR(41) +MAKE_EXCEPTION_VECTOR(42) +MAKE_EXCEPTION_VECTOR(43) +MAKE_EXCEPTION_VECTOR(44) +MAKE_EXCEPTION_VECTOR(45) +MAKE_EXCEPTION_VECTOR(46) +MAKE_EXCEPTION_VECTOR(47) +MAKE_EXCEPTION_VECTOR(48) +MAKE_EXCEPTION_VECTOR(49) + +MAKE_EXCEPTION_VECTOR(50) +MAKE_EXCEPTION_VECTOR(51) +MAKE_EXCEPTION_VECTOR(52) +MAKE_EXCEPTION_VECTOR(53) +MAKE_EXCEPTION_VECTOR(54) +MAKE_EXCEPTION_VECTOR(55) +MAKE_EXCEPTION_VECTOR(56) +MAKE_EXCEPTION_VECTOR(57) +MAKE_EXCEPTION_VECTOR(58) +MAKE_EXCEPTION_VECTOR(59) + +MAKE_EXCEPTION_VECTOR(60) +MAKE_EXCEPTION_VECTOR(61) +MAKE_EXCEPTION_VECTOR(62) +MAKE_EXCEPTION_VECTOR(63) +MAKE_EXCEPTION_VECTOR(64) +MAKE_EXCEPTION_VECTOR(65) +MAKE_EXCEPTION_VECTOR(66) +MAKE_EXCEPTION_VECTOR(67) +MAKE_EXCEPTION_VECTOR(68) +MAKE_EXCEPTION_VECTOR(69) + +MAKE_EXCEPTION_VECTOR(70) +MAKE_EXCEPTION_VECTOR(71) +MAKE_EXCEPTION_VECTOR(72) +MAKE_EXCEPTION_VECTOR(73) +MAKE_EXCEPTION_VECTOR(74) +MAKE_EXCEPTION_VECTOR(75) +MAKE_EXCEPTION_VECTOR(76) +MAKE_EXCEPTION_VECTOR(77) +MAKE_EXCEPTION_VECTOR(78) +MAKE_EXCEPTION_VECTOR(79) + +MAKE_EXCEPTION_VECTOR(80) +MAKE_EXCEPTION_VECTOR(81) +MAKE_EXCEPTION_VECTOR(82) +MAKE_EXCEPTION_VECTOR(83) +MAKE_EXCEPTION_VECTOR(84) +MAKE_EXCEPTION_VECTOR(85) +MAKE_EXCEPTION_VECTOR(86) +MAKE_EXCEPTION_VECTOR(87) +MAKE_EXCEPTION_VECTOR(88) +MAKE_EXCEPTION_VECTOR(89) + +MAKE_EXCEPTION_VECTOR(90) +MAKE_EXCEPTION_VECTOR(91) +MAKE_EXCEPTION_VECTOR(92) +MAKE_EXCEPTION_VECTOR(93) +MAKE_EXCEPTION_VECTOR(94) +MAKE_EXCEPTION_VECTOR(95) +MAKE_EXCEPTION_VECTOR(96) +MAKE_EXCEPTION_VECTOR(97) +MAKE_EXCEPTION_VECTOR(98) +MAKE_EXCEPTION_VECTOR(99) + +MAKE_EXCEPTION_VECTOR(100) +MAKE_EXCEPTION_VECTOR(101) +MAKE_EXCEPTION_VECTOR(102) +MAKE_EXCEPTION_VECTOR(103) +MAKE_EXCEPTION_VECTOR(104) +MAKE_EXCEPTION_VECTOR(105) +MAKE_EXCEPTION_VECTOR(106) +MAKE_EXCEPTION_VECTOR(107) +MAKE_EXCEPTION_VECTOR(108) +MAKE_EXCEPTION_VECTOR(109) + +MAKE_EXCEPTION_VECTOR(110) +MAKE_EXCEPTION_VECTOR(111) +MAKE_EXCEPTION_VECTOR(112) +MAKE_EXCEPTION_VECTOR(113) +MAKE_EXCEPTION_VECTOR(114) +MAKE_EXCEPTION_VECTOR(115) +MAKE_EXCEPTION_VECTOR(116) +MAKE_EXCEPTION_VECTOR(117) +MAKE_EXCEPTION_VECTOR(118) +MAKE_EXCEPTION_VECTOR(119) + +MAKE_EXCEPTION_VECTOR(120) +MAKE_EXCEPTION_VECTOR(121) +MAKE_EXCEPTION_VECTOR(122) +MAKE_EXCEPTION_VECTOR(123) +MAKE_EXCEPTION_VECTOR(124) +MAKE_EXCEPTION_VECTOR(125) +MAKE_EXCEPTION_VECTOR(126) +MAKE_EXCEPTION_VECTOR(127) +MAKE_EXCEPTION_VECTOR(128) +MAKE_EXCEPTION_VECTOR(129) + +MAKE_EXCEPTION_VECTOR(130) +MAKE_EXCEPTION_VECTOR(131) +MAKE_EXCEPTION_VECTOR(132) +MAKE_EXCEPTION_VECTOR(133) +MAKE_EXCEPTION_VECTOR(134) +MAKE_EXCEPTION_VECTOR(135) +MAKE_EXCEPTION_VECTOR(136) +MAKE_EXCEPTION_VECTOR(137) +MAKE_EXCEPTION_VECTOR(138) +MAKE_EXCEPTION_VECTOR(139) + +MAKE_EXCEPTION_VECTOR(140) +MAKE_EXCEPTION_VECTOR(141) +MAKE_EXCEPTION_VECTOR(142) +MAKE_EXCEPTION_VECTOR(143) +MAKE_EXCEPTION_VECTOR(144) +MAKE_EXCEPTION_VECTOR(145) +MAKE_EXCEPTION_VECTOR(146) +MAKE_EXCEPTION_VECTOR(147) +MAKE_EXCEPTION_VECTOR(148) +MAKE_EXCEPTION_VECTOR(149) + +MAKE_EXCEPTION_VECTOR(150) +MAKE_EXCEPTION_VECTOR(151) +MAKE_EXCEPTION_VECTOR(152) +MAKE_EXCEPTION_VECTOR(153) +MAKE_EXCEPTION_VECTOR(154) +MAKE_EXCEPTION_VECTOR(155) +MAKE_EXCEPTION_VECTOR(156) +MAKE_EXCEPTION_VECTOR(157) +MAKE_EXCEPTION_VECTOR(158) +MAKE_EXCEPTION_VECTOR(159) + +MAKE_EXCEPTION_VECTOR(160) +MAKE_EXCEPTION_VECTOR(161) +MAKE_EXCEPTION_VECTOR(162) +MAKE_EXCEPTION_VECTOR(163) +MAKE_EXCEPTION_VECTOR(164) +MAKE_EXCEPTION_VECTOR(165) +MAKE_EXCEPTION_VECTOR(166) +MAKE_EXCEPTION_VECTOR(167) +MAKE_EXCEPTION_VECTOR(168) +MAKE_EXCEPTION_VECTOR(169) + +MAKE_EXCEPTION_VECTOR(170) +MAKE_EXCEPTION_VECTOR(171) +MAKE_EXCEPTION_VECTOR(172) +MAKE_EXCEPTION_VECTOR(173) +MAKE_EXCEPTION_VECTOR(174) +MAKE_EXCEPTION_VECTOR(175) +MAKE_EXCEPTION_VECTOR(176) +MAKE_EXCEPTION_VECTOR(177) +MAKE_EXCEPTION_VECTOR(178) +MAKE_EXCEPTION_VECTOR(179) + +MAKE_EXCEPTION_VECTOR(180) +MAKE_EXCEPTION_VECTOR(181) +MAKE_EXCEPTION_VECTOR(182) +MAKE_EXCEPTION_VECTOR(183) +MAKE_EXCEPTION_VECTOR(184) +MAKE_EXCEPTION_VECTOR(185) +MAKE_EXCEPTION_VECTOR(186) +MAKE_EXCEPTION_VECTOR(187) +MAKE_EXCEPTION_VECTOR(188) +MAKE_EXCEPTION_VECTOR(189) + +MAKE_EXCEPTION_VECTOR(190) +MAKE_EXCEPTION_VECTOR(191) +MAKE_EXCEPTION_VECTOR(192) +MAKE_EXCEPTION_VECTOR(193) +MAKE_EXCEPTION_VECTOR(194) +MAKE_EXCEPTION_VECTOR(195) +MAKE_EXCEPTION_VECTOR(196) +MAKE_EXCEPTION_VECTOR(197) +MAKE_EXCEPTION_VECTOR(198) +MAKE_EXCEPTION_VECTOR(199) + +MAKE_EXCEPTION_VECTOR(200) +MAKE_EXCEPTION_VECTOR(201) +MAKE_EXCEPTION_VECTOR(202) +MAKE_EXCEPTION_VECTOR(203) +MAKE_EXCEPTION_VECTOR(204) +MAKE_EXCEPTION_VECTOR(205) +MAKE_EXCEPTION_VECTOR(206) +MAKE_EXCEPTION_VECTOR(207) +MAKE_EXCEPTION_VECTOR(208) +MAKE_EXCEPTION_VECTOR(209) + +MAKE_EXCEPTION_VECTOR(210) +MAKE_EXCEPTION_VECTOR(211) +MAKE_EXCEPTION_VECTOR(212) +MAKE_EXCEPTION_VECTOR(213) +MAKE_EXCEPTION_VECTOR(214) +MAKE_EXCEPTION_VECTOR(215) +MAKE_EXCEPTION_VECTOR(216) +MAKE_EXCEPTION_VECTOR(217) +MAKE_EXCEPTION_VECTOR(218) +MAKE_EXCEPTION_VECTOR(219) + +MAKE_EXCEPTION_VECTOR(220) +MAKE_EXCEPTION_VECTOR(221) +MAKE_EXCEPTION_VECTOR(222) +MAKE_EXCEPTION_VECTOR(223) +MAKE_EXCEPTION_VECTOR(224) +MAKE_EXCEPTION_VECTOR(225) +MAKE_EXCEPTION_VECTOR(226) +MAKE_EXCEPTION_VECTOR(227) +MAKE_EXCEPTION_VECTOR(228) +MAKE_EXCEPTION_VECTOR(229) + +MAKE_EXCEPTION_VECTOR(230) +MAKE_EXCEPTION_VECTOR(231) +MAKE_EXCEPTION_VECTOR(232) +MAKE_EXCEPTION_VECTOR(233) +MAKE_EXCEPTION_VECTOR(234) +MAKE_EXCEPTION_VECTOR(235) +MAKE_EXCEPTION_VECTOR(236) +MAKE_EXCEPTION_VECTOR(237) +MAKE_EXCEPTION_VECTOR(238) +MAKE_EXCEPTION_VECTOR(239) + +MAKE_EXCEPTION_VECTOR(240) +MAKE_EXCEPTION_VECTOR(241) +MAKE_EXCEPTION_VECTOR(242) +MAKE_EXCEPTION_VECTOR(243) +MAKE_EXCEPTION_VECTOR(244) +MAKE_EXCEPTION_VECTOR(245) +MAKE_EXCEPTION_VECTOR(246) +MAKE_EXCEPTION_VECTOR(247) +MAKE_EXCEPTION_VECTOR(248) +MAKE_EXCEPTION_VECTOR(249) + +MAKE_EXCEPTION_VECTOR(250) +MAKE_EXCEPTION_VECTOR(251) +MAKE_EXCEPTION_VECTOR(252) +MAKE_EXCEPTION_VECTOR(253) +MAKE_EXCEPTION_VECTOR(254) +MAKE_EXCEPTION_VECTOR(255) + +| +| Start +| +| Entered from a hardware reset. +| + + .global start | Default entry point for GNU +start: + + move.w #0x2700,%sr | Disable all interrupts + + | + | Program the BAR, give us a stack !! + | + + moveq #0,%d0 + move.w #(MC68302_BASE >> 12),%d0 + or.w #(MC68302_BAR_FC_CFC << 12),%d0 + move.l #MC68302_BAR,%a0 + move.w %d0,%a0@(0) + + | + | watch for sign extended maths with the linker on (boot_phase_1-V___ISSP) + | manage the address with code, limited address of 2K at reset for CS0 + | + + move.l #boot_phase_1,%d0 + and.l #0x1FFF,%d0 + move.l %d0,%a0 + jsr %a0@(0) | programs all basic 302 registers + + | + | Map to the 68302 registers + | + + move.l #MC68302_BASE,%a5 + + | + | Make a vector table in RAM + | + + move.l #RAM_BASE,%a0 | a0 -> rom vector table + moveal #ROM_BASE,%a1 | d1 -> start of tmp SRAM + + move.l #255,%d0 + +copy_vec_table: + + move.l (%a0)+,%d1 + or.l #ROM_BASE,%d1 + move.l %d1,(%a1)+ + subq.l #1,%d0 + bne copy_vec_table + +#if defined(SYSTEM_TABLE_ANCHOR_OFFSET) + | + | Clear the system table + | + + move.l #SYSTEM_TABLE_ANCHOR_OFFSET,%a0 + move.l #0,(%a0) +#endif + + | + | Copy the chip select swap code to DPRAM and run it + | + + move.l #boot_phase_2,%d0 + and.l #(ROM_SIZE - 1),%d0 + move.l %d0,%a0 | a0 -> remap code + lea %a5@(0),%a1 | a1 -> internal system RAM + + move.l #boot_phase_3,%d0 + and.l #(ROM_SIZE - 1),%d0 + sub.l %a0,%d0 + +copy_remap: + move.b (%a0)+,(%a1)+ | copy + dbra %d0,copy_remap + + | + | Jump to the remap code in the 68302''s internal system RAM. + | + + jsr %a5@(0) | execute the swap code + + | + | Map to the 68302 registers + | + + move.l #MC68302_BASE,%a5 + + | + | Copy initialized data area from ROM to RAM + | + +copy_data: + moveal #etext,%a0 | find the end of .text + moveal #data_start,%a1 | find the beginning of .data + moveal #edata,%a2 | find the end of .data + +copy_data_loop: + + movel %a0@+,%a1@+ | copy the data + cmpal %a2,%a1 + jlt copy_data_loop | loop until edata reached + + | + | zero out uninitialized data area + | + +zerobss: + moveal #end,%a0 | find end of .bss + moveal #bss_start,%a1 | find beginning of .bss + moveq #0,%d0 + +zerobss_loop: + + movel %d0,%a1@+ | to zero out uninitialized + cmpal %a0,%a1 + jlt zerobss_loop | loop until _end reached + + movel #end,%d0 | d0 = end of bss/start of heap + addl #heap_size,%d0 | d0 = end of heap + + movel %d0,stack_start | Save for brk() routine + addl #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 + + jsr boot_phase_3 + +| +| Create an unhandled exception jump table. The table has an entry for +| each vector in the vector table. The entry pushes the vector number onto +| the stack and then calls a common exception handler using PIC. +| +| The macros are to create the labels and format vectors. +| + +#define cat(x, y) x ## y +#define FORMAT_ID(n) (n << 2) +#define EXCEPTION_HANDLER(h, n) EH__##n: move.w cat(h, FORMAT_ID(n)),-(%sp) ; \ + bra common_exception_handler + +unhandled_exception: + +EXCEPTION_HANDLER(#, 0) +EXCEPTION_HANDLER(#, 1) +EXCEPTION_HANDLER(#, 2) +EXCEPTION_HANDLER(#, 3) +EXCEPTION_HANDLER(#, 4) +EXCEPTION_HANDLER(#, 5) +EXCEPTION_HANDLER(#, 6) +EXCEPTION_HANDLER(#, 7) +EXCEPTION_HANDLER(#, 8) +EXCEPTION_HANDLER(#, 9) + +EXCEPTION_HANDLER(#, 10) +EXCEPTION_HANDLER(#, 11) +EXCEPTION_HANDLER(#, 12) +EXCEPTION_HANDLER(#, 13) +EXCEPTION_HANDLER(#, 14) +EXCEPTION_HANDLER(#, 15) +EXCEPTION_HANDLER(#, 16) +EXCEPTION_HANDLER(#, 17) +EXCEPTION_HANDLER(#, 18) +EXCEPTION_HANDLER(#, 19) + +EXCEPTION_HANDLER(#, 20) +EXCEPTION_HANDLER(#, 21) +EXCEPTION_HANDLER(#, 22) +EXCEPTION_HANDLER(#, 23) +EXCEPTION_HANDLER(#, 24) +EXCEPTION_HANDLER(#, 25) +EXCEPTION_HANDLER(#, 26) +EXCEPTION_HANDLER(#, 27) +EXCEPTION_HANDLER(#, 28) +EXCEPTION_HANDLER(#, 29) + +EXCEPTION_HANDLER(#, 30) +EXCEPTION_HANDLER(#, 31) +EXCEPTION_HANDLER(#, 32) +EXCEPTION_HANDLER(#, 33) +EXCEPTION_HANDLER(#, 34) +EXCEPTION_HANDLER(#, 35) +EXCEPTION_HANDLER(#, 36) +EXCEPTION_HANDLER(#, 37) +EXCEPTION_HANDLER(#, 38) +EXCEPTION_HANDLER(#, 39) + +EXCEPTION_HANDLER(#, 40) +EXCEPTION_HANDLER(#, 41) +EXCEPTION_HANDLER(#, 42) +EXCEPTION_HANDLER(#, 43) +EXCEPTION_HANDLER(#, 44) +EXCEPTION_HANDLER(#, 45) +EXCEPTION_HANDLER(#, 46) +EXCEPTION_HANDLER(#, 47) +EXCEPTION_HANDLER(#, 48) +EXCEPTION_HANDLER(#, 49) + +EXCEPTION_HANDLER(#, 50) +EXCEPTION_HANDLER(#, 51) +EXCEPTION_HANDLER(#, 52) +EXCEPTION_HANDLER(#, 53) +EXCEPTION_HANDLER(#, 54) +EXCEPTION_HANDLER(#, 55) +EXCEPTION_HANDLER(#, 56) +EXCEPTION_HANDLER(#, 57) +EXCEPTION_HANDLER(#, 58) +EXCEPTION_HANDLER(#, 59) + +EXCEPTION_HANDLER(#, 60) +EXCEPTION_HANDLER(#, 61) +EXCEPTION_HANDLER(#, 62) +EXCEPTION_HANDLER(#, 63) +EXCEPTION_HANDLER(#, 64) +EXCEPTION_HANDLER(#, 65) +EXCEPTION_HANDLER(#, 66) +EXCEPTION_HANDLER(#, 67) +EXCEPTION_HANDLER(#, 68) +EXCEPTION_HANDLER(#, 69) + +EXCEPTION_HANDLER(#, 70) +EXCEPTION_HANDLER(#, 71) +EXCEPTION_HANDLER(#, 72) +EXCEPTION_HANDLER(#, 73) +EXCEPTION_HANDLER(#, 74) +EXCEPTION_HANDLER(#, 75) +EXCEPTION_HANDLER(#, 76) +EXCEPTION_HANDLER(#, 77) +EXCEPTION_HANDLER(#, 78) +EXCEPTION_HANDLER(#, 79) + +EXCEPTION_HANDLER(#, 80) +EXCEPTION_HANDLER(#, 81) +EXCEPTION_HANDLER(#, 82) +EXCEPTION_HANDLER(#, 83) +EXCEPTION_HANDLER(#, 84) +EXCEPTION_HANDLER(#, 85) +EXCEPTION_HANDLER(#, 86) +EXCEPTION_HANDLER(#, 87) +EXCEPTION_HANDLER(#, 88) +EXCEPTION_HANDLER(#, 89) + +EXCEPTION_HANDLER(#, 90) +EXCEPTION_HANDLER(#, 91) +EXCEPTION_HANDLER(#, 92) +EXCEPTION_HANDLER(#, 93) +EXCEPTION_HANDLER(#, 94) +EXCEPTION_HANDLER(#, 95) +EXCEPTION_HANDLER(#, 96) +EXCEPTION_HANDLER(#, 97) +EXCEPTION_HANDLER(#, 98) +EXCEPTION_HANDLER(#, 99) + +EXCEPTION_HANDLER(#, 100) +EXCEPTION_HANDLER(#, 101) +EXCEPTION_HANDLER(#, 102) +EXCEPTION_HANDLER(#, 103) +EXCEPTION_HANDLER(#, 104) +EXCEPTION_HANDLER(#, 105) +EXCEPTION_HANDLER(#, 106) +EXCEPTION_HANDLER(#, 107) +EXCEPTION_HANDLER(#, 108) +EXCEPTION_HANDLER(#, 109) + +EXCEPTION_HANDLER(#, 110) +EXCEPTION_HANDLER(#, 111) +EXCEPTION_HANDLER(#, 112) +EXCEPTION_HANDLER(#, 113) +EXCEPTION_HANDLER(#, 114) +EXCEPTION_HANDLER(#, 115) +EXCEPTION_HANDLER(#, 116) +EXCEPTION_HANDLER(#, 117) +EXCEPTION_HANDLER(#, 118) +EXCEPTION_HANDLER(#, 119) + +EXCEPTION_HANDLER(#, 120) +EXCEPTION_HANDLER(#, 121) +EXCEPTION_HANDLER(#, 122) +EXCEPTION_HANDLER(#, 123) +EXCEPTION_HANDLER(#, 124) +EXCEPTION_HANDLER(#, 125) +EXCEPTION_HANDLER(#, 126) +EXCEPTION_HANDLER(#, 127) +EXCEPTION_HANDLER(#, 128) +EXCEPTION_HANDLER(#, 129) + +EXCEPTION_HANDLER(#, 130) +EXCEPTION_HANDLER(#, 131) +EXCEPTION_HANDLER(#, 132) +EXCEPTION_HANDLER(#, 133) +EXCEPTION_HANDLER(#, 134) +EXCEPTION_HANDLER(#, 135) +EXCEPTION_HANDLER(#, 136) +EXCEPTION_HANDLER(#, 137) +EXCEPTION_HANDLER(#, 138) +EXCEPTION_HANDLER(#, 139) + +EXCEPTION_HANDLER(#, 140) +EXCEPTION_HANDLER(#, 141) +EXCEPTION_HANDLER(#, 142) +EXCEPTION_HANDLER(#, 143) +EXCEPTION_HANDLER(#, 144) +EXCEPTION_HANDLER(#, 145) +EXCEPTION_HANDLER(#, 146) +EXCEPTION_HANDLER(#, 147) +EXCEPTION_HANDLER(#, 148) +EXCEPTION_HANDLER(#, 149) + +EXCEPTION_HANDLER(#, 150) +EXCEPTION_HANDLER(#, 151) +EXCEPTION_HANDLER(#, 152) +EXCEPTION_HANDLER(#, 153) +EXCEPTION_HANDLER(#, 154) +EXCEPTION_HANDLER(#, 155) +EXCEPTION_HANDLER(#, 156) +EXCEPTION_HANDLER(#, 157) +EXCEPTION_HANDLER(#, 158) +EXCEPTION_HANDLER(#, 159) + +EXCEPTION_HANDLER(#, 160) +EXCEPTION_HANDLER(#, 161) +EXCEPTION_HANDLER(#, 162) +EXCEPTION_HANDLER(#, 163) +EXCEPTION_HANDLER(#, 164) +EXCEPTION_HANDLER(#, 165) +EXCEPTION_HANDLER(#, 166) +EXCEPTION_HANDLER(#, 167) +EXCEPTION_HANDLER(#, 168) +EXCEPTION_HANDLER(#, 169) + +EXCEPTION_HANDLER(#, 170) +EXCEPTION_HANDLER(#, 171) +EXCEPTION_HANDLER(#, 172) +EXCEPTION_HANDLER(#, 173) +EXCEPTION_HANDLER(#, 174) +EXCEPTION_HANDLER(#, 175) +EXCEPTION_HANDLER(#, 176) +EXCEPTION_HANDLER(#, 177) +EXCEPTION_HANDLER(#, 178) +EXCEPTION_HANDLER(#, 179) + +EXCEPTION_HANDLER(#, 180) +EXCEPTION_HANDLER(#, 181) +EXCEPTION_HANDLER(#, 182) +EXCEPTION_HANDLER(#, 183) +EXCEPTION_HANDLER(#, 184) +EXCEPTION_HANDLER(#, 185) +EXCEPTION_HANDLER(#, 186) +EXCEPTION_HANDLER(#, 187) +EXCEPTION_HANDLER(#, 188) +EXCEPTION_HANDLER(#, 189) + +EXCEPTION_HANDLER(#, 190) +EXCEPTION_HANDLER(#, 191) +EXCEPTION_HANDLER(#, 192) +EXCEPTION_HANDLER(#, 193) +EXCEPTION_HANDLER(#, 194) +EXCEPTION_HANDLER(#, 195) +EXCEPTION_HANDLER(#, 196) +EXCEPTION_HANDLER(#, 197) +EXCEPTION_HANDLER(#, 198) +EXCEPTION_HANDLER(#, 199) + +EXCEPTION_HANDLER(#, 200) +EXCEPTION_HANDLER(#, 201) +EXCEPTION_HANDLER(#, 202) +EXCEPTION_HANDLER(#, 203) +EXCEPTION_HANDLER(#, 204) +EXCEPTION_HANDLER(#, 205) +EXCEPTION_HANDLER(#, 206) +EXCEPTION_HANDLER(#, 207) +EXCEPTION_HANDLER(#, 208) +EXCEPTION_HANDLER(#, 209) + +EXCEPTION_HANDLER(#, 210) +EXCEPTION_HANDLER(#, 211) +EXCEPTION_HANDLER(#, 212) +EXCEPTION_HANDLER(#, 213) +EXCEPTION_HANDLER(#, 214) +EXCEPTION_HANDLER(#, 215) +EXCEPTION_HANDLER(#, 216) +EXCEPTION_HANDLER(#, 217) +EXCEPTION_HANDLER(#, 218) +EXCEPTION_HANDLER(#, 219) + +EXCEPTION_HANDLER(#, 220) +EXCEPTION_HANDLER(#, 221) +EXCEPTION_HANDLER(#, 222) +EXCEPTION_HANDLER(#, 223) +EXCEPTION_HANDLER(#, 224) +EXCEPTION_HANDLER(#, 225) +EXCEPTION_HANDLER(#, 226) +EXCEPTION_HANDLER(#, 227) +EXCEPTION_HANDLER(#, 228) +EXCEPTION_HANDLER(#, 229) + +EXCEPTION_HANDLER(#, 230) +EXCEPTION_HANDLER(#, 231) +EXCEPTION_HANDLER(#, 232) +EXCEPTION_HANDLER(#, 233) +EXCEPTION_HANDLER(#, 234) +EXCEPTION_HANDLER(#, 235) +EXCEPTION_HANDLER(#, 236) +EXCEPTION_HANDLER(#, 237) +EXCEPTION_HANDLER(#, 238) +EXCEPTION_HANDLER(#, 239) + +EXCEPTION_HANDLER(#, 240) +EXCEPTION_HANDLER(#, 241) +EXCEPTION_HANDLER(#, 242) +EXCEPTION_HANDLER(#, 243) +EXCEPTION_HANDLER(#, 244) +EXCEPTION_HANDLER(#, 245) +EXCEPTION_HANDLER(#, 246) +EXCEPTION_HANDLER(#, 247) +EXCEPTION_HANDLER(#, 248) +EXCEPTION_HANDLER(#, 249) + +EXCEPTION_HANDLER(#, 250) +EXCEPTION_HANDLER(#, 251) +EXCEPTION_HANDLER(#, 252) +EXCEPTION_HANDLER(#, 253) +EXCEPTION_HANDLER(#, 254) +EXCEPTION_HANDLER(#, 255) + + +common_exception_handler: + + | + | Need to put the format/vector above the PC and status register + | + + move.l %d0,-(%sp) | free a register + move.w 4(%sp),%d0 | get the format/vector id + + | + | If a bus error or address error then trash the extra + | data saved on the stack + | + + cmp.w #0x0008,%d0 + beq ceh_10 + + cmp.w #0x000C,%d0 + beq ceh_10 + + bra ceh_20 + +ceh_10: + + move.w %d0,12(%sp) | need to move the format/id + move.l (%sp)+,%d0 | recover d0 + addq #8,%sp | trash the stack + move.l %d0,-(%sp) | free a register, again + move.w 4(%sp),%d0 | get the format/vector id + +ceh_20: + + move.w 6(%sp),4(%sp) + move.w 8(%sp),6(%sp) + move.w 10(%sp),8(%sp) + move.w %d0,10(%sp) | put the format/vector id + move.l (%sp)+,%d0 + + | + | Save all the registers, pass control to a dump trace routine + | + + movem.l %d0-%d7/%a0-%a7,%sp@- + + | + | check to see if ROM is mapped to zero + | + + move.l #trace_exception,%d1 | get the linked address + and.l #(ROM_SIZE - 1),%d1 | obtain the offset into the ROM + lea.l %pc@(0),%a0 | were are we currently + move.l %a0,%d0 | need to use a data register + and.l #~(ROM_SIZE - 1),%d0 | keep the top part of the address + or.l %d1,%d0 | apply it to the trace exception offset + move.l %d0,%a0 | need an address register for jumping + jsr %a0@(0) + +ceh_30: + jmp ceh_30 +| +| The RAM based vector table +| + + .sect .vtable + + .global vector_table + +vector_table: + .space (256 * 4),0 + +| +| Initialised data +| + + .sect .data + + .global start_frame + +start_frame: + .space 4,0 + + .global stack_start + +stack_start: + .space 4,0 + +| +| Uninitialised data +| + + .sect .bss + + .global environ + .align 2 + +environ: + .long 0 + + .global heap_size + .set heap_size,0x2000 + + .global stack_size + .set stack_size,0x1000 + + diff --git a/c/src/lib/libbsp/m68k/ods68302/startup/Makefile.in b/c/src/lib/libbsp/m68k/ods68302/startup/Makefile.in new file mode 100644 index 0000000000..6db40dbea9 --- /dev/null +++ b/c/src/lib/libbsp/m68k/ods68302/startup/Makefile.in @@ -0,0 +1,59 @@ +# +# $Id$ +# + +@SET_MAKE@ +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH=@srcdir@:@srcdir@/../../shared:@srcdir@/../../../shared + +PGM=${ARCH}/startup.rel + +# C source names, if any, go here -- minus the .c +C_PIECES=crc debugport gdb-hooks m68302scc m68k-stub memcheck trace \ + bspstart bspclean sbrk setvec +C_FILES=$(C_PIECES:%=%.c) +C_O_FILES=$(C_PIECES:%=${ARCH}/%.o) + +H_FILES= + +SRCS=$(C_FILES) $(H_FILES) $(srcdir)/rom $(srcdir)/debugger +OBJS=$(C_O_FILES) + +include $(RTEMS_CUSTOM) +include $(PROJECT_ROOT)/make/leaf.cfg + +# +# (OPTIONAL) Add local stuff here using += +# + +DEFINES += +CPPFLAGS += +CFLAGS += + +LD_PATHS += +LD_LIBS += +LDFLAGS += + +# +# Add your list of files to delete here. The config files +# already know how to delete some stuff, so you may want +# to just run 'make clean' first to see what gets missed. +# 'make clobber' already includes 'make clean' +# + +CLEAN_ADDITIONS += +CLOBBER_ADDITIONS += + +${PGM}: ${SRCS} ${OBJS} + $(make-rel) + +$(srcdir)/rom: + +$(srcdir)/debugger: + +all: ${ARCH} $(SRCS) $(PGM) + $(INSTALL) $(srcdir)/rom $(srcdir)/debugger ${PROJECT_RELEASE}/lib + +# the .rel file built here will be put into libbsp.a by ../wrapup/Makefile + diff --git a/c/src/lib/libbsp/m68k/ods68302/startup/bspclean.c b/c/src/lib/libbsp/m68k/ods68302/startup/bspclean.c new file mode 100644 index 0000000000..90f64272a3 --- /dev/null +++ b/c/src/lib/libbsp/m68k/ods68302/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-1997. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may in + * the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + +#include +#include + +void bsp_cleanup( void ) +{ +} diff --git a/c/src/lib/libbsp/m68k/ods68302/startup/bspstart.c b/c/src/lib/libbsp/m68k/ods68302/startup/bspstart.c new file mode 100644 index 0000000000..c3c7bd538b --- /dev/null +++ b/c/src/lib/libbsp/m68k/ods68302/startup/bspstart.c @@ -0,0 +1,263 @@ +/* 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-1997. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may in + * the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + +#include +#include + +#include + +#include +#include + +#ifdef STACK_CHECKER_ON +#include +#endif + +/* + * 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; +rtems_interrupt_level bsp_isr_level; + +char *rtems_progname; + +/* 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); + + /* + * Init the RTEMS libio facility to provide UNIX-like system + * calls for use by newlib (ie: provide __rtems_open, __rtems_close, etc) + * Uses malloc() to get area for the iops, so must be after malloc init + */ + + rtems_libio_init(); + + /* + * 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 */ +} + +/* + * 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. + * + * NOTES: + * Must not use libc (to do io) from here, since drivers are + * not yet initialized. + * + */ + +void +bsp_pretasking_hook(void) +{ + bsp_libc_init(); + +#ifdef STACK_CHECKER_ON + /* + * Initialize the stack bounds checker + * We can either turn it on here or from the app. + */ + + Stack_check_Initialize(); +#endif + +#ifdef RTEMS_DEBUG + rtems_debug_enable( RTEMS_DEBUG_ALL_MASK ); +#endif +} + + +/* + * After drivers are setup, register some "filenames" + * and open stdin, stdout, stderr files + * + * Newlib will automatically associate the files with these + * (it hardcodes the numbers) + */ + +void +bsp_postdriver_hook(void) +{ + int stdin_fd, stdout_fd, stderr_fd; + int error_code; + + error_code = 'S' << 24 | 'T' << 16; + + if ((stdin_fd = __rtems_open("/dev/console", O_RDONLY, 0)) == -1) + rtems_fatal_error_occurred( error_code | 'D' << 8 | '0' ); + + if ((stdout_fd = __rtems_open("/dev/console", O_WRONLY, 0)) == -1) + rtems_fatal_error_occurred( error_code | 'D' << 8 | '1' ); + + if ((stderr_fd = __rtems_open("/dev/console", O_WRONLY, 0)) == -1) + rtems_fatal_error_occurred( error_code | 'D' << 8 | '2' ); + + if ((stdin_fd != 0) || (stdout_fd != 1) || (stderr_fd != 2)) + rtems_fatal_error_occurred( error_code | 'I' << 8 | 'O' ); +} + +void bsp_start() +{ + /* + * 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. + */ +#if 0 + Cpu_table.interrupt_vector_table = (mc68000_isr *) 0/*&M68Kvec*/; +#endif + + + /* + * Copy the Configuration Table .. so we can change it + */ + + BSP_Configuration = Configuration; + + /* + * Add 1 region for the RTEMS Malloc + */ + + BSP_Configuration.RTEMS_api_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 + + /* + * Tell libio how many fd's we want and allow it to tweak config + */ + + rtems_libio_config(&BSP_Configuration, BSP_LIBIO_MAX_FDS); + + /* + * 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 *) + (RAM_END - BSP_Configuration.work_space_size); + + /* + * initialize the CPU table for this BSP + */ + + /* + * we do not use the pretasking_hook + */ + + Cpu_table.pretasking_hook = bsp_pretasking_hook; /* init libc, etc. */ + + Cpu_table.predriver_hook = NULL; + + Cpu_table.postdriver_hook = bsp_postdriver_hook; + + 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_mpci_receive_server_stack = 0; + + /* + * Don't forget the other CPU Table entries. + */ + + /* + * Start RTEMS + */ + + bsp_isr_level = rtems_initialize_executive_early( &BSP_Configuration, &Cpu_table ); +} + +int main(int argc, char **argv, char **environ) +{ + if ((argc > 0) && argv && argv[0]) + rtems_progname = argv[0]; + else + rtems_progname = "RTEMS"; + + rtems_initialize_executive_late( bsp_isr_level ); + + bsp_cleanup(); + + return 0; +} + +void boot_bsp() +{ + /* the atexit hook will be before the static destructor list's entry + point */ + bsp_start(); + + exit(main(0, 0, 0)); +} + diff --git a/c/src/lib/libbsp/m68k/ods68302/startup/cpuboot.c b/c/src/lib/libbsp/m68k/ods68302/startup/cpuboot.c new file mode 100644 index 0000000000..1a8f9bd2cf --- /dev/null +++ b/c/src/lib/libbsp/m68k/ods68302/startup/cpuboot.c @@ -0,0 +1,133 @@ +/*****************************************************************************/ +/* + Boot the CPU. + + Occurs in 3 phases for a 68302. + + Phase 1. + + Called as soon as able after reset. The BAR has been programed, and + a small stack exists in the DPRAM. All interrupts are masked, and + the processor is running in supervisor mode. No other hardware or + chip selects are active. + + This phase programs the chip select registers, the parallel ports + are set into default configurations, and basic registers cleared or + reset. The leds are programmed to show the end of phase 1. + + Phase 2. + + This is a piece of code which is copied to DPRAM and executed. It + should not do any more thann is currently present. The return to ROM + is managed by modifing the return address. Again leds show the status. + + Phase 3. + + This code executes with a valid C environment. That is the data + section has been intialised and the bss section set to 0. This phase + performs any special card initialisation and then calls boot card. + + $Id$ + +*/ +/*****************************************************************************/ + +#include +#include +#include +#include + +/* + Open the address, reset all registers + */ + +void boot_phase_1() +{ + M302_SCR = SCR_DEFAULT; + + WRITE_OR(CSEL_ROM, ROM_SIZE, ROM_WAIT_STATES, OR_MASK_RW, OR_MASK_FC); + WRITE_BR(CSEL_ROM, RAM_BASE, BR_READ_ONLY, BR_FC_NULL, BR_ENABLED); + WRITE_OR(CSEL_RAM, RAM_SIZE, RAM_WAIT_STATES, OR_MASK_RW, OR_MASK_FC); + WRITE_BR(CSEL_RAM, ROM_BASE, BR_READ_WRITE, BR_FC_NULL, BR_ENABLED); + +#if defined(CSEL_1) + WRITE_OR(CSEL_1, CSEL_1_SIZE, CSEL_1_WAIT_STATES, OR_MASK_RW, OR_MASK_FC); + WRITE_BR(CSEL_1, CSEL_1_BASE, BR_READ_WRITE, BR_FC_NULL, BR_ENABLED); +#endif + +#if defined(CSEL_2) + WRITE_OR(CSEL_2, CSEL_2_SIZE, CSEL_2_WAIT_STATES, OR_MASK_RW, OR_MASK_FC); + WRITE_BR(CSEL_2, CSEL_2_BASE, BR_READ_WRITE, BR_FC_NULL, BR_ENABLED); +#endif + + m302.reg.gimr = m302.reg.ipr = m302.reg.imr = m302.reg.isr = 0; + + m302.reg.simode = 0; + + m302.reg.pacnt = CARD_PA_CONFIGURATION; + m302.reg.paddr = CARD_PA_DEFAULT_DIRECTIONS; + m302.reg.padat = CARD_PA_DEFAULT_DATA; + + m302.reg.pbcnt = CARD_PB_CONFIGURATION; + m302.reg.pbddr = CARD_PB_DEFAULT_DIRECTIONS; + m302.reg.pbdat = CARD_PB_DEFAULT_DATA; + + m302.reg.wrr = WATCHDOG_TIMEOUT_PERIOD | WATCHDOG_ENABLE; + +#if defined(LED_CONTROL) + LED_CONTROL(LED_1_RED, LED_2_OFF, LED_3_OFF, LED_4_OFF, + LED_5_OFF, LED_6_OFF, LED_7_OFF, LED_8_OFF); +#endif +} + +/* + Swap the chip select mapping for ROM and RAM + */ + +void boot_phase_2(void) +{ + rtems_unsigned32 stack; + +#if defined(LED_CONTROL) + LED_CONTROL(LED_1_RED, LED_2_RED, LED_3_OFF, LED_4_OFF, + LED_5_OFF, LED_6_OFF, LED_7_OFF, LED_8_OFF); +#endif + + WRITE_BR(CSEL_ROM, ROM_BASE, BR_READ_ONLY, BR_FC_NULL, BR_ENABLED); + WRITE_BR(CSEL_RAM, RAM_BASE, BR_READ_WRITE, BR_FC_NULL, BR_ENABLED); + +#if defined(LED_CONTROL) + LED_CONTROL(LED_1_GREEN, LED_2_RED, LED_3_OFF, LED_4_OFF, + LED_5_OFF, LED_6_OFF, LED_7_OFF, LED_8_OFF); +#endif + + /* seems to want 2, looked at assember code output */ + *(&stack + 2) |= ROM_BASE; +} + +/* + Any pre-main initialisation, the C environment is setup, how-ever C++ + static constructors have not been called, and RTEMS is not initialised. + */ + +void boot_bsp(); +void set_debug_traps(); +void breakpoint(); + +void boot_phase_3(void) +{ + if (GDB_RUN_MONITOR()) + { + set_debug_traps(); + breakpoint(); + } + + debug_port_banner(); + + /* FIXME : add RAM and ROM checks */ + + /* boot the bsp, what ever this means */ + boot_bsp(); + + WATCHDOG_TRIGGER(); +} diff --git a/c/src/lib/libbsp/m68k/ods68302/startup/crc.c b/c/src/lib/libbsp/m68k/ods68302/startup/crc.c new file mode 100644 index 0000000000..b589ccd2ba --- /dev/null +++ b/c/src/lib/libbsp/m68k/ods68302/startup/crc.c @@ -0,0 +1,88 @@ +/*****************************************************************************/ +/* + $Id$ + + CRC 16 Calculation + + This module calculates the CRC-16. + + */ +/*****************************************************************************/ + +#include "bsp.h" +#include "m68302.h" +#include "crc.h" + + /* ---- + C O N S T A N T S + + */ + +static const rtems_unsigned16 factor[] = + { + 0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241, + 0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440, + 0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40, + 0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841, + 0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40, + 0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41, + 0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641, + 0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040, + 0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240, + 0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441, + 0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41, + 0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840, + 0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41, + 0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40, + 0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640, + 0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041, + 0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240, + 0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441, + 0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41, + 0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840, + 0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41, + 0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40, + 0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640, + 0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041, + 0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241, + 0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440, + 0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40, + 0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841, + 0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40, + 0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41, + 0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641, + 0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040 + }; + +/* + MACRO : calculates a CRC byte wise + */ + +#define NEW_CRC(byte, crc) factor[(byte) ^ ((crc) & 0xFF)] ^ (((crc) >> 8) & 0xFF) + +/* ---- + CalcCRC + + Calculates the CRC value of a block of memory +*/ + +rtems_unsigned16 calc_crc(void* vdata, /* pointer to memory block */ + rtems_unsigned32 count) /* length of block in bytes */ +{ + register rtems_unsigned8 *data = vdata; + register rtems_unsigned16 crc; + register rtems_unsigned32 byte; + + /* initialise to either 0x0 or 0xffff depending on the + CRC implementation */ + + crc = 0; + + for (byte = count; byte > 0; byte--) + { + WATCHDOG_TOGGLE(); + crc = NEW_CRC(*data++, crc); + } + + return crc; +} diff --git a/c/src/lib/libbsp/m68k/ods68302/startup/debugger b/c/src/lib/libbsp/m68k/ods68302/startup/debugger new file mode 100644 index 0000000000..6009868468 --- /dev/null +++ b/c/src/lib/libbsp/m68k/ods68302/startup/debugger @@ -0,0 +1,54 @@ +/* + * $Id$ + * + * MC68302 Linker command file + * + */ + +SECTIONS +{ + .text . : + { + text_start = .; + *(.text) + etext = .; + . = ALIGN(4); + __CTOR_LIST__ = .; + LONG((__CTOR_END__ - __CTOR_LIST__) / 4 - 2) + *(.ctors) + LONG(0) + __CTOR_END__ = .; + . = ALIGN(4); + __DTOR_LIST__ = .; + LONG((__DTOR_END__ - __DTOR_LIST__) / 4 - 2) + *(.dtors) + LONG(0) + __DTOR_END__ = .; + } + + .vtable (ADDR(.text) + SIZEOF(.text)) : + { + vtable_start = .; + *(.vtable) + evtable = .; + } + .data (ADDR(.vtable) + SIZEOF(.vtable)) : + { + data_start = .; + *(.data) + edata = .; + } + .bss (ADDR(.data) + SIZEOF(.data)) : + { + bss_start = .; + *(.bss) + *(COMMON) + end = . ; + _end = . ; + } +} + +m302 = MC68302_BASE; +_VBR = 0; /* location of the VBR table (in RAM) */ + +ENTRY(start); diff --git a/c/src/lib/libbsp/m68k/ods68302/startup/debugport.c b/c/src/lib/libbsp/m68k/ods68302/startup/debugport.c new file mode 100644 index 0000000000..b4616152a3 --- /dev/null +++ b/c/src/lib/libbsp/m68k/ods68302/startup/debugport.c @@ -0,0 +1,163 @@ +/*****************************************************************************/ +/* + High Level Debug Port Functions + + $Id$ + + */ +/*****************************************************************************/ + +#include +#include + +#include "debugport.h" +#include "m68302scc.h" +#include "bsp.h" + +static int initialised; + +void debug_port_initialise(void) +{ + scc_initialise(CONSOLE_PORT, CONSOLE_BAUD, FALSE); +#if defined(DEBUG_PORT) + scc_initialise(DEBUG_PORT, DEBUG_BAUD, FALSE); +#endif +} + +unsigned char debug_port_status(const unsigned char status) +{ + if (!initialised) + { + initialised = 1; + debug_port_initialise(); + } + + return scc_status(CONSOLE_PORT, status); +} + +unsigned char debug_port_in(void) +{ + if (!initialised) + { + initialised = 1; + debug_port_initialise(); + } + + return scc_in(CONSOLE_PORT); +} + +void debug_port_out(const unsigned char character) +{ + if (!initialised) + { + initialised = 1; + debug_port_initialise(); + } + + scc_out(CONSOLE_PORT, character); +} + +void debug_port_write(const char *buffer) +{ + while (*buffer != '\0') + { + debug_port_out(*buffer++); + } +} + +void debug_port_write_buffer(const char *buffer, unsigned int size) +{ + unsigned int count; + for (count = 0; count < size; count++) + { + debug_port_out(buffer[count]); + } +} + +void debug_port_write_hex_uint(const unsigned int value) +{ + unsigned int bits = sizeof(value) * 8; + unsigned char c; + + do + { + bits -= 4; + c = (unsigned char) ((value >> bits) & 0x0F); + if (c < 10) + { + c += '0'; + } + else + { + c += 'a' - 10; + } + debug_port_out((char) c); + } + while (bits); +} + +void debug_port_write_hex_ulong(const unsigned long value) +{ + unsigned int bits = sizeof(value) * 8; + unsigned char c; + + do + { + bits -= 4; + c = (unsigned char) ((value >> bits) & 0x0F); + if (c < 10) + { + c += '0'; + } + else + { + c += 'a' - 10; + } + debug_port_out((char) c); + } + while (bits); +} + +#define BUFFER_SIZE (256) +static char buffer[BUFFER_SIZE]; + +void debug_port_printf(const char *format, ...) +{ + va_list args; + int written; + + /* gain access to the argument list */ + va_start(args, format); + + /* set the trap */ + buffer[BUFFER_SIZE - 2] = '\xAA'; + buffer[BUFFER_SIZE - 1] = '\x55'; + + /* format the string and send to stdout */ + written = vsprintf(buffer, format, args); + + /* try an trap format buffer overflows */ + if ((buffer[BUFFER_SIZE - 2] != '\xAA') || + (buffer[BUFFER_SIZE - 1] != '\x55')) + { + debug_port_write("debug port buffer overflow, halting..."); + DISABLE_WATCHDOG(); + while (1 == 1); + } + + /* see if an error occurred, if not flush the output buffer */ + if (written != -1) + { + debug_port_write_buffer(buffer, written); + } +} + +void debug_port_banner(void) +{ +#define CARD_LABEL "ods68302-" #VARIANT + + debug_port_write("\n\n\r"); + debug_port_write(_Copyright_Notice); + debug_port_write("\n\r " CARD_ID "\n\r"); +} + diff --git a/c/src/lib/libbsp/m68k/ods68302/startup/gdb-hooks.c b/c/src/lib/libbsp/m68k/ods68302/startup/gdb-hooks.c new file mode 100644 index 0000000000..64d220219f --- /dev/null +++ b/c/src/lib/libbsp/m68k/ods68302/startup/gdb-hooks.c @@ -0,0 +1,76 @@ +/*****************************************************************************/ +/* + $Id$ + + Hooks for GDB + + */ +/*****************************************************************************/ + + +#include +#include +#include + +static int initialised = 0; + +void putDebugChar(char ch) +{ + if (!initialised) + { + scc_initialise(DEBUG_PORT, DEBUG_BAUD, 0); + initialised = 1; + } + + scc_out(DEBUG_PORT, ch); +} + +char getDebugChar(void) +{ + if (!initialised) + { + scc_initialise(DEBUG_PORT, DEBUG_BAUD, 0); + initialised = 1; + } + + while (!scc_status(DEBUG_PORT, 0)); + + return scc_in(DEBUG_PORT); +} + +/* + * Need to create yet another jump table for gdb this time + */ + +void (*exceptionHook)(unsigned int) = 0; + +typedef struct { + rtems_unsigned16 move_a7; /* move #FORMAT_ID,%a7@- */ + rtems_unsigned16 format_id; + rtems_unsigned16 jmp; /* jmp _ISR_Handlers */ + rtems_unsigned32 isr_handler; +} GDB_HANDLER_ENTRY; + +#if !defined(M68K_MOVE_A7) +#define M68K_MOVE_A7 0x3F3C +#endif + +#if !defined(M68K_JMP) +#define M68K_JMP 0x4EF9 +#endif + +/* points to jsr-exception-table in targets wo/ VBR register */ +static GDB_HANDLER_ENTRY gdb_jump_table[256]; + +void exceptionHandler(unsigned int vector, void *handler) +{ + rtems_unsigned32 *interrupt_table = 0; + + gdb_jump_table[vector].move_a7 = M68K_MOVE_A7; + gdb_jump_table[vector].format_id = vector; + gdb_jump_table[vector].jmp = M68K_JMP; + gdb_jump_table[vector].isr_handler = (rtems_unsigned32) handler; + + interrupt_table[vector] = (rtems_unsigned32) &gdb_jump_table[vector]; +} + diff --git a/c/src/lib/libbsp/m68k/ods68302/startup/linkcmds b/c/src/lib/libbsp/m68k/ods68302/startup/linkcmds new file mode 100644 index 0000000000..225cc92f26 --- /dev/null +++ b/c/src/lib/libbsp/m68k/ods68302/startup/linkcmds @@ -0,0 +1,55 @@ +/* + * $Id$ + * + * MC68302 Linker command file + * + */ + +SECTIONS +{ + .text . : + { + text_start = .; + *(.text) + etext = .; + . = ALIGN(4); + __CTOR_LIST__ = .; + LONG((__CTOR_END__ - __CTOR_LIST__) / 4 - 2) + *(.ctors) + LONG(0) + __CTOR_END__ = .; + . = ALIGN(4); + __DTOR_LIST__ = .; + LONG((__DTOR_END__ - __DTOR_LIST__) / 4 - 2) + *(.dtors) + LONG(0) + __DTOR_END__ = .; + } + + .vtable 0 : + { + vtable_start = .; + *(.vtable) + evtable = .; + } + + .data (ADDR(.vtable) + SIZEOF(.vtable)) : + AT (ADDR(.text) + SIZEOF(.text)) + { + data_start = .; + *(.data) + edata = .; + } + .bss (ADDR(.data) + SIZEOF(.data)) : + { + bss_start = .; + *(.bss) + *(COMMON) + end = . ; + _end = . ; + } +} + +m302 = MC68302_BASE; +_VBR = ADDR(.vtable); /* location of the VBR table (in RAM) */ + diff --git a/c/src/lib/libbsp/m68k/ods68302/startup/m68302scc.c b/c/src/lib/libbsp/m68k/ods68302/startup/m68302scc.c new file mode 100644 index 0000000000..77d7867a21 --- /dev/null +++ b/c/src/lib/libbsp/m68k/ods68302/startup/m68302scc.c @@ -0,0 +1,159 @@ +/*****************************************************************************/ +/* + $Id$ + + M68302 SCC Polled Driver + + */ +/*****************************************************************************/ + + +#include +#include +#include + +#define M68302_SCC_COUNT (3) + +static volatile m302_SCC_t *scc[M68302_SCC_COUNT] = { 0, 0, 0 }; +static volatile m302_SCC_Registers_t *scc_reg[M68302_SCC_COUNT] = { 0, 0, 0 }; +static int scc_translate[M68302_SCC_COUNT] = { 0, 0, 0 }; + +static const rtems_unsigned16 baud_clocks[] = +{ + (SYSTEM_CLOCK / ( 4800 * 16)), + (SYSTEM_CLOCK / ( 9600 * 16)), + (SYSTEM_CLOCK / ( 19200 * 16)), + (SYSTEM_CLOCK / ( 38400 * 16)), + (SYSTEM_CLOCK / ( 57600 * 16)), + (SYSTEM_CLOCK / (115700 * 16)) +}; + +void scc_initialise(int channel, int baud, int translate) +{ + rtems_unsigned16 scon; + + if (channel < M68302_SCC_COUNT) + { + scc[channel] = &m302.scc1 + channel; + scc_reg[channel] = &m302.reg.scc[channel]; + scc_translate[channel] = translate; + + scon = (baud_clocks[baud] & 0xF800) == 0 ? 0 : 1; + scon |= (((baud_clocks[baud] / (1 + scon * 3)) - 1) << 1) & 0x0FFE; + + scc_reg[channel]->scon = scon; + scc_reg[channel]->scm = 0x0171; + + scc[channel]->bd.tx[0].status = 0x2000; + scc[channel]->bd.tx[0].length = 0; + scc[channel]->bd.tx[0].buffer = + (rtems_unsigned8*) &(scc[channel]->bd.tx[1].buffer); + + scc[channel]->bd.rx[0].status = 0x2000; + scc[channel]->bd.rx[0].length = 0; + scc[channel]->bd.rx[0].buffer = + (rtems_unsigned8*) &(scc[channel]->bd.rx[1].buffer); + + scc[channel]->parm.rfcr = 0x50; + scc[channel]->parm.tfcr = 0x50; + + scc[channel]->parm.mrblr = 0x0001; + scc[channel]->prot.uart.max_idl = 0x0004; + scc[channel]->prot.uart.brkcr = 1; + scc[channel]->prot.uart.parec = 0; + scc[channel]->prot.uart.frmec = 0; + scc[channel]->prot.uart.nosec = 0; + scc[channel]->prot.uart.brkec = 0; + scc[channel]->prot.uart.uaddr1 = 0; + scc[channel]->prot.uart.uaddr2 = 0; + scc[channel]->prot.uart.character[0] = 0x0003; + scc[channel]->prot.uart.character[1] = 0x8000; + + scc_reg[channel]->scce = 0xFF; + scc_reg[channel]->sccm = 0x15; + + scc_reg[channel]->scm = 0x17d; + } +} + +unsigned char scc_status(int channel, unsigned char status) +{ + rtems_unsigned16 rx_status; + + m302.reg.wcn = 0; + + if ((channel < M68302_SCC_COUNT) && scc[channel]) + { + rx_status = scc[channel]->bd.rx[0].status; + + if ((rx_status & 0x8000) == 0) + { + if (rx_status & 0x003B) + { + return 2; + } + if (status == 0) + { + return 1; + } + } + } + + return 0; +} + +unsigned char scc_in(int channel) +{ + m302.reg.wcn = 0; + + if ((channel < M68302_SCC_COUNT) && scc[channel]) + { + if ((scc[channel]->bd.rx[0].status & 0x8000) == 0) + { + unsigned char c; + + c = *(scc[channel]->bd.rx[0].buffer); + + scc[channel]->bd.rx[0].status = 0xa000; + + return c; + } + } + + return 0; +} + +void scc_out(int channel, unsigned char character) +{ + if ((channel < M68302_SCC_COUNT) && scc[channel]) + { + do + { + m302.reg.wcn = 0; + } + while (scc[channel]->bd.tx[0].status & 0x8000); + + *(scc[channel]->bd.tx[0].buffer) = character; + + scc[channel]->bd.tx[0].length = 1; + scc[channel]->bd.tx[0].status = 0xa000; + + if (scc_translate[channel]) + { + if (character == '\n') + { + scc_out(channel, '\r'); + } + } + } +} + + + + + + + + + + diff --git a/c/src/lib/libbsp/m68k/ods68302/startup/m68k-stub.c b/c/src/lib/libbsp/m68k/ods68302/startup/m68k-stub.c new file mode 100644 index 0000000000..f9172f4c9f --- /dev/null +++ b/c/src/lib/libbsp/m68k/ods68302/startup/m68k-stub.c @@ -0,0 +1,1084 @@ +/**************************************************************************** + + THIS SOFTWARE IS NOT COPYRIGHTED + + HP offers the following for use in the public domain. HP makes no + warranty with regard to the software or it's performance and the + user accepts the software "AS IS" with all faults. + + HP DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD + TO THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + +****************************************************************************/ + +/**************************************************************************** + * Header: remcom.c,v 1.34 91/03/09 12:29:49 glenne Exp $ + * + * Module name: remcom.c $ + * Revision: 1.34 $ + * Date: 91/03/09 12:29:49 $ + * Contributor: Lake Stevens Instrument Division$ + * + * Description: low level support for gdb debugger. $ + * + * Considerations: only works on target hardware $ + * + * Written by: Glenn Engel $ + * ModuleState: Experimental $ + * + * NOTES: See Below $ + * + * To enable debugger support, two things need to happen. One, a + * call to set_debug_traps() is necessary in order to allow any breakpoints + * or error conditions to be properly intercepted and reported to gdb. + * Two, a breakpoint needs to be generated to begin communication. This + * is most easily accomplished by a call to breakpoint(). Breakpoint() + * simulates a breakpoint by executing a trap #1. The breakpoint instruction + * is hardwired to trap #1 because not to do so is a compatibility problem-- + * there either should be a standard breakpoint instruction, or the protocol + * should be extended to provide some means to communicate which breakpoint + * instruction is in use (or have the stub insert the breakpoint). + * + * Some explanation is probably necessary to explain how exceptions are + * handled. When an exception is encountered the 68000 pushes the current + * program counter and status register onto the supervisor stack and then + * transfers execution to a location specified in it's vector table. + * The handlers for the exception vectors are hardwired to jmp to an address + * given by the relation: (exception - 256) * 6. These are decending + * addresses starting from -6, -12, -18, ... By allowing 6 bytes for + * each entry, a jsr, jmp, bsr, ... can be used to enter the exception + * handler. Using a jsr to handle an exception has an added benefit of + * allowing a single handler to service several exceptions and use the + * return address as the key differentiation. The vector number can be + * computed from the return address by [ exception = (addr + 1530) / 6 ]. + * The sole purpose of the routine _catchException is to compute the + * exception number and push it on the stack in place of the return address. + * The external function exceptionHandler() is + * used to attach a specific handler to a specific m68k exception. + * For 68020 machines, the ability to have a return address around just + * so the vector can be determined is not necessary because the '020 pushes an + * extra word onto the stack containing the vector offset + * + * Because gdb will sometimes write to the stack area to execute function + * calls, this program cannot rely on using the supervisor stack so it + * uses it's own stack area reserved in the int array remcomStack. + * + ************* + * + * The following gdb commands are supported: + * + * command function Return value + * + * g return the value of the CPU registers hex data or ENN + * G set the value of the CPU registers OK or ENN + * + * mAA..AA,LLLL Read LLLL bytes at address AA..AA hex data or ENN + * MAA..AA,LLLL: Write LLLL bytes at address AA.AA OK or ENN + * + * c Resume at current address SNN ( signal NN) + * cAA..AA Continue at address AA..AA SNN + * + * s Step one instruction SNN + * sAA..AA Step one instruction from AA..AA SNN + * + * k kill + * + * ? What was the last sigval ? SNN (signal NN) + * + * All commands and responses are sent with a packet which includes a + * checksum. A packet consists of + * + * $#. + * + * where + * :: + * :: < two hex digits computed as modulo 256 sum of > + * + * When a packet is received, it is first acknowledged with either '+' or '-'. + * '+' indicates a successful transfer. '-' indicates a failed transfer. + * + * Example: + * + * Host: Reply: + * $m0,10#2a +$00010203040506070809101112131415#42 + * + ****************************************************************************/ + +#include +#include +#include + +#include +#include + +/************************************************************************ + * + * external low-level support routines + */ +typedef void (*ExceptionHook)(int); /* pointer to function with int parm */ +typedef void (*Function)(void); /* pointer to a function */ + +/* assign an exception handler */ +Function exceptionHandler(int vector, Function handler); +extern ExceptionHook exceptionHook; /* hook variable for errors/exceptions */ + +int putDebugChar(char ch); +char getDebugChar(void); + +/************************/ +/* FORWARD DECLARATIONS */ +/************************/ +static int hex(char ch); +static void getpacket(char *buffer); +static void putpacket(char *buffer); +static char* mem2hex(char *mem, char *buf, int count); +static char* hex2mem(char *buf, char *mem, int count); +static void handle_buserror(void); +static int computeSignal(int exceptionVector); +static int hexToInt(char **ptr, int *intValue); + void handle_exception(int exceptionVector); +static void initializeRemcomErrorFrame(void); + +void set_debug_traps(void); +void breakpoint(void); + +/************************************************************************/ +/* BUFMAX defines the maximum number of characters in inbound/outbound buffers*/ +/* at least NUMREGBYTES*2 are needed for register packets */ +#define BUFMAX 400 + +static char initialized; /* boolean flag. != 0 means we've been initialized */ + +int remote_debug; +/* debug > 0 prints ill-formed commands in valid packets & checksum errors */ + +static const char hexchars[]="0123456789abcdef"; + +/* there are 180 bytes of registers on a 68020 w/68881 */ +/* many of the fpa registers are 12 byte (96 bit) registers */ +#define NUMREGBYTES 180 +enum regnames {D0,D1,D2,D3,D4,D5,D6,D7, + A0,A1,A2,A3,A4,A5,A6,A7, + PS,PC, + FP0,FP1,FP2,FP3,FP4,FP5,FP6,FP7, + FPCONTROL,FPSTATUS,FPIADDR + }; + + +/* We keep a whole frame cache here. "Why?", I hear you cry, "doesn't + GDB handle that sort of thing?" Well, yes, I believe the only + reason for this cache is to save and restore floating point state + (fsave/frestore). A cleaner way to do this would be to make the + fsave data part of the registers which GDB deals with like any + other registers. This should not be a performance problem if the + ability to read individual registers is added to the protocol. */ + +typedef struct FrameStruct +{ + struct FrameStruct *previous; + int exceptionPC; /* pc value when this frame created */ + int exceptionVector; /* cpu vector causing exception */ + short frameSize; /* size of cpu frame in words */ + short sr; /* for 68000, this not always sr */ + int pc; + short format; + int fsaveHeader; + int morejunk[0]; /* exception frame, fp save... */ +} Frame; + +#define FRAMESIZE 500 +int gdbFrameStack[FRAMESIZE]; +static Frame *lastFrame; + +/* + * these should not be static cuz they can be used outside this module + */ +int registers[NUMREGBYTES/4]; +int superStack; + +#define STACKSIZE 10000 +int remcomStack[STACKSIZE/sizeof(int)]; +static int* stackPtr = &remcomStack[STACKSIZE/sizeof(int) - 1]; + +/* + * In many cases, the system will want to continue exception processing + * when a continue command is given. + * oldExceptionHook is a function to invoke in this case. + */ + +static ExceptionHook oldExceptionHook; + +#if defined(__mc68020__) +/* the size of the exception stack on the 68020 varies with the type of + * exception. The following table is the number of WORDS used + * for each exception format. + */ +const short exceptionSize[] = { 4,4,6,4,4,4,4,4,29,10,16,46,12,4,4,4 }; +#endif + +#if defined(__mc68332__) +static const short exceptionSize[] = { 4,4,6,4,4,4,4,4,4,4,4,4,16,4,4,4 }; +#endif + +/************* jump buffer used for setjmp/longjmp **************************/ +jmp_buf remcomEnv; + +/*************************** ASSEMBLY CODE MACROS *************************/ +/* */ + +#if defined(__HAVE_68881__) + +/* do an fsave, then remember the address to begin a restore from */ +#define SAVE_FP_REGS() \ + asm(" fsave %a0@-"); \ + asm(" fmovemx %fp0-%fp7,registers+72"); \ + asm(" fmoveml %fpcr/%fpsr/%fpi,registers+168"); + +#define RESTORE_FP_REGS() \ +asm(" \n\ + fmoveml registers+168,%fpcr/%fpsr/%fpi \n\ + fmovemx registers+72,%fp0-%fp7 \n\ + cmpl #-1,%a0@ | skip frestore flag set ? \n\ + beq skip_frestore \n\ + frestore %a0@+ \n\ +skip_frestore: \n\ +"); + +#else + +#define SAVE_FP_REGS() +#define RESTORE_FP_REGS() + +#endif /* __HAVE_68881__ */ + +void return_to_super(void); +void return_to_user(void); + +asm(" + .text + + .globl return_to_super + .align 4 +return_to_super: + movel registers+60,%sp /* get new stack pointer */ + movel lastFrame,%a0 /* get last frame info */ + bra return_to_any + + .globl return_to_user + .align 4 + +return_to_user: + movel registers+60,%a0 /* get usp */ + movel %a0,%usp /* set usp */ + movel superStack,%sp /* get original stack pointer */ + +return_to_any: + movel lastFrame,%a0 /* get last frame info */ + movel %a0@+,lastFrame /* link in previous frame */ + addql #8,%a0 /* skip over pc, vector#*/ + movew %a0@+,%d0 /* get # of words in cpu frame */ + addw %d0,%a0 /* point to end of data */ + addw %d0,%a0 /* point to end of data */ + movel %a0,%a1 +# +# copy the stack frame + subql #1,%d0 + +copyUserLoop: + movew %a1@-,%sp@- + dbf %d0,copyUserLoop +"); + RESTORE_FP_REGS() +asm(" + moveml registers,%d0-%d7/%a0-%a6 + rte /* pop and go! */ +"); + +#define DISABLE_INTERRUPTS() asm(" oriw #0x0700,%sr"); +#define BREAKPOINT() asm(" trap #1"); + +/* this function is called immediately when a level 7 interrupt occurs */ +/* if the previous interrupt level was 7 then we're already servicing */ +/* this interrupt and an rte is in order to return to the debugger. */ +/* For the 68000, the offset for sr is 6 due to the jsr return address */ +asm(" + .text + .globl _debug_level7 + .align 4 + +_debug_level7: + movew %d0,%sp@- +"); + +#if defined(__mc68020__) || defined(__mc68332__) +asm(" + movew %sp@(2),%d0 +"); +#else +asm(" + movew %sp@(6),%d0 +"); +#endif +asm(" + andiw #0x700,%d0 + cmpiw #0x700,%d0 + beq _already7 + movew %sp@+,%d0 + bra _catchException +_already7: + movew %sp@+,%d0 +"); +#if defined (__m68000__) && !defined(__mc68020__) +asm(" + lea %sp@(4),%sp"); /* pull off 68000 return address */ +#endif +asm(" + rte +"); + +extern void _catchException(void); + +#if defined(__mc68020__) || defined(__mc68332__) +/* This function is called when a 68020 exception occurs. It saves + * all the cpu and fpcp regs in the _registers array, creates a frame on a + * linked list of frames which has the cpu and fpcp stack frames needed + * to properly restore the context of these processors, and invokes + * an exception handler (remcom_handler). + * + * stack on entry: stack on exit: + * N bytes of junk exception # MSWord + * Exception Format Word exception # MSWord + * Program counter LSWord + * Program counter MSWord + * Status Register + * + * + */ +asm(" + .text + + .globl _catchException + .align 4 +_catchException: +"); + +DISABLE_INTERRUPTS(); + +asm(" + moveml %d0-%d7/%a0-%a6,registers /* save registers */ + movel lastFrame,%a0 /* last frame pointer */ +"); +SAVE_FP_REGS(); +asm(" + lea registers,%a5 /* get address of registers */ + movew %sp@,%d1 /* get status register */ + movew %d1,%a5@(66) /* save sr */ + movel %sp@(2),%a4 /* save pc in %a4 for later use */ + movel %a4,%a5@(68) /* save pc in _regisers[] */ + +# +# figure out how many bytes in the stack frame +# + movew %sp@(6),%d0 /* get '020 exception format */ + movew %d0,%d2 /* make a copy of format word */ + andiw #0xf000,%d0 /* mask off format type */ + rolw #5,%d0 /* rotate into the low byte *2 */ + lea exceptionSize,%a1 + addw %d0,%a1 /* index into the table */ + movew %a1@,%d0 /* get number of words in frame */ + movew %d0,%d3 /* save it */ + subw %d0,%a0 /* adjust save pointer */ + subw %d0,%a0 /* adjust save pointer(bytes) */ + movel %a0,%a1 /* copy save pointer */ + subql #1,%d0 /* predecrement loop counter */ +# +# copy the frame +# +saveFrameLoop: + movew %sp@+,%a1@+ + dbf %d0,saveFrameLoop +# +# now that the stack has been clenaed, +# save the %a7 in use at time of exception + + movel %sp,superStack /* save supervisor %sp */ + andiw #0x2000,%d1 /* were we in supervisor mode ? */ + beq userMode + movel %a7,%a5@(60) /* save %a7 */ + bra a7saveDone +userMode: + movel %usp,%a1 + movel %a1,%a5@(60) /* save user stack pointer */ +a7saveDone: + +# +# save size of frame + movew %d3,%a0@- + +# +# compute exception number + andl #0xfff,%d2 /* mask off vector offset */ + lsrw #2,%d2 /* divide by 4 to get vect num */ + movel %d2,%a0@- /* save it */ +# +# save pc causing exception + movel %a4,%a0@- +# +# save old frame link and set the new value + movel lastFrame,%a1 /* last frame pointer */ + movel %a1,%a0@- /* save pointer to prev frame */ + movel %a0,lastFrame + + movel %d2,%sp@- /* push exception num */ + movel exceptionHook,%a0 /* get address of handler */ + jbsr %a0@ /* and call it */ + clrl %sp@ /* replace exception num parm with frame ptr */ + jbsr _returnFromException /* jbsr, but never returns */ + +"); + +#else /* mc68000 */ + +/* This function is called when an exception occurs. It translates the + * return address found on the stack into an exception vector # which + * is then handled by either handle_exception or a system handler. + * _catchException provides a front end for both. + * + * stack on entry: stack on exit: + * Program counter MSWord exception # MSWord + * Program counter LSWord exception # MSWord + * Status Register + * Return Address MSWord + * Return Address LSWord + */ +asm(" + .text + .globl _catchException + .align 4 +_catchException: +"); +DISABLE_INTERRUPTS(); +asm(" + moveml %d0-%d7/%a0-%a6,registers /* save registers */ + movel lastFrame,%a0 /* last frame pointer */ +"); + +SAVE_FP_REGS(); +asm(" + moveq.l #0,%d2 + movew %sp@+,%d2 + lea registers,%a5 /* get address of registers */ + + moveql #3,%d3 /* assume a three word frame */ + + cmpiw #3,%d2 /* bus error or address error ? */ + bgt normal /* if >3 then normal error */ + movel %sp@+,%a0@- /* copy error info to frame buff*/ + movel %sp@+,%a0@- /* these are never used */ + moveql #7,%d3 /* this is a 7 word frame */ + +normal: + movew %sp@+,%d1 /* pop status register */ + movel %sp@+,%a4 /* pop program counter */ + + cmpiw #33,%d2 /* trap #1, breakpoint ? */ + bne not_breakpoint + + subql #2,%a4 /* trap leaves the pc after the trap */ + +not_breakpoint: + movew %d1,%a5@(66) /* save sr */ + movel %a4,%a5@(68) /* save pc in _regisers[] */ + movel %a4,%a0@- /* copy pc to frame buffer */ + movew %d1,%a0@- /* copy sr to frame buffer */ + + movel %sp,superStack /* save supervisor %sp */ + + andiw #0x2000,%d1 /* were we in supervisor mode ? */ + beq userMode + movel %a7,%a5@(60) /* save %a7 */ + bra saveDone +userMode: + movel %usp,%a1 /* save user stack pointer */ + movel %a1,%a5@(60) /* save user stack pointer */ +saveDone: + + movew %d3,%a0@- /* push frame size in words */ + movel %d2,%a0@- /* push vector number */ + movel %a4,%a0@- /* push exception pc */ + +# +# save old frame link and set the new value +# + movel lastFrame,%a1 /* last frame pointer */ + movel %a1,%a0@- /* save pointer to prev frame */ + movel %a0,lastFrame + + movel %d2,%sp@- /* push exception num */ + movel exceptionHook,%a0 /* get address of handler */ + + jbsr %a0@ /* and call it */ + clrl %sp@ /* replace exception num parm with frame ptr */ + jbsr _returnFromException /* jbsr, but never returns */ +"); +#endif + + +/* + * remcomHandler is a front end for handle_exception. It moves the + * stack pointer into an area reserved for debugger use in case the + * breakpoint happened in supervisor mode. + */ +asm("remcomHandler:"); +asm(" addl #4,%sp"); /* pop off return address */ +asm(" movel %sp@+,%d0"); /* get the exception number */ +asm(" movel stackPtr,%sp"); /* move to remcom stack area */ +asm(" movel %d0,%sp@-"); /* push exception onto stack */ +asm(" jbsr handle_exception"); /* this never returns */ +asm(" rts"); /* return */ + +void _returnFromException(Frame *frame) +{ + /* if no passed in frame, use the last one */ + if (! frame) + { + frame = lastFrame; + frame->frameSize = 4; + frame->format = 0; + frame->fsaveHeader = -1; /* restore regs, but we dont have fsave info*/ + } + +#if defined(__m68000__) && !defined(__mc68020__) + /* a 68000 cannot use the internal info pushed onto a bus error + * or address error frame when doing an RTE so don't put this info + * onto the stack or the stack will creep every time this happens. + */ + frame->frameSize=3; +#endif + + /* throw away any frames in the list after this frame */ + lastFrame = frame; + + frame->sr = registers[(int) PS]; + frame->pc = registers[(int) PC]; + + if (registers[(int) PS] & 0x2000) + { + /* return to supervisor mode... */ + return_to_super(); + } + else + { /* return to user mode */ + return_to_user(); + } +} + +int hex(char ch) +{ + if ((ch >= 'a') && (ch <= 'f')) return (ch-'a'+10); + if ((ch >= '0') && (ch <= '9')) return (ch-'0'); + if ((ch >= 'A') && (ch <= 'F')) return (ch-'A'+10); + return (-1); +} + +/* scan for the sequence $# */ +void getpacket(char *buffer) +{ + unsigned char checksum; + unsigned char xmitcsum; + int i; + int count; + char ch; + + do { + /* wait around for the start character, ignore all other characters */ + while ((ch = (getDebugChar() & 0x7f)) != '$'); + checksum = 0; + xmitcsum = -1; + + count = 0; + + /* now, read until a # or end of buffer is found */ + while (count < BUFMAX) { + ch = getDebugChar() & 0x7f; + if (ch == '#') break; + checksum = checksum + ch; + buffer[count] = ch; + count = count + 1; + } + buffer[count] = 0; + + if (ch == '#') { + xmitcsum = hex(getDebugChar() & 0x7f) << 4; + xmitcsum += hex(getDebugChar() & 0x7f); + if ((remote_debug ) && (checksum != xmitcsum)) { + debug_port_printf ("bad checksum. My count = 0x%x, sent=0x%x. buf=%s\n", + checksum,xmitcsum,buffer); + } + + if (checksum != xmitcsum) putDebugChar('-'); /* failed checksum */ + else { + putDebugChar('+'); /* successful transfer */ + /* if a sequence char is present, reply the sequence ID */ + if (buffer[2] == ':') { + putDebugChar( buffer[0] ); + putDebugChar( buffer[1] ); + /* remove sequence chars from buffer */ + count = strlen(buffer); + for (i=3; i <= count; i++) buffer[i-3] = buffer[i]; + } + } + } + } while (checksum != xmitcsum); +} + +/* send the packet in buffer. The host get's one chance to read it. + This routine does not wait for a positive acknowledge. */ + + +void +putpacket(char *buffer) +{ + unsigned char checksum; + int count; + char ch; + + /* $#. */ + do { + putDebugChar('$'); + checksum = 0; + count = 0; + + while ((ch=buffer[count])) { + if (! putDebugChar(ch)) return; + checksum += ch; + count += 1; + } + + putDebugChar('#'); + putDebugChar(hexchars[checksum >> 4]); + putDebugChar(hexchars[checksum % 16]); + + } while (1 == 0); /* (getDebugChar() != '+'); */ + +} + +char remcomInBuffer[BUFMAX]; +char remcomOutBuffer[BUFMAX]; +static short error; + +/* convert the memory pointed to by mem into hex, placing result in buf */ +/* return a pointer to the last char put in buf (null) */ +char *mem2hex(char *mem, char *buf, int count) +{ + int i; + unsigned char ch; + + if (remote_debug) + debug_port_printf("mem=0x%x, count=0x%x\n", mem, count); + + for (i=0;i> 4]; + *buf++ = hexchars[ch % 16]; + } + *buf = 0; + return(buf); +} + +/* convert the hex array pointed to by buf into binary to be placed in mem */ +/* return a pointer to the character AFTER the last byte written */ +char *hex2mem(char *buf, char *mem, int count) +{ + int i; + unsigned char ch; + + if (remote_debug) + debug_port_printf("mem=0x%x, count=0x%x\n", mem, count); + + for (i=0;i=0) + { + *intValue = (*intValue <<4) | hexValue; + numChars ++; + } + else + break; + + (*ptr)++; + } + + return (numChars); +} + +/* + * This function does all command procesing for interfacing to gdb. + */ +void handle_exception(int exceptionVector) +{ + int sigval; + int addr, length; + char * ptr; + int newPC; + Frame *frame; + + if (remote_debug) + printf("vector=%d, sr=0x%x, pc=0x%x\n", + exceptionVector, + registers[ PS ], + registers[ PC ]); + + /* reply to host that an exception has occurred */ + sigval = computeSignal( exceptionVector ); + remcomOutBuffer[0] = 'S'; + remcomOutBuffer[1] = hexchars[sigval >> 4]; + remcomOutBuffer[2] = hexchars[sigval % 16]; + remcomOutBuffer[3] = 0; + + putpacket(remcomOutBuffer); + + while (1==1) { + error = 0; + remcomOutBuffer[0] = 0; + getpacket(remcomInBuffer); + switch (remcomInBuffer[0]) { + case '?' : remcomOutBuffer[0] = 'S'; + remcomOutBuffer[1] = hexchars[sigval >> 4]; + remcomOutBuffer[2] = hexchars[sigval % 16]; + remcomOutBuffer[3] = 0; + break; + case 'd' : + remote_debug = !(remote_debug); /* toggle debug flag */ + debug_port_printf("debug mode "); + if (remote_debug) + { + debug_port_printf("on\n"); + } + else + { + debug_port_printf("off\n"); + } + break; + case 'g' : /* return the value of the CPU registers */ + mem2hex((char*) registers, remcomOutBuffer, NUMREGBYTES); + break; + case 'G' : /* set the value of the CPU registers - return OK */ + hex2mem(&remcomInBuffer[1], (char*) registers, NUMREGBYTES); + strcpy(remcomOutBuffer,"OK"); + break; + + /* mAA..AA,LLLL Read LLLL bytes at address AA..AA */ + case 'm' : + if (setjmp(remcomEnv) == 0) + { + exceptionHandler(2,handle_buserror); + + /* TRY TO READ %x,%x. IF SUCCEED, SET PTR = 0 */ + ptr = &remcomInBuffer[1]; + if (hexToInt(&ptr,&addr)) + if (*(ptr++) == ',') + if (hexToInt(&ptr,&length)) + { + ptr = 0; + mem2hex((char*) addr, remcomOutBuffer, length); + } + + if (ptr) + { + strcpy(remcomOutBuffer,"E01"); + if (remote_debug) + printf("malformed read memory command: %s",remcomInBuffer); + } + } + else { + exceptionHandler(2,_catchException); + strcpy(remcomOutBuffer,"E03"); + if (remote_debug) + printf("bus error"); + } + + /* restore handler for bus error */ + exceptionHandler(2,_catchException); + break; + + /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */ + case 'M' : + if (setjmp(remcomEnv) == 0) { + exceptionHandler(2,handle_buserror); + + /* TRY TO READ '%x,%x:'. IF SUCCEED, SET PTR = 0 */ + ptr = &remcomInBuffer[1]; + if (hexToInt(&ptr,&addr)) + if (*(ptr++) == ',') + if (hexToInt(&ptr,&length)) + if (*(ptr++) == ':') + { + hex2mem(ptr, (char*) addr, length); + ptr = 0; + strcpy(remcomOutBuffer,"OK"); + } + if (ptr) + { + strcpy(remcomOutBuffer,"E02"); + if (remote_debug) + printf("malformed write memory command: %s",remcomInBuffer); + } + } + else { + exceptionHandler(2,_catchException); + strcpy(remcomOutBuffer,"E03"); + if (remote_debug) + printf("bus error"); + } + + /* restore handler for bus error */ + exceptionHandler(2,_catchException); + break; + + /* cAA..AA Continue at address AA..AA(optional) */ + /* sAA..AA Step one instruction from AA..AA(optional) */ + case 'c' : + case 's' : + /* try to read optional parameter, pc unchanged if no parm */ + ptr = &remcomInBuffer[1]; + if (hexToInt(&ptr,&addr)) + registers[ PC ] = addr; + + newPC = registers[ PC]; + + /* clear the trace bit */ + registers[ PS ] &= 0x7fff; + + /* set the trace bit if we're stepping */ + if (remcomInBuffer[0] == 's') registers[ PS ] |= 0x8000; + + /* + * look for newPC in the linked list of exception frames. + * if it is found, use the old frame it. otherwise, + * fake up a dummy frame in returnFromException(). + */ + if (remote_debug) debug_port_printf("new pc = 0x%x\n",newPC); + + frame = lastFrame; + while (frame) + { + if (remote_debug) + debug_port_printf("frame at 0x%x has pc=0x%x, except#=%d\n", + frame,frame->exceptionPC, + (unsigned int) frame->exceptionVector); + if (frame->exceptionPC == newPC) break; /* bingo! a match */ + /* + * for a breakpoint instruction, the saved pc may + * be off by two due to re-executing the instruction + * replaced by the trap instruction. Check for this. + */ + if ((frame->exceptionVector == 33) && + (frame->exceptionPC == newPC)) break; + if (frame == frame->previous) + { + frame = 0; /* no match found */ + break; + } + frame = frame->previous; + } + + /* + * If we found a match for the PC AND we are not returning + * as a result of a breakpoint (33), + * trace exception (9), nmi (31), jmp to + * the old exception handler as if this code never ran. + */ + if (frame) + { + if ((frame->exceptionVector != 9) && + (frame->exceptionVector != 31) && + (frame->exceptionVector != 33)) + { + /* + * invoke the previous handler. + */ + if (oldExceptionHook) + (*oldExceptionHook) (frame->exceptionVector); + newPC = registers[ PC ]; /* pc may have changed */ + if (newPC != frame->exceptionPC) + { + if (remote_debug) + debug_port_printf("frame at 0x%x has pc=0x%x, except#=%d\n", + frame,frame->exceptionPC, + (unsigned int) frame->exceptionVector); + /* re-use the last frame, we're skipping it (longjump?)*/ + frame = (Frame *) 0; + _returnFromException( frame ); /* this is a jump */ + } + } + } + + /* if we couldn't find a frame, create one */ + if (frame == 0) + { + frame = lastFrame -1 ; + + /* by using a bunch of print commands with breakpoints, + it's possible for the frame stack to creep down. If it creeps + too far, give up and reset it to the top. Normal use should + not see this happen. + */ + if ((unsigned int) (frame-2) < (unsigned int) &gdbFrameStack) + { + initializeRemcomErrorFrame(); + frame = lastFrame; + } + frame->previous = lastFrame; + lastFrame = frame; + frame = 0; /* null so _return... will properly initialize it */ + } + + _returnFromException( frame ); /* this is a jump */ + + break; + + /* kill the program */ + case 'k' : + /* reset the board */ + WATCHDOG_TRIGGER(); + while (1 == 1); + break; + + } /* switch */ + + /* reply to the request */ + putpacket(remcomOutBuffer); + } +} + + +void initializeRemcomErrorFrame() +{ + lastFrame = ((Frame *) &gdbFrameStack[FRAMESIZE-1]) - 1; + lastFrame->previous = lastFrame; +} + +/* this function is used to set up exception handlers for tracing and + breakpoints */ +void set_debug_traps() +{ + extern void _debug_level7(void); + extern void remcomHandler(void); + + int exception; + + initializeRemcomErrorFrame(); + stackPtr = &remcomStack[STACKSIZE/sizeof(int) - 1]; + + registers[ PC ] = 0x400; + registers[ PS ] = 0x2700; + + for (exception = 2; exception <= 30; exception++) + exceptionHandler(exception,_catchException); + + /* level 7 interrupt */ + exceptionHandler(31,_debug_level7); + + for (exception = 32; exception <= 47; exception++) + exceptionHandler(exception,_catchException); + + /* exclude the unassigned, reserved vector locations */ + + for (exception = 64; exception <= 255; exception++) + exceptionHandler(exception,_catchException); + + if (oldExceptionHook != (ExceptionHook) remcomHandler) + { + oldExceptionHook = exceptionHook; + exceptionHook = (ExceptionHook) remcomHandler; + } + + initialized = 1; + +#if defined(UPDATE_DISPLAY) + UPDATE_DISPLAY("gdb "); +#endif +} + +/* This function will generate a breakpoint exception. It is used at the + beginning of a program to sync up with a debugger and can be used + otherwise as a quick means to stop program execution and "break" into + the debugger. */ + +void breakpoint() +{ + if (initialized) BREAKPOINT(); +} diff --git a/c/src/lib/libbsp/m68k/ods68302/startup/memcheck.c b/c/src/lib/libbsp/m68k/ods68302/startup/memcheck.c new file mode 100644 index 0000000000..4341a88e37 --- /dev/null +++ b/c/src/lib/libbsp/m68k/ods68302/startup/memcheck.c @@ -0,0 +1,33 @@ +/*****************************************************************************/ +/* + $Id$ + + Memory check routines. + + The production test is a destrucive full test. + The boot test is a minimal, non-desctructive. + The partial memory test performs a scetion at a time, and gets + called in a repeated fashion to completely check the memory, + + */ +/*****************************************************************************/ + +void +production_memory_test() +{ +} + +void +boot_memory_test() +{ +} + +void +reset_partial_memory_test() +{ +} + +void +partial_memory_test() +{ +} diff --git a/c/src/lib/libbsp/m68k/ods68302/startup/rom b/c/src/lib/libbsp/m68k/ods68302/startup/rom new file mode 100644 index 0000000000..a8533e08b0 --- /dev/null +++ b/c/src/lib/libbsp/m68k/ods68302/startup/rom @@ -0,0 +1,56 @@ +/* + * $Id$ + * + * MC68302 Linker command file + * + */ + +SECTIONS +{ + .text . : + { + text_start = .; + *(.text) + etext = .; + . = ALIGN(4); + __CTOR_LIST__ = .; + LONG((__CTOR_END__ - __CTOR_LIST__) / 4 - 2) + *(.ctors) + LONG(0) + __CTOR_END__ = .; + . = ALIGN(4); + __DTOR_LIST__ = .; + LONG((__DTOR_END__ - __DTOR_LIST__) / 4 - 2) + *(.dtors) + LONG(0) + __DTOR_END__ = .; + } + + .vtable 0 : + { + vtable_start = .; + *(.vtable) + evtable = .; + } + + .data (ADDR(.vtable) + SIZEOF(.vtable)) : + AT (ADDR(.text) + SIZEOF(.text)) + { + data_start = .; + *(.data) + edata = .; + } + .bss (ADDR(.data) + SIZEOF(.data)) : + { + bss_start = .; + *(.bss) + *(COMMON) + end = . ; + _end = . ; + } +} + +m302 = MC68302_BASE; +_VBR = 0; /* location of the VBR table (in RAM) */ + + diff --git a/c/src/lib/libbsp/m68k/ods68302/startup/trace.c b/c/src/lib/libbsp/m68k/ods68302/startup/trace.c new file mode 100644 index 0000000000..bfc2b699e7 --- /dev/null +++ b/c/src/lib/libbsp/m68k/ods68302/startup/trace.c @@ -0,0 +1,175 @@ +/*****************************************************************************/ +/* + $Id$ + + Trace Exception dumps a back trace to the debug serial port + + */ +/*****************************************************************************/ + +#include +#include + +#ifdef 0 +/* FIXME : could get the string to print when in the BSP */ +static const char *exception_names[] = +{ + "RESET STACK TOP", + "RESET", + "BUS ERROR", + "ADDRESS ERROR", + "ILLEGAL OPCODE", + "ZERO DIVIDE", + "CHK", + "OVERFLOW", + "PRIVILEGE", + "TRACE", + "LINE 1010 EMULATOR", + "LINE 1111 EMULATOR", + "UNASSIGNED 12", + "UNASSIGNED 13", + "FORMAT ERROR", + "UNINITIALISED INTERRUPT", + "UNASSIGNED 16", + "NODE ANCHOR", + "SYSTEM ANCHOR", + "UNASSIGNED 19", + "UNASSIGNED 20", + "UNASSIGNED 21", + "UNASSIGNED 22", + "UNASSIGNED 23", + "SPURIOUS HANDLER", + "LEVEL 1", + "LEVEL 2", + "LEVEL 3", + "LEVEL 4", + "LEVEL 5", + "LEVEL 6", + "LEVEL 7", + "TRAP 0", + "TRAP 1", + "TRAP 2", + "TRAP 3", + "TRAP 4", + "TRAP 5", + "TRAP 6", + "TRAP 7", + "TRAP 8", + "TRAP 9", + "TRAP 10", + "TRAP 11", + "TRAP 12", + "TRAP 13", + "TRAP 14", + "TRAP 15" +}; +#endif + +void trace_exception(unsigned long d0, + unsigned long d1, + unsigned long d2, + unsigned long d3, + unsigned long d4, + unsigned long d5, + unsigned long d6, + unsigned long d7, + unsigned long a0, + unsigned long a1, + unsigned long a2, + unsigned long a3, + unsigned long a4, + unsigned long a5, + unsigned long a6, + unsigned long a7, + unsigned long sr_pch, + unsigned long pcl_format) +{ + unsigned int sr = sr_pch >> 16; + unsigned long pc = (sr_pch << 16) | (pcl_format >> 16); + unsigned int format = pcl_format & 0xFFFF; + unsigned int index; + unsigned char ch; + + asm volatile(" orw #0x0700,%sr"); + + debug_port_banner(); + + debug_port_write("unhandled exception="); + debug_port_write_hex_uint(format >> 2); + debug_port_write("\n"); + + debug_port_write("sr="); + debug_port_write_hex_uint(sr); + debug_port_write(", pc="); + debug_port_write_hex_ulong(pc); + debug_port_write("\n"); + + for (index = 0; index < 16; index++) + { + if (index == 8) + { + debug_port_write("\n\r"); + } + if (index < 8) + { + debug_port_out('d'); + debug_port_out('0' + index); + } + else + { + debug_port_out('a'); + debug_port_out('0' + index - 8); + } + debug_port_out('='); + debug_port_write_hex_ulong(*(((unsigned long*) &d0) + index)); + debug_port_out(' '); + } + + for (index = 0; index < (16 * 10); index++) + { + if ((index % 16) == 0) + { + debug_port_write("\n"); + debug_port_write_hex_ulong((unsigned long) (((char*) &index) + index)); + debug_port_write(" : "); + } + else + { + debug_port_out(' '); + } + + ch = (*(((char*) &index) + index) >> 4) & 0x0F; + + if (ch < 10) + { + ch += '0'; + } + else + { + ch += 'a' - 10; + } + + debug_port_out((char) ch); + + ch = *(((char*) &index) + index) & 0x0F; + + if (ch < 10) + { + ch += '0'; + } + else + { + ch += 'a' - 10; + } + debug_port_out((char) ch); + } + + debug_port_write("\nhalting cpu..."); + +#if defined(UPDATE_DISPLAY) + UPDATE_DISPLAY("HALT"); +#endif + + WATCHDOG_TRIGGER(); + while (1 == 1); +} diff --git a/c/src/lib/libbsp/m68k/ods68302/timer/Makefile.in b/c/src/lib/libbsp/m68k/ods68302/timer/Makefile.in new file mode 100644 index 0000000000..c2ba3476d3 --- /dev/null +++ b/c/src/lib/libbsp/m68k/ods68302/timer/Makefile.in @@ -0,0 +1,58 @@ +# +# $Id$ +# + +@SET_MAKE@ +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH=@srcdir@ + +PGM=${ARCH}/timer.rel + +# C source names, if any, go here -- minus the .c +C_PIECES=timer +C_FILES=$(C_PIECES:%=%.c) +C_O_FILES=$(C_PIECES:%=${ARCH}/%.o) + +H_FILES= + +# Assembly source names, if any, go here -- minus the .s +S_PIECES=timerisr +S_FILES=$(S_PIECES:%=%.s) +S_O_FILES=$(S_FILES:%.s=${ARCH}/%.o) + +SRCS=$(C_FILES) $(H_FILES) $(S_FILES) +OBJS=$(C_O_FILES) $(S_O_FILES) + +include $(RTEMS_CUSTOM) +include $(PROJECT_ROOT)/make/leaf.cfg + +# +# (OPTIONAL) Add local stuff here using += +# + +DEFINES += +CPPFLAGS += +CFLAGS += + +LD_PATHS += +LD_LIBS += +LDFLAGS += + +# +# Add your list of files to delete here. The config files +# already know how to delete some stuff, so you may want +# to just run 'make clean' first to see what gets missed. +# 'make clobber' already includes 'make clean' +# + +CLEAN_ADDITIONS += +CLOBBER_ADDITIONS += + +${PGM}: ${SRCS} ${OBJS} + $(make-rel) + +all: ${ARCH} $(SRCS) $(PGM) + +# the .rel file built here will be put into libbsp.a by ../wrapup/Makefile +install: all diff --git a/c/src/lib/libbsp/m68k/ods68302/timer/timer.c b/c/src/lib/libbsp/m68k/ods68302/timer/timer.c new file mode 100644 index 0000000000..83a10c4803 --- /dev/null +++ b/c/src/lib/libbsp/m68k/ods68302/timer/timer.c @@ -0,0 +1,130 @@ +/* Timer_init() + * + * This routine initializes TIMER 2 for an MC68302. + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * NOTE: It is important that the timer start/stop overhead be + * determined when porting or modifying this code. + * + * COPYRIGHT (c) 1989-1997. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may in + * the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + + +#include +#include +#include "m68302.h" + + +#define TMR2_VAL 0x071b /* Timer mode register + * (section 3.5.2.1 in 68302 manual) + * 15-8: "7" prescaler divide by 8 (x+1) + * 7-6: 00 dis. intr. on capture event + * 5: 0 active-low pulse + * 4: 1 intr. on reaching reference + * 3: 1 restart counter on reference + * 2-1: 01 master clock input source + * 0: 1 enable timer + */ +#define TRR2_VAL 2000 /* Timer reference register + * (section 3.5.2.2 in 68302 manual) + * 2000 ticks @ (16MHz/1)/8 = 1-ms count + */ + +rtems_unsigned32 Timer_interrupts; + +rtems_boolean Timer_driver_Find_average_overhead; + +rtems_isr timerisr(); + +void Timer_initialize( void ) +{ + m302.reg.tmr2 = 0; /* disable timer */ + + Timer_interrupts = 0; /* clear timer ISR count */ + + m302.reg.trr2 = TRR2_VAL; /* set timer reference register */ + m302.reg.tmr2 = TMR2_VAL; /* set timer mode register */ + m302.reg.imr |= RBIT_IMR_TIMER2; /* set 68302 int-mask to allow ints */ +} + +/* + * The following controls the behavior of Read_timer(). + * + * FIND_AVG_OVERHEAD * instructs the routine to return the "raw" count. + * + * 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 */ + +/* + * Return timer value in 1/2-microsecond units + */ +int Read_timer( void ) +{ + rtems_unsigned16 clicks; + rtems_unsigned32 total; + + /* + * Read the timer and see how many clicks it has been since counter + * rolled over. + */ + + clicks = m302.reg.tcn2; + + /* + * 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 = (Timer_interrupts * TRR2_VAL) + clicks; + + if ( Timer_driver_Find_average_overhead == 1 ) + return total; /* in XXX microsecond units */ + + if ( total < LEAST_VALID ) + return 0; /* below timer resolution */ + + /* + * Convert 1/2-microsecond count into microseconds + */ + + return (total - AVG_OVERHEAD) >> 1; +} + + +/* + * 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/m68k/ods68302/timer/timerisr.s b/c/src/lib/libbsp/m68k/ods68302/timer/timerisr.s new file mode 100644 index 0000000000..c804b9dfa6 --- /dev/null +++ b/c/src/lib/libbsp/m68k/ods68302/timer/timerisr.s @@ -0,0 +1,28 @@ +/* + * Handle 68302 TIMER2 interrupts. + * + * All code in this routine is pure overhead which can perturb the + * accuracy of RTEMS' timing test suite. + * + * See also: Read_timer() + * + * 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. + * + * An external counter, Timer_interrupts, is incremented. + * + * $Id$ + */ + +#include "asm.h" + +BEGIN_CODE + PUBLIC(timerisr) +SYM(timerisr): + move.w #0x0040,SYM(m302)+2072 | clear interrupt in-service bit + move.b #3,SYM(m302)+2137 | clear timer interrupt event register + addq.l #1,SYM(Timer_interrupts) | increment timer value + rte +END_CODE +END diff --git a/c/src/lib/libbsp/m68k/ods68302/wrapup/Makefile.in b/c/src/lib/libbsp/m68k/ods68302/wrapup/Makefile.in new file mode 100644 index 0000000000..bd06f5f90f --- /dev/null +++ b/c/src/lib/libbsp/m68k/ods68302/wrapup/Makefile.in @@ -0,0 +1,48 @@ +# +# $Id$ +# + +@SET_MAKE@ +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH=@srcdir@ + +BSP_PIECES=startup clock console timer +GENERIC_PIECES= + +# bummer; have to use $foreach since % pattern subst rules only replace 1x +OBJS=$(foreach piece, $(BSP_PIECES), ../$(piece)/$(ARCH)/$(piece).rel) \ + $(foreach piece, $(GENERIC_PIECES), ../../../$(piece)/$(ARCH)/$(piece).rel) +LIB=$(ARCH)/libbsp.a + +include $(RTEMS_CUSTOM) +include $(PROJECT_ROOT)/make/lib.cfg + +# +# (OPTIONAL) Add local stuff here using += +# + +DEFINES += +CPPFLAGS += +CFLAGS += + +LD_PATHS += +LD_LIBS += +LDFLAGS += + +# +# Add your list of files to delete here. The config files +# already know how to delete some stuff, so you may want +# to just run 'make clean' first to see what gets missed. +# 'make clobber' already includes 'make clean' +# + +CLEAN_ADDITIONS += +CLOBBER_ADDITIONS += + +$(LIB): ${OBJS} + $(make-library) + +all: ${ARCH} $(SRCS) $(LIB) + $(INSTALL_VARIANT) -m 644 $(LIB) ${PROJECT_RELEASE}/lib + diff --git a/c/src/lib/librtems++/Makefile.in b/c/src/lib/librtems++/Makefile.in new file mode 100644 index 0000000000..5e67e02110 --- /dev/null +++ b/c/src/lib/librtems++/Makefile.in @@ -0,0 +1,49 @@ +# +# $Id$ +# + +@SET_MAKE@ +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH=@srcdir@ + +LIBNAME=librtems++.a +LIB=${ARCH}/${LIBNAME} + +# C and C++ source names, if any, go here -- minus the .c or .cc +CC_PIECES=rtemsEvent rtemsInterrupt rtemsMessageQueue rtemsSemaphore \ + rtemsStatusCode rtemsTask rtemsTimer +CC_FILES=$(CC_PIECES:%=%.cc) +CC_O_FILES=$(CC_PIECES:%=${ARCH}/%.o) + +SRCS=$(CC_FILES) +OBJS=$(CC_O_FILES) + +include $(RTEMS_CUSTOM) +include $(PROJECT_ROOT)/make/lib.cfg + +# +# Add local stuff here using += +# + +DEFINES += +CPPFLAGS += +CFLAGS += $(LIBC_DEFINES) + +# +# Add your list of files to delete here. The config files +# already know how to delete some stuff, so you may want +# to just run 'make clean' first to see what gets missed. +# 'make clobber' already includes 'make clean' +# + +CLEAN_ADDITIONS += $(LIB) +CLOBBER_ADDITIONS += + +all: ${ARCH} $(LIB) + $(INSTALL_VARIANT) -m 644 ${LIB} ${PROJECT_RELEASE}/lib + +$(LIB): $(SRCS) ${OBJS} + $(make-library) + + diff --git a/c/src/lib/librtems++/README b/c/src/lib/librtems++/README new file mode 100644 index 0000000000..65b0eb980e --- /dev/null +++ b/c/src/lib/librtems++/README @@ -0,0 +1,266 @@ +# +# $Id$ +# + +RTEMS C++ Library +================= + +The RTEMS C++ Library or librtems++ is a wrapper for the RTEMS API. +The classes provide as close a match to the RTEMS C API, for +performance, to share the existing C documentation as much as +possible, and to allow easy tracking of any changes to the RTEMS C +API. + +The C++ interface only uses RTEMS API calls. No external references +or internal interfaces are used. This allows the classes to be used +in separately compiled modules or applications which link to the RTEMS +trap interface. + +(This is the goal, which has not quite been reached. The TOD macro for +micro-seconds to ticks is used, and this uses an internal global RTEMS +variable) + +The C++ interface does not deal with RTEMS initialisation or the +device driver interface. The current view is these parts of a system +are best handled in the current manner. This means BSP for +initialisation and the C API for drivers. + +RTEMS C++ Classes +================= + +The classes map to the managers of RTEMS. + +The methods have default values selected which try to fit most cases +or follow the documented RTEMS default values. Moving from left to +right the parameters become less used, allowing the defaults to be +selected. An example is the scope parameter for most classes. This +can be local or global. I assume that most RTEMS objects are local, +therefore it has been made the last parameter. + +Inline methods have been used for methods which are commonly used in +applications. This tries to add the minimum of overhead. For +example, the methods to send or receive events are inline, while all +methods for control of a task are not. + +The RTEMS types, enumerations, and defines are used. If a new type, +enumeration or define is made it will map directly to the RTEMS +equivalent. For example the enumeration Scope is defined for various +classes which can be local or global. The elements of the enumeration +are forced to the same value as the RTEMS values. An enumeration is +used in this case to allow the compiler to type check a little +better. It saves having to check only RTEMS_LOCAL or RTEMS_GLOBAL is +passed as a parameter (I am not convinced this is really needed as the +goal was to not define anything and to only use what RTEMS provided). + +Where possible the various parts of an option bit set, or mode can be +controlled separately or controlled as a group. An example is the +task mode. The RTEMS C API allows a set of modes to be modified at +once. The TaskMode class allows this to occur, while also providing +methods to control a single mode item. + +The name of an object is always passed as a string. The classes turn +the string into a rtems_name variable. The string does not have to be +nul character terminated. + +The RTEMS C API uses 'delete' to remove or kill an RTEMS object. This +is a reserved word in C++, so the word 'destroy' is used instead. + +Calling the classes from interrupts follows the rules of RTEMS. An +exception introduced by the class library is the last status code. +There is only one last status code for each instance of the library's +classes and it is not protected. This needs to be watched for. Maybe +a better solution needs to be found, such as interrupt calls do not set +the last status code. + +RTEMS objects created by the C++ library can be operated on by C code +just as any other RTEMS object. If limitations exist they should be +documented in under the class. + +RTEMS Object Ownership +====================== + +The concept of ownership of an object is not defined as part of the +RTEMS C API. A piece of code executing as part a task can create a +message queue. Another piece of code running as part of a different +task can destroy the message queue. Correct behavior between the code +that creates the message queue and the code which destroy's the +message queue must be provided by the programmer. + +The librtems++ supports the concept of ownership of an RTEMS object. +Only the C++ object that creates the RTEMS object can destroy it. A +C++ object can connect to an existing RTEMS object and control it, +how-ever it can not destroy it. + +Copy constructors and assignment operators are provided to in-force +this rule. + +Ownership only applies to classes that create RTEMS objects. These +classes contain a flag which signals ownership of the id. + +Timeouts +======== + +The timeout value is specified in micro-seconds. The classes turn the +micro-second timeout value into ticks required by the RTEMS C API. + +This causes a problem for timeout values which are less than one tick. +This case is tested for and the timeout value is set to one tick. All +other cases round down to the nearest tick. + +Status Codes +============ + +All classes which form the C++ API are derived from the StatusCode +class. This class provides a common method for handling the status +code returned by RTEMS. + +The last returned status code is held in the StatusCode object. It +can be queried directly, or as a boolean. You can also obtain an +error string for the status code. + +The setting of a status code is restricted to derived classes. + +The last status code attribute of the class is only ever set to an +RTEMS defined status code. + +Event Class +=========== + +The event class allows users to send and receive events to and from +tasks. + +Events objects are by default connected the RTEMS_SELF task. A send +or receive will operate on the task currently executing. + +An Event object can be connected to a task using the connect method. +The name is the name of the task. Connection can also be achieved by +using the copy constructor or assignment operator. + +Events can be sent to a task by specifying an RTEMS task id, or by +passing a reference to a Task object. + +Interrupt Class +=============== + +The interrupt class allows a protected virtual method of a derived +class to be an interrupt handler. + +You derive from this class and provide the handler method. The next +interrupt after the vector is caught will cause the handler method to +be entered. + +You can chain the interrupt by calling the chain method. If the old +handler is not an instance of this class the chain is passed as "void +(*)(void)". If it is an instance of this class, the handler method is +directly called. (Chaining has not been tested) + +This class implements a table of pointers to the last instance to +catch the interrupt. A static method of the class catches the +interrupt and re-directs the interrupt to the instance in the table. +The re-direct adds a additional virtual function call and return to +the overhead of the interrupt. For a i386 type processor this is +about 12 instructions including the function call entry. + +Message Queue Class +=================== + +The MessageQueue class allows message queue's to be created, or +connected too. Only the creator can destroy a message queue. + +The class implements, sending, urgent sending, broadcast, flushing, +and receiving. + +Semaphore Class +=============== + +The Semaphore class allows semaphores to be created, or connected +too. Only the creator can destroy a semaphore. + +All types of semaphores can be created. + +(Not tested in the test code) + +Task Class +========== + +The Task class allows tasks to be created, or connected too. Only the +creator can destroy a task. + +If creating a task, derive from the Task class and provide the body +method. The body method is the entry point for a task. When +connecting to an existing task, no body method is required to be +provided. It is how-ever required if you create a task. This is not +enforced by the compiler, how-ever the default body will be entered, +and it contains no code. The RTEMS default behaviour for a task that +returns occurs. + +The mode of a task is controlled using the TaskMode class. + +The Task class allows you to start, restart, suspend, and resume a +task. You can control the priority, and access the note-pad +registers. The task can also be slept using the wake_after and +wake_when methods. + +Currently the task argument is used to pass the 'this' pointer to the +libraries default task body. The actual argument is held in the class +instance and passed to the virtual body method. This means of passing +the 'this' pointer through RTEMS to the default task body requires the +actual task object to perform a restart call. This is not really the +best solution to the problem. Another solution is to remove a notpad +register, say 31 from the task and use it. This would mean any Task +object could stop and restart a task how-ever a notpad register is +lost. Any other ideas are welcome. + +Task Mode Class +=============== + +The TaskMode class allows you to query or change the mode of a task. +The object only operates on the currently executing task. + +The standard flags defined in RTEMS are used. + +Methods are provided to operate on a group of modes which are required +to be changed in a single operation. The mode and mask is specified +by ORing the required flags as documented in the RTEMS manual. + +Methods are provided for accessing and controlling a specific mode. +The returned value will only contain the requested mode's flags, and +only the that mode will be changed when setting a mode. + +Timer Class +=========== + +The Timer class allows timers to be created. You cannot connect to an +existing timer. + +You derive from the Timer class and provide the trigger method. This +method is called when the timer triggers or times out. + +You can request a single shot timer using the fire_after or fire_when +methods, or a periodic timer by calling the repeat_file_at method. + +You cannot copy timer objects. + +Contact +======= +Send any question to me Chris Johns at cjohns@plessey.com.au, or the RTEMS +mailing list. + +To Do +===== + +1) Develop a complete test suite (under way, cjohns@plessey.com.au). + +2) Complete wrapping the remaining RTEMS C API. + +3) Provide light weight cout/cerr/clog classes based on printf for +embedded systems. + +4) Provide a memory serial class which maps the <> operators onto +raw memory in network byte order independent of CPU byte order. + +5) Fix the Task class so any Task object can restart a task. + +6) Provide some frame work classes which allow actor type objects that +start in an ordered manner. + diff --git a/c/src/lib/librtems++/rtemsEvent.cc b/c/src/lib/librtems++/rtemsEvent.cc new file mode 100644 index 0000000000..a917f32836 --- /dev/null +++ b/c/src/lib/librtems++/rtemsEvent.cc @@ -0,0 +1,75 @@ +/* + ------------------------------------------------------------------------ + $Id$ + ------------------------------------------------------------------------ + + COPYRIGHT (c) 1997 + Objective Design Systems Ltd Pty (ODS) + All rights reserved (R) Objective Design Systems Ltd Pty + + The license and distribution terms for this file may be found in the + file LICENSE in this distribution or at + http://www.OARcorp.com/rtems/license.html. + + ------------------------------------------------------------------------ + + See header file. + + ------------------------------------------------------------------------ +*/ + +#include + +/* ---- + rtemsEvent +*/ + +rtemsEvent::rtemsEvent(const char *name_str, rtems_unsigned32 node) + : name(rtems_build_name('S', 'E', 'L', 'F')), + id(RTEMS_SELF) +{ + connect(name_str, node); +} + +rtemsEvent::rtemsEvent(const rtemsEvent& event) +{ + name = event.name; + id = event.id; +} + +rtemsEvent::rtemsEvent() + : name(rtems_build_name('S', 'E', 'L', 'F')), + id(RTEMS_SELF) +{ +} + +rtemsEvent::~rtemsEvent() +{ +} + +const rtemsEvent& rtemsEvent::operator=(const rtemsEvent& event) +{ + name = event.name; + id = event.id; + + return *this; +} + +const rtems_status_code rtemsEvent::connect(const char *name_str, + const rtems_unsigned32 node) +{ + name = rtems_build_name(name_str[0], + name_str[1], + name_str[2], + name_str[3]); + + set_status_code(rtems_task_ident(name, node, &id)); + + if (unsuccessful()) + { + name = rtems_build_name('S', 'E', 'L', 'F'); + id = RTEMS_SELF; + } + + return last_status_code(); +} diff --git a/c/src/lib/librtems++/rtemsInterrupt.cc b/c/src/lib/librtems++/rtemsInterrupt.cc new file mode 100644 index 0000000000..c445807c35 --- /dev/null +++ b/c/src/lib/librtems++/rtemsInterrupt.cc @@ -0,0 +1,110 @@ +/* + ------------------------------------------------------------------------ + $Id$ + ------------------------------------------------------------------------ + + COPYRIGHT (c) 1997 + Objective Design Systems Ltd Pty (ODS) + All rights reserved (R) Objective Design Systems Ltd Pty + + The license and distribution terms for this file may be found in the + file LICENSE in this distribution or at + http://www.OARcorp.com/rtems/license.html. + + ------------------------------------------------------------------------ + + See header file. + + ------------------------------------------------------------------------ +*/ + +#include + +/* ---- + Interrupt Table + + This table is used to re-direct the call from RTEMS to a user + object +*/ + +static rtemsInterrupt *interrupt_table[CPU_INTERRUPT_NUMBER_OF_VECTORS]; + +// has the table been initialised +static bool initialised = false; + +/* ---- + rtemsInterrupt +*/ + +rtemsInterrupt::rtemsInterrupt() + : vector(0), + caught(false), + old_handler(0), + old_interrupt(0) +{ + if (!initialised) + { + for (rtems_vector_number vec = 0; + vec < CPU_INTERRUPT_NUMBER_OF_VECTORS; + vec++) + { + interrupt_table[vector] = 0; + } + initialised = true; + } +} + +const rtems_status_code rtemsInterrupt::isr_catch(const rtems_vector_number vec) +{ + if (vec >= CPU_INTERRUPT_NUMBER_OF_VECTORS) + return set_status_code(RTEMS_INVALID_NUMBER); + + if (caught) + return set_status_code(RTEMS_RESOURCE_IN_USE); + + old_interrupt = interrupt_table[vector]; + interrupt_table[vector] = this; + vector = vec; + + set_status_code(rtems_interrupt_catch(redirector, + vector, + &old_handler)); + + if (successful()) + caught = true; + else + { + interrupt_table[vector] = old_interrupt; + old_interrupt = 0; + old_handler = 0; + vector = 0; + } + + return last_status_code(); +} + +const rtems_status_code rtemsInterrupt::release(void) +{ + if (caught) + { + set_status_code(rtems_interrupt_catch(old_handler, + vector, + &old_handler)); + + interrupt_table[vector] = old_interrupt; + old_interrupt = 0; + old_handler = 0; + vector = 0; + caught = false; + } + else + set_status_code(RTEMS_SUCCESSFUL); + + return last_status_code(); +} + +void rtemsInterrupt::redirector(rtems_vector_number vector) +{ + if (interrupt_table[vector]) + interrupt_table[vector]->handler(); +} diff --git a/c/src/lib/librtems++/rtemsMessageQueue.cc b/c/src/lib/librtems++/rtemsMessageQueue.cc new file mode 100644 index 0000000000..1978e1c6ec --- /dev/null +++ b/c/src/lib/librtems++/rtemsMessageQueue.cc @@ -0,0 +1,164 @@ +/* + ------------------------------------------------------------------------ + $Id$ + ------------------------------------------------------------------------ + + COPYRIGHT (c) 1997 + Objective Design Systems Ltd Pty (ODS) + All rights reserved (R) Objective Design Systems Ltd Pty + + The license and distribution terms for this file may be found in the + file LICENSE in this distribution or at + http://www.OARcorp.com/rtems/license.html. + + ------------------------------------------------------------------------ + + See header file. + + ------------------------------------------------------------------------ +*/ + +#include + +/* ---- + rtemsMessageQueue +*/ + +rtemsMessageQueue::rtemsMessageQueue(const char* mqname, + const rtems_unsigned32 count, + const rtems_unsigned32 max_message_size, + const WaitMode wait_mode, + const Scope scope) + : name(0), + owner(true), + id(0) +{ + strcpy(name_str, "NOID"); + create(mqname, count, max_message_size, wait_mode, scope); +} + +rtemsMessageQueue::rtemsMessageQueue(const char *mqname, + const rtems_unsigned32 node) + : name(0), + owner(false), + id(0) +{ + strcpy(name_str, "NOID"); + connect(mqname, node); +} + +rtemsMessageQueue::rtemsMessageQueue(const rtemsMessageQueue& message_queue) + : name(0), + owner(false), + id(0) +{ + name = message_queue.name; + strcpy(name_str, message_queue.name_str); + id = message_queue.id; +} + +rtemsMessageQueue::rtemsMessageQueue() + : name(0), + owner(false), + id(0) +{ + strcpy(name_str, "NOID"); +} + +rtemsMessageQueue::~rtemsMessageQueue() +{ + destroy(); +} + +void rtemsMessageQueue::make_invalid() +{ + strcpy(name_str, "NOID"); + name = 0; + id = 0; + owner = false; +} + +const rtems_status_code rtemsMessageQueue::create(const char* mqname, + const rtems_unsigned32 count, + const rtems_unsigned32 max_message_size, + const WaitMode wait_mode, + const Scope scope) +{ + if (id) + return set_status_code(RTEMS_ILLEGAL_ON_SELF); + + owner = true; + + strcpy(name_str, " "); + for (int c = 0; (c < 4) && (mqname[c] != '\0'); c++) + name_str[c] = mqname[c]; + name = rtems_build_name(name_str[0], + name_str[1], + name_str[2], + name_str[3]); + + set_status_code(rtems_message_queue_create(name, + count, + max_message_size, + scope | wait_mode, + &id)); + + if (unsuccessful()) + { + make_invalid(); + } + + return last_status_code(); +} + +const rtems_status_code rtemsMessageQueue::destroy() +{ + if (id && owner) + { + set_status_code(rtems_message_queue_delete(id)); + make_invalid(); + } + else + set_status_code(RTEMS_NOT_OWNER_OF_RESOURCE); + + return last_status_code(); +} + +const rtemsMessageQueue& rtemsMessageQueue::operator=(const rtemsMessageQueue& message_queue) +{ + if (!owner) + { + name = message_queue.name; + strcpy(name_str, message_queue.name_str); + id = message_queue.id; + } + + return *this; +} + +const rtems_status_code rtemsMessageQueue::connect(const char *mqname, + const rtems_unsigned32 node) +{ + if (id && owner) + return set_status_code(RTEMS_UNSATISFIED); + + // change state to not owner + owner = false; + + strcpy(name_str, " "); + for (int c = 0; (c < 4) && (mqname[c] != '\0'); c++) + name_str[c] = mqname[c]; + name = rtems_build_name(name_str[0], + name_str[1], + name_str[2], + name_str[3]); + + set_status_code(rtems_message_queue_ident(name, node, &id)); + + if (unsuccessful()) + { + make_invalid(); + } + + return last_status_code(); +} diff --git a/c/src/lib/librtems++/rtemsSemaphore.cc b/c/src/lib/librtems++/rtemsSemaphore.cc new file mode 100644 index 0000000000..1e0d3de472 --- /dev/null +++ b/c/src/lib/librtems++/rtemsSemaphore.cc @@ -0,0 +1,174 @@ +/* + ------------------------------------------------------------------------ + $Id$ + ------------------------------------------------------------------------ + + COPYRIGHT (c) 1997 + Objective Design Systems Ltd Pty (ODS) + All rights reserved (R) Objective Design Systems Ltd Pty + + The license and distribution terms for this file may be found in the + file LICENSE in this distribution or at + http://www.OARcorp.com/rtems/license.html. + + ------------------------------------------------------------------------ + + See header file. + + ------------------------------------------------------------------------ +*/ + +#include + +/* ---- + rtemsSemaphore +*/ + +rtemsSemaphore::rtemsSemaphore(const char* sname, + const Scope scope, + const rtems_unsigned32 counter, + const WaitMode wait_mode, + const Type type, + const Priority priority, + const Ceiling ceiling, + const rtems_task_priority priority_ceiling) + : name(0), + owner(true), + id(0) +{ + strcpy(name_str, "NOID"); + create(sname, + scope, + counter, + wait_mode, + type, + priority, + ceiling, + priority_ceiling); +} + +rtemsSemaphore::rtemsSemaphore(const char *sname, const rtems_unsigned32 node) + : name(0), + owner(false), + id(0) +{ + strcpy(name_str, "NOID"); + connect(sname, node); +} + +rtemsSemaphore::rtemsSemaphore(const rtemsSemaphore& semaphore) + : name(0), + owner(false), + id(0) +{ + name = semaphore.name; + strcpy(name_str, semaphore.name_str); + id = semaphore.id; +} + +rtemsSemaphore::rtemsSemaphore() + : name(0), + owner(false), + id(0) +{ + strcpy(name_str, "NOID"); +} + +rtemsSemaphore::~rtemsSemaphore() +{ + destroy(); +} + +void rtemsSemaphore::make_invalid() +{ + strcpy(name_str, "NOID"); + name = 0; + id = 0; + owner = false; +} + +const rtems_status_code rtemsSemaphore::create(const char* sname, + const Scope scope, + const rtems_unsigned32 counter, + const WaitMode wait_mode, + const Type type, + const Priority priority, + const Ceiling ceiling, + const rtems_task_priority priority_ceiling) +{ + if (id) + return set_status_code(RTEMS_ILLEGAL_ON_SELF); + + owner = true; + + strcpy(name_str, " "); + for (int c = 0; (c < 4) && (sname[c] != '\0'); c++) + name_str[c] = sname[c]; + name = rtems_build_name(name_str[0], + name_str[1], + name_str[2], + name_str[3]); + + set_status_code(rtems_semaphore_create(name, + counter, + scope | wait_mode | type | priority | ceiling, + priority_ceiling, + &id)); + + if (unsuccessful()) + { + make_invalid(); + } + + return last_status_code(); +} + +const rtems_status_code rtemsSemaphore::destroy() +{ + if (id && owner) + { + set_status_code(rtems_semaphore_delete(id)); + make_invalid(); + } + else + set_status_code(RTEMS_NOT_OWNER_OF_RESOURCE); + + return last_status_code(); +} + +const rtemsSemaphore& rtemsSemaphore::operator=(const rtemsSemaphore& semaphore) +{ + if (!owner) + { + name = semaphore.name; + id = semaphore.id; + } + return *this; +} + +const rtems_status_code rtemsSemaphore::connect(const char *sname, + const rtems_unsigned32 node) +{ + if (id && owner) + return set_status_code(RTEMS_UNSATISFIED); + + // change state to not owner + owner = false; + + strcpy(name_str, " "); + for (int c = 0; (c < 4) && (sname[c] != '\0'); c++) + name_str[c] = sname[c]; + name = rtems_build_name(name_str[0], + name_str[1], + name_str[2], + name_str[3]); + + set_status_code(rtems_semaphore_ident(name, node, &id)); + + if (unsuccessful()) + { + make_invalid(); + } + + return last_status_code(); +} diff --git a/c/src/lib/librtems++/rtemsStatusCode.cc b/c/src/lib/librtems++/rtemsStatusCode.cc new file mode 100644 index 0000000000..e8e3f965ba --- /dev/null +++ b/c/src/lib/librtems++/rtemsStatusCode.cc @@ -0,0 +1,77 @@ +/* + ------------------------------------------------------------------------ + $Id$ + ------------------------------------------------------------------------ + + COPYRIGHT (c) 1997 + Objective Design Systems Ltd Pty (ODS) + All rights reserved (R) Objective Design Systems Ltd Pty + + The license and distribution terms for this file may be found in the + file LICENSE in this distribution or at + http://www.OARcorp.com/rtems/license.html. + + ------------------------------------------------------------------------ + + See header file. + + ------------------------------------------------------------------------ +*/ + +#include + +/* ---- + Status Code string table +*/ + +static char *status_strings[RTEMS_STATUS_CODES_LAST + 1] = +{ + "RTEMS[00] successful completion", + "RTEMS[01] task exitted, returned from a thread", + "RTEMS[02] multiprocessing not configured", + "RTEMS[03] invalid object name", + "RTEMS[04] invalid object id", + "RTEMS[05] too many", + "RTEMS[06] timed out waiting", + "RTEMS[07] object deleted while waiting", + "RTEMS[08] specified size was invalid", + "RTEMS[09] address specified is invalid", + "RTEMS[10] number was invalid", + "RTEMS[11] item has not been initialized", + "RTEMS[12] resources still outstanding", + "RTEMS[13] request not satisfied", + "RTEMS[14] thread is in wrong state", + "RTEMS[15] thread already in state", + "RTEMS[16] illegal on calling thread", + "RTEMS[17] illegal for remote object", + "RTEMS[18] called from wrong environment", + "RTEMS[19] invalid thread priority", + "RTEMS[20] invalid date/time", + "RTEMS[21] invalid node id", + "RTEMS[22] directive not configured", + "RTEMS[23] not owner of resource", + "RTEMS[24] directive not implemented", + "RTEMS[25] RTEMS inconsistency detected", + "RTEMS[26] could not get enough memory" +}; + +/* ---- + StatusCode +*/ + +const char *rtemsStatusCode::last_status_string() +{ + return status_string(last_status); +} + +const char *rtemsStatusCode::status_string(rtems_status_code status_code) +{ + // mapped from "rtems/rtems/status.h" + if (status_code <= RTEMS_STATUS_CODES_LAST) + { + return status_strings[status_code]; + } + + return "unknown status code"; +} + diff --git a/c/src/lib/librtems++/rtemsTask.cc b/c/src/lib/librtems++/rtemsTask.cc new file mode 100644 index 0000000000..d90c8f669f --- /dev/null +++ b/c/src/lib/librtems++/rtemsTask.cc @@ -0,0 +1,287 @@ +/* + ------------------------------------------------------------------------ + $Id$ + ------------------------------------------------------------------------ + + COPYRIGHT (c) 1997 + Objective Design Systems Ltd Pty (ODS) + All rights reserved (R) Objective Design Systems Ltd Pty + + The license and distribution terms for this file may be found in the + file LICENSE in this distribution or at + http://www.OARcorp.com/rtems/license.html. + + ------------------------------------------------------------------------ + + See header file. + + ------------------------------------------------------------------------ +*/ + +#include +// include to allow it to be compiled +#include + +/* ---- + rtemsTask +*/ + +rtemsTask::rtemsTask(const char* tname, + const rtems_task_priority initial_priority, + const rtems_unsigned32 stack_size, + const rtems_mode preemption, + const rtems_mode timeslice, + const rtems_mode asr, + const rtems_interrupt_level interrupt_level, + const FloatingPoint floating_point, + const Scope scope) + : name(rtems_build_name('S', 'E', 'L', 'F')), + owner(true), + id(RTEMS_SELF), + argument(0) +{ + strcpy(name_str, "SELF"); + create(tname, + initial_priority, + stack_size, + preemption, + timeslice, + asr, + interrupt_level, + floating_point, + scope); +} + +rtemsTask::rtemsTask(const char *tname, rtems_unsigned32 node) + : name(rtems_build_name('S', 'E', 'L', 'F')), + owner(false), + id(RTEMS_SELF), + argument(0) +{ + strcpy(name_str, "SELF"); + connect(tname, node); +} + +rtemsTask::rtemsTask(const rtemsTask& task) + : name(rtems_build_name('S', 'E', 'L', 'F')), + owner(false), + id(RTEMS_SELF), + argument(0) +{ + name = task.name; + strcpy(name_str, task.name_str); + argument = task.argument; + id = task.id; +} + +rtemsTask::rtemsTask() + : name(rtems_build_name('S', 'E', 'L', 'F')), + owner(false), + id(RTEMS_SELF), + argument(0) +{ + strcpy(name_str, "SELF"); +} + +rtemsTask::~rtemsTask() +{ + destroy(); +} + +void rtemsTask::make_self() +{ + strcpy(name_str, "SELF"); + name = rtems_build_name('S', 'E', 'L', 'F'); + id = RTEMS_SELF; + owner = false; +} + +const rtems_status_code rtemsTask::create(const char* tname, + const rtems_task_priority initial_priority, + const rtems_unsigned32 stack_size, + const rtems_mode preemption, + const rtems_mode timeslice, + const rtems_mode asr, + const rtems_interrupt_level interrupt_level, + const FloatingPoint floating_point, + const Scope scope) +{ + if (id) + return set_status_code(RTEMS_ILLEGAL_ON_SELF); + + owner = true; + + strcpy(name_str, " "); + for (int c = 0; (c < 4) && (tname[c] != '\0'); c++) + name_str[c] = tname[c]; + name = rtems_build_name(name_str[0], + name_str[1], + name_str[2], + name_str[3]); + + // protect the values that be set as the parameters are not enums + set_status_code(rtems_task_create(name, + initial_priority, + stack_size, + (preemption & RTEMS_PREEMPT_MASK) | + (timeslice & RTEMS_TIMESLICE_MASK) | + (asr & RTEMS_ASR_MASK) | + (interrupt_level & RTEMS_INTERRUPT_MASK), + floating_point | scope, + &id)); + + if (unsuccessful()) + { + make_self(); + } + + return last_status_code(); +} + +const rtems_status_code rtemsTask::destroy() +{ + if (id && owner) + { + set_status_code(rtems_task_delete(id)); + make_self(); + } + else + set_status_code(RTEMS_NOT_OWNER_OF_RESOURCE); + + return last_status_code(); +} + +const rtemsTask& rtemsTask::operator=(const rtemsTask& task) +{ + if (!owner) + { + name = task.name; + strcpy(name_str, task.name_str); + argument = task.argument; + id = task.id; + } + return *this; +} + +const rtems_status_code rtemsTask::connect(const char *sname, + const rtems_unsigned32 node) +{ + if (id && owner) + return set_status_code(RTEMS_UNSATISFIED); + + // change state to not owner + owner = false; + + strcpy(name_str, " "); + for (int c = 0; (c < 4) && (sname[c] != '\0'); c++) + name_str[c] = sname[c]; + name = rtems_build_name(name_str[0], + name_str[1], + name_str[2], + name_str[3]); + + set_status_code(rtems_task_ident(name, node, &id)); + + if (unsuccessful()) + { + make_self(); + } + + return last_status_code(); +} + +const rtems_status_code rtemsTask::start(const rtems_task_argument arg) +{ + if (owner) + { + argument = arg; + // pass the this pointer as the argument + set_status_code(rtems_task_start(id, + origin, + (rtems_task_argument) this)); + } + else + set_status_code(RTEMS_NOT_OWNER_OF_RESOURCE); + return last_status_code(); +} + +const rtems_status_code rtemsTask::restart(const rtems_task_argument arg) +{ + if (owner) + { + argument = arg; + set_status_code(rtems_task_restart(id, (rtems_task_argument) this)); + } + else + set_status_code(RTEMS_NOT_OWNER_OF_RESOURCE); + + return last_status_code(); +} + +const rtems_status_code rtemsTask::suspend() +{ + return set_status_code(rtems_task_suspend(id)); +} + +const rtems_status_code rtemsTask::resume() +{ + return set_status_code(rtems_task_resume(id)); +} + +const rtems_status_code rtemsTask::wake_after(const rtems_interval micro_secs) +{ + rtems_interval usecs = + micro_secs && (micro_secs < _TOD_Microseconds_per_tick) ? + _TOD_Microseconds_per_tick : micro_secs; + return set_status_code(rtems_task_wake_after(TOD_MICROSECONDS_TO_TICKS(usecs))); +} + +const rtems_status_code rtemsTask::wake_when(const rtems_time_of_day& tod) +{ + return set_status_code(rtems_task_wake_when((rtems_time_of_day*) &tod)); +} + +const rtems_status_code rtemsTask::get_priority(rtems_task_priority& priority) +{ + return set_status_code(rtems_task_set_priority(id, + RTEMS_CURRENT_PRIORITY, + &priority)); +} + +const rtems_status_code rtemsTask::set_priority(const rtems_task_priority priority) +{ + rtems_task_priority old_priority; + return set_status_code(rtems_task_set_priority(id, + priority, + &old_priority)); +} + +const rtems_status_code rtemsTask::set_priority(const rtems_task_priority priority, + rtems_task_priority& old_priority) +{ + return set_status_code(rtems_task_set_priority(id, + priority, + &old_priority)); +} + +const rtems_status_code rtemsTask::get_note(const rtems_unsigned32 notepad, + rtems_unsigned32& note) +{ + return set_status_code(rtems_task_get_note(id, notepad, ¬e)); +} + +const rtems_status_code rtemsTask::set_note(const rtems_unsigned32 notepad, + const rtems_unsigned32 note) +{ + return set_status_code(rtems_task_set_note(id, notepad, note)); +} + +void rtemsTask::body(rtems_task_argument ) +{ +} + +rtems_task rtemsTask::origin(rtems_task_argument argument) +{ + rtemsTask *task = (rtemsTask*) argument; + task->body(task->argument); +} diff --git a/c/src/lib/librtems++/rtemsTimer.cc b/c/src/lib/librtems++/rtemsTimer.cc new file mode 100644 index 0000000000..b87ffd5e80 --- /dev/null +++ b/c/src/lib/librtems++/rtemsTimer.cc @@ -0,0 +1,100 @@ +/* + ------------------------------------------------------------------------ + $Id$ + ------------------------------------------------------------------------ + + COPYRIGHT (c) 1997 + Objective Design Systems Ltd Pty (ODS) + All rights reserved (R) Objective Design Systems Ltd Pty + + The license and distribution terms for this file may be found in the + file LICENSE in this distribution or at + http://www.OARcorp.com/rtems/license.html. + + ------------------------------------------------------------------------ + + See header file. + + ------------------------------------------------------------------------ +*/ + +#include + +/* ---- + rtemsTimer +*/ + +rtemsTimer::rtemsTimer(const char* tname) + : name(0), + repeat(false), + id(0) +{ + strcpy(name_str, " "); + create(tname); +} + +rtemsTimer::rtemsTimer() + : name(0), + repeat(false), + id(0) +{ + strcpy(name_str, " "); +} + +rtemsTimer::~rtemsTimer() +{ + destroy(); +} + +void rtemsTimer::make_invalid() +{ + strcpy(name_str, " "); + name = 0; + id = 0; + repeat = false; +} +const rtems_status_code rtemsTimer::create(const char* tname) +{ + if (id) + return set_status_code(RTEMS_ILLEGAL_ON_SELF); + + strcpy(name_str, " "); + for (int c = 0; (c < 4) && (tname[c] != '\0'); c++) + name_str[c] = tname[c]; + name = rtems_build_name(name_str[0], + name_str[1], + name_str[2], + name_str[3]); + + set_status_code(rtems_timer_create(name, &id)); + + if (unsuccessful()) + { + make_invalid(); + } + + return last_status_code(); +} + +const rtems_status_code rtemsTimer::destroy() +{ + if (id) + { + set_status_code(rtems_timer_delete(id)); + make_invalid(); + } + else + set_status_code(RTEMS_NOT_OWNER_OF_RESOURCE); + + return last_status_code(); +} + +void rtemsTimer::common_handler(rtems_id , void *user_data) +{ + rtemsTimer *timer = (rtemsTimer*) user_data; + + if (timer->repeat) + timer->reset(); + + timer->triggered(); +} -- cgit v1.2.3