// Glue code for parisc architecture
//
// Copyright (C) 2017-2023  Helge Deller <deller@gmx.de>
// Copyright (C) 2019 Sven Schnelle <svens@stackframe.org>
//
// This file may be distributed under the terms of the GNU LGPLv3 license.
//
// Example command line:
//
//Funktioniert:
//./qemu-system-hppa -drive file=../qemu-images/hdd.img -kernel vmlinux -append "root=/dev/sda5 cryptomgr.notests"   -smp cpus=2  -snapshot -machine C3700  -vnc :1  -fw_cfg opt/console,string=serial -serial mon:stdio  -device secondary-vga #-d in_asm # -fw_cfg opt/pdc_debug,string=255 2>&1| grep ohci  # -d trace:serial\*  # ,mmu,trace:serial\*,trace:iosapic\*,trace:elroy\*,trace:astro\*,trace:pci\*
//
// ./qemu-system-hppa -drive file=../qemu-images/hdd.img -kernel vmlinux -append root=/dev/sda5 cryptomgr.notests  console=ttyS0 earlycon=pdc -accel tcg,thread=multi,one-insn-per-tb=off -serial mon:stdio -smp cpus=1 -snapshot -nographic -machine B160L
// /qemu-system-hppa -drive file=../qemu-images/hdd.img -kernel vmlinux -append "root=/dev/sda5 cryptomgr.notests  console=ttyS0 earlycon=pdc"   -accel tcg,thread=multi,one-insn-per-tb=off -serial mon:stdio -smp cpus=1 -nographic  -machine C3700 -device pci-serial-4x -device pci-ohci -device usb-tablet -device ES1370 -snapshot  # -fw_cfg opt/pdc_debug,string=255   # -d trace:serial\*  # ,mmu,trace:serial\*,trace:iosapic\*,trace:elroy\*,trace:astro\*,trace:pci\*

#include "biosvar.h" // GET_BDA
#include "bregs.h" // struct bregs
#include "hw/pic.h" // enable_hwirq
#include "output.h" // debug_enter
#include "stacks.h" // call16_int
#include "string.h" // memset
#include "util.h" // serial_setup
#include "malloc.h" // malloc
#include "hw/serialio.h" // qemu_debug_port
#include "hw/pcidevice.h" // foreachpci
#include "hw/pci.h" // pci_config_readl
#include "hw/pci_ids.h" // PCI IDs
#include "hw/pci_regs.h" // PCI_BASE_ADDRESS_0
#include "hw/ata.h"
#include "hw/usb-ohci.h"
#include "hw/blockcmd.h" // scsi_is_ready()
#include "hw/rtc.h"
#include "fw/paravirt.h" // PlatformRunningOn
#include "vgahw.h"
#include "parisc/hppa_hardware.h" // DINO_UART_BASE
#include "parisc/pdc.h"
#include "parisc/sticore.h"
#include "parisc/lasips2.h"

#include "vgabios.h"

/*
 * Various variables which are needed by x86 code.
 * Defined here to be able to link seabios.
 */
int HaveRunPost;
u8 ExtraStack[BUILD_EXTRA_STACK_SIZE+1] __aligned(8);
u8 *StackPos;
u8 __VISIBLE parisc_stack[32*1024] __aligned(64);

volatile int num_online_cpus;
int __VISIBLE toc_lock = 1;
union {
	struct pdc_toc_pim_11 pim11;
	struct pdc_toc_pim_20 pim20;
} pim_toc_data[HPPA_MAX_CPUS] __VISIBLE __aligned(8);

#define is_64bit()	0	/* we only support 32-bit PDC for now. */

u8 BiosChecksum;

char zonefseg_start, zonefseg_end;  // SYMBOLS
char varlow_start, varlow_end, final_varlow_start;
char final_readonly_start;
char code32flat_start, code32flat_end;
char zonelow_base;

struct bios_data_area_s __VISIBLE bios_data_area;
struct vga_bda_s	__VISIBLE vga_bios_data_area;
struct floppy_dbt_s diskette_param_table;
struct bregs regs;
unsigned long parisc_vga_mem;
unsigned long parisc_vga_mmio;
struct segoff_s ivt_table[256];

void mtrr_setup(void) { }
void mouse_init(void) { }
void pnp_init(void) { }
u16  get_pnp_offset(void) { return 0; }
void mathcp_setup(void) { }
void smp_setup(void) { }
void bios32_init(void) { }
void yield_toirq(void) { }
void farcall16(struct bregs *callregs) { }
void farcall16big(struct bregs *callregs) { }
void mutex_lock(struct mutex_s *mutex) { }
void mutex_unlock(struct mutex_s *mutex) { }
void start_preempt(void) { }
void finish_preempt(void) { }
int wait_preempt(void) { return 0; }

void cpuid(u32 index, u32 *eax, u32 *ebx, u32 *ecx, u32 *edx)
{
    *eax = *ebx = *ecx = *edx = 0;
}

void wrmsr_smp(u32 index, u64 val) { }

/********************************************************
 * PA-RISC specific constants and functions.
 ********************************************************/

/* boot_args[] variables provided by qemu */
#define boot_args		PAGE0->pad608
#define ram_size		boot_args[0]
#define linux_kernel_entry	boot_args[1]
#define cmdline			boot_args[2]
#define initrd_start		boot_args[3]
#define initrd_end		boot_args[4]
#define smp_cpus		boot_args[5]
#define pdc_debug		boot_args[6]
#define fw_cfg_port		boot_args[7]

/* flags for pdc_debug */
#define DEBUG_PDC       0x01
#define DEBUG_IODC      0x02
#define DEBUG_BOOT_IO   0x04
#define DEBUG_CHASSIS   0x08

int pdc_console;
/* flags for pdc_console */
#define CONSOLE_DEFAULT   0x0000
#define CONSOLE_SERIAL    0x0001
#define CONSOLE_GRAPHICS  0x0002

int sti_font;

char qemu_version[16] = "unknown version";
char qemu_machine[16] = "B160L";
char cpu_bit_width;
char has_astro;
#define PCI_HPA         DINO_HPA        /* initial temp. PCI bus */
unsigned long pci_hpa = PCI_HPA;    /* HPA of Dino or Elroy0 */
unsigned long hppa_port_pci_cmd  = (PCI_HPA + DINO_PCI_ADDR);
unsigned long hppa_port_pci_data = (PCI_HPA + DINO_CONFIG_DATA);

/* 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;

#define PARISC_SERIAL_CONSOLE   PORT_SERIAL1

extern char pdc_entry;
extern char pdc_entry_table[12];
extern char iodc_entry[512];
extern char iodc_entry_table[14*4];

/* args as handed over for firmware calls */
#define ARG0 arg[7-0]
#define ARG1 arg[7-1]
#define ARG2 arg[7-2]
#define ARG3 arg[7-3]
#define ARG4 arg[7-4]
#define ARG5 arg[7-5]
#define ARG6 arg[7-6]
#define ARG7 arg[7-7]

/* size of I/O block used in HP firmware */
#define FW_BLOCKSIZE    2048

#define MIN_RAM_SIZE	(16*1024*1024) // 16 MB

#define MEM_PDC_ENTRY	0x4800	/* as in a B160L */

#define CPU_HPA_IDX(i)  (CPU_HPA + (i)*0x1000) /* CPU_HPA of CPU#i */

static int index_of_CPU_HPA(unsigned long hpa) {
    int i;
    for (i = 0; i < smp_cpus; i++) {
        if (hpa == CPU_HPA_IDX(i))
            return i;
    }
    return -1;
}

static unsigned long GoldenMemory = MIN_RAM_SIZE;

static unsigned int chassis_code = 0;

/*
 * Emulate the power switch button flag in head section of firmware.
 * Bit 31 (the lowest bit) is the status of the power switch.
 * This bit is "1" if the button is NOT pressed.
 */
int powersw_nop;
int *powersw_ptr;

/*
 * Real time clock emulation
 * Either LASI or Astro will provide access to an emulated RTC clock.
 */
int *rtc_ptr = (int *) (unsigned long) LASI_RTC_HPA;

void __VISIBLE __noreturn hlt(void)
{
    if (pdc_debug)
        printf("HALT initiated from %p\n",  __builtin_return_address(0));
    printf("SeaBIOS wants SYSTEM HALT.\n\n");
    /* call qemu artificial "halt" asm instruction */
    asm volatile("\t.word 0xfffdead0": : :"memory");
    while (1);
}

static void check_powersw_button(void)
{
    /* halt immediately if power button was pressed. */
    if ((*powersw_ptr & 1) == 0) {
        printf("SeaBIOS machine power switch was pressed.\n");
        hlt();
    }
}

void __VISIBLE __noreturn reset(void)
{
    if (pdc_debug)
        printf("RESET initiated from %p\n",  __builtin_return_address(0));
    printf("SeaBIOS wants SYSTEM RESET.\n"
            "***************************\n");
    check_powersw_button();
    PAGE0->imm_soft_boot = 1;
    /* call qemu artificial "reset" asm instruction */
    asm volatile("\t.word 0xfffdead1": : :"memory");
    while (1);
}

#undef BUG_ON
#define BUG_ON(cond) \
    if (unlikely(cond)) { \
        printf("*ERROR* in SeaBIOS-hppa-v%d:\n%s:%d\n", SEABIOS_HPPA_VERSION, \
        __FUNCTION__, __LINE__); hlt(); \
    }

void flush_data_cache(char *start, size_t length)
{
    char *end = start + length;

    do
    {
        asm volatile("fdc 0(%0)" : : "r" (start));
        asm volatile("fic 0(%%sr0,%0)" : : "r" (start));
        start += 16;
    } while (start < end);
    asm volatile("fdc 0(%0)" : : "r" (end));

    asm ("sync");
}

void memdump(void *mem, unsigned long len)
{
    printf("memdump @ 0x%x : ", (unsigned int) mem);
    while (len--) {
        printf("0x%x ", (unsigned int) *(unsigned char *)mem);
        mem++;
    }
    printf("\n");
}

/********************************************************
 * Boot drives
 ********************************************************/

static struct drive_s *boot_drive; // really currently booted drive
static struct drive_s *parisc_boot_harddisc; // first hard disc
static struct drive_s *parisc_boot_cdrom;    // first DVD or CD-ROM

static struct pdc_module_path mod_path_emulated_drives = {
    .path = { .flags = 0x0, .bc = { 0xff, 0xff, 0xff, 0x8, 0x0, 0x0 }, .mod = 0x0  },
    .layers = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } // first two layer entries get replaced
};

/********************************************************
 * FIRMWARE IO Dependent Code (IODC) HANDLER
 ********************************************************/

#define	MAX_DEVICES	HPPA_MAX_CPUS+16

typedef struct {
    unsigned long hpa;
    struct pdc_iodc *iodc;
    struct pdc_system_map_mod_info *mod_info;
    struct pdc_module_path *mod_path;
    int num_addr;
    int add_addr[5];
    struct pci_device *pci;
    unsigned long pci_addr;
} hppa_device_t;

static hppa_device_t *find_hpa_device(unsigned long hpa);

#define CONCAT2(a, b) a ## b
#define CONCAT(a, b) CONCAT2(a, b)

struct machine_info {
        char			pdc_modelstr[16];
        struct pdc_model 	pdc_model;
        int			pdc_version;
        int			pdc_cpuid;
        int			pdc_caps;
        int			pdc_entry;
        unsigned long		pdc_cache_info[30];
        hppa_device_t		device_list[MAX_DEVICES];
};


/* create machine definitions */
#define MACHINE	B160L
#include "parisc/b160l.h"
#include "parisc/machine-create.h"

#define MACHINE	C3700
#include "parisc/c3700.h"
#include "parisc/machine-create.h"

struct machine_info *current_machine = &machine_B160L;

static hppa_device_t *parisc_devices = machine_B160L.device_list;

#define PARISC_KEEP_LIST \
    DINO_UART_HPA,\
    /* DINO_SCSI_HPA, */ \
    LASI_UART_HPA, \
    LASI_LAN_HPA, \
    LASI_LPT_HPA, \
    LASI_GFX_HPA,\
    LASI_PS2KBD_HPA, \
    LASI_PS2MOU_HPA, \
    0

static const char *hpa_name(unsigned long hpa)
{
    struct pci_device *pci;
    int i;

    #define DO(x) if (hpa == x) return #x;
    DO(GSC_HPA)
    DO(DINO_HPA)
    DO(DINO_UART_HPA)
    DO(DINO_SCSI_HPA)
    DO(CPU_HPA)
    DO(MEMORY_HPA)
    DO(SCSI_HPA)
    DO(LASI_HPA)
    DO(LASI_UART_HPA)
    DO(LASI_SCSI_HPA)
    DO(LASI_LAN_HPA)
    DO(LASI_LPT_HPA)
    DO(LASI_AUDIO_HPA)
    DO(LASI_PS2KBD_HPA)
    DO(LASI_PS2MOU_HPA)
    DO(LASI_GFX_HPA)
    #undef DO

    /* could be one of the SMP CPUs */
    for (i = 1; i < smp_cpus; i++) {
        static char CPU_TXT[] = "CPU_HPA_x";
        if (hpa == CPU_HPA_IDX(i)) {
            CPU_TXT[8] = '0'+i;
            return CPU_TXT;
        }
    }

    /* could be a PCI device */
    foreachpci(pci) {
        unsigned long mem, mmio;
        mem = pci_config_readl(pci->bdf, PCI_BASE_ADDRESS_0);
        mem &= PCI_BASE_ADDRESS_MEM_MASK;
        if (hpa == mem)
            return "HPA_PCI_CARD_MEM";
        mmio = pci_config_readl(pci->bdf, PCI_BASE_ADDRESS_2);
        mmio &= PCI_BASE_ADDRESS_MEM_MASK;
        if (hpa == mem)
            return "HPA_PCI_CARD_MMIO";
    }

    return "UNKNOWN HPA";
}

