Revision 43

Date:
2007/03/29 06:44:12
Author:
gdshaw@RISCPKG.ORG
Revision Log:
Added virtualisation of floating point context.
Files:

Legend:

 
Added
 
Removed
 
Modified
  • trunk/thread/fp_context.cc

     
    1 // This file is part of the Thread module.
    2 // Copyright � 2007 Graham Shaw.
    3 // Redistribution and modification are permitted within the terms of the
    4 // GNU General Public License (version 2 or any later version).
    5
    6 #include "fp_context.h"
    7
    8 fp_context::fp_context()
    9 {
    10 for (unsigned int i=0;i!=fp_register_count;++i)
    11 {
    12 for (unsigned int j=0;j!=3;++j)
    13 {
    14 _fp_registers[i].value[j]=0;
    15 }
    16 }
    17 _fp_status=0;
    18 }
  • trunk/thread/fp_context.h

     
    1 // This file is part of the Thread module.
    2 // Copyright � 2007 Graham Shaw.
    3 // Redistribution and modification are permitted within the terms of the
    4 // GNU General Public License (version 2 or any later version).
    5
    6 #ifndef THREAD_FP_CONTEXT
    7 #define THREAD_FP_CONTEXT
    8
    9 #include "context.h"
    10
    11 /** A class to represent the floating point context of a thread. */
    12 class fp_context:
    13 public context
    14 {
    15 public:
    16 struct fp_register
    17 {
    18 int value[3];
    19 };
    20
    21 enum
    22 {
    23 /** The number of general-purpose floating point registers. */
    24 fp_register_count=8
    25 };
    26 private:
    27 /** The general-purpose floating point registers. */
    28 fp_register _fp_registers[fp_register_count];
    29
    30 /** The floating point status register. */
    31 int _fp_status;
    32 public:
    33 /** Construct floating point context. */
    34 fp_context();
    35
    36 /** Get general-purpose floating point registers. */
    37 const fp_register* fp_registers() const
    38 { return _fp_registers; }
    39
    40 /** Get floating point status registers. */
    41 int fp_status() const
    42 { return _fp_status; }
    43
    44 /** Load floating point context. */
    45 inline void load();
    46
    47 /** Save floating point context. */
    48 inline void save();
    49 };
    50
    51 extern "C"
    52 void load_fp_context(fp_context::fp_register* fp_registers,int* fp_status);
    53
    54 extern "C"
    55 void save_fp_context(fp_context::fp_register* fp_registers,int* fp_status);
    56
    57 inline void fp_context::load()
    58 {
    59 load_fp_context(_fp_registers,&_fp_status);
    60 }
    61
    62 inline void fp_context::save()
    63 {
    64 save_fp_context(_fp_registers,&_fp_status);
    65 }
    66
    67 #endif
  • trunk/thread/load_fp_context.s

     
    1 ; This file is part of the Thread module.
    2 ; Copyright � 2007 Graham Shaw.
    3 ; Redistribution and modification are permitted within the terms of the
    4 ; GNU General Public License (version 2 or any later version).
    5
    6 AREA |C$Code|,CODE,READONLY
    7
    8 ; On entry:
    9 ; R0 = pointer to general-purpose fp registers (8x12=96 bytes)
    10 ; R1 = pointer to fp status register (4 bytes)
    11
    12 EXPORT load_fp_context
    13 load_fp_context
    14 LFMIA f0,4,[r0]!
    15 LFMIA f4,4,[r0]!
    16 LDR r12,[r1]
    17 WFS r12
    18 MOV pc,lr
    19
    20 END
  • trunk/thread/save_fp_context.s

     
    1 ; This file is part of the Thread module.
    2 ; Copyright � 2007 Graham Shaw.
    3 ; Redistribution and modification are permitted within the terms of the
    4 ; GNU General Public License (version 2 or any later version).
    5
    6 AREA |C$Code|,CODE,READONLY
    7
    8 ; On entry:
    9 ; R0 = pointer to general-purpose fp registers (8x12=96 bytes)
    10 ; R1 = pointer to fp status register (4 bytes)
    11
    12 EXPORT save_fp_context
    13 save_fp_context
    14 SFMIA f0,4,[r0]!
    15 SFMIA f4,4,[r0]!
    16 RFS r12
    17 STR r12,[r1]
    18 MOV pc,lr
    19
    20 END
  • trunk/thread/thread.cc

     
    15 15 #include "amb.h"
    16 16 #include "environment.h"
    17 17 #include "shared_svc_stack.h"
    18 #include "fp_context.h"
    18 19 #include "thread.h"
    19 20 #include "scheduler.h"
    20 21
     
    45 46 _amb(increment_refcount(new(std::nothrow) ::amb(pages))),
    46 47 _environment(increment_refcount(new(std::nothrow) ::environment(pages))),
    47 48 _shared_svc_stack(increment_refcount(new(std::nothrow)
    48 ::shared_svc_stack(bytes_to_frags(cpu::current()->svc_stack_size()))))
    49 ::shared_svc_stack(bytes_to_frags(cpu::current()->svc_stack_size())))),
    50 _fp_context(increment_refcount(new(std::nothrow) ::fp_context()))
    49 51 {
    50 52 // Add this thread to the hash of thread handles.
    51 53 _threads[_handle%_threads_size].push_front(*this);
     
    62 64 _svc_stack_reservation(0),
    63 65 _amb(0),
    64 66 _environment(0),
    65 _shared_svc_stack(0)
    67 _shared_svc_stack(0),
    68 _fp_context(0)
    66 69 {
    67 70 // Copy context.
    68 71 _amb=increment_refcount(
     
    71 74 new(std::nothrow) ::environment(*parent._environment));
    72 75 _shared_svc_stack=increment_refcount(
    73 76 new(std::nothrow) ::shared_svc_stack(*parent._shared_svc_stack));
    77 _fp_context=increment_refcount(
    78 new(std::nothrow) ::fp_context(*parent._fp_context));
    74 79
    75 80 // Copy registers.
    76 81 memcpy(_registers,parent._registers,register_count*sizeof(int));
     
    102 107 release_svc_stack_reservation();
    103 108
    104 109 // Release context.
    110 decrement_refcount(_fp_context);
    105 111 decrement_refcount(_shared_svc_stack);
    106 112 decrement_refcount(_environment);
    107 113 decrement_refcount(_amb);
     
    170 176
    171 177 void thread::activate()
    172 178 {
    179 // Save floating point context.
    180 if (::fp_context* fp=cpu::current()->thread()->_fp_context) fp->save();
    181
    173 182 // Disable interrupts.
    174 183 int irqs_disabled=_kernel_irqs_disabled();
    175 184 _kernel_irqs_off();
     
    183 192 // Re-enable interrupts.
    184 193 if (!irqs_disabled) _kernel_irqs_on();
    185 194
    195 // Load floating point context.
    196 if (_fp_context) _fp_context->load();
    197
    186 198 // Change state to state_running and register with CPU.
    187 199 _state=state_running;
    188 200 cpu::current()->thread(this);
  • trunk/thread/thread.h

     
    13 13 class amb;
    14 14 class environment;
    15 15 class shared_svc_stack;
    16 class fp_context;
    16 17
    17 18 /** A structure used to tag list nodes for indexing threads by handle. */
    18 19 struct thread_tag
     
    105 106
    106 107 /** The shared supervisor stack for this thread. */
    107 108 ::shared_svc_stack* _shared_svc_stack;
    109
    110 /** The floating point context for this thread. */
    111 ::fp_context* _fp_context;
    108 112 public:
    109 113 /** Construct new thread.
    110 114 * @param pages the initial number of pages to be allocated
     
    185 189 ::shared_svc_stack* shared_svc_stack()
    186 190 { return _shared_svc_stack; }
    187 191
    192 /** Get floating point context.
    193 * @return the floating point context for this thread
    194 */
    195 ::fp_context* fp_context()
    196 { return _fp_context; }
    197
    188 198 /** Set state.
    189 199 * @param state the required state of this thread
    190 200 */