Browse Source
Remove architecture and dependencies. Remove altera HAL supporting nios2 Signed-off-by: Anas Nashif <anas.nashif@intel.com>pull/86868/merge
83 changed files with 17 additions and 3673 deletions
@ -1,37 +0,0 @@
@@ -1,37 +0,0 @@
|
||||
# SPDX-License-Identifier: Apache-2.0 |
||||
|
||||
if(CONFIG_GP_NONE) |
||||
set(gpopt none) |
||||
elseif(CONFIG_GP_LOCAL) |
||||
set(gpopt local) |
||||
elseif(CONFIG_GP_GLOBAL) |
||||
set(gpopt global) |
||||
elseif(CONFIG_GP_ALL_DATA) |
||||
set(gpopt data) |
||||
endif() |
||||
|
||||
# Set Global Pointer option based on Kconfig. |
||||
zephyr_cc_option(-mgpopt=${gpopt}) |
||||
|
||||
# TODO Find a way to pull this out of system.h somehow |
||||
# instead of having Kconfig for it |
||||
|
||||
if(CONFIG_HAS_MUL_INSTRUCTION) |
||||
zephyr_cc_option(-mhw-mul) |
||||
else() |
||||
zephyr_cc_option(-mno-hw-mul) |
||||
endif() |
||||
|
||||
if(CONFIG_HAS_MULX_INSTRUCTION) |
||||
zephyr_cc_option(-mhw-mulx) |
||||
else() |
||||
zephyr_cc_option(-mno-hw-mulx) |
||||
endif() |
||||
|
||||
if(CONFIG_HAS_DIV_INSTRUCTION) |
||||
zephyr_cc_option(-mhw-div) |
||||
else() |
||||
zephyr_cc_option(-mno-hw-div) |
||||
endif() |
||||
|
||||
add_subdirectory(core) |
@ -1,96 +0,0 @@
@@ -1,96 +0,0 @@
|
||||
# Copyright (c) 2016 Intel Corporation |
||||
# SPDX-License-Identifier: Apache-2.0 |
||||
|
||||
menu "Nios II Options" |
||||
depends on NIOS2 |
||||
|
||||
config ARCH |
||||
string |
||||
default "nios2" |
||||
|
||||
menu "Nios II Gen 2 Processor Options" |
||||
|
||||
config CPU_NIOS2_GEN2 |
||||
bool |
||||
default y |
||||
select BUILD_OUTPUT_HEX |
||||
select ARCH_HAS_EXTRA_EXCEPTION_INFO |
||||
help |
||||
This option signifies the use of a Nios II Gen 2 CPU |
||||
|
||||
endmenu |
||||
|
||||
menu "Nios II Family Options" |
||||
|
||||
config GEN_ISR_TABLES |
||||
default y |
||||
|
||||
config GEN_IRQ_VECTOR_TABLE |
||||
default n |
||||
|
||||
config NUM_IRQS |
||||
int |
||||
default 32 |
||||
|
||||
config HAS_MUL_INSTRUCTION |
||||
bool |
||||
|
||||
config HAS_DIV_INSTRUCTION |
||||
bool |
||||
|
||||
config HAS_MULX_INSTRUCTION |
||||
bool |
||||
|
||||
config INCLUDE_RESET_VECTOR |
||||
bool "Include Reset vector" |
||||
default y |
||||
help |
||||
Include the reset vector stub, which enables instruction/data caches |
||||
and then jumps to __start. This code is typically located at the very |
||||
beginning of flash memory. You may need to omit this if using the |
||||
nios2-download tool since it refuses to load data anywhere other than |
||||
RAM. |
||||
|
||||
config EXTRA_EXCEPTION_INFO |
||||
bool "Extra exception debug information" |
||||
help |
||||
Have exceptions print additional useful debugging information in |
||||
human-readable form, at the expense of code size. For example, |
||||
the cause code for an exception will be supplemented by a string |
||||
describing what that cause code means. |
||||
|
||||
choice |
||||
prompt "Global Pointer options" |
||||
default GP_GLOBAL |
||||
|
||||
config GP_NONE |
||||
bool "No global pointer" |
||||
help |
||||
Do not use global pointer relative offsets at all |
||||
|
||||
config GP_LOCAL |
||||
bool "Local data global pointer references" |
||||
help |
||||
Use global pointer relative offsets for small globals declared in the |
||||
same C file as the code that uses it. |
||||
|
||||
config GP_GLOBAL |
||||
bool "Global data global pointer references" |
||||
help |
||||
Use global pointer relative offsets for small globals declared |
||||
anywhere in the executable. Note that if any small globals that are put |
||||
in alternate sections they must be declared |
||||
in headers with proper __attribute__((section)) or the linker will |
||||
error out. |
||||
|
||||
config GP_ALL_DATA |
||||
bool "All data global pointer references" |
||||
help |
||||
Use GP relative access for all data in the program, not just |
||||
small data. Use this if your board has 64K or less of RAM. |
||||
|
||||
endchoice |
||||
|
||||
endmenu |
||||
|
||||
endmenu |
@ -1,19 +0,0 @@
@@ -1,19 +0,0 @@
|
||||
# SPDX-License-Identifier: Apache-2.0 |
||||
|
||||
zephyr_library() |
||||
|
||||
zephyr_library_sources( |
||||
thread.c |
||||
cpu_idle.c |
||||
fatal.c |
||||
irq_manage.c |
||||
swap.S |
||||
prep_c.c |
||||
reset.S |
||||
cache.c |
||||
exception.S |
||||
crt0.S |
||||
) |
||||
|
||||
zephyr_library_sources_ifdef(CONFIG_IRQ_OFFLOAD irq_offload.c) |
||||
zephyr_library_sources_ifdef(CONFIG_TIMING_FUNCTIONS timing.c) |
@ -1,92 +0,0 @@
@@ -1,92 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Intel Corporation |
||||
* |
||||
* SPDX-License-Identifier: Apache-2.0 |
||||
*/ |
||||
|
||||
#include <zephyr/arch/cpu.h> |
||||
#include <zephyr/sys/__assert.h> |
||||
|
||||
|
||||
/**
|
||||
* Flush the entire instruction cache and pipeline. |
||||
* |
||||
* You will need to call this function if the application writes new program |
||||
* text to memory, such as a boot copier or runtime synthesis of code. If the |
||||
* new text was written with instructions that do not bypass cache memories, |
||||
* this should immediately be followed by an invocation of |
||||
* z_nios2_dcache_flush_all() so that cached instruction data is committed to |
||||
* RAM. |
||||
* |
||||
* See Chapter 9 of the Nios II Gen 2 Software Developer's Handbook for more |
||||
* information on cache considerations. |
||||
*/ |
||||
#if ALT_CPU_ICACHE_SIZE > 0 |
||||
void z_nios2_icache_flush_all(void) |
||||
{ |
||||
uint32_t i; |
||||
|
||||
for (i = 0U; i < ALT_CPU_ICACHE_SIZE; i += ALT_CPU_ICACHE_LINE_SIZE) { |
||||
z_nios2_icache_flush(i); |
||||
} |
||||
|
||||
/* Get rid of any stale instructions in the pipeline */ |
||||
z_nios2_pipeline_flush(); |
||||
} |
||||
#endif |
||||
|
||||
/**
|
||||
* Flush the entire data cache. |
||||
* |
||||
* This will be typically needed after writing new program text to memory |
||||
* after flushing the instruction cache. |
||||
* |
||||
* The Nios II does not support hardware cache coherency for multi-master |
||||
* or multi-processor systems and software coherency must be implemented |
||||
* when communicating with shared memory. If support for this is introduced |
||||
* in Zephyr additional APIs for flushing ranges of the data cache will need |
||||
* to be implemented. |
||||
* |
||||
* See Chapter 9 of the Nios II Gen 2 Software Developer's Handbook for more |
||||
* information on cache considerations. |
||||
*/ |
||||
#if ALT_CPU_DCACHE_SIZE > 0 |
||||
void z_nios2_dcache_flush_all(void) |
||||
{ |
||||
uint32_t i; |
||||
|
||||
for (i = 0U; i < ALT_CPU_DCACHE_SIZE; i += ALT_CPU_DCACHE_LINE_SIZE) { |
||||
z_nios2_dcache_flush(i); |
||||
} |
||||
} |
||||
#endif |
||||
|
||||
/*
|
||||
* z_nios2_dcache_flush_no_writeback() is called to flush the data cache for a |
||||
* memory region of length "len" bytes, starting at address "start". |
||||
* |
||||
* Any dirty lines in the data cache are NOT written back to memory. |
||||
* Make sure you really want this behavior. If you aren't 100% sure, |
||||
* use the z_nios2_dcache_flush() routine instead. |
||||
*/ |
||||
#if ALT_CPU_DCACHE_SIZE > 0 |
||||
void z_nios2_dcache_flush_no_writeback(void *start, uint32_t len) |
||||
{ |
||||
uint8_t *i; |
||||
uint8_t *end = ((char *) start) + len; |
||||
|
||||
for (i = start; i < end; i += ALT_CPU_DCACHE_LINE_SIZE) { |
||||
__asm__ volatile ("initda (%0)" :: "r" (i)); |
||||
} |
||||
|
||||
/*
|
||||
* For an unaligned flush request, we've got one more line left. |
||||
* Note that this is dependent on ALT_CPU_DCACHE_LINE_SIZE to be a |
||||
* multiple of 2 (which it always is). |
||||
*/ |
||||
|
||||
if (((uint32_t) start) & (ALT_CPU_DCACHE_LINE_SIZE - 1)) { |
||||
__asm__ volatile ("initda (%0)" :: "r" (i)); |
||||
} |
||||
} |
||||
#endif |
@ -1,28 +0,0 @@
@@ -1,28 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Intel Corporation |
||||
* |
||||
* SPDX-License-Identifier: Apache-2.0 |
||||
*/ |
||||
|
||||
#include <zephyr/kernel.h> |
||||
#include <zephyr/kernel_structs.h> |
||||
|
||||
#ifndef CONFIG_ARCH_HAS_CUSTOM_CPU_IDLE |
||||
void arch_cpu_idle(void) |
||||
{ |
||||
/* Do nothing but unconditionally unlock interrupts and return to the
|
||||
* caller. This CPU does not have any kind of power saving instruction. |
||||
*/ |
||||
irq_unlock(NIOS2_STATUS_PIE_MSK); |
||||
} |
||||
#endif |
||||
|
||||
#ifndef CONFIG_ARCH_HAS_CUSTOM_CPU_ATOMIC_IDLE |
||||
void arch_cpu_atomic_idle(unsigned int key) |
||||
{ |
||||
/* Do nothing but restore IRQ state. This CPU does not have any
|
||||
* kind of power saving instruction. |
||||
*/ |
||||
irq_unlock(key); |
||||
} |
||||
#endif |
@ -1,146 +0,0 @@
@@ -1,146 +0,0 @@
|
||||
/* |
||||
* Copyright (c) 2016 Intel Corporation |
||||
* |
||||
* SPDX-License-Identifier: Apache-2.0 |
||||
*/ |
||||
|
||||
#include <zephyr/toolchain.h> |
||||
#include <zephyr/linker/sections.h> |
||||
|
||||
/* exports */ |
||||
GTEXT(__start) |
||||
GTEXT(__reset) |
||||
|
||||
/* imports */ |
||||
GTEXT(z_prep_c) |
||||
GTEXT(z_interrupt_stacks) |
||||
|
||||
/* Allow use of r1/at (the assembler temporary register) in this |
||||
* code, normally reserved for internal assembler use |
||||
*/ |
||||
.set noat
|
||||
|
||||
|
||||
#if CONFIG_INCLUDE_RESET_VECTOR |
||||
/* |
||||
* Reset vector entry point into the system. Placed into special 'reset' |
||||
* section so that the linker puts this at ALT_CPU_RESET_ADDR defined in |
||||
* system.h |
||||
* |
||||
* This code can be at most 0x20 bytes, since the exception vector for Nios II |
||||
* is usually configured to be 0x20 past the reset vector. |
||||
*/ |
||||
SECTION_FUNC(reset, __reset) |
||||
|
||||
#if ALT_CPU_ICACHE_SIZE > 0 |
||||
/* Aside from the instruction cache line associated with the reset |
||||
* vector, the contents of the cache memories are indeterminate after |
||||
* reset. To ensure cache coherency after reset, the reset handler |
||||
* located at the reset vector must immediately initialize the |
||||
* instruction cache. Next, either the reset handler or a subsequent |
||||
* routine should proceed to initialize the data cache. |
||||
* |
||||
* The cache memory sizes are *always* a power of 2. |
||||
*/ |
||||
#if ALT_CPU_ICACHE_SIZE > 0x8000 |
||||
movhi r2, %hi(ALT_CPU_ICACHE_SIZE) |
||||
#else |
||||
movui r2, ALT_CPU_ICACHE_SIZE |
||||
#endif |
||||
0: |
||||
/* If ECC present, need to execute initd for each word address |
||||
* to ensure ECC parity bits in data RAM get initialized |
||||
*/ |
||||
#ifdef ALT_CPU_ECC_PRESENT |
||||
subi r2, r2, 4 |
||||
#else |
||||
subi r2, r2, ALT_CPU_ICACHE_LINE_SIZE |
||||
#endif |
||||
initi r2 |
||||
bgt r2, zero, 0b |
||||
#endif /* ALT_CPU_ICACHE_SIZE > 0 */ |
||||
|
||||
/* Done all we need to do here, jump to __text_start */ |
||||
movhi r1, %hi(__start) |
||||
ori r1, r1, %lo(__start) |
||||
jmp r1 |
||||
#endif /* CONFIG_INCLUDE_RESET_VECTOR */ |
||||
|
||||
/* Remainder of asm-land initialization code before we can jump into |
||||
* the C domain |
||||
*/ |
||||
SECTION_FUNC(TEXT, __start) |
||||
|
||||
/* TODO if shadow register sets enabled, ensure we are in set 0 |
||||
* GH-1821 |
||||
*/ |
||||
|
||||
/* Initialize the data cache if booting from bare metal. If |
||||
* we're not booting from our reset vector, either by a bootloader |
||||
* or JTAG, assume caches already initialized. |
||||
*/ |
||||
#if ALT_CPU_DCACHE_SIZE > 0 && defined(CONFIG_INCLUDE_RESET_VECTOR) |
||||
/* Per documentation data cache size is always a power of two. */ |
||||
#if ALT_CPU_DCACHE_SIZE > 0x8000 |
||||
movhi r2, %hi(ALT_CPU_DCACHE_SIZE) |
||||
#else |
||||
movui r2, ALT_CPU_DCACHE_SIZE |
||||
#endif |
||||
0: |
||||
/* If ECC present, need to execute initd for each word address |
||||
* to ensure ECC parity bits in data RAM get initialized |
||||
*/ |
||||
#ifdef ALT_CPU_ECC_PRESENT |
||||
subi r2, r2, 4 |
||||
#else |
||||
subi r2, r2, ALT_CPU_DCACHE_LINE_SIZE |
||||
#endif |
||||
initd 0(r2) |
||||
bgt r2, zero, 0b |
||||
#endif /* ALT_CPU_DCACHE_SIZE && defined(CONFIG_INCLUDE_RESET_VECTOR) */ |
||||
|
||||
#ifdef CONFIG_INIT_STACKS |
||||
/* Pre-populate all bytes in z_interrupt_stacks with 0xAA |
||||
* init.c enforces that the z_interrupt_stacks pointer |
||||
* and CONFIG_ISR_STACK_SIZE are a multiple of ARCH_STACK_PTR_ALIGN (4) |
||||
*/ |
||||
movhi r1, %hi(z_interrupt_stacks) |
||||
ori r1, r1, %lo(z_interrupt_stacks) |
||||
movhi r2, %hi(CONFIG_ISR_STACK_SIZE) |
||||
ori r2, r2, %lo(CONFIG_ISR_STACK_SIZE) |
||||
/* Put constant 0xaaaaaaaa in r3 */ |
||||
movhi r3, 0xaaaa |
||||
ori r3, r3, 0xaaaa |
||||
1: |
||||
/* Loop through the z_interrupt_stacks treating it as an array of |
||||
* uint32_t, setting each element to r3 */ |
||||
stw r3, (r1) |
||||
subi r2, r2, 4 |
||||
addi r1, r1, 4 |
||||
blt r0, r2, 1b |
||||
#endif |
||||
|
||||
/* Set up the initial stack pointer to the interrupt stack, safe |
||||
* to use this as the CPU boots up with interrupts disabled and we |
||||
* don't turn them on until much later, when the kernel is on |
||||
* the main stack */ |
||||
movhi sp, %hi(z_interrupt_stacks) |
||||
ori sp, sp, %lo(z_interrupt_stacks) |
||||
addi sp, sp, CONFIG_ISR_STACK_SIZE |
||||
|
||||
#if defined(CONFIG_GP_LOCAL) || defined(CONFIG_GP_GLOBAL) || \ |
||||
defined(CONFIG_GP_ALL_DATA) |
||||
/* Initialize global pointer with the linker variable we set */ |
||||
movhi gp, %hi(_gp) |
||||
ori gp, gp, %lo(_gp) |
||||
#endif |
||||
|
||||
/* TODO if shadow register sets enabled, interate through them to set |
||||
* up. Need to clear r0, write gp, set the exception stack pointer |
||||
* GH-1821 |
||||
*/ |
||||
|
||||
/* Jump into C domain. z_prep_c zeroes BSS, copies rw data into RAM, |
||||
* and then enters z_cstart */ |
||||
call z_prep_c |
||||
|
@ -1,227 +0,0 @@
@@ -1,227 +0,0 @@
|
||||
/* |
||||
* Copyright (c) 2016 Intel Corporation |
||||
* |
||||
* SPDX-License-Identifier: Apache-2.0 |
||||
*/ |
||||
|
||||
#include <zephyr/toolchain.h> |
||||
#include <zephyr/linker/sections.h> |
||||
#include <offsets_short.h> |
||||
|
||||
/* exports */ |
||||
GTEXT(_exception) |
||||
|
||||
/* import */ |
||||
GTEXT(z_nios2_fault) |
||||
GTEXT(arch_swap) |
||||
#ifdef CONFIG_IRQ_OFFLOAD |
||||
GTEXT(z_irq_do_offload) |
||||
GTEXT(_offload_routine) |
||||
#endif |
||||
|
||||
/* Allows use of r1/at register, otherwise reserved for assembler use */ |
||||
.set noat
|
||||
|
||||
/* Placed into special 'exception' section so that the linker can put this code |
||||
* at ALT_CPU_EXCEPTION_ADDR defined in system.h |
||||
* |
||||
* This is the common entry point for processor exceptions and interrupts from |
||||
* the Internal Interrupt Controller (IIC). |
||||
* |
||||
* If the External (EIC) controller is in use, then we will never get here on |
||||
* behalf of an interrupt, instead the EIC driver will have set up a vector |
||||
* table and the processor will jump directly into the appropriate table |
||||
* entry. |
||||
*/ |
||||
SECTION_FUNC(exception.entry, _exception) |
||||
/* Reserve thread stack space for saving context */ |
||||
subi sp, sp, __struct_arch_esf_SIZEOF |
||||
|
||||
/* Preserve all caller-saved registers onto the thread's stack */ |
||||
stw ra, __struct_arch_esf_ra_OFFSET(sp) |
||||
stw r1, __struct_arch_esf_r1_OFFSET(sp) |
||||
stw r2, __struct_arch_esf_r2_OFFSET(sp) |
||||
stw r3, __struct_arch_esf_r3_OFFSET(sp) |
||||
stw r4, __struct_arch_esf_r4_OFFSET(sp) |
||||
stw r5, __struct_arch_esf_r5_OFFSET(sp) |
||||
stw r6, __struct_arch_esf_r6_OFFSET(sp) |
||||
stw r7, __struct_arch_esf_r7_OFFSET(sp) |
||||
stw r8, __struct_arch_esf_r8_OFFSET(sp) |
||||
stw r9, __struct_arch_esf_r9_OFFSET(sp) |
||||
stw r10, __struct_arch_esf_r10_OFFSET(sp) |
||||
stw r11, __struct_arch_esf_r11_OFFSET(sp) |
||||
stw r12, __struct_arch_esf_r12_OFFSET(sp) |
||||
stw r13, __struct_arch_esf_r13_OFFSET(sp) |
||||
stw r14, __struct_arch_esf_r14_OFFSET(sp) |
||||
stw r15, __struct_arch_esf_r15_OFFSET(sp) |
||||
|
||||
/* Store value of estatus control register */ |
||||
rdctl et, estatus |
||||
stw et, __struct_arch_esf_estatus_OFFSET(sp) |
||||
|
||||
/* ea-4 is the address of the instruction when the exception happened, |
||||
* put this in the stack frame as well |
||||
*/ |
||||
addi r15, ea, -4 |
||||
stw r15, __struct_arch_esf_instr_OFFSET(sp) |
||||
|
||||
/* Figure out whether we are here because of an interrupt or an |
||||
* exception. If an interrupt, switch stacks and enter IRQ handling |
||||
* code. If an exception, remain on current stack and enter exception |
||||
* handing code. From the CPU manual, ipending must be nonzero and |
||||
* estatis.PIE must be enabled for this to be considered an interrupt. |
||||
* |
||||
* Stick ipending in r4 since it will be an arg for _enter_irq |
||||
*/ |
||||
rdctl r4, ipending |
||||
beq r4, zero, not_interrupt |
||||
/* We stashed estatus in et earlier */ |
||||
andi r15, et, 1 |
||||
beq r15, zero, not_interrupt |
||||
|
||||
is_interrupt: |
||||
/* If we get here, this is an interrupt */ |
||||
|
||||
/* Grab a reference to _kernel in r10 so we can determine the |
||||
* current irq stack pointer |
||||
*/ |
||||
movhi r10, %hi(_kernel) |
||||
ori r10, r10, %lo(_kernel) |
||||
|
||||
/* Stash a copy of thread's sp in r12 so that we can put it on the IRQ |
||||
* stack |
||||
*/ |
||||
mov r12, sp |
||||
|
||||
/* Switch to interrupt stack */ |
||||
ldw sp, _kernel_offset_to_irq_stack(r10) |
||||
|
||||
/* Store thread stack pointer onto IRQ stack */ |
||||
addi sp, sp, -4 |
||||
stw r12, 0(sp) |
||||
|
||||
on_irq_stack: |
||||
|
||||
/* Enter C interrupt handling code. Value of ipending will be the |
||||
* function parameter since we put it in r4 |
||||
*/ |
||||
call _enter_irq |
||||
|
||||
/* Interrupt handler finished and the interrupt should be serviced |
||||
* now, the appropriate bits in ipending should be cleared */ |
||||
|
||||
/* Get a reference to _kernel again in r10 */ |
||||
movhi r10, %hi(_kernel) |
||||
ori r10, r10, %lo(_kernel) |
||||
|
||||
#ifdef CONFIG_PREEMPT_ENABLED |
||||
ldw r11, _kernel_offset_to_current(r10) |
||||
/* Determine whether the exception of the ISR requires context |
||||
* switch |
||||
*/ |
||||
|
||||
/* Call into the kernel to see if a scheduling decision is necessary */ |
||||
ldw r2, _kernel_offset_to_ready_q_cache(r10) |
||||
beq r2, r11, no_reschedule |
||||
|
||||
/* |
||||
* A context reschedule is required: keep the volatile registers of |
||||
* the interrupted thread on the context's stack. Utilize |
||||
* the existing arch_swap() primitive to save the remaining |
||||
* thread's registers (including floating point) and perform |
||||
* a switch to the new thread. |
||||
*/ |
||||
|
||||
/* We put the thread stack pointer on top of the IRQ stack before |
||||
* we switched stacks. Restore it to go back to thread stack |
||||
*/ |
||||
ldw sp, 0(sp) |
||||
|
||||
/* Argument to Swap() is estatus since that's the state of the |
||||
* status register before the exception happened. When coming |
||||
* out of the context switch we need this info to restore |
||||
* IRQ lock state. We put this value in et earlier. |
||||
*/ |
||||
mov r4, et |
||||
|
||||
call arch_swap |
||||
jmpi _exception_exit |
||||
#else |
||||
jmpi no_reschedule |
||||
#endif /* CONFIG_PREEMPT_ENABLED */ |
||||
|
||||
not_interrupt: |
||||
|
||||
/* Since this wasn't an interrupt we're not going to restart the |
||||
* faulting instruction. |
||||
* |
||||
* We earlier put ea - 4 in the stack frame, replace it with just ea |
||||
*/ |
||||
stw ea, __struct_arch_esf_instr_OFFSET(sp) |
||||
|
||||
#ifdef CONFIG_IRQ_OFFLOAD |
||||
/* Check the contents of _offload_routine. If non-NULL, jump into |
||||
* the interrupt code anyway. |
||||
*/ |
||||
movhi r10, %hi(_offload_routine) |
||||
ori r10, r10, %lo(_offload_routine) |
||||
ldw r11, (r10) |
||||
bne r11, zero, is_interrupt |
||||
#endif |
||||
|
||||
_exception_enter_fault: |
||||
/* If we get here, the exception wasn't in interrupt or an |
||||
* invocation of irq_offload(). Let z_nios2_fault() handle it in |
||||
* C domain |
||||
*/ |
||||
|
||||
mov r4, sp |
||||
call z_nios2_fault |
||||
jmpi _exception_exit |
||||
|
||||
no_reschedule: |
||||
|
||||
/* We put the thread stack pointer on top of the IRQ stack before |
||||
* we switched stacks. Restore it to go back to thread stack |
||||
*/ |
||||
ldw sp, 0(sp) |
||||
|
||||
/* Fall through */ |
||||
|
||||
_exception_exit: |
||||
/* We are on the thread stack. Restore all saved registers |
||||
* and return to the interrupted context */ |
||||
|
||||
/* Return address from the exception */ |
||||
ldw ea, __struct_arch_esf_instr_OFFSET(sp) |
||||
|
||||
/* Restore estatus |
||||
* XXX is this right??? */ |
||||
ldw r5, __struct_arch_esf_estatus_OFFSET(sp) |
||||
wrctl estatus, r5 |
||||
|
||||
/* Restore caller-saved registers */ |
||||
ldw ra, __struct_arch_esf_ra_OFFSET(sp) |
||||
ldw r1, __struct_arch_esf_r1_OFFSET(sp) |
||||
ldw r2, __struct_arch_esf_r2_OFFSET(sp) |
||||
ldw r3, __struct_arch_esf_r3_OFFSET(sp) |
||||
ldw r4, __struct_arch_esf_r4_OFFSET(sp) |
||||
ldw r5, __struct_arch_esf_r5_OFFSET(sp) |
||||
ldw r6, __struct_arch_esf_r6_OFFSET(sp) |
||||
ldw r7, __struct_arch_esf_r7_OFFSET(sp) |
||||
ldw r8, __struct_arch_esf_r8_OFFSET(sp) |
||||
ldw r9, __struct_arch_esf_r9_OFFSET(sp) |
||||
ldw r10, __struct_arch_esf_r10_OFFSET(sp) |
||||
ldw r11, __struct_arch_esf_r11_OFFSET(sp) |
||||
ldw r12, __struct_arch_esf_r12_OFFSET(sp) |
||||
ldw r13, __struct_arch_esf_r13_OFFSET(sp) |
||||
ldw r14, __struct_arch_esf_r14_OFFSET(sp) |
||||
ldw r15, __struct_arch_esf_r15_OFFSET(sp) |
||||
|
||||
/* Put the stack pointer back where it was when we entered |
||||
* exception state |
||||
*/ |
||||
addi sp, sp, __struct_arch_esf_SIZEOF |
||||
|
||||
/* All done, copy estatus into status and transfer to ea */ |
||||
eret |
@ -1,144 +0,0 @@
@@ -1,144 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Intel Corporation |
||||
* |
||||
* SPDX-License-Identifier: Apache-2.0 |
||||
*/ |
||||
|
||||
#include <zephyr/kernel.h> |
||||
#include <zephyr/arch/cpu.h> |
||||
#include <zephyr/kernel_structs.h> |
||||
#include <inttypes.h> |
||||
#include <zephyr/logging/log.h> |
||||
LOG_MODULE_DECLARE(os, CONFIG_KERNEL_LOG_LEVEL); |
||||
|
||||
FUNC_NORETURN void z_nios2_fatal_error(unsigned int reason, |
||||
const struct arch_esf *esf) |
||||
{ |
||||
#if CONFIG_EXCEPTION_DEBUG |
||||
if (esf != NULL) { |
||||
/* Subtract 4 from EA since we added 4 earlier so that the
|
||||
* faulting instruction isn't retried. |
||||
* |
||||
* TODO: Only caller-saved registers get saved upon exception |
||||
* entry. We may want to introduce a config option to save and |
||||
* dump all registers, at the expense of some stack space. |
||||
*/ |
||||
LOG_ERR("Faulting instruction: 0x%08x", esf->instr - 4); |
||||
LOG_ERR(" r1: 0x%08x r2: 0x%08x r3: 0x%08x r4: 0x%08x", |
||||
esf->r1, esf->r2, esf->r3, esf->r4); |
||||
LOG_ERR(" r5: 0x%08x r6: 0x%08x r7: 0x%08x r8: 0x%08x", |
||||
esf->r5, esf->r6, esf->r7, esf->r8); |
||||
LOG_ERR(" r9: 0x%08x r10: 0x%08x r11: 0x%08x r12: 0x%08x", |
||||
esf->r9, esf->r10, esf->r11, esf->r12); |
||||
LOG_ERR(" r13: 0x%08x r14: 0x%08x r15: 0x%08x ra: 0x%08x", |
||||
esf->r13, esf->r14, esf->r15, esf->ra); |
||||
LOG_ERR("estatus: %08x", esf->estatus); |
||||
} |
||||
#endif /* CONFIG_EXCEPTION_DEBUG */ |
||||
|
||||
z_fatal_error(reason, esf); |
||||
CODE_UNREACHABLE; |
||||
} |
||||
|
||||
#if defined(CONFIG_EXTRA_EXCEPTION_INFO) && \ |
||||
(defined(CONFIG_PRINTK) || defined(CONFIG_LOG)) \ |
||||
&& defined(ALT_CPU_HAS_EXTRA_EXCEPTION_INFO) |
||||
static char *cause_str(uint32_t cause_code) |
||||
{ |
||||
switch (cause_code) { |
||||
case 0: |
||||
return "reset"; |
||||
case 1: |
||||
return "processor-only reset request"; |
||||
case 2: |
||||
return "interrupt"; |
||||
case 3: |
||||
return "trap"; |
||||
case 4: |
||||
return "unimplemented instruction"; |
||||
case 5: |
||||
return "illegal instruction"; |
||||
case 6: |
||||
return "misaligned data address"; |
||||
case 7: |
||||
return "misaligned destination address"; |
||||
case 8: |
||||
return "division error"; |
||||
case 9: |
||||
return "supervisor-only instruction address"; |
||||
case 10: |
||||
return "supervisor-only instruction"; |
||||
case 11: |
||||
return "supervisor-only data address"; |
||||
case 12: |
||||
return "TLB miss"; |
||||
case 13: |
||||
return "TLB permission violation (execute)"; |
||||
case 14: |
||||
return "TLB permission violation (read)"; |
||||
case 15: |
||||
return "TLB permission violation (write)"; |
||||
case 16: |
||||
return "MPU region violation (instruction)"; |
||||
case 17: |
||||
return "MPU region violation (data)"; |
||||
case 18: |
||||
return "ECC TLB error"; |
||||
case 19: |
||||
return "ECC fetch error (instruction)"; |
||||
case 20: |
||||
return "ECC register file error"; |
||||
case 21: |
||||
return "ECC data error"; |
||||
case 22: |
||||
return "ECC data cache writeback error"; |
||||
case 23: |
||||
return "bus instruction fetch error"; |
||||
case 24: |
||||
return "bus data region violation"; |
||||
default: |
||||
return "unknown"; |
||||
} |
||||
} |
||||
#endif |
||||
|
||||
FUNC_NORETURN void z_nios2_fault(const struct arch_esf *esf) |
||||
{ |
||||
#if defined(CONFIG_PRINTK) || defined(CONFIG_LOG) |
||||
/* Unfortunately, completely unavailable on Nios II/e cores */ |
||||
#ifdef ALT_CPU_HAS_EXTRA_EXCEPTION_INFO |
||||
uint32_t exc_reg, badaddr_reg, eccftl; |
||||
enum nios2_exception_cause cause; |
||||
|
||||
exc_reg = z_nios2_creg_read(NIOS2_CR_EXCEPTION); |
||||
|
||||
/* Bit 31 indicates potentially fatal ECC error */ |
||||
eccftl = (exc_reg & NIOS2_EXCEPTION_REG_ECCFTL_MASK) != 0U; |
||||
|
||||
/* Bits 2-6 contain the cause code */ |
||||
cause = (exc_reg & NIOS2_EXCEPTION_REG_CAUSE_MASK) |
||||
>> NIOS2_EXCEPTION_REG_CAUSE_OFST; |
||||
|
||||
LOG_ERR("Exception cause: %d ECCFTL: 0x%x", cause, eccftl); |
||||
#if CONFIG_EXTRA_EXCEPTION_INFO |
||||
LOG_ERR("reason: %s", cause_str(cause)); |
||||
#endif |
||||
if (BIT(cause) & NIOS2_BADADDR_CAUSE_MASK) { |
||||
badaddr_reg = z_nios2_creg_read(NIOS2_CR_BADADDR); |
||||
LOG_ERR("Badaddr: 0x%x", badaddr_reg); |
||||
} |
||||
#endif /* ALT_CPU_HAS_EXTRA_EXCEPTION_INFO */ |
||||
#endif /* CONFIG_PRINTK || CONFIG_LOG */ |
||||
|
||||
z_nios2_fatal_error(K_ERR_CPU_EXCEPTION, esf); |
||||
} |
||||
|
||||
#ifdef ALT_CPU_HAS_DEBUG_STUB |
||||
FUNC_NORETURN void arch_system_halt(unsigned int reason) |
||||
{ |
||||
ARG_UNUSED(reason); |
||||
|
||||
z_nios2_break(); |
||||
CODE_UNREACHABLE; |
||||
} |
||||
#endif |
@ -1,124 +0,0 @@
@@ -1,124 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Intel Corporation |
||||
* |
||||
* SPDX-License-Identifier: Apache-2.0 |
||||
*/ |
||||
|
||||
/**
|
||||
* @file |
||||
* @brief Nios II C-domain interrupt management code for use with Internal |
||||
* Interrupt Controller (IIC) |
||||
*/ |
||||
|
||||
|
||||
#include <zephyr/kernel.h> |
||||
#include <zephyr/kernel_structs.h> |
||||
#include <zephyr/arch/cpu.h> |
||||
#include <zephyr/irq.h> |
||||
#include <zephyr/sw_isr_table.h> |
||||
#include <ksched.h> |
||||
#include <kswap.h> |
||||
#include <zephyr/tracing/tracing.h> |
||||
#include <zephyr/logging/log.h> |
||||
LOG_MODULE_DECLARE(os, CONFIG_KERNEL_LOG_LEVEL); |
||||
|
||||
FUNC_NORETURN void z_irq_spurious(const void *unused) |
||||
{ |
||||
ARG_UNUSED(unused); |
||||
LOG_ERR("Spurious interrupt detected! ipending: %x", |
||||
z_nios2_creg_read(NIOS2_CR_IPENDING)); |
||||
z_nios2_fatal_error(K_ERR_SPURIOUS_IRQ, NULL); |
||||
} |
||||
|
||||
|
||||
void arch_irq_enable(unsigned int irq) |
||||
{ |
||||
uint32_t ienable; |
||||
unsigned int key; |
||||
|
||||
key = irq_lock(); |
||||
|
||||
ienable = z_nios2_creg_read(NIOS2_CR_IENABLE); |
||||
ienable |= BIT(irq); |
||||
z_nios2_creg_write(NIOS2_CR_IENABLE, ienable); |
||||
|
||||
irq_unlock(key); |
||||
}; |
||||
|
||||
|
||||
|
||||
void arch_irq_disable(unsigned int irq) |
||||
{ |
||||
uint32_t ienable; |
||||
unsigned int key; |
||||
|
||||
key = irq_lock(); |
||||
|
||||
ienable = z_nios2_creg_read(NIOS2_CR_IENABLE); |
||||
ienable &= ~BIT(irq); |
||||
z_nios2_creg_write(NIOS2_CR_IENABLE, ienable); |
||||
|
||||
irq_unlock(key); |
||||
}; |
||||
|
||||
int arch_irq_is_enabled(unsigned int irq) |
||||
{ |
||||
uint32_t ienable; |
||||
|
||||
ienable = z_nios2_creg_read(NIOS2_CR_IENABLE); |
||||
return ienable & BIT(irq); |
||||
} |
||||
|
||||
/**
|
||||
* @brief Interrupt demux function |
||||
* |
||||
* Given a bitfield of pending interrupts, execute the appropriate handler |
||||
* |
||||
* @param ipending Bitfield of interrupts |
||||
*/ |
||||
void _enter_irq(uint32_t ipending) |
||||
{ |
||||
int index; |
||||
|
||||
_kernel.cpus[0].nested++; |
||||
|
||||
#ifdef CONFIG_IRQ_OFFLOAD |
||||
z_irq_do_offload(); |
||||
#endif |
||||
|
||||
while (ipending) { |
||||
struct _isr_table_entry *ite; |
||||
|
||||
#ifdef CONFIG_TRACING_ISR |
||||
sys_trace_isr_enter(); |
||||
#endif |
||||
|
||||
index = find_lsb_set(ipending) - 1; |
||||
ipending &= ~BIT(index); |
||||
|
||||
ite = &_sw_isr_table[index]; |
||||
|
||||
ite->isr(ite->arg); |
||||
#ifdef CONFIG_TRACING_ISR |
||||
sys_trace_isr_exit(); |
||||
#endif |
||||
} |
||||
|
||||
_kernel.cpus[0].nested--; |
||||
#ifdef CONFIG_STACK_SENTINEL |
||||
z_check_stack_sentinel(); |
||||
#endif |
||||
} |
||||
|
||||
#ifdef CONFIG_DYNAMIC_INTERRUPTS |
||||
int arch_irq_connect_dynamic(unsigned int irq, unsigned int priority, |
||||
void (*routine)(const void *parameter), |
||||
const void *parameter, uint32_t flags) |
||||
{ |
||||
ARG_UNUSED(flags); |
||||
ARG_UNUSED(priority); |
||||
|
||||
z_isr_install(irq, routine, parameter); |
||||
return irq; |
||||
} |
||||
#endif /* CONFIG_DYNAMIC_INTERRUPTS */ |
@ -1,47 +0,0 @@
@@ -1,47 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Intel Corporation |
||||
* |
||||
* SPDX-License-Identifier: Apache-2.0 |
||||
*/ |
||||
|
||||
#include <zephyr/kernel.h> |
||||
#include <zephyr/kernel_structs.h> |
||||
#include <zephyr/irq_offload.h> |
||||
|
||||
volatile irq_offload_routine_t _offload_routine; |
||||
static volatile const void *offload_param; |
||||
|
||||
/* Called by _enter_irq if it was passed 0 for ipending.
|
||||
* Just in case the offload routine itself generates an unhandled |
||||
* exception, clear the offload_routine global before executing. |
||||
*/ |
||||
void z_irq_do_offload(void) |
||||
{ |
||||
irq_offload_routine_t tmp; |
||||
|
||||
if (!_offload_routine) { |
||||
return; |
||||
} |
||||
|
||||
tmp = _offload_routine; |
||||
_offload_routine = NULL; |
||||
|
||||
tmp((const void *)offload_param); |
||||
} |
||||
|
||||
void arch_irq_offload(irq_offload_routine_t routine, const void *parameter) |
||||
{ |
||||
unsigned int key; |
||||
|
||||
key = irq_lock(); |
||||
_offload_routine = routine; |
||||
offload_param = parameter; |
||||
|
||||
__asm__ volatile ("trap"); |
||||
|
||||
irq_unlock(key); |
||||
} |
||||
|
||||
void arch_irq_offload_init(void) |
||||
{ |
||||
} |
@ -1,67 +0,0 @@
@@ -1,67 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Intel Corporation |
||||
* |
||||
* SPDX-License-Identifier: Apache-2.0 |
||||
*/ |
||||
|
||||
/**
|
||||
* @file |
||||
* @brief Nios II kernel structure member offset definition file |
||||
* |
||||
* This module is responsible for the generation of the absolute symbols whose |
||||
* value represents the member offsets for various Nios II kernel |
||||
* structures. |
||||
* |
||||
* All of the absolute symbols defined by this module will be present in the |
||||
* final kernel ELF image (due to the linker's reference to the _OffsetAbsSyms |
||||
* symbol). |
||||
* |
||||
* INTERNAL |
||||
* It is NOT necessary to define the offset for every member of a structure. |
||||
* Typically, only those members that are accessed by assembly language routines |
||||
* are defined; however, it doesn't hurt to define all fields for the sake of |
||||
* completeness. |
||||
*/ |
||||
|
||||
|
||||
#include <zephyr/kernel.h> |
||||
#include <kernel_arch_data.h> |
||||
#include <gen_offset.h> |
||||
#include <kernel_offsets.h> |
||||
|
||||
/* struct coop member offsets */ |
||||
GEN_OFFSET_SYM(_callee_saved_t, r16); |
||||
GEN_OFFSET_SYM(_callee_saved_t, r17); |
||||
GEN_OFFSET_SYM(_callee_saved_t, r18); |
||||
GEN_OFFSET_SYM(_callee_saved_t, r19); |
||||
GEN_OFFSET_SYM(_callee_saved_t, r20); |
||||
GEN_OFFSET_SYM(_callee_saved_t, r21); |
||||
GEN_OFFSET_SYM(_callee_saved_t, r22); |
||||
GEN_OFFSET_SYM(_callee_saved_t, r23); |
||||
GEN_OFFSET_SYM(_callee_saved_t, r28); |
||||
GEN_OFFSET_SYM(_callee_saved_t, ra); |
||||
GEN_OFFSET_SYM(_callee_saved_t, sp); |
||||
GEN_OFFSET_SYM(_callee_saved_t, key); |
||||
GEN_OFFSET_SYM(_callee_saved_t, retval); |
||||
|
||||
GEN_OFFSET_STRUCT(arch_esf, ra); |
||||
GEN_OFFSET_STRUCT(arch_esf, r1); |
||||
GEN_OFFSET_STRUCT(arch_esf, r2); |
||||
GEN_OFFSET_STRUCT(arch_esf, r3); |
||||
GEN_OFFSET_STRUCT(arch_esf, r4); |
||||
GEN_OFFSET_STRUCT(arch_esf, r5); |
||||
GEN_OFFSET_STRUCT(arch_esf, r6); |
||||
GEN_OFFSET_STRUCT(arch_esf, r7); |
||||
GEN_OFFSET_STRUCT(arch_esf, r8); |
||||
GEN_OFFSET_STRUCT(arch_esf, r9); |
||||
GEN_OFFSET_STRUCT(arch_esf, r10); |
||||
GEN_OFFSET_STRUCT(arch_esf, r11); |
||||
GEN_OFFSET_STRUCT(arch_esf, r12); |
||||
GEN_OFFSET_STRUCT(arch_esf, r13); |
||||
GEN_OFFSET_STRUCT(arch_esf, r14); |
||||
GEN_OFFSET_STRUCT(arch_esf, r15); |
||||
GEN_OFFSET_STRUCT(arch_esf, estatus); |
||||
GEN_OFFSET_STRUCT(arch_esf, instr); |
||||
GEN_ABSOLUTE_SYM(__struct_arch_esf_SIZEOF, sizeof(struct arch_esf)); |
||||
|
||||
GEN_ABS_SYM_END |
@ -1,59 +0,0 @@
@@ -1,59 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2014 Wind River Systems, Inc. |
||||
* |
||||
* SPDX-License-Identifier: Apache-2.0 |
||||
*/ |
||||
|
||||
/**
|
||||
* @file |
||||
* @brief Full C support initialization |
||||
* |
||||
* |
||||
* Initialization of full C support: zero the .bss, copy the .data if XIP, |
||||
* call z_cstart(). |
||||
* |
||||
* Stack is available in this module, but not the global data/bss until their |
||||
* initialization is performed. |
||||
*/ |
||||
|
||||
#include <zephyr/types.h> |
||||
#include <zephyr/toolchain.h> |
||||
#include <zephyr/linker/linker-defs.h> |
||||
#include <zephyr/kernel_structs.h> |
||||
#include <kernel_internal.h> |
||||
#include <zephyr/platform/hooks.h> |
||||
#include <zephyr/arch/cache.h> |
||||
|
||||
/**
|
||||
* @brief Prepare to and run C code |
||||
* |
||||
* This routine prepares for the execution of and runs C code. |
||||
*/ |
||||
|
||||
void z_prep_c(void) |
||||
{ |
||||
#if defined(CONFIG_SOC_PREP_HOOK) |
||||
soc_prep_hook(); |
||||
#endif |
||||
|
||||
z_bss_zero(); |
||||
z_data_copy(); |
||||
/* In most XIP scenarios we copy the exception code into RAM, so need
|
||||
* to flush instruction cache. |
||||
*/ |
||||
#ifdef CONFIG_XIP |
||||
z_nios2_icache_flush_all(); |
||||
#if ALT_CPU_ICACHE_SIZE > 0 |
||||
/* Only need to flush the data cache here if there actually is an
|
||||
* instruction cache, so that the cached instruction data written is |
||||
* actually committed. |
||||
*/ |
||||
z_nios2_dcache_flush_all(); |
||||
#endif |
||||
#endif |
||||
#if CONFIG_ARCH_CACHE |
||||
arch_cache_init(); |
||||
#endif |
||||
z_cstart(); |
||||
CODE_UNREACHABLE; |
||||
} |
@ -1,10 +0,0 @@
@@ -1,10 +0,0 @@
|
||||
/* |
||||
* Copyright (c) 2016 Intel Corporation |
||||
* |
||||
* SPDX-License-Identifier: Apache-2.0 |
||||
*/ |
||||
|
||||
#include <zephyr/toolchain.h> |
||||
|
||||
GTEXT(__start) |
||||
|
@ -1,167 +0,0 @@
@@ -1,167 +0,0 @@
|
||||
/* |
||||
* Copyright (c) 2016 Intel Corporation |
||||
* |
||||
* SPDX-License-Identifier: Apache-2.0 |
||||
*/ |
||||
|
||||
#include <zephyr/toolchain.h> |
||||
#include <zephyr/linker/sections.h> |
||||
#include <offsets_short.h> |
||||
|
||||
/* exports */ |
||||
GTEXT(arch_swap) |
||||
GTEXT(z_thread_entry_wrapper) |
||||
|
||||
/* imports */ |
||||
GTEXT(_k_neg_eagain) |
||||
|
||||
/* unsigned int arch_swap(unsigned int key) |
||||
* |
||||
* Always called with interrupts locked |
||||
*/ |
||||
SECTION_FUNC(exception.other, arch_swap) |
||||
|
||||
#if defined(CONFIG_INSTRUMENT_THREAD_SWITCHING) |
||||
/* Need to preserve r4 as it has the function argument. */ |
||||
addi sp, sp, -12 |
||||
stw ra, 8(sp) |
||||
stw fp, 4(sp) |
||||
stw r4, 0(sp) |
||||
|
||||
call z_thread_mark_switched_out |
||||
|
||||
ldw r4, 0(sp) |
||||
ldw fp, 4(sp) |
||||
ldw ra, 8(sp) |
||||
addi sp, sp, 12 |
||||
#endif |
||||
|
||||
/* Get a reference to _kernel in r10 */ |
||||
movhi r10, %hi(_kernel) |
||||
ori r10, r10, %lo(_kernel) |
||||
|
||||
/* Get the pointer to kernel->current */ |
||||
ldw r11, _kernel_offset_to_current(r10) |
||||
|
||||
/* Store all the callee saved registers. We either got here via |
||||
* an exception or from a cooperative invocation of arch_swap() from C |
||||
* domain, so all the caller-saved registers have already been |
||||
* saved by the exception asm or the calling C code already. |
||||
*/ |
||||
stw r16, _thread_offset_to_r16(r11) |
||||
stw r17, _thread_offset_to_r17(r11) |
||||
stw r18, _thread_offset_to_r18(r11) |
||||
stw r19, _thread_offset_to_r19(r11) |
||||
stw r20, _thread_offset_to_r20(r11) |
||||
stw r21, _thread_offset_to_r21(r11) |
||||
stw r22, _thread_offset_to_r22(r11) |
||||
stw r23, _thread_offset_to_r23(r11) |
||||
stw r28, _thread_offset_to_r28(r11) |
||||
stw ra, _thread_offset_to_ra(r11) |
||||
stw sp, _thread_offset_to_sp(r11) |
||||
|
||||
/* r4 has the 'key' argument which is the result of irq_lock() |
||||
* before this was called |
||||
*/ |
||||
stw r4, _thread_offset_to_key(r11) |
||||
|
||||
/* Populate default return value */ |
||||
movhi r5, %hi(_k_neg_eagain) |
||||
ori r5, r5, %lo(_k_neg_eagain) |
||||
ldw r4, (r5) |
||||
stw r4, _thread_offset_to_retval(r11) |
||||
|
||||
/* get cached thread to run */ |
||||
ldw r2, _kernel_offset_to_ready_q_cache(r10) |
||||
|
||||
/* At this point r2 points to the next thread to be swapped in */ |
||||
|
||||
/* the thread to be swapped in is now the current thread */ |
||||
stw r2, _kernel_offset_to_current(r10) |
||||
|
||||
/* Restore callee-saved registers and switch to the incoming |
||||
* thread's stack |
||||
*/ |
||||
ldw r16, _thread_offset_to_r16(r2) |
||||
ldw r17, _thread_offset_to_r17(r2) |
||||
ldw r18, _thread_offset_to_r18(r2) |
||||
ldw r19, _thread_offset_to_r19(r2) |
||||
ldw r20, _thread_offset_to_r20(r2) |
||||
ldw r21, _thread_offset_to_r21(r2) |
||||
ldw r22, _thread_offset_to_r22(r2) |
||||
ldw r23, _thread_offset_to_r23(r2) |
||||
ldw r28, _thread_offset_to_r28(r2) |
||||
ldw ra, _thread_offset_to_ra(r2) |
||||
ldw sp, _thread_offset_to_sp(r2) |
||||
|
||||
/* We need to irq_unlock(current->coopReg.key);
|
||||
* key was supplied as argument to arch_swap(). Fetch it. |
||||
*/ |
||||
ldw r3, _thread_offset_to_key(r2) |
||||
|
||||
/* |
||||
* Load return value into r2 (return value register). -EAGAIN unless |
||||
* someone previously called arch_thread_return_value_set(). Do this |
||||
* before we potentially unlock interrupts. |
||||
*/ |
||||
ldw r2, _thread_offset_to_retval(r2) |
||||
|
||||
/* Now do irq_unlock(current->coopReg.key) */ |
||||
#if (ALT_CPU_NUM_OF_SHADOW_REG_SETS > 0) || \ |
||||
(defined ALT_CPU_EIC_PRESENT) || \ |
||||
(defined ALT_CPU_MMU_PRESENT) || \ |
||||
(defined ALT_CPU_MPU_PRESENT) |
||||
andi r3, r3, NIOS2_STATUS_PIE_MSK |
||||
beq r3, zero, no_unlock |
||||
rdctl r3, status |
||||
ori r3, r3, NIOS2_STATUS_PIE_MSK |
||||
wrctl status, r3 |
||||
|
||||
no_unlock: |
||||
#else |
||||
wrctl status, r3 |
||||
#endif |
||||
|
||||
#if defined(CONFIG_INSTRUMENT_THREAD_SWITCHING) |
||||
/* Also need to preserve r2, r3 as return values */ |
||||
addi sp, sp, -20 |
||||
stw ra, 16(sp) |
||||
stw fp, 12(sp) |
||||
stw r4, 8(sp) |
||||
stw r3, 4(sp) |
||||
stw r2, 0(sp) |
||||
|
||||
call z_thread_mark_switched_in |
||||
|
||||
ldw r2, 0(sp) |
||||
ldw r3, 4(sp) |
||||
ldw r4, 8(sp) |
||||
ldw fp, 12(sp) |
||||
ldw ra, 16(sp) |
||||
addi sp, sp, 20 |
||||
#endif |
||||
ret |
||||
|
||||
|
||||
/* void z_thread_entry_wrapper(void) |
||||
*/ |
||||
SECTION_FUNC(TEXT, z_thread_entry_wrapper) |
||||
/* This all corresponds to struct init_stack_frame defined in |
||||
* thread.c. We need to take this stuff off the stack and put |
||||
* it in the appropriate registers |
||||
*/ |
||||
|
||||
/* Can't return from here, just put NULL in ra */ |
||||
movi ra, 0 |
||||
|
||||
/* Calling convention has first 4 arguments in registers r4-r7. */ |
||||
ldw r4, 0(sp) |
||||
ldw r5, 4(sp) |
||||
ldw r6, 8(sp) |
||||
ldw r7, 12(sp) |
||||
|
||||
/* pop all the stuff that we just loaded into registers */ |
||||
addi sp, sp, 16 |
||||
|
||||
call z_thread_entry |
||||
|
@ -1,50 +0,0 @@
@@ -1,50 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Intel Corporation |
||||
* |
||||
* SPDX-License-Identifier: Apache-2.0 |
||||
*/ |
||||
|
||||
#include <zephyr/kernel.h> |
||||
#include <ksched.h> |
||||
|
||||
/* forward declaration to asm function to adjust setup the arguments
|
||||
* to z_thread_entry() since this arch puts the first four arguments |
||||
* in r4-r7 and not on the stack |
||||
*/ |
||||
void z_thread_entry_wrapper(k_thread_entry_t, void *, void *, void *); |
||||
|
||||
struct init_stack_frame { |
||||
/* top of the stack / most recently pushed */ |
||||
|
||||
/* Used by z_thread_entry_wrapper. pulls these off the stack and
|
||||
* into argument registers before calling z_thread_entry() |
||||
*/ |
||||
k_thread_entry_t entry_point; |
||||
void *arg1; |
||||
void *arg2; |
||||
void *arg3; |
||||
|
||||
/* least recently pushed */ |
||||
}; |
||||
|
||||
|
||||
void arch_new_thread(struct k_thread *thread, k_thread_stack_t *stack, |
||||
char *stack_ptr, k_thread_entry_t entry, |
||||
void *arg1, void *arg2, void *arg3) |
||||
{ |
||||
struct init_stack_frame *iframe; |
||||
|
||||
/* Initial stack frame data, stored at the base of the stack */ |
||||
iframe = Z_STACK_PTR_TO_FRAME(struct init_stack_frame, stack_ptr); |
||||
|
||||
/* Setup the initial stack frame */ |
||||
iframe->entry_point = entry; |
||||
iframe->arg1 = arg1; |
||||
iframe->arg2 = arg2; |
||||
iframe->arg3 = arg3; |
||||
|
||||
thread->callee_saved.sp = (uint32_t)iframe; |
||||
thread->callee_saved.ra = (uint32_t)z_thread_entry_wrapper; |
||||
thread->callee_saved.key = NIOS2_STATUS_PIE_MSK; |
||||
/* Leave the rest of thread->callee_saved junk */ |
||||
} |
@ -1,71 +0,0 @@
@@ -1,71 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2020 Intel Corporation. |
||||
* |
||||
* SPDX-License-Identifier: Apache-2.0 |
||||
*/ |
||||
|
||||
#include <zephyr/kernel.h> |
||||
#include <zephyr/sys_clock.h> |
||||
#include <zephyr/timing/timing.h> |
||||
#include "altera_avalon_timer_regs.h" |
||||
|
||||
#define NIOS2_SUBTRACT_CLOCK_CYCLES(val) \ |
||||
((IORD_ALTERA_AVALON_TIMER_PERIODH(TIMER_0_BASE) << 16 | \ |
||||
(IORD_ALTERA_AVALON_TIMER_PERIODL(TIMER_0_BASE))) - \ |
||||
((uint32_t)val)) |
||||
|
||||
#define TIMING_INFO_OS_GET_TIME() \ |
||||
(NIOS2_SUBTRACT_CLOCK_CYCLES( \ |
||||
((uint32_t)IORD_ALTERA_AVALON_TIMER_SNAPH(TIMER_0_BASE) \ |
||||
<< 16) | \ |
||||
((uint32_t)IORD_ALTERA_AVALON_TIMER_SNAPL(TIMER_0_BASE)))) |
||||
|
||||
void arch_timing_init(void) |
||||
{ |
||||
} |
||||
|
||||
void arch_timing_start(void) |
||||
{ |
||||
} |
||||
|
||||
void arch_timing_stop(void) |
||||
{ |
||||
} |
||||
|
||||
timing_t arch_timing_counter_get(void) |
||||
{ |
||||
IOWR_ALTERA_AVALON_TIMER_SNAPL(TIMER_0_BASE, 10); |
||||
return TIMING_INFO_OS_GET_TIME(); |
||||
} |
||||
|
||||
uint64_t arch_timing_cycles_get(volatile timing_t *const start, |
||||
volatile timing_t *const end) |
||||
{ |
||||
timing_t start_ = *start; |
||||
timing_t end_ = *end; |
||||
|
||||
if (end_ >= start_) { |
||||
return (end_ - start_); |
||||
} |
||||
return (end_ + NIOS2_SUBTRACT_CLOCK_CYCLES(start_)); |
||||
} |
||||
|
||||
uint64_t arch_timing_freq_get(void) |
||||
{ |
||||
return sys_clock_hw_cycles_per_sec(); |
||||
} |
||||
|
||||
uint64_t arch_timing_cycles_to_ns(uint64_t cycles) |
||||
{ |
||||
return k_cyc_to_ns_floor64(cycles); |
||||
} |
||||
|
||||
uint64_t arch_timing_cycles_to_ns_avg(uint64_t cycles, uint32_t count) |
||||
{ |
||||
return arch_timing_cycles_to_ns(cycles) / count; |
||||
} |
||||
|
||||
uint32_t arch_timing_freq_get_mhz(void) |
||||
{ |
||||
return (uint32_t)(arch_timing_freq_get() / 1000000U); |
||||
} |
@ -1,45 +0,0 @@
@@ -1,45 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Intel Corporation |
||||
* Copyright (c) 2016 Wind River Systems, Inc. |
||||
* |
||||
* SPDX-License-Identifier: Apache-2.0 |
||||
*/ |
||||
|
||||
/**
|
||||
* @file |
||||
* @brief Private kernel definitions |
||||
* |
||||
* This file contains private kernel structures definitions and various |
||||
* other definitions for the Nios II processor architecture. |
||||
* |
||||
* This file is also included by assembly language files which must #define |
||||
* _ASMLANGUAGE before including this header file. Note that kernel |
||||
* assembly source files obtains structure offset values via "absolute |
||||
* symbols" in the offsets.o module. |
||||
*/ |
||||
|
||||
#ifndef ZEPHYR_ARCH_NIOS2_INCLUDE_KERNEL_ARCH_DATA_H_ |
||||
#define ZEPHYR_ARCH_NIOS2_INCLUDE_KERNEL_ARCH_DATA_H_ |
||||
|
||||
#include <zephyr/toolchain.h> |
||||
#include <zephyr/linker/sections.h> |
||||
#include <zephyr/arch/cpu.h> |
||||
|
||||
#ifndef _ASMLANGUAGE |
||||
|
||||
#include <zephyr/kernel.h> |
||||
#include <zephyr/types.h> |
||||
#include <zephyr/sys/util.h> |
||||
#include <zephyr/sys/dlist.h> |
||||
|
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
|
||||
#ifdef __cplusplus |
||||
} |
||||
#endif |
||||
|
||||
#endif /* _ASMLANGUAGE */ |
||||
|
||||
#endif /* ZEPHYR_ARCH_NIOS2_INCLUDE_KERNEL_ARCH_DATA_H_ */ |
@ -1,80 +0,0 @@
@@ -1,80 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Intel Corporation |
||||
* |
||||
* SPDX-License-Identifier: Apache-2.0 |
||||
*/ |
||||
|
||||
/**
|
||||
* @file |
||||
* @brief Private kernel definitions |
||||
* |
||||
* This file contains private kernel function/macro definitions and various |
||||
* other definitions for the Nios II processor architecture. |
||||
* |
||||
* This file is also included by assembly language files which must #define |
||||
* _ASMLANGUAGE before including this header file. Note that kernel |
||||
* assembly source files obtains structure offset values via "absolute |
||||
* symbols" in the offsets.o module. |
||||
*/ |
||||
|
||||
#ifndef ZEPHYR_ARCH_NIOS2_INCLUDE_KERNEL_ARCH_FUNC_H_ |
||||
#define ZEPHYR_ARCH_NIOS2_INCLUDE_KERNEL_ARCH_FUNC_H_ |
||||
|
||||
#include <kernel_arch_data.h> |
||||
|
||||
#include <zephyr/platform/hooks.h> |
||||
|
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
|
||||
#ifndef _ASMLANGUAGE |
||||
|
||||
static ALWAYS_INLINE void arch_kernel_init(void) |
||||
{ |
||||
#ifdef CONFIG_SOC_PER_CORE_INIT_HOOK |
||||
soc_per_core_init_hook(); |
||||
#endif /* CONFIG_SOC_PER_CORE_INIT_HOOK */ |
||||
} |
||||
|
||||
static ALWAYS_INLINE void |
||||
arch_thread_return_value_set(struct k_thread *thread, unsigned int value) |
||||
{ |
||||
thread->callee_saved.retval = value; |
||||
} |
||||
|
||||
FUNC_NORETURN void z_nios2_fatal_error(unsigned int reason, |
||||
const struct arch_esf *esf); |
||||
|
||||
static inline bool arch_is_in_isr(void) |
||||
{ |
||||
return _kernel.cpus[0].nested != 0U; |
||||
} |
||||
|
||||
int arch_swap(unsigned int key); |
||||
|
||||
#ifdef CONFIG_IRQ_OFFLOAD |
||||
void z_irq_do_offload(void); |
||||
#endif |
||||
|
||||
#if ALT_CPU_ICACHE_SIZE > 0 |
||||
void z_nios2_icache_flush_all(void); |
||||
#else |
||||
#define z_nios2_icache_flush_all() do { } while (false) |
||||
#endif |
||||
|
||||
#if ALT_CPU_DCACHE_SIZE > 0 |
||||
void z_nios2_dcache_flush_all(void); |
||||
void z_nios2_dcache_flush_no_writeback(void *start, uint32_t len); |
||||
#else |
||||
#define z_nios2_dcache_flush_all() do { } while (false) |
||||
#define z_nios2_dcache_flush_no_writeback(x, y) do { } while (false) |
||||
#endif |
||||
|
||||
#endif /* _ASMLANGUAGE */ |
||||
|
||||
#ifdef __cplusplus |
||||
} |
||||
#endif |
||||
|
||||
#endif /* ZEPHYR_ARCH_NIOS2_INCLUDE_KERNEL_ARCH_FUNC_H_ */ |
@ -1,61 +0,0 @@
@@ -1,61 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Wind River Systems, Inc. |
||||
* |
||||
* SPDX-License-Identifier: Apache-2.0 |
||||
*/ |
||||
|
||||
#ifndef ZEPHYR_ARCH_NIOS2_INCLUDE_OFFSETS_SHORT_ARCH_H_ |
||||
#define ZEPHYR_ARCH_NIOS2_INCLUDE_OFFSETS_SHORT_ARCH_H_ |
||||
|
||||
#include <zephyr/offsets.h> |
||||
|
||||
/* kernel */ |
||||
|
||||
/* nothing for now */ |
||||
|
||||
/* end - kernel */ |
||||
|
||||
/* threads */ |
||||
|
||||
#define _thread_offset_to_r16 \ |
||||
(___thread_t_callee_saved_OFFSET + ___callee_saved_t_r16_OFFSET) |
||||
|
||||
#define _thread_offset_to_r17 \ |
||||
(___thread_t_callee_saved_OFFSET + ___callee_saved_t_r17_OFFSET) |
||||
|
||||
#define _thread_offset_to_r18 \ |
||||
(___thread_t_callee_saved_OFFSET + ___callee_saved_t_r18_OFFSET) |
||||
|
||||
#define _thread_offset_to_r19 \ |
||||
(___thread_t_callee_saved_OFFSET + ___callee_saved_t_r19_OFFSET) |
||||
|
||||
#define _thread_offset_to_r20 \ |
||||
(___thread_t_callee_saved_OFFSET + ___callee_saved_t_r20_OFFSET) |
||||
|
||||
#define _thread_offset_to_r21 \ |
||||
(___thread_t_callee_saved_OFFSET + ___callee_saved_t_r21_OFFSET) |
||||
|
||||
#define _thread_offset_to_r22 \ |
||||
(___thread_t_callee_saved_OFFSET + ___callee_saved_t_r22_OFFSET) |
||||
|
||||
#define _thread_offset_to_r23 \ |
||||
(___thread_t_callee_saved_OFFSET + ___callee_saved_t_r23_OFFSET) |
||||
|
||||
#define _thread_offset_to_r28 \ |
||||
(___thread_t_callee_saved_OFFSET + ___callee_saved_t_r28_OFFSET) |
||||
|
||||
#define _thread_offset_to_ra \ |
||||
(___thread_t_callee_saved_OFFSET + ___callee_saved_t_ra_OFFSET) |
||||
|
||||
#define _thread_offset_to_sp \ |
||||
(___thread_t_callee_saved_OFFSET + ___callee_saved_t_sp_OFFSET) |
||||
|
||||
#define _thread_offset_to_key \ |
||||
(___thread_t_callee_saved_OFFSET + ___callee_saved_t_key_OFFSET) |
||||
|
||||
#define _thread_offset_to_retval \ |
||||
(___thread_t_callee_saved_OFFSET + ___callee_saved_t_retval_OFFSET) |
||||
|
||||
/* end - threads */ |
||||
|
||||
#endif /* ZEPHYR_ARCH_NIOS2_INCLUDE_OFFSETS_SHORT_ARCH_H_ */ |
@ -1,11 +0,0 @@
@@ -1,11 +0,0 @@
|
||||
# SPDX-License-Identifier: Apache-2.0 |
||||
|
||||
config SOC_FLASH_NIOS2_QSPI |
||||
bool "Nios-II QSPI flash driver" |
||||
default y |
||||
depends on HAS_ALTERA_HAL |
||||
depends on DT_HAS_ALTR_NIOS2_QSPI_NOR_ENABLED |
||||
select FLASH_HAS_DRIVER_ENABLED |
||||
select FLASH_HAS_EXPLICIT_ERASE |
||||
help |
||||
Enables the Nios-II QSPI flash driver. |
@ -1,531 +0,0 @@
@@ -1,531 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017 Intel Corporation |
||||
* |
||||
* SPDX-License-Identifier: Apache-2.0 |
||||
*/ |
||||
|
||||
/*
|
||||
* This driver is written based on the Altera's |
||||
* Nios-II QSPI Controller HAL driver. |
||||
*/ |
||||
|
||||
#define DT_DRV_COMPAT altr_nios2_qspi_nor |
||||
|
||||
#include <zephyr/kernel.h> |
||||
#include <zephyr/device.h> |
||||
#include <string.h> |
||||
#include <zephyr/drivers/flash.h> |
||||
#include <errno.h> |
||||
#include <zephyr/init.h> |
||||
#include <soc.h> |
||||
#include <zephyr/sys/util.h> |
||||
#include "flash_priv.h" |
||||
#include "altera_generic_quad_spi_controller2_regs.h" |
||||
#include "altera_generic_quad_spi_controller2.h" |
||||
|
||||
#define LOG_LEVEL CONFIG_FLASH_LOG_LEVEL |
||||
#include <zephyr/logging/log.h> |
||||
LOG_MODULE_REGISTER(flash_nios2_qspi); |
||||
|
||||
/*
|
||||
* Remove the following macros once the Altera HAL |
||||
* supports the QSPI Controller v2 IP. |
||||
*/ |
||||
#define ALTERA_QSPI_CONTROLLER2_FLAG_STATUS_REG 0x0000001C |
||||
#define FLAG_STATUS_PROTECTION_ERROR (1 << 1) |
||||
#define FLAG_STATUS_PROGRAM_SUSPENDED (1 << 2) |
||||
#define FLAG_STATUS_PROGRAM_ERROR (1 << 4) |
||||
#define FLAG_STATUS_ERASE_ERROR (1 << 5) |
||||
#define FLAG_STATUS_ERASE_SUSPENDED (1 << 6) |
||||
#define FLAG_STATUS_CONTROLLER_READY (1 << 7) |
||||
|
||||
/* ALTERA_QSPI_CONTROLLER2_STATUS_REG bits */ |
||||
#define STATUS_PROTECTION_POS 2 |
||||
#define STATUS_PROTECTION_MASK 0x1F |
||||
#define STATUS_PROTECTION_EN_VAL 0x17 |
||||
#define STATUS_PROTECTION_DIS_VAL 0x0 |
||||
|
||||
/* ALTERA_QSPI_CONTROLLER2_MEM_OP_REG bits */ |
||||
#define MEM_OP_ERASE_CMD 0x00000002 |
||||
#define MEM_OP_WRITE_EN_CMD 0x00000004 |
||||
#define MEM_OP_SECTOR_OFFSET_BIT_POS 8 |
||||
#define MEM_OP_UNLOCK_ALL_SECTORS 0x00000003 |
||||
#define MEM_OP_LOCK_ALL_SECTORS 0x00000F03 |
||||
|
||||
#define NIOS2_QSPI_BLANK_WORD 0xFFFFFFFF |
||||
|
||||
#define NIOS2_WRITE_BLOCK_SIZE 4 |
||||
|
||||
#define USEC_TO_MSEC(x) (x / 1000) |
||||
|
||||
struct flash_nios2_qspi_config { |
||||
alt_qspi_controller2_dev qspi_dev; |
||||
struct k_sem sem_lock; |
||||
}; |
||||
|
||||
static const struct flash_parameters flash_nios2_qspi_parameters = { |
||||
.write_block_size = NIOS2_WRITE_BLOCK_SIZE, |
||||
.erase_value = 0xff, |
||||
}; |
||||
|
||||
static int flash_nios2_qspi_write_protection(const struct device *dev, |
||||
bool enable); |
||||
|
||||
static int flash_nios2_qspi_erase(const struct device *dev, off_t offset, |
||||
size_t len) |
||||
{ |
||||
struct flash_nios2_qspi_config *flash_cfg = dev->data; |
||||
alt_qspi_controller2_dev *qspi_dev = &flash_cfg->qspi_dev; |
||||
uint32_t block_offset, offset_in_block, length_to_erase; |
||||
uint32_t erase_offset = offset; /* address of next byte to erase */ |
||||
uint32_t remaining_length = len; /* length of data left to be erased */ |
||||
uint32_t flag_status; |
||||
int32_t rc = 0, i, timeout, rc2; |
||||
|
||||
k_sem_take(&flash_cfg->sem_lock, K_FOREVER); |
||||
|
||||
rc = flash_nios2_qspi_write_protection(dev, false); |
||||
if (rc) { |
||||
goto qspi_erase_err; |
||||
} |
||||
/*
|
||||
* check if offset is word aligned and |
||||
* length is with in the range |
||||
*/ |
||||
if (((offset + len) > qspi_dev->data_end) || |
||||
(0 != (erase_offset & |
||||
(NIOS2_WRITE_BLOCK_SIZE - 1)))) { |
||||
LOG_ERR("erase failed at offset 0x%lx", (long)offset); |
||||
rc = -EINVAL; |
||||
goto qspi_erase_err; |
||||
} |
||||
|
||||
for (i = offset/qspi_dev->sector_size; |
||||
i < qspi_dev->number_of_sectors; i++) { |
||||
|
||||
if ((remaining_length <= 0U) || |
||||
erase_offset >= (offset + len)) { |
||||
break; |
||||
} |
||||
|
||||
block_offset = 0U; /* block offset in byte addressing */ |
||||
offset_in_block = 0U; /* offset into current sector to erase */ |
||||
length_to_erase = 0U; /* length to erase in current sector */ |
||||
|
||||
/* calculate current sector/block offset in byte addressing */ |
||||
block_offset = erase_offset & ~(qspi_dev->sector_size - 1); |
||||
|
||||
/* calculate offset into sector/block if there is one */ |
||||
if (block_offset != erase_offset) { |
||||
offset_in_block = erase_offset - block_offset; |
||||
} |
||||
|
||||
/* calculate the byte size of data to be written in a sector */ |
||||
length_to_erase = MIN(qspi_dev->sector_size - offset_in_block, |
||||
remaining_length); |
||||
|
||||
/* Erase sector */ |
||||
IOWR_32DIRECT(qspi_dev->csr_base, |
||||
ALTERA_QSPI_CONTROLLER2_MEM_OP_REG, |
||||
MEM_OP_WRITE_EN_CMD); |
||||
IOWR_32DIRECT(qspi_dev->csr_base, |
||||
ALTERA_QSPI_CONTROLLER2_MEM_OP_REG, |
||||
(i << MEM_OP_SECTOR_OFFSET_BIT_POS) |
||||
| MEM_OP_ERASE_CMD); |
||||
|
||||
/*
|
||||
* poll the status register to know the |
||||
* completion of the erase operation. |
||||
*/ |
||||
timeout = ALTERA_QSPI_CONTROLLER2_1US_TIMEOUT_VALUE; |
||||
while (timeout > 0) { |
||||
/* wait for 1 usec */ |
||||
k_busy_wait(1); |
||||
|
||||
flag_status = IORD_32DIRECT(qspi_dev->csr_base, |
||||
ALTERA_QSPI_CONTROLLER2_FLAG_STATUS_REG); |
||||
|
||||
if (flag_status & FLAG_STATUS_CONTROLLER_READY) { |
||||
break; |
||||
} |
||||
|
||||
timeout--; |
||||
} |
||||
|
||||
if ((flag_status & FLAG_STATUS_ERASE_ERROR) || |
||||
(flag_status & FLAG_STATUS_PROTECTION_ERROR)) { |
||||
LOG_ERR("erase failed, Flag Status Reg:0x%x", |
||||
flag_status); |
||||
rc = -EIO; |
||||
goto qspi_erase_err; |
||||
} |
||||
|
||||
/* update remaining length and erase_offset */ |
||||
remaining_length -= length_to_erase; |
||||
erase_offset += length_to_erase; |
||||
} |
||||
|
||||
qspi_erase_err: |
||||
rc2 = flash_nios2_qspi_write_protection(dev, true); |
||||
|
||||
if (!rc) { |
||||
rc = rc2; |
||||
} |
||||
|
||||
k_sem_give(&flash_cfg->sem_lock); |
||||
return rc; |
||||
|
||||
} |
||||
|
||||
static int flash_nios2_qspi_write_block(const struct device *dev, |
||||
int block_offset, |
||||
int mem_offset, const void *data, |
||||
size_t len) |
||||
{ |
||||
struct flash_nios2_qspi_config *flash_cfg = dev->data; |
||||
alt_qspi_controller2_dev *qspi_dev = &flash_cfg->qspi_dev; |
||||
uint32_t buffer_offset = 0U; /* offset into data buffer to get write data */ |
||||
int32_t remaining_length = len; /* length left to write */ |
||||
uint32_t write_offset = mem_offset; /* offset into flash to write too */ |
||||
uint32_t word_to_write, padding, bytes_to_copy; |
||||
uint32_t flag_status; |
||||
int32_t rc = 0; |
||||
|
||||
while (remaining_length > 0) { |
||||
/* initialize word to write to blank word */ |
||||
word_to_write = NIOS2_QSPI_BLANK_WORD; |
||||
|
||||
/* bytes to pad the next word that is written */ |
||||
padding = 0U; |
||||
|
||||
/* number of bytes from source to copy */ |
||||
bytes_to_copy = NIOS2_WRITE_BLOCK_SIZE; |
||||
|
||||
/*
|
||||
* we need to make sure the write is word aligned |
||||
* this should only be true at most 1 time |
||||
*/ |
||||
if (0 != (write_offset & (NIOS2_WRITE_BLOCK_SIZE - 1))) { |
||||
/*
|
||||
* data is not word aligned calculate padding bytes |
||||
* need to add before start of a data offset |
||||
*/ |
||||
padding = write_offset & (NIOS2_WRITE_BLOCK_SIZE - 1); |
||||
|
||||
/*
|
||||
* update variables to account |
||||
* for padding being added |
||||
*/ |
||||
bytes_to_copy -= padding; |
||||
|
||||
if (bytes_to_copy > remaining_length) { |
||||
bytes_to_copy = remaining_length; |
||||
} |
||||
|
||||
write_offset = write_offset - padding; |
||||
|
||||
if (0 != (write_offset & |
||||
(NIOS2_WRITE_BLOCK_SIZE - 1))) { |
||||
rc = -EINVAL; |
||||
goto qspi_write_block_err; |
||||
} |
||||
} else { |
||||
if (bytes_to_copy > remaining_length) { |
||||
bytes_to_copy = remaining_length; |
||||
} |
||||
} |
||||
|
||||
/* Check memcpy length is within NIOS2_WRITE_BLOCK_SIZE */ |
||||
if (padding + bytes_to_copy > NIOS2_WRITE_BLOCK_SIZE) { |
||||
rc = -EINVAL; |
||||
goto qspi_write_block_err; |
||||
} |
||||
|
||||
/* prepare the word to be written */ |
||||
memcpy((uint8_t *)&word_to_write + padding, |
||||
(const uint8_t *)data + buffer_offset, |
||||
bytes_to_copy); |
||||
|
||||
/* enable write */ |
||||
IOWR_32DIRECT(qspi_dev->csr_base, |
||||
ALTERA_QSPI_CONTROLLER2_MEM_OP_REG, |
||||
MEM_OP_WRITE_EN_CMD); |
||||
|
||||
/* write to flash 32 bits at a time */ |
||||
IOWR_32DIRECT(qspi_dev->data_base, write_offset, word_to_write); |
||||
|
||||
/* check whether write operation is successful */ |
||||
flag_status = IORD_32DIRECT(qspi_dev->csr_base, |
||||
ALTERA_QSPI_CONTROLLER2_FLAG_STATUS_REG); |
||||
|
||||
if ((flag_status & FLAG_STATUS_PROGRAM_ERROR) || |
||||
(flag_status & FLAG_STATUS_PROTECTION_ERROR)) { |
||||
LOG_ERR("write failed, Flag Status Reg:0x%x", |
||||
flag_status); |
||||
rc = -EIO; /* sector might be protected */ |
||||
goto qspi_write_block_err; |
||||
} |
||||
|
||||
/* update offset and length variables */ |
||||
buffer_offset += bytes_to_copy; |
||||
remaining_length -= bytes_to_copy; |
||||
write_offset = write_offset + NIOS2_WRITE_BLOCK_SIZE; |
||||
} |
||||
|
||||
qspi_write_block_err: |
||||
return rc; |
||||
} |
||||
|
||||
static int flash_nios2_qspi_write(const struct device *dev, off_t offset, |
||||
const void *data, size_t len) |
||||
{ |
||||
struct flash_nios2_qspi_config *flash_cfg = dev->data; |
||||
alt_qspi_controller2_dev *qspi_dev = &flash_cfg->qspi_dev; |
||||
uint32_t block_offset, offset_in_block, length_to_write; |
||||
uint32_t write_offset = offset; /* address of next byte to write */ |
||||
uint32_t buffer_offset = 0U; /* offset into source buffer */ |
||||
uint32_t remaining_length = len; /* length of data left to be written */ |
||||
int32_t rc = 0, i, rc2; |
||||
|
||||
k_sem_take(&flash_cfg->sem_lock, K_FOREVER); |
||||
|
||||
rc = flash_nios2_qspi_write_protection(dev, false); |
||||
if (rc) { |
||||
goto qspi_write_err; |
||||
} |
||||
/*
|
||||
* check if offset is word aligned and |
||||
* length is with in the range |
||||
*/ |
||||
if ((data == NULL) || ((offset + len) > qspi_dev->data_end) || |
||||
(0 != (write_offset & |
||||
(NIOS2_WRITE_BLOCK_SIZE - 1)))) { |
||||
LOG_ERR("write failed at offset 0x%lx", (long)offset); |
||||
rc = -EINVAL; |
||||
goto qspi_write_err; |
||||
} |
||||
|
||||
for (i = offset/qspi_dev->sector_size; |
||||
i < qspi_dev->number_of_sectors; i++) { |
||||
|
||||
if (remaining_length <= 0U) { |
||||
break; |
||||
} |
||||
|
||||
block_offset = 0U; /* block offset in byte addressing */ |
||||
offset_in_block = 0U; /* offset into current sector to write */ |
||||
length_to_write = 0U; /* length to write to current sector */ |
||||
|
||||
/* calculate current sector/block offset in byte addressing */ |
||||
block_offset = write_offset & ~(qspi_dev->sector_size - 1); |
||||
|
||||
/* calculate offset into sector/block if there is one */ |
||||
if (block_offset != write_offset) { |
||||
offset_in_block = write_offset - block_offset; |
||||
} |
||||
|
||||
/* calculate the byte size of data to be written in a sector */ |
||||
length_to_write = MIN(qspi_dev->sector_size - offset_in_block, |
||||
remaining_length); |
||||
|
||||
rc = flash_nios2_qspi_write_block(dev, |
||||
block_offset, write_offset, |
||||
(const uint8_t *)data + buffer_offset, |
||||
length_to_write); |
||||
if (rc < 0) { |
||||
goto qspi_write_err; |
||||
} |
||||
|
||||
/* update remaining length and buffer_offset */ |
||||
remaining_length -= length_to_write; |
||||
buffer_offset += length_to_write; |
||||
write_offset += length_to_write; |
||||
} |
||||
|
||||
qspi_write_err: |
||||
rc2 = flash_nios2_qspi_write_protection(dev, true); |
||||
|
||||
if (!rc) { |
||||
rc = rc2; |
||||
} |
||||
|
||||
k_sem_give(&flash_cfg->sem_lock); |
||||
return rc; |
||||
} |
||||
|
||||
static int flash_nios2_qspi_read(const struct device *dev, off_t offset, |
||||
void *data, size_t len) |
||||
{ |
||||
struct flash_nios2_qspi_config *flash_cfg = dev->data; |
||||
alt_qspi_controller2_dev *qspi_dev = &flash_cfg->qspi_dev; |
||||
uint32_t buffer_offset = 0U; /* offset into data buffer to get read data */ |
||||
uint32_t remaining_length = len; /* length left to read */ |
||||
uint32_t read_offset = offset; /* offset into flash to read from */ |
||||
uint32_t word_to_read, bytes_to_copy; |
||||
int32_t rc = 0; |
||||
|
||||
/*
|
||||
* check if offset and length are within the range |
||||
*/ |
||||
if ((data == NULL) || (offset < qspi_dev->data_base) || |
||||
((offset + len) > qspi_dev->data_end)) { |
||||
LOG_ERR("read failed at offset 0x%lx", (long)offset); |
||||
return -EINVAL; |
||||
} |
||||
|
||||
if (!len) { |
||||
return 0; |
||||
} |
||||
|
||||
k_sem_take(&flash_cfg->sem_lock, K_FOREVER); |
||||
|
||||
/* first unaligned start */ |
||||
read_offset &= ~(NIOS2_WRITE_BLOCK_SIZE - 1U); |
||||
if (offset > read_offset) { |
||||
/* number of bytes from source to copy */ |
||||
bytes_to_copy = NIOS2_WRITE_BLOCK_SIZE - (offset - read_offset); |
||||
if (bytes_to_copy > remaining_length) { |
||||
bytes_to_copy = remaining_length; |
||||
} |
||||
/* read from flash 32 bits at a time */ |
||||
word_to_read = IORD_32DIRECT(qspi_dev->data_base, read_offset); |
||||
memcpy((uint8_t *)data, (uint8_t *)&word_to_read + offset - |
||||
read_offset, bytes_to_copy); |
||||
/* update offset and length variables */ |
||||
read_offset += NIOS2_WRITE_BLOCK_SIZE; |
||||
buffer_offset += bytes_to_copy; |
||||
remaining_length -= bytes_to_copy; |
||||
} |
||||
|
||||
/* aligned part, including unaligned end */ |
||||
while (remaining_length > 0) { |
||||
/* number of bytes from source to copy */ |
||||
bytes_to_copy = NIOS2_WRITE_BLOCK_SIZE; |
||||
|
||||
if (bytes_to_copy > remaining_length) { |
||||
bytes_to_copy = remaining_length; |
||||
} |
||||
|
||||
/* read from flash 32 bits at a time */ |
||||
word_to_read = IORD_32DIRECT(qspi_dev->data_base, read_offset); |
||||
memcpy((uint8_t *)data + buffer_offset, &word_to_read, |
||||
bytes_to_copy); |
||||
/* update offset and length variables */ |
||||
read_offset += bytes_to_copy; |
||||
buffer_offset += bytes_to_copy; |
||||
remaining_length -= bytes_to_copy; |
||||
} |
||||
|
||||
k_sem_give(&flash_cfg->sem_lock); |
||||
return rc; |
||||
} |
||||
|
||||
static int flash_nios2_qspi_write_protection(const struct device *dev, |
||||
bool enable) |
||||
{ |
||||
struct flash_nios2_qspi_config *flash_cfg = dev->data; |
||||
alt_qspi_controller2_dev *qspi_dev = &flash_cfg->qspi_dev; |
||||
uint32_t status, lock_val; |
||||
int32_t rc = 0, timeout; |
||||
|
||||
/* set write enable */ |
||||
IOWR_32DIRECT(qspi_dev->csr_base, |
||||
ALTERA_QSPI_CONTROLLER2_MEM_OP_REG, |
||||
MEM_OP_WRITE_EN_CMD); |
||||
if (enable) { |
||||
IOWR_32DIRECT(qspi_dev->csr_base, |
||||
ALTERA_QSPI_CONTROLLER2_MEM_OP_REG, |
||||
MEM_OP_LOCK_ALL_SECTORS); |
||||
lock_val = STATUS_PROTECTION_EN_VAL; |
||||
} else { |
||||
IOWR_32DIRECT(qspi_dev->csr_base, |
||||
ALTERA_QSPI_CONTROLLER2_MEM_OP_REG, |
||||
MEM_OP_UNLOCK_ALL_SECTORS); |
||||
lock_val = STATUS_PROTECTION_DIS_VAL; |
||||
} |
||||
|
||||
/*
|
||||
* poll the status register to know the |
||||
* completion of the erase operation. |
||||
*/ |
||||
timeout = ALTERA_QSPI_CONTROLLER2_1US_TIMEOUT_VALUE; |
||||
while (timeout > 0) { |
||||
/* wait for 1 usec */ |
||||
k_busy_wait(1); |
||||
|
||||
/*
|
||||
* read flash flag status register before |
||||
* checking the QSPI status |
||||
*/ |
||||
IORD_32DIRECT(qspi_dev->csr_base, |
||||
ALTERA_QSPI_CONTROLLER2_FLAG_STATUS_REG); |
||||
|
||||
/* read QPSI status register */ |
||||
status = IORD_32DIRECT(qspi_dev->csr_base, |
||||
ALTERA_QSPI_CONTROLLER2_STATUS_REG); |
||||
if (((status >> STATUS_PROTECTION_POS) & |
||||
STATUS_PROTECTION_MASK) == lock_val) { |
||||
break; |
||||
} |
||||
|
||||
timeout--; |
||||
} |
||||
|
||||
if (timeout <= 0) { |
||||
LOG_ERR("locking failed, status-reg 0x%x", status); |
||||
rc = -EIO; |
||||
} |
||||
|
||||
/* clear flag status register */ |
||||
IOWR_32DIRECT(qspi_dev->csr_base, |
||||
ALTERA_QSPI_CONTROLLER2_FLAG_STATUS_REG, 0x0); |
||||
return rc; |
||||
} |
||||
|
||||
static const struct flash_parameters * |
||||
flash_nios2_qspi_get_parameters(const struct device *dev) |
||||
{ |
||||
ARG_UNUSED(dev); |
||||
|
||||
return &flash_nios2_qspi_parameters; |
||||
} |
||||
|
||||
static DEVICE_API(flash, flash_nios2_qspi_api) = { |
||||
.erase = flash_nios2_qspi_erase, |
||||
.write = flash_nios2_qspi_write, |
||||
.read = flash_nios2_qspi_read, |
||||
.get_parameters = flash_nios2_qspi_get_parameters, |
||||
#if defined(CONFIG_FLASH_PAGE_LAYOUT) |
||||
.page_layout = (flash_api_pages_layout) |
||||
flash_page_layout_not_implemented, |
||||
#endif |
||||
}; |
||||
|
||||
static int flash_nios2_qspi_init(const struct device *dev) |
||||
{ |
||||
struct flash_nios2_qspi_config *flash_cfg = dev->data; |
||||
|
||||
k_sem_init(&flash_cfg->sem_lock, 1, 1); |
||||
return 0; |
||||
} |
||||
|
||||
struct flash_nios2_qspi_config flash_cfg = { |
||||
.qspi_dev = { |
||||
.data_base = EXT_FLASH_AVL_MEM_BASE, |
||||
.data_end = EXT_FLASH_AVL_MEM_BASE + EXT_FLASH_AVL_MEM_SPAN, |
||||
.csr_base = EXT_FLASH_AVL_CSR_BASE, |
||||
.size_in_bytes = EXT_FLASH_AVL_MEM_SPAN, |
||||
.is_epcs = EXT_FLASH_AVL_MEM_IS_EPCS, |
||||
.number_of_sectors = EXT_FLASH_AVL_MEM_NUMBER_OF_SECTORS, |
||||
.sector_size = EXT_FLASH_AVL_MEM_SECTOR_SIZE, |
||||
.page_size = EXT_FLASH_AVL_MEM_PAGE_SIZE, |
||||
} |
||||
}; |
||||
|
||||
BUILD_ASSERT(DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) == 1, |
||||
"only one 'altr,nios2-qspi-nor' compatible node may be present"); |
||||
|
||||
DEVICE_DT_INST_DEFINE(0, |
||||
flash_nios2_qspi_init, NULL, &flash_cfg, NULL, |
||||
POST_KERNEL, CONFIG_FLASH_INIT_PRIORITY, |
||||
&flash_nios2_qspi_api); |
@ -1,14 +0,0 @@
@@ -1,14 +0,0 @@
|
||||
# Copyright (c) 2014-2015 Wind River Systems, Inc. |
||||
# Copyright (c) 2016 Cadence Design Systems, Inc. |
||||
# Copyright (c) 2019 Intel Corp. |
||||
# SPDX-License-Identifier: Apache-2.0 |
||||
|
||||
config ALTERA_AVALON_TIMER |
||||
bool "Altera Avalon Interval Timer" |
||||
default y |
||||
depends on NIOS2 |
||||
help |
||||
This module implements a kernel device driver for the Altera Avalon |
||||
Interval Timer as described in the Embedded IP documentation, for use |
||||
with Nios II and possibly other Altera soft CPUs. It provides the |
||||
standard "system clock driver" interfaces. |
@ -1,94 +0,0 @@
@@ -1,94 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017 Intel Corporation |
||||
* |
||||
* SPDX-License-Identifier: Apache-2.0 |
||||
*/ |
||||
|
||||
#include <zephyr/kernel.h> |
||||
#include <zephyr/arch/cpu.h> |
||||
#include <zephyr/init.h> |
||||
#include <zephyr/drivers/timer/system_timer.h> |
||||
#include <altera_common.h> |
||||
#include <zephyr/irq.h> |
||||
|
||||
#include "altera_avalon_timer_regs.h" |
||||
#include "altera_avalon_timer.h" |
||||
|
||||
/* The old driver "now" API would return a full uptime value. The new
|
||||
* one only requires the driver to track ticks since the last announce |
||||
* call. Implement the new call in terms of the old one on legacy |
||||
* drivers by keeping (yet another) uptime value locally. |
||||
*/ |
||||
static uint32_t driver_uptime; |
||||
|
||||
static uint32_t accumulated_cycle_count; |
||||
|
||||
static int32_t _sys_idle_elapsed_ticks = 1; |
||||
|
||||
#if defined(CONFIG_TEST) |
||||
const int32_t z_sys_timer_irq_for_test = TIMER_0_IRQ; |
||||
#endif |
||||
|
||||
static void wrapped_announce(int32_t ticks) |
||||
{ |
||||
driver_uptime += ticks; |
||||
sys_clock_announce(ticks); |
||||
} |
||||
|
||||
static void timer_irq_handler(const void *unused) |
||||
{ |
||||
ARG_UNUSED(unused); |
||||
|
||||
accumulated_cycle_count += k_ticks_to_cyc_floor32(1); |
||||
|
||||
/* Clear the interrupt */ |
||||
alt_handle_irq((void *)TIMER_0_BASE, TIMER_0_IRQ); |
||||
|
||||
wrapped_announce(_sys_idle_elapsed_ticks); |
||||
} |
||||
|
||||
uint32_t sys_clock_cycle_get_32(void) |
||||
{ |
||||
/* Per the Altera Embedded IP Peripherals guide, you cannot
|
||||
* use a timer instance for both the system clock and timestamps |
||||
* at the same time. |
||||
* |
||||
* Having this function return accumulated_cycle_count + get_snapshot() |
||||
* does not work reliably. It's possible for the current countdown |
||||
* to reset to the next interval before the timer interrupt is |
||||
* delivered (and accumulated cycle count gets updated). The result |
||||
* is an unlucky call to this function will appear to jump backward |
||||
* in time. |
||||
* |
||||
* To properly obtain timestamps, the CPU must be configured with |
||||
* a second timer peripheral instance that is configured to |
||||
* count down from some large initial 64-bit value. This |
||||
* is currently unimplemented. |
||||
*/ |
||||
return accumulated_cycle_count; |
||||
} |
||||
|
||||
uint32_t sys_clock_elapsed(void) |
||||
{ |
||||
return 0; |
||||
} |
||||
|
||||
static int sys_clock_driver_init(void) |
||||
{ |
||||
|
||||
IOWR_ALTERA_AVALON_TIMER_PERIODL(TIMER_0_BASE, |
||||
k_ticks_to_cyc_floor32(1) & 0xFFFF); |
||||
IOWR_ALTERA_AVALON_TIMER_PERIODH(TIMER_0_BASE, |
||||
(k_ticks_to_cyc_floor32(1) >> 16) & 0xFFFF); |
||||
|
||||
IRQ_CONNECT(TIMER_0_IRQ, 0, timer_irq_handler, NULL, 0); |
||||
irq_enable(TIMER_0_IRQ); |
||||
|
||||
alt_avalon_timer_sc_init((void *)TIMER_0_BASE, 0, |
||||
TIMER_0_IRQ, k_ticks_to_cyc_floor32(1)); |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
SYS_INIT(sys_clock_driver_init, PRE_KERNEL_2, |
||||
CONFIG_SYSTEM_CLOCK_INIT_PRIORITY); |
@ -1,15 +0,0 @@
@@ -1,15 +0,0 @@
|
||||
# Copyright (c) 2018 Nordic Semiconductor ASA |
||||
# SPDX-License-Identifier: Apache-2.0 |
||||
|
||||
description: Altera NIOS-2F CPU |
||||
|
||||
compatible: "altr,nios2f" |
||||
|
||||
include: [interrupt-controller.yaml, base.yaml] |
||||
|
||||
properties: |
||||
"#interrupt-cells": |
||||
const: 1 |
||||
|
||||
interrupt-cells: |
||||
- irq |
@ -1,15 +0,0 @@
@@ -1,15 +0,0 @@
|
||||
# Copyright (c) 2020 Nordic Semiconductor ASA |
||||
# SPDX-License-Identifier: Apache-2.0 |
||||
|
||||
description: QEMU NIOS2 Zephyr CPU |
||||
|
||||
compatible: "qemu,nios2-zephyr" |
||||
|
||||
include: [interrupt-controller.yaml, base.yaml] |
||||
|
||||
properties: |
||||
"#interrupt-cells": |
||||
const: 1 |
||||
|
||||
interrupt-cells: |
||||
- irq |
@ -1,52 +0,0 @@
@@ -1,52 +0,0 @@
|
||||
/* SPDX-License-Identifier: Apache-2.0 */ |
||||
|
||||
#include "skeleton.dtsi" |
||||
|
||||
/ { |
||||
cpus { |
||||
#address-cells = <1>; |
||||
#size-cells = <0>; |
||||
|
||||
cpu: cpu@0 { |
||||
device_type = "cpu"; |
||||
compatible = "qemu,nios2-zephyr"; |
||||
reg = <0>; |
||||
interrupt-controller; |
||||
#interrupt-cells = <1>; |
||||
}; |
||||
}; |
||||
|
||||
flash0: flash@420000 { |
||||
compatible = "soc-nv-flash"; |
||||
reg = <0x420000 0x20000>; |
||||
}; |
||||
|
||||
sram0: memory@400000 { |
||||
compatible = "mmio-sram"; |
||||
reg = <0x400000 0x20000>; |
||||
}; |
||||
|
||||
soc { |
||||
#address-cells = <1>; |
||||
#size-cells = <1>; |
||||
compatible = "simple-bus"; |
||||
interrupt-parent = <&cpu>; |
||||
ranges; |
||||
|
||||
jtag_uart: uart@201000 { |
||||
compatible = "altr,jtag-uart"; |
||||
reg = <0x201000 0x400>; |
||||
interrupts = <0>; |
||||
status = "disabled"; |
||||
}; |
||||
|
||||
ns16550_uart: uart@440000 { |
||||
compatible = "ns16550"; |
||||
reg = <0x440000 0x400>; |
||||
interrupts = <1>; |
||||
clock-frequency = <50000000>; |
||||
reg-shift = <2>; |
||||
status = "disabled"; |
||||
}; |
||||
}; |
||||
}; |
@ -1,79 +0,0 @@
@@ -1,79 +0,0 @@
|
||||
/* SPDX-License-Identifier: Apache-2.0 */ |
||||
|
||||
#include "skeleton.dtsi" |
||||
#include <zephyr/dt-bindings/i2c/i2c.h> |
||||
|
||||
/ { |
||||
cpus { |
||||
#address-cells = <1>; |
||||
#size-cells = <0>; |
||||
|
||||
cpu: cpu@0 { |
||||
device_type = "cpu"; |
||||
compatible = "altr,nios2f"; |
||||
reg = <0>; |
||||
interrupt-controller; |
||||
#interrupt-cells = <1>; |
||||
}; |
||||
}; |
||||
|
||||
flash0: flash@0 { |
||||
compatible = "soc-nv-flash"; |
||||
reg = <0x00 0xb8000>; |
||||
}; |
||||
|
||||
sram0: memory@400000 { |
||||
compatible = "mmio-sram"; |
||||
reg = <0x400000 0x20000>; |
||||
}; |
||||
|
||||
soc { |
||||
#address-cells = <1>; |
||||
#size-cells = <1>; |
||||
compatible = "simple-bus"; |
||||
interrupt-parent = <&cpu>; |
||||
ranges; |
||||
|
||||
uart0: uart@100000 { |
||||
compatible = "ns16550"; |
||||
reg = <0x100000 0x400>; |
||||
clock-frequency = <50000000>; |
||||
interrupts = <1 0>; |
||||
reg-shift = <2>; |
||||
status = "disabled"; |
||||
}; |
||||
|
||||
jtag_uart: uart@201000 { |
||||
compatible = "altr,jtag-uart"; |
||||
reg = <0x201000 0x8>; |
||||
|
||||
status = "disabled"; |
||||
}; |
||||
|
||||
i2c0: i2c@100200 { |
||||
compatible = "altr,nios2-i2c"; |
||||
clock-frequency = <I2C_BITRATE_ULTRA>; |
||||
#address-cells = <1>; |
||||
#size-cells = <0>; |
||||
reg = <0x100200 0x400>; |
||||
interrupts = <4 10>; |
||||
}; |
||||
|
||||
dma: dma@1002c0 { |
||||
compatible = "altr,msgdma"; |
||||
reg = <0x1002c0 0x30>; |
||||
interrupts = <3 3>; |
||||
#dma-cells = <0>; |
||||
}; |
||||
|
||||
|
||||
qspi: qspi@100240 { |
||||
compatible = "altr,nios2-qspi"; |
||||
#address-cells = <1>; |
||||
#size-cells = <0>; |
||||
reg = <0x100240 0x40>, <0x8000000 0x4000000>; |
||||
reg-names = "qspi", "qspi_mm"; |
||||
status = "disabled"; |
||||
}; |
||||
}; |
||||
}; |
@ -1,175 +0,0 @@
@@ -1,175 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Intel Corporation |
||||
* |
||||
* SPDX-License-Identifier: Apache-2.0 |
||||
*/ |
||||
|
||||
/**
|
||||
* @file |
||||
* @brief Nios II specific kernel interface header |
||||
* This header contains the Nios II specific kernel interface. It is |
||||
* included by the generic kernel interface header (include/arch/cpu.h) |
||||
*/ |
||||
|
||||
#ifndef ZEPHYR_INCLUDE_ARCH_NIOS2_ARCH_H_ |
||||
#define ZEPHYR_INCLUDE_ARCH_NIOS2_ARCH_H_ |
||||
|
||||
#include <system.h> |
||||
|
||||
#include <zephyr/arch/nios2/thread.h> |
||||
#include <zephyr/arch/nios2/exception.h> |
||||
#include <zephyr/arch/nios2/asm_inline.h> |
||||
#include <zephyr/arch/common/addr_types.h> |
||||
#include <zephyr/devicetree.h> |
||||
#include <zephyr/arch/nios2/nios2.h> |
||||
#include <zephyr/arch/common/sys_bitops.h> |
||||
#include <zephyr/sys/sys_io.h> |
||||
#include <zephyr/arch/common/ffs.h> |
||||
|
||||
#define ARCH_STACK_PTR_ALIGN 4 |
||||
|
||||
#ifndef _ASMLANGUAGE |
||||
#include <zephyr/types.h> |
||||
#include <zephyr/irq.h> |
||||
#include <zephyr/sw_isr_table.h> |
||||
|
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
|
||||
/* There is no notion of priority with the Nios II internal interrupt
|
||||
* controller and no flags are currently supported. |
||||
*/ |
||||
#define ARCH_IRQ_CONNECT(irq_p, priority_p, isr_p, isr_param_p, flags_p) \ |
||||
{ \ |
||||
Z_ISR_DECLARE(irq_p, 0, isr_p, isr_param_p); \ |
||||
} |
||||
|
||||
static ALWAYS_INLINE unsigned int arch_irq_lock(void) |
||||
{ |
||||
unsigned int key, tmp; |
||||
|
||||
__asm__ volatile ( |
||||
"rdctl %[key], status\n\t" |
||||
"movi %[tmp], -2\n\t" |
||||
"and %[tmp], %[key], %[tmp]\n\t" |
||||
"wrctl status, %[tmp]\n\t" |
||||
: [key] "=r" (key), [tmp] "=r" (tmp) |
||||
: : "memory"); |
||||
|
||||
return key; |
||||
} |
||||
|
||||
static ALWAYS_INLINE void arch_irq_unlock(unsigned int key) |
||||
{ |
||||
/* If the CPU is built without certain features, then
|
||||
* the only writable bit in the status register is PIE |
||||
* in which case we can just write the value stored in key, |
||||
* all the other writable bits will be the same. |
||||
* |
||||
* If not, other stuff could have changed and we need to |
||||
* specifically flip just that bit. |
||||
*/ |
||||
|
||||
#if (ALT_CPU_NUM_OF_SHADOW_REG_SETS > 0) || \ |
||||
(defined ALT_CPU_EIC_PRESENT) || \ |
||||
(defined ALT_CPU_MMU_PRESENT) || \ |
||||
(defined ALT_CPU_MPU_PRESENT) |
||||
__asm__ volatile ( |
||||
"andi %[key], %[key], 1\n\t" |
||||
"beq %[key], zero, 1f\n\t" |
||||
"rdctl %[key], status\n\t" |
||||
"ori %[key], %[key], 1\n\t" |
||||
"wrctl status, %[key]\n\t" |
||||
"1:\n\t" |
||||
: [key] "+r" (key) |
||||
: : "memory"); |
||||
#else |
||||
__asm__ volatile ( |
||||
"wrctl status, %[key]" |
||||
: : [key] "r" (key) |
||||
: "memory"); |
||||
#endif |
||||
} |
||||
|
||||
static ALWAYS_INLINE bool arch_irq_unlocked(unsigned int key) |
||||
{ |
||||
return key & 1; |
||||
} |
||||
|
||||
void arch_irq_enable(unsigned int irq); |
||||
void arch_irq_disable(unsigned int irq); |
||||
|
||||
FUNC_NORETURN void z_SysFatalErrorHandler(unsigned int reason, |
||||
const struct arch_esf *esf); |
||||
|
||||
FUNC_NORETURN void z_NanoFatalErrorHandler(unsigned int reason, |
||||
const struct arch_esf *esf); |
||||
|
||||
enum nios2_exception_cause { |
||||
NIOS2_EXCEPTION_UNKNOWN = -1, |
||||
NIOS2_EXCEPTION_RESET = 0, |
||||
NIOS2_EXCEPTION_CPU_ONLY_RESET_REQUEST = 1, |
||||
NIOS2_EXCEPTION_INTERRUPT = 2, |
||||
NIOS2_EXCEPTION_TRAP_INST = 3, |
||||
NIOS2_EXCEPTION_UNIMPLEMENTED_INST = 4, |
||||
NIOS2_EXCEPTION_ILLEGAL_INST = 5, |
||||
NIOS2_EXCEPTION_MISALIGNED_DATA_ADDR = 6, |
||||
NIOS2_EXCEPTION_MISALIGNED_TARGET_PC = 7, |
||||
NIOS2_EXCEPTION_DIVISION_ERROR = 8, |
||||
NIOS2_EXCEPTION_SUPERVISOR_ONLY_INST_ADDR = 9, |
||||
NIOS2_EXCEPTION_SUPERVISOR_ONLY_INST = 10, |
||||
NIOS2_EXCEPTION_SUPERVISOR_ONLY_DATA_ADDR = 11, |
||||
NIOS2_EXCEPTION_TLB_MISS = 12, |
||||
NIOS2_EXCEPTION_TLB_EXECUTE_PERM_VIOLATION = 13, |
||||
NIOS2_EXCEPTION_TLB_READ_PERM_VIOLATION = 14, |
||||
NIOS2_EXCEPTION_TLB_WRITE_PERM_VIOLATION = 15, |
||||
NIOS2_EXCEPTION_MPU_INST_REGION_VIOLATION = 16, |
||||
NIOS2_EXCEPTION_MPU_DATA_REGION_VIOLATION = 17, |
||||
NIOS2_EXCEPTION_ECC_TLB_ERR = 18, |
||||
NIOS2_EXCEPTION_ECC_FETCH_ERR = 19, |
||||
NIOS2_EXCEPTION_ECC_REGISTER_FILE_ERR = 20, |
||||
NIOS2_EXCEPTION_ECC_DATA_ERR = 21, |
||||
NIOS2_EXCEPTION_ECC_DATA_CACHE_WRITEBACK_ERR = 22 |
||||
}; |
||||
|
||||
/* Bitfield indicating which exception cause codes report a valid
|
||||
* badaddr register. NIOS2_EXCEPTION_TLB_MISS and NIOS2_EXCEPTION_ECC_TLB_ERR |
||||
* are deliberately not included here, you need to check if TLBMISC.D=1 |
||||
*/ |
||||
#define NIOS2_BADADDR_CAUSE_MASK \ |
||||
(BIT(NIOS2_EXCEPTION_SUPERVISOR_ONLY_DATA_ADDR) | \ |
||||
BIT(NIOS2_EXCEPTION_MISALIGNED_DATA_ADDR) | \ |
||||
BIT(NIOS2_EXCEPTION_MISALIGNED_TARGET_PC) | \ |
||||
BIT(NIOS2_EXCEPTION_TLB_READ_PERM_VIOLATION) | \ |
||||
BIT(NIOS2_EXCEPTION_TLB_WRITE_PERM_VIOLATION) | \ |
||||
BIT(NIOS2_EXCEPTION_MPU_DATA_REGION_VIOLATION) | \ |
||||
BIT(NIOS2_EXCEPTION_ECC_DATA_ERR)) |
||||
|
||||
|
||||
extern uint32_t sys_clock_cycle_get_32(void); |
||||
|
||||
static inline uint32_t arch_k_cycle_get_32(void) |
||||
{ |
||||
return sys_clock_cycle_get_32(); |
||||
} |
||||
|
||||
extern uint64_t sys_clock_cycle_get_64(void); |
||||
|
||||
static inline uint64_t arch_k_cycle_get_64(void) |
||||
{ |
||||
return sys_clock_cycle_get_64(); |
||||
} |
||||
|
||||
static ALWAYS_INLINE void arch_nop(void) |
||||
{ |
||||
__asm__ volatile("nop"); |
||||
} |
||||
|
||||
#ifdef __cplusplus |
||||
} |
||||
#endif |
||||
|
||||
#endif /* _ASMLANGUAGE */ |
||||
|
||||
#endif /* ZEPHYR_INCLUDE_ARCH_NIOS2_ARCH_H_ */ |
@ -1,17 +0,0 @@
@@ -1,17 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2022 Intel Corporation |
||||
* |
||||
* SPDX-License-Identifier: Apache-2.0 |
||||
*/ |
||||
|
||||
#ifndef ZEPHYR_INCLUDE_ARCH_NIOS2_ARCH_INLINES_H |
||||
#define ZEPHYR_INCLUDE_ARCH_NIOS2_ARCH_INLINES_H |
||||
|
||||
#include <zephyr/kernel_structs.h> |
||||
|
||||
static ALWAYS_INLINE unsigned int arch_num_cpus(void) |
||||
{ |
||||
return CONFIG_MP_MAX_NUM_CPUS; |
||||
} |
||||
|
||||
#endif /* ZEPHYR_INCLUDE_ARCH_NIOS2_ARCH_INLINES_H */ |
@ -1,21 +0,0 @@
@@ -1,21 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Intel Corporation |
||||
* |
||||
* SPDX-License-Identifier: Apache-2.0 |
||||
*/ |
||||
|
||||
#ifndef ZEPHYR_INCLUDE_ARCH_NIOS2_ASM_INLINE_H_ |
||||
#define ZEPHYR_INCLUDE_ARCH_NIOS2_ASM_INLINE_H_ |
||||
|
||||
/*
|
||||
* The file must not be included directly |
||||
* Include kernel.h instead |
||||
*/ |
||||
|
||||
#if defined(__GNUC__) |
||||
#include <zephyr/arch/nios2/asm_inline_gcc.h> |
||||
#else |
||||
#include <arch/nios2/asm_inline_other.h> |
||||
#endif |
||||
|
||||
#endif /* ZEPHYR_INCLUDE_ARCH_NIOS2_ASM_INLINE_H_ */ |
@ -1,56 +0,0 @@
@@ -1,56 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Intel Corporation |
||||
* |
||||
* SPDX-License-Identifier: Apache-2.0 |
||||
*/ |
||||
|
||||
#ifndef ZEPHYR_INCLUDE_ARCH_NIOS2_ASM_INLINE_GCC_H_ |
||||
#define ZEPHYR_INCLUDE_ARCH_NIOS2_ASM_INLINE_GCC_H_ |
||||
|
||||
/*
|
||||
* The file must not be included directly |
||||
* Include arch/cpu.h instead |
||||
*/ |
||||
|
||||
#ifndef _ASMLANGUAGE |
||||
#include <zephyr/types.h> |
||||
#include <zephyr/sys/sys_io.h> |
||||
#include <zephyr/toolchain.h> |
||||
|
||||
/* Using the *io variants of these instructions to prevent issues on
|
||||
* devices that have an instruction/data cache |
||||
*/ |
||||
|
||||
static ALWAYS_INLINE void sys_write32(uint32_t data, mm_reg_t addr) |
||||
{ |
||||
__builtin_stwio((void *)addr, data); |
||||
} |
||||
|
||||
static ALWAYS_INLINE uint32_t sys_read32(mm_reg_t addr) |
||||
{ |
||||
return __builtin_ldwio((void *)addr); |
||||
} |
||||
|
||||
static ALWAYS_INLINE void sys_write8(uint8_t data, mm_reg_t addr) |
||||
{ |
||||
sys_write32(data, addr); |
||||
} |
||||
|
||||
static ALWAYS_INLINE uint8_t sys_read8(mm_reg_t addr) |
||||
{ |
||||
return __builtin_ldbuio((void *)addr); |
||||
} |
||||
|
||||
static ALWAYS_INLINE void sys_write16(uint16_t data, mm_reg_t addr) |
||||
{ |
||||
sys_write32(data, addr); |
||||
} |
||||
|
||||
static ALWAYS_INLINE uint16_t sys_read16(mm_reg_t addr) |
||||
{ |
||||
return __builtin_ldhuio((void *)addr); |
||||
} |
||||
|
||||
#endif /* _ASMLANGUAGE */ |
||||
|
||||
#endif /* _ASM_INLINE_GCC_PUBLIC_GCC_H */ |
@ -1,44 +0,0 @@
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Intel Corporation |
||||
* |
||||
* SPDX-License-Identifier: Apache-2.0 |
||||
*/ |
||||
|
||||
#ifndef ZEPHYR_INCLUDE_ARCH_NIOS2_EXCEPTION_H_ |
||||
#define ZEPHYR_INCLUDE_ARCH_NIOS2_EXCEPTION_H_ |
||||
|
||||
#ifndef _ASMLANGUAGE |
||||
#include <zephyr/types.h> |
||||
|
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
|
||||
struct arch_esf { |
||||
uint32_t ra; /* return address r31 */ |
||||
uint32_t r1; /* at */ |
||||
uint32_t r2; /* return value */ |
||||
uint32_t r3; /* return value */ |
||||
uint32_t r4; /* register args */ |
||||
uint32_t r5; /* register args */ |
||||
uint32_t r6; /* register args */ |
||||
uint32_t r7; /* register args */ |
||||
uint32_t r8; /* Caller-saved general purpose */ |
||||
uint32_t r9; /* Caller-saved general purpose */ |
||||
uint32_t r10; /* Caller-saved general purpose */ |
||||
uint32_t r11; /* Caller-saved general purpose */ |
||||
uint32_t r12; /* Caller-saved general purpose */ |
||||
uint32_t r13; /* Caller-saved general purpose */ |
||||
uint32_t r14; /* Caller-saved general purpose */ |
||||
uint32_t r15; /* Caller-saved general purpose */ |
||||
uint32_t estatus; |
||||
uint32_t instr; /* Instruction being executed when exc occurred */ |
||||
}; |
||||
|
||||
#ifdef __cplusplus |
||||
} |
||||
#endif |
||||
|
||||
#endif /* _ASMLANGUAGE */ |
||||
|
||||
#endif /* ZEPHYR_INCLUDE_ARCH_NIOS2_EXCEPTION_H_ */ |
@ -1,286 +0,0 @@
@@ -1,286 +0,0 @@
|
||||
/* |
||||
* Copyright (c) 2016 Intel Corporation |
||||
* |
||||
* SPDX-License-Identifier: Apache-2.0 |
||||
*/ |
||||
|
||||
/** |
||||
* @file |
||||
* @brief Linker command/script file |
||||
* |
||||
* Linker script for the Nios II platform |
||||
*/ |
||||
|
||||
#include <zephyr/linker/sections.h> |
||||
|
||||
#include <zephyr/linker/linker-defs.h> |
||||
#include <zephyr/linker/linker-tool.h> |
||||
|
||||
/* These sections are specific to this CPU */ |
||||
#define _EXCEPTION_SECTION_NAME exceptions |
||||
#define _RESET_SECTION_NAME reset |
||||
|
||||
/* This linker script requires the following macros to be defined in the |
||||
* SOC-specific linker script. All of these values can be found defined |
||||
* in system.h for CPU configurations that can generate a HAL. |
||||
* |
||||
* _RESET_VECTOR CPU entry point at boot |
||||
* _EXC_VECTOR General exception vector |
||||
* _ROM_ADDR Beginning of flash memory |
||||
* _ROM_SIZE Size in bytes of flash memory |
||||
* _RAM_ADDR Beginning of RAM |
||||
* _RAM_SIZE Size of RAM in bytes |
||||
* |
||||
* For now we support two scenarios: |
||||
* |
||||
* 1. Non-XIP systems where the reset vector is at the beginning of RAM |
||||
* with the exception vector 0x20 bytes after it. |
||||
* 2. XIP systems where the reset vector is at the beginning of ROM and |
||||
* the exception vector is in RAM |
||||
*/ |
||||
|
||||
#if defined(CONFIG_ROM_END_OFFSET) |
||||
#define ROM_END_OFFSET CONFIG_ROM_END_OFFSET |
||||
#else |
||||
#define ROM_END_OFFSET 0 |
||||
#endif |
||||
|
||||
#ifdef CONFIG_XIP |
||||
#define ROMABLE_REGION FLASH |
||||
#else |
||||
#define ROMABLE_REGION RAM |
||||
#endif |
||||
#define RAMABLE_REGION RAM |
||||
|
||||
#ifdef CONFIG_XIP |
||||
|
||||
ASSERT(_RESET_VECTOR == _ROM_ADDR, "Reset vector not at beginning of ROM!") |
||||
|
||||
MEMORY |
||||
{ |
||||
RESET (rx) : ORIGIN = _RESET_VECTOR, LENGTH = 0x20 |
||||
FLASH (rx) : ORIGIN = _RESET_VECTOR + 0x20 , LENGTH = (_ROM_SIZE - 0x20 - ROM_END_OFFSET) |
||||
RAM (wx) : ORIGIN = _EXC_VECTOR, LENGTH = _RAM_SIZE - (_EXC_VECTOR - _RAM_ADDR) |
||||
/* Used by and documented in include/linker/intlist.ld */ |
||||
IDT_LIST (wx) : ORIGIN = 0xFFFFF7FF, LENGTH = 2K |
||||
|
||||
} |
||||
|
||||
#else |
||||
|
||||
MEMORY |
||||
{ |
||||
RESET (wx) : ORIGIN = _RESET_VECTOR, LENGTH = 0x20 |
||||
RAM (wx) : ORIGIN = _EXC_VECTOR, LENGTH = _RAM_SIZE - (_EXC_VECTOR - _RAM_ADDR) |
||||
|
||||
/* Used by and documented in include/linker/intlist.ld */ |
||||
IDT_LIST (wx) : ORIGIN = 0xFFFFF7FF, LENGTH = 2K |
||||
} |
||||
#endif |
||||
|
||||
ENTRY(CONFIG_KERNEL_ENTRY) |
||||
|
||||
SECTIONS |
||||
{ |
||||
|
||||
#include <zephyr/linker/rel-sections.ld> |
||||
|
||||
#ifdef CONFIG_LLEXT |
||||
#include <zephyr/linker/llext-sections.ld> |
||||
#endif |
||||
|
||||
/* |
||||
* .plt and .iplt are here according to |
||||
* 'nios2-zephyr-elf-ld --verbose', before text section. |
||||
*/ |
||||
SECTION_PROLOGUE(.plt,,) |
||||
{ |
||||
*(.plt) |
||||
} |
||||
|
||||
SECTION_PROLOGUE(.iplt,,) |
||||
{ |
||||
*(.iplt) |
||||
} |
||||
|
||||
GROUP_START(ROMABLE_REGION) |
||||
__rom_region_start = _ROM_ADDR; |
||||
|
||||
SECTION_PROLOGUE(_RESET_SECTION_NAME,,) |
||||
{ |
||||
KEEP(*(.reset.*)) |
||||
} GROUP_LINK_IN(RESET) |
||||
|
||||
#ifndef CONFIG_XIP |
||||
SECTION_PROLOGUE(_EXCEPTION_SECTION_NAME,,) |
||||
{ |
||||
KEEP(*(".exception.entry.*")) |
||||
*(".exception.other.*") |
||||
|
||||
} GROUP_LINK_IN(ROMABLE_REGION) |
||||
#endif |
||||
|
||||
SECTION_PROLOGUE(_TEXT_SECTION_NAME,,) |
||||
{ |
||||
/* XXX If ALT_CPU_RESET_ADDR is not the same as _ROM_ADDR |
||||
* we are going to waste flash space? */ |
||||
. = ALT_CPU_RESET_ADDR; |
||||
|
||||
__text_region_start = .; |
||||
|
||||
*(.text) |
||||
*(".text.*") |
||||
*(.gnu.linkonce.t.*) |
||||
} GROUP_LINK_IN(ROMABLE_REGION) |
||||
|
||||
__text_region_end = .; |
||||
|
||||
#if defined(CONFIG_GP_ALL_DATA) |
||||
_gp = ABSOLUTE(. + 0x8000); |
||||
PROVIDE(gp = _gp); |
||||
#endif |
||||
|
||||
__rodata_region_start = .; |
||||
|
||||
#include <zephyr/linker/common-rom.ld> |
||||
/* Located in generated directory. This file is populated by calling |
||||
* zephyr_linker_sources(ROM_SECTIONS ...). Useful for grouping iterable RO structs. |
||||
*/ |
||||
#include <snippets-rom-sections.ld> |
||||
|
||||
SECTION_PROLOGUE(_RODATA_SECTION_NAME,,) |
||||
{ |
||||
. = ALIGN(4); |
||||
|
||||
*(.rodata) |
||||
*(".rodata.*") |
||||
*(.gnu.linkonce.r.*) |
||||
|
||||
/* Located in generated directory. This file is populated by the |
||||
* zephyr_linker_sources() Cmake function. |
||||
*/ |
||||
#include <snippets-rodata.ld> |
||||
|
||||
. = ALIGN(4); |
||||
} GROUP_LINK_IN(ROMABLE_REGION) |
||||
|
||||
#include <zephyr/linker/cplusplus-rom.ld> |
||||
|
||||
__rodata_region_end = .; |
||||
__rodata_region_size = __rodata_region_end - __rodata_region_start; |
||||
|
||||
__rom_region_end = .; |
||||
__data_region_load_start = ALIGN(4); /* XIP imaged DATA ROM start addr */ |
||||
|
||||
GROUP_END(ROMABLE_REGION) |
||||
|
||||
GROUP_START(RAMABLE_REGION) |
||||
|
||||
#ifdef CONFIG_XIP |
||||
/* Altera strongly recommends keeping exception entry code in RAM |
||||
* even on XIP systems |
||||
* |
||||
* This is code not data, but we need this copied just like XIP data |
||||
*/ |
||||
|
||||
SECTION_DATA_PROLOGUE(_EXCEPTION_SECTION_NAME,,) |
||||
{ |
||||
_image_ram_start = .; |
||||
__data_region_start = .; |
||||
|
||||
KEEP(*(".exception.entry.*")) |
||||
*(".exception.other.*") |
||||
|
||||
} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) |
||||
#endif |
||||
|
||||
#ifndef CONFIG_XIP |
||||
_image_ram_start = .; |
||||
#endif |
||||
|
||||
#include <zephyr/linker/common-ram.ld> |
||||
|
||||
SECTION_DATA_PROLOGUE(_DATA_SECTION_NAME,,) |
||||
{ |
||||
__data_start = .; |
||||
*(.data) |
||||
*(".data.*") |
||||
|
||||
/* Located in generated directory. This file is populated by the |
||||
* zephyr_linker_sources() Cmake function. |
||||
*/ |
||||
#include <snippets-rwdata.ld> |
||||
|
||||
/* the Nios2 architecture only has 16-bit signed immediate offsets in |
||||
* the instructions, so accessing a general address requires typically |
||||
* three instructions - basically, two for the two halves of the 32-bit |
||||
* address, and one to merge them - but if we can put the most commonly |
||||
* accessed globals in a special 64K span of memory addressed by the GP |
||||
* register, then we can access those values in a single instruction, |
||||
* saving both codespace and runtime. |
||||
* |
||||
* Since these immediate offsets are signed, place gp 0x8000 past the |
||||
* beginning of .sdata so that we can use both positive and negative |
||||
* offsets. |
||||
*/ |
||||
#if defined(CONFIG_GP_LOCAL) || defined(CONFIG_GP_GLOBAL) |
||||
_gp = ABSOLUTE(. + 0x8000); |
||||
PROVIDE(gp = _gp); |
||||
#endif |
||||
|
||||
*(.sdata .sdata.* .gnu.linkonce.s.*) |
||||
*(.sdata2 .sdata2.* .gnu.linkonce.s2.*) |
||||
|
||||
/* Located in generated directory. This file is populated by the |
||||
* zephyr_linker_sources() Cmake function. |
||||
*/ |
||||
#include <snippets-ram-sections.ld> |
||||
__data_end = .; |
||||
|
||||
} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) |
||||
__data_size = __data_end - __data_start; |
||||
__data_load_start = LOADADDR(_DATA_SECTION_NAME); |
||||
|
||||
#include <zephyr/linker/cplusplus-ram.ld> |
||||
|
||||
/* Located in generated directory. This file is populated by the |
||||
* zephyr_linker_sources() Cmake function. |
||||
*/ |
||||
#include <snippets-data-sections.ld> |
||||
|
||||
__data_region_end = .; |
||||
|
||||
SECTION_DATA_PROLOGUE(_BSS_SECTION_NAME,(NOLOAD),) |
||||
{ |
||||
/* |
||||
* For performance, BSS section is assumed to be 4 byte aligned and |
||||
* a multiple of 4 bytes |
||||
*/ |
||||
. = ALIGN(4); |
||||
__bss_start = .; |
||||
*(.sbss) |
||||
*(".sbss.*") |
||||
*(.bss) |
||||
*(".bss.*") |
||||
COMMON_SYMBOLS |
||||
/* |
||||
* As memory is cleared in words only, it is simpler to ensure the BSS |
||||
* section ends on a 4 byte boundary. This wastes a maximum of 3 bytes. |
||||
*/ |
||||
__bss_end = ALIGN(4); |
||||
} GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION) |
||||
|
||||
#include <zephyr/linker/common-noinit.ld> |
||||
|
||||
/* Located in generated directory. This file is populated by the |
||||
* zephyr_linker_sources() Cmake function. |
||||
*/ |
||||
#include <snippets-sections.ld> |
||||
|
||||
#include <zephyr/linker/ram-end.ld> |
||||
|
||||
GROUP_END(RAMABLE_REGION) |
||||
|
||||
#include <zephyr/linker/debug-sections.ld> |
||||
|
||||
} |
@ -1,328 +0,0 @@
@@ -1,328 +0,0 @@
|
||||
#ifndef ZEPHYR_INCLUDE_ARCH_NIOS2_NIOS2_H_ |
||||
#define ZEPHYR_INCLUDE_ARCH_NIOS2_NIOS2_H_ |
||||
|
||||
/* SPDX-License-Identifier: Xnet */ |
||||
|
||||
/******************************************************************************
|
||||
* * |
||||
* License Agreement * |
||||
* * |
||||
* Copyright (c) 2008 Altera Corporation, San Jose, California, USA. * |
||||
* All rights reserved. * |
||||
* * |
||||
* Permission is hereby granted, free of charge, to any person obtaining a * |
||||
* copy of this software and associated documentation files (the "Software"), * |
||||
* to deal in the Software without restriction, including without limitation * |
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense, * |
||||
* and/or sell copies of the Software, and to permit persons to whom the * |
||||
* Software is furnished to do so, subject to the following conditions: * |
||||
* * |
||||
* The above copyright notice and this permission notice shall be included in * |
||||
* all copies or substantial portions of the Software. * |
||||
* * |
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * |
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * |
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * |
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * |
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * |
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * |
||||
* DEALINGS IN THE SOFTWARE. * |
||||
* * |
||||
* This agreement shall be governed in all respects by the laws of the State * |
||||
* of California and by the laws of the United States of America. * |
||||
* * |
||||
******************************************************************************/ |
||||
|
||||
/*
|
||||
* This header provides processor specific macros for accessing the Nios2 |
||||
* control registers. |
||||
*/ |
||||
|
||||
#ifdef __cplusplus |
||||
extern "C" |
||||
{ |
||||
#endif /* __cplusplus */ |
||||
|
||||
/*
|
||||
* Number of available IRQs in internal interrupt controller. |
||||
*/ |
||||
#define NIOS2_NIRQ 32 |
||||
|
||||
/* Size in bits of registers */ |
||||
#define SYSTEM_BUS_WIDTH 32 |
||||
|
||||
#ifndef _ASMLANGUAGE |
||||
|
||||
#include <zephyr/types.h> |
||||
#include <zephyr/arch/cpu.h> |
||||
#include <zephyr/sys/sys_io.h> |
||||
|
||||
/*
|
||||
* Functions for accessing select Nios II general-purpose registers. |
||||
*/ |
||||
|
||||
/* ET (Exception Temporary) register */ |
||||
static inline uint32_t _nios2_read_et(void) |
||||
{ |
||||
uint32_t et; |
||||
|
||||
__asm__("mov %0, et" : "=r" (et)); |
||||
return et; |
||||
} |
||||
|
||||
static inline void _nios2_write_et(uint32_t et) |
||||
{ |
||||
__asm__ volatile("mov et, %z0" : : "rM" (et)); |
||||
} |
||||
|
||||
static inline uint32_t _nios2_read_sp(void) |
||||
{ |
||||
uint32_t sp; |
||||
|
||||
__asm__("mov %0, sp" : "=r" (sp)); |
||||
return sp; |
||||
} |
||||
|
||||
/*
|
||||
* Functions for useful processor instructions. |
||||
*/ |
||||
static inline void z_nios2_break(void) |
||||
{ |
||||
__asm__ volatile("break"); |
||||
} |
||||
|
||||
static inline void _nios2_report_stack_overflow(void) |
||||
{ |
||||
__asm__ volatile("break 3"); |
||||
} |
||||
|
||||
/*
|
||||
* Low-level cache management functions |
||||
*/ |
||||
static inline void _nios2_dcache_addr_flush(void *addr) |
||||
{ |
||||
__asm__ volatile ("flushda (%0)" :: "r" (addr)); |
||||
} |
||||
|
||||
static inline void z_nios2_dcache_flush(uint32_t offset) |
||||
{ |
||||
__asm__ volatile ("flushd (%0)" :: "r" (offset)); |
||||
} |
||||
|
||||
static inline void z_nios2_icache_flush(uint32_t offset) |
||||
{ |
||||
__asm__ volatile ("flushi %0" :: "r" (offset)); |
||||
} |
||||
|
||||
static inline void z_nios2_pipeline_flush(void) |
||||
{ |
||||
__asm__ volatile ("flushp"); |
||||
} |
||||
|
||||
/*
|
||||
* Functions for reading/writing control registers |
||||
*/ |
||||
|
||||
enum nios2_creg { |
||||
NIOS2_CR_STATUS = 0, |
||||
NIOS2_CR_ESTATUS = 1, |
||||
NIOS2_CR_BSTATUS = 2, |
||||
NIOS2_CR_IENABLE = 3, |
||||
NIOS2_CR_IPENDING = 4, |
||||
NIOS2_CR_CPUID = 5, |
||||
/* 6 is reserved */ |
||||
NIOS2_CR_EXCEPTION = 7, |
||||
NIOS2_CR_PTEADDR = 8, |
||||
NIOS2_CR_TLBACC = 9, |
||||
NIOS2_CR_TLBMISC = 10, |
||||
NIOS2_CR_ECCINJ = 11, |
||||
NIOS2_CR_BADADDR = 12, |
||||
NIOS2_CR_CONFIG = 13, |
||||
NIOS2_CR_MPUBASE = 14, |
||||
NIOS2_CR_MPUACC = 15 |
||||
}; |
||||
|
||||
/* XXX I would prefer to define these as static inline functions for
|
||||
* type checking purposes. However if -O0 is used (i.e. CONFIG_DEBUG is on) |
||||
* we get errors "Control register number must be in range 0-31 for |
||||
* __builtin_rdctl" with the following code: |
||||
* |
||||
* static inline uint32_t z_nios2_creg_read(enum nios2_creg reg) |
||||
* { |
||||
* return __builtin_rdctl(reg); |
||||
* } |
||||
* |
||||
* This compiles just fine with -Os. |
||||
*/ |
||||
#define z_nios2_creg_read(reg) __builtin_rdctl(reg) |
||||
#define z_nios2_creg_write(reg, val) __builtin_wrctl(reg, val) |
||||
|
||||
#define z_nios2_get_register_address(base, regnum) \ |
||||
((void *)(((uint8_t *)base) + ((regnum) * (SYSTEM_BUS_WIDTH / 8)))) |
||||
|
||||
static inline void _nios2_reg_write(void *base, int regnum, uint32_t data) |
||||
{ |
||||
sys_write32(data, |
||||
(mm_reg_t)z_nios2_get_register_address(base, regnum)); |
||||
} |
||||
|
||||
static inline uint32_t _nios2_reg_read(void *base, int regnum) |
||||
{ |
||||
return sys_read32((mm_reg_t)z_nios2_get_register_address(base, regnum)); |
||||
} |
||||
|
||||
#endif /* _ASMLANGUAGE */ |
||||
|
||||
/*
|
||||
* Nios II control registers that are always present |
||||
*/ |
||||
#define NIOS2_STATUS status |
||||
#define NIOS2_ESTATUS estatus |
||||
#define NIOS2_BSTATUS bstatus |
||||
#define NIOS2_IENABLE ienable |
||||
#define NIOS2_IPENDING ipending |
||||
#define NIOS2_CPUID cpuid |
||||
|
||||
/*
|
||||
* Bit masks & offsets for Nios II control registers. |
||||
* The presence and size of a field is sometimes dependent on the Nios II |
||||
* configuration. Bit masks for every possible field and the maximum size of |
||||
* that field are defined. |
||||
* |
||||
* All bit-masks are expressed relative to the position |
||||
* of the data with a register. To read data that is LSB- |
||||
* aligned, the register read data should be masked, then |
||||
* right-shifted by the designated "OFST" macro value. The |
||||
* opposite should be used for register writes when starting |
||||
* with LSB-aligned data. |
||||
*/ |
||||
|
||||
/* STATUS, ESTATUS, BSTATUS, and SSTATUS registers */ |
||||
#define NIOS2_STATUS_PIE_MSK (0x00000001) |
||||
#define NIOS2_STATUS_PIE_OFST (0) |
||||
#define NIOS2_STATUS_U_MSK (0x00000002) |
||||
#define NIOS2_STATUS_U_OFST (1) |
||||
#define NIOS2_STATUS_EH_MSK (0x00000004) |
||||
#define NIOS2_STATUS_EH_OFST (2) |
||||
#define NIOS2_STATUS_IH_MSK (0x00000008) |
||||
#define NIOS2_STATUS_IH_OFST (3) |
||||
#define NIOS2_STATUS_IL_MSK (0x000003f0) |
||||
#define NIOS2_STATUS_IL_OFST (4) |
||||
#define NIOS2_STATUS_CRS_MSK (0x0000fc00) |
||||
#define NIOS2_STATUS_CRS_OFST (10) |
||||
#define NIOS2_STATUS_PRS_MSK (0x003f0000) |
||||
#define NIOS2_STATUS_PRS_OFST (16) |
||||
#define NIOS2_STATUS_NMI_MSK (0x00400000) |
||||
#define NIOS2_STATUS_NMI_OFST (22) |
||||
#define NIOS2_STATUS_RSIE_MSK (0x00800000) |
||||
#define NIOS2_STATUS_RSIE_OFST (23) |
||||
#define NIOS2_STATUS_SRS_MSK (0x80000000) |
||||
#define NIOS2_STATUS_SRS_OFST (31) |
||||
|
||||
/* EXCEPTION register */ |
||||
#define NIOS2_EXCEPTION_REG_CAUSE_MASK (0x0000007c) |
||||
#define NIOS2_EXCEPTION_REG_CAUSE_OFST (2) |
||||
#define NIOS2_EXCEPTION_REG_ECCFTL_MASK (0x80000000) |
||||
#define NIOS2_EXCEPTION_REG_ECCFTL_OFST (31) |
||||
|
||||
/* PTEADDR (Page Table Entry Address) register */ |
||||
#define NIOS2_PTEADDR_REG_VPN_OFST 2 |
||||
#define NIOS2_PTEADDR_REG_VPN_MASK 0x3ffffc |
||||
#define NIOS2_PTEADDR_REG_PTBASE_OFST 22 |
||||
#define NIOS2_PTEADDR_REG_PTBASE_MASK 0xffc00000 |
||||
|
||||
/* TLBACC (TLB Access) register */ |
||||
#define NIOS2_TLBACC_REG_PFN_OFST 0 |
||||
#define NIOS2_TLBACC_REG_PFN_MASK 0xfffff |
||||
#define NIOS2_TLBACC_REG_G_OFST 20 |
||||
#define NIOS2_TLBACC_REG_G_MASK 0x100000 |
||||
#define NIOS2_TLBACC_REG_X_OFST 21 |
||||
#define NIOS2_TLBACC_REG_X_MASK 0x200000 |
||||
#define NIOS2_TLBACC_REG_W_OFST 22 |
||||
#define NIOS2_TLBACC_REG_W_MASK 0x400000 |
||||
#define NIOS2_TLBACC_REG_R_OFST 23 |
||||
#define NIOS2_TLBACC_REG_R_MASK 0x800000 |
||||
#define NIOS2_TLBACC_REG_C_OFST 24 |
||||
#define NIOS2_TLBACC_REG_C_MASK 0x1000000 |
||||
#define NIOS2_TLBACC_REG_IG_OFST 25 |
||||
#define NIOS2_TLBACC_REG_IG_MASK 0xfe000000 |
||||
|
||||
/* TLBMISC (TLB Miscellaneous) register */ |
||||
#define NIOS2_TLBMISC_REG_D_OFST 0 |
||||
#define NIOS2_TLBMISC_REG_D_MASK 0x1 |
||||
#define NIOS2_TLBMISC_REG_PERM_OFST 1 |
||||
#define NIOS2_TLBMISC_REG_PERM_MASK 0x2 |
||||
#define NIOS2_TLBMISC_REG_BAD_OFST 2 |
||||
#define NIOS2_TLBMISC_REG_BAD_MASK 0x4 |
||||
#define NIOS2_TLBMISC_REG_DBL_OFST 3 |
||||
#define NIOS2_TLBMISC_REG_DBL_MASK 0x8 |
||||
#define NIOS2_TLBMISC_REG_PID_OFST 4 |
||||
#define NIOS2_TLBMISC_REG_PID_MASK 0x3fff0 |
||||
#define NIOS2_TLBMISC_REG_WE_OFST 18 |
||||
#define NIOS2_TLBMISC_REG_WE_MASK 0x40000 |
||||
#define NIOS2_TLBMISC_REG_RD_OFST 19 |
||||
#define NIOS2_TLBMISC_REG_RD_MASK 0x80000 |
||||
#define NIOS2_TLBMISC_REG_WAY_OFST 20 |
||||
#define NIOS2_TLBMISC_REG_WAY_MASK 0xf00000 |
||||
#define NIOS2_TLBMISC_REG_EE_OFST 24 |
||||
#define NIOS2_TLBMISC_REG_EE_MASK 0x1000000 |
||||
|
||||
/* ECCINJ (ECC Inject) register */ |
||||
#define NIOS2_ECCINJ_REG_RF_OFST 0 |
||||
#define NIOS2_ECCINJ_REG_RF_MASK 0x3 |
||||
#define NIOS2_ECCINJ_REG_ICTAG_OFST 2 |
||||
#define NIOS2_ECCINJ_REG_ICTAG_MASK 0xc |
||||
#define NIOS2_ECCINJ_REG_ICDAT_OFST 4 |
||||
#define NIOS2_ECCINJ_REG_ICDAT_MASK 0x30 |
||||
#define NIOS2_ECCINJ_REG_DCTAG_OFST 6 |
||||
#define NIOS2_ECCINJ_REG_DCTAG_MASK 0xc0 |
||||
#define NIOS2_ECCINJ_REG_DCDAT_OFST 8 |
||||
#define NIOS2_ECCINJ_REG_DCDAT_MASK 0x300 |
||||
#define NIOS2_ECCINJ_REG_TLB_OFST 10 |
||||
#define NIOS2_ECCINJ_REG_TLB_MASK 0xc00 |
||||
#define NIOS2_ECCINJ_REG_DTCM0_OFST 12 |
||||
#define NIOS2_ECCINJ_REG_DTCM0_MASK 0x3000 |
||||
#define NIOS2_ECCINJ_REG_DTCM1_OFST 14 |
||||
#define NIOS2_ECCINJ_REG_DTCM1_MASK 0xc000 |
||||
#define NIOS2_ECCINJ_REG_DTCM2_OFST 16 |
||||
#define NIOS2_ECCINJ_REG_DTCM2_MASK 0x30000 |
||||
#define NIOS2_ECCINJ_REG_DTCM3_OFST 18 |
||||
#define NIOS2_ECCINJ_REG_DTCM3_MASK 0xc0000 |
||||
|
||||
/* CONFIG register */ |
||||
#define NIOS2_CONFIG_REG_PE_MASK (0x00000001) |
||||
#define NIOS2_CONFIG_REG_PE_OFST (0) |
||||
#define NIOS2_CONFIG_REG_ANI_MASK (0x00000002) |
||||
#define NIOS2_CONFIG_REG_ANI_OFST (1) |
||||
#define NIOS2_CONFIG_REG_ECCEN_MASK (0x00000004) |
||||
#define NIOS2_CONFIG_REG_ECCEN_OFST (2) |
||||
#define NIOS2_CONFIG_REG_ECCEXC_MASK (0x00000008) |
||||
#define NIOS2_CONFIG_REG_ECCEXC_OFST (3) |
||||
|
||||
/* MPUBASE (MPU Base Address) Register */ |
||||
#define NIOS2_MPUBASE_D_MASK (0x00000001) |
||||
#define NIOS2_MPUBASE_D_OFST (0) |
||||
#define NIOS2_MPUBASE_INDEX_MASK (0x0000003e) |
||||
#define NIOS2_MPUBASE_INDEX_OFST (1) |
||||
#define NIOS2_MPUBASE_BASE_ADDR_MASK (0xffffffc0) |
||||
#define NIOS2_MPUBASE_BASE_ADDR_OFST (6) |
||||
|
||||
/* MPUACC (MPU Access) Register */ |
||||
#define NIOS2_MPUACC_LIMIT_MASK (0xffffffc0) |
||||
#define NIOS2_MPUACC_LIMIT_OFST (6) |
||||
#define NIOS2_MPUACC_MASK_MASK (0xffffffc0) |
||||
#define NIOS2_MPUACC_MASK_OFST (6) |
||||
#define NIOS2_MPUACC_C_MASK (0x00000020) |
||||
#define NIOS2_MPUACC_C_OFST (5) |
||||
#define NIOS2_MPUACC_PERM_MASK (0x0000001c) |
||||
#define NIOS2_MPUACC_PERM_OFST (2) |
||||
#define NIOS2_MPUACC_RD_MASK (0x00000002) |
||||
#define NIOS2_MPUACC_RD_OFST (1) |
||||
#define NIOS2_MPUACC_WR_MASK (0x00000001) |
||||
#define NIOS2_MPUACC_WR_OFST (0) |
||||
|
||||
#ifdef __cplusplus |
||||
} |
||||
#endif /* __cplusplus */ |
||||
|
||||
#endif /* ZEPHYR_INCLUDE_ARCH_NIOS2_NIOS2_H_ */ |
@ -1,64 +0,0 @@
@@ -1,64 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017 Intel Corporation |
||||
* |
||||
* SPDX-License-Identifier: Apache-2.0 |
||||
*/ |
||||
|
||||
/**
|
||||
* @file |
||||
* @brief Per-arch thread definition |
||||
* |
||||
* This file contains definitions for |
||||
* |
||||
* struct _thread_arch |
||||
* struct _callee_saved |
||||
* |
||||
* necessary to instantiate instances of struct k_thread. |
||||
*/ |
||||
|
||||
#ifndef ZEPHYR_INCLUDE_ARCH_NIOS2_THREAD_H_ |
||||
#define ZEPHYR_INCLUDE_ARCH_NIOS2_THREAD_H_ |
||||
|
||||
#ifndef _ASMLANGUAGE |
||||
#include <zephyr/types.h> |
||||
|
||||
struct _callee_saved { |
||||
/* General purpose callee-saved registers */ |
||||
uint32_t r16; |
||||
uint32_t r17; |
||||
uint32_t r18; |
||||
uint32_t r19; |
||||
uint32_t r20; |
||||
uint32_t r21; |
||||
uint32_t r22; |
||||
uint32_t r23; |
||||
|
||||
/* Normally used for the frame pointer but also a general purpose
|
||||
* register if frame pointers omitted |
||||
*/ |
||||
uint32_t r28; |
||||
|
||||
/* Return address */ |
||||
uint32_t ra; |
||||
|
||||
/* Stack pointer */ |
||||
uint32_t sp; |
||||
|
||||
/* IRQ status before irq_lock() and call to z_swap() */ |
||||
uint32_t key; |
||||
|
||||
/* Return value of z_swap() */ |
||||
uint32_t retval; |
||||
}; |
||||
|
||||
typedef struct _callee_saved _callee_saved_t; |
||||
|
||||
struct _thread_arch { |
||||
/* nothing for now */ |
||||
}; |
||||
|
||||
typedef struct _thread_arch _thread_arch_t; |
||||
|
||||
#endif /* _ASMLANGUAGE */ |
||||
|
||||
#endif /* ZEPHYR_INCLUDE_ARCH_NIOS2_THREAD_H_ */ |
@ -1,8 +0,0 @@
@@ -1,8 +0,0 @@
|
||||
# Altera HAL drivers configuration |
||||
|
||||
# Copyright (c) 2017 Intel Corporation |
||||
# SPDX-License-Identifier: Apache-2.0 |
||||
|
||||
config HAS_ALTERA_HAL |
||||
bool "Altera HAL drivers support" |
||||
depends on NIOS2 |
@ -1,106 +0,0 @@
@@ -1,106 +0,0 @@
|
||||
# Copyright (c) 2017 Linaro Limited. |
||||
# |
||||
# SPDX-License-Identifier: Apache-2.0 |
||||
|
||||
'''Runner for NIOS II, based on quartus-flash.py and GDB.''' |
||||
|
||||
from runners.core import NetworkPortHelper, RunnerCaps, ZephyrBinaryRunner |
||||
|
||||
|
||||
class Nios2BinaryRunner(ZephyrBinaryRunner): |
||||
'''Runner front-end for NIOS II.''' |
||||
|
||||
# From the original shell script: |
||||
# |
||||
# "XXX [flash] only support[s] cases where the .elf is sent |
||||
# over the JTAG and the CPU directly boots from __start. CONFIG_XIP |
||||
# and CONFIG_INCLUDE_RESET_VECTOR must be disabled." |
||||
|
||||
def __init__(self, cfg, quartus_py=None, cpu_sof=None, tui=False): |
||||
super().__init__(cfg) |
||||
self.hex_name = cfg.hex_file |
||||
self.elf_name = cfg.elf_file |
||||
self.cpu_sof = cpu_sof |
||||
self.quartus_py = quartus_py |
||||
self.gdb_cmd = [cfg.gdb] if cfg.gdb else None |
||||
self.tui_arg = ['-tui'] if tui else [] |
||||
|
||||
@classmethod |
||||
def name(cls): |
||||
return 'nios2' |
||||
|
||||
@classmethod |
||||
def capabilities(cls): |
||||
return RunnerCaps(commands={'flash', 'debug', 'debugserver', 'attach'}) |
||||
|
||||
@classmethod |
||||
def do_add_parser(cls, parser): |
||||
# TODO merge quartus-flash.py script into this file. |
||||
parser.add_argument('--quartus-flash', required=True) |
||||
parser.add_argument('--cpu-sof', required=True, |
||||
help='path to the CPU .sof data') |
||||
parser.add_argument('--tui', default=False, action='store_true', |
||||
help='if given, GDB uses -tui') |
||||
|
||||
@classmethod |
||||
def do_create(cls, cfg, args): |
||||
return Nios2BinaryRunner(cfg, |
||||
quartus_py=args.quartus_flash, |
||||
cpu_sof=args.cpu_sof, |
||||
tui=args.tui) |
||||
|
||||
def do_run(self, command, **kwargs): |
||||
if command == 'flash': |
||||
self.flash(**kwargs) |
||||
else: |
||||
self.debug_debugserver(command, **kwargs) |
||||
|
||||
def flash(self, **kwargs): |
||||
if self.quartus_py is None: |
||||
raise ValueError('Cannot flash; --quartus-flash not given.') |
||||
if self.cpu_sof is None: |
||||
raise ValueError('Cannot flash; --cpu-sof not given.') |
||||
self.ensure_output('hex') |
||||
|
||||
self.logger.info(f'Flashing file: {self.hex_name}') |
||||
cmd = [self.quartus_py, |
||||
'--sof', self.cpu_sof, |
||||
'--kernel', self.hex_name] |
||||
self.require(cmd[0]) |
||||
self.check_call(cmd) |
||||
|
||||
def print_gdbserver_message(self, gdb_port): |
||||
self.logger.info(f'Nios II GDB server running on port {gdb_port}') |
||||
|
||||
def debug_debugserver(self, command, **kwargs): |
||||
# Per comments in the shell script, the NIOSII GDB server |
||||
# doesn't exit gracefully, so it's better to explicitly search |
||||
# for an unused port. The script picks a random value in |
||||
# between 1024 and 49151, but we'll start with the |
||||
# "traditional" 3333 choice. |
||||
gdb_start = 3333 |
||||
nh = NetworkPortHelper() |
||||
gdb_port = nh.get_unused_ports([gdb_start])[0] |
||||
|
||||
server_cmd = (['nios2-gdb-server', |
||||
'--tcpport', str(gdb_port), |
||||
'--stop', '--reset-target']) |
||||
self.require(server_cmd[0]) |
||||
|
||||
if command == 'debugserver': |
||||
self.print_gdbserver_message(gdb_port) |
||||
self.check_call(server_cmd) |
||||
else: |
||||
if self.elf_name is None: |
||||
raise ValueError('Cannot debug; elf is missing') |
||||
if self.gdb_cmd is None: |
||||
raise ValueError('Cannot debug; no gdb specified') |
||||
|
||||
gdb_cmd = (self.gdb_cmd + |
||||
self.tui_arg + |
||||
[self.elf_name, |
||||
'-ex', f'target remote :{gdb_port}']) |
||||
self.require(gdb_cmd[0]) |
||||
|
||||
self.print_gdbserver_message(gdb_port) |
||||
self.run_server_and_client(server_cmd, gdb_cmd) |
Loading…
Reference in new issue