int HPA_is_astro_ioport(unsigned long hpa)
{
    if (!has_astro)
        return 0;
    return ((hpa - IOS_DIST_BASE_ADDR) < IOS_DIST_BASE_SIZE);
}

int HPA_is_astro_mmio(unsigned long hpa)
{
    if (!has_astro)
        return 0;
    return ((hpa - LMMIO_DIST_BASE_ADDR) < LMMIO_DIST_BASE_SIZE);
}

struct pci_device *find_pci_from_HPA(unsigned long hpa)
{
    struct pci_device *pci = NULL;
    int ioport;

    if (HPA_is_astro_ioport(hpa)) {
        ioport = 1;
        hpa -= IOS_DIST_BASE_ADDR;
    } else if (HPA_is_astro_mmio(hpa))
        ioport = 0;
    else
        return NULL;

    foreachpci(pci) {
        int i;
        for (i = 0; i < 6; i++) {
            unsigned long addr = PCI_BASE_ADDRESS_0 + 4*i;
            unsigned long mem;
            mem = pci_config_readl(pci->bdf, addr);
            if ((mem & PCI_BASE_ADDRESS_SPACE_IO) &&
                ((mem & PCI_BASE_ADDRESS_IO_MASK) == hpa) &&
                (ioport == 1))
                    return pci;     /* found ioport */
            if (((mem & PCI_BASE_ADDRESS_SPACE_IO) == 0) &&
                ((mem & PCI_BASE_ADDRESS_MEM_MASK) == hpa) &&
                (ioport == 0))
                    return pci;     /* found memaddr */
        }
    }
    dprintf(1, "No PCI device found for HPA %lx\n", hpa);
    return NULL;
}

int DEV_is_storage_device(hppa_device_t *dev)
{
    BUG_ON(!dev);
    if (dev->pci)
        return (dev->pci->class == PCI_CLASS_STORAGE_SCSI);
    return ((dev->iodc->type & 0xf) == 0x04); /* HPHW_A_DMA */
}

int DEV_is_serial_device(hppa_device_t *dev)
{
    BUG_ON(!dev);
    if (dev->pci)
        return (dev->pci->class == PCI_CLASS_COMMUNICATION_SERIAL);
    return ((dev->iodc->type & 0xf) == 0x0a); /* HPHW_FIO */
}

int HPA_is_serial_device(unsigned long hpa)
{
    hppa_device_t *dev;

    dev = find_hpa_device(hpa);
    if (!dev)
        return 0;
    return DEV_is_serial_device(dev);
}

int DEV_is_network_device(hppa_device_t *dev)
{
    BUG_ON(!dev);
    if (dev->pci)
        return (dev->pci->class == PCI_CLASS_NETWORK_ETHERNET);
    return ((dev->iodc->type & 0xf) == 0x0a); /* HPHW_FIO */
}

static int HPA_is_LASI_keyboard(unsigned long hpa)
{
    return !has_astro && (hpa == LASI_PS2KBD_HPA);
}

#if 0
static int HPA_is_keyboard_device(unsigned long hpa)
{
    struct pci_device *pci;
    int ret;

    if (HPA_is_LASI_keyboard(hpa))
        return 1;
    pci = find_pci_from_HPA(hpa);
    if (!pci)
        return 0;
    ret = pci->class == PCI_CLASS_COMMUNICATION_SERIAL ||
            pci->class == PCI_CLASS_INPUT_KEYBOARD;
    dprintf(1, "PCI: is_keyboard? %pP -> %s\n", pci, ret?"Yes":"no");
    return ret;
}
#endif

int HPA_is_LASI_graphics(unsigned long hpa)
{
    hppa_device_t *dev;

    dev = find_hpa_device(hpa);
    if (!dev)
        return 0;
    return (dev->iodc->sversion_model == 0x003b); /* XXX */
}
#define GFX_NUM_PAGES 0x2000
int HPA_is_graphics_device(unsigned long hpa)
{
    hppa_device_t *dev;

    dev = find_hpa_device(hpa);
    if (!dev)
        return 0;
    if (dev->pci)
        return (dev->pci->class >> 8) == PCI_BASE_CLASS_DISPLAY;
    return (dev->iodc->sversion_model == 0x3b); /* XXX */
}

static const char *hpa_device_name(unsigned long hpa, int output)
{
    return HPA_is_LASI_graphics(hpa) ? "GRAPHICS(1)" :
            HPA_is_graphics_device(hpa) ? "VGA" :
            HPA_is_LASI_keyboard(hpa) ? "PS2" :
            ((hpa + 0x800) == PORT_SERIAL1) ?
                "SERIAL_1.9600.8.none" : "SERIAL_2.9600.8.none";
}

static void print_mod_path(struct pdc_module_path *p)
{
    dprintf(1, "PATH %d/%d/%d/%d/%d/%d/%d:%d.%d.%d ", p->path.bc[0], p->path.bc[1],
            p->path.bc[2],p->path.bc[3],p->path.bc[4],p->path.bc[5],
            p->path.mod, p->layers[0], p->layers[1], p->layers[2]);
}

void make_module_path_from_pcidev(struct pci_device *pci,
            struct pdc_module_path *p)
{
    memset(p, 0, sizeof(*p));
    memset(&p->path.bc, 0xff, sizeof(p->path.bc));

    switch (pci->class) {
    case PCI_CLASS_COMMUNICATION_SERIAL:
    case PCI_CLASS_NETWORK_ETHERNET:
    case PCI_CLASS_STORAGE_SCSI:
    case PCI_CLASS_SERIAL_USB:
    default:
#if 0
static struct pdc_module_path mod_path_hpa_fed3c000 = { // SCSI
        .path = { .flags = 0x0, .bc = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xa }, .mod = 0x6  },
        .layers = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }
#endif
        p->path.bc[3] = has_astro ? ASTRO_BUS_MODULE : 0x08; /* astro or dino */
        p->path.bc[4] = 0; // elroy index (0,1,4,6) == PCI Bus number (0,1,2,3)
        p->path.bc[5] = pci->bdf >> 3;  /* slot */
        p->path.mod = pci->bdf & 0x07; /* function */
        break;
    }
}

void make_iodc_from_pcidev(struct pci_device *pci,
            struct pdc_iodc *p)
{
    memset(p, 0, sizeof(*p));
    p->hversion_model = 0x0058;
    p->hversion = 0x0020;
    p->sversion_model = 0;
    p->sversion_opt = 0;
    p->rev = 0x0099;
    p->length = 1;

    switch (pci->class) {
    case PCI_CLASS_STORAGE_SCSI:
        p->features = 0x0001;
        p->type = 0x0084;
        break;
    case PCI_CLASS_COMMUNICATION_SERIAL:
    case PCI_CLASS_NETWORK_ETHERNET:
    case PCI_CLASS_SERIAL_USB:
    default:
        p->type = 0x008a;
        break;
    }
};

void make_modinfo_from_pcidev(struct pci_device *pci,
            struct pdc_system_map_mod_info *p, unsigned long pfa)
{
    memset(p, 0, sizeof(*p));
    p->mod_addr = pfa;
    p->mod_pgs = 0;
    p->add_addrs = HPA_is_graphics_device(pfa) ? GFX_NUM_PAGES : 0;
};

#define MAX_PCI_DEVICES         10
static int curr_pci_devices;    /* current number of PCI devices in list */
static hppa_device_t                    hppa_pci_devices[MAX_PCI_DEVICES];
static struct pdc_iodc                  hppa_pci_iodc[MAX_PCI_DEVICES];
static struct pdc_system_map_mod_info   hppa_pci_mod_info[MAX_PCI_DEVICES];
static struct pdc_module_path           hppa_pci_mod_path[MAX_PCI_DEVICES];


/* create table of PFA (PCI Function address), similiar to HPA */
static void hppa_pci_build_devices_list(void)
{
    struct pci_device *pci;

    memset(&hppa_pci_devices, 0, sizeof(hppa_pci_devices));

    curr_pci_devices = 0;

    dprintf(1, "\n PCI DEVICE LIST PFA TABLE\n");
    foreachpci(pci) {
        unsigned long pfa, offs;
        hppa_device_t *pdev = &hppa_pci_devices[curr_pci_devices];

        offs = elroy_offset(pci->bdf);
        BUG_ON(offs == -1UL);
        pfa = (unsigned long) elroy_port(0, offs);
        pfa += pci->bdf << 8;
        pfa |= SCSI_HPA;
        dprintf(1, "PCI device #%d %pP bdf 0x%x at pfa 0x%lx\n", curr_pci_devices, pci, pci->bdf, pfa);

        pdev->hpa       = pfa;
        pdev->iodc      = &hppa_pci_iodc[curr_pci_devices];
        pdev->mod_info  = &hppa_pci_mod_info[curr_pci_devices];
        pdev->mod_path  = &hppa_pci_mod_path[curr_pci_devices];
        pdev->num_addr  = 0;
        pdev->pci = pci;

        make_iodc_from_pcidev(pci, pdev->iodc);
        make_modinfo_from_pcidev(pci, pdev->mod_info, pfa);
        make_module_path_from_pcidev(pci, pdev->mod_path);

        curr_pci_devices++;
        BUG_ON(curr_pci_devices >= MAX_PCI_DEVICES);
    }
}

static hppa_device_t *find_hpa_device(unsigned long hpa)
{
    int i;

    /* search classical HPPA devices */
    if (hpa)
      for (i = 0; i < (MAX_DEVICES-1); i++) {
        if (hpa == parisc_devices[i].hpa)
            return &parisc_devices[i];
        if (!parisc_devices[i].hpa)
            break;
    }

    /* search PCI devices */
    for (i = 0; i < curr_pci_devices; i++) {
        if (hpa == hppa_pci_devices[i].hpa)
            return &hppa_pci_devices[i];
    }
    return NULL;
}

static unsigned long keep_list[20] = { PARISC_KEEP_LIST };

static void remove_from_keep_list(unsigned long hpa)
{
    int i = 0;

    while (keep_list[i] && keep_list[i] != hpa)
        i++;
    while (keep_list[i]) {
            ++i;
            keep_list[i-1] = keep_list[i];
    }
}

static int keep_this_hpa(unsigned long hpa)
{
    int i = 0;

    while (keep_list[i]) {
        if (keep_list[i] == hpa)
            return 1;
        i++;
    }
    return 0;
}

/* walk all machine devices and add generic ones to the keep_list[] */
static int keep_add_generic_devices(void)
{
    hppa_device_t *dev = current_machine->device_list;
    int i = 0;

    /* search end of list */
    while (keep_list[i]) i++;

    while (dev->hpa) {
	switch (dev->iodc->type) {
	case 0x0041:	/* Memory. Save HPA in PAGE0 entry. */
                PAGE0->imm_hpa = dev->hpa;
                /* fallthrough */
	case 0x0007:	/* GSC+ Port bridge */
	case 0x004d:	/* Dino PCI bridge */
	case 0x004b:	/* Core Bus adapter (LASI) */
	case 0x0040:	/* CPU */
	case 0x000d:	/* Elroy PCI bridge */
	case 0x000c:	/* Runway port */
		keep_list[i++] = dev->hpa;
	}
	dev++;
    }
    BUG_ON(i >= ARRAY_SIZE(keep_list));

    return 0;
}

/* Rebuild hardware list and drop all devices which are not listed in
 * PARISC_KEEP_LIST. Generate num_cpus CPUs. */
static void remove_parisc_devices(unsigned int num_cpus)
{
    static struct pdc_system_map_mod_info modinfo[HPPA_MAX_CPUS] = { {1,}, };
    static struct pdc_module_path modpath[HPPA_MAX_CPUS] = { {{1,}} };
    hppa_device_t *cpu_dev = NULL;
    unsigned long hpa;
    int i, p, t;

    /* already initialized? */
    static int uninitialized = 1;
    if (!uninitialized)
        return;
    uninitialized = 0;

    /* check if qemu emulates LASI chip (LASI_IAR exists) */
    if (*(unsigned long *)(LASI_HPA+16) == 0) {
        remove_from_keep_list(LASI_UART_HPA);
        remove_from_keep_list(LASI_LAN_HPA);
        remove_from_keep_list(LASI_LPT_HPA);
    } else {
        /* check if qemu emulates LASI i82596 LAN card */
        if (*(unsigned long *)(LASI_LAN_HPA+12) != 0xBEEFBABE)
            remove_from_keep_list(LASI_LAN_HPA);
    }

    p = t = 0;
    while ((hpa = parisc_devices[p].hpa) != 0) {
        if (keep_this_hpa(hpa)) {
            parisc_devices[t] = parisc_devices[p];
            if (hpa == CPU_HPA)
                cpu_dev = &parisc_devices[t];
            t++;
        }
        p++;
    }

    /* Fix monarch CPU */
    BUG_ON(!cpu_dev);
    cpu_dev->mod_info->mod_addr = CPU_HPA;
    cpu_dev->mod_path->path.mod = (CPU_HPA - DINO_HPA) / 0x1000;

    /* Generate other CPU devices */
    for (i = 1; i < num_cpus; i++) {
        unsigned long hpa = CPU_HPA_IDX(i);

        parisc_devices[t] = *cpu_dev;
        parisc_devices[t].hpa = hpa;

        modinfo[i] = *cpu_dev->mod_info;
        modinfo[i].mod_addr = hpa;
        parisc_devices[t].mod_info = &modinfo[i];

        modpath[i] = *cpu_dev->mod_path;
        modpath[i].path.mod = (hpa - DINO_HPA) / 0x1000;
        parisc_devices[t].mod_path = &modpath[i];

        t++;
    }

    BUG_ON(t > MAX_DEVICES);

    while (t < MAX_DEVICES) {
        memset(&parisc_devices[t], 0, sizeof(*parisc_devices));
        t++;
    }
}

