diff options
author | Helge Deller <deller@gmx.de> | 2024-01-15 14:52:53 +0100 |
---|---|---|
committer | Helge Deller <deller@gmx.de> | 2024-01-15 14:52:53 +0100 |
commit | c7a6383b20418dda3eeaa4cefbb431fd3521c6fd (patch) | |
tree | ed3babe41a37fdd6ef1d5097d9e3bfd6611ae0a8 | |
parent | 2bce3fc3fa5b05d36e470571b971506586ab454e (diff) | |
download | seabios-hppa-c7a6383b20418dda3eeaa4cefbb431fd3521c6fd.zip seabios-hppa-c7a6383b20418dda3eeaa4cefbb431fd3521c6fd.tar.gz seabios-hppa-c7a6383b20418dda3eeaa4cefbb431fd3521c6fd.tar.bz2 |
erster boot schritt vorwärts
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | src/parisc/head.S | 203 | ||||
-rw-r--r-- | src/parisc/parisc.c | 35 |
3 files changed, 186 insertions, 54 deletions
@@ -107,7 +107,7 @@ parisc: FORCE ifneq "$(CONFIG_PARISC)" "y" @echo "ERROR: run 'make config' and select PA-RISC before building the parisc target." endif - # DIRS="" OUT=out/ BITS=32 BIT_SUFFIX="" CROSS_PREFIX=hppa-linux-gnu- $(MAKE) -f Makefile.parisc all + DIRS="" OUT=out/ BITS=32 BIT_SUFFIX="" CROSS_PREFIX=hppa-linux-gnu- $(MAKE) -f Makefile.parisc all DIRS="" OUT=out-64/ BITS=64 BIT_SUFFIX="64" CROSS_PREFIX=hppa64-linux-gnu- $(MAKE) -f Makefile.parisc all # Make definitions diff --git a/src/parisc/head.S b/src/parisc/head.S index a9ecce7..bb16f5b 100644 --- a/src/parisc/head.S +++ b/src/parisc/head.S @@ -77,6 +77,7 @@ name: #define ANDCM andcm,* #define COND(x) * ## x #define FRAME_SIZE 128 +#define FRAME_SIZE32 64 #define CALLEE_REG_FRAME_SIZE 144 #define ASM_ULONG_INSN .dword #define WORD_LEN 8 @@ -421,6 +422,45 @@ END(smp_ivt) PDC and IODC entry *******************************************************/ +/* pdc_entry_table will be copied into low memory. */ +ENTRY(pdc_entry_table) +#ifdef CONFIG_64BIT + /* see section "Testing the Current State of the PSW W-Bit", + page I-2 in parisc2 spec */ + addb,*>,n %r0,%r0,pdc_called_narrow /* branch if narrow addressing */ + +pdc_called_wide: + /* we know that PDC was called with PSW.W=1 */ + load32_firmware pdc_entry_64_64,%r1 + bv,n %r0(%r1) + +pdc_called_narrow: + /* we know that PDC was called with PSW.W=0 */ + load32 MEM_PDC_ENTRY + pdc_entry_64_32 - pdc_entry_table,%r1 + bv 0(%r1) + set_PSW_W /* enable PSW.W */ +#else +ENTRY(pdc_entry_32) /* 32-bit PDC */ + stw %rp,-20(%sp) + stw %dp,-32(%sp) + stw %arg0,-36(%sp) + stw %arg1,-40(%sp) + stw %arg2,-44(%sp) + stw %arg3,-48(%sp) + ldo -FRAME_SIZE(%sp),%arg0 + + loadgp + b,l parisc_pdc_entry, %rp + ldo FRAME_SIZE(%sp),%sp + + ldo -FRAME_SIZE(%sp),%sp + ldw -20(%sp),%rp + ldw -32(%sp),%dp + bv,n %r0(%rp) +END(pdc_entry_32) +#endif +END(pdc_entry_table) + #ifdef CONFIG_64BIT ENTRY(pdc_entry_64_32) /* 32-bit call on 64-bit PDC */ /* clear upper bits */ @@ -432,7 +472,7 @@ ENTRY(pdc_entry_64_32) /* 32-bit call on 64-bit PDC */ depdi 0, 31, 32, %r21 depdi 0, 31, 32, %r20 depdi 0, 31, 32, %r19 -ENTRY(pdc_entry_64_64) /* 64-bit call on 64-bit PDC */ + std %rp,-0x10(%sp) stw %dp,-0x18(%sp) std %arg0,-0x20(%sp) @@ -446,59 +486,57 @@ ENTRY(pdc_entry_64_64) /* 64-bit call on 64-bit PDC */ ldo -0x58(%sp),%arg0 /* points to arg7 */ loadgp - b,l parisc_pdc_entry, %rp + load32_firmware parisc_pdc_entry,%r1 + load32 MEM_PDC_ENTRY + 2f - pdc_entry_table,%rp + bv 0(%r1) ldo FRAME_SIZE(%sp),%sp +2: /* return from PDC call */ ldo -FRAME_SIZE(%sp),%sp + /* copy 64-bit-wide PDC result to 32-bit wide results */ + ldi 32,%r1 + ldd -0x30(%sp),%arg2 + copy %arg2,%arg3 +3: ldd 0(%arg2),%arg1 + ldo 8(%arg2),%arg2 + stw %arg1, 0(%arg3) + ldo 4(%arg1),%arg1 + ldo -1(%r1),%r1 + cmpb,>>,n %r1,%r0,3b + ldd -0x10(%sp),%rp ldd -0x18(%sp),%dp bv,n %r0(%rp) -END(pdc_entry_64_32) -#else -ENTRY(pdc_entry_32) /* 32-bit PDC */ - stw %rp,-20(%sp) - stw %dp,-32(%sp) - stw %arg0,-36(%sp) - stw %arg1,-40(%sp) - stw %arg2,-44(%sp) - stw %arg3,-48(%sp) - ldo -FRAME_SIZE(%sp),%arg0 + +ENTRY(pdc_entry_64_64) /* 64-bit call on 64-bit PDC */ + std %rp,-0x10(%sp) + stw %dp,-0x18(%sp) + std %arg0,-0x20(%sp) + std %arg1,-0x28(%sp) + std %arg2,-0x30(%sp) + std %arg3,-0x38(%sp) + std %r22, -0x40(%sp) + std %r21, -0x48(%sp) + std %r20, -0x50(%sp) + std %r19, -0x58(%sp) + ldo -0x58(%sp),%arg0 /* points to arg7 */ loadgp b,l parisc_pdc_entry, %rp ldo FRAME_SIZE(%sp),%sp ldo -FRAME_SIZE(%sp),%sp - ldw -20(%sp),%rp - ldw -32(%sp),%dp + ldd -0x10(%sp),%rp + ldd -0x18(%sp),%dp bv,n %r0(%rp) -END(pdc_entry_32) +END(pdc_entry_64_32) #endif -/* pdc_entry_table will be copied into low memory. */ -ENTRY(pdc_entry_table) -#ifdef CONFIG_64BIT - /* see section "Testing the Current State of the PSW W-Bit", - page I-2 in parisc2 spec */ - addb,*>,n %r0,%r0,pdc_called_narrow /* branch if narrow addressing */ - /* we know that PDC was called with PSW.W=1 */ - load32_firmware pdc_entry_64_64,%r1 - bv,n %r0(%r1) -pdc_called_narrow: - /* we know that PDC was called with PSW.W=0 */ - set_PSW_W /* enable PSW.W */ - load32_firmware pdc_entry_64_32,%r1 - bv,n %r0(%r1) -#else - load32_firmware pdc_entry_32,%r1 /* entry of 32-bit PDC */ - bv,n %r0(%r1) -#endif -pdc_entry_table_end: - .export pdc_entry_table_end -END(pdc_entry_table) ENTRY(iodc_entry_table) load32 parisc_iodc_ENTRY_INIT, %r1 +iodc_entry_table_one_entry: + .export iodc_entry_table_one_entry load32 parisc_iodc_ENTRY_IO, %r1 load32 parisc_iodc_ENTRY_SPA, %r1 load32 parisc_iodc_ENTRY_CONFIG, %r1 @@ -507,9 +545,89 @@ ENTRY(iodc_entry_table) load32 parisc_iodc_ENTRY_TLB, %r1 END(iodc_entry_table) +/* the code for iodc_entry[] will be copied to user. + the first load32* wil be replaced by an entry from + the iodc_entry_table[] table above. */ ENTRY(iodc_entry) + /* this first call we be replaced at runtime: */ load32 parisc_iodc_ENTRY_IO, %r1 +#ifdef CONFIG_64BIT + addb,*>,n %r0,%r0,iodc_narrow /* branch if narrow addressing */ + nop +#if 1 + // HALT + load32_firmware hlt,%r1 + bv,n %r0(%r1) +#endif + b,n iodc_wide + +// ./qemu-system-hppa -drive file=../qemu-images/hdd.img -kernel vmlinux64 -append "root=/dev/sda5 console=ttyS0" -serial mon:stdio -smp cpus=1 -machine C3700 -nographic -snapshot -fw_cfg opt/pdc_debug,string=255 -bios ../seabios-hppa/out-64/hppa-firmware64.img -dfilter 0xf0000ae0..0xf0000b00 -d in_asm,cpu 2>&1| tee L +// ./qemu-system-hppa -drive file=../qemu-images/hdd.img -kernel vmlinux32 -append "root=/dev/sda5 console=ttyS0" -serial mon:stdio -smp cpus=1 -machine C3700 -nographic -snapshot -bios ../seabios-hppa/out/hppa-firmware.img # -dfilter 0x00004800..0x00004900 -d in_asm,cpu 2>&1| tee L + +iodc_narrow: + /* we run narrow, but want wide! Jump to firmware to set PSW.W=1 */ + stw %r1,-20(%sp) /* temporarily store r1 */ + + /* Switch to wide mode. */ +#if 0 +1: mfia %r1 + ldo 2f-1b(%r1),%r1 + depdi 0,31,32,%r1 +#else + load32 MEM_PDC_ENTRY + 2f - pdc_entry_table,%r1 +#endif + bv 0(%r1) + set_PSW_W +2: /* now in wide mode, running in low memory */ + depdi 0, 31, 32, %sp + ldw -20(%sp),%r1 /* restore r1 */ + load_fw_upper32 %r1 + + stw %rp,-20(%sp) + stw %dp,-32(%sp) + stw %arg0,-36(%sp) + stw %arg1,-40(%sp) + stw %arg2,-44(%sp) + stw %arg3,-48(%sp) + ldo -FRAME_SIZE32(%sp),%arg0 + loadgp + load32 MEM_PDC_ENTRY + .iodc_ret32 - pdc_entry_table,%rp + bv %r0(%r1) + ldo 2*FRAME_SIZE(%sp),%sp +.iodc_ret32: + ldo -2*FRAME_SIZE(%sp),%sp + ldw -20(%sp),%rp + ldw -32(%sp),%dp + bv %r0(%rp) + clear_PSW_W + /* END for 32-bit IODC call */ + +iodc_narrow_jump_to_firmware: + /* clear upper bits */ + depdi 0, 31, 32, %rp + depdi 0, 31, 32, %dp + depdi 0, 31, 32, %arg0 + depdi 0, 31, 32, %arg1 + depdi 0, 31, 32, %arg2 + depdi 0, 31, 32, %arg3 + depdi 0, 31, 32, %r22 + depdi 0, 31, 32, %r21 + depdi 0, 31, 32, %r20 + depdi 0, 31, 32, %r19 +iodc_wide: + std %rp,-0x10(%sp) + std %dp,-0x18(%sp) + std %arg0,-0x20(%sp) + std %arg1,-0x28(%sp) + std %arg2,-0x30(%sp) + std %arg3,-0x38(%sp) + std %r22, -0x40(%sp) + std %r21, -0x48(%sp) + std %r20, -0x50(%sp) + std %r19, -0x58(%sp) + ldo -0x58(%sp),%arg0 /* points to arg7 */ +#else stw %rp,-20(%sp) stw %dp,-32(%sp) stw %arg0,-36(%sp) @@ -517,6 +635,7 @@ ENTRY(iodc_entry) stw %arg2,-44(%sp) stw %arg3,-48(%sp) ldo -FRAME_SIZE(%sp),%arg0 +#endif loadgp load32 .iodc_ret, %rp @@ -524,11 +643,21 @@ ENTRY(iodc_entry) ldo FRAME_SIZE(%sp),%sp .iodc_ret: ldo -FRAME_SIZE(%sp),%sp +#ifdef CONFIG_64BIT + ldd -0x10(%sp),%rp + ldd -0x18(%sp),%dp +#else ldw -20(%sp),%rp ldw -32(%sp),%dp - bv,n %r0(%rp) +#endif + bv %r0(%rp) + clear_PSW_W END(iodc_entry) +/* PDC is copied up until here: */ +pdc_entry_table_end: + .export pdc_entry_table_end + /**************************************************************** * Rom Header for VGA / STI ****************************************************************/ diff --git a/src/parisc/parisc.c b/src/parisc/parisc.c index 4e35919..7544171 100644 --- a/src/parisc/parisc.c +++ b/src/parisc/parisc.c @@ -152,7 +152,8 @@ extern char pdc_entry; extern char pdc_entry_table; extern char pdc_entry_table_end; extern char iodc_entry[512]; -extern char iodc_entry_table[14*4]; +extern char iodc_entry_table; +extern char iodc_entry_table_one_entry; /* args as handed over for firmware calls */ #define ARG0 arg[7-0] @@ -1080,7 +1081,8 @@ static char parisc_getchar(void) void iodc_log_call(unsigned int *arg, const char *func) { if (pdc_debug & DEBUG_IODC) { - printf("\nIODC %s called: hpa=0x%x (%s) option=0x%x arg2=0x%x arg3=0x%x ", func, ARG0, hpa_name(ARG0), ARG1, ARG2, ARG3); + printf("\nIODC %s called: hpa=0x%x (%s) option=0x%x arg2=0x%x arg3=0x%x ", + func, ARG0, hpa_name(ARG0), ARG1, ARG2, ARG3); printf("result=0x%x arg5=0x%x arg6=0x%x arg7=0x%x\n", ARG4, ARG5, ARG6, ARG7); } } @@ -1094,7 +1096,7 @@ int __VISIBLE parisc_iodc_ENTRY_IO(unsigned int *arg FUNC_MANY_ARGS) { unsigned long hpa = ARG0; unsigned long option = ARG1; - unsigned long *result = (unsigned long *)ARG4; + unsigned int *result = (unsigned int *)ARG4; hppa_device_t *dev; int ret, len; char *c; @@ -1103,6 +1105,7 @@ int __VISIBLE parisc_iodc_ENTRY_IO(unsigned int *arg FUNC_MANY_ARGS) dev = find_hpa_device(hpa); if (!dev) { +printf("HPA = %lx\n", hpa); BUG_ON(1); return PDC_INVALID_ARG; } @@ -1266,7 +1269,7 @@ int __VISIBLE parisc_iodc_ENTRY_TEST(unsigned int *arg FUNC_MANY_ARGS) { unsigned long hpa = ARG0; unsigned long option = ARG1; - unsigned long *result = (unsigned long *)ARG4; + unsigned int *result = (unsigned int *)ARG4; hppa_device_t *dev; iodc_log_call(arg, __FUNCTION__); @@ -1295,7 +1298,7 @@ int __VISIBLE parisc_iodc_ENTRY_TEST(unsigned int *arg FUNC_MANY_ARGS) int __VISIBLE parisc_iodc_ENTRY_TLB(unsigned int *arg FUNC_MANY_ARGS) { unsigned long option = ARG1; - unsigned long *result = (unsigned long *)ARG4; + unsigned int *result = (unsigned int *)ARG4; iodc_log_call(arg, __FUNCTION__); @@ -1641,7 +1644,7 @@ static int pdc_iodc(unsigned long *arg) { unsigned long option = ARG1; unsigned long *result = (unsigned long *)ARG2; - unsigned long hpa; + unsigned long hpa, entry_len; hppa_device_t *dev; struct pdc_iodc *iodc_p; unsigned char *c; @@ -1679,9 +1682,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. */ - c += (ARG4 - PDC_IODC_RI_INIT) * 2 * sizeof(unsigned int); - memcpy((void*) ARG5, c, 2 * sizeof(unsigned int)); - // dprintf(0, "\n\nSeaBIOS: Info PDC_IODC function OK\n"); + entry_len = &iodc_entry_table_one_entry - &iodc_entry[0]; + c += (ARG4 - PDC_IODC_RI_INIT) * entry_len; + memcpy((void*) ARG5, c, entry_len); + printf("\n\nSeaBIOS: Info PDC_IODC function OK\n"); flush_data_cache((char*)ARG5, *result); return PDC_OK; break; @@ -2937,6 +2941,10 @@ unsigned long romfile_loadstring_to_int(const char *name, unsigned long defval) return defval; } +extern void start_kernel(unsigned long mem_free, unsigned long cline, + unsigned long rdstart, unsigned long rdend, + unsigned long kernel_start_address); + void __VISIBLE start_parisc_firmware(void) { unsigned int i, cpu_hz; @@ -3273,9 +3281,6 @@ void __VISIBLE start_parisc_firmware(void) /* directly start Linux kernel if it was given on qemu command line. */ if (linux_kernel_entry > 1) { - extern void start_kernel(unsigned long mem_free, unsigned long cline, - unsigned long rdstart, unsigned long rdend, - unsigned long kernel_start_address); unsigned long kernel_entry = linux_kernel_entry; printf("Autobooting Linux kernel which was loaded by qemu...\n\n"); @@ -3288,16 +3293,14 @@ void __VISIBLE start_parisc_firmware(void) /* check for bootable drives, and load and start IPL bootloader if possible */ if (parisc_boot_menu(&iplstart, &iplend, bootdrive)) { - void (*start_ipl)(long interactive, long iplend); - PAGE0->mem_boot.dp.layers[0] = boot_drive->target; PAGE0->mem_boot.dp.layers[1] = boot_drive->lun; printf("\nBooting...\n" "Boot IO Dependent Code (IODC) revision 153\n\n" "%s Booted.\n", PAGE0->imm_soft_boot ? "SOFT":"HARD"); - start_ipl = (void *) iplstart; - start_ipl(interact_ipl, iplend); + /* actually: start_ipl(interact_ipl, iplend); */ + start_kernel(interact_ipl, iplend, 0, 0, iplstart); } hlt(); /* this ends the emulator */ |