Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
shengwen-tw committed Jan 25, 2024
2 parents 469bcfa + 35517a0 commit 9069999
Show file tree
Hide file tree
Showing 18 changed files with 233 additions and 109 deletions.
40 changes: 40 additions & 0 deletions .ci/autorun.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#!/usr/bin/env bash

function cleanup {
sleep 1
pkill -9 semu
}

function ASSERT {
$*
local RES=$?
if [ $RES -ne 0 ]; then
echo 'Assert failed: "' $* '"'
exit $RES
fi
}

cleanup

ASSERT expect <<DONE
set timeout 90
spawn make check
expect "buildroot login:" { send "root\n" } timeout { exit 1 }
expect "# " { send "uname -a\n" } timeout { exit 2 }
expect "riscv32 GNU/Linux" { send "\x01"; send "x" } timeout { exit 3 }
DONE

ret=$?
cleanup

MESSAGES=("OK!" \
"Fail to boot" \
"Fail to login" \
"Fail to run commands" \
)

COLOR_G='\e[32;01m' # Green
COLOR_N='\e[0m'
printf "\n[ ${COLOR_G}${MESSAGES[$ret]}${COLOR_N} ]\n"

exit ${ret}
10 changes: 7 additions & 3 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,24 @@ jobs:
rv32emu:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: install-dependencies
run: |
sudo apt-get install build-essential device-tree-compiler
sudo apt-get install expect
- name: default build
run: make
shell: bash
- name: automated test
run: .ci/autorun.sh
shell: bash

coding_style:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: coding convention
run: |
sudo apt-get install -q -y clang-format-12
sh .ci/check-format.sh
.ci/check-format.sh
shell: bash
87 changes: 66 additions & 21 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,42 +2,57 @@

:+1::tada: First off, thanks for taking the time to contribute! :tada::+1:

