2017-01-19 01:01:41 +03:00
|
|
|
/*
|
|
|
|
* Altera Nios II virtual CPU header
|
|
|
|
*
|
|
|
|
* Copyright (c) 2012 Chris Wulff <crwulff@gmail.com>
|
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This library 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
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with this library; if not, see
|
|
|
|
* <http://www.gnu.org/licenses/lgpl-2.1.html>
|
|
|
|
*/
|
2019-03-15 17:51:20 +03:00
|
|
|
|
|
|
|
#ifndef NIOS2_CPU_H
|
|
|
|
#define NIOS2_CPU_H
|
2017-01-19 01:01:41 +03:00
|
|
|
|
2019-03-22 21:51:19 +03:00
|
|
|
#include "exec/cpu-defs.h"
|
2019-07-09 18:20:52 +03:00
|
|
|
#include "hw/core/cpu.h"
|
2022-04-21 18:16:55 +03:00
|
|
|
#include "hw/registerfields.h"
|
2020-09-03 23:43:22 +03:00
|
|
|
#include "qom/object.h"
|
2017-01-19 01:01:41 +03:00
|
|
|
|
2022-02-07 15:35:58 +03:00
|
|
|
typedef struct CPUArchState CPUNios2State;
|
2017-01-19 01:01:41 +03:00
|
|
|
#if !defined(CONFIG_USER_ONLY)
|
|
|
|
#include "mmu.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#define TYPE_NIOS2_CPU "nios2-cpu"
|
|
|
|
|
2022-02-14 19:08:40 +03:00
|
|
|
OBJECT_DECLARE_CPU_TYPE(Nios2CPU, Nios2CPUClass, NIOS2_CPU)
|
2017-01-19 01:01:41 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Nios2CPUClass:
|
|
|
|
* @parent_reset: The parent class' reset handler.
|
|
|
|
*
|
|
|
|
* A Nios2 CPU model.
|
|
|
|
*/
|
2020-09-03 23:43:22 +03:00
|
|
|
struct Nios2CPUClass {
|
2017-01-19 01:01:41 +03:00
|
|
|
/*< private >*/
|
|
|
|
CPUClass parent_class;
|
|
|
|
/*< public >*/
|
|
|
|
|
|
|
|
DeviceRealize parent_realize;
|
cpu: Use DeviceClass reset instead of a special CPUClass reset
The CPUClass has a 'reset' method. This is a legacy from when
TYPE_CPU used not to inherit from TYPE_DEVICE. We don't need it any
more, as we can simply use the TYPE_DEVICE reset. The 'cpu_reset()'
function is kept as the API which most places use to reset a CPU; it
is now a wrapper which calls device_cold_reset() and then the
tracepoint function.
This change should not cause CPU objects to be reset more often
than they are at the moment, because:
* nobody is directly calling device_cold_reset() or
qdev_reset_all() on CPU objects
* no CPU object is on a qbus, so they will not be reset either
by somebody calling qbus_reset_all()/bus_cold_reset(), or
by the main "reset sysbus and everything in the qbus tree"
reset that most devices are reset by
Note that this does not change the need for each machine or whatever
to use qemu_register_reset() to arrange to call cpu_reset() -- that
is necessary because CPU objects are not on any qbus, so they don't
get reset when the qbus tree rooted at the sysbus bus is reset, and
this isn't being changed here.
All the changes to the files under target/ were made using the
included Coccinelle script, except:
(1) the deletion of the now-inaccurate and not terribly useful
"CPUClass::reset" comments was done with a perl one-liner afterwards:
perl -n -i -e '/ CPUClass::reset/ or print' target/*/*.c
(2) this bit of the s390 change was done by hand, because the
Coccinelle script is not sophisticated enough to handle the
parent_reset call being inside another function:
| @@ -96,8 +96,9 @@ static void s390_cpu_reset(CPUState *s, cpu_reset_type type)
| S390CPU *cpu = S390_CPU(s);
| S390CPUClass *scc = S390_CPU_GET_CLASS(cpu);
| CPUS390XState *env = &cpu->env;
|+ DeviceState *dev = DEVICE(s);
|
|- scc->parent_reset(s);
|+ scc->parent_reset(dev);
| cpu->env.sigp_order = 0;
| s390_cpu_set_state(S390_CPU_STATE_STOPPED, cpu);
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Message-Id: <20200303100511.5498-1-peter.maydell@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
2020-03-03 13:05:11 +03:00
|
|
|
DeviceReset parent_reset;
|
2020-09-03 23:43:22 +03:00
|
|
|
};
|
2017-01-19 01:01:41 +03:00
|
|
|
|
|
|
|
#define TARGET_HAS_ICE 1
|
|
|
|
|
|
|
|
/* Configuration options for Nios II */
|
|
|
|
#define RESET_ADDRESS 0x00000000
|
|
|
|
#define EXCEPTION_ADDRESS 0x00000004
|
|
|
|
#define FAST_TLB_MISS_ADDRESS 0x00000008
|
|
|
|
|
2022-04-21 18:16:46 +03:00
|
|
|
#define NUM_GP_REGS 32
|
|
|
|
#define NUM_CR_REGS 32
|
2017-01-19 01:01:41 +03:00
|
|
|
|
|
|
|
/* General purpose register aliases */
|
2022-04-21 18:17:01 +03:00
|
|
|
enum {
|
|
|
|
R_ZERO = 0,
|
|
|
|
R_AT = 1,
|
|
|
|
R_RET0 = 2,
|
|
|
|
R_RET1 = 3,
|
|
|
|
R_ARG0 = 4,
|
|
|
|
R_ARG1 = 5,
|
|
|
|
R_ARG2 = 6,
|
|
|
|
R_ARG3 = 7,
|
|
|
|
R_ET = 24,
|
|
|
|
R_BT = 25,
|
|
|
|
R_GP = 26,
|
|
|
|
R_SP = 27,
|
|
|
|
R_FP = 28,
|
|
|
|
R_EA = 29,
|
|
|
|
R_BA = 30,
|
|
|
|
R_RA = 31,
|
|
|
|
};
|
2017-01-19 01:01:41 +03:00
|
|
|
|
|
|
|
/* Control register aliases */
|
2022-04-21 18:17:01 +03:00
|
|
|
enum {
|
|
|
|
CR_STATUS = 0,
|
|
|
|
CR_ESTATUS = 1,
|
|
|
|
CR_BSTATUS = 2,
|
|
|
|
CR_IENABLE = 3,
|
|
|
|
CR_IPENDING = 4,
|
|
|
|
CR_CPUID = 5,
|
|
|
|
CR_EXCEPTION = 7,
|
|
|
|
CR_PTEADDR = 8,
|
|
|
|
CR_TLBACC = 9,
|
|
|
|
CR_TLBMISC = 10,
|
|
|
|
CR_ENCINJ = 11,
|
|
|
|
CR_BADADDR = 12,
|
|
|
|
CR_CONFIG = 13,
|
|
|
|
CR_MPUBASE = 14,
|
|
|
|
CR_MPUACC = 15,
|
|
|
|
};
|
2022-04-21 18:16:55 +03:00
|
|
|
|
|
|
|
FIELD(CR_STATUS, PIE, 0, 1)
|
|
|
|
FIELD(CR_STATUS, U, 1, 1)
|
|
|
|
FIELD(CR_STATUS, EH, 2, 1)
|
|
|
|
FIELD(CR_STATUS, IH, 3, 1)
|
|
|
|
FIELD(CR_STATUS, IL, 4, 6)
|
|
|
|
FIELD(CR_STATUS, CRS, 10, 6)
|
|
|
|
FIELD(CR_STATUS, PRS, 16, 6)
|
|
|
|
FIELD(CR_STATUS, NMI, 22, 1)
|
|
|
|
FIELD(CR_STATUS, RSIE, 23, 1)
|
|
|
|
|
|
|
|
#define CR_STATUS_PIE R_CR_STATUS_PIE_MASK
|
|
|
|
#define CR_STATUS_U R_CR_STATUS_U_MASK
|
|
|
|
#define CR_STATUS_EH R_CR_STATUS_EH_MASK
|
|
|
|
#define CR_STATUS_IH R_CR_STATUS_IH_MASK
|
|
|
|
#define CR_STATUS_NMI R_CR_STATUS_NMI_MASK
|
|
|
|
#define CR_STATUS_RSIE R_CR_STATUS_RSIE_MASK
|
|
|
|
|
2022-04-21 18:16:56 +03:00
|
|
|
FIELD(CR_EXCEPTION, CAUSE, 2, 5)
|
|
|
|
FIELD(CR_EXCEPTION, ECCFTL, 31, 1)
|
|
|
|
|
2022-04-21 18:16:57 +03:00
|
|
|
FIELD(CR_PTEADDR, VPN, 2, 20)
|
|
|
|
FIELD(CR_PTEADDR, PTBASE, 22, 10)
|
|
|
|
|
2022-04-21 18:16:58 +03:00
|
|
|
FIELD(CR_TLBACC, PFN, 0, 20)
|
|
|
|
FIELD(CR_TLBACC, G, 20, 1)
|
|
|
|
FIELD(CR_TLBACC, X, 21, 1)
|
|
|
|
FIELD(CR_TLBACC, W, 22, 1)
|
|
|
|
FIELD(CR_TLBACC, R, 23, 1)
|
|
|
|
FIELD(CR_TLBACC, C, 24, 1)
|
|
|
|
FIELD(CR_TLBACC, IG, 25, 7)
|
|
|
|
|
|
|
|
#define CR_TLBACC_C R_CR_TLBACC_C_MASK
|
|
|
|
#define CR_TLBACC_R R_CR_TLBACC_R_MASK
|
|
|
|
#define CR_TLBACC_W R_CR_TLBACC_W_MASK
|
|
|
|
#define CR_TLBACC_X R_CR_TLBACC_X_MASK
|
|
|
|
#define CR_TLBACC_G R_CR_TLBACC_G_MASK
|
|
|
|
|
2022-04-21 18:17:00 +03:00
|
|
|
FIELD(CR_TLBMISC, D, 0, 1)
|
|
|
|
FIELD(CR_TLBMISC, PERM, 1, 1)
|
|
|
|
FIELD(CR_TLBMISC, BAD, 2, 1)
|
|
|
|
FIELD(CR_TLBMISC, DBL, 3, 1)
|
|
|
|
FIELD(CR_TLBMISC, PID, 4, 14)
|
|
|
|
FIELD(CR_TLBMISC, WE, 18, 1)
|
|
|
|
FIELD(CR_TLBMISC, RD, 19, 1)
|
|
|
|
FIELD(CR_TLBMISC, WAY, 20, 4)
|
|
|
|
FIELD(CR_TLBMISC, EE, 24, 1)
|
|
|
|
|
|
|
|
#define CR_TLBMISC_EE R_CR_TLBMISC_EE_MASK
|
|
|
|
#define CR_TLBMISC_RD R_CR_TLBMISC_RD_MASK
|
|
|
|
#define CR_TLBMISC_WE R_CR_TLBMISC_WE_MASK
|
|
|
|
#define CR_TLBMISC_DBL R_CR_TLBMISC_DBL_MASK
|
|
|
|
#define CR_TLBMISC_BAD R_CR_TLBMISC_BAD_MASK
|
|
|
|
#define CR_TLBMISC_PERM R_CR_TLBMISC_PERM_MASK
|
|
|
|
#define CR_TLBMISC_D R_CR_TLBMISC_D_MASK
|
|
|
|
|
2017-01-19 01:01:41 +03:00
|
|
|
/* Exceptions */
|
2019-04-03 22:53:05 +03:00
|
|
|
#define EXCP_BREAK 0x1000
|
2022-04-21 18:17:02 +03:00
|
|
|
#define EXCP_SEMIHOST 0x1001
|
2017-01-19 01:01:41 +03:00
|
|
|
#define EXCP_RESET 0
|
|
|
|
#define EXCP_PRESET 1
|
|
|
|
#define EXCP_IRQ 2
|
|
|
|
#define EXCP_TRAP 3
|
|
|
|
#define EXCP_UNIMPL 4
|
|
|
|
#define EXCP_ILLEGAL 5
|
|
|
|
#define EXCP_UNALIGN 6
|
|
|
|
#define EXCP_UNALIGND 7
|
|
|
|
#define EXCP_DIV 8
|
target/nios2: Clean up handling of tlbmisc in do_exception
The 4 lower bits, D, PERM, BAD, DBL, are unconditionally set on any
exception with EH=0, or so says Table 42 (Processor Status After
Taking Exception).
We currently do not set PERM or BAD at all, and only set/clear
DBL for tlb miss, and do not clear DBL for any other exception.
It is a bit confusing to set D in tlb_fill and the rest during
do_interrupt, so move the setting of D to do_interrupt as well.
To do this, split EXP_TLBD into two cases, EXCP_TLB_X and EXCP_TLB_D,
which allows us to distinguish them during do_interrupt. Choose
a value for EXCP_TLB_D such that when truncated it produces the
correct value for exception.CAUSE.
Rename EXCP_TLB[RWX] to EXCP_PERM_[RWX], to emphasize that the
exception is permissions related. Rename EXCP_SUPER[AD] to
EXCP_SUPERA_[DX] to emphasize that they are both "supervisor
address" exceptions, data and execute.
Retain the setting of tlbmisc.WE for the fast-tlb-miss path, as it
is being relied upon, but remove it from the permission path.
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20220421151735.31996-37-richard.henderson@linaro.org>
2022-04-21 18:17:07 +03:00
|
|
|
#define EXCP_SUPERA_X 9
|
2017-01-19 01:01:41 +03:00
|
|
|
#define EXCP_SUPERI 10
|
target/nios2: Clean up handling of tlbmisc in do_exception
The 4 lower bits, D, PERM, BAD, DBL, are unconditionally set on any
exception with EH=0, or so says Table 42 (Processor Status After
Taking Exception).
We currently do not set PERM or BAD at all, and only set/clear
DBL for tlb miss, and do not clear DBL for any other exception.
It is a bit confusing to set D in tlb_fill and the rest during
do_interrupt, so move the setting of D to do_interrupt as well.
To do this, split EXP_TLBD into two cases, EXCP_TLB_X and EXCP_TLB_D,
which allows us to distinguish them during do_interrupt. Choose
a value for EXCP_TLB_D such that when truncated it produces the
correct value for exception.CAUSE.
Rename EXCP_TLB[RWX] to EXCP_PERM_[RWX], to emphasize that the
exception is permissions related. Rename EXCP_SUPER[AD] to
EXCP_SUPERA_[DX] to emphasize that they are both "supervisor
address" exceptions, data and execute.
Retain the setting of tlbmisc.WE for the fast-tlb-miss path, as it
is being relied upon, but remove it from the permission path.
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20220421151735.31996-37-richard.henderson@linaro.org>
2022-04-21 18:17:07 +03:00
|
|
|
#define EXCP_SUPERA_D 11
|
|
|
|
#define EXCP_TLB_X 12
|
|
|
|
#define EXCP_TLB_D (0x1000 | EXCP_TLB_X)
|
|
|
|
#define EXCP_PERM_X 13
|
|
|
|
#define EXCP_PERM_R 14
|
|
|
|
#define EXCP_PERM_W 15
|
2017-01-19 01:01:41 +03:00
|
|
|
#define EXCP_MPUI 16
|
|
|
|
#define EXCP_MPUD 17
|
|
|
|
|
2022-02-07 15:35:58 +03:00
|
|
|
struct CPUArchState {
|
2022-04-21 18:16:53 +03:00
|
|
|
uint32_t regs[NUM_GP_REGS];
|
|
|
|
uint32_t ctrl[NUM_CR_REGS];
|
2022-04-21 18:16:47 +03:00
|
|
|
uint32_t pc;
|
2017-01-19 01:01:41 +03:00
|
|
|
|
|
|
|
#if !defined(CONFIG_USER_ONLY)
|
|
|
|
Nios2MMU mmu;
|
|
|
|
#endif
|
2021-12-21 05:50:06 +03:00
|
|
|
int error_code;
|
2017-01-19 01:01:41 +03:00
|
|
|
};
|
|
|
|
|
2022-04-21 18:17:08 +03:00
|
|
|
typedef struct {
|
|
|
|
uint32_t writable;
|
|
|
|
uint32_t readonly;
|
|
|
|
} ControlRegState;
|
|
|
|
|
2017-01-19 01:01:41 +03:00
|
|
|
/**
|
|
|
|
* Nios2CPU:
|
|
|
|
* @env: #CPUNios2State
|
|
|
|
*
|
|
|
|
* A Nios2 CPU.
|
|
|
|
*/
|
2022-02-14 19:15:16 +03:00
|
|
|
struct ArchCPU {
|
2017-01-19 01:01:41 +03:00
|
|
|
/*< private >*/
|
|
|
|
CPUState parent_obj;
|
|
|
|
/*< public >*/
|
|
|
|
|
2019-03-23 03:16:06 +03:00
|
|
|
CPUNegativeOffsetState neg;
|
2017-01-19 01:01:41 +03:00
|
|
|
CPUNios2State env;
|
2019-03-23 03:16:06 +03:00
|
|
|
|
2022-04-21 18:17:12 +03:00
|
|
|
bool diverr_present;
|
2017-01-19 01:01:41 +03:00
|
|
|
bool mmu_present;
|
2022-04-21 18:17:12 +03:00
|
|
|
|
2017-01-19 01:01:41 +03:00
|
|
|
uint32_t pid_num_bits;
|
|
|
|
uint32_t tlb_num_ways;
|
|
|
|
uint32_t tlb_num_entries;
|
|
|
|
|
|
|
|
/* Addresses that are hard-coded in the FPGA build settings */
|
|
|
|
uint32_t reset_addr;
|
|
|
|
uint32_t exception_addr;
|
|
|
|
uint32_t fast_tlb_miss_addr;
|
2022-04-21 18:17:08 +03:00
|
|
|
|
|
|
|
/* Bits within each control register which are reserved or readonly. */
|
|
|
|
ControlRegState cr_state[NUM_CR_REGS];
|
2020-09-03 23:43:22 +03:00
|
|
|
};
|
2017-01-19 01:01:41 +03:00
|
|
|
|
|
|
|
|
2022-04-21 18:17:08 +03:00
|
|
|
static inline bool nios2_cr_reserved(const ControlRegState *s)
|
|
|
|
{
|
|
|
|
return (s->writable | s->readonly) == 0;
|
|
|
|
}
|
|
|
|
|
2017-01-19 01:01:41 +03:00
|
|
|
void nios2_tcg_init(void);
|
|
|
|
void nios2_cpu_do_interrupt(CPUState *cs);
|
2019-04-17 22:17:58 +03:00
|
|
|
void dump_mmu(CPUNios2State *env);
|
2019-04-17 22:18:02 +03:00
|
|
|
void nios2_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
|
2017-01-19 01:01:41 +03:00
|
|
|
hwaddr nios2_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
|
2022-04-20 16:26:02 +03:00
|
|
|
G_NORETURN void nios2_cpu_do_unaligned_access(CPUState *cpu, vaddr addr,
|
|
|
|
MMUAccessType access_type, int mmu_idx,
|
|
|
|
uintptr_t retaddr);
|
2017-01-19 01:01:41 +03:00
|
|
|
|
2019-04-03 22:53:05 +03:00
|
|
|
void do_nios2_semihosting(CPUNios2State *env);
|
|
|
|
|
2018-02-07 13:40:25 +03:00
|
|
|
#define CPU_RESOLVING_TYPE TYPE_NIOS2_CPU
|
2017-01-19 01:01:41 +03:00
|
|
|
|
|
|
|
#define cpu_gen_code cpu_nios2_gen_code
|
|
|
|
|
|
|
|
#define CPU_SAVE_VERSION 1
|
|
|
|
|
|
|
|
/* MMU modes definitions */
|
|
|
|
#define MMU_SUPERVISOR_IDX 0
|
|
|
|
#define MMU_USER_IDX 1
|
|
|
|
|
|
|
|
static inline int cpu_mmu_index(CPUNios2State *env, bool ifetch)
|
|
|
|
{
|
2022-04-21 18:16:53 +03:00
|
|
|
return (env->ctrl[CR_STATUS] & CR_STATUS_U) ? MMU_USER_IDX :
|
2017-01-19 01:01:41 +03:00
|
|
|
MMU_SUPERVISOR_IDX;
|
|
|
|
}
|
|
|
|
|
2022-04-21 18:16:41 +03:00
|
|
|
#ifndef CONFIG_USER_ONLY
|
2019-04-02 12:47:37 +03:00
|
|
|
bool nios2_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
|
|
|
|
MMUAccessType access_type, int mmu_idx,
|
|
|
|
bool probe, uintptr_t retaddr);
|
2021-09-30 20:41:43 +03:00
|
|
|
#endif
|
2017-01-19 01:01:41 +03:00
|
|
|
|
2019-03-23 01:32:23 +03:00
|
|
|
typedef CPUNios2State CPUArchState;
|
2019-03-23 01:56:19 +03:00
|
|
|
typedef Nios2CPU ArchCPU;
|
2019-03-23 01:32:23 +03:00
|
|
|
|
2017-01-19 01:01:41 +03:00
|
|
|
#include "exec/cpu-all.h"
|
|
|
|
|
|
|
|
static inline void cpu_get_tb_cpu_state(CPUNios2State *env, target_ulong *pc,
|
|
|
|
target_ulong *cs_base, uint32_t *flags)
|
|
|
|
{
|
2022-04-21 18:16:47 +03:00
|
|
|
*pc = env->pc;
|
2017-01-19 01:01:41 +03:00
|
|
|
*cs_base = 0;
|
2022-04-21 18:16:53 +03:00
|
|
|
*flags = env->ctrl[CR_STATUS] & (CR_STATUS_EH | CR_STATUS_U);
|
2017-01-19 01:01:41 +03:00
|
|
|
}
|
|
|
|
|
2019-03-15 17:51:20 +03:00
|
|
|
#endif /* NIOS2_CPU_H */
|