Skip to content

Commit

Permalink
mips: update ITU to utilise SAARI/SAAR registers
Browse files Browse the repository at this point in the history
Update the ITU to utilise SAARI/SAAR registers and add new ITU
Control Register (ICR0).

Signed-off-by: Yongbok Kim <yongbok.kim@imgtec.com>
  • Loading branch information
yongbok committed Apr 26, 2017
1 parent c934049 commit e03079c
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 7 deletions.
8 changes: 8 additions & 0 deletions hw/mips/cps.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ static void mips_cps_realize(DeviceState *dev, Error **errp)
Error *err = NULL;
target_ulong gcr_base;
bool itu_present = false;
bool saar_present = false;

for (i = 0; i < s->num_vp; i++) {
cpu = cpu_mips_init(s->cpu_model);
Expand All @@ -86,12 +87,14 @@ static void mips_cps_realize(DeviceState *dev, Error **errp)
itu_present = true;
/* Attach ITC Tag to the VP */
env->itc_tag = mips_itu_get_tag_region(&s->itu);
env->itu = &s->itu;
}
qemu_register_reset(main_cpu_reset, cpu);
}

cpu = MIPS_CPU(first_cpu);
env = &cpu->env;
saar_present = (bool) env->saarp;

/* Inter-Thread Communication Unit */
if (itu_present) {
Expand All @@ -100,6 +103,11 @@ static void mips_cps_realize(DeviceState *dev, Error **errp)

object_property_set_int(OBJECT(&s->itu), 16, "num-fifo", &err);
object_property_set_int(OBJECT(&s->itu), 16, "num-semaphores", &err);
object_property_set_bool(OBJECT(&s->itu), saar_present, "saar-present",
&err);
if (saar_present) {
qdev_prop_set_ptr(DEVICE(&s->itu), "saar", (void *) &env->CP0_SAAR);
}
object_property_set_bool(OBJECT(&s->itu), true, "realized", &err);
if (err != NULL) {
error_propagate(errp, err);
Expand Down
74 changes: 67 additions & 7 deletions hw/misc/mips_itu.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,17 @@ typedef enum ITCView {
ITCVIEW_EF_SYNC = 2,
ITCVIEW_EF_TRY = 3,
ITCVIEW_PV_SYNC = 4,
ITCVIEW_PV_TRY = 5
ITCVIEW_PV_TRY = 5,
ITCVIEW_PV_ICR = 15
} ITCView;

#define ITC_ICR0_CELL_NUM 16
#define ITC_ICR0_BLK_GRAIN 8
#define ITC_ICR0_BLK_GRAIN_MASK 0x7
#define ITC_ICR0_ERR_AXI 2
#define ITC_ICR0_ERR_PARITY 1
#define ITC_ICR0_ERR_EXEC 0

MemoryRegion *mips_itu_get_tag_region(MIPSITUState *itu)
{
return &itu->tag_io;
Expand All @@ -78,14 +86,20 @@ static uint64_t itc_tag_read(void *opaque, hwaddr addr, unsigned size)
return tag->ITCAddressMap[index];
}

static void itc_reconfigure(MIPSITUState *tag)
void itc_reconfigure(MIPSITUState *tag)
{
uint64_t *am = &tag->ITCAddressMap[0];
MemoryRegion *mr = &tag->storage_io;
hwaddr address = am[0] & ITC_AM0_BASE_ADDRESS_MASK;
uint64_t size = (1 << 10) + (am[1] & ITC_AM1_ADDR_MASK_MASK);
bool is_enabled = (am[0] & ITC_AM0_EN_MASK) != 0;

if (tag->saar_present) {
address = ((*(uint64_t *) tag->saar) & 0xFFFFFFFFE000ULL) << 4;
size = 1 << ((*(uint64_t *) tag->saar >> 1) & 0x1f);
is_enabled = *(uint64_t *) tag->saar & 1;
}

memory_region_transaction_begin();
if (!(size & (size - 1))) {
memory_region_set_size(mr, size);
Expand Down Expand Up @@ -144,7 +158,12 @@ static inline ITCView get_itc_view(hwaddr addr)
static inline int get_cell_stride_shift(const MIPSITUState *s)
{
/* Minimum interval (for EntryGain = 0) is 128 B */
return 7 + (s->ITCAddressMap[1] & ITC_AM1_ENTRY_GRAIN_MASK);
if (s->saar_present) {
return 7 + ((s->icr0 >> ITC_ICR0_BLK_GRAIN) &
ITC_ICR0_BLK_GRAIN_MASK);
} else {
return 7 + (s->ITCAddressMap[1] & ITC_AM1_ENTRY_GRAIN_MASK);
}
}

static inline ITCStorageCell *get_cell(MIPSITUState *s,
Expand Down Expand Up @@ -359,13 +378,27 @@ static void view_pv_try_write(ITCStorageCell *c)
view_pv_common_write(c);
}

static void raise_exception(int excp)
{
current_cpu->exception_index = excp;
cpu_loop_exit(current_cpu);
}

static uint64_t itc_storage_read(void *opaque, hwaddr addr, unsigned size)
{
MIPSITUState *s = (MIPSITUState *)opaque;
ITCStorageCell *cell = get_cell(s, addr);
ITCView view = get_itc_view(addr);
uint64_t ret = -1;

switch (size) {
case 1:
case 2:
s->icr0 |= 1 << ITC_ICR0_ERR_AXI;
raise_exception(EXCP_DBE);
return 0;
}

switch (view) {
case ITCVIEW_BYPASS:
ret = view_bypass_read(cell);
Expand All @@ -385,6 +418,9 @@ static uint64_t itc_storage_read(void *opaque, hwaddr addr, unsigned size)
case ITCVIEW_PV_TRY:
ret = view_pv_try_read(cell);
break;
case ITCVIEW_PV_ICR:
ret = s->icr0;
break;
default:
qemu_log_mask(LOG_GUEST_ERROR,
"itc_storage_read: Bad ITC View %d\n", (int)view);
Expand All @@ -401,6 +437,14 @@ static void itc_storage_write(void *opaque, hwaddr addr, uint64_t data,
ITCStorageCell *cell = get_cell(s, addr);
ITCView view = get_itc_view(addr);

switch (size) {
case 1:
case 2:
s->icr0 |= 1 << ITC_ICR0_ERR_AXI;
raise_exception(EXCP_DBE);
return;
}

switch (view) {
case ITCVIEW_BYPASS:
view_bypass_write(cell, data);
Expand All @@ -420,6 +464,15 @@ static void itc_storage_write(void *opaque, hwaddr addr, uint64_t data,
case ITCVIEW_PV_TRY:
view_pv_try_write(cell);
break;
case ITCVIEW_PV_ICR:
if (data & 0x7) {
/* clear ERROR bits */
s->icr0 &= ~(data & 0x7);
}
/* set BLK_GRAIN */
s->icr0 &= ~0x700;
s->icr0 |= data & 0x700;
break;
default:
qemu_log_mask(LOG_GUEST_ERROR,
"itc_storage_write: Bad ITC View %d\n", (int)view);
Expand Down Expand Up @@ -482,10 +535,15 @@ static void mips_itu_reset(DeviceState *dev)
{
MIPSITUState *s = MIPS_ITU(dev);

s->ITCAddressMap[0] = 0;
s->ITCAddressMap[1] =
((ITC_STORAGE_ADDRSPACE_SZ - 1) & ITC_AM1_ADDR_MASK_MASK) |
(get_num_cells(s) << ITC_AM1_NUMENTRIES_OFS);
if (s->saar_present) {
*(uint64_t *) s->saar = 0x11 << 1;
s->icr0 = get_num_cells(s) << ITC_ICR0_CELL_NUM;
} else {
s->ITCAddressMap[0] = 0;
s->ITCAddressMap[1] =
((ITC_STORAGE_ADDRSPACE_SZ - 1) & ITC_AM1_ADDR_MASK_MASK) |
(get_num_cells(s) << ITC_AM1_NUMENTRIES_OFS);
}
itc_reconfigure(s);

itc_reset_cells(s);
Expand All @@ -496,6 +554,8 @@ static Property mips_itu_properties[] = {
ITC_FIFO_NUM_MAX),
DEFINE_PROP_INT32("num-semaphores", MIPSITUState, num_semaphores,
ITC_SEMAPH_NUM_MAX),
DEFINE_PROP_BOOL("saar-present", MIPSITUState, saar_present, false),
DEFINE_PROP_PTR("saar", MIPSITUState, saar),
DEFINE_PROP_END_OF_LIST(),
};

Expand Down
7 changes: 7 additions & 0 deletions include/hw/misc/mips_itu.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,13 @@ typedef struct MIPSITUState {
/* ITC Configuration Tags */
uint64_t ITCAddressMap[ITC_ADDRESSMAP_NUM];
MemoryRegion tag_io;

/* ITU Control Registers */
uint64_t icr0;

/* SAAR */
bool saar_present;
void *saar;
} MIPSITUState;

/* Get ITC Configuration Tag memory region. */
Expand Down
5 changes: 5 additions & 0 deletions target-mips/cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,7 @@ struct TCState {
float_status msa_fp_status;
};

struct MIPSITUState;
typedef struct CPUMIPSState CPUMIPSState;
struct CPUMIPSState {
TCState active_tc;
Expand Down Expand Up @@ -653,6 +654,7 @@ struct CPUMIPSState {
const mips_def_t *cpu_model;
void *irq[8];
QEMUTimer *timer; /* Internal timer */
struct MIPSITUState *itu;
MemoryRegion *itc_tag; /* ITC Configuration Tags */
target_ulong exception_base; /* ExceptionBase input to the core */
};
Expand Down Expand Up @@ -863,6 +865,9 @@ void cpu_mips_stop_count(CPUMIPSState *env);
/* mips_int.c */
void cpu_mips_soft_irq(CPUMIPSState *env, int irq, int level);

/* mips_itu.c */
void itc_reconfigure(struct MIPSITUState *tag);

/* helper.c */
int mips_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw,
int mmu_idx);
Expand Down
14 changes: 14 additions & 0 deletions target-mips/op_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -1479,6 +1479,13 @@ void helper_mtc0_saar(CPUMIPSState *env, target_ulong arg1)
uint32_t target = env->CP0_SAARI & 0x3f;
if (target < 2) {
env->CP0_SAAR[target] = arg1 & 0x00000ffffffff03fULL;
switch (target) {
case 0:
if (env->itu) {
itc_reconfigure(env->itu);
}
break;
}
}
}

Expand All @@ -1489,6 +1496,13 @@ void helper_mthc0_saar(CPUMIPSState *env, target_ulong arg1)
env->CP0_SAAR[target] =
(((uint64_t) arg1 << 32) & 0x00000fff00000000ULL) |
(env->CP0_SAAR[target] & 0x00000000ffffffffULL);
switch (target) {
case 0:
if (env->itu) {
itc_reconfigure(env->itu);
}
break;
}
}
}

Expand Down

0 comments on commit e03079c

Please sign in to comment.