From 1c08aeb21cab38fd70cf11efc6e125701ca3bf63 Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Wed, 14 May 2014 10:24:56 +0200 Subject: [PATCH] Initial mor1kx (OpenRISC) support Based on milkymist-ng-mor1kx by Stefan Kristiansson --- .gitignore | 1 + .gitmodules | 3 + make.py | 21 +- misoclib/gensoc/__init__.py | 39 +- misoclib/gensoc/cpuif.py | 12 + misoclib/mor1kx/__init__.py | 73 ++ software/bios/Makefile | 4 +- .../{boot-helper.S => boot-helper-lm32.S} | 0 software/bios/boot-helper-or1k.S | 10 + software/bios/isr.c | 14 + software/bios/linker.ld | 2 +- software/bios/main.c | 19 +- software/bios/sdram.c | 6 + software/common.mak | 8 +- software/include/base/irq.h | 59 +- software/include/base/spr-defs.h | 696 ++++++++++++++++++ software/include/base/system.h | 17 + software/libbase/Makefile | 4 +- software/libbase/{crt0.S => crt0-lm32.S} | 0 software/libbase/crt0-or1k.S | 434 +++++++++++ software/libbase/linker-sdram.ld | 2 +- software/libbase/{setjmp.S => setjmp-lm32.S} | 0 software/libbase/setjmp-or1k.S | 66 ++ software/libbase/system.c | 47 ++ software/memtest/Makefile | 2 +- software/videomixer/Makefile | 2 +- targets/mlabs_video.py | 13 +- targets/simple.py | 7 +- verilog/mor1kx/submodule | 1 + 29 files changed, 1504 insertions(+), 58 deletions(-) create mode 100644 misoclib/mor1kx/__init__.py rename software/bios/{boot-helper.S => boot-helper-lm32.S} (100%) create mode 100644 software/bios/boot-helper-or1k.S create mode 100644 software/include/base/spr-defs.h rename software/libbase/{crt0.S => crt0-lm32.S} (100%) create mode 100644 software/libbase/crt0-or1k.S rename software/libbase/{setjmp.S => setjmp-lm32.S} (100%) create mode 100644 software/libbase/setjmp-or1k.S create mode 160000 verilog/mor1kx/submodule diff --git a/.gitignore b/.gitignore index 45c29b2c..0ce6c634 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,7 @@ tools/mkmscimg tools/byteswap software/include/generated/*.h software/include/generated/*.ld +software/include/generated/*.mak software/videomixer/dvisampler0.c software/videomixer/dvisampler0.h software/videomixer/dvisampler1.c diff --git a/.gitmodules b/.gitmodules index 07ef9c74..41a166d1 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "verilog/lm32/submodule"] path = verilog/lm32/submodule url = https://github.com/m-labs/lm32.git +[submodule "verilog/mor1kx/submodule"] + path = verilog/mor1kx/submodule + url = https://github.com/openrisc/mor1kx.git diff --git a/make.py b/make.py index 8d6edf38..57e16700 100755 --- a/make.py +++ b/make.py @@ -21,7 +21,7 @@ One or several actions can be specified: clean delete previous build(s). build-bitstream build FPGA bitstream. Implies build-bios on targets with integrated BIOS. -build-headers build software header files with CSR/IRQ/SDRAM_PHY definitions. +build-headers build software header files with CPU/CSR/IRQ/SDRAM_PHY definitions. build-csr-csv save CSR map into CSV file. build-bios build BIOS. Implies build-header. @@ -119,7 +119,8 @@ a high performance and small footprint SoC based on Migen Platform: {} Target: {} Subtarget: {} -===========================""".format(platform_name, args.target, top_class.__name__)) +CPU type: {} +===========================""".format(platform_name, args.target, top_class.__name__, soc.cpu_type)) # dependencies if actions["all"]: @@ -135,17 +136,27 @@ Subtarget: {} if actions["clean"]: subprocess.call(["rm", "-rf", "build/*"]) + subprocess.call(["make", "-C", "software/libcompiler-rt", "clean"]) + subprocess.call(["make", "-C", "software/libbase", "clean"]) + subprocess.call(["make", "-C", "software/libnet", "clean"]) + subprocess.call(["make", "-C", "software/bios", "clean"]) if actions["build-headers"]: boilerplate = """/* * Platform: {} * Target: {} * Subtarget: {} + * CPU type: {} */ -""".format(platform_name, args.target, top_class.__name__) - linker_header = cpuif.get_linker_regions(soc.cpu_memory_regions) - write_to_file("software/include/generated/regions.ld", boilerplate + linker_header) +""".format(platform_name, args.target, top_class.__name__, soc.cpu_type) + cpu_mak = cpuif.get_cpu_mak(soc.cpu_type) + write_to_file("software/include/generated/cpu.mak", cpu_mak) + linker_output_format = cpuif.get_linker_output_format(soc.cpu_type) + write_to_file("software/include/generated/output_format.ld", linker_output_format) + + linker_regions = cpuif.get_linker_regions(soc.cpu_memory_regions) + write_to_file("software/include/generated/regions.ld", boilerplate + linker_regions) try: flash_boot_address = soc.flash_boot_address except AttributeError: diff --git a/misoclib/gensoc/__init__.py b/misoclib/gensoc/__init__.py index 7780b068..4f3d17fe 100644 --- a/misoclib/gensoc/__init__.py +++ b/misoclib/gensoc/__init__.py @@ -8,7 +8,7 @@ from migen.bank import csrgen from migen.bus import wishbone, csr, lasmibus, dfi from migen.bus import wishbone2lasmi, wishbone2csr -from misoclib import lm32, uart, dfii, lasmicon, identifier, timer, memtest +from misoclib import lm32, mor1kx, uart, dfii, lasmicon, identifier, timer, memtest class GenSoC(Module): csr_base = 0xe0000000 @@ -30,16 +30,22 @@ class GenSoC(Module): "papilio_pro": 0x5050 }) - def __init__(self, platform, clk_freq, cpu_reset_address, sram_size=4096, l2_size=0, with_uart=True): + def __init__(self, platform, clk_freq, cpu_reset_address, sram_size=4096, l2_size=0, with_uart=True, cpu_type="lm32"): self.clk_freq = clk_freq self.cpu_reset_address = cpu_reset_address self.sram_size = sram_size self.l2_size = l2_size + self.cpu_type = cpu_type self.cpu_memory_regions = [] self._rom_registered = False # Wishbone - self.submodules.cpu = lm32.LM32(cpu_reset_address) + if cpu_type == "lm32": + self.submodules.cpu = lm32.LM32(cpu_reset_address) + elif cpu_type == "or1k": + self.submodules.cpu = mor1kx.MOR1KX(cpu_reset_address) + else: + raise ValueError("Unsupported CPU type: "+cpu_type) self.submodules.sram = wishbone.SRAM(sram_size) self.submodules.wishbone2csr = wishbone2csr.WB2CSR() @@ -60,16 +66,19 @@ class GenSoC(Module): log2_int(l2_size) if l2_size else 0) self.submodules.timer0 = timer.Timer() - # add LM32 verilog sources - platform.add_sources(os.path.join("verilog", "lm32", "submodule", "rtl"), - "lm32_cpu.v", "lm32_instruction_unit.v", "lm32_decoder.v", - "lm32_load_store_unit.v", "lm32_adder.v", "lm32_addsub.v", "lm32_logic_op.v", - "lm32_shifter.v", "lm32_multiplier.v", "lm32_mc_arithmetic.v", - "lm32_interrupt.v", "lm32_ram.v", "lm32_dp_ram.v", "lm32_icache.v", - "lm32_dcache.v", "lm32_debug.v", "lm32_itlb.v", "lm32_dtlb.v") - platform.add_verilog_include_path(os.path.join("verilog", "lm32")) - - def register_rom(self, rom_wb_if, bios_size=0x8000): + # add CPU Verilog sources + if cpu_type == "lm32": + platform.add_sources(os.path.join("verilog", "lm32", "submodule", "rtl"), + "lm32_cpu.v", "lm32_instruction_unit.v", "lm32_decoder.v", + "lm32_load_store_unit.v", "lm32_adder.v", "lm32_addsub.v", "lm32_logic_op.v", + "lm32_shifter.v", "lm32_multiplier.v", "lm32_mc_arithmetic.v", + "lm32_interrupt.v", "lm32_ram.v", "lm32_dp_ram.v", "lm32_icache.v", + "lm32_dcache.v", "lm32_debug.v", "lm32_itlb.v", "lm32_dtlb.v") + platform.add_verilog_include_path(os.path.join("verilog", "lm32")) + if cpu_type == "or1k": + platform.add_source_dir(os.path.join("verilog", "mor1kx", "submodule", "rtl", "verilog")) + + def register_rom(self, rom_wb_if, bios_size=0xa000): if self._rom_registered: raise FinalizeError self._rom_registered = True @@ -131,8 +140,8 @@ class SDRAMSoC(GenSoC): } csr_map.update(GenSoC.csr_map) - def __init__(self, platform, clk_freq, cpu_reset_address, with_memtest=False, sram_size=4096, l2_size=8192, with_uart=True): - GenSoC.__init__(self, platform, clk_freq, cpu_reset_address, sram_size, l2_size, with_uart) + def __init__(self, platform, clk_freq, cpu_reset_address, with_memtest=False, sram_size=4096, l2_size=8192, with_uart=True, **kwargs): + GenSoC.__init__(self, platform, clk_freq, cpu_reset_address, sram_size, l2_size, with_uart, **kwargs) self.with_memtest = with_memtest self._sdram_phy_registered = False diff --git a/misoclib/gensoc/cpuif.py b/misoclib/gensoc/cpuif.py index 3ebdd118..82d5cdbc 100644 --- a/misoclib/gensoc/cpuif.py +++ b/misoclib/gensoc/cpuif.py @@ -1,5 +1,17 @@ from migen.bank.description import CSRStatus +def get_cpu_mak(cpu_type): + if cpu_type == "lm32": + cpuflags = "-mbarrel-shift-enabled -mmultiply-enabled -mdivide-enabled -msign-extend-enabled" + elif cpu_type == "or1k": + cpuflags = "-mhard-mul -mhard-div" + else: + raise ValueError("Unsupported CPU type: "+cpu_type) + return "CPU={}\nCPUFLAGS={}\n".format(cpu_type, cpuflags) + +def get_linker_output_format(cpu_type): + return "OUTPUT_FORMAT(\"elf32-{}\")\n".format(cpu_type) + def get_linker_regions(regions): r = "MEMORY {\n" for name, origin, length in regions: diff --git a/misoclib/mor1kx/__init__.py b/misoclib/mor1kx/__init__.py new file mode 100644 index 00000000..173d29e4 --- /dev/null +++ b/misoclib/mor1kx/__init__.py @@ -0,0 +1,73 @@ +from migen.fhdl.std import * +from migen.bus import wishbone + +class MOR1KX(Module): + def __init__(self, reset_pc): + self.ibus = i = wishbone.Interface() + self.dbus = d = wishbone.Interface() + self.interrupt = Signal(32) + + ### + + i_adr_o = Signal(32) + d_adr_o = Signal(32) + self.specials += Instance("mor1kx", + p_FEATURE_INSTRUCTIONCACHE="ENABLED", + p_OPTION_ICACHE_BLOCK_WIDTH=4, + p_OPTION_ICACHE_SET_WIDTH=8, + p_OPTION_ICACHE_WAYS=1, + p_OPTION_ICACHE_LIMIT_WIDTH=31, + p_FEATURE_DATACACHE="ENABLED", + p_OPTION_DCACHE_BLOCK_WIDTH=4, + p_OPTION_DCACHE_SET_WIDTH=8, + p_OPTION_DCACHE_WAYS=1, + p_OPTION_DCACHE_LIMIT_WIDTH=31, + p_FEATURE_TIMER="NONE", + p_OPTION_PIC_TRIGGER="LEVEL", + p_FEATURE_SYSCALL="NONE", + p_FEATURE_TRAP="NONE", + p_FEATURE_RANGE="NONE", + p_FEATURE_OVERFLOW="NONE", + p_FEATURE_ADDC="NONE", + p_FEATURE_CMOV="NONE", + p_FEATURE_FFL1="NONE", + p_OPTION_CPU0="CAPPUCCINO", + p_OPTION_RESET_PC=reset_pc, + p_IBUS_WB_TYPE="B3_REGISTERED_FEEDBACK", + p_DBUS_WB_TYPE="B3_REGISTERED_FEEDBACK", + + i_clk=ClockSignal(), + i_rst=ResetSignal(), + + i_irq_i=self.interrupt, + + o_iwbm_adr_o=i_adr_o, + o_iwbm_dat_o=i.dat_w, + o_iwbm_sel_o=i.sel, + o_iwbm_cyc_o=i.cyc, + o_iwbm_stb_o=i.stb, + o_iwbm_we_o=i.we, + o_iwbm_cti_o=i.cti, + o_iwbm_bte_o=i.bte, + i_iwbm_dat_i=i.dat_r, + i_iwbm_ack_i=i.ack, + i_iwbm_err_i=i.err, + i_iwbm_rty_i=0, + + o_dwbm_adr_o=d_adr_o, + o_dwbm_dat_o=d.dat_w, + o_dwbm_sel_o=d.sel, + o_dwbm_cyc_o=d.cyc, + o_dwbm_stb_o=d.stb, + o_dwbm_we_o=d.we, + o_dwbm_cti_o=d.cti, + o_dwbm_bte_o=d.bte, + i_dwbm_dat_i=d.dat_r, + i_dwbm_ack_i=d.ack, + i_dwbm_err_i=d.err, + i_dwbm_rty_i=0) + + self.comb += [ + self.ibus.adr.eq(i_adr_o[2:]), + self.dbus.adr.eq(d_adr_o[2:]) + ] diff --git a/software/bios/Makefile b/software/bios/Makefile index d338c007..bd849f07 100644 --- a/software/bios/Makefile +++ b/software/bios/Makefile @@ -1,7 +1,7 @@ MSCDIR=../.. include $(MSCDIR)/software/common.mak -OBJECTS=isr.o sdram.o main.o boot-helper.o boot.o dataflow.o +OBJECTS=isr.o sdram.o main.o boot-helper-$(CPU).o boot.o dataflow.o all: bios.bin @@ -17,7 +17,7 @@ bios.elf: linker.ld $(OBJECTS) libs %.elf: $(LD) $(LDFLAGS) -T $< -N -o $@ \ - $(MSCDIR)/software/libbase/crt0.o \ + $(MSCDIR)/software/libbase/crt0-$(CPU).o \ $(OBJECTS) \ -L$(MSCDIR)/software/libnet \ -L$(MSCDIR)/software/libbase \ diff --git a/software/bios/boot-helper.S b/software/bios/boot-helper-lm32.S similarity index 100% rename from software/bios/boot-helper.S rename to software/bios/boot-helper-lm32.S diff --git a/software/bios/boot-helper-or1k.S b/software/bios/boot-helper-or1k.S new file mode 100644 index 00000000..ce775e8b --- /dev/null +++ b/software/bios/boot-helper-or1k.S @@ -0,0 +1,10 @@ +.section .text, "ax", @progbits +.global boot_helper +boot_helper: + /* Invalidate instruction cache */ + /* FIXME: wcsr ICC, r0 */ + l.nop + l.nop + l.nop + l.nop + l.jr r7 diff --git a/software/bios/isr.c b/software/bios/isr.c index c49d31d8..47d91542 100644 --- a/software/bios/isr.c +++ b/software/bios/isr.c @@ -12,3 +12,17 @@ void isr(void) if(irqs & (1 << UART_INTERRUPT)) uart_isr(); } + +#ifdef __or1k__ +#define EXTERNAL_IRQ 0x800 +void exception_handler(unsigned long vect, unsigned long *sp); +void exception_handler(unsigned long vect, unsigned long *sp) +{ + if ((vect & 0xf00) == EXTERNAL_IRQ) { + isr(); + } else { + /* Unhandled exception */ + for(;;); + } +} +#endif diff --git a/software/bios/linker.ld b/software/bios/linker.ld index 302f7e02..59960b7c 100644 --- a/software/bios/linker.ld +++ b/software/bios/linker.ld @@ -1,4 +1,4 @@ -OUTPUT_FORMAT("elf32-lm32") +INCLUDE generated/output_format.ld ENTRY(_start) __DYNAMIC = 0; diff --git a/software/bios/main.c b/software/bios/main.c index b779496d..7bd0d085 100644 --- a/software/bios/main.c +++ b/software/bios/main.c @@ -16,12 +16,6 @@ #include "dataflow.h" #include "boot.h" -enum { - CSR_IE = 1, CSR_IM, CSR_IP, CSR_ICC, CSR_DCC, CSR_CC, CSR_CFG, CSR_EBA, - CSR_DC, CSR_DEBA, CSR_JTX, CSR_JRX, CSR_BP0, CSR_BP1, CSR_BP2, CSR_BP3, - CSR_WP0, CSR_WP1, CSR_WP2, CSR_WP3, -}; - /* General address space functions */ #define NUMBER_OF_BYTES_ON_A_LINE 16 @@ -182,6 +176,13 @@ static void crc(char *startaddr, char *len) printf("CRC32: %08x\n", crc32((unsigned char *)addr, length)); } +#ifdef __lm32__ +enum { + CSR_IE = 1, CSR_IM, CSR_IP, CSR_ICC, CSR_DCC, CSR_CC, CSR_CFG, CSR_EBA, + CSR_DC, CSR_DEBA, CSR_JTX, CSR_JRX, CSR_BP0, CSR_BP1, CSR_BP2, CSR_BP3, + CSR_WP0, CSR_WP1, CSR_WP2, CSR_WP3, +}; + /* processor registers */ static int parse_csr(const char *csr) { @@ -285,6 +286,8 @@ static void wcsr(char *csr, char *value) } } +#endif /* __lm32__ */ + static void dfs(char *baseaddr) { char *c; @@ -312,8 +315,10 @@ static void help(void) puts("mw - write address space"); puts("mc - copy address space"); puts("crc - compute CRC32 of a part of the address space"); +#ifdef __lm32__ puts("rcsr - read processor CSR"); puts("wcsr - write processor CSR"); +#endif #ifdef MINIMAC_BASE puts("netboot - boot via TFTP"); #endif @@ -364,8 +369,10 @@ static void do_command(char *c) else if(strcmp(token, "help") == 0) help(); +#ifdef __lm32__ else if(strcmp(token, "rcsr") == 0) rcsr(get_token(&c)); else if(strcmp(token, "wcsr") == 0) wcsr(get_token(&c), get_token(&c)); +#endif #ifdef DFII_BASE else if(strcmp(token, "ddrrow") == 0) ddrrow(get_token(&c)); diff --git a/software/bios/sdram.c b/software/bios/sdram.c index 92e18635..afa72864 100644 --- a/software/bios/sdram.c +++ b/software/bios/sdram.c @@ -13,7 +13,13 @@ static void cdelay(int i) { while(i > 0) { +#if defined (__lm32__) __asm__ volatile("nop"); +#elif defined (__or1k__) + __asm__ volatile("l.nop"); +#else +#error Unsupported architecture +#endif i--; } } diff --git a/software/common.mak b/software/common.mak index 761982ec..332da825 100644 --- a/software/common.mak +++ b/software/common.mak @@ -1,4 +1,5 @@ -TARGET_PREFIX=lm32-elf- +include $(MSCDIR)/software/include/generated/cpu.mak +TARGET_PREFIX=$(CPU)-elf- RM ?= rm -f @@ -41,8 +42,7 @@ endif # Toolchain options # INCLUDES = -I$(MSCDIR)/software/include/base -I$(MSCDIR)/software/include -I$(MSCDIR)/common -COMMONFLAGS = -Os -mbarrel-shift-enabled -mmultiply-enabled -mdivide-enabled -msign-extend-enabled \ - -Wall -fno-builtin -nostdinc -DMSC_GIT_ID=$(MSC_GIT_ID) $(INCLUDES) +COMMONFLAGS = -Os $(CPUFLAGS) -Wall -fno-builtin -nostdinc -DMSC_GIT_ID=$(MSC_GIT_ID) $(INCLUDES) CFLAGS = $(COMMONFLAGS) -Wstrict-prototypes -Wold-style-definition -Wmissing-prototypes CXXFLAGS = $(COMMONFLAGS) -fno-exceptions -ffreestanding LDFLAGS = -nostdlib -nodefaultlibs -L$(MSCDIR)/software/include @@ -71,5 +71,5 @@ $(CC) -c $(CFLAGS) $(1) $< -o $*.o endef define assemble -$(AS) -o $*.o $< +$(CC) -c $(CFLAGS) -o $*.o $< endef diff --git a/software/include/base/irq.h b/software/include/base/irq.h index 504f2972..54da2f04 100644 --- a/software/include/base/irq.h +++ b/software/include/base/irq.h @@ -5,35 +5,72 @@ extern "C" { #endif +#ifdef __or1k__ +#include +#endif + static inline unsigned int irq_getie(void) { - unsigned int ie; - __asm__ __volatile__("rcsr %0, IE" : "=r" (ie)); - return ie; +#if defined (__lm32__) + unsigned int ie; + __asm__ __volatile__("rcsr %0, IE" : "=r" (ie)); + return ie; +#elif defined (__or1k__) + return !!(mfspr(SPR_SR) & SPR_SR_IEE); +#else +#error Unsupported architecture +#endif } static inline void irq_setie(unsigned int ie) { - __asm__ __volatile__("wcsr IE, %0" : : "r" (ie)); +#if defined (__lm32__) + __asm__ __volatile__("wcsr IE, %0" : : "r" (ie)); +#elif defined (__or1k__) + if (ie & 0x1) + mtspr(SPR_SR, mfspr(SPR_SR) | SPR_SR_IEE); + else + mtspr(SPR_SR, mfspr(SPR_SR) & ~SPR_SR_IEE); +#else +#error Unsupported architecture +#endif } static inline unsigned int irq_getmask(void) { - unsigned int mask; - __asm__ __volatile__("rcsr %0, IM" : "=r" (mask)); - return mask; +#if defined (__lm32__) + unsigned int mask; + __asm__ __volatile__("rcsr %0, IM" : "=r" (mask)); + return mask; +#elif defined (__or1k__) + return mfspr(SPR_PICMR); +#else +#error Unsupported architecture +#endif } static inline void irq_setmask(unsigned int mask) { - __asm__ __volatile__("wcsr IM, %0" : : "r" (mask)); +#if defined (__lm32__) + __asm__ __volatile__("wcsr IM, %0" : : "r" (mask)); +#elif defined (__or1k__) + mtspr(SPR_PICMR, mask); +#else +#error Unsupported architecture +#endif } static inline unsigned int irq_pending(void) { - unsigned int pending; - __asm__ __volatile__("rcsr %0, IP" : "=r" (pending)); - return pending; +#if defined (__lm32__) + unsigned int pending; + __asm__ __volatile__("rcsr %0, IP" : "=r" (pending)); + return pending; +#elif defined (__or1k__) + return mfspr(SPR_PICSR); +#else +#error Unsupported architecture +#endif } #ifdef __cplusplus diff --git a/software/include/base/spr-defs.h b/software/include/base/spr-defs.h new file mode 100644 index 00000000..e073a506 --- /dev/null +++ b/software/include/base/spr-defs.h @@ -0,0 +1,696 @@ +/* spr-defs.h - Special purpose registers definitions file + + Copyright (C) 2000 Damjan Lampret + Copyright (C) 2008, 2010 Embecosm Limited + + Contributor Damjan Lampret + Contributor Jeremy Bennett + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with this program. If not, see . */ + +/* ---------------------------------------------------------------------------- + This code is commented throughout for use with Doxygen. + --------------------------------------------------------------------------*/ +#ifndef SPR_DEFS__H +#define SPR_DEFS__H + +/* Definition of special-purpose registers (SPRs). */ + +#define MAX_GRPS (32) +#define MAX_SPRS_PER_GRP_BITS (11) +#define MAX_SPRS_PER_GRP (1 << MAX_SPRS_PER_GRP_BITS) +#define MAX_SPRS (0x10000) + +/* Base addresses for the groups */ +#define SPRGROUP_SYS (0<< MAX_SPRS_PER_GRP_BITS) +#define SPRGROUP_DMMU (1<< MAX_SPRS_PER_GRP_BITS) +#define SPRGROUP_IMMU (2<< MAX_SPRS_PER_GRP_BITS) +#define SPRGROUP_DC (3<< MAX_SPRS_PER_GRP_BITS) +#define SPRGROUP_IC (4<< MAX_SPRS_PER_GRP_BITS) +#define SPRGROUP_MAC (5<< MAX_SPRS_PER_GRP_BITS) +#define SPRGROUP_D (6<< MAX_SPRS_PER_GRP_BITS) +#define SPRGROUP_PC (7<< MAX_SPRS_PER_GRP_BITS) +#define SPRGROUP_PM (8<< MAX_SPRS_PER_GRP_BITS) +#define SPRGROUP_PIC (9<< MAX_SPRS_PER_GRP_BITS) +#define SPRGROUP_TT (10<< MAX_SPRS_PER_GRP_BITS) +#define SPRGROUP_FP (11<< MAX_SPRS_PER_GRP_BITS) + +/* System control and status group */ +#define SPR_VR (SPRGROUP_SYS + 0) +#define SPR_UPR (SPRGROUP_SYS + 1) +#define SPR_CPUCFGR (SPRGROUP_SYS + 2) +#define SPR_DMMUCFGR (SPRGROUP_SYS + 3) +#define SPR_IMMUCFGR (SPRGROUP_SYS + 4) +#define SPR_DCCFGR (SPRGROUP_SYS + 5) +#define SPR_ICCFGR (SPRGROUP_SYS + 6) +#define SPR_DCFGR (SPRGROUP_SYS + 7) +#define SPR_PCCFGR (SPRGROUP_SYS + 8) +#define SPR_VR2 (SPRGROUP_SYS + 9) +#define SPR_AVR (SPRGROUP_SYS + 10) +#define SPR_EVBAR (SPRGROUP_SYS + 11) +#define SPR_AECR (SPRGROUP_SYS + 12) +#define SPR_AESR (SPRGROUP_SYS + 13) +#define SPR_NPC (SPRGROUP_SYS + 16) /* CZ 21/06/01 */ +#define SPR_SR (SPRGROUP_SYS + 17) /* CZ 21/06/01 */ +#define SPR_PPC (SPRGROUP_SYS + 18) /* CZ 21/06/01 */ +#define SPR_FPCSR (SPRGROUP_SYS + 20) /* CZ 21/06/01 */ +#define SPR_ISR_BASE (SPRGROUP_SYS + 21) +#define SPR_EPCR_BASE (SPRGROUP_SYS + 32) /* CZ 21/06/01 */ +#define SPR_EPCR_LAST (SPRGROUP_SYS + 47) /* CZ 21/06/01 */ +#define SPR_EEAR_BASE (SPRGROUP_SYS + 48) +#define SPR_EEAR_LAST (SPRGROUP_SYS + 63) +#define SPR_ESR_BASE (SPRGROUP_SYS + 64) +#define SPR_ESR_LAST (SPRGROUP_SYS + 79) +#define SPR_GPR_BASE (SPRGROUP_SYS + 1024) + +/* Data MMU group */ +#define SPR_DMMUCR (SPRGROUP_DMMU + 0) +#define SPR_DTLBEIR (SPRGROUP_DMMU + 2) +#define SPR_DTLBMR_BASE(WAY) (SPRGROUP_DMMU + 0x200 + (WAY) * 0x100) +#define SPR_DTLBMR_LAST(WAY) (SPRGROUP_DMMU + 0x27f + (WAY) * 0x100) +#define SPR_DTLBTR_BASE(WAY) (SPRGROUP_DMMU + 0x280 + (WAY) * 0x100) +#define SPR_DTLBTR_LAST(WAY) (SPRGROUP_DMMU + 0x2ff + (WAY) * 0x100) + +/* Instruction MMU group */ +#define SPR_IMMUCR (SPRGROUP_IMMU + 0) +#define SPR_ITLBEIR (SPRGROUP_IMMU + 2) +#define SPR_ITLBMR_BASE(WAY) (SPRGROUP_IMMU + 0x200 + (WAY) * 0x100) +#define SPR_ITLBMR_LAST(WAY) (SPRGROUP_IMMU + 0x27f + (WAY) * 0x100) +#define SPR_ITLBTR_BASE(WAY) (SPRGROUP_IMMU + 0x280 + (WAY) * 0x100) +#define SPR_ITLBTR_LAST(WAY) (SPRGROUP_IMMU + 0x2ff + (WAY) * 0x100) + +/* Data cache group */ +#define SPR_DCCR (SPRGROUP_DC + 0) +#define SPR_DCBPR (SPRGROUP_DC + 1) +#define SPR_DCBFR (SPRGROUP_DC + 2) +#define SPR_DCBIR (SPRGROUP_DC + 3) +#define SPR_DCBWR (SPRGROUP_DC + 4) +#define SPR_DCBLR (SPRGROUP_DC + 5) +#define SPR_DCR_BASE(WAY) (SPRGROUP_DC + 0x200 + (WAY) * 0x200) +#define SPR_DCR_LAST(WAY) (SPRGROUP_DC + 0x3ff + (WAY) * 0x200) + +/* Instruction cache group */ +#define SPR_ICCR (SPRGROUP_IC + 0) +#define SPR_ICBPR (SPRGROUP_IC + 1) +#define SPR_ICBIR (SPRGROUP_IC + 2) +#define SPR_ICBLR (SPRGROUP_IC + 3) +#define SPR_ICR_BASE(WAY) (SPRGROUP_IC + 0x200 + (WAY) * 0x200) +#define SPR_ICR_LAST(WAY) (SPRGROUP_IC + 0x3ff + (WAY) * 0x200) + +/* MAC group */ +#define SPR_MACLO (SPRGROUP_MAC + 1) +#define SPR_MACHI (SPRGROUP_MAC + 2) + +/* Debug group */ +#define SPR_DVR(N) (SPRGROUP_D + (N)) +#define SPR_DCR(N) (SPRGROUP_D + 8 + (N)) +#define SPR_DMR1 (SPRGROUP_D + 16) +#define SPR_DMR2 (SPRGROUP_D + 17) +#define SPR_DWCR0 (SPRGROUP_D + 18) +#define SPR_DWCR1 (SPRGROUP_D + 19) +#define SPR_DSR (SPRGROUP_D + 20) +#define SPR_DRR (SPRGROUP_D + 21) + +/* Performance counters group */ +#define SPR_PCCR(N) (SPRGROUP_PC + (N)) +#define SPR_PCMR(N) (SPRGROUP_PC + 8 + (N)) + +/* Power management group */ +#define SPR_PMR (SPRGROUP_PM + 0) + +/* PIC group */ +#define SPR_PICMR (SPRGROUP_PIC + 0) +#define SPR_PICPR (SPRGROUP_PIC + 1) +#define SPR_PICSR (SPRGROUP_PIC + 2) + +/* Tick Timer group */ +#define SPR_TTMR (SPRGROUP_TT + 0) +#define SPR_TTCR (SPRGROUP_TT + 1) + +/* + * Bit definitions for the Version Register + * + */ +#define SPR_VR_VER 0xff000000 /* Processor version */ +#define SPR_VR_CFG 0x00ff0000 /* Processor configuration */ +#define SPR_VR_RES 0x0000ff80 /* Reserved */ +#define SPR_VR_UVRP 0x00000040 /* Updated version register present */ +#define SPR_VR_REV 0x0000003f /* Processor revision */ + +#define SPR_VR_VER_OFF 24 +#define SPR_VR_CFG_OFF 16 +#define SPR_VR_UVRP_OFF 6 +#define SPR_VR_REV_OFF 0 + +/* + * Bit definitions for the Unit Present Register + * + */ +#define SPR_UPR_UP 0x00000001 /* UPR present */ +#define SPR_UPR_DCP 0x00000002 /* Data cache present */ +#define SPR_UPR_ICP 0x00000004 /* Instruction cache present */ +#define SPR_UPR_DMP 0x00000008 /* Data MMU present */ +#define SPR_UPR_IMP 0x00000010 /* Instruction MMU present */ +#define SPR_UPR_MP 0x00000020 /* MAC present */ +#define SPR_UPR_DUP 0x00000040 /* Debug unit present */ +#define SPR_UPR_PCUP 0x00000080 /* Performance counters unit present */ +#define SPR_UPR_PMP 0x00000100 /* Power management present */ +#define SPR_UPR_PICP 0x00000200 /* PIC present */ +#define SPR_UPR_TTP 0x00000400 /* Tick timer present */ +#define SPR_UPR_RES 0x00fe0000 /* Reserved */ +#define SPR_UPR_CUP 0xff000000 /* Context units present */ + +/* + * JPB: Bit definitions for the CPU configuration register + * + */ +#define SPR_CPUCFGR_NSGF 0x0000000f /* Number of shadow GPR files */ +#define SPR_CPUCFGR_CGF 0x00000010 /* Custom GPR file */ +#define SPR_CPUCFGR_OB32S 0x00000020 /* ORBIS32 supported */ +#define SPR_CPUCFGR_OB64S 0x00000040 /* ORBIS64 supported */ +#define SPR_CPUCFGR_OF32S 0x00000080 /* ORFPX32 supported */ +#define SPR_CPUCFGR_OF64S 0x00000100 /* ORFPX64 supported */ +#define SPR_CPUCFGR_OV64S 0x00000200 /* ORVDX64 supported */ +#define SPR_CPUCFGR_ND 0x00000400 /* No delay-slot */ +#define SPR_CPUCFGR_AVRP 0x00000800 /* Architecture version register present */ +#define SPR_CPUCFGR_EVBARP 0x00001000 /* Exception vector base address register + present */ +#define SPR_CPUCFGR_ISRP 0x00002000 /* Implementation-specific registers present */ +#define SPR_CPUCFGR_AECSRP 0x00004000 /* Arithmetic exception control/status + registers present */ +#define SPR_CPUCFGR_RES 0xffff8000 /* Reserved */ + +/* + * Bit definitions for the Version Register 2 + * + */ +#define SPR_VR2_CPUID 0xff000000 /* Unique CPU identifier */ +#define SPR_VR2_VER 0x00ffffff /* Version */ + +#define SPR_VR2_CPUID_OFF 24 +#define SPR_VR2_VER_OFF 0 + +#define SPR_VR2_CPUID_OR1KSIM 0x00 +#define SPR_VR2_CPUID_MOR1KX 0x01 +#define SPR_VR2_CPUID_OR1200 0x12 +#define SPR_VR2_CPUID_ALTOR32 0x32 +#define SPR_VR2_CPUID_OR10 0x10 + + +/* + * Bit definitions for the Architecture Version register + * + */ +#define SPR_AVR_MAJ 0xff000000 /* Major architecture version number */ +#define SPR_AVR_MIN 0x00ff0000 /* Minor architecture version number */ +#define SPR_AVR_REV 0x0000ff00 /* Architecture revision number */ +#define SPR_AVR_RES 0x000000ff /* Reserved */ + +#define SPR_AVR_MAJ_OFF 24 +#define SPR_AVR_MIN_OFF 16 +#define SPR_AVR_REV_OFF 8 + +/* + * Bit definitions for the Exception Base Address register + * + */ +#define SPR_EVBAR_EVBA 0xffffe000 /* Exception vector base address */ +#define SPR_EVBAR_RES 0x00001fff /* Reserved */ + +#define SPR_EVBAR_EVBA_OFF 13 + +/* + * Bit definitions for the Arithmetic Exception Control register + * + */ +#define SPR_AECR_CYADDE 0x00000001 /* Carry on add/subtract exception */ +#define SPR_AECR_OVADDE 0x00000002 /* Overflow on add/subtract exception */ +#define SPR_AECR_CYMULE 0x00000004 /* Carry on multiply exception */ +#define SPR_AECR_OVMULE 0x00000008 /* Overflow on multiply exception */ +#define SPR_AECR_DBZE 0x00000010 /* Divide by zero exception */ +#define SPR_AECR_CYMACADDE 0x00000020 /* Carry on MAC add/subtract exception */ +#define SPR_AECR_OVMACADDE 0x00000040 /* Overflow on MAC add/subtract exception */ + +#define SPR_AECR_CYADDE_OFF 0 +#define SPR_AECR_OVADDE_OFF 1 +#define SPR_AECR_CYMULE_OFF 2 +#define SPR_AECR_OVMULE_OFF 3 +#define SPR_AECR_DBZE_OFF 4 +#define SPR_AECR_CYMACADDE_OFF 5 +#define SPR_AECR_OVMACADDE_OFF 6 + + +/* + * Bit definitions for the Arithmetic Exception Status register + * + */ +#define SPR_AESR_CYADDE 0x00000001 /* Carry on add/subtract exception */ +#define SPR_AESR_OVADDE 0x00000002 /* Overflow on add/subtract exception */ +#define SPR_AESR_CYMULE 0x00000004 /* Carry on multiply exception */ +#define SPR_AESR_OVMULE 0x00000008 /* Overflow on multiply exception */ +#define SPR_AESR_DBZE 0x00000010 /* Divide by zero exception */ +#define SPR_AESR_CYMACADDE 0x00000020 /* Carry on MAC add/subtract exception */ +#define SPR_AESR_OVMACADDE 0x00000040 /* Overflow on MAC add/subtract exception */ + +#define SPR_AESR_CYADDE_OFF 0 +#define SPR_AESR_OVADDE_OFF 1 +#define SPR_AESR_CYMULE_OFF 2 +#define SPR_AESR_OVMULE_OFF 3 +#define SPR_AESR_DBZE_OFF 4 +#define SPR_AESR_CYMACADDE_OFF 5 +#define SPR_AESR_OVMACADDE_OFF 6 + +/* + * JPB: Bit definitions for the Debug configuration register and other + * constants. + * + */ + +#define SPR_DCFGR_NDP 0x00000007 /* Number of matchpoints mask */ +#define SPR_DCFGR_NDP1 0x00000000 /* One matchpoint supported */ +#define SPR_DCFGR_NDP2 0x00000001 /* Two matchpoints supported */ +#define SPR_DCFGR_NDP3 0x00000002 /* Three matchpoints supported */ +#define SPR_DCFGR_NDP4 0x00000003 /* Four matchpoints supported */ +#define SPR_DCFGR_NDP5 0x00000004 /* Five matchpoints supported */ +#define SPR_DCFGR_NDP6 0x00000005 /* Six matchpoints supported */ +#define SPR_DCFGR_NDP7 0x00000006 /* Seven matchpoints supported */ +#define SPR_DCFGR_NDP8 0x00000007 /* Eight matchpoints supported */ +#define SPR_DCFGR_WPCI 0x00000008 /* Watchpoint counters implemented */ + +#define MATCHPOINTS_TO_NDP(n) (1 == n ? SPR_DCFGR_NDP1 : \ + 2 == n ? SPR_DCFGR_NDP2 : \ + 3 == n ? SPR_DCFGR_NDP3 : \ + 4 == n ? SPR_DCFGR_NDP4 : \ + 5 == n ? SPR_DCFGR_NDP5 : \ + 6 == n ? SPR_DCFGR_NDP6 : \ + 7 == n ? SPR_DCFGR_NDP7 : SPR_DCFGR_NDP8) +#define MAX_MATCHPOINTS 8 +#define MAX_WATCHPOINTS (MAX_MATCHPOINTS + 2) + +/* + * Bit definitions for the Supervision Register + * + */ +#define SPR_SR_SM 0x00000001 /* Supervisor Mode */ +#define SPR_SR_TEE 0x00000002 /* Tick timer Exception Enable */ +#define SPR_SR_IEE 0x00000004 /* Interrupt Exception Enable */ +#define SPR_SR_DCE 0x00000008 /* Data Cache Enable */ +#define SPR_SR_ICE 0x00000010 /* Instruction Cache Enable */ +#define SPR_SR_DME 0x00000020 /* Data MMU Enable */ +#define SPR_SR_IME 0x00000040 /* Instruction MMU Enable */ +#define SPR_SR_LEE 0x00000080 /* Little Endian Enable */ +#define SPR_SR_CE 0x00000100 /* CID Enable */ +#define SPR_SR_F 0x00000200 /* Condition Flag */ +#define SPR_SR_CY 0x00000400 /* Carry flag */ +#define SPR_SR_OV 0x00000800 /* Overflow flag */ +#define SPR_SR_OVE 0x00001000 /* Overflow flag Exception */ +#define SPR_SR_DSX 0x00002000 /* Delay Slot Exception */ +#define SPR_SR_EPH 0x00004000 /* Exception Prefix High */ +#define SPR_SR_FO 0x00008000 /* Fixed one */ +#define SPR_SR_SUMRA 0x00010000 /* Supervisor SPR read access */ +#define SPR_SR_RES 0x0ffe0000 /* Reserved */ +#define SPR_SR_CID 0xf0000000 /* Context ID */ + +/* + * Bit definitions for the Data MMU Control Register + * + */ +#define SPR_DMMUCR_P2S 0x0000003e /* Level 2 Page Size */ +#define SPR_DMMUCR_P1S 0x000007c0 /* Level 1 Page Size */ +#define SPR_DMMUCR_VADDR_WIDTH 0x0000f800 /* Virtual ADDR Width */ +#define SPR_DMMUCR_PADDR_WIDTH 0x000f0000 /* Physical ADDR Width */ + +/* + * Bit definitions for the Instruction MMU Control Register + * + */ +#define SPR_IMMUCR_P2S 0x0000003e /* Level 2 Page Size */ +#define SPR_IMMUCR_P1S 0x000007c0 /* Level 1 Page Size */ +#define SPR_IMMUCR_VADDR_WIDTH 0x0000f800 /* Virtual ADDR Width */ +#define SPR_IMMUCR_PADDR_WIDTH 0x000f0000 /* Physical ADDR Width */ + +/* + * Bit definitions for the Data TLB Match Register + * + */ +#define SPR_DTLBMR_V 0x00000001 /* Valid */ +#define SPR_DTLBMR_PL1 0x00000002 /* Page Level 1 (if 0 then PL2) */ +#define SPR_DTLBMR_CID 0x0000003c /* Context ID */ +#define SPR_DTLBMR_LRU 0x000000c0 /* Least Recently Used */ +#define SPR_DTLBMR_VPN 0xffffe000 /* Virtual Page Number */ + +/* + * Bit definitions for the Data TLB Translate Register + * + */ +#define SPR_DTLBTR_CC 0x00000001 /* Cache Coherency */ +#define SPR_DTLBTR_CI 0x00000002 /* Cache Inhibit */ +#define SPR_DTLBTR_WBC 0x00000004 /* Write-Back Cache */ +#define SPR_DTLBTR_WOM 0x00000008 /* Weakly-Ordered Memory */ +#define SPR_DTLBTR_A 0x00000010 /* Accessed */ +#define SPR_DTLBTR_D 0x00000020 /* Dirty */ +#define SPR_DTLBTR_URE 0x00000040 /* User Read Enable */ +#define SPR_DTLBTR_UWE 0x00000080 /* User Write Enable */ +#define SPR_DTLBTR_SRE 0x00000100 /* Supervisor Read Enable */ +#define SPR_DTLBTR_SWE 0x00000200 /* Supervisor Write Enable */ +#define SPR_DTLBTR_PPN 0xffffe000 /* Physical Page Number */ + +#define DTLB_PR_NOLIMIT ( SPR_DTLBTR_URE | \ + SPR_DTLBTR_UWE | \ + SPR_DTLBTR_SRE | \ + SPR_DTLBTR_SWE ) + +/* + * Bit definitions for the Instruction TLB Match Register + * + */ +#define SPR_ITLBMR_V 0x00000001 /* Valid */ +#define SPR_ITLBMR_PL1 0x00000002 /* Page Level 1 (if 0 then PL2) */ +#define SPR_ITLBMR_CID 0x0000003c /* Context ID */ +#define SPR_ITLBMR_LRU 0x000000c0 /* Least Recently Used */ +#define SPR_ITLBMR_VPN 0xffffe000 /* Virtual Page Number */ + +/* + * Bit definitions for the Instruction TLB Translate Register + * + */ +#define SPR_ITLBTR_CC 0x00000001 /* Cache Coherency */ +#define SPR_ITLBTR_CI 0x00000002 /* Cache Inhibit */ +#define SPR_ITLBTR_WBC 0x00000004 /* Write-Back Cache */ +#define SPR_ITLBTR_WOM 0x00000008 /* Weakly-Ordered Memory */ +#define SPR_ITLBTR_A 0x00000010 /* Accessed */ +#define SPR_ITLBTR_D 0x00000020 /* Dirty */ +#define SPR_ITLBTR_SXE 0x00000040 /* User Read Enable */ +#define SPR_ITLBTR_UXE 0x00000080 /* User Write Enable */ +#define SPR_ITLBTR_PPN 0xffffe000 /* Physical Page Number */ + +#define ITLB_PR_NOLIMIT ( SPR_ITLBTR_SXE | \ + SPR_ITLBTR_UXE ) + + +/* + * Bit definitions for Data Cache Control register + * + */ +#define SPR_DCCR_EW 0x000000ff /* Enable ways */ + +/* + * Bit definitions for Insn Cache Control register + * + */ +#define SPR_ICCR_EW 0x000000ff /* Enable ways */ + +/* + * Bit definitions for Data Cache Configuration Register + * + */ + +#define SPR_DCCFGR_NCW 0x00000007 +#define SPR_DCCFGR_NCS 0x00000078 +#define SPR_DCCFGR_CBS 0x00000080 +#define SPR_DCCFGR_CWS 0x00000100 +#define SPR_DCCFGR_CCRI 0x00000200 +#define SPR_DCCFGR_CBIRI 0x00000400 +#define SPR_DCCFGR_CBPRI 0x00000800 +#define SPR_DCCFGR_CBLRI 0x00001000 +#define SPR_DCCFGR_CBFRI 0x00002000 +#define SPR_DCCFGR_CBWBRI 0x00004000 + +#define SPR_DCCFGR_NCW_OFF 0 +#define SPR_DCCFGR_NCS_OFF 3 +#define SPR_DCCFGR_CBS_OFF 7 + +/* + * Bit definitions for Instruction Cache Configuration Register + * + */ +#define SPR_ICCFGR_NCW 0x00000007 +#define SPR_ICCFGR_NCS 0x00000078 +#define SPR_ICCFGR_CBS 0x00000080 +#define SPR_ICCFGR_CCRI 0x00000200 +#define SPR_ICCFGR_CBIRI 0x00000400 +#define SPR_ICCFGR_CBPRI 0x00000800 +#define SPR_ICCFGR_CBLRI 0x00001000 + +#define SPR_ICCFGR_NCW_OFF 0 +#define SPR_ICCFGR_NCS_OFF 3 +#define SPR_ICCFGR_CBS_OFF 7 + +/* + * Bit definitions for Data MMU Configuration Register + * + */ + +#define SPR_DMMUCFGR_NTW 0x00000003 +#define SPR_DMMUCFGR_NTS 0x0000001C +#define SPR_DMMUCFGR_NAE 0x000000E0 +#define SPR_DMMUCFGR_CRI 0x00000100 +#define SPR_DMMUCFGR_PRI 0x00000200 +#define SPR_DMMUCFGR_TEIRI 0x00000400 +#define SPR_DMMUCFGR_HTR 0x00000800 + +#define SPR_DMMUCFGR_NTW_OFF 0 +#define SPR_DMMUCFGR_NTS_OFF 2 + +/* + * Bit definitions for Instruction MMU Configuration Register + * + */ + +#define SPR_IMMUCFGR_NTW 0x00000003 +#define SPR_IMMUCFGR_NTS 0x0000001C +#define SPR_IMMUCFGR_NAE 0x000000E0 +#define SPR_IMMUCFGR_CRI 0x00000100 +#define SPR_IMMUCFGR_PRI 0x00000200 +#define SPR_IMMUCFGR_TEIRI 0x00000400 +#define SPR_IMMUCFGR_HTR 0x00000800 + +#define SPR_IMMUCFGR_NTW_OFF 0 +#define SPR_IMMUCFGR_NTS_OFF 2 + +/* + * Bit definitions for Debug Control registers + * + */ +#define SPR_DCR_DP 0x00000001 /* DVR/DCR present */ +#define SPR_DCR_CC 0x0000000e /* Compare condition */ +#define SPR_DCR_SC 0x00000010 /* Signed compare */ +#define SPR_DCR_CT 0x000000e0 /* Compare to */ + +/* Bit results with SPR_DCR_CC mask */ +#define SPR_DCR_CC_MASKED 0x00000000 +#define SPR_DCR_CC_EQUAL 0x00000002 +#define SPR_DCR_CC_LESS 0x00000004 +#define SPR_DCR_CC_LESSE 0x00000006 +#define SPR_DCR_CC_GREAT 0x00000008 +#define SPR_DCR_CC_GREATE 0x0000000a +#define SPR_DCR_CC_NEQUAL 0x0000000c + +/* Bit results with SPR_DCR_CT mask */ +#define SPR_DCR_CT_DISABLED 0x00000000 +#define SPR_DCR_CT_IFEA 0x00000020 +#define SPR_DCR_CT_LEA 0x00000040 +#define SPR_DCR_CT_SEA 0x00000060 +#define SPR_DCR_CT_LD 0x00000080 +#define SPR_DCR_CT_SD 0x000000a0 +#define SPR_DCR_CT_LSEA 0x000000c0 +#define SPR_DCR_CT_LSD 0x000000e0 +/* SPR_DCR_CT_LSD doesn't seem to be implemented anywhere in or1ksim. 2004-1-30 HP */ + +/* + * Bit definitions for Debug Mode 1 register + * + */ +#define SPR_DMR1_CW 0x000fffff /* Chain register pair data */ +#define SPR_DMR1_CW0_AND 0x00000001 +#define SPR_DMR1_CW0_OR 0x00000002 +#define SPR_DMR1_CW0 (SPR_DMR1_CW0_AND | SPR_DMR1_CW0_OR) +#define SPR_DMR1_CW1_AND 0x00000004 +#define SPR_DMR1_CW1_OR 0x00000008 +#define SPR_DMR1_CW1 (SPR_DMR1_CW1_AND | SPR_DMR1_CW1_OR) +#define SPR_DMR1_CW2_AND 0x00000010 +#define SPR_DMR1_CW2_OR 0x00000020 +#define SPR_DMR1_CW2 (SPR_DMR1_CW2_AND | SPR_DMR1_CW2_OR) +#define SPR_DMR1_CW3_AND 0x00000040 +#define SPR_DMR1_CW3_OR 0x00000080 +#define SPR_DMR1_CW3 (SPR_DMR1_CW3_AND | SPR_DMR1_CW3_OR) +#define SPR_DMR1_CW4_AND 0x00000100 +#define SPR_DMR1_CW4_OR 0x00000200 +#define SPR_DMR1_CW4 (SPR_DMR1_CW4_AND | SPR_DMR1_CW4_OR) +#define SPR_DMR1_CW5_AND 0x00000400 +#define SPR_DMR1_CW5_OR 0x00000800 +#define SPR_DMR1_CW5 (SPR_DMR1_CW5_AND | SPR_DMR1_CW5_OR) +#define SPR_DMR1_CW6_AND 0x00001000 +#define SPR_DMR1_CW6_OR 0x00002000 +#define SPR_DMR1_CW6 (SPR_DMR1_CW6_AND | SPR_DMR1_CW6_OR) +#define SPR_DMR1_CW7_AND 0x00004000 +#define SPR_DMR1_CW7_OR 0x00008000 +#define SPR_DMR1_CW7 (SPR_DMR1_CW7_AND | SPR_DMR1_CW7_OR) +#define SPR_DMR1_CW8_AND 0x00010000 +#define SPR_DMR1_CW8_OR 0x00020000 +#define SPR_DMR1_CW8 (SPR_DMR1_CW8_AND | SPR_DMR1_CW8_OR) +#define SPR_DMR1_CW9_AND 0x00040000 +#define SPR_DMR1_CW9_OR 0x00080000 +#define SPR_DMR1_CW9 (SPR_DMR1_CW9_AND | SPR_DMR1_CW9_OR) +#define SPR_DMR1_RES1 0x00300000 /* Reserved */ +#define SPR_DMR1_ST 0x00400000 /* Single-step trace*/ +#define SPR_DMR1_BT 0x00800000 /* Branch trace */ +#define SPR_DMR1_RES2 0xff000000 /* Reserved */ + +/* + * Bit definitions for Debug Mode 2 register. AWTC and WGB corrected by JPB + * + */ +#define SPR_DMR2_WCE0 0x00000001 /* Watchpoint counter 0 enable */ +#define SPR_DMR2_WCE1 0x00000002 /* Watchpoint counter 0 enable */ +#define SPR_DMR2_AWTC 0x00000ffc /* Assign watchpoints to counters */ +#define SPR_DMR2_AWTC_OFF 2 /* Bit offset to AWTC field */ +#define SPR_DMR2_WGB 0x003ff000 /* Watchpoints generating breakpoint */ +#define SPR_DMR2_WGB_OFF 12 /* Bit offset to WGB field */ +#define SPR_DMR2_WBS 0xffc00000 /* JPB: Watchpoint status */ +#define SPR_DMR2_WBS_OFF 22 /* Bit offset to WBS field */ + +/* + * Bit definitions for Debug watchpoint counter registers + * + */ +#define SPR_DWCR_COUNT 0x0000ffff /* Count */ +#define SPR_DWCR_MATCH 0xffff0000 /* Match */ +#define SPR_DWCR_MATCH_OFF 16 /* Match bit offset */ + +/* + * Bit definitions for Debug stop register + * + */ +#define SPR_DSR_RSTE 0x00000001 /* Reset exception */ +#define SPR_DSR_BUSEE 0x00000002 /* Bus error exception */ +#define SPR_DSR_DPFE 0x00000004 /* Data Page Fault exception */ +#define SPR_DSR_IPFE 0x00000008 /* Insn Page Fault exception */ +#define SPR_DSR_TTE 0x00000010 /* Tick Timer exception */ +#define SPR_DSR_AE 0x00000020 /* Alignment exception */ +#define SPR_DSR_IIE 0x00000040 /* Illegal Instruction exception */ +#define SPR_DSR_IE 0x00000080 /* Interrupt exception */ +#define SPR_DSR_DME 0x00000100 /* DTLB miss exception */ +#define SPR_DSR_IME 0x00000200 /* ITLB miss exception */ +#define SPR_DSR_RE 0x00000400 /* Range exception */ +#define SPR_DSR_SCE 0x00000800 /* System call exception */ +#define SPR_DSR_FPE 0x00001000 /* Floating Point Exception */ +#define SPR_DSR_TE 0x00002000 /* Trap exception */ + +/* + * Bit definitions for Debug reason register + * + */ +#define SPR_DRR_RSTE 0x00000001 /* Reset exception */ +#define SPR_DRR_BUSEE 0x00000002 /* Bus error exception */ +#define SPR_DRR_DPFE 0x00000004 /* Data Page Fault exception */ +#define SPR_DRR_IPFE 0x00000008 /* Insn Page Fault exception */ +#define SPR_DRR_TTE 0x00000010 /* Tick Timer exception */ +#define SPR_DRR_AE 0x00000020 /* Alignment exception */ +#define SPR_DRR_IIE 0x00000040 /* Illegal Instruction exception */ +#define SPR_DRR_IE 0x00000080 /* Interrupt exception */ +#define SPR_DRR_DME 0x00000100 /* DTLB miss exception */ +#define SPR_DRR_IME 0x00000200 /* ITLB miss exception */ +#define SPR_DRR_RE 0x00000400 /* Range exception */ +#define SPR_DRR_SCE 0x00000800 /* System call exception */ +#define SPR_DRR_FPE 0x00001000 /* Floating Point Exception */ +#define SPR_DRR_TE 0x00002000 /* Trap exception */ + +/* + * Bit definitions for Performance counters mode registers + * + */ +#define SPR_PCMR_CP 0x00000001 /* Counter present */ +#define SPR_PCMR_UMRA 0x00000002 /* User mode read access */ +#define SPR_PCMR_CISM 0x00000004 /* Count in supervisor mode */ +#define SPR_PCMR_CIUM 0x00000008 /* Count in user mode */ +#define SPR_PCMR_LA 0x00000010 /* Load access event */ +#define SPR_PCMR_SA 0x00000020 /* Store access event */ +#define SPR_PCMR_IF 0x00000040 /* Instruction fetch event*/ +#define SPR_PCMR_DCM 0x00000080 /* Data cache miss event */ +#define SPR_PCMR_ICM 0x00000100 /* Insn cache miss event */ +#define SPR_PCMR_IFS 0x00000200 /* Insn fetch stall event */ +#define SPR_PCMR_LSUS 0x00000400 /* LSU stall event */ +#define SPR_PCMR_BS 0x00000800 /* Branch stall event */ +#define SPR_PCMR_DTLBM 0x00001000 /* DTLB miss event */ +#define SPR_PCMR_ITLBM 0x00002000 /* ITLB miss event */ +#define SPR_PCMR_DDS 0x00004000 /* Data dependency stall event */ +#define SPR_PCMR_WPE 0x03ff8000 /* Watchpoint events */ + +/* + * Bit definitions for the Power management register + * + */ +#define SPR_PMR_SDF 0x0000000f /* Slow down factor */ +#define SPR_PMR_DME 0x00000010 /* Doze mode enable */ +#define SPR_PMR_SME 0x00000020 /* Sleep mode enable */ +#define SPR_PMR_DCGE 0x00000040 /* Dynamic clock gating enable */ +#define SPR_PMR_SUME 0x00000080 /* Suspend mode enable */ + +/* + * Bit definitions for PICMR + * + */ +#define SPR_PICMR_IUM 0xfffffffc /* Interrupt unmask */ + +/* + * Bit definitions for PICPR + * + */ +#define SPR_PICPR_IPRIO 0xfffffffc /* Interrupt priority */ + +/* + * Bit definitions for PICSR + * + */ +#define SPR_PICSR_IS 0xffffffff /* Interrupt status */ + +/* + * Bit definitions for Tick Timer Control Register + * + */ +#define SPR_TTCR_PERIOD 0x0fffffff /* Time Period */ +#define SPR_TTMR_PERIOD SPR_TTCR_PERIOD +#define SPR_TTMR_IP 0x10000000 /* Interrupt Pending */ +#define SPR_TTMR_IE 0x20000000 /* Interrupt Enable */ +#define SPR_TTMR_RT 0x40000000 /* Restart tick */ +#define SPR_TTMR_SR 0x80000000 /* Single run */ +#define SPR_TTMR_CR 0xc0000000 /* Continuous run */ +#define SPR_TTMR_M 0xc0000000 /* Tick mode */ + +/* + * Bit definitions for the FP Control Status Register + * + */ +#define SPR_FPCSR_FPEE 0x00000001 /* Floating Point Exception Enable */ +#define SPR_FPCSR_RM 0x00000006 /* Rounding Mode */ +#define SPR_FPCSR_OVF 0x00000008 /* Overflow Flag */ +#define SPR_FPCSR_UNF 0x00000010 /* Underflow Flag */ +#define SPR_FPCSR_SNF 0x00000020 /* SNAN Flag */ +#define SPR_FPCSR_QNF 0x00000040 /* QNAN Flag */ +#define SPR_FPCSR_ZF 0x00000080 /* Zero Flag */ +#define SPR_FPCSR_IXF 0x00000100 /* Inexact Flag */ +#define SPR_FPCSR_IVF 0x00000200 /* Invalid Flag */ +#define SPR_FPCSR_INF 0x00000400 /* Infinity Flag */ +#define SPR_FPCSR_DZF 0x00000800 /* Divide By Zero Flag */ +#define SPR_FPCSR_ALLF (SPR_FPCSR_OVF | SPR_FPCSR_UNF | SPR_FPCSR_SNF | \ + SPR_FPCSR_QNF | SPR_FPCSR_ZF | SPR_FPCSR_IXF | \ + SPR_FPCSR_IVF | SPR_FPCSR_INF | SPR_FPCSR_DZF) + +#define FPCSR_RM_RN (0<<1) +#define FPCSR_RM_RZ (1<<1) +#define FPCSR_RM_RIP (2<<1) +#define FPCSR_RM_RIN (3<<1) + +#endif /* SPR_DEFS__H */ diff --git a/software/include/base/system.h b/software/include/base/system.h index 41be80af..014dbf47 100644 --- a/software/include/base/system.h +++ b/software/include/base/system.h @@ -9,6 +9,23 @@ void flush_cpu_icache(void); void flush_cpu_dcache(void); void flush_l2_cache(void); +#ifdef __or1k__ +#include +static inline unsigned long mfspr(unsigned long add) +{ + unsigned long ret; + + __asm__ __volatile__ ("l.mfspr %0,r0,%1" : "=r" (ret) : "K" (add)); + + return ret; +} + +static inline void mtspr(unsigned long add, unsigned long val) +{ + __asm__ __volatile__ ("l.mtspr r0,%1,%0" : : "K" (add), "r" (val)); +} +#endif + #ifdef __cplusplus } #endif diff --git a/software/libbase/Makefile b/software/libbase/Makefile index f8a90b1a..124352c7 100644 --- a/software/libbase/Makefile +++ b/software/libbase/Makefile @@ -1,9 +1,9 @@ MSCDIR=../.. include $(MSCDIR)/software/common.mak -OBJECTS=setjmp.o libc.o errno.o crc16.o crc32.o console.o system.o id.o uart.o time.o qsort.o strtod.o +OBJECTS=setjmp-$(CPU).o libc.o errno.o crc16.o crc32.o console.o system.o id.o uart.o time.o qsort.o strtod.o -all: crt0.o libbase.a libbase-nofloat.a +all: crt0-$(CPU).o libbase.a libbase-nofloat.a # pull in dependency info for *existing* .o files -include $(OBJECTS:.o=.d) diff --git a/software/libbase/crt0.S b/software/libbase/crt0-lm32.S similarity index 100% rename from software/libbase/crt0.S rename to software/libbase/crt0-lm32.S diff --git a/software/libbase/crt0-or1k.S b/software/libbase/crt0-or1k.S new file mode 100644 index 00000000..220e2d3c --- /dev/null +++ b/software/libbase/crt0-or1k.S @@ -0,0 +1,434 @@ +/* + * (C) Copyright 2012, Stefan Kristiansson + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include + +#define EXCEPTION_STACK_SIZE (128+128) + +#define HANDLE_EXCEPTION ; \ + l.addi r1, r1, -EXCEPTION_STACK_SIZE ; \ + l.sw 0x1c(r1), r9 ; \ + l.jal _exception_handler ; \ + l.nop ; \ + l.lwz r9, 0x1c(r1) ; \ + l.addi r1, r1, EXCEPTION_STACK_SIZE ; \ + l.rfe ; \ + l.nop + + +.section .text, "ax", @progbits +.global _start +_start: +_reset_handler: + l.movhi r0, 0 + l.movhi r1, 0 + l.movhi r2, 0 + l.movhi r3, 0 + l.movhi r4, 0 + l.movhi r5, 0 + l.movhi r6, 0 + l.movhi r7, 0 + l.movhi r8, 0 + l.movhi r9, 0 + l.movhi r10, 0 + l.movhi r11, 0 + l.movhi r12, 0 + l.movhi r13, 0 + l.movhi r14, 0 + l.movhi r15, 0 + l.movhi r16, 0 + l.movhi r17, 0 + l.movhi r18, 0 + l.movhi r19, 0 + l.movhi r20, 0 + l.movhi r21, 0 + l.movhi r22, 0 + l.movhi r23, 0 + l.movhi r24, 0 + l.movhi r25, 0 + l.movhi r26, 0 + l.movhi r27, 0 + l.movhi r28, 0 + l.movhi r29, 0 + l.movhi r30, 0 + l.movhi r31, 0 + + l.ori r21, r0, SPR_SR_SM + l.mtspr r0, r21, SPR_SR + l.movhi r21, hi(_reset_handler) + l.ori r21, r21, lo(_reset_handler) + l.mtspr r0, r21, SPR_EVBAR + /* enable caches */ + l.jal _cache_init + l.nop + l.j _crt0 + l.nop + + /* bus error */ + .org 0x200 + HANDLE_EXCEPTION + + /* data page fault */ + .org 0x300 + HANDLE_EXCEPTION + + /* instruction page fault */ + .org 0x400 + HANDLE_EXCEPTION + + /* tick timer */ + .org 0x500 + HANDLE_EXCEPTION + + /* alignment */ + .org 0x600 + HANDLE_EXCEPTION + + /* illegal instruction */ + .org 0x700 + HANDLE_EXCEPTION + + /* external interrupt */ + .org 0x800 + HANDLE_EXCEPTION + + /* D-TLB miss */ + .org 0x900 + HANDLE_EXCEPTION + + /* I-TLB miss */ + .org 0xa00 + HANDLE_EXCEPTION + + /* range */ + .org 0xb00 + HANDLE_EXCEPTION + + /* system call */ + .org 0xc00 + HANDLE_EXCEPTION + + /* floating point */ + .org 0xd00 + HANDLE_EXCEPTION + + /* trap */ + .org 0xe00 + HANDLE_EXCEPTION + + /* reserved */ + .org 0xf00 + HANDLE_EXCEPTION + + /* reserved */ + .org 0x1000 + HANDLE_EXCEPTION + + /* reserved */ + .org 0x1100 + HANDLE_EXCEPTION + + /* reserved */ + .org 0x1200 + HANDLE_EXCEPTION + + /* reserved */ + .org 0x1300 + HANDLE_EXCEPTION + + /* reserved */ + .org 0x1400 + HANDLE_EXCEPTION + + /* reserved */ + .org 0x1500 + HANDLE_EXCEPTION + + /* reserved */ + .org 0x1600 + HANDLE_EXCEPTION + + /* reserved */ + .org 0x1700 + HANDLE_EXCEPTION + + /* reserved */ + .org 0x1800 + HANDLE_EXCEPTION + + /* reserved */ + .org 0x1900 + HANDLE_EXCEPTION + + /* reserved */ + .org 0x1a00 + HANDLE_EXCEPTION + + /* reserved */ + .org 0x1b00 + HANDLE_EXCEPTION + + /* reserved */ + .org 0x1c00 + HANDLE_EXCEPTION + + /* reserved */ + .org 0x1d00 + HANDLE_EXCEPTION + + /* reserved */ + .org 0x1e00 + HANDLE_EXCEPTION + + /* reserved */ + .org 0x1f00 + HANDLE_EXCEPTION + + .org 0x2000 +macaddress: + .byte 0x10 + .byte 0xe2 + .byte 0xd5 + .byte 0x00 + .byte 0x00 + .byte 0x00 + + /* padding to align to a 32-bit boundary */ + .byte 0x00 + .byte 0x00 + +_crt0: + /* Setup stack and global pointer */ + l.movhi r1, hi(_fstack) + l.ori r1, r1, lo(_fstack) +/* + l.movhi r16, hi(_gp) + l.ori r16, gp, lo(_gp) +*/ + + /* Clear BSS */ + l.movhi r21, hi(_fbss) + l.ori r21, r21, lo(_fbss) + l.movhi r3, hi(_ebss) + l.ori r3, r3, lo(_ebss) +.clearBSS: + l.sfeq r21, r3 + l.bf .callMain + l.nop + l.sw 0(r21), r0 + l.addi r21, r21, 4 + l.j .clearBSS + l.nop + +.callMain: + l.j main + l.nop + +_exception_handler: + l.sw 0x00(r1), r2 + l.sw 0x04(r1), r3 + l.sw 0x08(r1), r4 + l.sw 0x0c(r1), r5 + l.sw 0x10(r1), r6 + l.sw 0x14(r1), r7 + l.sw 0x18(r1), r8 + l.sw 0x20(r1), r10 + l.sw 0x24(r1), r11 + l.sw 0x28(r1), r12 + l.sw 0x2c(r1), r13 + l.sw 0x30(r1), r14 + l.sw 0x34(r1), r15 + l.sw 0x38(r1), r16 + l.sw 0x3c(r1), r17 + l.sw 0x40(r1), r18 + l.sw 0x44(r1), r19 + l.sw 0x48(r1), r20 + l.sw 0x4c(r1), r21 + l.sw 0x50(r1), r22 + l.sw 0x54(r1), r23 + l.sw 0x58(r1), r24 + l.sw 0x5c(r1), r25 + l.sw 0x60(r1), r26 + l.sw 0x64(r1), r27 + l.sw 0x68(r1), r28 + l.sw 0x6c(r1), r29 + l.sw 0x70(r1), r30 + l.sw 0x74(r1), r31 + + /* Save return address */ + l.or r14, r0, r9 + /* send stack pointer as argument */ + l.or r4, r0, r1 + /* Call exception handler with the link address as argument */ + l.jal exception_handler + l.or r3, r0, r14 + + /* Load return address */ + l.or r9, r0, r14 + /* Restore state */ + l.lwz r2, 0x00(r1) + l.lwz r3, 0x04(r1) + l.lwz r4, 0x08(r1) + l.lwz r5, 0x0c(r1) + l.lwz r6, 0x10(r1) + l.lwz r7, 0x14(r1) + l.lwz r8, 0x18(r1) + l.lwz r10, 0x20(r1) + l.lwz r11, 0x24(r1) + l.lwz r12, 0x28(r1) + l.lwz r13, 0x2c(r1) + l.lwz r14, 0x30(r1) + l.lwz r15, 0x34(r1) + l.lwz r16, 0x38(r1) + l.lwz r17, 0x3c(r1) + l.lwz r18, 0x40(r1) + l.lwz r19, 0x44(r1) + l.lwz r20, 0x48(r1) + l.lwz r21, 0x4c(r1) + l.lwz r22, 0x50(r1) + l.lwz r23, 0x54(r1) + l.lwz r24, 0x58(r1) + l.lwz r25, 0x5c(r1) + l.lwz r26, 0x60(r1) + l.lwz r27, 0x64(r1) + l.lwz r28, 0x68(r1) + l.lwz r29, 0x6c(r1) + l.lwz r30, 0x70(r1) + l.lwz r31, 0x74(r1) + l.jr r9 + l.nop + +_cache_init: + /* + This function is to be used ONLY during reset, before main() is called. + TODO: Perhaps break into individual enable instruction/data cache + sections functions, and provide disable functions, also, all + callable from C + */ + + /* Instruction cache enable */ + /* Check if IC present and skip enabling otherwise */ +#if 1 +.L6: + l.mfspr r3,r0,SPR_UPR + l.andi r7,r3,SPR_UPR_ICP + l.sfeq r7,r0 + l.bf .L8 + l.nop + + /* Disable IC */ + l.mfspr r6,r0,SPR_SR + l.addi r5,r0,-1 + l.xori r5,r5,SPR_SR_ICE + l.and r5,r6,r5 + l.mtspr r0,r5,SPR_SR + + /* Establish cache block size + If BS=0, 16; + If BS=1, 32; + r14 contain block size + */ + l.mfspr r3,r0,SPR_ICCFGR + l.andi r7,r3,SPR_ICCFGR_CBS + l.srli r8,r7,7 + l.ori r4,r0,16 + l.sll r14,r4,r8 + + /* Establish number of cache sets + r10 contains number of cache sets + r8 contains log(# of cache sets) + */ + l.andi r7,r3,SPR_ICCFGR_NCS + l.srli r8,r7,3 + l.ori r4,r0,1 + l.sll r10,r4,r8 + + /* Invalidate IC */ + l.addi r6,r0,0 + l.sll r5,r14,r8 + +.L7: l.mtspr r0,r6,SPR_ICBIR + l.sfne r6,r5 + l.bf .L7 + l.add r6,r6,r14 + + /* Enable IC */ + l.mfspr r6,r0,SPR_SR + l.ori r6,r6,SPR_SR_ICE + l.mtspr r0,r6,SPR_SR + l.nop + l.nop + l.nop + l.nop + l.nop + l.nop + l.nop + l.nop + /* Data cache enable */ + /* Check if DC present and skip enabling otherwise */ +#endif +.L8: +#if 1 + l.mfspr r3,r0,SPR_UPR + l.andi r7,r3,SPR_UPR_DCP + l.sfeq r7,r0 + l.bf .L10 + l.nop + /* Disable DC */ + l.mfspr r6,r0,SPR_SR + l.addi r5,r0,-1 + l.xori r5,r5,SPR_SR_DCE + l.and r5,r6,r5 + l.mtspr r0,r5,SPR_SR + /* Establish cache block size + If BS=0, 16; + If BS=1, 32; + r14 contain block size + */ + l.mfspr r3,r0,SPR_DCCFGR + l.andi r7,r3,SPR_DCCFGR_CBS + l.srli r8,r7,7 + l.ori r4,r0,16 + l.sll r14,r4,r8 + /* Establish number of cache sets + r10 contains number of cache sets + r8 contains log(# of cache sets) + */ + l.andi r7,r3,SPR_DCCFGR_NCS + l.srli r8,r7,3 + l.ori r4,r0,1 + l.sll r10,r4,r8 + /* Invalidate DC */ + l.addi r6,r0,0 + l.sll r5,r14,r8 + +.L9: + l.mtspr r0,r6,SPR_DCBIR + l.sfne r6,r5 + l.bf .L9 + l.add r6,r6,r14 + /* Enable DC */ + l.mfspr r6,r0,SPR_SR + l.ori r6,r6,SPR_SR_DCE + l.mtspr r0,r6,SPR_SR +#endif +.L10: + /* Return */ + l.jr r9 + l.nop diff --git a/software/libbase/linker-sdram.ld b/software/libbase/linker-sdram.ld index 16cb35e2..7a894968 100644 --- a/software/libbase/linker-sdram.ld +++ b/software/libbase/linker-sdram.ld @@ -1,4 +1,4 @@ -OUTPUT_FORMAT("elf32-lm32") +INCLUDE generated/output_format.ld ENTRY(_start) __DYNAMIC = 0; diff --git a/software/libbase/setjmp.S b/software/libbase/setjmp-lm32.S similarity index 100% rename from software/libbase/setjmp.S rename to software/libbase/setjmp-lm32.S diff --git a/software/libbase/setjmp-or1k.S b/software/libbase/setjmp-or1k.S new file mode 100644 index 00000000..590e69a0 --- /dev/null +++ b/software/libbase/setjmp-or1k.S @@ -0,0 +1,66 @@ +/* setjmp.S. Implementation of setjmp. + + Copyright (C) 2010, Embecosm Limited + + Contributor Jeremy Bennett + + Licensed under 2-clause BSD. +*/ + +/* -------------------------------------------------------------------------- */ +/*!setjmp + + All processor state is saved in the buffer provided. We need not save r0 + (it will always be zero) and we need not save r11 (it will always be + overridden here, and in longjmp). + + @todo We should prefer to save and restore the status register, but this is + not directly possible in user code. There is some merit in code to + set the flag, since in compiled C code, that might be expected to hold + a value. We leave a space for this information for future enhancement. + + @param[out] env(r3) A buffer to save all the current processor state. + + @return zero.*/ +/* -------------------------------------------------------------------------- */ + .align 4 + .global setjmp + .type setjmp,@function +setjmp: + l.sw 4(r3),r1 /* Slot 0 saved for flag in future */ + l.sw 8(r3),r2 + l.sw 12(r3),r3 + l.sw 16(r3),r4 + l.sw 20(r3),r5 + l.sw 24(r3),r6 + l.sw 28(r3),r7 + l.sw 32(r3),r8 + l.sw 36(r3),r9 + l.sw 40(r3),r10 /* Skip r11 */ + l.sw 44(r3),r12 + l.sw 48(r3),r13 + l.sw 52(r3),r14 + l.sw 56(r3),r15 + l.sw 60(r3),r16 + l.sw 64(r3),r17 + l.sw 68(r3),r18 + l.sw 72(r3),r19 + l.sw 76(r3),r20 + l.sw 80(r3),r21 + l.sw 84(r3),r22 + l.sw 88(r3),r23 + l.sw 92(r3),r24 + l.sw 96(r3),r25 + l.sw 100(r3),r26 + l.sw 104(r3),r27 + l.sw 108(r3),r28 + l.sw 112(r3),r29 + l.sw 116(r3),r30 + l.sw 120(r3),r31 + + + l.jr r9 + l.addi r11,r0,0 /* Zero result */ + + + .size setjmp, .-setjmp diff --git a/software/libbase/system.c b/software/libbase/system.c index 48c6ee22..2f65aeb1 100644 --- a/software/libbase/system.c +++ b/software/libbase/system.c @@ -1,5 +1,8 @@ #include #include +#ifdef __or1k__ +#include +#endif #include #include @@ -7,6 +10,7 @@ void flush_cpu_icache(void) { +#if defined (__lm32__) asm volatile( "wcsr ICC, r0\n" "nop\n" @@ -14,14 +18,53 @@ void flush_cpu_icache(void) "nop\n" "nop\n" ); +#elif defined (__or1k__) + unsigned long iccfgr; + unsigned long cache_set_size; + unsigned long cache_ways; + unsigned long cache_block_size; + unsigned long cache_size; + int i; + + iccfgr = mfspr(SPR_ICCFGR); + cache_ways = 1 << (iccfgr & SPR_ICCFGR_NCW); + cache_set_size = 1 << ((iccfgr & SPR_ICCFGR_NCS) >> 3); + cache_block_size = (iccfgr & SPR_ICCFGR_CBS) ? 32 : 16; + cache_size = cache_set_size * cache_ways * cache_block_size; + + for (i = 0; i < cache_size; i += cache_block_size) + mtspr(SPR_ICBIR, i); +#else +#error Unsupported architecture +#endif } void flush_cpu_dcache(void) { +#if defined (__lm32__) asm volatile( "wcsr DCC, r0\n" "nop\n" ); +#elif defined (__or1k__) + unsigned long dccfgr; + unsigned long cache_set_size; + unsigned long cache_ways; + unsigned long cache_block_size; + unsigned long cache_size; + int i; + + dccfgr = mfspr(SPR_DCCFGR); + cache_ways = 1 << (dccfgr & SPR_ICCFGR_NCW); + cache_set_size = 1 << ((dccfgr & SPR_DCCFGR_NCS) >> 3); + cache_block_size = (dccfgr & SPR_DCCFGR_CBS) ? 32 : 16; + cache_size = cache_set_size * cache_ways * cache_block_size; + + for (i = 0; i < cache_size; i += cache_block_size) + mtspr(SPR_DCBIR, i); +#else +#error Unsupported architecture +#endif } void flush_l2_cache(void) @@ -34,6 +77,10 @@ void flush_l2_cache(void) l2_nwords = 1 << (identifier_l2_size_read() - 2); for(i=0;i<2*l2_nwords;i++) { addr = SDRAM_BASE + i*4; +#ifdef __lm32__ __asm__ volatile("lw %0, (%1+0)\n":"=r"(dummy):"r"(addr)); +#else +#warning TODO +#endif } } diff --git a/software/memtest/Makefile b/software/memtest/Makefile index 0a06503c..ea93a3ae 100644 --- a/software/memtest/Makefile +++ b/software/memtest/Makefile @@ -18,7 +18,7 @@ memtest.elf: $(OBJECTS) libs $(LD) $(LDFLAGS) \ -T $(MSCDIR)/software/libbase/linker-sdram.ld \ -N -o $@ \ - $(MSCDIR)/software/libbase/crt0.o \ + $(MSCDIR)/software/libbase/crt0-$(CPU).o \ $(OBJECTS) \ -L$(MSCDIR)/software/libbase \ -L$(MSCDIR)/software/libcompiler-rt \ diff --git a/software/videomixer/Makefile b/software/videomixer/Makefile index a312fa0e..86be97fe 100644 --- a/software/videomixer/Makefile +++ b/software/videomixer/Makefile @@ -21,7 +21,7 @@ videomixer.elf: $(OBJECTS) libs $(LD) $(LDFLAGS) \ -T $(MSCDIR)/software/libbase/linker-sdram.ld \ -N -o $@ \ - $(MSCDIR)/software/libbase/crt0.o \ + $(MSCDIR)/software/libbase/crt0-$(CPU).o \ $(OBJECTS) \ -L$(MSCDIR)/software/libbase \ -L$(MSCDIR)/software/libcompiler-rt \ diff --git a/targets/mlabs_video.py b/targets/mlabs_video.py index 3c179c26..d00d320b 100644 --- a/targets/mlabs_video.py +++ b/targets/mlabs_video.py @@ -45,11 +45,12 @@ class MiniSoC(SDRAMSoC): } interrupt_map.update(SDRAMSoC.interrupt_map) - def __init__(self, platform, with_memtest=False): + def __init__(self, platform, with_memtest=False, **kwargs): SDRAMSoC.__init__(self, platform, clk_freq=(83 + Fraction(1, 3))*1000000, cpu_reset_address=0x00180000, - with_memtest=with_memtest) + with_memtest=with_memtest, + **kwargs) sdram_geom = lasmicon.GeomSettings( bank_a=2, @@ -130,15 +131,15 @@ TIMESPEC "TSise_sucks2" = FROM "GRPsys_clk" TO "GRPvga_clk" TIG; """, vga_clk=fb.driver.clocking.cd_pix.clk) class FramebufferSoC(MiniSoC): - def __init__(self, platform, with_memtest=False): - MiniSoC.__init__(self, platform, with_memtest) + def __init__(self, platform, with_memtest=False, **kwargs): + MiniSoC.__init__(self, platform, with_memtest, **kwargs) pads_vga, pads_dvi = _get_vga_dvi(platform) self.submodules.fb = framebuffer.Framebuffer(pads_vga, pads_dvi, self.lasmixbar.get_master()) _add_vga_tig(platform, self.fb) class VideomixerSoC(MiniSoC): - def __init__(self, platform, with_memtest=False): - MiniSoC.__init__(self, platform, with_memtest) + def __init__(self, platform, with_memtest=False, **kwargs): + MiniSoC.__init__(self, platform, with_memtest, **kwargs) pads_vga, pads_dvi = _get_vga_dvi(platform) self.submodules.fb = framebuffer.MixFramebuffer(pads_vga, pads_dvi, self.lasmixbar.get_master(), self.lasmixbar.get_master()) diff --git a/targets/simple.py b/targets/simple.py index 24d3e2e8..f03fa7cc 100644 --- a/targets/simple.py +++ b/targets/simple.py @@ -20,12 +20,13 @@ class PowerOnRst(Module): class SimpleSoC(GenSoC): default_platform = "papilio_pro" - def __init__(self, platform): + def __init__(self, platform, **kwargs): GenSoC.__init__(self, platform, clk_freq=32*1000000, - cpu_reset_address=0x60000) + cpu_reset_address=0x60000, + **kwargs) - # We can't use reset_less as LM32 does require a reset signal + # We can't use reset_less as CPU does require a reset signal self.clock_domains.cd_sys = ClockDomain() self.submodules += PowerOnRst(self.cd_sys) self.comb += self.cd_sys.clk.eq(platform.request("clk32")) diff --git a/verilog/mor1kx/submodule b/verilog/mor1kx/submodule new file mode 160000 index 00000000..e0e2f058 --- /dev/null +++ b/verilog/mor1kx/submodule @@ -0,0 +1 @@ +Subproject commit e0e2f058e3ebba40a9a0231c5f54aa1d6b04bb74 -- 2.30.2