From 6e3272ee6f95f47c23efd8a0719b7b2e144035f1 Mon Sep 17 00:00:00 2001 From: Randall Stewart Date: Thu, 29 Oct 2009 15:55:25 +0000 Subject: [PATCH] more Updates on the RMI code close to compiling now ;-) --- sys/mips/rmi/board.c | 7 +- sys/mips/rmi/clock.c | 225 +++++++++++++++++------ sys/mips/rmi/clock.h | 2 +- sys/mips/rmi/ehcireg.h | 301 +++++++++++++++++++++++++++++++ sys/mips/rmi/ehcivar.h | 191 ++++++++++++++++++++ sys/mips/rmi/files.xlr | 9 +- sys/mips/rmi/intr_machdep.c | 28 +-- sys/mips/rmi/iodi.c | 67 ++++--- sys/mips/rmi/msgring.c | 2 +- sys/mips/rmi/msgring.h | 2 +- sys/mips/rmi/msgring_xls.c | 2 +- sys/mips/rmi/on_chip.c | 18 +- sys/mips/rmi/pcibus.c | 105 +++++++---- sys/mips/rmi/pcibus.h | 9 + sys/mips/rmi/perfmon.h | 2 +- sys/mips/rmi/perfmon_kern.c | 6 +- sys/mips/rmi/perfmon_percpu.c | 12 +- sys/mips/rmi/perfmon_xlrconfig.h | 2 +- sys/mips/rmi/pic.h | 2 +- sys/mips/rmi/std.xlr | 4 +- sys/mips/rmi/tick.c | 113 ++++++++++++ sys/mips/rmi/uart_cpu_mips_xlr.c | 17 +- sys/mips/rmi/xlr_boot1_console.c | 6 +- sys/mips/rmi/xlr_i2c.c | 2 +- sys/mips/rmi/xlr_machdep.c | 136 +++++++++----- sys/mips/rmi/xlr_pci.c | 14 +- sys/mips/rmi/xlrconfig.h | 4 +- sys/mips/rmi/xls_ehci.c | 9 +- 28 files changed, 1064 insertions(+), 233 deletions(-) create mode 100644 sys/mips/rmi/ehcireg.h create mode 100644 sys/mips/rmi/ehcivar.h create mode 100644 sys/mips/rmi/tick.c diff --git a/sys/mips/rmi/board.c b/sys/mips/rmi/board.c index 73d783d51848..e50101eb9688 100644 --- a/sys/mips/rmi/board.c +++ b/sys/mips/rmi/board.c @@ -35,9 +35,10 @@ #include #include -#include -#include -#include +#include +#include +#include +#include static int xlr_rxstn_to_txstn_map[128] = { [0 ... 7] = TX_STN_CPU_0, diff --git a/sys/mips/rmi/clock.c b/sys/mips/rmi/clock.c index 44ba886c2f3e..2e5e0486b94d 100644 --- a/sys/mips/rmi/clock.c +++ b/sys/mips/rmi/clock.c @@ -53,19 +53,24 @@ #include #include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include #ifdef XLR_PERFMON -#include +#include #endif -int hw_clockrate; -SYSCTL_INT(_hw, OID_AUTO, clockrate, CTLFLAG_RD, &hw_clockrate, - 0, "CPU instruction clock rate"); +uint64_t counter_freq; +uint64_t cycles_per_tick; +uint64_t cycles_per_usec; +uint64_t cycles_per_sec; +uint64_t cycles_per_hz; + +u_int32_t counter_upper = 0; +u_int32_t counter_lower_last = 0; #define STAT_PROF_CLOCK_SCALE_FACTOR 8 @@ -77,6 +82,15 @@ uint64_t platform_get_frequency() return XLR_PIC_HZ; } +void +mips_timer_early_init(uint64_t clock_hz) +{ + /* Initialize clock early so that we can use DELAY sooner */ + counter_freq = clock_hz; + cycles_per_usec = (clock_hz / (1000 * 1000)); + +} + /* * count_compare_clockhandler: * @@ -100,11 +114,11 @@ count_compare_clockhandler(struct trapframe *tf) cycles += XLR_CPU_HZ/hz; mips_wr_compare(cycles); - hardclock_process((struct clockframe *)tf); + hardclock_cpu(USERMODE(tf->sr)); if (count_scale_factor[cpu] == STAT_PROF_CLOCK_SCALE_FACTOR) { - statclock((struct clockframe *)tf); + statclock(USERMODE(tf->sr)); if(profprocs != 0) { - profclock((struct clockframe *)tf); + profclock(USERMODE(tf->sr), tf->pc); } count_scale_factor[cpu] = 0; } @@ -124,11 +138,11 @@ pic_hardclockhandler(struct trapframe *tf) if (cpu == 0) { scale_factor++; - hardclock((struct clockframe *)tf); + hardclock(USERMODE(tf->sr), tf->pc); if (scale_factor == STAT_PROF_CLOCK_SCALE_FACTOR) { - statclock((struct clockframe *)tf); + statclock(USERMODE(tf->sr)); if(profprocs != 0) { - profclock((struct clockframe *)tf); + profclock(USERMODE(tf->sr), tf->pc); } scale_factor = 0; } @@ -141,73 +155,164 @@ pic_hardclockhandler(struct trapframe *tf) else { /* If needed , handle count compare tick skew here */ } - critical_exit(); } -void +int pic_timecounthandler(struct trapframe *tf) { + return (FILTER_HANDLED); } void platform_initclocks(void) { - int cpu = PCPU_GET(cpuid); - void *cookie; + int cpu = PCPU_GET(cpuid); + void *cookie; - /* Note: Passing #3 as NULL ensures that clockhandler - * gets called with trapframe - */ - /* profiling/process accounting timer interrupt for non-zero cpus */ - cpu_establish_intr("compare", IRQ_TIMER, - (driver_intr_t *)count_compare_clockhandler, - NULL, INTR_TYPE_CLK|INTR_FAST, &cookie, NULL, NULL); + /* Note: Passing #3 as NULL ensures that clockhandler + * gets called with trapframe + */ + /* profiling/process accounting timer interrupt for non-zero cpus */ + cpu_establish_hardintr("compare", + NULL, + (driver_intr_t *)count_compare_clockhandler, + NULL, + IRQ_TIMER, + INTR_TYPE_CLK|INTR_FAST, &cookie); - /* timekeeping timer interrupt for cpu 0 */ - cpu_establish_intr("hardclk", PIC_TIMER_7_IRQ, - (driver_intr_t *)pic_hardclockhandler, - NULL, INTR_TYPE_CLK|INTR_FAST, &cookie, NULL, NULL); + /* timekeeping timer interrupt for cpu 0 */ + cpu_establish_hardintr("hardclk", + NULL, + (driver_intr_t *)pic_hardclockhandler, + NULL, + PIC_TIMER_7_IRQ, + INTR_TYPE_CLK|INTR_FAST, + &cookie); - /* this is used by timecounter */ - cpu_establish_intr("timecount", PIC_TIMER_6_IRQ, - (driver_intr_t *)pic_timecounthandler, - NULL, INTR_TYPE_CLK|INTR_FAST, &cookie, NULL, NULL); + /* this is used by timecounter */ + cpu_establish_hardintr("timecount", + (driver_filter_t *)pic_timecounthandler, NULL, + NULL, PIC_TIMER_6_IRQ, INTR_TYPE_CLK|INTR_FAST, + &cookie); + + if (cpu == 0) { + __uint64_t maxval = XLR_PIC_HZ/hz; + xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET); - if (cpu == 0) { - __uint64_t maxval = XLR_PIC_HZ/hz; - xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET); + stathz = hz / STAT_PROF_CLOCK_SCALE_FACTOR; + profhz = stathz; - stathz = hz / STAT_PROF_CLOCK_SCALE_FACTOR; - profhz = stathz; + /* Setup PIC Interrupt */ - /* Setup PIC Interrupt */ + mtx_lock_spin(&xlr_pic_lock); + xlr_write_reg(mmio, PIC_TIMER_7_MAXVAL_0, (maxval & 0xffffffff)); /* 0x100 + 7*/ + xlr_write_reg(mmio, PIC_TIMER_7_MAXVAL_1, (maxval >> 32) & 0xffffffff);/* 0x110 + 7 */ + /* 0x40 + 8 */ + /* reg 40 is lower bits 31-0 and holds CPU mask */ + xlr_write_reg(mmio, PIC_IRT_0_TIMER_7, (1 << cpu)); + /* 0x80 + 8 */ + /* Reg 80 is upper bits 63-32 and holds */ + /* Valid Edge Local IRQ */ + xlr_write_reg(mmio, PIC_IRT_1_TIMER_7, (1<<31)|(0<<30)|(1<<6)|(PIC_TIMER_7_IRQ)); + pic_update_control(1<<(8+7)); - mtx_lock_spin(&xlr_pic_lock); - xlr_write_reg(mmio, PIC_TIMER_7_MAXVAL_0, (maxval & 0xffffffff)); - xlr_write_reg(mmio, PIC_TIMER_7_MAXVAL_1, (maxval >> 32) & 0xffffffff); - xlr_write_reg(mmio, PIC_IRT_0_TIMER_7, (1 << cpu)); - xlr_write_reg(mmio, PIC_IRT_1_TIMER_7, (1<<31)|(0<<30)|(1<<6)|(PIC_TIMER_7_IRQ)); - pic_update_control(1<<(8+7)); - - xlr_write_reg(mmio, PIC_TIMER_6_MAXVAL_0, (0xffffffff & 0xffffffff)); - xlr_write_reg(mmio, PIC_TIMER_6_MAXVAL_1, (0x0) & 0xffffffff); - xlr_write_reg(mmio, PIC_IRT_0_TIMER_6, (1 << cpu)); - xlr_write_reg(mmio, PIC_IRT_1_TIMER_6, (1<<31)|(0<<30)|(1<<6)|(PIC_TIMER_6_IRQ)); - pic_update_control(1<<(8+6)); - mtx_unlock_spin(&xlr_pic_lock); - } else { - /* Setup count-compare interrupt for vcpu[1-31] */ - mips_wr_compare((xlr_boot1_info.cpu_frequency)/hz); - } + xlr_write_reg(mmio, PIC_TIMER_6_MAXVAL_0, (0xffffffff & 0xffffffff)); + xlr_write_reg(mmio, PIC_TIMER_6_MAXVAL_1, (0xffffffff & 0xffffffff)); + xlr_write_reg(mmio, PIC_IRT_0_TIMER_6, (1 << cpu)); + xlr_write_reg(mmio, PIC_IRT_1_TIMER_6, (1<<31)|(0<<30)|(1<<6)|(PIC_TIMER_6_IRQ)); + pic_update_control(1<<(8+6)); + mtx_unlock_spin(&xlr_pic_lock); + } else { + /* Setup count-compare interrupt for vcpu[1-31] */ + mips_wr_compare((xlr_boot1_info.cpu_frequency)/hz); + } } - - unsigned __attribute__((no_instrument_function)) -platform_get_timecount(struct timecounter *tc) +platform_get_timecount(struct timecounter *tc __unused) { xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET); return 0xffffffffU - xlr_read_reg(mmio, PIC_TIMER_6_COUNTER_0); } + +void +DELAY(int n) +{ + uint32_t cur, last, delta, usecs; + + /* + * 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; + } + } +} + +static +uint64_t read_pic_counter(void) +{ + xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET); + uint32_t lower, upper; + uint64_t tc; + /* Pull the value of the 64 bit counter which is stored in + * PIC register 120+N and 130+N + */ + upper = 0xffffffffU - xlr_read_reg(mmio, PIC_TIMER_6_COUNTER_1); + lower = 0xffffffffU - xlr_read_reg(mmio, PIC_TIMER_6_COUNTER_0); + tc = (((uint64_t)upper << 32) | (uint64_t)lower); + return(tc); +} + +extern struct timecounter counter_timecounter; + +void +mips_timer_init_params(uint64_t platform_counter_freq, int double_count) +{ + + /* + * XXX: Do not use printf here: uart code 8250 may use DELAY so this + * function should be called before cninit. + */ + counter_freq = platform_counter_freq; + /* + * XXX: Some MIPS32 cores update the Count register only every two + * pipeline cycles. + */ + if (double_count != 0) + counter_freq /= 2; + + cycles_per_tick = counter_freq / 1000; + cycles_per_hz = counter_freq / hz; + cycles_per_usec = counter_freq / (1 * 1000 * 1000); + cycles_per_sec = counter_freq ; + + counter_timecounter.tc_frequency = counter_freq; + printf("hz=%d cyl_per_hz:%jd cyl_per_usec:%jd freq:%jd cyl_per_hz:%jd cyl_per_sec:%jd\n", + hz, + cycles_per_tick, + cycles_per_usec, + counter_freq, + cycles_per_hz, + cycles_per_sec + ); + set_cputicker(read_pic_counter, counter_freq, 1); +} diff --git a/sys/mips/rmi/clock.h b/sys/mips/rmi/clock.h index c582de529fab..750c3dae127b 100644 --- a/sys/mips/rmi/clock.h +++ b/sys/mips/rmi/clock.h @@ -35,6 +35,6 @@ void count_compare_clockhandler(struct trapframe *); void pic_hardclockhandler(struct trapframe *); -void pic_timecounthandler(struct trapframe *); +int pic_timecounthandler(struct trapframe *); #endif /* _RMI_CLOCK_H_ */ diff --git a/sys/mips/rmi/ehcireg.h b/sys/mips/rmi/ehcireg.h new file mode 100644 index 000000000000..e1e7dc3a19e2 --- /dev/null +++ b/sys/mips/rmi/ehcireg.h @@ -0,0 +1,301 @@ +/* $NetBSD: ehcireg.h,v 1.18 2004/10/22 10:38:17 augustss Exp $ */ +/* $FreeBSD: src/sys/dev/usb/ehcireg.h,v 1.7.2.2.2.1 2008/10/02 02:57:24 kensmith Exp $ */ + +/*- + * Copyright (c) 2001 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Lennart Augustsson (lennart@augustsson.net). + * + * 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 by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation 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 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. + */ + +/* + * The EHCI 0.96 spec can be found at + * http://developer.intel.com/technology/usb/download/ehci-r096.pdf + * and the USB 2.0 spec at + * http://www.usb.org/developers/data/usb_20.zip + */ + +#ifndef _DEV_PCI_EHCIREG_H_ +#define _DEV_PCI_EHCIREG_H_ + +/*** PCI config registers ***/ + +#define PCI_CBMEM 0x10 /* configuration base MEM */ + +#define PCI_INTERFACE_EHCI 0x20 + +#define PCI_USBREV 0x60 /* RO USB protocol revision */ +#define PCI_USBREV_MASK 0xff +#define PCI_USBREV_PRE_1_0 0x00 +#define PCI_USBREV_1_0 0x10 +#define PCI_USBREV_1_1 0x11 +#define PCI_USBREV_2_0 0x20 + +#define PCI_EHCI_FLADJ 0x61 /*RW Frame len adj, SOF=59488+6*fladj */ + +#define PCI_EHCI_PORTWAKECAP 0x62 /* RW Port wake caps (opt) */ + +/* EHCI Extended Capabilities */ +#define EHCI_EC_LEGSUP 0x01 + +#define EHCI_EECP_NEXT(x) (((x) >> 8) & 0xff) +#define EHCI_EECP_ID(x) ((x) & 0xff) + +/* Legacy support extended capability */ +#define EHCI_LEGSUP_OS_SEM 0x03 /* OS owned semaphore */ +#define EHCI_LEGSUP_BIOS_SEM 0x02 /* BIOS owned semaphore */ +#define EHCI_LEGSUP_USBLEGCTLSTS 0x04 + +/*** EHCI capability registers ***/ + +#define EHCI_CAPLENGTH 0x00 /*RO Capability register length field */ +/* reserved 0x01 */ +#define EHCI_HCIVERSION 0x02 /* RO Interface version number */ + +#define EHCI_HCSPARAMS 0x04 /* RO Structural parameters */ +#define EHCI_HCS_DEBUGPORT(x) (((x) >> 20) & 0xf) +#define EHCI_HCS_P_INDICATOR(x) ((x) & 0x10000) +#define EHCI_HCS_N_CC(x) (((x) >> 12) & 0xf) /* # of companion ctlrs */ +#define EHCI_HCS_N_PCC(x) (((x) >> 8) & 0xf) /* # of ports per comp. */ +#define EHCI_HCS_PPC(x) ((x) & 0x10) /* port power control */ +#define EHCI_HCS_N_PORTS(x) ((x) & 0xf) /* # of ports */ + +#define EHCI_HCCPARAMS 0x08 /* RO Capability parameters */ +#define EHCI_HCC_EECP(x) (((x) >> 8) & 0xff) /* extended ports caps */ +#define EHCI_HCC_IST(x) (((x) >> 4) & 0xf) /* isoc sched threshold */ +#define EHCI_HCC_ASPC(x) ((x) & 0x4) /* async sched park cap */ +#define EHCI_HCC_PFLF(x) ((x) & 0x2) /* prog frame list flag */ +#define EHCI_HCC_64BIT(x) ((x) & 0x1) /* 64 bit address cap */ + +#define EHCI_HCSP_PORTROUTE 0x0c /*RO Companion port route description */ + +/* EHCI operational registers. Offset given by EHCI_CAPLENGTH register */ +#define EHCI_USBCMD 0x00 /* RO, RW, WO Command register */ +#define EHCI_CMD_ITC_M 0x00ff0000 /* RW interrupt threshold ctrl */ +#define EHCI_CMD_ITC_1 0x00010000 +#define EHCI_CMD_ITC_2 0x00020000 +#define EHCI_CMD_ITC_4 0x00040000 +#define EHCI_CMD_ITC_8 0x00080000 +#define EHCI_CMD_ITC_16 0x00100000 +#define EHCI_CMD_ITC_32 0x00200000 +#define EHCI_CMD_ITC_64 0x00400000 +#define EHCI_CMD_ASPME 0x00000800 /* RW/RO async park enable */ +#define EHCI_CMD_ASPMC 0x00000300 /* RW/RO async park count */ +#define EHCI_CMD_LHCR 0x00000080 /* RW light host ctrl reset */ +#define EHCI_CMD_IAAD 0x00000040 /* RW intr on async adv door bell */ +#define EHCI_CMD_ASE 0x00000020 /* RW async sched enable */ +#define EHCI_CMD_PSE 0x00000010 /* RW periodic sched enable */ +#define EHCI_CMD_FLS_M 0x0000000c /* RW/RO frame list size */ +#define EHCI_CMD_FLS(x) (((x) >> 2) & 3) /* RW/RO frame list size */ +#define EHCI_CMD_HCRESET 0x00000002 /* RW reset */ +#define EHCI_CMD_RS 0x00000001 /* RW run/stop */ + +#define EHCI_USBSTS 0x04 /* RO, RW, RWC Status register */ +#define EHCI_STS_ASS 0x00008000 /* RO async sched status */ +#define EHCI_STS_PSS 0x00004000 /* RO periodic sched status */ +#define EHCI_STS_REC 0x00002000 /* RO reclamation */ +#define EHCI_STS_HCH 0x00001000 /* RO host controller halted */ +#define EHCI_STS_IAA 0x00000020 /* RWC interrupt on async adv */ +#define EHCI_STS_HSE 0x00000010 /* RWC host system error */ +#define EHCI_STS_FLR 0x00000008 /* RWC frame list rollover */ +#define EHCI_STS_PCD 0x00000004 /* RWC port change detect */ +#define EHCI_STS_ERRINT 0x00000002 /* RWC error interrupt */ +#define EHCI_STS_INT 0x00000001 /* RWC interrupt */ +#define EHCI_STS_INTRS(x) ((x) & 0x3f) + +#define EHCI_NORMAL_INTRS (EHCI_STS_IAA | EHCI_STS_HSE | EHCI_STS_PCD | EHCI_STS_ERRINT | EHCI_STS_INT) + +#define EHCI_USBINTR 0x08 /* RW Interrupt register */ +#define EHCI_INTR_IAAE 0x00000020 /* interrupt on async advance ena */ +#define EHCI_INTR_HSEE 0x00000010 /* host system error ena */ +#define EHCI_INTR_FLRE 0x00000008 /* frame list rollover ena */ +#define EHCI_INTR_PCIE 0x00000004 /* port change ena */ +#define EHCI_INTR_UEIE 0x00000002 /* USB error intr ena */ +#define EHCI_INTR_UIE 0x00000001 /* USB intr ena */ + +#define EHCI_FRINDEX 0x0c /* RW Frame Index register */ + +#define EHCI_CTRLDSSEGMENT 0x10 /* RW Control Data Structure Segment */ + +#define EHCI_PERIODICLISTBASE 0x14 /* RW Periodic List Base */ +#define EHCI_ASYNCLISTADDR 0x18 /* RW Async List Base */ + +#define EHCI_CONFIGFLAG 0x40 /* RW Configure Flag register */ +#define EHCI_CONF_CF 0x00000001 /* RW configure flag */ + +#define EHCI_PORTSC(n) (0x40+4*(n)) /* RO, RW, RWC Port Status reg */ +#define EHCI_PS_WKOC_E 0x00400000 /* RW wake on over current ena */ +#define EHCI_PS_WKDSCNNT_E 0x00200000 /* RW wake on disconnect ena */ +#define EHCI_PS_WKCNNT_E 0x00100000 /* RW wake on connect ena */ +#define EHCI_PS_PTC 0x000f0000 /* RW port test control */ +#define EHCI_PS_PIC 0x0000c000 /* RW port indicator control */ +#define EHCI_PS_PO 0x00002000 /* RW port owner */ +#define EHCI_PS_PP 0x00001000 /* RW,RO port power */ +#define EHCI_PS_LS 0x00000c00 /* RO line status */ +#define EHCI_PS_IS_LOWSPEED(x) (((x) & EHCI_PS_LS) == 0x00000400) +#define EHCI_PS_PR 0x00000100 /* RW port reset */ +#define EHCI_PS_SUSP 0x00000080 /* RW suspend */ +#define EHCI_PS_FPR 0x00000040 /* RW force port resume */ +#define EHCI_PS_OCC 0x00000020 /* RWC over current change */ +#define EHCI_PS_OCA 0x00000010 /* RO over current active */ +#define EHCI_PS_PEC 0x00000008 /* RWC port enable change */ +#define EHCI_PS_PE 0x00000004 /* RW port enable */ +#define EHCI_PS_CSC 0x00000002 /* RWC connect status change */ +#define EHCI_PS_CS 0x00000001 /* RO connect status */ +#define EHCI_PS_CLEAR (EHCI_PS_OCC|EHCI_PS_PEC|EHCI_PS_CSC) + +#define EHCI_PORT_RESET_COMPLETE 2 /* ms */ + +#define EHCI_FLALIGN_ALIGN 0x1000 + +/* No data structure may cross a page boundary. */ +#define EHCI_PAGE_SIZE 0x1000 +#define EHCI_PAGE(x) ((x) &~ 0xfff) +#define EHCI_PAGE_OFFSET(x) ((x) & 0xfff) +#if defined(__FreeBSD__) +#define EHCI_PAGE_MASK(x) ((x) & 0xfff) +#endif + +typedef u_int32_t ehci_link_t; +#define EHCI_LINK_TERMINATE 0x00000001 +#define EHCI_LINK_TYPE(x) ((x) & 0x00000006) +#define EHCI_LINK_ITD 0x0 +#define EHCI_LINK_QH 0x2 +#define EHCI_LINK_SITD 0x4 +#define EHCI_LINK_FSTN 0x6 +#define EHCI_LINK_ADDR(x) ((x) &~ 0x1f) + +typedef u_int32_t ehci_physaddr_t; + +/* Isochronous Transfer Descriptor */ +typedef struct { + ehci_link_t itd_next; + /* XXX many more */ +} ehci_itd_t; +#define EHCI_ITD_ALIGN 32 + +/* Split Transaction Isochronous Transfer Descriptor */ +typedef struct { + ehci_link_t sitd_next; + /* XXX many more */ +} ehci_sitd_t; +#define EHCI_SITD_ALIGN 32 + +/* Queue Element Transfer Descriptor */ +#define EHCI_QTD_NBUFFERS 5 +typedef struct { + ehci_link_t qtd_next; + ehci_link_t qtd_altnext; + u_int32_t qtd_status; +#define EHCI_QTD_GET_STATUS(x) (((x) >> 0) & 0xff) +#define EHCI_QTD_SET_STATUS(x) ((x) << 0) +#define EHCI_QTD_ACTIVE 0x80 +#define EHCI_QTD_HALTED 0x40 +#define EHCI_QTD_BUFERR 0x20 +#define EHCI_QTD_BABBLE 0x10 +#define EHCI_QTD_XACTERR 0x08 +#define EHCI_QTD_MISSEDMICRO 0x04 +#define EHCI_QTD_SPLITXSTATE 0x02 +#define EHCI_QTD_PINGSTATE 0x01 +#define EHCI_QTD_STATERRS 0x7c +#define EHCI_QTD_GET_PID(x) (((x) >> 8) & 0x3) +#define EHCI_QTD_SET_PID(x) ((x) << 8) +#define EHCI_QTD_PID_OUT 0x0 +#define EHCI_QTD_PID_IN 0x1 +#define EHCI_QTD_PID_SETUP 0x2 +#define EHCI_QTD_GET_CERR(x) (((x) >> 10) & 0x3) +#define EHCI_QTD_SET_CERR(x) ((x) << 10) +#define EHCI_QTD_GET_C_PAGE(x) (((x) >> 12) & 0x7) +#define EHCI_QTD_SET_C_PAGE(x) ((x) << 12) +#define EHCI_QTD_GET_IOC(x) (((x) >> 15) & 0x1) +#define EHCI_QTD_IOC 0x00008000 +#define EHCI_QTD_GET_BYTES(x) (((x) >> 16) & 0x7fff) +#define EHCI_QTD_SET_BYTES(x) ((x) << 16) +#define EHCI_QTD_GET_TOGGLE(x) (((x) >> 31) & 0x1) +#define EHCI_QTD_SET_TOGGLE(x) ((x) << 31) +#define EHCI_QTD_TOGGLE_MASK 0x80000000 + ehci_physaddr_t qtd_buffer[EHCI_QTD_NBUFFERS]; + ehci_physaddr_t qtd_buffer_hi[EHCI_QTD_NBUFFERS]; +} ehci_qtd_t; +#define EHCI_QTD_ALIGN 32 + +/* Queue Head */ +typedef struct { + ehci_link_t qh_link; + u_int32_t qh_endp; +#define EHCI_QH_GET_ADDR(x) (((x) >> 0) & 0x7f) /* endpoint addr */ +#define EHCI_QH_SET_ADDR(x) (x) +#define EHCI_QH_ADDRMASK 0x0000007f +#define EHCI_QH_GET_INACT(x) (((x) >> 7) & 0x01) /* inactivate on next */ +#define EHCI_QH_INACT 0x00000080 +#define EHCI_QH_GET_ENDPT(x) (((x) >> 8) & 0x0f) /* endpoint no */ +#define EHCI_QH_SET_ENDPT(x) ((x) << 8) +#define EHCI_QH_GET_EPS(x) (((x) >> 12) & 0x03) /* endpoint speed */ +#define EHCI_QH_SET_EPS(x) ((x) << 12) +#define EHCI_QH_SPEED_FULL 0x0 +#define EHCI_QH_SPEED_LOW 0x1 +#define EHCI_QH_SPEED_HIGH 0x2 +#define EHCI_QH_GET_DTC(x) (((x) >> 14) & 0x01) /* data toggle control */ +#define EHCI_QH_DTC 0x00004000 +#define EHCI_QH_GET_HRECL(x) (((x) >> 15) & 0x01) /* head of reclamation */ +#define EHCI_QH_HRECL 0x00008000 +#define EHCI_QH_GET_MPL(x) (((x) >> 16) & 0x7ff) /* max packet len */ +#define EHCI_QH_SET_MPL(x) ((x) << 16) +#define EHCI_QH_MPLMASK 0x07ff0000 +#define EHCI_QH_GET_CTL(x) (((x) >> 27) & 0x01) /* control endpoint */ +#define EHCI_QH_CTL 0x08000000 +#define EHCI_QH_GET_NRL(x) (((x) >> 28) & 0x0f) /* NAK reload */ +#define EHCI_QH_SET_NRL(x) ((x) << 28) + u_int32_t qh_endphub; +#define EHCI_QH_GET_SMASK(x) (((x) >> 0) & 0xff) /* intr sched mask */ +#define EHCI_QH_SET_SMASK(x) ((x) << 0) +#define EHCI_QH_GET_CMASK(x) (((x) >> 8) & 0xff) /* split completion mask */ +#define EHCI_QH_SET_CMASK(x) ((x) << 8) +#define EHCI_QH_GET_HUBA(x) (((x) >> 16) & 0x7f) /* hub address */ +#define EHCI_QH_SET_HUBA(x) ((x) << 16) +#define EHCI_QH_GET_PORT(x) (((x) >> 23) & 0x7f) /* hub port */ +#define EHCI_QH_SET_PORT(x) ((x) << 23) +#define EHCI_QH_GET_MULT(x) (((x) >> 30) & 0x03) /* pipe multiplier */ +#define EHCI_QH_SET_MULT(x) ((x) << 30) + ehci_link_t qh_curqtd; + ehci_qtd_t qh_qtd; +} ehci_qh_t; +#define EHCI_QH_ALIGN 32 + +/* Periodic Frame Span Traversal Node */ +typedef struct { + ehci_link_t fstn_link; + ehci_link_t fstn_back; +} ehci_fstn_t; +#define EHCI_FSTN_ALIGN 32 + +#endif /* _DEV_PCI_EHCIREG_H_ */ diff --git a/sys/mips/rmi/ehcivar.h b/sys/mips/rmi/ehcivar.h new file mode 100644 index 000000000000..eb318ad03c2e --- /dev/null +++ b/sys/mips/rmi/ehcivar.h @@ -0,0 +1,191 @@ +/* $NetBSD: ehcivar.h,v 1.19 2005/04/29 15:04:29 augustss Exp $ */ +/* $FreeBSD: src/sys/dev/usb/ehcivar.h,v 1.9.2.1.8.1 2008/10/02 02:57:24 kensmith Exp $ */ + +/*- + * Copyright (c) 2001 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Lennart Augustsson (lennart@augustsson.net). + * + * 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 by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation 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 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. + */ + +typedef struct ehci_soft_qtd { + ehci_qtd_t qtd; + struct ehci_soft_qtd *nextqtd; /* mirrors nextqtd in TD */ + ehci_physaddr_t physaddr; + usbd_xfer_handle xfer; + LIST_ENTRY(ehci_soft_qtd) hnext; + u_int16_t len; +} ehci_soft_qtd_t; +#define EHCI_SQTD_SIZE ((sizeof (struct ehci_soft_qtd) + EHCI_QTD_ALIGN - 1) / EHCI_QTD_ALIGN * EHCI_QTD_ALIGN) +#define EHCI_SQTD_CHUNK (EHCI_PAGE_SIZE / EHCI_SQTD_SIZE) + +typedef struct ehci_soft_qh { + ehci_qh_t qh; + struct ehci_soft_qh *next; + struct ehci_soft_qh *prev; + struct ehci_soft_qtd *sqtd; + ehci_physaddr_t physaddr; + int islot; /* Interrupt list slot. */ +} ehci_soft_qh_t; +#define EHCI_SQH_SIZE ((sizeof (struct ehci_soft_qh) + EHCI_QH_ALIGN - 1) / EHCI_QH_ALIGN * EHCI_QH_ALIGN) +#define EHCI_SQH_CHUNK (EHCI_PAGE_SIZE / EHCI_SQH_SIZE) + +struct ehci_xfer { + struct usbd_xfer xfer; + struct usb_task abort_task; + LIST_ENTRY(ehci_xfer) inext; /* list of active xfers */ + ehci_soft_qtd_t *sqtdstart; + ehci_soft_qtd_t *sqtdend; + u_int32_t ehci_xfer_flags; +#ifdef DIAGNOSTIC + int isdone; +#endif +}; +#define EHCI_XFER_ABORTING 0x0001 /* xfer is aborting. */ +#define EHCI_XFER_ABORTWAIT 0x0002 /* abort completion is being awaited. */ + +#define EXFER(xfer) ((struct ehci_xfer *)(xfer)) + +/* + * Information about an entry in the interrupt list. + */ +struct ehci_soft_islot { + ehci_soft_qh_t *sqh; /* Queue Head. */ +}; + +#define EHCI_FRAMELIST_MAXCOUNT 1024 +#define EHCI_IPOLLRATES 8 /* Poll rates (1ms, 2, 4, 8 ... 128) */ +#define EHCI_INTRQHS ((1 << EHCI_IPOLLRATES) - 1) +#define EHCI_MAX_POLLRATE (1 << (EHCI_IPOLLRATES - 1)) +#define EHCI_IQHIDX(lev, pos) \ + ((((pos) & ((1 << (lev)) - 1)) | (1 << (lev))) - 1) +#define EHCI_ILEV_IVAL(lev) (1 << (lev)) + +#define EHCI_HASH_SIZE 128 +#define EHCI_COMPANION_MAX 8 + +#define EHCI_SCFLG_DONEINIT 0x0001 /* ehci_init() has been called. */ +#define EHCI_SCFLG_LOSTINTRBUG 0x0002 /* workaround for VIA / ATI chipsets */ + +typedef struct ehci_softc { + struct usbd_bus sc_bus; /* base device */ + int sc_flags; + bus_space_tag_t iot; + bus_space_handle_t ioh; + bus_size_t sc_size; +#if defined(__FreeBSD__) + void *ih; + + struct resource *io_res; + struct resource *irq_res; +#endif + u_int sc_offs; /* offset to operational regs */ + + char sc_vendor[32]; /* vendor string for root hub */ + int sc_id_vendor; /* vendor ID for root hub */ + + u_int32_t sc_cmd; /* shadow of cmd reg during suspend */ +#if defined(__NetBSD__) || defined(__OpenBSD__) + void *sc_powerhook; /* cookie from power hook */ + void *sc_shutdownhook; /* cookie from shutdown hook */ +#endif + + u_int sc_ncomp; + u_int sc_npcomp; + struct usbd_bus *sc_comps[EHCI_COMPANION_MAX]; + + usb_dma_t sc_fldma; + ehci_link_t *sc_flist; + u_int sc_flsize; +#ifndef __FreeBSD__ + u_int sc_rand; /* XXX need proper intr scheduling */ +#endif + + struct ehci_soft_islot sc_islots[EHCI_INTRQHS]; + + LIST_HEAD(, ehci_xfer) sc_intrhead; + + ehci_soft_qh_t *sc_freeqhs; + ehci_soft_qtd_t *sc_freeqtds; + + int sc_noport; + u_int8_t sc_addr; /* device address */ + u_int8_t sc_conf; /* device configuration */ + usbd_xfer_handle sc_intrxfer; + char sc_isreset; +#ifdef USB_USE_SOFTINTR + char sc_softwake; +#endif /* USB_USE_SOFTINTR */ + + u_int32_t sc_eintrs; + ehci_soft_qh_t *sc_async_head; + + SIMPLEQ_HEAD(, usbd_xfer) sc_free_xfers; /* free xfers */ + + struct lock sc_doorbell_lock; + + usb_callout_t sc_tmo_pcd; + usb_callout_t sc_tmo_intrlist; + +#if defined(__NetBSD__) || defined(__OpenBSD__) + device_ptr_t sc_child; /* /dev/usb# device */ +#endif + char sc_dying; +#if defined(__NetBSD__) + struct usb_dma_reserve sc_dma_reserve; +#endif +} ehci_softc_t; + +#define EREAD1(sc, a) bus_space_read_1((sc)->iot, (sc)->ioh, (a)) +#define EREAD2(sc, a) bus_space_read_2((sc)->iot, (sc)->ioh, (a)) +#define EREAD4(sc, a) bus_space_read_4((sc)->iot, (sc)->ioh, (a)) +#define EWRITE1(sc, a, x) bus_space_write_1((sc)->iot, (sc)->ioh, (a), (x)) +#define EWRITE2(sc, a, x) bus_space_write_2((sc)->iot, (sc)->ioh, (a), (x)) +#define EWRITE4(sc, a, x) bus_space_write_4((sc)->iot, (sc)->ioh, (a), (x)) +#define EOREAD1(sc, a) bus_space_read_1((sc)->iot, (sc)->ioh, (sc)->sc_offs+(a)) +#define EOREAD2(sc, a) bus_space_read_2((sc)->iot, (sc)->ioh, (sc)->sc_offs+(a)) +#define EOREAD4(sc, a) bus_space_read_4((sc)->iot, (sc)->ioh, (sc)->sc_offs+(a)) +#define EOWRITE1(sc, a, x) bus_space_write_1((sc)->iot, (sc)->ioh, (sc)->sc_offs+(a), (x)) +#define EOWRITE2(sc, a, x) bus_space_write_2((sc)->iot, (sc)->ioh, (sc)->sc_offs+(a), (x)) +#define EOWRITE4(sc, a, x) bus_space_write_4((sc)->iot, (sc)->ioh, (sc)->sc_offs+(a), (x)) + +usbd_status ehci_init(ehci_softc_t *); +int ehci_intr(void *); +int ehci_detach(ehci_softc_t *, int); +#if defined(__NetBSD__) || defined(__OpenBSD__) +int ehci_activate(device_ptr_t, enum devact); +#endif +void ehci_power(int state, void *priv); +void ehci_shutdown(void *v); + +#define MS_TO_TICKS(ms) ((ms) * hz / 1000) + diff --git a/sys/mips/rmi/files.xlr b/sys/mips/rmi/files.xlr index 736e434ffb85..4cdd361c87f3 100644 --- a/sys/mips/rmi/files.xlr +++ b/sys/mips/rmi/files.xlr @@ -1,13 +1,14 @@ # $FreeBSD$ -mips/rmi/xlr_boot1_console.c standard +#mips/rmi/xlr_boot1_console.c standard mips/rmi/xlr_machdep.c standard -#mips/rmi/clock.c standard +mips/rmi/clock.c standard +mips/rmi/tick.c standard mips/rmi/iodi.c standard mips/rmi/msgring.c standard mips/rmi/msgring_xls.c standard mips/rmi/board.c standard mips/rmi/on_chip.c standard -mips/rmip/intr_machdep.c standard +mips/rmi/intr_machdep.c standard mips/rmi/xlr_i2c.c optional iic mips/rmi/uart_bus_xlr_iodi.c optional uart mips/rmi/uart_cpu_mips_xlr.c optional uart @@ -15,7 +16,7 @@ mips/rmi/perfmon_kern.c optional xlr_perfmon mips/rmi/perfmon_percpu.c optional xlr_perfmon mips/rmi/pcibus.c optional pci mips/rmi/xlr_pci.c optional pci -mips/rmi/xls_ehci.c optional usb ehci +#mips/rmi/xls_ehci.c optional usb ehci dev/rmi/xlr/rge.c optional rge dev/iicbus/xlr_rtc.c optional xlr_rtc dev/iicbus/xlr_temperature.c optional xlr_temperature diff --git a/sys/mips/rmi/intr_machdep.c b/sys/mips/rmi/intr_machdep.c index 10539c4d6178..3245ea7e2ac9 100644 --- a/sys/mips/rmi/intr_machdep.c +++ b/sys/mips/rmi/intr_machdep.c @@ -44,7 +44,11 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include +#include +#include +#include + +/*#include */ struct mips_intrhand mips_intr_handlers[XLR_MAX_INTR]; @@ -72,16 +76,16 @@ cpu_establish_hardintr(const char *name, driver_filter_t *filt, struct intr_event *ie; /* descriptor for the IRQ */ int errcode; - if (intr < 0 || intr > XLR_MAX_INTR) - panic("%s called for unknown hard intr %d", __func__, intr); + if (irq < 0 || irq > XLR_MAX_INTR) + panic("%s called for unknown hard intr %d", __func__, irq); /* FIXME locking - not needed now, because we do this only on startup from CPU0 */ mih = &mips_intr_handlers[irq]; - mih->cntp = &intrcnt[irq]; + /*mih->cntp = &intrcnt[irq]; */ ie = mih->mih_event; if (ie == NULL) { - errcode = intr_event_create(&event, (void *)(uintptr_t)irq, 0, + errcode = intr_event_create(&ie, (void *)(uintptr_t)irq, 0, irq, mips_mask_hard_irq, mips_unmask_hard_irq, NULL, NULL, "hard intr%d:", irq); @@ -90,7 +94,7 @@ cpu_establish_hardintr(const char *name, driver_filter_t *filt, return; } } - intr_event_add_handler(event, name, filt, handler, arg, + intr_event_add_handler(ie, name, filt, handler, arg, intr_priority(flags), flags, cookiep); mih->mih_event = ie; mips_unmask_hard_irq((void*)(uintptr_t)irq); @@ -103,17 +107,18 @@ cpu_establish_softintr(const char *name, driver_filter_t *filt, void **cookiep) { /* we don't separate them into soft/hard like other mips */ - cpu_establish_hardintr(name, filt, handler, arg, intr, flags, cookiep); + cpu_establish_hardintr(name, filt, handler, arg, irq, flags, cookiep); } + + void cpu_intr(struct trapframe *tf) { struct mips_intrhand *mih; - struct intr_handler *ih; struct intr_event *ie; register_t eirr; - int i, thread, error; + int i; critical_enter(); eirr = read_c0_eirr64(); @@ -156,7 +161,7 @@ cpu_intr(struct trapframe *tf) #endif #endif mih = &mips_intr_handlers[i]; - atomic_add_long(mih->cntp, 1); + /*atomic_add_long(mih->cntp, 1);*/ ie = mih->mih_event; write_c0_eirr64(1ULL << i); @@ -166,8 +171,7 @@ cpu_intr(struct trapframe *tf) } if (intr_event_handle(ie, tf) != 0) { - printf("stray %s interrupt %d\n", - hard ? "hard" : "soft", i); + printf("stray interrupt %d\n",i); } } diff --git a/sys/mips/rmi/iodi.c b/sys/mips/rmi/iodi.c index 3a8d3bde6abb..256d1bb8f3ca 100644 --- a/sys/mips/rmi/iodi.c +++ b/sys/mips/rmi/iodi.c @@ -46,11 +46,30 @@ #include #include #include -#include -#include -#include +#include +#include +#include +#include #include + +#include +#include +#include /* for DELAY */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + extern void iodi_activateirqs(void); extern bus_space_tag_t uart_bus_space_mem; @@ -61,10 +80,11 @@ static struct resource *iodi_alloc_resource(device_t, device_t, int, int *, static int iodi_activate_resource(device_t, device_t, int, int, struct resource *); static int iodi_setup_intr(device_t, device_t, struct resource *, int, - driver_intr_t *, void *, void **); + driver_filter_t *, driver_intr_t *, void *, void **); struct iodi_softc *iodi_softc; /* There can be only one. */ +/* static void pic_usb_ack(void *arg) { xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET); @@ -74,10 +94,11 @@ static void pic_usb_ack(void *arg) xlr_write_reg(mmio, PIC_INT_ACK, (1 << (irq - PIC_IRQ_BASE))); mtx_unlock_spin(&xlr_pic_lock); } +*/ static int iodi_setup_intr(device_t dev, device_t child, - struct resource *ires, int flags, driver_intr_t *intr, void *arg, + struct resource *ires, int flags, driver_filter_t *filt, driver_intr_t *intr, void *arg, void **cookiep) { int level; @@ -92,34 +113,38 @@ iodi_setup_intr(device_t dev, device_t child, xlr_write_reg(mmio, PIC_IRT_0_UART_0, 0x01); xlr_write_reg(mmio, PIC_IRT_1_UART_0, ((1 << 31) | (level<<30)|(1<<6)|(PIC_UART_0_IRQ))); mtx_unlock_spin(&xlr_pic_lock); - - cpu_establish_intr("uart", PIC_UART_0_IRQ, - (driver_intr_t *)intr, (void *)arg, flags, cookiep, - NULL, NULL); + cpu_establish_hardintr("uart", NULL, + (driver_intr_t *)intr, (void *)arg, PIC_UART_0_IRQ, flags, cookiep); } else if (strcmp(device_get_name(child),"rge") == 0) { + int irq; + irq = rman_get_rid(ires); mtx_lock_spin(&xlr_pic_lock); - reg = xlr_read_reg(mmio, PIC_IRT_1_BASE + ires->r_flags - PIC_IRQ_BASE); - xlr_write_reg(mmio, PIC_IRT_1_BASE + ires->r_flags - PIC_IRQ_BASE, reg | (1<<6)|(1<<30)| (1<<31)); + reg = xlr_read_reg(mmio, PIC_IRT_1_BASE + irq - PIC_IRQ_BASE); + xlr_write_reg(mmio, PIC_IRT_1_BASE + irq - PIC_IRQ_BASE, reg | (1<<6)|(1<<30)| (1<<31)); mtx_unlock_spin(&xlr_pic_lock); - cpu_establish_intr("rge", ires->r_flags, - (driver_intr_t *)intr, (void *)arg, - flags, cookiep, NULL, NULL); + cpu_establish_hardintr("rge", NULL, (driver_intr_t *)intr, (void *)arg, irq, flags, cookiep); + } else if (strcmp(device_get_name(child),"ehci") == 0) { mtx_lock_spin(&xlr_pic_lock); reg = xlr_read_reg(mmio, PIC_IRT_1_BASE + PIC_USB_IRQ - PIC_IRQ_BASE); xlr_write_reg(mmio, PIC_IRT_1_BASE + PIC_USB_IRQ - PIC_IRQ_BASE, reg | (1<<6)|(1<<30)| (1<<31)); mtx_unlock_spin(&xlr_pic_lock); - cpu_establish_intr("ehci", PIC_USB_IRQ, - (driver_intr_t *)intr, (void *)arg, - flags, cookiep, (flags & INTR_FAST)? NULL: pic_usb_ack , NULL); + cpu_establish_hardintr("ehci", NULL, (driver_intr_t *)intr, (void *)arg, PIC_USB_IRQ, flags, cookiep); } - BUS_SETUP_INTR(device_get_parent(dev), child, ires, flags, intr, arg, - cookiep); + BUS_SETUP_INTR(device_get_parent(dev), + child, ires, flags, filt, intr, arg, cookiep); + + return (0); } +/* Strange hook found in mips/include/bus.h */ +#ifndef MIPS_BUS_SPACE_PCI +#define MIPS_BUS_SPACE_PCI 10 +#endif + static struct resource * iodi_alloc_resource(device_t bus, device_t child, int type, int *rid, u_long start, u_long end, u_long count, u_int flags) @@ -159,12 +184,12 @@ iodi_alloc_resource(device_t bus, device_t child, int type, int *rid, res->r_bustag = uart_bus_space_mem; } else if (strcmp(device_get_name(child),"ehci") == 0) { res->r_bushandle = 0xbef24000; - res->r_bustag = MIPS_BUS_SPACE_PCI; + res->r_bustag = (bus_space_tag_t)MIPS_BUS_SPACE_PCI; } else if (strcmp(device_get_name(child),"cfi") == 0) { res->r_bushandle = 0xbc000000; res->r_bustag = 0; } - res->r_start = *rid; + /*res->r_start = *rid;*/ return (res); } diff --git a/sys/mips/rmi/msgring.c b/sys/mips/rmi/msgring.c index 472ad43c9e7c..860cd72a3945 100644 --- a/sys/mips/rmi/msgring.c +++ b/sys/mips/rmi/msgring.c @@ -33,7 +33,7 @@ * from "msgring.cfg" **********************************************************/ -#include +#include struct bucket_size bucket_sizes = { { diff --git a/sys/mips/rmi/msgring.h b/sys/mips/rmi/msgring.h index fba504daa3b2..8cc6898b54aa 100755 --- a/sys/mips/rmi/msgring.h +++ b/sys/mips/rmi/msgring.h @@ -30,7 +30,7 @@ #ifndef _RMI_MSGRING_H_ #define _RMI_MSGRING_H_ -#include +#include #define MSGRNG_TX_BUF_REG 0 #define MSGRNG_RX_BUF_REG 1 diff --git a/sys/mips/rmi/msgring_xls.c b/sys/mips/rmi/msgring_xls.c index f1b116e8f6b0..2171f1404bfd 100644 --- a/sys/mips/rmi/msgring_xls.c +++ b/sys/mips/rmi/msgring_xls.c @@ -4,7 +4,7 @@ * from "msgring_xls.cfg" **********************************************************/ -#include +#include struct bucket_size xls_bucket_sizes = { { 32, 32, 32, 32, 32, 32, 32, 32, diff --git a/sys/mips/rmi/on_chip.c b/sys/mips/rmi/on_chip.c index 8addfc4608a6..1a3d67e17fe0 100644 --- a/sys/mips/rmi/on_chip.c +++ b/sys/mips/rmi/on_chip.c @@ -42,12 +42,12 @@ #include #include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include void disable_msgring_int(void *arg) ; void enable_msgring_int(void *arg) ; @@ -258,9 +258,9 @@ int register_msgring_handler(int major, if (xlr_test_and_set(&msgring_int_enabled)) { platform_prep_smp_launch(); - cpu_establish_intr("msgring", IRQ_MSGRING, - (driver_intr_t *)msgring_process_fast_intr, - NULL, INTR_TYPE_NET|INTR_FAST, &cookie, NULL, NULL); + cpu_establish_hardintr("msgring", (driver_filter_t *)NULL, + (driver_intr_t *)msgring_process_fast_intr, + NULL, IRQ_MSGRING, INTR_TYPE_NET|INTR_FAST, &cookie); /* configure the msgring interrupt on cpu 0 */ enable_msgring_int(NULL); diff --git a/sys/mips/rmi/pcibus.c b/sys/mips/rmi/pcibus.c index 0aeacd68b777..133e4708c49c 100644 --- a/sys/mips/rmi/pcibus.c +++ b/sys/mips/rmi/pcibus.c @@ -47,26 +47,28 @@ __FBSDID("$FreeBSD: src/sys/alpha/pci/pcibus.c,v 1.36 2005/01/05 20:05:52 imp Ex #include #include #include -#include -#include -#include -#include +#include +#include +#include +#include #include #include #include #include #include -#include - +#include +/* static void bridge_pcix_ack(void *); static void bridge_pcie_ack(void *); static void pic_pcix_ack(void *); static void pic_pcie_ack(void *); +*/ extern vm_map_t kernel_map; vm_offset_t kmem_alloc_nofault( vm_map_t map, vm_size_t size); + int mips_pci_route_interrupt(device_t bus, device_t dev, int pin) { @@ -94,11 +96,13 @@ mips_pci_route_interrupt(device_t bus, device_t dev, int pin) static struct rman irq_rman, port_rman, mem_rman; +/* static void bridge_pcix_ack(void *arg) { xlr_read_reg(xlr_io_mmio(XLR_IO_PCIX_OFFSET), 0x140 >> 2); -} - + } +*/ +/* static void bridge_pcie_ack(void *arg) { int irq = (int)arg; @@ -116,7 +120,8 @@ static void bridge_pcie_ack(void *arg) xlr_write_reg(pcie_mmio_le, reg>>2, 0xffffffff); } - +*/ +/* static void pic_pcix_ack(void *none) { xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET); @@ -125,7 +130,8 @@ static void pic_pcix_ack(void *none) xlr_write_reg(mmio, PIC_INT_ACK, (1 << PIC_IRT_PCIX_INDEX)); mtx_unlock_spin(&xlr_pic_lock); } - +*/ +/* static void pic_pcie_ack(void *arg) { xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET); @@ -136,12 +142,15 @@ static void pic_pcie_ack(void *arg) mtx_unlock_spin(&xlr_pic_lock); } +*/ + int mips_platform_pci_setup_intr(device_t dev, device_t child, - struct resource *irq, int flags, - driver_intr_t *intr, void *arg, - void **cookiep) + struct resource *irq, int flags, + driver_filter_t *filt, + driver_intr_t *intr, void *arg, + void **cookiep) { int level; xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_PIC_OFFSET); @@ -151,13 +160,13 @@ mips_platform_pci_setup_intr(device_t dev, device_t child, error = rman_activate_resource(irq); if (error) return error; - if (irq->r_start != irq->r_end) { + if (rman_get_start(irq) != rman_get_end(irq)) { device_printf(dev, "Interrupt allocation %lu != %lu\n", - irq->r_start, irq->r_end); + rman_get_start(irq), rman_get_end(irq)); return EINVAL; } - xlrirq = irq->r_start; + xlrirq = rman_get_start(irq); if (strcmp(device_get_name(dev),"pcib") != 0) return 0; @@ -168,9 +177,9 @@ mips_platform_pci_setup_intr(device_t dev, device_t child, xlr_write_reg(mmio, PIC_IRT_1_PCIX, ((1 << 31) | (level<<30)| (1<<6)|(PIC_PCIX_IRQ))); mtx_unlock_spin(&xlr_pic_lock); - cpu_establish_intr(device_get_name(child), PIC_PCIX_IRQ, - (driver_intr_t *)intr, (void *)arg, flags, cookiep, - pic_pcix_ack, bridge_pcix_ack); + cpu_establish_hardintr(device_get_name(child), filt, + (driver_intr_t *)intr, (void *)arg, PIC_PCIX_IRQ, flags, cookiep); + } else { mtx_lock_spin(&xlr_pic_lock); xlr_write_reg(mmio, PIC_IRT_0_BASE + xlrirq - PIC_IRQ_BASE, 0x01); @@ -179,19 +188,22 @@ mips_platform_pci_setup_intr(device_t dev, device_t child, mtx_unlock_spin(&xlr_pic_lock); if (flags & INTR_FAST) - cpu_establish_intr(device_get_name(child), xlrirq, - (driver_intr_t *)intr, (void *)arg, flags, cookiep, - NULL, bridge_pcie_ack); + cpu_establish_hardintr(device_get_name(child), filt, + (driver_intr_t *)intr, (void *)arg, xlrirq, flags, cookiep); else - cpu_establish_intr(device_get_name(child), xlrirq, - (driver_intr_t *)intr, (void *)arg, flags, cookiep, - pic_pcie_ack, bridge_pcie_ack); + cpu_establish_hardintr(device_get_name(child), filt, + (driver_intr_t *)intr, (void *)arg, xlrirq, flags, cookiep); + } - return bus_generic_setup_intr(dev, child, irq, flags, intr, + return bus_generic_setup_intr(dev, child, irq, flags, filt, intr, arg, cookiep); } + +int +mips_platform_pci_teardown_intr(device_t dev, device_t child, + struct resource *irq, void *cookie); int mips_platform_pci_teardown_intr(device_t dev, device_t child, struct resource *irq, void *cookie) @@ -230,13 +242,18 @@ pci_init_resources(void) panic("pci_init_resources mem_rman"); } +/* hack from bus.h in mips/include/bus.h */ +#ifndef MIPS_BUS_SPACE_PCI +#define MIPS_BUS_SPACE_PCI 10 +#endif + struct resource * xlr_pci_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 rman *rm; struct resource *rv; - vm_offset_t va_start, va; + vm_offset_t va; int needactivate = flags & RF_ACTIVE; #if 0 @@ -265,18 +282,24 @@ xlr_pci_alloc_resource(device_t bus, device_t child, int type, int *rid, if (rv == 0) return 0; - rman_set_bustag(rv, MIPS_BUS_SPACE_PCI); - rman_set_rid(rv, *rid); + rman_set_bustag(rv, (bus_space_tag_t)MIPS_BUS_SPACE_PCI); + rman_set_rid(rv, *rid); if (type == SYS_RES_MEMORY || type == SYS_RES_IOPORT) { - if ((start + count) > (2 << 28)) { + /* if ((start + count) > (2 << 28)) { va_start = kmem_alloc_nofault(kernel_map, count); - } - va = pmap_map_uncached(&va_start, start, start + count); + }*/ + /* This called for pmap_map_uncached, but the pmap_map + * calls pmap_kenter which does a is_cacheable_mem() check and + * thus sets the PTE_UNCACHED bit. Hopefully this will work + * for this guy... RRS + */ + /* va = pmap_map(&va_start, start, start + count, 0);*/ + va = (vm_offset_t)pmap_mapdev(start, start + count); rman_set_bushandle(rv, va); /* bushandle is same as virtual addr */ rman_set_virtual(rv, (void *)va); - rman_set_bustag(rv, MIPS_BUS_SPACE_PCI); + rman_set_bustag(rv, (bus_space_tag_t)MIPS_BUS_SPACE_PCI); } if (needactivate) { @@ -289,6 +312,14 @@ xlr_pci_alloc_resource(device_t bus, device_t child, int type, int *rid, return rv; } + +int +pci_deactivate_resource(device_t bus, device_t child, int type, int rid, + struct resource *r) +{ + return (rman_deactivate_resource(r)); +} +/* now in pci.c int pci_activate_resource(device_t bus, device_t child, int type, int rid, struct resource *r) @@ -296,19 +327,13 @@ pci_activate_resource(device_t bus, device_t child, int type, int rid, return (rman_activate_resource(r)); } -int -pci_deactivate_resource(device_t bus, device_t child, int type, int rid, - struct resource *r) -{ - return (rman_deactivate_resource(r)); -} - int pci_release_resource(device_t bus, device_t child, int type, int rid, struct resource *r) { return (rman_release_resource(r)); } +*/ struct rman * pci_get_rman(device_t dev, int type) diff --git a/sys/mips/rmi/pcibus.h b/sys/mips/rmi/pcibus.h index ed4bb9768ec7..2f4fda8ccdb5 100644 --- a/sys/mips/rmi/pcibus.h +++ b/sys/mips/rmi/pcibus.h @@ -47,3 +47,12 @@ int pci_deactivate_resource(device_t bus, device_t child, int type, int rid, int pci_release_resource(device_t bus, device_t child, int type, int rid, struct resource *r); struct rman *pci_get_rman(device_t dev, int type); + +int +mips_platform_pci_setup_intr(device_t dev, device_t child, + struct resource *irq, int flags, + driver_filter_t *filt, + driver_intr_t *intr, void *arg, + void **cookiep); +int +mips_pci_route_interrupt(device_t bus, device_t dev, int pin); diff --git a/sys/mips/rmi/perfmon.h b/sys/mips/rmi/perfmon.h index 1ba6c468e645..23523caab6fb 100644 --- a/sys/mips/rmi/perfmon.h +++ b/sys/mips/rmi/perfmon.h @@ -31,7 +31,7 @@ #ifndef PERFMON_H #define PERFMON_H -#include +#include /* * category events reported by the perfmon library diff --git a/sys/mips/rmi/perfmon_kern.c b/sys/mips/rmi/perfmon_kern.c index 1e4b7ce20505..6b74f72bec3e 100644 --- a/sys/mips/rmi/perfmon_kern.c +++ b/sys/mips/rmi/perfmon_kern.c @@ -37,10 +37,10 @@ #include #include #include -#include -#include +#include +#include #include -#include +#include int xlr_perfmon_started = 0; diff --git a/sys/mips/rmi/perfmon_percpu.c b/sys/mips/rmi/perfmon_percpu.c index 5980ff76389c..44ba35671112 100644 --- a/sys/mips/rmi/perfmon_percpu.c +++ b/sys/mips/rmi/perfmon_percpu.c @@ -33,12 +33,12 @@ #include #include #include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include #define CC_SAMPLE (PERF_CP2_CREDITS <<24) diff --git a/sys/mips/rmi/perfmon_xlrconfig.h b/sys/mips/rmi/perfmon_xlrconfig.h index 8156c125951c..587334e5a91f 100644 --- a/sys/mips/rmi/perfmon_xlrconfig.h +++ b/sys/mips/rmi/perfmon_xlrconfig.h @@ -33,7 +33,7 @@ #ifndef XLRCONFIG_PERFMON_H #define XLRCONFIG_PERFMON_H -#include /* for DPRINT */ +#include /* for DPRINT */ #define NCPUS 32 #define NCORES 8 diff --git a/sys/mips/rmi/pic.h b/sys/mips/rmi/pic.h index 366a73659c76..eee251e6dda0 100644 --- a/sys/mips/rmi/pic.h +++ b/sys/mips/rmi/pic.h @@ -33,7 +33,7 @@ #include #include -#include +#include #define PIC_IRT_WD_INDEX 0 #define PIC_IRT_TIMER_0_INDEX 1 diff --git a/sys/mips/rmi/std.xlr b/sys/mips/rmi/std.xlr index da42ffeff053..c6221b95f68d 100644 --- a/sys/mips/rmi/std.xlr +++ b/sys/mips/rmi/std.xlr @@ -1,10 +1,10 @@ # $FreeBSD$ -files "../xlr/files.xlr" +files "../rmi/files.xlr" # # XXXMIPS: It's a stub, isn't it? # -cpu CPU_MIPSXLR +cpu CPU_MIPS4KC option NOFPU # Kludge for now options TARGET_XLR_XLS diff --git a/sys/mips/rmi/tick.c b/sys/mips/rmi/tick.c new file mode 100644 index 000000000000..1f4fcbea2d4f --- /dev/null +++ b/sys/mips/rmi/tick.c @@ -0,0 +1,113 @@ +/*- + * Copyright (c) 2006-2009 RMI Corporation + * Copyright (c) 2006 Bruce M. Simpson + * 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. + */ + +/* + * Simple driver for the 32-bit interval counter built in to all + * MIPS32 CPUs. + * XXX: For calibration this either needs an external clock, or + * to be explicitly told what the frequency is. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +struct timecounter counter_timecounter = { + platform_get_timecount, /* get_timecount */ + 0, /* no poll_pps */ + ~0u, /* counter_mask */ + 0, /* frequency */ + "MIPS32", /* name */ + 800, /* quality (adjusted in code) */ +}; + +void tick_init(void); + + +void +tick_init(void) +{ + counter_freq = platform_get_frequency(); + if (bootverbose) + printf("MIPS32 clock: %u MHz", cpu_clock); + + counter_timecounter.tc_frequency = counter_freq; + tc_init(&counter_timecounter); +} + + +void +cpu_startprofclock(void) +{ + /* nothing to do */ +} + +void +cpu_stopprofclock(void) +{ + /* nothing to do */ +} + + +static int +sysctl_machdep_counter_freq(SYSCTL_HANDLER_ARGS) +{ + int error; + uint64_t freq; + /* + * RRS wonders if this will really work. You don't + * change the req of the system here, it would require + * changes to the RMI PIC in order to get the TC to + * run at a differrent frequency. + */ + + if (counter_timecounter.tc_frequency == 0) + return (EOPNOTSUPP); + freq = counter_freq; + error = sysctl_handle_int(oidp, &freq, sizeof(freq), req); + if (error == 0 && req->newptr != NULL) { + counter_freq = freq; + counter_timecounter.tc_frequency = counter_freq; + } + return (error); +} + +SYSCTL_PROC(_machdep, OID_AUTO, counter_freq, CTLTYPE_QUAD | CTLFLAG_RW, + 0, sizeof(u_int), sysctl_machdep_counter_freq, "IU", ""); diff --git a/sys/mips/rmi/uart_cpu_mips_xlr.c b/sys/mips/rmi/uart_cpu_mips_xlr.c index 09703f55d4b6..6cbea14a3037 100644 --- a/sys/mips/rmi/uart_cpu_mips_xlr.c +++ b/sys/mips/rmi/uart_cpu_mips_xlr.c @@ -55,16 +55,18 @@ static int xlr_uart_probe(struct uart_bas *bas); static void xlr_uart_init(struct uart_bas *bas, int, int, int, int); static void xlr_uart_term(struct uart_bas *bas); static void xlr_uart_putc(struct uart_bas *bas, int); -static int xlr_uart_poll(struct uart_bas *bas); -static int xlr_uart_getc(struct uart_bas *bas); +/*static int xlr_uart_poll(struct uart_bas *bas);*/ +static int xlr_uart_getc(struct uart_bas *bas, struct mtx *hwmtx); struct mtx xlr_uart_mtx; /*UartLock*/ +extern struct uart_ops uart_ns8250_ops; + struct uart_ops xlr_uart_ns8250_ops = { .probe = xlr_uart_probe, .init = xlr_uart_init, .term = xlr_uart_term, .putc = xlr_uart_putc, - .poll = xlr_uart_poll, + /* .poll = xlr_uart_poll, ?? */ .getc = xlr_uart_getc, }; @@ -119,7 +121,7 @@ static void xlr_uart_putc(struct uart_bas *bas, int c) uart_ns8250_ops.putc(bas,c); xlr_uart_unlock(&xlr_uart_mtx); } - +/* static int xlr_uart_poll(struct uart_bas *bas) { int res; @@ -128,10 +130,11 @@ static int xlr_uart_poll(struct uart_bas *bas) xlr_uart_unlock(&xlr_uart_mtx); return res; } +*/ -static int xlr_uart_getc(struct uart_bas *bas) +static int xlr_uart_getc(struct uart_bas *bas, struct mtx *hwmtx) { - return uart_ns8250_ops.getc(bas); + return uart_ns8250_ops.getc(bas, hwmtx); } int @@ -144,7 +147,7 @@ uart_cpu_eqres(struct uart_bas *b1, struct uart_bas *b2) int uart_cpu_getdev(int devtype, struct uart_devinfo *di) { - di->ops = xlr_uart_ns8250_ops; + di->ops = &xlr_uart_ns8250_ops; di->bas.chan = 0; di->bas.bst = uart_bus_space_mem; /* TODO Need to call bus_space_map() here */ diff --git a/sys/mips/rmi/xlr_boot1_console.c b/sys/mips/rmi/xlr_boot1_console.c index 01e67b573f33..10b650eefd52 100644 --- a/sys/mips/rmi/xlr_boot1_console.c +++ b/sys/mips/rmi/xlr_boot1_console.c @@ -45,9 +45,9 @@ __FBSDID("$FreeBSD$"); #include #include -#include -#include -#include +#include +#include +#include #include diff --git a/sys/mips/rmi/xlr_i2c.c b/sys/mips/rmi/xlr_i2c.c index 60e51c596a85..5f36f7cd7973 100644 --- a/sys/mips/rmi/xlr_i2c.c +++ b/sys/mips/rmi/xlr_i2c.c @@ -46,7 +46,7 @@ __FBSDID("$FreeBSD: src/sys/mips/xlr/xlr_i2c.c,v 1.20.8.1 2008/08/25 23:17:51 co #include #include -#include +#include #include #include "iicbus_if.h" diff --git a/sys/mips/rmi/xlr_machdep.c b/sys/mips/rmi/xlr_machdep.c index 84bdb64a6d9c..e909b38c10d3 100644 --- a/sys/mips/rmi/xlr_machdep.c +++ b/sys/mips/rmi/xlr_machdep.c @@ -1,4 +1,5 @@ /*- + * Copyright (c) 2006-2009 RMI Corporation * Copyright (c) 2002-2004 Juli Mallett * All rights reserved. * @@ -70,15 +71,15 @@ #include #include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include #ifdef XLR_PERFMON -#include +#include #endif @@ -108,8 +109,8 @@ static unsigned long xlr_secondary_sp[MAXCPU]; #endif extern int mips_cpu_online_mask; extern int mips_cpu_logical_mask; -extern uint32_t cpu_ltop_map[MAXCPU]; -extern uint32_t cpu_ptol_map[MAXCPU]; +uint32_t cpu_ltop_map[MAXCPU]; +uint32_t cpu_ptol_map[MAXCPU]; uint32_t xlr_core_cpu_mask=0x1; /* Core 0 thread 0 is always there */ void @@ -128,13 +129,13 @@ void platform_secondary_init(void) xlr_msgring_cpu_init(); /* Setup interrupts for secondary CPUs here */ - platform_update_intrmask(IPI_SMP_CALL_FUNCTION); - platform_update_intrmask(IPI_STOP); - platform_update_intrmask(IPI_RENDEZVOUS); - platform_update_intrmask(IPI_AST); - platform_update_intrmask(IRQ_TIMER); + mips_mask_hard_irq(IPI_SMP_CALL_FUNCTION); + mips_mask_hard_irq(IPI_STOP); + mips_mask_hard_irq(IPI_RENDEZVOUS); + mips_mask_hard_irq(IPI_AST); + mips_mask_hard_irq(IRQ_TIMER); #ifdef XLR_PERFMON - platform_update_intrmask(IPI_PERFMON); + mips_mask_hard_irq(IPI_PERFMON); #endif return; @@ -325,10 +326,45 @@ static void xlr_set_boot_flags(void) return; } - extern uint32_t _end; + + +static void +mips_init(void) +{ + init_param1(); + init_param2(physmem); + + /* XXX: Catch 22. Something touches the tlb. */ + + mips_cpu_init(); + pmap_bootstrap(); + + mips_proc0_init(); + write_c0_register32(MIPS_COP_0_OSSCRATCH,7, pcpup->pc_curthread); + + mutex_init(); + + PMAP_LOCK_INIT(kernel_pmap); + +#ifdef DDB +#ifdef SMP + setup_nmi(); +#endif /* SMP */ + kdb_init(); + if (boothowto & RB_KDB) { + kdb_enter("Boot flags requested debugger"); + } +#endif +} + +void tick_init(void); + void -platform_start() +platform_start(__register_t a0 __unused, + __register_t a1 __unused, + __register_t a2 __unused, + __register_t a3 __unused) { vm_size_t physsz = 0; int i, j; @@ -356,7 +392,15 @@ platform_start() boothowto |= (RB_SERIAL | RB_MULTIPLE); /* Use multiple consoles */ /* clockrate used by delay, so initialize it here */ - hw_clockrate = xlr_boot1_info.cpu_frequency/1000000 ; + cpu_clock = xlr_boot1_info.cpu_frequency/1000000 ; + + /* Note the time counter on CPU0 runs not at system + * clock speed, but at PIC time counter speed (which is + * returned by platform_get_frequency(). Thus we do not + * use xlr_boot1_info.cpu_frequency here. + */ + mips_timer_early_init(platform_get_frequency()); + mips_timer_init_params(platform_get_frequency(), 0); cninit(); init_static_kenv(boot1_env, sizeof(boot1_env)); @@ -448,7 +492,7 @@ platform_start() /* Allocate stack for all other cpus from fbsd kseg0 memory. */ if((1U<i_thread; p = td->td_proc; - + /* Interrupt thread will enable the interrupts after processing all messages */ - mtx_lock_spin(&sched_lock); disable_msgring_int(NULL); it->i_pending = 1; if (TD_AWAITING_INTR(td)) { + thread_lock(td); CTR3(KTR_INTR, "%s: schedule pid %d (%s)", __func__, p->p_pid, p->p_comm); TD_CLR_IWAIT(td); - setrunqueue(td, SRQ_INTR); + sched_add(td, SRQ_INTR); + thread_unlock(td); } else { CTR4(KTR_INTR, "%s: pid %d (%s): state %d", __func__, p->p_pid, p->p_comm, td->td_state); } - mtx_unlock_spin(&sched_lock); } #define MIT_DEAD 4 @@ -574,9 +618,9 @@ msgring_process(void * arg) ("%s:msg_ithread and proc linkage out of sync", __func__)); /* First bind this thread to the right CPU */ - mtx_lock_spin(&sched_lock); + thread_lock(td); sched_bind(td, ithd->i_cpu); - mtx_unlock_spin(&sched_lock); + thread_unlock(td); // printf("Started %s on CPU %d\n", __FUNCTION__, ithd->i_cpu); @@ -584,7 +628,7 @@ msgring_process(void * arg) if (ithd->i_flags & MIT_DEAD) { CTR3(KTR_INTR, "%s: pid %d (%s) exiting", __func__, p->p_pid, p->p_comm); - kthread_exit(0); + kthread_exit(); } while (ithd->i_pending) { /* @@ -596,13 +640,14 @@ msgring_process(void * arg) atomic_store_rel_int(&ithd->i_pending, 0); xlr_msgring_handler(NULL); } - mtx_lock_spin(&sched_lock); if (!ithd->i_pending && !(ithd->i_flags & MIT_DEAD)) { + thread_lock(td); + sched_class(td, PRI_ITHD); TD_SET_IWAIT(td); + thread_unlock(td); enable_msgring_int(NULL); mi_switch(SW_VOL, NULL); } - mtx_unlock_spin(&sched_lock); } } @@ -629,16 +674,21 @@ void platform_prep_smp_launch(void) ithd = &msgring_ithreads[cpu]; sprintf(ithd_name[cpu], "msg_intr%d", cpu); - error = kthread_create(msgring_process, (void *)ithd, &p, - RFSTOPPED | RFHIGHPID, 0, "%s", ithd_name[cpu]); + error = kproc_create(msgring_process, + (void *)ithd, + &p, + (RFSTOPPED | RFHIGHPID), + 2, + ithd_name[cpu]); + if (error) - panic("kthread_create() failed with %d", error); + panic("kproc_create() failed with %d", error); td = FIRST_THREAD_IN_PROC(p); /* XXXKSE */ - mtx_lock_spin(&sched_lock); - td->td_ksegrp->kg_pri_class = PRI_ITHD; + + thread_lock(td); + sched_class(td, PRI_ITHD); TD_SET_IWAIT(td); - mtx_unlock_spin(&sched_lock); - td->td_pflags |= TDP_ITHREAD; + thread_unlock(td); ithd->i_thread = td; ithd->i_pending = 0; ithd->i_cpu = cpu; diff --git a/sys/mips/rmi/xlr_pci.c b/sys/mips/rmi/xlr_pci.c index 31fe5cf73062..3b11bf19e103 100644 --- a/sys/mips/rmi/xlr_pci.c +++ b/sys/mips/rmi/xlr_pci.c @@ -49,11 +49,11 @@ #include #include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include #include "pcib_if.h" #define LSU_CFG0_REGID 0 @@ -127,7 +127,7 @@ xlr_pcib_probe(device_t dev) } static int -xlr_pcib_read_ivar(device_t dev, device_t child, int which, u_long *result) +xlr_pcib_read_ivar(device_t dev, device_t child, int which, uintptr_t *result) { #if 0 device_printf(dev, "xlr_pcib_read_ivar : read ivar %d for child %s\n", which, device_get_nameunit(child)); @@ -392,7 +392,9 @@ static device_method_t xlr_pcib_methods[] = { DEVMETHOD(pcib_maxslots, xlr_pcib_maxslots), DEVMETHOD(pcib_read_config, xlr_pcib_read_config), DEVMETHOD(pcib_write_config, xlr_pcib_write_config), + DEVMETHOD(pcib_route_interrupt, mips_pci_route_interrupt), + DEVMETHOD(pcib_alloc_msi, xlr_alloc_msi), DEVMETHOD(pcib_release_msi, xlr_release_msi), DEVMETHOD(pcib_map_msi, xlr_map_msi), diff --git a/sys/mips/rmi/xlrconfig.h b/sys/mips/rmi/xlrconfig.h index c446595c7a05..01b67cb5d104 100644 --- a/sys/mips/rmi/xlrconfig.h +++ b/sys/mips/rmi/xlrconfig.h @@ -31,8 +31,8 @@ #define XLRCONFIG_H #include -#include -#include +#include +#include #define read_c0_register32(reg, sel) \ ({ unsigned int __rv; \ diff --git a/sys/mips/rmi/xls_ehci.c b/sys/mips/rmi/xls_ehci.c index 7d44eee46624..c351bb6eccae 100644 --- a/sys/mips/rmi/xls_ehci.c +++ b/sys/mips/rmi/xls_ehci.c @@ -60,6 +60,7 @@ __FBSDID("$FreeBSD: src/sys/dev/usb/ehci_pci.c,v 1.18.2.4 2008/04/23 18:54:51 jh #include #include #include +#include #include #include #include @@ -67,11 +68,11 @@ __FBSDID("$FreeBSD: src/sys/dev/usb/ehci_pci.c,v 1.18.2.4 2008/04/23 18:54:51 jh #include #include -#include -#include +/*#include */ +/*#include */ -#include -#include +#include +#include #ifdef USB_DEBUG #define EHCI_DEBUG USB_DEBUG