Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RISC-V ACLINT Support #53

Merged
merged 3 commits into from
Nov 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion .github/workflows/build-riscv.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,13 @@ jobs:
"PLIC",
"APLIC",
]
ipic: [
"IPIC_SBI",
"IPIC_ACLINT",
]
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- run: make PLATFORM=${{ matrix.platform }} IRQC=${{ matrix.irqc }} CONFIG=null
- run: make PLATFORM=${{ matrix.platform }} IRQC=${{ matrix.irqc }} \
IPIC=${{ matrix.ipic }} CONFIG=null
2 changes: 2 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,8 @@ gens+=$(config_def_generator) $(config_defs)
inc_dirs+=$(config_build_dir)

platform_def_generator_src:=$(scripts_dir)/platform_defs_gen.c
platform_arch_def_generator_src:=$(wildcard $(scripts_dir)/arch/$(ARCH)/platform_defs_gen.c)
platform_def_generator_src+=$(platform_arch_def_generator_src)
platform_def_generator:=$(scripts_build_dir)/platform_defs_gen
platform_defs:=$(platform_build_dir)/platform_defs_gen.h
platform_description:=$(platform_dir)/$(platform_description)
Expand Down
15 changes: 15 additions & 0 deletions scripts/arch/riscv/platform_defs_gen.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/**
* SPDX-License-Identifier: Apache-2.0
* Copyright (c) Bao Project and Contributors. All rights reserved
*/

#include <stdio.h>
#include <platform.h>

void arch_platform_defs() {

if (platform.arch.aclint_sswi.base != 0) {
printf("#define ACLINT_SSWI 1\n");
}

}
7 changes: 5 additions & 2 deletions scripts/platform_defs_gen.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
#include <stdio.h>
#include <platform.h>

extern void arch_platform_defs();
__attribute__((weak)) void arch_platform_defs(void){
return;
}

int main() {

Expand All @@ -15,6 +17,7 @@ int main() {
if (platform.cpu_master_fixed) {
printf("#define CPU_MASTER_FIXED (%ld)\n", platform.cpu_master);
}

// Call arch specific platform defines generator
arch_platform_defs();
return 0;
}
40 changes: 40 additions & 0 deletions src/arch/riscv/aclint.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/**
* SPDX-License-Identifier: Apache-2.0
* Copyright (c) Bao Project and Contributors. All rights reserved.
*/

#include <arch/aclint.h>
#include <cpu.h>
#include <bao.h>
#include <platform.h>

volatile struct aclint_sswi_hw* aclint_sswi;

void aclint_init()
{
aclint_sswi = (void*)mem_alloc_map_dev(&cpu()->as, SEC_HYP_GLOBAL, INVALID_VA,
platform.arch.aclint_sswi.base, NUM_PAGES(sizeof(struct aclint_sswi_hw)));
}

void aclint_send_ipi(cpuid_t target_hart)
{
cpuid_t aclint_index = aclint_plat_hart_id_to_sswi_index(target_hart);
if (target_hart < platform.cpu_num) {
aclint_sswi->setssip[aclint_index] = ACLINT_SSWI_SET_SETSSIP;
}
}

/**
* By default aclint hart index is equal to the hart identifier
* This may be overwritten on the platform defined code
*/

__attribute__((weak)) cpuid_t aclint_plat_sswi_index_to_hart_id(cpuid_t sswi_index)
{
return sswi_index;
}

__attribute__((weak)) cpuid_t aclint_plat_hart_id_to_sswi_index(cpuid_t hart_id)
{
return hart_id;
}
28 changes: 28 additions & 0 deletions src/arch/riscv/inc/arch/aclint.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/**
* SPDX-License-Identifier: Apache-2.0
* Copyright (c) Bao Project and Contributors. All rights reserved.
*/

#ifndef ACLINT_H
#define ACLINT_H

#include <bao.h>
#include <platform.h>

#define ACLINT_SSWI_MAX_HARTS (4095)
#define ACLINT_SSWI_SET_SETSSIP (0x1)

struct aclint_sswi_hw {
uint32_t setssip[ACLINT_SSWI_MAX_HARTS];
uint32_t res;
} __attribute__((__packed__, aligned(PAGE_SIZE)));

extern volatile struct aclint_sswi_hw* aclint_sswi;

void aclint_init();
void aclint_send_ipi(cpuid_t hart);

cpuid_t aclint_plat_sswi_index_to_hart_id(cpuid_t sswi_index);
cpuid_t aclint_plat_hart_id_to_sswi_index(cpuid_t hard_id);

#endif /* ACLINT_H */
14 changes: 8 additions & 6 deletions src/arch/riscv/inc/arch/interrupts.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,20 @@
#include <bao.h>
#include <irqc.h>

#define PLIC (1)
#define APLIC (2)
#define PLIC (1)
#define APLIC (2)

#define ACLINT_PRESENT() DEFINED(ACLINT_SSWI)

/**
* In riscv, the ipi (software interrupt) and timer interrupts dont actually have an ID as their
* are treated differently from external interrupts routed by the external interrupt controller,
* the PLIC. Will define their ids as the ids after the maximum possible in the PLIC.
*/
#define SOFT_INT_ID (IRQC_MAX_INTERRUPTS + 1)
#define TIMR_INT_ID (IRQC_MAX_INTERRUPTS + 2)
#define MAX_INTERRUPTS (TIMR_INT_ID + 1)
#define SOFT_INT_ID (IRQC_MAX_INTERRUPTS + 1)
#define TIMR_INT_ID (IRQC_MAX_INTERRUPTS + 2)
#define MAX_INTERRUPTS (TIMR_INT_ID + 1)

#define IPI_CPU_MSG SOFT_INT_ID
#define IPI_CPU_MSG SOFT_INT_ID

#endif /* __ARCH_INTERRUPTS_H__ */
4 changes: 4 additions & 0 deletions src/arch/riscv/inc/arch/platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ struct arch_platform {
unsigned mode; // Overall IOMMU mode (Off, Bypass, DDT-lvl)
irqid_t fq_irq_id; // Fault Queue IRQ ID (wired)
} iommu;

struct {
paddr_t base; // Base address of the ACLINT supervisor software interrupts
} aclint_sswi;
};

