=== modified file 'cam/cam_xpt.c' --- cam/cam_xpt.c 2010-08-13 22:16:49 +0000 +++ cam/cam_xpt.c 2010-08-13 22:20:49 +0000 @@ -816,6 +816,9 @@ return 0; } +static struct root_hold_token *xpt_rool_hold = NULL; +static int rescan_counter = 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) == 1) + { + root_mount_rel (xpt_rool_hold); + xpt_rool_hold = NULL; + } } /* thread to handle bus rescans */ @@ -861,6 +869,11 @@ { struct ccb_hdr *hdr; + if (atomic_fetchadd_int (&rescan_counter, 1) == 0) + { + xpt_rool_hold = root_mount_hold("XPT bus rescan"); + } + /* Prepare request */ if (ccb->ccb_h.path->target->target_id == CAM_TARGET_WILDCARD && ccb->ccb_h.path->device->lun_id == CAM_LUN_WILDCARD) === modified file 'conf/ldscript.mips' --- conf/ldscript.mips 2010-08-13 22:16:49 +0000 +++ conf/ldscript.mips 2010-08-14 11:21:21 +0000 @@ -44,6 +44,7 @@ { /* Read-only sections, merged into text segment: */ . = 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) } === modified file 'conf/ldscript.mips.mips64' --- conf/ldscript.mips.mips64 2010-08-13 22:16:49 +0000 +++ conf/ldscript.mips.mips64 2010-08-13 22:20:49 +0000 @@ -45,6 +45,7 @@ /* Read-only sections, merged into text segment: */ . = KERNLOADADDR + SIZEOF_HEADERS; .interp : { *(.interp) } + .multiboot : { *(.multiboot) } .hash : { *(.hash) } .dynsym : { *(.dynsym) } .dynstr : { *(.dynstr) } === modified file 'conf/options.mips' --- conf/options.mips 2010-08-13 22:16:49 +0000 +++ conf/options.mips 2010-08-14 18:03:06 +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 === modified file 'dev/atkbdc/atkbdc.c' --- dev/atkbdc/atkbdc.c 2010-08-13 22:16:49 +0000 +++ dev/atkbdc/atkbdc.c 2010-08-14 20:46:25 +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); -atkbdc_softc_t -*atkbdc_get_softc(int unit) +atkbdc_softc_t * +atkbdc_get_softc(int unit) { atkbdc_softc_t *sc; @@ -182,6 +182,8 @@ tag = IA64_BUS_SPACE_IO; #elif defined(__sparc64__) tag = &atkbdc_bst_store[0]; +#elif defined(__mips) + tag = mips_bus_space_generic; #else #error "define tag!" #endif @@ -213,6 +215,17 @@ return 0; h1 = sparc64_fake_bustag(space, port1, tag); bus_space_subregion(tag, h1, KBD_STATUS_PORT, 1, &h1); +#elif defined(__mips) + port0 = IO_KBD + (intptr_t)(int32_t)0xbfd00000; + resource_int_value("atkbdc", 0, "port", &port0); + port1 = 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 = (bus_space_handle_t)port0; + h1 = (bus_space_handle_t)port1; +#endif #else port0 = IO_KBD; resource_int_value("atkbdc", 0, "port", &port0); === added directory 'dev/cs5536' === added file 'dev/cs5536/cs5536.c' --- dev/cs5536/cs5536.c 1970-01-01 00:00:00 +0000 +++ dev/cs5536/cs5536.c 2010-08-17 14:03:30 +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 Foundation + * 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 the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * 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$"); + +/* + * 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)0xbfd00020) +#define GEODE_INTR_C2R0 (*(volatile uint8_t *)(intptr_t)(int32_t)0xbfd000a0) +#define GEODE_INTR_C1R1 (*(volatile uint8_t *)(intptr_t)(int32_t)0xbfd00021) +#define GEODE_INTR_C2R1 (*(volatile uint8_t *)(intptr_t)(int32_t)0xbfd000a1) + +#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 = device_get_softc(self); + int err; + + err = 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 = device_get_softc(self); + uint32_t reg, int_line; + + if (pci_get_powerstate(self) != PCI_POWERSTATE_D0) { + device_printf(self, "chip is in D%d mode " + "-- setting to D0\n", pci_get_powerstate(self)); + reg = pci_read_config(self, PCI_CBMEM, 4); + int_line = 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 = pci_get_devid(self); + + if (device_id == 0x208f1022) + return ("Geode PCI companion controller"); + return (NULL); +} + +static int +geode_pci_probe(device_t self) +{ + const char *desc = 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 = 0; + pci_write_config (self, CS5536_MSR_MAILBOX_ADDR, addr, 4); + ret = (uint64_t) pci_read_config (self, CS5536_MSR_MAILBOX_DATA0, 4); + ret |= ((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 = 0; + geode_softc_t *sc = sc_in; + int i; + + GEODE_INTR_C1R0 = 0x0a; + status = GEODE_INTR_C1R0; + GEODE_INTR_C2R0 = 0x0a; + status |= (GEODE_INTR_C2R0 << 8); + + GEODE_INTR_C1R0 = 0x0a; + GEODE_INTR_C1R0 = 0x0a; + + status &= ~intmask; + + while ((i = fls(status)) != 0) { + struct intr_event *event; + i--; /* Get a 0-offset interrupt. */ + event = sc->intr_events[i]; + + status &= ~(1 << i); + + /* issue EOI. */ + if (i >= 8) + GEODE_INTR_C2R0 = 0x60 | (i - 8); + else + GEODE_INTR_C1R0 = 0x60 | i; + + if (i == 2) + continue; + + if (!event || TAILQ_EMPTY(&event->ie_handlers)) { + printf("stray geode interrupt %d\n", i); + continue; + } + + if (intr_event_handle(event, NULL) != 0) { + printf("stray geode interrupt %d\n", i); + } + } +} + +static void +geode_unmask_irq(void *source) +{ + uintptr_t irq = (uintptr_t)source; + + intmask &= ~(1 << irq); + + GEODE_INTR_C2R1 = intmask >> 8; + GEODE_INTR_C1R1 = intmask & 0xff; +} + +static void +geode_mask_irq(void *source) +{ + uintptr_t irq = (uintptr_t)source; + + intmask |= (1 << irq); + GEODE_INTR_C2R1 = intmask >> 8; + GEODE_INTR_C1R1 = intmask & 0xff; +} + +static int +geode_setup_intr_real(device_t self, int irq, + int flags, driver_filter_t *filt, driver_intr_t *handler, + void *arg, void **cookiep) +{ + geode_softc_t *sc = device_get_softc(self); + struct intr_event *event; + int error; + + if (irq < 0 || irq >= GEODE_NUM_INTS) + return ENXIO; + + event = sc->intr_events[irq]; + if (event == NULL) { + error = 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] = 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, + void *arg, void **cookiep) +{ + return geode_setup_intr_real(bus, rman_get_start (res), + 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 = device_get_softc(bus); + + if (irq < 0 || irq >= GEODE_NUM_INTS) + return (ENXIO); + + event = 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 = 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 = 0xff; + GEODE_INTR_C2R1 = 0xff; + + GEODE_INTR_C1R0 = 0x11; + GEODE_INTR_C1R1 = 0 << 3; + GEODE_INTR_C1R1 = 1 << GEODE_CASCASE_IRQ; + GEODE_INTR_C1R1 = 0x01; + + GEODE_INTR_C2R0 = 0x11; + GEODE_INTR_C1R1 = 8 << 3; + GEODE_INTR_C1R1 = GEODE_CASCASE_IRQ; + GEODE_INTR_C1R1 = 0x01; + + DELAY (200); + + GEODE_INTR_C1R1 = 0xff; + GEODE_INTR_C2R1 = 0xff; + + intmask = 0xffff; + + geode_unmask_irq((void *) GEODE_CASCASE_IRQ); +} + +static int +geode_pci_attach(device_t self) +{ + geode_softc_t *sc = device_get_softc(self); + int rid; + int err; + uint32_t ohcibase; + uint32_t ehcibase; + int error; + + sc->sc_irq.rm_type = RMAN_ARRAY; + sc->sc_irq.rm_descr = "Geode IRQs"; + error = rman_init(&sc->sc_irq); + if (error != 0) + return (error); + + error = rman_manage_region(&sc->sc_irq, 0, GEODE_NUM_INTS - 1); + if (error != 0) + return (error); + + sc->mask = 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 = self; + sc->ohci.sc_bus.devices = sc->ohci.sc_devices; + sc->ohci.sc_bus.devices_max = OHCI_MAX_DEVICES; + sc->ehci.sc_bus.parent = self; + sc->ehci.sc_bus.devices = sc->ehci.sc_devices; + sc->ehci.sc_bus.devices_max = 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 = 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 = PCI_CBMEM; + /* Geode doesn't use normal BARs. */ + ohcibase = geode_read_msr (self, CS5536_MSR_USB_OHCI_BASE) + & CS5536_MSR_USB_BASE_ADDR_MASK; + sc->ohci.sc_io_res = + bus_alloc_resource(device_get_parent(self), + SYS_RES_MEMORY, &rid, + ohcibase, ohcibase, + 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) != 0) + { + device_printf(self, "Unaligned chunk\n"); + goto error; + } + + geode_write_msr (self, CS5536_MSR_USB_OHCI_BASE, + 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 = rman_get_bustag(sc->ohci.sc_io_res); + sc->ohci.sc_io_hdl = rman_get_bushandle(sc->ohci.sc_io_res); + sc->ohci.sc_io_size = rman_get_size(sc->ohci.sc_io_res); + + /* Geode doesn't use normal BARs. */ + ehcibase = geode_read_msr (self, CS5536_MSR_USB_EHCI_BASE) + & CS5536_MSR_USB_BASE_ADDR_MASK; + rid = PCI_CBMEM; + sc->ehci.sc_io_res = + bus_alloc_resource(device_get_parent(self), + SYS_RES_MEMORY, &rid, + ehcibase, ehcibase, + 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) != 0) + { + device_printf(self, "Unaligned chunk\n"); + goto error; + } + + geode_write_msr (self, CS5536_MSR_USB_EHCI_BASE, + 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 = rman_get_bustag(sc->ehci.sc_io_res); + sc->ehci.sc_io_hdl = rman_get_bushandle(sc->ehci.sc_io_res); + sc->ehci.sc_io_size = rman_get_size(sc->ehci.sc_io_res); + + rid = 0; + + sc->ehci.sc_io_res = sc->ohci.sc_io_res = rman_reserve_resource(&sc->sc_irq, USB_INTERRUPT, USB_INTERRUPT, 1, 0, self); + err = 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 = NULL; + goto error; + } + + err = 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 = NULL; + goto error; + } + + sc->ohci.sc_bus.bdev = 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 = 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 = ohci_init(&sc->ohci); + if (!err) { + err = device_probe_and_attach(sc->ohci.sc_bus.bdev); + } + if (err) { + device_printf(self, "USB init failed (%d)\n", err); + goto error; + } + + err = ehci_init(&sc->ehci); + if (!err) { + err = device_probe_and_attach(sc->ehci.sc_bus.bdev); + } + if (err) { + device_printf(self, "USB init failed err=%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 = 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 = 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 = NULL; + } + if (sc->ehci.sc_intr_hdl) { + /* + * only call ohci_detach() after ohci_init() + */ + ehci_detach(&sc->ehci); + + int err = 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 = 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 = device_get_softc(self); + int err; + + err = 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 = device_get_softc(bus); + + if (type != SYS_RES_IRQ) + return bus_generic_alloc_resource (bus, child, type, rid, + start, end, count, flags); + + res = rman_reserve_resource(&sc->sc_irq, start, end, count, flags, child); + if (res == NULL) + return (NULL); + + rman_set_rid(res, *rid); + + if ((flags & RF_ACTIVE) != 0) { + error = bus_activate_resource(child, type, *rid, res); + if (error != 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 != 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 != SYS_RES_IRQ) + bus_generic_release_resource(dev, child, type, rid, r); + return rman_release_resource(r); +} + + +static driver_t geode_driver = +{ + .name = "geode", + .methods = (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 = 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); === modified file 'dev/fb/fb.c' --- dev/fb/fb.c 2010-08-13 22:16:49 +0000 +++ dev/fb/fb.c 2010-08-14 15:29:46 +0000 @@ -608,6 +608,7 @@ { FBTYPE_VGA, KD_VGA }, { FBTYPE_PC98, KD_PC98 }, { FBTYPE_TGA, KD_TGA }, + { FBTYPE_MBFB, KD_MULTIBOOT }, }; int i; === added file 'dev/fb/mbfb.h' --- dev/fb/mbfb.h 1970-01-01 00:00:00 +0000 +++ dev/fb/mbfb.h 2010-08-14 16:28:14 +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" === added file 'dev/fb/mbvideo.c' --- dev/fb/mbvideo.c 1970-01-01 00:00:00 +0000 +++ dev/fb/mbvideo.c 2010-08-15 00:44:02 +0000 @@ -0,0 +1,637 @@ +/*- + * Copyright (c) 1999 Kazutaka YOKOTA + * Copyright (c) 1992-1998 Søren 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 the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * 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[] = { + 0x0000, + 0x001f, + 0x07e0, + 0x0618, + 0xf800, + 0xc018, + 0xc600, + 0xc618, + 0x8410, + 0x841f, + 0x87f0, + 0x87ff, + 0xfc10, + 0xfc1f, + 0xfff0, + 0xffff, +}; + +static video_adapter_t mbvidadapter = +{ + .va_index = 0, + .va_type = KD_MULTIBOOT, + .va_name = MBVID_NAME, + .va_unit = 0, + .va_minor = 0, + .va_flags = V_ADP_COLOR, + .va_io_base = 0, + .va_io_size = 0, + .va_crtc_addr = 0, + .va_window = (uintptr_t) &window, + .va_window_size = sizeof (window), + .va_window_gran = 0, + .va_window_orig = 0, + .va_buffer = 0, + .va_buffer_size = 0, + .va_initial_mode = 0, + .va_initial_bios_mode = 0, + .va_mode = 0, + .va_info = { + .vi_mode = 0, + .vi_flags = V_INFO_COLOR | V_INFO_LINEAR, + .vi_cwidth = 8, + .vi_cheight = 16, + .vi_planes = 1, + .vi_window_gran = 0, + .vi_buffer = 0, + .vi_buffer_size = 0, + .vi_mem_model = V_INFO_MM_DIRECT, + .vi_registers = 0, + .vi_registers_size = 0, + }, + .va_disp_start = { + .x = 0, + .y = 0, + }, + .va_token = 0, + .va_model = 0, + .va_little_bitian = 0, + .va_little_endian = 1, + .va_buffer_alias = 0, + .va_registers = 0, + .va_registers_size = 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 == 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 = { + .d_version = D_VERSION, + .d_flags = 0, + .d_open = mbvid_open, + .d_close = mbvid_close, + .d_read = mbvid_read, + .d_write = mbvid_write, + .d_ioctl = mbvid_ioctl, + .d_mmap = mbvid_mmap, + .d_name = "multiboot video console", +}; + +int +attach_mbvid (void) +{ + int error; + int idx; + + mbvidadapter.va_info.vi_mode = M_TEXT_80x25; + mbvidadapter.va_info.vi_cwidth = bold8x16.width; + mbvidadapter.va_info.vi_cheight = bold8x16.height; + mbvidadapter.va_info.vi_height = (mbvid_params.height / mbvidadapter.va_info.vi_cheight); + mbvidadapter.va_info.vi_width = (mbvid_params.width / mbvidadapter.va_info.vi_cwidth); + mbvidadapter.va_info.vi_flags = V_INFO_COLOR | V_INFO_LINEAR; + mbvidadapter.va_info.vi_mem_model = V_INFO_MM_DIRECT; + + mbvidadapter.va_flags |= V_ADP_COLOR; + + idx = vid_register (&mbvidadapter); + if (idx < 0) + { + return ENXIO; + } + mbvidadapter.va_flags |= V_ADP_REGISTERED; + + /* attach a virtual frame buffer device */ + error = 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 = { + mbvid_probe, + mbvid_init, + mbvid_get_info, + mbvid_query_mode, + (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 = mbvid_putp, + .putc = mbvid_putc, + .puts = mbvid_puts, + .putm = 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 >= fb_found) + return ENXIO; + + mbvidadapter.va_flags |= V_ADP_PROBED; + + *adpp = &mbvidadapter; + + return 0; +} + +static int +mbvid_init(int unit, video_adapter_t *adp, int flags) +{ + if (unit >= fb_found) + return ENXIO; + + mbvidadapter.va_flags |= 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 != 0) + return EINVAL; + *info = 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 != 0) + && (info->vi_width != adp->va_info.vi_width)) + return ENODEV; + + if ((info->vi_height != 0) + && (info->vi_height != adp->va_info.vi_height)) + return ENODEV; + + if ((info->vi_cwidth != 0) + && (info->vi_cwidth != adp->va_info.vi_cwidth)) + return ENODEV; + + if ((info->vi_cheight != 0) + && (info->vi_cheight != adp->va_info.vi_cheight)) + return ENODEV; + + if ((info->vi_depth != 0) + && (info->vi_depth != adp->va_info.vi_depth)) + return ENODEV; + + if ((info->vi_planes != 0) + && (info->vi_planes != adp->va_info.vi_planes)) + return ENODEV; + + /* XXX: should check pixel format, memory model */ + if ((info->vi_flags != 0) + && (info->vi_flags != 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 *paddr, + int prot, vm_memattr_t *memattr) +{ + printf("mbvid_mmap_buf(): window:0x%jx, offset:0x%jx\n", + (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 = 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 *paddr, + 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 = 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 = fb_type(adp->va_type); + ((struct fbtype *)arg)->fb_height = adp->va_info.vi_height; + ((struct fbtype *)arg)->fb_width = adp->va_info.vi_width; + ((struct fbtype *)arg)->fb_depth = adp->va_info.vi_depth; + if ((adp->va_info.vi_depth <= 1) || (adp->va_info.vi_depth > 8)) + ((struct fbtype *)arg)->fb_cmsize = 0; + else + ((struct fbtype *)arg)->fb_cmsize = 1 << adp->va_info.vi_depth; + ((struct fbtype *)arg)->fb_size = 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 = mbvid_params.ptr; + + /* calculate the position in the frame buffer */ + row = (off / mbvidadapter.va_info.vi_width) * mbvidadapter.va_info.vi_cheight; + col = (off % mbvidadapter.va_info.vi_width) * mbvidadapter.va_info.vi_cwidth; + fontdata = &bold8x16.data[c * mbvidadapter.va_info.vi_cheight]; + ptri += (row * mbvid_params.width) + col; + + /* Place the character on the screen, pixel by pixel */ + for (j = 0; j < mbvidadapter.va_info.vi_cheight; j++) { + mask = 0x80; + for (i = 0; i < mbvidadapter.va_info.vi_cwidth; i++) { + clr = (*fontdata & mask) ? cmap[a & 0xf] : cmap[(a >> 4) & 0xf]; + *ptri++ = clr; + mask >>= 1; + } + ptri += (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 = 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 = &xboxfb_sc; + uint32_t* ptri = (uint32_t*)sc->sc_framebuffer; + int i, j; + + if (x < 0 || y < 0 || x + width > sc->sc_width || y + (2 * size) > sc->sc_height) + return 0; + + ptri += (y * sc->sc_width) + x; + + /* plot the mousecursor wherever the user wants it */ + for (j = 0; j < size; j++) { + for (i = width; i > 0; i--) { + if (pixel_image[j] & (1 << i)) + *ptri = cmap[0xf]; + ptri++; + } + ptri += (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, from), count); + } else { + /* This is for selections and such: invert the color attribute */ + for (i = count; i-- > 0; ++from) { + c = sc_vtb_getc(&scp->vtb, from); + a = 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 <= 0) + return; + + ptri = mbvid_params.ptr; + + /* calculate the coordinates in the video buffer */ + row = (at / mbvidadapter.va_info.vi_width) * mbvidadapter.va_info.vi_cheight; + col = (at % mbvidadapter.va_info.vi_width) * mbvidadapter.va_info.vi_cwidth; + ptri += (row * mbvid_params.width) + col; + + /* our cursor consists of simply inverting the char under it */ + for (i = 0; i < mbvidadapter.va_info.vi_cheight; i++) { + for (j = 0; j < mbvidadapter.va_info.vi_cwidth; j++) { + *ptri++ ^= 0xFFFF; + } + ptri += (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 = { + 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); === modified file 'dev/syscons/schistory.c' --- dev/syscons/schistory.c 2010-08-13 22:16:49 +0000 +++ dev/syscons/schistory.c 2010-08-14 18:33:04 +0000 @@ -42,7 +42,7 @@ #include #include -#if defined(__sparc64__) || defined(__powerpc__) +#if defined(__sparc64__) || defined(__powerpc__) || defined (__mips) #include #else #include === 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:57:37 +0000 @@ -40,7 +40,7 @@ #include #include -#if defined(__sparc64__) || defined(__powerpc__) +#if defined(__sparc64__) || defined(__powerpc__) || defined(__mips) #include #else #include @@ -140,7 +140,8 @@ tp.tp_col = scp->xsize; teken_set_winsize(&ts->ts_teken, &tp); - if (scp->cursor_pos < scp->ysize * scp->xsize) { + if (scp->cursor_pos < scp->ysize * scp->xsize + && scp->cursor_pos >= 0) { /* Valid old cursor position. */ tp.tp_row = scp->cursor_pos / scp->xsize; tp.tp_col = scp->cursor_pos % scp->xsize; === modified file 'dev/syscons/syscons.c' --- dev/syscons/syscons.c 2010-08-13 22:16:49 +0000 +++ dev/syscons/syscons.c 2010-08-14 22:58:04 +0000 @@ -62,7 +62,7 @@ #include #include -#if defined(__sparc64__) || defined(__powerpc__) +#if defined(__sparc64__) || defined(__powerpc__) || defined (__mips) #include #else #include === 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:16:14 +0000 @@ -104,6 +104,7 @@ }; 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); === modified file 'dev/usb/usb_busdma.c' --- dev/usb/usb_busdma.c 2010-08-13 22:16:49 +0000 +++ dev/usb/usb_busdma.c 2010-08-17 14:12:28 +0000 @@ -699,7 +699,7 @@ /* nothing has been loaded into this page cache! */ return; } - bus_dmamap_sync(pc->tag, pc->map, BUS_DMASYNC_PREWRITE); + bus_dmamap_sync(pc->tag, pc->map, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); } /*------------------------------------------------------------------------* === modified file 'isa/rtc.h' --- isa/rtc.h 2010-08-13 22:16:49 +0000 +++ isa/rtc.h 2010-08-15 03:26:10 +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 = 12 hours, 1 = 24 hours */ -#define RTCSB_BCD 0x04 /* 0 = BCD, 1 = Binary coded time */ +#define RTCSB_BINARY 0x04 /* 0 = BCD, 1 = Binary coded time */ #define RTCSB_SQWE 0x08 /* 1 = output sqare wave at SQW pin */ #define RTCSB_UINTR 0x10 /* 1 = enable update-ended interrupt */ #define RTCSB_AINTR 0x20 /* 1 = enable alarm interrupt */ === added file 'mips/conf/YEELOONG' --- mips/conf/YEELOONG 1970-01-01 00:00:00 +0000 +++ mips/conf/YEELOONG 2010-08-14 18:03:39 +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/kernelconfig-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 first +# 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="" + +include "../yeeloong/std.yeeloong" + +# hints "YEELOONG.hints" #Default places to look for devices. + +makeoptions DEBUG=-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 extensions + +# 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 === modified file 'mips/include/bus.h' --- mips/include/bus.h 2010-08-13 22:16:49 +0000 +++ mips/include/bus.h 2010-08-14 18:26:44 +0000 @@ -74,6 +74,41 @@ #define _MACHINE_BUS_H_ #include +#include + +static inline void +memsetw (volatile void *ptr_, uint16_t val, size_t count) +{ + volatile uint16_t *ptr = ptr_; + while (count--) + *ptr++ = val; +} + +static inline void +memsetw_io (uintptr_t ptr_, uint16_t val, size_t count) +{ + volatile uint16_t *ptr = (volatile uint16_t *) ptr_; + while (count--) + *ptr++ = 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); +} struct bus_space { /* cookie */ === modified file 'mips/include/cache.h' --- mips/include/cache.h 2010-08-13 22:16:49 +0000 +++ mips/include/cache.h 2010-08-15 07:38:23 +0000 @@ -213,6 +213,22 @@ #define mips_intern_dcache_wb_range(v, s) \ __mco_2args(intern_, dcache_wb_range, (v), (s)) +#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; === 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 07:39:31 +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); === modified file 'mips/include/cpufunc.h' --- mips/include/cpufunc.h 2010-08-13 22:16:49 +0000 +++ mips/include/cpufunc.h 2010-08-13 22:21:55 +0000 @@ -142,6 +142,10 @@ #undef MIPS_RDRW64_COP0 #endif +#if __mips == 32 || __mips == 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 +#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 +#endif + #ifdef CPU_CNMIPS static __inline void mips_sync_icache (void) { @@ -201,9 +209,11 @@ 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 #undef MIPS_RDRW32_COP0 === modified file 'mips/include/cpuinfo.h' --- mips/include/cpuinfo.h 2010-08-13 22:16:49 +0000 +++ mips/include/cpuinfo.h 2010-08-15 07:43:39 +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; }; extern struct mips_cpuinfo cpuinfo; === 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:09:51 +0000 @@ -136,6 +136,10 @@ #define MIPS_CCA_UC 0x02 /* Uncached. */ #define MIPS_CCA_C 0x03 /* Cacheable, coherency unspecified. */ +#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 -#ifdef CPU_R10000 -#define MIPS_CCA_UA 0x07 -#endif - #define MIPS_CCA_CACHED MIPS_CCA_CCEW #endif /* defined(CPU_R4000) || defined(CPU_R10000) */ @@ -188,8 +188,14 @@ #define MIPS_XKSEG_START 0xc000000000000000 #define MIPS_XKSEG_END 0xc00000ff80000000 +#if __mips == 32 || __mips == 64 +#define SSNOP ssnop +#else +#define SSNOP nop +#endif + /* 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; ssnop; 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 === modified file 'mips/include/param.h' --- mips/include/param.h 2010-08-13 22:16:49 +0000 +++ mips/include/param.h 2010-08-16 23:24:43 +0000 @@ -100,7 +100,7 @@ #define CACHE_LINE_SHIFT 6 #define CACHE_LINE_SIZE (1 << CACHE_LINE_SHIFT) -#define PAGE_SHIFT 12 /* LOG2(PAGE_SIZE) */ +#define PAGE_SHIFT 14 /* LOG2(PAGE_SIZE) */ #define PAGE_SIZE (1<> TLBMASK_SHIFT) << TLBMASK_SHIFT) +#define TLBMASK_MASK ((PAGE_MASK >> (TLBMASK_SHIFT - 1)) << TLBMASK_SHIFT) /* * PFN for EntryLo register. Upper bits are 0, which is to say that @@ -63,7 +63,7 @@ */ #define TLBLO_SWBITS_SHIFT (30) #define TLBLO_SWBITS_MASK (0x3U << TLBLO_SWBITS_SHIFT) -#define TLBLO_PFN_SHIFT (6) +#define TLBLO_PFN_SHIFT (PAGE_SHIFT - 6) #define TLBLO_PFN_MASK (0x3FFFFFC0) #define TLBLO_PA_TO_PFN(pa) ((((pa) >> TLB_PAGE_SHIFT) << TLBLO_PFN_SHIFT) & TLBLO_PFN_MASK) #define TLBLO_PFN_TO_PA(pfn) ((vm_paddr_t)((pfn) >> TLBLO_PFN_SHIFT) << TLB_PAGE_SHIFT) @@ -89,9 +89,7 @@ #define TLBHI_R_KERNEL (0x03UL << TLBHI_R_SHIFT) #define TLBHI_R_MASK (0x03UL << TLBHI_R_SHIFT) #define TLBHI_VA_R(va) ((va) & TLBHI_R_MASK) -#define TLBHI_FILL_SHIFT 40 -#define TLBHI_VPN2_SHIFT (TLB_PAGE_SHIFT + 1) -#define TLBHI_VPN2_MASK (((~((1UL << TLBHI_VPN2_SHIFT) - 1)) << (63 - TLBHI_FILL_SHIFT)) >> (63 - TLBHI_FILL_SHIFT)) +#define TLBHI_VPN2_MASK (~((1ULL << (TLB_PAGE_SHIFT + 1)) - 1) & ~TLBHI_R_MASK) #define TLBHI_VA_TO_VPN2(va) ((va) & TLBHI_VPN2_MASK) #define TLBHI_ENTRY(va, asid) ((TLBHI_VA_R((va))) /* Region. */ | \ (TLBHI_VA_TO_VPN2((va))) /* VPN2. */ | \ === 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 18:45:20 +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 === modified file 'mips/include/vmparam.h' --- mips/include/vmparam.h 2010-08-13 22:16:49 +0000 +++ mips/include/vmparam.h 2010-08-17 17:15:01 +0000 @@ -112,7 +112,7 @@ * and some QED CPUs perform some virtual address checks before the * offset is calculated. */ -#define USRSTACK (VM_MAXUSER_ADDRESS - PAGE_SIZE) +#define USRSTACK (VM_MAXUSER_ADDRESS) /* * Only one memory domain. === 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 04:18:21 +0000 @@ -593,6 +593,9 @@ { #if 0 if (flags & BUS_SPACE_BARRIER_WRITE) + { mips_dcache_wbinv_all(); + mips_sdcache_wbinv_all(); + } #endif } === 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-17 14:02:19 +0000 @@ -638,6 +638,8 @@ newmap->allocbuffer = tmpaddr; mips_dcache_wbinv_range((vm_offset_t)*vaddr, dmat->maxsize); + mips_sdcache_wbinv_range((vm_offset_t)*vaddr, + dmat->maxsize); *vaddr = tmpaddr; } else newmap->origbuffer = newmap->allocbuffer = NULL; @@ -805,6 +807,9 @@ if (++seg >= dmat->nsegments) break; segs[seg].ds_addr = curaddr; +#ifdef TARGET_YEELOONG + segs[seg].ds_addr |= 0x80000000; +#endif segs[seg].ds_len = 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); /* * 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 == 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; 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; 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 == 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; 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 == 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 == 0) { mips_dcache_inv_range(bpage->vaddr, bpage->datacount); + mips_sdcache_inv_range(bpage->vaddr, + bpage->datacount); } bcopy((void *)(bpage->vaddr_nocache != 0 ? bpage->vaddr_nocache : bpage->vaddr), === modified file 'mips/mips/cache.c' --- mips/mips/cache.c 2010-08-13 22:16:49 +0000 +++ mips/mips/cache.c 2010-08-15 04:07:37 +0000 @@ -194,6 +194,28 @@ cpuinfo->l1.dc_linesize); } + switch (cpuinfo->l2.dc_linesize) { + case 32: + mips_cache_ops.mco_sdcache_wbinv_all = + mips_cache_ops.mco_intern_sdcache_wbinv_all = + mipsNN_sdcache_wbinv_all_32; + mips_cache_ops.mco_sdcache_wbinv_range = + mipsNN_sdcache_wbinv_range_32; + mips_cache_ops.mco_sdcache_wbinv_range_index = + mips_cache_ops.mco_intern_sdcache_wbinv_range_index = + mipsNN_sdcache_wbinv_range_index_32; + mips_cache_ops.mco_sdcache_inv_range = + mipsNN_sdcache_inv_range_32; + mips_cache_ops.mco_sdcache_wb_range = + mips_cache_ops.mco_intern_sdcache_wb_range = + mipsNN_sdcache_wb_range_32; + break; + default: + panic("no SDcache ops for %d byte lines", + cpuinfo->l1.dc_linesize); + } + + mipsNN_cache_init(cpuinfo); #if 0 === 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-16 22:00:16 +0000 @@ -82,6 +82,12 @@ static int pdcache_loopcount; static int pdcache_way_mask; +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; } + if (cpuinfo->l2.dc_nsets * cpuinfo->l2.dc_linesize < PAGE_SIZE) { + sdcache_stride = cpuinfo->l2.dc_nsets * cpuinfo->l2.dc_linesize; + sdcache_loopcount = cpuinfo->l2.dc_nways; + } else { + sdcache_stride = PAGE_SIZE; + sdcache_loopcount = (cpuinfo->l2.dc_nsets * cpuinfo->l2.dc_linesize / PAGE_SIZE) * + cpuinfo->l2.dc_nways; + } + mips_picache_linesize = cpuinfo->l1.ic_linesize; mips_pdcache_linesize = cpuinfo->l1.dc_linesize; @@ -123,6 +138,9 @@ pdcache_size = cpuinfo->l1.dc_size; pdcache_way_mask = cpuinfo->l1.dc_nways - 1; + sdcache_size = cpuinfo->l2.dc_size; + sdcache_way_mask = cpuinfo->l2.dc_nways - 1; + #define CACHE_DEBUG #ifdef CACHE_DEBUG printf("Cache info:\n"); @@ -181,6 +199,12 @@ SYNC; } +#if __mips == 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)); while ((eva - va) >= (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 += (32 * 16); } while (va < eva) { - cache_op_r4k_line(va, CACHE_R4K_I|CACHEOP_R4K_HIT_INV); + cache_op_r4k_line(va, HIT_I_INV); va += 16; } @@ -215,12 +239,12 @@ mips_intern_dcache_wb_range(va, (eva - va)); while ((eva - va) >= (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 += (32 * 32); } while (va < eva) { - cache_op_r4k_line(va, CACHE_R4K_I|CACHEOP_R4K_HIT_INV); + cache_op_r4k_line(va, HIT_I_INV); va += 32; } @@ -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; /* @@ -273,8 +297,8 @@ void mipsNN_icache_sync_range_index_32(vm_offset_t va, vm_size_t size) { - unsigned int eva, tmpva; - int i, stride, loopcount; + vm_offset_t eva, tmpva; + int stride, loopcount; /* * Since we're doing Index ops, we expect to not be able @@ -282,7 +306,7 @@ * bits that determine the cache index, and make a KSEG0 * address out of them. */ - va = MIPS_PHYS_TO_KSEG0(va & picache_way_mask); + va = MIPS_PHYS_TO_KSEG0(va & 0x3fe0); eva = round_line32(va + size); va = trunc_line32(va); @@ -298,7 +322,7 @@ while ((eva - va) >= (8 * 32)) { tmpva = va; - for (i = 0; i < loopcount; i++, tmpva += stride) +// for (i = 0; i < loopcount; i++, tmpva += stride) cache_r4k_op_8lines_32(tmpva, CACHE_R4K_I|CACHEOP_R4K_INDEX_INV); va += 8 * 32; @@ -306,7 +330,7 @@ while (va < eva) { tmpva = va; - for (i = 0; i < loopcount; i++, tmpva += stride) + // for (i = 0; i < loopcount; i++, tmpva += stride) cache_op_r4k_line(tmpva, CACHE_R4K_I|CACHEOP_R4K_INDEX_INV); va += 32; @@ -351,12 +375,19 @@ 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 += (32 * 32); } SYNC; } + void mipsNN_pdcache_wbinv_range_16(vm_offset_t va, vm_size_t size) { @@ -390,11 +421,20 @@ while ((eva - va) >= (32 * 32)) { cache_r4k_op_32lines_32(va, CACHE_R4K_D|CACHEOP_R4K_HIT_WB_INV); + cache_r4k_op_32lines_32(va + 1, + CACHE_R4K_D|CACHEOP_R4K_HIT_WB_INV); + cache_r4k_op_32lines_32(va + 2, + CACHE_R4K_D|CACHEOP_R4K_HIT_WB_INV); + cache_r4k_op_32lines_32(va + 3, + CACHE_R4K_D|CACHEOP_R4K_HIT_WB_INV); va += (32 * 32); } while (va < eva) { cache_op_r4k_line(va, CACHE_R4K_D|CACHEOP_R4K_HIT_WB_INV); + cache_op_r4k_line(va + 1, CACHE_R4K_D|CACHEOP_R4K_HIT_WB_INV); + cache_op_r4k_line(va + 2, CACHE_R4K_D|CACHEOP_R4K_HIT_WB_INV); + cache_op_r4k_line(va + 3, CACHE_R4K_D|CACHEOP_R4K_HIT_WB_INV); va += 32; } @@ -413,7 +453,7 @@ * bits that determine the cache index, and make a KSEG0 * address out of them. */ - va = MIPS_PHYS_TO_KSEG0(va & pdcache_way_mask); + va = MIPS_PHYS_TO_KSEG0(va & 0x3ff); eva = round_line16(va + size); va = trunc_line16(va); @@ -427,7 +467,7 @@ while ((eva - va) >= (8 * 16)) { tmpva = va; - for (i = 0; i < loopcount; i++, tmpva += stride) + for (i = 0; i < 4; i++, tmpva ++) cache_r4k_op_8lines_16(tmpva, CACHE_R4K_D|CACHEOP_R4K_INDEX_WB_INV); va += 8 * 16; @@ -454,7 +494,7 @@ * bits that determine the cache index, and make a KSEG0 * address out of them. */ - va = MIPS_PHYS_TO_KSEG0(va & pdcache_way_mask); + va = MIPS_PHYS_TO_KSEG0 (va & pdcache_way_mask); eva = round_line32(va + size); va = trunc_line32(va); @@ -482,7 +522,7 @@ va += 32; } } - + void mipsNN_pdcache_inv_range_16(vm_offset_t va, vm_size_t size) { @@ -514,11 +554,18 @@ while ((eva - va) >= (32 * 32)) { cache_r4k_op_32lines_32(va, CACHE_R4K_D|CACHEOP_R4K_HIT_INV); + cache_r4k_op_32lines_32(va + 1, CACHE_R4K_D|CACHEOP_R4K_HIT_INV); + cache_r4k_op_32lines_32(va + 2, CACHE_R4K_D|CACHEOP_R4K_HIT_INV); + cache_r4k_op_32lines_32(va + 3, CACHE_R4K_D|CACHEOP_R4K_HIT_INV); + va += (32 * 32); } while (va < eva) { cache_op_r4k_line(va, CACHE_R4K_D|CACHEOP_R4K_HIT_INV); + cache_op_r4k_line(va + 1, CACHE_R4K_D|CACHEOP_R4K_HIT_INV); + cache_op_r4k_line(va + 2, CACHE_R4K_D|CACHEOP_R4K_HIT_INV); + cache_op_r4k_line(va + 3, CACHE_R4K_D|CACHEOP_R4K_HIT_INV); va += 32; } @@ -556,18 +603,23 @@ while ((eva - va) >= (32 * 32)) { cache_r4k_op_32lines_32(va, CACHE_R4K_D|CACHEOP_R4K_HIT_WB); + cache_r4k_op_32lines_32(va + 1, CACHE_R4K_D|CACHEOP_R4K_HIT_WB); + cache_r4k_op_32lines_32(va + 2, CACHE_R4K_D|CACHEOP_R4K_HIT_WB); + cache_r4k_op_32lines_32(va + 3, CACHE_R4K_D|CACHEOP_R4K_HIT_WB); va += (32 * 32); } while (va < eva) { cache_op_r4k_line(va, CACHE_R4K_D|CACHEOP_R4K_HIT_WB); + cache_op_r4k_line(va + 1, CACHE_R4K_D|CACHEOP_R4K_HIT_WB); + cache_op_r4k_line(va + 2, CACHE_R4K_D|CACHEOP_R4K_HIT_WB); + cache_op_r4k_line(va + 3, CACHE_R4K_D|CACHEOP_R4K_HIT_WB); va += 32; } SYNC; } - #ifdef CPU_CNMIPS void @@ -617,3 +669,136 @@ } #endif + +void +mipsNN_sdcache_wbinv_all_32(void) +{ + vm_offset_t va, eva; + + va = MIPS_PHYS_TO_KSEG0(0); + eva = 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); + 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 += (32 * 32); + } + + SYNC; +} + +void +mipsNN_sdcache_wbinv_range_32(vm_offset_t va, vm_size_t size) +{ + vm_offset_t eva; + + eva = round_line32(va + size); + va = trunc_line32(va); + + while ((eva - va) >= (32 * 32)) { + cache_r4k_op_32lines_32(va, + CACHE_R4K_SD|CACHEOP_R4K_HIT_WB_INV); + va += (32 * 32); + } + + while (va < eva) { + cache_op_r4k_line(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_WB_INV); + va += 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 = MIPS_PHYS_TO_KSEG0 (va & 0x1ffff); + + eva = round_line32(va + size); + va = trunc_line32(va); + + /* + * GCC generates better code in the loops if we reference local + * copies of these global variables. + */ + stride = sdcache_stride; + loopcount = sdcache_loopcount; + + while ((eva - va) >= (8 * 32)) { + tmpva = va; + for (i = 0; i < 4; i++, tmpva++) + cache_r4k_op_8lines_32(tmpva, + CACHE_R4K_SD|CACHEOP_R4K_INDEX_WB_INV); + va += 8 * 32; + } + + while (va < eva) { + tmpva = va; + for (i = 0; i < loopcount; i++, tmpva += stride) + cache_op_r4k_line(tmpva, + CACHE_R4K_SD|CACHEOP_R4K_INDEX_WB_INV); + va += 32; + } +} + +void +mipsNN_sdcache_inv_range_32(vm_offset_t va, vm_size_t size) +{ + vm_offset_t eva; + + eva = round_line32(va + size); + va = trunc_line32(va); + + while ((eva - va) >= (32 * 32)) { + cache_r4k_op_32lines_32(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_INV); + va += (32 * 32); + } + + while (va < eva) { + cache_op_r4k_line(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_INV); + va += 32; + } + + SYNC; +} + +void +mipsNN_sdcache_wb_range_32(vm_offset_t va, vm_size_t size) +{ + vm_offset_t eva; + + eva = round_line32(va + size); + va = trunc_line32(va); + + while ((eva - va) >= (32 * 32)) { + cache_r4k_op_32lines_32(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_WB); + va += (32 * 32); + } + + while (va < eva) { + cache_op_r4k_line(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_WB); + va += 32; + } + + SYNC; +} === modified file 'mips/mips/cpu.c' --- mips/mips/cpu.c 2010-08-13 22:16:49 +0000 +++ mips/mips/cpu.c 2010-08-16 22:04:45 +0000 @@ -69,8 +69,6 @@ { u_int32_t prid; u_int32_t cfg0; - u_int32_t cfg1; - u_int32_t tmp; memset(cpuinfo, 0, sizeof(struct mips_cpuinfo)); @@ -87,46 +85,71 @@ ((cfg0 & MIPS_CONFIG0_MT_MASK) >> MIPS_CONFIG0_MT_SHIFT); cpuinfo->icache_virtual = cfg0 & MIPS_CONFIG0_VI; - /* If config register selection 1 does not exist, exit. */ - if (!(cfg0 & MIPS3_CONFIG_CM)) - return; - - /* Learn TLB size and L1 cache geometry. */ - cfg1 = mips_rd_config1(); - cpuinfo->tlb_nentries = - ((cfg1 & MIPS_CONFIG1_TLBSZ_MASK) >> MIPS_CONFIG1_TLBSZ_SHIFT) + 1; - - /* L1 instruction cache. */ - tmp = (cfg1 & MIPS_CONFIG1_IL_MASK) >> MIPS_CONFIG1_IL_SHIFT; - if (tmp != 0) { - cpuinfo->l1.ic_linesize = 1 << (tmp + 1); - cpuinfo->l1.ic_nways = (((cfg1 & MIPS_CONFIG1_IA_MASK) >> MIPS_CONFIG1_IA_SHIFT)) + 1; - cpuinfo->l1.ic_nsets = - 1 << (((cfg1 & MIPS_CONFIG1_IS_MASK) >> MIPS_CONFIG1_IS_SHIFT) + 6); - cpuinfo->l1.ic_size = - cpuinfo->l1.ic_linesize * cpuinfo->l1.ic_nsets * cpuinfo->l1.ic_nways; - } - - /* L1 data cache. */ - tmp = (cfg1 & MIPS_CONFIG1_DL_MASK) >> MIPS_CONFIG1_DL_SHIFT; - if (tmp != 0) { - cpuinfo->l1.dc_linesize = 1 << (tmp + 1); - cpuinfo->l1.dc_nways = - (((cfg1 & MIPS_CONFIG1_DA_MASK) >> MIPS_CONFIG1_DA_SHIFT)) + 1; - cpuinfo->l1.dc_nsets = - 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 = mips_rd_config1(); + cpuinfo->tlb_nentries = + ((cfg1 & MIPS_CONFIG1_TLBSZ_MASK) >> MIPS_CONFIG1_TLBSZ_SHIFT) + 1; + + /* L1 instruction cache. */ + tmp = (cfg1 & MIPS_CONFIG1_IL_MASK) >> MIPS_CONFIG1_IL_SHIFT; + if (tmp != 0) { + cpuinfo->l1.ic_linesize = 1 << (tmp + 1); + cpuinfo->l1.ic_nways = (((cfg1 & MIPS_CONFIG1_IA_MASK) >> MIPS_CONFIG1_IA_SHIFT)) + 1; + cpuinfo->l1.ic_nsets = + 1 << (((cfg1 & MIPS_CONFIG1_IS_MASK) >> MIPS_CONFIG1_IS_SHIFT) + 6); + cpuinfo->l1.ic_size = + cpuinfo->l1.ic_linesize * cpuinfo->l1.ic_nsets * cpuinfo->l1.ic_nways; + } + + /* L1 data cache. */ + tmp = (cfg1 & MIPS_CONFIG1_DL_MASK) >> MIPS_CONFIG1_DL_SHIFT; + if (tmp != 0) { + cpuinfo->l1.dc_linesize = 1 << (tmp + 1); + cpuinfo->l1.dc_nways = + (((cfg1 & MIPS_CONFIG1_DA_MASK) >> MIPS_CONFIG1_DA_SHIFT)) + 1; + cpuinfo->l1.dc_nsets = + 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 = 128; - cpuinfo->l1.dc_nsets = 1; - cpuinfo->l1.dc_nways = 64; -#endif - cpuinfo->l1.dc_size = cpuinfo->l1.dc_linesize - * 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 = 128; + cpuinfo->l1.dc_nsets = 1; + cpuinfo->l1.dc_nways = 64; +#endif + cpuinfo->l1.dc_size = cpuinfo->l1.dc_linesize + * cpuinfo->l1.dc_nsets * cpuinfo->l1.dc_nways; + } +#elif defined (TARGET_YEELOONG) + { + cpuinfo->tlb_nentries = 64; + + cpuinfo->l1.ic_linesize = 32; + cpuinfo->l1.ic_nways = 4; + cpuinfo->l1.ic_nsets = 65536 / (4 * 32); + cpuinfo->l1.ic_size = 65536; + + cpuinfo->l1.dc_linesize = 32; + cpuinfo->l1.dc_nways = 4; + cpuinfo->l1.dc_nsets = 65536 / (4 * 32); + cpuinfo->l1.dc_size = 65536; + + cpuinfo->l2.dc_linesize = 32; + cpuinfo->l2.dc_nways = 4; + cpuinfo->l2.dc_nsets = (512 * 1024) / (4 * 32); + cpuinfo->l2.dc_size = (512 * 1024); + } +#else +#error unknown architecture without selector support +#endif } void @@ -143,6 +166,7 @@ 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; - cfg1 = mips_rd_config1(); - printf(" Config1=0x%b\n", cfg1, - "\20\7COP2\6MDMX\5PerfCount\4WatchRegs\3MIPS16\2EJTAG\1FPU"); - - /* If config register selection 2 does not exist, exit. */ - if (!(cfg1 & MIPS3_CONFIG_CM)) - return; - cfg2 = mips_rd_config2(); - /* - * Config2 contains no useful information other then Config3 - * existence flag - */ - - /* If config register selection 3 does not exist, exit. */ - if (!(cfg2 & MIPS3_CONFIG_CM)) - return; - cfg3 = mips_rd_config3(); +#ifdef MIPS_HAS_CP0_SELECTORS + { + uint32_t cfg1, cfg2, cfg3; + + cfg1 = mips_rd_config1(); + printf(" Config1=0x%b\n", cfg1, + "\20\7COP2\6MDMX\5PerfCount\4WatchRegs\3MIPS16\2EJTAG\1FPU"); + + /* If config register selection 2 does not exist, exit. */ + if (!(cfg1 & MIPS3_CONFIG_CM)) + return; + cfg2 = mips_rd_config2(); + /* + * Config2 contains no useful information other then Config3 + * existence flag + */ + + /* If config register selection 3 does not exist, exit. */ + if (!(cfg2 & MIPS3_CONFIG_CM)) + return; + cfg3 = mips_rd_config3(); /* Print Config3 if it contains any useful info */ - if (cfg3 & ~(0x80000000)) - printf(" Config3=0x%b\n", cfg3, "\20\2SmartMIPS\1TraceLogic"); + if (cfg3 & ~(0x80000000)) + printf(" Config3=0x%b\n", cfg3, "\20\2SmartMIPS\1TraceLogic"); + } +#endif } static struct rman cpu_hardirq_rman; === 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-13 22:20:49 +0000 @@ -53,6 +53,17 @@ #include #include +static char *cache_op_suffix[4] = { + "i", "d", "s", "si" +}; + +static char *cache_op_type[8] = { + "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] = { /* 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; + 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; + case OP_ADDI: case OP_DADDI: case OP_ADDIU: === 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 04:10:14 +0000 @@ -211,6 +211,7 @@ 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); === 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-13 23:39:56 +0000 @@ -49,9 +49,19 @@ #define MIPS_END_OF_FUNCTION(ins) ((ins) == 0x03e00008) /* - * kdbpeekD(addr) - skip one word starting at 'addr', then read the second 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 +} /* * Functions ``special'' enough to print by name @@ -105,6 +115,9 @@ } 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 = 0; int more, stksize, j; + const uintptr_t kseg0_start = sizeof (uintptr_t) == 8 + ? 0x8000000000000000ULL : 0x80000000; /* 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 = 0; subr = 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 = (uintptr_t) panic; + else if (pcBetween(MipsKernGenException, MipsUserGenException)) subr = (uintptr_t)MipsKernGenException; else if (pcBetween(MipsUserGenException, MipsKernIntr)) subr = (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 = 0; goto done; @@ -303,32 +320,34 @@ mask |= (1 << i.IType.rt); switch (i.IType.rt) { case 4:/* a0 */ - args[0] = kdbpeekD((int *)(sp + (short)i.IType.imm)); + args[0] = kdbpeekD((sp + (short)i.IType.imm)); valid_args[0] = 1; break; case 5:/* a1 */ - args[1] = kdbpeekD((int *)(sp + (short)i.IType.imm)); + args[1] = kdbpeekD((sp + (short)i.IType.imm)); valid_args[1] = 1; break; case 6:/* a2 */ - args[2] = kdbpeekD((int *)(sp + (short)i.IType.imm)); + args[2] = kdbpeekD((sp + (short)i.IType.imm)); valid_args[2] = 1; break; case 7:/* a3 */ - args[3] = kdbpeekD((int *)(sp + (short)i.IType.imm)); + args[3] = kdbpeekD((sp + (short)i.IType.imm)); valid_args[3] = 1; break; case 31: /* ra */ - ra = kdbpeekD((int *)(sp + (short)i.IType.imm)); + ra = kdbpeekD((sp + (short)i.IType.imm)); } break; case OP_ADDI: case OP_ADDIU: + case OP_DADDIU: + case OP_DADDI: /* look for stack pointer adjustment */ if (i.IType.rs != 29 || i.IType.rt != 29) break; @@ -337,17 +356,18 @@ } done: - (*printfn) ("%s+%x (", fn_name(subr), pc - subr); + (*printfn) ("%s+%lx (", fn_name(subr), (unsigned long) (pc - subr)); for (j = 0; j < 4; j ++) { if (j > 0) (*printfn)(","); if (valid_args[j]) - (*printfn)("%x", args[j]); + (*printfn)("%lx", (unsigned long) args[j]); else (*printfn)("?"); } - (*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); if (ra) { if (pc == ra && stksize == 0) @@ -403,8 +423,12 @@ struct pcb *ctx; if (thr == curthread) { - sp = (register_t)(intptr_t)__builtin_frame_address(0); - ra = (register_t)(intptr_t)__builtin_return_address(0); + __asm __volatile( + "move %0, $sp\n" + : "=r" (sp)); + __asm __volatile( + "move %0, $ra\n" + : "=r" (ra)); __asm __volatile( "jal 99f\n" === modified file 'mips/mips/exception.S' --- mips/mips/exception.S 2010-08-13 22:16:49 +0000 +++ mips/mips/exception.S 2010-08-17 02:58:48 +0000 @@ -83,10 +83,10 @@ /* Pointer size and mask for n64 */ #if defined(__mips_n64) #define PTRSHIFT 3 -#define PTRMASK 0xff8 +#define PTRMASK (TLB_PAGE_MASK & ~7) #else #define PTRSHIFT 2 -#define PTRMASK 0xffc +#define PTRMASK (TLB_PAGE_MASK & ~3) #endif /* @@ -127,7 +127,7 @@ MipsDoTLBMiss: bltz k0, 1f #02: k0<0 -> 1f (kernel fault) PTR_SRL k0, k0, SEGSHIFT - PTRSHIFT #03: k0=seg offset (almost) - + GET_CPU_PCPU(k1) PTR_L k1, PC_SEGBASE(k1) beqz k1, 2f #05: make sure segbase is not null @@ -146,7 +146,7 @@ beq k1, zero, 2f # ==0 -- no page table #endif PTR_SRL k0, PAGE_SHIFT - 2 #0b: k0=VPN (aka va>>10) - andi k0, k0, 0xff8 #0c: k0=page tab offset + andi k0, k0, TLB_PAGE_MASK & ~7 #0c: k0=page tab offset PTR_ADDU k1, k1, k0 #0d: k1=pte address lw k0, 0(k1) #0e: k0=lo0 pte lw k1, 4(k1) #0f: k1=lo0 pte @@ -156,7 +156,11 @@ CLEAR_PTE_SWBITS(k1) MTC0 k1, MIPS_COP_0_TLB_LO1 #15: lo1 is loaded COP0_SYNC + li k0, TLBMASK_MASK + MTC0 k0, MIPS_COP_0_TLB_PG_MASK + COP0_SYNC tlbwr #1a: write to tlb + HAZARD_DELAY eret #1f: retUrn from exception 1: j MipsTLBMissException #20: kernel exception @@ -846,7 +850,7 @@ #endif MFC0 k0, MIPS_COP_0_BAD_VADDR # k0=bad address (again) PTR_SRL k0, PAGE_SHIFT - 2 # k0=VPN - andi k0, k0, 0xffc # k0=page tab offset + andi k0, k0, TLB_PAGE_MASK & ~3 # k0=page tab offset PTR_ADDU k1, k1, k0 # k1=pte address lw k0, 0(k1) # k0=this PTE @@ -868,6 +872,10 @@ CLEAR_PTE_SWBITS(k1) MTC0 k1, MIPS_COP_0_TLB_LO1 COP0_SYNC + li k0, TLB_PAGE_MASK + MTC0 k0, MIPS_COP_0_TLB_PG_MASK + COP0_SYNC + b tlb_insert_entry nop @@ -881,6 +889,9 @@ CLEAR_PTE_SWBITS(k1) MTC0 k1, MIPS_COP_0_TLB_LO1 COP0_SYNC + li k0, TLBMASK_MASK + MTC0 k0, MIPS_COP_0_TLB_PG_MASK + COP0_SYNC tlb_insert_entry: tlbp @@ -890,12 +901,12 @@ nop tlbwi eret - ssnop + SSNOP tlb_insert_random: tlbwr eret - ssnop + SSNOP 3: /* @@ -927,7 +938,8 @@ sll k1, k1, PAGE_SHIFT + 1 PTR_LA k0, _C_LABEL(pcpu_space) - PTR_ADDU k0, PAGE_SIZE * 2 + PTR_ADDU k0, PAGE_SIZE + PTR_ADDU k0, PAGE_SIZE PTR_ADDU k0, k0, k1 /* @@ -1013,7 +1025,7 @@ beq k1, zero, MipsKernGenException # ==0 -- no page table #endif PTR_SRL k0, PAGE_SHIFT - 2 # k0=VPN - andi k0, k0, 0xff8 # k0=page tab offset + andi k0, k0, TLB_PAGE_MASK & ~7 # k0=page tab offset PTR_ADDU k1, k1, k0 # k1=pte address lw k0, 0(k1) # k0=lo0 pte lw k1, 4(k1) # k1=lo1 pte @@ -1023,6 +1035,9 @@ CLEAR_PTE_SWBITS(k1) MTC0 k1, MIPS_COP_0_TLB_LO1 # lo1 is loaded COP0_SYNC + li k0, TLBMASK_MASK + MTC0 k0, MIPS_COP_0_TLB_PG_MASK + COP0_SYNC tlbwr # write to tlb HAZARD_DELAY eret # return from exception === modified file 'mips/mips/locore.S' --- mips/mips/locore.S 2010-08-13 22:16:49 +0000 +++ mips/mips/locore.S 2010-08-15 08:13:33 +0000 @@ -69,9 +69,38 @@ #include #include #include +#define ASM_FILE +#include "multiboot2.h" #include "assym.s" + .section ".multiboot", "a" + + /* Align 64 bits boundary. */ + .align 8 + + /* 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 + (multiboot_header_end - multiboot_header)) +framebuffer_tag_start: + .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 /* 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 === modified file 'mips/mips/machdep.c' --- mips/mips/machdep.c 2010-08-13 22:16:49 +0000 +++ mips/mips/machdep.c 2010-08-17 11:49:47 +0000 @@ -232,7 +232,8 @@ void cpu_flush_dcache(void *ptr, size_t len) { - /* TBD */ + mips_dcache_wbinv_range((vm_offset_t)ptr, len); + mips_sdcache_wbinv_range((vm_offset_t)ptr, len); } /* 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(); /* * 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!"); } === 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 04:18:27 +0000 @@ -272,6 +272,7 @@ * on the BSP. */ mips_dcache_wbinv_all(); + mips_sdcache_wbinv_all(); mips_icache_sync_all(); mips_sync(); === added file 'mips/mips/multiboot2.h' --- mips/mips/multiboot2.h 1970-01-01 00:00:00 +0000 +++ mips/mips/multiboot2.h 2010-08-13 22:20:49 +0000 @@ -0,0 +1,314 @@ +/* multiboot2.h - Multiboot 2 header file. */ +/* Copyright (C) 1999,2003,2007,2008,2009,2010 Free Software Foundation, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ANY + * DEVELOPER OR DISTRIBUTOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT 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]; +}; + +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 */ === modified file 'mips/mips/nexus.c' --- mips/mips/nexus.c 2010-08-13 22:16:49 +0000 +++ mips/mips/nexus.c 2010-08-15 11:56:05 +0000 @@ -151,7 +151,7 @@ } mem_rman.rm_start = 0; - mem_rman.rm_end = ~0u; + mem_rman.rm_end = ~(uintptr_t)0; mem_rman.rm_type = RMAN_ARRAY; mem_rman.rm_descr = "Memory addresses"; if (rman_init(&mem_rman) != 0 || === modified file 'mips/mips/pmap.c' --- mips/mips/pmap.c 2010-08-13 22:16:49 +0000 +++ mips/mips/pmap.c 2010-08-17 11:36:08 +0000 @@ -3252,16 +3252,16 @@ int rw; if (!(prot & VM_PROT_WRITE)) - rw = PTE_V | PTE_RO | PTE_C_CACHE; + rw = PTE_RO; else if ((m->flags & (PG_FICTITIOUS | PG_UNMANAGED)) == 0) { if ((m->md.pv_flags & PV_TABLE_MOD) != 0) - rw = PTE_V | PTE_D | PTE_C_CACHE; + rw = PTE_D; else - rw = PTE_V | PTE_C_CACHE; + rw = 0; vm_page_flag_set(m, PG_WRITEABLE); } else /* Needn't emulate a modified bit for unmanaged pages. */ - rw = PTE_V | PTE_D | PTE_C_CACHE; + rw = PTE_D; return (rw); } === 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:58:23 +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 the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS 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 +#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 = 0; + *flags = 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 >= 8) + return (NULL); + sc = &sc_softcs[unit]; + sc->unit = unit; + if ((sc->flags & SC_INIT_DONE) == 0) { + sc->keyboard = -1; + sc->adapter = -1; + sc->cursor_char = SC_CURSOR_CHAR; + sc->mouse_char = SC_MOUSE_CHAR; + } + return (sc); +} + +void +sc_get_bios_values(bios_values_t *values) +{ + values->cursor_start = 0; + values->cursor_end = 32; + values->shift_state = 0; +} + +int +sc_tone(int hz) +{ + return (0); +} === modified file 'mips/mips/support.S' --- mips/mips/support.S 2010-08-13 22:16:49 +0000 +++ mips/mips/support.S 2010-08-13 22:20:49 +0000 @@ -97,6 +97,8 @@ #include "assym.s" +#define MAKE_FRAMES 1 + .set noreorder # Noreorder is default style! /* @@ -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) - /* * bcmp(s1, s2, n) */ === modified file 'mips/mips/swtch.S' --- mips/mips/swtch.S 2010-08-13 22:16:49 +0000 +++ mips/mips/swtch.S 2010-08-17 04:01:47 +0000 @@ -308,6 +308,8 @@ MTC0 t1, MIPS_COP_0_TLB_HI mtc0 zero, MIPS_COP_0_TLB_LO0 mtc0 zero, MIPS_COP_0_TLB_LO1 + li t1, TLBMASK_MASK + MTC0 t1, MIPS_COP_0_TLB_PG_MASK HAZARD_DELAY tlbwi HAZARD_DELAY @@ -320,6 +322,8 @@ mtc0 a1, MIPS_COP_0_TLB_LO0 # upte[0] HAZARD_DELAY mtc0 a2, MIPS_COP_0_TLB_LO1 # upte[1] + li t1, TLBMASK_MASK + MTC0 t1, MIPS_COP_0_TLB_PG_MASK HAZARD_DELAY tlbwi # set TLB entry #0 HAZARD_DELAY === modified file 'mips/mips/tlb.c' --- mips/mips/tlb.c 2010-08-13 22:16:49 +0000 +++ mips/mips/tlb.c 2010-08-17 04:08:12 +0000 @@ -100,7 +100,7 @@ asid = mips_rd_entryhi() & TLBHI_ASID_MASK; mips_wr_index(i); - mips_wr_pagemask(0); + mips_wr_pagemask(TLBMASK_MASK); mips_wr_entryhi(TLBHI_ENTRY(va, 0)); mips_wr_entrylo0(pte0); mips_wr_entrylo1(pte1); @@ -122,7 +122,7 @@ s = intr_disable(); asid = mips_rd_entryhi() & TLBHI_ASID_MASK; - mips_wr_pagemask(0); + mips_wr_pagemask(TLBMASK_MASK); mips_wr_entryhi(TLBHI_ENTRY(va, pmap_asid(pmap))); tlb_probe(); i = mips_rd_index(); @@ -219,7 +219,7 @@ s = intr_disable(); asid = mips_rd_entryhi() & TLBHI_ASID_MASK; - mips_wr_pagemask(0); + mips_wr_pagemask(TLBMASK_MASK); mips_wr_entryhi(TLBHI_ENTRY(va, pmap_asid(pmap))); tlb_probe(); i = mips_rd_index(); @@ -245,7 +245,7 @@ mips_wr_entryhi(TLBHI_ENTRY(MIPS_KSEG0_START + (2 * i * PAGE_SIZE), 0)); mips_wr_entrylo0(0); mips_wr_entrylo1(0); - mips_wr_pagemask(0); + mips_wr_pagemask(TLBMASK_MASK); mips_wr_index(i); tlb_write_indexed(); } === 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:23:26 +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 = sf_buf_alloc(m, 0); @@ -131,7 +132,10 @@ if (sf != 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 = (char *)iov->iov_base + cnt; iov->iov_len -= cnt; uio->uio_resid -= cnt; === added directory 'mips/yeeloong' === 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:31:37 +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 the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * 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) != 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 = device_get_unit(dev); + sc = *(atkbdc_softc_t **)device_get_softc(dev); + if (sc == 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 = atkbdc_get_softc(unit); + if (sc == NULL) + return ENOMEM; + } + + rid = 0; + sc->retry = 5000; + sc->port0 = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, + 0x60, + 0x60, + 1, RF_ACTIVE); + if (sc->port0 == NULL) + return ENXIO; + + rid = 1; + sc->port1 = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, + 0x64, + 0x64, + 1, RF_ACTIVE); + if (sc->port1 == NULL) { + bus_release_resource(dev, SYS_RES_IOPORT, 0, sc->port0); + return ENXIO; + } + + error = 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) = sc; + + cdev = device_add_child(dev, ATKBD_DRIVER_NAME, -1); + adi = malloc(sizeof(struct atkbdc_device), M_ATKBDDEV, + M_NOWAIT | M_ZERO); + + if (cdev && adi) + { + int intr = 1; + adi->rid = 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[] = { + 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 = { + ATKBDC_DRIVER_NAME, + atkbdc_yeeloong_methods, + sizeof(atkbdc_softc_t *), +}; + + +DRIVER_MODULE(atkbdc, geode, atkbdc_driver, atkbdc_devclass, 0, 0); === 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:54: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 the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS 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. + * + * $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)0xbfe00118) +#define PCI_INTEDGE_REG (*(volatile uint32_t *)(intptr_t)(int32_t)0xbfe00124) +#define PCI_INTPOL_REG (*(volatile uint32_t *)(intptr_t)(int32_t)0xbfe0012c) +#define PCI_INTENSET_REG (*(volatile uint32_t *)(intptr_t)(int32_t)0xbfe00130) +#define PCI_INTENCLR_REG (*(volatile uint32_t *)(intptr_t)(int32_t)0xbfe00134) +#define PCI_INTEN_REG (*(volatile uint32_t *)(intptr_t)(int32_t)0xbfe00138) +#define PCI_INTISR_REG (*(volatile uint32_t *)(intptr_t)(int32_t)0xbfe0013c) +#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) != 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 = sc_in; + + while ((i = fls(PCI_INTISR_REG & PCI_INTEN_REG & HANDLED_INTERRUPTS)) + != 0) { + i--; /* Get a 0-offset interrupt. */ + PCI_INTENCLR_REG = (1 << i); + PCI_INTENSET_REG = (1 << i); + event = 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) != 0) { + printf("stray bonito interrupt %d\n", i); + } + } +} + +static int +bonito_attach(device_t dev) +{ + struct bonito_softc *sc; + int error; + + sc = device_get_softc(dev); + + mtx_init(&sc->config_mtx, "bonito_cfg", + "Bonito configuration space mutex", MTX_SPIN | MTX_QUIET); + + sc->sc_irq.rm_type = RMAN_ARRAY; + sc->sc_irq.rm_descr = "Bonito PCI IRQs"; + error = rman_init(&sc->sc_irq); + if (error != 0) + return (error); + + error = rman_manage_region(&sc->sc_irq, 0, BONITO_NUM_INTS - 1); + if (error != 0) + return (error); + + PCI_INTENCLR_REG = ~0; + PCI_INTPOL_REG = (1 << 12) | (1 << 11); + PCI_INTEDGE_REG = 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 = RMAN_ARRAY; + sc->sc_io.rm_descr = "Bonito PCI I/O Ports"; + error = rman_init(&sc->sc_io); + if (error != 0) + return (error); + + error = rman_manage_region(&sc->sc_io, 0x0, 0x100000); + if (error != 0) + return (error); + + sc->sc_mem.rm_type = RMAN_ARRAY; + sc->sc_mem.rm_descr = "Bonito PCI Memory"; + error = rman_init(&sc->sc_mem); + if (error != 0) + return (error); + + (*(volatile uint32_t *) (intptr_t) (int32_t) 0xbfe00104) = 0; + (*(volatile uint32_t *) (intptr_t) (int32_t) 0xbfe00110) + = (0) | (1 << 6) | (2 << 12); + + error = rman_manage_region(&sc->sc_mem, 0x1000, 0xc000000); + if (error != 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 *result) +{ + if (which == PCIB_IVAR_DOMAIN || which == PCIB_IVAR_BUS) + { + *result = 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_int reg, + int bytes) +{ + intptr_t addr; + uint32_t ret; + struct bonito_softc *sc; + + sc = device_get_softc(dev); + + addr = (int32_t) (PCI_CONFSPACE | (func << 8) | (reg & ~(bytes - 1))); + + mtx_lock_spin(&sc->config_mtx); + PCI_CONF_CTRL_REG = (1 << slot); + + switch (bytes) { + case 4: + ret = *((volatile uint32_t *) addr); + break; + case 2: + ret = *((volatile uint16_t *) addr); + break; + case 1: + ret = *((volatile uint8_t *) addr); + break; + default: + ret = ((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 = device_get_softc(dev); + + addr = (int32_t) (PCI_CONFSPACE | (func << 8) | (reg & ~(bytes - 1))); + + mtx_lock_spin(&sc->config_mtx); + + PCI_CONF_CTRL_REG = (1 << slot); + + switch (bytes) { + case 4: + *((volatile uint32_t *) addr) = data; + break; + case 2: + *((volatile uint16_t *) addr) = data; + break; + case 1: + *((volatile uint8_t *) addr) = data; + break; + default: + break; + } + mtx_unlock_spin(&sc->config_mtx); +} + +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 = device_get_softc(bus); + + switch (type) { + case SYS_RES_IRQ: + rm = &sc->sc_irq; + break; + case SYS_RES_MEMORY: + rm = &sc->sc_mem; + break; + case SYS_RES_IOPORT: + /* Low ports already have specific uses. Unless user + explicitly asks for low port allocate from other range. */ + if (end >= 0x1000) + start = 0x1000; + rm = &sc->sc_io; + break; + default: + return (NULL); + } + + res = rman_reserve_resource(rm, start, end, count, flags, child); + if (res == 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) != 0) { + error = bus_activate_resource(child, type, *rid, res); + if (error != 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 = bus_space_map(rman_get_bustag(res), + rman_get_bushandle(res), rman_get_size(res), 0, &bh); + if (error != 0) + return (error); + rman_set_bushandle(res, bh); + break; + default: + return (ENXIO); + } + + error = rman_activate_resource(res); + if (error != 0) + return (error); + return (0); +} + +static void +bonito_mask_irq(void *source) +{ + uintptr_t irq = (uintptr_t)source; + + PCI_INTENCLR_REG = (1 << irq); +} + +static void +bonito_unmask_irq(void *source) +{ + uintptr_t irq = (uintptr_t)source; + + PCI_INTENSET_REG = (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, + void *arg, void **cookiep) +{ + struct bonito_softc *sc; + int irq; + struct intr_event *event; + int error; + + sc = device_get_softc(bus); + + irq = rman_get_start (res); + + if (irq < 0 || irq >= BONITO_NUM_INTS) + return ENXIO; + + event = sc->intr_events[irq]; + if (event == NULL) { + error = 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] = 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 = device_get_softc(bus); + + irq = rman_get_start (res); + + if (irq < 0 || irq >= BONITO_NUM_INTS) + return (ENXIO); + + event = 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[] = { + /* 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 = { + "pcib", + bonito_methods, + sizeof(struct bonito_softc), +}; +static devclass_t bonito_devclass; +DRIVER_MODULE(bonito_pci, nexus, bonito_driver, bonito_devclass, 0, 0); === added file 'mips/yeeloong/clock.c' --- mips/yeeloong/clock.c 1970-01-01 00:00:00 +0000 +++ mips/yeeloong/clock.c 2010-08-13 22:20:49 +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 the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of RMI Corporation, nor the names of its contributors, + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS 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. + * + * RMI_BSD + */ + + +#include /* RCS ID & Copyright macro defns */ +__FBSDID("$FreeBSD: src/sys/mips/rmi/clock.c,v 1.3 2010/04/17 01:17:31 jmallett 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 = platform_counter_freq / hz; + uint64_t cycles_per_usec; + + cycles_per_usec = counter_freq / (1 * 1000 * 1000); + /* + * This works by polling the timer and counting the number of + * microseconds that go by. + */ + last = platform_get_timecount(NULL); + delta = usecs = 0; + + while (n > usecs) { + cur = platform_get_timecount(NULL); + + /* Check to see if the timer has wrapped around. */ + if (cur < last) + delta += (cur + (cycles_per_hz - last)); + else + delta += (cur - last); + + last = cur; + + if (delta >= cycles_per_usec) { + usecs += delta / cycles_per_usec; + delta %= cycles_per_usec; + } + } +} === added file 'mips/yeeloong/files.yeeloong' --- mips/yeeloong/files.yeeloong 1970-01-01 00:00:00 +0000 +++ mips/yeeloong/files.yeeloong 2010-08-15 19:28:13 +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.* = /static keymap_t key_map = /' -e 's/^static accentmap_t.* = /static accentmap_t accent_map = /' > 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 === added file 'mips/yeeloong/obio.c' --- mips/yeeloong/obio.c 1970-01-01 00:00:00 +0000 +++ mips/yeeloong/obio.c 2010-08-16 16:16:44 +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 the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * 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 prior + * 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 PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC + * 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. + */ + +/* + * 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) != 0) + return (ENXIO); + device_set_desc(dev, "obio"); + return (0); +} + +int +obio_attach(device_t dev) +{ + struct obio_softc *sc = device_get_softc(dev); + + sc->oba_st = mips_bus_space_generic; + sc->oba_addr = (intptr_t)(int32_t)0xbff003f8; + sc->oba_size = 0x8; + sc->oba_rman.rm_type = RMAN_ARRAY; + sc->oba_rman.rm_descr = "OBIO I/O"; + if (rman_init(&sc->oba_rman) != 0 || + rman_manage_region(&sc->oba_rman, + sc->oba_addr, sc->oba_addr + sc->oba_size) != 0) + panic("obio_attach: failed to set up I/O rman"); + + /* + * This module is intended for UART purposes only and + * it's IRQ is 1 + */ + sc->oba_irq_rman.rm_type = RMAN_ARRAY; + sc->oba_irq_rman.rm_descr = "OBIO IRQ"; + if (rman_init(&sc->oba_irq_rman) != 0 || + rman_manage_region(&sc->oba_irq_rman, 1, 1) != 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 = 0; + bus_space_handle_t bh = 0; + struct obio_softc *sc = device_get_softc(bus); + + switch (type) { + case SYS_RES_IRQ: + rm = &sc->oba_irq_rman; + break; + case SYS_RES_MEMORY: + return (NULL); + case SYS_RES_IOPORT: + rm = &sc->oba_rman; + bt = sc->oba_st; + bh = sc->oba_addr; + start = bh; + break; + default: + return (NULL); + } + + + rv = rman_reserve_resource(rm, start, end, count, flags, child); + if (rv == NULL) + return (NULL); + if (type == SYS_RES_IRQ) + return (rv); + rman_set_rid(rv, *rid); + rman_set_bustag(rv, bt); + rman_set_bushandle(rv, bh); + + 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 != SYS_RES_IOPORT) + return (bus_generic_release_resource(bus, child, type, rid, r)); + + return (rman_release_resource(r)); +} + +static device_method_t obio_methods[] = { + 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 = { + "obio", + obio_methods, + sizeof(struct obio_softc), +}; +static devclass_t obio_devclass; + +DRIVER_MODULE(obio, nexus, obio_driver, obio_devclass, 0, 0); === added file 'mips/yeeloong/std.yeeloong' --- mips/yeeloong/std.yeeloong 1970-01-01 00:00:00 +0000 +++ mips/yeeloong/std.yeeloong 2010-08-16 20:47:35 +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=defined +makeoptions ARCH_FLAGS="-march=mips3 -DTARGET_YEELOONG=1" +makeoptions LDSCRIPT_NAME= ldscript.mips +makeoptions KERNLOADADDR=0x80100000 + + +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 + === 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:43:22 +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 the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS 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 + * $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 file 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.1 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[] = { + /* 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 = { + 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 = 0; + + if (device_get_unit(dev) != 0 || probed) + return (ENXIO); + probed = 1; + + sc = device_get_softc(dev); + sc->sc_sysdev = SLIST_FIRST(&uart_sysdevs); + sc->sc_class = &uart_ns8250_class; + if (sc->sc_sysdev) + { + bcopy(&sc->sc_sysdev->bas, &sc->sc_bas, sizeof(sc->sc_bas)); + sc->sc_sysdev->bas.bst = mips_bus_space_generic; + sc->sc_sysdev->bas.bsh = (intptr_t) (int32_t) 0xbff003f8; + sc->sc_sysdev->bas.rclk = 1843200 * 2; + } + sc->sc_bas.bst = mips_bus_space_generic; + sc->sc_bas.bsh = (intptr_t) (int32_t) 0xbff003f8; + sc->sc_bas.rclk = 1843200 * 2; + + return(uart_bus_probe(dev, 0, 1843200 * 2, 0, 0)); +} + +DRIVER_MODULE(uart, obio, uart_yeeloong_driver, uart_devclass, 0, 0); === 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-13 22:20:49 +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 the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS 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. + * + * $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 file 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.1 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 == b2->bsh && b1->bst == b2->bst) ? 1 : 0); +} + +int +uart_cpu_getdev(int devtype, struct uart_devinfo *di) +{ + di->ops = uart_getops(&uart_ns8250_class); + di->bas.chan = 0; + di->bas.bst = mips_bus_space_generic; + di->bas.regshft = 0; + di->bas.rclk = 1843200 * 2; + di->baudrate = 115200; + di->databits = 8; + di->stopbits = 1; + di->parity = UART_PARITY_NONE; + + uart_bus_space_io = (void *) (intptr_t) (int32_t) 0xbff003f8; + uart_bus_space_mem = (void *) (intptr_t) (int32_t) 0xbff003f8; + di->bas.bsh = (intptr_t) (int32_t) 0xbff003f8; + return (0); +} === 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 21:56:51 +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 the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES 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 MIND, 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: 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) 0xbfd00381) +#define EC_MAGIC_PORT2 *((volatile uint8_t *) (intptr_t) (int32_t) 0xbfd00382) +#define EC_DATA_PORT *((volatile uint8_t *) (intptr_t) (int32_t) 0xbfd00383) + +#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) 0xbfe00120) +#define LOONGSON_SHUTDOWN_GPIO 1 + +static inline void +write_ec (uint8_t value) +{ + EC_MAGIC_PORT1 = EC_MAGIC_VAL1; + EC_MAGIC_PORT2 = EC_MAGIC_VAL2; + EC_DATA_PORT = value; +} + + +void +platform_halt(void) +{ + LOONGSON_GPIOCFG &= ~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 = 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 != MULTIBOOT2_BOOTLOADER_MAGIC) + return; + tag = (struct multiboot_tag *) (a1 + 8); + for (; tag->type != MULTIBOOT_TAG_TYPE_END; + tag = (void *) ((uint8_t *) tag + ((tag->size + 7) & ~7))) + { + switch (tag->type) + { + case MULTIBOOT_TAG_TYPE_CMDLINE: + { + struct multiboot_tag_string *tagt = (void *) tag; + char *ptr = tagt->string; + init_static_kenv (kenv_buf, sizeof (kenv_buf)); + while (*ptr) + { + char *ptr1, *ptr2, c1, c2; + while (*ptr == ' ') + ptr++; + ptr1 = ptr; + while (*ptr && *ptr != '=' && *ptr != ' ') + ptr++; + if (*ptr != '=') + { + if (sizeof ("verbose") - 1 == ptr - ptr1 + && memcmp (ptr1, "verbose", + sizeof ("verbose") - 1) + == 0) + boothowto |= RB_VERBOSE; + if (*ptr1 == '-') + { + for (ptr1++; ptr1 < ptr; ptr1++) + switch (*ptr1) + { + case 'v': + boothowto |= RB_VERBOSE; + break; + case 'D': + boothowto |= RB_MULTIPLE; + break; + case 'h': + boothowto |= RB_SERIAL; + } + } + continue; + } + ptr2 = ptr; + while (*ptr && *ptr != ' ') + ptr++; + c1 = *ptr2; + c2 = *ptr; + *ptr2 = 0; + *ptr = 0; + + setenv (ptr1, ptr2 + 1); + *ptr2 = c1; + *ptr = c2; + } + } + break; + case MULTIBOOT_TAG_TYPE_MMAP: + { + struct multiboot_tag_mmap *tagt = (void *) tag; + struct multiboot_mmap_entry *entry; + vm_offset_t memstart; + int i, cur = 0; + uint64_t totalmem = 0; + memstart = ((((vm_offset_t)&end) + 0xfffff) + & 0x1ff00000); + for (i = 0; i < 10; i++) { + phys_avail[i] = 0; + } + + for (entry = tagt->entries; + (uint8_t *) entry - (uint8_t *) tag < tag->size + && cur < 10; + entry = (void *) ((uint8_t *) entry + + tagt->entry_size)) + { + uint64_t start, end; + if (entry->type != MULTIBOOT_MEMORY_AVAILABLE) + continue; + start = entry->addr; + end = entry->addr + entry->len; + + if (start < memstart) + start = memstart; + /* FIXME: support post-256MiB memory. */ + if (end > 0x10000000) + end = 0x10000000; + + if (start >= end) + continue; + + totalmem += end - start; + + /* phys_avail regions are in bytes */ + phys_avail[cur] = start; + phys_avail[cur + 1] = end; + cur += 2; + } + realmem = btoc(totalmem); + physmem = realmem; + + } + break; + case MULTIBOOT_TAG_TYPE_FRAMEBUFFER: + { + struct multiboot_tag_framebuffer *tagt + = (void *) tag; + int window; + unsigned offset; + unsigned window_start_addr; + +// if (tagt->common.framebuffer_addr < 0xffffffffb0000000 + // || tagt->common.framebuffer_addr >= 0xffffffffbc000000) + //break; + + if (tagt->common.framebuffer_type != MULTIBOOT_FRAMEBUFFER_TYPE_RGB) + break; + + offset = tagt->common.framebuffer_addr & 0x3ffffff; + window = (tagt->common.framebuffer_addr >> 26) & 0x3; + + mbvid_params.width = tagt->common.framebuffer_width; + mbvid_params.height = tagt->common.framebuffer_height; +#if 0 + mbvidadapter.va_info.vi_depth = tagt->common.framebuffer_bpp; + mbvidadapter.va_info.vi_pixel_size = (tagt->common.framebuffer_bpp + 7) / 8; + mbvidadapter.va_info.vi_pixel_fields[0] = tagt->color.direct.framebuffer_red_field_position; + mbvidadapter.va_info.vi_pixel_fsizes[0] = tagt->color.direct.framebuffer_red_mask_size; + mbvidadapter.va_info.vi_pixel_fields[1] = tagt->color.direct.framebuffer_green_field_position; + mbvidadapter.va_info.vi_pixel_fsizes[1] = tagt->color.direct.framebuffer_green_mask_size; + mbvidadapter.va_info.vi_pixel_fields[2] = tagt->color.direct.framebuffer_blue_field_position; + mbvidadapter.va_info.vi_pixel_fsizes[2] = tagt->color.direct.framebuffer_blue_mask_size; +#endif + window_start_addr = ((*(volatile uint32_t *) (intptr_t) (int32_t) 0xbfe00110) >> (6 * window)) & 0x3f; + if (window_start_addr >= 3) + break; + window_start_addr <<= 26; + mbvid_params.ptr = + (void *) (((intptr_t) (int32_t) 0xb0000000) + | window_start_addr | offset); +#if 0 + mbvidadapter.va_mem_size = tagt->common.framebuffer_pitch + * tagt->common.framebuffer_height; + mbvidadapter.va_line_width = tagt->common.framebuffer_pitch; + mbvidadapter.va_info.vi_window = mbvidadapter.va_mem_base & 0x1fffffff; + mbvidadapter.va_info.vi_window_size = mbvidadapter.va_mem_size; +#endif + + fb_found = 1; + } + } + } +} + +void +platform_start(__register_t a0, __register_t a1, + __register_t a2 __unused, __register_t a3 __unused) +{ + /* FIXME: retrieve from multiboot2 info. */ + uint64_t platform_counter_freq = 400 * 1000 * 1000; + + { + vm_offset_t va, eva; + va = MIPS_PHYS_TO_KSEG0(0); + eva = va + 0x8000; + + 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 += (32 * 32); + } + + SYNC; + } + + { + vm_offset_t va, eva; + + va = MIPS_PHYS_TO_KSEG0(0); + eva = va + 0x80000; + + 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 += (32 * 32); + } + + SYNC; + } + + mips_pcpu0_init(); + mips_timer_early_init (platform_counter_freq); + + boothowto = 0; + + parse_multiboot (a0, a1); + + (*(volatile uint32_t *) (intptr_t) (int32_t) 0xbfe00110) + = (0) | (1 << 6) | (2 << 12); + + attach_mbvid (); + + cninit(); + + mtx_init(&clock_lock, "clk", NULL, MTX_SPIN | MTX_NOPROFILE); + + bootverbose = !!(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[] = { + /* 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 = { + "mbvid", + sc_methods, + sizeof(sc_softc_t) +}; + +static devclass_t sc_devclass; + +DRIVER_MODULE(sc, nexus, mbvid_sc_driver, sc_devclass, 0, 0); === modified file 'sys/fbio.h' --- sys/fbio.h 2010-08-13 22:16:49 +0000 +++ sys/fbio.h 2010-08-14 15:29:18 +0000 @@ -86,7 +86,9 @@ #define FBTYPE_TCXCOLOR 29 /* SUNW,tcx */ #define FBTYPE_CREATOR 30 -#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) */ /* * 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; === modified file 'vm/vm_fault.c' --- vm/vm_fault.c 2010-08-13 22:16:49 +0000 +++ vm/vm_fault.c 2010-08-17 16:40:21 +0000 @@ -979,6 +979,9 @@ vm_page_t m; vm_object_t object; + if (PAGE_SIZE == 1 << 14) + return; + if (pmap != vmspace_pmap(curthread->td_proc->p_vmspace)) return; === 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:51:53 +0000 @@ -65,6 +65,39 @@ * RTC support routines */ +#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 != reg) { + ADDR_PORT = reg; + rtc_reg = reg; + } + val = DATA_PORT; + RTC_UNLOCK; + return (val); +} + +void +writertc(int reg, u_char val) +{ + + RTC_LOCK; + if (rtc_reg != reg) { + ADDR_PORT = reg; + rtc_reg = reg; + } + DATA_PORT = val; + RTC_UNLOCK; +} +#else int rtcin(int reg) { @@ -97,9 +130,10 @@ inb(0x84); RTC_UNLOCK; } +#endif static __inline int -readrtc(int port) +readrtcbcd(int port) { return(bcd2bin(rtcin(port))); } @@ -112,6 +146,7 @@ writertc(RTC_STATUSB, RTCSB_24HR); } +#ifndef TARGET_YEELOONG static void atrtc_rate(unsigned rate) { @@ -137,6 +172,7 @@ writertc(RTC_STATUSB, rtc_statusb); rtcin(RTC_INTR); } +#endif void atrtc_restore(void) @@ -162,6 +198,7 @@ struct eventtimer et; }; +#ifndef TARGET_YEELOONG static int rtc_start(struct eventtimer *et, struct bintime *first, struct bintime *period) @@ -223,6 +260,11 @@ { 0 } }; +#endif + + +#ifndef TARGET_YEELOONG + static int atrtc_probe(device_t dev) { @@ -237,26 +279,49 @@ return (result); } +#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) != 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; sc = device_get_softc(dev); +#ifndef TARGET_YEELOONG if (!(sc->port_res = 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 = rtcin(RTC_DIAG); if (diag != 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) != 0 || i != 0)) { + int i; + u_long s; sc->intr_rid = 0; while (bus_get_resource(dev, SYS_RES_IRQ, sc->intr_rid, &s, NULL) == 0 && s != 8) @@ -288,14 +353,16 @@ sc->et.et_priv = dev; et_register(&sc->et); } +#endif return(0); } static int atrtc_resume(device_t dev) { - +#ifndef TARGET_YEELOONG atrtc_restore(); +#endif return(0); } @@ -309,17 +376,34 @@ /* Disable RTC updates and interrupts. */ writertc(RTC_STATUSB, RTCSB_HALT | RTCSB_24HR); - 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 */ + + 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 */ + + 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 + } /* Reenable RTC updates and interrupts. */ writertc(RTC_STATUSB, rtc_statusb); @@ -346,19 +430,39 @@ splx(s); s = splhigh(); } - ct.nsec = 0; - ct.sec = readrtc(RTC_SEC); - ct.min = readrtc(RTC_MIN); - ct.hour = readrtc(RTC_HRS); - ct.day = readrtc(RTC_DAY); - ct.dow = readrtc(RTC_WDAY) - 1; - ct.mon = readrtc(RTC_MONTH); - ct.year = readrtc(RTC_YEAR); -#ifdef USE_RTC_CENTURY - ct.year += readrtc(RTC_CENTURY) * 100; -#else - ct.year += 2000; -#endif + + if (rtcin (RTC_STATUSB) & RTCSB_BINARY) + { + ct.nsec = 0; + ct.sec = rtcin(RTC_SEC); + ct.min = rtcin(RTC_MIN); + ct.hour = rtcin(RTC_HRS); + ct.day = rtcin(RTC_DAY); + ct.dow = rtcin(RTC_WDAY) - 1; + ct.mon = rtcin(RTC_MONTH); + ct.year = rtcin(RTC_YEAR); +#ifdef USE_RTC_CENTURY + ct.year += rtcin(RTC_CENTURY) * 100; +#else + ct.year += 2000; +#endif + } + else + { + ct.nsec = 0; + ct.sec = readrtcbcd(RTC_SEC); + ct.min = readrtcbcd(RTC_MIN); + ct.hour = readrtcbcd(RTC_HRS); + ct.day = readrtcbcd(RTC_DAY); + ct.dow = readrtcbcd(RTC_WDAY) - 1; + ct.mon = readrtcbcd(RTC_MONTH); + ct.year = readrtcbcd(RTC_YEAR); +#ifdef USE_RTC_CENTURY + ct.year += readrtcbcd(RTC_CENTURY) * 100; +#else + ct.year += 2000; +#endif + } /* Set dow = -1 because some clocks don't set it correctly. */ ct.dow = -1; return (clock_ct_to_ts(&ct, ts)); @@ -366,6 +470,7 @@ static device_method_t atrtc_methods[] = { /* 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 @@ static devclass_t atrtc_devclass; +#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 + #include "opt_ddb.h" #ifdef DDB