static int compare_module_path(struct pdc_module_path *path,
                               struct pdc_module_path *search,
                               int check_layers)
{
    int i;

    if (path->path.mod != search->path.mod)
        return 0;

    for(i = 0; i < ARRAY_SIZE(path->path.bc); i++) {
        if (path->path.bc[i] != search->path.bc[i])
            return 0;
    }

    if (check_layers) {
        for(i = 0; i < ARRAY_SIZE(path->layers); i++) {
            if (path->layers[i] != search->layers[i])
                return 0;
        }
    }
    return 1;
}

static hppa_device_t *find_hppa_device_by_path(unsigned long hpa,
                            struct pdc_module_path *search,
                            unsigned long *index, int check_layers)
{
    hppa_device_t *dev;
    int i, nr = 0;

    for (i = 0; i < (MAX_DEVICES-1); i++) {
        dev = parisc_devices + i;
        if (dev->hpa != hpa)
            continue;

        if (compare_module_path(dev->mod_path, search, check_layers)) {
            if (index)
                *index = nr;
            return dev;
        }
        nr++;
    }

    /* search PCI devices */
    for (i = 0; i < curr_pci_devices; i++) {
        dev = hppa_pci_devices + i;
        if (compare_module_path(dev->mod_path, search, check_layers)) {
            if (index)
                *index = nr;
            return dev;
        }
        nr++;
    }

    return NULL;
}

static hppa_device_t *find_hppa_device_by_index(unsigned int index, int search_pci)
{
    hppa_device_t *dev;
    int i;

    for (i = 0; i < (MAX_DEVICES-1); i++) {
        dev = parisc_devices + i;
        if (!dev->hpa)
            continue;
        if (index-- == 0)
            return dev;
    }

    /* search PCI devices */
    if (search_pci) {
        for (i = 0; i < curr_pci_devices; i++) {
            dev = hppa_pci_devices + i;
            if (index-- == 0)
                return dev;
        }
    }

    return NULL;
}

#define SERIAL_TIMEOUT 20
static unsigned long parisc_serial_in(char *c, unsigned long maxchars)
{
    portaddr_t addr = PAGE0->mem_kbd.hpa;
    unsigned long end = timer_calc(SERIAL_TIMEOUT);
    unsigned long count = 0;

    if (has_astro) {
        hppa_device_t *dev = find_hpa_device(addr);
        BUG_ON(!dev);
        addr = dev->pci_addr;
    } else
        addr += 0x800;
    while (count < maxchars) {
        u8 lsr = inb(addr+SEROFF_LSR);
        if (lsr & 0x01) {
            // Success - can read data
            *c++ = inb(addr+SEROFF_DATA);
            count++;
        }
        if (timer_check(end))
            break;
    }
    return count;
}

static void parisc_serial_out(char c)
{
    portaddr_t addr = PAGE0->mem_cons.hpa;

    /* might not be initialized if problems happen during early bootup */
    if (!addr) {
        /* use debugoutput instead */
        dprintf(0, "%c", c);
        return;
    }
    if (0) {
        dprintf(1,"parisc_serial_out  search hpa %x   ", PAGE0->mem_cons.hpa);
        print_mod_path(&PAGE0->mem_cons.dp);
        dprintf(1,"  \n");
    }
    hppa_device_t *dev;
    dev = find_hppa_device_by_path(addr, &PAGE0->mem_cons.dp, NULL, 0);
    if (0) {
        dprintf(1,"parisc_serial_out  hpa %x\n", PAGE0->mem_cons.hpa);
        print_mod_path(dev->mod_path);
    }
    if (!dev) hlt();
    BUG_ON(!dev);
    if (dev->pci_addr)
        addr = dev->pci_addr;
    else
        addr += 0x800;  /* add offset for serial port on GSC */
//  dprintf(1,"  addr %x\n", addr);

    if (c == '\n')
        parisc_serial_out('\r');

    for (;;) {
        u8 lsr = inb(addr+SEROFF_LSR);
        if ((lsr & 0x60) == 0x60) {
            // Success - can write data
            outb(c, addr+SEROFF_DATA);
            break;
        }
    }
}

static void parisc_putchar_internal(char c)
{
    if (HPA_is_LASI_graphics(PAGE0->mem_cons.hpa))
        sti_putc(c);
    else
        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_LASI_keyboard(PAGE0->mem_kbd.hpa))
        count = lasips2_kbd_in(&c, sizeof(c));
    else if (HPA_is_serial_device(PAGE0->mem_kbd.hpa))
        count = parisc_serial_in(&c, sizeof(c));
    else
        BUG_ON(1);
    if (count == 0)
        c = 0;
    return c;
}

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("result=0x%x arg5=0x%x arg6=0x%x arg7=0x%x\n", ARG4, ARG5, ARG6, ARG7);
    }
}

#define FUNC_MANY_ARGS , \
    int a0, int a1, int a2, int a3,  int a4,  int a5,  int a6, \
    int a7, int a8, int a9, int a10, int a11, int a12


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;
    hppa_device_t *dev;
    int ret, len;
    char *c;
    struct disk_op_s disk_op;

    dev = find_hpa_device(hpa);
    if (!dev) {
        // BUG_ON(1);
        return PDC_INVALID_ARG;
    }

    if (1 &&
            (((DEV_is_serial_device(dev) || HPA_is_graphics_device(hpa)) && option == ENTRY_IO_COUT) ||
             ((DEV_is_serial_device(dev) || HPA_is_graphics_device(hpa)) && option == ENTRY_IO_CIN) ||
             ((DEV_is_storage_device(dev) && option == ENTRY_IO_BOOTIN && !(pdc_debug & DEBUG_BOOT_IO)))) ) {
        /* avoid debug messages */
    } else {
        iodc_log_call(arg, __FUNCTION__);
    }

    /* console I/O */
    switch (option) {
        case ENTRY_IO_COUT: /* console output */
            c = (char*)ARG6;
            result[0] = len = ARG7;
            if (DEV_is_serial_device(dev) || HPA_is_LASI_graphics(hpa)) {
                while (len--)
                    printf("%c", *c++);
            }
            return PDC_OK;
        case ENTRY_IO_CIN: /* console input, with 5 seconds timeout */
            c = (char*)ARG6;
            /* FIXME: Add loop to wait for up to 5 seconds for input */
            if (HPA_is_LASI_keyboard(hpa))
                result[0] = lasips2_kbd_in(c, ARG7);
            else if (DEV_is_serial_device(dev))
                result[0] = parisc_serial_in(c, ARG7);
            return PDC_OK;
    }

    /* boot medium I/O */
    if (DEV_is_storage_device(dev))
        switch (option) {
            case ENTRY_IO_BOOTIN: /* boot medium IN */
            case ENTRY_IO_BBLOCK_IN: /* boot block medium IN */
                disk_op.drive_fl = boot_drive;
                disk_op.buf_fl = (void*)ARG6;
                disk_op.command = CMD_READ;
                if (option == ENTRY_IO_BBLOCK_IN) { /* in 2k blocks */
                    /* reqsize must not be bigger than maxsize */
                    // if (ARG7 > ARG8) return PDC_INVALID_ARG;
                    disk_op.count = (ARG7 * ((u64)FW_BLOCKSIZE / disk_op.drive_fl->blksize));
                    disk_op.lba = (ARG5 * ((u64)FW_BLOCKSIZE / disk_op.drive_fl->blksize));
                } else {
                    // read one block at least.
                    if (ARG7 && (ARG7 < disk_op.drive_fl->blksize))
                        ARG7 = disk_op.drive_fl->blksize;
                    /* reqsize must be multiple of 2K */
                    if (ARG7 & (FW_BLOCKSIZE-1))
                        return PDC_INVALID_ARG;
                    /* reqsize must not be bigger than maxsize */
                    // if (ARG7 > ARG8) return PDC_INVALID_ARG;
                    /* medium start must be 2K aligned */
                    if (ARG5 & (FW_BLOCKSIZE-1))
                        return PDC_INVALID_ARG;
                    disk_op.count = (ARG7 / disk_op.drive_fl->blksize);
                    disk_op.lba = (ARG5 / disk_op.drive_fl->blksize);
                }
                // NOTE: LSI SCSI can not read more than 8191 blocks, so limit blocks to read
                if (disk_op.count >= 8192)
                    disk_op.count = 8192-16;

                // dprintf(0, "LBA %d  COUNT  %d\n", (u32) disk_op.lba, (u32)disk_op.count);
                ret = process_op(&disk_op);
                if (option == ENTRY_IO_BOOTIN)
                    result[0] = disk_op.count * disk_op.drive_fl->blksize; /* return bytes */
                else
                    result[0] = (disk_op.count * (u64)disk_op.drive_fl->blksize) / FW_BLOCKSIZE; /* return blocks */
                // printf("\nBOOT IO result %d, requested %d, read %ld\n", ret, ARG7, result[0]);
                if (ret)
                    return PDC_ERROR;
                return PDC_OK;
        }

    if (option == ENTRY_IO_CLOSE)
        return PDC_OK;

    //	BUG_ON(1);
    iodc_log_call(arg, __FUNCTION__);

    return PDC_BAD_OPTION;
}


int __VISIBLE parisc_iodc_ENTRY_INIT(unsigned int *arg FUNC_MANY_ARGS)
{
    unsigned long hpa = ARG0;
    unsigned long option = ARG1;
    unsigned long *result = (unsigned long *)ARG4;
    hppa_device_t *dev;

    iodc_log_call(arg, __FUNCTION__);

    dev = find_hpa_device(hpa);
    // dprintf(1, "HPA1 %lx  DEV %p  pci %p\n", hpa, dev, dev->pci);

    if (!dev || !(DEV_is_storage_device(dev) || DEV_is_serial_device(dev) || DEV_is_network_device(dev)))
        return PDC_INVALID_ARG;
    // dprintf(1, "HPA2 %lx  DEV %p\n", hpa, dev);

    switch (option) {
        case ENTRY_INIT_SRCH_FRST: /* 2: Search first */
            if (DEV_is_network_device(dev))
                return PDC_NE_BOOTDEV; /* No further boot devices */
            memcpy((void *)ARG3, &mod_path_emulated_drives.layers,
                sizeof(mod_path_emulated_drives.layers)); /* fill ID_addr */
            result[0] = 0;
            result[1] = DEV_is_serial_device(dev) ? CL_DUPLEX : CL_RANDOM;
            result[2] = result[3] = 0; /* No network card, so no MAC. */
            return PDC_OK;
	case ENTRY_INIT_SRCH_NEXT: /* 3: Search next */
            return PDC_NE_BOOTDEV; /* No further boot devices */
        case ENTRY_INIT_MOD_DEV: /* 4: Init & test mod & dev */
        case ENTRY_INIT_DEV:     /* 5: Init & test dev */
            result[0] = 0; /* module IO_STATUS */
            result[1] = DEV_is_serial_device(dev) ? CL_DUPLEX: CL_RANDOM;
            if (DEV_is_network_device(dev))
                result[2] = result[3] = 0x11221133; /* TODO?: MAC of network card. */
            else
                result[2] = result[3] = 0;
            return PDC_OK;
        case ENTRY_INIT_MOD:    /* 6: INIT */
            result[0] = 0; /* module IO_STATUS */
            return PDC_OK;
    }
    return PDC_BAD_OPTION;
}

int __VISIBLE parisc_iodc_ENTRY_SPA(unsigned int *arg FUNC_MANY_ARGS)
{
    iodc_log_call(arg, __FUNCTION__);
    return PDC_BAD_OPTION;
}

int __VISIBLE parisc_iodc_ENTRY_CONFIG(unsigned int *arg FUNC_MANY_ARGS)
{
    iodc_log_call(arg, __FUNCTION__);
    // BUG_ON(1);
    return PDC_BAD_OPTION;
}

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;
    hppa_device_t *dev;

    iodc_log_call(arg, __FUNCTION__);

    dev = find_hpa_device(hpa);
    if (!dev || !(DEV_is_storage_device(dev) || DEV_is_serial_device(dev)))
        return PDC_INVALID_ARG;

    /* The options ARG1=0 and ARG1=1 are required. Others are optional. */
    if (option == 0) { // Return info
        unsigned long *list_addr = (unsigned long *)ARG5;
        list_addr[0] = 0; // no test lists available.
        result[0] = 0; // data buffer size, no bytes required.
        result[1] = 0; // message buffer size, no bytes required.
        return PDC_OK;
    }

    if (option == 1) { // Execute step
        result[0] = 0; // fixed address of remote por
        return PDC_OK;
    }

    return PDC_BAD_OPTION;
}

