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

Initial MIPS CPUs support #1990

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
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
34 changes: 34 additions & 0 deletions litex/soc/cores/cpu/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ def __init__(self, *args, **kwargs):
def set_reset_address(self, reset_address):
pass # pass must be overloaded (if required)

def bios_map(self, addr, cached):
return addr

def enable_reset_address_check(self):
self.reset_address_check = True

Expand Down Expand Up @@ -90,6 +93,37 @@ def __init__(self, data_width=32, addr_width=32):
"riscv-none-elf",
)

CPU_GCC_TRIPLE_MIPS = (
"mips-unknown-elf",
"mips-sde-elf",
"mips-mti-elf",
"mips-img-elf",
"mips-linux-musl",
"mips-linux-musln32sf",
"mips-linux-muslsf",
"mipsel-linux-musl",
"mipsel-linux-musln32sf",
"mipsel-linux-muslsf",
"mips64-linux-musl",
"mips64-linux-musln32",
"mips64-linux-musln32sf",
"mips64-linux-muslsf",
"mips64el-linux-musl",
"mips64el-linux-musln32",
"mips64el-linux-musln32sf",
"mips64el-linux-muslsf",
"mips-linux-gnu",
"mipsel-linux-gnu",
"mips64-linux-gnu",
"mips64-linux-gnuabi64",
"mips64el-linux-gnu",
"mips64el-linux-gnuabi64",
"mipsisa32r6-linux-gnu",
"mipsisa32r6el-linux-gnu",
"mipsisa64r6-linux-gnuabi64",
"mipsisa64r6el-linux-gnuabi64",
)

# CPUs Collection ----------------------------------------------------------------------------------

def collect_cpus():
Expand Down
1 change: 1 addition & 0 deletions litex/soc/cores/cpu/cdim/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from litex.soc.cores.cpu.cdim.core import CDIM
4 changes: 4 additions & 0 deletions litex/soc/cores/cpu/cdim/boot-helper.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.section .text, "ax", @progbits
.global boot_helper
boot_helper:
jr $a3
129 changes: 129 additions & 0 deletions litex/soc/cores/cpu/cdim/core.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
#
# This file is part of LiteX.
#
# Copyright (c) 2024 Jiaxun Yang <[email protected]>
# SPDX-License-Identifier: BSD-2-Clause

import os

from migen import *
from litex.gen import *

from litex.soc.interconnect import axi
from litex.soc.cores.cpu import CPU, CPU_GCC_TRIPLE_MIPS

class CDIM(CPU):
category = "softcore"
family = "mips"
name = "cdim"
human_name = "CQU CDIM"
variants = ["standard"]
data_width = 32
endianness = "little"
gcc_triple = CPU_GCC_TRIPLE_MIPS
linker_output_format = "elf32-tradlittlemips"
nop = "nop"
io_regions = {0x1000_0000: 0x0c00_0000} # Origin, Length.

# GCC Flags.
@property
def gcc_flags(self):
flags = "-march=mips32 -mabi=32 -EL -msoft-float"
flags += " -D__cdim__ "
flags += " -DUART_POLLING"
return flags

# Memory Mapping.
@property
def mem_map(self):
# Based on vanilla sysmap.h
return {
"main_ram" : 0x0000_0000,
"csr" : 0x1800_0000,
"sram" : 0x1c00_0000,
"rom" : 0x1fc0_0000,
}

def __init__(self, platform, variant="standard"):
self.platform = platform
self.variant = variant
self.reset = Signal()
self.interrupt = Signal(6)
# Peripheral bus (Connected to main SoC's bus).
axi_if = axi.AXIInterface(data_width=32, address_width=32, id_width=4)
self.periph_buses = [axi_if]
# Memory buses (Connected directly to LiteDRAM).
self.memory_buses = []

