hppa power button support, graphics updates and firmware fixes

-----BEGIN PGP SIGNATURE-----
 
 iHUEABYIAB0WIQS86RI+GtKfB8BJu973ErUQojoPXwUCX1aFfQAKCRD3ErUQojoP
 X9kAAP9UgEFiOVCQILI7TSHl2moEjQ7x31CA/Bmod6V+eVKM6QD9Gucjy0KC5DWe
 PogywA+CdndMLmH71GN/AFrENVqNnws=
 =bbqB
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/hdeller/tags/target-hppa-pull-request' into staging

hppa power button support, graphics updates and firmware fixes

# gpg: Signature made Mon 07 Sep 2020 20:09:49 BST
# gpg:                using EDDSA key BCE9123E1AD29F07C049BBDEF712B510A23A0F5F
# gpg: Good signature from "Helge Deller <deller@gmx.de>" [unknown]
# gpg:                 aka "Helge Deller <deller@kernel.org>" [unknown]
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg:          There is no indication that the signature belongs to the owner.
# Primary key fingerprint: 4544 8228 2CD9 10DB EF3D  25F8 3E5F 3D04 A7A2 4603
#      Subkey fingerprint: BCE9 123E 1AD2 9F07 C049  BBDE F712 B510 A23A 0F5F

* remotes/hdeller/tags/target-hppa-pull-request:
  hw/display/artist: Allow screen size up to 2048 lines
  hw/display/artist: Refactor x/y coordination extraction
  hw/display/artist: Verify artist screen resolution
  target/hppa: Fix boot with old Linux installation CDs
  hw/hppa: Add power button emulation
  hw/hppa: Tell SeaBIOS port address of fw_cfg
  hw/hppa: Change fw_cfg port address
  hw/hppa: Store boot device in fw_cfg section
  hw/hppa: Make number of TLB and BTLB entries configurable
  seabios-hppa: Update SeaBIOS to hppa-qemu-5.2-2 tag

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2020-09-07 21:50:29 +01:00
commit e4c4f7db60
7 changed files with 95 additions and 24 deletions

View File

