arch-riscv,dev: Add HiFive Base Platform

This is basic abstract platform and all of RISC-V system should
use platform inherit from HiFiveBase, HiFiveBase declared the common
way to handle interrupt.

Change-Id: I52122e1c82c200d7e6012433c2535c07d427f637
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/68199
Maintainer: Jason Lowe-Power <power.jg@gmail.com>
Reviewed-by: Yu-hsin Wang <yuhsingw@google.com>
Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
Roger Chang
2023-02-21 12:02:37 +08:00
parent 2209957256
commit e6604bf109
4 changed files with 107 additions and 79 deletions

View File

@@ -1,5 +1,6 @@
# Copyright (c) 2021 Huawei International
# Copyright (c) 2022 EXAscale Performance SYStems (EXAPSYS)
# Copyright (c) 2023 Google LLC
# All rights reserved.
#
# The license below extends only to copyright in the software and shall
@@ -63,24 +64,14 @@ class GenericRiscvPciHost(GenericPciHost):
_dma_coherent = True
class HiFive(Platform):
"""HiFive Platform
class HiFiveBase(Platform):
"""HiFive Base Abstract Platform
Implementation:
This is the base class for SiFive's HiFive
board series. It contains the CLINT and PLIC
interrupt controllers, Uart and Disk.
Implementation details are based on SiFive
FU540-C000. https://sifive.cdn.prismic.io/
sifive/b5e7a29c-d3c2-44ea-85fb-acc1df282e2
1_FU540-C000-v1p3.pdf
Setup:
The following sections outline the required
setup for a RISC-V HiFive platform. See
configs/example/riscv/fs_linux.py for example.
Driving CLINT:
CLINT has an interrupt pin which increments
mtime. It can be connected to any interrupt
@@ -88,7 +79,7 @@ class HiFive(Platform):
abstract RTC wrapper called RiscvRTC can be
used.
Attaching PLIC devices:
Driving PLIC:
PLIC handles external interrupts. Interrupt
PioDevices should inherit from PlicIntDevice
(PCI and DMA not yet implemented). It contains
@@ -96,63 +87,30 @@ class HiFive(Platform):
to call platform->postPciInt(id).
All PLIC interrupt devices should be returned
by _off_chip_devices(). Calling attachPlic sets
up the PLIC interrupt source count.
Uart:
The HiFive platform also has an uart_int_id.
This is because Uart8250 uses postConsoleInt
instead of postPciInt. In the future if a Uart
that inherits PlicIntDevice is implemented,
this can be removed.
Disk:
See fs_linux.py for setup example.
PMAChecker:
The PMAChecker will be attached to the MMU of
each CPU (which allows them to differ). See
fs_linux.py for setup example.
by _off_chip_devices().
"""
type = "HiFive"
type = "HiFiveBase"
cxx_header = "dev/riscv/hifive.hh"
cxx_class = "gem5::HiFive"
cxx_class = "gem5::HiFiveBase"
# CLINT
clint = Param.Clint(Clint(pio_addr=0x2000000), "CLINT")
clint = Param.Clint(NULL, "CLINT")
# PLIC
plic = Param.Plic(Plic(pio_addr=0xC000000), "PLIC")
plic = Param.PlicBase(NULL, "PLIC")
# PCI
pci_host = GenericRiscvPciHost(
conf_base=0x30000000,
conf_size="256MB",
conf_device_bits=12,
pci_pio_base=0x2F000000,
pci_mem_base=0x40000000,
)
# Uart
uart = RiscvUart8250(pio_addr=0x10000000)
# Int source ID to redirect console interrupts to
# Set to 0 if using a pci interrupt for Uart instead
uart_int_id = Param.Int(0xA, "PLIC Uart interrupt ID")
terminal = Terminal()
uart_int_id = Param.Int(0, "PLIC Uart interrupt ID")
def _on_chip_devices(self):
"""Returns a list of on-chip peripherals"""
return [self.clint, self.plic]
return []
def _off_chip_devices(self):
"""Returns a list of off-chip peripherals"""
devices = [self.uart]
if hasattr(self, "disk"):
devices.append(self.disk)
if hasattr(self, "rng"):
devices.append(self.rng)
return devices
return []
def _on_chip_ranges(self):
"""Returns a list of on-chip peripherals
@@ -172,17 +130,6 @@ class HiFive(Platform):
for dev in self._off_chip_devices()
]
def attachPlic(self):
"""Count number of PLIC interrupt sources"""
plic_srcs = [
self.uart_int_id,
self.pci_host.int_base + self.pci_host.int_count,
]
for device in self._off_chip_devices():
if hasattr(device, "interrupt_id"):
plic_srcs.append(device.interrupt_id)
self.plic.n_src = max(plic_srcs) + 1
def attachOnChipIO(self, bus):
"""Attach on-chip IO devices, needs modification
to support DMA
@@ -197,6 +144,83 @@ class HiFive(Platform):
for device in self._off_chip_devices():
device.pio = bus.mem_side_ports
class HiFive(HiFiveBase):
"""HiFive Platform
Implementation:
Implementation details are based on SiFive
FU540-C000. https://sifive.cdn.prismic.io/
sifive/b5e7a29c-d3c2-44ea-85fb-acc1df282e2
1_FU540-C000-v1p3.pdf
Setup:
The following sections outline the required
setup for a RISC-V HiFive platform. See
configs/example/riscv/fs_linux.py for example.
Uart:
The HiFive platform also has an uart_int_id.
This is because Uart8250 uses postConsoleInt
instead of postPciInt. In the future if a Uart
that inherits PlicIntDevice is implemented,
this can be removed.
Disk:
See fs_linux.py for setup example.
PMAChecker:
The PMAChecker will be attached to the MMU of
each CPU (which allows them to differ). See
fs_linux.py for setup example.
"""
# CLINT
clint = Clint(pio_addr=0x2000000)
# PLIC
plic = Plic(pio_addr=0xC000000)
# PCI
pci_host = GenericRiscvPciHost(
conf_base=0x30000000,
conf_size="256MB",
conf_device_bits=12,
pci_pio_base=0x2F000000,
pci_mem_base=0x40000000,
)
# Uart
uart = RiscvUart8250(pio_addr=0x10000000)
# Int source ID to redirect console interrupts to
# Set to 0 if using a pci interrupt for Uart instead
uart_int_id = 0xA
terminal = Terminal()
def _on_chip_devices(self):
"""Returns a list of on-chip peripherals"""
return [self.clint, self.plic]
def _off_chip_devices(self):
"""Returns a list of off-chip peripherals"""
devices = [self.uart]
if hasattr(self, "disk"):
devices.append(self.disk)
if hasattr(self, "rng"):
devices.append(self.rng)
return devices
def attachPlic(self):
"""Count and set number of PLIC interrupt sources"""
plic_srcs = [
self.uart_int_id,
self.pci_host.int_base + self.pci_host.int_count,
]
for device in self._off_chip_devices():
if hasattr(device, "interrupt_id"):
plic_srcs.append(device.interrupt_id)
self.plic.n_src = max(plic_srcs) + 1
def setNumCores(self, num_cpu):
"""Sets the PLIC and CLINT to have the right number of threads and
contexts. Assumes that the cores have a single hardware thread.

