OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [hal/] [powerpc/] [arch/] [current/] [src/] [hal_misc.c] - Blame information for rev 786

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 786 skrzyp
//==========================================================================
2
//
3
//      hal_misc.c
4
//
5
//      HAL miscellaneous functions
6
//
7
//==========================================================================
8
// ####ECOSGPLCOPYRIGHTBEGIN####                                            
9
// -------------------------------------------                              
10
// This file is part of eCos, the Embedded Configurable Operating System.   
11
// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc.
12
//
13
// eCos is free software; you can redistribute it and/or modify it under    
14
// the terms of the GNU General Public License as published by the Free     
15
// Software Foundation; either version 2 or (at your option) any later      
16
// version.                                                                 
17
//
18
// eCos is distributed in the hope that it will be useful, but WITHOUT      
19
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or    
20
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License    
21
// for more details.                                                        
22
//
23
// You should have received a copy of the GNU General Public License        
24
// along with eCos; if not, write to the Free Software Foundation, Inc.,    
25
// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.            
26
//
27
// As a special exception, if other files instantiate templates or use      
28
// macros or inline functions from this file, or you compile this file      
29
// and link it with other works to produce a work based on this file,       
30
// this file does not by itself cause the resulting work to be covered by   
31
// the GNU General Public License. However the source code for this file    
32
// must still be made available in accordance with section (3) of the GNU   
33
// General Public License v2.                                               
34
//
35
// This exception does not invalidate any other reasons why a work based    
36
// on this file might be covered by the GNU General Public License.         
37
// -------------------------------------------                              
38
// ####ECOSGPLCOPYRIGHTEND####                                              
39
//==========================================================================
40
//#####DESCRIPTIONBEGIN####
41
//
42
// Author(s):    nickg, jskov
43
// Contributors: nickg, jskov,
44
//               jlarmour, gthomas
45
// Date:         1999-02-20
46
// Purpose:      HAL miscellaneous functions
47
// Description:  This file contains miscellaneous functions provided by the
48
//               HAL.
49
//
50
//####DESCRIPTIONEND####
51
//
52
//===========================================================================
53
 
54
#include <pkgconf/hal.h>
55
 
56
#define CYGARC_HAL_COMMON_EXPORT_CPU_MACROS
57
#include <cyg/hal/ppc_regs.h>           // SPR definitions
58
 
59
#include <cyg/infra/cyg_type.h>
60
#include <cyg/infra/cyg_trac.h>         // tracing macros
61
#include <cyg/infra/cyg_ass.h>          // assertion macros
62
#include <cyg/infra/diag.h>             // diag_printf
63
 
64
#include <cyg/hal/hal_arch.h>           // HAL header
65
#include <cyg/hal/hal_cache.h>          // HAL cache
66
#if defined(CYGFUN_HAL_COMMON_KERNEL_SUPPORT) && \
67
    defined(CYGPKG_HAL_EXCEPTIONS)
68
# include <cyg/hal/hal_intr.h>           // HAL interrupts/exceptions
69
#endif
70
#include <cyg/hal/hal_mem.h>            // HAL memory handling
71
 
72
//---------------------------------------------------------------------------
73
// Functions used during initialization.
74
 
75
#ifdef CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG
76
cyg_bool cyg_hal_stop_constructors;
77
#endif
78
 
79
typedef void (*pfunc) (void);
80
extern pfunc __CTOR_LIST__[];
81
extern pfunc __CTOR_END__[];
82
 
83
void
84
cyg_hal_invoke_constructors (void)
85
{
86
#ifdef CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG
87
    static pfunc *p = &__CTOR_END__[-1];
88
 
89
    cyg_hal_stop_constructors = 0;
90
    for (; p >= __CTOR_LIST__; p--) {
91
        (*p) ();
92
        if (cyg_hal_stop_constructors) {
93
            p--;
94
            break;
95
        }
96
    }
97
#else
98
    pfunc *p;
99
 
100
    for (p = &__CTOR_END__[-1]; p >= __CTOR_LIST__; p--)
101
        (*p) ();
102
#endif
103
}
104
 
105
// Override any __eabi the compiler might generate. We don't want
106
// constructors to be called twice.
107
void __eabi (void) {}
108
 
109
//---------------------------------------------------------------------------
110
// First level C exception handler.
111
 
112
externC void __handle_exception (void);
113
 
114
externC HAL_SavedRegisters *_hal_registers;
115
 
116
#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
117
externC void* volatile __mem_fault_handler;
118
#endif
119
 