int __VISIBLE parisc_iodc_ENTRY_TLB(unsigned int *arg FUNC_MANY_ARGS)
{
    unsigned long option = ARG1;
    unsigned long *result = (unsigned long *)ARG4;

    iodc_log_call(arg, __FUNCTION__);

    if (option == 0) {
        result[0] = 0; /* no TLB */
        result[1] = 0;
        return PDC_OK;
    }
    return PDC_BAD_OPTION;
}

/********************************************************
 * FIRMWARE PDC HANDLER
 ********************************************************/

#define STABLE_STORAGE_SIZE	512
static unsigned char stable_storage[STABLE_STORAGE_SIZE];

#define NVOLATILE_STORAGE_SIZE	512
static unsigned char nvolatile_storage[NVOLATILE_STORAGE_SIZE];

static void init_stable_storage(void)
{
    /* see ENGINEERING NOTE on page 4-92 in PDC2.0 doc */
    memset(&stable_storage, 0, STABLE_STORAGE_SIZE);
    // no intial paths
    stable_storage[0x07] = 0xff;
    stable_storage[0x67] = 0xff;
    stable_storage[0x87] = 0xff;
    stable_storage[0xa7] = 0xff;
    // 0x0e/0x0f => fastsize = all, needed for HPUX
    stable_storage[0x5f] = 0x0f;
}

/* values in PDC_CHASSIS */
const char * const systat[] = {
    "Off", "Fault", "Test", "Initialize",
    "Shutdown", "Warning", "Run", "All On"
};

static const char *pdc_name(unsigned long num)
{
#define DO(x) if (num == x) return #x;
        DO(PDC_POW_FAIL)
        DO(PDC_CHASSIS)
        DO(PDC_PIM)
        DO(PDC_MODEL)
        DO(PDC_CACHE)
        DO(PDC_HPA)
        DO(PDC_COPROC)
        DO(PDC_IODC)
        DO(PDC_TOD)
        DO(PDC_STABLE)
        DO(PDC_NVOLATILE)
        DO(PDC_ADD_VALID)
        DO(PDC_INSTR)
        DO(PDC_PROC)
        DO(PDC_BLOCK_TLB)
        DO(PDC_TLB)
        DO(PDC_MEM)
        DO(PDC_PSW)
        DO(PDC_SYSTEM_MAP)
        DO(PDC_SOFT_POWER)
        DO(PDC_CRASH_PREP)
        DO(PDC_MEM_MAP)
        DO(PDC_EEPROM)
        DO(PDC_NVM)
        DO(PDC_SEED_ERROR)
        DO(PDC_IO)
        DO(PDC_BROADCAST_RESET)
        DO(PDC_LAN_STATION_ID)
        DO(PDC_CHECK_RANGES)
        DO(PDC_NV_SECTIONS)
        DO(PDC_PERFORMANCE)
        DO(PDC_SYSTEM_INFO)
        DO(PDC_RDR)
        DO(PDC_INTRIGUE)
        DO(PDC_STI)
        DO(PDC_PCI_INDEX)
        DO(PDC_RELOCATE)
        DO(PDC_INITIATOR)
        DO(PDC_LINK)
#undef DO
        return "UNKNOWN!";
}

static int pdc_chassis(unsigned int *arg)
{
    unsigned long option = ARG1;
    unsigned long *result = (unsigned long *)ARG2;
    short *display_model = (short *)ARG3;

    switch (option) {
        case PDC_CHASSIS_DISP:
            ARG3 = ARG2;
            result = (unsigned long *)&ARG4; // do not write to ARG2, use &ARG4 instead
            // fall through
        case PDC_CHASSIS_DISPWARN:
            ARG4 = (ARG3 >> 17) & 7;
            chassis_code = ARG3 & 0xffff;
            if (pdc_debug & DEBUG_CHASSIS)
                printf("\nPDC_CHASSIS: %s (%d), %sCHASSIS  0x%0x\n",
                       systat[ARG4], ARG4, (ARG3>>16)&1 ? "blank display, ":"", chassis_code);
            // fall through
        case PDC_CHASSIS_WARN:
            // return warnings regarding fans, batteries and temperature: None!
            result[0] = 0;
            return PDC_OK;
        case PDC_RETURN_CHASSIS_INFO: /* return chassis LED/LCD info */
            // XXX: Later we could emulate an LCD display here.
            result[0] = result[1] = 4; // actcnt & maxcnt
            memset((char *)ARG3, 0, ARG4);
            display_model[0] = 1; // 1=DISPLAY_MODEL_NONE
            display_model[1] = 0; // 0=LCD WIDTH is 0
            return PDC_OK;
    }
    return PDC_BAD_PROC;
}

static int pdc_pim(unsigned int *arg)
{
    unsigned long option = ARG1;
    unsigned long *result = (unsigned long *)ARG2;
    unsigned long hpa;
    int i;
    unsigned int count, default_size;

    if (is_64bit())
	default_size = sizeof(struct pdc_toc_pim_20);
    else
	default_size = sizeof(struct pdc_toc_pim_11);

    switch (option) {
        case PDC_PIM_HPMC:
            break;
        case PDC_PIM_RETURN_SIZE:
            *result = default_size;
            // B160 returns only "2". Why?
            return PDC_OK;
        case PDC_PIM_LPMC:
        case PDC_PIM_SOFT_BOOT:
            break;
        case PDC_PIM_TOC:
            hpa = mfctl(CPU_HPA_CR_REG); /* get CPU HPA from cr7 */
            i = index_of_CPU_HPA(hpa);
            if (i < 0 || i >= smp_cpus) {
                *result = PDC_INVALID_ARG;
                return PDC_OK;
            }
            if (( is_64bit() && pim_toc_data[i].pim20.cpu_state.val == 0) ||
                (!is_64bit() && pim_toc_data[i].pim11.cpu_state.val == 0)) {
                /* PIM contents invalid */
                *result = PDC_NE_MOD;
                return PDC_OK;
            }
            count = (default_size < ARG4) ? default_size : ARG4;
            memcpy((void *)ARG3, &pim_toc_data[i], count);
            *result = count;
            /* clear PIM contents */
            if (is_64bit())
                pim_toc_data[i].pim20.cpu_state.val = 0;
            else
                pim_toc_data[i].pim11.cpu_state.val = 0;
            return PDC_OK;
    }
    return PDC_BAD_OPTION;
}

static int pdc_model(unsigned int *arg)
{
    const char *model_str = current_machine->pdc_modelstr;
    unsigned long option = ARG1;
    unsigned long *result = (unsigned long *)ARG2;

    switch (option) {
        case PDC_MODEL_INFO:
            /*
             * In case we run on a 32-bit only emulation, avoid a kernel crash
             * with old qemu versions which will try to run 64-bit instructions
             * kernel sr_disable_hash() function
             */
#if 1
            memcpy(result, (cpu_bit_width == 64) ?
                    &current_machine->pdc_model : &machine_B160L.pdc_model,
			sizeof(current_machine->pdc_model));
#else
            memcpy(result, &current_machine->pdc_model, sizeof(current_machine->pdc_model));
            struct pdc_model *p = (struct pdc_model *) result;
            /* HACK */
            p->arch_rev = 0x04;         /* 32-bit CPU, 64-bit has value 0x08 */
#endif
            return PDC_OK;
        case PDC_MODEL_VERSIONS:
            switch (ARG3) {
                case 0: /* return CPU0 version */
                    result[0] = 35; // TODO! ???
                    return PDC_OK;
                case 1: /* return PDC version */
                    result[0] = current_machine->pdc_version;
                    return PDC_OK;
            }
            return -4; // invalid c_index
        case PDC_MODEL_SYSMODEL:
            result[0] = strlen(model_str);
            strtcpy((char *)ARG4, model_str, result[0] + 1);
            return PDC_OK;
        case PDC_MODEL_ENSPEC:
        case PDC_MODEL_DISPEC:
            if (ARG3 != current_machine->pdc_model.pot_key)
                return -20;
            return PDC_OK;
        case PDC_MODEL_CPU_ID:
            result[0] = current_machine->pdc_cpuid;
            /* if CPU does not support 64bits, use the B160L CPUID */
            if (cpu_bit_width != 64)
                result[0] = machine_B160L.pdc_cpuid;
            return PDC_OK;
        case PDC_MODEL_CAPABILITIES:
            result[0] = current_machine->pdc_caps;
            result[0] |= PDC_MODEL_OS32; /* we do support 32-bit */
            if (cpu_bit_width == 64) /* and maybe 64-bit */
                result[0] |= PDC_MODEL_OS64;
            else
                result[0] &= ~PDC_MODEL_OS64;
            return PDC_OK;
        case PDC_MODEL_GET_INSTALL_KERNEL:
            // No need to provide a special install kernel during installation of HP-UX
            return PDC_BAD_OPTION;
        case PDC_MODEL_GET_PLATFORM_INFO:
            model_str = has_astro ? "A6057A" : "9000/778";
            strtcpy((char *)ARG2, model_str, 16);
            strtcpy((char *)ARG3, model_str, 16);
            /* use: current_machine->pdc_model.sw_id ? */
            strtcpy((char *)ARG4, "001122334455", 16);
            return PDC_OK;
    }
    dprintf(0, "\n\nSeaBIOS: Unimplemented PDC_MODEL function %d %x %x %x %x\n", ARG1, ARG2, ARG3, ARG4, ARG5);
    return PDC_BAD_OPTION;
}

static int pdc_cache(unsigned int *arg)
{
    unsigned long option = ARG1;
    unsigned long *result = (unsigned long *)ARG2;
    struct pdc_cache_info *machine_cache_info
        = (struct pdc_cache_info *) current_machine->pdc_cache_info;

    switch (option) {
        case PDC_CACHE_INFO:
            machine_cache_info->it_size = tlb_entries;
            machine_cache_info->dt_size = tlb_entries;
            machine_cache_info->it_conf = (struct pdc_tlb_cf) { .tc_sh = 3, .tc_page = 1, .tc_cst = 1, .tc_sr = 0, };
            machine_cache_info->dt_conf = (struct pdc_tlb_cf) { .tc_sh = 3, .tc_page = 1, .tc_cst = 1, .tc_sr = 0, };
            machine_cache_info->it_loop = 1;
            machine_cache_info->dt_loop = 1;

#if 0
            dprintf(0, "\n\nCACHE  IC: %ld %ld %ld DC: %ld %ld %ld\n",
                    machine_cache_info->ic_count, machine_cache_info->ic_loop, machine_cache_info->ic_stride,
                    machine_cache_info->dc_count, machine_cache_info->dc_loop, machine_cache_info->dc_stride);
#endif
#if 1
            machine_cache_info->ic_size = 1024; /* no instruction cache */
            machine_cache_info->dc_size = 1024; /* no data cache */
#elif 0
            machine_cache_info->dc_conf = (struct pdc_cache_cf) { 0 };  // .alias=1, .sh=3, };
            machine_cache_info->ic_conf = (struct pdc_cache_cf) { 0 };  // .alias=1, .sh=3, };

            machine_cache_info->ic_size = 0; /* no instruction cache */
            machine_cache_info->ic_count = 0;
            machine_cache_info->ic_loop = 0;
            machine_cache_info->ic_base = 0;
            machine_cache_info->ic_stride = 0;
            machine_cache_info->dc_size = 0; /* no data cache */
            machine_cache_info->dc_count = 0;
            machine_cache_info->dc_loop = 0;
            machine_cache_info->dc_base = 0;
            machine_cache_info->dc_stride = 0;
#endif

            memcpy(result, machine_cache_info, sizeof(*machine_cache_info));
            return PDC_OK;
        case PDC_CACHE_RET_SPID:	/* returns space-ID bits */
            memset(result, 0, 32 * sizeof(unsigned long));
	    /* for 32- and 64-bit CPUs, we allow only 32 useable bits for SIDs */
            result[0] = 32;
            return PDC_OK;
    }
    dprintf(0, "\n\nSeaBIOS: Unimplemented PDC_CACHE function %d %x %x %x %x\n", ARG1, ARG2, ARG3, ARG4, ARG5);
    return PDC_BAD_OPTION;
}

static int pdc_hpa(unsigned int *arg)
{
    unsigned long option = ARG1;
    unsigned long *result = (unsigned long *)ARG2;
    unsigned long hpa;
    int i;

    switch (option) {
        case PDC_HPA_PROCESSOR:
            hpa = mfctl(CPU_HPA_CR_REG); /* get CPU HPA from cr7 */
            i = index_of_CPU_HPA(hpa);
            BUG_ON(i < 0 || i >= smp_cpus); /* ARGH, someone modified cr7! */
            result[0] = hpa;    /* CPU_HPA */
            result[1] = i;      /* for SMP: 0,1,2,3,4...(num of this cpu) */
            return PDC_OK;
        case PDC_HPA_MODULES:
            return PDC_BAD_OPTION; // all modules on same board as the processor.
    }
    return PDC_BAD_OPTION;
}

