Changes for 4.5.0 snapshot
[newlib-cygwin.git] / libgloss / or1k / include / or1k-support.h
blobc29b064bed654912aa82bf77958cd1c78619c9ea
1 /* Copyright (c) 2014 Authors
3 * Contributor Julius Baxter <julius.baxter@orsoc.se>
4 * Contributor Stefan Wallentowitz <stefan.wallentowitz@tum.de>
6 * The authors hereby grant permission to use, copy, modify, distribute,
7 * and license this software and its documentation for any purpose, provided
8 * that existing copyright notices are retained in all copies and that this
9 * notice is included verbatim in any distributions. No written agreement,
10 * license, or royalty fee is required for any of the authorized uses.
11 * Modifications to this software may be copyrighted by their authors
12 * and need not follow the licensing terms described here, provided that
13 * the new terms are clearly indicated on the first page of each file where
14 * they apply.
17 /* -------------------------------------------------------------------------- */
18 /* This program is commented throughout in a fashion suitable for processing
19 with Doxygen. */
20 /* -------------------------------------------------------------------------- */
22 #include <stdint.h>
24 #ifndef __OR1K_SUPPORT_H__
25 #define __OR1K_SUPPORT_H__
27 /*!
28 * \defgroup or1k_macros OR1K macros
29 * @{
32 /*!
33 * Access byte-sized memory mapped register
35 * Used to access a byte-sized memory mapped register. It avoids usage errors
36 * when not defining register addresses volatile and handles casting correctly.
38 * Example for both read and write:
40 * \code
41 * uint8_t status = REG8(IPBLOCK_STATUS_REG_ADDR);
42 * REG8(IPBLOCK_ENABLE) = 1;
43 * \endcode
45 * \param add Register address
47 #define REG8(add) *((volatile unsigned char *) (add))
49 /*!
50 * Access halfword-sized memory mapped register
52 * Used to access a 16 byte-sized memory mapped register. It avoids usage errors
53 * when not defining register addresses volatile and handles casting correctly.
55 * See REG8() for an example.
57 * \param add Register address
59 #define REG16(add) *((volatile unsigned short *) (add))
61 /*!
62 * Access word-sized memory mapped register
64 * Used to access a word-sized memory mapped register. It avoids usage errors
65 * when not defining register addresses volatile and handles casting correctly.
67 * See REG8() for an example.
69 * \param add Register address
71 #define REG32(add) *((volatile unsigned long *) (add))
72 /*!
73 * @}
76 /*!
77 * \defgroup or1k_interrupts OR1K interrupt control
79 * Interrupt control function prototypes
81 * @{
84 /*! Function pointer to interrupt handler functions */
85 typedef void (*or1k_interrupt_handler_fptr)(void* data);
87 /*!
88 * Add interrupt handler for interrupt line
90 * Registers a callback function for a certain interrupt line.
92 * \param line Interrupt line/id to register a handler for
93 * \param handler Handler to register
94 * \param data Data value passed to the handler
96 void or1k_interrupt_handler_add(uint32_t line,
97 or1k_interrupt_handler_fptr handler,
98 void* data);
101 * Enable interrupts from a given line
103 * Unmask the given interrupt line. It is also important to enable interrupts
104 * in general, e.g., using or1k_interrupts_enable().
106 * \param line Interrupt line to enable
108 void or1k_interrupt_enable(int line);
111 * Disable interrupts from a given line
113 * Mask given interrupt line. It can be unmasked using or1k_interrupt_enable().
115 * \param line Interrupt line to disable
117 void or1k_interrupt_disable(int line);
120 * Disable interrupts
122 * This disables the interrupt exception. This is sufficient to disable all
123 * interrupts. It does not change the mask register (which is modified using
124 * or1k_interrupt_enable() and or1k_interrupt_disable()).
126 * The interrupt exception can be enabled using or1k_interrupts_enable().
128 * Finally, the status of the interrupt exception enable flag is returned by
129 * this function. That allows to call this function even if interrupts are
130 * already disabled. To restore the value of the interrupt exception enable
131 * flag, use the or1k_interrupts_restore() function. That way you avoid to
132 * accidentally enable interrupts. Example:
134 * \code
135 * void f() {
136 * uint32_t interrupt_status = or1k_interrupts_disable();
137 * // do something
138 * or1k_interrupts_restore(status);
140 * \endcode
142 * This code will preserve the original status of the interrupt enable flag.
144 * \return Interrupt exception enable flag before call
146 uint32_t or1k_interrupts_disable(void);
149 * Enable interrupt exception
151 * Enable the interrupt exception. Beside the interrupt exception, it is also
152 * necessary to enable the individual interrupt lines using
153 * or1k_interrupt_enable().
155 * You should avoid using this function together with or1k_interrupts_disable()
156 * to guard atomic blocks as it unconditionally enables the interrupt
157 * exception (see documentation of or1k_interrupts_disable()).
159 void or1k_interrupts_enable(void);
162 * Restore interrupt exception enable flag
164 * This function restores the given status to the processor.
165 * or1k_interrupts_restore(0) is identical to or1k_interrupts_disable() and
166 * or1k_interrupts_restore(SPR_SR_IEE) is identical to or1k_interrupts_enable().
168 * It is for example used to guard an atomic block and restore the original
169 * status of the interrupt exception enable flag as returned by
170 * or1k_interrupts_disable(). See the documentation of or1k_interrupts_disable()
171 * for a usage example.
173 * \param status Status of the flag to restore
175 void or1k_interrupts_restore(uint32_t status);
178 * Disable timer and interrupt exception
180 * This function disables the timer and interrupt exception to guard critical
181 * sections. It returns the status of the enable bits before the critical
182 * section, that is restored with or1k_critical_end().
184 * Example:
185 * \code
186 * ...
187 * uint32_t status = or1k_critical_start();
188 * // critical part
189 * or1k_critical_end(status);
190 * ...
191 * \endcode
193 * \return Status of timer and interrupt exception at time of call
195 uint32_t or1k_critical_begin();
198 * Enable timer and interrupt exception
200 * Restore the timer and interrupt exception enable. The restore value is the
201 * return value from or1k_critical_start().
203 * \param restore Interrupt and timer exception enable restore value
205 void or1k_critical_end(uint32_t restore);
207 * @}
211 * \defgroup or1k_exception Exception handling
212 * @{
214 /*! Function pointer to an exception handler function */
215 typedef void (*or1k_exception_handler_fptr)(void);
218 * Register exception handler
220 * Register an exception handler for the given exception id. This handler is
221 * in the following then called when the exception occurs. You can thereby
222 * individually handle those exceptions.
224 * \param id Exception id
225 * \param handler Handler callback
227 void or1k_exception_handler_add(int id, or1k_exception_handler_fptr handler);
229 * @}
233 * \defgroup or1k_spr SPR access
234 * @{
238 * Move value to special purpose register
240 * Move data value to a special purpose register
242 * \param spr SPR identifier, see spr-defs.h for macros
243 * \param value value to move to SPR
245 static inline void or1k_mtspr (uint32_t spr, uint32_t value)
247 __asm__ __volatile__ ("l.mtspr\t\t%0,%1,0": : "r" (spr), "r" (value));
251 * Copy value from special purpose register
253 * Copy a data value from the given special purpose register.
255 * \param spr SPR identifier, see spr-defs.h for macros
256 * \return SPR data value
258 static inline uint32_t or1k_mfspr (uint32_t spr) {
259 uint32_t value;
260 __asm__ __volatile__ ("l.mfspr\t\t%0,%1,0" : "=r" (value) : "r" (spr));
261 return value;
264 * @}
268 * \defgroup or1k_util Miscellaneous utility functions
270 * @{
274 * Report value to simulator
276 * Uses the built-in simulator functionality.
278 * \param value Value to report
280 void or1k_report (unsigned long int value);
283 * Get (pseudo) random number
285 * This should return pseudo-random numbers, based on a Galois LFSR.
287 * \return (Pseudo) Random number
289 unsigned long int or1k_rand(void);
292 * Register UART callback
294 * This function sets a callback function that is called when a character is
295 * received via UART. The callback function has no return and a gets the
296 * character as parameter. When a character is received, the function is called.
298 * Example (UART echo):
299 * \code
300 * void uart_in(char c) {
301 * printf("%c", c); // Echo
304 * int main() {
305 * or1k_uart_set_read_cb(&uart_in);
306 * or1k_interrupts_enable();
308 * while (1) {}
310 * \endcode
312 void or1k_uart_set_read_cb(void (*cb)(char c));
314 * @}
318 * \defgroup or1k_cache Cache control
320 * @{
324 * Enable instruction cache
326 void or1k_icache_enable(void);
329 * Disable instruction cache
331 void or1k_icache_disable(void);
334 * Flush instruction cache
336 * Invalidate instruction cache entry
338 * \param entry Entry to invalidate
340 void or1k_icache_flush(uint32_t entry);
343 * Enable data cache
345 void or1k_dcache_enable(void);
348 * Disable data cache
350 void or1k_dcache_disable(void);
353 * Flush data cache
355 * Invalidate data cache entry
357 * \param entry Entry to invalidate
359 void or1k_dcache_flush(unsigned long entry);
361 * @}
365 * \defgroup or1k_mmu MMU control
366 * @{
370 * Enable instruction MMU
372 void or1k_immu_enable(void);
375 * Disable instruction MMU
377 void or1k_immu_disable(void);
380 * Enable data MMU
382 void or1k_dmmu_enable(void);
385 * Disable data MMU
387 void or1k_dmmu_disable(void);
389 * @}
393 * \defgroup or1k_timer Timer control
395 * The tick timer can be used for time measurement, operating system scheduling
396 * etc. By default it is initialized to continuously count the ticks of a
397 * certain period after calling or1k_timer_init(). The period can later be
398 * changed using or1k_timer_set_period().
400 * The timer is controlled using or1k_timer_enable(), or1k_timer_disable(),
401 * or1k_timer_restore(), or1k_timer_pause(). After initialization it is required
402 * to enable the timer the first time using or1k_timer_enable().
403 * or1k_timer_disable() only disables the tick timer interrupts, it does not
404 * disable the timer counting. If you plan to use a pair of or1k_timer_disable()
405 * and or1k_timer_enable() to protect sections of your code against interrupts
406 * you should use or1k_timer_disable() and or1k_timer_restore(), as it may be
407 * possible that the timer interrupt was not enabled before disabling it,
408 * enable would then start it unconditionally. or1k_timer_pause() pauses the
409 * counting.
411 * In the default mode you can get the tick value using or1k_timer_get_ticks()
412 * and reset this value using or1k_timer_reset_ticks().
414 * Example for using the default mode:
416 * \code
417 * int main() {
418 * uint32_t ticks = 0;
419 * uint32_t timerstate;
420 * or1k_timer_init(100);
421 * or1k_timer_enable();
422 * while (1) {
423 * while (ticks == or1k_timer_get_ticks()) { }
424 * timerstate = or1k_timer_disable();
425 * // do something atomar
426 * or1k_timer_restore(timerstate);
427 * if (ticks == 100) {
428 * printf("A second elapsed\n");
429 * or1k_timer_reset_ticks();
430 * ticks = 0;
434 * \endcode
436 * It is possible to change the mode of the tick timer using
437 * or1k_timer_set_mode(). Allowed values are the correct bit pattern (including
438 * the bit positions) for the TTMR register, it is recommended to use the macros
439 * defined in spr-defs.h. For example, implementing an operating system with
440 * scheduling decisions of varying duration favors the implementation of single
441 * run tick timer. Here, each quantum is started before leaving the operating
442 * system kernel. The counter can be restarted with or1k_timer_reset().
443 * Example:
445 * \code
446 * void tick_handler(void) {
447 * // Make schedule decision
448 * // and set new thread
449 * or1k_timer_reset();
450 * // End of exception, new thread will run
453 * int main() {
454 * // Configure operating system and start threads..
456 * // Configure timer
457 * or1k_timer_init(50);
458 * or1k_timer_set_handler(&tick_handler);
459 * or1k_timer_set_mode(SPR_TTMR_SR);
460 * or1k_timer_enable();
462 * // Schedule first thread and die..
464 * \endcode
466 * @{
470 * Initialize tick timer
472 * This initializes the tick timer in default mode (see \ref or1k_timer for
473 * details).
475 * \param hz Initial period of the tick timer
476 * \return 0 if successful, -1 if timer not present
478 int or1k_timer_init(unsigned int hz);
481 * Set period of timer
483 * Set the period of the timer to a value in Hz. The frequency from the board
484 * support package is used to determine the match value.
486 void or1k_timer_set_period(uint32_t hz);
489 * Replace the timer interrupt handler
491 * By default the tick timer is used to handle timer ticks. The user can replace
492 * this with an own handler for example when implementing an operating system.
494 * \param handler The callback function pointer to the handler
496 void or1k_timer_set_handler(void (*handler)(void));
499 * Set timer mode
501 * The timer has different modes (see architecture manual). The default is to
502 * automatically restart counting (SPR_TTMR_RT), others are single run
503 * (SPR_TTMR_SR) and continuous run (SPR_TTMR_CR).
505 * \param mode a valid mode (use definitions from spr-defs.h as it is important
506 * that those are also at the correct position in the bit field!)
508 void or1k_timer_set_mode(uint32_t mode);
511 * Enable timer interrupt
513 * Enable the timer interrupt exception, independent of the status before.
514 * If you want to enable the timer conditionally, for example to implement a
515 * non-interruptible sequence of code, you should use or1k_timer_restore(). See
516 * the description of or1k_timer_disable() for more details.
518 * The enable will also restore the mode if the timer was paused previously.
520 void or1k_timer_enable(void);
523 * Disable timer interrupt
525 * This disables the timer interrupt exception and returns the state of the
526 * interrupt exception enable flag before the call. This can be used with
527 * or1k_timer_restore() to implement sequences of code that are not allowed to
528 * be interrupted. Using or1k_timer_enable() will unconditionally enable the
529 * interrupt independent of the state before calling or1k_timer_disable().
530 * For an example see \ref or1k_timer.
532 * \return Status of timer interrupt before call
534 uint32_t or1k_timer_disable(void);
537 * Restore timer interrupt exception flag
539 * Restores the timer interrupt exception flag as returned by
540 * or1k_timer_disable(). See the description of or1k_timer_disable() and \ref
541 * or1k_timer for details and an example.
543 * \param sr_tee Status of timer interrupt
545 void or1k_timer_restore(uint32_t sr_tee);
548 * Pause timer counter
550 * Pauses the counter of the tick timer. The counter will hold its current value
551 * and it can be started again with or1k_timer_enable() which will restore the
552 * configured mode.
554 void or1k_timer_pause(void);
557 * Reset timer counter
559 void or1k_timer_reset(void);
562 * Get timer ticks
564 * Get the global ticks of the default configuration. This will increment the
565 * tick counter according to the preconfigured period.
567 * \return Current value of ticks
569 unsigned long or1k_timer_get_ticks(void);
572 * Reset timer ticks
574 * Resets the timer ticks in default configuration to 0.
576 void or1k_timer_reset_ticks(void);
578 * @}
582 * \defgroup or1k_multicore Multicore and Synchronization Support
584 * @{
588 * Compiled with multicore support
590 * \return 1 if compiled with multicore support, 0 otherwise
592 uint32_t or1k_has_multicore_support(void);
595 * Read core identifier
597 * \return Core identifier
599 uint32_t or1k_coreid(void);
602 * Read number of cores
604 * \return Total number of cores
606 uint32_t or1k_numcores(void);
609 * Load linked
611 * Load a value from the given address and link it. If the following
612 * or1k_sync_sc() goes to the same address and there was no conflicting access
613 * between loading and storing, the value is written back, else the write fails.
615 * \param address Address to load value from
616 * \return Value read from the address
618 uint32_t or1k_sync_ll(void *address);
621 * Store conditional
623 * Conditionally store a value to the address. The address must have been read
624 * before using or1k_sync_ll() and there must be no other load link after that,
625 * otherwise this will always fail. In case there was no other write to the same
626 * address in between the load link and the store conditional, the store is
627 * successful, otherwise it will also fail.
629 * \param address Address to conditionally store to
630 * \param value Value to write to address
631 * \return 1 if success, 0 if fail
633 int or1k_sync_sc(void *address, uint32_t value);
636 * Compare and Swap
638 * Loads a data item from the memory and compares a given value to it. If the
639 * values match, a new value is written to the memory, if they mismatch, the
640 * operation is aborted. The whole operation is atomic, i.e., it is guaranteed
641 * that no other core changes the value between the read and the write.
643 * \param address Address to operate on
644 * \param compare Compare value
645 * \param swap New value to write
646 * \return The value read from memory (can be used to check for success)
648 uint32_t or1k_sync_cas(void *address, uint32_t compare, uint32_t swap);
651 * Test and Set Lock
653 * Check for a lock on an address. This means, if there is 0 at an address it
654 * will overwrite it with 1 and return 0. If the lock was already set (value
655 * 1 read from address), the function returns 1. The operation is atomic.
657 * \param address Address of the lock
658 * \return 0 if success, 1 if failed
660 int or1k_sync_tsl(void *address);
662 * @}
665 #endif /* __NEWLIB_OR1K_SUPPORT_H__ */