aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHelge Deller <deller@gmx.de>2024-01-15 14:52:53 +0100
committerHelge Deller <deller@gmx.de>2024-01-15 14:52:53 +0100
commitc7a6383b20418dda3eeaa4cefbb431fd3521c6fd (patch)
treeed3babe41a37fdd6ef1d5097d9e3bfd6611ae0a8
parent2bce3fc3fa5b05d36e470571b971506586ab454e (diff)
downloadseabios-hppa-c7a6383b20418dda3eeaa4cefbb431fd3521c6fd.zip
seabios-hppa-c7a6383b20418dda3eeaa4cefbb431fd3521c6fd.tar.gz
seabios-hppa-c7a6383b20418dda3eeaa4cefbb431fd3521c6fd.tar.bz2
erster boot schritt vorwärts
-rw-r--r--Makefile2
-rw-r--r--src/parisc/head.S203
-rw-r--r--src/parisc/parisc.c35
3 files changed, 186 insertions, 54 deletions
diff --git a/Makefile b/Makefile
index 2c813a5..ecea65e 100644
--- a/Makefile
+++ b/Makefile
@@ -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 */