static int pdc_coproc(unsigned int *arg)
{
    unsigned long option = ARG1;
    unsigned long *result = (unsigned long *)ARG2;
    unsigned long mask;
    switch (option) {
        case PDC_COPROC_CFG:
            memset(result, 0, 32 * sizeof(unsigned long));
            /* Set one bit per cpu in ccr_functional and ccr_present.
               Ignore that specification only mentions 8 bits for cr10
               and set all FPUs functional */
            mask = 1UL << 7;
            mtctl(mask, 10); /* initialize cr10 */
            result[0] = mask;
            result[1] = mask;
            result[17] = 1; // Revision
            result[18] = has_astro ? 0x0f : 0x13; // Model
            return PDC_OK;
    }
    return PDC_BAD_OPTION;
}

static int pdc_iodc(unsigned int *arg)
{
    unsigned long option = ARG1;
    unsigned long *result = (unsigned long *)ARG2;
    unsigned long hpa;
    hppa_device_t *dev;
    struct pdc_iodc *iodc_p;
    unsigned char *c;

    // dprintf(1, "\n\nSeaBIOS: Info PDC_IODC function %ld ARG3=%x ARG4=%x ARG5=%x ARG6=%x\n", option, ARG3, ARG4, ARG5, ARG6);
    switch (option) {
        case PDC_IODC_READ:
            hpa = ARG3;
            dev = find_hpa_device(hpa);
// dprintf(1, "pdc_iodc found dev %p\n", dev);
            if (!dev)
                return -4; // not found

            iodc_p = dev->iodc;

            if (ARG4 == PDC_IODC_INDEX_DATA) {
                if (iodc_p->type == 0x0041) // Memory ?
                    ARG6 = 2; // Memory modules return 2 bytes of IODC memory (result2 ret[0] = 0x6701f41 HI !!)
                memcpy((void*) ARG5, iodc_p, ARG6);
                c = (unsigned char *) ARG5;
                // printf("SeaBIOS: PDC_IODC get: hpa = 0x%lx, HV: 0x%x 0x%x IODC_SPA=0x%x  type 0x%x, \n", hpa, c[0], c[1], c[2], c[3]);
                // c[0] = iodc_p->hversion_model; // FIXME. BROKEN HERE !!!
                // c[1] = iodc_p->hversion_rev || (iodc_p->hversion << 4);
                result[0] = ARG6;
                return PDC_OK;
            }

            // ARG4 is IODC function to copy.
            if (ARG4 < PDC_IODC_RI_INIT || ARG4 > PDC_IODC_RI_TLB)
                return PDC_IODC_INVALID_INDEX;

            *result = 512; /* max size of function iodc_entry */
            if (ARG6 < *result)
                return PDC_IODC_COUNT;
            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");
            flush_data_cache((char*)ARG5, *result);
            return PDC_OK;
            break;
        case PDC_IODC_NINIT:	/* non-destructive init - for memory */
        case PDC_IODC_DINIT:	/* destructive init */
            result[0] = 0; /* IO_STATUS */
            result[1] = 0; /* max_spa */
            result[2] = ram_size; /* max memory */
            result[3] = 0;
            return PDC_OK;
        case PDC_IODC_MEMERR:
            result[0] = 0; /* IO_STATUS */
            result[1] = 0;
            result[2] = 0;
            result[3] = 0;
            return PDC_OK;
    }
    dprintf(0, "\n\nSeaBIOS: Unimplemented PDC_IODC function %ld ARG3=%x ARG4=%x ARG5=%x ARG6=%x\n", option, ARG3, ARG4, ARG5, ARG6);
    return PDC_BAD_OPTION;
}

static int pdc_tod(unsigned int *arg)
{
    unsigned long option = ARG1;
    unsigned long *result = (unsigned long *)ARG2;

    switch (option) {
        case PDC_TOD_READ:
            result[0] = *rtc_ptr;
            result[1] = result[2] = result[3] = 0;
            return PDC_OK;
        case PDC_TOD_WRITE:
            *rtc_ptr = ARG2;
            return PDC_OK;
        case 2: /* PDC_TOD_CALIBRATE_TIMERS */
            /* double-precision floating-point with frequency of Interval Timer in megahertz: */
            *(double*)&result[0] = (double)CPU_CLOCK_MHZ;
            /* unsigned 64-bit integers representing  clock accuracy in parts per billion: */
            result[2] = 1000000000; /* TOD_acc */
            result[3] = 0x5a6c; /* CR_acc (interval timer) */
            return PDC_OK;
    }
    dprintf(0, "\n\nSeaBIOS: Unimplemented PDC_TOD function %ld ARG2=%x ARG3=%x ARG4=%x\n", option, ARG2, ARG3, ARG4);
    return PDC_BAD_OPTION;
}

static int pdc_stable(unsigned int *arg)
{
    unsigned long option = ARG1;
    unsigned long *result = (unsigned long *)ARG2;

    // dprintf(0, "\n\nSeaBIOS: PDC_STABLE function %ld ARG2=%x ARG3=%x ARG4=%x\n", option, ARG2, ARG3, ARG4);
    switch (option) {
        case PDC_STABLE_READ:
            if ((ARG2 + ARG4) > STABLE_STORAGE_SIZE)
                return PDC_INVALID_ARG;
            memcpy((unsigned char *) ARG3, &stable_storage[ARG2], ARG4);
            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);
            return PDC_OK;
        case PDC_STABLE_RETURN_SIZE:
            result[0] = STABLE_STORAGE_SIZE;
            return PDC_OK;
        case PDC_STABLE_VERIFY_CONTENTS:
            return PDC_OK;
        case PDC_STABLE_INITIALIZE:
            init_stable_storage();
            return PDC_OK;
    }
    return PDC_BAD_OPTION;
}

static int pdc_nvolatile(unsigned int *arg)
{
    unsigned long option = ARG1;
    unsigned long *result = (unsigned long *)ARG2;

    switch (option) {
        case PDC_NVOLATILE_READ:
            if ((ARG2 + ARG4) > NVOLATILE_STORAGE_SIZE)
                return PDC_INVALID_ARG;
            memcpy((unsigned char *) ARG3, &nvolatile_storage[ARG2], ARG4);
            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);
            return PDC_OK;
        case PDC_NVOLATILE_RETURN_SIZE:
            result[0] = NVOLATILE_STORAGE_SIZE;
            return PDC_OK;
        case PDC_NVOLATILE_VERIFY_CONTENTS:
            return PDC_OK;
        case PDC_NVOLATILE_INITIALIZE:
            memset(nvolatile_storage, 0, sizeof(nvolatile_storage));
            return PDC_OK;
    }
    return PDC_BAD_OPTION;
}

static int pdc_add_valid(unsigned int *arg)
{
    unsigned long option = ARG1;

    // 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...
        return 1;
    // 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)
        return PDC_OK;
    if (ARG2 < FIRMWARE_END)
        return 1;
    if (ARG2 <= 0xffffffff)
        return PDC_OK;
    dprintf(0, "\n\nSeaBIOS: FAILED!!!! PDC_ADD_VALID function %ld ARG2=%x called.\n", option, ARG2);
    return PDC_REQ_ERR_0; /* Operation completed with a requestor bus error. */
}

static int pdc_proc(unsigned int *arg)
{
    extern void enter_smp_idle_loop(void);
    unsigned long option = ARG1;

    switch (option) {
        case 1:
            if (ARG2 != 0)
                return PDC_BAD_PROC;
            if (pdc_debug & DEBUG_PDC)
                printf("\nSeaBIOS: CPU%d enters rendenzvous loop.\n",
                        index_of_CPU_HPA(mfctl(CPU_HPA_CR_REG)));
            /* wait until all outstanding timer irqs arrived. */
            msleep(500);
            /* let the current CPU sleep until rendenzvous. */
            enter_smp_idle_loop();
            return PDC_OK;
    }
    return PDC_BAD_OPTION;
}

static int pdc_block_tlb(unsigned int *arg)
{
    int ret;

    /* Block TLB is only supported on 32-bit CPUs */
    if (cpu_bit_width != 32)
        return PDC_BAD_PROC;

    asm(
	"ldw (7-0)*%2(%1),%%r26 ! ldw (7-1)*%2(%1),%%r25 ! ldw (7-2)*%2(%1),%%r24 ! ldw (7-3)*%2(%1),%%r23\n"
	"ldw (7-4)*%2(%1),%%r22 ! ldw (7-5)*%2(%1),%%r21 ! ldw (7-6)*%2(%1),%%r20 ! ldw (7-7)*%2(%1),%%r19\n"
	"ldi %3,%%ret0\n"
	"diag 0x100\n"
	"copy %%ret0,%0\n"
	: "=r" (ret)
	: "r" (arg), "i" (sizeof(long)), "i" (PDC_BAD_OPTION)
	: "r28", "r26", "r25", "r24", "r23", "r22", "r21", "r20", "r19" );

    return ret;
}

static int pdc_tlb(unsigned int *arg)
{
#if 0
    /* still buggy, let's avoid it to keep things simple. */
    switch (option) {
        case PDC_TLB_INFO:
            result[0] = PAGE_SIZE;
            result[0] = PAGE_SIZE << 2;
            return PDC_OK;
        case PDC_TLB_SETUP:
            result[0] = ARG5 & 1;
            result[1] = 0;
            return PDC_OK;
    }
#endif
    return PDC_BAD_PROC;
}

static int pdc_mem(unsigned int *arg)
{
    unsigned long option = ARG1;
    unsigned long *result = (unsigned long *)ARG2;

    // only implemented on 64bit PDC!
    if (sizeof(unsigned long) == sizeof(unsigned int))
        return PDC_BAD_PROC;

    switch (option) {
        case PDC_MEM_MEMINFO:
            result[0] = 0;	// no PDT entries
            result[1] = 0;	// page entries
            result[2] = 0;	// PDT status
            result[3] = (unsigned long)-1ULL; // dbe_loc
            result[4] = GoldenMemory; // good_mem
            return PDC_OK;
        case PDC_MEM_READ_PDT:
            result[0] = 0;	// no PDT entries
            return PDC_OK;
        case PDC_MEM_GOODMEM:
            GoldenMemory = ARG3;
            return PDC_OK;
    }
    dprintf(0, "\n\nSeaBIOS: Check PDC_MEM option %ld ARG3=%x ARG4=%x ARG5=%x\n", option, ARG3, ARG4, ARG5);
    return PDC_BAD_PROC;
}

static int pdc_psw(unsigned int *arg)
{
    static unsigned long psw_defaults = PDC_PSW_ENDIAN_BIT;
    unsigned long option = ARG1;
    unsigned long *result = (unsigned long *)ARG2;

    if (option > PDC_PSW_SET_DEFAULTS)
        return PDC_BAD_OPTION;
    /* FIXME: For 64bit support enable PDC_PSW_WIDE_BIT too! */
    if (option == PDC_PSW_MASK)
        *result = PDC_PSW_ENDIAN_BIT;
    if (option == PDC_PSW_GET_DEFAULTS)
        *result = psw_defaults;
    if (option == PDC_PSW_SET_DEFAULTS) {
        psw_defaults = ARG2;
    }
    return PDC_OK;
}

static int pdc_system_map(unsigned int *arg)
{
    unsigned long option = ARG1;
    unsigned long *result = (unsigned long *)ARG2;
    struct pdc_module_path *mod_path;
    hppa_device_t *dev;
    unsigned long hpa;
    unsigned long hpa_index;

    // dprintf(0, "\n\nSeaBIOS: Info: PDC_SYSTEM_MAP function %ld ARG3=%x ARG4=%x ARG5=%x\n", option, ARG3, ARG4, ARG5);
    switch (option) {
        case PDC_FIND_MODULE:
            hpa_index = ARG4;
            dev = find_hppa_device_by_index(hpa_index, 0);
            if (!dev)
                return PDC_NE_MOD; // Module not found
            hpa = dev->hpa;

            if (0) {
                dprintf(1, "PDC_FIND_MODULE dev=%p hpa=%lx ", dev, dev ? dev->hpa:0UL);
                print_mod_path(dev->mod_path);
                if (dev->pci)
                    dprintf(1, "PCI %pP ", dev->pci);
                dprintf(1, "\n");
            }

            memset(result, 0, 32*sizeof(long));

            mod_path = (struct pdc_module_path *)ARG3;
            if (mod_path)
                *mod_path = *dev->mod_path;

            // *pdc_mod_info = *parisc_devices[hpa_index].mod_info; -> can be dropped.
            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;
            return PDC_OK;

        case PDC_FIND_ADDRESS:
            hpa_index = ARG3;
            dev = find_hppa_device_by_index(hpa_index, 1);
            if (!dev)
                return PDC_NE_MOD; // Module not found
            hpa = dev->hpa;

            memset(result, 0, 32*sizeof(long));
            ARG4 -= 1;
            if (ARG4 >= dev->num_addr)
                return PDC_INVALID_ARG;
            result[0] = dev->add_addr[ARG4];
            result[1] = HPA_is_graphics_device(hpa) ? GFX_NUM_PAGES : 1;
            return PDC_OK;

        case PDC_TRANSLATE_PATH:
            mod_path = (struct pdc_module_path *)ARG3;
            hppa_device_t *dev = find_hppa_device_by_path(0, mod_path, &hpa_index, 1); // XXX
            if (0) {
                dprintf(1, "PDC_TRANSLATE_PATH dev=%p hpa=%lx ", dev, dev ? dev->hpa:0UL);
                print_mod_path(mod_path);
                if (dev && dev->pci)
                    dprintf(1, "PCI %pP ", dev->pci);
                dprintf(1, "\n");
            }
            if (!dev)
                return PDC_NE_MOD;

            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;
            result[3] = hpa_index;
            return PDC_OK;
    }
    return PDC_BAD_OPTION;
}

