-
Notifications
You must be signed in to change notification settings - Fork 20
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
<RP2040> Add CPU and platform initial support
- Loading branch information
1 parent
07faeae
commit c4c6195
Showing
11 changed files
with
823 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
/* | ||
* CYANCORE LICENSE | ||
* Copyrights (C) 2019, Cyancore Team | ||
* | ||
* File Name : arch.c | ||
* Description : This file consists of architecture specific function that | ||
* cannot be inlined. Hence, present in c file. | ||
* Primary Author : Mayuri Lokhande [[email protected]] | ||
* Organisation : Cyancore Core-Team | ||
*/ | ||
|
||
#include <stdint.h> | ||
#include <stdbool.h> | ||
#include <assert.h> | ||
#include <status.h> | ||
#include <syslog.h> | ||
#include <plat_arch.h> | ||
#include <mmio.h> | ||
#include <arch.h> | ||
#include <terravisor/workers.h> | ||
|
||
static void arch_mcall_handler() | ||
{ | ||
context_frame_t *frame = get_context_frame(); | ||
mret_t mres; | ||
machine_call(frame->r0, frame->r1, frame->r3, &mres); | ||
frame->r0 = mres.p; | ||
frame->r1 = mres.size; | ||
frame->r2 = mres.status; | ||
return; | ||
} | ||
|
||
/** | ||
*arch_early_setup - This function is called in the early stages of boot | ||
* | ||
* @brief This function is respinsible to clean reset cpu status/control registers. | ||
* | ||
*/ | ||
void arch_early_setup() | ||
{ | ||
arch_di(); | ||
|
||
} | ||
|
||
/** | ||
* arch_setup - This function is called after initial setup is done | ||
* | ||
* @brief This function is called after initial setup is done. | ||
*/ | ||
void arch_setup() | ||
{ | ||
return; | ||
} | ||
|
||
void arch_di_save_state(istate_t *sreg_i_backup) | ||
{ | ||
* | ||
} | ||
|
||
void arch_ei_restore_state(istate_t *sreg_i_backup) | ||
{ | ||
|
||
} | ||
|
||
/** | ||
* arch_core_index - Returns code index | ||
*/ | ||
|
||
_WEAK unsigned int arch_core_index() | ||
{ | ||
return 0; | ||
} | ||
|
||
/** | ||
* arch_wfi - wait for interrupt | ||
* | ||
* @brief This function should be called when the program needs to | ||
* wait for interrupt. This also ensures low power consumption when compared to busy wait. | ||
*/ | ||
void arch_wfi() | ||
{ | ||
asm volatile("wfi"); | ||
} | ||
|
||
void _NORETURN arch_panic_handler_callback() | ||
{ | ||
context_frame_t *frame; | ||
frame = get_context_frame(); | ||
if(!frame) | ||
goto panic; | ||
syslog_stdout_enable(); | ||
sysdbg("r0=%p\tr1=%p\tr2=%p\tr3=%p\tr4=%p\tr5=%p\n", | ||
frame->r0, frame->r1, frame->r2, frame->r3, frame->r4, frame->r5); | ||
sysdbg("r6=%p\tr7=%p\tr8=%p\tr9=%p\tr10=%p\tr11=%p\n", | ||
frame->r6, frame->r7, frame->r8, frame->r9, frame->r10, frame->r11); | ||
sysdbg("r12=%p\tr13=%p\tr14=%p\tr15=%p\tAPSR=%p\n", | ||
frame->r12, frame->r13, frame->r14, frame->r15, frame->apsr); | ||
#if DEBUG==0 | ||
syslog(info, "APSR=%p\n", frame->apsr); | ||
#endif | ||
panic: | ||
while(1) arch_wfi(); | ||
} | ||
|
||
static cpu_sleep_t sleep_flag; | ||
|
||
/** | ||
* arch_suspended_state_was | ||
* | ||
* @brief This function checks for the suspended state | ||
* and returns true or flase based on arg. | ||
* | ||
* @param[in] state: suspended state | ||
* @return bool: True/False | ||
*/ | ||
|
||
bool arch_suspended_state_was(cpu_sleep_t state) | ||
{ | ||
assert(state != resume); | ||
if(!sleep_flag) | ||
return false; | ||
return (sleep_flag == state); | ||
} | ||
|
||
/** | ||
* arch_signal_suspend | ||
* | ||
* @brief This function is intended to be called before cpu enters | ||
* suspend state. By passing the state, we store and use to check while | ||
* exiting resume routine. | ||
* | ||
* @param[in] state: Suspend state of cpu | ||
*/ | ||
void arch_signal_suspend(cpu_sleep_t state) | ||
{ | ||
sleep_flag = state; | ||
} | ||
|
||
/** | ||
* @brief This function signals resume of cpu. It is intended | ||
* to be called after exiting resume routine. | ||
*/ | ||
void arch_signal_resume(void) | ||
{ | ||
sleep_flag = resume; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
* | ||
* CYANCORE LICENSE | ||
* Copyrights (C) 2022, Cyancore Team | ||
* | ||
* File Name : asm.S | ||
* Description : This file consists of all the function written in asm | ||
* like ISR, context management and panic handler | ||
* Primary Author : Mayuri Lokhande [[email protected]] | ||
* Organisation : Cyancore Core-Team | ||
*/ | ||
|
||
#include <asm.inc> | ||
#include <plat_arch.h> | ||
|
||
/** | ||
* PROLOGUE - A macro that defines context save operation. Saving only argument registers (r0 - r7) | ||
**/ | ||
|
||
.macro PROLOGUE | ||
push r0 | ||
push r1 | ||
MRS r1, APSR | ||
push r1 | ||
push r2 | ||
push r3 | ||
push r4 | ||
push r5 | ||
push r6 | ||
push r7 | ||
.endm | ||
|
||
/** | ||
* EPILOGUE - A macro that defines context restore operation | ||
**/ | ||
|
||
.macro EPILOGUE | ||
pop r7 | ||
pop r6 | ||
pop r5 | ||
pop r4 | ||
pop r3 | ||
pop r2 | ||
pop r1 | ||
MSR APSR, r1 | ||
pop r1 | ||
pop r0 | ||
.endm | ||
|
||
|
||
function int_ /id | ||
push r0 | ||
mov r0, #/id | ||
b isr | ||
|
||
/** | ||
* isr - interrupt service routine function | ||
* @brief This function is called from interrupt router. | ||
* It is responsible to do context management before and after | ||
* calling the interrupt handler function. | ||
*/ | ||
|
||
function isr | ||
PROLOGUE | ||
MRS r1, MPS | ||
add r1, #1 | ||
bl exception_handler | ||
EPILOGUE | ||
pop r0 | ||
|
||
/** | ||
* Interrupt Router Declaration Table | ||
* 1-15 Interrupt routers are define as of now. If possible more can | ||
* be added. But during compile time only necessary interrupt router | ||
* functions will be retained and others are cleaned up. | ||
*/ | ||
/*==========< Interrupt router functions >==========*/ | ||
.set i, 1 | ||
.rept 15 | ||
INT %i | ||
.set i, i+1 | ||
.endr |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
/* | ||
* CYANCORE LICENSE | ||
* Copyrights (C) 2019, Cyancore Team | ||
* | ||
* File Name : interrupt_handler.c | ||
* Description : This file consists of arch interrupt handler sources. | ||
* Primary Author : Mayuri Lokhande [[email protected]] | ||
* Organisation : Cyancore Core-Team | ||
*/ | ||
|
||
#include <stddef.h> | ||
#include <stdint.h> | ||
#include <stdbool.h> | ||
#include <status.h> | ||
#include <string.h> | ||
#include <assert.h> | ||
#include <arch.h> | ||
#include <assert.h> | ||
|
||
static context_frame_t *local_frame; | ||
|
||
static void set_context_frame(*frame) | ||
{ | ||
local_frame = frame; | ||
} | ||
|
||
bool in_isr(void) | ||
{ | ||
return (local_frame != NULL) ? true : false ; | ||
} | ||
|
||
/** | ||
* int_handler - Array of Interrupt handler pointers | ||
* | ||
* @brief This is a function pointer array which consists of addresses of corresponding | ||
* interrupt handler functions. This is by default assigned as arch_panic_handler. | ||
*/ | ||
static void (* exhandler[N_EXCEP])(void) = {{[0 ... N_EXCEP-1] = arch_panic_handler}}; | ||
|
||
/** | ||
* arch_register_interrupt_handlers - Registers arch interrupt handlers | ||
* @brief This function is responsible to registers all architectural level | ||
* Interrupt handling functions. | ||
* | ||
* @param[in] id: Interrupt ID | ||
* @param[in] *handler - function pointer of interrupt handling function. | ||
*/ | ||
|
||
void arch_register_interrupt_handler(unsigned int id, void(* handler)(void)) | ||
{ | ||
/*Check if Interrupt ID is valid*/ | ||
assert((id > 0) && (id <= N_EXCEP)); | ||
|
||
/* | ||
* Decrement ID as array indexing starts from 0. | ||
* ID = 0 is CPU entry address. | ||
*/ | ||
id --; | ||
|
||
/*Store interrupt handler*/ | ||
exhandler[id] = handler; | ||
} | ||
|
||
/** | ||
* Exception handler - Executes Interrupt handler corresponding to int ID | ||
* | ||
* @brief This function is called by ISR. It executes function pointed by int_handler. | ||
* It accepts int ID as argument, which indexes the interrupt handling function. | ||
* | ||
* @param[in] id: Interrupt ID | ||
*/ | ||
|
||
void exception_handler(unsigned int id, context_frame_t *frame) | ||
{ | ||
set_context_frame(frame); | ||
|
||
/*Check if Interrupt ID is valid*/ | ||
if((id > 0) && (id <= N_EXCEP)) | ||
{ | ||
/* | ||
* Decrement ID as array indexing starts from 0. | ||
* ID = 0 is CPU entry address. | ||
*/ | ||
id --; | ||
|
||
/* Get corresponding interrupt handling function */ | ||
void (*handler)(void) = exhandler[id] | ||
|
||
/* Check if the handler is valid*/ | ||
assert(handler) | ||
|
||
/* Execute exception handler */ | ||
handler(); | ||
} | ||
else if(id == 65535) | ||
plat_panic_handler_callback(); | ||
else if(id == 65536) | ||
arch_panic_handler_callback(); | ||
else{} | ||
set_context_frame(NULL); | ||
return; | ||
} | ||
|
||
context_frame_t *get_context_frame() | ||
{ | ||
if(local_frame) | ||
return local_frame; | ||
return NULL; | ||
} |
Oops, something went wrong.