From owner-soc-status@FreeBSD.ORG Tue Aug 17 00:03:56 2010 Return-Path: Delivered-To: soc-status@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 4EAA41065674; Tue, 17 Aug 2010 00:03:56 +0000 (UTC) (envelope-from phcoder@gmail.com) Received: from mail-bw0-f54.google.com (mail-bw0-f54.google.com [209.85.214.54]) by mx1.freebsd.org (Postfix) with ESMTP id D24278FC17; Tue, 17 Aug 2010 00:03:54 +0000 (UTC) Received: by bwz20 with SMTP id 20so2778615bwz.13 for ; Mon, 16 Aug 2010 17:03:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:message-id:date:from :user-agent:mime-version:to:subject:references:in-reply-to :x-enigmail-version:content-type; bh=+F/C6rEzA7EYeKmuyL+XeDTutgQw1e7/IVOGHACgYj0=; b=nnlV9sporNpKK+ha7QCaoWjGtOoRcNcLa6d1f5vBjEl8dS67hRqqaE20QmfUPdvcgH sOZH8xzvY2yNtaZJ9wMDEzBHP46wBKmY9x9hotoe7Cph20yrZjIBn1T87Z+GkkI2npiV MOZwdehEP4lvpUJDfd8X3uP0ef/7L/V2VMcLE= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=message-id:date:from:user-agent:mime-version:to:subject:references :in-reply-to:x-enigmail-version:content-type; b=xEiIq1SfR6qvkDmpXWKToXkMFGyDnLx3H7OsOSVjh22bY7Jmx+z6vbfQfNECb/vjry NiM68ZSjoOhXLFMBkfvAKTCQ9f+Wtq7Uja6dZbd1v4PO+7Zi9CYfKS40/0daoTIDd5UT QBpq+9UyiXUj8AV2JKsu/XVq21eGwHhHfLeIE= Received: by 10.204.81.39 with SMTP id v39mr3898486bkk.149.1282003433387; Mon, 16 Aug 2010 17:03:53 -0700 (PDT) Received: from debian.bg45.phnet (120-59.203-62.cust.bluewin.ch [62.203.59.120]) by mx.google.com with ESMTPS id y2sm4729888bkx.8.2010.08.16.17.03.44 (version=TLSv1/SSLv3 cipher=RC4-MD5); Mon, 16 Aug 2010 17:03:51 -0700 (PDT) Message-ID: <4C69D1D5.809@gmail.com> Date: Tue, 17 Aug 2010 02:03:33 +0200 From: =?UTF-8?B?VmxhZGltaXIgJ8+GLWNvZGVyL3BoY29kZXInIFNlcmJpbmVua28=?= User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.10) Gecko/20100620 Icedove/3.0.5 MIME-Version: 1.0 To: soc-status@freebsd.org, freebsd-mips@freebsd.org References: <4C67704C.70609@gmail.com> <4C6861B4.6020102@gmail.com> In-Reply-To: <4C6861B4.6020102@gmail.com> X-Enigmail-Version: 1.0.1 Content-Type: multipart/signed; micalg=pgp-sha512; protocol="application/pgp-signature"; boundary="------------enig7C782B83CD85D5ED0E2C2328" Cc: Subject: Re: Yeeloong port is functional X-BeenThere: soc-status@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Summer of Code Status Reports and Discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 17 Aug 2010 00:03:56 -0000 This is an OpenPGP/MIME signed message (RFC 2440 and 3156) --------------enig7C782B83CD85D5ED0E2C2328 Content-Type: multipart/mixed; boundary="------------040307070901010105060107" This is a multi-part message in MIME format. --------------040307070901010105060107 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable On 08/15/2010 11:52 PM, Vladimir '=CF=86-coder/phcoder' Serbinenko wrote:= > Hello, all. Some cleanups and I managed to enable cache on kseg0. > Additionally it has some basic Geode support. > I'm looking forward to split it in smaller patches in order to get it > into HEAD. Also I'll fill the blanks (like power management) as time > permits. > =20 And another update. Now Geode USB is fully functional. Few other issues are fixed. Unfortunately I couldn't find a way to fix cache completely. So I decided to change page size to 16KB to make tag bits of VA to be identical to PA effectively transforming VIPT cache into PIPT which is easier to handle. It's not functional yet but it will be soon. Even though the GSoC is nearly over I'll continue to work on yeeloong to fix remaining issues. Sorry for delays caused by hw malfunctions. And thanks to everybody who supported me, especially Juli Mallett, Olexandr Tymoshenko and M. Warner Losh > On 08/15/2010 06:42 AM, Vladimir '=CF=86-coder/phcoder' Serbinenko wrot= e: > =20 >> Hello, all. Despite the hardware-inflicted setbacks (my yeeloong fried= >> right before the mid-term), Yeeloong port is now functional. Both seri= al >> and local (keyboard + screen) work. Real Time Clock is working. Intern= et >> is working. USB controller on PCI is working. Userspace is working. >> >> Remaining issues: >> 1) Disabled cache. The reason are peculiar properties of L2 cache. I >> actualy have the code to fix it but I'm not sure to hit GSoC deadline >> about it. >> 2) Only 256 MiB of RAM are supported. Should be easy to fix once 64-bi= t >> parts are in. >> 3) No Geode support. So no IDE, 2 of 3 USB ports or audio. These >> components are actualy pretty standard, one has only to add support fo= r >> MSRs. >> 4) No power management. Wasn't planned to have it implemented during G= SoC. >> >> Not tested: >> 1) Touchpad. Never connected to my laptop during developpement because= >> to use it one has to close front lid and so cut from serial connector >> >> 3rd party developpements which will improve Yeeloong support: >> 1) X.org support. The required card is already supported in latest >> x.org. So it's a question of importing last X.org and testing it. >> 2) 64-bit developpement. Currently if I compile 64-bit kernel it >> contains only 64-bit imgact. Imposing only 64-bit binaries is suboptim= al. >> >> =20 >> =20 > > =20 --=20 Regards Vladimir '=CF=86-coder/phcoder' Serbinenko --------------040307070901010105060107 Content-Type: text/x-diff; name="yeeloong_rc3.diff" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="yeeloong_rc3.diff" =3D=3D=3D modified file 'cam/cam_xpt.c' --- cam/cam_xpt.c 2010-08-13 22:16:49 +0000 +++ cam/cam_xpt.c 2010-08-14 10:37:00 +0000 @@ -816,6 +816,9 @@ return 0; } =20 +static struct root_hold_token *xpt_rool_hold =3D NULL; +static int rescan_counter =3D 0; + static void xpt_rescan_done(struct cam_periph *periph, union ccb *done_ccb) { @@ -828,6 +831,11 @@ (*done_ccb->ccb_h.cbfcnp)(periph, done_ccb); } xpt_release_boot(); + if (atomic_fetchadd_int (&rescan_counter, -1) =3D=3D 1) + { + root_mount_rel (xpt_rool_hold); + xpt_rool_hold =3D NULL; + } } =20 /* thread to handle bus rescans */ @@ -861,6 +869,11 @@ { struct ccb_hdr *hdr; =20 + if (atomic_fetchadd_int (&rescan_counter, 1) =3D=3D 0) + { + xpt_rool_hold =3D root_mount_hold("XPT bus rescan"); + } + /* Prepare request */ if (ccb->ccb_h.path->target->target_id =3D=3D CAM_TARGET_WILDCARD && ccb->ccb_h.path->device->lun_id =3D=3D CAM_LUN_WILDCARD) =3D=3D=3D modified file 'conf/ldscript.mips' --- conf/ldscript.mips 2010-08-13 22:16:49 +0000 +++ conf/ldscript.mips 2010-08-14 20:45:41 +0000 @@ -44,6 +44,7 @@ { /* Read-only sections, merged into text segment: */ . =3D KERNLOADADDR + SIZEOF_HEADERS; + .multiboot : { *(.multiboot) } .text : { *(.trap) @@ -64,6 +65,7 @@ .rodata : { *(.rodata) *(.rodata.*) *(.gnu.linkonce.r.*) } .rodata1 : { *(.rodata1) } .interp : { *(.interp) } + .multiboot : { *(.multiboot) } .hash : { *(.hash) } .dynsym : { *(.dynsym) } .dynstr : { *(.dynstr) } =3D=3D=3D modified file 'conf/ldscript.mips.mips64' --- conf/ldscript.mips.mips64 2010-08-13 22:16:49 +0000 +++ conf/ldscript.mips.mips64 2010-08-14 10:37:00 +0000 @@ -45,6 +45,7 @@ /* Read-only sections, merged into text segment: */ . =3D KERNLOADADDR + SIZEOF_HEADERS; .interp : { *(.interp) } + .multiboot : { *(.multiboot) } .hash : { *(.hash) } .dynsym : { *(.dynsym) } .dynstr : { *(.dynstr) } =3D=3D=3D modified file 'conf/options.mips' --- conf/options.mips 2010-08-13 22:16:49 +0000 +++ conf/options.mips 2010-08-14 21:18:26 +0000 @@ -66,3 +66,9 @@ # OCTEON_VENDOR_LANNER opt_cvmx.h OCTEON_BOARD_CAPK_0100ND opt_cvmx.h + +ATKBD_DFLT_KEYMAP opt_atkbd.h + +PSM_DEBUG opt_psm.h +PSM_HOOKRESUME opt_psm.h +PSM_RESETAFTERSUSPEND opt_psm.h =3D=3D=3D modified file 'dev/atkbdc/atkbdc.c' --- dev/atkbdc/atkbdc.c 2010-08-13 22:16:49 +0000 +++ dev/atkbdc/atkbdc.c 2010-08-14 21:18:26 +0000 @@ -114,8 +114,8 @@ static int wait_for_aux_data(atkbdc_softc_t *kbdc); static int wait_for_aux_ack(atkbdc_softc_t *kbdc); =20 -atkbdc_softc_t -*atkbdc_get_softc(int unit) +atkbdc_softc_t * +atkbdc_get_softc(int unit) { atkbdc_softc_t *sc; =20 @@ -182,6 +182,8 @@ tag =3D IA64_BUS_SPACE_IO; #elif defined(__sparc64__) tag =3D &atkbdc_bst_store[0]; +#elif defined(__mips) + tag =3D mips_bus_space_generic; #else #error "define tag!" #endif @@ -213,6 +215,17 @@ return 0; h1 =3D sparc64_fake_bustag(space, port1, tag); bus_space_subregion(tag, h1, KBD_STATUS_PORT, 1, &h1); +#elif defined(__mips) + port0 =3D IO_KBD + (intptr_t)(int32_t)0xbfd00000; + resource_int_value("atkbdc", 0, "port", &port0); + port1 =3D IO_KBD + KBD_STATUS_PORT+ (intptr_t)(int32_t)0xbfd00000; +#ifdef notyet + bus_space_map(tag, port0, IO_KBDSIZE, 0, &h0); + bus_space_map(tag, port1, IO_KBDSIZE, 0, &h1); +#else + h0 =3D (bus_space_handle_t)port0; + h1 =3D (bus_space_handle_t)port1; +#endif #else port0 =3D IO_KBD; resource_int_value("atkbdc", 0, "port", &port0); =3D=3D=3D added directory 'dev/cs5536' =3D=3D=3D added file 'dev/cs5536/cs5536.c' --- dev/cs5536/cs5536.c 1970-01-01 00:00:00 +0000 +++ dev/cs5536/cs5536.c 2010-08-16 19:55:52 +0000 @@ -0,0 +1,708 @@ +/*- + * Copyright (c) 1998 The NetBSD Foundation, Inc. + * Copyright (c) 2010 Vladimir Serbinenko + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundati= on + * by Lennart Augustsson (augustss@carlstedt.se) at + * Carlstedt Research & Technology. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in th= e + * documentation and/or other materials provided with the distributio= n. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBU= TORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT L= IMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTI= CULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBU= TORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, O= R + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSIN= ESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER = IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWIS= E) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED O= F THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +/* + * USB Open Host Controller driver. + * + * OHCI spec: http://www.intel.com/design/usb/ohci11d.pdf + */ + +/* The low level controller code for OHCI has been split into + * PCI probes and OHCI specific code. This was done to facilitate the + * sharing of code between *BSD's + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +static device_probe_t geode_pci_probe; +static device_attach_t geode_pci_attach; +static device_detach_t geode_pci_detach; +static device_suspend_t geode_pci_suspend; +static device_resume_t geode_pci_resume; + +#define USB_INTERRUPT 11 + +#define GEODE_INTR_C1R0 (*(volatile uint8_t *)(intptr_t)(int32_t)0xbfd00= 020) +#define GEODE_INTR_C2R0 (*(volatile uint8_t *)(intptr_t)(int32_t)0xbfd00= 0a0) +#define GEODE_INTR_C1R1 (*(volatile uint8_t *)(intptr_t)(int32_t)0xbfd00= 021) +#define GEODE_INTR_C2R1 (*(volatile uint8_t *)(intptr_t)(int32_t)0xbfd00= 0a1) + +#define GEODE_NUM_INTS 16 + +typedef struct geode_softc +{ + ohci_softc_t ohci; + ehci_softc_t ehci; + struct intr_event *intr_events[GEODE_NUM_INTS]; + void *geode_intr_cookie; + int mask; + struct rman sc_irq; +} geode_softc_t; + +static int +geode_pci_suspend(device_t self) +{ + geode_softc_t *sc =3D device_get_softc(self); + int err; + + err =3D bus_generic_suspend(self); + if (err) { + return (err); + } + ohci_suspend(&sc->ohci); + ehci_suspend(&sc->ehci); + return (0); +} + +static int +geode_pci_resume(device_t self) +{ + geode_softc_t *sc =3D device_get_softc(self); + uint32_t reg, int_line; + + if (pci_get_powerstate(self) !=3D PCI_POWERSTATE_D0) { + device_printf(self, "chip is in D%d mode " + "-- setting to D0\n", pci_get_powerstate(self)); + reg =3D pci_read_config(self, PCI_CBMEM, 4); + int_line =3D pci_read_config(self, PCIR_INTLINE, 4); + pci_set_powerstate(self, PCI_POWERSTATE_D0); + pci_write_config(self, PCI_CBMEM, reg, 4); + pci_write_config(self, PCIR_INTLINE, int_line, 4); + } + ohci_resume(&sc->ohci); + ehci_resume(&sc->ehci); + + bus_generic_resume(self); + return (0); +} + +static const char * +geode_pci_match(device_t self) +{ + uint32_t device_id =3D pci_get_devid(self); + + if (device_id =3D=3D 0x208f1022) + return ("Geode PCI companion controller"); + return (NULL); +} + +static int +geode_pci_probe(device_t self) +{ + const char *desc =3D geode_pci_match(self); + + if (desc) { + device_set_desc(self, desc); + return (0); + } else { + return (ENXIO); + } +} + +#define CS5536_MSR_MAILBOX_ADDR 0xf4 +#define CS5536_MSR_MAILBOX_DATA0 0xf8 +#define CS5536_MSR_MAILBOX_DATA1 0xfc +#define CS5536_MSR_USB_OHCI_BASE 0x40000008 +#define CS5536_MSR_USB_EHCI_BASE 0x40000009 +#define CS5536_MSR_USB_BASE_ADDR_MASK 0x00ffffff00ULL +#define CS5536_MSR_USB_BASE_BUS_MASTER 0x0400000000ULL +#define CS5536_MSR_USB_BASE_MEMORY_ENABLE 0x0200000000ULL +#define CS5536_MSR_USB_BASE_PME_ENABLED 0x0800000000ULL +#define CS5536_MSR_USB_BASE_PME_STATUS 0x1000000000ULL +#define CS5536_MSR_USB_EHCI_BASE_FLDJ_SHIFT 40 + +static uint64_t +geode_read_msr (device_t self, uint32_t addr) +{ + uint64_t ret =3D 0; + pci_write_config (self, CS5536_MSR_MAILBOX_ADDR, addr, 4); + ret =3D (uint64_t) pci_read_config (self, CS5536_MSR_MAILBOX_DATA0, 4)= ; + ret |=3D ((uint64_t) pci_read_config (self, CS5536_MSR_MAILBOX_DATA1,4= )) << 32; + return ret; +} + +static void +geode_write_msr (device_t self, uint32_t addr, uint64_t val) +{ + pci_write_config (self, CS5536_MSR_MAILBOX_ADDR, addr, 4); + pci_write_config (self, CS5536_MSR_MAILBOX_DATA0, val & 0xffffffff, 4)= ; + pci_write_config (self, CS5536_MSR_MAILBOX_DATA1, val >> 32, 4); +} + +static uint16_t intmask; + +static void +geode_intr(void *sc_in) +{ + uint16_t status =3D 0; + geode_softc_t *sc =3D sc_in; + int i; + + GEODE_INTR_C1R0 =3D 0x0a; + status =3D GEODE_INTR_C1R0; + GEODE_INTR_C2R0 =3D 0x0a; + status |=3D (GEODE_INTR_C2R0 << 8); + + GEODE_INTR_C1R0 =3D 0x0a; + GEODE_INTR_C1R0 =3D 0x0a; + + status &=3D ~intmask; + + while ((i =3D fls(status)) !=3D 0) { + struct intr_event *event; + i--; /* Get a 0-offset interrupt. */ + event =3D sc->intr_events[i]; + + status &=3D ~(1 << i); + + /* issue EOI. */ + if (i >=3D 8) + GEODE_INTR_C2R0 =3D 0x60 | (i - 8); + else + GEODE_INTR_C1R0 =3D 0x60 | i; + + if (i =3D=3D 2) + continue; + + if (!event || TAILQ_EMPTY(&event->ie_handlers)) { + printf("stray geode interrupt %d\n", i); + continue; + } + + if (intr_event_handle(event, NULL) !=3D 0) { + printf("stray geode interrupt %d\n", i); + } + } +} + +static void +geode_unmask_irq(void *source) +{ + uintptr_t irq =3D (uintptr_t)source; + + intmask &=3D ~(1 << irq); + + GEODE_INTR_C2R1 =3D intmask >> 8; + GEODE_INTR_C1R1 =3D intmask & 0xff; +} + +static void +geode_mask_irq(void *source) +{ + uintptr_t irq =3D (uintptr_t)source; + + intmask |=3D (1 << irq); + GEODE_INTR_C2R1 =3D intmask >> 8; + GEODE_INTR_C1R1 =3D intmask & 0xff; +} + +static int +geode_setup_intr_real(device_t self, int irq, + int flags, driver_filter_t *filt, driver_intr_t *handler,=20 + void *arg, void **cookiep) +{ + geode_softc_t *sc =3D device_get_softc(self); + struct intr_event *event; + int error; + + if (irq < 0 || irq >=3D GEODE_NUM_INTS) + return ENXIO; + + event =3D sc->intr_events[irq]; + if (event =3D=3D NULL) { + error =3D intr_event_create(&event, (void *)(uintptr_t) irq, 0, + irq, geode_mask_irq, geode_unmask_irq, + NULL, NULL, "geode_int%d:", irq); + if (error) + return 0; + sc->intr_events[irq] =3D event; + geode_unmask_irq((void*)(uintptr_t) irq); + } + + intr_event_add_handler(event, device_get_nameunit(self), + filt, handler, arg, intr_priority(flags), + flags, cookiep); + + return 0; +} + +static int +geode_setup_intr(device_t bus, device_t dev, struct resource *res, + int flags, driver_filter_t *filt, driver_intr_t *handler,=20 + void *arg, void **cookiep) +{ + return geode_setup_intr_real(bus, rman_get_start (res),=20 + flags, filt, handler, arg, cookiep); + +} + +static int +geode_teardown_intr_real(device_t bus, int irq, void *cookie) +{ + struct geode_softc *sc; + struct intr_event *event; + + sc =3D device_get_softc(bus); + + if (irq < 0 || irq >=3D GEODE_NUM_INTS) + return (ENXIO); + + event =3D sc->intr_events[irq]; + + intr_event_remove_handler(cookie); + + if (TAILQ_EMPTY(&event->ie_handlers)) + geode_mask_irq((void*)(uintptr_t)irq); + return 0; +} + +static int +geode_teardown_intr(device_t bus, device_t child, struct resource *res, + void *cookie) +{ + int irq =3D rman_get_start (res); + return geode_teardown_intr_real(bus, irq, cookie); +} + + +#define GEODE_CASCASE_IRQ 2 + +static void +geode_init_pic (device_t self) +{ + GEODE_INTR_C1R1 =3D 0xff; + GEODE_INTR_C2R1 =3D 0xff; + + GEODE_INTR_C1R0 =3D 0x11; + GEODE_INTR_C1R1 =3D 0 << 3; + GEODE_INTR_C1R1 =3D 1 << GEODE_CASCASE_IRQ; + GEODE_INTR_C1R1 =3D 0x01; + + GEODE_INTR_C2R0 =3D 0x11; + GEODE_INTR_C1R1 =3D 8 << 3; + GEODE_INTR_C1R1 =3D GEODE_CASCASE_IRQ; + GEODE_INTR_C1R1 =3D 0x01; + + DELAY (200); + + GEODE_INTR_C1R1 =3D 0xff; + GEODE_INTR_C2R1 =3D 0xff; + + intmask =3D 0xffff; + + geode_unmask_irq((void *) GEODE_CASCASE_IRQ); +} + +static int +geode_pci_attach(device_t self) +{ + geode_softc_t *sc =3D device_get_softc(self); + int rid; + int err; + uint32_t ohcibase; + uint32_t ehcibase; + int error; + + sc->sc_irq.rm_type =3D RMAN_ARRAY; + sc->sc_irq.rm_descr =3D "Geode IRQs"; + error =3D rman_init(&sc->sc_irq); + if (error !=3D 0) + return (error); + + error =3D rman_manage_region(&sc->sc_irq, 0, GEODE_NUM_INTS - 1); + if (error !=3D 0) + return (error); +=20 + sc->mask =3D 0; + memset (sc->intr_events, 0, sizeof (sc->intr_events)); + + cpu_establish_hardintr("Geode interrupt", NULL, geode_intr, sc, + 0, INTR_TYPE_MISC, &sc->geode_intr_cookie); + + geode_init_pic (self); + + geode_write_msr (self, 0x80000020, (USB_INTERRUPT << 8) | (10)); + + device_add_child(self, "atkbdc", 0); + bus_generic_probe(self); + bus_generic_attach(self); + + /* initialise some bus fields */ + sc->ohci.sc_bus.parent =3D self; + sc->ohci.sc_bus.devices =3D sc->ohci.sc_devices; + sc->ohci.sc_bus.devices_max =3D OHCI_MAX_DEVICES; + sc->ehci.sc_bus.parent =3D self; + sc->ehci.sc_bus.devices =3D sc->ehci.sc_devices; + sc->ehci.sc_bus.devices_max =3D EHCI_MAX_DEVICES; + + /* get all DMA memory */ + if (usb_bus_mem_alloc_all(&sc->ohci.sc_bus, USB_GET_DMA_TAG(self), + &ohci_iterate_hw_softc)) { + return (ENOMEM); + } + sc->ohci.sc_dev =3D self; + + /* get all DMA memory */ + if (usb_bus_mem_alloc_all(&sc->ehci.sc_bus, + USB_GET_DMA_TAG(self), &ehci_iterate_hw_softc)) { + return (ENOMEM); + } + + pci_enable_busmaster(self); + + rid =3D PCI_CBMEM; + /* Geode doesn't use normal BARs. */ + ohcibase =3D geode_read_msr (self, CS5536_MSR_USB_OHCI_BASE) + & CS5536_MSR_USB_BASE_ADDR_MASK; + sc->ohci.sc_io_res =3D=20 + bus_alloc_resource(device_get_parent(self), + SYS_RES_MEMORY, &rid,=20 + ohcibase, ohcibase,=20 + 256, RF_ACTIVE); + + if (!sc->ohci.sc_io_res) { + device_printf(self, "Could not allocate memory\n"); + goto error; + } + + if ((rman_get_start (sc->ohci.sc_io_res) & 0xff) !=3D 0) + { + device_printf(self, "Unaligned chunk\n"); + goto error; + } + + geode_write_msr (self, CS5536_MSR_USB_OHCI_BASE,=20 + CS5536_MSR_USB_BASE_BUS_MASTER + | CS5536_MSR_USB_BASE_MEMORY_ENABLE + | (rman_get_start (sc->ohci.sc_io_res) + & CS5536_MSR_USB_BASE_ADDR_MASK)); + + sc->ohci.sc_io_tag =3D rman_get_bustag(sc->ohci.sc_io_res); + sc->ohci.sc_io_hdl =3D rman_get_bushandle(sc->ohci.sc_io_res); + sc->ohci.sc_io_size =3D rman_get_size(sc->ohci.sc_io_res); + + /* Geode doesn't use normal BARs. */ + ehcibase =3D geode_read_msr (self, CS5536_MSR_USB_EHCI_BASE) + & CS5536_MSR_USB_BASE_ADDR_MASK; + rid =3D PCI_CBMEM; + sc->ehci.sc_io_res =3D=20 + bus_alloc_resource(device_get_parent(self), + SYS_RES_MEMORY, &rid,=20 + ehcibase, ehcibase,=20 + 256, RF_ACTIVE); + + if (!sc->ehci.sc_io_res) { + device_printf(self, "Could not allocate memory\n"); + goto error; + } + + if ((rman_get_start (sc->ehci.sc_io_res) & 0xff) !=3D 0) + { + device_printf(self, "Unaligned chunk\n"); + goto error; + } + + geode_write_msr (self, CS5536_MSR_USB_EHCI_BASE,=20 + CS5536_MSR_USB_BASE_BUS_MASTER + | CS5536_MSR_USB_BASE_MEMORY_ENABLE + | (rman_get_start (sc->ehci.sc_io_res) + & CS5536_MSR_USB_BASE_ADDR_MASK) + | (0x20ULL << CS5536_MSR_USB_EHCI_BASE_FLDJ_SHIFT)); + + sc->ehci.sc_io_tag =3D rman_get_bustag(sc->ehci.sc_io_res); + sc->ehci.sc_io_hdl =3D rman_get_bushandle(sc->ehci.sc_io_res); + sc->ehci.sc_io_size =3D rman_get_size(sc->ehci.sc_io_res); + + rid =3D 0; + + sc->ehci.sc_io_res =3D sc->ohci.sc_io_res =3D rman_reserve_resource(&sc= ->sc_irq, USB_INTERRUPT, USB_INTERRUPT, 1, 0, self); + err =3D geode_setup_intr_real(self, USB_INTERRUPT, INTR_TYPE_BIO | INTR= _MPSAFE, + NULL, (driver_intr_t *)ohci_interrupt, &sc->ohci, + &sc->ohci.sc_intr_hdl); + if (err) { + device_printf(self, "Could not setup irq, %d\n", err); + sc->ohci.sc_intr_hdl =3D NULL; + goto error; + } + + err =3D geode_setup_intr_real(self, USB_INTERRUPT, INTR_TYPE_BIO | INTR= _MPSAFE, + NULL, (driver_intr_t *)ehci_interrupt, &sc->ehci, + &sc->ehci.sc_intr_hdl); + if (err) { + device_printf(self, "Could not setup irq, %d\n", err); + sc->ehci.sc_intr_hdl =3D NULL; + goto error; + } + + sc->ohci.sc_bus.bdev =3D device_add_child(self, "usbus", -1); + if (!sc->ohci.sc_bus.bdev) { + device_printf(self, "Could not add USB device\n"); + goto error; + } + device_set_ivars(sc->ohci.sc_bus.bdev, &sc->ohci.sc_bus); + + sc->ehci.sc_bus.bdev =3D device_add_child(self, "usbus", -1); + if (!sc->ehci.sc_bus.bdev) { + device_printf(self, "Could not add USB device\n"); + goto error; + } + device_set_ivars(sc->ehci.sc_bus.bdev, &sc->ehci.sc_bus); + + + /* + * ohci_pci_match will never return NULL if ohci_pci_probe + * succeeded + */ + device_set_desc(sc->ohci.sc_bus.bdev, "Geode PCI companion controller")= ; + device_set_desc(sc->ehci.sc_bus.bdev, "Geode PCI companion controller")= ; + + err =3D ohci_init(&sc->ohci); + if (!err) { + err =3D device_probe_and_attach(sc->ohci.sc_bus.bdev); + } + if (err) { + device_printf(self, "USB init failed (%d)\n", err); + goto error; + } + + err =3D ehci_init(&sc->ehci); + if (!err) { + err =3D device_probe_and_attach(sc->ehci.sc_bus.bdev); + } + if (err) { + device_printf(self, "USB init failed err=3D%d\n", err); + goto error; + } + + geode_intr (sc); + + return (0); + +error: + geode_pci_detach(self); + return (ENXIO); +} + +static int +geode_pci_detach(device_t self) +{ + geode_softc_t *sc =3D device_get_softc(self); + + if (sc->ohci.sc_bus.bdev) { + device_detach(sc->ohci.sc_bus.bdev); + device_delete_child(self, sc->ohci.sc_bus.bdev); + } + if (sc->ehci.sc_bus.bdev) { + device_detach(sc->ehci.sc_bus.bdev); + device_delete_child(self, sc->ehci.sc_bus.bdev); + } + /* during module unload there are lots of children leftover */ + device_delete_all_children(self); + + pci_disable_busmaster(self); + + if (sc->ohci.sc_io_res) + rman_release_resource(sc->ohci.sc_io_res); + + if (sc->ohci.sc_intr_hdl) { + /* + * only call ohci_detach() after ohci_init() + */ + ohci_detach(&sc->ohci); + + int err =3D geode_teardown_intr_real(self, 11, + sc->ohci.sc_intr_hdl); + + if (err) { + /* XXX or should we panic? */ + device_printf(self, "Could not tear down irq, %d\n", + err); + } + sc->ohci.sc_intr_hdl =3D NULL; + } + if (sc->ehci.sc_intr_hdl) { + /* + * only call ohci_detach() after ohci_init() + */ + ehci_detach(&sc->ehci); + + int err =3D geode_teardown_intr_real(self, 11, + sc->ehci.sc_intr_hdl); + + if (err) { + /* XXX or should we panic? */ + device_printf(self, "Could not tear down irq, %d\n", + err); + } + sc->ehci.sc_intr_hdl =3D NULL; + } + usb_bus_mem_free_all(&sc->ohci.sc_bus, &ohci_iterate_hw_softc); + usb_bus_mem_free_all(&sc->ehci.sc_bus, &ehci_iterate_hw_softc); + + return (0); +} + +static int +geode_pci_shutdown(device_t self) +{ + geode_softc_t *sc =3D device_get_softc(self); + int err; + + err =3D bus_generic_shutdown(self); + if (err) + return (err); + ehci_shutdown(&sc->ehci); + + return (0); +} + +static struct resource * +geode_alloc_resource(device_t bus, device_t child, int type, int *rid, + u_long start, u_long end, u_long count, u_int flags) +{ + struct geode_softc *sc; + struct resource *res; + int error; + + sc =3D device_get_softc(bus); + + if (type !=3D SYS_RES_IRQ) + return bus_generic_alloc_resource (bus, child, type, rid, + start, end, count, flags); + + res =3D rman_reserve_resource(&sc->sc_irq, start, end, count, flags, ch= ild); + if (res =3D=3D NULL) + return (NULL); + + rman_set_rid(res, *rid); + + if ((flags & RF_ACTIVE) !=3D 0) { + error =3D bus_activate_resource(child, type, *rid, res); + if (error !=3D 0) { + rman_release_resource(res); + return (NULL); + } + } + + return (res); +} + +static int +geode_activate_resource(device_t bus, device_t child, int type, int rid,= + struct resource *res) +{ + if (type !=3D SYS_RES_IRQ) + return bus_generic_activate_resource(bus, child, type, rid, res); + + return rman_activate_resource(res); +} + +static int +geode_release_resource(device_t dev, device_t child, int type, int rid, + struct resource *r) +{ + if (type !=3D SYS_RES_IRQ) + bus_generic_release_resource(dev, child, type, rid, r); + return rman_release_resource(r); +} + + +static driver_t geode_driver =3D +{ + .name =3D "geode", + .methods =3D (device_method_t[]){ + /* device interface */ + DEVMETHOD(device_probe, geode_pci_probe), + DEVMETHOD(device_attach, geode_pci_attach), + DEVMETHOD(device_detach, geode_pci_detach), + DEVMETHOD(device_suspend, geode_pci_suspend), + DEVMETHOD(device_resume, geode_pci_resume), + DEVMETHOD(device_shutdown, geode_pci_shutdown), + + /* bus interface */ + DEVMETHOD(bus_print_child, bus_generic_print_child), + DEVMETHOD(bus_setup_intr, geode_setup_intr), + DEVMETHOD(bus_teardown_intr, geode_teardown_intr), + DEVMETHOD(bus_activate_resource, geode_activate_resource), + DEVMETHOD(bus_alloc_resource, geode_alloc_resource), + DEVMETHOD(bus_release_resource, geode_release_resource), + + {0, 0} + }, + .size =3D sizeof(struct geode_softc), +}; + +static devclass_t geode_devclass; + +DRIVER_MODULE(geode, pci, geode_driver, geode_devclass, 0, 0); +MODULE_DEPEND(geode, ohci, 1, 1, 1); +MODULE_DEPEND(geode, ehci, 1, 1, 1); =3D=3D=3D modified file 'dev/fb/fb.c' --- dev/fb/fb.c 2010-08-13 22:16:49 +0000 +++ dev/fb/fb.c 2010-08-14 21:18:26 +0000 @@ -608,6 +608,7 @@ { FBTYPE_VGA, KD_VGA }, { FBTYPE_PC98, KD_PC98 }, { FBTYPE_TGA, KD_TGA }, + { FBTYPE_MBFB, KD_MULTIBOOT }, }; int i; =20 =3D=3D=3D added file 'dev/fb/mbfb.h' --- dev/fb/mbfb.h 1970-01-01 00:00:00 +0000 +++ dev/fb/mbfb.h 2010-08-14 21:18:26 +0000 @@ -0,0 +1,17 @@ +#include +#include "opt_fb.h" +#include "fbreg.h" + +extern int fb_found; + +struct mbvid_params +{ + int width; + int height; + void *ptr; +}; +extern struct mbvid_params mbvid_params; + +int attach_mbvid (void); + +#define MBVID_NAME "mbvid" =3D=3D=3D added file 'dev/fb/mbvideo.c' --- dev/fb/mbvideo.c 1970-01-01 00:00:00 +0000 +++ dev/fb/mbvideo.c 2010-08-15 02:57:44 +0000 @@ -0,0 +1,637 @@ +/*- + * Copyright (c) 1999 Kazutaka YOKOTA + * Copyright (c) 1992-1998 S=F8ren Schmidt + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer as + * the first lines of this file unmodified. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in th= e + * documentation and/or other materials provided with the distributio= n. + * 3. The name of the author may not be used to endorse or promote produ= cts + * derived from this software without specific prior written permissi= on. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR= + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRAN= TIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIME= D. + * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, = BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF = USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY= + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE= OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +__FBSDID("$FreeBSD$"); + +#include "opt_fb.h" +#ifndef FB_DEBUG +#define FB_DEBUG 0 +#endif +#include "opt_syscons.h" /* should be removed in the future, XXX */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "mbfb.h" +#include "fbreg.h" +#include "boot_font.c" +#include +#include +#include +#include + +static genfb_softc_t gensc; + +static uint16_t window[10000]; + +/* color mappings, from dev/fb/creator.c */ +static const uint16_t cmap[] =3D { + 0x0000, + 0x001f, + 0x07e0, + 0x0618, + 0xf800, + 0xc018, + 0xc600, + 0xc618, + 0x8410, + 0x841f, + 0x87f0, + 0x87ff, + 0xfc10, + 0xfc1f, + 0xfff0, + 0xffff, +}; + +static video_adapter_t mbvidadapter =3D +{ + .va_index =3D 0, + .va_type =3D KD_MULTIBOOT, + .va_name =3D MBVID_NAME, + .va_unit =3D 0, + .va_minor =3D 0, + .va_flags =3D V_ADP_COLOR, + .va_io_base =3D 0, + .va_io_size =3D 0, + .va_crtc_addr =3D 0, + .va_window =3D (uintptr_t) &window, + .va_window_size =3D sizeof (window), + .va_window_gran =3D 0, + .va_window_orig =3D 0, + .va_buffer =3D 0, + .va_buffer_size =3D 0, + .va_initial_mode =3D 0, + .va_initial_bios_mode =3D 0, + .va_mode =3D 0, + .va_info =3D { + .vi_mode =3D 0, + .vi_flags =3D V_INFO_COLOR | V_INFO_LINEAR, + .vi_cwidth =3D 8, + .vi_cheight =3D 16, + .vi_planes =3D 1, + .vi_window_gran =3D 0, + .vi_buffer =3D 0, + .vi_buffer_size =3D 0, + .vi_mem_model =3D V_INFO_MM_DIRECT, + .vi_registers =3D 0, + .vi_registers_size =3D 0, + }, + .va_disp_start =3D { + .x =3D 0, + .y =3D 0, + }, + .va_token =3D 0, + .va_model =3D 0, + .va_little_bitian =3D 0, + .va_little_endian =3D 1, + .va_buffer_alias =3D 0, + .va_registers =3D 0, + .va_registers_size =3D 0, +}; + + +#if 0 +int +mbvid_probe_unit(int unit, video_adapter_t *buf, int flags) +{ + if (!fb_found) + return ENXIO; + return 0; +} + +int +mbvid_attach_unit(int unit, mbvid_softc_t *sc, int flags) +{ + if (!fb_found) + return ENXIO; + return 0; +} +#endif + +/* cdev driver functions */ + +static int +mbvid_open(struct cdev *dev, int flag, int mode, struct thread *td) +{ + if (dev =3D=3D NULL) + return ENXIO; + if (mode & (O_CREAT | O_APPEND | O_TRUNC)) + return ENODEV; + + return genfbopen(&gensc, &mbvidadapter, flag, mode, td); +} + +static int +mbvid_close(struct cdev *dev, int flag, int mode, struct thread *td) +{ + return genfbclose(&gensc, &mbvidadapter, flag, mode, td); +} + +static int +mbvid_read(struct cdev *dev, struct uio *uio, int flag) +{ + return genfbread(&gensc, &mbvidadapter, uio, flag); +} + +static int +mbvid_write(struct cdev *dev, struct uio *uio, int flag) +{ + return genfbread(&gensc, &mbvidadapter, uio, flag); +} + +static int +mbvid_ioctl(struct cdev *dev, u_long cmd, caddr_t arg, int flag, + struct thread *td) +{ + return genfbioctl(&gensc, &mbvidadapter, cmd, arg, flag, td); +} + +static int +mbvid_mmap(struct cdev *dev, vm_ooffset_t offset, + vm_offset_t *paddr, int prot, vm_memattr_t *memattr) +{ + return (EINVAL); +} + +static struct cdevsw mbvid_cdevsw =3D { + .d_version =3D D_VERSION, + .d_flags =3D 0, + .d_open =3D mbvid_open, + .d_close =3D mbvid_close, + .d_read =3D mbvid_read, + .d_write =3D mbvid_write, + .d_ioctl =3D mbvid_ioctl, + .d_mmap =3D mbvid_mmap, + .d_name =3D "multiboot video console", +}; + +int +attach_mbvid (void) +{ + int error; + int idx; +=09 + mbvidadapter.va_info.vi_mode =3D M_TEXT_80x25; + mbvidadapter.va_info.vi_cwidth =3D bold8x16.width; + mbvidadapter.va_info.vi_cheight =3D bold8x16.height; + mbvidadapter.va_info.vi_height =3D (mbvid_params.height / mbvidadapter.= va_info.vi_cheight); + mbvidadapter.va_info.vi_width =3D (mbvid_params.width / mbvidadapter.va= _info.vi_cwidth); + mbvidadapter.va_info.vi_flags =3D V_INFO_COLOR | V_INFO_LINEAR; + mbvidadapter.va_info.vi_mem_model =3D V_INFO_MM_DIRECT; + + mbvidadapter.va_flags |=3D V_ADP_COLOR; + + idx =3D vid_register (&mbvidadapter); + if (idx < 0) + { + return ENXIO; + } + mbvidadapter.va_flags |=3D V_ADP_REGISTERED; + + /* attach a virtual frame buffer device */ + error =3D fb_attach(idx, &mbvidadapter, &mbvid_cdevsw); + if (error) + { + return (error); + } + return 0; +} + +/* video driver declarations */ +static int mbvid_configure(int flags); + int (*mbvid_sub_configure)(int flags); +static int mbvid_error(void); +static vi_probe_t mbvid_probe; +static vi_init_t mbvid_init; +static vi_get_info_t mbvid_get_info; +static vi_query_mode_t mbvid_query_mode; +static vi_mmap_t mbvid_mmap_buf; +static vi_ioctl_t mbvid_dev_ioctl; +static vi_diag_t mbvid_diag; +static vi_putc_t mbvid_putc; +static vi_putp_t mbvid_putp; +static vi_puts_t mbvid_puts; +static vi_putm_t mbvid_putm; + +static video_switch_t mbvidvidsw =3D { + mbvid_probe, + mbvid_init, + mbvid_get_info, + mbvid_query_mode,=09 + (vi_set_mode_t *) mbvid_error, + (vi_save_font_t *) mbvid_error, + (vi_load_font_t *) mbvid_error, + (vi_show_font_t *) mbvid_error, + (vi_save_palette_t *) mbvid_error, + (vi_load_palette_t *) mbvid_error, + (vi_set_border_t *) mbvid_error, + (vi_save_state_t *) mbvid_error, + (vi_load_state_t *) mbvid_error, + (vi_set_win_org_t *) mbvid_error, + (vi_read_hw_cursor_t *)mbvid_error, + (vi_set_hw_cursor_t *) mbvid_error, + (vi_set_hw_cursor_shape_t *) mbvid_error, + (vi_blank_display_t *) mbvid_error, + mbvid_mmap_buf, + mbvid_dev_ioctl, + (vi_clear_t *) mbvid_error, + (vi_fill_rect_t *) mbvid_error, + (vi_bitblt_t *) mbvid_error, + mbvid_error, + mbvid_error, + mbvid_diag, + .putp =3D mbvid_putp, + .putc =3D mbvid_putc, + .puts =3D mbvid_puts, + .putm =3D mbvid_putm +}; + + +VIDEO_DRIVER(mbvid, mbvidvidsw, mbvid_configure); + +/* a backdoor for the console driver */ +static int +mbvid_configure(int flags) +{ + return fb_found; +} + +/* entry points */ + +static int +mbvid_error(void) +{ + return ENODEV; +} + +static int +mbvid_probe(int unit, video_adapter_t **adpp, void *arg, int flags) +{ + if (unit >=3D fb_found) + return ENXIO; + + mbvidadapter.va_flags |=3D V_ADP_PROBED; + + *adpp =3D &mbvidadapter; + + return 0; +} + +static int +mbvid_init(int unit, video_adapter_t *adp, int flags) +{ + if (unit >=3D fb_found) + return ENXIO; + + mbvidadapter.va_flags |=3D V_ADP_INITIALIZED; + + return 0; +} + +/* + * get_info(): + * Return the video_info structure of the requested video mode. + * + * all adapters + */ +static int +mbvid_get_info(video_adapter_t *adp, int mode, video_info_t *info) +{ + if (mode !=3D 0) + return EINVAL; + *info =3D adp->va_info; + return 0; +} + +/* + * query_mode(): + * Find a video mode matching the requested parameters. + * Fields filled with 0 are considered "don't care" fields and + * match any modes. + * + * all adapters + */ +static int +mbvid_query_mode(video_adapter_t *adp, video_info_t *info) +{ + if ((info->vi_width !=3D 0) + && (info->vi_width !=3D adp->va_info.vi_width)) + return ENODEV; + + if ((info->vi_height !=3D 0) + && (info->vi_height !=3D adp->va_info.vi_height)) + return ENODEV; + + if ((info->vi_cwidth !=3D 0) + && (info->vi_cwidth !=3D adp->va_info.vi_cwidth)) + return ENODEV; + + if ((info->vi_cheight !=3D 0) + && (info->vi_cheight !=3D adp->va_info.vi_cheight)) + return ENODEV; + + if ((info->vi_depth !=3D 0) + && (info->vi_depth !=3D adp->va_info.vi_depth)) + return ENODEV; + + if ((info->vi_planes !=3D 0) + && (info->vi_planes !=3D adp->va_info.vi_planes)) + return ENODEV; + + /* XXX: should check pixel format, memory model */ + if ((info->vi_flags !=3D 0) + && (info->vi_flags !=3D adp->va_info.vi_flags)) + return ENODEV; + return 0; +} + +#if 0 +/* + * mmap(): + * Mmap frame buffer. + * + * all adapters + */ +static int +mbvid_mmap_buf(video_adapter_t *adp, vm_ooffset_t offset, vm_paddr_t *pa= ddr, + int prot, vm_memattr_t *memattr) +{ + printf("mbvid_mmap_buf(): window:0x%jx, offset:0x%jx\n",=20 + (uintmax_t)adp->va_info.vi_window, (uintmax_t)offset); + + /* XXX: is this correct? */ + if (offset > adp->va_window_size - PAGE_SIZE) + return -1; + + *paddr =3D adp->va_info.vi_window + offset; + return 0; +} +#else +static int +mbvid_mmap_buf(video_adapter_t *adp, vm_ooffset_t offset, vm_paddr_t *pa= ddr, + int prot, vm_memattr_t *memattr) +{ + return (EINVAL); +} +#endif + +static int +mbvid_dev_ioctl(video_adapter_t *adp, u_long cmd, caddr_t arg) +{ + switch (cmd) { + case FBIO_GETWINORG: /* get frame buffer window origin */ + *(u_int *)arg =3D 0; + return 0; + + case FBIO_SETWINORG: /* set frame buffer window origin */ + case FBIO_SETLINEWIDTH: /* set scan line length in pixel */ + case FBIO_SETDISPSTART: /* set display start address */ + case FBIO_GETPALETTE: /* get color palette */ + case FBIO_SETPALETTE: /* set color palette */ + case FBIOGETCMAP: /* get color palette */ + case FBIOPUTCMAP: /* set color palette */ + + return ENODEV; + case FBIOGTYPE: /* get frame buffer type info. */ + ((struct fbtype *)arg)->fb_type =3D fb_type(adp->va_type); + ((struct fbtype *)arg)->fb_height =3D adp->va_info.vi_height; + ((struct fbtype *)arg)->fb_width =3D adp->va_info.vi_width; + ((struct fbtype *)arg)->fb_depth =3D adp->va_info.vi_depth; + if ((adp->va_info.vi_depth <=3D 1) || (adp->va_info.vi_depth > 8)) + ((struct fbtype *)arg)->fb_cmsize =3D 0; + else + ((struct fbtype *)arg)->fb_cmsize =3D 1 << adp->va_info.vi_depth; + ((struct fbtype *)arg)->fb_size =3D adp->va_buffer_size; + return 0; + + default: + return fb_commonioctl(adp, cmd, arg); + } +} + +static int +mbvid_putp(video_adapter_t *adp, vm_offset_t off, u_int32_t p, u_int32_t= a, + int size, int bpp, int bit_ltor, int byte_ltor) +{ + return (ENODEV); +} + +static int +mbvid_putc(video_adapter_t *adp, vm_offset_t off, u_int8_t c, u_int8_t a= ) +{ + int row, col; + int i, j; + const uint8_t* fontdata; + uint16_t clr; + uint8_t mask; + uint16_t* ptri; + + ptri =3D mbvid_params.ptr; + + /* calculate the position in the frame buffer */ + row =3D (off / mbvidadapter.va_info.vi_width) * mbvidadapter.va_info.vi= _cheight; + col =3D (off % mbvidadapter.va_info.vi_width) * mbvidadapter.va_info.vi= _cwidth; + fontdata =3D &bold8x16.data[c * mbvidadapter.va_info.vi_cheight]; + ptri +=3D (row * mbvid_params.width) + col; + + /* Place the character on the screen, pixel by pixel */ + for (j =3D 0; j < mbvidadapter.va_info.vi_cheight; j++) { + mask =3D 0x80; + for (i =3D 0; i < mbvidadapter.va_info.vi_cwidth; i++) { + clr =3D (*fontdata & mask) ? cmap[a & 0xf] : cmap[(a >> 4) & 0xf]; + *ptri++ =3D clr; + mask >>=3D 1; + } + ptri +=3D (mbvid_params.width - mbvidadapter.va_info.vi_cwidth); + fontdata++; + } + return (0); +} + +static int +mbvid_puts(video_adapter_t *adp, vm_offset_t off, u_int16_t *s, int len)= +{ + int i; + + for (i =3D 0; i < len; i++) { + vidd_putc(adp, off + i, s[i] & 0xff, (s[i] & 0xff00) >> 8); + } + return (0); +} + +static int +mbvid_putm(video_adapter_t *adp, int x, int y, u_int8_t *pixel_image, + u_int32_t pixel_mask, int size, int width) +{ +#if 0 + struct xboxfb_softc* sc =3D &xboxfb_sc; + uint32_t* ptri =3D (uint32_t*)sc->sc_framebuffer; + int i, j;=09 + + if (x < 0 || y < 0 || x + width > sc->sc_width || y + (2 * size) > sc->= sc_height) + return 0; + + ptri +=3D (y * sc->sc_width) + x; + + /* plot the mousecursor wherever the user wants it */ + for (j =3D 0; j < size; j++) { + for (i =3D width; i > 0; i--) { + if (pixel_image[j] & (1 << i)) + *ptri =3D cmap[0xf]; + ptri++; + } + ptri +=3D (sc->sc_width - width); + } + return (0); +#else + return ENODEV; +#endif +} + + +/* + * diag(): + * Print some information about the video adapter and video modes, + * with requested level of details. + * + * all adapters + */ +static int +mbvid_diag(video_adapter_t *adp, int level) +{ + if (!fb_found) + return ENXIO; + return 0; +} + +static void +xbr_init(scr_stat* scp) +{ +} + +static void +xbr_clear(scr_stat* scp, int c, int attr) +{ +} + +static void +xbr_draw_border(scr_stat* scp, int color) +{ +} + +static void +xbr_draw(scr_stat* scp, int from, int count, int flip) +{ + int i, c, a; + + if (!flip) { + /* Normal printing */ + vidd_puts(&mbvidadapter, from, (uint16_t*)sc_vtb_pointer(&scp->vtb, fr= om), count); + } else {=09 + /* This is for selections and such: invert the color attribute */ + for (i =3D count; i-- > 0; ++from) { + c =3D sc_vtb_getc(&scp->vtb, from); + a =3D sc_vtb_geta(&scp->vtb, from) >> 8; + vidd_putc(&mbvidadapter, from, c, (a >> 4) | ((a & 0xf) << 4)); + } + } +} + +static void +xbr_set_cursor(scr_stat* scp, int base, int height, int blink) +{ +} + +static void +xbr_draw_cursor(scr_stat* scp, int at, int blink, int on, int flip) +{ + uint16_t* ptri; + int row, col, i, j; + + if (scp->curs_attr.height <=3D 0) + return; + + ptri =3D mbvid_params.ptr; + + /* calculate the coordinates in the video buffer */ + row =3D (at / mbvidadapter.va_info.vi_width) * mbvidadapter.va_info.vi_= cheight; + col =3D (at % mbvidadapter.va_info.vi_width) * mbvidadapter.va_info.vi_= cwidth; + ptri +=3D (row * mbvid_params.width) + col; + + /* our cursor consists of simply inverting the char under it */ + for (i =3D 0; i < mbvidadapter.va_info.vi_cheight; i++) { + for (j =3D 0; j < mbvidadapter.va_info.vi_cwidth; j++) { + *ptri++ ^=3D 0xFFFF; + } + ptri +=3D (mbvid_params.width - mbvidadapter.va_info.vi_cwidth); + } +} + +static void +xbr_blink_cursor(scr_stat* scp, int at, int flip) +{ +} + +static void +xbr_set_mouse(scr_stat* scp) +{ +} + +static void +xbr_draw_mouse(scr_stat* scp, int x, int y, int on) +{ +#if 0 + vidd_putm(scp->sc->adp, x, y, mouse_pointer, 0xffffffff, 16, 8); +#endif +} + +static sc_rndr_sw_t mbvidrend =3D { + xbr_init, + xbr_clear, + xbr_draw_border, + xbr_draw, + xbr_set_cursor, + xbr_draw_cursor, + xbr_blink_cursor, + xbr_set_mouse, + xbr_draw_mouse +}; +RENDERER(mbvid, 0, mbvidrend, gfb_set); =3D=3D=3D modified file 'dev/syscons/schistory.c' --- dev/syscons/schistory.c 2010-08-13 22:16:49 +0000 +++ dev/syscons/schistory.c 2010-08-14 21:18:26 +0000 @@ -42,7 +42,7 @@ #include #include =20 -#if defined(__sparc64__) || defined(__powerpc__) +#if defined(__sparc64__) || defined(__powerpc__) || defined (__mips) #include #else #include =3D=3D=3D modified file 'dev/syscons/scterm-teken.c' --- dev/syscons/scterm-teken.c 2010-08-13 22:16:49 +0000 +++ dev/syscons/scterm-teken.c 2010-08-14 22:59:01 +0000 @@ -40,7 +40,7 @@ #include #include =20 -#if defined(__sparc64__) || defined(__powerpc__) +#if defined(__sparc64__) || defined(__powerpc__) || defined(__mips) #include #else #include @@ -140,7 +140,8 @@ tp.tp_col =3D scp->xsize; teken_set_winsize(&ts->ts_teken, &tp); =20 - if (scp->cursor_pos < scp->ysize * scp->xsize) { + if (scp->cursor_pos < scp->ysize * scp->xsize + && scp->cursor_pos >=3D 0) { /* Valid old cursor position. */ tp.tp_row =3D scp->cursor_pos / scp->xsize; tp.tp_col =3D scp->cursor_pos % scp->xsize; =3D=3D=3D modified file 'dev/syscons/syscons.c' --- dev/syscons/syscons.c 2010-08-13 22:16:49 +0000 +++ dev/syscons/syscons.c 2010-08-14 21:18:26 +0000 @@ -62,7 +62,7 @@ #include =20 #include -#if defined(__sparc64__) || defined(__powerpc__) +#if defined(__sparc64__) || defined(__powerpc__) || defined (__mips) #include #else #include =3D=3D=3D modified file 'dev/usb/controller/usb_controller.c' --- dev/usb/controller/usb_controller.c 2010-08-13 22:16:49 +0000 +++ dev/usb/controller/usb_controller.c 2010-08-15 21:43:50 +0000 @@ -104,6 +104,7 @@ }; =20 DRIVER_MODULE(usbus, ohci, usb_driver, usb_devclass, 0, 0); +DRIVER_MODULE(usbus, geode, usb_driver, usb_devclass, 0, 0); DRIVER_MODULE(usbus, uhci, usb_driver, usb_devclass, 0, 0); DRIVER_MODULE(usbus, ehci, usb_driver, usb_devclass, 0, 0); DRIVER_MODULE(usbus, at91_udp, usb_driver, usb_devclass, 0, 0); =3D=3D=3D modified file 'isa/rtc.h' --- isa/rtc.h 2010-08-13 22:16:49 +0000 +++ isa/rtc.h 2010-08-15 03:56:28 +0000 @@ -72,7 +72,7 @@ #define RTC_STATUSB 0x0b /* status register B */ #define RTCSB_DST 0x01 /* USA Daylight Savings Time enable */ #define RTCSB_24HR 0x02 /* 0 =3D 12 hours, 1 =3D 24 hours */ -#define RTCSB_BCD 0x04 /* 0 =3D BCD, 1 =3D Binary coded time */ +#define RTCSB_BINARY 0x04 /* 0 =3D BCD, 1 =3D Binary coded time */ #define RTCSB_SQWE 0x08 /* 1 =3D output sqare wave at SQW pin */ #define RTCSB_UINTR 0x10 /* 1 =3D enable update-ended interrupt */ #define RTCSB_AINTR 0x20 /* 1 =3D enable alarm interrupt */ =3D=3D=3D added file 'mips/conf/YEELOONG' --- mips/conf/YEELOONG 1970-01-01 00:00:00 +0000 +++ mips/conf/YEELOONG 2010-08-14 21:18:26 +0000 @@ -0,0 +1,55 @@ +# QEMU -- Generic kernel configuration file for FreeBSD/mips +# +# For more information on this file, please read the handbook section on= +# Kernel Configuration Files: +# +# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelcon= fig-config.html +# +# The handbook is also available locally in /usr/share/doc/handbook +# if you've installed the doc distribution, otherwise always see the +# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# latest information. +# +# An exhaustive list of options and more detailed explanations of the +# device lines is also present in the ../../conf/NOTES and NOTES files. = +# If you are in doubt as to the purpose or necessity of a line, check fi= rst=20 +# in NOTES. +# +# $FreeBSD: src/sys/mips/conf/YEELOONG,v 1.4.2.1.2.1 2009/10/25 01:10:29= kensmith Exp $ + +# Don't build any modules yet. +makeoptions MODULES_OVERRIDE=3D"" + +include "../yeeloong/std.yeeloong" + +# hints "YEELOONG.hints" #Default places to look for devices. + +makeoptions DEBUG=3D-g #Build kernel with gdb(1) debug symbols + +options DDB +options KDB + +options SCHED_4BSD #4BSD scheduler +options INET #InterNETworking +options NFSCLIENT #Network Filesystem Client +options NFS_ROOT #NFS usable as /, requires NFSCLIENT +options PSEUDOFS #Pseudo-filesystem framework +options _KPOSIX_PRIORITY_SCHEDULING #Posix P1003_1B real-time extension= s + +# Debugging for use in -current +options INVARIANTS #Enable calls of extra sanity checking +options INVARIANT_SUPPORT #Extra sanity checks of internal structures, = required by INVARIANTS +#options WITNESS #Enable checks to detect deadlocks and cycles +#options WITNESS_SKIPSPIN #Don't run witness on spinlocks for speed +options USB_DEBUG # enable debug msgs + +device loop +device ether +device md +device uart + +options MSDOSFS # MSDOS Filesystem +options CD9660 # ISO 9660 Filesystem +options PROCFS # Process filesystem (requires PSEUDOFS) +options GEOM_PART_GPT # GUID Partition Tables. +options GEOM_LABEL # Provides labelization =3D=3D=3D modified file 'mips/include/bus.h' --- mips/include/bus.h 2010-08-13 22:16:49 +0000 +++ mips/include/bus.h 2010-08-14 21:18:26 +0000 @@ -74,6 +74,41 @@ #define _MACHINE_BUS_H_ =20 #include +#include + +static inline void +memsetw (volatile void *ptr_, uint16_t val, size_t count) +{ + volatile uint16_t *ptr =3D ptr_; + while (count--) + *ptr++ =3D val; +} + +static inline void +memsetw_io (uintptr_t ptr_, uint16_t val, size_t count) +{ + volatile uint16_t *ptr =3D (volatile uint16_t *) ptr_; + while (count--) + *ptr++ =3D val; +} + +static inline void +memcpy_io (uintptr_t to, uintptr_t from, size_t count) +{ + memcpy ((void *) to, (void *) from, count); +} + +static inline void +memcpy_toio (uintptr_t to, void *from, size_t count) +{ + memcpy ((void *) to, from, count); +} + +static inline void +memcpy_fromio (void *to, uintptr_t from, size_t count) +{ + memcpy (to, (void *) from, count); +} =20 struct bus_space { /* cookie */ =3D=3D=3D modified file 'mips/include/cache.h' --- mips/include/cache.h 2010-08-13 22:16:49 +0000 +++ mips/include/cache.h 2010-08-15 09:24:10 +0000 @@ -213,6 +213,22 @@ #define mips_intern_dcache_wb_range(v, s) \ __mco_2args(intern_, dcache_wb_range, (v), (s)) =20 +#define mips_sdcache_wbinv_all() \ + __mco_noargs(, dcache_wbinv_all) + +#define mips_sdcache_wbinv_range(v, s) \ + __mco_2args(, dcache_wbinv_range, (v), (s)) + +#define mips_sdcache_wbinv_range_index(v, s) \ + __mco_2args(, dcache_wbinv_range_index, (v), (s)) + +#define mips_sdcache_inv_range(v, s) \ + __mco_2args(, dcache_inv_range, (v), (s)) + +#define mips_sdcache_wb_range(v, s) \ + __mco_2args(, dcache_wb_range, (v), (s)) + + /* forward declaration */ struct mips_cpuinfo; =20 =3D=3D=3D modified file 'mips/include/cache_mipsNN.h' --- mips/include/cache_mipsNN.h 2010-08-13 22:16:49 +0000 +++ mips/include/cache_mipsNN.h 2010-08-15 09:24:10 +0000 @@ -57,6 +57,13 @@ void mipsNN_pdcache_inv_range_32(vm_offset_t, vm_size_t); void mipsNN_pdcache_wb_range_16(vm_offset_t, vm_size_t); void mipsNN_pdcache_wb_range_32(vm_offset_t, vm_size_t); + +void mipsNN_sdcache_wbinv_all_32(void); +void mipsNN_sdcache_wbinv_range_32(vm_offset_t, vm_size_t); +void mipsNN_sdcache_wbinv_range_index_32(vm_offset_t, vm_size_t); +void mipsNN_sdcache_inv_range_32(vm_offset_t, vm_size_t); +void mipsNN_sdcache_wb_range_32(vm_offset_t, vm_size_t); + #ifdef CPU_CNMIPS void mipsNN_icache_sync_all_128(void); void mipsNN_icache_sync_range_128(vm_offset_t, vm_size_t); =3D=3D=3D modified file 'mips/include/cpufunc.h' --- mips/include/cpufunc.h 2010-08-13 22:16:49 +0000 +++ mips/include/cpufunc.h 2010-08-14 10:37:00 +0000 @@ -142,6 +142,10 @@ #undef MIPS_RDRW64_COP0 #endif =20 +#if __mips =3D=3D 32 || __mips =3D=3D 64 +#define MIPS_HAS_CP0_SELECTORS 1 +#endif + #define MIPS_RDRW32_COP0(n,r) \ static __inline uint32_t \ mips_rd_ ## n (void) \ @@ -164,6 +168,8 @@ mips_barrier(); \ } struct __hack =20 +#ifdef MIPS_HAS_CP0_SELECTORS + #define MIPS_RDRW32_COP0_SEL(n,r,s) \ static __inline uint32_t \ mips_rd_ ## n(void) \ @@ -186,6 +192,8 @@ mips_barrier(); \ } struct __hack =20 +#endif + #ifdef CPU_CNMIPS static __inline void mips_sync_icache (void) { @@ -201,9 +209,11 @@ =20 MIPS_RDRW32_COP0(compare, MIPS_COP_0_COMPARE); MIPS_RDRW32_COP0(config, MIPS_COP_0_CONFIG); +#ifdef MIPS_HAS_CP0_SELECTORS MIPS_RDRW32_COP0_SEL(config1, MIPS_COP_0_CONFIG, 1); MIPS_RDRW32_COP0_SEL(config2, MIPS_COP_0_CONFIG, 2); MIPS_RDRW32_COP0_SEL(config3, MIPS_COP_0_CONFIG, 3); +#endif MIPS_RDRW32_COP0(count, MIPS_COP_0_COUNT); MIPS_RDRW32_COP0(index, MIPS_COP_0_TLB_INDEX); MIPS_RDRW32_COP0(wired, MIPS_COP_0_TLB_WIRED); @@ -219,12 +229,17 @@ #endif MIPS_RDRW32_COP0(prid, MIPS_COP_0_PRID); /* XXX 64-bit? */ +#ifdef MIPS_HAS_CP0_SELECTORS MIPS_RDRW32_COP0_SEL(ebase, MIPS_COP_0_PRID, 1); +#endif MIPS_RDRW32_COP0(watchlo, MIPS_COP_0_WATCH_LO); +#ifdef MIPS_HAS_CP0_SELECTORS MIPS_RDRW32_COP0_SEL(watchlo1, MIPS_COP_0_WATCH_LO, 1); MIPS_RDRW32_COP0_SEL(watchlo2, MIPS_COP_0_WATCH_LO, 2); MIPS_RDRW32_COP0_SEL(watchlo3, MIPS_COP_0_WATCH_LO, 3); +#endif MIPS_RDRW32_COP0(watchhi, MIPS_COP_0_WATCH_HI); +#ifdef MIPS_HAS_CP0_SELECTORS MIPS_RDRW32_COP0_SEL(watchhi1, MIPS_COP_0_WATCH_HI, 1); MIPS_RDRW32_COP0_SEL(watchhi2, MIPS_COP_0_WATCH_HI, 2); MIPS_RDRW32_COP0_SEL(watchhi3, MIPS_COP_0_WATCH_HI, 3); @@ -233,6 +248,7 @@ MIPS_RDRW32_COP0_SEL(perfcnt1, MIPS_COP_0_PERFCNT, 1); MIPS_RDRW32_COP0_SEL(perfcnt2, MIPS_COP_0_PERFCNT, 2); MIPS_RDRW32_COP0_SEL(perfcnt3, MIPS_COP_0_PERFCNT, 3); +#endif =20 #undef MIPS_RDRW32_COP0 =20 =3D=3D=3D modified file 'mips/include/cpuinfo.h' --- mips/include/cpuinfo.h 2010-08-13 22:16:49 +0000 +++ mips/include/cpuinfo.h 2010-08-15 09:24:10 +0000 @@ -67,6 +67,12 @@ u_int8_t dc_nways; u_int16_t dc_nsets; } l1; + struct { + u_int32_t dc_size; + u_int8_t dc_linesize; + u_int8_t dc_nways; + u_int16_t dc_nsets; + } l2; }; =20 extern struct mips_cpuinfo cpuinfo; =3D=3D=3D modified file 'mips/include/cpuregs.h' --- mips/include/cpuregs.h 2010-08-13 22:16:49 +0000 +++ mips/include/cpuregs.h 2010-08-15 11:18:29 +0000 @@ -136,6 +136,10 @@ #define MIPS_CCA_UC 0x02 /* Uncached. */ #define MIPS_CCA_C 0x03 /* Cacheable, coherency unspecified. */ =20 +#if defined (CPU_R10000) || defined (TARGET_YEELOONG) +#define MIPS_CCA_UA 0x07 +#endif + #if defined(CPU_R4000) || defined(CPU_R10000) #define MIPS_CCA_CNC 0x03 #define MIPS_CCA_CCE 0x04 @@ -145,10 +149,6 @@ #define MIPS_CCA_CCUOW 0x06 #endif =20 -#ifdef CPU_R10000 -#define MIPS_CCA_UA 0x07 -#endif - #define MIPS_CCA_CACHED MIPS_CCA_CCEW #endif /* defined(CPU_R4000) || defined(CPU_R10000) */ =20 @@ -188,8 +188,14 @@ #define MIPS_XKSEG_START 0xc000000000000000 #define MIPS_XKSEG_END 0xc00000ff80000000 =20 +#if __mips =3D=3D 32 || __mips =3D=3D 64 +#define SSNOP ssnop +#else +#define SSNOP nop +#endif +=20 /* CPU dependent mtc0 hazard hook */ -#ifdef CPU_CNMIPS +#if defined (CPU_CNMIPS) || defined (TARGET_YEELOONG) #define COP0_SYNC nop; nop; nop; nop; nop; #elif defined(CPU_SB1) #define COP0_SYNC ssnop; ssnop; ssnop; ssnop; ssnop; ssnop; ssnop; ssno= p; ssnop @@ -416,7 +422,7 @@ #define MIPS_VEC_EJTAG 0xBFC00480 #define MIPS_VEC_TLB 0x80000000 #define MIPS_VEC_XTLB 0x80000080 -#define MIPS_VEC_CACHE 0x80000100 +#define MIPS_VEC_CACHE 0xa0000100 #define MIPS_VEC_GENERIC 0x80000180 /* Most exceptions */ #define MIPS_VEC_INTERRUPT 0x80000200 =20 =3D=3D=3D added file 'mips/include/sc_machdep.h' --- mips/include/sc_machdep.h 1970-01-01 00:00:00 +0000 +++ mips/include/sc_machdep.h 2010-08-14 21:18:26 +0000 @@ -0,0 +1,30 @@ +/* Color attributes for foreground text */ + +#define FG_BLACK 0 +#define FG_BLUE 1 +#define FG_GREEN 2 +#define FG_CYAN 3 +#define FG_RED 4 +#define FG_MAGENTA 5 +#define FG_BROWN 6 +#define FG_LIGHTGREY 7 +#define FG_DARKGREY 8 +#define FG_LIGHTBLUE 9 +#define FG_LIGHTGREEN 10 +#define FG_LIGHTCYAN 11 +#define FG_LIGHTRED 12 +#define FG_LIGHTMAGENTA 13 +#define FG_YELLOW 14 +#define FG_WHITE 15 +#define FG_BLINK 0x80 + +/* Color attributes for text background */ + +#define BG_BLACK 0x00 +#define BG_BLUE 0x10 +#define BG_GREEN 0x20 +#define BG_CYAN 0x30 +#define BG_RED 0x40 +#define BG_MAGENTA 0x50 +#define BG_BROWN 0x60 +#define BG_LIGHTGREY 0x70 =3D=3D=3D modified file 'mips/mips/bus_space_generic.c' --- mips/mips/bus_space_generic.c 2010-08-13 22:16:49 +0000 +++ mips/mips/bus_space_generic.c 2010-08-15 09:24:10 +0000 @@ -593,6 +593,9 @@ { #if 0 if (flags & BUS_SPACE_BARRIER_WRITE) + { mips_dcache_wbinv_all(); + mips_sdcache_wbinv_all(); + } #endif } =3D=3D=3D modified file 'mips/mips/busdma_machdep.c' --- mips/mips/busdma_machdep.c 2010-08-13 22:16:49 +0000 +++ mips/mips/busdma_machdep.c 2010-08-15 09:24:10 +0000 @@ -638,6 +638,8 @@ newmap->allocbuffer =3D tmpaddr; mips_dcache_wbinv_range((vm_offset_t)*vaddr, dmat->maxsize); + mips_sdcache_wbinv_range((vm_offset_t)*vaddr, + dmat->maxsize); *vaddr =3D tmpaddr; } else newmap->origbuffer =3D newmap->allocbuffer =3D NULL; @@ -805,6 +807,9 @@ if (++seg >=3D dmat->nsegments) break; segs[seg].ds_addr =3D curaddr; +#ifdef TARGET_YEELOONG + segs[seg].ds_addr |=3D 0x80000000; +#endif segs[seg].ds_len =3D sgsize; } if (error) @@ -1074,6 +1079,7 @@ if (size_clend) memcpy (tmp_clend, (void*)buf_clend, size_clend); mips_dcache_inv_range((vm_offset_t)buf, len); + mips_sdcache_inv_range((vm_offset_t)buf, len); /*=20 * Restore them */ @@ -1088,15 +1094,23 @@ * necessary. */ if (size_cl) + { mips_dcache_wbinv_range((vm_offset_t)buf_cl, size_cl); + mips_sdcache_wbinv_range((vm_offset_t)buf_cl, size_cl); + } if (size_clend && (size_cl =3D=3D 0 || buf_clend - buf_cl > mips_pdcache_linesize)) + { mips_dcache_wbinv_range((vm_offset_t)buf_clend, size_clend); + mips_sdcache_wbinv_range((vm_offset_t)buf_clend, + size_clend); + } break; =20 case BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE: mips_dcache_wbinv_range((vm_offset_t)buf_cl, len); + mips_sdcache_wbinv_range((vm_offset_t)buf_cl, len); break; =20 case BUS_DMASYNC_PREREAD: @@ -1108,6 +1122,7 @@ if (size_clend) memcpy (tmp_clend, (void *)buf_clend, size_clend); mips_dcache_inv_range((vm_offset_t)buf, len); + mips_sdcache_inv_range((vm_offset_t)buf, len); /* * Restore them */ @@ -1122,15 +1137,23 @@ * necessary. */ if (size_cl) + { mips_dcache_wbinv_range((vm_offset_t)buf_cl, size_cl); + mips_sdcache_wbinv_range((vm_offset_t)buf_cl, size_cl); + } if (size_clend && (size_cl =3D=3D 0 || buf_clend - buf_cl > mips_pdcache_linesize)) + { mips_dcache_wbinv_range((vm_offset_t)buf_clend, size_clend); + mips_sdcache_wbinv_range((vm_offset_t)buf_clend, + size_clend); + } break; =20 case BUS_DMASYNC_PREWRITE: mips_dcache_wb_range((vm_offset_t)buf, len); + mips_sdcache_wb_range((vm_offset_t)buf, len); break; } } @@ -1149,6 +1172,8 @@ if (bpage->vaddr_nocache =3D=3D 0) { mips_dcache_wb_range(bpage->vaddr, bpage->datacount); + mips_sdcache_wb_range(bpage->vaddr, + bpage->datacount); } dmat->bounce_zone->total_bounced++; } @@ -1156,6 +1181,8 @@ if (bpage->vaddr_nocache =3D=3D 0) { mips_dcache_inv_range(bpage->vaddr, bpage->datacount); + mips_sdcache_inv_range(bpage->vaddr, + bpage->datacount); } bcopy((void *)(bpage->vaddr_nocache !=3D 0 ?=20 bpage->vaddr_nocache : bpage->vaddr), =3D=3D=3D modified file 'mips/mips/cache.c' --- mips/mips/cache.c 2010-08-13 22:16:49 +0000 +++ mips/mips/cache.c 2010-08-15 09:24:10 +0000 @@ -194,6 +194,28 @@ cpuinfo->l1.dc_linesize); } =20 + switch (cpuinfo->l2.dc_linesize) { + case 32: + mips_cache_ops.mco_sdcache_wbinv_all =3D + mips_cache_ops.mco_intern_sdcache_wbinv_all =3D + mipsNN_sdcache_wbinv_all_32; + mips_cache_ops.mco_sdcache_wbinv_range =3D + mipsNN_sdcache_wbinv_range_32; + mips_cache_ops.mco_sdcache_wbinv_range_index =3D + mips_cache_ops.mco_intern_sdcache_wbinv_range_index =3D + mipsNN_sdcache_wbinv_range_index_32; + mips_cache_ops.mco_sdcache_inv_range =3D + mipsNN_sdcache_inv_range_32; + mips_cache_ops.mco_sdcache_wb_range =3D + mips_cache_ops.mco_intern_sdcache_wb_range =3D + mipsNN_sdcache_wb_range_32; + break; + default: + panic("no SDcache ops for %d byte lines", + cpuinfo->l1.dc_linesize); + } + + mipsNN_cache_init(cpuinfo); =20 #if 0 =3D=3D=3D modified file 'mips/mips/cache_mipsNN.c' --- mips/mips/cache_mipsNN.c 2010-08-13 22:16:49 +0000 +++ mips/mips/cache_mipsNN.c 2010-08-15 09:24:10 +0000 @@ -82,6 +82,12 @@ static int pdcache_loopcount; static int pdcache_way_mask; =20 +static int sdcache_size; +static int sdcache_stride; +static int sdcache_loopcount; +static int sdcache_way_mask; + + void mipsNN_cache_init(struct mips_cpuinfo * cpuinfo) { @@ -115,6 +121,15 @@ cpuinfo->l1.dc_nways; } =20 + if (cpuinfo->l2.dc_nsets * cpuinfo->l2.dc_linesize < PAGE_SIZE) { + sdcache_stride =3D cpuinfo->l2.dc_nsets * cpuinfo->l2.dc_linesize; + sdcache_loopcount =3D cpuinfo->l2.dc_nways; + } else { + sdcache_stride =3D PAGE_SIZE; + sdcache_loopcount =3D (cpuinfo->l2.dc_nsets * cpuinfo->l2.dc_linesize = / PAGE_SIZE) * + cpuinfo->l2.dc_nways; + } + mips_picache_linesize =3D cpuinfo->l1.ic_linesize; mips_pdcache_linesize =3D cpuinfo->l1.dc_linesize; =20 @@ -123,6 +138,9 @@ pdcache_size =3D cpuinfo->l1.dc_size; pdcache_way_mask =3D cpuinfo->l1.dc_nways - 1; =20 + sdcache_size =3D cpuinfo->l2.dc_size; + sdcache_way_mask =3D cpuinfo->l2.dc_nways - 1; + #define CACHE_DEBUG #ifdef CACHE_DEBUG printf("Cache info:\n"); @@ -181,6 +199,12 @@ SYNC; } =20 +#if __mips =3D=3D 3 +#define HIT_I_INV CACHE_R4K_I|CACHEOP_R4K_INDEX_INV +#else +#define HIT_I_INV CACHE_R4K_I|CACHEOP_R4K_HIT_INV +#endif + void mipsNN_icache_sync_range_16(vm_offset_t va, vm_size_t size) { @@ -192,12 +216,12 @@ mips_intern_dcache_wb_range(va, (eva - va)); =20 while ((eva - va) >=3D (32 * 16)) { - cache_r4k_op_32lines_16(va, CACHE_R4K_I|CACHEOP_R4K_HIT_INV); + cache_r4k_op_32lines_16(va, HIT_I_INV); va +=3D (32 * 16); } =20 while (va < eva) { - cache_op_r4k_line(va, CACHE_R4K_I|CACHEOP_R4K_HIT_INV); + cache_op_r4k_line(va, HIT_I_INV); va +=3D 16; } =20 @@ -215,12 +239,12 @@ mips_intern_dcache_wb_range(va, (eva - va)); =20 while ((eva - va) >=3D (32 * 32)) { - cache_r4k_op_32lines_32(va, CACHE_R4K_I|CACHEOP_R4K_HIT_INV); + cache_r4k_op_32lines_32(va, HIT_I_INV); va +=3D (32 * 32); } =20 while (va < eva) { - cache_op_r4k_line(va, CACHE_R4K_I|CACHEOP_R4K_HIT_INV); + cache_op_r4k_line(va, HIT_I_INV); va +=3D 32; } =20 @@ -230,7 +254,7 @@ void mipsNN_icache_sync_range_index_16(vm_offset_t va, vm_size_t size) { - unsigned int eva, tmpva; + vm_offset_t eva, tmpva; int i, stride, loopcount; =20 /* @@ -273,7 +297,7 @@ void mipsNN_icache_sync_range_index_32(vm_offset_t va, vm_size_t size) { - unsigned int eva, tmpva; + vm_offset_t eva, tmpva; int i, stride, loopcount; =20 /* @@ -357,6 +381,7 @@ SYNC; } =20 + void mipsNN_pdcache_wbinv_range_16(vm_offset_t va, vm_size_t size) { @@ -454,7 +479,7 @@ * bits that determine the cache index, and make a KSEG0 * address out of them. */ - va =3D MIPS_PHYS_TO_KSEG0(va & pdcache_way_mask); + va =3D MIPS_PHYS_TO_KSEG0 (va & pdcache_way_mask); =20 eva =3D round_line32(va + size); va =3D trunc_line32(va); @@ -482,7 +507,7 @@ va +=3D 32; } } -=20 + void mipsNN_pdcache_inv_range_16(vm_offset_t va, vm_size_t size) { @@ -567,7 +592,6 @@ SYNC; } =20 - #ifdef CPU_CNMIPS =20 void @@ -617,3 +641,130 @@ } =20 #endif + +void +mipsNN_sdcache_wbinv_all_32(void) +{ + vm_offset_t va, eva; + + va =3D MIPS_PHYS_TO_KSEG0(0); + eva =3D va + sdcache_size; + + /* + * Since we're hitting the whole thing, we don't have to + * worry about the N different "ways". + */ + + while (va < eva) { + cache_r4k_op_32lines_32(va, + CACHE_R4K_SD|CACHEOP_R4K_INDEX_WB_INV); + va +=3D (32 * 32); + } + + SYNC; +} + +void +mipsNN_sdcache_wbinv_range_32(vm_offset_t va, vm_size_t size) +{ + vm_offset_t eva; + + eva =3D round_line32(va + size); + va =3D trunc_line32(va); + + while ((eva - va) >=3D (32 * 32)) { + cache_r4k_op_32lines_32(va, + CACHE_R4K_SD|CACHEOP_R4K_HIT_WB_INV); + va +=3D (32 * 32); + } + + while (va < eva) { + cache_op_r4k_line(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_WB_INV); + va +=3D 32; + } + + SYNC; +} + +void +mipsNN_sdcache_wbinv_range_index_32(vm_offset_t va, vm_size_t size) +{ + vm_offset_t eva, tmpva; + int i, stride, loopcount; + + /* + * Since we're doing Index ops, we expect to not be able + * to access the address we've been given. So, get the + * bits that determine the cache index, and make a KSEG0 + * address out of them. + */ + va =3D MIPS_PHYS_TO_KSEG0 (va & sdcache_way_mask); + + eva =3D round_line32(va + size); + va =3D trunc_line32(va); + + /* + * GCC generates better code in the loops if we reference local + * copies of these global variables. + */ + stride =3D sdcache_stride; + loopcount =3D sdcache_loopcount; + + while ((eva - va) >=3D (8 * 32)) { + tmpva =3D va; + for (i =3D 0; i < loopcount; i++, tmpva +=3D stride) + cache_r4k_op_8lines_32(tmpva, + CACHE_R4K_SD|CACHEOP_R4K_INDEX_WB_INV); + va +=3D 8 * 32; + } + + while (va < eva) { + tmpva =3D va; + for (i =3D 0; i < loopcount; i++, tmpva +=3D stride) + cache_op_r4k_line(tmpva, + CACHE_R4K_SD|CACHEOP_R4K_INDEX_WB_INV); + va +=3D 32; + } +} + +void +mipsNN_sdcache_inv_range_32(vm_offset_t va, vm_size_t size) +{ + vm_offset_t eva; + + eva =3D round_line32(va + size); + va =3D trunc_line32(va); + + while ((eva - va) >=3D (32 * 32)) { + cache_r4k_op_32lines_32(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_INV); + va +=3D (32 * 32); + } + + while (va < eva) { + cache_op_r4k_line(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_INV); + va +=3D 32; + } + + SYNC; +} + +void +mipsNN_sdcache_wb_range_32(vm_offset_t va, vm_size_t size) +{ + vm_offset_t eva; + + eva =3D round_line32(va + size); + va =3D trunc_line32(va); + + while ((eva - va) >=3D (32 * 32)) { + cache_r4k_op_32lines_32(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_WB); + va +=3D (32 * 32); + } + + while (va < eva) { + cache_op_r4k_line(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_WB); + va +=3D 32; + } + + SYNC; +} =3D=3D=3D modified file 'mips/mips/cpu.c' --- mips/mips/cpu.c 2010-08-13 22:16:49 +0000 +++ mips/mips/cpu.c 2010-08-15 09:24:10 +0000 @@ -69,8 +69,6 @@ { u_int32_t prid; u_int32_t cfg0; - u_int32_t cfg1; - u_int32_t tmp; =20 memset(cpuinfo, 0, sizeof(struct mips_cpuinfo)); =20 @@ -87,46 +85,71 @@ ((cfg0 & MIPS_CONFIG0_MT_MASK) >> MIPS_CONFIG0_MT_SHIFT); cpuinfo->icache_virtual =3D cfg0 & MIPS_CONFIG0_VI; =20 - /* If config register selection 1 does not exist, exit. */ - if (!(cfg0 & MIPS3_CONFIG_CM)) - return; - - /* Learn TLB size and L1 cache geometry. */ - cfg1 =3D mips_rd_config1(); - cpuinfo->tlb_nentries =3D=20 - ((cfg1 & MIPS_CONFIG1_TLBSZ_MASK) >> MIPS_CONFIG1_TLBSZ_SHIFT) + 1;= - - /* L1 instruction cache. */ - tmp =3D (cfg1 & MIPS_CONFIG1_IL_MASK) >> MIPS_CONFIG1_IL_SHIFT; - if (tmp !=3D 0) { - cpuinfo->l1.ic_linesize =3D 1 << (tmp + 1); - cpuinfo->l1.ic_nways =3D (((cfg1 & MIPS_CONFIG1_IA_MASK) >> MIPS_CONFI= G1_IA_SHIFT)) + 1; - cpuinfo->l1.ic_nsets =3D=20 - 1 << (((cfg1 & MIPS_CONFIG1_IS_MASK) >> MIPS_CONFIG1_IS_SHIFT) + = 6); - cpuinfo->l1.ic_size =3D=20 - cpuinfo->l1.ic_linesize * cpuinfo->l1.ic_nsets * cpuinfo->l1.ic_nw= ays; - } - - /* L1 data cache. */ - tmp =3D (cfg1 & MIPS_CONFIG1_DL_MASK) >> MIPS_CONFIG1_DL_SHIFT; - if (tmp !=3D 0) { - cpuinfo->l1.dc_linesize =3D 1 << (tmp + 1); - cpuinfo->l1.dc_nways =3D=20 - (((cfg1 & MIPS_CONFIG1_DA_MASK) >> MIPS_CONFIG1_DA_SHIFT)) + 1; - cpuinfo->l1.dc_nsets =3D=20 - 1 << (((cfg1 & MIPS_CONFIG1_DS_MASK) >> MIPS_CONFIG1_DS_SHIFT) + 6= ); - } +#ifdef MIPS_HAS_CP0_SELECTORS + { + /* If config register selection 1 does not exist, exit. */ + if (!(cfg0 & MIPS3_CONFIG_CM)) + return; + + /* Learn TLB size and L1 cache geometry. */ + cfg1 =3D mips_rd_config1(); + cpuinfo->tlb_nentries =3D=20 + ((cfg1 & MIPS_CONFIG1_TLBSZ_MASK) >> MIPS_CONFIG1_TLBSZ_SHIFT) + 1; + + /* L1 instruction cache. */ + tmp =3D (cfg1 & MIPS_CONFIG1_IL_MASK) >> MIPS_CONFIG1_IL_SHIFT; + if (tmp !=3D 0) { + cpuinfo->l1.ic_linesize =3D 1 << (tmp + 1); + cpuinfo->l1.ic_nways =3D (((cfg1 & MIPS_CONFIG1_IA_MASK) >> MIPS_CONF= IG1_IA_SHIFT)) + 1; + cpuinfo->l1.ic_nsets =3D=20 + 1 << (((cfg1 & MIPS_CONFIG1_IS_MASK) >> MIPS_CONFIG1_IS_SHIFT) + 6);= + cpuinfo->l1.ic_size =3D=20 + cpuinfo->l1.ic_linesize * cpuinfo->l1.ic_nsets * cpuinfo->l1.ic_nway= s; + } + + /* L1 data cache. */ + tmp =3D (cfg1 & MIPS_CONFIG1_DL_MASK) >> MIPS_CONFIG1_DL_SHIFT; + if (tmp !=3D 0) { + cpuinfo->l1.dc_linesize =3D 1 << (tmp + 1); + cpuinfo->l1.dc_nways =3D=20 + (((cfg1 & MIPS_CONFIG1_DA_MASK) >> MIPS_CONFIG1_DA_SHIFT)) + 1; + cpuinfo->l1.dc_nsets =3D=20 + 1 << (((cfg1 & MIPS_CONFIG1_DS_MASK) >> MIPS_CONFIG1_DS_SHIFT) + 6);= + } #ifdef CPU_CNMIPS - /* - * Octeon does 128 byte line-size. But Config-Sel1 doesn't show - * 128 line-size, 1 Set, 64 ways. - */ - cpuinfo->l1.dc_linesize =3D 128; - cpuinfo->l1.dc_nsets =3D 1; - cpuinfo->l1.dc_nways =3D 64; -#endif - cpuinfo->l1.dc_size =3D cpuinfo->l1.dc_linesize=20 - * cpuinfo->l1.dc_nsets * cpuinfo->l1.dc_nways; + /* + * Octeon does 128 byte line-size. But Config-Sel1 doesn't show + * 128 line-size, 1 Set, 64 ways. + */ + cpuinfo->l1.dc_linesize =3D 128; + cpuinfo->l1.dc_nsets =3D 1; + cpuinfo->l1.dc_nways =3D 64; +#endif + cpuinfo->l1.dc_size =3D cpuinfo->l1.dc_linesize=20 + * cpuinfo->l1.dc_nsets * cpuinfo->l1.dc_nways; + } +#elif defined (TARGET_YEELOONG) + { + cpuinfo->tlb_nentries =3D 64; + + cpuinfo->l1.ic_linesize =3D 32; + cpuinfo->l1.ic_nways =3D 4; + cpuinfo->l1.ic_nsets =3D 65536 / (4 * 32); + cpuinfo->l1.ic_size =3D 65536; + + cpuinfo->l1.dc_linesize =3D 32; + cpuinfo->l1.dc_nways =3D 4; + cpuinfo->l1.dc_nsets =3D 65536 / (4 * 32); + cpuinfo->l1.dc_size =3D 65536; + + cpuinfo->l2.dc_linesize =3D 32; + cpuinfo->l2.dc_nways =3D 4; + cpuinfo->l2.dc_nsets =3D (512 * 1024) / (4 * 32); + cpuinfo->l2.dc_size =3D (512 * 1024); + } +#else +#error unknown architecture without selector support +#endif } =20 void @@ -143,6 +166,7 @@ =20 mips_icache_sync_all(); mips_dcache_wbinv_all(); + mips_sdcache_wbinv_all(); /* Print some info about CPU */ cpu_identify(); } @@ -150,7 +174,7 @@ static void cpu_identify(void) { - uint32_t cfg0, cfg1, cfg2, cfg3; + uint32_t cfg0; printf("cpu%d: ", 0); /* XXX per-cpu */ switch (cpuinfo.cpu_vendor) { case MIPS_PRID_CID_MTI: @@ -236,27 +260,33 @@ if (!(cfg0 & MIPS3_CONFIG_CM)) return; =20 - cfg1 =3D mips_rd_config1(); - printf(" Config1=3D0x%b\n", cfg1,=20 - "\20\7COP2\6MDMX\5PerfCount\4WatchRegs\3MIPS16\2EJTAG\1FPU"); - - /* If config register selection 2 does not exist, exit. */ - if (!(cfg1 & MIPS3_CONFIG_CM)) - return; - cfg2 =3D mips_rd_config2(); - /*=20 - * Config2 contains no useful information other then Config3=20 - * existence flag - */ - - /* If config register selection 3 does not exist, exit. */ - if (!(cfg2 & MIPS3_CONFIG_CM)) - return; - cfg3 =3D mips_rd_config3(); +#ifdef MIPS_HAS_CP0_SELECTORS + { + uint32_t cfg1, cfg2, cfg3; + + cfg1 =3D mips_rd_config1(); + printf(" Config1=3D0x%b\n", cfg1,=20 + "\20\7COP2\6MDMX\5PerfCount\4WatchRegs\3MIPS16\2EJTAG\1FPU"); + + /* If config register selection 2 does not exist, exit. */ + if (!(cfg1 & MIPS3_CONFIG_CM)) + return; + cfg2 =3D mips_rd_config2(); + /*=20 + * Config2 contains no useful information other then Config3=20 + * existence flag + */ + + /* If config register selection 3 does not exist, exit. */ + if (!(cfg2 & MIPS3_CONFIG_CM)) + return; + cfg3 =3D mips_rd_config3(); =20 /* Print Config3 if it contains any useful info */ - if (cfg3 & ~(0x80000000)) - printf(" Config3=3D0x%b\n", cfg3, "\20\2SmartMIPS\1TraceLogic"); + if (cfg3 & ~(0x80000000)) + printf(" Config3=3D0x%b\n", cfg3, "\20\2SmartMIPS\1TraceLogic"); + } +#endif } =20 static struct rman cpu_hardirq_rman; =3D=3D=3D modified file 'mips/mips/db_disasm.c' --- mips/mips/db_disasm.c 2010-08-13 22:16:49 +0000 +++ mips/mips/db_disasm.c 2010-08-14 10:37:00 +0000 @@ -53,6 +53,17 @@ #include #include =20 +static char *cache_op_suffix[4] =3D { + "i", "d", "s", "si" +}; + +static char *cache_op_type[8] =3D { + "Index_Writeback_Invalidate", "Index_Load_Tag", + "Index_Store_Tag", "Create_Dirty_EXCL", + "Hit_Invalidate", "Hit_Writeback_Invalidate", + "Hit_Writeback", "Hit_Set_Virtual" +}; + static char *op_name[64] =3D { /* 0 */ "spec", "bcond","j", "jal", "beq", "bne", "blez", "bgtz", /* 8 */ "addi", "addiu","slti", "sltiu","andi", "ori", "xori", "lui", @@ -373,6 +384,14 @@ reg_name[i.IType.rt], i.IType.imm); break; =20 + case OP_CACHE: + db_printf("%s%s\t%s, %d(%s)", op_name[i.IType.op], + cache_op_suffix[i.IType.rt & 3], + cache_op_type[i.IType.rt >> 2], + (short)i.IType.imm, reg_name[i.IType.rs] + ); + break; + =09 case OP_ADDI: case OP_DADDI: case OP_ADDIU: =3D=3D=3D modified file 'mips/mips/db_interface.c' --- mips/mips/db_interface.c 2010-08-13 22:16:49 +0000 +++ mips/mips/db_interface.c 2010-08-15 09:24:10 +0000 @@ -211,6 +211,7 @@ =20 mips_icache_sync_range((db_addr_t) addr, size); mips_dcache_wbinv_range((db_addr_t) addr, size); + mips_sdcache_wbinv_range((db_addr_t) addr, size); } (void)kdb_jmpbuf(prev_jb); return (ret); =3D=3D=3D modified file 'mips/mips/db_trace.c' --- mips/mips/db_trace.c 2010-08-13 22:16:49 +0000 +++ mips/mips/db_trace.c 2010-08-14 10:37:00 +0000 @@ -49,9 +49,19 @@ #define MIPS_END_OF_FUNCTION(ins) ((ins) =3D=3D 0x03e00008) =20 /* - * kdbpeekD(addr) - skip one word starting at 'addr', then read the seco= nd word + * kdbpeekD(addr) - read double word. */ -#define kdbpeekD(addr) kdbpeek(((int *)(addr)) + 1) + +static inline register_t +kdbpeekD (uintptr_t addr) { +#ifdef __MIPSEL__ + return ((uint64_t) kdbpeek ((int *) addr)) + | (((uint64_t) kdbpeek ((int *) addr + 1)) << 32); +#else + return ((uint64_t) kdbpeek ((int *) addr + 1)) + | (((uint64_t) kdbpeek ((int *) addr)) << 32); +#endif +} =20 /* * Functions ``special'' enough to print by name @@ -105,6 +115,9 @@ } =20 void +kproc_shutdown(void *arg, int howto); + +void stacktrace_subr(register_t pc, register_t sp, register_t ra, int (*printfn) (const char *,...)) { @@ -119,6 +132,8 @@ unsigned instr, mask; unsigned int frames =3D 0; int more, stksize, j; + const uintptr_t kseg0_start =3D sizeof (uintptr_t) =3D=3D 8 + ? 0x8000000000000000ULL : 0x80000000; =20 /* Jump here when done with a frame, to start a new one */ loop: @@ -140,7 +155,7 @@ } /* check for bad SP: could foul up next frame */ /*XXX MIPS64 bad: this hard-coded SP is lame */ - if (sp & 3 || (uintptr_t)sp < 0x80000000u) { + if (sp & 3 || (uintptr_t)sp < kseg0_start) { (*printfn) ("SP 0x%x: not in kernel\n", sp); ra =3D 0; subr =3D 0; @@ -156,7 +171,9 @@ * preceding "j ra" at the tail of the preceding function. Depends * on relative ordering of functions in exception.S, swtch.S. */ - if (pcBetween(MipsKernGenException, MipsUserGenException)) + if (pcBetween(panic, shutdown_nice)) + subr =3D (uintptr_t) panic; + else if (pcBetween(MipsKernGenException, MipsUserGenException)) subr =3D (uintptr_t)MipsKernGenException; else if (pcBetween(MipsUserGenException, MipsKernIntr)) subr =3D (uintptr_t)MipsUserGenException; @@ -181,7 +198,7 @@ } /* check for bad PC */ /*XXX MIPS64 bad: These hard coded constants are lame */ - if (pc & 3 || pc < (uintptr_t)0x80000000) { + if (pc & 3 || (uintptr_t)pc < kseg0_start) { (*printfn) ("PC 0x%x: not in kernel\n", pc); ra =3D 0; goto done; @@ -303,32 +320,34 @@ mask |=3D (1 << i.IType.rt); switch (i.IType.rt) { case 4:/* a0 */ - args[0] =3D kdbpeekD((int *)(sp + (short)i.IType.imm)); + args[0] =3D kdbpeekD((sp + (short)i.IType.imm)); valid_args[0] =3D 1; break; =20 case 5:/* a1 */ - args[1] =3D kdbpeekD((int *)(sp + (short)i.IType.imm)); + args[1] =3D kdbpeekD((sp + (short)i.IType.imm)); valid_args[1] =3D 1; break; =20 case 6:/* a2 */ - args[2] =3D kdbpeekD((int *)(sp + (short)i.IType.imm)); + args[2] =3D kdbpeekD((sp + (short)i.IType.imm)); valid_args[2] =3D 1; break; =20 case 7:/* a3 */ - args[3] =3D kdbpeekD((int *)(sp + (short)i.IType.imm)); + args[3] =3D kdbpeekD((sp + (short)i.IType.imm)); valid_args[3] =3D 1; break; =20 case 31: /* ra */ - ra =3D kdbpeekD((int *)(sp + (short)i.IType.imm)); + ra =3D kdbpeekD((sp + (short)i.IType.imm)); } break; =20 case OP_ADDI: case OP_ADDIU: + case OP_DADDIU: + case OP_DADDI: /* look for stack pointer adjustment */ if (i.IType.rs !=3D 29 || i.IType.rt !=3D 29) break; @@ -337,17 +356,18 @@ } =20 done: - (*printfn) ("%s+%x (", fn_name(subr), pc - subr); + (*printfn) ("%s+%lx (", fn_name(subr), (unsigned long) (pc - subr)); for (j =3D 0; j < 4; j ++) { if (j > 0) (*printfn)(","); if (valid_args[j]) - (*printfn)("%x", args[j]); + (*printfn)("%lx", (unsigned long) args[j]); else (*printfn)("?"); } =20 - (*printfn) (") ra %x sp %x sz %d\n", ra, sp, stksize); + (*printfn) (") ra %lx sp %lx sz %ld\n", (unsigned long) ra, + (unsigned long) sp, (long) stksize); =20 if (ra) { if (pc =3D=3D ra && stksize =3D=3D 0) @@ -403,8 +423,12 @@ struct pcb *ctx; =20 if (thr =3D=3D curthread) { - sp =3D (register_t)(intptr_t)__builtin_frame_address(0); - ra =3D (register_t)(intptr_t)__builtin_return_address(0); + __asm __volatile( + "move %0, $sp\n" + : "=3Dr" (sp)); + __asm __volatile( + "move %0, $ra\n" + : "=3Dr" (ra)); =20 __asm __volatile( "jal 99f\n" =3D=3D=3D modified file 'mips/mips/exception.S' --- mips/mips/exception.S 2010-08-13 22:16:49 +0000 +++ mips/mips/exception.S 2010-08-14 10:37:00 +0000 @@ -156,7 +156,10 @@ CLEAR_PTE_SWBITS(k1) MTC0 k1, MIPS_COP_0_TLB_LO1 #15: lo1 is loaded COP0_SYNC + MTC0 zero, MIPS_COP_0_TLB_PG_MASK + COP0_SYNC tlbwr #1a: write to tlb +=09 HAZARD_DELAY eret #1f: retUrn from exception 1: j MipsTLBMissException #20: kernel exception @@ -868,6 +871,9 @@ CLEAR_PTE_SWBITS(k1) MTC0 k1, MIPS_COP_0_TLB_LO1 COP0_SYNC + MTC0 zero, MIPS_COP_0_TLB_PG_MASK + COP0_SYNC + =20 b tlb_insert_entry nop @@ -881,6 +887,8 @@ CLEAR_PTE_SWBITS(k1) MTC0 k1, MIPS_COP_0_TLB_LO1 COP0_SYNC + MTC0 zero, MIPS_COP_0_TLB_PG_MASK + COP0_SYNC =20 tlb_insert_entry: tlbp @@ -890,12 +898,12 @@ nop tlbwi eret - ssnop + SSNOP =20 tlb_insert_random: tlbwr eret - ssnop + SSNOP =20 3: /* @@ -1023,6 +1031,8 @@ CLEAR_PTE_SWBITS(k1) MTC0 k1, MIPS_COP_0_TLB_LO1 # lo1 is loaded COP0_SYNC + MTC0 zero, MIPS_COP_0_TLB_PG_MASK + COP0_SYNC tlbwr # write to tlb HAZARD_DELAY eret # return from exception =3D=3D=3D modified file 'mips/mips/locore.S' --- mips/mips/locore.S 2010-08-13 22:16:49 +0000 +++ mips/mips/locore.S 2010-08-15 09:24:10 +0000 @@ -69,9 +69,38 @@ #include #include #include +#define ASM_FILE +#include "multiboot2.h" =20 #include "assym.s" =20 + .section ".multiboot", "a" + + /* Align 64 bits boundary. */ + .align 8 + =09 + /* Multiboot header. */ +multiboot_header: + /* magic */ + .long MULTIBOOT2_HEADER_MAGIC + .long MULTIBOOT_ARCHITECTURE_MIPS32 + /* Header length. */ + .long multiboot_header_end - multiboot_header + /* checksum */ + .long -(MULTIBOOT2_HEADER_MAGIC + MULTIBOOT_ARCHITECTURE_MIPS32 + (mult= iboot_header_end - multiboot_header)) +framebuffer_tag_start:=09 + .short MULTIBOOT_HEADER_TAG_FRAMEBUFFER + .short MULTIBOOT_HEADER_TAG_OPTIONAL + .long framebuffer_tag_end - framebuffer_tag_start + .long 1024 + .long 600 + .long 16 +framebuffer_tag_end: + .short MULTIBOOT_HEADER_TAG_END + .short 0 + .long 8 +multiboot_header_end: + .data #ifdef YAMON GLOBAL(fenvp) @@ -133,7 +162,10 @@ COP0_SYNC =20 /* Make sure KSEG0 is cached */ - li t0, MIPS_CCA_CACHED + mfc0 t0, MIPS_COP_0_CONFIG + srl t0, 3 + sll t0, 3 + ori t0, MIPS_CCA_CACHED mtc0 t0, MIPS_COP_0_CONFIG COP0_SYNC =20 =3D=3D=3D modified file 'mips/mips/machdep.c' --- mips/mips/machdep.c 2010-08-13 22:16:49 +0000 +++ mips/mips/machdep.c 2010-08-15 09:24:10 +0000 @@ -232,7 +232,8 @@ void cpu_flush_dcache(void *ptr, size_t len) { - /* TBD */ + mips_dcache_wbinv_range((vm_offset_t)ptr, PAGE_SIZE); + mips_sdcache_wbinv_range((vm_offset_t)ptr, PAGE_SIZE); } =20 /* Get current clock frequency for the given cpu id. */ @@ -249,6 +250,7 @@ void cpu_halt(void) { + platform_halt (); for (;;) ; } @@ -351,6 +353,7 @@ */ mips_icache_sync_all(); mips_dcache_wbinv_all(); + mips_sdcache_wbinv_all(); =20 /*=20 * Mask all interrupts. Each interrupt will be enabled @@ -477,7 +480,11 @@ cpu_idle(int busy) { if (mips_rd_status() & MIPS_SR_INT_IE) + { +#ifndef TARGET_YEELOONG __asm __volatile ("wait"); +#endif + } else panic("ints disabled in idleproc!"); } =3D=3D=3D modified file 'mips/mips/mp_machdep.c' --- mips/mips/mp_machdep.c 2010-08-13 22:16:49 +0000 +++ mips/mips/mp_machdep.c 2010-08-15 09:24:10 +0000 @@ -272,6 +272,7 @@ * on the BSP. */ mips_dcache_wbinv_all(); + mips_sdcache_wbinv_all(); mips_icache_sync_all(); =20 mips_sync(); =3D=3D=3D added file 'mips/mips/multiboot2.h' --- mips/mips/multiboot2.h 1970-01-01 00:00:00 +0000 +++ mips/mips/multiboot2.h 2010-08-14 10:37:00 +0000 @@ -0,0 +1,314 @@ +/* multiboot2.h - Multiboot 2 header file. */ +/* Copyright (C) 1999,2003,2007,2008,2009,2010 Free Software Foundatio= n, Inc. + * + * Permission is hereby granted, free of charge, to any person obtainin= g a copy + * of this software and associated documentation files (the "Software")= , to + * deal in the Software without restriction, including without limitati= on the + * rights to use, copy, modify, merge, publish, distribute, sublicense,= and/or + * sell copies of the Software, and to permit persons to whom the Softw= are is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be inclu= ded in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPR= ESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL= ITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT S= HALL ANY + * DEVELOPER OR DISTRIBUTOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER L= IABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, O= UT OF OR + * IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE = SOFTWARE. + */ + +#ifndef MULTIBOOT_HEADER +#define MULTIBOOT_HEADER 1 + +/* How many bytes from the start of the file we search for the header. = */ +#define MULTIBOOT_SEARCH 32768 +#define MULTIBOOT_HEADER_ALIGN 8 + +/* The magic field should contain this. */ +#define MULTIBOOT2_HEADER_MAGIC 0xe85250d6 + +/* This should be in %eax. */ +#define MULTIBOOT2_BOOTLOADER_MAGIC 0x36d76289 + +/* Alignment of multiboot modules. */ +#define MULTIBOOT_MOD_ALIGN 0x00001000 + +/* Alignment of the multiboot info structure. */ +#define MULTIBOOT_INFO_ALIGN 0x00000008 + +/* Flags set in the 'flags' member of the multiboot header. */ + +#define MULTIBOOT_TAG_ALIGN 8 +#define MULTIBOOT_TAG_TYPE_END 0 +#define MULTIBOOT_TAG_TYPE_CMDLINE 1 +#define MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME 2 +#define MULTIBOOT_TAG_TYPE_MODULE 3 +#define MULTIBOOT_TAG_TYPE_BASIC_MEMINFO 4 +#define MULTIBOOT_TAG_TYPE_BOOTDEV 5 +#define MULTIBOOT_TAG_TYPE_MMAP 6 +#define MULTIBOOT_TAG_TYPE_VBE 7 +#define MULTIBOOT_TAG_TYPE_FRAMEBUFFER 8 +#define MULTIBOOT_TAG_TYPE_ELF_SECTIONS 9 +#define MULTIBOOT_TAG_TYPE_APM 10 + +#define MULTIBOOT_HEADER_TAG_END 0 +#define MULTIBOOT_HEADER_TAG_INFORMATION_REQUEST 1 +#define MULTIBOOT_HEADER_TAG_ADDRESS 2 +#define MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS 3 +#define MULTIBOOT_HEADER_TAG_CONSOLE_FLAGS 4 +#define MULTIBOOT_HEADER_TAG_FRAMEBUFFER 5 +#define MULTIBOOT_HEADER_TAG_MODULE_ALIGN 6 + +#define MULTIBOOT_ARCHITECTURE_I386 0 +#define MULTIBOOT_ARCHITECTURE_MIPS32 4 +#define MULTIBOOT_HEADER_TAG_OPTIONAL 1 + +#define MULTIBOOT_CONSOLE_FLAGS_CONSOLE_REQUIRED 1 +#define MULTIBOOT_CONSOLE_FLAGS_EGA_TEXT_SUPPORTED 2 + +#ifndef ASM_FILE + +typedef unsigned char multiboot_uint8_t; +typedef unsigned short multiboot_uint16_t; +typedef unsigned int multiboot_uint32_t; +typedef unsigned long long multiboot_uint64_t; + +struct multiboot_header +{ + /* Must be MULTIBOOT_MAGIC - see above. */ + multiboot_uint32_t magic; + + /* ISA */ + multiboot_uint32_t architecture; + + /* Total header length. */ + multiboot_uint32_t header_length; + + /* The above fields plus this one must equal 0 mod 2^32. */ + multiboot_uint32_t checksum; +}; + +struct multiboot_header_tag +{ + multiboot_uint16_t type; + multiboot_uint16_t flags; + multiboot_uint32_t size; +}; + +struct multiboot_header_tag_information_request +{ + multiboot_uint16_t type; + multiboot_uint16_t flags; + multiboot_uint32_t size; + multiboot_uint32_t requests[0]; +}; + +struct multiboot_header_tag_address +{ + multiboot_uint16_t type; + multiboot_uint16_t flags; + multiboot_uint32_t size; + multiboot_uint32_t header_addr; + multiboot_uint32_t load_addr; + multiboot_uint32_t load_end_addr; + multiboot_uint32_t bss_end_addr; +}; + +struct multiboot_header_tag_entry_address +{ + multiboot_uint16_t type; + multiboot_uint16_t flags; + multiboot_uint32_t size; + multiboot_uint32_t entry_addr; +}; + +struct multiboot_header_tag_console_flags +{ + multiboot_uint16_t type; + multiboot_uint16_t flags; + multiboot_uint32_t size; + multiboot_uint32_t console_flags; +}; + +struct multiboot_header_tag_framebuffer +{ + multiboot_uint16_t type; + multiboot_uint16_t flags; + multiboot_uint32_t size; + multiboot_uint32_t width; + multiboot_uint32_t height; + multiboot_uint32_t depth; +}; + +struct multiboot_header_tag_module_align +{ + multiboot_uint16_t type; + multiboot_uint16_t flags; + multiboot_uint32_t size; + multiboot_uint32_t width; + multiboot_uint32_t height; + multiboot_uint32_t depth; +}; + +struct multiboot_color +{ + multiboot_uint8_t red; + multiboot_uint8_t green; + multiboot_uint8_t blue; +}; + +struct multiboot_mmap_entry +{ + multiboot_uint64_t addr; + multiboot_uint64_t len; +#define MULTIBOOT_MEMORY_AVAILABLE 1 +#define MULTIBOOT_MEMORY_RESERVED 2 +#define MULTIBOOT_MEMORY_ACPI_RECLAIMABLE 3 +#define MULTIBOOT_MEMORY_NVS 4 + multiboot_uint32_t type; + multiboot_uint32_t zero; +} __attribute__((packed)); +typedef struct multiboot_mmap_entry multiboot_memory_map_t; + +struct multiboot_tag +{ + multiboot_uint32_t type; + multiboot_uint32_t size; +}; + +struct multiboot_tag_string +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + char string[0]; +}; + +struct multiboot_tag_module +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint32_t mod_start; + multiboot_uint32_t mod_end; + char cmdline[0]; +}; + +struct multiboot_tag_basic_meminfo +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint32_t mem_lower; + multiboot_uint32_t mem_upper; +}; + +struct multiboot_tag_bootdev +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint32_t biosdev; + multiboot_uint32_t slice; + multiboot_uint32_t part; +}; + +struct multiboot_tag_mmap +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint32_t entry_size; + multiboot_uint32_t entry_version; + struct multiboot_mmap_entry entries[0]; =20 +}; + +struct multiboot_vbe_info_block +{ + multiboot_uint8_t external_specification[512]; +}; + +struct multiboot_vbe_mode_info_block +{ + multiboot_uint8_t external_specification[256]; +}; + +struct multiboot_tag_vbe +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + + multiboot_uint16_t vbe_mode; + multiboot_uint16_t vbe_interface_seg; + multiboot_uint16_t vbe_interface_off; + multiboot_uint16_t vbe_interface_len; + + struct multiboot_vbe_info_block vbe_control_info; + struct multiboot_vbe_mode_info_block vbe_mode_info; +}; + +struct multiboot_tag_framebuffer_common +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + + multiboot_uint64_t framebuffer_addr; + multiboot_uint32_t framebuffer_pitch; + multiboot_uint32_t framebuffer_width; + multiboot_uint32_t framebuffer_height; + multiboot_uint8_t framebuffer_bpp; +#define MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED 0 +#define MULTIBOOT_FRAMEBUFFER_TYPE_RGB 1 +#define MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT 2 + multiboot_uint8_t framebuffer_type; + multiboot_uint16_t reserved; +}; + +struct multiboot_tag_framebuffer +{ + struct multiboot_tag_framebuffer_common common; + + union + { + struct + { + multiboot_uint16_t framebuffer_palette_num_colors; + struct multiboot_color framebuffer_palette[0]; + } palette; + struct + { + multiboot_uint8_t framebuffer_red_field_position; + multiboot_uint8_t framebuffer_red_mask_size; + multiboot_uint8_t framebuffer_green_field_position; + multiboot_uint8_t framebuffer_green_mask_size; + multiboot_uint8_t framebuffer_blue_field_position; + multiboot_uint8_t framebuffer_blue_mask_size; + } direct; + } color; +}; + +struct multiboot_tag_elf_sections +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint32_t num; + multiboot_uint32_t entsize; + multiboot_uint32_t shndx; + char sections[0]; +}; + +struct multiboot_tag_apm +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint16_t version; + multiboot_uint16_t cseg; + multiboot_uint32_t offset; + multiboot_uint16_t cseg_16; + multiboot_uint16_t dseg; + multiboot_uint16_t flags; + multiboot_uint16_t cseg_len; + multiboot_uint16_t cseg_16_len; + multiboot_uint16_t dseg_len; +}; + +#endif /* ! ASM_FILE */ + +#endif /* ! MULTIBOOT_HEADER */ =3D=3D=3D modified file 'mips/mips/nexus.c' --- mips/mips/nexus.c 2010-08-13 22:16:49 +0000 +++ mips/mips/nexus.c 2010-08-14 21:18:26 +0000 @@ -151,7 +151,7 @@ } =20 mem_rman.rm_start =3D 0; - mem_rman.rm_end =3D ~0u; + mem_rman.rm_end =3D ~(uintptr_t)0; mem_rman.rm_type =3D RMAN_ARRAY; mem_rman.rm_descr =3D "Memory addresses"; if (rman_init(&mem_rman) !=3D 0 || =3D=3D=3D modified file 'mips/mips/pmap.c' --- mips/mips/pmap.c 2010-08-13 22:16:49 +0000 +++ mips/mips/pmap.c 2010-08-15 11:18:29 +0000 @@ -213,6 +213,15 @@ */ static struct local_sysmaps sysmap_lmem[MAXCPU]; =20 +/* To avoid the need of flushing the cache again after just few writes + use only acceleration + */ +#ifdef MIPS_CCA_UA +#define PMAP_LMEM_CACHE PTE_C(MIPS_CCA_UA) +#else +#define PMAP_LMEM_CACHE PTE_C_UNCACHED +#endif + #define PMAP_LMEM_MAP1(va, phys) \ int cpu; \ struct local_sysmaps *sysm; \ @@ -223,7 +232,7 @@ sysm =3D &sysmap_lmem[cpu]; \ va =3D sysm->base; \ npte =3D TLBLO_PA_TO_PFN(phys) | \ - PTE_D | PTE_V | PTE_G | PTE_W | PTE_C_CACHE; \ + PTE_D | PTE_V | PTE_G | PTE_W | PMAP_LMEM_CACHE; \ pte =3D pmap_pte(kernel_pmap, va); \ *pte =3D npte; \ sysm->valid1 =3D 1 @@ -239,11 +248,11 @@ va1 =3D sysm->base; \ va2 =3D sysm->base + PAGE_SIZE; \ npte =3D TLBLO_PA_TO_PFN(phys1) | \ - PTE_D | PTE_V | PTE_G | PTE_W | PTE_C_CACHE; \ + PTE_D | PTE_V | PTE_G | PTE_W | PMAP_LMEM_CACHE; \ pte =3D pmap_pte(kernel_pmap, va1); \ *pte =3D npte; \ npte =3D TLBLO_PA_TO_PFN(phys2) | \ - PTE_D | PTE_V | PTE_G | PTE_W | PTE_C_CACHE; \ + PTE_D | PTE_V | PTE_G | PTE_W | PMAP_LMEM_CACHE; \ pte =3D pmap_pte(kernel_pmap, va2); \ *pte =3D npte; \ sysm->valid1 =3D 1; \ @@ -804,7 +813,7 @@ npte =3D TLBLO_PA_TO_PFN(pa) | PTE_D | PTE_V | PTE_G | PTE_W; =20 if (is_cacheable_mem(pa)) - npte |=3D PTE_C_CACHE; + npte |=3D PTE_C_UNCACHED; else npte |=3D PTE_C_UNCACHED; =20 @@ -827,6 +836,7 @@ * Write back all caches from the page being destroyed */ mips_dcache_wbinv_range_index(va, PAGE_SIZE); + mips_sdcache_wbinv_range_index(va, PAGE_SIZE); =20 pte =3D pmap_pte(kernel_pmap, va); *pte =3D PTE_G; @@ -894,6 +904,7 @@ } =20 mips_dcache_wbinv_range_index(origva, PAGE_SIZE*count); + mips_sdcache_wbinv_range_index(origva, PAGE_SIZE*count); } =20 /* @@ -1587,6 +1598,7 @@ * Write back all caches from the page being destroyed */ mips_dcache_wbinv_range_index(va, PAGE_SIZE); + mips_sdcache_wbinv_range_index(va, PAGE_SIZE); =20 /* * get a local va for mappings for this pmap. @@ -1690,7 +1702,10 @@ * the page being destroyed */ if (m->md.pv_list_count =3D=3D 1)=20 + { mips_dcache_wbinv_range_index(pv->pv_va, PAGE_SIZE); + mips_sdcache_wbinv_range_index(pv->pv_va, PAGE_SIZE); + } =20 pv->pv_pmap->pm_stats.resident_count--; =20 @@ -1961,7 +1976,7 @@ newpte =3D TLBLO_PA_TO_PFN(pa) | rw | PTE_V; =20 if (is_cacheable_mem(pa)) - newpte |=3D PTE_C_CACHE; + newpte |=3D PTE_C_UNCACHED; else newpte |=3D PTE_C_UNCACHED; =20 @@ -2009,7 +2024,15 @@ (prot & VM_PROT_EXECUTE)) { mips_icache_sync_range(va, PAGE_SIZE); mips_dcache_wbinv_range(va, PAGE_SIZE); + mips_sdcache_wbinv_range(va, PAGE_SIZE); } + mips_dcache_wbinv_range(MIPS_PHYS_TO_KSEG0(pa), PAGE_SIZE); + mips_sdcache_wbinv_range(MIPS_PHYS_TO_KSEG0(pa), PAGE_SIZE); +#if defined(__mips_n64) + mips_dcache_wbinv_range(MIPS_PHYS_TO_XKPHYS(MIPS_CCA_C, pa), PAGE_SIZE)= ; + mips_sdcache_wbinv_range(MIPS_PHYS_TO_KSEG0(MIPS_CCA_C, pa), PAGE_SIZE)= ; +#endif + vm_page_unlock_queues(); PMAP_UNLOCK(pmap); } @@ -2126,7 +2149,7 @@ *pte =3D TLBLO_PA_TO_PFN(pa) | PTE_V; =20 if (is_cacheable_mem(pa)) - *pte |=3D PTE_C_CACHE; + *pte |=3D PTE_C_UNCACHED; else *pte |=3D PTE_C_UNCACHED; =20 @@ -2142,6 +2165,7 @@ va &=3D ~PAGE_MASK; mips_icache_sync_range(va, PAGE_SIZE); mips_dcache_wbinv_range(va, PAGE_SIZE); + mips_sdcache_wbinv_range(va, PAGE_SIZE); } } return (mpte); @@ -2189,7 +2213,7 @@ cpu =3D PCPU_GET(cpuid); sysm =3D &sysmap_lmem[cpu]; /* Since this is for the debugger, no locks or any other fun */ - npte =3D TLBLO_PA_TO_PFN(pa) | PTE_D | PTE_V | PTE_G | PTE_W | PTE_C_C= ACHE; + npte =3D TLBLO_PA_TO_PFN(pa) | PTE_D | PTE_V | PTE_G | PTE_W | PTE_C_U= NCACHED; pte =3D pmap_pte(kernel_pmap, sysm->base); *pte =3D npte; sysm->valid1 =3D 1; @@ -2343,6 +2367,7 @@ va =3D MIPS_PHYS_TO_XKPHYS_CACHED(phys); bzero((caddr_t)va, PAGE_SIZE); mips_dcache_wbinv_range(va, PAGE_SIZE); + mips_sdcache_wbinv_range(va, PAGE_SIZE); } #else void @@ -2357,11 +2382,13 @@ =20 bzero((caddr_t)va, PAGE_SIZE); mips_dcache_wbinv_range(va, PAGE_SIZE); + mips_sdcache_wbinv_range(va, PAGE_SIZE); } else { PMAP_LMEM_MAP1(va, phys); =20 bzero((caddr_t)va, PAGE_SIZE); mips_dcache_wbinv_range(va, PAGE_SIZE); + mips_sdcache_wbinv_range(va, PAGE_SIZE); =20 PMAP_LMEM_UNMAP(); } @@ -2383,6 +2410,7 @@ va =3D MIPS_PHYS_TO_XKPHYS_CACHED(phys); bzero((char *)(caddr_t)va + off, size); mips_dcache_wbinv_range(va + off, size); + mips_sdcache_wbinv_range(va + off, size); } #else void @@ -2396,11 +2424,13 @@ va =3D MIPS_PHYS_TO_KSEG0(phys); bzero((char *)(caddr_t)va + off, size); mips_dcache_wbinv_range(va + off, size); + mips_sdcache_wbinv_range(va + off, size); } else { PMAP_LMEM_MAP1(va, phys); =20 bzero((char *)va + off, size); mips_dcache_wbinv_range(va + off, size); + mips_sdcache_wbinv_range(va + off, size); =20 PMAP_LMEM_UNMAP(); } @@ -2417,6 +2447,7 @@ va =3D MIPS_PHYS_TO_XKPHYS_CACHED(phys); bzero((caddr_t)va, PAGE_SIZE); mips_dcache_wbinv_range(va, PAGE_SIZE); + mips_sdcache_wbinv_range(va, PAGE_SIZE); } #else void @@ -2430,11 +2461,13 @@ va =3D MIPS_PHYS_TO_KSEG0(phys); bzero((caddr_t)va, PAGE_SIZE); mips_dcache_wbinv_range(va, PAGE_SIZE); + mips_sdcache_wbinv_range(va, PAGE_SIZE); } else { PMAP_LMEM_MAP1(va, phys); =20 bzero((caddr_t)va, PAGE_SIZE); mips_dcache_wbinv_range(va, PAGE_SIZE); + mips_sdcache_wbinv_range(va, PAGE_SIZE); =20 PMAP_LMEM_UNMAP(); } @@ -2459,10 +2492,12 @@ =20 pmap_flush_pvcache(src); mips_dcache_wbinv_range_index(MIPS_PHYS_TO_XKPHYS_CACHED(phy_dst), PAGE= _SIZE); + mips_sdcache_wbinv_range_index(MIPS_PHYS_TO_XKPHYS_CACHED(phy_dst), PAG= E_SIZE); va_src =3D MIPS_PHYS_TO_XKPHYS_CACHED(phy_src); va_dst =3D MIPS_PHYS_TO_XKPHYS_CACHED(phy_dst); bcopy((caddr_t)va_src, (caddr_t)va_dst, PAGE_SIZE); mips_dcache_wbinv_range(va_dst, PAGE_SIZE); + mips_sdcache_wbinv_range(va_dst, PAGE_SIZE); } #else void @@ -2482,15 +2517,19 @@ pmap_flush_pvcache(src); mips_dcache_wbinv_range_index( MIPS_PHYS_TO_KSEG0(phy_dst), PAGE_SIZE); + mips_sdcache_wbinv_range_index( + MIPS_PHYS_TO_KSEG0(phy_dst), PAGE_SIZE); va_src =3D MIPS_PHYS_TO_KSEG0(phy_src); va_dst =3D MIPS_PHYS_TO_KSEG0(phy_dst); bcopy((caddr_t)va_src, (caddr_t)va_dst, PAGE_SIZE); mips_dcache_wbinv_range(va_dst, PAGE_SIZE); + mips_sdcache_wbinv_range(va_dst, PAGE_SIZE); } else { PMAP_LMEM_MAP2(va_src, phy_src, va_dst, phy_dst); =20 bcopy((void *)va_src, (void *)va_dst, PAGE_SIZE); mips_dcache_wbinv_range(va_dst, PAGE_SIZE); + mips_sdcache_wbinv_range(va_dst, PAGE_SIZE); =20 PMAP_LMEM_UNMAP(); } @@ -3252,16 +3291,16 @@ int rw; =20 if (!(prot & VM_PROT_WRITE)) - rw =3D PTE_V | PTE_RO | PTE_C_CACHE; + rw =3D PTE_RO; else if ((m->flags & (PG_FICTITIOUS | PG_UNMANAGED)) =3D=3D 0) { if ((m->md.pv_flags & PV_TABLE_MOD) !=3D 0) - rw =3D PTE_V | PTE_D | PTE_C_CACHE; + rw =3D PTE_D; else - rw =3D PTE_V | PTE_C_CACHE; + rw =3D 0; vm_page_flag_set(m, PG_WRITEABLE); } else /* Needn't emulate a modified bit for unmanaged pages. */ - rw =3D PTE_V | PTE_D | PTE_C_CACHE; + rw =3D PTE_D; return (rw); } =20 @@ -3390,6 +3429,7 @@ for (pv =3D TAILQ_FIRST(&m->md.pv_list); pv; pv =3D TAILQ_NEXT(pv, pv_list)) { mips_dcache_wbinv_range_index(pv->pv_va, PAGE_SIZE); + mips_sdcache_wbinv_range_index(pv->pv_va, PAGE_SIZE); } } } =3D=3D=3D added file 'mips/mips/sc_machdep.c' --- mips/mips/sc_machdep.c 1970-01-01 00:00:00 +0000 +++ mips/mips/sc_machdep.c 2010-08-14 22:59:18 +0000 @@ -0,0 +1,90 @@ +/*- + * Copyright (c) 2003 Jake Burkholder. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in th= e + * documentation and/or other materials provided with the distributio= n. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AN= D + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE= + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PU= RPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIAB= LE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUE= NTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOO= DS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)= + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, S= TRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY= WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY O= F + * SUCH DAMAGE. + * + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +static sc_softc_t sc_softcs[8]; + +int +sc_get_cons_priority(int *unit, int *flags) +{ + + *unit =3D 0; + *flags =3D 0; + return (CN_INTERNAL); +} + +int +sc_max_unit(void) +{ + return (1); +} + +sc_softc_t * +sc_get_softc(int unit, int flags) +{ + sc_softc_t *sc; + + if (unit < 0 || unit >=3D 8) + return (NULL); + sc =3D &sc_softcs[unit]; + sc->unit =3D unit; + if ((sc->flags & SC_INIT_DONE) =3D=3D 0) { + sc->keyboard =3D -1; + sc->adapter =3D -1; + sc->cursor_char =3D SC_CURSOR_CHAR; + sc->mouse_char =3D SC_MOUSE_CHAR; + } + return (sc); +} + +void +sc_get_bios_values(bios_values_t *values) +{ + values->cursor_start =3D 0; + values->cursor_end =3D 32; + values->shift_state =3D 0; +} + +int +sc_tone(int hz) +{ + return (0); +} =3D=3D=3D modified file 'mips/mips/support.S' --- mips/mips/support.S 2010-08-13 22:16:49 +0000 +++ mips/mips/support.S 2010-08-14 10:37:00 +0000 @@ -97,6 +97,8 @@ =20 #include "assym.s" =20 +#define MAKE_FRAMES 1 + .set noreorder # Noreorder is default style! =20 /* @@ -827,6 +829,12 @@ LEAF(bzero) ALEAF(blkclr) .set noreorder +#ifdef MAKE_FRAMES + daddiu sp, sp, -32 + sd ra, 16(sp) + sd a0, 8(sp) + sd a1, 0(sp) +#endif blt a1, 12, smallclr # small amount to clear? PTR_SUBU a3, zero, a0 # compute # bytes to word align address and a3, a3, 3 @@ -851,11 +859,13 @@ bne a0, a3, 1b sb zero, -1(a0) 2: +#ifdef MAKE_FRAMES + daddiu sp, sp, 32 +#endif j ra nop END(bzero) =20 - /* * bcmp(s1, s2, n) */ =3D=3D=3D modified file 'mips/mips/uio_machdep.c' --- mips/mips/uio_machdep.c 2010-08-13 22:16:49 +0000 +++ mips/mips/uio_machdep.c 2010-08-15 09:24:10 +0000 @@ -100,6 +100,7 @@ * in order to get it overwritten by correct data */ mips_dcache_wbinv_range((vm_offset_t)cp, cnt); + mips_sdcache_wbinv_range((vm_offset_t)cp, cnt); pmap_flush_pvcache(m); } else { sf =3D sf_buf_alloc(m, 0); @@ -131,7 +132,10 @@ if (sf !=3D NULL) sf_buf_free(sf); else + { mips_dcache_wbinv_range((vm_offset_t)cp, cnt); + mips_sdcache_wbinv_range((vm_offset_t)cp, cnt); + } iov->iov_base =3D (char *)iov->iov_base + cnt; iov->iov_len -=3D cnt; uio->uio_resid -=3D cnt; =3D=3D=3D added directory 'mips/yeeloong' =3D=3D=3D added file 'mips/yeeloong/atkbdc_yeeloong.c' --- mips/yeeloong/atkbdc_yeeloong.c 1970-01-01 00:00:00 +0000 +++ mips/yeeloong/atkbdc_yeeloong.c 2010-08-16 19:55:52 +0000 @@ -0,0 +1,173 @@ +/*- + * Copyright (c) 1999 Kazutaka YOKOTA + * Copyright (c) 2010 Vladimir 'phcoder' Serbinenko + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer as + * the first lines of this file unmodified. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in th= e + * documentation and/or other materials provided with the distributio= n. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR= + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRAN= TIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIME= D. + * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, = BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF = USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY= + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE= OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include "opt_kbd.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include +#include + +static void +atkbdc_yeeloong_identify(driver_t * drv, device_t parent) +{ + BUS_ADD_CHILD(parent, 0, "atkbdc", 0); +} + +static int +atkbdc_yeeloong_probe(device_t dev) +{ + if (device_get_unit(dev) !=3D 0) + return (ENXIO); + device_set_desc(dev, "Keyboard controller (i8042)"); + return (0); +} + +static int +atkbdc_yeeloong_attach(device_t dev) +{ + atkbdc_softc_t *sc; + int unit; + int error; + int rid; + atkbdc_device_t *adi; + device_t cdev; + + unit =3D device_get_unit(dev); + sc =3D *(atkbdc_softc_t **)device_get_softc(dev); + if (sc =3D=3D NULL) { + /* + * We have to maintain two copies of the kbdc_softc struct, + * as the low-level console needs to have access to the + * keyboard controller before kbdc is probed and attached. + * kbdc_soft[] contains the default entry for that purpose. + * See atkbdc.c. XXX + */ + sc =3D atkbdc_get_softc(unit); + if (sc =3D=3D NULL) + return ENOMEM; + } + + rid =3D 0; + sc->retry =3D 5000; + sc->port0 =3D bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, + 0x60, + 0x60, + 1, RF_ACTIVE); + if (sc->port0 =3D=3D NULL) + return ENXIO; + + rid =3D 1; + sc->port1 =3D bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, + 0x64, + 0x64, + 1, RF_ACTIVE); + if (sc->port1 =3D=3D NULL) { + bus_release_resource(dev, SYS_RES_IOPORT, 0, sc->port0); + return ENXIO; + } + + error =3D atkbdc_attach_unit(unit, sc, sc->port0, sc->port1); + if (error) { + bus_release_resource(dev, SYS_RES_IOPORT, 0, sc->port0); + bus_release_resource(dev, SYS_RES_IOPORT, 1, sc->port1); + return error; + } + + *(atkbdc_softc_t **)device_get_softc(dev) =3D sc; +=09 + cdev =3D device_add_child(dev, ATKBD_DRIVER_NAME, -1); + adi =3D malloc(sizeof(struct atkbdc_device), M_ATKBDDEV, + M_NOWAIT | M_ZERO); + + if (cdev && adi) + { + int intr =3D 1; + adi->rid =3D KBDC_RID_KBD; + resource_list_init(&adi->resources); + resource_list_add(&adi->resources, SYS_RES_IRQ, adi->rid, + intr, intr, 1); + device_set_ivars(cdev, adi); + } + + + bus_generic_attach(dev); + + return 0; +} + +static device_method_t atkbdc_yeeloong_methods[] =3D { + DEVMETHOD(device_identify, atkbdc_yeeloong_identify), + DEVMETHOD(device_probe, atkbdc_yeeloong_probe), + + DEVMETHOD(device_attach, atkbdc_yeeloong_attach), + DEVMETHOD(device_suspend, bus_generic_suspend), + DEVMETHOD(device_resume, bus_generic_resume), + + DEVMETHOD(bus_print_child, atkbdc_print_child), + DEVMETHOD(bus_read_ivar, atkbdc_read_ivar), + DEVMETHOD(bus_write_ivar, atkbdc_write_ivar), + DEVMETHOD(bus_get_resource_list,atkbdc_get_resource_list), + DEVMETHOD(bus_alloc_resource, bus_generic_rl_alloc_resource), + DEVMETHOD(bus_release_resource, bus_generic_rl_release_resource), + DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), + DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), + DEVMETHOD(bus_get_resource, bus_generic_rl_get_resource), + DEVMETHOD(bus_set_resource, bus_generic_rl_set_resource), + DEVMETHOD(bus_delete_resource, bus_generic_rl_delete_resource), + DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), + DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), + + { 0, 0 } +}; + +static driver_t atkbdc_driver =3D { + ATKBDC_DRIVER_NAME, + atkbdc_yeeloong_methods, + sizeof(atkbdc_softc_t *), +}; + + +DRIVER_MODULE(atkbdc, geode, atkbdc_driver, atkbdc_devclass, 0, 0); =3D=3D=3D added file 'mips/yeeloong/bonito_pci.c' --- mips/yeeloong/bonito_pci.c 1970-01-01 00:00:00 +0000 +++ mips/yeeloong/bonito_pci.c 2010-08-16 19:55:52 +0000 @@ -0,0 +1,481 @@ +/*- + * Copyright (c) 2010 Vladimir Serbinenko + * Copyright (c) 2010 Juli Mallett + * Copyright (c) 2006 Oleksandr Tymoshenko + * Copyright (c) 2002-2004 Juli Mallett + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in th= e + * documentation and/or other materials provided with the distributio= n. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AN= D + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE= + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PU= RPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIAB= LE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUE= NTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOO= DS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)= + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, S= TRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY= WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY O= F + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include + +#include "pcib_if.h" + +#define BONITO_NUM_INTS 16 +#define PCI_NUM_INTS 4 + +struct bonito_softc +{ + struct rman sc_irq; + struct rman sc_io; + struct rman sc_mem; + struct intr_event *intr_events[BONITO_NUM_INTS]; + void *intr_cookie; + struct mtx config_mtx; +}; + +#define PCI_CONF_CTRL_REG (*(volatile uint32_t *)(intptr_t)(int32_t)0xbf= e00118) +#define PCI_INTEDGE_REG (*(volatile uint32_t *)(intptr_t)(int32_t)0xbfe0= 0124) +#define PCI_INTPOL_REG (*(volatile uint32_t *)(intptr_t)(int32_t)0xbfe00= 12c) +#define PCI_INTENSET_REG (*(volatile uint32_t *)(intptr_t)(int32_t)0xbfe= 00130) +#define PCI_INTENCLR_REG (*(volatile uint32_t *)(intptr_t)(int32_t)0xbfe= 00134) +#define PCI_INTEN_REG (*(volatile uint32_t *)(intptr_t)(int32_t)0xbfe001= 38) +#define PCI_INTISR_REG (*(volatile uint32_t *)(intptr_t)(int32_t)0xbfe00= 13c) +#define PCI_CONFSPACE 0xbfe80000 +#define PCI_INTA 4 +#define PCI_INTB 5 +#define PCI_INTC 6 +#define PCI_INTD 7 +#define HANDLED_INTERRUPTS 0xf0 + +#define BONITO_IRQ 4 + +static void +bonito_identify(driver_t *drv, device_t parent) +{ + BUS_ADD_CHILD(parent, 0, "pcib", 0); +} + +static int +bonito_probe(device_t dev) +{ + if (device_get_unit(dev) !=3D 0) + return (ENXIO); + device_set_desc(dev, "Bonito Loongson PCI bridge"); + return (0); +} + +static void +bonito_intr(void *sc_in) +{ + struct intr_event *event; + int i; + struct bonito_softc *sc =3D sc_in; + + while ((i =3D fls(PCI_INTISR_REG & PCI_INTEN_REG & HANDLED_INTERRUPTS))= + !=3D 0) { + i--; /* Get a 0-offset interrupt. */ + PCI_INTENCLR_REG =3D (1 << i); + PCI_INTENSET_REG =3D (1 << i); + event =3D sc->intr_events[i]; + + if (!event || TAILQ_EMPTY(&event->ie_handlers)) { + printf("stray bonito interrupt %d\n", i); + continue; + } + + if (intr_event_handle(event, NULL) !=3D 0) { + printf("stray bonito interrupt %d\n", i); + } + } +} + +static int +bonito_attach(device_t dev) +{ + struct bonito_softc *sc; + int error; + + sc =3D device_get_softc(dev); + + mtx_init(&sc->config_mtx, "bonito_cfg", + "Bonito configuration space mutex", MTX_SPIN | MTX_QUIET); + + sc->sc_irq.rm_type =3D RMAN_ARRAY; + sc->sc_irq.rm_descr =3D "Bonito PCI IRQs"; + error =3D rman_init(&sc->sc_irq); + if (error !=3D 0) + return (error); + + error =3D rman_manage_region(&sc->sc_irq, 0, BONITO_NUM_INTS - 1); + if (error !=3D 0) + return (error); + + PCI_INTENCLR_REG =3D ~0; + PCI_INTPOL_REG =3D (1 << 12) | (1 << 11); + PCI_INTEDGE_REG =3D 0; + + memset (sc->intr_events, 0, sizeof (sc->intr_events)); + cpu_establish_hardintr ("Bonito interrupt", NULL, bonito_intr, sc, + BONITO_IRQ, INTR_TYPE_MISC, &sc->intr_cookie); + + sc->sc_io.rm_type =3D RMAN_ARRAY; + sc->sc_io.rm_descr =3D "Bonito PCI I/O Ports"; + error =3D rman_init(&sc->sc_io); + if (error !=3D 0) + return (error); + + error =3D rman_manage_region(&sc->sc_io, 0x0, 0x100000); + if (error !=3D 0) + return (error); + + sc->sc_mem.rm_type =3D RMAN_ARRAY; + sc->sc_mem.rm_descr =3D "Bonito PCI Memory"; + error =3D rman_init(&sc->sc_mem); + if (error !=3D 0) + return (error); + + (*(volatile uint32_t *) (intptr_t) (int32_t) 0xbfe00104) =3D 0; + (*(volatile uint32_t *) (intptr_t) (int32_t) 0xbfe00110) + =3D (0) | (1 << 6) | (2 << 12); + + error =3D rman_manage_region(&sc->sc_mem, 0x1000, 0xc000000); + if (error !=3D 0) + return (error); + + device_add_child(dev, "pci", 0); + + return (bus_generic_attach(dev)); +} + +static int +bonito_read_ivar(device_t dev, device_t child, int which, uintptr_t *res= ult) +{ + if (which =3D=3D PCIB_IVAR_DOMAIN || which =3D=3D PCIB_IVAR_BUS) + { + *result =3D 0; + return (0); + } + return (ENOENT); +} + +static int +bonito_maxslots(device_t dev) +{ + return 10; +} + +static uint32_t +bonito_read_config(device_t dev, u_int bus, u_int slot, u_int func, u_in= t reg, + int bytes) +{ + intptr_t addr; + uint32_t ret; + struct bonito_softc *sc; + + sc =3D device_get_softc(dev); + + addr =3D (int32_t) (PCI_CONFSPACE | (func << 8) | (reg & ~(bytes - 1)))= ; + + mtx_lock_spin(&sc->config_mtx); + PCI_CONF_CTRL_REG =3D (1 << slot); + + switch (bytes) { + case 4: + ret =3D *((volatile uint32_t *) addr); + break; + case 2: + ret =3D *((volatile uint16_t *) addr); + break; + case 1: + ret =3D *((volatile uint8_t *) addr); + break; + default: + ret =3D ((uint32_t)-1); + break; + } + mtx_unlock_spin(&sc->config_mtx); + return ret; +} + +static void +bonito_write_config(device_t dev, u_int bus, u_int slot, u_int func, + u_int reg, uint32_t data, int bytes) +{ + intptr_t addr; + struct bonito_softc *sc; + + sc =3D device_get_softc(dev); + + addr =3D (int32_t) (PCI_CONFSPACE | (func << 8) | (reg & ~(bytes - 1)))= ; + + mtx_lock_spin(&sc->config_mtx); + + PCI_CONF_CTRL_REG =3D (1 << slot); + + switch (bytes) { + case 4: + *((volatile uint32_t *) addr) =3D data; + break; + case 2: + *((volatile uint16_t *) addr) =3D data; + break; + case 1: + *((volatile uint8_t *) addr) =3D data; + break; + default: + break; + } + mtx_unlock_spin(&sc->config_mtx);=09 +} + +static struct resource * +bonito_alloc_resource(device_t bus, device_t child, int type, int *rid, + u_long start, u_long end, u_long count, u_int flags) +{ + struct bonito_softc *sc; + struct resource *res; + struct rman *rm; + int error; + + sc =3D device_get_softc(bus); + + switch (type) { + case SYS_RES_IRQ: + rm =3D &sc->sc_irq; + break; + case SYS_RES_MEMORY: + rm =3D &sc->sc_mem; + break; + case SYS_RES_IOPORT: + /* Low ports already have specific uses. Unless user=20 + explicitly asks for low port allocate from other range. */ + if (end >=3D 0x1000) + start =3D 0x1000; + rm =3D &sc->sc_io; + break; + default: + return (NULL); + } + + res =3D rman_reserve_resource(rm, start, end, count, flags, child); + if (res =3D=3D NULL) + return (NULL); + + rman_set_rid(res, *rid); + + switch (type) { + case SYS_RES_MEMORY: + rman_set_bustag(res, mips_bus_space_generic); + rman_set_bushandle(res, ((intptr_t)(int32_t)0xb0000000) + + rman_get_start(res)); + break; + case SYS_RES_IOPORT: + rman_set_bustag(res, mips_bus_space_generic); + rman_set_bushandle(res, ((intptr_t)(int32_t)0xbfd00000) + + rman_get_start(res)); + break; + } + + if ((flags & RF_ACTIVE) !=3D 0) { + error =3D bus_activate_resource(child, type, *rid, res); + if (error !=3D 0) { + rman_release_resource(res); + return (NULL); + } + } + + return (res); +} + +static int +bonito_activate_resource(device_t bus, device_t child, int type, int rid= , + struct resource *res) +{ + bus_space_handle_t bh; + int error; + + switch (type) { + case SYS_RES_IRQ: + break; + case SYS_RES_MEMORY: + case SYS_RES_IOPORT: + error =3D bus_space_map(rman_get_bustag(res), + rman_get_bushandle(res), rman_get_size(res), 0, &bh); + if (error !=3D 0) + return (error); + rman_set_bushandle(res, bh); + break; + default: + return (ENXIO); + } + + error =3D rman_activate_resource(res); + if (error !=3D 0) + return (error); + return (0); +} + +static void +bonito_mask_irq(void *source) +{ + uintptr_t irq =3D (uintptr_t)source; + + PCI_INTENCLR_REG =3D (1 << irq); +} + +static void +bonito_unmask_irq(void *source) +{ + uintptr_t irq =3D (uintptr_t)source; + + PCI_INTENSET_REG =3D (1 << irq); +} + +static int +bonito_setup_intr(device_t bus, device_t dev, struct resource *res, + int flags, driver_filter_t *filt, driver_intr_t *handler,=20 + void *arg, void **cookiep) +{ + struct bonito_softc *sc; + int irq; + struct intr_event *event; + int error; + + sc =3D device_get_softc(bus); + + irq =3D rman_get_start (res); + + if (irq < 0 || irq >=3D BONITO_NUM_INTS) + return ENXIO; + + event =3D sc->intr_events[irq]; + if (event =3D=3D NULL) { + error =3D intr_event_create(&event, (void *)(uintptr_t) irq, 0, + irq, bonito_mask_irq, bonito_unmask_irq, + NULL, NULL, "bonito_int%d:", irq); + if (error) + return 0; + sc->intr_events[irq] =3D event; + bonito_unmask_irq((void*)(uintptr_t) irq); + } + + intr_event_add_handler(event, device_get_nameunit(dev), + filt, handler, arg, intr_priority(flags), + flags, cookiep); + + return 0; +} + +static int +bonito_teardown_intr(device_t bus, device_t child, struct resource *res,= + void *cookie) +{ + struct bonito_softc *sc; + int irq; + struct intr_event *event; + + sc =3D device_get_softc(bus); + + irq =3D rman_get_start (res); + + if (irq < 0 || irq >=3D BONITO_NUM_INTS) + return (ENXIO); + + event =3D sc->intr_events[irq]; + + intr_event_remove_handler(cookie); + + if (TAILQ_EMPTY(&event->ie_handlers)) + bonito_mask_irq((void*)(uintptr_t)irq); + return 0; +} + +static int +bonito_route_interrupt(device_t bus, device_t child, int pin) +{ + /* Some strange Yeeloong routing? */ + switch (pci_get_slot (child)) + { + case 2: // Ethernet + return PCI_INTB; + case 4: // USB + return PCI_INTD; + default: + return pin + PCI_INTA - 1; + } +} + + +static device_method_t bonito_methods[] =3D { + /* Device interface */ + DEVMETHOD(device_identify, bonito_identify), + DEVMETHOD(device_probe, bonito_probe), + DEVMETHOD(device_attach, bonito_attach), + + /* Bus interface */ + DEVMETHOD(bus_read_ivar, bonito_read_ivar), + DEVMETHOD(bus_print_child, bus_generic_print_child), + DEVMETHOD(bus_alloc_resource, bonito_alloc_resource), + DEVMETHOD(bus_release_resource, bus_generic_release_resource), + DEVMETHOD(bus_activate_resource,bonito_activate_resource), + DEVMETHOD(bus_deactivate_resource,bus_generic_deactivate_resource), + DEVMETHOD(bus_setup_intr, bonito_setup_intr), + DEVMETHOD(bus_teardown_intr, bonito_teardown_intr), + + /* pcib interface */ + DEVMETHOD(pcib_maxslots, bonito_maxslots), + DEVMETHOD(pcib_read_config, bonito_read_config), + DEVMETHOD(pcib_write_config, bonito_write_config), + DEVMETHOD(pcib_route_interrupt, bonito_route_interrupt), + + {0, 0} +}; + +static driver_t bonito_driver =3D { + "pcib", + bonito_methods, + sizeof(struct bonito_softc), +}; +static devclass_t bonito_devclass; +DRIVER_MODULE(bonito_pci, nexus, bonito_driver, bonito_devclass, 0, 0); =3D=3D=3D added file 'mips/yeeloong/clock.c' --- mips/yeeloong/clock.c 1970-01-01 00:00:00 +0000 +++ mips/yeeloong/clock.c 2010-08-14 10:37:00 +0000 @@ -0,0 +1,98 @@ +/*- + * Copyright (c) 2003-2009 RMI Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in th= e + * documentation and/or other materials provided with the distributio= n. + * 3. Neither the name of RMI Corporation, nor the names of its contribu= tors, + * may be used to endorse or promote products derived from this softw= are + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AN= D + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE= + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PU= RPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIAB= LE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUE= NTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOO= DS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)= + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, S= TRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY= WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY O= F + * SUCH DAMAGE. + * + * RMI_BSD=20 + */ + + +#include /* RCS ID & Copyright macro defns */ +__FBSDID("$FreeBSD: src/sys/mips/rmi/clock.c,v 1.3 2010/04/17 01:17:31 j= mallett Exp $"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +extern uint64_t platform_counter_freq; + +void +DELAY(int n) +{ + uint32_t cur, last, delta, usecs; + uint64_t cycles_per_hz =3D platform_counter_freq / hz; + uint64_t cycles_per_usec; + + cycles_per_usec =3D counter_freq / (1 * 1000 * 1000); + /* + * This works by polling the timer and counting the number of + * microseconds that go by. + */ + last =3D platform_get_timecount(NULL); + delta =3D usecs =3D 0; + + while (n > usecs) { + cur =3D platform_get_timecount(NULL); + + /* Check to see if the timer has wrapped around. */ + if (cur < last) + delta +=3D (cur + (cycles_per_hz - last)); + else + delta +=3D (cur - last); + + last =3D cur; + + if (delta >=3D cycles_per_usec) { + usecs +=3D delta / cycles_per_usec; + delta %=3D cycles_per_usec; + } + } +} =3D=3D=3D added file 'mips/yeeloong/files.yeeloong' --- mips/yeeloong/files.yeeloong 1970-01-01 00:00:00 +0000 +++ mips/yeeloong/files.yeeloong 2010-08-15 21:43:50 +0000 @@ -0,0 +1,31 @@ +mips/yeeloong/uart_cpu_yeeloongusart.c optional uart +mips/yeeloong/obio.c optional uart +mips/yeeloong/uart_bus_yeeloongusart.c optional uart +dev/uart/uart_dev_ns8250.c optional uart +mips/yeeloong/yeeloong_machdep.c standard +mips/mips/tick.c standard +mips/mips/intr_machdep.c standard +x86/isa/atrtc.c standard +mips/yeeloong/bonito_pci.c optional pci +dev/atkbdc/atkbd.c optional atkbd atkbdc +dev/atkbdc/atkbd_atkbdc.c optional atkbd atkbdc +dev/atkbdc/atkbdc.c optional atkbdc +mips/yeeloong/atkbdc_yeeloong.c optional atkbdc +dev/atkbdc/atkbdc_subr.c optional atkbdc +dev/atkbdc/psm.c optional psm atkbdc +dev/kbd/kbd.c optional atkbd + +atkbdmap.h optional atkbd_dflt_keymap \ + compile-with "/usr/sbin/kbdcontrol -L ${ATKBD_DFLT_KEYMAP} | sed -e 's/= ^static keymap_t.* =3D /static keymap_t key_map =3D /' -e 's/^static acce= ntmap_t.* =3D /static accentmap_t accent_map =3D /' > atkbdmap.h" \ + no-obj no-implicit-rule before-depend \ + clean "atkbdmap.h" + + +dev/fb/mbvideo.c standard +dev/fb/fb.c standard +dev/syscons/syscons.c standard +dev/syscons/scmouse.c standard +dev/syscons/scvtb.c standard +mips/mips/sc_machdep.c standard +dev/syscons/scterm-teken.c standard +dev/cs5536/cs5536.c standard =3D=3D=3D added file 'mips/yeeloong/obio.c' --- mips/yeeloong/obio.c 1970-01-01 00:00:00 +0000 +++ mips/yeeloong/obio.c 2010-08-15 19:01:11 +0000 @@ -0,0 +1,193 @@ +/* $NetBSD: obio.c,v 1.11 2003/07/15 00:25:05 lukem Exp $ */ + +/*- + * Copyright (c) 2001, 2002, 2003 Wasabi Systems, Inc. + * All rights reserved. + * + * Written by Jason R. Thorpe for Wasabi Systems, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in th= e + * documentation and/or other materials provided with the distributio= n. + * 3. All advertising materials mentioning features or use of this softw= are + * must display the following acknowledgement: + * This product includes software developed for the NetBSD Project by + * Wasabi Systems, Inc. + * 4. The name of Wasabi Systems, Inc. may not be used to endorse + * or promote products derived from this software without specific pr= ior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTI= CULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, O= R + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSIN= ESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER = IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWIS= E) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED O= F THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * On-board device autoconfiguration support for Intel IQ80321 + * evaluation boards. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +int obio_probe(device_t); +int obio_attach(device_t); + +static void +obio_identify(driver_t * drv, device_t parent) +{ + BUS_ADD_CHILD(parent, 0, "obio", 0); +} + +int +obio_probe(device_t dev) +{ + if (device_get_unit(dev) !=3D 0) + return (ENXIO); + device_set_desc(dev, "obio"); + return (0); +} + +int +obio_attach(device_t dev) +{ + struct obio_softc *sc =3D device_get_softc(dev); + + sc->oba_st =3D mips_bus_space_generic; + sc->oba_addr =3D (intptr_t)(int32_t)0xbff003f8; + sc->oba_size =3D 0x8; + sc->oba_rman.rm_type =3D RMAN_ARRAY; + sc->oba_rman.rm_descr =3D "OBIO I/O"; + if (rman_init(&sc->oba_rman) !=3D 0 || + rman_manage_region(&sc->oba_rman, + sc->oba_addr, sc->oba_addr + sc->oba_size) !=3D 0) + panic("obio_attach: failed to set up I/O rman"); + + /*=20 + * This module is intended for UART purposes only and + * it's IRQ is 1 + */ + sc->oba_irq_rman.rm_type =3D RMAN_ARRAY; + sc->oba_irq_rman.rm_descr =3D "OBIO IRQ"; + if (rman_init(&sc->oba_irq_rman) !=3D 0 || + rman_manage_region(&sc->oba_irq_rman, 1, 1) !=3D 0) + panic("obio_attach: failed to set up IRQ rman"); + + device_add_child(dev, "uart", 0); + bus_generic_probe(dev); + bus_generic_attach(dev); + + return (0); +} + +static struct resource * +obio_alloc_resource(device_t bus, device_t child, int type, int *rid, + u_long start, u_long end, u_long count, u_int flags) +{ + struct resource *rv; + struct rman *rm; + bus_space_tag_t bt =3D 0; + bus_space_handle_t bh =3D 0; + struct obio_softc *sc =3D device_get_softc(bus); + + switch (type) { + case SYS_RES_IRQ: + rm =3D &sc->oba_irq_rman; + break; + case SYS_RES_MEMORY: + return (NULL); + case SYS_RES_IOPORT: + rm =3D &sc->oba_rman; + bt =3D sc->oba_st; + bh =3D sc->oba_addr; + start =3D bh; + break; + default: + return (NULL); + } + + + rv =3D rman_reserve_resource(rm, start, end, count, flags, child); + if (rv =3D=3D NULL)=20 + return (NULL); + if (type =3D=3D SYS_RES_IRQ) + return (rv); + rman_set_rid(rv, *rid); + rman_set_bustag(rv, bt); + rman_set_bushandle(rv, bh); +=09 + if (0) { + if (bus_activate_resource(child, type, *rid, rv)) { + rman_release_resource(rv); + return (NULL); + } + } + return (rv); + +} + +static int +obio_activate_resource(device_t bus, device_t child, int type, int rid, + struct resource *r) +{ + return (0); +} + +static int +obio_release_resource(device_t bus, device_t child, int type, int rid, + struct resource *r) +{ + if (type !=3D SYS_RES_IOPORT) + return (bus_generic_release_resource(bus, child, type, rid, r)); + + return (rman_release_resource(r)); +} + +static device_method_t obio_methods[] =3D { + DEVMETHOD(device_identify, obio_identify), + DEVMETHOD(device_probe, obio_probe), + DEVMETHOD(device_attach, obio_attach), + + DEVMETHOD(bus_alloc_resource, obio_alloc_resource), + DEVMETHOD(bus_release_resource, obio_release_resource), + DEVMETHOD(bus_activate_resource, obio_activate_resource), + DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), + DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), + + {0, 0}, +}; + +static driver_t obio_driver =3D { + "obio", + obio_methods, + sizeof(struct obio_softc), +}; +static devclass_t obio_devclass; + +DRIVER_MODULE(obio, nexus, obio_driver, obio_devclass, 0, 0); =3D=3D=3D added file 'mips/yeeloong/std.yeeloong' --- mips/yeeloong/std.yeeloong 1970-01-01 00:00:00 +0000 +++ mips/yeeloong/std.yeeloong 2010-08-15 02:58:22 +0000 @@ -0,0 +1,45 @@ +# $FreeBSD: src/sys/mips/adm5120/files.adm5120,v 1.1.2.1.2.1 2009/10/25 = 01:10:29 kensmith Exp $ + +files "../yeeloong/files.yeeloong" + +cpu CPU_MIPS32 +ident YEELOONG + +# XXX: These two options must be defined in MIPS kernel configs. +makeoptions MIPS_LITTLE_ENDIAN=3Ddefined +makeoptions ARCH_FLAGS=3D"-march=3Dmips3 -DTARGET_YEELOONG=3D1" +makeoptions LDSCRIPT_NAME=3D ldscript.mips +makeoptions KERNLOADADDR=3D0x80100000 + + +options ISA_MIPS32 + +options FB_INSTALL_CDEV + +device pci +device ohci # OHCI PCI->USB interface +device ehci # EHCI PCI->USB interface (USB 2.0) +device usb # USB Bus (required) +device umass # Disks/Mass storage - Requires scbus and da +device scbus # SCSI bus (required for SCSI) +device ch # SCSI media changers +device da # Direct Access (disks) +device sa # Sequential Access (tape etc) +device cd # CD +device pass # Passthrough device (direct SCSI access) +device ses # SCSI Environmental Services (and SAF-TE) + +options FFS #Berkeley Fast Filesystem +options SOFTUPDATES #Enable FFS soft updates support +options UFS_ACL #Support for access control lists +options UFS_DIRHASH #Improve performance on big directories + +# atkbdc0 controls both the keyboard and the PS/2 mouse +device atkbdc # AT keyboard controller +device atkbd # AT keyboard +device psm # PS/2 mouse + +device sc +device rl +device miibus + =3D=3D=3D added file 'mips/yeeloong/uart_bus_yeeloongusart.c' --- mips/yeeloong/uart_bus_yeeloongusart.c 1970-01-01 00:00:00 +0000 +++ mips/yeeloong/uart_bus_yeeloongusart.c 2010-08-16 16:46:03 +0000 @@ -0,0 +1,102 @@ +/*- + * Copyright (c) 2006 Wojciech A. Koszek + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in th= e + * documentation and/or other materials provided with the distributio= n. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AN= D + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE= + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PU= RPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIAB= LE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUE= NTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOO= DS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)= + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, S= TRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY= WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY O= F + * $Id$ + */ +/* + * Skeleton of this file was based on respective code for ARM + * code written by Olivier Houchard. + */ + +/* + * XXXMIPS: This file is hacked from arm/... . XXXMIPS here means this f= ile is + * experimental and was written for MIPS32 port. + */ +#include "opt_uart.h" + +#include +__FBSDID("$FreeBSD: src/sys/mips/malta/uart_bus_maltausart.c,v 1.2.2.1.2= =2E1 2009/10/25 01:10:29 kensmith Exp $"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +static int uart_yeeloong_probe(device_t dev); + +extern struct uart_class uart_yeeloong_class; + +static device_method_t uart_yeeloong_methods[] =3D { + /* Device interface */ + DEVMETHOD(device_probe, uart_yeeloong_probe), + DEVMETHOD(device_attach, uart_bus_attach), + DEVMETHOD(device_detach, uart_bus_detach), + { 0, 0 } +}; + +static driver_t uart_yeeloong_driver =3D { + uart_driver_name, + uart_yeeloong_methods, + sizeof(struct uart_softc), +}; + +extern SLIST_HEAD(uart_devinfo_list, uart_devinfo) uart_sysdevs; +static int +uart_yeeloong_probe(device_t dev) +{ + struct uart_softc *sc; + static int probed =3D 0; + + if (device_get_unit(dev) !=3D 0 || probed) + return (ENXIO); + probed =3D 1; + + sc =3D device_get_softc(dev); + sc->sc_sysdev =3D SLIST_FIRST(&uart_sysdevs); + sc->sc_class =3D &uart_ns8250_class; + if (sc->sc_sysdev) + { + bcopy(&sc->sc_sysdev->bas, &sc->sc_bas, sizeof(sc->sc_bas)); + sc->sc_sysdev->bas.bst =3D mips_bus_space_generic; + sc->sc_sysdev->bas.bsh =3D (intptr_t) (int32_t) 0xbff003f8; + sc->sc_sysdev->bas.rclk =3D 1843200 * 2; + } + sc->sc_bas.bst =3D mips_bus_space_generic; + sc->sc_bas.bsh =3D (intptr_t) (int32_t) 0xbff003f8; + sc->sc_bas.rclk =3D 1843200 * 2; + + return(uart_bus_probe(dev, 0, 1843200 * 2, 0, 0)); +} + +DRIVER_MODULE(uart, obio, uart_yeeloong_driver, uart_devclass, 0, 0); =3D=3D=3D added file 'mips/yeeloong/uart_cpu_yeeloongusart.c' --- mips/yeeloong/uart_cpu_yeeloongusart.c 1970-01-01 00:00:00 +0000 +++ mips/yeeloong/uart_cpu_yeeloongusart.c 2010-08-14 10:37:00 +0000 @@ -0,0 +1,97 @@ +/*- + * Copyright (c) 2006 Wojciech A. Koszek + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in th= e + * documentation and/or other materials provided with the distributio= n. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AN= D + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE= + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PU= RPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIAB= LE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUE= NTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOO= DS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)= + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, S= TRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY= WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY O= F + * SUCH DAMAGE. + * + * $Id$ + */ +/* + * Skeleton of this file was based on respective code for ARM + * code written by Olivier Houchard. + */ +/* + * XXXMIPS: This file is hacked from arm/... . XXXMIPS here means this f= ile is + * experimental and was written for MIPS32 port. + */ +#include "opt_uart.h" +#include "opt_cputype.h" + +#include +__FBSDID("$FreeBSD: src/sys/mips/malta/uart_cpu_maltausart.c,v 1.2.2.1.2= =2E1 2009/10/25 01:10:29 kensmith Exp $"); + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +bus_space_tag_t uart_bus_space_io; +bus_space_tag_t uart_bus_space_mem; + +extern struct uart_ops malta_usart_ops; +extern struct bus_space malta_bs_tag; + +int +uart_cpu_eqres(struct uart_bas *b1, struct uart_bas *b2) +{ + return ((b1->bsh =3D=3D b2->bsh && b1->bst =3D=3D b2->bst) ? 1 : 0); +} + +int +uart_cpu_getdev(int devtype, struct uart_devinfo *di) +{ + di->ops =3D uart_getops(&uart_ns8250_class); + di->bas.chan =3D 0; + di->bas.bst =3D mips_bus_space_generic; + di->bas.regshft =3D 0; + di->bas.rclk =3D 1843200 * 2; + di->baudrate =3D 115200; + di->databits =3D 8; + di->stopbits =3D 1; + di->parity =3D UART_PARITY_NONE; + + uart_bus_space_io =3D (void *) (intptr_t) (int32_t) 0xbff003f8; + uart_bus_space_mem =3D (void *) (intptr_t) (int32_t) 0xbff003f8; + di->bas.bsh =3D (intptr_t) (int32_t) 0xbff003f8; + return (0); +} =3D=3D=3D added file 'mips/yeeloong/yeeloong_machdep.c' --- mips/yeeloong/yeeloong_machdep.c 1970-01-01 00:00:00 +0000 +++ mips/yeeloong/yeeloong_machdep.c 2010-08-16 22:05:20 +0000 @@ -0,0 +1,472 @@ +/*- + * Copyright (C) 2007 by Oleksandr Tymoshenko. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in th= e + * documentation and/or other materials provided with the distributio= n. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRAN= TIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIME= D. + * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIREC= T, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTI= ON) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING= + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +__FBSDID("$FreeBSD: src/sys/mips/adm5120/adm5120_machdep.c,v 1.2.2.1.2.1= 2009/10/25 01:10:29 kensmith Exp $"); + +#include "opt_ddb.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../mips/multiboot2.h" + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#if defined(__sparc64__) || defined(__powerpc__) || defined (__mips) +#include +#else +#include +#endif +#if defined( __i386__) || defined(__amd64__) +#include +#include +#endif +#include + +#include +#include +#include + +#include + +#include +#include +#define SYNC __asm volatile("sync") + + +extern int *edata; +extern int *end; + +static void +mips_init(void) +{ + printf("entry: mips_init()\n"); + + init_param1(); + + init_param2(physmem); + mips_cpu_init(); + pmap_bootstrap(); + mips_proc0_init(); + mutex_init(); +#ifdef DDB + kdb_init(); +#endif +} + +#define EC_MAGIC_PORT1 *((volatile uint8_t *) (intptr_t) (int32_t) 0xbfd= 00381) +#define EC_MAGIC_PORT2 *((volatile uint8_t *) (intptr_t) (int32_t) 0xbfd= 00382) +#define EC_DATA_PORT *((volatile uint8_t *) (intptr_t) (int32_t) 0xbfd00= 383) + +#define EC_MAGIC_VAL1 0xf4 +#define EC_MAGIC_VAL2 0xec + +#define EC_COMMAND_REBOOT 1 + +#define LOONGSON_GPIOCFG *((volatile uint8_t *) (intptr_t) (int32_t) 0xb= fe00120) +#define LOONGSON_SHUTDOWN_GPIO 1 + +static inline void +write_ec (uint8_t value) +{ + EC_MAGIC_PORT1 =3D EC_MAGIC_VAL1; + EC_MAGIC_PORT2 =3D EC_MAGIC_VAL2; + EC_DATA_PORT =3D value; +} + + +void +platform_halt(void) +{ + LOONGSON_GPIOCFG &=3D ~LOONGSON_SHUTDOWN_GPIO; +} + + +void +platform_identify(void) +{ + +} + +void +platform_reset(void) +{ + write_ec (EC_COMMAND_REBOOT); +} + +void +platform_trap_enter(void) +{ + +} + +void +platform_trap_exit(void) +{ + +} + +void +platform_cpu_init (void) +{ + +} + +static char kenv_buf[8192]; + +#include "../../dev/fb/mbfb.h" + +int fb_found =3D 0; + +struct mbvid_params mbvid_params; +struct mtx clock_lock; + +static void +parse_multiboot (__register_t a0, __register_t a1) +{ + struct multiboot_tag *tag; + if (a0 !=3D MULTIBOOT2_BOOTLOADER_MAGIC) + return; + tag =3D (struct multiboot_tag *) (a1 + 8); + for (; tag->type !=3D MULTIBOOT_TAG_TYPE_END; + tag =3D (void *) ((uint8_t *) tag + ((tag->size + 7) & ~7))) + { + switch (tag->type) + { + case MULTIBOOT_TAG_TYPE_CMDLINE: + { + struct multiboot_tag_string *tagt =3D (void *) tag; + char *ptr =3D tagt->string; + init_static_kenv (kenv_buf, sizeof (kenv_buf)); + while (*ptr) + { + char *ptr1, *ptr2, c1, c2; + while (*ptr =3D=3D ' ') + ptr++; + ptr1 =3D ptr; + while (*ptr && *ptr !=3D '=3D' && *ptr !=3D ' ') + ptr++; + if (*ptr !=3D '=3D') + { + if (sizeof ("verbose") - 1 =3D=3D ptr - ptr1 + && memcmp (ptr1, "verbose", + sizeof ("verbose") - 1) + =3D=3D 0) + boothowto |=3D RB_VERBOSE; + if (*ptr1 =3D=3D '-') + { + for (ptr1++; ptr1 < ptr; ptr1++) + switch (*ptr1) + { + case 'v': + boothowto |=3D RB_VERBOSE; + break; + case 'D': + boothowto |=3D RB_MULTIPLE; + break; + case 'h': + boothowto |=3D RB_SERIAL; + } + } + continue; + } + ptr2 =3D ptr; + while (*ptr && *ptr !=3D ' ') + ptr++; + c1 =3D *ptr2; + c2 =3D *ptr; + *ptr2 =3D 0; + *ptr =3D 0; + =09 + setenv (ptr1, ptr2 + 1); + *ptr2 =3D c1; + *ptr =3D c2; + } + } + break; + case MULTIBOOT_TAG_TYPE_MMAP: + { + struct multiboot_tag_mmap *tagt =3D (void *) tag; + struct multiboot_mmap_entry *entry; + vm_offset_t memstart; + int i, cur =3D 0; + uint64_t totalmem =3D 0; + memstart =3D ((((vm_offset_t)&end) + 0xfffff) + & 0x1ff00000); + for (i =3D 0; i < 10; i++) { + phys_avail[i] =3D 0; + } + + for (entry =3D tagt->entries; + (uint8_t *) entry - (uint8_t *) tag < tag->size + && cur < 10; + entry =3D (void *) ((uint8_t *) entry + + tagt->entry_size)) + { + uint64_t start, end; + if (entry->type !=3D MULTIBOOT_MEMORY_AVAILABLE) + continue; + start =3D entry->addr; + end =3D entry->addr + entry->len; + + if (start < memstart) + start =3D memstart; + /* FIXME: support post-256MiB memory. */ + if (end > 0x10000000) + end =3D 0x10000000; + + if (start >=3D end) + continue; + + totalmem +=3D end - start; + + /* phys_avail regions are in bytes */ + phys_avail[cur] =3D start; + phys_avail[cur + 1] =3D end; + cur +=3D 2; + } + realmem =3D btoc(totalmem); + physmem =3D realmem; + + } + break; + case MULTIBOOT_TAG_TYPE_FRAMEBUFFER: + { + struct multiboot_tag_framebuffer *tagt + =3D (void *) tag; + int window; + unsigned offset; + unsigned window_start_addr; + +// if (tagt->common.framebuffer_addr < 0xffffffffb0000000 + // || tagt->common.framebuffer_addr >=3D 0xffffffffbc000000) + //break; + + if (tagt->common.framebuffer_type !=3D MULTIBOOT_FRAMEBUFFER_TYPE_RGB= ) + break; + + offset =3D tagt->common.framebuffer_addr & 0x3ffffff; + window =3D (tagt->common.framebuffer_addr >> 26) & 0x3; + + mbvid_params.width =3D tagt->common.framebuffer_width; + mbvid_params.height =3D tagt->common.framebuffer_height; +#if 0 + mbvidadapter.va_info.vi_depth =3D tagt->common.framebuffer_bpp; + mbvidadapter.va_info.vi_pixel_size =3D (tagt->common.framebuffer_bpp = + 7) / 8; + mbvidadapter.va_info.vi_pixel_fields[0] =3D tagt->color.direct.frameb= uffer_red_field_position; + mbvidadapter.va_info.vi_pixel_fsizes[0] =3D tagt->color.direct.frameb= uffer_red_mask_size; + mbvidadapter.va_info.vi_pixel_fields[1] =3D tagt->color.direct.frameb= uffer_green_field_position; + mbvidadapter.va_info.vi_pixel_fsizes[1] =3D tagt->color.direct.frameb= uffer_green_mask_size; + mbvidadapter.va_info.vi_pixel_fields[2] =3D tagt->color.direct.frameb= uffer_blue_field_position; + mbvidadapter.va_info.vi_pixel_fsizes[2] =3D tagt->color.direct.frameb= uffer_blue_mask_size; +#endif + window_start_addr =3D ((*(volatile uint32_t *) (intptr_t) (int32_t) 0= xbfe00110) >> (6 * window)) & 0x3f; + if (window_start_addr >=3D 3) + break; + window_start_addr <<=3D 26; + mbvid_params.ptr =3D + (void *) (((intptr_t) (int32_t) 0xb0000000) + | window_start_addr | offset); +#if 0 + mbvidadapter.va_mem_size =3D tagt->common.framebuffer_pitch + * tagt->common.framebuffer_height; + mbvidadapter.va_line_width =3D tagt->common.framebuffer_pitch; + mbvidadapter.va_info.vi_window =3D mbvidadapter.va_mem_base & 0x1ffff= fff; + mbvidadapter.va_info.vi_window_size =3D mbvidadapter.va_mem_size; +#endif + + fb_found =3D 1; + } + } + } +} + +void +platform_start(__register_t a0, __register_t a1,=20 + __register_t a2 __unused, __register_t a3 __unused) +{ + /* FIXME: retrieve from multiboot2 info. */ + uint64_t platform_counter_freq =3D 400 * 1000 * 1000; + + { + vm_offset_t va, eva; + va =3D MIPS_PHYS_TO_KSEG0(0); + eva =3D va + 0x8000; + =09 + while (va < eva) { + cache_r4k_op_32lines_32(va, + CACHE_R4K_D|CACHEOP_R4K_INDEX_WB_INV); + cache_r4k_op_32lines_32(va + 1, + CACHE_R4K_D|CACHEOP_R4K_INDEX_WB_INV); + cache_r4k_op_32lines_32(va + 2, + CACHE_R4K_D|CACHEOP_R4K_INDEX_WB_INV); + cache_r4k_op_32lines_32(va + 3, + CACHE_R4K_D|CACHEOP_R4K_INDEX_WB_INV); + va +=3D (32 * 32); + } + =09 + SYNC; + } + + { + vm_offset_t va, eva; + + va =3D MIPS_PHYS_TO_KSEG0(0); + eva =3D va + 0x80000; + =09 + while (va < eva) { + cache_r4k_op_32lines_32(va, + CACHE_R4K_SD|CACHEOP_R4K_INDEX_WB_INV); + cache_r4k_op_32lines_32(va + 1, + CACHE_R4K_SD|CACHEOP_R4K_INDEX_WB_INV); + cache_r4k_op_32lines_32(va + 2, + CACHE_R4K_SD|CACHEOP_R4K_INDEX_WB_INV); + cache_r4k_op_32lines_32(va + 3, + CACHE_R4K_SD|CACHEOP_R4K_INDEX_WB_INV); + va +=3D (32 * 32); + } + =09 + SYNC; + } + + mips_pcpu0_init(); + mips_timer_early_init (platform_counter_freq); + + boothowto =3D 0; + + parse_multiboot (a0, a1); + + (*(volatile uint32_t *) (intptr_t) (int32_t) 0xbfe00110) + =3D (0) | (1 << 6) | (2 << 12); + + attach_mbvid (); +=09 + cninit(); + + mtx_init(&clock_lock, "clk", NULL, MTX_SPIN | MTX_NOPROFILE); +=09 + bootverbose =3D !!(boothowto & RB_VERBOSE); + + mips_init(); + mips_timer_init_params(platform_counter_freq, 0); +} + +static void +sc_identify(driver_t* driver, device_t parent) +{ + BUS_ADD_CHILD(parent, 0, "mbvid", 0); +} + +static int +sc_probe(device_t dev) +{ + device_set_desc(dev, "Mbvid console"); + return (sc_probe_unit(device_get_unit(dev), device_get_flags(dev) | SC_= AUTODETECT_KBD)); +} + +static int sc_attach(device_t dev) +{ + return (sc_attach_unit(device_get_unit(dev), device_get_flags(dev) | SC= _AUTODETECT_KBD)); +} + +static device_method_t sc_methods[] =3D { + /* Device interface */ + DEVMETHOD(device_identify, sc_identify), + DEVMETHOD(device_probe, sc_probe), + DEVMETHOD(device_attach, sc_attach), + { 0, 0 } +}; + +static driver_t mbvid_sc_driver =3D { + "mbvid", + sc_methods, + sizeof(sc_softc_t) +}; + +static devclass_t sc_devclass; + +DRIVER_MODULE(sc, nexus, mbvid_sc_driver, sc_devclass, 0, 0); =3D=3D=3D modified file 'sys/fbio.h' --- sys/fbio.h 2010-08-13 22:16:49 +0000 +++ sys/fbio.h 2010-08-14 21:18:26 +0000 @@ -86,7 +86,9 @@ #define FBTYPE_TCXCOLOR 29 /* SUNW,tcx */ #define FBTYPE_CREATOR 30 =20 -#define FBTYPE_LASTPLUSONE 31 /* max number of fbs (change as add) */ +#define FBTYPE_MBFB 31 + +#define FBTYPE_LASTPLUSONE 32 /* max number of fbs (change as add) */ =20 /* * Frame buffer descriptor as returned by FBIOGTYPE. @@ -315,6 +317,7 @@ #define KD_PC98 6 /* PC-98 display */ #define KD_TGA 7 /* TGA */ #define KD_TGA2 8 /* TGA2 */ +#define KD_MULTIBOOT 9 /* multiboot2 linear fb */ char *va_name; int va_unit; int va_minor; =3D=3D=3D modified file 'x86/isa/atrtc.c' --- x86/isa/atrtc.c 2010-08-13 22:16:49 +0000 +++ x86/isa/atrtc.c 2010-08-15 03:56:28 +0000 @@ -65,6 +65,39 @@ * RTC support routines */ =20 +#ifdef TARGET_YEELOONG + +#define ADDR_PORT *(volatile uint8_t *) ((intptr_t) (int32_t) 0xbfd00070= ) +#define DATA_PORT *(volatile uint8_t *) ((intptr_t) (int32_t) 0xbfd00071= ) + +int +rtcin(int reg) +{ + u_char val; + + RTC_LOCK; + if (rtc_reg !=3D reg) { + ADDR_PORT =3D reg; + rtc_reg =3D reg; + } + val =3D DATA_PORT; + RTC_UNLOCK; + return (val); +} + +void +writertc(int reg, u_char val) +{ + + RTC_LOCK; + if (rtc_reg !=3D reg) { + ADDR_PORT =3D reg; + rtc_reg =3D reg; + } + DATA_PORT =3D val; + RTC_UNLOCK; +} +#else int rtcin(int reg) { @@ -97,9 +130,10 @@ inb(0x84); RTC_UNLOCK; } +#endif =20 static __inline int -readrtc(int port) +readrtcbcd(int port) { return(bcd2bin(rtcin(port))); } @@ -112,6 +146,7 @@ writertc(RTC_STATUSB, RTCSB_24HR); } =20 +#ifndef TARGET_YEELOONG static void atrtc_rate(unsigned rate) { @@ -137,6 +172,7 @@ writertc(RTC_STATUSB, rtc_statusb); rtcin(RTC_INTR); } +#endif =20 void atrtc_restore(void) @@ -162,6 +198,7 @@ struct eventtimer et; }; =20 +#ifndef TARGET_YEELOONG static int rtc_start(struct eventtimer *et, struct bintime *first, struct bintime *period) @@ -223,6 +260,11 @@ { 0 } }; =20 +#endif + + +#ifndef TARGET_YEELOONG + static int atrtc_probe(device_t dev) { @@ -237,26 +279,49 @@ return (result); } =20 +#else + +static void +atrtc_identify(driver_t * drv, device_t parent) +{ + BUS_ADD_CHILD(parent, 0, "atrtc", 0); +} + +static int +atrtc_probe(device_t dev) +{ + if (device_get_unit(dev) !=3D 0) + return (ENXIO); + device_set_desc(dev, "AT realtime clock"); + return (0); +} +#endif + + static int atrtc_attach(device_t dev) { struct atrtc_softc *sc; - u_long s; - int i, diag; + int diag; =20 sc =3D device_get_softc(dev); +#ifndef TARGET_YEELOONG if (!(sc->port_res =3D bus_alloc_resource(dev, SYS_RES_IOPORT, &sc->port_rid, IO_RTC, IO_RTC + 1, 2, RF_ACTIVE))) device_printf(dev,"Warning: Couldn't map I/O.\n"); +#endif diag =3D rtcin(RTC_DIAG); if (diag !=3D 0) printf("RTC BIOS diagnostic error %b\n", diag, RTCDG_BITS); atrtc_start(); clock_register(dev, 1000000); bzero(&sc->et, sizeof(struct eventtimer)); +#ifndef TARGET_YEELOONG if (!atrtcclock_disable && (resource_int_value(device_get_name(dev), device_get_unit(dev), "clock", &i) !=3D 0 || i !=3D 0)) { + int i; + u_long s; sc->intr_rid =3D 0; while (bus_get_resource(dev, SYS_RES_IRQ, sc->intr_rid, &s, NULL) =3D=3D 0 && s !=3D 8) @@ -288,14 +353,16 @@ sc->et.et_priv =3D dev; et_register(&sc->et); } +#endif return(0); } =20 static int atrtc_resume(device_t dev) { - +#ifndef TARGET_YEELOONG atrtc_restore(); +#endif return(0); } =20 @@ -309,17 +376,34 @@ /* Disable RTC updates and interrupts. */ writertc(RTC_STATUSB, RTCSB_HALT | RTCSB_24HR); =20 - writertc(RTC_SEC, bin2bcd(ct.sec)); /* Write back Seconds */ - writertc(RTC_MIN, bin2bcd(ct.min)); /* Write back Minutes */ - writertc(RTC_HRS, bin2bcd(ct.hour)); /* Write back Hours */ - - writertc(RTC_WDAY, ct.dow + 1); /* Write back Weekday */ - writertc(RTC_DAY, bin2bcd(ct.day)); /* Write back Day */ - writertc(RTC_MONTH, bin2bcd(ct.mon)); /* Write back Month *= / - writertc(RTC_YEAR, bin2bcd(ct.year % 100)); /* Write back Year */ -#ifdef USE_RTC_CENTURY - writertc(RTC_CENTURY, bin2bcd(ct.year / 100)); /* ... and Century */= -#endif + if (rtcin (RTC_STATUSB) & RTCSB_BINARY) + { + writertc(RTC_SEC, ct.sec); /* Write back Seconds */ + writertc(RTC_MIN, ct.min); /* Write back Minutes */ + writertc(RTC_HRS, ct.hour); /* Write back Hours */ + =09 + writertc(RTC_WDAY, ct.dow + 1); /* Write back Weekday */ + writertc(RTC_DAY, ct.day); /* Write back Day */ + writertc(RTC_MONTH, ct.mon); /* Write back Month */ + writertc(RTC_YEAR, (ct.year % 100)); /* Write back Year */ +#ifdef USE_RTC_CENTURY + writertc(RTC_CENTURY, (ct.year / 100)); /* ... and Century */ +#endif + } + else + { + writertc(RTC_SEC, bin2bcd(ct.sec)); /* Write back Seconds */ + writertc(RTC_MIN, bin2bcd(ct.min)); /* Write back Minutes */ + writertc(RTC_HRS, bin2bcd(ct.hour)); /* Write back Hours */ + =09 + writertc(RTC_WDAY, ct.dow + 1); /* Write back Weekday */ + writertc(RTC_DAY, bin2bcd(ct.day)); /* Write back Day */ + writertc(RTC_MONTH, bin2bcd(ct.mon)); /* Write back Month = */ + writertc(RTC_YEAR, bin2bcd(ct.year % 100)); /* Write back Year */ +#ifdef USE_RTC_CENTURY + writertc(RTC_CENTURY, bin2bcd(ct.year / 100)); /* ... and Century *= / +#endif + } =20 /* Reenable RTC updates and interrupts. */ writertc(RTC_STATUSB, rtc_statusb); @@ -346,19 +430,39 @@ splx(s); s =3D splhigh(); } - ct.nsec =3D 0; - ct.sec =3D readrtc(RTC_SEC); - ct.min =3D readrtc(RTC_MIN); - ct.hour =3D readrtc(RTC_HRS); - ct.day =3D readrtc(RTC_DAY); - ct.dow =3D readrtc(RTC_WDAY) - 1; - ct.mon =3D readrtc(RTC_MONTH); - ct.year =3D readrtc(RTC_YEAR); -#ifdef USE_RTC_CENTURY - ct.year +=3D readrtc(RTC_CENTURY) * 100; -#else - ct.year +=3D 2000; -#endif + + if (rtcin (RTC_STATUSB) & RTCSB_BINARY) + { + ct.nsec =3D 0; + ct.sec =3D rtcin(RTC_SEC); + ct.min =3D rtcin(RTC_MIN); + ct.hour =3D rtcin(RTC_HRS); + ct.day =3D rtcin(RTC_DAY); + ct.dow =3D rtcin(RTC_WDAY) - 1; + ct.mon =3D rtcin(RTC_MONTH); + ct.year =3D rtcin(RTC_YEAR); +#ifdef USE_RTC_CENTURY + ct.year +=3D rtcin(RTC_CENTURY) * 100; +#else + ct.year +=3D 2000; +#endif + } + else + { + ct.nsec =3D 0; + ct.sec =3D readrtcbcd(RTC_SEC); + ct.min =3D readrtcbcd(RTC_MIN); + ct.hour =3D readrtcbcd(RTC_HRS); + ct.day =3D readrtcbcd(RTC_DAY); + ct.dow =3D readrtcbcd(RTC_WDAY) - 1; + ct.mon =3D readrtcbcd(RTC_MONTH); + ct.year =3D readrtcbcd(RTC_YEAR); +#ifdef USE_RTC_CENTURY + ct.year +=3D readrtcbcd(RTC_CENTURY) * 100; +#else + ct.year +=3D 2000; +#endif + } /* Set dow =3D -1 because some clocks don't set it correctly. */ ct.dow =3D -1; return (clock_ct_to_ts(&ct, ts)); @@ -366,6 +470,7 @@ =20 static device_method_t atrtc_methods[] =3D { /* Device interface */ + DEVMETHOD(device_identify, atrtc_identify), DEVMETHOD(device_probe, atrtc_probe), DEVMETHOD(device_attach, atrtc_attach), DEVMETHOD(device_detach, bus_generic_detach), @@ -389,8 +494,13 @@ =20 static devclass_t atrtc_devclass; =20 +#ifndef TARGET_YEELOONG DRIVER_MODULE(atrtc, isa, atrtc_driver, atrtc_devclass, 0, 0); DRIVER_MODULE(atrtc, acpi, atrtc_driver, atrtc_devclass, 0, 0); +#else +DRIVER_MODULE(atrtc, nexus, atrtc_driver, atrtc_devclass, 0, 0); +#endif + =20 #include "opt_ddb.h" #ifdef DDB --------------040307070901010105060107-- --------------enig7C782B83CD85D5ED0E2C2328 Content-Type: application/pgp-signature; name="signature.asc" Content-Description: OpenPGP digital signature Content-Disposition: attachment; filename="signature.asc" -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.10 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iF4EAREKAAYFAkxp0d4ACgkQNak7dOguQgklmwD/TxdD13GiWJylX6znbzrPGL4Z Qm49qunLsZuohXI8oEkA/1lr9aWaHPvcwpyfnyH6LMduCaLOqgoaYUiv1ToitKSa =1N7P -----END PGP SIGNATURE----- --------------enig7C782B83CD85D5ED0E2C2328--