From b07f41fe319d72215b244355fa7b8dc955e151bd Mon Sep 17 00:00:00 2001 From: Jiaxun Yang Date: Fri, 27 Dec 2024 15:47:33 +0000 Subject: [PATCH] openrisc: Initial OpenRISC 1000 support This target is in GCC/binutils/Linux/Glibc/musl for a while. Baremetal/glibc/musl toolchains are all build tested. Signed-off-by: Jiaxun Yang --- config/arch/openrisc.in | 13 ++ .../0003-or1k-fix-compiler-warnings.patch | 150 ++++++++++++++++++ .../0000-or1k-fix-compiler-warnings.patch | 150 ++++++++++++++++++ samples/or1k-unknown-elf/crosstool.config | 6 + samples/or1k-unknown-elf/reported.by | 3 + .../or1k-unknown-linux-gnu/crosstool.config | 9 ++ samples/or1k-unknown-linux-gnu/reported.by | 3 + .../or1k-unknown-linux-musl/crosstool.config | 10 ++ samples/or1k-unknown-linux-musl/reported.by | 3 + scripts/build/arch/openrisc.sh | 6 + 10 files changed, 353 insertions(+) create mode 100644 config/arch/openrisc.in create mode 100644 packages/newlib/4.3.0.20230120/0003-or1k-fix-compiler-warnings.patch create mode 100644 packages/newlib/4.4.0.20231231/0000-or1k-fix-compiler-warnings.patch create mode 100644 samples/or1k-unknown-elf/crosstool.config create mode 100644 samples/or1k-unknown-elf/reported.by create mode 100644 samples/or1k-unknown-linux-gnu/crosstool.config create mode 100644 samples/or1k-unknown-linux-gnu/reported.by create mode 100644 samples/or1k-unknown-linux-musl/crosstool.config create mode 100644 samples/or1k-unknown-linux-musl/reported.by create mode 100644 scripts/build/arch/openrisc.sh diff --git a/config/arch/openrisc.in b/config/arch/openrisc.in new file mode 100644 index 00000000..d4623ed1 --- /dev/null +++ b/config/arch/openrisc.in @@ -0,0 +1,13 @@ +# OpenRISC specific configuration file + +## no-package +## select ARCH_SUPPORTS_32 +## select ARCH_DEFAULT_32 +## select ARCH_SUPPORTS_BOTH_MMU +## select ARCH_DEFAULT_BE +## select ARCH_SUPPORTS_WITH_ARCH +## select ARCH_SUPPORTS_FLAT_FORMAT +## depends on EXPERIMENTAL +## +## help The OpenRISC architecture +## help https://openrisc.io/ diff --git a/packages/newlib/4.3.0.20230120/0003-or1k-fix-compiler-warnings.patch b/packages/newlib/4.3.0.20230120/0003-or1k-fix-compiler-warnings.patch new file mode 100644 index 00000000..e0fb8dce --- /dev/null +++ b/packages/newlib/4.3.0.20230120/0003-or1k-fix-compiler-warnings.patch @@ -0,0 +1,150 @@ +From 8e53c587597a33fec5f41a540a9b1b20d53fb439 Mon Sep 17 00:00:00 2001 +From: Stafford Horne +Date: Thu, 12 Dec 2024 16:23:03 +0000 +Subject: [PATCH] or1k: Fix compiler warnings +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +In my build the below are treated as error now and causing failures. I +have described the fixes of each warning below. + +In newlib/libc/sys/or1k/mlock.c: + + CC libc/sys/or1k/libc_a-mlock.o + newlib/libc/sys/or1k/mlock.c: In function ‘__malloc_lock’: + newlib/libc/sys/or1k/mlock.c:56:19: warning: implicit declaration of function ‘or1k_critical_begin’ [-Wimplicit-function-declaration] + 56 | restore = or1k_critical_begin(); + | ^~~~~~~~~~~~~~~~~~~ + newlib/libc/sys/or1k/mlock.c: In function ‘__malloc_unlock’: + newlib/libc/sys/or1k/mlock.c:93:17: warning: implicit declaration of function ‘or1k_critical_end’ [-Wimplicit-function-declaration] + 93 | or1k_critical_end(restore); + | ^~~~~~~~~~~~~~~~~ + +This patch adds prototypes for functions or1k_critical_begin and +or1k_critical_end to suppress the warning, inline with what we do for +or1k_sync_cas. + +In libgloss/or1k/or1k_uart.c: + + libgloss/or1k/or1k_uart.c: In function ‘or1k_uart_set_read_cb’: + libgloss/or1k/or1k_uart.c:163:25: warning: passing argument 2 of ‘or1k_interrupt_handler_add’ from incompatible pointer type [-Wincompatible-pointer-types] + 163 | _or1k_uart_interrupt_handler, 0); + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~ + | | + | void (*)(uint32_t) {aka void (*)(long unsigned int)} + In file included from libgloss/or1k/or1k_uart.c:19: + libgloss/or1k/include/or1k-support.h:97:45: note: expected ‘or1k_interrupt_handler_fptr’ {aka ‘void (*)(void *)’} but argument is of type ‘void (*)(uint32_t)’ {aka ‘void (*)(long unsigned int)’} + 97 | or1k_interrupt_handler_fptr handler, + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~ + +The public API is ‘void (*)(void *)' for our interrupt handlers. The +function _or1k_uart_interrupt_hander is the internal default +implementation of the uart IRQ handler and it doesn't use the data +argument. + +This patch updates the _or1k_uart_interrupt_handler argument type from +uint32_t to void* allowing the function prototype to match the required +prototype. + +If we did have a 64-bit implementation it would be an ABI issue. But, +there never has been one, or1k is only 32-bit. + +In libgloss/or1k/interrupts.c: + + libgloss/or1k/interrupts.c: In function ‘or1k_interrupt_handler_add’: + libgloss/or1k/interrupts.c:41:52: warning: assignment to ‘void *’ from ‘long unsigned int’ makes pointer from integer without a cast [-Wint-conversion] + 41 | _or1k_interrupt_handler_data_ptr_table[id] = (uint32_t) data_ptr; + | ^ + +The table _or1k_interrupt_handler_data_ptr_table is an array of void* +and data_ptr is void*. There is no need for the cast so remove it. + +In libgloss/or1k/sbrk.c: + + libgloss/or1k/sbrk.c:23:29: warning: initialization of ‘uint32_t’ {aka ‘long unsigned int’} from ‘uint32_t *’ {aka ‘long unsigned int *’} makes integer from pointer without a cast [-Wint-conversion] + 23 | uint32_t _or1k_heap_start = &end; + | + +This patch adds a cast, which is safe in or1k as the architecture in +32-bit only. But this code would not be 64-compatible. + +Signed-off-by: Stafford Horne +--- + libgloss/or1k/interrupts.c | 4 ++-- + libgloss/or1k/or1k_uart.c | 2 +- + libgloss/or1k/or1k_uart.h | 2 +- + libgloss/or1k/sbrk.c | 2 +- + newlib/libc/sys/or1k/mlock.c | 3 +++ + 5 files changed, 8 insertions(+), 5 deletions(-) + +diff --git a/libgloss/or1k/interrupts.c b/libgloss/or1k/interrupts.c +index 6badc497c1..516d74be38 100644 +--- a/libgloss/or1k/interrupts.c ++++ b/libgloss/or1k/interrupts.c +@@ -35,10 +35,10 @@ void or1k_interrupt_handler_add(uint32_t id, + { + #ifdef __OR1K_MULTICORE__ + _or1k_interrupt_handler_table[or1k_coreid()][id] = handler; +- _or1k_interrupt_handler_data_ptr_table[or1k_coreid()][id] = (uint32_t) data_ptr; ++ _or1k_interrupt_handler_data_ptr_table[or1k_coreid()][id] = data_ptr; + #else + _or1k_interrupt_handler_table[id] = handler; +- _or1k_interrupt_handler_data_ptr_table[id] = (uint32_t) data_ptr; ++ _or1k_interrupt_handler_data_ptr_table[id] = data_ptr; + #endif + } + +diff --git a/libgloss/or1k/or1k_uart.c b/libgloss/or1k/or1k_uart.c +index 0a991e6baf..1391d565c6 100644 +--- a/libgloss/or1k/or1k_uart.c ++++ b/libgloss/or1k/or1k_uart.c +@@ -90,7 +90,7 @@ void (*_or1k_uart_read_cb)(char c); + * This is the interrupt handler that is registered for the callback + * function. + */ +-void _or1k_uart_interrupt_handler(uint32_t data) ++void _or1k_uart_interrupt_handler(void *data) + { + uint8_t iir = REG8(IIR); + +diff --git a/libgloss/or1k/or1k_uart.h b/libgloss/or1k/or1k_uart.h +index 4cbb68350d..201b7749f6 100644 +--- a/libgloss/or1k/or1k_uart.h ++++ b/libgloss/or1k/or1k_uart.h +@@ -30,7 +30,7 @@ extern void (*_or1k_uart_read_cb)(char c); + /** + * The UART interrupt handler + */ +-void _or1k_uart_interrupt_handler(uint32_t data); ++void _or1k_uart_interrupt_handler(void *data); + + /** + * Initialize UART +diff --git a/libgloss/or1k/sbrk.c b/libgloss/or1k/sbrk.c +index 0c3e66e876..ca196d2282 100644 +--- a/libgloss/or1k/sbrk.c ++++ b/libgloss/or1k/sbrk.c +@@ -20,7 +20,7 @@ + #include "include/or1k-support.h" + + extern uint32_t end; /* Set by linker. */ +-uint32_t _or1k_heap_start = &end; ++uint32_t _or1k_heap_start = (uint32_t) &end; + uint32_t _or1k_heap_end; + + void * +diff --git a/newlib/libc/sys/or1k/mlock.c b/newlib/libc/sys/or1k/mlock.c +index ccb8401611..a0c0383356 100644 +--- a/newlib/libc/sys/or1k/mlock.c ++++ b/newlib/libc/sys/or1k/mlock.c +@@ -38,6 +38,9 @@ volatile uint32_t _or1k_malloc_lock_restore; + + extern uint32_t or1k_sync_cas(void *address, uint32_t compare, uint32_t swap); + ++extern uint32_t or1k_critical_begin(); ++extern void or1k_critical_end(uint32_t restore); ++ + /** + * Recursive lock of the malloc + */ diff --git a/packages/newlib/4.4.0.20231231/0000-or1k-fix-compiler-warnings.patch b/packages/newlib/4.4.0.20231231/0000-or1k-fix-compiler-warnings.patch new file mode 100644 index 00000000..e0fb8dce --- /dev/null +++ b/packages/newlib/4.4.0.20231231/0000-or1k-fix-compiler-warnings.patch @@ -0,0 +1,150 @@ +From 8e53c587597a33fec5f41a540a9b1b20d53fb439 Mon Sep 17 00:00:00 2001 +From: Stafford Horne +Date: Thu, 12 Dec 2024 16:23:03 +0000 +Subject: [PATCH] or1k: Fix compiler warnings +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +In my build the below are treated as error now and causing failures. I +have described the fixes of each warning below. + +In newlib/libc/sys/or1k/mlock.c: + + CC libc/sys/or1k/libc_a-mlock.o + newlib/libc/sys/or1k/mlock.c: In function ‘__malloc_lock’: + newlib/libc/sys/or1k/mlock.c:56:19: warning: implicit declaration of function ‘or1k_critical_begin’ [-Wimplicit-function-declaration] + 56 | restore = or1k_critical_begin(); + | ^~~~~~~~~~~~~~~~~~~ + newlib/libc/sys/or1k/mlock.c: In function ‘__malloc_unlock’: + newlib/libc/sys/or1k/mlock.c:93:17: warning: implicit declaration of function ‘or1k_critical_end’ [-Wimplicit-function-declaration] + 93 | or1k_critical_end(restore); + | ^~~~~~~~~~~~~~~~~ + +This patch adds prototypes for functions or1k_critical_begin and +or1k_critical_end to suppress the warning, inline with what we do for +or1k_sync_cas. + +In libgloss/or1k/or1k_uart.c: + + libgloss/or1k/or1k_uart.c: In function ‘or1k_uart_set_read_cb’: + libgloss/or1k/or1k_uart.c:163:25: warning: passing argument 2 of ‘or1k_interrupt_handler_add’ from incompatible pointer type [-Wincompatible-pointer-types] + 163 | _or1k_uart_interrupt_handler, 0); + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~ + | | + | void (*)(uint32_t) {aka void (*)(long unsigned int)} + In file included from libgloss/or1k/or1k_uart.c:19: + libgloss/or1k/include/or1k-support.h:97:45: note: expected ‘or1k_interrupt_handler_fptr’ {aka ‘void (*)(void *)’} but argument is of type ‘void (*)(uint32_t)’ {aka ‘void (*)(long unsigned int)’} + 97 | or1k_interrupt_handler_fptr handler, + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~ + +The public API is ‘void (*)(void *)' for our interrupt handlers. The +function _or1k_uart_interrupt_hander is the internal default +implementation of the uart IRQ handler and it doesn't use the data +argument. + +This patch updates the _or1k_uart_interrupt_handler argument type from +uint32_t to void* allowing the function prototype to match the required +prototype. + +If we did have a 64-bit implementation it would be an ABI issue. But, +there never has been one, or1k is only 32-bit. + +In libgloss/or1k/interrupts.c: + + libgloss/or1k/interrupts.c: In function ‘or1k_interrupt_handler_add’: + libgloss/or1k/interrupts.c:41:52: warning: assignment to ‘void *’ from ‘long unsigned int’ makes pointer from integer without a cast [-Wint-conversion] + 41 | _or1k_interrupt_handler_data_ptr_table[id] = (uint32_t) data_ptr; + | ^ + +The table _or1k_interrupt_handler_data_ptr_table is an array of void* +and data_ptr is void*. There is no need for the cast so remove it. + +In libgloss/or1k/sbrk.c: + + libgloss/or1k/sbrk.c:23:29: warning: initialization of ‘uint32_t’ {aka ‘long unsigned int’} from ‘uint32_t *’ {aka ‘long unsigned int *’} makes integer from pointer without a cast [-Wint-conversion] + 23 | uint32_t _or1k_heap_start = &end; + | + +This patch adds a cast, which is safe in or1k as the architecture in +32-bit only. But this code would not be 64-compatible. + +Signed-off-by: Stafford Horne +--- + libgloss/or1k/interrupts.c | 4 ++-- + libgloss/or1k/or1k_uart.c | 2 +- + libgloss/or1k/or1k_uart.h | 2 +- + libgloss/or1k/sbrk.c | 2 +- + newlib/libc/sys/or1k/mlock.c | 3 +++ + 5 files changed, 8 insertions(+), 5 deletions(-) + +diff --git a/libgloss/or1k/interrupts.c b/libgloss/or1k/interrupts.c +index 6badc497c1..516d74be38 100644 +--- a/libgloss/or1k/interrupts.c ++++ b/libgloss/or1k/interrupts.c +@@ -35,10 +35,10 @@ void or1k_interrupt_handler_add(uint32_t id, + { + #ifdef __OR1K_MULTICORE__ + _or1k_interrupt_handler_table[or1k_coreid()][id] = handler; +- _or1k_interrupt_handler_data_ptr_table[or1k_coreid()][id] = (uint32_t) data_ptr; ++ _or1k_interrupt_handler_data_ptr_table[or1k_coreid()][id] = data_ptr; + #else + _or1k_interrupt_handler_table[id] = handler; +- _or1k_interrupt_handler_data_ptr_table[id] = (uint32_t) data_ptr; ++ _or1k_interrupt_handler_data_ptr_table[id] = data_ptr; + #endif + } + +diff --git a/libgloss/or1k/or1k_uart.c b/libgloss/or1k/or1k_uart.c +index 0a991e6baf..1391d565c6 100644 +--- a/libgloss/or1k/or1k_uart.c ++++ b/libgloss/or1k/or1k_uart.c +@@ -90,7 +90,7 @@ void (*_or1k_uart_read_cb)(char c); + * This is the interrupt handler that is registered for the callback + * function. + */ +-void _or1k_uart_interrupt_handler(uint32_t data) ++void _or1k_uart_interrupt_handler(void *data) + { + uint8_t iir = REG8(IIR); + +diff --git a/libgloss/or1k/or1k_uart.h b/libgloss/or1k/or1k_uart.h +index 4cbb68350d..201b7749f6 100644 +--- a/libgloss/or1k/or1k_uart.h ++++ b/libgloss/or1k/or1k_uart.h +@@ -30,7 +30,7 @@ extern void (*_or1k_uart_read_cb)(char c); + /** + * The UART interrupt handler + */ +-void _or1k_uart_interrupt_handler(uint32_t data); ++void _or1k_uart_interrupt_handler(void *data); + + /** + * Initialize UART +diff --git a/libgloss/or1k/sbrk.c b/libgloss/or1k/sbrk.c +index 0c3e66e876..ca196d2282 100644 +--- a/libgloss/or1k/sbrk.c ++++ b/libgloss/or1k/sbrk.c +@@ -20,7 +20,7 @@ + #include "include/or1k-support.h" + + extern uint32_t end; /* Set by linker. */ +-uint32_t _or1k_heap_start = &end; ++uint32_t _or1k_heap_start = (uint32_t) &end; + uint32_t _or1k_heap_end; + + void * +diff --git a/newlib/libc/sys/or1k/mlock.c b/newlib/libc/sys/or1k/mlock.c +index ccb8401611..a0c0383356 100644 +--- a/newlib/libc/sys/or1k/mlock.c ++++ b/newlib/libc/sys/or1k/mlock.c +@@ -38,6 +38,9 @@ volatile uint32_t _or1k_malloc_lock_restore; + + extern uint32_t or1k_sync_cas(void *address, uint32_t compare, uint32_t swap); + ++extern uint32_t or1k_critical_begin(); ++extern void or1k_critical_end(uint32_t restore); ++ + /** + * Recursive lock of the malloc + */ diff --git a/samples/or1k-unknown-elf/crosstool.config b/samples/or1k-unknown-elf/crosstool.config new file mode 100644 index 00000000..7a791d75 --- /dev/null +++ b/samples/or1k-unknown-elf/crosstool.config @@ -0,0 +1,6 @@ +CT_CONFIG_VERSION="4" +CT_EXPERIMENTAL=y +CT_ARCH_OPENRISC=y +CT_CC_LANG_CXX=y +CT_DEBUG_GDB=y +# CT_GDB_CROSS_PYTHON is not set diff --git a/samples/or1k-unknown-elf/reported.by b/samples/or1k-unknown-elf/reported.by new file mode 100644 index 00000000..858a3180 --- /dev/null +++ b/samples/or1k-unknown-elf/reported.by @@ -0,0 +1,3 @@ +reporter_name="Jiaxun Yang " +reporter_url="https://flygoat.com/" +reporter_comment="Example for building a toolchain for OpenRISC 1000 bare metal targets" diff --git a/samples/or1k-unknown-linux-gnu/crosstool.config b/samples/or1k-unknown-linux-gnu/crosstool.config new file mode 100644 index 00000000..6d69d0e7 --- /dev/null +++ b/samples/or1k-unknown-linux-gnu/crosstool.config @@ -0,0 +1,9 @@ +CT_CONFIG_VERSION="4" +CT_EXPERIMENTAL=y +CT_ARCH_OPENRISC=y +CT_ARCH_USE_MMU=y +CT_TARGET_VENDOR="" +CT_KERNEL_LINUX=y +CT_CC_LANG_CXX=y +CT_DEBUG_GDB=y +# CT_GDB_CROSS_PYTHON is not set diff --git a/samples/or1k-unknown-linux-gnu/reported.by b/samples/or1k-unknown-linux-gnu/reported.by new file mode 100644 index 00000000..0b2a045d --- /dev/null +++ b/samples/or1k-unknown-linux-gnu/reported.by @@ -0,0 +1,3 @@ +reporter_name="Jiaxun Yang " +reporter_url="https://flygoat.com/" +reporter_comment="Example for building a toolchain for OpenRISC 1000 with Linux kernel and glibc" diff --git a/samples/or1k-unknown-linux-musl/crosstool.config b/samples/or1k-unknown-linux-musl/crosstool.config new file mode 100644 index 00000000..5f820624 --- /dev/null +++ b/samples/or1k-unknown-linux-musl/crosstool.config @@ -0,0 +1,10 @@ +CT_CONFIG_VERSION="4" +CT_EXPERIMENTAL=y +CT_ARCH_OPENRISC=y +CT_ARCH_USE_MMU=y +CT_TARGET_VENDOR="" +CT_KERNEL_LINUX=y +CT_LIBC_MUSL=y +CT_CC_LANG_CXX=y +CT_DEBUG_GDB=y +# CT_GDB_CROSS_PYTHON is not set diff --git a/samples/or1k-unknown-linux-musl/reported.by b/samples/or1k-unknown-linux-musl/reported.by new file mode 100644 index 00000000..c0dcc1e3 --- /dev/null +++ b/samples/or1k-unknown-linux-musl/reported.by @@ -0,0 +1,3 @@ +reporter_name="Jiaxun Yang " +reporter_url="https://flygoat.com/" +reporter_comment="Example for building a toolchain for OpenRISC 1000 with Linux kernel and musl libc" diff --git a/scripts/build/arch/openrisc.sh b/scripts/build/arch/openrisc.sh new file mode 100644 index 00000000..7b467540 --- /dev/null +++ b/scripts/build/arch/openrisc.sh @@ -0,0 +1,6 @@ +# Compute OpenRISC-specific values + +CT_DoArchTupleValues() { + CT_TARGET_ARCH="or1k" + :; +}