static int pdc_soft_power(unsigned int *arg)
{
    unsigned long option = ARG1;
    unsigned long *result = (unsigned long *)ARG2;

    switch (option) {
        case PDC_SOFT_POWER_INFO:
            result[0] = (unsigned long) powersw_ptr;
            return PDC_OK;
        case PDC_SOFT_POWER_ENABLE:
            /* put soft power button under hardware (ARG3=0) or
             * software (ARG3=1) control. */
            *powersw_ptr = (ARG3 & 1) << 8 | (*powersw_ptr & 1);
            check_powersw_button();
            return PDC_OK;
    }
    // dprintf(0, "\n\nSeaBIOS: PDC_SOFT_POWER called with ARG2=%x ARG3=%x ARG4=%x\n", ARG2, ARG3, ARG4);
    return PDC_BAD_OPTION;
}

static int pdc_mem_map(unsigned int *arg)
{
    unsigned long option = ARG1;
    struct pdc_memory_map *memmap = (struct pdc_memory_map *) ARG2;
    struct pdc_module_path *dp = (struct pdc_module_path *) ARG3;
    hppa_device_t *dev;
    unsigned long index;

    switch (option) {
        case PDC_MEM_MAP_HPA:
// NEEDS FIXING !!
            dprintf(0, "\nSeaBIOS: PDC_MEM_MAP_HPA  bus = %d,  mod = %d\n", dp->path.bc[4], dp->path.mod);
            dev = find_hppa_device_by_path(memmap->hpa, (struct pdc_module_path *) dp, &index, 0); // ??
            if (!dev)
                return PDC_NE_MOD;
            memcpy(memmap, dev->mod_info, sizeof(*memmap));
            return PDC_OK;
    }
    return PDC_BAD_OPTION;
}

static int pdc_io(unsigned int *arg)
{
    unsigned long option = ARG1;

    switch (option) {
        case PDC_IO_READ_AND_CLEAR_ERRORS:
            dprintf(0, "\n\nSeaBIOS: PDC_IO called with ARG2=%x ARG3=%x ARG4=%x\n", ARG2, ARG3, ARG4);
            // return PDC_BAD_OPTION;
        case PDC_IO_RESET:
        case PDC_IO_RESET_DEVICES:
            return PDC_OK;
    }
    return PDC_BAD_OPTION;
}

static int pdc_lan_station_id(unsigned int *arg)
{
    unsigned long option = ARG1;

    switch (option) {
        case PDC_LAN_STATION_ID_READ:
            if (ARG3 != LASI_LAN_HPA)
                return PDC_INVALID_ARG;
            if (!keep_this_hpa(LASI_LAN_HPA))
                return PDC_INVALID_ARG;
            /* Let qemu store the MAC of NIC to address @ARG2 */
            *(unsigned long *)(LASI_LAN_HPA+12) = ARG2;
            return PDC_OK;
    }
    return PDC_BAD_OPTION;
}


#if 0
[    3.212566] iosapic Interrupt Routing Table (cell 0)
[    3.282568] iosapic start = 0x1302f980 num_entries 5 entry_size 16
[    3.362568] iosapic 8b10000f30000002 fffffffffed30800 -   8b 10 00 0f 30 00 00 02 fffffffffed30800
[    3.482568] iosapic 8b10000f34000003 fffffffffed30800 -   8b 10 00 0f 34 00 00 03 fffffffffed30800
[    3.592568] iosapic 8b10000d3b000000 fffffffffed30800 -   8b 10 00 0d 3b 00 00 00 fffffffffed30800
[    3.712568] iosapic 8b10000f3c000001 fffffffffed30800 -   8b 10 00 0f 3c 00 00 01 fffffffffed30800
[    3.832568] iosapic 8b10000f3c000001 fffffffffed30800 -   8b 10 00 0f 3c 00 00 01 fffffffffed30800
                printk(MODULE_NAME " %016llx %016llx -   %02x %02x %02x %02x %02x %02x %02x %02x %08x%08x\n",
                p1[0], p1[1],
                p->entry_type, p->entry_length, p->interrupt_type, p->polarity_trigger,
		p->src_bus_irq_devno, p->src_bus_id, p->src_seg_id, p->dest_iosapic_intin,
                ((u32 *) p)[2],
                ((u32 *) p)[3]
#endif
#define IRT_TABLE_ENTRIES 24
#define IOSAPIC_HPA       0xfffffffffed30800ULL
#define ELROY_IRQS        8 /* IOSAPIC IRQs */
static int irt_table_entries;
static u32 irt_table[IRT_TABLE_ENTRIES * 16/sizeof(u32)];

static void iosapic_table_setup(void)
{
    struct pci_device *pci;
    u32 *p;
    u8 slot = 0, iosapic_intin = 0, irq_devno, bus_id;

    irt_table_entries = 0;
    memset(irt_table, 0, sizeof(irt_table));
    p = irt_table;

    foreachpci(pci) {
        // if (!pci->irq) continue;
        BUG_ON(irt_table_entries >= IRT_TABLE_ENTRIES);
        irt_table_entries++;
        dprintf(5, "IRT ENTRY #%d: bdf %02x\n", irt_table_entries, pci->bdf);
        /* write the 16 bytes */
        /* 1: entry_type, entry_length, interrupt_type, polarity_trigger */
        *p++ = 0x8b10000f;      // oder 0x8b10000d
        /* 2: src_bus_irq_devno, src_bus_id, src_seg_id, dest_iosapic_intin */
        /* irq_devno = (slot << 2) | (intr_pin-1); */
        irq_devno = (slot++ << 2) | (pci->irq - 1);
        bus_id = 0;
        *p++ = (irq_devno << 24) | (bus_id << 16) | (0 << 8) | (iosapic_intin << 0);
        *p++ = IOSAPIC_HPA >> 32;
        *p++ = (u32) IOSAPIC_HPA;
        iosapic_intin++;
        iosapic_intin &= (ELROY_IRQS - 1 );
    }
}

static int pdc_pci_index(unsigned int *arg)
{
    unsigned long option = ARG1;
    unsigned long *result = (unsigned long *)ARG2;
    /* machines with Dino don't provide this info */

    // dprintf(0, "\n\nSeaBIOS: PDC_PCI_INDEX(%lu) called with ARG2=%x ARG3=%x ARG4=%x\n", option, ARG2, ARG3, ARG4);
    switch (option) {
        case PDC_PCI_INTERFACE_INFO:
            memset(result, 0, 32 * sizeof(unsigned long));
            // BUG_ON(1);
            result[0] = 2;  /* XXX physical hardware returns those ?!? */
            return PDC_OK;
        case PDC_PCI_GET_INT_TBL_SIZE:
            if (!has_astro)
                return PDC_BAD_OPTION;
            result[0] = irt_table_entries;
            return PDC_OK;
        case PDC_PCI_GET_INT_TBL:
            if (!has_astro)
                return PDC_BAD_OPTION;
            result[0] = irt_table_entries;
            /* ARG4 is ptr to irt table */
            memcpy((void *)ARG4, irt_table, irt_table_entries * 16);
            return PDC_OK;
        case PDC_PCI_PCI_PATH_TO_PCI_HPA:
            BUG_ON(1);
            result[0] = pci_hpa;
            return PDC_OK;
        case PDC_PCI_PCI_HPA_TO_PCI_PATH:
            BUG_ON(1);
            break;
    }
    return PDC_BAD_OPTION;
}

static int pdc_initiator(unsigned int *arg)
{
    unsigned long option = ARG1;
    unsigned long *result = (unsigned long *)ARG2;

    switch (option) {
        case PDC_GET_INITIATOR:
            /* SCSI controller is on normal PCI bus on machines with Astro */
            if (has_astro) return PDC_BAD_OPTION;
            // ARG3 points to the hwpath of device for which initiator is asked for.
            result[0] = 7;  // initiator_id/host_id: 7 to 15.
            result[1] = 10; // scsi_rate: 1, 2, 5 or 10 for 5, 10, 20 or 40 MT/s
            result[2] = 7;  // firmware suggested value for initiator_id
            result[3] = 10; // firmware suggested value for scsi_rate
            result[4] = 0;  // width: 0:"Narrow, 1:"Wide"
            result[5] = 0; // mode: 0:SMODE_SE, 1:SMODE_HVD, 2:SMODE_LVD
            return PDC_OK;
        case PDC_SET_INITIATOR:
        case PDC_DELETE_INITIATOR:
        case PDC_RETURN_TABLE_SIZE:
        case PDC_RETURN_TABLE:
            break;
    }
    dprintf(0, "\n\nSeaBIOS: Unimplemented PDC_INITIATOR function %ld ARG3=%x ARG4=%x ARG5=%x\n", option, ARG3, ARG4, ARG5);
    return PDC_BAD_OPTION;
}


int __VISIBLE parisc_pdc_entry(unsigned int *arg FUNC_MANY_ARGS)
{
    unsigned long proc = ARG0;
    unsigned long option = ARG1;

    if (pdc_debug & DEBUG_PDC) {
        printf("\nSeaBIOS: Start PDC proc %s(%d) option %d result=0x%x ARG3=0x%x %s ",
                pdc_name(ARG0), ARG0, ARG1, ARG2, ARG3, (proc == PDC_IODC)?hpa_name(ARG3):"");
        printf("ARG4=0x%x ARG5=0x%x ARG6=0x%x ARG7=0x%x\n", ARG4, ARG5, ARG6, ARG7);
    }

    switch (proc) {
        case PDC_POW_FAIL:
            break;

        case PDC_CHASSIS: /* chassis functions */
            return pdc_chassis(arg);

        case PDC_PIM:
            return pdc_pim(arg);

        case PDC_MODEL: /* model information */
            return pdc_model(arg);

        case PDC_CACHE:
            return pdc_cache(arg);

        case PDC_HPA:
            return pdc_hpa(arg);

        case PDC_COPROC:
            return pdc_coproc(arg);

        case PDC_IODC: /* Call IODC functions */
            return pdc_iodc(arg);

        case PDC_TOD:	/* Time of day */
            return pdc_tod(arg);

        case PDC_STABLE:
            return pdc_stable(arg);

        case PDC_NVOLATILE:
            return pdc_nvolatile(arg);

        case PDC_ADD_VALID:
            return pdc_add_valid(arg);

        case PDC_INSTR:
            return PDC_BAD_PROC;

        case PDC_PROC:
            return pdc_proc(arg);

        case PDC_CONFIG:	/* Obsolete */
            return PDC_BAD_PROC;

        case PDC_BLOCK_TLB:
            return pdc_block_tlb(arg);

        case PDC_TLB:		/* hardware TLB not used on Linux, but on HP-UX (if available) */
            return pdc_tlb(arg);

        case PDC_MEM:
            return pdc_mem(arg);

        case PDC_PSW:	/* Get/Set default System Mask  */
            return pdc_psw(arg);

        case PDC_SYSTEM_MAP:
            return pdc_system_map(arg);

        case PDC_SOFT_POWER: // don't have a soft-power switch
            return pdc_soft_power(arg);

        case PDC_CRASH_PREP:
            /* This should actually quiesce all I/O and prepare the System for crash dumping.
               Ignoring it for now, otherwise the BUG_ON below would quit qemu before we have
               a chance to see the kernel panic */
            return PDC_OK;

        case 26: // PDC_SCSI_PARMS is the architected firmware interface to replace the Hversion PDC_INITIATOR procedure.
            return PDC_BAD_PROC;

        case 64: // Called by HP-UX 11 bootcd during boot. Probably checks PDC_PAT_CELL (even if we are not PAT firmware)
        case 65: // Called by HP-UX 11 bootcd during boot. Probably checks PDC_PAT_CHASSIS_LOG (even if we are not PAT firmware)
            dprintf(0, "\n\nSeaBIOS: UNKNOWN PDC proc %lu OPTION %lu called with ARG2=%x ARG3=%x ARG4=%x\n", proc, option, ARG2, ARG3, ARG4);
            return PDC_BAD_PROC;

	case PDC_MEM_MAP:
            return pdc_mem_map(arg);

        case 134:
            if (ARG1 == 1 || ARG1 == 513) /* HP-UX 11.11 ask for it. */
                return PDC_BAD_PROC;
            break;

        case PDC_IO:
            return pdc_io(arg);

        case PDC_BROADCAST_RESET:
            dprintf(0, "\n\nSeaBIOS: PDC_BROADCAST_RESET (reset system) called with ARG3=%x ARG4=%x\n", ARG3, ARG4);
            reset();
            return PDC_OK;

        case PDC_LAN_STATION_ID:
            return pdc_lan_station_id(arg);

        case PDC_SYSTEM_INFO:
            if (ARG1 == PDC_SYSINFO_RETURN_INFO_SIZE)
                return PDC_BAD_PROC;
            break;

        case PDC_PCI_INDEX:
            return pdc_pci_index(arg);

        case PDC_RELOCATE:
            /* We don't want to relocate any firmware. */
            return PDC_BAD_PROC;

        case PDC_INITIATOR:
            return pdc_initiator(arg);
    }

    printf("\n** WARNING **: SeaBIOS: Unimplemented PDC proc %s(%d) option %d result=%x ARG3=%x ",
            pdc_name(ARG0), ARG0, ARG1, ARG2, ARG3);
    printf("ARG4=%x ARG5=%x ARG6=%x ARG7=%x\n", ARG4, ARG5, ARG6, ARG7);

    BUG_ON(pdc_debug);
    return PDC_BAD_PROC;
}

/********************************************************
 * TOC HANDLER
 ********************************************************/

unsigned long __VISIBLE toc_handler(struct pdc_toc_pim_11 *pim)
{
        unsigned long hpa, os_toc_handler;
        int cpu, y;
        unsigned long *p;
        struct pdc_toc_pim_11 *pim11;
        struct pdc_toc_pim_20 *pim20;
        struct pim_cpu_state_cf state = { .iqv=1, .iqf=1, .ipv=1, .grv=1, .crv=1, .srv=1, .trv=1, .td=1 };

        hpa = mfctl(CPU_HPA_CR_REG); /* get CPU HPA from cr7 */
        cpu = index_of_CPU_HPA(hpa);

        pim11 = &pim_toc_data[cpu].pim11;
        pim20 = &pim_toc_data[cpu].pim20;
        if (is_64bit())
                pim20->cpu_state = state;
        else
                pim11->cpu_state = state;

        /* check that we use the same PIM entries as assembly code */
        BUG_ON(pim11 != pim);

        printf("\n");
        printf("##### CPU %d HPA %lx: SeaBIOS TOC register dump #####\n", cpu, hpa);
        for (y = 0; y < 32; y += 8) {
                if (is_64bit())
                        p = (unsigned long *)&pim20->gr[y];
                else
                        p = (unsigned long *)&pim11->gr[y];
                printf("GR%02d: %lx %lx %lx %lx",  y, p[0], p[1], p[2], p[3]);
                printf(       " %lx %lx %lx %lx\n",   p[4], p[5], p[6], p[7]);
        }
        printf("\n");
        for (y = 0; y < 32; y += 8) {
                if (is_64bit())
                        p = (unsigned long *)&pim20->cr[y];
                else
                        p = (unsigned long *)&pim11->cr[y];
                printf("CR%02d: %lx %lx %lx %lx", y, p[0], p[1], p[2], p[3]);
                printf(       " %lx %lx %lx %lx\n",  p[4], p[5], p[6], p[7]);
        }
        printf("\n");
        if (is_64bit())
                p = (unsigned long *)&pim20->sr[0];
        else
                p = (unsigned long *)&pim11->sr[0];
        printf("SR0: %lx %lx %lx %lx %lx %lx %lx %lx\n", p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
        if (is_64bit()) {
                printf("IAQ: %lx.%lx %lx.%lx   PSW: %lx\n",
                        (unsigned long)pim20->cr[17], (unsigned long)pim20->cr[18],
                        (unsigned long)pim20->iasq_back, (unsigned long)pim20->iaoq_back,
			(unsigned long)pim20->cr[22]);
                printf("RP(r2): %lx\n", (unsigned long)pim20->gr[2]);
        } else {
                printf("IAQ: %x.%x %x.%x   PSW: %x\n", pim11->cr[17], pim11->cr[18],
                        pim11->iasq_back, pim11->iaoq_back, pim11->cr[22]);
                printf("RP(r2): %x\n", pim11->gr[2]);
        }

        os_toc_handler = PAGE0->vec_toc;
        if (is_64bit())
                os_toc_handler |= ((unsigned long long) PAGE0->vec_toc_hi << 32);

        /* release lock - let other CPUs join now. */
        toc_lock = 1;

        num_online_cpus--;

        if (os_toc_handler) {
                /* will call OS handler, after all CPUs are here */
                while (num_online_cpus)
                        ; /* wait */
                return os_toc_handler; /* let asm code call os handler */
        }

        /* No OS handler installed. Wait for all CPUs, then last CPU will reset. */
        if (num_online_cpus)
                while (1) /* this CPU will wait endless. */;

        printf("SeaBIOS: Resetting machine after TOC.\n");
        reset();
}

/********************************************************
 * BOOT MENU
 ********************************************************/

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"
            "        EXIT                            Exit QEMU emulation\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, reply;

    // 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] == 'L' && input[1] == 'S')     // HELP? (ls)
        goto again;
    if (input[0] == 'E' && input[1] == 'X')     // EXIT
        hlt();
    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');
    reply = input[0];
    if (reply == 'C' || reply == 'c')
        goto again2;
    // allow Z as Y. It's the key used on german keyboards.
    if (reply == 'Y' || reply == 'y' || reply == 'Z' || reply == 'z')
        interact_ipl = 1;
}

static int parisc_boot_menu(unsigned long *iplstart, unsigned long *iplend,
        char bootdrive)
{
    int ret;
    unsigned int *target = (void *)(PAGE0->mem_free + 32*1024);
    struct disk_op_s disk_op = {
        .buf_fl = target,
        .command = CMD_SEEK,
        .count = 0,
        .lba = 0,
    };

    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);
    // printf("DISK_SEEK returned %d\n", ret);
    if (ret)
        return 0;

    // printf("Boot disc type is 0x%x\n", boot_drive->type);
    disk_op.drive_fl = boot_drive;
    if (boot_drive->type == DTYPE_ATA_ATAPI ||
            boot_drive->type == DTYPE_ATA) {
        disk_op.command = CMD_ISREADY;
        ret = process_op(&disk_op);
    } else {
        ret = scsi_is_ready(&disk_op);
    }
    // printf("DISK_READY returned %d\n", ret);

    /* read boot sector of disc/CD */
    disk_op.drive_fl = boot_drive;
    disk_op.buf_fl = target;
    disk_op.command = CMD_READ;
    disk_op.count = (FW_BLOCKSIZE / disk_op.drive_fl->blksize);
    disk_op.lba = 0;
    // printf("blocksize is %d, count is %d\n", disk_op.drive_fl->blksize, disk_op.count);
    ret = process_op(&disk_op);
    // printf("DISK_READ(count=%d) = %d\n", disk_op.count, ret);
    if (ret)
        return 0;

    unsigned int ipl_addr = be32_to_cpu(target[0xf0/sizeof(int)]); /* offset 0xf0 in bootblock */
    unsigned int ipl_size = be32_to_cpu(target[0xf4/sizeof(int)]);
    unsigned int ipl_entry= be32_to_cpu(target[0xf8/sizeof(int)]);

    /* check LIF header of bootblock */
    if ((target[0]>>16) != 0x8000) {
        printf("Not a PA-RISC boot image. LIF magic is 0x%x, should be 0x8000.\n", target[0]>>16);
        return 0;
    }
    // printf("ipl start at 0x%x, size %d, entry 0x%x\n", ipl_addr, ipl_size, ipl_entry);
    // TODO: check ipl values for out of range. Rules are:
    // IPL_ADDR - 2 Kbyte aligned, nonzero.
    // IPL_SIZE - Multiple of 2 Kbytes, nonzero, less than or equal to 256 Kbytes.
    // IPL_ENTRY-  Word aligned, less than IPL_SIZE

    /* seek to beginning of IPL */
    disk_op.drive_fl = boot_drive;
    disk_op.command = CMD_SEEK;
    disk_op.count = 0; // (ipl_size / disk_op.drive_fl->blksize);
    disk_op.lba = (ipl_addr / disk_op.drive_fl->blksize);
    ret = process_op(&disk_op);
    // printf("DISK_SEEK to IPL returned %d\n", ret);

    /* read IPL */
    disk_op.drive_fl = boot_drive;
    disk_op.buf_fl = target;
    disk_op.command = CMD_READ;
    disk_op.count = (ipl_size / disk_op.drive_fl->blksize);
    disk_op.lba = (ipl_addr / disk_op.drive_fl->blksize);
    ret = process_op(&disk_op);
    // printf("DISK_READ IPL returned %d\n", ret);

    // printf("First word at %p is 0x%x\n", target, target[0]);

    /* execute IPL */
    // TODO: flush D- and I-cache, not needed in emulation ?
    *iplstart = *iplend = (unsigned long) target;
    *iplstart += ipl_entry;
    *iplend += ALIGN(ipl_size, sizeof(unsigned long));
    return 1;
}


