From owner-freebsd-sparc64@FreeBSD.ORG Mon Sep 1 19:18:15 2003 Return-Path: Delivered-To: freebsd-sparc64@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 0E44E16A4BF for ; Mon, 1 Sep 2003 19:18:15 -0700 (PDT) Received: from ns1.xcllnt.net (209-128-86-226.bayarea.net [209.128.86.226]) by mx1.FreeBSD.org (Postfix) with ESMTP id B77DD43FAF for ; Mon, 1 Sep 2003 19:18:13 -0700 (PDT) (envelope-from marcel@xcllnt.net) Received: from dhcp01.pn.xcllnt.net (dhcp01.pn.xcllnt.net [192.168.4.201]) by ns1.xcllnt.net (8.12.9/8.12.9) with ESMTP id h822IDwO027250 for ; Mon, 1 Sep 2003 19:18:13 -0700 (PDT) (envelope-from marcel@piii.pn.xcllnt.net) Received: from dhcp01.pn.xcllnt.net (localhost [127.0.0.1]) by dhcp01.pn.xcllnt.net (8.12.9/8.12.9) with ESMTP id h822IDsn002334 for ; Mon, 1 Sep 2003 19:18:13 -0700 (PDT) (envelope-from marcel@dhcp01.pn.xcllnt.net) Received: (from marcel@localhost) by dhcp01.pn.xcllnt.net (8.12.9/8.12.9/Submit) id h822IDs9002333 for sparc64@FreeBSD.org; Mon, 1 Sep 2003 19:18:13 -0700 (PDT) (envelope-from marcel) Date: Mon, 1 Sep 2003 19:18:13 -0700 From: Marcel Moolenaar To: sparc64@FreeBSD.org Message-ID: <20030902021813.GA2300@dhcp01.pn.xcllnt.net> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="IJpNTDwzlM2Ie8A6" Content-Disposition: inline User-Agent: Mutt/1.5.4i Subject: Req review: OF_decode_addr() X-BeenThere: freebsd-sparc64@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Porting FreeBSD to the Sparc List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 02 Sep 2003 02:18:15 -0000 --IJpNTDwzlM2Ie8A6 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Gang, Attached a patch to add function OF_decode_addr(). The function takes a package handle (phandle_t) and returns the physical (decoded) address at which it resides as well as it space. This function is needed by uart(4) to for low-level console access. There's one thing I'm not happy about and that's the call to ofw_isa_map_iorange(). It makes it impossible to create a kernel without isa. It makes sense to move the bulk of the code in OF_decode_addr() to the respective bus drivers and have some linker set to tie bus name to function pointer. I'm not sure it's important to have that right away or if we can commit this and deal with that later? -- Marcel Moolenaar USPA: A-39004 marcel@xcllnt.net --IJpNTDwzlM2Ie8A6 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="sparc.diff" Index: dev/gem/if_gem_pci.c =================================================================== RCS file: /home/ncvs/src/sys/dev/gem/if_gem_pci.c,v retrieving revision 1.11 diff -u -r1.11 if_gem_pci.c --- dev/gem/if_gem_pci.c 24 Aug 2003 17:46:07 -0000 1.11 +++ dev/gem/if_gem_pci.c 2 Sep 2003 02:01:34 -0000 @@ -53,6 +53,7 @@ #include #include +#include #include #include Index: dev/hme/if_hme_pci.c =================================================================== RCS file: /home/ncvs/src/sys/dev/hme/if_hme_pci.c,v retrieving revision 1.10 diff -u -r1.10 if_hme_pci.c --- dev/hme/if_hme_pci.c 24 Aug 2003 17:46:09 -0000 1.10 +++ dev/hme/if_hme_pci.c 2 Sep 2003 02:03:45 -0000 @@ -43,6 +43,7 @@ #include #include +#include #include #include Index: dev/hme/if_hme_sbus.c =================================================================== RCS file: /home/ncvs/src/sys/dev/hme/if_hme_sbus.c,v retrieving revision 1.7 diff -u -r1.7 if_hme_sbus.c --- dev/hme/if_hme_sbus.c 24 Aug 2003 17:46:09 -0000 1.7 +++ dev/hme/if_hme_sbus.c 2 Sep 2003 02:03:55 -0000 @@ -51,6 +51,7 @@ #include #include +#include #include #include Index: dev/isp/isp_sbus.c =================================================================== RCS file: /home/ncvs/src/sys/dev/isp/isp_sbus.c,v retrieving revision 1.10 diff -u -r1.10 isp_sbus.c --- dev/isp/isp_sbus.c 24 Aug 2003 17:49:14 -0000 1.10 +++ dev/isp/isp_sbus.c 2 Sep 2003 00:47:52 -0000 @@ -35,10 +35,10 @@ #include #include #include -#include #include #include #include +#include #include #include Index: sparc64/include/ofw_machdep.h =================================================================== RCS file: /home/ncvs/src/sys/sparc64/include/ofw_machdep.h,v retrieving revision 1.2 diff -u -r1.2 ofw_machdep.h --- sparc64/include/ofw_machdep.h 13 Mar 2002 04:59:01 -0000 1.2 +++ sparc64/include/ofw_machdep.h 2 Sep 2003 00:20:14 -0000 @@ -30,7 +30,8 @@ #include -void OF_getetheraddr(device_t dev, u_char *addr); +int OF_decode_addr(phandle_t, int *, bus_addr_t *); +void OF_getetheraddr(device_t, u_char *); void cpu_shutdown(void *); void openfirmware_exit(void *); Index: sparc64/sparc64/machdep.c =================================================================== RCS file: /home/ncvs/src/sys/sparc64/sparc64/machdep.c,v retrieving revision 1.100 diff -u -r1.100 machdep.c --- sparc64/sparc64/machdep.c 11 Aug 2003 07:05:55 -0000 1.100 +++ sparc64/sparc64/machdep.c 2 Sep 2003 01:26:18 -0000 @@ -89,6 +89,7 @@ #include +#include #include #include #include Index: sparc64/sparc64/mp_machdep.c =================================================================== RCS file: /home/ncvs/src/sys/sparc64/sparc64/mp_machdep.c,v retrieving revision 1.22 diff -u -r1.22 mp_machdep.c --- sparc64/sparc64/mp_machdep.c 22 Aug 2003 07:38:08 -0000 1.22 +++ sparc64/sparc64/mp_machdep.c 2 Sep 2003 01:27:06 -0000 @@ -80,6 +80,7 @@ #include #include +#include #include #include #include Index: sparc64/sparc64/ofw_machdep.c =================================================================== RCS file: /home/ncvs/src/sys/sparc64/sparc64/ofw_machdep.c,v retrieving revision 1.3 diff -u -r1.3 ofw_machdep.c --- sparc64/sparc64/ofw_machdep.c 23 Aug 2003 00:11:15 -0000 1.3 +++ sparc64/sparc64/ofw_machdep.c 2 Sep 2003 00:24:55 -0000 @@ -36,8 +36,15 @@ #include +#include #include #include +#include +#include + +#include +#include +#include void OF_getetheraddr(device_t dev, u_char *addr) @@ -49,4 +56,107 @@ if (node <= 0 || OF_getprop(node, "idprom", &idp, sizeof(idp)) == -1) panic("Could not determine the machine ethernet address"); bcopy(&idp.id_ether, addr, ETHER_ADDR_LEN); +} + +int +OF_decode_addr(phandle_t node, int *space, bus_addr_t *addr) +{ + char name[32]; + union { + struct isa_ranges isa[4]; + struct sbus_ranges sbus[8]; + struct upa_ranges upa[4]; + } range; + union { + struct isa_regs isa; + struct sbus_regs sbus; + } reg; + phandle_t bus, pbus; + u_long child, dummy, phys; + int cs, i, rsz, type; + + bus = OF_parent(node); + if (bus == NULL) + return (ENXIO); + if (OF_getprop(bus, "name", name, sizeof(name)) == -1) + return (ENXIO); + name[sizeof(name) - 1] = '\0'; + if (strcmp(name, "ebus") == 0) { + if (OF_getprop(node, "reg", ®.isa, sizeof(reg.isa)) == -1) + return (ENXIO); + rsz = OF_getprop(bus, "ranges", range.isa, sizeof(range.isa)); + if (rsz == -1) + return (ENXIO); + phys = ISA_REG_PHYS(®.isa); + dummy = phys + 1; + type = ofw_isa_map_iorange(range.isa, rsz / sizeof(*range.isa), + &phys, &dummy); + if (type == SYS_RES_MEMORY) { + cs = PCI_CS_MEM32; + *space = PCI_MEMORY_BUS_SPACE; + } else { + cs = PCI_CS_IO; + *space = PCI_IO_BUS_SPACE; + } + + /* Find the topmost PCI node (the host bridge) */ + while (1) { + pbus = OF_parent(bus); + if (pbus == NULL) + return (ENXIO); + if (OF_getprop(pbus, "name", name, sizeof(name)) == -1) + return (ENXIO); + name[sizeof(name) - 1] = '\0'; + if (strcmp(name, "pci") != 0) + break; + bus = pbus; + } + + /* There wasn't a PCI bridge. */ + if (bus == OF_parent(node)) + return (ENXIO); + + /* Make sure we reached the UPA/PCI node. */ + if (OF_getprop(pbus, "device_type", name, sizeof(name)) == -1) + return (ENXIO); + name[sizeof(name) - 1] = '\0'; + if (strcmp(name, "upa") != 0) + return (ENXIO); + + rsz = OF_getprop(bus, "ranges", range.upa, sizeof(range.upa)); + if (rsz == -1) + return (ENXIO); + for (i = 0; i < (rsz / sizeof(range.upa[0])); i++) { + child = UPA_RANGE_CHILD(&range.upa[i]); + if (UPA_RANGE_CS(&range.upa[i]) == cs && + phys >= child && + phys - child < UPA_RANGE_SIZE(&range.upa[i])) { + *addr = UPA_RANGE_PHYS(&range.upa[i]) + phys; + return (0); + } + } + } else if (strcmp(name, "sbus") == 0) { + if (OF_getprop(node, "reg", ®.sbus, sizeof(reg.sbus)) == -1) + return (ENXIO); + rsz = OF_getprop(bus, "ranges", range.sbus, + sizeof(range.sbus)); + if (rsz == -1) + return (ENXIO); + for (i = 0; i < (rsz / sizeof(range.sbus[0])); i++) { + if (reg.sbus.sbr_slot != range.sbus[i].cspace) + continue; + if (reg.sbus.sbr_offset < range.sbus[i].coffset || + reg.sbus.sbr_offset >= range.sbus[i].coffset + + range.sbus[i].size) + continue; + /* Found it... */ + phys = range.sbus[i].poffset | + ((bus_addr_t)range.sbus[i].pspace << 32); + phys += reg.sbus.sbr_offset - range.sbus[i].coffset; + *addr = phys; + *space = SBUS_BUS_SPACE; + return (0); + } + } + return (ENXIO); } Index: sparc64/sparc64/vm_machdep.c =================================================================== RCS file: /home/ncvs/src/sys/sparc64/sparc64/vm_machdep.c,v retrieving revision 1.51 diff -u -r1.51 vm_machdep.c --- sparc64/sparc64/vm_machdep.c 29 Aug 2003 20:04:10 -0000 1.51 +++ sparc64/sparc64/vm_machdep.c 2 Sep 2003 01:28:46 -0000 @@ -76,6 +76,7 @@ #include #include +#include #include #include #include --IJpNTDwzlM2Ie8A6--