Getting a HP9000/K220 working with OpenBSD 3.4-current ------------------------------------------------------------------------------- Hellmuth Michaelis, hm@kts.org, last edit-date: [Fri Oct 31 18:23:38 2003] $Id: k220-openbsd-34.txt,v 1.1 2003/10/31 17:24:06 cvs Exp $ The following code and procedures were tested using a 715/64 and a K220. The following procedures and code should get at least a K100, K200, K210, K220 or K420 working with OpenBSD 3.4-current. You need a supported 700 for the initial compile and network boot. Because the FWD scsi controller is currently unsupported, the K needs to be modified in such a way that the internal CDROM drive or the internal DAT tape needs to be removed and replaced by a SE SCSI disk drive (a 2G HP C3725S in my case) for the OpenBSD filesystems. A terminal is used as the console on the console port using the pdc driver. procedure: ------------------------------------------------------------------------------- - apply the diffs below to the current kernel code - compile a GENERIC kernel on a 700 - go to /usr/src/distrib and make a lif.34 on a 700 - prepare bootp & tftp and ftp on a 700 - add a SE scsi drive to the internal SE scsi bus on an 800 - boot the 800 via network from the 700 - install all necessary filesets via the internet / network - before the 800 reboots, ftp the GENERIC kernel build on the 700 from the 700 to / on the 800 - reboot todo / open ends: ------------------------------------------------------------------------------- - the com code has to be fixed to remove the hardwired enablement of the com port from the code. - the pdc driver sometimes hangs so the terminal gets unusable - the ie driver sometimes hangs for some seconds - the osiop scsi driver sometimes hangs for some seconds - fix the pmap_page_alloc fail panic for large memory configurations - fix the double detection of cards. this is because cards are visible at several locations on the main bus _and_ below bus converters. imo the only way to do this is to create a database of found cards referenced by their path (i.e. 10/12/6) at autoconf time and ignore double detected cards at the same path - add support for the internal FW diff 53c720 scsi controller - add support for the LCD display, using PDC_CHASSIS at runtime is a no-no - add support for the rest of the HPPB and HSC card crowd code changes: ------------------------------------------------------------------------------- 1 - /usr/src/sys/arch/hppa/dev/pdc.c in case no com devices are in the kernel configuration, the pdc_speeds table needs to be ifdef'd 2 - /usr/src/sys/arch/hppa/hppa/autoconf.c fix PDC_SYSMAP_FIND probe mechanism in pdc_scan() the algorithm, assumptions and parameters using PDC_SYSMAP_FIND were wrong. split pdc_scanbus into a common part and a part doing MEMMAP or SYSMAP dependent scanning 3 - /usr/src/sys/arch/hppa/hppa/conf.c at the end of the file: disable cons_init(com) since this stops output to the (terminal) pdc console immediately before the copyright message and the machine hangs. this is because of a hard-enable of com devices in case of compilation on __hppa__ in the com-driver 4 - /usr/src/sys/arch/hppa/hppa/machdep.c a) truncate avail_end to 512. my K220 has 1G of memory and panics with pmap_pagealloc fail pmap_kenter_pa: cannot allocate pde for va=0xc1000000 immediately after the copyright message b) fix chassis message type from run to init c) add pdc type detection. missing: detect pdc type "pat" 5 - /usr/src/sys/arch/hppa/hppa/mainbus.c add routine walk_iomem(). Just a subset of the available modules is detected by PDC_SYSMAP_FIND, the other modules must be found by recursively scanning the central bus. the assembly inline must be used, because otherwise the routine panics on one particular bus converter. 6 - /usr/src/sys/arch/hppa/include/pdc.h a) add pdc types b) fix PDC_SYSMAP definitions, add struct pdc_sysmap_xlatpath K220 dmesg: ------------------------------------------------------------------------------- [ using 201420 bytes of bsd ELF symbol table ] Copyright (c) 1982, 1986, 1989, 1991, 1993 The Regents of the University of California. All rights reserved. Copyright (c) 1995-2003 OpenBSD. All rights reserved. http://www.OpenBSD.org OpenBSD 3.4-current (FLOYD) #1: Fri Oct 31 17:07:58 CET 2003 root@floyd.int.kts.org:/usr/src/sys/arch/hppa/compile/FLOYD HP 9000/859/K220 (ThunderHawk DC3- 120 1M) PA-RISC 1.1a (PDC-type: SYSMAP) real mem = 536870912 (524288 reserved for PROM, 6606848 used by OpenBSD) avail mem = 463798272 using 8421 buffers containing 53657600 bytes of memory mainbus0 (root) [flex fff80000] pdc0 at mainbus0 power0 at mainbus0: not available lasi0 at mainbus0 offset fd00000 irq 28: rev 3.0 gsc0 at lasi0 "LASI Bus Adapter" at gsc0 (type b, sv 81, hv 50) offset 0 not configured osiop0 at gsc0 offset 6000 irq 9: NCR53C710 rev 2, 40MHz, SCSI ID 7 scsibus0 at osiop0: 8 targets osiop0: target 0 now using 8 bit 10 MHz 8 REQ/ACK offset xfers st0 at scsibus0 targ 0 lun 0: SCSI2 1/sequential removable st0: drive empty osiop0: target 5 now using 8 bit 10 MHz 8 REQ/ACK offset xfers sd0 at scsibus0 targ 5 lun 0: SCSI2 0/direct fixed sd0: 2047MB, 3703 cyl, 9 head, 125 sec, 512 bytes/sec, 4194058 sec total ie0 at gsc0 offset 7000 irq 8: LASI/i82596CA v1.0, address 08:00:09:d4:36:b8 lpt0 at gsc0 offset 2000 irq 7 "PS/2 port" at gsc0 (type a, sv 84, hv 50) offset 8000 not configured "PS/2 port" at gsc0 (type a, sv 84, hv 50) offset 8100 not configured "NCR 53C710 SCSI" at mainbus0 (type a, sv 82, hv 50) offset fd06000 not configured "Core LAN" at mainbus0 (type a, sv 8a, hv 50) offset fd07000 not configured "Core Centronics" at mainbus0 (type a, sv 74, hv 50) offset fd02000 not configured "PS/2 port" at mainbus0 (type a, sv 84, hv 50) offset fd08000 not configured "PS/2 port" at mainbus0 (type a, sv 84, hv 50) offset fd08100 not configured "BC Runway Port" at mainbus0 (type c, sv b, hv 7) offset ff88000 not configured "Bus Converter Port" at mainbus0 (type 7, sv c, hv 11) offset 103f000 not configured "BC Runway Port" at mainbus0 (type c, sv b, hv 7) offset ff8a000 not configured "FW SCSI" at mainbus0 (type 4, sv 89, hv 51) offset 1800000 not configured "Bus Converter Port" at mainbus0 (type 7, sv c, hv 0) offset 1804000 not configured "AP/MUX" at mainbus0 (type 5, sv d, hv 50) offset 1900000 not configured "Interphase NIO-100BaseT" at mainbus0 (type 4, sv 382, hv 40) offset 1908000 not configured "SCSI" at mainbus0 (type 4, sv 39, hv 40) offset 1910000 not configured "Centronics interface" at mainbus0 (type 5, sv 3a, hv 40) offset 1911000 not configured "Bus Converter Port" at mainbus0 (type 7, sv c, hv 30) offset 193c000 not configured "Bus Converter Port" at mainbus0 (type 7, sv c, hv 11) offset 183f000 not configured cpu0 at mainbus0 offset ffa0000 irq 31: PCXT' L1-B 120MHz, FPU PCXT' (Tornado) rev 1 cpu0: 1024K(32b/l) Icache, 1026K(32b/l) wr-back coherent Dcache, 120 coherent TLB, 16 BTLB "PA-RISC" at mainbus0 (type 0, sv 4, hv c0) offset ffa2000 not configured mem0 at mainbus0 offset ffb1000: size 1024MB biomask 0x23 netmask 0x2b ttymask 0x3f root on sd0a swap on sd0b rootdev=0x400 rrootdev=0xa00 rawdev=0xa02 diffs: ------------------------------------------------------------------------------- Index: dev/pdc.c =================================================================== RCS file: /var/cvs/openbsd/src/sys/arch/hppa/dev/pdc.c,v retrieving revision 1.26 diff -c -r1.26 pdc.c *** dev/pdc.c 3 Oct 2003 16:44:49 -0000 1.26 --- dev/pdc.c 31 Oct 2003 16:39:10 -0000 *************** *** 75,80 **** --- 75,82 ---- int pdcparam(struct tty *tp, struct termios *); int pdccnlookc(dev_t dev, int *cp); + #include "com.h" + #if NCOM_GSC > 0 /* serial console speed table */ static int pdc_speeds[] = { B50, *************** *** 94,99 **** --- 96,102 ---- B115200, B230400, }; + #endif void pdc_init() *************** *** 124,130 **** cn_tab = &constab[0]; /* setup the console */ ! #include "com.h" #if NCOM_GSC > 0 if (PAGE0->mem_cons.pz_class == PCL_DUPLEX) { struct pz_device *pzd = &PAGE0->mem_cons; --- 127,133 ---- cn_tab = &constab[0]; /* setup the console */ ! #if NCOM_GSC > 0 if (PAGE0->mem_cons.pz_class == PCL_DUPLEX) { struct pz_device *pzd = &PAGE0->mem_cons; Index: gsc/osiop_gsc.c =================================================================== RCS file: /var/cvs/openbsd/src/sys/arch/hppa/gsc/osiop_gsc.c,v retrieving revision 1.7 diff -c -r1.7 osiop_gsc.c *** gsc/osiop_gsc.c 7 Aug 2003 19:47:33 -0000 1.7 --- gsc/osiop_gsc.c 31 Oct 2003 16:39:10 -0000 *************** *** 196,202 **** --- 196,204 ---- /* Deal with the interrupt */ osiop_intr(sc); + #ifdef USELEDS ledctl(PALED_DISK, 0, 0); + #endif return (1); } Index: hppa/autoconf.c =================================================================== RCS file: /var/cvs/openbsd/src/sys/arch/hppa/hppa/autoconf.c,v retrieving revision 1.36 diff -c -r1.36 autoconf.c *** hppa/autoconf.c 15 Oct 2003 17:42:09 -0000 1.36 --- hppa/autoconf.c 31 Oct 2003 16:39:10 -0000 *************** *** 2,7 **** --- 2,8 ---- /* * Copyright (c) 1998-2003 Michael Shalayeff + * Copyright (c) 2003 Hellmuth Michaelis * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. * *************** *** 91,96 **** --- 92,99 ---- #include #endif + static void pdc_scanbuscommon(struct device *self, struct confargs *pnca); + /* * cpu_configure: * called at boot time, configure all devices on system *************** *** 597,606 **** } struct pdc_memmap pdc_memmap PDC_ALIGNMENT; ! struct pdc_sysmap_find pdc_find PDC_ALIGNMENT; ! struct pdc_sysmap_addrs pdc_addr PDC_ALIGNMENT; struct pdc_iodc_read pdc_iodc_read PDC_ALIGNMENT; void pdc_scanbus(self, ca, maxmod) struct device *self; --- 600,645 ---- } struct pdc_memmap pdc_memmap PDC_ALIGNMENT; ! struct pdc_sysmap_findmod pdc_findmod PDC_ALIGNMENT; ! struct pdc_sysmap_findaddr pdc_findaddr PDC_ALIGNMENT; struct pdc_iodc_read pdc_iodc_read PDC_ALIGNMENT; + static void + pdc_scanbuscommon(self, pnca) + struct device *self; + struct confargs *pnca; + { + int error; + + if (autoconf_verbose) + printf(">> HPA 0x%x[0x%x]\n", + pnca->ca_hpa, pnca->ca_hpasz); + + if ((error = pdc_call((iodcio_t)pdc, 0, PDC_IODC, + PDC_IODC_READ, &pdc_iodc_read, pnca->ca_hpa, IODC_DATA, + &pnca->ca_type, sizeof(pnca->ca_type))) < 0) { + if (autoconf_verbose) + printf(">> iodc_data error %d\n", error); + return; + } + + pnca->ca_pdc_iodc_read = &pdc_iodc_read; + pnca->ca_name = hppa_mod_info(pnca->ca_type.iodc_type, + pnca->ca_type.iodc_sv_model); + + if (autoconf_verbose) { + printf(">> probing: flags %b bc %d/%d/%d/%d/%d/%d ", + pnca->ca_dp.dp_flags, PZF_BITS, + pnca->ca_dp.dp_bc[0], pnca->ca_dp.dp_bc[1], + pnca->ca_dp.dp_bc[2], pnca->ca_dp.dp_bc[3], + pnca->ca_dp.dp_bc[4], pnca->ca_dp.dp_bc[5]); + printf("mod %x hpa %x type %x sv %x\n", + pnca->ca_dp.dp_mod, pnca->ca_hpa, + pnca->ca_type.iodc_type, pnca->ca_type.iodc_sv_model); + } + config_found_sm(self, pnca, mbprint, mbsubmatch); + } + void pdc_scanbus(self, ca, maxmod) struct device *self; *************** *** 608,667 **** int maxmod; { int i; ! for (i = maxmod; i--; ) { ! struct confargs nca; ! int error; ! ! bzero(&nca, sizeof(nca)); ! nca.ca_iot = ca->ca_iot; ! nca.ca_dmatag = ca->ca_dmatag; ! nca.ca_dp.dp_bc[0] = ca->ca_dp.dp_bc[1]; ! nca.ca_dp.dp_bc[1] = ca->ca_dp.dp_bc[2]; ! nca.ca_dp.dp_bc[2] = ca->ca_dp.dp_bc[3]; ! nca.ca_dp.dp_bc[3] = ca->ca_dp.dp_bc[4]; ! nca.ca_dp.dp_bc[4] = ca->ca_dp.dp_bc[5]; ! nca.ca_dp.dp_bc[5] = ca->ca_dp.dp_mod; ! nca.ca_dp.dp_mod = i; ! nca.ca_hpamask = ca->ca_hpamask; ! ! if ((error = pdc_call((iodcio_t)pdc, 0, PDC_MEMMAP, ! PDC_MEMMAP_HPA, &pdc_memmap, &nca.ca_dp)) == 0) ! nca.ca_hpa = pdc_memmap.hpa; ! else if ((error = pdc_call((iodcio_t)pdc, 0, PDC_SYSMAP, ! PDC_SYSMAP_HPA, &pdc_memmap, &nca.ca_dp)) == 0) { ! struct device_path path; ! int im, ia; ! ! nca.ca_hpa = pdc_memmap.hpa; ! ! /* TODO fetch the hpa size and the addrs */ ! for (im = 0; !(error = pdc_call((iodcio_t)pdc, 0, ! PDC_SYSMAP, PDC_SYSMAP_FIND, ! &pdc_find, &path, im)) && ! pdc_find.hpa != nca.ca_hpa; im++) ! ; ! if (!error) ! nca.ca_hpasz = pdc_find.size << PGSHIFT; ! if (!error && pdc_find.naddrs) { ! nca.ca_naddrs = pdc_find.naddrs; if (nca.ca_naddrs > 16) { nca.ca_naddrs = 16; printf("WARNING: too many (%d) addrs\n", ! pdc_find.naddrs); } if (autoconf_verbose) printf(">> ADDRS:"); ! for (ia = 0; !(error = pdc_call((iodcio_t)pdc, ! 0, PDC_SYSMAP, PDC_SYSMAP_ADDR, &pdc_addr, ! im, ia)) && ia < nca.ca_naddrs; ia++) { ! nca.ca_addrs[ia].addr = pdc_addr.hpa; nca.ca_addrs[ia].size = ! pdc_addr.size << PGSHIFT; if (autoconf_verbose) printf(" 0x%x[0x%x]", --- 647,758 ---- int maxmod; { int i; + int ia; + struct confargs nca; + int error; + + extern int pdc_type; + + if(pdc_type == PDC_TYPE_MEMMAP) + { + for (i = maxmod; i--; ) { + + bzero(&nca, sizeof(nca)); + + nca.ca_iot = ca->ca_iot; + nca.ca_dmatag = ca->ca_dmatag; + nca.ca_dp.dp_bc[0] = ca->ca_dp.dp_bc[1]; + nca.ca_dp.dp_bc[1] = ca->ca_dp.dp_bc[2]; + nca.ca_dp.dp_bc[2] = ca->ca_dp.dp_bc[3]; + nca.ca_dp.dp_bc[3] = ca->ca_dp.dp_bc[4]; + nca.ca_dp.dp_bc[4] = ca->ca_dp.dp_bc[5]; + nca.ca_dp.dp_bc[5] = ca->ca_dp.dp_mod; + nca.ca_dp.dp_mod = i; + nca.ca_hpamask = ca->ca_hpamask; + + if ((error = pdc_call((iodcio_t)pdc, 0, PDC_MEMMAP, + PDC_MEMMAP_HPA, &pdc_memmap, &nca.ca_dp)) == 0) { + nca.ca_hpa = pdc_memmap.hpa; + #if 0 + printf("MEM: i=%d, mod=%d b %d/%d/%d/%d/%d/%d l %d/%d/%d/%d/%d/%d\n", + i, nca.ca_dp.dp_mod, + nca.ca_dp.dp_bc[0], nca.ca_dp.dp_bc[1], + nca.ca_dp.dp_bc[2], nca.ca_dp.dp_bc[3], + nca.ca_dp.dp_bc[4], nca.ca_dp.dp_bc[5], + nca.ca_dp.dp_layers[0], nca.ca_dp.dp_layers[1], + nca.ca_dp.dp_layers[2], nca.ca_dp.dp_layers[3], + nca.ca_dp.dp_layers[4], nca.ca_dp.dp_layers[5]); + #endif + } else { + continue; + } + + pdc_scanbuscommon(self, &nca); + } + } else if(pdc_type == PDC_TYPE_SYSMAP) { + for (i = 0; i < maxmod; i++) { + + bzero(&nca, sizeof(nca)); ! nca.ca_iot = ca->ca_iot; ! nca.ca_dmatag = ca->ca_dmatag; ! nca.ca_dp.dp_bc[0] = ca->ca_dp.dp_bc[1]; ! nca.ca_dp.dp_bc[1] = ca->ca_dp.dp_bc[2]; ! nca.ca_dp.dp_bc[2] = ca->ca_dp.dp_bc[3]; ! nca.ca_dp.dp_bc[3] = ca->ca_dp.dp_bc[4]; ! nca.ca_dp.dp_bc[4] = ca->ca_dp.dp_bc[5]; ! nca.ca_dp.dp_bc[5] = ca->ca_dp.dp_mod; ! nca.ca_dp.dp_mod = i; ! nca.ca_hpamask = ca->ca_hpamask; ! ! error = pdc_call((iodcio_t)pdc, 0, PDC_SYSMAP, ! PDC_SYSMAP_FINDMOD, &pdc_findmod, ! #if 0 ! &nca.ca_dp.dp_layers, i); ! #else ! &nca.ca_dp, i); ! #endif ! if(error == -5) ! break; ! ! if(error < 0) { ! printf("ERROR: PDC_SYSMAP_FINDMOD returned %d\n", error); ! continue; ! } ! if(error > 0) { ! printf("WARNING: PDC_SYSMAP_FINDMOD returned %d\n", error); ! } ! #if 0 ! printf("SYS: i=%d, mod=%d b %d/%d/%d/%d/%d/%d l %d/%d/%d/%d/%d/%d\n", ! i, nca.ca_dp.dp_mod, ! nca.ca_dp.dp_bc[0], nca.ca_dp.dp_bc[1], ! nca.ca_dp.dp_bc[2], nca.ca_dp.dp_bc[3], ! nca.ca_dp.dp_bc[4], nca.ca_dp.dp_bc[5], ! nca.ca_dp.dp_layers[0], nca.ca_dp.dp_layers[1], ! nca.ca_dp.dp_layers[2], nca.ca_dp.dp_layers[3], ! nca.ca_dp.dp_layers[4], nca.ca_dp.dp_layers[5]); ! #endif ! nca.ca_hpa = pdc_findmod.hpa; ! nca.ca_hpasz = pdc_findmod.size << PGSHIFT; ! if(pdc_findmod.naddrs) { ! nca.ca_naddrs = pdc_findmod.naddrs; if (nca.ca_naddrs > 16) { nca.ca_naddrs = 16; printf("WARNING: too many (%d) addrs\n", ! pdc_findmod.naddrs); } if (autoconf_verbose) printf(">> ADDRS:"); ! for (ia = 0; !(error = pdc_call((iodcio_t)pdc, 0, ! PDC_SYSMAP, PDC_SYSMAP_FINDADDR, &pdc_findaddr, ! i, ia)) && ia < nca.ca_naddrs; ia++) { ! nca.ca_addrs[ia].addr = pdc_findaddr.hpa; nca.ca_addrs[ia].size = ! pdc_findaddr.size << PGSHIFT; if (autoconf_verbose) printf(" 0x%x[0x%x]", *************** *** 671,709 **** if (autoconf_verbose) printf("\n"); } - } ! if (!nca.ca_hpa) ! continue; ! ! if (autoconf_verbose) ! printf(">> HPA 0x%x[0x%x]\n", ! nca.ca_hpa, nca.ca_hpasz); ! ! if ((error = pdc_call((iodcio_t)pdc, 0, PDC_IODC, ! PDC_IODC_READ, &pdc_iodc_read, nca.ca_hpa, IODC_DATA, ! &nca.ca_type, sizeof(nca.ca_type))) < 0) { ! if (autoconf_verbose) ! printf(">> iodc_data error %d\n", error); ! continue; ! } ! ! nca.ca_pdc_iodc_read = &pdc_iodc_read; ! nca.ca_name = hppa_mod_info(nca.ca_type.iodc_type, ! nca.ca_type.iodc_sv_model); ! ! if (autoconf_verbose) { ! printf(">> probing: flags %b bc %d/%d/%d/%d/%d/%d ", ! nca.ca_dp.dp_flags, PZF_BITS, ! nca.ca_dp.dp_bc[0], nca.ca_dp.dp_bc[1], ! nca.ca_dp.dp_bc[2], nca.ca_dp.dp_bc[3], ! nca.ca_dp.dp_bc[4], nca.ca_dp.dp_bc[5]); ! printf("mod %x hpa %x type %x sv %x\n", ! nca.ca_dp.dp_mod, nca.ca_hpa, ! nca.ca_type.iodc_type, nca.ca_type.iodc_sv_model); } ! ! config_found_sm(self, &nca, mbprint, mbsubmatch); } } --- 762,775 ---- if (autoconf_verbose) printf("\n"); } ! if (!nca.ca_hpa) ! continue; ! ! pdc_scanbuscommon(self, &nca); } ! } else { ! panic("unknown pdc_type value in pdc_scan, autoconf.c"); } } Index: hppa/conf.c =================================================================== RCS file: /var/cvs/openbsd/src/sys/arch/hppa/hppa/conf.c,v retrieving revision 1.28 diff -c -r1.28 conf.c *** hppa/conf.c 23 Sep 2003 16:51:11 -0000 1.28 --- hppa/conf.c 31 Oct 2003 16:39:10 -0000 *************** *** 246,256 **** --- 246,260 ---- struct consdev constab[] = { cons_init(pdc), /* XXX you'd better leave it here for pdc.c */ + #if NWSDISPLAY > 0 cons_init(ws), #endif + + #if 0 /* K machines hang if enabled, see __hppa__ in com.c */ #if NCOM > 0 cons_init(com), + #endif #endif { 0 } }; Index: hppa/machdep.c =================================================================== RCS file: /var/cvs/openbsd/src/sys/arch/hppa/hppa/machdep.c,v retrieving revision 1.116 diff -c -r1.116 machdep.c *** hppa/machdep.c 15 Oct 2003 18:54:55 -0000 1.116 --- hppa/machdep.c 31 Oct 2003 16:39:10 -0000 *************** *** 2,7 **** --- 2,8 ---- /* * Copyright (c) 1999-2002 Michael Shalayeff + * Copyright (c) 2003 Hellmuth Michaelis * All rights reserved. * * Redistribution and use in source and binary forms, with or without *************** *** 142,147 **** --- 143,150 ---- enum hppa_cpu_type cpu_type; const char *cpu_typename; int cpu_hvers; + int pdc_type; + #ifdef COMPAT_HPUX int cpu_model_hpux; /* contains HPUX_SYSCONF_CPU* kind of value */ #endif *************** *** 177,182 **** --- 180,186 ---- void dumpsys(void); void hpmc_dump(void); void cpuid(void); + void pdctype(void); /* * wide used hardware params *************** *** 186,191 **** --- 190,196 ---- struct pdc_coherence pdc_coherence PDC_ALIGNMENT; struct pdc_spidb pdc_spidbits PDC_ALIGNMENT; struct pdc_model pdc_model PDC_ALIGNMENT; + struct pdc_sysmap_findmod pdc_findmod PDC_ALIGNMENT; #ifdef DEBUG int sigdebug = 0; *************** *** 351,363 **** PAGE0->ivec_mempflen = (hppa_pfr_end - hppa_pfr + 1) * 4; } cpuid(); ptlball(); fcacheall(); avail_end = trunc_page(PAGE0->imm_max_mem); ! /*if (avail_end > 32*1024*1024) ! avail_end = 32*1024*1024;*/ totalphysmem = btoc(avail_end); resvmem = btoc(((vaddr_t)&kernel_text)); --- 356,375 ---- PAGE0->ivec_mempflen = (hppa_pfr_end - hppa_pfr + 1) * 4; } + pdctype(); cpuid(); ptlball(); fcacheall(); avail_end = trunc_page(PAGE0->imm_max_mem); ! ! #define AVAIL_END 512 ! ! #ifdef AVAIL_END ! if (avail_end > AVAIL_END*1024*1024) ! avail_end = AVAIL_END*1024*1024; ! #endif ! totalphysmem = btoc(avail_end); resvmem = btoc(((vaddr_t)&kernel_text)); *************** *** 418,424 **** /* they say PDC_COPROC might turn fault light on */ pdc_call((iodcio_t)pdc, 0, PDC_CHASSIS, PDC_CHASSIS_DISP, ! PDC_OSTAT(PDC_OSTAT_RUN) | 0xCEC0); #ifdef DDB ddb_init(); --- 430,436 ---- /* they say PDC_COPROC might turn fault light on */ pdc_call((iodcio_t)pdc, 0, PDC_CHASSIS, PDC_CHASSIS_DISP, ! PDC_OSTAT(PDC_OSTAT_INIT) | 0xCEC0); #ifdef DDB ddb_init(); *************** *** 427,432 **** --- 439,485 ---- } void + pdctype() + { + int i, error; + struct device_path path; + + if ((error = pdc_call((iodcio_t)pdc, 0, PDC_MODEL, PDC_MODEL_INFO, + &pdc_model)) == 0) { + i = (pdc_model.hvers >> 4); /* model */ + i = (i >> 7); /* bus id = upper 5 bits of model */ + i &= 0x1f; + + switch(i) { + case 0x4: /* Viper-VSC: 720, 730, 750, 735, 755 */ + case 0x6: /* K9-KSC: 705, 710 */ + case 0x7: /* Spider-SSC: 715, 725 */ + case 0x8: /* Stiletto-SSC: 745, 747, 742 */ + case 0xA: /* GSC+ (HSC): 712 etc. */ + case 0xC: /* GSC: 715/64 etc. */ + pdc_type = PDC_TYPE_MEMMAP; + return; + } + } else { + #ifdef DEBUG + printf("WARNING: PDC_MODEL error %d\n", error); + #endif + } + + if((pdc_call((iodcio_t)pdc, 0, PDC_SYSMAP, PDC_SYSMAP_FINDMOD, + &pdc_findmod, &path, 0)) == 0) { + pdc_type = PDC_TYPE_SYSMAP; + return; + } + + pdc_type = PDC_TYPE_UNKNOWN; + + /* TODO: check for other methods (PAT ..) */ + + return; + } + + void cpuid() { /* *************** *** 548,554 **** #undef LDILDO { ! const char *p, *q; char buf[32]; int lev; --- 601,607 ---- #undef LDILDO { ! const char *p, *q, *r; char buf[32]; int lev; *************** *** 594,601 **** } } snprintf(cpu_model, sizeof cpu_model, ! "HP 9000/%s PA-RISC %s%x", p, q, lev); } } --- 647,665 ---- } } + switch(pdc_type) { + case PDC_TYPE_MEMMAP: + r = "MEMMAP"; + break; + case PDC_TYPE_SYSMAP: + r = "SYSMAP"; + break; + default: + r = "UNKNOWN"; + break; + } snprintf(cpu_model, sizeof cpu_model, ! "HP 9000/%s PA-RISC %s%x (PDC-type: %s)", p, q, lev, r); } } Index: hppa/mainbus.c =================================================================== RCS file: /var/cvs/openbsd/src/sys/arch/hppa/hppa/mainbus.c,v retrieving revision 1.53 diff -c -r1.53 mainbus.c *** hppa/mainbus.c 29 Sep 2003 19:23:02 -0000 1.53 --- hppa/mainbus.c 31 Oct 2003 16:39:10 -0000 *************** *** 2,7 **** --- 2,8 ---- /* * Copyright (c) 1998-2003 Michael Shalayeff + * Copyright (c) 2003 Hellmuth Michaelis * All rights reserved. * * Redistribution and use in source and binary forms, with or without *************** *** 49,54 **** --- 50,57 ---- #include #include + #include + struct mainbus_softc { struct device sc_dv; *************** *** 1005,1010 **** --- 1008,1146 ---- return 1; } + /* + * for accessing io_status, io_io_low and io_io_high on modules + * with type == HPPA_TYPE_BCPORT, this inline has to be used + */ + + __inline__ unsigned int __raw_readl(unsigned long addr) + { + u_int32_t ret; + __asm__ __volatile__("ldwax 0(%1),%0\n" : "=r" (ret) : "r" (addr)); + return ret; + } + + struct pdc_iodc_read pdc_iodc_read PDC_ALIGNMENT; + + static void + walk_iomem(unsigned int, unsigned int, struct device *); + + #define BC_PORT_MASK 0x08 + #define BC_LOWER_PORT 0x08 + + #define IO_STATUS (offsetof(struct iomod, io_status)) + #define IO_IO_LOW (offsetof(struct iomod, io_io_low)) + #define IO_IO_HIGH (offsetof(struct iomod, io_io_high)) + + static void + walk_iomem(hpa_low, hpa_high, self) + unsigned int hpa_low; + unsigned int hpa_high; + struct device *self; + { + struct confargs nca; + unsigned int hpa; + int i; + int error; + + #ifdef DEBUG_WALK + printf("==> walk_iomem: enter low=0x%x high=0x%x self=0x%x\n", hpa_low, hpa_high, self); + #endif + + for(hpa=hpa_low, i=0; (hpa < hpa_high) && (i < 64); i++, hpa+=IOMOD_HPASIZE) + { + bzero (&nca, sizeof(nca)); + + nca.ca_hpa = hpa; + nca.ca_hpamask = HPPA_IOSPACE; + nca.ca_irq = -1; + nca.ca_iot = &hppa_bustag; + nca.ca_dmatag = &hppa_dmatag; + nca.ca_dp.dp_bc[0] = nca.ca_dp.dp_bc[1] = nca.ca_dp.dp_bc[2] = + nca.ca_dp.dp_bc[3] = nca.ca_dp.dp_bc[4] = nca.ca_dp.dp_bc[5] = -1; + nca.ca_dp.dp_mod = -1; + + if ((error = pdc_call((iodcio_t)pdc, 0, PDC_IODC, + PDC_IODC_READ, &pdc_iodc_read, nca.ca_hpa, IODC_DATA, + &nca.ca_type, sizeof(nca.ca_type))) < 0) + { + continue; + } + + #ifdef DEBUG_WALK + printf("==> walk_iomem: iodc_model = 0x%x\n", nca.ca_type.iodc_model); + printf("==> walk_iomem: iodc_revision = 0x%x\n", nca.ca_type.iodc_revision); + printf("==> walk_iomem: iodc_spa_io = 0x%x\n", nca.ca_type.iodc_spa_io); + printf("==> walk_iomem: iodc_spa_pack = 0x%x\n", nca.ca_type.iodc_spa_pack); + printf("==> walk_iomem: iodc_spa_enb = 0x%x\n", nca.ca_type.iodc_spa_enb); + printf("==> walk_iomem: iodc_spa_shift = 0x%x\n", nca.ca_type.iodc_spa_shift); + printf("==> walk_iomem: iodc_more = 0x%x\n", nca.ca_type.iodc_more); + printf("==> walk_iomem: iodc_word = 0x%x\n", nca.ca_type.iodc_word); + printf("==> walk_iomem: iodc_pf = 0x%x\n", nca.ca_type.iodc_pf); + printf("==> walk_iomem: iodc_type = 0x%x\n", nca.ca_type.iodc_type); + printf("==> walk_iomem: iodc_sv_rev = 0x%x\n", nca.ca_type.iodc_sv_rev); + printf("==> walk_iomem: iodc_sv_model = 0x%x\n", nca.ca_type.iodc_sv_model); + printf("==> walk_iomem: iodc_sv_opt = 0x%x\n", nca.ca_type.iodc_sv_opt); + printf("==> walk_iomem: iodc_rev = 0x%x\n", nca.ca_type.iodc_rev); + printf("==> walk_iomem: iodc_dep = 0x%x\n", nca.ca_type.iodc_dep); + #endif + + #if 0 + nca.ca_dp.dp_bc[5] = i; + #endif + + nca.ca_pdc_iodc_read = &pdc_iodc_read; + nca.ca_name = hppa_mod_info(nca.ca_type.iodc_type, + nca.ca_type.iodc_sv_model); + + config_found_sm(self, &nca, mbprint, mbsubmatch); + + if(nca.ca_type.iodc_type == HPPA_TYPE_IOA || + nca.ca_type.iodc_type == HPPA_TYPE_BCPORT) + { + unsigned int iostat; + + iostat = __raw_readl(hpa + IO_STATUS); + + #ifdef DEBUG_WALK + printf("==> walk_iomem: [%d] iostat = 0x%x\n", i, iostat); + #endif + + if(!((iostat & BC_PORT_MASK) == BC_LOWER_PORT)) + { + u_int low, high; + low = __raw_readl(hpa + IO_IO_LOW); + high = __raw_readl(hpa + IO_IO_HIGH); + + #ifdef DEBUG_WALK + printf("==> walk_iomem: [%d] io_io_low=0x%x io_io_high=0x%x\n", i, low, high); + #endif + + if(nca.ca_type.iodc_type == HPPA_TYPE_IOA) + { + low = low << 16; + high = (high << 16) + (64*IOMOD_HPASIZE); + + #ifdef DEBUG_WALK + printf("==> walk_iomem: [%d] ioa real io_io_low=0x%x io_io_high=0x%x\n", i, low, high); + #endif + } + else + { + low = (low + ~HPPA_FLEX_MASK) & HPPA_FLEX_MASK; + high = (high + ~HPPA_FLEX_MASK) & HPPA_FLEX_MASK; + #ifdef DEBUG_WALK + printf("==> walk_iomem: [%d] bcp real io_io_low=0x%x io_io_high=0x%x\n", i, low, high); + #endif + } + walk_iomem(low, high, self); + } + } + } + } + + extern int pdc_type; + void mbattach(parent, self, aux) struct device *parent; *************** *** 1066,1071 **** --- 1202,1214 ---- nca.ca_dp.dp_bc[3] = nca.ca_dp.dp_bc[4] = nca.ca_dp.dp_bc[5] = -1; nca.ca_dp.dp_mod = -1; pdc_scanbus(self, &nca, MAXMODBUS); + + if(pdc_type == PDC_TYPE_SYSMAP) { + + /* scan the central bus recursively */ + + walk_iomem(FP_ADDR, FP_ADDR+(64*IOMOD_HPASIZE), self); + } } /* Index: include/pdc.h =================================================================== RCS file: /var/cvs/openbsd/src/sys/arch/hppa/include/pdc.h,v retrieving revision 1.26 diff -c -r1.26 pdc.h *** include/pdc.h 20 Aug 2003 22:51:07 -0000 1.26 --- include/pdc.h 31 Oct 2003 16:39:11 -0000 *************** *** 31,36 **** --- 31,52 ---- #define _MACHINE_PDC_H_ /* + * There are three possibilities of probing for IODC modules: + * - using the pdc call PDC_MEMMAP + * this works for many workstations + * - using the pdc call PDC_SYSMAP + * this works for "old" servers like the K series + * - using the pdc PAT mechanisms + * this works for the "new" 64bit server like the L and upward + * implemented is the PDC_MEMMAP and PDC_SYSMAP probing + */ + + #define PDC_TYPE_UNKNOWN 0 + #define PDC_TYPE_MEMMAP 1 + #define PDC_TYPE_SYSMAP 2 + /* #define PDC_TYPE_PAT 3 */ + + /* * Definitions for interaction with "Processor Dependent Code", * which is a set of ROM routines used to provide information to the OS. * Also includes definitions for the layout of "Page Zero" memory when *************** *** 229,237 **** #define PDC_PSW_SETDEFAULTS 2 /* set default bits values */ #define PDC_SYSMAP 22 /* map system modules */ ! #define PDC_SYSMAP_FIND 0 /* find module by index */ ! #define PDC_SYSMAP_ADDR 1 ! #define PDC_SYSMAP_HPA 2 /* same as PDC_MEMMAP_HPA */ #define PDC_SOFT_POWER 23 /* support for soft power switch */ #define PDC_SOFT_POWER_INFO 0 /* get info about soft power switch */ --- 245,253 ---- #define PDC_PSW_SETDEFAULTS 2 /* set default bits values */ #define PDC_SYSMAP 22 /* map system modules */ ! #define PDC_SYSMAP_FINDMOD 0 /* find module by index */ ! #define PDC_SYSMAP_FINDADDR 1 /* find address */ ! #define PDC_SYSMAP_XLATPATH 2 /* translate path */ #define PDC_SOFT_POWER 23 /* support for soft power switch */ #define PDC_SOFT_POWER_INFO 0 /* get info about soft power switch */ *************** *** 462,480 **** u_int filler[30]; }; ! struct pdc_sysmap_find { /* PDC_SYSMAP_FIND */ ! u_int hpa; ! u_int size; /* pages */ ! u_int naddrs; u_int filler[29]; }; ! struct pdc_sysmap_addrs { /* PDC_SYSMAP_ADDR */ ! u_int hpa; ! u_int size; /* pages */ u_int filler[30]; }; struct pdc_pat_io_num { /* PDC_PAT_IO */ u_int num; u_int filler[31]; --- 478,504 ---- u_int filler[30]; }; ! struct pdc_sysmap_findmod { /* PDC_SYSMAP_FINDMOD */ ! u_int hpa; /* module address */ ! u_int size; /* no of pages */ ! u_int naddrs; /* no of additional address ranges */ u_int filler[29]; }; ! struct pdc_sysmap_findaddr { /* PDC_SYSMAP_FINDADDR */ ! u_int hpa; /* module address */ ! u_int size; /* no of pages */ u_int filler[30]; }; + struct pdc_sysmap_xlatpath { /* PDC_SYSMAP_XLATPATH */ + u_int hpa; /* module address */ + u_int size; /* no of pages */ + u_int naddr; /* no of additional address ranges */ + u_int modindex; /* module index */ + u_int filler[28]; + }; + struct pdc_pat_io_num { /* PDC_PAT_IO */ u_int num; u_int filler[31]; *************** *** 526,532 **** #define PDC_OSTAT_OFF 0x0 /* all off */ #define PDC_OSTAT_FAULT 0x1 /* the red LED of death */ #define PDC_OSTAT_TEST 0x2 /* self test */ ! #define PDC_OSTAT_BOOT 0x3 /* boot program running */ #define PDC_OSTAT_SHUT 0x4 /* shutdown in progress */ #define PDC_OSTAT_WARN 0x5 /* battery dying, etc */ #define PDC_OSTAT_RUN 0x6 /* OS running */ --- 550,556 ---- #define PDC_OSTAT_OFF 0x0 /* all off */ #define PDC_OSTAT_FAULT 0x1 /* the red LED of death */ #define PDC_OSTAT_TEST 0x2 /* self test */ ! #define PDC_OSTAT_INIT 0x3 /* initalize */ #define PDC_OSTAT_SHUT 0x4 /* shutdown in progress */ #define PDC_OSTAT_WARN 0x5 /* battery dying, etc */ #define PDC_OSTAT_RUN 0x6 /* OS running */