/********************************************************
 * FIRMWARE MAIN ENTRY POINT
 ********************************************************/

static const struct pz_device mem_cons_sti_boot = {
    .hpa = LASI_GFX_HPA,
    .iodc_io = (unsigned long)&iodc_entry,
    .cl_class = CL_DISPL,
};

static const struct pz_device mem_kbd_sti_boot = {
    .hpa = LASI_PS2KBD_HPA,
    .iodc_io = (unsigned long)&iodc_entry,
    .cl_class = CL_KEYBD,
};

static struct pz_device mem_cons_boot = {
    .hpa = PARISC_SERIAL_CONSOLE - 0x800,
    .iodc_io = (unsigned long)&iodc_entry,
    .cl_class = CL_DUPLEX,
};

static struct pz_device mem_kbd_boot = {
    .hpa = PARISC_SERIAL_CONSOLE - 0x800,
    .iodc_io = (unsigned long)&iodc_entry,
    .cl_class = CL_KEYBD,
};

static struct pz_device mem_boot_boot = {
    .dp.path.flags = PF_AUTOBOOT,
    .hpa = DINO_SCSI_HPA,  // will be overwritten
    .iodc_io = (unsigned long) &iodc_entry,
    .cl_class = CL_RANDOM,
};

#if 0
static void find_pci_slot_for_dev(unsigned int vendor, char *pci_slot)
{
    struct pci_device *pci;

    foreachpci(pci)
        if (pci->vendor == vendor) {
            *pci_slot = (pci->bdf >> 3) & 0x0f;
            return;
        }
}
#endif

