Why User-mode interrupt was introduced in RISC-V?
In RISC-V privileged architecture V1.11 or draft of version 1.12, "N" extension is introduced for User-level interrupts, hardware which implemented this extension can transfer control directly to a user-level trap handler without invoking the outer execution environment.
But there are mirrored CSR and instruction for the N extension, for a system which support M and U mode only, the both save and restore similar context for interrupts, so why the N extension introduced and what benefit can we get?
do you know?
how many words do you know
See also questions close to this topic
-
Can i use interrupts in inline assembly
I want to use interrupts in inline asm but it is not letting me I think my app is this
__asm__("movb %ah,9;" "movb %al,0x41;" "movb %bh,0x0;" "movw %cx,0x1; " "movb %bl,0x0F ;" "int $10; ");
I am getting nothing after running this just a blank space what should I do?
-
does single step interrupt(01H interrupt) clear TF flag after every instruction?
i want to use single step interrupt and i understand that for make this interrupt work for every instruction the TF flag should be 1 (TF=1). and in my code i see single step interrupt work but after some instructions(maybe after every output) it stop and i should make TF=1 again to continue code and continue display outputs). does that mean after every instruction or after special instructions cause TF=0 again ? this code i used to set TF=1
asm{ PUSHF MOV BP,SP OR WORD PTR[BP+0],0100H POPF }
-
Can a RDMA write verb cause interrupt on the targeted server?
Hi i am wondering whether a RDMA write verb can cause interrupt on the targeted server? i don't think this is how people would use it but i am just curious whether the RDMA can or can't
-
JPA Specification with null parameter
I have created JPA Specification like
public class CarFilterSpecs { public static Specification<Car> carStatusIn(Collection<String> carStatus) { return (root, query, builder) -> CollectionUtils.isEmpty(carStatus) ? builder.conjunction() : carStatus.contains(-1) ? builder.isNull(root.get("carStatus").get("id")) : root.get("carStatus").get("id").in(carStatus); } public static Specification<Car> carVisibilityStatusIn(Collection<String> carVisibilityStatus) { return (root, query, builder) -> CollectionUtils.isEmpty(carVisibilityStatus) ? builder.conjunction() : carVisibilityStatus.contains(-1) ? builder.isNull(root.get("carVisibilityStatus")) : root.get("carVisibilityStatus").in(carVisibilityStatus); } }
and models looks like
public class Status { String id; String name; } public class Car { String id; Status status; ... }
and I am consuming the spec like
import org.springframework.data.jpa.domain.Specification; Specification<Car> specs = Specification.where(CarSpecs.carStatusIn(status)) .and(CarSpecs.carVisibilityStatusIn(visibilityStatus)); carRepository.findAll(specs);
till here works perfectly but now I am failing to get cars with some status and as well cars with status null(there is a chance of having status null)
-
HTML FORMS - How do you ask for input to be in a specific format? (Discord name#ID format)
This is a part of my form:
<input class="input-text" type="text" pattern=".+#.+" name="Name-hash-ID" placeholder="Your name + # + four digit number ID*"/>
I want the user to write down in this specific format:
his username + # + number
But I also have some more specifications... I need the user's number to be 4 DIGITS exactly and the username to be between 2-12 characters only. Also to separate the number and name, user must also have a HASHTAG between...
How do you use the pattern attribute in this scenario? Thanks
-
Rebuild QEMU (For RISCV-GNU-TOOLCHAIN)
This is a follow-up from the following question Custom Instruction crashing with SIGNAL 4 (Illegal Instruction): RISC-V (32) GNU-Toolchain with QEMU (apologies if I have missed any etiquette points in advance or formatted this in an unsavoury way, as I am still new to posting here). I am using the latest version of the riscv-gnu-toolchain, so I am just wondering what caveats and differences this process will be for this platform.
I was following namely two guides to add custom RISC-V instructions to QEMU - namely https://www.ashling.com/wp-content/uploads/QEMU_CUSTOM_INST_WP.pdf and https://chowdera.com/2021/04/20210430120004272q.html.
After editing qemu/target/riscv/insn32.decode with a free opcode (following Ashling tutorial), and implementing translator function in insn_trans/trans_rvi.c.inc - QEMU hangs when calling the function as an .insn directive (I know this to work - ). Changing opcodes of existing instructions to test if disassembly changes indicated to me that QEMU was not registering the changes I made and that I didn't rebuild/recompile QEMU correctly. I simply ran
make clean
, reconfigured andmake
again in the QEMU directory to rebuild it - Is this the correct way to rebuild QEMU in this toolchain or is there something I missed.The code to call
#include <stdio.h> static int test_ins(int a, int b) { int result; asm volatile(".insn r 0x33, 7, 0x20, %0, %1, %2" : "=r"(result) : "r"(a), "r"(b)); return result; } int main() { int a, b, result; a = 2; b = 4; result = test_ins(a,b); printf("%d\n", result); }
Instruction in insn32.decode is as follows:
OPCODE = "0110011", FUNCT3 = "111" and FUNCT7 = "0100000".
Implementation of aforementioned instruction is as follows:
static bool trans_bitcnt(DisasContext *ctx, arg_bitcnt *a) { TCGLabel *loop_source1 = gen_new_label(); TCGLabel *loop_source2 = gen_new_label(); TCGv source1, source2, dstval, cntval; source1 = tcg_temp_local_new(); source2 = tcg_temp_local_new(); dstval = tcg_temp_local_new(); cntval = tcg_temp_local_new(); // Count all the bits set in rs1 and rs2 and put that number in rd gen_get_gpr(source1, a->rs1); gen_get_gpr(source2, a->rs2); tcg_gen_movi_tl(cntval, 0x0); /* Count the bits that are set in the first register */ gen_set_label(loop_source1); tcg_gen_andi_tl(dstval, source1, 0x1); tcg_gen_shri_tl(source1, source1, 0x1); tcg_gen_add_tl(cntval, cntval, dstval); tcg_gen_brcondi_tl(TCG_COND_NE, source1, 0x0, loop_source1); /* Count the bits that are set in the second register */ gen_set_label(loop_source2); tcg_gen_andi_tl(dstval, source2, 0x1); tcg_gen_shri_tl(source2, source2, 0x1); tcg_gen_add_tl(cntval, cntval, dstval); tcg_gen_brcondi_tl(TCG_COND_NE, source2, 0x0, loop_source2); /* Update the destination register with the bits total */ gen_set_gpr(a->rd, cntval); tcg_temp_free(source1); tcg_temp_free(source2); tcg_temp_free(dstval); tcg_temp_free(cntval); return true; }
-
[risc-v]does 2-way Simultaneous multithreading core share register files, or do they have separate registers?
For example, in an 4-core system with 2-way SMT, you have 8 harts, which is it? 4 separate x0-x31 registers ,pc, and csrs, or 8 separate x0-x31, pc, and csrs?
-
Reading RISC-V CSR registers using C asm
I'm trying to read a csr register using function macro
I have a struct array that contains name and address of csr registers
typedef struct csr_lists { int address; const cahr* name; } csr_lists; csr_lists list[] = { {0xc00, "CYCLE"}, ... };
And the function I made:
#define csr_read(csr) \ ({ \ register uint32_t v; \ __asm__ __volatile__ ("csrr %0, %1" \ : "=r" (v) \ : "n" (csr) \ : "memory"); \ v; \ })
So it is called like
uint64_t value = csr_read(list[i].address);
oruint64_t value = csr_read(0xc00);
And the compiler gives me following errors
csr.h:68:2: error: asm operand 1 probably doesn’t match constraints [-Werror] 68 | __asm__ __volatile__ ("csrr %0, %1" \ | ^~~~~~~ csr.c:127:25: note: in expansion of macro ‘csr_read’ 127 | value[i] = csr_read(list[i].address); | csr.h:68:2: error: impossible constraint in ‘asm’ 68 | __asm__ __volatile__ ("csrr %0, %1" \ | ^~~~~~~ csr.c:127:25: note: in expansion of macro ‘csr_read’ 127 | value[i] = csr_read(list[i].address); | cc1: all warnings being treated as errors /mnt/d/project/riscv32-linux/buildroot-2021.02.10/output/host/lib/gcc/riscv32-buildroot-linux-gnu/9.4.0/../../../../riscv32-buildroot-linux-gnu/bin/ld: ./libhpm.so: undefined reference to `csr_read'
How can I fix this problem?
edit) The problem happens at these lines
#define MAX 7 for (i = 0; i < MAX; i++) { value[i] = csr_read(list[i].address); }