diff options
author | Helge Deller <deller@gmx.de> | 2023-10-22 09:36:53 +0200 |
---|---|---|
committer | Helge Deller <deller@gmx.de> | 2023-10-22 09:36:53 +0200 |
commit | edb1c29da0df2c33e62305d1c1c71a4cbd6bff67 (patch) | |
tree | 7679aff1450332749e413b5f962a50a9fe427f56 | |
parent | ff162afa8a2d697d71f120ad1322233d9ace9545 (diff) | |
download | seabios-hppa-edb1c29da0df2c33e62305d1c1c71a4cbd6bff67.zip seabios-hppa-edb1c29da0df2c33e62305d1c1c71a4cbd6bff67.tar.gz seabios-hppa-edb1c29da0df2c33e62305d1c1c71a4cbd6bff67.tar.bz2 |
parisc: Save and restore current PSW_W across PDC call
When called from a 64-bit kernel, pdc_psw may be called with
PSW.W set, so save and restore it during the call.
Signed-off-by: Helge Deller <deller@gmx.de>
-rw-r--r-- | src/parisc/head.S | 15 | ||||
-rw-r--r-- | src/parisc/parisc.c | 9 |
2 files changed, 19 insertions, 5 deletions
diff --git a/src/parisc/head.S b/src/parisc/head.S index 53b3ddd..7bc7c09 100644 --- a/src/parisc/head.S +++ b/src/parisc/head.S @@ -353,6 +353,7 @@ ENTRY(pdc_entry) stw %arg1,-40(%sp) stw %arg2,-44(%sp) stw %arg3,-48(%sp) + stw %r31,-52(%sp) /* store PSW_W */ ldo -FRAME_SIZE(%sp),%arg0 loadgp @@ -361,13 +362,25 @@ ENTRY(pdc_entry) ldo -FRAME_SIZE(%sp),%sp ldw -20(%sp),%rp - bv %r0(%rp) ldw -32(%sp),%dp + ldw -52(%sp),%r31 + load32 0x8000000,%r1 /* mask PSW_W */ + and,= %r31,%r1,%r0 + bv %r0(%rp) /* return without setting PSW_W */ + nop + bv %r0(%rp) /* return with setting PSW_W */ + .level 2.0 + ssm PSW_W_SM,%r0 + .level 1.1 END(pdc_entry) /* pdc_entry_table will be copied into low memory. */ ENTRY(pdc_entry_table) load32 pdc_entry,%r1 + ;! nuke the W bit + .level 2.0 + rsm PSW_W_SM, %r31 + .level 1.1 bv,n %r0(%r1) END(pdc_entry_table) diff --git a/src/parisc/parisc.c b/src/parisc/parisc.c index cc55133..98e86f5 100644 --- a/src/parisc/parisc.c +++ b/src/parisc/parisc.c @@ -141,7 +141,7 @@ unsigned int tlb_entries = 256; #define PARISC_SERIAL_CONSOLE PORT_SERIAL1 extern char pdc_entry; -extern char pdc_entry_table[12]; +extern char pdc_entry_table[4*4]; extern char iodc_entry[512]; extern char iodc_entry_table[14*4]; @@ -1759,7 +1759,7 @@ static int pdc_psw(unsigned int *arg) if (option == PDC_PSW_SET_DEFAULTS) { psw_defaults = ARG2 & mask; /* we do not yet support little endian mode */ - BUG_ON((psw_defaults & PDC_PSW_ENDIAN_BIT) == 0); + BUG_ON((psw_defaults & PDC_PSW_ENDIAN_BIT) == 1); /* tell qemu the default mask */ mtctl(psw_defaults, CR_PSW_DEFAULT); } @@ -2677,6 +2677,7 @@ void __VISIBLE start_parisc_firmware(void) cpu_bit_width = (i == 63) ? 64 : 32; psw_defaults = PDC_PSW_ENDIAN_BIT; + /* if (cpu_bit_width == 64) psw_defaults |= PDC_PSW_WIDE_BIT; */ mtctl(psw_defaults, CR_PSW_DEFAULT); if (smp_cpus > HPPA_MAX_CPUS) @@ -2767,8 +2768,8 @@ void __VISIBLE start_parisc_firmware(void) /* memset((void*)PAGE0, 0, sizeof(*PAGE0)); */ /* copy pdc_entry entry into low memory. */ - memcpy((void*)MEM_PDC_ENTRY, &pdc_entry_table, 3*4); - flush_data_cache((char*)MEM_PDC_ENTRY, 3*4); + memcpy((void*)MEM_PDC_ENTRY, &pdc_entry_table, 4*4); + flush_data_cache((char*)MEM_PDC_ENTRY, 4*4); PAGE0->memc_cont = ram_size; PAGE0->memc_phsize = ram_size; |