aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHelge Deller <deller@gmx.de>2023-10-13 11:52:30 +0200
committerHelge Deller <deller@gmx.de>2023-10-13 11:52:30 +0200
commit6ab15759b1173312a6ecdf8788a860f24f0d28e8 (patch)
tree8ee429c64c281dd829087875642b7dfd342a5164
parentae2b0d735fba482f9e29945c2af0cfe033887756 (diff)
downloadseabios-hppa-6ab15759b1173312a6ecdf8788a860f24f0d28e8.zip
seabios-hppa-6ab15759b1173312a6ecdf8788a860f24f0d28e8.tar.gz
seabios-hppa-6ab15759b1173312a6ecdf8788a860f24f0d28e8.tar.bz2
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
-rw-r--r--src/fw/pciinit.c48
-rw-r--r--src/parisc/b160l.h4
-rw-r--r--src/parisc/c3700.h17
-rw-r--r--src/parisc/hppa_hardware.h7
-rw-r--r--src/parisc/parisc.c77
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