aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHelge Deller <deller@gmx.de>2024-01-17 03:51:16 +0100
committerHelge Deller <deller@gmx.de>2024-01-17 03:51:16 +0100
commite3c3a4630ceb0cc8b9f3e8df4d5a6c29ac690504 (patch)
tree69597dce7f54df5ae685d02c82b2430bd36ae6ca
parent90efa8f7eab67aef1e1a0a5821e75c3239e5da99 (diff)
downloadseabios-hppa-devel-last-for-v16.zip
seabios-hppa-devel-last-for-v16.tar.gz
seabios-hppa-devel-last-for-v16.tar.bz2
Linux boots again on all.devel-last-for-v16
Added fault handler, PDC32 fixes
-rw-r--r--src/parisc/head.S32
-rw-r--r--src/parisc/parisc.c59
2 files changed, 70 insertions, 21 deletions
diff --git a/src/parisc/head.S b/src/parisc/head.S
index e5c3408..b6289b5 100644
--- a/src/parisc/head.S
+++ b/src/parisc/head.S
@@ -249,6 +249,10 @@ $smp_exit_loop:
rsm PSW_I, %r0 /* disable local irqs */
mtctl %r0, CR_EIEM
+ /* Load IVT to detect and report crashes */
+ load32_firmware BOOTADDR(firmware_default_ivt),%r1
+ mtctl %r1, CR_IVA
+
/* provide PDCE_PROC entry in arg0 (required on 64-bit) */
load32 MEM_PDC_ENTRY, %arg0
@@ -295,6 +299,10 @@ $bss_loop:
cmpb,<<,n %r3,%r4,$bss_loop
STREGM %r0,WORD_LEN(%r3)
+ /* Load IVT to detect and report crashes */
+ load32_firmware BOOTADDR(firmware_default_ivt),%r1
+ mtctl %r1, CR_IVA
+
load32_firmware BOOTADDR(start_parisc_firmware),%r3
bv 0(%r3)
copy %r0,%r2
@@ -433,6 +441,20 @@ ENTRY(smp_ivt)
.endr
END(smp_ivt)
+ .align 32
+ENTRY(firmware_default_ivt) /* to detect crashes */
+ .set loop,0
+ .import firmware_fault_handler,code
+ .rept 32
+ .align 32
+ load32_firmware firmware_fault_handler,%arg0
+ loadgp
+ bv 0(%arg0)
+ ldi loop,%arg0
+ .set loop,loop+1
+ .endr
+END(smp_ivt)
+
/*******************************************************
PDC and IODC entry
@@ -475,6 +497,7 @@ ENTRY(pdc_entry_32) /* 32-bit PDC */
loadgp
load32 MEM_PDC_ENTRY + 1f - pdc_entry_table,%rp
load32 parisc_pdc_entry, %r1
+ clear_PSW_W
bv 0(%r1)
ldo FRAME_SIZE(%sp),%sp
1:
@@ -553,10 +576,15 @@ c64_32_return:
cmpb,=,n %r1,%r0,5f /* skip copy results */
#endif
- cmpib,>=,n 15,%arg2,5f /* skip copy results if target buffer in PAGE0 */
+ cmpb,=,n %r0,%arg2,5f /* skip copy results if target buffer is NULL */
+ cmpb,< %ret0,%r0,5f /* skip copy results if return value was negative (=error) */
+ ldi MEM_PDC_ENTRY,%r1
+ cmpb,>=,n %arg2,%r1,convert_ret64_buffer /* copy results if target buffer >= MEM_PDC_ENTRY */
+ b,n .
+ .word 0xfffdead0 /* immediately halt the emulator */
+convert_ret64_buffer:
/* copy 64-bit-wide PDC result to 32-bit wide results */
- /* TODO?: skip copy results if return value was < 0 */
ldi 32,%r1
copy %arg2,%arg3
.L1: ldd,ma 8(%arg2),%arg1
diff --git a/src/parisc/parisc.c b/src/parisc/parisc.c
index c502d07..f46b9d9 100644
--- a/src/parisc/parisc.c
+++ b/src/parisc/parisc.c
@@ -67,6 +67,9 @@ char cpu_bit_width;
#define COMPAT_VAL(val) ((long)(int)(val)) // (is_compat_mode() ? (long)(int)(val) : (val))
+/* Do not write back result buffer in compat mode */
+#define NO_COMPAT_RETURN_VALUE(res) { res = 0; }
+
u8 BiosChecksum;
char zonefseg_start, zonefseg_end; // SYMBOLS
@@ -244,6 +247,14 @@ void __VISIBLE __noreturn reset(void)
while (1);
}
+void __VISIBLE __noreturn firmware_fault_handler(unsigned long fault)
+{
+ printf("\n***************************\n"
+ "SeaBIOS: Detected trap #%lu, at 0x%lx:0x%lx, IIR=0x%lx, IOR addr=0x%lx:0x%lx\n", fault,
+ mfctl(17), mfctl(18), mfctl(19), mfctl(20), mfctl(21));
+ while (1) { asm("or %r10,%r10,%r10"); };
+}
+
#undef BUG_ON
#define BUG_ON(cond) \
if (unlikely(cond)) { \
@@ -1120,7 +1131,6 @@ int __VISIBLE parisc_iodc_ENTRY_IO(unsigned int *arg FUNC_MANY_ARGS)
struct disk_op_s disk_op;
dev = find_hpa_device(hpa);
-printf("HPA = %lx dev %p\n", hpa, dev);
if (!dev) {
BUG_ON(1);
@@ -1416,9 +1426,8 @@ static int pdc_chassis(unsigned long *arg)
case PDC_CHASSIS_DISP:
ARG3 = ARG2;
/* WARNING: Avoid copyig the 64-bit result array to ARG2 */
- ARG2 = 0; /* do not write back in compat mode */
+ NO_COMPAT_RETURN_VALUE(ARG2);
result = (unsigned long *)&ARG4; // do not write to ARG2, use &ARG4 instead
- printf("\nPDC_CHASSIS: %p ARG3 = %lx\n", result, ARG3);
// fall through
case PDC_CHASSIS_DISPWARN:
ARG4 = (ARG3 >> 17) & 7;
@@ -1631,7 +1640,6 @@ static int pdc_hpa(unsigned long *arg)
switch (option) {
case PDC_HPA_PROCESSOR:
hpa = mfctl(CPU_HPA_CR_REG); /* get CPU HPA from cr7 */
-printf("HPA = %lx\n", hpa);
i = index_of_CPU_HPA(hpa);
BUG_ON(i < 0 || i >= smp_cpus); /* ARGH, someone modified cr7! */
result[0] = hpa; /* CPU_HPA */
@@ -1678,7 +1686,7 @@ static int pdc_iodc(unsigned long *arg)
// dev = find_hpa_device(hpa);
// searches for 0xf1041000
dev = find_hppa_device_by_hpa(hpa);
- printf("pdc_iodc found dev %p\n", dev);
+ // printf("pdc_iodc found dev %p\n", dev);
if (!dev)
return -4; // not found
@@ -1704,10 +1712,10 @@ static int pdc_iodc(unsigned long *arg)
memcpy((void*) ARG5, &iodc_entry, *result);
c = (unsigned char *) &iodc_entry_table;
/* calculate offset into jump table. */
- entry_len = &iodc_entry_table_one_entry - &iodc_entry[0];
+ entry_len = &iodc_entry_table_one_entry - &iodc_entry_table;
c += (ARG4 - PDC_IODC_RI_INIT) * entry_len;
memcpy((void*) ARG5, c, entry_len);
- printf("\n\nSeaBIOS: Info PDC_IODC function OK\n");
+ // printf("\n\nSeaBIOS: Info PDC_IODC function OK\n");
flush_data_cache((char*)ARG5, *result);
return PDC_OK;
break;
@@ -1765,19 +1773,23 @@ static int pdc_stable(unsigned long *arg)
if ((ARG2 + ARG4) > STABLE_STORAGE_SIZE)
return PDC_INVALID_ARG;
memcpy((unsigned char *) ARG3, &stable_storage[ARG2], ARG4);
+ NO_COMPAT_RETURN_VALUE(ARG2);
return PDC_OK;
case PDC_STABLE_WRITE:
if ((ARG2 + ARG4) > STABLE_STORAGE_SIZE)
return PDC_INVALID_ARG;
memcpy(&stable_storage[ARG2], (unsigned char *) ARG3, ARG4);
+ NO_COMPAT_RETURN_VALUE(ARG2);
return PDC_OK;
case PDC_STABLE_RETURN_SIZE:
result[0] = STABLE_STORAGE_SIZE;
return PDC_OK;
case PDC_STABLE_VERIFY_CONTENTS:
+ NO_COMPAT_RETURN_VALUE(ARG2);
return PDC_OK;
case PDC_STABLE_INITIALIZE:
init_stable_storage();
+ NO_COMPAT_RETURN_VALUE(ARG2);
return PDC_OK;
}
return PDC_BAD_OPTION;
@@ -1793,19 +1805,23 @@ static int pdc_nvolatile(unsigned long *arg)
if ((ARG2 + ARG4) > NVOLATILE_STORAGE_SIZE)
return PDC_INVALID_ARG;
memcpy((unsigned char *) ARG3, &nvolatile_storage[ARG2], ARG4);
+ NO_COMPAT_RETURN_VALUE(ARG2);
return PDC_OK;
case PDC_NVOLATILE_WRITE:
if ((ARG2 + ARG4) > NVOLATILE_STORAGE_SIZE)
return PDC_INVALID_ARG;
memcpy(&nvolatile_storage[ARG2], (unsigned char *) ARG3, ARG4);
+ NO_COMPAT_RETURN_VALUE(ARG2);
return PDC_OK;
case PDC_NVOLATILE_RETURN_SIZE:
result[0] = NVOLATILE_STORAGE_SIZE;
return PDC_OK;
case PDC_NVOLATILE_VERIFY_CONTENTS:
+ NO_COMPAT_RETURN_VALUE(ARG2);
return PDC_OK;
case PDC_NVOLATILE_INITIALIZE:
memset(nvolatile_storage, 0, sizeof(nvolatile_storage));
+ NO_COMPAT_RETURN_VALUE(ARG2);
return PDC_OK;
}
return PDC_BAD_OPTION;
@@ -1814,23 +1830,25 @@ static int pdc_nvolatile(unsigned long *arg)
static int pdc_add_valid(unsigned long *arg)
{
unsigned long option = ARG1;
+ unsigned long arg2 = is_compat_mode() ? COMPAT_VAL(ARG2) : ARG2;
- // dprintf(0, "\n\nSeaBIOS: PDC_ADD_VALID function %ld ARG2=%x called.\n", option, ARG2);
+ NO_COMPAT_RETURN_VALUE(ARG2);
+ // dprintf(0, "\n\nSeaBIOS: PDC_ADD_VALID function %ld arg2=%x called.\n", option, arg2);
if (option != 0)
return PDC_BAD_OPTION;
- if (0 && ARG2 == 0) // should PAGE0 be valid? HP-UX asks for it, but maybe due a bug in our code...
+ if (0 && arg2 == 0) // should PAGE0 be valid? HP-UX asks for it, but maybe due a bug in our code...
return 1;
- // if (ARG2 < PAGE_SIZE) return PDC_ERROR;
- if (ARG2 < ram_size)
+ // if (arg2 < PAGE_SIZE) return PDC_ERROR;
+ if (arg2 < ram_size)
return PDC_OK;
- if (ARG2 >= (unsigned long)_sti_rom_start &&
- ARG2 <= (unsigned long)_sti_rom_end)
+ if (arg2 >= (unsigned long)_sti_rom_start &&
+ arg2 <= (unsigned long)_sti_rom_end)
return PDC_OK;
- if (ARG2 < FIRMWARE_END)
+ if (arg2 < FIRMWARE_END)
return 1;
- if (ARG2 <= 0xffffffff)
+ if (arg2 <= 0xffffffff)
return PDC_OK;
- dprintf(0, "\n\nSeaBIOS: FAILED!!!! PDC_ADD_VALID function %ld ARG2=%lx called.\n", option, ARG2);
+ dprintf(0, "\n\nSeaBIOS: FAILED!!!! PDC_ADD_VALID function %ld arg2=%lx called.\n", option, arg2);
return PDC_REQ_ERR_0; /* Operation completed with a requestor bus error. */
}
@@ -1951,6 +1969,7 @@ static int pdc_psw(unsigned long *arg)
mtctl(psw_defaults, CR_PSW_DEFAULT);
/* let model know that we support 64-bit */
current_machine->pdc_model.width = (psw_defaults & PDC_PSW_WIDE_BIT) ? 1 : 0;
+ NO_COMPAT_RETURN_VALUE(ARG2);
}
return PDC_OK;
}
@@ -1989,7 +2008,8 @@ static int pdc_system_map(unsigned long *arg)
result[0] = dev->mod_info->mod_addr; // for PDC_IODC
result[1] = dev->mod_info->mod_pgs;
result[2] = dev->num_addr; // dev->mod_info->add_addr;
- dprintf(1, "PDC_FIND_MODULE %lx %ld %ld \n", result[0], result[1],result[2]);
+ if (0)
+ dprintf(1, "PDC_FIND_MODULE %lx %ld %ld \n", result[0], result[1],result[2]);
return PDC_OK;
@@ -2311,7 +2331,7 @@ int __VISIBLE parisc_pdc_entry(unsigned long *arg FUNC_MANY_ARGS)
if (pdc_debug & DEBUG_PDC) {
printf("\nSeaBIOS: Start PDC%d proc %s(%ld) option %ld result=0x%lx ARG3=0x%lx %s ",
- is_compat_mode() ? 32 : 64, pdc_name(ARG0), ARG0, ARG1, ARG2, ARG3,
+ (!is_64bit_PDC() || is_compat_mode()) ? 32 : 64, pdc_name(ARG0), ARG0, ARG1, ARG2, ARG3,
(proc == PDC_IODC)?hpa_name(ARG3):"");
printf("ARG4=0x%lx ARG5=0x%lx ARG6=0x%lx ARG7=0x%lx\n", ARG4, ARG5, ARG6, ARG7);
}
@@ -2996,10 +3016,11 @@ void __VISIBLE start_parisc_firmware(void)
firmware_width_locked = 1;
psw_defaults = PDC_PSW_ENDIAN_BIT;
- if (is_64bit_CPU() && 0) {
+ if (0 && is_64bit_PDC()) {
/* enable 64-bit PSW by default */
psw_defaults |= PDC_PSW_WIDE_BIT;
current_machine->pdc_model.width = 1;
+ firmware_width_locked = 0;
}
mtctl(psw_defaults, CR_PSW_DEFAULT);