#endif /* __ARCH_PLATFORM_H__ */
10 changes: 9 additions & 1 deletion src/arch/riscv/interrupts.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,15 @@
#include <vm.h>
#include <arch/csrs.h>
#include <fences.h>
#include <arch/aclint.h>

void interrupts_arch_init()
{
if (cpu()->id == CPU_MASTER) {
irqc_init();
if (ACLINT_PRESENT()) {
aclint_init();
}
}

/* Wait for master hart to finish irqc initialization */
Expand All @@ -34,7 +38,11 @@ void interrupts_arch_init()

void interrupts_arch_ipi_send(cpuid_t target_cpu, irqid_t ipi_id)
{
sbi_send_ipi(1ULL << target_cpu, 0);
if (ACLINT_PRESENT()) {
aclint_send_ipi(target_cpu);
} else {
sbi_send_ipi(1ULL << target_cpu, 0);
}
}

void interrupts_arch_cpu_enable(bool en)
Expand Down
1 change: 1 addition & 0 deletions src/arch/riscv/objects.mk
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@ cpu-objs-y+=cpu.o
cpu-objs-y+=cache.o
cpu-objs-y+=iommu.o
cpu-objs-y+=relocate.o
cpu-objs-y+=aclint.o
3 changes: 3 additions & 0 deletions src/platform/qemu-riscv64-virt/inc/plat/platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,7 @@

#define CPU_EXT_SSTC 1

#define IPIC_SBI (1)
#define IPIC_ACLINT (2)

#endif
4 changes: 3 additions & 1 deletion src/platform/qemu-riscv64-virt/platform.mk
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,14 @@ ARCH:=riscv
CPU:=
# Interrupt controller definition
IRQC:=PLIC
# Core IPIs controller
IPIC:=IPIC_SBI

drivers := sbi_uart

platform_description:=virt_desc.c

platform-cppflags =
platform-cppflags =-DIPIC=$(IPIC)
platform-cflags =
platform-asflags =
platform-ldflags =
7 changes: 7 additions & 0 deletions src/platform/qemu-riscv64-virt/virt_desc.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,13 @@ struct platform platform = {
.irqc.aia.aplic.base = 0xd000000,
#else
#error "unknown IRQC type " IRQC
#endif
#if (IPIC == IPIC_SBI)
.aclint_sswi.base = 0,
#elif (IPIC == IPIC_ACLINT)
.aclint_sswi.base = 0x2f00000,
#else
#error "unknown IPIC type " IPIC
#endif
},

Expand Down