From 69eb60d87e7deb51984e7d479737ea991db8b461 Mon Sep 17 00:00:00 2001 From: Peter Date: Thu, 4 Feb 2021 13:04:37 +0800 Subject: [PATCH] arch-riscv: RISC-V HiFive Platform implementation This patch implements the RISC-V HiFive Platform (based on the SiFive HiFive series). The HiFive platform requires a PLIC and CLINT device (based on current HiFive boards). The optional uart_int_id field redirects Console interrupts to the PLIC interrupt controller. PlicDevice is a wrapper around BasicPioDevice that requires an interrupt ID. Interrupts are expected to be raised via platform->postPciInterrupt(id). VirtIOMMIO is a slight modification from the ARM implementation such that interrupts are posted through PLIC PlicDevice is a wrapper around BasicPioDevice that requires an interrupt ID. Interrupts are expected to be raised via platform->postPciInterrupt(id). VirtIOMMIO is a slight modification from the ARM implementation such that interrupts are posted through PLIC. Uart8250 was modified slightly for easier Python setup. Change-Id: I4bbdb5f903b52a41d1b7e0ccc44877c46cd30d56 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/40599 Reviewed-by: Ayaz Akram Reviewed-by: Jason Lowe-Power Tested-by: kokoro Maintainer: Jason Lowe-Power --- src/dev/riscv/HiFive.py | 169 ++++++++++++++++++++++ src/dev/riscv/PlicDevice.py | 46 ++++++ src/dev/riscv/SConscript | 7 + src/dev/riscv/VirtIOMMIO.py | 47 ++++++ src/dev/riscv/hifive.cc | 92 ++++++++++++ src/dev/riscv/hifive.hh | 73 ++++++++++ src/dev/riscv/plic_device.cc | 48 ++++++ src/dev/riscv/plic_device.hh | 75 ++++++++++ src/dev/riscv/vio_mmio.cc | 273 +++++++++++++++++++++++++++++++++++ src/dev/riscv/vio_mmio.hh | 111 ++++++++++++++ src/dev/serial/Uart.py | 1 + src/dev/serial/uart8250.cc | 3 +- 12 files changed, 944 insertions(+), 1 deletion(-) create mode 100755 src/dev/riscv/HiFive.py create mode 100644 src/dev/riscv/PlicDevice.py create mode 100644 src/dev/riscv/VirtIOMMIO.py create mode 100644 src/dev/riscv/hifive.cc create mode 100644 src/dev/riscv/hifive.hh create mode 100644 src/dev/riscv/plic_device.cc create mode 100644 src/dev/riscv/plic_device.hh create mode 100644 src/dev/riscv/vio_mmio.cc create mode 100644 src/dev/riscv/vio_mmio.hh diff --git a/src/dev/riscv/HiFive.py b/src/dev/riscv/HiFive.py new file mode 100755 index 0000000000..17d54e39ab --- /dev/null +++ b/src/dev/riscv/HiFive.py @@ -0,0 +1,169 @@ +# Copyright (c) 2021 Huawei International +# All rights reserved. +# +# The license below extends only to copyright in the software and shall +# not be construed as granting a license to any other intellectual +# property including but not limited to intellectual property relating +# to a hardware implementation of the functionality of the software +# licensed hereunder. You may use the software subject to the license +# terms below provided that you ensure that this notice is replicated +# unmodified and in its entirety in all distributions of the software, +# modified or unmodified, in source code or in binary form. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from m5.objects.Platform import Platform +from m5.objects.PMAChecker import PMAChecker +from m5.objects.Clint import Clint +from m5.objects.Plic import Plic +from m5.objects.RTC import RiscvRTC +from m5.objects.Uart import Uart8250 +from m5.objects.Terminal import Terminal +from m5.params import * +from m5.proxy import * + +class HiFive(Platform): + """HiFive 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 + source pin which acts as the RTCCLK pin. An + abstract RTC wrapper called RiscvRTC can be + used. + + Attaching PLIC devices: + PLIC handles external interrupts. Interrupt + PioDevices should inherit from PlicIntDevice + (PCI and DMA not yet implemented). It contains + a parameter interrupt_id which should be used + 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. + """ + type = 'HiFive' + cxx_header = "dev/riscv/hifive.hh" + system = Param.System(Parent.any, "system") + + # CLINT + clint = Param.Clint(Clint(pio_addr=0x2000000), "CLINT") + + # PLIC + plic = Param.Plic(Plic(pio_addr=0xc000000), "PLIC") + + # Uart + uart = Uart8250(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() + + 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) + return devices + + def _on_chip_ranges(self): + """Returns a list of on-chip peripherals + address range + """ + return [ + AddrRange(dev.pio_addr, size=dev.pio_size) + for dev in self._on_chip_devices() + ] + + def _off_chip_ranges(self): + """Returns a list of off-chip peripherals + address range + """ + return [ + AddrRange(dev.pio_addr, size=dev.pio_size) + for dev in self._off_chip_devices() + ] + + def attachPlic(self): + """Count number of PLIC interrupt sources + """ + plic_srcs = [self.uart_int_id] + 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 and PCI + """ + for device in self._on_chip_devices(): + device.pio = bus.mem_side_ports + + def attachOffChipIO(self, bus): + """Attach off-chip IO devices, needs modification + to support DMA and PCI + """ + for device in self._off_chip_devices(): + device.pio = bus.mem_side_ports diff --git a/src/dev/riscv/PlicDevice.py b/src/dev/riscv/PlicDevice.py new file mode 100644 index 0000000000..51956805d3 --- /dev/null +++ b/src/dev/riscv/PlicDevice.py @@ -0,0 +1,46 @@ +# Copyright (c) 2021 Huawei International +# All rights reserved. +# +# The license below extends only to copyright in the software and shall +# not be construed as granting a license to any other intellectual +# property including but not limited to intellectual property relating +# to a hardware implementation of the functionality of the software +# licensed hereunder. You may use the software subject to the license +# terms below provided that you ensure that this notice is replicated +# unmodified and in its entirety in all distributions of the software, +# modified or unmodified, in source code or in binary form. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from m5.objects.Device import BasicPioDevice +from m5.params import * +from m5.proxy import * + +class PlicIntDevice(BasicPioDevice): + type = 'PlicIntDevice' + cxx_header = 'dev/riscv/plic_device.hh' + abstract = True + platform = Param.Platform(Parent.any, "Platform") + pio_size = Param.Addr("PIO Size") + interrupt_id = Param.Int("PLIC Interrupt ID") diff --git a/src/dev/riscv/SConscript b/src/dev/riscv/SConscript index 08d462b030..57d61c28c2 100755 --- a/src/dev/riscv/SConscript +++ b/src/dev/riscv/SConscript @@ -30,13 +30,20 @@ Import('*') if env['TARGET_ISA'] == 'riscv': + SimObject('HiFive.py') SimObject('Clint.py') + SimObject('PlicDevice.py') SimObject('Plic.py') SimObject('RTC.py') + SimObject('VirtIOMMIO.py') DebugFlag('Clint') DebugFlag('Plic') + DebugFlag('VirtIOMMIO') + Source('hifive.cc') Source('clint.cc') + Source('plic_device.cc') Source('plic.cc') Source('rtc.cc') + Source('vio_mmio.cc') diff --git a/src/dev/riscv/VirtIOMMIO.py b/src/dev/riscv/VirtIOMMIO.py new file mode 100644 index 0000000000..20efc512cf --- /dev/null +++ b/src/dev/riscv/VirtIOMMIO.py @@ -0,0 +1,47 @@ +# Copyright (c) 2021 Huawei International +# Copyright (c) 2014, 2016-2018 ARM Limited +# All rights reserved. +# +# The license below extends only to copyright in the software and shall +# not be construed as granting a license to any other intellectual +# property including but not limited to intellectual property relating +# to a hardware implementation of the functionality of the software +# licensed hereunder. You may use the software subject to the license +# terms below provided that you ensure that this notice is replicated +# unmodified and in its entirety in all distributions of the software, +# modified or unmodified, in source code or in binary form. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from m5.SimObject import SimObject +from m5.params import * +from m5.proxy import * + +from m5.objects.PlicDevice import PlicIntDevice +from m5.objects.VirtIO import VirtIODummyDevice + +class MmioVirtIO(PlicIntDevice): + type = 'MmioVirtIO' + cxx_header = 'dev/riscv/vio_mmio.hh' + vio = Param.VirtIODeviceBase(VirtIODummyDevice(), "VirtIO device") diff --git a/src/dev/riscv/hifive.cc b/src/dev/riscv/hifive.cc new file mode 100644 index 0000000000..543153a04d --- /dev/null +++ b/src/dev/riscv/hifive.cc @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2021 Huawei International + * All rights reserved + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "dev/riscv/hifive.hh" + +#include "dev/riscv/clint.hh" +#include "dev/riscv/plic.hh" +#include "params/HiFive.hh" +#include "sim/system.hh" + +using namespace RiscvISA; + +HiFive::HiFive(const Params ¶ms) : + Platform(params), system(params.system), + clint(params.clint), plic(params.plic), + uartIntID(params.uart_int_id) +{ +} + +void +HiFive::postConsoleInt() +{ + plic->post(uartIntID); +} + +void +HiFive::clearConsoleInt() +{ + plic->clear(uartIntID); +} + +void +HiFive::postPciInt(int line) +{ + plic->post(line); +} + +void +HiFive::clearPciInt(int line) +{ + plic->clear(line); +} + +Addr +HiFive::pciToDma(Addr pciAddr) const +{ + panic("HiFive::pciToDma() has not been implemented."); +} + +void +HiFive::serialize(CheckpointOut &cp) const +{ +} + +void +HiFive::unserialize(CheckpointIn &cp) +{ +} diff --git a/src/dev/riscv/hifive.hh b/src/dev/riscv/hifive.hh new file mode 100644 index 0000000000..e4d162e542 --- /dev/null +++ b/src/dev/riscv/hifive.hh @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2021 Huawei International + * All rights reserved + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __DEV_RISCV_HIFIVE_HH__ +#define __DEV_RISCV_HIFIVE_HH__ + +#include "dev/platform.hh" +#include "dev/riscv/clint.hh" +#include "dev/riscv/plic.hh" +#include "params/HiFive.hh" + +using namespace RiscvISA; +class HiFive : public Platform { + public: + System *system; + Clint *clint; + Plic *plic; + int uartIntID; + + public: + typedef HiFiveParams Params; + HiFive(const Params ¶ms); + + void postConsoleInt() override; + + void clearConsoleInt() override; + + void postPciInt(int line) override; + + void clearPciInt(int line) override; + + virtual Addr pciToDma(Addr pciAddr) const; + + void serialize(CheckpointOut &cp) const override; + + void unserialize(CheckpointIn &cp) override; +}; + +#endif // __DEV_RISCV_HIFIVE_HH__ diff --git a/src/dev/riscv/plic_device.cc b/src/dev/riscv/plic_device.cc new file mode 100644 index 0000000000..dec5f635cd --- /dev/null +++ b/src/dev/riscv/plic_device.cc @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2021 Huawei International + * All rights reserved + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "dev/riscv/plic_device.hh" + +using namespace RiscvISA; + +PlicIntDevice::PlicIntDevice(const Params ¶ms) : + BasicPioDevice(params, params.pio_size), + system(params.system), + platform(params.platform), + _interruptID(params.interrupt_id) +{ +} \ No newline at end of file diff --git a/src/dev/riscv/plic_device.hh b/src/dev/riscv/plic_device.hh new file mode 100644 index 0000000000..75fbde464e --- /dev/null +++ b/src/dev/riscv/plic_device.hh @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2021 Huawei International + * All rights reserved + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __DEV_RISCV_PLIC_DEVICE_HH__ +#define __DEV_RISCV_PLIC_DEVICE_HH__ + +#include "dev/io_device.hh" +#include "dev/platform.hh" +#include "params/PlicIntDevice.hh" +#include "sim/system.hh" + +using namespace RiscvISA; + +class PlicIntDevice : public BasicPioDevice +{ + protected: + System *system; + Platform *platform; + int _interruptID; + + public: + typedef PlicIntDeviceParams Params; + + const Params & + params() const + { + return dynamic_cast(_params); + } + + PlicIntDevice(const Params ¶ms); + + const int & + id() + { + return _interruptID; + } + +}; + + +#endif // __DEV_RISCV_PLIC_DEVICE_HH__ diff --git a/src/dev/riscv/vio_mmio.cc b/src/dev/riscv/vio_mmio.cc new file mode 100644 index 0000000000..686f94bcfd --- /dev/null +++ b/src/dev/riscv/vio_mmio.cc @@ -0,0 +1,273 @@ +/* + * Copyright (c) 2021 Huawei International + * Copyright (c) 2016-2018 ARM Limited + * All rights reserved + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "dev/riscv/vio_mmio.hh" + +#include "debug/VirtIOMMIO.hh" +#include "dev/riscv/hifive.hh" +#include "mem/packet_access.hh" +#include "params/MmioVirtIO.hh" + +MmioVirtIO::MmioVirtIO(const MmioVirtIOParams ¶ms) + : PlicIntDevice(params), + hostFeaturesSelect(0), guestFeaturesSelect(0), pageSize(0), + interruptStatus(0), vio(*params.vio) +{ + vio.registerKickCallback([this]() { kick(); }); +} + +MmioVirtIO::~MmioVirtIO() +{ +} + +Tick +MmioVirtIO::read(PacketPtr pkt) +{ + const Addr offset = pkt->getAddr() - pioAddr; + const unsigned size(pkt->getSize()); + + DPRINTF(VirtIOMMIO, "Reading %u bytes @ 0x%x:\n", size, offset); + + // Forward device configuration writes to the device VirtIO model + if (offset >= OFF_CONFIG) { + vio.readConfig(pkt, offset - OFF_CONFIG); + return 0; + } + panic_if(size != 4, "Unexpected read size: %u\n", size); + + const uint32_t value = read(offset); + DPRINTF(VirtIOMMIO, " value: 0x%x\n", value); + pkt->makeResponse(); + pkt->setLE(value); + + return 0; +} + +uint32_t +MmioVirtIO::read(Addr offset) +{ + switch(offset) { + case OFF_MAGIC: + return MAGIC; + + case OFF_VERSION: + return VERSION; + + case OFF_DEVICE_ID: + return vio.deviceId; + + case OFF_VENDOR_ID: + return VENDOR_ID; + + case OFF_HOST_FEATURES: + // We only implement 32 bits of this register + if (hostFeaturesSelect == 0) + return vio.deviceFeatures; + else + return 0; + + case OFF_HOST_FEATURES_SELECT: + return hostFeaturesSelect; + + case OFF_GUEST_FEATURES: + // We only implement 32 bits of this register + if (guestFeaturesSelect == 0) + return vio.getGuestFeatures(); + else + return 0; + + case OFF_GUEST_FEATURES_SELECT: + return hostFeaturesSelect; + + case OFF_GUEST_PAGE_SIZE: + return pageSize; + + case OFF_QUEUE_SELECT: + return vio.getQueueSelect(); + + case OFF_QUEUE_NUM_MAX: + return vio.getQueueSize(); + + case OFF_QUEUE_NUM: + // TODO: We don't support queue resizing, so ignore this for now. + return vio.getQueueSize(); + + case OFF_QUEUE_ALIGN: + // TODO: Implement this once we support other alignment sizes + return VirtQueue::ALIGN_SIZE; + + case OFF_QUEUE_PFN: + return vio.getQueueAddress(); + + case OFF_INTERRUPT_STATUS: + return interruptStatus; + + case OFF_STATUS: + return vio.getDeviceStatus(); + + // Write-only registers + case OFF_QUEUE_NOTIFY: + case OFF_INTERRUPT_ACK: + warn("Guest is trying to read to write-only register 0x%\n", + offset); + return 0; + + default: + panic("Unhandled read offset (0x%x)\n", offset); + } +} + +Tick +MmioVirtIO::write(PacketPtr pkt) +{ + const Addr offset = pkt->getAddr() - pioAddr; + const unsigned size(pkt->getSize()); + + DPRINTF(VirtIOMMIO, "Writing %u bytes @ 0x%x:\n", size, offset); + + // Forward device configuration writes to the device VirtIO model + if (offset >= OFF_CONFIG) { + vio.writeConfig(pkt, offset - OFF_CONFIG); + return 0; + } + + panic_if(size != 4, "Unexpected write size @ 0x%x: %u\n", offset, size); + DPRINTF(VirtIOMMIO, " value: 0x%x\n", pkt->getLE()); + pkt->makeResponse(); + write(offset, pkt->getLE()); + return 0; +} + +void +MmioVirtIO::write(Addr offset, uint32_t value) +{ + switch(offset) { + case OFF_HOST_FEATURES_SELECT: + hostFeaturesSelect = value; + return; + + case OFF_GUEST_FEATURES: + if (guestFeaturesSelect == 0) { + vio.setGuestFeatures(value); + } else if (value != 0) { + warn("Setting unimplemented guest features register %u: %u\n", + guestFeaturesSelect, value); + } + return; + + case OFF_GUEST_FEATURES_SELECT: + guestFeaturesSelect = value; + return; + + case OFF_GUEST_PAGE_SIZE: + // TODO: We only support 4096 byte pages at the moment + panic_if(value != VirtQueue::ALIGN_SIZE, + "Unhandled VirtIO page size: %u", value); + pageSize = value; + return; + + case OFF_QUEUE_SELECT: + vio.setQueueSelect(value); + return; + + case OFF_QUEUE_NUM: + // TODO: We don't support queue resizing, so ignore this for now. + warn_once("Ignoring queue resize hint. Requested size: %u\n", value); + return; + + case OFF_QUEUE_ALIGN: + // TODO: We currently only support the hard-coded 4k alignment used + // in legacy VirtIO. + panic_if(value != VirtQueue::ALIGN_SIZE, + "Unhandled VirtIO alignment size: %u", value); + return; + + case OFF_QUEUE_PFN: + vio.setQueueAddress(value); + return; + + case OFF_QUEUE_NOTIFY: + vio.onNotify(value); + return; + + case OFF_INTERRUPT_ACK: + setInterrupts(interruptStatus & (~value)); + return; + + case OFF_STATUS: + panic_if(value > 0xff, "Unexpected status: 0x%x\n", value); + vio.setDeviceStatus(value); + return; + + /* Read-only registers */ + case OFF_MAGIC: + case OFF_VERSION: + case OFF_DEVICE_ID: + case OFF_VENDOR_ID: + case OFF_HOST_FEATURES: + case OFF_QUEUE_NUM_MAX: + case OFF_INTERRUPT_STATUS: + warn("Guest is trying to write to read-only register 0x%\n", + offset); + return; + + default: + panic("Unhandled read offset (0x%x)\n", offset); + } +} + +void +MmioVirtIO::kick() +{ + DPRINTF(VirtIOMMIO, "kick(): Sending interrupt...\n"); + setInterrupts(interruptStatus | INT_USED_RING); +} + +void +MmioVirtIO::setInterrupts(uint32_t value) +{ + const uint32_t old_ints = interruptStatus; + interruptStatus = value; + + if (!old_ints && interruptStatus) { + platform->postPciInt(_interruptID); + } else if (old_ints && !interruptStatus) { + platform->clearPciInt(_interruptID); + } +} + diff --git a/src/dev/riscv/vio_mmio.hh b/src/dev/riscv/vio_mmio.hh new file mode 100644 index 0000000000..da79e6bddc --- /dev/null +++ b/src/dev/riscv/vio_mmio.hh @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2021 Huawei International + * Copyright (c) 2016-2018 ARM Limited + * All rights reserved + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __DEV_ARM_VIO_MMIO_HH__ +#define __DEV_ARM_VIO_MMIO_HH__ + +#include "dev/riscv/hifive.hh" +#include "dev/riscv/plic_device.hh" +#include "dev/virtio/base.hh" + +struct MmioVirtIOParams; + +class MmioVirtIO : public PlicIntDevice +{ + public: + MmioVirtIO(const MmioVirtIOParams ¶ms); + virtual ~MmioVirtIO(); + + protected: // BasicPioDevice + Tick read(PacketPtr pkt) override; + Tick write(PacketPtr pkt) override; + + protected: + /** @{ */ + /** Offsets into VirtIO MMIO space. */ + + enum : Addr { + OFF_MAGIC = 0x00, + OFF_VERSION = 0x04, + OFF_DEVICE_ID = 0x08, + OFF_VENDOR_ID = 0x0C, + OFF_HOST_FEATURES = 0x10, + OFF_HOST_FEATURES_SELECT = 0x14, + OFF_GUEST_FEATURES = 0x20, + OFF_GUEST_FEATURES_SELECT = 0x24, + OFF_GUEST_PAGE_SIZE = 0x28, + OFF_QUEUE_SELECT = 0x30, + OFF_QUEUE_NUM_MAX = 0x34, + OFF_QUEUE_NUM = 0x38, + OFF_QUEUE_ALIGN = 0x3C, + OFF_QUEUE_PFN = 0x40, + OFF_QUEUE_NOTIFY = 0x50, + OFF_INTERRUPT_STATUS = 0x60, + OFF_INTERRUPT_ACK = 0x64, + OFF_STATUS = 0x70, + OFF_CONFIG = 0x100, + }; + + /** @} */ + + enum { + INT_USED_RING = 1 << 0, + INT_CONFIG = 1 << 1, + }; + + static const uint32_t MAGIC = 0x74726976; + static const uint32_t VERSION = 1; + static const uint32_t VENDOR_ID = 0x1AF4; + + + uint32_t read(Addr offset); + void write(Addr offset, uint32_t value); + + void kick(); + void setInterrupts(uint32_t value); + + uint32_t hostFeaturesSelect; + uint32_t guestFeaturesSelect; + uint32_t pageSize; + uint32_t interruptStatus; + + protected: // Params + VirtIODeviceBase &vio; +}; + +#endif // __DEV_ARM_VIO_MMIO_HH__ diff --git a/src/dev/serial/Uart.py b/src/dev/serial/Uart.py index 7955d69163..bcaf0a5555 100644 --- a/src/dev/serial/Uart.py +++ b/src/dev/serial/Uart.py @@ -60,3 +60,4 @@ class SimpleUart(Uart): class Uart8250(Uart): type = 'Uart8250' cxx_header = "dev/serial/uart8250.hh" + pio_size = Param.Addr(0x8, "Size of address range") diff --git a/src/dev/serial/uart8250.cc b/src/dev/serial/uart8250.cc index 1804a3b797..d3a466b73c 100644 --- a/src/dev/serial/uart8250.cc +++ b/src/dev/serial/uart8250.cc @@ -83,7 +83,8 @@ Uart8250::scheduleIntr(Event *event) Uart8250::Uart8250(const Params &p) - : Uart(p, 8), registers(this, name() + ".registers"), lastTxInt(0), + : Uart(p, p.pio_size), registers(this, name() + ".registers"), + lastTxInt(0), txIntrEvent([this]{ processIntrEvent(TX_INT); }, "TX"), rxIntrEvent([this]{ processIntrEvent(RX_INT); }, "RX") {