aboutsummaryrefslogtreecommitdiff
path: root/src/parisc/parisc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/parisc/parisc.c')
-rw-r--r--src/parisc/parisc.c217
1 files changed, 191 insertions, 26 deletions
diff --git a/src/parisc/parisc.c b/src/parisc/parisc.c
index 54616c2..55e8e49 100644
--- a/src/parisc/parisc.c
+++ b/src/parisc/parisc.c
@@ -120,6 +120,10 @@ int pdc_console;
int sti_font;
+/* Want PDC boot menu? Enable via qemu "-boot menu=on" option. */
+unsigned int show_boot_menu;
+unsigned int interact_ipl;
+
unsigned long PORT_QEMU_CFG_CTL;
unsigned int tlb_entries = 256;
unsigned int btlb_entries = 8;
@@ -348,6 +352,14 @@ int HPA_is_graphics_device(unsigned long hpa)
(hpa == 0xf8000000) || (hpa == 0xfa000000);
}
+static const char *hpa_device_name(unsigned long hpa, int output)
+{
+ return HPA_is_graphics_device(hpa) ? "GRAPHICS(1)" :
+ HPA_is_keyboard_device(hpa) ? "PS2" :
+ (PARISC_SERIAL_CONSOLE == PORT_SERIAL1) ?
+ "SERIAL_1.9600.8.none" : "SERIAL_2.9600.8.none";
+}
+
static unsigned long keep_list[] = { PARISC_KEEP_LIST };
static void remove_from_keep_list(unsigned long hpa)
@@ -533,7 +545,7 @@ static void parisc_serial_out(char c)
}
}
-void parisc_screenc(char c)
+static void parisc_putchar_internal(char c)
{
if (HPA_is_graphics_device(PAGE0->mem_cons.hpa))
sti_putc(c);
@@ -541,6 +553,29 @@ void parisc_screenc(char c)
parisc_serial_out(c);
}
+/* print char to default PDC output device */
+void parisc_putchar(char c)
+{
+ if (c == '\n')
+ parisc_putchar_internal('\r');
+ parisc_putchar_internal(c);
+}
+
+/* read char from default PDC input device (serial port / ps2-kbd) */
+static char parisc_getchar(void)
+{
+ int count;
+ char c;
+
+ if (HPA_is_serial_device(PAGE0->mem_kbd.hpa))
+ count = parisc_serial_in(&c, sizeof(c));
+ else
+ count = lasips2_kbd_in(&c, sizeof(c));
+ if (count == 0)
+ c = 0;
+ return c;
+}
+
void iodc_log_call(unsigned int *arg, const char *func)
{
if (pdc_debug & DEBUG_IODC) {
@@ -1708,6 +1743,145 @@ extern void find_initial_parisc_boot_drives(
struct drive_s **harddisc,
struct drive_s **cdrom);
extern struct drive_s *select_parisc_boot_drive(char bootdrive);
+extern int parisc_get_scsi_target(struct drive_s **boot_drive, int target);
+
+static void print_menu(void)
+{
+ printf("\n------- Main Menu -------------------------------------------------------------\n\n"
+ " Command Description\n"
+ " ------- -----------\n"
+ " BOot [PRI|ALT|<path>] Boot from specified path\n"
+#if 0
+ " PAth [PRI|ALT|CON|KEY] [<path>] Display or modify a path\n"
+ " SEArch [DIsplay|IPL] [<path>] Search for boot devices\n\n"
+ " COnfiguration [<command>] Access Configuration menu/commands\n"
+ " INformation [<command>] Access Information menu/commands\n"
+ " SERvice [<command>] Access Service menu/commands\n\n"
+ " DIsplay Redisplay the current menu\n"
+#endif
+ " HElp [<menu>|<command>] Display help for menu or command\n"
+ " RESET Restart the system\n"
+ "-------\n");
+}
+
+/* Copyright (C) 1999 Jason L. Eckhardt (jle@cygnus.com) - taken from palo */
+static char *enter_text(char *txt, int maxchars)
+{
+ char c;
+ int pos;
+ for (pos = 0; txt[pos]; pos++); /* calculate no. of chars */
+ if (pos > maxchars) /* if input too long, shorten it */
+ {
+ pos = maxchars;
+ txt[pos] = '\0';
+ }
+ printf(txt); /* print initial text */
+ do
+ {
+ c = parisc_getchar();
+ if (c == 13)
+ { /* CR -> finish! */
+ if (pos <= maxchars)
+ txt[pos] = 0;
+ else
+ txt[maxchars] = '\0';
+ return txt;
+ };
+ if (c == '\b' || c == 127 )
+ { /* BS -> delete prev. char */
+ if (pos)
+ {
+ pos--;
+ c='\b';
+ parisc_putchar(c);
+ parisc_putchar(' ');
+ parisc_putchar(c);
+ }
+ } else if (c == 21)
+ { /* CTRL-U */
+ while (pos)
+ {
+ pos--;
+ c='\b';
+ parisc_putchar(c);
+ parisc_putchar(' ');
+ parisc_putchar(c);
+ }
+ txt[0] = 0;
+ } else if ((pos < maxchars) && c >= ' ')
+ {
+ txt[pos] = c;
+ pos++;
+ parisc_putchar(c);
+ }
+ }
+ while (c != 13);
+ return txt;
+}
+
+static void menu_loop(void)
+{
+ int scsi_boot_target;
+ char input[24];
+ char *c;
+
+ // snprintf(input, sizeof(input), "BOOT FWSCSI.%d.0", boot_drive->target);
+again:
+ print_menu();
+
+again2:
+ input[0] = '\0';
+ printf("Main Menu: Enter command > ");
+ /* ask user for boot menu command */
+ enter_text(input, sizeof(input)-1);
+ parisc_putchar('\n');
+
+ /* convert to uppercase */
+ c = input;
+ while (*c) {
+ if ((*c >= 'a') && (*c <= 'z'))
+ *c += 'A'-'a';
+ c++;
+ }
+
+ if (input[0] == 'R' && input[1] == 'E') // RESET?
+ reset();
+ if (input[0] == 'H' && input[1] == 'E') // HELP?
+ goto again;
+ if (input[0] != 'B' || input[1] != 'O') { // BOOT?
+ printf("Unknown command, please try again.\n\n");
+ goto again2;
+ }
+ // from here on we handle "BOOT PRI/ALT/FWSCSI.x"
+ c = input;
+ while (*c && (*c != ' ')) c++; // search space
+ // preset with default boot target (this is same as "BOOT PRI"
+ scsi_boot_target = boot_drive->target;
+ if (c[0] == 'A' && c[1] == 'L' && c[2] == 'T')
+ scsi_boot_target = parisc_boot_cdrom->target;
+ while (*c) {
+ if (*c >= '0' && *c <= '9') {
+ scsi_boot_target = *c - '0';
+ break;
+ }
+ c++;
+ }
+
+ if (!parisc_get_scsi_target(&boot_drive, scsi_boot_target)) {
+ printf("No FWSCSI.%d.0 device available for boot. Please try again.\n\n",
+ scsi_boot_target);
+ goto again2;
+ }
+
+ printf("Interact with IPL (Y, N, or Cancel)?> ");
+ input[0] = '\0';
+ enter_text(input, 1);
+ parisc_putchar('\n');
+ if (input[0] == 'C' || input[0] == 'c')
+ goto again2;
+ if (input[0] == 'Y' || input[0] == 'y')
+ interact_ipl = 1;
+}
static int parisc_boot_menu(unsigned long *iplstart, unsigned long *iplend,
char bootdrive)
@@ -1722,12 +1896,21 @@ static int parisc_boot_menu(unsigned long *iplstart, unsigned long *iplend,
};
boot_drive = select_parisc_boot_drive(bootdrive);
+
+ /* enter main menu if booted with "boot menu=on" */
+ if (show_boot_menu)
+ menu_loop();
+ else
+ interact_ipl = 0;
+
disk_op.drive_fl = boot_drive;
if (boot_drive == NULL) {
printf("SeaBIOS: No boot device.\n");
return 0;
}
+ printf("\nBooting from FWSCSI.%d.0 ...\n", boot_drive->target);
+
/* seek to beginning of disc/CD */
disk_op.drive_fl = boot_drive;
ret = process_op(&disk_op);
@@ -1911,8 +2094,8 @@ void __VISIBLE start_parisc_firmware(void)
unsigned long iplstart, iplend;
char *str;
- unsigned long interactive = (linux_kernel_entry == 1) ? 1:0;
char bootdrive = (char)cmdline; // c = hdd, d = CD/DVD
+ show_boot_menu = (linux_kernel_entry == 1);
if (smp_cpus > HPPA_MAX_CPUS)
smp_cpus = HPPA_MAX_CPUS;
@@ -2069,10 +2252,9 @@ void __VISIBLE start_parisc_firmware(void)
printf("SeaBIOS PA-RISC Firmware Version %d\n"
"\n"
"Duplex Console IO Dependent Code (IODC) revision 1\n"
- "\n"
- "Memory Test/Initialization Completed\n\n", SEABIOS_HPPA_VERSION);
+ "\n", SEABIOS_HPPA_VERSION);
printf("------------------------------------------------------------------------------\n"
- " (c) Copyright 2017-2021 Helge Deller <deller@gmx.de> and SeaBIOS developers.\n"
+ " (c) Copyright 2017-2022 Helge Deller <deller@gmx.de> and SeaBIOS developers.\n"
"------------------------------------------------------------------------------\n\n");
printf( " Processor Speed State Coprocessor State Cache Size\n"
" --------- -------- --------------------- ----------------- ----------\n");
@@ -2091,11 +2273,11 @@ void __VISIBLE start_parisc_firmware(void)
printf(" Primary boot path: FWSCSI.%d.%d\n"
" Alternate boot path: FWSCSI.%d.%d\n"
" Console path: %s\n"
- " Keyboard path: PS2\n\n",
+ " Keyboard path: %s\n\n",
parisc_boot_harddisc->target, parisc_boot_harddisc->lun,
parisc_boot_cdrom->target, parisc_boot_cdrom->lun,
- HPA_is_graphics_device(PAGE0->mem_cons.hpa) ? "GRAPHICS(1)" :
- ((PARISC_SERIAL_CONSOLE == PORT_SERIAL1) ? "SERIAL_1.9600.8.none" : "SERIAL_2.9600.8.none"));
+ hpa_device_name(PAGE0->mem_cons.hpa, 1),
+ hpa_device_name(PAGE0->mem_kbd.hpa, 0));
if (bootdrive == 'c')
boot_drive = parisc_boot_harddisc;
@@ -2137,23 +2319,6 @@ void __VISIBLE start_parisc_firmware(void)
hlt(); /* this ends the emulator */
}
-#if 0
- printf("------- Main Menu -------------------------------------------------------------\n\n"
- " Command Description\n"
- " ------- -----------\n"
- " BOot [PRI|ALT|<path>] Boot from specified path\n"
- " PAth [PRI|ALT|CON|KEY] [<path>] Display or modify a path\n"
- " SEArch [DIsplay|IPL] [<path>] Search for boot devices\n\n"
- " COnfiguration [<command>] Access Configuration menu/commands\n"
- " INformation [<command>] Access Information menu/commands\n"
- " SERvice [<command>] Access Service menu/commands\n\n"
- " DIsplay Redisplay the current menu\n"
- " HElp [<menu>|<command>] Display help for menu or command\n"
- " RESET Restart the system\n"
- "-------\n"
- "Main Menu: Enter command > ");
-#endif
-
/* 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);
@@ -2165,7 +2330,7 @@ void __VISIBLE start_parisc_firmware(void)
"Boot IO Dependent Code (IODC) revision 153\n\n"
"%s Booted.\n", PAGE0->imm_soft_boot ? "SOFT":"HARD");
start_ipl = (void *) iplstart;
- start_ipl(interactive, iplend);
+ start_ipl(interact_ipl, iplend);
}
hlt(); /* this ends the emulator */