/* find serial PCI card (to be used as console) */
static void find_serial_pci_card(void)
{
    struct pci_device *pci;
    hppa_device_t *pdev;
    u32 pmem;

    if (!has_astro)     /* use built-in LASI serial port for console */
        return;

    pci = pci_find_class(PCI_CLASS_COMMUNICATION_SERIAL);
    if (!pci)
        return;

    dprintf(1, "PCI: Enabling %pP for primary SERIAL PORT\n", pci);
    pci_config_maskw(pci->bdf, PCI_COMMAND, 0,
                     PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
    pmem = pci_enable_iobar(pci, PCI_BASE_ADDRESS_0);
    dprintf(1, "PCI: Enabling %pP for primary SERIAL PORT mem %x\n", pci, pmem);
    pmem += IOS_DIST_BASE_ADDR;

    /* set serial port for console output and keyboard input */
    pdev = &hppa_pci_devices[0];
    while (pdev->pci != pci)
        pdev++;
    pdev->pci_addr = pmem;
    mem_cons_boot.hpa = pdev->hpa;
    mem_kbd_boot.hpa = pdev->hpa;
}

/* find SCSI PCI card (to be used as boot device) */
static void find_scsi_pci_card(void)
{
    struct pci_device *pci;
    hppa_device_t *pdev;
    u32 pmem;

    // if (!has_astro) return;
    pci = pci_find_class(PCI_CLASS_STORAGE_SCSI);
    if (!pci)
        return;
    dprintf(1, "PCI: Enabling %pP for primary SCSI PORT\n", pci);
    pmem = pci_enable_iobar(pci, PCI_BASE_ADDRESS_0);
    dprintf(1, "PCI: Enabling %pP for primary SCSI PORT mem %x\n", pci, pmem);
    pmem += IOS_DIST_BASE_ADDR;

    /* set SCSI HPA */
    pdev = &hppa_pci_devices[0];
    while (pdev->pci != pci)
        pdev++;
    pdev->pci_addr = pmem;
    mem_boot_boot.hpa = pdev->hpa;
    dprintf(1, "PCI: Enabling BOOT DEVICE HPA %x\n", mem_boot_boot.hpa);
}


/* Prepare boot paths in PAGE0 and stable memory */
static void prepare_boot_path(volatile struct pz_device *dest,
        const struct pz_device *source,
        unsigned int stable_offset)
{
    hppa_device_t *dev;
    unsigned long hpa;
    struct pdc_module_path *mod_path;

    hpa = source->hpa;
    dev = find_hpa_device(hpa);
    BUG_ON(!dev);

    if (DEV_is_storage_device(dev))
        mod_path = &mod_path_emulated_drives;
    else if (dev)
        mod_path = dev->mod_path;
    else {
        BUG_ON(1);
    }

    /* copy device path to entry in PAGE0 */
    memcpy((void*)dest, source, sizeof(*source));
    memcpy((void*)&dest->dp, mod_path, sizeof(struct pdc_module_path));

    /* copy device path to stable storage */
    memcpy(&stable_storage[stable_offset], mod_path, sizeof(*mod_path));

    BUG_ON(sizeof(*mod_path) != 0x20);
    BUG_ON(sizeof(struct pdc_module_path) != 0x20);
}

static int artist_present(void)
{
    return !!(*(u32 *)0xf8380004 == 0x6dc20006);
}

unsigned long _atoul(char *str)
{
    unsigned long val = 0;
    while (*str) {
        val *= 10;
        val += *str - '0';
        str++;
    }
    return val;
}

unsigned long romfile_loadstring_to_int(const char *name, unsigned long defval)
{
    char *str = romfile_loadfile(name, NULL);
    if (str)
        return _atoul(str);
    return defval;
}

void __VISIBLE start_parisc_firmware(void)
{
    unsigned int i, cpu_hz;
    unsigned long iplstart, iplend;
    char *str;

    char bootdrive = (char)cmdline; // c = hdd, d = CD/DVD
    show_boot_menu = (linux_kernel_entry == 1);

    // detect if we emulate a 32- or 64-bit CPU.
    // set all bits in cr11, read back, and if the return
    // value is 63 this is a 64-bit capable CPU.
    // A 32-bit only CPU returns 31.
    mtctl(-1UL, 11);
    cpu_bit_width = (mfctl(11) == 63) ? 64 : 32;
    // cpu_bit_width = 64; /* XXX HACK */

    if (smp_cpus > HPPA_MAX_CPUS)
        smp_cpus = HPPA_MAX_CPUS;
    num_online_cpus = smp_cpus;

    if (ram_size >= FIRMWARE_START)
        ram_size = FIRMWARE_START;

    /* Initialize malloc stack */
    malloc_preinit();

    // PlatformRunningOn = PF_QEMU;  // emulate runningOnQEMU()

    /* Initialize qemu fw_cfg interface */
    PORT_QEMU_CFG_CTL = fw_cfg_port;
    qemu_cfg_init();

    /* Initialize boot structures. Needs working fw_cfg for bootprio option. */
    boot_init();

    DebugOutputPort = romfile_loadint("/etc/hppa/DebugOutputPort", CPU_HPA + 24);

    i = romfile_loadint("/etc/firmware-min-version", 0);
    if (i && i > SEABIOS_HPPA_VERSION) {
        printf("\nSeaBIOS firmware is version %d, but version %d is required. "
            "Please update.\n", (int)SEABIOS_HPPA_VERSION, i);
        hlt();
    }

    /* which machine shall we emulate? */
    str = romfile_loadfile("/etc/hppa/machine", NULL);
    if (!str) {
        str = "B160L";
        current_machine = &machine_B160L;
        pci_hpa = DINO_HPA;
        hppa_port_pci_cmd  = pci_hpa + DINO_PCI_ADDR;
        hppa_port_pci_data = pci_hpa + DINO_CONFIG_DATA;
    }
    if (strcmp(str, "C3700") == 0) {
        has_astro = 1;
        current_machine = &machine_C3700;
        pci_hpa = (unsigned long) ELROY0_BASE_HPA;
        hppa_port_pci_cmd  = pci_hpa + 0x040;
        hppa_port_pci_data = pci_hpa + 0x048;
        /* no serial port for now, will find later */
        mem_cons_boot.hpa = 0;
        mem_kbd_boot.hpa = 0;
    }
    parisc_devices = current_machine->device_list;
    strtcpy(qemu_machine, str, sizeof(qemu_machine));

    tlb_entries = romfile_loadint("/etc/cpu/tlb_entries", 256);
    dprintf(0, "fw_cfg: TLB entries %d\n", tlb_entries);

    powersw_ptr = (int *) (unsigned long)
        romfile_loadint("/etc/hppa/power-button-addr", (unsigned long)&powersw_nop);

    /* real-time-clock addr */
    rtc_ptr = (int *) (unsigned long)
        romfile_loadint("/etc/hppa/rtc-addr", (unsigned long) LASI_RTC_HPA);
    // dprintf(0, "RTC PTR 0x%x\n", (int)rtc_ptr);

    /* use -fw_cfg opt/pdc_debug,string=255 to enable all firmware debug infos */
    pdc_debug = romfile_loadstring_to_int("opt/pdc_debug", 0);

    pdc_console = CONSOLE_DEFAULT;
    str = romfile_loadfile("opt/console", NULL);
    if (str) {
	if (strcmp(str, "serial") == 0)
		pdc_console = CONSOLE_SERIAL;
	if (strcmp(str, "graphics") == 0)
		pdc_console = CONSOLE_GRAPHICS;
    }

    /* 0,1 = default 8x16 font, 2 = 16x32 font */
    sti_font = romfile_loadstring_to_int("opt/font", 0);

    current_machine->pdc_model.sw_id = romfile_loadstring_to_int("opt/hostid",
					current_machine->pdc_model.sw_id);
    dprintf(0, "fw_cfg: machine hostid %lu\n", current_machine->pdc_model.sw_id);

    str = romfile_loadfile("/etc/qemu-version", NULL);
    if (str)
        strtcpy(qemu_version, str, sizeof(qemu_version));

    /* Do not initialize PAGE0. We have the boot args stored there. */
    /* memset((void*)PAGE0, 0, sizeof(*PAGE0)); */

    /* copy pdc_entry entry into low memory. */
    memcpy((void*)MEM_PDC_ENTRY, &pdc_entry_table, 3*4);
    flush_data_cache((char*)MEM_PDC_ENTRY, 3*4);

    PAGE0->memc_cont = ram_size;
    PAGE0->memc_phsize = ram_size;
    PAGE0->memc_adsize = ram_size;
    PAGE0->mem_pdc_hi = (MEM_PDC_ENTRY + 0ULL) >> 32;
    PAGE0->mem_free = 0x6000; // min PAGE_SIZE
    PAGE0->mem_hpa = CPU_HPA; // HPA of boot-CPU
    PAGE0->mem_pdc = MEM_PDC_ENTRY;
    PAGE0->mem_10msec = CPU_CLOCK_MHZ*(1000000ULL/100);

    BUG_ON(PAGE0->mem_free <= MEM_PDC_ENTRY);
    BUG_ON(smp_cpus < 1 || smp_cpus > HPPA_MAX_CPUS);
    BUG_ON(sizeof(pim_toc_data[0]) != PIM_STORAGE_SIZE);

    /* Put QEMU/SeaBIOS marker in PAGE0.
     * The Linux kernel will search for it. */
    memcpy((char*)&PAGE0->pad0, "SeaBIOS", 8);
    PAGE0->pad0[2] = ((unsigned long long)PORT_QEMU_CFG_CTL) >> 32; /* store as 64bit value */
    PAGE0->pad0[3] = PORT_QEMU_CFG_CTL;
    *powersw_ptr = 0x01; /* button not pressed, hw controlled. */

    /* PAGE0->imm_hpa - is set later (MEMORY_HPA) */
    PAGE0->imm_spa_size = ram_size;
    PAGE0->imm_max_mem = ram_size;

    /* initialize graphics (if available) */
    if (artist_present()) {
        sti_rom_init();
        sti_console_init(&sti_proc_rom);
        PAGE0->proc_sti = (u32)&sti_proc_rom;
        if (has_astro)
            kbd_init();
        else
            ps2port_setup();
    } else {
        remove_from_keep_list(LASI_GFX_HPA);
        remove_from_keep_list(LASI_PS2KBD_HPA);
        remove_from_keep_list(LASI_PS2MOU_HPA);
    }

    /* Initialize device list */
    keep_add_generic_devices();
    remove_parisc_devices(smp_cpus);

    /* Show list of HPA devices which are still returned by firmware. */
    if (0) { for (i=0; parisc_devices[i].hpa; i++)
        printf("Kept #%d at 0x%lx\n", i, parisc_devices[i].hpa);
    }

    // Initialize stable storage
    init_stable_storage();

    chassis_code = 0;

    cpu_hz = 100 * PAGE0->mem_10msec; /* Hz of this PARISC */
    dprintf(1, "\nPARISC SeaBIOS Firmware, %d x %d-bit PA-RISC CPU at %d.%06d MHz, %d MB RAM.\n",
            smp_cpus, cpu_bit_width, cpu_hz / 1000000, cpu_hz % 1000000,
            ram_size/1024/1024);

    if (ram_size < MIN_RAM_SIZE) {
        printf("\nSeaBIOS: Machine configured with too little "
                "memory (%d MB), minimum is %d MB.\n\n",
                ram_size/1024/1024, MIN_RAM_SIZE/1024/1024);
        hlt();
    }

    // handle_post();
    serial_debug_preinit();
    debug_banner();
    // maininit();
    qemu_preinit();
    RamSize = ram_size;
    // coreboot_preinit();

    pci_setup();
    if (has_astro) {
        iosapic_table_setup();
    }
    hppa_pci_build_devices_list();

    /* find serial PCI card when running on Astro */
    find_serial_pci_card();

    serial_setup();
    // ohci_setup();
    block_setup();

    /* find SCSI PCI card when running on Astro or Dino */
    find_scsi_pci_card();

    // Initialize boot paths (graphics & keyboard)
    if (pdc_console != CONSOLE_SERIAL) {
	if (artist_present())
            pdc_console = CONSOLE_GRAPHICS;
	else
            pdc_console = CONSOLE_SERIAL;
    }
    if (pdc_console == CONSOLE_GRAPHICS) {
        prepare_boot_path(&(PAGE0->mem_cons), &mem_cons_sti_boot, 0x60);
        prepare_boot_path(&(PAGE0->mem_kbd),  &mem_kbd_sti_boot, 0xa0);
    } else {
        prepare_boot_path(&(PAGE0->mem_cons), &mem_cons_boot, 0x60);
        prepare_boot_path(&(PAGE0->mem_kbd),  &mem_kbd_boot, 0xa0);
    }

    PAGE0->vec_rendz = 0; /* No rendezvous yet. Add MEM_RENDEZ_HI later */

    printf("\n");
    printf("SeaBIOS PA-RISC Firmware Version " SEABIOS_HPPA_VERSION_STR
           " (QEMU %s)\n\n"
            "Duplex Console IO Dependent Code (IODC) revision 1\n"
            "\n", qemu_version);
    printf("------------------------------------------------------------------------------\n"
            "  (c) Copyright 2017-2023 Helge Deller <deller@gmx.de> and SeaBIOS developers.\n"
            "------------------------------------------------------------------------------\n\n");
    printf( "  Processor   Speed            State           Coprocessor State  Cache Size\n"
            "  ---------  --------   ---------------------  -----------------  ----------\n");
    for (i = 0; i < smp_cpus; i++)
        printf("     %s%d      " __stringify(CPU_CLOCK_MHZ)
                " MHz    %s                 Functional            0 KB\n",
                i < 10 ? " ":"", i, i?"Idle  ":"Active");
    printf("\n\n");
    printf("  Emulated machine:     HP %s (%d-bit %s)\n"
            "  Available memory:     %u MB\n"
            "  Good memory required: %d MB\n\n",
            qemu_machine, cpu_bit_width, (cpu_bit_width == 64) ? "PA2.0" : "PA1.1",
            ram_size/1024/1024, MIN_RAM_SIZE/1024/1024);

    // search boot devices
    find_initial_parisc_boot_drives(&parisc_boot_harddisc, &parisc_boot_cdrom);

    printf("  Primary boot path:    FWSCSI.%d.%d\n"
           "  Alternate boot path:  FWSCSI.%d.%d\n"
           "  Console path:         %s\n"
           "  Keyboard path:        %s\n\n",
            parisc_boot_harddisc->target, parisc_boot_harddisc->lun,
            parisc_boot_cdrom->target, parisc_boot_cdrom->lun,
            hpa_device_name(PAGE0->mem_cons.hpa, 1),
            hpa_device_name(PAGE0->mem_kbd.hpa, 0));

    if (bootdrive == 'c')
        boot_drive = parisc_boot_harddisc;
    else
        boot_drive = parisc_boot_cdrom;

    // Find PCI bus id of LSI SCSI card
    // find_pci_slot_for_dev(PCI_VENDOR_ID_LSI_LOGIC, &mod_path_emulated_drives.path.bc[5]);

    // Store initial emulated drives path master data
    if (parisc_boot_harddisc) {
        mod_path_emulated_drives.layers[0] = parisc_boot_harddisc->target;
        mod_path_emulated_drives.layers[1] = parisc_boot_harddisc->lun;
    }

    prepare_boot_path(&(PAGE0->mem_boot), &mem_boot_boot, 0x0);

    // copy primary boot path to alt boot path
    memcpy(&stable_storage[0x80], &stable_storage[0], 0x20);
    if (parisc_boot_cdrom) {
        stable_storage[0x80 + 11] = parisc_boot_cdrom->target;
        stable_storage[0x80 + 12] = parisc_boot_cdrom->lun;
    }
    // currently booted path == CD in PAGE0->mem_boot
    if (boot_drive) {
        PAGE0->mem_boot.dp.layers[0] = boot_drive->target;
        PAGE0->mem_boot.dp.layers[1] = boot_drive->lun;
    }

    /* Qemu-specific: Drop *all* TLB entries for all CPUs before start. */
    /* Necessary if machine was rebooted. */
    asm("pdtlbe %%r0(%%sr1,%%r0)" : : : "memory");

    /* directly start Linux kernel if it was given on qemu command line. */
    if (linux_kernel_entry > 1) {
        void (*start_kernel)(unsigned long mem_free, unsigned long cline,
                unsigned long rdstart, unsigned long rdend);

        printf("Autobooting Linux kernel which was loaded by qemu...\n\n");
        start_kernel = (void *) linux_kernel_entry;
	/* zero out kernel entry point in case we reset the machine: */
        linux_kernel_entry = 0;
        start_kernel(PAGE0->mem_free, cmdline, initrd_start, initrd_end);
        hlt(); /* this ends the emulator */
    }

    /* 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);
    }

    hlt(); /* this ends the emulator */
}
