diff options
author | Helge Deller <deller@gmx.de> | 2023-10-17 11:16:29 +0200 |
---|---|---|
committer | Helge Deller <deller@gmx.de> | 2023-10-31 08:26:22 +0100 |
commit | 7449a316243d5e62f135a53c32e9af1e21419c02 (patch) | |
tree | fdc05f4410bf89defa9a57543ffa8df7458c4f20 | |
parent | 63a9007616f3a570b1ceef4a4fa3cdf4cf278d38 (diff) | |
download | seabios-hppa-7449a316243d5e62f135a53c32e9af1e21419c02.zip seabios-hppa-7449a316243d5e62f135a53c32e9af1e21419c02.tar.gz seabios-hppa-7449a316243d5e62f135a53c32e9af1e21419c02.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.h | 1 | ||||
-rw-r--r-- | src/parisc/parisc.c | 21 |
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; |