# CPU Instance.
self.cpu_params = dict(
# Clk / Rst
i_aclk = ClockSignal("sys"),
i_aresetn = ~ResetSignal("sys") & ~self.reset,

# Interrupts
i_ext_int= self.interrupt,

# AXI interface
o_arid = axi_if.ar.id,
o_araddr = axi_if.ar.addr,
o_arlen = axi_if.ar.len,
o_arsize = axi_if.ar.size,
o_arburst = axi_if.ar.burst,
o_arlock = axi_if.ar.lock,
o_arcache = axi_if.ar.cache,
o_arprot = axi_if.ar.prot,
o_arvalid = axi_if.ar.valid,
i_arready = axi_if.ar.ready,

i_rid = axi_if.r.id,
i_rdata = axi_if.r.data,
i_rresp = axi_if.r.resp,
i_rlast = axi_if.r.last,
i_rvalid = axi_if.r.valid,
o_rready = axi_if.r.ready,

o_awid = axi_if.aw.id,
o_awaddr = axi_if.aw.addr,
o_awlen = axi_if.aw.len,
o_awsize = axi_if.aw.size,
o_awburst = axi_if.aw.burst,
o_awlock = axi_if.aw.lock,
o_awcache = axi_if.aw.cache,
o_awprot = axi_if.aw.prot,
o_awvalid = axi_if.aw.valid,
i_awready = axi_if.aw.ready,

o_wid = axi_if.w.id,
o_wdata = axi_if.w.data,
o_wstrb = axi_if.w.strb,
o_wlast = axi_if.w.last,
o_wvalid = axi_if.w.valid,
i_wready = axi_if.w.ready,

i_bid = axi_if.b.id,
i_bresp = axi_if.b.resp,
i_bvalid = axi_if.b.valid,
o_bready = axi_if.b.ready,
)

# Add sources
basedir = os.path.join("CDIM", "mycpu")
self.platform.add_source_dir(basedir)
platform.add_verilog_include_path(basedir)

def set_reset_address(self, reset_address):
# Hardcoded reset address.
assert reset_address == 0x1fc0_0000
self.reset_address = reset_address

def bios_map(self, addr, cached):
# We can't access beyond KSEG0/1 in BIOS
assert addr < 0x2000_0000
if cached:
return addr + 0x8000_0000
else:
return addr + 0xa000_0000

def do_finalize(self):
self.specials += Instance("mycpu_top", **self.cpu_params)
44 changes: 44 additions & 0 deletions litex/soc/cores/cpu/cdim/crt0.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
.global main
.global isr
.global _start

_start:
j crt_init
nop
nop
nop
nop
nop
nop
nop

crt_init:
la $sp, _fstack

data_init:
la $t0, _fdata
la $t1, _edata
la $t2, _fdata_rom
data_loop:
beq $t0, $t1, data_done
lw $t3, 0($t2)
sw $t3, 0($t0)
addiu $t0, $t0,4
addiu $t2, $t2,4
b data_loop
data_done:

bss_init:
la $t0, _fbss
la $t1, _ebss
bss_loop:
beq $t0, $t1, bss_done
sw $zero, 0($t0)
addiu $t0, $t0, 4
b bss_loop
bss_done:

la $t9, main
jalr $t9
inf_loop:
b inf_loop
45 changes: 45 additions & 0 deletions litex/soc/cores/cpu/cdim/irq.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#ifndef __IRQ_H
#define __IRQ_H

#include <stdint.h>
#include "system.h"
#include "generated/soc.h"


#ifdef __cplusplus
extern "C" {
#endif


static inline unsigned int irq_getie(void)
{
return 0; /* FIXME */
}

static inline void irq_setie(unsigned int ie)
{
/* TODO */
}

static inline unsigned int irq_getmask(void)
{
return (1 << UART_INTERRUPT); // FIXME
}

static inline void irq_setmask(unsigned int mask)
{
/* TODO */
}

static inline unsigned int irq_pending(void)
{
/* TODO */
return 0;
}


#ifdef __cplusplus
}
#endif

#endif /* __IRQ_H */
19 changes: 19 additions & 0 deletions litex/soc/cores/cpu/cdim/system.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#ifndef __SYSTEM_H
#define __SYSTEM_H

#ifdef __cplusplus
extern "C" {
#endif

__attribute__((unused)) static void flush_cpu_icache(void){}; /* No instruction cache */
__attribute__((unused)) static void flush_cpu_dcache(void){}; /* No instruction cache */
void flush_l2_cache(void);

void busy_wait(unsigned int ms);
void busy_wait_us(unsigned int us);

#ifdef __cplusplus
}
#endif

#endif /* __SYSTEM_H */
1 change: 1 addition & 0 deletions litex/soc/cores/cpu/gs232/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from litex.soc.cores.cpu.gs232.core import GS232
4 changes: 4 additions & 0 deletions litex/soc/cores/cpu/gs232/boot-helper.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.section .text, "ax", @progbits
.global boot_helper
boot_helper:
jr $a3
Loading
Loading