@ -192,6 +192,10 @@ static const char *artist_reg_name(uint64_t addr)
} }
#undef REG_NAME #undef REG_NAME
/* artist has a fixed line length of 2048 bytes. */
#define ADDR_TO_Y(addr) extract32(addr, 11, 11)
#define ADDR_TO_X(addr) extract32(addr, 0, 11)
static int16_t artist_get_x(uint32_t reg) static int16_t artist_get_x(uint32_t reg)
{ {
return reg >> 16; return reg >> 16;
@ -348,13 +352,13 @@ static void artist_invalidate_cursor(ARTISTState *s)
y, s->cursor_height); y, s->cursor_height);
} }
static void vram_bit_write(ARTISTState *s, int posx, int posy, bool incr_x, static void vram_bit_write(ARTISTState *s, int posy, bool incr_x,
int size, uint32_t data) int size, uint32_t data)
{ {
struct vram_buffer *buf; struct vram_buffer *buf;
uint32_t vram_bitmask = s->vram_bitmask; uint32_t vram_bitmask = s->vram_bitmask;
int mask, i, pix_count, pix_length; int mask, i, pix_count, pix_length;
unsigned int offset, width; unsigned int posx, offset, width;
uint8_t *data8, *p; uint8_t *data8, *p;
pix_count = vram_write_pix_per_transfer(s); pix_count = vram_write_pix_per_transfer(s);
@ -366,6 +370,8 @@ static void vram_bit_write(ARTISTState *s, int posx, int posy, bool incr_x,
if (s->cmap_bm_access) { if (s->cmap_bm_access) {
offset = s->vram_pos; offset = s->vram_pos;
} else { } else {
posx = ADDR_TO_X(s->vram_pos >> 2);
posy += ADDR_TO_Y(s->vram_pos >> 2);
offset = posy * width + posx; offset = posy * width + posx;
} }
@ -858,7 +864,6 @@ static void artist_reg_write(void *opaque, hwaddr addr, uint64_t val,
unsigned size) unsigned size)
{ {
ARTISTState *s = opaque; ARTISTState *s = opaque;
int posx, posy;
int width, height; int width, height;
trace_artist_reg_write(size, addr, artist_reg_name(addr & ~3ULL), val); trace_artist_reg_write(size, addr, artist_reg_name(addr & ~3ULL), val);
@ -881,16 +886,12 @@ static void artist_reg_write(void *opaque, hwaddr addr, uint64_t val,
break; break;
case VRAM_WRITE_INCR_Y: case VRAM_WRITE_INCR_Y:
posx = (s->vram_pos >> 2) & 0x7ff; vram_bit_write(s, s->vram_char_y++, false, size, val);
posy = (s->vram_pos >> 13) & 0x3ff;
vram_bit_write(s, posx, posy + s->vram_char_y++, false, size, val);
break; break;
case VRAM_WRITE_INCR_X: case VRAM_WRITE_INCR_X:
case VRAM_WRITE_INCR_X2: case VRAM_WRITE_INCR_X2:
posx = (s->vram_pos >> 2) & 0x7ff; vram_bit_write(s, s->vram_char_y, true, size, val);
posy = (s->vram_pos >> 13) & 0x3ff;
vram_bit_write(s, posx, posy + s->vram_char_y, true, size, val);
break; break;
case VRAM_IDX: case VRAM_IDX:
@ -1156,8 +1157,7 @@ static void artist_vram_write(void *opaque, hwaddr addr, uint64_t val,
{ {
ARTISTState *s = opaque; ARTISTState *s = opaque;
struct vram_buffer *buf; struct vram_buffer *buf;
int posy = (addr >> 11) & 0x3ff; unsigned int posy, posx;
int posx = addr & 0x7ff;
unsigned int offset; unsigned int offset;
trace_artist_vram_write(size, addr, val); trace_artist_vram_write(size, addr, val);
@ -1170,6 +1170,9 @@ static void artist_vram_write(void *opaque, hwaddr addr, uint64_t val,
} }
buf = vram_write_buffer(s); buf = vram_write_buffer(s);
posy = ADDR_TO_Y(addr);
posx = ADDR_TO_X(addr);
if (!buf->size) { if (!buf->size) {
return; return;
} }
@ -1212,7 +1215,7 @@ static uint64_t artist_vram_read(void *opaque, hwaddr addr, unsigned size)
ARTISTState *s = opaque; ARTISTState *s = opaque;
struct vram_buffer *buf; struct vram_buffer *buf;
uint64_t val; uint64_t val;
int posy, posx; unsigned int posy, posx;
if (s->cmap_bm_access) { if (s->cmap_bm_access) {
buf = &s->vram_buffer[ARTIST_BUFFER_CMAP]; buf = &s->vram_buffer[ARTIST_BUFFER_CMAP];
@ -1229,8 +1232,8 @@ static uint64_t artist_vram_read(void *opaque, hwaddr addr, unsigned size)
return 0; return 0;
} }
posy = (addr >> 13) & 0x3ff; posy = ADDR_TO_Y(addr);
posx = (addr >> 2) & 0x7ff; posx = ADDR_TO_X(addr);
if (posy > buf->height || posx > buf->width) { if (posy > buf->height || posx > buf->width) {
return 0; return 0;
@ -1374,6 +1377,18 @@ static void artist_realizefn(DeviceState *dev, Error **errp)
struct vram_buffer *buf; struct vram_buffer *buf;
hwaddr offset = 0; hwaddr offset = 0;
if (s->width > 2048 || s->height > 2048) {
error_report("artist: screen size can not exceed 2048 x 2048 pixel.");
s->width = MIN(s->width, 2048);
s->height = MIN(s->height, 2048);
}
if (s->width < 640 || s->height < 480) {
error_report("artist: minimum screen size is 640 x 480 pixel.");
s->width = MAX(s->width, 640);
s->height = MAX(s->height, 480);
}
memory_region_init(&s->mem_as_root, OBJECT(dev), "artist", ~0ull); memory_region_init(&s->mem_as_root, OBJECT(dev), "artist", ~0ull);
address_space_init(&s->as, &s->mem_as_root, "artist"); address_space_init(&s->as, &s->mem_as_root, "artist");

View File

@ -38,8 +38,7 @@
#define PORT_PCI_CMD (PCI_HPA + DINO_PCI_ADDR) #define PORT_PCI_CMD (PCI_HPA + DINO_PCI_ADDR)
#define PORT_PCI_DATA (PCI_HPA + DINO_CONFIG_DATA) #define PORT_PCI_DATA (PCI_HPA + DINO_CONFIG_DATA)
/* QEMU fw_cfg interface port */ #define FW_CFG_IO_BASE 0xfffa0000
#define QEMU_FW_CFG_IO_BASE (MEMORY_HPA + 0x80)
#define PORT_SERIAL1 (DINO_UART_HPA + 0x800) #define PORT_SERIAL1 (DINO_UART_HPA + 0x800)
#define PORT_SERIAL2 (LASI_UART_HPA + 0x800) #define PORT_SERIAL2 (LASI_UART_HPA + 0x800)

View File

@ -12,6 +12,7 @@
#include "qemu/error-report.h" #include "qemu/error-report.h"
#include "sysemu/reset.h" #include "sysemu/reset.h"
#include "sysemu/sysemu.h" #include "sysemu/sysemu.h"
#include "sysemu/runstate.h"
#include "hw/rtc/mc146818rtc.h" #include "hw/rtc/mc146818rtc.h"
#include "hw/timer/i8254.h" #include "hw/timer/i8254.h"
#include "hw/char/serial.h" #include "hw/char/serial.h"
@ -27,6 +28,30 @@
#define MIN_SEABIOS_HPPA_VERSION 1 /* require at least this fw version */ #define MIN_SEABIOS_HPPA_VERSION 1 /* require at least this fw version */
#define HPA_POWER_BUTTON (FIRMWARE_END - 0x10)
static void hppa_powerdown_req(Notifier *n, void *opaque)
{
hwaddr soft_power_reg = HPA_POWER_BUTTON;
uint32_t val;
val = ldl_be_phys(&address_space_memory, soft_power_reg);
if ((val >> 8) == 0) {
/* immediately shut down when under hardware control */
qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
return;
}
/* clear bit 31 to indicate that the power switch was pressed. */
val &= ~1;
stl_be_phys(&address_space_memory, soft_power_reg, val);
}
static Notifier hppa_system_powerdown_notifier = {
.notify = hppa_powerdown_req
};
static ISABus *hppa_isa_bus(void) static ISABus *hppa_isa_bus(void)
{ {
ISABus *isa_bus; ISABus *isa_bus;
@ -58,12 +83,18 @@ static uint64_t cpu_hppa_to_phys(void *opaque, uint64_t addr)
static HPPACPU *cpu[HPPA_MAX_CPUS]; static HPPACPU *cpu[HPPA_MAX_CPUS];
static uint64_t firmware_entry; static uint64_t firmware_entry;
static void fw_cfg_boot_set(void *opaque, const char *boot_device,
Error **errp)
{
fw_cfg_modify_i16(opaque, FW_CFG_BOOT_DEVICE, boot_device[0]);
}
static FWCfgState *create_fw_cfg(MachineState *ms) static FWCfgState *create_fw_cfg(MachineState *ms)
{ {
FWCfgState *fw_cfg; FWCfgState *fw_cfg;
uint64_t val; uint64_t val;
fw_cfg = fw_cfg_init_mem(QEMU_FW_CFG_IO_BASE, QEMU_FW_CFG_IO_BASE + 4); fw_cfg = fw_cfg_init_mem(FW_CFG_IO_BASE, FW_CFG_IO_BASE + 4);
fw_cfg_add_i16(fw_cfg, FW_CFG_NB_CPUS, ms->smp.cpus); fw_cfg_add_i16(fw_cfg, FW_CFG_NB_CPUS, ms->smp.cpus);
fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, HPPA_MAX_CPUS); fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, HPPA_MAX_CPUS);
fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, ram_size); fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, ram_size);
@ -72,6 +103,21 @@ static FWCfgState *create_fw_cfg(MachineState *ms)
fw_cfg_add_file(fw_cfg, "/etc/firmware-min-version", fw_cfg_add_file(fw_cfg, "/etc/firmware-min-version",
g_memdup(&val, sizeof(val)), sizeof(val)); g_memdup(&val, sizeof(val)), sizeof(val));
val = cpu_to_le64(HPPA_TLB_ENTRIES);
fw_cfg_add_file(fw_cfg, "/etc/cpu/tlb_entries",
g_memdup(&val, sizeof(val)), sizeof(val));
val = cpu_to_le64(HPPA_BTLB_ENTRIES);
fw_cfg_add_file(fw_cfg, "/etc/cpu/btlb_entries",
g_memdup(&val, sizeof(val)), sizeof(val));
val = cpu_to_le64(HPA_POWER_BUTTON);
fw_cfg_add_file(fw_cfg, "/etc/power-button-addr",
g_memdup(&val, sizeof(val)), sizeof(val));
fw_cfg_add_i16(fw_cfg, FW_CFG_BOOT_DEVICE, ms->boot_order[0]);
qemu_register_boot_set(fw_cfg_boot_set, fw_cfg);
return fw_cfg; return fw_cfg;
} }
@ -160,6 +206,9 @@ static void machine_hppa_init(MachineState *machine)
} }
} }
/* register power switch emulation */
qemu_register_powerdown_notifier(&hppa_system_powerdown_notifier);
/* Load firmware. Given that this is not "real" firmware, /* Load firmware. Given that this is not "real" firmware,
but one explicitly written for the emulation, we might as but one explicitly written for the emulation, we might as
well load it directly from an ELF image. */ well load it directly from an ELF image. */
@ -273,6 +322,9 @@ static void machine_hppa_init(MachineState *machine)
/* tell firmware how many SMP CPUs to present in inventory table */ /* tell firmware how many SMP CPUs to present in inventory table */
cpu[0]->env.gr[21] = smp_cpus; cpu[0]->env.gr[21] = smp_cpus;
/* tell firmware fw_cfg port */
cpu[0]->env.gr[19] = FW_CFG_IO_BASE;
} }
static void hppa_machine_reset(MachineState *ms) static void hppa_machine_reset(MachineState *ms)
@ -300,6 +352,8 @@ static void hppa_machine_reset(MachineState *ms)
cpu[0]->env.gr[24] = 'c'; cpu[0]->env.gr[24] = 'c';
/* gr22/gr23 unused, no initrd while reboot. */ /* gr22/gr23 unused, no initrd while reboot. */
cpu[0]->env.gr[21] = smp_cpus; cpu[0]->env.gr[21] = smp_cpus;
/* tell firmware fw_cfg port */
cpu[0]->env.gr[19] = FW_CFG_IO_BASE;
} }

