Merge remote-tracking branch 'upstream/main' into fetch_buffer

This commit is contained in:
Jordan Carlin 2024-10-10 15:11:46 -07:00
commit dfe7c11af4
No known key found for this signature in database
21 changed files with 57 additions and 6010 deletions

View File

@ -414,6 +414,7 @@ if (args.ccov): # only run RV64GC tests on Questa in code coverage mode
elif (args.fcov): # only run RV64GC tests on Questa in lockstep in functional coverage mode elif (args.fcov): # only run RV64GC tests on Questa in lockstep in functional coverage mode
addLockstepTestsByDir(WALLY+"/addins/cvw-arch-verif/tests/rv32/", "rv32gc", coveragesim, 1) addLockstepTestsByDir(WALLY+"/addins/cvw-arch-verif/tests/rv32/", "rv32gc", coveragesim, 1)
addLockstepTestsByDir(WALLY+"/addins/cvw-arch-verif/tests/rv64/", "rv64gc", coveragesim, 1) addLockstepTestsByDir(WALLY+"/addins/cvw-arch-verif/tests/rv64/", "rv64gc", coveragesim, 1)
# addLockstepTestsByDir(WALLY+"/tests/riscof/work/wally-riscv-arch-test/rv64i_m/privilege/src/", "rv64gc", coveragesim, 0)
elif (args.fcovrvvi): # only run RV64GC tests on Questa in rvvi coverage mode elif (args.fcovrvvi): # only run RV64GC tests on Questa in rvvi coverage mode
addTests(tests64gc_nofp, coveragesim) addTests(tests64gc_nofp, coveragesim)
if (args.fp): if (args.fp):

View File

@ -3,7 +3,7 @@ lief>=0.14.1
Markdown>=3.6 Markdown>=3.6
matplotlib>=3.9.0 matplotlib>=3.9.0
PyYAML>=5.2 PyYAML>=5.2
riscv-isac @ git+https://github.com/riscv-software-src/riscv-isac@dev riscv-isac @ git+https://github.com/riscv-non-isa/riscv-arch-test/#subdirectory=riscv-isac
riscof @ git+https://github.com/riscv/riscof.git riscof @ git+https://github.com/riscv/riscof.git
riscv-config>=3.18.3 riscv-config>=3.18.3
riscv-isac>=0.18.0 riscv-isac>=0.18.0

View File

