Skip to content

Commit

Permalink
evalsoc: add Zcmt table jump example for rompatch similiar case (#21)
Browse files Browse the repository at this point in the history
Signed-off-by: Huaqi Fang <[email protected]>
  • Loading branch information
fanghuaqi authored Dec 1, 2023
1 parent 58cfdc0 commit 8485dad
Show file tree
Hide file tree
Showing 4 changed files with 191 additions and 0 deletions.
15 changes: 15 additions & 0 deletions evalsoc/zcmt_jumptable/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
TARGET = jmp

NUCLEI_SDK_ROOT = ../../..

CORE ?= n300

ARCH_EXT ?= _zca_zcb_zcmp_zcmt

SRCDIRS = .

INCDIRS = .

COMMON_FLAGS := -O3

include $(NUCLEI_SDK_ROOT)/Build/Makefile.base
27 changes: 27 additions & 0 deletions evalsoc/zcmt_jumptable/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# RISC-V Zcmt Jump Table Example For Nuclei SDK

This example is used to demostrate how to use Zcmt extension to implement
runtime jump function replacement, so you can do hotfix for certain functions.

## Run in command line

You need to download Nuclei SDK >= 0.5.0 version.

~~~shell
cd /path/to/nuclei-sdk
cd nuclei-board-labs/evalsoc/zcmt_jumptable
# build it
# Assume environment is already setup, see https://doc.nucleisys.com/nuclei_sdk/quickstart.html
# Require Nuclei Studio 2023.10
make all
# run on qemu
make run_qemu
# run on hw
# require N300 with Zc extension bitstream
make upload
~~~

## Run in Nuclei Studio

> Nuclei Studio >= 2023.10 is required
91 changes: 91 additions & 0 deletions evalsoc/zcmt_jumptable/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
#include "nuclei_sdk_hal.h"
#include <stdio.h>

// used for jump table index < 32, cm.jt
// https://github.com/riscv/riscv-code-size-reduction/blob/main/Zc-specification/cm_jt.adoc
void __attribute__ ((naked)) zcmt_cmjt(void)
{
asm volatile("cm.jt 0 \n");
}

// used for jump table index >= 32, cm.jalt
// https://github.com/riscv/riscv-code-size-reduction/blob/main/Zc-specification/cm_jalt.adoc
void __attribute__ ((naked)) zcmt_cmjalt(void)
{
#if __riscv_xlen == 32
asm volatile(
"add sp,sp,-4\n"
"sw ra,0(sp) \n"
"cm.jalt 255 \n"
"lw ra,0(sp) \n"
"add sp,sp,4\n"
"ret");
#else
asm volatile(
"add sp,sp,-8\n"
"sd ra,0(sp) \n"
"cm.jalt 255 \n"
"ld ra,0(sp) \n"
"add sp,sp,8\n"
"ret");
#endif
}

// Test func 1
void abc()
{
printf("hello from abc\n");
}

// Test func 2
void cdf()
{
printf("hello from cdf\n");
}

// Need to align at 64bytes, required by jvt csr
// The value in the BASE field must always be aligned on a 64-byte boundary. see https://github.com/riscv/riscv-code-size-reduction/blob/main/Zc-specification/jvt_csr.adoc
// For this encoding to decode as cm.jalt, index>=32, otherwise it decodes as cm.jt
// max entries are 0-255, total 256 entries
// TODO jump table need to place in a ram where cpu instruction fetch unit and data acess unit can both access it
static unsigned long jptbl[256] __ALIGNED(64) = {};

unsigned long update_jump_table(unsigned long index, unsigned long funptr)
{
unsigned long *tbptr = (unsigned long *)__RV_CSR_READ(CSR_JVT);

if (tbptr != jptbl) {
printf("jump table not match!\n");
return 1;
}
tbptr[index] = funptr;
// fence.i is required to flush cache if cache present
__FENCE_I();
}

// NOTE: About Zcmt table jump, see https://github.com/riscv/riscv-code-size-reduction/blob/main/Zc-specification/tablejump.adoc
void main(void)
{
__RV_CSR_WRITE(CSR_JVT, jptbl);

printf("Jump table located in 0x%x\n", __RV_CSR_READ(CSR_JVT));

printf("--> Test cm.jt instruction!\n");
// let cm.jt jump to abc
update_jump_table(0, (unsigned long)abc);
// before execute this function the jump table must be initialized
zcmt_cmjt();

// let cm.jt jump to cdf
update_jump_table(0, (unsigned long)cdf);
zcmt_cmjt();

printf("--> Test cm.jalt instruction!\n");
// let cm.jalt jump to abc
update_jump_table(255, (unsigned long)abc);
zcmt_cmjalt();

// let cm.jalt jump to cdf
update_jump_table(255, (unsigned long)cdf);
zcmt_cmjalt();
}
58 changes: 58 additions & 0 deletions evalsoc/zcmt_jumptable/npk.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
## Package Base Information
name: app_evalsoc_zcmt_jumptable
owner: nuclei
version: 1.0.0
description: Nuclei Zcmt Jump Table Demo
type: app
keywords:
- nuclei board labs
- baremetal
- jump table
category: Board Labs
license: Apache-2.0
homepage: https://github.com/Nuclei-Software/nuclei-board-labs/tree/master/evalsoc/zcmt_jumptable

## Package Dependency
dependencies:
- name: ssp-nsdk_evalsoc
owner: nuclei
version:

## Package Configurations
configuration:
app_commonflags:
value: -O3
type: text
description: Application Compile Flags

setconfig:
- config: nuclei_core
value: n300
- config: nuclei_archext
value: _zca_zcb_zcmp_zcmt

## Source Code Management
codemanage:
copyfiles:
- path: ["*.c", "*.h", "*.S", "*.s", "*.C"]
incdirs:
- path: ["./"]
libdirs:
ldlibs:
- libs: [""]

## Build Configuration
buildconfig:
- type: common
common_flags: # flags need to be combined together across all packages
- flags: ${app_commonflags}
ldflags:
cflags:
asmflags:
cxxflags:
prebuild_steps: # could be override by app/bsp type
command:
description:
postbuild_steps: # could be override by app/bsp type
command:
description:

0 comments on commit 8485dad

Please sign in to comment.