The following is a set of guidelines for contributing to [semu](https://github.com/jserv/semu)
hosted on GitHub. These are mostly guidelines, not rules. Use your best
judgment, and feel free to propose changes to this document in a pull request.
The following is a set of guidelines for contributing to [semu](https://github.com/sysprog21/semu)
hosted on GitHub. These are mostly guidelines, not rules.
Use your best judgment, and feel free to propose changes to this document in a pull request.

## Issues

This project uses GitHub Issues to track ongoing development, discuss project plans, and keep track of bugs. Be sure to search for existing issues before you create another one.
This project uses GitHub Issues to track ongoing development, discuss project plans, and keep track of bugs.
Be sure to search for existing issues before you create another one.

Visit our [Issues page on GitHub](https://github.com/jserv/semu/issues) to search and submit.
Visit our [Issues page on GitHub](https://github.com/sysprog21/semu/issues) to search and submit.

## Coding Convention

We welcome all contributions from corporate, academic and individual developers. However, there are a number of fundamental ground rules that you must adhere to in order to participate. These rules are outlined as follows:
* All code must adhere to the existing C coding style (see below). While we are somewhat flexible in basic style, you will adhere to what is currently in place. Uncommented, complicated algorithmic constructs will be rejected.
* All external pull requests must contain sufficient documentation in the pull request comments in order to be accepted.
Contributions from developers across corporations, academia, and individuals are welcome.
However, participation requires adherence to fundamental ground rules:
* Code must strictly adhere to the established C coding style (refer to the guidelines below).
While there is some flexibility in basic style, it is crucial to stick to the current coding standards.
Complex algorithmic constructs without proper comments will not be accepted.
* External pull requests should include thorough documentation in the pull request comments for consideration.

Software requirement: [clang-format](https://clang.llvm.org/docs/ClangFormat.html) version 12 or later.

Use the command `$ clang-format -i *.[ch]` to enforce a consistent coding style.
This repository consistently contains an up-to-date `.clang-format` file with rules that match the explained ones.
For maintaining a uniform coding style, execute the command `clang-format -i *.[ch]`.

## Coding Style for Modern C

This coding style is a variation of the K&R style. Some general principles: honor tradition, but accept progress; be consistent;
embrace the latest C standards; embrace modern compilers, their static analysis
capabilities and sanitizers.
This coding style is a variant of the K&R style.
Adhere to established practices while being open to innovation.
Maintain consistency, adopt the latest C standards,
and embrace modern compilers along with their advanced static analysis capabilities and sanitizers.

### Indentation

Use 4 spaces rather than tabs.
In this coding style guide, the use of 4 spaces for indentation instead of tabs is strongly enforced to ensure consistency.
Consistently apply a single space before and after comparison and assignment operators to maintain readable code.
Additionally, it is crucial to include a single space after every comma.
e.g.,
```c
for (int i = 0; i < 10; i++) {
printf("%d\n", i);
/* some operations */
}
```

### Line length

All lines should generally be within 80 characters. Wrap long lines.
There are some good reasons behind this:
* It forces the developer to write more succinct code;
* Humans are better at processing information in smaller quantity portions;
All lines should typically stay within 80 characters, and longer lines should be wrapped.
There are valid rationales for this practice:
* It encourages concise code writing by developers.
* Smaller portions of information are easier for humans to process.
* It helps users of vi/vim (and potentially other editors) who use vertical splits.

### Comments
Expand Down Expand Up @@ -66,7 +81,12 @@ Leave two spaces between the statement and the inline comment.
### Spacing and brackets

Use one space after the conditional or loop keyword, no spaces around
their brackets, and one space before the opening curly bracket.
their brackets, and one space before the opening curly bracket. e.g.,
```c
do {
/* some operations */
} while (condition);
```

Functions (their declarations or calls), `sizeof` operator or similar
macros shall not have a space after their name/keyword or around the
Expand All @@ -81,6 +101,8 @@ but otherwise avoid redundant or excessive brackets.

### Variable names and declarations

- Ensure that functions, variables, and comments are consistently named using English names/text.

- Use descriptive names for global variables and short names for locals.
Find the right balance between descriptive and succinct.

Expand All @@ -97,6 +119,29 @@ const uint8_t * const charmap; /* const pointer and const data */
const void * restrict key; /* const pointer which does not alias */
```

- Local variables of the same type should be declared in the same line.
```c
void func(void)
{
char a, b; /* OK */

char a;
char b; /* Incorrect: A variable with char type already exists. */
}
```
- Always include a trailing comma in the last element of structure initialization, including its children, to assist clang-format in correctly formatting structures. However, this can be omitted in very simple and short structures.
```c
typedef struct {
int width, height;
} screen_t;
screen_t s = {
.width = 640,
.height = 480, /* comma here */
}
```

### Type definitions

Declarations shall be on the same line, e.g.,
Expand Down Expand Up @@ -418,9 +463,9 @@ printf("val %lld\n", SOME_CONSTANT);

#### Avoid unaligned access

Do not assume unaligned access is safe. It is not safe on Arm, POWER,
and various other architectures. Moreover, even on x86 unaligned access
is slower.
Avoid assuming that unaligned access is safe.
It is not secure on architectures like Arm, POWER, and others.
Additionally, even on x86, unaligned access can be slower.

#### Avoid extreme portability

Expand Down
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (C) 2022-2023 National Cheng Kung University, Taiwan.
Copyright (C) 2022-2024 National Cheng Kung University, Taiwan.
All rights reserved.

Permission is hereby granted, free of charge, to any person obtaining a copy
Expand Down
2 changes: 1 addition & 1 deletion device.h
Original file line number Diff line number Diff line change
Expand Up @@ -239,5 +239,5 @@ typedef struct {
#if SEMU_HAS(VIRTIOGPU)
virtio_gpu_state_t vgpu;
#endif
uint32_t timer_lo, timer_hi;
uint64_t timer;
} emu_state_t;
40 changes: 20 additions & 20 deletions main.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,32 +14,34 @@
#include "riscv_private.h"
#include "window.h"

#define PRIV(x) ((emu_state_t *) x->priv)

/* Define fetch separately since it is simpler (fixed width, already checked
* alignment, only main RAM is executable).
*/
static void mem_fetch(vm_t *vm, uint32_t addr, uint32_t *value)
static void mem_fetch(vm_t *vm, uint32_t n_pages, uint32_t **page_addr)
{
emu_state_t *data = (emu_state_t *) vm->priv;
if (unlikely(addr >= RAM_SIZE)) {
emu_state_t *data = PRIV(vm);
if (unlikely(n_pages >= RAM_SIZE / RV_PAGE_SIZE)) {
/* TODO: check for other regions */
vm_set_exception(vm, RV_EXC_FETCH_FAULT, vm->exc_val);
return;
}
*value = data->ram[addr >> 2];
*page_addr = &data->ram[n_pages << (RV_PAGE_SHIFT - 2)];
}

/* Similarly, only main memory pages can be used as page tables. */
static uint32_t *mem_page_table(const vm_t *vm, uint32_t ppn)
{
emu_state_t *data = (emu_state_t *) vm->priv;
emu_state_t *data = PRIV(vm);
if (ppn < (RAM_SIZE / RV_PAGE_SIZE))
return &data->ram[ppn << (RV_PAGE_SHIFT - 2)];
return NULL;
}

static void emu_update_uart_interrupts(vm_t *vm)
{
emu_state_t *data = (emu_state_t *) vm->priv;
emu_state_t *data = PRIV(vm);
u8250_update_interrupts(&data->uart);
if (data->uart.pending_ints)
data->plic.active |= IRQ_UART_BIT;
Expand All @@ -51,7 +53,7 @@ static void emu_update_uart_interrupts(vm_t *vm)
#if SEMU_HAS(VIRTIONET)
static void emu_update_vnet_interrupts(vm_t *vm)
{
emu_state_t *data = (emu_state_t *) vm->priv;
emu_state_t *data = PRIV(vm);
if (data->vnet.InterruptStatus)
data->plic.active |= IRQ_VNET_BIT;
else
Expand All @@ -63,7 +65,7 @@ static void emu_update_vnet_interrupts(vm_t *vm)
#if SEMU_HAS(VIRTIOBLK)
static void emu_update_vblk_interrupts(vm_t *vm)
{
emu_state_t *data = (emu_state_t *) vm->priv;
emu_state_t *data = PRIV(vm);
if (data->vblk.InterruptStatus)
data->plic.active |= IRQ_VBLK_BIT;
else
Expand All @@ -86,8 +88,7 @@ static void emu_update_vgpu_interrupts(vm_t *vm)

static void mem_load(vm_t *vm, uint32_t addr, uint8_t width, uint32_t *value)
{
emu_state_t *data = (emu_state_t *) vm->priv;

emu_state_t *data = PRIV(vm);
/* RAM at 0x00000000 + RAM_SIZE */
if (addr < RAM_SIZE) {
ram_read(vm, data->ram, addr, width, value);
Expand Down Expand Up @@ -131,8 +132,7 @@ static void mem_load(vm_t *vm, uint32_t addr, uint8_t width, uint32_t *value)

static void mem_store(vm_t *vm, uint32_t addr, uint8_t width, uint32_t value)
{
emu_state_t *data = (emu_state_t *) vm->priv;

emu_state_t *data = PRIV(vm);
/* RAM at 0x00000000 + RAM_SIZE */
if (addr < RAM_SIZE) {
ram_write(vm, data->ram, addr, width, value);
Expand Down Expand Up @@ -185,11 +185,11 @@ typedef struct {

static inline sbi_ret_t handle_sbi_ecall_TIMER(vm_t *vm, int32_t fid)
{
emu_state_t *data = (emu_state_t *) vm->priv;
emu_state_t *data = PRIV(vm);
switch (fid) {
case SBI_TIMER__SET_TIMER:
data->timer_lo = vm->x_regs[RV_R_A0];
data->timer_hi = vm->x_regs[RV_R_A1];
data->timer = (((uint64_t) vm->x_regs[RV_R_A1]) << 32) |
(uint64_t) (vm->x_regs[RV_R_A0]);
return (sbi_ret_t){SBI_SUCCESS, 0};
default:
return (sbi_ret_t){SBI_ERR_NOT_SUPPORTED, 0};
Expand All @@ -198,7 +198,7 @@ static inline sbi_ret_t handle_sbi_ecall_TIMER(vm_t *vm, int32_t fid)

static inline sbi_ret_t handle_sbi_ecall_RST(vm_t *vm, int32_t fid)
{
emu_state_t *data = (emu_state_t *) vm->priv;
emu_state_t *data = PRIV(vm);
switch (fid) {
case SBI_RST__SYSTEM_RESET:
fprintf(stderr, "system reset: type=%u, reason=%u\n",
Expand All @@ -211,7 +211,7 @@ static inline sbi_ret_t handle_sbi_ecall_RST(vm_t *vm, int32_t fid)
}

#define RV_MVENDORID 0x12345678
#define RV_MARCHID ((1 << 31) | 1)
#define RV_MARCHID ((1ULL << 31) | 1)
#define RV_MIMPID 1

static inline sbi_ret_t handle_sbi_ecall_BASE(vm_t *vm, int32_t fid)
Expand Down Expand Up @@ -395,6 +395,7 @@ static int semu_start(int argc, char **argv)
.mem_store = mem_store,
.mem_page_table = mem_page_table,
};
vm_init(&vm);

/* Set up RAM */
emu.ram = mmap(NULL, RAM_SIZE, PROT_READ | PROT_WRITE,
Expand Down Expand Up @@ -431,7 +432,7 @@ static int semu_start(int argc, char **argv)
atexit(unmap_files);

/* Set up RISC-V hart */
emu.timer_hi = emu.timer_lo = 0xFFFFFFFF;
emu.timer = 0xFFFFFFFFFFFFFFFF;
vm.s_mode = true;
vm.x_regs[RV_R_A0] = 0; /* hart ID. i.e., cpuid */
vm.x_regs[RV_R_A1] = dtb_addr;
Expand Down Expand Up @@ -482,8 +483,7 @@ static int semu_start(int argc, char **argv)
#endif
}

if (vm.insn_count_hi > emu.timer_hi ||
(vm.insn_count_hi == emu.timer_hi && vm.insn_count > emu.timer_lo))
if (vm.insn_count > emu.timer)
vm.sip |= RV_INT_STI_BIT;
else
vm.sip &= ~RV_INT_STI_BIT;
Expand Down
5 changes: 3 additions & 2 deletions minimal.dts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
model = "semu";

aliases {
serial0 = "/soc/serial@4000000";
serial0 = "/soc@F0000000/serial@4000000";
};

chosen {
Expand All @@ -28,6 +28,7 @@
mmu-type = "riscv,rv32";
cpu0_intc: interrupt-controller {
#interrupt-cells = <1>;
#address-cells = <0>;
interrupt-controller;
compatible = "riscv,cpu-intc";
};
Expand All @@ -40,7 +41,7 @@
reg-names = "sram0";
};

soc {
soc: soc@F0000000 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "simple-bus";
Expand Down
Loading

0 comments on commit 9069999

Please sign in to comment.