comparison packages/hal/common/current/src/hal_if.c @ 105:5a0cc6c243a9 ecos-sw-2000-06-30

Merge from eCos master repository on 2000-06-30-08:18:49-BST
author jlarmour
date Fri, 30 Jun 2000 16:27:35 +0000
parents 95f3e12a6327
children 7f461c3a372c
comparison
equal deleted inserted replaced
104:ad66e26a9e7c 105:5a0cc6c243a9
39 // 39 //
40 //============================================================================= 40 //=============================================================================
41 41
42 #include <pkgconf/hal.h> 42 #include <pkgconf/hal.h>
43 43
44 #ifdef CYGPKG_KERNEL
45 # include <pkgconf/kernel.h>
46 #endif
47
44 #include <cyg/infra/cyg_ass.h> // assertions 48 #include <cyg/infra/cyg_ass.h> // assertions
45 49
46 #include <cyg/hal/hal_arch.h> // set/restore GP 50 #include <cyg/hal/hal_arch.h> // set/restore GP
47 51
48 #include <cyg/hal/hal_io.h> // IO macros 52 #include <cyg/hal/hal_io.h> // IO macros
49 #include <cyg/hal/hal_if.h> // our interface 53 #include <cyg/hal/hal_if.h> // our interface
50 54
51 #include <cyg/hal/hal_diag.h> // Diag IO 55 #include <cyg/hal/hal_diag.h> // Diag IO
56 #include <cyg/hal/hal_misc.h> // User break
52 57
53 #include <cyg/hal/hal_stub.h> // stub functionality 58 #include <cyg/hal/hal_stub.h> // stub functionality
54 #include <cyg/hal/plf_stub.h> // reset entry - FIXME, should be moved 59 #include <cyg/hal/plf_stub.h> // reset entry - FIXME, should be moved
55 60
61 #include <cyg/hal/hal_intr.h> // hal_vsr_table and others
62
56 63
57 //-------------------------------------------------------------------------- 64 //--------------------------------------------------------------------------
58 65
59 externC void patch_dbg_syscalls(void * vector); 66 externC void patch_dbg_syscalls(void * vector);
60 externC void init_thread_syscall(void * vector); 67 externC void init_thread_syscall(void * vector);
61 68
62 externC CYG_ADDRWORD hal_interrupt_handlers[];
63 externC CYG_ADDRWORD hal_vsr_table[];
64
65 //-------------------------------------------------------------------------- 69 //--------------------------------------------------------------------------
66 // Implementations and function wrappers for monitor services 70 // Implementations and function wrappers for monitor services
71
67 #ifdef CYGPRI_HAL_IMPLEMENTS_IF_SERVICES 72 #ifdef CYGPRI_HAL_IMPLEMENTS_IF_SERVICES
73 static void
74 delay_us(cyg_int32 usecs)
75 {
76 #ifdef CYGPKG_KERNEL
77 cyg_int32 start, elapsed;
78 cyg_int32 usec_ticks, slice;
79 CYGARC_HAL_SAVE_GP();
80
81 // How many ticks total we should wait for.
82 usec_ticks = usecs*CYGNUM_KERNEL_COUNTERS_RTC_PERIOD;
83 usec_ticks /= CYGNUM_HAL_RTC_NUMERATOR/CYGNUM_HAL_RTC_DENOMINATOR/1000;
84
85 do {
86 // Spin in slices of 1/2 the RTC period. Allows interrupts
87 // time to run without messing up the algorithm. If we spun
88 // for 1 period (or more) of the RTC, there'd be also problems
89 // figuring out when the timer wrapped. We may lose a tick or
90 // two for each cycle but it shouldn't matter much.
91 slice = usec_ticks % (CYGNUM_KERNEL_COUNTERS_RTC_PERIOD / 2);
92
93 HAL_CLOCK_READ(&start);
94 do {
95 HAL_CLOCK_READ(&elapsed);
96 elapsed = (elapsed - start); // counts up!
97 if (elapsed < 0)
98 elapsed += CYGNUM_KERNEL_COUNTERS_RTC_PERIOD;
99 } while (elapsed < slice);
100
101 // Adjust by elapsed, not slice, since an interrupt may have
102 // been stalling us for some time.
103 usec_ticks -= elapsed;
104 } while (usec_ticks > 0);
105
106 CYGARC_HAL_RESTORE_GP();
107 #endif
108 }
68 109
69 static void 110 static void
70 reset(void) 111 reset(void)
71 { 112 {
113 CYGARC_HAL_SAVE_GP();
72 // With luck, the platform defines some magic that will cause a hardware 114 // With luck, the platform defines some magic that will cause a hardware
73 // reset. 115 // reset.
74 HAL_STUB_PLATFORM_RESET(); 116 HAL_STUB_PLATFORM_RESET();
75 117
76 #ifdef HAL_STUB_PLATFORM_RESET_ENTRY 118 #ifdef HAL_STUB_PLATFORM_RESET_ENTRY
81 goto *HAL_STUB_PLATFORM_RESET_ENTRY; 123 goto *HAL_STUB_PLATFORM_RESET_ENTRY;
82 124
83 #else 125 #else
84 #error " no RESET_ENTRY" 126 #error " no RESET_ENTRY"
85 #endif 127 #endif
128
129 CYGARC_HAL_RESTORE_GP();
86 } 130 }
87 131
88 // This is the system's default kill signal routine. Unless overridden 132 // This is the system's default kill signal routine. Unless overridden
89 // by the application, it will cause a board reset when GDB quits the 133 // by the application, it will cause a board reset when GDB quits the
90 // connection. (The user can avoid the reset by using the GDB 'detach' 134 // connection. (The user can avoid the reset by using the GDB 'detach'
91 // command instead of 'kill' or 'quit'). 135 // command instead of 'kill' or 'quit').
92 static int 136 static int
93 kill_by_reset(int __irq_nr, void* __regs) 137 kill_by_reset(int __irq_nr, void* __regs)
94 { 138 {
139 CYGARC_HAL_SAVE_GP();
140
95 reset(); 141 reset();
142
143 CYGARC_HAL_RESTORE_GP();
96 return 0; 144 return 0;
97 } 145 }
98 146
99 static int 147 static int
100 nop_service(void) 148 nop_service(void)
108 //---------------------------------- 156 //----------------------------------
109 // Comm controls 157 // Comm controls
110 158
111 static hal_virtual_comm_table_t comm_channels[CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS+1]; 159 static hal_virtual_comm_table_t comm_channels[CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS+1];
112 160
113
114
115 static int 161 static int
116 set_debug_comm(int __comm_id) 162 set_debug_comm(int __comm_id)
117 { 163 {
118 static int __selected_id = CYGNUM_CALL_IF_SET_COMM_ID_EMPTY; 164 static int __selected_id = CYGNUM_CALL_IF_SET_COMM_ID_EMPTY;
165 hal_virtual_comm_table_t* __chan;
166 int interrupt_state = 0;
167 int res = 1, update = 0;
168 CYGARC_HAL_SAVE_GP();
119 169
120 CYG_ASSERT(__comm_id >= CYGNUM_CALL_IF_SET_COMM_ID_MANGLER 170 CYG_ASSERT(__comm_id >= CYGNUM_CALL_IF_SET_COMM_ID_MANGLER
121 && __comm_id < CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS, 171 && __comm_id < CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS,
122 "Invalid channel"); 172 "Invalid channel");
123 173
124 switch (__comm_id) { 174 switch (__comm_id) {
125 case CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT: 175 case CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT:
126 if (__selected_id > 0) 176 if (__selected_id > 0)
127 return __selected_id-1; 177 res = __selected_id-1;
128 if (__selected_id == 0) 178 else if (__selected_id == 0)
129 return CYGNUM_CALL_IF_SET_COMM_ID_MANGLER; 179 res = CYGNUM_CALL_IF_SET_COMM_ID_MANGLER;
130 return __selected_id; 180 else
181 res = __selected_id;
182 break;
131 183
132 case CYGNUM_CALL_IF_SET_COMM_ID_EMPTY: 184 case CYGNUM_CALL_IF_SET_COMM_ID_EMPTY:
133 CYGACC_CALL_IF_DEBUG_PROCS_SET(0); 185 CYGACC_CALL_IF_DEBUG_PROCS_SET(0);
134 __selected_id = __comm_id; 186 __selected_id = __comm_id;
135 return 1; 187 break;
136 188
137 case CYGNUM_CALL_IF_SET_COMM_ID_MANGLER: 189 case CYGNUM_CALL_IF_SET_COMM_ID_MANGLER:
138 __comm_id = 0; 190 __comm_id = 0;
191 update = 1;
139 break; 192 break;
140 193
141 default: 194 default:
142 __comm_id++; // skip mangler entry 195 __comm_id++; // skip mangler entry
143 break; 196 update = 1;
144 } 197 break;
145 198 }
146 __selected_id = __comm_id; 199
147 200 if (update) {
148 CYGACC_CALL_IF_DEBUG_PROCS_SET(comm_channels[__comm_id]); 201 // Find the interrupt state of the channel.
149 202 __chan = CYGACC_CALL_IF_DEBUG_PROCS();
150 return 1; 203 if (__chan)
204 interrupt_state = CYGACC_COMM_IF_CONTROL(*__chan)(CYGACC_COMM_IF_CH_DATA(*__chan), __COMMCTL_IRQ_DISABLE);
205
206 __selected_id = __comm_id;
207 CYGACC_CALL_IF_DEBUG_PROCS_SET(comm_channels[__comm_id]);
208
209 // Set interrupt state on the new channel.
210 __chan = CYGACC_CALL_IF_DEBUG_PROCS();
211 if (interrupt_state)
212 CYGACC_COMM_IF_CONTROL(*__chan)(CYGACC_COMM_IF_CH_DATA(*__chan), __COMMCTL_IRQ_ENABLE);
213 else
214 CYGACC_COMM_IF_CONTROL(*__chan)(CYGACC_COMM_IF_CH_DATA(*__chan), __COMMCTL_IRQ_DISABLE);
215 }
216
217 CYGARC_HAL_RESTORE_GP();
218 return res;
151 } 219 }
152 220
153 static int 221 static int
154 set_console_comm(int __comm_id) 222 set_console_comm(int __comm_id)
155 { 223 {
156 static int __selected_id = CYGNUM_CALL_IF_SET_COMM_ID_EMPTY; 224 static int __selected_id = CYGNUM_CALL_IF_SET_COMM_ID_EMPTY;
225 int res = 1, update = 0;
226 CYGARC_HAL_SAVE_GP();
157 227
158 CYG_ASSERT(__comm_id >= CYGNUM_CALL_IF_SET_COMM_ID_MANGLER 228 CYG_ASSERT(__comm_id >= CYGNUM_CALL_IF_SET_COMM_ID_MANGLER
159 && __comm_id < CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS, 229 && __comm_id < CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS,
160 "Invalid channel"); 230 "Invalid channel");
161 231
162 switch (__comm_id) { 232 switch (__comm_id) {
163 case CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT: 233 case CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT:
164 if (__selected_id > 0) 234 if (__selected_id > 0)
165 return __selected_id-1; 235 res = __selected_id-1;
166 if (__selected_id == 0) 236 else if (__selected_id == 0)
167 return CYGNUM_CALL_IF_SET_COMM_ID_MANGLER; 237 res = CYGNUM_CALL_IF_SET_COMM_ID_MANGLER;
168 return __selected_id; 238 else
239 res = __selected_id;
240 break;
169 241
170 case CYGNUM_CALL_IF_SET_COMM_ID_EMPTY: 242 case CYGNUM_CALL_IF_SET_COMM_ID_EMPTY:
171 CYGACC_CALL_IF_CONSOLE_PROCS_SET(0); 243 CYGACC_CALL_IF_CONSOLE_PROCS_SET(0);
172 __selected_id = __comm_id; 244 __selected_id = __comm_id;
173 return 1; 245 break;
174 246
175 case CYGNUM_CALL_IF_SET_COMM_ID_MANGLER: 247 case CYGNUM_CALL_IF_SET_COMM_ID_MANGLER:
176 __comm_id = 0; 248 __comm_id = 0;
249 update = 1;
177 break; 250 break;
178 251
179 default: 252 default:
180 __comm_id++; // skip mangler entry 253 __comm_id++; // skip mangler entry
254 update = 1;
181 break; 255 break;
182 } 256 }
183 257
184 __selected_id = __comm_id; 258 if (update) {
259 __selected_id = __comm_id;
185 260
186 CYGACC_CALL_IF_CONSOLE_PROCS_SET(comm_channels[__comm_id]); 261 CYGACC_CALL_IF_CONSOLE_PROCS_SET(comm_channels[__comm_id]);
187 262 }
188 return 1; 263
264 CYGARC_HAL_RESTORE_GP();
265 return res;
189 } 266 }
190 267
191 //---------------------------------- 268 //----------------------------------
192 // Cache functions 269 // Cache functions
193 270
194 static void 271 static void
195 flush_icache(void *__p, int __nbytes) 272 flush_icache(void *__p, int __nbytes)
196 { 273 {
274 CYGARC_HAL_SAVE_GP();
197 #ifdef HAL_ICACHE_FLUSH 275 #ifdef HAL_ICACHE_FLUSH
198 HAL_ICACHE_FLUSH( __p , __nbytes ); 276 HAL_ICACHE_FLUSH( __p , __nbytes );
199 #elif defined(HAL_ICACHE_INVALIDATE) 277 #elif defined(HAL_ICACHE_INVALIDATE)
200 HAL_ICACHE_INVALIDATE(); 278 HAL_ICACHE_INVALIDATE();
201 #endif 279 #endif
280 CYGARC_HAL_RESTORE_GP();
202 } 281 }
203 282
204 static void 283 static void
205 flush_dcache(void *__p, int __nbytes) 284 flush_dcache(void *__p, int __nbytes)
206 { 285 {
286 CYGARC_HAL_SAVE_GP();
207 #ifdef HAL_DCACHE_FLUSH 287 #ifdef HAL_DCACHE_FLUSH
208 HAL_DCACHE_FLUSH( __p , __nbytes ); 288 HAL_DCACHE_FLUSH( __p , __nbytes );
209 #elif defined(HAL_DCACHE_INVALIDATE) 289 #elif defined(HAL_DCACHE_INVALIDATE)
210 HAL_DCACHE_INVALIDATE(); 290 HAL_DCACHE_INVALIDATE();
211 #endif 291 #endif
292 CYGARC_HAL_RESTORE_GP();
212 } 293 }
213 294
214 #endif 295 #endif
215 296
216 #if defined(CYGSEM_HAL_VIRTUAL_VECTOR_DIAG) 297 #if defined(CYGSEM_HAL_VIRTUAL_VECTOR_DIAG)
220 // 301 //
221 // The platform HAL must specify the channel used, and provide raw IO 302 // The platform HAL must specify the channel used, and provide raw IO
222 // routines for that channel. The platform HAL also has the necessary 303 // routines for that channel. The platform HAL also has the necessary
223 // information to determine if the channel is already initialized by 304 // information to determine if the channel is already initialized by
224 // a debug agent (either builtin or in ROM). 305 // a debug agent (either builtin or in ROM).
225 void 306 void
226 hal_if_diag_init(void) 307 hal_if_diag_init(void)
227 { 308 {
228 #ifndef CYGSEM_HAL_VIRTUAL_VECTOR_DIAG 309 #ifdef CYGPRI_HAL_IMPLEMENTS_IF_SERVICES
229 cyg_hal_plf_comms_init(); 310 cyg_hal_plf_comms_init();
230 #endif 311 #endif
231 312
232 // Set console channel. This should only be done when the console channel 313 // Set console channel. This should only be done when the console channel
233 // differs from the debug channel to prevent removing the debug agent's 314 // differs from the debug channel to prevent removing the debug agent's
247 CYGACC_COMM_IF_PUTC(*__chan)(CYGACC_COMM_IF_CH_DATA(*__chan), c); 328 CYGACC_COMM_IF_PUTC(*__chan)(CYGACC_COMM_IF_CH_DATA(*__chan), c);
248 else { 329 else {
249 __chan = CYGACC_CALL_IF_DEBUG_PROCS(); 330 __chan = CYGACC_CALL_IF_DEBUG_PROCS();
250 CYGACC_COMM_IF_PUTC(*__chan)(CYGACC_COMM_IF_CH_DATA(*__chan), c); 331 CYGACC_COMM_IF_PUTC(*__chan)(CYGACC_COMM_IF_CH_DATA(*__chan), c);
251 } 332 }
333
334 // Check interrupt flag
335 if (CYGACC_CALL_IF_CONSOLE_INTERRUPT_FLAG()) {
336 cyg_hal_user_break(0);
337 CYGACC_CALL_IF_CONSOLE_INTERRUPT_FLAG_SET(0);
338 }
252 } 339 }
253 340
254 void 341 void
255 hal_if_diag_read_char(char *c) 342 hal_if_diag_read_char(char *c)
256 { 343 {
262 __chan = CYGACC_CALL_IF_DEBUG_PROCS(); 349 __chan = CYGACC_CALL_IF_DEBUG_PROCS();
263 *c = CYGACC_COMM_IF_GETC(*__chan)(CYGACC_COMM_IF_CH_DATA(*__chan)); 350 *c = CYGACC_COMM_IF_GETC(*__chan)(CYGACC_COMM_IF_CH_DATA(*__chan));
264 } 351 }
265 } 352 }
266 #endif // CYGSEM_HAL_VIRTUAL_VECTOR_DIAG 353 #endif // CYGSEM_HAL_VIRTUAL_VECTOR_DIAG
354
355 //=============================================================================
356 // CtrlC support
357 //=============================================================================
358
359 #if defined(CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT) \
360 || defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT)
361
362 struct Hal_SavedRegisters *hal_saved_interrupt_state;
363
364 void
365 hal_ctrlc_isr_init(void)
366 {
367 hal_virtual_comm_table_t* __chan = CYGACC_CALL_IF_DEBUG_PROCS();
368
369 #if 1 // Prevents crash on older stubs
370 if (CYGNUM_CALL_IF_TABLE_VERSION != CYGACC_CALL_IF_VERSION())
371 return;
372 #endif
373
374 CYGACC_COMM_IF_CONTROL(*__chan)(CYGACC_COMM_IF_CH_DATA(*__chan),
375 __COMMCTL_IRQ_ENABLE);
376 }
377
378 cyg_uint32
379 hal_ctrlc_isr(CYG_ADDRWORD vector, CYG_ADDRWORD data)
380 {
381 hal_virtual_comm_table_t* __chan = CYGACC_CALL_IF_DEBUG_PROCS();
382 int isr_ret, ctrlc = 0;
383
384 isr_ret = CYGACC_COMM_IF_DBG_ISR(*__chan)(CYGACC_COMM_IF_CH_DATA(*__chan),
385 &ctrlc, vector, data);
386 if (ctrlc)
387 cyg_hal_user_break( (CYG_ADDRWORD *)hal_saved_interrupt_state );
388 return isr_ret;
389 }
390 #endif // CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT || CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT
267 391
268 //-------------------------------------------------------------------------- 392 //--------------------------------------------------------------------------
269 // Init function. It should be called from the platform initialization code. 393 // Init function. It should be called from the platform initialization code.
270 // For monitor configurations it will initialize the calling interface table, 394 // For monitor configurations it will initialize the calling interface table,
271 // for client configurations it will patch the existing table as per 395 // for client configurations it will patch the existing table as per
296 // ICTRL and EXC tables - I assume these to be the equivalents of 420 // ICTRL and EXC tables - I assume these to be the equivalents of
297 // ISR and VSR tables. 421 // ISR and VSR tables.
298 CYGACC_CALL_IF_ICTRL_TABLE_SET(hal_interrupt_handlers); 422 CYGACC_CALL_IF_ICTRL_TABLE_SET(hal_interrupt_handlers);
299 CYGACC_CALL_IF_EXC_TABLE_SET(hal_vsr_table); 423 CYGACC_CALL_IF_EXC_TABLE_SET(hal_vsr_table);
300 424
301 // Reset and kill vector 425 // Miscellaneous services with wrappers in this file.
302 CYGACC_CALL_IF_RESET_SET(reset); 426 CYGACC_CALL_IF_RESET_SET(reset);
303 CYGACC_CALL_IF_KILL_VECTOR_SET(kill_by_reset); 427 CYGACC_CALL_IF_KILL_VECTOR_SET(kill_by_reset);
428 CYGACC_CALL_IF_DELAY_US_SET(delay_us);
304 429
305 // Comm controls 430 // Comm controls
306 CYGACC_CALL_IF_SET_DEBUG_COMM_SET(set_debug_comm); 431 CYGACC_CALL_IF_SET_DEBUG_COMM_SET(set_debug_comm);
307 CYGACC_CALL_IF_SET_CONSOLE_COMM_SET(set_console_comm); 432 CYGACC_CALL_IF_SET_CONSOLE_COMM_SET(set_console_comm);
308 433
309 // Cache functions 434 // Cache functions
310 CYGACC_CALL_IF_FLUSH_ICACHE_SET(flush_icache); 435 CYGACC_CALL_IF_FLUSH_ICACHE_SET(flush_icache);
311 CYGACC_CALL_IF_FLUSH_DCACHE_SET(flush_dcache); 436 CYGACC_CALL_IF_FLUSH_DCACHE_SET(flush_dcache);
312 437
313 // Clear console procs entry. If platform has been configured 438 // Clear debug and console procs entries. If platform has been
314 // to use a separate console port, it will be set up later 439 // configured to use a separate console port, it will be set
315 // (hal_diag_init). Alternatively (if this is a stub) it will 440 // up later (hal_diag_init). Alternatively (if this is a stub)
316 // be initialized with the output mangler (O-packetizer for 441 // it will be initialized with the output mangler
317 // GDB) which uses the debug comms. 442 // (O-packetizer for GDB) which uses the debug comms.
443 set_debug_comm(CYGNUM_CALL_IF_SET_COMM_ID_EMPTY);
318 set_console_comm(CYGNUM_CALL_IF_SET_COMM_ID_EMPTY); 444 set_console_comm(CYGNUM_CALL_IF_SET_COMM_ID_EMPTY);
319 445
320 // Data entries not currently supported in eCos 446 // Data entries not currently supported in eCos
321 CYGACC_CALL_IF_CPU_DATA_SET(0); 447 CYGACC_CALL_IF_CPU_DATA_SET(0);
322 CYGACC_CALL_IF_BOARD_DATA_SET(0); 448 CYGACC_CALL_IF_BOARD_DATA_SET(0);
323 CYGACC_CALL_IF_DBG_DATA_SET(0); 449 CYGACC_CALL_IF_DBG_DATA_SET(0);
324 } 450 }
325 #endif 451 #endif
452
453 // Reset console interrupt flag.
454 CYGACC_CALL_IF_CONSOLE_INTERRUPT_FLAG_SET(0);
326 455
327 // Set up services provided by clients 456 // Set up services provided by clients
328 #if defined(CYGFUN_HAL_COMMON_KERNEL_SUPPORT) && \ 457 #if defined(CYGFUN_HAL_COMMON_KERNEL_SUPPORT) && \
329 ( defined(CYGSEM_HAL_USE_ROM_MONITOR_GDB_stubs) \ 458 ( defined(CYGSEM_HAL_USE_ROM_MONITOR_GDB_stubs) \
330 || defined(CYGSEM_HAL_USE_ROM_MONITOR_CygMon)) 459 || defined(CYGSEM_HAL_USE_ROM_MONITOR_CygMon))