mirror of
https://github.com/plctlab/riscv-operating-system-mooc.git
synced 2025-11-16 12:34:47 +00:00
Following the standard RISC-V calling convention, make sure the stack pointer sp is always 16-byte aligned. Fixed an issue, make sure the sp of task point to the bottom of the stack, while originally we waste one byte (forgive my stupid ~~~). Signed-off-by: Wang Chen <wangchen20@iscas.ac.cn>
86 lines
1.6 KiB
C
86 lines
1.6 KiB
C
#include "os.h"
|
|
|
|
/* defined in entry.S */
|
|
extern void switch_to(struct context *next);
|
|
|
|
#define MAX_TASKS 10
|
|
#define STACK_SIZE 1024
|
|
/*
|
|
* In the standard RISC-V calling convention, the stack pointer sp
|
|
* is always 16-byte aligned.
|
|
*/
|
|
uint8_t __attribute__((aligned(16))) task_stack[MAX_TASKS][STACK_SIZE];
|
|
struct context ctx_tasks[MAX_TASKS];
|
|
|
|
/*
|
|
* _top is used to mark the max available position of ctx_tasks
|
|
* _current is used to point to the context of current task
|
|
*/
|
|
static int _top = 0;
|
|
static int _current = -1;
|
|
|
|
void sched_init()
|
|
{
|
|
w_mscratch(0);
|
|
|
|
/* enable machine-mode software interrupts. */
|
|
w_mie(r_mie() | MIE_MSIE);
|
|
}
|
|
|
|
/*
|
|
* implment a simple cycle FIFO schedular
|
|
*/
|
|
void schedule()
|
|
{
|
|
if (_top <= 0) {
|
|
panic("Num of task should be greater than zero!");
|
|
return;
|
|
}
|
|
|
|
_current = (_current + 1) % _top;
|
|
struct context *next = &(ctx_tasks[_current]);
|
|
switch_to(next);
|
|
}
|
|
|
|
/*
|
|
* DESCRIPTION
|
|
* Create a task.
|
|
* - start_routin: task routine entry
|
|
* RETURN VALUE
|
|
* 0: success
|
|
* -1: if error occured
|
|
*/
|
|
int task_create(void (*start_routin)(void))
|
|
{
|
|
if (_top < MAX_TASKS) {
|
|
ctx_tasks[_top].sp = (reg_t) &task_stack[_top][STACK_SIZE];
|
|
ctx_tasks[_top].pc = (reg_t) start_routin;
|
|
_top++;
|
|
return 0;
|
|
} else {
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* DESCRIPTION
|
|
* task_yield() causes the calling task to relinquish the CPU and a new
|
|
* task gets to run.
|
|
*/
|
|
void task_yield()
|
|
{
|
|
/* trigger a machine-level software interrupt */
|
|
int id = r_mhartid();
|
|
*(uint32_t*)CLINT_MSIP(id) = 1;
|
|
}
|
|
|
|
/*
|
|
* a very rough implementaion, just to consume the cpu
|
|
*/
|
|
void task_delay(volatile int count)
|
|
{
|
|
count *= 50000;
|
|
while (count--);
|
|
}
|
|
|