From 6ab15759b1173312a6ecdf8788a860f24f0d28e8 Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Fri, 13 Oct 2023 11:52:30 +0200 Subject: BEST EVERY, alles 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 --- src/fw/pciinit.c | 48 +++++++++++++++++++++++++++-- src/parisc/b160l.h | 4 +-- src/parisc/c3700.h | 17 +++++----- src/parisc/hppa_hardware.h | 7 ++++- src/parisc/parisc.c | 77 +++++++++++++++++++++++++++++----------------- 5 files changed, 111 insertions(+), 42 deletions(-) diff --git a/src/fw/pciinit.c b/src/fw/pciinit.c index c4e60ae..ea030bb 100644 --- a/src/fw/pciinit.c +++ b/src/fw/pciinit.c @@ -509,6 +509,12 @@ static void mch_mem_addr_setup(struct pci_device *dev, void *arg) pci_io_low_end = acpi_pm_base; } +/* + * parisc: If mmio bar is bigger than this size, map the bar it into the + * directed ELMMIO instead of the distributed LMMIO region. + */ +#define PARISC_MMIO_LIMIT 0x10000 + #if CONFIG_PARISC static int dino_pci_slot_get_irq(struct pci_device *pci, int pin) { @@ -565,6 +571,35 @@ static void parisc_mem_addr_setup(struct pci_device *dev, void *arg) } #endif /* CONFIG_PARISC */ +static unsigned long add_lmmio_directed_range(unsigned long size, int rope) +{ +#ifdef CONFIG_PARISC + int i; + + /* Astro has 4 directed ranges. */ + for (i = 0; i < 4; i++) { + unsigned long addr; + void *reg = (void *)(unsigned long) (ASTRO_BASE_HPA + i * 0x18); + + addr = readl(reg + LMMIO_DIRECT0_BASE); + if (addr & 1) + continue; /* already used */ + + /* fixme for multiple addresses */ + /* Linux driver currently only allows one distr. range per IOC */ + addr = 0xfa000000; /* graphics card area for parisc, f8 is used by artist */ + addr += i * 0x02000000; + + writel(reg + LMMIO_DIRECT0_BASE, addr | 1); + writel(reg + LMMIO_DIRECT0_ROUTE, rope & (ROPES_PER_IOC - 1)); + size = 0xfff8000000 | ~(size-1); /* is -1 correct? */ + // dprintf(1, "use addr %lx size %lx\n", addr|1, size); + writel(reg + LMMIO_DIRECT0_MASK, size); + return addr; + } +#endif /* CONFIG_PARISC */ + return -1UL; +} static const struct pci_device_id pci_platform_tbl[] = { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82441, @@ -813,7 +848,8 @@ static u64 pci_region_sum(struct pci_region *r) u64 sum = 0; struct pci_region_entry *entry; hlist_for_each_entry(entry, &r->list, node) { - sum += entry->size; + if (entry->size <= PARISC_MMIO_LIMIT && CONFIG_PARISC) + sum += entry->size; } return sum; } @@ -1123,6 +1159,8 @@ pci_region_map_one_entry(struct pci_region_entry *entry, u64 addr) u16 bdf = entry->dev->bdf; u64 limit = addr + entry->size - 1; + if (!entry->size) + return; if (entry->type == PCI_REGION_TYPE_IO) { pci_config_writeb(bdf, PCI_IO_BASE, addr >> PCI_IO_SHIFT); pci_config_writew(bdf, PCI_IO_BASE_UPPER16, 0); @@ -1147,7 +1185,13 @@ static void pci_region_map_entries(struct pci_bus *busses, struct pci_region *r) struct pci_region_entry *entry; hlist_for_each_entry_safe(entry, n, &r->list, node) { u64 addr = r->base; - r->base += entry->size; + if (entry->size <= PARISC_MMIO_LIMIT && CONFIG_PARISC) + r->base += entry->size; + else { + addr = add_lmmio_directed_range(entry->size, 0); + if (addr == -1UL) + hlt(); + } if (entry->bar == -1) // Update bus base address if entry is a bridge region busses[entry->dev->secondary_bus].r[entry->type].base = addr; diff --git a/src/parisc/b160l.h b/src/parisc/b160l.h index 0e057fa..1899590 100644 --- a/src/parisc/b160l.h +++ b/src/parisc/b160l.h @@ -464,7 +464,7 @@ static struct pdc_iodc iodc_data_hpa_fff10000 = { #define HPA_fffbf000_DESCRIPTION "Memory" static struct pdc_system_map_mod_info mod_info_hpa_fffbf000 = { - .mod_addr = 0xfffbf000, + .mod_addr = MEMORY_HPA, .mod_pgs = 0x1, .add_addrs = 0x0, }; @@ -615,7 +615,7 @@ static struct pdc_iodc iodc_data_hpa_fff81000 = { .mod_path = &mod_path_hpa_fff10000,\ .num_addr = HPA_fff10000_num_addr,\ .add_addr = { HPA_fff10000_add_addr } },\ - { .hpa = 0xfffbf000,\ + { .hpa = MEMORY_HPA,\ .iodc = &iodc_data_hpa_fffbf000,\ .mod_info = &mod_info_hpa_fffbf000,\ .mod_path = &mod_path_hpa_fffbf000,\ diff --git a/src/parisc/c3700.h b/src/parisc/c3700.h index b32312b..2c1862a 100644 --- a/src/parisc/c3700.h +++ b/src/parisc/c3700.h @@ -179,24 +179,19 @@ 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: +#if 1 // original C3700: .hversion_model = 0x005d, - .hversion = 0x00c0, - .spa = 0x0000, - .type = 0x0040, - .sversion_rev = 0x0000, - .sversion_model = 0x0002, - .sversion_opt = 0x0040, + .hversion = 0x00c0, // C3700: c0, B160: 20 #else /* this is from B160L */ .hversion_model = 0x0050, .hversion = 0x0020, +#endif .spa = 0x0000, .type = 0x0040, .sversion_rev = 0x0000, .sversion_model = 0x0002, .sversion_opt = 0x0040, -#endif .rev = 0x0000, .dep = 0x0000, .features = 0x0000, @@ -275,6 +270,12 @@ 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 } },\ + { .hpa = 0xf8000000, /* HACKED IN: Coral GSC graphics */ \ + .iodc = &iodc_data_hpa_f8000000,\ + .mod_info = &mod_info_hpa_f8000000,\ + .mod_path = &mod_path_hpa_f8000000,\ + .num_addr = HPA_f8000000_num_addr,\ + .add_addr = { HPA_f8000000_add_addr } },\ { .hpa = CPU_HPA /* XXX: 0xfffa0000 */ ,\ .iodc = &iodc_data_hpa_fffa0000,\ .mod_info = &mod_info_hpa_fffa0000,\ diff --git a/src/parisc/hppa_hardware.h b/src/parisc/hppa_hardware.h index cc5ea89..b088801 100644 --- a/src/parisc/hppa_hardware.h +++ b/src/parisc/hppa_hardware.h @@ -50,9 +50,11 @@ #define PIM_STORAGE_SIZE 600 /* storage size of pdc_pim_toc_struct (64bit) */ -#define ASTRO_BUS_MODULE 0x0a /* original: 0x0a, use 0 ? */ +#define ASTRO_BUS_MODULE 0x0a /* C3700: 0x0a, others maybe 0 ? */ /* ASTRO Memory and I/O regions */ +#define ASTRO_BASE_HPA 0xfffed00000 + #define LMMIO_DIST_BASE_ADDR 0xf4000000UL #define LMMIO_DIST_BASE_SIZE 0x4000000UL @@ -61,5 +63,8 @@ #define ROPES_PER_IOC 8 /* per Ike half or Pluto/Astro */ +#define LMMIO_DIRECT0_BASE 0x300 +#define LMMIO_DIRECT0_MASK 0x308 +#define LMMIO_DIRECT0_ROUTE 0x310 #endif diff --git a/src/parisc/parisc.c b/src/parisc/parisc.c index 33dcb3d..095017d 100644 --- a/src/parisc/parisc.c +++ b/src/parisc/parisc.c @@ -6,6 +6,10 @@ // 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\* @@ -476,16 +480,32 @@ static int HPA_is_keyboard_device(unsigned long hpa) } #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) { - return (hpa == LASI_GFX_HPA) || (hpa == 0xf4000000) || - (hpa == 0xf8000000) || (hpa == 0xfa000000); + 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_graphics_device(hpa) ? "GRAPHICS(1)" : + 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"; @@ -617,9 +637,9 @@ static hppa_device_t *find_hpa_device(unsigned long hpa) 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], + 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->path.mod, p->layers[0], p->layers[1], p->layers[2]); } static unsigned long keep_list[20] = { PARISC_KEEP_LIST }; @@ -659,11 +679,13 @@ static int keep_add_generic_devices(void) 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 0x0041: /* Memory */ case 0x000d: /* Elroy PCI bridge */ case 0x000c: /* Runway port */ keep_list[i++] = dev->hpa; @@ -859,12 +881,12 @@ static void parisc_serial_out(char c) dprintf(0, "%c", c); return; } - if (has_astro) { - hppa_device_t *dev = find_hpa_device(addr); - BUG_ON(!dev); + hppa_device_t *dev = find_hpa_device(addr); + BUG_ON(!dev); + if (dev->pci_addr) addr = dev->pci_addr; - } else - addr += 0x800; + else + addr += 0x800; /* add offset for serial port on GSC */ // dprintf(1,"parisc_serial_out addr %x\n", addr); if (c == '\n') @@ -882,7 +904,7 @@ static void parisc_serial_out(char c) static void parisc_putchar_internal(char c) { - if (HPA_is_graphics_device(PAGE0->mem_cons.hpa)) + if (HPA_is_LASI_graphics(PAGE0->mem_cons.hpa)) sti_putc(c); else parisc_serial_out(c); @@ -937,8 +959,10 @@ int __VISIBLE parisc_iodc_ENTRY_IO(unsigned int *arg FUNC_MANY_ARGS) struct disk_op_s disk_op; dev = find_hpa_device(hpa); - if (!dev) + 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) || @@ -954,7 +978,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 (DEV_is_serial_device(dev) || HPA_is_graphics_device(hpa)) { + if (DEV_is_serial_device(dev) || HPA_is_LASI_graphics(hpa)) { while (len--) printf("%c", *c++); } @@ -1076,6 +1100,7 @@ int __VISIBLE parisc_iodc_ENTRY_SPA(unsigned int *arg FUNC_MANY_ARGS) int __VISIBLE parisc_iodc_ENTRY_CONFIG(unsigned int *arg FUNC_MANY_ARGS) { iodc_log_call(arg, __FUNCTION__); + // BUG_ON(1); return PDC_BAD_OPTION; } @@ -1466,14 +1491,14 @@ static int pdc_iodc(unsigned int *arg) iodc_p = dev->iodc; if (ARG4 == PDC_IODC_INDEX_DATA) { - // if (hpa == MEMORY_HPA) - // ARG6 = 2; // Memory modules return 2 bytes of IODC memory (result2 ret[0] = 0x6701f41 HI !!) + 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]); + 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 = ARG6; + result[0] = ARG6; return PDC_OK; } @@ -1755,16 +1780,10 @@ static int pdc_system_map(unsigned int *arg) if (mod_path) *mod_path = *dev->mod_path; -#if 1 // *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; -#else - result[0] = hpa; // .mod_addr for PDC_IODC - 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: @@ -2523,8 +2542,9 @@ static void find_serial_pci_card(void) hppa_device_t *pdev; u32 pmem; - if (!has_astro) + if (!has_astro) /* use built-in LASI serial port for console */ return; + pci = pci_find_class(PCI_CLASS_COMMUNICATION_SERIAL); if (!pci) return; @@ -2689,7 +2709,6 @@ void __VISIBLE start_parisc_firmware(void) tlb_entries = romfile_loadint("/etc/cpu/tlb_entries", 256); dprintf(0, "fw_cfg: TLB entries %d\n", tlb_entries); -// hlt(); powersw_ptr = (int *) (unsigned long) romfile_loadint("/etc/hppa/power-button-addr", (unsigned long)&powersw_nop); @@ -2697,7 +2716,7 @@ void __VISIBLE start_parisc_firmware(void) /* 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); + // 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); @@ -2749,7 +2768,7 @@ void __VISIBLE start_parisc_firmware(void) PAGE0->pad0[3] = PORT_QEMU_CFG_CTL; *powersw_ptr = 0x01; /* button not pressed, hw controlled. */ - PAGE0->imm_hpa = MEMORY_HPA; + /* PAGE0->imm_hpa - is set later (MEMORY_HPA) */ PAGE0->imm_spa_size = ram_size; PAGE0->imm_max_mem = ram_size; @@ -2819,7 +2838,7 @@ void __VISIBLE start_parisc_firmware(void) find_scsi_pci_card(); // Initialize boot paths (graphics & keyboard) - if (pdc_console == CONSOLE_DEFAULT) { + if (pdc_console != CONSOLE_SERIAL) { if (artist_present()) pdc_console = CONSOLE_GRAPHICS; else -- cgit v1.1