120
void
121
cyg_hal_exception_handler(HAL_SavedRegisters *regs)
122
{
123
#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
124
 
125
    // If we caught an exception inside the stubs, see if we were expecting it
126
    // and if so jump to the saved address
127
    if (__mem_fault_handler) {
128
        regs->pc = (CYG_ADDRWORD)__mem_fault_handler;
129
        return; // Caught an exception inside stubs        
130
    }
131
 
132
    // Set the pointer to the registers of the current exception
133
    // context. At entry the GDB stub will expand the
134
    // HAL_SavedRegisters structure into a (bigger) register array.
135
    _hal_registers = regs;
136
 
137
    __handle_exception();
138
 
139
#ifdef CYGPKG_HAL_QUICC
140
    {
141
        // This is unpleasant: it appears that if we interrupt the board
142
        // using ^C coming in on the QUICC's SMC1, by planting a breakpoint
143
        // at the interrupt return address, the decrementer interrupt is
144
        // not taken when the bp exception returns AND WORSE no other
145
        // interrupt is possible until the decrementer fires again.  This
146
        // does not apply to simple "incoming character" interrupts; it
147
        // seems it has to be combined with an immediate trap on RTI for
148
        // this to occur.
149
        // 
150
        // The solution is to test for decrementer underflow after the
151
        // (any) exception, and maybe reinitialize the decrementer.  If the
152
        // decrementer interrupt gets taken, that causes decrementer reinit
153
        // too, and no harm is done.
154
 
155
        cyg_uint32 result;
156
        asm volatile(
157
            "mfdec  %0;"
158
            : "=r"(result)
159
            );
160
 
161
        if ( CYGNUM_HAL_RTC_PERIOD < result ) {
162
            // then we missed a tick, but the exception masked it
163
            // reset the decrementer here
164
            asm volatile(
165
                "mtdec  %0;"
166
                : : "r"(CYGNUM_HAL_RTC_PERIOD)
167
                );
168
        }
169
    }
170
#endif
171
 
172
#elif defined(CYGFUN_HAL_COMMON_KERNEL_SUPPORT) && \
173
      defined(CYGPKG_HAL_EXCEPTIONS)
174
    int vector = regs->vector>>CYGHWR_HAL_POWERPC_VECTOR_ALIGNMENT;
175
 
176
    // We should decode the vector and pass a more appropriate
177
    // value as the second argument. For now we simply pass a
178
    // pointer to the saved registers. We should also divert
179
    // breakpoint and other debug vectors into the debug stubs.
180
 
181
#ifndef CYGHWR_HAL_POWERPC_BOOK_E
182
    if (vector==CYGNUM_HAL_VECTOR_PROGRAM) {
183
        int srr1;
184
        CYGARC_MFSPR(CYGARC_REG_SRR1, srr1); // get srr1
185
 
186
        switch ((srr1 >> 17) & 0xf) {
187
        case 1:
188
            vector = CYGNUM_HAL_EXCEPTION_TRAP;
189
            break;
190
        case 2:
191
            vector = CYGNUM_HAL_EXCEPTION_PRIVILEGED_INSTRUCTION;
192
            break;
193
        case 4:
194
            vector = CYGNUM_HAL_EXCEPTION_ILLEGAL_INSTRUCTION;
195
            break;
196
        case 8:
197
            vector = CYGNUM_HAL_EXCEPTION_FPU;
198
            break;
199
        default:
200
            CYG_FAIL("Unknown PROGRAM exception!!");
201
        }
202
    }
203
#endif
204
 
205
    cyg_hal_deliver_exception( vector, (CYG_ADDRWORD)regs );
206
 
207
#else
208
 
209
    CYG_FAIL("Exception!!!");
210
 
211
#endif    
212
 
213
    return;
214
}
215
 
216
//---------------------------------------------------------------------------
217
// Default ISRs
218
 
219
#ifndef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
220
externC cyg_uint32
221
hal_default_isr(CYG_ADDRWORD vector, CYG_ADDRWORD data)
222
{
223
    diag_printf("Interrupt: %d\n", vector);
224
 
225
    CYG_FAIL("Spurious Interrupt!!!");
226
    return 0;
227
}
228
#else
229
externC cyg_uint32
230
hal_arch_default_isr(CYG_ADDRWORD vector, CYG_ADDRWORD data)
231
{
232
    return 0;
233
}
234
#endif
235
 
