mirror of https://github.com/xemu-project/xemu.git
Misc HW patch queue
[hw] - Do not silently overwrite 'io_timeout' property in scsi-generic (Lorenz) - Propagate period when enabling a clock in stm32l4x5 mux (Arnaud, Phil) - Add missing smbios_get_table_legacy() stub (Igor) - Append a space in gpa2hva() HMP error message (Yao) - Fix compiler warning in 'execlog' plugin (Yao) [target] - i386: Enable page walking from MMIO memory (Gregory, Jonathan) - tricore: Use correct string format in cpu_tlb_fill (Phil) [docs] - Fix formatting in amigang.rst (Zoltan) [ui] - Fix cocoa regression in platform fullscreen toggling (Akihiko) -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEE+qvnXhKRciHc/Wuy4+MsLN6twN4FAmYC7QoACgkQ4+MsLN6t wN4WIw//cLw1caDa8ki3htGWGVI2P/QFdsvId7ah4Iul7znf6NWUORDBjvIvLpaF sesPF7BRQ/qJFT5ttB8DsKc1IHw3IASAGL/NK3i7v9GkRiBJNJvQRO2rVfNmXvN8 ++AZ/J+Y1OZ4Y1hcxXGUVIpwKzndR5Oz9zNXQ+C0CQqYljwxC3huB3m6C7vKOgeq SNKVw/hrTBYLzyvooKqLb6Xual2+olSwc2/BwqUOOCP6Y1HmgQeWy5ckJqsuVS2T 5q5VtkduBCsUhgmflsLF3LCKrNTQUw+jOAGH2gyRvXMjmvwCmNy5xo8eOD0iTwXb +Ffp/kfqm2N1QwNWcBi39+BU+Plti03mnL7C9jNzaEBaQ9Q7wMNqASN0daHSk3vh 4Vw/FsaUJAohInKYghCgO0fUVpeLis+8p5lDD7QwAL9tiYk7/tgrbtyNLb+m/3P9 pPNGt9Fnijg+/zDDfjVYwtDMRbL0df7SqTjhJW3TIQ+d83tmoVuCDmBysEXywzSt 5e4yyjDf8q1C23yipK9I84wuvWjfIDYIPSUzCKaZYf4xbdx7GyNaOoOqWZYpordD ua/4hRuQ4AcDuCe3XBKsmAex6wpYodjnfEi5Y5uV8vyPfeiVQodY/07pok/NZjEL tUNy3EkQFqXxT1ctT7FhN2eh6WjSo0SJFtIjVDarJ0mUkS4VXgM= =ccz/ -----END PGP SIGNATURE----- Merge tag 'hw-misc-20240326' of https://github.com/philmd/qemu into staging Misc HW patch queue [hw] - Do not silently overwrite 'io_timeout' property in scsi-generic (Lorenz) - Propagate period when enabling a clock in stm32l4x5 mux (Arnaud, Phil) - Add missing smbios_get_table_legacy() stub (Igor) - Append a space in gpa2hva() HMP error message (Yao) - Fix compiler warning in 'execlog' plugin (Yao) [target] - i386: Enable page walking from MMIO memory (Gregory, Jonathan) - tricore: Use correct string format in cpu_tlb_fill (Phil) [docs] - Fix formatting in amigang.rst (Zoltan) [ui] - Fix cocoa regression in platform fullscreen toggling (Akihiko) # -----BEGIN PGP SIGNATURE----- # # iQIzBAABCAAdFiEE+qvnXhKRciHc/Wuy4+MsLN6twN4FAmYC7QoACgkQ4+MsLN6t # wN4WIw//cLw1caDa8ki3htGWGVI2P/QFdsvId7ah4Iul7znf6NWUORDBjvIvLpaF # sesPF7BRQ/qJFT5ttB8DsKc1IHw3IASAGL/NK3i7v9GkRiBJNJvQRO2rVfNmXvN8 # ++AZ/J+Y1OZ4Y1hcxXGUVIpwKzndR5Oz9zNXQ+C0CQqYljwxC3huB3m6C7vKOgeq # SNKVw/hrTBYLzyvooKqLb6Xual2+olSwc2/BwqUOOCP6Y1HmgQeWy5ckJqsuVS2T # 5q5VtkduBCsUhgmflsLF3LCKrNTQUw+jOAGH2gyRvXMjmvwCmNy5xo8eOD0iTwXb # +Ffp/kfqm2N1QwNWcBi39+BU+Plti03mnL7C9jNzaEBaQ9Q7wMNqASN0daHSk3vh # 4Vw/FsaUJAohInKYghCgO0fUVpeLis+8p5lDD7QwAL9tiYk7/tgrbtyNLb+m/3P9 # pPNGt9Fnijg+/zDDfjVYwtDMRbL0df7SqTjhJW3TIQ+d83tmoVuCDmBysEXywzSt # 5e4yyjDf8q1C23yipK9I84wuvWjfIDYIPSUzCKaZYf4xbdx7GyNaOoOqWZYpordD # ua/4hRuQ4AcDuCe3XBKsmAex6wpYodjnfEi5Y5uV8vyPfeiVQodY/07pok/NZjEL # tUNy3EkQFqXxT1ctT7FhN2eh6WjSo0SJFtIjVDarJ0mUkS4VXgM= # =ccz/ # -----END PGP SIGNATURE----- # gpg: Signature made Tue 26 Mar 2024 15:43:06 GMT # gpg: using RSA key FAABE75E12917221DCFD6BB2E3E32C2CDEADC0DE # gpg: Good signature from "Philippe Mathieu-Daudé (F4BUG) <f4bug@amsat.org>" [full] # Primary key fingerprint: FAAB E75E 1291 7221 DCFD 6BB2 E3E3 2C2C DEAD C0DE * tag 'hw-misc-20240326' of https://github.com/philmd/qemu: ui/cocoa: Use NSTrackingInVisibleRect ui/cocoa: Resize window after toggling zoom-to-fit ui/cocoa: Fix aspect ratio hw/smbios: add stub for smbios_get_table_legacy() contrib/plugins/execlog: Fix compiler warning docs/system/ppc/amigang.rst: Fix formatting hw/misc/stm32l4x5_rcc: Propagate period when enabling a clock hw/misc/stm32l4x5_rcc: Inline clock_update() in clock_mux_update() hw/clock: Let clock_set_mul_div() return a boolean value target/tricore/helper: Use correct string format in cpu_tlb_fill() monitor/hmp-cmds-target: Append a space in error message in gpa2hva() hw/scsi/scsi-generic: Fix io_timeout property not applying target/i386/tcg: Enable page walking from MMIO memory Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
38a23eb35c
|
@ -311,6 +311,24 @@ static Register *init_vcpu_register(qemu_plugin_reg_descriptor *desc)
|
||||||
return reg;
|
return reg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* g_pattern_match_string has been deprecated in Glib since 2.70 and
|
||||||
|
* will complain about it if you try to use it. Fortunately the
|
||||||
|
* signature of both functions is the same making it easy to work
|
||||||
|
* around.
|
||||||
|
*/
|
||||||
|
static inline
|
||||||
|
gboolean g_pattern_spec_match_string_qemu(GPatternSpec *pspec,
|
||||||
|
const gchar *string)
|
||||||
|
{
|
||||||
|
#if GLIB_CHECK_VERSION(2, 70, 0)
|
||||||
|
return g_pattern_spec_match_string(pspec, string);
|
||||||
|
#else
|
||||||
|
return g_pattern_match_string(pspec, string);
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
#define g_pattern_spec_match_string(p, s) g_pattern_spec_match_string_qemu(p, s)
|
||||||
|
|
||||||
static GPtrArray *registers_init(int vcpu_index)
|
static GPtrArray *registers_init(int vcpu_index)
|
||||||
{
|
{
|
||||||
g_autoptr(GPtrArray) registers = g_ptr_array_new();
|
g_autoptr(GPtrArray) registers = g_ptr_array_new();
|
||||||
|
@ -327,8 +345,8 @@ static GPtrArray *registers_init(int vcpu_index)
|
||||||
for (int p = 0; p < rmatches->len; p++) {
|
for (int p = 0; p < rmatches->len; p++) {
|
||||||
g_autoptr(GPatternSpec) pat = g_pattern_spec_new(rmatches->pdata[p]);
|
g_autoptr(GPatternSpec) pat = g_pattern_spec_new(rmatches->pdata[p]);
|
||||||
g_autofree gchar *rd_lower = g_utf8_strdown(rd->name, -1);
|
g_autofree gchar *rd_lower = g_utf8_strdown(rd->name, -1);
|
||||||
if (g_pattern_match_string(pat, rd->name) ||
|
if (g_pattern_spec_match_string(pat, rd->name) ||
|
||||||
g_pattern_match_string(pat, rd_lower)) {
|
g_pattern_spec_match_string(pat, rd_lower)) {
|
||||||
Register *reg = init_vcpu_register(rd);
|
Register *reg = init_vcpu_register(rd);
|
||||||
g_ptr_array_add(registers, reg);
|
g_ptr_array_add(registers, reg);
|
||||||
|
|
||||||
|
@ -336,7 +354,7 @@ static GPtrArray *registers_init(int vcpu_index)
|
||||||
if (disas_assist) {
|
if (disas_assist) {
|
||||||
g_mutex_lock(&add_reg_name_lock);
|
g_mutex_lock(&add_reg_name_lock);
|
||||||
if (!g_ptr_array_find(all_reg_names, reg->name, NULL)) {
|
if (!g_ptr_array_find(all_reg_names, reg->name, NULL)) {
|
||||||
g_ptr_array_add(all_reg_names, reg->name);
|
g_ptr_array_add(all_reg_names, (gpointer)reg->name);
|
||||||
}
|
}
|
||||||
g_mutex_unlock(&add_reg_name_lock);
|
g_mutex_unlock(&add_reg_name_lock);
|
||||||
}
|
}
|
||||||
|
|
|
@ -279,6 +279,10 @@ You can change the multiplier and divider of a clock at runtime,
|
||||||
so you can use this to model clock controller devices which
|
so you can use this to model clock controller devices which
|
||||||
have guest-programmable frequency multipliers or dividers.
|
have guest-programmable frequency multipliers or dividers.
|
||||||
|
|
||||||
|
Similary to ``clock_set()``, ``clock_set_mul_div()`` returns ``true`` if
|
||||||
|
the clock state was modified; that is, if the multiplier or the diviser
|
||||||
|
or both were changed by the call.
|
||||||
|
|
||||||
Note that ``clock_set_mul_div()`` does not automatically call
|
Note that ``clock_set_mul_div()`` does not automatically call
|
||||||
``clock_propagate()``. If you make a runtime change to the
|
``clock_propagate()``. If you make a runtime change to the
|
||||||
multiplier or divider you must call clock_propagate() yourself.
|
multiplier or divider you must call clock_propagate() yourself.
|
||||||
|
|
|
@ -143,14 +143,20 @@ char *clock_display_freq(Clock *clk)
|
||||||
return freq_to_str(clock_get_hz(clk));
|
return freq_to_str(clock_get_hz(clk));
|
||||||
}
|
}
|
||||||
|
|
||||||
void clock_set_mul_div(Clock *clk, uint32_t multiplier, uint32_t divider)
|
bool clock_set_mul_div(Clock *clk, uint32_t multiplier, uint32_t divider)
|
||||||
{
|
{
|
||||||
assert(divider != 0);
|
assert(divider != 0);
|
||||||
|
|
||||||
|
if (clk->multiplier == multiplier && clk->divider == divider) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
trace_clock_set_mul_div(CLOCK_PATH(clk), clk->multiplier, multiplier,
|
trace_clock_set_mul_div(CLOCK_PATH(clk), clk->multiplier, multiplier,
|
||||||
clk->divider, divider);
|
clk->divider, divider);
|
||||||
clk->multiplier = multiplier;
|
clk->multiplier = multiplier;
|
||||||
clk->divider = divider;
|
clk->divider = divider;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void clock_initfn(Object *obj)
|
static void clock_initfn(Object *obj)
|
||||||
|
|
|
@ -48,6 +48,8 @@ static void clock_mux_update(RccClockMuxState *mux, bool bypass_source)
|
||||||
uint64_t src_freq;
|
uint64_t src_freq;
|
||||||
Clock *current_source = mux->srcs[mux->src];
|
Clock *current_source = mux->srcs[mux->src];
|
||||||
uint32_t freq_multiplier = 0;
|
uint32_t freq_multiplier = 0;
|
||||||
|
bool clk_changed = false;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* To avoid rounding errors, we use the clock period instead of the
|
* To avoid rounding errors, we use the clock period instead of the
|
||||||
* frequency.
|
* frequency.
|
||||||
|
@ -59,8 +61,11 @@ static void clock_mux_update(RccClockMuxState *mux, bool bypass_source)
|
||||||
freq_multiplier = mux->divider;
|
freq_multiplier = mux->divider;
|
||||||
}
|
}
|
||||||
|
|
||||||
clock_set_mul_div(mux->out, freq_multiplier, mux->multiplier);
|
clk_changed |= clock_set_mul_div(mux->out, freq_multiplier, mux->multiplier);
|
||||||
clock_update(mux->out, clock_get(current_source));
|
clk_changed |= clock_set(mux->out, clock_get(current_source));
|
||||||
|
if (clk_changed) {
|
||||||
|
clock_propagate(mux->out);
|
||||||
|
}
|
||||||
|
|
||||||
src_freq = clock_get_hz(current_source);
|
src_freq = clock_get_hz(current_source);
|
||||||
/* TODO: can we simply detect if the config changed so that we reduce log spam ? */
|
/* TODO: can we simply detect if the config changed so that we reduce log spam ? */
|
||||||
|
|
|
@ -752,7 +752,6 @@ static void scsi_generic_realize(SCSIDevice *s, Error **errp)
|
||||||
|
|
||||||
/* Only used by scsi-block, but initialize it nevertheless to be clean. */
|
/* Only used by scsi-block, but initialize it nevertheless to be clean. */
|
||||||
s->default_scsi_version = -1;
|
s->default_scsi_version = -1;
|
||||||
s->io_timeout = DEFAULT_IO_TIMEOUT;
|
|
||||||
scsi_generic_read_device_inquiry(s);
|
scsi_generic_read_device_inquiry(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,3 +13,8 @@
|
||||||
void smbios_add_usr_blob_size(size_t size)
|
void smbios_add_usr_blob_size(size_t size)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t *smbios_get_table_legacy(size_t *length, Error **errp)
|
||||||
|
{
|
||||||
|
g_assert_not_reached();
|
||||||
|
}
|
||||||
|
|
|
@ -357,6 +357,8 @@ char *clock_display_freq(Clock *clk);
|
||||||
* @multiplier: multiplier value
|
* @multiplier: multiplier value
|
||||||
* @divider: divider value
|
* @divider: divider value
|
||||||
*
|
*
|
||||||
|
* @return: true if the clock is changed.
|
||||||
|
*
|
||||||
* By default, a Clock's children will all run with the same period
|
* By default, a Clock's children will all run with the same period
|
||||||
* as their parent. This function allows you to adjust the multiplier
|
* as their parent. This function allows you to adjust the multiplier
|
||||||
* and divider used to derive the child clock frequency.
|
* and divider used to derive the child clock frequency.
|
||||||
|
@ -374,6 +376,6 @@ char *clock_display_freq(Clock *clk);
|
||||||
* Note that this function does not call clock_propagate(); the
|
* Note that this function does not call clock_propagate(); the
|
||||||
* caller should do that if necessary.
|
* caller should do that if necessary.
|
||||||
*/
|
*/
|
||||||
void clock_set_mul_div(Clock *clk, uint32_t multiplier, uint32_t divider);
|
bool clock_set_mul_div(Clock *clk, uint32_t multiplier, uint32_t divider);
|
||||||
|
|
||||||
#endif /* QEMU_HW_CLOCK_H */
|
#endif /* QEMU_HW_CLOCK_H */
|
||||||
|
|
|
@ -59,14 +59,14 @@ typedef struct PTETranslate {
|
||||||
hwaddr gaddr;
|
hwaddr gaddr;
|
||||||
} PTETranslate;
|
} PTETranslate;
|
||||||
|
|
||||||
static bool ptw_translate(PTETranslate *inout, hwaddr addr)
|
static bool ptw_translate(PTETranslate *inout, hwaddr addr, uint64_t ra)
|
||||||
{
|
{
|
||||||
CPUTLBEntryFull *full;
|
CPUTLBEntryFull *full;
|
||||||
int flags;
|
int flags;
|
||||||
|
|
||||||
inout->gaddr = addr;
|
inout->gaddr = addr;
|
||||||
flags = probe_access_full(inout->env, addr, 0, MMU_DATA_STORE,
|
flags = probe_access_full(inout->env, addr, 0, MMU_DATA_STORE,
|
||||||
inout->ptw_idx, true, &inout->haddr, &full, 0);
|
inout->ptw_idx, true, &inout->haddr, &full, ra);
|
||||||
|
|
||||||
if (unlikely(flags & TLB_INVALID_MASK)) {
|
if (unlikely(flags & TLB_INVALID_MASK)) {
|
||||||
TranslateFault *err = inout->err;
|
TranslateFault *err = inout->err;
|
||||||
|
@ -82,20 +82,20 @@ static bool ptw_translate(PTETranslate *inout, hwaddr addr)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32_t ptw_ldl(const PTETranslate *in)
|
static inline uint32_t ptw_ldl(const PTETranslate *in, uint64_t ra)
|
||||||
{
|
{
|
||||||
if (likely(in->haddr)) {
|
if (likely(in->haddr)) {
|
||||||
return ldl_p(in->haddr);
|
return ldl_p(in->haddr);
|
||||||
}
|
}
|
||||||
return cpu_ldl_mmuidx_ra(in->env, in->gaddr, in->ptw_idx, 0);
|
return cpu_ldl_mmuidx_ra(in->env, in->gaddr, in->ptw_idx, ra);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint64_t ptw_ldq(const PTETranslate *in)
|
static inline uint64_t ptw_ldq(const PTETranslate *in, uint64_t ra)
|
||||||
{
|
{
|
||||||
if (likely(in->haddr)) {
|
if (likely(in->haddr)) {
|
||||||
return ldq_p(in->haddr);
|
return ldq_p(in->haddr);
|
||||||
}
|
}
|
||||||
return cpu_ldq_mmuidx_ra(in->env, in->gaddr, in->ptw_idx, 0);
|
return cpu_ldq_mmuidx_ra(in->env, in->gaddr, in->ptw_idx, ra);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -132,7 +132,8 @@ static inline bool ptw_setl(const PTETranslate *in, uint32_t old, uint32_t set)
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool mmu_translate(CPUX86State *env, const TranslateParams *in,
|
static bool mmu_translate(CPUX86State *env, const TranslateParams *in,
|
||||||
TranslateResult *out, TranslateFault *err)
|
TranslateResult *out, TranslateFault *err,
|
||||||
|
uint64_t ra)
|
||||||
{
|
{
|
||||||
const target_ulong addr = in->addr;
|
const target_ulong addr = in->addr;
|
||||||
const int pg_mode = in->pg_mode;
|
const int pg_mode = in->pg_mode;
|
||||||
|
@ -164,11 +165,11 @@ static bool mmu_translate(CPUX86State *env, const TranslateParams *in,
|
||||||
* Page table level 5
|
* Page table level 5
|
||||||
*/
|
*/
|
||||||
pte_addr = (in->cr3 & ~0xfff) + (((addr >> 48) & 0x1ff) << 3);
|
pte_addr = (in->cr3 & ~0xfff) + (((addr >> 48) & 0x1ff) << 3);
|
||||||
if (!ptw_translate(&pte_trans, pte_addr)) {
|
if (!ptw_translate(&pte_trans, pte_addr, ra)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
restart_5:
|
restart_5:
|
||||||
pte = ptw_ldq(&pte_trans);
|
pte = ptw_ldq(&pte_trans, ra);
|
||||||
if (!(pte & PG_PRESENT_MASK)) {
|
if (!(pte & PG_PRESENT_MASK)) {
|
||||||
goto do_fault;
|
goto do_fault;
|
||||||
}
|
}
|
||||||
|
@ -188,11 +189,11 @@ static bool mmu_translate(CPUX86State *env, const TranslateParams *in,
|
||||||
* Page table level 4
|
* Page table level 4
|
||||||
*/
|
*/
|
||||||
pte_addr = (pte & PG_ADDRESS_MASK) + (((addr >> 39) & 0x1ff) << 3);
|
pte_addr = (pte & PG_ADDRESS_MASK) + (((addr >> 39) & 0x1ff) << 3);
|
||||||
if (!ptw_translate(&pte_trans, pte_addr)) {
|
if (!ptw_translate(&pte_trans, pte_addr, ra)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
restart_4:
|
restart_4:
|
||||||
pte = ptw_ldq(&pte_trans);
|
pte = ptw_ldq(&pte_trans, ra);
|
||||||
if (!(pte & PG_PRESENT_MASK)) {
|
if (!(pte & PG_PRESENT_MASK)) {
|
||||||
goto do_fault;
|
goto do_fault;
|
||||||
}
|
}
|
||||||
|
@ -208,11 +209,11 @@ static bool mmu_translate(CPUX86State *env, const TranslateParams *in,
|
||||||
* Page table level 3
|
* Page table level 3
|
||||||
*/
|
*/
|
||||||
pte_addr = (pte & PG_ADDRESS_MASK) + (((addr >> 30) & 0x1ff) << 3);
|
pte_addr = (pte & PG_ADDRESS_MASK) + (((addr >> 30) & 0x1ff) << 3);
|
||||||
if (!ptw_translate(&pte_trans, pte_addr)) {
|
if (!ptw_translate(&pte_trans, pte_addr, ra)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
restart_3_lma:
|
restart_3_lma:
|
||||||
pte = ptw_ldq(&pte_trans);
|
pte = ptw_ldq(&pte_trans, ra);
|
||||||
if (!(pte & PG_PRESENT_MASK)) {
|
if (!(pte & PG_PRESENT_MASK)) {
|
||||||
goto do_fault;
|
goto do_fault;
|
||||||
}
|
}
|
||||||
|
@ -235,12 +236,12 @@ static bool mmu_translate(CPUX86State *env, const TranslateParams *in,
|
||||||
* Page table level 3
|
* Page table level 3
|
||||||
*/
|
*/
|
||||||
pte_addr = (in->cr3 & 0xffffffe0ULL) + ((addr >> 27) & 0x18);
|
pte_addr = (in->cr3 & 0xffffffe0ULL) + ((addr >> 27) & 0x18);
|
||||||
if (!ptw_translate(&pte_trans, pte_addr)) {
|
if (!ptw_translate(&pte_trans, pte_addr, ra)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
rsvd_mask |= PG_HI_USER_MASK;
|
rsvd_mask |= PG_HI_USER_MASK;
|
||||||
restart_3_nolma:
|
restart_3_nolma:
|
||||||
pte = ptw_ldq(&pte_trans);
|
pte = ptw_ldq(&pte_trans, ra);
|
||||||
if (!(pte & PG_PRESENT_MASK)) {
|
if (!(pte & PG_PRESENT_MASK)) {
|
||||||
goto do_fault;
|
goto do_fault;
|
||||||
}
|
}
|
||||||
|
@ -257,11 +258,11 @@ static bool mmu_translate(CPUX86State *env, const TranslateParams *in,
|
||||||
* Page table level 2
|
* Page table level 2
|
||||||
*/
|
*/
|
||||||
pte_addr = (pte & PG_ADDRESS_MASK) + (((addr >> 21) & 0x1ff) << 3);
|
pte_addr = (pte & PG_ADDRESS_MASK) + (((addr >> 21) & 0x1ff) << 3);
|
||||||
if (!ptw_translate(&pte_trans, pte_addr)) {
|
if (!ptw_translate(&pte_trans, pte_addr, ra)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
restart_2_pae:
|
restart_2_pae:
|
||||||
pte = ptw_ldq(&pte_trans);
|
pte = ptw_ldq(&pte_trans, ra);
|
||||||
if (!(pte & PG_PRESENT_MASK)) {
|
if (!(pte & PG_PRESENT_MASK)) {
|
||||||
goto do_fault;
|
goto do_fault;
|
||||||
}
|
}
|
||||||
|
@ -283,10 +284,10 @@ static bool mmu_translate(CPUX86State *env, const TranslateParams *in,
|
||||||
* Page table level 1
|
* Page table level 1
|
||||||
*/
|
*/
|
||||||
pte_addr = (pte & PG_ADDRESS_MASK) + (((addr >> 12) & 0x1ff) << 3);
|
pte_addr = (pte & PG_ADDRESS_MASK) + (((addr >> 12) & 0x1ff) << 3);
|
||||||
if (!ptw_translate(&pte_trans, pte_addr)) {
|
if (!ptw_translate(&pte_trans, pte_addr, ra)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
pte = ptw_ldq(&pte_trans);
|
pte = ptw_ldq(&pte_trans, ra);
|
||||||
if (!(pte & PG_PRESENT_MASK)) {
|
if (!(pte & PG_PRESENT_MASK)) {
|
||||||
goto do_fault;
|
goto do_fault;
|
||||||
}
|
}
|
||||||
|
@ -301,11 +302,11 @@ static bool mmu_translate(CPUX86State *env, const TranslateParams *in,
|
||||||
* Page table level 2
|
* Page table level 2
|
||||||
*/
|
*/
|
||||||
pte_addr = (in->cr3 & 0xfffff000ULL) + ((addr >> 20) & 0xffc);
|
pte_addr = (in->cr3 & 0xfffff000ULL) + ((addr >> 20) & 0xffc);
|
||||||
if (!ptw_translate(&pte_trans, pte_addr)) {
|
if (!ptw_translate(&pte_trans, pte_addr, ra)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
restart_2_nopae:
|
restart_2_nopae:
|
||||||
pte = ptw_ldl(&pte_trans);
|
pte = ptw_ldl(&pte_trans, ra);
|
||||||
if (!(pte & PG_PRESENT_MASK)) {
|
if (!(pte & PG_PRESENT_MASK)) {
|
||||||
goto do_fault;
|
goto do_fault;
|
||||||
}
|
}
|
||||||
|
@ -330,10 +331,10 @@ static bool mmu_translate(CPUX86State *env, const TranslateParams *in,
|
||||||
* Page table level 1
|
* Page table level 1
|
||||||
*/
|
*/
|
||||||
pte_addr = (pte & ~0xfffu) + ((addr >> 10) & 0xffc);
|
pte_addr = (pte & ~0xfffu) + ((addr >> 10) & 0xffc);
|
||||||
if (!ptw_translate(&pte_trans, pte_addr)) {
|
if (!ptw_translate(&pte_trans, pte_addr, ra)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
pte = ptw_ldl(&pte_trans);
|
pte = ptw_ldl(&pte_trans, ra);
|
||||||
if (!(pte & PG_PRESENT_MASK)) {
|
if (!(pte & PG_PRESENT_MASK)) {
|
||||||
goto do_fault;
|
goto do_fault;
|
||||||
}
|
}
|
||||||
|
@ -526,7 +527,8 @@ static G_NORETURN void raise_stage2(CPUX86State *env, TranslateFault *err,
|
||||||
|
|
||||||
static bool get_physical_address(CPUX86State *env, vaddr addr,
|
static bool get_physical_address(CPUX86State *env, vaddr addr,
|
||||||
MMUAccessType access_type, int mmu_idx,
|
MMUAccessType access_type, int mmu_idx,
|
||||||
TranslateResult *out, TranslateFault *err)
|
TranslateResult *out, TranslateFault *err,
|
||||||
|
uint64_t ra)
|
||||||
{
|
{
|
||||||
TranslateParams in;
|
TranslateParams in;
|
||||||
bool use_stage2 = env->hflags2 & HF2_NPT_MASK;
|
bool use_stage2 = env->hflags2 & HF2_NPT_MASK;
|
||||||
|
@ -546,7 +548,7 @@ static bool get_physical_address(CPUX86State *env, vaddr addr,
|
||||||
env->nested_pg_mode & PG_MODE_LMA ? MMU_USER64_IDX : MMU_USER32_IDX;
|
env->nested_pg_mode & PG_MODE_LMA ? MMU_USER64_IDX : MMU_USER32_IDX;
|
||||||
in.ptw_idx = MMU_PHYS_IDX;
|
in.ptw_idx = MMU_PHYS_IDX;
|
||||||
|
|
||||||
if (!mmu_translate(env, &in, out, err)) {
|
if (!mmu_translate(env, &in, out, err, ra)) {
|
||||||
err->stage2 = S2_GPA;
|
err->stage2 = S2_GPA;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -577,7 +579,7 @@ static bool get_physical_address(CPUX86State *env, vaddr addr,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return mmu_translate(env, &in, out, err);
|
return mmu_translate(env, &in, out, err, ra);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -597,7 +599,8 @@ bool x86_cpu_tlb_fill(CPUState *cs, vaddr addr, int size,
|
||||||
TranslateResult out;
|
TranslateResult out;
|
||||||
TranslateFault err;
|
TranslateFault err;
|
||||||
|
|
||||||
if (get_physical_address(env, addr, access_type, mmu_idx, &out, &err)) {
|
if (get_physical_address(env, addr, access_type, mmu_idx, &out, &err,
|
||||||
|
retaddr)) {
|
||||||
/*
|
/*
|
||||||
* Even if 4MB pages, we map only one 4KB page in the cache to
|
* Even if 4MB pages, we map only one 4KB page in the cache to
|
||||||
* avoid filling it too fast.
|
* avoid filling it too fast.
|
||||||
|
|
|
@ -76,9 +76,9 @@ bool tricore_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
|
||||||
ret = get_physical_address(env, &physical, &prot,
|
ret = get_physical_address(env, &physical, &prot,
|
||||||
address, rw, mmu_idx);
|
address, rw, mmu_idx);
|
||||||
|
|
||||||
qemu_log_mask(CPU_LOG_MMU, "%s address=" TARGET_FMT_lx " ret %d physical "
|
qemu_log_mask(CPU_LOG_MMU, "%s address=0x%" VADDR_PRIx " ret %d physical "
|
||||||
HWADDR_FMT_plx " prot %d\n",
|
HWADDR_FMT_plx " prot %d\n",
|
||||||
__func__, (target_ulong)address, ret, physical, prot);
|
__func__, address, ret, physical, prot);
|
||||||
|
|
||||||
if (ret == TLBRET_MATCH) {
|
if (ret == TLBRET_MATCH) {
|
||||||
tlb_set_page(cs, address & TARGET_PAGE_MASK,
|
tlb_set_page(cs, address & TARGET_PAGE_MASK,
|
||||||
|
|
90
ui/cocoa.m
90
ui/cocoa.m
|
@ -307,7 +307,6 @@ static void handleAnyDeviceErrors(Error * err)
|
||||||
*/
|
*/
|
||||||
@interface QemuCocoaView : NSView
|
@interface QemuCocoaView : NSView
|
||||||
{
|
{
|
||||||
NSTrackingArea *trackingArea;
|
|
||||||
QEMUScreen screen;
|
QEMUScreen screen;
|
||||||
pixman_image_t *pixman_image;
|
pixman_image_t *pixman_image;
|
||||||
BOOL isMouseGrabbed;
|
BOOL isMouseGrabbed;
|
||||||
|
@ -359,6 +358,19 @@ static CGEventRef handleTapEvent(CGEventTapProxy proxy, CGEventType type, CGEven
|
||||||
self = [super initWithFrame:frameRect];
|
self = [super initWithFrame:frameRect];
|
||||||
if (self) {
|
if (self) {
|
||||||
|
|
||||||
|
NSTrackingAreaOptions options = NSTrackingActiveInKeyWindow |
|
||||||
|
NSTrackingMouseEnteredAndExited |
|
||||||
|
NSTrackingMouseMoved |
|
||||||
|
NSTrackingInVisibleRect;
|
||||||
|
|
||||||
|
NSTrackingArea *trackingArea =
|
||||||
|
[[NSTrackingArea alloc] initWithRect:CGRectZero
|
||||||
|
options:options
|
||||||
|
owner:self
|
||||||
|
userInfo:nil];
|
||||||
|
|
||||||
|
[self addTrackingArea:trackingArea];
|
||||||
|
[trackingArea release];
|
||||||
screen.width = frameRect.size.width;
|
screen.width = frameRect.size.width;
|
||||||
screen.height = frameRect.size.height;
|
screen.height = frameRect.size.height;
|
||||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_VERSION_14_0
|
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_VERSION_14_0
|
||||||
|
@ -389,41 +401,9 @@ static CGEventRef handleTapEvent(CGEventTapProxy proxy, CGEventType type, CGEven
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) removeTrackingRect
|
|
||||||
{
|
|
||||||
if (trackingArea) {
|
|
||||||
[self removeTrackingArea:trackingArea];
|
|
||||||
[trackingArea release];
|
|
||||||
trackingArea = nil;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void) frameUpdated
|
|
||||||
{
|
|
||||||
[self removeTrackingRect];
|
|
||||||
|
|
||||||
if ([self window]) {
|
|
||||||
NSTrackingAreaOptions options = NSTrackingActiveInKeyWindow |
|
|
||||||
NSTrackingMouseEnteredAndExited |
|
|
||||||
NSTrackingMouseMoved;
|
|
||||||
trackingArea = [[NSTrackingArea alloc] initWithRect:[self frame]
|
|
||||||
options:options
|
|
||||||
owner:self
|
|
||||||
userInfo:nil];
|
|
||||||
[self addTrackingArea:trackingArea];
|
|
||||||
[self updateUIInfo];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void) viewDidMoveToWindow
|
- (void) viewDidMoveToWindow
|
||||||
{
|
{
|
||||||
[self resizeWindow];
|
[self resizeWindow];
|
||||||
[self frameUpdated];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void) viewWillMoveToWindow:(NSWindow *)newWindow
|
|
||||||
{
|
|
||||||
[self removeTrackingRect];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) selectConsoleLocked:(unsigned int)index
|
- (void) selectConsoleLocked:(unsigned int)index
|
||||||
|
@ -519,6 +499,43 @@ static CGEventRef handleTapEvent(CGEventTapProxy proxy, CGEventType type, CGEven
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (NSSize)fixAspectRatio:(NSSize)max
|
||||||
|
{
|
||||||
|
NSSize scaled;
|
||||||
|
NSSize fixed;
|
||||||
|
|
||||||
|
scaled.width = screen.width * max.height;
|
||||||
|
scaled.height = screen.height * max.width;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Here screen is our guest's output size, and max is the size of the
|
||||||
|
* largest possible area of the screen we can display on.
|
||||||
|
* We want to scale up (screen.width x screen.height) by either:
|
||||||
|
* 1) max.height / screen.height
|
||||||
|
* 2) max.width / screen.width
|
||||||
|
* With the first scale factor the scale will result in an output height of
|
||||||
|
* max.height (i.e. we will fill the whole height of the available screen
|
||||||
|
* space and have black bars left and right) and with the second scale
|
||||||
|
* factor the scaling will result in an output width of max.width (i.e. we
|
||||||
|
* fill the whole width of the available screen space and have black bars
|
||||||
|
* top and bottom). We need to pick whichever keeps the whole of the guest
|
||||||
|
* output on the screen, which is to say the smaller of the two scale
|
||||||
|
* factors.
|
||||||
|
* To avoid doing more division than strictly necessary, instead of directly
|
||||||
|
* comparing scale factors 1 and 2 we instead calculate and compare those
|
||||||
|
* two scale factors multiplied by (screen.height * screen.width).
|
||||||
|
*/
|
||||||
|
if (scaled.width < scaled.height) {
|
||||||
|
fixed.width = scaled.width / screen.height;
|
||||||
|
fixed.height = max.height;
|
||||||
|
} else {
|
||||||
|
fixed.width = max.width;
|
||||||
|
fixed.height = scaled.height / screen.width;
|
||||||
|
}
|
||||||
|
|
||||||
|
return fixed;
|
||||||
|
}
|
||||||
|
|
||||||
- (NSSize) screenSafeAreaSize
|
- (NSSize) screenSafeAreaSize
|
||||||
{
|
{
|
||||||
NSSize size = [[[self window] screen] frame].size;
|
NSSize size = [[[self window] screen] frame].size;
|
||||||
|
@ -536,8 +553,10 @@ static CGEventRef handleTapEvent(CGEventTapProxy proxy, CGEventType type, CGEven
|
||||||
[[self window] setContentSize:NSMakeSize(screen.width, screen.height)];
|
[[self window] setContentSize:NSMakeSize(screen.width, screen.height)];
|
||||||
[[self window] center];
|
[[self window] center];
|
||||||
} else if ([[self window] styleMask] & NSWindowStyleMaskFullScreen) {
|
} else if ([[self window] styleMask] & NSWindowStyleMaskFullScreen) {
|
||||||
[[self window] setContentSize:[self screenSafeAreaSize]];
|
[[self window] setContentSize:[self fixAspectRatio:[self screenSafeAreaSize]]];
|
||||||
[[self window] center];
|
[[self window] center];
|
||||||
|
} else {
|
||||||
|
[[self window] setContentSize:[self fixAspectRatio:[self frame].size]];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1275,7 +1294,7 @@ static CGEventRef handleTapEvent(CGEventTapProxy proxy, CGEventType type, CGEven
|
||||||
- (void)windowDidResize:(NSNotification *)notification
|
- (void)windowDidResize:(NSNotification *)notification
|
||||||
{
|
{
|
||||||
[cocoaView updateBounds];
|
[cocoaView updateBounds];
|
||||||
[cocoaView frameUpdated];
|
[cocoaView updateUIInfo];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Called when the user clicks on a window's close button */
|
/* Called when the user clicks on a window's close button */
|
||||||
|
@ -1369,6 +1388,7 @@ static CGEventRef handleTapEvent(CGEventTapProxy proxy, CGEventType type, CGEven
|
||||||
|
|
||||||
[[cocoaView window] setStyleMask:styleMask];
|
[[cocoaView window] setStyleMask:styleMask];
|
||||||
[sender setState:styleMask & NSWindowStyleMaskResizable ? NSControlStateValueOn : NSControlStateValueOff];
|
[sender setState:styleMask & NSWindowStyleMaskResizable ? NSControlStateValueOn : NSControlStateValueOff];
|
||||||
|
[cocoaView resizeWindow];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)toggleZoomInterpolation:(id) sender
|
- (void)toggleZoomInterpolation:(id) sender
|
||||||
|
|
Loading…
Reference in New Issue