aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHelge Deller <deller@gmx.de>2022-05-14 22:09:22 +0200
committerHelge Deller <deller@gmx.de>2022-05-14 22:19:36 +0200
commit1314c8b0bfb8d3b3be145936073ed2fec8adf8f9 (patch)
tree67d6fbdca847f2ba78f784b12f49bece6a822f45
parentf5c0ce4a292a41aeee7cca238ceffc66ed4b0de6 (diff)
downloadseabios-hppa-1314c8b0bfb8d3b3be145936073ed2fec8adf8f9.zip
seabios-hppa-1314c8b0bfb8d3b3be145936073ed2fec8adf8f9.tar.gz
seabios-hppa-1314c8b0bfb8d3b3be145936073ed2fec8adf8f9.tar.bz2
parisc: Add full PDC firmware boot menu
Finally add the real boot menu. If qemu is started with the "-boot menu=on" option, the PDC boot menu is shown and the user can then boot any of the available SCSI disc/CDs. Just type "BOOT" (to boot the default device), or "BOOT FWSCSI.4" (to boot SCSI device #4). Signed-off-by: Helge Deller <deller@gmx.de>
-rw-r--r--src/boot.c24
-rw-r--r--src/output.c2
-rw-r--r--src/parisc/parisc.c217
-rw-r--r--src/parisc/sticore.h2
4 files changed, 209 insertions, 36 deletions
diff --git a/src/boot.c b/src/boot.c
index 31f63ea..3d7f092 100644
--- a/src/boot.c
+++ b/src/boot.c
@@ -795,6 +795,17 @@ interactive_bootmenu(void)
}
#if CONFIG_PARISC
+int parisc_get_scsi_target(struct drive_s **boot_drive, int target)
+{
+ struct bootentry_s *pos;
+ hlist_for_each_entry(pos, &BootList, node) {
+ if (pos->drive->target != target)
+ continue;
+ *boot_drive = pos->drive;
+ return 1;
+ }
+ return 0;
+}
void find_initial_parisc_boot_drives(struct drive_s **harddisc,
struct drive_s **cdrom)
{
@@ -809,15 +820,13 @@ void find_initial_parisc_boot_drives(struct drive_s **harddisc,
struct drive_s *select_parisc_boot_drive(char bootdrive)
{
- printf("Available boot devices:\n");
+ printf(" Available boot devices:\n");
// Show menu items
- int maxmenu = 0;
struct bootentry_s *pos;
hlist_for_each_entry(pos, &BootList, node) {
char desc[77];
- maxmenu++;
- printf("%d. %s\n", maxmenu
+ printf(" FWSCSI.%d.0 : %s\n", pos->drive->target
, strtcpy(desc, pos->description, ARRAY_SIZE(desc)));
}
@@ -825,15 +834,14 @@ struct drive_s *select_parisc_boot_drive(char bootdrive)
hlist_for_each_entry(pos, &BootList, node) {
if (((bootdrive == 'd') && (pos->type == IPL_TYPE_CDROM)) ||
((bootdrive == 'c') && (pos->type == IPL_TYPE_HARDDISK))) {
- printf("\nBooting from %s\n",pos->description);
+ // printf("\nBooting from %s\n",pos->description);
return pos->drive;
}
/* -boot order=g-m: machine implementation dependent drives */
if ((bootdrive >= 'g') && (bootdrive <= 'm')) {
int scsi_index = (int)bootdrive - 'g';
if (pos->drive->target == scsi_index) {
- printf("\nBooting from SCSI target %d: %s\n",
- scsi_index, pos->description);
+ // printf("\nBooting from SCSI target %d: %s\n", scsi_index, pos->description);
return pos->drive;
}
}
@@ -842,7 +850,7 @@ struct drive_s *select_parisc_boot_drive(char bootdrive)
hlist_for_each_entry(pos, &BootList, node) {
if ((pos->type == IPL_TYPE_CDROM) ||
(pos->type == IPL_TYPE_HARDDISK)) {
- printf("\nAuto-Booting from %s\n",pos->description);
+ // printf("\nAuto-Booting from %s\n",pos->description);
return pos->drive;
}
}
diff --git a/src/output.c b/src/output.c
index fcbc3f9..b940480 100644
--- a/src/output.c
+++ b/src/output.c
@@ -90,7 +90,7 @@ screenc(char c)
br.bl = 0x07;
call16_int(0x10, &br);
#else
- parisc_screenc(c);
+ parisc_putchar(c);
#endif
}
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 */
diff --git a/src/parisc/sticore.h b/src/parisc/sticore.h
index 658714b..fff7d15 100644
--- a/src/parisc/sticore.h
+++ b/src/parisc/sticore.h
@@ -321,6 +321,6 @@ void sti_putc(const char c);
extern struct sti_rom sti_proc_rom;
extern char _sti_rom_end[];
extern char _sti_rom_start[];
-extern void parisc_screenc(char c);
+extern void parisc_putchar(char c);
#endif /* STICORE_H */