236
// The decrementer default ISR has to do nothing. The reason is that
237
// decrementer interrupts cannot be disabled - if a kernel configuration
238
// does not use the RTC, but does use external interrupts, the decrementer
239
// underflow could cause a CYG_FAIL (as above) even though the user did
240
// not expect any decrementer interrupts to happen.
241
externC cyg_uint32
242
hal_default_decrementer_isr(CYG_ADDRWORD vector, CYG_ADDRWORD data)
243
{
244
    return 0;
245
}
246
 
247
//---------------------------------------------------------------------------
248
// Idle thread action
249
 
250
externC bool hal_variant_idle_thread_action(cyg_uint32);
251
 
252
void
253
hal_idle_thread_action( cyg_uint32 count )
254
{
255
    // Execute variant idle thread action, while allowing it to control
256
    // whether to run any of the architecture action code.
257
    if (!hal_variant_idle_thread_action(count))
258
        return;
259
 
260
#if 0
261
    do {
262
        register cyg_uint32 dec;
263
 
264
        asm volatile(
265
            "mfdec  %0;"
266
            : "=r"(dec)
267
            );
268
        diag_printf( "Decrementer %08x\n", dec);
269
    } while (0);
270
#endif
271
}
272
 
273
//---------------------------------------------------------------------------
274
// Use MMU resources to map memory regions.  
275
// This relies that the platform HAL providing an
276
//          externC cyg_memdesc_t cyg_hal_mem_map[];
277
// as detailed in hal_cache.h, and the variant HAL providing the
278
// MMU mapping/clear functions.
279
externC void
280
hal_MMU_init (void)
281
{
282
    int id = 0;
283
    int i  = 0;
284
 
285
    cyg_hal_clear_MMU ();
286
 
287
    while (cyg_hal_mem_map[i].size) {
288
        id = cyg_hal_map_memory (id,
289
                                 cyg_hal_mem_map[i].virtual_addr,
290
                                 cyg_hal_mem_map[i].physical_addr,
291
                                 cyg_hal_mem_map[i].size,
292
                                 cyg_hal_mem_map[i].flags);
293
        i++;
294
    }
295
}
296
 
297
//---------------------------------------------------------------------------
298
// Initial cache enabling
299
// Specific behavior for each platform configured via plf_cache.h
300
 
301
externC void
302
hal_enable_caches(void)
303
{
304
#ifndef HAL_CACHE_UNIFIED
305
 
306
#if !(defined(CYG_HAL_STARTUP_RAM) || defined(CYG_HAL_STARTUP_JTAG))
307
    // Invalidate caches
308
    HAL_DCACHE_INVALIDATE_ALL();
309
    HAL_ICACHE_INVALIDATE_ALL();
310
#endif
311
 
312
#ifdef CYGSEM_HAL_ENABLE_ICACHE_ON_STARTUP
313
#ifdef HAL_ICACHE_UNLOCK_ALL
314
    HAL_ICACHE_UNLOCK_ALL();
315
#endif
316
    HAL_ICACHE_ENABLE();
317
#endif
318
 
319
#ifdef CYGSEM_HAL_ENABLE_DCACHE_ON_STARTUP
320
#ifdef HAL_DCACHE_UNLOCK_ALL
321
    HAL_DCACHE_UNLOCK_ALL();
322
#endif
323
    HAL_DCACHE_ENABLE();
324
#ifdef HAL_DCACHE_WRITE_MODE
325
#ifdef CYGSEM_HAL_DCACHE_STARTUP_MODE_COPYBACK
326
    HAL_DCACHE_WRITE_MODE(HAL_DCACHE_WRITEBACK_MODE);
327
#else
328
    HAL_DCACHE_WRITE_MODE(HAL_DCACHE_WRITETHRU_MODE);
329
#endif
330
#endif
331
#endif
332
 
333
#else // HAL_CACHE_UNIFIED
334
 
335
 
336
#if !(defined(CYG_HAL_STARTUP_RAM) || defined(CYG_HAL_STARTUP_JTAG))
337
    // Invalidate cache
338
    HAL_UCACHE_INVALIDATE_ALL();
339
#endif
340
 
341
 
342
#if defined(CYGSEM_HAL_ENABLE_DCACHE_ON_STARTUP)
343
 
344
 
345
    HAL_UCACHE_ENABLE();
346
 
347
#endif
348
 
349
#endif // HAL_CACHE_UNIFIED
350
 
351
}
352
 
353
//---------------------------------------------------------------------------
354
//A jump via a null pointer causes the CPU to end up here.
355
externC void
356
hal_null_call(void)
357
{
358
 
359
    CYG_FAIL("Call via NULL-pointer!");
360
    for(;;);
361
}
362
 
363
//---------------------------------------------------------------------------
364
// End of hal_misc.c

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.