target-arm queue:
* hw/net/dp8393x: don't make prom region 'nomigrate' * boards.h: Remove doc comment reference to nonexistent function * hw/sd/omap_mmc: Split 'pseudo-reset' from 'power-on-reset' * target/arm: Fix do_predset for large VL * tcg: Restrict check_size_impl to multiples of the line size * target/arm: Suppress Coverity warning for PRF * hw/timer/cmsdk-apb-timer: fix minor corner-case bugs and suppress spurious warnings when running Linux's timer driver * hw/arm/smmu-common: Fix devfn computation in smmu_iommu_mr -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABCAAGBQJbQ2jiAAoJEDwlJe0UNgzeKRQQAKXVERFFNPgzJDaWGw/1tS0l Ase7pSA1WsiXpkXAeVq9TTxvOWs0TOPMlnTXCoLV352qoEQ7hZMg027j5GMVW8TA KKIP/wkdYhI+Fa38rL5XWtJkX9HMUOOjNMBlTBHZoCb8i6ZyOdOIyBQXrXRZ9ScG pOEiwEiDpBBLxy33bx80ZMXgX4B6RPp6qdYgCNhk8/a09X+DKspBnBRDP9b4dLMx YypARIOKFQh9n13CdgiX+LQUoJyq7mmomW/fzP+XKSsNE23gpSDlCSfrV/ikK34g /9XY6MM16V5cvhRBwA1BXJi8lIsCy8jZVK0aVwAqrOSncxTJ0HvNU6f3W6GY1t+u QsLud1Pq8/oHGCSL51ZwAIY5edMkubSZXpgX5TABMmi8Fq4xVdzpSgYZA94BHDI4 5Tvymr3ctoe0yx/WePh67byDtwu2gCGftDA2NylLH821nBvB52kY/oXavb6Bzdsw BBtlDjNqFPCby6cg8gKZrf0RmtIf+p9Tj5lR/OWe3jMldf47lCI0pPK4vBR8/C/5 O+SiELbcaJwV4M38N/TmFd4Cv6FhBuYJu121rDlHX1yVEBVOcxpfczmC26a2iX/U gFw3y1EtD4RBr2kTwfekKzvbnOCB1H9nemFlHRjdKVc+bIXXQn8EhvtOtxxD4l8e oivqm+zyigCw3BWfl2Hz =/nnX -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20180709' into staging target-arm queue: * hw/net/dp8393x: don't make prom region 'nomigrate' * boards.h: Remove doc comment reference to nonexistent function * hw/sd/omap_mmc: Split 'pseudo-reset' from 'power-on-reset' * target/arm: Fix do_predset for large VL * tcg: Restrict check_size_impl to multiples of the line size * target/arm: Suppress Coverity warning for PRF * hw/timer/cmsdk-apb-timer: fix minor corner-case bugs and suppress spurious warnings when running Linux's timer driver * hw/arm/smmu-common: Fix devfn computation in smmu_iommu_mr # gpg: Signature made Mon 09 Jul 2018 14:53:38 BST # gpg: using RSA key 3C2525ED14360CDE # gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" # gpg: aka "Peter Maydell <pmaydell@gmail.com>" # gpg: aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>" # Primary key fingerprint: E1A5 C593 CD41 9DE2 8E83 15CF 3C25 25ED 1436 0CDE * remotes/pmaydell/tags/pull-target-arm-20180709: hw/net/dp8393x: don't make prom region 'nomigrate' boards.h: Remove doc comment reference to nonexistent function hw/sd/omap_mmc: Split 'pseudo-reset' from 'power-on-reset' target/arm: Fix do_predset for large VL tcg: Restrict check_size_impl to multiples of the line size target/arm: Suppress Coverity warning for PRF hw/timer/cmsdk-apb-timer: run or stop timer on writes to RELOAD and VALUE hw/timer/cmsdk-apb-timer: Correctly identify and set one-shot mode hw/timer/cmsdk-apb-timer: Correct ptimer policy settings ptimer: Add TRIGGER_ONLY_ON_DECREMENT policy option hw/arm/smmu-common: Fix devfn computation in smmu_iommu_mr Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
6d1d4276ae
@ -351,7 +351,7 @@ IOMMUMemoryRegion *smmu_iommu_mr(SMMUState *s, uint32_t sid)
|
||||
bus_n = PCI_BUS_NUM(sid);
|
||||
smmu_bus = smmu_find_smmu_pcibus(s, bus_n);
|
||||
if (smmu_bus) {
|
||||
devfn = sid & 0x7;
|
||||
devfn = SMMU_PCI_DEVFN(sid);
|
||||
smmu = smmu_bus->pbdev[devfn];
|
||||
if (smmu) {
|
||||
return &smmu->iommu;
|
||||
|
@ -45,8 +45,20 @@ static void ptimer_reload(ptimer_state *s, int delta_adjust)
|
||||
uint32_t period_frac = s->period_frac;
|
||||
uint64_t period = s->period;
|
||||
uint64_t delta = s->delta;
|
||||
bool suppress_trigger = false;
|
||||
|
||||
if (delta == 0 && !(s->policy_mask & PTIMER_POLICY_NO_IMMEDIATE_TRIGGER)) {
|
||||
/*
|
||||
* Note that if delta_adjust is 0 then we must be here because of
|
||||
* a count register write or timer start, not because of timer expiry.
|
||||
* In that case the policy might require us to suppress the timer trigger
|
||||
* that we would otherwise generate for a zero delta.
|
||||
*/
|
||||
if (delta_adjust == 0 &&
|
||||
(s->policy_mask & PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT)) {
|
||||
suppress_trigger = true;
|
||||
}
|
||||
if (delta == 0 && !(s->policy_mask & PTIMER_POLICY_NO_IMMEDIATE_TRIGGER)
|
||||
&& !suppress_trigger) {
|
||||
ptimer_trigger(s);
|
||||
}
|
||||
|
||||
@ -353,6 +365,14 @@ ptimer_state *ptimer_init(QEMUBH *bh, uint8_t policy_mask)
|
||||
s->bh = bh;
|
||||
s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, ptimer_tick, s);
|
||||
s->policy_mask = policy_mask;
|
||||
|
||||
/*
|
||||
* These two policies are incompatible -- trigger-on-decrement implies
|
||||
* a timer trigger when the count becomes 0, but no-immediate-trigger
|
||||
* implies a trigger when the count stops being 0.
|
||||
*/
|
||||
assert(!((policy_mask & PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT) &&
|
||||
(policy_mask & PTIMER_POLICY_NO_IMMEDIATE_TRIGGER)));
|
||||
return s;
|
||||
}
|
||||
|
||||
|
@ -887,7 +887,7 @@ static void dp8393x_realize(DeviceState *dev, Error **errp)
|
||||
s->watchdog = timer_new_ns(QEMU_CLOCK_VIRTUAL, dp8393x_watchdog, s);
|
||||
s->regs[SONIC_SR] = 0x0004; /* only revision recognized by Linux */
|
||||
|
||||
memory_region_init_ram_nomigrate(&s->prom, OBJECT(dev),
|
||||
memory_region_init_ram(&s->prom, OBJECT(dev),
|
||||
"dp8393x-prom", SONIC_PROM_SIZE, &local_err);
|
||||
if (local_err) {
|
||||
error_propagate(errp, local_err);
|
||||
|
@ -1,6 +1,8 @@
|
||||
/*
|
||||
* OMAP on-chip MMC/SD host emulation.
|
||||
*
|
||||
* Datasheet: TI Multimedia Card (MMC/SD/SDIO) Interface (SPRU765A)
|
||||
*
|
||||
* Copyright (C) 2006-2007 Andrzej Zaborowski <balrog@zabor.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
@ -278,6 +280,12 @@ static void omap_mmc_update(void *opaque)
|
||||
omap_mmc_interrupts_update(s);
|
||||
}
|
||||
|
||||
static void omap_mmc_pseudo_reset(struct omap_mmc_s *host)
|
||||
{
|
||||
host->status = 0;
|
||||
host->fifo_len = 0;
|
||||
}
|
||||
|
||||
void omap_mmc_reset(struct omap_mmc_s *host)
|
||||
{
|
||||
host->last_cmd = 0;
|
||||
@ -286,11 +294,9 @@ void omap_mmc_reset(struct omap_mmc_s *host)
|
||||
host->dw = 0;
|
||||
host->mode = 0;
|
||||
host->enable = 0;
|
||||
host->status = 0;
|
||||
host->mask = 0;
|
||||
host->cto = 0;
|
||||
host->dto = 0;
|
||||
host->fifo_len = 0;
|
||||
host->blen = 0;
|
||||
host->blen_counter = 0;
|
||||
host->nblk = 0;
|
||||
@ -305,6 +311,8 @@ void omap_mmc_reset(struct omap_mmc_s *host)
|
||||
qemu_set_irq(host->coverswitch, host->cdet_state);
|
||||
host->clkdiv = 0;
|
||||
|
||||
omap_mmc_pseudo_reset(host);
|
||||
|
||||
/* Since we're still using the legacy SD API the card is not plugged
|
||||
* into any bus, and we must reset it manually. When omap_mmc is
|
||||
* QOMified this must move into the QOM reset function.
|
||||
@ -459,7 +467,7 @@ static void omap_mmc_write(void *opaque, hwaddr offset,
|
||||
if (s->dw != 0 && s->lines < 4)
|
||||
printf("4-bit SD bus enabled\n");
|
||||
if (!s->enable)
|
||||
omap_mmc_reset(s);
|
||||
omap_mmc_pseudo_reset(s);
|
||||
break;
|
||||
|
||||
case 0x10: /* MMC_STAT */
|
||||
|
@ -119,17 +119,33 @@ static void cmsdk_apb_timer_write(void *opaque, hwaddr offset, uint64_t value,
|
||||
}
|
||||
s->ctrl = value & 0xf;
|
||||
if (s->ctrl & R_CTRL_EN_MASK) {
|
||||
ptimer_run(s->timer, 0);
|
||||
ptimer_run(s->timer, ptimer_get_limit(s->timer) == 0);
|
||||
} else {
|
||||
ptimer_stop(s->timer);
|
||||
}
|
||||
break;
|
||||
case A_RELOAD:
|
||||
/* Writing to reload also sets the current timer value */
|
||||
if (!value) {
|
||||
ptimer_stop(s->timer);
|
||||
}
|
||||
ptimer_set_limit(s->timer, value, 1);
|
||||
if (value && (s->ctrl & R_CTRL_EN_MASK)) {
|
||||
/*
|
||||
* Make sure timer is running (it might have stopped if this
|
||||
* was an expired one-shot timer)
|
||||
*/
|
||||
ptimer_run(s->timer, 0);
|
||||
}
|
||||
break;
|
||||
case A_VALUE:
|
||||
if (!value && !ptimer_get_limit(s->timer)) {
|
||||
ptimer_stop(s->timer);
|
||||
}
|
||||
ptimer_set_count(s->timer, value);
|
||||
if (value && (s->ctrl & R_CTRL_EN_MASK)) {
|
||||
ptimer_run(s->timer, ptimer_get_limit(s->timer) == 0);
|
||||
}
|
||||
break;
|
||||
case A_INTSTATUS:
|
||||
/* Just one bit, which is W1C. */
|
||||
@ -201,7 +217,7 @@ static void cmsdk_apb_timer_realize(DeviceState *dev, Error **errp)
|
||||
bh = qemu_bh_new(cmsdk_apb_timer_tick, s);
|
||||
s->timer = ptimer_init(bh,
|
||||
PTIMER_POLICY_WRAP_AFTER_ONE_PERIOD |
|
||||
PTIMER_POLICY_NO_IMMEDIATE_TRIGGER |
|
||||
PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT |
|
||||
PTIMER_POLICY_NO_IMMEDIATE_RELOAD |
|
||||
PTIMER_POLICY_NO_COUNTER_ROUND_DOWN);
|
||||
|
||||
|
@ -24,6 +24,7 @@
|
||||
|
||||
#define SMMU_PCI_BUS_MAX 256
|
||||
#define SMMU_PCI_DEVFN_MAX 256
|
||||
#define SMMU_PCI_DEVFN(sid) (sid & 0xFF)
|
||||
|
||||
#define SMMU_MAX_VA_BITS 48
|
||||
|
||||
|
@ -35,8 +35,7 @@
|
||||
*
|
||||
* Smaller pieces of memory (display RAM, static RAMs, etc) don't need
|
||||
* to be backed via the -mem-path memory backend and can simply
|
||||
* be created via memory_region_allocate_aux_memory() or
|
||||
* memory_region_init_ram().
|
||||
* be created via memory_region_init_ram().
|
||||
*/
|
||||
void memory_region_allocate_system_memory(MemoryRegion *mr, Object *owner,
|
||||
const char *name,
|
||||
|
@ -69,6 +69,15 @@
|
||||
* not the one less. */
|
||||
#define PTIMER_POLICY_NO_COUNTER_ROUND_DOWN (1 << 4)
|
||||
|
||||
/*
|
||||
* Starting to run with a zero counter, or setting the counter to "0" via
|
||||
* ptimer_set_count() or ptimer_set_limit() will not trigger the timer
|
||||
* (though it will cause a reload). Only a counter decrement to "0"
|
||||
* will cause a trigger. Not compatible with NO_IMMEDIATE_TRIGGER;
|
||||
* ptimer_init() will assert() that you don't set both.
|
||||
*/
|
||||
#define PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT (1 << 5)
|
||||
|
||||
/* ptimer.c */
|
||||
typedef struct ptimer_state ptimer_state;
|
||||
typedef void (*ptimer_cb)(void *opaque);
|
||||
|
@ -1438,7 +1438,7 @@ static bool do_predset(DisasContext *s, int esz, int rd, int pat, bool setflag)
|
||||
setsz = numelem << esz;
|
||||
lastword = word = pred_esz_masks[esz];
|
||||
if (setsz % 64) {
|
||||
lastword &= ~(-1ull << (setsz % 64));
|
||||
lastword &= MAKE_64BIT_MASK(0, setsz % 64);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1457,19 +1457,13 @@ static bool do_predset(DisasContext *s, int esz, int rd, int pat, bool setflag)
|
||||
tcg_gen_gvec_dup64i(ofs, oprsz, maxsz, word);
|
||||
goto done;
|
||||
}
|
||||
if (oprsz * 8 == setsz + 8) {
|
||||
tcg_gen_gvec_dup64i(ofs, oprsz, maxsz, word);
|
||||
tcg_gen_movi_i64(t, 0);
|
||||
tcg_gen_st_i64(t, cpu_env, ofs + oprsz - 8);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
setsz /= 8;
|
||||
fullsz /= 8;
|
||||
|
||||
tcg_gen_movi_i64(t, word);
|
||||
for (i = 0; i < setsz; i += 8) {
|
||||
for (i = 0; i < QEMU_ALIGN_DOWN(setsz, 8); i += 8) {
|
||||
tcg_gen_st_i64(t, cpu_env, ofs + i);
|
||||
}
|
||||
if (lastword != word) {
|
||||
@ -5164,7 +5158,7 @@ static bool trans_ST1_zpiz(DisasContext *s, arg_ST1_zpiz *a, uint32_t insn)
|
||||
static bool trans_PRF(DisasContext *s, arg_PRF *a, uint32_t insn)
|
||||
{
|
||||
/* Prefetch is a nop within QEMU. */
|
||||
sve_access_check(s);
|
||||
(void)sve_access_check(s);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -5174,7 +5168,7 @@ static bool trans_PRF_rr(DisasContext *s, arg_PRF_rr *a, uint32_t insn)
|
||||
return false;
|
||||
}
|
||||
/* Prefetch is a nop within QEMU. */
|
||||
sve_access_check(s);
|
||||
(void)sve_access_check(s);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -287,8 +287,11 @@ void tcg_gen_gvec_4_ptr(uint32_t dofs, uint32_t aofs, uint32_t bofs,
|
||||
in units of LNSZ. This limits the expansion of inline code. */
|
||||
static inline bool check_size_impl(uint32_t oprsz, uint32_t lnsz)
|
||||
{
|
||||
uint32_t lnct = oprsz / lnsz;
|
||||
return lnct >= 1 && lnct <= MAX_UNROLL;
|
||||
if (oprsz % lnsz == 0) {
|
||||
uint32_t lnct = oprsz / lnsz;
|
||||
return lnct >= 1 && lnct <= MAX_UNROLL;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void expand_clr(uint32_t dofs, uint32_t maxsz);
|
||||
|
@ -208,6 +208,7 @@ static void check_periodic(gconstpointer arg)
|
||||
bool no_immediate_trigger = (*policy & PTIMER_POLICY_NO_IMMEDIATE_TRIGGER);
|
||||
bool no_immediate_reload = (*policy & PTIMER_POLICY_NO_IMMEDIATE_RELOAD);
|
||||
bool no_round_down = (*policy & PTIMER_POLICY_NO_COUNTER_ROUND_DOWN);
|
||||
bool trig_only_on_dec = (*policy & PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT);
|
||||
|
||||
triggered = false;
|
||||
|
||||
@ -311,7 +312,7 @@ static void check_periodic(gconstpointer arg)
|
||||
g_assert_cmpuint(ptimer_get_count(ptimer), ==,
|
||||
no_immediate_reload ? 0 : 10);
|
||||
|
||||
if (no_immediate_trigger) {
|
||||
if (no_immediate_trigger || trig_only_on_dec) {
|
||||
g_assert_false(triggered);
|
||||
} else {
|
||||
g_assert_true(triggered);
|
||||
@ -506,6 +507,7 @@ static void check_run_with_delta_0(gconstpointer arg)
|
||||
bool no_immediate_trigger = (*policy & PTIMER_POLICY_NO_IMMEDIATE_TRIGGER);
|
||||
bool no_immediate_reload = (*policy & PTIMER_POLICY_NO_IMMEDIATE_RELOAD);
|
||||
bool no_round_down = (*policy & PTIMER_POLICY_NO_COUNTER_ROUND_DOWN);
|
||||
bool trig_only_on_dec = (*policy & PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT);
|
||||
|
||||
triggered = false;
|
||||
|
||||
@ -515,7 +517,7 @@ static void check_run_with_delta_0(gconstpointer arg)
|
||||
g_assert_cmpuint(ptimer_get_count(ptimer), ==,
|
||||
no_immediate_reload ? 0 : 99);
|
||||
|
||||
if (no_immediate_trigger) {
|
||||
if (no_immediate_trigger || trig_only_on_dec) {
|
||||
g_assert_false(triggered);
|
||||
} else {
|
||||
g_assert_true(triggered);
|
||||
@ -563,7 +565,7 @@ static void check_run_with_delta_0(gconstpointer arg)
|
||||
g_assert_cmpuint(ptimer_get_count(ptimer), ==,
|
||||
no_immediate_reload ? 0 : 99);
|
||||
|
||||
if (no_immediate_trigger) {
|
||||
if (no_immediate_trigger || trig_only_on_dec) {
|
||||
g_assert_false(triggered);
|
||||
} else {
|
||||
g_assert_true(triggered);
|
||||
@ -609,6 +611,7 @@ static void check_periodic_with_load_0(gconstpointer arg)
|
||||
ptimer_state *ptimer = ptimer_init(bh, *policy);
|
||||
bool continuous_trigger = (*policy & PTIMER_POLICY_CONTINUOUS_TRIGGER);
|
||||
bool no_immediate_trigger = (*policy & PTIMER_POLICY_NO_IMMEDIATE_TRIGGER);
|
||||
bool trig_only_on_dec = (*policy & PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT);
|
||||
|
||||
triggered = false;
|
||||
|
||||
@ -617,7 +620,7 @@ static void check_periodic_with_load_0(gconstpointer arg)
|
||||
|
||||
g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
|
||||
|
||||
if (no_immediate_trigger) {
|
||||
if (no_immediate_trigger || trig_only_on_dec) {
|
||||
g_assert_false(triggered);
|
||||
} else {
|
||||
g_assert_true(triggered);
|
||||
@ -667,6 +670,7 @@ static void check_oneshot_with_load_0(gconstpointer arg)
|
||||
QEMUBH *bh = qemu_bh_new(ptimer_trigger, NULL);
|
||||
ptimer_state *ptimer = ptimer_init(bh, *policy);
|
||||
bool no_immediate_trigger = (*policy & PTIMER_POLICY_NO_IMMEDIATE_TRIGGER);
|
||||
bool trig_only_on_dec = (*policy & PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT);
|
||||
|
||||
triggered = false;
|
||||
|
||||
@ -675,7 +679,7 @@ static void check_oneshot_with_load_0(gconstpointer arg)
|
||||
|
||||
g_assert_cmpuint(ptimer_get_count(ptimer), ==, 0);
|
||||
|
||||
if (no_immediate_trigger) {
|
||||
if (no_immediate_trigger || trig_only_on_dec) {
|
||||
g_assert_false(triggered);
|
||||
} else {
|
||||
g_assert_true(triggered);
|
||||
@ -725,6 +729,10 @@ static void add_ptimer_tests(uint8_t policy)
|
||||
g_strlcat(policy_name, "no_counter_rounddown,", 256);
|
||||
}
|
||||
|
||||
if (policy & PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT) {
|
||||
g_strlcat(policy_name, "trigger_only_on_decrement,", 256);
|
||||
}
|
||||
|
||||
g_test_add_data_func_full(
|
||||
tmp = g_strdup_printf("/ptimer/set_count policy=%s", policy_name),
|
||||
g_memdup(&policy, 1), check_set_count, g_free);
|
||||
@ -790,10 +798,15 @@ static void add_ptimer_tests(uint8_t policy)
|
||||
|
||||
static void add_all_ptimer_policies_comb_tests(void)
|
||||
{
|
||||
int last_policy = PTIMER_POLICY_NO_COUNTER_ROUND_DOWN;
|
||||
int last_policy = PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT;
|
||||
int policy = PTIMER_POLICY_DEFAULT;
|
||||
|
||||
for (; policy < (last_policy << 1); policy++) {
|
||||
if ((policy & PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT) &&
|
||||
(policy & PTIMER_POLICY_NO_IMMEDIATE_TRIGGER)) {
|
||||
/* Incompatible policy flag settings -- don't try to test them */
|
||||
continue;
|
||||
}
|
||||
add_ptimer_tests(policy);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user