View File

@@ -30,7 +30,7 @@
Import('*')
SimObject('HiFive.py', sim_objects=['HiFive', 'GenericRiscvPciHost'],
SimObject('HiFive.py', sim_objects=['HiFiveBase', 'GenericRiscvPciHost'],
tags='riscv isa')
SimObject('LupV.py', sim_objects=['LupV'], tags='riscv isa')
SimObject('Clint.py', sim_objects=['Clint'], tags='riscv isa')

View File

@@ -1,5 +1,6 @@
/*
* Copyright (c) 2021 Huawei International
* Copyright (c) 2023 Google LLC
* All rights reserved
*
* The license below extends only to copyright in the software and shall
@@ -39,7 +40,7 @@
#include "dev/riscv/clint.hh"
#include "dev/riscv/plic.hh"
#include "params/HiFive.hh"
#include "params/HiFiveBase.hh"
#include "sim/system.hh"
namespace gem5
@@ -47,44 +48,46 @@ namespace gem5
using namespace RiscvISA;
HiFive::HiFive(const Params &params) :
HiFiveBase::HiFiveBase(const Params &params) :
Platform(params),
clint(params.clint), plic(params.plic),
uartIntID(params.uart_int_id)
{
fatal_if(clint == nullptr, "CLINT should not be NULL");
fatal_if(plic == nullptr, "PLIC should not be NULL");
}
void
HiFive::postConsoleInt()
HiFiveBase::postConsoleInt()
{
plic->post(uartIntID);
}
void
HiFive::clearConsoleInt()
HiFiveBase::clearConsoleInt()
{
plic->clear(uartIntID);
}
void
HiFive::postPciInt(int line)
HiFiveBase::postPciInt(int line)
{
plic->post(line);
}
void
HiFive::clearPciInt(int line)
HiFiveBase::clearPciInt(int line)
{
plic->clear(line);
}
void
HiFive::serialize(CheckpointOut &cp) const
HiFiveBase::serialize(CheckpointOut &cp) const
{
}
void
HiFive::unserialize(CheckpointIn &cp)
HiFiveBase::unserialize(CheckpointIn &cp)
{
}

View File

@@ -1,5 +1,6 @@
/*
* Copyright (c) 2021 Huawei International
* Copyright (c) 2023 Google LLC
* All rights reserved
*
* The license below extends only to copyright in the software and shall
@@ -41,23 +42,23 @@
#include "dev/platform.hh"
#include "dev/riscv/clint.hh"
#include "dev/riscv/plic.hh"
#include "params/HiFive.hh"
#include "params/HiFiveBase.hh"
namespace gem5
{
using namespace RiscvISA;
class HiFive : public Platform
class HiFiveBase : public Platform
{
public:
Clint *clint;
Plic *plic;
PlicBase *plic;
int uartIntID;
public:
typedef HiFiveParams Params;
HiFive(const Params &params);
typedef HiFiveBaseParams Params;
HiFiveBase(const Params &params);
void postConsoleInt() override;