aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHelge Deller <deller@gmx.de>2023-10-17 11:16:29 +0200
committerHelge Deller <deller@gmx.de>2023-10-17 11:16:29 +0200
commit9c80be3ce1dc98d017d9cc6af41031ed6098ebbf (patch)
treefdc05f4410bf89defa9a57543ffa8df7458c4f20
parent84f4c0fb5c6dd9396cbadb532068f9fb34982527 (diff)
downloadseabios-hppa-9c80be3ce1dc98d017d9cc6af41031ed6098ebbf.zip
seabios-hppa-9c80be3ce1dc98d017d9cc6af41031ed6098ebbf.tar.gz
seabios-hppa-9c80be3ce1dc98d017d9cc6af41031ed6098ebbf.tar.bz2
parisc: Fully implement PDC_PSW for 64-bit CPUs
PDC_PSW tells the hardware how the default PSW is implemented. The w field indicates the default width of the processor. The w field also determines whether the External Interrupt Request (EIR) register is treated as a right-justified 32-bit register or a full 64-bit register. The e field indicates the default endianness of the processor. Both bits determine how the PSW W-bit and E-bit will be set on an interruption. Signed-off-by: Helge Deller <deller@gmx.de>
-rw-r--r--src/parisc/hppa_hardware.h1
-rw-r--r--src/parisc/parisc.c21
2 files changed, 18 insertions, 4 deletions
diff --git a/src/parisc/hppa_hardware.h b/src/parisc/hppa_hardware.h
index cc6b261..f74e770 100644
--- a/src/parisc/hppa_hardware.h
+++ b/src/parisc/hppa_hardware.h
@@ -46,6 +46,7 @@
#define HPPA_MAX_CPUS 16 /* max. number of SMP CPUs */
#define CPU_CLOCK_MHZ 250 /* emulate a 250 MHz CPU */
+#define CR_PSW_DEFAULT 6 /* used by SeaBIOS & QEMU for default PSW */
#define CPU_HPA_CR_REG 7 /* store CPU HPA in cr7 (SeaBIOS internal) */
#define PIM_STORAGE_SIZE 600 /* storage size of pdc_pim_toc_struct (64bit) */
diff --git a/src/parisc/parisc.c b/src/parisc/parisc.c
index 11b433f..679cf81 100644
--- a/src/parisc/parisc.c
+++ b/src/parisc/parisc.c
@@ -133,6 +133,8 @@ unsigned long hppa_port_pci_data = (PCI_HPA + DINO_CONFIG_DATA);
unsigned int show_boot_menu;
unsigned int interact_ipl;
+static unsigned long psw_defaults;
+
unsigned long PORT_QEMU_CFG_CTL;
unsigned int tlb_entries = 256;
@@ -1739,19 +1741,27 @@ static int pdc_mem(unsigned int *arg)
static int pdc_psw(unsigned int *arg)
{
- static unsigned long psw_defaults = PDC_PSW_ENDIAN_BIT;
unsigned long option = ARG1;
unsigned long *result = (unsigned long *)ARG2;
+ unsigned long mask;
+
+ if (cpu_bit_width == 64)
+ mask = PDC_PSW_WIDE_BIT | PDC_PSW_ENDIAN_BIT;
+ else
+ mask = PDC_PSW_ENDIAN_BIT;
if (option > PDC_PSW_SET_DEFAULTS)
return PDC_BAD_OPTION;
- /* FIXME: For 64bit support enable PDC_PSW_WIDE_BIT too! */
if (option == PDC_PSW_MASK)
- *result = PDC_PSW_ENDIAN_BIT;
+ *result = mask;
if (option == PDC_PSW_GET_DEFAULTS)
*result = psw_defaults;
if (option == PDC_PSW_SET_DEFAULTS) {
- psw_defaults = ARG2;
+ psw_defaults = ARG2 & mask;
+ /* we do not yet support little endian mode */
+ BUG_ON((psw_defaults & PDC_PSW_ENDIAN_BIT) == 0);
+ /* tell qemu the default mask */
+ mtctl(psw_defaults, CR_PSW_DEFAULT);
}
return PDC_OK;
}
@@ -2666,6 +2676,9 @@ void __VISIBLE start_parisc_firmware(void)
asm(".word 0x016048a0 + 1 ! copy %%r1,%0\n" : "=r" (i): : "r1");
cpu_bit_width = (i == 63) ? 64 : 32;
+ psw_defaults = PDC_PSW_ENDIAN_BIT;
+ mtctl(psw_defaults, CR_PSW_DEFAULT);
+
if (smp_cpus > HPPA_MAX_CPUS)
smp_cpus = HPPA_MAX_CPUS;
num_online_cpus = smp_cpus;