diff options
author | Helge Deller <deller@gmx.de> | 2023-10-08 20:45:09 +0200 |
---|---|---|
committer | Helge Deller <deller@gmx.de> | 2023-10-08 20:45:09 +0200 |
commit | 518055bfdb3ae3002640b9749ee517e8c29194eb (patch) | |
tree | b7b13b688bd5b88dc22da57e4f3e30ad964d8630 /src | |
parent | 3e63b39477e798e9d224a9fe53a2182383623168 (diff) | |
download | seabios-hppa-518055bfdb3ae3002640b9749ee517e8c29194eb.zip seabios-hppa-518055bfdb3ae3002640b9749ee517e8c29194eb.tar.gz seabios-hppa-518055bfdb3ae3002640b9749ee517e8c29194eb.tar.bz2 |
parisc: Serial port works, c3700 works, everything OK.
Diffstat (limited to 'src')
-rw-r--r-- | src/hw/pci.c | 4 | ||||
-rw-r--r-- | src/parisc/c3700.h | 27 | ||||
-rw-r--r-- | src/parisc/hppa.h | 4 | ||||
-rw-r--r-- | src/parisc/hppa_hardware.h | 2 | ||||
-rw-r--r-- | src/parisc/parisc.c | 475 |
5 files changed, 380 insertions, 132 deletions
diff --git a/src/hw/pci.c b/src/hw/pci.c index 763ca39..3f35250 100644 --- a/src/hw/pci.c +++ b/src/hw/pci.c @@ -42,7 +42,7 @@ static u32 ioconfig_cmd(u16 bdf, u32 addr) /* each elroy has 0x2000 offset */ #define ELROY_MAX_BUSSES 4 -static unsigned long elroy_offset(u16 bdf) +unsigned long elroy_offset(u16 bdf) { static const int elroy_hpa_offsets[ELROY_MAX_BUSSES] = { 0x30000, 0x32000, 0x38000, 0x3c000 }; int bus = pci_bdf_to_bus(bdf); @@ -51,7 +51,7 @@ static unsigned long elroy_offset(u16 bdf) return elroy_hpa_offsets[bus] - elroy_hpa_offsets[0]; } -static void *elroy_port(unsigned long port, unsigned long offs) +void *elroy_port(unsigned long port, unsigned long offs) { return (void *)(port + offs); } diff --git a/src/parisc/c3700.h b/src/parisc/c3700.h index 3634aeb..902b654 100644 --- a/src/parisc/c3700.h +++ b/src/parisc/c3700.h @@ -30,7 +30,7 @@ static struct pdc_system_map_mod_info mod_info_hpa_fed00000 = { .add_addrs = 0x0, }; static struct pdc_module_path mod_path_hpa_fed00000 = { - .path = { .flags = 0x0, .bc = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, .mod = 0xa }, + .path = { .flags = 0x0, .bc = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, .mod = ASTRO_BUS_MODULE }, .layers = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } }; static struct pdc_iodc iodc_data_hpa_fed00000 = { @@ -59,7 +59,7 @@ static struct pdc_system_map_mod_info mod_info_hpa_fed30000 = { .add_addrs = 0x0, }; static struct pdc_module_path mod_path_hpa_fed30000 = { - .path = { .flags = 0x0, .bc = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xa }, .mod = 0x0 }, + .path = { .flags = 0x0, .bc = { 0xff, 0xff, 0xff, 0xff, 0xff, ASTRO_BUS_MODULE }, .mod = 0x0 }, .layers = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } }; static struct pdc_iodc iodc_data_hpa_fed30000 = { @@ -88,7 +88,7 @@ static struct pdc_system_map_mod_info mod_info_hpa_fed32000 = { .add_addrs = 0x0, }; static struct pdc_module_path mod_path_hpa_fed32000 = { - .path = { .flags = 0x0, .bc = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xa }, .mod = 0x1 }, + .path = { .flags = 0x0, .bc = { 0xff, 0xff, 0xff, 0xff, 0xff, ASTRO_BUS_MODULE }, .mod = 0x1 }, .layers = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } }; static struct pdc_iodc iodc_data_hpa_fed32000 = { @@ -117,7 +117,7 @@ static struct pdc_system_map_mod_info mod_info_hpa_fed38000 = { .add_addrs = 0x0, }; static struct pdc_module_path mod_path_hpa_fed38000 = { - .path = { .flags = 0x0, .bc = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xa }, .mod = 0x4 }, + .path = { .flags = 0x0, .bc = { 0xff, 0xff, 0xff, 0xff, 0xff, ASTRO_BUS_MODULE }, .mod = 0x4 }, .layers = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } }; static struct pdc_iodc iodc_data_hpa_fed38000 = { @@ -146,7 +146,7 @@ static struct pdc_system_map_mod_info mod_info_hpa_fed3c000 = { .add_addrs = 0x0, }; static struct pdc_module_path mod_path_hpa_fed3c000 = { - .path = { .flags = 0x0, .bc = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xa }, .mod = 0x6 }, + .path = { .flags = 0x0, .bc = { 0xff, 0xff, 0xff, 0xff, 0xff, ASTRO_BUS_MODULE }, .mod = 0x6 }, .layers = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } }; static struct pdc_iodc iodc_data_hpa_fed3c000 = { @@ -179,6 +179,7 @@ static struct pdc_module_path mod_path_hpa_fffa0000 = { .layers = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } }; static struct pdc_iodc iodc_data_hpa_fffa0000 = { +#if 0 // original C3700: .hversion_model = 0x005d, .hversion = 0x00c0, .spa = 0x0000, @@ -186,6 +187,16 @@ static struct pdc_iodc iodc_data_hpa_fffa0000 = { .sversion_rev = 0x0000, .sversion_model = 0x0002, .sversion_opt = 0x0040, +#else + /* this is from B160L */ + .hversion_model = 0x0050, + .hversion = 0x0020, + .spa = 0x0000, + .type = 0x0040, + .sversion_rev = 0x0000, + .sversion_model = 0x0002, + .sversion_opt = 0x0040, +#endif .rev = 0x0000, .dep = 0x0000, .features = 0x0000, @@ -270,6 +281,9 @@ static struct pdc_iodc iodc_data_hpa_fed10200 = { .mod_path = &mod_path_hpa_fed10200,\ .num_addr = HPA_fed10200_num_addr,\ .add_addr = { HPA_fed10200_add_addr } },\ + { 0, } + +#if 0 /* hacked in from here */ \ { .hpa = 0xffd05000,\ .iodc = &iodc_data_hpa_ffd05000,\ @@ -277,4 +291,5 @@ static struct pdc_iodc iodc_data_hpa_fed10200 = { .mod_path = &mod_path_hpa_ffd05000,\ .num_addr = HPA_ffd05000_num_addr,\ .add_addr = { HPA_ffd05000_add_addr } },\ - { 0, } + +#endif diff --git a/src/parisc/hppa.h b/src/parisc/hppa.h index 953eff4..5214380 100644 --- a/src/parisc/hppa.h +++ b/src/parisc/hppa.h @@ -406,5 +406,9 @@ static inline void wrmsr(u32 index, u64 val) // x86.c void cpuid(u32 index, u32 *eax, u32 *ebx, u32 *ecx, u32 *edx); +// pci.c +unsigned long elroy_offset(u16 bdf); +void *elroy_port(unsigned long port, unsigned long offs); + #endif // !__ASSEMBLY__ #endif diff --git a/src/parisc/hppa_hardware.h b/src/parisc/hppa_hardware.h index 3ec6152..cc5ea89 100644 --- a/src/parisc/hppa_hardware.h +++ b/src/parisc/hppa_hardware.h @@ -50,6 +50,8 @@ #define PIM_STORAGE_SIZE 600 /* storage size of pdc_pim_toc_struct (64bit) */ +#define ASTRO_BUS_MODULE 0x0a /* original: 0x0a, use 0 ? */ + /* ASTRO Memory and I/O regions */ #define LMMIO_DIST_BASE_ADDR 0xf4000000UL #define LMMIO_DIST_BASE_SIZE 0x4000000UL diff --git a/src/parisc/parisc.c b/src/parisc/parisc.c index daa8dad..49fc124 100644 --- a/src/parisc/parisc.c +++ b/src/parisc/parisc.c @@ -219,7 +219,7 @@ void __VISIBLE __noreturn reset(void) #undef BUG_ON #define BUG_ON(cond) \ if (unlikely(cond)) { \ - printf("ERROR in SeaBIOS-hppa v%d: %s:%d\n", SEABIOS_HPPA_VERSION, \ + printf("*ERROR* in SeaBIOS-hppa-v%d:\n%s:%d\n", SEABIOS_HPPA_VERSION, \ __FUNCTION__, __LINE__); hlt(); \ } @@ -274,8 +274,12 @@ typedef struct { 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) @@ -290,6 +294,7 @@ struct machine_info { hppa_device_t device_list[MAX_DEVICES]; }; + /* create machine definitions */ #define MACHINE B160L #include "parisc/b160l.h" @@ -409,37 +414,54 @@ struct pci_device *find_pci_from_HPA(unsigned long 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) { - struct pci_device *pci; - if (!has_astro && ((hpa == DINO_UART_HPA) || (hpa == LASI_UART_HPA))) - return 1; - pci = find_pci_from_HPA(hpa); - // dprintf(1, "PCI: is_serial %pP \n", pci); - return pci && pci->class == PCI_CLASS_COMMUNICATION_SERIAL; + hppa_device_t *dev; + + dev = find_hpa_device(hpa); + if (!dev) + return 0; + return DEV_is_serial_device(dev); } -int HPA_is_storage_device(unsigned long hpa) +int DEV_is_network_device(hppa_device_t *dev) { - struct pci_device *pci; - if (!has_astro && ((hpa == DINO_SCSI_HPA) || (hpa == LASI_SCSI_HPA))) - return 1; - pci = find_pci_from_HPA(hpa); - dprintf(1, "PCI: is_storage %pP hpa %lx\n", pci, hpa); - return pci && pci->class == PCI_CLASS_STORAGE_SCSI; + BUG_ON(!dev); + if (dev->pci) + return (dev->pci->class == PCI_CLASS_NETWORK_ETHERNET); + return ((dev->iodc->type & 0xf) == 0x0a); /* HPHW_FIO */ } + int HPA_is_keyboard_device(unsigned long hpa) { struct pci_device *pci; + int ret; if (!has_astro && (hpa == LASI_PS2KBD_HPA)) return 1; pci = find_pci_from_HPA(hpa); - dprintf(1, "PCI: is_keyboard %pP \n", pci); if (!pci) return 0; - return pci->class == PCI_CLASS_COMMUNICATION_SERIAL || + 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; } #define GFX_NUM_PAGES 0x2000 @@ -457,18 +479,138 @@ static const char *hpa_device_name(unsigned long hpa, int output) "SERIAL_1.9600.8.none" : "SERIAL_2.9600.8.none"; } +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_STORAGE_SCSI: + case PCI_CLASS_COMMUNICATION_SERIAL: + case PCI_CLASS_NETWORK_ETHERNET: #if 0 -static struct pdc_module_path mod_path_hpa_fed3c000 = { +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 -void make_module_path_from_pcidev(struct pci_device *pci, - struct pdc_module_path *p) + 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; + default: + BUG_ON(1); + } +} + +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->features = 0x0001; + p->length = 1; + + switch (pci->class) { + case PCI_CLASS_STORAGE_SCSI: + p->type = 0x0084; + break; + case PCI_CLASS_COMMUNICATION_SERIAL: + p->type = 0x008a; + break; + case PCI_CLASS_NETWORK_ETHERNET: + p->type = 0x008a; + break; + default: + BUG_ON(1); + return; + } +}; + +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->path.bc[4] = has_astro ? 0x0a : 0x08; /* astro or dino */ - p->path.bc[5] = 0; // or elroy ?pci->bdf >> 8; /* bus_id */ - p->path.mod = pci->bdf & 0xff; /* slot */ + p->mod_addr = pfa; + p->mod_pgs = 0; + p->add_addrs = 0; // 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; + 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 void print_mod_path(struct pdc_module_path *p) +{ + dprintf(1, "PATH %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]); } static unsigned long keep_list[20] = { PARISC_KEEP_LIST }; @@ -593,20 +735,6 @@ static void remove_parisc_devices(unsigned int num_cpus) } } -static int find_hpa_index(unsigned long hpa) -{ - int i; - if (!hpa) - return -1; - for (i = 0; i < (MAX_DEVICES-1); i++) { - if (hpa == parisc_devices[i].hpa) - return i; - if (!parisc_devices[i].hpa) - return -1; - } - return -1; -} - static int compare_module_path(struct pdc_module_path *path, struct pdc_module_path *search, int check_layers) @@ -634,7 +762,7 @@ static hppa_device_t *find_hppa_device_by_path(struct pdc_module_path *search, unsigned long *index, int check_layers) { hppa_device_t *dev; - int i; + int i, nr = 0; for (i = 0; i < (MAX_DEVICES-1); i++) { dev = parisc_devices + i; @@ -642,21 +770,62 @@ static hppa_device_t *find_hppa_device_by_path(struct pdc_module_path *search, continue; if (!compare_module_path(dev->mod_path, search, check_layers)) { - *index = i; + *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)) { + *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; /* PARISC_SERIAL_CONSOLE */ + portaddr_t addr = PAGE0->mem_kbd.hpa; unsigned long end = timer_calc(SERIAL_TIMEOUT); unsigned long count = 0; - if (!has_astro) + 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); @@ -681,9 +850,11 @@ static void parisc_serial_out(char c) dprintf(0, "%c", c); return; } - if (has_astro) - addr -= IOS_DIST_BASE_ADDR; - else + if (has_astro) { + hppa_device_t *dev = find_hpa_device(addr); + BUG_ON(!dev); + addr = dev->pci_addr; + } else addr += 0x800; // dprintf(1,"parisc_serial_out addr %x\n", addr); @@ -749,14 +920,19 @@ 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) + return PDC_INVALID_ARG; + if (1 && - (((HPA_is_serial_device(hpa) || HPA_is_graphics_device(hpa)) && option == ENTRY_IO_COUT) || - ((HPA_is_serial_device(hpa) || HPA_is_graphics_device(hpa)) && option == ENTRY_IO_CIN) || - ((HPA_is_storage_device(hpa) && option == ENTRY_IO_BOOTIN && !(pdc_debug & DEBUG_BOOT_IO)))) ) { + (((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__); @@ -767,7 +943,7 @@ int __VISIBLE parisc_iodc_ENTRY_IO(unsigned int *arg FUNC_MANY_ARGS) case ENTRY_IO_COUT: /* console output */ c = (char*)ARG6; result[0] = len = ARG7; - if (HPA_is_serial_device(hpa) || HPA_is_graphics_device(hpa)) { + if (DEV_is_serial_device(dev) || HPA_is_graphics_device(hpa)) { while (len--) printf("%c", *c++); } @@ -775,7 +951,7 @@ int __VISIBLE parisc_iodc_ENTRY_IO(unsigned int *arg FUNC_MANY_ARGS) 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_serial_device(hpa)) + if (DEV_is_serial_device(dev)) result[0] = parisc_serial_in(c, ARG7); else if (HPA_is_keyboard_device(hpa)) result[0] = lasips2_kbd_in(c, ARG7); @@ -783,7 +959,7 @@ int __VISIBLE parisc_iodc_ENTRY_IO(unsigned int *arg FUNC_MANY_ARGS) } /* boot medium I/O */ - if (HPA_is_storage_device(hpa)) + if (DEV_is_storage_device(dev)) switch (option) { case ENTRY_IO_BOOTIN: /* boot medium IN */ case ENTRY_IO_BBLOCK_IN: /* boot block medium IN */ @@ -841,19 +1017,25 @@ 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__); - if (!HPA_is_storage_device(hpa) && !HPA_is_serial_device(hpa)) + 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] = HPA_is_serial_device(hpa) ? CL_DUPLEX: - HPA_is_storage_device(hpa) ? CL_RANDOM : 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 */ @@ -861,9 +1043,11 @@ int __VISIBLE parisc_iodc_ENTRY_INIT(unsigned int *arg FUNC_MANY_ARGS) 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] = HPA_is_serial_device(hpa) ? CL_DUPLEX: - HPA_is_storage_device(hpa) ? CL_RANDOM : 0; - result[2] = result[3] = 0; /* TODO?: MAC of network card. */ + 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 */ @@ -889,10 +1073,12 @@ 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__); - if (!(HPA_is_storage_device(hpa) || HPA_is_serial_device(hpa))) + 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. */ @@ -1061,7 +1247,7 @@ static int pdc_pim(unsigned int *arg) 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 >= HPPA_MAX_CPUS) { + if (i < 0 || i >= smp_cpus) { *result = PDC_INVALID_ARG; return PDC_OK; } @@ -1097,9 +1283,16 @@ static int pdc_model(unsigned int *arg) * with old qemu versions which will try to run 64-bit instructions * kernel sr_disable_hash() function */ - memcpy(result, (cpu_bit_width != 64) ? - &machine_B160L.pdc_model : ¤t_machine->pdc_model, +#if 1 + memcpy(result, (cpu_bit_width == 64) ? + ¤t_machine->pdc_model : &machine_B160L.pdc_model, sizeof(current_machine->pdc_model)); +#else + memcpy(result, ¤t_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) { @@ -1160,6 +1353,8 @@ static int pdc_cache(unsigned int *arg) 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; @@ -1168,18 +1363,20 @@ static int pdc_cache(unsigned int *arg) 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 - /* Increase cc_block from 1 to 11. This increases icache_stride - * and dcache_stride to 32768 bytes. Revisit for HP-UX. */ - machine_cache_info->dc_conf.cc_block = 11; - machine_cache_info->ic_conf.cc_block = 11; +#if 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)); @@ -1205,7 +1402,7 @@ static int pdc_hpa(unsigned int *arg) 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); /* ARGH, someone modified cr7! */ + 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; @@ -1226,12 +1423,12 @@ static int pdc_coproc(unsigned int *arg) /* 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; + mask = 1UL; mtctl(mask, 10); /* initialize cr10 */ - result[0] = mask; - result[1] = mask; + result[0] = 1; // mask + result[1] = 1; // mask result[17] = 1; // Revision - result[18] = 19; // Model + result[18] = has_astro ? 0x0f : 0x13; // Model return PDC_OK; } return PDC_BAD_OPTION; @@ -1242,18 +1439,20 @@ 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; - int hpa_index; unsigned char *c; - dprintf(0, "\n\nSeaBIOS: Info PDC_IODC function %ld ARG3=%x ARG4=%x ARG5=%x ARG6=%x\n", option, ARG3, ARG4, ARG5, ARG6); + // 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; - hpa_index = find_hpa_index(hpa); - if (hpa_index < 0) + dev = find_hpa_device(hpa); +// dprintf(1, "pdc_iodc found dev %p\n", dev); + if (!dev) return -4; // not found - iodc_p = parisc_devices[hpa_index].iodc; + + iodc_p = dev->iodc; if (ARG4 == PDC_IODC_INDEX_DATA) { // if (hpa == MEMORY_HPA) @@ -1283,9 +1482,13 @@ static int pdc_iodc(unsigned int *arg) flush_data_cache((char*)ARG5, *result); return PDC_OK; break; - case PDC_IODC_NINIT: /* non-destructive init */ + case PDC_IODC_NINIT: /* non-destructive init - for memory */ case PDC_IODC_DINIT: /* destructive init */ - break; + 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; @@ -1514,55 +1717,77 @@ 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; - int hpa_index; + 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; - if (hpa_index >= MAX_DEVICES) - return PDC_NE_MOD; // Module not found - hpa = parisc_devices[hpa_index].hpa; - if (!hpa) + 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 = *parisc_devices[hpa_index].mod_path; + *mod_path = *dev->mod_path; +#if 1 // *pdc_mod_info = *parisc_devices[hpa_index].mod_info; -> can be dropped. - memset(result, 0, 32*sizeof(long)); + 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; +#else result[0] = hpa; // .mod_addr for PDC_IODC - result[1] = HPA_is_graphics_device(hpa) ? GFX_NUM_PAGES : 1; - result[2] = parisc_devices[hpa_index].num_addr; // additional addresses + result[1] = HPA_is_graphics_device(hpa) ? GFX_NUM_PAGES : dev->pci ? 1 : 1; + result[2] = dev->num_addr; // additional addresses +#endif return PDC_OK; case PDC_FIND_ADDRESS: hpa_index = ARG3; - if (hpa_index >= MAX_DEVICES) - return PDC_NE_MOD; // Module not found - hpa = parisc_devices[hpa_index].hpa; - if (!hpa) + 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 >= parisc_devices[hpa_index].num_addr) + if (ARG4 >= dev->num_addr) return PDC_INVALID_ARG; - result[0] = parisc_devices[hpa_index].add_addr[ARG4]; + 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(mod_path, result+3, 1); + hppa_device_t *dev = find_hppa_device_by_path(mod_path, &hpa_index, 1); + 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->hpa; - result[1] = 1; - result[2] = 0; + 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; @@ -2266,21 +2491,24 @@ static struct pz_device mem_boot_boot = { .cl_class = CL_RANDOM, }; -static void find_pci_slot_for_dev(unsigned int pciid, char *pci_slot) +#if 0 +static void find_pci_slot_for_dev(unsigned int vendor, char *pci_slot) { struct pci_device *pci; foreachpci(pci) - if (pci->vendor == pciid) { + 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) @@ -2293,36 +2521,40 @@ static void find_serial_pci_card(void) pci_config_maskw(pci->bdf, PCI_COMMAND, 0, PCI_COMMAND_IO | PCI_COMMAND_MEMORY); pmem = pci_enable_iobar(pci, PCI_BASE_ADDRESS_0); - pmem += IOS_DIST_BASE_ADDR; dprintf(1, "PCI: Enabling %pP for primary SERIAL PORT mem %x\n", pci, pmem); - - pci = find_pci_from_HPA(pmem); - dprintf(1, "PCI: found PCI serial %pP \n", pci); + pmem += IOS_DIST_BASE_ADDR; /* set serial port for console output and keyboard input */ - mem_cons_boot.hpa = pmem; - mem_kbd_boot.hpa = pmem; + 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; + // 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); - pmem += IOS_DIST_BASE_ADDR; dprintf(1, "PCI: Enabling %pP for primary SCSI PORT mem %x\n", pci, pmem); + pmem += IOS_DIST_BASE_ADDR; /* set SCSI HPA */ -//HELGE - mem_boot_boot.hpa = pmem; + pdev = &hppa_pci_devices[0]; + while (pdev->pci != pci) + pdev++; + pdev->pci_addr = pmem; + mem_boot_boot.hpa = pdev->hpa; } @@ -2331,28 +2563,20 @@ static void prepare_boot_path(volatile struct pz_device *dest, const struct pz_device *source, unsigned int stable_offset) { - int hpa_index; + hppa_device_t *dev; unsigned long hpa; struct pdc_module_path *mod_path; - struct pdc_module_path temp_mod_path; hpa = source->hpa; - hpa_index = find_hpa_index(hpa); + dev = find_hpa_device(hpa); + BUG_ON(!dev); - if (HPA_is_storage_device(hpa)) + if (DEV_is_storage_device(dev)) mod_path = &mod_path_emulated_drives; - else if (hpa == LASI_UART_HPA) // HPA_is_serial_device(hpa)) - mod_path = &mod_path_hpa_ffd05000; - else if (hpa == DINO_UART_HPA) // HPA_is_serial_device(hpa)) - mod_path = &mod_path_hpa_fff83000; - else if (hpa_index >= 0) - mod_path = parisc_devices[hpa_index].mod_path; + else if (dev) + mod_path = dev->mod_path; else { - struct pci_device *pci; - pci = find_pci_from_HPA(hpa); - BUG_ON(!pci); - make_module_path_from_pcidev(pci, &temp_mod_path); - mod_path = &temp_mod_path; + BUG_ON(1); } /* copy device path to entry in PAGE0 */ @@ -2405,6 +2629,7 @@ void __VISIBLE start_parisc_firmware(void) // 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; @@ -2563,8 +2788,10 @@ void __VISIBLE start_parisc_firmware(void) // coreboot_preinit(); pci_setup(); - if (has_astro) + if (has_astro) { iosapic_table_setup(); + } + hppa_pci_build_devices_list(); /* find serial PCI card when running on Astro */ find_serial_pci_card(); |