Binary file not shown.

@ -1 +1 @@
Subproject commit 4ff7639e2b86d5775fa7d5cd0dbfa4d3a385a701 Subproject commit 73b740f77190643b2ada5ee97a9a108c6ef2a37b

View File

@ -196,9 +196,12 @@ struct CPUHPPAState {
target_ureg shadow[7]; /* shadow registers */ target_ureg shadow[7]; /* shadow registers */
/* ??? The number of entries isn't specified by the architecture. */ /* ??? The number of entries isn't specified by the architecture. */
#define HPPA_TLB_ENTRIES 256
#define HPPA_BTLB_ENTRIES 0
/* ??? Implement a unified itlb/dtlb for the moment. */ /* ??? Implement a unified itlb/dtlb for the moment. */
/* ??? We should use a more intelligent data structure. */ /* ??? We should use a more intelligent data structure. */
hppa_tlb_entry tlb[256]; hppa_tlb_entry tlb[HPPA_TLB_ENTRIES];
uint32_t tlb_last; uint32_t tlb_last;
}; };

View File

@ -149,9 +149,9 @@ lci 000001 ----- ----- -- 01001100 0 t:5
# Arith/Log # Arith/Log
#### ####
andcm 000010 ..... ..... .... 000000 0 ..... @rrr_cf andcm 000010 ..... ..... .... 000000 - ..... @rrr_cf
and 000010 ..... ..... .... 001000 0 ..... @rrr_cf and 000010 ..... ..... .... 001000 - ..... @rrr_cf
or 000010 ..... ..... .... 001001 0 ..... @rrr_cf or 000010 ..... ..... .... 001001 - ..... @rrr_cf
xor 000010 ..... ..... .... 001010 0 ..... @rrr_cf xor 000010 ..... ..... .... 001010 0 ..... @rrr_cf
uxor 000010 ..... ..... .... 001110 0 ..... @rrr_cf uxor 000010 ..... ..... .... 001110 0 ..... @rrr_cf
ds 000010 ..... ..... .... 010001 0 ..... @rrr_cf ds 000010 ..... ..... .... 010001 0 ..... @rrr_cf
@ -161,13 +161,13 @@ uaddcm_tc 000010 ..... ..... .... 100111 0 ..... @rrr_cf
dcor 000010 ..... 00000 .... 101110 0 ..... @rr_cf dcor 000010 ..... 00000 .... 101110 0 ..... @rr_cf
dcor_i 000010 ..... 00000 .... 101111 0 ..... @rr_cf dcor_i 000010 ..... 00000 .... 101111 0 ..... @rr_cf
add 000010 ..... ..... .... 0110.. 0 ..... @rrr_cf_sh add 000010 ..... ..... .... 0110.. - ..... @rrr_cf_sh
add_l 000010 ..... ..... .... 1010.. 0 ..... @rrr_cf_sh add_l 000010 ..... ..... .... 1010.. 0 ..... @rrr_cf_sh
add_tsv 000010 ..... ..... .... 1110.. 0 ..... @rrr_cf_sh add_tsv 000010 ..... ..... .... 1110.. 0 ..... @rrr_cf_sh
add_c 000010 ..... ..... .... 011100 0 ..... @rrr_cf_sh0 add_c 000010 ..... ..... .... 011100 0 ..... @rrr_cf_sh0
add_c_tsv 000010 ..... ..... .... 111100 0 ..... @rrr_cf_sh0 add_c_tsv 000010 ..... ..... .... 111100 0 ..... @rrr_cf_sh0
sub 000010 ..... ..... .... 010000 0 ..... @rrr_cf sub 000010 ..... ..... .... 010000 - ..... @rrr_cf
sub_tsv 000010 ..... ..... .... 110000 0 ..... @rrr_cf sub_tsv 000010 ..... ..... .... 110000 0 ..... @rrr_cf
sub_tc 000010 ..... ..... .... 010011 0 ..... @rrr_cf sub_tc 000010 ..... ..... .... 010011 0 ..... @rrr_cf
sub_tsv_tc 000010 ..... ..... .... 110011 0 ..... @rrr_cf sub_tsv_tc 000010 ..... ..... .... 110011 0 ..... @rrr_cf