@ -142,6 +142,11 @@ for d in ["logs", "wkdir", "cov", "ucdb", "fcov", "fcov_ucdb", "fcovrvvi", "fcov
cd = "cd $WALLY/sim/" +args.sim cd = "cd $WALLY/sim/" +args.sim
# check for unsupported sims
if (args.tb == "testbench_fp" and args.sim != "questa"):
print("Error: testbench_fp presently only supported by Questa, not VCS or Verilator, because of a touchy testbench")
exit(1)
# per-simulator launch # per-simulator launch
if (args.sim == "questa"): if (args.sim == "questa"):
if (args.gui) and (args.tb == "testbench"): if (args.gui) and (args.tb == "testbench"):

View File

@ -8,5 +8,6 @@
`include "RV32I_coverage.svh" `include "RV32I_coverage.svh"
`include "RV32M_coverage.svh" `include "RV32M_coverage.svh"
`include "RV32F_coverage.svh" `include "RV32F_coverage.svh"
`include "RV32Zfh_coverage.svh"
`include "RV32Zicond_coverage.svh" `include "RV32Zicond_coverage.svh"
`include "RV32Zca_coverage.svh" `include "RV32Zca_coverage.svh"

View File

@ -8,5 +8,11 @@
`include "RV64I_coverage.svh" `include "RV64I_coverage.svh"
`include "RV64M_coverage.svh" `include "RV64M_coverage.svh"
`include "RV64F_coverage.svh" `include "RV64F_coverage.svh"
`include "RV64Zfh_coverage.svh"
// `include "RV64VM_coverage.svh"
// `include "RV64VM_PMP_coverage.svh"
// `include "RV64CBO_VM_coverage.svh"
// `include "RV64CBO_PMP_coverage.svh"
// `include "RV64Zicbom_coverage.svh"
`include "RV64Zicond_coverage.svh" `include "RV64Zicond_coverage.svh"
`include "RV64Zca_coverage.svh" `include "RV64Zca_coverage.svh"

View File

@ -17,31 +17,3 @@ CORE-V Wally is functionally tested in the following ways. Each test is run in
| Code Coverage | 5.11.10 | | rv64gc | TBD | TBD | TBD | | Code Coverage | 5.11.10 | | rv64gc | TBD | TBD | TBD |
| Functional Coverage | 5.11.11 | | rv64gc | TBD | TBD | TBD | | Functional Coverage | 5.11.11 | | rv64gc | TBD | TBD | TBD |
* Run [RISC-V Architecture Compatibility Tests](https://github.com/riscv-non-isa/riscv-arch-test) in lock-step against the ImperasDV reference model.
* Run custom tests to cover virtual memory, PMP, privileged unit, and peripherals in lock step against ImperasDV.
* ***pending: Run random tests generated by risc-dv
* Run CoreMark and Embench benchmarks.
* Run performance validation against reference models for the branch predictor and caches.
* Run the TestFloat suite against all precisions of all operations for the FPU unit.
* *** 83.5% coverage of statements, branches, expressions, and FSM states and transitions
* Boot Buildroot Linux in lock-step against ImperasDV.
* Boot Buildroot Linux on an FPGA and run programs.
# Running Tests
#
# Detailed Test Plans
The test plans for specific units are lined below:
* Privileged Unit
* Memory Management Unit
* Peripherals
* Branch Predictor Performance Validation
* Cache Performance Validation
Wally is described in an upcoming textbook, *RISC-V System-on-Chip Design*, by Harris, Stine, Thompson, and Harris.

View File

@ -1,30 +0,0 @@
# core-v-wally Design Verification Test Plan
This document outlines the test plan for the Wally rv64gc configuration to reach Technology Readiness Level 5.
1. Pass riscv-arch-test
2. Boot Linux
3. FPU pass all TestFloat vectors
4. Performance verification: Caches and branch predictor miss rates match independent simulation
5. Directed tests
- Privileged unit: Chapter 5 test plan
- MMU: PMA, PMP, virtual memory: Chapter 8 test plan
- Peripherals: Chapter 16 test plan
6. Random tests
- riscdv tests
7. Coverage tests
- Directed tests to bring coverage up to 100%.
- Statement, experssion, branch, condition, FSM coverage in Questa
- Do not measure toggle coverage
All tests operate correctly in lock-step with ImperasDV
Open questions:
1. How to define extent of riscdv random tests needed?
2. What other directed tests?
PMP Tests
Virtual Memory Tests
How to define pipeline tests?
Simple ones like use after load stall are not important.
Hard ones such as page table walker fault during data access while I$ access is pending are hard to articulate and code
Is there an example of a good directed pipeline test plan & implementation

View File

@ -1,102 +0,0 @@
#include "system.h"
PERIOD = (SYSTEMCLOCK / 2)
.section .init
.global _start
.type _start, @function
_start:
# Initialize global pointer
.option push
.option norelax
1:auipc gp, %pcrel_hi(__global_pointer$)
addi gp, gp, %pcrel_lo(1b)
.option pop
li x1, 0
li x2, 0
li x4, 0
li x5, 0
li x6, 0
li x7, 0
li x8, 0
li x9, 0
li x10, 0
li x11, 0
li x12, 0
li x13, 0
li x14, 0
li x15, 0
li x16, 0
li x17, 0
li x18, 0
li x19, 0
li x20, 0
li x21, 0
li x22, 0
li x23, 0
li x24, 0
li x25, 0
li x26, 0
li x27, 0
li x28, 0
li x29, 0
li x30, 0
li x31, 0
# set the stack pointer to the top of memory - 8 bytes (pointer size)
li sp, (EXT_MEM_END - 8)
li a0, 0x00000000
li a1, EXT_MEM_BASE
#li a2, 128*1024*1024/512 # copy 128MB
li a2, 127*1024*1024/512 # copy 127MB upper 1MB contains the return address (ra)
#li a2, 800 # copy 400KB
jal ra, copyFlash
fence.i
# now toggle led so we know the copy completed.
# write to gpio
li t2, 0xFF
la t3, 0x1006000C
li t4, 5
loop:
# delay
li t0, PERIOD/2
delay1:
addi t0, t0, -1
bge t0, x0, delay1
sw t2, 0x0(t3)
li t0, PERIOD/2
delay2:
addi t0, t0, -1
bge t0, x0, delay2
sw x0, 0x0(t3)
addi t4, t4, -1
bgt t4, x0, loop
# now that the card is copied and the led toggled we
# jump to the copied contents of the sd card.
jumpToLinux:
csrrs a0, 0xF14, x0 # copy hart ID to a0
li a1, FDT_ADDRESS # This is the device tree address
la a2, end_of_bios
li t0, EXT_MEM_BASE # start of code
jalr x0, t0, 0
end_of_bios:

View File

@ -1,54 +0,0 @@
###########################################
## A component of the CORE-V-WALLY configurable RISC-V project.
## https://github.com/openhwgroup/cvw
##
## Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
##
## SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
##
## Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
## except in compliance with the License, or, at your option, the Apache License version 2.0. You
## may obtain a copy of the License at
##
## https://solderpad.org/licenses/SHL-2.1/
##
## Unless required by applicable law or agreed to in writing, any work distributed under the
## License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
## either express or implied. See the License for the specific language governing permissions
## and limitations under the License.
################################################################################################
Setup
1. goto github and fork openhwgroup/cvw.git
2. clone: git clone --recurse-submodules git@ross144/cvw.git
3. git remote add upstream https://github.com/openhwgroup/cvw.git
4. install gh (github command line interface)
type -p curl >/dev/null || sudo apt install curl -y
curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg \
&& sudo chmod go+r /usr/share/keyrings/githubcli-archive-keyring.gpg \
&& echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null \
&& sudo apt update \
&& sudo apt install gh -y
Once per session (This authorizes gh to use your github account)
1. gh auth login
2. Use ssh and point to your public key
3. Copy one-time code from terminal to browser
Fetch upstream and sync fork
1. git pull upstream main # fetch and merge the upstream openhwgroup/cvw into your local clone
2. git push # pushes changes back to your fork. Now all three should be in sync
Create pull request
1. git pull upstream main # fetch and merge the upstream openhwgroup/cvw into your local clone
3. git push # pushes changes back to your fork. Now all three should be in sync
4. gh pr create # Create a pull request.
5. Must include a title and strongly encourage a body message explaining your changes.
6. Wait for pull request to be approved, rejected, or needs changes.
7. Finish by fetching the upstream and pushing back to your fork.
1. git pull upstream main # fetch and merge the upstream openhwgroup/cvw into your local clone
3. git push # sync your fork with the upstream and clone
If the pull request need changes, modify accordingly, commit, and push changes back to the fork.
The pull request will automatically update.

View File

@ -17,12 +17,6 @@ endif
WALLYBOARDSRC := $(WALLYLINUX)/buildroot-config-src/wally WALLYBOARDSRC := $(WALLYLINUX)/buildroot-config-src/wally
WALLYBOARD := $(BUILDROOT)/board/wally WALLYBOARD := $(BUILDROOT)/board/wally
# Buildroot Package Stuff
PACKAGE_SOURCE := ${WALLYLINUX}/buildroot-packages/package-source
FPGA_AXI_SDC := ${WALLYLINUX}/buildroot-packages/fpga-axi-sdc
DRIVER := ${PACKAGE_SOURCE}/fpga-axi-sdc.c
PATCHFILE := $(BRPACKAGES)/package-2023.05.1.patch
# Device tree files # Device tree files
DTS ?= $(shell find devicetree -type f -regex ".*\.dts" | sort) DTS ?= $(shell find devicetree -type f -regex ".*\.dts" | sort)
DTB := $(DTS:%.dts=%.dtb) DTB := $(DTS:%.dts=%.dtb)
@ -114,15 +108,6 @@ $(WALLYBOARD): $(BUILDROOT)
cp $(BR2023)/main.config $(WALLYBOARD)/main.config cp $(BR2023)/main.config $(WALLYBOARD)/main.config
cp $(BR2023)/linux.config $(WALLYBOARD)/linux.config cp $(BR2023)/linux.config $(WALLYBOARD)/linux.config
# Buildroot Package ---------------------------------------------------
$(BUILDROOT)/package/fpga-axi-sdc: $(BUILDROOT) $(PATCHFILE) $(BRPACKAGES)/fpga-axi-sdc
cp -r $(BRPACKAGES)/fpga-axi-sdc $(BUILDROOT)/package
sed -i 's|FPGA_AXI_SDC_SITE =|FPGA_AXI_SDC_SITE = $(PACKAGE_SOURCE)|1' $(BUILDROOT)/package/fpga-axi-sdc/fpga-axi-sdc.mk
cd $(BUILDROOT); if git apply --check $(PATCHFILE) > /dev/null ; then git apply $(PATCHFILE); fi
$(PATCHFILE):
cd $(BUILDROOT); git apply $(PATCHFILE)
$(BUILDROOT): $(BUILDROOT):
git clone https://github.com/buildroot/buildroot.git $@ git clone https://github.com/buildroot/buildroot.git $@
cd $@; git checkout 2023.05.x cd $@; git checkout 2023.05.x

View File

@ -1,6 +1,6 @@
# #
# Automatically generated file; DO NOT EDIT. # Automatically generated file; DO NOT EDIT.
# Buildroot 2023.05.3-dirty Configuration # Buildroot 2023.05.3 Configuration
# #
BR2_HAVE_DOT_CONFIG=y BR2_HAVE_DOT_CONFIG=y
BR2_HOST_GCC_AT_LEAST_4_9=y BR2_HOST_GCC_AT_LEAST_4_9=y
@ -949,7 +949,6 @@ BR2_PACKAGE_SDL_FBCON=y
BR2_PACKAGE_FLASHROM_ARCH_SUPPORTS=y BR2_PACKAGE_FLASHROM_ARCH_SUPPORTS=y
# BR2_PACKAGE_FLASHROM is not set # BR2_PACKAGE_FLASHROM is not set
# BR2_PACKAGE_FMTOOLS is not set # BR2_PACKAGE_FMTOOLS is not set
BR2_PACKAGE_FPGA_AXI_SDC=y
# BR2_PACKAGE_FREEIPMI is not set # BR2_PACKAGE_FREEIPMI is not set
# BR2_PACKAGE_FXLOAD is not set # BR2_PACKAGE_FXLOAD is not set
# BR2_PACKAGE_GPM is not set # BR2_PACKAGE_GPM is not set

View File

@ -1,6 +0,0 @@
config BR2_PACKAGE_FPGA_AXI_SDC
bool "FPGA AXI SDC"
help
The Vivado-RISC-V SDC Drivers.
https://www.github.com/eugene-tarassov/vivado-risc-v

View File

@ -1,10 +0,0 @@
FPGA_AXI_SDC_MODULE_VERSION = 1.0
# TODO This variable needs to change based on where the package
# contents are stored on each individual computer. Might parameterize
# this somehow.
FPGA_AXI_SDC_SITE =
FPGA_AXI_SDC_SITE_METHOD = local
FPGA_AXI_SDC_LICENSE = GPLv2
$(eval $(kernel-module))
$(eval $(generic-package))

File diff suppressed because it is too large Load Diff

View File

@ -1,12 +0,0 @@
diff --git a/package/Config.in b/package/Config.in
index ad438667d2..810bf0897e 100644
--- a/package/Config.in
+++ b/package/Config.in
@@ -503,6 +503,7 @@ endmenu
source "package/fconfig/Config.in"
source "package/flashrom/Config.in"
source "package/fmtools/Config.in"
+ source "package/fpga-axi-sdc/Config.in"
source "package/freeipmi/Config.in"
source "package/freescale-imx/Config.in"
source "package/fxload/Config.in"

View File

@ -1,9 +0,0 @@
.PHONY: all clean
obj-m += fpga-axi-sdc.o
all:
$(MAKE) -C '$(LINUX-DIR)' M='$(PWD)' modules
$(MAKE) -C '$(LINUX-DIR)' M='$(PWD)' modules_install
clean:
$(MAKE) -C '$(LINUX-DIR)' M='$(PWD)' clean

View File

@ -1,496 +0,0 @@
// SPDX-License-Identifier: GPL-2.0-only
#include <linux/delay.h>
#include <linux/dma-mapping.h>
#include <linux/err.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/iopoll.h>
#include <linux/platform_device.h>
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/pinctrl/consumer.h>
#include <linux/regulator/consumer.h>
#include <linux/reset.h>
#include <linux/mmc/card.h>
#include <linux/mmc/host.h>
#include <linux/mmc/mmc.h>
#include <linux/mmc/slot-gpio.h>
#include <linux/ktime.h>
/*
* AXI SD Card driver.
*
* AXI SD Card is open source Verilog implementation of high speed SD card controller.
* It is mainly used in FPGA designs.
*/
#ifdef CONFIG_DEBUG_INFO
#pragma GCC optimize("O0")
#endif
// Capability bits
#define SDC_CAPABILITY_SD_4BIT 0x0001
#define SDC_CAPABILITY_SD_RESET 0x0002
#define SDC_CAPABILITY_ADDR 0xff00
// Control bits
#define SDC_CONTROL_SD_4BIT 0x0001
#define SDC_CONTROL_SD_RESET 0x0002
// Card detect bits
#define SDC_CARD_INSERT_INT_EN 0x0001
#define SDC_CARD_INSERT_INT_REQ 0x0002
#define SDC_CARD_REMOVE_INT_EN 0x0004
#define SDC_CARD_REMOVE_INT_REQ 0x0008
// Command status bits
#define SDC_CMD_INT_STATUS_CC 0x0001 // Command complete
#define SDC_CMD_INT_STATUS_EI 0x0002 // Any error
#define SDC_CMD_INT_STATUS_CTE 0x0004 // Timeout
#define SDC_CMD_INT_STATUS_CCRC 0x0008 // CRC error
#define SDC_CMD_INT_STATUS_CIE 0x0010 // Command code check error
// Data status bits
#define SDC_DAT_INT_STATUS_TRS 0x0001 // Transfer complete
#define SDC_DAT_INT_STATUS_ERR 0x0002 // Any error
#define SDC_DAT_INT_STATUS_CTE 0x0004 // Timeout
#define SDC_DAT_INT_STATUS_CRC 0x0008 // CRC error
#define SDC_DAT_INT_STATUS_CFE 0x0010 // Data FIFO underrun or overrun
#define CMD_TIMEOUT_MS 1000
#define BUSY_TIMEOUT_MS 500
struct sdc_regs {
volatile uint32_t argument;
volatile uint32_t command;
volatile uint32_t response1;
volatile uint32_t response2;
volatile uint32_t response3;
volatile uint32_t response4;
volatile uint32_t data_timeout;
volatile uint32_t control;
volatile uint32_t cmd_timeout;
volatile uint32_t clock_divider;
volatile uint32_t software_reset;
volatile uint32_t power_control;
volatile uint32_t capability;
volatile uint32_t cmd_int_status;
volatile uint32_t cmd_int_enable;
volatile uint32_t dat_int_status;
volatile uint32_t dat_int_enable;
volatile uint32_t block_size;
volatile uint32_t block_count;
volatile uint32_t card_detect;
volatile uint32_t res_50;
volatile uint32_t res_54;
volatile uint32_t res_58;
volatile uint32_t res_5c;
volatile uint64_t dma_addres;
};
struct sdc_host {
struct platform_device * pdev;
struct sdc_regs __iomem * regs;
uint32_t clk_freq;
spinlock_t lock;
struct mmc_request * mrq;
struct mmc_data * data;
unsigned dma_addr_bits;
unsigned dma_count;
dma_addr_t dma_addr;
unsigned dma_size;
int irq;
};
static const struct of_device_id axi_sdc_of_match_table[] = {
{ .compatible = "riscv,axi-sd-card-1.0" },
{},
};
MODULE_DEVICE_TABLE(of, axi_sdc_of_match_table);
/* Set clock prescalar value based on the required clock in HZ */
static void sdc_set_clock(struct sdc_host * host, uint clock) {
unsigned clk_div;
/* Min clock frequency should be 400KHz */
if (clock < 400000) clock = 400000;
clk_div = host->clk_freq / (2 * clock);
if (clk_div > 0x100) clk_div = 0x100;
if (clk_div < 1) clk_div = 1;
if (host->regs->clock_divider != clk_div - 1) {
host->regs->clock_divider = clk_div - 1;
udelay(10000);
}
}
static void sdc_cmd_finish(struct sdc_host * host, struct mmc_command * cmd) {
while (1) {
unsigned status = host->regs->cmd_int_status;
if (status) {
// clear interrupts
host->regs->cmd_int_status = 0;
while (host->regs->software_reset != 0) {}
if (status == SDC_CMD_INT_STATUS_CC) {
// get response
cmd->resp[0] = host->regs->response1;
if (cmd->flags & MMC_RSP_136) {
cmd->resp[1] = host->regs->response2;
cmd->resp[2] = host->regs->response3;
cmd->resp[3] = host->regs->response4;
}
break;
}
cmd->error = (status & SDC_CMD_INT_STATUS_CTE) ? -ETIME : -EIO;
break;
}
}
}
static int sdc_setup_data_xfer(struct sdc_host * host, struct mmc_host * mmc, struct mmc_data * data) {
uint64_t timeout = 0;
data->bytes_xfered = 0;
if (host->dma_addr & 3) return -EINVAL;
if (data->blksz & 3) return -EINVAL;
if (data->blksz < 4) return -EINVAL;
if (data->blksz > 0x1000) return -EINVAL;
if (data->blocks > 0x10000) return -EINVAL;
if (host->dma_addr + data->blksz * data->blocks > ((uint64_t)1 << host->dma_addr_bits)) return -EINVAL;
if (data->sg->length < data->blksz * data->blocks) return -EINVAL;
// SD card data transfer time
timeout += data->blocks * data->blksz * 8 / (1 << mmc->ios.bus_width);
// SD card "busy" time
timeout += (uint64_t)mmc->ios.clock * BUSY_TIMEOUT_MS / 1000 * data->blocks;
host->regs->dma_addres = (uint64_t)host->dma_addr;
host->regs->block_size = data->blksz - 1;
host->regs->block_count = data->blocks - 1;
host->regs->data_timeout = (uint32_t)timeout;
if (host->regs->data_timeout != timeout) host->regs->data_timeout = 0;
return 0;
}
static int sdc_send_cmd(struct sdc_host * host, struct mmc_host * mmc, struct mmc_command * cmd, struct mmc_data * data) {
int command = cmd->opcode << 8;
uint64_t timeout = 0;
int xfer = 0;
if (cmd->flags & MMC_RSP_PRESENT) {
if (cmd->flags & MMC_RSP_136)
command |= 2;
else {
command |= 1;
}
}
if (cmd->flags & MMC_RSP_BUSY) command |= 1 << 2;
if (cmd->flags & MMC_RSP_CRC) command |= 1 << 3;
if (cmd->flags & MMC_RSP_OPCODE) command |= 1 << 4;
if (data && (data->flags & (MMC_DATA_READ | MMC_DATA_WRITE)) && data->blocks) {
host->dma_count = dma_map_sg(&host->pdev->dev, data->sg, data->sg_len, mmc_get_dma_dir(data));
if (host->dma_count != 1) {
dma_unmap_sg(&host->pdev->dev, data->sg, data->sg_len, mmc_get_dma_dir(data));
return data->error = -EIO;
}
host->dma_addr = sg_dma_address(data->sg);
host->dma_size = sg_dma_len(data->sg);
if (data->flags & MMC_DATA_READ) command |= 1 << 5;
if (data->flags & MMC_DATA_WRITE) command |= 1 << 6;
data->error = sdc_setup_data_xfer(host, mmc, data);
if (data->error < 0) {
dma_unmap_sg(&host->pdev->dev, data->sg, data->sg_len, mmc_get_dma_dir(data));
return data->error;
}
xfer = 1;
}
timeout = (uint64_t)mmc->ios.clock * CMD_TIMEOUT_MS / 1000;
host->regs->command = command;
host->regs->cmd_timeout = (uint32_t)timeout;
if (host->regs->cmd_timeout != timeout) host->regs->cmd_timeout = 0;
host->regs->argument = cmd->arg;
sdc_cmd_finish(host, cmd);
if (cmd->error < 0) {
if (xfer) dma_unmap_sg(&host->pdev->dev, data->sg, data->sg_len, mmc_get_dma_dir(data));
return cmd->error;
}
if (xfer) host->data = data;
return 0;
}
static void sdc_request(struct mmc_host * mmc, struct mmc_request * mrq) {
struct sdc_host * host = mmc_priv(mmc);
/* Clear the error statuses in case this is a retry */
if (mrq->sbc) mrq->sbc->error = 0;
if (mrq->cmd) mrq->cmd->error = 0;
if (mrq->data) mrq->data->error = 0;
if (mrq->stop) mrq->stop->error = 0;
spin_lock_irq(&host->lock);
host->data = NULL;
host->mrq = mrq;
if (!mrq->sbc || sdc_send_cmd(host, mmc, mrq->sbc, NULL) == 0) {
sdc_send_cmd(host, mmc, mrq->cmd, mrq->data);
}
if (host->data == NULL) {
mmc_request_done(mmc, mrq);
host->mrq = NULL;
}
else {
host->regs->dat_int_enable = SDC_DAT_INT_STATUS_TRS | SDC_DAT_INT_STATUS_ERR;
}
spin_unlock_irq(&host->lock);
}
static void sdc_set_ios(struct mmc_host * mmc, struct mmc_ios * ios) {
struct sdc_host * host = mmc_priv(mmc);
spin_lock_irq(&host->lock);
sdc_set_clock(host, ios->clock);
host->regs->control = ios->bus_width == MMC_BUS_WIDTH_4 ? SDC_CONTROL_SD_4BIT : 0;
spin_unlock_irq(&host->lock);
}
static void sdc_reset(struct mmc_host * mmc) {
struct sdc_host * host = mmc_priv(mmc);
uint32_t card_detect = 0;
spin_lock_init(&host->lock);
spin_lock_irq(&host->lock);
sdc_set_clock(host, 400000);
// software reset
host->regs->software_reset = 1;
while ((host->regs->software_reset & 1) == 0) {}
// clear software reset
host->regs->software_reset = 0;
while (host->regs->software_reset != 0) {}
udelay(10000);
// set bus width 1 bit
host->regs->control = 0;
// disable cmd/data interrupts
host->regs->cmd_int_enable = 0;
host->regs->dat_int_enable = 0;
// clear cmd/data interrupts
host->regs->cmd_int_status = 0;
host->regs->dat_int_status = 0;
// enable card detect interrupt
card_detect = host->regs->card_detect;
if (card_detect & SDC_CARD_INSERT_INT_REQ) {
host->regs->card_detect = SDC_CARD_REMOVE_INT_EN;
}
else if (card_detect & SDC_CARD_REMOVE_INT_REQ) {
host->regs->card_detect = SDC_CARD_INSERT_INT_EN;
}
while (host->regs->software_reset != 0) {}
spin_unlock_irq(&host->lock);
}
static void sdc_card_reset(struct mmc_host * mmc) {
struct sdc_host * host = mmc_priv(mmc);
uint32_t control = 0;
spin_lock_irq(&host->lock);
control = host->regs->control;
host->regs->control = control | SDC_CONTROL_SD_RESET;
udelay(10);
host->regs->control = control & ~(uint32_t)SDC_CONTROL_SD_RESET;
udelay(10);
spin_unlock_irq(&host->lock);
}
static int sdc_get_cd(struct mmc_host * mmc) {
struct sdc_host * host = mmc_priv(mmc);
uint32_t card_detect = host->regs->card_detect;
if (card_detect == 0) return 1; /* Card detect not supported */
return (card_detect & SDC_CARD_INSERT_INT_REQ) != 0;
}
static irqreturn_t sdc_isr(int irq, void * dev_id) {
struct mmc_host * mmc = (struct mmc_host *)dev_id;
struct sdc_host * host = mmc_priv(mmc);
uint32_t card_detect = 0;
uint32_t data_status = 0;
unsigned long flags;
spin_lock_irqsave(&host->lock, flags);
card_detect = host->regs->card_detect;
if (card_detect & SDC_CARD_INSERT_INT_REQ) {
if (card_detect & SDC_CARD_INSERT_INT_EN) {
host->regs->card_detect = SDC_CARD_REMOVE_INT_EN;
mmc_detect_change(mmc, 0);
}
}
else if (card_detect & SDC_CARD_REMOVE_INT_REQ) {
if (card_detect & SDC_CARD_REMOVE_INT_EN) {
host->regs->card_detect = SDC_CARD_INSERT_INT_EN;
mmc_detect_change(mmc, 0);
}
}
if ((data_status = host->regs->dat_int_status) != 0) {
host->regs->dat_int_enable = 0;
host->regs->dat_int_status = 0;
while (host->regs->software_reset != 0) {}
if (host->data) {
struct mmc_request * mrq = host->mrq;
struct mmc_data * data = host->data;
if (data_status == SDC_DAT_INT_STATUS_TRS) {
data->bytes_xfered = data->blksz * data->blocks;
}
else {
data->error = -EIO;
if (data_status & SDC_DAT_INT_STATUS_CTE) data->error = -ETIME;
}
if (mrq->stop) sdc_send_cmd(host, mmc, mrq->stop, NULL);
mmc_request_done(mmc, mrq);
dma_unmap_sg(&host->pdev->dev, data->sg, data->sg_len, mmc_get_dma_dir(data));
host->data = NULL;
host->mrq = NULL;
}
}
spin_unlock_irqrestore(&host->lock, flags);
return IRQ_HANDLED;
}
/*---------------------------------------------------------------------*/
static const struct mmc_host_ops axi_sdc_ops = {
.request = sdc_request,
.set_ios = sdc_set_ios,
.get_cd = sdc_get_cd,
.card_hw_reset = sdc_card_reset,
};
static int axi_sdc_probe(struct platform_device * pdev) {
struct device * dev = &pdev->dev;
struct resource * iomem;
struct sdc_host * host;
struct mmc_host * mmc;
void __iomem * ioaddr;
uint32_t capability;
int irq;
int ret;
iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
ioaddr = devm_ioremap_resource(dev, iomem);
if (IS_ERR(ioaddr)) return PTR_ERR(ioaddr);
irq = platform_get_irq(pdev, 0);
if (irq <= 0) return -ENXIO;
mmc = mmc_alloc_host(sizeof(*host), dev);
if (!mmc) return -ENOMEM;
mmc->ops = &axi_sdc_ops;
host = mmc_priv(mmc);
host->pdev = pdev;
host->regs = (struct sdc_regs __iomem *)ioaddr;
host->irq = irq;
ret = of_property_read_u32(dev->of_node, "clock", &host->clk_freq);
if (ret) host->clk_freq = 100000000;
ret = mmc_of_parse(mmc);
if (ret) {
mmc_free_host(mmc);
return ret;
}
if (mmc->f_min == 0) mmc->f_min = host->clk_freq / 0x200; /* maximum clock division 256 * 2 */
if (mmc->f_max == 0) mmc->f_max = host->clk_freq / 2; /* minimum clock division 2 */
if ((mmc->caps2 & MMC_CAP2_NO_SDIO) == 0) {
/* TODO: deprecated 10/19/2022, set in DTS */
mmc->caps |= MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED;
mmc->caps2 |= MMC_CAP2_NO_SDIO;
}
mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
mmc->max_segs = 1;
mmc->max_req_size = 0x2000000;
mmc->max_seg_size = 0x2000000;
mmc->max_blk_size = 0x1000;
mmc->max_blk_count = 0x10000;
ret = request_irq(host->irq, sdc_isr, IRQF_TRIGGER_HIGH, "fpga-axi-sdc", mmc);
if (ret) {
mmc_free_host(mmc);
return ret;
}
host->dma_addr_bits = 32;
capability = host->regs->capability;
if (capability & SDC_CAPABILITY_ADDR) {
host->dma_addr_bits = (capability & SDC_CAPABILITY_ADDR) >> __builtin_ctz(SDC_CAPABILITY_ADDR);
ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(host->dma_addr_bits));
if (ret) {
printk(KERN_ERR "AXI-SDC: Can't set DMA mask\n");
mmc_free_host(mmc);
return ret;
}
}
sdc_reset(mmc);
ret = mmc_add_host(mmc);
if (ret) {
printk(KERN_ERR "AXI-SDC: Can't register device\n");
mmc_free_host(mmc);
return ret;
}
//spin_lock_init(&host->lock);
platform_set_drvdata(pdev, host);
return 0;
}
static int axi_sdc_remove(struct platform_device * pdev) {
struct sdc_host * host = platform_get_drvdata(pdev);
struct mmc_host * mmc = mmc_from_priv(host);
free_irq(host->irq, mmc);
mmc_remove_host(mmc);
mmc_free_host(mmc);
return 0;
}
static struct platform_driver axi_sdc_driver = {
.driver = {
.name = "riscv-axi-sdc",
.of_match_table = axi_sdc_of_match_table,
},
.probe = axi_sdc_probe,
.remove = axi_sdc_remove,
};
module_platform_driver(axi_sdc_driver);
MODULE_DESCRIPTION("AXI SD Card driver");
MODULE_AUTHOR("Eugene Tarassov");
MODULE_LICENSE("GPL v2");

View File

@ -1,12 +0,0 @@
diff --git a/package/Config.in b/package/Config.in
index 82b28d2835..29e8bb66ac 100644
--- a/package/Config.in
+++ b/package/Config.in
@@ -469,6 +469,7 @@ endmenu
source "package/fconfig/Config.in"
source "package/flashrom/Config.in"
source "package/fmtools/Config.in"
+ source "package/fpga-axi-sdc/Config.in"
source "package/freescale-imx/Config.in"
source "package/fxload/Config.in"
source "package/gcnano-binaries/Config.in"

File diff suppressed because it is too large Load Diff

View File

@ -192,9 +192,9 @@ if {$DEBUG > 0} {
# suppress spurious warnngs about # suppress spurious warnngs about
# "Extra checking for conflicts with always_comb done at vopt time" # "Extra checking for conflicts with always_comb done at vopt time"
# because vsim will run vopt # because vsim will run vopt
set INC_DIRS "+incdir+${CONFIG}/${CFG} +incdir+${CONFIG}/deriv/${CFG} +incdir+${CONFIG}/shared +incdir+${FCRVVI} +incdir+${FCRVVI}/rv32 +incdir+${FCRVVI}/rv64 +incdir+${FCRVVI}/common +incdir+${FCRVVI}" set INC_DIRS "+incdir+${CONFIG}/${CFG} +incdir+${CONFIG}/deriv/${CFG} +incdir+${CONFIG}/shared +incdir+${FCRVVI} +incdir+${FCRVVI}/rv32 +incdir+${FCRVVI}/rv64 +incdir+${FCRVVI}/rv64_priv +incdir+${FCRVVI}/common +incdir+${FCRVVI}"
set SOURCES "${SRC}/cvw.sv ${TB}/${TESTBENCH}.sv ${TB}/common/*.sv ${SRC}/*/*.sv ${SRC}/*/*/*.sv ${WALLY}/addins/verilog-ethernet/*/*.sv ${WALLY}/addins/verilog-ethernet/*/*/*/*.sv" set SOURCES "${SRC}/cvw.sv ${TB}/${TESTBENCH}.sv ${TB}/common/*.sv ${SRC}/*/*.sv ${SRC}/*/*/*.sv ${WALLY}/addins/verilog-ethernet/*/*.sv ${WALLY}/addins/verilog-ethernet/*/*/*/*.sv"
vlog -lint +nowarnRDGN -work ${WKDIR} {*}${INC_DIRS} {*}${FCvlog} {*}${FCdefineCOVER_EXTS} {*}${lockstepvlog} ${FCdefineRVVI_COVERAGE} {*}${SOURCES} -suppress 2244 -suppress 2282 -suppress 2583 -suppress 7063,2596,13286 vlog -permissive -lint -work ${WKDIR} {*}${INC_DIRS} {*}${FCvlog} {*}${FCdefineCOVER_EXTS} {*}${lockstepvlog} ${FCdefineRVVI_COVERAGE} {*}${SOURCES} -suppress 2282,2583,7053,7063,2596,13286
# start and run simulation # start and run simulation
# remove +acc flag for faster sim during regressions if there is no need to access internal signals # remove +acc flag for faster sim during regressions if there is no need to access internal signals

View File

@ -63,6 +63,16 @@ module wallyTracer import cvw::*; #(parameter cvw_t P) (rvviTrace rvvi);
logic [11:0] CSRAdrM, CSRAdrW; logic [11:0] CSRAdrM, CSRAdrW;
logic wfiM; logic wfiM;
logic InterruptM, InterruptW; logic InterruptM, InterruptW;
//For VM Verification
logic [(P.XLEN-1):0] VAdrIM,VAdrDM,VAdrIW,VAdrDW;
logic [(P.XLEN-1):0] PTE_iM,PTE_dM,PTE_iW,PTE_dW;
logic [(P.PA_BITS-1):0] PAIM,PADM,PAIW,PADW;
logic [(P.PPN_BITS-1):0] PPN_iM,PPN_dM,PPN_iW,PPN_dW;
logic ReadAccessM,WriteAccessM,ReadAccessW,WriteAccessW;
logic ExecuteAccessF,ExecuteAccessD,ExecuteAccessE,ExecuteAccessM,ExecuteAccessW;
assign clk = testbench.dut.clk; assign clk = testbench.dut.clk;
// assign InstrValidF = testbench.dut.core.ieu.InstrValidF; // not needed yet // assign InstrValidF = testbench.dut.core.ieu.InstrValidF; // not needed yet
@ -92,6 +102,20 @@ module wallyTracer import cvw::*; #(parameter cvw_t P) (rvviTrace rvvi);
assign STATUS_UXL = testbench.dut.core.priv.priv.csr.csrsr.STATUS_UXL; assign STATUS_UXL = testbench.dut.core.priv.priv.csr.csrsr.STATUS_UXL;
assign wfiM = testbench.dut.core.priv.priv.wfiM; assign wfiM = testbench.dut.core.priv.priv.wfiM;
assign InterruptM = testbench.dut.core.priv.priv.InterruptM; assign InterruptM = testbench.dut.core.priv.priv.InterruptM;
//FOr VM Verification
assign VAdrIM = testbench.dut.core.ifu.immu.immu.tlb.tlb.VAdr;
assign VAdrDM = testbench.dut.core.lsu.dmmu.dmmu.tlb.tlb.VAdr;
assign PAIM = testbench.dut.core.ifu.immu.immu.PhysicalAddress;
assign PADM = testbench.dut.core.lsu.dmmu.dmmu.PhysicalAddress;
assign ReadAccessM = testbench.dut.core.lsu.dmmu.dmmu.ReadAccessM;
assign WriteAccessM = testbench.dut.core.lsu.dmmu.dmmu.WriteAccessM;
assign ExecuteAccessF = testbench.dut.core.ifu.immu.immu.ExecuteAccessF;
assign PTE_iM = testbench.dut.core.ifu.immu.immu.PTE;
assign PTE_dM = testbench.dut.core.lsu.dmmu.dmmu.PTE;
assign PPN_iM = testbench.dut.core.ifu.immu.immu.tlb.tlb.PPN;
assign PPN_dM = testbench.dut.core.lsu.dmmu.dmmu.tlb.tlb.PPN;
logic valid; logic valid;
@ -276,6 +300,22 @@ module wallyTracer import cvw::*; #(parameter cvw_t P) (rvviTrace rvvi);
flopenrc #(12) CSRAdrWReg (clk, reset, FlushW, ~StallW, CSRAdrM, CSRAdrW); flopenrc #(12) CSRAdrWReg (clk, reset, FlushW, ~StallW, CSRAdrM, CSRAdrW);
flopenrc #(1) CSRWriteWReg (clk, reset, FlushW, ~StallW, CSRWriteM, CSRWriteW); flopenrc #(1) CSRWriteWReg (clk, reset, FlushW, ~StallW, CSRWriteM, CSRWriteW);
//for VM Verification
flopenrc #(P.XLEN) VAdrIWReg (clk, reset, FlushW, ~StallW, VAdrIM, VAdrIW);
flopenrc #(P.XLEN) VAdrDWReg (clk, reset, FlushW, ~StallW, VAdrDM, VAdrDW);
flopenrc #(P.PA_BITS) PAIWReg (clk, reset, FlushW, ~StallW, PAIM, PAIW);
flopenrc #(P.PA_BITS) PADWReg (clk, reset, FlushW, ~StallW, PADM, PADW);
flopenrc #(P.XLEN) PTE_iWReg (clk, reset, FlushW, ~StallW, PTE_iM, PTE_iW);
flopenrc #(P.XLEN) PTE_dWReg (clk, reset, FlushW, ~StallW, PTE_dM, PTE_dW);
flopenrc #(P.PPN_BITS) PPN_iWReg (clk, reset, FlushW, ~StallW, PPN_iM, PPN_iW);
flopenrc #(P.PPN_BITS) PPN_dWReg (clk, reset, FlushW, ~StallW, PPN_dM, PPN_dW);
flopenrc #(1) ReadAccessWReg (clk, reset, FlushW, ~StallW, ReadAccessM, ReadAccessW);
flopenrc #(1) WriteAccessWReg (clk, reset, FlushW, ~StallW, WriteAccessM, WriteAccessW);
flopenrc #(1) ExecuteAccessDReg (clk, reset, FlushE, ~StallE, ExecuteAccessF, ExecuteAccessD);
flopenrc #(1) ExecuteAccessEReg (clk, reset, FlushE, ~StallE, ExecuteAccessD, ExecuteAccessE);
flopenrc #(1) ExecuteAccessMReg (clk, reset, FlushM, ~StallM, ExecuteAccessE, ExecuteAccessM);
flopenrc #(1) ExecuteAccessWReg (clk, reset, FlushW, ~StallW, ExecuteAccessM, ExecuteAccessW);
// Initially connecting the writeback stage signals, but may need to use M stage // Initially connecting the writeback stage signals, but may need to use M stage
// and gate on ~FlushW. // and gate on ~FlushW.