From owner-svn-src-user@FreeBSD.ORG Sun Aug 22 19:09:18 2010 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id B4E141065672; Sun, 22 Aug 2010 19:09:18 +0000 (UTC) (envelope-from nwhitehorn@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 992B88FC0A; Sun, 22 Aug 2010 19:09:18 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id o7MJ9Ia6012233; Sun, 22 Aug 2010 19:09:18 GMT (envelope-from nwhitehorn@svn.freebsd.org) Received: (from nwhitehorn@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o7MJ9IUZ012226; Sun, 22 Aug 2010 19:09:18 GMT (envelope-from nwhitehorn@svn.freebsd.org) Message-Id: <201008221909.o7MJ9IUZ012226@svn.freebsd.org> From: Nathan Whitehorn Date: Sun, 22 Aug 2010 19:09:18 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r211636 - in user/nwhitehorn/ps3/powerpc: include ps3 X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 22 Aug 2010 19:09:18 -0000 Author: nwhitehorn Date: Sun Aug 22 19:09:18 2010 New Revision: 211636 URL: http://svn.freebsd.org/changeset/base/211636 Log: Get interrupts functioning, along with a few other minor things. The kernel now can transmit and receive network traffic, mounts root, and gets several thousand packets in before hanging. Modified: user/nwhitehorn/ps3/powerpc/include/cpufunc.h user/nwhitehorn/ps3/powerpc/include/spr.h user/nwhitehorn/ps3/powerpc/ps3/if_glc.c user/nwhitehorn/ps3/powerpc/ps3/platform_ps3.c user/nwhitehorn/ps3/powerpc/ps3/ps3bus.c user/nwhitehorn/ps3/powerpc/ps3/ps3pic.c Modified: user/nwhitehorn/ps3/powerpc/include/cpufunc.h ============================================================================== --- user/nwhitehorn/ps3/powerpc/include/cpufunc.h Sun Aug 22 19:06:20 2010 (r211635) +++ user/nwhitehorn/ps3/powerpc/include/cpufunc.h Sun Aug 22 19:09:18 2010 (r211636) @@ -106,6 +106,17 @@ mfsrin(vm_offset_t va) } #endif +static __inline register_t +mfctrl(void) +{ + register_t value; + + __asm __volatile ("mfspr %0,136" : "=r"(value)); + + return (value); +} + + static __inline void mtdec(register_t value) { Modified: user/nwhitehorn/ps3/powerpc/include/spr.h ============================================================================== --- user/nwhitehorn/ps3/powerpc/include/spr.h Sun Aug 22 19:06:20 2010 (r211635) +++ user/nwhitehorn/ps3/powerpc/include/spr.h Sun Aug 22 19:09:18 2010 (r211636) @@ -423,7 +423,7 @@ #define SPR_HID6 0x3f9 /* ..8 Hardware Implementation Register 6 */ #define SPR_CELL_TSRL 0x380 /* ... Cell BE Thread Status Register */ -#define SPR_CELL_TSCR 0x399 /* ... Cell BE Thread Status Register */ +#define SPR_CELL_TSCR 0x399 /* ... Cell BE Thread Switch Register */ #if defined(AIM) #define SPR_DBSR 0x3f0 /* 4.. Debug Status Register */ Modified: user/nwhitehorn/ps3/powerpc/ps3/if_glc.c ============================================================================== --- user/nwhitehorn/ps3/powerpc/ps3/if_glc.c Sun Aug 22 19:06:20 2010 (r211635) +++ user/nwhitehorn/ps3/powerpc/ps3/if_glc.c Sun Aug 22 19:09:18 2010 (r211636) @@ -128,32 +128,15 @@ glc_attach(device_t dev) sc->next_txdma_slot = sc->first_used_txdma_slot = 0; /* - * Open device, and shut down existing tasks. + * Shut down existing tasks. */ - err = lv1_open_device(sc->sc_bus, sc->sc_dev, 0); - if (err) { - device_printf(dev, "Error opening device: %d\n", err); - mtx_destroy(&sc->sc_mtx); - return (ENXIO); - } - lv1_net_stop_tx_dma(sc->sc_bus, sc->sc_dev, 0); lv1_net_stop_rx_dma(sc->sc_bus, sc->sc_dev, 0); sc->sc_ifp = if_alloc(IFT_ETHER); sc->sc_ifp->if_softc = sc; -/* Wait for link */ -for (i = 0; i < 1000; i++) { - lv1_net_control(sc->sc_bus, sc->sc_dev, GELIC_GET_LINK_STATUS, 2, 0, - 0, &val, &junk); - if (val & GELIC_LINK_UP) - break; - DELAY(500); -} - - /* * Get MAC address and VLAN id */ @@ -357,7 +340,6 @@ glc_start_locked(struct ifnet *ifp) mtx_assert(&sc->sc_mtx, MA_OWNED); first = 0; -printf("Transmitting packet!\n"); while (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) { IFQ_DRV_DEQUEUE(&ifp->if_snd, mb_head); @@ -614,7 +596,6 @@ glc_rxintr(struct glc_softc *sc) { int i, restart_rxdma; struct mbuf *m; - uint16_t tag; struct ifnet *ifp = sc->sc_ifp; bus_dmamap_sync(sc->sc_dmadesc_tag, sc->sc_rxdmadesc_map, @@ -640,27 +621,11 @@ glc_rxintr(struct glc_softc *sc) m->m_len = sc->sc_rxdmadesc[i].valid_size; m->m_pkthdr.len = m->m_len; sc->sc_next_rxdma_slot++; + if (sc->sc_next_rxdma_slot >= GLC_MAX_RX_PACKETS) + sc->sc_next_rxdma_slot = 0; - if (sc->sc_rx_vlan >= 0) { - struct ether_vlan_header *evl; - if (m->m_len < sizeof(*evl) && - (m = m_pullup(m, sizeof(*evl))) == NULL) { - if_printf(ifp, "cannot pullup VLAN header\n"); - return; - } - evl = mtod(m, struct ether_vlan_header *); - tag = EVL_VLANOFTAG(ntohs(evl->evl_tag)); - - /* - * Remove the 802.1q header by copying the Ethernet - * addresses over it and adjusting the beginning of - * the data in the mbuf. The encapsulated Ethernet - * type field is already in place. - */ - bcopy((char *)evl, (char *)evl + ETHER_VLAN_ENCAP_LEN, - ETHER_HDR_LEN - ETHER_TYPE_LEN); - m_adj(m, ETHER_VLAN_ENCAP_LEN); - } + if (sc->sc_rx_vlan >= 0) + m_adj(m, 2); mtx_unlock(&sc->sc_mtx); (*ifp->if_input)(ifp, m); @@ -725,12 +690,11 @@ glc_intr(void *xsc) mtx_lock(&sc->sc_mtx); - if (sc->sc_interrupt_status == 0) { + if (*sc->sc_interrupt_status == 0) { device_printf(sc->sc_self, "stray interrupt!\n"); mtx_unlock(&sc->sc_mtx); return; } -printf("GLC Interrupt!\n"); if (*sc->sc_interrupt_status & (GELIC_INT_RXDONE | GELIC_INT_RXFRAME)) glc_rxintr(sc); Modified: user/nwhitehorn/ps3/powerpc/ps3/platform_ps3.c ============================================================================== --- user/nwhitehorn/ps3/powerpc/ps3/platform_ps3.c Sun Aug 22 19:06:20 2010 (r211635) +++ user/nwhitehorn/ps3/powerpc/ps3/platform_ps3.c Sun Aug 22 19:09:18 2010 (r211636) @@ -192,7 +192,7 @@ static int ps3_smp_start_cpu(platform_t plat, struct pcpu *pc) { #ifdef SMP - /* loader(8) is spinning on 0x40 == 1 right now */ + /* loader(8) is spinning on 0x40 == 0 right now */ uint32_t *secondary_spin_sem = (uint32_t *)(0x40); int timeout; Modified: user/nwhitehorn/ps3/powerpc/ps3/ps3bus.c ============================================================================== --- user/nwhitehorn/ps3/powerpc/ps3/ps3bus.c Sun Aug 22 19:06:20 2010 (r211635) +++ user/nwhitehorn/ps3/powerpc/ps3/ps3bus.c Sun Aug 22 19:09:18 2010 (r211636) @@ -62,6 +62,12 @@ struct ps3bus_devinfo { static MALLOC_DEFINE(M_PS3BUS, "ps3bus", "PS3 system bus device information"); +enum ps3bus_irq_type { + SB_IRQ = 2, + OHCI_IRQ = 3, + EHCI_IRQ = 4, +}; + static device_method_t ps3bus_methods[] = { /* Device interface */ DEVMETHOD(device_identify, ps3bus_identify), @@ -75,6 +81,8 @@ static device_method_t ps3bus_methods[] DEVMETHOD(bus_read_ivar, ps3bus_read_ivar), DEVMETHOD(bus_alloc_resource, ps3bus_alloc_resource), DEVMETHOD(bus_activate_resource, ps3bus_activate_resource), + DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), + DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), { 0, 0 } }; @@ -112,13 +120,18 @@ ps3bus_probe(device_t dev) static void ps3bus_resources_init(int bus_index, int dev_index, struct resource_list *rl) { - uint64_t irq_type, irq; + uint64_t irq_type, irq, outlet; uint64_t reg_type, paddr, len; + uint64_t bus, dev, ppe; uint64_t junk; int i, result; + int thread; resource_list_init(rl); + lv1_get_logical_ppe_id(&ppe); + thread = 32 - fls(mfctrl()); + /* Scan for interrupts */ for (i = 0; i < 10; i++) { result = lv1_get_repository_node_value(PS3_LPAR_ID_PME, @@ -129,7 +142,35 @@ ps3bus_resources_init(int bus_index, int if (result != 0) break; - resource_list_add(rl, SYS_RES_IRQ, i, irq, irq, 1); + lv1_get_repository_node_value(PS3_LPAR_ID_PME, + (lv1_repository_string("bus") >> 32) | bus_index, + lv1_repository_string("id"), 0, 0, &bus, &junk); + lv1_get_repository_node_value(PS3_LPAR_ID_PME, + (lv1_repository_string("bus") >> 32) | bus_index, + lv1_repository_string("dev") | dev_index, + lv1_repository_string("id"), 0, &dev, &junk); + + switch (irq_type) { + case SB_IRQ: + lv1_construct_event_receive_port(&outlet); + lv1_connect_irq_plug_ext(ppe, thread, outlet, outlet, + 0); + lv1_connect_interrupt_event_receive_port(bus, dev, + outlet, irq); + break; + case OHCI_IRQ: + case EHCI_IRQ: + lv1_construct_io_irq_outlet(irq, &outlet); + lv1_connect_irq_plug_ext(ppe, thread, outlet, outlet, + 0); + break; + default: + printf("Unknown IRQ type %ld for device %ld.%ld\n", + irq_type, bus, dev); + break; + } + + resource_list_add(rl, SYS_RES_IRQ, i, outlet, outlet, 1); } /* Scan for registers */ @@ -212,6 +253,9 @@ ps3bus_attach(device_t self) dinfo->bustype = bustype; dinfo->devtype = devtype; + if (dinfo->bustype == PS3_BUSTYPE_SYSBUS) + lv1_open_device(bus, dev, 0); + ps3bus_resources_init(bus_index, dev_index, &dinfo->resources); Modified: user/nwhitehorn/ps3/powerpc/ps3/ps3pic.c ============================================================================== --- user/nwhitehorn/ps3/powerpc/ps3/ps3pic.c Sun Aug 22 19:06:20 2010 (r211635) +++ user/nwhitehorn/ps3/powerpc/ps3/ps3pic.c Sun Aug 22 19:09:18 2010 (r211636) @@ -31,7 +31,10 @@ #include #include #include -#include +#include + +#include +#include #include #include @@ -53,6 +56,15 @@ static void ps3pic_mask(device_t, u_int) static void ps3pic_unmask(device_t, u_int); static uint32_t ps3pic_id(device_t dev); +struct ps3pic_softc { + uint64_t *bitmap_thread0; + uint64_t *mask_thread0; + uint64_t *bitmap_thread1; + uint64_t *mask_thread1; + + int sc_vector[64]; +}; + static device_method_t ps3pic_methods[] = { /* Device interface */ DEVMETHOD(device_identify, ps3pic_identify), @@ -74,13 +86,15 @@ static device_method_t ps3pic_methods[] static driver_t ps3pic_driver = { "ps3pic", ps3pic_methods, - 0 + sizeof(struct ps3pic_softc) }; static devclass_t ps3pic_devclass; DRIVER_MODULE(ps3pic, nexus, ps3pic_driver, ps3pic_devclass, 0, 0); +static MALLOC_DEFINE(M_PS3PIC, "ps3pic", "PS3 PIC"); + static void ps3pic_identify(driver_t *driver, device_t parent) { @@ -101,9 +115,31 @@ ps3pic_probe(device_t dev) static int ps3pic_attach(device_t dev) { + struct ps3pic_softc *sc; + uint64_t ppe; + int thread; + powerpc_register_pic(dev, 64); root_pic = dev; /* PS3s have only one PIC */ + sc = device_get_softc(dev); + + sc->bitmap_thread0 = contigmalloc(128 /* 512 bits * 2 */, M_PS3PIC, + M_NOWAIT | M_ZERO, 0, BUS_SPACE_MAXADDR, 64 /* alignment */, + PAGE_SIZE /* boundary */); + sc->mask_thread0 = sc->bitmap_thread0 + 4; + sc->bitmap_thread1 = sc->bitmap_thread0 + 8; + sc->mask_thread1 = sc->bitmap_thread0 + 12; + + lv1_get_logical_ppe_id(&ppe); + thread = 32 - fls(mfctrl()); + lv1_configure_irq_state_bitmap(ppe, thread, + vtophys(sc->bitmap_thread0)); +#ifdef SMP + lv1_configure_irq_state_bitmap(ppe, !thread, + vtophys(sc->bitmap_thread1)); +#endif + return (0); } @@ -114,16 +150,50 @@ ps3pic_attach(device_t dev) static void ps3pic_dispatch(device_t dev, struct trapframe *tf) { + uint64_t bitmap, mask; + int irq; + struct ps3pic_softc *sc; + + sc = device_get_softc(dev); + + if (PCPU_GET(cpuid) == 0) { + bitmap = sc->bitmap_thread0[0]; + mask = sc->mask_thread0[0]; + } else { + bitmap = sc->bitmap_thread1[0]; + mask = sc->mask_thread1[0]; + } + + while ((irq = ffsl(bitmap & mask) - 1) != -1) { + bitmap &= ~(1UL << irq); + powerpc_dispatch_intr(sc->sc_vector[63 - irq], tf); + } } static void ps3pic_enable(device_t dev, u_int irq, u_int vector) { + struct ps3pic_softc *sc; + + if (irq > 63) /* IPI */ + return; + + sc = device_get_softc(dev); + sc->sc_vector[irq] = vector; + + ps3pic_unmask(dev, irq); } static void -ps3pic_eoi(device_t dev __unused, u_int irq __unused) +ps3pic_eoi(device_t dev, u_int irq) { + uint64_t ppe; + int thread; + + lv1_get_logical_ppe_id(&ppe); + thread = 32 - fls(mfctrl()); + + lv1_end_of_interrupt_ext(ppe, thread, irq); } static void @@ -134,11 +204,31 @@ ps3pic_ipi(device_t dev, u_int irq) static void ps3pic_mask(device_t dev, u_int irq) { + struct ps3pic_softc *sc; + uint64_t ppe; + + sc = device_get_softc(dev); + sc->mask_thread0[0] &= ~(1UL << (63 - irq)); + sc->mask_thread1[0] &= ~(1UL << (63 - irq)); + + lv1_get_logical_ppe_id(&ppe); + lv1_did_update_interrupt_mask(ppe, 0); + lv1_did_update_interrupt_mask(ppe, 1); } static void ps3pic_unmask(device_t dev, u_int irq) { + struct ps3pic_softc *sc; + uint64_t ppe; + + sc = device_get_softc(dev); + sc->mask_thread0[0] |= (1UL << (63 - irq)); + sc->mask_thread1[0] |= (1UL << (63 - irq)); + + lv1_get_logical_ppe_id(&ppe); + lv1_did_update_interrupt_mask(ppe, 0); + lv1_did_update_interrupt_mask(ppe, 1); } static uint32_t