Newlib
From OR1K
Contents |
Introduction
The OpenRISC 1000 port of the newlib library aims to provide a library to provide support for running on bare-metal hardware without an operating system. It is also used when running the GNU toolchain regression suite.
The library is automatically linked when using the newlib version of the GCC compiler (or32-elf-gcc). The target board is specified by -mboardname. If not board is specified, the default (-mor1ksim) is suitable for use with Or1ksim.
Port acknowledgements
This original port was for newlib 1.13.0 by Jacob Bower, then of Imperial College, London.
The port was completely rewritten and tested for newlib 1.18.0 by Jeremy Bennett of Embecosm. Further information is availble in Embecosm Application Note 9 Howto: Porting Newlib: A Simple Guide, which explains in full detail how the port for the OpenRISC 1000 architecture was done.
The port was subsequently extended by Julius Baxter to make support of multiple boards much more flexible.
OpenRISC support library
To assist with using features of the OpenRISC processor such as exceptions, interrupts and timers, a support library has been implemented.
This library also provides support for particular boards in ORPSoC.
Support library functions
These functions are implemented in the or1k-support.c and or1k-support-asm.S files in the newlib/libc/machine/or32 path in the newlib port directory. The header, or1k-newlib-support.h is found in the newlib/libc/machine/or32/include path. Note that this header and the OR1K spr-defs.h header are installed also in the /install_path/or32-elf/include path.
They are accessible via the inclusion of the following header.
#include <or1k-support.h>
The following functions are provided
| Function Name | Arguments | Description | Return value |
or1k_interrupt_handler_add
|
int irq, void(*function_name)(void*)
|
Install function_name as handler for interrupt at IRQ irq
|
none |
or1k_interrupt_enable
|
int irq
|
Enable generation interrupt at IRQ irq in PICMR | none |
or1k_interrupt_disable
|
int irq
|
Disable generation of interrupt at IRQ irq in PICMR | none |
or1k_exception_handler_add
|
int vector, void(*function_name)(void*)
|
Install function_name as handler for vector at address (vector*0x100) | none |
or1k_mtspr
|
unsigned long int spr, unsigned long int value
|
Write SPR[spr] = value | none |
or1k_mfspr
|
unsigned long int spr
|
Read SPR[spr] | SPR[spr] |
or1k_report
|
unsigned long int value
|
Simulator report function with l.nop 0x2 | none |
or1k_icache_enable
|
void
|
Enable instruction cache in SR | none |
or1k_icache_disable
|
void
|
Disable instruction cache in SR | none |
or1k_icache_flush
|
unsigned long addr
|
Flush addr from instruction cache | none |
or1k_dcache_enable
|
void
|
Enable data cache in SR | none |
or1k_dcache_disable
|
void
|
Disable data cache in SR | none |
or1k_dcache_flush
|
unsigned long addr
|
Flush addr from data cache | none |
or1k_immu_enable
|
void
|
Enable instruction MMU in SR | none |
or1k_immu_disable
|
void
|
Disable instruction MMU in SR | none |
or1k_dmmu_enable
|
void
|
Enable data MMU in SR | none |
or1k_dmmu_disable
|
void
|
Disable data MMU in SR | none |
or1k_timer_init
|
unsigned int hz
|
Initialise timer to count at hz hertz, reset tick counter, install handler | none |
or1k_timer_enable
|
void
|
Start timer, enable timer interrupt in SR | none |
or1k_timer_disable
|
void
|
Stop timer interrupts | none |
or1k_timer_get_ticks
|
void
|
Read tick counter value | tick counter |
or1k_timer_reset_ticks
|
void
|
Reset tick counter value | none |
Contributions are welcome to help fix and improve this support library.
Feel free to post any suggestions or offers to assist the project to the OpenRISC forum or the mailing lists.
TODO
Functions still missing: interrupt acknowledge/clear function to clear bit in PICSR, cache region flush, MMU map function.
Board support details
The OpenRISC portion of libgloss provides a simple way of adding support for boards by way of linking in a small library containing some values used at run-time to configure the system. Each board has its own path and libboard.a in the /install_path/or32-elf/lib/boards/boardname directory. The boardname above should correspond to a directory under this path.
Libgloss also implements system calls, and at present only read and write system calls are supported via the UART.
In the version currently in the repository, a handful of boards and the or1ksim architectural simulator are supported.
| Board | Description |
| or1ksim | or1ksim simulator, no peripherals |
| or1ksim-uart | or1ksim simulator with a UART |
| ordb1a3pe1500 | ORSoC dedvelopment board 1, A3PE1500 part, as in ORPSoC |
| ml501 | Xilinx ML501 board, as in ORPSoC |
| orpsocrefdesign | ORPSoC reference design |
For example, to compile with support for the ordb1a3pe1500 board, one would pass the following options at compile-time.
or32-elf-gcc -mboard=ordb1a3pe1500
Each libboard.a defines the following symbols:
| Symbol | Description |
| _board_mem_base | Base of main memory |
| _board_mem_size | Size of main memory |
| _board_clk_freq | Frequency in hertz of CPU clock, also presumed as UART clock |
| _board_uart_base | Base address of a UART 16550 peripheral |
| _board_uart_baud | Desired buad rate for UART |
| _board_uart_IRQ | IRQ number of UART |
Adding support for a new board
Adding additional boards (without recompiling and installing the toolchain) is as simple as creating a creating a libboard.a with the appropriate symbols set to the right values and placing it in the /install_path/or32-elf/lib/boards/boardname directory. The boardname should be the same as the one used when passing the -mboard=boardname to the compiler.
To create this libboard.a see examples of the existing boardname.S files in the newlib-1.x.0/libgloss/or32 path in the newlib port source.
For example, the ml501 board's code is in the newlib-1.x.0/libgloss/or32/ml501.S file and is as follows:
/* * Define symbols to be used during startup - file is linked at compile time * */ .global _board_mem_base .global _board_mem_size .global _board_clk_freq _board_mem_base: .long 0x0 _board_mem_size: .long 0x800000 _board_clk_freq: .long 66666666 /* Peripheral information - Set base to 0 if not present*/ .global _board_uart_base .global _board_uart_baud .global _board_uart_IRQ _board_uart_base: .long 0x90000000 _board_uart_baud: .long 115200 _board_uart_IRQ: .long 2
This file should be assembled and archived, and then placed into the correct install path as mentioned above.


