Skip to content

Commit

Permalink
<RP2040> Add CPU and platform initial support
Browse files Browse the repository at this point in the history
Issue: #87 #231
  • Loading branch information
MayuriLokhande committed Feb 12, 2023
1 parent 07faeae commit c4c6195
Show file tree
Hide file tree
Showing 11 changed files with 823 additions and 5 deletions.
146 changes: 146 additions & 0 deletions src/arch/arm/32m/common_v6_v7/supervisor/arch.c
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;
}
81 changes: 81 additions & 0 deletions src/arch/arm/32m/common_v6_v7/supervisor/asm.S
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
109 changes: 109 additions & 0 deletions src/arch/arm/32m/common_v6_v7/supervisor/exception_handler.c
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;
}
Loading

0 comments on commit c4c6195

Please sign in to comment.